1 /* $Source: /u/mark/src/pax/RCS/tar.c,v $
5 * tar.c - tar specific functions for archive handling
9 * These routines provide a tar conforming interface to the pax
14 * Mark H. Colburn, NAPS International (mark@jhereg.mn.org)
16 * Sponsored by The USENIX Association for public distribution.
18 * Copyright (c) 1989 Mark H. Colburn.
19 * All rights reserved.
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
28 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
29 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
30 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
33 * Revision 1.2 89/02/12 10:06:05 mark
36 * Revision 1.1 88/12/23 18:02:38 mark
42 static char *ident = "$Id: tar.c,v 1.2 89/02/12 10:06:05 mark Exp $";
43 static char *copyright ="Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.";
53 #define DEF_BLOCKING 20 /* default blocking factor for extract */
56 /* Function Prototypes */
60 static int taropt(int , char **, char *);
61 static void usage(void);
71 /* do_tar - main routine for tar.
75 * Provides a tar interface to the PAX program. All tar standard
76 * command line options are supported.
80 * int argc - argument count (argc from main)
81 * char **argv - argument list (argv from main)
90 int do_tar(int argc, char **argv)
94 int do_tar(argc, argv)
95 int argc; /* argument count (argc from main) */
96 char **argv; /* argument list (argv from main) */
100 int c; /* Option letter */
102 /* Set default option values */
103 names_from_stdin = 0;
104 ar_file = getenv("TAPE"); /* From environment, or */
106 ar_file = DEF_AR_FILE; /* From Makefile */
110 * set up the flags to reflect the default pax inteface. Unfortunately
111 * the pax interface has several options which are completely opposite
112 * of the tar and/or cpio interfaces...
123 while ((c = taropt(argc, argv, "b:cf:hlmortuvwx")) != EOF) {
125 case 'b': /* specify blocking factor */
127 * FIXME - we should use a conversion routine that does
128 * some kind of reasonable error checking, but...
130 blocking = atoi(optarg);
132 case 'c': /* create a new archive */
135 case 'f': /* specify input/output file */
139 f_follow_links = 1; /* follow symbolic links */
141 case 'l': /* report unresolved links */
144 case 'm': /* don't restore modification times */
147 case 'o': /* take on user's group rather than
150 case 'r': /* named files are appended to archive */
154 f_list = 1; /* list files in archive */
156 case 'u': /* named files are added to archive */
159 case 'v': /* verbose mode */
162 case 'w': /* user interactive mode */
165 case 'x': /* named files are extracted from archive */
174 /* check command line argument sanity */
175 if (f_create + f_extract + f_list + f_append + f_newer != 1) {
176 (void) fprintf(stderr,
177 "%s: you must specify exactly one of the c, t, r, u or x options\n",
183 /* set the blocking factor, if not set by the user */
186 if (f_extract || f_list) {
187 blocking = DEF_BLOCKING;
188 fprintf(stderr, "Tar: blocksize = %d\n", blocking);
196 blocksize = blocking * BLOCKSIZE;
197 buf_allocate((OFFSET) blocksize);
200 open_archive(AR_WRITE);
201 create_archive(); /* create the archive */
202 } else if (f_extract) {
203 open_archive(AR_READ);
204 read_archive(); /* extract files from archive */
206 open_archive(AR_READ);
207 read_archive(); /* read and list contents of archive */
208 } else if (f_append) {
209 open_archive(AR_APPEND);
210 append_archive(); /* append files to archive */
214 linkleft(); /* report any unresolved links */
221 /* taropt - tar specific getopt
225 * Plug-compatible replacement for getopt() for parsing tar-like
226 * arguments. If the first argument begins with "-", it uses getopt;
227 * otherwise, it uses the old rules used by tar, dump, and ps.
231 * int argc - argument count (argc from main)
232 * char **argv - argument list (argv from main)
233 * char *optstring - sring which describes allowable options
237 * Returns the next option character in the option string(s). If the
238 * option requires an argument and an argument was given, the argument
239 * is pointed to by "optarg". If no option character was found,
246 static int taropt(int argc, char **argv, char *optstring)
250 static int taropt(argc, argv, optstring)
257 extern char *optarg; /* Points to next arg */
258 extern int optind; /* Global argv index */
259 static char *key; /* Points to next keyletter */
260 static char use_getopt; /* !=0 if argv[1][0] was '-' */
264 optarg = (char *)NULL;
266 if (key == (char *)NULL) { /* First time */
276 return getopt(argc, argv, optstring);
284 place = strchr(optstring, c);
286 if (place == (char *)NULL || c == ':') {
287 fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
293 optarg = argv[optind];
296 fprintf(stderr, "%s: %c argument missing\n",
305 /* usage - print a helpful message and exit
309 * Usage prints out the usage message for the TAR interface and then
310 * exits with a non-zero termination status. This is used when a user
311 * has provided non-existant or incompatible command line arguments.
315 * Returns an exit status of 1 to the parent process.
321 static void usage(void)
329 fprintf(stderr, "Usage: %s -c[bfvw] device block filename..\n", myname);
330 fprintf(stderr, " %s -r[bvw] device block [filename...]\n", myname);
331 fprintf(stderr, " %s -t[vf] device\n", myname);
332 fprintf(stderr, " %s -u[bvw] device block [filename...]\n", myname);
333 fprintf(stderr, " %s -x[flmovw] device [filename...]\n", myname);