1*9983Seric static char sccsid[] = "@(#)v6mail.c 4.3 (Berkeley) 12/27/82"; 28208Smckusick 38208Smckusick /* 48208Smckusick * Version 6 Cory mail-- 58208Smckusick * a clean and simple mail program 68208Smckusick * machine and version independent 78208Smckusick * Eric Schmidt 88208Smckusick * must run as setuid root to chown the destination mailbox 98208Smckusick * if NOTROOT defined, doesn't need to run as root 108208Smckusick * 118208Smckusick * DON'T CHANGE THIS CODE 128208Smckusick * bitch to "csvax:schmidt" instead 138208Smckusick */ 148208Smckusick 158208Smckusick /* 168208Smckusick * mail command usage 178208Smckusick * mail [-yn] 188208Smckusick * prints your mail 198208Smckusick * mail people 208208Smckusick * sends standard input to people 218208Smckusick * 228208Smckusick * mail -r fromaddr people 238208Smckusick * sends mail from the network 248208Smckusick * 258208Smckusick * mail -d people 269981Seric * don't call sendmail, send mail directly 278208Smckusick * mail msgs 288208Smckusick * send to "msgs" 298208Smckusick * mail filename 308208Smckusick * mail to filename instead of user (must be at least one /) 318208Smckusick * mail -D 328208Smckusick * delete the invokers mailbox (more efficient than 338208Smckusick * mail -n >/dev/null) 348208Smckusick */ 358208Smckusick 368208Smckusick /* 378208Smckusick * bugs: 388208Smckusick * Ingres 11/70 multiple names/uid? 398208Smckusick * additions: 408208Smckusick * Save? type 'x' - doesn't unlink the mail file 418208Smckusick */ 428208Smckusick /* 438208Smckusick * BIFF is an immediate notification flag using the MPX stuff 448208Smckusick */ 458208Smckusick # include "local.h" 468208Smckusick # include <stdio.h> 478208Smckusick # include "mach.h" 488208Smckusick 498208Smckusick # ifdef RAND 508208Smckusick 518208Smckusick /* for all machines at RAND */ 528208Smckusick # define MAILMODE 0644 538208Smckusick 548208Smckusick # endif RAND 558208Smckusick 568208Smckusick # ifdef NOSC 578208Smckusick 588208Smckusick /* for all machines at NOSC */ 598208Smckusick # define MAILMODE 0644 608208Smckusick 618208Smckusick # endif NOSC 628208Smckusick 638208Smckusick # ifdef BERKELEY 648208Smckusick /* for Berkeley */ 658208Smckusick /* for each machine */ 668208Smckusick /* lump the CC machines into one */ 678208Smckusick # ifdef CCV7 688208Smckusick # define MAILMODE 0600 698208Smckusick # define MSGSCMD "/usr/ucb/bin/msgs" 708208Smckusick # endif 718208Smckusick 728208Smckusick # ifdef CCV6 738208Smckusick # define MSGSCMD "/usr/bin/eecs/msgs" 748208Smckusick # define MAILMODE 0600 758208Smckusick # endif 768208Smckusick 778208Smckusick # ifdef ING70 788208Smckusick # define MAILMODE 0666 798208Smckusick # define MSGSCMD "/usr/bin/msgs" 808208Smckusick # define NOTROOT 818208Smckusick # endif 828208Smckusick 838208Smckusick # ifdef INGVAX 848208Smckusick # define MAILMODE 0644 858208Smckusick # define MSGSCMD "/usr/ucb/msgs" 868208Smckusick # endif 878208Smckusick 888208Smckusick /* 898208Smckusick # ifdef VIRUS 908208Smckusick # define MAILMODE 0644 918208Smckusick # define MSGSCMD "/usr/bin/msgs" 928208Smckusick # endif 938208Smckusick */ 948208Smckusick 958208Smckusick # ifdef UCBVAX 968208Smckusick # define MAILMODE 0644 978208Smckusick # define MSGSCMD "/usr/ucb/msgs" 988208Smckusick # define BIFF 998208Smckusick # endif 1008208Smckusick 1018208Smckusick # ifdef IMAGE 1028208Smckusick # define MAILMODE 0644 1038208Smckusick # define MSGSCMD "/usr/bin/msgs" 1048208Smckusick # endif 1058208Smckusick 1068208Smckusick # ifdef KIM 1078208Smckusick # define MAILMODE 0644 1088208Smckusick # define MSGSCMD "/usr/ucb/msgs" 1098208Smckusick # endif 1108208Smckusick 1118208Smckusick # ifdef ESVAX 1128208Smckusick # define MAILMODE 0644 1138208Smckusick # define MSGSCMD "/usr/ucb/msgs" 1148208Smckusick # endif 1158208Smckusick 1168208Smckusick # ifdef Q 1178208Smckusick # define MAILMODE 0600 1188208Smckusick # define MSGSCMD "/usr/bin/eecs/msgs" 1198208Smckusick # endif 1208208Smckusick 1218208Smckusick # ifdef ARPAVAX 1228208Smckusick # define MAILMODE 0644 1238208Smckusick # define MSGSCMD "/usr/ucb/msgs" 1248208Smckusick # define BIFF 1258208Smckusick # endif 1268208Smckusick 1278208Smckusick # ifdef SRC 1288208Smckusick # define MAILMODE 0600 1298208Smckusick # define MSGSCMD "/usr/bin/msgs" 1308208Smckusick # endif 1318208Smckusick 1328208Smckusick # ifdef MATHSTAT 1338208Smckusick # define MAILMODE 0600 1348208Smckusick # define MSGSCMD "/usr/bin/msgs" 1358208Smckusick # endif 1368208Smckusick 1378208Smckusick # ifdef CSVAX 1388208Smckusick # define MAILMODE 0644 1398208Smckusick # define MSGSCMD "/usr/ucb/msgs" 1408208Smckusick # define BIFF 1418208Smckusick # endif 1428208Smckusick 1438208Smckusick # ifdef ONYX 1448208Smckusick # define MAILMODE 0644 1458208Smckusick # define MSGSCMD "/usr/ucb/bin/msgs" 1468208Smckusick # endif 1478208Smckusick 1488208Smckusick # ifdef CORY 1498208Smckusick # define MAILMODE 0600 1508208Smckusick # define MSGSCMD "/usr/bin/eecs/msgs" 1518208Smckusick # endif 1528208Smckusick 1538208Smckusick # ifdef EECS40 1548208Smckusick # define MAILMODE 0644 1558208Smckusick # define MSGSCMD "/usr/bin/msgs" 1568208Smckusick # endif 1578208Smckusick /* end of berkeley defsn */ 1588208Smckusick 1598208Smckusick # endif 1608208Smckusick /* end of per-machine ifdefs */ 1618208Smckusick 1628208Smckusick # ifdef USRMAIL 1638208Smckusick # define MAILDIR "/usr/mail" 1648208Smckusick # else 1658208Smckusick # define MAILDIR "/usr/spool/mail" 1668208Smckusick # endif 1678208Smckusick 1688208Smckusick char lettmp[] = "/tmp/MaXXXXX"; /* keep letter before sending it */ 1698208Smckusick char preptmp[] = "/tmp/mbXXXXX"; /* if prepending msg, use this file */ 1708208Smckusick int chew; /* if true, strip extra from lines */ 1719981Seric int dflag; /* if true, don't call sendmail */ 1728208Smckusick char shopcnt[30] = "0"; /* hop count parameter for rmt mail */ 1738208Smckusick int errs; /* no of errs in sending */ 1748208Smckusick char deleteonly; /* if true, just delete mailbox */ 1758208Smckusick char remname[50]; /* if non-empty, from line extra */ 1768208Smckusick 1778208Smckusick char _sobuf[BUFSIZ]; 1788208Smckusick main(argc, argv) 1798208Smckusick char **argv; 1808208Smckusick { 1818208Smckusick register int myuid; 1828208Smckusick int delexit(); 1838208Smckusick char namebuf[128], *sn = NULL, logindir[60]; 1848208Smckusick struct passwd *pwd; 1858208Smckusick 1868208Smckusick setbuf(stdout,_sobuf); 1878208Smckusick mktemp(lettmp); 1888208Smckusick mktemp(preptmp); 1898208Smckusick unlink(lettmp); 1908208Smckusick unlink(preptmp); 1918208Smckusick myuid = getuid(); 1928208Smckusick logindir[0] = 0; 1938208Smckusick sn = getlogin(); 1948208Smckusick if(sn == NULL || *sn == 0 || *sn == ' '){ 1958208Smckusick pwd = getpwuid(myuid); /* will read passwd file */ 1968208Smckusick if(pwd != NULL){ 1978208Smckusick sn = pwd->pw_name; 1988208Smckusick strcpy(logindir,pwd->pw_dir); 1998208Smckusick } 2008208Smckusick if(sn == NULL){ 2018208Smckusick fprintf(stderr,"Who are you?\n"); 2028208Smckusick delexit(EX_OSFILE); 2038208Smckusick } 2048208Smckusick } 2058208Smckusick strcpy(namebuf,sn); 2068208Smckusick if (argc < 2) 2078208Smckusick goto hitit; 2088208Smckusick for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) 2098208Smckusick switch(argv[0][1]) { 2108208Smckusick case 'y': 2118208Smckusick case 'n': 2128208Smckusick argc++, argv--; 2138208Smckusick hitit: 2148208Smckusick printmail(argc, argv, namebuf,logindir); 2158208Smckusick delexit(EX_OK); 2168208Smckusick 2178208Smckusick case 'r': /* one-arg -r-- -r addr */ 2188208Smckusick if (argc < 2) 2198208Smckusick continue; 2208208Smckusick /* ignore -r if not network or root */ 2218208Smckusick if (strcmp("network", namebuf) == 0 || myuid == 0 || 2228208Smckusick strcmp("uucp", namebuf) == 0 || index(argv[1], '!') != NULL) { 2238208Smckusick strcpy(namebuf,argv[1]); 2248208Smckusick chew++; /* eat From lines */ 2258208Smckusick } 2268208Smckusick else strcpy(remname, argv[1]); 2278208Smckusick argc--, argv++; 2288208Smckusick continue; 2298208Smckusick case 'h': /* hop count - used by network */ 2308208Smckusick if(argc < 2) continue; 2318208Smckusick strcpy(shopcnt,argv[1]); 2328208Smckusick argc--, argv++; 2338208Smckusick continue; 2348208Smckusick case 'd': /* really deliver this message */ 2358208Smckusick dflag++; 2368208Smckusick continue; 2378208Smckusick case 'D': /* only delete the invokers mailbox */ 2388208Smckusick deleteonly++; 2398208Smckusick goto hitit; /* delete mail box, thats all */ 2408208Smckusick } 2418208Smckusick /* if we are already ignoring signals, catch sigint */ 2428208Smckusick if(signal(SIGINT,SIG_IGN) != SIG_IGN) 2438208Smckusick signal(SIGINT, delexit); 2448208Smckusick argc++, argv--; 2458208Smckusick bulkmail(argc, argv, namebuf); 2468208Smckusick delexit(EX_OK); 2478208Smckusick } 2488208Smckusick 2498208Smckusick printmail(argc, argv, name, logindir) 2508208Smckusick char **argv; 2518208Smckusick char *name, *logindir; 2528208Smckusick { 2538208Smckusick register int c; 2548208Smckusick FILE *fdin; 2558208Smckusick char sfnmail[60], mbox[120]; 2568208Smckusick struct stat statbuf; 2578208Smckusick 2588208Smckusick # ifdef OLDMAIL 2598208Smckusick if(logindir[0] == 0){ 2608208Smckusick pwd = getpwuid(getuid()); 2618208Smckusick if(pwd == NULL){ 2628208Smckusick fprintf(stderr,"Can't get directory\n"); 2638208Smckusick exit(EX_OSFILE); 2648208Smckusick } 2658208Smckusick strcpy(logindir, pwd->pw_dir); 2668208Smckusick } 2678208Smckusick sprintf(sfnmail,"%s/.mail",logindir); 2688208Smckusick # else 2698208Smckusick sprintf(sfnmail,"%s/%s",MAILDIR,name); 2708208Smckusick # endif 2718208Smckusick if(deleteonly){ 2728208Smckusick remove(sfnmail); 2738208Smckusick return; 2748208Smckusick } 2758208Smckusick if (stat(sfnmail, &statbuf)>=0 && statbuf.st_nlink==1 && 2768208Smckusick getsize(&statbuf) > 0L && (fdin = fopen(sfnmail, "r")) != NULL){ 2778208Smckusick getput(fdin, stdout); 2788208Smckusick fclose(fdin); 2798208Smckusick fflush(stdout); 2808208Smckusick c = 'y'; 2818208Smckusick if (argc<2) { 2828208Smckusick if(isatty(0)){ 2838208Smckusick printf("Save(y-n) ?"); 2848208Smckusick fflush(stdout); 2858208Smckusick c = getchar(); 2868208Smckusick } 2878208Smckusick } else 2888208Smckusick c = argv[1][1]; 2898208Smckusick if (!any(c, "xyn")) 2908208Smckusick delexit(EX_OK); 2918208Smckusick if (c == 'y') { 2928208Smckusick sprintf(mbox,"%s/mbox",logindir); 2938208Smckusick if (accesss(mbox)) { 2948208Smckusick printf("Saved mail in 'mbox'\n"); 2958208Smckusick if(insert(sfnmail, mbox, getuid(),getgid())) 2968208Smckusick remove(sfnmail); 2978208Smckusick } 2988208Smckusick else printf("In wrong directory\n"); 2998208Smckusick } 3008208Smckusick else if(c != 'x') remove(sfnmail); 3018208Smckusick } else 3028208Smckusick printf("No mail.\n"); 3038208Smckusick } 3048208Smckusick 3058208Smckusick bulkmail(argc, argv, from) 3068208Smckusick char **argv, *from; 3078208Smckusick { 3088208Smckusick extern int errno; 3098208Smckusick char linebuf[BUFSIZ]; 3108208Smckusick char *getdate(); 3118208Smckusick FILE *fdout; 3128208Smckusick 3139981Seric # ifdef SENDMAIL 3148208Smckusick /* 3159981Seric ** Ship off to sendmail if appropriate (and possible) 3168208Smckusick */ 3178208Smckusick 3188208Smckusick if (!dflag) 3198208Smckusick { 3209981Seric argv[0] = "-sendmail"; 3218208Smckusick argv[argc] = 0; 3229981Seric execv("/usr/lib/sendmail", argv); 3238208Smckusick /* oops... better just deliver it. */ 3249981Seric fprintf(stderr, "Not using sendmail\n"); 3258208Smckusick errno = 0; 3268208Smckusick argv[argc] = (char *)-1; 3278208Smckusick } 3288208Smckusick # endif 3298208Smckusick 3308208Smckusick fdout = fopen(lettmp, "w"); 3318208Smckusick if (fdout == NULL) { 3328208Smckusick perror(lettmp); 3338208Smckusick delexit(EX_OSFILE); 3348208Smckusick } 3358208Smckusick /* 3368208Smckusick * If delivering mail from the network via mail -r, 3378208Smckusick * Strip the leading line and throw it away, as long 3388208Smckusick * as it begins with "From ..." (and preserve the date if poss.) 3398208Smckusick */ 3408208Smckusick if (chew) { 3418208Smckusick fgets(linebuf,BUFSIZ,stdin); 3428208Smckusick if(strncmp(linebuf,"From ",5) != 0){ 3438208Smckusick fline(fdout,NULL,from); 3448208Smckusick fprintf(fdout,"%s", linebuf); 3458208Smckusick } 3468208Smckusick else fline(fdout,getdate(linebuf),from); 3478208Smckusick } 3488208Smckusick else fline(fdout,NULL,from); 3498208Smckusick if(remname[0]) fprintf(fdout,"(from %s)\n",remname); 3508208Smckusick 3518208Smckusick /* on the image machine, promt with subj */ 3528208Smckusick if(getput(stdin,fdout) == 0) 3538208Smckusick delexit(EX_OSERR); 3548208Smckusick putc('\n',fdout); 3558208Smckusick fclose(fdout); 3568208Smckusick while (--argc > 0) 3578208Smckusick sendto(*++argv,from); 3588208Smckusick delexit(errs); 3598208Smckusick } 3608208Smckusick /* print from line, with date date, if date = NULL, compute it */ 3618208Smckusick fline(fdout,date,from) 3628208Smckusick FILE *fdout; 3638208Smckusick char *date; 3648208Smckusick char *from; 3658208Smckusick { 3668208Smckusick int tbuf[2]; 3678208Smckusick 3688208Smckusick if(date == NULL){ 3698208Smckusick time(tbuf); 3708208Smckusick date = ctime(tbuf); 3718208Smckusick } 3728208Smckusick fprintf(fdout,"From %s %s", from, date); 3738208Smckusick } 3748208Smckusick /* look over linebuf and return ptr to date, NULL if error */ 3758208Smckusick char *getdate(linebuf) 3768208Smckusick char *linebuf; 3778208Smckusick { 3788208Smckusick register char *s; 3798208Smckusick s = linebuf; 3808208Smckusick while(*s){ 3818208Smckusick if(strncmp(s," Sun ",5) == 0 3828208Smckusick || strncmp(s," Mon ",5) == 0 3838208Smckusick || strncmp(s," Tue ",5) == 0 3848208Smckusick || strncmp(s," Wed ",5) == 0 3858208Smckusick || strncmp(s," Thu ",5) == 0 3868208Smckusick || strncmp(s," Fri ",5) == 0 3878208Smckusick || strncmp(s," Sat ",5) == 0) 3888208Smckusick return(++s); 3898208Smckusick s++; 3908208Smckusick } 3918208Smckusick return(NULL); 3928208Smckusick } 3938208Smckusick 3948208Smckusick sendto(person, fromaddr) 3958208Smckusick char *person; 3968208Smckusick char *fromaddr; 3978208Smckusick { 3988208Smckusick static int saved = 0; 3998208Smckusick register int hisuid, hisgid; 4008208Smckusick char sfnmail[60], logindir[60]; 4018208Smckusick struct passwd *pwd; 4028208Smckusick 4038208Smckusick stripmach(&person); 4048208Smckusick if(person[0] == ':')person++; 4059981Seric /* sendmail provides these services */ 4068208Smckusick if(any(':',person) 4078208Smckusick # ifdef MSGSCMD 4088208Smckusick || strcmp(person,"msgs") == 0 4098208Smckusick # endif 4108208Smckusick ){ 4118208Smckusick int pid; 4128208Smckusick int pidchild; 4138208Smckusick 4148208Smckusick while((pid = fork()) == -1)sleep(2); 4158208Smckusick if (pid < 0) { 4168208Smckusick perror("fork"); 4178208Smckusick goto assback; 4188208Smckusick } 4198208Smckusick if (pid == 0) { 4208208Smckusick fclose(stdin); 4218208Smckusick freopen(lettmp,"r",stdin); 4228208Smckusick setuid(getuid()); /* insure no security hole*/ 4238208Smckusick if (strcmp(person,"msgs") != 0) { 4248208Smckusick /* 4258208Smckusick sendberkmail will add the machine, e.g. 4268208Smckusick CSVAX:schmidt, if the -f flag is not set 4278208Smckusick */ 4288208Smckusick execl("/usr/net/bin/sendberkmail", 4298208Smckusick "sendberkmail", "-t",person,"-h",shopcnt, 4308208Smckusick chew ? "-f" : 0,fromaddr,0); 4318208Smckusick perror("/usr/net/bin/sendberkmail"); 4328208Smckusick } 4338208Smckusick # ifdef MSGSCMD 4348208Smckusick else { 4358208Smckusick execl(MSGSCMD, "msgs", "-s", 0); 4368208Smckusick perror(MSGSCMD); 4378208Smckusick } 4388208Smckusick # endif 4398208Smckusick exit(EX_UNAVAILABLE); 4408208Smckusick } 4418208Smckusick for (;;) { 4428208Smckusick register int rcode = wait(&pidchild); 4438208Smckusick if (rcode == -1) 4448208Smckusick goto assback; 4458208Smckusick if (rcode == pid) 4468208Smckusick break; 4478208Smckusick } 4488208Smckusick if ((pidchild & 0377) != 0 || (pidchild >> 8) != 0) 4498208Smckusick goto assback; 4508208Smckusick return; 4518208Smckusick } 4528208Smckusick 4538208Smckusick if(!any('/',person)){ 4548208Smckusick /* if name has no / in it, we assume it is a user's name */ 4558208Smckusick # ifdef HPASSWD 4568208Smckusick hisuid = uidfromsn(person); 4578208Smckusick # else 4588208Smckusick pwd = getpwnam(person); 4598208Smckusick if(pwd != NULL){ 4608208Smckusick hisuid = guid(pwd->pw_uid,pwd->pw_gid); 4618208Smckusick hisgid = pwd->pw_gid; 4628208Smckusick strcpy(logindir,pwd->pw_dir); 4638208Smckusick } 4648208Smckusick else hisuid = -1; 4658208Smckusick # endif 4668208Smckusick if(hisuid == -1){ 4678208Smckusick assback: 4688208Smckusick fflush(stdout); 4698208Smckusick fprintf(stderr,"Can't send to %s.\n", person); 4708208Smckusick errs++; 4718208Smckusick if (isatty(0) && saved==0) { 4728208Smckusick saved++; 4738208Smckusick if (accesss("dead.letter")) { 4748208Smckusick printf("Letter saved in 'dead.letter'\n"); 4758208Smckusick insert(lettmp, "dead.letter", 4768208Smckusick getuid(),getgid()); 4778208Smckusick } else 4788208Smckusick printf("In wrong directory\n"); 4798208Smckusick } 4808208Smckusick return; 4818208Smckusick } 4828208Smckusick # ifdef OLDMAIL 4838208Smckusick sprintf(sfnmail,"%s/.mail",logindir); 4848208Smckusick # else 4858208Smckusick sprintf(sfnmail,"%s/%s",MAILDIR,person); 4868208Smckusick # endif 4878208Smckusick lock(sfnmail); 4888208Smckusick insert(lettmp, sfnmail, hisuid, hisgid); 4898208Smckusick unlock(); 4908208Smckusick } 4918208Smckusick else { /* it has / in it, "person" is a file */ 4928208Smckusick if(accesss(person)){ 4938208Smckusick lock(person); 4948208Smckusick insert(lettmp, person, -1, -1); 4958208Smckusick unlock(); 4968208Smckusick } 4978208Smckusick else 4988208Smckusick fprintf(stderr,"Can't access %s\n",person); 4998208Smckusick } 5008208Smckusick } 5018208Smckusick 5028208Smckusick /* return 1 if success, 0 otherwise */ 5038208Smckusick insert(from, to, uid, gid) 5048208Smckusick char *from, *to; 5058208Smckusick { 5068208Smckusick # ifdef V6 5078208Smckusick return(prepend(from,to,uid, gid)); 5088208Smckusick # else 5098208Smckusick return(append(from,to,uid, gid)); 5108208Smckusick # endif 5118208Smckusick } 5128208Smckusick /* return 1 if success, 0 otherwise */ 5138208Smckusick append(from,to,uid, gid) 5148208Smckusick char *from, *to; 5158208Smckusick { 5168208Smckusick register FILE *fdin, *fdout; 5178208Smckusick int ret; 5188208Smckusick struct stat statbuf; 5198208Smckusick #ifdef BIFF 5208208Smckusick /* biff ... */ 5218208Smckusick char *rindex(); 5228208Smckusick char *cp; 5238208Smckusick char buf[100]; 5248208Smckusick int f; 5258208Smckusick /* end biff */ 5268208Smckusick #endif BIFF 5278208Smckusick if (stat(to, &statbuf) >= 0 && (statbuf.st_mode&S_IFDIR) != 0) { 5288208Smckusick fprintf(stderr, "Exotic destination %s\n", to); 5298208Smckusick errs++; 5308208Smckusick return(0); 5318208Smckusick } 5328208Smckusick if ((fdout = fopen(to, "a")) == NULL) { 5338208Smckusick perror(to); 5348208Smckusick errs++; 5358208Smckusick return(0); 5368208Smckusick } 5378208Smckusick # ifndef NOTROOT 5388208Smckusick if(uid != -1)mchown(to, uid, gid); 5398208Smckusick # endif 5408208Smckusick if(uid != -1)chmod(to, MAILMODE); 5418208Smckusick if ((fdin = fopen(from, "r")) == NULL) { 5428208Smckusick perror(from); 5438208Smckusick return(0); 5448208Smckusick } 5458208Smckusick #ifdef BIFF 5468208Smckusick { 5478208Smckusick f = open("/dev/mail", 1); 5488208Smckusick cp = rindex(to, '/'); 5498208Smckusick if (cp) { 5508208Smckusick sprintf(buf, "%s@%d\n", cp+1, ftell(fdout)); 5518208Smckusick } 5528208Smckusick } 5538208Smckusick #endif BIFF 5548208Smckusick ret = getput(fdin,fdout); 5558208Smckusick fclose(fdin); 5568208Smckusick fclose(fdout); 5578208Smckusick #ifdef BIFF 5588208Smckusick if (cp && f >= 0) { 5598208Smckusick write(f, buf, strlen(buf)+1); 5608208Smckusick close(f); 5618208Smckusick } 5628208Smckusick #endif BIFF 5638208Smckusick return(ret); 5648208Smckusick } 5658208Smckusick 5668208Smckusick /* return 1 if success, 0 otherwise */ 5678208Smckusick prepend(from, to, uid, gid) 5688208Smckusick char *from, *to; 5698208Smckusick { 5708208Smckusick register int (*sig)(); 5718208Smckusick struct stat statbuf; 5728208Smckusick FILE *fdout, *fdin; 5738208Smckusick int ret; 5748208Smckusick 5758208Smckusick if (stat(to, &statbuf) >= 0 && (statbuf.st_mode&S_IFDIR) != 0) { 5768208Smckusick fprintf(stderr, "Exotic destination %s\n", to); 5778208Smckusick goto badexit; 5788208Smckusick } 5798208Smckusick unlink(preptmp); 5808208Smckusick if ((fdout = fopen(preptmp, "w")) == NULL) { 5818208Smckusick perror("mail"); 5828208Smckusick goto badexit; 5838208Smckusick } 5848208Smckusick chmod(preptmp, MAILMODE); 5858208Smckusick if ((fdin = fopen(from, "r")) == NULL) { 5868208Smckusick perror("mail"); 5878208Smckusick goto badexit; 5888208Smckusick } 5898208Smckusick if(getput(fdin,fdout) == 0){ 5908208Smckusick perror("file i/o"); 5918208Smckusick goto badexit; 5928208Smckusick } 5938208Smckusick fclose(fdin); 5948208Smckusick fdin = fopen(to, "r"); 5958208Smckusick /* ignore error since may not exist */ 5968208Smckusick if(fdin != NULL && getput(fdin,fdout) == 0){ 5978208Smckusick perror("file i/o"); 5988208Smckusick goto badexit; 5998208Smckusick } 6008208Smckusick if(fdin != NULL)fclose(fdin); 6018208Smckusick fclose(fdout); 6028208Smckusick sig = signal(SIGINT, SIG_IGN); 6038208Smckusick remove(to); 6048208Smckusick if ((fdout = fopen(to, "w")) == NULL) { 6058208Smckusick perror(to); 6068208Smckusick unlink(preptmp); 6078208Smckusick signal(SIGINT, sig); 6088208Smckusick goto badexit; 6098208Smckusick } 6108208Smckusick # ifdef NOTROOT 6118208Smckusick if(uid != -1)chmod(to,0666); 6128208Smckusick # else 6138208Smckusick if(uid != -1)mchown(to, uid, gid); 6148208Smckusick # endif 6158208Smckusick if(stat(to, &statbuf) < 0 || statbuf.st_nlink != 1) { 6168208Smckusick fclose(fdout); 6178208Smckusick signal(SIGINT, sig); 6188208Smckusick goto badexit; 6198208Smckusick } 6208208Smckusick if ((fdin = fopen(preptmp, "r")) == NULL) { 6218208Smckusick perror("mail"); 6228208Smckusick signal(SIGINT, sig); 6238208Smckusick goto badexit; 6248208Smckusick } 6258208Smckusick ret = getput(fdin,fdout); 6268208Smckusick fclose(fdout); 6278208Smckusick fclose(fdin); 6288208Smckusick signal(SIGINT, sig); 6298208Smckusick return(ret); 6308208Smckusick badexit: 6318208Smckusick unlink(preptmp); 6328208Smckusick errs++; 6338208Smckusick return(0); 6348208Smckusick } 6358208Smckusick 6368208Smckusick delexit(ex) 6378208Smckusick { 6388208Smckusick unlink(lettmp); 6398208Smckusick unlink(preptmp); 6408208Smckusick exit(ex); 6418208Smckusick } 6428208Smckusick 6438208Smckusick /* return 1 if ok, 0 otherwise */ 6448208Smckusick getput(fdin, fdout) 6458208Smckusick register FILE *fdin, *fdout; 6468208Smckusick { 6478208Smckusick extern int errno; 6488208Smckusick register int c; 6498208Smckusick 6508208Smckusick while((c = getc(fdin)) != EOF) { 6518208Smckusick errno = 0; 6528208Smckusick putc(c,fdout); 6538208Smckusick if(errno) { 6548208Smckusick perror("mail"); 6558208Smckusick return(0); 6568208Smckusick } 6578208Smckusick } 6588208Smckusick return(1); 6598208Smckusick } 6608208Smckusick 6618208Smckusick accesss(s1) 6628208Smckusick register char *s1; 6638208Smckusick { 6648208Smckusick struct stat statbuf; 6658208Smckusick if(stat(s1,&statbuf)<0 || access(s1,2) == 0) 6668208Smckusick return(1); 6678208Smckusick return(0); 6688208Smckusick } 6698208Smckusick 6708208Smckusick any(c, str) 6718208Smckusick register char *str, c; 6728208Smckusick { 6738208Smckusick register char *f; 6748208Smckusick 6758208Smckusick f = str; 6768208Smckusick while (*f) 6778208Smckusick if (c == *f++) 6788208Smckusick return(1); 6798208Smckusick return(0); 6808208Smckusick } 6818208Smckusick char locktmp[30]; /* Usable lock temporary */ 6828208Smckusick char curlock[50]; /* Last used name of lock */ 6838208Smckusick int locked; /* To note that we locked it */ 6848208Smckusick 6858208Smckusick /* 6868208Smckusick * Lock the specified mail file by setting the file mailfile.lock. 6878208Smckusick * We must, of course, be careful to unlink the lock file by a call 6888208Smckusick * to unlock before we stop. The algorithm used here is to see if 6898208Smckusick * the lock exists, and if it does, to check its modify time. If it 6908208Smckusick * is older than 30 seconds, we assume error and set our own file. 6918208Smckusick * Otherwise, we wait for 5 seconds and try again. 6928208Smckusick */ 6938208Smckusick 6948208Smckusick lock(file) 6958208Smckusick char *file; 6968208Smckusick { 6978208Smckusick register int f; 6988208Smckusick struct stat statbuf; 6998208Smckusick long curtime; 7008208Smckusick /* 7018208Smckusick if using OLDMAIL, and NOTROOT, cann't lock since can't necessarily 7028208Smckusick write on user's login directory 7038208Smckusick */ 7048208Smckusick # ifdef OLDMAIL 7058208Smckusick return; 7068208Smckusick # endif 7078208Smckusick 7088208Smckusick if (file == NULL) { 7098208Smckusick printf("Locked = %d\n", locked); 7108208Smckusick return(0); 7118208Smckusick } 7128208Smckusick if (locked) 7138208Smckusick return(0); 714*9983Seric sprintf(curlock,"%s%s",file,".lock"); 7158208Smckusick sprintf(locktmp,"%s/tmXXXXXX",MAILDIR); 7168208Smckusick mktemp(locktmp); 7178208Smckusick unlink(locktmp); 7188208Smckusick for (;;) { 7198208Smckusick f = lock1(locktmp, curlock); 7208208Smckusick if (f == 0) { 7218208Smckusick locked = 1; 7228208Smckusick return(0); 7238208Smckusick } 7248208Smckusick if (stat(curlock, &statbuf) < 0) 7258208Smckusick return(0); 7268208Smckusick time(&curtime); 7278208Smckusick if (curtime < statbuf.st_mtime + 30) { 7288208Smckusick sleep(5); 7298208Smckusick continue; 7308208Smckusick } 7318208Smckusick unlink(curlock); 7328208Smckusick } 7338208Smckusick } 7348208Smckusick 7358208Smckusick /* 7368208Smckusick * Remove the mail lock, and note that we no longer 7378208Smckusick * have it locked. 7388208Smckusick */ 7398208Smckusick 7408208Smckusick unlock() 7418208Smckusick { 7428208Smckusick 7438208Smckusick if (locked) 7448208Smckusick unlink(curlock); 7458208Smckusick locked = 0; 7468208Smckusick } 7478208Smckusick 7488208Smckusick /* 7498208Smckusick * Attempt to set the lock by creating the temporary file, 7508208Smckusick * then doing a link/unlink. If it fails, return -1 else 0 7518208Smckusick */ 7528208Smckusick 7538208Smckusick lock1(tempfile, name) 7548208Smckusick char tempfile[], name[]; 7558208Smckusick { 7568208Smckusick int fno; 7578208Smckusick 7588208Smckusick fno = creat(tempfile, 0400); 7598208Smckusick if (fno < 0) 7608208Smckusick return(-1); 7618208Smckusick close(fno); 7628208Smckusick if (link(tempfile, name) < 0) { 7638208Smckusick unlink(tempfile); 7648208Smckusick return(-1); 7658208Smckusick } 7668208Smckusick unlink(tempfile); 7678208Smckusick return(0); 7688208Smckusick } 7698208Smckusick 7708208Smckusick /* 7718208Smckusick stripfx(prefix string, pointer to string) 7728208Smckusick 7738208Smckusick takes a ptr to string and compares it to prefix string. 7748208Smckusick may be called multiple times 7758208Smckusick returns ":username" 7768208Smckusick */ 7778208Smckusick stripfx(pfx, name) 7788208Smckusick register char *pfx; 7798208Smckusick register char **name; 7808208Smckusick { 7818208Smckusick register char *cp = *name; 7828208Smckusick 7838208Smckusick while (*pfx && (*cp == *pfx || *cp == toupper(*pfx))) 7848208Smckusick cp++, pfx++; 7858208Smckusick if (*cp != ':' || *pfx != 0) 7868208Smckusick return; 7878208Smckusick *name = cp; 7888208Smckusick } 7898208Smckusick stripmach(pperson) 7908208Smckusick register char **pperson; 7918208Smckusick { 7928208Smckusick # ifdef RAND 7938208Smckusick /* for machines at RAND */ 7948208Smckusick # ifdef GRAPHICS 7958208Smckusick stripfx("g",pperson); 7968208Smckusick stripfx("graphics",pperson); 7978208Smckusick # endif 7988208Smckusick # ifdef TP 7998208Smckusick stripfx("t",pperson); 8008208Smckusick stripfx("tp",pperson); 8018208Smckusick # endif 8028208Smckusick # ifdef VAX 8038208Smckusick stripfx("v",pperson); 8048208Smckusick stripfx("vax",pperson); 8058208Smckusick # endif 8068208Smckusick /* end of defns for Rand */ 8078208Smckusick # endif 8088208Smckusick 8098208Smckusick # ifdef NOSC 8108208Smckusick /* for machines at NOSC */ 8118208Smckusick # ifdef ATTS 8128208Smckusick stripfx("a",pperson); 8138208Smckusick stripfx("atts",pperson); 8148208Smckusick # endif 8158208Smckusick # ifdef CCMM 8168208Smckusick stripfx("c",pperson); 8178208Smckusick stripfx("ccmm",pperson); 8188208Smckusick # endif 8198208Smckusick # ifdef MSSF 8208208Smckusick stripfx("m",pperson); 8218208Smckusick stripfx("mssf",pperson); 8228208Smckusick # endif 8238208Smckusick /* end of defns for NOSC */ 8248208Smckusick # endif 8258208Smckusick 8268208Smckusick # ifdef BERKELEY 8278208Smckusick 8288208Smckusick /* for Berkeley */ 8298208Smckusick # ifdef A 8308208Smckusick stripfx("a",pperson); 8318208Smckusick # endif 8328208Smckusick # ifdef B 8338208Smckusick stripfx("b",pperson); 8348208Smckusick # endif 8358208Smckusick # ifdef C 8368208Smckusick stripfx("c",pperson); 8378208Smckusick # endif 8388208Smckusick # ifdef D 8398208Smckusick stripfx("d",pperson); 8408208Smckusick # endif 8418208Smckusick # ifdef E 8428208Smckusick stripfx("e",pperson); 8438208Smckusick # endif 8448208Smckusick # ifdef ING70 8458208Smckusick stripfx("i",pperson); 8468208Smckusick stripfx("ing70",pperson); 8478208Smckusick stripfx("ingres",pperson); 8488208Smckusick # endif 8498208Smckusick # ifdef INGVAX 8508208Smckusick stripfx("j",pperson); 8518208Smckusick stripfx("ingvax",pperson); 8528208Smckusick # endif 8538208Smckusick # ifdef VIRUS 8548208Smckusick stripfx("k",pperson); 8558208Smckusick stripfx("virus",pperson); 8568208Smckusick # endif 8578208Smckusick # ifdef IMAGE 8588208Smckusick stripfx("m",pperson); 8598208Smckusick stripfx("image",pperson); 8608208Smckusick # endif 8618208Smckusick # ifdef KIM 8628208Smckusick stripfx("n",pperson); 8638208Smckusick stripfx("kim",pperson); 8648208Smckusick # endif 8658208Smckusick # ifdef ESVAX 8668208Smckusick stripfx("o",pperson); 8678208Smckusick stripfx("esvax",pperson); 8688208Smckusick # endif 8698208Smckusick # ifdef Q 8708208Smckusick stripfx("q",pperson); 8718208Smckusick # endif 8728208Smckusick # ifdef ARPAVAX 8738208Smckusick stripfx("r",pperson); 8748208Smckusick stripfx("arpavax",pperson); 8758208Smckusick # endif 8768208Smckusick # ifdef SRC 8778208Smckusick stripfx("s",pperson); 8788208Smckusick stripfx("src",pperson); 8798208Smckusick # endif 8808208Smckusick # ifdef MATHSTAT 8818208Smckusick stripfx("t",pperson); 8828208Smckusick stripfx("mathstat",pperson); 8838208Smckusick # endif 8848208Smckusick # ifdef CSVAX 8858208Smckusick stripfx("v",pperson); 8868208Smckusick stripfx("vax",pperson); 8878208Smckusick stripfx("csvax",pperson); 8888208Smckusick # endif 8898208Smckusick # ifdef CORY 8908208Smckusick stripfx("y",pperson); 8918208Smckusick stripfx("cory",pperson); 8928208Smckusick # endif 8938208Smckusick # ifdef EECS40 8948208Smckusick stripfx("z",pperson); 8958208Smckusick stripfx("eecs40",pperson); 8968208Smckusick # endif 8978208Smckusick /* end of berkeley defns */ 8988208Smckusick # endif 8998208Smckusick } 9008208Smckusick /* 9018208Smckusick this removes the mail file sfn by either truncating it, as required 9028208Smckusick on OLDMAIL systems, or unlinking it. If the unlink fails, we truncate it. 9038208Smckusick */ 9048208Smckusick remove(sfn) 9058208Smckusick char *sfn; 9068208Smckusick { 9078208Smckusick int i; 9088208Smckusick # ifdef OLDMAIL 9098208Smckusick i = creat(sfn,0666); 9108208Smckusick if(i >= 0)close(i); 9118208Smckusick # else 9128208Smckusick if(unlink(sfn) < 0){ 9138208Smckusick i = creat(sfn,MAILMODE); 9148208Smckusick if(i >= 0)close(i); 9158208Smckusick } 9168208Smckusick # endif 9178208Smckusick } 918