home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / std_unix / pax / 3 / tar.c < prev   
Encoding:
C/C++ Source or Header  |  1989-01-07  |  7.7 KB  |  338 lines

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