fail in pick if a massage of -thread has no thread-id
[mmh] / uip / pick.c
index 464a734..f700a0c 100644 (file)
@@ -73,9 +73,11 @@ static struct swit switches[] = {
     { "width columns", 0 },
 #define THREADSW  24
        { "thread", 0 },
-#define VERSIONSW  25
+#define FILESW  25
+       { "file file", 0 },
+#define VERSIONSW  26
        { "Version", 0 },
-#define HELPSW  26
+#define HELPSW  27
        { "help", 0 },
        { NULL, 0 }
 };
@@ -100,6 +102,7 @@ static int pcompile(char **, char *);
 static int pmatches(FILE *, int);
 static struct nexus * createonethread(char *);
 static struct nexus * createpickthread(char *);
+static void scan_mbox(char *, char *, int);
 
 
 static int listsw = -1;
@@ -122,6 +125,7 @@ main(int argc, char **argv)
        char *form = NULL;
        char *fmtstr;
        FILE *fp;
+       char *file = NULL;
 
        if (atexit(putzero_done) != 0) {
                adios(EX_OSERR, NULL, "atexit failed");
@@ -237,6 +241,15 @@ main(int argc, char **argv)
                                }
                                width = atoi(cp);
                                continue;
+                       case FILESW:
+                               if (!(cp = *argp++) || (cp[0] == '-' && cp[1])) {
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
+                                                       argp[-2]);
+                               }
+                               if (strcmp(file = cp, "-")!=0) {
+                                       file = mh_xstrdup(expanddir(cp));
+                               }
+                               continue;
                        }
                }
                if (*cp == '+' || *cp == '@') {
@@ -251,6 +264,21 @@ main(int argc, char **argv)
 
        fmtstr = new_fs(form, "pick.default");
 
+       if (file) {
+               if (folder) {
+                       adios(EX_USAGE, NULL, "\"+folder\" not allowed with -file");
+               }
+               if (msgs.size) {
+                       adios(EX_USAGE, NULL, "\"msgs\" not allowed with -file");
+               }
+               if (vecp) {
+                       adios(EX_USAGE, NULL, "section arguments not allowed with -file");
+               }
+
+               scan_mbox(file, fmtstr, width);
+               exit(EX_OK);
+       }
+
        /*
        ** If we didn't specify which messages to search,
        ** then search the whole folder.
@@ -363,6 +391,29 @@ main(int argc, char **argv)
        return 0;
 }
 
+static void
+scan_mbox(char *file, char *fmtstr, int width)
+{
+       FILE *in;
+       int msgnum;
+       int state;
+
+       if (strcmp(file, "-") == 0) {
+               in = stdin;
+               file = "stdin";
+       } else if (!(in = fopen(file, "r"))) {
+               adios(EX_IOERR, file, "unable to open");
+       }
+
+       for (msgnum = 1; ;msgnum++) {
+               state = scan(in, msgnum, SCN_MBOX, fmtstr, width, 0, 0);
+               if (state != SCNMSG) {
+                       break;
+               }
+       }
+       fclose(in);
+}
+
 
 void
 putzero_done()
@@ -1037,26 +1088,29 @@ GREPaction(struct field *f, int msgnum, void *data)
 {
        struct grep_data *g = data;
        int ret;
-       char *buf;
+       char buf[BUFSIZ];
 
        if (!g->header && *f->name) {
                return FALSE;
        }
 
        /* check for the right field */
-       if (g->header && *g->header && mh_strcasecmp(g->header, f->name)==0) {
+       if (!(g->header && *g->header && mh_strcasecmp(g->header, f->name)==0)) {
                return FALSE;
        }
 
-       ret = regexec(g->preg, f->value, 0, NULL, 0) == REG_NOMATCH;
+       if(decode_rfc2047(f->value, buf, sizeof(buf))) {
+               ret = regexec(g->preg, buf, 0, NULL, 0);
+       } else {
+               ret = regexec(g->preg, f->value, 0, NULL, 0);
+       }
        switch (ret) {
        case 0:
                return TRUE;
        case REG_NOMATCH:
                return FALSE;
        default:
-               buf = mh_xcalloc(BUFSIZ, sizeof(char));
-               regerror(ret, g->preg, buf, BUFSIZ*sizeof(char));
+               regerror(ret, g->preg, buf, sizeof(buf));
                fprintf(stderr, "%s\n", buf);
                return FALSE;
        }
@@ -1231,7 +1285,6 @@ DATEfree(struct nexus **n)
        }
        dd = (*n)->data;
 
-       mh_free0(&dd->datef);
        mh_free0(n);
 }
 
@@ -1277,6 +1330,7 @@ createpickthread(char *msgs)
        for (i = 0; i < files.size; i++) {
                buf = getthreadid(files.msgs[i]);
                if (!buf) {
+                       adios(EX_DATAERR, NULL, "message %s is not part of a thread", basename(files.msgs[i]));
                        continue;
                }
 
@@ -1313,7 +1367,7 @@ createonethread(char *c)
 
        bd->left = left;
        bd->right = right;
-       gd->header = "message-id";
+       gd->header = mh_xstrdup("message-id");
 
        snprintf(buf, sizeof(buf), "^[ \t]*<%s>", c);
        if(!gcompile(gd, buf)) {
@@ -1322,7 +1376,7 @@ createonethread(char *c)
        }
 
        gd = right->data;
-       gd->header = "references";
+       gd->header = mh_xstrdup("references");
 
        snprintf(buf, sizeof(buf), "^[ \t]*<%s>", c);
        if(!gcompile(gd, buf)) {