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