directory = notmuch_database_get_directory (notmuch, path);
db_mtime = notmuch_directory_get_mtime (directory);
+ db_files = notmuch_directory_get_child_files (directory);
+ db_subdirs = notmuch_directory_get_child_directories (directory);
/* If the database knows about this directory, then we sort based
* on strcmp to match the database sorting. Otherwise, we can do
goto DONE;
/* Pass 2: Scan for new files, removed files, and removed directories. */
- db_files = notmuch_directory_get_child_files (directory);
- db_subdirs = notmuch_directory_get_child_directories (directory);
-
for (i = 0; i < num_fs_entries; i++)
{
if (interrupted)
notmuch_filenames_advance (db_subdirs);
}
- if (entry->d_type != DT_REG)
+ /* If we're looking at a symlink, we only want to add it if it
+ * links to a regular file, (and not to a directory, say). */
+ if (entry->d_type == DT_LNK) {
+ int err;
+
+ next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name);
+ err = stat (next, &st);
+ talloc_free (next);
+ next = NULL;
+
+ /* Don't emit an error for a link pointing nowhere, since
+ * the directory-traversal pass will have already done
+ * that. */
+ if (err)
+ continue;
+
+ if (! S_ISREG (st.st_mode))
+ continue;
+ } else if (entry->d_type != DT_REG) {
continue;
+ }
/* Don't add a file that we've added before. */
if (notmuch_filenames_has_more (db_files) &&
next = NULL;
}
+ /* Now that we've walked the whole filesystem list, anything left
+ * over in the database lists has been deleted. */
+ while (notmuch_filenames_has_more (db_files))
+ {
+ char *absolute = talloc_asprintf (state->removed_files,
+ "%s/%s", path,
+ notmuch_filenames_get (db_files));
+
+ _filename_list_add (state->removed_files, absolute);
+
+ notmuch_filenames_advance (db_files);
+ }
+
+ while (notmuch_filenames_has_more (db_subdirs))
+ {
+ char *absolute = talloc_asprintf (state->removed_directories,
+ "%s/%s", path,
+ notmuch_filenames_get (db_subdirs));
+
+ _filename_list_add (state->removed_directories, absolute);
+
+ notmuch_filenames_advance (db_subdirs);
+ }
+
if (! interrupted) {
status = notmuch_directory_set_mtime (directory, fs_mtime);
if (status && ret == NOTMUCH_STATUS_SUCCESS)