From: Sergey Poznyakoff Date: Sun, 31 Aug 2003 22:35:35 +0000 (+0000) Subject: New file X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=5be0f2ba491f27074c35875185286d1d425ce044;p=chaz%2Ftar New file --- diff --git a/src/xheader.c b/src/xheader.c new file mode 100644 index 0000000..114a499 --- /dev/null +++ b/src/xheader.c @@ -0,0 +1,295 @@ +/* This file is part of GNU Tar + + Copyright (C) 2003 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 + version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "system.h" + +#include +#include +#include +#include + +#include "common.h" + +/* Forward declarations */ +static void dummy_handler (struct tar_stat_info *st, char *keyword, char *arg); + +static void atime_coder (struct tar_stat_info *st, char *keyword, char *arg); +static void atime_decoder (struct tar_stat_info *st, char *keyword, char *arg); + +static void gid_coder (struct tar_stat_info *st, char *keyword, char *arg); +static void gid_decoder (struct tar_stat_info *st, char *keyword, char *arg); + +static void gname_coder (struct tar_stat_info *st, char *keyword, char *arg); +static void gname_decoder (struct tar_stat_info *st, char *keyword, char *arg); + +static void linkpath_coder (struct tar_stat_info *st, char *keyword, char *arg); +static void linkpath_decoder (struct tar_stat_info *st, char *keyword, char *arg); + +static void mtime_coder (struct tar_stat_info *st, char *keyword, char *arg); +static void mtime_decoder (struct tar_stat_info *st, char *keyword, char *arg); + +static void ctime_coder (struct tar_stat_info *st, char *keyword, char *arg); +static void ctime_decoder (struct tar_stat_info *st, char *keyword, char *arg); + +static void path_coder (struct tar_stat_info *st, char *keyword, char *arg); +static void path_decoder (struct tar_stat_info *st, char *keyword, char *arg); + +static void size_coder (struct tar_stat_info *st, char *keyword, char *arg); +static void size_decoder (struct tar_stat_info *st, char *keyword, char *arg); + +static void uid_coder (struct tar_stat_info *st, char *keyword, char *arg); +static void uid_decoder (struct tar_stat_info *st, char *keyword, char *arg); + +static void uname_coder (struct tar_stat_info *st, char *keyword, char *arg); +static void uname_decoder (struct tar_stat_info *st, char *keyword, char *arg); + +/* General Interface */ + +struct xhdr_tab +{ + char *keyword; + void (*coder) (struct tar_stat_info *st, char *keyword, char *arg); + void (*decoder) (struct tar_stat_info *st, char *keyword, char *arg); +}; + +struct xhdr_tab xhdr_tab[] = { + { "atime", atime_coder, atime_decoder }, + { "comment", dummy_handler, dummy_handler }, + { "charset", dummy_handler, dummy_handler }, + { "ctime", ctime_coder, ctime_decoder }, + { "gid", gid_coder, gid_decoder }, + { "gname", gname_coder, gname_decoder }, + { "linkpath", linkpath_coder, linkpath_decoder }, + { "mtime", mtime_coder, mtime_decoder }, + { "path", path_coder, path_decoder }, + { "size", size_coder, size_decoder }, + { "uid", uid_coder, uid_decoder }, + { "uname", uname_coder, uname_decoder }, + { NULL }, +}; + +static struct xhdr_tab * +locate_handler (char *keyword) +{ + struct xhdr_tab *p; + + for (p = xhdr_tab; p->keyword; p++) + if (strcmp (p->keyword, keyword) == 0) + return p; + return NULL; +} + +static int +decode_record (char **p, struct tar_stat_info *st) +{ + size_t len; + char *keyword, *eqp; + char *start = *p; + struct xhdr_tab *t; + + if (**p == 0) + return 1; + + len = strtoul (*p, p, 10); + if (**p != ' ') + { + ERROR ((0, 0, _("Malformed extended headed"))); + return 1; + } + + keyword = ++*p; + for (;*p < start + len; ++*p) + if (**p == '=') + break; + + if (**p != '=') + { + ERROR ((0, 0, _("Malformed extended headed"))); + return 1; + } + + eqp = *p; + **p = 0; + t = locate_handler (keyword); + if (t) + { + char endc; + char *value; + + value = ++*p; + + endc = start[len-1]; + start[len-1] = 0; + t->decoder (st, keyword, value); + start[len-1] = endc; + } + *eqp = '='; + *p = &start[len]; + return 0; +} + +void +xheader_decode (struct tar_stat_info *st) +{ + char *p, *endp; + + p = extended_header.blocks->buffer; + endp = &extended_header.blocks[extended_header.nblocks-1].buffer + [sizeof(extended_header.blocks[0])-1]; + while (p < endp) + if (decode_record (&p, st)) + break; +} + +void +xheader_read (union block *p, size_t size) +{ + size_t i; + + free (extended_header.blocks); + extended_header.nblocks = (size + BLOCKSIZE - 1) / BLOCKSIZE; + extended_header.blocks = xmalloc (sizeof (extended_header.blocks[0]) * + extended_header.nblocks); + set_next_block_after (p); + for (i = 0; i < extended_header.nblocks; i++) + { + p = find_next_block (); + memcpy (&extended_header.blocks[i], p, sizeof (p[0])); + set_next_block_after (p); + } +} + + +/* Implementations */ +static void +dummy_handler (struct tar_stat_info *st, char *keyword, char *arg) +{ +} + +static void +atime_coder (struct tar_stat_info *st, char *keyword, char *arg) +{ +} + +static void +atime_decoder (struct tar_stat_info *st, char *keyword, char *arg) +{ + st->stat.st_atime = strtoul (arg, NULL, 0); +} + +static void +gid_coder (struct tar_stat_info *st, char *keyword, char *arg) +{ +} + +static void +gid_decoder (struct tar_stat_info *st, char *keyword, char *arg) +{ + st->stat.st_gid = strtoul (arg, NULL, 0); +} + +static void +gname_coder (struct tar_stat_info *st, char *keyword, char *arg) +{ +} + +static void +gname_decoder (struct tar_stat_info *st, char *keyword, char *arg) +{ + st->gname = strdup (arg); +} + +static void +linkpath_coder (struct tar_stat_info *st, char *keyword, char *arg) +{ +} + +static void +linkpath_decoder (struct tar_stat_info *st, char *keyword, char *arg) +{ + st->link_name = strdup (arg); +} + +static void +ctime_coder (struct tar_stat_info *st, char *keyword, char *arg) +{ +} + +static void +ctime_decoder (struct tar_stat_info *st, char *keyword, char *arg) +{ + st->stat.st_ctime = strtoul (arg, NULL, 0); +} + +static void +mtime_coder (struct tar_stat_info *st, char *keyword, char *arg) +{ +} + +static void +mtime_decoder (struct tar_stat_info *st, char *keyword, char *arg) +{ + st->stat.st_mtime = strtoul (arg, NULL, 0); +} + +static void +path_coder (struct tar_stat_info *st, char *keyword, char *arg) +{ +} + +static void +path_decoder (struct tar_stat_info *st, char *keyword, char *arg) +{ + assign_string (&st->orig_file_name, arg); + assign_string (&st->file_name, arg); + st->had_trailing_slash = strip_trailing_slashes (st->file_name); +} + +static void +size_coder (struct tar_stat_info *st, char *keyword, char *arg) +{ +} + +static void +size_decoder (struct tar_stat_info *st, char *keyword, char *arg) +{ + st->stat.st_size = strtoul (arg, NULL, 0); +} + +static void +uid_coder (struct tar_stat_info *st, char *keyword, char *arg) +{ +} + +static void +uid_decoder (struct tar_stat_info *st, char *keyword, char *arg) +{ + st->stat.st_uid = strtoul (arg, NULL, 0); +} + +static void +uname_coder (struct tar_stat_info *st, char *keyword, char *arg) +{ +} + +static void +uname_decoder (struct tar_stat_info *st, char *keyword, char *arg) +{ + st->uname = strdup (arg); +} +