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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <locale.h> 30 #include <stdio.h> 31 #include <string.h> 32 #include <sys/param.h> 33 #include <unistd.h> 34 35 #define MAIN 1 36 #include "rules.h" 37 #include "elfrd.h" 38 39 int verbose = 0; 40 struct libpath *libp, libp_hd; 41 42 int 43 main(int argc, char **argv) 44 { 45 int prtfn(); 46 int packfn(); 47 int unpackfn(); 48 int inquirefn(); 49 FILE *open_rulesfile(); 50 FILE *rfd; 51 int c; 52 int fflag = 0; 53 int Bflag = 0; 54 int index; 55 char *rulesfile; 56 int typearg = 0; 57 int (*wrkfunc)(); 58 extern char *optarg; 59 extern int optind, opterr; 60 extern void bld_pack_list(); 61 extern void usage(); 62 63 (void) setlocale(LC_ALL, ""); 64 #if !defined(TEXT_DOMAIN) 65 #define TEXT_DOMAIN "SYS_TEST" 66 #endif 67 (void) textdomain(TEXT_DOMAIN); 68 69 global_flags = LF_NULL; 70 71 rfd = open_rulesfile(); 72 73 libp = &libp_hd; 74 get_libsrch_path(libp); 75 76 /* create hash table for tracking libraries */ 77 if (hcreate(10000) == 0) { 78 /* unlikely this ever happens or I would work around it */ 79 fprintf(stderr, 80 gettext("cachefspack: can't create hash table\n")); 81 exit(1); 82 } 83 84 while ((c = getopt(argc, argv, "df:hiprsuvB:I:L:U:")) != -1) { 85 switch (c) { 86 case 'd': 87 wrkfunc = prtfn; 88 typearg++; 89 break; 90 case 'f': 91 fflag++; 92 rulesfile = strdup(optarg); 93 break; 94 case 'h': 95 usage(); 96 exit(0); 97 break; 98 case 'i': 99 wrkfunc = inquirefn; 100 typearg++; 101 break; 102 case 'p': 103 wrkfunc = packfn; 104 typearg++; 105 break; 106 case 'r': 107 global_flags |= LF_REGEX; 108 break; 109 case 's': 110 global_flags |= LF_STRIP_DOTSLASH; 111 break; 112 case 'u': 113 wrkfunc = unpackfn; 114 typearg++; 115 break; 116 case 'v': 117 verbose = 1; 118 break; 119 case 'B': 120 Bflag++; 121 fprintf(rfd, "BASE %s\n", optarg); 122 break; 123 case 'I': 124 fprintf(rfd, "IGNORE %s\n", optarg); 125 break; 126 case 'L': 127 fprintf(rfd, "LIST %s\n", optarg); 128 break; 129 case 'U': 130 typearg++; 131 wrkfunc = unpackfn; 132 bld_pack_list(rfd, optarg); 133 break; 134 default: 135 usage(); 136 exit(1); 137 } 138 } 139 140 def_lign_flags = LF_NULL; 141 def_gign_flags = LF_NULL; 142 def_list_flags = LF_REGEX; 143 bang_list_flags = LF_STRIP_DOTSLASH; 144 if (global_flags != 0) { 145 def_list_flags = global_flags; 146 bang_list_flags = global_flags; 147 } 148 149 if (fflag & Bflag) { 150 fprintf(stderr, gettext( 151 "cachefspack: B and f options are mutually exclusive\n")); 152 exit(1); 153 } 154 155 if (fflag) { 156 fclose(rfd); 157 rfd = fopen(rulesfile, "r"); 158 if (rfd == NULL) { 159 fprintf(stderr, gettext( 160 "cachefspack: can't open file associated" 161 " with -f\n")); 162 exit(1); 163 } 164 } 165 166 if (typearg != 1) { 167 if (typearg == 0) { 168 wrkfunc = packfn; 169 } else { 170 fprintf(stderr, 171 gettext( 172 "cachefspack: only one 'd', 'i', 'p' or 'u' ")); 173 fprintf(stderr, 174 gettext(" option allowed\n")); 175 exit(1); 176 } 177 } 178 if (optind < argc) { 179 if (fflag || Bflag) { 180 fprintf(stderr, 181 gettext( 182 "cachefspack: 'B' or 'f' specified ")); 183 fprintf(stderr, 184 gettext("with filenames\n")); 185 exit(1); 186 } 187 for (index = optind; index < argc; index++) { 188 #ifdef DEBUG 189 printf("argv[%d] = %s\n", index, argv[index]); 190 #endif /* DEBUG */ 191 bld_pack_list(rfd, argv[index]); 192 } 193 } 194 rewind(rfd); 195 read_rules(rfd, wrkfunc); 196 fclose(rfd); 197 return (0); 198 } 199 200 /* 201 * The bld_pack_list() function is used to write the temporary packing 202 * list function. When the BASE directory changes, a new BASE command is 203 * generated. If the filename argument(fnam) starts with a '/', then the 204 * filename is assumed to be an absolute pathname. Otherwise, the filename 205 * is assumed to be realtive to the current directory. 206 */ 207 void 208 bld_pack_list(FILE *fd, char *filename) 209 { 210 static char last_base[MAXPATHLEN+1] = {" "}; 211 static char fnam[MAXPATHLEN+1]; 212 static int last_base_sz = 1; 213 char *lastsl_pos; 214 int sz; 215 int endpos; 216 char *cwd; 217 218 /* strip off any trailing /'s */ 219 strcpy(fnam, filename); 220 for (endpos = strlen(fnam) - 1; endpos > 0; endpos--) { 221 if (fnam[endpos] == '/') 222 fnam[endpos] = '\0'; 223 else 224 break; 225 } 226 227 if (*fnam == '/') { /* absolute pathname */ 228 lastsl_pos = strrchr(fnam, '/'); 229 sz = (int)lastsl_pos - (int)fnam + 1; 230 if ((last_base_sz != sz) || 231 (strncmp(last_base, fnam, sz) != 0)) { 232 fprintf(fd, "BASE %.*s\n", (sz <= 1 ? sz : sz-1), fnam); 233 last_base_sz = sz; 234 strncpy(last_base, fnam, sz); 235 } 236 fprintf(fd, "LIST %s\n", &fnam[sz]); 237 } else { /* relative pathname */ 238 /* Really only need to call this once, ... */ 239 cwd = getcwd(NULL, MAXPATHLEN+1); 240 sz = strlen(cwd); 241 if ((last_base_sz != sz) || 242 (strncmp(last_base, cwd, sz) != 0)) { 243 fprintf(fd, "BASE %s\n", cwd); 244 last_base_sz = sz; 245 strncpy(last_base, cwd, sz); 246 } 247 free(cwd); 248 fprintf(fd, "LIST %s\n", fnam); 249 } 250 } 251 252 void 253 usage() 254 { 255 #ifdef DEBUG 256 printf( 257 gettext("cachefspack -[dipu] -[fBIL] [-h] [-r] [-s] [-U dir]")); 258 #else /* DEBUG */ 259 printf( 260 gettext("cachefspack -[dipu] -[f] [-h] [-r] [-s] [-U dir]")); 261 #endif /* DEBUG */ 262 printf(gettext(" [files]\n")); 263 printf("\n"); 264 printf( 265 gettext("Must select 1 and only 1 of the following 5 options\n")); 266 printf(gettext("-d Display selected filenames\n")); 267 printf(gettext("-i Display selected filenames packing status\n")); 268 printf(gettext("-p Pack selected filenames\n")); 269 printf(gettext("-u Unpack selected filenames\n")); 270 printf(gettext("-U Unpack all files in directory 'dir'\n")); 271 printf(gettext("\n")); 272 printf(gettext("-f Specify input file containing rules\n")); 273 #ifdef DEBUG 274 printf(gettext("-B Specify BASE rule on command line\n")); 275 printf(gettext("-I Specify IGNORE rule on command line\n")); 276 printf(gettext("-L Specify LIST rule on command line\n")); 277 printf(gettext("\n")); 278 #endif /* DEBUG */ 279 printf(gettext("-h Print usage information\n")); 280 printf(gettext( 281 "-r Interpret strings in LIST rules as regular expressions\n")); 282 printf(gettext("-s Strip './' from the beginning of a pattern name\n")); 283 printf(gettext("-v Verbose option\n")); 284 printf(gettext("files - a list of filenames to be packed/unpacked\n")); 285 } 286