xref: /original-bsd/old/berknet/mmail.c (revision f9986144)
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(&timesent);
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