114465Ssam #ifndef lint 2*17019Sralph static char sccsid[] = "@(#)mail.local.c 4.23 (Berkeley) 08/27/84"; 314465Ssam #endif 414465Ssam 516731Sralph #include <sys/types.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; 47579Sroot char *my_name; 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; 67579Sroot 68579Sroot mktemp(lettmp); 69579Sroot unlink(lettmp); 70579Sroot my_name = getlogin(); 7116731Sralph if (my_name == NULL || *my_name == '\0') { 72579Sroot struct passwd *pwent; 73579Sroot pwent = getpwuid(getuid()); 74579Sroot if (pwent==NULL) 75579Sroot my_name = "???"; 76579Sroot else 77579Sroot my_name = pwent->pw_name; 78579Sroot } 7916731Sralph if (setjmp(sjbuf)) 8016731Sralph done(); 8114912Sralph for (i=SIGHUP; i<=SIGTERM; i++) 8216731Sralph setsig(i, delex); 8316731Sralph tmpf = fopen(lettmp, "w+r"); 8416731Sralph if (tmpf == NULL) 8516731Sralph panic("mail: %s: cannot open for writing", lettmp); 8616731Sralph /* 8716731Sralph * This protects against others reading mail from temp file and 8816731Sralph * if we exit, the file will be deleted already. 8916731Sralph */ 9016731Sralph unlink(lettmp); 91579Sroot if (argv[0][0] == 'r') 92579Sroot rmail++; 93579Sroot if (argv[0][0] != 'r' && /* no favors for rmail*/ 94579Sroot (argc == 1 || argv[1][0] == '-' && !any(argv[1][1], "rhd"))) 95579Sroot printmail(argc, argv); 96579Sroot else 976015Swnj bulkmail(argc, argv); 98579Sroot done(); 99579Sroot } 100579Sroot 101579Sroot setsig(i, f) 102579Sroot int i; 103579Sroot int (*f)(); 104579Sroot { 10516731Sralph if (signal(i, SIG_IGN) != SIG_IGN) 106579Sroot signal(i, f); 107579Sroot } 108579Sroot 109579Sroot any(c, str) 110579Sroot register int c; 111579Sroot register char *str; 112579Sroot { 113579Sroot 114579Sroot while (*str) 115579Sroot if (c == *str++) 116579Sroot return(1); 117579Sroot return(0); 118579Sroot } 119579Sroot 120579Sroot printmail(argc, argv) 12116731Sralph char **argv; 122579Sroot { 123579Sroot int flg, i, j, print; 124579Sroot char *p, *getarg(); 125579Sroot struct stat statb; 126579Sroot 127579Sroot setuid(getuid()); 128579Sroot cat(mailfile, maildir, my_name); 12916731Sralph #ifdef notdef 130579Sroot if (stat(mailfile, &statb) >= 0 131579Sroot && (statb.st_mode & S_IFMT) == S_IFDIR) { 132579Sroot strcat(mailfile, "/"); 133579Sroot strcat(mailfile, my_name); 134579Sroot } 13516731Sralph #endif 13616731Sralph for (; argc > 1; argv++, argc--) { 13716731Sralph if (argv[1][0] != '-') 13816731Sralph break; 13916731Sralph switch (argv[1][1]) { 14016731Sralph 14116731Sralph case 'p': 14216731Sralph flgp++; 14316731Sralph /* fall thru... */ 14416731Sralph case 'q': 14516731Sralph delflg = 0; 14616731Sralph break; 14716731Sralph 14816731Sralph case 'f': 14916731Sralph if (argc >= 3) { 15016731Sralph strcpy(mailfile, argv[2]); 15116731Sralph argv++, argc--; 152579Sroot } 153579Sroot break; 15416731Sralph 15516731Sralph case 'b': 15616731Sralph forward = 1; 15716731Sralph break; 15816731Sralph 15916731Sralph default: 16016731Sralph panic("unknown option %c", argv[1][1]); 16116731Sralph /*NOTREACHED*/ 16216731Sralph } 163579Sroot } 164579Sroot malf = fopen(mailfile, "r"); 165579Sroot if (malf == NULL) { 16616731Sralph printf("No mail.\n"); 167579Sroot return; 168579Sroot } 16916731Sralph flock(fileno(malf), LOCK_SH); 170579Sroot copymt(malf, tmpf); 17116731Sralph fclose(malf); /* implicit unlock */ 17216731Sralph fseek(tmpf, 0, L_SET); 173579Sroot 174579Sroot changed = 0; 175579Sroot print = 1; 176579Sroot for (i = 0; i < nlet; ) { 177579Sroot j = forward ? i : nlet - i - 1; 17816731Sralph if (setjmp(sjbuf)) { 17916731Sralph print = 0; 180579Sroot } else { 181579Sroot if (print) 182579Sroot copylet(j, stdout, ORDINARY); 183579Sroot print = 1; 184579Sroot } 185579Sroot if (flgp) { 186579Sroot i++; 187579Sroot continue; 188579Sroot } 189579Sroot setjmp(sjbuf); 19016731Sralph fputs("? ", stdout); 191579Sroot fflush(stdout); 192579Sroot if (fgets(resp, LSIZE, stdin) == NULL) 193579Sroot break; 194579Sroot switch (resp[0]) { 195579Sroot 196579Sroot default: 19716731Sralph printf("usage\n"); 198579Sroot case '?': 199579Sroot print = 0; 20016731Sralph printf("q\tquit\n"); 20116731Sralph printf("x\texit without changing mail\n"); 20216731Sralph printf("p\tprint\n"); 20316731Sralph printf("s[file]\tsave (default mbox)\n"); 20416731Sralph printf("w[file]\tsame without header\n"); 20516731Sralph printf("-\tprint previous\n"); 20616731Sralph printf("d\tdelete\n"); 20716731Sralph printf("+\tnext (no delete)\n"); 20816731Sralph printf("m user\tmail to user\n"); 20916731Sralph printf("! cmd\texecute cmd\n"); 210579Sroot break; 211579Sroot 212579Sroot case '+': 213579Sroot case 'n': 214579Sroot case '\n': 215579Sroot i++; 216579Sroot break; 217579Sroot case 'x': 218579Sroot changed = 0; 219579Sroot case 'q': 220579Sroot goto donep; 221579Sroot case 'p': 222579Sroot break; 223579Sroot case '^': 224579Sroot case '-': 225579Sroot if (--i < 0) 226579Sroot i = 0; 227579Sroot break; 228579Sroot case 'y': 229579Sroot case 'w': 230579Sroot case 's': 231579Sroot flg = 0; 232579Sroot if (resp[1] != '\n' && resp[1] != ' ') { 233579Sroot printf("illegal\n"); 234579Sroot flg++; 235579Sroot print = 0; 236579Sroot continue; 237579Sroot } 238579Sroot if (resp[1] == '\n' || resp[1] == '\0') { 239579Sroot p = getenv("HOME"); 24016731Sralph if (p != 0) 241579Sroot cat(resp+1, p, "/mbox"); 242579Sroot else 243579Sroot cat(resp+1, "", "mbox"); 244579Sroot } 245579Sroot for (p = resp+1; (p = getarg(lfil, p)) != NULL; ) { 246579Sroot malf = fopen(lfil, "a"); 247579Sroot if (malf == NULL) { 24816731Sralph printf("mail: %s: cannot append\n", 24916731Sralph lfil); 250579Sroot flg++; 251579Sroot continue; 252579Sroot } 253579Sroot copylet(j, malf, resp[0]=='w'? ZAP: ORDINARY); 254579Sroot fclose(malf); 255579Sroot } 256579Sroot if (flg) 257579Sroot print = 0; 258579Sroot else { 259579Sroot let[j].change = 'd'; 260579Sroot changed++; 261579Sroot i++; 262579Sroot } 263579Sroot break; 264579Sroot case 'm': 265579Sroot flg = 0; 266579Sroot if (resp[1] == '\n' || resp[1] == '\0') { 267579Sroot i++; 268579Sroot continue; 269579Sroot } 270579Sroot if (resp[1] != ' ') { 271579Sroot printf("invalid command\n"); 272579Sroot flg++; 273579Sroot print = 0; 274579Sroot continue; 275579Sroot } 276579Sroot for (p = resp+1; (p = getarg(lfil, p)) != NULL; ) 277*17019Sralph if (!sendmail(j, lfil, my_name)) 278579Sroot flg++; 279579Sroot if (flg) 280579Sroot print = 0; 281579Sroot else { 282579Sroot let[j].change = 'd'; 283579Sroot changed++; 284579Sroot i++; 285579Sroot } 286579Sroot break; 287579Sroot case '!': 288579Sroot system(resp+1); 289579Sroot printf("!\n"); 290579Sroot print = 0; 291579Sroot break; 292579Sroot case 'd': 293579Sroot let[j].change = 'd'; 294579Sroot changed++; 295579Sroot i++; 296579Sroot if (resp[1] == 'q') 297579Sroot goto donep; 298579Sroot break; 299579Sroot } 300579Sroot } 301579Sroot donep: 302579Sroot if (changed) 303579Sroot copyback(); 304579Sroot } 305579Sroot 30616731Sralph /* copy temp or whatever back to /usr/spool/mail */ 30716731Sralph copyback() 308579Sroot { 30916731Sralph register i, c; 31016731Sralph int fd, new = 0, oldmask; 311579Sroot struct stat stbuf; 312579Sroot 31316731Sralph #define mask(s) (1 << ((s) - 1)) 31416731Sralph oldmask = sigblock(mask(SIGINT)|mask(SIGHUP)|mask(SIGQUIT)); 31516731Sralph #undef mask 31616731Sralph fd = open(mailfile, O_RDWR | O_CREAT, MAILMODE); 31716731Sralph if (fd >= 0) { 31816731Sralph flock(fd, LOCK_EX); 31916731Sralph malf = fdopen(fd, "r+w"); 32016731Sralph } 32116731Sralph if (fd < 0 || malf == NULL) 32216731Sralph panic("can't rewrite %s", lfil); 32316731Sralph fstat(fd, &stbuf); 324579Sroot if (stbuf.st_size != let[nlet].adr) { /* new mail has arrived */ 32516731Sralph fseek(malf, let[nlet].adr, L_SET); 32616731Sralph fseek(tmpf, let[nlet].adr, L_SET); 32716731Sralph while ((c = getc(malf)) != EOF) 32816731Sralph putc(c, tmpf); 329579Sroot let[++nlet].adr = stbuf.st_size; 330579Sroot new = 1; 33116731Sralph fseek(malf, 0, L_SET); 332579Sroot } 33316731Sralph ftruncate(fd, 0); 334579Sroot for (i = 0; i < nlet; i++) 33516731Sralph if (let[i].change != 'd') 336579Sroot copylet(i, malf, ORDINARY); 33716731Sralph fclose(malf); /* implict unlock */ 338579Sroot if (new) 33916731Sralph printf("New mail has arrived.\n"); 34016731Sralph sigsetmask(oldmask); 341579Sroot } 342579Sroot 34316731Sralph /* copy mail (f1) to temp (f2) */ 34416731Sralph copymt(f1, f2) 34516731Sralph FILE *f1, *f2; 346579Sroot { 347579Sroot long nextadr; 348579Sroot 349579Sroot nlet = nextadr = 0; 350579Sroot let[0].adr = 0; 351579Sroot while (fgets(line, LSIZE, f1) != NULL) { 352579Sroot if (isfrom(line)) 353579Sroot let[nlet++].adr = nextadr; 354579Sroot nextadr += strlen(line); 355579Sroot fputs(line, f2); 356579Sroot } 357579Sroot let[nlet].adr = nextadr; /* last plus 1 */ 358579Sroot } 359579Sroot 36011893Seric copylet(n, f, type) 36111893Seric FILE *f; 36211893Seric { 36311893Seric int ch; 36411893Seric long k; 36516731Sralph char hostname[32]; 36611893Seric 36716731Sralph fseek(tmpf, let[n].adr, L_SET); 368579Sroot k = let[n+1].adr - let[n].adr; 36916731Sralph while (k-- > 1 && (ch = getc(tmpf)) != '\n') 37016731Sralph if (type != ZAP) 37116731Sralph putc(ch, f); 37216731Sralph switch (type) { 37316731Sralph 37416731Sralph case REMOTE: 3756199Sroot gethostname(hostname, sizeof (hostname)); 3766199Sroot fprintf(f, " remote from %s\n", hostname); 37716731Sralph break; 37816731Sralph 37916731Sralph case FORWARD: 380579Sroot fprintf(f, forwmsg); 38116731Sralph break; 38216731Sralph 38316731Sralph case ORDINARY: 38416731Sralph putc(ch, f); 38516731Sralph break; 38616731Sralph 387*17019Sralph case ZAP: 388*17019Sralph break; 389*17019Sralph 39016731Sralph default: 39116731Sralph panic("Bad letter type %d to copylet.", type); 39216731Sralph } 39316731Sralph while (k-- > 1) { 39416731Sralph ch = getc(tmpf); 39516731Sralph putc(ch, f); 39616731Sralph } 39716731Sralph if (type != ZAP || ch != '\n') 39816731Sralph putc(getc(tmpf), f); 399579Sroot } 400579Sroot 401579Sroot isfrom(lp) 402579Sroot register char *lp; 403579Sroot { 404579Sroot register char *p; 405579Sroot 406579Sroot for (p = from; *p; ) 407579Sroot if (*lp++ != *p++) 408579Sroot return(0); 409579Sroot return(1); 410579Sroot } 411579Sroot 4126015Swnj bulkmail(argc, argv) 413579Sroot char **argv; 414579Sroot { 415579Sroot char truename[100]; 416579Sroot int first; 417579Sroot register char *cp; 418579Sroot int gaver = 0; 419579Sroot char *newargv[1000]; 420579Sroot register char **ap; 421579Sroot register char **vp; 422579Sroot int dflag; 423579Sroot 424579Sroot dflag = 0; 42516731Sralph if (argc < 1) { 426579Sroot fprintf(stderr, "puke\n"); 42716731Sralph return; 42816731Sralph } 429579Sroot for (vp = argv, ap = newargv + 1; (*ap = *vp++) != 0; ap++) 430579Sroot if (ap[0][0] == '-' && ap[0][1] == 'd') 431579Sroot dflag++; 43216731Sralph if (!dflag) { 4339978Seric /* give it to sendmail, rah rah! */ 434579Sroot unlink(lettmp); 435579Sroot ap = newargv+1; 436579Sroot if (rmail) 437579Sroot *ap-- = "-s"; 4389978Seric *ap = "-sendmail"; 4394461Sroot setuid(getuid()); 4409978Seric execv(SENDMAIL, ap); 4419978Seric perror(SENDMAIL); 442579Sroot exit(EX_UNAVAILABLE); 443579Sroot } 444579Sroot 445579Sroot truename[0] = 0; 446579Sroot line[0] = '\0'; 447579Sroot 448579Sroot /* 449579Sroot * When we fall out of this, argv[1] should be first name, 450579Sroot * argc should be number of names + 1. 451579Sroot */ 452579Sroot 453579Sroot while (argc > 1 && *argv[1] == '-') { 454579Sroot cp = *++argv; 455579Sroot argc--; 456579Sroot switch (cp[1]) { 457579Sroot case 'r': 45816731Sralph if (argc <= 1) 459579Sroot usage(); 46015346Skarels gaver++; 46115346Skarels strcpy(truename, argv[1]); 46215346Skarels fgets(line, LSIZE, stdin); 46315346Skarels if (strcmpn("From", line, 4) == 0) 46415346Skarels line[0] = '\0'; 465579Sroot argv++; 466579Sroot argc--; 467579Sroot break; 468579Sroot 469579Sroot case 'h': 47016731Sralph if (argc <= 1) 471579Sroot usage(); 472579Sroot hseqno = atoi(argv[1]); 473579Sroot argv++; 474579Sroot argc--; 475579Sroot break; 476579Sroot 477579Sroot case 'd': 478579Sroot break; 479579Sroot 480579Sroot default: 481579Sroot usage(); 482579Sroot } 483579Sroot } 48416731Sralph if (argc <= 1) 485579Sroot usage(); 486579Sroot if (gaver == 0) 487579Sroot strcpy(truename, my_name); 488579Sroot time(&iop); 489579Sroot fprintf(tmpf, "%s%s %s", from, truename, ctime(&iop)); 490579Sroot iop = ftell(tmpf); 49116731Sralph flgf = first = 1; 49216731Sralph for (;;) { 49316731Sralph if (first) { 49416731Sralph first = 0; 49516731Sralph if (*line == '\0' && fgets(line, LSIZE, stdin) == NULL) 49616731Sralph break; 49716731Sralph } else { 49816731Sralph if (fgets(line, LSIZE, stdin) == NULL) 49916731Sralph break; 50016731Sralph } 50116731Sralph if (*line == '.' && line[1] == '\n' && isatty(fileno(stdin))) 502579Sroot break; 503579Sroot if (isfrom(line)) 50416731Sralph putc('>', tmpf); 505579Sroot fputs(line, tmpf); 506579Sroot flgf = 0; 507579Sroot } 50816731Sralph putc('\n', tmpf); 509579Sroot nlet = 1; 510579Sroot let[0].adr = 0; 511579Sroot let[1].adr = ftell(tmpf); 512579Sroot if (flgf) 513579Sroot return; 51416731Sralph while (--argc > 0) 5156015Swnj if (!sendmail(0, *++argv, truename)) 516579Sroot error++; 51710644Seric if (error && safefile(dead)) { 518579Sroot setuid(getuid()); 519579Sroot malf = fopen(dead, "w"); 520579Sroot if (malf == NULL) { 52116731Sralph printf("mail: cannot open %s\n", dead); 522579Sroot fclose(tmpf); 523579Sroot return; 524579Sroot } 525579Sroot copylet(0, malf, ZAP); 526579Sroot fclose(malf); 52716731Sralph printf("Mail saved in %s\n", dead); 528579Sroot } 529579Sroot fclose(tmpf); 530579Sroot } 531579Sroot 532*17019Sralph sendrmt(n, name) 533579Sroot char *name; 534579Sroot { 535579Sroot FILE *rmf, *popen(); 536579Sroot register char *p; 537579Sroot char rsys[64], cmd[64]; 538*17019Sralph register pid; 539579Sroot int sts; 540579Sroot 541*17019Sralph #ifdef notdef 542*17019Sralph if (any('^', name)) { 543579Sroot while (p = index(name, '^')) 544579Sroot *p = '!'; 545579Sroot if (strncmp(name, "researc", 7)) { 546579Sroot strcpy(rsys, "research"); 547579Sroot if (*name != '!') 548579Sroot --name; 549579Sroot goto skip; 550579Sroot } 551579Sroot } 552*17019Sralph #endif 553*17019Sralph for (p=rsys; *name!='!'; *p++ = *name++) 554*17019Sralph if (*name=='\0') 555*17019Sralph return(0); /* local address, no '!' */ 556579Sroot *p = '\0'; 557*17019Sralph if (name[1]=='\0') { 55816731Sralph printf("null name\n"); 559579Sroot return(0); 560579Sroot } 561579Sroot skip: 562579Sroot if ((pid = fork()) == -1) { 563579Sroot fprintf(stderr, "mail: can't create proc for remote\n"); 564579Sroot return(0); 565579Sroot } 566579Sroot if (pid) { 567579Sroot while (wait(&sts) != pid) { 568579Sroot if (wait(&sts)==-1) 569579Sroot return(0); 570579Sroot } 571579Sroot return(!sts); 572579Sroot } 573579Sroot setuid(getuid()); 574*17019Sralph if (any('!', name+1)) 575*17019Sralph sprintf(cmd, "uux - %s!rmail \\(%s\\)", rsys, name+1); 576*17019Sralph else 577*17019Sralph sprintf(cmd, "uux - %s!rmail %s", rsys, name+1); 578579Sroot if ((rmf=popen(cmd, "w")) == NULL) 579579Sroot exit(1); 580*17019Sralph copylet(n, rmf, REMOTE); 58110783Seric exit(pclose(rmf) != 0); 582579Sroot } 583579Sroot 584579Sroot usage() 585579Sroot { 586579Sroot 587579Sroot fprintf(stderr, "Usage: mail [ -f ] people . . .\n"); 58815299Skarels error = EX_USAGE; 58916731Sralph done(); 590579Sroot } 591579Sroot 5926015Swnj #include <sys/socket.h> 5939226Ssam #include <netinet/in.h> 59410227Ssam #include <netdb.h> 5956015Swnj 59616731Sralph notifybiff(msg) 59716731Sralph char *msg; 59816731Sralph { 59916731Sralph static struct sockaddr_in addr; 60016731Sralph static int f = -1; 60116731Sralph 60216731Sralph if (addr.sin_family == 0) { 60316731Sralph struct hostent *hp = gethostbyname("localhost"); 60416731Sralph struct servent *sp = getservbyname("biff", "udp"); 60516731Sralph 60616731Sralph if (hp && sp) { 60716731Sralph addr.sin_family = hp->h_addrtype; 60816731Sralph bcopy(hp->h_addr, &addr.sin_addr, hp->h_length); 60916731Sralph addr.sin_port = sp->s_port; 61016731Sralph } 61116731Sralph } 61216731Sralph if (addr.sin_family) { 61316731Sralph if (f < 0) 61416731Sralph f = socket(AF_INET, SOCK_DGRAM, 0); 61516731Sralph sendto(f, msg, strlen(msg)+1, 0, &addr, sizeof (addr)); 61616731Sralph } 61716731Sralph } 61816731Sralph 6196015Swnj sendmail(n, name, fromaddr) 62016731Sralph int n; 62116731Sralph char *name, *fromaddr; 622579Sroot { 62316731Sralph char file[256]; 62416731Sralph int mask, fd; 62516731Sralph struct passwd *pw; 62616731Sralph #ifdef notdef 627579Sroot struct stat statb; 62816731Sralph #endif 6293666Swnj char buf[128]; 630579Sroot 631*17019Sralph if (*name=='!') 632*17019Sralph name++; 633*17019Sralph if (any('!', name)) 634*17019Sralph return (sendrmt(n, name)); 635579Sroot if ((pw = getpwnam(name)) == NULL) { 63616731Sralph printf("mail: can't send to %s\n", name); 637579Sroot return(0); 638579Sroot } 639579Sroot cat(file, maildir, name); 64016731Sralph #ifdef notdef 641579Sroot if (stat(file, &statb) >= 0 && (statb.st_mode & S_IFMT) == S_IFDIR) { 642579Sroot strcat(file, "/"); 643579Sroot strcat(file, name); 644579Sroot } 64516731Sralph #endif 64610644Seric if (!safefile(file)) 6474458Sroot return(0); 64816731Sralph fd = open(file, O_WRONLY | O_CREAT, MAILMODE); 64916731Sralph if (fd >= 0) { 65016731Sralph flock(fd, LOCK_EX); 65116731Sralph malf = fdopen(fd, "a"); 65216731Sralph } 65316731Sralph if (fd < 0 || malf == NULL) { 65416731Sralph close(fd); 65516731Sralph printf("mail: %s: cannot append\n", file); 656579Sroot return(0); 657579Sroot } 65816731Sralph fchown(fd, pw->pw_uid, pw->pw_gid); 65916731Sralph sprintf(buf, "%s@%d\n", name, ftell(malf)); 660579Sroot copylet(n, malf, ORDINARY); 6616015Swnj fclose(malf); 66216731Sralph notifybiff(buf); 663579Sroot return(1); 664579Sroot } 665579Sroot 66616731Sralph delex(i) 667579Sroot { 66816731Sralph setsig(i, delex); 66916731Sralph putc('\n', stderr); 67016731Sralph if (delflg) 671579Sroot longjmp(sjbuf, 1); 672579Sroot done(); 673579Sroot } 674579Sroot 67516731Sralph done() 676579Sroot { 677579Sroot 678579Sroot unlink(lettmp); 679579Sroot exit(error); 680579Sroot } 681579Sroot 682579Sroot cat(to, from1, from2) 68316731Sralph char *to, *from1, *from2; 684579Sroot { 68516731Sralph register char *cp, *dp; 686579Sroot 68716731Sralph cp = to; 68816731Sralph for (dp = from1; *cp = *dp++; cp++) 68916731Sralph ; 69016731Sralph for (dp = from2; *cp++ = *dp++; ) 69116731Sralph ; 692579Sroot } 693579Sroot 69416731Sralph /* copy p... into s, update p */ 69516731Sralph char * 69616731Sralph getarg(s, p) 69716731Sralph register char *s, *p; 698579Sroot { 699579Sroot while (*p == ' ' || *p == '\t') 700579Sroot p++; 701579Sroot if (*p == '\n' || *p == '\0') 702579Sroot return(NULL); 703579Sroot while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') 704579Sroot *s++ = *p++; 705579Sroot *s = '\0'; 706579Sroot return(p); 707579Sroot } 70810644Seric 70910644Seric safefile(f) 71010644Seric char *f; 71110644Seric { 71210644Seric struct stat statb; 71310644Seric 71410644Seric if (lstat(f, &statb) < 0) 71510644Seric return (1); 71610644Seric if (statb.st_nlink != 1 || (statb.st_mode & S_IFMT) == S_IFLNK) { 71716731Sralph fprintf(stderr, 71816731Sralph "mail: %s has more than one link or is a symbolic link\n", 71916731Sralph f); 72010644Seric return (0); 72110644Seric } 72210644Seric return (1); 72310644Seric } 72416731Sralph 72516731Sralph panic(msg, a1, a2, a3) 72616731Sralph char *msg; 72716731Sralph { 72816731Sralph 72916731Sralph fprintf(stderr, "mail: "); 73016731Sralph fprintf(stderr, msg, a1, a2, a3); 73116731Sralph fprintf(stderr, "\n"); 73216731Sralph done(); 73316731Sralph } 734