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