"Fossies" - the Fresh Open Source Software Archive

Member "xorriso-1.5.4/xorriso/parse_exec.c" (30 Jan 2021, 101681 Bytes) of package /linux/misc/xorriso-1.5.4.pl02.tar.gz:


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

    1 
    2 /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
    3 
    4    Copyright 2007-2020 Thomas Schmitt, <scdbackup@gmx.net>
    5 
    6    Provided under GPL version 2 or later.
    7 
    8    This file contains the implementation of functions which deal with parsing
    9    and interpretation of command input.
   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 <fcntl.h>
   26 #include <errno.h>
   27 #include <pwd.h>
   28 #include <grp.h>
   29 #include <sys/resource.h>
   30 #include <sys/wait.h>
   31 
   32 
   33 #include "xorriso.h"
   34 #include "xorriso_private.h"
   35 #include "xorrisoburn.h"
   36 
   37 
   38 #ifdef Xorriso_fetch_with_msg_queueS
   39 #include <pthread.h>
   40 #endif
   41 
   42 
   43 /* @param flag bit0= do not warn of wildcards
   44                bit1= these are disk_paths
   45 */
   46 int Xorriso_end_idx(struct XorrisO *xorriso,
   47                     int argc, char **argv, int idx, int flag)
   48 {
   49  int i, warned= 0;
   50 
   51  for(i= idx; i<argc; i++) {
   52    if(strcmp(argv[i], xorriso->list_delimiter)==0)
   53  break;
   54    if(!((flag&1) || warned))
   55      warned= Xorriso_warn_of_wildcards(xorriso, argv[i], flag&2);
   56  }
   57  return(i);
   58 }
   59 
   60 
   61 /* Returns a vector of strings which belong to an open ended arg list.
   62    If expansion is enabled, the vector might be allocated, else it is
   63    a pointer into the argv input vector.
   64    Thus the release of that memory is an expert task to be done by this
   65    function only. Use bit8 for that. With bit8 parameter argc MUST be the
   66    same value as with the call which might have allocated memory.
   67    @param xorriso The environment object
   68    @param argc Length of argv
   69    @param argv The vector with arguments, eventual list_delimiter ("--")
   70                and then eventual unrelated words
   71    @param idx  Start index in argv of the argument list
   72    @param optc Length of the effective possibly expanded option vector
   73    @param optv The option vector. Maybe a pointer into argv or maybe
   74                an own allocated vector.
   75    @param flag bit0= do not warn of wildcards
   76                bit1= these are disk_paths
   77                bit2= never expand wildcards
   78                bit3= do not expand last argument
   79                bit4= ignore last argument
   80                bit5= demand exactly one match
   81                bit6= with bit5 allow 0 matches if pattern is a constant
   82                bit7= silently tolerate empty argument list
   83                bit8= free the eventually allocated sub_vector
   84                bit9= always expand wildcards
   85               bit10= do not add unresolved pattern to optv
   86 */
   87 int Xorriso_opt_args(struct XorrisO *xorriso, char *cmd,
   88                      int argc, char **argv, int idx,
   89                      int *end_idx, int *optc, char ***optv, int flag)
   90 {
   91  int i, do_expand, nump, was_empty= 0, filec= 0, ret;
   92  char **filev= NULL, **patterns= NULL;
   93  off_t mem= 0;
   94 
   95  if(flag&2)
   96    do_expand= (xorriso->do_disk_pattern==1 && !(flag&4)) || (flag & 512);
   97  else
   98    do_expand= (xorriso->do_iso_rr_pattern==1 && !(flag&4)) || (flag & 512);
   99  if(flag&256) {
  100    if(argv == NULL || *optv < argv || (*optv >= argv + argc && argc > 0))
  101      Sfile_destroy_argv(optc, optv, 0);
  102    return(1);
  103  }
  104  if(idx>=argc) {
  105    *end_idx= argc;
  106    *optc= 0;
  107    *optv= NULL;
  108    sprintf(xorriso->info_text, "%s : Not enough arguments given", cmd);
  109    if((flag & 128))
  110      return(1);
  111    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
  112    return(0);
  113  }
  114  *end_idx= Xorriso_end_idx(xorriso, argc, argv, idx,
  115                            ((flag&1) || do_expand) | (flag&2));
  116  if(*end_idx<0)
  117    return(*end_idx);
  118  if((flag&16) && (*end_idx)>idx)
  119    (*end_idx)--;
  120 
  121  *optc= *end_idx - idx;
  122  *optv= NULL;
  123  if(*optc<=0 || !do_expand) {
  124 copy_args:;
  125    if(*optc > 0) {
  126      Xorriso_alloc_meM(*optv, char *,  *optc);
  127      for(i= 0; i < *optc; i++) {
  128        Xorriso_alloc_meM((*optv)[i], char, strlen(argv[idx + i]) + 1);
  129        strcpy((*optv)[i], argv[idx + i]);
  130      }
  131    }
  132    return(1);
  133  }
  134  patterns= calloc(*optc, sizeof(char *));
  135  if(patterns==NULL) {
  136 no_memory:;
  137    sprintf(xorriso->info_text,
  138            "%s : Cannot allocate enough memory for pattern expansion", cmd);
  139    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
  140    {ret= -1; goto ex;}
  141  }
  142  nump= 0;
  143  if(flag&8) {
  144    was_empty= 1;
  145    mem+= strlen(argv[idx + *optc - 1])+1+sizeof(char *);
  146  }
  147  for(i= 0; i<*optc-!!(flag&8); i++) {
  148    if(argv[i + idx][0]==0) {
  149      was_empty++;
  150      mem+= sizeof(char *); /* as upper limit for size of an empty string */
  151  continue;
  152    }
  153    patterns[nump++]= argv[i + idx];
  154  }
  155  if(nump<=0) { /* Only empty texts. May the caller get happy with them. */
  156    free(patterns);
  157    goto copy_args;
  158  }
  159  if(flag&2)
  160    ret= Xorriso_expand_disk_pattern(xorriso, nump, patterns, was_empty,
  161                                  &filec, &filev, &mem,
  162                                  ((flag >> 5) & 3) | ((!!(flag & 1024)) << 3));
  163  else
  164    ret= Xorriso_expand_pattern(xorriso, nump, patterns, was_empty, 
  165                                &filec, &filev, &mem,
  166                                ((flag >> 5) & 3) | ((!!(flag & 1024)) << 3));
  167  if(ret<=0)
  168    {ret= 0; goto ex;}
  169  for(i= 0; i<was_empty; i++) {
  170    if(i==was_empty-1 && (flag&8))
  171      filev[filec++]= strdup(argv[idx + *optc - 1]);
  172    else
  173      filev[filec++]= strdup("");
  174    if(filev[filec-1]==NULL)
  175      goto no_memory;
  176  }
  177 
  178 #ifdef Xorriso_verbous_pattern_expansioN
  179 { int l;
  180  sprintf(xorriso->info_text, "Pattern expansion yields %d items:", filec);
  181  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
  182  l= 0;
  183  xorriso->info_text[0]= 0;
  184  for(i= 0; i<filec; i++) {
  185    l= strlen(xorriso->info_text);
  186    if(l>0 && l+1+strlen(filev[i])>60) {
  187      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
  188      xorriso->info_text[0]= 0;
  189      l= 0;
  190    }
  191    sprintf(xorriso->info_text+l, " %s", filev[i]);
  192  }
  193  l= strlen(xorriso->info_text);
  194  if(l>0)
  195    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
  196 }
  197 #endif /* Xorriso_verbous_pattern_expansioN */
  198 
  199  ret= 1;
  200 ex:;
  201  if(patterns!=NULL)
  202    free((char *) patterns);
  203  if(ret<=0) {
  204    Sfile_destroy_argv(&filec, &filev, 0);
  205  } else {
  206    *optc= filec;
  207    *optv= filev;
  208  }
  209  return(ret);
  210 }
  211 
  212 
  213 /* @param flag bit0= get eternal problem status
  214 */
  215 int Xorriso_get_problem_status(struct XorrisO *xorriso, char severity[80],
  216                                int flag)
  217 {
  218  if(flag & 1) {
  219    strcpy(severity, xorriso->eternal_problem_status_text);
  220    return(xorriso->eternal_problem_status);
  221  } else {
  222    strcpy(severity, xorriso->problem_status_text);
  223    return(xorriso->problem_status);
  224  }
  225 }
  226 
  227 
  228 /* @param flag bit0= set eternal problem status to severity,
  229                      and set problem status to ALL
  230 */
  231 int Xorriso_set_problem_status(struct XorrisO *xorriso, char *severity, 
  232                                int flag)
  233 {
  234  char *sev_text= "ALL";
  235  int sev, ret;
  236 
  237 #ifdef Xorriso_fetch_with_msg_queueS
  238  int locked= 0, uret;
  239  static int complaints= 0, complaint_limit= 5;
  240 #endif
  241 
  242  if(severity[0] && strlen(severity) < sizeof(xorriso->problem_status_text))
  243    sev_text= severity;
  244  ret= Xorriso__text_to_sev(sev_text, &sev, 0);
  245  if(ret<=0)
  246    return(0);
  247 
  248 #ifdef Xorriso_fetch_with_msg_queueS
  249 
  250  ret= pthread_mutex_lock(&(xorriso->problem_status_lock));
  251  if(ret != 0) {
  252    /* Cannot report failure through the failing message output system */
  253    complaints++;
  254    if(complaints < complaint_limit)
  255      fprintf(stderr,
  256         "xorriso : pthread_mutex_lock() for problem_status returns %d\n",
  257         ret);
  258  } else
  259    locked= 1;
  260 
  261 #endif /* Xorriso_fetch_with_msg_queueS */
  262 
  263  if(flag & 1) {
  264    strcpy(xorriso->problem_status_text, "ALL");
  265    Xorriso__text_to_sev(xorriso->problem_status_text,
  266                         &(xorriso->problem_status), 0);
  267  } else {
  268    xorriso->problem_status= sev;
  269    strcpy(xorriso->problem_status_text, sev_text);
  270  }
  271  if(sev > xorriso->eternal_problem_status || (flag & 1)) {
  272    xorriso->eternal_problem_status= sev;
  273    strcpy(xorriso->eternal_problem_status_text, sev_text);
  274  }
  275 
  276 #ifdef Xorriso_fetch_with_msg_queueS
  277 
  278  if(locked) {
  279    uret= pthread_mutex_unlock(&(xorriso->problem_status_lock));
  280    if(uret != 0) {
  281      /* Cannot report failure through the failing message output system */
  282      complaints++;
  283      if(complaints < complaint_limit)
  284        fprintf(stderr,
  285             "xorriso : pthread_mutex_unlock() for problem_status returns %d\n",
  286             uret);
  287    }
  288  }
  289 
  290 #endif /* Xorriso_fetch_with_msg_queueS */
  291 
  292  return(1);
  293 }
  294 
  295 
  296 /**
  297     @param flag       bit0= do not issue own event messages
  298                       bit1= take xorriso->request_to_abort as reason for abort
  299     @return           Gives the advice:
  300                         2= pardon was given, go on
  301                         1= no problem, go on
  302                         0= function failed but xorriso would not abort, go on
  303                        <0= do abort
  304                            -1 = due to problem_status
  305                            -2 = due to xorriso->request_to_abort
  306 */
  307 int Xorriso_eval_problem_status(struct XorrisO *xorriso, int ret, int flag)
  308 {
  309  static int sev= 0;
  310  if(sev==0)
  311    Xorriso__text_to_sev("SORRY", &sev, 0);
  312 
  313  if((flag&2) && xorriso->request_to_abort)
  314    return(-2);
  315 
  316  Xorriso_process_msg_queues(xorriso, 0);
  317  if(ret>0 && xorriso->problem_status <= 0)
  318    return(1);
  319 
  320  if(xorriso->problem_status < xorriso->abort_on_severity &&
  321     xorriso->problem_status > 0) {
  322    if(xorriso->problem_status >= sev && !(flag&1)) {
  323      sprintf(xorriso->info_text,
  324              "xorriso : NOTE : Tolerated problem event of severity '%s'\n",
  325              xorriso->problem_status_text);
  326      Xorriso_info(xorriso, 0);/* submit not as problem event */
  327    }
  328    ret= 2;
  329  } else if(xorriso->problem_status > 0) {
  330    sprintf(xorriso->info_text,
  331            "xorriso : aborting : -abort_on '%s' encountered '%s'\n",
  332            xorriso->abort_on_text, xorriso->problem_status_text);
  333    if(!(flag&1))
  334      Xorriso_info(xorriso, 0);/* submit not as problem event */
  335    ret= -1;
  336  } else if(ret>0)
  337    ret= 1;
  338  else
  339    ret= 2;
  340  return(ret);
  341 }
  342 
  343 
  344 /* @param flag bit0= a non-existing target of multiple sources is a directory
  345                bit1= all paths except the last one are disk_paths
  346                bit2= the last path is a disk_path
  347    @return <=0 is error, 1= leaf file object, 2= directory
  348 */
  349 int Xorriso_cpmv_args(struct XorrisO *xorriso, char *cmd,
  350                       int argc, char **argv, int *idx,
  351                       int *optc, char ***optv, char eff_dest[SfileadrL],
  352                       int flag)
  353 {
  354  int destc= 0, is_dir=0, end_idx, ret, i;
  355  char **destv= NULL;
  356 
  357  end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx,
  358                           (xorriso->do_iso_rr_pattern==1)|(flag&2));
  359  if(end_idx - *idx < 2) {
  360    sprintf(xorriso->info_text, "%s: not enough arguments", cmd);
  361    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
  362    {ret= 0; goto ex;}
  363  }
  364 
  365  ret= Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, optc, optv,
  366                        1 | (flag&2) | 16); /* ignore last argument */
  367  if(ret<=0)
  368    goto ex;
  369  /* demand one match, or 0 with a constant */
  370  ret= Xorriso_opt_args(xorriso, cmd, argc, argv, end_idx, &end_idx, &destc,
  371                        &destv, 1 | ((flag&4)>>1) | 32 | 64);
  372  if(ret<=0)
  373    goto ex;
  374 
  375  /* Evaluate target address */
  376  if(flag&4)
  377    ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, destv[0], eff_dest,
  378                                    2|4|16);
  379  else
  380    ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, destv[0], eff_dest,
  381                                    1);
  382  if(ret<0)
  383    {ret= 0; goto ex;}
  384  if(ret==2 || ((flag&1) && *optc > 1 && ret==0)) {
  385    is_dir= 1;
  386  } else if(*optc > 1) {
  387    if(flag & 2)
  388      for(i= 0; i<*optc; i++)
  389        Xorriso_msgs_submit(xorriso, 0, (*optv)[i], 0, "ERRFILE", 0);
  390    sprintf(xorriso->info_text,
  391         "%s: more than one origin given, destination is a non-directory: ",
  392         cmd);
  393    Text_shellsafe(destv[0], xorriso->info_text, 1);
  394    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
  395    {ret= 0; goto ex;}
  396  }
  397  if(ret==0) { /* compute complete eff_dest */
  398    ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, destv[0], eff_dest,
  399                                    2 | (flag&4));
  400    if(ret<0)
  401      {ret= 0; goto ex;}
  402  }
  403 
  404  ret= 1+is_dir;
  405 ex:;
  406  Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, &destc, &destv,
  407                   256);
  408  (*idx)= end_idx;
  409  return(ret);
  410 }
  411 
  412 
  413 /* @param flag bit0= with adr_mode sbsector: adr_value is possibly 16 too high
  414 */
  415 int Xorriso_decode_load_adr(struct XorrisO *xorriso, char *cmd,
  416                             char *adr_mode, char *adr_value,
  417                             int *entity_code, char entity_id[81],
  418                             int flag)
  419 {
  420  double num;
  421  int l;
  422 
  423  if(strcmp(adr_mode, "auto")==0)
  424    *entity_code= 0;
  425  else if(strcmp(adr_mode, "session")==0)
  426    *entity_code= 1;
  427  else if(strcmp(adr_mode, "track")==0)
  428    *entity_code= 2;
  429  else if(strcmp(adr_mode, "lba")==0 || strcmp(adr_mode, "sbsector")==0)
  430    *entity_code= 3 | ((flag&1) << 16);
  431  else if(strcmp(adr_mode, "volid")==0)
  432    *entity_code= 4;
  433  else {
  434    sprintf(xorriso->info_text, "%s: unknown address mode '%s'", cmd, adr_mode);
  435    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
  436    return(0);
  437  }
  438  l= strlen(adr_value);
  439  if(l==0)
  440    *entity_code= 0;
  441 
  442  if(*entity_code>=1 && *entity_code<= 3) {
  443    num= Scanf_io_size(adr_value, 0);
  444    if(*entity_code==3 &&
  445       (adr_value[l-1]<'0' || adr_value[l-1]>'9'))
  446      num/= 2048.0;
  447    sprintf(entity_id, "%.f", num);
  448  } else {
  449    if(strlen(adr_value)>80) {
  450      sprintf(xorriso->info_text, "%s: address value too long (80 < %d)",
  451              cmd, (int) strlen(adr_value));
  452      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
  453      return(0);
  454    }
  455    strcpy(entity_id, adr_value);
  456  }
  457  return(1);
  458 }
  459 
  460  
  461 int Xorriso_check_thing_len(struct XorrisO *xorriso, char *name, int size,
  462                             char *cmd, char *thing, int flag)
  463 {
  464  if((int) strlen(name) >= size) {
  465    sprintf(xorriso->info_text,
  466            "%s too long with option %s (%d > %d)", thing, cmd,
  467            (int) strlen(name), size - 1);
  468    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
  469    return(0);
  470  }
  471  return(1);
  472 }
  473  
  474 
  475 int Xorriso_check_name_len(struct XorrisO *xorriso, char *name, int size,
  476                            char *cmd, int flag)
  477 {
  478  return Xorriso_check_thing_len(xorriso, name, size, cmd, "Name", flag);
  479 }
  480 
  481 
  482 /* @return <0 error , >=0 number of skipped dashes
  483 */
  484 int Xorriso_normalize_command(struct XorrisO *xorriso, char *original_cmd,
  485                               int argno, char *cmd_data, int sizeof_cmd_data,
  486                               char **cmd, int flag)
  487 {
  488  int was_dashed= 0;
  489  char *dash_pt;
  490 
  491  if((int) strlen(original_cmd) >= sizeof_cmd_data) {
  492    if(argno>=0)
  493      sprintf(xorriso->info_text, "Oversized argument #%d (length %d)\n",
  494              argno, (int) strlen(original_cmd));
  495    else
  496      sprintf(xorriso->info_text, "Oversized option (length %d)\n",
  497              (int) strlen(original_cmd));
  498    return(-1);
  499  }
  500  strcpy(cmd_data, original_cmd);
  501  *cmd= cmd_data;
  502  if(strcmp(*cmd, xorriso->list_delimiter)==0)
  503    return(1);
  504  while((*cmd)[0]=='-') {
  505    if((*cmd)[1]==0)
  506  break;
  507    was_dashed++;
  508    (*cmd)++;
  509  }
  510  for(dash_pt= *cmd; *dash_pt!=0; dash_pt++)
  511    if(*dash_pt=='-')
  512      *dash_pt= '_';
  513  return(was_dashed);
  514 }
  515 
  516 
  517 /* @param flag bit0= do not warn of unknown option
  518    @return <=0 error,
  519            1=count is valid, 2=dashed unknown, 3=undashed unknown
  520 */
  521 int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv,
  522                        int *count, int flag)
  523 {
  524  int ret, was_dashed= 0, i, cmd_data_size= 2 * SfileadrL;
  525  char *cmd, *cmd_data= NULL;
  526  static char arg0_commands[][40]= {
  527     "ban_stdio_write","close_filter_list","commit",
  528     "device_links","devices","end",
  529     "for_backup", "help",
  530     "list_arg_sorting","list_formats","list_speeds",
  531     "no_rc","print_size","pvd_info","pwd","pwdi","pwdx",
  532     "read_mkisofsrc","rollback","rollback_end",
  533     "tell_media_space","toc","version",
  534     ""
  535  };
  536  static char arg1_commands[][40]= {
  537     "abort_on","acl","add_plainly","application_id","application_use",
  538     "auto_charset","abstract_file",
  539     "backslash_codes","blank","biblio_file",
  540     "calm_drive","cd","cdi","cdx","changes_pending","charset",
  541     "close","close_damaged",
  542     "commit_eject","compliance","copyright_file",
  543     "dev","dialog","disk_dev_ino","disk_pattern","displacement",
  544     "drive_access","dummy","dvd_obs","early_stdio_test","ecma119_map","eject",
  545     "extract_boot_images",
  546     "iso_nowtime","iso_rr_pattern","file_name_limit","follow","format","fs",
  547     "gid","grow_blindly","hardlinks",
  548     "hfsplus","history","indev","in_charset","joliet","joliet_map",
  549     "list_delimiter","list_extras","list_profiles","local_charset",
  550     "mark","md5","mount_opts","modesty_on_drive",
  551     "not_leaf","not_list","not_mgt",
  552     "options_from_file","osirrox","outdev","out_charset","overwrite",
  553     "pacifier","padding","path_list","pathspecs","pkt_output",
  554     "preparer_id","print","print_info","print_mark","prompt",
  555     "prog","prog_help","publisher","quoted_not_list","quoted_path_list",
  556     "read_fs","read_speed","reassure","report_about",
  557     "report_el_torito","report_system_area","rockridge",
  558     "rom_toc_scan","rr_reloc_dir","scsi_dev_family","scsi_log",
  559     "session_log","sh_style_result","signal_handling","sleep",
  560     "speed","split_size","status","status_history_max",
  561     "stdio_sync","stream_recording","system_id","temp_mem_limit","toc_of",
  562     "uid","unregister_filter","use_immed_bit","use_readline",
  563     "volid","volset_id",
  564     "write_type","xattr","zisofs",
  565     ""
  566  };
  567  static char arg2_commands[][40]= {
  568     "assert_volid","boot_image","clone","compare","compare_r","drive_class",
  569     "data_cache_size",
  570     "errfile_log","error_behavior","extract","extract_single",
  571     "jigdo","lns","lnsi","load","logfile",
  572     "map","map_single","move","msg_op","page","return_with",
  573     "scdbackup_tag","update","update_r","volume_date",
  574     ""
  575  };
  576  static char arg3_commands[][40]= {
  577     "append_partition", "truncate_overwritable",
  578     ""
  579  };
  580  static char arg4_commands[][40]= {
  581     "cut_out","extract_cut","mount","mount_cmd","named_pipe_loop",
  582     "paste_in","session_string",
  583     ""
  584  };
  585  static char argn_commands[][40]= {
  586     "add","alter_date","alter_date_r","as",
  587     "check_md5","check_md5_r","check_media","check_media_defaults",
  588     "chgrp","chgrpi","chgrp_r","chgrp_ri","chmod","chmodi",
  589     "chmod_r","chmod_ri","chown","chowni","chown_r","chown_ri",
  590     "compare_l","concat","cp_clone","cp_rax","cp_rx","cpr","cpri","cpax","cpx",
  591     "du","dui","dus","dusi","dux","dusx","external_filter","extract_l",
  592     "file_size_limit","find","findi","finds","findx",
  593     "getfacl","getfacli","getfacl_r","getfacl_ri",
  594     "getfattr","getfattri","getfattr_r","getfattr_ri","hide",
  595     "launch_frontend","ls","lsi","lsl","lsli","lsd","lsdi","lsdl","lsdli",
  596     "lsx","lslx","lsdx","lsdlx","map_l","mv","mvi","mkdir","mkdiri",
  597     "not_paths","rm","rmi","rm_r","rm_ri","rmdir","rmdiri",
  598     "update_l","update_li","update_lx","update_lxi",
  599     "setfacl","setfacli","setfacl_list","setfacl_listi",
  600     "setfacl_r","setfacl_ri","setfattr","setfattri",
  601     "setfattr_list","setfattr_listi","setfattr_r","setfattr_ri",
  602     "set_filter","set_filter_r","show_stream","show_stream_r",
  603     ""
  604  };
  605 
  606  Xorriso_alloc_meM(cmd_data, char, cmd_data_size);
  607 
  608  *count= 0;
  609  if(argc<=0)
  610    {ret= -1; goto ex;}
  611  ret= Xorriso_normalize_command(xorriso, argv[0], -1,
  612                                 cmd_data, cmd_data_size, &cmd, 0);
  613  if(ret<0)
  614    goto ex;
  615  was_dashed= (ret>0);
  616  if(cmd[0]=='#' || cmd[0]==0 || strcmp(cmd, xorriso->list_delimiter) == 0) {
  617    /* ignore: comment line , empty option , orphaned list delimiter */
  618    {ret= 1; goto ex;}
  619  }
  620  for(i=0; arg0_commands[i][0]!=0; i++)
  621    if(strcmp(arg0_commands[i], cmd)==0)
  622      {ret= 1; goto ex;}
  623  *count= 1;
  624  for(i=0; arg1_commands[i][0]!=0; i++)
  625    if(strcmp(arg1_commands[i], cmd)==0)
  626      {ret= 1; goto ex;}
  627  *count= 2;
  628  for(i=0; arg2_commands[i][0]!=0; i++)
  629    if(strcmp(arg2_commands[i], cmd)==0)
  630      {ret= 1; goto ex;}
  631  *count= 3;
  632  for(i=0; arg3_commands[i][0]!=0; i++)
  633    if(strcmp(arg3_commands[i], cmd)==0)
  634      {ret= 1; goto ex;}
  635  *count= 4;
  636  for(i=0; arg4_commands[i][0]!=0; i++)
  637    if(strcmp(arg4_commands[i], cmd)==0)
  638      {ret= 1; goto ex;}
  639  *count= 0;
  640  for(i=0; argn_commands[i][0]!=0; i++)
  641    if(strcmp(argn_commands[i], cmd)==0) {
  642      ret= Xorriso_end_idx(xorriso, argc, argv, 1, 1);
  643      if(ret<1)
  644        goto ex;
  645      *count= ret-1;
  646      {ret= 1; goto ex;}
  647    }
  648 
  649  if(!(flag&1)) {
  650    sprintf(xorriso->info_text, "Unknown option : '%s'", argv[0]);
  651    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
  652  }
  653 
  654  ret= 2 + !was_dashed;
  655 ex:
  656  Xorriso_free_meM(cmd_data);
  657  return(ret);
  658 }
  659 
  660 
  661 /* @param flag bit0= list sorting order rather than looking for argv[idx]
  662 */
  663 int Xorriso_cmd_sorting_rank(struct XorrisO *xorriso,
  664                         int argc, char **argv, int idx, int flag)
  665 {
  666  int ret, i, cmd_data_size= 2 * SfileadrL;
  667  char *cmd, *cmd_data= NULL;
  668  static char *commands[]= {
  669 
  670    "* Execution order of program arguments with option -x:",
  671    "x",
  672 
  673    "* Support for frontend programs via stdin and stdout (1):",
  674    "prog", "prog_help",
  675 
  676    "* Exception processing:",
  677    "abort_on", "return_with", "report_about", "signal_handling",
  678    "error_behavior",
  679 
  680    "* Scripting, dialog and program control features (1):",
  681    "no_rc", "help", "version", "list_extras", "list_arg_sorting",
  682    "temp_mem_limit", "backslash_codes",
  683    "errfile_log", "session_log", "scsi_log",
  684    "options_from_file", "list_delimiter",
  685    "print", "print_info", "print_mark", "prompt", "sleep",
  686    "sh_style_result",
  687 
  688    "* Influencing opening of drives:",
  689    "drive_access","drive_class","early_stdio_test",
  690 
  691    "* Drive and media related inquiry actions (1):",
  692    "devices", "device_links",
  693    "mount_opts", "mount_cmd", "session_string",
  694 
  695    "* Influencing the behavior of image loading:",
  696    "read_speed", "load", "displacement", "read_fs",
  697    "assert_volid", "in_charset",
  698    "auto_charset", "hardlinks", "acl", "xattr", "md5", "for_backup",
  699    "ecma119_map", "joliet_map",
  700    "disk_dev_ino", "rom_toc_scan", "calm_drive", "ban_stdio_write",
  701    "data_cache_size",
  702    "scsi_dev_family", "iso_nowtime",
  703 
  704    "* Character sets:",
  705    "charset", "local_charset",
  706 
  707    "* Acquiring source and target drive:",
  708    "dev", "indev", "outdev",
  709 
  710    "* Drive and media related inquiry actions (2):",
  711    "list_profiles", "list_formats", "list_speeds",
  712    "toc", "toc_of", "pvd_info", "report_system_area", "report_el_torito",
  713 
  714    "* Settings for file insertion:",
  715    "file_name_limit", "file_size_limit",
  716    "not_mgt", "not_paths", "not_leaf", "not_list",
  717    "quoted_not_list", "follow", "pathspecs", "overwrite", "split_size",
  718 
  719    "* Navigation in ISO image and disk filesystem (1):",
  720    "cd", "cdx", "pwd", "pwdx",
  721 
  722    "* Inserting files into ISO image:",
  723    "disk_pattern", "add_plainly",
  724    "mkdir", "lns", "add", "path_list", "quoted_path_list",
  725    "map", "map_single", "map_l", "update", "update_r",
  726    "update_l", "update_li", "update_lx", "update_lxi",
  727    "cut_out", "cpr", 
  728    "clone", "cp_clone",
  729 
  730    "* Navigation in ISO image and disk filesystem (2):",
  731    "ls", "lsd", "lsl", "lsdl", "lsx", "lsdx", "lslx", "lsdlx",
  732    "getfacl", "getfacl_r", "getfattr", "getfattr_r", "du", "dus",
  733    "dux", "dusx", "findx",
  734    "compare", "compare_r", "compare_l", "show_stream", "show_stream_r",
  735 
  736    "* File manipulations:",
  737    "iso_rr_pattern",
  738    "rm", "rm_r", "rmdir", "move", "mv",
  739    "chown", "chown_r", "chgrp", "chgrp_r", "chmod", "chmod_r", "setfacl",
  740    "setfacl_r", "setfacl_list", "setfattr", "setfattr_r", "setfattr_list",
  741    "alter_date", "alter_date_r", "hide",
  742 
  743    "* Filters for data file content:",
  744    "external_filter", "unregister_filter", "close_filter_list",
  745    "set_filter", "set_filter_r", 
  746 
  747    "* Tree traversal command -find:",
  748    "find",
  749 
  750    "* osirrox ISO-to-disk restore options:",
  751    "osirrox", "extract", "extract_single", "extract_l", "extract_cut",
  752    "extract_boot_images",
  753    "cpx", "cpax", "cp_rx", "cp_rax", "paste_in", "concat",
  754    "mount",
  755 
  756    "* Settings for result writing:",
  757    "rockridge", "joliet", "hfsplus","compliance", "rr_reloc_dir",
  758    "volid", "volset_id", "publisher",
  759    "application_id", "system_id", "volume_date", "copyright_file",
  760    "abstract_file", "biblio_file", "preparer_id", "application_use",
  761    "out_charset", "read_mkisofsrc",
  762    "uid", "gid", "zisofs", "speed", "stream_recording", "dvd_obs",
  763    "modesty_on_drive", "use_immed_bit",
  764    "stdio_sync", "dummy", "fs", "close", "padding", "write_type",
  765    "grow_blindly", "pacifier", "scdbackup_tag",
  766 
  767    "* Bootable ISO images:",
  768    "boot_image", "append_partition",
  769 
  770    "* Jigdo Template Extraction:",
  771    "jigdo",
  772 
  773    "* Command compatibility emulations:",
  774    "as",
  775 
  776    "* Scripting, dialog and program control features (2):",
  777    "history", "status_history_max", "status",
  778 
  779    "* Drive and media related inquiry actions (3):",
  780    "print_size", "tell_media_space",
  781 
  782    "* Writing the result, drive control:",
  783    "format", "blank", "truncate_overwritable", "close_damaged",
  784    "rollback", "changes_pending", "commit", "commit_eject",
  785    "eject",
  786 
  787    "* Evaluation of readability and recovery:",
  788    "check_media_defaults", "check_media", "check_md5", "check_md5_r",
  789 
  790    "* Support for frontend programs via stdin and stdout (2):",
  791    "pkt_output", "logfile", "mark", "msg_op",
  792 
  793    "* Dialog mode control:",
  794    "dialog", "page", "use_readline", "reassure",
  795 
  796    "* Support for frontend programs via stdin and stdout (3):",
  797    "launch_frontend", "named_pipe_loop",
  798 
  799    "* Scripting, dialog and program control features (3):",
  800    "rollback_end", "end",
  801 
  802    ""
  803  };
  804 
  805  if(flag & 1) {
  806    for(i= 0; commands[i][0] !=0; i++) {
  807      if(commands[i][0] == '*')
  808        sprintf(xorriso->result_line, "#%s\n", commands[i] + 1);
  809      else
  810        sprintf(xorriso->result_line, "-%s\n", commands[i]);
  811      Xorriso_result(xorriso, 0);
  812    }
  813    ret= 1; goto ex;
  814  }
  815  if(argc <= 0)
  816    {ret= -1; goto ex;}
  817 
  818  Xorriso_alloc_meM(cmd_data, char, cmd_data_size);
  819  ret= Xorriso_normalize_command(xorriso, argv[idx], -1,
  820                                 cmd_data, cmd_data_size, &cmd, 0);
  821  if(ret < 0)
  822    goto ex;
  823 
  824  if(cmd[0] == '#' || cmd[0] == 0 ||
  825     strcmp(cmd, xorriso->list_delimiter) == 0) {
  826    /* Move to end: comment line , empty option , orphaned list delimiter */
  827    ret= 0x7fffffff; goto ex;
  828  }
  829  for(i= 0; commands[i][0] !=0; i++) {
  830    if(commands[i][0] == '*') /* headline in command list */
  831  continue;
  832    if(strcmp(commands[i], cmd) != 0)
  833  continue;
  834    ret= i + 1; goto ex;
  835  }
  836 
  837  ret= 1;
  838 ex:
  839  Xorriso_free_meM(cmd_data);
  840  return(ret);
  841 }
  842 
  843 
  844 int Xorriso__cmp_cmd_rank(const void *a, const void *b)
  845 {
  846  int ra, rb;
  847 
  848  ra= ((int *) a)[1];
  849  rb= ((int *) b)[1];
  850  if(ra < rb)
  851    return(-1);
  852  if(ra > rb)
  853    return(1);
  854  ra= ((int *) a)[2];
  855  rb= ((int *) b)[2];
  856  if(ra < rb)
  857    return(-1);
  858  if(ra > rb)
  859    return(1);
  860  return(0);
  861 }
  862 
  863 
  864 /* @param flag bit0= print command sequence rather than executing it
  865                bit1= these are command line arguments
  866                      (for xorriso->argument_emulation)
  867 */
  868 int Xorriso_exec_args_sorted(struct XorrisO *xorriso,
  869                              int argc, char **argv, int *idx, int flag)
  870 {
  871  int cmd_count= 0, ret, i, arg_count, *idx_rank= NULL, cmd_idx;
  872 
  873  /* Count commands and allocate index-rank array */
  874  for(i= *idx; i < argc; i++) {
  875    ret= Xorriso_count_args(xorriso, argc - i, argv + i, &arg_count, 1);
  876    if(ret <= 0)
  877      goto ex;
  878    if(ret != 1)
  879  continue;
  880    cmd_count++;
  881    i+= arg_count;
  882  }
  883  if(cmd_count <= 0)
  884    {ret= 1; goto ex;}
  885  Xorriso_alloc_meM(idx_rank, int, 3 * cmd_count);
  886 
  887  /* Fill index-rank array and sort */
  888  cmd_count= 0;
  889  for(i= *idx; i < argc; i++) {
  890    ret= Xorriso_count_args(xorriso, argc - i, argv + i, &arg_count, 1);
  891    if(ret <= 0)
  892      goto ex;
  893    if(ret != 1)
  894  continue;
  895    idx_rank[3 * cmd_count]= i;
  896    ret= Xorriso_cmd_sorting_rank(xorriso, argc, argv, i, 0);
  897    if(ret < 0)
  898      goto ex;
  899    idx_rank[3 * cmd_count + 1]= ret;
  900    idx_rank[3 * cmd_count + 2]= cmd_count;
  901    cmd_count++;
  902    i+= arg_count;
  903  }
  904  qsort(idx_rank, cmd_count, 3 * sizeof(int), Xorriso__cmp_cmd_rank);
  905 
  906  /* Execute or print indice from index-rank array */
  907  if(flag & 1) {
  908    sprintf(xorriso->result_line,
  909            "Automatically determined command sequence:\n");
  910    Xorriso_result(xorriso, 0);
  911    xorriso->result_line[0]= 0;
  912  }
  913  for(i= 0; i < cmd_count; i++) {
  914    cmd_idx= idx_rank[3 * i];
  915    if(flag & 1) {
  916      if(strlen(xorriso->result_line) + 1 + strlen(argv[cmd_idx]) > 78) {
  917        strcat(xorriso->result_line, "\n");
  918        Xorriso_result(xorriso, 0);
  919        xorriso->result_line[0]= 0;
  920      }
  921      sprintf(xorriso->result_line + strlen(xorriso->result_line),
  922              " %s", argv[cmd_idx]);
  923    } else {
  924      ret= Xorriso_interpreter(xorriso, argc, argv, &cmd_idx, 4 | (flag & 2));
  925      if(ret <= 0 || ret == 3)
  926        goto ex;
  927    }
  928  }
  929  if(flag & 1) {
  930    if(strlen(xorriso->result_line) > 0) {
  931      strcat(xorriso->result_line, "\n");
  932      Xorriso_result(xorriso, 0);
  933    }
  934  } else
  935    *idx= argc;
  936  ret= 1;
  937 ex:
  938  Xorriso_free_meM(idx_rank); 
  939  return(ret);
  940 }
  941 
  942 
  943 /* @param flag bit0= recursion
  944                bit1= these are command line arguments
  945                      (for xorriso->argument_emulation)
  946                bit2= Only execute the one command argv[*idx] and advance 
  947                      *idx to the next command if successful. Then return.
  948 */
  949 int Xorriso_interpreter(struct XorrisO *xorriso,
  950                         int argc, char **argv, int *idx, int flag)
  951 /*
  952 return:
  953  <=0 error , 1 = success , 2 = problem event ignored , 3 = end program run
  954 */
  955 {
  956  int ret, was_dashed, end_ret, num1, num2, cmd_data_size= 2 * SfileadrL;
  957  int mem_idx, arg_count, i;
  958  char *cmd, *original_cmd, *cmd_data= NULL, *arg1, *arg2, *arg3, *arg4;
  959  
  960  Xorriso_alloc_meM(cmd_data, char, cmd_data_size);
  961 
  962  if(xorriso==NULL)
  963    {ret= 0; goto ex;}
  964  if(xorriso->is_dialog) {
  965    xorriso->result_line_counter= xorriso->result_page_counter= 0;
  966    if(xorriso->result_page_length<0)
  967      xorriso->result_page_length= -xorriso->result_page_length;
  968  }
  969 
  970 next_command:;
  971  if(flag&2) {
  972    ret= 1;
  973    if(xorriso->argument_emulation==1)
  974      ret= Xorriso_as_genisofs(xorriso, argc, argv, idx, 0);
  975    else if(xorriso->argument_emulation==2)
  976      ret= Xorriso_as_cdrskin(xorriso, argc, argv, idx, 0);
  977    if(xorriso->argument_emulation>0) {
  978      xorriso->argument_emulation= 0;
  979      if(ret<=0)
  980        goto eval_any_problems;
  981      if((*idx)>=argc)
  982        {ret= 1; goto ex;}
  983    }
  984    if((xorriso->arrange_args || (flag & 8)) && !(flag & (4 | 16))) {
  985      ret= Xorriso_exec_args_sorted(xorriso, argc, argv, idx, 0);
  986      goto ex;
  987    } 
  988  }
  989 
  990  ret= Xorriso_count_args(xorriso, argc - *idx, argv + *idx, &arg_count, 1);
  991  if((ret == 1 || ret == 2) &&
  992     strcmp(argv[*idx], xorriso->list_delimiter) != 0) {
  993    sprintf(xorriso->info_text, "Command:    %s", argv[*idx]);
  994    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
  995    for(i= 1; i <= arg_count && *idx + i < argc; i++) {
  996      sprintf(xorriso->info_text, "Parameter:     %s", argv[*idx + i]);
  997      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
  998    }
  999    if(*idx + arg_count >= argc) {
 1000      sprintf(xorriso->info_text, "Missing arguments: %d",
 1001              *idx + arg_count + 1 - argc);
 1002      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
 1003    }
 1004  }
 1005 
 1006  xorriso->prepended_wd= 0;
 1007  xorriso->request_to_abort= xorriso->request_not_to_ask= 0;
 1008  Xorriso_set_problem_status(xorriso, "", 0);
 1009  if((*idx)<argc)
 1010    original_cmd= cmd= argv[*idx];
 1011  else
 1012    original_cmd= cmd= "";
 1013  if(xorriso->add_plainly==3 && cmd[0] && !xorriso->is_dialog) {
 1014    (*idx)++;
 1015    goto add_plain_argument;
 1016  }
 1017  was_dashed= 0;
 1018  ret= Xorriso_normalize_command(xorriso, original_cmd, -1,
 1019                                 cmd_data, cmd_data_size, &cmd, 0);
 1020  if(ret<0)
 1021    goto eval_any_problems;
 1022  was_dashed= ret;
 1023 
 1024  (*idx)++;
 1025  if((*idx)<argc)
 1026    arg1= argv[(*idx)];
 1027  else
 1028    arg1= "";
 1029  if((*idx)+1<argc)
 1030    arg2= argv[(*idx)+1];
 1031  else
 1032    arg2= "";
 1033  if((*idx) + 2 < argc)
 1034    arg3= argv[(*idx) + 2];
 1035  else
 1036    arg3= "";
 1037 
 1038  ret= 1;
 1039  if(cmd[0]=='#' || cmd[0]==0) {
 1040    /* ignore comment line and empty option */; 
 1041 
 1042  } else if(strcmp(cmd,"abort_on")==0) {
 1043    (*idx)++;
 1044    ret= Xorriso_option_abort_on(xorriso, arg1, 0);
 1045 
 1046  } else if(strcmp(cmd,"abstract_file")==0) { 
 1047    (*idx)++;
 1048    Xorriso_option_abstract_file(xorriso, arg1, 0);
 1049 
 1050  } else if(strcmp(cmd,"acl")==0) {
 1051    (*idx)++;
 1052    ret= Xorriso_option_acl(xorriso, arg1, 0);
 1053 
 1054  } else if(strcmp(cmd,"add")==0) {
 1055    ret= Xorriso_option_add(xorriso, argc, argv, idx, 0);
 1056 
 1057  } else if(strcmp(cmd,"add_plainly")==0) {
 1058    (*idx)++;
 1059    ret= Xorriso_option_add_plainly(xorriso, arg1, 0);
 1060 
 1061  } else if(strcmp(cmd,"alter_date")==0 || strcmp(cmd,"alter_date_r")==0) {
 1062    (*idx)+= 2;
 1063    ret= Xorriso_option_alter_date(xorriso, arg1, arg2, argc, argv, idx,
 1064                                   strlen(cmd)>10);
 1065 
 1066  } else if(strcmp(cmd,"append_partition")==0) {
 1067    (*idx)+= 3;
 1068    ret= Xorriso_option_append_partition(xorriso, arg1, arg2, arg3, 0);
 1069 
 1070  } else if(strcmp(cmd,"application_id")==0) {
 1071    (*idx)++;
 1072    ret= Xorriso_option_application_id(xorriso, arg1, 0);
 1073 
 1074  } else if(strcmp(cmd,"application_use") == 0) {
 1075    (*idx)++;
 1076    ret= Xorriso_option_application_use(xorriso, arg1, 0);
 1077 
 1078  } else if(strcmp(cmd,"as")==0) {
 1079    ret= Xorriso_option_as(xorriso, argc, argv, idx, 0);
 1080 
 1081  } else if(strcmp(cmd,"assert_volid")==0) {
 1082    (*idx)+= 2;
 1083    ret= Xorriso_option_assert_volid(xorriso, arg1, arg2, 0);
 1084 
 1085  } else if(strcmp(cmd,"auto_charset")==0) {
 1086    (*idx)++;
 1087    ret= Xorriso_option_auto_charset(xorriso, arg1, 0);
 1088 
 1089  } else if(strcmp(cmd,"backslash_codes")==0) {
 1090    (*idx)++;
 1091    ret= Xorriso_option_backslash_codes(xorriso, arg1, 0);
 1092 
 1093  } else if(strcmp(cmd,"ban_stdio_write")==0) {
 1094    ret= Xorriso_option_ban_stdio_write(xorriso, 0);
 1095 
 1096  } else if(strcmp(cmd,"biblio_file")==0) { 
 1097    (*idx)++;
 1098    Xorriso_option_biblio_file(xorriso, arg1, 0);
 1099 
 1100  } else if(strcmp(cmd,"blank")==0) {
 1101    (*idx)++;
 1102    ret= Xorriso_option_blank(xorriso, arg1, 0);
 1103 
 1104  } else if(strcmp(cmd,"boot_image")==0) {
 1105    (*idx)+= 2;
 1106    ret= Xorriso_option_boot_image(xorriso, arg1, arg2, 0);
 1107 
 1108  } else if(strcmp(cmd,"calm_drive")==0) {
 1109    (*idx)++;
 1110    ret= Xorriso_option_calm_drive(xorriso, arg1, 0);
 1111 
 1112  } else if(strcmp(cmd,"cd")==0 || strcmp(cmd,"cdi")==0) {
 1113    (*idx)++;
 1114    ret= Xorriso_option_cdi(xorriso, arg1, 0);
 1115 
 1116  } else if(strcmp(cmd,"cdx")==0) {
 1117    (*idx)++;
 1118    ret= Xorriso_option_cdx(xorriso, arg1, 0);
 1119 
 1120  } else if(strcmp(cmd, "changes_pending")==0) {
 1121    (*idx)++;
 1122    ret= Xorriso_option_changes_pending(xorriso, arg1, 0);
 1123 
 1124  } else if(strcmp(cmd,"charset")==0) {
 1125    (*idx)++;
 1126    ret= Xorriso_option_charset(xorriso, arg1, 3);
 1127 
 1128  } else if(strcmp(cmd,"check_md5")==0) {
 1129    ret= Xorriso_option_check_md5(xorriso, argc, argv, idx, 0);
 1130 
 1131  } else if(strcmp(cmd,"check_md5_r")==0) {
 1132    ret= Xorriso_option_check_md5(xorriso, argc, argv, idx, 8);
 1133 
 1134  } else if(strcmp(cmd,"check_media")==0) {
 1135    ret= Xorriso_option_check_media(xorriso, argc, argv, idx, 0);
 1136 
 1137  } else if(strcmp(cmd,"check_media_defaults")==0) {
 1138    ret= Xorriso_option_check_media_defaults(xorriso, argc, argv, idx, 0);
 1139 
 1140  } else if(strcmp(cmd,"chgrp")==0 || strcmp(cmd,"chgrpi")==0) {
 1141    (*idx)+= 1;
 1142    ret= Xorriso_option_chgrpi(xorriso, arg1, argc, argv, idx, 0);   
 1143 
 1144  } else if(strcmp(cmd,"chgrp_r")==0 || strcmp(cmd,"chgrp_ri")==0) {
 1145    (*idx)+= 1;
 1146    ret= Xorriso_option_chgrpi(xorriso, arg1, argc, argv, idx, 1);   
 1147 
 1148  } else if(strcmp(cmd,"chmod")==0 || strcmp(cmd,"chmodi")==0) {
 1149    (*idx)+= 1;
 1150    ret= Xorriso_option_chmodi(xorriso, arg1, argc, argv, idx, 0);   
 1151 
 1152  } else if(strcmp(cmd,"chmod_r")==0 || strcmp(cmd,"chmod_ri")==0) {
 1153    (*idx)+= 1;
 1154    ret= Xorriso_option_chmodi(xorriso, arg1, argc, argv, idx, 1);   
 1155 
 1156  } else if(strcmp(cmd,"chown_r")==0 || strcmp(cmd,"chown_ri")==0) {
 1157    (*idx)+= 1;
 1158    ret= Xorriso_option_chowni(xorriso, arg1, argc, argv, idx, 1);   
 1159 
 1160  } else if(strcmp(cmd,"chown")==0 || strcmp(cmd,"chowni")==0) {
 1161    (*idx)+= 1;
 1162    ret= Xorriso_option_chowni(xorriso, arg1, argc, argv, idx, 0);   
 1163 
 1164  } else if(strcmp(cmd,"clone")==0) {
 1165    (*idx)+= 2;
 1166    ret= Xorriso_option_clone(xorriso, arg1, arg2, 1);
 1167 
 1168  } else if(strcmp(cmd,"close")==0) {
 1169    (*idx)++;
 1170    ret= Xorriso_option_close(xorriso, arg1, 0);
 1171 
 1172  } else if(strcmp(cmd,"close_damaged")==0) {
 1173    (*idx)++;
 1174    ret= Xorriso_option_close_damaged(xorriso, arg1, 0);
 1175 
 1176  } else if(strcmp(cmd,"close_filter_list")==0) {
 1177    ret= Xorriso_option_close_filter_list(xorriso, 0);
 1178 
 1179  } else if(strcmp(cmd,"commit")==0) {
 1180    ret= Xorriso_option_commit(xorriso, 0);
 1181 
 1182  } else if(strcmp(cmd,"commit_eject")==0) {
 1183    (*idx)++;
 1184    ret= Xorriso_option_commit_eject(xorriso, arg1, 0);
 1185 
 1186  } else if(strcmp(cmd,"compare")==0) {
 1187    (*idx)+= 2;
 1188    ret= Xorriso_option_compare(xorriso, arg1, arg2, 1);
 1189 
 1190  } else if(strcmp(cmd,"compare_l")==0) {
 1191    ret= Xorriso_option_map_l(xorriso, argc, argv, idx, 1<<8);
 1192 
 1193  } else if(strcmp(cmd,"compare_r")==0) {
 1194    (*idx)+= 2;
 1195    ret= Xorriso_option_compare(xorriso, arg1, arg2, 1|8);
 1196 
 1197  } else if(strcmp(cmd,"compliance")==0) {
 1198    (*idx)++;
 1199    Xorriso_option_compliance(xorriso, arg1, 0);
 1200 
 1201  } else if(strcmp(cmd,"concat") == 0) {
 1202    ret= Xorriso_option_concat(xorriso, argc, argv, idx, 0);
 1203 
 1204  } else if(strcmp(cmd,"copyright_file")==0) { 
 1205    (*idx)++;
 1206    Xorriso_option_copyright_file(xorriso, arg1, 0);
 1207 
 1208  } else if(strcmp(cmd,"cp_clone") == 0) {
 1209    ret= Xorriso_option_cp_clone(xorriso, argc, argv, idx, 0);
 1210 
 1211  } else if(strcmp(cmd,"cp_rx")==0 || strcmp(cmd,"cp_rax")==0) {
 1212    ret= Xorriso_option_cpx(xorriso, argc, argv, idx,
 1213                            1|((strcmp(cmd,"cp_rax")==0)<<1));
 1214 
 1215  } else if(strcmp(cmd,"cpr")==0 || strcmp(cmd,"cpri")==0) {
 1216    ret= Xorriso_option_cpri(xorriso, argc, argv, idx, 0);
 1217 
 1218  } else if(strcmp(cmd,"cpx")==0 || strcmp(cmd,"cpax")==0) {
 1219    ret= Xorriso_option_cpx(xorriso, argc, argv, idx,
 1220                            (strcmp(cmd,"cpax")==0)<<1);
 1221 
 1222  } else if(strcmp(cmd,"cut_out")==0) {
 1223    (*idx)+= 4;
 1224    if((*idx)>argc) {
 1225      sprintf(xorriso->info_text,
 1226             "-cut_out: Not enough arguments. Needed are: disk_path start count so_rr_path");
 1227      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
 1228      ret= 0;
 1229    } else
 1230      ret= Xorriso_option_cut_out(xorriso, arg1, arg2,
 1231                                  argv[(*idx)-2], argv[(*idx)-1], 0);
 1232 
 1233  } else if(strcmp(cmd,"data_cache_size")==0) {
 1234    (*idx)+= 2;
 1235    ret= Xorriso_option_data_cache_size(xorriso, arg1, arg2, 0);
 1236 
 1237  } else if(strcmp(cmd,"dev")==0) {
 1238    (*idx)++;
 1239    ret= Xorriso_option_dev(xorriso, arg1, 3);
 1240 
 1241  } else if(strcmp(cmd,"device_links")==0) {
 1242    ret= Xorriso_option_devices(xorriso, 1);
 1243 
 1244  } else if(strcmp(cmd,"devices")==0) {
 1245    ret= Xorriso_option_devices(xorriso, 0);
 1246 
 1247  } else if(strcmp(cmd,"dialog")==0) {
 1248    (*idx)++;
 1249    ret= Xorriso_option_dialog(xorriso, arg1, 0);
 1250 
 1251  } else if(strcmp(cmd,"disk_dev_ino")==0) {
 1252    (*idx)++;
 1253    ret= Xorriso_option_disk_dev_ino(xorriso, arg1, 0);
 1254 
 1255  } else if(strcmp(cmd,"displacement")==0) {
 1256    (*idx)++;
 1257    ret= Xorriso_option_displacement(xorriso, arg1, 0);
 1258 
 1259  } else if(strcmp(cmd,"disk_pattern")==0) {
 1260    (*idx)++;
 1261    ret= Xorriso_option_disk_pattern(xorriso, arg1, 0);
 1262 
 1263  } else if(strcmp(cmd,"drive_access")==0) {
 1264    (*idx)++;
 1265    ret= Xorriso_option_drive_access(xorriso, arg1, 0);
 1266 
 1267  } else if(strcmp(cmd,"drive_class")==0) {
 1268    (*idx)+= 2;
 1269    ret= Xorriso_option_drive_class(xorriso, arg1, arg2, 0);
 1270 
 1271  } else if(strcmp(cmd,"du")==0   || strcmp(cmd,"dui")==0 ||
 1272            strcmp(cmd,"dus")==0 || strcmp(cmd,"dusi")==0) {
 1273    ret= Xorriso_option_lsi(xorriso, argc, argv, idx, (cmd[2]!='s')|4);
 1274 
 1275  } else if(strcmp(cmd,"dummy")==0) {
 1276    (*idx)++;
 1277    ret= Xorriso_option_dummy(xorriso, arg1, 0);
 1278 
 1279  } else if(strcmp(cmd,"dvd_obs")==0) {
 1280    (*idx)++;
 1281    ret= Xorriso_option_dvd_obs(xorriso, arg1, 0);
 1282 
 1283  } else if(strcmp(cmd,"dux")==0 || strcmp(cmd,"dusx")==0) {
 1284    ret= Xorriso_option_lsx(xorriso, argc, argv, idx, (cmd[2]!='s')|4);
 1285 
 1286  } else if(strcmp(cmd,"early_stdio_test")==0) {
 1287    (*idx)++;
 1288    ret= Xorriso_option_early_stdio_test(xorriso, arg1, 0);
 1289 
 1290  } else if(strcmp(cmd,"ecma119_map")==0) {
 1291    (*idx)++;
 1292    ret= Xorriso_option_ecma119_map(xorriso, arg1, 0);
 1293 
 1294  } else if(strcmp(cmd,"eject")==0) {
 1295    (*idx)++;
 1296    ret= Xorriso_option_eject(xorriso, arg1, 0);
 1297 
 1298  } else if(strcmp(cmd,"end")==0) {
 1299    end_ret= Xorriso_option_end(xorriso, 0);
 1300    ret= Xorriso_eval_problem_status(xorriso, ret, 0);
 1301    if(ret<0)
 1302      goto ex;
 1303    if(end_ret!=2)
 1304      {ret= 3; goto ex;}
 1305 
 1306  } else if(strcmp(cmd,"errfile_log")==0) {
 1307    (*idx)+= 2;
 1308     ret= Xorriso_option_errfile_log(xorriso, arg1, arg2, 0);
 1309 
 1310  } else if(strcmp(cmd,"error_behavior")==0) {
 1311    (*idx)+= 2;
 1312    ret= Xorriso_option_error_behavior(xorriso, arg1, arg2, 0);
 1313 
 1314  } else if(strcmp(cmd,"external_filter")==0) {
 1315    ret= Xorriso_option_external_filter(xorriso, argc, argv, idx, 0);
 1316 
 1317  } else if(strcmp(cmd,"extract")==0) {
 1318    (*idx)+= 2;
 1319    ret= Xorriso_option_extract(xorriso, arg1, arg2, 0);
 1320 
 1321  } else if(strcmp(cmd,"extract_boot_images")==0) {
 1322    (*idx)+= 1;
 1323    if((*idx)>argc) {
 1324      sprintf(xorriso->info_text,
 1325             "-extract_boot_images: Empty disk_path cannot be used as target directory");
 1326      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
 1327      ret= 0;
 1328    } else {
 1329      ret= Xorriso_option_extract_boot_images(xorriso, arg1, 0);
 1330    }
 1331 
 1332  } else if(strcmp(cmd,"extract_cut")==0) {
 1333    (*idx)+= 4;
 1334    if((*idx)>argc) {
 1335      sprintf(xorriso->info_text,
 1336             "-extract_cut: Not enough arguments. Needed are: disk_path start count iso_rr_path");
 1337      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
 1338      ret= 0;
 1339    } else
 1340      ret= Xorriso_option_extract_cut(xorriso, arg1, arg2,
 1341                                      argv[(*idx)-2], argv[(*idx)-1], 0);
 1342 
 1343  } else if(strcmp(cmd,"extract_l")==0) {
 1344    ret= Xorriso_option_map_l(xorriso, argc, argv, idx, 3<<8);
 1345 
 1346  } else if(strcmp(cmd,"extract_single")==0) {
 1347    (*idx)+= 2;
 1348    ret= Xorriso_option_extract(xorriso, arg1, arg2, 32);
 1349 
 1350  } else if(strcmp(cmd,"file_name_limit")==0) {
 1351    (*idx)++;
 1352    ret= Xorriso_option_file_name_limit(xorriso, arg1, 0);
 1353 
 1354  } else if(strcmp(cmd,"file_size_limit")==0) {
 1355    ret= Xorriso_option_file_size_limit(xorriso, argc, argv, idx, 0);
 1356 
 1357  } else if(strcmp(cmd,"find")==0 || strcmp(cmd,"findi")==0) {
 1358    ret= Xorriso_option_find(xorriso, argc, argv, idx, 0);
 1359 
 1360  } else if(strcmp(cmd,"findx")==0) {
 1361    ret= Xorriso_option_find(xorriso, argc, argv, idx, 1);
 1362 
 1363  } else if(strcmp(cmd,"follow")==0) {
 1364    (*idx)++;
 1365    ret= Xorriso_option_follow(xorriso, arg1, 0);
 1366 
 1367  } else if(strcmp(cmd,"for_backup")==0) {
 1368    Xorriso_option_hardlinks(xorriso, "on", 0);
 1369    Xorriso_option_acl(xorriso, "on", 0);
 1370    Xorriso_option_xattr(xorriso, "any", 0);
 1371    Xorriso_option_md5(xorriso, "on", 0);
 1372    ret= 1;
 1373 
 1374  } else if(strcmp(cmd,"format")==0) {
 1375    (*idx)++;
 1376    ret= Xorriso_option_blank(xorriso, arg1, 1);
 1377 
 1378  } else if(strcmp(cmd,"fs")==0) {
 1379    (*idx)++;
 1380    ret= Xorriso_option_fs(xorriso, arg1, 0);
 1381 
 1382  } else if(strcmp(cmd,"getfacl")==0 || strcmp(cmd,"getfacli")==0) {
 1383    ret= Xorriso_option_getfacli(xorriso, argc, argv, idx, 0);   
 1384 
 1385  } else if(strcmp(cmd,"getfacl_r")==0 || strcmp(cmd,"getfacl_ri")==0) {
 1386    ret= Xorriso_option_getfacli(xorriso, argc, argv, idx, 1);   
 1387 
 1388  } else if(strcmp(cmd,"getfattr")==0 || strcmp(cmd,"getfattri")==0) {
 1389    ret= Xorriso_option_getfacli(xorriso, argc, argv, idx, 2);   
 1390 
 1391  } else if(strcmp(cmd,"getfattr_r")==0 || strcmp(cmd,"getfattr_ri")==0) {
 1392    ret= Xorriso_option_getfacli(xorriso, argc, argv, idx, 1 | 2);   
 1393 
 1394  } else if(strcmp(cmd,"gid")==0) {
 1395    (*idx)++;
 1396    ret= Xorriso_option_gid(xorriso,arg1,0);
 1397 
 1398  } else if(strcmp(cmd,"grow_blindly")==0) {
 1399    (*idx)++;
 1400    ret= Xorriso_option_grow_blindly(xorriso,arg1,0);
 1401 
 1402  } else if(strcmp(cmd,"hardlinks")==0) {
 1403    (*idx)++;
 1404    ret= Xorriso_option_hardlinks(xorriso, arg1, 0);
 1405 
 1406  } else if(strcmp(cmd,"hfsplus")==0) {
 1407    (*idx)++;
 1408    ret= Xorriso_option_hfsplus(xorriso, arg1, 0);
 1409 
 1410  } else if(strcmp(cmd,"help")==0) {
 1411    Xorriso_option_help(xorriso,0);
 1412 
 1413  } else if(strcmp(cmd,"hide")==0) {
 1414    (*idx)+= 1;
 1415    ret= Xorriso_option_hide(xorriso, arg1, argc, argv, idx, 1);   
 1416 
 1417  } else if(strcmp(cmd,"history")==0) {
 1418    /* add to readline history */
 1419    (*idx)++;
 1420    ret= Xorriso_option_history(xorriso, arg1, 0);
 1421 
 1422  } else if(strcmp(cmd,"indev")==0) {
 1423    (*idx)++;
 1424    ret= Xorriso_option_dev(xorriso, arg1, 1);
 1425 
 1426  } else if(strcmp(cmd,"in_charset")==0) {
 1427    (*idx)++;
 1428    ret= Xorriso_option_charset(xorriso, arg1, 1);
 1429 
 1430  } else if(strcmp(cmd,"iso_nowtime")==0) {
 1431    (*idx)++;
 1432    ret= Xorriso_option_iso_nowtime(xorriso, arg1, 0);
 1433 
 1434  } else if(strcmp(cmd,"iso_rr_pattern")==0) {
 1435    (*idx)++;
 1436    ret= Xorriso_option_iso_rr_pattern(xorriso, arg1, 0);
 1437 
 1438  } else if(strcmp(cmd,"jigdo")==0) {
 1439    (*idx)+= 2;
 1440    ret= Xorriso_option_jigdo(xorriso, arg1, arg2, 0);
 1441 
 1442  } else if(strcmp(cmd,"joliet")==0) {
 1443    (*idx)++;
 1444    ret= Xorriso_option_joliet(xorriso, arg1, 0);
 1445 
 1446  } else if(strcmp(cmd,"joliet_map")==0) {
 1447    (*idx)++;
 1448    ret= Xorriso_option_joliet_map(xorriso, arg1, 0);
 1449 
 1450  } else if(strcmp(cmd, "launch_frontend") == 0) {
 1451    ret= Xorriso_option_launch_frontend(xorriso, argc, argv, idx, 0);
 1452 
 1453  } else if(strcmp(cmd, "list_arg_sorting") == 0) {
 1454    ret= Xorriso_option_list_arg_sorting(xorriso, 0);
 1455 
 1456  } else if(strcmp(cmd, "list_delimiter") == 0) {
 1457    (*idx)++;
 1458    ret= Xorriso_option_list_delimiter(xorriso, arg1, 0);
 1459 
 1460  } else if(strcmp(cmd, "list_extras") == 0) {
 1461    (*idx)++;
 1462    ret= Xorriso_option_list_extras(xorriso, arg1, 0);
 1463 
 1464  } else if(strcmp(cmd,"list_formats")==0) {
 1465    ret= Xorriso_option_list_formats(xorriso, 0);
 1466 
 1467  } else if(strcmp(cmd,"list_profiles")==0) {
 1468    (*idx)++;
 1469    ret= Xorriso_option_list_profiles(xorriso, arg1, 0);
 1470 
 1471  } else if(strcmp(cmd,"list_speeds")==0) {
 1472    ret= Xorriso_option_list_speeds(xorriso, 0);
 1473 
 1474  } else if(strcmp(cmd, "lns") == 0 || strcmp(cmd, "lnsi") == 0) {
 1475    (*idx)+= 2;
 1476    ret= Xorriso_option_lnsi(xorriso, arg1, arg2, 0);
 1477 
 1478  } else if(strcmp(cmd,"load")==0) {
 1479    (*idx)+= 2;
 1480    ret= Xorriso_option_load(xorriso, arg1, arg2, 0);
 1481    
 1482  } else if(strcmp(cmd,"local_charset")==0) {
 1483    (*idx)++;
 1484    ret= Xorriso_option_charset(xorriso, arg1, 4);
 1485 
 1486  } else if(strcmp(cmd,"logfile")==0) {
 1487    (*idx)+= 2;
 1488    ret= Xorriso_option_logfile(xorriso, arg1, arg2, 0);
 1489    
 1490  } else if(strcmp(cmd,"ls")==0 || strcmp(cmd,"lsi")==0 ||
 1491            strcmp(cmd,"lsl")==0 || strcmp(cmd,"lsli")==0) {
 1492    ret= Xorriso_option_lsi(xorriso, argc, argv, idx, (cmd[2]=='l'));
 1493 
 1494  } else if(strcmp(cmd,"lsd")==0 || strcmp(cmd,"lsdi")==0 ||
 1495            strcmp(cmd,"lsdl")==0 || strcmp(cmd,"lsdli")==0) {
 1496    ret= Xorriso_option_lsi(xorriso, argc, argv, idx, (cmd[3]=='l')|8);
 1497 
 1498  } else if(strcmp(cmd,"lsdx")==0 || strcmp(cmd,"lsdlx")==0) {
 1499    ret= Xorriso_option_lsx(xorriso, argc, argv, idx, (cmd[3]=='l')|8);
 1500 
 1501  } else if(strcmp(cmd,"lsx")==0 || strcmp(cmd,"lslx")==0) {
 1502    ret= Xorriso_option_lsx(xorriso, argc, argv, idx, (cmd[2]=='l'));
 1503 
 1504  } else if(strcmp(cmd,"map")==0) {
 1505    (*idx)+= 2;
 1506    ret= Xorriso_option_map(xorriso, arg1, arg2, 0);
 1507 
 1508  } else if(strcmp(cmd,"map_l")==0) {
 1509    ret= Xorriso_option_map_l(xorriso, argc, argv, idx, 0);
 1510 
 1511  } else if(strcmp(cmd,"map_single")==0) {
 1512    (*idx)+= 2;
 1513    ret= Xorriso_option_map(xorriso, arg1, arg2, 32);
 1514 
 1515  } else if(strcmp(cmd,"mark")==0) {
 1516    (*idx)++;
 1517    ret= Xorriso_option_mark(xorriso, arg1, 0);
 1518 
 1519  } else if(strcmp(cmd, "md5")==0) {
 1520    (*idx)++;
 1521    ret= Xorriso_option_md5(xorriso, arg1, 0);
 1522 
 1523  } else if(strcmp(cmd,"mkdir")==0 || strcmp(cmd,"mkdiri")==0) {
 1524    ret= Xorriso_option_mkdiri(xorriso, argc, argv, idx, 0);
 1525 
 1526  } else if(strcmp(cmd, "modesty_on_drive")==0) {
 1527    (*idx)++;
 1528    ret= Xorriso_option_modesty_on_drive(xorriso, arg1, 0);
 1529 
 1530  } else if(strcmp(cmd, "mount") == 0 || strcmp(cmd, "mount_cmd") == 0) {
 1531    (*idx)+= 4;
 1532    if((*idx)>argc) {
 1533      sprintf(xorriso->info_text,
 1534          "-%s: Not enough arguments. Needed are: device entity id command",
 1535          cmd);
 1536      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
 1537      ret= 0;
 1538    } else
 1539      ret= Xorriso_option_mount(xorriso, arg1, arg2,
 1540                                argv[(*idx)-2], argv[(*idx)-1],
 1541                                (strcmp(cmd, "mount_cmd") == 0));
 1542 
 1543  } else if(strcmp(cmd, "mount_opts")==0) {
 1544    (*idx)++;
 1545    ret= Xorriso_option_mount_opts(xorriso, arg1, 0);
 1546 
 1547  } else if(strcmp(cmd, "move")==0) {
 1548    (*idx)+= 2;
 1549    ret= Xorriso_option_move(xorriso, arg1, arg2, 0);
 1550 
 1551  } else if(strcmp(cmd,"msg_op") == 0) {
 1552    (*idx)+= 2;
 1553    ret= Xorriso_option_msg_op(xorriso, arg1, arg2, 0);
 1554 
 1555  } else if(strcmp(cmd,"mv")==0 || strcmp(cmd,"mvi")==0) {
 1556    ret= Xorriso_option_mvi(xorriso, argc, argv, idx, 0);
 1557 
 1558  } else if(strcmp(cmd,"named_pipe_loop")==0) {
 1559    if((*idx) + 3 < argc)
 1560      arg4= argv[(*idx) + 3];
 1561    else
 1562      arg4= "";
 1563    (*idx)+= 4;
 1564    ret= Xorriso_option_named_pipe_loop(xorriso, arg1, arg2, arg3, arg4, 0);
 1565    if(ret == 3)
 1566      goto ex;
 1567 
 1568  } else if(strcmp(cmd,"no_rc")==0) {
 1569    ret= Xorriso_option_no_rc(xorriso, 0);
 1570 
 1571  } else if(strcmp(cmd,"not_leaf")==0) {
 1572    (*idx)++;
 1573    ret= Xorriso_option_not_leaf(xorriso, arg1, 0);
 1574 
 1575  } else if(strcmp(cmd,"not_list")==0) {
 1576    (*idx)++;
 1577    ret= Xorriso_option_not_list(xorriso, arg1, 0);
 1578 
 1579  } else if(strcmp(cmd,"not_mgt")==0) {
 1580    (*idx)++;
 1581    ret= Xorriso_option_not_mgt(xorriso, arg1, 0);
 1582 
 1583  } else if(strcmp(cmd,"not_paths")==0) {
 1584    ret= Xorriso_option_not_paths(xorriso, argc, argv, idx, 0);
 1585 
 1586  } else if(strcmp(cmd,"options_from_file")==0) {
 1587    (*idx)++;
 1588    ret= Xorriso_option_options_from_file(xorriso,arg1,0);
 1589    if(ret==3)
 1590      goto ex;
 1591 
 1592  } else if(strcmp(cmd,"osirrox")==0) {
 1593    (*idx)++;
 1594    ret= Xorriso_option_osirrox(xorriso,arg1,0);
 1595 
 1596  } else if(strcmp(cmd,"outdev")==0) {
 1597    (*idx)++;
 1598    ret= Xorriso_option_dev(xorriso, arg1, 2);
 1599 
 1600  } else if(strcmp(cmd,"out_charset")==0) {
 1601    (*idx)++;
 1602    ret= Xorriso_option_charset(xorriso, arg1, 2);
 1603 
 1604  } else if(strcmp(cmd,"overwrite")==0) {
 1605    (*idx)++;
 1606    ret= Xorriso_option_overwrite(xorriso,arg1,0);
 1607 
 1608  } else if(strcmp(cmd,"pacifier")==0) {
 1609    (*idx)++;
 1610    ret= Xorriso_option_pacifier(xorriso, arg1, 0);
 1611 
 1612  } else if(strcmp(cmd,"padding")==0) {
 1613    (*idx)++;
 1614    ret= Xorriso_option_padding(xorriso, arg1, 0);
 1615 
 1616  } else if(strcmp(cmd,"page")==0) {
 1617    (*idx)+= 2;
 1618    num1= num2= 0;
 1619    sscanf(arg1,"%d",&num1);
 1620    sscanf(arg2,"%d",&num2);
 1621    if(num1<0)
 1622      num1= 0;
 1623    if(arg1[0]==0)
 1624      num1= 16;
 1625    if(num2<=0)
 1626      num2= 80;
 1627    ret= Xorriso_option_page(xorriso, num1, num2, 0);
 1628 
 1629  } else if(strcmp(cmd,"paste_in")==0) {
 1630    (*idx)+= 4;
 1631    if((*idx)>argc) {
 1632      sprintf(xorriso->info_text,
 1633             "-paste_in: Not enough arguments. Needed are: disk_path start count so_rr_path");
 1634      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
 1635      ret= 0;
 1636    } else
 1637      ret= Xorriso_option_paste_in(xorriso, arg1, arg2,
 1638                                  argv[(*idx)-2], argv[(*idx)-1], 0);
 1639 
 1640  } else if(strcmp(cmd,"path-list")==0 || strcmp(cmd,"path_list")==0) {
 1641    (*idx)++;
 1642    ret= Xorriso_option_path_list(xorriso, arg1, 0);
 1643 
 1644  } else if(strcmp(cmd,"pathspecs")==0) {
 1645    (*idx)++;
 1646    ret= Xorriso_option_pathspecs(xorriso, arg1, 0);
 1647 
 1648  } else if(strcmp(cmd,"pkt_output")==0) {
 1649    (*idx)++;
 1650    ret=  Xorriso_option_pkt_output(xorriso, arg1, 0);
 1651 
 1652  } else if(strcmp(cmd,"preparer_id")==0) {
 1653    (*idx)++;
 1654    ret= Xorriso_option_preparer_id(xorriso, arg1, 0);
 1655 
 1656  } else if(strcmp(cmd,"print")==0) {
 1657    (*idx)++;
 1658    ret= Xorriso_option_print(xorriso, arg1, 0);
 1659 
 1660  } else if(strcmp(cmd,"print_info")==0) {
 1661    (*idx)++;
 1662    ret= Xorriso_option_print(xorriso, arg1, 1);
 1663 
 1664  } else if(strcmp(cmd,"print_mark")==0) {
 1665    (*idx)++;
 1666    ret= Xorriso_option_print(xorriso, arg1, 2);
 1667 
 1668  } else if(strcmp(cmd,"print_size")==0) {
 1669    Xorriso_option_print_size(xorriso, 0);
 1670 
 1671  } else if(strcmp(cmd,"prompt")==0) {
 1672    (*idx)++;
 1673    ret= Xorriso_option_prompt(xorriso, arg1, 0);
 1674 
 1675  } else if(strcmp(cmd,"prog")==0) {
 1676    (*idx)++;
 1677    ret= Xorriso_option_prog(xorriso, arg1, 0);
 1678 
 1679  } else if(strcmp(cmd,"publisher")==0) { 
 1680    (*idx)++;
 1681    Xorriso_option_publisher(xorriso, arg1, 0);
 1682 
 1683  } else if(strcmp(cmd,"pvd_info")==0) { 
 1684    Xorriso_option_pvd_info(xorriso, 0);
 1685 
 1686  } else if(strcmp(cmd,"pwd")==0 || strcmp(cmd,"pwdi")==0) {
 1687    Xorriso_option_pwdi(xorriso, 0);
 1688 
 1689  } else if(strcmp(cmd,"pwdx")==0) { 
 1690    Xorriso_option_pwdx(xorriso, 0);
 1691 
 1692  } else if(strcmp(cmd,"quoted_not_list")==0) {
 1693    (*idx)++;
 1694    ret= Xorriso_option_not_list(xorriso, arg1, 1);
 1695 
 1696  } else if(strcmp(cmd,"quoted_path_list")==0) {
 1697    (*idx)++;
 1698    ret= Xorriso_option_path_list(xorriso, arg1, 1);
 1699 
 1700  } else if(strcmp(cmd,"read_fs")==0) {
 1701    (*idx)++;
 1702    ret= Xorriso_option_read_fs(xorriso, arg1, 0);
 1703 
 1704  } else if(strcmp(cmd,"read_mkisofsrc")==0) {
 1705    ret= Xorriso_option_read_mkisofsrc(xorriso, 0);
 1706 
 1707  } else if(strcmp(cmd,"read_speed")==0) {
 1708    (*idx)++;
 1709    ret= Xorriso_option_speed(xorriso, arg1, 1);
 1710 
 1711  } else if(strcmp(cmd,"reassure")==0) {
 1712    (*idx)++;
 1713    ret= Xorriso_option_reassure(xorriso, arg1, 0);
 1714 
 1715  } else if(strcmp(cmd,"report_about")==0) {
 1716    (*idx)++;
 1717    ret= Xorriso_option_report_about(xorriso, arg1, 0);
 1718 
 1719  } else if(strcmp(cmd,"report_el_torito")==0) {
 1720    (*idx)++;
 1721    ret= Xorriso_option_report_el_torito(xorriso, arg1, 0);
 1722 
 1723  } else if(strcmp(cmd,"report_system_area")==0) {
 1724    (*idx)++;
 1725    ret= Xorriso_option_report_system_area(xorriso, arg1, 0);
 1726 
 1727  } else if(strcmp(cmd,"return_with")==0) {
 1728    (*idx)+= 2;
 1729    num2= 0;
 1730    sscanf(arg2,"%d",&num2);
 1731    ret= Xorriso_option_return_with(xorriso, arg1, num2, 0);
 1732 
 1733  } else if(strcmp(cmd,"rm")==0 || strcmp(cmd,"rmi")==0) {
 1734    ret= Xorriso_option_rmi(xorriso, argc, argv, idx, 0);
 1735 
 1736  } else if(strcmp(cmd,"rm_r")==0 || strcmp(cmd,"rm_ri")==0) {
 1737    ret= Xorriso_option_rmi(xorriso, argc, argv, idx, 1);
 1738 
 1739  } else if(strcmp(cmd,"rmdir")==0 || strcmp(cmd,"rmdiri")==0) {
 1740    ret= Xorriso_option_rmi(xorriso, argc, argv, idx, 2);
 1741 
 1742  } else if(strcmp(cmd, "rockridge") == 0) {
 1743    (*idx)++;
 1744    ret= Xorriso_option_rockridge(xorriso, arg1, 0);
 1745 
 1746  } else if(strcmp(cmd,"rollback")==0) {
 1747    ret= Xorriso_option_rollback(xorriso, 0);
 1748 
 1749  } else if(strcmp(cmd,"rollback_end")==0) {
 1750    end_ret= Xorriso_option_end(xorriso, 1);
 1751    ret= Xorriso_eval_problem_status(xorriso, ret, 0);
 1752    if(ret<0)
 1753      goto ex;
 1754    if(end_ret!=2)
 1755      {ret= 3; goto ex;}
 1756 
 1757  } else if(strcmp(cmd,"rom_toc_scan")==0) {
 1758    (*idx)++;
 1759    Xorriso_option_rom_toc_scan(xorriso, arg1, 0);
 1760 
 1761  } else if(strcmp(cmd,"rr_reloc_dir")==0) {
 1762    (*idx)++;
 1763    Xorriso_option_rr_reloc_dir(xorriso, arg1, 0);
 1764 
 1765  } else if(strcmp(cmd,"scdbackup_tag")==0) {
 1766    (*idx)+= 2;
 1767    ret= Xorriso_option_scdbackup_tag(xorriso, arg1, arg2, 0);
 1768  
 1769  } else if(strcmp(cmd, "scsi_dev_family") == 0) {
 1770    (*idx)++;
 1771    ret= Xorriso_option_scsi_dev_family(xorriso, arg1, 0);
 1772 
 1773  } else if(strcmp(cmd, "scsi_log") == 0) {
 1774    (*idx)++;
 1775    ret= Xorriso_option_scsi_log(xorriso, arg1, 0);
 1776 
 1777  } else if(strcmp(cmd,"session_log")==0) {
 1778    (*idx)++;
 1779    ret= Xorriso_option_session_log(xorriso, arg1, 0);
 1780  
 1781  } else if(strcmp(cmd, "session_string") == 0) {
 1782    (*idx)+= 4;
 1783    if((*idx)>argc) {
 1784      sprintf(xorriso->info_text,
 1785          "-%s: Not enough arguments. Needed are: device entity id command",
 1786          cmd);
 1787      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
 1788      ret= 0;
 1789    } else
 1790      ret= Xorriso_option_mount(xorriso, arg1, arg2,
 1791                                argv[(*idx)-2], argv[(*idx)-1], 2);
 1792 
 1793  } else if(strcmp(cmd,"setfacl")==0 || strcmp(cmd,"setfacli")==0) {
 1794    (*idx)+= 1;
 1795    ret= Xorriso_option_setfacli(xorriso, arg1, argc, argv, idx, 0);   
 1796 
 1797  } else if(strcmp(cmd,"setfacl_list")==0 || strcmp(cmd,"setfacl_listi")==0) {
 1798    (*idx)+= 1;
 1799    ret= Xorriso_option_setfacl_listi(xorriso, arg1, 0);   
 1800 
 1801  } else if(strcmp(cmd,"setfacl_r")==0 || strcmp(cmd,"setfacl_ri")==0) {
 1802    (*idx)+= 1;
 1803    ret= Xorriso_option_setfacli(xorriso, arg1, argc, argv, idx, 1);   
 1804 
 1805  } else if(strcmp(cmd,"setfattr")==0 || strcmp(cmd,"setfattri")==0) {
 1806    (*idx)+= 2;
 1807    ret= Xorriso_option_setfattri(xorriso, arg1, arg2, argc, argv, idx, 0);   
 1808 
 1809  } else if(strcmp(cmd,"setfattr_list")==0 || strcmp(cmd,"setfattr_listi")==0) {
 1810    (*idx)+= 1;
 1811    ret= Xorriso_option_setfattr_listi(xorriso, arg1, 0);   
 1812 
 1813  } else if(strcmp(cmd,"setfattr_r")==0 || strcmp(cmd,"setfattr_ri")==0) {
 1814    (*idx)+= 2;
 1815    ret= Xorriso_option_setfattri(xorriso, arg1, arg2, argc, argv, idx, 1);   
 1816 
 1817  } else if(strcmp(cmd,"set_filter")==0 || strcmp(cmd,"set_filter_r")==0) {
 1818    (*idx)+= 1;
 1819    ret= Xorriso_option_set_filter(xorriso, arg1, argc, argv, idx,
 1820                                   strcmp(cmd,"set_filter_r")==0);
 1821 
 1822  } else if(strcmp(cmd,"show_stream")==0 || strcmp(cmd,"show_stream_r")==0) {
 1823    ret= Xorriso_option_set_filter(xorriso, "", argc, argv, idx,
 1824                                   (strcmp(cmd,"show_stream_r")==0) | 2 | 4);
 1825 
 1826  } else if(strcmp(cmd,"sh_style_result")==0) {
 1827    (*idx)++;
 1828    ret= Xorriso_option_sh_style_result(xorriso, arg1, 0);
 1829 
 1830  } else if(strcmp(cmd,"signal_handling")==0) {
 1831    (*idx)++;
 1832    ret= Xorriso_option_signal_handling(xorriso, arg1, 0);
 1833 
 1834  } else if(strcmp(cmd,"sleep")==0) {
 1835    (*idx)++;
 1836    ret= Xorriso_option_sleep(xorriso, arg1, 0);
 1837 
 1838  } else if(strcmp(cmd,"speed")==0) {
 1839    (*idx)++;
 1840    ret= Xorriso_option_speed(xorriso, arg1, 0);
 1841 
 1842  } else if(strcmp(cmd,"split_size")==0) {
 1843    (*idx)++;
 1844    ret= Xorriso_option_split_size(xorriso, arg1, 0);
 1845 
 1846  } else if(strcmp(cmd,"status")==0) {
 1847    (*idx)++;
 1848    ret= Xorriso_option_status(xorriso, arg1, 0);
 1849 
 1850  } else if(strcmp(cmd,"status_history_max")==0) {
 1851    (*idx)++;
 1852    sscanf(arg1,"%d",&num1);
 1853    ret= Xorriso_option_status_history_max(xorriso, num1, 0);
 1854 
 1855  } else if(strcmp(cmd,"stdio_sync")==0) {
 1856    (*idx)++;
 1857    ret= Xorriso_option_stdio_sync(xorriso, arg1, 0);
 1858 
 1859  } else if(strcmp(cmd,"stream_recording")==0) {
 1860    (*idx)++;
 1861    ret= Xorriso_option_stream_recording(xorriso, arg1, 0);
 1862 
 1863  } else if(strcmp(cmd,"system_id")==0) {
 1864    (*idx)++;
 1865    ret= Xorriso_option_system_id(xorriso, arg1, 0);
 1866 
 1867  } else if(strcmp(cmd,"tell_media_space")==0) {
 1868    Xorriso_option_tell_media_space(xorriso, 0);
 1869 
 1870  } else if(strcmp(cmd,"temp_mem_limit")==0) {
 1871    (*idx)++;
 1872    ret= Xorriso_option_temp_mem_limit(xorriso, arg1, 0);
 1873 
 1874  } else if(strcmp(cmd,"test")==0) { /* This option does not exist. */
 1875    /* install temporary test code here */;
 1876 
 1877 if (0) {
 1878 /* Test setup for for Xorriso_push_outlists() et.al. */
 1879 /* Test setup for Xorriso_parse_line */
 1880    int stack_handle = -1, line_count= 0;
 1881    struct Xorriso_lsT *result_list, *info_list;
 1882    int Xorriso_process_msg_lists(struct XorrisO *xorriso,
 1883                                      struct Xorriso_lsT *result_list,
 1884                                      struct Xorriso_lsT *info_list,
 1885                                      int *line_count, int flag);
 1886 
 1887    (*idx)++;
 1888    if(strcmp(arg1, "push") == 0) {
 1889      ret= Xorriso_push_outlists(xorriso, &stack_handle, 3);
 1890      fprintf(stderr, "xorriso -test: push = %d, handle = %d\n",
 1891              ret, stack_handle);
 1892    } else if(strcmp(arg1, "pull") == 0) {
 1893      ret= Xorriso_pull_outlists(xorriso, -1, &result_list, &info_list, 0);
 1894      fprintf(stderr, "xorriso -test: pull = %d\n", ret);
 1895      if(ret > 0) {
 1896        ret= Xorriso_process_msg_lists(xorriso, result_list, info_list,
 1897                                       &line_count, 0);
 1898        fprintf(stderr,
 1899           "xorriso -test: Xorriso_process_msg_lists() = %d, line_count = %d\n",
 1900           ret, line_count);
 1901      }
 1902    } else if(strcmp(arg1, "fetch") == 0) {
 1903      ret= Xorriso_fetch_outlists(xorriso, -1, &result_list, &info_list, 0);
 1904      fprintf(stderr, "xorriso -test: fetch = %d\n", ret);
 1905      if(ret > 0) {
 1906        ret= Xorriso_process_msg_lists(xorriso, result_list, info_list,
 1907                                       &line_count, 0);
 1908        fprintf(stderr,
 1909           "xorriso -test: Xorriso_process_msg_lists() = %d, line_count = %d\n",
 1910           ret, line_count);
 1911      }
 1912    } else if(strcmp(arg1, "peek") == 0) {
 1913      ret= Xorriso_peek_outlists(xorriso, -1, 0, 0);
 1914      fprintf(stderr, "xorriso -test: peek = %d\n", ret);
 1915    } else if(strcmp(arg1, "sleep_peek") == 0) {
 1916      usleep(1000000);
 1917      ret= Xorriso_peek_outlists(xorriso, -1, 0, 0);
 1918      fprintf(stderr, "xorriso -test: sleep_peek = %d\n", ret);
 1919    } else if(strcmp(arg1, "peek_loop") == 0) {
 1920      ret= Xorriso_peek_outlists(xorriso, -1, 3, 4);
 1921      fprintf(stderr, "xorriso -test: peek_loop = %d\n", ret);
 1922    } else if(strcmp(arg1, "start") == 0) {
 1923      ret= Xorriso_start_msg_watcher(xorriso, NULL, NULL, NULL, NULL, 0);
 1924      fprintf(stderr, "xorriso -test: Xorriso_start_msg_watcher() = %d\n", ret);
 1925    } else if(strcmp(arg1, "stop") == 0) {
 1926      ret= Xorriso_stop_msg_watcher(xorriso, 0);
 1927      fprintf(stderr, "xorriso -test: Xorriso_stop_msg_watcher() = %d\n", ret);
 1928 
 1929    } else if(strcmp(arg1, "help") == 0) {
 1930      fprintf(stderr, "-test [mode] [arguments]\n");
 1931      fprintf(stderr, "   push\n");
 1932      fprintf(stderr, "     perform Xorriso_push_outlists()\n");
 1933      fprintf(stderr, "   pull\n");
 1934      fprintf(stderr, "     perform Xorriso_pull_outlists() and show messages\n");
 1935      fprintf(stderr, "   fetch\n");
 1936      fprintf(stderr, "     perform Xorriso_fetch_outlists() and show\n");
 1937      fprintf(stderr, "   peek\n");
 1938      fprintf(stderr, "     perform Xorriso_peek_outlists()\n");
 1939      fprintf(stderr, "   sleep_peek\n");
 1940      fprintf(stderr, "     sleep 1 s and perform Xorriso_peek_outlists()\n");
 1941      fprintf(stderr, "   peek_loop\n");
 1942      fprintf(stderr, "     wait for up to 3s in Xorriso_peek_outlists()\n");
 1943      fprintf(stderr, "     for return value 0 or -1\n");
 1944      fprintf(stderr, "   start\n");
 1945      fprintf(stderr, "     perform Xorriso_start_msg_watcher()\n");
 1946      fprintf(stderr, "   stop\n");
 1947      fprintf(stderr, "     perform Xorriso_stop_msg_watcher()\n");
 1948    } else {
 1949      fprintf(stderr, "xorriso -test: unknown mode: %s\n", arg1);
 1950    }
 1951    ret= 0;
 1952 }
 1953 
 1954  } else if(strcmp(cmd,"toc")==0) {
 1955    Xorriso_option_toc(xorriso, 0);
 1956 
 1957  } else if(strcmp(cmd,"toc_of")==0) {
 1958    (*idx)++;
 1959    Xorriso_option_toc_of(xorriso, arg1, 0);
 1960 
 1961  } else if(strcmp(cmd,"truncate_overwritable")==0) {
 1962    (*idx)+= 3;
 1963    ret= Xorriso_option_truncate_overwritable(xorriso, arg1, arg2, arg3, 0);
 1964 
 1965  } else if(strcmp(cmd,"uid")==0) {
 1966    (*idx)++;
 1967    ret= Xorriso_option_uid(xorriso,arg1,0);
 1968 
 1969  } else if(strcmp(cmd,"unregister_filter")==0) {
 1970    (*idx)++;
 1971    ret= Xorriso_option_unregister_filter(xorriso, arg1, 0);
 1972 
 1973  } else if(strcmp(cmd,"update")==0) {
 1974    (*idx)+= 2;
 1975    ret= Xorriso_option_update(xorriso, arg1, arg2, 1);
 1976 
 1977  } else if(strcmp(cmd,"update_l") == 0 || strcmp(cmd,"update_lx") == 0) {
 1978    ret= Xorriso_option_map_l(xorriso, argc, argv, idx, 2<<8);
 1979 
 1980  } else if(strcmp(cmd,"update_li") == 0) {
 1981    ret= Xorriso_option_map_l(xorriso, argc, argv, idx, 5 << 8);
 1982 
 1983  } else if(strcmp(cmd,"update_lxi") == 0) {
 1984    ret= Xorriso_option_map_l(xorriso, argc, argv, idx, 4 << 8);
 1985 
 1986  } else if(strcmp(cmd,"update_r")==0) {
 1987    (*idx)+= 2;
 1988    ret= Xorriso_option_update(xorriso, arg1, arg2, 1|8);
 1989 
 1990  } else if(strcmp(cmd,"use_immed_bit")==0) {
 1991    (*idx)++;
 1992    ret= Xorriso_option_use_immed_bit(xorriso, arg1, 0);
 1993 
 1994  } else if(strcmp(cmd,"use_readline")==0) {
 1995    (*idx)++;
 1996    ret= Xorriso_option_use_readline(xorriso, arg1, 0);
 1997 
 1998  } else if(strcmp(cmd,"version")==0){
 1999    ret= Xorriso_option_version(xorriso, 0);
 2000 
 2001  } else if(strcmp(cmd,"volset_id")==0) {
 2002    (*idx)++;
 2003    ret= Xorriso_option_volset_id(xorriso, arg1, 0);
 2004 
 2005  } else if(strcmp(cmd,"volid")==0) {
 2006    (*idx)++;
 2007    ret= Xorriso_option_volid(xorriso,arg1,0);
 2008 
 2009  } else if(strcmp(cmd,"volume_date")==0) {
 2010    (*idx)+= 2;
 2011    ret= Xorriso_option_volume_date(xorriso, arg1, arg2, 0);
 2012 
 2013  } else if(strcmp(cmd,"write_type")==0) {
 2014    (*idx)++;
 2015    ret= Xorriso_option_write_type(xorriso, arg1, 0);
 2016 
 2017  } else if(strcmp(cmd, "x") == 0) {
 2018    /* only in effect in Xorriso_prescan_args() */;
 2019 
 2020  } else if(strcmp(cmd,"xattr")==0) {
 2021    (*idx)++;
 2022    ret= Xorriso_option_xattr(xorriso, arg1, 0);
 2023 
 2024  } else if(strcmp(cmd,"zisofs")==0) {
 2025    (*idx)++;
 2026    ret= Xorriso_option_zisofs(xorriso, arg1, 0);
 2027 
 2028  } else if(strcmp(cmd, xorriso->list_delimiter)==0){
 2029    /* tis ok */;
 2030 
 2031  } else if(was_dashed) {
 2032    if(xorriso->add_plainly>1)
 2033      goto add_plain_argument;
 2034 unknown_option:;
 2035    sprintf(xorriso->info_text, "Not a known command:  '%s'\n",
 2036            original_cmd);
 2037    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
 2038    {ret= 0; goto eval_any_problems;}
 2039 
 2040  } else {
 2041    if(xorriso->add_plainly<=0)
 2042      goto unknown_option;
 2043 add_plain_argument:;
 2044    mem_idx= *idx;
 2045    (*idx)--;
 2046    ret= Xorriso_option_add(xorriso, (*idx)+1, argv, idx, 0);
 2047    (*idx)= mem_idx;
 2048 
 2049  }
 2050 
 2051 eval_any_problems:
 2052  ret= Xorriso_eval_problem_status(xorriso, ret, 0);
 2053  if(ret<0)
 2054    goto ex;
 2055 
 2056  if(*idx < argc && !(flag & 4))
 2057    goto next_command;
 2058 
 2059 ex:;
 2060  fflush(stdout);
 2061  Xorriso_free_meM(cmd_data);
 2062  return(ret);
 2063 }
 2064 
 2065 
 2066 int Xorriso_parse_line(struct XorrisO *xorriso, char *line,
 2067                        char *prefix, char *separators, int max_words,
 2068                        int *argc, char ***argv, int flag)
 2069 {
 2070  int ret, bsl_mode;
 2071  char *to_parse, *progname= "";
 2072 
 2073  if(xorriso == NULL && (flag & (32 | 64))) {
 2074    ret= -2; goto ex;
 2075  }
 2076 
 2077  *argc= 0;
 2078  *argv= NULL;
 2079 
 2080  to_parse= line;
 2081  if((flag & 1) || xorriso == NULL)
 2082    bsl_mode= (flag >> 1) & 3;
 2083  else
 2084    bsl_mode= xorriso->bsl_interpretation & 3;
 2085  if(prefix[0]) {
 2086    if(strncmp(line, prefix, strlen(prefix)) == 0) {
 2087      to_parse= line + strlen(prefix);
 2088    } else {
 2089      ret= 2; goto ex;
 2090    }
 2091  }
 2092 
 2093  if(xorriso != NULL)
 2094    progname= xorriso->progname;
 2095  ret= Sfile_sep_make_argv(progname, to_parse, separators,
 2096                           max_words, argc, argv,
 2097                           (!(flag & 32)) | 4 | (bsl_mode << 5));
 2098  if(ret < 0) {
 2099    if(xorriso != NULL)
 2100      Xorriso_msgs_submit(xorriso, 0,
 2101         "Severe lack of resources during command line parsing", 0, "FATAL", 0);
 2102    ret= -1; goto ex;
 2103  }
 2104  if(ret == 0) {
 2105    if((flag & 64) && xorriso != NULL) {
 2106      sprintf(xorriso->info_text, "Incomplete quotation in %s line: %s",
 2107              (flag & 32) ? "command" : "parsed", to_parse);
 2108      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
 2109    }
 2110    goto ex;
 2111  }
 2112  ret= 1;
 2113 ex:;
 2114  if(ret <= 0)
 2115    Sfile_sep_make_argv("", "", "", 0, argc, argv, 2); /* release memory */
 2116  return(ret);
 2117 }
 2118 
 2119 
 2120 void Xorriso__dispose_words(int *argc, char ***argv)
 2121 {
 2122  Sfile_make_argv("", "", argc, argv, 2); /* release memory */
 2123 }
 2124 
 2125 
 2126 int Xorriso_execute_option(struct XorrisO *xorriso, char *line, int flag)
 2127 /*
 2128  bit0-bit15 are forwarded to Xorriso_interpreter
 2129  
 2130  bit16= no pageing of info lines
 2131  bit17= print === bar even if xorriso->found<0
 2132 */
 2133 {
 2134  int ret,argc= 0, idx= 1;
 2135  char **argv= NULL;
 2136  double tdiff;
 2137  struct timeval tv;
 2138 
 2139  gettimeofday(&tv, NULL);
 2140  Xorriso_reset_counters(xorriso,0);
 2141  xorriso->idle_time= 0.0;
 2142  tdiff= tv.tv_sec+(1.e-6*(double) tv.tv_usec);
 2143 
 2144  ret= Xorriso_parse_line(xorriso, line, "", "", 0, &argc, &argv, 32 | 64);
 2145  if(ret <= 0)
 2146    goto ex;
 2147 
 2148  if(argc<2)
 2149    {ret= 1; goto ex;}
 2150  if(argv[1][0]=='#')
 2151    {ret= 1; goto ex;}
 2152 
 2153  ret= Xorriso_interpreter(xorriso, argc, argv, &idx, flag&0xffff);
 2154  if(ret<0)
 2155    goto ex;
 2156  gettimeofday(&tv, NULL);
 2157  tdiff= tv.tv_sec+(1.e-6*(double) tv.tv_usec)-tdiff-xorriso->idle_time;
 2158  if(tdiff<0.001)
 2159    tdiff= 0.001;
 2160  if(xorriso->error_count>0) {
 2161    sprintf(xorriso->info_text,
 2162            "----------------------------- %7.f errors encountered\n",
 2163            xorriso->error_count);
 2164    Xorriso_info(xorriso,!(flag&(1<<16)));
 2165  }
 2166 
 2167  /* ??? >>> print elapsed time  tdiff ? */;
 2168 
 2169  if((flag&(1<<17)) && !xorriso->bar_is_fresh) {
 2170    sprintf(xorriso->info_text,"============================\n");
 2171    Xorriso_info(xorriso,0);
 2172    xorriso->bar_is_fresh= 1;
 2173  }
 2174  Xorriso_reset_counters(xorriso,0);
 2175 ex:;
 2176  Sfile_make_argv("", "", &argc, &argv, 2); /* release memory */
 2177  return(ret);
 2178 }
 2179 
 2180 
 2181 int Xorriso_dialog(struct XorrisO *xorriso, int flag)
 2182 {
 2183  int ret, line_size= 2 * SfileadrL;
 2184  char *line= NULL;
 2185 
 2186  Xorriso_alloc_meM(line, char, line_size);
 2187 
 2188  if(!xorriso->dialog)
 2189    {ret= 1; goto ex;}
 2190  if(xorriso->abort_on_is_default)
 2191    Xorriso_option_abort_on(xorriso, "NEVER", 0);
 2192  xorriso->is_dialog= 1;
 2193  while(1) {
 2194    if(xorriso->pending_option[0]!=0) {
 2195      Xorriso_mark(xorriso,0);
 2196      strcpy(line,xorriso->pending_option);
 2197      xorriso->pending_option[0]= 0;
 2198    } else {
 2199      if(!xorriso->bar_is_fresh) {
 2200        sprintf(xorriso->info_text,"============================\n");
 2201        Xorriso_info(xorriso,0);
 2202        xorriso->bar_is_fresh= 1;
 2203      }
 2204      sprintf(xorriso->info_text,"enter option and arguments :\n");
 2205      Xorriso_info(xorriso,0);
 2206      Xorriso_mark(xorriso,0);
 2207      ret= Xorriso_dialog_input(xorriso,line, line_size, 4);
 2208      if(ret<=0)
 2209  break;
 2210    }
 2211    sprintf(xorriso->info_text,
 2212            "==============================================================\n");
 2213    Xorriso_info(xorriso,0);
 2214 
 2215    ret= Xorriso_execute_option(xorriso,line,1<<17);
 2216    if(ret<0)
 2217      goto ex;
 2218    if(ret==3)
 2219      goto ex;
 2220    xorriso->did_something_useful= 1;
 2221    xorriso->no_volset_present= 0; /* Re-enable "No ISO image present." */
 2222  }
 2223  ret= 1;
 2224 ex:;
 2225  xorriso->is_dialog= 0;
 2226  Xorriso_free_meM(line);
 2227  return(ret);
 2228 }
 2229 
 2230 
 2231 /* @return  1=replaced , 2=not replaced , <=0 = error
 2232 */
 2233 int Xorriso_replace_arg_by_bsl(struct XorrisO *xorriso, char **arg,
 2234                                char **argpt, int flag)
 2235 {
 2236  int ret, eaten, l;
 2237 
 2238  if(!(xorriso->bsl_interpretation & 16))
 2239    return(2);
 2240  l= strlen(*argpt);
 2241  Xorriso_free_meM(*arg);
 2242  Xorriso_alloc_meM(*arg, char, l + 1);
 2243  strcpy(*arg, *argpt);
 2244  *argpt= *arg;
 2245  ret= Sfile_bsl_interpreter(*arg, l, &eaten, 0);
 2246 ex:;
 2247  return(ret);
 2248 }
 2249 
 2250 
 2251 int Xorriso_prescan_args(struct XorrisO *xorriso, int argc, char **argv,
 2252                          int flag)
 2253 /*
 2254  bit0= do not interpret argv[1]
 2255  bit1= complain about inknown arguments
 2256 */
 2257 /*
 2258  return:
 2259   <0  error
 2260    0  end program
 2261    1  ok, go on
 2262 */
 2263 {
 2264  int i, ret, was_dashed, num2, arg_count;
 2265  int advice, mem_add_plainly, error_seen= 0, mem_bsl;
 2266  int was_report_about= 0, was_abort_on= 0, was_return_with= 0;
 2267  int was_signal_handling= 0, was_scsi_log= 0, cmd_data_size= 5 * SfileadrL;
 2268  char *cmd, *original_cmd, *cmd_data= NULL, *arg1, *arg2;
 2269  char *arg1_data= NULL, *arg2_data= NULL;
 2270  char mem_list_delimiter[81];
 2271 
 2272  strcpy(mem_list_delimiter, xorriso->list_delimiter);
 2273  mem_add_plainly= xorriso->add_plainly;
 2274  mem_bsl= xorriso->bsl_interpretation;
 2275 
 2276  Xorriso_alloc_meM(cmd_data, char, cmd_data_size);
 2277 
 2278  for(i=1+(flag&1);i<argc;i++) {
 2279    original_cmd= cmd= argv[i];
 2280    was_dashed= 0;
 2281 
 2282    was_dashed= Xorriso_normalize_command(xorriso, original_cmd, i,
 2283                                          cmd_data, cmd_data_size, &cmd, 0);
 2284    if(was_dashed<0)
 2285      {ret= -1; goto ex;}
 2286 
 2287    arg1= "";
 2288    if(i + 1 < argc) {
 2289      arg1= argv[i + 1];
 2290      ret= Xorriso_replace_arg_by_bsl(xorriso, &arg1_data, &arg1, 0);
 2291      if(ret <= 0)
 2292        goto ex;
 2293    }
 2294    arg2= "";
 2295    if(i + 2 < argc) {
 2296      arg2= argv[i + 2];
 2297      ret= Xorriso_replace_arg_by_bsl(xorriso, &arg2_data, &arg2, 0);
 2298      if(ret <= 0)
 2299        goto ex;
 2300    }
 2301    if(i>1)
 2302      xorriso->did_something_useful= 1;
 2303    if(i==1 && argc==2) {
 2304      if(strcmp(cmd,"prog_help")==0) {
 2305        i++;
 2306        Xorriso_option_prog_help(xorriso,arg1,0);
 2307        xorriso->did_something_useful= 1;
 2308        {ret= 0; goto ex;}
 2309      } else if(strcmp(cmd,"help")==0) {
 2310        if(xorriso->argument_emulation == 1) {
 2311          Xorriso_genisofs_help(xorriso, 0);
 2312        } else if(xorriso->argument_emulation == 2) {
 2313          Xorriso_cdrskin_help(xorriso, 0);
 2314        } else {
 2315          Xorriso_option_help(xorriso,0);
 2316        }
 2317        xorriso->did_something_useful= 1;
 2318        {ret= 0; goto ex;}
 2319      }
 2320    } else if(i==1 && strcmp(cmd,"no_rc")==0) {
 2321      ret= Xorriso_option_no_rc(xorriso, 0);
 2322      if(ret<=0)
 2323        error_seen= 1;
 2324      {ret= 1; goto ex;}
 2325    } else if(xorriso->argument_emulation == 1) { /* mkisofs emulation */
 2326      if(xorriso->dev_fd_1 < 0)
 2327        goto protect_stdout;
 2328      {ret= 1; goto ex;}
 2329 
 2330    } else if(xorriso->argument_emulation == 2) { /* cdrecord emulation */
 2331      if(xorriso->dev_fd_1 < 0)
 2332        if(Xorriso_cdrskin_uses_stdout(xorriso, argc - 1 - (flag & 1),
 2333                                       argv + 1 + (flag & 1), 0))
 2334          goto protect_stdout;
 2335      {ret= 1; goto ex;}
 2336 
 2337    } else if((strcmp(cmd,"dev")==0 || strcmp(cmd,"outdev")==0 ||
 2338                                       strcmp(cmd,"indev")==0) &&
 2339              (strcmp(arg1,"stdio:/dev/fd/1")==0 || strcmp(arg1,"-")==0) &&
 2340              xorriso->dev_fd_1<0) {
 2341      /* Detach fd 1 from externally perceived stdout and attach it to stderr.
 2342         Keep dev_fd_1 connected to external stdout. dev_fd_1 is to be used when
 2343         "stdio:/dev/fd/1" is interpreted as drive address.
 2344      */
 2345 protect_stdout:;
 2346      ret= Xorriso_protect_stdout(xorriso, 0);
 2347      if(ret == 1) {
 2348        sprintf(xorriso->info_text,
 2349              "Encountered  -  or  stdio:/dev/fd/1  as possible write target.");
 2350        Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
 2351        sprintf(xorriso->info_text,
 2352              "Redirecting nearly all text message output to stderr.");
 2353        Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
 2354        sprintf(xorriso->info_text, "Disabling use of libreadline.");
 2355        Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
 2356      }
 2357      if(xorriso->argument_emulation >= 1 && xorriso->argument_emulation <=2)
 2358        {ret= 1; goto ex;}
 2359 
 2360    } else if(strcmp(cmd,"abort_on")==0 && was_dashed == 1) {
 2361      i++;
 2362      if(!was_abort_on)
 2363        Xorriso_option_abort_on(xorriso, arg1, 0);
 2364      was_abort_on= 1;
 2365 
 2366    } else if(strcmp(cmd,"report_about")==0 && was_dashed == 1) {
 2367      i++;
 2368      if(!was_report_about)
 2369        Xorriso_option_report_about(xorriso, arg1, 0);
 2370      was_report_about= 1;
 2371 
 2372    } else if(strcmp(cmd,"return_with")==0 && was_dashed == 1) {
 2373      i+= 2;
 2374      num2= 0;
 2375      sscanf(arg2,"%d",&num2);
 2376      if(!was_return_with)
 2377        Xorriso_option_return_with(xorriso, arg1, num2, 0);
 2378      was_return_with= 1;
 2379 
 2380    } else if(strcmp(cmd,"as")==0 && was_dashed == 1) {
 2381      ret= Xorriso_count_args(xorriso, argc - i, argv + i, &arg_count, 1);
 2382      if(ret == 1) {
 2383        i+= arg_count;
 2384 
 2385        if((strcmp(arg1, "cdrecord")==0 || strcmp(arg1, "wodim")==0 ||
 2386            strcmp(arg1, "cdrskin")==0 || strcmp(arg1, "xorrecord")==0) &&
 2387           xorriso->dev_fd_1 < 0)
 2388          if(Xorriso_cdrskin_uses_stdout(xorriso, arg_count - 1,
 2389                                         argv + i - arg_count + 2, 0))
 2390            goto protect_stdout;
 2391      }
 2392      if(was_dashed == 1) {
 2393        if((strcmp(arg1, "mkisofs")==0 || strcmp(arg1, "genisoimage")==0 ||
 2394            strcmp(arg1, "genisofs")==0 || strcmp(arg1, "xorrisofs")==0) &&
 2395           xorriso->dev_fd_1 < 0)
 2396          goto protect_stdout;
 2397      }
 2398 
 2399    } else if(strcmp(cmd, "list_delimiter") == 0) {
 2400      /* Needed for interpreting other args. Gets reset after prescan. */
 2401      i++;
 2402      ret= Xorriso_option_list_delimiter(xorriso, arg1, 0);
 2403      if(ret <= 0)
 2404        error_seen= 1;
 2405 
 2406    } else if(strcmp(cmd, "add_plainly") == 0) {
 2407      i++;
 2408      ret= Xorriso_option_add_plainly(xorriso, arg1, 0);
 2409      if(ret <= 0)
 2410        error_seen= 1;
 2411      if(xorriso->add_plainly == 3) {
 2412        /* All further arguments count as pathspecs */
 2413        {ret= 1; goto ex;}
 2414      }
 2415    } else if(strcmp(cmd, "scsi_log") == 0 && was_dashed == 1) {
 2416      i++;
 2417      if(!was_scsi_log)
 2418         Xorriso_option_scsi_log(xorriso, arg1, 0);
 2419      was_scsi_log= 1;
 2420 
 2421    } else if(strcmp(cmd, "signal_handling") == 0 && was_dashed == 1) {
 2422      i++;
 2423      if(!was_signal_handling)
 2424        Xorriso_option_signal_handling(xorriso, arg1, 1); /* no install */
 2425      was_signal_handling= 1;
 2426 
 2427    } else if(strcmp(original_cmd, "-x") == 0) {
 2428      xorriso->arrange_args= 1;
 2429 
 2430    } else if(strcmp(cmd, "backslash_codes") == 0) {
 2431      i++;
 2432      ret= Xorriso_option_backslash_codes(xorriso, arg1, 0);
 2433      if(ret <= 0)
 2434        error_seen= 1;
 2435 
 2436    } else {
 2437      ret= Xorriso_count_args(xorriso, argc - i, argv + i, &arg_count, 1);
 2438      if(ret == 1) {
 2439        i+= arg_count;
 2440      } else if((flag & 2) && ((was_dashed && xorriso->add_plainly <= 1) ||
 2441                               xorriso->add_plainly <= 0)) {
 2442        sprintf(xorriso->info_text, "Not a known command:  '%s'\n",
 2443                original_cmd);
 2444        Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
 2445        error_seen= 1;
 2446      }
 2447    }
 2448  }
 2449  ret= 1;
 2450 ex:;
 2451  strcpy(xorriso->list_delimiter, mem_list_delimiter);
 2452  xorriso->add_plainly= mem_add_plainly;
 2453  xorriso->bsl_interpretation= mem_bsl;
 2454  Xorriso_free_meM(arg1_data);
 2455  Xorriso_free_meM(arg2_data);
 2456  Xorriso_free_meM(cmd_data);
 2457  if(error_seen && ret > 0) {
 2458    advice= Xorriso_eval_problem_status(xorriso, 0, 0);
 2459    if(advice < 0)
 2460      ret= -1;
 2461  }
 2462  return(ret);
 2463 }
 2464 
 2465 
 2466 int Xorriso_read_as_mkisofsrc(struct XorrisO *xorriso, char *path, int flag)
 2467 {
 2468  int ret, linecount= 0;
 2469  FILE *fp= NULL;
 2470  char *sret, *line= NULL, *cpt, *wpt;
 2471 
 2472  Xorriso_alloc_meM(line, char, SfileadrL);
 2473 
 2474  ret= Xorriso_afile_fopen(xorriso, path, "rb", &fp, 1 | 2);
 2475  if(ret <= 0)
 2476    {ret= 0; goto ex;}
 2477  while(1) {
 2478    sret= Sfile_fgets_n(line, SfileadrL - 1, fp, 0);
 2479    if(sret == NULL) {
 2480      if(ferror(fp))
 2481        {ret= 0; goto ex;}
 2482  break;
 2483    }
 2484    linecount++;
 2485    
 2486    /* Interpret line */
 2487    if(line[0] == 0 || line[0] == '#')
 2488  continue;
 2489    cpt= strchr(line, '=');
 2490    if(cpt == NULL) {
 2491 
 2492      /* >>> ??? complain ? abort reading ? */;
 2493 
 2494  continue;
 2495    }
 2496    *cpt= 0;
 2497    /* Names are not case sensitive */
 2498    for(wpt= line; wpt < cpt; wpt++)
 2499      if(*wpt >= 'a' && *wpt <= 'z')
 2500        *wpt= toupper(*wpt);
 2501    /* Remove trailing whitespace from name */
 2502    for(wpt= cpt - 1; wpt >= line ; wpt--)
 2503      if(*wpt == ' ' || *wpt == '\t')
 2504        *wpt= 0;
 2505      else
 2506    break;
 2507    /* Remove trailing whitespace from value */
 2508    for(wpt= cpt + 1 + strlen(cpt + 1) - 1; wpt >= cpt; wpt--)
 2509       if(*wpt == ' ' || *wpt == '\t')
 2510        *wpt= 0;
 2511      else
 2512    break;
 2513    /* Remove leading whitespace from value */
 2514    for(cpt++; *cpt == ' ' || *cpt == '\t'; cpt++);
 2515    
 2516    if(strcmp(line, "APPI") == 0) {
 2517      ret= Xorriso_option_application_id(xorriso, cpt, 0);
 2518    } else if(strcmp(line, "COPY") == 0) {
 2519      ret= Xorriso_option_copyright_file(xorriso, cpt, 0);
 2520    } else if(strcmp(line, "ABST") == 0) {
 2521      ret= Xorriso_option_abstract_file(xorriso, cpt, 0);
 2522    } else if(strcmp(line, "BIBL") == 0) {
 2523      ret= Xorriso_option_biblio_file(xorriso, cpt, 0);
 2524    } else if(strcmp(line, "PREP") == 0) {
 2525      /* Not planned to be implemented. Preparer is xorriso. */
 2526      ret= 1;
 2527    } else if(strcmp(line, "PUBL") == 0) {
 2528      ret= Xorriso_option_publisher(xorriso, cpt, 0);
 2529    } else if(strcmp(line, "SYSI") == 0) {
 2530      ret= Xorriso_option_system_id(xorriso, cpt, 0);
 2531    } else if(strcmp(line, "VOLI") == 0) {
 2532      ret= Xorriso_option_volid(xorriso, cpt, 1);
 2533    } else if(strcmp(line, "VOLS") == 0) {
 2534      ret= Xorriso_option_volset_id(xorriso, cpt, 0);
 2535    } else if(strcmp(line, "HFS_TYPE") == 0) {
 2536      /* Not planned to be implemented */
 2537      ret= 1;
 2538    } else if(strcmp(line, "HFS_CREATOR") == 0) {
 2539      /* Not planned to be implemented */
 2540      ret= 1;
 2541    } else {
 2542 
 2543      /* >>> ??? complain ? abort reading ? */;
 2544 
 2545    }
 2546    if(ret <= 0)
 2547      goto ex;
 2548  }
 2549  xorriso->mkisofsrc_done= 1;
 2550  ret= 1;
 2551 ex:
 2552  if(fp != NULL)
 2553    fclose(fp);
 2554  Xorriso_free_meM(line);
 2555  return(ret);
 2556 }
 2557 
 2558 
 2559 /* ./.mkisofsrc , getenv("MKISOFSRC") ,
 2560    $HOME/.mkisofsrc , $(basename $0)/.mkisofsrc
 2561  */
 2562 int Xorriso_read_mkisofsrc(struct XorrisO *xorriso, int flag)
 2563 {
 2564  char *path= NULL, *cpt;
 2565  int ret;
 2566 
 2567  Xorriso_alloc_meM(path, char, SfileadrL);
 2568 
 2569  ret= Xorriso_read_as_mkisofsrc(xorriso, "./.mkisofsrc", 0);
 2570  if(ret > 0)
 2571    goto ex;
 2572  cpt= getenv("MKISOFSRC");
 2573  if(cpt != NULL) {
 2574    strncpy(path, cpt, SfileadrL - 1);
 2575    path[SfileadrL - 1]= 0;
 2576    ret= Xorriso_read_as_mkisofsrc(xorriso, path, 0);
 2577    if(ret > 0)
 2578      goto ex;
 2579  }
 2580  cpt= getenv("HOME");
 2581  if(cpt != NULL) {
 2582    strncpy(path, cpt, SfileadrL - 1 - 11);
 2583    path[SfileadrL - 1 - 11]= 0;
 2584    strcat(path, "/.mkisofsrc");
 2585    ret= Xorriso_read_as_mkisofsrc(xorriso, path, 0);
 2586    if(ret > 0)
 2587      goto ex;
 2588  }
 2589  strcpy(path, xorriso->progname);
 2590  cpt= strrchr(path, '/');
 2591  if(cpt != NULL) {
 2592    strcpy(cpt + 1, ".mkisofsrc");
 2593    ret= Xorriso_read_as_mkisofsrc(xorriso, path, 0);
 2594    if(ret > 0)
 2595      goto ex;
 2596  }
 2597  /* no .mkisofsrc file found */
 2598  ret= 2;
 2599 ex:;
 2600  Xorriso_free_meM(path);
 2601  return(ret);
 2602 }
 2603 
 2604 
 2605 /* https://reproducible-builds.org/specs/source-date-epoch/
 2606    and reproducible-builds@lists.alioth.debian.org in august 2016
 2607 */
 2608 int Xorriso_source_date_epoch(struct XorrisO *xorriso, int flag)
 2609 {
 2610  /* num_text must be able to take the sprintf output of "%.f".
 2611     num_text + 12 must be able to take "%d" with a 64 bit int.
 2612  */
 2613  char *sec_text, num_text[40];
 2614  double dsec= -1.0;
 2615  time_t tsec;
 2616  struct tm *gmt;
 2617 
 2618  sec_text= getenv("SOURCE_DATE_EPOCH");
 2619  if(sec_text == NULL)
 2620    return(2);
 2621 
 2622  sscanf(sec_text, "%lf", &dsec);
 2623  sprintf(num_text, "%.f", dsec);
 2624  tsec= dsec;
 2625  if(dsec < 0 || ((double) tsec) != dsec ||
 2626     strcmp(sec_text, num_text) != 0) {
 2627 malformed:;
 2628    Xorriso_msgs_submit(xorriso, 0,
 2629                 "Malformed environment variable SOURCE_DATE_EPOCH encountered",
 2630                        0, "SORRY", 0);
 2631    Xorriso_msgs_submit(xorriso, 0,
 2632                 "Unset SOURCE_DATE_EPOCH before starting xorriso or see https://reproducible-builds.org/specs/source-date-epoch/",
 2633                        0, "HINT", 0);
 2634    return(0);
 2635  }
 2636  gmt= gmtime(&tsec);
 2637  if(gmt == NULL)
 2638    goto malformed;
 2639 
 2640  sprintf(num_text,      "%4.4d", 1900 + gmt->tm_year);
 2641  sprintf(num_text +  4, "%2.2d", gmt->tm_mon + 1);
 2642  sprintf(num_text +  6, "%2.2d", gmt->tm_mday);
 2643  sprintf(num_text +  8, "%2.2d", gmt->tm_hour);
 2644  sprintf(num_text + 10, "%2.2d", gmt->tm_min);
 2645  sprintf(num_text + 12, "%2.2d", gmt->tm_sec);
 2646  strcpy(num_text  + 14, "00");
 2647  strcpy(xorriso->vol_uuid, num_text);
 2648  xorriso->gpt_guid_mode= 2; /* Disk GUID from vol_uuid */
 2649  strcpy(xorriso->all_file_dates, "set_to_mtime");
 2650  xorriso->do_override_now_time= 1;
 2651  xorriso->now_time_override= tsec;
 2652  Xorriso_set_libisofs_now(xorriso, 0);
 2653 
 2654  sprintf(xorriso->info_text,
 2655          "Environment variable SOURCE_DATE_EPOCH encountered with value %s",
 2656          sec_text);
 2657  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
 2658  sprintf(xorriso->info_text, "SOURCE_DATE_EPOCH : -volume_date uuid %s",
 2659                              xorriso->vol_uuid);
 2660  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
 2661  sprintf(xorriso->info_text,
 2662                           "SOURCE_DATE_EPOCH : -volume_date all_file_dates %s",
 2663                           xorriso->all_file_dates);
 2664  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
 2665  sprintf(xorriso->info_text,
 2666          "SOURCE_DATE_EPOCH : -boot_image any gpt_disk_guid=volume_date_uuid");
 2667  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
 2668  sprintf(xorriso->info_text,
 2669                    "SOURCE_DATE_EPOCH : -iso_nowtime =%.f", (double) tsec);
 2670  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
 2671 
 2672  return(1);
 2673 }
 2674 
 2675 
 2676 int Xorriso_read_rc(struct XorrisO *xorriso, int flag)
 2677 {
 2678  int ret,i,was_failure= 0,fret;
 2679 
 2680  /* Interpret environment variable SOURCE_DATE_EPOCH */
 2681  ret= Xorriso_source_date_epoch(xorriso, 0);
 2682  ret= Xorriso_eval_problem_status(xorriso, ret, 0);
 2683  if(ret < 0)
 2684    return(0);
 2685 
 2686  if(xorriso->no_rc)
 2687    return(1);
 2688  i= xorriso->rc_filename_count-1;
 2689  Sfile_home_adr_s(".xorrisorc", xorriso->rc_filenames[i],
 2690                   sizeof(xorriso->rc_filenames[i]),0);
 2691  for(i=0;i<xorriso->rc_filename_count;i++) {
 2692    ret= Sfile_type(xorriso->rc_filenames[i],1|8);
 2693    if(ret!=1)
 2694  continue;
 2695    ret= Xorriso_option_options_from_file(xorriso,xorriso->rc_filenames[i],0);
 2696    if(ret>1)
 2697      return(ret);
 2698    if(ret==1)
 2699  continue; /* regular bottom of loop */
 2700    was_failure= 1;
 2701    fret= Xorriso_eval_problem_status(xorriso, ret, 1);
 2702    if(fret>=0)
 2703  continue;
 2704    return(ret);
 2705  }
 2706  if(xorriso->argument_emulation == 1 && !xorriso->mkisofsrc_done) {
 2707    ret= Xorriso_read_mkisofsrc(xorriso, 0);
 2708    if(ret <= 0)
 2709      was_failure= 1;
 2710  }
 2711  return(!was_failure);
 2712 }
 2713 
 2714 
 2715 int Xorriso_make_return_value(struct XorrisO *xorriso, int flag)
 2716 {
 2717  int exit_value= 0;
 2718 
 2719  if(xorriso->eternal_problem_status >= xorriso->return_with_severity)
 2720    exit_value= xorriso->return_with_value;
 2721  if(exit_value) {
 2722    sprintf(xorriso->info_text,
 2723           "-return_with %s %d triggered by problem severity %s",
 2724           xorriso->return_with_text, exit_value,
 2725           xorriso->eternal_problem_status_text);
 2726    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
 2727  }
 2728  return(exit_value);
 2729 }
 2730 
 2731 
 2732 int Xorriso_program_arg_bsl(struct XorrisO *xorriso, int argc, char ***argv,
 2733                             int flag)
 2734 {
 2735  int i, ret, eaten, bsl_mem, params_to_come= 0, cmd_data_size= 5 * SfileadrL;
 2736  int next_is_backslash_codes= 0, next_is_list_delimiter= 0;
 2737  char **new_argv= NULL, *cmd, *cmd_data= NULL;
 2738  char mem_list_delimiter[81];
 2739 
 2740  strcpy(mem_list_delimiter, xorriso->list_delimiter);
 2741  bsl_mem= xorriso->bsl_interpretation;
 2742  if(argc <= 0)
 2743    return(0);
 2744  Xorriso_alloc_meM(cmd_data, char, cmd_data_size);
 2745  new_argv= (char **) Smem_malloC(argc * sizeof(char *));
 2746  if(new_argv == NULL)
 2747    {ret= -1; goto ex;}
 2748  for(i= 0; i < argc; i++) {
 2749    new_argv[i]= strdup((*argv)[i]);
 2750    if(new_argv[i] == NULL)
 2751      {ret= -1; goto ex;}
 2752    if(i == 0)
 2753  continue;
 2754    if(xorriso->bsl_interpretation & 16) {
 2755      ret= Sfile_bsl_interpreter(new_argv[i], strlen(new_argv[i]), &eaten, 0);
 2756      if(ret <= 0)
 2757        goto ex;
 2758    }
 2759    if(params_to_come == 0) {
 2760      ret= Xorriso_normalize_command(xorriso, new_argv[i], i,
 2761                                     cmd_data, cmd_data_size, &cmd, 0);
 2762      if(ret < 0)
 2763        goto ex;
 2764      if(strcmp(cmd, "backslash_codes") == 0) {
 2765        params_to_come= 1;
 2766        next_is_backslash_codes= 1;
 2767      } else if(strcmp(cmd, "list_delimiter") == 0) {
 2768        params_to_come= 1;
 2769        next_is_list_delimiter= 1;
 2770      } else {
 2771        ret= Xorriso_count_args(xorriso, argc - i, *argv + i,
 2772                                &params_to_come, 1);
 2773        if(ret <= 0)
 2774          goto ex;
 2775        if(ret != 1)
 2776          params_to_come= 0;
 2777      }
 2778    } else {
 2779      params_to_come--;
 2780      if(next_is_backslash_codes) {
 2781        next_is_backslash_codes= 0;
 2782        ret= Xorriso_option_backslash_codes(xorriso, new_argv[i], 0);
 2783        if(ret <= 0)
 2784          goto ex;
 2785      } else if(next_is_list_delimiter) {
 2786        next_is_list_delimiter= 0;
 2787        ret= Xorriso_option_list_delimiter(xorriso, new_argv[i], 0);
 2788        if(ret <= 0)
 2789          goto ex;
 2790      }
 2791    }
 2792  }
 2793  ret= 1;
 2794 ex:;
 2795  Xorriso_free_meM(cmd_data);
 2796  strcpy(xorriso->list_delimiter, mem_list_delimiter);
 2797  xorriso->bsl_interpretation= bsl_mem;
 2798  if(ret <= 0) {
 2799    if(new_argv != NULL)
 2800      free((char *) new_argv);
 2801  } else
 2802    *argv= new_argv;
 2803  return(ret);
 2804 }
 2805 
 2806 
 2807 /* @param flag bit0= prepend wd only if name does not begin by '/'
 2808                bit1= normalize image path
 2809                bit2= prepend wd (automatically done if wd[0]!=0)
 2810                bit3= (with bit1) this is an address in the disk world
 2811 */
 2812 int Xorriso_make_abs_adr(struct XorrisO *xorriso, char *wd, char *name,
 2813                              char adr[], int flag)
 2814 {
 2815  char *norm_adr= NULL;
 2816  int ret;
 2817 
 2818  Xorriso_alloc_meM(norm_adr, char, SfileadrL);
 2819 
 2820  if((wd[0]!=0 || (flag&4)) && !((flag&1) && name[0]=='/')) {
 2821    if(strlen(wd)+1>=SfileadrL)
 2822      goto much_too_long;
 2823    strcpy(adr, wd);
 2824    if(name[0])
 2825      if(Sfile_add_to_path(adr, name, 0)<=0) {
 2826 much_too_long:;
 2827        Xorriso_much_too_long(xorriso, (int) (strlen(adr)+strlen(name)+1), 2);
 2828        {ret= 0; goto ex;}
 2829      }
 2830  } else {
 2831    if(strlen(name)+1>=SfileadrL)
 2832      goto much_too_long;
 2833    strcpy(adr, name);
 2834  }
 2835  if(flag&2) {
 2836    ret= Xorriso_normalize_img_path(xorriso, "", adr, norm_adr,
 2837                                    1|2|((flag&8)>>1));
 2838    if(ret<=0)
 2839      goto ex;
 2840    if(norm_adr[0]==0)
 2841      strcpy(norm_adr, "/");
 2842    strcpy(adr, norm_adr);
 2843  }
 2844  ret= 1;
 2845 ex:;
 2846  Xorriso_free_meM(norm_adr);
 2847  return(ret);
 2848 }
 2849 
 2850 
 2851 /* @param flag bit0= do not complain in case of error, but set info_text */
 2852 int Xorriso_convert_datestring(struct XorrisO *xorriso, char *cmd,
 2853                                char *time_type, char *timestring,
 2854                                int *t_type, time_t *t, int flag)
 2855 {
 2856  int ret;
 2857 
 2858  *t_type= 0;
 2859  if(strcmp(time_type, "a")==0)
 2860    (*t_type)|= 1;
 2861  else if(strcmp(time_type, "a-c")==0)
 2862    (*t_type)|= 1 | 256;
 2863  else if(strcmp(time_type, "m")==0)
 2864    (*t_type)|= 4;
 2865  else if(strcmp(time_type, "m-c")==0)
 2866    (*t_type)|= 4 | 256;
 2867  else if(strcmp(time_type, "b")==0)
 2868    (*t_type)|= 5;
 2869  else if(strcmp(time_type, "b-c")==0)
 2870    (*t_type)|= 5 | 256;
 2871  else if(strcmp(time_type, "c")==0)
 2872    (*t_type)|= 2 | 256;
 2873  else {
 2874    sprintf(xorriso->info_text, "%s: Unrecognized type '%s'", cmd, time_type);
 2875    if(!(flag & 1))
 2876      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
 2877    return(0);
 2878  }
 2879  ret= Decode_timestring(timestring, t, 0);
 2880  if(ret<=0) {
 2881    sprintf(xorriso->info_text, "%s: Cannot decode timestring '%s'", cmd,
 2882            timestring);
 2883    if(!(flag & 1))
 2884      Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
 2885    return(0);
 2886  }
 2887  sprintf(xorriso->info_text, "Understanding timestring '%s' as:  %s",
 2888          timestring, ctime(t));
 2889  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
 2890  return(1);
 2891 }
 2892 
 2893 
 2894 /* @param flag bit1= do not report memory usage as DEBUG
 2895 */ 
 2896 int Xorriso_check_temp_mem_limit(struct XorrisO *xorriso, off_t mem, int flag)
 2897 {
 2898  char mem_text[80], limit_text[80];
 2899  
 2900  Sfile_scale((double) mem, mem_text,5,1e4,0);
 2901  if(!(flag&2)) {
 2902    sprintf(xorriso->info_text,
 2903            "Temporary memory needed for result sorting : %s", mem_text);
 2904    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
 2905  }
 2906  if(mem > xorriso->temp_mem_limit) {
 2907    Sfile_scale((double) xorriso->temp_mem_limit,limit_text,5,1e4,1);
 2908    sprintf(xorriso->info_text,
 2909        "Cannot sort. List of matching files exceeds -temp_mem_limit (%s > %s)",
 2910            mem_text, limit_text);
 2911    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
 2912    return(0);
 2913  }
 2914  return(1);
 2915 }
 2916 
 2917 
 2918 int Xorriso_wait_child_end(struct XorrisO *xorriso, pid_t child_pid,
 2919                            int *status, int flag)
 2920 {
 2921  int ret;
 2922 
 2923  do {
 2924    /* try to read and print the reply */;
 2925    ret= waitpid(child_pid, status, WNOHANG);
 2926    if(ret == -1) {
 2927      if(errno != EINTR)
 2928        return(0);
 2929    } else if(ret == 0) {
 2930  continue;
 2931    } else {
 2932  break;
 2933    }
 2934  } while(1);
 2935 
 2936  /* >>> interpret *status */;
 2937 
 2938  return(1);
 2939 }
 2940 
 2941 
 2942 int Xorriso_make_argv_with_null(struct XorrisO *xorriso,
 2943                                 int in_argc, char **in_argv,
 2944                                 int *argc, char ***argv, int flag)
 2945 {
 2946  int i, ret= 0;
 2947 
 2948  *argv= NULL;
 2949  Xorriso_alloc_meM(*argv, char *, in_argc + 1);
 2950  for(i= 0; i < in_argc; i++) {
 2951    Xorriso_alloc_meM((*argv)[i], char, strlen(in_argv[i]) + 1);
 2952    strcpy((*argv)[i], in_argv[i]);
 2953    *argc= i + 1;
 2954  }
 2955  (*argv)[in_argc]= NULL;
 2956  ret= 1;
 2957 ex:;
 2958  if(ret <= 0)
 2959    Sfile_destroy_argv(argc, argv, 0);
 2960  return(ret);
 2961 }
 2962 
 2963 
 2964 /*
 2965   @param flag bit0= use env_path to find the desired program
 2966               bit1= use in_argv rather than parsing cmd to words
 2967               bit2= -reserved-
 2968               bit3= demand absolute cmd path
 2969 return:
 2970  <=0 : error
 2971  1   : done
 2972 */
 2973 int Xorriso_execv(struct XorrisO *xorriso, char *cmd,
 2974                   int in_argc, char **in_argv, char *env_path,
 2975                   int *stdin_pipe, int *stdout_pipe, pid_t *forked_pid,
 2976                   int *status, int flag)
 2977 {
 2978  int ret, argc= 0, has_slash;
 2979  char **argv= NULL, *pathlist= NULL, *cpt, *npt, *prog= NULL;
 2980  pid_t child_pid;
 2981  struct stat stbuf;
 2982 
 2983  Xorriso_alloc_meM(prog, char, 5 * SfileadrL);
 2984 
 2985  wait3(NULL,WNOHANG,NULL); /* just to remove any old dead child */
 2986 
 2987  if(flag & 2) {
 2988    ret= Xorriso_make_argv_with_null(xorriso, in_argc, in_argv,
 2989                                     &argc, &argv, 0);
 2990  } else {
 2991    ret= Sfile_make_argv("", cmd, &argc, &argv, 1|4|128);
 2992  }
 2993  if(ret <= 0)
 2994    goto ex;
 2995  if(argc < 1)
 2996    {ret= 0; goto ex;}
 2997 
 2998  strcpy(prog, argv[0]);
 2999  has_slash= (strchr(argv[0], '/') != NULL);
 3000  if((flag & 8) && !has_slash) {
 3001    sprintf(xorriso->info_text, "External program path contains no '/': ");
 3002    Text_shellsafe(argv[0], xorriso->info_text, 1);
 3003    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
 3004    ret= 0; goto ex;
 3005  }
 3006  if((flag & 1) && !has_slash) {
 3007      if(env_path == NULL)
 3008        env_path= "/bin:/sbin";
 3009      else if(env_path[0] == 0)
 3010        env_path= "/bin:/sbin";
 3011      if(Sregex_string(&pathlist, env_path, 0) <= 0)
 3012        {ret= -1; goto ex;}
 3013      for(cpt= npt= pathlist; npt != NULL; cpt= npt + 1) {
 3014        npt= strchr(cpt, ':');
 3015        if(npt != NULL)
 3016          *npt= 0;
 3017        if(strlen(cpt) + strlen(argv[0]) + 1 >= SfileadrL)
 3018          {ret= -1; goto ex;}
 3019        sprintf(prog, "%s/%s", cpt, argv[0]);
 3020        ret= stat(prog, &stbuf);
 3021        if(ret != -1)
 3022      break;
 3023        prog[0]= 0;
 3024      }
 3025      if(prog[0] == 0) {
 3026        sprintf(xorriso->info_text, "Cannot find external program ");
 3027        Text_shellsafe(argv[0], xorriso->info_text, 1);
 3028        Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
 3029        ret= 0; goto ex;
 3030      }
 3031    }
 3032 
 3033  child_pid= fork();
 3034  if(child_pid==-1) 
 3035    {ret= -1; goto ex;}
 3036 
 3037  if(child_pid==0) {
 3038                      /* this is the child process */
 3039 
 3040    sprintf(xorriso->info_text, "Executing external program ");
 3041    Text_shellsafe(prog, xorriso->info_text, 1);
 3042    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
 3043    Xorriso_destroy(&xorriso, 0); /* reduce memory foot print */
 3044 
 3045    if(stdin_pipe != NULL) {
 3046      close(0);
 3047      if(dup2(stdin_pipe[0], 0) == -1)
 3048             { perror("dup2(,0)"); exit(1); }
 3049      close(stdin_pipe[1]); /* unused */
 3050    }
 3051    if(stdout_pipe != NULL) {
 3052      close(1);
 3053      if(dup2(stdout_pipe[1], 1) == -1)
 3054             { perror("dup2(,1)"); exit(1); }
 3055      close(stdout_pipe[0]); /* unused */
 3056    }
 3057 
 3058    execv(prog, argv); /* should never come back */
 3059    fprintf(stderr,"--- execution of shell command failed:\n");
 3060    fprintf(stderr,"    %s\n",cmd);
 3061    exit(127);
 3062  }
 3063 
 3064 
 3065          /* this is the original process waiting for child to exit */
 3066 
 3067  if(stdin_pipe != NULL)
 3068    close(stdin_pipe[0]); /* unused */
 3069  if(stdout_pipe != NULL)
 3070    close(stdout_pipe[1]); /* unused */
 3071  if(stdin_pipe != NULL || stdout_pipe != NULL) {
 3072    /* Pipes need to be fed by the caller who later calls Xorriso_wait_child_end
 3073       with *forked_pid as child_pid.
 3074    */
 3075    *forked_pid= child_pid;
 3076    {ret= 1; goto ex;}
 3077  }
 3078 
 3079  ret= Xorriso_wait_child_end(xorriso, child_pid, status, 0);
 3080  if(ret <= 0)
 3081    goto ex;
 3082  ret= 1;
 3083 ex:
 3084  Sfile_make_argv("", "", &argc, &argv, 2);
 3085  Sregex_string(&pathlist, NULL, 0);
 3086  Xorriso_free_meM(prog);
 3087  return(ret);
 3088 }
 3089 
 3090 
 3091 /* @param flag bit0= use env_path to find the desired program
 3092                bit1= use in_argv rather than parsing cmd to words
 3093                bit2= "r" rather than "w"
 3094                bit3= demand absolute cmd path
 3095                bit4= override any restriction on external filters
 3096 */
 3097 int Xorriso_pipe_open(struct XorrisO *xorriso, char *purpose, char *cmd,
 3098                       int in_argc, char **in_argv, char *env_path,
 3099                       int *fd, pid_t *forked_pid, int flag)
 3100 {
 3101  int fp_pipe[2], *stdin_pipe= NULL, *stdout_pipe= NULL, status, ret;
 3102 
 3103  *fd= -1;
 3104 
 3105  if(!(flag & 16)) {
 3106    ret= Xorriso_external_filter_banned(xorriso, purpose, 0);
 3107    if(ret)
 3108      return(0);
 3109  }
 3110  if(pipe(fp_pipe) != 0) {
 3111    sprintf(xorriso->info_text, "Cannot create pipe(2) object");
 3112    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FATAL", 0);
 3113    return(0);
 3114  }
 3115  if(flag & 4) {
 3116    stdout_pipe= fp_pipe;
 3117    *fd= fp_pipe[0];
 3118  } else {
 3119    stdin_pipe= fp_pipe;
 3120    *fd= fp_pipe[1];
 3121  }
 3122  ret= Xorriso_execv(xorriso, cmd, in_argc, in_argv, env_path,
 3123                     stdin_pipe, stdout_pipe, forked_pid, &status, flag & 11);
 3124  return(ret);
 3125 }
 3126 
 3127 
 3128 /* @param flag bit0= path is a command parameter
 3129 */
 3130 int Xorriso_path_is_excluded(struct XorrisO *xorriso, char *path, int flag)
 3131 {
 3132  int ret;
 3133 
 3134  if(!(xorriso->disk_excl_mode&1)) /* exclusion is off */
 3135    return(0);
 3136  if((flag&1) && !(xorriso->disk_excl_mode&2)) /* params are exempted */
 3137    return(0);
 3138  ret= Exclusions_match(xorriso->disk_exclusions, path,
 3139                        !!(xorriso->disk_excl_mode&4));
 3140  if(ret<0) {
 3141    sprintf(xorriso->info_text,
 3142            "Error during disk file exclusion decision");
 3143    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
 3144  }
 3145  if(ret>0 && (flag&1)) {
 3146    sprintf(xorriso->info_text, "Disk path parameter excluded by %s : ",
 3147           (ret==1 ? "-not_paths" : "-not_leaf"));
 3148    Text_shellsafe(path, xorriso->info_text, 1);
 3149    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
 3150  }
 3151  return(ret);
 3152 }
 3153 
 3154 
 3155 int Xorriso_path_is_hidden(struct XorrisO *xorriso, char *path, int flag)
 3156 {
 3157  int ret, hide_attrs= 0;
 3158 
 3159  ret= Exclusions_match(xorriso->iso_rr_hidings, path, 0);
 3160  if(ret < 0) {
 3161 failure:;
 3162    sprintf(xorriso->info_text, "Error during disk file hiding decision");
 3163    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
 3164    return(-1);
 3165  }
 3166  if(ret > 0)
 3167    hide_attrs|= 1;
 3168  ret= Exclusions_match(xorriso->joliet_hidings, path, 0);
 3169  if(ret < 0)
 3170    goto failure;
 3171  if(ret > 0)
 3172    hide_attrs|= 2;
 3173  ret= Exclusions_match(xorriso->hfsplus_hidings, path, 0);
 3174  if(ret < 0)
 3175    goto failure;
 3176  if(ret > 0)
 3177    hide_attrs|= 4;
 3178  return(hide_attrs);
 3179 }
 3180 
 3181 
 3182 /* Normalize ACL and sort apart "access" ACL from "default" ACL.
 3183  */
 3184 int Xorriso_normalize_acl_text(struct XorrisO *xorriso, char *in_text,
 3185                      char **access_acl_text, char **default_acl_text, int flag)
 3186 {
 3187  int ret, access_count= 0, default_count= 0, pass, is_default, line_len;
 3188  int was_error= 0, line_count= 0, perms;
 3189  char *acl_text= NULL, *cpt, *npt, *access_wpt= NULL, *default_wpt= NULL; 
 3190  char *dpt= NULL, *ddpt= NULL, **wpt, *ppt;
 3191 
 3192  if(in_text[0] == 0 || strcmp(in_text, "clear") == 0 ||
 3193     strcmp(in_text, "--remove-all") == 0) {
 3194    *access_acl_text= *default_acl_text= NULL;
 3195    return(1);
 3196  } else if (strcmp(in_text, "--remove-default") == 0) {
 3197 
 3198    /* >>> protect Access-ACL and delete Default-ACL */;
 3199 
 3200    /* <<< */
 3201    return(0);
 3202    
 3203  }
 3204 
 3205  acl_text= strdup(in_text);
 3206  if(acl_text == NULL) {
 3207    Xorriso_no_malloc_memory(xorriso, NULL, 0);
 3208    {ret= -1; goto ex;}
 3209  }
 3210 
 3211  /* From comma to newline */
 3212  for(cpt= strchr(acl_text, ','); cpt != NULL; cpt= strchr(cpt + 1, ','))
 3213    *cpt= '\n';
 3214 
 3215  /* Normalize to long text form
 3216     and sort apart "access" ACL from "default" ACL */;
 3217  for(pass= 0; pass < 2; pass++) {
 3218    line_count= 0;
 3219    for(cpt= acl_text; cpt != NULL; cpt= npt) {
 3220      line_count++;
 3221      npt= strchr(cpt, '\n');
 3222      if(npt != NULL)
 3223        npt++;
 3224      if(*cpt == '#' || *cpt == '\n' || *cpt == 0)
 3225    continue;
 3226 
 3227      is_default= 0;
 3228      wpt= &access_wpt;
 3229      if(*cpt == 'd') {
 3230        is_default= 1;
 3231        if(pass == 1)
 3232          wpt= &default_wpt;
 3233        cpt= strchr(cpt, ':');
 3234        if(cpt == NULL) {
 3235          was_error= line_count;
 3236    continue;
 3237        }
 3238        cpt++;
 3239      } 
 3240 
 3241      line_len= 0;
 3242      dpt= strchr(cpt, ':');
 3243      if(dpt != NULL)
 3244        ddpt= strchr(dpt + 1, ':');
 3245      if(dpt == NULL || ddpt == NULL) {
 3246        was_error= line_count;
 3247    continue;
 3248      }
 3249      if(*cpt == 'u') {
 3250        if(pass == 0) {
 3251          line_len+= 5;
 3252          line_len+= ddpt - dpt;
 3253        } else {
 3254          strcpy(*wpt, "user:");
 3255          strncpy(*wpt + 5, dpt + 1, ddpt - dpt);
 3256          (*wpt)+= 5 + (ddpt - dpt);
 3257        }
 3258      } else if(*cpt == 'g') {
 3259        if(pass == 0) {
 3260          line_len+= 6 + (ddpt - dpt);
 3261        } else {
 3262          strcpy(*wpt, "group:");
 3263          strncpy(*wpt + 6, dpt + 1, ddpt - dpt);
 3264          (*wpt)+= 6 + (ddpt - dpt);
 3265        }
 3266      } else if(*cpt == 'o') {
 3267        if(pass == 0) {
 3268          if(ddpt - dpt > 1) {
 3269            was_error= line_count;
 3270    continue;
 3271          }
 3272          line_len+= 6 + (ddpt - dpt);
 3273        } else {
 3274          strcpy(*wpt, "other:");
 3275          strncpy(*wpt + 6, dpt + 1, ddpt - dpt);
 3276          (*wpt)+= 6 + (ddpt - dpt);
 3277        }
 3278      } else if(*cpt == 'm') {
 3279        if(pass == 0) {
 3280          if(ddpt - dpt > 1) {
 3281            was_error= line_count;
 3282    continue;
 3283          }
 3284          line_len+= 5 + (ddpt - dpt);
 3285        } else {
 3286          strcpy(*wpt, "mask:");
 3287          strncpy(*wpt + 5, dpt + 1, ddpt - dpt);
 3288          (*wpt)+= 5 + (ddpt - dpt);
 3289        }
 3290 
 3291      } else {
 3292        /* Unknown tag type */
 3293        was_error= line_count;
 3294    continue;
 3295      }
 3296 
 3297      /* Examine permissions at ddpt + 1 */;
 3298      perms= 0;
 3299      for(ppt= ddpt + 1; *ppt != 0 && *ppt != '\n'; ppt++) {
 3300        if(*ppt == 'r')
 3301          perms|= 4;
 3302        else if(*ppt == 'w')
 3303          perms|= 2;
 3304        else if(*ppt == 'x')
 3305          perms|= 1;
 3306        else if(*ppt == '-' || *ppt == ' ' || *ppt == '\t')
 3307          ;
 3308        else if(*ppt == '#')
 3309      break;
 3310        else {
 3311          was_error= line_count;
 3312      break;
 3313        }
 3314      }
 3315      if(pass == 0) {
 3316        line_len+= 4;
 3317      } else {
 3318        sprintf(*wpt, "%c%c%c\n",
 3319           perms & 4 ? 'r' : '-', perms & 2 ? 'w' : '-', perms & 1 ? 'x' : '-');
 3320        (*wpt)+= 4;
 3321      }
 3322 
 3323      if(pass == 0) {
 3324        if(is_default)
 3325          default_count+= line_len;
 3326        else
 3327          access_count+= line_len;
 3328      }
 3329    }
 3330 
 3331    if(pass == 0) {
 3332      *access_acl_text= calloc(access_count + 1, 1);
 3333      *default_acl_text= calloc(default_count + 1, 1);
 3334      if(*access_acl_text == NULL || *default_acl_text == NULL) {
 3335        Xorriso_no_malloc_memory(xorriso, access_acl_text, 0);
 3336        {ret= -1; goto ex;}
 3337      }
 3338      access_wpt= *access_acl_text;
 3339      default_wpt= *default_acl_text;
 3340    } else {
 3341      *access_wpt= 0;
 3342      *default_wpt= 0;
 3343    }
 3344  }
 3345 
 3346  ret= 1;
 3347 ex:;
 3348  if(acl_text != NULL)
 3349    free(acl_text);
 3350  if(was_error) {
 3351    sprintf(xorriso->info_text,
 3352            "Malformed ACL entries encountered. Last one in line number %d.",
 3353            was_error);
 3354    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
 3355    return(0);
 3356  }
 3357  return(ret);
 3358 }
 3359