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