source: trunk/third/nmh/uip/spost.c @ 14720

Revision 14720, 19.4 KB checked in by ghudson, 24 years ago (diff)
Check the return value of getm(); it can be NULL if you give it an invalid address.
Line 
1
2/*
3 * spost.c -- feed messages to sendmail
4 *
5 * This is a simpler, faster, replacement for "post" for use
6 * when "sendmail" is the transport system.
7 *
8 * $Id: spost.c,v 1.3 2000-05-08 15:47:28 ghudson Exp $
9 */
10
11#include <h/mh.h>
12#include <signal.h>
13#include <h/addrsbr.h>
14#include <h/aliasbr.h>
15#include <h/dropsbr.h>
16#include <zotnet/tws/tws.h>
17
18#define uptolow(c)      ((isalpha(c) && isupper (c)) ? tolower (c) : c)
19
20#define MAX_SM_FIELD    1476    /* < largest hdr field sendmail will accept */
21#define FCCS            10      /* max number of fccs allowed */
22
23struct swit switches[] = {
24#define FILTSW               0
25    { "filter filterfile", 0 },
26#define NFILTSW              1
27    { "nofilter", 0 },
28#define FRMTSW               2
29    { "format", 0 },
30#define NFRMTSW              3
31    { "noformat", 0 },
32#define REMVSW               4
33    { "remove", 0 },
34#define NREMVSW              5
35    { "noremove", 0 },
36#define VERBSW               6
37    { "verbose", 0 },
38#define NVERBSW              7
39    { "noverbose", 0 },
40#define WATCSW               8
41    { "watch", 0 },
42#define NWATCSW              9
43    { "nowatch", 0 },
44#define BACKSW              10
45    { "backup", 0 },
46#define NBACKSW             11
47    { "nobackup", 0 },
48#define ALIASW              12
49    { "alias aliasfile", 0 },
50#define NALIASW             13
51    { "noalias", 0 },
52#define WIDTHSW             14
53    { "width columns", 0 },
54#define VERSIONSW           15
55    { "version", 0 },
56#define HELPSW              16
57    { "help", 4 },
58#define DEBUGSW             17
59    { "debug", -5 },
60#define DISTSW              18
61    { "dist", -4 },             /* interface from dist */
62#define CHKSW               19
63    { "check", -5 },            /* interface from whom */
64#define NCHKSW              20
65    { "nocheck", -7 },          /* interface from whom */
66#define WHOMSW              21
67    { "whom", -4 },             /* interface from whom */
68#define PUSHSW              22  /* fork to sendmail then exit */
69    { "push", -4 },
70#define NPUSHSW             23  /* exec sendmail */
71    { "nopush", -6 },
72#define LIBSW               24
73    { "library directory", -7 },
74#define ANNOSW              25
75    { "idanno number", -6 },
76    { NULL, 0 }
77};
78
79
80/* flags for headers->flags */
81#define HNOP    0x0000          /* just used to keep .set around */
82#define HBAD    0x0001          /* bad header - don't let it through */
83#define HADR    0x0002          /* header has an address field */
84#define HSUB    0x0004          /* Subject: header */
85#define HTRY    0x0008          /* try to send to addrs on header */
86#define HBCC    0x0010          /* don't output this header */
87#define HMNG    0x0020          /* mung this header */
88#define HNGR    0x0040          /* no groups allowed in this header */
89#define HFCC    0x0080          /* FCC: type header */
90#define HNIL    0x0100          /* okay for this header not to have addrs */
91#define HIGN    0x0200          /* ignore this header */
92
93/* flags for headers->set */
94#define MFRM    0x0001          /* we've seen a From: */
95#define MDAT    0x0002          /* we've seen a Date: */
96#define MRFM    0x0004          /* we've seen a Resent-From: */
97#define MVIS    0x0008          /* we've seen sighted addrs */
98#define MINV    0x0010          /* we've seen blind addrs */
99#define MRDT    0x0020          /* we've seen a Resent-Date: */
100
101struct headers {
102    char *value;
103    unsigned int flags;
104    unsigned int set;
105};
106
107
108static struct headers NHeaders[] = {
109    { "Return-Path", HBAD,                0 },
110    { "Received",    HBAD,                0 },
111    { "Reply-To",    HADR|HNGR,           0 },
112    { "From",        HADR|HNGR,           MFRM },
113    { "Sender",      HADR|HBAD,           0 },
114    { "Date",        HNOP,                MDAT },
115    { "Subject",     HSUB,                0 },
116    { "To",          HADR|HTRY,           MVIS },
117    { "cc",          HADR|HTRY,           MVIS },
118    { "Bcc",         HADR|HTRY|HBCC|HNIL, MINV },
119    { "Message-Id",  HBAD,                0 },
120    { "Fcc",         HFCC,                0 },
121    { NULL,          0,                   0 }
122};
123
124static struct headers RHeaders[] = {
125    { "Resent-Reply-To",   HADR|HNGR,      0 },
126    { "Resent-From",       HADR|HNGR,      MRFM },
127    { "Resent-Sender",     HADR|HBAD,      0 },
128    { "Resent-Date",       HNOP,           MRDT },
129    { "Resent-Subject",    HSUB,           0 },
130    { "Resent-To",         HADR|HTRY,      MVIS },
131    { "Resent-cc",         HADR|HTRY,      MVIS },
132    { "Resent-Bcc",        HADR|HTRY|HBCC, MINV },
133    { "Resent-Message-Id", HBAD,           0 },
134    { "Resent-Fcc",        HFCC,           0 },
135    { "Reply-To",          HADR,           0 },
136    { "Fcc",               HIGN,           0 },
137    { NULL,                0,              0 }
138};
139
140
141static short fccind = 0;        /* index into fccfold[] */
142
143static int badmsg = 0;          /* message has bad semantics            */
144static int verbose = 0;         /* spell it out                         */
145static int debug = 0;           /* debugging post                       */
146static int rmflg = 1;           /* remove temporary file when done      */
147static int watch = 0;           /* watch the delivery process           */
148static int backflg = 0;         /* rename input file as *.bak when done */
149static int whomflg = 0;         /* if just checking addresses           */
150static int pushflg = 0;         /* if going to fork to sendmail         */
151static int aliasflg = -1;       /* if going to process aliases          */
152static int outputlinelen=72;
153
154static unsigned msgflags = 0;   /* what we've seen */
155
156static enum {
157    normal, resent
158} msgstate = normal;
159
160static char tmpfil[] = "/tmp/pstXXXXXX";
161
162static char from[BUFSIZ];       /* my network address */
163static char signature[BUFSIZ];  /* my signature */
164static char *filter = NULL;     /* the filter for BCC'ing */
165static char *subject = NULL;    /* the subject field for BCC'ing */
166static char *fccfold[FCCS];     /* foldernames for FCC'ing */
167
168static struct headers *hdrtab;  /* table for the message we're doing */
169static FILE *out;               /* output (temp) file */
170
171extern char *sendmail;
172
173/*
174 * external prototypes
175 */
176extern char *getfullname (void);
177extern char *getusername (void);
178
179/*
180 * static prototypes
181 */
182static void putfmt (char *, char *, FILE *);
183static void start_headers (void);
184static void finish_headers (FILE *);
185static int get_header (char *, struct headers *);
186static void putadr (char *, struct mailname *);
187static int putone (char *, int, int);
188static void insert_fcc (struct headers *, char *);
189static void file (char *);
190static void fcc (char *, char *);
191
192#if 0
193static void die (char *, char *, ...);
194static void make_bcc_file (void);
195#endif
196
197
198int
199main (int argc, char **argv)
200{
201    int state, i, pid, compnum;
202    char *cp, *msg = NULL, **argp, **arguments;
203    char *sargv[16], buf[BUFSIZ], name[NAMESZ];
204    FILE *in;
205
206#ifdef LOCALE
207    setlocale(LC_ALL, "");
208#endif
209    invo_name = r1bindex (argv[0], '/');
210
211    /* foil search of user profile/context */
212    if (context_foil (NULL) == -1)
213        done (1);
214
215    mts_init (invo_name);
216    arguments = getarguments (invo_name, argc, argv, 0);
217    argp = arguments;
218
219    while ((cp = *argp++)) {
220        if (*cp == '-') {
221            switch (smatch (++cp, switches)) {
222                case AMBIGSW:
223                    ambigsw (cp, switches);
224                    done (1);
225                case UNKWNSW:
226                    adios (NULL, "-%s unknown", cp);
227
228                case HELPSW:
229                    snprintf (buf, sizeof(buf), "%s [switches] file", invo_name);
230                    print_help (buf, switches, 1);
231                    done (1);
232                case VERSIONSW:
233                    print_version(invo_name);
234                    done (1);
235
236                case DEBUGSW:
237                    debug++;
238                    continue;
239
240                case DISTSW:
241                    msgstate = resent;
242                    continue;
243
244                case WHOMSW:
245                    whomflg++;
246                    continue;
247
248                case FILTSW:
249                    if (!(filter = *argp++) || *filter == '-')
250                        adios (NULL, "missing argument to %s", argp[-2]);
251                    continue;
252                case NFILTSW:
253                    filter = NULL;
254                    continue;
255               
256                case REMVSW:
257                    rmflg++;
258                    continue;
259                case NREMVSW:
260                    rmflg = 0;
261                    continue;
262
263                case BACKSW:
264                    backflg++;
265                    continue;
266                case NBACKSW:
267                    backflg = 0;
268                    continue;
269
270                case VERBSW:
271                    verbose++;
272                    continue;
273                case NVERBSW:
274                    verbose = 0;
275                    continue;
276
277                case WATCSW:
278                    watch++;
279                    continue;
280                case NWATCSW:
281                    watch = 0;
282                    continue;
283               
284                case PUSHSW:
285                    pushflg++;
286                    continue;
287                case NPUSHSW:
288                    pushflg = 0;
289                    continue;
290
291                case ALIASW:
292                    if (!(cp = *argp++) || *cp == '-')
293                        adios (NULL, "missing argument to %s", argp[-2]);
294                    if (aliasflg < 0)
295                        alias (AliasFile);/* load default aka's */
296                    aliasflg = 1;
297                    if ((state = alias(cp)) != AK_OK)
298                        adios (NULL, "aliasing error in file %s - %s",
299                               cp, akerror(state) );
300                    continue;
301                case NALIASW:
302                    aliasflg = 0;
303                    continue;
304
305                case WIDTHSW:
306                    if (!(cp = *argp++) || *cp == '-')
307                        adios (NULL, "missing argument to %s", argp[-2]);
308                    outputlinelen = atoi (cp);
309                    if (outputlinelen <= 10)
310                        outputlinelen = 72;
311                    continue;
312
313                case LIBSW:
314                    if (!(cp = *argp++) || *cp == '-')
315                        adios (NULL, "missing argument to %s", argp[-2]);
316                    /* create a minimal context */
317                    if (context_foil (cp) == -1)
318                        done(1);
319                    continue;
320
321                case ANNOSW:
322                    /* -idanno switch ignored */
323                    if (!(cp = *argp++) || *cp == '-')
324                        adios (NULL, "missing argument to %s", argp[-2]);
325                    continue;
326            }
327        }
328        if (msg)
329            adios (NULL, "only one message at a time!");
330        else
331            msg = cp;
332    }
333
334    if (aliasflg < 0)
335        alias (AliasFile);      /* load default aka's */
336
337    if (!msg)
338        adios (NULL, "usage: %s [switches] file", invo_name);
339
340    if ((in = fopen (msg, "r")) == NULL)
341        adios (msg, "unable to open");
342
343    start_headers ();
344    if (debug) {
345        verbose++;
346        out = stdout;
347    }
348    else {
349            mktemp (tmpfil);
350            if ((out = fopen (tmpfil, "w")) == NULL)
351                adios (tmpfil, "unable to create");
352            chmod (tmpfil, 0600);
353        }
354
355    hdrtab = (msgstate == normal) ? NHeaders : RHeaders;
356
357    for (compnum = 1, state = FLD;;) {
358        switch (state = m_getfld (state, name, buf, sizeof(buf), in)) {
359            case FLD:
360                compnum++;
361                putfmt (name, buf, out);
362                continue;
363
364            case FLDPLUS:
365                compnum++;
366                cp = add (buf, cp);
367                while (state == FLDPLUS) {
368                    state = m_getfld (state, name, buf, sizeof(buf), in);
369                    cp = add (buf, cp);
370                }
371                putfmt (name, cp, out);
372                free (cp);
373                continue;
374
375            case BODY:
376                finish_headers (out);
377                fprintf (out, "\n%s", buf);
378                if(whomflg == 0)
379                    while (state == BODY) {
380                        state = m_getfld (state, name, buf, sizeof(buf), in);
381                        fputs (buf, out);
382                    }
383                break;
384
385            case FILEEOF:
386                finish_headers (out);
387                break;
388
389            case LENERR:
390            case FMTERR:
391                adios (NULL, "message format error in component #%d",
392                        compnum);
393
394            default:
395                adios (NULL, "getfld() returned %d", state);
396        }
397        break;
398    }
399
400    fclose (in);
401    if (backflg && !whomflg) {
402        strncpy (buf, m_backup (msg), sizeof(buf));
403        if (rename (msg, buf) == NOTOK)
404            advise (buf, "unable to rename %s to", msg);
405    }
406
407    if (debug) {
408        done (0);
409    }
410    else
411        fclose (out);
412
413    file (tmpfil);
414
415    /*
416     * re-open the temp file, unlink it and exec sendmail, giving it
417     * the msg temp file as std in.
418     */
419    if ( freopen( tmpfil, "r", stdin) == NULL)
420        adios (tmpfil, "can't reopen for sendmail");
421    if (rmflg)
422        unlink (tmpfil);
423
424    argp = sargv;
425    *argp++ = "send-mail";
426    *argp++ = "-m";     /* send to me too */
427    *argp++ = "-t";     /* read msg for recipients */
428    *argp++ = "-i";     /* don't stop on "." */
429    if (whomflg)
430        *argp++ = "-bv";
431    if (watch || verbose)
432        *argp++ = "-v";
433    *argp = NULL;
434
435    if (pushflg && !(watch || verbose)) {
436        /* fork to a child to run sendmail */
437        for (i=0; (pid = vfork()) == NOTOK && i < 5; i++)
438            sleep(5);
439        switch (pid) {
440            case NOTOK:
441                fprintf (verbose ? stdout : stderr, "%s: can't fork to %s\n",
442                         invo_name, sendmail);
443                exit(-1);
444            case OK:
445                /* we're the child .. */
446                break;
447            default:
448                exit(0);
449        }
450    }
451    execv ( sendmail, sargv);
452    adios ( sendmail, "can't exec");
453}
454
455/* DRAFT GENERATION */
456
457static void
458putfmt (char *name, char *str, FILE *out)
459{
460    int i;
461    char *cp, *pp;
462    struct headers *hdr;
463
464    while (*str == ' ' || *str == '\t')
465        str++;
466
467    if ((i = get_header (name, hdrtab)) == NOTOK) {
468        fprintf (out, "%s: %s", name, str);
469        return;
470    }
471
472    hdr = &hdrtab[i];
473    if (hdr->flags & HIGN)
474        return;
475    if (hdr->flags & HBAD) {
476        advise (NULL, "illegal header line -- %s:", name);
477        badmsg++;
478        return;
479    }
480    msgflags |= hdr->set;
481
482    if (hdr->flags & HSUB)
483        subject = subject ? add (str, add ("\t", subject)) : getcpy (str);
484
485    if (hdr->flags & HFCC) {
486        if ((cp = strrchr(str, '\n')))
487            *cp = 0;
488        for (cp = pp = str; cp = strchr(pp, ','); pp = cp) {
489            *cp++ = 0;
490            insert_fcc (hdr, pp);
491        }
492        insert_fcc (hdr, pp);
493        return;
494    }
495
496#ifdef notdef
497    if (hdr->flags & HBCC) {
498        insert_bcc(str);
499        return;
500    }
501#endif  /* notdef */
502
503    if (*str != '\n' && *str != '\0')
504        if (aliasflg && hdr->flags & HTRY) {
505            /* this header contains address(es) that we have to do
506             * alias expansion on.  Because of the saved state in
507             * getname we have to put all the addresses into a list.
508             * We then let putadr munch on that list, possibly
509             * expanding aliases.
510             */
511            register struct mailname *f = 0;
512            register struct mailname *mp = 0;
513
514            while ((cp = getname(str))) {
515                mp = getm( cp, NULL, 0, AD_HOST, NULL);
516                if (mp == NULL)
517                    continue;
518                if (f == 0) {
519                    f = mp;
520                    mp->m_next = mp;
521                } else {
522                    mp->m_next = f->m_next;
523                    f->m_next = mp;
524                    f = mp;
525                }
526            }
527            f = mp->m_next; mp->m_next = 0;
528            putadr( name, f );
529        } else {
530            fprintf (out, "%s: %s", name, str );
531        }
532}
533
534
535static void
536start_headers (void)
537{
538    char *cp;
539    char sigbuf[BUFSIZ];
540
541    strncpy(from, getusername(), sizeof(from));
542
543    if ((cp = getfullname ()) && *cp) {
544        strncpy (sigbuf, cp, sizeof(sigbuf));
545        snprintf (signature, sizeof(signature), "%s <%s>", sigbuf,  from);
546    }
547    else
548        snprintf (signature, sizeof(signature), "%s",  from);
549}
550
551
552static void
553finish_headers (FILE *out)
554{
555    switch (msgstate) {
556        case normal:
557            if (!(msgflags & MDAT))
558                fprintf (out, "Date: %s\n", dtimenow (0));
559            if (msgflags & MFRM)
560                fprintf (out, "Sender: %s\n", from);
561            else
562                fprintf (out, "From: %s\n", signature);
563#ifdef notdef
564            if (!(msgflags & MVIS))
565                fprintf (out, "Bcc: Blind Distribution List: ;\n");
566#endif  /* notdef */
567            break;
568
569        case resent:
570            if (!(msgflags & MRDT))
571                fprintf (out, "Resent-Date: %s\n", dtimenow(0));
572            if (msgflags & MRFM)
573                fprintf (out, "Resent-Sender: %s\n", from);
574            else
575                fprintf (out, "Resent-From: %s\n", signature);
576#ifdef notdef
577            if (!(msgflags & MVIS))
578                fprintf (out, "Resent-Bcc: Blind Re-Distribution List: ;\n");
579#endif  /* notdef */
580            break;
581    }
582
583    if (badmsg)
584        adios (NULL, "re-format message and try again");
585}
586
587
588static int
589get_header (char *header, struct headers *table)
590{
591    struct headers *h;
592
593    for (h = table; h->value; h++)
594        if (!strcasecmp (header, h->value))
595            return (h - table);
596
597    return NOTOK;
598}
599
600
601/*
602 * output the address list for header "name".  The address list
603 * is a linked list of mailname structs.  "nl" points to the head
604 * of the list.  Alias substitution should be done on nl.
605 */
606static void
607putadr (char *name, struct mailname *nl)
608{
609    register struct mailname *mp, *mp2;
610    register int linepos;
611    register char *cp;
612    int namelen;
613
614    fprintf (out, "%s: ", name);
615    namelen = strlen(name) + 2;
616    linepos = namelen;
617
618    for (mp = nl; mp; ) {
619        if (linepos > MAX_SM_FIELD) {
620                fprintf (out, "\n%s: ", name);
621                linepos = namelen;
622        }
623        if (mp->m_nohost) {
624            /* a local name - see if it's an alias */
625            cp = akvalue(mp->m_mbox);
626            if (cp == mp->m_mbox)
627                /* wasn't an alias - use what the user typed */
628                linepos = putone( mp->m_text, linepos, namelen );
629            else
630                /* an alias - expand it */
631                while ((cp = getname(cp))) {
632                    if (linepos > MAX_SM_FIELD) {
633                            fprintf (out, "\n%s: ", name);
634                            linepos = namelen;
635                    }
636                    mp2 = getm( cp, NULL, 0, AD_HOST, NULL);
637                    if (mp2 == NULL)
638                        continue;
639                    if (akvisible()) {
640                        mp2->m_pers = getcpy(mp->m_mbox);
641                        linepos = putone( adrformat(mp2), linepos, namelen );
642                    } else {
643                        linepos = putone( mp2->m_text, linepos, namelen );
644                    }
645                    mnfree( mp2 );
646                }
647        } else {
648            /* not a local name - use what the user typed */
649            linepos = putone( mp->m_text, linepos, namelen );
650        }
651        mp2 = mp;
652        mp = mp->m_next;
653        mnfree( mp2 );
654    }
655    putc( '\n', out );
656}
657
658static int
659putone (char *adr, int pos, int indent)
660{
661    register int len;
662    static int linepos;
663
664    len = strlen( adr );
665    if (pos == indent)
666        linepos = pos;
667    else if ( linepos+len > outputlinelen ) {
668        fprintf ( out, ",\n%*s", indent, "");
669        linepos = indent;
670        pos += indent + 2;
671    }
672    else {
673        fputs( ", ", out );
674        linepos += 2;
675        pos += 2;
676    }
677    fputs( adr, out );
678
679    linepos += len;
680    return (pos+len);
681}
682
683
684static void
685insert_fcc (struct headers *hdr, char *pp)
686{
687    char   *cp;
688
689    for (cp = pp; isspace (*cp); cp++)
690        continue;
691    for (pp += strlen (pp) - 1; pp > cp && isspace (*pp); pp--)
692        continue;
693    if (pp >= cp)
694        *++pp = 0;
695    if (*cp == 0)
696        return;
697
698    if (fccind >= FCCS)
699        adios (NULL, "too many %ss", hdr->value);
700    fccfold[fccind++] = getcpy (cp);
701}
702
703#if 0
704/* BCC GENERATION */
705
706static void
707make_bcc_file (void)
708{
709    pid_t child_id;
710    int fd, i, status;
711    char *vec[6];
712    FILE * in, *out;
713
714    mktemp (bccfil);
715    if ((out = fopen (bccfil, "w")) == NULL)
716        adios (bccfil, "unable to create");
717    chmod (bccfil, 0600);
718
719    fprintf (out, "Date: %s\n", dtimenow (0));
720    fprintf (out, "From: %s\n", signature);
721    if (subject)
722        fprintf (out, "Subject: %s", subject);
723    fprintf (out, "BCC:\n\n------- Blind-Carbon-Copy\n\n");
724    fflush (out);
725
726    if (filter == NULL) {
727        if ((fd = open (tmpfil, O_RDONLY)) == NOTOK)
728            adios (NULL, "unable to re-open");
729        cpydgst (fd, fileno (out), tmpfil, bccfil);
730        close (fd);
731    }
732    else {
733        vec[0] = r1bindex (mhlproc, '/');
734
735        for (i = 0; (child_id = vfork()) == NOTOK && i < 5; i++)
736            sleep (5);
737        switch (child_id) {
738            case NOTOK:
739                adios ("vfork", "unable to");
740
741            case OK:
742                dup2 (fileno (out), 1);
743
744                i = 1;
745                vec[i++] = "-forward";
746                vec[i++] = "-form";
747                vec[i++] = filter;
748                vec[i++] = tmpfil;
749                vec[i] = NULL;
750
751                execvp (mhlproc, vec);
752                adios (mhlproc, "unable to exec");
753
754            default:
755                if (status = pidwait(child_id, OK))
756                    admonish (NULL, "%s lost (status=0%o)", vec[0], status);
757                break;
758        }
759    }
760
761    fseek (out, 0L, SEEK_END);
762    fprintf (out, "\n------- End of Blind-Carbon-Copy\n");
763    fclose (out);
764}
765#endif  /* if 0 */
766
767/* FCC INTERACTION */
768
769static void
770file (char *path)
771{
772    int i;
773
774    if (fccind == 0)
775        return;
776
777    for (i = 0; i < fccind; i++)
778        if (whomflg)
779            printf ("Fcc: %s\n", fccfold[i]);
780        else
781            fcc (path, fccfold[i]);
782}
783
784
785static void
786fcc (char *file, char *folder)
787{
788    pid_t child_id;
789    int i, status;
790    char fold[BUFSIZ];
791
792    if (verbose)
793        printf ("%sFcc: %s\n", msgstate == resent ? "Resent-" : "", folder);
794    fflush (stdout);
795
796    for (i = 0; (child_id = vfork()) == NOTOK && i < 5; i++)
797        sleep (5);
798    switch (child_id) {
799        case NOTOK:
800            if (!verbose)
801                fprintf (stderr, "  %sFcc %s: ",
802                        msgstate == resent ? "Resent-" : "", folder);
803            fprintf (verbose ? stdout : stderr, "no forks, so not ok\n");
804            break;
805
806        case OK:
807            snprintf (fold, sizeof(fold), "%s%s",
808                    *folder == '+' || *folder == '@' ? "" : "+", folder);
809            execlp (fileproc, r1bindex (fileproc, '/'),
810                    "-link", "-file", file, fold, NULL);
811            _exit (-1);
812
813        default:
814            if ((status = pidwait(child_id, OK))) {
815                if (!verbose)
816                    fprintf (stderr, "  %sFcc %s: ",
817                            msgstate == resent ? "Resent-" : "", folder);
818                fprintf (verbose ? stdout : stderr,
819                        " errored (0%o)\n", status);
820            }
821    }
822
823    fflush (stdout);
824}
825
826
827#if 0
828
829/*
830 * TERMINATION
831 */
832
833static void
834die (char *what, char *fmt, ...)
835{
836    va_list ap;
837
838    va_start(ap, fmt);
839    advertise (what, NULL, fmt, ap);
840    va_end(ap);
841
842    done (1);
843}
844#endif
Note: See TracBrowser for help on using the repository browser.