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

1.1       root        1: /* folder(s).c - report on folders */
                      2: 
                      3: #include "../h/mh.h"
                      4: #include <errno.h>
                      5: #include <stdio.h>
                      6: #include <sys/types.h>
                      7: #ifndef        BSD42
                      8: #ifndef SYS5
                      9: #include <ndir.h>
                     10: #else   SYS5
                     11: #include <dir.h>
                     12: #endif  SYS5
                     13: #else  BSD42
                     14: #include <sys/dir.h>
                     15: #endif BSD42
                     16: #include <sys/stat.h>
                     17: 
                     18: /*  */
                     19: 
                     20: static struct swit switches[] = {
                     21: #define        ALLSW   0
                     22:     "all", 0,
                     23: 
                     24: #define        FASTSW  1
                     25:     "fast", 0,
                     26: #define        NFASTSW 2
                     27:     "nofast", 0,
                     28: 
                     29: #define        HDRSW   3
                     30:     "header", 0,
                     31: #define        NHDRSW  4
                     32:     "noheader", 0,
                     33: 
                     34: #define        PACKSW  5
                     35:     "pack", 0,
                     36: #define        NPACKSW 6
                     37:     "nopack", 0,
                     38: #define        VERBSW  7
                     39:     "verbose", 0,
                     40: #define        NVERBSW 8
                     41:     "noverbose", 0,
                     42: 
                     43: #define        RECURSW 9
                     44:     "recurse", 0,
                     45: #define        NRECRSW 10
                     46:     "norecurse", 0,
                     47: 
                     48: #define        TOTALSW 11
                     49:     "total", 0,
                     50: #define        NTOTLSW 12
                     51:     "nototal", 0,
                     52: 
                     53: #define        PRNTSW  13
                     54:     "print", 0,
                     55: #define        NPRNTSW 14
                     56:     "noprint", 0,
                     57: #define        LISTSW  15
                     58:     "list", 0,
                     59: #define        NLISTSW 16
                     60:     "nolist", 0,
                     61: #define        PUSHSW  17
                     62:     "push", 0,
                     63: #define        POPSW   18
                     64:     "pop", 0,
                     65: 
                     66: #define        HELPSW  19
                     67:     "help", 4,
                     68: 
                     69:     NULL, NULL
                     70: };
                     71: 
                     72: /*  */
                     73: 
                     74: extern int errno;
                     75: 
                     76: static int  fshort = 0;
                     77: static int  fpack = 0;
                     78: static int  fverb = 0;
                     79: static int  fheader = 0;
                     80: static int  frecurse = 0;
                     81: static int  ftotonly = 0;
                     82: static int  msgtot = 0;
                     83: static int  foldtot = 0;
                     84: static int  start = 0;
                     85: static int  foldp = 0;
                     86: 
                     87: static char *mhdir;
                     88: static char *stack = "Folder-Stack";
                     89: static char folder[BUFSIZ];
                     90: static char *folds[NFOLDERS + 1];
                     91: 
                     92: struct msgs *tfold ();
                     93: static int pfold(), sfold(), compare();
                     94: static void dodir(), addir(), addfold(), dother();
                     95: 
                     96: /*  */
                     97: 
                     98: /* ARGSUSED */
                     99: 
                    100: main(argc, argv)
                    101:        int argc;
                    102:        char *argv[];
                    103: {
                    104:     int     all = 0,
                    105:             printsw = 0,
                    106:             listsw = 0,
                    107:             pushsw = 0,
                    108:             popsw = 0;
                    109:     char   *cp,
                    110:            *dp,
                    111:            *msg = NULL,
                    112:            *argfolder = NULL,
                    113:           **ap,
                    114:           **argp,
                    115:             buf[100],
                    116:            *arguments[MAXARGS];
                    117:     struct stat st;
                    118: 
                    119:     invo_name = r1bindex (argv[0], '/');
                    120:     if (argv[0][strlen (argv[0]) - 1] == 's')
                    121:        all++;
                    122:     if ((cp = m_find (invo_name)) != NULL) {
                    123:        ap = brkstring (cp = getcpy (cp), " ", "\n");
                    124:        ap = copyip (ap, arguments);
                    125:     }
                    126:     else
                    127:        ap = arguments;
                    128:     (void) copyip (argv + 1, ap);
                    129:     argp = arguments;
                    130: 
                    131: /*  */
                    132: 
                    133:     while (cp = *argp++) {
                    134:        if (*cp == '-')
                    135:            switch (smatch (++cp, switches)) {
                    136:                case AMBIGSW:
                    137:                    ambigsw (cp, switches);
                    138:                    done (1);
                    139:                case UNKWNSW:
                    140:                    adios (NULLCP, "-%s unknown", cp);
                    141:                case HELPSW:
                    142:                    (void) sprintf (buf, "%s [+folder] [msg] [switches]",
                    143:                            invo_name);
                    144:                    help (buf, switches);
                    145:                    done (1);
                    146: 
                    147:                case ALLSW:
                    148:                    all++;
                    149:                    continue;
                    150: 
                    151:                case FASTSW:
                    152:                    fshort++;
                    153:                    continue;
                    154:                case NFASTSW:
                    155:                    fshort = 0;
                    156:                    continue;
                    157: 
                    158:                case HDRSW:
                    159:                    fheader = -1;
                    160:                    continue;
                    161:                case NHDRSW:
                    162:                    fheader++;
                    163:                    continue;
                    164: 
                    165:                case PACKSW:
                    166:                    fpack++;
                    167:                    continue;
                    168:                case NPACKSW:
                    169:                    fpack = 0;
                    170:                    continue;
                    171: 
                    172:                case VERBSW:
                    173:                    fverb++;
                    174:                    continue;
                    175:                case NVERBSW:
                    176:                    fverb = 0;
                    177:                    continue;
                    178: 
                    179:                case RECURSW:
                    180:                    frecurse++;
                    181:                    continue;
                    182:                case NRECRSW:
                    183:                    frecurse = 0;
                    184:                    continue;
                    185: 
                    186:                case TOTALSW:
                    187:                    all++;
                    188:                    ftotonly++;
                    189:                    continue;
                    190:                case NTOTLSW:
                    191:                    if (ftotonly)
                    192:                        all = 0;
                    193:                    ftotonly = 0;
                    194:                    continue;
                    195: 
                    196:                case PRNTSW:
                    197:                    printsw++;
                    198:                    continue;
                    199:                case NPRNTSW:
                    200:                    printsw = 0;
                    201:                    continue;
                    202: 
                    203:                case LISTSW:
                    204:                    listsw++;
                    205:                    continue;
                    206:                case NLISTSW:
                    207:                    listsw = 0;
                    208:                    continue;
                    209: 
                    210:                case PUSHSW:
                    211:                    pushsw++;
                    212:                    popsw = 0;
                    213:                    continue;
                    214:                case POPSW:
                    215:                    popsw++;
                    216:                    pushsw = 0;
                    217:                    continue;
                    218:            }
                    219:        if (*cp == '+' || *cp == '@')
                    220:            if (argfolder)
                    221:                adios (NULLCP, "only one folder at a time!");
                    222:            else
                    223:                argfolder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
                    224:        else
                    225:            if (msg)
                    226:                adios (NULLCP, "only one (current) message at a time!");
                    227:            else
                    228:                msg = cp;
                    229:     }
                    230: 
                    231: /*  */
                    232: 
                    233:     if (!m_find ("path"))
                    234:        free (path ("./", TFOLDER));
                    235:     mhdir = concat (m_maildir (""), "/", NULLCP);
                    236: 
                    237:     if (pushsw == 0 && popsw == 0 && listsw == 0)
                    238:        printsw++;
                    239:     if (pushsw) {
                    240:        if (!argfolder) {
                    241:            if ((cp = m_find (stack)) == NULL
                    242:                    || (ap = brkstring (dp = getcpy (cp), " ", "\n")) == NULL
                    243:                    || (argfolder = *ap++) == NULL)
                    244:                adios (NULLCP, "no other folder");
                    245:            for (cp = getcpy (m_getfolder ()); *ap; ap++)
                    246:                cp = add (*ap, add (" ", cp));
                    247:            free (dp);
                    248:            m_replace (stack, cp);
                    249:        }
                    250:        else
                    251:            m_replace (stack,
                    252:                    (cp = m_find (stack))
                    253:                    ? concat (m_getfolder (), " ", cp, NULLCP)
                    254:                    : getcpy (m_getfolder ()));
                    255:     }
                    256:     if (popsw) {
                    257:        if (argfolder)
                    258:            adios (NULLCP, "sorry, no folders allowed with -pop");
                    259:        if ((cp = m_find (stack)) == NULL
                    260:                || (ap = brkstring (dp = getcpy (cp), " ", "\n")) == NULL
                    261:                || (argfolder = *ap++) == NULL)
                    262:            adios (NULLCP, "folder stack empty");
                    263:        for (cp = NULL; *ap; ap++)
                    264:            cp = cp ? add (*ap, add (" ", cp)) : getcpy (*ap);
                    265:        free (dp);
                    266:        if (cp)
                    267:            m_replace (stack, cp);
                    268:        else
                    269:            (void) m_delete (stack);
                    270:     }
                    271:     if (pushsw || popsw) {
                    272:        if (access (cp = m_maildir (argfolder), 0) == NOTOK)
                    273:            adios (cp, "unable to find folder");
                    274:        m_replace (pfolder, argfolder);
                    275:        m_update ();
                    276:        argfolder = NULL;
                    277:     }
                    278:     if (pushsw || popsw || listsw) {
                    279:        printf ("%s", argfolder ? argfolder : m_getfolder ());
                    280:        if (cp = m_find (stack)) {
                    281:            for (ap = brkstring (dp = getcpy (cp), " ", "\n"); *ap; ap++)
                    282:                printf (" %s", *ap);
                    283:            free (dp);
                    284:        }
                    285:        printf ("\n");
                    286: 
                    287:        if (!printsw)
                    288:            done (0);
                    289:     }
                    290: 
                    291: /*  */
                    292: 
                    293:     if (all) {
                    294:        fheader = 0;
                    295:        if (argfolder || msg) {
                    296:            (void) strcpy (folder, argfolder ? argfolder : m_getfolder ());
                    297: 
                    298:            if (pfold (argfolder, msg) && argfolder) {
                    299:                m_replace (pfolder, argfolder);
                    300:                m_update ();
                    301:            }
                    302:            if (!frecurse)      /* counter-intuitive */
                    303:                dodir (folder);
                    304:        }
                    305:        else {
                    306:            dother ();
                    307: 
                    308:            (void) strcpy (folder, (cp = m_find (pfolder)) ? cp : "");
                    309:            dodir (".");
                    310:        }
                    311: 
                    312:        if (!fshort) {
                    313:            if (!ftotonly)
                    314:                printf ("\n\t\t     ");
                    315:            printf ("TOTAL= %*d message%c in %d folder%s.\n",
                    316:                    DMAXFOLDER, msgtot, msgtot != 1 ? 's' : ' ',
                    317:                    foldtot, foldtot != 1 ? "s" : "");
                    318:        }
                    319:     }
                    320:     else {
                    321:        fheader++;
                    322: 
                    323:        (void) strcpy (folder, argfolder ? argfolder : m_getfolder ());
                    324:        if (stat (strcpy (buf, m_maildir (folder)), &st) == NOTOK) {
                    325:            if (errno != ENOENT)
                    326:                adios (buf, "error on folder");
                    327:            cp = concat ("Create folder \"", buf, "\"? ", NULLCP);
                    328:            if (!getanswer (cp))
                    329:                done (1);
                    330:            free (cp);
                    331:            if (!makedir (buf))
                    332:                adios (NULLCP, "unable to create folder %s", buf);
                    333:        }
                    334: 
                    335:        if (pfold (folder, msg) && argfolder)
                    336:            m_replace (pfolder, argfolder);
                    337:     }
                    338: 
                    339:     m_update ();
                    340: 
                    341:     done (0);
                    342: }
                    343: 
                    344: /*  */
                    345: 
                    346: static void
                    347: dodir(dir)
                    348:        register char *dir;
                    349: {
                    350:     int     i;
                    351:     int     os = start;
                    352:     int     of = foldp;
                    353:     char    buffer[BUFSIZ];
                    354: 
                    355:     start = foldp;
                    356:     if (chdir (mhdir) == NOTOK)
                    357:        adios (mhdir, "unable to change directory to");
                    358: 
                    359:     addir (strcpy (buffer, dir));
                    360:     for (i = start; i < foldp; i++)
                    361:        (void) pfold (folds[i], NULLCP), (void) fflush (stdout);
                    362: 
                    363:     start = os;
                    364:     foldp = of;
                    365: }
                    366: 
                    367: /*  */
                    368: 
                    369: static int
                    370: pfold(fold, msg)
                    371:        register char *fold, *msg;
                    372: {
                    373:     int            hack,
                    374:            others,
                    375:             retval = 1;
                    376:     register char *mailfile;
                    377:     register struct msgs   *mp = NULL;
                    378: 
                    379:     mailfile = m_maildir (fold);
                    380:     if (chdir (mailfile) == NOTOK) {
                    381:        if (errno != EACCES)
                    382:            admonish (mailfile, "unable to change directory to");
                    383:        else
                    384:            printf ("%22s%c unreadable\n",
                    385:                    fold, strcmp (folder, fold) ? ' ' : '+');
                    386:        return 0;
                    387:     }
                    388: 
                    389:     if (fshort) {
                    390:        printf ("%s\n", fold);
                    391: 
                    392:        if (!msg && !fpack) {
                    393:            if (frecurse)
                    394:                dodir (fold);
                    395:            return retval;
                    396:        }
                    397:     }
                    398: 
                    399:     if (!(mp = m_gmsg (fold))) {
                    400:        admonish (NULLCP, "unable to read folder %s", fold);
                    401:        return 0;
                    402:     }
                    403: 
                    404:     if (msg && !sfold (mp, msg))
                    405:        retval = 0;
                    406:     if (fpack)
                    407:        mp = tfold (mp);
                    408: 
                    409:     if (fshort)
                    410:        goto out;
                    411:     foldtot++;
                    412:     msgtot += mp -> nummsg;
                    413: 
                    414:     if (ftotonly)
                    415:        goto out;
                    416: 
                    417:     if (!fheader++)
                    418:        printf ("\t\tFolder  %*s# of messages (%*srange%*s); cur%*smsg  (other files)\n",
                    419:            DMAXFOLDER, "", DMAXFOLDER - 2, "", DMAXFOLDER - 2, "",
                    420:            DMAXFOLDER - 2, "");
                    421: 
                    422:     printf ("%22s%c ", fold, strcmp (folder, fold) ? ' ' : '+');
                    423: 
                    424:     hack = 0;
                    425:     if (mp -> hghmsg == 0)
                    426:        printf ("has   no messages%*s",
                    427:                mp -> msgflags & OTHERS ? DMAXFOLDER * 2 + 4 : 0, "");
                    428:     else {
                    429:        printf ("has %*d message%s (%*d-%*d)",
                    430:                DMAXFOLDER, mp -> nummsg, (mp -> nummsg == 1) ? " " : "s",
                    431:                DMAXFOLDER, mp -> lowmsg, DMAXFOLDER, mp -> hghmsg);
                    432:        if (mp -> curmsg >= mp -> lowmsg && mp -> curmsg <= mp -> hghmsg)
                    433:            printf ("; cur=%*d", DMAXFOLDER, hack = mp -> curmsg);
                    434:     }
                    435: 
                    436:     if (mp -> msgflags & OTHERS)
                    437:        printf (";%*s (others)", hack ? 0 : DMAXFOLDER + 6, "");
                    438:     printf (".\n");
                    439: 
                    440: out: ;
                    441:     others = mp -> msgflags & OTHERS;
                    442:     m_fmsg (mp);
                    443: 
                    444:     if (frecurse && others)
                    445:        dodir (fold);
                    446: 
                    447:     return retval;
                    448: }
                    449: 
                    450: /*  */
                    451: 
                    452: static int
                    453: sfold(mp, msg)
                    454:        register struct msgs *mp;
                    455:        char *msg;
                    456: {
                    457:     if (!m_convert (mp, msg))
                    458:        return 0;
                    459: 
                    460:     if (mp -> numsel > 1) {
                    461:        admonish (NULLCP, "only one message at a time!");
                    462:        return 0;
                    463:     }
                    464:     m_setseq (mp);
                    465:     m_setcur (mp, mp -> lowsel);
                    466:     m_sync (mp);
                    467:     m_update ();
                    468: 
                    469:     return 1;
                    470: }
                    471: 
                    472: 
                    473: struct msgs *
                    474: tfold(mp)
                    475:        register struct msgs *mp;
                    476: {
                    477:     register int    hole,
                    478:                     msgnum;
                    479:     char    newmsg[BUFSIZ],
                    480:             oldmsg[BUFSIZ];
                    481: 
                    482:     if (mp -> lowmsg > 1 && (mp = m_remsg (mp, 1, mp -> hghmsg)) == NULL)
                    483:        adios (NULLCP, "unable to allocate folder storage");
                    484: 
                    485:     for (msgnum = mp -> lowmsg, hole = 1; msgnum <= mp -> hghmsg; msgnum++)
                    486:        if (mp -> msgstats[msgnum] & EXISTS) {
                    487:            if (msgnum != hole) {
                    488:                (void) strcpy (newmsg, m_name (hole));
                    489:                (void) strcpy (oldmsg, m_name (msgnum));
                    490:                if (fverb)
                    491:                        printf ("    %s becomes %s\n", oldmsg, newmsg);
                    492:                if (rename (oldmsg, newmsg) == NOTOK)
                    493:                    adios (newmsg, "unable to rename %s to", oldmsg);
                    494:                if (msgnum == mp -> curmsg)
                    495:                    m_setcur (mp, mp -> curmsg = hole);
                    496:                mp -> msgstats[hole] = mp -> msgstats[msgnum];
                    497:                mp -> msgflags |= SEQMOD;
                    498:                if (msgnum == mp -> lowsel)
                    499:                    mp -> lowsel = hole;
                    500:                if (msgnum == mp -> hghsel)
                    501:                    mp -> hghsel = hole;
                    502:            }
                    503:            hole++;
                    504:        }
                    505:     if (mp -> nummsg > 0) {
                    506:        mp -> lowmsg = 1;
                    507:        mp -> hghmsg = hole - 1;
                    508:     }
                    509:     m_sync (mp);
                    510:     m_update ();
                    511: 
                    512:     return mp;
                    513: }
                    514: 
                    515: /*  */
                    516: 
                    517: static void
                    518: addir(name)
                    519:        register char *name;
                    520: {
                    521:     register char  *base,
                    522:                    *cp;
                    523:     struct stat st;
                    524:     register struct direct *dp;
                    525:     register    DIR * dd;
                    526: 
                    527:     cp = name + strlen (name);
                    528:     *cp++ = '/';
                    529:     *cp = NULL;
                    530: 
                    531:     base = strcmp (name, "./") ? name : name + 2;/* hack */
                    532: 
                    533:     if ((dd = opendir (name)) == NULL) {
                    534:        admonish (name, "unable to read directory ");
                    535:        return;
                    536:     }
                    537:     while (dp = readdir (dd))
                    538:        if (strcmp (dp -> d_name, ".") && strcmp (dp -> d_name, "..")) {
                    539:            if (cp + dp -> d_namlen + 2 >= name + BUFSIZ)
                    540:                continue;
                    541:            (void) strcpy (cp, dp -> d_name);
                    542:            if (stat (name, &st) != NOTOK && (st.st_mode & S_IFMT) == S_IFDIR)
                    543:                addfold (base);
                    544:        }
                    545:     closedir (dd);
                    546: 
                    547:     *--cp = NULL;
                    548: }
                    549: 
                    550: /*  */
                    551: 
                    552: static void
                    553: addfold(fold)
                    554:        register char *fold;
                    555: {
                    556:     register int    i,
                    557:                     j;
                    558:     register char  *cp;
                    559: 
                    560:     if (foldp > NFOLDERS)
                    561:        adios (NULLCP, "more than %d folders to report on", NFOLDERS);
                    562: 
                    563:     cp = getcpy (fold);
                    564:     for (i = start; i < foldp; i++)
                    565:        if (compare (cp, folds[i]) < 0) {
                    566:            for (j = foldp - 1; j >= i; j--)
                    567:                folds[j + 1] = folds[j];
                    568:            foldp++;
                    569:            folds[i] = cp;
                    570:            return;
                    571:        }
                    572: 
                    573:     folds[foldp++] = cp;
                    574: }
                    575: 
                    576: /*  */
                    577: 
                    578: static int
                    579: compare(s1, s2)
                    580:        register char *s1, *s2;
                    581: {
                    582:     register int    i;
                    583: 
                    584:     while (*s1 || *s2)
                    585:        if (i = *s1++ - *s2++)
                    586:            return i;
                    587: 
                    588:     return 0;
                    589: }
                    590: 
                    591: /*  */
                    592: 
                    593: static void
                    594: dother()
                    595: {
                    596:     int            atrlen;
                    597:     char    atrcur[BUFSIZ];
                    598:     register struct node   *np;
                    599: 
                    600:     (void) sprintf (atrcur, "atr-%s-", current);
                    601:     atrlen = strlen (atrcur);
                    602: 
                    603:     m_getdefs ();
                    604:     for (np = m_defs; np; np = np -> n_next)
                    605:        if (ssequal (atrcur, np -> n_name)
                    606:                && !ssequal (mhdir, np -> n_name + atrlen))
                    607:            (void) pfold (np -> n_name + atrlen, NULLCP);
                    608: }

unix.superglobalmegacorp.com

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