/[tar]/tar/src/list.c
ViewVC logotype

Diff of /tar/src/list.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.51 by gray, Sun Jul 27 12:01:04 2003 UTC revision 1.52 by gray, Sun Aug 31 22:40:34 2003 UTC
# Line 30  Line 30 
30  #define max(a, b) ((a) < (b) ? (b) : (a))  #define max(a, b) ((a) < (b) ? (b) : (a))
31    
32  union block *current_header;    /* points to current archive header */  union block *current_header;    /* points to current archive header */
 struct stat current_stat;       /* stat struct corresponding */  
33  enum archive_format current_format; /* recognized format */  enum archive_format current_format; /* recognized format */
34  union block *recent_long_name;  /* recent long name header and contents */  union block *recent_long_name;  /* recent long name header and contents */
35  union block *recent_long_link;  /* likewise, for long link */  union block *recent_long_link;  /* likewise, for long link */
# Line 88  read_and (void (*do_something) (void)) Line 87  read_and (void (*do_something) (void))
87            /* Valid header.  We should decode next field (mode) first.            /* Valid header.  We should decode next field (mode) first.
88               Ensure incoming names are null terminated.  */               Ensure incoming names are null terminated.  */
89    
90            if (! name_match (current_file_name)            if (! name_match (current_stat_info.file_name)
91                || (newer_mtime_option != TYPE_MINIMUM (time_t)                || (newer_mtime_option != TYPE_MINIMUM (time_t)
92                    /* FIXME: We get mtime now, and again later; this causes                    /* FIXME: We get mtime now, and again later; this causes
93                       duplicate diagnostics if header.mtime is bogus.  */                       duplicate diagnostics if header.mtime is bogus.  */
94                    && ((current_stat.st_mtime                    && ((current_stat_info.stat.st_mtime
95                         = TIME_FROM_HEADER (current_header->header.mtime))                         = TIME_FROM_HEADER (current_header->header.mtime))
96                        < newer_mtime_option))                        < newer_mtime_option))
97                || excluded_name (current_file_name))                || excluded_name (current_stat_info.file_name))
98              {              {
99                switch (current_header->header.typeflag)                switch (current_header->header.typeflag)
100                  {                  {
# Line 107  read_and (void (*do_something) (void)) Line 106  read_and (void (*do_something) (void))
106                  case DIRTYPE:                  case DIRTYPE:
107                    if (show_omitted_dirs_option)                    if (show_omitted_dirs_option)
108                      WARN ((0, 0, _("%s: Omitting"),                      WARN ((0, 0, _("%s: Omitting"),
109                             quotearg_colon (current_file_name)));                             quotearg_colon (current_stat_info.file_name)));
110                    /* Fall through.  */                    /* Fall through.  */
111                  default:                  default:
112                    skip_member ();                    skip_member ();
# Line 179  list_archive (void) Line 178  list_archive (void)
178    if (verbose_option)    if (verbose_option)
179      {      {
180        if (verbose_option > 1)        if (verbose_option > 1)
181          decode_header (current_header, &current_stat, &current_format, 0);          decode_header (current_header, &current_stat_info, &current_format, 0);
182        print_header (-1);        print_header (-1);
183      }      }
184    
# Line 192  list_archive (void) Line 191  list_archive (void)
191        set_next_block_after (current_header);        set_next_block_after (current_header);
192        if (multi_volume_option)        if (multi_volume_option)
193          {          {
194            assign_string (&save_name, current_file_name);            assign_string (&save_name, current_stat_info.file_name);
195            save_totsize = current_stat.st_size;            save_totsize = current_stat_info.stat.st_size;
196          }          }
197        for (size = current_stat.st_size; size > 0; size -= written)        for (size = current_stat_info.stat.st_size; size > 0; size -= written)
198          {          {
199            if (multi_volume_option)            if (multi_volume_option)
200              save_sizeleft = size;              save_sizeleft = size;
# Line 214  list_archive (void) Line 213  list_archive (void)
213                                  (data_block->buffer + written - 1));                                  (data_block->buffer + written - 1));
214            if (check != written)            if (check != written)
215              {              {
216                write_error_details (current_file_name, check, written);                write_error_details (current_stat_info.file_name, check, written);
217                skip_file (size - written);                skip_file (size - written);
218                break;                break;
219              }              }
# Line 228  list_archive (void) Line 227  list_archive (void)
227      }      }
228    
229    if (multi_volume_option)    if (multi_volume_option)
230      assign_string (&save_name, current_file_name);      assign_string (&save_name, current_stat_info.file_name);
231    
232    skip_member ();    skip_member ();
233    
# Line 238  list_archive (void) Line 237  list_archive (void)
237    
238  /* Read a block that's supposed to be a header block.  Return its  /* Read a block that's supposed to be a header block.  Return its
239     address in "current_header", and if it is good, the file's size in     address in "current_header", and if it is good, the file's size in
240     current_stat.st_size.     current_stat_info.stat.st_size.
241    
242     Return 1 for success, 0 if the checksum is bad, EOF on eof, 2 for a     Return 1 for success, 0 if the checksum is bad, EOF on eof, 2 for a
243     block full of zeros (EOF marker).     block full of zeros (EOF marker).
# Line 320  read_header (bool raw_extended_headers) Line 319  read_header (bool raw_extended_headers)
319    
320        /* Good block.  Decode file size and return.  */        /* Good block.  Decode file size and return.  */
321    
322          if (header->header.typeflag == XHDTYPE
323              || header->header.typeflag == XGLTYPE)
324            {
325              xheader_read (header, OFF_FROM_HEADER (header->header.size));
326              continue;
327            }
328          
329        if (header->header.typeflag == LNKTYPE)        if (header->header.typeflag == LNKTYPE)
330          current_stat.st_size = 0;       /* links 0 size on tape */          current_stat_info.stat.st_size = 0;     /* links 0 size on tape */
331        else        else
332          current_stat.st_size = OFF_FROM_HEADER (header->header.size);          current_stat_info.stat.st_size = OFF_FROM_HEADER (header->header.size);
333    
334        if (header->header.typeflag == GNUTYPE_LONGNAME        if (header->header.typeflag == GNUTYPE_LONGNAME
335            || header->header.typeflag == GNUTYPE_LONGLINK)            || header->header.typeflag == GNUTYPE_LONGLINK)
# Line 332  read_header (bool raw_extended_headers) Line 338  read_header (bool raw_extended_headers)
338              return HEADER_SUCCESS_EXTENDED;              return HEADER_SUCCESS_EXTENDED;
339            else            else
340              {              {
341                size_t name_size = current_stat.st_size;                size_t name_size = current_stat_info.stat.st_size;
342                size = name_size - name_size % BLOCKSIZE + 2 * BLOCKSIZE;                size = name_size - name_size % BLOCKSIZE + 2 * BLOCKSIZE;
343                if (name_size != current_stat.st_size || size < name_size)                if (name_size != current_stat_info.stat.st_size || size < name_size)
344                  xalloc_die ();                  xalloc_die ();
345              }              }
346    
# Line 421  read_header (bool raw_extended_headers) Line 427  read_header (bool raw_extended_headers)
427                recent_long_name = 0;                recent_long_name = 0;
428                recent_long_name_blocks = 0;                recent_long_name_blocks = 0;
429              }              }
430            assign_string (&orig_file_name, name);            assign_string (&current_stat_info.orig_file_name, name);
431            assign_string (&current_file_name, name);            assign_string (&current_stat_info.file_name, name);
432            current_trailing_slash = strip_trailing_slashes (current_file_name);            current_stat_info.had_trailing_slash = strip_trailing_slashes (current_stat_info.file_name);
433    
434            if (recent_long_link)            if (recent_long_link)
435              free (recent_long_link);              free (recent_long_link);
# Line 442  read_header (bool raw_extended_headers) Line 448  read_header (bool raw_extended_headers)
448                recent_long_link = 0;                recent_long_link = 0;
449                recent_long_link_blocks = 0;                recent_long_link_blocks = 0;
450              }              }
451            assign_string (&current_link_name, name);            assign_string (&current_stat_info.link_name, name);
452    
453            return HEADER_SUCCESS;            return HEADER_SUCCESS;
454          }          }
455      }      }
456  }  }
457    
458    #define ISOCTAL(c) ((c)>='0'&&(c)<='7')
459    
460  /* Decode things from a file HEADER block into STAT_INFO, also setting  /* Decode things from a file HEADER block into STAT_INFO, also setting
461     *FORMAT_POINTER depending on the header block format.  If     *FORMAT_POINTER depending on the header block format.  If
462     DO_USER_GROUP, decode the user/group information (this is useful     DO_USER_GROUP, decode the user/group information (this is useful
# Line 463  read_header (bool raw_extended_headers) Line 471  read_header (bool raw_extended_headers)
471     should decode it without uid/gid before calling a routine,     should decode it without uid/gid before calling a routine,
472     e.g. print_header, that assumes decoded data.  */     e.g. print_header, that assumes decoded data.  */
473  void  void
474  decode_header (union block *header, struct stat *stat_info,  decode_header (union block *header, struct tar_stat_info *stat_info,
475                 enum archive_format *format_pointer, int do_user_group)                 enum archive_format *format_pointer, int do_user_group)
476  {  {
477    enum archive_format format;    enum archive_format format;
478    
479    if (strcmp (header->header.magic, TMAGIC) == 0)    if (strcmp (header->header.magic, TMAGIC) == 0)
480      format = POSIX_FORMAT;      {
481          if (header->star_header.prefix[130] == 0
482              && ISOCTAL (header->star_header.atime[0])
483              && header->star_header.atime[11] == ' '
484              && ISOCTAL (header->star_header.ctime[0])
485              && header->star_header.ctime[11] == ' ')
486            format = STAR_FORMAT;
487          else
488            format = POSIX_FORMAT;
489        }
490    else if (strcmp (header->header.magic, OLDGNU_MAGIC) == 0)    else if (strcmp (header->header.magic, OLDGNU_MAGIC) == 0)
491      format = OLDGNU_FORMAT;      format = OLDGNU_FORMAT;
492    else    else
493      format = V7_FORMAT;      format = V7_FORMAT;
494    *format_pointer = format;    *format_pointer = format;
495    
496    stat_info->st_mode = MODE_FROM_HEADER (header->header.mode);    stat_info->stat.st_mode = MODE_FROM_HEADER (header->header.mode);
497    stat_info->st_mtime = TIME_FROM_HEADER (header->header.mtime);    stat_info->stat.st_mtime = TIME_FROM_HEADER (header->header.mtime);
498      assign_string (&stat_info->uname, header->header.uname);
499      assign_string (&stat_info->gname, header->header.gname);
500      stat_info->devmajor = MAJOR_FROM_HEADER (header->header.devmajor);
501      stat_info->devminor = MINOR_FROM_HEADER (header->header.devminor);
502      
503    if (format == OLDGNU_FORMAT && incremental_option)    if (format == OLDGNU_FORMAT && incremental_option)
504      {      {
505        stat_info->st_atime = TIME_FROM_HEADER (header->oldgnu_header.atime);        stat_info->stat.st_atime = TIME_FROM_HEADER (header->oldgnu_header.atime);
506        stat_info->st_ctime = TIME_FROM_HEADER (header->oldgnu_header.ctime);        stat_info->stat.st_ctime = TIME_FROM_HEADER (header->oldgnu_header.ctime);
507      }      }
508    
509    if (format == V7_FORMAT)    if (format == V7_FORMAT)
510      {      {
511        stat_info->st_uid = UID_FROM_HEADER (header->header.uid);        stat_info->stat.st_uid = UID_FROM_HEADER (header->header.uid);
512        stat_info->st_gid = GID_FROM_HEADER (header->header.gid);        stat_info->stat.st_gid = GID_FROM_HEADER (header->header.gid);
513        stat_info->st_rdev = 0;        stat_info->stat.st_rdev = 0;
514      }      }
515    else    else
516      {      {
517    
518          if (format == STAR_FORMAT)
519            {
520              stat_info->stat.st_atime = TIME_FROM_HEADER (header->star_header.atime);
521              stat_info->stat.st_ctime = TIME_FROM_HEADER (header->star_header.ctime);
522            }
523    
524        if (do_user_group)        if (do_user_group)
525          {          {
526            /* FIXME: Decide if this should somewhat depend on -p.  */            /* FIXME: Decide if this should somewhat depend on -p.  */
527    
528            if (numeric_owner_option            if (numeric_owner_option
529                || !*header->header.uname                || !*header->header.uname
530                || !uname_to_uid (header->header.uname, &stat_info->st_uid))                || !uname_to_uid (header->header.uname, &stat_info->stat.st_uid))
531              stat_info->st_uid = UID_FROM_HEADER (header->header.uid);              stat_info->stat.st_uid = UID_FROM_HEADER (header->header.uid);
532    
533            if (numeric_owner_option            if (numeric_owner_option
534                || !*header->header.gname                || !*header->header.gname
535                || !gname_to_gid (header->header.gname, &stat_info->st_gid))                || !gname_to_gid (header->header.gname, &stat_info->stat.st_gid))
536              stat_info->st_gid = GID_FROM_HEADER (header->header.gid);              stat_info->stat.st_gid = GID_FROM_HEADER (header->header.gid);
537          }          }
538          
539        switch (header->header.typeflag)        switch (header->header.typeflag)
540          {          {
541          case BLKTYPE:          case BLKTYPE:
           stat_info->st_rdev  
             = makedev (MAJOR_FROM_HEADER (header->header.devmajor),  
                        MINOR_FROM_HEADER (header->header.devminor));  
           break;  
   
542          case CHRTYPE:          case CHRTYPE:
543            stat_info->st_rdev            stat_info->stat.st_rdev = makedev (stat_info->devmajor, stat_info->devminor);
             = makedev (MAJOR_FROM_HEADER (header->header.devmajor),  
                        MINOR_FROM_HEADER (header->header.devminor));  
544            break;            break;
545    
546          default:          default:
547            stat_info->st_rdev = 0;            stat_info->stat.st_rdev = 0;
548          }          }
549      }      }
550    
551      if (extended_header.nblocks)
552        xheader_decode (stat_info);
553  }  }
554    
555  /* Convert buffer at WHERE0 of size DIGS from external format to  /* Convert buffer at WHERE0 of size DIGS from external format to
# Line 723  from_header (char const *where0, size_t Line 748  from_header (char const *where0, size_t
748          *--value_string = '-';          *--value_string = '-';
749        if (minus_minval)        if (minus_minval)
750          *--minval_string = '-';          *--minval_string = '-';
751        ERROR ((0, 0, _("Archive value %s is out of %s range %s..%s"),        ERROR ((0, 0, _("Archive value %s is out of %s range %s.%s"),
752                value_string, type,                value_string, type,
753                minval_string, STRINGIFY_BIGINT (maxval, maxval_buf)));                minval_string, STRINGIFY_BIGINT (maxval, maxval_buf)));
754      }      }
# Line 885  tartime (time_t t) Line 910  tartime (time_t t)
910    
911    
912  /* FIXME: Note that print_header uses the globals HEAD, HSTAT, and  /* FIXME: Note that print_header uses the globals HEAD, HSTAT, and
913     HEAD_STANDARD, which must be set up in advance.  Not very clean...  */     HEAD_STANDARD, which must be set up in advance.  Not very clean..  */
914    
915  /* UGSWIDTH starts with 18, so with user and group names <= 8 chars, the  /* UGSWIDTH starts with 18, so with user and group names <= 8 chars, the
916     columns never shift during the listing.  */     columns never shift during the listing.  */
# Line 904  print_header (off_t block_ordinal) Line 929  print_header (off_t block_ordinal)
929  {  {
930    char modes[11];    char modes[11];
931    char const *time_stamp;    char const *time_stamp;
932    char *temp_name = orig_file_name ? orig_file_name : current_file_name;    char *temp_name = current_stat_info.orig_file_name ? current_stat_info.orig_file_name : current_stat_info.file_name;
933        
934    /* These hold formatted ints.  */    /* These hold formatted ints.  */
935    char uform[UINTMAX_STRSIZE_BOUND], gform[UINTMAX_STRSIZE_BOUND];    char uform[UINTMAX_STRSIZE_BOUND], gform[UINTMAX_STRSIZE_BOUND];
# Line 988  print_header (off_t block_ordinal) Line 1013  print_header (off_t block_ordinal)
1013            break;            break;
1014          }          }
1015    
1016        decode_mode (current_stat.st_mode, modes + 1);        decode_mode (current_stat_info.stat.st_mode, modes + 1);
1017    
1018        /* Time stamp.  */        /* Time stamp.  */
1019    
1020        time_stamp = tartime (current_stat.st_mtime);        time_stamp = tartime (current_stat_info.stat.st_mtime);
1021    
1022        /* User and group names.  */        /* User and group names.  */
1023    
# Line 1047  print_header (off_t block_ordinal) Line 1072  print_header (off_t block_ordinal)
1072          case CHRTYPE:          case CHRTYPE:
1073          case BLKTYPE:          case BLKTYPE:
1074            strcpy (size,            strcpy (size,
1075                    STRINGIFY_BIGINT (major (current_stat.st_rdev), uintbuf));                    STRINGIFY_BIGINT (major (current_stat_info.stat.st_rdev), uintbuf));
1076            strcat (size, ",");            strcat (size, ",");
1077            strcat (size,            strcat (size,
1078                    STRINGIFY_BIGINT (minor (current_stat.st_rdev), uintbuf));                    STRINGIFY_BIGINT (minor (current_stat_info.stat.st_rdev), uintbuf));
1079            break;            break;
1080          case GNUTYPE_SPARSE:          case GNUTYPE_SPARSE:
1081            strcpy (size,            strcpy (size,
# Line 1060  print_header (off_t block_ordinal) Line 1085  print_header (off_t block_ordinal)
1085                     uintbuf));                     uintbuf));
1086            break;            break;
1087          default:          default:
1088            strcpy (size, STRINGIFY_BIGINT (current_stat.st_size, uintbuf));            strcpy (size, STRINGIFY_BIGINT (current_stat_info.stat.st_size, uintbuf));
1089            break;            break;
1090          }          }
1091    
# Line 1078  print_header (off_t block_ordinal) Line 1103  print_header (off_t block_ordinal)
1103        switch (current_header->header.typeflag)        switch (current_header->header.typeflag)
1104          {          {
1105          case SYMTYPE:          case SYMTYPE:
1106            fprintf (stdlis, " -> %s\n", quotearg (current_link_name));            fprintf (stdlis, " -> %s\n", quotearg (current_stat_info.link_name));
1107            break;            break;
1108    
1109          case LNKTYPE:          case LNKTYPE:
1110            fprintf (stdlis, _(" link to %s\n"), quotearg (current_link_name));            fprintf (stdlis, _(" link to %s\n"), quotearg (current_stat_info.link_name));
1111            break;            break;
1112    
1113          default:          default:
# Line 1192  skip_member (void) Line 1217  skip_member (void)
1217    char save_typeflag = current_header->header.typeflag;    char save_typeflag = current_header->header.typeflag;
1218    set_next_block_after (current_header);    set_next_block_after (current_header);
1219    
1220    if (current_header->oldgnu_header.isextended)    if (current_format == OLDGNU_FORMAT
1221          && current_header->oldgnu_header.isextended)
1222      {      {
1223        union block *exhdr;        union block *exhdr;
1224        do        do
# Line 1206  skip_member (void) Line 1232  skip_member (void)
1232      }      }
1233    
1234    if (save_typeflag != DIRTYPE)    if (save_typeflag != DIRTYPE)
1235      skip_file (current_stat.st_size);      skip_file (current_stat_info.stat.st_size);
1236  }  }

Legend:
Removed from v.1.51  
changed lines
  Added in v.1.52

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26