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