]> git.notmuchmail.org Git - notmuch/blobdiff - notmuch-new.c
lib: Treat NULL as a valid (and empty) notmuch_filenames_t iterator.
[notmuch] / notmuch-new.c
index e2b5878f06058196f2e1826f681befbe32970641..7d15fe9184183401ab96556ff9f6d7c6168be8c9 100644 (file)
@@ -239,6 +239,8 @@ add_files_recursive (notmuch_database_t *notmuch,
 
     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
@@ -294,9 +296,6 @@ add_files_recursive (notmuch_database_t *notmuch,
        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)
@@ -334,8 +333,27 @@ add_files_recursive (notmuch_database_t *notmuch,
            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) &&
@@ -411,6 +429,30 @@ add_files_recursive (notmuch_database_t *notmuch,
        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)