[PATCH 3/4] Access messages through mail store interface
Michal Sojka
sojkam1 at fel.cvut.cz
Thu Apr 8 07:42:45 PDT 2010
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 <sojkam1 at fel.cvut.cz>
---
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
More information about the notmuch
mailing list