"Fossies" - the Fresh Open Source Software Archive

Member "libisoburn-1.5.4/xorriso/findjob.c" (8 Jul 2020, 27842 Bytes) of package /linux/misc/libisoburn-1.5.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "findjob.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.4.6_vs_1.4.8.

    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 
   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 
   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 
   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 
  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 
  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 
  148 int Exprnode_is_if(struct ExprnodE *fnode, int flag)
  149 {
  150   return(fnode->is_if_then_else);
  151 }
  152 
  153 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 */
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 whether 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 */
  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 
  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 */
  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 */
  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 
  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 
  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 
  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 */
  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 */
  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 */
  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 */
  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 
  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 
  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 
 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 
 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 
 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 */
 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 
 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 
 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 
 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 
 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 
 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 */
 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 
 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 
 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 
 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 
 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 */
 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 */
 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 */
 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 */
 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 
 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 
 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