xref: /original-bsd/old/berknet/prmail.c (revision e59fb703)
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(&ltimeMail);
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