Annotation of src/usr.bin/ar/ar.c, Revision 1.2
1.2 ! deraadt 1: /* $OpenBSD: ar.c,v 1.5 1995/03/26 03:27:44 glass Exp $ */
1.1 deraadt 2: /* $NetBSD: ar.c,v 1.5 1995/03/26 03:27:44 glass Exp $ */
3:
4: /*-
5: * Copyright (c) 1990, 1993, 1994
6: * The Regents of the University of California. All rights reserved.
7: *
8: * This code is derived from software contributed to Berkeley by
9: * Hugh Smith at The University of Guelph.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the University of
22: * California, Berkeley and its contributors.
23: * 4. Neither the name of the University nor the names of its contributors
24: * may be used to endorse or promote products derived from this software
25: * without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37: * SUCH DAMAGE.
38: */
39:
40: #ifndef lint
41: static char copyright[] =
42: "@(#) Copyright (c) 1990, 1993, 1994\n\
43: The Regents of the University of California. All rights reserved.\n";
44: #endif /* not lint */
45:
46: #ifndef lint
47: #if 0
48: static char sccsid[] = "@(#)ar.c 8.3 (Berkeley) 4/2/94";
49: #else
1.2 ! deraadt 50: static char rcsid[] = "$OpenBSD: ar.c,v 1.5 1995/03/26 03:27:44 glass Exp $";
1.1 deraadt 51: #endif
52: #endif /* not lint */
53:
54: #include <sys/param.h>
55:
56: #include <ar.h>
57: #include <dirent.h>
58: #include <err.h>
59: #include <paths.h>
60: #include <stdio.h>
61: #include <stdlib.h>
62: #include <string.h>
63: #include <unistd.h>
64:
65: #include "archive.h"
66: #include "extern.h"
67:
68: CHDR chdr;
69: u_int options;
70: char *archive, *envtmp, *posarg, *posname;
71: static void badoptions __P((char *));
72: static void usage __P((void));
73:
74: /*
75: * main --
76: * main basically uses getopt to parse options and calls the appropriate
77: * functions. Some hacks that let us be backward compatible with 4.3 ar
78: * option parsing and sanity checking.
79: */
80: int
81: main(argc, argv)
82: int argc;
83: char **argv;
84: {
85: int c;
86: char *p;
87: int (*fcall) __P((char **));
88:
89: if (argc < 3)
90: usage();
91:
92: /*
93: * Historic versions didn't require a '-' in front of the options.
94: * Fix it, if necessary.
95: */
96: if (*argv[1] != '-') {
97: if (!(p = malloc((u_int)(strlen(argv[1]) + 2))))
98: err(1, NULL);
99: *p = '-';
100: (void)strcpy(p + 1, argv[1]);
101: argv[1] = p;
102: }
103:
104: while ((c = getopt(argc, argv, "abcdilmopqrTtuvx")) != EOF) {
105: switch(c) {
106: case 'a':
107: options |= AR_A;
108: break;
109: case 'b':
110: case 'i':
111: options |= AR_B;
112: break;
113: case 'c':
114: options |= AR_C;
115: break;
116: case 'd':
117: options |= AR_D;
118: fcall = delete;
119: break;
120: case 'l': /* not documented, compatibility only */
121: envtmp = ".";
122: break;
123: case 'm':
124: options |= AR_M;
125: fcall = move;
126: break;
127: case 'o':
128: options |= AR_O;
129: break;
130: case 'p':
131: options |= AR_P;
132: fcall = print;
133: break;
134: case 'q':
135: options |= AR_Q;
136: fcall = append;
137: break;
138: case 'r':
139: options |= AR_R;
140: fcall = replace;
141: break;
142: case 'T':
143: options |= AR_TR;
144: break;
145: case 't':
146: options |= AR_T;
147: fcall = contents;
148: break;
149: case 'u':
150: options |= AR_U;
151: break;
152: case 'v':
153: options |= AR_V;
154: break;
155: case 'x':
156: options |= AR_X;
157: fcall = extract;
158: break;
159: default:
160: usage();
161: }
162: }
163:
164: argv += optind;
165: argc -= optind;
166:
167: /* One of -dmpqrtx required. */
168: if (!(options & (AR_D|AR_M|AR_P|AR_Q|AR_R|AR_T|AR_X))) {
169: warnx("one of options -dmpqrtx is required");
170: usage();
171: }
172: /* Only one of -a and -bi allowed. */
173: if (options & AR_A && options & AR_B) {
174: warnx("only one of -a and -[bi] options allowed");
175: usage();
176: }
177: /* -ab require a position argument. */
178: if (options & (AR_A|AR_B)) {
179: if (!(posarg = *argv++)) {
180: warnx("no position operand specified");
181: usage();
182: }
183: posname = rname(posarg);
184: }
185: /* -d only valid with -Tv. */
186: if (options & AR_D && options & ~(AR_D|AR_TR|AR_V))
187: badoptions("-d");
188: /* -m only valid with -abiTv. */
189: if (options & AR_M && options & ~(AR_A|AR_B|AR_M|AR_TR|AR_V))
190: badoptions("-m");
191: /* -p only valid with -Tv. */
192: if (options & AR_P && options & ~(AR_P|AR_TR|AR_V))
193: badoptions("-p");
194: /* -q only valid with -cTv. */
195: if (options & AR_Q && options & ~(AR_C|AR_Q|AR_TR|AR_V))
196: badoptions("-q");
197: /* -r only valid with -abcuTv. */
198: if (options & AR_R && options & ~(AR_A|AR_B|AR_C|AR_R|AR_U|AR_TR|AR_V))
199: badoptions("-r");
200: /* -t only valid with -Tv. */
201: if (options & AR_T && options & ~(AR_T|AR_TR|AR_V))
202: badoptions("-t");
203: /* -x only valid with -ouTv. */
204: if (options & AR_X && options & ~(AR_O|AR_U|AR_TR|AR_V|AR_X))
205: badoptions("-x");
206:
207: if (!(archive = *argv++)) {
208: warnx("no archive specified");
209: usage();
210: }
211:
212: /* -dmqr require a list of archive elements. */
213: if (options & (AR_D|AR_M|AR_Q|AR_R) && !*argv) {
214: warnx("no archive members specified");
215: usage();
216: }
217:
218: exit((*fcall)(argv));
219: }
220:
221: static void
222: badoptions(arg)
223: char *arg;
224: {
225:
226: warnx("illegal option combination for %s", arg);
227: usage();
228: }
229:
230: static void
231: usage()
232: {
233:
234: (void)fprintf(stderr, "usage: ar -d [-Tv] archive file ...\n");
235: (void)fprintf(stderr, "\tar -m [-Tv] archive file ...\n");
236: (void)fprintf(stderr, "\tar -m [-abiTv] position archive file ...\n");
237: (void)fprintf(stderr, "\tar -p [-Tv] archive [file ...]\n");
238: (void)fprintf(stderr, "\tar -q [-cTv] archive file ...\n");
239: (void)fprintf(stderr, "\tar -r [-cuTv] archive file ...\n");
240: (void)fprintf(stderr, "\tar -r [-abciuTv] position archive file ...\n");
241: (void)fprintf(stderr, "\tar -t [-Tv] archive [file ...]\n");
242: (void)fprintf(stderr, "\tar -x [-ouTv] archive [file ...]\n");
243: exit(1);
244: }