X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Ftar;a=blobdiff_plain;f=scripts%2Fxsparse.c;h=29ee1b194aa0bceecc2c28d5f408b855845f2b66;hp=c77c3f5ced78b0e1c96baf816726cdf754d59876;hb=45ccda119355a1087450039a250359c1d0de0d08;hpb=a0fb51e136d3df620eb3189683aae90b25bd8dd7 diff --git a/scripts/xsparse.c b/scripts/xsparse.c index c77c3f5..29ee1b1 100644 --- a/scripts/xsparse.c +++ b/scripts/xsparse.c @@ -1,27 +1,30 @@ /* xsparse - expands compressed sparse file images extracted from GNU tar archives. - Copyright (C) 2006, 2007 Free Software Foundation, Inc. + Copyright 2006-2007, 2010, 2013-2014 Free Software Foundation, Inc. - Written by Sergey Poznyakoff - - 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 3, or (at your option) any later - version. + This file is part of GNU tar. - 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. + GNU tar 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 3 of the License, or + (at your option) any later version. - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + GNU tar 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, see . + + Written by Sergey Poznyakoff */ #include +#include #include #include +#include #include #include #include @@ -38,7 +41,7 @@ struct sp_array { off_t offset; - size_t numbytes; + off_t numbytes; }; char *progname; @@ -128,12 +131,12 @@ get_var (FILE *fp, char **name, char **value) static char *buffer; static size_t bufsize = OFF_T_STRSIZE_BOUND; char *p, *q; - + buffer = emalloc (bufsize); do { size_t len, s; - + if (!fgets (buffer, bufsize, fp)) return 0; len = strlen (buffer); @@ -162,7 +165,7 @@ get_var (FILE *fp, char **name, char **value) p += 11; q = strchr (p, '='); if (!q) - die (1, "malformed header: expected `=' not found"); + die (1, "malformed header: expected '=' not found"); *q++ = 0; q[strlen (q) - 1] = 0; *name = p; @@ -185,14 +188,14 @@ read_xheader (char *name) if (verbose) printf ("Reading extended header file\n"); - + while (get_var (fp, &kw, &val)) { if (verbose) printf ("Found variable GNU.sparse.%s = %s\n", kw, val); - + if (expect && strcmp (kw, expect)) - die (1, "bad keyword sequence: expected `%s' but found `%s'", + die (1, "bad keyword sequence: expected '%s' but found '%s'", expect, kw); expect = NULL; if (strcmp (kw, "name") == 0) @@ -225,7 +228,7 @@ read_xheader (char *name) } else if (strcmp (kw, "numbytes") == 0) { - sparse_map[i++].numbytes = string_to_size (val, NULL); + sparse_map[i++].numbytes = string_to_off (val, NULL); } else if (strcmp (kw, "map") == 0) { @@ -233,13 +236,13 @@ read_xheader (char *name) { sparse_map[i].offset = string_to_off (val, &val); if (*val != ',') - die (1, "bad GNU.sparse.map: expected `,' but found `%c'", + die (1, "bad GNU.sparse.map: expected ',' but found '%c'", *val); - sparse_map[i].numbytes = string_to_size (val+1, &val); + sparse_map[i].numbytes = string_to_off (val+1, &val); if (*val != ',') { if (!(*val == 0 && i == sparse_map_size-1)) - die (1, "bad GNU.sparse.map: expected `,' but found `%c'", + die (1, "bad GNU.sparse.map: expected ',' but found '%c'", *val); } else @@ -250,7 +253,7 @@ read_xheader (char *name) } } if (expect) - die (1, "bad keyword sequence: expected `%s' not found", expect); + die (1, "bad keyword sequence: expected '%s' not found", expect); if (version_major == 0 && sparse_map_size == 0) die (1, "size of the sparse map unknown"); if (i != sparse_map_size) @@ -266,7 +269,7 @@ read_map (FILE *ifp) if (verbose) printf ("Reading v.1.0 sparse map\n"); - + get_line (nbuf, sizeof nbuf, ifp); sparse_map_size = string_to_size (nbuf, NULL); sparse_map = emalloc (sparse_map_size * sizeof *sparse_map); @@ -276,31 +279,34 @@ read_map (FILE *ifp) get_line (nbuf, sizeof nbuf, ifp); sparse_map[i].offset = string_to_off (nbuf, NULL); get_line (nbuf, sizeof nbuf, ifp); - sparse_map[i].numbytes = string_to_size (nbuf, NULL); + sparse_map[i].numbytes = string_to_off (nbuf, NULL); } - fseek (ifp, ((ftell (ifp) + BLOCKSIZE - 1) / BLOCKSIZE) * BLOCKSIZE, - SEEK_SET); -} + fseeko (ifp, ((ftell (ifp) + BLOCKSIZE - 1) / BLOCKSIZE) * BLOCKSIZE, + SEEK_SET); +} void expand_sparse (FILE *sfp, int ofd) { size_t i; - size_t maxbytes = 0; + off_t max_numbytes = 0; + size_t maxbytes; char *buffer; for (i = 0; i < sparse_map_size; i++) - if (maxbytes < sparse_map[i].numbytes) - maxbytes = sparse_map[i].numbytes; - + if (max_numbytes < sparse_map[i].numbytes) + max_numbytes = sparse_map[i].numbytes; + + maxbytes = max_numbytes < SIZE_MAX ? max_numbytes : SIZE_MAX; + for (buffer = malloc (maxbytes); !buffer; maxbytes /= 2) if (maxbytes == 0) die (1, "not enough memory"); - + for (i = 0; i < sparse_map_size; i++) { - size_t size = sparse_map[i].numbytes; + off_t size = sparse_map[i].numbytes; if (size == 0) ftruncate (ofd, sparse_map[i].offset); @@ -341,13 +347,13 @@ guess_outname (char *name) { char *p; char *s; - + if (name[0] == '.' && name[1] == '/') name += 2; p = name + strlen (name) - 1; s = NULL; - + for (; p > name && *p != '/'; p--) ; if (*p == '/') @@ -357,7 +363,7 @@ guess_outname (char *name) for (p--; p > name && *p != '/'; p--) ; } - + if (*p != '/') { if (s) @@ -388,7 +394,7 @@ main (int argc, char **argv) FILE *ifp; struct stat st; int ofd; - + progname = argv[0]; while ((c = getopt (argc, argv, "hnvx:")) != EOF) { @@ -407,7 +413,7 @@ main (int argc, char **argv) case 'v': verbose++; break; - + default: exit (1); } @@ -428,30 +434,30 @@ main (int argc, char **argv) if (stat (inname, &st)) die (1, "cannot stat %s (%d)", inname, errno); - + ifp = fopen (inname, "r"); if (ifp == NULL) die (1, "cannot open file %s (%d)", inname, errno); - + if (!xheader_file || version_major == 1) read_map (ifp); if (!outname) guess_outname (inname); - + ofd = open (outname, O_RDWR|O_CREAT|O_TRUNC, st.st_mode); if (ofd == -1) die (1, "cannot open file %s (%d)", outname, errno); if (verbose) - printf ("Expanding file `%s' to `%s'\n", inname, outname); + printf ("Expanding file '%s' to '%s'\n", inname, outname); if (dry_run) { printf ("Finished dry run\n"); return 0; } - + expand_sparse (ifp, ofd); fclose (ifp); @@ -459,7 +465,7 @@ main (int argc, char **argv) if (verbose) printf ("Done\n"); - + if (outsize) { if (stat (outname, &st)) @@ -467,7 +473,6 @@ main (int argc, char **argv) if (st.st_size != outsize) die (1, "expanded file has wrong size"); } - + return 0; } -