1 static char sccsid[] = "@(#)prmail.c 4.1 (Berkeley) 09/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 } 243