From fd5b2965a2a2cab883ef8fa8d6bc372a127dfa21 Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Tue, 26 Jun 2012 16:51:55 +2000 Subject: [PATCH] [RFC PATCH 12/14] mailstore: support for mbox:// URIs --- c9/0c5cbcbdac296181a1f6a447be99e47606b66b | 188 ++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 c9/0c5cbcbdac296181a1f6a447be99e47606b66b diff --git a/c9/0c5cbcbdac296181a1f6a447be99e47606b66b b/c9/0c5cbcbdac296181a1f6a447be99e47606b66b new file mode 100644 index 000000000..6b6c0b51c --- /dev/null +++ b/c9/0c5cbcbdac296181a1f6a447be99e47606b66b @@ -0,0 +1,188 @@ +Return-Path: +X-Original-To: notmuch@notmuchmail.org +Delivered-To: notmuch@notmuchmail.org +Received: from localhost (localhost [127.0.0.1]) + by olra.theworths.org (Postfix) with ESMTP id 8DBDB431FAF + for ; Mon, 25 Jun 2012 13:54:23 -0700 (PDT) +X-Virus-Scanned: Debian amavisd-new at olra.theworths.org +X-Spam-Flag: NO +X-Spam-Score: 1.061 +X-Spam-Level: * +X-Spam-Status: No, score=1.061 tagged_above=-999 required=5 + tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, + FREEMAIL_FROM=0.001, RCVD_IN_BL_SPAMCOP_NET=1.246, + RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_SORBS_WEB=0.614] autolearn=disabled +Received: from olra.theworths.org ([127.0.0.1]) + by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id DGKHb36IH1Pn for ; + Mon, 25 Jun 2012 13:54:23 -0700 (PDT) +Received: from mail-we0-f181.google.com (mail-we0-f181.google.com + [74.125.82.181]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) + (No client certificate requested) + by olra.theworths.org (Postfix) with ESMTPS id D2450431FB6 + for ; Mon, 25 Jun 2012 13:54:22 -0700 (PDT) +Received: by mail-we0-f181.google.com with SMTP id j55so3649559wer.26 + for ; Mon, 25 Jun 2012 13:54:22 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; + h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; + bh=qFV8lIM0wUbaJb3QQa15HFk6nHSx8wYDwaZm03WSkbI=; + b=iat6tx0LAge9nov/ohkNvdcU945bed9EnVRVIbB3SXGqSTMTF6XhiuXN2DOZfMxOoK + v++QNoItw+0LQokxxMzx1+6b81GICc+yGrF58xlMp6ppycZ5mEdN2Cp1pSOuVZaHrXmE + /bs520PzcPESReLwYku88QS788/Ms6/gXmdhUNFstZwvaeMBmRoHBjXw8n4OoOhjCvG2 + a7b9Z0HqHK4CvBy8usrCAcYKU/FD+pZBmeyhpQjAjEf/PObcLk662IyDeeY0fLA7wBq7 + kpryupytyemu0AZQFd/5OU4YI5ksaTtmDEi1jppHxSTdv5di//+7XPs7aaelvID6fNev + OzYQ== +Received: by 10.180.96.4 with SMTP id do4mr27121547wib.18.1340657662442; + Mon, 25 Jun 2012 13:54:22 -0700 (PDT) +Received: from localhost ([195.24.209.21]) + by mx.google.com with ESMTPS id t8sm35405wiy.3.2012.06.25.13.54.16 + (version=TLSv1/SSLv3 cipher=OTHER); + Mon, 25 Jun 2012 13:54:21 -0700 (PDT) +From: Ethan Glasser-Camp +To: notmuch@notmuchmail.org +Subject: [RFC PATCH 12/14] mailstore: support for mbox:// URIs +Date: Mon, 25 Jun 2012 16:51:55 -0400 +Message-Id: <1340657517-6539-8-git-send-email-ethan@betacantrips.com> +X-Mailer: git-send-email 1.7.9.5 +In-Reply-To: <1340657517-6539-1-git-send-email-ethan@betacantrips.com> +References: <1340657517-6539-1-git-send-email-ethan@betacantrips.com> +X-Mailman-Approved-At: Tue, 26 Jun 2012 03:51:54 -0700 +X-BeenThere: notmuch@notmuchmail.org +X-Mailman-Version: 2.1.13 +Precedence: list +List-Id: "Use and development of the notmuch mail system." + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +X-List-Received-Date: Mon, 25 Jun 2012 20:54:23 -0000 + + +Signed-off-by: Ethan Glasser-Camp +--- + lib/mailstore.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 85 insertions(+) + +diff --git a/lib/mailstore.c b/lib/mailstore.c +index ae02c12..e8d9bc1 100644 +--- a/lib/mailstore.c ++++ b/lib/mailstore.c +@@ -19,6 +19,7 @@ + */ + #include + #include ++#include + + #include "notmuch-private.h" + +@@ -28,6 +29,74 @@ notmuch_mailstore_basic_open (const char *filename) + return fopen (filename, "r"); + } + ++/* Since we have to return a FILE*, we use fmemopen to turn buffers ++ * into FILE* streams. But when we close these streams, we have to ++ * free() the buffers. Use a hash to associate the two. ++ */ ++static GHashTable *_mbox_files_to_strings = NULL; ++ ++static void ++_ensure_mbox_files_to_strings () { ++ if (_mbox_files_to_strings == NULL) ++ _mbox_files_to_strings = g_hash_table_new (NULL, NULL); ++} ++ ++static FILE * ++notmuch_mailstore_mbox_open (UriUriA *uri) ++{ ++ FILE *ret = NULL, *mbox = NULL; ++ char *filename, *message, *length_s; ++ const char *error; ++ long int offset, length, this_read; ++ _ensure_mbox_files_to_strings (); ++ ++ offset = strtol (uri->fragment.first, &length_s, 10); ++ length = strtol (length_s+1, NULL, 10); ++ ++ filename = talloc_strndup (NULL, uri->pathHead->text.first-1, ++ uri->pathTail->text.afterLast-uri->pathHead->text.first+1); ++ ++ if (filename == NULL) ++ goto DONE; ++ ++ mbox = fopen (filename, "r"); ++ if (mbox == NULL) { ++ fprintf (stderr, "Couldn't open message %s: %s.\n", uri->scheme.first, ++ strerror (errno)); ++ goto DONE; ++ } ++ ++ message = talloc_array (NULL, char, length); ++ fseek (mbox, offset, SEEK_SET); ++ ++ this_read = fread (message, sizeof(char), length, mbox); ++ if (this_read != length) { ++ if (feof (mbox)) ++ error = "end of file reached"; ++ if (ferror (mbox)) ++ error = strerror (ferror (mbox)); ++ ++ fprintf (stderr, "Couldn't read message %s: %s.\n", uri->scheme.first, error); ++ goto DONE; ++ } ++ ++ ret = fmemopen (message, length, "r"); ++ if (ret == NULL) { ++ /* No fclose will ever be called, so let's free message now */ ++ talloc_free (message); ++ goto DONE; ++ } ++ ++ g_hash_table_insert (_mbox_files_to_strings, ret, message); ++DONE: ++ if (filename) ++ talloc_free (filename); ++ if (mbox) ++ fclose (mbox); ++ ++ return ret; ++} ++ + FILE * + notmuch_mailstore_open (const char *filename) + { +@@ -57,6 +126,14 @@ notmuch_mailstore_open (const char *filename) + goto DONE; + } + ++ if (0 == strncmp (parsed.scheme.first, "mbox", ++ parsed.scheme.afterLast-parsed.scheme.first)) { ++ /* mbox URI of the form mbox:///path/to/file#offset+length. ++ * Just pass the parsed URI. */ ++ ret = notmuch_mailstore_mbox_open (&parsed); ++ goto DONE; ++ } ++ + DONE: + uriFreeUriMembersA (&parsed); + return ret; +@@ -65,5 +142,13 @@ DONE: + int + notmuch_mailstore_close (FILE *file) + { ++ char *file_buffer; ++ if (_mbox_files_to_strings != NULL) { ++ file_buffer = g_hash_table_lookup (_mbox_files_to_strings, file); ++ if (file_buffer != NULL) { ++ talloc_free (file_buffer); ++ } ++ g_hash_table_remove (_mbox_files_to_strings, file); ++ } + return fclose (file); + } +-- +1.7.9.5 + -- 2.26.2