|
|
1.1 root 1: # include "defs.h"
2: /*
3: Mmail is a berkeley network internal command.
4: It is executed locally by the mwrite command,
5: and from a remote machine by the sendberkmail command.
6: Its purpose is to send mail to a user on this
7: machine using the system mail program.
8:
9: Archaic Usage:
10:
11: mmail [-commandsent -timesent] fromuser frommach touser
12:
13: Correct Usage:
14: mmail [-c commandsent] [-e timesent] [-f fromaddress] [-t toaddress]
15: [-h hopcnt] [-r rc] [-z]
16:
17: The mwrite command uses all the options.
18: The sendberkmail command does not use the commandsend, timesent and rc
19: options.
20: Timesent is time in seconds since 1901 in decimal, as returned by time().
21: Frommach is a multi-character name, not a single letter.
22: Rc is the return code (exit code>>8) of the command.
23:
24: Assumptions about the system mail command:
25: 1. We assume there is an optional argument "-r" which can be added to mail.
26: Mail argument format (two choices):
27:
28: (ROPTION)
29: mail -f fromaddress toaddress
30: which becomes mail from "fromaddress" instead of "network".
31:
32: (ROPTION2)
33: mail -r frommach fromuser toaddress
34: which becomes mail from "fromach:fromuser" instead of "network".
35:
36: ROPTION is to be preferred.
37:
38: 2. We assume that mail accepts the "-h hopcnt" flag, and passes it thru
39: unchanged to the sendberkmail program. The hopcnt is incremented everytime
40: it passes thru mmail, so inifinite mail forwarding is detected.
41: Since both the from and to addresses cycle, it there is infinite looping
42: we simply mail to root to that effect and throw away the mail.
43:
44:
45: If this argument scheme looks flakey it is because I screwed up
46: in the argument design. With the network now up to 10 machines,
47: I can't add another parameter to the internal commands of the network
48: like mmail and mwrite. If I had used labeled parms instead of
49: positional parms, I would be able to add more options/info
50: without having to recompile all code...
51:
52: exit codes:
53: normally returns the exit code from the mail program
54: returns 101 if unable to exec the mail program
55: returns 102 if infinite mail forwarding loop is detected.
56:
57: NUID is the value returned from getuid for "network" account.
58: */
59: main(argc,argv)
60: char **argv; {
61: int pip[2], n, ret, i, uid, roption = 0, hopcnt = 0, pid;
62: char *sargv[20], *cmdstr=NULL, buf[BUFSIZ], *timestr, fromaddress[BUFSIZ];
63: char toaddress[BUFSIZ], src[20], snFrom[BUFSIZ], snto[BUFSIZ], mchFrom, mchto,
64: *sn, stemp[BUFSIZ], fisresponse = 0;
65: long timesent = TIMEBASE, el;
66:
67: debugflg = DBV;
68: src[0] = 0;
69:
70: /* parse old format positional parms */
71: if(argv[1][0] == '-'){
72: cmdstr = argv[1] + 1;
73: timesent = atol(argv[2] + 1);
74: sprintf(fromaddress,"%s:%s",argv[4],argv[3]);
75: strcpy(toaddress,argv[5]);
76: }
77: else {
78: sprintf(fromaddress,"%s:%s",argv[2],argv[1]);
79: strcpy(toaddress,argv[3]);
80: }
81: argv[argc] = 0;
82:
83: /* parse labeled parameters */
84: /* prob because of -cmd in arg1 and arg2 */
85: for(i = 1; i < argc; i++){
86: if(argv[i][0] == '-' && argv[i][2] == 0)
87: switch(argv[i][1]){
88: case 'f':
89: strcpy(fromaddress,argv[++i]);
90: break;
91: case 'c':
92: cmdstr = argv[++i];
93: break;
94: case 'e':
95: timesent = atol(argv[++i]);
96: break;
97: case 't':
98: strcpy(toaddress,argv[++i]);
99: break;
100: case 'h':
101: hopcnt = atoi(argv[++i]);
102: break;
103: case 'r':
104: strcpy(src,argv[++i]);
105: break;
106: case 'z':
107: fisresponse++;
108: break;
109: /* it is important there be no error if an unknown
110: flag is encountered */
111: }
112: }
113: mchFrom = MchSFromAddr(snFrom,fromaddress);
114:
115: /* compute time send */
116: timestr = ctime(×ent);
117: timestr[strlen(timestr) - 6] = 0;
118: el = gettime() - timesent;
119:
120: # ifdef ROPTION
121: /* only use roption if super-user or "network" */
122: /*
123: uid = getuid();
124: uid = uidmask(uid);
125: if(uid == SUPERUSER || uid == NUID)roption++;
126: */
127: /* or if mail is to the same user who is sending it */
128: /*
129: sn = SnCurrent();
130: if(sn != NULL){
131: stemp[0] = 0;
132: mchfrom = MchSFromAddr(stemp,fromaddress);
133: if(strcmp(stemp,????) == 0)roption++;
134: }
135: uid = geteuid();
136: uid = uidmask(uid);
137: if(uid == SUPERUSER || uid == NUID)roption++;
138: */
139: roption++;
140: # endif
141:
142: # ifdef ROPTION2
143: /* only use roption if super-user or "network" */
144: uid = getuid();
145: uid = uidmask(uid);
146: if(uid == SUPERUSER || uid == NUID)roption++;
147: /* or if mail is to the same user who is sending it */
148: /* disabled since mail must accept this and it does not now */
149: /* if(strcmp(SnCurrent(),argv[3]) == 0)roption++; */
150: uid = geteuid();
151: uid = uidmask(uid);
152: if(uid == SUPERUSER || uid == NUID)roption++;
153: # endif
154:
155: /* check the hopcnt */
156: hopcnt++;
157: if(hopcnt > MAXHOPS)hopcnterr(toaddress, hopcnt);
158:
159: /* analyze the dest, if local, strip off mach name, otherwise ok */
160: mchto = MchSFromAddr(snto,toaddress);
161: if(mchto == local)strcpy(toaddress,snto);
162:
163: /* add the hopcnt here */
164: if(roption){
165: sargv[1] = "-r";
166: # ifdef ROPTION2
167: sargv[2] = longname(mchFrom);
168: sargv[3] = snFrom;
169: sargv[4] = toaddress;
170: sargv[5] = 0;
171: # endif
172: # ifdef ROPTION
173: sargv[2] = fromaddress;
174: sargv[3] = toaddress;
175: sargv[4] = 0;
176: # endif
177: }
178: else {
179: sargv[1] = toaddress;
180: sargv[2] = 0;
181: }
182: sargv[0] = "mail";
183: pipe(pip);
184: while((pid = fork()) == -1)sleep(2);
185: if(pid == 0){
186: close(pip[1]);
187: close(0);
188: dup(pip[0]);
189: /* by convention, SYSMAIL1 may forward this mail
190: and response messages shouldn't be forwarded */
191: if(!fisresponse)
192: execv(SYSMAIL1, sargv);
193: execv(SYSMAIL2, sargv);
194: execv(SYSMAIL3, sargv);
195: execv(SYSMAIL4, sargv);
196: exit(101);
197: /* mexecv is not used because it gives a diagnostic */
198: }
199: close(pip[0]);
200: close(1);
201: dup(pip[1]);
202: if(!roption)
203: printf("(from %s)\n",fromaddress);
204: if(cmdstr != NULL){
205: if(src[0] != 0)sprintf(stemp,", R: %s", src);
206: else stemp[0] = 0;
207: printf("(command: %s%s, sent %s, took %s)\n",
208: cmdstr,stemp,timestr,comptime(el));
209: }
210: fflush(stdout);
211: while((n = read(0,buf,BUFSIZ)) > 0)
212: write(pip[1],buf,n);
213: close(pip[1]);
214: close(1);
215: wait(&ret);
216: ret >>= 8;
217: if(ret != 0)
218: fprintf(stderr,
219: "Non-zero return code (%d) from the mail program.\n",ret);
220: exit(ret);
221: }
222: /*
223: hopcnterr()
224:
225: there appears to be infinite mail forwarding -
226: as detected by the hop count. Mail to root and give up.
227: Both the from and to addresses are cycling, so mail
228: can't be sent there.
229: */
230: hopcnterr(toaddress,hopcnt)
231: char *toaddress;
232: int hopcnt;
233: {
234: char cmdstr[BUFSIZ];
235: int rcode;
236: sprintf(cmdstr,"echo infinite mail loop for %s hops %d | mail root",
237: toaddress,hopcnt);
238: rcode = system(cmdstr);
239: exit(102);
240: /*UNREACHED*/
241: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.