]> granicus.if.org Git - neomutt/commitdiff
search in new/cur subfolders if DB is not up-to-date
authorKarel Zak <kzak@redhat.com>
Thu, 12 Apr 2012 12:44:34 +0000 (14:44 +0200)
committerRichard Russon <rich@flatcap.org>
Mon, 4 Apr 2016 15:30:05 +0000 (16:30 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
mh.c
mutt_notmuch.c
mx.c
mx.h

diff --git a/mh.c b/mh.c
index f304b298a79596383c65a023d5655c0e3f80be0b..48a419b4241149742383471b938f9ad3678b14bf 100644 (file)
--- 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)
index cc1c41c5106d01808bd9e29b682e1b8e9645f527..b2f76d5292d9ea2a532c1471b013525744c48153 100644 (file)
@@ -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 ec206a6fe818ca4e8488daed3675a50aa0be94ec..631882faf05adec896adf36ef18f917fa87b5e35 100644 (file)
--- 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 490fef6fd617fb979e0a13033582a84b323c355a..8939d682bde2ff6599038e638e89b7ed78822745 100644 (file)
--- 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 *);