/*
* scan.c -- display a one-line "scan" listing of folder or messages
*
- * $Id$
+ * This code is Copyright (c) 2002, by the authors of nmh. See the
+ * COPYRIGHT file in the root directory of the nmh distribution for
+ * complete copyright information.
*/
#include <h/mh.h>
#include <h/fmt_scan.h>
#include <h/scansbr.h>
-#include <zotnet/tws/tws.h>
-#include <zotnet/mts/mts.h>
-#include <errno.h>
-
-/*
- * We allocate space for message names (msgs array)
- * this number of elements at a time.
- */
-#define MAXMSGS 256
-
-
-static struct swit switches[] = {
-#define CLRSW 0
- { "clear", 0 },
-#define NCLRSW 1
- { "noclear", 0 },
-#define FORMSW 2
- { "form formatfile", 0 },
-#define FMTSW 3
- { "format string", 5 },
-#define HEADSW 4
- { "header", 0 },
-#define NHEADSW 5
- { "noheader", 0 },
-#define WIDTHSW 6
- { "width columns", 0 },
-#define REVSW 7
- { "reverse", 0 },
-#define NREVSW 8
- { "noreverse", 0 },
-#define FILESW 9
- { "file file", 4 },
-#define VERSIONSW 10
- { "version", 0 },
-#define HELPSW 11
- { "help", 0 },
- { NULL, 0 }
-};
-
-extern int errno;
-
-/*
- * global for sbr/formatsbr.c - yech!
- */
-#ifdef LBL
-extern struct msgs *fmt_current_folder;
-#endif
-
-/*
- * prototypes
- */
-void clear_screen(void); /* from termsbr.c */
+#include <h/tws.h>
+#include <h/mts.h>
+#include <h/utils.h>
+
+#define SCAN_SWITCHES \
+ X("clear", 0, CLRSW) \
+ X("noclear", 0, NCLRSW) \
+ X("form formatfile", 0, FORMSW) \
+ X("format string", 5, FMTSW) \
+ X("header", 0, HEADSW) \
+ X("noheader", 0, NHEADSW) \
+ X("width columns", 0, WIDTHSW) \
+ X("reverse", 0, REVSW) \
+ X("noreverse", 0, NREVSW) \
+ X("file file", 4, FILESW) \
+ X("version", 0, VERSIONSW) \
+ X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(SCAN);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(SCAN, switches);
+#undef X
int
main (int argc, char **argv)
{
int clearflag = 0, hdrflag = 0, ontty;
- int width = 0, revflag = 0;
- int i, state, msgnum, nummsgs, maxmsgs;
- int seqnum[NUMATTRS], unseen, num_unseen_seq = 0;
+ int width = -1, revflag = 0;
+ int i, state, msgnum;
+ ivector_t seqnum = ivector_create (0);
+ int unseen, num_unseen_seq = 0;
char *cp, *maildir, *file = NULL, *folder = NULL;
char *form = NULL, *format = NULL, buf[BUFSIZ];
- char **argp, *nfs, **arguments, **msgs;
+ char **argp, *nfs, **arguments;
+ struct msgs_array msgs = { 0, 0, NULL };
struct msgs *mp;
FILE *in;
-#ifdef LOCALE
- setlocale(LC_ALL, "");
-#endif
- invo_name = r1bindex (argv[0], '/');
+ if (nmh_init(argv[0], 1)) { return 1; }
- /* read user profile/context */
- context_read();
-
- mts_init (invo_name);
+ mts_init ();
arguments = getarguments (invo_name, argc, argv, 1);
argp = arguments;
- /*
- * Allocate the initial space to record message
- * names, ranges, and sequences.
- */
- nummsgs = 0;
- maxmsgs = MAXMSGS;
- if (!(msgs = (char **) malloc ((size_t) (maxmsgs * sizeof(*msgs)))))
- adios (NULL, "unable to allocate storage");
-
/*
* Parse arguments
*/
snprintf (buf, sizeof(buf), "%s [+folder] [msgs] [switches]",
invo_name);
print_help (buf, switches, 1);
- done (1);
+ done (0);
case VERSIONSW:
print_version(invo_name);
- done (1);
+ done (0);
case CLRSW:
clearflag++;
if (folder)
adios (NULL, "only one folder at a time!");
else
- folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
- } else {
- /*
- * Check if we need to allocate more space
- * for message names/ranges/sequences.
- */
- if (nummsgs >= maxmsgs) {
- maxmsgs += MAXMSGS;
- if (!(msgs = (char **) realloc (msgs,
- (size_t) (maxmsgs * sizeof(*msgs)))))
- adios (NULL, "unable to reallocate msgs storage");
- }
- msgs[nummsgs++] = cp;
- }
+ folder = pluspath (cp);
+ } else
+ app_msgarg(&msgs, cp);
}
if (!context_find ("path"))
* We are scanning a maildrop file
*/
if (file) {
- if (nummsgs)
+ if (msgs.size)
adios (NULL, "\"msgs\" not allowed with -file");
if (folder)
adios (NULL, "\"+folder\" not allowed with -file");
adios (file, "unable to open");
}
-#ifndef JLR
if (hdrflag) {
printf ("FOLDER %s\t%s\n", file, dtimenow (1));
}
-#endif /* JLR */
- m_unknown (in);
+ scan_detect_mbox_style (in);
for (msgnum = 1; ; ++msgnum) {
+ charstring_t scanl = NULL;
+
state = scan (in, msgnum, -1, nfs, width, 0, 0,
- hdrflag ? file : NULL, 0L, 1);
+ hdrflag ? file : NULL, 0L, 1, &scanl);
+ charstring_free (scanl);
if (state != SCNMSG && state != SCNENC)
break;
}
+ scan_finished ();
fclose (in);
done (0);
}
* We are scanning a folder
*/
- if (!nummsgs)
- msgs[nummsgs++] = "all";
+ if (!msgs.size)
+ app_msgarg(&msgs, "all");
if (!folder)
folder = getfolder (1);
maildir = m_maildir (folder);
adios (maildir, "unable to change directory to");
/* read folder and create message structure */
- if (!(mp = folder_read (folder)))
+ if (!(mp = folder_read (folder, 1)))
adios (NULL, "unable to read folder %s", folder);
/* check for empty folder */
adios (NULL, "no messages in %s", folder);
/* parse all the message ranges/sequences and set SELECTED */
- for (msgnum = 0; msgnum < nummsgs; msgnum++)
- if (!m_convert (mp, msgs[msgnum]))
+ for (msgnum = 0; msgnum < msgs.size; msgnum++)
+ if (!m_convert (mp, msgs.msgs[msgnum]))
done(1);
seq_setprev (mp); /* set the Previous-Sequence */
dp = getcpy(cp);
ap = brkstring (dp, " ", "\n");
for (i = 0; ap && *ap; i++, ap++)
- seqnum[i] = seq_getnum (mp, *ap);
+ ivector_push_back (seqnum, seq_getnum (mp, *ap));
num_unseen_seq = i;
if (dp)
ontty = isatty (fileno (stdout));
-#ifdef LBL
- else
- fmt_current_folder = mp;
-#endif
-
for (msgnum = revflag ? mp->hghsel : mp->lowsel;
(revflag ? msgnum >= mp->lowsel : msgnum <= mp->hghsel);
msgnum += (revflag ? -1 : 1)) {
if (is_selected(mp, msgnum)) {
+ charstring_t scanl = NULL;
+
if ((in = fopen (cp = m_name (msgnum), "r")) == NULL) {
-#if 0
- if (errno != EACCES)
-#endif
admonish (cp, "unable to open message");
-#if 0
- else
- printf ("%*d unreadable\n", DMAXFOLDER, msgnum);
-#endif
continue;
}
-#ifndef JLR
if (hdrflag) {
printf ("FOLDER %s\t%s\n", folder, dtimenow(1));
}
-#endif /* JLR */
/*
* Check if message is in any sequence given
*/
unseen = 0;
for (i = 0; i < num_unseen_seq; i++) {
- if (in_sequence(mp, seqnum[i], msgnum)) {
+ if (in_sequence(mp, ivector_at (seqnum, i), msgnum)) {
unseen = 1;
break;
}
switch (state = scan (in, msgnum, 0, nfs, width,
msgnum == mp->curmsg, unseen,
- hdrflag ? folder : NULL, 0L, 1)) {
+ folder, 0L, 1, &scanl)) {
case SCNMSG:
case SCNENC:
case SCNERR:
adios (NULL, "scan() botch (%d)", state);
case SCNEOF:
-#if 0
- printf ("%*d empty\n", DMAXFOLDER, msgnum);
-#else
advise (NULL, "message %d: empty", msgnum);
-#endif
break;
}
+ charstring_free (scanl);
+ scan_finished ();
hdrflag = 0;
fclose (in);
if (ontty)
}
}
-#ifdef LBL
- seq_save (mp); /* because formatsbr might have made changes */
-#endif
-
+ ivector_free (seqnum);
folder_free (mp); /* free folder/message structure */
if (clearflag)
- clear_screen ();
+ nmh_clear_screen ();
- return done (0);
+ done (0);
+ return 1;
}