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