* 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:
Sergey Poznyakoff
2008-10-30 14:13:01 +00:00
parent 5354888e40
commit b4ec8aedf9
11 changed files with 242 additions and 124 deletions
+8 -12
View File
@@ -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
View File
@@ -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);
-3
View File
@@ -917,7 +917,6 @@ extract_link (char *file_name, int typeflag)
int interdir_made = 0;
char const *link_name;
transform_member_name (&current_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 (&current_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
View File
@@ -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
-14
View File
@@ -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
View File
@@ -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);
}