static char sccsid[] = "@(#)prmail.c 4.1 (Berkeley) 9/12/82"; /* prmail -f fromaddress [-l username] [-c] [-k] Print/forward mail on this machine to another machine. Preferred usage (Has two modes): Mail check- A message is printed that there is mail. This is intended for people who put netmail -c addr in their .login files, and don't want to be prompted for their password. Mail check is indicated by a -c option. Mail forward- The mail is "mailed" to the fetcher. If the -r option is given, the mail is also appended to the mbox file and then removed. Forward is indicated by the lack of a -c option. Options: -l username read username's mail -f fromaddress forward mail to this address -c is a mail check, don't forward mail. -k print "No Mail" for all to see */ # include "defs.h" /* mail seems to reside in one of three places: 1. the user's home directory/.mail 2. /usr/mail/username 3. /usr/spool/mail/username the conditional compilation flags for these three forms are: 1. OLDMAIL 2. USRMAIL 3. is the default */ # ifdef USRMAIL # define MAILDIR "/usr/mail" # else # define MAILDIR "/usr/spool/mail" # endif char _sobuf[BUFSIZ]; main(argc,argv) char **argv; { long ltimeMail; struct stat statbuf; struct passwd *pwd; FILE *f; char fn[BUFSIZ],*s,username[20], fromaddress[BUFSIZ],toaddress[BUFSIZ], fMailCheck=0, *stimeMail,fquiet = 1; int ret,pid; fromaddress[0] = 0; username[0] = 0; setbuf(stdout,_sobuf); while(argc > 1){ argc--, argv++; if(argv[0][0] == '-'){ switch(argv[0][1]){ case 'c': fMailCheck++; break; case 'f': harg(fromaddress); break; case 'k': fquiet = 0; break; case 'l': harg(username); break; /* it is important to ignore unknown flags for compatibilty reasons */ } } } /* get the name of the user who's mail we're reading */ if(username[0] == 0){ s = SnFromUid(getuid()); if(s == NULL){ fprintf(stderr,"Unknown user\n"); exit(EX_OSFILE); } strcpy(username,s); } # ifdef OLDMAIL /* handle mail directory in user's directory */ /* can't do getenv because may be logging in as "network" */ pwd = getpwnam(username); if(pwd == NULL){ fprintf(stderr,"no passwd file\n"); exit(EX_OSFILE); } sprintf(fn,"%s/.mail",pwd->pw_dir); # else sprintf(fn,"%s/%s",MAILDIR,username); # endif sprintf(toaddress,"%s:%s", longname(local),username); if(fromaddress[0] == 0){ fprintf(stderr,"Need a From Address\n"); exit(EX_USAGE); } /* don't send anything back if nothing to send */ if(stat(fn,&statbuf) < 0 || getsize(&statbuf) == 0L) { if(!fquiet) printf("No mail for %s on the %s machine.\n", username,longname(local)); exit(EX_OK); } /* if a mail check, print message and exit */ if(fMailCheck){ ltimeMail = statbuf.st_mtime; stimeMail = ctime(<imeMail); stimeMail[strlen(stimeMail) - 6] = 0; printf( "\"%s\" has mail on the %s machine. \nLast updated on %s. \n", username,longname(local),stimeMail); printf("File %s:%s, Length %ld characters. \n", longname(local),fn,getsize(&statbuf)); exit(EX_OK); } /* read the mail and mail it to the account asking for it */ /* send mail to "fromaddress", as from "toaddress" */ ret = mailmail(fn,fromaddress); if(ret == 0){ ret = RcAppendMail(fn,username); if(ret == 0){ # ifndef OLDMAIL ret = unlink(fn); if(ret < 0) # endif ret = creat(fn,0644); if(ret >= 0)close(ret); } } if(ret < 0)fprintf(stderr,"Mail not removed\n"); exit(ret); } /* mail contents of file fn to user "toaddress" */ /* read file and mail each message separately */ /* returns return code of executing the mail prorgam */ mailmail(fn,toaddress) char *fn, *toaddress; { FILE *fdfile, *fdcmd; FILE *mailopen(); char line[BUFSIZ]; int ret; int more; fdfile = fopen(fn,"r"); if(fdfile == NULL){ perror(fn); exit(EX_DATAERR); } more = 1; line[0] = 0; while(more){ fdcmd = mailopen(toaddress,NULL,1,0); if(fdcmd == NULL){ perror("mail command"); exit(EX_UNAVAILABLE); } /* read line with from on it */ if(line[0] == 0)fgets(line,BUFSIZ,fdfile); /* insert a > before the first from line */ fprintf(fdcmd,">%s",line); more = 0; while(fgets(line,BUFSIZ,fdfile) != NULL){ if(strncmp(line,"From ",5) == 0){ more++; break; } fputs(line,fdcmd); } ret = mailclose(fdcmd); ret >>= 8; if(ret != 0){ fprintf(stderr, "Non-zero return code (%d) from the mail program\n", ret); break; } } fclose(fdfile); return(ret); } /* RcAppendMail(fnFrom) returns a return code Copy mail from fnFrom to the end of the mbox file in the user's home directory. Returns -1 if error, 0 if ok. Can't use getenv() because if there's no entry in utmp for machines with multiple names per uid, the getenv() will return the homedir of the first name/uid pair it finds. */ RcAppendMail(fnFrom,sn) char *fnFrom; char *sn; { FILE *fdFrom, *fdTo; char *shdir, fnTo[BUFSIZ], sBuf[BUFSIZ]; int nchar; # ifdef MULTNAMS struct passwd *pwd; pwd = getpwnam(sn); if(pwd == NULL)return(-1); shdir = pwd->pw_dir; # else shdir = getenv("HOME"); if(shdir == NULL)return(-1); # endif sprintf(fnTo,"%s/mbox",shdir); fdTo = fopen(fnTo,"a"); if(fdTo == NULL){ perror(fnTo); return(-1); } fdFrom = fopen(fnFrom,"r"); if(fdFrom == NULL){ perror(fdFrom); return(-1); } while((nchar = fread(sBuf,1,BUFSIZ,fdFrom)) > 0){ if(fwrite(sBuf,1,nchar,fdTo) != nchar){ perror(fnTo); return(-1); } } fclose(fdFrom); fclose(fdTo); return(0); }