1 /* Functions for dealing with sparse files
3 Copyright 2003-2007, 2010, 2013-2016 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 3, or (at your option) any later
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program. If not, see <http://www.gnu.org/licenses/>. */
23 struct tar_sparse_file;
24 static bool sparse_select_optab (struct tar_sparse_file *file);
26 enum sparse_scan_state
33 struct tar_sparse_optab
35 bool (*init) (struct tar_sparse_file *);
36 bool (*done) (struct tar_sparse_file *);
37 bool (*sparse_member_p) (struct tar_sparse_file *);
38 bool (*dump_header) (struct tar_sparse_file *);
39 bool (*fixup_header) (struct tar_sparse_file *);
40 bool (*decode_header) (struct tar_sparse_file *);
41 bool (*scan_block) (struct tar_sparse_file *, enum sparse_scan_state,
43 bool (*dump_region) (struct tar_sparse_file *, size_t);
44 bool (*extract_region) (struct tar_sparse_file *, size_t);
47 struct tar_sparse_file
49 int fd; /* File descriptor */
50 bool seekable; /* Is fd seekable? */
51 off_t offset; /* Current offset in fd if seekable==false.
53 off_t dumped_size; /* Number of bytes actually written
55 struct tar_stat_info *stat_info; /* Information about the file */
56 struct tar_sparse_optab const *optab; /* Operation table */
57 void *closure; /* Any additional data optab calls might
61 /* Dump zeros to file->fd until offset is reached. It is used instead of
62 lseek if the output file is not seekable */
64 dump_zeros (struct tar_sparse_file *file, off_t offset)
66 static char const zero_buf[BLOCKSIZE];
68 if (offset < file->offset)
74 while (file->offset < offset)
76 size_t size = (BLOCKSIZE < offset - file->offset
78 : offset - file->offset);
81 wrbytes = write (file->fd, zero_buf, size);
88 file->offset += wrbytes;
95 tar_sparse_member_p (struct tar_sparse_file *file)
97 if (file->optab->sparse_member_p)
98 return file->optab->sparse_member_p (file);
103 tar_sparse_init (struct tar_sparse_file *file)
105 memset (file, 0, sizeof *file);
107 if (!sparse_select_optab (file))
110 if (file->optab->init)
111 return file->optab->init (file);
117 tar_sparse_done (struct tar_sparse_file *file)
119 if (file->optab->done)
120 return file->optab->done (file);
125 tar_sparse_scan (struct tar_sparse_file *file, enum sparse_scan_state state,
128 if (file->optab->scan_block)
129 return file->optab->scan_block (file, state, block);
134 tar_sparse_dump_region (struct tar_sparse_file *file, size_t i)
136 if (file->optab->dump_region)
137 return file->optab->dump_region (file, i);
142 tar_sparse_extract_region (struct tar_sparse_file *file, size_t i)
144 if (file->optab->extract_region)
145 return file->optab->extract_region (file, i);
150 tar_sparse_dump_header (struct tar_sparse_file *file)
152 if (file->optab->dump_header)
153 return file->optab->dump_header (file);
158 tar_sparse_decode_header (struct tar_sparse_file *file)
160 if (file->optab->decode_header)
161 return file->optab->decode_header (file);
166 tar_sparse_fixup_header (struct tar_sparse_file *file)
168 if (file->optab->fixup_header)
169 return file->optab->fixup_header (file);
175 lseek_or_error (struct tar_sparse_file *file, off_t offset)
178 ? lseek (file->fd, offset, SEEK_SET) < 0
179 : ! dump_zeros (file, offset))
181 seek_diag_details (file->stat_info->orig_file_name, offset);
187 /* Takes a blockful of data and basically cruises through it to see if
188 it's made *entirely* of zeros, returning a 0 the instant it finds
189 something that is a nonzero, i.e., useful data. */
191 zero_block_p (char const *buffer, size_t size)
200 sparse_add_map (struct tar_stat_info *st, struct sp_array const *sp)
202 struct sp_array *sparse_map = st->sparse_map;
203 size_t avail = st->sparse_map_avail;
204 if (avail == st->sparse_map_size)
205 st->sparse_map = sparse_map =
206 x2nrealloc (sparse_map, &st->sparse_map_size, sizeof *sparse_map);
207 sparse_map[avail] = *sp;
208 st->sparse_map_avail = avail + 1;
211 /* Scan the sparse file byte-by-byte and create its map. */
213 sparse_scan_file_raw (struct tar_sparse_file *file)
215 struct tar_stat_info *st = file->stat_info;
217 char buffer[BLOCKSIZE];
220 struct sp_array sp = {0, 0};
222 st->archive_file_size = 0;
224 if (!tar_sparse_scan (file, scan_begin, NULL))
227 while ((count = blocking_read (fd, buffer, sizeof buffer)) != 0
228 && count != SAFE_READ_ERROR)
230 /* Analyze the block. */
231 if (zero_block_p (buffer, count))
235 sparse_add_map (st, &sp);
237 if (!tar_sparse_scan (file, scan_block, NULL))
243 if (sp.numbytes == 0)
245 sp.numbytes += count;
246 st->archive_file_size += count;
247 if (!tar_sparse_scan (file, scan_block, buffer))
254 /* save one more sparse segment of length 0 to indicate that
255 the file ends with a hole */
256 if (sp.numbytes == 0)
259 sparse_add_map (st, &sp);
260 st->archive_file_size += count;
261 return tar_sparse_scan (file, scan_end, NULL);
265 sparse_scan_file_wholesparse (struct tar_sparse_file *file)
267 struct tar_stat_info *st = file->stat_info;
268 struct sp_array sp = {0, 0};
270 /* Note that this function is called only for truly sparse files of size >= 1
271 block size (checked via ST_IS_SPARSE before). See the thread
272 http://www.mail-archive.com/bug-tar@gnu.org/msg04209.html for more info */
273 if (ST_NBLOCKS (st->stat) == 0)
275 st->archive_file_size = 0;
276 sp.offset = st->stat.st_size;
277 sparse_add_map (st, &sp);
285 /* Try to engage SEEK_HOLE/SEEK_DATA feature. */
287 sparse_scan_file_seek (struct tar_sparse_file *file)
289 struct tar_stat_info *st = file->stat_info;
291 struct sp_array sp = {0, 0};
296 st->archive_file_size = 0;
300 /* locate first chunk of data */
301 data_offset = lseek (fd, offset, SEEK_DATA);
303 if (data_offset == (off_t)-1)
304 /* ENXIO == EOF; error otherwise */
308 /* file ends with hole, add one more empty chunk of data */
310 sp.offset = st->stat.st_size;
311 sparse_add_map (st, &sp);
317 hole_offset = lseek (fd, data_offset, SEEK_HOLE);
319 /* according to specs, if FS does not fully support
320 SEEK_DATA/SEEK_HOLE it may just implement kind of "wrapper" around
321 classic lseek() call. We must detect it here and try to use other
322 hole-detection methods. */
323 if (offset == 0 /* first loop */
325 && hole_offset == st->stat.st_size)
327 lseek (fd, 0, SEEK_SET);
331 sp.offset = data_offset;
332 sp.numbytes = hole_offset - data_offset;
333 sparse_add_map (st, &sp);
335 st->archive_file_size += sp.numbytes;
336 offset = hole_offset;
344 sparse_scan_file (struct tar_sparse_file *file)
346 /* always check for completely sparse files */
347 if (sparse_scan_file_wholesparse (file))
350 switch (hole_detection)
352 case HOLE_DETECTION_DEFAULT:
353 case HOLE_DETECTION_SEEK:
355 if (sparse_scan_file_seek (file))
358 if (hole_detection == HOLE_DETECTION_SEEK)
360 _("\"seek\" hole detection is not supported, using \"raw\".")));
361 /* fall back to "raw" for this and all other files */
362 hole_detection = HOLE_DETECTION_RAW;
364 case HOLE_DETECTION_RAW:
365 if (sparse_scan_file_raw (file))
372 static struct tar_sparse_optab const oldgnu_optab;
373 static struct tar_sparse_optab const star_optab;
374 static struct tar_sparse_optab const pax_optab;
377 sparse_select_optab (struct tar_sparse_file *file)
379 switch (current_format == DEFAULT_FORMAT ? archive_format : current_format)
386 case GNU_FORMAT: /*FIXME: This one should disappear? */
387 file->optab = &oldgnu_optab;
391 file->optab = &pax_optab;
395 file->optab = &star_optab;
405 sparse_dump_region (struct tar_sparse_file *file, size_t i)
408 off_t bytes_left = file->stat_info->sparse_map[i].numbytes;
410 if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset))
413 while (bytes_left > 0)
415 size_t bufsize = (bytes_left > BLOCKSIZE) ? BLOCKSIZE : bytes_left;
418 blk = find_next_block ();
419 bytes_read = safe_read (file->fd, blk->buffer, bufsize);
420 if (bytes_read == SAFE_READ_ERROR)
422 read_diag_details (file->stat_info->orig_file_name,
423 (file->stat_info->sparse_map[i].offset
424 + file->stat_info->sparse_map[i].numbytes
430 memset (blk->buffer + bytes_read, 0, BLOCKSIZE - bytes_read);
431 bytes_left -= bytes_read;
432 file->dumped_size += bytes_read;
433 set_next_block_after (blk);
440 sparse_extract_region (struct tar_sparse_file *file, size_t i)
444 if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset))
447 write_size = file->stat_info->sparse_map[i].numbytes;
451 /* Last block of the file is a hole */
452 if (file->seekable && sys_truncate (file->fd))
453 truncate_warn (file->stat_info->orig_file_name);
455 else while (write_size > 0)
458 size_t wrbytes = (write_size > BLOCKSIZE) ? BLOCKSIZE : write_size;
459 union block *blk = find_next_block ();
462 ERROR ((0, 0, _("Unexpected EOF in archive")));
465 set_next_block_after (blk);
466 count = blocking_write (file->fd, blk->buffer, wrbytes);
468 file->dumped_size += count;
469 mv_size_left (file->stat_info->archive_file_size - file->dumped_size);
470 file->offset += count;
471 if (count != wrbytes)
473 write_error_details (file->stat_info->orig_file_name,
483 /* Interface functions */
485 sparse_dump_file (int fd, struct tar_stat_info *st)
488 struct tar_sparse_file file;
490 if (!tar_sparse_init (&file))
491 return dump_status_not_implemented;
495 file.seekable = true; /* File *must* be seekable for dump to work */
497 rc = sparse_scan_file (&file);
498 if (rc && file.optab->dump_region)
500 tar_sparse_dump_header (&file);
506 mv_begin_write (file.stat_info->file_name,
507 file.stat_info->stat.st_size,
508 file.stat_info->archive_file_size - file.dumped_size);
509 for (i = 0; rc && i < file.stat_info->sparse_map_avail; i++)
510 rc = tar_sparse_dump_region (&file, i);
514 pad_archive (file.stat_info->archive_file_size - file.dumped_size);
515 return (tar_sparse_done (&file) && rc) ? dump_status_ok : dump_status_short;
519 sparse_member_p (struct tar_stat_info *st)
521 struct tar_sparse_file file;
523 if (!tar_sparse_init (&file))
526 return tar_sparse_member_p (&file);
530 sparse_fixup_header (struct tar_stat_info *st)
532 struct tar_sparse_file file;
534 if (!tar_sparse_init (&file))
537 return tar_sparse_fixup_header (&file);
541 sparse_extract_file (int fd, struct tar_stat_info *st, off_t *size)
544 struct tar_sparse_file file;
547 if (!tar_sparse_init (&file))
548 return dump_status_not_implemented;
552 file.seekable = lseek (fd, 0, SEEK_SET) == 0;
555 rc = tar_sparse_decode_header (&file);
556 for (i = 0; rc && i < file.stat_info->sparse_map_avail; i++)
557 rc = tar_sparse_extract_region (&file, i);
558 *size = file.stat_info->archive_file_size - file.dumped_size;
559 return (tar_sparse_done (&file) && rc) ? dump_status_ok : dump_status_short;
563 sparse_skip_file (struct tar_stat_info *st)
566 struct tar_sparse_file file;
568 if (!tar_sparse_init (&file))
569 return dump_status_not_implemented;
574 rc = tar_sparse_decode_header (&file);
575 skip_file (file.stat_info->archive_file_size - file.dumped_size);
576 return (tar_sparse_done (&file) && rc) ? dump_status_ok : dump_status_short;
581 check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end)
583 if (!lseek_or_error (file, beg))
589 size_t rdsize = BLOCKSIZE < end - beg ? BLOCKSIZE : end - beg;
590 char diff_buffer[BLOCKSIZE];
592 bytes_read = safe_read (file->fd, diff_buffer, rdsize);
593 if (bytes_read == SAFE_READ_ERROR)
595 read_diag_details (file->stat_info->orig_file_name,
600 if (!zero_block_p (diff_buffer, bytes_read))
602 char begbuf[INT_BUFSIZE_BOUND (off_t)];
603 report_difference (file->stat_info,
604 _("File fragment at %s is not a hole"),
605 offtostr (beg, begbuf));
615 check_data_region (struct tar_sparse_file *file, size_t i)
619 if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset))
621 size_left = file->stat_info->sparse_map[i].numbytes;
622 mv_size_left (file->stat_info->archive_file_size - file->dumped_size);
624 while (size_left > 0)
627 size_t rdsize = (size_left > BLOCKSIZE) ? BLOCKSIZE : size_left;
628 char diff_buffer[BLOCKSIZE];
630 union block *blk = find_next_block ();
633 ERROR ((0, 0, _("Unexpected EOF in archive")));
636 set_next_block_after (blk);
637 bytes_read = safe_read (file->fd, diff_buffer, rdsize);
638 if (bytes_read == SAFE_READ_ERROR)
640 read_diag_details (file->stat_info->orig_file_name,
641 (file->stat_info->sparse_map[i].offset
642 + file->stat_info->sparse_map[i].numbytes
647 file->dumped_size += bytes_read;
648 size_left -= bytes_read;
649 mv_size_left (file->stat_info->archive_file_size - file->dumped_size);
650 if (memcmp (blk->buffer, diff_buffer, rdsize))
652 report_difference (file->stat_info, _("Contents differ"));
660 sparse_diff_file (int fd, struct tar_stat_info *st)
663 struct tar_sparse_file file;
667 if (!tar_sparse_init (&file))
668 return dump_status_not_implemented;
672 file.seekable = true; /* File *must* be seekable for compare to work */
674 rc = tar_sparse_decode_header (&file);
676 for (i = 0; rc && i < file.stat_info->sparse_map_avail; i++)
678 rc = check_sparse_region (&file,
679 offset, file.stat_info->sparse_map[i].offset)
680 && check_data_region (&file, i);
681 offset = file.stat_info->sparse_map[i].offset
682 + file.stat_info->sparse_map[i].numbytes;
686 skip_file (file.stat_info->archive_file_size - file.dumped_size);
689 tar_sparse_done (&file);
694 /* Old GNU Format. The sparse file information is stored in the
695 oldgnu_header in the following manner:
697 The header is marked with type 'S'. Its 'size' field contains
698 the cumulative size of all non-empty blocks of the file. The
699 actual file size is stored in 'realsize' member of oldgnu_header.
701 The map of the file is stored in a list of 'struct sparse'.
702 Each struct contains offset to the block of data and its
703 size (both as octal numbers). The first file header contains
704 at most 4 such structs (SPARSES_IN_OLDGNU_HEADER). If the map
705 contains more structs, then the field 'isextended' of the main
706 header is set to 1 (binary) and the 'struct sparse_header'
707 header follows, containing at most 21 following structs
708 (SPARSES_IN_SPARSE_HEADER). If more structs follow, 'isextended'
709 field of the extended header is set and next next extension header
712 enum oldgnu_add_status
720 oldgnu_sparse_member_p (struct tar_sparse_file *file __attribute__ ((unused)))
722 return current_header->header.typeflag == GNUTYPE_SPARSE;
725 /* Add a sparse item to the sparse file and its obstack */
726 static enum oldgnu_add_status
727 oldgnu_add_sparse (struct tar_sparse_file *file, struct sparse *s)
731 if (s->numbytes[0] == '\0')
733 sp.offset = OFF_FROM_HEADER (s->offset);
734 sp.numbytes = OFF_FROM_HEADER (s->numbytes);
735 if (sp.offset < 0 || sp.numbytes < 0
736 || INT_ADD_OVERFLOW (sp.offset, sp.numbytes)
737 || file->stat_info->stat.st_size < sp.offset + sp.numbytes
738 || file->stat_info->archive_file_size < 0)
741 sparse_add_map (file->stat_info, &sp);
746 oldgnu_fixup_header (struct tar_sparse_file *file)
748 /* NOTE! st_size was initialized from the header
749 which actually contains archived size. The following fixes it */
750 off_t realsize = OFF_FROM_HEADER (current_header->oldgnu_header.realsize);
751 file->stat_info->archive_file_size = file->stat_info->stat.st_size;
752 file->stat_info->stat.st_size = max (0, realsize);
753 return 0 <= realsize;
756 /* Convert old GNU format sparse data to internal representation */
758 oldgnu_get_sparse_info (struct tar_sparse_file *file)
761 union block *h = current_header;
763 enum oldgnu_add_status rc;
765 file->stat_info->sparse_map_avail = 0;
766 for (i = 0; i < SPARSES_IN_OLDGNU_HEADER; i++)
768 rc = oldgnu_add_sparse (file, &h->oldgnu_header.sp[i]);
773 for (ext_p = h->oldgnu_header.isextended;
774 rc == add_ok && ext_p; ext_p = h->sparse_header.isextended)
776 h = find_next_block ();
779 ERROR ((0, 0, _("Unexpected EOF in archive")));
782 set_next_block_after (h);
783 for (i = 0; i < SPARSES_IN_SPARSE_HEADER && rc == add_ok; i++)
784 rc = oldgnu_add_sparse (file, &h->sparse_header.sp[i]);
789 ERROR ((0, 0, _("%s: invalid sparse archive member"),
790 file->stat_info->orig_file_name));
797 oldgnu_store_sparse_info (struct tar_sparse_file *file, size_t *pindex,
798 struct sparse *sp, size_t sparse_size)
800 for (; *pindex < file->stat_info->sparse_map_avail
801 && sparse_size > 0; sparse_size--, sp++, ++*pindex)
803 OFF_TO_CHARS (file->stat_info->sparse_map[*pindex].offset,
805 OFF_TO_CHARS (file->stat_info->sparse_map[*pindex].numbytes,
811 oldgnu_dump_header (struct tar_sparse_file *file)
813 off_t block_ordinal = current_block_ordinal ();
817 blk = start_header (file->stat_info);
818 blk->header.typeflag = GNUTYPE_SPARSE;
819 if (file->stat_info->sparse_map_avail > SPARSES_IN_OLDGNU_HEADER)
820 blk->oldgnu_header.isextended = 1;
822 /* Store the real file size */
823 OFF_TO_CHARS (file->stat_info->stat.st_size, blk->oldgnu_header.realsize);
824 /* Store the effective (shrunken) file size */
825 OFF_TO_CHARS (file->stat_info->archive_file_size, blk->header.size);
828 oldgnu_store_sparse_info (file, &i,
829 blk->oldgnu_header.sp,
830 SPARSES_IN_OLDGNU_HEADER);
831 blk->oldgnu_header.isextended = i < file->stat_info->sparse_map_avail;
832 finish_header (file->stat_info, blk, block_ordinal);
834 while (i < file->stat_info->sparse_map_avail)
836 blk = find_next_block ();
837 memset (blk->buffer, 0, BLOCKSIZE);
838 oldgnu_store_sparse_info (file, &i,
839 blk->sparse_header.sp,
840 SPARSES_IN_SPARSE_HEADER);
841 if (i < file->stat_info->sparse_map_avail)
842 blk->sparse_header.isextended = 1;
843 set_next_block_after (blk);
848 static struct tar_sparse_optab const oldgnu_optab = {
849 NULL, /* No init function */
850 NULL, /* No done function */
851 oldgnu_sparse_member_p,
854 oldgnu_get_sparse_info,
855 NULL, /* No scan_block function */
857 sparse_extract_region,
864 star_sparse_member_p (struct tar_sparse_file *file __attribute__ ((unused)))
866 return current_header->header.typeflag == GNUTYPE_SPARSE;
870 star_fixup_header (struct tar_sparse_file *file)
872 /* NOTE! st_size was initialized from the header
873 which actually contains archived size. The following fixes it */
874 off_t realsize = OFF_FROM_HEADER (current_header->star_in_header.realsize);
875 file->stat_info->archive_file_size = file->stat_info->stat.st_size;
876 file->stat_info->stat.st_size = max (0, realsize);
877 return 0 <= realsize;
880 /* Convert STAR format sparse data to internal representation */
882 star_get_sparse_info (struct tar_sparse_file *file)
885 union block *h = current_header;
887 enum oldgnu_add_status rc = add_ok;
889 file->stat_info->sparse_map_avail = 0;
891 if (h->star_in_header.prefix[0] == '\0'
892 && h->star_in_header.sp[0].offset[10] != '\0')
894 /* Old star format */
895 for (i = 0; i < SPARSES_IN_STAR_HEADER; i++)
897 rc = oldgnu_add_sparse (file, &h->star_in_header.sp[i]);
901 ext_p = h->star_in_header.isextended;
906 for (; rc == add_ok && ext_p; ext_p = h->star_ext_header.isextended)
908 h = find_next_block ();
911 ERROR ((0, 0, _("Unexpected EOF in archive")));
914 set_next_block_after (h);
915 for (i = 0; i < SPARSES_IN_STAR_EXT_HEADER && rc == add_ok; i++)
916 rc = oldgnu_add_sparse (file, &h->star_ext_header.sp[i]);
917 file->dumped_size += BLOCKSIZE;
922 ERROR ((0, 0, _("%s: invalid sparse archive member"),
923 file->stat_info->orig_file_name));
930 static struct tar_sparse_optab const star_optab = {
931 NULL, /* No init function */
932 NULL, /* No done function */
933 star_sparse_member_p,
936 star_get_sparse_info,
937 NULL, /* No scan_block function */
938 NULL, /* No dump region function */
939 sparse_extract_region,
943 /* GNU PAX sparse file format. There are several versions:
947 The initial version of sparse format used by tar 1.14-1.15.1.
948 The sparse file map is stored in x header:
950 GNU.sparse.size Real size of the stored file
951 GNU.sparse.numblocks Number of blocks in the sparse map
952 repeat numblocks time
953 GNU.sparse.offset Offset of the next data block
954 GNU.sparse.numbytes Size of the next data block
957 This has been reported as conflicting with the POSIX specs. The reason is
958 that offsets and sizes of non-zero data blocks were stored in multiple
959 instances of GNU.sparse.offset/GNU.sparse.numbytes variables, whereas
960 POSIX requires the latest occurrence of the variable to override all
961 previous occurrences.
963 To avoid this incompatibility two following versions were introduced.
967 Used by tar 1.15.2 -- 1.15.91 (alpha releases).
969 The sparse file map is stored in
972 GNU.sparse.size Real size of the stored file
973 GNU.sparse.numblocks Number of blocks in the sparse map
974 GNU.sparse.map Map of non-null data chunks. A string consisting
975 of comma-separated values "offset,size[,offset,size]..."
977 The resulting GNU.sparse.map string can be *very* long. While POSIX does not
978 impose any limit on the length of a x header variable, this can confuse some
983 Starting from this version, the exact sparse format version is specified
984 explicitely in the header using the following variables:
986 GNU.sparse.major Major version
987 GNU.sparse.minor Minor version
989 X header keeps the following variables:
991 GNU.sparse.name Real file name of the sparse file
992 GNU.sparse.realsize Real size of the stored file (corresponds to the old
993 GNU.sparse.size variable)
995 The name field of the ustar header is constructed using the pattern
996 "%d/GNUSparseFile.%p/%f".
998 The sparse map itself is stored in the file data block, preceding the actual
999 file data. It consists of a series of octal numbers of arbitrary length,
1000 delimited by newlines. The map is padded with nulls to the nearest block
1003 The first number gives the number of entries in the map. Following are map
1004 entries, each one consisting of two numbers giving the offset and size of
1005 the data block it describes.
1007 The format is designed in such a way that non-posix aware tars and tars not
1008 supporting GNU.sparse.* keywords will extract each sparse file in its
1009 condensed form with the file map attached and will place it into a separate
1010 directory. Then, using a simple program it would be possible to expand the
1011 file to its original form even without GNU tar.
1013 Bu default, v.1.0 archives are created. To use other formats,
1014 --sparse-version option is provided. Additionally, v.0.0 can be obtained
1015 by deleting GNU.sparse.map from 0.1 format: --sparse-version 0.1
1016 --pax-option delete=GNU.sparse.map
1020 pax_sparse_member_p (struct tar_sparse_file *file)
1022 return file->stat_info->sparse_map_avail > 0
1023 || file->stat_info->sparse_major > 0;
1026 /* Start a header that uses the effective (shrunken) file size. */
1027 static union block *
1028 pax_start_header (struct tar_stat_info *st)
1030 off_t realsize = st->stat.st_size;
1032 st->stat.st_size = st->archive_file_size;
1033 blk = start_header (st);
1034 st->stat.st_size = realsize;
1039 pax_dump_header_0 (struct tar_sparse_file *file)
1041 off_t block_ordinal = current_block_ordinal ();
1044 char nbuf[UINTMAX_STRSIZE_BOUND];
1045 struct sp_array *map = file->stat_info->sparse_map;
1046 char *save_file_name = NULL;
1048 /* Store the real file size */
1049 xheader_store ("GNU.sparse.size", file->stat_info, NULL);
1050 xheader_store ("GNU.sparse.numblocks", file->stat_info, NULL);
1052 if (xheader_keyword_deleted_p ("GNU.sparse.map")
1053 || tar_sparse_minor == 0)
1055 for (i = 0; i < file->stat_info->sparse_map_avail; i++)
1057 xheader_store ("GNU.sparse.offset", file->stat_info, &i);
1058 xheader_store ("GNU.sparse.numbytes", file->stat_info, &i);
1063 xheader_store ("GNU.sparse.name", file->stat_info, NULL);
1064 save_file_name = file->stat_info->file_name;
1065 file->stat_info->file_name = xheader_format_name (file->stat_info,
1066 "%d/GNUSparseFile.%p/%f", 0);
1068 xheader_string_begin (&file->stat_info->xhdr);
1069 for (i = 0; i < file->stat_info->sparse_map_avail; i++)
1072 xheader_string_add (&file->stat_info->xhdr, ",");
1073 xheader_string_add (&file->stat_info->xhdr,
1074 umaxtostr (map[i].offset, nbuf));
1075 xheader_string_add (&file->stat_info->xhdr, ",");
1076 xheader_string_add (&file->stat_info->xhdr,
1077 umaxtostr (map[i].numbytes, nbuf));
1079 if (!xheader_string_end (&file->stat_info->xhdr,
1082 free (file->stat_info->file_name);
1083 file->stat_info->file_name = save_file_name;
1087 blk = pax_start_header (file->stat_info);
1088 finish_header (file->stat_info, blk, block_ordinal);
1091 free (file->stat_info->file_name);
1092 file->stat_info->file_name = save_file_name;
1098 pax_dump_header_1 (struct tar_sparse_file *file)
1100 off_t block_ordinal = current_block_ordinal ();
1104 char nbuf[UINTMAX_STRSIZE_BOUND];
1106 struct sp_array *map = file->stat_info->sparse_map;
1107 char *save_file_name = file->stat_info->file_name;
1109 #define COPY_STRING(b,dst,src) do \
1111 char *endp = b->buffer + BLOCKSIZE; \
1112 char const *srcp = src; \
1117 set_next_block_after (b); \
1118 b = find_next_block (); \
1120 endp = b->buffer + BLOCKSIZE; \
1126 /* Compute stored file size */
1127 p = umaxtostr (file->stat_info->sparse_map_avail, nbuf);
1128 size += strlen (p) + 1;
1129 for (i = 0; i < file->stat_info->sparse_map_avail; i++)
1131 p = umaxtostr (map[i].offset, nbuf);
1132 size += strlen (p) + 1;
1133 p = umaxtostr (map[i].numbytes, nbuf);
1134 size += strlen (p) + 1;
1136 size = (size + BLOCKSIZE - 1) / BLOCKSIZE;
1137 file->stat_info->archive_file_size += size * BLOCKSIZE;
1138 file->dumped_size += size * BLOCKSIZE;
1140 /* Store sparse file identification */
1141 xheader_store ("GNU.sparse.major", file->stat_info, NULL);
1142 xheader_store ("GNU.sparse.minor", file->stat_info, NULL);
1143 xheader_store ("GNU.sparse.name", file->stat_info, NULL);
1144 xheader_store ("GNU.sparse.realsize", file->stat_info, NULL);
1146 file->stat_info->file_name =
1147 xheader_format_name (file->stat_info, "%d/GNUSparseFile.%p/%f", 0);
1148 /* Make sure the created header name is shorter than NAME_FIELD_SIZE: */
1149 if (strlen (file->stat_info->file_name) > NAME_FIELD_SIZE)
1150 file->stat_info->file_name[NAME_FIELD_SIZE] = 0;
1152 blk = pax_start_header (file->stat_info);
1153 finish_header (file->stat_info, blk, block_ordinal);
1154 free (file->stat_info->file_name);
1155 file->stat_info->file_name = save_file_name;
1157 blk = find_next_block ();
1159 p = umaxtostr (file->stat_info->sparse_map_avail, nbuf);
1160 COPY_STRING (blk, q, p);
1161 COPY_STRING (blk, q, "\n");
1162 for (i = 0; i < file->stat_info->sparse_map_avail; i++)
1164 p = umaxtostr (map[i].offset, nbuf);
1165 COPY_STRING (blk, q, p);
1166 COPY_STRING (blk, q, "\n");
1167 p = umaxtostr (map[i].numbytes, nbuf);
1168 COPY_STRING (blk, q, p);
1169 COPY_STRING (blk, q, "\n");
1171 memset (q, 0, BLOCKSIZE - (q - blk->buffer));
1172 set_next_block_after (blk);
1177 pax_dump_header (struct tar_sparse_file *file)
1179 file->stat_info->sparse_major = tar_sparse_major;
1180 file->stat_info->sparse_minor = tar_sparse_minor;
1182 return (file->stat_info->sparse_major == 0) ?
1183 pax_dump_header_0 (file) : pax_dump_header_1 (file);
1187 decode_num (uintmax_t *num, char const *arg, uintmax_t maxval)
1192 if (!ISDIGIT (*arg))
1196 u = strtoumax (arg, &arg_lim, 10);
1198 if (! (u <= maxval && errno != ERANGE) || *arg_lim)
1206 pax_decode_header (struct tar_sparse_file *file)
1208 if (file->stat_info->sparse_major > 0)
1211 char nbuf[UINTMAX_STRSIZE_BOUND];
1216 #define COPY_BUF(b,buf,src) do \
1218 char *endp = b->buffer + BLOCKSIZE; \
1222 if (dst == buf + UINTMAX_STRSIZE_BOUND -1) \
1224 ERROR ((0, 0, _("%s: numeric overflow in sparse archive member"), \
1225 file->stat_info->orig_file_name)); \
1230 set_next_block_after (b); \
1231 file->dumped_size += BLOCKSIZE; \
1232 b = find_next_block (); \
1234 endp = b->buffer + BLOCKSIZE; \
1238 while (*dst++ != '\n'); \
1242 set_next_block_after (current_header);
1243 file->dumped_size += BLOCKSIZE;
1244 blk = find_next_block ();
1246 COPY_BUF (blk,nbuf,p);
1247 if (!decode_num (&u, nbuf, TYPE_MAXIMUM (size_t)))
1249 ERROR ((0, 0, _("%s: malformed sparse archive member"),
1250 file->stat_info->orig_file_name));
1253 file->stat_info->sparse_map_size = u;
1254 file->stat_info->sparse_map = xcalloc (file->stat_info->sparse_map_size,
1255 sizeof (*file->stat_info->sparse_map));
1256 file->stat_info->sparse_map_avail = 0;
1257 for (i = 0; i < file->stat_info->sparse_map_size; i++)
1261 COPY_BUF (blk,nbuf,p);
1262 if (!decode_num (&u, nbuf, TYPE_MAXIMUM (off_t)))
1264 ERROR ((0, 0, _("%s: malformed sparse archive member"),
1265 file->stat_info->orig_file_name));
1269 COPY_BUF (blk,nbuf,p);
1270 if (!decode_num (&u, nbuf, TYPE_MAXIMUM (off_t)))
1272 ERROR ((0, 0, _("%s: malformed sparse archive member"),
1273 file->stat_info->orig_file_name));
1277 sparse_add_map (file->stat_info, &sp);
1279 set_next_block_after (blk);
1285 static struct tar_sparse_optab const pax_optab = {
1286 NULL, /* No init function */
1287 NULL, /* No done function */
1288 pax_sparse_member_p,
1292 NULL, /* No scan_block function */
1294 sparse_extract_region,