BSD 2 development
[unix-history] / misc / mail.c
CommitLineData
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
18struct 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
33char lettmp[] "/tmp/maXXXXX";
34char preptmp[] "/tmp/mbXXXXX";
35int pwfil;
36int chew;
37int errs;
38
39main(argc, argv)
40char **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--;
65hitit:
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
102printmail(argc, argv, name)
103char **argv;
104char *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
140bulkmail(argc, argv, from)
141char **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
170sendto(person)
171char *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) {
220assback:
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
238prepend(from, to, own)
239char *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
298delexit(ex)
299{
300 unlink(lettmp);
301 unlink(preptmp);
302 exit(ex);
303}
304
305equal(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
317cat(ap1, ap2)
318char *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
332getput()
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
347accesss(s1)
348{
349 if (access(".", 2) != -1 && (stat(s1, &inode)<0 || access(s1, 2)==0))
350 return(1);
351 return(0);
352}
353
354any(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}