1*10217Ssam static char sccsid[] = "@(#)v6mail.c 4.4 (Berkeley) 01/09/83";
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 /*
43*10217Ssam * BIFF is an immediate notification flag using the IPC 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];
main(argc,argv)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
printmail(argc,argv,name,logindir)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
bulkmail(argc,argv,from)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 */
fline(fdout,date,from)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 */
getdate(linebuf)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
sendto(person,fromaddr)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 */
insert(from,to,uid,gid)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 }
512*10217Ssam
513*10217Ssam #ifdef BIFF
514*10217Ssam #include <sys/socket.h>
515*10217Ssam #include <netinet/in.h>
516*10217Ssam #include <netdb.h>
517*10217Ssam #endif
518*10217Ssam
5198208Smckusick /* return 1 if success, 0 otherwise */
append(from,to,uid,gid)5208208Smckusick append(from,to,uid, gid)
5218208Smckusick char *from, *to;
5228208Smckusick {
5238208Smckusick register FILE *fdin, *fdout;
5248208Smckusick int ret;
5258208Smckusick struct stat statbuf;
5268208Smckusick #ifdef BIFF
527*10217Ssam char *cp, buf[100], *rindex();
528*10217Ssam int s;
529*10217Ssam struct hostent *hp;
530*10217Ssam struct sockaddr_in sin;
531*10217Ssam struct servent *sp;
532*10217Ssam #endif
5338208Smckusick if (stat(to, &statbuf) >= 0 && (statbuf.st_mode&S_IFDIR) != 0) {
5348208Smckusick fprintf(stderr, "Exotic destination %s\n", to);
5358208Smckusick errs++;
5368208Smckusick return(0);
5378208Smckusick }
5388208Smckusick if ((fdout = fopen(to, "a")) == NULL) {
5398208Smckusick perror(to);
5408208Smckusick errs++;
5418208Smckusick return(0);
5428208Smckusick }
5438208Smckusick # ifndef NOTROOT
5448208Smckusick if(uid != -1)mchown(to, uid, gid);
5458208Smckusick # endif
5468208Smckusick if(uid != -1)chmod(to, MAILMODE);
5478208Smckusick if ((fdin = fopen(from, "r")) == NULL) {
5488208Smckusick perror(from);
5498208Smckusick return(0);
5508208Smckusick }
5518208Smckusick #ifdef BIFF
552*10217Ssam { s = socket(AF_INET, SOCK_STREAM, 0, 0);
553*10217Ssam cp = rindex(to, '/');
554*10217Ssam if (cp)
555*10217Ssam sprintf(buf, "%s@%d\n", cp+1, ftell(fdout));
5568208Smckusick }
557*10217Ssam #endif
5588208Smckusick ret = getput(fdin,fdout);
5598208Smckusick fclose(fdin);
5608208Smckusick fclose(fdout);
5618208Smckusick #ifdef BIFF
562*10217Ssam if (cp && s >= 0) {
563*10217Ssam hp = gethostbyname("localhost");
564*10217Ssam sp = getservent("biff", "udp");
565*10217Ssam if (hp && sp) {
566*10217Ssam bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
567*10217Ssam sin.sin_family = hp->h_addrtype;
568*10217Ssam sin.sin_port = sp->s_port;
569*10217Ssam (void) sendto(s, buf, strlen(buf) + 1, 0,
570*10217Ssam &sin, sizeof (sin));
571*10217Ssam }
572*10217Ssam close(s);
5738208Smckusick }
574*10217Ssam #endif
5758208Smckusick return(ret);
5768208Smckusick }
5778208Smckusick
5788208Smckusick /* return 1 if success, 0 otherwise */
prepend(from,to,uid,gid)5798208Smckusick prepend(from, to, uid, gid)
5808208Smckusick char *from, *to;
5818208Smckusick {
5828208Smckusick register int (*sig)();
5838208Smckusick struct stat statbuf;
5848208Smckusick FILE *fdout, *fdin;
5858208Smckusick int ret;
5868208Smckusick
5878208Smckusick if (stat(to, &statbuf) >= 0 && (statbuf.st_mode&S_IFDIR) != 0) {
5888208Smckusick fprintf(stderr, "Exotic destination %s\n", to);
5898208Smckusick goto badexit;
5908208Smckusick }
5918208Smckusick unlink(preptmp);
5928208Smckusick if ((fdout = fopen(preptmp, "w")) == NULL) {
5938208Smckusick perror("mail");
5948208Smckusick goto badexit;
5958208Smckusick }
5968208Smckusick chmod(preptmp, MAILMODE);
5978208Smckusick if ((fdin = fopen(from, "r")) == NULL) {
5988208Smckusick perror("mail");
5998208Smckusick goto badexit;
6008208Smckusick }
6018208Smckusick if(getput(fdin,fdout) == 0){
6028208Smckusick perror("file i/o");
6038208Smckusick goto badexit;
6048208Smckusick }
6058208Smckusick fclose(fdin);
6068208Smckusick fdin = fopen(to, "r");
6078208Smckusick /* ignore error since may not exist */
6088208Smckusick if(fdin != NULL && getput(fdin,fdout) == 0){
6098208Smckusick perror("file i/o");
6108208Smckusick goto badexit;
6118208Smckusick }
6128208Smckusick if(fdin != NULL)fclose(fdin);
6138208Smckusick fclose(fdout);
6148208Smckusick sig = signal(SIGINT, SIG_IGN);
6158208Smckusick remove(to);
6168208Smckusick if ((fdout = fopen(to, "w")) == NULL) {
6178208Smckusick perror(to);
6188208Smckusick unlink(preptmp);
6198208Smckusick signal(SIGINT, sig);
6208208Smckusick goto badexit;
6218208Smckusick }
6228208Smckusick # ifdef NOTROOT
6238208Smckusick if(uid != -1)chmod(to,0666);
6248208Smckusick # else
6258208Smckusick if(uid != -1)mchown(to, uid, gid);
6268208Smckusick # endif
6278208Smckusick if(stat(to, &statbuf) < 0 || statbuf.st_nlink != 1) {
6288208Smckusick fclose(fdout);
6298208Smckusick signal(SIGINT, sig);
6308208Smckusick goto badexit;
6318208Smckusick }
6328208Smckusick if ((fdin = fopen(preptmp, "r")) == NULL) {
6338208Smckusick perror("mail");
6348208Smckusick signal(SIGINT, sig);
6358208Smckusick goto badexit;
6368208Smckusick }
6378208Smckusick ret = getput(fdin,fdout);
6388208Smckusick fclose(fdout);
6398208Smckusick fclose(fdin);
6408208Smckusick signal(SIGINT, sig);
6418208Smckusick return(ret);
6428208Smckusick badexit:
6438208Smckusick unlink(preptmp);
6448208Smckusick errs++;
6458208Smckusick return(0);
6468208Smckusick }
6478208Smckusick
delexit(ex)6488208Smckusick delexit(ex)
6498208Smckusick {
6508208Smckusick unlink(lettmp);
6518208Smckusick unlink(preptmp);
6528208Smckusick exit(ex);
6538208Smckusick }
6548208Smckusick
6558208Smckusick /* return 1 if ok, 0 otherwise */
getput(fdin,fdout)6568208Smckusick getput(fdin, fdout)
6578208Smckusick register FILE *fdin, *fdout;
6588208Smckusick {
6598208Smckusick extern int errno;
6608208Smckusick register int c;
6618208Smckusick
6628208Smckusick while((c = getc(fdin)) != EOF) {
6638208Smckusick errno = 0;
6648208Smckusick putc(c,fdout);
6658208Smckusick if(errno) {
6668208Smckusick perror("mail");
6678208Smckusick return(0);
6688208Smckusick }
6698208Smckusick }
6708208Smckusick return(1);
6718208Smckusick }
6728208Smckusick
accesss(s1)6738208Smckusick accesss(s1)
6748208Smckusick register char *s1;
6758208Smckusick {
6768208Smckusick struct stat statbuf;
6778208Smckusick if(stat(s1,&statbuf)<0 || access(s1,2) == 0)
6788208Smckusick return(1);
6798208Smckusick return(0);
6808208Smckusick }
6818208Smckusick
any(c,str)6828208Smckusick any(c, str)
6838208Smckusick register char *str, c;
6848208Smckusick {
6858208Smckusick register char *f;
6868208Smckusick
6878208Smckusick f = str;
6888208Smckusick while (*f)
6898208Smckusick if (c == *f++)
6908208Smckusick return(1);
6918208Smckusick return(0);
6928208Smckusick }
6938208Smckusick char locktmp[30]; /* Usable lock temporary */
6948208Smckusick char curlock[50]; /* Last used name of lock */
6958208Smckusick int locked; /* To note that we locked it */
6968208Smckusick
6978208Smckusick /*
6988208Smckusick * Lock the specified mail file by setting the file mailfile.lock.
6998208Smckusick * We must, of course, be careful to unlink the lock file by a call
7008208Smckusick * to unlock before we stop. The algorithm used here is to see if
7018208Smckusick * the lock exists, and if it does, to check its modify time. If it
7028208Smckusick * is older than 30 seconds, we assume error and set our own file.
7038208Smckusick * Otherwise, we wait for 5 seconds and try again.
7048208Smckusick */
7058208Smckusick
lock(file)7068208Smckusick lock(file)
7078208Smckusick char *file;
7088208Smckusick {
7098208Smckusick register int f;
7108208Smckusick struct stat statbuf;
7118208Smckusick long curtime;
7128208Smckusick /*
7138208Smckusick if using OLDMAIL, and NOTROOT, cann't lock since can't necessarily
7148208Smckusick write on user's login directory
7158208Smckusick */
7168208Smckusick # ifdef OLDMAIL
7178208Smckusick return;
7188208Smckusick # endif
7198208Smckusick
7208208Smckusick if (file == NULL) {
7218208Smckusick printf("Locked = %d\n", locked);
7228208Smckusick return(0);
7238208Smckusick }
7248208Smckusick if (locked)
7258208Smckusick return(0);
7269983Seric sprintf(curlock,"%s%s",file,".lock");
7278208Smckusick sprintf(locktmp,"%s/tmXXXXXX",MAILDIR);
7288208Smckusick mktemp(locktmp);
7298208Smckusick unlink(locktmp);
7308208Smckusick for (;;) {
7318208Smckusick f = lock1(locktmp, curlock);
7328208Smckusick if (f == 0) {
7338208Smckusick locked = 1;
7348208Smckusick return(0);
7358208Smckusick }
7368208Smckusick if (stat(curlock, &statbuf) < 0)
7378208Smckusick return(0);
7388208Smckusick time(&curtime);
7398208Smckusick if (curtime < statbuf.st_mtime + 30) {
7408208Smckusick sleep(5);
7418208Smckusick continue;
7428208Smckusick }
7438208Smckusick unlink(curlock);
7448208Smckusick }
7458208Smckusick }
7468208Smckusick
7478208Smckusick /*
7488208Smckusick * Remove the mail lock, and note that we no longer
7498208Smckusick * have it locked.
7508208Smckusick */
7518208Smckusick
unlock()7528208Smckusick unlock()
7538208Smckusick {
7548208Smckusick
7558208Smckusick if (locked)
7568208Smckusick unlink(curlock);
7578208Smckusick locked = 0;
7588208Smckusick }
7598208Smckusick
7608208Smckusick /*
7618208Smckusick * Attempt to set the lock by creating the temporary file,
7628208Smckusick * then doing a link/unlink. If it fails, return -1 else 0
7638208Smckusick */
7648208Smckusick
lock1(tempfile,name)7658208Smckusick lock1(tempfile, name)
7668208Smckusick char tempfile[], name[];
7678208Smckusick {
7688208Smckusick int fno;
7698208Smckusick
7708208Smckusick fno = creat(tempfile, 0400);
7718208Smckusick if (fno < 0)
7728208Smckusick return(-1);
7738208Smckusick close(fno);
7748208Smckusick if (link(tempfile, name) < 0) {
7758208Smckusick unlink(tempfile);
7768208Smckusick return(-1);
7778208Smckusick }
7788208Smckusick unlink(tempfile);
7798208Smckusick return(0);
7808208Smckusick }
7818208Smckusick
7828208Smckusick /*
7838208Smckusick stripfx(prefix string, pointer to string)
7848208Smckusick
7858208Smckusick takes a ptr to string and compares it to prefix string.
7868208Smckusick may be called multiple times
7878208Smckusick returns ":username"
7888208Smckusick */
stripfx(pfx,name)7898208Smckusick stripfx(pfx, name)
7908208Smckusick register char *pfx;
7918208Smckusick register char **name;
7928208Smckusick {
7938208Smckusick register char *cp = *name;
7948208Smckusick
7958208Smckusick while (*pfx && (*cp == *pfx || *cp == toupper(*pfx)))
7968208Smckusick cp++, pfx++;
7978208Smckusick if (*cp != ':' || *pfx != 0)
7988208Smckusick return;
7998208Smckusick *name = cp;
8008208Smckusick }
stripmach(pperson)8018208Smckusick stripmach(pperson)
8028208Smckusick register char **pperson;
8038208Smckusick {
8048208Smckusick # ifdef RAND
8058208Smckusick /* for machines at RAND */
8068208Smckusick # ifdef GRAPHICS
8078208Smckusick stripfx("g",pperson);
8088208Smckusick stripfx("graphics",pperson);
8098208Smckusick # endif
8108208Smckusick # ifdef TP
8118208Smckusick stripfx("t",pperson);
8128208Smckusick stripfx("tp",pperson);
8138208Smckusick # endif
8148208Smckusick # ifdef VAX
8158208Smckusick stripfx("v",pperson);
8168208Smckusick stripfx("vax",pperson);
8178208Smckusick # endif
8188208Smckusick /* end of defns for Rand */
8198208Smckusick # endif
8208208Smckusick
8218208Smckusick # ifdef NOSC
8228208Smckusick /* for machines at NOSC */
8238208Smckusick # ifdef ATTS
8248208Smckusick stripfx("a",pperson);
8258208Smckusick stripfx("atts",pperson);
8268208Smckusick # endif
8278208Smckusick # ifdef CCMM
8288208Smckusick stripfx("c",pperson);
8298208Smckusick stripfx("ccmm",pperson);
8308208Smckusick # endif
8318208Smckusick # ifdef MSSF
8328208Smckusick stripfx("m",pperson);
8338208Smckusick stripfx("mssf",pperson);
8348208Smckusick # endif
8358208Smckusick /* end of defns for NOSC */
8368208Smckusick # endif
8378208Smckusick
8388208Smckusick # ifdef BERKELEY
8398208Smckusick
8408208Smckusick /* for Berkeley */
8418208Smckusick # ifdef A
8428208Smckusick stripfx("a",pperson);
8438208Smckusick # endif
8448208Smckusick # ifdef B
8458208Smckusick stripfx("b",pperson);
8468208Smckusick # endif
8478208Smckusick # ifdef C
8488208Smckusick stripfx("c",pperson);
8498208Smckusick # endif
8508208Smckusick # ifdef D
8518208Smckusick stripfx("d",pperson);
8528208Smckusick # endif
8538208Smckusick # ifdef E
8548208Smckusick stripfx("e",pperson);
8558208Smckusick # endif
8568208Smckusick # ifdef ING70
8578208Smckusick stripfx("i",pperson);
8588208Smckusick stripfx("ing70",pperson);
8598208Smckusick stripfx("ingres",pperson);
8608208Smckusick # endif
8618208Smckusick # ifdef INGVAX
8628208Smckusick stripfx("j",pperson);
8638208Smckusick stripfx("ingvax",pperson);
8648208Smckusick # endif
8658208Smckusick # ifdef VIRUS
8668208Smckusick stripfx("k",pperson);
8678208Smckusick stripfx("virus",pperson);
8688208Smckusick # endif
8698208Smckusick # ifdef IMAGE
8708208Smckusick stripfx("m",pperson);
8718208Smckusick stripfx("image",pperson);
8728208Smckusick # endif
8738208Smckusick # ifdef KIM
8748208Smckusick stripfx("n",pperson);
8758208Smckusick stripfx("kim",pperson);
8768208Smckusick # endif
8778208Smckusick # ifdef ESVAX
8788208Smckusick stripfx("o",pperson);
8798208Smckusick stripfx("esvax",pperson);
8808208Smckusick # endif
8818208Smckusick # ifdef Q
8828208Smckusick stripfx("q",pperson);
8838208Smckusick # endif
8848208Smckusick # ifdef ARPAVAX
8858208Smckusick stripfx("r",pperson);
8868208Smckusick stripfx("arpavax",pperson);
8878208Smckusick # endif
8888208Smckusick # ifdef SRC
8898208Smckusick stripfx("s",pperson);
8908208Smckusick stripfx("src",pperson);
8918208Smckusick # endif
8928208Smckusick # ifdef MATHSTAT
8938208Smckusick stripfx("t",pperson);
8948208Smckusick stripfx("mathstat",pperson);
8958208Smckusick # endif
8968208Smckusick # ifdef CSVAX
8978208Smckusick stripfx("v",pperson);
8988208Smckusick stripfx("vax",pperson);
8998208Smckusick stripfx("csvax",pperson);
9008208Smckusick # endif
9018208Smckusick # ifdef CORY
9028208Smckusick stripfx("y",pperson);
9038208Smckusick stripfx("cory",pperson);
9048208Smckusick # endif
9058208Smckusick # ifdef EECS40
9068208Smckusick stripfx("z",pperson);
9078208Smckusick stripfx("eecs40",pperson);
9088208Smckusick # endif
9098208Smckusick /* end of berkeley defns */
9108208Smckusick # endif
9118208Smckusick }
9128208Smckusick /*
9138208Smckusick this removes the mail file sfn by either truncating it, as required
9148208Smckusick on OLDMAIL systems, or unlinking it. If the unlink fails, we truncate it.
9158208Smckusick */
remove(sfn)9168208Smckusick remove(sfn)
9178208Smckusick char *sfn;
9188208Smckusick {
9198208Smckusick int i;
9208208Smckusick # ifdef OLDMAIL
9218208Smckusick i = creat(sfn,0666);
9228208Smckusick if(i >= 0)close(i);
9238208Smckusick # else
9248208Smckusick if(unlink(sfn) < 0){
9258208Smckusick i = creat(sfn,MAILMODE);
9268208Smckusick if(i >= 0)close(i);
9278208Smckusick }
9288208Smckusick # endif
9298208Smckusick }
930