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
main(int argc,char ** argv)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
bld_pack_list(FILE * fd,char * filename)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
usage()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