Commit | Line | Data |
---|---|---|
b32ac84b KM |
1 | static char sccsid[] = "@(#)mmail.c 4.1 (Berkeley) %G%"; |
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(×ent); | |
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 | } |