]> Dogcows Code - chaz/tar/blob - src/create.c
(<quotearg.h>): New include.
[chaz/tar] / src / create.c
1 /* Create a tar archive.
2 Copyright 1985, 92, 93, 94, 96, 97, 1999 Free Software Foundation, Inc.
3 Written by John Gilmore, on 1985-08-25.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any later
8 version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19 #include "system.h"
20
21 #if !MSDOS
22 # include <pwd.h>
23 # include <grp.h>
24 #endif
25
26 #if HAVE_UTIME_H
27 # include <utime.h>
28 #else
29 struct utimbuf
30 {
31 long actime;
32 long modtime;
33 };
34 #endif
35
36 #include <quotearg.h>
37
38 #include "common.h"
39
40 #ifndef MSDOS
41 extern dev_t ar_dev;
42 extern ino_t ar_ino;
43 #endif
44
45 extern struct name *gnu_list_name;
46
47 /* This module is the only one that cares about `struct link's. */
48
49 struct link
50 {
51 struct link *next;
52 dev_t dev;
53 ino_t ino;
54 char name[1];
55 };
56
57 static struct link *linklist; /* points to first link in list */
58 \f
59 /* The maximum uintmax_t value that can be represented with DIGITS digits,
60 assuming that each digit is BITS_PER_DIGIT wide. */
61 #define MAX_VAL_WITH_DIGITS(digits, bits_per_digit) \
62 ((digits) * (bits_per_digit) < sizeof (uintmax_t) * CHAR_BIT \
63 ? ((uintmax_t) 1 << ((digits) * (bits_per_digit))) - 1 \
64 : (uintmax_t) -1)
65
66 /* Convert VALUE to an octal representation suitable for tar headers.
67 Output to buffer WHERE with size SIZE.
68 The result is undefined if SIZE is 0 or if VALUE is too large to fit. */
69
70 static void
71 to_octal (uintmax_t value, char *where, size_t size)
72 {
73 uintmax_t v = value;
74 size_t i = size;
75
76 do
77 {
78 where[--i] = '0' + (v & ((1 << LG_8) - 1));
79 v >>= LG_8;
80 }
81 while (i);
82 }
83
84 /* Convert NEGATIVE VALUE to a base-256 representation suitable for
85 tar headers. NEGATIVE is 1 if VALUE was negative before being cast
86 to uintmax_t, 0 otherwise. Output to buffer WHERE with size SIZE.
87 The result is undefined if SIZE is 0 or if VALUE is too large to
88 fit. */
89
90 static void
91 to_base256 (int negative, uintmax_t value, char *where, size_t size)
92 {
93 uintmax_t v = value;
94 uintmax_t propagated_sign_bits =
95 ((uintmax_t) - negative << (CHAR_BIT * sizeof v - LG_256));
96 size_t i = size;
97
98 do
99 {
100 where[--i] = v & ((1 << LG_256) - 1);
101 v = propagated_sign_bits | (v >> LG_256);
102 }
103 while (i);
104 }
105
106 /* Convert NEGATIVE VALUE (which was originally of size VALSIZE) to
107 external form, using SUBSTITUTE (...) if VALUE won't fit. Output
108 to buffer WHERE with size SIZE. NEGATIVE is 1 iff VALUE was
109 negative before being cast to uintmax_t; its original bitpattern
110 can be deduced from VALSIZE, its original size before casting.
111 TYPE is the kind of value being output (useful for diagnostics).
112 Prefer the POSIX format of SIZE - 1 octal digits (with leading zero
113 digits), followed by '\0'. If this won't work, and if GNU or
114 OLDGNU format is allowed, use '\200' followed by base-256, or (if
115 NEGATIVE is nonzero) '\377' followed by two's complement base-256.
116 If neither format works, use SUBSTITUTE (...) instead. Pass to
117 SUBSTITUTE the address of an 0-or-1 flag recording whether the
118 substitute value is negative. */
119
120 static void
121 to_chars (int negative, uintmax_t value, size_t valsize,
122 uintmax_t (*substitute) PARAMS ((int *)),
123 char *where, size_t size, const char *type)
124 {
125 int base256_allowed = (archive_format == GNU_FORMAT
126 || archive_format == OLDGNU_FORMAT);
127
128 /* Generate the POSIX octal representation if the number fits. */
129 if (! negative && value <= MAX_VAL_WITH_DIGITS (size - 1, LG_8))
130 {
131 where[size - 1] = '\0';
132 to_octal (value, where, size - 1);
133 }
134
135 /* Otherwise, generate the base-256 representation if we are
136 generating an old or new GNU format and if the number fits. */
137 else if (((negative ? -1 - value : value)
138 <= MAX_VAL_WITH_DIGITS (size - 1, LG_256))
139 && base256_allowed)
140 {
141 where[0] = negative ? -1 : 1 << (LG_256 - 1);
142 to_base256 (negative, value, where + 1, size - 1);
143 }
144
145 /* Otherwise, if the number is negative, and if it would not cause
146 ambiguity on this host by confusing positive with negative
147 values, then generate the POSIX octal representation of the value
148 modulo 2**(field bits). The resulting tar file is
149 machine-dependent, since it depends on the host word size. Yuck!
150 But this is the traditional behavior. */
151 else if (negative && valsize * CHAR_BIT <= (size - 1) * LG_8)
152 {
153 static int warned_once;
154 if (! warned_once)
155 {
156 warned_once = 1;
157 WARN ((0, 0, _("Generating negative octal headers")));
158 }
159 where[size - 1] = '\0';
160 to_octal (value & MAX_VAL_WITH_DIGITS (valsize * CHAR_BIT, 1),
161 where, size - 1);
162 }
163
164 /* Otherwise, output a substitute value if possible (with a
165 warning), and an error message if not. */
166 else
167 {
168 uintmax_t maxval = (base256_allowed
169 ? MAX_VAL_WITH_DIGITS (size - 1, LG_256)
170 : MAX_VAL_WITH_DIGITS (size - 1, LG_8));
171 char valbuf[UINTMAX_STRSIZE_BOUND + 1];
172 char maxbuf[UINTMAX_STRSIZE_BOUND];
173 char minbuf[UINTMAX_STRSIZE_BOUND + 1];
174 char const *minval_string;
175 char const *maxval_string = STRINGIFY_BIGINT (maxval, maxbuf);
176 char const *value_string;
177
178 if (base256_allowed)
179 {
180 uintmax_t m = maxval + 1 ? maxval + 1 : maxval / 2 + 1;
181 char *p = STRINGIFY_BIGINT (m, minbuf + 1);
182 *--p = '-';
183 minval_string = p;
184 }
185 else
186 minval_string = "0";
187
188 if (negative)
189 {
190 char *p = STRINGIFY_BIGINT (- value, valbuf + 1);
191 *--p = '-';
192 value_string = p;
193 }
194 else
195 value_string = STRINGIFY_BIGINT (value, valbuf);
196
197 if (substitute)
198 {
199 int negsub;
200 uintmax_t sub = substitute (&negsub) & maxval;
201 uintmax_t s = (negsub &= archive_format == GNU_FORMAT) ? - sub : sub;
202 char subbuf[UINTMAX_STRSIZE_BOUND + 1];
203 char *sub_string = STRINGIFY_BIGINT (s, subbuf + 1);
204 if (negsub)
205 *--sub_string = '-';
206 WARN ((0, 0, _("value %s out of %s range %s..%s; substituting %s"),
207 value_string, type, minval_string, maxval_string,
208 sub_string));
209 to_chars (negsub, s, valsize, 0, where, size, type);
210 }
211 else
212 ERROR ((0, 0, _("value %s out of %s range %s..%s"),
213 value_string, type, minval_string, maxval_string));
214 }
215 }
216
217 static uintmax_t
218 gid_substitute (int *negative)
219 {
220 gid_t r;
221 #ifdef GID_NOBODY
222 r = GID_NOBODY;
223 #else
224 static gid_t gid_nobody;
225 if (!gid_nobody && !gname_to_gid ("nobody", &gid_nobody))
226 gid_nobody = -2;
227 r = gid_nobody;
228 #endif
229 *negative = r < 0;
230 return r;
231 }
232
233 void
234 gid_to_chars (gid_t v, char *p, size_t s)
235 {
236 to_chars (v < 0, (uintmax_t) v, sizeof v, gid_substitute, p, s, "gid_t");
237 }
238
239 void
240 major_to_chars (major_t v, char *p, size_t s)
241 {
242 to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "major_t");
243 }
244
245 void
246 minor_to_chars (minor_t v, char *p, size_t s)
247 {
248 to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "minor_t");
249 }
250
251 void
252 mode_to_chars (mode_t v, char *p, size_t s)
253 {
254 /* In the common case where the internal and external mode bits are the same,
255 and we are not using POSIX or GNU format,
256 propagate all unknown bits to the external mode.
257 This matches historical practice.
258 Otherwise, just copy the bits we know about. */
259 int negative;
260 uintmax_t u;
261 if (S_ISUID == TSUID && S_ISGID == TSGID && S_ISVTX == TSVTX
262 && S_IRUSR == TUREAD && S_IWUSR == TUWRITE && S_IXUSR == TUEXEC
263 && S_IRGRP == TGREAD && S_IWGRP == TGWRITE && S_IXGRP == TGEXEC
264 && S_IROTH == TOREAD && S_IWOTH == TOWRITE && S_IXOTH == TOEXEC
265 && archive_format != POSIX_FORMAT
266 && archive_format != GNU_FORMAT)
267 {
268 negative = v < 0;
269 u = v;
270 }
271 else
272 {
273 negative = 0;
274 u = ((v & S_ISUID ? TSUID : 0)
275 | (v & S_ISGID ? TSGID : 0)
276 | (v & S_ISVTX ? TSVTX : 0)
277 | (v & S_IRUSR ? TUREAD : 0)
278 | (v & S_IWUSR ? TUWRITE : 0)
279 | (v & S_IXUSR ? TUEXEC : 0)
280 | (v & S_IRGRP ? TGREAD : 0)
281 | (v & S_IWGRP ? TGWRITE : 0)
282 | (v & S_IXGRP ? TGEXEC : 0)
283 | (v & S_IROTH ? TOREAD : 0)
284 | (v & S_IWOTH ? TOWRITE : 0)
285 | (v & S_IXOTH ? TOEXEC : 0));
286 }
287 to_chars (negative, u, sizeof v, 0, p, s, "mode_t");
288 }
289
290 void
291 off_to_chars (off_t v, char *p, size_t s)
292 {
293 to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "off_t");
294 }
295
296 void
297 size_to_chars (size_t v, char *p, size_t s)
298 {
299 to_chars (0, (uintmax_t) v, sizeof v, 0, p, s, "size_t");
300 }
301
302 void
303 time_to_chars (time_t v, char *p, size_t s)
304 {
305 to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "time_t");
306 }
307
308 static uintmax_t
309 uid_substitute (int *negative)
310 {
311 uid_t r;
312 #ifdef UID_NOBODY
313 r = UID_NOBODY;
314 #else
315 static uid_t uid_nobody;
316 if (!uid_nobody && !uname_to_uid ("nobody", &uid_nobody))
317 uid_nobody = -2;
318 r = uid_nobody;
319 #endif
320 *negative = r < 0;
321 return r;
322 }
323
324 void
325 uid_to_chars (uid_t v, char *p, size_t s)
326 {
327 to_chars (v < 0, (uintmax_t) v, sizeof v, uid_substitute, p, s, "uid_t");
328 }
329
330 void
331 uintmax_to_chars (uintmax_t v, char *p, size_t s)
332 {
333 to_chars (0, v, sizeof v, 0, p, s, "uintmax_t");
334 }
335 \f
336 /* Writing routines. */
337
338 /*-----------------------------------------------------------------------.
339 | Just zeroes out the buffer so we don't confuse ourselves with leftover |
340 | data. |
341 `-----------------------------------------------------------------------*/
342
343 static void
344 clear_buffer (char *buffer)
345 {
346 memset (buffer, 0, BLOCKSIZE);
347 }
348
349 /*-------------------------------------------------------------------------.
350 | Write the EOT block(s). We zero at least two blocks, through |
351 | the end of the record. Old tar, as previous versions of GNU tar, writes |
352 | garbage after two zeroed blocks. |
353 `-------------------------------------------------------------------------*/
354
355 void
356 write_eot (void)
357 {
358 union block *pointer = find_next_block ();
359 memset (pointer->buffer, 0, BLOCKSIZE);
360 set_next_block_after (pointer);
361 pointer = find_next_block ();
362 memset (pointer->buffer, 0, available_space_after (pointer));
363 set_next_block_after (pointer);
364 }
365
366 /*-----------------------------------------------------.
367 | Write a GNUTYPE_LONGLINK or GNUTYPE_LONGNAME block. |
368 `-----------------------------------------------------*/
369
370 /* FIXME: Cross recursion between start_header and write_long! */
371
372 static union block *start_header PARAMS ((const char *, struct stat *));
373
374 static void
375 write_long (const char *p, char type)
376 {
377 size_t size = strlen (p) + 1;
378 size_t bufsize;
379 union block *header;
380 struct stat foo;
381
382 memset (&foo, 0, sizeof foo);
383 foo.st_size = size;
384
385 header = start_header ("././@LongLink", &foo);
386 header->header.typeflag = type;
387 finish_header (header);
388
389 header = find_next_block ();
390
391 bufsize = available_space_after (header);
392
393 while (bufsize < size)
394 {
395 memcpy (header->buffer, p, bufsize);
396 p += bufsize;
397 size -= bufsize;
398 set_next_block_after (header + (bufsize - 1) / BLOCKSIZE);
399 header = find_next_block ();
400 bufsize = available_space_after (header);
401 }
402 memcpy (header->buffer, p, size);
403 memset (header->buffer + size, 0, bufsize - size);
404 set_next_block_after (header + (size - 1) / BLOCKSIZE);
405 }
406 \f
407 /* Header handling. */
408
409 /* Make a header block for the file whose stat info is st,
410 and return its address. */
411
412 static union block *
413 start_header (const char *name, struct stat *st)
414 {
415 union block *header;
416
417 if (!absolute_names_option)
418 {
419 size_t prefix_len = FILESYSTEM_PREFIX_LEN (name);
420
421 if (prefix_len)
422 {
423 static int warned_once;
424 if (!warned_once)
425 {
426 warned_once = 1;
427 WARN ((0, 0, _("Removing `%.*s' prefix from member names"),
428 (int) prefix_len, name));
429 }
430 name += prefix_len;
431 }
432
433 while (*name == '/')
434 {
435 static int warned_once;
436 if (!warned_once)
437 {
438 warned_once = 1;
439 WARN ((0, 0, _("Removing leading `/' from member names")));
440 }
441 name++;
442 }
443
444 {
445 static int warned_once;
446 if (! warned_once && contains_dot_dot (name))
447 {
448 warned_once = 1;
449 WARN ((0, 0, _("Member names contain `..'")));
450 }
451 }
452 }
453
454 if (sizeof header->header.name <= strlen (name))
455 write_long (name, GNUTYPE_LONGNAME);
456 header = find_next_block ();
457 memset (header->buffer, 0, sizeof (union block));
458
459 assign_string (&current_file_name, name);
460
461 strncpy (header->header.name, name, NAME_FIELD_SIZE);
462 header->header.name[NAME_FIELD_SIZE - 1] = '\0';
463
464 /* Override some stat fields, if requested to do so. */
465
466 if (owner_option != (uid_t) -1)
467 st->st_uid = owner_option;
468 if (group_option != (gid_t) -1)
469 st->st_gid = group_option;
470 if (mode_option)
471 st->st_mode = ((st->st_mode & ~MODE_ALL)
472 | mode_adjust (st->st_mode, mode_option));
473
474 /* Paul Eggert tried the trivial test ($WRITER cf a b; $READER tvf a)
475 for a few tars and came up with the following interoperability
476 matrix:
477
478 WRITER
479 1 2 3 4 5 6 7 8 9 READER
480 . . . . . . . . . 1 = SunOS 4.2 tar
481 # . . # # . . # # 2 = NEC SVR4.0.2 tar
482 . . . # # . . # . 3 = Solaris 2.1 tar
483 . . . . . . . . . 4 = GNU tar 1.11.1
484 . . . . . . . . . 5 = HP-UX 8.07 tar
485 . . . . . . . . . 6 = Ultrix 4.1
486 . . . . . . . . . 7 = AIX 3.2
487 . . . . . . . . . 8 = Hitachi HI-UX 1.03
488 . . . . . . . . . 9 = Omron UNIOS-B 4.3BSD 1.60Beta
489
490 . = works
491 # = ``impossible file type''
492
493 The following mask for old archive removes the `#'s in column 4
494 above, thus making GNU tar both a universal donor and a universal
495 acceptor for Paul's test. */
496
497 if (archive_format == V7_FORMAT)
498 MODE_TO_CHARS (st->st_mode & MODE_ALL, header->header.mode);
499 else
500 MODE_TO_CHARS (st->st_mode, header->header.mode);
501
502 UID_TO_CHARS (st->st_uid, header->header.uid);
503 GID_TO_CHARS (st->st_gid, header->header.gid);
504 OFF_TO_CHARS (st->st_size, header->header.size);
505 TIME_TO_CHARS (st->st_mtime, header->header.mtime);
506
507 if (incremental_option)
508 if (archive_format == OLDGNU_FORMAT)
509 {
510 TIME_TO_CHARS (st->st_atime, header->oldgnu_header.atime);
511 TIME_TO_CHARS (st->st_ctime, header->oldgnu_header.ctime);
512 }
513
514 header->header.typeflag = archive_format == V7_FORMAT ? AREGTYPE : REGTYPE;
515
516 switch (archive_format)
517 {
518 case V7_FORMAT:
519 break;
520
521 case OLDGNU_FORMAT:
522 /* Overwrite header->header.magic and header.version in one blow. */
523 strcpy (header->header.magic, OLDGNU_MAGIC);
524 break;
525
526 case POSIX_FORMAT:
527 case GNU_FORMAT:
528 strncpy (header->header.magic, TMAGIC, TMAGLEN);
529 strncpy (header->header.version, TVERSION, TVERSLEN);
530 break;
531
532 default:
533 abort ();
534 }
535
536 if (archive_format == V7_FORMAT || numeric_owner_option)
537 {
538 /* header->header.[ug]name are left as the empty string. */
539 }
540 else
541 {
542 uid_to_uname (st->st_uid, header->header.uname);
543 gid_to_gname (st->st_gid, header->header.gname);
544 }
545
546 return header;
547 }
548
549 /*-------------------------------------------------------------------------.
550 | Finish off a filled-in header block and write it out. We also print the |
551 | file name and/or full info if verbose is on. |
552 `-------------------------------------------------------------------------*/
553
554 void
555 finish_header (union block *header)
556 {
557 size_t i;
558 int sum;
559 char *p;
560
561 memcpy (header->header.chksum, CHKBLANKS, sizeof header->header.chksum);
562
563 sum = 0;
564 p = header->buffer;
565 for (i = sizeof *header; i-- != 0; )
566 /* We can't use unsigned char here because of old compilers, e.g. V7. */
567 sum += 0xFF & *p++;
568
569 /* Fill in the checksum field. It's formatted differently from the
570 other fields: it has [6] digits, a null, then a space -- rather than
571 digits, then a null. We use to_chars.
572 The final space is already there, from
573 checksumming, and to_chars doesn't modify it.
574
575 This is a fast way to do:
576
577 sprintf(header->header.chksum, "%6o", sum); */
578
579 uintmax_to_chars ((uintmax_t) sum, header->header.chksum, 7);
580
581 if (verbose_option
582 && header->header.typeflag != GNUTYPE_LONGLINK
583 && header->header.typeflag != GNUTYPE_LONGNAME)
584 {
585 /* These globals are parameters to print_header, sigh. */
586
587 current_header = header;
588 /* current_stat is already set up. */
589 current_format = archive_format;
590 print_header ();
591 }
592
593 set_next_block_after (header);
594 }
595 \f
596 /* Sparse file processing. */
597
598 /*-------------------------------------------------------------------------.
599 | Takes a blockful of data and basically cruises through it to see if it's |
600 | made *entirely* of zeros, returning a 0 the instant it finds something |
601 | that is a nonzero, i.e., useful data. |
602 `-------------------------------------------------------------------------*/
603
604 static int
605 zero_block_p (char *buffer)
606 {
607 int counter;
608
609 for (counter = 0; counter < BLOCKSIZE; counter++)
610 if (buffer[counter] != '\0')
611 return 0;
612 return 1;
613 }
614
615 /*---.
616 | ? |
617 `---*/
618
619 static void
620 init_sparsearray (void)
621 {
622 int counter;
623
624 sp_array_size = 10;
625
626 /* Make room for our scratch space -- initially is 10 elts long. */
627
628 sparsearray = xmalloc (sp_array_size * sizeof (struct sp_array));
629 for (counter = 0; counter < sp_array_size; counter++)
630 {
631 sparsearray[counter].offset = 0;
632 sparsearray[counter].numbytes = 0;
633 }
634 }
635
636 /*---.
637 | ? |
638 `---*/
639
640 static void
641 find_new_file_size (off_t *filesize, int highest_index)
642 {
643 int counter;
644
645 *filesize = 0;
646 for (counter = 0;
647 sparsearray[counter].numbytes && counter <= highest_index;
648 counter++)
649 *filesize += sparsearray[counter].numbytes;
650 }
651
652 /*-----------------------------------------------------------------------.
653 | Make one pass over the file NAME, studying where any non-zero data is, |
654 | that is, how far into the file each instance of data is, and how many |
655 | bytes are there. Save this information in the sparsearray, which will |
656 | later be translated into header information. |
657 `-----------------------------------------------------------------------*/
658
659 /* There is little point in trimming small amounts of null data at the head
660 and tail of blocks, only avoid dumping full null blocks. */
661
662 /* FIXME: this routine might accept bits of algorithmic cleanup, it is
663 too kludgey for my taste... */
664
665 static int
666 deal_with_sparse (char *name, union block *header)
667 {
668 size_t numbytes = 0;
669 off_t offset = 0;
670 int file;
671 int sparse_index = 0;
672 ssize_t count;
673 char buffer[BLOCKSIZE];
674
675 if (archive_format == OLDGNU_FORMAT)
676 header->oldgnu_header.isextended = 0;
677
678 if (file = open (name, O_RDONLY), file < 0)
679 /* This problem will be caught later on, so just return. */
680 return 0;
681
682 init_sparsearray ();
683 clear_buffer (buffer);
684
685 while (count = safe_read (file, buffer, sizeof buffer), count != 0)
686 {
687 /* Realloc the scratch area as necessary. FIXME: should reallocate
688 only at beginning of a new instance of non-zero data. */
689
690 if (sparse_index > sp_array_size - 1)
691 {
692 sparsearray =
693 xrealloc (sparsearray,
694 2 * sp_array_size * sizeof (struct sp_array));
695 sp_array_size *= 2;
696 }
697
698 /* Process one block. */
699
700 if (count == sizeof buffer)
701
702 if (zero_block_p (buffer))
703 {
704 if (numbytes)
705 {
706 sparsearray[sparse_index++].numbytes = numbytes;
707 numbytes = 0;
708 }
709 }
710 else
711 {
712 if (!numbytes)
713 sparsearray[sparse_index].offset = offset;
714 numbytes += count;
715 }
716
717 else
718
719 /* Since count < sizeof buffer, we have the last bit of the file. */
720
721 if (!zero_block_p (buffer))
722 {
723 if (!numbytes)
724 sparsearray[sparse_index].offset = offset;
725 numbytes += count;
726 }
727 else
728 /* The next two lines are suggested by Andreas Degert, who says
729 they are required for trailing full blocks to be written to the
730 archive, when all zeroed. Yet, it seems to me that the case
731 does not apply. Further, at restore time, the file is not as
732 sparse as it should. So, some serious cleanup is *also* needed
733 in this area. Just one more... :-(. FIXME. */
734 if (numbytes)
735 numbytes += count;
736
737 /* Prepare for next block. */
738
739 offset += count;
740 /* FIXME: do not clear unless necessary. */
741 clear_buffer (buffer);
742 }
743
744 if (numbytes)
745 sparsearray[sparse_index++].numbytes = numbytes;
746 else
747 {
748 sparsearray[sparse_index].offset = offset - 1;
749 sparsearray[sparse_index++].numbytes = 1;
750 }
751
752 close (file);
753 return sparse_index - 1;
754 }
755
756 /*---.
757 | ? |
758 `---*/
759
760 static int
761 finish_sparse_file (int file, off_t *sizeleft, off_t fullsize, char *name)
762 {
763 union block *start;
764 size_t bufsize;
765 int sparse_index = 0;
766 ssize_t count;
767
768 while (*sizeleft > 0)
769 {
770 start = find_next_block ();
771 memset (start->buffer, 0, BLOCKSIZE);
772 bufsize = sparsearray[sparse_index].numbytes;
773 if (!bufsize)
774 {
775 /* We blew it, maybe. */
776 char buf1[UINTMAX_STRSIZE_BOUND];
777 char buf2[UINTMAX_STRSIZE_BOUND];
778
779 ERROR ((0, 0, _("Wrote %s of %s bytes to file %s"),
780 STRINGIFY_BIGINT (fullsize - *sizeleft, buf1),
781 STRINGIFY_BIGINT (fullsize, buf2), quote (name)));
782 break;
783 }
784
785 if (lseek (file, sparsearray[sparse_index++].offset, SEEK_SET) < 0)
786 {
787 char buf[UINTMAX_STRSIZE_BOUND];
788 int e = errno;
789 ERROR ((0, e, _("lseek error at byte %s in file %s"),
790 STRINGIFY_BIGINT (sparsearray[sparse_index - 1].offset,
791 buf),
792 quote (name)));
793 break;
794 }
795
796 /* If the number of bytes to be written here exceeds the size of
797 the temporary buffer, do it in steps. */
798
799 while (bufsize > BLOCKSIZE)
800 {
801 #if 0
802 if (amount_read)
803 {
804 count = safe_read (file, start->buffer + amount_read,
805 BLOCKSIZE - amount_read);
806 bufsize -= BLOCKSIZE - amount_read;
807 amount_read = 0;
808 set_next_block_after (start);
809 start = find_next_block ();
810 memset (start->buffer, 0, BLOCKSIZE);
811 }
812 #endif
813 /* Store the data. */
814
815 count = safe_read (file, start->buffer, BLOCKSIZE);
816 if (count < 0)
817 {
818 char buf[UINTMAX_STRSIZE_BOUND];
819 int e = errno;
820 ERROR ((0, e,
821 _("Read error at byte %s, reading %lu bytes, in file %s"),
822 STRINGIFY_BIGINT (fullsize - *sizeleft, buf),
823 (unsigned long) bufsize, quote (name)));
824 return 1;
825 }
826 bufsize -= count;
827 *sizeleft -= count;
828 set_next_block_after (start);
829 start = find_next_block ();
830 memset (start->buffer, 0, BLOCKSIZE);
831 }
832
833 {
834 char buffer[BLOCKSIZE];
835
836 clear_buffer (buffer);
837 count = safe_read (file, buffer, bufsize);
838 memcpy (start->buffer, buffer, BLOCKSIZE);
839 }
840
841 if (count < 0)
842 {
843 char buf[UINTMAX_STRSIZE_BOUND];
844 int e = errno;
845 ERROR ((0, e,
846 _("Read error at byte %s, reading %lu bytes, in file %s"),
847 STRINGIFY_BIGINT (fullsize - *sizeleft, buf),
848 (unsigned long) bufsize, quote (name)));
849 return 1;
850 }
851 #if 0
852 if (amount_read >= BLOCKSIZE)
853 {
854 amount_read = 0;
855 set_next_block_after (start + (count - 1) / BLOCKSIZE);
856 if (count != bufsize)
857 {
858 ERROR ((0, 0,
859 _("File %s shrunk, padding with zeros"), quote (name)));
860 return 1;
861 }
862 start = find_next_block ();
863 }
864 else
865 amount_read += bufsize;
866 #endif
867 *sizeleft -= count;
868 set_next_block_after (start);
869
870 }
871 free (sparsearray);
872 #if 0
873 set_next_block_after (start + (count - 1) / BLOCKSIZE);
874 #endif
875 return 0;
876 }
877 \f
878 /* Main functions of this module. */
879
880 /*---.
881 | ? |
882 `---*/
883
884 void
885 create_archive (void)
886 {
887 char *p;
888
889 open_archive (ACCESS_WRITE);
890
891 if (incremental_option)
892 {
893 char *buffer = xmalloc (PATH_MAX);
894 const char *q;
895 char *bufp;
896
897 collect_and_sort_names ();
898
899 while (p = name_from_list (), p)
900 if (!excluded_name (p))
901 dump_file (p, -1, (dev_t) 0);
902
903 blank_name_list ();
904 while (p = name_from_list (), p)
905 if (!excluded_name (p))
906 {
907 strcpy (buffer, p);
908 if (p[strlen (p) - 1] != '/')
909 strcat (buffer, "/");
910 bufp = buffer + strlen (buffer);
911 q = gnu_list_name->dir_contents;
912 if (q)
913 for (; *q; q += strlen (q) + 1)
914 if (*q == 'Y')
915 {
916 strcpy (bufp, q + 1);
917 dump_file (buffer, -1, (dev_t) 0);
918 }
919 }
920 free (buffer);
921 }
922 else
923 {
924 while (p = name_next (1), p)
925 if (!excluded_name (p))
926 dump_file (p, 1, (dev_t) 0);
927 }
928
929 write_eot ();
930 close_archive ();
931
932 if (listed_incremental_option)
933 write_directory_file ();
934 }
935
936 /* Dump a single file, recursing on directories. P is the file name
937 to dump. TOP_LEVEL tells whether this is a top-level call; zero
938 means no, positive means yes, and negative means an incremental
939 dump. PARENT_DEVICE is the device of P's
940 parent directory; it is examined only if TOP_LEVEL is zero.
941
942 Set global CURRENT_STAT to stat output for this file. */
943
944 /* FIXME: One should make sure that for *every* path leading to setting
945 exit_status to failure, a clear diagnostic has been issued. */
946
947 void
948 dump_file (char *p, int top_level, dev_t parent_device)
949 {
950 union block *header;
951 char type;
952 union block *exhdr;
953 char save_typeflag;
954 time_t original_ctime;
955 struct utimbuf restore_times;
956
957 /* FIXME: `header' and `upperbound' might be used uninitialized in this
958 function. Reported by Bruno Haible. */
959
960 if (interactive_option && !confirm ("add", p))
961 return;
962
963 if (deref_stat (dereference_option, p, &current_stat) != 0)
964 {
965 if (ignore_failed_read_option)
966 stat_error (p);
967 else
968 stat_warn (p);
969 return;
970 }
971
972 original_ctime = current_stat.st_ctime;
973 restore_times.actime = current_stat.st_atime;
974 restore_times.modtime = current_stat.st_mtime;
975
976 #ifdef S_ISHIDDEN
977 if (S_ISHIDDEN (current_stat.st_mode))
978 {
979 char *new = (char *) alloca (strlen (p) + 2);
980 if (new)
981 {
982 strcpy (new, p);
983 strcat (new, "@");
984 p = new;
985 }
986 }
987 #endif
988
989 /* See if we want only new files, and check if this one is too old to
990 put in the archive. */
991
992 if ((0 < top_level || !incremental_option)
993 && !S_ISDIR (current_stat.st_mode)
994 && current_stat.st_mtime < newer_mtime_option
995 && (!after_date_option || current_stat.st_ctime < newer_ctime_option))
996 {
997 if (0 < top_level)
998 WARN ((0, 0, _("%s is unchanged; not dumped"), quote (p)));
999 /* FIXME: recheck this return. */
1000 return;
1001 }
1002
1003 #if !MSDOS
1004 /* See if we are trying to dump the archive. */
1005
1006 if (ar_dev && current_stat.st_dev == ar_dev && current_stat.st_ino == ar_ino)
1007 {
1008 WARN ((0, 0, _("%s is the archive; not dumped"), quote (p)));
1009 return;
1010 }
1011 #endif
1012
1013 if (S_ISDIR (current_stat.st_mode))
1014 {
1015 DIR *directory;
1016 struct dirent *entry;
1017 char *namebuf;
1018 size_t buflen;
1019 size_t len;
1020 dev_t our_device = current_stat.st_dev;
1021
1022 errno = 0;
1023
1024 directory = opendir (p);
1025 if (! directory)
1026 {
1027 if (ignore_failed_read_option)
1028 opendir_warn (p);
1029 else
1030 opendir_error (p);
1031 return;
1032 }
1033
1034 /* Build new prototype name. Ensure exactly one trailing slash. */
1035
1036 len = strlen (p);
1037 buflen = len + NAME_FIELD_SIZE;
1038 namebuf = xmalloc (buflen + 1);
1039 strncpy (namebuf, p, buflen);
1040 while (len >= 1 && namebuf[len - 1] == '/')
1041 len--;
1042 namebuf[len++] = '/';
1043 namebuf[len] = '\0';
1044
1045 if (! is_avoided_name (namebuf))
1046 {
1047 /* The condition above used to be "archive_format != V7_FORMAT".
1048 GNU tar was not writing directory blocks at all. Daniel Trinkle
1049 writes: ``All old versions of tar I have ever seen have
1050 correctly archived an empty directory. The really old ones I
1051 checked included HP-UX 7 and Mt. Xinu More/BSD. There may be
1052 some subtle reason for the exclusion that I don't know, but the
1053 current behavior is broken.'' I do not know those subtle
1054 reasons either, so until these are reported (anew?), just allow
1055 directory blocks to be written even with old archives. */
1056
1057 current_stat.st_size = 0; /* force 0 size on dir */
1058
1059 /* FIXME: If people could really read standard archives, this
1060 should be:
1061
1062 header
1063 = start_header (standard_option ? p : namebuf, &current_stat);
1064
1065 but since they'd interpret DIRTYPE blocks as regular
1066 files, we'd better put the / on the name. */
1067
1068 header = start_header (namebuf, &current_stat);
1069
1070 if (incremental_option)
1071 header->header.typeflag = GNUTYPE_DUMPDIR;
1072 else /* if (standard_option) */
1073 header->header.typeflag = DIRTYPE;
1074
1075 /* If we're gnudumping, we aren't done yet so don't close it. */
1076
1077 if (!incremental_option)
1078 finish_header (header); /* done with directory header */
1079 }
1080
1081 if (incremental_option && gnu_list_name->dir_contents)
1082 {
1083 off_t sizeleft;
1084 off_t totsize;
1085 size_t bufsize;
1086 union block *start;
1087 ssize_t count;
1088 const char *buffer, *p_buffer;
1089
1090 buffer = gnu_list_name->dir_contents; /* FOO */
1091 totsize = 0;
1092 for (p_buffer = buffer; p_buffer && *p_buffer;)
1093 {
1094 size_t tmp;
1095
1096 tmp = strlen (p_buffer) + 1;
1097 totsize += tmp;
1098 p_buffer += tmp;
1099 }
1100 totsize++;
1101 OFF_TO_CHARS (totsize, header->header.size);
1102 finish_header (header);
1103 p_buffer = buffer;
1104 sizeleft = totsize;
1105 while (sizeleft > 0)
1106 {
1107 if (multi_volume_option)
1108 {
1109 assign_string (&save_name, p);
1110 save_sizeleft = sizeleft;
1111 save_totsize = totsize;
1112 }
1113 start = find_next_block ();
1114 bufsize = available_space_after (start);
1115 if (sizeleft < bufsize)
1116 {
1117 bufsize = sizeleft;
1118 count = bufsize % BLOCKSIZE;
1119 if (count)
1120 memset (start->buffer + sizeleft, 0, BLOCKSIZE - count);
1121 }
1122 memcpy (start->buffer, p_buffer, bufsize);
1123 sizeleft -= bufsize;
1124 p_buffer += bufsize;
1125 set_next_block_after (start + (bufsize - 1) / BLOCKSIZE);
1126 }
1127 if (multi_volume_option)
1128 assign_string (&save_name, 0);
1129 if (atime_preserve_option)
1130 utime (p, &restore_times);
1131 return;
1132 }
1133
1134 /* See if we are about to recurse into a directory, and avoid doing
1135 so if the user wants that we do not descend into directories. */
1136
1137 if (no_recurse_option)
1138 return;
1139
1140 /* See if we are crossing from one file system to another, and
1141 avoid doing so if the user only wants to dump one file system. */
1142
1143 if (one_file_system_option && !top_level
1144 && parent_device != current_stat.st_dev)
1145 {
1146 if (verbose_option)
1147 WARN ((0, 0, _("%s is on a different filesystem; not dumped"),
1148 quote (p)));
1149 return;
1150 }
1151
1152 /* Now output all the files in the directory. */
1153
1154 /* FIXME: Should speed this up by cd-ing into the dir. */
1155
1156 while (errno = 0, (entry = readdir (directory)))
1157 {
1158 /* Skip `.', `..', and excluded file names. */
1159
1160 if (is_dot_or_dotdot (entry->d_name))
1161 continue;
1162
1163 if ((int) NAMLEN (entry) + len >= buflen)
1164 {
1165 buflen = len + NAMLEN (entry);
1166 namebuf = xrealloc (namebuf, buflen + 1);
1167 }
1168 strcpy (namebuf + len, entry->d_name);
1169 if (!excluded_name (namebuf))
1170 dump_file (namebuf, 0, our_device);
1171 }
1172
1173 if (errno)
1174 {
1175 if (ignore_failed_read_option)
1176 readdir_warn (p);
1177 else
1178 readdir_error (p);
1179 }
1180
1181 if (closedir (directory) != 0)
1182 closedir_error (p);
1183 free (namebuf);
1184 if (atime_preserve_option)
1185 utime (p, &restore_times);
1186 return;
1187 }
1188 else if (is_avoided_name (p))
1189 return;
1190 else
1191 {
1192 /* Check for multiple links.
1193
1194 We maintain a list of all such files that we've written so far. Any
1195 time we see another, we check the list and avoid dumping the data
1196 again if we've done it once already. */
1197
1198 if (1 < current_stat.st_nlink)
1199 {
1200 struct link *lp;
1201
1202 /* FIXME: First quick and dirty. Hashing, etc later. */
1203
1204 for (lp = linklist; lp; lp = lp->next)
1205 if (lp->ino == current_stat.st_ino
1206 && lp->dev == current_stat.st_dev)
1207 {
1208 char *link_name = lp->name;
1209
1210 /* We found a link. */
1211
1212 while (!absolute_names_option && *link_name == '/')
1213 {
1214 static int warned_once;
1215 if (!warned_once)
1216 {
1217 warned_once = 1;
1218 WARN ((0, 0,
1219 _("Removing leading `/' from link names")));
1220 }
1221 link_name++;
1222 }
1223 if (strlen (link_name) >= NAME_FIELD_SIZE)
1224 write_long (link_name, GNUTYPE_LONGLINK);
1225 assign_string (&current_link_name, link_name);
1226
1227 current_stat.st_size = 0;
1228 header = start_header (p, &current_stat);
1229 strncpy (header->header.linkname,
1230 link_name, NAME_FIELD_SIZE);
1231
1232 /* Force null truncated. */
1233
1234 header->header.linkname[NAME_FIELD_SIZE - 1] = 0;
1235
1236 header->header.typeflag = LNKTYPE;
1237 finish_header (header);
1238
1239 /* FIXME: Maybe remove from list after all links found? */
1240
1241 if (remove_files_option)
1242 if (unlink (p) == -1)
1243 unlink_error (p);
1244
1245 /* We dumped it. */
1246 return;
1247 }
1248
1249 /* Not found. Add it to the list of possible links. */
1250
1251 lp = xmalloc (sizeof (struct link) + strlen (p));
1252 lp->ino = current_stat.st_ino;
1253 lp->dev = current_stat.st_dev;
1254 strcpy (lp->name, p);
1255 lp->next = linklist;
1256 linklist = lp;
1257 }
1258
1259 /* This is not a link to a previously dumped file, so dump it. */
1260
1261 if (S_ISREG (current_stat.st_mode)
1262 || S_ISCTG (current_stat.st_mode))
1263 {
1264 int f; /* file descriptor */
1265 size_t bufsize;
1266 ssize_t count;
1267 off_t sizeleft;
1268 union block *start;
1269 int header_moved;
1270 char isextended = 0;
1271 int upperbound;
1272
1273 header_moved = 0;
1274
1275 if (sparse_option)
1276 {
1277 /* Check the size of the file against the number of blocks
1278 allocated for it, counting both data and indirect blocks.
1279 If there is a smaller number of blocks that would be
1280 necessary to accommodate a file of this size, this is safe
1281 to say that we have a sparse file: at least one of those
1282 blocks in the file is just a useless hole. For sparse
1283 files not having more hole blocks than indirect blocks, the
1284 sparseness will go undetected. */
1285
1286 /* Bruno Haible sent me these statistics for Linux. It seems
1287 that some filesystems count indirect blocks in st_blocks,
1288 while others do not seem to:
1289
1290 minix-fs tar: size=7205, st_blocks=18 and ST_NBLOCKS=18
1291 extfs tar: size=7205, st_blocks=18 and ST_NBLOCKS=18
1292 ext2fs tar: size=7205, st_blocks=16 and ST_NBLOCKS=16
1293 msdos-fs tar: size=7205, st_blocks=16 and ST_NBLOCKS=16
1294
1295 Dick Streefland reports the previous numbers as misleading,
1296 because ext2fs use 12 direct blocks, while minix-fs uses only
1297 6 direct blocks. Dick gets:
1298
1299 ext2 size=20480 ls listed blocks=21
1300 minix size=20480 ls listed blocks=21
1301 msdos size=20480 ls listed blocks=20
1302
1303 It seems that indirect blocks *are* included in st_blocks.
1304 The minix filesystem does not account for phantom blocks in
1305 st_blocks, so `du' and `ls -s' give wrong results. So, the
1306 --sparse option would not work on a minix filesystem. */
1307
1308 if (ST_NBLOCKS (current_stat)
1309 < (current_stat.st_size / ST_NBLOCKSIZE
1310 + (current_stat.st_size % ST_NBLOCKSIZE != 0)))
1311 {
1312 off_t filesize = current_stat.st_size;
1313 int counter;
1314
1315 header = start_header (p, &current_stat);
1316 header->header.typeflag = GNUTYPE_SPARSE;
1317 header_moved = 1;
1318
1319 /* Call the routine that figures out the layout of the
1320 sparse file in question. UPPERBOUND is the index of the
1321 last element of the "sparsearray," i.e., the number of
1322 elements it needed to describe the file. */
1323
1324 upperbound = deal_with_sparse (p, header);
1325
1326 /* See if we'll need an extended header later. */
1327
1328 if (upperbound > SPARSES_IN_OLDGNU_HEADER - 1)
1329 header->oldgnu_header.isextended = 1;
1330
1331 /* We store the "real" file size so we can show that in
1332 case someone wants to list the archive, i.e., tar tvf
1333 <file>. It might be kind of disconcerting if the
1334 shrunken file size was the one that showed up. */
1335
1336 OFF_TO_CHARS (current_stat.st_size,
1337 header->oldgnu_header.realsize);
1338
1339 /* This will be the new "size" of the file, i.e., the size
1340 of the file minus the blocks of holes that we're
1341 skipping over. */
1342
1343 find_new_file_size (&filesize, upperbound);
1344 current_stat.st_size = filesize;
1345 OFF_TO_CHARS (filesize, header->header.size);
1346
1347 for (counter = 0; counter < SPARSES_IN_OLDGNU_HEADER; counter++)
1348 {
1349 if (!sparsearray[counter].numbytes)
1350 break;
1351
1352 OFF_TO_CHARS (sparsearray[counter].offset,
1353 header->oldgnu_header.sp[counter].offset);
1354 SIZE_TO_CHARS (sparsearray[counter].numbytes,
1355 header->oldgnu_header.sp[counter].numbytes);
1356 }
1357
1358 }
1359 }
1360 else
1361 upperbound = SPARSES_IN_OLDGNU_HEADER - 1;
1362
1363 sizeleft = current_stat.st_size;
1364
1365 /* Don't bother opening empty, world readable files. Also do not open
1366 files when archive is meant for /dev/null. */
1367
1368 if (dev_null_output
1369 || (sizeleft == 0
1370 && MODE_R == (MODE_R & current_stat.st_mode)))
1371 f = -1;
1372 else
1373 {
1374 f = open (p, O_RDONLY | O_BINARY);
1375 if (f < 0)
1376 {
1377 if (! top_level && errno == ENOENT)
1378 WARN ((0, 0, _("File %s removed before we read it"),
1379 quote (p)));
1380 else if (ignore_failed_read_option)
1381 open_warn (p);
1382 else
1383 open_error (p);
1384 return;
1385 }
1386 }
1387
1388 /* If the file is sparse, we've already taken care of this. */
1389
1390 if (!header_moved)
1391 header = start_header (p, &current_stat);
1392
1393 /* Mark contiguous files, if we support them. */
1394
1395 if (archive_format != V7_FORMAT && S_ISCTG (current_stat.st_mode))
1396 header->header.typeflag = CONTTYPE;
1397
1398 isextended = header->oldgnu_header.isextended;
1399 save_typeflag = header->header.typeflag;
1400 finish_header (header);
1401 if (isextended)
1402 {
1403 int counter;
1404 /* static */ int index_offset = SPARSES_IN_OLDGNU_HEADER;
1405
1406 extend:
1407 exhdr = find_next_block ();
1408 memset (exhdr->buffer, 0, BLOCKSIZE);
1409 for (counter = 0; counter < SPARSES_IN_SPARSE_HEADER; counter++)
1410 {
1411 if (counter + index_offset > upperbound)
1412 break;
1413
1414 SIZE_TO_CHARS (sparsearray[counter + index_offset].numbytes,
1415 exhdr->sparse_header.sp[counter].numbytes);
1416 OFF_TO_CHARS (sparsearray[counter + index_offset].offset,
1417 exhdr->sparse_header.sp[counter].offset);
1418 }
1419 set_next_block_after (exhdr);
1420 if (index_offset + counter <= upperbound)
1421 {
1422 index_offset += counter;
1423 exhdr->sparse_header.isextended = 1;
1424 goto extend;
1425 }
1426
1427 }
1428 if (save_typeflag == GNUTYPE_SPARSE)
1429 {
1430 if (f < 0
1431 || finish_sparse_file (f, &sizeleft,
1432 current_stat.st_size, p))
1433 goto padit;
1434 }
1435 else
1436 while (sizeleft > 0)
1437 {
1438 if (multi_volume_option)
1439 {
1440 assign_string (&save_name, p);
1441 save_sizeleft = sizeleft;
1442 save_totsize = current_stat.st_size;
1443 }
1444 start = find_next_block ();
1445
1446 bufsize = available_space_after (start);
1447
1448 if (sizeleft < bufsize)
1449 {
1450 /* Last read -- zero out area beyond. */
1451
1452 bufsize = sizeleft;
1453 count = bufsize % BLOCKSIZE;
1454 if (count)
1455 memset (start->buffer + sizeleft, 0, BLOCKSIZE - count);
1456 }
1457 if (f < 0)
1458 count = bufsize;
1459 else
1460 count = safe_read (f, start->buffer, bufsize);
1461 if (count < 0)
1462 {
1463 char buf[UINTMAX_STRSIZE_BOUND];
1464 int e = errno;
1465 ERROR ((0, e,
1466 _("Read error at byte %s, reading %lu bytes, in file %s"),
1467 STRINGIFY_BIGINT (current_stat.st_size - sizeleft,
1468 buf),
1469 (unsigned long) bufsize, quote (p)));
1470 goto padit;
1471 }
1472 sizeleft -= count;
1473
1474 /* This is nonportable (the type of set_next_block_after's arg). */
1475
1476 set_next_block_after (start + (count - 1) / BLOCKSIZE);
1477
1478 if (count == bufsize)
1479 continue;
1480 else
1481 {
1482 char buf[UINTMAX_STRSIZE_BOUND];
1483 ERROR ((0, 0,
1484 _("File %s shrunk by %s bytes, padding with zeros"),
1485 quote (p), STRINGIFY_BIGINT (sizeleft, buf)));
1486 goto padit; /* short read */
1487 }
1488 }
1489
1490 if (multi_volume_option)
1491 assign_string (&save_name, 0);
1492
1493 if (f >= 0)
1494 {
1495 struct stat final_stat;
1496 if (fstat (f, &final_stat) != 0)
1497 stat_error (p);
1498 else if (final_stat.st_ctime != original_ctime)
1499 ERROR ((0, 0, _("File %s changed as we read it"), quote (p)));
1500 if (close (f) != 0)
1501 close_error (p);
1502 if (atime_preserve_option)
1503 utime (p, &restore_times);
1504 }
1505 if (remove_files_option)
1506 {
1507 if (unlink (p) == -1)
1508 unlink_error (p);
1509 }
1510 return;
1511
1512 /* File shrunk or gave error, pad out tape to match the size we
1513 specified in the header. */
1514
1515 padit:
1516 while (sizeleft > 0)
1517 {
1518 save_sizeleft = sizeleft;
1519 start = find_next_block ();
1520 memset (start->buffer, 0, BLOCKSIZE);
1521 set_next_block_after (start);
1522 sizeleft -= BLOCKSIZE;
1523 }
1524 if (multi_volume_option)
1525 assign_string (&save_name, 0);
1526 if (f >= 0)
1527 {
1528 close (f);
1529 if (atime_preserve_option)
1530 utime (p, &restore_times);
1531 }
1532 return;
1533 }
1534 #ifdef HAVE_READLINK
1535 else if (S_ISLNK (current_stat.st_mode))
1536 {
1537 int size;
1538 char *buffer = (char *) alloca (PATH_MAX + 1);
1539
1540 size = readlink (p, buffer, PATH_MAX + 1);
1541 if (size < 0)
1542 {
1543 if (ignore_failed_read_option)
1544 readlink_warn (p);
1545 else
1546 readlink_error (p);
1547 return;
1548 }
1549 buffer[size] = '\0';
1550 if (size >= NAME_FIELD_SIZE)
1551 write_long (buffer, GNUTYPE_LONGLINK);
1552 assign_string (&current_link_name, buffer);
1553
1554 current_stat.st_size = 0; /* force 0 size on symlink */
1555 header = start_header (p, &current_stat);
1556 strncpy (header->header.linkname, buffer, NAME_FIELD_SIZE);
1557 header->header.linkname[NAME_FIELD_SIZE - 1] = '\0';
1558 header->header.typeflag = SYMTYPE;
1559 finish_header (header); /* nothing more to do to it */
1560 if (remove_files_option)
1561 {
1562 if (unlink (p) == -1)
1563 unlink_error (p);
1564 }
1565 return;
1566 }
1567 #endif
1568 else if (S_ISCHR (current_stat.st_mode))
1569 type = CHRTYPE;
1570 else if (S_ISBLK (current_stat.st_mode))
1571 type = BLKTYPE;
1572 else if (S_ISFIFO (current_stat.st_mode))
1573 type = FIFOTYPE;
1574 else if (S_ISSOCK (current_stat.st_mode))
1575 {
1576 WARN ((0, 0, _("%s: socket ignored"), quotearg_colon (p)));
1577 return;
1578 }
1579 else if (S_ISDOOR (current_stat.st_mode))
1580 {
1581 WARN ((0, 0, _("%s: door ignored"), quotearg_colon (p)));
1582 return;
1583 }
1584 else
1585 goto unknown;
1586 }
1587
1588 if (archive_format == V7_FORMAT)
1589 goto unknown;
1590
1591 current_stat.st_size = 0; /* force 0 size */
1592 header = start_header (p, &current_stat);
1593 header->header.typeflag = type;
1594
1595 if (type != FIFOTYPE)
1596 {
1597 MAJOR_TO_CHARS (major (current_stat.st_rdev), header->header.devmajor);
1598 MINOR_TO_CHARS (minor (current_stat.st_rdev), header->header.devminor);
1599 }
1600
1601 finish_header (header);
1602 if (remove_files_option)
1603 {
1604 if (unlink (p) == -1)
1605 unlink_error (p);
1606 }
1607 return;
1608
1609 unknown:
1610 ERROR ((0, 0, _("%s: Unknown file type; file ignored"),
1611 quotearg_colon (p)));
1612 }
This page took 0.100418 seconds and 5 git commands to generate.