1
2 /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
3
4 Copyright 2007-2016 Thomas Schmitt, <scdbackup@gmx.net>
5
6 Provided under GPL version 2 or later.
7
8 This file contains the implementation of classes FindjoB, ExprnodE,
9 ExprtesT which perform tree searches in libisofs or in POSIX filesystem
10 */
11
12 #ifdef HAVE_CONFIG_H
13 #include "../config.h"
14 #endif
15
16 #include <ctype.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <sys/stat.h>
23 #include <sys/time.h>
24 #include <time.h>
25 #include <dirent.h>
26 #include <errno.h>
27
28
29 #include "xorriso.h"
30 #include "xorriso_private.h"
31 #include "xorrisoburn.h"
32
33
34 /* ----------------------- Exprtest ----------------------- */
35
36
Exprtest_new(struct ExprtesT ** ftest,struct FindjoB * boss,int flag)37 int Exprtest_new( struct ExprtesT **ftest, struct FindjoB *boss, int flag)
38 {
39 struct ExprtesT *f;
40
41 *ftest= f= TSOB_FELD(struct ExprtesT,1);
42 if(f==NULL)
43 return(-1);
44 f->boss= boss;
45 f->invert= 0;
46 f->test_type= -1;
47 f->arg1= NULL;
48 f->arg2= NULL;
49 return(1);
50 }
51
52
Exprtest_destroy(struct ExprtesT ** ftest,int flag)53 int Exprtest_destroy(struct ExprtesT **ftest, int flag)
54 {
55 struct ExprtesT *f;
56
57 f= *ftest;
58 if(f==NULL)
59 return(0);
60
61 if(f->test_type == 1 || f->test_type == 13 || f->test_type == 16) {
62 if(f->arg1 != NULL)
63 free(f->arg1);
64 if(f->arg2 != NULL) {
65 regfree(f->arg2);
66 free(f->arg2);
67 }
68 } else if(f->test_type == 9) {
69 /* arg1 is not an allocated value */;
70 } else {
71 if(f->arg1 != NULL)
72 free(f->arg1);
73 if(f->arg2 != NULL)
74 free(f->arg2);
75 }
76 free((char *) f);
77 *ftest= NULL;
78 return(1);
79 }
80
81
82 /* ----------------------- Nttpfnode ----------------------- */
83
84
Exprnode_new(struct ExprnodE ** fnode,struct FindjoB * job,struct ExprnodE * up,char * origin,int flag)85 int Exprnode_new(struct ExprnodE **fnode, struct FindjoB *job,
86 struct ExprnodE *up, char *origin, int flag)
87 /*
88 bit0= set invert-property
89 bit1= set use_shortcuts
90 */
91 {
92 struct ExprnodE *n;
93 int ret,i;
94
95 *fnode= n= TSOB_FELD(struct ExprnodE,1);
96 if(n == NULL)
97 return(-1);
98 for(i= 0; i < (int) sizeof(n->origin); i++)
99 n->origin[i]= 0;
100 strncpy(n->origin, origin, sizeof(n->origin) - 1);
101 n->up= up;
102 n->invert= (flag & 1);
103 n->assoc= 0;
104 n->use_shortcuts= !!(flag & 2);
105 n->left= NULL;
106 n->left_op= -1;
107 n->right= NULL;
108 n->right_op= -1;
109 n->sub= NULL;
110 n->is_if_then_else= 0;
111 n->true_branch= NULL;
112 n->false_branch= NULL;
113 n->test= NULL;
114 n->own_value= -1;
115 n->composed_value= -1;
116
117 ret= Exprtest_new(&(n->test), job, 0);
118 if(ret<=0){
119 Exprnode_destroy(fnode, 0);
120 return(-1);
121 }
122 return(1);
123 }
124
125
Exprnode_destroy(struct ExprnodE ** fnode,int flag)126 int Exprnode_destroy(struct ExprnodE **fnode, int flag)
127 {
128 if(*fnode == NULL)
129 return(0);
130 Exprnode_destroy(&((*fnode)->right),0);
131 Exprnode_destroy(&((*fnode)->sub),0);
132 Exprnode_destroy(&((*fnode)->true_branch),0);
133 Exprnode_destroy(&((*fnode)->false_branch),0);
134 Exprtest_destroy(&((*fnode)->test),0);
135 free((char *) *fnode);
136 *fnode= NULL;
137 return(1);
138 }
139
140
Exprnode_set_is_if(struct ExprnodE * fnode,int value,int flag)141 int Exprnode_set_is_if(struct ExprnodE *fnode, int value, int flag)
142 {
143 fnode->is_if_then_else= value;
144 return(1);
145 }
146
147
Exprnode_is_if(struct ExprnodE * fnode,int flag)148 int Exprnode_is_if(struct ExprnodE *fnode, int flag)
149 {
150 return(fnode->is_if_then_else);
151 }
152
153
Exprnode_set_branch(struct ExprnodE * fnode,struct ExprnodE * target,int flag)154 int Exprnode_set_branch(struct ExprnodE *fnode, struct ExprnodE *target,
155 int flag)
156 /*
157 bit0= false_branch (else true_branch)
158 */
159 {
160 struct ExprnodE **branch;
161
162 if(flag&1)
163 branch= &(fnode->false_branch);
164 else
165 branch= &(fnode->true_branch);
166 Exprnode_destroy(branch,0);
167 (*branch)= target;
168 return(1);
169 }
170
171
Exprnode_get_branch(struct ExprnodE * fnode,struct ExprnodE ** branch,int flag)172 int Exprnode_get_branch(struct ExprnodE *fnode, struct ExprnodE **branch,
173 int flag)
174 /*
175 bit0= false_branch (else true_branch)
176 */
177 {
178 if(flag&1)
179 (*branch)= fnode->false_branch;
180 else
181 (*branch)= fnode->true_branch;
182 return(1);
183 }
184
185
Exprnode_is_defined(struct ExprnodE * fnode,int flag)186 int Exprnode_is_defined(struct ExprnodE *fnode, int flag)
187 {
188 struct ExprtesT *ftest;
189
190 if(fnode==NULL)
191 return(0);
192 if(fnode->sub!=NULL)
193 return(1);
194 ftest= fnode->test;
195 if(ftest==NULL)
196 return(0);
197 if(ftest->test_type>=0)
198 return(1);
199 return(0);
200 }
201
202
Exprnode_own_value(struct XorrisO * xorriso,struct ExprnodE * fnode,void * node,char * name,char * path,struct stat * boss_stbuf,struct stat * stbuf,int flag)203 int Exprnode_own_value(struct XorrisO *xorriso, struct ExprnodE *fnode,
204 void *node, char *name, char *path,
205 struct stat *boss_stbuf, struct stat *stbuf, int flag)
206 /*
207 flag:
208 return: (also from Exprtest_match() and Exprnode_tree_value() )
209 <0 = error
210 0 = does not match
211 1 = does match
212 2 = immediate decision : does not match
213 3 = immediate decision : does match
214 */
215 {
216 int ret;
217
218 if(fnode==NULL)
219 return(1);
220 if(fnode->sub!=NULL) {
221 ret= Exprnode_tree_value(xorriso, fnode->sub, -1,
222 node, name, path, boss_stbuf, stbuf, 0);
223 } else {
224 ret= Exprtest_match(xorriso, fnode->test, node, name, path,
225 boss_stbuf, stbuf, 0);
226 }
227 if(ret<0)
228 return(ret);
229 if(ret>1)
230 return(ret);
231 if(fnode->invert)
232 ret= !ret;
233 return(ret);
234 }
235
236
Exprnode_op(int value1,int value2,int op,int flag)237 int Exprnode_op(int value1, int value2, int op, int flag)
238 {
239 int ret;
240
241 if(op==0)
242 ret= value1 || value2 ;
243 else
244 ret= value1 && value2 ;
245 return(ret);
246 }
247
248
Exprnode_tree_value(struct XorrisO * xorriso,struct ExprnodE * fnode,int left_value,void * node,char * name,char * path,struct stat * boss_stbuf,struct stat * stbuf,int flag)249 int Exprnode_tree_value(struct XorrisO *xorriso, struct ExprnodE *fnode,
250 int left_value, void *node, char *name, char *path,
251 struct stat *boss_stbuf, struct stat *stbuf, int flag)
252 /*
253 bit0-7= testmode: 0=head , 1=filename
254 return: (also from Nntpftest_match() and Nntpfnode_own_value() )
255 <0 = error
256 0 = does not match
257 1 = does match
258 2 = immediate decision : does not match
259 3 = immediate decision : does match
260 */
261 {
262 int value= 1,ret;
263
264 if(fnode==NULL)
265 return(1);
266 if(!Exprnode_is_defined(fnode,0))
267 return(1);
268
269 if(fnode->use_shortcuts && fnode->left!=NULL){
270 fnode->composed_value= left_value;
271 if(fnode->left_op==0) {/* OR */
272 if(left_value!=0)
273 goto ex;
274 } else { /* AND */
275 if(left_value==0)
276 goto ex;
277 }
278 }
279 fnode->composed_value= fnode->own_value=
280 Exprnode_own_value(xorriso, fnode, node, name, path, boss_stbuf, stbuf, 0);
281 if(fnode->own_value < 0 || fnode->own_value > 1)
282 return(fnode->own_value);
283
284 if(fnode->assoc == 0){ /* left associative */
285 if(fnode->left != NULL && left_value >= 0)
286 fnode->composed_value=
287 Exprnode_op(left_value, fnode->own_value, fnode->left_op, 0);
288 /* compute right value */
289 /* is the right value relevant ? */
290 if(fnode->right!=NULL){
291 if(fnode->use_shortcuts){
292 if(fnode->right_op==0) {/* OR */
293 if(fnode->composed_value!=0)
294 goto ex;
295 } else { /* AND */
296 if(fnode->composed_value==0)
297 goto ex;
298 }
299 }
300 value= Exprnode_tree_value(xorriso, fnode->right,fnode->composed_value,
301 node, name, path, boss_stbuf, stbuf, 0);
302 if(value<0 || value>1)
303 return(value);
304 fnode->composed_value= value;
305 }
306 }else{ /* right associative */
307 if(fnode->right!=NULL){
308 /* is the right value relevant ? */
309 if(fnode->use_shortcuts){
310 if(fnode->right_op==0) {/* OR */
311 if(fnode->composed_value!=0)
312 goto ex;
313 } else { /* AND */
314 if(fnode->composed_value==0)
315 goto ex;
316 }
317 }
318 value= Exprnode_tree_value(xorriso, fnode->right,fnode->own_value,
319 node, name, path, boss_stbuf, stbuf, 0);
320 if(value<0||value>1)
321 return(value);
322 } else
323 value= fnode->own_value;
324 fnode->composed_value= value;
325 if(fnode->left!=NULL && left_value>=0)
326 fnode->composed_value=
327 Exprnode_op(left_value,fnode->composed_value,fnode->left_op,0);
328 }
329 ex:
330 ret= fnode->composed_value;
331 if(fnode->is_if_then_else) {
332 /* The if-condition is evaluated. Now follow the chosen branch */
333 struct ExprnodE *branch;
334 if(ret>0)
335 branch= fnode->true_branch;
336 else
337 branch= fnode->false_branch;
338 if(branch!=NULL) {
339 ret= Exprnode_tree_value(xorriso, branch, -1,
340 node, name, path, boss_stbuf, stbuf, 0);
341 if(ret<0)
342 return(ret);
343 if(ret>1)
344 return(ret);
345 }
346 fnode->composed_value= ret;
347 }
348 return(fnode->composed_value);
349 }
350
351
352 /* --------------------- Findjob -------------------- */
353
354
Findjob_new(struct FindjoB ** o,char * start_path,int flag)355 int Findjob_new(struct FindjoB **o, char *start_path, int flag)
356 {
357 struct FindjoB *m;
358 int ret;
359
360 m= *o= TSOB_FELD(struct FindjoB,1);
361 if(m==NULL)
362 return(-1);
363 m->start_path= NULL;
364 m->test_tree= NULL;
365 m->cursor= NULL;
366 m->invert= 0;
367 m->use_shortcuts= 1;
368 m->action= 0; /* print */
369 m->prune= 0;
370 m->use_pattern= 1;
371 m->target= NULL; /* a mere pointer, not managed memory */
372 m->text_2= NULL; /* a mere pointer, not managed memory */
373 m->user= 0;
374 m->group= 0;
375 m->type= 0;
376 m->date= 0;
377 m->start_path= strdup(start_path);
378 if(m->start_path==NULL)
379 goto failed;
380 m->found_path= NULL;
381 m->estim_upper_size= 0;
382 m->estim_lower_size= 0;
383 m->subjob= NULL;
384 m->errmsg[0]= 0;
385 m->errn= 0;
386 m->match_count= 0;
387 m->depth= 0;
388
389 ret= Exprnode_new(&(m->test_tree), m, NULL, "-find", (m->use_shortcuts)<<1);
390 if(ret<=0)
391 goto failed;
392 m->cursor= m->test_tree;
393 return(1);
394
395 failed:;
396 Findjob_destroy(o, 0);
397 return(-1);
398 }
399
400
Findjob_destroy(struct FindjoB ** o,int flag)401 int Findjob_destroy(struct FindjoB **o, int flag)
402 {
403 struct FindjoB *m;
404
405 m= *o;
406 if(m==NULL)
407 return(0);
408 if(m->test_tree != NULL)
409 Exprnode_destroy(&(m->test_tree), 0);
410 if(m->start_path != NULL)
411 free(m->start_path);
412 if(m->found_path != NULL)
413 free(m->found_path);
414 free((char *) *o);
415 *o= NULL;
416 return(1);
417 }
418
419
Findjob_set_start_path(struct FindjoB * o,char * start_path,int flag)420 int Findjob_set_start_path(struct FindjoB *o, char *start_path, int flag)
421 {
422 if(o->start_path!=NULL)
423 free(o->start_path);
424 if(start_path!=NULL) {
425 o->start_path= strdup(start_path);
426 if(o->start_path==NULL)
427 return(-1);
428 } else
429 o->start_path= NULL;
430 return(1);
431 }
432
433
Findjob_get_start_path(struct FindjoB * o,char ** start_path,int flag)434 int Findjob_get_start_path(struct FindjoB *o, char **start_path, int flag)
435 {
436 *start_path= o->start_path;
437 return(1);
438 }
439
440
Findjob_cursor_complete(struct FindjoB * job,int flag)441 int Findjob_cursor_complete( struct FindjoB *job, int flag)
442 {
443 int ret;
444
445 if(job==NULL)
446 return(0);
447 ret= Exprnode_is_defined(job->cursor,0);
448 return(ret);
449 }
450
451
Findjob_is_restrictive(struct FindjoB * job,int flag)452 int Findjob_is_restrictive(struct FindjoB *job, int flag)
453 {
454 if(job == NULL)
455 return(0);
456 if(job->test_tree == NULL)
457 return(0);
458 if(!Exprnode_is_defined(job->test_tree, 0))
459 return(0);
460 return(1);
461 }
462
463
Findjob_new_node(struct FindjoB * job,struct ExprnodE ** fnode,char * origin,int flag)464 int Findjob_new_node(struct FindjoB *job, struct ExprnodE **fnode,
465 char *origin, int flag)
466 /*
467 bit0= open new branch
468 bit1= with bit0 : do not register as sub-node of job->cursor
469 */
470 {
471 int ret;
472 struct ExprnodE *f;
473
474 ret= Exprnode_new(fnode,job,NULL,origin,
475 job->invert|((job->use_shortcuts)<<1));
476 if(ret<=0)
477 return(ret);
478 f= *fnode;
479 if(flag&1) {
480 f->up= job->cursor;
481 if(job->cursor!=NULL && !(flag&2)) {
482 if(job->cursor->sub!=NULL) {
483 /* This would become a memory leak */
484 job->errn= -2;
485 sprintf(job->errmsg,
486 "Program error while parsing -job : sub branch overwrite");
487 Exprnode_destroy(fnode, 0);
488 return(0);
489 } else
490 job->cursor->sub= f;
491 }
492 } else {
493 if(job->cursor != NULL)
494 f->up= job->cursor->up;
495 f->left= job->cursor;
496 if(job->cursor!=NULL)
497 job->cursor->right= f;
498 }
499 job->invert= 0;
500 return(1);
501 }
502
503
504 /* If an operator is expected : use -and
505 @param flag bit0= prepare for a pseudo-test:
506 if an operator is expected, do nothing and return 2
507 bit1= use -or rather than -and
508 */
Findjob_default_and(struct FindjoB * o,int flag)509 int Findjob_default_and(struct FindjoB *o, int flag)
510 {
511 int ret;
512
513 if(Findjob_cursor_complete(o, 0)) {
514 if(flag & 1)
515 return(2);
516 if(flag & 2) {
517 ret= Findjob_or(o, 0);
518 } else {
519 ret= Findjob_and(o, 0);
520 }
521 if(ret <= 0)
522 return(ret);
523 }
524 return(1);
525 }
526
527
Findjob_open_bracket(struct FindjoB * job,int flag)528 int Findjob_open_bracket(struct FindjoB *job, int flag)
529 {
530 int ret;
531 struct ExprnodE *fnode;
532
533 ret= Findjob_default_and(job, 0);
534 if(ret <= 0)
535 return(ret);
536 ret= Findjob_new_node(job, &fnode, "-sub", 1);
537 if(ret <= 0)
538 return(ret);
539 job->cursor= fnode;
540 return(1);
541 }
542
543
Findjob_close_bracket(struct FindjoB * job,int flag)544 int Findjob_close_bracket(struct FindjoB *job, int flag)
545 {
546 if(!Findjob_cursor_complete(job, 0)) {
547 job->errn= -3;
548 sprintf(job->errmsg,
549 "Unary operator or expression expected, closing-bracket found");
550 return(0);
551 }
552
553 if(job->cursor->up==NULL){
554 job->errn= -1;
555 sprintf(job->errmsg,
556 "No bracket open when encountering closing bracket.");
557 return(0);
558 }
559 job->cursor= job->cursor->up;
560 return(1);
561 }
562
563
Findjob_not(struct FindjoB * job,int flag)564 int Findjob_not(struct FindjoB *job, int flag)
565 {
566 int ret;
567
568 ret= Findjob_default_and(job, 0);
569 if(ret <= 0)
570 return(ret);
571 job->cursor->invert= !job->cursor->invert;
572 return(1);
573 }
574
575
Findjob_and(struct FindjoB * job,int flag)576 int Findjob_and(struct FindjoB *job, int flag)
577 {
578 int ret;
579 struct ExprnodE *fnode;
580
581 if(!Findjob_cursor_complete(job, 0)) {
582 job->errn= -3;
583 sprintf(job->errmsg,
584 "Unary operator or expression expected, binary operator found");
585 return(0);
586 }
587
588 ret= Findjob_new_node(job, &fnode, "-and", 0);
589 if(ret<=0)
590 return(ret);
591 job->cursor->right_op= 1;
592 job->cursor->assoc= 1; /* compute right side first */
593 fnode->left_op= 1;
594 fnode->assoc= 0; /* compute left side first */
595 job->cursor= fnode;
596 return(1);
597 }
598
599
Findjob_or(struct FindjoB * job,int flag)600 int Findjob_or(struct FindjoB *job, int flag)
601 {
602 int ret;
603 struct ExprnodE *fnode;
604
605 if(!Findjob_cursor_complete(job, 0)) {
606 job->errn= -3;
607 sprintf(job->errmsg,
608 "Unary operator or expression expected, binary operator found");
609 return(0);
610 }
611
612 ret= Findjob_new_node(job, &fnode, "-or", 0);
613 if(ret<=0)
614 return(ret);
615 job->cursor->right= fnode;
616 job->cursor->right_op= 0;
617 /* if existing : compute left side first */
618 job->cursor->assoc= (job->cursor->left == NULL);
619 fnode->left= job->cursor;
620 fnode->left_op= 0;
621 fnode->assoc= 0; /* no right side yet : compute left side first */
622 job->cursor= fnode;
623 return(1);
624 }
625
626
Findjob_if(struct FindjoB * job,int flag)627 int Findjob_if(struct FindjoB *job, int flag)
628 {
629 int ret;
630 struct ExprnodE *fnode;
631
632 ret= Findjob_default_and(job, 0);
633 if(ret <= 0)
634 return(ret);
635 ret= Findjob_new_node(job, &fnode, "-if", 1);
636 if(ret<=0)
637 return(ret);
638 Exprnode_set_is_if(fnode,1,0);
639 job->cursor= fnode;
640 return(1);
641 }
642
643
Findjob_then(struct FindjoB * job,int flag)644 int Findjob_then(struct FindjoB *job, int flag)
645 {
646 int ret;
647 struct ExprnodE *fnode,*branch= NULL;
648
649 if(! Findjob_cursor_complete(job,0)) {
650 job->errn= -3;
651 sprintf(job->errmsg,
652 "Unary operator or expression expected, -then-operator found");
653 return(0);
654 }
655 /* Finding the -if that matches this -then
656 Do not go up one node but look for the leftmost one.
657 If everything is right we are at level of the -if node */
658 while(job->cursor->left!=NULL)
659 job->cursor= job->cursor->left;
660 Exprnode_get_branch(job->cursor, &branch, 0);
661 if(!Exprnode_is_if(job->cursor, 0) || branch != NULL) {
662 job->errn= -5;
663 sprintf(job->errmsg, "-then-operator found outside its proper range.");
664 return(0);
665 }
666 ret= Findjob_new_node(job, &fnode, "-then", 1|2);
667 if(ret <= 0)
668 return(ret);
669 Exprnode_set_branch(job->cursor, fnode, 0);
670 job->cursor= fnode;
671 return(1);
672 }
673
674
Findjob_else(struct FindjoB * job,int flag)675 int Findjob_else(struct FindjoB *job, int flag)
676 {
677 int ret;
678 struct ExprnodE *fnode, *true_branch, *false_branch;
679
680 if(! Findjob_cursor_complete(job, 0)) {
681 job->errn= -3;
682 sprintf(job->errmsg,
683 "Unary operator or expression expected, -else-operator found");
684 return(0);
685 }
686 if(job->cursor->up == NULL)
687 goto improper_range;
688 job->cursor= job->cursor->up;
689 Exprnode_get_branch(job->cursor, &true_branch, 0);
690 Exprnode_get_branch(job->cursor, &false_branch, 1);
691 if(!Exprnode_is_if(job->cursor, 0) ||
692 true_branch == NULL || false_branch != NULL) {
693 improper_range:;
694 job->errn= -5;
695 sprintf(job->errmsg, "-else-operator found outside its proper range.");
696 return(0);
697 }
698 ret= Findjob_new_node(job, &fnode, "-else", 1 | 2);
699 if(ret <= 0)
700 return(ret);
701 Exprnode_set_branch(job->cursor, fnode, 1);
702 job->cursor= fnode;
703 return(1);
704 }
705
706
Findjob_elseif(struct FindjoB * job,int flag)707 int Findjob_elseif(struct FindjoB *job, int flag)
708 {
709 int ret;
710 struct ExprnodE *true_branch, *false_branch;
711
712 if(!Findjob_cursor_complete(job, 0)) {
713 job->errn= -3;
714 sprintf(job->errmsg,
715 "Unary operator or expression expected, -elseif-operator found");
716 return(0);
717 }
718 if(job->cursor->up == NULL)
719 goto improper_range;
720 job->cursor= job->cursor->up;
721 Exprnode_get_branch(job->cursor, &true_branch, 0);
722 Exprnode_get_branch(job->cursor, &false_branch, 1);
723 if(!Exprnode_is_if(job->cursor, 0) ||
724 true_branch==NULL || false_branch!=NULL) {
725 improper_range:;
726 job->errn= -5;
727 sprintf(job->errmsg,
728 "-elseif-operator found outside its proper range.");
729 return(0);
730 }
731 job->cursor= job->cursor->up;
732 /* -elseif is equivalent to the three-step sequence : -endif -or -if
733 ( -endif has already been performed by following job->cursor->up ) */
734 ret= Findjob_or(job, 0);
735 if(ret <= 0)
736 return(0);
737 ret= Findjob_if(job, 0);
738 if(ret <= 0)
739 return(0);
740 return(1);
741 }
742
743
Findjob_endif(struct FindjoB * job,int flag)744 int Findjob_endif(struct FindjoB *job, int flag)
745 {
746 struct ExprnodE *true_branch;
747
748 if(!Findjob_cursor_complete(job,0)) {
749 job->errn= -3;
750 sprintf(job->errmsg,
751 "Unary operator or expression expected, -endif found");
752 return(0);
753 }
754 if(job->cursor->up==NULL)
755 goto improper_range;
756 /* test wether parent node is -if */
757 job->cursor= job->cursor->up;
758 Exprnode_get_branch(job->cursor, &true_branch, 0);
759 if(!Exprnode_is_if(job->cursor,0) || true_branch == NULL) {
760 improper_range:;
761 job->errn= -5;
762 sprintf(job->errmsg, "-endif-mark found outside its proper range.");
763 return(0);
764 }
765 /* go to grand parent node */
766 job->cursor= job->cursor->up;
767 return(1);
768 }
769
770
771 /* @param flag bit0-1: 0= -name , 1= -wholename , 2= -disk_name , 3= -disk_path
772 */
Findjob_set_name_expr(struct FindjoB * o,char * name_expr,int flag)773 int Findjob_set_name_expr(struct FindjoB *o, char *name_expr, int flag)
774 {
775 char *regexpr= NULL;
776 regex_t *name_re;
777 struct ExprtesT *t;
778 int ret;
779
780 regexpr= TSOB_FELD(char, 2*SfileadrL+2);
781 if(regexpr == NULL)
782 {ret= -1; goto ex;}
783 if(strlen(name_expr)>=SfileadrL)
784 {ret= 0; goto ex;};
785
786 ret= Findjob_default_and(o, 0);
787 if(ret <= 0)
788 goto ex;
789 t= o->cursor->test;
790 t->test_type= 1;
791 if ((flag & 3) == 1)
792 t->test_type= 13;
793 else if((flag & 3) == 2)
794 t->test_type= 16;
795 else if((flag & 3) == 3)
796 t->test_type= 20;
797 t->arg1= strdup(name_expr);
798 if(t->arg1 == NULL)
799 {ret= -1; goto ex;};
800
801 if((flag & 3) == 3)
802 {ret= 1; goto ex;}
803
804 name_re= (regex_t *) calloc(1, sizeof(regex_t));
805 if(name_re == NULL)
806 {ret= -1; goto ex;};
807 Xorriso__bourne_to_reg(name_expr, regexpr, 0);
808 if(regcomp(name_re, regexpr, 0) != 0) {
809 free((char *) name_re);
810 {ret= 0; goto ex;};
811 }
812 t->arg2= name_re;
813 ret= 1;
814 ex:;
815 Xorriso_free_meM(regexpr);
816 return(ret);
817 }
818
819
Findjob_set_file_type(struct FindjoB * o,char file_type,int flag)820 int Findjob_set_file_type(struct FindjoB *o, char file_type, int flag)
821 {
822 static char known[]= {"bcdpf-lsmeX"};
823 struct ExprtesT *t;
824 int ret;
825
826 ret= Findjob_default_and(o, 0);
827 if(ret <= 0)
828 return(ret);
829
830 if(file_type != 0)
831 if(strchr(known, file_type) == NULL)
832 return(0);
833 t= o->cursor->test;
834 t->test_type= 2;
835 t->arg1= calloc(1, 1);
836 if(t->arg1 == NULL)
837 return(-1);
838 *((char *) t->arg1)= file_type;
839 return(1);
840 }
841
842
843 /* @param value -1= only without property, 1= only with property
844 @param flag bit0= pseudo-test:
845 if no operator is open, do nothing and return 2
846 */
Findjob_set_prop_filter(struct FindjoB * o,int test_type,int value,int flag)847 int Findjob_set_prop_filter(struct FindjoB *o, int test_type, int value,
848 int flag)
849 {
850 struct ExprtesT *t;
851 int ret;
852
853 ret= Findjob_default_and(o, flag & 1);
854 if(ret <= 0 || ret == 2)
855 return(ret);
856
857 t= o->cursor->test;
858 t->test_type= test_type;
859 if(value < 0)
860 t->invert= !t->invert;
861 return(1);
862 }
863
864
865 /* @param value -1= only undamaged files, 1= only damaged files
866 */
Findjob_set_damage_filter(struct FindjoB * o,int value,int flag)867 int Findjob_set_damage_filter(struct FindjoB *o, int value, int flag)
868 {
869 int ret;
870
871 ret= Findjob_set_prop_filter(o, 3, value, 0);
872 return(ret);
873 }
874
875
Findjob_set_num_filter(struct FindjoB * o,int test_type,int num1,int num2,int flag)876 int Findjob_set_num_filter(struct FindjoB *o, int test_type,
877 int num1, int num2, int flag)
878 {
879 struct ExprtesT *t;
880 int ret;
881
882 ret= Findjob_default_and(o, 0);
883 if(ret <= 0)
884 return(ret);
885
886 t= o->cursor->test;
887 t->test_type= test_type;
888 t->arg1= calloc(sizeof(int), 1);
889 t->arg2= calloc(sizeof(int), 1);
890 if(t->arg1 == NULL || t->arg2 == NULL)
891 return(-1);
892 *((int *) t->arg1)= num1;
893 *((int *) t->arg2)= num2;
894 return(1);
895 }
896
897
Findjob_set_lba_range(struct FindjoB * o,int start_lba,int count,int flag)898 int Findjob_set_lba_range(struct FindjoB *o, int start_lba, int count,
899 int flag)
900 {
901 int ret, end_lba;
902
903 if(start_lba > 0)
904 end_lba= start_lba + count - 1;
905 else
906 end_lba= start_lba - count + 1;
907 ret= Findjob_set_num_filter(o, 4, start_lba, end_lba, 0);
908 return(ret);
909 }
910
911
Findjob_set_test_hidden(struct FindjoB * o,int mode,int flag)912 int Findjob_set_test_hidden(struct FindjoB *o, int mode, int flag)
913 {
914 struct ExprtesT *t;
915 int ret;
916
917 ret= Findjob_default_and(o, 0);
918 if(ret <= 0)
919 return(ret);
920
921 t= o->cursor->test;
922 t->test_type= 17;
923 t->arg1= calloc(sizeof(int), 1);
924 if(t->arg1 == NULL)
925 return(-1);
926 *((int *) t->arg1)= mode;
927 return(1);
928 }
929
930
931 /* @param value -1= files without ACL, 1= only files with ACL
932 */
Findjob_set_acl_filter(struct FindjoB * o,int value,int flag)933 int Findjob_set_acl_filter(struct FindjoB *o, int value, int flag)
934 {
935 int ret;
936
937 ret= Findjob_set_prop_filter(o, 5, value, 0);
938 return(ret);
939 }
940
941
942 /* @param value -1= files without xattr, 1= only files with xattr
943 @param flag bit0=-has_any_xattr rather than -has_xattr
944 */
Findjob_set_xattr_filter(struct FindjoB * o,int value,int flag)945 int Findjob_set_xattr_filter(struct FindjoB *o, int value, int flag)
946 {
947 int ret;
948
949 ret= Findjob_set_prop_filter(o, (flag & 1 ? 14 : 6), value, 0);
950 return(ret);
951 }
952
953
954 /* @param value -1= files without aaip, 1= only files with aaip
955 */
Findjob_set_aaip_filter(struct FindjoB * o,int value,int flag)956 int Findjob_set_aaip_filter(struct FindjoB *o, int value, int flag)
957 {
958 int ret;
959
960 ret= Findjob_set_prop_filter(o, 7, value, 0);
961 return(ret);
962 }
963
964
965 /* @param value -1= files without filter, 1= files with filter
966 */
Findjob_set_filter_filter(struct FindjoB * o,int value,int flag)967 int Findjob_set_filter_filter(struct FindjoB *o, int value, int flag)
968 {
969 int ret;
970
971 ret= Findjob_set_prop_filter(o, 8, value, 0);
972 return(ret);
973 }
974
975
Findjob_set_crtp_filter(struct FindjoB * o,char * creator,char * hfs_type,int flag)976 int Findjob_set_crtp_filter(struct FindjoB *o, char *creator, char *hfs_type,
977 int flag)
978 {
979 struct ExprtesT *t;
980 int ret;
981
982 ret= Findjob_default_and(o, 0);
983 if(ret <= 0)
984 return(ret);
985
986 t= o->cursor->test;
987 t->test_type= 18;
988 t->arg1= calloc(1, strlen(creator) + 1);
989 t->arg2= calloc(1, strlen(hfs_type) + 1);
990 if(t->arg1 == NULL || t->arg2 == NULL)
991 return(-1);
992 strcpy(t->arg1, creator);
993 strcpy(t->arg2, hfs_type);
994 return(1);
995 }
996
997
Findjob_set_bless_filter(struct XorrisO * xorriso,struct FindjoB * o,char * blessing,int flag)998 int Findjob_set_bless_filter(struct XorrisO *xorriso, struct FindjoB *o,
999 char *blessing, int flag)
1000 {
1001 struct ExprtesT *t;
1002 int ret;
1003
1004 ret= Findjob_default_and(o, 0);
1005 if(ret <= 0)
1006 return(ret);
1007
1008 t= o->cursor->test;
1009 t->test_type= 19;
1010 t->arg1= calloc(1, sizeof(int));
1011 if(t->arg1 == NULL)
1012 return(-1);
1013 ret= Xorriso_hfsplus_bless(xorriso, "", NULL, blessing, 4 | 8);
1014 if(ret <= 0)
1015 return(ret);
1016 *((int *) t->arg1)= ret - 1;
1017 return(1);
1018 }
1019
1020
Findjob_set_wanted_node(struct FindjoB * o,void * wanted_node,int flag)1021 int Findjob_set_wanted_node(struct FindjoB *o, void *wanted_node, int flag)
1022 {
1023 struct ExprtesT *t;
1024 int ret;
1025
1026 ret= Findjob_default_and(o, 0);
1027 if(ret <= 0)
1028 return(ret);
1029
1030 t= o->cursor->test;
1031 t->test_type= 9;
1032 t->arg1= wanted_node;
1033 return(1);
1034 }
1035
1036
Findjob_set_commit_filter_2(struct FindjoB * o,int flag)1037 int Findjob_set_commit_filter_2(struct FindjoB *o, int flag)
1038 {
1039 int ret;
1040
1041 ret= Findjob_default_and(o, 0);
1042 if(ret <= 0)
1043 return(ret);
1044
1045 o->cursor->test->test_type= 10;
1046 return(1);
1047 }
1048
1049
Findjob_set_arg1(struct FindjoB * o,int test_type,char * arg1,int flag)1050 int Findjob_set_arg1(struct FindjoB *o, int test_type, char *arg1, int flag)
1051 {
1052 struct ExprtesT *t;
1053 int ret, hflag= 0;
1054
1055 if(test_type == 23)
1056 hflag= 2; /* prepend -or rather than -and */
1057 ret= Findjob_default_and(o, hflag);
1058 if(ret <= 0)
1059 return(ret);
1060 t= o->cursor->test;
1061 t->test_type= test_type;
1062 t->arg1= strdup(arg1);
1063 if(t->arg1 == NULL)
1064 return(-1);
1065 return(1);
1066 }
1067
1068
1069 /* @param value -1= true, 1= false
1070 @param flag bit0= pseudo-test:
1071 if no operator is open, do nothing and return 2
1072 */
Findjob_set_false(struct FindjoB * o,int value,int flag)1073 int Findjob_set_false(struct FindjoB *o, int value, int flag)
1074 {
1075 int ret;
1076
1077 ret= Findjob_set_prop_filter(o, 0, value, flag & 1);
1078 return(ret);
1079 }
1080
1081
Findjob_set_prune(struct FindjoB * o,int flag)1082 int Findjob_set_prune(struct FindjoB *o, int flag)
1083 {
1084 int ret;
1085
1086 ret= Findjob_set_prop_filter(o, 12, 0, 0);
1087 return(ret);
1088 }
1089
1090
Findjob_set_found_path(struct FindjoB * o,char * path,int flag)1091 int Findjob_set_found_path(struct FindjoB *o, char *path, int flag)
1092 {
1093 if(o->found_path != NULL)
1094 free(o->found_path);
1095 if(path != NULL) {
1096 o->found_path= strdup(path);
1097 if(o->found_path == NULL)
1098 return(-1);
1099 } else
1100 o->found_path= NULL;
1101 return(1);
1102 }
1103
1104
Findjob_get_found_path(struct FindjoB * o,char ** path,int flag)1105 int Findjob_get_found_path(struct FindjoB *o, char **path, int flag)
1106 {
1107 *path= o->found_path;
1108 return(1);
1109 }
1110
1111
Findjob_get_last_data_file_block(struct FindjoB * o,uint32_t * lba,int flag)1112 int Findjob_get_last_data_file_block(struct FindjoB *o, uint32_t *lba,
1113 int flag)
1114 {
1115 *lba= o->last_data_file_block;
1116 return(1);
1117 }
1118
1119
Findjob_get_action(struct FindjoB * o,int flag)1120 int Findjob_get_action(struct FindjoB *o, int flag)
1121 {
1122 return(o->action);
1123 }
1124
1125
1126 /* @return <0 error, >=0 see above struct FindjoB.action
1127 */
Findjob_get_action_parms(struct FindjoB * o,char ** target,char ** text_2,uid_t * user,gid_t * group,mode_t * mode_and,mode_t * mode_or,int * type,time_t * date,struct FindjoB ** subjob,int flag)1128 int Findjob_get_action_parms(struct FindjoB *o, char **target, char **text_2,
1129 uid_t *user, gid_t *group,
1130 mode_t *mode_and, mode_t *mode_or,
1131 int *type, time_t *date, struct FindjoB **subjob,
1132 int flag)
1133 {
1134 *target= o->target;
1135 *text_2= o->text_2;
1136 *user= o->user;
1137 *group= o->group;
1138 *mode_and= o->mode_and;
1139 *mode_or= o->mode_or;
1140 *type= o->type;
1141 *date= o->date;
1142 *subjob= o->subjob;
1143 return(o->action);
1144 }
1145
1146
Findjob_test_2(struct XorrisO * xorriso,struct FindjoB * o,void * node,char * name,char * path,struct stat * boss_stbuf,struct stat * stbuf,int flag)1147 int Findjob_test_2(struct XorrisO *xorriso, struct FindjoB *o,
1148 void *node, char *name, char *path,
1149 struct stat *boss_stbuf, struct stat *stbuf, int flag)
1150 {
1151 int ret;
1152
1153 ret= Exprnode_tree_value(xorriso, o->test_tree, -1,
1154 node, name, path, boss_stbuf, stbuf, 0);
1155 if(ret == 3)
1156 ret= 1;
1157 else if(ret == 2)
1158 ret= 0;
1159 return(ret);
1160 }
1161
1162
Findjob_set_action_target(struct FindjoB * o,int action,char * target,int flag)1163 int Findjob_set_action_target(struct FindjoB *o, int action, char *target,
1164 int flag)
1165 {
1166 o->action= action;
1167 o->target= target;
1168 return(1);
1169 }
1170
1171
Findjob_set_action_type(struct FindjoB * o,int action,int type,int flag)1172 int Findjob_set_action_type(struct FindjoB *o, int action, int type,
1173 int flag)
1174 {
1175 o->action= action;
1176 o->type= type;
1177 return(1);
1178 }
1179
1180
Findjob_set_action_text_2(struct FindjoB * o,int action,char * target,char * text_2,int flag)1181 int Findjob_set_action_text_2(struct FindjoB *o, int action, char *target,
1182 char* text_2, int flag)
1183 {
1184 o->action= action;
1185 o->target= target;
1186 o->text_2= text_2;
1187 return(1);
1188 }
1189
1190
1191 /* @param flag bit0= recursive
1192 */
Findjob_set_action_chown(struct FindjoB * o,uid_t user,int flag)1193 int Findjob_set_action_chown(struct FindjoB *o, uid_t user,int flag)
1194 {
1195 int ret;
1196
1197 if(flag&1) {
1198 o->action= 0;
1199 Findjob_destroy(&(o->subjob), 0);
1200 ret= Findjob_new(&(o->subjob), "", 0);
1201 if(ret<=0)
1202 return(-1);
1203 Findjob_set_action_chown(o->subjob, user, 0);
1204 o->action= 9;
1205 } else {
1206 o->action= 4;
1207 o->user= user;
1208 }
1209 return(1);
1210 }
1211
1212
1213 /* @param flag bit0= recursive
1214 */
Findjob_set_action_chgrp(struct FindjoB * o,gid_t group,int flag)1215 int Findjob_set_action_chgrp(struct FindjoB *o, gid_t group, int flag)
1216 {
1217 int ret;
1218
1219 if(flag&1) {
1220 o->action= 0;
1221 Findjob_destroy(&(o->subjob), 0);
1222 ret= Findjob_new(&(o->subjob), "", 0);
1223 if(ret<=0)
1224 return(-1);
1225 Findjob_set_action_chgrp(o->subjob, group, 0);
1226 o->action= 10;
1227 } else {
1228 o->action= 5;
1229 o->group= group;
1230 }
1231 return(1);
1232 }
1233
1234
1235 /* @param flag bit0= recursive
1236 */
Findjob_set_action_chmod(struct FindjoB * o,mode_t mode_and,mode_t mode_or,int flag)1237 int Findjob_set_action_chmod(struct FindjoB *o,
1238 mode_t mode_and, mode_t mode_or, int flag)
1239 {
1240 int ret;
1241
1242 if(flag&1) {
1243 o->action= 0;
1244 Findjob_destroy(&(o->subjob), 0);
1245 ret= Findjob_new(&(o->subjob), "", 0);
1246 if(ret<=0)
1247 return(-1);
1248 Findjob_set_action_chmod(o->subjob, mode_and, mode_or, 0);
1249 o->action= 11;
1250 } else {
1251 o->action= 6;
1252 o->mode_and= mode_and;
1253 o->mode_or= mode_or;
1254 }
1255 return(1);
1256 }
1257
1258
1259 /* @param flag bit0= recursive
1260 */
Findjob_set_action_ad(struct FindjoB * o,int type,time_t date,int flag)1261 int Findjob_set_action_ad(struct FindjoB *o, int type, time_t date, int flag)
1262 {
1263 int ret;
1264
1265 if(flag&1) {
1266 o->action= 0;
1267 Findjob_destroy(&(o->subjob), 0);
1268 ret= Findjob_new(&(o->subjob), "", 0);
1269 if(ret<=0)
1270 return(-1);
1271 Findjob_set_action_ad(o->subjob, type, date, 0);
1272 o->action= 12;
1273 } else {
1274 o->action= 7;
1275 o->type= type;
1276 o->date= date;
1277 }
1278 return(1);
1279 }
1280
1281
Findjob_set_action_subjob(struct FindjoB * o,int action,struct FindjoB * subjob,int flag)1282 int Findjob_set_action_subjob(struct FindjoB *o, int action,
1283 struct FindjoB *subjob, int flag)
1284 {
1285 o->action= action;
1286 Findjob_destroy(&(o->subjob), 0);
1287 o->subjob= subjob;
1288 return(1);
1289 }
1290
1291
Findjob_set_action_found_path(struct FindjoB * o,int flag)1292 int Findjob_set_action_found_path(struct FindjoB *o, int flag)
1293 {
1294 o->action= 23;
1295 Findjob_set_found_path(o, NULL, 0);
1296 return(1);
1297 }
1298
1299