1 /* folder(s).c - report on folders */
3 static char ident[] = "@(#)$Id: folder.c,v 2.11 1993/08/27 23:23:06 jromine Exp $";
7 #include "../h/local.h"
14 static dodir(), addir(), addfold(), dother();
15 static int pfold(), sfold(), compare();
18 static struct swit switches[] = {
79 static int fshort = 0;
80 static int fcreat = 0;
83 static int fheader = 0;
84 static int frecurse = 0;
85 static int ftotonly = 0;
86 static int msgtot = 0;
87 static int foldtot = 0;
92 static char *stack = "Folder-Stack";
93 static char folder[BUFSIZ];
94 static char *folds[NFOLDERS + 1];
96 struct msgs *tfold ();
121 setlocale(LC_ALL, "");
123 invo_name = r1bindex (argv[0], '/');
124 if (argv[0][strlen (argv[0]) - 1] == 's')
126 if ((cp = m_find (invo_name)) != NULL) {
127 ap = brkstring (cp = getcpy (cp), " ", "\n");
128 ap = copyip (ap, arguments);
132 (void) copyip (argv + 1, ap);
137 while (cp = *argp++) {
139 switch (smatch (++cp, switches)) {
141 ambigsw (cp, switches);
144 adios (NULLCP, "-%s unknown", cp);
146 (void) sprintf (buf, "%s [+folder] [msg] [switches]",
148 help (buf, switches);
232 if (*cp == '+' || *cp == '@')
234 adios (NULLCP, "only one folder at a time!");
236 argfolder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
239 adios (NULLCP, "only one (current) message at a time!");
246 if (!m_find ("path"))
247 free (path ("./", TFOLDER));
248 mhdir = concat (m_maildir (""), "/", NULLCP);
250 if (pushsw == 0 && popsw == 0 && listsw == 0)
254 if ((cp = m_find (stack)) == NULL
255 || (ap = brkstring (dp = getcpy (cp), " ", "\n")) == NULL
256 || (argfolder = *ap++) == NULL)
257 adios (NULLCP, "no other folder");
258 for (cp = getcpy (m_getfolder ()); *ap; ap++)
259 cp = add (*ap, add (" ", cp));
261 m_replace (stack, cp);
265 (cp = m_find (stack))
266 ? concat (m_getfolder (), " ", cp, NULLCP)
267 : getcpy (m_getfolder ()));
271 adios (NULLCP, "sorry, no folders allowed with -pop");
272 if ((cp = m_find (stack)) == NULL
273 || (ap = brkstring (dp = getcpy (cp), " ", "\n")) == NULL
274 || (argfolder = *ap++) == NULL)
275 adios (NULLCP, "folder stack empty");
276 for (cp = NULL; *ap; ap++)
277 cp = cp ? add (*ap, add (" ", cp)) : getcpy (*ap);
280 m_replace (stack, cp);
282 (void) m_delete (stack);
284 if (pushsw || popsw) {
285 if (access (cp = m_maildir (argfolder), 0) == NOTOK)
286 adios (cp, "unable to find folder");
287 m_replace (pfolder, argfolder);
292 printf ("%s", argfolder ? argfolder : m_getfolder ());
293 if (cp = m_find (stack)) {
294 for (ap = brkstring (dp = getcpy (cp), " ", "\n"); *ap; ap++)
309 (void) strcpy (folder, argfolder);
310 if (pfold (argfolder, msg)) {
311 m_replace (pfolder, argfolder);
314 if (!frecurse) /* recurse not done in pfold(), */
315 dodir (folder); /* so just list all level-1 sub-folders */
319 admonish (NULLCP, "no folder given for message %s", msg);
322 (void) strcpy (folder, (cp = m_find (pfolder)) ? cp : "");
329 printf ("TOTAL= %*d message%c in %d folder%s.\n",
330 DMAXFOLDER, msgtot, msgtot != 1 ? 's' : ' ',
331 foldtot, foldtot != 1 ? "s" : "");
337 (void) strcpy (folder, argfolder ? argfolder : m_getfolder ());
338 if (stat (strcpy (buf, m_maildir (folder)), &st) == NOTOK) {
340 adios (buf, "error on folder");
342 case 0: /* ask before create */
343 cp = concat ("Create folder \"", buf, "\"? ", NULLCP);
348 case -1: /* do not create */
353 adios (NULLCP, "unable to create folder %s", buf);
356 if (pfold (folder, msg) && argfolder)
357 m_replace (pfolder, argfolder);
376 if (chdir (mhdir) == NOTOK)
377 adios (mhdir, "unable to change directory to");
379 addir (strcpy (buffer, dir));
380 for (i = start; i < foldp; i++)
381 (void) pfold (folds[i], NULLCP), (void) fflush (stdout);
389 static int pfold (fold, msg)
396 register char *mailfile;
397 register struct msgs *mp = NULL;
399 mailfile = m_maildir (fold);
400 if (chdir (mailfile) == NOTOK) {
402 admonish (mailfile, "unable to change directory to");
404 printf ("%22s%c unreadable\n",
405 fold, strcmp (folder, fold) ? ' ' : '+');
410 printf ("%s\n", fold);
412 if (!msg && !fpack) {
419 if (!(mp = m_gmsg (fold))) {
420 admonish (NULLCP, "unable to read folder %s", fold);
424 if (msg && !sfold (mp, msg))
432 msgtot += mp -> nummsg;
438 printf ("\t\tFolder %*s# of messages (%*srange%*s); cur%*smsg (other files)\n",
439 DMAXFOLDER, "", DMAXFOLDER - 2, "", DMAXFOLDER - 2, "",
442 printf ("%22s%c ", fold, strcmp (folder, fold) ? ' ' : '+');
445 if (mp -> hghmsg == 0)
446 printf ("has no messages%*s",
447 mp -> msgflags & OTHERS ? DMAXFOLDER * 2 + 4 : 0, "");
449 printf ("has %*d message%s (%*d-%*d)",
450 DMAXFOLDER, mp -> nummsg, (mp -> nummsg == 1) ? " " : "s",
451 DMAXFOLDER, mp -> lowmsg, DMAXFOLDER, mp -> hghmsg);
452 if (mp -> curmsg >= mp -> lowmsg && mp -> curmsg <= mp -> hghmsg)
453 printf ("; cur=%*d", DMAXFOLDER, hack = mp -> curmsg);
456 if (mp -> msgflags & OTHERS)
457 printf (";%*s (others)", hack ? 0 : DMAXFOLDER + 6, "");
461 others = mp -> msgflags & OTHERS;
464 if (frecurse && others)
472 static int sfold (mp, msg)
473 register struct msgs *mp;
476 if (!m_convert (mp, msg))
479 if (mp -> numsel > 1) {
480 admonish (NULLCP, "only one message at a time!");
484 m_setcur (mp, mp -> lowsel);
492 struct msgs *tfold (mp)
493 register struct msgs *mp;
500 if (mp -> lowmsg > 1 && (mp = m_remsg (mp, 1, mp -> hghmsg)) == NULL)
501 adios (NULLCP, "unable to allocate folder storage");
503 for (msgnum = mp -> lowmsg, hole = 1; msgnum <= mp -> hghmsg; msgnum++)
504 if (mp -> msgstats[msgnum] & EXISTS) {
505 if (msgnum != hole) {
506 (void) strcpy (newmsg, m_name (hole));
507 (void) strcpy (oldmsg, m_name (msgnum));
509 printf ("message %s becomes %s\n", oldmsg, newmsg);
510 if (rename (oldmsg, newmsg) == NOTOK)
511 adios (newmsg, "unable to rename %s to", oldmsg);
512 if (msgnum == mp -> curmsg)
513 m_setcur (mp, mp -> curmsg = hole);
514 mp -> msgstats[hole] = mp -> msgstats[msgnum];
515 mp -> msgflags |= SEQMOD;
516 if (msgnum == mp -> lowsel)
518 if (msgnum == mp -> hghsel)
523 if (mp -> nummsg > 0) {
525 mp -> hghmsg = hole - 1;
542 register struct dirent *dp;
544 register struct direct *dp;
548 cp = name + strlen (name);
552 base = strcmp (name, "./") ? name : name + 2;/* hack */
554 if ((dd = opendir (name)) == NULL) {
555 admonish (name, "unable to read directory ");
558 while (dp = readdir (dd))
559 if (strcmp (dp -> d_name, ".") && strcmp (dp -> d_name, "..")) {
561 if (cp + dp -> d_reclen + 2 >= name + BUFSIZ)
563 if (cp + strlen (dp -> d_name) + 2 >= name + BUFSIZ)
566 (void) strcpy (cp, dp -> d_name);
567 if (stat (name, &st) != NOTOK && (st.st_mode & S_IFMT) == S_IFDIR)
577 static addfold (fold)
584 if (foldp > NFOLDERS)
585 adios (NULLCP, "more than %d folders to report on", NFOLDERS);
588 for (i = start; i < foldp; i++)
589 if (compare (cp, folds[i]) < 0) {
590 for (j = foldp - 1; j >= i; j--)
591 folds[j + 1] = folds[j];
602 static int compare (s1, s2)
609 if (i = *s1++ - *s2++)
620 register struct node *np;
622 (void) sprintf (atrcur, "atr-%s-", current);
623 atrlen = strlen (atrcur);
626 for (np = m_defs; np; np = np -> n_next)
627 if (ssequal (atrcur, np -> n_name)
628 && !ssequal (mhdir, np -> n_name + atrlen))
629 (void) pfold (np -> n_name + atrlen, NULLCP);