xref: /csrg-svn/old/berknet/mmail.c (revision 8188)
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(&timesent);
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