]> diplodocus.org Git - nmh/blob - docs/historical/2.9BSD/cmds/mail.c
Added start_test/finish_test to a bunch of tests.
[nmh] / docs / historical / 2.9BSD / cmds / mail.c
1 #include "mh.h"
2 #include <stdio.h>
3 #include <signal.h>
4
5 #define NUMTOS 10 /* Number of to's & cc's accepted */
6
7 char tmpfil[32];
8 int exitstat = 1;
9 char *subject, *cc, *body;
10
11 struct swit switches[] = {
12 "body", 0, /* 0 */
13 "cc", 0, /* 1 */
14 "subject", 0, /* 2 */
15 "help", 4, /* 3 */
16 0, 0
17 };
18
19 main(argc, argv)
20 int argc;
21 char *argv[];
22 {
23 register FILE *out;
24 register int i, cnt;
25 register char *cp;
26 int pid, status, top, ccp, sig(), somebody = 0;
27 char buf[BUFSIZ], *tos[NUMTOS], *ccs[NUMTOS], **argp;
28
29 top = 0;
30 ccp = -1; /* -1 -> collecting TOs */
31 if(argc == 1) { /* Just call inc to read mail */
32 execl("/bin/inc", "inc", 0);
33 execl("/usr/bin/inc", "inc", 0);
34 perror("inc");
35 done(exitstat);
36 }
37 argp = argv + 1;
38 while(cp = *argp++) {
39 if(*cp == '-')
40 switch(smatch(++cp, switches)) {
41 case -2:ambigsw(cp, switches); /* ambiguous */
42 done(exitstat);
43 /* unknown */
44 case -1:fprintf(stderr, "send: -%s unknown\n", cp);
45 done(exitstat);
46 /* -body */
47 case 0: if((body = *argp++) == 0) {
48 missing: fprintf(stderr, "Mail: Missing %s arg\n", cp);
49 done(exitstat);
50 }
51 continue;
52 /* -cc */
53 case 1: ccp = 0; /* Now collecting ccs */
54 continue;
55 /* -subject */
56 case 2: if((subject = *argp++) == 0)
57 goto missing;
58 continue;
59 /* -help */
60 case 3: help("mail [switches] users ...",
61 switches);
62 done(0);
63 }
64 else {
65 if(ccp >= 0) { /* If getting ccs..*/
66 if(ccp < NUMTOS)
67 ccs[ccp++] = cp;
68 else {
69 fprintf(stderr, "Mail: Too many ccs\n");
70 done(exitstat);
71 }
72 } else { /* Else, to */
73 if(top < NUMTOS)
74 tos[top++] = cp;
75 else {
76 fprintf(stderr, "Mail: Too many tos\n");
77 done(exitstat);
78 }
79 }
80 }
81 }
82 /* Create a mail temp file */
83 sprintf(tmpfil, "/tmp/%s", makename("mail", ".tmp"));
84 if((out = fopen(tmpfil, "w")) == NULL) {
85 perror(tmpfil);
86 done(exitstat);
87 }
88 signal(SIGINT, sig); /* Clean up if user <del>s out */
89 fprintf(out, "To: "); /* Create to list */
90 for(i = 0; i < top;) {
91 fprintf(out, "%s", tos[i]);
92 if(++i < top)
93 fprintf(out, ", ");
94 }
95 fprintf(out, "\n");
96 if(ccp > 0) {
97 fprintf(out, "Cc: "); /* Create cc list if needed */
98 for(i = 0; i < ccp;) {
99 fprintf(out, "%s", ccs[i]);
100 if(++i < ccp)
101 fprintf(out, ", ");
102 }
103 fprintf(out, "\n");
104 }
105 if(subject) /* Create subject if needed */
106 fprintf(out, "Subject: %s\n", subject);
107
108 fprintf(out, "\n");
109
110 if(body) { /* Use body if I have it, */
111 somebody++;
112 fprintf(out, "%s\n", body);
113 } else { /* Otherwise, get a body */
114 while((cnt = read(0, buf, sizeof buf)) > 0) {
115 somebody++;
116 if(!fwrite(buf, cnt, 1, out)) {
117 perror(tmpfil);
118 sig();
119 }
120 }
121 }
122
123 if(ferror(out)) { /* Check that all wrote well */
124 fprintf(stderr, "Error writing tmp file\n");
125 sig();
126 }
127 fclose(out);
128 if(!somebody) /* If NO body, then don't send */
129 sig(); /* To be compatible with BELL mail */
130 while((i = fork()) == -1) { /* Now, deliver the mail */
131 fprintf(stderr, "Waiting for a fork...\n");
132 sleep(2);
133 }
134 if(i == 0) { /* Call deliverer in child */
135 execl(mh_deliver, mh_deliver, tmpfil, 0);
136 perror(mh_deliver);
137 done(exitstat);
138 }
139 signal(SIGINT, SIG_IGN);
140 while((pid = wait(&status)) != -1 && pid != i) ;
141 if(status) { /* And save mail if delivery failed */
142 signal(SIGINT, SIG_DFL);
143 fprintf(stderr, "Letter saved in dead.letter\n");
144 execl("/bin/mv", "mv", tmpfil, "dead.letter", 0);
145 execl("/usr/bin/mv", "mv", tmpfil, "dead.letter", 0);
146 perror("/bin/mv");
147 done(exitstat);
148 }
149 exitstat = 0;
150 sig();
151 }
152
153 sig()
154 {
155 unlink(tmpfil);
156 done(exitstat);
157 }