X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=uip%2Fpick.c;h=3e250a779bb0576a97a80798d9b5297090ec8d3d;hp=b3bac286f221a357e0fca813202cbd7d177edf25;hb=641a9d953e86685f9ca2f3da72e9a94e5bcfd69e;hpb=5ba9c2f13fedf1d8d6ed907ef1f505616290efaa diff --git a/uip/pick.c b/uip/pick.c index b3bac28..3e250a7 100644 --- a/uip/pick.c +++ b/uip/pick.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include #ifdef HAVE_SYS_TIME_H # include @@ -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 *) calloc((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; }