X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Flist.c;h=4f85fb5b9f0b2a099ef53ca302239462245bde5f;hb=6a61354ea0dd97af5c87643e9bf5dfd2a31f2cea;hp=d15653d3b39530a2fd27caa8ec1fa0519d1e9d87;hpb=372ac37d01a218e87ad6279c43a75c1b88c1d41f;p=chaz%2Ftar diff --git a/src/list.c b/src/list.c index d15653d..4f85fb5 100644 --- a/src/list.c +++ b/src/list.c @@ -75,6 +75,66 @@ base64_init (void) base64_map[(int) base_64_digits[i]] = i; } +static char * +decode_xform (char *file_name, void *data) +{ + int type = *(int*)data; + + switch (type) + { + case XFORM_SYMLINK: + /* FIXME: It is not quite clear how and to which extent are the symbolic + links subject to filename transformation. In the absence of another + solution, symbolic links are exempt from component stripping and + name suffix normalization, but subject to filename transformation + proper. */ + return file_name; + + case XFORM_LINK: + file_name = safer_name_suffix (file_name, true, absolute_names_option); + break; + + case XFORM_REGFILE: + file_name = safer_name_suffix (file_name, false, absolute_names_option); + break; + } + + if (strip_name_components) + { + size_t prefix_len = stripped_prefix_len (file_name, + strip_name_components); + if (prefix_len == (size_t) -1) + prefix_len = strlen (file_name); + file_name += prefix_len; + } + return file_name; +} + +static bool +transform_member_name (char **pinput, int type) +{ + return transform_name_fp (pinput, type, decode_xform, &type); +} + +void +transform_stat_info (int typeflag, struct tar_stat_info *stat_info) +{ + if (typeflag == GNUTYPE_VOLHDR) + /* Name transformations don't apply to volume headers. */ + return; + + transform_member_name (&stat_info->file_name, XFORM_REGFILE); + switch (typeflag) + { + case SYMTYPE: + transform_member_name (&stat_info->link_name, XFORM_SYMLINK); + break; + + case LNKTYPE: + transform_member_name (&stat_info->link_name, XFORM_LINK); + } +} + /* Main loop for reading an archive. */ void read_and (void (*do_something) (void)) @@ -135,7 +195,8 @@ read_and (void (*do_something) (void)) continue; } } - + transform_stat_info (current_header->header.typeflag, + ¤t_stat_info); (*do_something) (); continue; @@ -372,15 +433,13 @@ read_header (union block **return_block, struct tar_stat_info *info, if (header->header.typeflag == GNUTYPE_LONGNAME) { - if (next_long_name) - free (next_long_name); + free (next_long_name); next_long_name = header_copy; next_long_name_blocks = size / BLOCKSIZE; } else { - if (next_long_link) - free (next_long_link); + free (next_long_link); next_long_link = header_copy; next_long_link_blocks = size / BLOCKSIZE; } @@ -439,8 +498,7 @@ read_header (union block **return_block, struct tar_stat_info *info, struct posix_header const *h = &header->header; char namebuf[sizeof h->prefix + 1 + NAME_FIELD_SIZE + 1]; - if (recent_long_name) - free (recent_long_name); + free (recent_long_name); if (next_long_name) { @@ -471,8 +529,7 @@ read_header (union block **return_block, struct tar_stat_info *info, assign_string (&info->file_name, name); info->had_trailing_slash = strip_trailing_slashes (info->file_name); - if (recent_long_link) - free (recent_long_link); + free (recent_long_link); if (next_long_link) { @@ -495,47 +552,6 @@ read_header (union block **return_block, struct tar_stat_info *info, } } -static char * -decode_xform (char *file_name, void *data) -{ - int type = *(int*)data; - - switch (type) - { - case XFORM_SYMLINK: - /* FIXME: It is not quite clear how and to which extent are the symbolic - links subject to filename transformation. In the absence of another - solution, symbolic links are exempt from component stripping and - name suffix normalization, but subject to filename transformation - proper. */ - return file_name; - - case XFORM_LINK: - file_name = safer_name_suffix (file_name, true, absolute_names_option); - break; - - case XFORM_REGFILE: - file_name = safer_name_suffix (file_name, false, absolute_names_option); - break; - } - - if (strip_name_components) - { - size_t prefix_len = stripped_prefix_len (file_name, - strip_name_components); - if (prefix_len == (size_t) -1) - prefix_len = strlen (file_name); - file_name += prefix_len; - } - return file_name; -} - -static bool -transform_member_name (char **pinput, int type) -{ - return transform_name_fp (pinput, type, decode_xform, &type); -} - #define ISOCTAL(c) ((c)>='0'&&(c)<='7') /* Decode things from a file HEADER block into STAT_INFO, also setting @@ -572,7 +588,9 @@ decode_header (union block *header, struct tar_stat_info *stat_info, else format = USTAR_FORMAT; } - else if (strcmp (header->header.magic, OLDGNU_MAGIC) == 0) + else if (strcmp (header->buffer + offsetof (struct posix_header, magic), + OLDGNU_MAGIC) + == 0) format = hbits ? OLDGNU_FORMAT : GNU_FORMAT; else format = V7_FORMAT; @@ -655,23 +673,9 @@ decode_header (union block *header, struct tar_stat_info *stat_info, || stat_info->dumpdir) stat_info->is_dumpdir = true; } - - if (header->header.typeflag == GNUTYPE_VOLHDR) - /* Name transformations don't apply to volume headers. */ - return; - - transform_member_name (&stat_info->file_name, XFORM_REGFILE); - switch (header->header.typeflag) - { - case SYMTYPE: - transform_member_name (&stat_info->link_name, XFORM_SYMLINK); - break; - - case LNKTYPE: - transform_member_name (&stat_info->link_name, XFORM_LINK); - } } + /* Convert buffer at WHERE0 of size DIGS from external format to uintmax_t. DIGS must be positive. If TYPE is nonnull, the data are of type TYPE. The buffer must represent a value in the range @@ -1353,8 +1357,8 @@ print_for_mkdir (char *dirname, int length, mode_t mode) STRINGIFY_BIGINT (current_block_ordinal (), buf)); } - fprintf (stdlis, "%s %*s %.*s\n", modes, ugswidth + 1 + datewidth, - _("Creating directory:"), length, quotearg (dirname)); + fprintf (stdlis, "%s %*s %s\n", modes, ugswidth + 1 + datewidth, + _("Creating directory:"), quotearg (dirname)); } } @@ -1411,7 +1415,7 @@ skip_member (void) } void -test_archive_label () +test_archive_label (void) { base64_init (); name_gather ();