]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/send.c
sbr/mts.c: Delete mmdlm2; use same-valued mmdlm1 instead.
[nmh] / docs / historical / mh-6.8.5 / uip / send.c
1 /* send.c - send a composed message */
2 #ifndef lint
3 static char ident[] = "@(#)$Id: send.c,v 1.14 1995/12/06 21:04:47 jromine Exp $";
4 #endif /* lint */
5
6 #include "../h/mh.h"
7 #include <errno.h>
8 #include <stdio.h>
9 #include <signal.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #ifdef LOCALE
13 #include <locale.h>
14 #endif
15
16 /* \f */
17
18 #ifndef TMA
19 #define TMAminc(a) (a)
20 #else /* TMA */
21 #define TMAminc(a) 0
22 #endif /* TMA */
23
24 #ifdef MIME
25 #define MIMEminc(a) (a)
26 #else
27 #define MIMEminc(a) 0
28 #endif
29
30 static struct swit switches[] = {
31 #define ALIASW 0
32 "alias aliasfile", 0,
33
34 #define DEBUGSW 1
35 "debug", -5,
36
37 #define DRAFTSW 2
38 "draft", 0,
39
40 #define DFOLDSW 3
41 "draftfolder +folder", 6,
42 #define DMSGSW 4
43 "draftmessage msg", 6,
44 #define NDFLDSW 5
45 "nodraftfolder", 0,
46
47 #define ENCRSW 6
48 "encrypt", TMAminc (-7),
49 #define NENCRSW 7
50 "noencrypt", TMAminc (-9),
51
52 #define FILTSW 8
53 "filter filterfile", 0,
54 #define NFILTSW 9
55 "nofilter", 0,
56
57 #define FRMTSW 10
58 "format", 0,
59 #define NFRMTSW 11
60 "noformat", 0,
61
62 #define FORWSW 12
63 "forward", 0,
64 #define NFORWSW 13
65 "noforward", 0,
66
67 #define MIMESW 14
68 "mime", MIMEminc(-4),
69 #define NMIMESW 15
70 "nomime", MIMEminc(-6),
71
72 #define MSGDSW 16
73 "msgid", 0,
74 #define NMSGDSW 17
75 "nomsgid", 0,
76
77 #define PUSHSW 18
78 "push", 0,
79 #define NPUSHSW 19
80 "nopush", 0,
81
82 #define SPLITSW 20
83 "split seconds", MIMEminc(-5),
84
85 #define UNIQSW 21
86 "unique", -6,
87 #define NUNIQSW 22
88 "nounique", -8,
89
90 #define VERBSW 23
91 "verbose", 0,
92 #define NVERBSW 24
93 "noverbose", 0,
94
95 #define WATCSW 25
96 "watch", 0,
97 #define NWATCSW 26
98 "nowatch", 0,
99
100 #define WIDTHSW 27
101 "width columns", 0,
102
103 #define HELPSW 28
104 "help", 4,
105
106 #define MAILSW 29
107 "mail", -4,
108 #define SAMLSW 30
109 "saml", -4,
110 #define SENDSW 31
111 "send", -4,
112 #define SOMLSW 32
113 "soml", -4,
114
115 #define CLIESW 33
116 "client host", -6,
117 #define SERVSW 34
118 "server host", -6,
119 #define SNOOPSW 35
120 "snoop", -5,
121
122 #define QUEUESW 36
123 "queued", -6,
124
125 #define RECORSW 37
126 "record program", -6,
127 #define NRECOSW 38
128 "norecord", -8,
129
130 NULL, 0
131 };
132
133 static struct swit anyl[] = {
134 #define NOSW 0
135 "no", 0,
136 #define YESW 1
137 "yes", 0,
138 #define LISTDSW 2
139 "list", 0,
140
141 NULL, 0
142 };
143
144 /* \f */
145
146 extern int debugsw; /* from sendsbr.c */
147 extern int forwsw;
148 extern int inplace;
149 extern int mime;
150 extern int pushsw;
151 extern int splitsw;
152 extern int unique;
153 extern int verbsw;
154
155 extern char *altmsg; /* .. */
156 extern char *annotext;
157 extern char *distfile;
158
159
160 extern int errno;
161
162 /* \f */
163
164 /* ARGSUSED */
165
166 main (argc, argv)
167 int argc;
168 char *argv[];
169 {
170 int msgp = 0,
171 distsw = 0,
172 vecp = 1,
173 isdf = 0,
174 msgnum,
175 status;
176 char *cp,
177 *dfolder = NULL,
178 *maildir = NULL,
179 buf[100],
180 **ap,
181 **argp,
182 *arguments[MAXARGS],
183 *msgs[MAXARGS],
184 *vec[MAXARGS];
185 struct msgs *mp;
186 struct stat st;
187 #ifdef UCI
188 FILE *fp;
189 #endif /* UCI */
190
191 #ifdef LOCALE
192 setlocale(LC_ALL, "");
193 #endif
194 invo_name = r1bindex (argv[0], '/');
195 if ((cp = m_find (invo_name)) != NULL) {
196 ap = brkstring (cp = getcpy (cp), " ", "\n");
197 ap = copyip (ap, arguments);
198 }
199 else
200 ap = arguments;
201 (void) copyip (argv + 1, ap);
202 argp = arguments;
203
204 vec[vecp++] = "-library";
205 vec[vecp++] = getcpy (m_maildir (""));
206
207 /* \f */
208
209 while (cp = *argp++) {
210 if (*cp == '-')
211 switch (smatch (++cp, switches)) {
212 case AMBIGSW:
213 ambigsw (cp, switches);
214 done (1);
215 case UNKWNSW:
216 adios (NULLCP, "-%s unknown\n", cp);
217 case HELPSW:
218 (void) sprintf (buf, "%s [file] [switches]", invo_name);
219 help (buf, switches);
220 done (1); /* thanks, phyl */
221
222 case DRAFTSW:
223 msgs[msgp++] = draft;
224 continue;
225
226 case DFOLDSW:
227 if (dfolder)
228 adios (NULLCP, "only one draft folder at a time!");
229 if (!(cp = *argp++) || *cp == '-')
230 adios (NULLCP, "missing argument to %s", argp[-2]);
231 dfolder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp,
232 *cp != '@' ? TFOLDER : TSUBCWF);
233 continue;
234 case DMSGSW:
235 if (!(cp = *argp++) || *cp == '-')
236 adios (NULLCP, "missing argument to %s", argp[-2]);
237 msgs[msgp++] = cp;
238 continue;
239 case NDFLDSW:
240 dfolder = NULL;
241 isdf = NOTOK;
242 continue;
243
244 case PUSHSW:
245 pushsw++;
246 continue;
247 case NPUSHSW:
248 pushsw = 0;
249 continue;
250
251 case SPLITSW:
252 if (!(cp = *argp++) || sscanf (cp, "%d", &splitsw) != 1)
253 adios (NULLCP, "missing argument to %s", argp[-2]);
254 continue;
255
256 case UNIQSW:
257 unique++;
258 continue;
259 case NUNIQSW:
260 unique = 0;
261 continue;
262
263 case FORWSW:
264 forwsw++;
265 continue;
266 case NFORWSW:
267 forwsw = 0;
268 continue;
269
270 case VERBSW:
271 verbsw++;
272 vec[vecp++] = --cp;
273 continue;
274 case NVERBSW:
275 verbsw = 0;
276 vec[vecp++] = --cp;
277 continue;
278
279 case MIMESW:
280 #ifdef MIME
281 mime++;
282 vec[vecp++] = --cp;
283 #endif
284 continue;
285 case NMIMESW:
286 #ifdef MIME
287 mime = 0;
288 vec[vecp++] = --cp;
289 #endif
290 continue;
291
292 case DEBUGSW:
293 debugsw++; /* fall */
294 case NFILTSW:
295 case FRMTSW:
296 case NFRMTSW:
297 case MSGDSW:
298 case NMSGDSW:
299 case WATCSW:
300 case NWATCSW:
301 case MAILSW:
302 case SAMLSW:
303 case SENDSW:
304 case SOMLSW:
305 case ENCRSW:
306 case NENCRSW:
307 case SNOOPSW:
308 case QUEUESW:
309 case NRECOSW:
310 vec[vecp++] = --cp;
311 continue;
312
313 case ALIASW:
314 case FILTSW:
315 case WIDTHSW:
316 case CLIESW:
317 case SERVSW:
318 case RECORSW:
319 vec[vecp++] = --cp;
320 if (!(cp = *argp++) || *cp == '-')
321 adios (NULLCP, "missing argument to %s", argp[-2]);
322 vec[vecp++] = cp;
323 continue;
324 }
325 else
326 msgs[msgp++] = cp;
327 }
328 if (cp = m_find ("Aliasfile")) { /* allow Aliasfile: profile entry */
329 char *dp = NULL;
330
331 for (ap = brkstring(dp = getcpy(cp), " ", "\n"); ap && *ap; ap++) {
332 vec[vecp++] = "-alias";
333 vec[vecp++] = *ap;
334 }
335 }
336
337 /* \f */
338
339 if (dfolder == NULL) {
340 if (msgp == 0) {
341 #ifdef WHATNOW
342 if ((cp = getenv ("mhdraft")) && *cp) {
343 msgs[msgp++] = cp;
344 goto go_to_it;
345 }
346 #endif /* WHATNOW */
347 msgs[msgp++] = getcpy (m_draft (NULLCP, NULLCP, 1, &isdf));
348 if (stat (msgs[0], &st) == NOTOK)
349 adios (msgs[0], "unable to stat draft file");
350 cp = concat ("Use \"", msgs[0], "\"? ", NULLCP);
351 for (status = LISTDSW; status != YESW;) {
352 if (!(argp = getans (cp, anyl)))
353 done (1);
354 switch (status = smatch (*argp, anyl)) {
355 case NOSW:
356 done (0);
357 case YESW:
358 break;
359 case LISTDSW:
360 (void) showfile (++argp, msgs[0]);
361 break;
362 default:
363 advise (NULLCP, "say what?");
364 break;
365 }
366 }
367 }
368 else
369 for (msgnum = 0; msgnum < msgp; msgnum++)
370 msgs[msgnum] = getcpy (m_maildir (msgs[msgnum]));
371 }
372 else {
373 if (!m_find ("path"))
374 free (path ("./", TFOLDER));
375
376 if (!msgp)
377 msgs[msgp++] = "cur";
378 maildir = m_maildir (dfolder);
379
380 if (chdir (maildir) == NOTOK)
381 adios (maildir, "unable to change directory to");
382 if (!(mp = m_gmsg (dfolder)))
383 adios (NULLCP, "unable to read folder %s", dfolder);
384 if (mp -> hghmsg == 0)
385 adios (NULLCP, "no messages in %s", dfolder);
386
387 for (msgnum = 0; msgnum < msgp; msgnum++)
388 if (!m_convert (mp, msgs[msgnum]))
389 done (1);
390 m_setseq (mp);
391
392 for (msgp = 0, msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
393 if (mp -> msgstats[msgnum] & SELECTED) {
394 msgs[msgp++] = getcpy (m_name (msgnum));
395 #ifdef notdef
396 mp -> msgstats[msgnum] |= DELETED;
397 #endif /* notdef */
398 mp -> msgstats[msgnum] &= ~EXISTS;
399 }
400 mp -> msgflags |= SEQMOD;
401
402 m_sync (mp);
403 }
404 #ifdef WHATNOW
405 go_to_it: ;
406 #endif /* WHATNOW */
407
408 /* \f */
409
410 #ifdef TMA
411 if ((cp = getenv ("KDS")) == NULL || *cp == 0)
412 if ((cp = m_find ("kdsproc")) && *cp)
413 (void) m_putenv ("KDS", cp);
414 if ((cp = getenv ("TMADB")) == NULL || *cp == 0)
415 if ((cp = m_find ("tmadb")) && *cp)
416 (void) m_putenv ("TMADB", m_maildir (cp));
417 #endif /* TMA */
418
419 if ((cp = getenv ("SIGNATURE")) == NULL || *cp == 0)
420 if ((cp = m_find ("signature")) && *cp)
421 (void) m_putenv ("SIGNATURE", cp);
422 #ifdef UCI
423 else {
424 (void) sprintf (buf, "%s/.signature", mypath);
425 if ((fp = fopen (buf, "r")) != NULL
426 && fgets (buf, sizeof buf, fp) != NULL) {
427 (void) fclose (fp);
428 if (cp = index (buf, '\n'))
429 *cp = 0;
430 (void) m_putenv ("SIGNATURE", buf);
431 }
432 }
433 #endif /* UCI */
434
435 for (msgnum = 0; msgnum < msgp; msgnum++)
436 if (stat (msgs[msgnum], &st) == NOTOK)
437 adios (msgs[msgnum], "unable to stat draft file");
438
439 if ((annotext = getenv ("mhannotate")) == NULL || *annotext == 0)
440 annotext = NULL;
441 if (annotext && ((cp = getenv ("mhinplace")) != NULL && *cp != 0))
442 inplace = atoi (cp);
443 if ((altmsg = getenv ("mhaltmsg")) == NULL || *altmsg == 0)
444 altmsg = NULL; /* used by dist interface - see below */
445
446 if ((cp = getenv ("mhdist"))
447 && *cp
448 && (distsw = atoi (cp))
449 && altmsg) {
450 vec[vecp++] = "-dist";
451 distfile = getcpy (m_scratch (altmsg, invo_name));
452 if (link (altmsg, distfile) == NOTOK) {
453 if (errno != EXDEV
454 #ifdef EISREMOTE
455 && errno != EISREMOTE
456 #endif /* EISREMOTE */
457 )
458 adios (distfile, "unable to link %s to", altmsg);
459 free (distfile);
460 distfile = getcpy (m_tmpfil (invo_name));
461 {
462 int in, out;
463 struct stat st;
464
465 if ((in = open (altmsg, 0)) == NOTOK)
466 adios (altmsg, "unable to open");
467 (void) fstat(in, &st);
468 if ((out = creat (distfile, (int) st.st_mode & 0777)) == NOTOK)
469 adios (distfile, "unable to write");
470 cpydata (in, out, altmsg, distfile);
471 (void) close (in);
472 (void) close (out);
473 }
474 }
475 }
476 else
477 distfile = NULL;
478
479 if (altmsg == NULL || stat (altmsg, &st) == NOTOK)
480 st.st_mtime = 0, st.st_dev = 0, st.st_ino = 0;
481 if (pushsw)
482 push ();
483
484 status = 0;
485 vec[0] = r1bindex (postproc, '/');
486 closefds (3);
487
488 for (msgnum = 0; msgnum < msgp; msgnum++)
489 switch (sendsbr (vec, vecp, msgs[msgnum], &st)) {
490 case DONE:
491 done (++status);
492
493 case NOTOK:
494 status++; /* fall */
495 case OK:
496 break;
497 }
498
499 m_update ();
500
501 done (status);
502 }