Parolin 0.7.9 6796
Console (soon DLLs) to do a tar like job
Loading...
Searching...
No Matches
sparse_2_k.c
Go to the documentation of this file.
1//dureza...
2
3#ifdef _M_X64
4#define Print_Long_ARP "ll"
5#else
6#define Print_Long_ARP "I64"
7#endif
8
9#include "obstack.h"
10#include "verify.h"
11
12#ifndef S_ISCTG
13#ifdef S_IFCTG
14#define S_ISCTG(mode) (((mode)&S_IFMT) == S_IFCTG)
15#else
16#define S_ISCTG(mode) 0
17#endif
18#endif
19
20#define CHKBLANKS " "
21
22#define UNAME_FIELD_SIZE 32
23#define GNAME_FIELD_SIZE 32
24
25#define NAME_FIELD_SIZE 100
26#define PREFIX_FIELD_SIZE 155
27
28#define GLOBAL_HEADER_TEMPLATE "/GlobalHead.%p.%n"
29
30#ifndef MAX
31#define MAX(a, b) ((a) > (b) ? (a) : (b))
32#endif
33
34#define DEFAULT_ALIGNMENT MAX(__alignof__(long double), \
35 MAX(__alignof__(uintmax_t), \
36 __alignof__(void *)))
37#define DEFAULT_ROUNDING MAX(sizeof(long double), \
38 MAX(sizeof(uintmax_t), \
39 sizeof(void *)))
40static struct fmttab
41{
42 char const *name;
43 enum archive_format fmt;
44} const fmttab[] = {
45 {"v7", V7_FORMAT},
46 {"oldgnu", OLDGNU_FORMAT},
47 {"ustar", USTAR_FORMAT},
48 {"posix", POSIX_FORMAT},
49#if 0 /* not fully supported yet */
50 { "star", STAR_FORMAT },
51#endif
52 {"gnu", GNU_FORMAT},
53 {"pax", POSIX_FORMAT}, /* An alias for posix */
54 {NULL, 0}};
55
56enum
57{
58 TIMESPEC_HZ = 1000000000
59};
66
67static time_t exthdr_mtime;
68static char *exthdr_mtime_option /*arp*/;
69static char *globexthdr_mtime_option;
70static time_t globexthdr_mtime;
71
72/* Number of global headers written so far. */
73static size_t global_header_count;
74
75/* Template for the name field of a 'g' type header */
76static char *globexthdr_name;
77/* Override actual mtime if set to FORCE_MTIME or CLAMP_MTIME */
79
80/* If positive, save the user and root xattrs. */
82
83/* If positive, save the SELinux context. */
85
86/* If positive, save the ACLs. */
88
89/* Special operations flags. */
90enum
91{
92 /* For the sentinel at the end of the mode changes array. */
94
95 /* The typical case. */
97
98 /* In addition to the typical case, affect the execute bits if at
99 least one execute bit is set already, or if the file is a
100 directory. */
102
103 /* Instead of the typical case, copy some existing permissions for
104 u, g, or o onto the other two. Which of u, g, or o is copied
105 is determined by which bits are set in the 'value' field. */
108
109#define FILE_SYSTEM_PREFIX_LEN(P) 0
110#define ISSLASH(C) ((C) == '/')
111/*
112 #define uid_t int
113 #define gid_t int
114 */
115
116typedef int gid_t;
117typedef int uid_t;
118
119static bool
120mode_to_chars(mode_t v, char *p, size_t s);
121
122static bool
123uid_to_chars(int v, char *p, size_t s);
124
125static bool
126gid_to_chars(int v, char *p, size_t s);
127
128bool off_to_chars(off_t v, char *p, size_t s);
129
130bool time_to_chars(time_t v, char *p, size_t s);
131
132static bool
133major_to_chars(major_t v, char *p, size_t s);
134
135static bool
136minor_to_chars(minor_t v, char *p, size_t s);
137
138static void
139string_to_chars(char const *str, char *p, size_t s);
140
141#define UNAME_TO_CHARS(name, buf) string_to_chars(name, buf, sizeof(buf))
142#define GNAME_TO_CHARS(name, buf) string_to_chars(name, buf, sizeof(buf))
143#define MINOR_TO_CHARS(val, where) minor_to_chars(val, where, sizeof(where))
144#define MAJOR_TO_CHARS(val, where) major_to_chars(val, where, sizeof(where))
145#define MODE_TO_CHARS(val, where) mode_to_chars(val, where, sizeof(where))
146#define UID_TO_CHARS(val, where) uid_to_chars(val, where, sizeof(where))
147#define GID_TO_CHARS(val, where) gid_to_chars(val, where, sizeof(where))
148#define S_ISUID 04000
149#define S_ISGID 02000
150#define S_ISVTX 01000
151#define S_IRGRP (S_IRUSR >> 3)
152#define S_IWGRP (S_IWUSR >> 3)
153#define S_IXGRP (S_IXUSR >> 3)
154#if 0
155#define S_IROTH (S_IRUSR >> 6)
156#define S_IWOTH (S_IWUSR >> 6)
157#define S_IXOTH (S_IXUSR >> 6)
158#endif
159#define MODE_WXUSR (S_IWUSR | S_IXUSR)
160#define MODE_R (S_IRUSR | S_IRGRP | S_IROTH)
161#define MODE_RW (S_IWUSR | S_IWGRP | S_IWOTH | MODE_R)
162#define MODE_RWX (S_IXUSR | S_IXGRP | S_IXOTH | MODE_RW)
163#define MODE_ALL (S_ISUID | S_ISGID | S_ISVTX | MODE_RWX)
164#if 0
165#define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)
166#define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)
167#endif
168#define CHMOD_MODE_BITS \
169 (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
170
171#define STRINGIFY_BIGINT(i, b) umaxtostr(i, b)
172
173#define LG_8 3
174#define LG_64 6
175#define LG_256 8
176
177/* The maximum uintmax_t value that can be represented with DIGITS digits,
178 assuming that each digit is BITS_PER_DIGIT wide. */
179#define MAX_VAL_WITH_DIGITS(digits, bits_per_digit) \
180 ((digits) * (bits_per_digit) < sizeof(uintmax_t) * CHAR_BIT \
181 ? ((uintmax_t)1 << ((digits) * (bits_per_digit))) - 1 \
182 : (uintmax_t)-1)
183
184/* The maximum uintmax_t value that can be represented with octal
185 digits and a trailing NUL in BUFFER. */
186#define MAX_OCTAL_VAL(buffer) MAX_VAL_WITH_DIGITS(sizeof(buffer) - 1, LG_8)
187
188#define OFF_TO_CHARS(val, where) off_to_chars(val, where, sizeof(where))
189#define TIME_TO_CHARS(val, where) time_to_chars(val, where, sizeof(where))
190
191/* The maximum uintmax_t value that can be represented with DIGITS digits,
192 assuming that each digit is BITS_PER_DIGIT wide. */
193#define MAX_VAL_WITH_DIGITS(digits, bits_per_digit) \
194 ((digits) * (bits_per_digit) < sizeof(uintmax_t) * CHAR_BIT \
195 ? ((uintmax_t)1 << ((digits) * (bits_per_digit))) - 1 \
196 : (uintmax_t)-1)
197
204typedef size_t (*Hash_hasher)(const void *, size_t);
205typedef bool (*Hash_comparator)(const void *, const void *);
206typedef void (*Hash_data_freer)(void *);
207typedef bool (*Hash_processor)(void *, void *);
208
210
211struct hash_table;
212
213typedef struct hash_table Hash_table;
214
216{
217 void *data;
219};
220
222{
223 /* The array of buckets starts at BUCKET and extends to BUCKET_LIMIT-1,
224 for a possibility of N_BUCKETS. Among those, N_BUCKETS_USED buckets
225 are not empty, there are N_ENTRIES active entries in the table. */
228 size_t n_buckets;
230 size_t n_entries;
231
232 /* Tuning arguments, kept in a physically separate structure. */
234
235 /* Three functions are given to 'hash_initialize', see the documentation
236 block for this function. In a word, HASHER randomizes a user entry
237 into a number up from 0 up to some maximum minus 1; COMPARATOR returns
238 true if two user entries compare equally; and DATA_FREER is the cleanup
239 function for a user entry. */
243
244 /* A linked list of freed struct hash_entry structs. */
246
247#if USE_OBSTACK
248 /* Whenever obstacks are used, it is possible to allocate all overflowed
249 entries into a single stack, so they all can be freed in a single
250 operation. It is not clear if the speedup is worth the trouble. */
251 struct obstack entry_stack;
252#endif
253};
254
256{
257 /* This structure is mainly used for 'hash_initialize', see the block
258 documentation of 'hash_reset_tuning' for more complete comments. */
259
260 float shrink_threshold; /* ratio of used buckets to trigger a shrink */
261 float shrink_factor; /* ratio of new smaller size to original size */
262 float growth_threshold; /* ratio of used buckets to trigger a growth */
263 float growth_factor; /* ratio of new bigger size to original size */
264 bool is_n_buckets; /* if CANDIDATE really means table size */
265};
266
267/* If an insertion makes the ratio of nonempty buckets to table size larger
268 than the growth threshold (a number between 0.0 and 1.0), then increase
269 the table size by multiplying by the growth factor (a number greater than
270 1.0). The growth threshold defaults to 0.8, and the growth factor
271 defaults to 1.414, meaning that the table will have doubled its size
272 every second time 80% of the buckets get used. */
273#define DEFAULT_GROWTH_THRESHOLD 0.8f
274#define DEFAULT_GROWTH_FACTOR 1.414f
275
276/* If a deletion empties a bucket and causes the ratio of used buckets to
277 table size to become smaller than the shrink threshold (a number between
278 0.0 and 1.0), then shrink the table by multiplying by the shrink factor (a
279 number greater than the shrink threshold but smaller than 1.0). The shrink
280 threshold and factor default to 0.0 and 1.0, meaning that the table never
281 shrinks. */
282#define DEFAULT_SHRINK_THRESHOLD 0.0f
283#define DEFAULT_SHRINK_FACTOR 1.0f
284
285/* Use this to initialize or reset a TUNING structure to
286 some sensible values. */
287
288static const Hash_tuning default_tuning =
289 {
294 false};
295
296static Hash_table *prefix_table[2];
297
298static Hash_table *owner_map;
299
301{
302 uintmax_t orig_id;
303 uintmax_t new_id;
304 char *new_name;
305};
306
307static Hash_table *group_map;
308
309/* Description of a mode change. */
311{
312 char op; /* One of "=+-". */
313 char flag; /* Special operations flag. */
314 mode_t affected; /* Set for u, g, o, or a. */
315 mode_t value; /* Bits to add/remove. */
316 mode_t mentioned; /* Bits explicitly mentioned. */
317};
318
320
321GLOBAL struct timespec mtime_option;
322
324{
325 int fd; /* File descriptor */
326 bool seekable; /* Is fd seekable? */
327 off_t offset; /* Current offset in fd if seekable==false.
328 Otherwise unused */
329 off_t dumped_size; /* Number of bytes actually written
330 to the archive */
331 struct tar_stat_info *stat_info; /* Information about the file */
332 struct tar_sparse_optab const *optab; /* Operation table */
333 void *closure; /* Any additional data optab calls might
334 require */
335};
336
338
339static size_t
340split_long_name(const char *name, size_t length);
341
342static void
343oldgnu_store_sparse_info(struct tar_sparse_file *file, size_t *pindex,
344 struct sparse *sp, size_t sparse_size);
345union block *
346write_extended(bool global, struct tar_stat_info *st, union block *old_header);
347
349 union block *header, off_t block_ordinal);
350void _obstack_newchunk(struct obstack *h, _OBSTACK_SIZE_T length);
351
352static void *
353call_chunkfun(struct obstack *h, size_t size);
354
355static int
356_obstack_begin_worker(struct obstack *h,
358
359int _obstack_begin(struct obstack *h,
361 void *(*chunkfun)(size_t),
362 void (*freefun)(void *));
363
364;
365char *
366last_component(char const *name);
367
369
370void tar_name_copy_str(char *dst, const char *src, size_t len);
371
372union block *
373start_private_header(const char *name, size_t size, time_t t);
374
375void xheader_write(char type, char *name, time_t t, struct xheader *xhdr);
376
377char *
379static void
380code_string(char const *string, char const *keyword, struct xheader *xhdr);
381
382static struct keyword_list *keyword_global_override_list = {0};
383static struct keyword_list *keyword_pattern_list = {0};
384/* List of keyword/value pairs set by 'keyword:=value' option */
385static struct keyword_list *keyword_override_list = {0};
386
387void xheader_finish(struct xheader *xhdr);
388
389static void
390x_obstack_1grow(struct xheader *xhdr, char c);
391
392static void
393x_obstack_blank(struct xheader *xhdr, size_t length);
394
395static void
396x_obstack_grow(struct xheader *xhdr, const char *ptr, size_t length);
397
398void xheader_string_add(struct xheader *xhdr, char const *s);
399
400void xheader_string_begin(struct xheader *xhdr);
401
402void finish_header(struct tar_stat_info *st,
403 union block *header, off_t block_ordinal);
404
405void gid_to_gname(int gid, char **gname);
406
407void uid_to_uname(uid_t uid, char **uname);
408
409int timespec_cmp(struct timespec a, struct timespec b);
410
411mode_t
412mode_adjust(mode_t oldmode, bool dir, mode_t umask_value,
413 struct mode_change const *changes, mode_t *pmode_bits);
414
415void *
416hash_lookup(const Hash_table *table, const void *entry);
417
418int group_map_translate(gid_t gid, gid_t *new_gid, char const **new_name);
419
420int owner_map_translate(uid_t uid, uid_t *new_uid, char const **new_name);
421
422static union block *
423write_long_name(struct tar_stat_info *st);
424
425static union block *
427
428bool string_ascii_p(char const *p);
429
430static union block *
431write_header_name(struct tar_stat_info *st);
432
433union block *
434start_header(struct tar_stat_info *st);
435
436static union block *
437pax_start_header(struct tar_stat_info *st);
438
439char *
440stpcpy(char *dest, const char *src);
441
442static struct hash_entry *
443allocate_entry(Hash_table *table);
444
445static bool
446transfer_entries(Hash_table *dst, Hash_table *src, bool safe);
447
448bool hash_rehash(Hash_table *table, size_t candidate);
449
450static void
451free_entry(Hash_table *table, struct hash_entry *entry);
452
453static struct hash_entry *
454safe_hasher(const Hash_table *table, const void *key);
455
456static void *
457hash_find_entry(Hash_table *table, const void *entry,
458 struct hash_entry **bucket_head, bool delete);
459
460int hash_insert_if_absent(Hash_table *table, void const *entry,
461 void const **matched_ent);
462
463void *
464hash_insert(Hash_table *table, void const *entry);
465
466/* Compare two strings for equality. */
467static bool
468hash_string_compare(void const *name1, void const *name2);
469
470size_t
471hash_string(const char *string, size_t n_buckets);
472
473static size_t
474hash_string_hasher(void const *name, size_t n_buckets);
475
476static bool
477is_prime(size_t candidate);
478
479static size_t
480next_prime(size_t candidate);
481
482static size_t
483compute_bucket_size(size_t candidate, const Hash_tuning *tuning);
484
485static bool
486check_tuning(Hash_table *table);
487
488static bool
489raw_comparator(const void *a, const void *b);
490
491size_t
492rotr_sz(size_t x, int n);
493
494static size_t
495raw_hasher(const void *data, size_t n);
496
498hash_initialize(size_t candidate, const Hash_tuning *tuning,
499 Hash_hasher hasher, Hash_comparator comparator,
500 Hash_data_freer data_freer);
501static bool
502hash_string_insert_prefix(Hash_table **table, char const *string, size_t len,
503 const char **return_prefix);
504
505char *
506safer_name_suffix(char const *file_name, bool link_target,
507 bool absolute_names);
508
509char *
510mdir_name(char const *file);
511
512char *
513dir_name(char const *file);
514
515char *
516xheader_format_name(struct tar_stat_info *st, const char *fmt, size_t n);
517
518static bool
519xheader_keyword_override_p(const char *keyword);
520
523
524static void
525xheader_init(struct xheader *xhdr);
526
527void xheader_store(char const *keyword, struct tar_stat_info *st,
528 void const *data);
529
530bool xheader_keyword_deleted_p(const char *kw);
531
532static struct xhdr_tab const *
533locate_handler(char const *keyword);
534
539static uintmax_t
540strtoumax(char const *ptr, char **endptr, int base)
541{
542 return strtoul(ptr, endptr, base);
543}
544
549static intmax_t
550strtoimax(char const *ptr, char **endptr, int base)
551{
552 return strtol(ptr, endptr, base);
553}
554
555#define ISDIGIT(c) ((unsigned)(c) - '0' <= 9)
556
557#define xalloc_oversized(n, s) \
558 ((size_t)(PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX - 1) / (s) < (n))
559
560#define _GL_ADD_OVERFLOW(a, b, min, max) \
561 __builtin_add_overflow_p(a, b, (__typeof__((a) + (b)))0)
562
563#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \
564 op_result_overflow(a, b, \
565 _GL_INT_MINIMUM(_GL_INT_CONVERT(a, b)), \
566 _GL_INT_MAXIMUM(_GL_INT_CONVERT(a, b)))
567
568#define INT_ADD_OVERFLOW(a, b) \
569 _GL_BINARY_OP_OVERFLOW(a, b, _GL_ADD_OVERFLOW)
570
577
584
598
599static bool
600star_sparse_member_p(struct tar_sparse_file *file __attribute__((unused)));
601
602static bool
603star_fixup_header(struct tar_sparse_file *file);
604
605static bool
606star_get_sparse_info(struct tar_sparse_file *file);
607
608static bool
609sparse_extract_region(struct tar_sparse_file *file, size_t i);
610
611static struct tar_sparse_optab const star_optab = {
612 NULL, /* No init function */
613 NULL, /* No done function */
614 star_sparse_member_p,
615 NULL,
616 star_fixup_header,
617 star_get_sparse_info,
618 NULL, /* No scan_block function */
619 NULL, /* No dump region function */
620 sparse_extract_region,
621};
622
623static bool
624sparse_dump_region(struct tar_sparse_file *file, size_t i);
625
626/* Convert old GNU format sparse data to internal representation */
627static bool
628oldgnu_get_sparse_info(struct tar_sparse_file *file);
629
630static bool
631oldgnu_fixup_header(struct tar_sparse_file *file);
632
633static bool
634oldgnu_dump_header(struct tar_sparse_file *file);
635
636static bool
637oldgnu_sparse_member_p(struct tar_sparse_file *file __attribute__((unused)));
638
639static struct tar_sparse_optab const oldgnu_optab = {
640 NULL, /* No init function */
641 NULL, /* No done function */
642 oldgnu_sparse_member_p,
643 oldgnu_dump_header,
644 oldgnu_fixup_header,
645 oldgnu_get_sparse_info,
646 NULL, /* No scan_block function */
647 sparse_dump_region,
648 sparse_extract_region,
649};
650
651static bool
652pax_sparse_member_p(struct tar_sparse_file *file);
653
654static bool
655pax_dump_header(struct tar_sparse_file *file);
656
657static bool
658pax_decode_header(struct tar_sparse_file *file);
659
660static struct tar_sparse_optab const pax_optab = {
661 NULL, /* No init function */
662 NULL, /* No done function */
663 pax_sparse_member_p,
664 pax_dump_header,
665 NULL,
666 pax_decode_header,
667 NULL, /* No scan_block function */
668 sparse_dump_region,
669 sparse_extract_region,
670};
671
672enum dump_status
673sparse_extract_file(int fd, struct tar_stat_info *st, off_t *size);
674
675static bool
676tar_sparse_init(struct tar_sparse_file *file);
677
678static bool
679sparse_select_optab(struct tar_sparse_file *file);
680
681static bool
682tar_sparse_decode_header(struct tar_sparse_file *file);
683
684static bool
685tar_sparse_extract_region(struct tar_sparse_file *file, size_t i);
686
687static bool
688tar_sparse_done(struct tar_sparse_file *file);
689
690static bool
691to_chars(int negative, uintmax_t value, size_t valsize,
692 uintmax_t (*substitute)(int *),
693 char *where, size_t size, const char *type);
694
696
701const char *
703{
704 struct fmttab const *p;
705
706 for (p = fmttab; p->name; p++)
707 if (p->fmt == fmt)
708 return p->name;
709 return "unknown?";
710}
711
716static size_t
717split_long_name(const char *name, size_t length)
718{
719 size_t i;
720
721 if (length > PREFIX_FIELD_SIZE + 1)
722 length = PREFIX_FIELD_SIZE + 1;
723 else if (ISSLASH(name[length - 1]))
724 length--;
725 for (i = length - 1; i > 0; i--)
726 if (ISSLASH(name[i]))
727 break;
728 return i;
729}
730
735static void
736oldgnu_store_sparse_info(struct tar_sparse_file *file, size_t *pindex,
737 struct sparse *sp, size_t sparse_size)
738{
739 for (; *pindex < file->stat_info->sparse_map_avail && sparse_size > 0; sparse_size--, sp++, ++*pindex)
740 {
741 OFF_TO_CHARS(file->stat_info->sparse_map[*pindex].offset,
742 sp->offset);
743 OFF_TO_CHARS(file->stat_info->sparse_map[*pindex].numbytes,
744 sp->numbytes);
745 }
746}
747
753 union block *header, __attribute__((unused)) off_t block_ordinal)
754{
755 /* Note: It is important to do this before the call to write_extended(),
756 so that the actual ustar header is printed */
757 /*
758 if (verbose_option
759 && header->header.typeflag != GNUTYPE_LONGLINK
760 && header->header.typeflag != GNUTYPE_LONGNAME
761 && header->header.typeflag != XHDTYPE
762 && header->header.typeflag != XGLTYPE)
763 {
764 // FIXME: This global is used in print_header, sigh.
765 current_format = archive_format;
766 print_header (st, header, block_ordinal);
767 }
768 */
769 header = write_extended(false, st, header);
771}
772
773/* Call functions with either the traditional malloc/free calling
774 interface, or the mmalloc/mfree interface (that adds an extra first
775 argument), based on the value of use_extra_arg. */
776
781static void *
782call_chunkfun(struct obstack *h, size_t size)
783{
784 if (h->use_extra_arg)
785 return h->chunkfun.extra(h->extra_arg, size);
786 else
787 return h->chunkfun.plain(size);
788}
789
790/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
791 Objects start on multiples of ALIGNMENT (0 means use default).
792
793 Return nonzero if successful, calls obstack_alloc_failed_handler if
794 allocation fails. */
795
800static int
801_obstack_begin_worker(struct obstack *h,
803{
804 struct _obstack_chunk *chunk; /* points to new chunk */
805
806 if (alignment == 0)
807 alignment = DEFAULT_ALIGNMENT;
808 if (size == 0)
809 /* Default size is what GNU malloc can fit in a 4096-byte block. */
810 {
811 /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
812 Use the values for range checking, because if range checking is off,
813 the extra bytes won't be missed terribly, but if range checking is on
814 and we used a larger request, a whole extra 4096 bytes would be
815 allocated.
816
817 These number are irrelevant to the new GNU malloc. I suspect it is
818 less sensitive to the size of the request. */
819 int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)) + 4 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1));
820 size = 4096 - extra;
821 }
822
823 h->chunk_size = size;
824 h->alignment_mask = alignment - 1;
825
826 chunk = h->chunk = call_chunkfun(h, h->chunk_size);
827 if (!chunk)
828 {
829 assert(0 && "Malloc problems");
830 exit(27);
831 }
832 h->next_free = h->object_base = __PTR_ALIGN((char *)chunk, chunk->contents,
833 alignment - 1);
834 h->chunk_limit = chunk->limit = (char *)chunk + h->chunk_size;
835 chunk->prev = 0;
836 /* The initial chunk now contains no empty object. */
837 h->maybe_empty_object = 0;
838 h->alloc_failed = 0;
839 return 1;
840}
841
848 void *(*chunkfun)(size_t),
849 void (*freefun)(void *))
850{
851 h->chunkfun.plain = chunkfun;
852 h->freefun.plain = freefun;
853 h->use_extra_arg = 0;
854 return _obstack_begin_worker(h, size, alignment);
855}
856
857/* Return the address of the last file name component of NAME. If
858 NAME has no relative file name components because it is a file
859 system root, return the empty string. */
860
865char *
867{
868 char const *base = name + FILE_SYSTEM_PREFIX_LEN(name);
869 char const *p;
870 bool saw_slash = false;
871
872 while (ISSLASH(*base))
873 base++;
874
875 for (p = base; *p; p++)
876 {
877 if (ISSLASH(*p))
878 saw_slash = true;
879 else if (saw_slash)
880 {
881 base = p;
882 saw_slash = false;
883 }
884 }
885
886 return (char *)base;
887}
888
889/* Write a "private" header */
890
895union block *
896start_private_header(const char *name, size_t size, time_t t)
897{
898 union block *header = find_next_block();
899
900 memset(header->buffer, 0, sizeof(union block));
901
903 OFF_TO_CHARS(size, header->header.size);
904
905 TIME_TO_CHARS(t < 0 ? 0 : min(t, MAX_OCTAL_VAL(header->header.mtime)),
906 header->header.mtime);
907 MODE_TO_CHARS(S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, header->header.mode);
908 UID_TO_CHARS(0, header->header.uid);
909 GID_TO_CHARS(0, header->header.gid);
910 memcpy(header->header.magic, TMAGIC, TMAGLEN);
911 memcpy(header->header.version, TVERSION, TVERSLEN);
912 return header;
913}
914
919void xheader_write(char type, char *name, time_t t, struct xheader *xhdr)
920{
921 union block *header;
922 size_t size;
923 char *p;
924
925 size = xhdr->size;
926 switch (type)
927 {
928 case XGLTYPE:
929 if (globexthdr_mtime_option)
930 t = globexthdr_mtime;
931 break;
932
933 case XHDTYPE:
934 if (exthdr_mtime_option)
935 t = exthdr_mtime;
936 break;
937 }
939 header->header.typeflag = type;
940
942
943 p = xhdr->buffer;
944
945 do
946 {
947 size_t len;
948
950 len = BLOCKSIZE;
951 if (len > size)
952 len = size;
953 memcpy(header->buffer, p, len);
954 if (len < BLOCKSIZE)
955 memset(header->buffer + len, 0, BLOCKSIZE - len);
956 p += len;
957 size -= len;
959 } while (size > 0);
960 xheader_destroy(xhdr);
961
962 if (type == XGLTYPE)
963 global_header_count++;
964}
965
970char *
972{
973 if (!globexthdr_name)
974 {
975 size_t len;
976 const char *tmp = getenv("TMPDIR");
977 if (!tmp)
978 tmp = "/tmp";
979 len = strlen(tmp) + sizeof(GLOBAL_HEADER_TEMPLATE); /* Includes nul */
980 globexthdr_name = xmalloc(len);
981 strcpy(globexthdr_name, tmp);
982 strcat(globexthdr_name, GLOBAL_HEADER_TEMPLATE);
983 }
984
985 return xheader_format_name(NULL, globexthdr_name, global_header_count + 1);
986}
987
992void xheader_finish(struct xheader *xhdr)
993{
994 struct keyword_list *kp;
995
996 for (kp = keyword_override_list; kp; kp = kp->next)
997 code_string(kp->value, kp->pattern, xhdr);
998
999 xhdr->buffer = obstack_finish(xhdr->stk);
1000}
1001
1006static void
1007x_obstack_blank(struct xheader *xhdr, size_t length)
1008{
1009 obstack_blank(xhdr->stk, length);
1010 xhdr->size += length;
1011}
1012
1017bool xheader_string_end(struct xheader *xhdr, char const *keyword)
1018{
1019 uintmax_t len;
1020 uintmax_t p;
1021 uintmax_t n = 0;
1022 size_t size;
1023 char nbuf[UINTMAX_STRSIZE_BOUND];
1024 char const *np;
1025 char *cp;
1026
1027 if (xhdr->buffer)
1028 return false;
1029 xheader_init(xhdr);
1030
1031 len = strlen(keyword) + xhdr->string_length + 3; /* ' ' + '=' + '\n' */
1032
1033 do
1034 {
1035 p = n;
1036 np = umaxtostr(len + p, nbuf);
1037 n = nbuf + sizeof nbuf - 1 - np;
1038 } while (n != p);
1039
1040 p = strlen(keyword) + n + 2;
1041 size = p;
1042 if (size != p)
1043 {
1044#if 0
1045 ERROR((0, 0,
1046 _("Generated keyword/value pair is too long (keyword=%s, length=%s)"),
1047 keyword, nbuf));
1048#endif
1049
1050 pedro_dprintf(2, "Generated keyword/value pair is too long (keyword=%s, length=%s)", keyword, nbuf);
1051 obstack_free(xhdr->stk, obstack_finish(xhdr->stk));
1052 return false;
1053 }
1054 x_obstack_blank(xhdr, p);
1055 x_obstack_1grow(xhdr, '\n');
1056 cp = (char *)obstack_next_free(xhdr->stk) - xhdr->string_length - p - 1;
1057 memmove(cp + p, cp, xhdr->string_length);
1058 cp = stpcpy(cp, np);
1059 *cp++ = ' ';
1060 cp = stpcpy(cp, keyword);
1061 *cp++ = '=';
1062 return true;
1063}
1064
1065/* Buildable strings */
1066
1071void xheader_string_add(struct xheader *xhdr, char const *s)
1072{
1073 if (xhdr->buffer)
1074 return;
1075 xheader_init(xhdr);
1076 xhdr->string_length += strlen(s);
1077 x_obstack_grow(xhdr, s, strlen(s));
1078}
1079
1085{
1086 xhdr->string_length = 0;
1087}
1088
1089/* Given UID, find the corresponding UNAME. */
1090
1095void uid_to_uname(__attribute__((unused)) uid_t uid, char **uname)
1096{
1097#if 1
1098 *uname = xstrdup(""); //little memory leak
1099 return;
1100#else
1101 struct passwd *passwd;
1102
1103 if (uid != 0 && uid == cached_no_such_uid)
1104 {
1105 *uname = xstrdup("");
1106 return;
1107 }
1108
1109 if (!cached_uname || uid != cached_uid)
1110 {
1111 passwd = getpwuid(uid);
1112 if (passwd)
1113 {
1114 cached_uid = uid;
1115 assign_string(&cached_uname, passwd->pw_name);
1116 }
1117 else
1118 {
1119 cached_no_such_uid = uid;
1120 *uname = xstrdup("");
1121 return;
1122 }
1123 }
1124 *uname = xstrdup(cached_uname);
1125#endif
1126}
1127
1132static bool
1133minor_to_chars(minor_t v, char *p, size_t s)
1134{
1135 return to_chars(v < 0, (uintmax_t)v, sizeof v, 0, p, s, "minor_t");
1136}
1137
1142static bool
1143major_to_chars(major_t v, char *p, size_t s)
1144{
1145 return to_chars(v < 0, (uintmax_t)v, sizeof v, 0, p, s, "major_t");
1146}
1147
1152int timespec_cmp(struct timespec a, struct timespec b)
1153{
1154 if (a.tv_sec < b.tv_sec)
1155 return -1;
1156 if (a.tv_sec > b.tv_sec)
1157 return 1;
1158
1159 /* Pacify gcc -Wstrict-overflow (bleeding-edge circa 2017-10-02). See:
1160 https://lists.gnu.org/r/bug-gnulib/2017-10/msg00006.html */
1161 assume(-1 <= a.tv_nsec && a.tv_nsec <= 2 * TIMESPEC_HZ);
1162 assume(-1 <= b.tv_nsec && b.tv_nsec <= 2 * TIMESPEC_HZ);
1163
1164 return a.tv_nsec - b.tv_nsec;
1165}
1166
1167/* Return the file mode bits of OLDMODE (which is the mode of a
1168 directory if DIR), assuming the umask is UMASK_VALUE, adjusted as
1169 indicated by the list of change operations CHANGES. If DIR, the
1170 type 'X' change affects the returned value even if no execute bits
1171 were set in OLDMODE, and set user and group ID bits are preserved
1172 unless CHANGES mentioned them. If PMODE_BITS is not null, store into
1173 * PMODE_BITS a mask denoting file mode bits that are affected by
1174 CHANGES.
1175
1176 The returned value and *PMODE_BITS contain only file mode bits.
1177 For example, they have the S_IFMT bits cleared on a standard
1178 Unix-like host. */
1179
1184mode_t
1185mode_adjust(mode_t oldmode, bool dir, mode_t umask_value,
1186 struct mode_change const *changes, mode_t *pmode_bits)
1187{
1188 /* The adjusted mode. */
1189 mode_t newmode = oldmode & CHMOD_MODE_BITS;
1190
1191 /* File mode bits that CHANGES cares about. */
1192 mode_t mode_bits = 0;
1193
1194 for (; changes->flag != MODE_DONE; changes++)
1195 {
1196 mode_t affected = changes->affected;
1197 mode_t omit_change =
1198 (dir ? S_ISUID | S_ISGID : 0) & ~changes->mentioned;
1199 mode_t value = changes->value;
1200
1201 switch (changes->flag)
1202 {
1204 break;
1205
1206 case MODE_COPY_EXISTING:
1207 /* Isolate in 'value' the bits in 'newmode' to copy. */
1208 value &= newmode;
1209
1210 /* Copy the isolated bits to the other two parts. */
1211 value |= ((value & (S_IRUSR | S_IRGRP | S_IROTH)
1212 ? S_IRUSR | S_IRGRP | S_IROTH
1213 : 0) |
1214 (value & (S_IWUSR | S_IWGRP | S_IWOTH)
1215 ? S_IWUSR | S_IWGRP | S_IWOTH
1216 : 0) |
1217 (value & (S_IXUSR | S_IXGRP | S_IXOTH)
1218 ? S_IXUSR | S_IXGRP | S_IXOTH
1219 : 0));
1220 break;
1221
1222 case MODE_X_IF_ANY_X:
1223 /* Affect the execute bits if execute bits are already set
1224 or if the file is a directory. */
1225 if ((newmode & (S_IXUSR | S_IXGRP | S_IXOTH)) | dir)
1226 value |= S_IXUSR | S_IXGRP | S_IXOTH;
1227 break;
1228 }
1229
1230 /* If WHO was specified, limit the change to the affected bits.
1231 Otherwise, apply the umask. Either way, omit changes as
1232 requested. */
1233 value &= (affected ? affected : ~umask_value) & ~omit_change;
1234
1235 switch (changes->op)
1236 {
1237 case '=':
1238 /* If WHO was specified, preserve the previous values of
1239 bits that are not affected by this change operation.
1240 Otherwise, clear all the bits. */
1241 {
1242 mode_t preserved = (affected ? ~affected : 0) | omit_change;
1243 mode_bits |= CHMOD_MODE_BITS & ~preserved;
1244 newmode = (newmode & preserved) | value;
1245 break;
1246 }
1247
1248 case '+':
1249 mode_bits |= value;
1250 newmode |= value;
1251 break;
1252
1253 case '-':
1254 mode_bits |= value;
1255 newmode &= ~value;
1256 break;
1257 }
1258 }
1259
1260 if (pmode_bits)
1261 *pmode_bits = mode_bits;
1262 return newmode;
1263}
1264
1265/* If ENTRY matches an entry already in the hash table, return the
1266 entry from the table. Otherwise, return NULL. */
1267
1272void *
1273hash_lookup(const Hash_table *table, const void *entry)
1274{
1275 struct hash_entry const *bucket = safe_hasher(table, entry);
1276 struct hash_entry const *cursor;
1277
1278 if (bucket->data == NULL)
1279 return NULL;
1280
1281 for (cursor = bucket; cursor; cursor = cursor->next)
1282 if (entry == cursor->data || table->comparator(entry, cursor->data))
1283 return cursor->data;
1284
1285 return NULL;
1286}
1287
1292int group_map_translate(gid_t gid, gid_t *new_gid, char const **new_name)
1293{
1294 int rc = 1;
1295
1296 if (group_map)
1297 {
1298 struct mapentry ent, *res;
1299
1300 ent.orig_id = gid;
1301 res = hash_lookup(group_map, &ent);
1302 if (res)
1303 {
1304 *new_gid = res->new_id;
1305 *new_name = res->new_name;
1306 return 0;
1307 }
1308 }
1309
1310 if (group_option != (uid_t)-1)
1311 {
1312 *new_gid = group_option;
1313 rc = 0;
1314 }
1316 {
1318 rc = 0;
1319 }
1320
1321 return rc;
1322}
1323
1328int owner_map_translate(uid_t uid, uid_t *new_uid, char const **new_name)
1329{
1330 int rc = 1;
1331
1332 if (owner_map)
1333 {
1334 struct mapentry ent, *res;
1335
1336 ent.orig_id = uid;
1337 res = hash_lookup(owner_map, &ent);
1338 if (res)
1339 {
1340 *new_uid = res->new_id;
1341 *new_name = res->new_name;
1342 return 0;
1343 }
1344 }
1345
1346 if (owner_option != (uid_t)-1)
1347 {
1348 *new_uid = owner_option;
1349 rc = 0;
1350 }
1352 {
1354 rc = 0;
1355 }
1356
1357 return rc;
1358}
1359
1364static union block *
1365write_header_name(struct tar_stat_info *st)
1366{
1368 {
1369 xheader_store("path", st, NULL);
1370 return write_short_name(st);
1371 }
1372 else if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < strlen(st->file_name))
1373 return write_long_name(st);
1374 else
1375 return write_short_name(st);
1376}
1377
1378/* Make a header block for the file whose stat info is st,
1379 and return its address. */
1380
1385union block *
1387{
1388 union block *header;
1389 char const *uname = NULL;
1390 char const *gname = NULL;
1391
1392 header = write_header_name(st);
1393 if (!header)
1394 return NULL;
1395
1396 /* Override some stat fields, if requested to do so. */
1397 owner_map_translate(st->stat.st_uid, (uid_t *)&st->stat.st_uid, &uname);
1398 group_map_translate(st->stat.st_gid, (uid_t *)&st->stat.st_gid, &gname);
1399
1400 if (mode_option)
1401 st->stat.st_mode =
1402 ((st->stat.st_mode & ~MODE_ALL) | mode_adjust(st->stat.st_mode, S_ISDIR(st->stat.st_mode) != 0,
1404
1405 /* Paul Eggert tried the trivial test ($WRITER cf a b; $READER tvf a)
1406 for a few tars and came up with the following interoperability
1407 matrix:
1408
1409 WRITER
1410 1 2 3 4 5 6 7 8 9 READER
1411 . . . . . . . . . 1 = SunOS 4.2 tar
1412 # . . # # . . # # 2 = NEC SVR4.0.2 tar
1413 . . . # # . . # . 3 = Solaris 2.1 tar
1414 . . . . . . . . . 4 = GNU tar 1.11.1
1415 . . . . . . . . . 5 = HP-UX 8.07 tar
1416 . . . . . . . . . 6 = Ultrix 4.1
1417 . . . . . . . . . 7 = AIX 3.2
1418 . . . . . . . . . 8 = Hitachi HI-UX 1.03
1419 . . . . . . . . . 9 = Omron UNIOS-B 4.3BSD 1.60Beta
1420
1421 . = works
1422 # = "impossible file type"
1423
1424 The following mask for old archive removes the '#'s in column 4
1425 above, thus making GNU tar both a universal donor and a universal
1426 acceptor for Paul's test. */
1427
1429 MODE_TO_CHARS(st->stat.st_mode & MODE_ALL, header->header.mode);
1430 else
1431 MODE_TO_CHARS(st->stat.st_mode, header->header.mode);
1432
1433 {
1434 uid_t uid = st->stat.st_uid;
1435 if (archive_format == POSIX_FORMAT && (int)(MAX_OCTAL_VAL(header->header.uid)) < uid)
1436 {
1437 xheader_store("uid", st, NULL);
1438 uid = 0;
1439 }
1440 if (!UID_TO_CHARS(uid, header->header.uid))
1441 return NULL;
1442 }
1443
1444 {
1445 gid_t gid = st->stat.st_gid;
1446 if (archive_format == POSIX_FORMAT && (int)(MAX_OCTAL_VAL(header->header.gid)) < gid)
1447 {
1448 xheader_store("gid", st, NULL);
1449 gid = 0;
1450 }
1451 if (!GID_TO_CHARS(gid, header->header.gid))
1452 return NULL;
1453 }
1454
1455 {
1456 off_t size = st->stat.st_size;
1457 if (archive_format == POSIX_FORMAT && (long int)(MAX_OCTAL_VAL(header->header.size)) < size)
1458 {
1459 xheader_store("size", st, NULL);
1460 size = 0;
1461 }
1462 if (!OFF_TO_CHARS(size, header->header.size))
1463 return NULL;
1464 }
1465
1466 {
1467 struct timespec mtime;
1468
1469 switch (set_mtime_option)
1470 {
1471 case USE_FILE_MTIME:
1472 mtime = st->mtime;
1473 break;
1474
1475 case FORCE_MTIME:
1476 mtime = mtime_option;
1477 break;
1478
1479 case CLAMP_MTIME:
1480 mtime = timespec_cmp(st->mtime, mtime_option) > 0
1481 ? mtime_option
1482 : st->mtime;
1483 break;
1484 }
1485
1487 {
1488 if ((time_t)(MAX_OCTAL_VAL(header->header.mtime)) < mtime.tv_sec || mtime.tv_nsec != 0)
1489 xheader_store("mtime", st, &mtime);
1490 if ((time_t)(MAX_OCTAL_VAL(header->header.mtime)) < mtime.tv_sec)
1491 mtime.tv_sec = 0;
1492 }
1493 if (!TIME_TO_CHARS(mtime.tv_sec, header->header.mtime))
1494 return NULL;
1495 }
1496
1497 /* FIXME */
1498 if (S_ISCHR(st->stat.st_mode) || S_ISBLK(st->stat.st_mode))
1499 {
1500 major_t devmajor = major(st->stat.st_rdev);
1501 minor_t devminor = minor(st->stat.st_rdev);
1502
1503 if (archive_format == POSIX_FORMAT && (int)(MAX_OCTAL_VAL(header->header.devmajor)) < devmajor)
1504 {
1505 xheader_store("devmajor", st, NULL);
1506 devmajor = 0;
1507 }
1508 if (!MAJOR_TO_CHARS(devmajor, header->header.devmajor))
1509 return NULL;
1510
1511 if (archive_format == POSIX_FORMAT && (int)(MAX_OCTAL_VAL(header->header.devminor)) < devminor)
1512 {
1513 xheader_store("devminor", st, NULL);
1514 devminor = 0;
1515 }
1516 if (!MINOR_TO_CHARS(devminor, header->header.devminor))
1517 return NULL;
1518 }
1520 {
1521 if (!(MAJOR_TO_CHARS(0, header->header.devmajor) && MINOR_TO_CHARS(0, header->header.devminor)))
1522 return NULL;
1523 }
1524
1526 {
1527 xheader_store("atime", st, NULL);
1528 xheader_store("ctime", st, NULL);
1529 }
1530 else if (incremental_option)
1532 {
1533 TIME_TO_CHARS(st->atime.tv_sec, header->oldgnu_header.atime);
1534 TIME_TO_CHARS(st->ctime.tv_sec, header->oldgnu_header.ctime);
1535 }
1536
1537 header->header.typeflag = archive_format == V7_FORMAT ? AREGTYPE : REGTYPE;
1538
1539 switch (archive_format)
1540 {
1541 case V7_FORMAT:
1542 break;
1543
1544 case OLDGNU_FORMAT:
1545 case GNU_FORMAT: /*FIXME?*/
1546 /* Overwrite header->header.magic and header.version in one blow. */
1547 strcpy(header->buffer + offsetof(struct posix_header, magic),
1548 OLDGNU_MAGIC);
1549 break;
1550
1551 case POSIX_FORMAT:
1552 case USTAR_FORMAT:
1553 memcpy(header->header.magic, TMAGIC, TMAGLEN);
1554 memcpy(header->header.version, TVERSION, TVERSLEN);
1555 break;
1556
1557 default:
1558 abort();
1559 }
1560
1562 {
1563 /* header->header.[ug]name are left as the empty string. */
1564 }
1565 else
1566 {
1567 if (uname)
1568 st->uname = xstrdup(uname);
1569 else
1570 uid_to_uname(st->stat.st_uid, &st->uname);
1571
1572 if (gname)
1573 st->gname = xstrdup(gname);
1574 else
1575 gid_to_gname(st->stat.st_gid, &st->gname);
1576
1577 if (archive_format == POSIX_FORMAT && (strlen(st->uname) > UNAME_FIELD_SIZE || !string_ascii_p(st->uname)))
1578 xheader_store("uname", st, NULL);
1579 UNAME_TO_CHARS(st->uname, header->header.uname);
1580
1581 if (archive_format == POSIX_FORMAT && (strlen(st->gname) > GNAME_FIELD_SIZE || !string_ascii_p(st->gname)))
1582 xheader_store("gname", st, NULL);
1583 GNAME_TO_CHARS(st->gname, header->header.gname);
1584 }
1585
1587 {
1588 if (acls_option > 0)
1589 {
1590 if (st->acls_a_ptr)
1591 xheader_store("SCHILY.acl.access", st, NULL);
1592 if (st->acls_d_ptr)
1593 xheader_store("SCHILY.acl.default", st, NULL);
1594 }
1595 if ((selinux_context_option > 0) && st->cntx_name)
1596 xheader_store("RHT.security.selinux", st, NULL);
1597 if (xattrs_option > 0)
1598 {
1599 size_t scan_xattr = 0;
1600 struct xattr_array *xattr_map = st->xattr_map;
1601
1602 while (scan_xattr < st->xattr_map_size)
1603 {
1604 xheader_store(xattr_map[scan_xattr].xkey, st, &scan_xattr);
1605 ++scan_xattr;
1606 }
1607 }
1608 }
1609
1610 return header;
1611}
1612
1613/* Start a header that uses the effective (shrunken) file size. */
1614
1619static union block *
1620pax_start_header(struct tar_stat_info *st)
1621{
1622 off_t realsize = st->stat.st_size;
1623 union block *blk;
1624
1625 st->stat.st_size = st->archive_file_size;
1626 blk = start_header(st);
1627 st->stat.st_size = realsize;
1628 return blk;
1629}
1630
1631/* Get a new hash entry for a bucket overflow, possibly by recycling a
1632 previously freed one. If this is not possible, allocate a new one. */
1633
1638static struct hash_entry *
1639allocate_entry(Hash_table *table)
1640{
1641 struct hash_entry *new;
1642
1643 if (table->free_entry_list)
1644 {
1645 new = table->free_entry_list;
1646 table->free_entry_list = new->next;
1647 }
1648 else
1649 {
1650#if USE_OBSTACK
1651 new = obstack_alloc(&table->entry_stack, sizeof *new);
1652#else
1653 new = malloc(sizeof *new);
1654#endif
1655 }
1656
1657 return new;
1658}
1659
1660/* Internal helper, to move entries from SRC to DST. Both tables must
1661 share the same free entry list. If SAFE, only move overflow
1662 entries, saving bucket heads for later, so that no allocations will
1663 occur. Return false if the free entry list is exhausted and an
1664 allocation fails. */
1665
1670static bool
1671transfer_entries(Hash_table *dst, Hash_table *src, bool safe)
1672{
1673 struct hash_entry *bucket;
1674 struct hash_entry *cursor;
1675 struct hash_entry *next;
1676
1677 for (bucket = src->bucket; bucket < src->bucket_limit; bucket++)
1678 if (bucket->data)
1679 {
1680 void *data;
1681 struct hash_entry *new_bucket;
1682
1683 /* Within each bucket, transfer overflow entries first and
1684 then the bucket head, to minimize memory pressure. After
1685 all, the only time we might allocate is when moving the
1686 bucket head, but moving overflow entries first may create
1687 free entries that can be recycled by the time we finally
1688 get to the bucket head. */
1689 for (cursor = bucket->next; cursor; cursor = next)
1690 {
1691 data = cursor->data;
1692 new_bucket = safe_hasher(dst, data);
1693
1694 next = cursor->next;
1695
1696 if (new_bucket->data)
1697 {
1698 /* Merely relink an existing entry, when moving from a
1699 bucket overflow into a bucket overflow. */
1700 cursor->next = new_bucket->next;
1701 new_bucket->next = cursor;
1702 }
1703 else
1704 {
1705 /* Free an existing entry, when moving from a bucket
1706 overflow into a bucket header. */
1707 new_bucket->data = data;
1708 dst->n_buckets_used++;
1709 free_entry(dst, cursor);
1710 }
1711 }
1712 /* Now move the bucket head. Be sure that if we fail due to
1713 allocation failure that the src table is in a consistent
1714 state. */
1715 data = bucket->data;
1716 bucket->next = NULL;
1717 if (safe)
1718 continue;
1719 new_bucket = safe_hasher(dst, data);
1720
1721 if (new_bucket->data)
1722 {
1723 /* Allocate or recycle an entry, when moving from a bucket
1724 header into a bucket overflow. */
1725 struct hash_entry *new_entry = allocate_entry(dst);
1726
1727 if (new_entry == NULL)
1728 return false;
1729
1730 new_entry->data = data;
1731 new_entry->next = new_bucket->next;
1732 new_bucket->next = new_entry;
1733 }
1734 else
1735 {
1736 /* Move from one bucket header to another. */
1737 new_bucket->data = data;
1738 dst->n_buckets_used++;
1739 }
1740 bucket->data = NULL;
1741 src->n_buckets_used--;
1742 }
1743 return true;
1744}
1745
1746/* For an already existing hash table, change the number of buckets through
1747 specifying CANDIDATE. The contents of the hash table are preserved. The
1748 new number of buckets is automatically selected so as to _guarantee_ that
1749 the table may receive at least CANDIDATE different user entries, including
1750 those already in the table, before any other growth of the hash table size
1751 occurs. If TUNING->IS_N_BUCKETS is true, then CANDIDATE specifies the
1752 exact number of buckets desired. Return true iff the rehash succeeded. */
1753
1758bool hash_rehash(Hash_table *table, size_t candidate)
1759{
1760 Hash_table storage;
1761 Hash_table *new_table;
1762 size_t new_size = compute_bucket_size(candidate, table->tuning);
1763
1764 if (!new_size)
1765 return false;
1766 if (new_size == table->n_buckets)
1767 return true;
1768 new_table = &storage;
1769 new_table->bucket = calloc(new_size, sizeof *new_table->bucket);
1770 if (new_table->bucket == NULL)
1771 return false;
1772 new_table->n_buckets = new_size;
1773 new_table->bucket_limit = new_table->bucket + new_size;
1774 new_table->n_buckets_used = 0;
1775 new_table->n_entries = 0;
1776 new_table->tuning = table->tuning;
1777 new_table->hasher = table->hasher;
1778 new_table->comparator = table->comparator;
1779 new_table->data_freer = table->data_freer;
1780
1781 /* In order for the transfer to successfully complete, we need
1782 additional overflow entries when distinct buckets in the old
1783 table collide into a common bucket in the new table. The worst
1784 case possible is a hasher that gives a good spread with the old
1785 size, but returns a constant with the new size; if we were to
1786 guarantee table->n_buckets_used-1 free entries in advance, then
1787 the transfer would be guaranteed to not allocate memory.
1788 However, for large tables, a guarantee of no further allocation
1789 introduces a lot of extra memory pressure, all for an unlikely
1790 corner case (most rehashes reduce, rather than increase, the
1791 number of overflow entries needed). So, we instead ensure that
1792 the transfer process can be reversed if we hit a memory
1793 allocation failure mid-transfer. */
1794
1795 /* Merely reuse the extra old space into the new table. */
1796#if USE_OBSTACK
1797 new_table->entry_stack = table->entry_stack;
1798#endif
1799 new_table->free_entry_list = table->free_entry_list;
1800
1801 if (transfer_entries(new_table, table, false))
1802 {
1803 /* Entries transferred successfully; tie up the loose ends. */
1804 free(table->bucket);
1805 table->bucket = new_table->bucket;
1806 table->bucket_limit = new_table->bucket_limit;
1807 table->n_buckets = new_table->n_buckets;
1808 table->n_buckets_used = new_table->n_buckets_used;
1809 table->free_entry_list = new_table->free_entry_list;
1810 /* table->n_entries and table->entry_stack already hold their value. */
1811 return true;
1812 }
1813
1814 /* We've allocated new_table->bucket (and possibly some entries),
1815 exhausted the free list, and moved some but not all entries into
1816 new_table. We must undo the partial move before returning
1817 failure. The only way to get into this situation is if new_table
1818 uses fewer buckets than the old table, so we will reclaim some
1819 free entries as overflows in the new table are put back into
1820 distinct buckets in the old table.
1821
1822 There are some pathological cases where a single pass through the
1823 table requires more intermediate overflow entries than using two
1824 passes. Two passes give worse cache performance and takes
1825 longer, but at this point, we're already out of memory, so slow
1826 and safe is better than failure. */
1827 table->free_entry_list = new_table->free_entry_list;
1828 if (!(transfer_entries(table, new_table, true) && transfer_entries(table, new_table, false)))
1829 abort();
1830 /* table->n_entries already holds its value. */
1831 free(new_table->bucket);
1832 return false;
1833}
1834
1835/* Free a hash entry which was part of some bucket overflow,
1836 saving it for later recycling. */
1837
1842static void
1843free_entry(Hash_table *table, struct hash_entry *entry)
1844{
1845 entry->data = NULL;
1846 entry->next = table->free_entry_list;
1847 table->free_entry_list = entry;
1848}
1849
1850/* Hash KEY and return a pointer to the selected bucket.
1851 If TABLE->hasher misbehaves, abort. */
1852
1857static struct hash_entry *
1858safe_hasher(const Hash_table *table, const void *key)
1859{
1860 size_t n = table->hasher(key, table->n_buckets);
1861
1862 if (!(n < table->n_buckets))
1863 abort();
1864 return table->bucket + n;
1865}
1866
1867/* This private function is used to help with insertion and deletion. When
1868 ENTRY matches an entry in the table, return a pointer to the corresponding
1869 user data and set *BUCKET_HEAD to the head of the selected bucket.
1870 Otherwise, return NULL. When DELETE is true and ENTRY matches an entry in
1871 the table, unlink the matching entry. */
1872
1877static void *
1878hash_find_entry(Hash_table *table, const void *entry,
1879 struct hash_entry **bucket_head, bool delete)
1880{
1881 struct hash_entry *bucket = safe_hasher(table, entry);
1882 struct hash_entry *cursor;
1883
1884 *bucket_head = bucket;
1885
1886 /* Test for empty bucket. */
1887 if (bucket->data == NULL)
1888 return NULL;
1889
1890 /* See if the entry is the first in the bucket. */
1891 if (entry == bucket->data || table->comparator(entry, bucket->data))
1892 {
1893 void *data = bucket->data;
1894
1895 if (delete)
1896 {
1897 if (bucket->next)
1898 {
1899 struct hash_entry *next = bucket->next;
1900
1901 /* Bump the first overflow entry into the bucket head, then save
1902 the previous first overflow entry for later recycling. */
1903 *bucket = *next;
1904 free_entry(table, next);
1905 }
1906 else
1907 {
1908 bucket->data = NULL;
1909 }
1910 }
1911
1912 return data;
1913 }
1914
1915 /* Scan the bucket overflow. */
1916 for (cursor = bucket; cursor->next; cursor = cursor->next)
1917 {
1918 if (entry == cursor->next->data || table->comparator(entry, cursor->next->data))
1919 {
1920 void *data = cursor->next->data;
1921
1922 if (delete)
1923 {
1924 struct hash_entry *next = cursor->next;
1925
1926 /* Unlink the entry to delete, then save the freed entry for later
1927 recycling. */
1928 cursor->next = next->next;
1929 free_entry(table, next);
1930 }
1931
1932 return data;
1933 }
1934 }
1935
1936 /* No entry found. */
1937 return NULL;
1938}
1939
1940/* Insert ENTRY into hash TABLE if there is not already a matching entry.
1941
1942 Return -1 upon memory allocation failure.
1943 Return 1 if insertion succeeded.
1944 Return 0 if there is already a matching entry in the table,
1945 and in that case, if MATCHED_ENT is non-NULL, set *MATCHED_ENT
1946 to that entry.
1947
1948 This interface is easier to use than hash_insert when you must
1949 distinguish between the latter two cases. More importantly,
1950 hash_insert is unusable for some types of ENTRY values. When using
1951 hash_insert, the only way to distinguish those cases is to compare
1952 the return value and ENTRY. That works only when you can have two
1953 different ENTRY values that point to data that compares "equal". Thus,
1954 when the ENTRY value is a simple scalar, you must use
1955 hash_insert_if_absent. ENTRY must not be NULL. */
1956
1962 void const **matched_ent)
1963{
1964 void *data;
1965 struct hash_entry *bucket;
1966
1967 /* The caller cannot insert a NULL entry, since hash_lookup returns NULL
1968 to indicate "not found", and hash_find_entry uses "bucket->data == NULL"
1969 to indicate an empty bucket. */
1970 if (!entry)
1971 abort();
1972
1973 /* If there's a matching entry already in the table, return that. */
1974 if ((data = hash_find_entry(table, entry, &bucket, false)) != NULL)
1975 {
1976 if (matched_ent)
1977 *matched_ent = data;
1978 return 0;
1979 }
1980
1981 /* If the growth threshold of the buckets in use has been reached, increase
1982 the table size and rehash. There's no point in checking the number of
1983 entries: if the hashing function is ill-conditioned, rehashing is not
1984 likely to improve it. */
1985
1986 if (table->n_buckets_used > table->tuning->growth_threshold * table->n_buckets)
1987 {
1988 /* Check more fully, before starting real work. If tuning arguments
1989 became invalid, the second check will rely on proper defaults. */
1990 check_tuning(table);
1991 if (table->n_buckets_used > table->tuning->growth_threshold * table->n_buckets)
1992 {
1993 const Hash_tuning *tuning = table->tuning;
1994 float candidate =
1995 (tuning->is_n_buckets
1996 ? (table->n_buckets * tuning->growth_factor)
1997 : (table->n_buckets * tuning->growth_factor * tuning->growth_threshold));
1998
1999 if (SIZE_MAX <= candidate)
2000 return -1;
2001
2002 /* If the rehash fails, arrange to return NULL. */
2003 if (!hash_rehash(table, candidate))
2004 return -1;
2005
2006 /* Update the bucket we are interested in. */
2007 if (hash_find_entry(table, entry, &bucket, false) != NULL)
2008 abort();
2009 }
2010 }
2011
2012 /* ENTRY is not matched, it should be inserted. */
2013
2014 if (bucket->data)
2015 {
2016 struct hash_entry *new_entry = allocate_entry(table);
2017
2018 if (new_entry == NULL)
2019 return -1;
2020
2021 /* Add ENTRY in the overflow of the bucket. */
2022
2023 new_entry->data = (void *)entry;
2024 new_entry->next = bucket->next;
2025 bucket->next = new_entry;
2026 table->n_entries++;
2027 return 1;
2028 }
2029
2030 /* Add ENTRY right in the bucket head. */
2031
2032 bucket->data = (void *)entry;
2033 table->n_entries++;
2034 table->n_buckets_used++;
2035
2036 return 1;
2037}
2038
2044 void const **matched_ent)
2045{
2046 void *data;
2047 struct hash_entry *bucket;
2048
2049 /* The caller cannot insert a NULL entry, since hash_lookup returns NULL
2050 to indicate "not found", and hash_find_entry uses "bucket->data == NULL"
2051 to indicate an empty bucket. */
2052 if (!entry)
2053 abort();
2054
2055 /* If there's a matching entry already in the table, return that. */
2056 if ((data = hash_find_entry(table, entry, &bucket, false)) != NULL)
2057 {
2058 if (matched_ent)
2059 *matched_ent = data;
2060 return 0;
2061 }
2062
2063 /* If the growth threshold of the buckets in use has been reached, increase
2064 the table size and rehash. There's no point in checking the number of
2065 entries: if the hashing function is ill-conditioned, rehashing is not
2066 likely to improve it. */
2067
2068 if (table->n_buckets_used > table->tuning->growth_threshold * table->n_buckets)
2069 {
2070 /* Check more fully, before starting real work. If tuning arguments
2071 became invalid, the second check will rely on proper defaults. */
2072 check_tuning(table);
2073 if (table->n_buckets_used > table->tuning->growth_threshold * table->n_buckets)
2074 {
2075 const Hash_tuning *tuning = table->tuning;
2076 float candidate =
2077 (tuning->is_n_buckets
2078 ? (table->n_buckets * tuning->growth_factor)
2079 : (table->n_buckets * tuning->growth_factor * tuning->growth_threshold));
2080
2081 if ((float)SIZE_MAX <= candidate)
2082 return -1;
2083
2084 /* If the rehash fails, arrange to return NULL. */
2085 if (!hash_rehash(table, candidate))
2086 return -1;
2087
2088 /* Update the bucket we are interested in. */
2089 if (hash_find_entry(table, entry, &bucket, false) != NULL)
2090 abort();
2091 }
2092 }
2093
2094 /* ENTRY is not matched, it should be inserted. */
2095
2096 if (bucket->data)
2097 {
2098 struct hash_entry *new_entry = allocate_entry(table);
2099
2100 if (new_entry == NULL)
2101 return -1;
2102
2103 /* Add ENTRY in the overflow of the bucket. */
2104
2105 new_entry->data = (void *)entry;
2106 new_entry->next = bucket->next;
2107 bucket->next = new_entry;
2108 table->n_entries++;
2109 return 1;
2110 }
2111
2112 /* Add ENTRY right in the bucket head. */
2113
2114 bucket->data = (void *)entry;
2115 table->n_entries++;
2116 table->n_buckets_used++;
2117
2118 return 1;
2119}
2120
2121/* If ENTRY matches an entry already in the hash table, return the pointer
2122 to the entry from the table. Otherwise, insert ENTRY and return ENTRY.
2123 Return NULL if the storage required for insertion cannot be allocated.
2124 This implementation does not support duplicate entries or insertion of
2125 NULL. */
2126
2131void *
2132hash_insert(Hash_table *table, void const *entry)
2133{
2134 void const *matched_ent;
2135 int err = hash_insert_if_absent(table, entry, &matched_ent);
2136
2137 return (err == -1
2138 ? NULL
2139 : (void *)(err == 0 ? matched_ent : entry));
2140}
2141
2142/* Compare two strings for equality. */
2143
2148static bool
2149hash_string_compare(void const *name1, void const *name2)
2150{
2151 return strcmp(name1, name2) == 0;
2152}
2153
2154/* Return a hash index for a NUL-terminated STRING between 0 and N_BUCKETS-1.
2155 This is a convenience routine for constructing other hashing functions. */
2156
2157#if USE_DIFF_HASH
2158
2159/* About hashings, Paul Eggert writes to me (FP), on 1994-01-01: "Please see
2160 B. J. McKenzie, R. Harries & T. Bell, Selecting a hashing algorithm,
2161 Software--practice & experience 20, 2 (Feb 1990), 209-224. Good hash
2162 algorithms tend to be domain-specific, so what's good for [diffutils'] io.c
2163 may not be good for your application." */
2164
2169size_t
2170hash_string(const char *string, size_t n_buckets)
2171{
2172#define HASH_ONE_CHAR(Value, Byte) \
2173 ((Byte) + rotl_sz(Value, 7))
2174
2175 size_t value = 0;
2176 unsigned char ch;
2177
2178 for (; (ch = *string); string++)
2179 value = HASH_ONE_CHAR(value, ch);
2180 return value % n_buckets;
2181
2182#undef HASH_ONE_CHAR
2183}
2184
2185#else /* not USE_DIFF_HASH */
2186
2187/* This one comes from 'recode', and performs a bit better than the above as
2188 per a few experiments. It is inspired from a hashing routine found in the
2189 very old Cyber 'snoop', itself written in typical Greg Mansfield style.
2190 (By the way, what happened to this excellent man? Is he still alive?) */
2191
2196size_t
2197hash_string(const char *string, size_t n_buckets)
2198{
2199 size_t value = 0;
2200 unsigned char ch;
2201
2202 for (; (ch = *string); string++)
2203 value = (value * 31 + ch) % n_buckets;
2204 return value;
2205}
2206
2207#endif /* not USE_DIFF_HASH */
2208
2209/* Calculate the hash of a string. */
2210
2215static size_t
2216hash_string_hasher(void const *name, size_t n_buckets)
2217{
2218 return hash_string(name, n_buckets);
2219}
2220
2221/* Return true if CANDIDATE is a prime number. CANDIDATE should be an odd
2222 number at least equal to 11. */
2223
2228static bool
2229is_prime(size_t candidate)
2230{
2231 size_t divisor = 3;
2232 size_t square = divisor * divisor;
2233
2234 while (square < candidate && (candidate % divisor))
2235 {
2236 divisor++;
2237 square += 4 * divisor;
2238 divisor++;
2239 }
2240
2241 return (candidate % divisor ? true : false);
2242}
2243
2248static size_t
2249next_prime(size_t candidate)
2250{
2251 /* Skip small primes. */
2252 if (candidate < 10)
2253 candidate = 10;
2254
2255 /* Make it definitely odd. */
2256 candidate |= 1;
2257
2258 while (SIZE_MAX != candidate && !is_prime(candidate))
2259 candidate += 2;
2260
2261 return candidate;
2262}
2263
2268static size_t
2269compute_bucket_size(size_t candidate, const Hash_tuning *tuning)
2270{
2271 if (!tuning->is_n_buckets)
2272 {
2273 float new_candidate = candidate / tuning->growth_threshold;
2274 if ((float)SIZE_MAX <= new_candidate)
2275 return 0;
2276 candidate = new_candidate;
2277 }
2278 candidate = next_prime(candidate);
2279 if (xalloc_oversized(candidate, sizeof(struct hash_entry *)))
2280 return 0;
2281 return candidate;
2282}
2283
2284/* For the given hash TABLE, check the user supplied tuning structure for
2285 reasonable values, and return true if there is no gross error with it.
2286 Otherwise, definitively reset the TUNING field to some acceptable default
2287 in the hash table (that is, the user loses the right of further modifying
2288 tuning arguments), and return false. */
2289
2294static bool
2295check_tuning(Hash_table *table)
2296{
2297 const Hash_tuning *tuning = table->tuning;
2298 float epsilon;
2299
2300 if (tuning == &default_tuning)
2301 return true;
2302
2303 /* Be a bit stricter than mathematics would require, so that
2304 rounding errors in size calculations do not cause allocations to
2305 fail to grow or shrink as they should. The smallest allocation
2306 is 11 (due to next_prime's algorithm), so an epsilon of 0.1
2307 should be good enough. */
2308 epsilon = 0.1f;
2309
2310 if (epsilon < tuning->growth_threshold && tuning->growth_threshold < 1 - epsilon && 1 + epsilon < tuning->growth_factor && 0 <= tuning->shrink_threshold && tuning->shrink_threshold + epsilon < tuning->shrink_factor && tuning->shrink_factor <= 1 && tuning->shrink_threshold + epsilon < tuning->growth_threshold)
2311 return true;
2312
2313 table->tuning = &default_tuning;
2314 return false;
2315}
2316
2317/* If the user passes a NULL comparator, we use pointer comparison. */
2318
2323static bool
2324raw_comparator(const void *a, const void *b)
2325{
2326 return a == b;
2327}
2328
2333size_t
2334rotr_sz(size_t x, int n)
2335{
2336 return ((x >> n) | (x << ((CHAR_BIT * sizeof x) - n))) & SIZE_MAX;
2337}
2338
2343static size_t
2344raw_hasher(const void *data, size_t n)
2345{
2346 /* When hashing unique pointers, it is often the case that they were
2347 generated by malloc and thus have the property that the low-order
2348 bits are 0. As this tends to give poorer performance with small
2349 tables, we rotate the pointer value before performing division,
2350 in an attempt to improve hash quality. */
2351 size_t val = rotr_sz((size_t)data, 3);
2352
2353 return val % n;
2354}
2355
2360Hash_table *
2361hash_initialize(size_t candidate, const Hash_tuning *tuning,
2362 Hash_hasher hasher, Hash_comparator comparator,
2363 Hash_data_freer data_freer)
2364{
2366
2367 if (hasher == NULL)
2368 hasher = raw_hasher;
2369 if (comparator == NULL)
2370 comparator = raw_comparator;
2371
2372 table = malloc(sizeof *table);
2373 if (table == NULL)
2374 return NULL;
2375
2376 if (!tuning)
2377 tuning = &default_tuning;
2378 table->tuning = tuning;
2379 if (!check_tuning(table))
2380 {
2381 /* Fail if the tuning options are invalid. This is the only occasion
2382 when the user gets some feedback about it. Once the table is created,
2383 if the user provides invalid tuning options, we silently revert to
2384 using the defaults, and ignore further request to change the tuning
2385 options. */
2386 goto fail;
2387 }
2388
2389 table->n_buckets = compute_bucket_size(candidate, tuning);
2390 if (!table->n_buckets)
2391 goto fail;
2392
2393 table->bucket = calloc(table->n_buckets, sizeof *table->bucket);
2394 if (table->bucket == NULL)
2395 goto fail;
2396 table->bucket_limit = table->bucket + table->n_buckets;
2397 table->n_buckets_used = 0;
2398 table->n_entries = 0;
2399
2400 table->hasher = hasher;
2401 table->comparator = comparator;
2402 table->data_freer = data_freer;
2403
2404 table->free_entry_list = NULL;
2405#if USE_OBSTACK
2406 obstack_init(&table->entry_stack);
2407#endif
2408 return table;
2409
2410fail:
2411 free(table);
2412 return NULL;
2413}
2414
2419static bool
2420hash_string_insert_prefix(Hash_table **table, char const *string, size_t len,
2421 const char **return_prefix)
2422{
2423 Hash_table *t = *table;
2424 char *s;
2425 char *e;
2426
2427 if (len)
2428 {
2429 s = xmalloc(len + 1);
2430 memcpy(s, string, len);
2431 s[len] = 0;
2432 }
2433 else
2434 s = xstrdup(string);
2435
2436 if (!((t || (*table = t = hash_initialize(0, 0, hash_string_hasher,
2437 hash_string_compare, 0))) &&
2438 (e = hash_insert(t, s))))
2439 {
2440 assert(0 && "Malloc problems, exiting...");
2441 exit(27);
2442#if 0
2443 xalloc_die();
2444#endif
2445 }
2446
2447 if (e == s)
2448 {
2449 if (return_prefix)
2450 *return_prefix = s;
2451 return 1;
2452 }
2453 else
2454 {
2455 free(s);
2456 return 0;
2457 }
2458}
2459
2464char *
2465safer_name_suffix(char const *file_name, bool link_target,
2466 bool absolute_names)
2467{
2468 char const *p;
2469
2470 if (absolute_names)
2471 p = file_name;
2472 else
2473 {
2474 /* Skip file system prefixes, leading file name components that contain
2475 "..", and leading slashes. */
2476
2477 size_t prefix_len = FILE_SYSTEM_PREFIX_LEN(file_name);
2478
2479 for (p = file_name + prefix_len; *p;)
2480 {
2481 if (p[0] == '.' && p[1] == '.' && (ISSLASH(p[2]) || !p[2]))
2482 prefix_len = p + 2 - file_name;
2483
2484 do
2485 {
2486 char c = *p++;
2487 if (ISSLASH(c))
2488 break;
2489 } while (*p);
2490 }
2491
2492 for (p = file_name + prefix_len; ISSLASH(*p); p++)
2493 continue;
2494 prefix_len = p - file_name;
2495
2496 if (prefix_len)
2497 {
2498 const char *prefix;
2499 if (hash_string_insert_prefix(&prefix_table[link_target], file_name,
2500 prefix_len, &prefix))
2501 {
2502 static char const *const diagnostic[] =
2503 {
2504 "Removing leading `%s' from member names",
2505 "Removing leading `%s' from hard link targets"};
2506#if 0
2507 WARN((0, 0, (const char *)diagnostic[link_target], prefix));
2508#endif
2509 pedro_dprintf(2, (char *)diagnostic[link_target], prefix);
2510 }
2511 }
2512 }
2513
2514 if (!*p)
2515 {
2516 if (p == file_name)
2517 {
2518 static char const *const diagnostic[] =
2519 {
2520 "Substituting `.' for empty member name",
2521 "Substituting `.' for empty hard link target"};
2522#if 0
2523 WARN((0, 0, "%s", _(diagnostic[link_target])));
2524#endif
2525 pedro_dprintf(2, (char *)diagnostic[link_target]);
2526 }
2527
2528 p = ".";
2529 }
2530
2531 return (char *)p;
2532}
2533
2538char *
2539mdir_name(__attribute__((unused)) char const *file)
2540{
2541 assert(0 && "dentro de dir name");
2542
2543//tem que testar primeiro pra ver, porque nao manipula diretorio
2544#if 0
2545 size_t length = dir_len(file);
2546 bool append_dot = (length == 0
2547 || (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
2548 && length == FILE_SYSTEM_PREFIX_LEN(file)
2549 && file[2] != '\0' && !ISSLASH(file[2])));
2550 char *dir = malloc(length + append_dot + 1);
2551 if (!dir)
2552 return NULL;
2553 memcpy(dir, file, length);
2554 if (append_dot)
2555 dir[length++] = '.';
2556 dir[length] = '\0';
2557 return dir;
2558#endif
2559
2560 return NULL;
2561}
2562
2567char *
2568dir_name(char const *file)
2569{
2570 char *result = mdir_name(file);
2571
2572 if (!result)
2573 {
2574 assert(0 && "Malloc problem, exiting");
2575 exit(27);
2576 }
2577 return result;
2578}
2579/*
2580 string Includes: Replaced By:
2581 %d The directory name of the file,
2582 equivalent to the result of the
2583 dirname utility on the translated
2584 file name.
2585 %f The filename of the file, equivalent
2586 to the result of the basename
2587 utility on the translated file name.
2588 %p The process ID of the pax process.
2589 %n The value of the 3rd argument.
2590 %% A '%' character. */
2591
2596char *
2597xheader_format_name(struct tar_stat_info *st, const char *fmt, size_t n)
2598{
2599 char *buf;
2600 size_t len;
2601 char *q;
2602 const char *p;
2603 char *dirp = NULL;
2604 char *dir = NULL;
2605 char *base = NULL;
2606 char pidbuf[UINTMAX_STRSIZE_BOUND];
2607 char const *pptr = NULL;
2608 char nbuf[UINTMAX_STRSIZE_BOUND];
2609 char const *nptr = NULL;
2610
2611 len = 0;
2612 for (p = fmt; *p; p++)
2613 {
2614 if (*p == '%' && p[1])
2615 {
2616 switch (*++p)
2617 {
2618 case '%':
2619 len++;
2620 break;
2621
2622 case 'd':
2623 if (st)
2624 {
2625 if (!dirp)
2626 dirp = dir_name(st->orig_file_name);
2627 dir = safer_name_suffix(dirp, false, absolute_names_option);
2628 len += strlen(dir);
2629 }
2630 break;
2631
2632 case 'f':
2633 if (st)
2634 {
2635 base = last_component(st->orig_file_name);
2636 len += strlen(base);
2637 }
2638 break;
2639
2640 case 'p':
2641 pptr = umaxtostr(1, pidbuf);
2642 len += pidbuf + sizeof pidbuf - 1 - pptr;
2643 break;
2644
2645 case 'n':
2646 nptr = umaxtostr(n, nbuf);
2647 len += nbuf + sizeof nbuf - 1 - nptr;
2648 break;
2649
2650 default:
2651 len += 2;
2652 }
2653 }
2654 else
2655 len++;
2656 }
2657
2658 buf = xmalloc(len + 1);
2659 for (q = buf, p = fmt; *p;)
2660 {
2661 if (*p == '%')
2662 {
2663 switch (p[1])
2664 {
2665 case '%':
2666 *q++ = *p++;
2667 p++;
2668 break;
2669
2670 case 'd':
2671 if (dir)
2672 q = stpcpy(q, dir);
2673 p += 2;
2674 break;
2675
2676 case 'f':
2677 if (base)
2678 q = stpcpy(q, base);
2679 p += 2;
2680 break;
2681
2682 case 'p':
2683 q = stpcpy(q, pptr);
2684 p += 2;
2685 break;
2686
2687 case 'n':
2688 q = stpcpy(q, nptr);
2689 p += 2;
2690 break;
2691
2692 default:
2693 *q++ = *p++;
2694 if (*p)
2695 *q++ = *p++;
2696 }
2697 }
2698 else
2699 *q++ = *p++;
2700 }
2701
2702 free(dirp);
2703
2704 /* Do not allow it to end in a slash */
2705 while (q > buf && ISSLASH(q[-1]))
2706 q--;
2707 *q = 0;
2708 return buf;
2709}
2710
2715static void
2716xheader_init(struct xheader *xhdr)
2717{
2718 if (!xhdr->stk)
2719 {
2720 xhdr->stk = xmalloc(sizeof *xhdr->stk);
2721 obstack_init(xhdr->stk);
2722 }
2723}
2724
2729static bool
2730tar_sparse_extract_region(struct tar_sparse_file *file, size_t i)
2731{
2732 if (file->optab->extract_region)
2733 return file->optab->extract_region(file, i);
2734 return false;
2735}
2736
2741enum dump_status
2742sparse_extract_file(int fd, struct tar_stat_info *st, off_t *size)
2743{
2744 bool rc = true;
2745 struct tar_sparse_file file;
2746 size_t i;
2747
2748 if (!tar_sparse_init(&file))
2750
2751 file.stat_info = st;
2752 file.fd = fd;
2753 file.seekable = lseek(fd, 0, SEEK_SET) == 0;
2754 file.offset = 0;
2755
2756 rc = tar_sparse_decode_header(&file);
2757 for (i = 0; rc && i < file.stat_info->sparse_map_avail; i++)
2758 rc = tar_sparse_extract_region(&file, i);
2759 *size = file.stat_info->archive_file_size - file.dumped_size;
2760 return (tar_sparse_done(&file) && rc) ? dump_status_ok : dump_status_short;
2761}
2762
2763enum dump_status
2765
2766static bool
2767tar_sparse_init(struct tar_sparse_file *file);
2768
2769static bool
2770lseek_or_error(struct tar_sparse_file *file, off_t offset);
2771
2772static bool
2773dump_zeros(struct tar_sparse_file *file, off_t offset);
2774
2775void seek_diag_details(char const *name, off_t offset);
2776
2777void seek_warn_details(char const *name, off_t offset);
2778
2779void seek_error_details(char const *name, off_t offset);
2780
2781int sys_truncate(int fd);
2782
2783size_t
2784blocking_write(int fd, void const *buf, size_t count);
2785
2786static enum oldgnu_add_status
2787oldgnu_add_sparse(struct tar_sparse_file *file, struct sparse *s);
2788
2789static void
2790sparse_add_map(struct tar_stat_info *st, struct sp_array const *sp);
2791
2792void *
2793x2nrealloc(void *p, size_t *pn, size_t s);
2794
2795static bool
2796decode_num(uintmax_t *num, char const *arg, uintmax_t maxval);
2797
2798static bool
2799pax_dump_header_0(struct tar_sparse_file *file);
2800
2801static bool
2802pax_dump_header_1(struct tar_sparse_file *file);
2803
2804static bool
2805star_fixup_header(struct tar_sparse_file *file);
2806
2807static bool
2808star_get_sparse_info(struct tar_sparse_file *file);
2809
2810void skip_file(off_t size);
2811
2812static bool
2813tar_sparse_done(struct tar_sparse_file *file);
2814
2815bool sparse_member_p(struct tar_stat_info *st);
2816
2817static bool
2818tar_sparse_member_p(struct tar_sparse_file *file);
2819
2820bool sparse_fixup_header(struct tar_stat_info *st);
2821
2822static bool
2823tar_sparse_fixup_header(struct tar_sparse_file *file);
2824
2826
2831static bool
2832tar_sparse_fixup_header(struct tar_sparse_file *file)
2833{
2834 if (file->optab->fixup_header)
2835 return file->optab->fixup_header(file);
2836 return true;
2837}
2838
2844{
2845 struct tar_sparse_file file;
2846
2847 if (!tar_sparse_init(&file))
2848 return false;
2849 file.stat_info = st;
2850 return tar_sparse_fixup_header(&file);
2851}
2852
2857static bool
2858tar_sparse_member_p(struct tar_sparse_file *file)
2859{
2860 if (file->optab->sparse_member_p)
2861 return file->optab->sparse_member_p(file);
2862 return false;
2863}
2864
2870{
2871 struct tar_sparse_file file;
2872
2873 if (!tar_sparse_init(&file))
2874 return false;
2875 file.stat_info = st;
2876 return tar_sparse_member_p(&file);
2877}
2878
2883static bool
2884tar_sparse_done(struct tar_sparse_file *file)
2885{
2886 if (file->optab->done)
2887 return file->optab->done(file);
2888 return true;
2889}
2890
2895static bool
2896tar_sparse_decode_header(struct tar_sparse_file *file)
2897{
2898 if (file->optab->decode_header)
2899 return file->optab->decode_header(file);
2900 return true;
2901}
2902
2903/* Convert STAR format sparse data to internal representation */
2904
2909static bool
2910star_get_sparse_info(struct tar_sparse_file *file)
2911{
2912 size_t i;
2913 union block *h = current_header;
2914 int ext_p;
2915 enum oldgnu_add_status rc = add_ok;
2916
2917 file->stat_info->sparse_map_avail = 0;
2918
2919 if (h->star_in_header.prefix[0] == '\0' && h->star_in_header.sp[0].offset[10] != '\0')
2920 {
2921 /* Old star format */
2922 for (i = 0; i < SPARSES_IN_STAR_HEADER; i++)
2923 {
2924 rc = oldgnu_add_sparse(file, &h->star_in_header.sp[i]);
2925 if (rc != add_ok)
2926 break;
2927 }
2928 ext_p = h->star_in_header.isextended;
2929 }
2930 else
2931 ext_p = 1;
2932
2933 for (; rc == add_ok && ext_p; ext_p = h->star_ext_header.isextended)
2934 {
2935 h = find_next_block();
2936 if (!h)
2937 {
2938 /*
2939 ERROR ((0, 0, _("Unexpected EOF in archive")));
2940 */
2941
2942 pedro_dprintf(2, "Unexpected EOF in archive");
2943 printf("Unexpected EOF in archive");
2944 return false;
2945 }
2947 for (i = 0; i < SPARSES_IN_STAR_EXT_HEADER && rc == add_ok; i++)
2948 rc = oldgnu_add_sparse(file, &h->star_ext_header.sp[i]);
2949 file->dumped_size += BLOCKSIZE;
2950 }
2951
2952 if (rc == add_fail)
2953 {
2954 /*
2955 ERROR ((0, 0, _("%s: invalid sparse archive member"),
2956 file->stat_info->orig_file_name));
2957 */
2958
2959 pedro_dprintf(2, "%s: Invalid sparse archive member", file->stat_info->orig_file_name);
2960 printf("%s: Invalid sparse archive member", file->stat_info->orig_file_name);
2961 return false;
2962 }
2963 return true;
2964}
2965
2970static bool
2971star_fixup_header(struct tar_sparse_file *file)
2972{
2973 /* NOTE! st_size was initialized from the header
2974 which actually contains archived size. The following fixes it */
2976
2977 file->stat_info->archive_file_size = file->stat_info->stat.st_size;
2978 file->stat_info->stat.st_size = max(0, realsize); //what is this?!!! kkkkkkkk...
2979 return 0 <= realsize;
2980}
2981
2982/* Star */
2983
2988static bool
2989star_sparse_member_p(struct tar_sparse_file *file __attribute__((unused)))
2990{
2992}
2993
2998void xheader_store(char const *keyword, struct tar_stat_info *st,
2999 void const *data)
3000{
3001 struct xhdr_tab const *t;
3002
3003 if (st->xhdr.buffer)
3004 return;
3005 t = locate_handler(keyword);
3006 if (!t || !t->coder)
3007 return;
3009 return;
3010 xheader_init(&st->xhdr);
3011 if (!xheader_keyword_override_p(keyword))
3012 t->coder(st, keyword, &st->xhdr, data);
3013}
3014
3019static bool
3020pax_dump_header_1(struct tar_sparse_file *file)
3021{
3022#if 1
3023 off_t block_ordinal = current_block_ordinal();
3024 union block *blk;
3025 char *p, *q;
3026 size_t i;
3027 char nbuf[UINTMAX_STRSIZE_BOUND];
3028 off_t size = 0;
3029 struct sp_array *map = file->stat_info->sparse_map;
3030 char *save_file_name = file->stat_info->file_name;
3031
3032#define COPY_STRING(b, dst, src) \
3033 do \
3034 { \
3035 char *endp = b->buffer + BLOCKSIZE; \
3036 char const *srcp = src; \
3037 while (*srcp) \
3038 { \
3039 if (dst == endp) \
3040 { \
3041 set_next_block_after(b); \
3042 b = find_next_block(); \
3043 dst = b->buffer; \
3044 endp = b->buffer + BLOCKSIZE; \
3045 } \
3046 *dst++ = *srcp++; \
3047 } \
3048 } while (0)
3049
3050 /* Compute stored file size */
3051 p = umaxtostr(file->stat_info->sparse_map_avail, nbuf);
3052 size += strlen(p) + 1;
3053 for (i = 0; i < file->stat_info->sparse_map_avail; i++)
3054 {
3055 p = umaxtostr(map[i].offset, nbuf);
3056 size += strlen(p) + 1;
3057 p = umaxtostr(map[i].numbytes, nbuf);
3058 size += strlen(p) + 1;
3059 }
3060 size = (size + BLOCKSIZE - 1) / BLOCKSIZE;
3061 file->stat_info->archive_file_size += size * BLOCKSIZE;
3062 file->dumped_size += size * BLOCKSIZE;
3063
3064 /* Store sparse file identification */
3065 xheader_store("GNU.sparse.major", file->stat_info, NULL);
3066 xheader_store("GNU.sparse.minor", file->stat_info, NULL);
3067 xheader_store("GNU.sparse.name", file->stat_info, NULL);
3068 xheader_store("GNU.sparse.realsize", file->stat_info, NULL);
3069
3070 file->stat_info->file_name =
3071 xheader_format_name(file->stat_info, "%d/GNUSparseFile.%p/%f", 0);
3072 /* Make sure the created header name is shorter than NAME_FIELD_SIZE: */
3073 if (strlen(file->stat_info->file_name) > NAME_FIELD_SIZE)
3074 file->stat_info->file_name[NAME_FIELD_SIZE] = 0;
3075
3076 blk = pax_start_header(file->stat_info);
3077 finish_header(file->stat_info, blk, block_ordinal);
3078 free(file->stat_info->file_name);
3079 file->stat_info->file_name = save_file_name;
3080
3081 blk = find_next_block();
3082 q = blk->buffer;
3083 p = umaxtostr(file->stat_info->sparse_map_avail, nbuf);
3084 COPY_STRING(blk, q, p);
3085 COPY_STRING(blk, q, "\n");
3086 for (i = 0; i < file->stat_info->sparse_map_avail; i++)
3087 {
3088 p = umaxtostr(map[i].offset, nbuf);
3089 COPY_STRING(blk, q, p);
3090 COPY_STRING(blk, q, "\n");
3091 p = umaxtostr(map[i].numbytes, nbuf);
3092 COPY_STRING(blk, q, p);
3093 COPY_STRING(blk, q, "\n");
3094 }
3095 memset(q, 0, BLOCKSIZE - (q - blk->buffer));
3097 return true;
3098#endif
3099 return false;
3100}
3101
3106static bool
3107pax_dump_header_0(struct tar_sparse_file *file)
3108{
3109#if 1
3110 off_t block_ordinal = current_block_ordinal();
3111 union block *blk;
3112 size_t i;
3113 char nbuf[UINTMAX_STRSIZE_BOUND];
3114 struct sp_array *map = file->stat_info->sparse_map;
3115 char *save_file_name = NULL;
3116
3117 /* Store the real file size */
3118 xheader_store("GNU.sparse.size", file->stat_info, NULL);
3119 xheader_store("GNU.sparse.numblocks", file->stat_info, NULL);
3120
3121 if (xheader_keyword_deleted_p("GNU.sparse.map") || tar_sparse_minor == 0)
3122 {
3123 for (i = 0; i < file->stat_info->sparse_map_avail; i++)
3124 {
3125 xheader_store("GNU.sparse.offset", file->stat_info, &i);
3126 xheader_store("GNU.sparse.numbytes", file->stat_info, &i);
3127 }
3128 }
3129 else
3130 {
3131 xheader_store("GNU.sparse.name", file->stat_info, NULL);
3132 save_file_name = file->stat_info->file_name;
3133 file->stat_info->file_name = xheader_format_name(file->stat_info,
3134 "%d/GNUSparseFile.%p/%f", 0);
3135
3136 xheader_string_begin(&file->stat_info->xhdr);
3137 for (i = 0; i < file->stat_info->sparse_map_avail; i++)
3138 {
3139 if (i)
3140 xheader_string_add(&file->stat_info->xhdr, ",");
3141 xheader_string_add(&file->stat_info->xhdr,
3142 umaxtostr(map[i].offset, nbuf));
3143 xheader_string_add(&file->stat_info->xhdr, ",");
3144 xheader_string_add(&file->stat_info->xhdr,
3145 umaxtostr(map[i].numbytes, nbuf));
3146 }
3147 if (!xheader_string_end(&file->stat_info->xhdr,
3148 "GNU.sparse.map"))
3149 {
3150 free(file->stat_info->file_name);
3151 file->stat_info->file_name = save_file_name;
3152 return false;
3153 }
3154 }
3155 blk = pax_start_header(file->stat_info);
3156 finish_header(file->stat_info, blk, block_ordinal);
3157 if (save_file_name)
3158 {
3159 free(file->stat_info->file_name);
3160 file->stat_info->file_name = save_file_name;
3161 }
3162 return true;
3163#endif
3164
3165 return false;
3166}
3167
3172static bool
3173decode_num(uintmax_t *num, char const *arg, uintmax_t maxval)
3174{
3175 uintmax_t u;
3176 char *arg_lim;
3177
3178 if (!ISDIGIT(*arg))
3179 return false;
3180
3181 errno = 0;
3182 u = strtoumax(arg, &arg_lim, 10);
3183
3184 if (!(u <= maxval && errno != ERANGE) || *arg_lim)
3185 return false;
3186
3187 *num = u;
3188 return true;
3189}
3190
3195static bool
3196pax_decode_header(struct tar_sparse_file *file)
3197{
3198 if (file->stat_info->sparse_major > 0)
3199 {
3200 uintmax_t u;
3201 char nbuf[5000];
3202 union block *blk;
3203 char *p;
3204 size_t i;
3205 off_t start;
3206
3207#define COPY_BUF(b, buf, src) \
3208 do \
3209 { \
3210 char *endp = b->buffer + BLOCKSIZE; \
3211 char *dst = buf; \
3212 do \
3213 { \
3214 if (dst == buf + 5000 - 1) \
3215 { \
3216 printf("%s: numeric overflow in sparse archive member", \
3217 file->stat_info->orig_file_name); \
3218 return false; \
3219 } \
3220 if (src == endp) \
3221 { \
3222 set_next_block_after(b); \
3223 b = find_next_block(); \
3224 if (!b) \
3225 printf("Unexpected EOF in archive"); \
3226 src = b->buffer; \
3227 endp = b->buffer + BLOCKSIZE; \
3228 } \
3229 *dst = *src++; \
3230 } while (*dst++ != '\n'); \
3231 dst[-1] = 0; \
3232 } while (0)
3233
3236 blk = find_next_block();
3237 if (!blk)
3238 {
3239 //FATAL_ERROR ((0, 0, _("Unexpected EOF in archive")));
3240
3241 pedro_dprintf(2, "Unexpected EOF in archive");
3242 printf("Unexpected EOF in archive");
3243 }
3244 p = blk->buffer;
3245 COPY_BUF(blk, nbuf, p);
3246 if (!decode_num(&u, nbuf, TYPE_MAXIMUM(size_t)))
3247 {
3248 /*
3249 ERROR ((0, 0, _("%s: malformed sparse archive member"),
3250 file->stat_info->orig_file_name));*/
3251
3252 pedro_dprintf(2, "%s: malformed sparse archive member", file->stat_info->orig_file_name);
3253 printf("%s: malformed sparse archive member", file->stat_info->orig_file_name);
3254
3255 return false;
3256 }
3257 file->stat_info->sparse_map_size = u;
3258 file->stat_info->sparse_map = calloc(file->stat_info->sparse_map_size,
3259 sizeof(*file->stat_info->sparse_map));
3260 file->stat_info->sparse_map_avail = 0;
3261 for (i = 0; i < file->stat_info->sparse_map_size; i++)
3262 {
3263 struct sp_array sp;
3264
3265 COPY_BUF(blk, nbuf, p);
3266 if (!decode_num(&u, nbuf, TYPE_MAXIMUM(off_t)))
3267 {
3268 /*
3269 ERROR ((0, 0, _("%s: malformed sparse archive member"),
3270 file->stat_info->orig_file_name));*/
3271
3272 pedro_dprintf(2, "%s: malformed sparse archive member", file->stat_info->orig_file_name);
3273 printf("%s: malformed sparse archive member", file->stat_info->orig_file_name);
3274
3275 return false;
3276 }
3277 sp.offset = u;
3278 COPY_BUF(blk, nbuf, p);
3279 if (!decode_num(&u, nbuf, TYPE_MAXIMUM(off_t)))
3280 {
3281 /*
3282 ERROR ((0, 0, _("%s: malformed sparse archive member"),
3283 file->stat_info->orig_file_name));
3284 */
3285
3286 pedro_dprintf(2, "%s: malformed sparse archive member", file->stat_info->orig_file_name);
3287 printf("%s: malformed sparse archive member", file->stat_info->orig_file_name);
3288
3289 return false;
3290 }
3291 sp.numbytes = u;
3292 sparse_add_map(file->stat_info, &sp);
3293 }
3295
3296 file->dumped_size += BLOCKSIZE * (current_block_ordinal() - start);
3297 }
3298
3299 return true;
3300}
3301
3306static bool
3307pax_dump_header(struct tar_sparse_file *file)
3308{
3309 file->stat_info->sparse_major = tar_sparse_major;
3310 file->stat_info->sparse_minor = tar_sparse_minor;
3311
3312 return (file->stat_info->sparse_major == 0) ? pax_dump_header_0(file) : pax_dump_header_1(file);
3313}
3314
3319static bool
3320pax_sparse_member_p(struct tar_sparse_file *file)
3321{
3322 return file->stat_info->sparse_map_avail > 0 || file->stat_info->sparse_major > 0;
3323}
3324
3329void *
3330x2nrealloc(void *p, size_t *pn, size_t s)
3331{
3332 size_t n = *pn;
3333
3334 if (!p)
3335 {
3336 if (!n)
3337 {
3338 /* The approximate size to use for initial small allocation
3339 requests, when the invoking code specifies an old size of
3340 zero. This is the largest "small" request for the GNU C
3341 library malloc. */
3342 enum
3343 {
3344 DEFAULT_MXFAST = 64 * sizeof(size_t) / 4
3345 };
3346
3347 n = DEFAULT_MXFAST / s;
3348 n += !n;
3349 }
3350 if (xalloc_oversized(n, s))
3351 {
3352 assert(0 && "nao pode acontecer");
3353 }
3354 }
3355 else
3356 {
3357 /* Set N = floor (1.5 * N) + 1 so that progress is made even if N == 0.
3358 Check for overflow, so that N * S stays in both ptrdiff_t and
3359 size_t range. The check may be slightly conservative, but an
3360 exact check isn't worth the trouble. */
3361 if ((PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX) / 3 * 2 / s <= n)
3362 {
3363 assert(0 && "nao pode acontecer");
3364 }
3365 n += n / 2 + 1;
3366 }
3367
3368 *pn = n;
3369 return realloc(p, n * s);
3370}
3371
3376static void
3377sparse_add_map(struct tar_stat_info *st, struct sp_array const *sp)
3378{
3379 struct sp_array *sparse_map = st->sparse_map;
3380 size_t avail = st->sparse_map_avail;
3381
3382 if (avail == st->sparse_map_size)
3383 st->sparse_map = sparse_map =
3384 x2nrealloc(sparse_map, &st->sparse_map_size, sizeof *sparse_map);
3385 sparse_map[avail] = *sp;
3386 st->sparse_map_avail = avail + 1;
3387}
3388
3389/* Add a sparse item to the sparse file and its obstack */
3390
3395static enum oldgnu_add_status
3396oldgnu_add_sparse(struct tar_sparse_file *file, struct sparse *s)
3397{
3398 struct sp_array sp;
3399
3400 if (s->numbytes[0] == '\0')
3401 return add_finish;
3402 sp.offset = OFF_FROM_HEADER(s->offset);
3404 if (sp.offset < 0 || sp.numbytes < 0 || INT_ADD_OVERFLOW(sp.offset, sp.numbytes) || file->stat_info->stat.st_size < sp.offset + sp.numbytes || file->stat_info->archive_file_size < 0)
3405 return add_fail;
3406
3407 sparse_add_map(file->stat_info, &sp);
3408 return add_ok;
3409}
3410
3411/* Write to FD from the buffer BUF with COUNT bytes. Do a full write.
3412 Wait until an output buffer is available; this matters because
3413 files are opened O_NONBLOCK for security reasons, and on some file
3414 systems this can cause write to fail with errno == EAGAIN. Return
3415 the actual number of bytes written, setting errno if that is less
3416 than COUNT. */
3417
3422size_t
3423blocking_write(int fd, void const *buf, size_t count)
3424{
3425 //assert(0 && "nao pode chamar esta funcao");
3426
3427#if 1
3428 size_t bytes = write(fd, buf, count);
3429
3430#if defined F_SETFL && O_NONBLOCK
3431#error nao pode chegar aqui
3432 if (bytes < count && errno == EAGAIN)
3433 {
3434 int flags = fcntl(fd, F_GETFL);
3435 if (0 <= flags && flags & O_NONBLOCK && fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) != -1)
3436 {
3437 char const *buffer = buf;
3438 bytes += full_write(fd, buffer + bytes, count - bytes);
3439 }
3440 }
3441#endif
3442
3443 return bytes;
3444#endif
3445
3446 return 0;
3447}
3448
3453int sys_truncate(int fd)
3454{
3455 return write(fd, "", 0);
3456}
3457
3462void seek_error_details(char const *name, off_t offset)
3463{
3464#if 0
3466 int e = errno;
3467 ERROR((0, e, _("%s: Cannot seek to %s"),
3468 quotearg_colon(name),
3470#endif
3471 pedro_dprintf(2, "%s: Cannot seek to %lld", name, (__int64)offset);
3472 printf("%s: Cannot seek to %lld", name, (__int64)offset);
3473}
3474
3479void seek_warn_details(char const *name, off_t offset)
3480{
3481#if 0
3483 int e = errno;
3484 WARN((0, e, _("%s: Warning: Cannot seek to %s"),
3485 quotearg_colon(name),
3487#endif
3488
3489 pedro_dprintf(2, "%s: Warning: Cannot seek to %lld", name, (__int64)offset);
3490 printf("%s: Warning: Cannot seek to %lld", name, (__int64)offset);
3491}
3492
3497void seek_diag_details(char const *name, off_t offset)
3498{
3500 {
3503 }
3504 else
3506}
3507
3508/* Dump zeros to file->fd until offset is reached. It is used instead of
3509 lseek if the output file is not seekable */
3510
3515static bool
3516dump_zeros(struct tar_sparse_file *file, off_t offset)
3517{
3518 static char const zero_buf[BLOCKSIZE];
3519
3521 {
3522 errno = EINVAL;
3523 return false;
3524 }
3525
3526 while (file->offset < offset)
3527 {
3528 size_t size = (BLOCKSIZE < offset - file->offset
3529 ? BLOCKSIZE
3530 : offset - file->offset);
3531 ssize_t wrbytes;
3532
3533 wrbytes = write(file->fd, zero_buf, size);
3534 if (wrbytes <= 0)
3535 {
3536 if (wrbytes == 0)
3537 errno = EINVAL;
3538 return false;
3539 }
3540 file->offset += wrbytes;
3541 }
3542
3543 return true;
3544}
3545
3550static bool
3551lseek_or_error(struct tar_sparse_file *file, off_t offset)
3552{
3553 if (file->seekable
3554 ? lseek(file->fd, offset, SEEK_SET) < 0
3555 : !dump_zeros(file, offset))
3556 {
3557 seek_diag_details(file->stat_info->orig_file_name, offset);
3558 return false;
3559 }
3560 return true;
3561}
3562
3567static bool
3568sparse_extract_region(struct tar_sparse_file *file, size_t i)
3569{
3570 off_t write_size;
3571
3572 if (!lseek_or_error(file, file->stat_info->sparse_map[i].offset))
3573 return false;
3574
3575 write_size = file->stat_info->sparse_map[i].numbytes;
3576
3577 if (write_size == 0)
3578 {
3579 /* Last block of the file is a hole */
3580 if (file->seekable && sys_truncate(file->fd))
3581 {
3582 //truncate_warn (file->stat_info->orig_file_name);
3583
3584 pedro_dprintf(2, "Error truncating file %s\n", file->stat_info->orig_file_name);
3585 printf("Error truncating file %s\n", file->stat_info->orig_file_name);
3586 }
3587 }
3588 else
3589 while (write_size > 0)
3590 {
3591 size_t count;
3592 size_t wrbytes = (write_size > BLOCKSIZE) ? BLOCKSIZE : write_size;
3593 union block *blk = find_next_block();
3594 if (!blk)
3595 {
3596 //ERROR ((0, 0, _("Unexpected EOF in archive")));
3597
3598 pedro_dprintf(2, "Unexpected EOF in archive");
3599 printf("Unexpected EOF in archive");
3600
3601 return false;
3602 }
3604 file->dumped_size += BLOCKSIZE;
3605 count = blocking_write(file->fd, blk->buffer, wrbytes);
3606 write_size -= count;
3607 mv_size_left(file->stat_info->archive_file_size - file->dumped_size);
3608 file->offset += count;
3609 if (count != wrbytes)
3610 {
3611 /*
3612 write_error_details (file->stat_info->orig_file_name,
3613 count, wrbytes);
3614 */
3615 return false;
3616 }
3617 }
3618 return true;
3619}
3620
3625static bool
3626sparse_dump_region(struct tar_sparse_file *file, size_t i)
3627{
3628 union block *blk;
3629 off_t bytes_left = file->stat_info->sparse_map[i].numbytes;
3630
3631 if (!lseek_or_error(file, file->stat_info->sparse_map[i].offset))
3632 return false;
3633
3634 while (bytes_left > 0)
3635 {
3636 size_t bufsize = (bytes_left > BLOCKSIZE) ? BLOCKSIZE : bytes_left;
3637 size_t bytes_read;
3638
3639 blk = find_next_block();
3640 bytes_read = read(file->fd, blk->buffer, bufsize);
3641 if (-1 == (int)bytes_read)
3642 {
3643 /*
3644 read_diag_details (file->stat_info->orig_file_name,
3645 (file->stat_info->sparse_map[i].offset
3646 + file->stat_info->sparse_map[i].numbytes
3647 - bytes_left),
3648 bufsize);
3649 */
3650 return false;
3651 }
3652 else if (bytes_read == 0)
3653 {
3654#if 0
3656 struct stat st;
3657 size_t n;
3658 if (fstat(file->fd, &st) == 0)
3659 n = file->stat_info->stat.st_size - st.st_size;
3660 else
3661 n = file->stat_info->stat.st_size
3662 - (file->stat_info->sparse_map[i].offset
3663 + file->stat_info->sparse_map[i].numbytes
3664 - bytes_left);
3665
3667 (0, 0,
3668 ngettext("%s: File shrank by %s byte; padding with zeros",
3669 "%s: File shrank by %s bytes; padding with zeros",
3670 n),
3671 quotearg_colon(file->stat_info->orig_file_name),
3672 STRINGIFY_BIGINT(n, buf)));
3674 set_exit_status(TAREXIT_DIFFERS);
3675#endif
3676 return false;
3677 }
3678
3679 memset(blk->buffer + bytes_read, 0, BLOCKSIZE - bytes_read);
3680 bytes_left -= bytes_read;
3681 file->dumped_size += bytes_read;
3683 }
3684
3685 return true;
3686}
3687
3688/* Convert old GNU format sparse data to internal representation */
3689
3694static bool
3695oldgnu_get_sparse_info(struct tar_sparse_file *file)
3696{
3697 size_t i;
3698 union block *h = current_header;
3699 int ext_p;
3700 enum oldgnu_add_status rc;
3701
3702 file->stat_info->sparse_map_avail = 0;
3703 for (i = 0; i < SPARSES_IN_OLDGNU_HEADER; i++)
3704 {
3705 rc = oldgnu_add_sparse(file, &h->oldgnu_header.sp[i]);
3706 if (rc != add_ok)
3707 break;
3708 }
3709
3710 for (ext_p = h->oldgnu_header.isextended;
3711 rc == add_ok && ext_p; ext_p = h->sparse_header.isextended)
3712 {
3713 h = find_next_block();
3714 if (!h)
3715 {
3716 //ERROR ((0, 0, _("Unexpected EOF in archive")));
3717
3718 pedro_dprintf(2, "Unexpected EOF in archive");
3719 printf("Unexpected EOF in archive");
3720
3721 return false;
3722 }
3724 for (i = 0; i < SPARSES_IN_SPARSE_HEADER && rc == add_ok; i++)
3725 rc = oldgnu_add_sparse(file, &h->sparse_header.sp[i]);
3726 }
3727
3728 if (rc == add_fail)
3729 {
3730 /*
3731 ERROR ((0, 0, _("%s: invalid sparse archive member"),
3732 file->stat_info->orig_file_name));
3733 */
3734 pedro_dprintf(2, "%s: invalid sparse archive member", file->stat_info->orig_file_name);
3735 printf("%s: invalid sparse archive member", file->stat_info->orig_file_name);
3736
3737 return false;
3738 }
3739 return true;
3740}
3741
3746static bool
3747oldgnu_fixup_header(struct tar_sparse_file *file)
3748{
3749 /* NOTE! st_size was initialized from the header
3750 which actually contains archived size. The following fixes it */
3752
3753 file->stat_info->archive_file_size = file->stat_info->stat.st_size;
3754 file->stat_info->stat.st_size = max(0, realsize);
3755 return 0 <= realsize;
3756}
3757
3762static bool
3763oldgnu_dump_header(struct tar_sparse_file *file)
3764{
3765#if 1
3766 off_t block_ordinal = current_block_ordinal();
3767 union block *blk;
3768 size_t i;
3769
3770 blk = start_header(file->stat_info);
3772 if (file->stat_info->sparse_map_avail > SPARSES_IN_OLDGNU_HEADER)
3773 blk->oldgnu_header.isextended = 1;
3774
3775 /* Store the real file size */
3776 OFF_TO_CHARS(file->stat_info->stat.st_size, blk->oldgnu_header.realsize);
3777 /* Store the effective (shrunken) file size */
3778 OFF_TO_CHARS(file->stat_info->archive_file_size, blk->header.size);
3779
3780 i = 0;
3781 oldgnu_store_sparse_info(file, &i,
3782 blk->oldgnu_header.sp,
3784 blk->oldgnu_header.isextended = i < file->stat_info->sparse_map_avail;
3785 finish_header(file->stat_info, blk, block_ordinal);
3786
3787 while (i < file->stat_info->sparse_map_avail)
3788 {
3789 blk = find_next_block();
3790 memset(blk->buffer, 0, BLOCKSIZE);
3791 oldgnu_store_sparse_info(file, &i,
3792 blk->sparse_header.sp,
3794 if (i < file->stat_info->sparse_map_avail)
3795 blk->sparse_header.isextended = 1;
3797 }
3798#endif
3799 return true;
3800}
3801
3806static bool
3807oldgnu_sparse_member_p(struct tar_sparse_file *file __attribute__((unused)))
3808{
3810}
3811
3816static bool
3817sparse_select_optab(struct tar_sparse_file *file)
3818{
3820 {
3821 case V7_FORMAT:
3822 case USTAR_FORMAT:
3823 return false;
3824
3825 case OLDGNU_FORMAT:
3826 case GNU_FORMAT: /*FIXME: This one should disappear? */
3827 file->optab = &oldgnu_optab;
3828 break;
3829
3830 case POSIX_FORMAT:
3831 file->optab = &pax_optab;
3832 break;
3833
3834 case STAR_FORMAT:
3835 file->optab = &star_optab;
3836 break;
3837
3838 default:
3839 return false;
3840 }
3841 return true;
3842}
3843
3848static bool
3849tar_sparse_init(struct tar_sparse_file *file)
3850{
3851 memset(file, 0, sizeof *file);
3852
3853 if (!sparse_select_optab(file))
3854 return false;
3855
3856 if (file->optab->init)
3857 return file->optab->init(file);
3858
3859 return true;
3860}
3861
3866enum dump_status
3868{
3869 bool rc = true;
3870 struct tar_sparse_file file;
3871
3872 if (!tar_sparse_init(&file))
3874
3875 file.stat_info = st;
3876 file.fd = -1;
3877
3878 rc = tar_sparse_decode_header(&file);
3879 skip_file(file.stat_info->archive_file_size - file.dumped_size);
3880 return (tar_sparse_done(&file) && rc) ? dump_status_ok : dump_status_short;
3881}
3882//finished at 15:03:29 2021/03/18 by amanda & MathMan
static const void * data
Definition XzCrc64.c:50
static const void size_t const UInt64 * table
Definition XzCrc64.c:50
void pedro_dprintf(int amanda_level, char *format,...)
Definition pedro.c:43
int start()
char * umaxtostr(uintmax_t i, char *buf)
Definition create_zen_ar.c:952
union block * write_short_name(struct tar_stat_info *st)
Definition create_zen_ar.c:1268
off_t current_block_ordinal(void)
Definition create_zen_ar.c:1213
#define assert(condition)
Definition lz4.c:273
char * dst
Definition lz4.h:833
const char * src
Definition lz4.h:866
char * dest
Definition lz4.h:806
#define __attribute__(unused_ric_since_2004)
Definition main_cr.c:84
file
Definition check_size.py:20
#define min(a, b)
Definition compress42.c:304
#define __PTR_ALIGN(B, P, A)
Definition obstack.h:146
#define _OBSTACK_SIZE_T
Definition obstack.h:128
#define obstack_alloc(h, length)
Definition obstack.h:510
#define obstack_blank(h, length)
Definition obstack.h:504
#define obstack_finish(h)
Definition obstack.h:519
#define obstack_free(h, obj)
Definition obstack.h:533
#define obstack_init(h)
Definition obstack.h:254
#define obstack_next_free(h)
Definition obstack.h:247
#define UNAME_TO_CHARS(name, buf)
Definition sparse_2_k.c:141
int owner_map_translate(uid_t uid, uid_t *new_uid, char const **new_name)
Definition sparse_2_k.c:1328
union block * write_extended(bool global, struct tar_stat_info *st, union block *old_header)
#define MODE_TO_CHARS(val, where)
Definition sparse_2_k.c:145
#define DEFAULT_ALIGNMENT
Definition sparse_2_k.c:34
bool hash_rehash(Hash_table *table, size_t candidate)
Definition sparse_2_k.c:1758
#define S_IXGRP
Definition sparse_2_k.c:153
oldgnu_add_status
Definition sparse_2_k.c:572
@ add_ok
Definition sparse_2_k.c:573
@ add_finish
Definition sparse_2_k.c:574
@ add_fail
Definition sparse_2_k.c:575
#define INT_ADD_OVERFLOW(a, b)
Definition sparse_2_k.c:568
sparse_scan_state
Definition sparse_2_k.c:579
@ scan_block
Definition sparse_2_k.c:581
@ scan_begin
Definition sparse_2_k.c:580
@ scan_end
Definition sparse_2_k.c:582
char * last_component(char const *name)
Definition sparse_2_k.c:866
GLOBAL unsigned tar_sparse_minor
Definition sparse_2_k.c:522
void * hash_insert(Hash_table *table, void const *entry)
Definition sparse_2_k.c:2132
void finish_header(struct tar_stat_info *st, union block *header, off_t block_ordinal)
size_t(* Hash_hasher)(const void *, size_t)
Definition sparse_2_k.c:204
#define PREFIX_FIELD_SIZE
Definition sparse_2_k.c:26
union block * start_header(struct tar_stat_info *st)
Definition sparse_2_k.c:1386
int hash_insert_if_absent(Hash_table *table, void const *entry, void const **matched_ent)
Definition sparse_2_k.c:2043
set_mtime_option_mode
Definition sparse_2_k.c:61
@ CLAMP_MTIME
Definition sparse_2_k.c:64
@ FORCE_MTIME
Definition sparse_2_k.c:63
@ USE_FILE_MTIME
Definition sparse_2_k.c:62
void * x2nrealloc(void *p, size_t *pn, size_t s)
Definition sparse_2_k.c:3330
void _obstack_newchunk(struct obstack *h, _OBSTACK_SIZE_T length)
Definition xheader_k.c:653
#define DEFAULT_ROUNDING
Definition sparse_2_k.c:37
#define STRINGIFY_BIGINT(i, b)
Definition sparse_2_k.c:171
char * dir_name(char const *file)
Definition sparse_2_k.c:2568
enum dump_status sparse_skip_file(struct tar_stat_info *st)
Definition sparse_2_k.c:3867
int hash_insert_if_absent_version_1_32(Hash_table *table, void const *entry, void const **matched_ent)
Definition sparse_2_k.c:1961
#define S_ISUID
Definition sparse_2_k.c:148
void * hash_lookup(const Hash_table *table, const void *entry)
Definition sparse_2_k.c:1273
size_t blocking_write(int fd, void const *buf, size_t count)
Definition sparse_2_k.c:3423
#define MAJOR_TO_CHARS(val, where)
Definition sparse_2_k.c:144
#define GNAME_FIELD_SIZE
Definition sparse_2_k.c:23
#define GNAME_TO_CHARS(name, buf)
Definition sparse_2_k.c:142
#define FILE_SYSTEM_PREFIX_LEN(P)
Definition sparse_2_k.c:109
void xheader_string_add(struct xheader *xhdr, char const *s)
Definition sparse_2_k.c:1071
int _obstack_begin(struct obstack *h, _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment, void *(*chunkfun)(size_t), void(*freefun)(void *))
Definition sparse_2_k.c:846
#define DEFAULT_GROWTH_FACTOR
Definition sparse_2_k.c:274
GLOBAL char const * group_name_option
Definition sparse_2_k.c:202
void xheader_finish(struct xheader *xhdr)
Definition sparse_2_k.c:992
#define S_IRGRP
Definition sparse_2_k.c:151
Hash_table * hash_initialize(size_t candidate, const Hash_tuning *tuning, Hash_hasher hasher, Hash_comparator comparator, Hash_data_freer data_freer)
Definition sparse_2_k.c:2361
void seek_warn_details(char const *name, off_t offset)
Definition sparse_2_k.c:3479
#define GLOBAL_HEADER_TEMPLATE
Definition sparse_2_k.c:28
bool xheader_keyword_deleted_p(const char *kw)
Definition xheader_k.c:488
#define MINOR_TO_CHARS(val, where)
Definition sparse_2_k.c:143
@ TIMESPEC_HZ
Definition sparse_2_k.c:58
const char * archive_format_string(enum archive_format fmt)
Definition sparse_2_k.c:702
GLOBAL struct mode_change * mode_option
Definition sparse_2_k.c:319
char * xheader_ghdr_name(void)
Definition sparse_2_k.c:971
void xheader_string_begin(struct xheader *xhdr)
Definition sparse_2_k.c:1084
void tar_name_copy_str(char *dst, const char *src, size_t len)
Definition create_zen_ar.c:1241
enum dump_status sparse_extract_file(int fd, struct tar_stat_info *st, off_t *size)
Definition sparse_2_k.c:2742
#define COPY_STRING(b, dst, src)
#define COPY_BUF(b, buf, src)
GLOBAL int selinux_context_option
Definition sparse_2_k.c:84
#define DEFAULT_SHRINK_FACTOR
Definition sparse_2_k.c:283
bool(* Hash_comparator)(const void *, const void *)
Definition sparse_2_k.c:205
GLOBAL unsigned tar_sparse_major
Definition sparse_2_k.c:521
#define UNAME_FIELD_SIZE
Definition sparse_2_k.c:22
@ MODE_DONE
Definition sparse_2_k.c:93
@ MODE_ORDINARY_CHANGE
Definition sparse_2_k.c:96
@ MODE_X_IF_ANY_X
Definition sparse_2_k.c:101
@ MODE_COPY_EXISTING
Definition sparse_2_k.c:106
bool xheader_string_end(struct xheader *xhdr, char const *keyword)
Definition sparse_2_k.c:1017
char * stpcpy(char *dest, const char *src)
Definition xheader_k.c:753
int gid_t
Definition sparse_2_k.c:116
void gid_to_gname(int gid, char **gname)
#define NAME_FIELD_SIZE
Definition sparse_2_k.c:25
GLOBAL struct timespec mtime_option
Definition sparse_2_k.c:321
mode_t mode_adjust(mode_t oldmode, bool dir, mode_t umask_value, struct mode_change const *changes, mode_t *pmode_bits)
Definition sparse_2_k.c:1185
void seek_error_details(char const *name, off_t offset)
Definition sparse_2_k.c:3462
GLOBAL bool absolute_names_option
Definition sparse_2_k.c:200
size_t hash_string(const char *string, size_t n_buckets)
Definition sparse_2_k.c:2197
size_t rotr_sz(size_t x, int n)
Definition sparse_2_k.c:2334
GLOBAL int acls_option
Definition sparse_2_k.c:87
void(* Hash_data_freer)(void *)
Definition sparse_2_k.c:206
void uid_to_uname(uid_t uid, char **uname)
bool(* Hash_processor)(void *, void *)
Definition sparse_2_k.c:207
void seek_diag_details(char const *name, off_t offset)
Definition sparse_2_k.c:3497
GLOBAL gid_t group_option
Definition sparse_2_k.c:199
union block * start_private_header(const char *name, size_t size, time_t t)
Definition sparse_2_k.c:896
#define S_ISGID
Definition sparse_2_k.c:149
#define UID_TO_CHARS(val, where)
Definition sparse_2_k.c:146
GLOBAL mode_t initial_umask
Definition sparse_2_k.c:203
void skip_file(off_t size)
Definition tar_1_33.c:4709
#define CHMOD_MODE_BITS
Definition sparse_2_k.c:168
GLOBAL char const * owner_name_option
Definition sparse_2_k.c:201
void simple_finish_header(union block *header)
Definition create_zen_ar.c:743
#define xalloc_oversized(n, s)
Definition sparse_2_k.c:557
void xheader_write(char type, char *name, time_t t, struct xheader *xhdr)
Definition sparse_2_k.c:919
#define DEFAULT_GROWTH_THRESHOLD
Definition sparse_2_k.c:273
GLOBAL enum set_mtime_option_mode set_mtime_option
Definition sparse_2_k.c:78
#define ISSLASH(C)
Definition sparse_2_k.c:110
bool off_to_chars(off_t v, char *p, size_t s)
Definition create_zen_ar.c:1152
char * mdir_name(char const *file)
#define ISDIGIT(c)
Definition sparse_2_k.c:555
bool time_to_chars(time_t v, char *p, size_t s)
Definition create_zen_ar.c:886
#define OFF_TO_CHARS(val, where)
Definition sparse_2_k.c:188
int group_map_translate(gid_t gid, gid_t *new_gid, char const **new_name)
Definition sparse_2_k.c:1292
char * safer_name_suffix(char const *file_name, bool link_target, bool absolute_names)
Definition sparse_2_k.c:2465
#define MAX_OCTAL_VAL(buffer)
Definition sparse_2_k.c:186
char * xheader_format_name(struct tar_stat_info *st, const char *fmt, size_t n)
Definition sparse_2_k.c:2597
GLOBAL int xattrs_option
Definition sparse_2_k.c:81
void xheader_store(char const *keyword, struct tar_stat_info *st, void const *data)
Definition sparse_2_k.c:2998
#define DEFAULT_SHRINK_THRESHOLD
Definition sparse_2_k.c:282
#define TIME_TO_CHARS(val, where)
Definition sparse_2_k.c:189
GLOBAL uid_t owner_option
Definition sparse_2_k.c:198
bool string_ascii_p(char const *p)
Definition create_zen_ar.c:790
int timespec_cmp(struct timespec a, struct timespec b)
Definition sparse_2_k.c:1152
#define GID_TO_CHARS(val, where)
Definition sparse_2_k.c:147
int sys_truncate(int fd)
Definition sparse_2_k.c:3453
#define MODE_ALL
Definition sparse_2_k.c:163
#define S_IWGRP
Definition sparse_2_k.c:152
bool sparse_fixup_header(struct tar_stat_info *st)
Definition sparse_2_k.c:2843
int uid_t
Definition sparse_2_k.c:117
bool sparse_member_p(struct tar_stat_info *st)
Definition sparse_2_k.c:2869
char buf[N_BUF]
Definition spewG.c:36
Definition obstack.h:168
char * limit
Definition obstack.h:169
struct _obstack_chunk * prev
Definition obstack.h:170
Definition poolTests.c:28
Definition sparse_2_k.c:216
void * data
Definition sparse_2_k.c:217
struct hash_entry * next
Definition sparse_2_k.c:218
Definition sparse_2_k.c:222
size_t n_entries
Definition sparse_2_k.c:230
size_t n_buckets_used
Definition sparse_2_k.c:229
Hash_comparator comparator
Definition sparse_2_k.c:241
size_t n_buckets
Definition sparse_2_k.c:228
struct hash_entry const * bucket_limit
Definition sparse_2_k.c:227
Hash_hasher hasher
Definition sparse_2_k.c:240
const Hash_tuning * tuning
Definition sparse_2_k.c:233
struct hash_entry * free_entry_list
Definition sparse_2_k.c:245
Hash_data_freer data_freer
Definition sparse_2_k.c:242
struct hash_entry * bucket
Definition sparse_2_k.c:226
Definition sparse_2_k.c:256
float growth_threshold
Definition sparse_2_k.c:262
bool is_n_buckets
Definition sparse_2_k.c:264
float shrink_factor
Definition sparse_2_k.c:261
float shrink_threshold
Definition sparse_2_k.c:260
float growth_factor
Definition sparse_2_k.c:263
Definition tar_1_33.c:3105
char * value
Definition tar_1_33.c:3108
struct keyword_list * next
Definition tar_1_33.c:3106
char * pattern
Definition tar_1_33.c:3107
Definition sparse_2_k.c:301
uintmax_t orig_id
Definition sparse_2_k.c:302
char * new_name
Definition sparse_2_k.c:304
uintmax_t new_id
Definition sparse_2_k.c:303
Definition sparse_2_k.c:311
char flag
Definition sparse_2_k.c:313
char op
Definition sparse_2_k.c:312
mode_t mentioned
Definition sparse_2_k.c:316
mode_t value
Definition sparse_2_k.c:315
mode_t affected
Definition sparse_2_k.c:314
Definition obstack.h:175
char isextended
Definition tar.h:149
char realsize[12]
Definition tar.h:151
struct sparse sp[SPARSES_IN_OLDGNU_HEADER]
Definition tar.h:147
Definition tar.h:25
char typeflag
Definition tar.h:33
char size[12]
Definition tar.h:30
Definition tar.h:265
off_t numbytes
Definition tar.h:267
off_t offset
Definition tar.h:266
char isextended
Definition tar.h:126
struct sparse sp[SPARSES_IN_SPARSE_HEADER]
Definition tar.h:124
Definition tar.h:98
char numbytes[12]
Definition tar.h:100
char offset[12]
Definition tar.h:99
char realsize[12]
Definition tar.h:228
Definition sparse_2_k.c:324
struct tar_sparse_optab const * optab
Definition sparse_2_k.c:332
struct tar_stat_info * stat_info
Definition sparse_2_k.c:331
bool seekable
Definition sparse_2_k.c:326
int fd
Definition sparse_2_k.c:325
off_t dumped_size
Definition sparse_2_k.c:329
off_t offset
Definition sparse_2_k.c:327
void * closure
Definition sparse_2_k.c:333
Definition sparse_2_k.c:586
bool(* scan_block)(struct tar_sparse_file *, enum sparse_scan_state, void *)
Definition sparse_2_k.c:593
bool(* dump_header)(struct tar_sparse_file *)
Definition sparse_2_k.c:590
bool(* sparse_member_p)(struct tar_sparse_file *)
Definition sparse_2_k.c:589
bool(* decode_header)(struct tar_sparse_file *)
Definition sparse_2_k.c:592
bool(* dump_region)(struct tar_sparse_file *, size_t)
Definition sparse_2_k.c:595
bool(* fixup_header)(struct tar_sparse_file *)
Definition sparse_2_k.c:591
bool(* init)(struct tar_sparse_file *)
Definition sparse_2_k.c:587
bool(* done)(struct tar_sparse_file *)
Definition sparse_2_k.c:588
bool(* extract_region)(struct tar_sparse_file *, size_t)
Definition sparse_2_k.c:596
Definition tar.h:287
char * acls_a_ptr
Definition tar.h:300
struct sp_array * sparse_map
Definition tar.h:326
char * gname
Definition tar.h:296
struct xheader xhdr
Definition tar.h:340
size_t sparse_map_avail
Definition tar.h:322
size_t sparse_map_size
Definition tar.h:325
off_t archive_file_size
Definition tar.h:314
char * acls_d_ptr
Definition tar.h:303
char * file_name
Definition tar.h:289
struct xattr_array * xattr_map
Definition tar.h:337
struct _stat stat
Definition tar.h:306
char * orig_file_name
Definition tar.h:288
struct timespec mtime
Definition tar.h:311
struct timespec ctime
Definition tar.h:312
char * uname
Definition tar.h:295
char * cntx_name
Definition tar.h:298
struct timespec atime
Definition tar.h:310
Definition tar.h:280
char * xkey
Definition tar.h:281
Definition tar_1_33.c:3051
void(* coder)(struct tar_stat_info const *, char const *, struct xheader *, void const *data)
Definition tar_1_33.c:3053
char const * keyword
Definition tar_1_33.c:3052
Definition tar.h:271
struct obstack * stk
Definition tar.h:272
size_t size
Definition tar.h:273
uintmax_t string_length
Definition tar.h:275
char * buffer
Definition tar.h:274
#define TVERSLEN
Definition tar.h:48
#define SPARSES_IN_STAR_EXT_HEADER
Definition tar.h:218
#define SPARSES_IN_STAR_HEADER
Definition tar.h:217
#define XHDTYPE
Definition tar.h:61
#define TMAGIC
Definition tar.h:45
#define SPARSES_IN_SPARSE_HEADER
Definition tar.h:115
#define TMAGLEN
Definition tar.h:46
#define SPARSES_IN_OLDGNU_HEADER
Definition tar.h:114
#define GNUTYPE_SPARSE
Definition tar.h:184
#define REGTYPE
Definition tar.h:51
#define TVERSION
Definition tar.h:47
archive_format
Definition tar.h:251
@ GNU_FORMAT
Definition tar.h:258
@ OLDGNU_FORMAT
Definition tar.h:254
@ DEFAULT_FORMAT
Definition tar.h:252
@ POSIX_FORMAT
Definition tar.h:256
@ STAR_FORMAT
Definition tar.h:257
@ USTAR_FORMAT
Definition tar.h:255
@ V7_FORMAT
Definition tar.h:253
#define AREGTYPE
Definition tar.h:52
#define OLDGNU_MAGIC
Definition tar.h:159
#define XGLTYPE
Definition tar.h:62
#define BLOCKSIZE
Definition tar.h:248
#define S_IROTH
Definition tar_1_33.c:4891
GLOBAL bool incremental_option
Definition tar_1_33.c:3298
#define WARNOPT(opt, args)
Definition tar_1_33.c:3280
char * xstrdup(char const *string)
Safe strdup() that never returns NULL.
Definition tar_1_33.c:3038
enum archive_format current_format
Definition tar_1_33.c:3161
#define WARNING_ENABLED(opt)
Definition tar_1_33.c:3278
void set_next_block_after(union block *block)
Definition tar_1_33.c:5178
#define GLOBAL
Definition tar_1_33.c:3287
#define S_IXOTH
Definition tar_1_33.c:4917
#define OFF_FROM_HEADER(where)
Definition tar_1_33.c:3242
#define WARN_FILE_SHRANK
Definition tar_1_33.c:3252
void assign_string(char **string, const char *value)
Definition tar_1_33.c:5155
#define S_IWOTH
Definition tar_1_33.c:4904
#define UINTMAX_STRSIZE_BOUND
Definition tar_1_33.c:543
#define xmalloc
Definition tar_1_33.c:545
#define S_IRUSR
Definition tar_1_33.c:4885
#define minor_t
Definition tar_1_33.c:663
#define WARN_FAILED_READ
Definition tar_1_33.c:3268
#define major(device)
Definition tar_1_33.c:658
union block * find_next_block(void)
Definition tar_1_33.c:6798
#define TYPE_MAXIMUM(t)
Definition tar_1_33.c:3237
GLOBAL bool ignore_failed_read_option
Definition tar_1_33.c:3294
GLOBAL bool numeric_owner_option
Definition tar_1_33.c:3300
#define S_IWUSR
Definition tar_1_33.c:4898
union block * current_header
Definition tar_1_33.c:3201
dump_status
Definition tar_1_33.c:3095
@ dump_status_ok
Definition tar_1_33.c:3096
@ dump_status_not_implemented
Definition tar_1_33.c:3099
@ dump_status_short
Definition tar_1_33.c:3097
void xheader_destroy(struct xheader *xhdr)
Definition tar_1_33.c:3546
void mv_size_left(off_t size)
Definition tar_1_33.c:4699
#define minor(device)
Definition tar_1_33.c:659
#define S_IXUSR
Definition tar_1_33.c:4911
#define major_t
Definition tar_1_33.c:662
Definition tar.h:373
struct posix_header header
Definition tar.h:375
char buffer[BLOCKSIZE]
Definition tar.h:374
struct star_in_header star_in_header
Definition tar.h:379
struct oldgnu_header oldgnu_header
Definition tar.h:377
struct sparse_header sparse_header
Definition tar.h:378
Definition compress42.c:551
#define assume(R)
Definition verify.h:280
size_t size
Definition platform.h:559
#define SEEK_SET
Definition zconf.h:498
#define const
Definition zconf.h:230
#define b(i)
Definition sha256.c:42
#define c(i)
Definition sha256.c:43
#define a(i)
Definition sha256.c:41
#define h(i)
Definition sha256.c:48
#define e(i)
Definition sha256.c:45
void set_exit_status(enum exit_status_type new_status)
Definition main.c:31
uint32_t flags
Definition container.h:628
lzma_index ** i
Definition index.h:629
#define NULL
Definition getopt1.c:37
#define _(msgid)
Definition getopt.c:49
#define bool
Definition sysdefs.h:146
#define ngettext(msgid1, msgid2, n)
Definition tuklib_gettext.h:40
static uint32_t const uint8_t uint32_t len
Definition memcmplen.h:44
char name[NAME_LEN_MAX+1]
Name of the filter.
Definition string_conversion.c:450
#define header(is_bt, len_min, ret_op)
Definition lz_encoder_mf.c:191
const char * str
Table column heading string.
Definition list.c:109
#define fail(test)
Definition tests.h:31
const char * fmt
Definition message.h:50
#define EINVAL
Definition errno.h:13
#define ERROR(name)
Definition zstdseek_compress.c:27