|
|
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.13 3/19/86";
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: * This code will probably cause a core dump some day.
116: */
117: mypath = getenv("PATH");
118: if (mypath)
119: strcpy(mypath, "/bin:/usr/bin");
120:
121: /*
122: * We send the copies out separately, because of a bug in
123: * USG's /bin/mail which will generate ANOTHER To: line,
124: * even though we already have one, if there are at least
125: * two recipients.
126: */
127: for (i=0; i<nrecips; i++) {
128: /*
129: * mail recips[i] < tmpf
130: */
131: pid = mailto(tmpf, errfd, recips[i]);
132: exstat = -1;
133: while ((wpid = wait(&exstat)) >= 0 && wpid != pid)
134: ;
135: if (exstat == 0)
136: goodcnt++;
137: else
138: badcnt++;
139: }
140: if (badcnt) {
141: mailback(errfd, tmpf, errf);
142: (void) unlink(tmpf);
143: (void) unlink(errf);
144: exit(1);
145: } else if (goodcnt == 0) {
146: fprintf(errfd, "recmail: no 'To:' line\n");
147: mailback(errfd, tmpf, errf);
148: (void) unlink(tmpf);
149: (void) unlink(errf);
150: exit (1);
151: }
152: (void) unlink(tmpf);
153: (void) unlink(errf);
154: exit (0);
155: }
156:
157: #define isok(c) (isprint(c) && (c) != ' ' && c != ',')
158: addrecips(line)
159: char *line;
160: {
161: char *front, *back, *tail;
162: char *malloc();
163:
164: tail = line + strlen(line);
165: for (front=line; front < tail; ) {
166: while (!isok(*front) && front < tail)
167: front++;
168: if (front >= tail)
169: break; /* skip end of line garbage */
170: for (back=front; isok(*back); back++)
171: ;
172: *back=0;
173: if (nrecips >= MAXRECIPS) {
174: printf("Too many destinations\n");
175: exit(2);
176: }
177: if ((recips[nrecips] = malloc(strlen(front) + 1)) == NULL) {
178: printf("Out of space\n");
179: exit(2);
180: }
181: (void) strcpy(recips[nrecips], front);
182: nrecips++;
183: front = back+1;
184: }
185: }
186:
187: int
188: mailto(tmpf, errfd, recip)
189: char *tmpf;
190: FILE *errfd;
191: char *recip;
192: {
193: register int pid;
194:
195: /*
196: * mail recips < tmpf
197: */
198: while ((pid = fork()) == -1) {
199: fprintf(stderr, "fork failed, waiting...\r\n");
200: sleep(60);
201: }
202: if (pid == 0) {
203: (void) close(0);
204: (void) open(tmpf, 0);
205: if (errfd != NULL) {
206: (void) close(1);
207: (void) dup(fileno(errfd));
208: (void) fclose(errfd);
209: (void) close(2);
210: (void) dup(1);
211: }
212: execlp(mailer, mailer, recip, (char *)0);
213: perror(mailer);
214: exit(1);
215: }
216: return pid;
217: }
218:
219: mailback(errfd, tmpf, errf)
220: register FILE *errfd;
221: char *tmpf;
222: char *errf;
223: {
224: register FILE *fd;
225: register int c;
226: int exstat;
227: register int pid, wpid;
228: char *logn;
229: char *getlogin(), *getenv();
230: register struct passwd *pwd;
231:
232: if ((fd = fopen(tmpf, "r")) != NULL) {
233: fprintf(errfd, "\n ----- Unsent message follows -----\n");
234: while ((c = getc(fd)) != EOF)
235: putc(c, errfd);
236: (void) fclose(fd);
237: }
238: (void) fclose(errfd);
239: if ((logn = getlogin()) == NULL && (logn = getenv("USER")) == NULL) {
240: if ((pwd = getpwent(getuid())) == NULL)
241: return;
242: logn = pwd->pw_name;
243: }
244: pid = mailto(errf, (FILE *)NULL, logn);
245: while ((wpid = wait(&exstat)) >= 0 && wpid != pid)
246: ;
247: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.