Deleted Added
full compact
main.c (24360) main.c (32189)
1/*
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static char copyright[] =
36"@(#) Copyright (c) 1980, 1993\n\
37 The Regents of the University of California. All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93";
42#endif /* not lint */
43
44#include "rcv.h"
45#include <err.h>
46#include <fcntl.h>
47#include "extern.h"
48
49/*
50 * Mail -- a mail program
51 *
52 * Startup -- interface with user.
53 */
54
55jmp_buf hdrjmp;
56
57int
58main(argc, argv)
59 int argc;
60 char *argv[];
61{
62 register int i;
63 struct name *to, *cc, *bcc, *smopts;
1/*
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static char copyright[] =
36"@(#) Copyright (c) 1980, 1993\n\
37 The Regents of the University of California. All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93";
42#endif /* not lint */
43
44#include "rcv.h"
45#include <err.h>
46#include <fcntl.h>
47#include "extern.h"
48
49/*
50 * Mail -- a mail program
51 *
52 * Startup -- interface with user.
53 */
54
55jmp_buf hdrjmp;
56
57int
58main(argc, argv)
59 int argc;
60 char *argv[];
61{
62 register int i;
63 struct name *to, *cc, *bcc, *smopts;
64 char *subject;
65 char *ef;
64 char *subject, *replyto;
65 char *ef, *cp;
66 char nosrc = 0;
67 void hdrstop();
68 sig_t prevint;
69 void sigchild();
70
71 /*
72 * Set up a reasonable environment.
73 * Figure out whether we are being run interactively,
74 * start the SIGCHLD catcher, and so forth.
75 */
76 (void) signal(SIGCHLD, sigchild);
77 if (isatty(0))
78 assign("interactive", "");
79 image = -1;
80 /*
81 * Now, determine how we are being used.
82 * We successively pick off - flags.
83 * If there is anything left, it is the base of the list
84 * of users to mail to. Argp will be set to point to the
85 * first of these users.
86 */
87 ef = NOSTR;
88 to = NIL;
89 cc = NIL;
90 bcc = NIL;
91 smopts = NIL;
92 subject = NOSTR;
66 char nosrc = 0;
67 void hdrstop();
68 sig_t prevint;
69 void sigchild();
70
71 /*
72 * Set up a reasonable environment.
73 * Figure out whether we are being run interactively,
74 * start the SIGCHLD catcher, and so forth.
75 */
76 (void) signal(SIGCHLD, sigchild);
77 if (isatty(0))
78 assign("interactive", "");
79 image = -1;
80 /*
81 * Now, determine how we are being used.
82 * We successively pick off - flags.
83 * If there is anything left, it is the base of the list
84 * of users to mail to. Argp will be set to point to the
85 * first of these users.
86 */
87 ef = NOSTR;
88 to = NIL;
89 cc = NIL;
90 bcc = NIL;
91 smopts = NIL;
92 subject = NOSTR;
93 replyto = NOSTR;
93 while ((i = getopt(argc, argv, "INT:b:c:dfins:u:v")) != -1) {
94 switch (i) {
95 case 'T':
96 /*
97 * Next argument is temp file to write which
98 * articles have been read/deleted for netnews.
99 */
100 Tflag = optarg;
101 if ((i = creat(Tflag, 0600)) < 0) {
102 perror(Tflag);
103 exit(1);
104 }
105 close(i);
106 break;
107 case 'u':
108 /*
109 * Next argument is person to pretend to be.
110 */
111 myname = optarg;
112 break;
113 case 'i':
114 /*
115 * User wants to ignore interrupts.
116 * Set the variable "ignore"
117 */
118 assign("ignore", "");
119 break;
120 case 'd':
121 debug++;
122 break;
123 case 's':
124 /*
125 * Give a subject field for sending from
126 * non terminal
127 */
128 subject = optarg;
129 break;
130 case 'f':
131 /*
132 * User is specifying file to "edit" with Mail,
133 * as opposed to reading system mailbox.
134 * If no argument is given after -f, we read his
135 * mbox file.
136 *
137 * getopt() can't handle optional arguments, so here
138 * is an ugly hack to get around it.
139 */
140 if ((argv[optind]) && (argv[optind][0] != '-'))
141 ef = argv[optind++];
142 else
143 ef = "&";
144 break;
145 case 'n':
146 /*
147 * User doesn't want to source /usr/lib/Mail.rc
148 */
149 nosrc++;
150 break;
151 case 'N':
152 /*
153 * Avoid initial header printing.
154 */
155 assign("noheader", "");
156 break;
157 case 'v':
158 /*
159 * Send mailer verbose flag
160 */
161 assign("verbose", "");
162 break;
163 case 'I':
164 /*
165 * We're interactive
166 */
167 assign("interactive", "");
168 break;
169 case 'c':
170 /*
171 * Get Carbon Copy Recipient list
172 */
173 cc = cat(cc, nalloc(optarg, GCC));
174 break;
175 case 'b':
176 /*
177 * Get Blind Carbon Copy Recipient list
178 */
179 bcc = cat(bcc, nalloc(optarg, GBCC));
180 break;
181 case '?':
182 fputs("\
183Usage: mail [-iInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\
184 [- sendmail-options ...]\n\
185 mail [-iInNv] -f [name]\n\
186 mail [-iInNv] [-u user]\n",
187 stderr);
188 exit(1);
189 }
190 }
191 for (i = optind; (argv[i]) && (*argv[i] != '-'); i++)
192 to = cat(to, nalloc(argv[i], GTO));
193 for (; argv[i]; i++)
194 smopts = cat(smopts, nalloc(argv[i], 0));
195 /*
196 * Check for inconsistent arguments.
197 */
198 if (to == NIL && (subject != NOSTR || cc != NIL || bcc != NIL)) {
199 fputs("You must specify direct recipients with -s, -c, or -b.\n", stderr);
200 exit(1);
201 }
202 if (ef != NOSTR && to != NIL) {
203 fprintf(stderr, "Cannot give -f and people to send to.\n");
204 exit(1);
205 }
206 tinit();
207 setscreensize();
208 input = stdin;
209 rcvmode = !to;
210 spreserve();
211 if (!nosrc) {
212 char *s, *path_rc;
213
214 path_rc = malloc(sizeof(_PATH_MASTER_RC));
215 if (path_rc == NULL)
216 errx(1, "malloc(path_rc) failed");
217
218 strcpy(path_rc, _PATH_MASTER_RC);
219 while ((s = strsep(&path_rc, ":")) != NULL)
220 if (*s != '\0')
221 load(s);
222 }
94 while ((i = getopt(argc, argv, "INT:b:c:dfins:u:v")) != -1) {
95 switch (i) {
96 case 'T':
97 /*
98 * Next argument is temp file to write which
99 * articles have been read/deleted for netnews.
100 */
101 Tflag = optarg;
102 if ((i = creat(Tflag, 0600)) < 0) {
103 perror(Tflag);
104 exit(1);
105 }
106 close(i);
107 break;
108 case 'u':
109 /*
110 * Next argument is person to pretend to be.
111 */
112 myname = optarg;
113 break;
114 case 'i':
115 /*
116 * User wants to ignore interrupts.
117 * Set the variable "ignore"
118 */
119 assign("ignore", "");
120 break;
121 case 'd':
122 debug++;
123 break;
124 case 's':
125 /*
126 * Give a subject field for sending from
127 * non terminal
128 */
129 subject = optarg;
130 break;
131 case 'f':
132 /*
133 * User is specifying file to "edit" with Mail,
134 * as opposed to reading system mailbox.
135 * If no argument is given after -f, we read his
136 * mbox file.
137 *
138 * getopt() can't handle optional arguments, so here
139 * is an ugly hack to get around it.
140 */
141 if ((argv[optind]) && (argv[optind][0] != '-'))
142 ef = argv[optind++];
143 else
144 ef = "&";
145 break;
146 case 'n':
147 /*
148 * User doesn't want to source /usr/lib/Mail.rc
149 */
150 nosrc++;
151 break;
152 case 'N':
153 /*
154 * Avoid initial header printing.
155 */
156 assign("noheader", "");
157 break;
158 case 'v':
159 /*
160 * Send mailer verbose flag
161 */
162 assign("verbose", "");
163 break;
164 case 'I':
165 /*
166 * We're interactive
167 */
168 assign("interactive", "");
169 break;
170 case 'c':
171 /*
172 * Get Carbon Copy Recipient list
173 */
174 cc = cat(cc, nalloc(optarg, GCC));
175 break;
176 case 'b':
177 /*
178 * Get Blind Carbon Copy Recipient list
179 */
180 bcc = cat(bcc, nalloc(optarg, GBCC));
181 break;
182 case '?':
183 fputs("\
184Usage: mail [-iInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\
185 [- sendmail-options ...]\n\
186 mail [-iInNv] -f [name]\n\
187 mail [-iInNv] [-u user]\n",
188 stderr);
189 exit(1);
190 }
191 }
192 for (i = optind; (argv[i]) && (*argv[i] != '-'); i++)
193 to = cat(to, nalloc(argv[i], GTO));
194 for (; argv[i]; i++)
195 smopts = cat(smopts, nalloc(argv[i], 0));
196 /*
197 * Check for inconsistent arguments.
198 */
199 if (to == NIL && (subject != NOSTR || cc != NIL || bcc != NIL)) {
200 fputs("You must specify direct recipients with -s, -c, or -b.\n", stderr);
201 exit(1);
202 }
203 if (ef != NOSTR && to != NIL) {
204 fprintf(stderr, "Cannot give -f and people to send to.\n");
205 exit(1);
206 }
207 tinit();
208 setscreensize();
209 input = stdin;
210 rcvmode = !to;
211 spreserve();
212 if (!nosrc) {
213 char *s, *path_rc;
214
215 path_rc = malloc(sizeof(_PATH_MASTER_RC));
216 if (path_rc == NULL)
217 errx(1, "malloc(path_rc) failed");
218
219 strcpy(path_rc, _PATH_MASTER_RC);
220 while ((s = strsep(&path_rc, ":")) != NULL)
221 if (*s != '\0')
222 load(s);
223 }
224 if ((cp = getenv("REPLYTO")) != NULL)
225 replyto = cp;
223
224 /*
225 * Expand returns a savestr, but load only uses the file name
226 * for fopen, so it's safe to do this.
227 */
228 load(expand("~/.mailrc"));
229 if (!rcvmode) {
226
227 /*
228 * Expand returns a savestr, but load only uses the file name
229 * for fopen, so it's safe to do this.
230 */
231 load(expand("~/.mailrc"));
232 if (!rcvmode) {
230 mail(to, cc, bcc, smopts, subject);
233 mail(to, cc, bcc, smopts, subject, replyto);
231 /*
232 * why wait?
233 */
234 exit(senderr);
235 }
236 /*
237 * Ok, we are reading mail.
238 * Decide whether we are editing a mailbox or reading
239 * the system mailbox, and open up the right stuff.
240 */
241 if (ef == NOSTR)
242 ef = "%";
243 if (setfile(ef) < 0)
244 exit(1); /* error already reported */
245 if (setjmp(hdrjmp) == 0) {
246 extern char *version;
247
248 if ((prevint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
249 signal(SIGINT, hdrstop);
250 if (value("quiet") == NOSTR)
251 printf("Mail version %s. Type ? for help.\n",
252 version);
253 announce();
254 fflush(stdout);
255 signal(SIGINT, prevint);
256 }
257 commands();
258 signal(SIGHUP, SIG_IGN);
259 signal(SIGINT, SIG_IGN);
260 signal(SIGQUIT, SIG_IGN);
261 quit();
262 exit(0);
263}
264
265/*
266 * Interrupt printing of the headers.
267 */
268void
269hdrstop(signo)
270 int signo;
271{
272
273 fflush(stdout);
274 fprintf(stderr, "\nInterrupt\n");
275 longjmp(hdrjmp, 1);
276}
277
278/*
279 * Compute what the screen size for printing headers should be.
280 * We use the following algorithm for the height:
281 * If baud rate < 1200, use 9
282 * If baud rate = 1200, use 14
283 * If baud rate > 1200, use 24 or ws_row
284 * Width is either 80 or ws_col;
285 */
286void
287setscreensize()
288{
289 struct winsize ws;
290 struct termios tio;
291 speed_t speed = 0;
292
293 if (ioctl(1, TIOCGWINSZ, (char *) &ws) < 0)
294 ws.ws_col = ws.ws_row = 0;
295 if (tcgetattr(1, &tio) != -1)
296 speed = cfgetospeed(&tio);
297 if (speed <= 0)
298 speed = B9600;
299 if (speed < B1200)
300 screenheight = 9;
301 else if (speed == B1200)
302 screenheight = 14;
303 else if (ws.ws_row != 0)
304 screenheight = ws.ws_row;
305 else
306 screenheight = 24;
307 if ((realscreenheight = ws.ws_row) == 0)
308 realscreenheight = 24;
309 if ((screenwidth = ws.ws_col) == 0)
310 screenwidth = 80;
311}
234 /*
235 * why wait?
236 */
237 exit(senderr);
238 }
239 /*
240 * Ok, we are reading mail.
241 * Decide whether we are editing a mailbox or reading
242 * the system mailbox, and open up the right stuff.
243 */
244 if (ef == NOSTR)
245 ef = "%";
246 if (setfile(ef) < 0)
247 exit(1); /* error already reported */
248 if (setjmp(hdrjmp) == 0) {
249 extern char *version;
250
251 if ((prevint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
252 signal(SIGINT, hdrstop);
253 if (value("quiet") == NOSTR)
254 printf("Mail version %s. Type ? for help.\n",
255 version);
256 announce();
257 fflush(stdout);
258 signal(SIGINT, prevint);
259 }
260 commands();
261 signal(SIGHUP, SIG_IGN);
262 signal(SIGINT, SIG_IGN);
263 signal(SIGQUIT, SIG_IGN);
264 quit();
265 exit(0);
266}
267
268/*
269 * Interrupt printing of the headers.
270 */
271void
272hdrstop(signo)
273 int signo;
274{
275
276 fflush(stdout);
277 fprintf(stderr, "\nInterrupt\n");
278 longjmp(hdrjmp, 1);
279}
280
281/*
282 * Compute what the screen size for printing headers should be.
283 * We use the following algorithm for the height:
284 * If baud rate < 1200, use 9
285 * If baud rate = 1200, use 14
286 * If baud rate > 1200, use 24 or ws_row
287 * Width is either 80 or ws_col;
288 */
289void
290setscreensize()
291{
292 struct winsize ws;
293 struct termios tio;
294 speed_t speed = 0;
295
296 if (ioctl(1, TIOCGWINSZ, (char *) &ws) < 0)
297 ws.ws_col = ws.ws_row = 0;
298 if (tcgetattr(1, &tio) != -1)
299 speed = cfgetospeed(&tio);
300 if (speed <= 0)
301 speed = B9600;
302 if (speed < B1200)
303 screenheight = 9;
304 else if (speed == B1200)
305 screenheight = 14;
306 else if (ws.ws_row != 0)
307 screenheight = ws.ws_row;
308 else
309 screenheight = 24;
310 if ((realscreenheight = ws.ws_row) == 0)
311 realscreenheight = 24;
312 if ((screenwidth = ws.ws_col) == 0)
313 screenwidth = 80;
314}