BSD 4_1c_2 release
[unix-history] / usr / src / ucb / berknet / prmail.c
CommitLineData
e804469b 1static char sccsid[] = "@(#)prmail.c 4.1 (Berkeley) 9/12/82";
96626201
KM
2
3/*
4 prmail -f fromaddress [-l username] [-c] [-k]
5
6 Print/forward mail on this machine to another machine.
7
8Preferred 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
47char _sobuf[BUFSIZ];
48main(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 */
145mailmail(fn,toaddress)
146char *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*/
202RcAppendMail(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}