{
HEADER *h;
char *canon_fname;
+ unsigned header_parsed : 1;
struct maildir *next;
};
ctx->mtime = st.st_mtime;
}
-static HEADER *maildir_parse_message(int magic, const char *fname, int is_old)
+/*
+ * Actually parse a maildir message. This may also be used to fill
+ * out a fake header structure generated by lazy maildir parsing.
+ */
+static HEADER *maildir_parse_message (int magic, const char *fname, int is_old, HEADER *_h)
{
FILE *f;
- HEADER *h = NULL;
+ HEADER *h = _h;
struct stat st;
if ((f = fopen (fname, "r")) != NULL)
{
- h = mutt_new_header();
+ if (!h)
+ h = mutt_new_header();
h->env = mutt_read_rfc822_header (f, h, 0, 0);
fstat (fileno (f), &st);
if (magic == M_MAILDIR)
{
- /* maildir stores its flags in the filename, so ignore the flags in
- * the header of the message
+ /*
+ * 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);
+ maildir_parse_flags (h, fname);
}
}
return h;
}
-/* note that this routine will _not_ modify the context given by ctx. */
+/*
+ * Note that this routine will _not_ modify the context given by
+ * ctx.
+ *
+ * It's used in the first parsing pass on maildir and MH folders.
+ * In the MH case, this means full parsing of the folder. In the
+ * maildir case, it means that we only look at flags, and create a
+ * fake HEADER structure, which may later be filled in by
+ * maildir_parse_message(), when called from
+ * maildir_delayed_parsing().
+ *
+ */
-static int maildir_parse_entry(CONTEXT *ctx, struct maildir ***last,
+static int maildir_parse_entry (CONTEXT *ctx, struct maildir ***last,
const char *subdir, const char *fname,
int *count, int is_old)
{
struct maildir *entry;
- HEADER *h;
+ HEADER *h = NULL;
char buf[_POSIX_PATH_MAX];
if(subdir)
else
snprintf(buf, sizeof(buf), "%s/%s", ctx->path, fname);
- if((h = maildir_parse_message(ctx->magic, buf, is_old)) != NULL)
+ if (ctx->magic == M_MH)
+ h = maildir_parse_message (ctx->magic, buf, is_old, NULL);
+ else
+ {
+ h = mutt_new_header ();
+ h->old = is_old;
+ maildir_parse_flags (h, buf);
+ }
+
+ if (h != NULL)
{
- if(count)
+ if (count)
{
(*count)++;
if (!ctx->quiet && ReadInc && ((*count % ReadInc) == 0 || *count == 1))
entry = safe_calloc(sizeof(struct maildir), 1);
entry->h = h;
+ entry->header_parsed = (ctx->magic == M_MH);
**last = entry;
*last = &entry->next;
return -1;
}
+
+
/* Ignore the garbage files. A valid MH message consists of only
* digits. Deleted message get moved to a filename with a comma before
* it.
return 1;
}
-static int maildir_parse_dir(CONTEXT *ctx, struct maildir ***last,
- const char *subdir, int *count)
+static int maildir_parse_dir (CONTEXT *ctx, struct maildir ***last,
+ const char *subdir, int *count)
{
DIR *dirp;
struct dirent *de;
static void maildir_move_to_context(CONTEXT *ctx, struct maildir **md)
{
- maildir_add_to_context(ctx, *md);
- maildir_free_maildir(md);
+ maildir_add_to_context (ctx, *md);
+ maildir_free_maildir (md);
}
+
+/*
+ * This function does the second parsing pass for a maildir-style
+ * folder.
+ */
+
+void maildir_delayed_parsing (CONTEXT *ctx, struct maildir *md)
+{
+ struct maildir *p;
+ char fn[_POSIX_PATH_MAX];
+
+ for (p = md; p; p = p->next)
+ if (p && p->h && !p->header_parsed)
+ {
+ snprintf (fn, sizeof (fn), "%s/%s", ctx->path, p->h->path);
+ if (maildir_parse_message (ctx->magic, fn, p->h->old, p->h))
+ p->header_parsed = 1;
+ else
+ mutt_free_header (&p->h);
+ }
+}
+
+
+
/* Read a MH/maildir style mailbox.
*
* args:
maildir_update_mtime(ctx);
- if(maildir_parse_dir(ctx, &last, subdir, &count) == -1)
+ if (maildir_parse_dir(ctx, &last, subdir, &count) == -1)
return -1;
if (ctx->magic == M_MH)
mhs_free_sequences (&mhs);
}
+ if (ctx->magic == M_MAILDIR)
+ maildir_delayed_parsing (ctx, md);
+
maildir_move_to_context(ctx, &md);
return 0;
}
dprint(2, (debugfile, "%s:%d: mh_check_mailbox(): Looking for %s.\n", __FILE__, __LINE__, b1));
- if((p = hash_find(fnames, b1)) && p->h &&
- mbox_strict_cmp_headers(ctx->hdrs[i], p->h))
+ if ((p = hash_find(fnames, b1)) && p->h &&
+ (ctx->magic == M_MAILDIR || mbox_strict_cmp_headers(ctx->hdrs[i], p->h)))
{
/* found the right message */
occult = 1;
}
+
}
/* destroy the file name hash */
mx_update_tables(ctx, 0);
}
+ /* If this is a maildir folder, do any delayed parsing we need to do. */
+ if (ctx->magic == M_MAILDIR)
+ maildir_delayed_parsing (ctx, md);
+
/* Incorporate new messages */
maildir_move_to_context(ctx, &md);