]> Dogcows Code - chaz/tar/blob - src/create.c
Carefully crafted invalid headers can cause buffer overrun.
[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 not dumpable if
354 a) it is empty *and* world-readable, or
355 b) current archive is /dev/null */
356
357 bool
358 file_dumpable_p (struct tar_stat_info *st)
359 {
360 return !(dev_null_output
361 || (st->archive_file_size == 0
362 && (st->stat.st_mode & MODE_R) == MODE_R));
363 }
364
365 \f
366 /* Writing routines. */
367
368 /* Write the EOT block(s). Zero at least two blocks, through the end
369 of the record. Old tar, as previous versions of GNU tar, writes
370 garbage after two zeroed blocks. */
371 void
372 write_eot (void)
373 {
374 union block *pointer = find_next_block ();
375 memset (pointer->buffer, 0, BLOCKSIZE);
376 set_next_block_after (pointer);
377 pointer = find_next_block ();
378 memset (pointer->buffer, 0, available_space_after (pointer));
379 set_next_block_after (pointer);
380 }
381
382 /* Write a "private" header */
383 union block *
384 start_private_header (const char *name, size_t size)
385 {
386 time_t t;
387 union block *header = find_next_block ();
388
389 memset (header->buffer, 0, sizeof (union block));
390
391 tar_name_copy_str (header->header.name, name, NAME_FIELD_SIZE);
392 OFF_TO_CHARS (size, header->header.size);
393
394 time (&t);
395 TIME_TO_CHARS (t, header->header.mtime);
396 MODE_TO_CHARS (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, header->header.mode);
397 UID_TO_CHARS (getuid (), header->header.uid);
398 GID_TO_CHARS (getgid (), header->header.gid);
399 MAJOR_TO_CHARS (0, header->header.devmajor);
400 MINOR_TO_CHARS (0, header->header.devminor);
401 strncpy (header->header.magic, TMAGIC, TMAGLEN);
402 strncpy (header->header.version, TVERSION, TVERSLEN);
403 return header;
404 }
405
406 /* Create a new header and store there at most NAME_FIELD_SIZE bytes of
407 the file name */
408
409 static union block *
410 write_short_name (struct tar_stat_info *st)
411 {
412 union block *header = find_next_block ();
413 memset (header->buffer, 0, sizeof (union block));
414 tar_name_copy_str (header->header.name, st->file_name, NAME_FIELD_SIZE);
415 return header;
416 }
417
418 #define FILL(field,byte) do { \
419 memset(field, byte, sizeof(field)-1); \
420 (field)[sizeof(field)-1] = 0; \
421 } while (0)
422
423 /* Write a GNUTYPE_LONGLINK or GNUTYPE_LONGNAME block. */
424 static void
425 write_gnu_long_link (struct tar_stat_info *st, const char *p, char type)
426 {
427 size_t size = strlen (p) + 1;
428 size_t bufsize;
429 union block *header;
430 char *tmpname;
431
432 header = start_private_header ("././@LongLink", size);
433 FILL(header->header.mtime, '0');
434 FILL(header->header.mode, '0');
435 FILL(header->header.uid, '0');
436 FILL(header->header.gid, '0');
437 FILL(header->header.devmajor, 0);
438 FILL(header->header.devminor, 0);
439 uid_to_uname (0, &tmpname);
440 UNAME_TO_CHARS (tmpname, header->header.uname);
441 free (tmpname);
442 gid_to_gname (0, &tmpname);
443 GNAME_TO_CHARS (tmpname, header->header.gname);
444 free (tmpname);
445
446 strcpy (header->header.magic, OLDGNU_MAGIC);
447 header->header.typeflag = type;
448 finish_header (st, header, -1);
449
450 header = find_next_block ();
451
452 bufsize = available_space_after (header);
453
454 while (bufsize < size)
455 {
456 memcpy (header->buffer, p, bufsize);
457 p += bufsize;
458 size -= bufsize;
459 set_next_block_after (header + (bufsize - 1) / BLOCKSIZE);
460 header = find_next_block ();
461 bufsize = available_space_after (header);
462 }
463 memcpy (header->buffer, p, size);
464 memset (header->buffer + size, 0, bufsize - size);
465 set_next_block_after (header + (size - 1) / BLOCKSIZE);
466 }
467
468 static size_t
469 split_long_name (const char *name, size_t length)
470 {
471 size_t i;
472
473 if (length > PREFIX_FIELD_SIZE)
474 length = PREFIX_FIELD_SIZE+2;
475 for (i = length - 1; i > 0; i--)
476 if (ISSLASH (name[i]))
477 break;
478 return i;
479 }
480
481 static union block *
482 write_ustar_long_name (const char *name)
483 {
484 size_t length = strlen (name);
485 size_t i;
486 union block *header;
487
488 if (length > PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1)
489 {
490 ERROR ((0, 0, _("%s: file name is too long (max %d); not dumped"),
491 quotearg_colon (name),
492 PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1));
493 return NULL;
494 }
495
496 i = split_long_name (name, length);
497 if (i == 0 || length - i - 1 > NAME_FIELD_SIZE)
498 {
499 ERROR ((0, 0,
500 _("%s: file name is too long (cannot be split); not dumped"),
501 quotearg_colon (name)));
502 return NULL;
503 }
504
505 header = find_next_block ();
506 memset (header->buffer, 0, sizeof (header->buffer));
507 memcpy (header->header.prefix, name, i);
508 memcpy (header->header.name, name + i + 1, length - i - 1);
509
510 return header;
511 }
512
513 /* Write a long link name, depending on the current archive format */
514 static void
515 write_long_link (struct tar_stat_info *st)
516 {
517 switch (archive_format)
518 {
519 case POSIX_FORMAT:
520 xheader_store ("linkpath", st, NULL);
521 break;
522
523 case V7_FORMAT: /* old V7 tar format */
524 case USTAR_FORMAT:
525 case STAR_FORMAT:
526 ERROR ((0, 0,
527 _("%s: link name is too long; not dumped"),
528 quotearg_colon (st->link_name)));
529 break;
530
531 case OLDGNU_FORMAT:
532 case GNU_FORMAT:
533 write_gnu_long_link (st, st->link_name, GNUTYPE_LONGLINK);
534 break;
535
536 default:
537 abort(); /*FIXME*/
538 }
539 }
540
541 static union block *
542 write_long_name (struct tar_stat_info *st)
543 {
544 switch (archive_format)
545 {
546 case POSIX_FORMAT:
547 xheader_store ("path", st, NULL);
548 break;
549
550 case V7_FORMAT:
551 if (strlen (st->file_name) > NAME_FIELD_SIZE-1)
552 {
553 ERROR ((0, 0, _("%s: file name is too long (max %d); not dumped"),
554 quotearg_colon (st->file_name),
555 NAME_FIELD_SIZE - 1));
556 return NULL;
557 }
558 break;
559
560 case USTAR_FORMAT:
561 case STAR_FORMAT:
562 return write_ustar_long_name (st->file_name);
563
564 case OLDGNU_FORMAT:
565 case GNU_FORMAT:
566 write_gnu_long_link (st, st->file_name, GNUTYPE_LONGNAME);
567 break;
568
569 default:
570 abort(); /*FIXME*/
571 }
572 return write_short_name (st);
573 }
574
575 static union block *
576 write_extended (struct tar_stat_info *st, union block *old_header)
577 {
578 union block *header, hp;
579 char *p;
580
581 if (extended_header.buffer || extended_header.stk == NULL)
582 return old_header;
583
584 xheader_finish (&extended_header);
585 memcpy (hp.buffer, old_header, sizeof (hp));
586 p = xheader_xhdr_name (st);
587 xheader_write (XHDTYPE, p, &extended_header);
588 free (p);
589 header = find_next_block ();
590 memcpy (header, &hp.buffer, sizeof (hp.buffer));
591 return header;
592 }
593
594 static union block *
595 write_header_name (struct tar_stat_info *st)
596 {
597 if (archive_format == POSIX_FORMAT && !string_ascii_p (st->file_name))
598 {
599 xheader_store ("path", st, NULL);
600 return write_short_name (st);
601 }
602 else if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT)
603 < strlen (st->file_name))
604 return write_long_name (st);
605 else
606 return write_short_name (st);
607 }
608
609 \f
610 /* Header handling. */
611
612 /* Make a header block for the file whose stat info is st,
613 and return its address. */
614
615 union block *
616 start_header (struct tar_stat_info *st)
617 {
618 union block *header;
619
620 header = write_header_name (st);
621 if (!header)
622 return NULL;
623
624 /* Override some stat fields, if requested to do so. */
625
626 if (owner_option != (uid_t) -1)
627 st->stat.st_uid = owner_option;
628 if (group_option != (gid_t) -1)
629 st->stat.st_gid = group_option;
630 if (mode_option)
631 st->stat.st_mode =
632 ((st->stat.st_mode & ~MODE_ALL)
633 | mode_adjust (st->stat.st_mode, mode_option, initial_umask));
634
635 /* Paul Eggert tried the trivial test ($WRITER cf a b; $READER tvf a)
636 for a few tars and came up with the following interoperability
637 matrix:
638
639 WRITER
640 1 2 3 4 5 6 7 8 9 READER
641 . . . . . . . . . 1 = SunOS 4.2 tar
642 # . . # # . . # # 2 = NEC SVR4.0.2 tar
643 . . . # # . . # . 3 = Solaris 2.1 tar
644 . . . . . . . . . 4 = GNU tar 1.11.1
645 . . . . . . . . . 5 = HP-UX 8.07 tar
646 . . . . . . . . . 6 = Ultrix 4.1
647 . . . . . . . . . 7 = AIX 3.2
648 . . . . . . . . . 8 = Hitachi HI-UX 1.03
649 . . . . . . . . . 9 = Omron UNIOS-B 4.3BSD 1.60Beta
650
651 . = works
652 # = ``impossible file type''
653
654 The following mask for old archive removes the `#'s in column 4
655 above, thus making GNU tar both a universal donor and a universal
656 acceptor for Paul's test. */
657
658 if (archive_format == V7_FORMAT || archive_format == USTAR_FORMAT)
659 MODE_TO_CHARS (st->stat.st_mode & MODE_ALL, header->header.mode);
660 else
661 MODE_TO_CHARS (st->stat.st_mode, header->header.mode);
662
663 {
664 uid_t uid = st->stat.st_uid;
665 if (archive_format == POSIX_FORMAT
666 && MAX_OCTAL_VAL (header->header.uid) < uid)
667 {
668 xheader_store ("uid", st, NULL);
669 uid = 0;
670 }
671 UID_TO_CHARS (uid, header->header.uid);
672 }
673
674 {
675 gid_t gid = st->stat.st_gid;
676 if (archive_format == POSIX_FORMAT
677 && MAX_OCTAL_VAL (header->header.gid) < gid)
678 {
679 xheader_store ("gid", st, NULL);
680 gid = 0;
681 }
682 GID_TO_CHARS (gid, header->header.gid);
683 }
684
685 {
686 off_t size = st->stat.st_size;
687 if (archive_format == POSIX_FORMAT
688 && MAX_OCTAL_VAL (header->header.size) < size)
689 {
690 xheader_store ("size", st, NULL);
691 size = 0;
692 }
693 OFF_TO_CHARS (size, header->header.size);
694 }
695
696 {
697 struct timespec mtime = get_stat_mtime (&st->stat);
698 if (archive_format == POSIX_FORMAT)
699 {
700 if (MAX_OCTAL_VAL (header->header.mtime) < mtime.tv_sec
701 || mtime.tv_nsec != 0)
702 xheader_store ("mtime", st, NULL);
703 if (MAX_OCTAL_VAL (header->header.mtime) < mtime.tv_sec)
704 mtime.tv_sec = 0;
705 }
706 TIME_TO_CHARS (mtime.tv_sec, header->header.mtime);
707 }
708
709 /* FIXME */
710 if (S_ISCHR (st->stat.st_mode)
711 || S_ISBLK (st->stat.st_mode))
712 {
713 major_t devmajor = major (st->stat.st_rdev);
714 minor_t devminor = minor (st->stat.st_rdev);
715
716 if (archive_format == POSIX_FORMAT
717 && MAX_OCTAL_VAL (header->header.devmajor) < devmajor)
718 {
719 xheader_store ("devmajor", st, NULL);
720 devmajor = 0;
721 }
722 MAJOR_TO_CHARS (devmajor, header->header.devmajor);
723
724 if (archive_format == POSIX_FORMAT
725 && MAX_OCTAL_VAL (header->header.devminor) < devminor)
726 {
727 xheader_store ("devminor", st, NULL);
728 devminor = 0;
729 }
730 MINOR_TO_CHARS (devminor, header->header.devminor);
731 }
732 else if (archive_format != GNU_FORMAT && archive_format != OLDGNU_FORMAT)
733 {
734 MAJOR_TO_CHARS (0, header->header.devmajor);
735 MINOR_TO_CHARS (0, header->header.devminor);
736 }
737
738 if (archive_format == POSIX_FORMAT)
739 {
740 xheader_store ("atime", st, NULL);
741 xheader_store ("ctime", st, NULL);
742 }
743 else if (incremental_option)
744 if (archive_format == OLDGNU_FORMAT || archive_format == GNU_FORMAT)
745 {
746 TIME_TO_CHARS (st->stat.st_atime, header->oldgnu_header.atime);
747 TIME_TO_CHARS (st->stat.st_ctime, header->oldgnu_header.ctime);
748 }
749
750 header->header.typeflag = archive_format == V7_FORMAT ? AREGTYPE : REGTYPE;
751
752 switch (archive_format)
753 {
754 case V7_FORMAT:
755 break;
756
757 case OLDGNU_FORMAT:
758 case GNU_FORMAT: /*FIXME?*/
759 /* Overwrite header->header.magic and header.version in one blow. */
760 strcpy (header->header.magic, OLDGNU_MAGIC);
761 break;
762
763 case POSIX_FORMAT:
764 case USTAR_FORMAT:
765 strncpy (header->header.magic, TMAGIC, TMAGLEN);
766 strncpy (header->header.version, TVERSION, TVERSLEN);
767 break;
768
769 default:
770 abort ();
771 }
772
773 if (archive_format == V7_FORMAT || numeric_owner_option)
774 {
775 /* header->header.[ug]name are left as the empty string. */
776 }
777 else
778 {
779 uid_to_uname (st->stat.st_uid, &st->uname);
780 gid_to_gname (st->stat.st_gid, &st->gname);
781
782 if (archive_format == POSIX_FORMAT
783 && (strlen (st->uname) > UNAME_FIELD_SIZE
784 || !string_ascii_p (st->uname)))
785 xheader_store ("uname", st, NULL);
786 UNAME_TO_CHARS (st->uname, header->header.uname);
787
788 if (archive_format == POSIX_FORMAT
789 && (strlen (st->gname) > GNAME_FIELD_SIZE
790 || !string_ascii_p (st->gname)))
791 xheader_store ("gname", st, NULL);
792 GNAME_TO_CHARS (st->gname, header->header.gname);
793 }
794
795 return header;
796 }
797
798 void
799 simple_finish_header (union block *header)
800 {
801 size_t i;
802 int sum;
803 char *p;
804
805 memcpy (header->header.chksum, CHKBLANKS, sizeof header->header.chksum);
806
807 sum = 0;
808 p = header->buffer;
809 for (i = sizeof *header; i-- != 0; )
810 /* We can't use unsigned char here because of old compilers, e.g. V7. */
811 sum += 0xFF & *p++;
812
813 /* Fill in the checksum field. It's formatted differently from the
814 other fields: it has [6] digits, a null, then a space -- rather than
815 digits, then a null. We use to_chars.
816 The final space is already there, from
817 checksumming, and to_chars doesn't modify it.
818
819 This is a fast way to do:
820
821 sprintf(header->header.chksum, "%6o", sum); */
822
823 uintmax_to_chars ((uintmax_t) sum, header->header.chksum, 7);
824
825 set_next_block_after (header);
826 }
827
828 /* Finish off a filled-in header block and write it out. We also
829 print the file name and/or full info if verbose is on. If BLOCK_ORDINAL
830 is not negative, is the block ordinal of the first record for this
831 file, which may be a preceding long name or long link record. */
832 void
833 finish_header (struct tar_stat_info *st,
834 union block *header, off_t block_ordinal)
835 {
836 /* Note: It is important to do this before the call to write_extended(),
837 so that the actual ustar header is printed */
838 if (verbose_option
839 && header->header.typeflag != GNUTYPE_LONGLINK
840 && header->header.typeflag != GNUTYPE_LONGNAME
841 && header->header.typeflag != XHDTYPE
842 && header->header.typeflag != XGLTYPE)
843 {
844 /* These globals are parameters to print_header, sigh. */
845
846 current_header = header;
847 current_format = archive_format;
848 print_header (st, block_ordinal);
849 }
850
851 header = write_extended (st, header);
852 simple_finish_header (header);
853 }
854 \f
855
856 void
857 pad_archive (off_t size_left)
858 {
859 union block *blk;
860 while (size_left > 0)
861 {
862 save_sizeleft = size_left;
863 blk = find_next_block ();
864 memset (blk->buffer, 0, BLOCKSIZE);
865 set_next_block_after (blk);
866 size_left -= BLOCKSIZE;
867 }
868 }
869
870 static enum dump_status
871 dump_regular_file (int fd, struct tar_stat_info *st)
872 {
873 off_t size_left = st->stat.st_size;
874 off_t block_ordinal;
875 union block *blk;
876
877 block_ordinal = current_block_ordinal ();
878 blk = start_header (st);
879 if (!blk)
880 return dump_status_fail;
881
882 /* Mark contiguous files, if we support them. */
883 if (archive_format != V7_FORMAT && S_ISCTG (st->stat.st_mode))
884 blk->header.typeflag = CONTTYPE;
885
886 finish_header (st, blk, block_ordinal);
887
888 while (size_left > 0)
889 {
890 size_t bufsize, count;
891
892 if (multi_volume_option)
893 {
894 assign_string (&save_name, st->orig_file_name);
895 save_sizeleft = size_left;
896 save_totsize = st->stat.st_size;
897 }
898 blk = find_next_block ();
899
900 bufsize = available_space_after (blk);
901
902 if (size_left < bufsize)
903 {
904 /* Last read -- zero out area beyond. */
905 bufsize = size_left;
906 count = bufsize % BLOCKSIZE;
907 if (count)
908 memset (blk->buffer + size_left, 0, BLOCKSIZE - count);
909 }
910
911 count = (fd < 0) ? bufsize : safe_read (fd, blk->buffer, bufsize);
912 if (count == SAFE_READ_ERROR)
913 {
914 read_diag_details (st->orig_file_name,
915 st->stat.st_size - size_left, bufsize);
916 pad_archive (size_left);
917 return dump_status_short;
918 }
919 size_left -= count;
920 if (count)
921 set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE);
922
923 if (count != bufsize)
924 {
925 char buf[UINTMAX_STRSIZE_BOUND];
926 memset (blk->buffer + count, 0, bufsize - count);
927 WARN ((0, 0,
928 ngettext ("%s: File shrank by %s byte; padding with zeros",
929 "%s: File shrank by %s bytes; padding with zeros",
930 size_left),
931 quotearg_colon (st->orig_file_name),
932 STRINGIFY_BIGINT (size_left, buf)));
933 if (! ignore_failed_read_option)
934 exit_status = TAREXIT_FAILURE;
935 pad_archive (size_left - (bufsize-count));
936 return dump_status_short;
937 }
938 }
939 return dump_status_ok;
940 }
941
942 static void
943 dump_regular_finish (int fd, struct tar_stat_info *st,
944 struct timespec original_ctime)
945 {
946 if (fd >= 0)
947 {
948 struct stat final_stat;
949 if (fstat (fd, &final_stat) != 0)
950 {
951 stat_diag (st->orig_file_name);
952 }
953 else if (final_stat.st_ctime != original_ctime.tv_sec
954 || (get_stat_ctime (&final_stat).tv_nsec
955 != original_ctime.tv_nsec))
956 {
957 WARN ((0, 0, _("%s: file changed as we read it"),
958 quotearg_colon (st->orig_file_name)));
959 }
960 if (close (fd) != 0)
961 {
962 close_diag (st->orig_file_name);
963 }
964 }
965 if (remove_files_option)
966 {
967 if (unlink (st->orig_file_name) == -1)
968 unlink_error (st->orig_file_name);
969 }
970 }
971
972 /* Look in directory DIRNAME for a cache directory tag file
973 with the magic name "CACHEDIR.TAG" and a standard header,
974 as described at:
975 http://www.brynosaurus.com/cachedir
976 Applications can write this file into directories they create
977 for use as caches containing purely regenerable, non-precious data,
978 allowing us to avoid archiving them if --exclude-caches is specified. */
979
980 #define CACHEDIR_SIGNATURE "Signature: 8a477f597d28d172789f06886806bc55"
981 #define CACHEDIR_SIGNATURE_SIZE (sizeof CACHEDIR_SIGNATURE - 1)
982
983 static bool
984 check_cache_directory (char *dirname)
985 {
986 static char tagname[] = "CACHEDIR.TAG";
987 char *tagpath;
988 int fd;
989 int tag_present = false;
990
991 tagpath = xmalloc (strlen (dirname) + strlen (tagname) + 1);
992 strcpy (tagpath, dirname);
993 strcat (tagpath, tagname);
994
995 fd = open (tagpath, O_RDONLY);
996 if (fd >= 0)
997 {
998 static char tagbuf[CACHEDIR_SIGNATURE_SIZE];
999
1000 if (read (fd, tagbuf, CACHEDIR_SIGNATURE_SIZE)
1001 == CACHEDIR_SIGNATURE_SIZE
1002 && memcmp (tagbuf, CACHEDIR_SIGNATURE, CACHEDIR_SIGNATURE_SIZE) == 0)
1003 tag_present = true;
1004
1005 close (fd);
1006 }
1007
1008 free (tagpath);
1009
1010 return tag_present;
1011 }
1012
1013 static void
1014 dump_dir0 (char *directory,
1015 struct tar_stat_info *st, int top_level, dev_t parent_device)
1016 {
1017 dev_t our_device = st->stat.st_dev;
1018
1019 if (!is_avoided_name (st->orig_file_name))
1020 {
1021 union block *blk = NULL;
1022 off_t block_ordinal = current_block_ordinal ();
1023 st->stat.st_size = 0; /* force 0 size on dir */
1024
1025 blk = start_header (st);
1026 if (!blk)
1027 return;
1028
1029 if (incremental_option)
1030 blk->header.typeflag = GNUTYPE_DUMPDIR;
1031 else /* if (standard_option) */
1032 blk->header.typeflag = DIRTYPE;
1033
1034 /* If we're gnudumping, we aren't done yet so don't close it. */
1035
1036 if (!incremental_option)
1037 finish_header (st, blk, block_ordinal);
1038 else if (gnu_list_name->dir_contents)
1039 {
1040 off_t size_left;
1041 off_t totsize;
1042 size_t bufsize;
1043 ssize_t count;
1044 const char *buffer, *p_buffer;
1045
1046 block_ordinal = current_block_ordinal ();
1047 buffer = gnu_list_name->dir_contents; /* FOO */
1048 totsize = 0;
1049 if (buffer)
1050 for (p_buffer = buffer; *p_buffer; )
1051 {
1052 size_t size = strlen (p_buffer) + 1;
1053 totsize += size;
1054 p_buffer += size;
1055 }
1056 totsize++;
1057 OFF_TO_CHARS (totsize, blk->header.size);
1058 finish_header (st, blk, block_ordinal);
1059 p_buffer = buffer;
1060 size_left = totsize;
1061 while (size_left > 0)
1062 {
1063 if (multi_volume_option)
1064 {
1065 assign_string (&save_name, st->orig_file_name);
1066 save_sizeleft = size_left;
1067 save_totsize = totsize;
1068 }
1069 blk = find_next_block ();
1070 bufsize = available_space_after (blk);
1071 if (size_left < bufsize)
1072 {
1073 bufsize = size_left;
1074 count = bufsize % BLOCKSIZE;
1075 if (count)
1076 memset (blk->buffer + size_left, 0, BLOCKSIZE - count);
1077 }
1078 memcpy (blk->buffer, p_buffer, bufsize);
1079 size_left -= bufsize;
1080 p_buffer += bufsize;
1081 set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE);
1082 }
1083 if (multi_volume_option)
1084 assign_string (&save_name, 0);
1085 return;
1086 }
1087 }
1088
1089 if (!recursion_option)
1090 return;
1091
1092 if (one_file_system_option
1093 && !top_level
1094 && parent_device != st->stat.st_dev)
1095 {
1096 if (verbose_option)
1097 WARN ((0, 0,
1098 _("%s: file is on a different filesystem; not dumped"),
1099 quotearg_colon (st->orig_file_name)));
1100 return;
1101 }
1102
1103 if (exclude_caches_option
1104 && check_cache_directory(st->orig_file_name))
1105 {
1106 if (verbose_option)
1107 WARN ((0, 0,
1108 _("%s: contains a cache directory tag; not dumped"),
1109 quotearg_colon (st->orig_file_name)));
1110 return;
1111 }
1112
1113 {
1114 char const *entry;
1115 size_t entry_len;
1116 char *name_buf = xstrdup (st->orig_file_name);
1117 size_t name_size = strlen (name_buf);
1118 size_t name_len = name_size;
1119
1120 /* Now output all the files in the directory. */
1121 /* FIXME: Should speed this up by cd-ing into the dir. */
1122
1123 for (entry = directory; (entry_len = strlen (entry)) != 0;
1124 entry += entry_len + 1)
1125 {
1126 if (name_size < name_len + entry_len)
1127 {
1128 name_size = name_len + entry_len;
1129 name_buf = xrealloc (name_buf, name_size + 1);
1130 }
1131 strcpy (name_buf + name_len, entry);
1132 if (!excluded_name (name_buf))
1133 dump_file (name_buf, 0, our_device);
1134 }
1135
1136 free (name_buf);
1137 }
1138 }
1139
1140 /* Ensure exactly one trailing slash. */
1141 static void
1142 ensure_slash (char **pstr)
1143 {
1144 size_t len = strlen (*pstr);
1145 while (len >= 1 && ISSLASH ((*pstr)[len - 1]))
1146 len--;
1147 if (!ISSLASH ((*pstr)[len]))
1148 *pstr = xrealloc (*pstr, len + 2);
1149 (*pstr)[len++] = '/';
1150 (*pstr)[len] = '\0';
1151 }
1152
1153 static bool
1154 dump_dir (struct tar_stat_info *st, int top_level, dev_t parent_device)
1155 {
1156 char *directory;
1157
1158 directory = savedir (st->orig_file_name);
1159 if (!directory)
1160 {
1161 savedir_diag (st->orig_file_name);
1162 return false;
1163 }
1164
1165 ensure_slash (&st->orig_file_name);
1166 ensure_slash (&st->file_name);
1167
1168 dump_dir0 (directory, st, top_level, parent_device);
1169
1170 free (directory);
1171 return true;
1172 }
1173
1174 \f
1175 /* Main functions of this module. */
1176
1177 void
1178 create_archive (void)
1179 {
1180 char *p;
1181
1182 open_archive (ACCESS_WRITE);
1183 xheader_write_global ();
1184
1185 if (incremental_option)
1186 {
1187 size_t buffer_size = 1000;
1188 char *buffer = xmalloc (buffer_size);
1189 const char *q;
1190
1191 collect_and_sort_names ();
1192
1193 while ((p = name_from_list ()) != NULL)
1194 if (!excluded_name (p))
1195 dump_file (p, -1, (dev_t) 0);
1196
1197 blank_name_list ();
1198 while ((p = name_from_list ()) != NULL)
1199 if (!excluded_name (p))
1200 {
1201 size_t plen = strlen (p);
1202 if (buffer_size <= plen)
1203 {
1204 while ((buffer_size *= 2) <= plen)
1205 continue;
1206 buffer = xrealloc (buffer, buffer_size);
1207 }
1208 memcpy (buffer, p, plen);
1209 if (! ISSLASH (buffer[plen - 1]))
1210 buffer[plen++] = '/';
1211 q = gnu_list_name->dir_contents;
1212 if (q)
1213 while (*q)
1214 {
1215 size_t qlen = strlen (q);
1216 if (*q == 'Y')
1217 {
1218 if (buffer_size < plen + qlen)
1219 {
1220 while ((buffer_size *=2 ) < plen + qlen)
1221 continue;
1222 buffer = xrealloc (buffer, buffer_size);
1223 }
1224 strcpy (buffer + plen, q + 1);
1225 dump_file (buffer, -1, (dev_t) 0);
1226 }
1227 q += qlen + 1;
1228 }
1229 }
1230 free (buffer);
1231 }
1232 else
1233 {
1234 while ((p = name_next (1)) != NULL)
1235 if (!excluded_name (p))
1236 dump_file (p, 1, (dev_t) 0);
1237 }
1238
1239 write_eot ();
1240 close_archive ();
1241
1242 if (listed_incremental_option)
1243 write_directory_file ();
1244 }
1245
1246
1247 /* Calculate the hash of a link. */
1248 static size_t
1249 hash_link (void const *entry, size_t n_buckets)
1250 {
1251 struct link const *l = entry;
1252 uintmax_t num = l->dev ^ l->ino;
1253 return num % n_buckets;
1254 }
1255
1256 /* Compare two links for equality. */
1257 static bool
1258 compare_links (void const *entry1, void const *entry2)
1259 {
1260 struct link const *link1 = entry1;
1261 struct link const *link2 = entry2;
1262 return ((link1->dev ^ link2->dev) | (link1->ino ^ link2->ino)) == 0;
1263 }
1264
1265 static void
1266 unknown_file_error (char *p)
1267 {
1268 WARN ((0, 0, _("%s: Unknown file type; file ignored"),
1269 quotearg_colon (p)));
1270 if (!ignore_failed_read_option)
1271 exit_status = TAREXIT_FAILURE;
1272 }
1273
1274 \f
1275 /* Handling of hard links */
1276
1277 /* Table of all non-directories that we've written so far. Any time
1278 we see another, we check the table and avoid dumping the data
1279 again if we've done it once already. */
1280 static Hash_table *link_table;
1281
1282 /* Try to dump stat as a hard link to another file in the archive. If
1283 succeeded returns true */
1284 static bool
1285 dump_hard_link (struct tar_stat_info *st)
1286 {
1287 if (link_table && st->stat.st_nlink > 1)
1288 {
1289 struct link lp;
1290 struct link *duplicate;
1291 off_t block_ordinal;
1292 union block *blk;
1293
1294 lp.ino = st->stat.st_ino;
1295 lp.dev = st->stat.st_dev;
1296
1297 if ((duplicate = hash_lookup (link_table, &lp)))
1298 {
1299 /* We found a link. */
1300 char const *link_name = safer_name_suffix (duplicate->name, true,
1301 absolute_names_option);
1302
1303 duplicate->nlink--;
1304
1305 block_ordinal = current_block_ordinal ();
1306 assign_string (&st->link_name, link_name);
1307 if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT)
1308 < strlen (link_name))
1309 write_long_link (st);
1310
1311 st->stat.st_size = 0;
1312 blk = start_header (st);
1313 if (!blk)
1314 return true;
1315 tar_copy_str (blk->header.linkname, link_name, NAME_FIELD_SIZE);
1316
1317 blk->header.typeflag = LNKTYPE;
1318 finish_header (st, blk, block_ordinal);
1319
1320 if (remove_files_option && unlink (st->orig_file_name) != 0)
1321 unlink_error (st->orig_file_name);
1322
1323 return true;
1324 }
1325 }
1326 return false;
1327 }
1328
1329 static void
1330 file_count_links (struct tar_stat_info *st)
1331 {
1332 if (st->stat.st_nlink > 1)
1333 {
1334 struct link *duplicate;
1335 struct link *lp = xmalloc (offsetof (struct link, name)
1336 + strlen (st->orig_file_name) + 1);
1337 lp->ino = st->stat.st_ino;
1338 lp->dev = st->stat.st_dev;
1339 lp->nlink = st->stat.st_nlink;
1340 strcpy (lp->name, st->orig_file_name);
1341
1342 if (! ((link_table
1343 || (link_table = hash_initialize (0, 0, hash_link,
1344 compare_links, 0)))
1345 && (duplicate = hash_insert (link_table, lp))))
1346 xalloc_die ();
1347
1348 if (duplicate != lp)
1349 abort ();
1350 lp->nlink--;
1351 }
1352 }
1353
1354 /* For each dumped file, check if all its links were dumped. Emit
1355 warnings if it is not so. */
1356 void
1357 check_links (void)
1358 {
1359 struct link *lp;
1360
1361 if (!link_table)
1362 return;
1363
1364 for (lp = hash_get_first (link_table); lp;
1365 lp = hash_get_next (link_table, lp))
1366 {
1367 if (lp->nlink)
1368 {
1369 WARN ((0, 0, _("Missing links to %s.\n"), quote (lp->name)));
1370 }
1371 }
1372 }
1373
1374
1375 /* Dump a single file, recursing on directories. P is the file name
1376 to dump. TOP_LEVEL tells whether this is a top-level call; zero
1377 means no, positive means yes, and negative means the top level
1378 of an incremental dump. PARENT_DEVICE is the device of P's
1379 parent directory; it is examined only if TOP_LEVEL is zero. */
1380
1381 /* FIXME: One should make sure that for *every* path leading to setting
1382 exit_status to failure, a clear diagnostic has been issued. */
1383
1384 static void
1385 dump_file0 (struct tar_stat_info *st, char *p,
1386 int top_level, dev_t parent_device)
1387 {
1388 union block *header;
1389 char type;
1390 struct timespec original_ctime;
1391 struct timespec restore_times[2];
1392 off_t block_ordinal = -1;
1393
1394 if (interactive_option && !confirm ("add", p))
1395 return;
1396
1397 assign_string (&st->orig_file_name, p);
1398 assign_string (&st->file_name,
1399 safer_name_suffix (p, false, absolute_names_option));
1400
1401 if (deref_stat (dereference_option, p, &st->stat) != 0)
1402 {
1403 stat_diag (p);
1404 return;
1405 }
1406 st->archive_file_size = st->stat.st_size;
1407 original_ctime = get_stat_ctime (&st->stat);
1408 restore_times[0] = get_stat_atime (&st->stat);
1409 restore_times[1] = get_stat_mtime (&st->stat);
1410
1411 #ifdef S_ISHIDDEN
1412 if (S_ISHIDDEN (st->stat.st_mode))
1413 {
1414 char *new = (char *) alloca (strlen (p) + 2);
1415 if (new)
1416 {
1417 strcpy (new, p);
1418 strcat (new, "@");
1419 p = new;
1420 }
1421 }
1422 #endif
1423
1424 /* See if we want only new files, and check if this one is too old to
1425 put in the archive.
1426
1427 This check is omitted if incremental_option is set *and* the
1428 requested file is not explicitely listed in the command line. */
1429
1430 if (!(incremental_option && !is_individual_file (p))
1431 && !S_ISDIR (st->stat.st_mode)
1432 && OLDER_STAT_TIME (st->stat, m)
1433 && (!after_date_option || OLDER_STAT_TIME (st->stat, c)))
1434 {
1435 if (!incremental_option && verbose_option)
1436 WARN ((0, 0, _("%s: file is unchanged; not dumped"),
1437 quotearg_colon (p)));
1438 return;
1439 }
1440
1441 /* See if we are trying to dump the archive. */
1442 if (sys_file_is_archive (st))
1443 {
1444 WARN ((0, 0, _("%s: file is the archive; not dumped"),
1445 quotearg_colon (p)));
1446 return;
1447 }
1448
1449 if (is_avoided_name (p))
1450 return;
1451 if (S_ISDIR (st->stat.st_mode))
1452 {
1453 dump_dir (st, top_level, parent_device);
1454 if (atime_preserve_option)
1455 utimens (p, restore_times);
1456 return;
1457 }
1458 else
1459 {
1460 /* Check for multiple links. */
1461 if (dump_hard_link (st))
1462 return;
1463
1464 /* This is not a link to a previously dumped file, so dump it. */
1465
1466 if (S_ISREG (st->stat.st_mode)
1467 || S_ISCTG (st->stat.st_mode))
1468 {
1469 int fd;
1470 enum dump_status status;
1471
1472 if (file_dumpable_p (st))
1473 {
1474 fd = open (st->orig_file_name,
1475 O_RDONLY | O_BINARY);
1476 if (fd < 0)
1477 {
1478 if (!top_level && errno == ENOENT)
1479 WARN ((0, 0, _("%s: File removed before we read it"),
1480 quotearg_colon (st->orig_file_name)));
1481 else
1482 open_diag (st->orig_file_name);
1483 return;
1484 }
1485 }
1486 else
1487 fd = -1;
1488
1489 if (sparse_option && sparse_file_p (st))
1490 {
1491 status = sparse_dump_file (fd, st);
1492 if (status == dump_status_not_implemented)
1493 status = dump_regular_file (fd, st);
1494 }
1495 else
1496 status = dump_regular_file (fd, st);
1497
1498 switch (status)
1499 {
1500 case dump_status_ok:
1501 if (multi_volume_option)
1502 assign_string (&save_name, 0);
1503 dump_regular_finish (fd, st, original_ctime);
1504 break;
1505
1506 case dump_status_short:
1507 if (multi_volume_option)
1508 assign_string (&save_name, 0);
1509 close (fd);
1510 break;
1511
1512 case dump_status_fail:
1513 close (fd);
1514 return;
1515
1516 case dump_status_not_implemented:
1517 abort ();
1518 }
1519
1520 if (atime_preserve_option)
1521 utimens (st->orig_file_name, restore_times);
1522 file_count_links (st);
1523 return;
1524 }
1525 #ifdef HAVE_READLINK
1526 else if (S_ISLNK (st->stat.st_mode))
1527 {
1528 char *buffer;
1529 int size;
1530 size_t linklen = st->stat.st_size;
1531 if (linklen != st->stat.st_size || linklen + 1 == 0)
1532 xalloc_die ();
1533 buffer = (char *) alloca (linklen + 1);
1534 size = readlink (p, buffer, linklen + 1);
1535 if (size < 0)
1536 {
1537 readlink_diag (p);
1538 return;
1539 }
1540 buffer[size] = '\0';
1541 assign_string (&st->link_name, buffer);
1542 if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size)
1543 write_long_link (st);
1544
1545 block_ordinal = current_block_ordinal ();
1546 st->stat.st_size = 0; /* force 0 size on symlink */
1547 header = start_header (st);
1548 if (!header)
1549 return;
1550 tar_copy_str (header->header.linkname, buffer, NAME_FIELD_SIZE);
1551 header->header.typeflag = SYMTYPE;
1552 finish_header (st, header, block_ordinal);
1553 /* nothing more to do to it */
1554
1555 if (remove_files_option)
1556 {
1557 if (unlink (p) == -1)
1558 unlink_error (p);
1559 }
1560 file_count_links (st);
1561 return;
1562 }
1563 #endif
1564 else if (S_ISCHR (st->stat.st_mode))
1565 type = CHRTYPE;
1566 else if (S_ISBLK (st->stat.st_mode))
1567 type = BLKTYPE;
1568 else if (S_ISFIFO (st->stat.st_mode))
1569 type = FIFOTYPE;
1570 else if (S_ISSOCK (st->stat.st_mode))
1571 {
1572 WARN ((0, 0, _("%s: socket ignored"), quotearg_colon (p)));
1573 return;
1574 }
1575 else if (S_ISDOOR (st->stat.st_mode))
1576 {
1577 WARN ((0, 0, _("%s: door ignored"), quotearg_colon (p)));
1578 return;
1579 }
1580 else
1581 {
1582 unknown_file_error (p);
1583 return;
1584 }
1585 }
1586
1587 if (archive_format == V7_FORMAT)
1588 {
1589 unknown_file_error (p);
1590 return;
1591 }
1592
1593 block_ordinal = current_block_ordinal ();
1594 st->stat.st_size = 0; /* force 0 size */
1595 header = start_header (st);
1596 if (!header)
1597 return;
1598 header->header.typeflag = type;
1599
1600 if (type != FIFOTYPE)
1601 {
1602 MAJOR_TO_CHARS (major (st->stat.st_rdev),
1603 header->header.devmajor);
1604 MINOR_TO_CHARS (minor (st->stat.st_rdev),
1605 header->header.devminor);
1606 }
1607
1608 finish_header (st, header, block_ordinal);
1609 if (remove_files_option)
1610 {
1611 if (unlink (p) == -1)
1612 unlink_error (p);
1613 }
1614 }
1615
1616 void
1617 dump_file (char *p, int top_level, dev_t parent_device)
1618 {
1619 struct tar_stat_info st;
1620 tar_stat_init (&st);
1621 dump_file0 (&st, p, top_level, parent_device);
1622 tar_stat_destroy (&st);
1623 }
This page took 0.105272 seconds and 5 git commands to generate.