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