mirror of
https://git.savannah.gnu.org/git/tar.git
synced 2026-09-06 16:26:55 +00:00
* NEWS, configure.ac: Version 1.20.91
* doc/tar.texi: Document transformation scope flags. * src/common.h (transform_symlinks_option): Remove in favor of transformation scope flags. (XFORM_REGFILE, XFORM_LINK, XFORM_SYMLINK, XFORM_ALL): New macros. (transform_name, transform_member_name, transform_name_fp): Take an additional argument, specifying scope flags. * src/create.c: Reflect changes to transform_name. * src/extract.c (extract_link, extract_symlink): Remove calls to transform_member_name. It is done in read_header. * src/list.c (decode_xform): Reflect change in data type of 2nd argument. (transform_member_name): 2nd arg is int. (decode_header): Transform file name and link target names. * src/tar.c: Remove --transform-symlinks. * src/transform.c (struct transform): New member `flags'. (transform_flags): New variable. (parse_transform_expr): Parse transformation scope flags. Allow to set global flags using `flags=' syntax. (_transform_name_to_obstack, transform_name_fp) (transform_name): Take an additional argument, specifying scope flags.
This commit is contained in:
+8
-12
@@ -346,9 +346,6 @@ GLOBAL bool unquote_option;
|
||||
|
||||
GLOBAL bool test_label_option; /* Test archive volume label and exit */
|
||||
|
||||
/* Apply transformations to symlink targets as well. */
|
||||
GLOBAL bool transform_symlinks_option;
|
||||
|
||||
/* Show file or archive names after transformation.
|
||||
In particular, when creating archive in verbose mode, list member names
|
||||
as stored in the archive */
|
||||
@@ -738,17 +735,16 @@ bool string_ascii_p (const char *str);
|
||||
bool utf8_convert (bool to_utf, char const *input, char **output);
|
||||
|
||||
/* Module transform.c */
|
||||
typedef enum
|
||||
{
|
||||
xform_regfile,
|
||||
xform_link,
|
||||
xform_symlink
|
||||
} xform_type;
|
||||
#define XFORM_REGFILE 0x01
|
||||
#define XFORM_LINK 0x02
|
||||
#define XFORM_SYMLINK 0x04
|
||||
#define XFORM_ALL (XFORM_REGFILE|XFORM_LINK|XFORM_SYMLINK)
|
||||
|
||||
void set_transform_expr (const char *expr);
|
||||
bool transform_name (char **pinput);
|
||||
bool transform_member_name (char **pinput, xform_type type);
|
||||
bool transform_name_fp (char **pinput, char *(*fun)(char *, void *), void *);
|
||||
bool transform_name (char **pinput, int type);
|
||||
bool transform_member_name (char **pinput, int type);
|
||||
bool transform_name_fp (char **pinput, int type,
|
||||
char *(*fun)(char *, void *), void *);
|
||||
|
||||
/* Module suffix.c */
|
||||
void set_comression_program_by_suffix (const char *name, const char *defprog);
|
||||
|
||||
+2
-3
@@ -1495,7 +1495,7 @@ dump_file0 (struct tar_stat_info *st, const char *p,
|
||||
assign_string (&st->file_name,
|
||||
safer_name_suffix (p, false, absolute_names_option));
|
||||
|
||||
transform_name (&st->file_name);
|
||||
transform_name (&st->file_name, XFORM_REGFILE);
|
||||
|
||||
if (deref_stat (dereference_option, p, &st->stat) != 0)
|
||||
{
|
||||
@@ -1705,8 +1705,7 @@ dump_file0 (struct tar_stat_info *st, const char *p,
|
||||
}
|
||||
buffer[size] = '\0';
|
||||
assign_string (&st->link_name, buffer);
|
||||
if (transform_symlinks_option)
|
||||
transform_name (&st->link_name);
|
||||
transform_name (&st->link_name, XFORM_SYMLINK);
|
||||
if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size)
|
||||
write_long_link (st);
|
||||
|
||||
|
||||
@@ -917,7 +917,6 @@ extract_link (char *file_name, int typeflag)
|
||||
int interdir_made = 0;
|
||||
char const *link_name;
|
||||
|
||||
transform_member_name (¤t_stat_info.link_name, xform_link);
|
||||
link_name = current_stat_info.link_name;
|
||||
|
||||
if (! absolute_names_option && contains_dot_dot (link_name))
|
||||
@@ -974,8 +973,6 @@ extract_symlink (char *file_name, int typeflag)
|
||||
int status;
|
||||
int interdir_made = 0;
|
||||
|
||||
transform_member_name (¤t_stat_info.link_name, xform_symlink);
|
||||
|
||||
if (! absolute_names_option
|
||||
&& (IS_ABSOLUTE_FILE_NAME (current_stat_info.link_name)
|
||||
|| contains_dot_dot (current_stat_info.link_name)))
|
||||
|
||||
+16
-7
@@ -472,11 +472,11 @@ read_header (bool raw_extended_headers)
|
||||
static char *
|
||||
decode_xform (char *file_name, void *data)
|
||||
{
|
||||
xform_type type = *(xform_type*)data;
|
||||
int type = *(int*)data;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case xform_symlink:
|
||||
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
|
||||
@@ -484,11 +484,11 @@ decode_xform (char *file_name, void *data)
|
||||
proper. */
|
||||
return file_name;
|
||||
|
||||
case xform_link:
|
||||
case XFORM_LINK:
|
||||
file_name = safer_name_suffix (file_name, true, absolute_names_option);
|
||||
break;
|
||||
|
||||
case xform_regfile:
|
||||
case XFORM_REGFILE:
|
||||
file_name = safer_name_suffix (file_name, false, absolute_names_option);
|
||||
break;
|
||||
}
|
||||
@@ -505,9 +505,9 @@ decode_xform (char *file_name, void *data)
|
||||
}
|
||||
|
||||
bool
|
||||
transform_member_name (char **pinput, xform_type type)
|
||||
transform_member_name (char **pinput, int type)
|
||||
{
|
||||
return transform_name_fp (pinput, decode_xform, &type);
|
||||
return transform_name_fp (pinput, type, decode_xform, &type);
|
||||
}
|
||||
|
||||
#define ISOCTAL(c) ((c)>='0'&&(c)<='7')
|
||||
@@ -628,7 +628,16 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
|
||||
stat_info->is_dumpdir = true;
|
||||
}
|
||||
|
||||
transform_member_name (&stat_info->file_name, xform_regfile);
|
||||
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
|
||||
|
||||
@@ -287,7 +287,6 @@ enum
|
||||
NO_RECURSION_OPTION,
|
||||
NO_SAME_OWNER_OPTION,
|
||||
NO_SAME_PERMISSIONS_OPTION,
|
||||
NO_TRANSFORM_SYMLINKS_OPTION,
|
||||
NO_UNQUOTE_OPTION,
|
||||
NO_WILDCARDS_MATCH_SLASH_OPTION,
|
||||
NO_WILDCARDS_OPTION,
|
||||
@@ -322,7 +321,6 @@ enum
|
||||
TOTALS_OPTION,
|
||||
TO_COMMAND_OPTION,
|
||||
TRANSFORM_OPTION,
|
||||
TRANSFORM_SYMLINKS_OPTION,
|
||||
UNQUOTE_OPTION,
|
||||
USAGE_OPTION,
|
||||
USE_COMPRESS_PROGRAM_OPTION,
|
||||
@@ -689,10 +687,6 @@ static struct argp_option options[] = {
|
||||
{"transform", TRANSFORM_OPTION, N_("EXPRESSION"), 0,
|
||||
N_("use sed replace EXPRESSION to transform file names"), GRID+1 },
|
||||
{"xform", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
|
||||
{"transform-symlinks", TRANSFORM_SYMLINKS_OPTION, NULL, 0,
|
||||
N_("apply transformations to symlink targets"), GRID+1 },
|
||||
{"no-transform-symlinks", NO_TRANSFORM_SYMLINKS_OPTION, NULL, 0,
|
||||
N_("cancel effect of the previous --transform-symlinks option"), GRID+1 },
|
||||
#undef GRID
|
||||
|
||||
#define GRID 120
|
||||
@@ -1911,14 +1905,6 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
||||
set_transform_expr (arg);
|
||||
break;
|
||||
|
||||
case TRANSFORM_SYMLINKS_OPTION:
|
||||
transform_symlinks_option = true;
|
||||
break;
|
||||
|
||||
case NO_TRANSFORM_SYMLINKS_OPTION:
|
||||
transform_symlinks_option = false;
|
||||
break;
|
||||
|
||||
case USE_COMPRESS_PROGRAM_OPTION:
|
||||
set_use_compress_program_option (arg);
|
||||
break;
|
||||
|
||||
+78
-14
@@ -61,6 +61,7 @@ struct transform
|
||||
{
|
||||
struct transform *next;
|
||||
enum transform_type transform_type;
|
||||
int flags;
|
||||
unsigned match_number;
|
||||
regex_t regex;
|
||||
/* Compiled replacement expression */
|
||||
@@ -69,6 +70,8 @@ struct transform
|
||||
};
|
||||
|
||||
|
||||
|
||||
int transform_flags = XFORM_ALL;
|
||||
static struct transform *transform_head, *transform_tail;
|
||||
|
||||
static struct transform *
|
||||
@@ -131,6 +134,41 @@ add_backref_segment (struct transform *tf, size_t ref)
|
||||
segm->v.ref = ref;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_xform_flags (int *pflags, int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'r':
|
||||
*pflags |= XFORM_REGFILE;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
*pflags &= ~XFORM_REGFILE;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
*pflags |= XFORM_LINK;
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
*pflags &= ~XFORM_LINK;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
*pflags |= XFORM_SYMLINK;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
*pflags &= ~XFORM_SYMLINK;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
add_case_ctl_segment (struct transform *tf, enum case_ctl_type ctl)
|
||||
{
|
||||
@@ -150,8 +188,26 @@ parse_transform_expr (const char *expr)
|
||||
struct transform *tf = new_transform ();
|
||||
|
||||
if (expr[0] != 's')
|
||||
USAGE_ERROR ((0, 0, _("Invalid transform expression")));
|
||||
|
||||
{
|
||||
if (strncmp (expr, "flags=", 6) == 0)
|
||||
{
|
||||
transform_flags = 0;
|
||||
for (expr += 6; *expr; expr++)
|
||||
{
|
||||
if (*expr == ';')
|
||||
{
|
||||
expr++;
|
||||
break;
|
||||
}
|
||||
if (parse_xform_flags (&transform_flags, *expr))
|
||||
USAGE_ERROR ((0, 0, _("Unknown transform flag: %c"),
|
||||
*expr));
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
USAGE_ERROR ((0, 0, _("Invalid transform expression")));
|
||||
}
|
||||
|
||||
delim = expr[1];
|
||||
|
||||
/* Scan regular expression */
|
||||
@@ -172,6 +228,7 @@ parse_transform_expr (const char *expr)
|
||||
|
||||
/* Check flags */
|
||||
tf->transform_type = transform_first;
|
||||
tf->flags = transform_flags;
|
||||
for (p = expr + j + 1; *p && *p != ';'; p++)
|
||||
switch (*p)
|
||||
{
|
||||
@@ -186,7 +243,7 @@ parse_transform_expr (const char *expr)
|
||||
case 'x':
|
||||
cflags |= REG_EXTENDED;
|
||||
break;
|
||||
|
||||
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
tf->match_number = strtoul (p, (char**) &p, 0);
|
||||
@@ -194,8 +251,9 @@ parse_transform_expr (const char *expr)
|
||||
break;
|
||||
|
||||
default:
|
||||
USAGE_ERROR ((0, 0, _("Unknown flag in transform expression: %c"),
|
||||
*p));
|
||||
if (parse_xform_flags (&tf->flags, *p))
|
||||
USAGE_ERROR ((0, 0, _("Unknown flag in transform expression: %c"),
|
||||
*p));
|
||||
}
|
||||
|
||||
if (*p == ';')
|
||||
@@ -520,10 +578,11 @@ _single_transform_name_to_obstack (struct transform *tf, char *input)
|
||||
}
|
||||
|
||||
bool
|
||||
_transform_name_to_obstack (char *input, char **output)
|
||||
_transform_name_to_obstack (int flags, char *input, char **output)
|
||||
{
|
||||
struct transform *tf;
|
||||
|
||||
bool alloced = false;
|
||||
|
||||
if (!stk_init)
|
||||
{
|
||||
obstack_init (&stk);
|
||||
@@ -532,18 +591,23 @@ _transform_name_to_obstack (char *input, char **output)
|
||||
|
||||
for (tf = transform_head; tf; tf = tf->next)
|
||||
{
|
||||
_single_transform_name_to_obstack (tf, input);
|
||||
input = obstack_finish (&stk);
|
||||
if (tf->flags & flags)
|
||||
{
|
||||
_single_transform_name_to_obstack (tf, input);
|
||||
input = obstack_finish (&stk);
|
||||
alloced = true;
|
||||
}
|
||||
}
|
||||
*output = input;
|
||||
return transform_head != NULL;
|
||||
return alloced;
|
||||
}
|
||||
|
||||
bool
|
||||
transform_name_fp (char **pinput, char *(*fun)(char *, void *), void *dat)
|
||||
transform_name_fp (char **pinput, int flags,
|
||||
char *(*fun)(char *, void *), void *dat)
|
||||
{
|
||||
char *str;
|
||||
bool ret = _transform_name_to_obstack (*pinput, &str);
|
||||
bool ret = _transform_name_to_obstack (flags, *pinput, &str);
|
||||
if (ret)
|
||||
{
|
||||
assign_string (pinput, fun ? fun (str, dat) : str);
|
||||
@@ -560,8 +624,8 @@ transform_name_fp (char **pinput, char *(*fun)(char *, void *), void *dat)
|
||||
}
|
||||
|
||||
bool
|
||||
transform_name (char **pinput)
|
||||
transform_name (char **pinput, int type)
|
||||
{
|
||||
return transform_name_fp (pinput, NULL, NULL);
|
||||
return transform_name_fp (pinput, type, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user