BSD 4_3_Reno release
[unix-history] / usr / src / usr.bin / mail / main.c
CommitLineData
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 21char 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 27static 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 39jmp_buf hdrjmp;
83f7d6ec 40
83f7d6ec
KS
41main(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("\
167Usage: 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 */
241hdrstop()
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 */
257setscreensize()
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}