stamail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 326216d12d44a5b3ebc480d8cb20ac3708094eee
parent cd8d754cc036718b092b4aaf899852a8ee41e649
Author: Nathaniel Chappelle <nathaniel@chappelle.dev>
Date:   Thu, 29 Jan 2026 10:37:18 -0800

it renders threads, but weird bug generating extra (empty) messages

Diffstat:
Mstamail.c | 105++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 104 insertions(+), 1 deletion(-)

diff --git a/stamail.c b/stamail.c @@ -358,6 +358,102 @@ static int write_message(const char *output_dir, struct message *m) { return 0; } +static void render_thread_ascii(FILE *fp, + struct thread_node *n, + const char *prefix, + int is_last) +{ + char next_prefix[1024]; + + /* branch marker */ + fprintf(fp, "%s%s ", prefix, is_last ? "\\-" : "+-"); + + /* link to message */ + unsigned long hash = + hash_msgid(n->msg->id, n->msg->id_len); + + fprintf(fp, "<a href=\"msg-%08lx.html\">", hash); + fprinthtml(fp, + n->msg->subject, + n->msg->subject_len); + fprintf(fp, "</a>\n"); + + /* extend prefix */ + snprintf(next_prefix, sizeof(next_prefix), + "%s%s ", + prefix, + is_last ? " " : "| "); + + /* walk children */ + struct thread_node *c = n->child; + while (c) { + render_thread_ascii(fp, + c, + next_prefix, + c->sibling == NULL); + c = c->sibling; + } +} + +static int write_threads(const char *output_dir, + const char *archive_name, + struct thread_node **threads, + int num_threads) +{ + FILE *fp; + char path[1024]; + + snprintf(path, sizeof(path), "%s/threads.html", output_dir); + fp = fopen(path, "w"); + if (!fp) { + perror(path); + return -1; + } + + writeheader(fp, archive_name); + + fprintf(fp, "<h1>%s — Threads</h1>\n", archive_name); + fprintf(fp, "<nav>\n"); + fprintf(fp, "<a href=\"index.html\">Messages</a> | "); + fprintf(fp, "<a href=\"threads.html\">Threads</a>\n"); + fprintf(fp, "</nav>\n"); + + fprintf(fp, + "<pre style=\"font-family: monospace;" + "white-space: pre; line-height: 1.3;\">\n"); + + for (int i = 0; i < num_threads; i++) { + struct thread_node *r = *threads++; + + /* root line (no prefix) */ + unsigned long hash = + hash_msgid(r->msg->id, r->msg->id_len); + + fprintf(fp, "<a href=\"msg-%08lx.html\">", hash); + fprinthtml(fp, + r->msg->subject, + r->msg->subject_len); + fprintf(fp, "</a>\n"); + + /* children */ + struct thread_node *c = r->child; + while (c) { + render_thread_ascii(fp, + c, + "", + c->sibling == NULL); + c = c->sibling; + } + + fprintf(fp, "\n"); + } + + fprintf(fp, "</pre>\n"); + writefooter(fp); + fclose(fp); + return 0; +} + int main(int argc, char *argv[]) { /* CONFIG */ const char *output_dir = "./output"; @@ -496,7 +592,14 @@ int main(int argc, char *argv[]) { print_threads(threads, num_threads); } - + if (threads) { + if (write_threads(output_dir, + archive_name, + threads, + num_threads) != 0) { + fprintf(stderr, "Failed to write threads.html\n"); + } + } free(buf); struct message_node *n = head;