Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* $Source: /u/mark/src/pax/RCS/tar.c,v $
2
 *
3
 * $Revision: 1.2 $
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 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
31
 *
32
 * $Log:	tar.c,v $
33
 * Revision 1.2  89/02/12  10:06:05  mark
34
 * 1.2 release fixes
35
 * 
36
 * Revision 1.1  88/12/23  18:02:38  mark
37
 * Initial revision
38
 * 
39
 */
40
 
41
#ifndef lint
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.";
44
#endif /* not lint */
45
 
46
/* Headers */
47
 
48
#include "pax.h"
49
 
50
 
51
/* Defines */
52
 
53
#define DEF_BLOCKING	20	/* default blocking factor for extract */
54
 
55
 
56
/* Function Prototypes */
57
 
58
#ifdef __STDC__
59
 
60
static int taropt(int , char **, char *);
61
static void usage(void);
62
 
63
#else /* !__STDC__ */
64
 
65
static int taropt();
66
static void usage();
67
 
68
#endif /* __STDC__ */
69
 
70
 
71
/* do_tar - main routine for tar. 
72
 *
73
 * DESCRIPTION
74
 *
75
 *	Provides a tar interface to the PAX program.  All tar standard
76
 *	command line options are supported.
77
 *
78
 * PARAMETERS
79
 *
80
 *	int argc	- argument count (argc from main) 
81
 *	char **argv	- argument list (argv from main) 
82
 *
83
 * RETURNS
84
 *
85
 *	zero
86
 */
87
 
88
#ifdef __STDC__
89
 
90
int do_tar(int argc, char **argv)
91
 
92
#else
93
 
94
int do_tar(argc, argv)
95
int             argc;		/* argument count (argc from main) */
96
char          **argv;		/* argument list (argv from main) */
97
 
98
#endif
99
{
100
    int             c;		/* Option letter */
101
 
102
    /* Set default option values */
103
    names_from_stdin = 0;
104
    ar_file = getenv("TAPE");	/* From environment, or */
105
    if (ar_file == 0) {
106
	ar_file = DEF_AR_FILE;	/* From Makefile */
107
    }
108
 
109
    /*
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...
113
     */
114
    f_unconditional = 1;
115
    f_mtime = 1;
116
    f_dir_create = 1;
117
    blocking = 0;
118
    ar_interface = TAR;
119
    ar_format = TAR;
120
    msgfile=stderr;
121
 
122
    /* Parse options */
123
    while ((c = taropt(argc, argv, "b:cf:hlmortuvwx")) != EOF) {
124
	switch (c) {
125
	case 'b':		/* specify blocking factor */
126
	    /* 
127
	     * FIXME - we should use a conversion routine that does
128
	     * some kind of reasonable error checking, but...
129
	     */
130
	    blocking = atoi(optarg);
131
	    break;
132
	case 'c':		/* create a new archive */
133
	    f_create = 1;
134
	    break;
135
	case 'f':		/* specify input/output file */
136
	    ar_file = optarg;
137
	    break;
138
	case 'h':
139
	    f_follow_links = 1;	/* follow symbolic links */
140
	    break;
141
	case 'l':		/* report unresolved links */
142
	    f_linksleft = 1;
143
	    break;
144
	case 'm':		/* don't restore modification times */
145
	    f_modified = 1;
146
	    break;
147
	case 'o':		/* take on user's group rather than
148
				 * archives */
149
	    break;
150
	case 'r':		/* named files are appended to archive */
151
	    f_append = 1;
152
	    break;
153
	case 't':
154
	    f_list = 1;		/* list files in archive */
155
	    break;
156
	case 'u':		/* named files are added to archive */
157
	    f_newer = 1;
158
	    break;
159
	case 'v':		/* verbose mode */
160
	    f_verbose = 1;
161
	    break;
162
	case 'w':		/* user interactive mode */
163
	    f_disposition = 1;
164
	    break;
165
	case 'x':		/* named files are extracted from archive */
166
	    f_extract = 1;
167
	    break;
168
	case '?':
169
	    usage();
170
	    exit(EX_ARGSBAD);
171
	}
172
    }
173
 
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",
178
		       myname);
179
	usage();
180
	exit(EX_ARGSBAD);
181
    }
182
 
183
    /* set the blocking factor, if not set by the user */
184
    if (blocking == 0) {
185
#ifdef USG
186
	if (f_extract || f_list) {
187
	    blocking = DEF_BLOCKING;
188
	    fprintf(stderr, "Tar: blocksize = %d\n", blocking);
189
	} else {
190
	    blocking = 1;
191
	}
192
#else /* !USG */
193
	blocking = 20;
194
#endif /* USG */
195
    }
196
    blocksize = blocking * BLOCKSIZE;
197
    buf_allocate((OFFSET) blocksize);
198
 
199
    if (f_create) {
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 */
205
    } else if (f_list) {
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 */
211
    }
212
 
213
    if (f_linksleft) {		
214
	linkleft(); 		/* report any unresolved links */ 
215
    }
216
 
217
    return (0);
218
}
219
 
220
 
221
/* taropt -  tar specific getopt
222
 *
223
 * DESCRIPTION
224
 *
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.
228
 *
229
 * PARAMETERS
230
 *
231
 *	int argc	- argument count (argc from main) 
232
 *	char **argv	- argument list (argv from main) 
233
 *	char *optstring	- sring which describes allowable options
234
 *
235
 * RETURNS
236
 *
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,
240
 *	returns an EOF.
241
 *
242
 */
243
 
244
#ifdef __STDC__
245
 
246
static int taropt(int argc, char **argv, char *optstring)
247
 
248
#else
249
 
250
static int taropt(argc, argv, optstring)
251
int             argc;
252
char          **argv;
253
char           *optstring;
254
 
255
#endif
256
{
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 '-' */
261
    char            c;
262
    char           *place;
263
 
264
    optarg = (char *)NULL;
265
 
266
    if (key == (char *)NULL) {		/* First time */
267
	if (argc < 2)
268
	    return EOF;
269
	key = argv[1];
270
	if (*key == '-')
271
	    use_getopt++;
272
	else
273
	    optind = 2;
274
    }
275
    if (use_getopt) {
276
	return getopt(argc, argv, optstring);
277
    }
278
 
279
    c = *key++;
280
    if (c == '\0') {
281
	key--;
282
	return EOF;
283
    }
284
    place = strchr(optstring, c);
285
 
286
    if (place == (char *)NULL || c == ':') {
287
	fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
288
	return ('?');
289
    }
290
    place++;
291
    if (*place == ':') {
292
	if (optind < argc) {
293
	    optarg = argv[optind];
294
	    optind++;
295
	} else {
296
	    fprintf(stderr, "%s: %c argument missing\n",
297
		    argv[0], c);
298
	    return ('?');
299
	}
300
    }
301
    return (c);
302
}
303
 
304
 
305
/* usage - print a helpful message and exit
306
 *
307
 * DESCRIPTION
308
 *
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.
312
 *
313
 * RETURNS
314
 *
315
 *	Returns an exit status of 1 to the parent process.
316
 *
317
 */
318
 
319
#ifdef __STDC__
320
 
321
static void usage(void)
322
 
323
#else
324
 
325
static void usage()
326
 
327
#endif
328
{
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);
334
    exit(1);
335
}