+ (is_maildir && strcmp (entry->d_name, "tmp") == 0) ||
+ strcmp (entry->d_name, ".notmuch") == 0)
+ continue;
+
+ next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name);
+ status = add_files (notmuch, next, state);
+ if (status) {
+ ret = status;
+ goto DONE;
+ }
+ talloc_free (next);
+ next = NULL;
+ }
+
+ /* If the directory's modification time in the filesystem is the
+ * same as what we recorded in the database the last time we
+ * scanned it, then we can skip the second pass entirely.
+ *
+ * We test for strict equality here to avoid a bug that can happen
+ * if the system clock jumps backward, (preventing new mail from
+ * being discovered until the clock catches up and the directory
+ * is modified again).
+ */
+ if (directory && fs_mtime == db_mtime)
+ goto DONE;
+
+ /* If the database has never seen this directory before, we can
+ * simply leave db_files and db_subdirs NULL. */
+ if (directory) {
+ db_files = notmuch_directory_get_child_files (directory);
+ db_subdirs = notmuch_directory_get_child_directories (directory);
+ }
+
+ /* Pass 2: Scan for new files, removed files, and removed directories. */
+ for (i = 0; i < num_fs_entries; i++)
+ {
+ if (interrupted)
+ break;
+
+ entry = fs_entries[i];
+
+ /* Ignore files & directories user has configured to be ignored */
+ if (_entry_in_ignore_list (entry->d_name, state)) {
+ if (state->debug)
+ printf ("(D) add_files, pass 2: explicitly ignoring %s/%s\n",
+ path, entry->d_name);
+ continue;
+ }
+
+ /* Check if we've walked past any names in db_files or
+ * db_subdirs. If so, these have been deleted. */
+ while (notmuch_filenames_valid (db_files) &&
+ strcmp (notmuch_filenames_get (db_files), entry->d_name) < 0)
+ {
+ char *absolute = talloc_asprintf (state->removed_files,
+ "%s/%s", path,
+ notmuch_filenames_get (db_files));
+
+ if (state->debug)
+ printf ("(D) add_files, pass 2: queuing passed file %s for deletion from database\n",
+ absolute);
+
+ _filename_list_add (state->removed_files, absolute);
+
+ notmuch_filenames_move_to_next (db_files);
+ }
+
+ while (notmuch_filenames_valid (db_subdirs) &&
+ strcmp (notmuch_filenames_get (db_subdirs), entry->d_name) <= 0)
+ {
+ const char *filename = notmuch_filenames_get (db_subdirs);
+
+ if (strcmp (filename, entry->d_name) < 0)
+ {
+ char *absolute = talloc_asprintf (state->removed_directories,
+ "%s/%s", path, filename);
+ if (state->debug)
+ printf ("(D) add_files, pass 2: queuing passed directory %s for deletion from database\n",
+ absolute);
+
+ _filename_list_add (state->removed_directories, absolute);
+ }
+
+ notmuch_filenames_move_to_next (db_subdirs);
+ }
+
+ /* Only add regular files (and symlinks to regular files). */
+ entry_type = dirent_type (path, entry);
+ if (entry_type == -1) {
+ fprintf (stderr, "Error reading file %s/%s: %s\n",
+ path, entry->d_name, strerror (errno));
+ return NOTMUCH_STATUS_FILE_ERROR;
+ } else if (entry_type != S_IFREG) {
+ continue;
+ }
+
+ /* Don't add a file that we've added before. */
+ if (notmuch_filenames_valid (db_files) &&
+ strcmp (notmuch_filenames_get (db_files), entry->d_name) == 0)