From b8754a37c740d7771637a0ef8f8d7c0683315d5d Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Sun, 22 Feb 2004 20:54:44 +0000 Subject: [PATCH] Use keywords from the global headers. Correctly handle UTF-8 conversions. (xheader_list_destroy): New function. (xheader_set_single_keyword,xheader_set_keyword_equal): Added missing gettext markers (decode_record): Rewritten using caller-provided handler and data closure. --- src/xheader.c | 140 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 109 insertions(+), 31 deletions(-) diff --git a/src/xheader.c b/src/xheader.c index 129ce84..b8b8581 100644 --- a/src/xheader.c +++ b/src/xheader.c @@ -62,12 +62,19 @@ struct keyword_list /* 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; @@ -94,7 +101,8 @@ xheader_keyword_override_p (const char *keyword) } 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); @@ -103,10 +111,29 @@ xheader_list_append (struct keyword_list **root, char *kw, char *value) *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 @@ -132,7 +159,7 @@ xheader_set_keyword_equal (char *kw, char *eq) 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) @@ -142,7 +169,7 @@ xheader_set_keyword_equal (char *kw, char *eq) 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 @@ -423,13 +450,14 @@ xheader_protected_keyword_p (const char *keyword) 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; @@ -453,26 +481,15 @@ decode_record (char **p, struct tar_stat_info *st) 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; } @@ -488,10 +505,26 @@ run_override_list (struct keyword_list *kp, struct tar_stat_info *st) } } +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) { @@ -499,12 +532,34 @@ xheader_decode (struct tar_stat_info *st) 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 () { @@ -645,7 +700,29 @@ xheader_destroy (struct xheader *xhdr) 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 @@ -735,7 +812,7 @@ gname_coder (struct tar_stat_info const *st, char const *keyword, static void gname_decoder (struct tar_stat_info *st, char const *arg) { - assign_string (&st->gname, arg); + decode_string (&st->gname, arg); } static void @@ -748,7 +825,7 @@ linkpath_coder (struct tar_stat_info const *st, char const *keyword, 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 @@ -787,8 +864,8 @@ path_coder (struct tar_stat_info const *st, char const *keyword, 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); } @@ -832,7 +909,7 @@ uname_coder (struct tar_stat_info const *st, char const *keyword, static void uname_decoder (struct tar_stat_info *st, char const *arg) { - assign_string (&st->uname, arg); + decode_string (&st->uname, arg); } static void @@ -938,7 +1015,8 @@ struct xhdr_tab const xhdr_tab[] = { /* 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. */ -- 2.44.0