summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--content/fetchers/file.c2
-rw-r--r--utils/utils.c35
-rw-r--r--utils/utils.h14
3 files changed, 50 insertions, 1 deletions
diff --git a/content/fetchers/file.c b/content/fetchers/file.c
index 4fe1c9867..c574c2160 100644
--- a/content/fetchers/file.c
+++ b/content/fetchers/file.c
@@ -508,7 +508,7 @@ static void fetch_file_process_dir(struct fetch_file_context *ctx,
int i; /* directory entry index */
int n; /* number of directory entries */
- n = scandir(ctx->path, &listing, 0, alphasort);
+ n = scandir(ctx->path, &listing, 0, dir_sort_alpha);
if (n < 0) {
fetch_file_process_error(ctx,
fetch_file_errno_to_http_code(errno));
diff --git a/utils/utils.c b/utils/utils.c
index 7155ef78d..ac9f5af7a 100644
--- a/utils/utils.c
+++ b/utils/utils.c
@@ -340,6 +340,41 @@ char *strndup(const char *s, size_t n)
#endif
+/* Exported interface, documented in utils.c */
+int dir_sort_alpha(const struct dirent **d1, const struct dirent **d2)
+{
+ const char *s1 = (*d1)->d_name;
+ const char *s2 = (*d2)->d_name;
+
+ while (*s1 != '\0' && *s2 != '\0') {
+ if ((*s1 >= '0' && *s1 <= '9') &&
+ (*s2 >= '0' && *s2 <= '9')) {
+ int n1 = 0, n2 = 0;
+ while (*s1 >= '0' && *s1 <= '9') {
+ n1 = n1 * 10 + (*s1) - '0';
+ s1++;
+ }
+ while (*s2 >= '0' && *s2 <= '9') {
+ n2 = n2 * 10 + (*s2) - '0';
+ s2++;
+ }
+ if (n1 != n2) {
+ return n1 - n2;
+ }
+ if (*s1 == '\0' || *s2 == '\0')
+ break;
+ }
+ if (tolower(*s1) != tolower(*s2))
+ break;
+
+ s1++;
+ s2++;
+ }
+
+ return tolower(*s1) - tolower(*s2);
+}
+
+
#ifndef HAVE_SCANDIR
int alphasort(const struct dirent **d1, const struct dirent **d2)
{
diff --git a/utils/utils.h b/utils/utils.h
index 8172d2d26..a1ff683d3 100644
--- a/utils/utils.h
+++ b/utils/utils.h
@@ -29,6 +29,8 @@
#include <regex.h>
#include <assert.h>
+struct dirent;
+
#ifndef NOF_ELEMENTS
#define NOF_ELEMENTS(array) (sizeof(array)/sizeof(*(array)))
#endif
@@ -157,6 +159,18 @@ char *human_friendly_bytesize(unsigned long bytesize);
const char *rfc1123_date(time_t t);
unsigned int wallclock(void);
+
+/**
+ * Comparison function for sorting directories.
+ *
+ * Correctly orders non zero-padded numerical parts.
+ * ie. produces "file1, file2, file10" rather than "file1, file10, file2".
+ *
+ * d1 first directory entry
+ * d2 second directory entry
+ */
+int dir_sort_alpha(const struct dirent **d1, const struct dirent **d2);
+
/**
* Return a hex digit for the given numerical value.
*