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 / copyout.c < prev    next >
C/C++ Source or Header  |  1993-04-28  |  23KB  |  802 lines

  1. /* copyout.c - create 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.  
  29. static unsigned long read_for_checksum ();
  30. static void clear_rest_of_block ();
  31. static void pad_output ();
  32. static int last_link ();
  33. static int count_defered_links_to_dev_ino ();
  34. static void add_link_defer ();
  35. static void writeout_other_defers ();
  36. static void writeout_final_defers();
  37. static void writeout_defered_file ();
  38.  
  39. /* Write out header FILE_HDR, including the file name, to file
  40.    descriptor OUT_DES.  */
  41.  
  42. void
  43. write_out_header (file_hdr, out_des)
  44.      struct new_cpio_header *file_hdr;
  45.      int out_des;
  46. {
  47.   if (archive_format == arf_newascii || archive_format == arf_crcascii)
  48.     {
  49.       char ascii_header[112];
  50.       char *magic_string;
  51.  
  52.       if (archive_format == arf_crcascii)
  53.     magic_string = "070702";
  54.       else
  55.     magic_string = "070701";
  56.       sprintf (ascii_header,
  57.            "%6s%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx",
  58.            magic_string,
  59.            file_hdr->c_ino, file_hdr->c_mode, file_hdr->c_uid,
  60.            file_hdr->c_gid, file_hdr->c_nlink, file_hdr->c_mtime,
  61.          file_hdr->c_filesize, file_hdr->c_dev_maj, file_hdr->c_dev_min,
  62.        file_hdr->c_rdev_maj, file_hdr->c_rdev_min, file_hdr->c_namesize,
  63.            file_hdr->c_chksum);
  64.       copy_buf_out (ascii_header, out_des, 110L);
  65.  
  66.       /* Write file name to output.  */
  67.       copy_buf_out (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
  68.       pad_output (out_des, file_hdr->c_namesize + 110);
  69.     }
  70.   else if (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
  71.     {
  72.       char ascii_header[78];
  73. #ifndef __MSDOS__
  74.       dev_t dev;
  75.       dev_t rdev;
  76.  
  77.       if (archive_format == arf_oldascii)
  78.     {
  79.       dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
  80.       rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
  81.     }
  82.       else
  83.     {
  84.       /* HP/UX cpio creates archives that look just like ordinary archives,
  85.          but for devices it sets major = 0, minor = 1, and puts the
  86.          actual major/minor number in the filesize field.  */
  87.       switch (file_hdr->c_mode & CP_IFMT)
  88.         {
  89.           case CP_IFCHR:
  90.           case CP_IFBLK:
  91. #ifdef CP_IFSOCK
  92.           case CP_IFSOCK:
  93. #endif
  94. #ifdef CP_IFIFO
  95.           case CP_IFIFO:
  96. #endif
  97.         file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj,
  98.                         file_hdr->c_rdev_min);
  99.         rdev = 1;
  100.         break;
  101.           default:
  102.         dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
  103.         rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
  104.         break;
  105.         }
  106.     }
  107. #else
  108.       int dev = 0, rdev = 0;
  109. #endif
  110.  
  111.       if ((file_hdr->c_ino >> 16) != 0)
  112.     error (0, 0, "%s: truncating inode number", file_hdr->c_name);
  113.  
  114.       sprintf (ascii_header,
  115.            "%06lo%06lo%06lo%06lo%06lo%06lo%06lo%06lo%011lo%06lo%011lo",
  116.            file_hdr->c_magic & 0xFFFF, dev & 0xFFFF,
  117.            file_hdr->c_ino & 0xFFFF, file_hdr->c_mode & 0xFFFF,
  118.            file_hdr->c_uid & 0xFFFF, file_hdr->c_gid & 0xFFFF,
  119.            file_hdr->c_nlink & 0xFFFF, rdev & 0xFFFF,
  120.            file_hdr->c_mtime, file_hdr->c_namesize & 0xFFFF,
  121.            file_hdr->c_filesize);
  122.       copy_buf_out (ascii_header, out_des, 76L);
  123.  
  124.       /* Write file name to output.  */
  125.       copy_buf_out (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
  126.     }
  127.   else if (archive_format == arf_tar || archive_format == arf_ustar)
  128.     {
  129.       write_out_tar_header (file_hdr, out_des);
  130.     }
  131.   else
  132.     {
  133.       struct old_cpio_header short_hdr;
  134.  
  135.       short_hdr.c_magic = 070707;
  136.       short_hdr.c_dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
  137.  
  138.       if ((file_hdr->c_ino >> 16) != 0)
  139.     error (0, 0, "%s: truncating inode number", file_hdr->c_name);
  140.  
  141.       short_hdr.c_ino = file_hdr->c_ino & 0xFFFF;
  142.       short_hdr.c_mode = file_hdr->c_mode & 0xFFFF;
  143.       short_hdr.c_uid = file_hdr->c_uid & 0xFFFF;
  144.       short_hdr.c_gid = file_hdr->c_gid & 0xFFFF;
  145.       short_hdr.c_nlink = file_hdr->c_nlink & 0xFFFF;
  146.       if (archive_format != arf_hpbinary)
  147.     short_hdr.c_rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
  148.       else
  149.     {
  150.       switch (file_hdr->c_mode & CP_IFMT)
  151.         {
  152.           /* HP/UX cpio creates archives that look just like ordinary 
  153.          archives, but for devices it sets major = 0, minor = 1, and 
  154.          puts the actual major/minor number in the filesize field.  */
  155.           case CP_IFCHR:
  156.           case CP_IFBLK:
  157. #ifdef CP_IFSOCK
  158.           case CP_IFSOCK:
  159. #endif
  160. #ifdef CP_IFIFO
  161.           case CP_IFIFO:
  162. #endif
  163.         file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj,
  164.                         file_hdr->c_rdev_min);
  165.         short_hdr.c_rdev = makedev (0, 1);
  166.         break;
  167.           default:
  168.         short_hdr.c_rdev = makedev (file_hdr->c_rdev_maj, 
  169.                         file_hdr->c_rdev_min);
  170.         break;
  171.         }
  172.     }
  173.       short_hdr.c_mtimes[0] = file_hdr->c_mtime >> 16;
  174.       short_hdr.c_mtimes[1] = file_hdr->c_mtime & 0xFFFF;
  175.  
  176.       short_hdr.c_namesize = file_hdr->c_namesize & 0xFFFF;
  177.  
  178.       short_hdr.c_filesizes[0] = file_hdr->c_filesize >> 16;
  179.       short_hdr.c_filesizes[1] = file_hdr->c_filesize & 0xFFFF;
  180.  
  181.       /* Output the file header.  */
  182.       copy_buf_out ((char *) &short_hdr, out_des, 26L);
  183.  
  184.       /* Write file name to output.  */
  185.       copy_buf_out (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
  186.  
  187.       pad_output (out_des, file_hdr->c_namesize + 26);
  188.     }
  189. }
  190.  
  191. /* Read a list of file names from the standard input
  192.    and write a cpio collection on the standard output.
  193.    The format of the header depends on the compatibility (-c) flag.  */
  194.  
  195. void
  196. process_copy_out ()
  197. {
  198.   int res;            /* Result of functions.  */
  199.   dynamic_string input_name;    /* Name of file read from stdin.  */
  200.   struct utimbuf times;        /* For resetting file times after copy.  */
  201.   struct stat file_stat;    /* Stat record for file.  */
  202.   struct new_cpio_header file_hdr; /* Output header information.  */
  203.   int in_file_des;        /* Source file descriptor.  */
  204.   int out_file_des;        /* Output file descriptor.  */
  205.   char *p;
  206.  
  207.   /* Initialize the copy out.  */
  208.   ds_init (&input_name, 128);
  209.   /* Initialize this in case it has members we don't know to set.  */
  210.   bzero (×, sizeof (struct utimbuf));
  211.   file_hdr.c_magic = 070707;
  212.  
  213. #ifdef __MSDOS__
  214.   setmode (archive_des, O_BINARY);
  215. #endif
  216.   /* Check whether the output file might be a tape.  */
  217.   out_file_des = archive_des;
  218.   if (_isrmt (out_file_des))
  219.     {
  220.       output_is_special = 1;
  221.       output_is_seekable = 0;
  222.     }
  223.   else
  224.     {
  225.       if (fstat (out_file_des, &file_stat))
  226.     error (1, errno, "standard output is closed");
  227.       output_is_special =
  228. #ifdef S_ISBLK
  229.     S_ISBLK (file_stat.st_mode) ||
  230. #endif
  231.     S_ISCHR (file_stat.st_mode);
  232.       output_is_seekable = S_ISREG (file_stat.st_mode);
  233.     }
  234.  
  235.   if (append_flag)
  236.     {
  237.       process_copy_in ();
  238.       prepare_append (out_file_des);
  239.     }
  240.  
  241.   /* Copy files with names read from stdin.  */
  242.   while (ds_fgetstr (stdin, &input_name, name_end) != NULL)
  243.     {
  244.       /* Check for blank line.  */
  245.       if (input_name.ds_string[0] == 0)
  246.     {
  247.       error (0, 0, "blank line ignored");
  248.       continue;
  249.     }
  250.  
  251.       /* Process next file.  */
  252.       if ((*xstat) (input_name.ds_string, &file_stat) < 0)
  253.     error (0, errno, "%s", input_name.ds_string);
  254.       else
  255.     {
  256.       /* Set values in output header.  */
  257.       file_hdr.c_dev_maj = major (file_stat.st_dev);
  258.       file_hdr.c_dev_min = minor (file_stat.st_dev);
  259.       file_hdr.c_ino = file_stat.st_ino;
  260.       /* For POSIX systems that don't define the S_I