114465Ssam #ifndef lint 2*16731Sralph static char sccsid[] = "@(#)mail.local.c 4.22 (Berkeley) 07/19/84"; 314465Ssam #endif 414465Ssam 5*16731Sralph #include <sys/types.h> 6*16731Sralph #include <sys/stat.h> 7*16731Sralph #include <sys/file.h> 8*16731Sralph 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 19*16731Sralph /* copylet flags */ 20*16731Sralph #define REMOTE 1 /* remote mail, add rmtmsg */ 21*16731Sralph #define ORDINARY 2 22*16731Sralph #define ZAP 3 /* zap header and trailing empty line */ 23*16731Sralph #define FORWARD 4 24579Sroot 25*16731Sralph #define LSIZE 256 26*16731Sralph #define MAXLET 300 /* maximum number of letters */ 27*16731Sralph #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(); 54*16731Sralph 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(); 71*16731Sralph 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 } 79*16731Sralph if (setjmp(sjbuf)) 80*16731Sralph done(); 8114912Sralph for (i=SIGHUP; i<=SIGTERM; i++) 82*16731Sralph setsig(i, delex); 83*16731Sralph tmpf = fopen(lettmp, "w+r"); 84*16731Sralph if (tmpf == NULL) 85*16731Sralph panic("mail: %s: cannot open for writing", lettmp); 86*16731Sralph /* 87*16731Sralph * This protects against others reading mail from temp file and 88*16731Sralph * if we exit, the file will be deleted already. 89*16731Sralph */ 90*16731Sralph 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 { 105*16731Sralph 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) 121*16731Sralph 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); 129*16731Sralph #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 } 135*16731Sralph #endif 136*16731Sralph for (; argc > 1; argv++, argc--) { 137*16731Sralph if (argv[1][0] != '-') 138*16731Sralph break; 139*16731Sralph switch (argv[1][1]) { 140*16731Sralph 141*16731Sralph case 'p': 142*16731Sralph flgp++; 143*16731Sralph /* fall thru... */ 144*16731Sralph case 'q': 145*16731Sralph delflg = 0; 146*16731Sralph break; 147*16731Sralph 148*16731Sralph case 'f': 149*16731Sralph if (argc >= 3) { 150*16731Sralph strcpy(mailfile, argv[2]); 151*16731Sralph argv++, argc--; 152579Sroot } 153579Sroot break; 154*16731Sralph 155*16731Sralph case 'b': 156*16731Sralph forward = 1; 157*16731Sralph break; 158*16731Sralph 159*16731Sralph default: 160*16731Sralph panic("unknown option %c", argv[1][1]); 161*16731Sralph /*NOTREACHED*/ 162*16731Sralph } 163579Sroot } 164579Sroot malf = fopen(mailfile, "r"); 165579Sroot if (malf == NULL) { 166*16731Sralph printf("No mail.\n"); 167579Sroot return; 168579Sroot } 169*16731Sralph flock(fileno(malf), LOCK_SH); 170579Sroot copymt(malf, tmpf); 171*16731Sralph fclose(malf); /* implicit unlock */ 172*16731Sralph 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; 178*16731Sralph if (setjmp(sjbuf)) { 179*16731Sralph 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); 190*16731Sralph fputs("? ", stdout); 191579Sroot fflush(stdout); 192579Sroot if (fgets(resp, LSIZE, stdin) == NULL) 193579Sroot break; 194579Sroot switch (resp[0]) { 195579Sroot 196579Sroot default: 197*16731Sralph printf("usage\n"); 198579Sroot case '?': 199579Sroot print = 0; 200*16731Sralph printf("q\tquit\n"); 201*16731Sralph printf("x\texit without changing mail\n"); 202*16731Sralph printf("p\tprint\n"); 203*16731Sralph printf("s[file]\tsave (default mbox)\n"); 204*16731Sralph printf("w[file]\tsame without header\n"); 205*16731Sralph printf("-\tprint previous\n"); 206*16731Sralph printf("d\tdelete\n"); 207*16731Sralph printf("+\tnext (no delete)\n"); 208*16731Sralph printf("m user\tmail to user\n"); 209*16731Sralph 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"); 240*16731Sralph 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) { 248*16731Sralph printf("mail: %s: cannot append\n", 249*16731Sralph 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*16731Sralph if (!sendrmt(j, lfil, "/bin/mail")) 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 306*16731Sralph /* copy temp or whatever back to /usr/spool/mail */ 307*16731Sralph copyback() 308579Sroot { 309*16731Sralph register i, c; 310*16731Sralph int fd, new = 0, oldmask; 311579Sroot struct stat stbuf; 312579Sroot 313*16731Sralph #define mask(s) (1 << ((s) - 1)) 314*16731Sralph oldmask = sigblock(mask(SIGINT)|mask(SIGHUP)|mask(SIGQUIT)); 315*16731Sralph #undef mask 316*16731Sralph fd = open(mailfile, O_RDWR | O_CREAT, MAILMODE); 317*16731Sralph if (fd >= 0) { 318*16731Sralph flock(fd, LOCK_EX); 319*16731Sralph malf = fdopen(fd, "r+w"); 320*16731Sralph } 321*16731Sralph if (fd < 0 || malf == NULL) 322*16731Sralph panic("can't rewrite %s", lfil); 323*16731Sralph fstat(fd, &stbuf); 324579Sroot if (stbuf.st_size != let[nlet].adr) { /* new mail has arrived */ 325*16731Sralph fseek(malf, let[nlet].adr, L_SET); 326*16731Sralph fseek(tmpf, let[nlet].adr, L_SET); 327*16731Sralph while ((c = getc(malf)) != EOF) 328*16731Sralph putc(c, tmpf); 329579Sroot let[++nlet].adr = stbuf.st_size; 330579Sroot new = 1; 331*16731Sralph fseek(malf, 0, L_SET); 332579Sroot } 333*16731Sralph ftruncate(fd, 0); 334579Sroot for (i = 0; i < nlet; i++) 335*16731Sralph if (let[i].change != 'd') 336579Sroot copylet(i, malf, ORDINARY); 337*16731Sralph fclose(malf); /* implict unlock */ 338579Sroot if (new) 339*16731Sralph printf("New mail has arrived.\n"); 340*16731Sralph sigsetmask(oldmask); 341579Sroot } 342579Sroot 343*16731Sralph /* copy mail (f1) to temp (f2) */ 344*16731Sralph copymt(f1, f2) 345*16731Sralph 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; 365*16731Sralph char hostname[32]; 36611893Seric 367*16731Sralph fseek(tmpf, let[n].adr, L_SET); 368579Sroot k = let[n+1].adr - let[n].adr; 369*16731Sralph while (k-- > 1 && (ch = getc(tmpf)) != '\n') 370*16731Sralph if (type != ZAP) 371*16731Sralph putc(ch, f); 372*16731Sralph switch (type) { 373*16731Sralph 374*16731Sralph case REMOTE: 3756199Sroot gethostname(hostname, sizeof (hostname)); 3766199Sroot fprintf(f, " remote from %s\n", hostname); 377*16731Sralph break; 378*16731Sralph 379*16731Sralph case FORWARD: 380579Sroot fprintf(f, forwmsg); 381*16731Sralph break; 382*16731Sralph 383*16731Sralph case ORDINARY: 384*16731Sralph putc(ch, f); 385*16731Sralph break; 386*16731Sralph 387*16731Sralph default: 388*16731Sralph panic("Bad letter type %d to copylet.", type); 389*16731Sralph } 390*16731Sralph while (k-- > 1) { 391*16731Sralph ch = getc(tmpf); 392*16731Sralph putc(ch, f); 393*16731Sralph } 394*16731Sralph if (type != ZAP || ch != '\n') 395*16731Sralph putc(getc(tmpf), f); 396579Sroot } 397579Sroot 398579Sroot isfrom(lp) 399579Sroot register char *lp; 400579Sroot { 401579Sroot register char *p; 402579Sroot 403579Sroot for (p = from; *p; ) 404579Sroot if (*lp++ != *p++) 405579Sroot return(0); 406579Sroot return(1); 407579Sroot } 408579Sroot 4096015Swnj bulkmail(argc, argv) 410579Sroot char **argv; 411579Sroot { 412579Sroot char truename[100]; 413579Sroot int first; 414579Sroot register char *cp; 415579Sroot int gaver = 0; 416579Sroot char *newargv[1000]; 417579Sroot register char **ap; 418579Sroot register char **vp; 419579Sroot int dflag; 420579Sroot 421579Sroot dflag = 0; 422*16731Sralph if (argc < 1) { 423579Sroot fprintf(stderr, "puke\n"); 424*16731Sralph return; 425*16731Sralph } 426579Sroot for (vp = argv, ap = newargv + 1; (*ap = *vp++) != 0; ap++) 427579Sroot if (ap[0][0] == '-' && ap[0][1] == 'd') 428579Sroot dflag++; 429*16731Sralph if (!dflag) { 4309978Seric /* give it to sendmail, rah rah! */ 431579Sroot unlink(lettmp); 432579Sroot ap = newargv+1; 433579Sroot if (rmail) 434579Sroot *ap-- = "-s"; 4359978Seric *ap = "-sendmail"; 4364461Sroot setuid(getuid()); 4379978Seric execv(SENDMAIL, ap); 4389978Seric perror(SENDMAIL); 439579Sroot exit(EX_UNAVAILABLE); 440579Sroot } 441579Sroot 442579Sroot truename[0] = 0; 443579Sroot line[0] = '\0'; 444579Sroot 445579Sroot /* 446579Sroot * When we fall out of this, argv[1] should be first name, 447579Sroot * argc should be number of names + 1. 448579Sroot */ 449579Sroot 450579Sroot while (argc > 1 && *argv[1] == '-') { 451579Sroot cp = *++argv; 452579Sroot argc--; 453579Sroot switch (cp[1]) { 454579Sroot case 'r': 455*16731Sralph if (argc <= 1) 456579Sroot usage(); 45715346Skarels gaver++; 45815346Skarels strcpy(truename, argv[1]); 45915346Skarels fgets(line, LSIZE, stdin); 46015346Skarels if (strcmpn("From", line, 4) == 0) 46115346Skarels line[0] = '\0'; 462579Sroot argv++; 463579Sroot argc--; 464579Sroot break; 465579Sroot 466579Sroot case 'h': 467*16731Sralph if (argc <= 1) 468579Sroot usage(); 469579Sroot hseqno = atoi(argv[1]); 470579Sroot argv++; 471579Sroot argc--; 472579Sroot break; 473579Sroot 474579Sroot case 'd': 475579Sroot break; 476579Sroot 477579Sroot default: 478579Sroot usage(); 479579Sroot } 480579Sroot } 481*16731Sralph if (argc <= 1) 482579Sroot usage(); 483579Sroot if (gaver == 0) 484579Sroot strcpy(truename, my_name); 485579Sroot time(&iop); 486579Sroot fprintf(tmpf, "%s%s %s", from, truename, ctime(&iop)); 487579Sroot iop = ftell(tmpf); 488*16731Sralph flgf = first = 1; 489*16731Sralph for (;;) { 490*16731Sralph if (first) { 491*16731Sralph first = 0; 492*16731Sralph if (*line == '\0' && fgets(line, LSIZE, stdin) == NULL) 493*16731Sralph break; 494*16731Sralph } else { 495*16731Sralph if (fgets(line, LSIZE, stdin) == NULL) 496*16731Sralph break; 497*16731Sralph } 498*16731Sralph if (*line == '.' && line[1] == '\n' && isatty(fileno(stdin))) 499579Sroot break; 500579Sroot if (isfrom(line)) 501*16731Sralph putc('>', tmpf); 502579Sroot fputs(line, tmpf); 503579Sroot flgf = 0; 504579Sroot } 505*16731Sralph putc('\n', tmpf); 506579Sroot nlet = 1; 507579Sroot let[0].adr = 0; 508579Sroot let[1].adr = ftell(tmpf); 509579Sroot if (flgf) 510579Sroot return; 511*16731Sralph while (--argc > 0) 5126015Swnj if (!sendmail(0, *++argv, truename)) 513579Sroot error++; 51410644Seric if (error && safefile(dead)) { 515579Sroot setuid(getuid()); 516579Sroot malf = fopen(dead, "w"); 517579Sroot if (malf == NULL) { 518*16731Sralph printf("mail: cannot open %s\n", dead); 519579Sroot fclose(tmpf); 520579Sroot return; 521579Sroot } 522579Sroot copylet(0, malf, ZAP); 523579Sroot fclose(malf); 524*16731Sralph printf("Mail saved in %s\n", dead); 525579Sroot } 526579Sroot fclose(tmpf); 527579Sroot } 528579Sroot 529579Sroot sendrmt(n, name, rcmd) 530579Sroot char *name; 531579Sroot char *rcmd; 532579Sroot { 533579Sroot FILE *rmf, *popen(); 534579Sroot register char *p; 535579Sroot char rsys[64], cmd[64]; 536579Sroot register local, pid; 537579Sroot int sts; 538579Sroot 539579Sroot local = 0; 540579Sroot if (index(name, '^')) { 541579Sroot while (p = index(name, '^')) 542579Sroot *p = '!'; 543579Sroot if (strncmp(name, "researc", 7)) { 544579Sroot strcpy(rsys, "research"); 545579Sroot if (*name != '!') 546579Sroot --name; 547579Sroot goto skip; 548579Sroot } 549579Sroot } 550579Sroot if (*name=='!') 551579Sroot name++; 552579Sroot for(p=rsys; *name!='!'; *p++ = *name++) 553579Sroot if (*name=='\0') { 554579Sroot local++; 555579Sroot break; 556579Sroot } 557579Sroot *p = '\0'; 558579Sroot if ((!local && *name=='\0') || (local && *rsys=='\0')) { 559*16731Sralph printf("null name\n"); 560579Sroot return(0); 561579Sroot } 562579Sroot skip: 563579Sroot if ((pid = fork()) == -1) { 564579Sroot fprintf(stderr, "mail: can't create proc for remote\n"); 565579Sroot return(0); 566579Sroot } 567579Sroot if (pid) { 568579Sroot while (wait(&sts) != pid) { 569579Sroot if (wait(&sts)==-1) 570579Sroot return(0); 571579Sroot } 572579Sroot return(!sts); 573579Sroot } 574579Sroot setuid(getuid()); 575579Sroot if (local) 576579Sroot sprintf(cmd, "%s %s", rcmd, rsys); 577579Sroot else { 578579Sroot if (index(name+1, '!')) 579579Sroot sprintf(cmd, "uux - %s!rmail \\(%s\\)", rsys, name+1); 580579Sroot else 581579Sroot sprintf(cmd, "uux - %s!rmail %s", rsys, name+1); 582579Sroot } 583579Sroot if ((rmf=popen(cmd, "w")) == NULL) 584579Sroot exit(1); 585579Sroot copylet(n, rmf, local ? !strcmp(rcmd, "/bin/mail") ? FORWARD : ORDINARY : REMOTE); 58610783Seric exit(pclose(rmf) != 0); 587579Sroot } 588579Sroot 589579Sroot usage() 590579Sroot { 591579Sroot 592579Sroot fprintf(stderr, "Usage: mail [ -f ] people . . .\n"); 59315299Skarels error = EX_USAGE; 594*16731Sralph done(); 595579Sroot } 596579Sroot 5976015Swnj #include <sys/socket.h> 5989226Ssam #include <netinet/in.h> 59910227Ssam #include <netdb.h> 6006015Swnj 601*16731Sralph notifybiff(msg) 602*16731Sralph char *msg; 603*16731Sralph { 604*16731Sralph static struct sockaddr_in addr; 605*16731Sralph static int f = -1; 606*16731Sralph 607*16731Sralph if (addr.sin_family == 0) { 608*16731Sralph struct hostent *hp = gethostbyname("localhost"); 609*16731Sralph struct servent *sp = getservbyname("biff", "udp"); 610*16731Sralph 611*16731Sralph if (hp && sp) { 612*16731Sralph addr.sin_family = hp->h_addrtype; 613*16731Sralph bcopy(hp->h_addr, &addr.sin_addr, hp->h_length); 614*16731Sralph addr.sin_port = sp->s_port; 615*16731Sralph } 616*16731Sralph } 617*16731Sralph if (addr.sin_family) { 618*16731Sralph if (f < 0) 619*16731Sralph f = socket(AF_INET, SOCK_DGRAM, 0); 620*16731Sralph sendto(f, msg, strlen(msg)+1, 0, &addr, sizeof (addr)); 621*16731Sralph } 622*16731Sralph } 623*16731Sralph 6246015Swnj sendmail(n, name, fromaddr) 625*16731Sralph int n; 626*16731Sralph char *name, *fromaddr; 627579Sroot { 628*16731Sralph char file[256]; 629*16731Sralph int mask, fd; 630*16731Sralph struct passwd *pw; 631*16731Sralph #ifdef notdef 632579Sroot struct stat statb; 633*16731Sralph #endif 6343666Swnj char buf[128]; 635579Sroot 636*16731Sralph if (any(name, "!^")) 637*16731Sralph return (sendrmt(n, name, 0)); 638579Sroot if ((pw = getpwnam(name)) == NULL) { 639*16731Sralph printf("mail: can't send to %s\n", name); 640579Sroot return(0); 641579Sroot } 642579Sroot cat(file, maildir, name); 643*16731Sralph #ifdef notdef 644579Sroot if (stat(file, &statb) >= 0 && (statb.st_mode & S_IFMT) == S_IFDIR) { 645579Sroot strcat(file, "/"); 646579Sroot strcat(file, name); 647579Sroot } 648*16731Sralph #endif 64910644Seric if (!safefile(file)) 6504458Sroot return(0); 651*16731Sralph fd = open(file, O_WRONLY | O_CREAT, MAILMODE); 652*16731Sralph if (fd >= 0) { 653*16731Sralph flock(fd, LOCK_EX); 654*16731Sralph malf = fdopen(fd, "a"); 655*16731Sralph } 656*16731Sralph if (fd < 0 || malf == NULL) { 657*16731Sralph close(fd); 658*16731Sralph printf("mail: %s: cannot append\n", file); 659579Sroot return(0); 660579Sroot } 661*16731Sralph fchown(fd, pw->pw_uid, pw->pw_gid); 662*16731Sralph sprintf(buf, "%s@%d\n", name, ftell(malf)); 663579Sroot copylet(n, malf, ORDINARY); 6646015Swnj fclose(malf); 665*16731Sralph notifybiff(buf); 666579Sroot return(1); 667579Sroot } 668579Sroot 669*16731Sralph delex(i) 670579Sroot { 671*16731Sralph setsig(i, delex); 672*16731Sralph putc('\n', stderr); 673*16731Sralph if (delflg) 674579Sroot longjmp(sjbuf, 1); 675579Sroot done(); 676579Sroot } 677579Sroot 678*16731Sralph done() 679579Sroot { 680579Sroot 681579Sroot unlink(lettmp); 682579Sroot exit(error); 683579Sroot } 684579Sroot 685579Sroot cat(to, from1, from2) 686*16731Sralph char *to, *from1, *from2; 687579Sroot { 688*16731Sralph register char *cp, *dp; 689579Sroot 690*16731Sralph cp = to; 691*16731Sralph for (dp = from1; *cp = *dp++; cp++) 692*16731Sralph ; 693*16731Sralph for (dp = from2; *cp++ = *dp++; ) 694*16731Sralph ; 695579Sroot } 696579Sroot 697*16731Sralph /* copy p... into s, update p */ 698*16731Sralph char * 699*16731Sralph getarg(s, p) 700*16731Sralph register char *s, *p; 701579Sroot { 702579Sroot while (*p == ' ' || *p == '\t') 703579Sroot p++; 704579Sroot if (*p == '\n' || *p == '\0') 705579Sroot return(NULL); 706579Sroot while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') 707579Sroot *s++ = *p++; 708579Sroot *s = '\0'; 709579Sroot return(p); 710579Sroot } 71110644Seric 71210644Seric safefile(f) 71310644Seric char *f; 71410644Seric { 71510644Seric struct stat statb; 71610644Seric 71710644Seric if (lstat(f, &statb) < 0) 71810644Seric return (1); 71910644Seric if (statb.st_nlink != 1 || (statb.st_mode & S_IFMT) == S_IFLNK) { 720*16731Sralph fprintf(stderr, 721*16731Sralph "mail: %s has more than one link or is a symbolic link\n", 722*16731Sralph f); 72310644Seric return (0); 72410644Seric } 72510644Seric return (1); 72610644Seric } 727*16731Sralph 728*16731Sralph panic(msg, a1, a2, a3) 729*16731Sralph char *msg; 730*16731Sralph { 731*16731Sralph 732*16731Sralph fprintf(stderr, "mail: "); 733*16731Sralph fprintf(stderr, msg, a1, a2, a3); 734*16731Sralph fprintf(stderr, "\n"); 735*16731Sralph done(); 736*16731Sralph } 737