"Fossies" - the Fresh Open Source Software Archive 
Member "xorriso-1.5.4/xorriso/match.c" (30 Jan 2021, 22516 Bytes) of package /linux/misc/xorriso-1.5.4.pl02.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "match.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
1.5.1_vs_1.5.2.
1
2 /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
3
4 Copyright 2007-2013 Thomas Schmitt, <scdbackup@gmx.net>
5
6 Provided under GPL version 2 or later.
7
8 This file contains the implementation of functions for pattern matching.
9 */
10
11 #ifdef HAVE_CONFIG_H
12 #include "../config.h"
13 #endif
14
15 #include <ctype.h>
16 #include <sys/types.h>
17 #include <unistd.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <sys/stat.h>
22 #include <sys/time.h>
23 #include <time.h>
24 #include <fcntl.h>
25 #include <errno.h>
26
27 #include "xorriso.h"
28 #include "xorriso_private.h"
29 #include "xorrisoburn.h"
30
31
32 /* @param flag bit0= do not augment relative structured search by xorriso->wdi
33 bit1= return 2 if bonked at start point by ..
34 (caller then aborts or retries without bit0)
35 bit2= eventually prepend wdx rather than wdi
36 @return <=0 error, 1= ok, 2= with bit1: relative pattern exceeds start point
37 */
38 int Xorriso_prepare_regex(struct XorrisO *xorriso, char *adr, int flag)
39 {
40 int l,ret,i,count,bonked= 0,is_constant,is_still_relative= 0, adr_size;
41 char *cpt,*npt,*adr_part= NULL, *absolute_adr= NULL, *adr_start,*wd;
42
43 adr_size= 2 * SfileadrL;
44 Xorriso_alloc_meM(adr_part, char, adr_size);
45 Xorriso_alloc_meM(absolute_adr, char, adr_size);
46
47 if(flag&4)
48 wd= xorriso->wdx;
49 else
50 wd= xorriso->wdi;
51
52 if(xorriso->search_mode>=2 && xorriso->search_mode<=4) {
53 if(xorriso->search_mode==3 || xorriso->search_mode==4) {
54 l= strlen(adr)+strlen(wd)+1;
55 if(l * 2 + 2 > ((int) sizeof(xorriso->reg_expr)) || l * 2 + 2 > adr_size){
56 sprintf(xorriso->info_text,"Search pattern too long");
57 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
58 {ret= 0; goto ex;}
59 }
60 }
61 Xorriso_destroy_re(xorriso,0);
62 if(xorriso->structured_search && xorriso->search_mode==3) {
63 if(adr[0]!='/')
64 is_still_relative= 1;
65 if(is_still_relative && !(flag&1)) {
66 /* relative expression : prepend working directory */
67 sprintf(absolute_adr,"%s/%s",wd,adr);
68 adr_start= absolute_adr;
69 xorriso->prepended_wd= 1;
70 is_still_relative= 0;
71 } else
72 adr_start= adr;
73 /* count slashes */;
74 cpt= adr_start;
75 while(*cpt=='/')
76 cpt++;
77 for(i= 0;1;i++) {
78 cpt= strchr(cpt,'/');
79 if(cpt==NULL)
80 break;
81 while(*cpt=='/')
82 cpt++;
83 }
84 count= i+1;
85 xorriso->re= TSOB_FELD(regex_t,count);
86 if(xorriso->re==NULL)
87 {ret= -1; goto ex;}
88 xorriso->re_constants= TSOB_FELD(char *,count);
89 if(xorriso->re_constants==NULL)
90 {ret= -1; goto ex;}
91 for(i= 0;i<count;i++)
92 xorriso->re_constants[i]= NULL;
93 xorriso->re_count= count;
94 xorriso->re_fill= 0;
95
96 /* loop over slash chunks*/;
97 cpt= adr_start;
98 xorriso->re_fill= 0;
99 while(*cpt=='/')
100 cpt++;
101 for(i= 0;i<count;i++) {
102 npt= strchr(cpt,'/');
103 if(npt==NULL) {
104 if((int) strlen(cpt) >= adr_size)
105 {ret= -1; goto ex;}
106 strcpy(adr_part,cpt);
107 } else {
108 if(npt-cpt >= adr_size)
109 {ret= -1; goto ex;}
110 strncpy(adr_part,cpt,npt-cpt);
111 adr_part[npt-cpt]= 0;
112 }
113
114 if(adr_part[0]==0)
115 goto next_adr_part;
116 if(adr_part[0] == '.' && adr_part[1] == 0)
117 goto next_adr_part;
118 if(adr_part[0]=='.' && adr_part[1]=='.' && adr_part[2]==0) {
119 /* delete previous part */
120 if(xorriso->re_fill <= 0) {
121 bonked= 1;
122 goto next_adr_part;
123 }
124 if(xorriso->re_constants[xorriso->re_fill-1]!=NULL) {
125 free(xorriso->re_constants[xorriso->re_fill-1]);
126 xorriso->re_constants[xorriso->re_fill-1]= NULL;
127 } else
128 regfree(&(xorriso->re[xorriso->re_fill-1]));
129 (xorriso->re_fill)--;
130 goto next_adr_part;
131 }
132 if(strcmp(adr_part,"*")==0) {
133 adr_part[0]= 0;
134 ret= 2;
135 } else
136 ret= Xorriso__bourne_to_reg(adr_part,xorriso->reg_expr,0);
137 if(ret==2) {
138 if(Sregex_string(&(xorriso->re_constants[xorriso->re_fill]),adr_part,0)
139 <=0)
140 {ret= -1; goto ex;}
141 } else {
142 if(regcomp(&(xorriso->re[xorriso->re_fill]),xorriso->reg_expr,0)!=0)
143 goto cannot_compile;
144 }
145 xorriso->re_fill++;
146 next_adr_part:;
147 if(i==count-1)
148 break;
149 cpt= npt+1;
150 while(*cpt=='/')
151 cpt++;
152 }
153 if(bonked) {
154 if(flag&2)
155 {ret= 2; goto ex;}
156 sprintf(xorriso->info_text, "Your '..' bonked at the %s directory.",
157 is_still_relative ? "working" : "root");
158 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE",0);
159 {ret= 0; goto ex;}
160 }
161 if(xorriso->re_fill == 0 && is_still_relative) {
162 /* "." and its equivalents end up here */
163 if(Sregex_string(&(xorriso->re_constants[0]), ".", 0) <=0)
164 {ret= -1; goto ex;}
165 xorriso->re_fill= 1;
166 }
167
168 Xorriso__bourne_to_reg(adr_start,xorriso->reg_expr,0); /* just for show */
169
170 } else {
171 is_constant= 0;
172 if(strcmp(adr,"*")==0 || adr[0]==0) {
173 is_constant= 1;
174 } else if(xorriso->search_mode==3 || xorriso->search_mode==4) {
175 ret= Xorriso__bourne_to_reg(adr,xorriso->reg_expr,0);
176 is_constant= (ret==2);
177 } else {
178 if(strlen(adr)>=sizeof(xorriso->reg_expr))
179 {ret= -1; goto ex;}
180 strcpy(xorriso->reg_expr,adr);
181 }
182 xorriso->re_count= 0; /* tells matcher that this is not structured */
183 xorriso->re_constants= TSOB_FELD(char *,1);
184 if(xorriso->re_constants==NULL)
185 {ret= -1; goto ex;}
186 xorriso->re_constants[0]= NULL;
187 if(is_constant) {
188 if(strcmp(adr,"*")==0) {
189 if(Sregex_string(&(xorriso->re_constants[0]),"",0)<=0)
190 {ret= -1; goto ex;}
191 } else {
192 if(Sregex_string(&(xorriso->re_constants[0]),adr,0)<=0)
193 {ret= -1; goto ex;}
194 }
195 xorriso->re_fill= 1;
196 } else {
197 xorriso->re= TSOB_FELD(regex_t,1);
198 if(xorriso->re==NULL)
199 {ret= -1; goto ex;}
200 if(regcomp(&(xorriso->re[0]),xorriso->reg_expr,0)!=0) {
201 cannot_compile:;
202 sprintf(xorriso->info_text, "Cannot compile regular expression : %s",
203 xorriso->reg_expr);
204 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE",0);
205 {ret= 0; goto ex;}
206 }
207 }
208
209 }
210 }
211 ret= 1;
212 ex:;
213 Xorriso_free_meM(adr_part);
214 Xorriso_free_meM(absolute_adr);
215 return(ret);
216 }
217
218
219 /* @param flag bit0= do not shortcut last component of to_match
220 bit1= consider match if regex matches parent of path
221 bit2= retry beginning at failed last component
222
223 @return 0=match , else no match
224 */
225 int Xorriso_regexec(struct XorrisO *xorriso, char *to_match, int *failed_at,
226 int flag)
227 {
228 int ret,i,re_start= 0,reg_nomatch= -1;
229 char *cpt,*npt, *adr_part= NULL, *mpt;
230
231 Xorriso_alloc_meM(adr_part, char, SfileadrL);
232
233 reg_nomatch= REG_NOMATCH;
234
235 *failed_at= 0;
236 if(!(xorriso->structured_search && xorriso->re_count>0)) {
237 if(xorriso->re_constants!=NULL)
238 if(xorriso->re_constants[0]!=NULL) {
239 if(xorriso->re_constants[0][0]==0)
240 {ret= 0; goto ex;}
241 if(strcmp(xorriso->re_constants[0],to_match)!=0)
242 {ret= reg_nomatch; goto ex;}
243 {ret= 0; goto ex;}
244 }
245 ret= regexec(&(xorriso->re[0]),to_match,1,xorriso->match,0);
246 goto ex;
247 }
248
249 cpt= to_match;
250 while(*cpt=='/')
251 cpt++;
252 if(flag&4)
253 re_start= xorriso->re_failed_at;
254 if(re_start<0)
255 re_start= 0;
256 for(i= re_start;i<xorriso->re_fill;i++) {
257 *failed_at= i;
258 npt= strchr(cpt,'/');
259 if(npt==NULL) {
260 if(i<xorriso->re_fill-1 && !(flag&1))
261 {ret= reg_nomatch; goto ex;} /* this must be the last expression part */
262 mpt= cpt;
263 } else {
264 strncpy(adr_part,cpt,npt-cpt);
265 adr_part[npt-cpt]= 0;
266 mpt= adr_part;
267 }
268 if(xorriso->re_constants[i]!=NULL) {
269 if(xorriso->re_constants[i][0]!=0) /* empty constant matches anything */
270 if(strcmp(xorriso->re_constants[i],mpt)!=0)
271 {ret= reg_nomatch; goto ex;}
272 } else {
273 ret= regexec(&(xorriso->re[i]),mpt,1,xorriso->match,0);
274 if(ret!=0)
275 goto ex;
276 }
277 if(npt==NULL) {
278 if(i>=xorriso->re_fill-1)
279 {ret= 0; goto ex;} /* MATCH */
280 *failed_at= i+1;
281 {ret= reg_nomatch; goto ex;}
282 }
283 cpt= npt+1;
284 while(*cpt=='/')
285 cpt++;
286 }
287 *failed_at= xorriso->re_fill;
288 if(flag & 2)
289 {ret= 0; goto ex;} /* MATCH */
290 ret= reg_nomatch;
291 ex:;
292 Xorriso_free_meM(adr_part);
293 return(ret);
294 }
295
296
297 int Xorriso_is_in_patternlist(struct XorrisO *xorriso,
298 struct Xorriso_lsT *patternlist, char *path,
299 int flag)
300 {
301 int ret, failed_at, i= 0;
302 struct Xorriso_lsT *s;
303
304 xorriso->search_mode= 3;
305 xorriso->structured_search= 1;
306
307 for(s= patternlist; s != NULL; s= Xorriso_lst_get_next(s, 0)) {
308 ret= Xorriso_prepare_regex(xorriso, Xorriso_lst_get_text(s, 0), 0);
309 if(ret <= 0)
310 return(-1);
311 /* Match path or parent of path */
312 ret= Xorriso_regexec(xorriso, path, &failed_at, 2);
313 if(ret == 0)
314 return(i + 1);
315 i++;
316 }
317 return(0);
318 }
319
320
321 char *Xorriso_get_pattern(struct XorrisO *xorriso,
322 struct Xorriso_lsT *patternlist, int index, int flag)
323 {
324 int i= 0;
325 struct Xorriso_lsT *s;
326
327 for(s= patternlist; s != NULL; s= Xorriso_lst_get_next(s, 0)) {
328 if(i == index)
329 return(Xorriso_lst_get_text(s, 0));
330 i++;
331 }
332 return(NULL);
333 }
334
335
336
337 /* @param flag bit2= this is a disk_pattern
338 @return <=0 failure , 1 pattern ok , 2 pattern needed prepended wd */
339 int Xorriso_prepare_expansion_pattern(struct XorrisO *xorriso, char *pattern,
340 int flag)
341 {
342 int ret, prepwd= 0;
343
344 ret= Xorriso_prepare_regex(xorriso, pattern, 1|2|(flag&4));
345 if(ret==2) {
346 ret= Xorriso_prepare_regex(xorriso, pattern, flag&4);
347 prepwd= 1;
348 }
349 if(ret<=0) {
350 sprintf(xorriso->info_text,
351 "Cannot compile pattern to regular expression: %s", pattern);
352 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
353 return(0);
354 }
355 return(1+prepwd);
356 }
357
358
359 /* @param flag bit0= count results rather than storing them
360 bit1= unexpected change of number is a FATAL event
361 @return <=0 error , 1 is root (end processing) ,
362 2 is not root (go on processing)
363 */
364 int Xorriso_check_for_root_pattern(struct XorrisO *xorriso,
365 int *filec, char **filev, int count_limit, off_t *mem, int flag)
366 {
367 if(xorriso->re_fill!=0)
368 return(2);
369 /* This is the empty pattern representing root */
370 if(flag&1) {
371 (*filec)++;
372 (*mem)+= 8;
373 } else {
374 if(*filec >= count_limit) {
375 sprintf(xorriso->info_text,
376 "Number of matching files changed unexpectedly (> %d)",
377 count_limit);
378 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
379 (flag&2 ? "FATAL" : "WARNING"), 0);
380 return(flag&2 ? -1 : 0);
381 }
382 filev[*filec]= strdup("/");
383 if(filev[*filec]==NULL) {
384 Xorriso_no_pattern_memory(xorriso, (off_t) 2, 0);
385 return(-1);
386 }
387 (*filec)++;
388 }
389 return(1);
390 }
391
392
393 /* @param flag bit0= count result rather than storing it
394 bit1= unexpected change of number is a FATAL event
395 */
396 int Xorriso_register_matched_adr(struct XorrisO *xorriso,
397 char *adr, int count_limit,
398 int *filec, char **filev, off_t *mem, int flag)
399 {
400 int l;
401
402 if(flag&1) {
403 (*filec)++;
404 l= strlen(adr)+1;
405 (*mem)+= sizeof(char *)+l;
406 if(l % sizeof(char *))
407 (*mem)+= sizeof(char *)-(l % sizeof(char *));
408 } else {
409 if(*filec >= count_limit) {
410 sprintf(xorriso->info_text,
411 "Number of matching files changed unexpectedly (> %d)",
412 count_limit);
413 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
414 (flag&2 ? "FATAL" : "WARNING"), 0);
415 return(flag&2 ? -1 : 0);
416 }
417 filev[*filec]= strdup(adr);
418 if(filev[*filec]==NULL) {
419 Xorriso_no_pattern_memory(xorriso, (off_t) (strlen(adr)+1), 0);
420 return(-1);
421 }
422 (*filec)++;
423 }
424 return(1);
425 }
426
427
428 /* @param flag bit0= count results rather than storing them
429 bit1= this is a recursion
430 bit2= prepend wd (automatically done if wd[0]!=0)
431 @return <=0 error , 1 ok , 2 could not open directory
432 */
433 int Xorriso_obtain_pattern_files_x(
434 struct XorrisO *xorriso, char *wd, char *dir_adr,
435 int *filec, char **filev, int count_limit, off_t *mem,
436 int *dive_count, int flag)
437 {
438 int ret, failed_at, follow_mount, follow_links;
439 struct DirseQ *dirseq= NULL;
440 struct stat stbuf;
441 dev_t dir_dev;
442 char *path;
443 char *adr= NULL, *name= NULL, *path_data= NULL;
444
445 adr= malloc(SfileadrL);
446 name= malloc(SfileadrL);
447 path_data= malloc(SfileadrL);
448 if(adr==NULL || name==NULL || path_data==NULL) {
449 Xorriso_no_malloc_memory(xorriso, &adr, 0);
450 {ret= -1; goto ex;}
451 }
452 follow_mount= (xorriso->do_follow_mount || xorriso->do_follow_pattern);
453 follow_links= (xorriso->do_follow_links || xorriso->do_follow_pattern);
454 if(!(flag&2))
455 *dive_count= 0;
456 else
457 (*dive_count)++;
458
459 ret= Xorriso_check_for_root_pattern(xorriso, filec, filev, count_limit,
460 mem, flag&1);
461 if(ret!=2)
462 goto ex;
463
464 if(lstat(dir_adr, &stbuf)==-1)
465 {ret= 2; goto ex;}
466 dir_dev= stbuf.st_dev;
467 if(S_ISLNK(stbuf.st_mode)) {
468 if(stat(dir_adr, &stbuf)==-1)
469 {ret= 2; goto ex;}
470 if(dir_dev != stbuf.st_dev && !follow_mount)
471 {ret= 2; goto ex;}
472 }
473 ret= Dirseq_new(&dirseq, dir_adr, 1);
474 if(ret<0) {
475 sprintf(xorriso->info_text, "Cannot obtain disk directory iterator");
476 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
477 {ret= -1; goto ex;}
478 }
479 if(ret==0)
480 {ret= 2; goto ex;}
481
482 while(1) {
483 ret= Dirseq_next_adr(dirseq,name,0);
484 if(ret==0)
485 break;
486 if(ret<0) {
487 sprintf(xorriso->info_text,"Failed to obtain next directory entry");
488 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
489 {ret= -1; goto ex;}
490 }
491
492 ret= Xorriso_make_abs_adr(xorriso, wd, name, adr, flag&4);
493 if(ret<=0)
494 goto ex;
495
496 ret= Xorriso_regexec(xorriso, adr, &failed_at, 1);
497 if(ret>0) { /* no match */
498 if(failed_at <= *dive_count) /* no hope for a match */
499 continue;
500 path= adr;
501 if(adr[0]!='/') {
502 path= path_data;
503 ret= Xorriso_make_abs_adr(xorriso, xorriso->wdx, adr, path, 1|4);
504 if(ret<=0)
505 goto ex;
506 }
507
508 if(follow_links)
509 ret= stat(path,&stbuf);
510 else
511 ret= lstat(path,&stbuf);
512 if(ret==-1)
513 continue;
514 if(!S_ISDIR(stbuf.st_mode))
515 continue;
516 if(dir_dev != stbuf.st_dev && !follow_mount)
517 continue;
518
519 /* dive deeper */
520 ret= Xorriso_obtain_pattern_files_x(xorriso, adr, path,
521 filec, filev, count_limit, mem, dive_count, flag|2);
522 if(ret<=0)
523 goto ex;
524 } else {
525 ret= Xorriso_register_matched_adr(xorriso, adr, count_limit,
526 filec, filev, mem, flag&1);
527 if(ret<0)
528 goto ex;
529 if(ret==0)
530 break;
531 }
532 }
533 ret= 1;
534 ex:;
535 if(adr!=NULL)
536 free(adr);
537 if(name!=NULL)
538 free(name);
539 if(path_data!=NULL)
540 free(path_data);
541 Dirseq_destroy(&dirseq,0);
542 if(flag&2)
543 (*dive_count)--;
544 return(ret);
545 }
546
547
548 int Xorriso_eval_nonmatch(struct XorrisO *xorriso, char *pattern,
549 int *nonconst_mismatches, off_t *mem, int flag)
550 {
551 int k,l;
552
553 /* Is this a constant pattern ? */
554 for(k= 0; k<xorriso->re_fill; k++) {
555 if(xorriso->re_constants[k]==NULL)
556 break;
557 if(xorriso->re_constants[k][0]==0)
558 break;
559 }
560 if(k<xorriso->re_fill)
561 (*nonconst_mismatches)++; /* it is not */
562
563 l= strlen(pattern)+1;
564 (*mem)+= sizeof(char *)+l;
565 if(l % sizeof(char *))
566 (*mem)+= sizeof(char *)-(l % sizeof(char *));
567 return(1);
568 }
569
570
571 /* @param flag bit0= a match count !=1 is a SORRY event
572 bit1= a match count !=1 is a FAILURE event
573 */
574 int Xorriso_check_matchcount(struct XorrisO *xorriso,
575 int count, int nonconst_mismatches, int num_patterns,
576 char **patterns, int flag)
577 {
578
579 if((flag&1) && (count!=1 || nonconst_mismatches)){
580 if(count-nonconst_mismatches>0)
581 sprintf(xorriso->info_text,
582 "Pattern match with more than one file object");
583 else
584 sprintf(xorriso->info_text, "No pattern match with any file object");
585 if(num_patterns==1)
586 sprintf(xorriso->info_text+strlen(xorriso->info_text), ": ");
587 Text_shellsafe(patterns[0], xorriso->info_text, 1);
588 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
589 (flag&2 ? "FAILURE" : "SORRY"), 0);
590 return(0);
591 }
592 return(1);
593 }
594
595
596 int Xorriso_no_pattern_memory(struct XorrisO *xorriso, off_t mem, int flag)
597 {
598 char mem_text[80];
599
600 Sfile_scale((double) mem, mem_text,5,1e4,1);
601 sprintf(xorriso->info_text,
602 "Cannot allocate enough memory (%s) for pattern expansion",
603 mem_text);
604 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
605 return(1);
606 }
607
608
609 int Xorriso_alloc_pattern_mem(struct XorrisO *xorriso, off_t mem,
610 int count, char ***filev, int flag)
611 {
612 char mem_text[80], limit_text[80];
613
614 Sfile_scale((double) mem, mem_text,5,1e4,0);
615 sprintf(xorriso->info_text,
616 "Temporary memory needed for pattern expansion : %s", mem_text);
617 if(!(flag&1))
618 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
619 if(mem > xorriso->temp_mem_limit) {
620 Sfile_scale((double) xorriso->temp_mem_limit, limit_text,5,1e4,1);
621 sprintf(xorriso->info_text,
622 "List of matching file addresses exceeds -temp_mem_limit (%s > %s)",
623 mem_text, limit_text);
624 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
625 return(0);
626 }
627
628 (*filev)= (char **) calloc(count, sizeof(char *));
629 if(*filev==NULL) {
630 Xorriso_no_pattern_memory(xorriso, mem, 0);
631 return(-1);
632 }
633 return(1);
634 }
635
636
637 /* @param flag bit0= a match count !=1 is a FAILURE event
638 bit1= with bit0 tolerate 0 matches if pattern is a constant
639 bit3= do not add unresolved pattern to filev
640 */
641 int Xorriso_expand_disk_pattern(struct XorrisO *xorriso,
642 int num_patterns, char **patterns, int extra_filec,
643 int *filec, char ***filev, off_t *mem, int flag)
644 {
645 int ret, count= 0, abs_adr= 0, i, was_count, was_filec;
646 int nonconst_mismatches= 0, dive_count= 0;
647 char *dir_adr= NULL;
648
649 Xorriso_alloc_meM(dir_adr, char, SfileadrL);
650
651 *filec= 0;
652 *filev= NULL;
653
654 xorriso->search_mode= 3;
655 xorriso->structured_search= 1;
656
657 for(i= 0; i<num_patterns; i++) {
658 abs_adr= 0;
659 ret= Xorriso_prepare_expansion_pattern(xorriso, patterns[i], 4);
660 if(ret<=0)
661 goto ex;
662 if(ret==2)
663 abs_adr= 4;
664
665 if(patterns[i][0]=='/' || abs_adr) {
666 strcpy(dir_adr, "/");
667 abs_adr= 4;
668 } else {
669 strcpy(dir_adr, xorriso->wdx);
670 if(dir_adr[0]==0)
671 strcpy(dir_adr, "/");
672 ret= Sfile_type(dir_adr, 1|4);
673 if(ret!=2) {
674 Xorriso_msgs_submit(xorriso, 0, dir_adr, 0, "ERRFILE", 0);
675 sprintf(xorriso->info_text, "Address set by -cdx is not a directory: ");
676 Text_shellsafe(dir_adr, xorriso->info_text, 1);
677 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
678 ret= 0; goto ex;
679 }
680 }
681
682 /* count the matches */
683 was_count= count;
684 ret= Xorriso_obtain_pattern_files_x(xorriso, "", dir_adr, &count, NULL, 0,
685 mem, &dive_count, 1 | abs_adr);
686 if(ret<=0)
687 goto ex;
688 if(was_count==count && strcmp(patterns[i],"*")!=0 && (flag&3)!=1 &&
689 !(flag & 8)) {
690 count++;
691 ret= Xorriso_eval_nonmatch(xorriso, patterns[i],
692 &nonconst_mismatches, mem, 0);
693 if(ret<=0)
694 goto ex;
695 }
696 }
697
698 ret= Xorriso_check_matchcount(xorriso, count, nonconst_mismatches,
699 num_patterns, patterns, (flag&1)|2);
700 if(ret<=0)
701 goto ex;
702
703 count+= extra_filec;
704 (*mem)+= extra_filec * sizeof(char *);
705
706 if(count<=0)
707 {ret= !(flag & 8); goto ex;}
708
709 ret= Xorriso_alloc_pattern_mem(xorriso, *mem, count, filev, 0);
710 if(ret<=0)
711 goto ex;
712
713 /* now store addresses */
714 for(i= 0; i<num_patterns; i++) {
715 abs_adr= 0;
716 ret= Xorriso_prepare_expansion_pattern(xorriso, patterns[i], 4);
717 if(ret<=0)
718 goto ex;
719 if(ret==2)
720 abs_adr= 4;
721
722 if(patterns[i][0]=='/' || abs_adr) {
723 strcpy(dir_adr, "/");
724 abs_adr= 4;
725 } else {
726 strcpy(dir_adr, xorriso->wdx);
727 if(dir_adr[0]==0)
728 strcpy(dir_adr, "/");
729 }
730
731 was_filec= *filec;
732 ret= Xorriso_obtain_pattern_files_x(xorriso, "", dir_adr, filec, *filev,
733 count, mem, &dive_count, abs_adr);
734 if(ret<=0)
735 goto ex;
736
737 if(was_filec == *filec && strcmp(patterns[i],"*")!=0 && (flag & 3) != 1 &&
738 !(flag & 8)) {
739 (*filev)[*filec]= strdup(patterns[i]);
740 if((*filev)[*filec]==NULL) {
741 (*mem)= strlen(patterns[i])+1;
742 Xorriso_no_pattern_memory(xorriso, *mem, 0);
743 ret= -1; goto ex;
744 }
745 (*filec)++;
746 }
747 }
748
749 ret= 1;
750 ex:;
751 if(ret<=0) {
752 if(filev!=NULL)
753 Sfile_destroy_argv(&count, filev, 0);
754 *filec= 0;
755 }
756 Xorriso_free_meM(dir_adr);
757 return(ret);
758 }
759
760
761 /* @param flag bit0= command without pattern capability
762 bit1= disk_pattern rather than iso_rr_pattern
763 */
764 int Xorriso_warn_of_wildcards(struct XorrisO *xorriso, char *path, int flag)
765 {
766 static int count_iso= 0, count_disk= 0, max_iso= 3, max_disk= 3;
767
768 if(strchr(path,'*')!=NULL || strchr(path,'?')!=NULL ||
769 strchr(path,'[')!=NULL) {
770 if(flag & 2) {
771 count_disk++;
772 if(count_disk > max_disk)
773 return(1);
774 } else {
775 count_iso++;
776 if(count_iso > max_iso)
777 return(1);
778 }
779 if(flag&1) {
780 sprintf(xorriso->info_text,
781 "Pattern expansion of wildcards \"*?[\" does not apply to this command");
782 } else {
783 sprintf(xorriso->info_text,
784 "Pattern expansion of wildcards \"*?[\" is disabled by command %s",
785 (flag&2) ? "-disk_pattern or -pathspecs" : "-iso_rr_pattern");
786 }
787 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
788 sprintf(xorriso->info_text,"Pattern seen: ");
789 Text_shellsafe(path, xorriso->info_text, 1);
790 strcat(xorriso->info_text, "\n");
791 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
792 return(1);
793 }
794 return(0);
795 }
796