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