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 >
Wrap
C/C++ Source or Header
|
1992-02-22
|
8KB
|
299 lines
/* 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);
}