the ORPHANS macro sets eval on error, but does not clear it on success,
[unix-history] / usr / src / usr.bin / ar / ar.c
CommitLineData
4d882547
KB
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * 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 * %sccs.include.redist.c%
1f312495
DF
9 */
10
d059363b 11#ifndef lint
20104047 12char copyright[] =
4d882547 13"@(#) Copyright (c) 1990 The Regents of the University of California.\n\
20104047 14 All rights reserved.\n";
4d882547
KB
15#endif /* not lint */
16
17#ifndef lint
18static char sccsid[] = "@(#)ar.c 5.6 (Berkeley) %G%";
19#endif /* not lint */
828d5b76 20
15bdd757 21#include <sys/param.h>
4d882547
KB
22#include <sys/errno.h>
23#include <dirent.h>
828d5b76 24#include <stdio.h>
3d4622f1 25#include <ar.h>
4d882547
KB
26#include <paths.h>
27#include "archive.h"
be40ff3d 28
4d882547
KB
29CHDR chdr;
30u_int options;
31char *archive, *envtmp, *posname;
be40ff3d 32
4d882547
KB
33/*
34 * main --
35 * main basically uses getopt to parse options and calls the appropriate
36 * functions. Some hacks that let us be backward compatible with 4.3 ar
37 * option parsing and sanity checking.
38 */
be40ff3d 39main(argc, argv)
4d882547
KB
40 int argc;
41 char **argv;
be40ff3d 42{
4d882547
KB
43 extern int optind;
44 int c, rval;
45 char *p;
46 int (*fcall)(), append(), contents(), delete(), extract(),
47 move(), print(), replace();
48 char *rname();
be40ff3d 49
4d882547 50 if (argc < 3)
be40ff3d 51 usage();
be40ff3d 52
4d882547
KB
53 /*
54 * Historic versions didn't require a '-' in front of the options.
55 * Fix it, if necessary.
56 */
57 if (*argv[1] != '-') {
58 if (!(p = malloc((u_int)(strlen(argv[1]) + 2)))) {
59 (void)fprintf(stderr, "ar: %s.\n", strerror(errno));
60 exit(1);
61 }
62 *p = '-';
63 (void)strcpy(p + 1, argv[1]);
64 argv[1] = p;
65 }
66
67 while ((c = getopt(argc, argv, "abcdilmopqrtuvx")) != EOF) {
68 switch(c) {
69 case 'a':
70 options |= AR_A;
71 break;
72 case 'b':
73 case 'i':
74 options |= AR_B;
75 break;
76 case 'c':
77 options |= AR_C;
78 break;
79 case 'd':
80 options |= AR_D;
81 fcall = delete;
82 break;
83 case 'l': /* not documented, compatibility only */
84 envtmp = ".";
85 break;
86 case 'm':
87 options |= AR_M;
88 fcall = move;
89 break;
90 case 'o':
91 options |= AR_O;
92 break;
93 case 'p':
94 options |= AR_P;
95 fcall = print;
96 break;
97 case 'q':
98 options |= AR_Q;
99 fcall = append;
100 break;
101 case 'r':
102 options |= AR_R;
103 fcall = replace;
104 break;
105 case 't':
106 options |= AR_T;
107 fcall = contents;
108 break;
109 case 'u':
110 options |= AR_U;
111 break;
112 case 'v':
113 options |= AR_V;
114 break;
115 case 'x':
116 options |= AR_X;
117 fcall = extract;
118 break;
119 default:
be40ff3d 120 usage();
be40ff3d 121 }
be40ff3d 122 }
be40ff3d 123
4d882547
KB
124 argv += optind;
125 argc -= optind;
be40ff3d 126
4d882547
KB
127 /* One of -dmpqrtx required. */
128 if (!(options & (AR_D|AR_M|AR_P|AR_Q|AR_R|AR_T|AR_X))) {
129 (void)fprintf(stderr,
130 "ar: one of options -dmpqrtx is required.\n");
131 usage();
be40ff3d 132 }
4d882547
KB
133 /* Only one of -a and -bi. */
134 if (options & AR_A && options & AR_B) {
135 (void)fprintf(stderr,
136 "ar: only one of -a and -[bi] options allowed.\n");
137 usage();
be40ff3d 138 }
4d882547
KB
139 /* -ab require a position argument. */
140 if (options & (AR_A|AR_B)) {
141 if (!(posname = *argv++)) {
142 (void)fprintf(stderr,
143 "ar: no position operand specified.\n");
144 usage();
be40ff3d 145 }
4d882547
KB
146 posname = rname(posname);
147 }
148 /* -d only valid with -v. */
149 if (options & AR_D && options & ~(AR_D|AR_V))
150 badoptions("-d");
151 /* -m only valid with -abiv. */
152 if (options & AR_M && options & ~(AR_A|AR_B|AR_M|AR_V))
153 badoptions("-m");
154 /* -p only valid with -v. */
155 if (options & AR_P && options & ~(AR_P|AR_V))
156 badoptions("-p");
157 /* -q only valid with -cv. */
158 if (options & AR_Q && options & ~(AR_C|AR_Q|AR_V))
159 badoptions("-q");
160 /* -r only valid with -abcuv. */
161 if (options & AR_R && options & ~(AR_A|AR_B|AR_C|AR_R|AR_U|AR_V))
162 badoptions("-r");
163 /* -t only valid with -v. */
164 if (options & AR_T && options & ~(AR_T|AR_V))
165 badoptions("-t");
166 /* -x only valid with -ouv. */
167 if (options & AR_X && options & ~(AR_O|AR_U|AR_V|AR_X))
168 badoptions("-x");
169
170 if (!(archive = *argv++)) {
171 (void)fprintf(stderr, "ar: no archive specified.\n");
172 usage();
be40ff3d 173 }
be40ff3d 174
4d882547
KB
175 /* -dmqr require a list of archive elements. */
176 if (options & (AR_D|AR_M|AR_Q|AR_R) && !*argv) {
177 (void)fprintf(stderr, "ar: no archive members specified.\n");
178 usage();
be40ff3d 179 }
be40ff3d 180
4d882547
KB
181 rval = (*fcall)(argv);
182 exit(rval);
be40ff3d
BJ
183}
184
4d882547
KB
185badoptions(arg)
186 char *arg;
be40ff3d 187{
4d882547
KB
188 (void)fprintf(stderr,
189 "ar: illegal option combination for %s.\n", arg);
190 usage();
be40ff3d
BJ
191}
192
193usage()
194{
4d882547
KB
195 (void)fprintf(stderr, "usage: ar -d [-v] archive file ...\n");
196 (void)fprintf(stderr, "\tar -m [-v] archive file ...\n");
197 (void)fprintf(stderr, "\tar -m [-abiv] position archive file ...\n");
198 (void)fprintf(stderr, "\tar -p [-v] archive [file ...]\n");
199 (void)fprintf(stderr, "\tar -q [-cv] archive file ...\n");
200 (void)fprintf(stderr, "\tar -r [-cuv] archive file ...\n");
201 (void)fprintf(stderr, "\tar -r [-abciuv] position archive file ...\n");
202 (void)fprintf(stderr, "\tar -t [-v] archive [file ...]\n");
203 (void)fprintf(stderr, "\tar -x [-ouv] archive [file ...]\n");
204 exit(1);
205}