/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include "inc.h" #include "extern.h" static char *arnam; /* * Function prototypes */ static void setup(int, char **, Cmd_info *); static void setcom(Cmd_info *, int (*)()); static void usage(void); static void sigexit(int sig); static int notfound(Cmd_info *); static void check_swap(); #define OPTSTR ":a:b:i:vucsrdxtplmqVCTzM" int main(int argc, char **argv) { int i; int fd; Cmd_info *cmd_info; int ret; char *new = NULL; char *data = NULL; (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ #endif (void) textdomain(TEXT_DOMAIN); for (i = 0; signum[i]; i++) if (signal(signum[i], SIG_IGN) != SIG_IGN) (void) signal(signum[i], sigexit); /* * Initialize cmd_info */ cmd_info = (Cmd_info *)calloc(1, sizeof (Cmd_info)); if (cmd_info == NULL) { error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0); exit(1); } if (argc < 2) usage(); /* * Option handling. */ if (argv[1][0] != '-') { new = (char *)malloc(strlen(argv[1]) + 2); if (new == NULL) { error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0); exit(1); } (void) strcpy(new, "-"); (void) strcat(new, argv[1]); argv[1] = new; } setup(argc, argv, cmd_info); /* * Check SWAP */ if (opt_FLAG((cmd_info), z_FLAG)) check_swap(); if (cmd_info->comfun == 0) { if (!(opt_FLAG((cmd_info), d_FLAG) || opt_FLAG(cmd_info, r_FLAG) || opt_FLAG(cmd_info, q_FLAG) || opt_FLAG(cmd_info, t_FLAG) || opt_FLAG(cmd_info, p_FLAG) || opt_FLAG(cmd_info, m_FLAG) || opt_FLAG(cmd_info, x_FLAG))) { error_message(USAGE_01_ERROR, PLAIN_ERROR, (char *)0); exit(1); } } cmd_info->modified = opt_FLAG(cmd_info, s_FLAG); fd = getaf(cmd_info); if ((fd == -1) && (opt_FLAG(cmd_info, d_FLAG) || opt_FLAG(cmd_info, t_FLAG) || opt_FLAG(cmd_info, p_FLAG) || opt_FLAG(cmd_info, m_FLAG) || opt_FLAG(cmd_info, x_FLAG) || (opt_FLAG(cmd_info, r_FLAG) && (opt_FLAG(cmd_info, a_FLAG) || opt_FLAG(cmd_info, b_FLAG))))) { error_message(NOT_FOUND_01_ERROR, PLAIN_ERROR, (char *)0, arnam); exit(1); } (*cmd_info->comfun)(cmd_info); if (cmd_info->modified) { data = writefile(cmd_info); } else (void) close(fd); ret = notfound(cmd_info); /* * Check SWAP */ if (opt_FLAG((cmd_info), z_FLAG)) check_swap(); free(data); free(new); free(cmd_info); return (ret); } /* * Option hadning function. * Using getopt(), following xcu4 convention. */ static void setup(int argc, char *argv[], Cmd_info *cmd_info) { int Vflag = 0; int c; int usage_err = 0; while ((c = getopt(argc, argv, OPTSTR)) != -1) { switch (c) { case 'a': /* position after named archive member file */ cmd_info->opt_flgs |= a_FLAG; cmd_info->ponam = trim(optarg); break; case 'b': /* position before named archive member file */ case 'i': /* position before named archive member: same as b */ cmd_info->opt_flgs |= b_FLAG; cmd_info->ponam = trim(optarg); break; case 'c': /* supress messages */ cmd_info->opt_flgs |= c_FLAG; break; case 'd': /* * key operation: * delete files from the archive */ setcom(cmd_info, dcmd); cmd_info->opt_flgs |= d_FLAG; break; case 'l': /* temporary directory */ cmd_info->opt_flgs |= l_FLAG; break; case 'm': /* * key operation: * move files to end of the archive * or as indicated by position flag */ setcom(cmd_info, mcmd); cmd_info->opt_flgs |= m_FLAG; break; case 'p': /* * key operation: * print files in the archive */ setcom(cmd_info, pcmd); cmd_info->opt_flgs |= p_FLAG; break; case 'q': /* * key operation: * quickly append files to end of the archive */ setcom(cmd_info, qcmd); cmd_info->opt_flgs |= q_FLAG; break; case 'r': /* * key operation: * replace or add files to the archive */ setcom(cmd_info, rcmd); cmd_info->opt_flgs |= r_FLAG; break; case 's': /* force symbol table regeneration */ cmd_info->opt_flgs |= s_FLAG; break; case 't': /* * key operation: * print table of contents */ setcom(cmd_info, tcmd); cmd_info->opt_flgs |= t_FLAG; break; case 'u': /* update: change archive dependent on file dates */ cmd_info->opt_flgs |= u_FLAG; break; case 'v': /* verbose */ cmd_info->opt_flgs |= v_FLAG; break; case 'x': /* * key operation: * extract files from the archive */ setcom(cmd_info, xcmd); cmd_info->opt_flgs |= x_FLAG; break; case 'z': cmd_info->opt_flgs |= z_FLAG; break; case 'V': /* * print version information. * adjust command line access accounting */ if (Vflag == 0) { (void) fprintf(stderr, "ar: %s %s\n", (const char *)SGU_PKG, (const char *)SGU_REL); Vflag++; } break; case 'C': cmd_info->OPT_flgs |= C_FLAG; break; case 'M': cmd_info->OPT_flgs |= M_FLAG; break; case 'T': cmd_info->OPT_flgs |= T_FLAG; break; case ':': error_message(USAGE_02_ERROR, PLAIN_ERROR, (char *)0, optopt); usage_err++; break; case '?': error_message(USAGE_03_ERROR, PLAIN_ERROR, (char *)0, optopt); usage_err++; break; } } if (usage_err || argc - optind < 1) usage(); cmd_info->arnam = arnam = argv[optind]; cmd_info->namv = &argv[optind+1]; cmd_info->namc = argc - optind - 1; } /* * Set the function to be called to do the key operation. * Check that only one key is indicated. */ static void setcom(Cmd_info *cmd_info, int (*fun)()) { if (cmd_info->comfun != 0) { error_message(USAGE_04_ERROR, PLAIN_ERROR, (char *)0); exit(1); } cmd_info->comfun = fun; } static void usage(void) { (void) fprintf(stderr, gettext( "usage: ar -d[-vV] archive file ...\n" " ar -m[-abivV] [posname] archive file ...\n" " ar -p[-vV][-s] archive [file ...]\n" " ar -q[-cuvV] [-abi] [posname] [file ...]\n" " ar -r[-cuvV] [-abi] [posname] [file ...]\n" " ar -t[-vV][-s] archive [file ...]\n" " ar -x[-vV][-sCT] archive [file ...]\n")); exit(1); } /*ARGSUSED0*/ static void sigexit(int sig) { exit(100); } /* tells the user which of the listed files were not found in the archive */ static int notfound(Cmd_info *cmd_info) { int i, n; n = 0; for (i = 0; i < cmd_info->namc; i++) if (cmd_info->namv[i]) { error_message(NOT_FOUND_03_ERROR, PLAIN_ERROR, (char *)0, cmd_info->namv[i]); n++; } return (n); } /* * Debugging info */ static void check_swap(void) { (void) system("/usr/sbin/swap -s"); }