mh_xstrdup arguments now const
[mmh] / uip / pick.c
index 819d81a..3e250a7 100644 (file)
@@ -12,6 +12,8 @@
 #include <unistd.h>
 #include <locale.h>
 #include <sysexits.h>
+#include <h/scansbr.h>
+#include <h/fmt_scan.h>
 
 #ifdef HAVE_SYS_TIME_H
 # include <sys/time.h>
@@ -63,13 +65,19 @@ static struct swit switches[] = {
        { "list", 0 },
 #define NLISTSW  21
        { "nolist", 2 },
-#define VERSIONSW  22
+#define FORMATSW  22
+       { "format format", 0 },
+#define WIDTHSW  23
+    { "width columns", 0 },
+#define VERSIONSW  24
        { "Version", 0 },
-#define HELPSW  23
+#define HELPSW  25
        { "help", 0 },
        { NULL, 0 }
 };
 
+char *version=VERSION;
+
 /*
 ** static prototypes
 */
@@ -81,10 +89,12 @@ static int listsw = -1;
 
 void putzero_done();
 
+static void printmsg(FILE *, struct msgs *, int, char *, int);
+
 int
 main(int argc, char **argv)
 {
-       int publicsw = -1, zerosw = 1, vecp = 0;
+       int publicsw = -1, zerosw = 1, vecp = 0, width = 0;
        unsigned int seqp = 0;
        int lo, hi, msgnum;
        char *maildir, *folder = NULL, buf[100];
@@ -92,9 +102,11 @@ main(int argc, char **argv)
        char *seqs[NUMATTRS + 1], *vec[MAXARGS];
        struct msgs_array msgs = { 0, 0, NULL };
        struct msgs *mp;
+       char *form = NULL;
+       char *fmtstr;
        FILE *fp;
 
-        if (atexit(putzero_done) != 0) {
+       if (atexit(putzero_done) != 0) {
                adios(EX_OSERR, NULL, "atexit failed");
        }
 
@@ -107,6 +119,10 @@ main(int argc, char **argv)
        arguments = getarguments(invo_name, argc, argv, 1);
        argp = arguments;
 
+       if (strcmp(invo_name, "scan")==0) {
+               form = scanformat;
+       }
+
        while ((cp = *argp++)) {
                if (*cp == '-') {
                        if (*++cp == '-') {
@@ -191,18 +207,32 @@ main(int argc, char **argv)
                        case NLISTSW:
                                listsw = 0;
                                continue;
+                       case FORMATSW:
+                               if (!(form = *argp++) || *form == '-') {
+                                       adios(EX_USAGE, NULL, "missing argument to %s", argp[-2]);
+                               }
+                               continue;
+                       case WIDTHSW:
+                               if (!(cp = *argp++) || *cp == '-') {
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
+                                                       argp[-2]);
+                               }
+                               width = atoi(cp);
+                               continue;
                        }
                }
                if (*cp == '+' || *cp == '@') {
                        if (folder)
                                adios(EX_USAGE, NULL, "only one folder at a time!");
                        else
-                               folder = getcpy(expandfol(cp));
+                               folder = mh_xstrdup(expandfol(cp));
                } else
                        app_msgarg(&msgs, cp);
        }
        vec[vecp] = NULL;
 
+       fmtstr = new_fs(form, "pick.default");
+
        /*
        ** If we didn't specify which messages to search,
        ** then search the whole folder.
@@ -269,12 +299,12 @@ main(int argc, char **argv)
                                if (msgnum > hi)
                                        hi = msgnum;
 
-                               if (listsw)
-                                       printf("%s\n", m_name(msgnum));
+                               if (listsw) {
+                                       printmsg(fp, mp, msgnum, fmtstr, width);
+                               }
                        } else {
                                /* if it doesn't match, then unselect it */
                                unset_selected(mp, msgnum);
-                               mp->numsel--;
                        }
                        if (fp)
                                fclose(fp);
@@ -319,6 +349,31 @@ putzero_done()
                printf("0\n");
 }
 
+static void
+printmsg(FILE *f, struct msgs *mp, int msgnum, char *fmtstr, int width)
+{
+       int seqnum;
+       int state;
+       boolean unseen = FALSE;
+
+       fseek(f, 0L, SEEK_SET);
+
+       seqnum = seq_getnum(mp, seq_unseen);
+       unseen = in_sequence(mp, seqnum, msgnum);
+
+       switch (state = scan(f, msgnum, SCN_FOLD, fmtstr,
+                       width, msgnum==mp->curmsg, unseen)) {
+       case SCNMSG:
+       case SCNERR:
+               break;
+       case SCNEOF:
+               advise(NULL, "message %d: empty", msgnum);
+               break;
+       default:
+               adios(EX_SOFTWARE, NULL, "scan() botch(%d)", state);
+       }
+}
+
 
 static struct swit parswit[] = {
 #define PRAND   0
@@ -381,6 +436,7 @@ static struct swit parswit[] = {
 
 
 static char linebuf[LBSIZE + 1];
+static char decoded_linebuf[LBSIZE + 1];
 
 /* the magic array for case-independence */
 static char cc[] = {
@@ -731,7 +787,7 @@ pattern: ;
                        padvise(NULL, "pattern error in %s %s", argp[-2], cp);
                        return NULL;
                }
-               n->n_patbuf = getcpy(dp);
+               n->n_patbuf = mh_xstrdup(dp);
                return n;
 
        case PROTHR:
@@ -768,8 +824,7 @@ newnexus(int (*action)())
 {
        struct nexus *p;
 
-       if ((p = (struct nexus *) mh_xcalloc((size_t) 1, sizeof *p)) == NULL)
-               adios(EX_OSERR, NULL, "unable to allocate component storage");
+       p = mh_xcalloc(1, sizeof *p);
 
        p->n_action = action;
        return p;
@@ -1016,8 +1071,17 @@ plist
                p1 = linebuf;
                p2 = n->n_expbuf;
 
+               /*
+               ** Attempt to decode as a MIME header.  If it's the
+               ** last header, body will be 1 and lf will be at least 1.
+               */
+               if ((body == 0 || lf > 0) && decode_rfc2047(linebuf,
+                               decoded_linebuf, sizeof decoded_linebuf)) {
+                       p1 = decoded_linebuf;
+               }
+
                if (n->n_circf) {
-                       if (advance(p1, p2))
+                       if (advance(p1, p2)) 
                                return 1;
                        continue;
                }
@@ -1233,41 +1297,40 @@ static int
 TWSaction(params)
 plist
 {
-       int state;
+       enum state state;
+       struct field f = {{0}};
        char *bp;
-       char buf[BUFSIZ], name[NAMESZ];
        struct tws *tw;
 
        fseek(fp, start, SEEK_SET);
-       for (state = FLD, bp = NULL;;) {
-               switch (state = m_getfld(state, name, buf, sizeof buf, fp)) {
-               case FLD:
-               case FLDEOF:
-               case FLDPLUS:
-                       if (bp != NULL) {
-                               free(bp);
-                               bp = NULL;
-                       }
-                       bp = getcpy(buf);
-                       while (state == FLDPLUS) {
-                               state = m_getfld(state, name, buf,
-                                               sizeof buf, fp);
-                               bp = add(buf, bp);
+       for (state = FLD2, bp = NULL;;) {
+               switch (state = m_getfld2(state, &f, fp)) {
+               case LENERR2:
+                       state = FLD2;
+                       /* FALL */
+
+               case FLD2:
+                       if (bp) {
+                               mh_free0(&bp);
                        }
-                       if (!mh_strcasecmp(name, n->n_datef))
+                       bp = mh_xstrdup(f.value);
+                       if (mh_strcasecmp(f.name, n->n_datef)==0) {
                                break;
-                       if (state != FLDEOF)
-                               continue;
+                       }
+                       continue;
+
+               case FMTERR2:
+                       advise(NULL, "format error in message %d", msgnum);
+                       state = FLD2;
+                       continue;
+
+               case IOERR2:
+                       adios(EX_IOERR, "m_getfld2", "io error on message %d", msgnum);
+                       /* FALL */
 
-               case BODY:
-               case BODYEOF:
-               case FILEEOF:
-               case LENERR:
-               case FMTERR:
-                       if (state == LENERR || state == FMTERR)
-                               advise(NULL, "format error in message %d", msgnum);
-                       if (bp != NULL)
-                               free(bp);
+               case BODY2:
+               case FILEEOF2:
+                       mh_free0(&bp);
                        return 0;
 
                default:
@@ -1284,6 +1347,6 @@ plist
                        : (twsort(tw, &n->n_tws) < 0);
 
        if (bp != NULL)
-               free(bp);
+               mh_free0(&bp);
        return state;
 }