home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / arc / Archiver / cpio / src / copyin.c < prev    next >
C/C++ Source or Header  |  1992-09-19  |  26KB  |  945 lines

  1. /* copyin.c - extract or list a cpio archive
  2.    Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #include <stdio.h>
  19. #include <fnmatch.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include "filetypes.h"
  23. #include "system.h"
  24. #include "cpiohdr.h"
  25. #include "dstring.h"
  26. #include "extern.h"
  27. #include "rmt.h"
  28.  
  29. #ifndef HAVE_LCHOWN
  30. #define lchown chown
  31. #endif
  32.  
  33. static void read_pattern_file ();
  34. static void skip_padding ();
  35.  
  36. /* Return 16-bit integer I with the bytes swapped.  */
  37. #define swab_short(i) ((((i) << 8) & 0xff00) | (((i) >> 8) & 0x00ff))
  38.  
  39. /* Read the header, including the name of the file, from file
  40.    descriptor IN_DES into FILE_HDR.  */
  41.  
  42. void
  43. read_in_header (file_hdr, in_des)
  44.      struct new_cpio_header *file_hdr;
  45.      int in_des;
  46. {
  47.   long bytes_skipped = 0;    /* Bytes of junk found before magic number.  */
  48.  
  49.   /* Search for a valid magic number.  */
  50.  
  51.   if (archive_format == arf_unknown)
  52.     {
  53.       char tmpbuf[512];
  54.       int check_tar;
  55.       int peeked_bytes;
  56.  
  57.       while (archive_format == arf_unknown)
  58.     {
  59.       peeked_bytes = peek_in_buf (tmpbuf, in_des, 512);
  60.       if (peeked_bytes < 6)
  61.         error (1, 0, "premature end of archive");
  62.  
  63.       if (!strncmp (tmpbuf, "070701", 6))
  64.         archive_format = arf_newascii;
  65.       else if (!strncmp (tmpbuf, "070707", 6))
  66.         archive_format = arf_oldascii;
  67.       else if (!strncmp (tmpbuf, "070702", 6))
  68.         {
  69.           archive_format = arf_crcascii;
  70.           crc_i_flag = TRUE;
  71.         }
  72.       else if ((*((unsigned short *) tmpbuf) == 070707) ||
  73.            (*((unsigned short *) tmpbuf) == swab_short ((unsigned short) 070707)))
  74.         archive_format = arf_binary;
  75.       else if (peeked_bytes >= 512
  76.            && (check_tar = is_tar_header (tmpbuf)))
  77.         {
  78.           if (check_tar == 2)
  79.         archive_format = arf_ustar;
  80.           else
  81.         archive_format = arf_tar;
  82.         }
  83.       else
  84.         {
  85.           copy_in_buf ((char *) tmpbuf, in_des, 1L);
  86.           ++bytes_skipped;
  87.         }
  88.     }
  89.     }
  90.  
  91.   if (archive_format == arf_tar || archive_format == arf_ustar)
  92.     {
  93.       if (append_flag)
  94.     last_header_start = input_bytes - io_block_size +
  95.       (in_buff - input_buffer);
  96.       if (bytes_skipped > 0)
  97.     error (0, 0, "warning: skipped %ld bytes of junk", bytes_skipped);
  98.       read_in_tar_header (file_hdr, in_des);
  99.       return;
  100.     }
  101.  
  102.   file_hdr->c_tar_linkname = NULL;
  103.  
  104.   copy_in_buf ((char *) file_hdr, in_des, 6L);
  105.   while (1)
  106.     {
  107.       if (append_flag)
  108.     last_header_start = input_bytes - io_block_size
  109.       + (in_buff - input_buffer) - 6;
  110.       if (archive_format == arf_newascii
  111.       && !strncmp ((char *) file_hdr, "070701", 6))
  112.     {
  113.       if (bytes_skipped > 0)
  114.         error (0, 0, "warning: skipped %ld bytes of junk", bytes_skipped);
  115.       read_in_new_ascii (file_hdr, in_des);
  116.       break;
  117.     }
  118.       if (archive_format == arf_crcascii
  119.       && !strncmp ((char *) file_hdr, "070702", 6))
  120.     {
  121.       if (bytes_skipped > 0)
  122.         error (0, 0, "warning: skipped %ld bytes of junk", bytes_skipped);
  123.       read_in_new_ascii (file_hdr, in_des);
  124.       break;
  125.     }
  126.       if (archive_format == arf_oldascii
  127.       && !strncmp ((char *) file_hdr, "070707", 6))
  128.     {
  129.       if (bytes_skipped > 0)
  130.         error (0, 0, "warning: skipped %ld bytes of junk", bytes_skipped);
  131.       read_in_old_ascii (file_hdr, in_des);
  132.       break;
  133.     }
  134.       if (archive_format == arf_binary
  135.       && (file_hdr->c_magic == 070707
  136.           || file_hdr->c_magic == swab_short ((unsigned short) 070707)))
  137.     {
  138.       /* Having to skip 1 byte because of word alignment is normal.  */
  139.       if (bytes_skipped > 0)
  140.         error (0, 0, "warning: skipped %ld bytes of junk", bytes_skipped);
  141.       read_in_binary (file_hdr, in_des);
  142.       break;
  143.     }
  144.       bytes_skipped++;
  145.       bcopy ((char *) file_hdr + 1, (char *) file_hdr, 5);
  146.       copy_in_buf ((char *) file_hdr + 5, in_des, 1L);
  147.     }
  148. }
  149.  
  150. /* Fill in FILE_HDR by reading an old-format ASCII format cpio header from
  151.    file descriptor IN_DES, except for the magic number, which is
  152.    already filled in.  */
  153.  
  154. void
  155. read_in_old_ascii (file_hdr, in_des)
  156.      struct new_cpio_header *file_hdr;
  157.      int in_des;
  158. {
  159.   char ascii_header[78];
  160.   unsigned long dev;
  161.   unsigned long rdev;
  162.  
  163.   copy_in_buf (ascii_header, in_des, 70L);
  164.   ascii_header[70] = '\0';
  165.   sscanf (ascii_header,
  166.       "%6o%6o%6o%6o%6o%6o%6o%11o%6o%11o",
  167.       &dev, &file_hdr->c_ino,
  168.       &file_hdr->c_mode, &file_hdr->c_uid, &file_hdr->c_gid,
  169.       &file_hdr->c_nlink, &rdev, &file_hdr->c_mtime,
  170.       &file_hdr->c_namesize, &file_hdr->c_filesize);
  171.   file_hdr->c_dev_maj = major (dev);
  172.   file_hdr->c_dev_min = minor (dev);
  173.   file_hdr->c_rdev_maj = major (rdev);
  174.   file_hdr->c_rdev_min = minor (rdev);
  175.  
  176.   /* Read file name from input.  */
  177.   if (file_hdr->c_name != NULL)
  178.     free (file_hdr->c_name);
  179.   file_hdr->c_name = (char *) xmalloc (file_hdr->c_namesize + 1);
  180.   copy_in_buf (file_hdr->c_name, in_des, (long) file_hdr->c_namesize);
  181. }
  182.  
  183. /* Fill in FILE_HDR by reading a new-format ASCII format cpio header from
  184.    file descriptor IN_DES, except for the magic number, which is
  185.    already filled in.  */
  186.  
  187. void
  188. read_in_new_ascii (file_hdr, in_des)
  189.      struct new_cpio_header *file_hdr;
  190.      int in_des;
  191. {
  192.   char ascii_header[112];
  193.  
  194.   copy_in_buf (ascii_header, in_des, 104L);
  195.   ascii_header[104] = '\0';
  196.   sscanf (ascii_header,
  197.       "%8x%8x%8x%8x%8x%8x%8x%8x%8x%8x%8x%8x%8x",
  198.       &file_hdr->c_ino, &file_hdr->c_mode, &file_hdr->c_uid,
  199.       &file_hdr->c_gid, &file_hdr->c_nlink, &file_hdr->c_mtime,
  200.       &file_hdr->c_filesize, &file_hdr->c_dev_maj, &file_hdr->c_dev_min,
  201.     &file_hdr->c_rdev_maj, &file_hdr->c_rdev_min, &file_hdr->c_namesize,
  202.       &file_hdr->c_chksum);
  203.   /* Read file name from input.  */
  204.   if (file_hdr->c_name != NULL)
  205.     free (file_hdr->c_name);
  206.   file_hdr->c_name = (char *) xmalloc (file_hdr->c_namesize);
  207.   copy_in_buf (file_hdr->c_name, in_des, (long) file_hdr->c_namesize);
  208.  
  209.   /* In SVR4 ASCII format, the amount of space allocated for the header
  210.      is rounded up to the next long-word, so we might need to drop
  211.      1-3 bytes.  */
  212.   skip_padding (in_des, file_hdr->c_namesize + 110);
  213. }
  214.  
  215. /* Fill in FILE_HDR by reading a binary format cpio header from
  216.    file descriptor IN_DES, except for the first 6 bytes (the magic
  217.    number), which are already filled in.  */
  218.  
  219. void
  220. read_in_binary (file_hdr, in_des)
  221.      struct new_cpio_header *file_hdr;
  222.      int in_des;
  223. {
  224.   struct old_cpio_header short_hdr;
  225.  
  226.   copy_in_buf (((char *) &short_hdr) + 6, in_des, 20L);
  227.  
  228.   /* If the magic number is byte swapped, fix the header.  */
  229.   if (file_hdr->c_magic == swab_short ((unsigned short) 070707))
  230.     {
  231.       static int warned = 0;
  232.  
  233.       /* Alert the user that they might have to do byte swapping on
  234.      the file contents.  */
  235.       if (warned == 0)
  236.     {
  237.       error (0, 0, "warning: archive header has reverse byte-order");
  238.       warned = 1;
  239.     }
  240.       swab_array ((char *) &short_hdr, 13);
  241.     }
  242.  
  243.   file_hdr->c_dev_maj = major (short_hdr.c_dev);
  244.   file_hdr->c_dev_min = minor (short_hdr.c_dev);
  245.   file_hdr->c_ino = short_hdr.c_ino;
  246.   file_hdr->c_mode = short_hdr.c_mode;
  247.   file_hdr->c_uid = short_hdr.c_uid;
  248.   file_hdr->c_gid = short_hdr.c_gid;
  249.   file_hdr->c_nlink = short_hdr.c_nlink;
  250.   file_hdr->c_rdev_maj = major (short_hdr.c_rdev);
  251.   file_hdr->c_rdev_min = minor (short_hdr.c_rdev);
  252.   file_hdr->c_mtime = (unsigned long) short_hdr.c_mtimes[0] << 16
  253.     | short_hdr.c_mtimes[1];
  254.  
  255.   file_hdr->c_namesize = short_hdr.c_namesize;
  256.   file_hdr->c_filesize = (unsigned long) short_hdr.c_filesizes[0] << 16
  257.     | short_hdr.c_filesizes[1];
  258.  
  259.   /* Read file name from input.  */
  260.   if (file_hdr->c_name != NULL)
  261.     free (file_hdr->c_name);
  262.   file_hdr->c_name = (char *) xmalloc (file_hdr->c_namesize);
  263.   copy_in_buf (file_hdr->c_name, in_des, (long) file_hdr->c_namesize);
  264.  
  265.   /* In binary mode, the amount of space allocated in the header for
  266.      the filename is `c_namesize' rounded up to the next short-word,
  267.      so we might need to drop a byte.  */
  268.   if (file_hdr->c_namesize % 2)
  269.     toss_input (in_des, 1L);
  270. }
  271.  
  272. /* Exchange the bytes of each element of the array of COUNT shorts
  273.    starting at PTR.  */
  274.  
  275. void
  276. swab_array (ptr, count)
  277.      char *ptr;
  278.      int count;
  279. {
  280.   char tmp;
  281.  
  282.   while (count-- > 0)
  283.     {
  284.       tmp = *ptr;
  285.       *ptr = *(ptr + 1);
  286.       ++ptr;
  287.       *ptr = tmp;
  288.       ++ptr;
  289.     }
  290. }
  291.  
  292. /* Current time for verbose table.  */
  293. static time_t current_time;
  294.  
  295. /* Read the collection from standard input and create files
  296.    in the file system.  */
  297.  
  298. void
  299. process_copy_in ()
  300. {
  301.   char done = FALSE;        /* True if trailer reached.  */
  302.   int res;            /* Result of various function calls.  */
  303.   dynamic_string new_name;    /* New file name for rename option.  */
  304.   FILE *tty_in;            /* Interactive file for rename option.  */
  305.   FILE *tty_out;        /* Interactive file for rename option.  */
  306.   char *str_res;        /* Result for string function.  */
  307.   struct utimbuf times;        /* For setting file times.  */
  308.   struct stat file_stat;    /* Output file stat record.  */
  309.   struct new_cpio_header file_hdr;    /* Output header information.  */
  310.   int out_file_des;        /* Output file descriptor.  */
  311.   int in_file_des;        /* Input file descriptor.  */
  312.   char skip_file;        /* Flag for use with patterns.  */
  313.   int existing_dir;        /* True if file is a dir & already exists.  */
  314.   int i;            /* Loop index variable.  */
  315.   char *link_name = NULL;    /* Name of hard and symbolic links.  */
  316.  
  317.   /* Initialize the copy in.  */
  318.   if (pattern_file_name)
  319.     read_pattern_file ();
  320.   file_hdr.c_name = NULL;
  321.   ds_init (&new_name, 128);
  322.   /* Initialize this in case it has members we don't know to set.  */
  323.   bzero (×, sizeof (struct utimbuf));
  324.  
  325.   /* Open interactive file pair for rename operation.  */
  326.   if (rename_flag)
  327.     {
  328.       tty_in = fopen (CONSOLE, "r");
  329.       if (tty_in == NULL)
  330.     error (2, errno, CONSOLE);
  331.       tty_out = fopen (CONSOLE, "w");
  332.       if (tty_out == NULL)
  333.     error (2, errno, CONSOLE);
  334.     }
  335.  
  336.   /* Get date and time if needed for processing the table option.  */
  337.   if (table_flag && verbose_flag)
  338.     time (¤t_time);
  339.  
  340. #ifdef __MSDOS__
  341.   setmode (archive_des, O_BINARY);
  342. #endif
  343.   /* Check whether the input file might be a tape.  */
  344.   in_file_des = archive_des;
  345.   if (_isrmt (in_file_des))
  346.     {
  347.       input_is_special = 1;
  348.       input_is_seekable = 0;
  349.     }
  350.   else
  351.     {
  352.       if (fstat (in_file_des, &file_stat))
  353.     error (1, errno, "standard input is closed");
  354.       input_is_special =
  355. #ifdef S_ISBLK
  356.     S_ISBLK (file_stat.st_mode) ||
  357. #endif
  358.     S_ISCHR (file_stat.st_mode);
  359.       input_is_seekable = S_ISREG (file_stat.st_mode);
  360.     }
  361.   output_is_seekable = TRUE;
  362.  
  363.   /* While there is more input in the collection, process the input.  */
  364.   while (!done)
  365.     {
  366.       link_name = NULL;
  367.       swapping_halfwords = swapping_bytes = FALSE;
  368.  
  369.       /* Start processing the next file by reading the header.  */
  370.       read_in_header (&file_hdr, in_file_des);
  371.  
  372.       /* Is this the header for the TRAILER file?  */
  373.       if (strcmp ("TRAILER!!!", file_hdr.c_name) == 0)
  374.     {
  375.       done = TRUE;
  376.       break;
  377.     }
  378.  
  379.       /* Does the file name match one of the given patterns?  */
  380.       if (num_patterns <= 0)
  381.     skip_file = FALSE;
  382.       else
  383.     {
  384.       skip_file = copy_matching_files;
  385.       for (i = 0; i < num_patterns
  386.            && skip_file == copy_matching_files; i++)
  387.         {
  388.           if (fnmatch (save_patterns[i], file_hdr.c_name, 0) == 0)
  389.         skip_file = !copy_matching_files;
  390.         }
  391.     }
  392.  
  393.       if (skip_file)
  394.     {
  395.       toss_input (in_file_des, file_hdr.c_filesize);
  396.       skip_padding (in_file_des, file_hdr.c_filesize);
  397.     }
  398.       else if (table_flag)
  399.     {
  400.       if (verbose_flag)
  401.         {
  402. #ifdef CP_IFLNK
  403.           if ((file_hdr.c_mode & CP_IFMT) == CP_IFLNK)
  404.         {
  405.           if (archive_format != arf_tar && archive_format != arf_ustar)
  406.             {
  407.               link_name = (char *) xmalloc ((unsigned int) file_hdr.c_filesize + 1);
  408.               link_name[file_hdr.c_filesize] = '\0';
  409.               copy_in_buf (link_name, in_file_des, file_hdr.c_filesize);
  410.               long_format (&file_hdr, link_name);
  411.               free (link_name);
  412.               skip_padding (in_file_des, file_hdr.c_filesize);
  413.               continue;
  414.             }
  415.           else
  416.             {
  417.               long_format (&file_hdr, file_hdr.c_tar_linkname);
  418.               continue;
  419.             }
  420.         }
  421.           else
  422. #endif
  423.         long_format (&file_hdr, (char *) 0);
  424.         }
  425.       else
  426.         printf ("%s\n", file_hdr.c_name);
  427.  
  428.       toss_input (in_file_des, file_hdr.c_filesize);
  429.       skip_padding (in_file_des, file_hdr.c_filesize);
  430.     }
  431.       else if (append_flag)
  432.     {
  433.       toss_input (in_file_des, file_hdr.c_filesize);
  434.       skip_padding (in_file_des, file_hdr.c_filesize);
  435.     }
  436.       else
  437.     {
  438.       /* Copy the input file into the directory structure.  */
  439.  
  440.       /* Do we need to rename the file? */
  441.       if (rename_flag)
  442.         {
  443.           fprintf (tty_out, "rename %s -> ", file_hdr.c_name);
  444.           fflush (tty_out);
  445.           str_res = ds_fgets (tty_in, &new_name);
  446.           if (str_res == NULL || str_res[0] == 0)
  447.         {
  448.           toss_input (in_file_des, file_hdr.c_filesize);
  449.           skip_padding (in_file_des, file_hdr.c_filesize);
  450.           continue;
  451.         }
  452.           else
  453.         file_hdr.c_name = xstrdup (new_name.ds_string);
  454.         }
  455.  
  456.       /* See if the file already exists.  */
  457.       existing_dir = FALSE;
  458.       if (lstat (file_hdr.c_name, &file_stat) == 0)
  459.         {
  460.           if (S_ISDIR (file_stat.st_mode)
  461.           && ((file_hdr.c_mode & CP_IFMT) == CP_IFDIR))
  462.         {
  463.           /* If there is already a directory there that
  464.              we are trying to create, don't complain about
  465.              it.  */
  466.           existing_dir = TRUE;
  467.         }
  468.           else if (!unconditional_flag
  469.                && file_hdr.c_mtime <= file_stat.st_mtime)
  470.         {
  471.           error (0, 0, "%s not created: newer or same age version exists",
  472.              file_hdr.c_name);
  473.           toss_input (in_file_des, file_hdr.c_filesize);
  474.           skip_padding (in_file_des, file_hdr.c_filesize);
  475.           continue;    /* Go to the next file.  */
  476.         }
  477.           else if (unlink (file_hdr.c_name))
  478.         {
  479.           error (0, errno, "cannot remove current %s",
  480.              file_hdr.c_name);
  481.           toss_input (in_file_des, file_hdr.c_filesize);
  482.           skip_padding (in_file_des, file_hdr.c_filesize);
  483.           continue;    /* Go to the next file.  */
  484.         }
  485.         }
  486.  
  487.       /* Do the real copy or link.  */
  488.       switch (file_hdr.c_mode & CP_IFMT)
  489.         {
  490.         case CP_IFREG:
  491. #ifndef __MSDOS__
  492.           /* Can the current file be linked to a previously copied file? */
  493.           if (file_hdr.c_nlink > 1 && archive_format != arf_tar
  494.           && archive_format != arf_ustar)
  495.         {
  496.           link_name = find_inode_file (file_hdr.c_ino,
  497.                     file_hdr.c_dev_maj, file_hdr.c_dev_min);
  498.           if (link_name == NULL)
  499.             add_inode (file_hdr.c_ino, file_hdr.c_name,
  500.                    file_hdr.c_dev_maj, file_hdr.c_dev_min);
  501.           else
  502.             {
  503.               res = link (link_name, file_hdr.c_name);
  504.               if (res < 0 && create_dir_flag)
  505.             {
  506.               create_all_directories (file_hdr.c_name);
  507.               res = link (link_name, file_hdr.c_name);
  508.             }
  509.               if (res == 0)
  510.             {
  511.               if (verbose_flag)
  512.                 error (0, 0, "%s linked to %s",
  513.                    link_name, file_hdr.c_name);
  514.               toss_input (in_file_des, file_hdr.c_filesize);
  515.               skip_padding (in_file_des, file_hdr.c_filesize);
  516.             }
  517.               else
  518.             link_name = NULL;
  519.             }
  520.         }
  521.           else if ((archive_format == arf_tar || archive_format == arf_ustar)
  522.                && file_hdr.c_tar_linkname)
  523.         {
  524.           link_name = file_hdr.c_tar_linkname;
  525.           res = link (link_name, file_hdr.c_name);
  526.           if (res < 0 && create_dir_flag)
  527.             {
  528.               create_all_directories (file_hdr.c_name);
  529.               res = link (link_name, file_hdr.c_name);
  530.             }
  531.           if (res == 0)
  532.             {
  533.               if (verbose_flag)
  534.             error (0, 0, "%s linked to %s",
  535.                    link_name, file_hdr.c_name);
  536.             }
  537.           else
  538.             {
  539.               error (0, errno, "cannot link %s to %s",
  540.                  file_hdr.c_tar_linkname, file_hdr.c_name);
  541.             }
  542.         }
  543. #endif
  544.  
  545.           /* If not linked, copy the contents of the file.  */
  546.           if (link_name == NULL)
  547.         {
  548.           out_file_des = open (file_hdr.c_name,
  549.                        O_CREAT | O_WRONLY | O_BINARY, 0600);
  550.           if (out_file_des < 0 && create_dir_flag)
  551.             {
  552.               create_all_directories (file_hdr.c_name);
  553.               out_file_des = open (file_hdr.c_name,
  554.                        O_CREAT | O_WRONLY | O_BINARY,
  555.                        0600);
  556.             }
  557.           if (out_file_des < 0)
  558.             {
  559.               error (0, errno, "%s", file_hdr.c_name);
  560.               toss_input (in_file_des, file_hdr.c_filesize);
  561.               skip_padding (in_file_des, file_hdr.c_filesize);
  562.               continue;
  563.             }
  564.  
  565.           crc = 0;
  566.           if (swap_halfwords_flag)
  567.             {
  568.               if ((file_hdr.c_filesize % 4) == 0)
  569.             swapping_halfwords = TRUE;
  570.               else
  571.             error (0, 0, "cannot swap halfwords of %s: odd number of halfwords",
  572.                    file_hdr.c_name);
  573.             }
  574.           if (swap_bytes_flag)
  575.             {
  576.               if ((file_hdr.c_filesize % 2) == 0)
  577.             swapping_bytes = TRUE;
  578.               else
  579.             error (0, 0, "cannot swap bytes of %s: odd number of bytes",
  580.                    file_hdr.c_name);
  581.             }
  582.           copy_files (in_file_des, out_file_des, file_hdr.c_filesize);
  583.           empty_output_buffer (out_file_des);
  584.           if (close (out_file_des) < 0)
  585.             error (0, errno, "%s", file_hdr.c_name);
  586.  
  587.           if (archive_format == arf_crcascii)
  588.             {
  589.               if (crc != file_hdr.c_chksum)
  590.             error (0, 0, "%s: checksum error (0x%x, should be 0x%x)",
  591.                    file_hdr.c_name, crc, file_hdr.c_chksum);
  592.             }
  593.           /* File is now copied; set attributes.  */
  594.           if (!no_chown_flag)
  595.             if ((chown (file_hdr.c_name,
  596.                 set_owner_flag ? set_owner : file_hdr.c_uid,
  597.                set_group_flag ? set_group : file_hdr.c_gid) < 0)
  598.             && errno != EPERM)
  599.               error (0, errno, "%s", file_hdr.c_name);
  600.           /* chown may have turned off some permissions we wanted. */
  601.           if (chmod (file_hdr.c_name, (int) file_hdr.c_mode) < 0)
  602.             error (0, errno, "%s", file_hdr.c_name);
  603.           if (retain_time_flag)
  604.             {
  605.               times.actime = times.modtime = file_hdr.c_mtime;
  606.               if (utime (file_hdr.c_name, ×) < 0)
  607.             error (0, errno, "%s", file_hdr.c_name);
  608.             }
  609.           skip_padding (in_file_des, file_hdr.c_filesize);
  610.         }
  611.           break;
  612.  
  613.         case CP_IFDIR:
  614.           /* Strip any trailing `/'s off the filename; tar puts
  615.          them on.  We might as well do it here in case anybody
  616.          else does too, since they cause strange things to happen.  */
  617.           strip_trailing_slashes (file_hdr.c_name);
  618.  
  619.           /* Ignore the current directory.  It must already exist,
  620.          and we don't want to change its permission, ownership
  621.          or time.  */
  622.           if (file_hdr.c_name[0] == '.' && file_hdr.c_name[1] == '\0')
  623.         break;
  624.  
  625.           if (!existing_dir)
  626.         res = mkdir (file_hdr.c_name, file_hdr.c_mode);
  627.           else
  628.         res = 0;
  629.           if (res < 0 && create_dir_flag)
  630.         {
  631.           create_all_directories (file_hdr.c_name);
  632.           res = mkdir (file_hdr.c_name, file_hdr.c_mode);
  633.         }
  634.           if (res < 0)
  635.         {
  636.           error (0, errno, "%s", file_hdr.c_name);
  637.           continue;
  638.         }
  639.           if (!no_chown_flag)
  640.         if ((chown (file_hdr.c_name,
  641.                 set_owner_flag ? set_owner : file_hdr.c_uid,
  642.                 set_group_flag ? set_group : file_hdr.c_gid) < 0)
  643.             && errno != EPERM)
  644.           error (0, errno, "%s", file_hdr.c_name);
  645.           /* chown may have turned off some permissions we wanted. */
  646.           if (chmod (file_hdr.c_name, (int) file_hdr.c_mode) < 0)
  647.         error (0, errno, "%s", file_hdr.c_name);
  648.           if (retain_time_flag)
  649.         {
  650.           times.actime = times.modtime = file_hdr.c_mtime;
  651.           if (utime (file_hdr.c_name, ×) < 0)
  652.             error (0, errno, "%s", file_hdr.c_name);
  653.         }
  654.           break;
  655.  
  656. #ifndef __MSDOS__
  657.         case CP_IFCHR:
  658.         case CP_IFBLK:
  659. #ifdef CP_IFSOCK
  660.         case CP_IFSOCK:
  661. #endif
  662. #ifdef CP_IFIFO
  663.         case CP_IFIFO:
  664. #endif
  665.           res = mknod (file_hdr.c_name, file_hdr.c_mode,
  666.             makedev (file_hdr.c_rdev_maj, file_hdr.c_rdev_min));
  667.           if (res < 0 && create_dir_flag)
  668.         {
  669.           create_all_directories (file_hdr.c_name);
  670.           res = mknod (file_hdr.c_name, file_hdr.c_mode,
  671.             makedev (file_hdr.c_rdev_maj, file_hdr.c_rdev_min));
  672.         }
  673.           if (res < 0)
  674.         {
  675.           error (0, errno, "%s", file_hdr.c_name);
  676.           continue;
  677.         }
  678.           if (!no_chown_flag)
  679.         if ((chown (file_hdr.c_name,
  680.                 set_owner_flag ? set_owner : file_hdr.c_uid,
  681.                 set_group_flag ? set_group : file_hdr.c_gid) < 0)
  682.             && errno != EPERM)
  683.           error (0, errno, "%s", file_hdr.c_name);
  684.           /* chown may have turned off some permissions we wanted. */
  685.           if (chmod (file_hdr.c_name, file_hdr.c_mode) < 0)
  686.         error (0, errno, "%s", file_hdr.c_name);
  687.           break;
  688. #endif
  689.  
  690. #ifdef CP_IFLNK
  691.         case CP_IFLNK:
  692.           {
  693.         if (archive_format != arf_tar && archive_format != arf_ustar)
  694.           {
  695.             link_name = (char *) xmalloc ((unsigned int) file_hdr.c_filesize + 1);
  696.             link_name[file_hdr.c_filesize] = '\0';
  697.             copy_in_buf (link_name, in_file_des, file_hdr.c_filesize);
  698.             skip_padding (in_file_des, file_hdr.c_filesize);
  699.           }
  700.         else
  701.           {
  702.             link_name = xstrdup (file_hdr.c_tar_linkname);
  703.           }
  704.  
  705.         res = symlink (link_name, file_hdr.c_name);
  706.         if (res < 0 && create_dir_flag)
  707.           {
  708.             create_all_directories (file_hdr.c_name);
  709.             res = symlink (link_name, file_hdr.c_name);
  710.           }
  711.         if (res < 0)
  712.           {
  713.             error (0, errno, "%s", file_hdr.c_name);
  714.             free (link_name);
  715.             link_name = NULL;
  716.             continue;
  717.           }
  718.         if (!no_chown_flag)
  719.           if ((lchown (file_hdr.c_name,
  720.                    set_owner_flag ? set_owner : file_hdr.c_uid,
  721.                set_group_flag ? set_group : file_hdr.c_gid) < 0)
  722.               && errno != EPERM)
  723.             error (0, errno, "%s", file_hdr.c_name);
  724.         free (link_name);
  725.         link_name = NULL;
  726.           }
  727.           break;
  728. #endif
  729.  
  730.         default:
  731.           error (0, 0, "%s: unknown file type", file_hdr.c_name);
  732.           toss_input (in_file_des, file_hdr.c_filesize);
  733.           skip_padding (in_file_des, file_hdr.c_filesize);
  734.         }
  735.  
  736.       if (verbose_flag)
  737.         fprintf (stderr, "%s\n", file_hdr.c_name);
  738.       if (dot_flag)
  739.         fputc ('.', stderr);
  740.     }
  741.     }
  742.  
  743.   if (dot_flag)
  744.     fputc ('\n', stderr);
  745.  
  746.   if (append_flag)
  747.     return;
  748.  
  749.   res = (input_bytes + io_block_size - 1) / io_block_size;
  750.   if (res == 1)
  751.     fprintf (stderr, "1 block\n");
  752.   else
  753.     fprintf (stderr, "%d blocks\n", res);
  754. }
  755.  
  756. /* Print the file described by FILE_HDR in long format.
  757.    If LINK_NAME is nonzero, it is the name of the file that
  758.    this file is a symbolic link to.  */
  759.  
  760. void
  761. long_format (file_hdr, link_name)
  762.      struct new_cpio_header *file_hdr;
  763.      char *link_name;
  764. {
  765.   char mbuf[11];
  766.   char tbuf[40];
  767.   time_t when;
  768.  
  769.   mode_string (file_hdr->c_mode, mbuf);
  770.   mbuf[10] = '\0';
  771.  
  772.   /* Get time values ready to print.  */
  773.   when = file_hdr->c_mtime;
  774.   strcpy (tbuf, ctime (&when));
  775.   if (current_time - when > 6L * 30L * 24L * 60L * 60L
  776.       || current_time - when < 0L)
  777.     {
  778.       /* The file is older than 6 months, or in the future.
  779.      Show the year instead of the time of day.  */
  780.       strcpy (tbuf + 11, tbuf + 19);
  781.     }
  782.   tbuf[16] = '\0';
  783.  
  784.   printf ("%s %3u ", mbuf, file_hdr->c_nlink);
  785.  
  786. #ifndef __MSDOS__
  787.   if (numeric_uid)
  788. #endif
  789.     printf ("%-8u %-8u ", (unsigned int) file_hdr->c_uid,
  790.         (unsigned int) file_hdr->c_gid);
  791. #ifndef __MSDOS__
  792.   else
  793.     printf ("%-8.8s %-8.8s ", getuser (file_hdr->c_uid),
  794.         getgroup (file_hdr->c_gid));
  795.  
  796.   if ((file_hdr->c_mode & CP_IFMT) == CP_IFCHR
  797.       || (file_hdr->c_mode & CP_IFMT) == CP_IFBLK)
  798.     printf ("%3u, %3u ", file_hdr->c_rdev_maj,
  799.         file_hdr->c_rdev_min);
  800.   else
  801. #endif
  802.     printf ("%8lu ", file_hdr->c_filesize);
  803.  
  804.   printf ("%s ", tbuf + 4);
  805.  
  806.   print_name_with_quoting (file_hdr->c_name);
  807.   if (link_name)
  808.     {
  809.       printf (" -> ");
  810.       print_name_with_quoting (link_name);
  811.     }
  812.   putc ('\n', stdout);
  813. }
  814.  
  815. void
  816. print_name_with_quoting (p)
  817.      register char *p;
  818. {
  819.   register unsigned char c;
  820.  
  821.   while (c = *p++)
  822.     {
  823.       switch (c)
  824.     {
  825. #ifndef __MSDOS__
  826.     case '\\':
  827.       printf ("\\\\");
  828.       break;
  829. #endif
  830.  
  831.     case '\n':
  832.       printf ("\\n");
  833.       break;
  834.  
  835.     case '\b':
  836.       printf ("\\b");
  837.       break;
  838.  
  839.     case '\r':
  840.       printf ("\\r");
  841.       break;
  842.  
  843.     case '\t':
  844.       printf ("\\t");
  845.       break;
  846.  
  847.     case '\f':
  848.       printf ("\\f");
  849.       break;
  850.  
  851.     case ' ':
  852.       printf ("\\ ");
  853.       break;
  854.  
  855.     case '"':
  856.       printf ("\\\"");
  857.       break;
  858.  
  859.     default:
  860.       if (c > 040 &&
  861. #ifdef __MSDOS__
  862.           c < 0377 && c != 0177
  863. #else
  864.           c < 0177
  865. #endif
  866.         )
  867.         putchar (c);
  868.       else
  869.         printf ("\\%03o", (unsigned int) c);
  870.     }
  871.     }
  872. }
  873.  
  874. /* Read a pattern file (for the -E option).  Put a list of
  875.    `num_patterns' elements in `save_patterns'.  Any patterns that were
  876.    already in `save_patterns' (from the command line) are preserved.  */
  877.  
  878. static void
  879. read_pattern_file ()
  880. {
  881.   int max_new_patterns;
  882.   char **new_save_patterns;
  883.   int new_num_patterns;
  884.   int i;
  885.   dynamic_string pattern_name;
  886.   FILE *pattern_fp;
  887.  
  888.   if (num_patterns < 0)
  889.     num_patterns = 0;
  890.   max_new_patterns = 1 + num_patterns;
  891.   new_save_patterns = (char **) xmalloc (max_new_patterns * sizeof (char *));
  892.   new_num_patterns = num_patterns;
  893.   ds_init (&pattern_name, 128);
  894.  
  895.   pattern_fp = fopen (pattern_file_name, "r");
  896.   if (pattern_fp == NULL)
  897.     error (1, errno, "%s", pattern_file_name);
  898.   while (ds_fgetstr (pattern_fp, &pattern_name, '\n') != NULL)
  899.     {
  900.       if (new_num_patterns >= max_new_patterns)
  901.     {
  902.       max_new_patterns += 1;
  903.       new_save_patterns = (char **)
  904.         xrealloc ((char *) new_save_patterns,
  905.               max_new_patterns * sizeof (char *));
  906.     }
  907.       new_save_patterns[new_num_patterns] = xstrdup (pattern_name.ds_string);
  908.       ++new_num_patterns;
  909.     }
  910.   if (ferror (pattern_fp) || fclose (pattern_fp) == EOF)
  911.     error (1, errno, "%s", pattern_file_name);
  912.  
  913.   for (i = 0; i < num_patterns; ++i)
  914.     new_save_patterns[i] = save_patterns[i];
  915.  
  916.   save_patterns = new_save_patterns;
  917.   num_patterns = new_num_patterns;
  918. }
  919.  
  920. /* Skip the padding on IN_FILE_DES after a header or file,
  921.    up to the next header.
  922.    The number of bytes skipped is based on OFFSET -- the current offset
  923.    from the last start of a header (or file) -- and the current
  924.    header type.  */
  925.  
  926. static void
  927. skip_padding (in_file_des, offset)
  928.      int in_file_des;
  929.      int offset;
  930. {
  931.   int pad;
  932.  
  933.   if (archive_format == arf_crcascii || archive_format == arf_newascii)
  934.     pad = (4 - (offset % 4)) % 4;
  935.   else if (archive_format == arf_binary)
  936.     pad = (2 - (offset % 2)) % 2;
  937.   else if (archive_format == arf_tar || archive_format == arf_ustar)
  938.     pad = (512 - (offset % 512)) % 512;
  939.   else
  940.     pad = 0;
  941.  
  942.   if (pad != 0)
  943.     toss_input (in_file_des, pad);
  944. }
  945.