X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Flist.c;h=68f511506dd83d7453c904ab795151953a218fe2;hb=cc5892ba8cbe46ac2f5ad3758293cebdb7003319;hp=fabe8b382725f76c368c581ce5a74b1ad17f4d98;hpb=112d4460f5f96d69f25419117a7fa47154d0a928;p=debian%2Ftar diff --git a/src/list.c b/src/list.c index fabe8b38..68f51150 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; @@ -503,47 +564,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 @@ -580,7 +600,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; @@ -663,23 +685,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