1 /*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Hugh Smith at The University of Guelph. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 char copyright[] = 13 "@(#) Copyright (c) 1990 The Regents of the University of California.\n\ 14 All rights reserved.\n"; 15 #endif /* not lint */ 16 17 #ifndef lint 18 static char sccsid[] = "@(#)ar.c 5.9 (Berkeley) 03/11/91"; 19 #endif /* not lint */ 20 21 #include <sys/param.h> 22 #include <sys/errno.h> 23 #include <dirent.h> 24 #include <stdio.h> 25 #include <ar.h> 26 #include <string.h> 27 #include <stdlib.h> 28 #include <paths.h> 29 #include "archive.h" 30 #include "extern.h" 31 32 CHDR chdr; 33 u_int options; 34 char *archive, *envtmp, *posarg, *posname; 35 static void badoptions(), usage(); 36 37 /* 38 * main -- 39 * main basically uses getopt to parse options and calls the appropriate 40 * functions. Some hacks that let us be backward compatible with 4.3 ar 41 * option parsing and sanity checking. 42 */ 43 main(argc, argv) 44 int argc; 45 char **argv; 46 { 47 extern int optind; 48 int c, rval; 49 char *p; 50 int (*fcall)(), append(), contents(), delete(), extract(), 51 move(), print(), replace(); 52 53 if (argc < 3) 54 usage(); 55 56 /* 57 * Historic versions didn't require a '-' in front of the options. 58 * Fix it, if necessary. 59 */ 60 if (*argv[1] != '-') { 61 if (!(p = malloc((u_int)(strlen(argv[1]) + 2)))) { 62 (void)fprintf(stderr, "ar: %s.\n", strerror(errno)); 63 exit(1); 64 } 65 *p = '-'; 66 (void)strcpy(p + 1, argv[1]); 67 argv[1] = p; 68 } 69 70 while ((c = getopt(argc, argv, "abcdilmopqrstuvx")) != EOF) { 71 switch(c) { 72 case 'a': 73 options |= AR_A; 74 break; 75 case 'b': 76 case 'i': 77 options |= AR_B; 78 break; 79 case 'c': 80 options |= AR_C; 81 break; 82 case 'd': 83 options |= AR_D; 84 fcall = delete; 85 break; 86 case 'l': /* not documented, compatibility only */ 87 envtmp = "."; 88 break; 89 case 'm': 90 options |= AR_M; 91 fcall = move; 92 break; 93 case 'o': 94 options |= AR_O; 95 break; 96 case 'p': 97 options |= AR_P; 98 fcall = print; 99 break; 100 case 'q': 101 options |= AR_Q; 102 fcall = append; 103 break; 104 case 'r': 105 options |= AR_R; 106 fcall = replace; 107 break; 108 case 's': 109 options |= AR_S; 110 break; 111 case 't': 112 options |= AR_T; 113 fcall = contents; 114 break; 115 case 'u': 116 options |= AR_U; 117 break; 118 case 'v': 119 options |= AR_V; 120 break; 121 case 'x': 122 options |= AR_X; 123 fcall = extract; 124 break; 125 default: 126 usage(); 127 } 128 } 129 130 argv += optind; 131 argc -= optind; 132 133 /* One of -dmpqrtx required. */ 134 if (!(options & (AR_D|AR_M|AR_P|AR_Q|AR_R|AR_T|AR_X))) { 135 (void)fprintf(stderr, 136 "ar: one of options -dmpqrtx is required.\n"); 137 usage(); 138 } 139 /* Only one of -a and -bi allowed. */ 140 if (options & AR_A && options & AR_B) { 141 (void)fprintf(stderr, 142 "ar: only one of -a and -[bi] options allowed.\n"); 143 usage(); 144 } 145 /* -ab require a position argument. */ 146 if (options & (AR_A|AR_B)) { 147 if (!(posarg = *argv++)) { 148 (void)fprintf(stderr, 149 "ar: no position operand specified.\n"); 150 usage(); 151 } 152 posname = rname(posarg); 153 } 154 /* -d only valid with -sv. */ 155 if (options & AR_D && options & ~(AR_D|AR_S|AR_V)) 156 badoptions("-d"); 157 /* -m only valid with -abisv. */ 158 if (options & AR_M && options & ~(AR_A|AR_B|AR_M|AR_S|AR_V)) 159 badoptions("-m"); 160 /* -p only valid with -sv. */ 161 if (options & AR_P && options & ~(AR_P|AR_S|AR_V)) 162 badoptions("-p"); 163 /* -q only valid with -csv. */ 164 if (options & AR_Q && options & ~(AR_C|AR_Q|AR_S|AR_V)) 165 badoptions("-q"); 166 /* -r only valid with -abcusv. */ 167 if (options & AR_R && options & ~(AR_A|AR_B|AR_C|AR_R|AR_U|AR_S|AR_V)) 168 badoptions("-r"); 169 /* -t only valid with -sv. */ 170 if (options & AR_T && options & ~(AR_T|AR_S|AR_V)) 171 badoptions("-t"); 172 /* -x only valid with -ousv. */ 173 if (options & AR_X && options & ~(AR_O|AR_U|AR_S|AR_V|AR_X)) 174 badoptions("-x"); 175 176 if (!(archive = *argv++)) { 177 (void)fprintf(stderr, "ar: no archive specified.\n"); 178 usage(); 179 } 180 181 /* -dmqr require a list of archive elements. */ 182 if (options & (AR_D|AR_M|AR_Q|AR_R) && !*argv) { 183 (void)fprintf(stderr, "ar: no archive members specified.\n"); 184 usage(); 185 } 186 187 rval = (*fcall)(argv); 188 exit(rval); 189 } 190 191 static void 192 badoptions(arg) 193 char *arg; 194 { 195 (void)fprintf(stderr, 196 "ar: illegal option combination for %s.\n", arg); 197 usage(); 198 } 199 200 static void 201 usage() 202 { 203 (void)fprintf(stderr, "usage: ar -d [-sv] archive file ...\n"); 204 (void)fprintf(stderr, "\tar -m [-sv] archive file ...\n"); 205 (void)fprintf(stderr, "\tar -m [-abisv] position archive file ...\n"); 206 (void)fprintf(stderr, "\tar -p [-sv] archive [file ...]\n"); 207 (void)fprintf(stderr, "\tar -q [-csv] archive file ...\n"); 208 (void)fprintf(stderr, "\tar -r [-cusv] archive file ...\n"); 209 (void)fprintf(stderr, "\tar -r [-abciusv] position archive file ...\n"); 210 (void)fprintf(stderr, "\tar -t [-sv] archive [file ...]\n"); 211 (void)fprintf(stderr, "\tar -x [-ousv] archive [file ...]\n"); 212 exit(1); 213 } 214