1579Sroot #include <ctype.h> 2579Sroot #include <stdio.h> 3579Sroot #include <pwd.h> 4579Sroot #include <utmp.h> 5579Sroot #include <signal.h> 6579Sroot #include <sys/types.h> 7579Sroot #include <sys/stat.h> 8579Sroot #include <setjmp.h> 9579Sroot #include <whoami.h> 10579Sroot #include <sysexits.h> 11579Sroot 12*580Seric static char SccsId[] = "@(#)mail.local.c 1.2 08/04/80"; 13*580Seric 14579Sroot #define DELIVERMAIL "/etc/delivermail" 15579Sroot 16579Sroot 17579Sroot /*copylet flags */ 18579Sroot /*remote mail, add rmtmsg */ 19579Sroot #define REMOTE 1 20579Sroot /* zap header and trailing empty line */ 21579Sroot #define ZAP 3 22579Sroot #define ORDINARY 2 23579Sroot #define FORWARD 4 24579Sroot #define LSIZE 256 25579Sroot #define MAXLET 300 /* maximum number of letters */ 26579Sroot #define MAILMODE (~0644) /* mode of created mail */ 27*580Seric # ifndef DELIVERMAIL 28579Sroot #define RMAIL "/usr/net/bin/sendberkmail" 29579Sroot #define LOCNAM1 "csvax" 30579Sroot #define LOCNAM2 "ucbvax" 31579Sroot #define LOCNAM3 "vax" 32579Sroot #define LOCNAM4 "v" 33*580Seric # endif 34579Sroot 35579Sroot char line[LSIZE]; 36579Sroot char resp[LSIZE]; 37579Sroot struct let { 38579Sroot long adr; 39579Sroot char change; 40579Sroot } let[MAXLET]; 41579Sroot int nlet = 0; 42579Sroot char lfil[50]; 43579Sroot long iop, time(); 44579Sroot char *getenv(); 45579Sroot char *index(); 46579Sroot char lettmp[] = "/tmp/maXXXXX"; 47579Sroot char maildir[] = "/usr/spool/mail/"; 48579Sroot char mailfile[] = "/usr/spool/mail/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; 49579Sroot char dead[] = "dead.letter"; 50579Sroot char *thissys = sysname; 51579Sroot char *netname = "vax"; 52579Sroot char forwmsg[] = " forwarded\n"; 53579Sroot FILE *tmpf; 54579Sroot FILE *malf; 55579Sroot char *my_name; 56579Sroot char *getlogin(); 57579Sroot struct passwd *getpwuid(); 58579Sroot int error; 59579Sroot int changed; 60579Sroot int forward; 61579Sroot char from[] = "From "; 62579Sroot long ftell(); 63579Sroot int delete(); 64579Sroot char *ctime(); 65579Sroot int flgf; 66579Sroot int flgp; 67579Sroot int delflg = 1; 68579Sroot int hseqno; 69579Sroot jmp_buf sjbuf; 70579Sroot int rmail; 71579Sroot 72579Sroot main(argc, argv) 73579Sroot char **argv; 74579Sroot { 75579Sroot register i; 76579Sroot char sobuf[BUFSIZ]; 77579Sroot 78579Sroot setbuf(stdout, sobuf); 79579Sroot mktemp(lettmp); 80579Sroot unlink(lettmp); 81579Sroot my_name = getlogin(); 82579Sroot if (my_name == NULL || strlen(my_name) == 0) { 83579Sroot struct passwd *pwent; 84579Sroot pwent = getpwuid(getuid()); 85579Sroot if (pwent==NULL) 86579Sroot my_name = "???"; 87579Sroot else 88579Sroot my_name = pwent->pw_name; 89579Sroot } 90579Sroot if(setjmp(sjbuf)) done(); 91579Sroot for (i=0; i<20; i++) 92579Sroot setsig(i, delete); 93579Sroot tmpf = fopen(lettmp, "w"); 94579Sroot if (tmpf == NULL) { 95579Sroot fprintf(stderr, "mail: cannot open %s for writing\n", lettmp); 96579Sroot done(); 97579Sroot } 98579Sroot if (argv[0][0] == 'r') 99579Sroot rmail++; 100579Sroot if (argv[0][0] != 'r' && /* no favors for rmail*/ 101579Sroot (argc == 1 || argv[1][0] == '-' && !any(argv[1][1], "rhd"))) 102579Sroot printmail(argc, argv); 103579Sroot else 104579Sroot sendmail(argc, argv); 105579Sroot done(); 106579Sroot } 107579Sroot 108579Sroot setsig(i, f) 109579Sroot int i; 110579Sroot int (*f)(); 111579Sroot { 112579Sroot if(signal(i, SIG_IGN)!=SIG_IGN) 113579Sroot signal(i, f); 114579Sroot } 115579Sroot 116579Sroot any(c, str) 117579Sroot register int c; 118579Sroot register char *str; 119579Sroot { 120579Sroot 121579Sroot while (*str) 122579Sroot if (c == *str++) 123579Sroot return(1); 124579Sroot return(0); 125579Sroot } 126579Sroot 127579Sroot printmail(argc, argv) 128579Sroot char **argv; 129579Sroot { 130579Sroot int flg, i, j, print; 131579Sroot char *p, *getarg(); 132579Sroot struct stat statb; 133579Sroot 134579Sroot setuid(getuid()); 135579Sroot cat(mailfile, maildir, my_name); 136579Sroot if (stat(mailfile, &statb) >= 0 137579Sroot && (statb.st_mode & S_IFMT) == S_IFDIR) { 138579Sroot strcat(mailfile, "/"); 139579Sroot strcat(mailfile, my_name); 140579Sroot } 141579Sroot for (; argc>1; argv++, argc--) { 142579Sroot if (argv[1][0]=='-') { 143579Sroot if (argv[1][1]=='q') 144579Sroot delflg = 0; 145579Sroot else if (argv[1][1]=='p') { 146579Sroot flgp++; 147579Sroot delflg = 0; 148579Sroot } else if (argv[1][1]=='f') { 149579Sroot if (argc>=3) { 150579Sroot strcpy(mailfile, argv[2]); 151579Sroot argv++; 152579Sroot argc--; 153579Sroot } 154579Sroot } else if (argv[1][1]=='r') { 155579Sroot forward = 1; 156579Sroot } else if (argv[1][1]=='h') { 157579Sroot forward = 1; 158579Sroot } else { 159579Sroot fprintf(stderr, "mail: unknown option %c\n", argv[1][1]); 160579Sroot done(); 161579Sroot } 162579Sroot } else 163579Sroot break; 164579Sroot } 165579Sroot malf = fopen(mailfile, "r"); 166579Sroot if (malf == NULL) { 167579Sroot fprintf(stdout, "No mail.\n"); 168579Sroot return; 169579Sroot } 170579Sroot lock(mailfile); 171579Sroot copymt(malf, tmpf); 172579Sroot fclose(malf); 173579Sroot fclose(tmpf); 174579Sroot unlock(); 175579Sroot tmpf = fopen(lettmp, "r"); 176579Sroot 177579Sroot changed = 0; 178579Sroot print = 1; 179579Sroot for (i = 0; i < nlet; ) { 180579Sroot j = forward ? i : nlet - i - 1; 181579Sroot if(setjmp(sjbuf)) { 182579Sroot print=0; 183579Sroot } else { 184579Sroot if (print) 185579Sroot copylet(j, stdout, ORDINARY); 186579Sroot print = 1; 187579Sroot } 188579Sroot if (flgp) { 189579Sroot i++; 190579Sroot continue; 191579Sroot } 192579Sroot setjmp(sjbuf); 193579Sroot fprintf(stdout, "? "); 194579Sroot fflush(stdout); 195579Sroot if (fgets(resp, LSIZE, stdin) == NULL) 196579Sroot break; 197579Sroot switch (resp[0]) { 198579Sroot 199579Sroot default: 200579Sroot fprintf(stderr, "usage\n"); 201579Sroot case '?': 202579Sroot print = 0; 203579Sroot fprintf(stderr, "q\tquit\n"); 204579Sroot fprintf(stderr, "x\texit without changing mail\n"); 205579Sroot fprintf(stderr, "p\tprint\n"); 206579Sroot fprintf(stderr, "s[file]\tsave (default mbox)\n"); 207579Sroot fprintf(stderr, "w[file]\tsame without header\n"); 208579Sroot fprintf(stderr, "-\tprint previous\n"); 209579Sroot fprintf(stderr, "d\tdelete\n"); 210579Sroot fprintf(stderr, "+\tnext (no delete)\n"); 211579Sroot fprintf(stderr, "m user\tmail to user\n"); 212579Sroot fprintf(stderr, "! cmd\texecute cmd\n"); 213579Sroot break; 214579Sroot 215579Sroot case '+': 216579Sroot case 'n': 217579Sroot case '\n': 218579Sroot i++; 219579Sroot break; 220579Sroot case 'x': 221579Sroot changed = 0; 222579Sroot case 'q': 223579Sroot goto donep; 224579Sroot case 'p': 225579Sroot break; 226579Sroot case '^': 227579Sroot case '-': 228579Sroot if (--i < 0) 229579Sroot i = 0; 230579Sroot break; 231579Sroot case 'y': 232579Sroot case 'w': 233579Sroot case 's': 234579Sroot flg = 0; 235579Sroot if (resp[1] != '\n' && resp[1] != ' ') { 236579Sroot printf("illegal\n"); 237579Sroot flg++; 238579Sroot print = 0; 239579Sroot continue; 240579Sroot } 241579Sroot if (resp[1] == '\n' || resp[1] == '\0') { 242579Sroot p = getenv("HOME"); 243579Sroot if(p != 0) 244579Sroot cat(resp+1, p, "/mbox"); 245579Sroot else 246579Sroot cat(resp+1, "", "mbox"); 247579Sroot } 248579Sroot for (p = resp+1; (p = getarg(lfil, p)) != NULL; ) { 249579Sroot malf = fopen(lfil, "a"); 250579Sroot if (malf == NULL) { 251579Sroot fprintf(stdout, "mail: cannot append to %s\n", lfil); 252579Sroot flg++; 253579Sroot continue; 254579Sroot } 255579Sroot copylet(j, malf, resp[0]=='w'? ZAP: ORDINARY); 256579Sroot fclose(malf); 257579Sroot } 258579Sroot if (flg) 259579Sroot print = 0; 260579Sroot else { 261579Sroot let[j].change = 'd'; 262579Sroot changed++; 263579Sroot i++; 264579Sroot } 265579Sroot break; 266579Sroot case 'm': 267579Sroot flg = 0; 268579Sroot if (resp[1] == '\n' || resp[1] == '\0') { 269579Sroot i++; 270579Sroot continue; 271579Sroot } 272579Sroot if (resp[1] != ' ') { 273579Sroot printf("invalid command\n"); 274579Sroot flg++; 275579Sroot print = 0; 276579Sroot continue; 277579Sroot } 278579Sroot for (p = resp+1; (p = getarg(lfil, p)) != NULL; ) 279579Sroot if (!sendrmt(j, lfil, "/bin/mail")) /* couldn't send it */ 280579Sroot flg++; 281579Sroot if (flg) 282579Sroot print = 0; 283579Sroot else { 284579Sroot let[j].change = 'd'; 285579Sroot changed++; 286579Sroot i++; 287579Sroot } 288579Sroot break; 289579Sroot case '!': 290579Sroot system(resp+1); 291579Sroot printf("!\n"); 292579Sroot print = 0; 293579Sroot break; 294579Sroot case 'd': 295579Sroot let[j].change = 'd'; 296579Sroot changed++; 297579Sroot i++; 298579Sroot if (resp[1] == 'q') 299579Sroot goto donep; 300579Sroot break; 301579Sroot } 302579Sroot } 303579Sroot donep: 304579Sroot if (changed) 305579Sroot copyback(); 306579Sroot } 307579Sroot 308579Sroot copyback() /* copy temp or whatever back to /usr/spool/mail */ 309579Sroot { 310579Sroot register i, n, c; 311579Sroot int new = 0; 312579Sroot struct stat stbuf; 313579Sroot 314579Sroot signal(SIGINT, SIG_IGN); 315579Sroot signal(SIGHUP, SIG_IGN); 316579Sroot signal(SIGQUIT, SIG_IGN); 317579Sroot lock(mailfile); 318579Sroot stat(mailfile, &stbuf); 319579Sroot if (stbuf.st_size != let[nlet].adr) { /* new mail has arrived */ 320579Sroot malf = fopen(mailfile, "r"); 321579Sroot if (malf == NULL) { 322579Sroot fprintf(stdout, "mail: can't re-read %s\n", mailfile); 323579Sroot done(); 324579Sroot } 325579Sroot fseek(malf, let[nlet].adr, 0); 326579Sroot fclose(tmpf); 327579Sroot tmpf = fopen(lettmp, "a"); 328579Sroot fseek(tmpf, let[nlet].adr, 0); 329579Sroot while ((c = fgetc(malf)) != EOF) 330579Sroot fputc(c, tmpf); 331579Sroot fclose(malf); 332579Sroot fclose(tmpf); 333579Sroot tmpf = fopen(lettmp, "r"); 334579Sroot let[++nlet].adr = stbuf.st_size; 335579Sroot new = 1; 336579Sroot } 337579Sroot malf = fopen(mailfile, "w"); 338579Sroot if (malf == NULL) { 339579Sroot fprintf(stderr, "mail: can't rewrite %s\n", lfil); 340579Sroot done(); 341579Sroot } 342579Sroot n = 0; 343579Sroot for (i = 0; i < nlet; i++) 344579Sroot if (let[i].change != 'd') { 345579Sroot copylet(i, malf, ORDINARY); 346579Sroot n++; 347579Sroot } 348579Sroot fclose(malf); 349579Sroot if (new) 350579Sroot fprintf(stdout, "new mail arrived\n"); 351579Sroot unlock(); 352579Sroot } 353579Sroot 354579Sroot copymt(f1, f2) /* copy mail (f1) to temp (f2) */ 355579Sroot FILE *f1, *f2; 356579Sroot { 357579Sroot long nextadr; 358579Sroot 359579Sroot nlet = nextadr = 0; 360579Sroot let[0].adr = 0; 361579Sroot while (fgets(line, LSIZE, f1) != NULL) { 362579Sroot if (isfrom(line)) 363579Sroot let[nlet++].adr = nextadr; 364579Sroot nextadr += strlen(line); 365579Sroot fputs(line, f2); 366579Sroot } 367579Sroot let[nlet].adr = nextadr; /* last plus 1 */ 368579Sroot } 369579Sroot 370579Sroot copylet(n, f, type) FILE *f; 371579Sroot { int ch, k; 372579Sroot fseek(tmpf, let[n].adr, 0); 373579Sroot k = let[n+1].adr - let[n].adr; 374579Sroot while(k-- > 1 && (ch=fgetc(tmpf))!='\n') 375579Sroot if(type!=ZAP) fputc(ch,f); 376579Sroot if(type==REMOTE) 377579Sroot fprintf(f, " remote from %s\n", thissys); 378579Sroot else if (type==FORWARD) 379579Sroot fprintf(f, forwmsg); 380579Sroot else if(type==ORDINARY) 381579Sroot fputc(ch,f); 382579Sroot while(k-->1) 383579Sroot fputc(ch=fgetc(tmpf), f); 384579Sroot if(type!=ZAP || ch!= '\n') 385579Sroot fputc(fgetc(tmpf), f); 386579Sroot } 387579Sroot 388579Sroot isfrom(lp) 389579Sroot register char *lp; 390579Sroot { 391579Sroot register char *p; 392579Sroot 393579Sroot for (p = from; *p; ) 394579Sroot if (*lp++ != *p++) 395579Sroot return(0); 396579Sroot return(1); 397579Sroot } 398579Sroot 399579Sroot sendmail(argc, argv) 400579Sroot char **argv; 401579Sroot { 402579Sroot char truename[100]; 403579Sroot int first; 404579Sroot register char *cp; 405579Sroot int gaver = 0; 406579Sroot # ifdef DELIVERMAIL 407579Sroot char *newargv[1000]; 408579Sroot register char **ap; 409579Sroot register char **vp; 410579Sroot int dflag; 411579Sroot 412579Sroot dflag = 0; 413579Sroot if (argc < 1) 414579Sroot fprintf(stderr, "puke\n"); 415579Sroot for (vp = argv, ap = newargv + 1; (*ap = *vp++) != 0; ap++) 416579Sroot { 417579Sroot if (ap[0][0] == '-' && ap[0][1] == 'd') 418579Sroot dflag++; 419579Sroot } 420579Sroot if (!dflag) 421579Sroot { 422579Sroot /* give it to delivermail, rah rah! */ 423579Sroot unlink(lettmp); 424579Sroot ap = newargv+1; 425579Sroot if (rmail) 426579Sroot *ap-- = "-s"; 427579Sroot *ap = "-delivermail"; 428579Sroot execv(DELIVERMAIL, ap); 429579Sroot perror(DELIVERMAIL); 430579Sroot exit(EX_UNAVAILABLE); 431579Sroot } 432579Sroot # endif DELIVERMAIL 433579Sroot 434579Sroot truename[0] = 0; 435579Sroot line[0] = '\0'; 436579Sroot 437579Sroot /* 438579Sroot * When we fall out of this, argv[1] should be first name, 439579Sroot * argc should be number of names + 1. 440579Sroot */ 441579Sroot 442579Sroot while (argc > 1 && *argv[1] == '-') { 443579Sroot cp = *++argv; 444579Sroot argc--; 445579Sroot switch (cp[1]) { 446579Sroot case 'r': 447579Sroot if (argc <= 0) { 448579Sroot usage(); 449579Sroot done(); 450579Sroot } 451579Sroot gaver++; 452579Sroot strcpy(truename, argv[1]); 453579Sroot fgets(line, LSIZE, stdin); 454579Sroot if (strcmpn("From", line, 4) == 0) 455579Sroot line[0] = '\0'; 456579Sroot argv++; 457579Sroot argc--; 458579Sroot break; 459579Sroot 460579Sroot case 'h': 461579Sroot if (argc <= 0) { 462579Sroot usage(); 463579Sroot done(); 464579Sroot } 465579Sroot hseqno = atoi(argv[1]); 466579Sroot argv++; 467579Sroot argc--; 468579Sroot break; 469579Sroot 470579Sroot # ifdef DELIVERMAIL 471579Sroot case 'd': 472579Sroot break; 473579Sroot # endif DELIVERMAIL 474579Sroot 475579Sroot default: 476579Sroot usage(); 477579Sroot done(); 478579Sroot } 479579Sroot } 480579Sroot if (argc <= 1) { 481579Sroot usage(); 482579Sroot done(); 483579Sroot } 484579Sroot if (gaver == 0) 485579Sroot strcpy(truename, my_name); 486579Sroot /* 487579Sroot if (argc > 4 && strcmp(argv[1], "-r") == 0) { 488579Sroot strcpy(truename, argv[2]); 489579Sroot argc -= 2; 490579Sroot argv += 2; 491579Sroot fgets(line, LSIZE, stdin); 492579Sroot if (strcmpn("From", line, 4) == 0) 493579Sroot line[0] = '\0'; 494579Sroot } else 495579Sroot strcpy(truename, my_name); 496579Sroot */ 497579Sroot time(&iop); 498579Sroot fprintf(tmpf, "%s%s %s", from, truename, ctime(&iop)); 499579Sroot iop = ftell(tmpf); 500579Sroot flgf = 1; 501579Sroot for (first = 1;; first = 0) { 502579Sroot if (first && line[0] == '\0' && fgets(line, LSIZE, stdin) == NULL) 503579Sroot break; 504579Sroot if (!first && fgets(line, LSIZE, stdin) == NULL) 505579Sroot break; 506579Sroot if (line[0] == '.' && line[1] == '\n' && isatty(fileno(stdin))) 507579Sroot break; 508579Sroot if (isfrom(line)) 509579Sroot fputs(">", tmpf); 510579Sroot fputs(line, tmpf); 511579Sroot flgf = 0; 512579Sroot } 513579Sroot fputs("\n", tmpf); 514579Sroot nlet = 1; 515579Sroot let[0].adr = 0; 516579Sroot let[1].adr = ftell(tmpf); 517579Sroot fclose(tmpf); 518579Sroot if (flgf) 519579Sroot return; 520579Sroot tmpf = fopen(lettmp, "r"); 521579Sroot if (tmpf == NULL) { 522579Sroot fprintf(stderr, "mail: cannot reopen %s for reading\n", lettmp); 523579Sroot return; 524579Sroot } 525579Sroot while (--argc > 0) 526579Sroot if (!send(0, *++argv, truename)) 527579Sroot error++; 528579Sroot if (error) { 529579Sroot setuid(getuid()); 530579Sroot malf = fopen(dead, "w"); 531579Sroot if (malf == NULL) { 532579Sroot fprintf(stdout, "mail: cannot open %s\n", dead); 533579Sroot fclose(tmpf); 534579Sroot return; 535579Sroot } 536579Sroot copylet(0, malf, ZAP); 537579Sroot fclose(malf); 538579Sroot fprintf(stdout, "Mail saved in %s\n", dead); 539579Sroot } 540579Sroot fclose(tmpf); 541579Sroot } 542579Sroot 543579Sroot sendrmt(n, name, rcmd) 544579Sroot char *name; 545579Sroot char *rcmd; 546579Sroot { 547579Sroot FILE *rmf, *popen(); 548579Sroot register char *p; 549579Sroot char rsys[64], cmd[64]; 550579Sroot register local, pid; 551579Sroot int sts; 552579Sroot 553579Sroot local = 0; 554579Sroot if (index(name, '^')) { 555579Sroot while (p = index(name, '^')) 556579Sroot *p = '!'; 557579Sroot if (strncmp(name, "researc", 7)) { 558579Sroot strcpy(rsys, "research"); 559579Sroot if (*name != '!') 560579Sroot --name; 561579Sroot goto skip; 562579Sroot } 563579Sroot } 564579Sroot if (*name=='!') 565579Sroot name++; 566579Sroot for(p=rsys; *name!='!'; *p++ = *name++) 567579Sroot if (*name=='\0') { 568579Sroot local++; 569579Sroot break; 570579Sroot } 571579Sroot *p = '\0'; 572579Sroot if ((!local && *name=='\0') || (local && *rsys=='\0')) { 573579Sroot fprintf(stdout, "null name\n"); 574579Sroot return(0); 575579Sroot } 576579Sroot skip: 577579Sroot if ((pid = fork()) == -1) { 578579Sroot fprintf(stderr, "mail: can't create proc for remote\n"); 579579Sroot return(0); 580579Sroot } 581579Sroot if (pid) { 582579Sroot while (wait(&sts) != pid) { 583579Sroot if (wait(&sts)==-1) 584579Sroot return(0); 585579Sroot } 586579Sroot return(!sts); 587579Sroot } 588579Sroot setuid(getuid()); 589579Sroot if (local) 590579Sroot sprintf(cmd, "%s %s", rcmd, rsys); 591579Sroot else { 592579Sroot if (index(name+1, '!')) 593579Sroot sprintf(cmd, "uux - %s!rmail \\(%s\\)", rsys, name+1); 594579Sroot else 595579Sroot sprintf(cmd, "uux - %s!rmail %s", rsys, name+1); 596579Sroot } 597579Sroot if ((rmf=popen(cmd, "w")) == NULL) 598579Sroot exit(1); 599579Sroot copylet(n, rmf, local ? !strcmp(rcmd, "/bin/mail") ? FORWARD : ORDINARY : REMOTE); 600579Sroot pclose(rmf); 601579Sroot exit(0); 602579Sroot } 603579Sroot 604*580Seric # ifndef DELIVERMAIL 605579Sroot /* 606579Sroot * Send mail on the Berkeley network. 607579Sroot * Sorry Bill, sendrmt() is so awful we just gave up. 608579Sroot */ 609579Sroot 610579Sroot sendberkmail(n, name, fromaddr) 611579Sroot char name[]; 612579Sroot char fromaddr[]; 613579Sroot { 614579Sroot char cmd[200]; 615579Sroot register FILE *cmdf; 616579Sroot 617579Sroot sprintf(cmd, "%s -h %d -f %s -t %s", RMAIL, hseqno, fromaddr, name); 618579Sroot if ((cmdf = popen(cmd, "w")) == NULL) { 619579Sroot perror(RMAIL); 620579Sroot return(0); 621579Sroot } 622579Sroot copylet(n, cmdf, ORDINARY); 623579Sroot pclose(cmdf); 624579Sroot return(9); 625579Sroot } 626*580Seric # endif 627579Sroot 628579Sroot usage() 629579Sroot { 630579Sroot 631579Sroot fprintf(stderr, "Usage: mail [ -f ] people . . .\n"); 632579Sroot } 633579Sroot 634579Sroot send(n, name, fromaddr) 635579Sroot int n; 636579Sroot char *name; 637579Sroot char *fromaddr; 638579Sroot { 639579Sroot char file[100]; 640579Sroot register char *p; 641579Sroot register mask; 642579Sroot struct passwd *pw, *getpwnam(); 643579Sroot struct stat statb; 644579Sroot 645*580Seric # ifndef DELIVERMAIL 646579Sroot stripfx(LOCNAM1, &name); 647579Sroot stripfx(LOCNAM2, &name); 648579Sroot stripfx(LOCNAM3, &name); 649579Sroot stripfx(LOCNAM4, &name); 650579Sroot if(*name == ':')name++; /* skip colon in to-name */ 651*580Seric for(p=name; *p!=':' && *p!='!' && *p!='^' &&*p!='\0'; p++); 652579Sroot /* if(*p == ':') return(sendrmt(n, name, RMAIL)); */ 653579Sroot if (*p == ':') 654579Sroot return(sendberkmail(n, name, fromaddr)); 655*580Seric else if (*p=='\0' && strcmp(name, "msgs") == 0) 656*580Seric return(sendrmt(n, "-s", "/usr/ucb/msgs")); 657*580Seric # endif 658579Sroot for(p=name; *p!='!'&&*p!='^' &&*p!='\0'; p++) 659579Sroot ; 660579Sroot if (*p == '!'|| *p=='^') 661579Sroot return(sendrmt(n, name, 0)); 662579Sroot if ((pw = getpwnam(name)) == NULL) { 663579Sroot fprintf(stdout, "mail: can't send to %s\n", name); 664579Sroot return(0); 665579Sroot } 666579Sroot cat(file, maildir, name); 667579Sroot if (stat(file, &statb) >= 0 && (statb.st_mode & S_IFMT) == S_IFDIR) { 668579Sroot strcat(file, "/"); 669579Sroot strcat(file, name); 670579Sroot } 671579Sroot mask = umask(MAILMODE); 672579Sroot malf = fopen(file, "a"); 673579Sroot umask(mask); 674579Sroot if (malf == NULL) { 675579Sroot fprintf(stdout, "mail: cannot append to %s\n", file); 676579Sroot return(0); 677579Sroot } 678579Sroot lock(file); 679579Sroot chown(file, pw->pw_uid, pw->pw_gid); 680579Sroot copylet(n, malf, ORDINARY); 681579Sroot fclose(malf); 682579Sroot unlock(); 683579Sroot return(1); 684579Sroot } 685579Sroot 686579Sroot delete(i) 687579Sroot { 688579Sroot setsig(i, delete); 689579Sroot fprintf(stderr, "\n"); 690579Sroot if(delflg) 691579Sroot longjmp(sjbuf, 1); 692579Sroot done(); 693579Sroot } 694579Sroot 695579Sroot /* 696579Sroot * Lock the specified mail file by setting the file mailfile.lock. 697579Sroot * We must, of course, be careful to unlink the lock file by a call 698579Sroot * to unlock before we stop. The algorithm used here is to see if 699579Sroot * the lock exists, and if it does, to check its modify time. If it 700579Sroot * is older than 30 seconds, we assume error and set our own file. 701579Sroot * Otherwise, we wait for 5 seconds and try again. 702579Sroot */ 703579Sroot 704579Sroot char *maillock = ".lock"; /* Lock suffix for mailname */ 705579Sroot char *lockname = "/usr/spool/mail/tmXXXXXX"; 706579Sroot char locktmp[30]; /* Usable lock temporary */ 707579Sroot char curlock[50]; /* Last used name of lock */ 708579Sroot int locked; /* To note that we locked it */ 709579Sroot 710579Sroot lock(file) 711579Sroot char *file; 712579Sroot { 713579Sroot register int f; 714579Sroot struct stat sbuf; 715579Sroot long curtime; 716579Sroot int statfailed; 717579Sroot 718579Sroot if (locked || flgf) 719579Sroot return(0); 720579Sroot strcpy(curlock, file); 721579Sroot strcat(curlock, maillock); 722579Sroot strcpy(locktmp, lockname); 723579Sroot mktemp(locktmp); 724579Sroot unlink(locktmp); 725579Sroot statfailed = 0; 726579Sroot for (;;) { 727579Sroot f = lock1(locktmp, curlock); 728579Sroot if (f == 0) { 729579Sroot locked = 1; 730579Sroot return(0); 731579Sroot } 732579Sroot if (stat(curlock, &sbuf) < 0) { 733579Sroot if (statfailed++ > 5) 734579Sroot return(-1); 735579Sroot sleep(5); 736579Sroot continue; 737579Sroot } 738579Sroot statfailed = 0; 739579Sroot time(&curtime); 740579Sroot if (curtime < sbuf.st_ctime + 30) { 741579Sroot sleep(5); 742579Sroot continue; 743579Sroot } 744579Sroot unlink(curlock); 745579Sroot } 746579Sroot } 747579Sroot 748579Sroot /* 749579Sroot * Remove the mail lock, and note that we no longer 750579Sroot * have it locked. 751579Sroot */ 752579Sroot 753579Sroot unlock() 754579Sroot { 755579Sroot 756579Sroot unlink(curlock); 757579Sroot locked = 0; 758579Sroot } 759579Sroot 760579Sroot /* 761579Sroot * Attempt to set the lock by creating the temporary file, 762579Sroot * then doing a link/unlink. If it fails, return -1 else 0 763579Sroot */ 764579Sroot 765579Sroot lock1(tempfile, name) 766579Sroot char tempfile[], name[]; 767579Sroot { 768579Sroot register int fd; 769579Sroot 770579Sroot fd = creat(tempfile, 0); 771579Sroot if (fd < 0) 772579Sroot return(-1); 773579Sroot close(fd); 774579Sroot if (link(tempfile, name) < 0) { 775579Sroot unlink(tempfile); 776579Sroot return(-1); 777579Sroot } 778579Sroot unlink(tempfile); 779579Sroot return(0); 780579Sroot } 781579Sroot 782579Sroot done() 783579Sroot { 784579Sroot if(locked) 785579Sroot unlock(); 786579Sroot unlink(lettmp); 787579Sroot unlink(locktmp); 788579Sroot exit(error); 789579Sroot } 790579Sroot 791579Sroot cat(to, from1, from2) 792579Sroot char *to, *from1, *from2; 793579Sroot { 794579Sroot int i, j; 795579Sroot 796579Sroot j = 0; 797579Sroot for (i=0; from1[i]; i++) 798579Sroot to[j++] = from1[i]; 799579Sroot for (i=0; from2[i]; i++) 800579Sroot to[j++] = from2[i]; 801579Sroot to[j] = 0; 802579Sroot } 803579Sroot 804579Sroot char *getarg(s, p) /* copy p... into s, update p */ 805579Sroot register char *s, *p; 806579Sroot { 807579Sroot while (*p == ' ' || *p == '\t') 808579Sroot p++; 809579Sroot if (*p == '\n' || *p == '\0') 810579Sroot return(NULL); 811579Sroot while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') 812579Sroot *s++ = *p++; 813579Sroot *s = '\0'; 814579Sroot return(p); 815579Sroot } 816*580Seric # ifndef DELIVERMAIL 817579Sroot /* 818579Sroot stripfx(prefix string, pointer to string) 819579Sroot 820579Sroot takes a ptr to string and compares it to prefix string. 821579Sroot may be called multiple times 822579Sroot */ 823579Sroot stripfx(pfx, name) 824579Sroot char *pfx; 825579Sroot char **name; 826579Sroot { 827579Sroot register char *cp = *name; 828579Sroot 829579Sroot while (*pfx && (*cp == *pfx || *cp == toupper(*pfx))) 830579Sroot cp++, pfx++; 831579Sroot if (*cp != ':' || *pfx != 0) 832579Sroot return; 833579Sroot *name = cp; 834579Sroot } 835*580Seric # endif 836