summaryrefslogtreecommitdiffstats
path: root/contrib/libarchive/tar/subst.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libarchive/tar/subst.c')
-rw-r--r--contrib/libarchive/tar/subst.c53
1 files changed, 42 insertions, 11 deletions
diff --git a/contrib/libarchive/tar/subst.c b/contrib/libarchive/tar/subst.c
index 765f74b..b592fe0 100644
--- a/contrib/libarchive/tar/subst.c
+++ b/contrib/libarchive/tar/subst.c
@@ -44,7 +44,7 @@ struct subst_rule {
struct subst_rule *next;
regex_t re;
char *result;
- unsigned int global:1, print:1, symlink:1;
+ unsigned int global:1, print:1, regular:1, symlink:1, hardlink:1;
};
struct substitution {
@@ -117,9 +117,12 @@ add_substitution(struct bsdtar *bsdtar, const char *rule_text)
memcpy(rule->result, start_subst, end_pattern - start_subst);
rule->result[end_pattern - start_subst] = '\0';
- rule->global = 0;
- rule->print = 0;
- rule->symlink = 0;
+ /* Defaults */
+ rule->global = 0; /* Don't do multiple replacements. */
+ rule->print = 0; /* Don't print. */
+ rule->regular = 1; /* Rewrite regular filenames. */
+ rule->symlink = 1; /* Rewrite symlink targets. */
+ rule->hardlink = 1; /* Rewrite hardlink targets. */
while (*++end_pattern) {
switch (*end_pattern) {
@@ -127,14 +130,28 @@ add_substitution(struct bsdtar *bsdtar, const char *rule_text)
case 'G':
rule->global = 1;
break;
+ case 'h':
+ rule->hardlink = 1;
+ break;
+ case 'H':
+ rule->hardlink = 0;
+ break;
case 'p':
case 'P':
rule->print = 1;
break;
+ case 'r':
+ rule->regular = 1;
+ break;
+ case 'R':
+ rule->regular = 0;
+ break;
case 's':
- case 'S':
rule->symlink = 1;
break;
+ case 'S':
+ rule->symlink = 0;
+ break;
default:
lafe_errc(1, 0, "Invalid replacement flag %c", *end_pattern);
}
@@ -155,7 +172,8 @@ realloc_strncat(char **str, const char *append, size_t len)
new_str = malloc(old_len + len + 1);
if (new_str == NULL)
lafe_errc(1, errno, "Out of memory");
- memcpy(new_str, *str, old_len);
+ if (*str != NULL)
+ memcpy(new_str, *str, old_len);
memcpy(new_str + old_len, append, len);
new_str[old_len + len] = '\0';
free(*str);
@@ -176,14 +194,16 @@ realloc_strcat(char **str, const char *append)
new_str = malloc(old_len + strlen(append) + 1);
if (new_str == NULL)
lafe_errc(1, errno, "Out of memory");
- memcpy(new_str, *str, old_len);
+ if (*str != NULL)
+ memcpy(new_str, *str, old_len);
strcpy(new_str + old_len, append);
free(*str);
*str = new_str;
}
int
-apply_substitution(struct bsdtar *bsdtar, const char *name, char **result, int symlink_only)
+apply_substitution(struct bsdtar *bsdtar, const char *name, char **result,
+ int symlink_target, int hardlink_target)
{
const char *path = name;
regmatch_t matches[10];
@@ -201,8 +221,17 @@ apply_substitution(struct bsdtar *bsdtar, const char *name, char **result, int s
print_match = 0;
for (rule = subst->first_rule; rule != NULL; rule = rule->next) {
- if (symlink_only && !rule->symlink)
- continue;
+ if (symlink_target) {
+ if (!rule->symlink)
+ continue;
+ } else if (hardlink_target) {
+ if (!rule->hardlink)
+ continue;
+ } else { /* Regular filename. */
+ if (!rule->regular)
+ continue;
+ }
+
if (regexec(&rule->re, name, 10, matches, 0))
continue;
@@ -213,7 +242,9 @@ apply_substitution(struct bsdtar *bsdtar, const char *name, char **result, int s
for (i = 0, j = 0; rule->result[i] != '\0'; ++i) {
if (rule->result[i] == '~') {
realloc_strncat(result, rule->result + j, i - j);
- realloc_strncat(result, name, matches[0].rm_eo);
+ realloc_strncat(result,
+ name + matches[0].rm_so,
+ matches[0].rm_eo - matches[0].rm_so);
j = i + 1;
continue;
}
OpenPOWER on IntegriCloud