8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / sgs / ar / common / main.c
bloba452d403ffd2fbc64161da3734e4853738410ae6
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
21 /* Copyright (c) 1988 AT&T */
22 /* All Rights Reserved */
25 * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
28 #include "inc.h"
29 #include "conv.h"
32 * Forward declarations
34 static void setup(int, char **, Cmd_info *);
35 static void setcom(Cmd_info *, Cmd_func);
36 static void usage(void);
37 static void sigexit(int sig);
38 static int notfound(Cmd_info *);
39 static void check_swap();
41 const char *
42 _ar_msg(Msg mid)
44 return (gettext(MSG_ORIG(mid)));
48 void
49 establish_sighandler(void (*handler)())
51 static const int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
52 int i;
54 if (handler == SIG_IGN) {
55 /* Ignore all the specified signals */
56 for (i = 0; signum[i]; i++)
57 (void) signal(signum[i], SIG_IGN);
59 } else {
61 * Set any signal that doesn't default to being ignored
62 * to our signal handler.
64 for (i = 0; signum[i]; i++)
65 if (signal(signum[i], SIG_IGN) != SIG_IGN)
66 (void) signal(signum[i], handler);
70 int
71 main(int argc, char **argv, char *envp[])
73 int fd;
74 Cmd_info *cmd_info;
75 int ret;
76 char *new = NULL;
78 #ifndef XPG4
80 * Check for a binary that better fits this architecture.
82 (void) conv_check_native(argv, envp);
83 #endif
86 * Establish locale.
88 (void) setlocale(LC_ALL, MSG_ORIG(MSG_STR_EMPTY));
89 (void) textdomain(MSG_ORIG(MSG_SUNW_OST_SGS));
91 /* Allow a graceful exit up until we start to write an archive */
92 establish_sighandler(sigexit);
95 * Initialize cmd_info
97 cmd_info = (Cmd_info *)calloc(1, sizeof (Cmd_info));
98 if (cmd_info == NULL) {
99 int err = errno;
100 (void) fprintf(stderr, MSG_INTL(MSG_MALLOC), strerror(err));
101 exit(1);
104 if (argc < 2)
105 usage();
108 * Option handling.
110 if (argv[1][0] != '-') {
111 new = (char *)malloc(strlen(argv[1]) + 2);
112 if (new == NULL) {
113 int err = errno;
114 (void) fprintf(stderr, MSG_INTL(MSG_MALLOC),
115 strerror(err));
116 exit(1);
118 (void) strcpy(new, MSG_ORIG(MSG_STR_HYPHEN));
119 (void) strcat(new, argv[1]);
120 argv[1] = new;
122 setup(argc, argv, cmd_info);
125 * Check SWAP
127 if (cmd_info->opt_flgs & z_FLAG)
128 check_swap();
130 if (cmd_info->comfun == NULL) {
131 if ((cmd_info->opt_flgs & (d_FLAG | r_FLAG | q_FLAG |
132 t_FLAG | p_FLAG | m_FLAG | x_FLAG)) == 0) {
133 (void) fprintf(stderr, MSG_INTL(MSG_USAGE_01));
134 exit(1);
138 cmd_info->modified = (cmd_info->opt_flgs & s_FLAG);
139 fd = getaf(cmd_info);
141 if ((fd == -1) &&
142 (cmd_info->opt_flgs &
143 (d_FLAG | m_FLAG | p_FLAG | t_FLAG | x_FLAG)) ||
144 ((cmd_info->opt_flgs & r_FLAG) &&
145 (cmd_info->opt_flgs & (a_FLAG | b_FLAG)))) {
146 (void) fprintf(stderr, MSG_INTL(MSG_NOT_FOUND_AR),
147 cmd_info->arnam);
148 exit(1);
151 (*cmd_info->comfun)(cmd_info);
152 if (cmd_info->modified) {
153 writefile(cmd_info);
154 } else
155 (void) close(fd);
157 ret = notfound(cmd_info);
160 * Check SWAP
162 if (cmd_info->opt_flgs & z_FLAG)
163 check_swap();
165 free(new);
166 free(cmd_info);
167 return (ret);
172 * Option handing function.
173 * Using getopt(), following xcu4 convention.
175 static void
176 setup(int argc, char *argv[], Cmd_info *cmd_info)
178 int Vflag = 0;
179 int c;
180 int usage_err = 0;
182 while ((c = getopt(argc, argv, MSG_ORIG(MSG_STR_OPTIONS))) != -1) {
183 switch (c) {
184 case 'a': /* position after named archive member file */
185 cmd_info->opt_flgs |= a_FLAG;
186 cmd_info->ponam = trim(optarg);
187 break;
188 case 'b': /* position before named archive member file */
189 case 'i': /* position before named archive member: same as b */
190 cmd_info->opt_flgs |= b_FLAG;
191 cmd_info->ponam = trim(optarg);
192 break;
193 case 'c': /* supress messages */
194 cmd_info->opt_flgs |= c_FLAG;
195 break;
196 case 'd':
198 * key operation:
199 * delete files from the archive
201 setcom(cmd_info, dcmd);
202 cmd_info->opt_flgs |= d_FLAG;
203 break;
204 case 'l': /* ignored */
205 break;
206 case 'm':
208 * key operation:
209 * move files to end of the archive
210 * or as indicated by position flag
212 setcom(cmd_info, mcmd);
213 cmd_info->opt_flgs |= m_FLAG;
214 break;
215 case 'p':
217 * key operation:
218 * print files in the archive
220 setcom(cmd_info, pcmd);
221 cmd_info->opt_flgs |= p_FLAG;
222 break;
223 case 'q':
225 * key operation:
226 * quickly append files to end of the archive
228 setcom(cmd_info, qcmd);
229 cmd_info->opt_flgs |= q_FLAG;
230 break;
231 case 'r':
233 * key operation:
234 * replace or add files to the archive
236 setcom(cmd_info, rcmd);
237 cmd_info->opt_flgs |= r_FLAG;
238 break;
239 case 's': /* force symbol table regeneration */
240 cmd_info->opt_flgs |= s_FLAG;
241 break;
242 case 'S': /* Build SYM64 symbol table */
243 cmd_info->opt_flgs |= S_FLAG;
244 break;
245 case 't':
247 * key operation:
248 * print table of contents
250 setcom(cmd_info, tcmd);
251 cmd_info->opt_flgs |= t_FLAG;
252 break;
253 case 'u': /* update: change archive dependent on file dates */
254 cmd_info->opt_flgs |= u_FLAG;
255 break;
256 case 'v': /* verbose */
257 cmd_info->opt_flgs |= v_FLAG;
258 break;
259 case 'x':
261 * key operation:
262 * extract files from the archive
264 setcom(cmd_info, xcmd);
265 cmd_info->opt_flgs |= x_FLAG;
266 break;
267 case 'z':
268 cmd_info->opt_flgs |= z_FLAG;
269 break;
270 case 'V':
272 * print version information.
273 * adjust command line access accounting
275 if (Vflag == 0) {
276 (void) fprintf(stderr,
277 MSG_ORIG(MSG_FMT_VERSION),
278 (const char *)SGU_PKG,
279 (const char *)SGU_REL);
280 Vflag++;
282 break;
283 case 'C':
284 cmd_info->opt_flgs |= C_FLAG;
285 break;
286 case 'M':
288 * -M was an original undocumented AT&T feature that
289 * would force the use of mmap() instead of read()
290 * for pulling file data into the process before
291 * writing it to the archive. Ignored.
293 break;
294 case 'T':
295 cmd_info->opt_flgs |= T_FLAG;
296 break;
297 case ':':
298 (void) fprintf(stderr, MSG_INTL(MSG_USAGE_02), optopt);
299 usage_err++;
300 break;
301 case '?':
302 (void) fprintf(stderr, MSG_INTL(MSG_USAGE_03), optopt);
303 usage_err++;
304 break;
308 if (usage_err || argc - optind < 1)
309 usage();
311 cmd_info->arnam = argv[optind];
312 cmd_info->namv = &argv[optind+1];
313 cmd_info->namc = argc - optind - 1;
318 * Set the function to be called to do the key operation.
319 * Check that only one key is indicated.
321 static void
322 setcom(Cmd_info *cmd_info, Cmd_func *fun)
324 if (cmd_info->comfun != 0) {
325 (void) fprintf(stderr, MSG_INTL(MSG_USAGE_04));
326 exit(1);
328 cmd_info->comfun = fun;
331 static void
332 usage(void)
334 (void) fprintf(stderr, MSG_INTL(MSG_USAGE));
335 exit(1);
338 /*ARGSUSED0*/
339 static void
340 sigexit(int sig)
342 exit(100);
345 /* tells the user which of the listed files were not found in the archive */
347 static int
348 notfound(Cmd_info *cmd_info)
350 int i, n;
352 n = 0;
353 for (i = 0; i < cmd_info->namc; i++)
354 if (cmd_info->namv[i]) {
355 (void) fprintf(stderr, MSG_INTL(MSG_NOT_FOUND_FILE),
356 cmd_info->namv[i]);
357 n++;
359 return (n);
363 * Debugging info
365 static void
366 check_swap(void)
368 (void) system(MSG_ORIG(MSG_CMD_SWAP));