1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 /* Copyright (c) 1988 AT&T */ 22 /* All Rights Reserved */ 23 24 /* 25 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29 #include "inc.h" 30 #include "extern.h" 31 32 static char *arnam; 33 34 /* 35 * Function prototypes 36 */ 37 static void setup(int, char **, Cmd_info *); 38 static void setcom(Cmd_info *, int (*)()); 39 static void usage(void); 40 static void sigexit(int sig); 41 static int notfound(Cmd_info *); 42 static void check_swap(); 43 44 #define OPTSTR ":a:b:i:vucsrdxtplmqVCTzM" 45 46 int 47 main(int argc, char **argv) 48 { 49 int i; 50 int fd; 51 Cmd_info *cmd_info; 52 int ret; 53 char *new = NULL; 54 char *data = NULL; 55 56 (void) setlocale(LC_ALL, ""); 57 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 58 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 59 #endif 60 (void) textdomain(TEXT_DOMAIN); 61 62 for (i = 0; signum[i]; i++) 63 if (signal(signum[i], SIG_IGN) != SIG_IGN) 64 (void) signal(signum[i], sigexit); 65 /* 66 * Initialize cmd_info 67 */ 68 cmd_info = (Cmd_info *)calloc(1, sizeof (Cmd_info)); 69 if (cmd_info == NULL) { 70 error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0); 71 exit(1); 72 } 73 74 if (argc < 2) 75 usage(); 76 77 /* 78 * Option handling. 79 */ 80 if (argv[1][0] != '-') { 81 new = (char *)malloc(strlen(argv[1]) + 2); 82 if (new == NULL) { 83 error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0); 84 exit(1); 85 } 86 (void) strcpy(new, "-"); 87 (void) strcat(new, argv[1]); 88 argv[1] = new; 89 } 90 setup(argc, argv, cmd_info); 91 92 /* 93 * Check SWAP 94 */ 95 if (opt_FLAG((cmd_info), z_FLAG)) 96 check_swap(); 97 98 if (cmd_info->comfun == 0) { 99 if (!(opt_FLAG((cmd_info), d_FLAG) || 100 opt_FLAG(cmd_info, r_FLAG) || 101 opt_FLAG(cmd_info, q_FLAG) || opt_FLAG(cmd_info, t_FLAG) || 102 opt_FLAG(cmd_info, p_FLAG) || opt_FLAG(cmd_info, m_FLAG) || 103 opt_FLAG(cmd_info, x_FLAG))) { 104 error_message(USAGE_01_ERROR, PLAIN_ERROR, (char *)0); 105 exit(1); 106 } 107 } 108 109 cmd_info->modified = opt_FLAG(cmd_info, s_FLAG); 110 fd = getaf(cmd_info); 111 112 if ((fd == -1) && 113 (opt_FLAG(cmd_info, d_FLAG) || opt_FLAG(cmd_info, t_FLAG) || 114 opt_FLAG(cmd_info, p_FLAG) || opt_FLAG(cmd_info, m_FLAG) || 115 opt_FLAG(cmd_info, x_FLAG) || 116 (opt_FLAG(cmd_info, r_FLAG) && (opt_FLAG(cmd_info, a_FLAG) || 117 opt_FLAG(cmd_info, b_FLAG))))) { 118 error_message(NOT_FOUND_01_ERROR, 119 PLAIN_ERROR, (char *)0, arnam); 120 exit(1); 121 } 122 123 (*cmd_info->comfun)(cmd_info); 124 if (cmd_info->modified) { 125 data = writefile(cmd_info); 126 } else 127 (void) close(fd); 128 129 ret = notfound(cmd_info); 130 131 /* 132 * Check SWAP 133 */ 134 if (opt_FLAG((cmd_info), z_FLAG)) 135 check_swap(); 136 137 free(data); 138 free(new); 139 free(cmd_info); 140 return (ret); 141 142 } 143 144 /* 145 * Option hadning function. 146 * Using getopt(), following xcu4 convention. 147 */ 148 static void 149 setup(int argc, char *argv[], Cmd_info *cmd_info) 150 { 151 int Vflag = 0; 152 int c; 153 int usage_err = 0; 154 155 while ((c = getopt(argc, argv, OPTSTR)) != -1) { 156 switch (c) { 157 case 'a': /* position after named archive member file */ 158 cmd_info->opt_flgs |= a_FLAG; 159 cmd_info->ponam = trim(optarg); 160 break; 161 case 'b': /* position before named archive member file */ 162 case 'i': /* position before named archive member: same as b */ 163 cmd_info->opt_flgs |= b_FLAG; 164 cmd_info->ponam = trim(optarg); 165 break; 166 case 'c': /* supress messages */ 167 cmd_info->opt_flgs |= c_FLAG; 168 break; 169 case 'd': 170 /* 171 * key operation: 172 * delete files from the archive 173 */ 174 setcom(cmd_info, dcmd); 175 cmd_info->opt_flgs |= d_FLAG; 176 break; 177 case 'l': /* temporary directory */ 178 cmd_info->opt_flgs |= l_FLAG; 179 break; 180 case 'm': 181 /* 182 * key operation: 183 * move files to end of the archive 184 * or as indicated by position flag 185 */ 186 setcom(cmd_info, mcmd); 187 cmd_info->opt_flgs |= m_FLAG; 188 break; 189 case 'p': 190 /* 191 * key operation: 192 * print files in the archive 193 */ 194 setcom(cmd_info, pcmd); 195 cmd_info->opt_flgs |= p_FLAG; 196 break; 197 case 'q': 198 /* 199 * key operation: 200 * quickly append files to end of the archive 201 */ 202 setcom(cmd_info, qcmd); 203 cmd_info->opt_flgs |= q_FLAG; 204 break; 205 case 'r': 206 /* 207 * key operation: 208 * replace or add files to the archive 209 */ 210 setcom(cmd_info, rcmd); 211 cmd_info->opt_flgs |= r_FLAG; 212 break; 213 case 's': /* force symbol table regeneration */ 214 cmd_info->opt_flgs |= s_FLAG; 215 break; 216 case 't': 217 /* 218 * key operation: 219 * print table of contents 220 */ 221 setcom(cmd_info, tcmd); 222 cmd_info->opt_flgs |= t_FLAG; 223 break; 224 case 'u': /* update: change archive dependent on file dates */ 225 cmd_info->opt_flgs |= u_FLAG; 226 break; 227 case 'v': /* verbose */ 228 cmd_info->opt_flgs |= v_FLAG; 229 break; 230 case 'x': 231 /* 232 * key operation: 233 * extract files from the archive 234 */ 235 setcom(cmd_info, xcmd); 236 cmd_info->opt_flgs |= x_FLAG; 237 break; 238 case 'z': 239 cmd_info->opt_flgs |= z_FLAG; 240 break; 241 case 'V': 242 /* 243 * print version information. 244 * adjust command line access accounting 245 */ 246 if (Vflag == 0) { 247 (void) fprintf(stderr, "ar: %s %s\n", 248 (const char *)SGU_PKG, 249 (const char *)SGU_REL); 250 Vflag++; 251 } 252 break; 253 case 'C': 254 cmd_info->OPT_flgs |= C_FLAG; 255 break; 256 case 'M': 257 cmd_info->OPT_flgs |= M_FLAG; 258 break; 259 case 'T': 260 cmd_info->OPT_flgs |= T_FLAG; 261 break; 262 case ':': 263 error_message(USAGE_02_ERROR, 264 PLAIN_ERROR, (char *)0, optopt); 265 usage_err++; 266 break; 267 case '?': 268 error_message(USAGE_03_ERROR, 269 PLAIN_ERROR, (char *)0, optopt); 270 usage_err++; 271 break; 272 } 273 } 274 275 if (usage_err || argc - optind < 1) 276 usage(); 277 278 cmd_info->arnam = arnam = argv[optind]; 279 cmd_info->namv = &argv[optind+1]; 280 cmd_info->namc = argc - optind - 1; 281 } 282 283 284 /* 285 * Set the function to be called to do the key operation. 286 * Check that only one key is indicated. 287 */ 288 static void 289 setcom(Cmd_info *cmd_info, int (*fun)()) 290 { 291 if (cmd_info->comfun != 0) { 292 error_message(USAGE_04_ERROR, PLAIN_ERROR, (char *)0); 293 exit(1); 294 } 295 cmd_info->comfun = fun; 296 } 297 298 static void 299 usage(void) 300 { 301 (void) fprintf(stderr, gettext( 302 "usage: ar -d[-vV] archive file ...\n" 303 " ar -m[-abivV] [posname] archive file ...\n" 304 " ar -p[-vV][-s] archive [file ...]\n" 305 " ar -q[-cuvV] [-abi] [posname] [file ...]\n" 306 " ar -r[-cuvV] [-abi] [posname] [file ...]\n" 307 " ar -t[-vV][-s] archive [file ...]\n" 308 " ar -x[-vV][-sCT] archive [file ...]\n")); 309 exit(1); 310 } 311 312 /*ARGSUSED0*/ 313 static void 314 sigexit(int sig) 315 { 316 exit(100); 317 } 318 319 /* tells the user which of the listed files were not found in the archive */ 320 321 static int 322 notfound(Cmd_info *cmd_info) 323 { 324 int i, n; 325 326 n = 0; 327 for (i = 0; i < cmd_info->namc; i++) 328 if (cmd_info->namv[i]) { 329 error_message(NOT_FOUND_03_ERROR, 330 PLAIN_ERROR, (char *)0, cmd_info->namv[i]); 331 n++; 332 } 333 return (n); 334 } 335 336 /* 337 * Debugging info 338 */ 339 static void 340 check_swap(void) 341 { 342 (void) system("/usr/sbin/swap -s"); 343 } 344