From: Karel Zak Date: Thu, 19 Apr 2012 09:35:33 +0000 (+0200) Subject: make filename changes more robust X-Git-Tag: neomutt-20160404~13^2~62 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=32040612e1e11b2dc92956ca325c1586a12ad050;p=neomutt make filename changes more robust * use code from 'notmuch new' for add/remove messages * use the last added filename for duplicate emails Signed-off-by: Karel Zak --- diff --git a/copy.c b/copy.c index a8b75da38..6ce6fc10f 100644 --- a/copy.c +++ b/copy.c @@ -736,7 +736,7 @@ _mutt_append_message (CONTEXT *dest, FILE *fpin, CONTEXT *src, HEADER *hdr, char old[_POSIX_PATH_MAX]; if (nm_header_get_fullpath(hdr, old, sizeof(old))) - nm_update_filename(src, old, msg->commited_path); + nm_update_filename(src, old, msg->commited_path, hdr); } #endif diff --git a/mutt_notmuch.c b/mutt_notmuch.c index c4088bce3..3a05a6287 100644 --- a/mutt_notmuch.c +++ b/mutt_notmuch.c @@ -483,7 +483,7 @@ err: } -static int update_message_tags(HEADER *h, notmuch_message_t *msg) +static int update_header_tags(HEADER *h, notmuch_message_t *msg) { struct nm_hdrdata *data = h->data; notmuch_tags_t *tags; @@ -612,19 +612,36 @@ static int init_header(HEADER *h, const char *path, notmuch_message_t *msg) if (update_message_path(h, path)) return -1; - update_message_tags(h, msg); + update_header_tags(h, msg); return 0; } +static const char *get_message_last_filename(notmuch_message_t *msg) +{ + notmuch_filenames_t *ls; + const char *name = NULL; + + for (ls = notmuch_message_get_filenames(msg); + ls && notmuch_filenames_valid(ls); + notmuch_filenames_move_to_next(ls)) { + + name = notmuch_filenames_get(ls); + } + + return name; +} + static void append_message(CONTEXT *ctx, notmuch_message_t *msg) { - const char *path = notmuch_message_get_filename(msg); + const char *path = get_message_last_filename(msg); char *newpath = NULL; HEADER *h = NULL; if (!path) return; + + dprint(2, (debugfile, "nm: appending message, i=%d, (%s)\n", ctx->msgcount, notmuch_message_get_message_id(msg))); @@ -765,24 +782,14 @@ static notmuch_message_t *get_nm_message(notmuch_database_t *db, HEADER *hdr) return msg; } -int nm_modify_message_tags(CONTEXT *ctx, HEADER *hdr, char *buf0) +static int update_tags(notmuch_message_t *msg, const char *tags) { - struct nm_ctxdata *data = get_ctxdata(ctx); - notmuch_database_t *db = NULL; - notmuch_message_t *msg = NULL; - int rc = -1; - char *tag = NULL, *end = NULL, *p, *buf = NULL; + char *tag = NULL, *end = NULL, *p; + char *buf = safe_strdup(tags); - if (!buf0 || !*buf0 || !data) + if (!buf) return -1; - if (!(db = get_db(data, TRUE)) || !(msg = get_nm_message(db, hdr))) - goto done; - - dprint(1, (debugfile, "nm: tags modify: '%s'\n", buf0)); - - buf = safe_strdup(buf0); - notmuch_message_freeze(msg); for (p = buf; p && *p; p++) { @@ -812,15 +819,31 @@ int nm_modify_message_tags(CONTEXT *ctx, HEADER *hdr, char *buf0) } notmuch_message_thaw(msg); + FREE(&buf); + return 0; +} - update_message_tags(hdr, msg); +int nm_modify_message_tags(CONTEXT *ctx, HEADER *hdr, char *buf) +{ + struct nm_ctxdata *data = get_ctxdata(ctx); + notmuch_database_t *db = NULL; + notmuch_message_t *msg = NULL; + int rc = -1; + + if (!buf || !*buf || !data) + return -1; + + if (!(db = get_db(data, TRUE)) || !(msg = get_nm_message(db, hdr))) + goto done; + + dprint(1, (debugfile, "nm: tags modify: '%s'\n", buf)); + + update_tags(msg, buf); + update_header_tags(hdr, msg); rc = 0; hdr->changed = TRUE; done: - FREE(&buf); - if (msg) - notmuch_message_destroy(msg); if (!is_longrun(data)) release_db(data); if (hdr->changed) @@ -829,49 +852,97 @@ done: return rc; } -static int _nm_update_filename(notmuch_database_t *db, - const char *old, const char *new) +static int remove_filename(notmuch_database_t *db, const char *path) { notmuch_status_t st; notmuch_message_t *msg = NULL; - if (!db) + dprint(2, (debugfile, "nm: removing filename '%s'\n", path)); + + st = notmuch_database_begin_atomic(db); + if (st) return -1; - if (new && access(new, F_OK) == 0) { - dprint(2, (debugfile, "nm: add filename '%s'\n", new)); - st = notmuch_database_add_message(db, new, &msg); - } else - /* if the new file does not exist then we remove old file only */ - st = NOTMUCH_STATUS_SUCCESS; - - if (st == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID || - st == NOTMUCH_STATUS_SUCCESS) { - dprint(2, (debugfile, "nm: remove filename '%s'\n", old)); - st = notmuch_database_remove_message(db, old); - if (st != NOTMUCH_STATUS_SUCCESS && - st != NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) - dprint(1, (debugfile, "nm: failed to remove '%s' [st=%d]\n", - old, (int) st)); - } + st = notmuch_database_find_message_by_filename(db, path, &msg); + if (st || !msg) + return -1; + + st = notmuch_database_remove_message(db, path); + if (st != NOTMUCH_STATUS_SUCCESS && + st != NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) + dprint(1, (debugfile, "nm: failed to remove '%s' [st=%d]\n", + path, (int) st)); + + if (st == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) + notmuch_message_maildir_flags_to_tags(msg); + + notmuch_message_destroy(msg); + notmuch_database_end_atomic(db); + return 0; +} + +static int add_filename(notmuch_database_t *db, const char *path, HEADER *h) +{ + int rc = -1; + notmuch_status_t st; + notmuch_message_t *msg; + + dprint(2, (debugfile, "nm: adding filename '%s'\n", path)); + + st = notmuch_database_begin_atomic(db); + if (st) + return -1; - if (msg) { + st = notmuch_database_add_message(db, path, &msg); + switch (st) { + case NOTMUCH_STATUS_SUCCESS: + if (h) + update_tags(msg, nm_header_get_tags(h)); + break; + case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID: notmuch_message_maildir_flags_to_tags(msg); - notmuch_message_destroy(msg); + break; + default: + dprint(1, (debugfile, "nm: failed to add '%s' [st=%d]\n", + path, (int) st)); + goto done; } + st = notmuch_database_end_atomic(db); + if (st) + goto done; + + rc = 0; +done: + if (msg) + notmuch_message_destroy(msg); + return rc; +} + +static int rename_filename(notmuch_database_t *db, + const char *old, const char *new, HEADER *h) +{ + if (!db) + return -1; + + dprint(1, (debugfile, "nm: rename filename, %s -> %s\n", old, new)); + + if (new && access(new, F_OK) == 0 && add_filename(db, new, h) != 0) + return -1; + if (old && remove_filename(db, old) != 0) + return -1; + return 0; } -int nm_update_filename(CONTEXT *ctx, const char *old, const char *new) +int nm_update_filename(CONTEXT *ctx, const char *old, const char *new, HEADER *h) { struct nm_ctxdata *data = get_ctxdata(ctx); if (!data || !new || !old) return -1; - dprint(1, (debugfile, "nm: update filenames, old='%s', new='%s'\n", old, new)); - return _nm_update_filename(get_db(data, TRUE), old, new); + return rename_filename(get_db(data, TRUE), old, new, h); } int nm_sync(CONTEXT *ctx, int *index_hint) @@ -935,14 +1006,10 @@ int nm_sync(CONTEXT *ctx, int *index_hint) if (!db) break; } - if (h->deleted) { - dprint(2, (debugfile, "nm: delete filename '%s'\n", old)); - notmuch_database_remove_message(db, old); + if (h->deleted && remove_filename(db, old) == 0) changed = 1; - } else if (*new && *old) { - _nm_update_filename(db, old, new); + else if (*new && *old && rename_filename(db, old, new, h) == 0) changed = 1; - } } FREE(&hd->oldpath); @@ -1163,7 +1230,7 @@ int nm_check_database(CONTEXT *ctx, int *index_hint) maildir_update_flags(ctx, h, &tmp); } - if (update_message_tags(h, m) == 0) + if (update_header_tags(h, m) == 0) new_flags++; } diff --git a/mutt_notmuch.h b/mutt_notmuch.h index 0a26c8203..80f50ae31 100644 --- a/mutt_notmuch.h +++ b/mutt_notmuch.h @@ -11,7 +11,7 @@ char *nm_header_get_folder(HEADER *h); int nm_header_get_magic(HEADER *h); char *nm_header_get_fullpath(HEADER *h, char *buf, size_t bufsz); char *nm_header_get_tags(HEADER *h); -int nm_update_filename(CONTEXT *ctx, const char *old, const char *new); +int nm_update_filename(CONTEXT *ctx, const char *o, const char *n, HEADER *h); char *nm_uri_from_query(CONTEXT *ctx, char *buf, size_t bufsz); int nm_modify_message_tags(CONTEXT *ctx, HEADER *hdr, char *tags);