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]
21 /* Copyright (c) 1988 AT&T */
22 /* All Rights Reserved */
25 * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
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();
44 return (gettext(MSG_ORIG(mid
)));
49 establish_sighandler(void (*handler
)())
51 static const int signum
[] = {SIGHUP
, SIGINT
, SIGQUIT
, 0};
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
);
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
);
71 main(int argc
, char **argv
, char *envp
[])
80 * Check for a binary that better fits this architecture.
82 (void) conv_check_native(argv
, envp
);
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
);
97 cmd_info
= (Cmd_info
*)calloc(1, sizeof (Cmd_info
));
98 if (cmd_info
== NULL
) {
100 (void) fprintf(stderr
, MSG_INTL(MSG_MALLOC
), strerror(err
));
110 if (argv
[1][0] != '-') {
111 new = (char *)malloc(strlen(argv
[1]) + 2);
114 (void) fprintf(stderr
, MSG_INTL(MSG_MALLOC
),
118 (void) strcpy(new, MSG_ORIG(MSG_STR_HYPHEN
));
119 (void) strcat(new, argv
[1]);
122 setup(argc
, argv
, cmd_info
);
127 if (cmd_info
->opt_flgs
& z_FLAG
)
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
));
138 cmd_info
->modified
= (cmd_info
->opt_flgs
& s_FLAG
);
139 fd
= getaf(cmd_info
);
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
),
151 (*cmd_info
->comfun
)(cmd_info
);
152 if (cmd_info
->modified
) {
157 ret
= notfound(cmd_info
);
162 if (cmd_info
->opt_flgs
& z_FLAG
)
172 * Option handing function.
173 * Using getopt(), following xcu4 convention.
176 setup(int argc
, char *argv
[], Cmd_info
*cmd_info
)
182 while ((c
= getopt(argc
, argv
, MSG_ORIG(MSG_STR_OPTIONS
))) != -1) {
184 case 'a': /* position after named archive member file */
185 cmd_info
->opt_flgs
|= a_FLAG
;
186 cmd_info
->ponam
= trim(optarg
);
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
);
193 case 'c': /* supress messages */
194 cmd_info
->opt_flgs
|= c_FLAG
;
199 * delete files from the archive
201 setcom(cmd_info
, dcmd
);
202 cmd_info
->opt_flgs
|= d_FLAG
;
204 case 'l': /* ignored */
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
;
218 * print files in the archive
220 setcom(cmd_info
, pcmd
);
221 cmd_info
->opt_flgs
|= p_FLAG
;
226 * quickly append files to end of the archive
228 setcom(cmd_info
, qcmd
);
229 cmd_info
->opt_flgs
|= q_FLAG
;
234 * replace or add files to the archive
236 setcom(cmd_info
, rcmd
);
237 cmd_info
->opt_flgs
|= r_FLAG
;
239 case 's': /* force symbol table regeneration */
240 cmd_info
->opt_flgs
|= s_FLAG
;
242 case 'S': /* Build SYM64 symbol table */
243 cmd_info
->opt_flgs
|= S_FLAG
;
248 * print table of contents
250 setcom(cmd_info
, tcmd
);
251 cmd_info
->opt_flgs
|= t_FLAG
;
253 case 'u': /* update: change archive dependent on file dates */
254 cmd_info
->opt_flgs
|= u_FLAG
;
256 case 'v': /* verbose */
257 cmd_info
->opt_flgs
|= v_FLAG
;
262 * extract files from the archive
264 setcom(cmd_info
, xcmd
);
265 cmd_info
->opt_flgs
|= x_FLAG
;
268 cmd_info
->opt_flgs
|= z_FLAG
;
272 * print version information.
273 * adjust command line access accounting
276 (void) fprintf(stderr
,
277 MSG_ORIG(MSG_FMT_VERSION
),
278 (const char *)SGU_PKG
,
279 (const char *)SGU_REL
);
284 cmd_info
->opt_flgs
|= C_FLAG
;
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.
295 cmd_info
->opt_flgs
|= T_FLAG
;
298 (void) fprintf(stderr
, MSG_INTL(MSG_USAGE_02
), optopt
);
302 (void) fprintf(stderr
, MSG_INTL(MSG_USAGE_03
), optopt
);
308 if (usage_err
|| argc
- optind
< 1)
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.
322 setcom(Cmd_info
*cmd_info
, Cmd_func
*fun
)
324 if (cmd_info
->comfun
!= 0) {
325 (void) fprintf(stderr
, MSG_INTL(MSG_USAGE_04
));
328 cmd_info
->comfun
= fun
;
334 (void) fprintf(stderr
, MSG_INTL(MSG_USAGE
));
345 /* tells the user which of the listed files were not found in the archive */
348 notfound(Cmd_info
*cmd_info
)
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
),
368 (void) system(MSG_ORIG(MSG_CMD_SWAP
));