Commit | Line | Data |
---|---|---|
96626201 KM |
1 | static char sccsid[] = "@(#)prmail.c 4.1 (Berkeley) %G%"; |
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 | } |