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

unix.superglobalmegacorp.com

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