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
pull/174/head
Duncaen 5 years ago committed by Leah Neukirchen
parent 1010ae06bf
commit 482bbffd2c

@ -121,6 +121,7 @@ struct expr {
}; };
struct mailinfo { struct mailinfo {
char *file;
char *fpath; char *fpath;
struct stat *sb; struct stat *sb;
struct message *msg; struct message *msg;
@ -973,8 +974,13 @@ msg_date(struct mailinfo *m)
if (m->date) if (m->date)
return m->date; return m->date;
if (!m->msg) // XXX: date comparisation should handle zero dates
m->msg = blaze822(m->fpath); if (!m->msg && m->fpath) {
if (!(m->msg = blaze822(m->fpath))) {
m->fpath = NULL;
return -1;
}
}
char *b; char *b;
if (m->msg && (b = blaze822_hdr(m->msg, "date"))) if (m->msg && (b = blaze822_hdr(m->msg, "date")))
@ -986,28 +992,35 @@ msg_date(struct mailinfo *m)
char * char *
msg_hdr(struct mailinfo *m, const char *h) msg_hdr(struct mailinfo *m, const char *h)
{ {
if (!m->msg) static char hdrbuf[4096];
m->msg = blaze822(m->fpath);
char *b; if (!m->msg && m->fpath) {
if (!m->msg || !(b = blaze822_chdr(m->msg, h))) if (!(m->msg = blaze822(m->fpath))) {
goto err; m->fpath = NULL;
*hdrbuf = 0;
return hdrbuf;
}
}
char buf[4096]; char *b;
blaze822_decode_rfc2047(buf, b, sizeof buf - 1, "UTF-8"); if (!m->msg || !(b = blaze822_chdr(m->msg, h))) {
if (!*buf) *hdrbuf = 0;
goto err; return hdrbuf;
}
return strdup(buf); blaze822_decode_rfc2047(hdrbuf, b, sizeof hdrbuf - 1, "UTF-8");
err: return hdrbuf;
return "";
} }
char * char *
msg_addr(struct mailinfo *m, char *h, int t) msg_addr(struct mailinfo *m, char *h, int t)
{ {
if (!m->msg) if (!m->msg && m->fpath) {
m->msg = blaze822(m->fpath); if (!(m->msg = blaze822(m->fpath))) {
m->fpath = NULL;
return "";
}
}
char *b; char *b;
if (m->msg == 0 || (b = blaze822_chdr(m->msg, h)) == 0) 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_FILE:
case EXPR_REDIR_PIPE: case EXPR_REDIR_PIPE:
fp = redir(e); fp = redir(e);
fputs(m->fpath, fp); fputs(m->file, fp);
putc('\n', fp); putc('\n', fp);
fflush(fp); fflush(fp);
return 1; return 1;
@ -1099,15 +1112,15 @@ eval(struct expr *e, struct mailinfo *m)
case EXPR_ANYSET: { case EXPR_ANYSET: {
long v = 0, n; long v = 0, n;
if (!m->sb && ( if (!m->sb && m->fpath && (
e->a.prop == PROP_ATIME || e->a.prop == PROP_ATIME ||
e->a.prop == PROP_CTIME || e->a.prop == PROP_CTIME ||
e->a.prop == PROP_MTIME || e->a.prop == PROP_MTIME ||
e->a.prop == PROP_SIZE) && e->a.prop == PROP_SIZE)) {
(m->sb = calloc(1, sizeof *m->sb)) && m->sb = xcalloc(1, sizeof *m->sb);
stat(m->fpath, m->sb) != 0) { if (stat(m->fpath, m->sb) == -1)
fprintf(stderr, "stat"); m->fpath = NULL;
exit(2); // XXX: stat based expressions should handle 0
} }
n = e->b.num; n = e->b.num;
@ -1154,9 +1167,9 @@ eval(struct expr *e, struct mailinfo *m)
case EXPR_GLOBI: case EXPR_GLOBI:
case EXPR_REGEX: case EXPR_REGEX:
case EXPR_REGEXI: { case EXPR_REGEXI: {
const char *s = ""; const char *s;
switch (e->a.prop) { 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_FROM: s = msg_addr(m, "from", e->extra); break;
case PROP_TO: s = msg_addr(m, "to", e->extra); break; case PROP_TO: s = msg_addr(m, "to", e->extra); break;
default: s = msg_hdr(m, e->a.string); break; default: s = msg_hdr(m, e->a.string); break;
@ -1175,7 +1188,7 @@ eval(struct expr *e, struct mailinfo *m)
} }
struct mailinfo * struct mailinfo *
mailfile(char *file) mailfile(struct mailinfo *m, char *file)
{ {
static int init; static int init;
if (!init) { if (!init) {
@ -1186,45 +1199,36 @@ mailfile(char *file)
cur = blaze822_seq_cur(); cur = blaze822_seq_cur();
init = 1; 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->index = num++;
m->flags = 0; m->file = file;
m->replies = 0;
m->depth = 0;
m->sb = 0;
m->msg = 0;
while (*m->fpath == ' ' || *m->fpath == '\t') { while (*fpath == ' ' || *fpath == '\t') {
m->depth++; m->depth++;
m->fpath++; fpath++;
} }
char *e = m->fpath + strlen(m->fpath) - 1; char *e = fpath + strlen(fpath) - 1;
while (m->fpath < e && (*e == ' ' || *e == '\t')) while (fpath < e && (*e == ' ' || *e == '\t'))
*e-- = 0; *e-- = 0;
if (m->fpath[0] == '<') { if (fpath[0] == '<') {
m->flags |= FLAG_SEEN | FLAG_INFO; m->flags |= FLAG_SEEN | FLAG_INFO;
m->fpath = NULL;
return m; 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') *e-- == 'w' && *e-- == 'e' && *e-- == 'n')
m->flags |= FLAG_NEW; m->flags |= FLAG_NEW;
if (cur && strcmp(cur, m->fpath) == 0) { if (cur && strcmp(cur, fpath) == 0) {
m->flags |= FLAG_CUR; m->flags |= FLAG_CUR;
cur_idx = m->index; cur_idx = m->index;
} }
char *f = strstr(m->fpath, ":2,"); char *f = strstr(fpath, ":2,");
if (f) { if (f) {
if (strchr(f, 'P')) if (strchr(f, 'P'))
m->flags |= FLAG_PASSED; m->flags |= FLAG_PASSED;
@ -1240,6 +1244,7 @@ mailfile(char *file)
m->flags |= FLAG_FLAGGED; m->flags |= FLAG_FLAGGED;
} }
m->fpath = fpath;
return m; return m;
} }
@ -1268,11 +1273,7 @@ do_thr()
break; break;
if (((Tflag && thr->matched) || ml->m->matched) && !ml->m->prune) { if (((Tflag && thr->matched) || ml->m->matched) && !ml->m->prune) {
int i; fputs(ml->m->file, stdout);
for (i = 0; i < ml->m->depth; i++)
putc(' ', stdout);
fputs(ml->m->fpath, stdout);
putc('\n', stdout); putc('\n', stdout);
kept++; kept++;
@ -1285,7 +1286,7 @@ do_thr()
if (ml->m->sb) if (ml->m->sb)
free(ml->m->sb); free(ml->m->sb);
free(ml->m->fpath); free(ml->m->file);
free(ml->m); free(ml->m);
} }
@ -1298,11 +1299,14 @@ collect(char *file)
{ {
struct mailinfo *m; struct mailinfo *m;
struct mlist *ml; struct mlist *ml;
char *f;
if ((m = mailfile(file)) == 0) f = xstrdup(file);
return; m = xcalloc(1, sizeof *m);
m = mailfile(m, f);
if (m->depth == 0) { if (m->depth == 0) {
/* process previous thread */
if (thr) if (thr)
do_thr(); do_thr();
@ -1337,17 +1341,15 @@ collect(char *file)
for (ml = ml->parent; ml; ml = ml->parent) for (ml = ml->parent; ml; ml = ml->parent)
ml->m->replies++; ml->m->replies++;
m->fpath = strdup(m->fpath);
} }
void void
oneline(char *file) oneline(char *file)
{ {
struct mailinfo *m; struct mailinfo m = { 0 };
m.index = num++;
m = mailfile(file); (void) mailfile(&m, file);
if (expr && !eval(expr, m)) if (expr && !eval(expr, &m))
goto out; goto out;
fputs(file, stdout); fputs(file, stdout);
@ -1356,11 +1358,10 @@ oneline(char *file)
kept++; kept++;
out: out:
if (m->msg) if (m.msg)
blaze822_free(m->msg); blaze822_free(m.msg);
if (m->sb) if (m.sb)
free(m->sb); free(m.sb);
free(m);
} }
int int

Loading…
Cancel
Save