Annotation of src/usr.bin/ar/ar.c, Revision 1.7
1.7 ! millert 1: /* $OpenBSD: ar.c,v 1.6 2000/11/20 14:03:30 deraadt 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.7 ! millert 50: static char rcsid[] = "$OpenBSD: ar.c,v 1.6 2000/11/20 14:03:30 deraadt 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;
1.7 ! millert 71: static void badoptions(char *);
! 72: static void usage(void);
1.1 deraadt 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;
1.7 ! millert 87: int (*fcall)(char **);
1.1 deraadt 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 = '-';
1.5 deraadt 100: (void)strcpy(p + 1, argv[1]); /* ok */
1.1 deraadt 101: argv[1] = p;
102: }
103:
1.4 denny 104: while ((c = getopt(argc, argv, "abcCdilmopqrTtuvx")) != -1) {
1.1 deraadt 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;
1.4 denny 116: case 'C':
117: options |= AR_CC;
118: break;
1.1 deraadt 119: case 'd':
120: options |= AR_D;
121: fcall = delete;
122: break;
123: case 'l': /* not documented, compatibility only */
124: envtmp = ".";
125: break;
126: case 'm':
127: options |= AR_M;
128: fcall = move;
129: break;
130: case 'o':
131: options |= AR_O;
132: break;
133: case 'p':
134: options |= AR_P;
135: fcall = print;
136: break;
137: case 'q':
138: options |= AR_Q;
139: fcall = append;
140: break;
141: case 'r':
142: options |= AR_R;
143: fcall = replace;
144: break;
145: case 'T':
146: options |= AR_TR;
147: break;
148: case 't':
149: options |= AR_T;
150: fcall = contents;
151: break;
152: case 'u':
153: options |= AR_U;
154: break;
155: case 'v':
156: options |= AR_V;
157: break;
158: case 'x':
159: options |= AR_X;
160: fcall = extract;
161: break;
162: default:
163: usage();
164: }
165: }
166:
167: argv += optind;
168: argc -= optind;
169:
170: /* One of -dmpqrtx required. */
171: if (!(options & (AR_D|AR_M|AR_P|AR_Q|AR_R|AR_T|AR_X))) {
172: warnx("one of options -dmpqrtx is required");
173: usage();
174: }
175: /* Only one of -a and -bi allowed. */
176: if (options & AR_A && options & AR_B) {
177: warnx("only one of -a and -[bi] options allowed");
178: usage();
179: }
180: /* -ab require a position argument. */
181: if (options & (AR_A|AR_B)) {
182: if (!(posarg = *argv++)) {
183: warnx("no position operand specified");
184: usage();
185: }
186: posname = rname(posarg);
187: }
188: /* -d only valid with -Tv. */
189: if (options & AR_D && options & ~(AR_D|AR_TR|AR_V))
190: badoptions("-d");
191: /* -m only valid with -abiTv. */
192: if (options & AR_M && options & ~(AR_A|AR_B|AR_M|AR_TR|AR_V))
193: badoptions("-m");
194: /* -p only valid with -Tv. */
195: if (options & AR_P && options & ~(AR_P|AR_TR|AR_V))
196: badoptions("-p");
197: /* -q only valid with -cTv. */
198: if (options & AR_Q && options & ~(AR_C|AR_Q|AR_TR|AR_V))
199: badoptions("-q");
200: /* -r only valid with -abcuTv. */
201: if (options & AR_R && options & ~(AR_A|AR_B|AR_C|AR_R|AR_U|AR_TR|AR_V))
202: badoptions("-r");
203: /* -t only valid with -Tv. */
204: if (options & AR_T && options & ~(AR_T|AR_TR|AR_V))
205: badoptions("-t");
1.6 deraadt 206: /* -x only valid with -CouTv. */
1.4 denny 207: if (options & AR_X && options & ~(AR_O|AR_U|AR_TR|AR_V|AR_X|AR_CC))
1.1 deraadt 208: badoptions("-x");
209:
210: if (!(archive = *argv++)) {
211: warnx("no archive specified");
212: usage();
213: }
214:
215: /* -dmqr require a list of archive elements. */
216: if (options & (AR_D|AR_M|AR_Q|AR_R) && !*argv) {
217: warnx("no archive members specified");
218: usage();
219: }
220:
221: exit((*fcall)(argv));
222: }
223:
224: static void
225: badoptions(arg)
226: char *arg;
227: {
228:
229: warnx("illegal option combination for %s", arg);
230: usage();
231: }
232:
233: static void
234: usage()
235: {
236:
237: (void)fprintf(stderr, "usage: ar -d [-Tv] archive file ...\n");
238: (void)fprintf(stderr, "\tar -m [-Tv] archive file ...\n");
239: (void)fprintf(stderr, "\tar -m [-abiTv] position archive file ...\n");
240: (void)fprintf(stderr, "\tar -p [-Tv] archive [file ...]\n");
241: (void)fprintf(stderr, "\tar -q [-cTv] archive file ...\n");
242: (void)fprintf(stderr, "\tar -r [-cuTv] archive file ...\n");
243: (void)fprintf(stderr, "\tar -r [-abciuTv] position archive file ...\n");
244: (void)fprintf(stderr, "\tar -t [-Tv] archive [file ...]\n");
1.6 deraadt 245: (void)fprintf(stderr, "\tar -x [-CouTv] archive [file ...]\n");
1.1 deraadt 246: exit(1);
247: }