Annotation of 43BSD/contrib/mh/uip/sendsbr.c, revision 1.1.1.1

1.1       root        1: /* sendsbr.c - routines to help WhatNow/Send along */
                      2: 
                      3: #include "../h/mh.h"
                      4: #include <setjmp.h>
                      5: #include <stdio.h>
                      6: #include <signal.h>
                      7: #include <sys/types.h>
                      8: #include <sys/stat.h>
                      9: 
                     10: /*  */
                     11: 
                     12: int     debugsw = 0;           /* global */
                     13: int     forwsw = 1;
                     14: int     inplace = 0;
                     15: int     pushsw = 0;
                     16: int     unique = 0;
                     17: 
                     18: char   *altmsg = NULL;         /*  .. */
                     19: char   *annotext = NULL;
                     20: char   *distfile = NULL;
                     21: 
                     22: 
                     23: static int armed = 0;
                     24: static jmp_buf env;
                     25: 
                     26: 
                     27: char   *getusr ();
                     28: long   lseek ();
                     29: 
                     30: /*  */
                     31: 
                     32: int    sendsbr (vec, vecp, drft, st)
                     33: register char **vec,
                     34:               *drft;
                     35: int     vecp;
                     36: register struct stat *st;
                     37: {
                     38:     int     status;
                     39: 
                     40:     armed++;
                     41:     switch (setjmp (env)) {
                     42:        case OK: 
                     43:            status = sendaux (vec, vecp, drft, st) ? NOTOK : OK;
                     44:            break;
                     45: 
                     46:        default: 
                     47:            status = DONE;
                     48:            break;
                     49:     }
                     50:     armed = 0;
                     51:     if (distfile)
                     52:        (void) unlink (distfile);
                     53: 
                     54:     return status;
                     55: }
                     56: 
                     57: /*  */
                     58: 
                     59: int    sendaux (vec, vecp, drft, st)
                     60: register char **vec,
                     61:               *drft;
                     62: int     vecp;
                     63: register struct stat *st;
                     64: {
                     65:     int     child_id,
                     66:             i,
                     67:            status,
                     68:             fd,
                     69:             fd2;
                     70:     char    backup[BUFSIZ],
                     71:             buf[BUFSIZ],
                     72:             file[BUFSIZ];
                     73: 
                     74:     fd = pushsw ? tmp_fd () : NOTOK;
                     75:     fd2 = NOTOK;
                     76: 
                     77:     if (pushsw && unique) {
                     78:        if (rename (drft, strcpy (file, m_scratch (drft, invo_name)))
                     79:                == NOTOK)
                     80:            adios (file, "unable to rename %s to", drft);
                     81:        drft = file;
                     82:     }
                     83:     vec[vecp++] = drft;
                     84:     if (annotext)
                     85:        if ((fd2 = tmp_fd ()) != NOTOK) {
                     86:            vec[vecp++] = "-idanno";
                     87:            (void) sprintf (buf, "%d", fd2);
                     88:            vec[vecp++] = buf;
                     89:        }
                     90:        else
                     91:            admonish (NULLCP, "unable to create file for annotation list");
                     92:     if (distfile && distout (drft, distfile, backup) == NOTOK)
                     93:        done (1);
                     94:     vec[vecp] = NULL;
                     95: 
                     96:     for (i = 0; (child_id = vfork ()) == NOTOK && i < 5; i++)
                     97:        sleep (5);
                     98:     switch (child_id) {
                     99:        case NOTOK:             /* oops */
                    100:            adios ("fork", "unable to");
                    101: 
                    102:        case OK:                /* send it */
                    103:            if (fd != NOTOK) {
                    104:                (void) dup2 (fd, fileno (stdout));
                    105:                (void) dup2 (fd, fileno (stderr));
                    106:                (void) close (fd);
                    107:            }
                    108:            execvp (postproc, vec);
                    109:            fprintf (stderr, "unable to exec ");
                    110:            perror (postproc);
                    111:            _exit (-1);
                    112: 
                    113:        default:                /* wait for it */
                    114:            if ((status = pidwait (child_id, NOTOK)) == 0) {
                    115:                if (annotext && fd2 != NOTOK)
                    116:                    anno (fd2, st);
                    117:                if (rename (drft, strcpy (buf, m_backup (drft))) == NOTOK)
                    118:                    advise (buf, "unable to rename %s to", drft);
                    119:            }
                    120:            else {
                    121:                if (fd != NOTOK) {
                    122:                    alert (drft, fd);
                    123:                    (void) close (fd);
                    124:                }
                    125:                else
                    126:                    advise (NULLCP, "message not delivered to anyone");
                    127:                if (fd2 != NOTOK)
                    128:                    (void) close (fd2);
                    129:                if (distfile) {
                    130:                    (void) unlink (drft);
                    131:                    if (rename (backup, drft) == NOTOK)
                    132:                        advise (drft, "unable to rename %s to", backup);
                    133:                }
                    134:            }
                    135:            break;
                    136:     }
                    137: 
                    138:     return status;
                    139: }
                    140: 
                    141: /*  */
                    142: 
                    143: static  alert (file, out)
                    144: register char   *file;
                    145: int     out;
                    146: {
                    147:     int     child_id,
                    148:             i,
                    149:             in;
                    150:     char    buf[BUFSIZ];
                    151: 
                    152:     for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
                    153:        sleep (5);
                    154:     switch (child_id) {
                    155:        case NOTOK:             /* oops */
                    156:            advise ("fork", "unable to");
                    157: 
                    158:        case OK:                /* send it */
                    159:            (void) signal (SIGHUP, SIG_IGN);
                    160:            (void) signal (SIGINT, SIG_IGN);
                    161:            (void) signal (SIGQUIT, SIG_IGN);
                    162:            (void) signal (SIGTERM, SIG_IGN);
                    163:            if (forwsw)
                    164:                if ((in = open (file, 0)) == NOTOK)
                    165:                    admonish (file, "unable to re-open");
                    166:                else {
                    167:                    (void) lseek (out, 0L, 2);
                    168:                    (void) strcpy (buf, "\nMessage not delivered to anyone.\n");
                    169:                    (void) write (out, buf, strlen (buf));
                    170:                    (void) strcpy (buf, "\n------- Unsent Draft\n\n");
                    171:                    (void) write (out, buf, strlen (buf));
                    172:                    cpydgst (in, out, file, "temporary file");
                    173:                    (void) close (in);
                    174:                    (void) strcpy (buf, "\n------- End of Unsent Draft\n");
                    175:                    (void) write (out, buf, strlen (buf));
                    176:                    if (rename (file, strcpy (buf, m_backup (file))) == NOTOK)
                    177:                        admonish (buf, "unable to rename %s to", file);
                    178:                }
                    179:            (void) lseek (out, 0L, 0);
                    180:            (void) dup2 (out, fileno (stdin));
                    181:            (void) close (out);
                    182:            (void) sprintf (buf, "send failed on %s",
                    183:                        forwsw ? "enclosed draft" : file);
                    184: 
                    185:            execlp (mailproc, r1bindex (mailproc, '/'), getusr (),
                    186:                    "-subject", buf, NULLCP);
                    187:            fprintf (stderr, "unable to exec ");
                    188:            perror (mailproc);
                    189:            _exit (-1);
                    190: 
                    191:        default:                /* no waiting... */
                    192:            break;
                    193:     }
                    194: }
                    195: 
                    196: /*  */
                    197: 
                    198: static int  tmp_fd () {
                    199:     int     fd;
                    200:     char    tmpfil[BUFSIZ];
                    201: 
                    202:     (void) strcpy (tmpfil, m_tmpfil (invo_name));
                    203:     if ((fd = creat (tmpfil, 0600)) == NOTOK)
                    204:        return NOTOK;
                    205:     (void) close (fd);
                    206: 
                    207:     if ((fd = open (tmpfil, 2)) == NOTOK)
                    208:        return NOTOK;
                    209:     if (debugsw)
                    210:        advise (NULLCP, "temporary file %s selected", tmpfil);
                    211:     else
                    212:        if (unlink (tmpfil) == NOTOK)
                    213:            advise (tmpfil, "unable to remove");
                    214: 
                    215:     return fd;
                    216: }
                    217: 
                    218: /*  */
                    219: 
                    220: static anno (fd, st)
                    221: int    fd;
                    222: register struct stat *st;
                    223: {
                    224:     int     child_id;
                    225:     int     (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
                    226:     static char *cwd = NULL;
                    227:     struct stat st2;
                    228: 
                    229:     if (altmsg &&
                    230:            (stat (altmsg, &st2) == NOTOK
                    231:                || st -> st_mtime != st2.st_mtime
                    232:                || st -> st_dev != st2.st_dev
                    233:                || st -> st_ino != st2.st_ino)) {
                    234:        if (debugsw)
                    235:            admonish (NULLCP, "$mhaltmsg mismatch");
                    236:        return;
                    237:     }
                    238: 
                    239:     child_id = debugsw ? NOTOK : fork ();
                    240:     switch (child_id) {
                    241:        case NOTOK:             /* oops */
                    242:            if (!debugsw)
                    243:                advise (NULLCP,
                    244:                            "unable to fork, so doing annotations by hand...");
                    245:            if (cwd == NULL)
                    246:                cwd = getcpy (pwd ());
                    247: 
                    248:        case OK: 
                    249:            hstat = signal (SIGHUP, SIG_IGN);
                    250:            istat = signal (SIGINT, SIG_IGN);
                    251:            qstat = signal (SIGQUIT, SIG_IGN);
                    252:            tstat = signal (SIGTERM, SIG_IGN);
                    253:            annoaux (fd);
                    254:            if (child_id == OK)
                    255:                _exit (0);
                    256:            (void) signal (SIGHUP, hstat);
                    257:            (void) signal (SIGINT, istat);
                    258:            (void) signal (SIGQUIT, qstat);
                    259:            (void) signal (SIGTERM, tstat);
                    260:            (void) chdir (cwd);
                    261:            break;
                    262: 
                    263:        default:                /* no waiting... */
                    264:            (void) close (fd);
                    265:            break;
                    266:     }
                    267: }
                    268: 
                    269: /*  */
                    270: 
                    271: static annoaux (fd)
                    272: int    fd;
                    273: {
                    274:     int            fd2,
                    275:            fd3,
                    276:            msgnum;
                    277:     char   *cp,
                    278:           *folder,
                    279:           *maildir,
                    280:             buffer[BUFSIZ],
                    281:           **ap;
                    282:     FILE   *fp;
                    283:     struct msgs *mp;
                    284: 
                    285:     if ((folder = getenv ("mhfolder")) == NULL || *folder == NULL) {
                    286:        if (debugsw)
                    287:            admonish (NULLCP, "$mhfolder not set");
                    288:        return;
                    289:     }
                    290:     maildir = m_maildir (folder);
                    291:     if (chdir (maildir) == NOTOK) {
                    292:        if (debugsw)
                    293:            admonish (maildir, "unable to change directory to");
                    294:        return;
                    295:     }
                    296:     if (!(mp = m_gmsg (folder))) {
                    297:        if (debugsw)
                    298:            admonish (NULLCP, "unable to read folder %s");
                    299:        return;
                    300:     }
                    301:     if (mp -> hghmsg == 0) {
                    302:        if (debugsw)
                    303:            admonish (NULLCP, "no messages in %s", folder);
                    304:        goto oops;
                    305:     }
                    306: 
                    307:     if ((cp = getenv ("mhmessages")) == NULL || *cp == NULL) {
                    308:        if (debugsw)
                    309:            admonish (NULLCP, "$mhmessages not set");
                    310:        goto oops;
                    311:     }
                    312:     if (!debugsw                       /* MOBY HACK... */
                    313:            && pushsw
                    314:            && (fd3 = open ("/dev/null", 2)) != NOTOK
                    315:            && (fd2 = dup (fileno (stderr))) != NOTOK) {
                    316:        (void) dup2 (fd3, fileno (stderr));
                    317:        (void) close (fd3);
                    318:     }
                    319:     else
                    320:        fd2 = NOTOK;
                    321:     for (ap = brkstring (cp = getcpy (cp), " ", NULLCP); *ap; ap++)
                    322:        (void) m_convert (mp, *ap);
                    323:     free (cp);
                    324:     if (fd2 != NOTOK)
                    325:        (void) dup2 (fd2, fileno (stderr));
                    326:     if (mp -> numsel == 0) {
                    327:        if (debugsw)
                    328:            admonish (NULLCP, "no messages to annotate");
                    329:        goto oops;
                    330:     }
                    331: 
                    332:     (void) lseek (fd, 0L, 0);
                    333:     if ((fp = fdopen (fd, "r")) == NULL) {
                    334:        if (debugsw)
                    335:            admonish (NULLCP, "unable to fdopen annotation list");
                    336:        goto oops;
                    337:     }
                    338:     cp = NULL;
                    339:     while (fgets (buffer, sizeof buffer, fp) != NULL)
                    340:        cp = add (buffer, cp);
                    341:     (void) fclose (fp);
                    342: 
                    343:     if (debugsw)
                    344:        advise (NULLCP, "annotate%s with %s: \"%s\"",
                    345:                inplace ? " inplace" : "", annotext, cp);
                    346:     for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                    347:        if (mp -> msgstats[msgnum] & SELECTED) {
                    348:            if (debugsw)
                    349:                advise (NULLCP, "annotate message %d", msgnum);
                    350:            (void) annotate (m_name (msgnum), annotext, cp, inplace);
                    351:        }
                    352: 
                    353:     free (cp);
                    354: 
                    355: oops: ;
                    356:     m_fmsg (mp);
                    357: }
                    358: 
                    359: /*  */
                    360: 
                    361: void done (status)
                    362: int    status;
                    363: {
                    364:     if (armed)
                    365:        longjmp (env, status ? status : NOTOK);
                    366: 
                    367:     exit (status);
                    368: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.