Remove __P macros from src/usr.bin and src/usr.sbin.
[dragonfly.git] / usr.bin / ar / ar.c
CommitLineData
984263bc
MD
1/*-
2 * Copyright (c) 1990, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Hugh Smith at The University of Guelph.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * $FreeBSD: src/usr.bin/ar/ar.c,v 1.8.2.1 2001/08/02 00:51:00 obrien Exp $
2d8a3be7 37 * $DragonFly: src/usr.bin/ar/Attic/ar.c,v 1.4 2003/11/03 19:31:28 eirikn Exp $
1de703da
MD
38 *
39 * @(#) Copyright (c) 1990, 1993, 1994 The Regents of the University of California. All rights reserved.
40 * @(#)ar.c 8.3 (Berkeley) 4/2/94
984263bc
MD
41 */
42
984263bc
MD
43#include <sys/param.h>
44
45#include <ar.h>
46#include <dirent.h>
47#include <err.h>
48#include <libgen.h>
49#include <paths.h>
50#include <stdio.h>
51#include <stdlib.h>
52#include <string.h>
53#include <unistd.h>
54#include <locale.h>
55
56#include "archive.h"
57#include "extern.h"
58
59CHDR chdr;
60u_int options;
61char *archive, *envtmp, *posarg, *posname;
2d8a3be7
EN
62static void badoptions(char *);
63static void usage(void);
984263bc
MD
64
65/*
66 * main --
67 * main basically uses getopt to parse options and calls the appropriate
68 * functions. Some hacks that let us be backward compatible with 4.3 ar
69 * option parsing and sanity checking.
70 */
71int
16777b6b 72main(int argc, char **argv)
984263bc
MD
73{
74 int c;
75 char *p;
2d8a3be7 76 int (*fcall)(char **) = NULL;
984263bc
MD
77
78 (void) setlocale(LC_TIME, "");;
79
80 if (argc < 3)
81 usage();
82
83 /*
84 * Historic versions didn't require a '-' in front of the options.
85 * Fix it, if necessary.
86 */
87 if (*argv[1] != '-') {
88 if (!(p = malloc((u_int)(strlen(argv[1]) + 2))))
89 err(1, NULL);
90 *p = '-';
91 (void)strcpy(p + 1, argv[1]);
92 argv[1] = p;
93 }
94
95 while ((c = getopt(argc, argv, "abcdilmopqrTtuvx")) != -1) {
96 switch(c) {
97 case 'a':
98 options |= AR_A;
99 break;
100 case 'b':
101 case 'i':
102 options |= AR_B;
103 break;
104 case 'c':
105 options |= AR_C;
106 break;
107 case 'd':
108 options |= AR_D;
109 fcall = delete;
110 break;
111 case 'l': /* not documented, compatibility only */
112 envtmp = ".";
113 break;
114 case 'm':
115 options |= AR_M;
116 fcall = move;
117 break;
118 case 'o':
119 options |= AR_O;
120 break;
121 case 'p':
122 options |= AR_P;
123 fcall = print;
124 break;
125 case 'q':
126 options |= AR_Q;
127 fcall = append;
128 break;
129 case 'r':
130 options |= AR_R;
131 fcall = replace;
132 break;
133 case 'T':
134 options |= AR_TR;
135 break;
136 case 't':
137 options |= AR_T;
138 fcall = contents;
139 break;
140 case 'u':
141 options |= AR_U;
142 break;
143 case 'v':
144 options |= AR_V;
145 break;
146 case 'x':
147 options |= AR_X;
148 fcall = extract;
149 break;
150 default:
151 usage();
152 }
153 }
154
155 argv += optind;
156 argc -= optind;
157
158 /* One of -dmpqrtx required. */
159 if (!(options & (AR_D|AR_M|AR_P|AR_Q|AR_R|AR_T|AR_X))) {
160 warnx("one of options -dmpqrtx is required");
161 usage();
162 }
163 /* Only one of -a and -bi allowed. */
164 if (options & AR_A && options & AR_B) {
165 warnx("only one of -a and -[bi] options allowed");
166 usage();
167 }
168 /* -ab require a position argument. */
169 if (options & (AR_A|AR_B)) {
170 if (!(posarg = *argv++)) {
171 warnx("no position operand specified");
172 usage();
173 }
174 posname = basename(posarg);
175 }
176 /* -d only valid with -Tv. */
177 if (options & AR_D && options & ~(AR_D|AR_TR|AR_V))
178 badoptions("-d");
179 /* -m only valid with -abiTv. */
180 if (options & AR_M && options & ~(AR_A|AR_B|AR_M|AR_TR|AR_V))
181 badoptions("-m");
182 /* -p only valid with -Tv. */
183 if (options & AR_P && options & ~(AR_P|AR_TR|AR_V))
184 badoptions("-p");
185 /* -q only valid with -cTv. */
186 if (options & AR_Q && options & ~(AR_C|AR_Q|AR_TR|AR_V))
187 badoptions("-q");
188 /* -r only valid with -abcuTv. */
189 if (options & AR_R && options & ~(AR_A|AR_B|AR_C|AR_R|AR_U|AR_TR|AR_V))
190 badoptions("-r");
191 /* -t only valid with -Tv. */
192 if (options & AR_T && options & ~(AR_T|AR_TR|AR_V))
193 badoptions("-t");
194 /* -x only valid with -ouTv. */
195 if (options & AR_X && options & ~(AR_O|AR_U|AR_TR|AR_V|AR_X))
196 badoptions("-x");
197
198 if (!(archive = *argv++)) {
199 warnx("no archive specified");
200 usage();
201 }
202
203 /* -dmr require a list of archive elements. */
204 if (options & (AR_D|AR_M|AR_R) && !*argv) {
205 warnx("no archive members specified");
206 usage();
207 }
208
209 exit((*fcall)(argv));
210}
211
212static void
16777b6b 213badoptions(char *arg)
984263bc
MD
214{
215
216 warnx("illegal option combination for %s", arg);
217 usage();
218}
219
220static void
16777b6b 221usage(void)
984263bc
MD
222{
223
224 (void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
225 "usage: ar -d [-Tv] archive file ...",
226 " ar -m [-Tv] archive file ...",
227 " ar -m [-abiTv] position archive file ...",
228 " ar -p [-Tv] archive [file ...]",
229 " ar -q [-cTv] archive file ...",
230 " ar -r [-cuTv] archive file ...",
231 " ar -r [-abciuTv] position archive file ...",
232 " ar -t [-Tv] archive [file ...]",
233 " ar -x [-ouTv] archive [file ...]");
234 exit(1);
235}