From: Sergey Poznyakoff Date: Mon, 1 Dec 2003 21:21:11 +0000 (+0000) Subject: (struct xhdr_tab.coder; all coder function): Added X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=fa2801b6dc22e25f744d11f00aafee43abe28312;p=chaz%2Ftar (struct xhdr_tab.coder; all coder function): Added extra argument Implemeted GNU.sparse.* keywords. --- diff --git a/src/xheader.c b/src/xheader.c index d5a75b3..1a7edd0 100644 --- a/src/xheader.c +++ b/src/xheader.c @@ -33,7 +33,8 @@ struct xhdr_tab { char const *keyword; - void (*coder) (struct tar_stat_info const *, char const *, struct xheader *); + void (*coder) (struct tar_stat_info const *, char const *, + struct xheader *, void *data); void (*decoder) (struct tar_stat_info *, char const *); }; @@ -121,7 +122,7 @@ xheader_decode (struct tar_stat_info *st) } void -xheader_store (char const *keyword, struct tar_stat_info const *st) +xheader_store (char const *keyword, struct tar_stat_info const *st, void *data) { struct xhdr_tab const *t; @@ -135,7 +136,7 @@ xheader_store (char const *keyword, struct tar_stat_info const *st) extended_header.stk = xmalloc (sizeof *extended_header.stk); obstack_init (extended_header.stk); } - t->coder (st, keyword, &extended_header); + t->coder (st, keyword, &extended_header, data); } void @@ -272,7 +273,7 @@ code_num (uintmax_t value, char const *keyword, struct xheader *xhdr) static void dummy_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr) + struct xheader *xhdr, void *data) { } @@ -283,7 +284,7 @@ dummy_decoder (struct tar_stat_info *st, char const *arg) static void atime_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr) + struct xheader *xhdr, void *data) { code_time (st->stat.st_atime, keyword, xhdr); } @@ -298,7 +299,7 @@ atime_decoder (struct tar_stat_info *st, char const *arg) static void gid_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr) + struct xheader *xhdr, void *data) { code_num (st->stat.st_gid, keyword, xhdr); } @@ -313,7 +314,7 @@ gid_decoder (struct tar_stat_info *st, char const *arg) static void gname_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr) + struct xheader *xhdr, void *data) { code_string (st->gname, keyword, xhdr); } @@ -326,7 +327,7 @@ gname_decoder (struct tar_stat_info *st, char const *arg) static void linkpath_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr) + struct xheader *xhdr, void *data) { code_string (st->link_name, keyword, xhdr); } @@ -339,7 +340,7 @@ linkpath_decoder (struct tar_stat_info *st, char const *arg) static void ctime_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr) + struct xheader *xhdr, void *data) { code_time (st->stat.st_ctime, keyword, xhdr); } @@ -354,7 +355,7 @@ ctime_decoder (struct tar_stat_info *st, char const *arg) static void mtime_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr) + struct xheader *xhdr, void *data) { code_time (st->stat.st_mtime, keyword, xhdr); } @@ -369,7 +370,7 @@ mtime_decoder (struct tar_stat_info *st, char const *arg) static void path_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr) + struct xheader *xhdr, void *data) { code_string (st->file_name, keyword, xhdr); } @@ -384,7 +385,7 @@ path_decoder (struct tar_stat_info *st, char const *arg) static void size_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr) + struct xheader *xhdr, void *data) { code_num (st->stat.st_size, keyword, xhdr); } @@ -399,7 +400,7 @@ size_decoder (struct tar_stat_info *st, char const *arg) static void uid_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr) + struct xheader *xhdr, void *data) { code_num (st->stat.st_uid, keyword, xhdr); } @@ -414,7 +415,7 @@ uid_decoder (struct tar_stat_info *st, char const *arg) static void uname_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr) + struct xheader *xhdr, void *data) { code_string (st->uname, keyword, xhdr); } @@ -425,6 +426,81 @@ uname_decoder (struct tar_stat_info *st, char const *arg) assign_string (&st->uname, arg); } +static void +sparse_size_coder (struct tar_stat_info const *st, char const *keyword, + struct xheader *xhdr, void *data) +{ + size_coder (st, keyword, xhdr, data); +} + +static void +sparse_size_decoder (struct tar_stat_info *st, char const *arg) +{ + uintmax_t u; + if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK) + st->archive_file_size = u; +} + +static void +sparse_numblocks_coder (struct tar_stat_info const *st, char const *keyword, + struct xheader *xhdr, void *data) +{ + code_num (st->sparse_map_avail, keyword, xhdr); +} + +static void +sparse_numblocks_decoder (struct tar_stat_info *st, char const *arg) +{ + uintmax_t u; + if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK) + { + st->sparse_map_size = u; + st->sparse_map = calloc(st->sparse_map_size, sizeof(st->sparse_map[0])); + st->sparse_map_avail = 0; + } +} + +static void +sparse_offset_coder (struct tar_stat_info const *st, char const *keyword, + struct xheader *xhdr, void *data) +{ + size_t i = *(size_t*)data; + code_num (st->sparse_map[i].offset, keyword, xhdr); +} + +static void +sparse_offset_decoder (struct tar_stat_info *st, char const *arg) +{ + uintmax_t u; + if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK) + st->sparse_map[st->sparse_map_avail].offset = u; +} + +static void +sparse_numbytes_coder (struct tar_stat_info const *st, char const *keyword, + struct xheader *xhdr, void *data) +{ + size_t i = *(size_t*)data; + code_num (st->sparse_map[i].numbytes, keyword, xhdr); +} + +static void +sparse_numbytes_decoder (struct tar_stat_info *st, char const *arg) +{ + uintmax_t u; + if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK) + { + if (st->sparse_map_avail == st->sparse_map_size) + { + size_t newsize = st->sparse_map_size *= 2; + st->sparse_map = xrealloc (st->sparse_map, + st->sparse_map_size + * sizeof st->sparse_map[0]); + } + st->sparse_map[st->sparse_map_avail++].numbytes = u; + } +} + struct xhdr_tab const xhdr_tab[] = { { "atime", atime_coder, atime_decoder }, { "comment", dummy_coder, dummy_decoder }, @@ -439,14 +515,14 @@ struct xhdr_tab const xhdr_tab[] = { { "uid", uid_coder, uid_decoder }, { "uname", uname_coder, uname_decoder }, - /* The number of entries in xhdr_tab must agree with the array - bounds in xhdr_tab's forward declaration. */ - -#if 0 /* GNU private keywords (not yet implemented) */ /* Sparse file handling */ + { "GNU.sparse.size", sparse_size_coder, sparse_size_decoder }, + { "GNU.sparse.numblocks", sparse_numblocks_coder, sparse_numblocks_decoder }, { "GNU.sparse.offset", sparse_offset_coder, sparse_offset_decoder }, { "GNU.sparse.numbytes", sparse_numbytes_coder, sparse_numbytes_decoder }, +#if 0 /* GNU private keywords (not yet implemented) */ + /* 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. */