Annotation of src/usr.bin/ar/ar.c, Revision 1.12
1.12 ! deraadt 1: /* $OpenBSD: ar.c,v 1.11 2003/06/12 20:58:08 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.
1.10 millert 19: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 20: * may be used to endorse or promote products derived from this software
21: * without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33: * SUCH DAMAGE.
34: */
35:
36: #include <sys/param.h>
37:
38: #include <ar.h>
39: #include <dirent.h>
40: #include <err.h>
41: #include <paths.h>
42: #include <stdio.h>
43: #include <stdlib.h>
44: #include <string.h>
45: #include <unistd.h>
46:
47: #include "archive.h"
48: #include "extern.h"
49:
50: CHDR chdr;
51: u_int options;
52: char *archive, *envtmp, *posarg, *posname;
1.7 millert 53: static void badoptions(char *);
54: static void usage(void);
1.1 deraadt 55:
56: /*
57: * main --
58: * main basically uses getopt to parse options and calls the appropriate
59: * functions. Some hacks that let us be backward compatible with 4.3 ar
60: * option parsing and sanity checking.
61: */
62: int
1.11 deraadt 63: main(int argc, char *argv[])
1.1 deraadt 64: {
65: int c;
66: char *p;
1.7 millert 67: int (*fcall)(char **);
1.1 deraadt 68:
69: if (argc < 3)
70: usage();
71:
72: /*
73: * Historic versions didn't require a '-' in front of the options.
74: * Fix it, if necessary.
75: */
76: if (*argv[1] != '-') {
1.9 deraadt 77: size_t len;
78:
79: len = (u_int)(strlen(argv[1]) + 2);
80: if (!(p = malloc(len)))
1.1 deraadt 81: err(1, NULL);
82: *p = '-';
1.9 deraadt 83: (void)strlcpy(p + 1, argv[1], len - 1);
1.1 deraadt 84: argv[1] = p;
85: }
86:
1.4 denny 87: while ((c = getopt(argc, argv, "abcCdilmopqrTtuvx")) != -1) {
1.1 deraadt 88: switch(c) {
89: case 'a':
90: options |= AR_A;
91: break;
92: case 'b':
93: case 'i':
94: options |= AR_B;
95: break;
96: case 'c':
97: options |= AR_C;
98: break;
1.4 denny 99: case 'C':
100: options |= AR_CC;
101: break;
1.1 deraadt 102: case 'd':
103: options |= AR_D;
104: fcall = delete;
105: break;
106: case 'l': /* not documented, compatibility only */
107: envtmp = ".";
108: break;
109: case 'm':
110: options |= AR_M;
111: fcall = move;
112: break;
113: case 'o':
114: options |= AR_O;
115: break;
116: case 'p':
117: options |= AR_P;
118: fcall = print;
119: break;
120: case 'q':
121: options |= AR_Q;
122: fcall = append;
123: break;
124: case 'r':
125: options |= AR_R;
126: fcall = replace;
127: break;
128: case 'T':
129: options |= AR_TR;
130: break;
131: case 't':
132: options |= AR_T;
133: fcall = contents;
134: break;
135: case 'u':
136: options |= AR_U;
137: break;
138: case 'v':
139: options |= AR_V;
140: break;
141: case 'x':
142: options |= AR_X;
143: fcall = extract;
144: break;
145: default:
146: usage();
147: }
148: }
149:
150: argv += optind;
151: argc -= optind;
152:
153: /* One of -dmpqrtx required. */
154: if (!(options & (AR_D|AR_M|AR_P|AR_Q|AR_R|AR_T|AR_X))) {
155: warnx("one of options -dmpqrtx is required");
156: usage();
157: }
158: /* Only one of -a and -bi allowed. */
159: if (options & AR_A && options & AR_B) {
160: warnx("only one of -a and -[bi] options allowed");
161: usage();
162: }
163: /* -ab require a position argument. */
164: if (options & (AR_A|AR_B)) {
165: if (!(posarg = *argv++)) {
166: warnx("no position operand specified");
167: usage();
168: }
169: posname = rname(posarg);
170: }
171: /* -d only valid with -Tv. */
172: if (options & AR_D && options & ~(AR_D|AR_TR|AR_V))
173: badoptions("-d");
174: /* -m only valid with -abiTv. */
175: if (options & AR_M && options & ~(AR_A|AR_B|AR_M|AR_TR|AR_V))
176: badoptions("-m");
177: /* -p only valid with -Tv. */
178: if (options & AR_P && options & ~(AR_P|AR_TR|AR_V))
179: badoptions("-p");
180: /* -q only valid with -cTv. */
181: if (options & AR_Q && options & ~(AR_C|AR_Q|AR_TR|AR_V))
182: badoptions("-q");
183: /* -r only valid with -abcuTv. */
184: if (options & AR_R && options & ~(AR_A|AR_B|AR_C|AR_R|AR_U|AR_TR|AR_V))
185: badoptions("-r");
186: /* -t only valid with -Tv. */
187: if (options & AR_T && options & ~(AR_T|AR_TR|AR_V))
188: badoptions("-t");
1.6 deraadt 189: /* -x only valid with -CouTv. */
1.4 denny 190: if (options & AR_X && options & ~(AR_O|AR_U|AR_TR|AR_V|AR_X|AR_CC))
1.1 deraadt 191: badoptions("-x");
192:
193: if (!(archive = *argv++)) {
194: warnx("no archive specified");
195: usage();
196: }
197:
198: exit((*fcall)(argv));
199: }
200:
201: static void
1.11 deraadt 202: badoptions(char *arg)
1.1 deraadt 203: {
204:
205: warnx("illegal option combination for %s", arg);
206: usage();
207: }
208:
209: static void
1.11 deraadt 210: usage(void)
1.1 deraadt 211: {
212:
213: (void)fprintf(stderr, "usage: ar -d [-Tv] archive file ...\n");
214: (void)fprintf(stderr, "\tar -m [-Tv] archive file ...\n");
215: (void)fprintf(stderr, "\tar -m [-abiTv] position archive file ...\n");
216: (void)fprintf(stderr, "\tar -p [-Tv] archive [file ...]\n");
217: (void)fprintf(stderr, "\tar -q [-cTv] archive file ...\n");
218: (void)fprintf(stderr, "\tar -r [-cuTv] archive file ...\n");
219: (void)fprintf(stderr, "\tar -r [-abciuTv] position archive file ...\n");
220: (void)fprintf(stderr, "\tar -t [-Tv] archive [file ...]\n");
1.6 deraadt 221: (void)fprintf(stderr, "\tar -x [-CouTv] archive [file ...]\n");
1.1 deraadt 222: exit(1);
223: }