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 (; dstcdent = (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 (; dstcdent = (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,