|
|
1.1 root 1: /*
2: * The code that basically handles the sending of
3: * an individual message in the mail system.
4: */
5:
6: #include "mail.h"
7:
8: #define SITENAMELEN 32 /* max length of sitename */
9:
10: extern char *strtok();
11: FILE *aliasfp;
12: char aliasbuf [BUFSIZ];
13: static char **tolist;
14:
15: extern char *temp;
16: extern int myuid; /* User-id of mail user */
17: extern int mygid; /* Group-id of mail user */
18: extern char cmdname[]; /* Command for x{en,de}code filter */
19: /* and for tail recursion to uumail */
20: /* and for editor recursion */
21: extern char *editname; /* name of editor */
22: extern char *askcc; /* Ask for CC: list? (YES/NO) */
23: extern int callmexmail; /* Xmail modifier present */
24: extern char wrerr[];
25: extern char myname[]; /* User name */
26: extern char myfullname[]; /* full user name */
27: extern int mflag; /* `You have mail.' message to recipient */
28: extern int verbflag; /* verbose flag */
29: extern char templ[]; /* Temp file name template */
30: extern char nosave[];
31: extern int callmermail;
32:
33: static int senderr;
34: struct tm *tp;
35: char toerr[] = "Cannot create temporary file\n";
36: char header[BUFSIZ]; /* Message header */
37: char boxname[256]; /* Destination mailbox */
38: char remotefrom [32]; /* "remote from uucp" */
39:
40: char nosend[] = "Can't send mail to '%s'\n";
41: char nopubk[] = "Can't send xmail to '%s'\n";
42:
43: /*
44: * Send the message found on
45: * the file pointer to the list
46: * of people (argv style) with
47: * a NULL pointer at the end.
48: * The message is copied to a temp-file
49: * from position `start' to `end' (or EOF).
50: */
51: send2(fp, users, start, end, asksubj)
52: FILE *fp;
53: register char **users;
54: fsize_t start, end;
55: int asksubj;
56: {
57: char **getcc();
58: FILE *xfp, *tfp, *sigfp;
59: time_t curtime;
60:
61: senderr = 0;
62: temp = templ;
63:
64: if ((tfp = fopen(temp, "w")) != NULL) {
65: fclose(tfp);
66: if ((tfp = fopen(temp, "r+w")) == NULL)
67: merr(toerr);
68: } else
69: merr(toerr);
70: chown(temp, myuid, mygid);
71: unlink(temp);
72: temp = NULL;
73: fseek(fp, start, 0);
74: end -= start;
75:
76: if (intcheck()) {
77: fclose(tfp);
78: return(1);
79: }
80:
81: for (;;) {
82: if (fgets(msgline, NLINE, fp) == NULL)
83: break;
84: fputs(msgline, tfp);
85: if ( (end-=strlen(msgline)) <= 0 )
86: break;
87: }
88:
89: if (intcheck()) {
90: fclose(tfp);
91: return(1);
92: }
93:
94: /*
95: * if empty message, bug out.
96: */
97:
98: if (ftell(tfp) == 0) {
99: fclose(tfp);
100: return(1);
101: }
102:
103: /*
104: * Now send the message.
105: */
106:
107: time(&curtime);
108: tp = localtime(&curtime);
109:
110: if (callmexmail)
111: xsend(users, tfp);
112: else
113: usend(users, tfp);
114:
115: return( senderr );
116: }
117:
118: usend(users, tfp)
119: char **users;
120: FILE *tfp;
121: {
122: FILE *xfp;
123: char *cp, *name;
124: char **ulist;
125: register struct passwd *pwp;
126:
127: for (ulist = users; (name=*ulist) != NULL; ulist++) {
128: rewind(tfp);
129:
130:
131: sprintf(boxname, "%s%s", SPOOLDIR, name);
132: if ((pwp = getpwnam(name)) == NULL) {
133: /* RFC 822 (Internet) addresses are case independent,
134: * so valid local addresses must should be lower case.
135: */
136: lcase(name);
137: sprintf(boxname, "%s%s", SPOOLDIR, name);
138: if ((pwp = getpwnam(name)) == NULL) {
139: mmsg(nosend, name);
140: logdump(nosend, name);
141: senderr = 1;
142: continue;
143: }
144: }
145:
146: mlock(pwp->pw_uid);
147: if ((xfp = fopen(boxname, "a")) == NULL) {
148: mmsg(nosend, name);
149: logdump(nosend, name);
150: senderr = 1;
151: munlock();
152: continue;
153: }
154: chown(boxname, pwp->pw_uid, pwp->pw_gid);
155: mcopy(tfp, xfp, ftell(tfp), (fsize_t)MAXLONG, 0);
156: fprintf(xfp, "\n\1\1\n");
157: fclose(xfp);
158: munlock();
159: advise(name);
160: }
161:
162: if (senderr && callmermail) {
163: mmsg("error sending mail, text of message follows:\n\n");
164: mmsg("------------------------\n\n");
165: rewind(tfp);
166: mcopy(tfp, stdout, ftell(tfp), (fsize_t)MAXLONG, 0);
167: mmsg("\n------------------------\n\n");
168: }
169:
170: fclose(tfp);
171: }
172:
173: xsend(users, tfp) char **users; FILE *tfp;
174: {
175: register char **ulist;
176: register char *cp;
177: register struct passwd *pwp;
178: FILE *xfp;
179:
180: for (ulist = users; *ulist!=NULL; ulist++) {
181: rewind(tfp);
182: sprintf(boxname, "%s%s", SPOOLDIR, *ulist);
183: sprintf(cmdname, "xencode %s >> %s", *ulist, boxname);
184: if (index(*ulist, '!') != NULL
185: || (pwp = getpwnam(*ulist)) == NULL) {
186: mmsg(nosend, *ulist);
187: continue;
188: }
189: if (xaccess(*ulist) == 0) {
190: mmsg(nopubk, *ulist);
191: continue;
192: }
193: mlock(pwp->pw_uid);
194: if ((xfp = fopen(boxname, "a")) == NULL) {
195: mmsg(nosend, *ulist);
196: munlock();
197: continue;
198: }
199: chown(boxname, pwp->pw_uid, pwp->pw_gid);
200: fprintf(xfp, "From xmail %s %s\n", cp,
201: tzname[tp->tm_isdst ? 1 : 0]);
202: fclose(xfp);
203: if ((xfp = popen(cmdname, "w")) == NULL) {
204: mmsg("Can't pipe to xencode\n");
205: continue;
206: }
207: if (fwrite(header, strlen(header), 1, xfp) != 1
208: || mcopy(tfp, xfp, (fsize_t)0, (fsize_t)MAXLONG, 0)) {
209: merr(wrerr, cmdname);
210: }
211: pclose(xfp);
212: munlock();
213: }
214: fclose(tfp);
215: }
216:
217: /*
218: * If the `-m' option is specified, advise
219: * the recipient of the presence of mail.
220: */
221: advise(recipient)
222: char *recipient;
223: {
224: register FILE *fp;
225: register FILE *tfp;
226: struct utmp ut;
227: char tty[30];
228: struct stat sb;
229:
230: if (!mflag)
231: return;
232: if ((fp = fopen("/etc/utmp", "r")) == NULL)
233: return;
234: while (fread(&ut, sizeof ut, 1, fp) == 1)
235: if (strncmp(ut.ut_name, recipient, DIRSIZ) == 0) {
236: sprintf(tty, "/dev/%s", ut.ut_line);
237: if (stat(tty, &sb)<0 || (sb.st_mode&S_IEXEC)==0)
238: continue;
239: if ((tfp = fopen(tty, "w")) != NULL) {
240: fprintf(tfp, "\7%s: you have mail.\n", myname);
241: fclose(tfp);
242: }
243: }
244: fclose(fp);
245: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.