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
[])
79 * Check for a binary that better fits this architecture.
81 (void) conv_check_native(argv
, envp
);
86 (void) setlocale(LC_ALL
, MSG_ORIG(MSG_STR_EMPTY
));
87 (void) textdomain(MSG_ORIG(MSG_SUNW_OST_SGS
));
89 /* Allow a graceful exit up until we start to write an archive */
90 establish_sighandler(sigexit
);
95 cmd_info
= (Cmd_info
*)calloc(1, sizeof (Cmd_info
));
96 if (cmd_info
== NULL
) {
98 (void) fprintf(stderr
, MSG_INTL(MSG_MALLOC
), strerror(err
));
108 if (argv
[1][0] != '-') {
109 new = (char *)malloc(strlen(argv
[1]) + 2);
112 (void) fprintf(stderr
, MSG_INTL(MSG_MALLOC
),
116 (void) strcpy(new, MSG_ORIG(MSG_STR_HYPHEN
));
117 (void) strcat(new, argv
[1]);
120 setup(argc
, argv
, cmd_info
);
125 if (cmd_info
->opt_flgs
& z_FLAG
)
128 if (cmd_info
->comfun
== NULL
) {
129 if ((cmd_info
->opt_flgs
& (d_FLAG
| r_FLAG
| q_FLAG
|
130 t_FLAG
| p_FLAG
| m_FLAG
| x_FLAG
)) == 0) {
131 (void) fprintf(stderr
, MSG_INTL(MSG_USAGE_01
));
136 cmd_info
->modified
= (cmd_info
->opt_flgs
& s_FLAG
);
137 fd
= getaf(cmd_info
);
140 (cmd_info
->opt_flgs
&
141 (d_FLAG
| m_FLAG
| p_FLAG
| t_FLAG
| x_FLAG
)) ||
142 ((cmd_info
->opt_flgs
& r_FLAG
) &&
143 (cmd_info
->opt_flgs
& (a_FLAG
| b_FLAG
)))) {
144 (void) fprintf(stderr
, MSG_INTL(MSG_NOT_FOUND_AR
),
149 (*cmd_info
->comfun
)(cmd_info
);
150 if (cmd_info
->modified
) {
155 ret
= notfound(cmd_info
);
160 if (cmd_info
->opt_flgs
& z_FLAG
)
170 * Option handing function.
171 * Using getopt(), following xcu4 convention.
174 setup(int argc
, char *argv
[], Cmd_info
*cmd_info
)
180 while ((c
= getopt(argc
, argv
, MSG_ORIG(MSG_STR_OPTIONS
))) != -1) {
182 case 'a': /* position after named archive member file */
183 cmd_info
->opt_flgs
|= a_FLAG
;
184 cmd_info
->ponam
= trim(optarg
);
186 case 'b': /* position before named archive member file */
187 case 'i': /* position before named archive member: same as b */
188 cmd_info
->opt_flgs
|= b_FLAG
;
189 cmd_info
->ponam
= trim(optarg
);
191 case 'c': /* supress messages */
192 cmd_info
->opt_flgs
|= c_FLAG
;
197 * delete files from the archive
199 setcom(cmd_info
, dcmd
);
200 cmd_info
->opt_flgs
|= d_FLAG
;
202 case 'l': /* ignored */
207 * move files to end of the archive
208 * or as indicated by position flag
210 setcom(cmd_info
, mcmd
);
211 cmd_info
->opt_flgs
|= m_FLAG
;
216 * print files in the archive
218 setcom(cmd_info
, pcmd
);
219 cmd_info
->opt_flgs
|= p_FLAG
;
224 * quickly append files to end of the archive
226 setcom(cmd_info
, qcmd
);
227 cmd_info
->opt_flgs
|= q_FLAG
;
232 * replace or add files to the archive
234 setcom(cmd_info
, rcmd
);
235 cmd_info
->opt_flgs
|= r_FLAG
;
237 case 's': /* force symbol table regeneration */
238 cmd_info
->opt_flgs
|= s_FLAG
;
240 case 'S': /* Build SYM64 symbol table */
241 cmd_info
->opt_flgs
|= S_FLAG
;
246 * print table of contents
248 setcom(cmd_info
, tcmd
);
249 cmd_info
->opt_flgs
|= t_FLAG
;
251 case 'u': /* update: change archive dependent on file dates */
252 cmd_info
->opt_flgs
|= u_FLAG
;
254 case 'v': /* verbose */
255 cmd_info
->opt_flgs
|= v_FLAG
;
260 * extract files from the archive
262 setcom(cmd_info
, xcmd
);
263 cmd_info
->opt_flgs
|= x_FLAG
;
266 cmd_info
->opt_flgs
|= z_FLAG
;
270 * print version information.
271 * adjust command line access accounting
274 (void) fprintf(stderr
,
275 MSG_ORIG(MSG_FMT_VERSION
),
276 (const char *)SGU_PKG
,
277 (const char *)SGU_REL
);
282 cmd_info
->opt_flgs
|= C_FLAG
;
286 * -M was an original undocumented AT&T feature that
287 * would force the use of mmap() instead of read()
288 * for pulling file data into the process before
289 * writing it to the archive. Ignored.
293 cmd_info
->opt_flgs
|= T_FLAG
;
296 (void) fprintf(stderr
, MSG_INTL(MSG_USAGE_02
), optopt
);
300 (void) fprintf(stderr
, MSG_INTL(MSG_USAGE_03
), optopt
);
306 if (usage_err
|| argc
- optind
< 1)
309 cmd_info
->arnam
= argv
[optind
];
310 cmd_info
->namv
= &argv
[optind
+1];
311 cmd_info
->namc
= argc
- optind
- 1;
316 * Set the function to be called to do the key operation.
317 * Check that only one key is indicated.
320 setcom(Cmd_info
*cmd_info
, Cmd_func
*fun
)
322 if (cmd_info
->comfun
!= 0) {
323 (void) fprintf(stderr
, MSG_INTL(MSG_USAGE_04
));
326 cmd_info
->comfun
= fun
;
332 (void) fprintf(stderr
, MSG_INTL(MSG_USAGE
));
343 /* tells the user which of the listed files were not found in the archive */
346 notfound(Cmd_info
*cmd_info
)
351 for (i
= 0; i
< cmd_info
->namc
; i
++)
352 if (cmd_info
->namv
[i
]) {
353 (void) fprintf(stderr
, MSG_INTL(MSG_NOT_FOUND_FILE
),
366 (void) system(MSG_ORIG(MSG_CMD_SWAP
));