X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fxheader.c;h=9be0a2fe30e778695023019d40dd29ac0318582d;hb=b4ec8aedf9c8948bee9bf1635132a7da7a522611;hp=2948859ab076180a69f36807dca282d841409d05;hpb=e359fad6413c3fbff4d862e535c6e78e92d6d44e;p=chaz%2Ftar diff --git a/src/xheader.c b/src/xheader.c index 2948859..9be0a2f 100644 --- a/src/xheader.c +++ b/src/xheader.c @@ -1,10 +1,10 @@ /* POSIX extended headers for tar. - Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any later + Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but @@ -22,7 +22,6 @@ #include #include #include -#include #include "common.h" @@ -35,7 +34,6 @@ static void xheader_set_single_keyword (char *) __attribute__ ((noreturn)); /* Used by xheader_finish() */ static void code_string (char const *string, char const *keyword, struct xheader *xhdr); -static void extended_header_init (void); /* Number of global headers written so far. */ static size_t global_header_count; @@ -225,7 +223,7 @@ xheader_set_option (char *string) to the result of the basename utility on the translated file name. %p The process ID of the pax process. - %n The value of the 3rd argument. + %n The value of the 3rd argument. %% A '%' character. */ char * @@ -264,7 +262,7 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n) case 'f': if (st) { - base = base_name (st->orig_file_name); + base = last_component (st->orig_file_name); len += strlen (base) - 2; } break; @@ -331,7 +329,7 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n) } free (dirp); - + /* Do not allow it to end in a slash */ while (q > buf && ISSLASH (q[-1])) q--; @@ -405,7 +403,7 @@ xheader_write (char type, char *name, struct xheader *xhdr) } void -xheader_write_global (void) +xheader_write_global (struct xheader *xhdr) { char *name; struct keyword_list *kp; @@ -413,12 +411,11 @@ xheader_write_global (void) if (!keyword_global_override_list) return; - extended_header_init (); + xheader_init (xhdr); for (kp = keyword_global_override_list; kp; kp = kp->next) - code_string (kp->value, kp->pattern, &extended_header); - xheader_finish (&extended_header); - xheader_write (XGLTYPE, name = xheader_ghdr_name (), - &extended_header); + code_string (kp->value, kp->pattern, xhdr); + xheader_finish (xhdr); + xheader_write (XGLTYPE, name = xheader_ghdr_name (), xhdr); free (name); } @@ -478,7 +475,8 @@ xheader_protected_keyword_p (const char *keyword) /* Decode a single extended header record, advancing *PTR to the next record. Return true on success, false otherwise. */ static bool -decode_record (char **ptr, +decode_record (struct xheader *xhdr, + char **ptr, void (*handler) (void *, char const *, char const *, size_t), void *data) { @@ -489,7 +487,7 @@ decode_record (char **ptr, char *len_lim; char const *keyword; char *nextp; - size_t len_max = extended_header.buffer + extended_header.size - start; + size_t len_max = xhdr->buffer + xhdr->size - start; while (*p == ' ' || *p == '\t') p++; @@ -508,7 +506,7 @@ decode_record (char **ptr, ERROR ((0, 0, _("Extended header length is out of allowed range"))); return false; } - + if (len_max < len) { int len_len = len_lim - p; @@ -575,8 +573,8 @@ decx (void *data, char const *keyword, char const *value, size_t size) if (t) t->decoder (st, keyword, value, size); else - ERROR((0, 0, _("Ignoring unknown extended header keyword `%s'"), - keyword)); + WARN((0, 0, _("Ignoring unknown extended header keyword `%s'"), + keyword)); } void @@ -585,10 +583,10 @@ 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) + if (st->xhdr.size) { - char *p = extended_header.buffer + BLOCKSIZE; - while (decode_record (&p, decx, st)) + char *p = st->xhdr.buffer + BLOCKSIZE; + while (decode_record (&st->xhdr, &p, decx, st)) continue; } run_override_list (keyword_override_list, st); @@ -603,35 +601,35 @@ decg (void *data, char const *keyword, char const *value, } void -xheader_decode_global (void) +xheader_decode_global (struct xheader *xhdr) { - if (extended_header.size) + if (xhdr->size) { - char *p = extended_header.buffer + BLOCKSIZE; + char *p = xhdr->buffer + BLOCKSIZE; xheader_list_destroy (&global_header_override_list); - while (decode_record (&p, decg, &global_header_override_list)) + while (decode_record (xhdr, &p, decg, &global_header_override_list)) continue; } } -static void -extended_header_init (void) +void +xheader_init (struct xheader *xhdr) { - if (!extended_header.stk) + if (!xhdr->stk) { - extended_header.stk = xmalloc (sizeof *extended_header.stk); - obstack_init (extended_header.stk); + xhdr->stk = xmalloc (sizeof *xhdr->stk); + obstack_init (xhdr->stk); } } void -xheader_store (char const *keyword, struct tar_stat_info const *st, +xheader_store (char const *keyword, struct tar_stat_info *st, void const *data) { struct xhdr_tab const *t; - if (extended_header.buffer) + if (st->xhdr.buffer) return; t = locate_handler (keyword); if (!t || !t->coder) @@ -639,22 +637,20 @@ xheader_store (char const *keyword, struct tar_stat_info const *st, if (xheader_keyword_deleted_p (keyword) || xheader_keyword_override_p (keyword)) return; - extended_header_init (); - t->coder (st, keyword, &extended_header, data); + xheader_init (&st->xhdr); + t->coder (st, keyword, &st->xhdr, data); } void -xheader_read (union block *p, size_t size) +xheader_read (struct xheader *xhdr, union block *p, size_t size) { size_t j = 0; - size_t nblocks; - free (extended_header.buffer); + xheader_init (xhdr); size += BLOCKSIZE; - extended_header.size = size; - nblocks = (size + BLOCKSIZE - 1) / BLOCKSIZE; - extended_header.buffer = xmalloc (size + 1); - extended_header.buffer[size] = '\0'; + xhdr->size = size; + xhdr->buffer = xmalloc (size + 1); + xhdr->buffer[size] = '\0'; do { @@ -663,7 +659,7 @@ xheader_read (union block *p, size_t size) if (len > BLOCKSIZE) len = BLOCKSIZE; - memcpy (&extended_header.buffer[j], p->buffer, len); + memcpy (&xhdr->buffer[j], p->buffer, len); set_next_block_after (p); p = find_next_block (); @@ -734,26 +730,25 @@ xheader_destroy (struct xheader *xhdr) /* Buildable strings */ -static uintmax_t string_length; void -xheader_string_begin () +xheader_string_begin (struct xheader *xhdr) { - string_length = 0; + xhdr->string_length = 0; } void -xheader_string_add (char const *s) +xheader_string_add (struct xheader *xhdr, char const *s) { - if (extended_header.buffer) + if (xhdr->buffer) return; - extended_header_init (); - string_length += strlen (s); - x_obstack_grow (&extended_header, s, strlen (s)); + xheader_init (xhdr); + xhdr->string_length += strlen (s); + x_obstack_grow (xhdr, s, strlen (s)); } bool -xheader_string_end (char const *keyword) +xheader_string_end (struct xheader *xhdr, char const *keyword) { uintmax_t len; uintmax_t p; @@ -763,11 +758,11 @@ xheader_string_end (char const *keyword) char const *np; char *cp; - if (extended_header.buffer) + if (xhdr->buffer) return false; - extended_header_init (); + xheader_init (xhdr); - len = strlen (keyword) + string_length + 3; /* ' ' + '=' + '\n' */ + len = strlen (keyword) + xhdr->string_length + 3; /* ' ' + '=' + '\n' */ do { @@ -784,13 +779,13 @@ xheader_string_end (char const *keyword) ERROR ((0, 0, _("Generated keyword/value pair is too long (keyword=%s, length=%s)"), keyword, nbuf)); - obstack_free (extended_header.stk, obstack_finish (extended_header.stk)); + obstack_free (xhdr->stk, obstack_finish (xhdr->stk)); return false; } - x_obstack_blank (&extended_header, p); - x_obstack_1grow (&extended_header, '\n'); - cp = obstack_next_free (extended_header.stk) - string_length - p - 1; - memmove (cp + p, cp, string_length); + x_obstack_blank (xhdr, p); + x_obstack_1grow (xhdr, '\n'); + cp = obstack_next_free (xhdr->stk) - xhdr->string_length - p - 1; + memmove (cp + p, cp, xhdr->string_length); cp = stpcpy (cp, np); *cp++ = ' '; cp = stpcpy (cp, keyword); @@ -956,7 +951,7 @@ decode_time (struct timespec *ts, char const *arg, char const *keyword) return true; } - + static void code_num (uintmax_t value, char const *keyword, struct xheader *xhdr) @@ -1094,9 +1089,10 @@ ctime_decoder (struct tar_stat_info *st, static void mtime_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data __attribute__ ((unused))) + struct xheader *xhdr, void const *data) { - code_time (st->mtime, keyword, xhdr); + struct timespec const *mtime = data; + code_time (mtime ? *mtime : st->mtime, keyword, xhdr); } static void @@ -1380,8 +1376,8 @@ static void volume_size_coder (struct tar_stat_info const *st, char const *keyword, struct xheader *xhdr, void const *data) { - off_t v = *(off_t*)data; - code_num (v, keyword, xhdr); + off_t const *v = data; + code_num (*v, keyword, xhdr); } static void @@ -1399,8 +1395,8 @@ static void volume_offset_coder (struct tar_stat_info const *st, char const *keyword, struct xheader *xhdr, void const *data) { - off_t v = *(off_t*)data; - code_num (v, keyword, xhdr); + off_t const *v = data; + code_num (*v, keyword, xhdr); } static void @@ -1439,12 +1435,12 @@ sparse_major_decoder (struct tar_stat_info *st, if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword)) st->sparse_major = u; } - + static void sparse_minor_coder (struct tar_stat_info const *st, char const *keyword, struct xheader *xhdr, void const *data) { - code_num (st->sparse_minor, keyword, xhdr); + code_num (st->sparse_minor, keyword, xhdr); } static void @@ -1457,7 +1453,7 @@ sparse_minor_decoder (struct tar_stat_info *st, if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword)) st->sparse_minor = u; } - + struct xhdr_tab const xhdr_tab[] = { { "atime", atime_coder, atime_decoder, false }, { "comment", dummy_coder, dummy_decoder, false },