|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.