|
|
1.1 root 1: /*
2: * The code that passes an individual message to the mail system.
3: */
4:
5: #include "mail.h"
6:
7: #define SITENAMELEN 32 /* max length of sitename */
8: #define NODENAME "/etc/uucpname"
9: #define DOMAINNAME "/etc/domain"
10: char domain [64];
11:
12: extern char *strtok();
13: static char **allist;
14: static char **tolist;
15: static char **cclist = NULL;
16:
17: char mysite[SITENAMELEN]; /* this host's uucpname */
18:
19: extern char *temp;
20: extern int myuid; /* User-id of mail user */
21: extern int mygid; /* Group-id of mail user */
22: extern char cmdname[]; /* Command for x{en,de}code filter */
23: /* and for tail recursion to uumail */
24: /* and for editor recursion */
25: extern char *editname; /* name of editor */
26: extern char *askcc; /* Ask for CC: list? (YES/NO) */
27: extern int callmexmail; /* Xmail modifier present */
28: extern char wrerr[];
29: extern char myname[]; /* User name */
30: extern char myfullname[]; /* full user name */
31: extern int mflag; /* `You have mail.' message to recipient */
32: extern int verbflag; /* verbose flag */
33: extern char templ[]; /* Temp file name template */
34: extern char mydead[]; /* $HOME/dead.letter */
35: extern char mysig[];
36: extern char nosave[];
37: extern int callmermail;
38:
39: static int eflag; /* Edit this mail */
40: static int senderr;
41: struct tm *tp;
42: char toerr[] = "Cannot create temporary file\n";
43: char header[BUFSIZ]; /* Message header */
44: char boxname[256]; /* Destination mailbox */
45: char remotefrom [32]; /* "remote from uucp" */
46:
47: char nosend[] = "Can't send mail to '%s'\n";
48: char nopubk[] = "Can't send xmail to '%s'\n";
49: static int fromtty;
50:
51: /*
52: * Send the message found on
53: * the file pointer to the list
54: * of people (argv style) with
55: * a NULL pointer at the end.
56: * The message is copied to a temp-file
57: * from position `start' to `end' (or EOF).
58: */
59: send2(fp, users, start, end, asksubj)
60: FILE *fp;
61: register char **users;
62: fsize_t start, end;
63: int asksubj;
64: {
65: char **getcc(), **listpp;
66: FILE *xfp, *tfp, *sigfp;
67: time_t curtime;
68:
69: uucpname();
70: domainname();
71: senderr = 0;
72: temp = templ;
73:
74: fromtty = isatty(fileno(stdin));
75: if ((tfp = fopen(temp, "w")) != NULL) {
76: fclose(tfp);
77: if ((tfp = fopen(temp, "r+w")) == NULL)
78: merr(toerr);
79: } else
80: merr(toerr);
81: chown(temp, myuid, mygid);
82: unlink(temp);
83: temp = NULL;
84: fseek(fp, start, 0);
85: end -= start;
86:
87: eflag = 0;
88: if (fromtty && asksubj && !callmermail) {
89: fprintf(stdout, "Subject: ");
90: fflush(stdout);
91: if (fgets(msgline, NLINE, fp) != NULL) {
92: if (strlen(msgline) > 1)
93: fprintf(tfp, "Subject: %s", msgline);
94: }
95: }
96:
97: if (intcheck()) {
98: fclose(tfp);
99: return(1);
100: }
101:
102: for (;;) {
103: if (fgets(msgline, NLINE, fp) == NULL)
104: break;
105: if (fp == stdin)
106: if ((strcmp(".\n", msgline)==0))
107: break;
108: else if ((strcmp("?\n", msgline)==0)) {
109: eflag = 1;
110: break;
111: }
112: fputs(msgline, tfp);
113: if ( (end-=strlen(msgline)) <= 0 )
114: break;
115: }
116:
117: if (intcheck()) {
118: fclose(tfp);
119: return(1);
120: }
121:
122: if (!callmermail && (sigfp = fopen(mysig, "r")) != NULL) {
123: fputs("\n", tfp);
124: while (fgets(msgline, NLINE, sigfp) != NULL)
125: fputs(msgline, tfp);
126: fclose(sigfp);
127: }
128:
129: /*
130: * Now, see if user wants to edit the message
131: */
132:
133: if (eflag) {
134: xfp = tfp;
135: temp = templ;
136: if ((tfp = fopen(temp, "wr")) == NULL)
137: merr(toerr);
138: chown(temp, myuid, mygid);
139: mcopy(xfp, tfp, (fsize_t)0, (fsize_t)MAXLONG, 0);
140: fclose(xfp);
141: sprintf(cmdname, "exec %s %s", editname, templ);
142: system(cmdname);
143: unlink(temp);
144: temp = NULL;
145: }
146:
147: /*
148: * if empty message, bug out.
149: */
150:
151: if (ftell(tfp) == 0) {
152: fclose(tfp);
153: return(1);
154: }
155:
156: /*
157: * Now see if a copy list is requested.
158: */
159:
160: tolist = users;
161: cclist = (askcc && fromtty && !callmermail) ? getcc(): NULL;
162: allist = listcat(tolist, cclist);
163:
164: if ( verbflag ) {
165: mmsg(
166: "Recipient List:\n\n");
167: for (listpp=allist; *listpp != NULL; listpp++)
168: mmsg("\t%s\n", *listpp);
169: }
170:
171: /*
172: * Now send the message.
173: */
174:
175: time(&curtime);
176: tp = localtime(&curtime);
177:
178: if (callmexmail)
179: xsend(allist, tfp);
180: else
181: usend(allist, tfp);
182:
183: return( senderr );
184: }
185:
186: usend(users, tfp)
187: char **users;
188: FILE *tfp;
189: {
190: FILE *xfp;
191: char *name;
192: char **ulist, **listpp;
193: char command[CMDLINE];
194: char *arpadate();
195: FILE *popen();
196:
197: logdump("Date: %s From: %s!%s (%s)\n",
198: arpadate(tp), mysite, myname, myfullname);
199: for (ulist = users; (name=*ulist) != NULL; ulist++)
200: logdump("To: \"%s\"\n", name);
201:
202: /* Build the command line to the delivery program. */
203: if ( callmexmail ) {
204: strcpy(command, XDELIVER); /* usually "/bin/rxmail" */
205: } else {
206: strcpy(command, DELIVER); /* usually "/bin/rmail" */
207: } /* if ( callmexmail ) */
208:
209: /* Add the list of recipients to the command line. */
210: for (listpp = users; *listpp != NULL; listpp++) {
211: strcat(command, " ");
212: strcat(command, *listpp);
213: }
214:
215: /* NB: I think there may be a security problem
216: here, since popen ought to exec $SHELL. Check this. */
217: /* Now actually call the mail delivery agent. */
218: if ( (xfp = popen(command, "w")) == NULL ) {
219: /* Report a send error and return. */
220: }
221:
222: /* Pump the headers into the delivery agent. */
223: build_header(xfp);
224:
225: /* Pump the message into the delivery agent. */
226: rewind(tfp);
227: mcopy(tfp, xfp, (fsize_t)0, (fsize_t)MAXLONG, 0);
228:
229: fclose(xfp);
230: fclose(tfp);
231: }
232:
233: xsend(users, tfp) char **users; FILE *tfp;
234: {
235: register char **ulist;
236: register char *cp;
237: register struct passwd *pwp;
238: FILE *xfp;
239:
240: for (ulist = users; *ulist!=NULL; ulist++) {
241: rewind(tfp);
242: sprintf(boxname, "%s%s", SPOOLDIR, *ulist);
243: sprintf(cmdname, "xencode %s >> %s", *ulist, boxname);
244: if (index(*ulist, '!') != NULL
245: || (pwp = getpwnam(*ulist)) == NULL) {
246: mmsg(nosend, *ulist);
247: continue;
248: }
249: if (xaccess(*ulist) == 0) {
250: mmsg(nopubk, *ulist);
251: continue;
252: }
253: mlock(pwp->pw_uid);
254: if ((xfp = fopen(boxname, "a")) == NULL) {
255: mmsg(nosend, *ulist);
256: munlock();
257: continue;
258: }
259: chown(boxname, pwp->pw_uid, pwp->pw_gid);
260: fprintf(xfp, "From xmail %s %s\n", cp,
261: tzname[tp->tm_isdst ? 1 : 0]);
262: fclose(xfp);
263: if ((xfp = popen(cmdname, "w")) == NULL) {
264: mmsg("Can't pipe to xencode\n");
265: continue;
266: }
267: if (fwrite(header, strlen(header), 1, xfp) != 1
268: || mcopy(tfp, xfp, (fsize_t)0, (fsize_t)MAXLONG, 0)) {
269: merr(wrerr, cmdname);
270: }
271: pclose(xfp);
272: munlock();
273: }
274: fclose(tfp);
275: }
276:
277: uucpname()
278: {
279: FILE *uufile;
280:
281: if (NULL == (uufile = fopen(NODENAME, "r"))) {
282: strcpy(mysite, "<unknown>");
283: return;
284: }
285: fgets(mysite, sizeof mysite, uufile);
286: mysite[strlen(mysite) - 1] = '\0'; /* remove '\n' */
287: fclose(uufile);
288: return;
289: }
290:
291: domainname()
292: {
293: FILE *domfile;
294: if((domfile = fopen(DOMAINNAME, "r")) == NULL) {
295: strcpy(domain, ".UNKNOWN");
296: return;
297: }
298: fgets(domain, sizeof domain, domfile);
299: domain [strlen(domain) - 1] = '\0';
300: fclose (domfile);
301: return;
302: }
303:
304: char *
305: arpadate(tp)
306: struct tm *tp;
307: {
308: static char arpabuf [64];
309: static char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
310: sprintf(arpabuf, "%d %c%c%c %d %02d:%02d:%02d",
311: tp->tm_mday,
312: months[tp->tm_mon * 3],
313: months[tp->tm_mon * 3 + 1],
314: months[tp->tm_mon * 3 + 2],
315: tp->tm_year,
316: tp->tm_hour, tp->tm_min, tp->tm_sec);
317: return arpabuf;
318: }
319:
320: char *
321: msgid(tp)
322: struct tm *tp;
323: {
324: static char msgidbuf [32];
325: sprintf(msgidbuf, "%02d%02d%02d%02d%02d",
326: tp->tm_year, tp->tm_mon + 1, tp->tm_mday, tp->tm_hour, tp->tm_min);
327: return msgidbuf;
328: }
329:
330: build_header(xfp)
331: FILE *xfp;
332: {
333: char **ulist;
334: int processid;
335:
336: /* Generate a Message-Id. */
337: processid = getpid();
338: sprintf(header, "Message-Id: <%s.AA%d.V%s@%s.%s>\n",
339: msgid(tp), processid, revnop(), mysite, domain);
340: if (fwrite(header, strlen(header), 1, xfp) != 1)
341: return 0;
342:
343: /* generate Date: and From: lines. */
344: sprintf(header, "Date: %s\nFrom: %s@%s.%s (%s)\n",
345: arpadate(tp), myname, mysite, domain, myfullname);
346: if (fwrite(header, strlen(header), 1, xfp) != 1)
347: return 0;
348:
349: /* Generate the full To: lines. We just spit addresses out
350: verbatum, with no cleanup. */
351: strcpy(header, "To:");
352: for (ulist=tolist; *ulist != NULL; ulist++) {
353: strcat(header, " ");
354: strcat(header, *ulist);
355: }
356: strcat(header, "\n");
357: if (fwrite(header, strlen(header), 1, xfp) != 1)
358: return 0;
359:
360: /* Generate a Cc: line if needed. */
361: if (cclist[0] != NULL) {
362: strcpy(header, "Cc:");
363: for (ulist=cclist; *ulist != NULL; ulist++) {
364: strcat(header, " ");
365: strcat(header, *ulist);
366: }
367: strcat(header, "\n");
368: if (fwrite(header, strlen(header), 1, xfp) != 1)
369: return 0;
370: }
371: return 1;
372: }
373:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.