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