Annotation of 43BSDReno/contrib/mh/uip/forw.c, revision 1.1.1.1

1.1       root        1: /* forw.c - forward messages */
                      2: 
                      3: #include "../h/mh.h"
                      4: #include "../h/formatsbr.h"
                      5: #include "../zotnet/tws.h"
                      6: #include <stdio.h>
                      7: #include <sys/types.h>
                      8: #include <sys/stat.h>
                      9: 
                     10: 
                     11: #define        IFMT    "digest-issue-%s"
                     12: #define        VFMT    "digest-volume-%s"
                     13: 
                     14: /*  */
                     15: 
                     16: static struct swit switches[] = {
                     17: #define        ANNOSW  0
                     18:     "annotate", 0,
                     19: #define        NANNOSW 1
                     20:     "noannotate", 0,
                     21: 
                     22: #define        DFOLDSW 2
                     23:     "draftfolder +folder", 0,
                     24: #define        DMSGSW  3
                     25:     "draftmessage msg", 0,
                     26: #define        NDFLDSW 4
                     27:     "nodraftfolder", 0,
                     28: 
                     29: #define        EDITRSW 5
                     30:     "editor editor", 0,
                     31: #define        NEDITSW 6
                     32:     "noedit", 0,
                     33: 
                     34: #define        FILTSW  7
                     35:     "filter filterfile", 0,
                     36: #define        FORMSW  8
                     37:     "form formfile", 0,
                     38: 
                     39: #define        FRMTSW  9
                     40:     "format", 5,
                     41: #define        NFRMTSW 10
                     42:     "noformat", 7,
                     43: 
                     44: #define        INPLSW  11
                     45:     "inplace", 0,
                     46: #define        NINPLSW 12
                     47:     "noinplace", 0,
                     48: 
                     49: #define        DGSTSW  13
                     50:     "digest list", 0,
                     51: #define        ISSUESW 14
                     52:     "issue number", 0,
                     53: #define        VOLUMSW 15
                     54:     "volume number", 0,
                     55: 
                     56: #define        WHATSW  16
                     57:     "whatnowproc program", 0,
                     58: #define        NWHATSW 17
                     59:     "nowhatnowproc", 0,
                     60: 
                     61: #define        DASHSW  18
                     62:     "dashmunging", 4,
                     63: #define        NDASHSW 19
                     64:     "nodashmunging", 6,
                     65: 
                     66: #define        HELPSW  20
                     67:     "help", 4,
                     68: 
                     69: #define        FILESW  21
                     70:     "file file", -4,           /* interface from msh */
                     71: 
                     72: #ifdef MHE
                     73: #define        BILDSW  22
                     74:     "build", -5,               /* interface from mhe */
                     75: #endif MHE
                     76: 
                     77:     NULL, NULL
                     78: };
                     79: 
                     80: /*  */
                     81: 
                     82: static struct swit aqrnl[] = {
                     83: #define        NOSW    0
                     84:     "quit", 0,
                     85: #define        YESW    1
                     86:     "replace", 0,
                     87: #define        LISTDSW 2
                     88:     "list", 0,
                     89: #define        REFILSW 3
                     90:     "refile +folder", 0,
                     91: #define NEWSW  4
                     92:     "new", 0,
                     93: 
                     94:     NULL, NULL
                     95: };
                     96: 
                     97: 
                     98: static struct swit aqrl[] = {
                     99:     "quit", 0,
                    100:     "replace", 0,
                    101:     "list", 0,
                    102:     "refile +folder", 0,
                    103: 
                    104:     NULL, NULL
                    105: };
                    106: 
                    107: /*  */
                    108: 
                    109: static char drft[BUFSIZ];
                    110: 
                    111: static char delim3[] =
                    112:     "\n------------------------------------------------------------\n\n";
                    113: static char delim4[] = "\n------------------------------\n\n";
                    114: 
                    115: 
                    116: static struct msgs *mp = NULL;         /* used a lot */
                    117: 
                    118: 
                    119: long lseek(), time();
                    120: 
                    121: static void mhl_draft(), copy_draft();
                    122: static int build_form();
                    123: 
                    124: /*  */
                    125: 
                    126: /* ARGSUSED */
                    127: 
                    128: main(argc, argv)
                    129:        int argc;
                    130:        char *argv[];
                    131: {
                    132:     int     msgp = 0,
                    133:             anot = 0,
                    134:             inplace = 0,
                    135:            issue = 0,
                    136:            volume = 0,
                    137:            dashflg = 1,
                    138: #ifdef MHE
                    139:            buildsw = 0,
                    140: #endif MHE
                    141:            nedit = 0,
                    142:            nwhat = 0,
                    143:            i,
                    144:             in,
                    145:             out,
                    146:            isdf = 0,
                    147:             msgnum;
                    148:     char   *cp,
                    149:           *cwd,
                    150:            *maildir,
                    151:           *dfolder = NULL,
                    152:           *dmsg = NULL,
                    153:           *digest = NULL,
                    154:            *ed = NULL,
                    155:            *file = NULL,
                    156:           *filter = NULL,
                    157:            *folder = NULL,
                    158:            *form = NULL,
                    159:             buf[100],
                    160:            value[10],
                    161:           **ap,
                    162:           **argp,
                    163:            *arguments[MAXARGS],
                    164:            *msgs[MAXARGS];
                    165:     struct stat st;
                    166: 
                    167:     invo_name = r1bindex (argv[0], '/');
                    168:     if ((cp = m_find (invo_name)) != NULL) {
                    169:        ap = brkstring (cp = getcpy (cp), " ", "\n");
                    170:        ap = copyip (ap, arguments);
                    171:     }
                    172:     else
                    173:        ap = arguments;
                    174:     (void) copyip (argv + 1, ap);
                    175:     argp = arguments;
                    176: 
                    177: /*  */
                    178: 
                    179:     while (cp = *argp++) {
                    180:        if (*cp == '-')
                    181:            switch (smatch (++cp, switches)) {
                    182:                case AMBIGSW:
                    183:                    ambigsw (cp, switches);
                    184:                    done (1);
                    185:                case UNKWNSW:
                    186:                    adios (NULLCP, "-%s unknown", cp);
                    187:                case HELPSW:
                    188:                    (void) sprintf (buf, "%s [+folder] [msgs] [switches]",
                    189:                        invo_name);
                    190:                    help (buf, switches);
                    191:                    done (1);
                    192: 
                    193:                case ANNOSW:
                    194:                    anot++;
                    195:                    continue;
                    196:                case NANNOSW:
                    197:                    anot = 0;
                    198:                    continue;
                    199: 
                    200:                case EDITRSW:
                    201:                    if (!(ed = *argp++) || *ed == '-')
                    202:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    203:                    nedit = 0;
                    204:                    continue;
                    205:                case NEDITSW:
                    206:                    nedit++;
                    207:                    continue;
                    208: 
                    209:                case WHATSW:
                    210:                    if (!(whatnowproc = *argp++) || *whatnowproc == '-')
                    211:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    212:                    nwhat = 0;
                    213:                    continue;
                    214: #ifdef MHE
                    215:                case BILDSW:
                    216:                    buildsw++;  /* fall... */
                    217: #endif MHE
                    218:                case NWHATSW:
                    219:                    nwhat++;
                    220:                    continue;
                    221: 
                    222:                case FILESW:
                    223:                    if (file)
                    224:                        adios (NULLCP, "only one file at a time!");
                    225:                    if (!(cp = *argp++) || *cp == '-')
                    226:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    227:                    file = path (cp, TFILE);
                    228:                    continue;
                    229:                case FILTSW:
                    230:                    if (!(cp = *argp++) || *cp == '-')
                    231:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    232:                    filter = getcpy (libpath (cp));
                    233:                    continue;
                    234:                case FORMSW:
                    235:                    if (!(form = *argp++) || *form == '-')
                    236:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    237:                    continue;
                    238: 
                    239:                case FRMTSW:
                    240:                    filter = getcpy (libpath (mhlforward));
                    241:                    continue;
                    242:                case NFRMTSW:
                    243:                    filter = NULL;
                    244:                    continue;
                    245: 
                    246:                case INPLSW:
                    247:                    inplace++;
                    248:                    continue;
                    249:                case NINPLSW:
                    250:                    inplace = 0;
                    251:                    continue;
                    252: 
                    253:                case DGSTSW:
                    254:                    if (!(digest = *argp++) || *digest == '-')
                    255:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    256:                    continue;
                    257:                case ISSUESW:
                    258:                    if (!(cp = *argp++) || *cp == '-')
                    259:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    260:                    if ((issue = atoi (cp)) < 1)
                    261:                        adios (NULLCP, "bad argument %s %s", argp[-2], cp);
                    262:                    continue;
                    263:                case VOLUMSW:
                    264:                    if (!(cp = *argp++) || *cp == '-')
                    265:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    266:                    if ((volume = atoi (cp)) < 1)
                    267:                        adios (NULLCP, "bad argument %s %s", argp[-2], cp);
                    268:                    continue;
                    269: 
                    270:                case DFOLDSW:
                    271:                    if (dfolder)
                    272:                        adios (NULLCP, "only one draft folder at a time!");
                    273:                    if (!(cp = *argp++) || *cp == '-')
                    274:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    275:                    dfolder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp,
                    276:                                    *cp != '@' ? TFOLDER : TSUBCWF);
                    277:                    continue;
                    278:                case DMSGSW:
                    279:                    if (dmsg)
                    280:                        adios (NULLCP, "only one draft message at a time!");
                    281:                    if (!(dmsg = *argp++) || *dmsg == '-')
                    282:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    283:                    continue;
                    284:                case NDFLDSW:
                    285:                    dfolder = NULL;
                    286:                    isdf = NOTOK;
                    287:                    continue;
                    288: 
                    289:                case DASHSW:
                    290:                    dashflg++;
                    291:                    continue;
                    292:                case NDASHSW:
                    293:                    dashflg = 0;
                    294:                    continue;
                    295:            }
                    296:        if (*cp == '+' || *cp == '@') {
                    297:            if (folder)
                    298:                adios (NULLCP, "only one folder at a time!");
                    299:            else
                    300:                folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
                    301:        }
                    302:        else
                    303:            msgs[msgp++] = cp;
                    304:     }
                    305: 
                    306: /*  */
                    307: 
                    308:     cwd = getcpy (pwd ());
                    309: 
                    310:     if (!m_find ("path"))
                    311:        free (path ("./", TFOLDER));
                    312:     if (file && (msgp || folder))
                    313:        adios (NULLCP, "can't mix files and folders/msgs");
                    314: 
                    315: try_it_again: ;
                    316: #ifndef MHE
                    317:     (void) strcpy (drft, m_draft (dfolder, dmsg, NOUSE, &isdf));
                    318:     if (stat (drft, &st) != NOTOK)
                    319: #else  MHE
                    320:     (void) strcpy (drft, buildsw ? m_maildir ("draft")
                    321:                          : m_draft (dfolder, NULLCP, NOUSE, &isdf));
                    322:     if (!buildsw && stat (drft, &st) != NOTOK)
                    323: #endif MHE
                    324:                                                {
                    325:        printf ("Draft \"%s\" exists (%ld bytes).", drft, st.st_size);
                    326:        for (i = LISTDSW; i != YESW;) {
                    327:            if (!(argp = getans ("\nDisposition? ", isdf ? aqrnl : aqrl)))
                    328:                done (1);
                    329:            switch (i = smatch (*argp, isdf ? aqrnl : aqrl)) {
                    330:                case NOSW:
                    331:                    done (0);
                    332:                case NEWSW:
                    333:                    dmsg = NULL;
                    334:                    goto try_it_again;
                    335:                case YESW:
                    336:                    break;
                    337:                case LISTDSW:
                    338:                    (void) showfile (++argp, drft);
                    339:                    break;
                    340:                case REFILSW:
                    341:                    if (refile (++argp, drft) == 0)
                    342:                        i = YESW;
                    343:                    break;
                    344:                default:
                    345:                    advise (NULLCP, "say what?");
                    346:                    break;
                    347:            }
                    348:        }
                    349:     }
                    350: 
                    351: /*  */
                    352: 
                    353:     if (file) {
                    354:        anot = 0;
                    355:        goto go_to_it;
                    356:     }
                    357: 
                    358:     if (!msgp)
                    359:        msgs[msgp++] = "cur";
                    360:     if (!folder)
                    361:        folder = m_getfolder ();
                    362:     maildir = m_maildir (folder);
                    363: 
                    364:     if (chdir (maildir) == NOTOK)
                    365:        adios (maildir, "unable to change directory to");
                    366:     if (!(mp = m_gmsg (folder)))
                    367:        adios (NULLCP, "unable to read folder %s", folder);
                    368:     if (mp -> hghmsg == 0)
                    369:        adios (NULLCP, "no messages in %s", folder);
                    370: 
                    371:     for (msgnum = 0; msgnum < msgp; msgnum++)
                    372:        if (!m_convert (mp, msgs[msgnum]))
                    373:            done (1);
                    374:     m_setseq (mp);
                    375: 
                    376: /*  */
                    377: 
                    378: go_to_it: ;
                    379:     if (filter && access (filter, 04) == NOTOK)
                    380:        adios (filter, "unable to read");
                    381: 
                    382:     if (digest) {
                    383:        if (issue == 0) {
                    384:            (void) sprintf (buf, IFMT, digest);
                    385:            if (volume == 0
                    386:                    && (cp = m_find (buf))
                    387:                    && ((issue = atoi (cp)) < 0))
                    388:                issue = 0;
                    389:            issue++;
                    390:        }
                    391:        if (volume == 0)
                    392:            (void) sprintf (buf, VFMT, digest);
                    393:            if ((cp = m_find (buf)) == NULL || (volume = atoi (cp)) <= 0)
                    394:                volume = 1;
                    395:        if (!form)
                    396:            form = digestcomps;
                    397:        in = build_form (form, digest, volume, issue);
                    398:     }
                    399:     else
                    400:        if (form) {
                    401:            if ((in = open (libpath (form), 0)) == NOTOK)
                    402:                adios (form, "unable to open form file");
                    403:        }
                    404:        else {
                    405:            if ((in = open (libpath (forwcomps), 0)) == NOTOK)
                    406:                adios (forwcomps, "unable to open default components file");
                    407:            form = forwcomps;
                    408:        }
                    409: 
                    410:     if ((out = creat (drft, m_gmprot ())) == NOTOK)
                    411:        adios (drft, "unable to create");
                    412: 
                    413:     cpydata (in, out, form, drft);
                    414:     (void) close (in);
                    415: 
                    416: /*  */
                    417: 
                    418:     if (file) {
                    419:        if ((in = open (file, 0)) == NOTOK)
                    420:            adios (file, "unable to open");
                    421:        cpydata (in, out, file, drft);
                    422:        (void) close (in);
                    423:        (void) close (out);
                    424:        goto edit_it;
                    425:     }
                    426: 
                    427:     if (filter)
                    428:        mhl_draft (out, digest, drft, filter, dashflg);
                    429:     else
                    430:        copy_draft (out, digest, drft);
                    431:     (void) close (out);
                    432: 
                    433:     if (digest) {
                    434:        (void) sprintf (buf, IFMT, digest);
                    435:        (void) sprintf (value, "%d", issue);
                    436:        m_replace (buf, getcpy (value));
                    437:        (void) sprintf (buf, VFMT, digest);
                    438:        (void) sprintf (value, "%d", volume);
                    439:        m_replace (buf, getcpy (value));
                    440:     }
                    441: 
                    442:     m_replace (pfolder, folder);
                    443:     if (mp -> lowsel != mp -> curmsg)
                    444:        m_setcur (mp, mp -> lowsel);
                    445:     m_sync (mp);
                    446:     m_update ();
                    447: 
                    448: edit_it: ;
                    449:     if (nwhat)
                    450:        done (0);
                    451:     (void) m_whatnow (ed, nedit, NOUSE, drft, NULLCP, 0, mp,
                    452:        anot ? "Forwarded" : NULLCP, inplace, cwd);
                    453:     done (1);
                    454: }
                    455: 
                    456: /*  */
                    457: 
                    458: static void
                    459: mhl_draft(out, digest, file, filter, dashflg)
                    460:        int out;
                    461:        register char *digest, *file, *filter;
                    462:        int dashflg;
                    463: {
                    464:     int     i,
                    465:             child_id,
                    466:            msgnum,
                    467:             pd[2];
                    468:     char   *vec[MAXARGS];
                    469: 
                    470:     if (pipe (pd) == NOTOK)
                    471:        adios ("pipe", "unable to create");
                    472: 
                    473:     vec[0] = r1bindex (mhlproc, '/');
                    474: 
                    475:     for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
                    476:        sleep (5);
                    477:     switch (child_id) {
                    478:        case NOTOK:
                    479:            adios ("fork", "unable to");
                    480: 
                    481:        case OK:
                    482:            (void) close (pd[0]);
                    483:            (void) dup2 (pd[1], 1);
                    484:            (void) close (pd[1]);
                    485: 
                    486:            i = 1;
                    487:            vec[i++] = "-forwall";
                    488:            vec[i++] = "-form";
                    489:            vec[i++] = filter;
                    490:            if (digest) {
                    491:                vec[i++] = "-digest";
                    492:                vec[i++] = digest;
                    493:            }
                    494:            if (dashflg)
                    495:                vec[i++] = "-dashmunging";
                    496:            else
                    497:                vec[i++] = "-nodashmunging";
                    498:            if (mp -> numsel >= MAXARGS - i)
                    499:                adios (NULLCP, "more than %d messages for %s exec",
                    500:                        vec[0], MAXARGS - i);
                    501:            for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                    502:                if (mp -> msgstats[msgnum] & SELECTED)
                    503:                    vec[i++] = getcpy (m_name (msgnum));
                    504:            vec[i] = NULL;
                    505: 
                    506:            execvp (mhlproc, vec);
                    507:            fprintf (stderr, "unable to exec ");
                    508:            perror (mhlproc);
                    509:            _exit (-1);
                    510: 
                    511:        default:
                    512:            (void) close (pd[1]);
                    513:            cpydata (pd[0], out, vec[0], file);
                    514:            (void) close (pd[0]);
                    515:            (void) pidXwait (child_id, mhlproc);
                    516:            break;
                    517:     }
                    518: }
                    519: 
                    520: /*  */
                    521: 
                    522: static void
                    523: copy_draft(out, digest, file)
                    524:        int out;
                    525:        register char *digest, *file;
                    526: {
                    527:     int     fd,i,
                    528:             msgcnt,
                    529:             msgnum;
                    530:     register char  *bp,
                    531:                    *msgnam;
                    532:     char    buffer[BUFSIZ];
                    533: 
                    534:     msgcnt = 1;
                    535:     for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                    536:        if (mp -> msgstats[msgnum] & SELECTED) {
                    537:            if (digest)
                    538:                (void) strcpy (buffer,
                    539:                        msgnum == mp -> lowsel ? delim3 : delim4);
                    540:            else {
                    541:                (void) strcpy (bp = buffer, "\n-------"), bp += strlen (bp);
                    542:                if (msgnum == mp -> lowsel)
                    543:                    (void) sprintf (bp, " Forwarded Message%s",
                    544:                            mp -> numsel > 1 ? "s" : "");
                    545:                else
                    546:                    (void) sprintf (bp, " Message %d", msgcnt);
                    547:                bp += strlen (bp);
                    548:                (void) strcpy (bp, "\n\n");
                    549:            }
                    550:            (void) write (out, buffer, strlen (buffer));
                    551: 
                    552:            if ((fd = open (msgnam = m_name (msgnum), 0)) == NOTOK) {
                    553:                admonish (msgnam, "unable to read message");
                    554:                continue;
                    555:            }
                    556:            cpydgst (fd, out, msgnam, file);
                    557:            (void) close (fd);
                    558: 
                    559:            msgcnt++;
                    560:        }
                    561: 
                    562:     if (digest)
                    563:        (void) strcpy (buffer, delim4);
                    564:     else
                    565:        (void) sprintf (buffer, "\n------- End of Forwarded Message%s\n\n",
                    566:                mp -> numsel > 1 ? "s" : "");
                    567:     (void) write (out, buffer, strlen (buffer));
                    568: 
                    569:     if (digest) {
                    570:        (void) sprintf (buffer, "End of %s Digest\n", digest);
                    571:        i = strlen (buffer);
                    572:        for (bp = buffer + i; i > 1; i--)
                    573:            *bp++ = '*';
                    574:        *bp++ = '\n';
                    575:        *bp = NULL;
                    576:        (void) write (out, buffer, strlen (buffer));
                    577:     }
                    578: }
                    579: 
                    580: /*  */
                    581: 
                    582: static int
                    583: build_form(form, digest, volume, issue)
                    584:        register char *form, *digest;
                    585:        int volume, issue;
                    586: {
                    587:     int            in;
                    588:     int     fmtsize;
                    589:     register char *nfs;
                    590:     char   *line,
                    591:             tmpfil[BUFSIZ];
                    592:     register    FILE *tmp;
                    593:     register struct comp *cptr;
                    594:     struct format *fmt;
                    595:     int     dat[4];
                    596: 
                    597:     nfs = new_fs (form, NULLCP, NULLCP);
                    598:     fmtsize = strlen (nfs) + 256;
                    599:     (void) fmt_compile (nfs, &fmt);
                    600: 
                    601:     FINDCOMP (cptr, "digest");
                    602:     if (cptr)
                    603:        cptr->c_text = digest;
                    604:     FINDCOMP (cptr, "date");
                    605:     if (cptr)
                    606:        cptr->c_text = getcpy(dtimenow ());
                    607: 
                    608:     dat[0] = issue;
                    609:     dat[1] = volume;
                    610:     dat[2] = 0;
                    611:     dat[3] = fmtsize;
                    612: 
                    613:     (void) strcpy (tmpfil, m_tmpfil (invo_name));
                    614:     if ((tmp = fopen (tmpfil, "w+")) == NULL)
                    615:        adios (tmpfil, "unable to create");
                    616:     (void) unlink (tmpfil);
                    617:     if ((in = dup (fileno (tmp))) == NOTOK)
                    618:        adios ("dup", "unable to");
                    619: 
                    620:     if ((line = malloc ((unsigned) fmtsize)) == NULLCP)
                    621:        adios (NULLCP, "unable to allocate format line storage");
                    622:     (void) fmtscan (fmt, line, fmtsize, dat);
                    623:     (void) fputs (line, tmp);
                    624:     (void) free (line);
                    625:     if (fclose (tmp))
                    626:        adios (tmpfil, "error writing");
                    627: 
                    628:     (void) lseek (in, 0L, 0);
                    629:     return in;
                    630: }
                    631: 
                    632: /*
                    633:  * XXX We need to force WhatNow() to be linked in to get around
                    634:  * library order problems
                    635:  */
                    636: /* XXX don't bother if linking with the shared library */
                    637: #ifndef SHARED
                    638: static void
                    639: kludge()
                    640: {
                    641:        WhatNow(0, (char **)0);
                    642: }
                    643: #endif

unix.superglobalmegacorp.com

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