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