X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=lib%2Fmessage.cc;h=b8128505bfb7c63176728bbe145b87113dd4c5a7;hb=404db1de90f6e5a66c34077b38b18a39c955ece2;hp=bc9cd2592adb27e9c0440bf75c41ea9a59bf4fe1;hpb=d422dcf0a276f2806d5563fbdc48fa7d69e4c3eb;p=notmuch diff --git a/lib/message.cc b/lib/message.cc index bc9cd259..b8128505 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -32,7 +32,7 @@ struct _notmuch_message { char *message_id; char *thread_id; char *in_reply_to; - char *filename; + notmuch_filename_list_t *filename_list; char *author; notmuch_message_file_t *message_file; notmuch_message_list_t *replies; @@ -101,7 +101,7 @@ _notmuch_message_create_for_document (const void *talloc_owner, message->message_id = NULL; message->thread_id = NULL; message->in_reply_to = NULL; - message->filename = NULL; + message->filename_list = NULL; message->message_file = NULL; message->author = NULL; @@ -432,9 +432,9 @@ _notmuch_message_add_filename (notmuch_message_t *message, void *local = talloc_new (message); char *direntry; - if (message->filename) { - talloc_free (message->filename); - message->filename = NULL; + if (message->filename_list) { + _notmuch_filename_list_destroy (message->filename_list); + message->filename_list = NULL; } if (filename == NULL) @@ -465,28 +465,23 @@ _notmuch_message_clear_data (notmuch_message_t *message) message->doc.set_data (""); } -const char * -notmuch_message_get_filename (notmuch_message_t *message) +static void +_notmuch_message_ensure_filename_list (notmuch_message_t *message) { const char *prefix = _find_prefix ("file-direntry"); int prefix_len = strlen (prefix); Xapian::TermIterator i; - char *colon, *direntry = NULL; - const char *db_path, *directory, *basename; - unsigned int directory_id; - void *local = talloc_new (message); - if (message->filename) - return message->filename; + if (message->filename_list) + return; + + message->filename_list = _notmuch_filename_list_create (message); i = message->doc.termlist_begin (); i.skip_to (prefix); - if (i != message->doc.termlist_end ()) - direntry = talloc_strdup (local, (*i).c_str ()); - if (i == message->doc.termlist_end () || - strncmp (direntry, prefix, prefix_len)) + strncmp ((*i).c_str (), prefix, prefix_len)) { /* A message document created by an old version of notmuch * (prior to rename support) will have the filename in the @@ -501,39 +496,77 @@ notmuch_message_get_filename (notmuch_message_t *message) if (data == NULL) INTERNAL_ERROR ("message with no filename"); - message->filename = talloc_strdup (message, data); + _notmuch_filename_list_add_filename (message->filename_list, data); - return message->filename; + return; } - direntry += prefix_len; + for (; i != message->doc.termlist_end (); i++) { + void *local = talloc_new (message); + const char *db_path, *directory, *basename, *filename; + char *colon, *direntry = NULL; + unsigned int directory_id; - directory_id = strtol (direntry, &colon, 10); + /* Terminate loop at first term without desired prefix. */ + if (strncmp ((*i).c_str (), prefix, prefix_len)) + break; - if (colon == NULL || *colon != ':') - INTERNAL_ERROR ("malformed direntry"); + direntry = talloc_strdup (local, (*i).c_str ()); - basename = colon + 1; + direntry += prefix_len; - *colon = '\0'; + directory_id = strtol (direntry, &colon, 10); - db_path = notmuch_database_get_path (message->notmuch); + if (colon == NULL || *colon != ':') + INTERNAL_ERROR ("malformed direntry"); - directory = _notmuch_database_get_directory_path (local, - message->notmuch, - directory_id); + basename = colon + 1; - if (strlen (directory)) - message->filename = talloc_asprintf (message, "%s/%s/%s", - db_path, directory, basename); - else - message->filename = talloc_asprintf (message, "%s/%s", - db_path, basename); - talloc_free ((void *) directory); + *colon = '\0'; - talloc_free (local); + db_path = notmuch_database_get_path (message->notmuch); - return message->filename; + directory = _notmuch_database_get_directory_path (local, + message->notmuch, + directory_id); + + if (strlen (directory)) + filename = talloc_asprintf (message, "%s/%s/%s", + db_path, directory, basename); + else + filename = talloc_asprintf (message, "%s/%s", + db_path, basename); + + _notmuch_filename_list_add_filename (message->filename_list, + filename); + + talloc_free (local); + } +} + +const char * +notmuch_message_get_filename (notmuch_message_t *message) +{ + _notmuch_message_ensure_filename_list (message); + + if (message->filename_list == NULL) + return NULL; + + if (message->filename_list->head == NULL || + message->filename_list->head->filename == NULL) + { + INTERNAL_ERROR ("message with no filename"); + } + + return message->filename_list->head->filename; +} + +notmuch_filenames_t * +notmuch_message_get_filenames (notmuch_message_t *message) +{ + _notmuch_message_ensure_filename_list (message); + + return _notmuch_filenames_create (message, message->filename_list); } notmuch_bool_t @@ -826,53 +859,48 @@ notmuch_message_remove_tag (notmuch_message_t *message, const char *tag) return NOTMUCH_STATUS_SUCCESS; } -/* XXX: Needs to iterate over all message filenames. */ notmuch_status_t notmuch_message_maildir_flags_to_tags (notmuch_message_t *message) { - const char *flags, *p; - char f; - bool valid, unread; - unsigned i; + const char *flags; notmuch_status_t status; + notmuch_filenames_t *filenames; const char *filename; + char *combined_flags = talloc_strdup (message, ""); + unsigned i; + int seen_maildir_info = 0; - filename = notmuch_message_get_filename (message); + for (filenames = notmuch_message_get_filenames (message); + notmuch_filenames_valid (filenames); + notmuch_filenames_move_to_next (filenames)) + { + filename = notmuch_filenames_get (filenames); - flags = strstr (filename, ":2,"); - if (!flags) - return NOTMUCH_STATUS_FILE_NOT_EMAIL; - flags += 3; - - /* Check that the letters are valid Maildir flags */ - f = 0; - valid = true; - for (p=flags; valid && *p; p++) { - switch (*p) { - case 'P': - case 'R': - case 'S': - case 'T': - case 'D': - case 'F': - if (*p > f) f=*p; - else valid = false; - break; - default: - valid = false; - } - } - if (!valid) { - fprintf (stderr, "Warning: Invalid maildir flags in filename %s\n", filename); - return NOTMUCH_STATUS_FILE_NOT_EMAIL; + flags = strstr (filename, ":2,"); + if (! flags) + continue; + + seen_maildir_info = 1; + flags += 3; + + combined_flags = talloc_strdup_append (combined_flags, flags); } + /* If none of the filenames have any maildir info field (not even + * an empty info with no flags set) then there's no information to + * go on, so do nothing. */ + if (! seen_maildir_info) + return NOTMUCH_STATUS_SUCCESS; + status = notmuch_message_freeze (message); if (status) return status; - unread = true; + for (i = 0; i < ARRAY_SIZE(flag2tag); i++) { - if ((strchr (flags, flag2tag[i].flag) != NULL) ^ flag2tag[i].inverse) { + if ((strchr (combined_flags, flag2tag[i].flag) != NULL) + ^ + flag2tag[i].inverse) + { status = notmuch_message_add_tag (message, flag2tag[i].tag); } else { status = notmuch_message_remove_tag (message, flag2tag[i].tag); @@ -882,6 +910,8 @@ notmuch_message_maildir_flags_to_tags (notmuch_message_t *message) } status = notmuch_message_thaw (message); + talloc_free (combined_flags); + return status; } @@ -976,14 +1006,19 @@ notmuch_message_tags_to_maildir_flags (notmuch_message_t *message) strcpy (filename_new+(p-filename)+3, flags); if (strcmp (filename, filename_new) != 0) { + notmuch_status_t status; + ret = rename (filename, filename_new); if (ret == -1) { perror (talloc_asprintf (message, "rename of %s to %s failed", filename, filename_new)); exit (1); } - return _notmuch_message_rename (message, filename_new); - /* _notmuch_message_sync is our caller. Do not call it here. */ + status = _notmuch_message_rename (message, filename_new); + + _notmuch_message_sync (message); + + return status; } return NOTMUCH_STATUS_SUCCESS; }