xref: /csrg-svn/old/berknet/prmail.c (revision 8203)
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(&ltimeMail);
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