2019-03-08 18:18:31 +01:00
|
|
|
/* SPDX-License-Identifier: ISC */
|
2019-01-19 17:26:41 +01:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2019-02-04 15:39:43 +01:00
|
|
|
#include "filelist/image_entry.h"
|
2019-01-19 17:26:41 +01:00
|
|
|
|
|
|
|
static int compare_ent(image_entry_t *a, image_entry_t *b)
|
|
|
|
{
|
2019-02-04 18:08:32 +01:00
|
|
|
/* directories < .. < symlinks < devices < .. < files */
|
|
|
|
switch (a->mode & S_IFMT) {
|
|
|
|
case S_IFDIR:
|
2019-01-19 17:26:41 +01:00
|
|
|
if (S_ISDIR(b->mode))
|
|
|
|
goto out_len;
|
|
|
|
return -1;
|
2019-02-04 18:08:32 +01:00
|
|
|
case S_IFREG:
|
|
|
|
if (S_ISREG(b->mode))
|
|
|
|
goto out_fsize;
|
2019-01-19 17:26:41 +01:00
|
|
|
return 1;
|
2019-02-04 18:08:32 +01:00
|
|
|
case S_IFLNK:
|
|
|
|
if (S_ISLNK(b->mode))
|
|
|
|
goto out_len;
|
|
|
|
if (S_ISDIR(b->mode))
|
|
|
|
return 1;
|
|
|
|
return -1;
|
|
|
|
case S_IFBLK:
|
|
|
|
case S_IFCHR:
|
|
|
|
if (S_ISDIR(b->mode) || S_ISLNK(b->mode))
|
|
|
|
return 1;
|
|
|
|
if (S_ISBLK(b->mode) || S_ISCHR(b->mode))
|
|
|
|
goto out_len;
|
|
|
|
return -1;
|
2019-01-19 17:26:41 +01:00
|
|
|
}
|
|
|
|
out_len:
|
|
|
|
return (int)strlen(a->name) - (int)strlen(b->name);
|
2019-02-04 18:08:32 +01:00
|
|
|
out_fsize:
|
|
|
|
if (a->data.file.size > b->data.file.size)
|
|
|
|
return 1;
|
|
|
|
if (a->data.file.size < b->data.file.size)
|
|
|
|
return -1;
|
|
|
|
return 0;
|
2019-01-19 17:26:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static image_entry_t *insert_sorted(image_entry_t *list, image_entry_t *ent)
|
|
|
|
{
|
|
|
|
image_entry_t *it, *prev;
|
|
|
|
|
|
|
|
if (list == NULL || compare_ent(list, ent) > 0) {
|
|
|
|
ent->next = list;
|
|
|
|
return ent;
|
|
|
|
}
|
|
|
|
|
|
|
|
it = list->next;
|
|
|
|
prev = list;
|
|
|
|
|
|
|
|
while (it != NULL) {
|
|
|
|
if (compare_ent(it, ent) > 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
prev = it;
|
|
|
|
it = it->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
prev->next = ent;
|
|
|
|
ent->next = it;
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
image_entry_t *image_entry_sort(image_entry_t *list)
|
|
|
|
{
|
|
|
|
image_entry_t *sorted = NULL, *ent;
|
|
|
|
|
|
|
|
while (list != NULL) {
|
|
|
|
ent = list;
|
|
|
|
list = list->next;
|
|
|
|
|
|
|
|
sorted = insert_sorted(sorted, ent);
|
|
|
|
}
|
|
|
|
|
|
|
|
return sorted;
|
|
|
|
}
|