/* List of keyword patterns set by delete= option */
static struct keyword_list *keyword_pattern_list;
+
/* List of keyword/value pairs set by `keyword=value' option */
static struct keyword_list *keyword_global_override_list;
+
/* List of keyword/value pairs set by `keyword:=value' option */
static struct keyword_list *keyword_override_list;
+
+/* List of keyword/value pairs decoded from the last 'g' type header */
+static struct keyword_list *global_header_override_list;
+
/* Template for the name field of an 'x' type header */
static char *exthdr_name;
+
/* Template for the name field of a 'g' type header */
static char *globexthdr_name;
}
void
-xheader_list_append (struct keyword_list **root, char *kw, char *value)
+xheader_list_append (struct keyword_list **root, char const *kw,
+ char const *value)
{
struct keyword_list *kp = xmalloc (sizeof *kp);
kp->pattern = xstrdup (kw);
*root = kp;
}
+void
+xheader_list_destroy (struct keyword_list **root)
+{
+ if (root)
+ {
+ struct keyword_list *kw = *root;
+ while (kw)
+ {
+ struct keyword_list *next = kw->next;
+ free (kw->pattern);
+ free (kw->value);
+ free (kw);
+ kw = next;
+ }
+ *root = NULL;
+ }
+}
+
+
void
xheader_set_single_keyword (char *kw)
{
- USAGE_ERROR ((0, 0, "Keyword %s is unknown or not yet imlemented", kw));
+ USAGE_ERROR ((0, 0, _("Keyword %s is unknown or not yet imlemented"), kw));
}
void
if (strcmp (kw, "delete") == 0)
{
if (xheader_protected_pattern_p (p))
- USAGE_ERROR ((0, 0, "Pattern %s cannot be used", p));
+ USAGE_ERROR ((0, 0, _("Pattern %s cannot be used"), p));
xheader_list_append (&keyword_pattern_list, p, NULL);
}
else if (strcmp (kw, "exthdr.name") == 0)
else
{
if (xheader_protected_keyword_p (kw))
- USAGE_ERROR ((0, 0, "Keyword %s cannot be overridden", kw));
+ USAGE_ERROR ((0, 0, _("Keyword %s cannot be overridden"), kw));
if (global)
xheader_list_append (&keyword_global_override_list, kw, p);
else
record.
Returns true on success, false otherwise. */
static bool
-decode_record (char **p, struct tar_stat_info *st)
+decode_record (char **p,
+ void (*handler) (void *, char const *, char const *),
+ void *data)
{
size_t len;
char const *keyword;
- char *eqp;
char *start = *p;
- struct xhdr_tab const *t;
+ char endc;
if (**p == 0)
return false;
return false;
}
- eqp = *p;
**p = 0;
- if (xheader_keyword_deleted_p (keyword)
- || xheader_keyword_override_p (keyword))
- return true;
- t = locate_handler (keyword);
- if (t)
- {
- char endc;
- char *value;
+ endc = start[len-1];
+ start[len-1] = 0;
- value = ++*p;
+ handler (data, keyword, *p + 1);
- endc = start[len-1];
- start[len-1] = 0;
- t->decoder (st, value);
- start[len-1] = endc;
- }
- *eqp = '=';
+ start[len-1] = endc;
+ **p = '=';
*p = &start[len];
return true;
}
}
}
+static void
+decx (void *data, char const *keyword, char const *value)
+{
+ struct xhdr_tab const *t;
+ struct tar_stat_info *st = data;
+
+ if (xheader_keyword_deleted_p (keyword)
+ || xheader_keyword_override_p (keyword))
+ return;
+
+ t = locate_handler (keyword);
+ if (t)
+ t->decoder (st, value);
+}
+
void
xheader_decode (struct tar_stat_info *st)
{
run_override_list (keyword_global_override_list, st);
+ run_override_list (global_header_override_list, st);
if (extended_header.size)
{
char *endp = &extended_header.buffer[extended_header.size-1];
while (p < endp)
- if (!decode_record (&p, st))
+ if (!decode_record (&p, decx, st))
break;
}
run_override_list (keyword_override_list, st);
}
+static void
+decg (void *data, char const *keyword, char const *value)
+{
+ struct keyword_list **kwl = data;
+ xheader_list_append (kwl, keyword, value);
+}
+
+void
+xheader_decode_global ()
+{
+ if (extended_header.size)
+ {
+ char *p = extended_header.buffer + BLOCKSIZE;
+ char *endp = &extended_header.buffer[extended_header.size-1];
+
+ xheader_list_destroy (&global_header_override_list);
+ while (p < endp)
+ if (!decode_record (&p, decg, &global_header_override_list))
+ break;
+ }
+}
+
static void
extended_header_init ()
{
static void
code_string (char const *string, char const *keyword, struct xheader *xhdr)
{
- xheader_print (xhdr, keyword, string);
+ char *outstr;
+ if (!utf8_convert (true, string, &outstr))
+ {
+ /* FIXME: report error */
+ outstr = xstrdup (string);
+ }
+ xheader_print (xhdr, keyword, outstr);
+ free (outstr);
+}
+
+static void
+decode_string (char **string, char const *arg)
+{
+ if (*string)
+ {
+ free (*string);
+ *string = NULL;
+ }
+ if (!utf8_convert (false, arg, string))
+ {
+ /* FIXME: report error and act accordingly to --pax invalid=UTF-8 */
+ assign_string (string, arg);
+ }
}
static void
static void
gname_decoder (struct tar_stat_info *st, char const *arg)
{
- assign_string (&st->gname, arg);
+ decode_string (&st->gname, arg);
}
static void
static void
linkpath_decoder (struct tar_stat_info *st, char const *arg)
{
- assign_string (&st->link_name, arg);
+ decode_string (&st->link_name, arg);
}
static void
static void
path_decoder (struct tar_stat_info *st, char const *arg)
{
- assign_string (&st->orig_file_name, arg);
- assign_string (&st->file_name, arg);
+ decode_string (&st->orig_file_name, arg);
+ decode_string (&st->file_name, arg);
st->had_trailing_slash = strip_trailing_slashes (st->file_name);
}
static void
uname_decoder (struct tar_stat_info *st, char const *arg)
{
- assign_string (&st->uname, arg);
+ decode_string (&st->uname, arg);
}
static void
/* The next directory entry actually contains the names of files
that were in the directory at the time the dump was made.
Supersedes GNUTYPE_DUMPDIR header type. */
- { "GNU.dumpdir", dumpdir_coder, dumpdir_decoder },
+ { "GNU.dump.name", dump_name_coder, dump_name_decoder },
+ { "GNU.dump.status", dump_status_coder, dump_status_decoder },
/* Keeps the tape/volume header. May be present only in the global headers.
Equivalent to GNUTYPE_VOLHDR. */