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