diff src/lib-storage/index/mbox/mbox-md5.c @ 2972:7c4238c78aee HEAD

Reorganized mbox md5 summing code so it doesn't require sync context anymore.
author Timo Sirainen <tss@iki.fi>
date Wed, 15 Dec 2004 20:43:40 +0200
parents
children 55df57c028d4
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/mbox/mbox-md5.c	Wed Dec 15 20:43:40 2004 +0200
@@ -0,0 +1,116 @@
+/* Copyright (C) 2004 Timo Sirainen */
+
+#include "lib.h"
+#include "md5.h"
+#include "message-parser.h"
+#include "mbox-md5.h"
+
+#include <stdlib.h>
+
+struct mbox_md5_context {
+	struct md5_context hdr_md5_ctx;
+	int seen_received_hdr;
+};
+
+struct mbox_md5_header_func {
+	const char *header;
+	int (*func)(struct mbox_md5_context *ctx,
+		    struct message_header_line *hdr);
+};
+
+static int parse_date(struct mbox_md5_context *ctx,
+		      struct message_header_line *hdr)
+{
+	if (!ctx->seen_received_hdr) {
+		/* Received-header contains date too, and more trusted one */
+		md5_update(&ctx->hdr_md5_ctx, hdr->value, hdr->value_len);
+	}
+	return TRUE;
+}
+
+static int parse_delivered_to(struct mbox_md5_context *ctx,
+			      struct message_header_line *hdr)
+{
+	md5_update(&ctx->hdr_md5_ctx, hdr->value, hdr->value_len);
+	return TRUE;
+}
+
+static int parse_message_id(struct mbox_md5_context *ctx,
+			    struct message_header_line *hdr)
+{
+	if (!ctx->seen_received_hdr) {
+		/* Received-header contains unique ID too,
+		   and more trusted one */
+		md5_update(&ctx->hdr_md5_ctx, hdr->value, hdr->value_len);
+	}
+	return TRUE;
+}
+
+static int parse_received(struct mbox_md5_context *ctx,
+			  struct message_header_line *hdr)
+{
+	if (!ctx->seen_received_hdr) {
+		/* get only the first received-header */
+		md5_update(&ctx->hdr_md5_ctx, hdr->value, hdr->value_len);
+		if (!hdr->continues)
+			ctx->seen_received_hdr = TRUE;
+	}
+	return TRUE;
+}
+
+static int parse_x_delivery_id(struct mbox_md5_context *ctx,
+			       struct message_header_line *hdr)
+{
+	/* Let the local delivery agent help generate unique ID's but don't
+	   blindly trust this header alone as it could just as easily come from
+	   the remote. */
+	md5_update(&ctx->hdr_md5_ctx, hdr->value, hdr->value_len);
+	return TRUE;
+}
+
+
+static struct mbox_md5_header_func md5_header_funcs[] = {
+	{ "Date", parse_date },
+	{ "Delivered-To", parse_delivered_to },
+	{ "Message-ID", parse_message_id },
+	{ "Received", parse_received },
+	{ "X-Delivery-ID", parse_x_delivery_id }
+};
+#define MD5_HEADER_FUNCS_COUNT \
+	(sizeof(md5_header_funcs) / sizeof(*md5_header_funcs))
+
+static int bsearch_header_func_cmp(const void *p1, const void *p2)
+{
+	const char *key = p1;
+	const struct mbox_md5_header_func *func = p2;
+
+	return strcasecmp(key, func->header);
+}
+
+struct mbox_md5_context *mbox_md5_init(void)
+{
+	struct mbox_md5_context *ctx;
+
+	ctx = i_new(struct mbox_md5_context, 1);
+	md5_init(&ctx->hdr_md5_ctx);
+	return ctx;
+}
+
+void mbox_md5_continue(struct mbox_md5_context *ctx,
+		       struct message_header_line *hdr)
+{
+	struct mbox_md5_header_func *func;
+
+	func = bsearch(hdr->name, md5_header_funcs,
+		       MD5_HEADER_FUNCS_COUNT, sizeof(*md5_header_funcs),
+		       bsearch_header_func_cmp);
+	if (func != NULL)
+		(void)func->func(ctx, hdr);
+}
+
+void mbox_md5_finish(struct mbox_md5_context *ctx,
+		     unsigned char result[16])
+{
+	md5_final(&ctx->hdr_md5_ctx, result);
+	i_free(ctx);
+}