home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / cpio-2.3-src.lha / GNU / src / amiga / cpio-2.3 / copyin.c < prev    next >
C/C++ Source or Header  |  1993-05-04  |  37KB  |  1,273 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 <sys/types.h>
  20. #include <sys/stat.h>
  21. #include "filetypes.h"
  22. #include "system.h"
  23. #include "cpiohdr.h"
  24. #include "dstring.h"
  25. #include "extern.h"
  26. #include "defer.h"
  27. #include "rmt.h"
  28. #ifndef    FNM_PATHNAME
  29. #include <fnmatch.h>
  30. #endif
  31.  
  32. #ifndef HAVE_LCHOWN
  33. #define lchown chown
  34. #endif
  35.  
  36. static void read_pattern_file ();
  37. static void skip_padding ();
  38. static void defer_copyin ();
  39. static void create_defered_links ();
  40. static void create_final_defers ();
  41.  
  42. /* Return 16-bit integer I with the bytes swapped.  */
  43. #define swab_short(i) ((((i) << 8) & 0xff00) | (((i) >> 8) & 0x00ff))
  44.  
  45. /* Read the header, including the name of the file, from file
  46.    descriptor IN_DES into FILE_HDR.  */
  47.  
  48. void
  49. read_in_header (file_hdr, in_des)
  50.      struct new_cpio_header *file_hdr;
  51.      int in_des;
  52. {
  53.   long bytes_skipped = 0;    /* Bytes of junk found before magic number.  */
  54.  
  55.   /* Search for a valid magic number.  */
  56.  
  57.   if (archive_format == arf_unknown)
  58.     {
  59.       char tmpbuf[512];
  60.       int check_tar;
  61.       int peeked_bytes;
  62.  
  63.       while (archive_format == arf_unknown)
  64.     {
  65.       peeked_bytes = peek_in_buf (tmpbuf, in_des, 512);
  66.       if (peeked_bytes < 6)
  67.         error (1, 0, "premature end of archive");
  68.  
  69.       if (!strncmp (tmpbuf, "070701", 6))
  70.         archive_format = arf_newascii;
  71.       else if (!strncmp (tmpbuf, "070707", 6))
  72.         archive_format = arf_oldascii;
  73.       else if (!strncmp (tmpbuf, "070702", 6))
  74.         {
  75.           archive_format = arf_crcascii;
  76.           crc_i_flag = TRUE;
  77.         }
  78.       else if ((*((unsigned short *) tmpbuf) == 070707) ||
  79.            (*((unsigned short *) tmpbuf) == swab_short ((unsigned short) 070707)))
  80.         archive_format = arf_binary;
  81.       else if (peeked_bytes >= 512
  82.            && (check_tar = is_tar_header (tmpbuf)))
  83.         {
  84.           if (check_tar == 2)
  85.         archive_format = arf_ustar;
  86.           else
  87.         archive_format = arf_tar;
  88.         }
  89.       else
  90.         {
  91.           copy_in_buf ((char *) tmpbuf, in_des, 1L);
  92.           ++bytes_skipped;
  93.         }
  94.     }
  95.     }
  96.  
  97.   if (archive_format == arf_tar || archive_format == arf_ustar)
  98.     {
  99.       if (append_flag)
  100.     last_header_start = input_bytes - io_block_size +
  101.       (in_buff - input_buffer);
  102.       if (bytes_skipped > 0)
  103.     error (0, 0, "warning: skipped %ld bytes of junk", bytes_skipped);
  104.       read_in_tar_header (file_hdr, in_des);
  105.       return;
  106.     }
  107.  
  108.   file_hdr->c_tar_linkname = NULL;
  109.  
  110.   copy_in_buf ((char *) file_hdr, in_des, 6L);
  111.   while (1)
  112.     {
  113.       if (append_flag)
  114.     last_header_start = input_bytes - io_block_size
  115.       + (in_buff - input_buffer) - 6;
  116.       if (archive_format == arf_newascii
  117.       && !strncmp ((char *) file_hdr, "070701", 6))
  118.     {
  119.       if (bytes_skipped > 0)
  120.         error (0, 0, "warning: skipped %ld bytes of junk", bytes_skipped);
  121.       read_in_new_ascii (file_hdr, in_des);
  122.       break;
  123.     }
  124.       if (archive_format == arf_crcascii
  125.       && !strncmp ((char *) file_hdr, "070702", 6))
  126.     {
  127.       if (bytes_skipped > 0)
  128.         error (0, 0, "warning: skipped %ld bytes of junk", bytes_skipped);
  129.       read_in_new_ascii (file_hdr, in_des);
  130.       break;
  131.     }
  132.       if ( (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
  133.       && !strncmp ((char *) file_hdr, "070707", 6))
  134.     {
  135.       if (bytes_skipped > 0)
  136.         error (0, 0, "warning: skipped %ld bytes of junk", bytes_skipped);
  137.       read_in_old_ascii (file_hdr, in_des);
  138.       break;
  139.     }
  140.       if ( (archive_format == arf_binary || archive_format == arf_hpbinary)
  141.       && (file_hdr->c_magic == 070707
  142.           || file_hdr->c_magic == swab_short ((unsigned short) 070707)))
  143.     {
  144.       /* Having to skip 1 byte because of word alignment is normal.  */
  145.       if (bytes_skipped > 0)
  146.         error (0, 0, "warning: skipped %ld bytes of junk", bytes_skipped);
  147.       read_in_binary (file_hdr, in_des);
  148.       break;
  149.     }
  150.       bytes_skipped++;
  151.       bcopy ((char *) file_hdr + 1, (char *) file_hdr, 5);
  152.       copy_in_buf ((char *) file_hdr + 5, in_des, 1L);
  153.     }
  154. }
  155.  
  156. /* Fill in FILE_HDR by reading an old-format ASCII format cpio header from
  157.    file descriptor IN_DES, except for the magic number, which is
  158.    already filled in.  */
  159.  
  160. void
  161. read_in_old_ascii (file_hdr, in_des)
  162.      struct new_cpio_header *file_hdr;
  163.      int in_des;
  164. {
  165.   char ascii_header[78];
  166.   unsigned long dev;
  167.   unsigned long rdev;
  168.  
  169.   copy_in_buf (ascii_header, in_des, 70L);
  170.   ascii_header[70] = '\0';
  171.   sscanf (ascii_header,
  172.       "%6lo%6lo%6lo%6lo%6lo%6lo%6lo%11lo%6lo%11lo",
  173.       &dev, &file_hdr->c_ino,
  174.       &file_hdr->c_mode, &file_hdr->c_uid, &file_hdr->c_gid,
  175.       &file_hdr->c_nlink, &rdev, &file_hdr->c_mtime,
  176.       &file_hdr->c_namesize, &file_hdr->c_filesize);
  177.   file_hdr->c_dev_maj = major (dev);
  178.   file_hdr->c_dev_min = minor (dev);
  179.   file_hdr->c_rdev_maj = major (rdev);
  180.   file_hdr->c_rdev_min = minor (rdev);
  181.  
  182.   /* Read file name from input.  */
  183.   if (file_hdr->c_name != NULL)
  184.     free (file_hdr->c_name);
  185.   file_hdr->c_name = (char *) xmalloc (file_hdr->c_namesize + 1);
  186.   copy_in_buf (file_hdr->c_name, in_des, (long) file_hdr->c_namesize);
  187. #ifndef __MSDOS__
  188.   /* HP/UX cpio creates archives that look just like ordinary archives,
  189.      but for devices it sets major = 0, minor = 1, and puts the
  190.      actual major/minor number in the filesize field.  See if this
  191.      is an HP/UX cpio archive, and if so fix it.  We have to do this
  192.      here because process_copy_in() assumes filesize is always 0
  193.      for devices.  */
  194.   switch (file_hdr->c_mode & CP_IFMT)
  195.     {
  196.       case CP_IFCHR:
  197.       case CP_IFBLK:
  198. #ifdef CP_IFSOCK
  199.       case CP_IFSOCK:
  200. #endif
  201. #ifdef CP_IFIFO
  202.       case CP_IFIFO:
  203. #endif
  204.     if (file_hdr->c_filesize != 0
  205.         && file_hdr->c_rdev_maj == 0
  206.         && file_hdr->c_rdev_min == 1)
  207.       {
  208.         file_hdr->c_rdev_maj = major (file_hdr->c_filesize);
  209.         file_hdr->c_rdev_min = minor (file_hdr->c_filesize);
  210.         file_hdr->c_filesize = 0;
  211.       }
  212.     break;
  213.       default:
  214.     break;
  215.     }
  216. #endif  /* __MSDOS__ */
  217. }
  218.  
  219. /* Fill in FILE_HDR by reading a new-format ASCII format cpio header from
  220.    file descriptor IN_DES, except for the magic number, which is
  221.    already filled in.  */
  222.  
  223. void
  224. read_in_new_ascii (file_hdr, in_des)
  225.      struct new_cpio_header *file_hdr;
  226.      int in_des;
  227. {
  228.   char ascii_header[112];
  229.  
  230.   copy_in_buf (ascii_header, in_des, 104L);
  231.   ascii_header[104] = '\0';
  232.   sscanf (ascii_header,
  233.       "%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx",
  234.       &file_hdr->c_ino, &file_hdr->c_mode, &file_hdr->c_uid,
  235.       &file_hdr->c_gid, &file_hdr->c_nlink, &file_hdr->c_mtime,
  236.       &file_hdr->c_filesize, &file_hdr->c_dev_maj, &file_hdr->c_dev_min,
  237.     &file_hdr->c_rdev_maj, &file_hdr->c_rdev_min, &file_hdr->c_namesize,
  238.       &file_hdr->c_chksum);
  239.   /* Read file name from input.  */
  240.   if (file_hdr->c_name != NULL)
  241.     free (file_hdr->c_name);
  242.   file_hdr->c_name = (char *) xmalloc (file_hdr->c_namesize);
  243.   copy_in_buf (file_hdr->c_name, in_des, (long) file_hdr->c_namesize);
  244.  
  245.   /* In SVR4 ASCII format, the amount of space allocated for the header
  246.      is rounded up to the next long-word, so we might need to drop
  247.      1-3 bytes.  */
  248.   skip_padding (in_des, file_hdr->c_namesize + 110);
  249. }
  250.  
  251. /* Fill in FILE_HDR by reading a binary format cpio header from
  252.    file descriptor IN_DES, except for the first 6 bytes (the magic
  253.    number, device, and inode number), which are already filled in.  */
  254.  
  255. void
  256. read_in_binary (file_hdr, in_des)
  257.      struct new_cpio_header *file_hdr;
  258.      int in_des;
  259. {
  260.   struct old_cpio_header short_hdr;
  261.  
  262.   /* Copy the data into the short header, then later transfer
  263.      it into the argument long header.  */
  264.   short_hdr.c_dev = ((struct old_cpio_header *)