aboutsummaryrefslogtreecommitdiff
path: root/fontconfig/src/fcstat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fontconfig/src/fcstat.c')
-rw-r--r--fontconfig/src/fcstat.c56
1 files changed, 48 insertions, 8 deletions
diff --git a/fontconfig/src/fcstat.c b/fontconfig/src/fcstat.c
index 0c15f8700..fd64d5cb3 100644
--- a/fontconfig/src/fcstat.c
+++ b/fontconfig/src/fcstat.c
@@ -26,6 +26,7 @@
#include "fcint.h"
#include "fcarch.h"
#include <dirent.h>
+#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -159,12 +160,14 @@ Adler32Finish (struct Adler32 *ctx)
return ctx->a + (ctx->b << 16);
}
+#ifdef HAVE_STRUCT_DIRENT_D_TYPE
/* dirent.d_type can be relied upon on FAT filesystem */
static FcBool
FcDirChecksumScandirFilter(const struct dirent *entry)
{
return entry->d_type != DT_DIR;
}
+#endif
static int
FcDirChecksumScandirSorter(const struct dirent **lhs, const struct dirent **rhs)
@@ -177,25 +180,62 @@ FcDirChecksum (const FcChar8 *dir, time_t *checksum)
{
struct Adler32 ctx;
struct dirent **files;
- int n;
+ int n, ret = 0;
+#ifndef HAVE_STRUCT_DIRENT_D_TYPE
+ size_t len = strlen ((const char *)dir);
+#endif
Adler32Init (&ctx);
n = scandir ((const char *)dir, &files,
- &FcDirChecksumScandirFilter,
- &FcDirChecksumScandirSorter);
+#ifdef HAVE_STRUCT_DIRENT_D_TYPE
+ &FcDirChecksumScandirFilter,
+#else
+ NULL,
+#endif
+ &FcDirChecksumScandirSorter);
if (n == -1)
- return -1;
+ return -1;
while (n--)
{
- Adler32Update (&ctx, files[n]->d_name, strlen(files[n]->d_name) + 1);
- Adler32Update (&ctx, (char *)&files[n]->d_type, sizeof(files[n]->d_type));
- free(files[n]);
+ size_t dlen = strlen (files[n]->d_name);
+ int dtype;
+
+#ifdef HAVE_STRUCT_DIRENT_D_TYPE
+ dtype = files[n]->d_type;
+#else
+ struct stat statb;
+ char f[PATH_MAX + 1];
+
+ memcpy (f, dir, len);
+ f[len] = FC_DIR_SEPARATOR;
+ memcpy (&f[len + 1], files[n]->d_name, dlen);
+ f[len + 1 + dlen] = 0;
+ if (lstat (f, &statb) < 0)
+ {
+ ret = -1;
+ goto bail;
+ }
+ if (S_ISDIR (statb.st_mode))
+ goto bail;
+
+ dtype = statb.st_mode;
+#endif
+ Adler32Update (&ctx, files[n]->d_name, dlen + 1);
+ Adler32Update (&ctx, (char *)&dtype, sizeof (int));
+
+#ifndef HAVE_STRUCT_DIRENT_D_TYPE
+ bail:
+#endif
+ free (files[n]);
}
- free(files);
+ free (files);
+ if (ret == -1)
+ return -1;
*checksum = Adler32Finish (&ctx);
+
return 0;
}