114465Ssam #ifndef lint 2*19868Smiriam static char sccsid[] = "@(#)mail.local.c 4.25 (Berkeley) 05/01/85"; 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; 67*19868Smiriam struct passwd *pwent; 68579Sroot 69579Sroot my_name = getlogin(); 7016731Sralph if (my_name == NULL || *my_name == '\0') { 71579Sroot pwent = getpwuid(getuid()); 72579Sroot if (pwent==NULL) 73579Sroot my_name = "???"; 74579Sroot else 75579Sroot my_name = pwent->pw_name; 76579Sroot } 77*19868Smiriam else { 78*19868Smiriam pwent = getpwnam(my_name); 79*19868Smiriam if ( getuid() != pwent->pw_uid) { 80*19868Smiriam pwent = getpwuid(getuid()); 81*19868Smiriam my_name = pwent->pw_name; 82*19868Smiriam } 83*19868Smiriam } 8416731Sralph if (setjmp(sjbuf)) 8516731Sralph done(); 8614912Sralph for (i=SIGHUP; i<=SIGTERM; i++) 8716731Sralph setsig(i, delex); 8817533Sralph i = mkstemp(lettmp); 8917533Sralph tmpf = fdopen(i, "r+w"); 9017533Sralph if (i < 0 || tmpf == NULL) 9116731Sralph panic("mail: %s: cannot open for writing", lettmp); 9216731Sralph /* 9316731Sralph * This protects against others reading mail from temp file and 9416731Sralph * if we exit, the file will be deleted already. 9516731Sralph */ 9616731Sralph unlink(lettmp); 97579Sroot if (argv[0][0] == 'r') 98579Sroot rmail++; 99579Sroot if (argv[0][0] != 'r' && /* no favors for rmail*/ 100579Sroot (argc == 1 || argv[1][0] == '-' && !any(argv[1][1], "rhd"))) 101579Sroot printmail(argc, argv); 102579Sroot else 1036015Swnj bulkmail(argc, argv); 104579Sroot done(); 105579Sroot } 106579Sroot 107579Sroot setsig(i, f) 108579Sroot int i; 109579Sroot int (*f)(); 110579Sroot { 11116731Sralph if (signal(i, SIG_IGN) != SIG_IGN) 112579Sroot signal(i, f); 113579Sroot } 114579Sroot 115579Sroot any(c, str) 116579Sroot register int c; 117579Sroot register char *str; 118579Sroot { 119579Sroot 120579Sroot while (*str) 121579Sroot if (c == *str++) 122579Sroot return(1); 123579Sroot return(0); 124579Sroot } 125579Sroot 126579Sroot printmail(argc, argv) 12716731Sralph char **argv; 128579Sroot { 129579Sroot int flg, i, j, print; 130579Sroot char *p, *getarg(); 131579Sroot struct stat statb; 132579Sroot 133579Sroot setuid(getuid()); 134579Sroot cat(mailfile, maildir, my_name); 13516731Sralph #ifdef notdef 136579Sroot if (stat(mailfile, &statb) >= 0 137579Sroot && (statb.st_mode & S_IFMT) == S_IFDIR) { 138579Sroot strcat(mailfile, "/"); 139579Sroot strcat(mailfile, my_name); 140579Sroot } 14116731Sralph #endif 14216731Sralph for (; argc > 1; argv++, argc--) { 14316731Sralph if (argv[1][0] != '-') 14416731Sralph break; 14516731Sralph switch (argv[1][1]) { 14616731Sralph 14716731Sralph case 'p': 14816731Sralph flgp++; 14916731Sralph /* fall thru... */ 15016731Sralph case 'q': 15116731Sralph delflg = 0; 15216731Sralph break; 15316731Sralph 15416731Sralph case 'f': 15516731Sralph if (argc >= 3) { 15616731Sralph strcpy(mailfile, argv[2]); 15716731Sralph argv++, argc--; 158579Sroot } 159579Sroot break; 16016731Sralph 16116731Sralph case 'b': 16216731Sralph forward = 1; 16316731Sralph break; 16416731Sralph 16516731Sralph default: 16616731Sralph panic("unknown option %c", argv[1][1]); 16716731Sralph /*NOTREACHED*/ 16816731Sralph } 169579Sroot } 170579Sroot malf = fopen(mailfile, "r"); 171579Sroot if (malf == NULL) { 17216731Sralph printf("No mail.\n"); 173579Sroot return; 174579Sroot } 17516731Sralph flock(fileno(malf), LOCK_SH); 176579Sroot copymt(malf, tmpf); 17716731Sralph fclose(malf); /* implicit unlock */ 17816731Sralph fseek(tmpf, 0, L_SET); 179579Sroot 180579Sroot changed = 0; 181579Sroot print = 1; 182579Sroot for (i = 0; i < nlet; ) { 183579Sroot j = forward ? i : nlet - i - 1; 18416731Sralph if (setjmp(sjbuf)) { 18516731Sralph print = 0; 186579Sroot } else { 187579Sroot if (print) 188579Sroot copylet(j, stdout, ORDINARY); 189579Sroot print = 1; 190579Sroot } 191579Sroot if (flgp) { 192579Sroot i++; 193579Sroot continue; 194579Sroot } 195579Sroot setjmp(sjbuf); 19616731Sralph fputs("? ", stdout); 197579Sroot fflush(stdout); 198579Sroot if (fgets(resp, LSIZE, stdin) == NULL) 199579Sroot break; 200579Sroot switch (resp[0]) { 201579Sroot 202579Sroot default: 20316731Sralph printf("usage\n"); 204579Sroot case '?': 205579Sroot print = 0; 20616731Sralph printf("q\tquit\n"); 20716731Sralph printf("x\texit without changing mail\n"); 20816731Sralph printf("p\tprint\n"); 20916731Sralph printf("s[file]\tsave (default mbox)\n"); 21016731Sralph printf("w[file]\tsame without header\n"); 21116731Sralph printf("-\tprint previous\n"); 21216731Sralph printf("d\tdelete\n"); 21316731Sralph printf("+\tnext (no delete)\n"); 21416731Sralph printf("m user\tmail to user\n"); 21516731Sralph printf("! cmd\texecute cmd\n"); 216579Sroot break; 217579Sroot 218579Sroot case '+': 219579Sroot case 'n': 220579Sroot case '\n': 221579Sroot i++; 222579Sroot break; 223579Sroot case 'x': 224579Sroot changed = 0; 225579Sroot case 'q': 226579Sroot goto donep; 227579Sroot case 'p': 228579Sroot break; 229579Sroot case '^': 230579Sroot case '-': 231579Sroot if (--i < 0) 232579Sroot i = 0; 233579Sroot break; 234579Sroot case 'y': 235579Sroot case 'w': 236579Sroot case 's': 237579Sroot flg = 0; 238579Sroot if (resp[1] != '\n' && resp[1] != ' ') { 239579Sroot printf("illegal\n"); 240579Sroot flg++; 241579Sroot print = 0; 242579Sroot continue; 243579Sroot } 244579Sroot if (resp[1] == '\n' || resp[1] == '\0') { 245579Sroot p = getenv("HOME"); 24616731Sralph if (p != 0) 247579Sroot cat(resp+1, p, "/mbox"); 248579Sroot else 249579Sroot cat(resp+1, "", "mbox"); 250579Sroot } 251579Sroot for (p = resp+1; (p = getarg(lfil, p)) != NULL; ) { 252579Sroot malf = fopen(lfil, "a"); 253579Sroot if (malf == NULL) { 25416731Sralph printf("mail: %s: cannot append\n", 25516731Sralph lfil); 256579Sroot flg++; 257579Sroot continue; 258579Sroot } 259579Sroot copylet(j, malf, resp[0]=='w'? ZAP: ORDINARY); 260579Sroot fclose(malf); 261579Sroot } 262579Sroot if (flg) 263579Sroot print = 0; 264579Sroot else { 265579Sroot let[j].change = 'd'; 266579Sroot changed++; 267579Sroot i++; 268579Sroot } 269579Sroot break; 270579Sroot case 'm': 271579Sroot flg = 0; 272579Sroot if (resp[1] == '\n' || resp[1] == '\0') { 273579Sroot i++; 274579Sroot continue; 275579Sroot } 276579Sroot if (resp[1] != ' ') { 277579Sroot printf("invalid command\n"); 278579Sroot flg++; 279579Sroot print = 0; 280579Sroot continue; 281579Sroot } 282579Sroot for (p = resp+1; (p = getarg(lfil, p)) != NULL; ) 28317019Sralph if (!sendmail(j, lfil, my_name)) 284579Sroot flg++; 285579Sroot if (flg) 286579Sroot print = 0; 287579Sroot else { 288579Sroot let[j].change = 'd'; 289579Sroot changed++; 290579Sroot i++; 291579Sroot } 292579Sroot break; 293579Sroot case '!': 294579Sroot system(resp+1); 295579Sroot printf("!\n"); 296579Sroot print = 0; 297579Sroot break; 298579Sroot case 'd': 299579Sroot let[j].change = 'd'; 300579Sroot changed++; 301579Sroot i++; 302579Sroot if (resp[1] == 'q') 303579Sroot goto donep; 304579Sroot break; 305579Sroot } 306579Sroot } 307579Sroot donep: 308579Sroot if (changed) 309579Sroot copyback(); 310579Sroot } 311579Sroot 31216731Sralph /* copy temp or whatever back to /usr/spool/mail */ 31316731Sralph copyback() 314579Sroot { 31516731Sralph register i, c; 31616731Sralph int fd, new = 0, oldmask; 317579Sroot struct stat stbuf; 318579Sroot 31916731Sralph #define mask(s) (1 << ((s) - 1)) 32016731Sralph oldmask = sigblock(mask(SIGINT)|mask(SIGHUP)|mask(SIGQUIT)); 32116731Sralph #undef mask 32216731Sralph fd = open(mailfile, O_RDWR | O_CREAT, MAILMODE); 32316731Sralph if (fd >= 0) { 32416731Sralph flock(fd, LOCK_EX); 32516731Sralph malf = fdopen(fd, "r+w"); 32616731Sralph } 32716731Sralph if (fd < 0 || malf == NULL) 32816731Sralph panic("can't rewrite %s", lfil); 32916731Sralph fstat(fd, &stbuf); 330579Sroot if (stbuf.st_size != let[nlet].adr) { /* new mail has arrived */ 33116731Sralph fseek(malf, let[nlet].adr, L_SET); 33216731Sralph fseek(tmpf, let[nlet].adr, L_SET); 33316731Sralph while ((c = getc(malf)) != EOF) 33416731Sralph putc(c, tmpf); 335579Sroot let[++nlet].adr = stbuf.st_size; 336579Sroot new = 1; 33716731Sralph fseek(malf, 0, L_SET); 338579Sroot } 33916731Sralph ftruncate(fd, 0); 340579Sroot for (i = 0; i < nlet; i++) 34116731Sralph if (let[i].change != 'd') 342579Sroot copylet(i, malf, ORDINARY); 34316731Sralph fclose(malf); /* implict unlock */ 344579Sroot if (new) 34516731Sralph printf("New mail has arrived.\n"); 34616731Sralph sigsetmask(oldmask); 347579Sroot } 348579Sroot 34916731Sralph /* copy mail (f1) to temp (f2) */ 35016731Sralph copymt(f1, f2) 35116731Sralph FILE *f1, *f2; 352579Sroot { 353579Sroot long nextadr; 354579Sroot 355579Sroot nlet = nextadr = 0; 356579Sroot let[0].adr = 0; 357579Sroot while (fgets(line, LSIZE, f1) != NULL) { 358579Sroot if (isfrom(line)) 359579Sroot let[nlet++].adr = nextadr; 360579Sroot nextadr += strlen(line); 361579Sroot fputs(line, f2); 362579Sroot } 363579Sroot let[nlet].adr = nextadr; /* last plus 1 */ 364579Sroot } 365579Sroot 36611893Seric copylet(n, f, type) 36711893Seric FILE *f; 36811893Seric { 36911893Seric int ch; 37011893Seric long k; 37116731Sralph char hostname[32]; 37211893Seric 37316731Sralph fseek(tmpf, let[n].adr, L_SET); 374579Sroot k = let[n+1].adr - let[n].adr; 37516731Sralph while (k-- > 1 && (ch = getc(tmpf)) != '\n') 37616731Sralph if (type != ZAP) 37716731Sralph putc(ch, f); 37816731Sralph switch (type) { 37916731Sralph 38016731Sralph case REMOTE: 3816199Sroot gethostname(hostname, sizeof (hostname)); 3826199Sroot fprintf(f, " remote from %s\n", hostname); 38316731Sralph break; 38416731Sralph 38516731Sralph case FORWARD: 386579Sroot fprintf(f, forwmsg); 38716731Sralph break; 38816731Sralph 38916731Sralph case ORDINARY: 39016731Sralph putc(ch, f); 39116731Sralph break; 39216731Sralph 39317019Sralph case ZAP: 39417019Sralph break; 39517019Sralph 39616731Sralph default: 39716731Sralph panic("Bad letter type %d to copylet.", type); 39816731Sralph } 39916731Sralph while (k-- > 1) { 40016731Sralph ch = getc(tmpf); 40116731Sralph putc(ch, f); 40216731Sralph } 40316731Sralph if (type != ZAP || ch != '\n') 40416731Sralph putc(getc(tmpf), f); 405579Sroot } 406579Sroot 407579Sroot isfrom(lp) 408579Sroot register char *lp; 409579Sroot { 410579Sroot register char *p; 411579Sroot 412579Sroot for (p = from; *p; ) 413579Sroot if (*lp++ != *p++) 414579Sroot return(0); 415579Sroot return(1); 416579Sroot } 417579Sroot 4186015Swnj bulkmail(argc, argv) 419579Sroot char **argv; 420579Sroot { 421579Sroot char truename[100]; 422579Sroot int first; 423579Sroot register char *cp; 424579Sroot int gaver = 0; 425579Sroot char *newargv[1000]; 426579Sroot register char **ap; 427579Sroot register char **vp; 428579Sroot int dflag; 429579Sroot 430579Sroot dflag = 0; 43116731Sralph if (argc < 1) { 432579Sroot fprintf(stderr, "puke\n"); 43316731Sralph return; 43416731Sralph } 435579Sroot for (vp = argv, ap = newargv + 1; (*ap = *vp++) != 0; ap++) 436579Sroot if (ap[0][0] == '-' && ap[0][1] == 'd') 437579Sroot dflag++; 43816731Sralph if (!dflag) { 4399978Seric /* give it to sendmail, rah rah! */ 440579Sroot unlink(lettmp); 441579Sroot ap = newargv+1; 442579Sroot if (rmail) 443579Sroot *ap-- = "-s"; 4449978Seric *ap = "-sendmail"; 4454461Sroot setuid(getuid()); 4469978Seric execv(SENDMAIL, ap); 4479978Seric perror(SENDMAIL); 448579Sroot exit(EX_UNAVAILABLE); 449579Sroot } 450579Sroot 451579Sroot truename[0] = 0; 452579Sroot line[0] = '\0'; 453579Sroot 454579Sroot /* 455579Sroot * When we fall out of this, argv[1] should be first name, 456579Sroot * argc should be number of names + 1. 457579Sroot */ 458579Sroot 459579Sroot while (argc > 1 && *argv[1] == '-') { 460579Sroot cp = *++argv; 461579Sroot argc--; 462579Sroot switch (cp[1]) { 463579Sroot case 'r': 46416731Sralph if (argc <= 1) 465579Sroot usage(); 46615346Skarels gaver++; 46715346Skarels strcpy(truename, argv[1]); 46815346Skarels fgets(line, LSIZE, stdin); 46915346Skarels if (strcmpn("From", line, 4) == 0) 47015346Skarels line[0] = '\0'; 471579Sroot argv++; 472579Sroot argc--; 473579Sroot break; 474579Sroot 475579Sroot case 'h': 47616731Sralph if (argc <= 1) 477579Sroot usage(); 478579Sroot hseqno = atoi(argv[1]); 479579Sroot argv++; 480579Sroot argc--; 481579Sroot break; 482579Sroot 483579Sroot case 'd': 484579Sroot break; 485579Sroot 486579Sroot default: 487579Sroot usage(); 488579Sroot } 489579Sroot } 49016731Sralph if (argc <= 1) 491579Sroot usage(); 492579Sroot if (gaver == 0) 493579Sroot strcpy(truename, my_name); 494579Sroot time(&iop); 495579Sroot fprintf(tmpf, "%s%s %s", from, truename, ctime(&iop)); 496579Sroot iop = ftell(tmpf); 49716731Sralph flgf = first = 1; 49816731Sralph for (;;) { 49916731Sralph if (first) { 50016731Sralph first = 0; 50116731Sralph if (*line == '\0' && fgets(line, LSIZE, stdin) == NULL) 50216731Sralph break; 50316731Sralph } else { 50416731Sralph if (fgets(line, LSIZE, stdin) == NULL) 50516731Sralph break; 50616731Sralph } 50716731Sralph if (*line == '.' && line[1] == '\n' && isatty(fileno(stdin))) 508579Sroot break; 509579Sroot if (isfrom(line)) 51016731Sralph putc('>', tmpf); 511579Sroot fputs(line, tmpf); 512579Sroot flgf = 0; 513579Sroot } 51416731Sralph putc('\n', tmpf); 515579Sroot nlet = 1; 516579Sroot let[0].adr = 0; 517579Sroot let[1].adr = ftell(tmpf); 518579Sroot if (flgf) 519579Sroot return; 52016731Sralph while (--argc > 0) 5216015Swnj if (!sendmail(0, *++argv, truename)) 522579Sroot error++; 52310644Seric if (error && safefile(dead)) { 524579Sroot setuid(getuid()); 525579Sroot malf = fopen(dead, "w"); 526579Sroot if (malf == NULL) { 52716731Sralph printf("mail: cannot open %s\n", dead); 528579Sroot fclose(tmpf); 529579Sroot return; 530579Sroot } 531579Sroot copylet(0, malf, ZAP); 532579Sroot fclose(malf); 53316731Sralph printf("Mail saved in %s\n", dead); 534579Sroot } 535579Sroot fclose(tmpf); 536579Sroot } 537579Sroot 53817019Sralph sendrmt(n, name) 539579Sroot char *name; 540579Sroot { 541579Sroot FILE *rmf, *popen(); 542579Sroot register char *p; 543579Sroot char rsys[64], cmd[64]; 54417019Sralph register pid; 545579Sroot int sts; 546579Sroot 54717019Sralph #ifdef notdef 54817019Sralph if (any('^', name)) { 549579Sroot while (p = index(name, '^')) 550579Sroot *p = '!'; 551579Sroot if (strncmp(name, "researc", 7)) { 552579Sroot strcpy(rsys, "research"); 553579Sroot if (*name != '!') 554579Sroot --name; 555579Sroot goto skip; 556579Sroot } 557579Sroot } 55817019Sralph #endif 55917019Sralph for (p=rsys; *name!='!'; *p++ = *name++) 56017019Sralph if (*name=='\0') 56117019Sralph return(0); /* local address, no '!' */ 562579Sroot *p = '\0'; 56317019Sralph if (name[1]=='\0') { 56416731Sralph printf("null name\n"); 565579Sroot return(0); 566579Sroot } 567579Sroot skip: 568579Sroot if ((pid = fork()) == -1) { 569579Sroot fprintf(stderr, "mail: can't create proc for remote\n"); 570579Sroot return(0); 571579Sroot } 572579Sroot if (pid) { 573579Sroot while (wait(&sts) != pid) { 574579Sroot if (wait(&sts)==-1) 575579Sroot return(0); 576579Sroot } 577579Sroot return(!sts); 578579Sroot } 579579Sroot setuid(getuid()); 58017019Sralph if (any('!', name+1)) 58117019Sralph sprintf(cmd, "uux - %s!rmail \\(%s\\)", rsys, name+1); 58217019Sralph else 58317019Sralph sprintf(cmd, "uux - %s!rmail %s", rsys, name+1); 584579Sroot if ((rmf=popen(cmd, "w")) == NULL) 585579Sroot exit(1); 58617019Sralph copylet(n, rmf, REMOTE); 58710783Seric exit(pclose(rmf) != 0); 588579Sroot } 589579Sroot 590579Sroot usage() 591579Sroot { 592579Sroot 593579Sroot fprintf(stderr, "Usage: mail [ -f ] people . . .\n"); 59415299Skarels error = EX_USAGE; 59516731Sralph done(); 596579Sroot } 597579Sroot 5986015Swnj #include <sys/socket.h> 5999226Ssam #include <netinet/in.h> 60010227Ssam #include <netdb.h> 6016015Swnj 60216731Sralph notifybiff(msg) 60316731Sralph char *msg; 60416731Sralph { 60516731Sralph static struct sockaddr_in addr; 60616731Sralph static int f = -1; 60716731Sralph 60816731Sralph if (addr.sin_family == 0) { 60916731Sralph struct hostent *hp = gethostbyname("localhost"); 61016731Sralph struct servent *sp = getservbyname("biff", "udp"); 61116731Sralph 61216731Sralph if (hp && sp) { 61316731Sralph addr.sin_family = hp->h_addrtype; 61416731Sralph bcopy(hp->h_addr, &addr.sin_addr, hp->h_length); 61516731Sralph addr.sin_port = sp->s_port; 61616731Sralph } 61716731Sralph } 61816731Sralph if (addr.sin_family) { 61916731Sralph if (f < 0) 62016731Sralph f = socket(AF_INET, SOCK_DGRAM, 0); 62116731Sralph sendto(f, msg, strlen(msg)+1, 0, &addr, sizeof (addr)); 62216731Sralph } 62316731Sralph } 62416731Sralph 6256015Swnj sendmail(n, name, fromaddr) 62616731Sralph int n; 62716731Sralph char *name, *fromaddr; 628579Sroot { 62916731Sralph char file[256]; 63016731Sralph int mask, fd; 63116731Sralph struct passwd *pw; 63216731Sralph #ifdef notdef 633579Sroot struct stat statb; 63416731Sralph #endif 6353666Swnj char buf[128]; 636579Sroot 63717019Sralph if (*name=='!') 63817019Sralph name++; 63917019Sralph if (any('!', name)) 64017019Sralph return (sendrmt(n, name)); 641579Sroot if ((pw = getpwnam(name)) == NULL) { 64216731Sralph printf("mail: can't send to %s\n", name); 643579Sroot return(0); 644579Sroot } 645579Sroot cat(file, maildir, name); 64616731Sralph #ifdef notdef 647579Sroot if (stat(file, &statb) >= 0 && (statb.st_mode & S_IFMT) == S_IFDIR) { 648579Sroot strcat(file, "/"); 649579Sroot strcat(file, name); 650579Sroot } 65116731Sralph #endif 65210644Seric if (!safefile(file)) 6534458Sroot return(0); 65416731Sralph fd = open(file, O_WRONLY | O_CREAT, MAILMODE); 65516731Sralph if (fd >= 0) { 65616731Sralph flock(fd, LOCK_EX); 65716731Sralph malf = fdopen(fd, "a"); 65816731Sralph } 65916731Sralph if (fd < 0 || malf == NULL) { 66016731Sralph close(fd); 66116731Sralph printf("mail: %s: cannot append\n", file); 662579Sroot return(0); 663579Sroot } 66416731Sralph fchown(fd, pw->pw_uid, pw->pw_gid); 66516731Sralph sprintf(buf, "%s@%d\n", name, ftell(malf)); 666579Sroot copylet(n, malf, ORDINARY); 6676015Swnj fclose(malf); 66816731Sralph notifybiff(buf); 669579Sroot return(1); 670579Sroot } 671579Sroot 67216731Sralph delex(i) 673579Sroot { 67416731Sralph setsig(i, delex); 67516731Sralph putc('\n', stderr); 67616731Sralph if (delflg) 677579Sroot longjmp(sjbuf, 1); 678579Sroot done(); 679579Sroot } 680579Sroot 68116731Sralph done() 682579Sroot { 683579Sroot 684579Sroot unlink(lettmp); 685579Sroot exit(error); 686579Sroot } 687579Sroot 688579Sroot cat(to, from1, from2) 68916731Sralph char *to, *from1, *from2; 690579Sroot { 69116731Sralph register char *cp, *dp; 692579Sroot 69316731Sralph cp = to; 69416731Sralph for (dp = from1; *cp = *dp++; cp++) 69516731Sralph ; 69616731Sralph for (dp = from2; *cp++ = *dp++; ) 69716731Sralph ; 698579Sroot } 699579Sroot 70016731Sralph /* copy p... into s, update p */ 70116731Sralph char * 70216731Sralph getarg(s, p) 70316731Sralph register char *s, *p; 704579Sroot { 705579Sroot while (*p == ' ' || *p == '\t') 706579Sroot p++; 707579Sroot if (*p == '\n' || *p == '\0') 708579Sroot return(NULL); 709579Sroot while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') 710579Sroot *s++ = *p++; 711579Sroot *s = '\0'; 712579Sroot return(p); 713579Sroot } 71410644Seric 71510644Seric safefile(f) 71610644Seric char *f; 71710644Seric { 71810644Seric struct stat statb; 71910644Seric 72010644Seric if (lstat(f, &statb) < 0) 72110644Seric return (1); 72210644Seric if (statb.st_nlink != 1 || (statb.st_mode & S_IFMT) == S_IFLNK) { 72316731Sralph fprintf(stderr, 72416731Sralph "mail: %s has more than one link or is a symbolic link\n", 72516731Sralph f); 72610644Seric return (0); 72710644Seric } 72810644Seric return (1); 72910644Seric } 73016731Sralph 73116731Sralph panic(msg, a1, a2, a3) 73216731Sralph char *msg; 73316731Sralph { 73416731Sralph 73516731Sralph fprintf(stderr, "mail: "); 73616731Sralph fprintf(stderr, msg, a1, a2, a3); 73716731Sralph fprintf(stderr, "\n"); 73816731Sralph done(); 73916731Sralph } 740