Commit | Line | Data |
---|---|---|
9552e6b8 DF |
1 | /* |
2 | * Copyright (c) 1980 Regents of the University of California. | |
0c5f72fb KB |
3 | * All rights reserved. |
4 | * | |
1c15e888 C |
5 | * Redistribution and use in source and binary forms are permitted provided |
6 | * that: (1) source distributions retain this entire copyright notice and | |
7 | * comment, and (2) distributions including binaries display the following | |
8 | * acknowledgement: ``This product includes software developed by the | |
9 | * University of California, Berkeley and its contributors'' in the | |
10 | * documentation or other materials provided with the distribution and in | |
11 | * all advertising materials mentioning features or use of this software. | |
12 | * Neither the name of the University nor the names of its contributors may | |
13 | * be used to endorse or promote products derived from this software without | |
14 | * specific prior written permission. | |
15 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED | |
16 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF | |
17 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
9552e6b8 DF |
18 | */ |
19 | ||
acfc7e9b | 20 | #ifndef lint |
0c5f72fb | 21 | char copyright[] = |
9552e6b8 DF |
22 | "@(#) Copyright (c) 1980 Regents of the University of California.\n\ |
23 | All rights reserved.\n"; | |
acfc7e9b | 24 | #endif /* not lint */ |
9552e6b8 | 25 | |
acfc7e9b | 26 | #ifndef lint |
1c15e888 | 27 | static char sccsid[] = "@(#)main.c 5.27 (Berkeley) 6/25/90"; |
acfc7e9b | 28 | #endif /* not lint */ |
83f7d6ec KS |
29 | |
30 | #include "rcv.h" | |
31 | #include <sys/stat.h> | |
32 | ||
33 | /* | |
34 | * Mail -- a mail program | |
35 | * | |
36 | * Startup -- interface with user. | |
37 | */ | |
38 | ||
5807729c | 39 | jmp_buf hdrjmp; |
83f7d6ec | 40 | |
83f7d6ec KS |
41 | main(argc, argv) |
42 | char **argv; | |
43 | { | |
790344bc EW |
44 | register int i; |
45 | struct name *to, *cc, *bcc, *smopts; | |
3d6f01e5 EW |
46 | char *subject; |
47 | char *ef; | |
f674e088 | 48 | char nosrc = 0; |
e62a1467 EW |
49 | int hdrstop(); |
50 | sig_t prevint; | |
322c8626 | 51 | int sigchild(); |
790344bc EW |
52 | extern int getopt(), optind, opterr; |
53 | extern char *optarg; | |
83f7d6ec | 54 | |
83f7d6ec | 55 | /* |
828615a1 | 56 | * Set up a reasonable environment. |
322c8626 EW |
57 | * Figure out whether we are being run interactively, |
58 | * start the SIGCHLD catcher, and so forth. | |
83f7d6ec | 59 | */ |
322c8626 | 60 | (void) signal(SIGCHLD, sigchild); |
686f6134 EW |
61 | if (isatty(0)) |
62 | assign("interactive", ""); | |
83f7d6ec | 63 | image = -1; |
83f7d6ec KS |
64 | /* |
65 | * Now, determine how we are being used. | |
723b83d3 | 66 | * We successively pick off - flags. |
83f7d6ec KS |
67 | * If there is anything left, it is the base of the list |
68 | * of users to mail to. Argp will be set to point to the | |
69 | * first of these users. | |
70 | */ | |
83f7d6ec | 71 | ef = NOSTR; |
3d6f01e5 EW |
72 | to = NIL; |
73 | cc = NIL; | |
74 | bcc = NIL; | |
75 | smopts = NIL; | |
76 | subject = NOSTR; | |
723b83d3 EW |
77 | while ((i = getopt(argc, argv, "INT:b:c:dfins:u:v")) != EOF) { |
78 | switch (i) { | |
12a8dbc7 KS |
79 | case 'T': |
80 | /* | |
81 | * Next argument is temp file to write which | |
82 | * articles have been read/deleted for netnews. | |
83 | */ | |
790344bc | 84 | Tflag = optarg; |
723b83d3 | 85 | if ((i = creat(Tflag, 0600)) < 0) { |
e3d4be91 KS |
86 | perror(Tflag); |
87 | exit(1); | |
88 | } | |
723b83d3 | 89 | close(i); |
12a8dbc7 | 90 | break; |
83f7d6ec KS |
91 | case 'u': |
92 | /* | |
93 | * Next argument is person to pretend to be. | |
94 | */ | |
f674e088 | 95 | myname = optarg; |
83f7d6ec | 96 | break; |
83f7d6ec KS |
97 | case 'i': |
98 | /* | |
99 | * User wants to ignore interrupts. | |
100 | * Set the variable "ignore" | |
101 | */ | |
102 | assign("ignore", ""); | |
103 | break; | |
83f7d6ec KS |
104 | case 'd': |
105 | debug++; | |
106 | break; | |
83f7d6ec KS |
107 | case 's': |
108 | /* | |
109 | * Give a subject field for sending from | |
110 | * non terminal | |
111 | */ | |
3d6f01e5 | 112 | subject = optarg; |
83f7d6ec | 113 | break; |
83f7d6ec KS |
114 | case 'f': |
115 | /* | |
116 | * User is specifying file to "edit" with Mail, | |
117 | * as opposed to reading system mailbox. | |
118 | * If no argument is given after -f, we read his | |
2a0f6531 | 119 | * mbox file. |
790344bc EW |
120 | * |
121 | * getopt() can't handle optional arguments, so here | |
122 | * is an ugly hack to get around it. | |
83f7d6ec | 123 | */ |
209a87d1 | 124 | if ((argv[optind]) && (argv[optind][0] != '-')) |
790344bc | 125 | ef = argv[optind++]; |
83f7d6ec | 126 | else |
2a0f6531 | 127 | ef = "&"; |
83f7d6ec | 128 | break; |
83f7d6ec KS |
129 | case 'n': |
130 | /* | |
131 | * User doesn't want to source /usr/lib/Mail.rc | |
132 | */ | |
133 | nosrc++; | |
134 | break; | |
da8590df KS |
135 | case 'N': |
136 | /* | |
137 | * Avoid initial header printing. | |
138 | */ | |
209a87d1 | 139 | assign("noheader", ""); |
da8590df | 140 | break; |
843ac7dd CL |
141 | case 'v': |
142 | /* | |
143 | * Send mailer verbose flag | |
144 | */ | |
145 | assign("verbose", ""); | |
146 | break; | |
0f016ad0 S |
147 | case 'I': |
148 | /* | |
149 | * We're interactive | |
150 | */ | |
686f6134 | 151 | assign("interactive", ""); |
0f016ad0 | 152 | break; |
790344bc EW |
153 | case 'c': |
154 | /* | |
155 | * Get Carbon Copy Recipient list | |
156 | */ | |
3d6f01e5 | 157 | cc = cat(cc, nalloc(optarg, GCC)); |
790344bc EW |
158 | break; |
159 | case 'b': | |
160 | /* | |
161 | * Get Blind Carbon Copy Recipient list | |
162 | */ | |
3d6f01e5 | 163 | bcc = cat(bcc, nalloc(optarg, GBCC)); |
790344bc EW |
164 | break; |
165 | case '?': | |
ecedbe81 EW |
166 | fputs("\ |
167 | Usage: mail [-iInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\ | |
168 | [- sendmail-options ...]\n\ | |
169 | mail [-iInNv] -f [name]\n\ | |
170 | mail [-iInNv] [-u user]\n", | |
171 | stderr); | |
83f7d6ec KS |
172 | exit(1); |
173 | } | |
174 | } | |
209a87d1 | 175 | for (i = optind; (argv[i]) && (*argv[i] != '-'); i++) |
3d6f01e5 | 176 | to = cat(to, nalloc(argv[i], GTO)); |
790344bc | 177 | for (; argv[i]; i++) |
3d6f01e5 | 178 | smopts = cat(smopts, nalloc(argv[i], 0)); |
83f7d6ec KS |
179 | /* |
180 | * Check for inconsistent arguments. | |
181 | */ | |
3d6f01e5 EW |
182 | if (to == NIL && (subject != NOSTR || cc != NIL || bcc != NIL)) { |
183 | fputs("You must specify direct recipients with -s, -c, or -b.\n", stderr); | |
790344bc EW |
184 | exit(1); |
185 | } | |
3d6f01e5 | 186 | if (ef != NOSTR && to != NIL) { |
83f7d6ec KS |
187 | fprintf(stderr, "Cannot give -f and people to send to.\n"); |
188 | exit(1); | |
189 | } | |
83f7d6ec | 190 | tinit(); |
828615a1 | 191 | setscreensize(); |
5807729c | 192 | input = stdin; |
790344bc | 193 | rcvmode = !to; |
f674e088 | 194 | spreserve(); |
5807729c | 195 | if (!nosrc) |
435e8dff | 196 | load(_PATH_MASTER_RC); |
e9d34eb2 EW |
197 | /* |
198 | * Expand returns a savestr, but load only uses the file name | |
07b0d286 | 199 | * for fopen, so it's safe to do this. |
e9d34eb2 EW |
200 | */ |
201 | load(expand("~/.mailrc")); | |
790344bc | 202 | if (!rcvmode) { |
3d6f01e5 | 203 | mail(to, cc, bcc, smopts, subject); |
83f7d6ec KS |
204 | /* |
205 | * why wait? | |
206 | */ | |
83f7d6ec KS |
207 | exit(senderr); |
208 | } | |
83f7d6ec KS |
209 | /* |
210 | * Ok, we are reading mail. | |
211 | * Decide whether we are editing a mailbox or reading | |
212 | * the system mailbox, and open up the right stuff. | |
213 | */ | |
8421b6a6 | 214 | if (ef == NOSTR) |
2a0f6531 | 215 | ef = "%"; |
8421b6a6 | 216 | if (setfile(ef) < 0) |
2a0f6531 | 217 | exit(1); /* error already reported */ |
209a87d1 | 218 | if (setjmp(hdrjmp) == 0) { |
4d20fb09 EW |
219 | extern char *version; |
220 | ||
209a87d1 EW |
221 | if ((prevint = signal(SIGINT, SIG_IGN)) != SIG_IGN) |
222 | signal(SIGINT, hdrstop); | |
4d20fb09 EW |
223 | if (value("quiet") == NOSTR) |
224 | printf("Mail version %s. Type ? for help.\n", | |
225 | version); | |
226 | announce(); | |
209a87d1 EW |
227 | fflush(stdout); |
228 | signal(SIGINT, prevint); | |
5807729c | 229 | } |
83f7d6ec | 230 | commands(); |
2ee3bce2 EW |
231 | signal(SIGHUP, SIG_IGN); |
232 | signal(SIGINT, SIG_IGN); | |
233 | signal(SIGQUIT, SIG_IGN); | |
234 | quit(); | |
83f7d6ec KS |
235 | exit(0); |
236 | } | |
5807729c KS |
237 | |
238 | /* | |
239 | * Interrupt printing of the headers. | |
240 | */ | |
241 | hdrstop() | |
242 | { | |
243 | ||
5807729c | 244 | fflush(stdout); |
80187484 | 245 | fprintf(stderr, "\nInterrupt\n"); |
5807729c KS |
246 | longjmp(hdrjmp, 1); |
247 | } | |
828615a1 EW |
248 | |
249 | /* | |
d56fd190 | 250 | * Compute what the screen size for printing headers should be. |
828615a1 EW |
251 | * We use the following algorithm for the height: |
252 | * If baud rate < 1200, use 9 | |
253 | * If baud rate = 1200, use 14 | |
254 | * If baud rate > 1200, use 24 or ws_row | |
255 | * Width is either 80 or ws_col; | |
256 | */ | |
257 | setscreensize() | |
258 | { | |
d56fd190 | 259 | struct sgttyb tbuf; |
828615a1 EW |
260 | struct winsize ws; |
261 | ||
686f6134 | 262 | if (ioctl(1, TIOCGWINSZ, (char *) &ws) < 0) |
d56fd190 | 263 | ws.ws_col = ws.ws_row = 0; |
9a7dcab2 | 264 | if (ioctl(1, TIOCGETP, &tbuf) < 0) |
d56fd190 EW |
265 | tbuf.sg_ospeed = B9600; |
266 | if (tbuf.sg_ospeed < B1200) | |
828615a1 | 267 | screenheight = 9; |
d56fd190 | 268 | else if (tbuf.sg_ospeed == B1200) |
828615a1 | 269 | screenheight = 14; |
828615a1 EW |
270 | else if (ws.ws_row != 0) |
271 | screenheight = ws.ws_row; | |
828615a1 EW |
272 | else |
273 | screenheight = 24; | |
d56fd190 EW |
274 | if ((realscreenheight = ws.ws_row) == 0) |
275 | realscreenheight = 24; | |
276 | if ((screenwidth = ws.ws_col) == 0) | |
828615a1 EW |
277 | screenwidth = 80; |
278 | } |