home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / c / cpio11as.zip / MAIN.C < prev    next >
C/C++ Source or Header  |  1992-02-22  |  8KB  |  299 lines

  1. /* main.c - main program and argument processing for cpio.
  2.    Copyright (C) 1988, 1989, 1990 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 1, 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. /* Written by Philip A. Nelson and David MacKenzie.  */
  19.  
  20. /* MS-DOS port (c) 1990 by Thorsten Ohl, ohl@gnu.ai.mit.edu
  21.    This port is also distributed under the terms of the
  22.    GNU General Public License as published by the
  23.    Free Software Foundation.
  24.  
  25.    Please note that this file is not identical to the
  26.    original GNU release, you should have received this
  27.    code as patch to the official release.
  28.  
  29.    $Header: e:/gnu/cpio/RCS/main.c 1.1.0.2 90/09/23 23:11:10 tho Exp $
  30.  */
  31.  
  32. #include <stdio.h>
  33. #include <sys/types.h>
  34. #include <sys/stat.h>
  35. #ifndef S_IFLNK
  36. #define lstat stat
  37. #endif
  38. #ifdef USG
  39. #include <string.h>
  40. #else
  41. #include <strings.h>
  42. #endif
  43. #include <getopt.h>
  44. #include "cpio.h"
  45. #include "dstring.h"
  46. #include "extern.h"
  47.  
  48. int lstat ();
  49. int stat ();
  50.  
  51. #ifdef MSDOS
  52. extern void usage (void);
  53. extern void main (int argc, char **argv);
  54. extern void process_args (int argc, char **argv);
  55. extern void initialize_buffers (void);
  56. #endif /* MSDOS */
  57.  
  58. struct option long_opts[] =
  59. {
  60.   {"binary", 0, &binary_flag, TRUE},
  61.   {"block-size", 1, 0, 130},
  62.   {"create", 0, 0, 'o'},
  63.   {"dereference", 0, 0, 'L'},
  64.   {"extract", 0, 0, 'i'},
  65.   {"link", 0, &link_flag, TRUE},
  66.   {"list", 0, &table_flag, TRUE},
  67.   {"make-directories", 0, &create_dir_flag, TRUE},
  68.   {"nonmatching", 0, ©_matching_files, FALSE},
  69.   {"numeric-uid-gid", 0, &numeric_uid, TRUE},
  70.   {"pass-through", 0, 0, 'p'},
  71.   {"portability", 0, &portability_flag, TRUE},
  72.   {"preserve-modification-time", 0, &retain_time_flag, TRUE},
  73.   {"rename", 0, &rename_flag, TRUE},
  74.   {"reset-access-time", 0, &reset_time_flag, TRUE},
  75.   {"unconditional", 0, &unconditional_flag, TRUE},
  76.   {"verbose", 0, &verbose_flag, TRUE},
  77.   {"version", 0, 0, 'V'},
  78.   {0, 0, 0, 0}
  79. };
  80.  
  81. /*  Print usage message and exit with error.  */
  82.  
  83. void
  84. usage ()
  85. {
  86.   fprintf (stderr, "\
  87. Usage: %s {-o|+create} [-abcvBLV] [+reset-access-time] [+binary]\n\
  88.        [+portability] [+verbose] [+block-size=blocks] [+dereference]\n\
  89.        [+version] < name-list > archive\n\
  90. \n\
  91.        %s {-i|+extract} [-bcdfmnrtuvBV] [+binary] [+portability]\n\
  92.        [+make-directories] [+nonmatching] [+preserve-modification-time]\n\
  93.        [+numeric-uid-gid] [+rename] [+list] [+unconditional] [+verbose]\n\
  94.        [+block-size=blocks] [+version] [pattern...] < archive\n\
  95. \n\
  96.        %s {-p|+pass-through} [-adlLmuvV] [+reset-access-time]\n\
  97.        [+make-directories] [+link] [+preserve-modification-time]\n\
  98.        [+unconditional] [+verbose] [+dereference] [+version]\n\
  99.        destination-directory < name-list\n",
  100.        program_name, program_name, program_name);
  101.   exit (2);
  102. }
  103.  
  104. /* Process the arguments.  Set all options and set up the copy pass
  105.    directory or the copy in patterns.  */
  106.  
  107. void
  108. process_args (argc, argv)
  109.      int argc;
  110.      char *argv[];
  111. {
  112.   extern char *version_string;
  113.   void (*copy_in) ();        /* Work around for pcc bug. */
  114.   void (*copy_out) ();
  115.   int c;
  116.   int longind;
  117.  
  118.   if (argc < 2)
  119.     usage ();
  120.  
  121.   xstat = lstat;
  122.  
  123.   while ((c = getopt_long (argc, argv, "abBcdfilLmnoprtuvV", long_opts,
  124.                &longind)) != EOF)
  125.     {
  126.       switch (c)
  127.     {
  128.     case 0:            /* A long option that just sets a flag. */
  129.       break;
  130.  
  131.     case 'a':        /* Reset access times.  */
  132.       reset_time_flag = TRUE;
  133.       break;
  134.  
  135.     case 'b':        /* Use the nonportable format. */
  136.       binary_flag = TRUE;
  137.       break;
  138.  
  139.     case 'B':        /* Set block size to 5120. */
  140.       io_block_size = 5120;
  141.       break;
  142.  
  143.     case 130:        /* +block-size */
  144.       io_block_size = atoi (optarg);
  145.       if (io_block_size < 1)
  146.         error (2, 0, "invalid block size");
  147.       io_block_size *= 512;
  148.       break;
  149.  
  150.     case 'c':        /* Use the portable format. */
  151.       portability_flag = TRUE;
  152.       break;
  153.  
  154.     case 'd':        /* Create directories where needed.  */
  155.       create_dir_flag = TRUE;
  156.       break;
  157.  
  158.     case 'f':        /* Only copy files not matching patterns. */
  159.       copy_matching_files = FALSE;
  160.       break;
  161.  
  162.     case 'i':        /* Copy-in mode.  */
  163.       if (copy_function != 0)
  164.         usage ();
  165.       copy_function = process_copy_in;
  166.       break;
  167.  
  168.     case 'l':        /* Link files when possible.  */
  169.       link_flag = TRUE;
  170.       break;
  171.  
  172.     case 'L':        /* Dereference symbolic links.  */
  173.       xstat = stat;
  174.       break;
  175.  
  176.     case 'm':        /* Retain previous file modify times. */
  177.       retain_time_flag = TRUE;
  178.       break;
  179.  
  180.     case 'n':        /* Long list owner and group as numbers. */
  181.       numeric_uid = TRUE;
  182.       break;
  183.  
  184.     case 'o':        /* Copy-out mode.  */
  185.       if (copy_function != 0)
  186.         usage ();
  187.       copy_function = process_copy_out;
  188.       break;
  189.  
  190.     case 'p':        /* Copy-pass mode.  */
  191.       if (copy_function != 0)
  192.         usage ();
  193.       copy_function = process_copy_pass;
  194.       break;
  195.  
  196.     case 'r':        /* Interactively rename.  */
  197.       rename_flag = TRUE;
  198.       break;
  199.  
  200.     case 't':        /* Only print a list.  */
  201.       table_flag = TRUE;
  202.       break;
  203.  
  204.     case 'u':        /* Replace all!  Unconditionally!  */
  205.       unconditional_flag = TRUE;
  206.       break;
  207.  
  208.     case 'v':        /* Verbose!  */
  209.       verbose_flag = TRUE;
  210.       break;
  211.  
  212.     case 'V':
  213.       printf ("%s", version_string);
  214.       break;
  215.  
  216.     default:
  217.       usage ();
  218.     }
  219.     }
  220.  
  221.   /* Do error checking and look at other args.  */
  222.  
  223.   if (copy_function == 0)
  224.     {
  225.       if (table_flag)
  226.     copy_function = process_copy_in;
  227.       else
  228.     usage ();
  229.     }
  230.  
  231.   if ((!table_flag || !verbose_flag) && numeric_uid)
  232.     usage ();
  233.  
  234.   /* Work around for pcc bug. */
  235.   copy_in = process_copy_in;
  236.   copy_out = process_copy_out;
  237.  
  238.   if (copy_function == copy_in)
  239.     {
  240.       if (link_flag || reset_time_flag || xstat != lstat
  241.       || (binary_flag && portability_flag))
  242.     usage ();
  243.       if (!binary_flag && !portability_flag)
  244.     binary_flag = portability_flag = TRUE;
  245.       num_patterns = argc - optind;
  246.       save_patterns = &argv[optind];
  247.     }
  248.   else if (copy_function == copy_out)
  249.     {
  250.       if (argc != optind || create_dir_flag || rename_flag
  251.       || table_flag || unconditional_flag || link_flag
  252.       || retain_time_flag || (binary_flag && portability_flag))
  253.     usage ();
  254.     }
  255.   else
  256.     {
  257.       if (argc - 1 != optind || binary_flag || portability_flag
  258.       || table_flag || rename_flag)
  259.     usage ();
  260.       directory_name = argv[optind];
  261.     }
  262. }
  263.  
  264. /* Initialize the input and output buffers to their proper size and
  265.    initialize all variables associated with the input and output
  266.    buffers.  */
  267.  
  268. void
  269. initialize_buffers ()
  270. {
  271.   input_buffer = (char *) xmalloc (io_block_size);
  272.   in_buff = input_buffer;
  273.   input_size = 0;
  274.   input_bytes = 0;
  275.  
  276.   /* Leave space for an `int' sentinel for `empty_output_buffer'. */
  277.   output_buffer = (char *) xmalloc (io_block_size + sizeof (int) * 2);
  278.   out_buff = output_buffer;
  279.   output_size = 0;
  280.   output_bytes = 0;
  281. }
  282.  
  283. void
  284. main (argc, argv)
  285.      int argc;
  286.      char *argv[];
  287. {
  288.   program_name = argv[0];
  289.   umask (0);
  290.  
  291.   process_args (argc, argv);
  292.  
  293.   initialize_buffers ();
  294.  
  295.   (*copy_function) ();
  296.  
  297.   exit (0);
  298. }
  299.