diff options
Diffstat (limited to 'lib/sqfs/xattr_writer.c')
-rw-r--r-- | lib/sqfs/xattr_writer.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/lib/sqfs/xattr_writer.c b/lib/sqfs/xattr_writer.c index 827d0c5..488fd43 100644 --- a/lib/sqfs/xattr_writer.c +++ b/lib/sqfs/xattr_writer.c @@ -115,6 +115,64 @@ struct sqfs_xattr_writer_t { }; +static sqfs_object_t *xattr_writer_copy(const sqfs_object_t *obj) +{ + const sqfs_xattr_writer_t *xwr = (const sqfs_xattr_writer_t *)obj; + kv_block_desc_t *blk, *it, **next; + sqfs_xattr_writer_t *copy; + + copy = calloc(1, sizeof(*copy)); + if (copy == NULL) + return NULL; + + memcpy(copy, xwr, sizeof(*xwr)); + + if (str_table_copy(©->keys, &xwr->keys)) + goto fail_keys; + + if (str_table_copy(©->values, &xwr->values)) + goto fail_values; + + copy->max_pairs = xwr->num_pairs; + copy->num_pairs = xwr->num_pairs; + + copy->kv_pairs = malloc(sizeof(copy->kv_pairs[0]) * xwr->num_pairs); + if (copy->kv_pairs == NULL) + goto fail_pairs; + + memcpy(copy->kv_pairs, xwr->kv_pairs, + sizeof(copy->kv_pairs[0]) * xwr->num_pairs); + + next = &(copy->kv_blocks); + + for (it = xwr->kv_blocks; it != NULL; it = it->next) { + blk = malloc(sizeof(*blk)); + if (blk == NULL) + goto fail_blk; + + memcpy(blk, it, sizeof(*it)); + blk->next = NULL; + + *next = blk; + next = &(blk->next); + } + + return (sqfs_object_t *)copy; +fail_blk: + while (copy->kv_blocks != NULL) { + blk = copy->kv_blocks; + copy->kv_blocks = copy->kv_blocks->next; + free(blk); + } +fail_pairs: + str_table_cleanup(©->values); +fail_values: + str_table_cleanup(©->keys); +fail_keys: + free(copy); + return NULL; +} + static void xattr_writer_destroy(sqfs_object_t *obj) { sqfs_xattr_writer_t *xwr = (sqfs_xattr_writer_t *)obj; @@ -148,6 +206,7 @@ sqfs_xattr_writer_t *sqfs_xattr_writer_create(void) if (xwr->kv_pairs == NULL) goto fail_pairs; + ((sqfs_object_t *)xwr)->copy = xattr_writer_copy; ((sqfs_object_t *)xwr)->destroy = xattr_writer_destroy; return xwr; fail_pairs: |