|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.