1: static char sccsid[] = "@(#)prmail.c 4.1 (Berkeley) 9/12/82"; 2: 3: /* 4: prmail -f fromaddress [-l username] [-c] [-k] 5: 6: Print/forward mail on this machine to another machine. 7: 8: Preferred usage (Has two modes): 9: Mail check- 10: A message is printed that there is mail. 11: This is intended for people who put netmail -c addr 12: in their .login files, and don't want to 13: be prompted for their password. 14: Mail check is indicated by a -c option. 15: Mail forward- 16: The mail is "mailed" to the fetcher. 17: If the -r option is given, the mail is also 18: appended to the mbox file and then removed. 19: Forward is indicated by the lack of a -c option. 20: 21: Options: 22: -l username read username's mail 23: -f fromaddress forward mail to this address 24: -c is a mail check, don't forward mail. 25: -k print "No Mail" for all to see 26: 27: */ 28: 29: # include "defs.h" 30: 31: /* 32: mail seems to reside in one of three places: 33: 1. the user's home directory/.mail 34: 2. /usr/mail/username 35: 3. /usr/spool/mail/username 36: the conditional compilation flags for these three forms are: 37: 1. OLDMAIL 38: 2. USRMAIL 39: 3. is the default 40: */ 41: # ifdef USRMAIL 42: # define MAILDIR "/usr/mail" 43: # else 44: # define MAILDIR "/usr/spool/mail" 45: # endif 46: 47: char _sobuf[BUFSIZ]; 48: main(argc,argv) 49: char **argv; 50: { 51: long ltimeMail; 52: struct stat statbuf; 53: struct passwd *pwd; 54: FILE *f; 55: char fn[BUFSIZ],*s,username[20], 56: fromaddress[BUFSIZ],toaddress[BUFSIZ], 57: fMailCheck=0, *stimeMail,fquiet = 1; 58: int ret,pid; 59: fromaddress[0] = 0; 60: username[0] = 0; 61: setbuf(stdout,_sobuf); 62: while(argc > 1){ 63: argc--, argv++; 64: if(argv[0][0] == '-'){ 65: switch(argv[0][1]){ 66: case 'c': fMailCheck++; break; 67: case 'f': harg(fromaddress); break; 68: case 'k': fquiet = 0; break; 69: case 'l': harg(username); break; 70: /* it is important to ignore unknown flags for 71: compatibilty reasons */ 72: } 73: } 74: } 75: 76: /* get the name of the user who's mail we're reading */ 77: if(username[0] == 0){ 78: s = SnFromUid(getuid()); 79: if(s == NULL){ 80: fprintf(stderr,"Unknown user\n"); 81: exit(EX_OSFILE); 82: } 83: strcpy(username,s); 84: } 85: 86: # ifdef OLDMAIL 87: /* handle mail directory in user's directory */ 88: /* can't do getenv because may be logging in as "network" */ 89: pwd = getpwnam(username); 90: if(pwd == NULL){ 91: fprintf(stderr,"no passwd file\n"); 92: exit(EX_OSFILE); 93: } 94: sprintf(fn,"%s/.mail",pwd->pw_dir); 95: # else 96: sprintf(fn,"%s/%s",MAILDIR,username); 97: # endif 98: sprintf(toaddress,"%s:%s", longname(local),username); 99: if(fromaddress[0] == 0){ 100: fprintf(stderr,"Need a From Address\n"); 101: exit(EX_USAGE); 102: } 103: 104: /* don't send anything back if nothing to send */ 105: if(stat(fn,&statbuf) < 0 || getsize(&statbuf) == 0L) { 106: if(!fquiet) 107: printf("No mail for %s on the %s machine.\n", 108: username,longname(local)); 109: exit(EX_OK); 110: } 111: 112: /* if a mail check, print message and exit */ 113: if(fMailCheck){ 114: ltimeMail = statbuf.st_mtime; 115: stimeMail = ctime(<imeMail); 116: stimeMail[strlen(stimeMail) - 6] = 0; 117: printf( 118: "\"%s\" has mail on the %s machine. \nLast updated on %s. \n", 119: username,longname(local),stimeMail); 120: printf("File %s:%s, Length %ld characters. \n", 121: longname(local),fn,getsize(&statbuf)); 122: exit(EX_OK); 123: } 124: 125: /* read the mail and mail it to the account asking for it */ 126: /* send mail to "fromaddress", as from "toaddress" */ 127: ret = mailmail(fn,fromaddress); 128: if(ret == 0){ 129: ret = RcAppendMail(fn,username); 130: if(ret == 0){ 131: # ifndef OLDMAIL 132: ret = unlink(fn); 133: if(ret < 0) 134: # endif 135: ret = creat(fn,0644); 136: if(ret >= 0)close(ret); 137: } 138: } 139: if(ret < 0)fprintf(stderr,"Mail not removed\n"); 140: exit(ret); 141: } 142: /* mail contents of file fn to user "toaddress" */ 143: /* read file and mail each message separately */ 144: /* returns return code of executing the mail prorgam */ 145: mailmail(fn,toaddress) 146: char *fn, *toaddress; 147: { 148: FILE *fdfile, *fdcmd; 149: FILE *mailopen(); 150: char line[BUFSIZ]; 151: int ret; 152: int more; 153: 154: fdfile = fopen(fn,"r"); 155: if(fdfile == NULL){ 156: perror(fn); 157: exit(EX_DATAERR); 158: } 159: more = 1; 160: line[0] = 0; 161: while(more){ 162: fdcmd = mailopen(toaddress,NULL,1,0); 163: if(fdcmd == NULL){ 164: perror("mail command"); 165: exit(EX_UNAVAILABLE); 166: } 167: /* read line with from on it */ 168: if(line[0] == 0)fgets(line,BUFSIZ,fdfile); 169: /* insert a > before the first from line */ 170: fprintf(fdcmd,">%s",line); 171: more = 0; 172: while(fgets(line,BUFSIZ,fdfile) != NULL){ 173: if(strncmp(line,"From ",5) == 0){ 174: more++; 175: break; 176: } 177: fputs(line,fdcmd); 178: } 179: ret = mailclose(fdcmd); 180: ret >>= 8; 181: if(ret != 0){ 182: fprintf(stderr, 183: "Non-zero return code (%d) from the mail program\n", 184: ret); 185: break; 186: } 187: } 188: fclose(fdfile); 189: return(ret); 190: } 191: 192: /* 193: RcAppendMail(fnFrom) returns a return code 194: 195: Copy mail from fnFrom to the end of the mbox file in the user's 196: home directory. 197: Returns -1 if error, 0 if ok. 198: Can't use getenv() because if there's no entry in utmp 199: for machines with multiple names per uid, the getenv() will 200: return the homedir of the first name/uid pair it finds. 201: */ 202: RcAppendMail(fnFrom,sn) 203: char *fnFrom; 204: char *sn; 205: { 206: FILE *fdFrom, *fdTo; 207: char *shdir, fnTo[BUFSIZ], sBuf[BUFSIZ]; 208: int nchar; 209: 210: # ifdef MULTNAMS 211: struct passwd *pwd; 212: 213: pwd = getpwnam(sn); 214: if(pwd == NULL)return(-1); 215: shdir = pwd->pw_dir; 216: # else 217: shdir = getenv("HOME"); 218: if(shdir == NULL)return(-1); 219: # endif 220: sprintf(fnTo,"%s/mbox",shdir); 221: fdTo = fopen(fnTo,"a"); 222: if(fdTo == NULL){ 223: perror(fnTo); 224: return(-1); 225: } 226: 227: fdFrom = fopen(fnFrom,"r"); 228: if(fdFrom == NULL){ 229: perror(fdFrom); 230: return(-1); 231: } 232: 233: while((nchar = fread(sBuf,1,BUFSIZ,fdFrom)) > 0){ 234: if(fwrite(sBuf,1,nchar,fdTo) != nchar){ 235: perror(fnTo); 236: return(-1); 237: } 238: } 239: fclose(fdFrom); 240: fclose(fdTo); 241: return(0); 242: }