|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved.
4: *
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.
18: */
19:
20: #ifndef lint
21: char copyright[] =
22: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
23: All rights reserved.\n";
24: #endif /* not lint */
25:
26: #ifndef lint
27: static char sccsid[] = "@(#)main.c 5.27 (Berkeley) 6/25/90";
28: #endif /* not lint */
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:
39: jmp_buf hdrjmp;
40:
41: main(argc, argv)
42: char **argv;
43: {
44: register int i;
45: struct name *to, *cc, *bcc, *smopts;
46: char *subject;
47: char *ef;
48: char nosrc = 0;
49: int hdrstop();
50: sig_t prevint;
51: int sigchild();
52: extern int getopt(), optind, opterr;
53: extern char *optarg;
54:
55: /*
56: * Set up a reasonable environment.
57: * Figure out whether we are being run interactively,
58: * start the SIGCHLD catcher, and so forth.
59: */
60: (void) signal(SIGCHLD, sigchild);
61: if (isatty(0))
62: assign("interactive", "");
63: image = -1;
64: /*
65: * Now, determine how we are being used.
66: * We successively pick off - flags.
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: */
71: ef = NOSTR;
72: to = NIL;
73: cc = NIL;
74: bcc = NIL;
75: smopts = NIL;
76: subject = NOSTR;
77: while ((i = getopt(argc, argv, "INT:b:c:dfins:u:v")) != EOF) {
78: switch (i) {
79: case 'T':
80: /*
81: * Next argument is temp file to write which
82: * articles have been read/deleted for netnews.
83: */
84: Tflag = optarg;
85: if ((i = creat(Tflag, 0600)) < 0) {
86: perror(Tflag);
87: exit(1);
88: }
89: close(i);
90: break;
91: case 'u':
92: /*
93: * Next argument is person to pretend to be.
94: */
95: myname = optarg;
96: break;
97: case 'i':
98: /*
99: * User wants to ignore interrupts.
100: * Set the variable "ignore"
101: */
102: assign("ignore", "");
103: break;
104: case 'd':
105: debug++;
106: break;
107: case 's':
108: /*
109: * Give a subject field for sending from
110: * non terminal
111: */
112: subject = optarg;
113: break;
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
119: * mbox file.
120: *
121: * getopt() can't handle optional arguments, so here
122: * is an ugly hack to get around it.
123: */
124: if ((argv[optind]) && (argv[optind][0] != '-'))
125: ef = argv[optind++];
126: else
127: ef = "&";
128: break;
129: case 'n':
130: /*
131: * User doesn't want to source /usr/lib/Mail.rc
132: */
133: nosrc++;
134: break;
135: case 'N':
136: /*
137: * Avoid initial header printing.
138: */
139: assign("noheader", "");
140: break;
141: case 'v':
142: /*
143: * Send mailer verbose flag
144: */
145: assign("verbose", "");
146: break;
147: case 'I':
148: /*
149: * We're interactive
150: */
151: assign("interactive", "");
152: break;
153: case 'c':
154: /*
155: * Get Carbon Copy Recipient list
156: */
157: cc = cat(cc, nalloc(optarg, GCC));
158: break;
159: case 'b':
160: /*
161: * Get Blind Carbon Copy Recipient list
162: */
163: bcc = cat(bcc, nalloc(optarg, GBCC));
164: break;
165: case '?':
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);
172: exit(1);
173: }
174: }
175: for (i = optind; (argv[i]) && (*argv[i] != '-'); i++)
176: to = cat(to, nalloc(argv[i], GTO));
177: for (; argv[i]; i++)
178: smopts = cat(smopts, nalloc(argv[i], 0));
179: /*
180: * Check for inconsistent arguments.
181: */
182: if (to == NIL && (subject != NOSTR || cc != NIL || bcc != NIL)) {
183: fputs("You must specify direct recipients with -s, -c, or -b.\n", stderr);
184: exit(1);
185: }
186: if (ef != NOSTR && to != NIL) {
187: fprintf(stderr, "Cannot give -f and people to send to.\n");
188: exit(1);
189: }
190: tinit();
191: setscreensize();
192: input = stdin;
193: rcvmode = !to;
194: spreserve();
195: if (!nosrc)
196: load(_PATH_MASTER_RC);
197: /*
198: * Expand returns a savestr, but load only uses the file name
199: * for fopen, so it's safe to do this.
200: */
201: load(expand("~/.mailrc"));
202: if (!rcvmode) {
203: mail(to, cc, bcc, smopts, subject);
204: /*
205: * why wait?
206: */
207: exit(senderr);
208: }
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: */
214: if (ef == NOSTR)
215: ef = "%";
216: if (setfile(ef) < 0)
217: exit(1); /* error already reported */
218: if (setjmp(hdrjmp) == 0) {
219: extern char *version;
220:
221: if ((prevint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
222: signal(SIGINT, hdrstop);
223: if (value("quiet") == NOSTR)
224: printf("Mail version %s. Type ? for help.\n",
225: version);
226: announce();
227: fflush(stdout);
228: signal(SIGINT, prevint);
229: }
230: commands();
231: signal(SIGHUP, SIG_IGN);
232: signal(SIGINT, SIG_IGN);
233: signal(SIGQUIT, SIG_IGN);
234: quit();
235: exit(0);
236: }
237:
238: /*
239: * Interrupt printing of the headers.
240: */
241: hdrstop()
242: {
243:
244: fflush(stdout);
245: fprintf(stderr, "\nInterrupt\n");
246: longjmp(hdrjmp, 1);
247: }
248:
249: /*
250: * Compute what the screen size for printing headers should be.
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: {
259: struct sgttyb tbuf;
260: struct winsize ws;
261:
262: if (ioctl(1, TIOCGWINSZ, (char *) &ws) < 0)
263: ws.ws_col = ws.ws_row = 0;
264: if (ioctl(1, TIOCGETP, &tbuf) < 0)
265: tbuf.sg_ospeed = B9600;
266: if (tbuf.sg_ospeed < B1200)
267: screenheight = 9;
268: else if (tbuf.sg_ospeed == B1200)
269: screenheight = 14;
270: else if (ws.ws_row != 0)
271: screenheight = ws.ws_row;
272: else
273: screenheight = 24;
274: if ((realscreenheight = ws.ws_row) == 0)
275: realscreenheight = 24;
276: if ((screenwidth = ws.ws_col) == 0)
277: screenwidth = 80;
278: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.