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

unix.superglobalmegacorp.com

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