Commit | Line | Data |
---|---|---|
ddcb4516 BJ |
1 | # |
2 | ||
3 | /* | |
4 | * mail command usage | |
5 | * mail [-yn] | |
6 | * prints your mail | |
7 | * mail people | |
8 | * sends standard input to people | |
9 | * | |
10 | * mail -r machine user people | |
11 | * sends mail from the network | |
12 | */ | |
13 | ||
14 | #define SIGINT 2 | |
15 | #define DIRECT 040000 | |
16 | #define RMAILCMD "/usr/net/bin/sendmail" | |
17 | ||
18 | struct inode { | |
19 | char minor; | |
20 | char major; | |
21 | int inumber; | |
22 | int flags; | |
23 | char nlinks; | |
24 | char uid; | |
25 | char gid; | |
26 | char size0; | |
27 | int size1; | |
28 | int addr[8]; | |
29 | int actime[2]; | |
30 | int modtime[2]; | |
31 | } inode; | |
32 | ||
33 | char lettmp[] "/tmp/maXXXXX"; | |
34 | char preptmp[] "/tmp/mbXXXXX"; | |
35 | int pwfil; | |
36 | int chew; | |
37 | int errs; | |
38 | ||
39 | main(argc, argv) | |
40 | char **argv; | |
41 | { | |
42 | register int me; | |
43 | extern int fout; | |
44 | int uf, delexit(); | |
45 | char namebuf[20]; | |
46 | ||
47 | mktemp(lettmp); | |
48 | mktemp(preptmp); | |
49 | unlink(lettmp); | |
50 | unlink(preptmp); | |
51 | me = getuid(); | |
52 | if (getname(me, namebuf) < 0) { | |
53 | printf("Who are you?\n"); | |
54 | delexit(1); | |
55 | } | |
56 | if (argc < 2) | |
57 | goto hitit; | |
58 | for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) | |
59 | switch(argv[0][1]) { | |
60 | register char *cp, *np; | |
61 | ||
62 | case 'y': | |
63 | case 'n': | |
64 | argc++, argv--; | |
65 | hitit: | |
66 | printmail(argc, argv, namebuf); | |
67 | delexit(0); | |
68 | ||
69 | case 'r': | |
70 | if (argc < 2) | |
71 | continue; | |
72 | if (!equal("network", namebuf) && me != 0) { | |
73 | printf("Nice try!\n"); | |
74 | delexit(1); | |
75 | } | |
76 | chew++; | |
77 | np = namebuf; | |
78 | for (cp = argv[1]; *cp; cp++) | |
79 | *np++ = *cp; | |
80 | argc--, argv++; | |
81 | *np++ = ':'; | |
82 | for (cp = argv[1]; *cp; cp++) | |
83 | *np++ = *cp; | |
84 | *np++ = 0; | |
85 | argc--, argv++; | |
86 | continue; | |
87 | } | |
88 | if ((signal(SIGINT, 01) & 01) == 0) | |
89 | signal(SIGINT, delexit); | |
90 | unlink(lettmp); | |
91 | fout = creat(lettmp, 0600); | |
92 | if (fout < 0) { | |
93 | fout = 1; | |
94 | perror(lettmp); | |
95 | delexit(1); | |
96 | } | |
97 | argc++, argv--; | |
98 | bulkmail(argc, argv, namebuf); | |
99 | delexit(0); | |
100 | } | |
101 | ||
102 | printmail(argc, argv, name) | |
103 | char **argv; | |
104 | char *name; | |
105 | { | |
106 | extern int fin, fout; | |
107 | register n, c, f; | |
108 | char *mname; | |
109 | ||
110 | mname = cat("/usr/mail/", name); | |
111 | if (stat(mname, &inode)>=0 && inode.nlinks==1 && | |
112 | fopen(mname, &fin)>=0 && (c = getchar())) { | |
113 | putchar(c); | |
114 | getput(); | |
115 | close(fin); | |
116 | c = 'y'; | |
117 | if (argc<2) { | |
118 | if (ttyn(0)!='x') { | |
119 | printf("Save?"); | |
120 | fin = 0; | |
121 | c = getchar(); | |
122 | } | |
123 | } else | |
124 | c = argv[1][1]; | |
125 | if (!any(c, "yn")) | |
126 | delexit(0); | |
127 | if (c == 'y') { | |
128 | if (accesss("mbox")) { | |
129 | printf("Saved mail in 'mbox'\n"); | |
130 | prepend(mname, "mbox", getuid()); | |
131 | unlink(mname); | |
132 | } else | |
133 | printf("In wrong directory\n"); | |
134 | } else | |
135 | unlink(mname); | |
136 | } else | |
137 | printf("No mail.\n"); | |
138 | } | |
139 | ||
140 | bulkmail(argc, argv, from) | |
141 | char **argv, *from; | |
142 | { | |
143 | extern int fin, fout; | |
144 | register int c; | |
145 | int tbuf[2], ttyn1; | |
146 | ||
147 | fin = 0; | |
148 | (&fin)[1] = 0; | |
149 | time(tbuf); | |
150 | ttyn1 = ttyn(1); | |
151 | if (ttyn1 < 033) { | |
152 | ttyn1 =+ 'a' - 1; | |
153 | ttyn1 =<< 8; | |
154 | ttyn1 =| '^'; | |
155 | } | |
156 | printf("From %s tty%c %s", from, ttyn1, ctime(tbuf)); | |
157 | if (chew) | |
158 | do { | |
159 | c = getchar(); | |
160 | } while (c != '\n' && c != 0); | |
161 | getput(); | |
162 | putchar('\n'); | |
163 | flush(); | |
164 | close(fout); | |
165 | while (--argc > 0) | |
166 | sendto(*++argv); | |
167 | delexit(errs); | |
168 | } | |
169 | ||
170 | sendto(person) | |
171 | char *person; | |
172 | { | |
173 | static int saved; | |
174 | extern int fout, fin; | |
175 | register char *filep; | |
176 | register int him; | |
177 | ||
178 | if ((person[0] == 'y' || person[0] == 'Y') && person[1] == ':') | |
179 | person += 2; | |
180 | if ((person[0] | ' ') == 'c' && (person[1] | ' ') == 'o' && | |
181 | (person[2] | ' ') == 'r' && (person[3] | ' ') == 'y' && | |
182 | person[4] == ':') | |
183 | person += 5; | |
184 | if (any(':', person) || person[0] == 'm' && person[1] == 's' && | |
185 | person[2] == 'g' && person[3] == 's' && person[4] == 0) { | |
186 | int i = fork(); | |
187 | int s; | |
188 | ||
189 | if (i < 0) { | |
190 | perror("fork"); | |
191 | goto assback; | |
192 | } | |
193 | if (i == 0) { | |
194 | close(0); | |
195 | open(lettmp, 0); | |
196 | if (any(':', person)) { | |
197 | execl(RMAILCMD,"sendmail", person, 0); | |
198 | execl("/usr/bin/sendmail", "sendmail", person, 0); | |
199 | execl("/bin/sendmail", "sendmail", person, 0); | |
200 | perror("sendmail"); | |
201 | } else { | |
202 | execl("/usr/new/msgs", "msgs", "-s", 0); | |
203 | execl("/usr/bin/msgs", "msgs", "-s", 0); | |
204 | } | |
205 | exit(12); | |
206 | } | |
207 | for (;;) { | |
208 | register int j = wait(&s); | |
209 | if (j == -1) | |
210 | goto assback; | |
211 | if (j == i) | |
212 | break; | |
213 | } | |
214 | if ((s & 0377) != 0 || (s >> 8) == 12) | |
215 | goto assback; | |
216 | return; | |
217 | } | |
218 | ||
219 | if ((him = getuserid(person)) == -1) { | |
220 | assback: | |
221 | fout = 1; | |
222 | flush(); | |
223 | printf("Can't send to %s.\n", person); | |
224 | errs++; | |
225 | if (ttyn(0)!='x' && saved==0) { | |
226 | saved++; | |
227 | if (accesss("dead.letter")) { | |
228 | printf("Letter saved in 'dead.letter'\n"); | |
229 | prepend(lettmp, "dead.letter", getuid()); | |
230 | } else | |
231 | printf("In wrong directory\n"); | |
232 | } | |
233 | return; | |
234 | } | |
235 | prepend(lettmp, filep=cat("/usr/mail/", person), him); | |
236 | } | |
237 | ||
238 | prepend(from, to, own) | |
239 | char *from, *to; | |
240 | { | |
241 | extern int fin, fout; | |
242 | register int sig; | |
243 | ||
244 | unlink(preptmp); | |
245 | if (fcreat(preptmp, &fout) < 0) { | |
246 | fout = 1; | |
247 | perror("mail"); | |
248 | delexit(1); | |
249 | } | |
250 | chmod(preptmp, 0600); | |
251 | if (fopen(from, &fin) < 0) { | |
252 | close(fout); | |
253 | fout = 1; | |
254 | perror("mail"); | |
255 | unlink(preptmp); | |
256 | return(0); | |
257 | } | |
258 | getput(); | |
259 | close(fin); | |
260 | fopen(to, &fin); | |
261 | getput(); | |
262 | close(fin); | |
263 | flush(); | |
264 | close(fout); | |
265 | sig = signal(SIGINT, 01); | |
266 | unlink(to); | |
267 | if (fcreat(to, &fout) < 0) { | |
268 | unlink(preptmp); | |
269 | fout = 1; | |
270 | signal(SIGINT, sig); | |
271 | return(0); | |
272 | } | |
273 | chmod(to, 0600); | |
274 | chown(to, own); | |
275 | if(stat(to, &inode) < 0 || inode.nlinks != 1) { | |
276 | close(fout); | |
277 | fout = 1; | |
278 | unlink(preptmp); | |
279 | signal(SIGINT, sig); | |
280 | return(0); | |
281 | } | |
282 | if (fopen(preptmp, &fin) < 0) { | |
283 | fout = 1; | |
284 | perror("mail"); | |
285 | signal(SIGINT, sig); | |
286 | errs++; | |
287 | return(0); | |
288 | } | |
289 | getput(); | |
290 | flush(); | |
291 | close(fout); | |
292 | close(fin); | |
293 | fout = 1; | |
294 | signal(SIGINT, sig); | |
295 | return(1); | |
296 | } | |
297 | ||
298 | delexit(ex) | |
299 | { | |
300 | unlink(lettmp); | |
301 | unlink(preptmp); | |
302 | exit(ex); | |
303 | } | |
304 | ||
305 | equal(as1, as2) | |
306 | { | |
307 | register char *s1, *s2; | |
308 | ||
309 | s1 = as1; | |
310 | s2 = as2; | |
311 | while (*s1++ == *s2) | |
312 | if (*s2++ == 0) | |
313 | return(1); | |
314 | return(0); | |
315 | } | |
316 | ||
317 | cat(ap1, ap2) | |
318 | char *ap1, *ap2; | |
319 | { | |
320 | register char *p1, *p2; | |
321 | static char fn[32]; | |
322 | ||
323 | p1 = ap1; | |
324 | p2 = fn; | |
325 | while (*p2++ = *p1++); | |
326 | p2--; | |
327 | p1 = ap2; | |
328 | while (*p2++ = *p1++); | |
329 | return(fn); | |
330 | } | |
331 | ||
332 | getput() | |
333 | { | |
334 | extern int errno; | |
335 | register c; | |
336 | ||
337 | while(c = getchar()) { | |
338 | errno = 0; | |
339 | putchar(c); | |
340 | if(errno) { | |
341 | perror("mail"); | |
342 | delexit(1); | |
343 | } | |
344 | } | |
345 | } | |
346 | ||
347 | accesss(s1) | |
348 | { | |
349 | if (access(".", 2) != -1 && (stat(s1, &inode)<0 || access(s1, 2)==0)) | |
350 | return(1); | |
351 | return(0); | |
352 | } | |
353 | ||
354 | any(c, str) | |
355 | char *str; | |
356 | { | |
357 | register char *f; | |
358 | ||
359 | f = str; | |
360 | while (*f) | |
361 | if (c == *f++) | |
362 | return(1); | |
363 | return(0); | |
364 | } |