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 4EC304196F5 for ; Thu, 8 Apr 2010 07:43:12 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: -1.9 X-Spam-Level: X-Spam-Status: No, score=-1.9 tagged_above=-999 required=5 tests=[BAYES_00=-1.9] autolearn=ham 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 dl2HlPiVMWYm for ; Thu, 8 Apr 2010 07:43:08 -0700 (PDT) Received: from max.feld.cvut.cz (max.feld.cvut.cz [147.32.192.36]) by olra.theworths.org (Postfix) with ESMTP id 834274196F0 for ; Thu, 8 Apr 2010 07:43:07 -0700 (PDT) Received: from localhost (unknown [192.168.200.4]) by max.feld.cvut.cz (Postfix) with ESMTP id E5C9719F33D8; Thu, 8 Apr 2010 16:43:06 +0200 (CEST) X-Virus-Scanned: IMAP AMAVIS Received: from max.feld.cvut.cz ([192.168.200.1]) by localhost (styx.feld.cvut.cz [192.168.200.4]) (amavisd-new, port 10044) with ESMTP id 4g-PakWlGmXu; Thu, 8 Apr 2010 16:43:05 +0200 (CEST) Received: from imap.feld.cvut.cz (imap.feld.cvut.cz [147.32.192.34]) by max.feld.cvut.cz (Postfix) with ESMTP id 165B519F3404; Thu, 8 Apr 2010 16:43:05 +0200 (CEST) Received: from steelpick.2x.cz (k335-30.felk.cvut.cz [147.32.86.30]) (Authenticated sender: sojkam1) by imap.feld.cvut.cz (Postfix) with ESMTPSA id 12ACF15C062; Thu, 8 Apr 2010 16:43:05 +0200 (CEST) Received: from wsh by steelpick.2x.cz with local (Exim 4.71) (envelope-from ) id 1Nzswi-0007cJ-Q0; Thu, 08 Apr 2010 16:43:04 +0200 From: Michal Sojka To: notmuch@notmuchmail.org Subject: [PATCH 3/4] Access messages through mail store interface Date: Thu, 8 Apr 2010 16:42:45 +0200 Message-Id: <1270737766-29237-4-git-send-email-sojkam1@fel.cvut.cz> X-Mailer: git-send-email 1.7.0.2 In-Reply-To: <1270737766-29237-1-git-send-email-sojkam1@fel.cvut.cz> References: <1270737766-29237-1-git-send-email-sojkam1@fel.cvut.cz> 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: Thu, 08 Apr 2010 14:43:12 -0000 This patch modifies notmuch binary to access the messages through mail store interface, so that non-file based mail stores can also be implemented. The API of notmuch library was changed. Now, notmuch_message_get_filename() returns relative file name with respect to the database path. As a result, notmuch show also outputs relative paths so that MUAs need to be changed. Signed-off-by: Michal Sojka --- lib/database.cc | 14 +++++++++++--- lib/index.cc | 8 ++++++-- lib/mailstore-files.c | 18 +++++++++++++++++- lib/message-file.c | 8 ++++---- lib/message.cc | 33 +++++++++++++++++++++++++-------- lib/notmuch-private.h | 6 +++--- lib/notmuch.h | 16 ++++++++++++++-- lib/sha1.c | 6 +----- notmuch-client.h | 2 +- notmuch-reply.c | 10 +++++++++- notmuch-show.c | 14 ++++++++++++-- show-message.c | 14 +------------- 12 files changed, 104 insertions(+), 45 deletions(-) diff --git a/lib/database.cc b/lib/database.cc index 93c8d0f..bd64ed3 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -1374,6 +1374,7 @@ notmuch_database_add_message (notmuch_database_t *notmuch, notmuch_message_t *message = NULL; notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS; notmuch_private_status_t private_status; + const char *relative; const char *date, *header; const char *from, *to, *subject; @@ -1386,7 +1387,8 @@ notmuch_database_add_message (notmuch_database_t *notmuch, if (ret) return ret; - message_file = notmuch_message_file_open (filename); + relative = _notmuch_database_relative_path (notmuch, filename); + message_file = notmuch_message_file_open (notmuch->mailstore, relative); if (message_file == NULL) return NOTMUCH_STATUS_FILE_ERROR; @@ -1438,9 +1440,15 @@ notmuch_database_add_message (notmuch_database_t *notmuch, } if (message_id == NULL ) { + FILE *file; + char *sha1 = NULL; /* No message-id at all, let's generate one by taking a * hash over the file's contents. */ - char *sha1 = notmuch_sha1_of_file (filename); + file = notmuch_mailstore_open_file (notmuch->mailstore, relative); + if (file) { + sha1 = notmuch_sha1_of_file (file); + fclose (file); + } /* If that failed too, something is really wrong. Give up. */ if (sha1 == NULL) { @@ -1483,7 +1491,7 @@ notmuch_database_add_message (notmuch_database_t *notmuch, date = notmuch_message_file_get_header (message_file, "date"); _notmuch_message_set_date (message, date); - _notmuch_message_index_file (message, filename); + _notmuch_message_index_file (message, relative); } else { ret = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID; } diff --git a/lib/index.cc b/lib/index.cc index cf93025..4d8c4dd 100644 --- a/lib/index.cc +++ b/lib/index.cc @@ -425,15 +425,19 @@ _notmuch_message_index_file (notmuch_message_t *message, const char *from, *subject; notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS; static int initialized = 0; + notmuch_mailstore_t *mailstore; if (! initialized) { g_mime_init (0); initialized = 1; } - file = fopen (filename, "r"); + mailstore = notmuch_message_get_mailstore(message); + file = notmuch_mailstore_open_file (mailstore, filename); if (! file) { - fprintf (stderr, "Error opening %s: %s\n", filename, strerror (errno)); + fprintf (stderr, "Error opening %s: %s\n", + notmuch_message_get_filename (message), + strerror (errno)); ret = NOTMUCH_STATUS_FILE_ERROR; goto DONE; } diff --git a/lib/mailstore-files.c b/lib/mailstore-files.c index 8b5e1d5..f2cb8d7 100644 --- a/lib/mailstore-files.c +++ b/lib/mailstore-files.c @@ -602,11 +602,27 @@ index_new(notmuch_mailstore_t *mailstore, const char* path, return ret; } +static FILE * +open_file(notmuch_mailstore_t *mailstore, const char *filename) +{ + const char *db_path; + char *abs_filename; + FILE *file; + + db_path = notmuch_database_get_path(mailstore->notmuch); + abs_filename = talloc_asprintf(NULL, "%s/%s", db_path, filename); + if (unlikely(abs_filename == NULL)) + return NULL; + file = fopen (abs_filename, "r"); + talloc_free(abs_filename); + return file; +} + /* Original notmuch mail store */ struct _notmuch_mailstore mailstore_files = { .type = "files", .count_files = count_files, .index_new = index_new, .sync_tags = NULL, /* We cannot store tags in this mailstore. */ - .open_file = NULL, /* Currently not implemented */ + .open_file = open_file, }; diff --git a/lib/message-file.c b/lib/message-file.c index 0c152a3..13c9f4c 100644 --- a/lib/message-file.c +++ b/lib/message-file.c @@ -94,7 +94,7 @@ _notmuch_message_file_destructor (notmuch_message_file_t *message) /* Create a new notmuch_message_file_t for 'filename' with 'ctx' as * the talloc owner. */ notmuch_message_file_t * -_notmuch_message_file_open_ctx (void *ctx, const char *filename) +_notmuch_message_file_open_ctx (void *ctx, notmuch_mailstore_t *mailstore, const char *filename) { notmuch_message_file_t *message; @@ -104,7 +104,7 @@ _notmuch_message_file_open_ctx (void *ctx, const char *filename) talloc_set_destructor (message, _notmuch_message_file_destructor); - message->file = fopen (filename, "r"); + message->file = notmuch_mailstore_open_file(mailstore, filename); if (message->file == NULL) goto FAIL; @@ -126,9 +126,9 @@ _notmuch_message_file_open_ctx (void *ctx, const char *filename) } notmuch_message_file_t * -notmuch_message_file_open (const char *filename) +notmuch_message_file_open (notmuch_mailstore_t *mailstore, const char *filename) { - return _notmuch_message_file_open_ctx (NULL, filename); + return _notmuch_message_file_open_ctx (NULL, mailstore, filename); } void diff --git a/lib/message.cc b/lib/message.cc index c32ee7d..c7eff7c 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -247,6 +247,7 @@ static void _notmuch_message_ensure_message_file (notmuch_message_t *message) { const char *filename; + notmuch_mailstore_t *mailstore; if (message->message_file) return; @@ -255,7 +256,9 @@ _notmuch_message_ensure_message_file (notmuch_message_t *message) if (unlikely (filename == NULL)) return; - message->message_file = _notmuch_message_file_open_ctx (message, filename); + mailstore = notmuch_message_get_mailstore (message); + + message->message_file = _notmuch_message_file_open_ctx (message, mailstore, filename); } const char * @@ -429,7 +432,7 @@ notmuch_message_get_filename (notmuch_message_t *message) int prefix_len = strlen (prefix); Xapian::TermIterator i; char *colon, *direntry = NULL; - const char *db_path, *directory, *basename; + const char *directory, *basename; unsigned int directory_id; void *local = talloc_new (message); @@ -474,18 +477,16 @@ notmuch_message_get_filename (notmuch_message_t *message) *colon = '\0'; - db_path = notmuch_database_get_path (message->notmuch); - directory = _notmuch_database_get_directory_path (local, message->notmuch, directory_id); if (strlen (directory)) - message->filename = talloc_asprintf (message, "%s/%s/%s", - db_path, directory, basename); - else message->filename = talloc_asprintf (message, "%s/%s", - db_path, basename); + directory, basename); + else + message->filename = talloc_asprintf (message, "%s", + basename); talloc_free ((void *) directory); talloc_free (local); @@ -493,6 +494,22 @@ notmuch_message_get_filename (notmuch_message_t *message) return message->filename; } +FILE * +notmuch_message_fopen (notmuch_message_t *message) +{ + const char *filename; + filename = notmuch_message_get_filename (message); + return notmuch_mailstore_open_file (message->notmuch->mailstore, + filename); +} + +notmuch_mailstore_t * +notmuch_message_get_mailstore (notmuch_message_t *message) +{ + return message->notmuch->mailstore; +} + + notmuch_bool_t notmuch_message_get_flag (notmuch_message_t *message, notmuch_message_flag_t flag) diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h index d52d84d..bab2090 100644 --- a/lib/notmuch-private.h +++ b/lib/notmuch-private.h @@ -295,11 +295,11 @@ typedef struct _notmuch_message_file notmuch_message_file_t; * Returns NULL if any error occurs. */ notmuch_message_file_t * -notmuch_message_file_open (const char *filename); +notmuch_message_file_open (notmuch_mailstore_t *mailstore, const char *filename); /* Like notmuch_message_file_open but with 'ctx' as the talloc owner. */ notmuch_message_file_t * -_notmuch_message_file_open_ctx (void *ctx, const char *filename); +_notmuch_message_file_open_ctx (void *ctx, notmuch_mailstore_t *mailstore, const char *filename); /* Close a notmuch message previously opened with notmuch_message_open. */ void @@ -402,7 +402,7 @@ char * notmuch_sha1_of_string (const char *str); char * -notmuch_sha1_of_file (const char *filename); +notmuch_sha1_of_file (FILE *file); /* tags.c */ diff --git a/lib/notmuch.h b/lib/notmuch.h index 31e47a4..54de0bd 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -739,8 +739,8 @@ notmuch_message_get_replies (notmuch_message_t *message); /* Get a filename for the email corresponding to 'message'. * - * The returned filename is an absolute filename, (the initial - * component will match notmuch_database_get_path() ). + * The returned filename is an relative filename of the message within + * the mail store. * * The returned string belongs to the message so should not be * modified or freed by the caller (nor should it be referenced after @@ -754,6 +754,18 @@ notmuch_message_get_replies (notmuch_message_t *message); const char * notmuch_message_get_filename (notmuch_message_t *message); +/* Return file handle to read the content of the message. + * + * This is a helper function which determines message filename and + * calls notmuch_mailstore_open_file(). + */ +FILE * +notmuch_message_fopen (notmuch_message_t *message); + +/* Get a pointer to the mailstore where the message is stored */ +notmuch_mailstore_t * +notmuch_message_get_mailstore (notmuch_message_t *message); + /* Message flags */ typedef enum _notmuch_message_flag { NOTMUCH_MESSAGE_FLAG_MATCH, diff --git a/lib/sha1.c b/lib/sha1.c index cc48108..a8991b1 100644 --- a/lib/sha1.c +++ b/lib/sha1.c @@ -74,9 +74,8 @@ notmuch_sha1_of_string (const char *str) * file not found, etc.), this function returns NULL. */ char * -notmuch_sha1_of_file (const char *filename) +notmuch_sha1_of_file (FILE *file) { - FILE *file; #define BLOCK_SIZE 4096 unsigned char block[BLOCK_SIZE]; size_t bytes_read; @@ -84,7 +83,6 @@ notmuch_sha1_of_file (const char *filename) unsigned char digest[SHA1_DIGEST_SIZE]; char *result; - file = fopen (filename, "r"); if (file == NULL) return NULL; @@ -108,8 +106,6 @@ notmuch_sha1_of_file (const char *filename) result = _hex_of_sha1_digest (digest); - fclose (file); - return result; } diff --git a/notmuch-client.h b/notmuch-client.h index d8c8df4..728e448 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -126,7 +126,7 @@ char * query_string_from_args (void *ctx, int argc, char *argv[]); notmuch_status_t -show_message_body (const char *filename, +show_message_body (FILE *file, void (*show_part) (GMimeObject *part, int *part_count)); notmuch_status_t diff --git a/notmuch-reply.c b/notmuch-reply.c index 1ec28cd..32d17ef 100644 --- a/notmuch-reply.c +++ b/notmuch-reply.c @@ -347,6 +347,7 @@ guess_from_received_header (notmuch_config_t *config, notmuch_message_t *message static int notmuch_reply_format_default(void *ctx, notmuch_config_t *config, notmuch_query_t *query) { + FILE *file; GMimeMessage *reply; notmuch_messages_t *messages; notmuch_message_t *message; @@ -415,7 +416,14 @@ notmuch_reply_format_default(void *ctx, notmuch_config_t *config, notmuch_query_ notmuch_message_get_header (message, "date"), notmuch_message_get_header (message, "from")); - show_message_body (notmuch_message_get_filename (message), reply_part); + file = notmuch_message_fopen (message); + if (file) { + show_message_body (file, reply_part); + fclose (file); + } else + fprintf (stderr, "Error opening %s: %s\n", + notmuch_message_get_filename (message), + strerror (errno)); notmuch_message_destroy (message); } diff --git a/notmuch-show.c b/notmuch-show.c index 6dca672..66fd773 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -339,6 +339,8 @@ format_part_json (GMimeObject *part, int *part_count) static void show_message (void *ctx, const show_format_t *format, notmuch_message_t *message, int indent) { + FILE *file; + fputs (format->message_start, stdout); if (format->message) format->message(ctx, message, indent); @@ -349,8 +351,16 @@ show_message (void *ctx, const show_format_t *format, notmuch_message_t *message fputs (format->header_end, stdout); fputs (format->body_start, stdout); - if (format->part) - show_message_body (notmuch_message_get_filename (message), format->part); + if (format->part) { + file = notmuch_message_fopen (message); + if (file) { + show_message_body (file, format->part); + fclose (file); + } else + fprintf (stderr, "Error opening %s: %s\n", + notmuch_message_get_filename (message), + strerror (errno)); + } fputs (format->body_end, stdout); fputs (format->message_end, stdout); diff --git a/show-message.c b/show-message.c index b1b61be..79911a7 100644 --- a/show-message.c +++ b/show-message.c @@ -60,23 +60,15 @@ show_message_part (GMimeObject *part, int *part_count, } notmuch_status_t -show_message_body (const char *filename, +show_message_body (FILE *file, void (*show_part) (GMimeObject *part, int *part_count)) { GMimeStream *stream = NULL; GMimeParser *parser = NULL; GMimeMessage *mime_message = NULL; notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS; - FILE *file = NULL; int part_count = 0; - file = fopen (filename, "r"); - if (! file) { - fprintf (stderr, "Error opening %s: %s\n", filename, strerror (errno)); - ret = NOTMUCH_STATUS_FILE_ERROR; - goto DONE; - } - stream = g_mime_stream_file_new (file); g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream), FALSE); @@ -87,7 +79,6 @@ show_message_body (const char *filename, show_message_part (g_mime_message_get_mime_part (mime_message), &part_count, show_part); - DONE: if (mime_message) g_object_unref (mime_message); @@ -97,9 +88,6 @@ show_message_body (const char *filename, if (stream) g_object_unref (stream); - if (file) - fclose (file); - return ret; } -- 1.7.0.2