summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/logic/tpax_archive_append.c133
1 files changed, 78 insertions, 55 deletions
diff --git a/src/logic/tpax_archive_append.c b/src/logic/tpax_archive_append.c
index 76ac436..4bc3d2f 100644
--- a/src/logic/tpax_archive_append.c
+++ b/src/logic/tpax_archive_append.c
@@ -140,6 +140,77 @@ static int tpax_archive_append_ret(
return ret;
}
+static int tpax_archive_append_queue_item(
+ const struct tpax_driver_ctx * dctx,
+ const struct dirent * dirent,
+ const struct tpax_dirent * parent,
+ struct tpax_unit_ctx * unit,
+ int depth,
+ int fd,
+ bool * fkeep)
+
+{
+ struct tpax_dirent_buffer * dentbuf;
+ struct tpax_dirent * cdent;
+ const char * src;
+ char * dst;
+ char * cap;
+ size_t needed;
+
+ if (!(dentbuf = tpax_get_driver_dirents(dctx)))
+ if (!(dentbuf = tpax_dirent_buf_first_alloc(dctx)))
+ return tpax_archive_append_ret(
+ TPAX_SYSTEM_ERROR(dctx),
+ unit);
+
+ needed = dirent->d_reclen;
+ needed += offsetof(struct tpax_dirent,dirent);
+ needed += 0x7;
+ needed |= 0x7;
+ needed ^= 0x7;
+
+ for (; dentbuf->next && (dentbuf->nfree < needed); )
+ dentbuf = dentbuf->next;
+
+ if (dentbuf->nfree < needed)
+ if (!(dentbuf = tpax_dirent_buf_next_alloc(dentbuf)))
+ return tpax_archive_append_ret(
+ TPAX_SYSTEM_ERROR(dctx),
+ unit);
+
+ *fkeep = true;
+ cdent = dentbuf->cdent;
+
+ cdent->fdat = fd;
+ cdent->depth = depth;
+ cdent->nsize = needed;
+ cdent->parent = parent;
+
+ memset(&cdent->dirent,0,offsetof(struct dirent,d_name));
+
+ cdent->dirent.d_ino = dirent->d_ino;
+ cdent->dirent.d_type = dirent->d_type;
+ cdent->dirent.d_reclen = dirent->d_reclen;
+
+ src = dirent->d_name;
+ dst = cdent->dirent.d_name;
+
+ cap = dst - offsetof(struct dirent,d_name);
+ cap -= offsetof(struct tpax_dirent,dirent);
+ cap += needed;
+
+ for (; *src; )
+ *dst++ = *src++;
+
+ for (; dst<cap; )
+ *dst++ = 0;
+
+ dentbuf->cdent = (struct tpax_dirent *)cap;
+ dentbuf->nfree -= needed;
+
+ return 0;
+}
+
static int tpax_archive_append_one(
const struct tpax_driver_ctx * dctx,
const struct tpax_unit_ctx * uctx,
@@ -362,17 +433,11 @@ static int tpax_archive_append_dir(
int fd;
bool fkeep;
long nbytes;
- size_t needed;
struct dirent * dirent;
struct dirent * dirents;
- struct tpax_dirent_buffer * dentbuf;
- struct tpax_dirent * cdent;
struct tpax_unit_ctx * unit;
struct stat st;
uintptr_t addr;
- char * src;
- char * dst;
- char * cap;
/* fake uctx for recursion items */
unit = 0;
@@ -443,55 +508,13 @@ static int tpax_archive_append_dir(
}
if (dirent->d_type == DT_DIR) {
- if (!(dentbuf = tpax_get_driver_dirents(dctx)))
- if (!(dentbuf = tpax_dirent_buf_first_alloc(dctx)))
- return tpax_archive_append_ret(
- TPAX_SYSTEM_ERROR(dctx),
- unit);
-
- needed = dirent->d_reclen;
- needed += offsetof(struct tpax_dirent,dirent);
- needed += 0x7;
- needed |= 0x7;
- needed ^= 0x7;
-
- for (; dentbuf->next && (dentbuf->nfree < needed); )
- dentbuf = dentbuf->next;
-
- if (dentbuf->nfree < needed)
- if (!(dentbuf = tpax_dirent_buf_next_alloc(dentbuf)))
- return tpax_archive_append_ret(
- TPAX_SYSTEM_ERROR(dctx),
- unit);
-
- fkeep = true;
- cdent = dentbuf->cdent;
-
- cdent->fdat = fd;
- cdent->depth = depth;
- cdent->nsize = needed;
- cdent->parent = parent;
-
- memset(&cdent->dirent,0,offsetof(struct dirent,d_name));
-
- cdent->dirent.d_type = dirent->d_type;
- cdent->dirent.d_reclen = dirent->d_reclen;
-
- src = dirent->d_name;
- dst = cdent->dirent.d_name;
-
- cap = dst - offsetof(struct dirent,d_name);
- cap -= offsetof(struct tpax_dirent,dirent);
- cap += needed;
-
- for (; *src; )
- *dst++ = *src++;
-
- for (; dst<cap; )
- *dst++ = 0;
-
- dentbuf->cdent = (struct tpax_dirent *)cap;
- dentbuf->nfree -= needed;
+ if (tpax_archive_append_queue_item(
+ dctx,dirent,
+ parent,unit,depth,
+ fd,&fkeep) < 0)
+ return tpax_archive_append_ret(
+ TPAX_NESTED_ERROR(dctx),
+ unit);
} else {
if (tpax_archive_append_one(
dctx,0,dirent,fd,prefix,