|
|
1.1 root 1: /*
2: * This software is Copyright (c) 1986 by Rick Adams.
3: *
4: * Permission is hereby granted to copy, reproduce, redistribute or
5: * otherwise use this software as long as: there is no monetary
6: * profit gained specifically from the use or reproduction or this
7: * software, it is not sold, rented, traded or otherwise marketed, and
8: * this copyright notice is included prominently in any copy
9: * made.
10: *
11: * The author make no claims as to the fitness or correctness of
12: * this software for any use whatsoever, and it is provided as is.
13: * Any use of this software is at the user's own risk.
14: *
15: * recmail: read a mail message on stdin, grab all addresses in To and Cc
16: * lines, and pass the full message to all addressees. This is useful to
17: * send the output of a recently edited mail message (with headers edited too).
18: * It is similar to sendmail -t, but only assumes /bin/mail.
19: * To use your own mailer, e. g. nmail, compile with -DMAILER=my_mailer.
20: */
21:
22: #ifdef SCCSID
23: static char *SccsId = "@(#)recmail.c 1.16 9/24/87";
24: #endif /* SCCSID */
25:
26: #include "params.h"
27:
28: #ifndef MAILER
29: #define MAILER "/bin/mail"
30: #endif
31: char mailer[] = MAILER;
32:
33: #define MAXRECIPS 100
34: char *recips[MAXRECIPS];
35: int nrecips = 0;
36:
37: main()
38: {
39: FILE *fd;
40: char *tmpf;
41: FILE *errfd;
42: char *errf;
43: char linebuf[1024];
44: int i, pid, wpid;
45: int exstat;
46: char *mypath;
47: int goodcnt, badcnt;
48: char *mktemp(), *getenv();
49:
50: tmpf = mktemp("/tmp/rmXXXXXX");
51: (void) close(creat(tmpf,0666));
52: fd = fopen(tmpf, "w");
53: errf = mktemp("/tmp/rmXXXXXX");
54: (void) close(creat(errf,0666));
55: errfd = fopen(errf, "w");
56: fprintf(errfd, "Subject: Returned mail\n");
57: fprintf(errfd, "\n ----- Transcript of session follows -----\n");
58: (void) fflush(errfd);
59: goodcnt = badcnt = 0;
60:
61: while (fgets(linebuf, sizeof linebuf, stdin) != NULL) {
62: if ((strncmp(linebuf, "Bcc: ", 5) == 0 ||
63: strncmp(linebuf, "bcc: ", 5) == 0 ||
64: strncmp(linebuf, "BCC: ", 5) == 0)) {
65: if (linebuf[5] != '\n')
66: addrecips(linebuf+5);
67: }
68: else if (fputs(linebuf, fd) == EOF)
69: goto werror;
70: if (linebuf[0] == '\n')
71: break;
72: if ((strncmp(linebuf, "To: ", 4) == 0 ||
73: strncmp(linebuf, "to: ", 4) == 0 ||
74: strncmp(linebuf, "TO: ", 4) == 0 ||
75: strncmp(linebuf, "Cc: ", 4) == 0 ||
76: strncmp(linebuf, "cc: ", 4) == 0 ||
77: strncmp(linebuf, "CC: ", 4) == 0) &&
78: linebuf[4] != '\n')
79: addrecips(linebuf+4);
80: }
81: if (!feof(stdin)) {
82: while (fgets(linebuf, sizeof linebuf, stdin) != NULL) {
83: if (fputs(linebuf, fd) == EOF) {
84: werror:
85: printf("write error on temp file\n");
86: exit(2);
87: }
88: }
89: }
90: /*
91: * Append the contents of the .signature file (if it exists) to
92: * the end of the mail message
93: */
94: {
95: char sigbuf[BUFSIZ];
96: register c;
97: register char *p = getenv("HOME");
98: FILE *infp;
99:
100: if (p) {
101: (void) sprintf(sigbuf, "%s/%s", p, ".signature");
102: if (infp = fopen(sigbuf, "r")) {
103: fprintf(fd,"---\n");
104: while ((c = getc(infp)) != EOF)
105: putc(c,fd);
106: (void) fclose(infp);
107: }
108: }
109: }
110: (void) fclose(fd);
111:
112: /*
113: * Force the path to only consider /bin and /usr/bin, since
114: * that's the version of mail we want (not /usr/ucb/mail)
115: */
116: if (mailer[0] != '/') {
117: register int e;
118: extern char **environ;
119: for (e = 0; environ[e] != NULL; ++e)
120: if (strncmp(environ[e], "PATH=", 5) == 0) {
121: environ[e] = "PATH=/bin:/usr/bin";
122: break;
123: }
124: }
125: mypath = getenv("PATH");
126: if (mypath)
127: strcpy(mypath, "/bin:/usr/bin");
128:
129: /*
130: * We send the copies out separately, because of a bug in
131: * USG's /bin/mail which will generate ANOTHER To: line,
132: * even though we already have one, if there are at least
133: * two recipients.
134: */
135: for (i=0; i<nrecips; i++) {
136: /*
137: * mail recips[i] < tmpf
138: */
139: pid = mailto(tmpf, errfd, recips[i]);
140: exstat = -1;
141: while ((wpid = wait(&exstat)) >= 0 && wpid != pid)
142: ;
143: if (exstat == 0)
144: goodcnt++;
145: else
146: badcnt++;
147: }
148: if (badcnt) {
149: mailback(errfd, tmpf, errf);
150: (void) unlink(tmpf);
151: (void) unlink(errf);
152: exit(1);
153: } else if (goodcnt == 0) {
154: fprintf(errfd, "recmail: no 'To:' line\n");
155: mailback(errfd, tmpf, errf);
156: (void) unlink(tmpf);
157: (void) unlink(errf);
158: exit (1);
159: }
160: (void) unlink(tmpf);
161: (void) unlink(errf);
162: exit (0);
163: }
164:
165: #define isok(c) (isprint(c) && (c) != ' ' && c != ',')
166: addrecips(line)
167: char *line;
168: {
169: char *front, *back, *tail;
170: char *malloc();
171:
172: tail = line + strlen(line);
173: for (front=line; front < tail; ) {
174: while (!isok(*front) && front < tail)
175: front++;
176: if (front >= tail)
177: break; /* skip end of line garbage */
178: for (back=front; isok(*back); back++)
179: ;
180: *back=0;
181: if (nrecips >= MAXRECIPS) {
182: printf("Too many destinations\n");
183: exit(2);
184: }
185: if ((recips[nrecips] = malloc(strlen(front) + 1)) == NULL) {
186: printf("Out of space\n");
187: exit(2);
188: }
189: (void) strcpy(recips[nrecips], front);
190: nrecips++;
191: front = back+1;
192: }
193: }
194:
195: int
196: mailto(tmpf, errfd, recip)
197: char *tmpf;
198: FILE *errfd;
199: char *recip;
200: {
201: register int pid;
202:
203: /*
204: * mail recips < tmpf
205: */
206: while ((pid = vfork()) == -1) {
207: fprintf(stderr, "fork failed, waiting...\r\n");
208: sleep(60);
209: }
210: if (pid == 0) {
211: (void) close(0);
212: (void) open(tmpf, 0);
213: if (errfd != NULL) {
214: (void) close(1);
215: (void) dup(fileno(errfd));
216: (void) fclose(errfd);
217: (void) close(2);
218: (void) dup(1);
219: }
220: execlp(mailer, mailer, recip, (char *)0);
221: perror(mailer);
222: exit(1);
223: }
224: return pid;
225: }
226:
227: mailback(errfd, tmpf, errf)
228: register FILE *errfd;
229: char *tmpf;
230: char *errf;
231: {
232: register FILE *fd;
233: register int c;
234: int exstat;
235: register int pid, wpid;
236: char *logn;
237: char *getlogin(), *getenv();
238: register struct passwd *pwd;
239:
240: if ((fd = fopen(tmpf, "r")) != NULL) {
241: fprintf(errfd, "\n ----- Unsent message follows -----\n");
242: while ((c = getc(fd)) != EOF)
243: putc(c, errfd);
244: (void) fclose(fd);
245: }
246: (void) fclose(errfd);
247: if ((logn = getlogin()) == NULL && (logn = getenv("USER")) == NULL) {
248: if ((pwd = getpwuid(getuid())) == NULL)
249: return;
250: logn = pwd->pw_name;
251: }
252: pid = mailto(errf, (FILE *)NULL, logn);
253: while ((wpid = wait(&exstat)) >= 0 && wpid != pid)
254: ;
255: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.