diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index d6c3c03a..8915ee08 100644 --- a/xorriso/xorriso.1 +++ b/xorriso/xorriso.1 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH XORRISO 1 "Oct 16, 2008" +.TH XORRISO 1 "Oct 17, 2008" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -385,14 +385,30 @@ lists which are marked in this man page by "[***]" rather than "[...]". Some other commands perform pattern matching unconditionally. .PP Command and parameter words are either read from program arguments, where one -argument is one word, or from input lines where words are recognized similar -to the quotation rules of a shell parser. +argument is one word, or from quoted input lines where words are recognized +similar to the quotation rules of a shell parser. .br xorriso is not a shell, although it might appear so on first glimpse. Be aware that the interaction of quotation marks and pattern symbols like "*" differs from the usual shell parsers. In xorriso, a quotation mark does not make a pattern symbol literal. .PP +.B Quoted input +combines words from text pieces which are separated by whitespace. +The double quotation mark " and the single quotation mark ' can be used to +enclose whitespace and make it part of words (e.g. of file names). Each mark +type can enclose the marks of the other type. A trailing backslash \\ outside +quotations or an open quotation cause the next input line to be appended. +.br +Quoted input accepts any ASCII character except NUL (0) as content of quotes. +Nevertheless it can be cumbersome for the user to produce those characters +at all. Therefore quoted input and program arguments allow optional +.B Backslash Interpretation +which can represent all ASCII characters except NUL (0) by backslash codes +as in $'...' of bash. +.br +It is not enabled by default. See option -backslash_codes. +.PP When the program begins then it first looks for argument -no_rc. If this is not present then it looks for its startup files and eventually reads their content as command input lines. Then it interprets @@ -666,11 +682,8 @@ or standard input if disk_path is "-". The list must contain exactly one pathspec resp. disk_path pattern per line. .TP \fB\-quoted_path_list\fR disk_path -Like -path_list but with line reading rules of -dialog mode "on". -I.e. newline characters within quotes and trailing backslashes outside quotes -cause the next line to be appended to the pathspec resp. disk_pattern. -Eventual newline characters get part of the line, trailing backslashes get -discarded. Lines get split into words. Whitespace outside quotes is discarded. +Like -path_list but with quoted input reading rules. Lines get split into +parameter words for -add. Whitespace outside quotes is discarded. .TP \fB\-map\fR disk_path iso_rr_path Insert file object disk_path into the ISO image as iso_rr_path. If disk_path @@ -680,7 +693,7 @@ is a directory then its whole sub tree is inserted into the ISO image. Like -map, but if disk_path is a directory then its sub tree is not inserted. .TP \fB\-map_l\fR disk_prefix iso_rr_prefix disk_path [***] -Performs -map with each of the disk_path arguments. iso_rr_path will be +Perform -map with each of the disk_path arguments. iso_rr_path will be composed from disk_path by replacing disk_prefix by iso_rr_prefix. .TP \fB\-update\fR disk_path iso_rr_path @@ -708,7 +721,7 @@ If iso_rr_path does not exist yet, then it gets added. If disk_path does not exist, then iso_rr_path gets deleted. .TP \fB\-update_l\fR disk_prefix iso_rr_prefix disk_path [***] -Performs -update_r with each of the disk_path arguments. iso_rr_path will be +Perform -update_r with each of the disk_path arguments. iso_rr_path will be composed from disk_path by replacing disk_prefix by iso_rr_prefix. .TP \fB\-cut_out\fR disk_path byte_offset byte_count iso_rr_path @@ -1198,11 +1211,11 @@ disk leafnames. These patterns are evaluated when the exclusion checks are made. .TP \fB\-not_list\fR disk_path -Read lines from disk_path and use them as -not_paths argument if they contain -a / character. If not use the line as -not_leaf pattern. +Read lines from disk_path and use each of them either as -not_paths argument, +if they contain a / character, or as -not_leaf pattern. .TP \fB\-quoted_not_list\fR disk_path -Like -not_list but with line reading rules of -dialog mode "on". Each word is +Like -not_list but with quoted input reading rules. Each word is handled as one argument for -not_paths resp. -not_leaf. .TP \fB\-follow\fR occasion[:occasion[...]] @@ -1305,7 +1318,7 @@ Rock Ridge info will be generated by the program unconditionally. If enabled by "on", generate Joliet info additional to Rock Ridge info. .TP \fB\-volid\fR text -Specifies the volume ID. xorriso accepts any text up to 32 characters, +Specify the volume ID. xorriso accepts any text up to 32 characters, but according to rarely obeyed specs stricter rules apply: .br ECMA 119 demands character set [A-Z0-9_]. Like: "IMAGE_23" @@ -1406,7 +1419,7 @@ capability to influence the bootability of the existing sessions, unless one can assume overwriteable media. .TP \fB\-boot_image\fR "any"|"isolinux" "discard"|"keep"|"patch"|bootspec -Defines the handling of an eventual El Torito object which has +Define the handling of an eventual El Torito object which has been read from an existing ISO image or defines how to make a prepared ISOLINUX file set bootable. .br @@ -1989,7 +2002,7 @@ Like -extract, but if iso_rr_path is a directory then its sub tree gets not restored. .TP \fB\-extract_l\fR iso_rr_prefix disk_prefix iso_rr_path [***] -Performs -extract with each of the iso_rr_path arguments. disk_path will be +Perform -extract with each of the iso_rr_path arguments. disk_path will be composed from iso_rr_path by replacing iso_rr_prefix by disk_prefix. .TP \fB\-extract_cut\fR iso_rr_path byte_offset byte_count disk_path @@ -2050,7 +2063,7 @@ of commands which in said programs trigger comparable actions. .TP \fB\-as\fR personality option [options] -- .br -Performs its variable length option list as sparse emulation of the program +Perform its variable length option list as sparse emulation of the program depicted by the personality word. .br @@ -2162,7 +2175,7 @@ prevents reading and interpretation of eventual startup files. See section FILES below. .TP \fB\-options_from_file\fR fileaddress -Reads lines from fileaddress and executes them as dialog lines. +Read quoted input from fileaddress and executes it like dialog lines. .TP \fB\-help\fR .br @@ -2200,8 +2213,8 @@ 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: +characters with quoted input, or with program arguments, or with program +text output. If enabled the following translations apply: .br \\a=bell(007) \\b=backspace(008) \\e=Escape(033) \\f=formfeed(014) .br @@ -2215,16 +2228,22 @@ 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. + "in_quotes" translates inside " and ' quotation. .br - "with_quoted_input" translates all input text. + "with_quoted_input" translates inside and outside quotes. .br With the start program arguments there is mode: .br "with_program_arguments" translates all program arguments. .br +.br +Mode "encode_output" encodes output characters inside single or double +quotation marks. It combines "encode_results" with "encode_infos". Encoding +applies to ASCII characters 1 to 31 and 127 to 255. +.br Mode "off" is default and disables any translation. -Mode "on" is the same as "with_quoted_input:with_program_arguments". +Mode "on" is +"with_quoted_input:with_program_arguments:encode_output". .TP \fB\-temp_mem_limit\fR number["k"|"m"] Set the maximum size of temporary memory to be used for image dependent diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 94b66404..a20a6bfd 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -496,23 +496,6 @@ int Sfile_off_t_text(char text[80], off_t num, int flag) } -int Sfile_destroy_argv(int *argc, char ***argv, int flag) -{ - int i; - - if(*argc>0 && *argv!=NULL){ - for(i=0;i<*argc;i++){ - if((*argv)[i]!=NULL) - Smem_freE((*argv)[i]); - } - Smem_freE((char *) *argv); - } - *argc= 0; - *argv= NULL; - return(1); -} - - /* 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 @@ -637,6 +620,83 @@ ex:; } +/* @param flag bit0= only encode inside quotes +*/ +int Sfile_bsl_encoder(char **result, char *text, int flag) +{ + char *rpt, *wpt; + int count, sq_open= 0, dq_open= 0; + + count= 0; + for(rpt= text; *rpt != 0; rpt++) { + count++; + if(*rpt >= 32 && *rpt <= 126 && *rpt != '\\') + continue; + if((*rpt >= 7 && *rpt <= 13) || *rpt == 27 || *rpt == '\\') + count++; + else + count+= 3; + } + (*result)= wpt= calloc(count + 1, 1); + if(wpt == NULL) + return(-1); + for(rpt= text; *rpt != 0; rpt++) { + if(*rpt == '\'') + sq_open= !(sq_open || dq_open); + if(*rpt == '"') + dq_open= !(sq_open || dq_open); + if((*rpt >= 32 && *rpt <= 126 && *rpt != '\\') || + ((flag & 1) && !(sq_open || dq_open))) { + *(wpt++)= *rpt; + continue; + } + *(wpt++)= '\\'; + if((*rpt >= 7 && *rpt <= 13) || *rpt == 27 || *rpt == '\\') { + if(*rpt == 7) + *(wpt++)= 'a'; + else if(*rpt == 8) + *(wpt++)= 'b'; + else if(*rpt == 9) + *(wpt++)= 't'; + else if(*rpt == 10) { + *(wpt++)= 'n'; + } else if(*rpt == 11) + *(wpt++)= 'v'; + else if(*rpt == 12) + *(wpt++)= 'f'; + else if(*rpt == 13) + *(wpt++)= 'c'; + else if(*rpt == 27) + *(wpt++)= 'e'; + else if(*rpt == '\\') + *(wpt++)= '\\'; + } else { + sprintf(wpt, "%-3.3o", (unsigned int) *((unsigned char *) rpt)); + wpt+= 3; + } + } + *wpt= 0; + return(1); +} + + +int Sfile_destroy_argv(int *argc, char ***argv, int flag) +{ + int i; + + if(*argc>0 && *argv!=NULL){ + for(i=0;i<*argc;i++){ + if((*argv)[i]!=NULL) + Smem_freE((*argv)[i]); + } + Smem_freE((char *) *argv); + } + *argc= 0; + *argv= NULL; + return(1); +} + + int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv, int flag) /* @@ -691,7 +751,7 @@ int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv, l= cpt-start; bufl= strlen(buf); if(l>0) { strncpy(buf + bufl, start, l); buf[bufl + l]= 0; - if(bsl_mode >= 2) { + if(bsl_mode >= 3) { ret= Sfile_bsl_interpreter(buf, l, &eaten, 0); if(ret <= 0) goto ex; @@ -717,7 +777,7 @@ int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv, l= cpt-start; bufl= strlen(buf); if(l>0) { strncpy(buf + bufl, start, l); buf[bufl + l]= 0; - if(bsl_mode >= 2) { + if(bsl_mode >= 3) { ret= Sfile_bsl_interpreter(buf, l, &eaten, 0); if(ret <= 0) goto ex; @@ -731,7 +791,7 @@ int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv, l= cpt-start; bufl= strlen(buf); if(l>0) { strncat(buf,start,l);buf[bufl+l]= 0; - if(bsl_mode >= 3) { + if(bsl_mode >= 2) { ret= Sfile_bsl_interpreter(buf + bufl, l, &eaten, 0); if(ret <= 0) goto ex; @@ -745,7 +805,7 @@ int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv, bufl= strlen(buf); if(l>0) { strncpy(buf + bufl, start, l); buf[bufl + l]= 0; - if(bsl_mode >= 2) { + if(bsl_mode >= 3) { ret= Sfile_bsl_interpreter(buf, l, &eaten, 0); if(ret <= 0) goto ex; @@ -4175,14 +4235,15 @@ ask_for_page:; int Xorriso_write_to_channel(struct XorrisO *xorriso, - char *text, int channel_no, int flag) + char *in_text, int channel_no, int flag) /* + bit0= eventually backslash encode linefeeds bit1= text is the name of the log file for the given channel bit2= text is the name of the consolidated packet log file for all channels bit15= with bit1 or bit2: close depicted log file */ { - char *rpt,*npt; + char *rpt, *npt, *text; int ret= 1, info_redirected= 0, result_redirected= 0; char prefix[16]; FILE *logfile_fp, *pktlog_fp; @@ -4191,7 +4252,9 @@ bit15= with bit1 or bit2: close depicted log file static char channel_prefixes[4][4]= {".","R","I","M"}; if(channel_no<0 || channel_no>=num_channels) - return(-1); + {ret= -1; goto ex;} + + text= in_text; /* might change due to backslash encoding */ /* Logfiles */ logfile_fp= xorriso->logfile_fp[channel_no]; @@ -4211,11 +4274,11 @@ bit15= with bit1 or bit2: close depicted log file xorriso->pktlog_fp= pktlog_fp= NULL; } if(flag&(1<<15)) - return(1); + {ret= 1; goto ex;} if((flag&2)) { xorriso->logfile_fp[channel_no]= logfile_fp= fopen(text,"a"); if(logfile_fp==NULL) - return(0); + {ret= 0; goto ex;} fprintf(logfile_fp, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! xorriso log : %s : %s\n", channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256)); @@ -4224,14 +4287,22 @@ bit15= with bit1 or bit2: close depicted log file if((flag&4)) { xorriso->pktlog_fp= pktlog_fp= fopen(text,"a"); if(pktlog_fp==NULL) - return(0); + {ret= 0; goto ex;} fprintf(pktlog_fp, "I:1:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! xorriso log : . : %s\n", Sfile_datestr(time(0),1|2|256)); fflush(pktlog_fp); } if(flag&(2|4)) - return(1); + {ret= 1; goto ex;} + + /* Eventually perform backslash encoding of non-printable characters */ + if(((xorriso->bsl_interpretation & 32) && channel_no == 1) || + ((xorriso->bsl_interpretation & 64) && channel_no == 2)) { + ret= Sfile_bsl_encoder(&text, text, 1); + if(ret <= 0) + {ret= -1; goto ex;} + } /* Eventually perform messag redirection */ if(xorriso->msglist_stackfill > 0) { @@ -4245,7 +4316,7 @@ bit15= with bit1 or bit2: close depicted log file msglist= xorriso->result_msglists[xorriso->msglist_stackfill - 1]; ret= Xorriso_lst_append_binary(&msglist, text, strlen(text) + 1, 0); if(ret <= 0) - return(-1); + {ret= -1; goto ex;} if(xorriso->result_msglists[xorriso->msglist_stackfill - 1] == NULL) xorriso->result_msglists[xorriso->msglist_stackfill - 1]= msglist; } @@ -4255,7 +4326,7 @@ bit15= with bit1 or bit2: close depicted log file msglist= xorriso->info_msglists[xorriso->msglist_stackfill - 1]; ret= Xorriso_lst_append_binary(&msglist, text, strlen(text) + 1, 0); if(ret <= 0) - return(-1); + {ret= -1; goto ex;} if(xorriso->info_msglists[xorriso->msglist_stackfill - 1] == NULL) xorriso->info_msglists[xorriso->msglist_stackfill - 1]= msglist; } @@ -4263,7 +4334,7 @@ bit15= with bit1 or bit2: close depicted log file if((channel_no == 1 && result_redirected) || (channel_no == 2 && info_redirected) || (result_redirected && info_redirected)) - return(1); + {ret= 1; goto ex;} /* Non-redirected output */ if(!xorriso->packet_output) { @@ -4278,7 +4349,7 @@ bit15= with bit1 or bit2: close depicted log file fflush(logfile_fp); } if(pktlog_fp==NULL) - return(1); + {ret= 1; goto ex;} } rpt= text; sprintf(prefix,"%s:x: ",channel_prefixes[channel_no]); @@ -4291,41 +4362,41 @@ bit15= with bit1 or bit2: close depicted log file if(xorriso->packet_output) { ret= fwrite(prefix,5,1,stdout); if(ret<=0) - return(0); + {ret= 0; goto ex;} } if(pktlog_fp!=NULL) { ret= fwrite(prefix,5,1,pktlog_fp); if(ret<=0) - return(0); + {ret= 0; goto ex;} } if(npt==NULL) { if(xorriso->packet_output) { ret= fwrite(rpt,strlen(rpt),1,stdout); if(ret<=0) - return(0); + {ret= 0; goto ex;} ret= fwrite("\n",1,1,stdout); if(ret<=0) - return(0); + {ret= 0; goto ex;} } if(pktlog_fp!=NULL) { ret= fwrite(rpt,strlen(rpt),1,pktlog_fp); if(ret<=0) - return(0); + {ret= 0; goto ex;} ret= fwrite("\n",1,1,pktlog_fp); if(ret<=0) - return(0); + {ret= 0; goto ex;} } break; } else { if(xorriso->packet_output) { ret= fwrite(rpt,npt+1-rpt,1,stdout); if(ret<=0) - return(0); + {ret= 0; goto ex;} } if(pktlog_fp!=NULL) { ret= fwrite(rpt,npt+1-rpt,1,pktlog_fp); if(ret<=0) - return(0); + {ret= 0; goto ex;} } } rpt= npt+1; @@ -4334,7 +4405,11 @@ bit15= with bit1 or bit2: close depicted log file fflush(stdout); if(pktlog_fp!=NULL) fflush(pktlog_fp); - return(1); + ret= 1; +ex: + if(text != in_text && text != NULL) + free(text); + return(ret); } @@ -5265,13 +5340,13 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag) strcpy(line, "-backslash_codes "); if(xorriso->bsl_interpretation == 0) strcat(line, "off"); - else if(xorriso->bsl_interpretation == (3 | 16)) + else if(xorriso->bsl_interpretation == (3 | 16 | 32 | 64)) 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"); + strcat(line, "in_quotes"); else if((xorriso->bsl_interpretation & 3) == 3) strcat(line, "with_quoted_input"); if(xorriso->bsl_interpretation & 16) { @@ -5279,6 +5354,22 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag) strcat(line, ":"); strcat(line, "with_program_arguments"); } + if((xorriso->bsl_interpretation & (32 | 64)) == (32 | 64)) { + if(strlen(line) > 17) + strcat(line, ":"); + strcat(line, "encode_output"); + } else { + if(xorriso->bsl_interpretation & 32) { + if(strlen(line) > 17) + strcat(line, ":"); + strcat(line, "encode_results"); + } + if(xorriso->bsl_interpretation & 64) { + if(strlen(line) > 17) + strcat(line, ":"); + strcat(line, "encode_infos"); + } + } } strcat(line, "\n"); if(!(is_default && no_defaults)) @@ -10211,14 +10302,20 @@ int Xorriso_option_backslash_codes(struct XorrisO *xorriso, char *mode, 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) { + } else if(l == 9 && strncmp(cpt, "in_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 == 13 && strncmp(cpt, "encode_output", l)==0) { + xorriso->bsl_interpretation= xorriso->bsl_interpretation | 32 | 64; + } else if(l == 14 && strncmp(cpt, "encode_results", l)==0) { + xorriso->bsl_interpretation= xorriso->bsl_interpretation | 32; + } else if(l == 12 && strncmp(cpt, "encode_infos", l)==0) { + xorriso->bsl_interpretation= xorriso->bsl_interpretation | 64; } else if(l == 2 && strncmp(cpt, "on", l)==0) { - xorriso->bsl_interpretation= 3 | 16; + xorriso->bsl_interpretation= 3 | 16 | 32 | 64; } else { if(linfo_text, "-backslash_codes: unknown mode '%s'", cpt); @@ -12378,9 +12475,9 @@ 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\"]", +" -backslash_codes \"on\"|\"off\"|", +" \"in_double_quotes\"|\"in_quotes\"|\"with_quoted_input\"", +" [:\"with_program_arguments\"][:\"encode_output\"]", " 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", @@ -15279,7 +15376,6 @@ 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]; @@ -15368,12 +15464,6 @@ protect_stdout:; 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) diff --git a/xorriso/xorriso_private.h b/xorriso/xorriso_private.h index 41f624d9..6cd9721d 100644 --- a/xorriso/xorriso_private.h +++ b/xorriso/xorriso_private.h @@ -218,6 +218,8 @@ struct XorrisO { /* the global context of xorriso */ 3= everywhere bit2-3= reserved as future expansion of bit0-1 bit4= interpretation within program start arguments + bit5= perform backslash encoding with results + bit6= perform backslash encoding with info texts */ /* Pattern matching facility. It still carries legacy from scdbackup/askme.c diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index dbd79d97..cab12e66 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2008.10.17.074953" +#define Xorriso_timestamP "2008.10.17.123308"