head 2.11; access; symbols; locks; strict; comment @ * @; 2.11 date 93.08.27.23.23.06; author jromine; state Exp; branches; next 2.10; 2.10 date 93.08.26.22.30.09; author jromine; state Exp; branches; next 2.9; 2.9 date 92.12.15.00.20.22; author jromine; state Exp; branches; next 2.8; 2.8 date 92.11.04.00.43.01; author jromine; state Exp; branches; next 2.7; 2.7 date 92.05.19.18.01.13; author jromine; state Exp; branches; next 2.6; 2.6 date 92.02.07.20.16.40; author jromine; state Exp; branches; next 2.5; 2.5 date 92.02.06.21.38.18; author jromine; state Exp; branches; next 2.4; 2.4 date 90.04.05.14.56.54; author sources; state Exp; branches; next 2.3; 2.3 date 90.02.09.09.48.38; author sources; state Exp; branches; next 2.2; 2.2 date 90.02.06.13.18.44; author sources; state Exp; branches; next 2.1; 2.1 date 90.02.05.14.41.04; author sources; state Exp; branches; next 2.0; 2.0 date 89.11.17.15.57.53; author sources; state Exp; branches; next 1.1; 1.1 date 89.06.26.14.36.39; author sources; state Exp; branches; next ; desc @@ 2.11 log @add -[no]create instead of -create policy @ text @/* folder(s).c - report on folders */ #ifndef lint static char ident[] = "@@(#)$Id: folder.c,v 2.10 1993/08/26 22:30:09 jromine Exp jromine $"; #endif /* lint */ #include "../h/mh.h" #include "../h/local.h" #include #include #ifdef LOCALE #include #endif static dodir(), addir(), addfold(), dother(); static int pfold(), sfold(), compare(); /* */ static struct swit switches[] = { #define ALLSW 0 "all", 0, #define CREATSW 1 "create", 0, #define NCREATSW 2 "nocreate", 0, #define FASTSW 3 "fast", 0, #define NFASTSW 4 "nofast", 0, #define HDRSW 5 "header", 0, #define NHDRSW 6 "noheader", 0, #define PACKSW 7 "pack", 0, #define NPACKSW 8 "nopack", 0, #define VERBSW 9 "verbose", 0, #define NVERBSW 10 "noverbose", 0, #define RECURSW 11 "recurse", 0, #define NRECRSW 12 "norecurse", 0, #define TOTALSW 13 "total", 0, #define NTOTLSW 14 "nototal", 0, #define PRNTSW 15 "print", 0, #define NPRNTSW 16 "noprint", -4, #define LISTSW 17 "list", 0, #define NLISTSW 18 "nolist", 0, #define PUSHSW 19 "push", 0, #define POPSW 20 "pop", 0, #define HELPSW 21 "help", 4, NULL, 0 }; /* */ extern int errno; static int fshort = 0; static int fcreat = 0; static int fpack = 0; static int fverb = 0; static int fheader = 0; static int frecurse = 0; static int ftotonly = 0; static int msgtot = 0; static int foldtot = 0; static int start = 0; static int foldp = 0; static char *mhdir; static char *stack = "Folder-Stack"; static char folder[BUFSIZ]; static char *folds[NFOLDERS + 1]; struct msgs *tfold (); /* */ /* ARGSUSED */ main (argc, argv) char *argv[]; { int all = 0, printsw = 0, listsw = 0, pushsw = 0, popsw = 0; char *cp, *dp, *msg = NULL, *argfolder = NULL, **ap, **argp, buf[100], *arguments[MAXARGS]; struct stat st; #ifdef LOCALE setlocale(LC_ALL, ""); #endif invo_name = r1bindex (argv[0], '/'); if (argv[0][strlen (argv[0]) - 1] == 's') all++; if ((cp = m_find (invo_name)) != NULL) { ap = brkstring (cp = getcpy (cp), " ", "\n"); ap = copyip (ap, arguments); } else ap = arguments; (void) copyip (argv + 1, ap); argp = arguments; /* */ while (cp = *argp++) { if (*cp == '-') switch (smatch (++cp, switches)) { case AMBIGSW: ambigsw (cp, switches); done (1); case UNKWNSW: adios (NULLCP, "-%s unknown", cp); case HELPSW: (void) sprintf (buf, "%s [+folder] [msg] [switches]", invo_name); help (buf, switches); done (1); case ALLSW: all++; continue; case CREATSW: fcreat = 1; continue; case NCREATSW: fcreat = -1; continue; case FASTSW: fshort++; continue; case NFASTSW: fshort = 0; continue; case HDRSW: fheader = -1; continue; case NHDRSW: fheader++; continue; case PACKSW: fpack++; continue; case NPACKSW: fpack = 0; continue; case VERBSW: fverb++; continue; case NVERBSW: fverb = 0; continue; case RECURSW: frecurse++; continue; case NRECRSW: frecurse = 0; continue; case TOTALSW: all++; ftotonly++; continue; case NTOTLSW: if (ftotonly) all = 0; ftotonly = 0; continue; case PRNTSW: printsw++; continue; case NPRNTSW: printsw = 0; continue; case LISTSW: listsw++; continue; case NLISTSW: listsw = 0; continue; case PUSHSW: pushsw++; listsw++; popsw = 0; continue; case POPSW: popsw++; listsw++; pushsw = 0; continue; } if (*cp == '+' || *cp == '@@') if (argfolder) adios (NULLCP, "only one folder at a time!"); else argfolder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF); else if (msg) adios (NULLCP, "only one (current) message at a time!"); else msg = cp; } /* */ if (!m_find ("path")) free (path ("./", TFOLDER)); mhdir = concat (m_maildir (""), "/", NULLCP); if (pushsw == 0 && popsw == 0 && listsw == 0) printsw++; if (pushsw) { if (!argfolder) { if ((cp = m_find (stack)) == NULL || (ap = brkstring (dp = getcpy (cp), " ", "\n")) == NULL || (argfolder = *ap++) == NULL) adios (NULLCP, "no other folder"); for (cp = getcpy (m_getfolder ()); *ap; ap++) cp = add (*ap, add (" ", cp)); free (dp); m_replace (stack, cp); } else m_replace (stack, (cp = m_find (stack)) ? concat (m_getfolder (), " ", cp, NULLCP) : getcpy (m_getfolder ())); } if (popsw) { if (argfolder) adios (NULLCP, "sorry, no folders allowed with -pop"); if ((cp = m_find (stack)) == NULL || (ap = brkstring (dp = getcpy (cp), " ", "\n")) == NULL || (argfolder = *ap++) == NULL) adios (NULLCP, "folder stack empty"); for (cp = NULL; *ap; ap++) cp = cp ? add (*ap, add (" ", cp)) : getcpy (*ap); free (dp); if (cp) m_replace (stack, cp); else (void) m_delete (stack); } if (pushsw || popsw) { if (access (cp = m_maildir (argfolder), 0) == NOTOK) adios (cp, "unable to find folder"); m_replace (pfolder, argfolder); m_update (); argfolder = NULL; } if (listsw) { printf ("%s", argfolder ? argfolder : m_getfolder ()); if (cp = m_find (stack)) { for (ap = brkstring (dp = getcpy (cp), " ", "\n"); *ap; ap++) printf (" %s", *ap); free (dp); } printf ("\n"); if (!printsw) done (0); } /* */ if (all) { fheader = 0; if (argfolder) { (void) strcpy (folder, argfolder); if (pfold (argfolder, msg)) { m_replace (pfolder, argfolder); m_update (); } if (!frecurse) /* recurse not done in pfold(), */ dodir (folder); /* so just list all level-1 sub-folders */ } else { if (msg) admonish (NULLCP, "no folder given for message %s", msg); dother (); (void) strcpy (folder, (cp = m_find (pfolder)) ? cp : ""); dodir ("."); } if (!fshort) { if (!ftotonly) printf ("\n\t\t "); printf ("TOTAL= %*d message%c in %d folder%s.\n", DMAXFOLDER, msgtot, msgtot != 1 ? 's' : ' ', foldtot, foldtot != 1 ? "s" : ""); } } else { fheader++; (void) strcpy (folder, argfolder ? argfolder : m_getfolder ()); if (stat (strcpy (buf, m_maildir (folder)), &st) == NOTOK) { if (errno != ENOENT) adios (buf, "error on folder"); switch (fcreat) { case 0: /* ask before create */ cp = concat ("Create folder \"", buf, "\"? ", NULLCP); if (!getanswer (cp)) done (1); free (cp); break; case -1: /* do not create */ done (1); break; } if (!makedir (buf)) adios (NULLCP, "unable to create folder %s", buf); } if (pfold (folder, msg) && argfolder) m_replace (pfolder, argfolder); } m_update (); done (0); } /* */ static dodir (dir) register char *dir; { int i; int os = start; int of = foldp; char buffer[BUFSIZ]; start = foldp; if (chdir (mhdir) == NOTOK) adios (mhdir, "unable to change directory to"); addir (strcpy (buffer, dir)); for (i = start; i < foldp; i++) (void) pfold (folds[i], NULLCP), (void) fflush (stdout); start = os; foldp = of; } /* */ static int pfold (fold, msg) register char *fold, *msg; { int hack, others, retval = 1; register char *mailfile; register struct msgs *mp = NULL; mailfile = m_maildir (fold); if (chdir (mailfile) == NOTOK) { if (errno != EACCES) admonish (mailfile, "unable to change directory to"); else printf ("%22s%c unreadable\n", fold, strcmp (folder, fold) ? ' ' : '+'); return 0; } if (fshort) { printf ("%s\n", fold); if (!msg && !fpack) { if (frecurse) dodir (fold); return retval; } } if (!(mp = m_gmsg (fold))) { admonish (NULLCP, "unable to read folder %s", fold); return 0; } if (msg && !sfold (mp, msg)) retval = 0; if (fpack) mp = tfold (mp); if (fshort) goto out; foldtot++; msgtot += mp -> nummsg; if (ftotonly) goto out; if (!fheader++) printf ("\t\tFolder %*s# of messages (%*srange%*s); cur%*smsg (other files)\n", DMAXFOLDER, "", DMAXFOLDER - 2, "", DMAXFOLDER - 2, "", DMAXFOLDER - 2, ""); printf ("%22s%c ", fold, strcmp (folder, fold) ? ' ' : '+'); hack = 0; if (mp -> hghmsg == 0) printf ("has no messages%*s", mp -> msgflags & OTHERS ? DMAXFOLDER * 2 + 4 : 0, ""); else { printf ("has %*d message%s (%*d-%*d)", DMAXFOLDER, mp -> nummsg, (mp -> nummsg == 1) ? " " : "s", DMAXFOLDER, mp -> lowmsg, DMAXFOLDER, mp -> hghmsg); if (mp -> curmsg >= mp -> lowmsg && mp -> curmsg <= mp -> hghmsg) printf ("; cur=%*d", DMAXFOLDER, hack = mp -> curmsg); } if (mp -> msgflags & OTHERS) printf (";%*s (others)", hack ? 0 : DMAXFOLDER + 6, ""); printf (".\n"); out: ; others = mp -> msgflags & OTHERS; m_fmsg (mp); if (frecurse && others) dodir (fold); return retval; } /* */ static int sfold (mp, msg) register struct msgs *mp; char *msg; { if (!m_convert (mp, msg)) return 0; if (mp -> numsel > 1) { admonish (NULLCP, "only one message at a time!"); return 0; } m_setseq (mp); m_setcur (mp, mp -> lowsel); m_sync (mp); m_update (); return 1; } struct msgs *tfold (mp) register struct msgs *mp; { register int hole, msgnum; char newmsg[BUFSIZ], oldmsg[BUFSIZ]; if (mp -> lowmsg > 1 && (mp = m_remsg (mp, 1, mp -> hghmsg)) == NULL) adios (NULLCP, "unable to allocate folder storage"); for (msgnum = mp -> lowmsg, hole = 1; msgnum <= mp -> hghmsg; msgnum++) if (mp -> msgstats[msgnum] & EXISTS) { if (msgnum != hole) { (void) strcpy (newmsg, m_name (hole)); (void) strcpy (oldmsg, m_name (msgnum)); if (fverb) printf ("message %s becomes %s\n", oldmsg, newmsg); if (rename (oldmsg, newmsg) == NOTOK) adios (newmsg, "unable to rename %s to", oldmsg); if (msgnum == mp -> curmsg) m_setcur (mp, mp -> curmsg = hole); mp -> msgstats[hole] = mp -> msgstats[msgnum]; mp -> msgflags |= SEQMOD; if (msgnum == mp -> lowsel) mp -> lowsel = hole; if (msgnum == mp -> hghsel) mp -> hghsel = hole; } hole++; } if (mp -> nummsg > 0) { mp -> lowmsg = 1; mp -> hghmsg = hole - 1; } m_sync (mp); m_update (); return mp; } /* */ static addir (name) register char *name; { register char *base, *cp; struct stat st; #ifdef SYS5DIR register struct dirent *dp; #else /* SYS5DIR */ register struct direct *dp; #endif /* SYS5DIR */ register DIR * dd; cp = name + strlen (name); *cp++ = '/'; *cp = '\0'; base = strcmp (name, "./") ? name : name + 2;/* hack */ if ((dd = opendir (name)) == NULL) { admonish (name, "unable to read directory "); return; } while (dp = readdir (dd)) if (strcmp (dp -> d_name, ".") && strcmp (dp -> d_name, "..")) { #ifdef SYS5DIR if (cp + dp -> d_reclen + 2 >= name + BUFSIZ) #else /* SYS5DIR */ if (cp + strlen (dp -> d_name) + 2 >= name + BUFSIZ) #endif /* SYS5DIR */ continue; (void) strcpy (cp, dp -> d_name); if (stat (name, &st) != NOTOK && (st.st_mode & S_IFMT) == S_IFDIR) addfold (base); } closedir (dd); *--cp = '\0'; } /* */ static addfold (fold) register char *fold; { register int i, j; register char *cp; if (foldp > NFOLDERS) adios (NULLCP, "more than %d folders to report on", NFOLDERS); cp = getcpy (fold); for (i = start; i < foldp; i++) if (compare (cp, folds[i]) < 0) { for (j = foldp - 1; j >= i; j--) folds[j + 1] = folds[j]; foldp++; folds[i] = cp; return; } folds[foldp++] = cp; } /* */ static int compare (s1, s2) register char *s1, *s2; { register int i; while (*s1 || *s2) if (i = *s1++ - *s2++) return i; return 0; } /* */ static dother () { int atrlen; char atrcur[BUFSIZ]; register struct node *np; (void) sprintf (atrcur, "atr-%s-", current); atrlen = strlen (atrcur); m_getdefs (); for (np = m_defs; np; np = np -> n_next) if (ssequal (atrcur, np -> n_name) && !ssequal (mhdir, np -> n_name + atrlen)) (void) pfold (np -> n_name + atrlen, NULLCP); } @ 2.10 log @add -create policy @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: folder.c,v 2.9 1992/12/15 00:20:22 jromine Exp jromine $"; d23 3 a25 1 "create policy", 0, d27 1 a27 1 #define FASTSW 2 d29 1 a29 1 #define NFASTSW 3 d32 1 a32 1 #define HDRSW 4 d34 1 a34 1 #define NHDRSW 5 d37 1 a37 1 #define PACKSW 6 d39 1 a39 1 #define NPACKSW 7 d41 1 a41 1 #define VERBSW 8 d43 1 a43 1 #define NVERBSW 9 d46 1 a46 1 #define RECURSW 10 d48 1 a48 1 #define NRECRSW 11 d51 1 a51 1 #define TOTALSW 12 d53 1 a53 1 #define NTOTLSW 13 d56 1 a56 1 #define PRNTSW 14 d58 1 a58 1 #define NPRNTSW 15 d60 1 a60 1 #define LISTSW 16 d62 1 a62 1 #define NLISTSW 17 d64 1 a64 1 #define PUSHSW 18 d66 1 a66 1 #define POPSW 19 d69 1 a69 1 #define HELPSW 20 a74 11 static struct swit creats[] = { #define CREAT_ALWAYS 0 "always", 0, #define CREAT_ASK 1 "ask", 0, #define CREAT_NEVER 2 "never", 0, NULL, 0 }; d80 1 a80 1 static int fcreat = CREAT_ASK; d155 2 a156 12 case CREATSW: if (!(cp = *argp++) || *cp == '-') adios (NULLCP, "missing argument to %s", argp[-2]); switch (fcreat = smatch (cp, creats)) { case AMBIGSW: ambigsw (cp, creats); done (1); case UNKWNSW: adios (NULLCP, "%s unknown", cp); default: break; } d158 3 a161 1 d342 1 a342 1 case CREAT_ASK: d348 1 a348 1 case CREAT_NEVER: @ 2.9 log @endif sugar @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: folder.c,v 2.8 1992/11/04 00:43:01 jromine Exp jromine $"; d22 4 a25 1 #define FASTSW 1 d27 1 a27 1 #define NFASTSW 2 d30 1 a30 1 #define HDRSW 3 d32 1 a32 1 #define NHDRSW 4 d35 1 a35 1 #define PACKSW 5 d37 1 a37 1 #define NPACKSW 6 d39 1 a39 1 #define VERBSW 7 d41 1 a41 1 #define NVERBSW 8 d44 1 a44 1 #define RECURSW 9 d46 1 a46 1 #define NRECRSW 10 d49 1 a49 1 #define TOTALSW 11 d51 1 a51 1 #define NTOTLSW 12 d54 1 a54 1 #define PRNTSW 13 d56 1 a56 1 #define NPRNTSW 14 d58 1 a58 1 #define LISTSW 15 d60 1 a60 1 #define NLISTSW 16 d62 1 a62 1 #define PUSHSW 17 d64 1 a64 1 #define POPSW 18 d67 1 a67 1 #define HELPSW 19 d73 11 d89 1 d164 15 d358 11 a368 4 cp = concat ("Create folder \"", buf, "\"? ", NULLCP); if (!getanswer (cp)) done (1); free (cp); @ 2.8 log @LOCALE @ text @d3 2 a4 2 static char ident[] = "@@(#)$Id: folder.c,v 2.7 1992/05/19 18:01:13 jromine Exp jromine $"; #endif lint @ 2.7 log @compiler sugar @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: folder.c,v 2.6 1992/02/07 20:16:40 jromine Exp jromine $"; d10 3 d114 3 @ 2.6 log @undocument noprint let -nolist turn -list off if -push/-pop @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: folder.c,v 2.5 1992/02/06 21:38:18 jromine Exp jromine $"; d64 1 a64 1 NULL, NULL d517 1 a517 1 #else SYS5DIR d519 1 a519 1 #endif SYS5DIR d524 1 a524 1 *cp = NULL; d536 1 a536 1 #else SYS5DIR d538 1 a538 1 #endif SYS5DIR d546 1 a546 1 *--cp = NULL; @ 2.5 log @complain if -all w/o +folder w/ msg allow -[push|pop] -nolist @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: folder.c,v 2.4 1990/04/05 14:56:54 sources Exp jromine $"; d51 1 a51 1 "noprint", 0, d199 1 a199 1 listsw = -1; d272 1 a272 1 if (listsw > 0) { @ 2.4 log @add ID @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id:$"; d199 1 a199 1 listsw = 0; d204 1 d209 1 d272 1 a272 1 if (pushsw || popsw || listsw) { d289 3 a291 4 if (argfolder || msg) { (void) strcpy (folder, argfolder ? argfolder : m_getfolder ()); if (pfold (argfolder, msg) && argfolder) { d295 2 a296 2 if (!frecurse) /* counter-intuitive */ dodir (folder); d299 2 @ 2.3 log @Fixes from Van Jacobson @ text @d2 3 @ 2.2 log @ANSI Compilance @ text @d30 4 d35 1 a35 1 #define RECURSW 7 d37 1 a37 1 #define NRECRSW 8 d40 1 a40 1 #define TOTALSW 9 d42 1 a42 1 #define NTOTLSW 10 d45 1 a45 1 #define PRNTSW 11 d47 1 a47 1 #define NPRNTSW 12 d49 1 a49 1 #define LISTSW 13 d51 1 a51 1 #define NLISTSW 14 d53 1 a53 1 #define PUSHSW 15 d55 1 a55 1 #define POPSW 16 d58 1 a58 1 #define HELPSW 17 d70 1 d161 7 d476 2 @ 2.1 log @change SYS5DIR fix @ text @d8 2 @ 2.0 log @changes for SUN40 shared libraries and NNTP under bbc @ text @d515 1 a515 1 if (cp + dp -> d_namlen + 2 >= name + BUFSIZ) @ 1.1 log @Initial revision @ text @d493 3 d497 1 d512 3 d516 1 @