1 /* @(#)match.c 1.34 16/11/27 joerg */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)match.c 1.34 16/11/27 joerg";
6 #endif
7 /*
8 * 27-Mar-96: Jan-Piet Mens <jpm@mens.de>
9 * added 'match' option (-m) to specify regular expressions NOT to be included
10 * in the CD image.
11 *
12 * Re-written 13-Apr-2000 James Pearson
13 * now uses a generic set of routines
14 * Conversions to make the code more portable May 2000 .. March 2004
15 * Copyright (c) 2000-2016 J. Schilling
16 */
17
18 #include <schily/stdio.h>
19 #include <schily/stdlib.h>
20 #include <schily/unistd.h>
21 #include <schily/string.h>
22 #include <schily/standard.h>
23 #include <schily/schily.h>
24 #include <schily/libport.h>
25 #include <schily/nlsdefs.h>
26 #include "match.h"
27
28 struct match {
29 struct match *next;
30 char *name;
31 };
32
33 typedef struct match match;
34
35 static BOOL isort;
36
37 static match *mats[MAX_MAT];
38
39 static char *mesg[MAX_MAT] = {
40 "excluded",
41 "excluded ISO-9660",
42 "excluded Joliet",
43 "excluded UDF",
44 "hidden attribute ISO-9660",
45 #ifdef APPLE_HYB
46 "excluded HFS",
47 #endif /* APPLE_HYB */
48 };
49
50 #ifdef SORTING
51 struct sort_match {
52 struct sort_match *next;
53 char *name;
54 int val;
55 };
56
57 typedef struct sort_match sort_match;
58
59 static sort_match *s_mats;
60
61 EXPORT int
add_sort_match(fn,val)62 add_sort_match(fn, val)
63 char *fn;
64 int val;
65 {
66 sort_match *s_mat;
67
68 s_mat = (sort_match *)malloc(sizeof (sort_match));
69 if (s_mat == NULL) {
70 errmsg(_("Can't allocate memory for sort filename\n"));
71 return (0);
72 }
73
74 if ((s_mat->name = strdup(fn)) == NULL) {
75 errmsg(_("Can't allocate memory for sort filename\n"));
76 free(s_mat);
77 return (0);
78 }
79
80 /* need to reserve the minimum value for other uses */
81 if (val == NOT_SORTED)
82 val++;
83
84 s_mat->val = val;
85 s_mat->next = s_mats;
86 s_mats = s_mat;
87
88 return (1);
89 }
90
91 EXPORT int
add_sort_list(file,valp,pac,pav,opt)92 add_sort_list(file, valp, pac, pav, opt)
93 const char *file;
94 void *valp;
95 int *pac;
96 char *const **pav;
97 const char *opt;
98 {
99 FILE *fp;
100 char name[4096];
101 char *p;
102 int val;
103 extern int do_sort;
104
105 while (*opt == '-')
106 opt++;
107 if (*opt == 'i')
108 isort = TRUE;
109 do_sort++;
110 if ((fp = fopen(file, "r")) == NULL) {
111 comerr(_("Can't open sort file list %s\n"), file);
112 }
113
114 while (fgets(name, sizeof (name), fp) != NULL) {
115 /*
116 * look for the last space or tab character
117 */
118 if ((p = strrchr(name, ' ')) == NULL)
119 p = strrchr(name, '\t');
120 else if (strrchr(p, '\t') != NULL) /* Tab after space? */
121 p = strrchr(p, '\t');
122
123 if (p == NULL) {
124 /*
125 * XXX old code did not abort here.
126 */
127 comerrno(EX_BAD, _("Incorrect sort file format\n\t%s\n"), name);
128 continue;
129 } else {
130 *p = '\0';
131 val = atoi(++p);
132 }
133 if (!add_sort_match(name, val)) {
134 fclose(fp);
135 return (-1);
136 }
137 }
138
139 fclose(fp);
140 return (1);
141 }
142
143 EXPORT int
sort_matches(fn,val)144 sort_matches(fn, val)
145 char *fn;
146 int val;
147 {
148 register sort_match *s_mat;
149 int flags = FNM_PATHNAME;
150
151 if (isort)
152 flags |= FNM_IGNORECASE;
153
154 for (s_mat = s_mats; s_mat; s_mat = s_mat->next) {
155 if (fnmatch(s_mat->name, fn, flags) != FNM_NOMATCH) {
156 return (s_mat->val); /* found sort value */
157 }
158 }
159 return (val); /* not found - default sort value */
160 }
161
162 EXPORT void
del_sort()163 del_sort()
164 {
165 register sort_match * s_mat, *s_mat1;
166
167 s_mat = s_mats;
168 while (s_mat) {
169 s_mat1 = s_mat->next;
170
171 free(s_mat->name);
172 free(s_mat);
173
174 s_mat = s_mat1;
175 }
176
177 s_mats = 0;
178 }
179
180 #endif /* SORTING */
181
182
183 EXPORT int
gen_add_match(fn,n)184 gen_add_match(fn, n)
185 char *fn;
186 int n;
187 {
188 match *mat;
189
190 if (n >= MAX_MAT) {
191 errmsgno(EX_BAD, _("Too many patterns.\n"));
192 return (0);
193 }
194
195 mat = (match *)malloc(sizeof (match));
196 if (mat == NULL) {
197 errmsg(_("Can't allocate memory for %s filename\n"), mesg[n]);
198 return (0);
199 }
200
201 if ((mat->name = strdup(fn)) == NULL) {
202 errmsg(_("Can't allocate memory for %s filename\n"), mesg[n]);
203 free(mat);
204 return (0);
205 }
206
207 mat->next = mats[n];
208 mats[n] = mat;
209
210 return (1);
211 }
212
213 EXPORT int
add_match(fn)214 add_match(fn)
215 char *fn;
216 {
217 int ret = gen_add_match(fn, EXCLUDE);
218
219 if (ret == 0)
220 return (-1);
221 return (1);
222 }
223
224 EXPORT int
i_add_match(fn)225 i_add_match(fn)
226 char *fn;
227 {
228 int ret = gen_add_match(fn, I_HIDE);
229
230 if (ret == 0)
231 return (-1);
232 return (1);
233 }
234
235 EXPORT int
h_add_match(fn)236 h_add_match(fn)
237 char *fn;
238 {
239 int ret = gen_add_match(fn, H_HIDE);
240
241 if (ret == 0)
242 return (-1);
243 return (1);
244 }
245
246 #ifdef APPLE_HYB
247 EXPORT int
hfs_add_match(fn)248 hfs_add_match(fn)
249 char *fn;
250 {
251 int ret = gen_add_match(fn, HFS_HIDE);
252
253 if (ret == 0)
254 return (-1);
255 return (1);
256 }
257 #endif /* APPLE_HYB */
258
259 EXPORT int
j_add_match(fn)260 j_add_match(fn)
261 char *fn;
262 {
263 int ret = gen_add_match(fn, J_HIDE);
264
265 if (ret == 0)
266 return (-1);
267 return (1);
268 }
269
270 EXPORT int
u_add_match(fn)271 u_add_match(fn)
272 char *fn;
273 {
274 int ret = gen_add_match(fn, U_HIDE);
275
276 if (ret == 0)
277 return (-1);
278 return (1);
279 }
280
281 EXPORT void
gen_add_list(file,n)282 gen_add_list(file, n)
283 char *file;
284 int n;
285 {
286 FILE *fp;
287 char name[4096];
288 int len;
289
290 if ((fp = fopen(file, "r")) == NULL) {
291 comerr(_("Can't open %s file list %s\n"), mesg[n], file);
292 }
293
294 while (fgets(name, sizeof (name), fp) != NULL) {
295 /*
296 * strip of '\n'
297 */
298 len = strlen(name);
299 if (name[len - 1] == '\n') {
300 name[len - 1] = '\0';
301 }
302 if (!gen_add_match(name, n)) {
303 fclose(fp);
304 return;
305 }
306 }
307
308 fclose(fp);
309 }
310
311 EXPORT int
add_list(fn)312 add_list(fn)
313 char *fn;
314 {
315 gen_add_list(fn, EXCLUDE);
316 return (1);
317 }
318
319 EXPORT int
i_add_list(fn)320 i_add_list(fn)
321 char *fn;
322 {
323 gen_add_list(fn, I_HIDE);
324 return (1);
325 }
326
327 EXPORT int
h_add_list(fn)328 h_add_list(fn)
329 char *fn;
330 {
331 gen_add_list(fn, H_HIDE);
332 return (1);
333 }
334
335 EXPORT int
j_add_list(fn)336 j_add_list(fn)
337 char *fn;
338 {
339 gen_add_list(fn, J_HIDE);
340 return (1);
341 }
342
343 EXPORT int
u_add_list(fn)344 u_add_list(fn)
345 char *fn;
346 {
347 gen_add_list(fn, U_HIDE);
348 return (1);
349 }
350
351 #ifdef APPLE_HYB
352 EXPORT int
hfs_add_list(fn)353 hfs_add_list(fn)
354 char *fn;
355 {
356 gen_add_list(fn, HFS_HIDE);
357 return (1);
358 }
359 #endif /* APPLE_HYB */
360
361 EXPORT int
gen_matches(fn,n)362 gen_matches(fn, n)
363 char *fn;
364 int n;
365 {
366 register match * mat;
367 int flags = FNM_PATHNAME;
368
369
370 if (n >= MAX_MAT)
371 return (0);
372
373 if (match_igncase)
374 flags |= FNM_IGNORECASE;
375
376 for (mat = mats[n]; mat; mat = mat->next) {
377 if (fnmatch(mat->name, fn, flags) != FNM_NOMATCH) {
378 return (1); /* found -> excluded filename */
379 }
380 }
381 return (0); /* not found -> not excluded */
382 }
383
384 EXPORT int
gen_ishidden(n)385 gen_ishidden(n)
386 int n;
387 {
388 if (n >= MAX_MAT)
389 return (0);
390
391 return ((int)(mats[n] != 0));
392 }
393
394 EXPORT void
gen_del_match(n)395 gen_del_match(n)
396 int n;
397 {
398 register match *mat;
399 register match *mat1;
400
401 if (n >= MAX_MAT)
402 return;
403
404 mat = mats[n];
405
406 while (mat) {
407 mat1 = mat->next;
408
409 free(mat->name);
410 free(mat);
411
412 mat = mat1;
413 }
414
415 mats[n] = 0;
416 }
417