From: Karel Zak Date: Thu, 12 Apr 2012 12:44:34 +0000 (+0200) Subject: search in new/cur subfolders if DB is not up-to-date X-Git-Tag: neomutt-20160404~13^2~70 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ae7e36512fb2aad013752b2888b5aa050b398b07;p=neomutt search in new/cur subfolders if DB is not up-to-date Signed-off-by: Karel Zak --- diff --git a/mh.c b/mh.c index f304b298a..48a419b42 100644 --- a/mh.c +++ b/mh.c @@ -736,40 +736,51 @@ static void maildir_update_mtime (CONTEXT * ctx) * Actually parse a maildir message. This may also be used to fill * out a fake header structure generated by lazy maildir parsing. */ -HEADER *maildir_parse_message (int magic, const char *fname, +HEADER *maildir_parse_stream (int magic, FILE *f, const char *fname, int is_old, HEADER * _h) { - FILE *f; HEADER *h = _h; struct stat st; - if ((f = fopen (fname, "r")) != NULL) - { - if (!h) - h = mutt_new_header (); - h->env = mutt_read_rfc822_header (f, h, 0, 0); + if (!h) + h = mutt_new_header (); + h->env = mutt_read_rfc822_header (f, h, 0, 0); - fstat (fileno (f), &st); - safe_fclose (&f); + fstat (fileno (f), &st); - if (!h->received) - h->received = h->date_sent; + if (!h->received) + h->received = h->date_sent; - /* always update the length since we have fresh information available. */ - h->content->length = st.st_size - h->content->offset; + /* always update the length since we have fresh information available. */ + h->content->length = st.st_size - h->content->offset; - h->index = -1; + h->index = -1; - if (magic == M_MAILDIR) - { - /* - * maildir stores its flags in the filename, so ignore the - * flags in the header of the message - */ + if (magic == M_MAILDIR) + { + /* + * maildir stores its flags in the filename, so ignore the + * flags in the header of the message + */ - h->old = is_old; - maildir_parse_flags (h, fname); - } + h->old = is_old; + maildir_parse_flags (h, fname); + } + return h; +} + +/* + * Actually parse a maildir message. This may also be used to fill + * out a fake header structure generated by lazy maildir parsing. + */ +HEADER *maildir_parse_message (int magic, const char *fname, + int is_old, HEADER * h) +{ + FILE *f; + + if ((f = fopen (fname, "r")) != NULL) { + h = maildir_parse_stream (magic, f, fname, is_old, h); + safe_fclose (&f); return h; } return NULL; @@ -2216,7 +2227,7 @@ int mh_check_mailbox (CONTEXT * ctx, int *index_hint) */ static FILE *_maildir_open_find_message (const char *folder, const char *unique, - const char *subfolder) + const char *subfolder, char **newname) { char dir[_POSIX_PATH_MAX]; char tunique[_POSIX_PATH_MAX]; @@ -2252,11 +2263,15 @@ static FILE *_maildir_open_find_message (const char *folder, const char *unique, closedir (dp); + if (newname && fp) + *newname = safe_strdup(fname); + errno = oe; return fp; } -FILE *maildir_open_find_message (const char *folder, const char *msg) +FILE *maildir_open_find_message (const char *folder, const char *msg, + char **newname) { char unique[_POSIX_PATH_MAX]; FILE *fp; @@ -2268,7 +2283,8 @@ FILE *maildir_open_find_message (const char *folder, const char *msg) if ( (fp = _maildir_open_find_message (folder, unique, - new_hits > cur_hits ? "new" : "cur")) + new_hits > cur_hits ? "new" : "cur", + newname)) || errno != ENOENT) { if (new_hits < UINT_MAX && cur_hits < UINT_MAX) @@ -2282,7 +2298,8 @@ FILE *maildir_open_find_message (const char *folder, const char *msg) if ( (fp = _maildir_open_find_message (folder, unique, - new_hits > cur_hits ? "cur" : "new")) + new_hits > cur_hits ? "cur" : "new", + newname)) || errno != ENOENT) { if (new_hits < UINT_MAX && cur_hits < UINT_MAX) diff --git a/mutt_notmuch.c b/mutt_notmuch.c index cc1c41c51..b2f76d529 100644 --- a/mutt_notmuch.c +++ b/mutt_notmuch.c @@ -60,6 +60,7 @@ struct uri_tag { struct nm_hdrdata { char *folder; char *tags; + char *oldpath; int magic; }; @@ -77,7 +78,6 @@ struct nm_ctxdata { struct uri_tag *query_items; }; - static void url_free_tags(struct uri_tag *tags) { while (tags) { @@ -168,6 +168,7 @@ static void free_hdrdata(struct nm_hdrdata *data) dprint(2, (debugfile, "nm: freeing header %p\n", data)); FREE(&data->folder); FREE(&data->tags); + FREE(&data->oldpath); FREE(&data); } @@ -548,6 +549,22 @@ static int update_message_path(HEADER *h, const char *path) return 1; } +static char *get_folder_from_path(const char *path) +{ + char *p = strrchr(path, '/'); + + if (p && p - path > 3 && + (strncmp(p - 3, "cur", 3) == 0 || + strncmp(p - 3, "new", 3) == 0 || + strncmp(p - 3, "tmp", 3) == 0)) { + + p -= 3; + return strndup(path, p - path - 1); + } + + return NULL; +} + static void deinit_header(HEADER *h) { if (h) { @@ -577,7 +594,8 @@ static int init_header(HEADER *h, const char *path, notmuch_message_t *msg) static void append_message(CONTEXT *ctx, notmuch_message_t *msg) { const char *path = notmuch_message_get_filename(msg); - HEADER *h; + char *newpath = NULL; + HEADER *h = NULL; if (!path) return; @@ -589,14 +607,33 @@ static void append_message(CONTEXT *ctx, notmuch_message_t *msg) if (ctx->msgcount >= ctx->hdrmax) mx_alloc_memory(ctx); - h = maildir_parse_message(M_MAILDIR, path, 0, NULL); - if (!h) - return; + if (access(path, F_OK) == 0) + h = maildir_parse_message(M_MAILDIR, path, 0, NULL); + else { + /* maybe moved try find it... */ + char *folder = get_folder_from_path(path); - if (init_header(h, path, msg) != 0) { + if (folder) { + FILE *f = maildir_open_find_message(folder, path, &newpath); + if (f) { + h = maildir_parse_stream(M_MAILDIR, f, path, 0, NULL); + fclose(f); + + dprint(1, (debugfile, "nm: not up-to-date: %s -> %s\n", + path, newpath)); + } + } + FREE(&folder); + } + + if (!h) { + dprint(1, (debugfile, "nm: failed to parse message: %s\n", path)); + goto done; + } + if (init_header(h, newpath ? newpath : path, msg) != 0) { mutt_free_header(&h); dprint(1, (debugfile, "nm: failed to append header!\n")); - return; + goto done; } h->active = 1; @@ -606,6 +643,15 @@ static void append_message(CONTEXT *ctx, notmuch_message_t *msg) - h->content->hdr_offset; ctx->hdrs[ctx->msgcount] = h; ctx->msgcount++; + + if (newpath) { + /* remember that file has been moved -- nm_sync() will update the DB */ + struct nm_hdrdata *hd = (struct nm_hdrdata *) h->data; + if (hd) + hd->oldpath = safe_strdup(path); + } +done: + FREE(&newpath); } int nm_read_query(CONTEXT *ctx) @@ -824,7 +870,11 @@ int nm_sync(CONTEXT *ctx, int *index_hint) *old = *new = '\0'; - nm_header_get_fullpath(h, old, sizeof(old)); + if (hd->oldpath) { + strncpy(old, hd->oldpath, sizeof(old)); + old[sizeof(old) - 1] = '\0'; + } else + nm_header_get_fullpath(h, old, sizeof(old)); ctx->path = hd->folder; ctx->magic = hd->magic; @@ -855,6 +905,8 @@ int nm_sync(CONTEXT *ctx, int *index_hint) changed = 1; } } + + FREE(&hd->oldpath); } ctx->path = uri; diff --git a/mx.c b/mx.c index ec206a6fe..631882faf 100644 --- a/mx.c +++ b/mx.c @@ -1465,7 +1465,7 @@ MESSAGE *mx_open_message (CONTEXT *ctx, int msgno) if ((msg->fp = fopen (path, "r")) == NULL && errno == ENOENT && (ctx->magic == M_MAILDIR || ctx->magic == M_NOTMUCH)) - msg->fp = maildir_open_find_message (folder, cur->path); + msg->fp = maildir_open_find_message (folder, cur->path, NULL); if (msg->fp == NULL) { diff --git a/mx.h b/mx.h index 490fef6fd..8939d682b 100644 --- a/mx.h +++ b/mx.h @@ -69,6 +69,7 @@ int maildir_check_mailbox (CONTEXT *, int *); int maildir_check_empty (const char *); HEADER *maildir_parse_message (int magic, const char *fname, int is_old, HEADER * _h); +HEADER *maildir_parse_stream (int magic, FILE *f, const char *fname, int is_old, HEADER * _h); void maildir_parse_flags (HEADER * h, const char *path); void maildir_update_flags (CONTEXT *ctx, HEADER *o, HEADER *n); @@ -89,7 +90,7 @@ int mh_commit_message (CONTEXT *, MESSAGE *, HEADER *); int maildir_open_new_message (MESSAGE *, CONTEXT *, HEADER *); int mh_open_new_message (MESSAGE *, CONTEXT *, HEADER *); -FILE *maildir_open_find_message (const char *, const char *); +FILE *maildir_open_find_message (const char *, const char *, char **); int mbox_strict_cmp_headers (const HEADER *, const HEADER *); int mutt_reopen_mailbox (CONTEXT *, int *);