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