From 67ae2377a9ec2da296a2e012352f962664a4d1a8 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Fri, 18 May 2012 00:13:36 -0400 Subject: lib: Perform the same transformation to _notmuch_database_filename_to_direntry Now _notmuch_database_filename_to_direntry takes a flags argument and can indicate if the necessary directory documents do not exist. Again, callers have been updated, but retain their original behavior. --- lib/message.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'lib/message.cc') diff --git a/lib/message.cc b/lib/message.cc index 0075425..8d552f1 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -495,9 +495,8 @@ _notmuch_message_add_filename (notmuch_message_t *message, if (status) return status; - status = _notmuch_database_filename_to_direntry (local, - message->notmuch, - filename, &direntry); + status = _notmuch_database_filename_to_direntry ( + local, message->notmuch, filename, NOTMUCH_FIND_CREATE, &direntry); if (status) return status; @@ -541,8 +540,8 @@ _notmuch_message_remove_filename (notmuch_message_t *message, notmuch_status_t status; Xapian::TermIterator i, last; - status = _notmuch_database_filename_to_direntry (local, message->notmuch, - filename, &direntry); + status = _notmuch_database_filename_to_direntry ( + local, message->notmuch, filename, NOTMUCH_FIND_CREATE, &direntry); if (status) return status; -- cgit v1.2.3 From d9f61c26a1344b123c1812392bc39c32634a099a Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Fri, 18 May 2012 00:13:42 -0400 Subject: lib: Don't needlessly create directory docs in _notmuch_message_remove_filename Previously, if passed a filename with a directory that did not exist in the database, _notmuch_message_remove_filename would needlessly create that directory document. Fix it so that doesn't happen. --- lib/message.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/message.cc') diff --git a/lib/message.cc b/lib/message.cc index 8d552f1..6787506 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -541,8 +541,8 @@ _notmuch_message_remove_filename (notmuch_message_t *message, Xapian::TermIterator i, last; status = _notmuch_database_filename_to_direntry ( - local, message->notmuch, filename, NOTMUCH_FIND_CREATE, &direntry); - if (status) + local, message->notmuch, filename, NOTMUCH_FIND_LOOKUP, &direntry); + if (status || !direntry) return status; /* Unlink this file from its parent directory. */ -- cgit v1.2.3 From 93ab4c7d119bb751c4d7297cb18a6f5eb50ae478 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Sat, 9 Jun 2012 15:14:15 -0400 Subject: lib: Move _filename_is_in_maildir This way notmuch_message_maildir_flags_to_tags can call it. It makes more sense for this to be just above all of the maildir synchronization code rather than mixed in the middle. --- lib/message.cc | 82 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) (limited to 'lib/message.cc') diff --git a/lib/message.cc b/lib/message.cc index 6787506..ed96477 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -1027,6 +1027,47 @@ notmuch_message_remove_tag (notmuch_message_t *message, const char *tag) return NOTMUCH_STATUS_SUCCESS; } +/* Is the given filename within a maildir directory? + * + * Specifically, is the final directory component of 'filename' either + * "cur" or "new". If so, return a pointer to that final directory + * component within 'filename'. If not, return NULL. + * + * A non-NULL return value is guaranteed to be a valid string pointer + * pointing to the characters "new/" or "cur/", (but not + * NUL-terminated). + */ +static const char * +_filename_is_in_maildir (const char *filename) +{ + const char *slash, *dir = NULL; + + /* Find the last '/' separating directory from filename. */ + slash = strrchr (filename, '/'); + if (slash == NULL) + return NULL; + + /* Jump back 4 characters to where the previous '/' will be if the + * directory is named "cur" or "new". */ + if (slash - filename < 4) + return NULL; + + slash -= 4; + + if (*slash != '/') + return NULL; + + dir = slash + 1; + + if (STRNCMP_LITERAL (dir, "cur/") == 0 || + STRNCMP_LITERAL (dir, "new/") == 0) + { + return dir; + } + + return NULL; +} + notmuch_status_t notmuch_message_maildir_flags_to_tags (notmuch_message_t *message) { @@ -1083,47 +1124,6 @@ notmuch_message_maildir_flags_to_tags (notmuch_message_t *message) return status; } -/* Is the given filename within a maildir directory? - * - * Specifically, is the final directory component of 'filename' either - * "cur" or "new". If so, return a pointer to that final directory - * component within 'filename'. If not, return NULL. - * - * A non-NULL return value is guaranteed to be a valid string pointer - * pointing to the characters "new/" or "cur/", (but not - * NUL-terminated). - */ -static const char * -_filename_is_in_maildir (const char *filename) -{ - const char *slash, *dir = NULL; - - /* Find the last '/' separating directory from filename. */ - slash = strrchr (filename, '/'); - if (slash == NULL) - return NULL; - - /* Jump back 4 characters to where the previous '/' will be if the - * directory is named "cur" or "new". */ - if (slash - filename < 4) - return NULL; - - slash -= 4; - - if (*slash != '/') - return NULL; - - dir = slash + 1; - - if (STRNCMP_LITERAL (dir, "cur/") == 0 || - STRNCMP_LITERAL (dir, "new/") == 0) - { - return dir; - } - - return NULL; -} - /* From the set of tags on 'message' and the flag2tag table, compute a * set of maildir-flag actions to be taken, (flags that should be * either set or cleared). -- cgit v1.2.3 From 750231bae8a0bdb3273c2f9a74da14327fbc5d52 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Sat, 9 Jun 2012 15:14:16 -0400 Subject: lib: Only synchronize maildir flags for messages in maildirs Previously, we synchronized flags to tags for any message that looked like it had maildir flags in its file name, regardless of whether it was in a maildir-like directory structure. This was asymmetric with tag-to-flag synchronization, which only applied to messages in directories named new/ and cur/ (introduced by 95dd5fe5). This change makes our interpretation stricter and addresses this asymmetry by only synchronizing flags to tags for messages in directories named new/ or cur/. It also prepares us to treat messages in new/ as maildir messages, even though they lack maildir flags. --- lib/message.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/message.cc') diff --git a/lib/message.cc b/lib/message.cc index ed96477..bbac2ff 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -1074,7 +1074,7 @@ notmuch_message_maildir_flags_to_tags (notmuch_message_t *message) const char *flags; notmuch_status_t status; notmuch_filenames_t *filenames; - const char *filename; + const char *filename, *dir; char *combined_flags = talloc_strdup (message, ""); unsigned i; int seen_maildir_info = 0; @@ -1084,6 +1084,10 @@ notmuch_message_maildir_flags_to_tags (notmuch_message_t *message) notmuch_filenames_move_to_next (filenames)) { filename = notmuch_filenames_get (filenames); + dir = _filename_is_in_maildir (filename); + + if (! dir) + continue; flags = strstr (filename, ":2,"); if (! flags) -- cgit v1.2.3 From b88030bda6da084ef74e41f588589fd98e773ad7 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Sat, 9 Jun 2012 15:14:17 -0400 Subject: lib: Treat messages in new/ as maildir messages with no flags set Previously, notmuch new only synchronized maildir flags to tags for files with a maildir "info" part. Since messages in new/ don't have an info part, notmuch would ignore them for flag-to-tag synchronization. This patch makes notmuch consider messages in new/ to be legitimate maildir messages that simply have no maildir flags set. The most visible effect of this is that such messages now automatically get the unread tag. --- lib/message.cc | 20 +++++++++++++------- test/maildir-sync | 1 - 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'lib/message.cc') diff --git a/lib/message.cc b/lib/message.cc index bbac2ff..978de06 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -1090,13 +1090,19 @@ notmuch_message_maildir_flags_to_tags (notmuch_message_t *message) continue; flags = strstr (filename, ":2,"); - if (! flags) - continue; - - seen_maildir_info = 1; - flags += 3; - - combined_flags = talloc_strdup_append (combined_flags, flags); + if (flags) { + seen_maildir_info = 1; + flags += 3; + combined_flags = talloc_strdup_append (combined_flags, flags); + } else if (STRNCMP_LITERAL (dir, "new/") == 0) { + /* Messages are delivered to new/ with no "info" part, but + * they effectively have default maildir flags. According + * to the spec, we should ignore the info part for + * messages in new/, but some MUAs (mutt) can set maildir + * flags on messages in new/, so we're liberal in what we + * accept. */ + seen_maildir_info = 1; + } } /* If none of the filenames have any maildir info field (not even diff --git a/test/maildir-sync b/test/maildir-sync index 6360fd2..01348d3 100755 --- a/test/maildir-sync +++ b/test/maildir-sync @@ -167,7 +167,6 @@ notmuch tag +unread +draft -flagged subject:"Non-compliant maildir info" test_expect_equal "$(cd $MAIL_DIR/cur/; ls non-compliant*)" "non-compliant-maildir-info:2,These-are-not-flags-in-ASCII-order-donottouch" test_begin_subtest "Files in new/ get default synchronized tags" -test_subtest_known_broken OLDCONFIG=$(notmuch config get new.tags) notmuch config set new.tags test add_message [subject]='"File in new/"' [dir]=new [filename]='file-in-new' -- cgit v1.2.3