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