diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index d168b41c..3a905300 100644 --- a/xorriso/xorriso.1 +++ b/xorriso/xorriso.1 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH XORRISO 1 "Apr 18, 2009" +.TH XORRISO 1 "Apr 21, 2009" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -1162,7 +1162,7 @@ The reserved filter name "--remove-all-filters" revokes filtering. This will revoke eventual suffix renamings as well. Use "--remove-all-filters+" to prevent any suffix renaming. .br -Builtin filters are "--zisofs" and "--zisofs-decode". The former is to be +Built-in filters are "--zisofs" and "--zisofs-decode". The former is to be applied via -set_filter, the latter is automatically applied if zisofs compressed content is detected with a file when loading the ISO image. .br @@ -1207,185 +1207,168 @@ where "A0" is year 2000, "B0" is 2010, etc. \fB\-alter_date_r\fR type timestring iso_rr_path [***] Like -alter_date but affecting all files below eventual directories. .TP -\fB\-find\fR iso_rr_path [test [test ...]] [-exec action [params]] -- -A very restricted substitute for shell command find in the ISO image. +\fB\-find\fR iso_rr_path [test [op] [test ...]] [-exec action [params]] -- +A restricted substitute for shell command find in the ISO image. It performs an action on matching file objects at or below iso_rr_path. .br +If not used as last command in the line then the argument list +needs to get terminated by "--". +.br Tests are optional. If they are omitted then action is applied to all file -objects. If tests are given then action is applied only if all of them -match the file object. Available tests are: +objects. If tests are given then they form together an expression. +The action is applied only if the expression matches the file object. Default +expression operator between tests is -and, i.e. the expression matches only +if all its tests match. .br --name pattern +Available tests are: .br +\fB\-name\fR pattern : Pattern is not expanded but used for comparison with the particular file names of the eventual directory tree underneath iso_rr_path. .br --type type_letter -.br -matches only files files of the given type: +\fB\-type\fR type_letter : +Matches files files of the given type: "block", "char", "dir", "pipe", "file", "link", "socket", "eltorito", "Xotic" which eventually matches what is not matched by the other types. .br Only the first letter is interpreted. E.g.: -find / -type d .br --damaged -.br -matches only files which use data blocks marked as damaged by a previous +\fB\-damaged\fR : +Matches files which use data blocks marked as damaged by a previous run of -check_media. The damage info vanishes when a new ISO image gets loaded. .br --undamaged +\fB\-pending_data\fR : +Matches files which get their content from outside the loaded ISO image. .br -matches only files which use data blocks outside the areas marked as damaged. +\fB\-lba_range\fR start_lba block_count : +Matches files which use data blocks within the range of start_lba +and start_lba+block_count-1. .br --lba_range start_lba block_count +\fB\-has_acl\fR : +Matches files which have a non-trivial ACL. .br -matches only files which use data blocks within the range of start_lba -and start_lba+block_count-1. A negative start_lba matches those files which -would not match the range given by its positive counter part. +\fB\-has_xattr\fR : +Matches files which have xattr name-value pairs from user namespace. .br --has_acl , -has_no_acl +\fB\-has_aaip\fR : +Matches files which have ACL or any xattr. .br -match files which have resp. have not a non-trivial ACL. +\fB\-has_filter\fR : +Matches files which are filtered by -set_filter. .br --has_xattr , -has_no_xattr +\fB\-decision\fR "yes"|"no" : +If this test is reached then the evaluation ends immediatly and action +is performed if the decision is not "no", "0", or "false". See operator -if. .br -match files which have resp. have not xattr name-value pairs -from user namespace. +Available operators are: .br --has_aaip , -has_no_aaip +\fB\-not\fR : +Matches if the next test or sub expression does not match. +Several tests do this specifically: .br -match files which have ACL or any xattr resp. have neither of them. +-undamaged, -lba_range with negative start_lba, -has_no_acl, -has_no_xattr, +-has_no_aaip, -has_no_filter .br --has_filter , -has_no_filter +\fB\-and\fR : +Matches if both neighboring tests or expressions match. .br -match files which are filtered by -set_filter resp. are not. +\fB\-or\fR : +Matches if at least one of both neighboring tests or expressions matches. .br +\fB\-sub\fR ... \fB\-subend\fR : +Enclose a sub expression which gets evaluated first before it +is processed by neighboring operators. The same meaning have "(" and ")". +.br +Normal precedence is: -not, -or , -and. +.br +\fB\-if\fR ... \fB\-then\fR\ ... \fB\-elseif\fR ... \fB\-then\fR ... +\fB\-else\fR ... \fB\-endif\fR : +Enclose one or more sub expressions. If the -if expression matches, then +the -then expression is evaluated as the result of the whole expression +up to -endif. Else the next -elseif expression is evaluated and eventually +its -then expression. Finally in case of no match, the -else expression +is evaluated. +There may be more than one -elseif. Neither -else nor -elseif are mandatory. +If -else is missing and would be hit, then the result is a non-match. +.br +-if expressions are the main use case for the test -decision. -Default action is "echo", +Default action is \fBecho\fR, i.e. to print the address of the found file. Other actions are certain xorriso commands which get performed on the found files. These commands may have specific parameters. See also their particular descriptions. .br -"chown" and "chown_r" change the ownership and get the user id as param. E.g.: +\fBchown\fR and \fBchown_r\fR change the ownership and get the user id +as parameter. E.g.: -exec chown thomas -- .br - -find / -exec chown thomas -- +\fBchgrp\fR and \fBchgrp_r\fR change the group attribute and get the group id +as paramieter. E.g.: -exec chgrp_r staff -- .br -"chgrp" and "chgrp_r" change the group attribute and get the group id as param. -E.g.: +\fBchmod\fR and \fBchmod_r\fR change access permissions and get a mode string +as parameter. E.g.: -exec chmod a-w,a+r -- .br - -find / name 'news*' -type d -exec chgrp_r staff -- +\fBalter_date\fR and \fBalter_date_r\fR change the timestamps. They get a type +character and a timestring as parameters. .br -"chmod" and "chmod_r" change access permissions and get a mode string as param. -E.g.: +E.g.: -exec alter_date "m" "Dec 30 19:34:12 2007" -- .br - -find / -exec chmod a-w,a+r -- +\fBlsdl\fR prints file information like shell command ls -dl. .br -"alter_date" and "alter_date_r" change the timestamps. -They get a type character and a timestring as params. -E.g.: +\fBcompare\fR performs command -compare with the found file address as +iso_rr_path and the corresponding file address below its argument +disk_path_start. For this the iso_rr_path of the -find command gets +replaced by the disk_path_start. .br - -find / -exec alter_date "m" "Dec 30 19:34:12 2007" -- +E.g.: -find /thomas -exec compare /home/thomas -- .br -"lsdl" prints file information like shell command ls -dl. -E.g.: +\fBupdate\fR performs command -update with the found file address as +iso_rr_path. The corresponding file address is determined like with above +action "compare". .br - -find / -exec lsdl -- +\fBrm\fR removes the found iso_rr_path from the image if it is not a directory +with files in it. I.e. this "rm" includes "rmdir". .br -"compare" performs command -compare with the found file address as iso_rr_path -and the corresponding file address below its argument disk_path_start. For this -the iso_rr_path of the -find command gets replaced by the disk_path_start. -E.g.: +\fBrm_r\fR removes the found iso_rr_path from the image, including whole +directory trees. .br - -find / -exec compare /home/thomas -- -.br -"update" performs command -update with the found file address as iso_rr_path. -The corresponding file address is determined like with above "compare". -.br -E.g.: -.br - -find / -exec update /home/thomas -- -.br -"rm" removes the found iso_rr_path from the image if it is not a directory with -files in it. I.e. this "rm" includes "rmdir". -.br -E.g.: -.br - -find / -name *.doc -exec rm -- -.br -"rm_r" removes the found iso_rr_path from the image, including whole directory -trees. -.br -E.g.: -.br - -find /uh/oh -name *private* -exec rm_r -- -.br -"report_damage" classifies files whether they hit a data block that is +\fBreport_damage\fR classifies files whether they hit a data block that is marked as damaged. The result is printed together with the eventual address of the first damaged byte, the maximum span of damages, file size, and the path of the file. .br -E.g.: -.br - -find / -damaged -exec report_damage -- -.br -"report_lba" prints files which are associated to image data blocks. +\fBreport_lba\fR prints files which are associated to image data blocks. It tells the logical block address, the block number, the byte size, and the path of each file. There may be reported more than one line per file if the file is very large. In this case each line has a different extent number in column "xt". .br -E.g.: +\fBgetfacl\fR prints access permissions in ACL text form to the result channel. .br - -find / -lba_range 302000 50000 -exec report_lba -- -.br -"getfacl" prints access permissions in ACL text form to the result channel. -.br -E.g.: -.br - -find / -has_acl -exec getfacl -.br -"setfacl" attaches ACLs after removing eventually exiting ones. The new +\fBsetfacl\fR attaches ACLs after removing eventually exiting ones. The new ACL is given in text form as defined with option -setfacl. .br -E.g.: +E.g.: -exec setfacl u:lisa:rw,u::rw,g::r,o::-,m::rw -- .br - -find /work -exec setfacl u:lisa:rw,u::rw,g::r,o::-,m::rw -- +\fBgetfattr\fR prints eventual xattr name-value pairs to the result channel. .br -"getfattr" prints eventual xattr name-value pairs to the result channel. +\fBsetfattr\fR sets or deletes xattr name value pairs. .br -E.g.: +E.g.: -find / -has_xattr -exec setfattr --remove-all '' -- .br - -find / -has_xattr -exec getfattr -- +\fBset_filter\fR applies or removes filters. .br -"setfattr" sets or deletes xattr name value pairs. +E.g.: -exec set_filter --zisofs -- .br -E.g.: +\fBshow_stream\fR shows the content stream chain of a data file. .br - -find / -has_xattr -exec setfattr --remove-all '' -- -.br -"set_filter" applies or removes filters (see -external_filter). -.br -E.g.: -.br - -find / -type f -exec set_filter gzip -- -.br -"show_stream" shows the content stream chain of a data file. -.br -E.g.: -.br - -find / -type f -exec show_stream -- -.br -"find" performs another run of -find on the matching file address. It accepts -the same params as -find, except iso_rr_path. +\fBfind\fR performs another run of -find on the matching file address. +It accepts the same params as -find, except iso_rr_path. .br E.g.: .br -find / -name '???' -type d -exec find -name '[abc]*' -exec chmod a-w,a+r -- -.br -If not used as last command in the line then the argument list -needs to get terminated by "--". .TP \fB\-mkdir\fR iso_rr_path [...] Create empty directories if they do not exist yet. @@ -2373,37 +2356,33 @@ Similar to shell command du -sk. Like -find but operating on local filesystem and not on the ISO image. This is subject to the settings of -follow. .br -Find accepts the same -type arguments as -find. Additionally it recognizes -type "mountpoint" (or "m"). It matches subdirectories which reside on a +-findx accepts the same -type arguments as -find. Additionally it recognizes +type "mountpoint" (or "m") which matches subdirectories which reside on a different device than their parent. It never matches the disk_path given as start address for -findx. .br -findx accepts the -exec actions as does -find. But except the following few actions it will allways perform action "echo". .br -"in_iso" iso_rr_path_start reports the path if its counterpart exist in -the ISO image. For this the disk_path of the -find command gets replaced -by iso_rr_path_start. E.g.: +\fBin_iso\fR reports the path if its counterpart exist in the ISO image. +For this the disk_path of the -findx command gets replaced +by the iso_rr_path given as parameter. .br - -findx /home -exec in_iso / +E.g.: -findx /home/thomas -exec in_iso /thomas_on_cd -- .br -"not_in_iso" iso_rr_path_start reports the path if its counterpart does +\fBnot_in_iso\fR reports the path if its counterpart does not exist in the ISO image. The report format is the same as with command -compare. -E.g. .br - -findx /home/thomas -exec not_in_iso /thomas_on_cd -.br -"add_missing" iso_rr_path_start adds the counterpart if it does not yet +\fBadd_missing\fR iso_rr_path_start adds the counterpart if it does not yet exist in the ISO image. -E.g. .br - -findx /home/thomas -exec add_missing /thomas_on_cd +E.g.: -findx /home/thomas -exec add_missing /thomas_on_cd -- .br -"is_full_in_iso" iso_rr_path_start reports if the counterpart in the ISO image +\fBis_full_in_iso\fR reports if the counterpart in the ISO image contains files. To be used with -type "m" to report mount points. .br -"empty_iso_dir" iso_rr_path_start deletes all files from the counterpart +\fBempty_iso_dir\fR deletes all files from the counterpart in the ISO image. To be used with -type "m" to truncate mount points. .TP \fB\-compare\fR disk_path iso_rr_path diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 5cebe796..88b186da 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -2438,6 +2438,1132 @@ int Linkitem_find(struct LinkiteM *stack, dev_t target_dev, ino_t target_ino, } +#ifdef Xorriso_findjob_on_expR + + +/* ----------------------- Exprtest ----------------------- */ + + +int Exprtest_new( struct ExprtesT **ftest, struct FindjoB *boss, int flag) +{ + struct ExprtesT *f; + + *ftest= f= TSOB_FELD(struct ExprtesT,1); + if(f==NULL) + return(-1); + f->boss= boss; + f->invert= 0; + f->test_type= -1; + f->arg1= NULL; + f->arg2= NULL; + return(1); +} + + +int Exprtest_destroy(struct ExprtesT **ftest, int flag) +{ + struct ExprtesT *f; + + f= *ftest; + if(f==NULL) + return(0); + + if(f->test_type == 1) { + if(f->arg1 != NULL) + free(f->arg1); + if(f->arg2 != NULL) { + regfree(f->arg2); + free(f->arg2); + } + } else if(f->test_type == 9) { + /* arg1 is not an allocated value */; + } else { + if(f->arg1 != NULL) + free(f->arg1); + if(f->arg2 != NULL) + free(f->arg2); + } + free((char *) f); + *ftest= NULL; + return(1); +} + + +/* ----------------------- Nttpfnode ----------------------- */ + + +int Exprnode_new(struct ExprnodE **fnode, struct FindjoB *job, + struct ExprnodE *up, char *origin, int flag) +/* + bit0= set invert-property + bit1= set use_shortcuts +*/ +{ + struct ExprnodE *n; + int ret,i; + + *fnode= n= TSOB_FELD(struct ExprnodE,1); + if(n == NULL) + return(-1); + for(i= 0; i < sizeof(n->origin); i++) + n->origin[i]= 0; + strncpy(n->origin, origin, sizeof(n->origin) - 1); + n->up= up; + n->invert= (flag & 1); + n->assoc= 0; + n->use_shortcuts= !!(flag & 2); + n->left= NULL; + n->left_op= -1; + n->right= NULL; + n->right_op= -1; + n->sub= NULL; + n->is_if_then_else= 0; + n->true_branch= NULL; + n->false_branch= NULL; + n->test= NULL; + n->own_value= -1; + n->composed_value= -1; + + ret= Exprtest_new(&(n->test), job, 0); + if(ret<=0){ + Exprnode_destroy(fnode, 0); + return(-1); + } + return(1); +} + + +int Exprnode_destroy(struct ExprnodE **fnode, int flag) +{ + if(*fnode == NULL) + return(0); + Exprnode_destroy(&((*fnode)->right),0); + Exprnode_destroy(&((*fnode)->sub),0); + Exprnode_destroy(&((*fnode)->true_branch),0); + Exprnode_destroy(&((*fnode)->false_branch),0); + Exprtest_destroy(&((*fnode)->test),0); + free((char *) *fnode); + *fnode= NULL; + return(1); +} + + +int Exprnode_set_is_if(struct ExprnodE *fnode, int value, int flag) +{ + fnode->is_if_then_else= value; + return(1); +} + + +int Exprnode_is_if(struct ExprnodE *fnode, int flag) +{ + return(fnode->is_if_then_else); +} + + +int Exprnode_set_branch(struct ExprnodE *fnode, struct ExprnodE *target, + int flag) +/* + bit0= false_branch (else true_branch) +*/ +{ + struct ExprnodE **branch; + + if(flag&1) + branch= &(fnode->false_branch); + else + branch= &(fnode->true_branch); + Exprnode_destroy(branch,0); + (*branch)= target; + return(1); +} + + +int Exprnode_get_branch(struct ExprnodE *fnode, struct ExprnodE **branch, + int flag) +/* + bit0= false_branch (else true_branch) +*/ +{ + if(flag&1) + (*branch)= fnode->false_branch; + else + (*branch)= fnode->true_branch; + return(1); +} + + +int Exprnode_is_defined(struct ExprnodE *fnode, int flag) +{ + struct ExprtesT *ftest; + + if(fnode==NULL) + return(0); + if(fnode->sub!=NULL) + return(1); + ftest= fnode->test; + if(ftest==NULL) + return(0); + if(ftest->test_type>=0) + return(1); + return(0); +} + + +int Exprnode_own_value(struct XorrisO *xorriso, struct ExprnodE *fnode, + void *node, char *name, + struct stat *boss_stbuf, struct stat *stbuf, int flag) +/* +flag: +return: (also from Exprtest_match() and Exprnode_tree_value() ) + <0 = error + 0 = does not match + 1 = does match + 2 = immediate decision : does not match + 3 = immediate decision : does match +*/ +{ + int ret; + + if(fnode==NULL) + return(1); + if(fnode->sub!=NULL) { + ret= Exprnode_tree_value(xorriso, fnode->sub, -1, + node, name, boss_stbuf, stbuf, 0); + } else { + ret= Exprtest_match(xorriso, fnode->test, node, name, boss_stbuf, stbuf, 0); + } + if(ret<0) + return(ret); + if(ret>1) + return(ret); + if(fnode->invert) + ret= !ret; + return(ret); +} + + +int Exprnode_op(int value1, int value2, int op, int flag) +{ + int ret; + + if(op==0) + ret= value1 || value2 ; + else + ret= value1 && value2 ; + return(ret); +} + + +int Exprnode_tree_value(struct XorrisO *xorriso, struct ExprnodE *fnode, + int left_value, void *node, char *name, + struct stat *boss_stbuf, struct stat *stbuf, int flag) +/* + bit0-7= testmode: 0=head , 1=filename +return: (also from Nntpftest_match() and Nntpfnode_own_value() ) + <0 = error + 0 = does not match + 1 = does match + 2 = immediate decision : does not match + 3 = immediate decision : does match +*/ +{ + int value= 1,ret; + + if(fnode==NULL) + return(1); + if(!Exprnode_is_defined(fnode,0)) + return(1); + + if(fnode->use_shortcuts && fnode->left!=NULL){ + fnode->composed_value= left_value; + if(fnode->left_op==0) {/* OR */ + if(left_value!=0) + goto ex; + } else { /* AND */ + if(left_value==0) + goto ex; + } + } + fnode->composed_value= fnode->own_value= + Exprnode_own_value(xorriso, fnode, node, name, boss_stbuf, stbuf, 0); + if(fnode->own_value < 0 || fnode->own_value > 1) + return(fnode->own_value); + + if(fnode->assoc == 0){ /* left associative */ + if(fnode->left != NULL && left_value >= 0) + fnode->composed_value= + Exprnode_op(left_value, fnode->own_value, fnode->left_op, 0); + /* compute right value */ + /* is the right value relevant ? */ + if(fnode->right!=NULL){ + if(fnode->use_shortcuts){ + if(fnode->right_op==0) {/* OR */ + if(fnode->composed_value!=0) + goto ex; + } else { /* AND */ + if(fnode->composed_value==0) + goto ex; + } + } + value= Exprnode_tree_value(xorriso, fnode->right,fnode->composed_value, + node, name, boss_stbuf, stbuf, 0); + if(value<0 || value>1) + return(value); + fnode->composed_value= value; + } + }else{ /* right associative */ + if(fnode->right!=NULL){ + /* is the right value relevant ? */ + if(fnode->use_shortcuts){ + if(fnode->right_op==0) {/* OR */ + if(fnode->composed_value!=0) + goto ex; + } else { /* AND */ + if(fnode->composed_value==0) + goto ex; + } + } + value= Exprnode_tree_value(xorriso, fnode->right,fnode->own_value, + node, name, boss_stbuf, stbuf, 0); + if(value<0||value>1) + return(value); + } else + value= fnode->own_value; + fnode->composed_value= value; + if(fnode->left!=NULL && left_value>=0) + fnode->composed_value= + Exprnode_op(left_value,fnode->composed_value,fnode->left_op,0); + } +ex: + ret= fnode->composed_value; + if(fnode->is_if_then_else) { + /* The if-condition is evaluated. Now follow the chosen branch */ + struct ExprnodE *branch; + if(ret>0) + branch= fnode->true_branch; + else + branch= fnode->false_branch; + if(branch!=NULL) { + ret= Exprnode_tree_value(xorriso, branch, -1, + node, name, boss_stbuf, stbuf, 0); + if(ret<0) + return(ret); + if(ret>1) + return(ret); + } + fnode->composed_value= ret; + } + return(fnode->composed_value); +} + + +/* --------------------- Findjob -------------------- */ + + +int Findjob_new(struct FindjoB **o, char *start_path, int flag) +{ + struct FindjoB *m; + int ret; + + m= *o= TSOB_FELD(struct FindjoB,1); + if(m==NULL) + return(-1); + m->start_path= NULL; + m->test_tree= NULL; + m->cursor= NULL; + m->invert= 0; + m->use_shortcuts= 1; + m->action= 0; /* print */ + m->target= NULL; /* a mere pointer, not managed memory */ + m->text_2= NULL; /* a mere pointer, not managed memory */ + m->user= 0; + m->group= 0; + m->type= 0; + m->date= 0; + m->start_path= strdup(start_path); + if(m->start_path==NULL) + goto failed; + m->found_path= NULL; + m->subjob= NULL; + + ret= Exprnode_new(&(m->test_tree), m, NULL, "-find", (m->use_shortcuts)<<1); + if(ret<=0) + goto failed; + m->cursor= m->test_tree; + return(1); + +failed:; + Findjob_destroy(o, 0); + return(-1); +} + + +int Findjob_destroy(struct FindjoB **o, int flag) +{ + struct FindjoB *m; + + m= *o; + if(m==NULL) + return(0); + if(m->test_tree != NULL) + Exprnode_destroy(&(m->test_tree), 0); + free((char *) *o); + *o= NULL; + return(1); +} + + +int Findjob_set_start_path(struct FindjoB *o, char *start_path, int flag) +{ + if(o->start_path!=NULL) + free(o->start_path); + if(start_path!=NULL) { + o->start_path= strdup(start_path); + if(o->start_path==NULL) + return(-1); + } else + o->start_path= NULL; + return(1); +} + + +int Findjob_get_start_path(struct FindjoB *o, char **start_path, int flag) +{ + *start_path= o->start_path; + return(1); +} + + +int Findjob_cursor_complete( struct FindjoB *job, int flag) +{ + int ret; + + if(job==NULL) + return(0); + ret= Exprnode_is_defined(job->cursor,0); + return(ret); +} + + +int Findjob_is_restrictive(struct FindjoB *job, int flag) +{ + if(job == NULL) + return(0); + if(job->test_tree == NULL) + return(0); + if(!Exprnode_is_defined(job->test_tree, 0)) + return(0); + return(1); +} + + +int Findjob_new_node(struct FindjoB *job, struct ExprnodE **fnode, + char *origin, int flag) +/* + bit0= open new branch + bit1= with bit1 : do not register as sub-node of job->cursor +*/ +{ + int ret; + struct ExprnodE *f; + + ret= Exprnode_new(fnode,job,NULL,origin, + job->invert|((job->use_shortcuts)<<1)); + if(ret<=0) + return(ret); + f= *fnode; + if(flag&1) { + f->up= job->cursor; + if(job->cursor!=NULL && !(flag&2)) { + if(job->cursor->sub!=NULL) { + /* This would become a memory leak */ + job->errn= -2; + sprintf(job->errmsg, + "Program error while parsing -job : sub branch overwrite"); + return(0); + } else + job->cursor->sub= f; + } + } else { + f->up= job->cursor->up; + f->left= job->cursor; + if(job->cursor!=NULL) + job->cursor->right= f; + } + job->invert= 0; + return(1); +} + + +int Findjob_open_bracket(struct FindjoB *job, int flag) +{ + int ret; + struct ExprnodE *fnode; + + if(Findjob_cursor_complete(job, 0)) { + job->errn= -2; + sprintf(job->errmsg,"Binary operator expected, opening-bracket found"); + return(0); + } + ret= Findjob_new_node(job, &fnode, "-sub", 1); + if(ret <= 0) + return(ret); + job->cursor= fnode; + return(1); +} + + +int Findjob_close_bracket(struct FindjoB *job, int flag) +{ + if(!Findjob_cursor_complete(job, 0)) { + job->errn= -3; + sprintf(job->errmsg, + "Unary operator or expression expected, closing-bracket found"); + return(0); + } + + if(job->cursor->up==NULL){ + job->errn= -1; + sprintf(job->errmsg, + "No bracket open when encountering closing bracket."); + return(0); + } + job->cursor= job->cursor->up; + return(1); +} + + +int Findjob_not(struct FindjoB *job, int flag) +{ + if(Findjob_cursor_complete(job, 0)) { + job->errn= -2; + sprintf(job->errmsg, "Binary operator expected, unary operator found"); + return(0); + } + job->cursor->invert= !job->cursor->invert; + return(1); +} + + +int Findjob_and(struct FindjoB *job, int flag) +{ + int ret; + struct ExprnodE *fnode; + + if(!Findjob_cursor_complete(job, 0)) { + job->errn= -3; + sprintf(job->errmsg, + "Unary operator or expression expected, binary operator found"); + return(0); + } + + ret= Findjob_new_node(job, &fnode, "-and", 0); + if(ret<=0) + return(ret); + job->cursor->right_op= 1; + job->cursor->assoc= 1; /* compute right side first */ + fnode->left_op= 1; + fnode->assoc= 0; /* compute left side first */ + job->cursor= fnode; + return(1); +} + + +int Findjob_or(struct FindjoB *job, int flag) +{ + int ret; + struct ExprnodE *fnode; + + if(!Findjob_cursor_complete(job, 0)) { + job->errn= -3; + sprintf(job->errmsg, + "Unary operator or expression expected, binary operator found"); + return(0); + } + + ret= Findjob_new_node(job, &fnode, "-or", 0); + if(ret<=0) + return(ret); + job->cursor->right= fnode; + job->cursor->right_op= 0; + /* if existing : compute left side first */ + job->cursor->assoc= (job->cursor->left == NULL); + fnode->left= job->cursor; + fnode->left_op= 0; + fnode->assoc= 0; /* no right side yet : compute left side first */ + job->cursor= fnode; + return(1); +} + + +int Findjob_if(struct FindjoB *job, int flag) +{ + int ret; + struct ExprnodE *fnode; + + if(Findjob_cursor_complete(job,0)) { + job->errn= -2; + sprintf(job->errmsg,"Binary operator expected, -if-mark found"); + return(0); + } + ret= Findjob_new_node(job, &fnode, "-if", 1); + if(ret<=0) + return(ret); + Exprnode_set_is_if(fnode,1,0); + job->cursor= fnode; + return(1); +} + + +int Findjob_then(struct FindjoB *job, int flag) +{ + int ret; + struct ExprnodE *fnode,*branch= NULL; + + if(! Findjob_cursor_complete(job,0)) { + job->errn= -3; + sprintf(job->errmsg, + "Unary operator or expression expected, -then-operator found"); + return(0); + } + /* Finding the -if that matches this -then + Do not go up one node but look for the leftmost one. + If everything is right we are at level of the -if node */ + while(job->cursor->left!=NULL) + job->cursor= job->cursor->left; + Exprnode_get_branch(job->cursor, &branch, 0); + if(!Exprnode_is_if(job->cursor, 0) || branch != NULL) { + job->errn= -5; + sprintf(job->errmsg, "-then-operator found outside its proper range."); + return(0); + } + ret= Findjob_new_node(job, &fnode, "-then", 1|2); + if(ret <= 0) + return(ret); + Exprnode_set_branch(job->cursor, fnode, 0); + job->cursor= fnode; + return(1); +} + + +int Findjob_else(struct FindjoB *job, int flag) +{ + int ret; + struct ExprnodE *fnode, *true_branch, *false_branch; + + if(! Findjob_cursor_complete(job, 0)) { + job->errn= -3; + sprintf(job->errmsg, + "Unary operator or expression expected, -else-operator found"); + return(0); + } + if(job->cursor->up == NULL) + goto improper_range; + job->cursor= job->cursor->up; + Exprnode_get_branch(job->cursor, &true_branch, 0); + Exprnode_get_branch(job->cursor, &false_branch, 1); + if(!Exprnode_is_if(job->cursor, 0) || + true_branch == NULL || false_branch != NULL) { +improper_range:; + job->errn= -5; + sprintf(job->errmsg, "-else-operator found outside its proper range."); + return(0); + } + ret= Findjob_new_node(job, &fnode, "-else", 1 | 2); + if(ret <= 0) + return(ret); + Exprnode_set_branch(job->cursor, fnode, 1); + job->cursor= fnode; + return(1); +} + + +int Findjob_elseif(struct FindjoB *job, int flag) +{ + int ret; + struct ExprnodE *true_branch, *false_branch; + + if(!Findjob_cursor_complete(job, 0)) { + job->errn= -3; + sprintf(job->errmsg, + "Unary operator or expression expected, -elseif-operator found"); + return(0); + } + if(job->cursor->up == NULL) + goto improper_range; + job->cursor= job->cursor->up; + Exprnode_get_branch(job->cursor, &true_branch, 0); + Exprnode_get_branch(job->cursor, &false_branch, 1); + if(!Exprnode_is_if(job->cursor, 0) || + true_branch==NULL || false_branch!=NULL) { +improper_range:; + job->errn= -5; + sprintf(job->errmsg, + "-elseif-operator found outside its proper range."); + return(0); + } + job->cursor= job->cursor->up; + /* -elseif is equivalent to the three-step sequence : -endif -or -if + ( -endif has already been performed by following job->cursor->up ) */ + ret= Findjob_or(job, 0); + if(ret <= 0) + return(0); + ret= Findjob_if(job, 0); + if(ret <= 0) + return(0); + return(1); +} + + +int Findjob_endif(struct FindjoB *job, int flag) +{ + struct ExprnodE *true_branch; + + if(!Findjob_cursor_complete(job,0)) { + job->errn= -3; + sprintf(job->errmsg, + "Unary operator or expression expected, -endif found"); + return(0); + } + if(job->cursor->up==NULL) + goto improper_range; + /* test wether parent node is -if */ + job->cursor= job->cursor->up; + Exprnode_get_branch(job->cursor, &true_branch, 0); + if(!Exprnode_is_if(job->cursor,0) || true_branch == NULL) { +improper_range:; + job->errn= -5; + sprintf(job->errmsg, "-endif-mark found outside its proper range."); + return(0); + } + /* go to grand parent node */ + job->cursor= job->cursor->up; + return(1); +} + + +/* If an operator is expected : use -and */ +int Findjob_default_and(struct FindjoB *o, int flag) +{ + int ret; + + if(Findjob_cursor_complete(o, 0)) { + ret= Findjob_and(o, 0); + if(ret <= 0) + return(ret); + } + return(1); +} + + +int Findjob_set_name_expr(struct FindjoB *o, char *name_expr, int flag) +{ + char regexpr[2*SfileadrL+2]; + regex_t *name_re; + struct ExprtesT *t; + int ret; + + if(strlen(name_expr)>=SfileadrL) + return(0); + + ret= Findjob_default_and(o, 0); + if(ret <= 0) + return(ret); + t= o->cursor->test; + t->test_type= 1; + name_re= (regex_t *) calloc(1, sizeof(regex_t)); + if(name_re == NULL) + return(-1); + t->arg1= strdup(name_expr); + if(t->arg1 == NULL) { + free((char *) name_re); + return(-1); + } + Xorriso__bourne_to_reg(name_expr, regexpr, 0); + if(regcomp(name_re, regexpr, 0) != 0) + return(0); + t->arg2= name_re; + return(1); +} + + +int Findjob_set_file_type(struct FindjoB *o, char file_type, int flag) +{ + static char known[]= {"bcdpf-lsmeX"}; + struct ExprtesT *t; + int ret; + + ret= Findjob_default_and(o, 0); + if(ret <= 0) + return(ret); + + if(file_type != 0) + if(strchr(known, file_type) == NULL) + return(0); + t= o->cursor->test; + t->test_type= 2; + t->arg1= calloc(1, 1); + if(t->arg1 == NULL) + return(-1); + *((char *) t->arg1)= file_type; + return(1); +} + + +/* @param value -1= only without property, 1= only with property +*/ +int Findjob_set_prop_filter(struct FindjoB *o, int test_type, int value, + int flag) +{ + struct ExprtesT *t; + int ret; + + ret= Findjob_default_and(o, 0); + if(ret <= 0) + return(ret); + + t= o->cursor->test; + t->test_type= test_type; + if(value < 0) + t->invert= !t->invert; + return(1); +} + + +/* @param value -1= only undamaged files, 1= only damaged files +*/ +int Findjob_set_damage_filter(struct FindjoB *o, int value, int flag) +{ + int ret; + + ret= Findjob_set_prop_filter(o, 3, value, 0); + return(ret); +} + + +int Findjob_set_lba_range(struct FindjoB *o, int start_lba, int count, + int flag) +{ + struct ExprtesT *t; + int ret; + + ret= Findjob_default_and(o, 0); + if(ret <= 0) + return(ret); + + t= o->cursor->test; + t->test_type= 4; + t->arg1= calloc(sizeof(int), 1); + t->arg2= calloc(sizeof(int), 1); + if(t->arg1 == NULL || t->arg2 == NULL) + return(-1); + *((int *) t->arg1)= start_lba; + if(start_lba > 0) + *((int *) t->arg2)= start_lba + count - 1; + else + *((int *) t->arg2)= start_lba - count + 1; + return(1); +} + + +/* @param value -1= files without ACL, 1= only files with ACL +*/ +int Findjob_set_acl_filter(struct FindjoB *o, int value, int flag) +{ + int ret; + + ret= Findjob_set_prop_filter(o, 5, value, 0); + return(ret); +} + + +/* @param value -1= files without xattr, 1= only files with xattr +*/ +int Findjob_set_xattr_filter(struct FindjoB *o, int value, int flag) +{ + int ret; + + ret= Findjob_set_prop_filter(o, 6, value, 0); + return(ret); +} + + +/* @param value -1= files without aaip, 1= only files with aaip +*/ +int Findjob_set_aaip_filter(struct FindjoB *o, int value, int flag) +{ + int ret; + + ret= Findjob_set_prop_filter(o, 7, value, 0); + return(ret); +} + + +/* @param value -1= files without filter, 1= files with filter +*/ +int Findjob_set_filter_filter(struct FindjoB *o, int value, int flag) +{ + int ret; + + ret= Findjob_set_prop_filter(o, 8, value, 0); + return(ret); +} + + +int Findjob_set_wanted_node(struct FindjoB *o, void *wanted_node, int flag) +{ + struct ExprtesT *t; + int ret; + + ret= Findjob_default_and(o, 0); + if(ret <= 0) + return(ret); + + t= o->cursor->test; + t->test_type= 9; + t->arg1= wanted_node; + return(1); +} + + +int Findjob_set_commit_filter_2(struct FindjoB *o, int flag) +{ + int ret; + + ret= Findjob_default_and(o, 0); + if(ret <= 0) + return(ret); + + o->cursor->test->test_type= 10; + return(1); +} + + +int Findjob_set_decision(struct FindjoB *o, char *decision, int flag) +{ + struct ExprtesT *t; + int ret; + + ret= Findjob_default_and(o, 0); + if(ret <= 0) + return(ret); + + t= o->cursor->test; + t->test_type= 11; + t->arg1= strdup(decision); + if(t->arg1 == NULL) + return(-1); + return(1); +} + + +/* @param value -1= true, 1= false +*/ +int Findjob_set_false(struct FindjoB *o, int value, int flag) +{ + int ret; + + ret= Findjob_set_prop_filter(o, 0, value, 0); + return(ret); +} + + +int Findjob_set_found_path(struct FindjoB *o, char *path, int flag) +{ + if(o->found_path != NULL) + free(o->found_path); + if(path != NULL) { + o->found_path= strdup(path); + if(o->found_path == NULL) + return(-1); + } else + o->found_path= NULL; + return(1); +} + + +int Findjob_get_found_path(struct FindjoB *o, char **path, int flag) +{ + *path= o->found_path; + return(1); +} + + +int Findjob_get_action(struct FindjoB *o, int flag) +{ + return(o->action); +} + + +/* @return <0 error, >=0 see above struct FindjoB.action +*/ +int 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) +{ + *target= o->target; + *text_2= o->text_2; + *user= o->user; + *group= o->group; + *mode_and= o->mode_and; + *mode_or= o->mode_or; + *type= o->type; + *date= o->date; + *subjob= o->subjob; + return(o->action); +} + + +int Findjob_test_2(struct XorrisO *xorriso, struct FindjoB *o, + void *node, char *name, + struct stat *boss_stbuf, struct stat *stbuf, int flag) +{ + int ret; + + ret= Exprnode_tree_value(xorriso, o->test_tree, -1, + node, name, boss_stbuf, stbuf, 0); + if(ret == 3) + ret= 1; + else if(ret == 2) + ret= 0; + return(ret); +} + + +int Findjob_set_action_target(struct FindjoB *o, int action, char *target, + int flag) +{ + o->action= action; + o->target= target; + return(1); +} + + +int Findjob_set_action_text_2(struct FindjoB *o, int action, char *target, + char* text_2, int flag) +{ + o->action= action; + o->target= target; + o->text_2= text_2; + return(1); +} + + +/* @param flag bit0= recursive +*/ +int Findjob_set_action_chown(struct FindjoB *o, uid_t user,int flag) +{ + int ret; + + if(flag&1) { + o->action= 0; + Findjob_destroy(&(o->subjob), 0); + ret= Findjob_new(&(o->subjob), "", 0); + if(ret<=0) + return(-1); + Findjob_set_action_chown(o->subjob, user, 0); + o->action= 9; + } else { + o->action= 4; + o->user= user; + } + return(1); +} + + +/* @param flag bit0= recursive +*/ +int Findjob_set_action_chgrp(struct FindjoB *o, gid_t group, int flag) +{ + int ret; + + if(flag&1) { + o->action= 0; + Findjob_destroy(&(o->subjob), 0); + ret= Findjob_new(&(o->subjob), "", 0); + if(ret<=0) + return(-1); + Findjob_set_action_chgrp(o->subjob, group, 0); + o->action= 10; + } else { + o->action= 5; + o->group= group; + } + return(1); +} + + +/* @param flag bit0= recursive +*/ +int Findjob_set_action_chmod(struct FindjoB *o, + mode_t mode_and, mode_t mode_or, int flag) +{ + int ret; + + if(flag&1) { + o->action= 0; + Findjob_destroy(&(o->subjob), 0); + ret= Findjob_new(&(o->subjob), "", 0); + if(ret<=0) + return(-1); + Findjob_set_action_chmod(o->subjob, mode_and, mode_or, 0); + o->action= 11; + } else { + o->action= 6; + o->mode_and= mode_and; + o->mode_or= mode_or; + } + return(1); +} + + +/* @param flag bit0= recursive +*/ +int Findjob_set_action_ad(struct FindjoB *o, int type, time_t date, int flag) +{ + int ret; + + if(flag&1) { + o->action= 0; + Findjob_destroy(&(o->subjob), 0); + ret= Findjob_new(&(o->subjob), "", 0); + if(ret<=0) + return(-1); + Findjob_set_action_ad(o->subjob, type, date, 0); + o->action= 12; + } else { + o->action= 7; + o->type= type; + o->date= date; + } + return(1); +} + + +int Findjob_set_action_subjob(struct FindjoB *o, int action, + struct FindjoB *subjob, int flag) +{ + o->action= action; + Findjob_destroy(&(o->subjob), 0); + o->subjob= subjob; + return(1); +} + + +int Findjob_set_action_found_path(struct FindjoB *o, int flag) +{ + o->action= 23; + Findjob_set_found_path(o, NULL, 0); + return(1); +} + + +#else /* Xorriso_findjob_on_expR */ + + /* ------------------------------- FindjoB -------------------------------- */ @@ -3012,6 +4138,7 @@ int Findjob_set_action_found_path(struct FindjoB *o, int flag) return(1); } +#endif /* ! Xorriso_findjob_on_expR */ /* ---------------------------- SplitparT ------------------------- */ @@ -9201,7 +10328,19 @@ int Xorriso_findx(struct XorrisO *xorriso, struct FindjoB *job, namept= dir_path; else namept++; + + +#ifdef Xorriso_findjob_on_expR + + ret= Findjob_test_2(xorriso, job, NULL, namept, NULL, dir_stbuf, 0); + +#else /* Xorriso_findjob_on_expR */ + ret= Findjob_test(job, namept, NULL, dir_stbuf, depth, 0); + +#endif /* ! Xorriso_findjob_on_expR */ + + if(ret<0) goto ex; if(ret>0) { @@ -9263,7 +10402,17 @@ int Xorriso_findx(struct XorrisO *xorriso, struct FindjoB *job, if(ret!=1) no_dive= 1; } + +#ifdef Xorriso_findjob_on_expR + + ret= Findjob_test_2(xorriso, job, NULL, name, dir_stbuf, &stbuf, 0); + +#else /* Xorriso_findjob_on_expR */ + ret= Findjob_test(job, name, dir_stbuf, &stbuf, depth, 0); + +#endif /* ! Xorriso_findjob_on_expR */ + if(ret<0) goto ex; if(ret>0) { @@ -13640,7 +14789,17 @@ not_enough_arguments:; sscanf(argv[i], "%d", &count); Findjob_set_lba_range(job, start_lba, count, 0); } else if(strcmp(argv[i], "-pending_data")==0) { + +#ifdef Xorriso_findjob_on_expR + + Findjob_set_commit_filter_2(job, 0); + +#else /* Xorriso_findjob_on_expR */ + Findjob_set_commit_filter(job, 1, 1, 0); + +#endif /* ! Xorriso_findjob_on_expR */ + } else if(strcmp(argv[i], "-has_acl")==0) { Findjob_set_acl_filter(job, 1, 0); } else if(strcmp(argv[i], "-has_no_acl")==0) { @@ -13657,6 +14816,42 @@ not_enough_arguments:; Findjob_set_filter_filter(job, 1, 0); } else if(strcmp(argv[i], "-has_no_filter")==0) { Findjob_set_filter_filter(job, -1, 0); + +#ifdef Xorriso_findjob_on_expR + + } else if(strcmp(argv[i], "-true") == 0) { + ret= Findjob_set_false(job, -1, 0); + } else if(strcmp(argv[i], "-false") == 0) { + ret= Findjob_set_false(job, 1, 0); + } else if(strcmp(argv[i], "-decision") == 0) { + if(i+1>=end_idx) + goto not_enough_arguments; + i++; + ret= Findjob_set_decision(job, argv[i], 0); + + } else if(strcmp(argv[i], "-sub") == 0 || strcmp(argv[i], "(") == 0) { + ret= Findjob_open_bracket(job, 0); + } else if(strcmp(argv[i], "-subend") == 0 || strcmp(argv[i], ")") == 0) { + ret= Findjob_close_bracket(job, 0); + } else if(strcmp(argv[i], "-not") == 0 || strcmp(argv[i], "!") == 0) { + ret= Findjob_not(job, 0); + } else if(strcmp(argv[i], "-and") == 0 || strcmp(argv[i], "-a") == 0) { + ret= Findjob_and(job, 0); + } else if(strcmp(argv[i], "-or") == 0 || strcmp(argv[i], "-o") == 0) { + ret= Findjob_or(job, 0); + } else if(strcmp(argv[i], "-if") == 0) { + ret= Findjob_if(job, 0); + } else if(strcmp(argv[i], "-then") == 0) { + ret= Findjob_then(job, 0); + } else if(strcmp(argv[i], "-else") == 0) { + ret= Findjob_else(job, 0); + } else if(strcmp(argv[i], "-elseif") == 0) { + ret= Findjob_elseif(job, 0); + } else if(strcmp(argv[i], "-endif") == 0) { + ret= Findjob_endif(job, 0); + +#endif /* Xorriso_findjob_on_expR */ + } else if(strcmp(argv[i], "-exec")==0) { if(i+1>=end_idx) goto not_enough_arguments; @@ -14253,16 +15448,14 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " access time, modification time, both times.", " -alter_date_r type timestring iso_rr_path [***]", " Like -alter_date but affecting all files below directories.", -" -find iso_rr_path [test [test ...]] [-exec action [params]]", +" -find iso_rr_path [test [op] [test ...]] [-exec action [params]]", " performs an action on files below the given directory in", -" the ISO image. If -name pattern is given then only files", -" with matching leaf names are processed.", -" If -type is given then only files with matching type are", -" processed. Types: block,char,dir,pipe,file,link,socket.", -" Further tests: -damaged, -undamaged, -lba_range start count,", -" -pending_data, -has_acl, -has_no_acl, -has_xattr,", -" -has_no_xattr, -has_aaip, -has_no_aaip, -has_filter,", -" -has_no_filter.", +" the ISO image. Tests:", +" -name pattern, -type b|c|d|p|f|l|s|e, -pending_data,", +" -lba_range start count, -damaged, -has_acl, -has_xattr,", +" -has_aaip, -has_filter, -decision yes|no", +" Operators: -not, -or, -and, -sub, (, -subend, ),", +" -if, -then, -elseif, -else, -endif", " Action may be one of: echo, chown, chown_r, chgrp, chgrp_r", " chmod, chmod_r, alter_date, alter_date_r, lsdl, compare,", " rm, rm_r, compare, update, report_damage, report_lba,", diff --git a/xorriso/xorriso_private.h b/xorriso/xorriso_private.h index b8a58166..6418ca00 100644 --- a/xorriso/xorriso_private.h +++ b/xorriso/xorriso_private.h @@ -736,6 +736,229 @@ int Dirseq_next_adr(struct DirseQ *o, char reply[SfileadrL], int flag); int Linkitem_reset_stack(struct LinkiteM **o, struct LinkiteM *to, int flag); + + +#define Xorriso_findjob_on_expR yes + +#ifdef Xorriso_findjob_on_expR + +/* + A single Testnode. +*/ +struct ExprtesT { + + struct FindjoB *boss; + + int invert; /* 0=normal 1=invert result */ + + /* + 0= -false (with invert : -true) + 1= -name char *arg1 (regex_t in *arg2) + 2= -type char *arg1 + 3= -damaged + 4= -lba_range int *arg1 int *arg2 + 5= -has_acl + 6= -has_xattr + 7= -has_aaip + 8= -has_filter + 9= -wanted_node IsoNode *arg1 (for internal use, arg1 not allocated) + 10= -pending_data + 11= -decision *arg1 ("y", "1", "n", "0") + */ + int test_type; + + void *arg1; + void *arg2; + +}; + + +/* + A computational node. + A tree of these nodes forms the expression. + Sequences of AND/OR operations form branches, brackets spawn new branches, + NOT inverts node's test resp. subtree result. +*/ +struct ExprnodE { + + struct ExprnodE *up; + + char origin[8]; + + /* Operators */ + int invert; /* 0=normal 1=invert own result (subtree or test, but not op) */ + + int assoc; /* + 0= left : compute own value, combine with left value, + compute right value, combine with current value + 1= right: compute own value, compute right value, + combine own and right, combine with left value + */ + + int use_shortcuts; /* 0= evaluate all tests of -and and -or, + 1= evaluate only until the combined result is known + */ + + struct ExprnodE *left; + int left_op; /* 0=OR , 1=AND */ + + struct ExprnodE *right; + int right_op; /* see left_op */ + + /* Brackets : a pointer to the first node in a subchain */ + struct ExprnodE *sub; + + int is_if_then_else; + struct ExprnodE *true_branch; + struct ExprnodE *false_branch; + + /* elementary test : if sub!=NULL , test is ignored */ + struct ExprtesT *test; + + /* Result */ + int own_value; + int composed_value; + +}; + + +struct FindjoB { + + char *start_path; + + struct ExprnodE *test_tree; + + struct ExprnodE *cursor; + int invert; /* 0=normal 1=set invert-property for next new test node */ + int use_shortcuts; + + /* 0= echo + 1= rm (also rmdir) + 2= rm_r +>>> 3= mv target + 4= chown user + 5= chgrp group + 6= chmod mode_and mode_or + 7= alter_date type date + 8= lsdl + 9= chown_r user + 10= chgrp_r group + 11= chmod_r mode_and mode_or + 12= alter_date_r type date + 13= find + 14= compare disk_equivalent_of_start_path + 15= in_iso iso_rr_equivalent_of_start_path + 16= not_in_iso iso_rr_equiv + 17= update disk_equiv + 18= add_missing iso_rr_equiv + 19= empty_iso_dir iso_rr_equiv + 20= is_full_in_iso iso_rr_equiv + 21= report_damage + 22= report_lba + 23= internal:memorize path of last matching node in found_path + 24= getfacl + 25= setfacl access_acl default_acl + 26= getfattr + 27= setfattr + 28= set_filter name + 29= show_stream + */ + int action; + + /* action specific parameters */ + char *target; + char *text_2; + uid_t user; + gid_t group; + mode_t mode_and, mode_or; + int type; /* see Xorriso_set_time flag */ + time_t date; + char *found_path; + struct FindjoB *subjob; + + /* Errors */ + char errmsg[4096]; + int errn; /* + >0 = UNIX errno + -1 = close_bracket: no bracket open + -2 = binary operator or closing bracket expected + -3 = unexpected binary operator or closing bracket + -4 = unsupported command + -5 = -then -elseif -else -endif without -if or at wrong place + */ +}; + + +int Exprtest_match(struct XorrisO *xorriso, struct ExprtesT *ftest, + void *node_pt, char *name, + struct stat *boss_stbuf, struct stat *stbuf, int flag); + + +int Exprnode_destroy(struct ExprnodE **fnode, int flag); + +int Exprnode_tree_value(struct XorrisO *xorriso, struct ExprnodE *fnode, + int left_value, void *node, char *name, + struct stat *boss_stbuf, struct stat *stbuf, int flag); + + +int Findjob_new(struct FindjoB **o, char *start_path, int flag); + +int Findjob_destroy(struct FindjoB **o, int flag); + +int Findjob_set_start_path(struct FindjoB *o, char *start_path, int flag); + +int Findjob_get_start_path(struct FindjoB *o, char **start_path, int flag); + +int Findjob_set_commit_filter_2(struct FindjoB *o, int flag); + +int Findjob_set_lba_range(struct FindjoB *o, int start_lba, int count, + int flag); + +int Findjob_set_wanted_node(struct FindjoB *o, void *wanted_node, int flag); + +int Findjob_set_decision(struct FindjoB *o, char *decision, int flag); + +int Findjob_open_bracket(struct FindjoB *job, int flag); + +int Findjob_close_bracket(struct FindjoB *job, int flag); + +int Findjob_not(struct FindjoB *job, int flag); + +int Findjob_and(struct FindjoB *job, int flag); + +int Findjob_or(struct FindjoB *job, int flag); + +int Findjob_if(struct FindjoB *job, int flag); + +int Findjob_then(struct FindjoB *job, int flag); + +int Findjob_else(struct FindjoB *job, int flag); + +int Findjob_elseif(struct FindjoB *job, int flag); + +int Findjob_endif(struct FindjoB *job, int flag); + +int Findjob_test_2(struct XorrisO *xorriso, struct FindjoB *o, + void *node, char *name, + struct stat *boss_stbuf, struct stat *stbuf, int flag); + +int Findjob_set_action_found_path(struct FindjoB *o, int flag); + +int Findjob_get_action(struct FindjoB *o, int flag); + +int 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); + +int Findjob_set_found_path(struct FindjoB *o, char *path, int flag); + +int Findjob_get_found_path(struct FindjoB *o, char **path, int flag); + +#else /* Xorriso_findjob_on_expR */ + + struct FindjoB; @@ -810,6 +1033,8 @@ int Findjob_set_found_path(struct FindjoB *o, char *path, int flag); int Findjob_get_found_path(struct FindjoB *o, char **path, int flag); +#endif /* ! Xorriso_findjob_on_expR */ + struct SplitparT; diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index e44c114a..f2d01d26 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2009.04.18.150555" +#define Xorriso_timestamP "2009.04.21.173600" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index a4be8324..55b42288 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -63,7 +63,6 @@ #endif /* Xorriso_standalonE */ -#define Xorriso_with_aaiP yes /* Some private in advance declarations */ int Xorriso_pacifier_loop(struct XorrisO *xorriso, struct burn_drive *drive, @@ -121,11 +120,6 @@ int Xorriso_path_from_node(struct XorrisO *xorriso, IsoNode *node, int lba, isoburn_igopt_rrip_version_1_10 | isoburn_igopt_aaip_susp_1_10 ) -/* <<< Whether to allow xattr and ACL with the root node. - (It is supposed to work since libisofs-ng resision 479) -*/ -#define Xorriso_root_with_aaiP yes - /* ------------------------------------------------------------------------ */ @@ -1803,35 +1797,6 @@ int Xorriso_get_volume(struct XorrisO *xorriso, IsoImage **volume, return(*volume != NULL); } -/* - @param flag bit0= do not issue warning -*/ -int Xorriso_aaip_warn_of_root(struct XorrisO *xorriso, IsoNode *node, int flag) -{ - -#ifndef Xorriso_root_with_aaiP - - int ret; - IsoDir *root= NULL; - IsoImage *volume; - - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - return(ret); - root= iso_image_get_root(volume); - if(node == (IsoNode *) root) { - sprintf(xorriso->info_text, - "Cannot attach ACL or xattr to ISO root directory"); - if(!(flag & 1)) - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - return(0); - } - -#endif /* ! Xorriso_root_with_aaiP */ - - return(1); -} - /* @param flag bit0=do not complain about non existent node */ int Xorriso_node_from_path(struct XorrisO *xorriso, IsoImage *volume, @@ -2131,11 +2096,9 @@ int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf, mode= stbuf->st_mode; -#ifdef Xorriso_with_aaiP if((!(flag & 2)) && !(xorriso->do_aaip & 1)) /* Will drop ACL. Update mode S_IRWXG by eventual group:: ACL entry */ iso_local_get_perms_wo_acl(disk_path, &mode, flag & 32); -#endif if((flag&1) && S_ISDIR(mode)) { if(mode&S_IRUSR) @@ -2152,8 +2115,6 @@ int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf, iso_node_set_mtime(node, stbuf->st_mtime); iso_node_set_ctime(node, stbuf->st_ctime); -#ifdef Xorriso_with_aaiP - if((xorriso->do_aaip & 5) && !(flag & 2)) { ret= iso_local_get_attrs(disk_path, &num_attrs, &names, &value_lengths, &values, ((xorriso->do_aaip & 1) && !(flag & 2)) @@ -2184,17 +2145,11 @@ int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf, goto ex; } -#endif /* Xorriso_with_aaiP */ - ret= 1; ex:; Xorriso_process_msg_queues(xorriso,0); - -#ifdef Xorriso_with_aaiP iso_local_get_attrs(disk_path, &num_attrs, &names, &value_lengths, &values, 1 << 15); /* free memory */ -#endif /* Xorriso_with_aaiP */ - return(ret); } @@ -3056,8 +3011,6 @@ int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path, mode= iso_node_get_permissions(node); -#ifdef Xorriso_with_aaiP - if(xorriso->do_aaip & (2 | 8 | 16)) { ret= iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values, (!!(xorriso->do_aaip & 2)) | (!(xorriso->do_aaip & (8 | 16))) << 2); @@ -3083,8 +3036,6 @@ int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path, if(!(xorriso->do_aaip & 2)) mode= iso_node_get_perms_wo_acl(node); -#endif /* Xorriso_with_aaiP */ - if(is_dir && (flag&2)) { ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1 | ((!!(xorriso->do_aaip & 2)) << 3)); @@ -5759,18 +5710,10 @@ int Xorriso_ls_filev(struct XorrisO *xorriso, char *wd, continue; link_target[0]= 0; if((flag&5)==1) { /* -ls_l */ - -#ifdef Xorriso_with_aaiP iso_node_get_acl_text(node, &a_text, &d_text, 16); -#endif - ret= Xorriso_format_ls_l(xorriso, &stbuf, 1 | ((a_text != NULL || d_text != NULL) << 1)); - -#ifdef Xorriso_with_aaiP iso_node_get_acl_text(node, &a_text, &d_text, 1 << 15); -#endif - if(ret<=0) continue; if(LIBISO_ISLNK(node)) { @@ -6686,6 +6629,215 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, } +#ifdef Xorriso_findjob_on_expR + +int Exprtest_match(struct XorrisO *xorriso, struct ExprtesT *ftest, + void *node_pt, char *name, + struct stat *boss_stbuf, struct stat *stbuf, int flag) +/* +return: + <0 = error + 0 = does not match + 1 = does match + 2 = immediate decision : does not match + 3 = immediate decision : does match +*/ +{ + int value=0, ret, start_lba, end_lba; + int lba_count, *file_end_lbas= NULL, *file_start_lbas= NULL, i; + void *arg1, *arg2; + char ft, *decision; + regmatch_t name_match; + off_t damage_start, damage_end, size; + void *xinfo_dummy; + IsoNode *node; + IsoStream *stream; + + if(ftest == NULL) + return(1); + + node= (IsoNode *) node_pt; + arg1= ftest->arg1; + arg2= ftest->arg2; + + if(node == NULL) { + if(ftest->test_type > 2 && ftest->test_type != 4) { + value= 0; + goto ex; + } + } + + switch(ftest->test_type) { + case 0: /* -false */ + value= 0; + + break; case 1: /* -name *arg1 (regex in *arg2) */ + ret= regexec(arg2, name, 1, &name_match, 0); + value= !ret; + + break; case 2: /* -type *arg1 */ + value= 1; + ft= *((char *) arg1); + if(ft!=0) { + if(S_ISBLK(stbuf->st_mode)) { + if(ft!='b') + value= 0; + } else if(S_ISCHR(stbuf->st_mode)) { + if(ft!='c') + value= 0; + } else if(S_ISDIR(stbuf->st_mode)) { + if(ft=='m') { + if(node != NULL) + value= 0; + else if(boss_stbuf==NULL) + value= 0; + else if(boss_stbuf->st_dev == stbuf->st_dev) + value= 0; + } else if(ft!='d') + value= 0; + } else if(S_ISFIFO(stbuf->st_mode)) { + if(ft!='p') + value= 0; + } else if(S_ISREG(stbuf->st_mode)) { + if(ft!='f' && ft!='-') + value= 0; + } else if(((stbuf->st_mode)&S_IFMT)==S_IFLNK) { + if(ft!='l') + value= 0; + } else if(((stbuf->st_mode)&S_IFMT)==S_IFSOCK) { + if(ft!='s') + value= 0; + } else if((flag & 1) && ((stbuf->st_mode) & S_IFMT) == Xorriso_IFBOOT) { + if(ft!='e' || node == NULL) + value= 0; + } else { + if(ft!='X') + value= 0; + } + } + + break; case 3: /* -damaged */; + value= Xorriso_file_eval_damage(xorriso, node, &damage_start, &damage_end, + 0); + if(value > 0) + value= 1; + + break; case 4: /* -lba_range *arg1 *arg2 */ + if(node == NULL) { + value= !(start_lba >= 0); + goto ex; + } + value= 1; + start_lba= *((int *) ftest->arg1); + end_lba= *((int *) ftest->arg2); + ret= Xorriso__start_end_lbas(node, &lba_count, + &file_start_lbas, &file_end_lbas, &size, 0); + if(ret <= 0) { + if(ret < 0) + Xorriso_process_msg_queues(xorriso, 0); + if(start_lba >= 0) + value= 0; + } else { + for(i= 0; i < lba_count; i++) { + if(start_lba >= 0) { + if(file_end_lbas[i] < start_lba || file_start_lbas[i] > end_lba) + value= 0; + } else { + if(file_end_lbas[i] >= -start_lba && file_start_lbas[i] <= -end_lba) + value= 0; + } + } + } + + break; case 5: /* -has_acl */ + ret = Xorriso_getfacl(xorriso, (void *) node, "", NULL, 2); + if(ret <= 0) { + value= -1; + Xorriso_process_msg_queues(xorriso, 0); + goto ex; + } + value= (ret == 1); + + break; case 6: /* -has_xattr */ + ret = Xorriso_getfattr(xorriso, (void *) node, "", NULL, 64); + if(ret < 0) { + value= -1; + Xorriso_process_msg_queues(xorriso, 0); + goto ex; + } + value= (ret > 0); + + break; case 7: /* -has_aaip */ + ret= iso_node_get_xinfo(node, aaip_xinfo_func, &xinfo_dummy); + if(ret < 0) { + value= -1; + Xorriso_process_msg_queues(xorriso, 0); + goto ex; + } + value= (ret > 0); + + break; case 8: /* -has_filter */ + value= 0; + if(LIBISO_ISREG(node)) { + stream= iso_file_get_stream((IsoFile *) node); + if(iso_stream_get_input_stream(stream, 0) != NULL) + value= 1; + } + + break; case 9: /* -wanted_node arg1 (for internal use) */ + value= (((IsoNode *) arg1) == node); + + break; case 10: /* -pending_data */ + value= 1; + if(!LIBISO_ISREG(node)) { + value= 0; + } else { + ret= Xorriso__file_start_lba(node, &start_lba, 0); + if(ret > 0 && start_lba >= 0) + value= 0; + } + + break; case 11: /* -decision */ + value= 3; + decision= (char *) arg1; + if(strcmp(decision, "no") == 0 || strcmp(decision, "false") == 0 || + strcmp(decision, "0") == 0) + value= 2; + + break; default: + + /* >>> complain about unknown test type */; + + value= -1; + + } + +ex:; + if(ftest->invert && value<=1 && value>=0) + value= !value; + if(file_start_lbas != NULL) + free((char *) file_start_lbas); + if(file_end_lbas != NULL) + free((char *) file_end_lbas); + return(value); +} + + +int Xorriso_findi_test(struct XorrisO *xorriso, struct FindjoB *job, + IsoNode *node, char *name, + struct stat *boss_stbuf, struct stat *stbuf, + int depth, int flag) +{ + int ret; + + ret= Findjob_test_2(xorriso, job, node, name, boss_stbuf, stbuf, 1); + if(ret<=0) + return(ret); + return(1); +} + +#else /* Xorriso_findjob_on_expR */ + int Xorriso_findi_test(struct XorrisO *xorriso, struct FindjoB *job, IsoNode *node, char *name, struct stat *boss_stbuf, struct stat *stbuf, @@ -6763,13 +6915,9 @@ int Xorriso_findi_test(struct XorrisO *xorriso, struct FindjoB *job, } Findjob_get_aaip_filter(job, &a_filter, 0); if(a_filter) { -#ifdef Xorriso_with_aaiP { void *xinfo_dummy; ret= iso_node_get_xinfo(node, aaip_xinfo_func, &xinfo_dummy); } -#else - ret= 0; -#endif if(ret < 0) { Xorriso_process_msg_queues(xorriso, 0); goto ex; @@ -6806,6 +6954,8 @@ ex:; return(ret); } +#endif /* ! Xorriso_findjob_on_expR */ + /* @param flag bit0= recursion bit1= do not count deleted files with rm and rm_r @@ -9070,14 +9220,8 @@ int Xorriso_getfacl(struct XorrisO *xorriso, void *in_node, char *path, if(ret<=0) goto ex; } - -#ifdef Xorriso_with_aaiP ret= iso_node_get_acl_text(node, &text, &d_text, flag & 16); d_ret= (d_text != NULL); -#else - ret= d_ret= 0; -#endif - if(ret < 0 || d_ret < 0) { if(path != NULL && path[0] != 0) { strcpy(xorriso->info_text, "Error with obtaining ACL of "); @@ -9095,13 +9239,8 @@ int Xorriso_getfacl(struct XorrisO *xorriso, void *in_node, char *path, ret= 1 + (ret == 0); goto ex; } -#ifdef Xorriso_with_aaiP strcpy(xorriso->info_text, "No ACL associated with "); Text_shellsafe(path, xorriso->info_text, 1); -#else - strcpy(xorriso->info_text, - "ACL not enabled by Libisofs_with_aaiP/Xorriso_with_aaiP"); -#endif Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); if(ret == 0) {ret= 2; goto ex;} @@ -9229,19 +9368,7 @@ int Xorriso_setfacl(struct XorrisO *xorriso, void *in_node, char *path, if(ret<=0) goto ex; } - - ret= Xorriso_aaip_warn_of_root(xorriso, node, flag & 1); - if (ret < 0) - goto ex; - if (ret == 0) - {ret= 1; goto ex;} - -#ifdef Xorriso_with_aaiP ret= iso_node_set_acl_text(node, access_text, default_text, 0); -#else - ret= 0; -#endif - if(ret <= 0) { if(path != NULL && path[0] != 0) { strcpy(xorriso->info_text, "Error with setting ACL of "); @@ -9366,20 +9493,8 @@ int Xorriso_setfattr(struct XorrisO *xorriso, void *in_node, char *path, if(ret<=0) goto ex; } - - ret= Xorriso_aaip_warn_of_root(xorriso, node, !!(flag & 16)); - if (ret < 0) - goto ex; - if (ret == 0) - {ret= 1; goto ex;} - -#ifdef Xorriso_with_aaiP ret= iso_node_set_attrs(node, num_attrs, names, value_lengths, values, flag & (1 | 2 | 4 | 8)); -#else - ret= 0; -#endif - Xorriso_process_msg_queues(xorriso,0); if(ret <= 0) { Xorriso_report_iso_error(xorriso, "", ret, @@ -9419,8 +9534,6 @@ ex:; int Xorriso_local_getfacl(struct XorrisO *xorriso, char *disk_path, char **text, int flag) { -#ifdef Xorriso_with_aaiP - int ret, skip= 0, colons= 0, countdown= 0; char *acl= NULL, *cpt, *wpt; @@ -9471,12 +9584,6 @@ int Xorriso_local_getfacl(struct XorrisO *xorriso, char *disk_path, *wpt= 0; return(1); -#else - - *text= NULL; - return(0); - -#endif /* ! Xorriso_with_aaiP */ } @@ -9495,7 +9602,6 @@ int Xorriso_get_attrs(struct XorrisO *xorriso, void *in_node, char *path, IsoNode *node; if(flag & (1 << 15)) { -#ifdef Xorriso_with_aaiP if(flag & 2) { iso_local_get_attrs(NULL, num_attrs, names, value_lengths, values, 1 << 15); @@ -9503,14 +9609,11 @@ int Xorriso_get_attrs(struct XorrisO *xorriso, void *in_node, char *path, iso_node_get_attrs(NULL, num_attrs, names, value_lengths, values, 1 << 15); } -#endif /* Xorriso_with_aaiP */ return(1); } *num_attrs= 0; if(flag & 2) { - -#ifdef Xorriso_with_aaiP ret= iso_local_get_attrs(path, num_attrs, names, value_lengths, values, flag & (8 | 32)); if(ret < 0) { @@ -9518,9 +9621,6 @@ int Xorriso_get_attrs(struct XorrisO *xorriso, void *in_node, char *path, Text_shellsafe(path, xorriso->info_text, 1); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); } -#endif /* Xorriso_with_aaiP */ - ; - } else { node= (IsoNode *) in_node; if(node == NULL) { @@ -9528,7 +9628,6 @@ int Xorriso_get_attrs(struct XorrisO *xorriso, void *in_node, char *path, if(ret<=0) goto ex; } -#ifdef Xorriso_with_aaiP ret= iso_node_get_attrs(node, num_attrs, names, value_lengths, values, 0); if(ret < 0) { @@ -9536,7 +9635,6 @@ int Xorriso_get_attrs(struct XorrisO *xorriso, void *in_node, char *path, "Error when obtaining xattr of ISO node", 0, "FAILURE", 1); goto ex; } -#endif /* Xorriso_with_aaiP */ if(!(flag & 8)) { /* Filter away any non-userspace xattr */;