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