home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / PAX20.ZIP / TAR.C < prev    next >
C/C++ Source or Header  |  1990-11-12  |  10KB  |  380 lines

  1. /* $Source: /u/mark/src/pax/RCS/tar.c,v $
  2.  *
  3.  * $Revision: 2.0.0.4 $
  4.  *
  5.  * tar.c - tar specific functions for archive handling
  6.  *
  7.  * DESCRIPTION
  8.  *
  9.  *    These routines provide a tar conforming interface to the pax
  10.  *    program.
  11.  *
  12.  * AUTHOR
  13.  *
  14.  *    Mark H. Colburn, Open Systems Architects, Inc. (mark@minnetech.mn.org)
  15.  *
  16.  * COPYRIGHT
  17.  *
  18.  *    Copyright (c) 1989 Mark H. Colburn.  All rights reserved.
  19.  *
  20.  *    Redistribution and use in source and binary forms are permitted
  21.  *    provided that the above copyright notice and this paragraph are
  22.  *    duplicated in all such forms and that any documentation,
  23.  *    advertising materials, and other materials related to such
  24.  *    distribution and use acknowledge that the software was developed
  25.  *    by Mark H. Colburn.
  26.  *
  27.  *    THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  28.  *    IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  29.  *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  30.  *
  31.  * $Log:    tar.c,v $
  32.  * Revision 2.0.0.4  89/10/13  02:35:57  mark
  33.  * Beta Test Freeze
  34.  *
  35.  */
  36.  
  37. #ifndef lint
  38. static char        *ident = "$Id: tar.c,v 2.0.0.4 89/10/13 02:35:57 mark Exp Locker: mark $";
  39. static char        *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.";
  40. #endif /* not lint */
  41.  
  42. /* Headers */
  43.  
  44. #include "pax.h"
  45.  
  46.  
  47. /* Defines */
  48.  
  49. #define DEF_BLOCKING    20    /* default blocking factor for extract */
  50.  
  51.  
  52. /* Function Prototypes */
  53.  
  54. #ifdef __STDC__
  55.  
  56. static int        taropt(int, char **, char *);
  57. static void         usage(void);
  58.  
  59. #else /* !__STDC__ */
  60.  
  61. static int          taropt();
  62. static void         usage();
  63.  
  64. #endif /* __STDC__ */
  65.  
  66.  
  67. /* do_tar - main routine for tar.
  68.  *
  69.  * DESCRIPTION
  70.  *
  71.  *    Provides a tar interface to the PAX program.  All tar standard
  72.  *    command line options are supported.
  73.  *
  74.  * PARAMETERS
  75.  *
  76.  *    int argc    - argument count (argc from main)
  77.  *    char **argv    - argument list (argv from main)
  78.  *
  79.  * RETURNS
  80.  *
  81.  *    zero
  82.  */
  83.  
  84. #ifdef __STDC__
  85.  
  86. int
  87. do_tar(int argc, char **argv)
  88.  
  89. #else
  90.  
  91. int
  92. do_tar(argc, argv)
  93.     int                 argc;    /* argument count (argc from main) */
  94.     char              **argv;    /* argument list (argv from main) */
  95.  
  96. #endif
  97. {
  98.     int                 c;    /* Option letter */
  99.  
  100.     DBUG_ENTER("do_tar");
  101.     /* Set default option values */
  102.     names_from_stdin = 0;
  103.     ar_file = getenv("TAPE");    /* From environment, or */
  104.     if (ar_file == NULL) {    /* from Makefile */
  105.     ar_file = DEF_TAR_FILE;
  106.     }
  107.     /*
  108.      * set up the flags to reflect the default pax inteface.  Unfortunately
  109.      * the pax interface has several options which are completely opposite of
  110.      * the tar and/or cpio interfaces...
  111.      */
  112.     f_unconditional = 1;
  113.     f_mtime = 1;
  114.     f_dir_create = 1;
  115.     blocking = 0;
  116.     ar_interface = TAR;
  117.     ar_format = TAR;
  118.     msgfile = stderr;
  119.  
  120.     /* Parse options */
  121.     while ((c = taropt(argc, argv, "#:b:cf:hlmortuvwx")) != EOF) {
  122.     switch (c) {
  123.  
  124.     case '#':
  125.         DBUG_PUSH(optarg);
  126.         break;
  127.  
  128.     case 'b':        /* specify blocking factor */
  129.         /*
  130.          * FIXME - we should use a conversion routine that does some kind
  131.          * of reasonable error checking, but...
  132.          */
  133.         blocking = atoi(optarg);
  134.         break;
  135.  
  136.     case 'c':        /* create a new archive */
  137.         f_create = 1;
  138.         break;
  139.  
  140.     case 'f':        /* specify input/output file */
  141.         ar_file = optarg;
  142.         break;
  143.  
  144.     case 'h':
  145.         f_follow_links = 1;    /* follow symbolic links */
  146.         break;
  147.  
  148.     case 'l':        /* report unresolved links */
  149.         f_unresolved = 1;
  150.         break;
  151.  
  152.     case 'm':        /* don't restore modification times */
  153.         f_modified = 1;
  154.         break;
  155.  
  156.     case 'o':        /* take on user's group rather than archives */
  157.         break;
  158.  
  159.     case 'r':        /* named files are appended to archive */
  160.         f_append = 1;
  161.         break;
  162.  
  163.     case 't':
  164.         f_list = 1;        /* list files in archive */
  165.         break;
  166.  
  167.     case 'u':        /* named files are added to archive */
  168.         f_newer = 1;
  169.         break;
  170.  
  171.     case 'v':        /* verbose mode */
  172.         f_verbose = 1;
  173.         break;
  174.  
  175.     case 'w':        /* user interactive mode */
  176.         f_disposition = 1;
  177.         break;
  178.  
  179.     case 'x':        /* named files are extracted from archive */
  180.         f_extract = 1;
  181.         break;
  182.  
  183.     case '?':
  184.         usage();
  185.         exit(EX_ARGSBAD);
  186.     }
  187.     }
  188.  
  189. #ifdef MSDOS
  190.     setmode(fileno(msgfile), O_TEXT);
  191.     if (names_from_stdin) {
  192.         setmode(fileno(stdin), O_TEXT);
  193.     }
  194. #endif /* MSDOS */
  195.  
  196.     /* check command line argument sanity */
  197.     if (f_create + f_extract + f_list + f_append + f_newer != 1) {
  198. #ifdef MSDOS
  199.         printf(
  200.         "\r\n%s: you must specify exactly one of the c, t, r, u or x options\r\n",
  201.                        myname);
  202. #else
  203.     (void) fprintf(stderr,
  204.     "%s: you must specify exactly one of the c, t, r, u or x options\n",
  205.                        myname);
  206. #endif
  207.     usage();
  208.     exit(EX_ARGSBAD);
  209.     }
  210.     /* set the blocking factor, if not set by the user */
  211.     if (blocking == 0) {
  212.     if (f_extract || f_list) {
  213.         blocking = DEF_BLOCKING;
  214.         fprintf(stderr, "Tar: blocksize = %d\n", blocking);
  215.     } else {
  216.         blocking = 1;
  217.     }
  218.     }
  219.     blocksize = blocking * BLOCKSIZE;
  220.     buf_allocate((OFFSET) blocksize);
  221.  
  222.     if (f_create) {
  223.     open_archive(AR_WRITE);
  224.     create_archive();    /* create the archive */
  225.     } else if (f_extract) {
  226.     open_archive(AR_READ);
  227.     read_archive();        /* extract files from archive */
  228.     } else if (f_list) {
  229.     open_archive(AR_READ);
  230.     read_archive();        /* read and list contents of archive */
  231.     } else if (f_append) {
  232.     open_archive(AR_APPEND);
  233.     append_archive();    /* append files to archive */
  234.     }
  235.     if (f_unresolved) {
  236.     linkleft();        /* report any unresolved links */
  237.     }
  238.     DBUG_RETURN(0);
  239. }
  240.  
  241.  
  242. /* taropt -  tar specific getopt
  243.  *
  244.  * DESCRIPTION
  245.  *
  246.  *     Plug-compatible replacement for getopt() for parsing tar-like
  247.  *     arguments.  If the first argument begins with "-", it uses getopt;
  248.  *     otherwise, it uses the old rules used by tar, dump, and ps.
  249.  *
  250.  * PARAMETERS
  251.  *
  252.  *    int argc    - argument count (argc from main)
  253.  *    char **argv    - argument list (argv from main)
  254.  *    char *optstring    - sring which describes allowable options
  255.  *
  256.  * RETURNS
  257.  *
  258.  *    Returns the next option character in the option string(s).  If the
  259.  *    option requires an argument and an argument was given, the argument
  260.  *    is pointed to by "optarg".  If no option character was found,
  261.  *    returns an EOF.
  262.  *
  263.  */
  264. #ifdef __STDC__
  265.  
  266. static int
  267. taropt(int argc, char **argv, char *optstring)
  268.  
  269. #else
  270.  
  271. static int
  272. taropt(argc, argv, optstring)
  273.     int                 argc;    /* argument count from cmd line */
  274.     char              **argv;    /* argument vector from cmd line */
  275.     char               *optstring;    /* option string ala getopt */
  276.  
  277. #endif
  278. {
  279.     extern char        *optarg;    /* Points to next arg */
  280.     extern int          optind;    /* Global argv index */
  281.     static char        *key;    /* Points to next keyletter */
  282.     static char         use_getopt;    /* !=0 if argv[1][0] was '-' */
  283.     char                c;
  284.     char               *place;
  285.  
  286.     DBUG_ENTER("taropt");
  287.     optarg = (char *) NULL;
  288.  
  289.     if (key == (char *) NULL) {    /* First time */
  290.     if (argc < 2) {
  291.         DBUG_RETURN(EOF);
  292.     }
  293.     key = argv[1];
  294.     if (*key == '-') {
  295.         use_getopt++;
  296.     } else {
  297.         optind = 2;
  298.     }
  299.  
  300.     }
  301.     if (use_getopt) {
  302.     DBUG_RETURN(getopt(argc, argv, optstring));
  303.     }
  304.     c = *key++;
  305.     if (c == '\0') {
  306.     key--;
  307.     DBUG_RETURN(EOF);
  308.     }
  309.     place = index(optstring, c);
  310.  
  311.     if (place == (char *) NULL || c == ':') {
  312.     fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
  313.     DBUG_RETURN('?');
  314.     }
  315.     place++;
  316.     if (*place == ':') {
  317.     if (optind < argc) {
  318.         optarg = argv[optind];
  319.         optind++;
  320.     } else {
  321.         fprintf(stderr, "%s: %c argument missing\n", argv[0], c);
  322.         DBUG_RETURN('?');
  323.     }
  324.     }
  325.     DBUG_RETURN(c);
  326. }
  327.  
  328.  
  329. /* usage - print a helpful message and exit
  330.  *
  331.  * DESCRIPTION
  332.  *
  333.  *    Usage prints out the usage message for the TAR interface and then
  334.  *    exits with a non-zero termination status.  This is used when a user
  335.  *    has provided non-existant or incompatible command line arguments.
  336.  *
  337.  * RETURNS
  338.  *
  339.  *    Returns an exit status of 1 to the parent process.
  340.  *
  341.  */
  342.  
  343. #ifdef __STDC__
  344.  
  345. static void
  346. usage(void)
  347.  
  348. #else
  349.  
  350. static void
  351. usage()
  352.  
  353. #endif
  354. {
  355.     DBUG_ENTER("usage");
  356. #ifdef MSDOS
  357.     printf("\r\nPAX version 2.0 - POSIX conforming tar and cpio archiver for DOS and OS/2\r\n");
  358.  
  359.     printf("\r\nUsage: %s -c[bfvw] device block filename..\r\n", myname);
  360.     printf("       %s -r[bvw] device block [filename...]\r\n", myname);
  361.     printf("       %s -t[vf] device\r\n", myname);
  362.     printf("       %s -u[bvw] device block [filename...]\r\n", myname);
  363.     printf("       %s -x[flmovw] device [filename...]\r\n", myname);
  364.  
  365.     printf("\r\nRename TAR.EXE to PAX.EXE or CPIO.EXE to get the PAX or CPIO user interface.\r\n");
  366.  
  367. #ifdef DISKACC
  368.     printf("\r\nUse the option f with the special device names 0: and 1: to access Unix floppy"
  369.            "\r\ndisks with tar archives. The disk type is automatically detected.\r\n");
  370. #endif
  371. #else
  372.     fprintf(stderr, "Usage: %s -c[bfvw] device block filename..\n", myname);
  373.     fprintf(stderr, "       %s -r[bvw] device block [filename...]\n", myname);
  374.     fprintf(stderr, "       %s -t[vf] device\n", myname);
  375.     fprintf(stderr, "       %s -u[bvw] device block [filename...]\n", myname);
  376.     fprintf(stderr, "       %s -x[flmovw] device [filename...]\n", myname);
  377. #endif
  378.     exit(1);
  379. }
  380.