You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3209 lines
94 KiB

/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2015 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
This file contains the implementation of functions which deal with parsing
and interpretation of command input.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <ctype.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <time.h>
#include <fcntl.h>
#include <errno.h>
#include <pwd.h>
#include <grp.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include "xorriso.h"
#include "xorriso_private.h"
#include "xorrisoburn.h"
#ifdef Xorriso_fetch_with_msg_queueS
#include <pthread.h>
#endif
/* @param flag bit0= do not warn of wildcards
bit1= these are disk_paths
*/
int Xorriso_end_idx(struct XorrisO *xorriso,
int argc, char **argv, int idx, int flag)
{
int i, warned= 0;
for(i= idx; i<argc; i++) {
if(strcmp(argv[i], xorriso->list_delimiter)==0)
break;
if(!((flag&1) || warned))
warned= Xorriso_warn_of_wildcards(xorriso, argv[i], flag&2);
}
return(i);
}
/* Returns a vector of strings which belong to an open ended arg list.
If expansion is enabled, the vector might be allocated, else it is
a pointer into the argv input vector.
Thus the release of that memory is an expert task to be done by this
function only. Use bit8 for that. With bit8 parameter argc MUST be the
same value as with the call which might have allocated memory.
@param xorriso The environment object
@param argc Length of argv
@param argv The vector with arguments, eventual list_delimiter ("--")
and then eventual unrelated words
@param idx Start index in argv of the argument list
@param optc Length of the effective possibly expanded option vector
@param optv The option vector. Maybe a pointer into argv or maybe
an own allocated vector.
@param flag bit0= do not warn of wildcards
bit1= these are disk_paths
bit2= never expand wildcards
bit3= do not expand last argument
bit4= ignore last argument
bit5= demand exactly one match
bit6= with bit5 allow 0 matches if pattern is a constant
bit7= silently tolerate empty argument list
bit8= free the eventually allocated sub_vector
bit9= always expand wildcards
*/
int Xorriso_opt_args(struct XorrisO *xorriso, char *cmd,
int argc, char **argv, int idx,
int *end_idx, int *optc, char ***optv, int flag)
{
int i, do_expand, nump, was_empty= 0, filec= 0, ret;
char **filev= NULL, **patterns= NULL;
off_t mem= 0;
if(flag&2)
do_expand= (xorriso->do_disk_pattern==1 && !(flag&4)) || (flag & 512);
else
do_expand= (xorriso->do_iso_rr_pattern==1 && !(flag&4)) || (flag & 512);
if(flag&256) {
if(*optv < argv || (*optv >= argv + argc && argc > 0))
Sfile_destroy_argv(optc, optv, 0);
return(1);
}
if(idx>=argc) {
*end_idx= argc;
*optc= 0;
*optv= NULL;
sprintf(xorriso->info_text, "%s : Not enough arguments given", cmd);
if((flag & 128))
return(1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
return(0);
}
*end_idx= Xorriso_end_idx(xorriso, argc, argv, idx,
((flag&1) || do_expand) | (flag&2));
if(*end_idx<0)
return(*end_idx);
if((flag&16) && (*end_idx)>idx)
(*end_idx)--;
*optc= *end_idx - idx;
*optv= argv+idx;
if(*optc<=0 || !do_expand)
return(1);
patterns= calloc(*optc, sizeof(char *));
if(patterns==NULL) {
no_memory:;
sprintf(xorriso->info_text,
"%s : Cannot allocate enough memory for pattern expansion", cmd);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
{ret= -1; goto ex;}
}
nump= 0;
if(flag&8) {
was_empty= 1;
mem+= strlen(argv[idx + *optc - 1])+1+sizeof(char *);
}
for(i= 0; i<*optc-!!(flag&8); i++) {
if(argv[i + idx][0]==0) {
was_empty++;
mem+= sizeof(char *); /* as upper limit for size of an empty string */
continue;
}
patterns[nump++]= argv[i + idx];
}
if(nump<=0) { /* Only empty texts. May the caller get happy with them. */
free(patterns);
return(1);
}
if(flag&2)
ret= Xorriso_expand_disk_pattern(xorriso, nump, patterns, was_empty,
&filec, &filev, &mem, (flag>>5)&3);
else
ret= Xorriso_expand_pattern(xorriso, nump, patterns, was_empty,
&filec, &filev, &mem, (flag>>5)&3);
if(ret<=0)
{ret= 0; goto ex;}
for(i= 0; i<was_empty; i++) {
if(i==was_empty-1 && (flag&8))
filev[filec++]= strdup(argv[idx + *optc - 1]);
else
filev[filec++]= strdup("");
if(filev[filec-1]==NULL)
goto no_memory;
}
#ifdef Xorriso_verbous_pattern_expansioN
{ int l;
sprintf(xorriso->info_text, "Pattern expansion yields %d items:", filec);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
l= 0;
xorriso->info_text[0]= 0;
for(i= 0; i<filec; i++) {
l= strlen(xorriso->info_text);
if(l>0 && l+1+strlen(filev[i])>60) {
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
xorriso->info_text[0]= 0;
l= 0;
}
sprintf(xorriso->info_text+l, " %s", filev[i]);
}
l= strlen(xorriso->info_text);
if(l>0)
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
}
#endif /* Xorriso_verbous_pattern_expansioN */
ret= 1;
ex:;
if(patterns!=NULL)
free((char *) patterns);
if(ret<=0) {
Sfile_destroy_argv(&filec, &filev, 0);
} else {
*optc= filec;
*optv= filev;
}
return(ret);
}
/* @param flag bit0= get eternal problem status
*/
int Xorriso_get_problem_status(struct XorrisO *xorriso, char severity[80],
int flag)
{
if(flag & 1) {
strcpy(severity, xorriso->eternal_problem_status_text);
return(xorriso->eternal_problem_status);
} else {
strcpy(severity, xorriso->problem_status_text);
return(xorriso->problem_status);
}
}
/* @param flag bit0= set eternal problem status to severity,
and set problem status to ALL
*/
int Xorriso_set_problem_status(struct XorrisO *xorriso, char *severity,
int flag)
{
char *sev_text= "ALL";
int sev, ret;
#ifdef Xorriso_fetch_with_msg_queueS
int locked= 0, uret;
static int complaints= 0, complaint_limit= 5;
#endif
if(severity[0])
sev_text= severity;
ret= Xorriso__text_to_sev(sev_text, &sev, 0);
if(ret<=0)
return(0);
#ifdef Xorriso_fetch_with_msg_queueS
ret= pthread_mutex_lock(&(xorriso->problem_status_lock));
if(ret != 0) {
/* Cannot report failure through the failing message output system */
complaints++;
if(complaints < complaint_limit)
fprintf(stderr,
"xorriso : pthread_mutex_lock() for problem_status returns %d\n",
ret);
} else
locked= 1;
#endif /* Xorriso_fetch_with_msg_queueS */
if(flag & 1) {
strcpy(xorriso->problem_status_text, "ALL");
Xorriso__text_to_sev(xorriso->problem_status_text,
&(xorriso->problem_status), 0);
} else {
xorriso->problem_status= sev;
strcpy(xorriso->problem_status_text, sev_text);
}
if(sev > xorriso->eternal_problem_status || (flag & 1)) {
xorriso->eternal_problem_status= sev;
strcpy(xorriso->eternal_problem_status_text, sev_text);
}
#ifdef Xorriso_fetch_with_msg_queueS
if(locked) {
uret= pthread_mutex_unlock(&(xorriso->problem_status_lock));
if(uret != 0) {
/* Cannot report failure through the failing message output system */
complaints++;
if(complaints < complaint_limit)
fprintf(stderr,
"xorriso : pthread_mutex_unlock() for problem_status returns %d\n",
uret);
}
}
#endif /* Xorriso_fetch_with_msg_queueS */
return(1);
}
/**
@param flag bit0= do not issue own event messages
bit1= take xorriso->request_to_abort as reason for abort
@return Gives the advice:
2= pardon was given, go on
1= no problem, go on
0= function failed but xorriso would not abort, go on
<0= do abort
-1 = due to problem_status
-2 = due to xorriso->request_to_abort
*/
int Xorriso_eval_problem_status(struct XorrisO *xorriso, int ret, int flag)
{
static int sev= 0;
if(sev==0)
Xorriso__text_to_sev("SORRY", &sev, 0);
if((flag&2) && xorriso->request_to_abort)
return(-2);
Xorriso_process_msg_queues(xorriso, 0);
if(ret>0 && xorriso->problem_status <= 0)
return(1);
if(xorriso->problem_status < xorriso->abort_on_severity &&
xorriso->problem_status > 0) {
if(xorriso->problem_status >= sev && !(flag&1)) {
sprintf(xorriso->info_text,
"xorriso : NOTE : Tolerated problem event of severity '%s'\n",
xorriso->problem_status_text);
Xorriso_info(xorriso, 0);/* submit not as problem event */
}
ret= 2;
} else if(xorriso->problem_status > 0) {
sprintf(xorriso->info_text,
"xorriso : aborting : -abort_on '%s' encountered '%s'\n",
xorriso->abort_on_text, xorriso->problem_status_text);
if(!(flag&1))
Xorriso_info(xorriso, 0);/* submit not as problem event */
ret= -1;
} else if(ret>0)
ret= 1;
else
ret= 2;
return(ret);
}
/* @param flag bit0= a non-existing target of multiple sources is a directory
bit1= all paths except the last one are disk_paths
bit2= the last path is a disk_path
@return <=0 is error, 1= leaf file object, 2= directory
*/
int Xorriso_cpmv_args(struct XorrisO *xorriso, char *cmd,
int argc, char **argv, int *idx,
int *optc, char ***optv, char eff_dest[SfileadrL],
int flag)
{
int destc= 0, is_dir=0, end_idx, ret, i;
char **destv= NULL;
end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx,
(xorriso->do_iso_rr_pattern==1)|(flag&2));
if(end_idx - *idx < 2) {
sprintf(xorriso->info_text, "%s: not enough arguments", cmd);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
{ret= 0; goto ex;}
}
ret= Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, optc, optv,
1 | (flag&2) | 16); /* ignore last argument */
if(ret<=0)
goto ex;
/* demand one match, or 0 with a constant */
ret= Xorriso_opt_args(xorriso, cmd, argc, argv, end_idx, &end_idx, &destc,
&destv, 1 | ((flag&4)>>1) | 32 | 64);
if(ret<=0)
goto ex;
/* Evaluate target address */
if(flag&4)
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, destv[0], eff_dest,
2|4|16);
else
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, destv[0], eff_dest,
1);
if(ret<0)
{ret= 0; goto ex;}
if(ret==2 || ((flag&1) && *optc > 1 && ret==0)) {
is_dir= 1;
} else if(*optc > 1) {
if(flag & 2)
for(i= 0; i<*optc; i++)
Xorriso_msgs_submit(xorriso, 0, (*optv)[i], 0, "ERRFILE", 0);
sprintf(xorriso->info_text,
"%s: more than one origin given, destination is a non-directory: ",
cmd);
Text_shellsafe(destv[0], xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
{ret= 0; goto ex;}
}
if(ret==0) { /* compute complete eff_dest */
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, destv[0], eff_dest,
2 | (flag&4));
if(ret<0)
{ret= 0; goto ex;}
}
ret= 1+is_dir;
ex:;
Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, &destc, &destv,
256);
(*idx)= end_idx;
return(ret);
}
/* @param flag bit0= with adr_mode sbsector: adr_value is possibly 16 too high
*/
int Xorriso_decode_load_adr(struct XorrisO *xorriso, char *cmd,
char *adr_mode, char *adr_value,
int *entity_code, char entity_id[81],
int flag)
{
double num;
int l;
if(strcmp(adr_mode, "auto")==0)
*entity_code= 0;
else if(strcmp(adr_mode, "session")==0)
*entity_code= 1;
else if(strcmp(adr_mode, "track")==0)
*entity_code= 2;
else if(strcmp(adr_mode, "lba")==0 || strcmp(adr_mode, "sbsector")==0)
*entity_code= 3 | ((flag&1) << 16);
else if(strcmp(adr_mode, "volid")==0)
*entity_code= 4;
else {
sprintf(xorriso->info_text, "%s: unknown address mode '%s'", cmd, adr_mode);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
l= strlen(adr_value);
if(l==0)
*entity_code= 0;
if(*entity_code>=1 && *entity_code<= 3) {
num= Scanf_io_size(adr_value, 0);
if(*entity_code==3 &&
(adr_value[l-1]<'0' || adr_value[l-1]>'9'))
num/= 2048.0;
sprintf(entity_id, "%.f", num);
} else {
if(strlen(adr_value)>80) {
sprintf(xorriso->info_text, "%s: address value too long (80 < %d)",
cmd, (int) strlen(adr_value));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
strcpy(entity_id, adr_value);
}
return(1);
}
int Xorriso_check_name_len(struct XorrisO *xorriso, char *name, int size,
char *cmd, int flag)
{
if((int) strlen(name) >= size) {
sprintf(xorriso->info_text,
"Name too long with option %s (%d > %d)", cmd,
(int) strlen(name), size - 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
return(0);
}
return(1);
}
/* @return <0 error , >=0 number of skipped dashes
*/
int Xorriso_normalize_command(struct XorrisO *xorriso, char *original_cmd,
int argno, char *cmd_data, int sizeof_cmd_data,
char **cmd, int flag)
{
int was_dashed= 0;
char *dash_pt;
if((int) strlen(original_cmd) >= sizeof_cmd_data) {
if(argno>=0)
sprintf(xorriso->info_text, "Oversized argument #%d (length %d)\n",
argno, (int) strlen(original_cmd));
else
sprintf(xorriso->info_text, "Oversized option (length %d)\n",
(int) strlen(original_cmd));
return(-1);
}
strcpy(cmd_data, original_cmd);
*cmd= cmd_data;
if(strcmp(*cmd, xorriso->list_delimiter)==0)
return(1);
while((*cmd)[0]=='-') {
if((*cmd)[1]==0)
break;
was_dashed++;
(*cmd)++;
}
for(dash_pt= *cmd; *dash_pt!=0; dash_pt++)
if(*dash_pt=='-')
*dash_pt= '_';
return(was_dashed);
}
/* @param flag bit0= do not warn of unknown option
@return <=0 error,
1=count is valid, 2=dashed unknown, 3=undashed unknown
*/
int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv,
int *count, int flag)
{
int ret, was_dashed= 0, i, cmd_data_size= 2 * SfileadrL;
char *cmd, *cmd_data= NULL;
static char arg0_commands[][40]= {
"ban_stdio_write","close_filter_list","commit",
"device_links","devices","end",
"for_backup", "help",
"list_arg_sorting","list_formats","list_speeds",
"no_rc","print_size","pvd_info","pwd","pwdi","pwdx",
"read_mkisofsrc","rollback","rollback_end",
"tell_media_space","toc","version",
""
};
static char arg1_commands[][40]= {
"abort_on","acl","add_plainly","application_id","application_use",
"auto_charset","abstract_file",
"backslash_codes","blank","biblio_file",
"calm_drive","cd","cdi","cdx","changes_pending","charset",
"close","close_damaged",
"commit_eject","compliance","copyright_file",
"dev","dialog","disk_dev_ino","disk_pattern","displacement",
"dummy","dvd_obs","early_stdio_test","ecma119_map","eject",
"iso_rr_pattern","file_name_limit","follow","format","fs",
"gid","grow_blindly","hardlinks",
"hfsplus","history","indev","in_charset","joliet",
"list_delimiter","list_extras","list_profiles","local_charset",
"mark","md5","mount_opts","modesty_on_drive",
"not_leaf","not_list","not_mgt",
"options_from_file","osirrox","outdev","out_charset","overwrite",
"pacifier","padding","path_list","pathspecs","pkt_output",
"preparer_id","print","print_info","print_mark","prompt",
"prog","prog_help","publisher","quoted_not_list","quoted_path_list",
"read_speed","reassure","report_about",
"report_el_torito","report_system_area","rockridge",
"rom_toc_scan","rr_reloc_dir","scsi_log",
"session_log","sh_style_result","signal_handling","sleep",
"speed","split_size","status","status_history_max",
"stdio_sync","stream_recording","system_id","temp_mem_limit","toc_of",
"uid","unregister_filter","use_readline","volid","volset_id",
"write_type","xattr","zisofs",
""
};
static char arg2_commands[][40]= {
11 years ago
"assert_volid","boot_image","clone","compare","compare_r","drive_class",
"data_cache_size",
"errfile_log","error_behavior","extract","extract_single",
"jigdo","lns","lnsi","load","logfile",
"map","map_single","move","msg_op","page","return_with",
"scdbackup_tag","update","update_r","volume_date",
""
};
static char arg3_commands[][40]= {
"append_partition",
""
};
static char arg4_commands[][40]= {
"cut_out","extract_cut","mount","mount_cmd","named_pipe_loop",
"paste_in","session_string",
""
};
static char argn_commands[][40]= {
"add","alter_date","alter_date_r","as",
"check_md5","check_md5_r","check_media","check_media_defaults",
"chgrp","chgrpi","chgrp_r","chgrp_ri","chmod","chmodi",
"chmod_r","chmod_ri","chown","chowni","chown_r","chown_ri",
"compare_l","concat","cp_clone","cp_rax","cp_rx","cpr","cpri","cpax","cpx",
"du","dui","dus","dusi","dux","dusx","external_filter","extract_l",
"file_size_limit","find","findi","finds","findx",
"getfacl","getfacli","getfacl_r","getfacl_ri",
12 years ago
"getfattr","getfattri","getfattr_r","getfattr_ri","hide",
"launch_frontend","ls","lsi","lsl","lsli","lsd","lsdi","lsdl","lsdli",
"lsx","lslx","lsdx","lsdlx","map_l","mv","mvi","mkdir","mkdiri",
"not_paths","rm","rmi","rm_r","rm_ri","rmdir","rmdiri","update_l",
"setfacl","setfacli","setfacl_list","setfacl_listi",
"setfacl_r","setfacl_ri","setfattr","setfattri",
"setfattr_list","setfattr_listi","setfattr_r","setfattr_ri",
"set_filter","set_filter_r","show_stream","show_stream_r",
""
};
Xorriso_alloc_meM(cmd_data, char, cmd_data_size);
*count= 0;
if(argc<=0)
{ret= -1; goto ex;}
ret= Xorriso_normalize_command(xorriso, argv[0], -1,
cmd_data, cmd_data_size, &cmd, 0);
if(ret<0)
goto ex;
was_dashed= (ret>0);
if(cmd[0]=='#' || cmd[0]==0 || strcmp(cmd, xorriso->list_delimiter) == 0) {
/* ignore: comment line , empty option , orphaned list delimiter */
{ret= 1; goto ex;}
}
for(i=0; arg0_commands[i][0]!=0; i++)
if(strcmp(arg0_commands[i], cmd)==0)
{ret= 1; goto ex;}
*count= 1;
for(i=0; arg1_commands[i][0]!=0; i++)
if(strcmp(arg1_commands[i], cmd)==0)
{ret= 1; goto ex;}
*count= 2;
for(i=0; arg2_commands[i][0]!=0; i++)
if(strcmp(arg2_commands[i], cmd)==0)
{ret= 1; goto ex;}
*count= 3;
for(i=0; arg3_commands[i][0]!=0; i++)
if(strcmp(arg3_commands[i], cmd)==0)
{ret= 1; goto ex;}
*count= 4;
for(i=0; arg4_commands[i][0]!=0; i++)
if(strcmp(arg4_commands[i], cmd)==0)
{ret= 1; goto ex;}
*count= 0;
for(i=0; argn_commands[i][0]!=0; i++)
if(strcmp(argn_commands[i], cmd)==0) {
ret= Xorriso_end_idx(xorriso, argc, argv, 1, 1);
if(ret<1)
goto ex;
*count= ret-1;
{ret= 1; goto ex;}
}
if(!(flag&1)) {
sprintf(xorriso->info_text, "Unknown option : '%s'", argv[0]);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
}
ret= 2 + !was_dashed;
ex:
Xorriso_free_meM(cmd_data);
return(ret);
}
/* @param flag bit0= list sorting order rather than looking for argv[idx]
*/
int Xorriso_cmd_sorting_rank(struct XorrisO *xorriso,
int argc, char **argv, int idx, int flag)
{
int ret, i, cmd_data_size= 2 * SfileadrL;
char *cmd, *cmd_data= NULL;
static char *commands[]= {
"* Execution order of program arguments with option -x:",
"x",
"* Support for frontend programs via stdin and stdout (1):",
"prog", "prog_help",
"* Exception processing:",
"abort_on", "return_with", "report_about", "signal_handling",
"error_behavior",
"* Scripting, dialog and program control features (1):",
"no_rc", "help", "version", "list_extras", "list_arg_sorting",
"temp_mem_limit", "backslash_codes",
"errfile_log", "session_log", "scsi_log",
"options_from_file", "list_delimiter",
"print", "print_info", "print_mark", "prompt", "sleep",
"sh_style_result",
"* Drive and media related inquiry actions (1):",
"devices", "device_links",
"mount_opts", "mount_cmd", "session_string",
"* Influencing the behavior of image loading:",
"read_speed", "load", "displacement",
"drive_class", "assert_volid", "in_charset",
"auto_charset", "hardlinks", "acl", "xattr", "md5", "for_backup",
"ecma119_map",
"disk_dev_ino", "rom_toc_scan", "calm_drive", "ban_stdio_write",
"early_stdio_test", "data_cache_size",
"* Character sets:",
"charset", "local_charset",
"* Aquiring source and target drive:",
"dev", "indev", "outdev",
"* Drive and media related inquiry actions (2):",
"list_profiles", "list_formats", "list_speeds",
"toc", "toc_of", "pvd_info", "report_system_area", "report_el_torito",
"* Settings for file insertion:",
"file_name_limit", "file_size_limit",
"not_mgt", "not_paths", "not_leaf", "not_list",
"quoted_not_list", "follow", "pathspecs", "overwrite", "split_size",
"* Navigation in ISO image and disk filesystem (1):",
"cd", "cdx", "pwd", "pwdx",
"* Inserting files into ISO image:",
"disk_pattern", "add_plainly",
"mkdir", "lns", "add", "path_list", "quoted_path_list",
"map", "map_single", "map_l", "update", "update_r", "update_l",
"cut_out", "cpr",
"clone", "cp_clone",
"* Navigation in ISO image and disk filesystem (2):",
"ls", "lsd", "lsl", "lsdl", "lsx", "lsdx", "lslx", "lsdlx",
"getfacl", "getfacl_r", "getfattr", "getfattr_r", "du", "dus",
"dux", "dusx", "findx",
"compare", "compare_r", "compare_l", "show_stream", "show_stream_r",
"* File manipulations:",
"iso_rr_pattern",
"rm", "rm_r", "rmdir", "move", "mv",
"chown", "chown_r", "chgrp", "chgrp_r", "chmod", "chmod_r", "setfacl",
"setfacl_r", "setfacl_list", "setfattr", "setfattr_r", "setfattr_list",
"alter_date", "alter_date_r", "hide",
"* Filters for data file content:",
"external_filter", "unregister_filter", "close_filter_list",
"set_filter", "set_filter_r",
"* Tree traversal command -find:",
"find",
"* osirrox ISO-to-disk restore options:",
"osirrox", "extract", "extract_single", "extract_l", "extract_cut",
"cpx", "cpax", "cp_rx", "cp_rax", "paste_in", "concat",
"mount",
"* Settings for result writing:",
"rockridge", "joliet", "hfsplus","compliance", "rr_reloc_dir",
"volid", "volset_id", "publisher",
"application_id", "system_id", "volume_date", "copyright_file",
"abstract_file", "biblio_file", "preparer_id", "application_use",
"out_charset", "read_mkisofsrc",
"uid", "gid", "zisofs", "speed", "stream_recording", "dvd_obs",
"modesty_on_drive",
"stdio_sync", "dummy", "fs", "close", "padding", "write_type",
"grow_blindly", "pacifier", "scdbackup_tag",
"* Bootable ISO images:",
"boot_image", "append_partition",
"* Jigdo Template Extraction:",
"jigdo",
"* Command compatibility emulations:",
"as",
"* Scripting, dialog and program control features (2):",
"history", "status_history_max", "status",
"* Drive and media related inquiry actions (3):",
"print_size", "tell_media_space",
"* Writing the result, drive control:",
"format", "blank", "close_damaged",
"rollback", "changes_pending", "commit", "commit_eject",
"eject",
"* Evaluation of readability and recovery:",
"check_media_defaults", "check_media", "check_md5", "check_md5_r",
"* Support for frontend programs via stdin and stdout (2):",
"pkt_output", "logfile", "mark", "msg_op",
"* Dialog mode control:",
"dialog", "page", "use_readline", "reassure",
"* Support for frontend programs via stdin and stdout (3):",
"launch_frontend", "named_pipe_loop",
"* Scripting, dialog and program control features (3):",
"rollback_end", "end",
""
};
if(flag & 1) {
for(i= 0; commands[i][0] !=0; i++) {
if(commands[i][0] == '*')
sprintf(xorriso->result_line, "#%s\n", commands[i] + 1);
else
sprintf(xorriso->result_line, "-%s\n", commands[i]);
Xorriso_result(xorriso, 0);
}
ret= 1; goto ex;
}
if(argc <= 0)
{ret= -1; goto ex;}
Xorriso_alloc_meM(cmd_data, char, cmd_data_size);
ret= Xorriso_normalize_command(xorriso, argv[idx], -1,
cmd_data, cmd_data_size, &cmd, 0);
if(ret < 0)
goto ex;
if(cmd[0] == '#' || cmd[0] == 0 ||
strcmp(cmd, xorriso->list_delimiter) == 0) {
/* Move to end: comment line , empty option , orphaned list delimiter */
ret= 0x7fffffff; goto ex;
}
for(i= 0; commands[i][0] !=0; i++) {
if(commands[i][0] == '*') /* headline in command list */
continue;
if(strcmp(commands[i], cmd) != 0)
continue;
ret= i + 1; goto ex;
}
ret= 1;
ex:
Xorriso_free_meM(cmd_data);
return(ret);
}
int Xorriso__cmp_cmd_rank(const void *a, const void *b)
{
int ra, rb;
ra= ((int *) a)[1];
rb= ((int *) b)[1];
if(ra < rb)
return(-1);
if(ra > rb)
return(1);
ra= ((int *) a)[2];
rb= ((int *) b)[2];
if(ra < rb)
return(-1);
if(ra > rb)
return(1);
return(0);
}
/* @param flag bit0= print command sequence rather than executing it
bit1= these are command line arguments
(for xorriso->argument_emulation)
*/
int Xorriso_exec_args_sorted(struct XorrisO *xorriso,
int argc, char **argv, int *idx, int flag)
{
int cmd_count= 0, ret, i, arg_count, *idx_rank= NULL, cmd_idx;
/* Count commands and allocate index-rank array */
for(i= *idx; i < argc; i++) {
ret= Xorriso_count_args(xorriso, argc - i, argv + i, &arg_count, 1);
if(ret <= 0)
goto ex;
if(ret != 1)
continue;