1*8188Smckusick static char sccsid[] = "@(#)mmail.c 4.1 (Berkeley) 09/12/82";
2*8188Smckusick
3*8188Smckusick # include "defs.h"
4*8188Smckusick /* sccs id variable */
5*8188Smckusick static char *mmail_sid = "@(#)mmail.c 1.2";
6*8188Smckusick
7*8188Smckusick /*
8*8188Smckusick Mmail is a berkeley network internal command.
9*8188Smckusick It is executed locally by the mwrite command,
10*8188Smckusick and from a remote machine by the sendberkmail command.
11*8188Smckusick Its purpose is to send mail to a user on this
12*8188Smckusick machine using the system mail program.
13*8188Smckusick
14*8188Smckusick Archaic Usage:
15*8188Smckusick
16*8188Smckusick mmail [-commandsent -timesent] fromuser frommach touser
17*8188Smckusick
18*8188Smckusick Correct Usage:
19*8188Smckusick mmail [-c commandsent] [-e timesent] [-f fromaddress] [-t toaddress]
20*8188Smckusick [-h hopcnt] [-r rc] [-z]
21*8188Smckusick
22*8188Smckusick The mwrite command uses all the options.
23*8188Smckusick The sendberkmail command does not use the commandsend, timesent and rc
24*8188Smckusick options.
25*8188Smckusick Timesent is time in seconds since 1901 in decimal, as returned by time().
26*8188Smckusick Frommach is a multi-character name, not a single letter.
27*8188Smckusick Rc is the return code (exit code>>8) of the command.
28*8188Smckusick
29*8188Smckusick Assumptions about the system mail command:
30*8188Smckusick 1. We assume there is an optional argument "-r" which can be added to mail.
31*8188Smckusick Mail argument format (two choices):
32*8188Smckusick
33*8188Smckusick mail -r fromaddress toaddress
34*8188Smckusick
35*8188Smckusick which becomes mail from "fromaddress" instead of "network".
36*8188Smckusick
37*8188Smckusick 2. We assume that mail accepts the "-h hopcnt" flag, and passes it thru
38*8188Smckusick unchanged to the sendberkmail program. The hopcnt is incremented everytime
39*8188Smckusick it passes thru mmail, so inifinite mail forwarding is detected.
40*8188Smckusick Since both the from and to addresses cycle, it there is infinite looping
41*8188Smckusick we simply mail to root to that effect and throw away the mail.
42*8188Smckusick
43*8188Smckusick
44*8188Smckusick If this argument scheme looks flakey it is because I screwed up
45*8188Smckusick in the argument design. With the network now up to 10 machines,
46*8188Smckusick I can't add another parameter to the internal commands of the network
47*8188Smckusick like mmail and mwrite. If I had used labeled parms instead of
48*8188Smckusick positional parms, I would be able to add more options/info
49*8188Smckusick without having to recompile all code...
50*8188Smckusick
51*8188Smckusick exit codes:
52*8188Smckusick normally returns the exit code from the mail program
53*8188Smckusick
54*8188Smckusick */
main(argc,argv)55*8188Smckusick main(argc,argv)
56*8188Smckusick char **argv; {
57*8188Smckusick int n, ret, i, hopcnt = 0, pid;
58*8188Smckusick char *sargv[20], *cmdstr=NULL, buf[BUFSIZ], *timestr,
59*8188Smckusick fromaddress[BUFSIZ];
60*8188Smckusick char toaddress[BUFSIZ], src[20], snFrom[BUFSIZ], snto[BUFSIZ],
61*8188Smckusick mchFrom, mchto, stemp[BUFSIZ], fisresponse = 0;
62*8188Smckusick long timesent = TIMEBASE, el;
63*8188Smckusick FILE *fdm;
64*8188Smckusick
65*8188Smckusick debugflg = DBV;
66*8188Smckusick src[0] = 0;
67*8188Smckusick
68*8188Smckusick /* parse old format positional parms */
69*8188Smckusick if(argv[1][0] == '-'){
70*8188Smckusick cmdstr = argv[1] + 1;
71*8188Smckusick timesent = atol(argv[2] + 1);
72*8188Smckusick sprintf(fromaddress,"%s:%s",argv[4],argv[3]);
73*8188Smckusick strcpy(toaddress,argv[5]);
74*8188Smckusick }
75*8188Smckusick else {
76*8188Smckusick sprintf(fromaddress,"%s:%s",argv[2],argv[1]);
77*8188Smckusick strcpy(toaddress,argv[3]);
78*8188Smckusick }
79*8188Smckusick argv[argc] = 0;
80*8188Smckusick
81*8188Smckusick /* parse labeled parameters */
82*8188Smckusick /* prob because of -cmd in arg1 and arg2 */
83*8188Smckusick for(i = 1; i < argc; i++){
84*8188Smckusick if(argv[i][0] == '-' && argv[i][2] == 0)
85*8188Smckusick switch(argv[i][1]){
86*8188Smckusick case 'f':
87*8188Smckusick strcpy(fromaddress,argv[++i]);
88*8188Smckusick break;
89*8188Smckusick case 'c':
90*8188Smckusick cmdstr = argv[++i];
91*8188Smckusick break;
92*8188Smckusick case 'e':
93*8188Smckusick timesent = atol(argv[++i]);
94*8188Smckusick break;
95*8188Smckusick case 't':
96*8188Smckusick strcpy(toaddress,argv[++i]);
97*8188Smckusick break;
98*8188Smckusick case 'h':
99*8188Smckusick hopcnt = atoi(argv[++i]);
100*8188Smckusick break;
101*8188Smckusick case 'r':
102*8188Smckusick strcpy(src,argv[++i]);
103*8188Smckusick break;
104*8188Smckusick case 'z':
105*8188Smckusick fisresponse++;
106*8188Smckusick break;
107*8188Smckusick /* it is important there be no error if an unknown
108*8188Smckusick flag is encountered */
109*8188Smckusick }
110*8188Smckusick }
111*8188Smckusick mchFrom = MchSFromAddr(snFrom,fromaddress);
112*8188Smckusick
113*8188Smckusick /* compute time send */
114*8188Smckusick timestr = ctime(×ent);
115*8188Smckusick timestr[strlen(timestr) - 6] = 0;
116*8188Smckusick el = gettime() - timesent;
117*8188Smckusick
118*8188Smckusick /* check the hopcnt */
119*8188Smckusick hopcnt++;
120*8188Smckusick if(hopcnt > MAXHOPS)hopcnterr(toaddress, hopcnt);
121*8188Smckusick
122*8188Smckusick /* analyze the dest, if local, strip off mach name, otherwise ok */
123*8188Smckusick mchto = MchSFromAddr(snto,toaddress);
124*8188Smckusick if(mchto == local)strcpy(toaddress,snto);
125*8188Smckusick
126*8188Smckusick /* it is important to realize that mmail is executed
127*8188Smckusick either as root, network, or the USER!
128*8188Smckusick So the -r option must be accepted (and possibly ignored)
129*8188Smckusick by the mail program if the user is a reandom user.
130*8188Smckusick */
131*8188Smckusick /* now we fork off a mail command. if fisresponse, then
132*8188Smckusick we are "cautious" and don't use mail forwarders */
133*8188Smckusick
134*8188Smckusick fdm = mailopen(toaddress, fromaddress, fisresponse, hopcnt);
135*8188Smckusick if(cmdstr != NULL){
136*8188Smckusick if(src[0] != 0)sprintf(stemp,", R: %s", src);
137*8188Smckusick else stemp[0] = 0;
138*8188Smckusick fprintf(fdm,"Subject: \"%s\"%s, sent %s, took %s\n",
139*8188Smckusick cmdstr,stemp,timestr,comptime(el));
140*8188Smckusick }
141*8188Smckusick while((n = fread(buf,1,BUFSIZ,stdin)) > 0)
142*8188Smckusick fwrite(buf,1,n,fdm);
143*8188Smckusick ret = mailclose(fdm);
144*8188Smckusick ret >>= 8;
145*8188Smckusick if(ret != 0)
146*8188Smckusick fprintf(stderr,
147*8188Smckusick "Non-zero return code (%d) from the mail program.\n",ret);
148*8188Smckusick exit(ret);
149*8188Smckusick }
150*8188Smckusick /*
151*8188Smckusick hopcnterr()
152*8188Smckusick
153*8188Smckusick there appears to be infinite mail forwarding -
154*8188Smckusick as detected by the hop count. Mail to root and give up.
155*8188Smckusick Both the from and to addresses are cycling, so mail
156*8188Smckusick can't be sent there.
157*8188Smckusick */
hopcnterr(toaddress,hopcnt)158*8188Smckusick hopcnterr(toaddress,hopcnt)
159*8188Smckusick char *toaddress;
160*8188Smckusick int hopcnt;
161*8188Smckusick {
162*8188Smckusick char cmdstr[BUFSIZ];
163*8188Smckusick int rcode;
164*8188Smckusick sprintf(cmdstr,"echo infinite mail loop for %s hops %d | mail root",
165*8188Smckusick toaddress,hopcnt);
166*8188Smckusick rcode = system(cmdstr);
167*8188Smckusick exit(EX_OSERR);
168*8188Smckusick /*UNREACHED*/
169*8188Smckusick }
170