123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- /* $Source: /u/mark/src/pax/RCS/tar.c,v $
- *
- * $Revision: 1.2 $
- *
- * tar.c - tar specific functions for archive handling
- *
- * DESCRIPTION
- *
- * These routines provide a tar conforming interface to the pax
- * program.
- *
- * AUTHOR
- *
- * Mark H. Colburn, NAPS International (mark@jhereg.mn.org)
- *
- * Sponsored by The USENIX Association for public distribution.
- *
- * Copyright (c) 1989 Mark H. Colburn.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice is duplicated in all such
- * forms and that any documentation, advertising materials, and other
- * materials related to such distribution and use acknowledge that the
- * software was developed by Mark H. Colburn and sponsored by The
- * USENIX Association.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Log: tar.c,v $
- * Revision 1.2 89/02/12 10:06:05 mark
- * 1.2 release fixes
- *
- * Revision 1.1 88/12/23 18:02:38 mark
- * Initial revision
- *
- */
- #ifndef lint
- static char *ident = "$Id: tar.c,v 1.2 89/02/12 10:06:05 mark Exp $";
- static char *copyright ="Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.";
- #endif /* not lint */
- /* Headers */
- #include "pax.h"
- /* Defines */
- #define DEF_BLOCKING 20 /* default blocking factor for extract */
- /* Function Prototypes */
- #ifdef __STDC__
- static int taropt(int , char **, char *);
- static void usage(void);
- #else /* !__STDC__ */
- static int taropt();
- static void usage();
- #endif /* __STDC__ */
- /* do_tar - main routine for tar.
- *
- * DESCRIPTION
- *
- * Provides a tar interface to the PAX program. All tar standard
- * command line options are supported.
- *
- * PARAMETERS
- *
- * int argc - argument count (argc from main)
- * char **argv - argument list (argv from main)
- *
- * RETURNS
- *
- * zero
- */
- #ifdef __STDC__
- int do_tar(int argc, char **argv)
- #else
- int do_tar(argc, argv)
- int argc; /* argument count (argc from main) */
- char **argv; /* argument list (argv from main) */
- #endif
- {
- int c; /* Option letter */
- /* Set default option values */
- names_from_stdin = 0;
- ar_file = getenv("TAPE"); /* From environment, or */
- if (ar_file == 0) {
- ar_file = DEF_AR_FILE; /* From Makefile */
- }
- /*
- * set up the flags to reflect the default pax inteface. Unfortunately
- * the pax interface has several options which are completely opposite
- * of the tar and/or cpio interfaces...
- */
- f_unconditional = 1;
- f_mtime = 1;
- f_dir_create = 1;
- blocking = 0;
- ar_interface = TAR;
- ar_format = TAR;
- msgfile=stderr;
- /* Parse options */
- while ((c = taropt(argc, argv, "b:cf:hlmortuvwx")) != EOF) {
- switch (c) {
- case 'b': /* specify blocking factor */
- /*
- * FIXME - we should use a conversion routine that does
- * some kind of reasonable error checking, but...
- */
- blocking = atoi(optarg);
- break;
- case 'c': /* create a new archive */
- f_create = 1;
- break;
- case 'f': /* specify input/output file */
- ar_file = optarg;
- break;
- case 'h':
- f_follow_links = 1; /* follow symbolic links */
- break;
- case 'l': /* report unresolved links */
- f_linksleft = 1;
- break;
- case 'm': /* don't restore modification times */
- f_modified = 1;
- break;
- case 'o': /* take on user's group rather than
- * archives */
- break;
- case 'r': /* named files are appended to archive */
- f_append = 1;
- break;
- case 't':
- f_list = 1; /* list files in archive */
- break;
- case 'u': /* named files are added to archive */
- f_newer = 1;
- break;
- case 'v': /* verbose mode */
- f_verbose = 1;
- break;
- case 'w': /* user interactive mode */
- f_disposition = 1;
- break;
- case 'x': /* named files are extracted from archive */
- f_extract = 1;
- break;
- case '?':
- usage();
- exit(EX_ARGSBAD);
- }
- }
- /* check command line argument sanity */
- if (f_create + f_extract + f_list + f_append + f_newer != 1) {
- (void) fprintf(stderr,
- "%s: you must specify exactly one of the c, t, r, u or x options\n",
- myname);
- usage();
- exit(EX_ARGSBAD);
- }
- /* set the blocking factor, if not set by the user */
- if (blocking == 0) {
- #ifdef USG
- if (f_extract || f_list) {
- blocking = DEF_BLOCKING;
- fprintf(stderr, "Tar: blocksize = %d\n", blocking);
- } else {
- blocking = 1;
- }
- #else /* !USG */
- blocking = 20;
- #endif /* USG */
- }
- blocksize = blocking * BLOCKSIZE;
- buf_allocate((OFFSET) blocksize);
- if (f_create) {
- open_archive(AR_WRITE);
- create_archive(); /* create the archive */
- } else if (f_extract) {
- open_archive(AR_READ);
- read_archive(); /* extract files from archive */
- } else if (f_list) {
- open_archive(AR_READ);
- read_archive(); /* read and list contents of archive */
- } else if (f_append) {
- open_archive(AR_APPEND);
- append_archive(); /* append files to archive */
- }
-
- if (f_linksleft) {
- linkleft(); /* report any unresolved links */
- }
-
- return (0);
- }
- /* taropt - tar specific getopt
- *
- * DESCRIPTION
- *
- * Plug-compatible replacement for getopt() for parsing tar-like
- * arguments. If the first argument begins with "-", it uses getopt;
- * otherwise, it uses the old rules used by tar, dump, and ps.
- *
- * PARAMETERS
- *
- * int argc - argument count (argc from main)
- * char **argv - argument list (argv from main)
- * char *optstring - sring which describes allowable options
- *
- * RETURNS
- *
- * Returns the next option character in the option string(s). If the
- * option requires an argument and an argument was given, the argument
- * is pointed to by "optarg". If no option character was found,
- * returns an EOF.
- *
- */
- #ifdef __STDC__
- static int taropt(int argc, char **argv, char *optstring)
- #else
- static int taropt(argc, argv, optstring)
- int argc;
- char **argv;
- char *optstring;
- #endif
- {
- extern char *optarg; /* Points to next arg */
- extern int optind; /* Global argv index */
- static char *key; /* Points to next keyletter */
- static char use_getopt; /* !=0 if argv[1][0] was '-' */
- char c;
- char *place;
- optarg = (char *)NULL;
- if (key == (char *)NULL) { /* First time */
- if (argc < 2)
- return EOF;
- key = argv[1];
- if (*key == '-')
- use_getopt++;
- else
- optind = 2;
- }
- if (use_getopt) {
- return getopt(argc, argv, optstring);
- }
- c = *key++;
- if (c == '\0') {
- key--;
- return EOF;
- }
- place = strchr(optstring, c);
- if (place == (char *)NULL || c == ':') {
- fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
- return ('?');
- }
- place++;
- if (*place == ':') {
- if (optind < argc) {
- optarg = argv[optind];
- optind++;
- } else {
- fprintf(stderr, "%s: %c argument missing\n",
- argv[0], c);
- return ('?');
- }
- }
- return (c);
- }
- /* usage - print a helpful message and exit
- *
- * DESCRIPTION
- *
- * Usage prints out the usage message for the TAR interface and then
- * exits with a non-zero termination status. This is used when a user
- * has provided non-existant or incompatible command line arguments.
- *
- * RETURNS
- *
- * Returns an exit status of 1 to the parent process.
- *
- */
- #ifdef __STDC__
- static void usage(void)
- #else
- static void usage()
- #endif
- {
- fprintf(stderr, "Usage: %s -c[bfvw] device block filename..\n", myname);
- fprintf(stderr, " %s -r[bvw] device block [filename...]\n", myname);
- fprintf(stderr, " %s -t[vf] device\n", myname);
- fprintf(stderr, " %s -u[bvw] device block [filename...]\n", myname);
- fprintf(stderr, " %s -x[flmovw] device [filename...]\n", myname);
- exit(1);
- }
|