New option -backslash_codes for expressing weird file names

This commit is contained in:
Thomas Schmitt 2008-10-17 07:50:35 +00:00
parent d0b53ac018
commit 2fce109cee
5 changed files with 344 additions and 27 deletions

View File

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH XORRISO 1 "Oct 15, 2008"
.TH XORRISO 1 "Oct 16, 2008"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -2198,6 +2198,34 @@ quotation marks.
.br
For brevity the list delimiter is referred as "--" throughout this text.
.TP
\fB\-backslash_codes\fR "on"|"off"|mode[:mode]
Enable or disable the interpretation of symbolic representations of special
characters with quoted input or with program arguments. If enabled the
following translations apply:
.br
\\a=bell(007) \\b=backspace(008) \\e=Escape(033) \\f=formfeed(014)
.br
\\n=linefeed(012) \\r=carriage_return(015) \\t=tab(011)
.br
\\v=vtab(013) \\\\=backslash(134) \\[0-9][0-9][0-9]=octal_code
.br
\\\\x[0-9a-f][0-9a-f]=hex_code \\cC=control-C
.br
Translations can occur with quoted input in 3 modes:
.br
"in_double_quotes" translates only inside " quotation.
.br
"outside_single_quotes" translates not inside ' quotation.
.br
"with_quoted_input" translates all input text.
.br
With the start program arguments there is mode:
.br
"with_program_arguments" translates all program arguments.
.br
Mode "off" is default and disables any translation.
Mode "on" is the same as "with_quoted_input:with_program_arguments".
.TP
\fB\-temp_mem_limit\fR number["k"|"m"]
Set the maximum size of temporary memory to be used for image dependent
buffering. Currently this applies to pattern expansion only.

View File

@ -513,6 +513,130 @@ int Sfile_destroy_argv(int *argc, char ***argv, int flag)
}
/* Converts backslash codes into single characters:
\a BEL 7 , \b BS 8 , \e ESC 27 , \f FF 12 , \n LF 10 , \r CR 13 ,
\t HT 9 , \v VT 11 , \\ \ 92
\[0-9][0-9][0-9] octal code , \x[0-9a-f][0-9a-f] hex code ,
\cX control-x (ascii(X)-64)
@param upto maximum number of characters to examine for backslash.
The scope of a backslash (0 to 3 characters) is not affected.
@param eaten returns the difference in length between input and output
@param flag bit0= only determine *eaten, do not convert
*/
int Sfile_bsl_interpreter(char *text, int upto, int *eaten, int flag)
{
char *rpt, *wpt, num_text[4], wdummy[8];
unsigned int num= 0;
*eaten= 0;
wpt= text;
for(rpt= text; *rpt != 0 && rpt - text < upto; rpt++) {
if(flag & 1)
wpt= wdummy;
if(*rpt == '\\') {
rpt++;
(*eaten)++;
if(*rpt == 'a') {
*(wpt++)= 7;
} else if(*rpt == 'b') {
*(wpt++)= 8;
} else if(*rpt == 'e') {
*(wpt++)= 27;
} else if(*rpt == 'f') {
*(wpt++)= 12;
} else if(*rpt == 'n') {
*(wpt++)= 10;
} else if(*rpt == 'r') {
*(wpt++)= 13;
} else if(*rpt == 't') {
*(wpt++)= 9;
} else if(*rpt == 'v') {
*(wpt++)= 11;
} else if(*rpt == '\\') {
*(wpt++)= '\\';
} else if(rpt[0] >= '0' && rpt[0] <= '9' &&
rpt[1] >= '0' && rpt[1] <= '9' &&
rpt[2] >= '0' && rpt[2] <= '9') {
num_text[0]= *(rpt + 0);
num_text[1]= *(rpt + 1);
num_text[2]= *(rpt + 2);
num_text[3]= 0;
sscanf(num_text, "%o", &num);
if(num > 0 && num <= 255) {
rpt+= 2;
(*eaten)+= 2;
*(wpt++)= num;
} else
goto not_a_code;
} else if(rpt[0] == 'x' &&
((rpt[1] >= '0' && rpt[1] <= '9') ||
(rpt[1] >= 'A' && rpt[1] <= 'F') ||
(rpt[1] >= 'a' && rpt[1] <= 'f'))
&&
((rpt[2] >= '0' && rpt[2] <= '9') ||
(rpt[2] >= 'A' && rpt[2] <= 'F') ||
(rpt[2] >= 'a' && rpt[2] <= 'f'))
) {
num_text[0]= *(rpt + 1);
num_text[1]= *(rpt + 2);
num_text[2]= 0;
sscanf(num_text, "%x", &num);
if(num > 0 && num <= 255) {
rpt+= 2;
(*eaten)+= 2;
*(wpt++)= num;
} else
goto not_a_code;
} else if(*rpt == 'c') {
if(rpt[1] > 64 && rpt[1] < 96) {
*(wpt++)= rpt[1] - 64;
rpt++;
(*eaten)++;
} else
goto not_a_code;
} else {
not_a_code:;
*(wpt++)= '\\';
rpt--;
(*eaten)--;
}
} else
*(wpt++)= *rpt;
}
*wpt= *rpt;
return(1);
}
int Sfile_argv_bsl(int argc, char ***argv, int flag)
{
int i, ret, eaten;
char **new_argv= NULL;
if(argc <= 0)
return(0);
new_argv= (char **) Smem_malloC(argc * sizeof(char *));
if(new_argv == NULL)
return(-1);
for(i= 0; i < argc; i++) {
new_argv[i]= strdup((*argv)[i]);
if(new_argv[i] == NULL)
{ret= -1; goto ex;}
ret= Sfile_bsl_interpreter(new_argv[i], strlen(new_argv[i]), &eaten, 0);
if(ret <= 0)
goto ex;
}
ret= 1;
ex:;
if(ret <= 0) {
if(new_argv != NULL)
free((char *) new_argv);
} else
*argv= new_argv;
return(ret);
}
int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv,
int flag)
/*
@ -521,18 +645,29 @@ int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv,
bit2= abort with return(0) if incomplete quotes are found
bit3= eventually prepend missing '-' to first argument read from line
bit4= like bit2 but only check quote completeness, do not allocate memory
>>>
bit5+6= interpretation of backslashes:
0= no interpretation, leave unchanged
1= only inside double quotes
2= outside single quotes
3= everywhere
*/
{
int i,pass,maxl=0,l,argzaehl=0,bufl,line_start_argc;
int i,pass,maxl=0,l,argzaehl=0,bufl,line_start_argc, bsl_mode, ret= 0, eaten;
char *cpt,*start;
char buf[SfileadrL];
char *buf= NULL;
Sfile_destroy_argv(argc,argv,0);
if(flag&2) return(1);
if(flag&2)
{ret= 1; goto ex;}
if(flag & 16)
flag|= 4;
bsl_mode= (flag >> 5) & 3;
buf= calloc(strlen(line) + SfileadrL, 1);
if(buf == NULL)
{ret= -1; goto ex;}
for(pass=0;pass<2;pass++) {
cpt= line-1;
if(!(flag&1)){
@ -554,32 +689,68 @@ int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv,
if(isspace(*cpt)) break;
if(*cpt=='"'){
l= cpt-start; bufl= strlen(buf);
if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;}
if(l>0) {
strncpy(buf + bufl, start, l); buf[bufl + l]= 0;
if(bsl_mode >= 2) {
ret= Sfile_bsl_interpreter(buf, l, &eaten, 0);
if(ret <= 0)
goto ex;
}
}
l= strlen(buf);
start= cpt+1;
while(*(++cpt)!=0) if(*cpt=='"') break;
if((flag&4) && *cpt==0)
return(0);
{ret= 0; goto ex;}
l= cpt-start; bufl= strlen(buf);
if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;}
if(l>0) {
strncpy(buf + bufl, start, l);
buf[bufl + l]= 0;
if(bsl_mode >= 1) {
ret= Sfile_bsl_interpreter(buf + bufl, l, &eaten, 0);
if(ret <= 0)
goto ex;
}
}
start= cpt+1;
}else if(*cpt=='\''){
l= cpt-start; bufl= strlen(buf);
if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;}
if(l>0) {
strncpy(buf + bufl, start, l); buf[bufl + l]= 0;
if(bsl_mode >= 2) {
ret= Sfile_bsl_interpreter(buf, l, &eaten, 0);
if(ret <= 0)
goto ex;
}
}
l= strlen(buf);
start= cpt+1;
while(*(++cpt)!=0) if(*cpt=='\'') break;
if((flag&4) && *cpt==0)
return(0);
{ret= 0; goto ex;}
l= cpt-start; bufl= strlen(buf);
if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;}
if(l>0) {
strncat(buf,start,l);buf[bufl+l]= 0;
if(bsl_mode >= 3) {
ret= Sfile_bsl_interpreter(buf + bufl, l, &eaten, 0);
if(ret <= 0)
goto ex;
}
}
start= cpt+1;
}
if(*cpt==0) break;
}
l= cpt-start;
bufl= strlen(buf);
if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;}
if(l>0) {
strncpy(buf + bufl, start, l); buf[bufl + l]= 0;
if(bsl_mode >= 2) {
ret= Sfile_bsl_interpreter(buf, l, &eaten, 0);
if(ret <= 0)
goto ex;
}
}
l= strlen(buf);
if(pass==0){
if(argzaehl==line_start_argc && (flag&8))
@ -597,21 +768,25 @@ int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv,
}
if(pass==0){
if(flag & 16)
return(1);
{ret= 1; goto ex;}
*argc= argzaehl;
if(argzaehl>0) {
*argv= (char **) Smem_malloC(argzaehl*sizeof(char *));
if(*argv==NULL)
return(-1);
{ret= -1; goto ex;}
}
for(i=0;i<*argc;i++) {
(*argv)[i]= (char *) Smem_malloC((maxl+1));
if((*argv)[i]==NULL)
return(-1);
{ret= -1; goto ex;}
}
}
}
return(1);
ret= 1;
ex:
if(buf != NULL)
free(buf);
return(ret);
}
@ -3405,6 +3580,7 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
m->do_concat_split= 1;
m->do_auto_chmod= 0;
m->dialog= 0;
m->bsl_interpretation= 0;
m->search_mode= 0;
m->structured_search= 1;
m->do_iso_rr_pattern= 1;
@ -3837,6 +4013,7 @@ klammer_affe:;
bit1= release allocated memory and return 1
bit2= with bit0: warn of empty text arguments
bit3= deliver as single quoted text including all whitespace
and without any backslash interpretation
@return -1=out of memory , 0=line format error , 1=ok, go on , 2=done
*/
int Xorriso_read_lines(struct XorrisO *xorriso, FILE *fp, int *linecount,
@ -3894,7 +4071,8 @@ int Xorriso_read_lines(struct XorrisO *xorriso, FILE *fp, int *linecount,
linept= line + base_length;
}
if((flag & 1) && !(flag & 8)) {
ret= Sfile_make_argv("", line, argc, argv, 1);
ret= Sfile_make_argv("", line, argc, argv,
1 | ((xorriso->bsl_interpretation & 3) << 5));
if(ret < 0)
return(ret);
if(flag & 4)
@ -3970,7 +4148,8 @@ int Xorriso_pager(struct XorrisO *xorriso, char *line, int flag)
int ret,linecount;
char info_text[10*SfileadrL];
if(xorriso->result_page_length<=0 || xorriso->request_not_to_ask)
if(xorriso->result_page_length<=0 || xorriso->request_not_to_ask ||
xorriso->dialog == 0)
return(1);
Xorriso_predict_linecount(xorriso,line,&linecount,0);
if(xorriso->result_line_counter+linecount>xorriso->result_page_length) {
@ -5082,6 +5261,29 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag)
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2);
is_default= (xorriso->bsl_interpretation == 0);
strcpy(line, "-backslash_codes ");
if(xorriso->bsl_interpretation == 0)
strcat(line, "off");
else if(xorriso->bsl_interpretation == (3 | 16))
strcat(line, "on");
else {
if((xorriso->bsl_interpretation & 3) == 1)
strcat(line, "in_double_quotes");
else if((xorriso->bsl_interpretation & 3) == 2)
strcat(line, "outside_single_quotes");
else if((xorriso->bsl_interpretation & 3) == 3)
strcat(line, "with_quoted_input");
if(xorriso->bsl_interpretation & 16) {
if(strlen(line) > 17)
strcat(line, ":");
strcat(line, "with_program_arguments");
}
}
strcat(line, "\n");
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2);
is_default= !xorriso->packet_output;
sprintf(line,"-pkt_output %s\n",(xorriso->packet_output?"on":"off"));
if(!(is_default && no_defaults))
@ -9987,6 +10189,50 @@ ex:;
}
/* Option -backslash_codes */
int Xorriso_option_backslash_codes(struct XorrisO *xorriso, char *mode,
int flag)
{
char *npt, *cpt;
int l, was;
was= xorriso->bsl_interpretation;
xorriso->bsl_interpretation= 0;
npt= cpt= mode;
for(; npt!=NULL; cpt= npt+1) {
npt= strchr(cpt,':');
if(npt==NULL)
l= strlen(cpt);
else
l= npt-cpt;
if(l == 0)
continue;
if(l == 3 && strncmp(cpt, "off", l)==0) {
xorriso->bsl_interpretation= 0;
} else if(l == 16 && strncmp(cpt, "in_double_quotes", l)==0) {
xorriso->bsl_interpretation= (xorriso->bsl_interpretation & ~3) | 1;
} else if(l == 21 && strncmp(cpt, "outside_single_quotes", l)==0) {
xorriso->bsl_interpretation= (xorriso->bsl_interpretation & ~3) | 2;
} else if(l == 17 && strncmp(cpt, "with_quoted_input", l)==0) {
xorriso->bsl_interpretation= (xorriso->bsl_interpretation & ~3) | 3;
} else if(l == 22 && strncmp(cpt, "with_program_arguments", l)==0) {
xorriso->bsl_interpretation= xorriso->bsl_interpretation | 16;
} else if(l == 2 && strncmp(cpt, "on", l)==0) {
xorriso->bsl_interpretation= 3 | 16;
} else {
if(l<SfileadrL)
sprintf(xorriso->info_text, "-backslash_codes: unknown mode '%s'", cpt);
else
sprintf(xorriso->info_text,
"-backslash_codes: oversized mode parameter (%d)", l);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
xorriso->bsl_interpretation= was;
return(0);
}
}
return(1);
}
/* Option -ban_stdio_write */
int Xorriso_option_ban_stdio_write(struct XorrisO *xorriso, int flag)
@ -12132,6 +12378,11 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" -history text Copy text into libreadline history. This command",
" itself is not copied to the history list.",
#endif /* Xorriso_with_readlinE */
" -backslash_codes \"on\"|\"off\"|\"in_double_quotes\"|",
" \"outside_single_quotes\"|\"with_quoted_input\"",
" [:\"with_program_arguments\"]",
" Disable or enable interpretation of \\a \\b \\e \\f \\n \\r \\t \\v",
" \\\\ \\NNN \\xNN \\cC in input or program arguments.",
" -pkt_output \"on\"|\"off\" Direct output to stdout and prefix each line",
" by a short header which tells channel id and a mode number.",
" Each such output packet is finalized by a newline.",
@ -13060,7 +13311,7 @@ return:
<=0 error , 1 = success , 3 = end program run
*/
{
int ret,linecount= 0, argc, was_failure= 0, fret;
int ret,linecount= 0, argc= 0, was_failure= 0, fret;
FILE *fp= NULL;
char shellsafe[5*SfileadrL];
char **argv= NULL;
@ -13092,11 +13343,11 @@ return:
continue;
if(flag&1) {
ret= Sfile_make_argv(xorriso->progname, line, &argc, &argv, 4|8);
ret= Sfile_make_argv(xorriso->progname, line, &argc, &argv,
4 | 8 | ((xorriso->bsl_interpretation & 3) << 5));
if(ret<=0)
goto problem_handler;
ret= Xorriso_prescan_args(xorriso,argc,argv,1);
Sfile_make_argv("", "", &argc, &argv, 2); /* release memory */
if(ret==0)
{ret= 3; goto ex;}
if(ret<0)
@ -13123,6 +13374,7 @@ problem_handler:;
}
ret= 1;
ex:;
Sfile_make_argv("", "", &argc, &argv, 2); /* release memory */
Xorriso_read_lines(xorriso, fp, &linecount, &linec, &linev, 2);
Xorriso_reset_counters(xorriso,0);
if(fp!=NULL)
@ -14197,7 +14449,8 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv,
""
};
static char arg1_commands[][40]= {
"abort_on","add_plainly","blank","cd","cdi","cdx","close","commit_eject",
"abort_on","add_plainly","backslash_codes","blank",
"cd","cdi","cdx","close","commit_eject",
"dev", "dummy","dialog","disk_pattern","eject","iso_rr_pattern","follow",
"format","fs","gid","grow_blindly",
"history","indev","joliet","list_delimiter","mark","not_leaf",
@ -14280,16 +14533,16 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv,
}
/* @param flag bit0= recursion
bit1= these are command line arguments
(for xorriso->argument_emulation)
*/
int Xorriso_interpreter(struct XorrisO *xorriso,
int argc, char **argv, int *idx, int flag)
/*
return:
<=0 error , 1 = success , 2 = problem event ignored , 3 = end program run
*/
/*
bit0= recursion
bit1= these are command line arguments (for xorriso->argument_emulation)
*/
{
int ret, was_dashed, end_ret, num1, num2;
char *cmd, *original_cmd, cmd_data[2*SfileadrL], *arg1, *arg2;
@ -14370,6 +14623,10 @@ next_command:;
} else if(strcmp(cmd,"as")==0) {
ret= Xorriso_option_as(xorriso, argc, argv, idx, 0);
} else if(strcmp(cmd,"backslash_codes")==0) {
(*idx)++;
ret= Xorriso_option_backslash_codes(xorriso, arg1, 0);
} else if(strcmp(cmd,"ban_stdio_write")==0) {
ret= Xorriso_option_ban_stdio_write(xorriso, 0);
@ -14908,7 +15165,8 @@ int Xorriso_execute_option(struct XorrisO *xorriso, char *line, int flag)
tdiff= tv.tv_sec+(1.e-6*(double) tv.tv_usec);
/* parse line into args */
ret= Sfile_make_argv(xorriso->progname, line, &argc, &argv, 4);
ret= Sfile_make_argv(xorriso->progname, line, &argc, &argv,
4 | ((xorriso->bsl_interpretation & 3) << 5));
if(ret < 0) {
Xorriso_msgs_submit(xorriso, 0,
"Severe lack of resources during command line parsing", 0, "FATAL", 0);
@ -15021,6 +15279,7 @@ int Xorriso_prescan_args(struct XorrisO *xorriso, int argc, char **argv,
{
int i, ret, was_dashed, num2, arg_count;
int was_report_about= 0, was_abort_on= 0, was_return_with= 0;
int was_backslash_codes= 0;
char *cmd, *original_cmd, cmd_data[5*SfileadrL], *arg1, *arg2;
char mem_list_delimiter[81];
@ -15103,11 +15362,18 @@ protect_stdout:;
goto protect_stdout;
} else if(strcmp(cmd, "list_delimiter") == 0) {
/* Needed for interpreting other args. Gets reset after prescan. */
i++;
ret= Xorriso_option_list_delimiter(xorriso, arg1, 0);
if(ret <= 0)
goto ex;
} else if(strcmp(cmd,"backslash_codes")==0) {
i++;
if(!was_backslash_codes)
Xorriso_option_backslash_codes(xorriso, arg1, 0);
was_backslash_codes= 1;
} else {
ret= Xorriso_count_args(xorriso, argc-i, argv+i, &arg_count, 1);
if(ret==1)
@ -15222,6 +15488,8 @@ int Xorriso_main(int argc, char **argv)
}
/* Interpret program arguments */
if(xorriso->bsl_interpretation & 16)
Sfile_argv_bsl(argc, &argv, 0); /* apply Sfile_bsl_interpreter() to args */
i= 1;
ret= Xorriso_interpreter(xorriso,argc,argv,&i,2);
if(ret==3)

View File

@ -282,6 +282,17 @@ int Xorriso_option_alter_date(struct XorrisO *xorriso,
char *time_type, char *timestring,
int argc, char **argv, int *idx, int flag);
/* Option -as */
/* @param flag bit0=do not report the added item
bit1=do not reset pacifier, no final pacifier message
*/
int Xorriso_option_as(struct XorrisO *xorriso, int argc, char **argv,
int *idx, int flag);
/* Option -backslash_codes */
int Xorriso_option_backslash_codes(struct XorrisO *xorriso, char *mode,
int flag);
/* Option -ban_stdio_write */
int Xorriso_option_ban_stdio_write(struct XorrisO *xorriso, int flag);

View File

@ -209,6 +209,16 @@ struct XorrisO { /* the global context of xorriso */
int dialog; /* 0=off , 1=single-line , 2=multi-line */
int bsl_interpretation;
/* whether to run input through Sfile_bsl_interpreter():
bit0-1= dialog and quoted file reading
0= no interpretation, leave unchanged
1= only inside double quotes
2= outside single quotes
3= everywhere
bit2-3= reserved as future expansion of bit0-1
bit4= interpretation within program start arguments
*/
/* Pattern matching facility. It still carries legacy from scdbackup/askme.c
but is fully functional for xorriso.

View File

@ -1 +1 @@
#define Xorriso_timestamP "2008.10.15.182605"
#define Xorriso_timestamP "2008.10.17.074953"