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