From 482bbffd2c49859612eeda1505f0c243cd974137 Mon Sep 17 00:00:00 2001 From: Duncaen Date: Mon, 28 Jan 2019 15:10:24 +0100 Subject: mpick: refactor mailfile handling - fix some memory leaks - fix handling of unexisting files/mthread containers - in oneline mode use one mailinfo struct for each line --- mpick.c | 131 ++++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 66 insertions(+), 65 deletions(-) diff --git a/mpick.c b/mpick.c index eb6afc9..27ee831 100644 --- a/mpick.c +++ b/mpick.c @@ -121,6 +121,7 @@ struct expr { }; struct mailinfo { + char *file; char *fpath; struct stat *sb; struct message *msg; @@ -973,8 +974,13 @@ msg_date(struct mailinfo *m) if (m->date) return m->date; - if (!m->msg) - m->msg = blaze822(m->fpath); + // XXX: date comparisation should handle zero dates + if (!m->msg && m->fpath) { + if (!(m->msg = blaze822(m->fpath))) { + m->fpath = NULL; + return -1; + } + } char *b; if (m->msg && (b = blaze822_hdr(m->msg, "date"))) @@ -986,28 +992,35 @@ msg_date(struct mailinfo *m) char * msg_hdr(struct mailinfo *m, const char *h) { - if (!m->msg) - m->msg = blaze822(m->fpath); + static char hdrbuf[4096]; - char *b; - if (!m->msg || !(b = blaze822_chdr(m->msg, h))) - goto err; + if (!m->msg && m->fpath) { + if (!(m->msg = blaze822(m->fpath))) { + m->fpath = NULL; + *hdrbuf = 0; + return hdrbuf; + } + } - char buf[4096]; - blaze822_decode_rfc2047(buf, b, sizeof buf - 1, "UTF-8"); - if (!*buf) - goto err; + char *b; + if (!m->msg || !(b = blaze822_chdr(m->msg, h))) { + *hdrbuf = 0; + return hdrbuf; + } - return strdup(buf); -err: - return ""; + blaze822_decode_rfc2047(hdrbuf, b, sizeof hdrbuf - 1, "UTF-8"); + return hdrbuf; } char * msg_addr(struct mailinfo *m, char *h, int t) { - if (!m->msg) - m->msg = blaze822(m->fpath); + if (!m->msg && m->fpath) { + if (!(m->msg = blaze822(m->fpath))) { + m->fpath = NULL; + return ""; + } + } char *b; if (m->msg == 0 || (b = blaze822_chdr(m->msg, h)) == 0) @@ -1085,7 +1098,7 @@ eval(struct expr *e, struct mailinfo *m) case EXPR_REDIR_FILE: case EXPR_REDIR_PIPE: fp = redir(e); - fputs(m->fpath, fp); + fputs(m->file, fp); putc('\n', fp); fflush(fp); return 1; @@ -1099,15 +1112,15 @@ eval(struct expr *e, struct mailinfo *m) case EXPR_ANYSET: { long v = 0, n; - if (!m->sb && ( + if (!m->sb && m->fpath && ( e->a.prop == PROP_ATIME || e->a.prop == PROP_CTIME || e->a.prop == PROP_MTIME || - e->a.prop == PROP_SIZE) && - (m->sb = calloc(1, sizeof *m->sb)) && - stat(m->fpath, m->sb) != 0) { - fprintf(stderr, "stat"); - exit(2); + e->a.prop == PROP_SIZE)) { + m->sb = xcalloc(1, sizeof *m->sb); + if (stat(m->fpath, m->sb) == -1) + m->fpath = NULL; + // XXX: stat based expressions should handle 0 } n = e->b.num; @@ -1154,9 +1167,9 @@ eval(struct expr *e, struct mailinfo *m) case EXPR_GLOBI: case EXPR_REGEX: case EXPR_REGEXI: { - const char *s = ""; + const char *s; switch (e->a.prop) { - case PROP_PATH: s = m->fpath; break; + case PROP_PATH: s = m->fpath ? m->fpath : ""; break; case PROP_FROM: s = msg_addr(m, "from", e->extra); break; case PROP_TO: s = msg_addr(m, "to", e->extra); break; default: s = msg_hdr(m, e->a.string); break; @@ -1175,7 +1188,7 @@ eval(struct expr *e, struct mailinfo *m) } struct mailinfo * -mailfile(char *file) +mailfile(struct mailinfo *m, char *file) { static int init; if (!init) { @@ -1186,45 +1199,36 @@ mailfile(char *file) cur = blaze822_seq_cur(); init = 1; } + char *fpath = file; - struct mailinfo *m; - m = calloc(1, sizeof *m); - if (!m) { - fprintf(stderr, "calloc"); - exit(2); - } - m->fpath = file; m->index = num++; - m->flags = 0; - m->replies = 0; - m->depth = 0; - m->sb = 0; - m->msg = 0; + m->file = file; - while (*m->fpath == ' ' || *m->fpath == '\t') { + while (*fpath == ' ' || *fpath == '\t') { m->depth++; - m->fpath++; + fpath++; } - char *e = m->fpath + strlen(m->fpath) - 1; - while (m->fpath < e && (*e == ' ' || *e == '\t')) + char *e = fpath + strlen(fpath) - 1; + while (fpath < e && (*e == ' ' || *e == '\t')) *e-- = 0; - if (m->fpath[0] == '<') { + if (fpath[0] == '<') { m->flags |= FLAG_SEEN | FLAG_INFO; + m->fpath = NULL; return m; } - if ((e = strrchr(m->fpath, '/') - 1) && (e - m->fpath) >= 2 && + if ((e = strrchr(fpath, '/') - 1) && (e - fpath) >= 2 && *e-- == 'w' && *e-- == 'e' && *e-- == 'n') m->flags |= FLAG_NEW; - if (cur && strcmp(cur, m->fpath) == 0) { + if (cur && strcmp(cur, fpath) == 0) { m->flags |= FLAG_CUR; cur_idx = m->index; } - char *f = strstr(m->fpath, ":2,"); + char *f = strstr(fpath, ":2,"); if (f) { if (strchr(f, 'P')) m->flags |= FLAG_PASSED; @@ -1240,6 +1244,7 @@ mailfile(char *file) m->flags |= FLAG_FLAGGED; } + m->fpath = fpath; return m; } @@ -1268,11 +1273,7 @@ do_thr() break; if (((Tflag && thr->matched) || ml->m->matched) && !ml->m->prune) { - int i; - for (i = 0; i < ml->m->depth; i++) - putc(' ', stdout); - - fputs(ml->m->fpath, stdout); + fputs(ml->m->file, stdout); putc('\n', stdout); kept++; @@ -1285,7 +1286,7 @@ do_thr() if (ml->m->sb) free(ml->m->sb); - free(ml->m->fpath); + free(ml->m->file); free(ml->m); } @@ -1298,11 +1299,14 @@ collect(char *file) { struct mailinfo *m; struct mlist *ml; + char *f; - if ((m = mailfile(file)) == 0) - return; + f = xstrdup(file); + m = xcalloc(1, sizeof *m); + m = mailfile(m, f); if (m->depth == 0) { + /* process previous thread */ if (thr) do_thr(); @@ -1337,17 +1341,15 @@ collect(char *file) for (ml = ml->parent; ml; ml = ml->parent) ml->m->replies++; - - m->fpath = strdup(m->fpath); } void oneline(char *file) { - struct mailinfo *m; - - m = mailfile(file); - if (expr && !eval(expr, m)) + struct mailinfo m = { 0 }; + m.index = num++; + (void) mailfile(&m, file); + if (expr && !eval(expr, &m)) goto out; fputs(file, stdout); @@ -1356,11 +1358,10 @@ oneline(char *file) kept++; out: - if (m->msg) - blaze822_free(m->msg); - if (m->sb) - free(m->sb); - free(m); + if (m.msg) + blaze822_free(m.msg); + if (m.sb) + free(m.sb); } int -- cgit 1.4.1