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