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