aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/util/src/unix_dir_iterator.c53
1 files changed, 19 insertions, 34 deletions
diff --git a/lib/util/src/unix_dir_iterator.c b/lib/util/src/unix_dir_iterator.c
index 3f23311..87cf516 100644
--- a/lib/util/src/unix_dir_iterator.c
+++ b/lib/util/src/unix_dir_iterator.c
@@ -35,54 +35,41 @@ static void dir_destroy(sqfs_object_t *obj)
static int dir_read_link(dir_iterator_t *base, char **out)
{
unix_dir_iterator_t *it = (unix_dir_iterator_t *)base;
+ ssize_t ret;
size_t size;
char *str;
*out = NULL;
- if (it->state != 0 || it->ent == NULL) {
- fputs("[BUG] no entry loaded, cannot readlink\n", stderr);
- return SQFS_ERROR_INTERNAL;
- }
+ if (it->state < 0)
+ return it->state;
- if (!S_ISLNK(it->sb.st_mode)) {
- fprintf(stderr, "[BUG] %s is not a symlink, cannot readlink\n",
- it->ent->d_name);
- it->state = SQFS_ERROR_INTERNAL;
- return SQFS_ERROR_INTERNAL;
- }
+ if (it->state > 0 || it->ent == NULL)
+ return SQFS_ERROR_NO_ENTRY;
if ((sizeof(it->sb.st_size) > sizeof(size_t)) &&
it->sb.st_size > SIZE_MAX) {
- goto fail_ov;
+ return SQFS_ERROR_ALLOC;
}
if (SZ_ADD_OV((size_t)it->sb.st_size, 1, &size))
- goto fail_ov;
+ return SQFS_ERROR_ALLOC;
str = calloc(1, size);
- if (str == NULL) {
- perror(it->ent->d_name);
- it->state = SQFS_ERROR_ALLOC;
- return it->state;
- }
+ if (str == NULL)
+ return SQFS_ERROR_ALLOC;
- if (readlinkat(dirfd(it->dir), it->ent->d_name,
- str, (size_t)it->sb.st_size) < 0) {
- fprintf(stderr, "%s: readlink: %s\n", it->ent->d_name,
- strerror(errno));
+ ret = readlinkat(dirfd(it->dir), it->ent->d_name,
+ str, (size_t)it->sb.st_size);
+ if (ret < 0) {
free(str);
- it->state = SQFS_ERROR_INTERNAL;
- return it->state;
+ return SQFS_ERROR_IO;
}
- str[it->sb.st_size] = '\0';
+ str[ret] = '\0';
*out = str;
- return it->state;
-fail_ov:
- fprintf(stderr, "%s: link target too long\n", it->ent->d_name);
- return SQFS_ERROR_OVERFLOW;
+ return 0;
}
static int dir_next(dir_iterator_t *base, dir_entry_t **out)
@@ -100,8 +87,7 @@ static int dir_next(dir_iterator_t *base, dir_entry_t **out)
if (it->ent == NULL) {
if (errno != 0) {
- perror("readdir");
- it->state = SQFS_ERROR_INTERNAL;
+ it->state = SQFS_ERROR_IO;
} else {
it->state = 1;
}
@@ -109,9 +95,9 @@ static int dir_next(dir_iterator_t *base, dir_entry_t **out)
return it->state;
}
- if (fstatat(dirfd(it->dir), it->ent->d_name, &it->sb, AT_SYMLINK_NOFOLLOW)) {
- perror(it->ent->d_name);
- it->state = SQFS_ERROR_INTERNAL;
+ if (fstatat(dirfd(it->dir), it->ent->d_name,
+ &it->sb, AT_SYMLINK_NOFOLLOW)) {
+ it->state = SQFS_ERROR_IO;
return it->state;
}
@@ -119,7 +105,6 @@ static int dir_next(dir_iterator_t *base, dir_entry_t **out)
decoded = alloc_flex(sizeof(*decoded), 1, len + 1);
if (decoded == NULL) {
- perror(it->ent->d_name);
it->state = SQFS_ERROR_ALLOC;
return it->state;
}