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