]> Dogcows Code - chaz/tar/blob - src/list.c
GNU tar 1.12
[chaz/tar] / src / list.c
1 /* List a tar archive, with support routines for reading a tar archive.
2 Copyright (C) 1988, 92, 93, 94, 96, 97 Free Software Foundation, Inc.
3 Written by John Gilmore, on 1985-08-26.
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 /* Define to non-zero for forcing old ctime() instead of isotime(). */
20 #undef USE_OLD_CTIME
21
22 #include "system.h"
23
24 #include <ctype.h>
25 #include <time.h>
26
27 #define ISODIGIT(Char) \
28 ((unsigned char) (Char) >= '0' && (unsigned char) (Char) <= '7')
29 #define ISSPACE(Char) (ISASCII (Char) && isspace (Char))
30
31 #include "common.h"
32
33 union block *current_header; /* points to current archive header */
34 struct stat current_stat; /* stat struct corresponding */
35 enum archive_format current_format; /* recognized format */
36
37 /*-----------------------------------.
38 | Main loop for reading an archive. |
39 `-----------------------------------*/
40
41 void
42 read_and (void (*do_something) ())
43 {
44 enum read_header status = HEADER_STILL_UNREAD;
45 enum read_header prev_status;
46 char save_typeflag;
47
48 name_gather ();
49 open_archive (ACCESS_READ);
50
51 while (1)
52 {
53 prev_status = status;
54 status = read_header ();
55 switch (status)
56 {
57 case HEADER_STILL_UNREAD:
58 abort ();
59
60 case HEADER_SUCCESS:
61
62 /* Valid header. We should decode next field (mode) first.
63 Ensure incoming names are null terminated. */
64
65 /* FIXME: This is a quick kludge before 1.12 goes out. */
66 current_stat.st_mtime
67 = from_oct (1 + 12, current_header->header.mtime);
68
69 if (!name_match (current_file_name)
70 || current_stat.st_mtime < newer_mtime_option
71 || (exclude_option && check_exclude (current_file_name)))
72 {
73 int isextended = 0;
74
75 if (current_header->header.typeflag == GNUTYPE_VOLHDR
76 || current_header->header.typeflag == GNUTYPE_MULTIVOL
77 || current_header->header.typeflag == GNUTYPE_NAMES)
78 {
79 (*do_something) ();
80 continue;
81 }
82 if (show_omitted_dirs_option
83 && current_header->header.typeflag == DIRTYPE)
84 WARN ((0, 0, _("Omitting %s"), current_file_name));
85
86 /* Skip past it in the archive. */
87
88 if (current_header->oldgnu_header.isextended)
89 isextended = 1;
90 save_typeflag = current_header->header.typeflag;
91 set_next_block_after (current_header);
92 if (isextended)
93 {
94 #if 0
95 union block *exhdr;
96
97 while (1)
98 {
99 exhdr = find_next_block ();
100 if (!exhdr->sparse_header.isextended)
101 {
102 set_next_block_after (exhdr);
103 break;
104 }
105 }
106 set_next_block_after (exhdr);
107 #endif
108 skip_extended_headers ();
109 }
110
111 /* Skip to the next header on the archive. */
112
113 if (save_typeflag != DIRTYPE)
114 skip_file ((long) current_stat.st_size);
115 continue;
116 }
117
118 (*do_something) ();
119 continue;
120
121 case HEADER_ZERO_BLOCK:
122 if (block_number_option)
123 fprintf (stdlis, _("block %10ld: ** Block of NULs **\n"),
124 current_block_ordinal ());
125
126 set_next_block_after (current_header);
127 status = prev_status;
128 if (ignore_zeros_option)
129 continue;
130 break;
131
132 case HEADER_END_OF_FILE:
133 if (block_number_option)
134 fprintf (stdlis, _("block %10ld: ** End of File **\n"),
135 current_block_ordinal ());
136 break;
137
138 case HEADER_FAILURE:
139 /* If the previous header was good, tell them that we are
140 skipping bad ones. */
141 set_next_block_after (current_header);
142 switch (prev_status)
143 {
144 case HEADER_STILL_UNREAD:
145 WARN ((0, 0, _("Hmm, this doesn't look like a tar archive")));
146 /* Fall through. */
147
148 case HEADER_ZERO_BLOCK:
149 case HEADER_SUCCESS:
150 WARN ((0, 0, _("Skipping to next file header")));
151 break;
152
153 case HEADER_END_OF_FILE:
154 case HEADER_FAILURE:
155 /* We are in the middle of a cascade of errors. */
156 break;
157 }
158 continue;
159 }
160 break;
161 }
162
163 apply_delayed_set_stat ();
164 close_archive ();
165 names_notfound (); /* print names not found */
166 }
167
168 /*---------------------------------------------.
169 | Print a header block, based on tar options. |
170 `---------------------------------------------*/
171
172 void
173 list_archive (void)
174 {
175 int isextended = 0; /* to remember if current_header is extended */
176
177 /* Print the header block. */
178
179 if (verbose_option)
180 {
181 if (verbose_option > 1)
182 decode_header (current_header, &current_stat, &current_format, 0);
183 print_header ();
184 }
185
186 if (incremental_option && current_header->header.typeflag == GNUTYPE_DUMPDIR)
187 {
188 size_t size, written, check;
189 union block *data_block;
190
191 set_next_block_after (current_header);
192 if (multi_volume_option)
193 {
194 assign_string (&save_name, current_file_name);
195 save_totsize = current_stat.st_size;
196 }
197 for (size = current_stat.st_size; size > 0; size -= written)
198 {
199 if (multi_volume_option)
200 save_sizeleft = size;
201 data_block = find_next_block ();
202 if (!data_block)
203 {
204 ERROR ((0, 0, _("EOF in archive file")));
205 break; /* FIXME: What happens, then? */
206 }
207 written = available_space_after (data_block);
208 if (written > size)
209 written = size;
210 errno = 0; /* FIXME: errno should be read-only */
211 check = fwrite (data_block->buffer, sizeof (char), written, stdlis);
212 set_next_block_after ((union block *)
213 (data_block->buffer + written - 1));
214 if (check != written)
215 {
216 ERROR ((0, errno, _("Only wrote %ld of %ld bytes to file %s"),
217 check, written, current_file_name));
218 skip_file ((long) (size - written));
219 break;
220 }
221 }
222 if (multi_volume_option)
223 assign_string (&save_name, NULL);
224 fputc ('\n', stdlis);
225 fflush (stdlis);
226 return;
227
228 }
229
230 /* Check to see if we have an extended header to skip over also. */
231
232 if (current_header->oldgnu_header.isextended)
233 isextended = 1;
234
235 /* Skip past the header in the archive. */
236
237 set_next_block_after (current_header);
238
239 /* If we needed to skip any extended headers, do so now, by reading
240 extended headers and skipping past them in the archive. */
241
242 if (isextended)
243 {
244 #if 0
245 union block *exhdr;
246
247 while (1)
248 {
249 exhdr = find_next_block ();
250
251 if (!exhdr->sparse_header.isextended)
252 {
253 set_next_block_after (exhdr);
254 break;
255 }
256 set_next_block_after (exhdr);
257 }
258 #endif
259 skip_extended_headers ();
260 }
261
262 if (multi_volume_option)
263 assign_string (&save_name, current_file_name);
264
265 /* Skip to the next header on the archive. */
266
267 skip_file ((long) current_stat.st_size);
268
269 if (multi_volume_option)
270 assign_string (&save_name, NULL);
271 }
272
273 /*-----------------------------------------------------------------------.
274 | Read a block that's supposed to be a header block. Return its address |
275 | in "current_header", and if it is good, the file's size in |
276 | current_stat.st_size. |
277 | |
278 | Return 1 for success, 0 if the checksum is bad, EOF on eof, 2 for a |
279 | block full of zeros (EOF marker). |
280 | |
281 | You must always set_next_block_after(current_header) to skip past the |
282 | header which this routine reads. |
283 `-----------------------------------------------------------------------*/
284
285 /* The standard BSD tar sources create the checksum by adding up the
286 bytes in the header as type char. I think the type char was unsigned
287 on the PDP-11, but it's signed on the Next and Sun. It looks like the
288 sources to BSD tar were never changed to compute the checksum
289 currectly, so both the Sun and Next add the bytes of the header as
290 signed chars. This doesn't cause a problem until you get a file with
291 a name containing characters with the high bit set. So read_header
292 computes two checksums -- signed and unsigned. */
293
294 /* FIXME: The signed checksum computation is broken on machines where char's
295 are unsigned. It's uneasy to handle all cases correctly... */
296
297 enum read_header
298 read_header (void)
299 {
300 int i;
301 long unsigned_sum; /* the POSIX one :-) */
302 long signed_sum; /* the Sun one :-( */
303 long recorded_sum;
304 char *p;
305 union block *header;
306 char **longp;
307 char *bp;
308 union block *data_block;
309 int size, written;
310 static char *next_long_name, *next_long_link;
311
312 while (1)
313 {
314 header = find_next_block ();
315 current_header = header;
316 if (!header)
317 return HEADER_END_OF_FILE;
318
319 recorded_sum
320 = from_oct (sizeof header->header.chksum, header->header.chksum);
321
322 unsigned_sum = 0;
323 signed_sum = 0;
324 p = header->buffer;
325 for (i = sizeof (*header); --i >= 0;)
326 {
327 /* We can't use unsigned char here because of old compilers,
328 e.g. V7. */
329
330 unsigned_sum += 0xFF & *p;
331 signed_sum += *p++;
332 }
333
334 /* Adjust checksum to count the "chksum" field as blanks. */
335
336 for (i = sizeof (header->header.chksum); --i >= 0;)
337 {
338 unsigned_sum -= 0xFF & header->header.chksum[i];
339 signed_sum -= header->header.chksum[i];
340 }
341 unsigned_sum += ' ' * sizeof header->header.chksum;
342 signed_sum += ' ' * sizeof header->header.chksum;
343
344 if (unsigned_sum == sizeof header->header.chksum * ' ')
345 {
346 /* This is a zeroed block...whole block is 0's except for the
347 blanks we faked for the checksum field. */
348
349 return HEADER_ZERO_BLOCK;
350 }
351
352 if (unsigned_sum != recorded_sum && signed_sum != recorded_sum)
353 return HEADER_FAILURE;
354
355 /* Good block. Decode file size and return. */
356
357 if (header->header.typeflag == LNKTYPE)
358 current_stat.st_size = 0; /* links 0 size on tape */
359 else
360 current_stat.st_size = from_oct (1 + 12, header->header.size);
361
362 header->header.name[NAME_FIELD_SIZE - 1] = '\0';
363 if (header->header.typeflag == GNUTYPE_LONGNAME
364 || header->header.typeflag == GNUTYPE_LONGLINK)
365 {
366 longp = ((header->header.typeflag == GNUTYPE_LONGNAME)
367 ? &next_long_name
368 : &next_long_link);
369
370 set_next_block_after (header);
371 if (*longp)
372 free (*longp);
373 bp = *longp = (char *) xmalloc ((size_t) current_stat.st_size);
374
375 for (size = current_stat.st_size; size > 0; size -= written)
376 {
377 data_block = find_next_block ();
378 if (data_block == NULL)
379 {
380 ERROR ((0, 0, _("Unexpected EOF on archive file")));
381 break;
382 }
383 written = available_space_after (data_block);
384 if (written > size)
385 written = size;
386
387 memcpy (bp, data_block->buffer, (size_t) written);
388 bp += written;
389 set_next_block_after ((union block *)
390 (data_block->buffer + written - 1));
391 }
392
393 /* Loop! */
394
395 }
396 else
397 {
398 assign_string (&current_file_name,
399 (next_long_name ? next_long_name
400 : current_header->header.name));
401 assign_string (&current_link_name,
402 (next_long_link ? next_long_link
403 : current_header->header.linkname));
404 next_long_link = next_long_name = 0;
405 return HEADER_SUCCESS;
406 }
407 }
408 }
409
410 /*-------------------------------------------------------------------------.
411 | Decode things from a file HEADER block into STAT_INFO, also setting |
412 | *FORMAT_POINTER depending on the header block format. If DO_USER_GROUP, |
413 | decode the user/group information (this is useful for extraction, but |
414 | waste time when merely listing). |
415 | |
416 | read_header() has already decoded the checksum and length, so we don't. |
417 | |
418 | This routine should *not* be called twice for the same block, since the |
419 | two calls might use different DO_USER_GROUP values and thus might end up |
420 | with different uid/gid for the two calls. If anybody wants the uid/gid |
421 | they should decode it first, and other callers should decode it without |
422 | uid/gid before calling a routine, e.g. print_header, that assumes |
423 | decoded data. |
424 `-------------------------------------------------------------------------*/
425
426 void
427 decode_header (union block *header, struct stat *stat_info,
428 enum archive_format *format_pointer, int do_user_group)
429 {
430 enum archive_format format;
431
432 if (strcmp (header->header.magic, TMAGIC) == 0)
433 format = POSIX_FORMAT;
434 else if (strcmp (header->header.magic, OLDGNU_MAGIC) == 0)
435 format = OLDGNU_FORMAT;
436 else
437 format = V7_FORMAT;
438 *format_pointer = format;
439
440 stat_info->st_mode = from_oct (8, header->header.mode);
441 stat_info->st_mode &= 07777;
442 stat_info->st_mtime = from_oct (1 + 12, header->header.mtime);
443
444 if (format == OLDGNU_FORMAT && incremental_option)
445 {
446 stat_info->st_atime = from_oct (1 + 12, header->oldgnu_header.atime);
447 stat_info->st_ctime = from_oct (1 + 12, header->oldgnu_header.ctime);
448 }
449
450 if (format == V7_FORMAT)
451 {
452 stat_info->st_uid = from_oct (8, header->header.uid);
453 stat_info->st_gid = from_oct (8, header->header.gid);
454 stat_info->st_rdev = 0;
455 }
456 else
457 {
458 if (do_user_group)
459 {
460 /* FIXME: Decide if this should somewhat depend on -p. */
461
462 if (numeric_owner_option
463 || !*header->header.uname
464 || !uname_to_uid (header->header.uname, &stat_info->st_uid))
465 stat_info->st_uid = from_oct (8, header->header.uid);
466
467 if (numeric_owner_option
468 || !*header->header.gname
469 || !gname_to_gid (header->header.gname, &stat_info->st_gid))
470 stat_info->st_gid = from_oct (8, header->header.gid);
471 }
472 switch (header->header.typeflag)
473 {
474 #ifdef S_IFBLK
475 case BLKTYPE:
476 stat_info->st_rdev = makedev (from_oct (8, header->header.devmajor),
477 from_oct (8, header->header.devminor));
478 break;
479 #endif
480
481 #ifdef S_IFCHR
482 case CHRTYPE:
483 stat_info->st_rdev = makedev (from_oct (8, header->header.devmajor),
484 from_oct (8, header->header.devminor));
485 break;
486 #endif
487
488 default:
489 stat_info->st_rdev = 0;
490 }
491 }
492 }
493
494 /*------------------------------------------------------------------------.
495 | Quick and dirty octal conversion. Result is -1 if the field is invalid |
496 | (all blank, or nonoctal). |
497 `------------------------------------------------------------------------*/
498
499 long
500 from_oct (int digs, char *where)
501 {
502 long value;
503
504 while (ISSPACE (*where))
505 { /* skip spaces */
506 where++;
507 if (--digs <= 0)
508 return -1; /* all blank field */
509 }
510 value = 0;
511 while (digs > 0 && ISODIGIT (*where))
512 {
513 /* Scan til nonoctal. */
514
515 value = (value << 3) | (*where++ - '0');
516 --digs;
517 }
518
519 if (digs > 0 && *where && !ISSPACE (*where))
520 return -1; /* ended on non-space/nul */
521
522 return value;
523 }
524
525 #if !USE_OLD_CTIME
526
527 /*-------------------------------------------.
528 | Return the time formatted along ISO 8601. |
529 `-------------------------------------------*/
530
531 /* Also, see http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html. */
532
533 static char *
534 isotime (const time_t *time)
535 {
536 static char buffer[21];
537 struct tm *tm;
538
539 tm = localtime (time);
540 sprintf (buffer, "%4d-%02d-%02d %02d:%02d:%02d\n",
541 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
542 tm->tm_hour, tm->tm_min, tm->tm_sec);
543 return buffer;
544 }
545
546 #endif /* not USE_OLD_CTIME */
547
548 /*-------------------------------------------------------------------------.
549 | Decode MODE from its binary form in a stat structure, and encode it into |
550 | a 9 characters string STRING, terminated with a NUL. |
551 `-------------------------------------------------------------------------*/
552
553 static void
554 decode_mode (unsigned mode, char *string)
555 {
556 unsigned mask;
557 const char *rwx = "rwxrwxrwx";
558
559 for (mask = 0400; mask != 0; mask >>= 1)
560 if (mode & mask)
561 *string++ = *rwx++;
562 else
563 {
564 *string++ = '-';
565 rwx++;
566 }
567
568 if (mode & S_ISUID)
569 string[-7] = string[-7] == 'x' ? 's' : 'S';
570 if (mode & S_ISGID)
571 string[-4] = string[-4] == 'x' ? 's' : 'S';
572 if (mode & S_ISVTX)
573 string[-1] = string[-1] == 'x' ? 't' : 'T';
574
575 *string = '\0';
576 }
577
578 /*-------------------------------------------------------------------------.
579 | Actually print it. |
580 | |
581 | Plain and fancy file header block logging. Non-verbose just prints the |
582 | name, e.g. for "tar t" or "tar x". This should just contain file names, |
583 | so it can be fed back into tar with xargs or the "-T" option. The |
584 | verbose option can give a bunch of info, one line per file. I doubt |
585 | anybody tries to parse its format, or if they do, they shouldn't. Unix |
586 | tar is pretty random here anyway. |
587 `-------------------------------------------------------------------------*/
588
589 /* FIXME: Note that print_header uses the globals HEAD, HSTAT, and
590 HEAD_STANDARD, which must be set up in advance. Not very clean... */
591
592 /* UGSWIDTH starts with 18, so with user and group names <= 8 chars, the
593 columns never shift during the listing. */
594 #define UGSWIDTH 18
595 static int ugswidth = UGSWIDTH; /* maximum width encountered so far */
596
597 /* DATEWIDTH is the number of columns taken by the date and time fields. */
598 #if USE_OLD_CDATE
599 # define DATEWIDTH 19
600 #else
601 # define DATEWIDTH 18
602 #endif
603
604 void
605 print_header (void)
606 {
607 char modes[11];
608 char *timestamp;
609 char uform[11], gform[11]; /* these hold formatted ints */
610 char *user, *group;
611 char size[24]; /* holds a formatted long or maj, min */
612 time_t longie; /* to make ctime() call portable */
613 int pad;
614 char *name;
615
616 if (block_number_option)
617 fprintf (stdlis, _("block %10ld: "), current_block_ordinal ());
618
619 if (verbose_option <= 1)
620 {
621 /* Just the fax, mam. */
622
623 char *quoted_name = quote_copy_string (current_file_name);
624
625 if (quoted_name)
626 {
627 fprintf (stdlis, "%s\n", quoted_name);
628 free (quoted_name);
629 }
630 else
631 fprintf (stdlis, "%s\n", current_file_name);
632 }
633 else
634 {
635 /* File type and modes. */
636
637 modes[0] = '?';
638 switch (current_header->header.typeflag)
639 {
640 case GNUTYPE_VOLHDR:
641 modes[0] = 'V';
642 break;
643
644 case GNUTYPE_MULTIVOL:
645 modes[0] = 'M';
646 break;
647
648 case GNUTYPE_NAMES:
649 modes[0] = 'N';
650 break;
651
652 case GNUTYPE_LONGNAME:
653 case GNUTYPE_LONGLINK:
654 ERROR ((0, 0, _("Visible longname error")));
655 break;
656
657 case GNUTYPE_SPARSE:
658 case REGTYPE:
659 case AREGTYPE:
660 case LNKTYPE:
661 modes[0] = '-';
662 if (current_file_name[strlen (current_file_name) - 1] == '/')
663 modes[0] = 'd';
664 break;
665 case GNUTYPE_DUMPDIR:
666 modes[0] = 'd';
667 break;
668 case DIRTYPE:
669 modes[0] = 'd';
670 break;
671 case SYMTYPE:
672 modes[0] = 'l';
673 break;
674 case BLKTYPE:
675 modes[0] = 'b';
676 break;
677 case CHRTYPE:
678 modes[0] = 'c';
679 break;
680 case FIFOTYPE:
681 modes[0] = 'p';
682 break;
683 case CONTTYPE:
684 modes[0] = 'C';
685 break;
686 }
687
688 decode_mode ((unsigned) current_stat.st_mode, modes + 1);
689
690 /* Timestamp. */
691
692 longie = current_stat.st_mtime;
693 #if USE_OLD_CTIME
694 timestamp = ctime (&longie);
695 timestamp[16] = '\0';
696 timestamp[24] = '\0';
697 #else
698 timestamp = isotime (&longie);
699 timestamp[16] = '\0';
700 #endif
701
702 /* User and group names. */
703
704 if (*current_header->header.uname && current_format != V7_FORMAT)
705 user = current_header->header.uname;
706 else
707 {
708 user = uform;
709 sprintf (uform, "%ld", from_oct (8, current_header->header.uid));
710 }
711
712 if (*current_header->header.gname && current_format != V7_FORMAT)
713 group = current_header->header.gname;
714 else
715 {
716 group = gform;
717 sprintf (gform, "%ld", from_oct (8, current_header->header.gid));
718 }
719
720 /* Format the file size or major/minor device numbers. */
721
722 switch (current_header->header.typeflag)
723 {
724 #if defined(S_IFBLK) || defined(S_IFCHR)
725 case CHRTYPE:
726 case BLKTYPE:
727 sprintf (size, "%d,%d",
728 major (current_stat.st_rdev), minor (current_stat.st_rdev));
729 break;
730 #endif
731 case GNUTYPE_SPARSE:
732 sprintf (size, "%ld",
733 from_oct (1 + 12, current_header->oldgnu_header.realsize));
734 break;
735 default:
736 sprintf (size, "%ld", (long) current_stat.st_size);
737 }
738
739 /* Figure out padding and print the whole line. */
740
741 pad = strlen (user) + strlen (group) + strlen (size) + 1;
742 if (pad > ugswidth)
743 ugswidth = pad;
744
745 #if USE_OLD_CTIME
746 fprintf (stdlis, "%s %s/%s %*s%s %s %s",
747 modes, user, group, ugswidth - pad, "",
748 size, timestamp + 4, timestamp + 20);
749 #else
750 fprintf (stdlis, "%s %s/%s %*s%s %s",
751 modes, user, group, ugswidth - pad, "", size, timestamp);
752 #endif
753
754 name = quote_copy_string (current_file_name);
755 if (name)
756 {
757 fprintf (stdlis, " %s", name);
758 free (name);
759 }
760 else
761 fprintf (stdlis, " %s", current_file_name);
762
763 switch (current_header->header.typeflag)
764 {
765 case SYMTYPE:
766 name = quote_copy_string (current_link_name);
767 if (name)
768 {
769 fprintf (stdlis, " -> %s\n", name);
770 free (name);
771 }
772 else
773 fprintf (stdlis, " -> %s\n", current_link_name);
774 break;
775
776 case LNKTYPE:
777 name = quote_copy_string (current_link_name);
778 if (name)
779 {
780 fprintf (stdlis, _(" link to %s\n"), name);
781 free (name);
782 }
783 else
784 fprintf (stdlis, _(" link to %s\n"), current_link_name);
785 break;
786
787 default:
788 fprintf (stdlis, _(" unknown file type `%c'\n"),
789 current_header->header.typeflag);
790 break;
791
792 case AREGTYPE:
793 case REGTYPE:
794 case GNUTYPE_SPARSE:
795 case CHRTYPE:
796 case BLKTYPE:
797 case DIRTYPE:
798 case FIFOTYPE:
799 case CONTTYPE:
800 case GNUTYPE_DUMPDIR:
801 putc ('\n', stdlis);
802 break;
803
804 case GNUTYPE_VOLHDR:
805 fprintf (stdlis, _("--Volume Header--\n"));
806 break;
807
808 case GNUTYPE_MULTIVOL:
809 fprintf (stdlis, _("--Continued at byte %ld--\n"),
810 from_oct (1 + 12, current_header->oldgnu_header.offset));
811 break;
812
813 case GNUTYPE_NAMES:
814 fprintf (stdlis, _("--Mangled file names--\n"));
815 break;
816 }
817 }
818 fflush (stdlis);
819 }
820
821 /*--------------------------------------------------------------.
822 | Print a similar line when we make a directory automatically. |
823 `--------------------------------------------------------------*/
824
825 void
826 print_for_mkdir (char *pathname, int length, int mode)
827 {
828 char modes[11];
829 char *name;
830
831 if (verbose_option > 1)
832 {
833 /* File type and modes. */
834
835 modes[0] = 'd';
836 decode_mode ((unsigned) mode, modes + 1);
837
838 if (block_number_option)
839 fprintf (stdlis, _("block %10ld: "), current_block_ordinal ());
840 name = quote_copy_string (pathname);
841 if (name)
842 {
843 fprintf (stdlis, "%s %*s %.*s\n", modes, ugswidth + DATEWIDTH,
844 _("Creating directory:"), length, name);
845 free (name);
846 }
847 else
848 fprintf (stdlis, "%s %*s %.*s\n", modes, ugswidth + DATEWIDTH,
849 _("Creating directory:"), length, pathname);
850 }
851 }
852
853 /*--------------------------------------------------------.
854 | Skip over SIZE bytes of data in blocks in the archive. |
855 `--------------------------------------------------------*/
856
857 void
858 skip_file (long size)
859 {
860 union block *x;
861
862 if (multi_volume_option)
863 {
864 save_totsize = size;
865 save_sizeleft = size;
866 }
867
868 while (size > 0)
869 {
870 x = find_next_block ();
871 if (x == NULL)
872 FATAL_ERROR ((0, 0, _("Unexpected EOF on archive file")));
873
874 set_next_block_after (x);
875 size -= BLOCKSIZE;
876 if (multi_volume_option)
877 save_sizeleft -= BLOCKSIZE;
878 }
879 }
880
881 /*---.
882 | ? |
883 `---*/
884
885 void
886 skip_extended_headers (void)
887 {
888 union block *exhdr;
889
890 while (1)
891 {
892 exhdr = find_next_block ();
893 if (!exhdr->sparse_header.isextended)
894 {
895 set_next_block_after (exhdr);
896 break;
897 }
898 set_next_block_after (exhdr);
899 }
900 }
This page took 0.0816170000000001 seconds and 5 git commands to generate.