source: trunk/essentials/app-arch/tar/src/create.c

Last change on this file was 3342, checked in by bird, 18 years ago

tar 1.16.1

File size: 44.4 KB
Line 
1/* Create a tar archive.
2
3 Copyright (C) 1985, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
4 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5
6 Written by John Gilmore, on 1985-08-25.
7
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 Public License for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
21
22#include <system.h>
23
24#include <quotearg.h>
25
26#include "common.h"
27#include <hash.h>
28
29struct link
30 {
31 dev_t dev;
32 ino_t ino;
33 size_t nlink;
34 char name[1];
35 };
36
37struct exclude_tag
38{
39 const char *name;
40 size_t length;
41 struct exclude_tag *next;
42};
43
44static struct exclude_tag *exclude_tags;
45
46void
47add_exclude_tag (const char *name)
48{
49 struct exclude_tag *tag = xmalloc (sizeof tag[0]);
50 tag->next = exclude_tags;
51 tag->name = name;
52 tag->length = strlen (name);
53 exclude_tags = tag;
54}
55
56static bool
57check_exclude_tags (char *dirname)
58{
59 static char *tagname;
60 static size_t tagsize;
61 struct exclude_tag *tag;
62 size_t dlen = strlen (dirname);
63 char *nptr = NULL;
64 char *ret = NULL;
65
66 for (tag = exclude_tags; tag; tag = tag->next)
67 {
68 size_t size = dlen + tag->length + 1;
69 if (size > tagsize)
70 {
71 tagsize = size;
72 tagname = xrealloc (tagname, tagsize);
73 }
74
75 if (!nptr)
76 {
77 strcpy (tagname, dirname);
78 nptr = tagname + dlen;
79 }
80 strcpy (nptr, tag->name);
81 if (access (tagname, F_OK) == 0)
82 {
83 if (verbose_option)
84 WARN ((0, 0,
85 _("%s: contains a cache directory tag %s; not dumped"),
86 quotearg_colon (dirname),
87 quotearg_n (1, tag->name)));
88 return true;
89 }
90 }
91
92 return false;
93}
94
95
96
97/* The maximum uintmax_t value that can be represented with DIGITS digits,
98 assuming that each digit is BITS_PER_DIGIT wide. */
99#define MAX_VAL_WITH_DIGITS(digits, bits_per_digit) \
100 ((digits) * (bits_per_digit) < sizeof (uintmax_t) * CHAR_BIT \
101 ? ((uintmax_t) 1 << ((digits) * (bits_per_digit))) - 1 \
102 : (uintmax_t) -1)
103
104/* The maximum uintmax_t value that can be represented with octal
105 digits and a trailing NUL in BUFFER. */
106#define MAX_OCTAL_VAL(buffer) MAX_VAL_WITH_DIGITS (sizeof (buffer) - 1, LG_8)
107
108/* Convert VALUE to an octal representation suitable for tar headers.
109 Output to buffer WHERE with size SIZE.
110 The result is undefined if SIZE is 0 or if VALUE is too large to fit. */
111
112static void
113to_octal (uintmax_t value, char *where, size_t size)
114{
115 uintmax_t v = value;
116 size_t i = size;
117
118 do
119 {
120 where[--i] = '0' + (v & ((1 << LG_8) - 1));
121 v >>= LG_8;
122 }
123 while (i);
124}
125
126/* Copy at most LEN bytes from the string SRC to DST. Terminate with
127 NUL unless SRC is LEN or more bytes long. */
128
129static void
130tar_copy_str (char *dst, const char *src, size_t len)
131{
132 size_t i;
133 for (i = 0; i < len; i++)
134 if (! (dst[i] = src[i]))
135 break;
136}
137
138/* Same as tar_copy_str, but always terminate with NUL if using
139 is OLDGNU format */
140
141static void
142tar_name_copy_str (char *dst, const char *src, size_t len)
143{
144 tar_copy_str (dst, src, len);
145 if (archive_format == OLDGNU_FORMAT)
146 dst[len-1] = 0;
147}
148
149/* Convert NEGATIVE VALUE to a base-256 representation suitable for
150 tar headers. NEGATIVE is 1 if VALUE was negative before being cast
151 to uintmax_t, 0 otherwise. Output to buffer WHERE with size SIZE.
152 The result is undefined if SIZE is 0 or if VALUE is too large to
153 fit. */
154
155static void
156to_base256 (int negative, uintmax_t value, char *where, size_t size)
157{
158 uintmax_t v = value;
159 uintmax_t propagated_sign_bits =
160 ((uintmax_t) - negative << (CHAR_BIT * sizeof v - LG_256));
161 size_t i = size;
162
163 do
164 {
165 where[--i] = v & ((1 << LG_256) - 1);
166 v = propagated_sign_bits | (v >> LG_256);
167 }
168 while (i);
169}
170
171
172static bool
173to_chars (int negative, uintmax_t value, size_t valsize,
174 uintmax_t (*substitute) (int *),
175 char *where, size_t size, const char *type);
176
177static bool
178to_chars_subst (int negative, int gnu_format, uintmax_t value, size_t valsize,
179 uintmax_t (*substitute) (int *),
180 char *where, size_t size, const char *type)
181{
182 uintmax_t maxval = (gnu_format
183 ? MAX_VAL_WITH_DIGITS (size - 1, LG_256)
184 : MAX_VAL_WITH_DIGITS (size - 1, LG_8));
185 char valbuf[UINTMAX_STRSIZE_BOUND + 1];
186 char maxbuf[UINTMAX_STRSIZE_BOUND];
187 char minbuf[UINTMAX_STRSIZE_BOUND + 1];
188 char const *minval_string;
189 char const *maxval_string = STRINGIFY_BIGINT (maxval, maxbuf);
190 char const *value_string;
191
192 if (gnu_format)
193 {
194 uintmax_t m = maxval + 1 ? maxval + 1 : maxval / 2 + 1;
195 char *p = STRINGIFY_BIGINT (m, minbuf + 1);
196 *--p = '-';
197 minval_string = p;
198 }
199 else
200 minval_string = "0";
201
202 if (negative)
203 {
204 char *p = STRINGIFY_BIGINT (- value, valbuf + 1);
205 *--p = '-';
206 value_string = p;
207 }
208 else
209 value_string = STRINGIFY_BIGINT (value, valbuf);
210
211 if (substitute)
212 {
213 int negsub;
214 uintmax_t sub = substitute (&negsub) & maxval;
215 /* NOTE: This is one of the few places where GNU_FORMAT differs from
216 OLDGNU_FORMAT. The actual differences are:
217
218 1. In OLDGNU_FORMAT all strings in a tar header end in \0
219 2. Incremental archives use oldgnu_header.
220
221 Apart from this they are completely identical. */
222 uintmax_t s = (negsub &= archive_format == GNU_FORMAT) ? - sub : sub;
223 char subbuf[UINTMAX_STRSIZE_BOUND + 1];
224 char *sub_string = STRINGIFY_BIGINT (s, subbuf + 1);
225 if (negsub)
226 *--sub_string = '-';
227 WARN ((0, 0, _("value %s out of %s range %s..%s; substituting %s"),
228 value_string, type, minval_string, maxval_string,
229 sub_string));
230 return to_chars (negsub, s, valsize, 0, where, size, type);
231 }
232 else
233 ERROR ((0, 0, _("value %s out of %s range %s..%s"),
234 value_string, type, minval_string, maxval_string));
235 return false;
236}
237
238/* Convert NEGATIVE VALUE (which was originally of size VALSIZE) to
239 external form, using SUBSTITUTE (...) if VALUE won't fit. Output
240 to buffer WHERE with size SIZE. NEGATIVE is 1 iff VALUE was
241 negative before being cast to uintmax_t; its original bitpattern
242 can be deduced from VALSIZE, its original size before casting.
243 TYPE is the kind of value being output (useful for diagnostics).
244 Prefer the POSIX format of SIZE - 1 octal digits (with leading zero
245 digits), followed by '\0'. If this won't work, and if GNU or
246 OLDGNU format is allowed, use '\200' followed by base-256, or (if
247 NEGATIVE is nonzero) '\377' followed by two's complement base-256.
248 If neither format works, use SUBSTITUTE (...) instead. Pass to
249 SUBSTITUTE the address of an 0-or-1 flag recording whether the
250 substitute value is negative. */
251
252static bool
253to_chars (int negative, uintmax_t value, size_t valsize,
254 uintmax_t (*substitute) (int *),
255 char *where, size_t size, const char *type)
256{
257 int gnu_format = (archive_format == GNU_FORMAT
258 || archive_format == OLDGNU_FORMAT);
259
260 /* Generate the POSIX octal representation if the number fits. */
261 if (! negative && value <= MAX_VAL_WITH_DIGITS (size - 1, LG_8))
262 {
263 where[size - 1] = '\0';
264 to_octal (value, where, size - 1);
265 return true;
266 }
267 else if (gnu_format)
268 {
269 /* Try to cope with the number by using traditional GNU format
270 methods */
271
272 /* Generate the base-256 representation if the number fits. */
273 if (((negative ? -1 - value : value)
274 <= MAX_VAL_WITH_DIGITS (size - 1, LG_256)))
275 {
276 where[0] = negative ? -1 : 1 << (LG_256 - 1);
277 to_base256 (negative, value, where + 1, size - 1);
278 return true;
279 }
280
281 /* Otherwise, if the number is negative, and if it would not cause
282 ambiguity on this host by confusing positive with negative
283 values, then generate the POSIX octal representation of the value
284 modulo 2**(field bits). The resulting tar file is
285 machine-dependent, since it depends on the host word size. Yuck!
286 But this is the traditional behavior. */
287 else if (negative && valsize * CHAR_BIT <= (size - 1) * LG_8)
288 {
289 static int warned_once;
290 if (! warned_once)
291 {
292 warned_once = 1;
293 WARN ((0, 0, _("Generating negative octal headers")));
294 }
295 where[size - 1] = '\0';
296 to_octal (value & MAX_VAL_WITH_DIGITS (valsize * CHAR_BIT, 1),
297 where, size - 1);
298 return true;
299 }
300 /* Otherwise fall back to substitution, if possible: */
301 }
302 else
303 substitute = NULL; /* No substitution for formats, other than GNU */
304
305 return to_chars_subst (negative, gnu_format, value, valsize, substitute,
306 where, size, type);
307}
308
309static uintmax_t
310gid_substitute (int *negative)
311{
312 gid_t r;
313#ifdef GID_NOBODY
314 r = GID_NOBODY;
315#else
316 static gid_t gid_nobody;
317 if (!gid_nobody && !gname_to_gid ("nobody", &gid_nobody))
318 gid_nobody = -2;
319 r = gid_nobody;
320#endif
321 *negative = r < 0;
322 return r;
323}
324
325bool
326gid_to_chars (gid_t v, char *p, size_t s)
327{
328 return to_chars (v < 0, (uintmax_t) v, sizeof v, gid_substitute, p, s, "gid_t");
329}
330
331bool
332major_to_chars (major_t v, char *p, size_t s)
333{
334 return to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "major_t");
335}
336
337bool
338minor_to_chars (minor_t v, char *p, size_t s)
339{
340 return to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "minor_t");
341}
342
343bool
344mode_to_chars (mode_t v, char *p, size_t s)
345{
346 /* In the common case where the internal and external mode bits are the same,
347 and we are not using POSIX or GNU format,
348 propagate all unknown bits to the external mode.
349 This matches historical practice.
350 Otherwise, just copy the bits we know about. */
351 int negative;
352 uintmax_t u;
353 if (S_ISUID == TSUID && S_ISGID == TSGID && S_ISVTX == TSVTX
354 && S_IRUSR == TUREAD && S_IWUSR == TUWRITE && S_IXUSR == TUEXEC
355 && S_IRGRP == TGREAD && S_IWGRP == TGWRITE && S_IXGRP == TGEXEC
356 && S_IROTH == TOREAD && S_IWOTH == TOWRITE && S_IXOTH == TOEXEC
357 && archive_format != POSIX_FORMAT
358 && archive_format != USTAR_FORMAT
359 && archive_format != GNU_FORMAT
360 && archive_format != OLDGNU_FORMAT)
361 {
362 negative = v < 0;
363 u = v;
364 }
365 else
366 {
367 negative = 0;
368 u = ((v & S_ISUID ? TSUID : 0)
369 | (v & S_ISGID ? TSGID : 0)
370 | (v & S_ISVTX ? TSVTX : 0)
371 | (v & S_IRUSR ? TUREAD : 0)
372 | (v & S_IWUSR ? TUWRITE : 0)
373 | (v & S_IXUSR ? TUEXEC : 0)
374 | (v & S_IRGRP ? TGREAD : 0)
375 | (v & S_IWGRP ? TGWRITE : 0)
376 | (v & S_IXGRP ? TGEXEC : 0)
377 | (v & S_IROTH ? TOREAD : 0)
378 | (v & S_IWOTH ? TOWRITE : 0)
379 | (v & S_IXOTH ? TOEXEC : 0));
380 }
381 return to_chars (negative, u, sizeof v, 0, p, s, "mode_t");
382}
383
384bool
385off_to_chars (off_t v, char *p, size_t s)
386{
387 return to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "off_t");
388}
389
390bool
391size_to_chars (size_t v, char *p, size_t s)
392{
393 return to_chars (0, (uintmax_t) v, sizeof v, 0, p, s, "size_t");
394}
395
396bool
397time_to_chars (time_t v, char *p, size_t s)
398{
399 return to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "time_t");
400}
401
402static uintmax_t
403uid_substitute (int *negative)
404{
405 uid_t r;
406#ifdef UID_NOBODY
407 r = UID_NOBODY;
408#else
409 static uid_t uid_nobody;
410 if (!uid_nobody && !uname_to_uid ("nobody", &uid_nobody))
411 uid_nobody = -2;
412 r = uid_nobody;
413#endif
414 *negative = r < 0;
415 return r;
416}
417
418bool
419uid_to_chars (uid_t v, char *p, size_t s)
420{
421 return to_chars (v < 0, (uintmax_t) v, sizeof v, uid_substitute, p, s, "uid_t");
422}
423
424bool
425uintmax_to_chars (uintmax_t v, char *p, size_t s)
426{
427 return to_chars (0, v, sizeof v, 0, p, s, "uintmax_t");
428}
429
430void
431string_to_chars (char const *str, char *p, size_t s)
432{
433 tar_copy_str (p, str, s);
434 p[s - 1] = '\0';
435}
436
437
438
439/* A file is considered dumpable if it is sparse and both --sparse and --totals
440 are specified.
441 Otherwise, it is dumpable unless any of the following conditions occur:
442
443 a) it is empty *and* world-readable, or
444 b) current archive is /dev/null */
445
446bool
447file_dumpable_p (struct tar_stat_info *st)
448{
449 if (dev_null_output)
450 return totals_option && sparse_option && ST_IS_SPARSE (st->stat);
451 return !(st->archive_file_size == 0
452 && (st->stat.st_mode & MODE_R) == MODE_R);
453}
454
455
456
457/* Writing routines. */
458
459/* Write the EOT block(s). Zero at least two blocks, through the end
460 of the record. Old tar, as previous versions of GNU tar, writes
461 garbage after two zeroed blocks. */
462void
463write_eot (void)
464{
465 union block *pointer = find_next_block ();
466 memset (pointer->buffer, 0, BLOCKSIZE);
467 set_next_block_after (pointer);
468 pointer = find_next_block ();
469 memset (pointer->buffer, 0, available_space_after (pointer));
470 set_next_block_after (pointer);
471}
472
473/* Write a "private" header */
474union block *
475start_private_header (const char *name, size_t size)
476{
477 time_t t;
478 union block *header = find_next_block ();
479
480 memset (header->buffer, 0, sizeof (union block));
481
482 tar_name_copy_str (header->header.name, name, NAME_FIELD_SIZE);
483 OFF_TO_CHARS (size, header->header.size);
484
485 time (&t);
486 TIME_TO_CHARS (t, header->header.mtime);
487 MODE_TO_CHARS (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, header->header.mode);
488 UID_TO_CHARS (getuid (), header->header.uid);
489 GID_TO_CHARS (getgid (), header->header.gid);
490 MAJOR_TO_CHARS (0, header->header.devmajor);
491 MINOR_TO_CHARS (0, header->header.devminor);
492 strncpy (header->header.magic, TMAGIC, TMAGLEN);
493 strncpy (header->header.version, TVERSION, TVERSLEN);
494 return header;
495}
496
497/* Create a new header and store there at most NAME_FIELD_SIZE bytes of
498 the file name */
499
500static union block *
501write_short_name (struct tar_stat_info *st)
502{
503 union block *header = find_next_block ();
504 memset (header->buffer, 0, sizeof (union block));
505 tar_name_copy_str (header->header.name, st->file_name, NAME_FIELD_SIZE);
506 return header;
507}
508
509#define FILL(field,byte) do { \
510 memset(field, byte, sizeof(field)-1); \
511 (field)[sizeof(field)-1] = 0; \
512} while (0)
513
514/* Write a GNUTYPE_LONGLINK or GNUTYPE_LONGNAME block. */
515static void
516write_gnu_long_link (struct tar_stat_info *st, const char *p, char type)
517{
518 size_t size = strlen (p) + 1;
519 size_t bufsize;
520 union block *header;
521 char *tmpname;
522
523 header = start_private_header ("././@LongLink", size);
524 FILL(header->header.mtime, '0');
525 FILL(header->header.mode, '0');
526 FILL(header->header.uid, '0');
527 FILL(header->header.gid, '0');
528 FILL(header->header.devmajor, 0);
529 FILL(header->header.devminor, 0);
530 uid_to_uname (0, &tmpname);
531 UNAME_TO_CHARS (tmpname, header->header.uname);
532 free (tmpname);
533 gid_to_gname (0, &tmpname);
534 GNAME_TO_CHARS (tmpname, header->header.gname);
535 free (tmpname);
536
537 strcpy (header->header.magic, OLDGNU_MAGIC);
538 header->header.typeflag = type;
539 finish_header (st, header, -1);
540
541 header = find_next_block ();
542
543 bufsize = available_space_after (header);
544
545 while (bufsize < size)
546 {
547 memcpy (header->buffer, p, bufsize);
548 p += bufsize;
549 size -= bufsize;
550 set_next_block_after (header + (bufsize - 1) / BLOCKSIZE);
551 header = find_next_block ();
552 bufsize = available_space_after (header);
553 }
554 memcpy (header->buffer, p, size);
555 memset (header->buffer + size, 0, bufsize - size);
556 set_next_block_after (header + (size - 1) / BLOCKSIZE);
557}
558
559static size_t
560split_long_name (const char *name, size_t length)
561{
562 size_t i;
563
564 if (length > PREFIX_FIELD_SIZE)
565 length = PREFIX_FIELD_SIZE + 1;
566 for (i = length - 1; i > 0; i--)
567 if (ISSLASH (name[i]))
568 break;
569 return i;
570}
571
572static union block *
573write_ustar_long_name (const char *name)
574{
575 size_t length = strlen (name);
576 size_t i;
577 union block *header;
578
579 if (length > PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1)
580 {
581 ERROR ((0, 0, _("%s: file name is too long (max %d); not dumped"),
582 quotearg_colon (name),
583 PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1));
584 return NULL;
585 }
586
587 i = split_long_name (name, length);
588 if (i == 0 || length - i - 1 > NAME_FIELD_SIZE)
589 {
590 ERROR ((0, 0,
591 _("%s: file name is too long (cannot be split); not dumped"),
592 quotearg_colon (name)));
593 return NULL;
594 }
595
596 header = find_next_block ();
597 memset (header->buffer, 0, sizeof (header->buffer));
598 memcpy (header->header.prefix, name, i);
599 memcpy (header->header.name, name + i + 1, length - i - 1);
600
601 return header;
602}
603
604/* Write a long link name, depending on the current archive format */
605static void
606write_long_link (struct tar_stat_info *st)
607{
608 switch (archive_format)
609 {
610 case POSIX_FORMAT:
611 xheader_store ("linkpath", st, NULL);
612 break;
613
614 case V7_FORMAT: /* old V7 tar format */
615 case USTAR_FORMAT:
616 case STAR_FORMAT:
617 ERROR ((0, 0,
618 _("%s: link name is too long; not dumped"),
619 quotearg_colon (st->link_name)));
620 break;
621
622 case OLDGNU_FORMAT:
623 case GNU_FORMAT:
624 write_gnu_long_link (st, st->link_name, GNUTYPE_LONGLINK);
625 break;
626
627 default:
628 abort(); /*FIXME*/
629 }
630}
631
632static union block *
633write_long_name (struct tar_stat_info *st)
634{
635 switch (archive_format)
636 {
637 case POSIX_FORMAT:
638 xheader_store ("path", st, NULL);
639 break;
640
641 case V7_FORMAT:
642 if (strlen (st->file_name) > NAME_FIELD_SIZE-1)
643 {
644 ERROR ((0, 0, _("%s: file name is too long (max %d); not dumped"),
645 quotearg_colon (st->file_name),
646 NAME_FIELD_SIZE - 1));
647 return NULL;
648 }
649 break;
650
651 case USTAR_FORMAT:
652 case STAR_FORMAT:
653 return write_ustar_long_name (st->file_name);
654
655 case OLDGNU_FORMAT:
656 case GNU_FORMAT:
657 write_gnu_long_link (st, st->file_name, GNUTYPE_LONGNAME);
658 break;
659
660 default:
661 abort(); /*FIXME*/
662 }
663 return write_short_name (st);
664}
665
666union block *
667write_extended (bool global, struct tar_stat_info *st, union block *old_header)
668{
669 union block *header, hp;
670 char *p;
671 int type;
672
673 if (extended_header.buffer || extended_header.stk == NULL)
674 return old_header;
675
676 xheader_finish (&extended_header);
677 memcpy (hp.buffer, old_header, sizeof (hp));
678 if (global)
679 {
680 type = XGLTYPE;
681 p = xheader_ghdr_name ();
682 }
683 else
684 {
685 type = XHDTYPE;
686 p = xheader_xhdr_name (st);
687 }
688 xheader_write (type, p, &extended_header);
689 free (p);
690 header = find_next_block ();
691 memcpy (header, &hp.buffer, sizeof (hp.buffer));
692 return header;
693}
694
695static union block *
696write_header_name (struct tar_stat_info *st)
697{
698 if (archive_format == POSIX_FORMAT && !string_ascii_p (st->file_name))
699 {
700 xheader_store ("path", st, NULL);
701 return write_short_name (st);
702 }
703 else if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT)
704 < strlen (st->file_name))
705 return write_long_name (st);
706 else
707 return write_short_name (st);
708}
709
710
711
712/* Header handling. */
713
714/* Make a header block for the file whose stat info is st,
715 and return its address. */
716
717union block *
718start_header (struct tar_stat_info *st)
719{
720 union block *header;
721
722 header = write_header_name (st);
723 if (!header)
724 return NULL;
725
726 /* Override some stat fields, if requested to do so. */
727
728 if (owner_option != (uid_t) -1)
729 st->stat.st_uid = owner_option;
730 if (group_option != (gid_t) -1)
731 st->stat.st_gid = group_option;
732 if (mode_option)
733 st->stat.st_mode =
734 ((st->stat.st_mode & ~MODE_ALL)
735 | mode_adjust (st->stat.st_mode, S_ISDIR (st->stat.st_mode) != 0,
736 initial_umask, mode_option, NULL));
737
738 /* Paul Eggert tried the trivial test ($WRITER cf a b; $READER tvf a)
739 for a few tars and came up with the following interoperability
740 matrix:
741
742 WRITER
743 1 2 3 4 5 6 7 8 9 READER
744 . . . . . . . . . 1 = SunOS 4.2 tar
745 # . . # # . . # # 2 = NEC SVR4.0.2 tar
746 . . . # # . . # . 3 = Solaris 2.1 tar
747 . . . . . . . . . 4 = GNU tar 1.11.1
748 . . . . . . . . . 5 = HP-UX 8.07 tar
749 . . . . . . . . . 6 = Ultrix 4.1
750 . . . . . . . . . 7 = AIX 3.2
751 . . . . . . . . . 8 = Hitachi HI-UX 1.03
752 . . . . . . . . . 9 = Omron UNIOS-B 4.3BSD 1.60Beta
753
754 . = works
755 # = ``impossible file type''
756
757 The following mask for old archive removes the `#'s in column 4
758 above, thus making GNU tar both a universal donor and a universal
759 acceptor for Paul's test. */
760
761 if (archive_format == V7_FORMAT || archive_format == USTAR_FORMAT)
762 MODE_TO_CHARS (st->stat.st_mode & MODE_ALL, header->header.mode);
763 else
764 MODE_TO_CHARS (st->stat.st_mode, header->header.mode);
765
766 {
767 uid_t uid = st->stat.st_uid;
768 if (archive_format == POSIX_FORMAT
769 && MAX_OCTAL_VAL (header->header.uid) < uid)
770 {
771 xheader_store ("uid", st, NULL);
772 uid = 0;
773 }
774 if (!UID_TO_CHARS (uid, header->header.uid))
775 return NULL;
776 }
777
778 {
779 gid_t gid = st->stat.st_gid;
780 if (archive_format == POSIX_FORMAT
781 && MAX_OCTAL_VAL (header->header.gid) < gid)
782 {
783 xheader_store ("gid", st, NULL);
784 gid = 0;
785 }
786 if (!GID_TO_CHARS (gid, header->header.gid))
787 return NULL;
788 }
789
790 {
791 off_t size = st->stat.st_size;
792 if (archive_format == POSIX_FORMAT
793 && MAX_OCTAL_VAL (header->header.size) < size)
794 {
795 xheader_store ("size", st, NULL);
796 size = 0;
797 }
798 if (!OFF_TO_CHARS (size, header->header.size))
799 return NULL;
800 }
801
802 {
803 struct timespec mtime = set_mtime_option ? mtime_option : st->mtime;
804 if (archive_format == POSIX_FORMAT)
805 {
806 if (MAX_OCTAL_VAL (header->header.mtime) < mtime.tv_sec
807 || mtime.tv_nsec != 0)
808 xheader_store ("mtime", st, &mtime);
809 if (MAX_OCTAL_VAL (header->header.mtime) < mtime.tv_sec)
810 mtime.tv_sec = 0;
811 }
812 if (!TIME_TO_CHARS (mtime.tv_sec, header->header.mtime))
813 return NULL;
814 }
815
816 /* FIXME */
817 if (S_ISCHR (st->stat.st_mode)
818 || S_ISBLK (st->stat.st_mode))
819 {
820 major_t devmajor = major (st->stat.st_rdev);
821 minor_t devminor = minor (st->stat.st_rdev);
822
823 if (archive_format == POSIX_FORMAT
824 && MAX_OCTAL_VAL (header->header.devmajor) < devmajor)
825 {
826 xheader_store ("devmajor", st, NULL);
827 devmajor = 0;
828 }
829 if (!MAJOR_TO_CHARS (devmajor, header->header.devmajor))
830 return NULL;
831
832 if (archive_format == POSIX_FORMAT
833 && MAX_OCTAL_VAL (header->header.devminor) < devminor)
834 {
835 xheader_store ("devminor", st, NULL);
836 devminor = 0;
837 }
838 if (!MINOR_TO_CHARS (devminor, header->header.devminor))
839 return NULL;
840 }
841 else if (archive_format != GNU_FORMAT && archive_format != OLDGNU_FORMAT)
842 {
843 if (!(MAJOR_TO_CHARS (0, header->header.devmajor)
844 && MINOR_TO_CHARS (0, header->header.devminor)))
845 return NULL;
846 }
847
848 if (archive_format == POSIX_FORMAT)
849 {
850 xheader_store ("atime", st, NULL);
851 xheader_store ("ctime", st, NULL);
852 }
853 else if (incremental_option)
854 if (archive_format == OLDGNU_FORMAT || archive_format == GNU_FORMAT)
855 {
856 TIME_TO_CHARS (st->atime.tv_sec, header->oldgnu_header.atime);
857 TIME_TO_CHARS (st->ctime.tv_sec, header->oldgnu_header.ctime);
858 }
859
860 header->header.typeflag = archive_format == V7_FORMAT ? AREGTYPE : REGTYPE;
861
862 switch (archive_format)
863 {
864 case V7_FORMAT:
865 break;
866
867 case OLDGNU_FORMAT:
868 case GNU_FORMAT: /*FIXME?*/
869 /* Overwrite header->header.magic and header.version in one blow. */
870 strcpy (header->header.magic, OLDGNU_MAGIC);
871 break;
872
873 case POSIX_FORMAT:
874 case USTAR_FORMAT:
875 strncpy (header->header.magic, TMAGIC, TMAGLEN);
876 strncpy (header->header.version, TVERSION, TVERSLEN);
877 break;
878
879 default:
880 abort ();
881 }
882
883 if (archive_format == V7_FORMAT || numeric_owner_option)
884 {
885 /* header->header.[ug]name are left as the empty string. */
886 }
887 else
888 {
889 uid_to_uname (st->stat.st_uid, &st->uname);
890 gid_to_gname (st->stat.st_gid, &st->gname);
891
892 if (archive_format == POSIX_FORMAT
893 && (strlen (st->uname) > UNAME_FIELD_SIZE
894 || !string_ascii_p (st->uname)))
895 xheader_store ("uname", st, NULL);
896 UNAME_TO_CHARS (st->uname, header->header.uname);
897
898 if (archive_format == POSIX_FORMAT
899 && (strlen (st->gname) > GNAME_FIELD_SIZE
900 || !string_ascii_p (st->gname)))
901 xheader_store ("gname", st, NULL);
902 GNAME_TO_CHARS (st->gname, header->header.gname);
903 }
904
905 return header;
906}
907
908void
909simple_finish_header (union block *header)
910{
911 size_t i;
912 int sum;
913 char *p;
914
915 memcpy (header->header.chksum, CHKBLANKS, sizeof header->header.chksum);
916
917 sum = 0;
918 p = header->buffer;
919 for (i = sizeof *header; i-- != 0; )
920 /* We can't use unsigned char here because of old compilers, e.g. V7. */
921 sum += 0xFF & *p++;
922
923 /* Fill in the checksum field. It's formatted differently from the
924 other fields: it has [6] digits, a null, then a space -- rather than
925 digits, then a null. We use to_chars.
926 The final space is already there, from
927 checksumming, and to_chars doesn't modify it.
928
929 This is a fast way to do:
930
931 sprintf(header->header.chksum, "%6o", sum); */
932
933 uintmax_to_chars ((uintmax_t) sum, header->header.chksum, 7);
934
935 set_next_block_after (header);
936}
937
938/* Finish off a filled-in header block and write it out. We also
939 print the file name and/or full info if verbose is on. If BLOCK_ORDINAL
940 is not negative, is the block ordinal of the first record for this
941 file, which may be a preceding long name or long link record. */
942void
943finish_header (struct tar_stat_info *st,
944 union block *header, off_t block_ordinal)
945{
946 /* Note: It is important to do this before the call to write_extended(),
947 so that the actual ustar header is printed */
948 if (verbose_option
949 && header->header.typeflag != GNUTYPE_LONGLINK
950 && header->header.typeflag != GNUTYPE_LONGNAME
951 && header->header.typeflag != XHDTYPE
952 && header->header.typeflag != XGLTYPE)
953 {
954 /* These globals are parameters to print_header, sigh. */
955
956 current_header = header;
957 current_format = archive_format;
958 print_header (st, block_ordinal);
959 }
960
961 header = write_extended (false, st, header);
962 simple_finish_header (header);
963}
964
965
966
967void
968pad_archive (off_t size_left)
969{
970 union block *blk;
971 while (size_left > 0)
972 {
973 mv_size_left (size_left);
974 blk = find_next_block ();
975 memset (blk->buffer, 0, BLOCKSIZE);
976 set_next_block_after (blk);
977 size_left -= BLOCKSIZE;
978 }
979}
980
981static enum dump_status
982dump_regular_file (int fd, struct tar_stat_info *st)
983{
984 off_t size_left = st->stat.st_size;
985 off_t block_ordinal;
986 union block *blk;
987
988 block_ordinal = current_block_ordinal ();
989 blk = start_header (st);
990 if (!blk)
991 return dump_status_fail;
992
993 /* Mark contiguous files, if we support them. */
994 if (archive_format != V7_FORMAT && S_ISCTG (st->stat.st_mode))
995 blk->header.typeflag = CONTTYPE;
996
997 finish_header (st, blk, block_ordinal);
998
999 mv_begin (st);
1000 while (size_left > 0)
1001 {
1002 size_t bufsize, count;
1003
1004 mv_size_left (size_left);
1005
1006 blk = find_next_block ();
1007
1008 bufsize = available_space_after (blk);
1009
1010 if (size_left < bufsize)
1011 {
1012 /* Last read -- zero out area beyond. */
1013 bufsize = size_left;
1014 count = bufsize % BLOCKSIZE;
1015 if (count)
1016 memset (blk->buffer + size_left, 0, BLOCKSIZE - count);
1017 }
1018
1019 count = (fd < 0) ? bufsize : safe_read (fd, blk->buffer, bufsize);
1020 if (count == SAFE_READ_ERROR)
1021 {
1022 read_diag_details (st->orig_file_name,
1023 st->stat.st_size - size_left, bufsize);
1024 pad_archive (size_left);
1025 return dump_status_short;
1026 }
1027 size_left -= count;
1028 if (count)
1029 set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE);
1030
1031 if (count != bufsize)
1032 {
1033 char buf[UINTMAX_STRSIZE_BOUND];
1034 memset (blk->buffer + count, 0, bufsize - count);
1035 WARN ((0, 0,
1036 ngettext ("%s: File shrank by %s byte; padding with zeros",
1037 "%s: File shrank by %s bytes; padding with zeros",
1038 size_left),
1039 quotearg_colon (st->orig_file_name),
1040 STRINGIFY_BIGINT (size_left, buf)));
1041 if (! ignore_failed_read_option)
1042 exit_status = TAREXIT_DIFFERS;
1043 pad_archive (size_left - (bufsize-count));
1044 return dump_status_short;
1045 }
1046 }
1047 return dump_status_ok;
1048}
1049
1050
1051
1052/* Look in directory DIRNAME for a cache directory tag file
1053 with the magic name "CACHEDIR.TAG" and a standard header,
1054 as described at:
1055 http://www.brynosaurus.com/cachedir
1056 Applications can write this file into directories they create
1057 for use as caches containing purely regenerable, non-precious data,
1058 allowing us to avoid archiving them if --exclude-caches is specified. */
1059
1060#define CACHEDIR_SIGNATURE "Signature: 8a477f597d28d172789f06886806bc55"
1061#define CACHEDIR_SIGNATURE_SIZE (sizeof CACHEDIR_SIGNATURE - 1)
1062
1063static bool
1064check_cache_directory (char *dirname)
1065{
1066 static char tagname[] = "CACHEDIR.TAG";
1067 char *tagpath;
1068 int fd;
1069 bool tag_present = false;
1070
1071 tagpath = xmalloc (strlen (dirname) + strlen (tagname) + 1);
1072 strcpy (tagpath, dirname);
1073 strcat (tagpath, tagname);
1074
1075 fd = open (tagpath, O_RDONLY);
1076 if (fd >= 0)
1077 {
1078 static char tagbuf[CACHEDIR_SIGNATURE_SIZE];
1079
1080 if (read (fd, tagbuf, CACHEDIR_SIGNATURE_SIZE)
1081 == CACHEDIR_SIGNATURE_SIZE
1082 && memcmp (tagbuf, CACHEDIR_SIGNATURE, CACHEDIR_SIGNATURE_SIZE) == 0)
1083 tag_present = true;
1084
1085 close (fd);
1086 }
1087
1088 free (tagpath);
1089
1090 return tag_present;
1091}
1092
1093static void
1094dump_dir0 (char *directory,
1095 struct tar_stat_info *st, int top_level, dev_t parent_device)
1096{
1097 dev_t our_device = st->stat.st_dev;
1098
1099 if (!is_avoided_name (st->orig_file_name))
1100 {
1101 union block *blk = NULL;
1102 off_t block_ordinal = current_block_ordinal ();
1103 st->stat.st_size = 0; /* force 0 size on dir */
1104
1105 blk = start_header (st);
1106 if (!blk)
1107 return;
1108
1109 if (incremental_option && archive_format != POSIX_FORMAT)
1110 blk->header.typeflag = GNUTYPE_DUMPDIR;
1111 else /* if (standard_option) */
1112 blk->header.typeflag = DIRTYPE;
1113
1114 /* If we're gnudumping, we aren't done yet so don't close it. */
1115
1116 if (!incremental_option)
1117 finish_header (st, blk, block_ordinal);
1118 else if (gnu_list_name->dir_contents)
1119 {
1120 if (archive_format == POSIX_FORMAT)
1121 {
1122 xheader_store ("GNU.dumpdir", st, gnu_list_name->dir_contents);
1123 finish_header (st, blk, block_ordinal);
1124 }
1125 else
1126 {
1127 off_t size_left;
1128 off_t totsize;
1129 size_t bufsize;
1130 ssize_t count;
1131 const char *buffer, *p_buffer;
1132
1133 block_ordinal = current_block_ordinal ();
1134 buffer = gnu_list_name->dir_contents;
1135 if (buffer)
1136 totsize = dumpdir_size (buffer);
1137 else
1138 totsize = 0;
1139 OFF_TO_CHARS (totsize, blk->header.size);
1140 finish_header (st, blk, block_ordinal);
1141 p_buffer = buffer;
1142 size_left = totsize;
1143
1144 mv_begin (st);
1145 mv_total_size (totsize);
1146 while (size_left > 0)
1147 {
1148 mv_size_left (size_left);
1149 blk = find_next_block ();
1150 bufsize = available_space_after (blk);
1151 if (size_left < bufsize)
1152 {
1153 bufsize = size_left;
1154 count = bufsize % BLOCKSIZE;
1155 if (count)
1156 memset (blk->buffer + size_left, 0, BLOCKSIZE - count);
1157 }
1158 memcpy (blk->buffer, p_buffer, bufsize);
1159 size_left -= bufsize;
1160 p_buffer += bufsize;
1161 set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE);
1162 }
1163 mv_end ();
1164 }
1165 return;
1166 }
1167 }
1168
1169 if (!recursion_option)
1170 return;
1171
1172 if (one_file_system_option
1173 && !top_level
1174 && parent_device != st->stat.st_dev)
1175 {
1176 if (verbose_option)
1177 WARN ((0, 0,
1178 _("%s: file is on a different filesystem; not dumped"),
1179 quotearg_colon (st->orig_file_name)));
1180 return;
1181 }
1182
1183 {
1184 char const *entry;
1185 size_t entry_len;
1186 char *name_buf = xstrdup (st->orig_file_name);
1187 size_t name_size = strlen (name_buf);
1188 size_t name_len = name_size;
1189
1190 /* Now output all the files in the directory. */
1191 /* FIXME: Should speed this up by cd-ing into the dir. */
1192
1193 for (entry = directory; (entry_len = strlen (entry)) != 0;
1194 entry += entry_len + 1)
1195 {
1196 if (name_size < name_len + entry_len)
1197 {
1198 name_size = name_len + entry_len;
1199 name_buf = xrealloc (name_buf, name_size + 1);
1200 }
1201 strcpy (name_buf + name_len, entry);
1202 if (!excluded_name (name_buf))
1203 dump_file (name_buf, 0, our_device);
1204 }
1205
1206 free (name_buf);
1207 }
1208}
1209
1210/* Ensure exactly one trailing slash. */
1211static void
1212ensure_slash (char **pstr)
1213{
1214 size_t len = strlen (*pstr);
1215 while (len >= 1 && ISSLASH ((*pstr)[len - 1]))
1216 len--;
1217 if (!ISSLASH ((*pstr)[len]))
1218 *pstr = xrealloc (*pstr, len + 2);
1219 (*pstr)[len++] = '/';
1220 (*pstr)[len] = '\0';
1221}
1222
1223static bool
1224dump_dir (int fd, struct tar_stat_info *st, int top_level, dev_t parent_device)
1225{
1226 char *directory = fdsavedir (fd);
1227 if (!directory)
1228 {
1229 savedir_diag (st->orig_file_name);
1230 return false;
1231 }
1232
1233 dump_dir0 (directory, st, top_level, parent_device);
1234
1235 free (directory);
1236 return true;
1237}
1238
1239
1240
1241/* Main functions of this module. */
1242
1243void
1244create_archive (void)
1245{
1246 const char *p;
1247
1248 open_archive (ACCESS_WRITE);
1249 xheader_write_global ();
1250
1251 if (incremental_option)
1252 {
1253 size_t buffer_size = 1000;
1254 char *buffer = xmalloc (buffer_size);
1255 const char *q;
1256
1257 collect_and_sort_names ();
1258
1259 while ((p = name_from_list ()) != NULL)
1260 if (!excluded_name (p))
1261 dump_file (p, -1, (dev_t) 0);
1262
1263 blank_name_list ();
1264 while ((p = name_from_list ()) != NULL)
1265 if (!excluded_name (p))
1266 {
1267 size_t plen = strlen (p);
1268 if (buffer_size <= plen)
1269 {
1270 while ((buffer_size *= 2) <= plen)
1271 continue;
1272 buffer = xrealloc (buffer, buffer_size);
1273 }
1274 memcpy (buffer, p, plen);
1275 if (! ISSLASH (buffer[plen - 1]))
1276 buffer[plen++] = '/';
1277 q = gnu_list_name->dir_contents;
1278 if (q)
1279 while (*q)
1280 {
1281 size_t qlen = strlen (q);
1282 if (*q == 'Y')
1283 {
1284 if (buffer_size < plen + qlen)
1285 {
1286 while ((buffer_size *=2 ) < plen + qlen)
1287 continue;
1288 buffer = xrealloc (buffer, buffer_size);
1289 }
1290 strcpy (buffer + plen, q + 1);
1291 dump_file (buffer, -1, (dev_t) 0);
1292 }
1293 q += qlen + 1;
1294 }
1295 }
1296 free (buffer);
1297 }
1298 else
1299 {
1300 while ((p = name_next (1)) != NULL)
1301 if (!excluded_name (p))
1302 dump_file (p, 1, (dev_t) 0);
1303 }
1304
1305 write_eot ();
1306 close_archive ();
1307
1308 if (listed_incremental_option)
1309 write_directory_file ();
1310}
1311
1312
1313/* Calculate the hash of a link. */
1314static size_t
1315hash_link (void const *entry, size_t n_buckets)
1316{
1317 struct link const *l = entry;
1318 uintmax_t num = l->dev ^ l->ino;
1319 return num % n_buckets;
1320}
1321
1322/* Compare two links for equality. */
1323static bool
1324compare_links (void const *entry1, void const *entry2)
1325{
1326 struct link const *link1 = entry1;
1327 struct link const *link2 = entry2;
1328 return ((link1->dev ^ link2->dev) | (link1->ino ^ link2->ino)) == 0;
1329}
1330
1331static void
1332unknown_file_error (char const *p)
1333{
1334 WARN ((0, 0, _("%s: Unknown file type; file ignored"),
1335 quotearg_colon (p)));
1336 if (!ignore_failed_read_option)
1337 exit_status = TAREXIT_FAILURE;
1338}
1339
1340
1341
1342/* Handling of hard links */
1343
1344/* Table of all non-directories that we've written so far. Any time
1345 we see another, we check the table and avoid dumping the data
1346 again if we've done it once already. */
1347static Hash_table *link_table;
1348
1349/* Try to dump stat as a hard link to another file in the archive.
1350 Return true if successful. */
1351static bool
1352dump_hard_link (struct tar_stat_info *st)
1353{
1354 if (link_table && st->stat.st_nlink > 1)
1355 {
1356 struct link lp;
1357 struct link *duplicate;
1358 off_t block_ordinal;
1359 union block *blk;
1360
1361 lp.ino = st->stat.st_ino;
1362 lp.dev = st->stat.st_dev;
1363
1364 if ((duplicate = hash_lookup (link_table, &lp)))
1365 {
1366 /* We found a link. */
1367 char const *link_name = safer_name_suffix (duplicate->name, true,
1368 absolute_names_option);
1369
1370 duplicate->nlink--;
1371
1372 block_ordinal = current_block_ordinal ();
1373 assign_string (&st->link_name, link_name);
1374 if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT)
1375 < strlen (link_name))
1376 write_long_link (st);
1377
1378 st->stat.st_size = 0;
1379 blk = start_header (st);
1380 if (!blk)
1381 return false;
1382 tar_copy_str (blk->header.linkname, link_name, NAME_FIELD_SIZE);
1383
1384 blk->header.typeflag = LNKTYPE;
1385 finish_header (st, blk, block_ordinal);
1386
1387 if (remove_files_option && unlink (st->orig_file_name) != 0)
1388 unlink_error (st->orig_file_name);
1389
1390 return true;
1391 }
1392 }
1393 return false;
1394}
1395
1396static void
1397file_count_links (struct tar_stat_info *st)
1398{
1399 if (st->stat.st_nlink > 1)
1400 {
1401 struct link *duplicate;
1402 struct link *lp = xmalloc (offsetof (struct link, name)
1403 + strlen (st->orig_file_name) + 1);
1404 lp->ino = st->stat.st_ino;
1405 lp->dev = st->stat.st_dev;
1406 lp->nlink = st->stat.st_nlink;
1407 strcpy (lp->name, st->orig_file_name);
1408
1409 if (! ((link_table
1410 || (link_table = hash_initialize (0, 0, hash_link,
1411 compare_links, 0)))
1412 && (duplicate = hash_insert (link_table, lp))))
1413 xalloc_die ();
1414
1415 if (duplicate != lp)
1416 abort ();
1417 lp->nlink--;
1418 }
1419}
1420
1421/* For each dumped file, check if all its links were dumped. Emit
1422 warnings if it is not so. */
1423void
1424check_links (void)
1425{
1426 struct link *lp;
1427
1428 if (!link_table)
1429 return;
1430
1431 for (lp = hash_get_first (link_table); lp;
1432 lp = hash_get_next (link_table, lp))
1433 {
1434 if (lp->nlink)
1435 {
1436 WARN ((0, 0, _("Missing links to %s.\n"), quote (lp->name)));
1437 }
1438 }
1439}
1440
1441
1442/* Dump a single file, recursing on directories. P is the file name
1443 to dump. TOP_LEVEL tells whether this is a top-level call; zero
1444 means no, positive means yes, and negative means the top level
1445 of an incremental dump. PARENT_DEVICE is the device of P's
1446 parent directory; it is examined only if TOP_LEVEL is zero. */
1447
1448/* FIXME: One should make sure that for *every* path leading to setting
1449 exit_status to failure, a clear diagnostic has been issued. */
1450
1451static void
1452dump_file0 (struct tar_stat_info *st, const char *p,
1453 int top_level, dev_t parent_device)
1454{
1455 union block *header;
1456 char type;
1457 off_t original_size;
1458 struct timespec original_ctime;
1459 struct timespec restore_times[2];
1460 off_t block_ordinal = -1;
1461 bool is_dir;
1462
1463 if (interactive_option && !confirm ("add", p))
1464 return;
1465
1466 assign_string (&st->orig_file_name, p);
1467 assign_string (&st->file_name,
1468 safer_name_suffix (p, false, absolute_names_option));
1469
1470 transform_name (&st->file_name);
1471
1472 if (deref_stat (dereference_option, p, &st->stat) != 0)
1473 {
1474 stat_diag (p);
1475 return;
1476 }
1477 st->archive_file_size = original_size = st->stat.st_size;
1478 st->atime = restore_times[0] = get_stat_atime (&st->stat);
1479 st->mtime = restore_times[1] = get_stat_mtime (&st->stat);
1480 st->ctime = original_ctime = get_stat_ctime (&st->stat);
1481
1482#ifdef S_ISHIDDEN
1483 if (S_ISHIDDEN (st->stat.st_mode))
1484 {
1485 char *new = (char *) alloca (strlen (p) + 2);
1486 if (new)
1487 {
1488 strcpy (new, p);
1489 strcat (new, "@");
1490 p = new;
1491 }
1492 }
1493#endif
1494
1495 /* See if we want only new files, and check if this one is too old to
1496 put in the archive.
1497
1498 This check is omitted if incremental_option is set *and* the
1499 requested file is not explicitely listed in the command line. */
1500
1501 if (!(incremental_option && !is_individual_file (p))
1502 && !S_ISDIR (st->stat.st_mode)
1503 && OLDER_TAR_STAT_TIME (*st, m)
1504 && (!after_date_option || OLDER_TAR_STAT_TIME (*st, c)))
1505 {
1506 if (!incremental_option && verbose_option)
1507 WARN ((0, 0, _("%s: file is unchanged; not dumped"),
1508 quotearg_colon (p)));
1509 return;
1510 }
1511
1512 /* See if we are trying to dump the archive. */
1513 if (sys_file_is_archive (st))
1514 {
1515 WARN ((0, 0, _("%s: file is the archive; not dumped"),
1516 quotearg_colon (p)));
1517 return;
1518 }
1519
1520 if (is_avoided_name (p))
1521 return;
1522
1523 is_dir = S_ISDIR (st->stat.st_mode) != 0;
1524
1525 if (!is_dir && dump_hard_link (st))
1526 return;
1527
1528 if (is_dir || S_ISREG (st->stat.st_mode) || S_ISCTG (st->stat.st_mode))
1529 {
1530 bool ok;
1531 int fd = -1;
1532 struct stat final_stat;
1533
1534 if (is_dir || file_dumpable_p (st))
1535 {
1536 fd = open (p,
1537 (O_RDONLY | O_BINARY
1538 | (is_dir ? O_DIRECTORY | O_NONBLOCK : 0)
1539 | (atime_preserve_option == system_atime_preserve
1540 ? O_NOATIME
1541 : 0)));
1542 if (fd < 0)
1543 {
1544 if (!top_level && errno == ENOENT)
1545 WARN ((0, 0, _("%s: File removed before we read it"),
1546 quotearg_colon (p)));
1547 else
1548 open_diag (p);
1549 return;
1550 }
1551 }
1552
1553 if (is_dir)
1554 {
1555 ensure_slash (&st->orig_file_name);
1556 ensure_slash (&st->file_name);
1557
1558 if (exclude_caches_option
1559 && check_cache_directory (st->orig_file_name))
1560 {
1561 if (verbose_option)
1562 WARN ((0, 0,
1563 _("%s: contains a cache directory tag; not dumped"),
1564 quotearg_colon (st->orig_file_name)));
1565 return;
1566 }
1567
1568 if (check_exclude_tags (st->orig_file_name))
1569 return;
1570
1571 ok = dump_dir (fd, st, top_level, parent_device);
1572
1573 /* dump_dir consumes FD if successful. */
1574 if (ok)
1575 fd = -1;
1576 }
1577 else
1578 {
1579 enum dump_status status;
1580
1581 if (fd != -1 && sparse_option && ST_IS_SPARSE (st->stat))
1582 {
1583 status = sparse_dump_file (fd, st);
1584 if (status == dump_status_not_implemented)
1585 status = dump_regular_file (fd, st);
1586 }
1587 else
1588 status = dump_regular_file (fd, st);
1589
1590 switch (status)
1591 {
1592 case dump_status_ok:
1593 case dump_status_short:
1594 mv_end ();
1595 break;
1596
1597 case dump_status_fail:
1598 break;
1599
1600 case dump_status_not_implemented:
1601 abort ();
1602 }
1603
1604 file_count_links (st);
1605
1606 ok = status == dump_status_ok;
1607 }
1608
1609 if (ok)
1610 {
1611 /* If possible, reopen a directory if we are preserving
1612 atimes, so that we can set just the atime on systems with
1613 _FIOSATIME. */
1614 if (fd < 0 && is_dir
1615 && atime_preserve_option == replace_atime_preserve)
1616 fd = open (p, O_RDONLY | O_BINARY | O_DIRECTORY | O_NONBLOCK);
1617
1618 if ((fd < 0
1619 ? deref_stat (dereference_option, p, &final_stat)
1620 : fstat (fd, &final_stat))
1621 != 0)
1622 {
1623 stat_diag (p);
1624 ok = false;
1625 }
1626 }
1627
1628 if (ok)
1629 {
1630 if (timespec_cmp (get_stat_ctime (&final_stat), original_ctime) != 0
1631 || original_size < final_stat.st_size)
1632 {
1633 WARN ((0, 0, _("%s: file changed as we read it"),
1634 quotearg_colon (p)));
1635 if (exit_status == TAREXIT_SUCCESS)
1636 exit_status = TAREXIT_DIFFERS;
1637 }
1638 else if (atime_preserve_option == replace_atime_preserve
1639 && set_file_atime (fd, p, restore_times) != 0)
1640 utime_error (p);
1641 }
1642
1643 if (0 <= fd && close (fd) != 0)
1644 {
1645 close_diag (p);
1646 ok = false;
1647 }
1648
1649 if (ok && remove_files_option)
1650 {
1651 if (is_dir)
1652 {
1653 if (rmdir (p) != 0 && errno != ENOTEMPTY)
1654 rmdir_error (p);
1655 }
1656 else
1657 {
1658 if (unlink (p) != 0)
1659 unlink_error (p);
1660 }
1661 }
1662
1663 return;
1664 }
1665#ifdef HAVE_READLINK
1666 else if (S_ISLNK (st->stat.st_mode))
1667 {
1668 char *buffer;
1669 int size;
1670 size_t linklen = st->stat.st_size;
1671 if (linklen != st->stat.st_size || linklen + 1 == 0)
1672 xalloc_die ();
1673 buffer = (char *) alloca (linklen + 1);
1674 size = readlink (p, buffer, linklen + 1);
1675 if (size < 0)
1676 {
1677 readlink_diag (p);
1678 return;
1679 }
1680 buffer[size] = '\0';
1681 assign_string (&st->link_name, buffer);
1682 if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size)
1683 write_long_link (st);
1684
1685 block_ordinal = current_block_ordinal ();
1686 st->stat.st_size = 0; /* force 0 size on symlink */
1687 header = start_header (st);
1688 if (!header)
1689 return;
1690 tar_copy_str (header->header.linkname, buffer, NAME_FIELD_SIZE);
1691 header->header.typeflag = SYMTYPE;
1692 finish_header (st, header, block_ordinal);
1693 /* nothing more to do to it */
1694
1695 if (remove_files_option)
1696 {
1697 if (unlink (p) == -1)
1698 unlink_error (p);
1699 }
1700 file_count_links (st);
1701 return;
1702 }
1703#endif
1704 else if (S_ISCHR (st->stat.st_mode))
1705 type = CHRTYPE;
1706 else if (S_ISBLK (st->stat.st_mode))
1707 type = BLKTYPE;
1708 else if (S_ISFIFO (st->stat.st_mode))
1709 type = FIFOTYPE;
1710 else if (S_ISSOCK (st->stat.st_mode))
1711 {
1712 WARN ((0, 0, _("%s: socket ignored"), quotearg_colon (p)));
1713 return;
1714 }
1715 else if (S_ISDOOR (st->stat.st_mode))
1716 {
1717 WARN ((0, 0, _("%s: door ignored"), quotearg_colon (p)));
1718 return;
1719 }
1720 else
1721 {
1722 unknown_file_error (p);
1723 return;
1724 }
1725
1726 if (archive_format == V7_FORMAT)
1727 {
1728 unknown_file_error (p);
1729 return;
1730 }
1731
1732 block_ordinal = current_block_ordinal ();
1733 st->stat.st_size = 0; /* force 0 size */
1734 header = start_header (st);
1735 if (!header)
1736 return;
1737 header->header.typeflag = type;
1738
1739 if (type != FIFOTYPE)
1740 {
1741 MAJOR_TO_CHARS (major (st->stat.st_rdev),
1742 header->header.devmajor);
1743 MINOR_TO_CHARS (minor (st->stat.st_rdev),
1744 header->header.devminor);
1745 }
1746
1747 finish_header (st, header, block_ordinal);
1748 if (remove_files_option)
1749 {
1750 if (unlink (p) == -1)
1751 unlink_error (p);
1752 }
1753}
1754
1755void
1756dump_file (const char *p, int top_level, dev_t parent_device)
1757{
1758 struct tar_stat_info st;
1759 tar_stat_init (&st);
1760 dump_file0 (&st, p, top_level, parent_device);
1761 if (listed_incremental_option)
1762 update_parent_directory (p);
1763 tar_stat_destroy (&st);
1764}
Note: See TracBrowser for help on using the repository browser.