xref: /freebsd/contrib/elftoolchain/ar/ar.c (revision 839529caa9c35f92b638dbe074655598e7a6bb6f)
13fe401a5SEd Maste /*-
23fe401a5SEd Maste  * Copyright (c) 2007 Kai Wang
33fe401a5SEd Maste  * Copyright (c) 2007 Tim Kientzle
43fe401a5SEd Maste  * Copyright (c) 2007 Joseph Koshy
53fe401a5SEd Maste  * All rights reserved.
63fe401a5SEd Maste  *
73fe401a5SEd Maste  * Redistribution and use in source and binary forms, with or without
83fe401a5SEd Maste  * modification, are permitted provided that the following conditions
93fe401a5SEd Maste  * are met:
103fe401a5SEd Maste  * 1. Redistributions of source code must retain the above copyright
113fe401a5SEd Maste  *    notice, this list of conditions and the following disclaimer
123fe401a5SEd Maste  *    in this position and unchanged.
133fe401a5SEd Maste  * 2. Redistributions in binary form must reproduce the above copyright
143fe401a5SEd Maste  *    notice, this list of conditions and the following disclaimer in the
153fe401a5SEd Maste  *    documentation and/or other materials provided with the distribution.
163fe401a5SEd Maste  *
173fe401a5SEd Maste  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
183fe401a5SEd Maste  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
193fe401a5SEd Maste  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
203fe401a5SEd Maste  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
213fe401a5SEd Maste  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
223fe401a5SEd Maste  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233fe401a5SEd Maste  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243fe401a5SEd Maste  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253fe401a5SEd Maste  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
263fe401a5SEd Maste  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273fe401a5SEd Maste  */
283fe401a5SEd Maste 
293fe401a5SEd Maste /*-
303fe401a5SEd Maste  * Copyright (c) 1990, 1993, 1994
313fe401a5SEd Maste  *	The Regents of the University of California.  All rights reserved.
323fe401a5SEd Maste  *
333fe401a5SEd Maste  * This code is derived from software contributed to Berkeley by
343fe401a5SEd Maste  * Hugh Smith at The University of Guelph.
353fe401a5SEd Maste  *
363fe401a5SEd Maste  * Redistribution and use in source and binary forms, with or without
373fe401a5SEd Maste  * modification, are permitted provided that the following conditions
383fe401a5SEd Maste  * are met:
393fe401a5SEd Maste  * 1. Redistributions of source code must retain the above copyright
403fe401a5SEd Maste  *    notice, this list of conditions and the following disclaimer.
413fe401a5SEd Maste  * 2. Redistributions in binary form must reproduce the above copyright
423fe401a5SEd Maste  *    notice, this list of conditions and the following disclaimer in the
433fe401a5SEd Maste  *    documentation and/or other materials provided with the distribution.
443fe401a5SEd Maste  * 3. Neither the name of the University nor the names of its contributors
453fe401a5SEd Maste  *    may be used to endorse or promote products derived from this software
463fe401a5SEd Maste  *    without specific prior written permission.
473fe401a5SEd Maste  *
483fe401a5SEd Maste  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
493fe401a5SEd Maste  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
503fe401a5SEd Maste  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
513fe401a5SEd Maste  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
523fe401a5SEd Maste  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
533fe401a5SEd Maste  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
543fe401a5SEd Maste  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
553fe401a5SEd Maste  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
563fe401a5SEd Maste  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
573fe401a5SEd Maste  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
583fe401a5SEd Maste  * SUCH DAMAGE.
593fe401a5SEd Maste  */
603fe401a5SEd Maste 
613fe401a5SEd Maste #include <sys/queue.h>
623fe401a5SEd Maste #include <sys/types.h>
633fe401a5SEd Maste #include <archive.h>
643fe401a5SEd Maste #include <errno.h>
653fe401a5SEd Maste #include <getopt.h>
663fe401a5SEd Maste #include <libelftc.h>
673fe401a5SEd Maste #include <libgen.h>
683fe401a5SEd Maste #include <stdio.h>
693fe401a5SEd Maste #include <stdlib.h>
703fe401a5SEd Maste #include <stdint.h>
713fe401a5SEd Maste #include <string.h>
723fe401a5SEd Maste 
733fe401a5SEd Maste #include "ar.h"
743fe401a5SEd Maste 
75*839529caSEd Maste ELFTC_VCSID("$Id: ar.c 3319 2016-01-13 21:37:53Z jkoshy $");
763fe401a5SEd Maste 
773fe401a5SEd Maste enum options
783fe401a5SEd Maste {
793fe401a5SEd Maste 	OPTION_HELP
803fe401a5SEd Maste };
813fe401a5SEd Maste 
823fe401a5SEd Maste static struct option longopts[] =
833fe401a5SEd Maste {
843fe401a5SEd Maste 	{"flavor", required_argument, NULL, 'F'},
853fe401a5SEd Maste 	{"help", no_argument, NULL, OPTION_HELP},
863fe401a5SEd Maste 	{"version", no_argument, NULL, 'V'},
873fe401a5SEd Maste 	{NULL, 0, NULL, 0}
883fe401a5SEd Maste };
893fe401a5SEd Maste 
903fe401a5SEd Maste static void	bsdar_usage(void);
913fe401a5SEd Maste static void	ranlib_usage(void);
923fe401a5SEd Maste static void	set_mode(struct bsdar *bsdar, char opt);
933fe401a5SEd Maste static void	only_mode(struct bsdar *bsdar, const char *opt,
943fe401a5SEd Maste 		    const char *valid_modes);
953fe401a5SEd Maste static void	bsdar_version(void);
963fe401a5SEd Maste 
973fe401a5SEd Maste int
983fe401a5SEd Maste main(int argc, char **argv)
993fe401a5SEd Maste {
1003fe401a5SEd Maste 	struct bsdar	*bsdar, bsdar_storage;
1013fe401a5SEd Maste 	char		*arcmd, *argv1_saved;
1023fe401a5SEd Maste 	size_t		 len;
1033fe401a5SEd Maste 	int		 i, opt;
1043fe401a5SEd Maste 
1053fe401a5SEd Maste 	bsdar = &bsdar_storage;
1063fe401a5SEd Maste 	memset(bsdar, 0, sizeof(*bsdar));
1073fe401a5SEd Maste 
1083fe401a5SEd Maste 	arcmd = argv1_saved = NULL;
1093fe401a5SEd Maste 	bsdar->output = stdout;
1103fe401a5SEd Maste 
1113fe401a5SEd Maste 	if ((bsdar->progname = ELFTC_GETPROGNAME()) == NULL)
1123fe401a5SEd Maste 		bsdar->progname = "ar";
1133fe401a5SEd Maste 
1143fe401a5SEd Maste 	if (elf_version(EV_CURRENT) == EV_NONE)
1153fe401a5SEd Maste 		bsdar_errc(bsdar, 0, "ELF library initialization failed: %s",
1163fe401a5SEd Maste 		    elf_errmsg(-1));
1173fe401a5SEd Maste 
1183fe401a5SEd Maste 	/*
1193fe401a5SEd Maste 	 * Act like ranlib if our name ends in "ranlib"; this
1203fe401a5SEd Maste 	 * accommodates names like "arm-freebsd7.1-ranlib",
1213fe401a5SEd Maste 	 * "bsdranlib", etc.
1223fe401a5SEd Maste 	 */
1233fe401a5SEd Maste 	len = strlen(bsdar->progname);
1243fe401a5SEd Maste 	if (len >= strlen("ranlib") &&
1253fe401a5SEd Maste 	    strcmp(bsdar->progname + len - strlen("ranlib"), "ranlib") == 0) {
126656f49f8SEd Maste 		while ((opt = getopt_long(argc, argv, "tDUV", longopts,
1273fe401a5SEd Maste 		    NULL)) != -1) {
1283fe401a5SEd Maste 			switch(opt) {
1293fe401a5SEd Maste 			case 't':
1303fe401a5SEd Maste 				/* Ignored. */
1313fe401a5SEd Maste 				break;
1323fe401a5SEd Maste 			case 'D':
1333fe401a5SEd Maste 				bsdar->options |= AR_D;
1343fe401a5SEd Maste 				break;
135656f49f8SEd Maste 			case 'U':
136656f49f8SEd Maste 				bsdar->options &= ~AR_D;
137656f49f8SEd Maste 				break;
1383fe401a5SEd Maste 			case 'V':
1393fe401a5SEd Maste 				bsdar_version();
1403fe401a5SEd Maste 				break;
1413fe401a5SEd Maste 			case OPTION_HELP:
1423fe401a5SEd Maste 				ranlib_usage();
1433fe401a5SEd Maste 			default:
1443fe401a5SEd Maste 				ranlib_usage();
1453fe401a5SEd Maste 			}
1463fe401a5SEd Maste 		}
1473fe401a5SEd Maste 		argv += optind;
1483fe401a5SEd Maste 		argc -= optind;
1493fe401a5SEd Maste 
1503fe401a5SEd Maste 		if (*argv == NULL)
1513fe401a5SEd Maste 			ranlib_usage();
1523fe401a5SEd Maste 
1533fe401a5SEd Maste 		bsdar->options |= AR_S;
154656f49f8SEd Maste 		while ((bsdar->filename = *argv++) != NULL)
1553fe401a5SEd Maste 			ar_write_archive(bsdar, 's');
1563fe401a5SEd Maste 
1573fe401a5SEd Maste 		exit(EXIT_SUCCESS);
1583fe401a5SEd Maste 	} else {
1593fe401a5SEd Maste 		if (argc < 2)
1603fe401a5SEd Maste 			bsdar_usage();
1613fe401a5SEd Maste 
1623fe401a5SEd Maste 		/*
1633fe401a5SEd Maste 		 * Tack on a leading '-', for old-style usage.
1643fe401a5SEd Maste 		 */
1653fe401a5SEd Maste 		if (*argv[1] != '-') {
1663fe401a5SEd Maste 			argv1_saved = argv[1];
1673fe401a5SEd Maste 			len = strlen(argv[1]) + 2;
1683fe401a5SEd Maste 			if ((arcmd = malloc(len)) == NULL)
1693fe401a5SEd Maste 				bsdar_errc(bsdar, errno, "malloc failed");
1703fe401a5SEd Maste 			(void) snprintf(arcmd, len, "-%s", argv[1]);
1713fe401a5SEd Maste 			argv[1] = arcmd;
1723fe401a5SEd Maste 		}
1733fe401a5SEd Maste 	}
1743fe401a5SEd Maste 
175656f49f8SEd Maste 	while ((opt = getopt_long(argc, argv, "abCcdDfF:ijlMmopqrSsTtUuVvxz",
1763fe401a5SEd Maste 	    longopts, NULL)) != -1) {
1773fe401a5SEd Maste 		switch(opt) {
1783fe401a5SEd Maste 		case 'a':
1793fe401a5SEd Maste 			bsdar->options |= AR_A;
1803fe401a5SEd Maste 			break;
1813fe401a5SEd Maste 		case 'b':
1823fe401a5SEd Maste 		case 'i':
1833fe401a5SEd Maste 			bsdar->options |= AR_B;
1843fe401a5SEd Maste 			break;
1853fe401a5SEd Maste 		case 'C':
1863fe401a5SEd Maste 			bsdar->options |= AR_CC;
1873fe401a5SEd Maste 			break;
1883fe401a5SEd Maste 		case 'c':
1893fe401a5SEd Maste 			bsdar->options |= AR_C;
1903fe401a5SEd Maste 			break;
1913fe401a5SEd Maste 		case 'd':
1923fe401a5SEd Maste 			set_mode(bsdar, opt);
1933fe401a5SEd Maste 			break;
1943fe401a5SEd Maste 		case 'D':
1953fe401a5SEd Maste 			bsdar->options |= AR_D;
1963fe401a5SEd Maste 			break;
1973fe401a5SEd Maste 		case 'F':
1983fe401a5SEd Maste 			if (!strcasecmp(optarg, "svr4") ||
1993fe401a5SEd Maste 			    !strcasecmp(optarg, "gnu"))
2003fe401a5SEd Maste 				bsdar->options &= ~AR_BSD;
2013fe401a5SEd Maste 			else if (!strcasecmp(optarg, "bsd"))
2023fe401a5SEd Maste 				bsdar->options |= AR_BSD;
2033fe401a5SEd Maste 			else
2043fe401a5SEd Maste 				bsdar_usage();
2053fe401a5SEd Maste 			break;
2063fe401a5SEd Maste 		case 'f':
2073fe401a5SEd Maste 		case 'T':
2083fe401a5SEd Maste 			bsdar->options |= AR_TR;
2093fe401a5SEd Maste 			break;
2103fe401a5SEd Maste 		case 'j':
2113fe401a5SEd Maste 			/* ignored */
2123fe401a5SEd Maste 			break;
2133fe401a5SEd Maste 		case 'l':
2143fe401a5SEd Maste 			/* ignored, for GNU ar comptibility */
2153fe401a5SEd Maste 			break;
2163fe401a5SEd Maste 		case 'M':
2173fe401a5SEd Maste 			set_mode(bsdar, opt);
2183fe401a5SEd Maste 			break;
2193fe401a5SEd Maste 		case 'm':
2203fe401a5SEd Maste 			set_mode(bsdar, opt);
2213fe401a5SEd Maste 			break;
2223fe401a5SEd Maste 		case 'o':
2233fe401a5SEd Maste 			bsdar->options |= AR_O;
2243fe401a5SEd Maste 			break;
2253fe401a5SEd Maste 		case 'p':
2263fe401a5SEd Maste 			set_mode(bsdar, opt);
2273fe401a5SEd Maste 			break;
2283fe401a5SEd Maste 		case 'q':
2293fe401a5SEd Maste 			set_mode(bsdar, opt);
2303fe401a5SEd Maste 			break;
2313fe401a5SEd Maste 		case 'r':
2323fe401a5SEd Maste 			set_mode(bsdar, opt);
2333fe401a5SEd Maste 			break;
2343fe401a5SEd Maste 		case 'S':
2353fe401a5SEd Maste 			bsdar->options |= AR_SS;
2363fe401a5SEd Maste 			break;
2373fe401a5SEd Maste 		case 's':
2383fe401a5SEd Maste 			bsdar->options |= AR_S;
2393fe401a5SEd Maste 			break;
2403fe401a5SEd Maste 		case 't':
2413fe401a5SEd Maste 			set_mode(bsdar, opt);
2423fe401a5SEd Maste 			break;
243656f49f8SEd Maste 		case 'U':
244656f49f8SEd Maste 			bsdar->options &= ~AR_D;
245656f49f8SEd Maste 			break;
2463fe401a5SEd Maste 		case 'u':
2473fe401a5SEd Maste 			bsdar->options |= AR_U;
2483fe401a5SEd Maste 			break;
2493fe401a5SEd Maste 		case 'V':
2503fe401a5SEd Maste 			bsdar_version();
2513fe401a5SEd Maste 			break;
2523fe401a5SEd Maste 		case 'v':
2533fe401a5SEd Maste 			bsdar->options |= AR_V;
2543fe401a5SEd Maste 			break;
2553fe401a5SEd Maste 		case 'x':
2563fe401a5SEd Maste 			set_mode(bsdar, opt);
2573fe401a5SEd Maste 			break;
2583fe401a5SEd Maste 		case 'z':
2593fe401a5SEd Maste 			/* ignored */
2603fe401a5SEd Maste 			break;
2613fe401a5SEd Maste 		case OPTION_HELP:
2623fe401a5SEd Maste 			bsdar_usage();
2633fe401a5SEd Maste 		default:
2643fe401a5SEd Maste 			bsdar_usage();
2653fe401a5SEd Maste 		}
2663fe401a5SEd Maste 	}
2673fe401a5SEd Maste 
2683fe401a5SEd Maste 	/* Restore argv[1] if we had modified it. */
2693fe401a5SEd Maste 	if (arcmd != NULL) {
2703fe401a5SEd Maste 		argv[1] = argv1_saved;
2713fe401a5SEd Maste 		free(arcmd);
2723fe401a5SEd Maste 		arcmd = argv1_saved = NULL;
2733fe401a5SEd Maste 	}
2743fe401a5SEd Maste 
2753fe401a5SEd Maste 	argv += optind;
2763fe401a5SEd Maste 	argc -= optind;
2773fe401a5SEd Maste 
2783fe401a5SEd Maste 	if (*argv == NULL && bsdar->mode != 'M')
2793fe401a5SEd Maste 		bsdar_usage();
2803fe401a5SEd Maste 
2813fe401a5SEd Maste 	if (bsdar->options & AR_A && bsdar->options & AR_B)
2823fe401a5SEd Maste 		bsdar_errc(bsdar, 0,
2833fe401a5SEd Maste 		    "only one of -a and -[bi] options allowed");
2843fe401a5SEd Maste 
2853fe401a5SEd Maste 	if (bsdar->options & AR_J && bsdar->options & AR_Z)
2863fe401a5SEd Maste 		bsdar_errc(bsdar, 0,
2873fe401a5SEd Maste 		    "only one of -j and -z options allowed");
2883fe401a5SEd Maste 
2893fe401a5SEd Maste 	if (bsdar->options & AR_S && bsdar->options & AR_SS)
2903fe401a5SEd Maste 		bsdar_errc(bsdar, 0,
2913fe401a5SEd Maste 		    "only one of -s and -S options allowed");
2923fe401a5SEd Maste 
2933fe401a5SEd Maste 	if (bsdar->options & (AR_A | AR_B)) {
2943fe401a5SEd Maste 		if (*argv == NULL)
2953fe401a5SEd Maste 			bsdar_errc(bsdar, 0,
2963fe401a5SEd Maste 			    "no position operand specified");
2973fe401a5SEd Maste 		if ((bsdar->posarg = basename(*argv)) == NULL)
2983fe401a5SEd Maste 			bsdar_errc(bsdar, errno,
2993fe401a5SEd Maste 			    "basename failed");
3003fe401a5SEd Maste 		argc--;
3013fe401a5SEd Maste 		argv++;
3023fe401a5SEd Maste 	}
3033fe401a5SEd Maste 
3043fe401a5SEd Maste 	if (bsdar->options & AR_A)
3053fe401a5SEd Maste 		only_mode(bsdar, "-a", "mqr");
3063fe401a5SEd Maste 	if (bsdar->options & AR_B)
3073fe401a5SEd Maste 		only_mode(bsdar, "-b", "mqr");
3083fe401a5SEd Maste 	if (bsdar->options & AR_C)
3093fe401a5SEd Maste 		only_mode(bsdar, "-c", "qr");
3103fe401a5SEd Maste 	if (bsdar->options & AR_CC)
3113fe401a5SEd Maste 		only_mode(bsdar, "-C", "x");
3123fe401a5SEd Maste 	if (bsdar->options & AR_D)
3133fe401a5SEd Maste 		only_mode(bsdar, "-D", "qr");
3143fe401a5SEd Maste 	if (bsdar->options & AR_O)
3153fe401a5SEd Maste 		only_mode(bsdar, "-o", "x");
3163fe401a5SEd Maste 	if (bsdar->options & AR_SS)
3173fe401a5SEd Maste 		only_mode(bsdar, "-S", "mqr");
3183fe401a5SEd Maste 	if (bsdar->options & AR_U)
3193fe401a5SEd Maste 		only_mode(bsdar, "-u", "qrx");
3203fe401a5SEd Maste 
3213fe401a5SEd Maste 	if (bsdar->mode == 'M') {
3223fe401a5SEd Maste 		ar_mode_script(bsdar);
3233fe401a5SEd Maste 		exit(EXIT_SUCCESS);
3243fe401a5SEd Maste 	}
3253fe401a5SEd Maste 
3263fe401a5SEd Maste 	if ((bsdar->filename = *argv) == NULL)
3273fe401a5SEd Maste 		bsdar_usage();
3283fe401a5SEd Maste 
3293fe401a5SEd Maste 	bsdar->argc = --argc;
3303fe401a5SEd Maste 	bsdar->argv = ++argv;
3313fe401a5SEd Maste 
3323fe401a5SEd Maste 	if ((!bsdar->mode || strchr("ptx", bsdar->mode)) &&
3333fe401a5SEd Maste 	    bsdar->options & AR_S) {
3343fe401a5SEd Maste 		ar_write_archive(bsdar, 's');
3353fe401a5SEd Maste 		if (!bsdar->mode)
3363fe401a5SEd Maste 			exit(EXIT_SUCCESS);
3373fe401a5SEd Maste 	}
3383fe401a5SEd Maste 
3393fe401a5SEd Maste 	switch(bsdar->mode) {
3403fe401a5SEd Maste 	case 'd': case 'm': case 'q': case 'r':
3413fe401a5SEd Maste 		ar_write_archive(bsdar, bsdar->mode);
3423fe401a5SEd Maste 		break;
3433fe401a5SEd Maste 
3443fe401a5SEd Maste 	case 'p': case 't': case 'x':
3453fe401a5SEd Maste 		ar_read_archive(bsdar, bsdar->mode);
3463fe401a5SEd Maste 		break;
3473fe401a5SEd Maste 	default:
3483fe401a5SEd Maste 		bsdar_usage();
3493fe401a5SEd Maste 		/* NOTREACHED */
3503fe401a5SEd Maste 	}
3513fe401a5SEd Maste 
3523fe401a5SEd Maste 	for (i = 0; i < bsdar->argc; i++)
3533fe401a5SEd Maste 		if (bsdar->argv[i] != NULL)
3543fe401a5SEd Maste 			bsdar_warnc(bsdar, 0, "%s: not found in archive",
3553fe401a5SEd Maste 			    bsdar->argv[i]);
3563fe401a5SEd Maste 
3573fe401a5SEd Maste 	exit(EXIT_SUCCESS);
3583fe401a5SEd Maste }
3593fe401a5SEd Maste 
3603fe401a5SEd Maste static void
3613fe401a5SEd Maste set_mode(struct bsdar *bsdar, char opt)
3623fe401a5SEd Maste {
3633fe401a5SEd Maste 
3643fe401a5SEd Maste 	if (bsdar->mode != '\0' && bsdar->mode != opt)
3653fe401a5SEd Maste 		bsdar_errc(bsdar, 0, "Can't specify both -%c and -%c",
3663fe401a5SEd Maste 		    opt, bsdar->mode);
3673fe401a5SEd Maste 	bsdar->mode = opt;
3683fe401a5SEd Maste }
3693fe401a5SEd Maste 
3703fe401a5SEd Maste static void
3713fe401a5SEd Maste only_mode(struct bsdar *bsdar, const char *opt, const char *valid_modes)
3723fe401a5SEd Maste {
3733fe401a5SEd Maste 
3743fe401a5SEd Maste 	if (strchr(valid_modes, bsdar->mode) == NULL)
3753fe401a5SEd Maste 		bsdar_errc(bsdar, 0, "Option %s is not permitted in mode -%c",
3763fe401a5SEd Maste 		    opt, bsdar->mode);
3773fe401a5SEd Maste }
3783fe401a5SEd Maste 
3793fe401a5SEd Maste #define	AR_USAGE_MESSAGE	"\
3803fe401a5SEd Maste Usage: %s <command> [options] archive file...\n\
3813fe401a5SEd Maste   Manage archives.\n\n\
3823fe401a5SEd Maste   Where <command> is one of:\n\
3833fe401a5SEd Maste   -d            Delete members from the archive.\n\
3843fe401a5SEd Maste   -m            Move archive members within the archive.\n\
3853fe401a5SEd Maste   -p            Write the contents of members to standard output.\n\
3863fe401a5SEd Maste   -q            Append files to an archive.\n\
3873fe401a5SEd Maste   -r            Replace (add) files to an archive.\n\
3883fe401a5SEd Maste   -s            Add an archive symbol to an archive.\n\
3893fe401a5SEd Maste   -t            List files in an archive.\n\
3903fe401a5SEd Maste   -x            Extract members from an archive.\n\
3913fe401a5SEd Maste   -M            Execute MRI librarian commands.\n\
3923fe401a5SEd Maste   -V            Print a version identifier and exit.\n\n\
3933fe401a5SEd Maste   Options:\n\
3943fe401a5SEd Maste   -a MEMBER     Add members after the specified member.\n\
3953fe401a5SEd Maste   -b MEMBER | -i MEMBER\n\
3963fe401a5SEd Maste                 Add members before the specified member.\n\
3973fe401a5SEd Maste   -c            Do not print a message when creating a new archive.\n\
3983fe401a5SEd Maste   -f | -T       Only use the first fifteen characters of the member name.\n\
3993fe401a5SEd Maste   -j            (This option is accepted, but is ignored).\n\
4003fe401a5SEd Maste   -l            (This option is accepted, but is ignored).\n\
4013fe401a5SEd Maste   -o            Preserve modification times when extracting members.\n\
4023fe401a5SEd Maste   -u            Conditionally update or extract members.\n\
4033fe401a5SEd Maste   -v            Be verbose.\n\
4043fe401a5SEd Maste   -z            (This option is accepted, but is ignored).\n\
4053fe401a5SEd Maste   -C            Do not overwrite existing files in the file system.\n\
4063fe401a5SEd Maste   -D            Use fixed metadata, for consistent archive checksums.\n\
4073fe401a5SEd Maste   -F FORMAT | --flavor=FORMAT\n\
4083fe401a5SEd Maste                 Create archives with the specified format.\n\
409656f49f8SEd Maste   -S            Do not generate an archive symbol table.\n\
410*839529caSEd Maste   -U            Use original metadata for archive members.\n"
4113fe401a5SEd Maste 
4123fe401a5SEd Maste static void
4133fe401a5SEd Maste bsdar_usage(void)
4143fe401a5SEd Maste {
4153fe401a5SEd Maste 	(void) fprintf(stderr, AR_USAGE_MESSAGE, ELFTC_GETPROGNAME());
4163fe401a5SEd Maste 	exit(EXIT_FAILURE);
4173fe401a5SEd Maste }
4183fe401a5SEd Maste 
4193fe401a5SEd Maste #define	RANLIB_USAGE_MESSAGE	"\
4203fe401a5SEd Maste Usage: %s [options] archive...\n\
4213fe401a5SEd Maste   Update or create archive symbol tables.\n\n\
4223fe401a5SEd Maste   Options:\n\
4233fe401a5SEd Maste   -t              (This option is accepted, but ignored).\n\
4243fe401a5SEd Maste   -D              Use fixed metadata, for consistent archive checksums.\n\
425656f49f8SEd Maste   -U              Use original metadata, for unique archive checksums.\n\
4263fe401a5SEd Maste   -V              Print a version identifier and exit.\n"
4273fe401a5SEd Maste 
4283fe401a5SEd Maste static void
4293fe401a5SEd Maste ranlib_usage(void)
4303fe401a5SEd Maste {
4313fe401a5SEd Maste 	(void)fprintf(stderr, RANLIB_USAGE_MESSAGE, ELFTC_GETPROGNAME());
4323fe401a5SEd Maste 	exit(EXIT_FAILURE);
4333fe401a5SEd Maste }
4343fe401a5SEd Maste 
4353fe401a5SEd Maste static void
4363fe401a5SEd Maste bsdar_version(void)
4373fe401a5SEd Maste {
4383fe401a5SEd Maste 	(void)printf("%s (%s, %s)\n", ELFTC_GETPROGNAME(), archive_version_string(),
4393fe401a5SEd Maste 	    elftc_version());
4403fe401a5SEd Maste 	exit(EXIT_SUCCESS);
4413fe401a5SEd Maste }
442