util/disk_cache: use stat() to check if entry is a directory

d_type is not supported on all systems.

Tested-by: Vinson Lee <vlee@freedesktop.org>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97967
(cherry picked from commit d7b3707c612027b354deea6bc5eae56a02d5f8d5)

Squashed with commit:

util/disk_cache: correctly use stat(3)

I forgot to error check stat() and also I wasn't using the subdir in
is_two_character_sub_directory().

Fixes: d7b3707c612 "util/disk_cache: use stat() to check if entry is a directory"
Reviewed-by: Plamena Manolova <plamena.manolova@intel.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit 0cbde643eb29c8bf19eb8551ac8e821f7f733212)
diff --git a/src/util/disk_cache.c b/src/util/disk_cache.c
index 6de608c..d3e8b40 100644
--- a/src/util/disk_cache.c
+++ b/src/util/disk_cache.c
@@ -366,7 +366,8 @@
  */
 static char *
 choose_random_file_matching(const char *dir_path,
-                            bool (*predicate)(struct dirent *))
+                            bool (*predicate)(struct dirent *,
+                                              const char *dir_path))
 {
    DIR *dir;
    struct dirent *entry;
@@ -383,7 +384,7 @@
       entry = readdir(dir);
       if (entry == NULL)
          break;
-      if (! predicate(entry))
+      if (!predicate(entry, dir_path))
          continue;
 
       count++;
@@ -403,7 +404,7 @@
       entry = readdir(dir);
       if (entry == NULL)
          break;
-      if (! predicate(entry))
+      if (!predicate(entry, dir_path))
          continue;
       if (count == victim)
          break;
@@ -428,14 +429,20 @@
  * ".tmp"
  */
 static bool
-is_regular_non_tmp_file(struct dirent *entry)
+is_regular_non_tmp_file(struct dirent *entry, const char *path)
 {
-   size_t len;
-
-   if (entry->d_type != DT_REG)
+   char *filename;
+   if (asprintf(&filename, "%s/%s", path, entry->d_name) == -1)
       return false;
 
-   len = strlen (entry->d_name);
+   struct stat sb;
+   int res = stat(filename, &sb);
+   free(filename);
+
+   if (res == -1 || !S_ISREG(sb.st_mode))
+      return false;
+
+   size_t len = strlen (entry->d_name);
    if (len >= 4 && strcmp(&entry->d_name[len-4], ".tmp") == 0)
       return false;
 
@@ -469,9 +476,17 @@
  * special name of "..")
  */
 static bool
-is_two_character_sub_directory(struct dirent *entry)
+is_two_character_sub_directory(struct dirent *entry, const char *path)
 {
-   if (entry->d_type != DT_DIR)
+   char *subdir;
+   if (asprintf(&subdir, "%s/%s", path, entry->d_name) == -1)
+      return false;
+
+   struct stat sb;
+   int res = stat(subdir, &sb);
+   free(subdir);
+
+   if (res == -1 || !S_ISDIR(sb.st_mode))
       return false;
 
    if (strlen(entry->d_name) != 2)