|
|
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:
123: if (!callmermail && (sigfp = fopen(mysig, "r")) != NULL) {
124: fputs("\n", tfp);
125: while (fgets(msgline, NLINE, sigfp) != NULL)
126: fputs(msgline, tfp);
127: fclose(sigfp);
128: }
129:
130:
131: /*
132: * Now, see if user wants to edit the message
133: */
134:
135: if (eflag) {
136: xfp = tfp;
137: temp = templ;
138: if ((tfp = fopen(temp, "wr")) == NULL)
139: merr(toerr);
140: chown(temp, myuid, mygid);
141: mcopy(xfp, tfp, (fsize_t)0, (fsize_t)MAXLONG, 0);
142: fclose(xfp);
143: sprintf(cmdname, "exec %s %s", editname, templ);
144: system(cmdname);
145: unlink(temp);
146: temp = NULL;
147: }
148:
149: /*
150: * if empty message, bug out.
151: */
152:
153: if (ftell(tfp) == 0) {
154: fclose(tfp);
155: return(1);
156: }
157:
158: /*
159: * Now see if a copy list is requested.
160: */
161:
162: tolist = users;
163: cclist = (askcc && fromtty && !callmermail) ? getcc(): NULL;
164: allist = listcat(tolist, cclist);
165:
166: if ( verbflag ) {
167: mmsg(
168: "Recipient List:\n\n");
169: for (listpp=allist; *listpp != NULL; listpp++)
170: mmsg("\t%s\n", *listpp);
171: }
172:
173: /*
174: * Now send the message.
175: */
176:
177: time(&curtime);
178: tp = localtime(&curtime);
179:
180: if (callmexmail){
181: xsend(allist, tfp);
182: }else{
183: usend(allist, tfp);
184: }
185:
186: return( senderr );
187: }
188:
189: usend(users, tfp)
190: char **users;
191: FILE *tfp;
192: {
193: FILE *xfp;
194: char *name;
195: char **ulist, **listpp;
196: char command[CMDLINE];
197: char *arpadate();
198: FILE *popen();
199:
200: logdump("Date: %s From: %s!%s (%s)\n",
201: arpadate(tp), mysite, myname, myfullname);
202: for (ulist = users; (name=*ulist) != NULL; ulist++)
203: logdump("To: \"%s\"\n", name);
204:
205: /* Build the command line to the delivery program. */
206: if ( callmexmail ) {
207: strcpy(command, XDELIVER); /* usually "/bin/rxmail" */
208: } else {
209: strcpy(command, DELIVER); /* usually "/bin/rmail" */
210: } /* if ( callmexmail ) */
211:
212: /* Add the list of recipients to the command line. */
213:
214: for (listpp = users; *listpp != NULL; listpp++) {
215: strcat(command, " ");
216: strcat(command, *listpp);
217: }
218:
219: /* NB: I think there may be a security problem
220: here, since popen ought to exec $SHELL. Check this. */
221: /* Now actually call the mail delivery agent. */
222:
223:
224: if ( (xfp = popen(command, "w")) == NULL ) {
225: /* Report a send error and return. */
226: }
227:
228: /* Pump the headers into the delivery agent. */
229:
230: build_header(xfp);
231:
232: /* Pump the message into the delivery agent. */
233:
234: rewind(tfp);
235: mcopy(tfp, xfp, (fsize_t)0, (fsize_t)MAXLONG, 0);
236:
237: fclose(xfp);
238: fclose(tfp);
239: }
240:
241: xsend(users, tfp) char **users; FILE *tfp;
242: {
243: register char **ulist;
244: register char *cp;
245: register struct passwd *pwp;
246: FILE *xfp;
247:
248: for (ulist = users; *ulist!=NULL; ulist++) {
249: rewind(tfp);
250: sprintf(boxname, "%s%s", SPOOLDIR, *ulist);
251: sprintf(cmdname, "xencode %s >> %s", *ulist, boxname);
252: if (index(*ulist, '!') != NULL
253: || (pwp = getpwnam(*ulist)) == NULL) {
254: mmsg(nosend, *ulist);
255: continue;
256: }
257: if (xaccess(*ulist) == 0) {
258: mmsg(nopubk, *ulist);
259: continue;
260: }
261: mlock(pwp->pw_uid);
262: if ((xfp = fopen(boxname, "a")) == NULL) {
263: mmsg(nosend, *ulist);
264: munlock();
265: continue;
266: }
267: chown(boxname, pwp->pw_uid, pwp->pw_gid);
268: fprintf(xfp, "From xmail %s %s\n", cp,
269: tzname[tp->tm_isdst ? 1 : 0]);
270: fclose(xfp);
271: if ((xfp = popen(cmdname, "w")) == NULL) {
272: mmsg("Can't pipe to xencode\n");
273: continue;
274: }
275: if (fwrite(header, strlen(header), 1, xfp) != 1
276: || mcopy(tfp, xfp, (fsize_t)0, (fsize_t)MAXLONG, 0)) {
277: merr(wrerr, cmdname);
278: }
279: pclose(xfp);
280: munlock();
281: }
282: fclose(tfp);
283: }
284:
285: uucpname()
286: {
287: FILE *uufile;
288:
289: if (NULL == (uufile = fopen(NODENAME, "r"))) {
290: strcpy(mysite, "<unknown>");
291: return;
292: }
293: fgets(mysite, sizeof mysite, uufile);
294: mysite[strlen(mysite) - 1] = '\0'; /* remove '\n' */
295: fclose(uufile);
296: return;
297: }
298:
299: domainname()
300: {
301: FILE *domfile;
302: if((domfile = fopen(DOMAINNAME, "r")) == NULL) {
303: strcpy(domain, ".UNKNOWN");
304: return;
305: }
306: fgets(domain, sizeof domain, domfile);
307: domain [strlen(domain) - 1] = '\0';
308: fclose (domfile);
309: return;
310: }
311:
312: char *
313: arpadate(tp)
314: struct tm *tp;
315: {
316: static char arpabuf [64];
317: static char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
318: sprintf(arpabuf, "%d %c%c%c %d %02d:%02d:%02d",
319: tp->tm_mday,
320: months[tp->tm_mon * 3],
321: months[tp->tm_mon * 3 + 1],
322: months[tp->tm_mon * 3 + 2],
323: tp->tm_year,
324: tp->tm_hour, tp->tm_min, tp->tm_sec);
325: return arpabuf;
326: }
327:
328: char *
329: msgid(tp)
330: struct tm *tp;
331: {
332: static char msgidbuf [32];
333: sprintf(msgidbuf, "%02d%02d%02d%02d%02d",
334: tp->tm_year, tp->tm_mon + 1, tp->tm_mday, tp->tm_hour, tp->tm_min);
335: return msgidbuf;
336: }
337:
338: build_header(xfp)
339: FILE *xfp;
340: {
341: char **ulist;
342: int processid;
343:
344: /* Generate a Message-Id. */
345: processid = getpid();
346: sprintf(header, "Message-Id: <%s.AA%d.V%s@%s.%s>\n",
347: msgid(tp), processid, revnop(), mysite, domain);
348: if (fwrite(header, strlen(header), 1, xfp) != 1)
349: return 0;
350:
351: /* generate Date: and From: lines. */
352: sprintf(header, "Date: %s\nFrom: %s@%s.%s (%s)\n",
353: arpadate(tp), myname, mysite, domain, myfullname);
354: if (fwrite(header, strlen(header), 1, xfp) != 1)
355: return 0;
356:
357: /* Generate the full To: lines. We just spit addresses out
358: verbatum, with no cleanup. */
359: strcpy(header, "To:");
360: for (ulist=tolist; *ulist != NULL; ulist++) {
361: strcat(header, " ");
362: strcat(header, *ulist);
363: }
364: strcat(header, "\n");
365: if (fwrite(header, strlen(header), 1, xfp) != 1)
366: return 0;
367:
368: /* Generate a Cc: line if needed. */
369: if (cclist[0] != NULL) {
370: strcpy(header, "Cc:");
371: for (ulist=cclist; *ulist != NULL; ulist++) {
372: strcat(header, " ");
373: strcat(header, *ulist);
374: }
375: strcat(header, "\n");
376: if (fwrite(header, strlen(header), 1, xfp) != 1)
377: return 0;
378: }
379: return 1;
380: }
381:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.