tar: avoid need for base64_init and extra table.
[midnight-commander.git] / src / vfs / tar / tar-xheader.c
blob766124a7709b84b7d2665fcb1823458deddcaec6
1 /*
2 Virtual File System: GNU Tar file system.
4 Copyright (C) 1995-2024
5 Free Software Foundation, Inc.
7 Written by:
8 Andrew Borodin <aborodin@vmail.ru>, 2023
10 This file is part of the Midnight Commander.
12 The Midnight Commander is free software: you can redistribute it
13 and/or modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation, either version 3 of the License,
15 or (at your option) any later version.
17 The Midnight Commander is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 /**
27 * \file
28 * \brief Source: Virtual File System: GNU Tar file system
31 #include <config.h>
33 #include <ctype.h> /* isdigit() */
34 #include <stdlib.h>
35 #include <string.h>
37 #include "lib/global.h"
38 #include "lib/util.h" /* MC_PTR_FREE */
40 #include "tar-internal.h"
42 /*** global variables ****************************************************************************/
44 /*** file scope macro definitions ****************************************************************/
46 #define XHDR_PROTECTED 0x01
47 #define XHDR_GLOBAL 0x02
49 /*** file scope type declarations ****************************************************************/
51 /* General Interface */
53 /* Since tar VFS is read-only, inplement decodes only */
54 /* *INDENT-OFF* */
55 struct xhdr_tab
57 const char *keyword;
58 gboolean (*decoder) (struct tar_stat_info * st, const char *keyword, const char *arg, size_t size);
59 int flags;
61 /* *INDENT-ON* */
63 /* Keyword options */
64 struct keyword_item
66 char *pattern;
67 char *value;
70 enum decode_record_status
72 decode_record_ok,
73 decode_record_finish,
74 decode_record_fail
77 /*** forward declarations (file scope functions) *************************************************/
79 static gboolean dummy_decoder (struct tar_stat_info *st, const char *keyword, const char *arg,
80 size_t size);
81 static gboolean atime_decoder (struct tar_stat_info *st, const char *keyword, const char *arg,
82 size_t size);
83 static gboolean gid_decoder (struct tar_stat_info *st, const char *keyword, const char *arg,
84 size_t size);
85 #if 0
86 static gboolean gname_decoder (struct tar_stat_info *st, const char *keyword, const char *arg,
87 size_t size);
88 #endif
89 static gboolean linkpath_decoder (struct tar_stat_info *st, const char *keyword, const char *arg,
90 size_t size);
91 static gboolean mtime_decoder (struct tar_stat_info *st, const char *keyword, const char *arg,
92 size_t size);
93 static gboolean ctime_decoder (struct tar_stat_info *st, const char *keyword, const char *arg,
94 size_t size);
95 static gboolean path_decoder (struct tar_stat_info *st, const char *keyword, const char *arg,
96 size_t size);
97 static gboolean size_decoder (struct tar_stat_info *st, const char *keyword, const char *arg,
98 size_t size);
99 static gboolean uid_decoder (struct tar_stat_info *st, const char *keyword, const char *arg,
100 size_t size);
101 #if 0
102 static gboolean uname_decoder (struct tar_stat_info *st, const char *keyword, const char *arg,
103 size_t size);
104 #endif
105 static gboolean sparse_path_decoder (struct tar_stat_info *st, const char *keyword, const char *arg,
106 size_t size);
107 static gboolean sparse_major_decoder (struct tar_stat_info *st, const char *keyword,
108 const char *arg, size_t size);
109 static gboolean sparse_minor_decoder (struct tar_stat_info *st, const char *keyword,
110 const char *arg, size_t size);
111 static gboolean sparse_size_decoder (struct tar_stat_info *st, const char *keyword, const char *arg,
112 size_t size);
113 static gboolean sparse_numblocks_decoder (struct tar_stat_info *st, const char *keyword,
114 const char *arg, size_t size);
115 static gboolean sparse_offset_decoder (struct tar_stat_info *st, const char *keyword,
116 const char *arg, size_t size);
117 static gboolean sparse_numbytes_decoder (struct tar_stat_info *st, const char *keyword,
118 const char *arg, size_t size);
119 static gboolean sparse_map_decoder (struct tar_stat_info *st, const char *keyword, const char *arg,
120 size_t size);
121 static gboolean dumpdir_decoder (struct tar_stat_info *st, const char *keyword, const char *arg,
122 size_t size);
124 /*** file scope variables ************************************************************************/
126 enum
128 BILLION = 1000000000,
129 LOG10_BILLION = 9
132 /* *INDENT-OFF* */
133 static struct xhdr_tab xhdr_tab[] =
135 { "atime", atime_decoder, 0 },
136 { "comment", dummy_decoder, 0 },
137 { "charset", dummy_decoder, 0 },
138 { "ctime", ctime_decoder, 0 },
139 { "gid", gid_decoder, 0 },
140 #if 0
141 { "gname", gname_decoder, 0 },
142 #endif
143 { "linkpath", linkpath_decoder, 0 },
144 { "mtime", mtime_decoder, 0 },
145 { "path", path_decoder, 0 },
146 { "size", size_decoder, 0 },
147 { "uid", uid_decoder, 0 },
148 #if 0
149 { "uname", uname_decoder, 0 },
150 #endif
152 /* Sparse file handling */
153 { "GNU.sparse.name", sparse_path_decoder, XHDR_PROTECTED },
154 { "GNU.sparse.major", sparse_major_decoder, XHDR_PROTECTED },
155 { "GNU.sparse.minor", sparse_minor_decoder, XHDR_PROTECTED },
156 { "GNU.sparse.realsize", sparse_size_decoder, XHDR_PROTECTED },
157 { "GNU.sparse.numblocks", sparse_numblocks_decoder, XHDR_PROTECTED },
159 { "GNU.sparse.size", sparse_size_decoder, XHDR_PROTECTED },
160 /* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x'
161 headers, and each of them was meaningful. It confilcted with POSIX specs,
162 which requires that "when extended header records conflict, the last one
163 given in the header shall take precedence." */
164 { "GNU.sparse.offset", sparse_offset_decoder, XHDR_PROTECTED },
165 { "GNU.sparse.numbytes", sparse_numbytes_decoder, XHDR_PROTECTED },
166 /* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */
167 { "GNU.sparse.map", sparse_map_decoder, 0 },
169 { "GNU.dumpdir", dumpdir_decoder, XHDR_PROTECTED },
171 { NULL, NULL, 0 }
173 /* *INDENT-ON* */
175 /* List of keyword/value pairs decoded from the last 'g' type header */
176 static GSList *global_header_override_list = NULL;
178 /* --------------------------------------------------------------------------------------------- */
179 /*** file scope functions ************************************************************************/
180 /* --------------------------------------------------------------------------------------------- */
182 static struct xhdr_tab *
183 locate_handler (const char *keyword)
185 struct xhdr_tab *p;
187 for (p = xhdr_tab; p->keyword != NULL; p++)
188 if (strcmp (p->keyword, keyword) == 0)
189 return p;
191 return NULL;
194 /* --------------------------------------------------------------------------------------------- */
196 static gboolean
197 keyword_item_run (gpointer data, gpointer user_data)
199 struct keyword_item *kp = (struct keyword_item *) data;
200 struct tar_stat_info *st = (struct tar_stat_info *) user_data;
201 struct xhdr_tab const *t;
203 t = locate_handler (kp->pattern);
204 if (t != NULL)
205 return t->decoder (st, t->keyword, kp->value, strlen (kp->value));
207 return TRUE; /* FIXME */
210 /* --------------------------------------------------------------------------------------------- */
212 static void
213 keyword_item_free (gpointer data)
215 struct keyword_item *kp = (struct keyword_item *) data;
217 g_free (kp->pattern);
218 g_free (kp->value);
219 g_free (kp);
222 /* --------------------------------------------------------------------------------------------- */
224 static void
225 xheader_list_append (GSList **root, const char *kw, const char *value)
227 struct keyword_item *kp;
229 kp = g_new (struct keyword_item, 1);
230 kp->pattern = g_strdup (kw);
231 kp->value = g_strdup (value);
232 *root = g_slist_prepend (*root, kp);
235 /* --------------------------------------------------------------------------------------------- */
237 static inline void
238 xheader_list_destroy (GSList **root)
240 g_slist_free_full (*root, keyword_item_free);
241 *root = NULL;
244 /* --------------------------------------------------------------------------------------------- */
246 static inline void
247 run_override_list (GSList *kp, struct tar_stat_info *st)
249 g_slist_foreach (kp, (GFunc) keyword_item_run, st);
252 /* --------------------------------------------------------------------------------------------- */
254 static struct timespec
255 decode_timespec (const char *arg, char **arg_lim, gboolean parse_fraction)
257 int ns = -1;
258 gboolean overflow;
259 time_t s;
260 char const *p = *arg_lim;
261 struct timespec r;
263 s = stoint (arg, arg_lim, &overflow, TYPE_MINIMUM (time_t), TYPE_MAXIMUM (time_t));
265 if (p != arg)
267 ns = 0;
269 if (parse_fraction && *p == '.')
271 int digits = 0;
272 gboolean trailing_nonzero = FALSE;
274 while (isdigit (*++p))
275 if (digits < LOG10_BILLION)
277 digits++;
278 ns = 10 * ns + (*p - '0');
280 else if (*p != '0')
281 trailing_nonzero = TRUE;
283 *arg_lim = (char *) p;
285 while (digits < LOG10_BILLION)
287 digits++;
288 ns *= 10;
291 if (*arg == '-')
293 /* Convert "-1.10000000000001" to s == -2, ns == 89999999.
294 I.e., truncate time stamps towards minus infinity while
295 converting them to internal form. */
296 if (trailing_nonzero)
297 ns++;
298 if (ns != 0)
299 ns = ckd_sub (&s, s, 1) ? -1 : BILLION - ns;
303 if (overflow)
304 ns = -1;
307 r.tv_sec = s;
308 r.tv_nsec = ns;
309 return r;
312 /* --------------------------------------------------------------------------------------------- */
314 static gboolean
315 decode_time (struct timespec *ts, const char *arg, const char *keyword)
317 char *arg_lim;
318 struct timespec t;
320 (void) keyword;
322 t = decode_timespec (arg, &arg_lim, TRUE);
324 if (t.tv_nsec < 0)
325 /* Malformed extended header */
326 return FALSE;
328 if (*arg_lim != '\0')
329 /* Malformed extended header */
330 return FALSE;
332 *ts = t;
334 return TRUE;
337 /* --------------------------------------------------------------------------------------------- */
339 static gboolean
340 decode_signed_num (intmax_t *num, const char *arg, intmax_t minval, uintmax_t maxval,
341 const char *keyword)
343 char *arg_lim;
344 gboolean overflow;
345 intmax_t u;
347 (void) keyword;
349 u = stoint (arg, &arg_lim, &overflow, minval, maxval);
351 if (arg_lim == arg || *arg_lim != '\0')
352 return FALSE; /* malformed extended header */
354 if (overflow)
355 return FALSE; /* out of range */
357 *num = u;
358 return TRUE;
361 /* --------------------------------------------------------------------------------------------- */
363 static gboolean
364 decode_num (uintmax_t *num, const char *arg, uintmax_t maxval, const char *keyword)
366 intmax_t i;
368 if (!decode_signed_num (&i, arg, 0, maxval, keyword))
369 return FALSE;
371 *num = i;
372 return TRUE;
375 /* --------------------------------------------------------------------------------------------- */
377 static gboolean
378 raw_path_decoder (struct tar_stat_info *st, const char *arg)
380 if (*arg != '\0')
382 tar_assign_string_dup (&st->orig_file_name, arg);
383 tar_assign_string_dup (&st->file_name, arg);
386 return TRUE;
389 /* --------------------------------------------------------------------------------------------- */
391 static gboolean
392 dummy_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
394 (void) st;
395 (void) keyword;
396 (void) arg;
397 (void) size;
399 return TRUE;
402 /* --------------------------------------------------------------------------------------------- */
404 static gboolean
405 atime_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
407 struct timespec ts;
409 (void) size;
411 if (!decode_time (&ts, arg, keyword))
412 return FALSE;
414 st->atime = ts;
415 return TRUE;
418 /* --------------------------------------------------------------------------------------------- */
420 static gboolean
421 gid_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
423 intmax_t u;
425 (void) size;
427 if (!decode_signed_num (&u, arg, TYPE_MINIMUM (gid_t), TYPE_MINIMUM (gid_t), keyword))
428 return FALSE;
430 st->stat.st_gid = u;
431 return TRUE;
434 /* --------------------------------------------------------------------------------------------- */
436 #if 0
437 static gboolean
438 gname_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
440 (void) keyword;
441 (void) size;
443 tar_assign_string_dup (&st->gname, arg);
444 return TRUE;
446 #endif
448 /* --------------------------------------------------------------------------------------------- */
450 static gboolean
451 linkpath_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
453 (void) keyword;
454 (void) size;
456 tar_assign_string_dup (&st->link_name, arg);
457 return TRUE;
460 /* --------------------------------------------------------------------------------------------- */
462 static gboolean
463 ctime_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
465 struct timespec ts;
467 (void) size;
469 if (!decode_time (&ts, arg, keyword))
470 return FALSE;
472 st->ctime = ts;
473 return TRUE;
476 /* --------------------------------------------------------------------------------------------- */
478 static gboolean
479 mtime_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
481 struct timespec ts;
483 (void) size;
485 if (!decode_time (&ts, arg, keyword))
486 return FALSE;
488 st->mtime = ts;
489 return TRUE;
492 /* --------------------------------------------------------------------------------------------- */
494 static gboolean
495 path_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
497 (void) keyword;
498 (void) size;
500 if (!st->sparse_name_done)
501 return raw_path_decoder (st, arg);
503 return TRUE; /* FIXME */
506 /* --------------------------------------------------------------------------------------------- */
508 static gboolean
509 size_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
511 uintmax_t u;
513 (void) size;
515 if (!decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
516 return FALSE;
518 st->stat.st_size = u;
519 return TRUE;
522 /* --------------------------------------------------------------------------------------------- */
524 static gboolean
525 uid_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
527 intmax_t u;
529 (void) size;
531 if (!decode_signed_num (&u, arg, TYPE_MINIMUM (uid_t), TYPE_MAXIMUM (uid_t), keyword))
532 return FALSE;
534 st->stat.st_uid = u;
535 return TRUE;
538 /* --------------------------------------------------------------------------------------------- */
540 #if 0
541 static gboolean
542 uname_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
544 (void) keyword;
545 (void) size;
547 tar_assign_string_dup (&st->uname, arg);
548 return TRUE;
550 #endif
552 /* --------------------------------------------------------------------------------------------- */
554 static gboolean
555 dumpdir_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
557 (void) keyword;
559 #if GLIB_CHECK_VERSION (2, 68, 0)
560 st->dumpdir = g_memdup2 (arg, size);
561 #else
562 st->dumpdir = g_memdup (arg, size);
563 #endif
564 return TRUE;
567 /* --------------------------------------------------------------------------------------------- */
570 * Decodes a single extended header record, advancing @ptr to the next record.
572 * @param p pointer to extended header record
573 * @param st stat info
575 * @return decode_record_ok or decode_record_finish on success, decode_record_fail otherwize
577 static enum decode_record_status
578 decode_record (struct xheader *xhdr, char **ptr,
579 gboolean (*handler) (void *data, const char *keyword, const char *value,
580 size_t size), void *data)
582 char *start = *ptr;
583 char *p = start;
584 idx_t len;
585 char *len_lim;
586 const char *keyword;
587 char *nextp;
588 idx_t len_max;
589 gboolean ret;
591 len_max = xhdr->buffer + xhdr->size - start;
593 while (*p == ' ' || *p == '\t')
594 p++;
596 len = stoint (p, &len_lim, NULL, 0, IDX_MAX);
598 if (len_lim == p)
599 /* Is the length missing? */
600 return (*p != '\0' ? decode_record_fail : decode_record_finish);
602 if (len_max < len)
603 return decode_record_fail;
605 nextp = start + len;
607 for (p = len_lim; *p == ' ' || *p == '\t'; p++)
610 if (p == len_lim)
611 return decode_record_fail;
613 keyword = p;
614 p = strchr (p, '=');
615 if (!(p != NULL && p < nextp))
616 return decode_record_fail;
618 if (nextp[-1] != '\n')
619 return decode_record_fail;
621 *p = nextp[-1] = '\0';
622 ret = handler (data, keyword, p + 1, nextp - p - 2); /* '=' + trailing '\n' */
623 *p = '=';
624 nextp[-1] = '\n';
625 *ptr = nextp;
627 return (ret ? decode_record_ok : decode_record_fail);
630 /* --------------------------------------------------------------------------------------------- */
632 static gboolean
633 decg (void *data, const char *keyword, const char *value, size_t size)
635 GSList **kwl = (GSList **) data;
636 struct xhdr_tab const *tab;
638 (void) size;
640 tab = locate_handler (keyword);
641 if (tab != NULL && (tab->flags & XHDR_GLOBAL) != 0)
643 if (!tab->decoder (data, keyword, value, size))
644 return FALSE;
646 else
647 xheader_list_append (kwl, keyword, value);
649 return TRUE;
652 /* --------------------------------------------------------------------------------------------- */
654 static gboolean
655 decx (void *data, const char *keyword, const char *value, size_t size)
657 struct keyword_item kp = {
658 .pattern = (char *) keyword,
659 .value = (char *) value
662 (void) size;
664 return keyword_item_run (&kp, data);
667 /* --------------------------------------------------------------------------------------------- */
669 static gboolean
670 sparse_path_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
672 (void) keyword;
673 (void) size;
675 st->sparse_name_done = TRUE;
676 return raw_path_decoder (st, arg);
679 /* --------------------------------------------------------------------------------------------- */
681 static gboolean
682 sparse_major_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
684 uintmax_t u;
686 (void) size;
688 if (!decode_num (&u, arg, INTMAX_MAX, keyword))
689 return FALSE;
691 st->sparse_major = u;
692 return TRUE;
695 /* --------------------------------------------------------------------------------------------- */
697 static gboolean
698 sparse_minor_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
700 uintmax_t u;
702 (void) size;
704 if (!decode_num (&u, arg, INTMAX_MAX, keyword))
705 return FALSE;
707 st->sparse_minor = u;
708 return TRUE;
711 /* --------------------------------------------------------------------------------------------- */
713 static gboolean
714 sparse_size_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
716 uintmax_t u;
718 (void) size;
720 if (!decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
721 return FALSE;
723 st->real_size_set = TRUE;
724 st->real_size = u;
725 return TRUE;
728 /* --------------------------------------------------------------------------------------------- */
730 static gboolean
731 sparse_numblocks_decoder (struct tar_stat_info *st, const char *keyword, const char *arg,
732 size_t size)
734 uintmax_t u;
736 (void) size;
738 if (!decode_num (&u, arg, SIZE_MAX, keyword))
739 return FALSE;
741 if (st->sparse_map == NULL)
742 st->sparse_map = g_array_sized_new (FALSE, FALSE, sizeof (struct sp_array), u);
743 else
744 g_array_set_size (st->sparse_map, u);
746 return TRUE;
749 /* --------------------------------------------------------------------------------------------- */
751 static gboolean
752 sparse_offset_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
754 uintmax_t u;
755 struct sp_array *s;
757 (void) size;
759 if (!decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
760 return FALSE;
762 s = &g_array_index (st->sparse_map, struct sp_array, st->sparse_map->len - 1);
763 s->offset = u;
764 return TRUE;
767 /* --------------------------------------------------------------------------------------------- */
769 static gboolean
770 sparse_numbytes_decoder (struct tar_stat_info *st, const char *keyword, const char *arg,
771 size_t size)
773 uintmax_t u;
774 struct sp_array s;
776 (void) size;
778 if (!decode_num (&u, arg, SIZE_MAX, keyword))
779 return FALSE;
781 s.offset = 0;
782 s.numbytes = u;
783 g_array_append_val (st->sparse_map, s);
784 return TRUE;
787 /* --------------------------------------------------------------------------------------------- */
789 static gboolean
790 sparse_map_decoder (struct tar_stat_info *st, const char *keyword, const char *arg, size_t size)
792 gboolean offset = TRUE;
793 struct sp_array e;
795 (void) keyword;
796 (void) size;
798 if (st->sparse_map != NULL)
799 g_array_set_size (st->sparse_map, 0);
801 while (TRUE)
803 off_t u;
804 char *delim;
805 gboolean overflow;
807 u = stoint (arg, &delim, &overflow, 0, TYPE_MAXIMUM (off_t));
809 if (delim == arg)
811 /* malformed extended header */
812 return FALSE;
815 if (offset)
817 e.offset = u;
818 if (overflow)
820 /* out of range */
821 return FALSE;
824 else
826 e.numbytes = u;
827 if (overflow)
829 /* out of range */
830 return FALSE;
833 g_array_append_val (st->sparse_map, e);
836 offset = !offset;
838 if (*delim == '\0')
839 break;
840 if (*delim != ',')
842 /* malformed extended header */
843 return FALSE;
846 arg = delim + 1;
849 if (!offset)
851 /* malformed extended header */
852 return FALSE;
855 return TRUE;
858 /* --------------------------------------------------------------------------------------------- */
859 /*** public functions ****************************************************************************/
860 /* --------------------------------------------------------------------------------------------- */
863 * Decodes an extended header.
865 * @param st stat info
867 * @return TRUE on success, FALSE otherwize
869 gboolean
870 tar_xheader_decode (struct tar_stat_info *st)
872 char *p;
873 enum decode_record_status status;
875 run_override_list (global_header_override_list, st);
877 p = st->xhdr.buffer + BLOCKSIZE;
879 while ((status = decode_record (&st->xhdr, &p, decx, st)) == decode_record_ok)
882 if (status == decode_record_fail)
883 return FALSE;
885 /* The archived (effective) file size is always set directly in tar header
886 field, possibly overridden by "size" extended header - in both cases,
887 result is now decoded in st->stat.st_size */
888 st->archive_file_size = st->stat.st_size;
890 /* The real file size (given by stat()) may be redefined for sparse
891 files in "GNU.sparse.realsize" extended header */
892 if (st->real_size_set)
893 st->stat.st_size = st->real_size;
895 return TRUE;
898 /* --------------------------------------------------------------------------------------------- */
900 gboolean
901 tar_xheader_read (tar_super_t *archive, struct xheader *xhdr, union block *p, off_t size)
903 size_t j = 0;
904 size_t size_plus_1;
906 size = MAX (0, size);
907 if (ckd_add (&size_plus_1, size, BLOCKSIZE + 1))
908 return FALSE;
909 size = size_plus_1 - 1;
910 xhdr->size = size;
911 xhdr->buffer = g_malloc (size_plus_1);
912 xhdr->buffer[size] = '\0';
916 size_t len;
918 if (p == NULL)
919 return FALSE; /* Unexpected EOF in archive */
921 len = MIN (size, BLOCKSIZE);
923 memcpy (xhdr->buffer + j, p->buffer, len);
924 tar_set_next_block_after (p);
925 p = tar_find_next_block (archive);
927 j += len;
928 size -= len;
930 while (size > 0);
932 return TRUE;
935 /* --------------------------------------------------------------------------------------------- */
937 gboolean
938 tar_xheader_decode_global (struct xheader *xhdr)
940 char *p;
941 gboolean ret;
943 p = xhdr->buffer + BLOCKSIZE;
945 xheader_list_destroy (&global_header_override_list);
947 while ((ret = decode_record (xhdr, &p, decg, &global_header_override_list)) == decode_record_ok)
950 return (ret == decode_record_finish);
953 /* --------------------------------------------------------------------------------------------- */
955 void
956 tar_xheader_destroy (struct xheader *xhdr)
958 MC_PTR_FREE (xhdr->buffer);
959 xhdr->size = 0;
962 /* --------------------------------------------------------------------------------------------- */