Some platforms don't provide DT_REG/DT_LNK/DT_DIR. Create wrapper functions which test the presence of those symbols and fall back to stat(2).
--- Not sure if I got the handling of DT_UNKNOWN correct in all cases. Someone please double-check that. notmuch-new.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 62 insertions(+), 8 deletions(-) diff --git a/notmuch-new.c b/notmuch-new.c index 44b50aa..95ddddb 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -140,6 +140,62 @@ dirent_sort_strcmp_name (const struct dirent **a, const struct dirent **b) return strcmp ((*a)->d_name, (*b)->d_name); } +/* Helper functions to test if a given dirent is of a certain type + */ +static int +_is_reg(const char *path, struct dirent *entry) +{ +#ifdef DT_REG + if (entry->d_type == DT_REG) + return 1; +#endif + + char buffer[PATH_MAX]; + snprintf(buffer, PATH_MAX, "%s/%s", path, entry->d_name); + + struct stat sbuf; + if (!stat(buffer, &sbuf)) + return S_ISREG(sbuf.st_mode); + + return 0; +} + +static int +_is_dir(const char *path, struct dirent *entry) +{ +#ifdef DT_DIR + if (entry->d_type == DT_DIR) + return 1; +#endif + + char buffer[PATH_MAX]; + snprintf(buffer, PATH_MAX, "%s/%s", path, entry->d_name); + + struct stat sbuf; + if (!stat(buffer, &sbuf)) + return S_ISDIR(sbuf.st_mode); + + return 0; +} + +static int +_is_lnk(const char *path, struct dirent *entry) +{ +#ifdef DT_LNK + if (entry->d_type == DT_LNK) + return 1; +#endif + + char buffer[PATH_MAX]; + snprintf(buffer, PATH_MAX, "%s/%s", path, entry->d_name); + + struct stat sbuf; + if (!stat(buffer, &sbuf)) + return S_ISLNK(sbuf.st_mode); + + return 0; +} + /* Test if the directory looks like a Maildir directory. * * Search through the array of directory entries to see if we can find all @@ -148,12 +204,12 @@ dirent_sort_strcmp_name (const struct dirent **a, const struct dirent **b) * Return 1 if the directory looks like a Maildir and 0 otherwise. */ static int -_entries_resemble_maildir (struct dirent **entries, int count) +_entries_resemble_maildir (const char *path, struct dirent **entries, int count) { int i, found = 0; for (i = 0; i < count; i++) { - if (entries[i]->d_type != DT_DIR && entries[i]->d_type != DT_UNKNOWN) + if (!_is_dir(path, entries[i])) continue; if (strcmp(entries[i]->d_name, "new") == 0 || @@ -265,7 +321,7 @@ add_files_recursive (notmuch_database_t *notmuch, } /* Pass 1: Recurse into all sub-directories. */ - is_maildir = _entries_resemble_maildir (fs_entries, num_fs_entries); + is_maildir = _entries_resemble_maildir (path, fs_entries, num_fs_entries); for (i = 0; i < num_fs_entries; i++) { if (interrupted) @@ -280,9 +336,7 @@ add_files_recursive (notmuch_database_t *notmuch, * scandir results, then it might be a directory (and if not, * then we'll stat and return immediately in the next level of * recursion). */ - if (entry->d_type != DT_DIR && - entry->d_type != DT_LNK && - entry->d_type != DT_UNKNOWN) + if (!_is_dir(path, entry) && !_is_lnk(path, entry)) { continue; } @@ -360,7 +414,7 @@ add_files_recursive (notmuch_database_t *notmuch, * * In either case, a stat does the trick. */ - if (entry->d_type == DT_LNK || entry->d_type == DT_UNKNOWN) { + if (_is_lnk(path, entry)) { int err; next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name); @@ -376,7 +430,7 @@ add_files_recursive (notmuch_database_t *notmuch, if (! S_ISREG (st.st_mode)) continue; - } else if (entry->d_type != DT_REG) { + } else if (!_is_reg(path, entry)) { continue; } -- 1.7.0.5 _______________________________________________ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch