X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Flist.c;h=2cf3c1000aae33f9f09aec7f7629466275a99b12;hb=d4bcefe915fc07ef18615586ab247388582fb45a;hp=425ba7cb45bec3695c2497b1d2a2319ca2191480;hpb=e6e72bf7ed8e6226c0d19118c6a92296e83d45c4;p=chaz%2Ftar diff --git a/src/list.c b/src/list.c index 425ba7c..2cf3c10 100644 --- a/src/list.c +++ b/src/list.c @@ -1,7 +1,7 @@ /* List a tar archive, with support routines for reading a tar archive. - Copyright 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, - 2001 Free Software Foundation, Inc. + Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, + 2001, 2003 Free Software Foundation, Inc. Written by John Gilmore, on 1985-08-26. @@ -37,8 +37,8 @@ union block *recent_long_link; /* likewise, for long link */ size_t recent_long_name_blocks; /* number of blocks in recent_long_name */ size_t recent_long_link_blocks; /* likewise, for long link */ -static uintmax_t from_header PARAMS ((const char *, size_t, const char *, - uintmax_t, uintmax_t)); +static uintmax_t from_header (const char *, size_t, const char *, + uintmax_t, uintmax_t); /* Base 64 digits; see Internet RFC 2045 Table 1. */ static char const base_64_digits[64] = @@ -65,7 +65,7 @@ base64_init (void) /* Main loop for reading an archive. */ void -read_and (void (*do_something) ()) +read_and (void (*do_something) (void)) { enum read_header status = HEADER_STILL_UNREAD; enum read_header prev_status; @@ -103,7 +103,7 @@ read_and (void (*do_something) ()) case GNUTYPE_MULTIVOL: case GNUTYPE_NAMES: break; - + case DIRTYPE: if (show_omitted_dirs_option) WARN ((0, 0, _("%s: Omitting"), @@ -180,7 +180,7 @@ list_archive (void) { if (verbose_option > 1) decode_header (current_header, ¤t_stat, ¤t_format, 0); - print_header (); + print_header (-1); } if (incremental_option && current_header->header.typeflag == GNUTYPE_DUMPDIR) @@ -268,14 +268,14 @@ read_header (bool raw_extended_headers) uintmax_t parsed_sum; char *p; union block *header; - union block **longp; + union block *header_copy; char *bp; union block *data_block; size_t size, written; - static union block *next_long_name; - static union block *next_long_link; - static size_t next_long_name_blocks; - static size_t next_long_link_blocks; + union block *next_long_name = 0; + union block *next_long_link = 0; + size_t next_long_name_blocks; + size_t next_long_link_blocks; while (1) { @@ -338,23 +338,26 @@ read_header (bool raw_extended_headers) xalloc_die (); } + header_copy = xmalloc (size + 1); + if (header->header.typeflag == GNUTYPE_LONGNAME) { - longp = &next_long_name; + if (next_long_name) + free (next_long_name); + next_long_name = header_copy; next_long_name_blocks = size / BLOCKSIZE; } else { - longp = &next_long_link; + if (next_long_link) + free (next_long_link); + next_long_link = header_copy; next_long_link_blocks = size / BLOCKSIZE; } set_next_block_after (header); - if (*longp) - free (*longp); - *longp = xmalloc (size + 1); - **longp = *header; - bp = (*longp)->buffer + BLOCKSIZE; + *header_copy = *header; + bp = header_copy->buffer + BLOCKSIZE; for (size -= BLOCKSIZE; size > 0; size -= written) { @@ -385,6 +388,9 @@ read_header (bool raw_extended_headers) struct posix_header const *h = ¤t_header->header; char namebuf[sizeof h->prefix + 1 + NAME_FIELD_SIZE + 1]; + if (recent_long_name) + free (recent_long_name); + if (next_long_name) { name = next_long_name->buffer + BLOCKSIZE; @@ -412,10 +418,15 @@ read_header (bool raw_extended_headers) memcpy (np, h->name, sizeof h->name); np[sizeof h->name] = '\0'; name = namebuf; + recent_long_name = 0; recent_long_name_blocks = 0; } assign_string (¤t_file_name, name); - + current_trailing_slash = strip_trailing_slashes (current_file_name); + + if (recent_long_link) + free (recent_long_link); + if (next_long_link) { name = next_long_link->buffer + BLOCKSIZE; @@ -427,6 +438,7 @@ read_header (bool raw_extended_headers) memcpy (namebuf, h->linkname, sizeof h->linkname); namebuf[sizeof h->linkname] = '\0'; name = namebuf; + recent_long_link = 0; recent_long_link_blocks = 0; } assign_string (¤t_link_name, name); @@ -775,7 +787,7 @@ off_from_header (const char *p, size_t s) size_t size_from_header (const char *p, size_t s) { - return from_header (p, s, "size_t", (uintmax_t) 0, + return from_header (p, s, "size_t", (uintmax_t) 0, (uintmax_t) TYPE_MAXIMUM (size_t)); } @@ -841,8 +853,8 @@ tartime (time_t t) struct tm *tm = localtime (&t); if (tm) { - sprintf (buffer, "%04d-%02d-%02d %02d:%02d:%02d", - tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + sprintf (buffer, "%04ld-%02d-%02d %02d:%02d:%02d", + tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); return buffer; } @@ -887,10 +899,12 @@ static int ugswidth = UGSWIDTH; /* maximum width encountered so far */ #endif void -print_header (void) +print_header (off_t block_ordinal) { char modes[11]; char const *time_stamp; + char *temp_name; + /* These hold formatted ints. */ char uform[UINTMAX_STRSIZE_BOUND], gform[UINTMAX_STRSIZE_BOUND]; char *user, *group; @@ -902,14 +916,30 @@ print_header (void) if (block_number_option) { char buf[UINTMAX_STRSIZE_BOUND]; + if (block_ordinal < 0) + block_ordinal = current_block_ordinal (); + block_ordinal -= recent_long_name_blocks; + block_ordinal -= recent_long_link_blocks; fprintf (stdlis, _("block %s: "), - STRINGIFY_BIGINT (current_block_ordinal (), buf)); + STRINGIFY_BIGINT (block_ordinal, buf)); } + if (current_trailing_slash) + { + temp_name = xmalloc (strlen (current_file_name) + 2); + strcpy (temp_name, current_file_name); + strcat (temp_name, "/"); + } + else + { + temp_name = xmalloc (strlen (current_file_name) + 1); + strcpy (temp_name, current_file_name); + } + if (verbose_option <= 1) { /* Just the fax, mam. */ - fprintf (stdlis, "%s\n", quotearg (current_file_name)); + fprintf (stdlis, "%s\n", quotearg (temp_name)); } else { @@ -932,17 +962,20 @@ print_header (void) case GNUTYPE_LONGNAME: case GNUTYPE_LONGLINK: + modes[0] = 'L'; ERROR ((0, 0, _("Visible longname error"))); break; case GNUTYPE_SPARSE: case REGTYPE: case AREGTYPE: - case LNKTYPE: modes[0] = '-'; - if (current_file_name[strlen (current_file_name) - 1] == '/') + if (temp_name[strlen (temp_name) - 1] == '/') modes[0] = 'd'; break; + case LNKTYPE: + modes[0] = 'h'; + break; case GNUTYPE_DUMPDIR: modes[0] = 'd'; break; @@ -1051,7 +1084,7 @@ print_header (void) fprintf (stdlis, "%s %s/%s %*s%s %s", modes, user, group, ugswidth - pad, "", size, time_stamp); - fprintf (stdlis, " %s", quotearg (current_file_name)); + fprintf (stdlis, " %s", quotearg (temp_name)); switch (current_header->header.typeflag) { @@ -1085,6 +1118,14 @@ print_header (void) putc ('\n', stdlis); break; + case GNUTYPE_LONGLINK: + fprintf (stdlis, _("--Long Link--\n")); + break; + + case GNUTYPE_LONGNAME: + fprintf (stdlis, _("--Long Name--\n")); + break; + case GNUTYPE_VOLHDR: fprintf (stdlis, _("--Volume Header--\n")); break; @@ -1102,6 +1143,7 @@ print_header (void) break; } } + free (temp_name); fflush (stdlis); }