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