From 66262c10d10c173519d423341ec0f4839240b1aa Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Thu, 2 Sep 2021 20:41:28 +0300 Subject: Provide functions for manipulating arrays of extended attributes * src/common.h (xheader_xattr_free,xheader_xattr_copy): Remove protos. (xattr_map_init,xattr_map_copy) (xattr_map_add,xattr_map_free): New protos. * src/tar.h (xattr_map): New struct. (tar_stat_info): Replace xattr_map_size and xattr_map with one field: xattr_map. * src/xattrs.c (XATTRS_PREFIX,XATTRS_PREFIX_LEN): New defines. (xheader_xattr_init,xattr_map_init) (xattr_map_free,xattr_map_add) (xheader_xattr_add,xattr_map_copy): New functions. All uses changed. * src/create.c (start_header): Update to use struct xattr_map. * src/extract.c: Update to use struct xattr_map. * src/tar.c: Likewise. * src/xheader.c (xheader_xattr_init,xheader_xattr_free) (xheader_xattr_add,xheader_xattr_copy): Remove. (xattr_coder,xattr_decoder): Use xattr_map_ functions. --- src/common.h | 10 ++++-- src/create.c | 11 ++----- src/extract.c | 25 +++++--------- src/tar.c | 2 +- src/tar.h | 10 ++++-- src/xattrs.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- src/xheader.c | 95 +++-------------------------------------------------- 7 files changed, 123 insertions(+), 134 deletions(-) diff --git a/src/common.h b/src/common.h index 40ccdd12..7961f35c 100644 --- a/src/common.h +++ b/src/common.h @@ -881,12 +881,16 @@ bool xheader_keyword_deleted_p (const char *kw); char *xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n); void xheader_xattr_init (struct tar_stat_info *st); -void xheader_xattr_free (struct xattr_array *vals, size_t sz); -void xheader_xattr_copy (const struct tar_stat_info *st, - struct xattr_array **vals, size_t *sz); void xheader_xattr_add (struct tar_stat_info *st, const char *key, const char *val, size_t len); +void xattr_map_init (struct xattr_map *map); +void xattr_map_copy (struct xattr_map *dst, + const struct xattr_map *src); +void xattr_map_add (struct xattr_map *map, + const char *key, const char *val, size_t len); +void xattr_map_free (struct xattr_map *xattr_map); + /* Module system.c */ void sys_detect_dev_null_output (void); diff --git a/src/create.c b/src/create.c index 7ca742f5..941c38be 100644 --- a/src/create.c +++ b/src/create.c @@ -966,14 +966,9 @@ start_header (struct tar_stat_info *st) xheader_store ("RHT.security.selinux", st, NULL); if (xattrs_option > 0) { - size_t scan_xattr = 0; - struct xattr_array *xattr_map = st->xattr_map; - - while (scan_xattr < st->xattr_map_size) - { - xheader_store (xattr_map[scan_xattr].xkey, st, &scan_xattr); - ++scan_xattr; - } + size_t i; + for (i = 0; i < st->xattr_map.xm_size; i++) + xheader_store (st->xattr_map.xm_map[i].xkey, st, &i); } } diff --git a/src/extract.c b/src/extract.c index 7a95892e..850a08a2 100644 --- a/src/extract.c +++ b/src/extract.c @@ -105,7 +105,7 @@ struct delayed_set_stat char *acls_d_ptr; size_t acls_d_len; size_t xattr_map_size; - struct xattr_array *xattr_map; + struct xattr_map xattr_map; /* Length and contents of name. */ size_t file_name_len; char *file_name; @@ -155,8 +155,7 @@ struct delayed_link char *acls_d_ptr; size_t acls_d_len; - size_t xattr_map_size; - struct xattr_array *xattr_map; + struct xattr_map xattr_map; /* The desired target of the desired link. */ char target[1]; @@ -503,6 +502,7 @@ delay_set_stat (char const *file_name, struct tar_stat_info const *st, data->dev = st->stat.st_dev; data->ino = st->stat.st_ino; } + xattr_map_init (&data->xattr_map); } data->mode = mode; @@ -542,12 +542,7 @@ delay_set_stat (char const *file_name, struct tar_stat_info const *st, data->acls_d_len = 0; } if (st) - xheader_xattr_copy (st, &data->xattr_map, &data->xattr_map_size); - else - { - data->xattr_map = NULL; - data->xattr_map_size = 0; - } + xattr_map_copy (&data->xattr_map, &st->xattr_map); if (must_be_dot_or_slash (file_name)) mark_after_links (data); } @@ -595,7 +590,7 @@ static void free_delayed_set_stat (struct delayed_set_stat *data) { free (data->file_name); - xheader_xattr_free (data->xattr_map, data->xattr_map_size); + xattr_map_free (&data->xattr_map); free (data->cntx_name); free (data->acls_a_ptr); free (data->acls_d_ptr); @@ -859,7 +854,7 @@ set_xattr (char const *file_name, struct tar_stat_info const *st, #ifdef HAVE_XATTRS bool interdir_made = false; - if ((xattrs_option > 0) && st->xattr_map_size) + if ((xattrs_option > 0) && st->xattr_map.xm_size) { mode_t mode = current_stat_info.stat.st_mode & MODE_RWX & ~ current_umask; @@ -957,7 +952,6 @@ apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links) sb.acls_d_ptr = data->acls_d_ptr; sb.acls_d_len = data->acls_d_len; sb.xattr_map = data->xattr_map; - sb.xattr_map_size = data->xattr_map_size; set_stat (data->file_name, &sb, -1, current_mode, current_mode_mask, DIRTYPE, data->interdir, data->atflag); @@ -1447,8 +1441,8 @@ create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made, p->acls_a_len = 0; p->acls_d_ptr = NULL; p->acls_d_len = 0; - xheader_xattr_copy (¤t_stat_info, &p->xattr_map, - &p->xattr_map_size); + xattr_map_init (&p->xattr_map); + xattr_map_copy (&p->xattr_map, ¤t_stat_info.xattr_map); strcpy (p->target, current_stat_info.link_name); if ((h = find_direct_ancestor (file_name)) != NULL) @@ -1882,7 +1876,6 @@ apply_delayed_links (void) st1.acls_d_ptr = ds->acls_d_ptr; st1.acls_d_len = ds->acls_d_len; st1.xattr_map = ds->xattr_map; - st1.xattr_map_size = ds->xattr_map_size; set_stat (source, &st1, -1, 0, 0, SYMTYPE, false, AT_SYMLINK_NOFOLLOW); valid_source = source; @@ -1897,7 +1890,7 @@ apply_delayed_links (void) sources = next; } - xheader_xattr_free (ds->xattr_map, ds->xattr_map_size); + xattr_map_free (&ds->xattr_map); free (ds->cntx_name); { diff --git a/src/tar.c b/src/tar.c index fc3c470d..de85d4ba 100644 --- a/src/tar.c +++ b/src/tar.c @@ -2883,7 +2883,7 @@ void tar_stat_destroy (struct tar_stat_info *st) { tar_stat_close (st); - xheader_xattr_free (st->xattr_map, st->xattr_map_size); + xattr_map_free (&st->xattr_map); free (st->orig_file_name); free (st->file_name); free (st->link_name); diff --git a/src/tar.h b/src/tar.h index 9214c814..0a8c470d 100644 --- a/src/tar.h +++ b/src/tar.h @@ -284,6 +284,13 @@ struct xattr_array size_t xval_len; }; +struct xattr_map +{ + struct xattr_array *xm_map; + size_t xm_size; /* Size of the xattr map */ + size_t xm_max; /* Max. number of entries in xattr_map */ +}; + struct tar_stat_info { char *orig_file_name; /* name of file read from the archive header */ @@ -334,8 +341,7 @@ struct tar_stat_info processed pax header parsing. Following 'path' header (lower priority) will be ignored. */ - size_t xattr_map_size; /* Size of the xattr map */ - struct xattr_array *xattr_map; + struct xattr_map xattr_map; /* Extended headers */ struct xheader xhdr; diff --git a/src/xattrs.c b/src/xattrs.c index bbf68815..d2a8df70 100644 --- a/src/xattrs.c +++ b/src/xattrs.c @@ -30,6 +30,83 @@ #include "xattr-at.h" #include "selinux-at.h" +#define XATTRS_PREFIX "SCHILY.xattr." +#define XATTRS_PREFIX_LEN (sizeof XATTRS_PREFIX - 1) + +void +xheader_xattr_init (struct tar_stat_info *st) +{ + xattr_map_init (&st->xattr_map); + + st->acls_a_ptr = NULL; + st->acls_a_len = 0; + st->acls_d_ptr = NULL; + st->acls_d_len = 0; + st->cntx_name = NULL; +} + +void +xattr_map_init (struct xattr_map *map) +{ + memset (map, 0, sizeof *map); +} + +void +xattr_map_free (struct xattr_map *xattr_map) +{ + size_t i; + + for (i = 0; i < xattr_map->xm_size; i++) + { + free (xattr_map->xm_map[i].xkey); + free (xattr_map->xm_map[i].xval_ptr); + } + free (xattr_map->xm_map); +} + +void +xattr_map_add (struct xattr_map *map, + const char *key, const char *val, size_t len) +{ + struct xattr_array *p; + + if (map->xm_size == map->xm_max) + map->xm_map = x2nrealloc (map->xm_map, &map->xm_max, + sizeof (map->xm_map[0])); + p = &map->xm_map[map->xm_size]; + p->xkey = xstrdup (key); + p->xval_ptr = xmemdup (val, len + 1); + p->xval_len = len; + map->xm_size++; +} + +void +xheader_xattr_add (struct tar_stat_info *st, + const char *key, const char *val, size_t len) +{ + size_t klen = strlen (key); + char *xkey = xmalloc (XATTRS_PREFIX_LEN + klen + 1); + char *tmp = xkey; + + tmp = stpcpy (tmp, XATTRS_PREFIX); + stpcpy (tmp, key); + + xattr_map_add (&st->xattr_map, xkey, val, len); + + free (xkey); +} + +void +xattr_map_copy (struct xattr_map *dst, const struct xattr_map *src) +{ + size_t i; + + for (i = 0; i < src->xm_size; i++) + xattr_map_add (dst, src->xm_map[i].xkey, + src->xm_map[i].xval_ptr, + src->xm_map[i].xval_len); +} + struct xattrs_mask_map { const char **masks; @@ -678,15 +755,14 @@ xattrs_xattrs_set (struct tar_stat_info const *st, WARN ((0, 0, _("XATTR support is not available"))); done = 1; #else - size_t scan = 0; + size_t i; - if (!st->xattr_map_size) + if (!st->xattr_map.xm_size) return; - for (; scan < st->xattr_map_size; ++scan) + for (i = 0; i < st->xattr_map.xm_size; i++) { - char *keyword = st->xattr_map[scan].xkey; - keyword += strlen ("SCHILY.xattr."); + char *keyword = st->xattr_map.xm_map[i].xkey + XATTRS_PREFIX_LEN; /* TODO: this 'later_run' workaround is temporary solution -> once capabilities should become fully supported by it's API and there @@ -703,8 +779,8 @@ xattrs_xattrs_set (struct tar_stat_info const *st, continue; xattrs__fd_set (st, file_name, typeflag, keyword, - st->xattr_map[scan].xval_ptr, - st->xattr_map[scan].xval_len); + st->xattr_map.xm_map[i].xval_ptr, + st->xattr_map.xm_map[i].xval_len); } #endif } @@ -728,10 +804,10 @@ xattrs_print_char (struct tar_stat_info const *st, char *output) output[1] = 0; } - if (xattrs_option > 0 && st->xattr_map_size) - for (i = 0; i < st->xattr_map_size; ++i) + if (xattrs_option > 0 && st->xattr_map.xm_size) + for (i = 0; i < st->xattr_map.xm_size; ++i) { - char *keyword = st->xattr_map[i].xkey + strlen ("SCHILY.xattr."); + char *keyword = st->xattr_map.xm_map[i].xkey + XATTRS_PREFIX_LEN; if (!xattrs_masked_out (keyword, false /* like extracting */ )) { *output = '*'; @@ -768,16 +844,16 @@ xattrs_print (struct tar_stat_info const *st) } /* xattrs */ - if (xattrs_option > 0 && st->xattr_map_size) + if (xattrs_option > 0 && st->xattr_map.xm_size) { int i; - for (i = 0; i < st->xattr_map_size; ++i) + for (i = 0; i < st->xattr_map.xm_size; ++i) { - char *keyword = st->xattr_map[i].xkey + strlen ("SCHILY.xattr."); + char *keyword = st->xattr_map.xm_map[i].xkey + XATTRS_PREFIX_LEN; if (!xattrs_masked_out (keyword, false /* like extracting */ )) fprintf (stdlis, " x: %lu %s\n", - (unsigned long) st->xattr_map[i].xval_len, keyword); + (unsigned long) st->xattr_map.xm_map[i].xval_len, keyword); } } } diff --git a/src/xheader.c b/src/xheader.c index 3cd694d1..a9075099 100644 --- a/src/xheader.c +++ b/src/xheader.c @@ -492,48 +492,6 @@ xheader_forbid_global (void) USAGE_ERROR ((0, 0, _("can't update global extended header record"))); } -void -xheader_xattr_init (struct tar_stat_info *st) -{ - st->xattr_map = NULL; - st->xattr_map_size = 0; - - st->acls_a_ptr = NULL; - st->acls_a_len = 0; - st->acls_d_ptr = NULL; - st->acls_d_len = 0; - st->cntx_name = NULL; -} - -void -xheader_xattr_free (struct xattr_array *xattr_map, size_t xattr_map_size) -{ - size_t scan = 0; - - while (scan < xattr_map_size) - { - free (xattr_map[scan].xkey); - free (xattr_map[scan].xval_ptr); - - ++scan; - } - free (xattr_map); -} - -static void -xheader_xattr__add (struct xattr_array **xattr_map, - size_t *xattr_map_size, - const char *key, const char *val, size_t len) -{ - size_t pos = (*xattr_map_size)++; - - *xattr_map = xrealloc (*xattr_map, - *xattr_map_size * sizeof(struct xattr_array)); - (*xattr_map)[pos].xkey = xstrdup (key); - (*xattr_map)[pos].xval_ptr = xmemdup (val, len + 1); - (*xattr_map)[pos].xval_len = len; -} - /* This is reversal function for xattr_encode_keyword. See comment for xattr_encode_keyword() for more info. */ static void @@ -571,44 +529,6 @@ xattr_decode_keyword (char *keyword) kpl++; } } - -void -xheader_xattr_add (struct tar_stat_info *st, - const char *key, const char *val, size_t len) -{ - size_t klen = strlen (key); - char *xkey = xmalloc (strlen("SCHILY.xattr.") + klen + 1); - char *tmp = xkey; - - tmp = stpcpy (tmp, "SCHILY.xattr."); - stpcpy (tmp, key); - - xheader_xattr__add (&st->xattr_map, &st->xattr_map_size, xkey, val, len); - - free (xkey); -} - -void -xheader_xattr_copy (const struct tar_stat_info *st, - struct xattr_array **xattr_map, size_t *xattr_map_size) -{ - size_t scan = 0; - - *xattr_map = NULL; - *xattr_map_size = 0; - - while (scan < st->xattr_map_size) - { - char *key = st->xattr_map[scan].xkey; - char *val = st->xattr_map[scan].xval_ptr; - size_t len = st->xattr_map[scan].xval_len; - - xheader_xattr__add(xattr_map, xattr_map_size, key, val, len); - - ++scan; - } -} - /* General Interface */ @@ -1705,31 +1625,26 @@ static void xattr_coder (struct tar_stat_info const *st, char const *keyword, struct xheader *xhdr, void const *data) { - struct xattr_array *xattr_map = st->xattr_map; - const size_t *off = data; + size_t n = *(size_t *)data; xheader_print_n (xhdr, keyword, - xattr_map[*off].xval_ptr, xattr_map[*off].xval_len); + st->xattr_map.xm_map[n].xval_ptr, + st->xattr_map.xm_map[n].xval_len); } static void xattr_decoder (struct tar_stat_info *st, char const *keyword, char const *arg, size_t size) { - char *xstr, *xkey; + char *xkey; /* copy keyword */ xkey = xstrdup (keyword); - /* copy value */ - xstr = xmalloc (size + 1); - memcpy (xstr, arg, size + 1); /* separator included, for GNU tar '\n' */; - xattr_decode_keyword (xkey); - xheader_xattr_add (st, xkey + strlen ("SCHILY.xattr."), xstr, size); + xattr_map_add (&st->xattr_map, xkey, arg, size); free (xkey); - free (xstr); } static void -- cgit v1.2.1