about summary refs log tree commit diff
path: root/mpick.c
diff options
context:
space:
mode:
authorDuncaen <mail@duncano.de>2019-01-28 15:10:24 +0100
committerLeah Neukirchen <chneukirchen@gmail.com>2020-05-15 18:41:13 +0200
commit482bbffd2c49859612eeda1505f0c243cd974137 (patch)
tree466e7f4d31b0710be9b4c5833aefd6ee483416e8 /mpick.c
parent1010ae06bfa4ab1fd3c6708a9a2e8f5e0f329ac3 (diff)
downloadmblaze-482bbffd2c49859612eeda1505f0c243cd974137.tar.gz
mblaze-482bbffd2c49859612eeda1505f0c243cd974137.tar.xz
mblaze-482bbffd2c49859612eeda1505f0c243cd974137.zip
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
Diffstat (limited to 'mpick.c')
-rw-r--r--mpick.c131
1 files 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