Commit | Line | Data |
---|---|---|
7f0f90d9 KS |
1 | #include <ctype.h> |
2 | #include <stdio.h> | |
3 | #include <pwd.h> | |
4 | #include <utmp.h> | |
5 | #include <signal.h> | |
6 | #include <sys/types.h> | |
7 | #include <sys/stat.h> | |
8 | #include <setjmp.h> | |
9 | #include <whoami.h> | |
10 | ||
11 | /*copylet flags */ | |
12 | /*remote mail, add rmtmsg */ | |
13 | #define REMOTE 1 | |
14 | /* zap header and trailing empty line */ | |
15 | #define ZAP 3 | |
16 | #define ORDINARY 2 | |
17 | #define FORWARD 4 | |
18 | #define LSIZE 256 | |
19 | #define MAXLET 300 /* maximum number of letters */ | |
20 | #define MAILMODE (~0644) /* mode of created mail */ | |
21 | #define RMAIL "/usr/net/bin/sendberkmail" | |
22 | #define LOCNAM1 "csvax" | |
23 | #define LOCNAM2 "ucbvax" | |
24 | #define LOCNAM3 "vax" | |
25 | #define LOCNAM4 "v" | |
26 | ||
27 | char line[LSIZE]; | |
28 | char resp[LSIZE]; | |
29 | struct let { | |
30 | long adr; | |
31 | char change; | |
32 | } let[MAXLET]; | |
33 | int nlet = 0; | |
34 | char lfil[50]; | |
35 | long iop, time(); | |
36 | char *getenv(); | |
37 | char *index(); | |
38 | char lettmp[] = "/tmp/maXXXXX"; | |
39 | char maildir[] = "/usr/spool/mail/"; | |
40 | char mailfile[] = "/usr/spool/mail/xxxxxxxxxxxxxxxxxxxxxxx"; | |
41 | char dead[] = "dead.letter"; | |
42 | char *thissys = sysname; | |
43 | char *netname = "vax"; | |
44 | char forwmsg[] = " forwarded\n"; | |
45 | FILE *tmpf; | |
46 | FILE *malf; | |
47 | char *my_name; | |
48 | char *getlogin(); | |
49 | struct passwd *getpwuid(); | |
50 | int error; | |
51 | int changed; | |
52 | int forward; | |
53 | char from[] = "From "; | |
54 | long ftell(); | |
55 | int delete(); | |
56 | char *ctime(); | |
57 | int flgf; | |
58 | int flgp; | |
59 | int delflg = 1; | |
60 | int hseqno; | |
61 | jmp_buf sjbuf; | |
62 | ||
63 | main(argc, argv) | |
64 | char **argv; | |
65 | { | |
66 | register i; | |
67 | char sobuf[BUFSIZ]; | |
68 | ||
69 | setbuf(stdout, sobuf); | |
70 | mktemp(lettmp); | |
71 | unlink(lettmp); | |
72 | my_name = getlogin(); | |
73 | if (my_name == NULL || strlen(my_name) == 0) { | |
74 | struct passwd *pwent; | |
75 | pwent = getpwuid(getuid()); | |
76 | if (pwent==NULL) | |
77 | my_name = "???"; | |
78 | else | |
79 | my_name = pwent->pw_name; | |
80 | } | |
81 | if(setjmp(sjbuf)) done(); | |
82 | for (i=0; i<20; i++) | |
83 | setsig(i, delete); | |
84 | tmpf = fopen(lettmp, "w"); | |
85 | if (tmpf == NULL) { | |
86 | fprintf(stderr, "mail: cannot open %s for writing\n", lettmp); | |
87 | done(); | |
88 | } | |
89 | if (argv[0][0] != 'r' && /* no favors for rmail*/ | |
90 | (argc == 1 || argv[1][0] == '-' && !any(argv[1][1], "rh"))) | |
91 | printmail(argc, argv); | |
92 | else | |
93 | sendmail(argc, argv); | |
94 | done(); | |
95 | } | |
96 | ||
97 | setsig(i, f) | |
98 | int i; | |
99 | int (*f)(); | |
100 | { | |
101 | if(signal(i, SIG_IGN)!=SIG_IGN) | |
102 | signal(i, f); | |
103 | } | |
104 | ||
105 | any(c, str) | |
106 | register int c; | |
107 | register char *str; | |
108 | { | |
109 | ||
110 | while (*str) | |
111 | if (c == *str++) | |
112 | return(1); | |
113 | return(0); | |
114 | } | |
115 | ||
116 | printmail(argc, argv) | |
117 | char **argv; | |
118 | { | |
119 | int flg, i, j, print; | |
120 | char *p, *getarg(); | |
121 | ||
122 | setuid(getuid()); | |
123 | cat(mailfile, maildir, my_name); | |
124 | for (; argc>1; argv++, argc--) { | |
125 | if (argv[1][0]=='-') { | |
126 | if (argv[1][1]=='q') | |
127 | delflg = 0; | |
128 | else if (argv[1][1]=='p') { | |
129 | flgp++; | |
130 | delflg = 0; | |
131 | } else if (argv[1][1]=='f') { | |
132 | if (argc>=3) { | |
133 | strcpy(mailfile, argv[2]); | |
134 | argv++; | |
135 | argc--; | |
136 | } | |
137 | } else if (argv[1][1]=='r') { | |
138 | forward = 1; | |
139 | } else if (argv[1][1]=='h') { | |
140 | forward = 1; | |
141 | } else { | |
142 | fprintf(stderr, "mail: unknown option %c\n", argv[1][1]); | |
143 | done(); | |
144 | } | |
145 | } else | |
146 | break; | |
147 | } | |
148 | malf = fopen(mailfile, "r"); | |
149 | if (malf == NULL) { | |
150 | fprintf(stdout, "No mail.\n"); | |
151 | return; | |
152 | } | |
153 | lock(mailfile); | |
154 | copymt(malf, tmpf); | |
155 | fclose(malf); | |
156 | fclose(tmpf); | |
157 | unlock(); | |
158 | tmpf = fopen(lettmp, "r"); | |
159 | ||
160 | changed = 0; | |
161 | print = 1; | |
162 | for (i = 0; i < nlet; ) { | |
163 | j = forward ? i : nlet - i - 1; | |
164 | if(setjmp(sjbuf)) { | |
165 | print=0; | |
166 | } else { | |
167 | if (print) | |
168 | copylet(j, stdout, ORDINARY); | |
169 | print = 1; | |
170 | } | |
171 | if (flgp) { | |
172 | i++; | |
173 | continue; | |
174 | } | |
175 | setjmp(sjbuf); | |
176 | fprintf(stdout, "? "); | |
177 | fflush(stdout); | |
178 | if (fgets(resp, LSIZE, stdin) == NULL) | |
179 | break; | |
180 | switch (resp[0]) { | |
181 | ||
182 | default: | |
183 | fprintf(stderr, "usage\n"); | |
184 | case '?': | |
185 | print = 0; | |
186 | fprintf(stderr, "q\tquit\n"); | |
187 | fprintf(stderr, "x\texit without changing mail\n"); | |
188 | fprintf(stderr, "p\tprint\n"); | |
189 | fprintf(stderr, "s[file]\tsave (default mbox)\n"); | |
190 | fprintf(stderr, "w[file]\tsame without header\n"); | |
191 | fprintf(stderr, "-\tprint previous\n"); | |
192 | fprintf(stderr, "d\tdelete\n"); | |
193 | fprintf(stderr, "+\tnext (no delete)\n"); | |
194 | fprintf(stderr, "m user\tmail to user\n"); | |
195 | fprintf(stderr, "! cmd\texecute cmd\n"); | |
196 | break; | |
197 | ||
198 | case '+': | |
199 | case 'n': | |
200 | case '\n': | |
201 | i++; | |
202 | break; | |
203 | case 'x': | |
204 | changed = 0; | |
205 | case 'q': | |
206 | goto donep; | |
207 | case 'p': | |
208 | break; | |
209 | case '^': | |
210 | case '-': | |
211 | if (--i < 0) | |
212 | i = 0; | |
213 | break; | |
214 | case 'y': | |
215 | case 'w': | |
216 | case 's': | |
217 | flg = 0; | |
218 | if (resp[1] != '\n' && resp[1] != ' ') { | |
219 | printf("illegal\n"); | |
220 | flg++; | |
221 | print = 0; | |
222 | continue; | |
223 | } | |
224 | if (resp[1] == '\n' || resp[1] == '\0') { | |
225 | p = getenv("HOME"); | |
226 | if(p != 0) | |
227 | cat(resp+1, p, "/mbox"); | |
228 | else | |
229 | cat(resp+1, "", "mbox"); | |
230 | } | |
231 | for (p = resp+1; (p = getarg(lfil, p)) != NULL; ) { | |
232 | malf = fopen(lfil, "a"); | |
233 | if (malf == NULL) { | |
234 | fprintf(stdout, "mail: cannot append to %s\n", lfil); | |
235 | flg++; | |
236 | continue; | |
237 | } | |
238 | copylet(j, malf, resp[0]=='w'? ZAP: ORDINARY); | |
239 | fclose(malf); | |
240 | } | |
241 | if (flg) | |
242 | print = 0; | |
243 | else { | |
244 | let[j].change = 'd'; | |
245 | changed++; | |
246 | i++; | |
247 | } | |
248 | break; | |
249 | case 'm': | |
250 | flg = 0; | |
251 | if (resp[1] == '\n' || resp[1] == '\0') { | |
252 | i++; | |
253 | continue; | |
254 | } | |
255 | if (resp[1] != ' ') { | |
256 | printf("invalid command\n"); | |
257 | flg++; | |
258 | print = 0; | |
259 | continue; | |
260 | } | |
261 | for (p = resp+1; (p = getarg(lfil, p)) != NULL; ) | |
262 | if (!sendrmt(j, lfil, "/bin/mail")) /* couldn't send it */ | |
263 | flg++; | |
264 | if (flg) | |
265 | print = 0; | |
266 | else { | |
267 | let[j].change = 'd'; | |
268 | changed++; | |
269 | i++; | |
270 | } | |
271 | break; | |
272 | case '!': | |
273 | system(resp+1); | |
274 | printf("!\n"); | |
275 | print = 0; | |
276 | break; | |
277 | case 'd': | |
278 | let[j].change = 'd'; | |
279 | changed++; | |
280 | i++; | |
281 | if (resp[1] == 'q') | |
282 | goto donep; | |
283 | break; | |
284 | } | |
285 | } | |
286 | donep: | |
287 | if (changed) | |
288 | copyback(); | |
289 | } | |
290 | ||
291 | copyback() /* copy temp or whatever back to /usr/spool/mail */ | |
292 | { | |
293 | register i, n, c; | |
294 | int new = 0; | |
295 | struct stat stbuf; | |
296 | ||
297 | signal(SIGINT, SIG_IGN); | |
298 | signal(SIGHUP, SIG_IGN); | |
299 | signal(SIGQUIT, SIG_IGN); | |
300 | lock(mailfile); | |
301 | stat(mailfile, &stbuf); | |
302 | if (stbuf.st_size != let[nlet].adr) { /* new mail has arrived */ | |
303 | malf = fopen(mailfile, "r"); | |
304 | if (malf == NULL) { | |
305 | fprintf(stdout, "mail: can't re-read %s\n", mailfile); | |
306 | done(); | |
307 | } | |
308 | fseek(malf, let[nlet].adr, 0); | |
309 | fclose(tmpf); | |
310 | tmpf = fopen(lettmp, "a"); | |
311 | fseek(tmpf, let[nlet].adr, 0); | |
312 | while ((c = fgetc(malf)) != EOF) | |
313 | fputc(c, tmpf); | |
314 | fclose(malf); | |
315 | fclose(tmpf); | |
316 | tmpf = fopen(lettmp, "r"); | |
317 | let[++nlet].adr = stbuf.st_size; | |
318 | new = 1; | |
319 | } | |
320 | malf = fopen(mailfile, "w"); | |
321 | if (malf == NULL) { | |
322 | fprintf(stderr, "mail: can't rewrite %s\n", lfil); | |
323 | done(); | |
324 | } | |
325 | n = 0; | |
326 | for (i = 0; i < nlet; i++) | |
327 | if (let[i].change != 'd') { | |
328 | copylet(i, malf, ORDINARY); | |
329 | n++; | |
330 | } | |
331 | fclose(malf); | |
332 | if (new) | |
333 | fprintf(stdout, "new mail arrived\n"); | |
334 | unlock(); | |
335 | } | |
336 | ||
337 | copymt(f1, f2) /* copy mail (f1) to temp (f2) */ | |
338 | FILE *f1, *f2; | |
339 | { | |
340 | long nextadr; | |
341 | ||
342 | nlet = nextadr = 0; | |
343 | let[0].adr = 0; | |
344 | while (fgets(line, LSIZE, f1) != NULL) { | |
345 | if (isfrom(line)) | |
346 | let[nlet++].adr = nextadr; | |
347 | nextadr += strlen(line); | |
348 | fputs(line, f2); | |
349 | } | |
350 | let[nlet].adr = nextadr; /* last plus 1 */ | |
351 | } | |
352 | ||
353 | copylet(n, f, type) FILE *f; | |
354 | { int ch, k; | |
355 | fseek(tmpf, let[n].adr, 0); | |
356 | k = let[n+1].adr - let[n].adr; | |
357 | while(k-- > 1 && (ch=fgetc(tmpf))!='\n') | |
358 | if(type!=ZAP) fputc(ch,f); | |
359 | if(type==REMOTE) | |
360 | fprintf(f, " remote from %s\n", thissys); | |
361 | else if (type==FORWARD) | |
362 | fprintf(f, forwmsg); | |
363 | else if(type==ORDINARY) | |
364 | fputc(ch,f); | |
365 | while(k-->1) | |
366 | fputc(ch=fgetc(tmpf), f); | |
367 | if(type!=ZAP || ch!= '\n') | |
368 | fputc(fgetc(tmpf), f); | |
369 | } | |
370 | ||
371 | isfrom(lp) | |
372 | register char *lp; | |
373 | { | |
374 | register char *p; | |
375 | ||
376 | for (p = from; *p; ) | |
377 | if (*lp++ != *p++) | |
378 | return(0); | |
379 | return(1); | |
380 | } | |
381 | ||
382 | sendmail(argc, argv) | |
383 | char **argv; | |
384 | { | |
385 | char truename[100]; | |
386 | int first; | |
387 | register char *cp; | |
388 | int gaver = 0; | |
389 | ||
390 | truename[0] = 0; | |
391 | line[0] = '\0'; | |
392 | ||
393 | /* | |
394 | * When we fall out of this, argv[1] should be first name, | |
395 | * argc should be number of names + 1. | |
396 | */ | |
397 | ||
398 | while (argc > 1 && *argv[1] == '-') { | |
399 | cp = *++argv; | |
400 | argc--; | |
401 | switch (cp[1]) { | |
402 | case 'r': | |
403 | if (argc <= 0) { | |
404 | usage(); | |
405 | done(); | |
406 | } | |
407 | gaver++; | |
408 | strcpy(truename, argv[1]); | |
409 | fgets(line, LSIZE, stdin); | |
410 | if (strcmpn("From", line, 4) == 0) | |
411 | line[0] = '\0'; | |
412 | argv++; | |
413 | argc--; | |
414 | break; | |
415 | ||
416 | case 'h': | |
417 | if (argc <= 0) { | |
418 | usage(); | |
419 | done(); | |
420 | } | |
421 | hseqno = atoi(argv[1]); | |
422 | argv++; | |
423 | argc--; | |
424 | break; | |
425 | ||
426 | default: | |
427 | usage(); | |
428 | done(); | |
429 | } | |
430 | } | |
431 | if (argc <= 1) { | |
432 | usage(); | |
433 | done(); | |
434 | } | |
435 | if (gaver == 0) | |
436 | strcpy(truename, my_name); | |
437 | /* | |
438 | if (argc > 4 && strcmp(argv[1], "-r") == 0) { | |
439 | strcpy(truename, argv[2]); | |
440 | argc -= 2; | |
441 | argv += 2; | |
442 | fgets(line, LSIZE, stdin); | |
443 | if (strcmpn("From", line, 4) == 0) | |
444 | line[0] = '\0'; | |
445 | } else | |
446 | strcpy(truename, my_name); | |
447 | */ | |
448 | time(&iop); | |
449 | fprintf(tmpf, "%s%s %s", from, truename, ctime(&iop)); | |
450 | iop = ftell(tmpf); | |
451 | flgf = 1; | |
452 | for (first = 1;; first = 0) { | |
453 | if (first && line[0] == '\0' && fgets(line, LSIZE, stdin) == NULL) | |
454 | break; | |
455 | if (!first && fgets(line, LSIZE, stdin) == NULL) | |
456 | break; | |
457 | if (line[0] == '.' && line[1] == '\n' && isatty(fileno(stdin))) | |
458 | break; | |
459 | if (isfrom(line)) | |
460 | fputs(">", tmpf); | |
461 | fputs(line, tmpf); | |
462 | flgf = 0; | |
463 | } | |
464 | fputs("\n", tmpf); | |
465 | nlet = 1; | |
466 | let[0].adr = 0; | |
467 | let[1].adr = ftell(tmpf); | |
468 | fclose(tmpf); | |
469 | if (flgf) | |
470 | return; | |
471 | tmpf = fopen(lettmp, "r"); | |
472 | if (tmpf == NULL) { | |
473 | fprintf(stderr, "mail: cannot reopen %s for reading\n", lettmp); | |
474 | return; | |
475 | } | |
476 | while (--argc > 0) | |
477 | if (!send(0, *++argv, truename)) | |
478 | error++; | |
479 | if (error) { | |
480 | setuid(getuid()); | |
481 | malf = fopen(dead, "w"); | |
482 | if (malf == NULL) { | |
483 | fprintf(stdout, "mail: cannot open %s\n", dead); | |
484 | fclose(tmpf); | |
485 | return; | |
486 | } | |
487 | copylet(0, malf, ZAP); | |
488 | fclose(malf); | |
489 | fprintf(stdout, "Mail saved in %s\n", dead); | |
490 | } | |
491 | fclose(tmpf); | |
492 | } | |
493 | ||
494 | sendrmt(n, name, rcmd) | |
495 | char *name; | |
496 | char *rcmd; | |
497 | { | |
498 | FILE *rmf, *popen(); | |
499 | register char *p; | |
500 | char rsys[64], cmd[64]; | |
501 | register local, pid; | |
502 | int sts; | |
503 | ||
504 | local = 0; | |
505 | if (index(name, '^')) { | |
506 | while (p = index(name, '^')) | |
507 | *p = '!'; | |
508 | if (strncmp(name, "researc", 7)) { | |
509 | strcpy(rsys, "research"); | |
510 | if (*name != '!') | |
511 | --name; | |
512 | goto skip; | |
513 | } | |
514 | } | |
515 | if (*name=='!') | |
516 | name++; | |
517 | for(p=rsys; *name!='!'; *p++ = *name++) | |
518 | if (*name=='\0') { | |
519 | local++; | |
520 | break; | |
521 | } | |
522 | *p = '\0'; | |
523 | if ((!local && *name=='\0') || (local && *rsys=='\0')) { | |
524 | fprintf(stdout, "null name\n"); | |
525 | return(0); | |
526 | } | |
527 | skip: | |
528 | if ((pid = fork()) == -1) { | |
529 | fprintf(stderr, "mail: can't create proc for remote\n"); | |
530 | return(0); | |
531 | } | |
532 | if (pid) { | |
533 | while (wait(&sts) != pid) { | |
534 | if (wait(&sts)==-1) | |
535 | return(0); | |
536 | } | |
537 | return(!sts); | |
538 | } | |
539 | setuid(getuid()); | |
540 | if (local) | |
541 | sprintf(cmd, "%s %s", rcmd, rsys); | |
542 | else { | |
543 | if (index(name+1, '!')) | |
544 | sprintf(cmd, "uux - %s!rmail \\(%s\\)", rsys, name+1); | |
545 | else | |
546 | sprintf(cmd, "uux - %s!rmail %s", rsys, name+1); | |
547 | } | |
548 | if ((rmf=popen(cmd, "w")) == NULL) | |
549 | exit(1); | |
550 | copylet(n, rmf, local ? !strcmp(rcmd, "/bin/mail") ? FORWARD : ORDINARY : REMOTE); | |
551 | pclose(rmf); | |
552 | exit(0); | |
553 | } | |
554 | ||
555 | /* | |
556 | * Send mail on the Berkeley network. | |
557 | * Sorry Bill, sendrmt() is so awful we just gave up. | |
558 | */ | |
559 | ||
560 | sendberkmail(n, name, fromaddr) | |
561 | char name[]; | |
562 | char fromaddr[]; | |
563 | { | |
564 | char cmd[200]; | |
565 | register FILE *cmdf; | |
566 | ||
567 | sprintf(cmd, "%s -h %d -f %s -t %s", RMAIL, hseqno, fromaddr, name); | |
568 | if ((cmdf = popen(cmd, "w")) == NULL) { | |
569 | perror(RMAIL); | |
570 | return(0); | |
571 | } | |
572 | copylet(n, cmdf, ORDINARY); | |
573 | pclose(cmdf); | |
574 | return(9); | |
575 | } | |
576 | ||
577 | usage() | |
578 | { | |
579 | ||
580 | fprintf(stderr, "Usage: mail [ -f ] people . . .\n"); | |
581 | } | |
582 | ||
583 | send(n, name, fromaddr) | |
584 | int n; | |
585 | char *name; | |
586 | char *fromaddr; | |
587 | { | |
588 | char file[50]; | |
589 | register char *p; | |
590 | register mask; | |
591 | struct passwd *pw, *getpwnam(); | |
592 | ||
593 | stripfx(LOCNAM1, &name); | |
594 | stripfx(LOCNAM2, &name); | |
595 | stripfx(LOCNAM3, &name); | |
596 | stripfx(LOCNAM4, &name); | |
597 | if(*name == ':')name++; /* skip colon in to-name */ | |
598 | for(p=name; *p!=':' &&*p!='\0'; p++); | |
599 | /* if(*p == ':') return(sendrmt(n, name, RMAIL)); */ | |
600 | if (*p == ':') | |
601 | return(sendberkmail(n, name, fromaddr)); | |
602 | else if (strcmp(name, "msgs") == 0) return(sendrmt(n, "-s", "/usr/ucb/msgs")); | |
603 | for(p=name; *p!='!'&&*p!='^' &&*p!='\0'; p++) | |
604 | ; | |
605 | if (*p == '!'|| *p=='^') | |
606 | return(sendrmt(n, name, 0)); | |
607 | if ((pw = getpwnam(name)) == NULL) { | |
608 | fprintf(stdout, "mail: can't send to %s\n", name); | |
609 | return(0); | |
610 | } | |
611 | cat(file, maildir, name); | |
612 | mask = umask(MAILMODE); | |
613 | malf = fopen(file, "a"); | |
614 | umask(mask); | |
615 | if (malf == NULL) { | |
616 | fprintf(stdout, "mail: cannot append to %s\n", file); | |
617 | return(0); | |
618 | } | |
619 | lock(file); | |
620 | chown(file, pw->pw_uid, pw->pw_gid); | |
621 | copylet(n, malf, ORDINARY); | |
622 | fclose(malf); | |
623 | unlock(); | |
624 | return(1); | |
625 | } | |
626 | ||
627 | delete(i) | |
628 | { | |
629 | setsig(i, delete); | |
630 | fprintf(stderr, "\n"); | |
631 | if(delflg) | |
632 | longjmp(sjbuf, 1); | |
633 | done(); | |
634 | } | |
635 | ||
636 | /* | |
637 | * Lock the specified mail file by setting the file mailfile.lock. | |
638 | * We must, of course, be careful to unlink the lock file by a call | |
639 | * to unlock before we stop. The algorithm used here is to see if | |
640 | * the lock exists, and if it does, to check its modify time. If it | |
641 | * is older than 30 seconds, we assume error and set our own file. | |
642 | * Otherwise, we wait for 5 seconds and try again. | |
643 | */ | |
644 | ||
645 | char *maillock = ".lock"; /* Lock suffix for mailname */ | |
646 | char *lockname = "/usr/spool/mail/tmXXXXXX"; | |
647 | char locktmp[30]; /* Usable lock temporary */ | |
648 | char curlock[50]; /* Last used name of lock */ | |
649 | int locked; /* To note that we locked it */ | |
650 | ||
651 | lock(file) | |
652 | char *file; | |
653 | { | |
654 | register int f; | |
655 | struct stat sbuf; | |
656 | long curtime; | |
657 | int statfailed; | |
658 | ||
659 | if (locked || flgf) | |
660 | return(0); | |
661 | strcpy(curlock, file); | |
662 | strcat(curlock, maillock); | |
663 | strcpy(locktmp, lockname); | |
664 | mktemp(locktmp); | |
665 | unlink(locktmp); | |
666 | statfailed = 0; | |
667 | for (;;) { | |
668 | f = lock1(locktmp, curlock); | |
669 | if (f == 0) { | |
670 | locked = 1; | |
671 | return(0); | |
672 | } | |
673 | if (stat(curlock, &sbuf) < 0) { | |
674 | if (statfailed++ > 5) | |
675 | return(-1); | |
676 | sleep(5); | |
677 | continue; | |
678 | } | |
679 | statfailed = 0; | |
680 | time(&curtime); | |
681 | if (curtime < sbuf.st_ctime + 30) { | |
682 | sleep(5); | |
683 | continue; | |
684 | } | |
685 | unlink(curlock); | |
686 | } | |
687 | } | |
688 | ||
689 | /* | |
690 | * Remove the mail lock, and note that we no longer | |
691 | * have it locked. | |
692 | */ | |
693 | ||
694 | unlock() | |
695 | { | |
696 | ||
697 | unlink(curlock); | |
698 | locked = 0; | |
699 | } | |
700 | ||
701 | /* | |
702 | * Attempt to set the lock by creating the temporary file, | |
703 | * then doing a link/unlink. If it fails, return -1 else 0 | |
704 | */ | |
705 | ||
706 | lock1(tempfile, name) | |
707 | char tempfile[], name[]; | |
708 | { | |
709 | register int fd; | |
710 | ||
711 | fd = creat(tempfile, 0); | |
712 | if (fd < 0) | |
713 | return(-1); | |
714 | close(fd); | |
715 | if (link(tempfile, name) < 0) { | |
716 | unlink(tempfile); | |
717 | return(-1); | |
718 | } | |
719 | unlink(tempfile); | |
720 | return(0); | |
721 | } | |
722 | ||
723 | done() | |
724 | { | |
725 | if(locked) | |
726 | unlock(); | |
727 | unlink(lettmp); | |
728 | unlink(locktmp); | |
729 | exit(error); | |
730 | } | |
731 | ||
732 | cat(to, from1, from2) | |
733 | char *to, *from1, *from2; | |
734 | { | |
735 | int i, j; | |
736 | ||
737 | j = 0; | |
738 | for (i=0; from1[i]; i++) | |
739 | to[j++] = from1[i]; | |
740 | for (i=0; from2[i]; i++) | |
741 | to[j++] = from2[i]; | |
742 | to[j] = 0; | |
743 | } | |
744 | ||
745 | char *getarg(s, p) /* copy p... into s, update p */ | |
746 | register char *s, *p; | |
747 | { | |
748 | while (*p == ' ' || *p == '\t') | |
749 | p++; | |
750 | if (*p == '\n' || *p == '\0') | |
751 | return(NULL); | |
752 | while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') | |
753 | *s++ = *p++; | |
754 | *s = '\0'; | |
755 | return(p); | |
756 | } | |
757 | /* | |
758 | stripfx(prefix string, pointer to string) | |
759 | ||
760 | takes a ptr to string and compares it to prefix string. | |
761 | may be called multiple times | |
762 | */ | |
763 | stripfx(pfx, name) | |
764 | char *pfx; | |
765 | char **name; | |
766 | { | |
767 | register char *cp = *name; | |
768 | ||
769 | while (*pfx && (*cp == *pfx || *cp == toupper(*pfx))) | |
770 | cp++, pfx++; | |
771 | if (*cp != ':' || *pfx != 0) | |
772 | return; | |
773 | *name = cp; | |
774 | } |