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