114465Ssam #ifndef lint 2*29763Skarels static char sccsid[] = "@(#)mail.c 4.25 (Berkeley) 5/1/85"; 314465Ssam #endif 414465Ssam 5*29763Skarels #include <sys/param.h> 616731Sralph #include <sys/stat.h> 716731Sralph #include <sys/file.h> 816731Sralph 9579Sroot #include <ctype.h> 10579Sroot #include <stdio.h> 11579Sroot #include <pwd.h> 12579Sroot #include <utmp.h> 13579Sroot #include <signal.h> 14579Sroot #include <setjmp.h> 15579Sroot #include <sysexits.h> 16579Sroot 179978Seric #define SENDMAIL "/usr/lib/sendmail" 18579Sroot 1916731Sralph /* copylet flags */ 2016731Sralph #define REMOTE 1 /* remote mail, add rmtmsg */ 2116731Sralph #define ORDINARY 2 2216731Sralph #define ZAP 3 /* zap header and trailing empty line */ 2316731Sralph #define FORWARD 4 24579Sroot 2516731Sralph #define LSIZE 256 2616731Sralph #define MAXLET 300 /* maximum number of letters */ 2716731Sralph #define MAILMODE 0600 /* mode of created mail */ 28579Sroot 29579Sroot char line[LSIZE]; 30579Sroot char resp[LSIZE]; 31579Sroot struct let { 32579Sroot long adr; 33579Sroot char change; 34579Sroot } let[MAXLET]; 35579Sroot int nlet = 0; 36579Sroot char lfil[50]; 37579Sroot long iop, time(); 38579Sroot char *getenv(); 39579Sroot char *index(); 40579Sroot char lettmp[] = "/tmp/maXXXXX"; 41579Sroot char maildir[] = "/usr/spool/mail/"; 42579Sroot char mailfile[] = "/usr/spool/mail/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; 43579Sroot char dead[] = "dead.letter"; 44579Sroot char forwmsg[] = " forwarded\n"; 45579Sroot FILE *tmpf; 46579Sroot FILE *malf; 47*29763Skarels char my_name[60]; 48579Sroot char *getlogin(); 49579Sroot int error; 50579Sroot int changed; 51579Sroot int forward; 52579Sroot char from[] = "From "; 53579Sroot long ftell(); 5416731Sralph int delex(); 55579Sroot char *ctime(); 56579Sroot int flgf; 57579Sroot int flgp; 58579Sroot int delflg = 1; 59579Sroot int hseqno; 60579Sroot jmp_buf sjbuf; 61579Sroot int rmail; 62579Sroot 63579Sroot main(argc, argv) 64579Sroot char **argv; 65579Sroot { 66579Sroot register i; 67*29763Skarels char *name; 6819868Smiriam struct passwd *pwent; 69579Sroot 70*29763Skarels name = getlogin(); 71*29763Skarels if (name == NULL || *name == '\0') { 72579Sroot pwent = getpwuid(getuid()); 73579Sroot if (pwent==NULL) 74*29763Skarels name = "???"; 75579Sroot else 76*29763Skarels name = pwent->pw_name; 77579Sroot } 7819868Smiriam else { 7919868Smiriam pwent = getpwnam(my_name); 8019868Smiriam if ( getuid() != pwent->pw_uid) { 8119868Smiriam pwent = getpwuid(getuid()); 82*29763Skarels name = pwent->pw_name; 8319868Smiriam } 8419868Smiriam } 85*29763Skarels strncpy(my_name, name, sizeof(my_name)-1); 8616731Sralph if (setjmp(sjbuf)) 8716731Sralph done(); 8814912Sralph for (i=SIGHUP; i<=SIGTERM; i++) 8916731Sralph setsig(i, delex); 9017533Sralph i = mkstemp(lettmp); 9117533Sralph tmpf = fdopen(i, "r+w"); 9217533Sralph if (i < 0 || tmpf == NULL) 9316731Sralph panic("mail: %s: cannot open for writing", lettmp); 9416731Sralph /* 9516731Sralph * This protects against others reading mail from temp file and 9616731Sralph * if we exit, the file will be deleted already. 9716731Sralph */ 9816731Sralph unlink(lettmp); 99579Sroot if (argv[0][0] == 'r') 100579Sroot rmail++; 101579Sroot if (argv[0][0] != 'r' && /* no favors for rmail*/ 102579Sroot (argc == 1 || argv[1][0] == '-' && !any(argv[1][1], "rhd"))) 103579Sroot printmail(argc, argv); 104579Sroot else 1056015Swnj bulkmail(argc, argv); 106579Sroot done(); 107579Sroot } 108579Sroot 109579Sroot setsig(i, f) 110579Sroot int i; 111579Sroot int (*f)(); 112579Sroot { 11316731Sralph if (signal(i, SIG_IGN) != SIG_IGN) 114579Sroot signal(i, f); 115579Sroot } 116579Sroot 117579Sroot any(c, str) 118579Sroot register int c; 119579Sroot register char *str; 120579Sroot { 121579Sroot 122579Sroot while (*str) 123579Sroot if (c == *str++) 124579Sroot return(1); 125579Sroot return(0); 126579Sroot } 127579Sroot 128579Sroot printmail(argc, argv) 12916731Sralph char **argv; 130579Sroot { 131579Sroot int flg, i, j, print; 132579Sroot char *p, *getarg(); 133579Sroot struct stat statb; 134579Sroot 135579Sroot setuid(getuid()); 136579Sroot cat(mailfile, maildir, my_name); 13716731Sralph #ifdef notdef 138579Sroot if (stat(mailfile, &statb) >= 0 139579Sroot && (statb.st_mode & S_IFMT) == S_IFDIR) { 140579Sroot strcat(mailfile, "/"); 141579Sroot strcat(mailfile, my_name); 142579Sroot } 14316731Sralph #endif 14416731Sralph for (; argc > 1; argv++, argc--) { 14516731Sralph if (argv[1][0] != '-') 14616731Sralph break; 14716731Sralph switch (argv[1][1]) { 14816731Sralph 14916731Sralph case 'p': 15016731Sralph flgp++; 15116731Sralph /* fall thru... */ 15216731Sralph case 'q': 15316731Sralph delflg = 0; 15416731Sralph break; 15516731Sralph 15616731Sralph case 'f': 15716731Sralph if (argc >= 3) { 15816731Sralph strcpy(mailfile, argv[2]); 15916731Sralph argv++, argc--; 160579Sroot } 161579Sroot break; 16216731Sralph 16316731Sralph case 'b': 16416731Sralph forward = 1; 16516731Sralph break; 16616731Sralph 16716731Sralph default: 16816731Sralph panic("unknown option %c", argv[1][1]); 16916731Sralph /*NOTREACHED*/ 17016731Sralph } 171579Sroot } 172579Sroot malf = fopen(mailfile, "r"); 173579Sroot if (malf == NULL) { 17416731Sralph printf("No mail.\n"); 175579Sroot return; 176579Sroot } 17716731Sralph flock(fileno(malf), LOCK_SH); 178579Sroot copymt(malf, tmpf); 17916731Sralph fclose(malf); /* implicit unlock */ 18016731Sralph fseek(tmpf, 0, L_SET); 181579Sroot 182579Sroot changed = 0; 183579Sroot print = 1; 184579Sroot for (i = 0; i < nlet; ) { 185579Sroot j = forward ? i : nlet - i - 1; 18616731Sralph if (setjmp(sjbuf)) { 18716731Sralph print = 0; 188579Sroot } else { 189579Sroot if (print) 190579Sroot copylet(j, stdout, ORDINARY); 191579Sroot print = 1; 192579Sroot } 193579Sroot if (flgp) { 194579Sroot i++; 195579Sroot continue; 196579Sroot } 197579Sroot setjmp(sjbuf); 19816731Sralph fputs("? ", stdout); 199579Sroot fflush(stdout); 200579Sroot if (fgets(resp, LSIZE, stdin) == NULL) 201579Sroot break; 202579Sroot switch (resp[0]) { 203579Sroot 204579Sroot default: 20516731Sralph printf("usage\n"); 206579Sroot case '?': 207579Sroot print = 0; 20816731Sralph printf("q\tquit\n"); 20916731Sralph printf("x\texit without changing mail\n"); 21016731Sralph printf("p\tprint\n"); 21116731Sralph printf("s[file]\tsave (default mbox)\n"); 21216731Sralph printf("w[file]\tsame without header\n"); 21316731Sralph printf("-\tprint previous\n"); 21416731Sralph printf("d\tdelete\n"); 21516731Sralph printf("+\tnext (no delete)\n"); 21616731Sralph printf("m user\tmail to user\n"); 21716731Sralph printf("! cmd\texecute cmd\n"); 218579Sroot break; 219579Sroot 220579Sroot case '+': 221579Sroot case 'n': 222579Sroot case '\n': 223579Sroot i++; 224579Sroot break; 225579Sroot case 'x': 226579Sroot changed = 0; 227579Sroot case 'q': 228579Sroot goto donep; 229579Sroot case 'p': 230579Sroot break; 231579Sroot case '^': 232579Sroot case '-': 233579Sroot if (--i < 0) 234579Sroot i = 0; 235579Sroot break; 236579Sroot case 'y': 237579Sroot case 'w': 238579Sroot case 's': 239579Sroot flg = 0; 240579Sroot if (resp[1] != '\n' && resp[1] != ' ') { 241579Sroot printf("illegal\n"); 242579Sroot flg++; 243579Sroot print = 0; 244579Sroot continue; 245579Sroot } 246579Sroot if (resp[1] == '\n' || resp[1] == '\0') { 247579Sroot p = getenv("HOME"); 24816731Sralph if (p != 0) 249579Sroot cat(resp+1, p, "/mbox"); 250579Sroot else 251579Sroot cat(resp+1, "", "mbox"); 252579Sroot } 253579Sroot for (p = resp+1; (p = getarg(lfil, p)) != NULL; ) { 254579Sroot malf = fopen(lfil, "a"); 255579Sroot if (malf == NULL) { 25616731Sralph printf("mail: %s: cannot append\n", 25716731Sralph lfil); 258579Sroot flg++; 259579Sroot continue; 260579Sroot } 261579Sroot copylet(j, malf, resp[0]=='w'? ZAP: ORDINARY); 262579Sroot fclose(malf); 263579Sroot } 264579Sroot if (flg) 265579Sroot print = 0; 266579Sroot else { 267579Sroot let[j].change = 'd'; 268579Sroot changed++; 269579Sroot i++; 270579Sroot } 271579Sroot break; 272579Sroot case 'm': 273579Sroot flg = 0; 274579Sroot if (resp[1] == '\n' || resp[1] == '\0') { 275579Sroot i++; 276579Sroot continue; 277579Sroot } 278579Sroot if (resp[1] != ' ') { 279579Sroot printf("invalid command\n"); 280579Sroot flg++; 281579Sroot print = 0; 282579Sroot continue; 283579Sroot } 284579Sroot for (p = resp+1; (p = getarg(lfil, p)) != NULL; ) 28517019Sralph if (!sendmail(j, lfil, my_name)) 286579Sroot flg++; 287579Sroot if (flg) 288579Sroot print = 0; 289579Sroot else { 290579Sroot let[j].change = 'd'; 291579Sroot changed++; 292579Sroot i++; 293579Sroot } 294579Sroot break; 295579Sroot case '!': 296579Sroot system(resp+1); 297579Sroot printf("!\n"); 298579Sroot print = 0; 299579Sroot break; 300579Sroot case 'd': 301579Sroot let[j].change = 'd'; 302579Sroot changed++; 303579Sroot i++; 304579Sroot if (resp[1] == 'q') 305579Sroot goto donep; 306579Sroot break; 307579Sroot } 308579Sroot } 309579Sroot donep: 310579Sroot if (changed) 311579Sroot copyback(); 312579Sroot } 313579Sroot 31416731Sralph /* copy temp or whatever back to /usr/spool/mail */ 31516731Sralph copyback() 316579Sroot { 31716731Sralph register i, c; 31816731Sralph int fd, new = 0, oldmask; 319579Sroot struct stat stbuf; 320579Sroot 32116731Sralph #define mask(s) (1 << ((s) - 1)) 32216731Sralph oldmask = sigblock(mask(SIGINT)|mask(SIGHUP)|mask(SIGQUIT)); 32316731Sralph #undef mask 32416731Sralph fd = open(mailfile, O_RDWR | O_CREAT, MAILMODE); 32516731Sralph if (fd >= 0) { 32616731Sralph flock(fd, LOCK_EX); 32716731Sralph malf = fdopen(fd, "r+w"); 32816731Sralph } 32916731Sralph if (fd < 0 || malf == NULL) 33016731Sralph panic("can't rewrite %s", lfil); 33116731Sralph fstat(fd, &stbuf); 332579Sroot if (stbuf.st_size != let[nlet].adr) { /* new mail has arrived */ 33316731Sralph fseek(malf, let[nlet].adr, L_SET); 33416731Sralph fseek(tmpf, let[nlet].adr, L_SET); 33516731Sralph while ((c = getc(malf)) != EOF) 33616731Sralph putc(c, tmpf); 337579Sroot let[++nlet].adr = stbuf.st_size; 338579Sroot new = 1; 33916731Sralph fseek(malf, 0, L_SET); 340579Sroot } 34116731Sralph ftruncate(fd, 0); 342579Sroot for (i = 0; i < nlet; i++) 34316731Sralph if (let[i].change != 'd') 344579Sroot copylet(i, malf, ORDINARY); 34516731Sralph fclose(malf); /* implict unlock */ 346579Sroot if (new) 34716731Sralph printf("New mail has arrived.\n"); 34816731Sralph sigsetmask(oldmask); 349579Sroot } 350579Sroot 35116731Sralph /* copy mail (f1) to temp (f2) */ 35216731Sralph copymt(f1, f2) 35316731Sralph FILE *f1, *f2; 354579Sroot { 355579Sroot long nextadr; 356579Sroot 357579Sroot nlet = nextadr = 0; 358579Sroot let[0].adr = 0; 359579Sroot while (fgets(line, LSIZE, f1) != NULL) { 360579Sroot if (isfrom(line)) 361579Sroot let[nlet++].adr = nextadr; 362579Sroot nextadr += strlen(line); 363579Sroot fputs(line, f2); 364579Sroot } 365579Sroot let[nlet].adr = nextadr; /* last plus 1 */ 366579Sroot } 367579Sroot 36811893Seric copylet(n, f, type) 36911893Seric FILE *f; 37011893Seric { 37111893Seric int ch; 37211893Seric long k; 373*29763Skarels char hostname[MAXHOSTNAMELEN]; 37411893Seric 37516731Sralph fseek(tmpf, let[n].adr, L_SET); 376579Sroot k = let[n+1].adr - let[n].adr; 37716731Sralph while (k-- > 1 && (ch = getc(tmpf)) != '\n') 37816731Sralph if (type != ZAP) 37916731Sralph putc(ch, f); 38016731Sralph switch (type) { 38116731Sralph 38216731Sralph case REMOTE: 3836199Sroot gethostname(hostname, sizeof (hostname)); 3846199Sroot fprintf(f, " remote from %s\n", hostname); 38516731Sralph break; 38616731Sralph 38716731Sralph case FORWARD: 388579Sroot fprintf(f, forwmsg); 38916731Sralph break; 39016731Sralph 39116731Sralph case ORDINARY: 39216731Sralph putc(ch, f); 39316731Sralph break; 39416731Sralph 39517019Sralph case ZAP: 39617019Sralph break; 39717019Sralph 39816731Sralph default: 39916731Sralph panic("Bad letter type %d to copylet.", type); 40016731Sralph } 40116731Sralph while (k-- > 1) { 40216731Sralph ch = getc(tmpf); 40316731Sralph putc(ch, f); 40416731Sralph } 40516731Sralph if (type != ZAP || ch != '\n') 40616731Sralph putc(getc(tmpf), f); 407579Sroot } 408579Sroot 409579Sroot isfrom(lp) 410579Sroot register char *lp; 411579Sroot { 412579Sroot register char *p; 413579Sroot 414579Sroot for (p = from; *p; ) 415579Sroot if (*lp++ != *p++) 416579Sroot return(0); 417579Sroot return(1); 418579Sroot } 419579Sroot 4206015Swnj bulkmail(argc, argv) 421579Sroot char **argv; 422579Sroot { 423*29763Skarels char *truename; 424579Sroot int first; 425579Sroot register char *cp; 426579Sroot char *newargv[1000]; 427579Sroot register char **ap; 428579Sroot register char **vp; 429579Sroot int dflag; 430579Sroot 431579Sroot dflag = 0; 432*29763Skarels delflg = 0; 43316731Sralph if (argc < 1) { 434579Sroot fprintf(stderr, "puke\n"); 43516731Sralph return; 43616731Sralph } 437579Sroot for (vp = argv, ap = newargv + 1; (*ap = *vp++) != 0; ap++) 438579Sroot if (ap[0][0] == '-' && ap[0][1] == 'd') 439579Sroot dflag++; 44016731Sralph if (!dflag) { 4419978Seric /* give it to sendmail, rah rah! */ 442579Sroot unlink(lettmp); 443579Sroot ap = newargv+1; 444579Sroot if (rmail) 445579Sroot *ap-- = "-s"; 4469978Seric *ap = "-sendmail"; 4474461Sroot setuid(getuid()); 4489978Seric execv(SENDMAIL, ap); 4499978Seric perror(SENDMAIL); 450579Sroot exit(EX_UNAVAILABLE); 451579Sroot } 452579Sroot 453*29763Skarels truename = 0; 454579Sroot line[0] = '\0'; 455579Sroot 456579Sroot /* 457579Sroot * When we fall out of this, argv[1] should be first name, 458579Sroot * argc should be number of names + 1. 459579Sroot */ 460579Sroot 461579Sroot while (argc > 1 && *argv[1] == '-') { 462579Sroot cp = *++argv; 463579Sroot argc--; 464579Sroot switch (cp[1]) { 465579Sroot case 'r': 46616731Sralph if (argc <= 1) 467579Sroot usage(); 468*29763Skarels truename = argv[1]; 46915346Skarels fgets(line, LSIZE, stdin); 47015346Skarels if (strcmpn("From", line, 4) == 0) 47115346Skarels line[0] = '\0'; 472579Sroot argv++; 473579Sroot argc--; 474579Sroot break; 475579Sroot 476579Sroot case 'h': 47716731Sralph if (argc <= 1) 478579Sroot usage(); 479579Sroot hseqno = atoi(argv[1]); 480579Sroot argv++; 481579Sroot argc--; 482579Sroot break; 483579Sroot 484579Sroot case 'd': 485579Sroot break; 486579Sroot 487579Sroot default: 488579Sroot usage(); 489579Sroot } 490579Sroot } 49116731Sralph if (argc <= 1) 492579Sroot usage(); 493*29763Skarels if (truename == 0) 494*29763Skarels truename = my_name; 495579Sroot time(&iop); 496579Sroot fprintf(tmpf, "%s%s %s", from, truename, ctime(&iop)); 497579Sroot iop = ftell(tmpf); 49816731Sralph flgf = first = 1; 49916731Sralph for (;;) { 50016731Sralph if (first) { 50116731Sralph first = 0; 50216731Sralph if (*line == '\0' && fgets(line, LSIZE, stdin) == NULL) 50316731Sralph break; 50416731Sralph } else { 50516731Sralph if (fgets(line, LSIZE, stdin) == NULL) 50616731Sralph break; 50716731Sralph } 50816731Sralph if (*line == '.' && line[1] == '\n' && isatty(fileno(stdin))) 509579Sroot break; 510579Sroot if (isfrom(line)) 51116731Sralph putc('>', tmpf); 512579Sroot fputs(line, tmpf); 513579Sroot flgf = 0; 514579Sroot } 51516731Sralph putc('\n', tmpf); 516579Sroot nlet = 1; 517579Sroot let[0].adr = 0; 518579Sroot let[1].adr = ftell(tmpf); 519579Sroot if (flgf) 520579Sroot return; 52116731Sralph while (--argc > 0) 5226015Swnj if (!sendmail(0, *++argv, truename)) 523579Sroot error++; 52410644Seric if (error && safefile(dead)) { 525579Sroot setuid(getuid()); 526579Sroot malf = fopen(dead, "w"); 527579Sroot if (malf == NULL) { 52816731Sralph printf("mail: cannot open %s\n", dead); 529579Sroot fclose(tmpf); 530579Sroot return; 531579Sroot } 532579Sroot copylet(0, malf, ZAP); 533579Sroot fclose(malf); 53416731Sralph printf("Mail saved in %s\n", dead); 535579Sroot } 536579Sroot fclose(tmpf); 537579Sroot } 538579Sroot 53917019Sralph sendrmt(n, name) 540579Sroot char *name; 541579Sroot { 542579Sroot FILE *rmf, *popen(); 543579Sroot register char *p; 544579Sroot char rsys[64], cmd[64]; 54517019Sralph register pid; 546579Sroot int sts; 547579Sroot 54817019Sralph #ifdef notdef 54917019Sralph if (any('^', name)) { 550579Sroot while (p = index(name, '^')) 551579Sroot *p = '!'; 552579Sroot if (strncmp(name, "researc", 7)) { 553579Sroot strcpy(rsys, "research"); 554579Sroot if (*name != '!') 555579Sroot --name; 556579Sroot goto skip; 557579Sroot } 558579Sroot } 55917019Sralph #endif 56017019Sralph for (p=rsys; *name!='!'; *p++ = *name++) 56117019Sralph if (*name=='\0') 56217019Sralph return(0); /* local address, no '!' */ 563579Sroot *p = '\0'; 56417019Sralph if (name[1]=='\0') { 56516731Sralph printf("null name\n"); 566579Sroot return(0); 567579Sroot } 568579Sroot skip: 569579Sroot if ((pid = fork()) == -1) { 570579Sroot fprintf(stderr, "mail: can't create proc for remote\n"); 571579Sroot return(0); 572579Sroot } 573579Sroot if (pid) { 574579Sroot while (wait(&sts) != pid) { 575579Sroot if (wait(&sts)==-1) 576579Sroot return(0); 577579Sroot } 578579Sroot return(!sts); 579579Sroot } 580579Sroot setuid(getuid()); 58117019Sralph if (any('!', name+1)) 58217019Sralph sprintf(cmd, "uux - %s!rmail \\(%s\\)", rsys, name+1); 58317019Sralph else 58417019Sralph sprintf(cmd, "uux - %s!rmail %s", rsys, name+1); 585579Sroot if ((rmf=popen(cmd, "w")) == NULL) 586579Sroot exit(1); 58717019Sralph copylet(n, rmf, REMOTE); 58810783Seric exit(pclose(rmf) != 0); 589579Sroot } 590579Sroot 591579Sroot usage() 592579Sroot { 593579Sroot 594579Sroot fprintf(stderr, "Usage: mail [ -f ] people . . .\n"); 59515299Skarels error = EX_USAGE; 59616731Sralph done(); 597579Sroot } 598579Sroot 5996015Swnj #include <sys/socket.h> 6009226Ssam #include <netinet/in.h> 60110227Ssam #include <netdb.h> 6026015Swnj 60316731Sralph notifybiff(msg) 60416731Sralph char *msg; 60516731Sralph { 60616731Sralph static struct sockaddr_in addr; 60716731Sralph static int f = -1; 60816731Sralph 60916731Sralph if (addr.sin_family == 0) { 61016731Sralph struct hostent *hp = gethostbyname("localhost"); 61116731Sralph struct servent *sp = getservbyname("biff", "udp"); 61216731Sralph 61316731Sralph if (hp && sp) { 61416731Sralph addr.sin_family = hp->h_addrtype; 61516731Sralph bcopy(hp->h_addr, &addr.sin_addr, hp->h_length); 61616731Sralph addr.sin_port = sp->s_port; 61716731Sralph } 61816731Sralph } 61916731Sralph if (addr.sin_family) { 62016731Sralph if (f < 0) 62116731Sralph f = socket(AF_INET, SOCK_DGRAM, 0); 62216731Sralph sendto(f, msg, strlen(msg)+1, 0, &addr, sizeof (addr)); 62316731Sralph } 62416731Sralph } 62516731Sralph 6266015Swnj sendmail(n, name, fromaddr) 62716731Sralph int n; 62816731Sralph char *name, *fromaddr; 629579Sroot { 63016731Sralph char file[256]; 63116731Sralph int mask, fd; 63216731Sralph struct passwd *pw; 63316731Sralph #ifdef notdef 634579Sroot struct stat statb; 63516731Sralph #endif 6363666Swnj char buf[128]; 637579Sroot 63817019Sralph if (*name=='!') 63917019Sralph name++; 64017019Sralph if (any('!', name)) 64117019Sralph return (sendrmt(n, name)); 642579Sroot if ((pw = getpwnam(name)) == NULL) { 64316731Sralph printf("mail: can't send to %s\n", name); 644579Sroot return(0); 645579Sroot } 646579Sroot cat(file, maildir, name); 64716731Sralph #ifdef notdef 648579Sroot if (stat(file, &statb) >= 0 && (statb.st_mode & S_IFMT) == S_IFDIR) { 649579Sroot strcat(file, "/"); 650579Sroot strcat(file, name); 651579Sroot } 65216731Sralph #endif 65310644Seric if (!safefile(file)) 6544458Sroot return(0); 65516731Sralph fd = open(file, O_WRONLY | O_CREAT, MAILMODE); 65616731Sralph if (fd >= 0) { 65716731Sralph flock(fd, LOCK_EX); 65816731Sralph malf = fdopen(fd, "a"); 65916731Sralph } 66016731Sralph if (fd < 0 || malf == NULL) { 66116731Sralph close(fd); 66216731Sralph printf("mail: %s: cannot append\n", file); 663579Sroot return(0); 664579Sroot } 66516731Sralph fchown(fd, pw->pw_uid, pw->pw_gid); 66616731Sralph sprintf(buf, "%s@%d\n", name, ftell(malf)); 667579Sroot copylet(n, malf, ORDINARY); 6686015Swnj fclose(malf); 66916731Sralph notifybiff(buf); 670579Sroot return(1); 671579Sroot } 672579Sroot 67316731Sralph delex(i) 674579Sroot { 675*29763Skarels if (i != SIGINT) { 676*29763Skarels setsig(i, SIG_DFL); 677*29763Skarels sigsetmask(sigblock(0) &~ sigmask(i)); 678*29763Skarels } 67916731Sralph putc('\n', stderr); 68016731Sralph if (delflg) 681579Sroot longjmp(sjbuf, 1); 682*29763Skarels if (error == 0) 683*29763Skarels error = i; 684579Sroot done(); 685579Sroot } 686579Sroot 68716731Sralph done() 688579Sroot { 689579Sroot 690579Sroot unlink(lettmp); 691579Sroot exit(error); 692579Sroot } 693579Sroot 694579Sroot cat(to, from1, from2) 69516731Sralph char *to, *from1, *from2; 696579Sroot { 69716731Sralph register char *cp, *dp; 698579Sroot 69916731Sralph cp = to; 70016731Sralph for (dp = from1; *cp = *dp++; cp++) 70116731Sralph ; 70216731Sralph for (dp = from2; *cp++ = *dp++; ) 70316731Sralph ; 704579Sroot } 705579Sroot 70616731Sralph /* copy p... into s, update p */ 70716731Sralph char * 70816731Sralph getarg(s, p) 70916731Sralph register char *s, *p; 710579Sroot { 711579Sroot while (*p == ' ' || *p == '\t') 712579Sroot p++; 713579Sroot if (*p == '\n' || *p == '\0') 714579Sroot return(NULL); 715579Sroot while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') 716579Sroot *s++ = *p++; 717579Sroot *s = '\0'; 718579Sroot return(p); 719579Sroot } 72010644Seric 72110644Seric safefile(f) 72210644Seric char *f; 72310644Seric { 72410644Seric struct stat statb; 72510644Seric 72610644Seric if (lstat(f, &statb) < 0) 72710644Seric return (1); 72810644Seric if (statb.st_nlink != 1 || (statb.st_mode & S_IFMT) == S_IFLNK) { 72916731Sralph fprintf(stderr, 73016731Sralph "mail: %s has more than one link or is a symbolic link\n", 73116731Sralph f); 73210644Seric return (0); 73310644Seric } 73410644Seric return (1); 73510644Seric } 73616731Sralph 73716731Sralph panic(msg, a1, a2, a3) 73816731Sralph char *msg; 73916731Sralph { 74016731Sralph 74116731Sralph fprintf(stderr, "mail: "); 74216731Sralph fprintf(stderr, msg, a1, a2, a3); 74316731Sralph fprintf(stderr, "\n"); 74416731Sralph done(); 74516731Sralph } 746