xref: /freebsd/usr.bin/ar/ar.c (revision f05da0e98091eb65ed73ecbf80dfafbdcca4a0de)
1d192f3d3SKai Wang /*-
2d192f3d3SKai Wang  * Copyright (c) 2007 Kai Wang
3d192f3d3SKai Wang  * Copyright (c) 2007 Tim Kientzle
4d192f3d3SKai Wang  * Copyright (c) 2007 Joseph Koshy
5d192f3d3SKai Wang  * All rights reserved.
6d192f3d3SKai Wang  *
7d192f3d3SKai Wang  * Redistribution and use in source and binary forms, with or without
8d192f3d3SKai Wang  * modification, are permitted provided that the following conditions
9d192f3d3SKai Wang  * are met:
10d192f3d3SKai Wang  * 1. Redistributions of source code must retain the above copyright
11d192f3d3SKai Wang  *    notice, this list of conditions and the following disclaimer
12d192f3d3SKai Wang  *    in this position and unchanged.
13d192f3d3SKai Wang  * 2. Redistributions in binary form must reproduce the above copyright
14d192f3d3SKai Wang  *    notice, this list of conditions and the following disclaimer in the
15d192f3d3SKai Wang  *    documentation and/or other materials provided with the distribution.
16d192f3d3SKai Wang  *
17d192f3d3SKai Wang  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
18d192f3d3SKai Wang  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19d192f3d3SKai Wang  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20d192f3d3SKai Wang  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
21d192f3d3SKai Wang  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22d192f3d3SKai Wang  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23d192f3d3SKai Wang  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24d192f3d3SKai Wang  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25d192f3d3SKai Wang  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26d192f3d3SKai Wang  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27d192f3d3SKai Wang  */
28d192f3d3SKai Wang 
29d192f3d3SKai Wang /*-
30d192f3d3SKai Wang  * Copyright (c) 1990, 1993, 1994
31d192f3d3SKai Wang  *	The Regents of the University of California.  All rights reserved.
32d192f3d3SKai Wang  *
33d192f3d3SKai Wang  * This code is derived from software contributed to Berkeley by
34d192f3d3SKai Wang  * Hugh Smith at The University of Guelph.
35d192f3d3SKai Wang  *
36d192f3d3SKai Wang  * Redistribution and use in source and binary forms, with or without
37d192f3d3SKai Wang  * modification, are permitted provided that the following conditions
38d192f3d3SKai Wang  * are met:
39d192f3d3SKai Wang  * 1. Redistributions of source code must retain the above copyright
40d192f3d3SKai Wang  *    notice, this list of conditions and the following disclaimer.
41d192f3d3SKai Wang  * 2. Redistributions in binary form must reproduce the above copyright
42d192f3d3SKai Wang  *    notice, this list of conditions and the following disclaimer in the
43d192f3d3SKai Wang  *    documentation and/or other materials provided with the distribution.
44d192f3d3SKai Wang  * 3. Neither the name of the University nor the names of its contributors
45d192f3d3SKai Wang  *    may be used to endorse or promote products derived from this software
46d192f3d3SKai Wang  *    without specific prior written permission.
47d192f3d3SKai Wang  *
48d192f3d3SKai Wang  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49d192f3d3SKai Wang  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50d192f3d3SKai Wang  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51d192f3d3SKai Wang  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52d192f3d3SKai Wang  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53d192f3d3SKai Wang  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54d192f3d3SKai Wang  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55d192f3d3SKai Wang  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56d192f3d3SKai Wang  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57d192f3d3SKai Wang  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58d192f3d3SKai Wang  * SUCH DAMAGE.
59d192f3d3SKai Wang  */
60d192f3d3SKai Wang 
61d192f3d3SKai Wang #include <sys/cdefs.h>
62d192f3d3SKai Wang __FBSDID("$FreeBSD$");
63d192f3d3SKai Wang 
64d192f3d3SKai Wang #include <sys/queue.h>
65d192f3d3SKai Wang #include <sys/types.h>
66d192f3d3SKai Wang #include <archive.h>
67d192f3d3SKai Wang #include <errno.h>
68d192f3d3SKai Wang #include <getopt.h>
69d192f3d3SKai Wang #include <libgen.h>
70d192f3d3SKai Wang #include <stdio.h>
71d192f3d3SKai Wang #include <stdlib.h>
72d192f3d3SKai Wang #include <string.h>
73d192f3d3SKai Wang #include <sysexits.h>
74d192f3d3SKai Wang 
75d192f3d3SKai Wang #include "ar.h"
76d192f3d3SKai Wang 
77d192f3d3SKai Wang enum options
78d192f3d3SKai Wang {
79d192f3d3SKai Wang 	OPTION_HELP
80d192f3d3SKai Wang };
81d192f3d3SKai Wang 
82d192f3d3SKai Wang static struct option longopts[] =
83d192f3d3SKai Wang {
84d192f3d3SKai Wang 	{"help", no_argument, NULL, OPTION_HELP},
85d192f3d3SKai Wang 	{"version", no_argument, NULL, 'V'},
86d192f3d3SKai Wang 	{NULL, 0, NULL, 0}
87d192f3d3SKai Wang };
88d192f3d3SKai Wang 
89d192f3d3SKai Wang static void	bsdar_usage(void);
90d192f3d3SKai Wang static void	ranlib_usage(void);
91d192f3d3SKai Wang static void	set_mode(struct bsdar *bsdar, char opt);
92d192f3d3SKai Wang static void	only_mode(struct bsdar *bsdar, const char *opt,
93d192f3d3SKai Wang 		    const char *valid_modes);
94d192f3d3SKai Wang static void	bsdar_version(void);
95d192f3d3SKai Wang static void	ranlib_version(void);
96d192f3d3SKai Wang 
97d192f3d3SKai Wang int
98d192f3d3SKai Wang main(int argc, char **argv)
99d192f3d3SKai Wang {
100d192f3d3SKai Wang 	struct bsdar	*bsdar, bsdar_storage;
101d192f3d3SKai Wang 	char		*p;
102d192f3d3SKai Wang 	size_t		 len;
103d192f3d3SKai Wang 	int		 i, opt;
104d192f3d3SKai Wang 
105d192f3d3SKai Wang 	bsdar = &bsdar_storage;
106d192f3d3SKai Wang 	memset(bsdar, 0, sizeof(*bsdar));
107d192f3d3SKai Wang 
108d192f3d3SKai Wang 	if ((bsdar->progname = getprogname()) == NULL)
109d192f3d3SKai Wang 		bsdar->progname = "ar";
110d192f3d3SKai Wang 
111f05da0e9STim Kientzle 	/* Act like ranlib if our name ends in "ranlib"; this
112f05da0e9STim Kientzle 	 * accomodates arm-freebsd7.1-ranlib, bsdranlib, etc. */
113f05da0e9STim Kientzle 	len = strlen(bsdar->progname);
114f05da0e9STim Kientzle 	if (len >= strlen("ranlib") &&
115f05da0e9STim Kientzle 	    strcmp(bsdar->progname + len - strlen("ranlib"), "ranlib") == 0) {
116d192f3d3SKai Wang 		while ((opt = getopt_long(argc, argv, "tV", longopts,
117d192f3d3SKai Wang 		    NULL)) != -1) {
118d192f3d3SKai Wang 			switch(opt) {
119d192f3d3SKai Wang 			case 't':
120d192f3d3SKai Wang 				/* Ignored. */
121d192f3d3SKai Wang 				break;
122d192f3d3SKai Wang 			case 'V':
123d192f3d3SKai Wang 				ranlib_version();
124d192f3d3SKai Wang 				break;
125d192f3d3SKai Wang 			case OPTION_HELP:
126d192f3d3SKai Wang 				ranlib_usage();
127d192f3d3SKai Wang 			default:
128d192f3d3SKai Wang 				ranlib_usage();
129d192f3d3SKai Wang 			}
130d192f3d3SKai Wang 		}
131d192f3d3SKai Wang 		argv += optind;
132d192f3d3SKai Wang 		argc -= optind;
133d192f3d3SKai Wang 
134d192f3d3SKai Wang 		if (*argv == NULL)
135d192f3d3SKai Wang 			ranlib_usage();
136d192f3d3SKai Wang 
137d192f3d3SKai Wang 		bsdar->options |= AR_S;
138d192f3d3SKai Wang 		for (;(bsdar->filename = *argv++) != NULL;)
139d192f3d3SKai Wang 			ar_mode_s(bsdar);
140d192f3d3SKai Wang 
141d192f3d3SKai Wang 		exit(EX_OK);
142d192f3d3SKai Wang 	} else {
143d192f3d3SKai Wang 		if (argc < 2)
144d192f3d3SKai Wang 			bsdar_usage();
145d192f3d3SKai Wang 
146d192f3d3SKai Wang 		if (*argv[1] != '-') {
147d192f3d3SKai Wang 			len = strlen(argv[1]) + 2;
148d192f3d3SKai Wang 			if ((p = malloc(len)) == NULL)
149d192f3d3SKai Wang 				bsdar_errc(bsdar, EX_SOFTWARE, errno,
150d192f3d3SKai Wang 				    "malloc failed");
151d192f3d3SKai Wang 			*p = '-';
152d192f3d3SKai Wang 			(void)strlcpy(p + 1, argv[1], len - 1);
153d192f3d3SKai Wang 			argv[1] = p;
154d192f3d3SKai Wang 		}
155d192f3d3SKai Wang 	}
156d192f3d3SKai Wang 
1570c099281SKai Wang 	while ((opt = getopt_long(argc, argv, "abCcdfijlMmopqrSsTtuVvxz",
158d192f3d3SKai Wang 	    longopts, NULL)) != -1) {
159d192f3d3SKai Wang 		switch(opt) {
160d192f3d3SKai Wang 		case 'a':
161d192f3d3SKai Wang 			bsdar->options |= AR_A;
162d192f3d3SKai Wang 			break;
163d192f3d3SKai Wang 		case 'b':
164d192f3d3SKai Wang 		case 'i':
165d192f3d3SKai Wang 			bsdar->options |= AR_B;
166d192f3d3SKai Wang 			break;
167d192f3d3SKai Wang 		case 'C':
168d192f3d3SKai Wang 			bsdar->options |= AR_CC;
169d192f3d3SKai Wang 			break;
170d192f3d3SKai Wang 		case 'c':
171d192f3d3SKai Wang 			bsdar->options |= AR_C;
172d192f3d3SKai Wang 			break;
173d192f3d3SKai Wang 		case 'd':
174d192f3d3SKai Wang 			set_mode(bsdar, opt);
175d192f3d3SKai Wang 			break;
176d192f3d3SKai Wang 		case 'f':
177d192f3d3SKai Wang 		case 'T':
178d192f3d3SKai Wang 			bsdar->options |= AR_TR;
179d192f3d3SKai Wang 			break;
180d192f3d3SKai Wang 		case 'j':
181d192f3d3SKai Wang 			bsdar->options |= AR_J;
182d192f3d3SKai Wang 			break;
183d192f3d3SKai Wang 		case 'l':
184d192f3d3SKai Wang 			/* ignored, for GNU ar comptibility */
185d192f3d3SKai Wang 			break;
1860c099281SKai Wang 		case 'M':
1870c099281SKai Wang 			set_mode(bsdar, opt);
1880c099281SKai Wang 			break;
189d192f3d3SKai Wang 		case 'm':
190d192f3d3SKai Wang 			set_mode(bsdar, opt);
191d192f3d3SKai Wang 			break;
192d192f3d3SKai Wang 		case 'o':
193d192f3d3SKai Wang 			bsdar->options |= AR_O;
194d192f3d3SKai Wang 			break;
195d192f3d3SKai Wang 		case 'p':
196d192f3d3SKai Wang 			set_mode(bsdar, opt);
197d192f3d3SKai Wang 			break;
198d192f3d3SKai Wang 		case 'q':
199d192f3d3SKai Wang 			set_mode(bsdar, opt);
200d192f3d3SKai Wang 			break;
201d192f3d3SKai Wang 		case 'r':
202d192f3d3SKai Wang 			set_mode(bsdar, opt);
203d192f3d3SKai Wang 			break;
204d192f3d3SKai Wang 		case 'S':
205d192f3d3SKai Wang 			bsdar->options |= AR_SS;
206d192f3d3SKai Wang 			break;
207d192f3d3SKai Wang 		case 's':
208d192f3d3SKai Wang 			bsdar->options |= AR_S;
209d192f3d3SKai Wang 			break;
210d192f3d3SKai Wang 		case 't':
211d192f3d3SKai Wang 			set_mode(bsdar, opt);
212d192f3d3SKai Wang 			break;
213d192f3d3SKai Wang 		case 'u':
214d192f3d3SKai Wang 			bsdar->options |= AR_U;
215d192f3d3SKai Wang 			break;
216d192f3d3SKai Wang 		case 'V':
217d192f3d3SKai Wang 			bsdar_version();
218d192f3d3SKai Wang 			break;
219d192f3d3SKai Wang 		case 'v':
220d192f3d3SKai Wang 			bsdar->options |= AR_V;
221d192f3d3SKai Wang 			break;
222d192f3d3SKai Wang 		case 'x':
223d192f3d3SKai Wang 			set_mode(bsdar, opt);
224d192f3d3SKai Wang 			break;
225d192f3d3SKai Wang 		case 'z':
226d192f3d3SKai Wang 			bsdar->options |= AR_Z;
227d192f3d3SKai Wang 			break;
228d192f3d3SKai Wang 		case OPTION_HELP:
229d192f3d3SKai Wang 			bsdar_usage();
230d192f3d3SKai Wang 		default:
231d192f3d3SKai Wang 			bsdar_usage();
232d192f3d3SKai Wang 		}
233d192f3d3SKai Wang 	}
234d192f3d3SKai Wang 
235d192f3d3SKai Wang 	argv += optind;
236d192f3d3SKai Wang 	argc -= optind;
237d192f3d3SKai Wang 
2380c099281SKai Wang 	if (*argv == NULL && bsdar->mode != 'M')
239d192f3d3SKai Wang 		bsdar_usage();
240d192f3d3SKai Wang 
241d192f3d3SKai Wang 	if (bsdar->options & AR_A && bsdar->options & AR_B)
242d192f3d3SKai Wang 		bsdar_errc(bsdar, EX_USAGE, 0,
243d192f3d3SKai Wang 		    "only one of -a and -[bi] options allowed");
244d192f3d3SKai Wang 
245d192f3d3SKai Wang 	if (bsdar->options & AR_J && bsdar->options & AR_Z)
246d192f3d3SKai Wang 		bsdar_errc(bsdar, EX_USAGE, 0,
247d192f3d3SKai Wang 		    "only one of -j and -z options allowed");
248d192f3d3SKai Wang 
249d192f3d3SKai Wang 	if (bsdar->options & AR_S && bsdar->options & AR_SS)
250d192f3d3SKai Wang 		bsdar_errc(bsdar, EX_USAGE, 0,
251d192f3d3SKai Wang 		    "only one of -s and -S options allowed");
252d192f3d3SKai Wang 
253d192f3d3SKai Wang 	if (bsdar->options & (AR_A | AR_B)) {
254d192f3d3SKai Wang 		if ((bsdar->posarg = *argv) == NULL)
255d192f3d3SKai Wang 			bsdar_errc(bsdar, EX_USAGE, 0,
256d192f3d3SKai Wang 			    "no position operand specified");
257d192f3d3SKai Wang 		if ((bsdar->posarg = basename(bsdar->posarg)) == NULL)
258d192f3d3SKai Wang 			bsdar_errc(bsdar, EX_SOFTWARE, errno,
259d192f3d3SKai Wang 			    "basename failed");
260d192f3d3SKai Wang 		argc--;
261d192f3d3SKai Wang 		argv++;
262d192f3d3SKai Wang 	}
263d192f3d3SKai Wang 
264d192f3d3SKai Wang 	if (bsdar->options & AR_A)
265d192f3d3SKai Wang 		only_mode(bsdar, "-a", "mqr");
266d192f3d3SKai Wang 	if (bsdar->options & AR_B)
267d192f3d3SKai Wang 		only_mode(bsdar, "-b", "mqr");
268d192f3d3SKai Wang 	if (bsdar->options & AR_C)
269d192f3d3SKai Wang 		only_mode(bsdar, "-c", "qr");
270d192f3d3SKai Wang 	if (bsdar->options & AR_CC)
271d192f3d3SKai Wang 		only_mode(bsdar, "-C", "x");
272d192f3d3SKai Wang 	if (bsdar->options & AR_O)
273d192f3d3SKai Wang 		only_mode(bsdar, "-o", "x");
274d192f3d3SKai Wang 	if (bsdar->options & AR_SS)
275d192f3d3SKai Wang 		only_mode(bsdar, "-S", "mqr");
276d192f3d3SKai Wang 	if (bsdar->options & AR_U)
277d192f3d3SKai Wang 		only_mode(bsdar, "-u", "qrx");
278d192f3d3SKai Wang 
2790c099281SKai Wang 	if (bsdar->mode == 'M') {
2800c099281SKai Wang 		ar_mode_script(bsdar);
2810c099281SKai Wang 		exit(EX_OK);
2820c099281SKai Wang 	}
2830c099281SKai Wang 
284d192f3d3SKai Wang 	if ((bsdar->filename = *argv) == NULL)
285d192f3d3SKai Wang 		bsdar_usage();
286d192f3d3SKai Wang 
287d192f3d3SKai Wang 	bsdar->argc = --argc;
288d192f3d3SKai Wang 	bsdar->argv = ++argv;
289d192f3d3SKai Wang 
290d192f3d3SKai Wang 	if ((!bsdar->mode || strchr("ptx", bsdar->mode)) &&
291d192f3d3SKai Wang 	    bsdar->options & AR_S) {
292d192f3d3SKai Wang 		ar_mode_s(bsdar);
293d192f3d3SKai Wang 		if (!bsdar->mode)
294d192f3d3SKai Wang 			exit(EX_OK);
295d192f3d3SKai Wang 	}
296d192f3d3SKai Wang 
297d192f3d3SKai Wang 	switch(bsdar->mode) {
298d192f3d3SKai Wang 	case 'd':
299d192f3d3SKai Wang 		ar_mode_d(bsdar);
300d192f3d3SKai Wang 		break;
301d192f3d3SKai Wang 	case 'm':
302d192f3d3SKai Wang 		ar_mode_m(bsdar);
303d192f3d3SKai Wang 		break;
304d192f3d3SKai Wang 	case 'p':
305d192f3d3SKai Wang 		ar_mode_p(bsdar);
306d192f3d3SKai Wang 		break;
307d192f3d3SKai Wang 	case 'q':
308cb0dad38SKai Wang 		ar_mode_q(bsdar);
309d192f3d3SKai Wang 		break;
310d192f3d3SKai Wang 	case 'r':
311d192f3d3SKai Wang 		ar_mode_r(bsdar);
312d192f3d3SKai Wang 		break;
313d192f3d3SKai Wang 	case 't':
314d192f3d3SKai Wang 		ar_mode_t(bsdar);
315d192f3d3SKai Wang 		break;
316d192f3d3SKai Wang 	case 'x':
317d192f3d3SKai Wang 		ar_mode_x(bsdar);
318d192f3d3SKai Wang 		break;
319d192f3d3SKai Wang 	default:
320d192f3d3SKai Wang 		bsdar_usage();
321d192f3d3SKai Wang 		/* NOTREACHED */
322d192f3d3SKai Wang 	}
323d192f3d3SKai Wang 
324d192f3d3SKai Wang 	for (i = 0; i < bsdar->argc; i++)
325d192f3d3SKai Wang 		if (bsdar->argv[i] != NULL)
326d192f3d3SKai Wang 			bsdar_warnc(bsdar, 0, "%s: not found in archive",
327d192f3d3SKai Wang 			    bsdar->argv[i]);
328d192f3d3SKai Wang 
329d192f3d3SKai Wang 	exit(EX_OK);
330d192f3d3SKai Wang }
331d192f3d3SKai Wang 
332d192f3d3SKai Wang static void
333d192f3d3SKai Wang set_mode(struct bsdar *bsdar, char opt)
334d192f3d3SKai Wang {
335d192f3d3SKai Wang 
336d192f3d3SKai Wang 	if (bsdar->mode != '\0' && bsdar->mode != opt)
337d192f3d3SKai Wang 		bsdar_errc(bsdar, EX_USAGE, 0,
338d192f3d3SKai Wang 		    "Can't specify both -%c and -%c", opt, bsdar->mode);
339d192f3d3SKai Wang 	bsdar->mode = opt;
340d192f3d3SKai Wang }
341d192f3d3SKai Wang 
342d192f3d3SKai Wang static void
343d192f3d3SKai Wang only_mode(struct bsdar *bsdar, const char *opt, const char *valid_modes)
344d192f3d3SKai Wang {
345d192f3d3SKai Wang 
346d192f3d3SKai Wang 	if (strchr(valid_modes, bsdar->mode) == NULL)
347d192f3d3SKai Wang 		bsdar_errc(bsdar, EX_USAGE, 0,
348d192f3d3SKai Wang 		    "Option %s is not permitted in mode -%c", opt, bsdar->mode);
349d192f3d3SKai Wang }
350d192f3d3SKai Wang 
351d192f3d3SKai Wang static void
352d192f3d3SKai Wang bsdar_usage()
353d192f3d3SKai Wang {
354d192f3d3SKai Wang 
355d192f3d3SKai Wang 	(void)fprintf(stderr, "usage:  ar -d [-Tjsvz] archive file ...\n");
356d192f3d3SKai Wang 	(void)fprintf(stderr, "\tar -m [-Tjsvz] archive file ...\n");
357d192f3d3SKai Wang 	(void)fprintf(stderr, "\tar -m [-Tabijsvz] position archive file ...\n");
358d192f3d3SKai Wang 	(void)fprintf(stderr, "\tar -p [-Tv] archive [file ...]\n");
359cb0dad38SKai Wang 	(void)fprintf(stderr, "\tar -q [-Tcjsvz] archive file ...\n");
360d192f3d3SKai Wang 	(void)fprintf(stderr, "\tar -r [-Tcjsuvz] archive file ...\n");
361d192f3d3SKai Wang 	(void)fprintf(stderr, "\tar -r [-Tabcijsuvz] position archive file ...\n");
362d192f3d3SKai Wang 	(void)fprintf(stderr, "\tar -s [-jz] archive\n");
363d192f3d3SKai Wang 	(void)fprintf(stderr, "\tar -t [-Tv] archive [file ...]\n");
364d192f3d3SKai Wang 	(void)fprintf(stderr, "\tar -x [-CTouv] archive [file ...]\n");
365d192f3d3SKai Wang 	(void)fprintf(stderr, "\tar -V\n");
366d192f3d3SKai Wang 	exit(EX_USAGE);
367d192f3d3SKai Wang }
368d192f3d3SKai Wang 
369d192f3d3SKai Wang static void
370d192f3d3SKai Wang ranlib_usage()
371d192f3d3SKai Wang {
372d192f3d3SKai Wang 
373d192f3d3SKai Wang 	(void)fprintf(stderr, "usage:	ranlib [-t] archive ...\n");
374d192f3d3SKai Wang 	(void)fprintf(stderr, "\tranlib -V\n");
375d192f3d3SKai Wang 	exit(EX_USAGE);
376d192f3d3SKai Wang }
377d192f3d3SKai Wang 
378d192f3d3SKai Wang static void
379d192f3d3SKai Wang bsdar_version()
380d192f3d3SKai Wang {
381d192f3d3SKai Wang 	(void)printf("BSD ar %s - %s\n", BSDAR_VERSION, archive_version());
382d192f3d3SKai Wang 	exit(EX_OK);
383d192f3d3SKai Wang }
384d192f3d3SKai Wang 
385d192f3d3SKai Wang static void
386d192f3d3SKai Wang ranlib_version()
387d192f3d3SKai Wang {
388d192f3d3SKai Wang 	(void)printf("ranlib %s - %s\n", BSDAR_VERSION, archive_version());
389d192f3d3SKai Wang 	exit(EX_OK);
390d192f3d3SKai Wang }
391