xref: /freebsd/usr.bin/ar/ar.c (revision a80ac30b2df8e89e46c3d1bb1e375b25c618e24c)
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;
103*a80ac30bSEd Maste 	int		 i, opt, Dflag, Uflag;
104d192f3d3SKai Wang 
105d192f3d3SKai Wang 	bsdar = &bsdar_storage;
106d192f3d3SKai Wang 	memset(bsdar, 0, sizeof(*bsdar));
107*a80ac30bSEd Maste 	Dflag = 0;
108*a80ac30bSEd Maste 	Uflag = 0;
109d192f3d3SKai Wang 
110d192f3d3SKai Wang 	if ((bsdar->progname = getprogname()) == NULL)
111d192f3d3SKai Wang 		bsdar->progname = "ar";
112d192f3d3SKai Wang 
113f05da0e9STim Kientzle 	/* Act like ranlib if our name ends in "ranlib"; this
1146bef5d28SBenedict Reuschling 	 * accommodates arm-freebsd7.1-ranlib, bsdranlib, etc. */
115f05da0e9STim Kientzle 	len = strlen(bsdar->progname);
116f05da0e9STim Kientzle 	if (len >= strlen("ranlib") &&
117f05da0e9STim Kientzle 	    strcmp(bsdar->progname + len - strlen("ranlib"), "ranlib") == 0) {
1187072861cSEd Maste 		while ((opt = getopt_long(argc, argv, "tDUV", longopts,
119d192f3d3SKai Wang 		    NULL)) != -1) {
120d192f3d3SKai Wang 			switch(opt) {
121d192f3d3SKai Wang 			case 't':
122d192f3d3SKai Wang 				/* Ignored. */
123d192f3d3SKai Wang 				break;
124773810fbSKai Wang 			case 'D':
125*a80ac30bSEd Maste 				Dflag = 1;
126*a80ac30bSEd Maste 				Uflag = 0;
127773810fbSKai Wang 				break;
1287072861cSEd Maste 			case 'U':
129*a80ac30bSEd Maste 				Uflag = 1;
130*a80ac30bSEd Maste 				Dflag = 0;
1317072861cSEd Maste 				break;
132d192f3d3SKai Wang 			case 'V':
133d192f3d3SKai Wang 				ranlib_version();
134d192f3d3SKai Wang 				break;
135d192f3d3SKai Wang 			case OPTION_HELP:
136d192f3d3SKai Wang 				ranlib_usage();
137d192f3d3SKai Wang 			default:
138d192f3d3SKai Wang 				ranlib_usage();
139d192f3d3SKai Wang 			}
140d192f3d3SKai Wang 		}
141d192f3d3SKai Wang 		argv += optind;
142d192f3d3SKai Wang 		argc -= optind;
143d192f3d3SKai Wang 
144d192f3d3SKai Wang 		if (*argv == NULL)
145d192f3d3SKai Wang 			ranlib_usage();
146d192f3d3SKai Wang 
147d192f3d3SKai Wang 		bsdar->options |= AR_S;
148d192f3d3SKai Wang 		for (;(bsdar->filename = *argv++) != NULL;)
149d192f3d3SKai Wang 			ar_mode_s(bsdar);
150d192f3d3SKai Wang 
151d192f3d3SKai Wang 		exit(EX_OK);
152d192f3d3SKai Wang 	} else {
153d192f3d3SKai Wang 		if (argc < 2)
154d192f3d3SKai Wang 			bsdar_usage();
155d192f3d3SKai Wang 
156d192f3d3SKai Wang 		if (*argv[1] != '-') {
157d192f3d3SKai Wang 			len = strlen(argv[1]) + 2;
158d192f3d3SKai Wang 			if ((p = malloc(len)) == NULL)
159d192f3d3SKai Wang 				bsdar_errc(bsdar, EX_SOFTWARE, errno,
160d192f3d3SKai Wang 				    "malloc failed");
161d192f3d3SKai Wang 			*p = '-';
162d192f3d3SKai Wang 			(void)strlcpy(p + 1, argv[1], len - 1);
163d192f3d3SKai Wang 			argv[1] = p;
164d192f3d3SKai Wang 		}
165d192f3d3SKai Wang 	}
166d192f3d3SKai Wang 
1677072861cSEd Maste 	while ((opt = getopt_long(argc, argv, "abCcdDfijlMmopqrSsTtUuVvxz",
168d192f3d3SKai Wang 	    longopts, NULL)) != -1) {
169d192f3d3SKai Wang 		switch(opt) {
170d192f3d3SKai Wang 		case 'a':
171d192f3d3SKai Wang 			bsdar->options |= AR_A;
172d192f3d3SKai Wang 			break;
173d192f3d3SKai Wang 		case 'b':
174d192f3d3SKai Wang 		case 'i':
175d192f3d3SKai Wang 			bsdar->options |= AR_B;
176d192f3d3SKai Wang 			break;
177d192f3d3SKai Wang 		case 'C':
178d192f3d3SKai Wang 			bsdar->options |= AR_CC;
179d192f3d3SKai Wang 			break;
180d192f3d3SKai Wang 		case 'c':
181d192f3d3SKai Wang 			bsdar->options |= AR_C;
182d192f3d3SKai Wang 			break;
183d192f3d3SKai Wang 		case 'd':
184d192f3d3SKai Wang 			set_mode(bsdar, opt);
185d192f3d3SKai Wang 			break;
1860e479ac8STim Kientzle 		case 'D':
187*a80ac30bSEd Maste 			Dflag = 1;
188*a80ac30bSEd Maste 			Uflag = 0;
1890e479ac8STim Kientzle 			break;
190d192f3d3SKai Wang 		case 'f':
191d192f3d3SKai Wang 		case 'T':
192d192f3d3SKai Wang 			bsdar->options |= AR_TR;
193d192f3d3SKai Wang 			break;
194d192f3d3SKai Wang 		case 'j':
1955dfab45bSKai Wang 			/* ignored */
196d192f3d3SKai Wang 			break;
197d192f3d3SKai Wang 		case 'l':
198d192f3d3SKai Wang 			/* ignored, for GNU ar comptibility */
199d192f3d3SKai Wang 			break;
2000c099281SKai Wang 		case 'M':
2010c099281SKai Wang 			set_mode(bsdar, opt);
2020c099281SKai Wang 			break;
203d192f3d3SKai Wang 		case 'm':
204d192f3d3SKai Wang 			set_mode(bsdar, opt);
205d192f3d3SKai Wang 			break;
206d192f3d3SKai Wang 		case 'o':
207d192f3d3SKai Wang 			bsdar->options |= AR_O;
208d192f3d3SKai Wang 			break;
209d192f3d3SKai Wang 		case 'p':
210d192f3d3SKai Wang 			set_mode(bsdar, opt);
211d192f3d3SKai Wang 			break;
212d192f3d3SKai Wang 		case 'q':
213d192f3d3SKai Wang 			set_mode(bsdar, opt);
214d192f3d3SKai Wang 			break;
215d192f3d3SKai Wang 		case 'r':
216d192f3d3SKai Wang 			set_mode(bsdar, opt);
217d192f3d3SKai Wang 			break;
218d192f3d3SKai Wang 		case 'S':
219d192f3d3SKai Wang 			bsdar->options |= AR_SS;
220d192f3d3SKai Wang 			break;
221d192f3d3SKai Wang 		case 's':
222d192f3d3SKai Wang 			bsdar->options |= AR_S;
223d192f3d3SKai Wang 			break;
224d192f3d3SKai Wang 		case 't':
225d192f3d3SKai Wang 			set_mode(bsdar, opt);
226d192f3d3SKai Wang 			break;
2277072861cSEd Maste 		case 'U':
228*a80ac30bSEd Maste 			Uflag = 1;
229*a80ac30bSEd Maste 			Dflag = 0;
2307072861cSEd Maste 			break;
231d192f3d3SKai Wang 		case 'u':
232d192f3d3SKai Wang 			bsdar->options |= AR_U;
233d192f3d3SKai Wang 			break;
234d192f3d3SKai Wang 		case 'V':
235d192f3d3SKai Wang 			bsdar_version();
236d192f3d3SKai Wang 			break;
237d192f3d3SKai Wang 		case 'v':
238d192f3d3SKai Wang 			bsdar->options |= AR_V;
239d192f3d3SKai Wang 			break;
240d192f3d3SKai Wang 		case 'x':
241d192f3d3SKai Wang 			set_mode(bsdar, opt);
242d192f3d3SKai Wang 			break;
243d192f3d3SKai Wang 		case 'z':
2445dfab45bSKai Wang 			/* ignored */
245d192f3d3SKai Wang 			break;
246d192f3d3SKai Wang 		case OPTION_HELP:
247d192f3d3SKai Wang 			bsdar_usage();
248d192f3d3SKai Wang 		default:
249d192f3d3SKai Wang 			bsdar_usage();
250d192f3d3SKai Wang 		}
251d192f3d3SKai Wang 	}
252d192f3d3SKai Wang 
253d192f3d3SKai Wang 	argv += optind;
254d192f3d3SKai Wang 	argc -= optind;
255d192f3d3SKai Wang 
2560c099281SKai Wang 	if (*argv == NULL && bsdar->mode != 'M')
257d192f3d3SKai Wang 		bsdar_usage();
258d192f3d3SKai Wang 
259d192f3d3SKai Wang 	if (bsdar->options & AR_A && bsdar->options & AR_B)
260d192f3d3SKai Wang 		bsdar_errc(bsdar, EX_USAGE, 0,
261d192f3d3SKai Wang 		    "only one of -a and -[bi] options allowed");
262d192f3d3SKai Wang 
263d192f3d3SKai Wang 	if (bsdar->options & AR_J && bsdar->options & AR_Z)
264d192f3d3SKai Wang 		bsdar_errc(bsdar, EX_USAGE, 0,
265d192f3d3SKai Wang 		    "only one of -j and -z options allowed");
266d192f3d3SKai Wang 
267d192f3d3SKai Wang 	if (bsdar->options & AR_S && bsdar->options & AR_SS)
268d192f3d3SKai Wang 		bsdar_errc(bsdar, EX_USAGE, 0,
269d192f3d3SKai Wang 		    "only one of -s and -S options allowed");
270d192f3d3SKai Wang 
271d192f3d3SKai Wang 	if (bsdar->options & (AR_A | AR_B)) {
272d192f3d3SKai Wang 		if ((bsdar->posarg = *argv) == NULL)
273d192f3d3SKai Wang 			bsdar_errc(bsdar, EX_USAGE, 0,
274d192f3d3SKai Wang 			    "no position operand specified");
275d192f3d3SKai Wang 		if ((bsdar->posarg = basename(bsdar->posarg)) == NULL)
276d192f3d3SKai Wang 			bsdar_errc(bsdar, EX_SOFTWARE, errno,
277d192f3d3SKai Wang 			    "basename failed");
278d192f3d3SKai Wang 		argc--;
279d192f3d3SKai Wang 		argv++;
280d192f3d3SKai Wang 	}
281d192f3d3SKai Wang 
282*a80ac30bSEd Maste 	/* Set determinstic mode for -D, and by default without -U. */
283*a80ac30bSEd Maste 	if (Dflag || (Uflag == 0 && (bsdar->mode == 'q' || bsdar->mode == 'r')))
284*a80ac30bSEd Maste 		bsdar->options |= AR_D;
285*a80ac30bSEd Maste 
286d192f3d3SKai Wang 	if (bsdar->options & AR_A)
287d192f3d3SKai Wang 		only_mode(bsdar, "-a", "mqr");
288d192f3d3SKai Wang 	if (bsdar->options & AR_B)
289d192f3d3SKai Wang 		only_mode(bsdar, "-b", "mqr");
290d192f3d3SKai Wang 	if (bsdar->options & AR_C)
291d192f3d3SKai Wang 		only_mode(bsdar, "-c", "qr");
292d192f3d3SKai Wang 	if (bsdar->options & AR_CC)
293d192f3d3SKai Wang 		only_mode(bsdar, "-C", "x");
294*a80ac30bSEd Maste 	if (Dflag)
2950e479ac8STim Kientzle 		only_mode(bsdar, "-D", "qr");
296*a80ac30bSEd Maste 	if (Uflag)
297*a80ac30bSEd Maste 		only_mode(bsdar, "-U", "qr");
298d192f3d3SKai Wang 	if (bsdar->options & AR_O)
299d192f3d3SKai Wang 		only_mode(bsdar, "-o", "x");
300d192f3d3SKai Wang 	if (bsdar->options & AR_SS)
301d192f3d3SKai Wang 		only_mode(bsdar, "-S", "mqr");
302d192f3d3SKai Wang 	if (bsdar->options & AR_U)
303d192f3d3SKai Wang 		only_mode(bsdar, "-u", "qrx");
304d192f3d3SKai Wang 
3050c099281SKai Wang 	if (bsdar->mode == 'M') {
3060c099281SKai Wang 		ar_mode_script(bsdar);
3070c099281SKai Wang 		exit(EX_OK);
3080c099281SKai Wang 	}
3090c099281SKai Wang 
310d192f3d3SKai Wang 	if ((bsdar->filename = *argv) == NULL)
311d192f3d3SKai Wang 		bsdar_usage();
312d192f3d3SKai Wang 
313d192f3d3SKai Wang 	bsdar->argc = --argc;
314d192f3d3SKai Wang 	bsdar->argv = ++argv;
315d192f3d3SKai Wang 
316d192f3d3SKai Wang 	if ((!bsdar->mode || strchr("ptx", bsdar->mode)) &&
317d192f3d3SKai Wang 	    bsdar->options & AR_S) {
318d192f3d3SKai Wang 		ar_mode_s(bsdar);
319d192f3d3SKai Wang 		if (!bsdar->mode)
320d192f3d3SKai Wang 			exit(EX_OK);
321d192f3d3SKai Wang 	}
322d192f3d3SKai Wang 
323d192f3d3SKai Wang 	switch(bsdar->mode) {
324d192f3d3SKai Wang 	case 'd':
325d192f3d3SKai Wang 		ar_mode_d(bsdar);
326d192f3d3SKai Wang 		break;
327d192f3d3SKai Wang 	case 'm':
328d192f3d3SKai Wang 		ar_mode_m(bsdar);
329d192f3d3SKai Wang 		break;
330d192f3d3SKai Wang 	case 'p':
331d192f3d3SKai Wang 		ar_mode_p(bsdar);
332d192f3d3SKai Wang 		break;
333d192f3d3SKai Wang 	case 'q':
334cb0dad38SKai Wang 		ar_mode_q(bsdar);
335d192f3d3SKai Wang 		break;
336d192f3d3SKai Wang 	case 'r':
337d192f3d3SKai Wang 		ar_mode_r(bsdar);
338d192f3d3SKai Wang 		break;
339d192f3d3SKai Wang 	case 't':
340d192f3d3SKai Wang 		ar_mode_t(bsdar);
341d192f3d3SKai Wang 		break;
342d192f3d3SKai Wang 	case 'x':
343d192f3d3SKai Wang 		ar_mode_x(bsdar);
344d192f3d3SKai Wang 		break;
345d192f3d3SKai Wang 	default:
346d192f3d3SKai Wang 		bsdar_usage();
347d192f3d3SKai Wang 		/* NOTREACHED */
348d192f3d3SKai Wang 	}
349d192f3d3SKai Wang 
350d192f3d3SKai Wang 	for (i = 0; i < bsdar->argc; i++)
351d192f3d3SKai Wang 		if (bsdar->argv[i] != NULL)
352d192f3d3SKai Wang 			bsdar_warnc(bsdar, 0, "%s: not found in archive",
353d192f3d3SKai Wang 			    bsdar->argv[i]);
354d192f3d3SKai Wang 
355d192f3d3SKai Wang 	exit(EX_OK);
356d192f3d3SKai Wang }
357d192f3d3SKai Wang 
358d192f3d3SKai Wang static void
359d192f3d3SKai Wang set_mode(struct bsdar *bsdar, char opt)
360d192f3d3SKai Wang {
361d192f3d3SKai Wang 
362d192f3d3SKai Wang 	if (bsdar->mode != '\0' && bsdar->mode != opt)
363d192f3d3SKai Wang 		bsdar_errc(bsdar, EX_USAGE, 0,
364d192f3d3SKai Wang 		    "Can't specify both -%c and -%c", opt, bsdar->mode);
365d192f3d3SKai Wang 	bsdar->mode = opt;
366d192f3d3SKai Wang }
367d192f3d3SKai Wang 
368d192f3d3SKai Wang static void
369d192f3d3SKai Wang only_mode(struct bsdar *bsdar, const char *opt, const char *valid_modes)
370d192f3d3SKai Wang {
371d192f3d3SKai Wang 
372d192f3d3SKai Wang 	if (strchr(valid_modes, bsdar->mode) == NULL)
373d192f3d3SKai Wang 		bsdar_errc(bsdar, EX_USAGE, 0,
374d192f3d3SKai Wang 		    "Option %s is not permitted in mode -%c", opt, bsdar->mode);
375d192f3d3SKai Wang }
376d192f3d3SKai Wang 
377d192f3d3SKai Wang static void
378ef636796SEd Schouten bsdar_usage(void)
379d192f3d3SKai Wang {
380d192f3d3SKai Wang 
381d192f3d3SKai Wang 	(void)fprintf(stderr, "usage:  ar -d [-Tjsvz] archive file ...\n");
382d192f3d3SKai Wang 	(void)fprintf(stderr, "\tar -m [-Tjsvz] archive file ...\n");
383d192f3d3SKai Wang 	(void)fprintf(stderr, "\tar -m [-Tabijsvz] position archive file ...\n");
384d192f3d3SKai Wang 	(void)fprintf(stderr, "\tar -p [-Tv] archive [file ...]\n");
3857072861cSEd Maste 	(void)fprintf(stderr, "\tar -q [-TcDjsUvz] archive file ...\n");
3867072861cSEd Maste 	(void)fprintf(stderr, "\tar -r [-TcDjsUuvz] archive file ...\n");
3877072861cSEd Maste 	(void)fprintf(stderr, "\tar -r [-TabcDijsUuvz] position archive file ...\n");
388d192f3d3SKai Wang 	(void)fprintf(stderr, "\tar -s [-jz] archive\n");
389d192f3d3SKai Wang 	(void)fprintf(stderr, "\tar -t [-Tv] archive [file ...]\n");
390d192f3d3SKai Wang 	(void)fprintf(stderr, "\tar -x [-CTouv] archive [file ...]\n");
391d192f3d3SKai Wang 	(void)fprintf(stderr, "\tar -V\n");
392d192f3d3SKai Wang 	exit(EX_USAGE);
393d192f3d3SKai Wang }
394d192f3d3SKai Wang 
395d192f3d3SKai Wang static void
396ef636796SEd Schouten ranlib_usage(void)
397d192f3d3SKai Wang {
398d192f3d3SKai Wang 
3997072861cSEd Maste 	(void)fprintf(stderr, "usage:	ranlib [-DtU] archive ...\n");
400d192f3d3SKai Wang 	(void)fprintf(stderr, "\tranlib -V\n");
401d192f3d3SKai Wang 	exit(EX_USAGE);
402d192f3d3SKai Wang }
403d192f3d3SKai Wang 
404d192f3d3SKai Wang static void
405ef636796SEd Schouten bsdar_version(void)
406d192f3d3SKai Wang {
4076c95142eSMartin Matuska 	(void)printf("BSD ar %s - %s\n", BSDAR_VERSION, archive_version_string());
408d192f3d3SKai Wang 	exit(EX_OK);
409d192f3d3SKai Wang }
410d192f3d3SKai Wang 
411d192f3d3SKai Wang static void
412ef636796SEd Schouten ranlib_version(void)
413d192f3d3SKai Wang {
4146c95142eSMartin Matuska 	(void)printf("ranlib %s - %s\n", BSDAR_VERSION, archive_version_string());
415d192f3d3SKai Wang 	exit(EX_OK);
416d192f3d3SKai Wang }
417