home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / tar-1.11.8-src.tgz / tar.out / fsf / tar / src / list.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  21KB  |  858 lines

  1. /* List a tar archive.
  2.    Copyright (C) 1988, 1992, 1993, 1994 Free Software Foundation, Inc.
  3.  
  4.    This file is part of GNU Tar.
  5.  
  6.    GNU Tar is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    GNU Tar is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with GNU Tar; see the file COPYING.  If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /* List a tar archive.
  21.    Also includes support routines for reading a tar archive.
  22.    Written 26 Aug 1985 by John Gilmore.  */
  23.  
  24. #include "system.h"
  25.  
  26. #include <ctype.h>
  27. #include <time.h>
  28.  
  29. #define    ISODIGIT(Char) \
  30.   ((unsigned char) (Char) >= '0' && (unsigned char) (Char) <= '7')
  31. #define ISSPACE(Char) (ISASCII (Char) && isspace (Char))
  32.  
  33. #include "tar.h"
  34.  
  35. static void demode __P ((unsigned, char *));
  36.  
  37. union record *head;        /* points to current archive header */
  38. struct stat hstat;        /* stat struct corresponding */
  39. int head_standard;        /* tape header is in ANSI format */
  40.  
  41. /*-----------------------------------.
  42. | Main loop for reading an archive.  |
  43. `-----------------------------------*/
  44.  
  45. void
  46. read_and (void (*do_something) ())
  47. {
  48.   int status = 3;        /* initial status at start of archive */
  49.   int prev_status;
  50.   char save_linkflag;
  51.  
  52.   name_gather ();        /* gather all the names */
  53.   open_archive (1);        /* open for reading */
  54.  
  55.   while (1)
  56.     {
  57.       prev_status = status;
  58.       status = read_header ();
  59.       switch (status)
  60.     {
  61.  
  62.     case 1:
  63.  
  64.       /* Valid header.  We should decode next field (mode) first.
  65.          Ensure incoming names are null terminated.  */
  66.  
  67.       if (!name_match (current_file_name)
  68.           || (flag_new_files && hstat.st_mtime < new_time)
  69.           || (flag_exclude && check_exclude (current_file_name)))
  70.         {
  71.  
  72.           int isextended = 0;
  73.  
  74.           if (head->header.linkflag == LF_VOLHDR
  75.           || head->header.linkflag == LF_MULTIVOL
  76.           || head->header.linkflag == LF_NAMES)
  77.         {
  78.           (*do_something) ();
  79.           continue;
  80.         }
  81.           if (flag_show_omitted_dirs && head->header.linkflag == LF_DIR)
  82.         WARN ((0, 0, _("Omitting %s"), current_file_name));
  83.  
  84.           /* Skip past it in the archive.  */
  85.  
  86.           if (head->header.isextended)
  87.         isextended = 1;
  88.           save_linkflag = head->header.linkflag;
  89.           userec (head);
  90.           if (isextended)
  91.         {
  92. #if 0
  93.           register union record *exhdr;
  94.  
  95.           while (1)
  96.             {
  97.               exhdr = findrec ();
  98.               if (!exhdr->ext_hdr.isextended)
  99.             {
  100.               userec (exhdr);
  101.               break;
  102.             }
  103.             }
  104.           userec (exhdr);
  105. #endif
  106.           skip_extended_headers ();
  107.         }
  108.  
  109.           /* Skip to the next header on the archive.  */
  110.  
  111.           if (save_linkflag != LF_DIR)
  112.         skip_file ((long) hstat.st_size);
  113.           continue;
  114.         }
  115.  
  116.       (*do_something) ();
  117.       continue;
  118.  
  119.       /* If the previous header was good, tell them that we are
  120.          skipping bad ones.  */
  121.  
  122.     case 0:            /* invalid header */
  123.       userec (head);
  124.       switch (prev_status)
  125.         {
  126.         case 3:        /* error on first record */
  127.           WARN ((0, 0, _("Hmm, this doesn't look like a tar archive")));
  128.           /* Fall through.  */
  129.  
  130.         case 2:        /* error after record of zeroes */
  131.         case 1:        /* error after header rec */
  132.           WARN ((0, 0, _("Skipping to next file header")));
  133.         case 0:        /* error after error */
  134.           break;
  135.         }
  136.       continue;
  137.  
  138.     case 2:            /* record of zeroes */
  139.       userec (head);
  140.       status = prev_status;    /* if error after 0's */
  141.       if (flag_ignorez)
  142.         continue;
  143.       /* Fall through.  */
  144.  
  145.     case EOF:        /* end of archive */
  146.       break;
  147.     }
  148.       break;
  149.     };
  150.  
  151.   restore_saved_dir_info ();
  152.   close_archive ();
  153.   names_notfound ();        /* print names not found */
  154. }
  155.  
  156. /*----------------------------------------------.
  157. | Print a header record, based on tar options.  |
  158. `----------------------------------------------*/
  159.  
  160. void
  161. list_archive (void)
  162. {
  163.   int isextended = 0;        /* flag to remember if head is extended */
  164.  
  165.   /* Save the record.  */
  166.  
  167.   saverec (&head);
  168.  
  169.   /* Print the header record.  */
  170.  
  171.   if (flag_verbose)
  172.     {
  173.       if (flag_verbose > 1)
  174.     decode_header (head, &hstat, &head_standard, 0);
  175.       print_header ();
  176.     }
  177.  
  178.   if (flag_gnudump && head->header.linkflag == LF_DUMPDIR)
  179.     {
  180.       size_t size, written, check;
  181.       char *data;
  182.  
  183.       userec (head);
  184.       if (flag_multivol)
  185.     {
  186.       assign_string (&save_name, current_file_name);
  187.       save_totsize = hstat.st_size;
  188.     }
  189.       for (size = hstat.st_size; size > 0; size -= written)
  190.     {
  191.       if (flag_multivol)
  192.         save_sizeleft = size;
  193.       data = findrec ()->charptr;
  194.       if (data == NULL)
  195.         {
  196.           ERROR ((0, 0, _("EOF in archive file")));
  197.           break;
  198.         }
  199.       written = endofrecs ()->charptr - data;
  200.       if (written > size)
  201.         written = size;
  202.       errno = 0;
  203.       check = fwrite (data, sizeof (char), written, stdlis);
  204.       userec ((union record *) (data + written - 1));
  205.       if (check != written)
  206.         {
  207.           ERROR ((0, errno, _("Only wrote %ld of %ld bytes to file %s"),
  208.               check, written, current_file_name));
  209.           skip_file ((long) (size - written));
  210.           break;
  211.         }
  212.     }
  213.       if (flag_multivol)
  214.     assign_string (&save_name, NULL);
  215.       saverec (NULL);        /* unsave it */
  216.       fputc ('\n', stdlis);
  217.       fflush (stdlis);
  218.       return;
  219.  
  220.     }
  221.   saverec ((union record **) 0);    /* unsave it */
  222.  
  223.   /* Check to see if we have an extended header to skip over also.  */
  224.  
  225.   if (head->header.isextended)
  226.     isextended = 1;
  227.  
  228.   /* Skip past the header in the archive.  */
  229.  
  230.   userec (head);
  231.  
  232.   /* If we needed to skip any extended headers, do so now, by reading
  233.      extended headers and skipping past them in the archive.  */
  234.  
  235.   if (isextended)
  236.     {
  237. #if 0
  238.       register union record *exhdr;
  239.  
  240.       while (1)
  241.     {
  242.       exhdr = findrec ();
  243.  
  244.       if (!exhdr->ext_hdr.isextended)
  245.         {
  246.           userec (exhdr);
  247.           break;
  248.         }
  249.       userec (exhdr);
  250.     }
  251. #endif
  252.       skip_extended_headers ();
  253.     }
  254.  
  255.   if (flag_multivol)
  256.     assign_string (&save_name, current_file_name);
  257.  
  258.   /* Skip to the next header on the archive.  */
  259.  
  260.   skip_file ((long) hstat.st_size);
  261.  
  262.   if (flag_multivol)
  263.     assign_string (&save_name, NULL);
  264. }
  265.  
  266. /*-------------------------------------------------------------------------.
  267. | Read a record that's supposed to be a header record.  Return its address |
  268. | in "head", and if it is good, the file's size in hstat.st_size.       |
  269. |                                        |
  270. | Return 1 for success, 0 if the checksum is bad, EOF on eof, 2 for a       |
  271. | record full of zeros (EOF marker).                       |
  272. |                                        |
  273. | You must always userec(head) to skip past the header which this routine  |
  274. | reads.                                   |
  275. `-------------------------------------------------------------------------*/
  276.  
  277. /* The standard BSD tar sources create the checksum by adding up the
  278.    bytes in the header as type char.  I think the type char was unsigned
  279.    on the PDP-11, but it's signed on the Next and Sun.  It looks like the
  280.    sources to BSD tar were never changed to compute the checksum
  281.    currectly, so both the Sun and Next add the bytes of the header as
  282.    signed chars.  This doesn't cause a problem until you get a file with
  283.    a name containing characters with the high bit set.  So read_header
  284.    computes two checksums -- signed and unsigned.  */
  285.  
  286. int
  287. read_header (void)
  288. {
  289.   register int i;
  290.   register long sum, signed_sum, recsum;
  291.   register char *p;
  292.   register union record *header;
  293.   char **longp;
  294.   char *bp, *data;
  295.   int size, written;
  296.   static char *next_long_name, *next_long_link;
  297.  
  298.   while (1)
  299.     {
  300.       header = findrec ();
  301.       head = header;        /* this is our current header */
  302.       if (!header)
  303.     return EOF;
  304.  
  305.       recsum = from_oct (8, header->header.chksum);
  306.  
  307.       sum = 0;
  308.       signed_sum = 0;
  309.       p = header->charptr;
  310.       for (i = sizeof (*header); --i >= 0;)
  311.     {
  312.  
  313.       /* We can't use unsigned char here because of old compilers,
  314.          e.g. V7.  */
  315.  
  316.       sum += 0xFF & *p;
  317.       signed_sum += *p++;
  318.     }
  319.  
  320.       /* Adjust checksum to count the "chksum" field as blanks.  */
  321.  
  322.       for (i = sizeof (header->header.chksum); --i >= 0;)
  323.     {
  324.       sum -= 0xFF & header->header.chksum[i];
  325.       signed_sum -= (char) header->header.chksum[i];
  326.     }
  327.       sum += ' ' * sizeof header->header.chksum;
  328.       signed_sum += ' ' * sizeof header->header.chksum;
  329.  
  330.       if (sum == 8 * ' ')
  331.     {
  332.  
  333.       /* This is a zeroed record...whole record is 0's except for the 8
  334.          blanks we faked for the checksum field.  */
  335.  
  336.       return 2;
  337.     }
  338.  
  339.       if (sum != recsum && signed_sum != recsum)
  340.     return 0;
  341.  
  342.       /* Good record.  Decode file size and return.  */
  343.  
  344.       if (header->header.linkflag == LF_LINK)
  345.     hstat.st_size = 0;    /* links 0 size on tape */
  346.       else
  347.     hstat.st_size = from_oct (1 + 12, header->header.size);
  348.  
  349.       header->header.arch_name[NAMSIZ - 1] = '\0';
  350.       if (header->header.linkflag == LF_LONGNAME
  351.       || header->header.linkflag == LF_LONGLINK)
  352.     {
  353.       longp = ((header->header.linkflag == LF_LONGNAME)
  354.            ? &next_long_name
  355.            : &next_long_link);
  356.  
  357.       userec (header);
  358.       if (*longp)
  359.         free (*longp);
  360.       bp = *longp = (char *) ck_malloc ((size_t) hstat.st_size);
  361.  
  362.       for (size = hstat.st_size; size > 0; size -= written)
  363.         {
  364.           data = findrec ()->charptr;
  365.           if (data == NULL)
  366.         {
  367.           ERROR ((0, 0, _("Unexpected EOF on archive file")));
  368.           break;
  369.         }
  370.           written = endofrecs ()->charptr - data;
  371.           if (written > size)
  372.         written = size;
  373.  
  374.           memcpy (bp, data, (size_t) written);
  375.           bp += written;
  376.           userec ((union record *) (data + written - 1));
  377.         }
  378.  
  379.       /* Loop!  */
  380.  
  381.     }
  382.       else
  383.     {
  384.       assign_string (¤t_file_name, (next_long_name ? next_long_name
  385.                           : head->header.arch_name));
  386.       assign_string (¤t_link_name, (next_long_link ? next_long_link
  387.                           : head->header.arch_linkname));
  388.       next_long_link = next_long_name = 0;
  389.       return 1;
  390.     }
  391.     }
  392. }
  393.  
  394. /*-------------------------------------------------------------------------.
  395. | Decode things from a file header record into a "struct stat".  Also set  |
  396. | "*stdp" to !=0 or ==0 depending whether header record is "Unix Standard" |
  397. | tar format or regular old tar format.                       |
  398. |                                        |
  399. | read_header() has already decoded the checksum and length, so we don't.  |
  400. |                                        |
  401. | If wantug != 0, we want the uid/group info decoded from Unix Standard       |
  402. | tapes (for extraction).  If == 0, we are just printing anyway, so save   |
  403. | time.                                       |
  404. |                                        |
  405. | decode_header should NOT be called twice for the same record, since the  |
  406. | two calls might use different "wantug" values and thus might end up with |
  407. | different uid/gid for the two calls.  If anybody wants the uid/gid they  |
  408. | should decode it first, and other callers should decode it without       |
  409. | uid/gid before calling a routine, e.g. print_header, that assumes       |
  410. | decoded data.                                   |
  411. `-------------------------------------------------------------------------*/
  412.  
  413. void
  414. decode_header (register union record *header, register struct stat *st,
  415.            int *stdp, int wantug)
  416. {
  417.   st->st_mode = from_oct (8, header->header.mode);
  418.   st->st_mode &= 07777;
  419.   st->st_mtime = from_oct (1 + 12, header->header.mtime);
  420.   if (flag_gnudump)
  421.     {
  422.       st->st_atime = from_oct (1 + 12, header->header.atime);
  423.       st->st_ctime = from_oct (1 + 12, header->header.ctime);
  424.     }
  425.  
  426.   if (strcmp (header->header.magic, TMAGIC) == 0)
  427.     {
  428.  
  429.       /* Unix Standard tar archive.  */
  430.  
  431.       *stdp = 1;
  432.       if (wantug)
  433.     {
  434. #ifdef NONAMES
  435.       st->st_uid = from_oct (8, header->header.uid);
  436.       st->st_gid = from_oct (8, header->header.gid);
  437. #else
  438.       st->st_uid =
  439.         (*header->header.uname
  440.          ? finduid (header->header.uname)
  441.          : from_oct (8, header->header.uid));
  442.       st->st_gid =
  443.         (*header->header.gname
  444.          ? findgid (header->header.gname)
  445.          : from_oct (8, header->header.gid));
  446. #endif
  447.     }
  448. #if defined(S_IFBLK) || defined(S_IFCHR)
  449.       switch (header->header.linkflag)
  450.     {
  451.     case LF_BLK:
  452.     case LF_CHR:
  453.       st->st_rdev = makedev (from_oct (8, header->header.devmajor),
  454.                  from_oct (8, header->header.devminor));
  455.     }
  456. #endif
  457.     }
  458.   else
  459.     {
  460.  
  461.       /* Old fashioned tar archive.  */
  462.  
  463.       *stdp = 0;
  464.       st->st_uid = from_oct (8, header->header.uid);
  465.       st->st_gid = from_oct (8, header->header.gid);
  466.       st->st_rdev = 0;
  467.     }
  468. }
  469.  
  470. /*------------------------------------------------------------------------.
  471. | Quick and dirty octal conversion.  Result is -1 if the field is invalid |
  472. | (all blank, or nonoctal).                          |
  473. `------------------------------------------------------------------------*/
  474.  
  475. long
  476. from_oct (register int digs, register char *where)
  477. {
  478.   register long value;
  479.  
  480.   while (ISSPACE (*where))
  481.     {                /* skip spaces */
  482.       where++;
  483.       if (--digs <= 0)
  484.     return -1;        /* all blank field */
  485.     }
  486.   value = 0;
  487.   while (digs > 0 && ISODIGIT (*where))
  488.     {
  489.  
  490.       /* Scan til nonoctal.  */
  491.  
  492.       value = (value << 3) | (*where++ - '0');
  493.       --digs;
  494.     }
  495.  
  496.   if (digs > 0 && *where && !ISSPACE (*where))
  497.     return -1;            /* ended on non-space/nul */
  498.  
  499.   return value;
  500. }
  501.  
  502. /*-------------------------------------------------------------------------.
  503. | Actually print it.                               |
  504. |                                        |
  505. | Plain and fancy file header block logging.  Non-verbose just prints the  |
  506. | name, e.g. for "tar t" or "tar x".  This should just contain file names, |
  507. | so it can be fed back into tar with xargs or the "-T" option.  The       |
  508. | verbose option can give a bunch of info, one line per file.  I doubt       |
  509. | anybody tries to parse its format, or if they do, they shouldn't.  Unix  |
  510. | tar is pretty random here anyway.                       |
  511. `-------------------------------------------------------------------------*/
  512.  
  513. /* Note that print_header uses the globals <head>, <hstat>, and
  514.    <head_standard>, which must be set up in advance.  This is not very
  515.    clean and should be cleaned up.  FIXME.  */
  516.  
  517. #define    UGSWIDTH    18    /* min width of User, group, size */
  518. /* UGSWIDTH of 18 means that with user and group names <= 8 chars the columns
  519.    never shift during the listing.  */
  520. #define    DATEWIDTH    19    /* last mod date */
  521. static int ugswidth = UGSWIDTH;    /* max width encountered so far */
  522.  
  523. void
  524. print_header (void)
  525. {
  526.   char modes[11];
  527.   char *timestamp;
  528.   char uform[11], gform[11];    /* these hold formatted ints */
  529.   char *user, *group;
  530.   char size[24];        /* holds a formatted long or maj, min */
  531.   time_t longie;        /* to make ctime() call portable */
  532.   int pad;
  533.   char *name;
  534.  
  535.   if (flag_sayblock)
  536.     fprintf (stdlis, _("rec %10ld: "), baserec + (ar_record - ar_block));
  537. #if 0
  538.   annofile (stdlis, (char *) NULL);
  539. #endif
  540.  
  541.   if (flag_verbose <= 1)
  542.     {
  543.  
  544.       /* Just the fax, mam.  */
  545.  
  546.       char *quoted_name = quote_copy_string (current_file_name);
  547.  
  548.       if (quoted_name)
  549.     {
  550.       fprintf (stdlis, "%s\n", quoted_name);
  551.       free (quoted_name);
  552.     }
  553.       else
  554.     fprintf (stdlis, "%s\n", current_file_name);
  555.     }
  556.   else
  557.     {
  558.  
  559.       /* File type and modes.  */
  560.  
  561.       modes[0] = '?';
  562.       switch (head->header.linkflag)
  563.     {
  564.     case LF_VOLHDR:
  565.       modes[0] = 'V';
  566.       break;
  567.  
  568.     case LF_MULTIVOL:
  569.       modes[0] = 'M';
  570.       break;
  571.  
  572.     case LF_NAMES:
  573.       modes[0] = 'N';
  574.       break;
  575.  
  576.     case LF_LONGNAME:
  577.     case LF_LONGLINK:
  578.       ERROR ((0, 0, _("Visible longname error")));
  579.       break;
  580.  
  581.     case LF_SPARSE:
  582.     case LF_NORMAL:
  583.     case LF_OLDNORMAL:
  584.     case LF_LINK:
  585.       modes[0] = '-';
  586.       if (current_file_name[strlen (current_file_name) - 1] == '/')
  587.         modes[0] = 'd';
  588.       break;
  589.     case LF_DUMPDIR:
  590.       modes[0] = 'd';
  591.       break;
  592.     case LF_DIR:
  593.       modes[0] = 'd';
  594.       break;
  595.     case LF_SYMLINK:
  596.       modes[0] = 'l';
  597.       break;
  598.     case LF_BLK:
  599.       modes[0] = 'b';
  600.       break;
  601.     case LF_CHR:
  602.       modes[0] = 'c';
  603.       break;
  604.     case LF_FIFO:
  605.       modes[0] = 'p';
  606.       break;
  607.     case LF_CONTIG:
  608.       modes[0] = 'C';
  609.       break;
  610.     }
  611.  
  612.       demode ((unsigned) hstat.st_mode, modes + 1);
  613.  
  614.       /* Timestamp.  */
  615.  
  616.       longie = hstat.st_mtime;
  617.       timestamp = ctime (&longie);
  618.       timestamp[16] = '\0';
  619.       timestamp[24] = '\0';
  620.  
  621.       /* User and group names.  */
  622.  
  623.       if (*head->header.uname && head_standard)
  624.     {
  625.       user = head->header.uname;
  626.     }
  627.       else
  628.     {
  629.       user = uform;
  630.       sprintf (uform, "%ld", from_oct (8, head->header.uid));
  631.     }
  632.       if (*head->header.gname && head_standard)
  633.     {
  634.       group = head->header.gname;
  635.     }
  636.       else
  637.     {
  638.       group = gform;
  639.       sprintf (gform, "%ld", from_oct (8, head->header.gid));
  640.     }
  641.  
  642.       /* Format the file size or major/minor device numbers.  */
  643.  
  644.       switch (head->header.linkflag)
  645.     {
  646. #if defined(S_IFBLK) || defined(S_IFCHR)
  647.     case LF_CHR:
  648.     case LF_BLK:
  649.       sprintf (size, "%d,%d",
  650.            major (hstat.st_rdev), minor (hstat.st_rdev));
  651.       break;
  652. #endif
  653.     case LF_SPARSE:
  654.       sprintf (size, "%ld", from_oct (1 + 12, head->header.realsize));
  655.       break;
  656.     default:
  657.       sprintf (size, "%ld", (long) hstat.st_size);
  658.     }
  659.  
  660.       /* Figure out padding and print the whole line.  */
  661.  
  662.       pad = strlen (user) + strlen (group) + strlen (size) + 1;
  663.       if (pad > ugswidth)
  664.     ugswidth = pad;
  665.  
  666.       fprintf (stdlis, "%s %s/%s %*s%s %s %s",
  667.            modes, user, group, ugswidth - pad, "",
  668.            size, timestamp + 4, timestamp + 20);
  669.  
  670.       name = quote_copy_string (current_file_name);
  671.       if (name)
  672.     {
  673.       fprintf (stdlis, " %s", name);
  674.       free (name);
  675.     }
  676.       else
  677.     fprintf (stdlis, " %s", current_file_name);
  678.  
  679.       switch (head->header.linkflag)
  680.     {
  681.     case LF_SYMLINK:
  682.       name = quote_copy_string (current_link_name);
  683.       if (name)
  684.         {
  685.           fprintf (stdlis, " -> %s\n", name);
  686.           free (name);
  687.         }
  688.       else
  689.         fprintf (stdlis, " -> %s\n", current_link_name);
  690.       break;
  691.  
  692.     case LF_LINK:
  693.       name = quote_copy_string (current_link_name);
  694.       if (name)
  695.         {
  696.           fprintf (stdlis, _(" link to %s\n"), name);
  697.           free (name);
  698.         }
  699.       else
  700.         fprintf (stdlis, _(" link to %s\n"), current_link_name);
  701.       break;
  702.  
  703.     default:
  704.       fprintf (stdlis, _(" unknown file type `%c'\n"),
  705.            head->header.linkflag);
  706.       break;
  707.  
  708.     case LF_OLDNORMAL:
  709.     case LF_NORMAL:
  710.     case LF_SPARSE:
  711.     case LF_CHR:
  712.     case LF_BLK:
  713.     case LF_DIR:
  714.     case LF_FIFO:
  715.     case LF_CONTIG:
  716.     case LF_DUMPDIR:
  717.       putc ('\n', stdlis);
  718.       break;
  719.  
  720.     case LF_VOLHDR:
  721.       fprintf (stdlis, _("--Volume Header--\n"));
  722.       break;
  723.  
  724.     case LF_MULTIVOL:
  725.       fprintf (stdlis, _("--Continued at byte %ld--\n"),
  726.            from_oct (1 + 12, head->header.offset));
  727.       break;
  728.  
  729.     case LF_NAMES:
  730.       fprintf (stdlis, _("--Mangled file names--\n"));
  731.       break;
  732.     }
  733.     }
  734.   fflush (stdlis);
  735. }
  736.  
  737. /*--------------------------------------------------------------.
  738. | Print a similar line when we make a directory automatically.  |
  739. `--------------------------------------------------------------*/
  740.  
  741. void
  742. pr_mkdir (char *pathname, int length, int mode)
  743. {
  744.   char modes[11];
  745.   char *name;
  746.  
  747.   if (flag_verbose > 1)
  748.     {
  749.  
  750.       /* File type and modes.  */
  751.  
  752.       modes[0] = 'd';
  753.       demode ((unsigned) mode, modes + 1);
  754.  
  755.       if (flag_sayblock)
  756.     fprintf (stdlis, _("rec %10ld: "), baserec + (ar_record - ar_block));
  757. #if 0
  758.       annofile (stdlis, (char *) NULL);
  759. #endif
  760.       name = quote_copy_string (pathname);
  761.       if (!name)
  762.     name = pathname;
  763.       fprintf (stdlis, "%s %*s %.*s\n", modes, ugswidth + DATEWIDTH,
  764.            _("Creating directory:"), length, pathname);
  765.       if (name != pathname)
  766.     free (name);
  767.     }
  768. }
  769.  
  770. /*-----------------------------------------------------------.
  771. | Skip over <size> bytes of data in records in the archive.  |
  772. `-----------------------------------------------------------*/
  773.  
  774. void
  775. skip_file (register long size)
  776. {
  777.   union record *x;
  778.  
  779.   if (flag_multivol)
  780.     {
  781.       save_totsize = size;
  782.       save_sizeleft = size;
  783.     }
  784.  
  785.   while (size > 0)
  786.     {
  787.       x = findrec ();
  788.       if (x == NULL)
  789.     ERROR ((TAREXIT_FAILURE, 0, _("Unexpected EOF on archive file")));
  790.  
  791.       userec (x);
  792.       size -= RECORDSIZE;
  793.       if (flag_multivol)
  794.     save_sizeleft -= RECORDSIZE;
  795.     }
  796. }
  797.  
  798. /*---.
  799. | ?  |
  800. `---*/
  801.  
  802. void
  803. skip_extended_headers (void)
  804. {
  805.   register union record *exhdr;
  806.  
  807.   while (1)
  808.     {
  809.       exhdr = findrec ();
  810.       if (!exhdr->ext_hdr.isextended)
  811.     {
  812.       userec (exhdr);
  813.       break;
  814.     }
  815.       userec (exhdr);
  816.     }
  817. }
  818.  
  819. /*--------------------------------------------------------------------.
  820. | Decode the mode string from a stat entry into a 9-char string and a |
  821. | null.                                      |
  822. `--------------------------------------------------------------------*/
  823.  
  824. static void
  825. demode (register unsigned mode, register char *string)
  826. {
  827.   register unsigned mask;
  828.   register const char *rwx = "rwxrwxrwx";
  829.  
  830.   for (mask = 0400; mask != 0; mask >>= 1)
  831.     {
  832.       if (mode & mask)
  833.     *string++ = *rwx++;
  834.       else
  835.     {
  836.       *string++ = '-';
  837.       rwx++;
  838.     }
  839.     }
  840.  
  841.   if (mode & S_ISUID)
  842.     if (string[-7] == 'x')
  843.       string[-7] = 's';
  844.     else
  845.       string[-7] = 'S';
  846.   if (mode & S_ISGID)
  847.     if (string[-4] == 'x')
  848.       string[-4] = 's';
  849.     else
  850.       string[-4] = 'S';
  851.   if (mode & S_ISVTX)
  852.     if (string[-1] == 'x')
  853.       string[-1] = 't';
  854.     else
  855.       string[-1] = 'T';
  856.   *string = '\0';
  857. }
  858.