]> diplodocus.org Git - nmh/blob - docs/historical/mh-nov-1983/cmds/send.c
Removed --depth 1 from git clone invocation.
[nmh] / docs / historical / mh-nov-1983 / cmds / send.c
1 #ifndef lint
2 static char sccsid[] = "@(#)send.c 4.6 7/7/83";
3 #endif
4
5 #include "mh.h"
6 #include <sys/wait.h>
7 #include <stdio.h>
8 #include <ctype.h>
9 #include <pwd.h>
10 #include <sys/types.h>
11 #include <sys/timeb.h>
12 #include <sys/stat.h>
13 #include <signal.h>
14 #include <strings.h>
15
16 #define SENDMAIL "/usr/lib/sendmail"
17 #define FCCS 10 /* Max number of fcc's allowed */
18
19 struct swit switches[] = {
20 "debug", -1, /* 0 */
21 "draft", 0, /* 1 */
22 "format", 0, /* 2 */
23 "noformat", 0, /* 3 */
24 "msgid", 0, /* 4 */
25 "nomsgid", 0, /* 5 */
26 "verbose", 0, /* 6 */
27 "noverbose", 0, /* 7 */
28 "help", 4, /* 8 */
29 "wait", 0, /* 9 */
30 "nowait", 0, /* 10 */
31 0, 0
32 };
33
34 int verbose, format, msgid, debug, myuid;
35 int waitfor = 1;
36 char *anoyes[]; /* Std no/yes gans array */
37 int donecd;
38 long now;
39 char tmpfil[32], fccfold[FCCS][128];
40 int fccind;
41 char *rindex();
42
43 main(argc, argv)
44 char *argv[];
45 {
46 register char *drft, *cp, *addrs;
47 register int i;
48 int pid;
49 struct stat stbuf;
50 char **ap, *msg;
51 char *arguments[50], **argp;
52 char buf[BUFSIZ], name[NAMESZ];
53 int state, compnum, fd;
54 FILE *in, *out;
55 char *getname();
56
57 #ifdef NEWS
58 m_news();
59 #endif
60 drft = 0;
61 cp = r1bindex(argv[0], '/');
62 if ((cp = m_find(cp)) != NULL) {
63 ap = brkstring(cp = getcpy(cp), " ", "\n");
64 ap = copyip(ap, arguments);
65 } else
66 ap = arguments;
67 copyip(argv+1, ap);
68 argp = arguments;
69
70 while(cp = *argp++) {
71 if(*cp == '-')
72 switch(smatch(++cp, switches)) {
73 case -2:ambigsw(cp, switches); /* ambiguous */
74 done(1);
75 /* unknown */
76 case -1:fprintf(stderr, "send: -%s unknown\n", cp);
77 done(1);
78 case 0: verbose++; debug++; continue; /* -debug */
79 case 1: drft = m_maildir(draft); /* -draft */
80 continue;
81 case 2: fprintf(stderr, "Send: -format not yet.\n");
82 done(1);
83 case 3: format = 0; continue; /* -noformat */
84 case 4: msgid = 1; continue; /* -msgid */
85 case 5: msgid = 0; continue; /* -nomsgid */
86 case 6: verbose = 1; continue; /* -verbose */
87 case 7: verbose = 0; continue; /* -noverbose */
88 case 8: help("send [file] [switches]", switches);
89 done(1);
90 case 9: waitfor = 1; continue; /* -wait */
91 case 10:waitfor = 0; continue; /* -nowait */
92 }
93 if(drft) {
94 fprintf(stderr, "send: Only 1 message at a time!\n");
95 done(1);
96 } else
97 drft = cp;
98 }
99 if(!drft) {
100 drft = m_maildir(draft);
101 if(stat(drft, &stbuf) == -1) {
102 fprintf(stderr,
103 "Draft file: %s doesn't exist.\n", drft);
104 done(1);
105 }
106 cp = concat("Use \"", drft, "\"? ", 0);
107 if(!gans(cp, anoyes))
108 done(0);
109 } else {
110 if(stat(drft, &stbuf) == -1) {
111 fprintf(stderr,
112 "Draft file: %s doesn't exist.\n", drft);
113 done(1);
114 }
115 }
116 m_update();
117
118 /* open files... */
119 if((in = fopen(drft, "r")) == NULL) {
120 fprintf(stderr, "Send: Can't open ");
121 perror(drft);
122 done(1);
123 }
124 copy(makename("locs", ".tmp"), copy("/tmp/", tmpfil));
125 if(!debug) {
126 if((out = fopen(tmpfil, "w")) == NULL) {
127 fprintf(stderr, "Can't create %s\n", tmpfil);
128 done(1);
129 }
130 chmod(tmpfil, 0744);
131 } else
132 out = stdout;
133
134 myuid = getuid();
135 putdate(0, out); /* Tack on the date */
136 /* putfrom(out);*/ /* let sendmail do this */
137 putmsgid(out); /* and message id if desired */
138
139 /*
140 ** Delivery phase
141 */
142 for(compnum = 1, state = FLD;;) {
143 state = m_getfld(state, name, buf, sizeof buf, in);
144 switch (state)
145 {
146 case FLD:
147 case FLDEOF:
148 case FLDPLUS:
149 compnum++;
150 cp = buf;
151 while(*cp == ' ' || *cp == '\t')
152 cp++;
153 fprintf(out, "%s: %s", name, cp);
154 if(uleq(name, "fcc")) {
155 if(fccind >= FCCS) {
156 fprintf(stderr, "Send: too many fcc's.\n");
157 done(1);
158 }
159 copy(cp, fccfold[fccind]);
160 if(cp = rindex(fccfold[fccind], '\n'))
161 *cp = 0;
162 fccind++;
163 }
164 while(state == FLDPLUS || state == FLDEOF) {
165 state = m_getfld(state, name, buf, sizeof buf, in);
166 fputs(buf, out);
167 }
168 if(state == FLDEOF)
169 goto process;
170 break;
171
172 case BODY:
173 case BODYEOF:
174 fprintf(out, "\n%s", buf);
175 while(state == BODY) {
176 state=m_getfld(state,name,buf,sizeof buf,in);
177 fputs(buf, out);
178 }
179
180 case FILEEOF:
181 goto process;
182
183 case LENERR:
184 case FMTERR:
185 fprintf(stderr, "??Message Format Error ");
186 fprintf(stderr, "in Component #%d.\n", compnum);
187 done(1);
188
189 default:
190 fprintf(stderr, "Getfld returned %d\n", state);
191 done(1);
192 }
193 }
194 process:
195 if(!debug)
196 fclose(out);
197 else
198 printf("-----\n");
199 fclose(in);
200
201 signal(SIGINT, SIG_IGN);
202 signal(SIGQUIT, SIG_IGN);
203 if(!debug) { /* Send the mail */
204 fd = open(tmpfil, 0);
205 sendmail(fd);
206 close(fd);
207 if(fccind) {
208 for(state = 0; state < fccind; state++)
209 fcc(tmpfil, fccfold[state]);
210 }
211 unlink(tmpfil);
212 }
213 if (!debug)
214 backup(drft);
215 done(donecd);
216 }
217
218 sendmail(fd)
219 {
220 int pid;
221 char *stashname[10];
222 char **stashp;
223
224 stashp = stashname;
225 *stashp++ = "sendmail";
226 *stashp++ = "-i";
227 *stashp++ = "-t";
228 if (verbose)
229 *stashp++ = "-v";
230 *stashp = 0;
231
232 while ((pid = fork()) == -1)
233 sleep(2);
234 if (pid == 0) {
235 close(0);
236 dup(fd);
237 close(fd);
238 execv(SENDMAIL, stashname);
239 perror(SENDMAIL);
240 _exit(1);
241 }
242 else if (waitfor)
243 (void) wait(0);
244 }
245
246 putfrom(out)
247 register FILE *out;
248 {
249 register struct passwd *pw;
250
251 pw = getpwuid(myuid);
252 if (pw == NULL)
253 {
254 fprintf(stderr, "Send: WHO ARE YOU?\n");
255 done(1);
256 }
257 fprintf(out, "From: %s\n", pw->pw_name);
258 }
259
260 putmsgid(sp)
261 FILE *sp;
262 {
263 char hostname[32];
264 auto int i = sizeof hostname;
265
266 if(!msgid)
267 return;
268 if(!now)
269 time(&now);
270 gethostname(hostname, &i);
271 fprintf(sp,
272 "Message-Id: <%u.%u.%ld@%s>\n", getpid(), myuid, now, hostname);
273 }
274
275 fcc(file, folder)
276 char *file, *folder;
277 {
278 int child, pid;
279 union wait status;
280 char fold[128];
281
282 if(verbose) {
283 printf("Fcc: %s...", folder);
284 fflush(stdout);
285 }
286 while ((child = fork()) == -1)
287 sleep(5);
288 if(child == 0) {
289 if(*file != '+')
290 strcpy(fold, "+");
291 strcat(fold, folder);
292 execl(fileproc, "file", "-link", "-file", file, fold, 0);
293 exit(-1);
294 } else
295 while((pid = wait(&status)) != -1 && pid != child);
296 if (status.w_status)
297 fprintf(stderr, "Send: Error on fcc to %s\n", folder);
298 else if(verbose)
299 putchar('\n');
300 }
301
302 backup(file)
303 char *file;
304 {
305 char buf[128];
306 register char *cp;
307
308 buf[0] = 0;
309 if(cp = rindex(file, '/'))
310 sprintf(buf, "%.*s", (++cp)-file, file);
311 else
312 cp = file;
313 #ifdef UCB
314 strcat(buf, "#");
315 #else
316 strcat(buf, ",");
317 #endif
318 strcat(buf, cp);
319 unlink(buf);
320 if(link(file, buf) < 0 || unlink(file) < 0) {
321 fprintf(stderr, "Send: Backup rename failure ");
322 perror(buf);
323 done(1);
324 }
325 }