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