home *** CD-ROM | disk | FTP | other *** search
- /* main.c - main program and argument processing for cpio.
- Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- /* Written by Philip A. Nelson and David MacKenzie. */
-
- /* MS-DOS port (c) 1990 by Thorsten Ohl, ohl@gnu.ai.mit.edu
- This port is also distributed under the terms of the
- GNU General Public License as published by the
- Free Software Foundation.
-
- Please note that this file is not identical to the
- original GNU release, you should have received this
- code as patch to the official release.
-
- $Header: e:/gnu/cpio/RCS/main.c 1.1.0.2 90/09/23 23:11:10 tho Exp $
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #ifndef S_IFLNK
- #define lstat stat
- #endif
- #ifdef USG
- #include <string.h>
- #else
- #include <strings.h>
- #endif
- #include <getopt.h>
- #include "cpio.h"
- #include "dstring.h"
- #include "extern.h"
-
- int lstat ();
- int stat ();
-
- #ifdef MSDOS
- extern void usage (void);
- extern void main (int argc, char **argv);
- extern void process_args (int argc, char **argv);
- extern void initialize_buffers (void);
- #endif /* MSDOS */
-
- struct option long_opts[] =
- {
- {"binary", 0, &binary_flag, TRUE},
- {"block-size", 1, 0, 130},
- {"create", 0, 0, 'o'},
- {"dereference", 0, 0, 'L'},
- {"extract", 0, 0, 'i'},
- {"link", 0, &link_flag, TRUE},
- {"list", 0, &table_flag, TRUE},
- {"make-directories", 0, &create_dir_flag, TRUE},
- {"nonmatching", 0, ©_matching_files, FALSE},
- {"numeric-uid-gid", 0, &numeric_uid, TRUE},
- {"pass-through", 0, 0, 'p'},
- {"portability", 0, &portability_flag, TRUE},
- {"preserve-modification-time", 0, &retain_time_flag, TRUE},
- {"rename", 0, &rename_flag, TRUE},
- {"reset-access-time", 0, &reset_time_flag, TRUE},
- {"unconditional", 0, &unconditional_flag, TRUE},
- {"verbose", 0, &verbose_flag, TRUE},
- {"version", 0, 0, 'V'},
- {0, 0, 0, 0}
- };
-
- /* Print usage message and exit with error. */
-
- void
- usage ()
- {
- fprintf (stderr, "\
- Usage: %s {-o|+create} [-abcvBLV] [+reset-access-time] [+binary]\n\
- [+portability] [+verbose] [+block-size=blocks] [+dereference]\n\
- [+version] < name-list > archive\n\
- \n\
- %s {-i|+extract} [-bcdfmnrtuvBV] [+binary] [+portability]\n\
- [+make-directories] [+nonmatching] [+preserve-modification-time]\n\
- [+numeric-uid-gid] [+rename] [+list] [+unconditional] [+verbose]\n\
- [+block-size=blocks] [+version] [pattern...] < archive\n\
- \n\
- %s {-p|+pass-through} [-adlLmuvV] [+reset-access-time]\n\
- [+make-directories] [+link] [+preserve-modification-time]\n\
- [+unconditional] [+verbose] [+dereference] [+version]\n\
- destination-directory < name-list\n",
- program_name, program_name, program_name);
- exit (2);
- }
-
- /* Process the arguments. Set all options and set up the copy pass
- directory or the copy in patterns. */
-
- void
- process_args (argc, argv)
- int argc;
- char *argv[];
- {
- extern char *version_string;
- void (*copy_in) (); /* Work around for pcc bug. */
- void (*copy_out) ();
- int c;
- int longind;
-
- if (argc < 2)
- usage ();
-
- xstat = lstat;
-
- while ((c = getopt_long (argc, argv, "abBcdfilLmnoprtuvV", long_opts,
- &longind)) != EOF)
- {
- switch (c)
- {
- case 0: /* A long option that just sets a flag. */
- break;
-
- case 'a': /* Reset access times. */
- reset_time_flag = TRUE;
- break;
-
- case 'b': /* Use the nonportable format. */
- binary_flag = TRUE;
- break;
-
- case 'B': /* Set block size to 5120. */
- io_block_size = 5120;
- break;
-
- case 130: /* +block-size */
- io_block_size = atoi (optarg);
- if (io_block_size < 1)
- error (2, 0, "invalid block size");
- io_block_size *= 512;
- break;
-
- case 'c': /* Use the portable format. */
- portability_flag = TRUE;
- break;
-
- case 'd': /* Create directories where needed. */
- create_dir_flag = TRUE;
- break;
-
- case 'f': /* Only copy files not matching patterns. */
- copy_matching_files = FALSE;
- break;
-
- case 'i': /* Copy-in mode. */
- if (copy_function != 0)
- usage ();
- copy_function = process_copy_in;
- break;
-
- case 'l': /* Link files when possible. */
- link_flag = TRUE;
- break;
-
- case 'L': /* Dereference symbolic links. */
- xstat = stat;
- break;
-
- case 'm': /* Retain previous file modify times. */
- retain_time_flag = TRUE;
- break;
-
- case 'n': /* Long list owner and group as numbers. */
- numeric_uid = TRUE;
- break;
-
- case 'o': /* Copy-out mode. */
- if (copy_function != 0)
- usage ();
- copy_function = process_copy_out;
- break;
-
- case 'p': /* Copy-pass mode. */
- if (copy_function != 0)
- usage ();
- copy_function = process_copy_pass;
- break;
-
- case 'r': /* Interactively rename. */
- rename_flag = TRUE;
- break;
-
- case 't': /* Only print a list. */
- table_flag = TRUE;
- break;
-
- case 'u': /* Replace all! Unconditionally! */
- unconditional_flag = TRUE;
- break;
-
- case 'v': /* Verbose! */
- verbose_flag = TRUE;
- break;
-
- case 'V':
- printf ("%s", version_string);
- break;
-
- default:
- usage ();
- }
- }
-
- /* Do error checking and look at other args. */
-
- if (copy_function == 0)
- {
- if (table_flag)
- copy_function = process_copy_in;
- else
- usage ();
- }
-
- if ((!table_flag || !verbose_flag) && numeric_uid)
- usage ();
-
- /* Work around for pcc bug. */
- copy_in = process_copy_in;
- copy_out = process_copy_out;
-
- if (copy_function == copy_in)
- {
- if (link_flag || reset_time_flag || xstat != lstat
- || (binary_flag && portability_flag))
- usage ();
- if (!binary_flag && !portability_flag)
- binary_flag = portability_flag = TRUE;
- num_patterns = argc - optind;
- save_patterns = &argv[optind];
- }
- else if (copy_function == copy_out)
- {
- if (argc != optind || create_dir_flag || rename_flag
- || table_flag || unconditional_flag || link_flag
- || retain_time_flag || (binary_flag && portability_flag))
- usage ();
- }
- else
- {
- if (argc - 1 != optind || binary_flag || portability_flag
- || table_flag || rename_flag)
- usage ();
- directory_name = argv[optind];
- }
- }
-
- /* Initialize the input and output buffers to their proper size and
- initialize all variables associated with the input and output
- buffers. */
-
- void
- initialize_buffers ()
- {
- input_buffer = (char *) xmalloc (io_block_size);
- in_buff = input_buffer;
- input_size = 0;
- input_bytes = 0;
-
- /* Leave space for an `int' sentinel for `empty_output_buffer'. */
- output_buffer = (char *) xmalloc (io_block_size + sizeof (int) * 2);
- out_buff = output_buffer;
- output_size = 0;
- output_bytes = 0;
- }
-
- void
- main (argc, argv)
- int argc;
- char *argv[];
- {
- program_name = argv[0];
- umask (0);
-
- process_args (argc, argv);
-
- initialize_buffers ();
-
- (*copy_function) ();
-
- exit (0);
- }
-