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: }

Defined functions

addfold defined in line 531; used 1 times
addir defined in line 497; used 1 times
compare defined in line 556; used 1 times
dodir defined in line 331; used 4 times
dother defined in line 571; used 1 times
main defined in line 93; never used
pfold defined in line 353; used 4 times
sfold defined in line 436; used 1 times
tfold defined in line 456; used 2 times

Defined variables

fheader defined in line 74; used 5 times
folder defined in line 84; used 8 times
foldp defined in line 80; used 9 times
folds defined in line 85; used 6 times
foldtot defined in line 78; used 3 times
fpack defined in line 73; used 4 times
frecurse defined in line 75; used 5 times
fshort defined in line 72; used 5 times
ftotonly defined in line 76; used 5 times
mhdir defined in line 82; used 4 times
msgtot defined in line 77; used 3 times
stack defined in line 83; used 8 times
start defined in line 79; used 5 times
switches defined in line 20; used 3 times

Defined macros

ALLSW defined in line 21; never used
FASTSW defined in line 24; never used
HDRSW defined in line 29; never used
HELPSW defined in line 62; never used
LISTSW defined in line 53; never used
NFASTSW defined in line 26; never used
NHDRSW defined in line 31; never used
NLISTSW defined in line 55; never used
NPACKSW defined in line 36; never used
NPRNTSW defined in line 51; never used
NRECRSW defined in line 41; never used
NTOTLSW defined in line 46; never used
PACKSW defined in line 34; never used
POPSW defined in line 59; never used
PRNTSW defined in line 49; never used
PUSHSW defined in line 57; never used
RECURSW defined in line 39; never used
TOTALSW defined in line 44; never used
Last modified: 1985-12-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2007
Valid CSS Valid XHTML 1.0 Strict