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