From c5b9d6471f823bc5d9b3ded4120c5e097be441dd Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Fri, 12 Oct 2007 20:39:29 +0000 Subject: [PATCH] The stub of new application xorriso --- test/xorriso.c | 4448 ++++++++++++++++++++++++++++++++++++++++++++++ test/xorriso.h | 222 +++ test/xorriso.txt | 531 ++++++ 3 files changed, 5201 insertions(+) create mode 100644 test/xorriso.c create mode 100644 test/xorriso.h create mode 100644 test/xorriso.txt diff --git a/test/xorriso.c b/test/xorriso.c new file mode 100644 index 00000000..458e4b2d --- /dev/null +++ b/test/xorriso.c @@ -0,0 +1,4448 @@ + + + +/* + cc -g -DXorriso_with_maiN -DXorriso_with_regeX -DXorriso_with_readlinE \ + -Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ + -o test/xorriso test/xorriso.c -lreadline +*/ + +/* Command line oriented batch and dialog tool which creates, loads, + manipulates and burns ISO 9660 filesystem images. + + Copyright 2007 Thomas Schmitt, + + Initial code of this program was derived from program src/askme.c out + of scdbackup-0.8.8, Copyright 2007 Thomas Schmitt, BSD-License. + + Provided under GPL version 2, with the announcement that this might + get changed in future. I would prefer BSD or a modifyied LGPL with no + option to choose any kind of future GPL version. + (This announcement affects only future releases of xorriso. + If you obtain a copy licensed as "GPL version 2" then this license is + not revocable for that particular copy, of course.) +*/ + +#define PROG_VERSION "0.0.0" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef Xorriso_with_regeX +#include +#endif /* Xorriso_with_regeX */ + +#ifdef Xorriso_with_readlinE +#ifdef Xorriso_with_old_readlinE +#include +#include +#else /* Xorriso_with_old_readlinE */ +#include +#include +#endif /* ! Xorriso_with_old_readlinE */ +#endif /* Xorriso_with_readlinE */ + +#define TSOB_FELD(typ,anz) (typ *) malloc((anz)*sizeof(typ)); + + +/* Diet facility: exclude help texts from binaries */ +/* This will eventually be redefined to eat up its content */ +#define AlN(x) x + + +/* There is only one stage of diet: Xorriso_no_helP */ +#ifdef Xorriso_no_helP +#undef AlN +#define AlN(x) +#endif + +#define Smem_malloC malloc +#define Smem_freE free +#define SfileadrL 4096 + +/* <<< ??? */ +typedef int (*Cleanup_app_handler_T)(); + + +/* Include this in code that uses xorriso via its options API */ +#include "xorriso.h" + + +/* ------------------------------------------------------------------------ */ + + +#ifndef Xorriso_sfile_externaL + + +char *Sfile_fgets(char *line, int maxl, FILE *fp) +{ + int l; + char *ret; + + ret= fgets(line,maxl,fp); + if(ret==NULL) + return(NULL); + l= strlen(line); + if(l>0) if(line[l-1]=='\r') line[--l]= 0; + if(l>0) if(line[l-1]=='\n') line[--l]= 0; + if(l>0) if(line[l-1]=='\r') line[--l]= 0; + return(ret); +} + + +int Sfile_fclose(FILE *fp) +{ + if(fp!=stdout && fp!=stdin && fp!=NULL) + fclose(fp); + return(1); +} + + +int Sfile_count_components(char *path, int flag) +/* + bit0= do not ignore trailing slash + bit1= do not ignore empty components (other than the empty root name) +*/ +{ + int l,count= 0; + char *cpt; + + l= strlen(path); + if(l==0) + return(0); + count= 1; + for(cpt= path+l-1;cpt>=path;cpt--) { + if(*cpt=='/') { + if(*(cpt+1)==0 && !(flag&1)) + continue; + if(*(cpt+1)=='/' && !(flag&2)) + continue; + count++; + } + } + return(count); +} + + +int Sfile_component_pointer(char *path, char **sourcept, int idx, int flag) +/* + bit0= do not ignore trailing slash + bit1= do not ignore empty components (other than the empty root name) + bit2= accept 0 as '/' +*/ +{ + int count= 0; + char *spt; + + for(spt= path;*spt!=0 || (flag&4);spt++) { + if(count>=idx) { + *sourcept= spt; + return(1); + } + if(*spt=='/' || *spt==0) { + if(*(spt+1)=='/' && !(flag&2)) + continue; + if(*(spt+1)==0 && !(flag&1)) + continue; + count++; + } + } + if((flag&1) && count>=idx) + return(1); + return(0); +} + + +int Sfile_add_to_path(char path[SfileadrL], char *addon, int flag) +{ + int l; + + l= strlen(path); + if(l==0) { + strcpy(path,"/"); + l= 1; + } else if(path[l-1]!='/') { + path[l++]= '/'; + path[l]= 0; + } + if(l+strlen(addon)>=SfileadrL) + return(0); + if(addon[0]=='/') + strcpy(path+l,addon+1); + else + strcpy(path+l,addon); + return(1); +} + + +int Sfile_being_group_member(struct stat *stbuf, int flag) +{ + int i, suppl_groups; + gid_t *suppl_glist; + + if (getegid()==stbuf->st_gid) + return(1); + suppl_groups= getgroups(0, NULL); + suppl_glist= (gid_t *) malloc((suppl_groups + 1) * sizeof(gid_t)); + if (suppl_glist==NULL) + return(-1); + suppl_groups= getgroups(suppl_groups+1,suppl_glist); + for (i= 0; ist_gid) { + free((char *) suppl_glist); + return(1); + } + } + free((char *) suppl_glist); + return(0); +} + + +int Sfile_type(char *filename, int flag) +/* + bit0= return -1 if file is missing + bit1= return a hardlink with siblings as type 5 + bit2= evaluate eventual link target rather than the link object itself + bit3= return a socket or a char device as types 7 or 8 rather than 0 +*/ +/* + return: + 0=unknown + 1=regular + 2=directory + 3=symbolic link + 4=named pipe + 5=multiple hardlink (with bit1) + 6=block device + 7=socket (with bit3) + 8=character device (with bit3) +*/ +{ + struct stat stbuf; + if(flag&4) { + if(stat(filename,&stbuf)==-1) { + if(flag&1) return(-1); + else return(0); + } + } else { + if(lstat(filename,&stbuf)==-1) { + if(flag&1) return(-1); + else return(0); + } + } + if(S_ISREG(stbuf.st_mode)) { + if(flag&2) + if(stbuf.st_nlink>1) + return(5); + return(1); + } + if(S_ISDIR(stbuf.st_mode)) + return(2); + if((stbuf.st_mode&S_IFMT)==S_IFLNK) + return(3); + if(S_ISFIFO(stbuf.st_mode)) + return(4); + if(S_ISBLK(stbuf.st_mode)) + return(6); + if(flag&8) + if((stbuf.st_mode&S_IFMT)==S_IFSOCK) + return(7); + if(flag&8) + if(S_ISCHR(stbuf.st_mode)) + return(8); + return(0); +} + + +int Sfile_lookup_permissions(char *fname, int *perms, mode_t *st_mode,int flag) +/* perms: bit0= r , bit1= w , bit2= x */ +/* return: <0 fatal error, 0= file nonexistent, 1=owner, 2=group, 3=other */ +{ + struct stat stbuf; + + *perms= 0; + if(stat(fname,&stbuf)==-1) + return(0); + *st_mode= stbuf.st_mode; + if(geteuid()==stbuf.st_uid || geteuid()==0) { + if(stbuf.st_mode & S_IRUSR) + (*perms)|= 1; + if(stbuf.st_mode & S_IWUSR) + (*perms)|= 2; + if(stbuf.st_mode & S_IXUSR) + (*perms)|= 4; + return(1); + } + /* group membership is a complicated thing */ + if(Sfile_being_group_member(&stbuf,0)>0) { + if(stbuf.st_mode & S_IRGRP) + (*perms)|= 1; + if(stbuf.st_mode & S_IWGRP) + (*perms)|= 2; + if(stbuf.st_mode & S_IXGRP) + (*perms)|= 4; + return(2); + } + if(stbuf.st_mode & S_IROTH) + (*perms)|= 1; + if(stbuf.st_mode & S_IWOTH) + (*perms)|= 2; + if(stbuf.st_mode & S_IXOTH) + (*perms)|= 4; + return(3); +} + + +int Sfile_select(int *fds, int fdcount, int fdidx[3], unsigned int microsec, + int flag) +/* + bit0= check for reading (and choose one into fdidx[0]) + bit1= check for writing (and choose one into fdidx[1]) + bit2= check for exception (and choose one into fdidx[2]) + bit3= initialize fdidx +return-bits are set according to matching flag-bits +*/ +{ + struct timeval wt; + fd_set rds,wts,exs,*s; + int ready,ret,i,j,max_fd= -1; + + if(flag&8) + for(j=0;j<3;j++) + fdidx[j]= 0; + wt.tv_sec= microsec/1000000; + wt.tv_usec= microsec%1000000; + FD_ZERO(&rds); + FD_ZERO(&wts); + FD_ZERO(&exs); + for(i= 0;imax_fd) + max_fd= fds[i]; + } + ready= select(max_fd+1,&rds,&wts,&exs,&wt); + if(ready<=0) + return(0); + ret= 0; + if(fdcount>0) + for(j=0;j<2;j++) + fdidx[j]= (fdidx[j]+1)%fdcount; + for(i= 0;itm_year>99) + sprintf(zeitcode,"%c%1.1d%2.2d%2.2d", + 'A'+(azt->tm_year-100)/10,azt->tm_year%10, + azt->tm_mon+1,azt->tm_mday); + else + sprintf(zeitcode,"%2.2d%2.2d%2.2d", + azt->tm_year,azt->tm_mon+1,azt->tm_mday); + if(flag&1){ + sprintf(puff,".%2.2d%2.2d",azt->tm_hour,azt->tm_min); + strcat(zeitcode,puff); + } + if(flag&2){ + sprintf(puff,"%2.2d",azt->tm_sec); + strcat(zeitcode,puff); + } + + return(zeitcode); +} + + +int Sfile_scale(double value, char *result, int siz, double thresh, int flag) +/* + bit0= eventually ommit 'b' + bit1= make text as short as possible + bit2= no fraction (if it would fit at all) +*/ +{ + char scale_c,scales[6],form[80]; + int i,dec_siz= 0,avail_siz= 1; + + strcpy(scales,"bkmgtp"); + scale_c= scales[0]; + for(i=1;scales[i]!=0;i++) { + if(value0) + sprintf(form,"%%%d.%dlf%%c",avail_siz,dec_siz); + else + sprintf(form,"%%%d.lf%%c",siz-1); + sprintf(result,form,value,scale_c); + } + 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) +/* + bit0= read progname as first argument from line + bit1= just release argument list argv and return + bit2= abort with return(0) if incomplete quotes are found +*/ +{ + int i,pass,maxl=0,l,argzaehl=0,bufl; + char *cpt,*start; + char buf[SfileadrL]; + + Sfile_destroy_argv(argc,argv,0); + if(flag&2) return(1); + + for(pass=0;pass<2;pass++) { + cpt= line-1; + if(!(flag&1)){ + argzaehl= 1; + if(pass==0) + maxl= strlen(progname); + else + strcpy((*argv)[0],progname); + } else { + argzaehl= 0; + if(pass==0) maxl= 0; + } + while(*(++cpt)!=0){ + if(isspace(*cpt)) continue; + start= cpt; + buf[0]= 0; + cpt--; + while(*(++cpt)!=0) { + if(isspace(*cpt)) break; + if(*cpt=='"'){ + l= cpt-start; bufl= strlen(buf); + if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;} + l= strlen(buf); + start= cpt+1; + while(*(++cpt)!=0) if(*cpt=='"') break; + if((flag&4) && *cpt==0) + return(0); + l= cpt-start; bufl= strlen(buf); + if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;} + start= cpt+1; + }else if(*cpt=='\''){ + l= cpt-start; bufl= strlen(buf); + if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;} + l= strlen(buf); + start= cpt+1; + while(*(++cpt)!=0) if(*cpt=='\'') break; + if((flag&4) && *cpt==0) + return(0); + l= cpt-start; bufl= strlen(buf); + if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;} + start= cpt+1; + } + if(*cpt==0) break; + } + l= cpt-start; + bufl= strlen(buf); + if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;} + l= strlen(buf); + if(pass==0){ + if(l>maxl) maxl= l; + }else{ + strcpy((*argv)[argzaehl],buf); + } + argzaehl++; + if(*cpt==0) break; + } + if(pass==0){ + *argc= argzaehl; + if(argzaehl>0) { + *argv= (char **) Smem_malloC(argzaehl*sizeof(char *)); + if(*argv==NULL) + return(-1); + } + for(i=0;i<*argc;i++) { + (*argv)[i]= (char *) Smem_malloC((maxl+1)); + if((*argv)[i]==NULL) + return(-1); + } + } + } + return(1); +} + + +#endif /* Xorriso_sfile_externaL */ + + +/* --------------------------------- misc --------------------------------- */ + + +int Write_to_channel(char *text, int channel_no, int flag) +/* + bit0= packet write disabled, write to stdin resp. stderr + 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,ret= 1; + char prefix[16]; + static int num_channels= 4; + static char channel_prefixes[4][4]= {"-","R","I","M"}; + static FILE *logfile_fp[4]= {NULL,NULL,NULL,NULL}; + static FILE *pktlog_fp= NULL; + + if(channel_no<0 || channel_no>=num_channels) + return(-1); + + /* Logfiles */ + if((flag&2) && logfile_fp[channel_no]!=NULL) { + fprintf(logfile_fp[channel_no], + "! end ! end ! end ! end ! end ! end ! end ! end xorriso log : %s : %s\n", + channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256)); + fclose(logfile_fp[channel_no]); + logfile_fp[channel_no]= NULL; + } + if((flag&4) && pktlog_fp!=NULL) { + fprintf(pktlog_fp, + "I:1:! end ! end ! end ! end ! end ! end ! end ! end xorriso log : %s : %s\n", + channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256)); + fclose(pktlog_fp); + pktlog_fp= NULL; + } + if(flag&(1<<15)) + return(1); + if((flag&2)) { + logfile_fp[channel_no]= fopen(text,"a"); + if(logfile_fp[channel_no]==NULL) + return(0); + fprintf(logfile_fp[channel_no], + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! xorriso log : %s : %s\n", + channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256)); + fflush(logfile_fp[channel_no]); + } + if((flag&4)) { + pktlog_fp= fopen(text,"a"); + if(pktlog_fp==NULL) + return(0); + 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); + if(flag&1) { + if(channel_no==1 || channel_no==3) + printf("%s",text); + if(channel_no==2 || channel_no==3) + fprintf(stderr,"%s",text); + if(logfile_fp[channel_no]!=NULL) { + fprintf(logfile_fp[channel_no],"%s",text); + fflush(logfile_fp[channel_no]); + } + if(pktlog_fp!=NULL) + return(1); + } + rpt= text; + sprintf(prefix,"%s:x: ",channel_prefixes[channel_no]); + while(*rpt!=0) { + npt= strchr(rpt,'\n'); + if(npt==NULL) + prefix[2]= '0'; + else + prefix[2]= '1'; + if(!(flag&1)) { + ret= fwrite(prefix,5,1,stdout); + if(ret<=0) + return(0); + } + if(pktlog_fp!=NULL) { + ret= fwrite(prefix,5,1,pktlog_fp); + if(ret<=0) + return(0); + } + if(npt==NULL) { + if(!(flag&1)) { + ret= fwrite(rpt,strlen(rpt),1,stdout); + if(ret<=0) + return(0); + ret= fwrite("\n",1,1,stdout); + if(ret<=0) + return(0); + } + if(pktlog_fp!=NULL) { + ret= fwrite(rpt,strlen(rpt),1,pktlog_fp); + if(ret<=0) + return(0); + ret= fwrite("\n",1,1,pktlog_fp); + if(ret<=0) + return(0); + } + break; + } else { + if(!(flag&1)) { + ret= fwrite(rpt,npt+1-rpt,1,stdout); + if(ret<=0) + return(0); + } + if(pktlog_fp!=NULL) { + ret= fwrite(rpt,npt+1-rpt,1,pktlog_fp); + if(ret<=0) + return(0); + } + } + rpt= npt+1; + } + if(!(flag&1)) + fflush(stdout); + if(pktlog_fp!=NULL) + fflush(pktlog_fp); + return(1); +} + + +int Exec_cmd(char *prog, char *cmd, char *simple_arg, char **argv, + char errmsg[SfileadrL], int flag) +/* + bit0= package mode (!bit0 of Write_to_channel()) +*/ +{ + int wait_status,is_dead= 0,pipes_open= 0,ret,channel_no; + int stdout_pipe[2],stderr_pipe[2],fds[2],fdidx[3]; + char **exec_argv,*simple_argv[3],buffer[256]; + pid_t pid,dead_pid; + static int debug= 0; + + errmsg[0]= 0; + if(debug) + fprintf(stderr,"Exec_cmd():fork\n"); + + /* create pipes */ + if(pipe(stdout_pipe)==-1) { +cannot_make_pipe:; + sprintf(errmsg,"%s : cannot create two pipes\n reason given: %s\n", + prog,strerror(errno)); + return(-1); + } + if(pipe(stderr_pipe)==-1) { + close(stdout_pipe[0]); + close(stdout_pipe[1]); + goto cannot_make_pipe; + } + pipes_open= 1; + + pid= fork(); + if(pid==-1) { + sprintf(errmsg,"%s : cannot fork a new process\n reason given: %s\n", + prog,strerror(errno)); + {ret= -1; goto father_ex;} + } else if(pid>0) { /* original process */ + if(debug) + fprintf(stderr,"Exec_cmd():father\n"); + /* close unused pipe ends so we register EOF by the child process */ + close(stdout_pipe[1]); + close(stderr_pipe[1]); + fds[0]= stdout_pipe[0]; + fds[1]= stderr_pipe[0]; + is_dead= 0; + while(1) { + if((fds[0]==-1 && fds[1]==-1)) { /* not before both pipes have closed */ + dead_pid= wait3(&wait_status,WNOHANG,NULL); + if(dead_pid==pid) { + is_dead= 1; + break; + } else if(dead_pid<0) { + sprintf(errmsg, + "%s : error while waiting for end of sub process\n %s\n", + prog,strerror(errno)); + {ret= -1; goto father_ex;} + } + } + + /* check for input at both pipes */; + ret= Sfile_select(fds,2,fdidx,100000,1|8); + if(ret<=0 || fdidx[0]<0 || fdidx[0]>1) + continue; + ret= read(fds[fdidx[0]],buffer,sizeof(buffer)-3); + if(ret<0) { + sprintf(errmsg,"--- error %d on read from %s pipe : %s\n", + errno,(fdidx[0]?"stdout":"stderr"), + (errno>0?strerror(errno):"-unknown error-")); + {ret= -1; goto father_ex;} + } + if(ret==0) { + fds[fdidx[0]]= -1; + continue; + } + buffer[ret]= 0; + channel_no= fdidx[0]+1; + ret= Write_to_channel(buffer,channel_no,!(flag&1)); + if(ret<=0) { + sprintf(errmsg,"--- error %d on write to %s : %s\n", + errno,(fdidx[0]?"stdout":"stderr"), + (errno>0?strerror(errno):"-unknown error-")); + {ret= -1; goto father_ex;} + } + } + ret= 127; + if(WIFEXITED(wait_status)) + ret= WEXITSTATUS(wait_status); +father_ex:; + if(pipes_open) { + close(stdout_pipe[0]); + close(stderr_pipe[0]); + } + return(ret); + } + + if(debug) + fprintf(stderr,"Exec_cmd():child\n"); + + /* Connect stdout and stderr to the appropriate ends of the pipes. */ + close(1); + ret= dup(stdout_pipe[1]); + if(ret==-1) { +cannot_dup_pipe:; + sprintf(errmsg, + "%s : cannot redirect standard i/o to pipes\n reason given: %s\n", + prog,strerror(errno)); + Write_to_channel(errmsg,2,!(flag&1)); + exit(1); + } + close(2); + ret= dup(stderr_pipe[1]); + if(ret==-1) + goto cannot_dup_pipe; + /* close pipes so we register EOF by the father process */ + close(stdout_pipe[0]); + close(stdout_pipe[1]); + close(stderr_pipe[0]); + close(stderr_pipe[1]); + + /* switch process to desired program */ + if(simple_arg!=NULL) { + simple_argv[0]= cmd; + simple_argv[1]= simple_arg; + simple_argv[2]= NULL; + exec_argv= simple_argv; + } else { + exec_argv= argv; + } + if(debug) { int i; + fprintf(stderr,"debug: cmd='%s'\n",cmd); + for(i=0;exec_argv[i]!=NULL;i++) + fprintf(stderr,"debug: argv[%d]='%s'\n",i,exec_argv[i]); + } + if(strchr(cmd,'/')!=NULL) + execv(cmd,exec_argv); + else + execvp(cmd,exec_argv); + sprintf(errmsg,"%s : cannot start program %s\n reason given: %s\n", + prog,cmd,strerror(errno)); + Write_to_channel(errmsg,2,!(flag&1)); + exit(127); +} + + +int Exec_cmd_line(char *prog, char *cmd_line, + int extra_argc, char **extra_argv, char *errmsg, int flag) +/* + bit0= packade mode (!bit0 of Write_to_channel()) +*/ +{ + int ret,cmd_argc= 0,i,w; + char **cmd_argv= NULL,**argv= NULL; + + ret= Sfile_make_argv("",cmd_line,&cmd_argc,&cmd_argv,1); + if(ret<=0) + {ret= -1; goto ex;} + argv= TSOB_FELD(char *,cmd_argc+extra_argc+1); + if(argv==NULL) + {ret= -1; goto ex;} + w= 0; + for(i=0;i31) + return(0); + if(flag&1) + (*data)&= ~(1<0) + sprintf(errmsg+strlen(errmsg)," %s\n",strerror(errno)); + Write_to_channel(errmsg,2,!(flag&64)); + } + return(NULL); + } + return(fp); +} + + +/* ------------------------------------------------------------------------ */ + + +#ifndef Xorriso_sregex_externaL + +#ifndef Smem_malloC +#define Smem_malloC malloc +#endif +#ifndef Smem_freE +#define Smem_freE free +#endif + + +int Sregex_string_cut(char **handle, char *text, int len, int flag) +/* + bit0= append (text!=NULL) +*/ +{ + int l=0; + char *old_handle; + + if((flag&1)&&*handle!=NULL) + l+= strlen(*handle); + old_handle= *handle; + if(text!=NULL) { + l+= len; + *handle= TSOB_FELD(char,l+1); + if(*handle==NULL) { + *handle= old_handle; + return(0); + } + if((flag&1) && old_handle!=NULL) + strcpy(*handle,old_handle); + else + (*handle)[0]= 0; + if(len>0) + strncat(*handle,text,len); + } else { + *handle= NULL; + } + if(old_handle!=NULL) + Smem_freE(old_handle); + return(1); +} + + +int Sregex_string(char **handle, char *text, int flag) +/* + bit0= append (text!=NULL) +*/ +{ + int ret,l=0; + + if(text!=NULL) + l= strlen(text); + +/* #define Sregex_looking_for_contenT 1 */ +#ifdef Sregex_looking_for_contenT + /* a debugging point if a certain text content has to be caught */ + if(text!=NULL) + if(strcmp(text,"clear")==0) + ret= 0; +#endif + + ret= Sregex_string_cut(handle,text,l,flag&1); + return(ret); +} + + +/* + from Juergen Helbing's yencode-c.txt + found at www.yenc.org , Feb 4, 2002 + license : "It is public domain - as well as the yEnc specification" + some alterations made to adapt it to Sregex_crc32() + + seems to be compatible with SFV/CSV files +*/ + +int Sregex_crc32_yenc(char *data, int len, unsigned long *crc, int flag) +/* + bit0= start of data polynom +*/ +{ + /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ + static unsigned long crc_tab[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + + int k; + unsigned long crc_val,ch1,ch2,cc; + + if(flag&1) + crc_val = ~0; + else + crc_val = ~*crc; + + for(k=0;k>8L) & 0xffffffL; + crc_val= ch1 ^ ch2; + } + *crc= ~crc_val; + return(1); +} + +#endif /* Xorriso_sregex_externaL */ + + +#ifndef Xorriso_text_shellsafe_externaL + +char *Text_shellsafe(char *in_text, char *out_text, int flag) +{ + int l,i,w=0; + + /* enclose everything by hard quotes */ + l= strlen(in_text); + out_text[w++]= '\''; + for(i=0;i=0;i--) + if(target[i]=='=' || target[i]=='\\') + offset++; + target[strlen(target)+offset]= 0; + for(i= strlen(target)-1;i>=0;i--) { + if(target[i]=='=' || target[i]=='\\') { + target[i+offset]= target[i]; + offset--; + target[i+offset]= '\\'; + } else { + target[i+offset]= target[i]; + } + } + return(1); +} + +#endif /* ! Xorriso_fileliste_externaL */ + + +#ifndef Xorriso_cleanup_externaL + +/* <<< ??? ts A71006 : will this be replaced by the libburn signal handler ? */ + +#include +typedef void (*sighandler_t)(int); + + +/* Signals to be caught */ +static int signal_list[]= { + SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, + SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, + SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, + SIGTTOU, + SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP, + SIGVTALRM, SIGXCPU, SIGXFSZ, -1 +}; +static char *signal_name_list[]= { + "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", + "SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", + "SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", + "SIGTTOU", + "SIGBUS", "SIGPOLL", "SIGPROF", "SIGSYS", "SIGTRAP", + "SIGVTALRM", "SIGXCPU", "SIGXFSZ", "@" +}; +static int signal_list_count= 24; + + +/* Signals not to be caught */ +static int non_signal_list[]= { + SIGKILL, SIGCHLD, SIGSTOP, SIGURG, -1 +}; +static int non_signal_list_count= 4; + + +/* run time dynamic part */ +static char cleanup_msg[SfileadrL]= {""}; +static int cleanup_exiting= 0; + +static void *cleanup_app_handle= NULL; +static Cleanup_app_handler_T cleanup_app_handler= NULL; +static int cleanup_perform_app_handler_first= 0; + + +static int Cleanup_handler_exit(int exit_value, int signum, int flag) +{ + int ret; + + if(cleanup_perform_app_handler_first) + if(cleanup_app_handler!=NULL) { + ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0); + if(ret==2) + return(2); + } + if(cleanup_exiting) { + if(cleanup_msg[0]!=0) + fprintf(stderr,"%s\n",cleanup_msg); + fprintf(stderr,"cleanup: ABORT : repeat by pid=%d, signum=%d\n", + getpid(),signum); + return(0); + } + cleanup_exiting= 1; + if(cleanup_msg[0]!=0) + fprintf(stderr,"%s\n",cleanup_msg); + alarm(0); + if(!cleanup_perform_app_handler_first) + if(cleanup_app_handler!=NULL) + (*cleanup_app_handler)(cleanup_app_handle,signum,0); + exit(exit_value); +} + + +static void Cleanup_handler_generic(int signum) +{ + int i; + + sprintf(cleanup_msg,"UNIX-SIGNAL caught: %d errno= %d",signum,errno); + for(i= 0; imax_sig) + max_sig= signal_list[i]; + if(signal_list[i]=non_signal_list_count) { + if(i==SIGABRT && (flag&8)) + signal(i,Cleanup_handler_generic); + else + signal(i,sig_handler); + } + } + return(1); +} + + +#endif /* ! Xorriso_cleanup_externaL */ + + +#ifndef Xorriso_dirseq_externaL + +/* ------------------------------------------------------------------------ */ +/* DirseQ : crawl along a directory's content list */ + +static int Dirseq_buffer_sizE= 1000; + +struct DirseQ { + DIR *dirpt; + int count; + char **buffer; + int buffer_size; + int buffer_fill; + int buffer_rpt; +}; + +int Dirseq_destroy(struct DirseQ **o, int flag); +int Dirseq_next_adrblock(struct DirseQ *o, char *replies[], int *reply_count, + int max_replies, int flag); + + +int Dirseq_new(struct DirseQ **o, char *dir, int flag) +/* + bit0= do not complain about failed opendir() +*/ +{ + int ret,i; + struct DirseQ *m; + + m= *o= TSOB_FELD(struct DirseQ,1); + if(m==NULL) + return(-1); + m->dirpt= NULL; + m->count= 0; + m->buffer= NULL; + m->buffer_size= 0; + m->buffer_fill= 0; + m->buffer_rpt= 0; + m->buffer= TSOB_FELD(char *,Dirseq_buffer_sizE); + if(m->buffer==NULL) + {ret= -1; goto failed;} + m->buffer_size= Dirseq_buffer_sizE; + for(i= 0;ibuffer_size;i++) + m->buffer[i]= NULL; + if(dir[0]==0) + m->dirpt= opendir("."); + else + m->dirpt= opendir(dir); + if(m->dirpt==NULL) { + if(!(flag&1)) + fprintf(stderr,"opendir(%s) failed : %s\n",dir,strerror(errno)); + ret= 0; goto failed; + } + return(1); +failed:; + Dirseq_destroy(o,0); + return(ret); +} + + +int Dirseq_destroy(struct DirseQ **o, int flag) +{ + int i; + + if(*o==NULL) + return(0); + if((*o)->dirpt!=NULL) + closedir((*o)->dirpt); + if((*o)->buffer!=NULL) { + for(i=0;i<(*o)->buffer_size;i++) + if((*o)->buffer[i]!=NULL) + free((*o)->buffer[i]); + free((char *) (*o)->buffer); + } + free((char *) *o); + (*o)= NULL; + return(1); +} + + +int Dirseq_rewind(struct DirseQ *o, int flag) +{ + rewinddir(o->dirpt); + return(1); +} + + +int Dirseq_next_adr(struct DirseQ *o, char reply[SfileadrL], int flag) +/* +flag: + bit0= permission to use buffer + bit1= do not increment counter + bit2= ignore buffer in any case + bit3= do not exclude '.' and '..' + bit4= sort buffer + bit5= sort only incomplete last buffer +return: + <0 error + 0= no more entries available + 1= ok, reply is valid +*/ +{ + int ret; + struct dirent *entry; + char *name; + + static int override_flag_0= 0,override_flag_1= 32; + flag= (flag&~override_flag_0)|override_flag_1; + + if((flag&1) && o->buffer_rpt>=o->buffer_fill) { + /* permission to buffer and buffer empty : load a buffer */ + ret= Dirseq_next_adrblock(o,o->buffer,&(o->buffer_fill), + o->buffer_size,2|4|(flag&16)); + if(ret<=0) + return(ret); + o->buffer_rpt= 0; + if((flag&32) && o->buffer_fillbuffer_size && o->buffer_fill>0) + Sort_argv(o->buffer_fill,o->buffer,0); + } + if(o->buffer_rptbuffer_fill && !(flag&4)) { + strcpy(reply,o->buffer[o->buffer_rpt]); + Sregex_string(&(o->buffer[o->buffer_rpt]),NULL,0); + (o->buffer_rpt)++; + if(!(flag&2)) + o->count++; + return(1); + } + do { + entry= readdir(o->dirpt); + if(entry==NULL) { + /* >>> how to distinguish error from EOF , do i need a (FILE *) ? */ + return(0); + } + if(strlen(entry->d_name)>4095) { + fprintf(stderr,"--- oversized directory entry (number %d) :\n %s", + o->count+1,entry->d_name); + return(-1); + } + name= entry->d_name; + if(flag&8) + break; + /* skip "." and ".." */ + } while(name[0]=='.' && ((name[1]=='.' && name[2]==0) || name[1]==0)); + strcpy(reply,name); + if(!(flag&2)) + o->count++; + return(1); +} + + +int Dirseq_next_adrblock(struct DirseQ *o, char *replies[], int *reply_count, + int max_replies, int flag) +/* @param replies A vector of Sregex_string pointers */ +/* +flag: + bit0= permission to use buffer + bit1= do not increment counter + bit2= ignore buffer in any case + bit4= sort replies +return: + <0 error + 0= no more entries available + 1= ok, reply is valid +*/ +{ + int i,ret; + char reply[SfileadrL]; + + *reply_count= 0; + for(i=0;ino_rc= 0; + m->pkt_set= 0; + m->logfile_set[0]= m->logfile_set[1]= m->logfile_set[2]= m->logfile_set[3]= 0; + m->logfile_pkt_set= 0; + return(1); +} + + +int Xorriso_prestate_destroy(struct Xorriso_prestatE **pst, int flag) +{ + if(*pst==NULL) + return(0); + free((char *) *pst); + *pst= NULL; + return(1); +} + + +/* ------------------------------- Xorriso -------------------------------- */ + + +/* maximum number of history lines to be reported with -status:long_history */ +#define Xorriso_status_history_maX 100 + +/* try to catch signals and ignore them during abort handling */ +#define Xorriso_abort_handler_defaulT (1|(2<<4)) + + +struct XorrisO { /* the global context of askme */ + + /* source */ + char progname[SfileadrL]; + + char initial_wdx[SfileadrL]; + char wdi[SfileadrL]; + char wdx[SfileadrL]; + int did_something_useful; + + + /* >>> put libisofs aspects here <<< */ + + int do_joliet; + int do_follow_links; + int do_global_uid; + uid_t global_uid; + int do_global_gid; + gid_t global_gid; + int do_overwrite; + int do_reassure; + + char volid[SfileadrL]; + + /* >>> put libburn/isoburn aspects here */ + + char indev[SfileadrL]; + char outdev[SfileadrL]; + int ban_stdio_write; + int do_dummy; + int do_close; + + + /* XORRISO options */ + int allow_graft_points; + + int dialog; + + + + /* ??? does this search stuff make sense ? */ + int search_mode; + /* 0= start text + 1= fgrep , + 2= regular expression + 3= (eventually structured) shell parser expression + 4= shell parser expression for leaf name + */ + int structured_search; + /* ( 0= flat text search ) + 1= '/' is a significant separator that cannot be matched by wildcards + ( 2= like 1 : but report only occurence in tree, no payload, no location ) + ( 3= like 2 : but report first content level of matching directories ) + 4= actually not structured but unique find mode (with search_mode 4) + */ + + int use_stdin; /* use raw stdin even if readline support is compiled */ + int result_page_length; + int result_page_width; + char mark_text[SfileadrL]; /* ( stdout+stderr, M: ) */ + int packet_output; + int status_history_max; /* for -status long_history */ + + + /* >>> put -abort_on severity parameters here <<< */ + + + /* temporary search facilities */ +#ifdef Xorriso_with_regeX + regex_t *re; + regmatch_t match[1]; +#endif /* Xorriso_with_regeX */ + char **re_constants; + int re_count; + int re_fill; + char reg_expr[2*SfileadrL]; + + /* >>> put overwrite_mode here */ + + /* run state */ + struct Xorriso_prestatE *prescan_state; + int is_dialog; + int bar_is_fresh; + char pending_option[SfileadrL]; /* eventual option entered at page prompt */ + int request_to_abort; + double idle_time; + int re_failed_at; /* mismatch position with structured_search */ + int prepended_wd; + double insert_count; + double insert_bytes; + double error_count; /* double will not roll over */ + + /* <<< ??? result (stdout, R: ) */ + char result_line[5*SfileadrL]; + int result_line_counter; + int result_page_counter; + int result_open_line_len; + + + /* info (stderr, I:) */ + char info_text[10*SfileadrL]; + +}; + + +int Xorriso_destroy(struct XorrisO **xorriso, int flag); +int Xorriso_prepare_regex(struct XorrisO *xorriso, char *adr, int flag); +int Xorriso_info(struct XorrisO *xorriso, int flag); +int Xorriso_prescan_args(struct XorrisO *xorriso, int argc, char **argv, + int flag); + +int Xorriso_execute_option(struct XorrisO *xorriso, char *line, int flag); + + +int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) +{ + int ret; + struct XorrisO *m; + + *xorriso= m= TSOB_FELD(struct XorrisO,1); + if(m==NULL) + return(-1); + strcpy(m->progname,progname); + m->initial_wdx[0]= 0; + m->wdi[0]= 0; + m->wdx[0]= 0; + m->did_something_useful= 0; + m->do_joliet= 0; + m->do_follow_links= 0; + m->do_global_uid= 0; + m->global_uid= 0; + m->volid[0]= 0; + m->do_global_gid= 0; + m->do_overwrite= 0; + m->do_reassure= 0; + m->global_gid= 0; + m->indev[0]= 0; + m->outdev[0]= 0; + m->ban_stdio_write= 0; + m->do_dummy= 0; + m->do_close= 0; + m->allow_graft_points= 0; + m->dialog= 0; + m->search_mode= 0; + m->structured_search= 1; + m->use_stdin= 0; + m->result_page_length= 0; + m->result_page_width= 80; + m->mark_text[0]= 0; + m->packet_output= 0; + m->status_history_max= Xorriso_status_history_maX; +#ifdef Xorriso_with_regeX + m->re= NULL; + /* >>> ??? how to initialize m->match[0] ? */ +#endif /* Xorriso_with_regeX */ + m->re_constants= NULL; + m->re_count= 0; + m->re_fill= 0; + m->reg_expr[0]= 0; + m->prescan_state= NULL; + m->is_dialog= 0; + m->bar_is_fresh= 0; + m->pending_option[0]= 0; + m->request_to_abort= 0; + m->idle_time= 0.0; + m->re_failed_at= -1; + m->prepended_wd= 0; + m->insert_count= 0; + m->insert_bytes= 0; + m->error_count= 0; + m->result_line[0]= 0; + m->result_line_counter= 0; + m->result_page_counter= 0; + m->result_open_line_len= 0; + m->info_text[0]= 0; + + ret= Xorriso_prestate_new(&(m->prescan_state),0); + if(ret<=0) + goto failed; + + return(1); +failed: + Xorriso_destroy(xorriso,0); + return(-1); +} + + +int Xorriso_destroy_re(struct XorrisO *m, int flag) +{ + int i; + +#ifdef Xorriso_with_regeX + if(m->re!=NULL) { + for(i=0;ire_fill;i++) { + if(m->re_constants!=NULL) + if(m->re_constants[i]!=NULL) + continue; /* ,->re[i] was never subject to regcomp() */ + regfree(&(m->re[i])); + } + free((char *) m->re); + m->re= NULL; + } +#endif /* Xorriso_with_regeX */ + + if(m->re_constants!=NULL) { + for(i=0;ire_fill;i++) + if(m->re_constants[i]!=NULL) + free(m->re_constants[i]); + free((char *) m->re_constants); + m->re_constants= NULL; + } + m->re_count= 0; + m->re_fill= 0; + return(1); +} + + +int Xorriso_destroy(struct XorrisO **xorriso, int flag) +{ + struct XorrisO *m; + + m= *xorriso; + if(m==NULL) + return(0); + Xorriso_destroy_re(m,0); + Xorriso_prestate_destroy(&(m->prescan_state),0); + + free((char *) m); + *xorriso= NULL; + return(1); +} + + +int Xorriso_clone_options(struct XorrisO *target, struct XorrisO *source, + int flag) +{ + int ret; + + target->dialog= source->dialog; + target->search_mode= source->search_mode; + target->use_stdin= source->use_stdin; + target->result_page_length= source->result_page_length; + target->result_page_width= source->result_page_width; + strcpy(target->mark_text,source->mark_text); + target->packet_output= source->packet_output; + target->status_history_max= source->status_history_max; + ret= Xorriso_prepare_regex(target,source->reg_expr,0); + if(ret<=0) + return(ret); + target->is_dialog= source->is_dialog; + target->bar_is_fresh= source->bar_is_fresh; + target->request_to_abort= source->request_to_abort; + target->error_count= source->error_count; + target->insert_count= source->insert_count; + target->insert_bytes= source->insert_bytes; + target->prepended_wd= source->prepended_wd; + return(1); +} + + +int Xorriso_dialog_input(struct XorrisO *xorriso, char line[], int linesize, + int flag) +/* + bit0= do not write to history + bit1= do not read input (but eventually write to history) + bit2= do not write to history line which begin with "-history:" or "-history " +*/ +{ + char *cpt= NULL; + int ret; +#ifdef Xorriso_with_readlinE + int l; + static char last_input[SfileadrL]= {""}; +#endif /* ! Xorriso_with_readlinE */ + double tdiff; + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv,&tz); + tdiff= tv.tv_sec+(1.e-6*(double) tv.tv_usec); + + fflush(stdout); + +#ifdef Xorriso_with_readlinE + + if(xorriso->use_stdin) { + if(flag&2) + {ret= 1; goto ex;} + if(Sfile_fgets(line,linesize-1,stdin)==NULL) { + /* need a very dramatic end */ + kill(getpid(),SIGHUP); + {ret= -1; goto ex;} + } + {ret= 1; goto ex;} + } + if(flag&2) { + cpt= NULL; + } else { + cpt= readline(""); + if(cpt==NULL) { + /* need a very dramatic end */ + kill(getpid(),SIGHUP); + {ret= -1; goto ex;} + } + l= strlen(cpt); + if(l>=linesize) { + strncpy(line,cpt,linesize-1); + line[sizeof(line)-1]= 0; + } else + strcpy(line,cpt); + } + if(line[0]!=0 && strcmp(last_input,line)!=0 && !(flag&1)) + if(!((flag&4) && + (strncmp(line,"-history:",9)==0 || strncmp(line,"-history ",9)==0))) { + add_history(line); + strncpy(last_input,line,sizeof(last_input)-1); + last_input[sizeof(last_input)-1]= 0; + } + +#else /* Xorriso_with_readlinE */ + + if(flag&2) + {ret= 1; goto ex;} + if(Sfile_fgets(line,linesize-1,stdin)==NULL) { + /* need a very dramatic end */ + kill(getpid(),SIGHUP); + {ret= -1; goto ex;} + } + +#endif /* ! Xorriso_with_readlinE */ + + ret= 1; +ex:; + if(cpt!=NULL) + free(cpt); + gettimeofday(&tv,&tz); + xorriso->idle_time+= tv.tv_sec+(1.e-6*(double) tv.tv_usec)-tdiff; + return(ret); +} + + +int Xorriso_request_confirmation(struct XorrisO *xorriso, int flag) +/* + bit0= important operation going on: + demand confirmation of abort, only abort on @@@ + bit1= mark '@' and '@@' by return 4 + bit2= accept: i=ignore , r=retry , x=abort + bit3= @@@ = 'done reading' rather than 'abort' +*/ +/* return: <=0 error , 1=go on , 2=abort , 3=redo request, 4=see flag bit1 + (5=skip volume) , 6=retry failed operation + */ +{ + int ret; + char line[SfileadrL],*cpt,previous_line[SfileadrL],*abort_req_text,*abort_really_text; + + if(flag&8) { + abort_req_text= "request to end"; + abort_really_text= "done reading"; + } else { + abort_req_text= "request to abort"; + abort_really_text= "abort"; + } + ret= Xorriso_dialog_input(xorriso,line,sizeof(line),1); + xorriso->result_line_counter= 0; + xorriso->result_page_counter++; + if(ret<=0) + if(xorriso->result_page_length>0) + xorriso->result_page_length= -xorriso->result_page_length; + + cpt= line; + if(*cpt=='@') { + if(strcmp(cpt,"@@@")==0) { +request_to_abort:; + if(flag&1) { + strcpy(previous_line,cpt); + sprintf(xorriso->info_text, + "....... [%s = %s registered. Really %s ? (y/n) ] .......\n", + cpt,abort_req_text,abort_really_text); + Xorriso_info(xorriso,0); + ret= Xorriso_dialog_input(xorriso,line,sizeof(line),1); + if(ret<=0) + return(ret); + cpt= line; + if(strcmp(cpt,previous_line)==0 || + ((*cpt=='Y' || *cpt=='y' || *cpt=='j' || *cpt=='J' || *cpt=='1') && + *(cpt+1)==0)) { + xorriso->request_to_abort= 1; + sprintf(xorriso->info_text, + "------- ( %s confirmed )\n",abort_req_text); + Xorriso_info(xorriso,0); + return(2); + } + sprintf(xorriso->info_text, + "....... ( %s revoked )\n",abort_req_text); + Xorriso_info(xorriso,0); + return(3); + } + xorriso->request_to_abort= 1; + sprintf(xorriso->info_text, +"----------- [%s = request to abort registered. Operation ends ] ------------\n", + cpt); + Xorriso_info(xorriso,0); + return(2); + } else if(strcmp(cpt,"@@")==0) { + goto klammer_affe; + + } else if(strcmp(cpt,"@")==0) { +klammer_affe:; + if(xorriso->result_page_length>0) + xorriso->result_page_length= -xorriso->result_page_length; + if(flag&1) { + sprintf(xorriso->info_text, +"... [@ = page prompt suppression registered. -page disabled temporarily ] ...\n"); + Xorriso_info(xorriso,0); + } + + } else { + Xorriso_dialog_input(xorriso,cpt,strlen(line)+1,2); /* write to history */ + sprintf(xorriso->info_text, + "--- Unrecognized input beginning with @. Please enter someting else.\n"); + Xorriso_info(xorriso,0); + return(3); + } + if(flag&2) + return(4); + if(flag&1) + return(3); + return(1); + } else if(flag&4) { + + if(strcmp(cpt,"i")==0 || strcmp(cpt,"I")==0 || *cpt==0) { + return(1); + } else if(strcmp(cpt,"r")==0 || strcmp(cpt,"R")==0) { + return(6); + } else if(strcmp(cpt,"x")==0 || strcmp(cpt,"X")==0) { + goto request_to_abort; + } else { + /* >>> unknown input */ + sprintf(xorriso->info_text, + "--- Please enter one of : empty line, i, r, x, @, @@, @@@\n"); + Xorriso_info(xorriso,0); + return(3); + } + + } else if(*cpt=='-' && !(flag&1)) { + Xorriso_dialog_input(xorriso,cpt,strlen(line)+1,2); /* write to history */ + strcpy(xorriso->pending_option,cpt); + xorriso->request_to_abort= 1; + sprintf(xorriso->info_text, +"------------ [-* = input of option registered. Operation ends ] -------------\n"); + Xorriso_info(xorriso,0); + return(2); + + } else if(*cpt!=0 && !(flag&1)) { + Xorriso_dialog_input(xorriso,cpt,strlen(line)+1,2); /* write to history */ + strcpy(xorriso->pending_option,cpt); + xorriso->request_to_abort= 1; + sprintf(xorriso->info_text, +"------------ [ input of searchtext registered. Operation ends ] -------------\n"); + Xorriso_info(xorriso,0); + return(2); + } else if(*cpt!=0) { + Xorriso_dialog_input(xorriso,cpt,strlen(line)+1,2); /* write to history */ + sprintf(xorriso->info_text, + "--- Please enter one of : empty line, @, @@, @@@\n"); + Xorriso_info(xorriso,0); + return(3); + } + return(1); +} + + +int Xorriso_predict_linecount(struct XorrisO *xorriso, char *line, + int *linecount, int flag) +{ + int width,l; + char *spt,*ept; + + *linecount= 0; + spt= line; + width= xorriso->result_page_width; + while(1) { + ept= strchr(spt,'\n'); + if(ept==NULL) + l= strlen(spt); + else + l= ept-spt; + l+= xorriso->result_open_line_len; + if(ept!=NULL && l==0) + (*linecount)++; + else { + (*linecount)+= l/width; + if(ept==NULL) { + xorriso->result_open_line_len= l%width; + break; + } + (*linecount)+= !!(l%width); + } + xorriso->result_open_line_len= 0; + spt= ept+1; + } + return(1); +} + + +int Xorriso_pager(struct XorrisO *xorriso, char *line, int flag) +/* + bit1= mark '@' by return 4 +*/ +/* return: <=0 error , 1=go on , 2=abort , 4=see flag bit1*/ +{ + int ret,linecount; + char info_text[10*SfileadrL]; + + if(xorriso->result_page_length<=0) + return(1); + Xorriso_predict_linecount(xorriso,line,&linecount,0); + if(xorriso->result_line_counter+linecount>xorriso->result_page_length) { +ask_for_page:; + strcpy(info_text,xorriso->info_text); + sprintf(xorriso->info_text,"\n"); + Xorriso_info(xorriso,0); + sprintf(xorriso->info_text, +".... [Press Enter to continue. @,Enter avoids further stops. @@@ aborts] ....\n"); + Xorriso_info(xorriso,0); + ret= Xorriso_request_confirmation(xorriso,flag&2); + strcpy(xorriso->info_text,info_text); + if(ret<=0) + return(ret); + if(ret==2) + return(2); + if(ret==3) + goto ask_for_page; + } + xorriso->result_line_counter+= linecount; + return(1); +} + + +int Xorriso_result(struct XorrisO *xorriso, int flag) +/* + bit0= no considerations or computations or dialog. Just put out. +*/ +{ + int ret; + + if(flag&1) + goto put_it_out; + if(xorriso->request_to_abort) + return(1); + if(xorriso->result_page_length>0) { + ret= Xorriso_pager(xorriso,xorriso->result_line,2); + if(ret<=0) + return(ret); + if(ret==2) + return(1); + if(xorriso->request_to_abort) + return(1); + } +put_it_out:; + xorriso->bar_is_fresh= 0; + ret= Write_to_channel(xorriso->result_line,1,!xorriso->packet_output); + return(ret); +} + + +int Xorriso_info(struct XorrisO *xorriso, int flag) +/* + bit0= use pager (as with result) + bit1= permission to suppress output +*/ +{ + int ret; + + if(flag&2) + if(xorriso->request_to_abort) + return(1); + if(flag&1) { + ret= Xorriso_pager(xorriso,xorriso->info_text,2); + if(ret<=0) + return(ret); + if(ret==2) + return(1); + if(flag&2) + if(xorriso->request_to_abort) + return(1); + } + xorriso->bar_is_fresh= 0; + ret= Write_to_channel(xorriso->info_text,2,!xorriso->packet_output); + return(ret); +} + + +int Xorriso_mark(struct XorrisO *xorriso, int flag) +{ + int ret= 1,r_ret,i_ret; + + if(xorriso->mark_text[0]==0) + return(1); + if(xorriso->packet_output) + ret= Write_to_channel(xorriso->mark_text,3,0); + else { + sprintf(xorriso->result_line,"%s\n",xorriso->mark_text); + r_ret= Xorriso_result(xorriso,1); + strcpy(xorriso->info_text,xorriso->result_line); + i_ret= Xorriso_info(xorriso,0); + if(r_ret==0 || i_ret==0) + ret= 0; + } + return(ret); +} + + +int Xorriso_restxt(struct XorrisO *xorriso, char *text) +{ + int ret; + + strcpy(xorriso->result_line,text); + ret= Xorriso_result(xorriso,0); + return(ret); +} + + +int Xorriso_reset_counters(struct XorrisO *xorriso, int flag) +/* + bit0= reset xorriso->found to -1 +*/ +{ + xorriso->error_count= 0; + xorriso->insert_count= 0; + xorriso->insert_bytes= 0; + return(1); +} + + +int Xorriso__bourne_to_reg(char bourne_expr[], char reg_expr[], int flag) +/* reg_expr should be twice as large as bourne_expr ( + 2 to be exact) */ +/* return: 2= bourne_expr is surely a constant */ +{ + char *wpt,*lpt; + int backslash= 0,is_constant= 1,in_square_brackets= 0; + int first_in_square_brackets=0; + + wpt= reg_expr; + lpt= bourne_expr; + + *(wpt++)= '^'; + + while(*lpt!=0){ + if(first_in_square_brackets>0) + first_in_square_brackets--; + if(!backslash){ + switch(*lpt){ + case '?': + *(wpt++)= '.'; + is_constant= 0; + break;case '*': + *(wpt++)= '.'; + *(wpt++)= '*'; + is_constant= 0; + break;case '.': + *(wpt++)= '\\'; + *(wpt++)= '.'; + break;case '+': + *(wpt++)= '\\'; + *(wpt++)= '+'; + break;case '[': + *(wpt++)= *lpt; + first_in_square_brackets= 2; + in_square_brackets= 1; + is_constant= 0; + break;case ']': + *(wpt++)= *lpt; + in_square_brackets= 0; + break;case '!': + if(first_in_square_brackets) + *(wpt++)= '^'; + else if(in_square_brackets) + *(wpt++)= '!'; + else { + *(wpt++)= '\\'; + *(wpt++)= '!'; + } + break;case '^': + if(in_square_brackets) + *(wpt++)= '^'; + else + *(wpt++)= '\\'; + *(wpt++)= '^'; + break;case '$': + *(wpt++)= '\\'; + *(wpt++)= '$'; + break;case '\\': + backslash= 1; + *(wpt++)= '\\'; + is_constant= 0; + break;default: + *(wpt++)= *lpt; + } + } else { + backslash= 0; + *(wpt++)= *lpt; + } + lpt++; + } + *(wpt++)= '$'; + *wpt= 0; + return(1+(is_constant>0)); +} + + +int Xorriso_prepare_regex(struct XorrisO *xorriso, char *adr, int flag) +/* + bit0= do not augment relative structured search by xorriso->wd +*/ +{ + int l,ret,i,count,bonked= 0,is_constant; + char *cpt,*npt,adr_part[2*SfileadrL],absolute_adr[2*SfileadrL],*adr_start; + +#ifndef Xorriso_with_regeX + + if(xorriso->search_mode==2 || + (xorriso->search_mode==3 && xorriso->structured_search==0)) { +no_regex_available:; + sprintf(xorriso->info_text,"%s : regular expressions not implemented\n", + xorriso->progname); + Xorriso_info(xorriso,0); + return(0); + } + +#endif /* ! Xorriso_with_regeX */ + + if(xorriso->search_mode>=2 && xorriso->search_mode<=4) { + if(xorriso->search_mode==3 || xorriso->search_mode==4) { + l= strlen(adr)+strlen(xorriso->wdi)+1; + if(l*2+2>sizeof(xorriso->reg_expr) || l*2+2>sizeof(adr_part)) { + sprintf(xorriso->info_text,"%s : search text too long\n",xorriso->progname); + Xorriso_info(xorriso,0); + return(0); + } + } + Xorriso_destroy_re(xorriso,0); + if(xorriso->structured_search && xorriso->search_mode==3) { + if(adr[0]!='/' && !(flag&1)) { + /* relative expression : prepend working directory */ + sprintf(absolute_adr,"%s/%s",xorriso->wdi,adr); + adr_start= absolute_adr; + xorriso->prepended_wd= 1; + } else + adr_start= adr; + /* count slashes */; + cpt= adr_start; + while(*cpt=='/') + cpt++; + for(i= 0;1;i++) { + cpt= strchr(cpt,'/'); + if(cpt==NULL) + break; + while(*cpt=='/') + cpt++; + } + count= i+1; + +#ifdef Xorriso_with_regeX + xorriso->re= TSOB_FELD(regex_t,count); + if(xorriso->re==NULL) + return(-1); +#endif /* Xorriso_with_regeX */ + + xorriso->re_constants= TSOB_FELD(char *,count); + if(xorriso->re_constants==NULL) + return(-1); + for(i= 0;ire_constants[i]= NULL; + xorriso->re_count= count; + xorriso->re_fill= 0; + + /* loop over slash chunks*/; + cpt= adr_start; + xorriso->re_fill= 0; + while(*cpt=='/') + cpt++; + for(i= 0;ire_fill<=0) { + bonked= 1; + goto next_adr_part; + } + if(xorriso->re_constants[xorriso->re_fill-1]!=NULL) { + free(xorriso->re_constants[xorriso->re_fill-1]); + xorriso->re_constants[xorriso->re_fill-1]= NULL; + } else +#ifdef Xorriso_with_regeX + regfree(&(xorriso->re[xorriso->re_fill-1])); +#else /* Xorriso_with_regeX */ + ; +#endif /* ! Xorriso_with_regeX */ + (xorriso->re_fill)--; + goto next_adr_part; + } + if(strcmp(adr_part,"*")==0) { + adr_part[0]= 0; + ret= 2; + } else + ret= Xorriso__bourne_to_reg(adr_part,xorriso->reg_expr,0); + if(ret==2) { + if(Sregex_string(&(xorriso->re_constants[xorriso->re_fill]),adr_part,0) + <=0) + return(-1); + } else { + +#ifdef Xorriso_with_regeX + if(regcomp(&(xorriso->re[xorriso->re_fill]),xorriso->reg_expr,0)!=0) + goto cannot_compile; +#else /* Xorriso_with_regeX */ + if(!warned_of_regex) { + sprintf(xorriso->info_text, + "=== Note: no wildcards get recognized besides single '*'\n"); + Xorriso_info(xorriso,0); + warned_of_regex= 1; + } + if(Sregex_string(&(xorriso->re_constants[xorriso->re_fill]),adr_part,0) + <=0) + return(-1); +#endif /* ! Xorriso_with_regeX */ + + } + xorriso->re_fill++; +next_adr_part:; + if(i==count-1) + break; + cpt= npt+1; + while(*cpt=='/') + cpt++; + } + if(bonked) { + sprintf(xorriso->info_text, + "=== Note: Your '..' bonked at the root directory.\n"); + Xorriso_info(xorriso,0); + } + + Xorriso__bourne_to_reg(adr_start,xorriso->reg_expr,0); /* just for show */ + + } else { + is_constant= 0; + if(strcmp(adr,"*")==0) { + is_constant= 1; + } else if(xorriso->search_mode==3 || xorriso->search_mode==4) { + ret= Xorriso__bourne_to_reg(adr,xorriso->reg_expr,0); + is_constant= (ret==2); + } else + strcpy(xorriso->reg_expr,adr); + xorriso->re_count= 0; /* tells matcher that this is not structured */ + xorriso->re_constants= TSOB_FELD(char *,1); + if(xorriso->re_constants==NULL) + return(-1); + xorriso->re_constants[0]= NULL; + if(is_constant) { + if(strcmp(adr,"*")==0) { + if(Sregex_string(&(xorriso->re_constants[0]),"",0)<=0) + return(-1); + } else { + if(Sregex_string(&(xorriso->re_constants[0]),adr,0)<=0) + return(-1); + } + xorriso->re_fill= 1; + } else { +#ifdef Xorriso_with_regeX + xorriso->re= TSOB_FELD(regex_t,1); + if(xorriso->re==NULL) + return(-1); + if(regcomp(&(xorriso->re[0]),xorriso->reg_expr,0)!=0) { +cannot_compile:; + sprintf(xorriso->info_text, + "%s : cannot compile regular expression : %s\n", + xorriso->progname,xorriso->reg_expr); + Xorriso_info(xorriso,0); + return(0); + } +#else /* Xorriso_with_regeX */ + sprintf(xorriso->info_text, + Xorriso_info(xorriso,0); + if(Sregex_string(&(xorriso->re_constants[0]),adr,0)<=0) + return(-1); + xorriso->re_fill= 1; +#endif /* ! Xorriso_with_regeX */ + } + + } + } + return(1); +} + + +int Xorriso_regexec(struct XorrisO *xorriso, char *to_match, int *failed_at, + int flag) +/* + bit0= do not shortcut last component of to_match + bit2= retry beginning at failed last component +*/ +{ + int ret,i,re_start= 0,reg_nomatch= -1; + char *cpt,*npt,adr_part[SfileadrL],*mpt; + +#ifdef Xorriso_with_regeX + reg_nomatch= REG_NOMATCH; +#endif /* Xorriso_with_regeX */ + + *failed_at= 0; + if(!(xorriso->structured_search && xorriso->re_count>0)) { + if(xorriso->re_constants!=NULL) + if(xorriso->re_constants[0]!=NULL) { + if(xorriso->re_constants[0][0]==0) + return(0); + if(strcmp(xorriso->re_constants[0],to_match)!=0) + return(reg_nomatch); + return(0); + } +#ifdef Xorriso_with_regeX + ret= regexec(&(xorriso->re[0]),to_match,1,xorriso->match,0); +#else + ret= reg_nomatch; +#endif /* ! Xorriso_with_regeX */ + + return(ret); + } + + cpt= to_match; + while(*cpt=='/') + cpt++; + if(flag&4) + re_start= xorriso->re_failed_at; + if(re_start<0) + re_start= 0; + for(i= re_start;ire_fill;i++) { + *failed_at= i; + npt= strchr(cpt,'/'); + if(npt==NULL) { + if(ire_fill-1 && !(flag&1)) + return(reg_nomatch); /* this must be the last expression part */ + mpt= cpt; + } else { + strncpy(adr_part,cpt,npt-cpt); + adr_part[npt-cpt]= 0; + mpt= adr_part; + } + if(xorriso->re_constants[i]!=NULL) { + if(xorriso->re_constants[i][0]!=0) /* empty constant matches anything */ + if(strcmp(xorriso->re_constants[i],mpt)!=0) + return(reg_nomatch); + } else { + +#ifdef Xorriso_with_regeX + ret= regexec(&(xorriso->re[i]),mpt,1,xorriso->match,0); + if(ret!=0) + return(ret); +#else + return(reg_nomatch); +#endif /* ! Xorriso_with_regeX */ + + } + if(npt==NULL) { + if(i>=xorriso->re_fill-1) + return(0); /* MATCH */ + *failed_at= i+1; + return(reg_nomatch); + } + cpt= npt+1; + while(*cpt=='/') + cpt++; + } + *failed_at= xorriso->re_fill; + return(reg_nomatch); +} + + +int Xorriso_match_file(struct XorrisO *xorriso, char *to_match, char *adr, + int flag) +/* + bit0= match under fsm rules: with search_mode 0 : do not accept partial match + bit1= with xorriso->search_mode==4 : do not check for '/' + bit2= single level bit for Xorriso_regexec() +*/ +/* return: + <0 error + 0 no match + 1 match + 2 match with request to break volume loop +*/ +{ + int ret,l,failed_at; + char *cpt; + + l= strlen(to_match); + if(xorriso->search_mode==0) { + if(flag&1) { + if(strcmp(adr,to_match)==0) + return(2); + } else { + if(strncmp(adr,to_match,l)==0) + if(adr[l]=='/'||adr[l]==0) + return(2); + } + l= strlen(adr); + if(strncmp(to_match,adr,l)==0) + if(to_match[l]=='/'||to_match[l]==0) { + return(1); + } + } else if(xorriso->search_mode==1) { + if(strstr(to_match,adr)!=NULL) + return(1); + } else if(xorriso->search_mode>=2 && xorriso->search_mode<=4) { + if(xorriso->search_mode==4 && !(flag&2)) { + cpt= strrchr(to_match,'/'); + if(cpt==NULL) + cpt= to_match; + else + cpt++; + } else + cpt= to_match; + ret= Xorriso_regexec(xorriso,cpt,&failed_at,1|(flag&4)); + if(ret==0) + return(1); + xorriso->re_failed_at= failed_at; + } + return(0); +} + + +int Xorriso_status_result(struct XorrisO *xorriso, char *filter, FILE *fp, + int flag) +/* +bit1= do only report to fp +*/ +{ + int ret,l; + + if(filter!=NULL) + if(filter[0]=='-') { + l= strlen(filter); + if(strncmp(filter,xorriso->result_line,l)!=0) + return(2); + } + if(!(flag&2)) + Xorriso_result(xorriso,0); + if(fp!=NULL) { + ret= fwrite(xorriso->result_line,strlen(xorriso->result_line),1,fp); + if(ret<=0) + return(ret); + } + return(1); +} + + +int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag) +/* + bit0= do only report non-default settings + bit1= do only report to fp + bit2= report current -resume status even if bit0 is set, but only if valid + bit3= report readline history + bit4= report -resume options indirectly as + -options_from_file:${resume_state_file}_pos +*/ +{ + int is_default,no_defaults; + char *line, sfe[4*SfileadrL]; + + no_defaults= flag&1; + line= xorriso->result_line; + + is_default= 0; + if(xorriso->dialog) + sprintf(line,"-dialog\n"); + else { + sprintf(line,"-dialog_reset\n"); + is_default= 1; + } + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->result_page_length==0 && xorriso->result_page_width==80); + sprintf(line,"-page:%d:%d\n", + (xorriso->result_page_length>=0?xorriso->result_page_length + :-xorriso->result_page_length), + xorriso->result_page_width); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= 0; + if(xorriso->use_stdin) + sprintf(line,"-use_stdin\n"); + else { + sprintf(line,"-use_readline\n"); + is_default= 1; + } + 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)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->mark_text[0]==0); + sprintf(line,"-mark %s\n",Text_shellsafe(xorriso->mark_text,sfe,0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + sprintf(line,"-prog %s\n",Text_shellsafe(xorriso->progname,sfe,0)); + Xorriso_status_result(xorriso,filter,fp,flag&2); + + sprintf(line,"-cd %s\n", + (xorriso->wdi[0] ? Text_shellsafe(xorriso->wdi,sfe,0) : "'/'")); + Xorriso_status_result(xorriso,filter,fp,flag&2); + + if(xorriso->status_history_max!=Xorriso_status_history_maX || !no_defaults) { + sprintf(line,"-status_history_max %d\n",xorriso->status_history_max); + Xorriso_status_result(xorriso,filter,fp,flag&2); + } + +#ifdef Xorriso_with_readlinE + + if((flag&8) && xorriso->status_history_max>0) { + HIST_ENTRY **hl; + int hc,i; + + hl= history_list(); + if(hl!=NULL) { + for(hc= 0;hl[hc]!=NULL;hc++); + if(hc>0) + if(strcmp(hl[hc-1]->line,"-end")==0) + hc--; + if(hc>=xorriso->status_history_max) + i= hc-xorriso->status_history_max; + else + i= 0; + for(;iline,sfe,0)); + Xorriso_status_result(xorriso,filter,fp,flag&2); + } + } + } + +#endif /* Xorriso_with_readlinE */ + + return(1); +} + + +int Xorriso_exec(struct XorrisO *xorriso, char *cmd, int flag) +{ + char *spt,*cpt,**argv= NULL,errmsg[2*SfileadrL]; + int is_done= 0,argc= 0,widx= 0,cmd_l,pass,ret; + + cmd_l= strlen(cmd); + for(pass=0;pass<2;pass++) { + is_done= 0; + widx= 0; + for(spt= cmd;!is_done;spt= cpt+1) { + for(cpt= spt;*cpt!=0 && *cpt!=':' && *cpt!=' ';cpt++); + if(*cpt==0) + is_done= 1; + if(pass==0) { + argc++; + } else { + *cpt= 0; + if(Sregex_string(&(argv[widx]),spt,0)<=0) + {ret= -1; goto ex;} + widx++; + } + } + if(pass==0) { + if(argc==0) + {ret= 2; goto ex;} + argv= TSOB_FELD(char *,argc+1); + if(argv==NULL) + {ret= -1; goto ex;} + for(widx= 0;widxprogname,cmd,NULL,argv,errmsg, + !!(xorriso->packet_output)); + if(ret<0) + goto ex; + if(ret>0) { + for(widx=0; widxinfo_text,"--- failed : %s\n",cmd); + Xorriso_info(xorriso,0); + if(errmsg[0]!=0) { + sprintf(xorriso->info_text,"--- message: %s\n",errmsg); + Xorriso_info(xorriso,1); + } + {ret= 0; goto ex;} + } + ret= 1; +ex: + if(argv!=NULL) { + for(widx=0;widx>> LIBISOBURN : -abort_on %s",severity); + return(1); +} + + +/* Option -add */ +int Xorriso_option_add(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int i, end_idx; + + end_idx= Xorriso__end_idx(argc, argv, *idx, 0); + + fprintf(stderr, ">>> LIBISOFS : -add "); + for(i= *idx; i>> XORRISO : decode timestring %s\n", timestring); + fprintf(stderr, ">>> LIBISOFS : -alter_date %s %s ", + time_type, timestring); + for(i= *idx; iban_stdio_write= 1; + return(1); +} + + +/* Option -blank */ +int Xorriso_option_blank(struct XorrisO *xorriso, char *mode, int flag) +{ + fprintf(stderr, ">>> LIBISOBURN : would perform -blank %s on %s", + mode, xorriso->indev); + return(1); +} + + +/* Option -cd alias -cdi */ +int Xorriso_option_cdi(struct XorrisO *xorriso, char *iso_rr_path, int flag) +{ + char sfe[4*SfileadrL]; + int ret, l; + + if (strlen(iso_rr_path)>sizeof(xorriso->wdi)) { + sprintf(xorriso->info_text,"%s: -cdi: iso_rr_path too long (%d > %d)\n", + xorriso->progname, strlen(iso_rr_path), sizeof(xorriso->wdi)-1); + Xorriso_info(xorriso,0); + return(0); + } + sprintf(xorriso->info_text,"previous working directory:\n"); + Xorriso_info(xorriso,0); + sprintf(xorriso->result_line,"%s/\n",Text_shellsafe(xorriso->wdi, sfe, 0)); + Xorriso_result(xorriso,0); + if(iso_rr_path[0]==0) { + strcpy(xorriso->wdi,"/"); + Xorriso_option_pwdi(xorriso, 0); + return(1); + } + + ret= 1; + /* >>> LIBISOFS: check whether directory exists in ISO image */; + + if(ret<=0) { + sprintf(xorriso->info_text, + "-cdi: not found or not a directory :\n%s\n",iso_rr_path); + Xorriso_info(xorriso,0); + return(0); + } + strcpy(xorriso->wdi,iso_rr_path); + l= strlen(xorriso->wdi); + while(l>0) + if(xorriso->wdi[l-1]=='/') + xorriso->wdi[--l]= 0; + else + break; + Xorriso_option_pwdi(xorriso, 0); + return(1); +} + + +/* Option -cdx */ +int Xorriso_option_cdx(struct XorrisO *xorriso, char *disk_path, int flag) +{ + char sfe[4*SfileadrL]; + int ret, l; + + if (strlen(disk_path)>sizeof(xorriso->wdx)) { + sprintf(xorriso->info_text,"%s: -cdx: disk_path too long (%d > %d)\n", + xorriso->progname, strlen(disk_path), sizeof(xorriso->wdx)-1); + Xorriso_info(xorriso,0); + return(0); + } + sprintf(xorriso->info_text,"previous working directory on hard disk:\n"); + Xorriso_info(xorriso,0); + sprintf(xorriso->result_line,"%s/\n",Text_shellsafe(xorriso->wdx, sfe, 0)); + Xorriso_result(xorriso,0); + if(disk_path[0]==0) { + strcpy(xorriso->wdx,"/"); + Xorriso_option_pwdx(xorriso, 0); + return(1); + } + + ret= 1; + /* >>> XORRISO: check whether directory exists on disk */; + + if(ret<=0) { + sprintf(xorriso->info_text, + "-cdx: not found or not a directory :\n%s\n",disk_path); + Xorriso_info(xorriso,0); + return(0); + } + strcpy(xorriso->wdx,disk_path); + l= strlen(xorriso->wdx); + while(l>0) + if(xorriso->wdx[l-1]=='/') + xorriso->wdx[--l]= 0; + else + break; + Xorriso_option_pwdx(xorriso, 0); + return(1); +} + + +/* Option -chgrp alias -chgrpi */ +int Xorriso_option_chgrpi(struct XorrisO *xorriso, char *gid, char *path, + int argc, char **argv, int *idx, int flag) +{ + int i, end_idx; + + end_idx= Xorriso__end_idx(argc, argv, *idx, 0); + + fprintf(stderr, ">>> LIBISOFS : would perform -chgrpi %s %s ", gid, path); + for(i= *idx; i>> LIBISOFS : would perform -chmodi %s %s ", mode, path); + for(i= *idx; i>> LIBISOFS : would perform -chowni %s %s ", uid, path); + for(i= *idx; ido_close= !!strcmp(mode, "off"); + return(1); +} + + +/* Option -commit */ +int Xorriso_option_commit(struct XorrisO *xorriso, int flag) +{ + + fprintf(stderr, ">>> LIBISOBURN : -commit\n"); + + return(1); +} + + +/* Option -cp_r alias -cp_ri */ +int Xorriso_option_cp_ri(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int i, end_idx; + + end_idx= Xorriso__end_idx(argc, argv, *idx, 0); + + fprintf(stderr, ">>> LIBISOFS : -cp_ri X: "); + for(i= *idx; i I: %s", argv[end_idx-1]); + fprintf(stderr, "\n"); + + (*idx)= end_idx; + return(1); +} + + +/* Option -cut_out */ +int Xorriso_option_cut_out(struct XorrisO *xorriso, char *disk_path, + off_t startbyte, off_t bytecount, char *iso_rr_path, int flag) +{ + + fprintf(stderr, + ">>> LIBISOFS : would cut out from %s , byte %.f to %.f, and graft as %s", + disk_path, (double) startbyte, (double) (startbyte+bytecount), + iso_rr_path); + + return(1); +} + + +/* Options -dev , -indev, -outdev */ +/** @param flag bit0=use as indev , bit1= use as outdev */ +int Xorriso_option_dev(struct XorrisO *xorriso, char *adr, int flag) +{ + if((flag&3)==0) + flag|= 3; + + fprintf(stderr, ">>> XORRISO : would execute -%sdev %s", + ((flag&3)==1 ? "in" : ((flag&3)==2 ? "out" : "")), adr); + + return(1); +} + + +/* Option -devices */ +int Xorriso_option_devices(struct XorrisO *xorriso, int flag) +{ + fprintf(stderr, ">>> LIBISOBURN : -devices\n"); + return(1); +} + + +/* Option -dialog "on"|"off" */ +int Xorriso_option_dialog(struct XorrisO *xorriso, char *mode, int flag) +{ + xorriso->dialog= !!strcmp(mode, "off"); + return(1); +} + + +/* Option -dummy "on"|"off" */ +int Xorriso_option_dummy(struct XorrisO *xorriso, char *mode, int flag) +{ + xorriso->do_dummy= !!strcmp(mode, "off"); + return(1); +} + + +/* Option -eject */ +int Xorriso_option_eject(struct XorrisO *xorriso, char *which, int flag) +{ + char *drive1="", *drive2=""; + + if(strncmp(which,"in",2)==0) + drive1= xorriso->indev; + else if(strncmp(which,"out",3)==0) + drive1= xorriso->outdev; + else { + drive1= xorriso->indev; + drive2= xorriso->outdev; + } + fprintf(stderr, ">>> LIBBURN : eject media in drive%s %s %s\n", + (drive2[0]!=0 ? "s" : ""), drive1, drive2); + return(1); +} + + +/* Option -end */ +int Xorriso_option_end(struct XorrisO *xorriso, int flag) +{ + + fprintf(stderr, ">>> XORRISO : -end\n"); + + return(1); +} + + +/* Option -f */ +int Xorriso_option_f(struct XorrisO *xorriso, int flag) +{ + xorriso->do_follow_links= 1; + return(1); +} + + +/* Option -find alias -findi */ +int Xorriso_option_findi(struct XorrisO *xorriso, char *pattern, int flag) +{ + char sfe[4*SfileadrL]; + + fprintf(stderr, ">>> XORRISO : filter by pattern %s\n", pattern); + /* >>> prepare regex */ + + fprintf(stderr, ">>> LIBISOFS : traverse ISO tree beginning at %s\n", + Text_shellsafe(xorriso->wdi, sfe, 0)); + + return(1); +} + + +/* Option -findx */ +int Xorriso_option_findx(struct XorrisO *xorriso, char *pattern, int flag) +{ + char sfe[4*SfileadrL]; + + fprintf(stderr, ">>> XORRISO : filter by pattern %s\n", pattern); + /* >>> prepare regex */ + + fprintf(stderr, ">>> XORRISO : traverse disk tree beginning at %s\n", + Text_shellsafe(xorriso->wdx, sfe, 0)); + + return(1); +} + + +/* Option -fs */ +int Xorriso_option_fs(struct XorrisO *xorriso, char *size, int flag) +{ + fprintf(stderr, ">>> LIBISOBURN: -fs %s\n", size); + return(1); +} + + +/* Option -gid */ +int Xorriso_option_gid(struct XorrisO *xorriso, char *gid, int flag) +{ + fprintf(stderr, ">>> LIBISOFS : -gid %s\n", gid); + return(1); +} + + +/* Option -graft-points */ +int Xorriso_option_graft_points(struct XorrisO *xorriso, int flag) +{ + xorriso->allow_graft_points= 1; + return(1); +} + + +/* Option -help and part of -prog_help */ +int Xorriso_option_help(struct XorrisO *xorriso, int flag) +{ + static char text[][80]={ + +#ifdef Xorriso_no_helP + +"This binary program does not contain a help text.", +"If available, read: man 1 xorriso", + +#else + +"This program creates, loads, manipulates and writes ISO 9660 filesystem", +"images with Rock Ridge extensions. Write targets can be drives with optical", +"media or local filesystem objects.", +"", +"Preparation options:", +"Drive addresses are either /dev/... as listed with option -devices or", +"disk files with prefix \"stdio:\", e.g. stdio:/tmp/pseudo_drive .", +" -dev address Set input and output drive and load eventual ISO image.", +" Set the image expansion method to growing.", +" -indev address Set input drive and load eventual ISO image. Switch from", +" growing to modifying.", +" -outdev address", +" Set output drive and switch from growing to modifying.", +" -ban_stdio_write", +" Allow for writing only the usage of optical drives.", +" -blank \"fast\"|\"all\"|\"format\"", +" Blank media resp. invalidate ISO image on media.", +" -V volume_id Specifies the volume ID text.", +"", +" -J Generate Joliet info additional to Rock Ridge info.", +"", +" -uid uid User id to be used for all iso_rr_paths.", +" -gid gid Group id for the same purpose.", +"", +" -devices Show list of available optical drives and their addresses.", +"", +" -toc Show media specific table of content. (MMC, not ISO 9660)", +"", +" -print-size Print the foreseeable consumption by next -commit.", +"", +" -tell_media_space", +" Print foreseeable available space on output media", +"", +"Manipulation options:", +"disk_path is a path to an object in the local filesystem tree.", +"iso_rr_path is the Rock Ridge name of a file object in the ISO image.", +"pathspec is either a disk_path or (if allowed) a pair: iso_rr_path=disk_path", +"Options with variable length path list [...] need \"--\" as end mark", +"if they are followed by another option. In dialog and with options read from", +"files, the line end serves as such a mark. With program arguments this mark", +"can be omitted only with the last option in the list of arguments.", +"", +" -add pathspec [...] Insert the given files or directory trees from", +" filesystem into the ISO image. Much like mkisofs.", +" -path-list disk_path", +" Like -add but read the pathspecs from file disk_path.", +" -graft-points Allow pathspecs of form iso_rr_path=disk_path", +"", +" -cp_r disk_path [...] iso_rr_path", +" Insert the given files or directory trees from filesystem", +" into the ISO image.", +" -rm iso_rr_path [...]", +" Delete the given files from the ISO image.", +" -rm_r iso_rr_path [...]", +" Delete the given directory trees from ISO image.", +" -mv iso_rr_path [...] iso_rr_path", +" Rename the given file objects in the ISO tree to the last", +" argument in the list.", +" -chown uid iso_rr_path [...]", +" Equivalent to chown in the ISO image.", +" -chgrp gid iso_rr_path [...]", +" Equivalent to chgrp in the ISO image.", +" -chmod mode iso_rr_path [...]", +" Equivalent to chmod in the ISO image.", +" -alter_date type timestring iso_rr_path [...]", +" Alter the date entries of a file in the ISO image. type is", +" one of \"a\", \"m\", \"b\" for:", +" access time, modification time, both times.", +" -mkdir iso_rr_path [...]", +" Create empty directories if they do not exist yet", +" -rmdir iso_rr_path [...]", +" Delete empty directories.", +" -- Mark end of particular action argument list.", +"", +" -f Follow symbolic links within disk_path.", +"", +" -overwrite \"on\"|\"off\"", +" Allow or disallow to overwrite existing files in ISO image.", +" -reassure \"on\"|\"off\"", +" If \"on\" then ask the user for \"y\" or \"n\" with any", +" file before deleting or overwriting it in the ISO image.", +"", +"Write-to-media options:", +"", +" -rollback Discard the manipulated ISO image and reload it.", +"", +" -commit Perform the write operation and then perform -dev outdrive.", +" Hint: To perform a final write operation with no new -dev", +" and no new loading of image, execute option -end.", +" -close \"on\"|\"off\"", +" If \"on\" then mark the written media as not appendable.", +" -dummy \"on\"|\"off\"", +" If \"on\" simulate burning. Refuse if media cannot simulate.", +" -speed number[\"k\"|\"m\"]", +" Set the burn speed. Default is maximum speed.", +" -fs number[\"k\"|\"m\"]", +" Set the size of the fifo buffer. (Default is 4m)", +" -eject \"in\"|\"out\"|\"all\"", +" Immediately eject the media in -indev, resp. -outdev,", +" resp. both.", +"", +"Navigation options:", +"", +" -cd iso_rr_path Change working directory in the ISO image. iso_rr_paths", +" which do not begin with '/' will be inserted beginning at", +" the path given with -cd. -ls patterns will eventually", +" looked up at this path.", +" -cdi disk_path Same as -cd disk_path", +" -cdx disk_path Change the current working directory in the local", +" filesystem. disk_paths which do not begin with '/'", +" will be looked up beginning at the path given with -cdx.", +" -lsx patterns will eventually be looked up at this path.", +" -pwd tells the current working directory in the ISO image.", +" -pwdi same as -pwd.", +" -pwdx tells the current working directory in the local filesystem.", +"", +" -ls pattern lists files of the ISO image which match the given", +" shell parser pattern. (I.e. wildcards '*' '?')", +" -lsi pattern same as -ls.", +" -lsx pattern lists files of the local filesystem which match the given", +" shell parser pattern. (I.e. wildcards '*' '?')", +"", +" -ls_l pattern like -ls but also telling some file attributes.", +" -ls_li pattern same as -ls_l.", +" -ls_lx pattern like -lsx but also telling some file attributes.", +"", +" -find pattern lists matching files below current working directory in", +" the ISO image.", +" -findi pattern same as -find.", +" -findx pattern lists matching files below current working directory in", +" the local filesystem.", +"", +"General options:", +" -help Print this text", +" -abort_on severity Set the threshhold for events to abort the program.", +" -dialog after all arguments are processed, enter dialog mode.", +" In this mode you may enter searchtexts or any of the options", +" described here. One per line.", +" -dialog_reset Revoke -dialog (works only if given as argument)", +" -page len width Prompt user after len output lines (0=no prompt).", +" width (default 80) can adjust line number computation", +" to the output terminal's line width.", +#ifdef Xorriso_with_readlinE +" -use_stdin Use raw standard input even if libreadline is available", +" -use_readline Use libreadline for dialog if available", +" -history text Copy text into libreadline history. This command", +" itself is not copied to the history list.", +#endif /* Xorriso_with_readlinE */ +" -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.", +" Channel ids are 'R:' for result lines, 'I:' for notes", +" and error messages, 'M:' for -mark texts. Bit 0 of the", +" mode number tells whether the newline is also part of the", +" packet payload. Example of a info message with newline:", +" I:1: enter option text :", +" -pkt_output:on is intended for use by frontend programs.", +" -logfile channel fileaddress Copy output of a channel to the given file.", +" channel may be 'R','I','M' as with -pkt_output or '.'", +" for the consolidated -pkt_output stream.", +" -mark text If text is not empty it will get put out each time an", +" option is completed.", +" -prog text Use text as this program's name in subsequent messages", +" -prog_help text Use text as this program's name and perform -help", +" -status mode|filter Report the current settings of persistent options.", +" Modes:", +" short... print only important or altered options", +" long ... print options even if they have default settings", +" long_history like long plus -history: lines", +" Filters begin with '-' and are compared literally against the", +" output lines of -status long_history. A line is put out only", +" if its start matches the filter.", +" -status_history_max number Maximum number of history lines to be reported", +" with -status:long_history", +" -options_from_file fileaddress", +" Reads lines from the given file and executes them as program", +" options.", +" -no_rc Only if used as first command line argument this option", +" prevents reading and interpretation of startup files.", +" -print text", +" Print a text to result channel.", +" -prompt text", +" Wait for Enter key resp. for a line of input at stdin.", +" # any text Is ignored. In dialog mode the input line will be stored in", +" the eventual readline history, nevertheless.", +" -version Tell program and version number", +" -end End program immediately", +"", +"", +"Option -page causes a user prompt after the given number of result lines.", +"Empty input resumes output until the next prompt. Other input may be:", +" @ suppresses paging until the current action is done", +" @@ suppresses further result output but continues the action", +" @@@ aborts the current action", +" other aborts the current action and executes input as new", +" option", +"", + +#endif /* ! Xorriso_no_helP */ + +"@ENDE_OF_HELPTEXT_(HOPEFULLY_UNIQUELY_SILLY_TEXT)@" + }; + + char *tpt= NULL; + int i,pass; + + Xorriso_restxt(xorriso,"\n"); + sprintf(xorriso->result_line,"usage: %s [settings|actions]\n", + xorriso->progname); + Xorriso_result(xorriso,0); + Xorriso_restxt(xorriso,"\n"); + for(pass=0;pass<1;pass++) { + for(i=0;1;i++) { + if(pass==0) + tpt= text[i]; + + if(strcmp(tpt,"@ENDE_OF_HELPTEXT_(HOPEFULLY_UNIQUELY_SILLY_TEXT)@")==0) + break; + sprintf(xorriso->result_line,"%s\n",tpt); + Xorriso_result(xorriso,0); + if(xorriso->request_to_abort) + return(1); + } + } + Xorriso_restxt(xorriso,"\n"); + return(1); +} + + +/* Option -history */ +int Xorriso_option_history(struct XorrisO *xorriso, char *line, int flag) +{ + Xorriso_dialog_input(xorriso,line,strlen(line)+1,2); + return(1); +} + + +/* Option -J */ +int Xorriso_option_j_capital(struct XorrisO *xorriso, int flag) +{ + xorriso->do_joliet= 1; + return(1); +} + + +/* Options -ls alias -lsi and ls_l alias ls_li */ +/* @param flag bit0= long format (-ls_l) */ +int Xorriso_option_lsi(struct XorrisO *xorriso, char *pattern, int flag) +{ + char sfe[4*SfileadrL]; + + fprintf(stderr, ">>> XORRISO : filter by pattern %s\n", pattern); + /* >>> prepare regex */ + + fprintf(stderr, ">>> LIBISOFS : -ls of ISO directory %s\n", + Text_shellsafe(xorriso->wdi, sfe, 0)); + + return(1); +} + + +/* Options -lsx and -ls_lx */ +/* @param flag bit0= long format (-ls_l) */ +int Xorriso_option_lsx(struct XorrisO *xorriso, char *pattern, int flag) +{ + char sfe[4*SfileadrL]; + + fprintf(stderr, ">>> XORRISO : filter by pattern %s\n", pattern); + /* >>> prepare regex */ + + fprintf(stderr, ">>> XORRISO : -ls of disk directory %s\n", + Text_shellsafe(xorriso->wdx, sfe, 0)); + + return(1); +} + + +/* Option -logfile */ +int Xorriso_option_logfile(struct XorrisO *xorriso, char *channel, + char *fileadr, int flag) +{ + int hflag,channel_no= 0, ret; + + if(channel[0]==0) { +logfile_wrong_form:; + sprintf(xorriso->info_text,"--- Wrong form. Correct would be: -logfile \".\"|\"R\"|\"I\"|\"M\" file_address\n"); + Xorriso_info(xorriso,0); + return(0); + } + hflag= 2; + if(channel[0]=='R') + channel_no= 1; + else if(channel[0]=='I') + channel_no= 2; + else if(channel[0]=='M') + channel_no= 3; + else if(channel[0]=='.') + hflag= 4; + else + goto logfile_wrong_form; + if(strcmp(fileadr,"-")==0) + hflag|= (1<<15); + ret= Write_to_channel(fileadr,channel_no,hflag); + if(ret<=0) { + sprintf(xorriso->info_text, + "--- Cannot open logfile: %s\n %s\n", + fileadr,(errno>0?strerror(errno):"-unknown error-")); + Xorriso_info(xorriso,0); + } + return(ret>0); +} + + +/* Option -mark */ +int Xorriso_option_mark(struct XorrisO *xorriso, char *mark, int flag) +{ + if(mark[0]==0) + xorriso->mark_text[0]= 0; + else + strncpy(xorriso->mark_text,mark,sizeof(xorriso->mark_text)-1); + xorriso->mark_text[sizeof(xorriso->mark_text)-1]= 0; + return(1); +} + + +/* Option -mkdir alias -mkdiri */ +int Xorriso_option_mkdiri(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int i, end_idx; + + end_idx= Xorriso__end_idx(argc, argv, *idx, 0); + + fprintf(stderr, ">>> LIBISOFS : -mkdiri "); + for(i= *idx; i>> LIBISOFS : -mvi I: "); + for(i= *idx; i I: %s", argv[end_idx-1]); + fprintf(stderr, "\n"); + + (*idx)= end_idx; + return(1); +} + + +/* Option -no_rc */ +int Xorriso_option_no_rc(struct XorrisO *xorriso, int flag) +{ + xorriso->prescan_state->no_rc= 1; + return(1); +} + + +/* Option -options_from_file*/ +int Xorriso_option_options_from_file(struct XorrisO *xorriso, char *adr, + int flag) +/* + bit0= called from Xorriso_prescan_args, + therefore execute via that same function +*/ +/* +return: + <=0 error , 1 = success , 3 = end program run +*/ +{ + int ret,linecount= 0; + FILE *fp= NULL; + char line[4*SfileadrL], shellsafe[5*SfileadrL]; + + char *argv[3]; /* <<< must become dynamic */ + + if(adr[0]==0) { + sprintf(xorriso->info_text,"--- Empty file name with -options_from_file\n"); + Xorriso_info(xorriso,0); + return(0); + } + Text_shellsafe(adr,shellsafe,0); + argv[0]= xorriso->progname; + fp= Afile_fopen(adr,"rb",((!!xorriso->packet_output)<<6)); + if(fp==NULL) + return(0); + while(1) { + if(Sfile_fgets(line,sizeof(line),fp)==NULL) { + ret= 1; + if(ferror(fp)) + ret= 0; + break; + } + linecount++; + if(line[0]==0 || line[0]=='#') + continue; + + /* >>> parse line into args */ + fprintf(stderr, "XORRISO: parse line into args:\n%s\n", line); + continue; + + if(flag&1) { + ret= Xorriso_prescan_args(xorriso,3,argv,1); + if(ret==0) + {ret= 3; goto ex;} + if(ret<0) + goto ex; + } else { + if(xorriso->is_dialog) { + sprintf(xorriso->info_text,"+ line %d of file %s :\n+ %s\n", + linecount,shellsafe,line); + Xorriso_info(xorriso,1); + } + ret= Xorriso_execute_option(xorriso,line,1|(1<<16)); + if(ret<=0 || ret==3) + goto ex; + } + } +ex:; + Xorriso_reset_counters(xorriso,1); + if(fp!=NULL) + fclose(fp); + if(ret<=0) { + sprintf(xorriso->info_text, + "--- error triggered by line %d of file:\n %s\n", + linecount,shellsafe); + Xorriso_info(xorriso,1); + } + return(ret); +} + + +/* Option -overwrite "on"|"off" */ +int Xorriso_option_overwrite(struct XorrisO *xorriso, char *mode, int flag) +{ + xorriso->do_overwrite= !!strcmp(mode, "off"); + return(1); +} + + +/* Option -page */ +int Xorriso_option_page(struct XorrisO *xorriso, int len, int width, int flag) +{ + if(len<=0 || width<=0) { + sprintf(xorriso->info_text, + "--- Improper numeric value of arguments of -page: %d %d\n", + len, width); + Xorriso_info(xorriso,1); + return(0); + } + xorriso->result_page_length= len; + xorriso->result_page_width= width; + return(1); +} + + +/* Option -path-list */ +int Xorriso_option_path_list(struct XorrisO *xorriso, char *adr, int flag) +{ + + fprintf(stderr, ">>> XORRISO : read pathspecs from %s\n", adr); + fprintf(stderr, ">>> LIBISOFS : insert pathspecs into ISO tree\n"); + + return(1); +} + + +/* Option -pkt_output */ +int Xorriso_option_pkt_output(struct XorrisO *xorriso, char *mode, int flag) +{ + if(strcmp(mode,"off")==0) + xorriso->packet_output= 0; + else + xorriso->packet_output= 1; + return(1); +} + + +/* Option -print */ +int Xorriso_option_print(struct XorrisO *xorriso, char *text, int flag) +{ + sprintf(xorriso->result_line,"%s\n",text); + Xorriso_result(xorriso,1); + return(1); +} + + +/* Option -print-size */ +int Xorriso_option_print_size(struct XorrisO *xorriso, int flag) +{ + fprintf(stderr, ">>> LIBISOFS : -print-size\n"); + return(1); +} + + +/* Option -prog */ +int Xorriso_option_prog(struct XorrisO *xorriso, char *name, int flag) +{ + if(strlen(name)>=sizeof(xorriso->progname)) { + sprintf(xorriso->info_text, + "--- Name too long with option -prog (%d > %d)\n", + strlen(name), sizeof(xorriso->progname)-1); + Xorriso_info(xorriso,1); + return(0); + } + strcpy(xorriso->progname,name); + return(1); +} + + +/* Option -prog_help */ +int Xorriso_option_prog_help(struct XorrisO *xorriso, char *name, int flag) +{ + int ret; + + ret= Xorriso_option_prog(xorriso, name, 0); + if(ret<=0) + return(ret); + ret= Xorriso_option_help(xorriso, 0); + return(ret); +} + + +/* Option -prompt */ +int Xorriso_option_prompt(struct XorrisO *xorriso, char *text, int flag) +{ + int ret; + char line[80]; + + strcpy(xorriso->result_line,text); + Xorriso_result(xorriso,0); + ret= Xorriso_dialog_input(xorriso, line, sizeof(line),1); + return(ret); +} + + +/* Option -pwd alias -pwdi */ +int Xorriso_option_pwdi(struct XorrisO *xorriso, int flag) +{ + sprintf(xorriso->info_text,"current working directory:\n"); + Xorriso_info(xorriso,0); + sprintf(xorriso->result_line,"%s/\n",xorriso->wdi); + Xorriso_result(xorriso,0); + return(1); +} + + +/* Option -pwdx */ +int Xorriso_option_pwdx(struct XorrisO *xorriso, int flag) +{ + sprintf(xorriso->info_text,"current working directory on hard disk:\n"); + Xorriso_info(xorriso,0); + sprintf(xorriso->result_line,"%s/\n",xorriso->wdx); + Xorriso_result(xorriso,0); + return(1); +} + + +/* Options -rm alias -rmi , and -rm_r aias -rm_ri */ +/* @param flag bit0=recursive */ +int Xorriso_option_rmi(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int i, end_idx; + + end_idx= Xorriso__end_idx(argc, argv, *idx, 0); + + fprintf(stderr, ">>> LIBISOFS : -rm%si ", ((flag&1) ? "_r" : "")); + for(i= *idx; i>> LIBISOFS : -rmdiri "); + for(i= *idx; ido_reassure= !!strcmp(mode, "off"); + return(1); +} + + +/* Option -rollback */ +int Xorriso_option_rollback(struct XorrisO *xorriso, int flag) +{ + + fprintf(stderr, ">>> LIBISOBURN : -rollback\n"); + + return(1); +} + + +/* Option -speed */ +int Xorriso_option_speed(struct XorrisO *xorriso, char *speed, int flag) +{ + fprintf(stderr, ">>> LIBISOFS : -speed %s\n", speed); + return(1); +} + + +/* Option -status */ +int Xorriso_option_status(struct XorrisO *xorriso, char *mode, int flag) +{ + if(strcmp(mode,"short")==0) + Xorriso_status(xorriso,NULL,NULL,1); + else if(strcmp(mode,"long")==0) + Xorriso_status(xorriso,NULL,NULL,0); + else if(strcmp(mode,"long_history")==0) + Xorriso_status(xorriso,NULL,NULL,8); + else if(mode[0]=='-') + Xorriso_status(xorriso,mode,NULL,8); + else + Xorriso_status(xorriso,NULL,NULL,1); + return(1); +} + + +/* Option -status_history_max */ +int Xorriso_option_status_history_max(struct XorrisO *xorriso, int num, + int flag) +{ + if(num>=0 && num<1000000) + xorriso->status_history_max= num; + return(1); +} + + +/* Option -tell_media_space */ +int Xorriso_option_tell_media_space(struct XorrisO *xorriso, int flag) +{ + fprintf(stderr, ">>> LIBISOBURN : -tell_media_space\n"); + return(1); +} + + +/* Option -toc */ +int Xorriso_option_toc(struct XorrisO *xorriso, int flag) +{ + fprintf(stderr, ">>> LIBISOBURN : -toc\n"); + return(1); +} + + +/* Option -uid */ +int Xorriso_option_uid(struct XorrisO *xorriso, char *uid, int flag) +{ + fprintf(stderr, ">>> LIBISOFS : -uid %s\n", uid); + return(1); +} + + +/* Option -use_readline */ +int Xorriso_option_use_readline(struct XorrisO *xorriso, char *mode, int flag) +{ + if(strcmp(mode,"off")==0) + xorriso->use_stdin= 1; + else + xorriso->use_stdin= 0; + return(1); +} + + +/* Option -uid */ +int Xorriso_option_v_capital(struct XorrisO *xorriso, char *volid, int flag) +{ + fprintf(stderr, ">>> LIBISOFS : -V %s\n", volid); + return(1); +} + + +/* Option -version */ +int Xorriso_option_version(struct XorrisO *xorriso, int flag) +{ + printf("xorriso %s : RockRidge filesystem manipulator\n", PROG_VERSION); + printf("Copyright (C) 2007, Thomas Schmitt , libburnia project\n"); + return(1); +} + +/* ---------------------------- End Options API ------------------------ */ + + +int Xorriso_interpreter(struct XorrisO *xorriso, + int argc, char **argv, int *idx, int flag) +/* +return: + <=0 error , 1 = success , ( 2 = nothing found ) , 3 = end program run +*/ +/* + bit0= recursion +*/ +{ + int ret; + int num1, num2; + double d1, d2; + char *cmd, *arg1, *arg2, *arg4; + + if(xorriso==NULL) + return(0); + if(xorriso->is_dialog) { + xorriso->result_line_counter= xorriso->result_page_counter= 0; + if(xorriso->result_page_length<0) + xorriso->result_page_length= -xorriso->result_page_length; + } + xorriso->request_to_abort= 0; + xorriso->prepended_wd= 0; + +next_command:; + cmd= argv[*idx]; + (*idx)++; + + if((*idx)info_text, + "=== Input line beginning with '-' is not a known option\n"); + sprintf(xorriso->info_text+strlen(xorriso->info_text), + "=== '%s'\n",cmd); + Xorriso_info(xorriso,0); + {ret= 0; goto ex;} + + } else { + + /* >>> ??? pathspecs for option -add */; + + fprintf(stderr, "--- Ignored : %s\n", cmd); + + } + if(ret<=0) + goto ex; + if(*idxis_dialog) && !(flag&1)) + Xorriso_mark(xorriso,0); + fflush(stdout); + return(ret); +} + + +int Xorriso_execute_option(struct XorrisO *xorriso, char *line, int flag) +/* + bit0-bit15 are forwarded to Xorriso_interpreter + + bit16= no pageing of info lines + bit17= print === bar even if xorriso->found<0 +*/ +{ + int ret,argc= 0, idx= 1; + char **argv= NULL; + double tdiff; + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv,&tz); + Xorriso_reset_counters(xorriso,1); + xorriso->idle_time= 0.0; + tdiff= tv.tv_sec+(1.e-6*(double) tv.tv_usec); + + /* >>> parse line into args */ + fprintf(stderr, "XORRISO: parse line into args:\n%s\n", line); + return(1); + + ret= Xorriso_interpreter(xorriso, argc, argv, &idx, flag&0xffff); + if(ret<0) + return(ret); + gettimeofday(&tv,&tz); + tdiff= tv.tv_sec+(1.e-6*(double) tv.tv_usec)-tdiff-xorriso->idle_time; + if(tdiff<0.001) + tdiff= 0.001; + if(xorriso->error_count>0) { + sprintf(xorriso->info_text, + "----------------------------- %7.lf errors encountered\n", + xorriso->error_count); + Xorriso_info(xorriso,!(flag&(1<<16))); + } + if((flag&(1<<17)) && !xorriso->bar_is_fresh) { + sprintf(xorriso->info_text,"===========================\n"); + Xorriso_info(xorriso,0); + xorriso->bar_is_fresh= 1; + } + Xorriso_reset_counters(xorriso,1); + return(ret); +} + + +int Xorriso_dialog(struct XorrisO *xorriso, int flag) +{ + int ret,first_round; + char line[2*SfileadrL]; + + xorriso->is_dialog= 1; + for(first_round= 1;1;first_round= 0) { + if(xorriso->pending_option[0]!=0) { + Xorriso_mark(xorriso,0); + strcpy(line,xorriso->pending_option); + xorriso->pending_option[0]= 0; + } else { + if(!xorriso->bar_is_fresh) { + sprintf(xorriso->info_text,"===========================\n"); + Xorriso_info(xorriso,0); + xorriso->bar_is_fresh= 1; + } + sprintf(xorriso->info_text,"enter option and arguments :\n"); + Xorriso_info(xorriso,0); + Xorriso_mark(xorriso,0); + ret= Xorriso_dialog_input(xorriso,line,sizeof(line),4); + if(ret<=0) + break; + } + sprintf(xorriso->info_text, + "==============================================================\n"); + Xorriso_info(xorriso,0); + + ret= Xorriso_execute_option(xorriso,line,1<<17); + if(ret<0) + goto ex; + if(ret==3) + break; + xorriso->did_something_useful= 1; + } + ret= 1; +ex:; + xorriso->is_dialog= 0; + return(ret); +} + + +int Xorriso_prescan_args(struct XorrisO *xorriso, int argc, char **argv, + int flag) +/* + bit0= do not interpret argv[1] +*/ +/* + return: + <0 error + 0 end program + 1 ok, go on +*/ +{ + int i,ret; + char *cmd, *arg1; + + for(i=1+(flag&1);i1) + xorriso->did_something_useful= 1; + if(i==1 && argc==2) { + if(strcmp(cmd,"-prog_help")==0) { + i++; + Xorriso_option_prog_help(xorriso,arg1,0); + xorriso->did_something_useful= 1; + return(0); + } else if(strcmp(cmd,"-help")==0) { + Xorriso_option_help(xorriso,0); + xorriso->did_something_useful= 1; + return(0); + } else if(strcmp(cmd,"-version")==0) { + Xorriso_option_version(xorriso, 0); + xorriso->did_something_useful= 1; + return(0); + } + } else if(strcmp(cmd,"-no_rc")==0) { + ret= Xorriso_option_no_rc(xorriso, 0); + if(ret<=0) + return(ret); + } + } + return(1); +} + + +/* >>>>> BAUSTELLE */ + + +#ifdef Xorriso_with_maiN + +int main(int argc, char **argv) +{ + int ret,i; + struct XorrisO *xorriso= NULL; + + if(argc<2) { + fprintf(stderr,"usage : %s [options]\n", + argv[0]); + exit(2); + } + ret= Xorriso_new(&xorriso,argv[0],0); + if(ret<=0) { + fprintf(stderr,"Creation of XorrisO object failed. (not enough memory ?)\n"); + exit(3); + } + + /* >>> Is a prescan needed at all ? + There is no fixed meaning of the first argument */ + ret= Xorriso_prescan_args(xorriso,argc,argv,0); + if(ret==0) + goto end_sucessfully; + if(ret<0) + exit(5); + + i= 1; + ret= Xorriso_interpreter(xorriso,argc,argv,&i,0); + + if(xorriso->dialog) { + ret= Xorriso_dialog(xorriso,0); + if(ret<=0) + exit(6); + } +end_sucessfully:; + Xorriso_destroy(&xorriso,0); + exit(0); +} + +#endif /* Xorriso_with_maiN */ + diff --git a/test/xorriso.h b/test/xorriso.h new file mode 100644 index 00000000..cbe2409d --- /dev/null +++ b/test/xorriso.h @@ -0,0 +1,222 @@ + +/* Command line oriented batch and dialog tool which creates, loads, + manipulates and burns ISO 9660 filesystem images. + + Copyright 2007 Thomas Schmitt, + + Provided under GPL version 2. + + This file contains the public option interface of xorriso. +*/ + +#ifndef Xorriso_includeD +#define Xorriso_includeD yes + +/** Opaque handle of the xorriso runtime context */ +struct XorrisO; + + +/* ---------------------------- Options API ------------------------ */ +/* See man 1 xorriso for explanation of the particular options */ + +/* Option -abort_on */ +int Xorriso_option_abort_on(struct XorrisO *xorriso, char *severity, int flag); + +/* Option -add */ +int Xorriso_option_add(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag); + +/* Option -alter_date */ +int Xorriso_option_slater_date(struct XorrisO *xorriso, + char *time_type, char *timestring, + int argc, char **argv, int *idx, int flag); + +/* Option -ban_stdio_write */ +int Xorriso_option_ban_stdio_write(struct XorrisO *xorriso, int flag); + +/* Option -blank */ +int Xorriso_option_blank(struct XorrisO *xorriso, char *mode, int flag); + +/* Option -cd alias -cdi */ +int Xorriso_option_cdi(struct XorrisO *xorriso, char *iso_rr_path, int flag); + +/* Option -cdx */ +int Xorriso_option_cdx(struct XorrisO *xorriso, char *disk_path, int flag); + +/* Option -chgrp alias -chgrpi */ +int Xorriso_option_chgrpi(struct XorrisO *xorriso, char *gid, char *path, + int argc, char **argv, int *idx, int flag); + +/* Option -chmod alias -chmodi */ +int Xorriso_option_chmodi(struct XorrisO *xorriso, char *mode, char *path, + int argc, char **argv, int *idx, int flag); + +/* Option -chown alias -chowni */ +int Xorriso_option_chowni(struct XorrisO *xorriso, char *uid, char *path, + int argc, char **argv, int *idx, int flag); + +/* Option -close "on"|"off" */ +int Xorriso_option_close(struct XorrisO *xorriso, char *mode, int flag); + +/* Option -commit */ +int Xorriso_option_commit(struct XorrisO *xorriso, int flag); + +/* Option -cp_r alias -cp_ri */ +int Xorriso_option_cp_ri( struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag); + +/* Option -cut_out */ +int Xorriso_option_cut_out(struct XorrisO *xorriso, char *disk_path, + off_t startbyte, off_t bytecount, char *iso_rr_path, int flag); + +/* Options -dev , -indev, -outdev */ +/** @param flag bit0=use as indev , bit1= use as outdev */ +int Xorriso_option_dev(struct XorrisO *xorriso, char *adr, int flag); + +/* Option -devices */ +int Xorriso_option_devices(struct XorrisO *xorriso, int flag); + +/* Option -dialog "on"|"off" */ +int Xorriso_option_dialog(struct XorrisO *xorriso, char *mode, int flag); + +/* Option -dummy "on"|"off" */ +int Xorriso_option_dummy(struct XorrisO *xorriso, char *mode, int flag); + +/* Option -eject */ +int Xorriso_option_eject(struct XorrisO *xorriso, char *which, int flag); + +/* Option -end */ +int Xorriso_option_end(struct XorrisO *xorriso, int flag); + +/* Option -f */ +int Xorriso_option_f(struct XorrisO *xorriso, int flag); + +/* Option -fs */ +int Xorriso_option_fs(struct XorrisO *xorriso, char *size, int flag); + +/* Option -find alias -findi */ +int Xorriso_option_findi(struct XorrisO *xorriso, char *pattern, int flag); + +/* Option -findx */ +int Xorriso_option_findx(struct XorrisO *xorriso, char *pattern, int flag); + +/* Option -gid */ +int Xorriso_option_gid(struct XorrisO *xorriso, char *gid, int flag); + +/* Option -graft-points */ +int Xorriso_option_graft_points(struct XorrisO *xorriso, int flag); + +/* Option -help and part of -prog_help */ +int Xorriso_option_help(struct XorrisO *xorriso, int flag); + +/* Option -history */ +int Xorriso_option_history(struct XorrisO *xorriso, char *line, int flag); + +/* Option -J */ +int Xorriso_option_j_capital(struct XorrisO *xorriso, int flag); + +/* Options -ls alias -lsi and ls_l alias ls_li */ +/* @param flag bit0= long format (-ls_l) */ +int Xorriso_option_lsi(struct XorrisO *xorriso, char *pattern, int flag); + +/* Options -lsx and -ls_lx */ +/* @param flag bit0= long format (-ls_l) */ +int Xorriso_option_lsi(struct XorrisO *xorriso, char *pattern, int flag); + +/* Option -logfile */ +int Xorriso_option_logfile(struct XorrisO *xorriso, char *channel, + char *fileadr, int flag); + +/* Option -mark */ +int Xorriso_option_mark(struct XorrisO *xorriso, char *mark, int flag); + +/* Option -mkdir alias -mkdiri */ +int Xorriso_option_mkdiri(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag); + +/* Option -mv alias -mvi */ +int Xorriso_option_mvi(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag); + +/* Option -no_rc */ +int Xorriso_option_no_rc(struct XorrisO *xorriso, int flag); + +/* Option -options_from_file*/ +/* @return <=0 error , 1 = success , 3 = request to end program run */ +int Xorriso_option_options_from_file(struct XorrisO *xorriso, char *adr, + int flag); + +/* Option -overwrite "on"|"off" */ +int Xorriso_option_overwrite(struct XorrisO *xorriso, char *mode, int flag); + +/* Option -page */ +int Xorriso_option_page(struct XorrisO *xorriso, int len, int width, int flag); + +/* Option -path-list */ +int Xorriso_option_path_list(struct XorrisO *xorriso, char *adr, int flag); + +/* Option -pkt_output */ +int Xorriso_option_pkt_output(struct XorrisO *xorriso, char *mode, int flag); + +/* Option -print */ +int Xorriso_option_print(struct XorrisO *xorriso, char *text, int flag); + +/* Option -print-size */ +int Xorriso_option_print_size(struct XorrisO *xorriso, int flag); + +/* Option -prog */ +int Xorriso_option_prog(struct XorrisO *xorriso, char *name, int flag); + +/* Option -prog_help */ +int Xorriso_option_prog_help(struct XorrisO *xorriso, char *name, int flag); + +/* Option -pwd alias -pwdi */ +int Xorriso_option_pwdi(struct XorrisO *xorriso, int flag); + +/* Option -pwdx */ +int Xorriso_option_pwdx(struct XorrisO *xorriso, int flag); + +/* Option -reassure "on"|"off" */ +int Xorriso_option_reassure(struct XorrisO *xorriso, char *mode, int flag); + +/* Options -rm alias -rmi , and -rm_r aias -rm_ri */ +/* @param flag bit0=recursive */ +int Xorriso_option_rmi(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag); + +/* Option -rmdir alias -rmdiri */ +int Xorriso_option_rmdiri(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag); + +/* Option -rollback */ +int Xorriso_option_rollback(struct XorrisO *xorriso, int flag); + +/* Option -speed */ +int Xorriso_option_speed(struct XorrisO *xorriso, char *speed, int flag); + +/* Option -status */ +int Xorriso_option_status(struct XorrisO *xorriso, char *mode, int flag); + +/* Option -status_history_max */ +int Xorriso_option_status_history_max(struct XorrisO *xorriso, int num1, + int flag); + +/* Option -tell_media_space */ +int Xorriso_option_tell_media_space(struct XorrisO *xorriso, int flag); + +/* Option -toc */ +int Xorriso_option_toc(struct XorrisO *xorriso, int flag); + +/* Option -uid */ +int Xorriso_option_use_readline(struct XorrisO *xorriso, char *uid, int flag); + +/* Option -use_readline */ +int Xorriso_option_use_readline(struct XorrisO *xorriso, char *mode, int flag); + +/* Option -version */ +int Xorriso_option_version(struct XorrisO *xorriso, int flag); + + +#endif /* Xorriso_includeD */ + + diff --git a/test/xorriso.txt b/test/xorriso.txt new file mode 100644 index 00000000..ede90732 --- /dev/null +++ b/test/xorriso.txt @@ -0,0 +1,531 @@ + +-------------------------------------------------------------------------- +The architecture of the xorriso application is planned as follows: + +The main program module creates a xorriso object, calls startup-file reading, +argument reading, and eventual dialog shell function. + +The xorriso class module implements the xorriso state object and above three +main functions. These functions rely on a common interpreter of a list of +words as described in man xorriso, paragraph "Command processing". +The list may contain more than one command with its parameters. It is intended +to be either the list of program arguments or a list parsed from a single +input line. + +The interpreter converts the words command-wise into suitable parameters +for an actor function which performs the command's action resp. a setter +function which brings the command's setting into effect. The interpreter then +calls this function immediately and synchronously. + +These option functions form a well documented API which may be used by +interpreters of things other than words. E.g. by a GUI module or as libxorriso. + +xorriso will encapsulate libisoburn, libisofs and libburn. Although i know +it is not popular, i propose to link it with the object files of those +libraries and not against external library objects. + +(Did i watch somebody having an allergy against external programs ? +I got an allergy against .so . My immune system mistakes them for .DLL .) + + +>>> currently a stub for xorriso is derived from the source of scdbackup_askme. + +-------------------------------------------------------------------------- +Emerging man page: + +XORRISO(1) XORRISO(1) + + +NAME +xorriso - creates, loads, manipulates and writes ISO 9660 filesystem images +with Rock Ridge extensions. + +SYNOPSIS +xorriso [settings|actions] + +DESCRIPTION +xorriso is a program which maps file objects from POSIX compliant +filesystems into Rock Ridge enhanced ISO 9660 filesystems and allows +session-wise manipulation of such filesystems. It can load the management +information of existing ISO images and it writes the session results to +optical media or to filesystem objects. + +A special property of xorriso is that it needs neither an external ISO 9660 +formatter program nor an external burn program but rather incorporates +the libraries of the libburnia project. + +Overview of features: + +Operates on an existing ISO image or creates a new one. +Copies files from filesystem into the ISO image. +Renames or deletes file objects in the ISO image. +Changes file properties in the ISO image. +Writes result as completely new image to optical media or filesystem objects. +Writes result as add-on session to appendable multi-session media, +to overwriteable media, to regular files, and to block devices. +Scans for optical drives, blanks re-useable optical media. +Reads its instructions from command line arguments, dialog, and batch files. + +General information paragraphs: +Session model +Command processing +Libburn drives +Rock Ridge, POSIX, X/Open + +Session model: + +Unlike other filesystems, ISO 9660 is not intended for read-write operation but +rather for being generated in a single sweep and being written to media as a +.B session . +The data content of a session if called filesystem +.B image . + +The written image in its session can then be mounted by the operating system +for being used read-only. Linux is able to mount ISO images from block devices, +which may represent optical media, other media or via a loop device even +regular disk files. + +This session usage model has been extended on CD media by the concept of +.B multi-session , +which allows to add information to the CD and gives the mount programs +of the operating systems the addresses of the entry points of each +session. The mount programs recognize block devices which represent +CD media and will by default mount the image in the last session. +This session usually contains an updated directory tree for the whole media +which governs the data contents in all recorded sessions. + +The multi-session model of the MMC standard applies to CD-R[W], to DVD-R, to +certain states of DVD-RW, and to DVD+R. But it does not apply to overwriteable +MMC media like DVD-RAM, DVD+RW, formatted DVD-RW, and of course not to disk +files or block devices. +Program growisofs by Andy Polyakov showed how to extend this functionality +to overwriteable media or disk files which carry valid ISO 9660 filesystems. +These two expansion methods are referred as "growing" in this text. + +xorriso provides growing as well as an own method which produces a completely +new ISO image from the old one and the modifications. This unique xorriso +method produces compact filesystem images with no waste by outdated data blocks +and it can write modified images to targets which are completely unsuitable +for multi-session operations. E.g. fast blanked DVD-RW, named pipes, +character devices, sockets. +Therefore this method is called "modifying". Its drawback is that the target +cannot be the same media which holds the unmodified ISO image but that this +media has to be present while the new image gets written to another media. +So typically one needs either two optical drives or has to work with +filesystem objects as source and/or target media. + +xorriso adopts the concept of session by loading an eventual image directory +tree, allowing to manipulate it by several actions, and to write the new +image to the target media. +The first session of a xorriso run begins by the definition of the input +drive with the eventual ISO image and ends by command -commit which triggers +writing. A -commit is done automatically when the program ends regularly. + +After -commit a new session begins. A new input drive can only be chosen +as long as the loaded ISO image was not altered. Alteration can be revoked +by command -rollback. + +Writing a session to the target is supposed to be very expensive in terms of +time and of consumed space on appendable or write-once media. Therefore all +intended manipulations of a particular ISO image should be done in a single +session. +In some special situations (e.g. in a file-to-file situation) it can be +useful to store intermediate states and to continue with image manipulations. + + +Command processing: + +Commands are either actions or settings. They consist of a command word, +followed by zero or more parameter words. If the list of parameter words +is of variable length (indicated by "[...]") then it has to be terminated +by either the word "--" or the end of argument list or an end of an input +line. It is not an error if "--" appears after the parameters of a command +with a fixed list length. + +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. +When the program begins then it first looks for its startup files and +eventually reads their content as command input lines. Then it interprets +the program arguments as commands and parameters and finally it enters +dialog mode if command -dialog was executed up to then. + +The program ends either by command -end or by the end of arguments with +no command -dialog encountered. + +Libburn drives: + +Source of an existing ISO image can be any random access readable libburn +drive: optical media with readable data, regular files, block devices. +RockRidge info must be present in existing ISO images and it will be generated +by the program unconditionally. + +Target for writing can be any libburn drive. +Some drive types do not support the method of growing but only the method +of modifying. + +All drive file objects have to offer rw-permission to the user of xorriso. +Even those which will not be useable for reading an ISO image. + +Optical drives on Linux usually get addressed by the path of their block +device or of their generic character device. E.g. + -dev /dev/sr0 + -dev /dev/hdc + -dev /dev/sg2 +Get a list of accessible drives by command + -devices +It might be necessary to do this as superuser in order to see all drives +and to then allow rw-access for the intended users. + +Filesystem objects of nearly any type can be addressed by prefix "stdio:" and +their path in the filesystem. E.g. + -dev stdio:/tmp/pseudo_drive +If path leads to a regular file or to a block device then the emulated drive +is random access readable and can be used for the method of growing if it +already contains a valid ISO 9660 image. Any other file type is not readable +and can only be used as target for the method of modifying. + +Be aware that especially the superuser can write into any accessible file or +device by using its path with the "stdio:" prefix. Addresses without prefix +"stdio:" will only work if they lead to an optical drive. + + +Rock Ridge, POSIX, X/Open: + +.B Rock Ridge +is the name of a set of additional informations which enhance +an ISO 9660 filesystem so that it can represent a POSIX compliant filesystem +with ownership, access permissions, symbolic links, and other attributes. + +This is what xorriso uses for a decent representation of the disk files +within the ISO image. Rock Ridge information is produced with any xorriso +image and xorriso will load for manipulation only Rock Ridge enhanced images. + +xorriso is not named "porriso" because POSIX only guarantees 14 characters +of filename length. It is the X/Open System Interface standard XSI which +demands a file name length of up to 255 characters and paths of up to 1024 +characters. Rock Ridge fulfills this demand. + + +OPTIONS + +Aquiring source and target drive: + +-dev address Set input and output drive and load eventual ISO image. + Set the image expansion method to growing. + Only allowed as long as no ISO image was loaded and + altered, or after actions -rollback, or -commit. + Violation yields a SORRY event. + +-indev address Set input drive and load eventual ISO image. Switch from + growing to modifying. Same restrictions as with -dev + +-outdev address Set output drive and switch from growing to modifying. +>>> (Do we need the restrictions as with -dev ? +>>> I.e. do we need to know that we are doing modification +>>> before we call isoburn_prepare_*() ? ) + +-ban_stdio_write Allow for writing only the usage of optical drives. Disallow + to write the result into files of nearly arbitrary type. + Once set, this command cannot be revoked. + +Data manipulations: + +The following commands may depend on settings listed further below. +disk_path is a path to an object in the local filesystem tree. +iso_rr_path is the Rock Ridge name of a file object in the ISO image. (Do not +confuse with the lowlevel ISO 9660 names visible if Rock Ridge gets ignored.) + +Note that in the ISO image you are as powerful as the superuser. Access +permissions of the existing files in the image do not apply to your write +operations. They are intended to be in effect with the read-only mounted image. + +If the iso_rr_path of a newly inserted or renamed file leads to an existing +file object in the ISO image, then the following collision handling happens: +If both objects are directories then they get merged by recursively inserting +the subobjects from filesystem into ISO image. If other file types collide then +the setting of command -overwrite decides. Directories may only be deleted by +commands -rmdir or -rm_r. + +The commands in this section alter the ISO image and not the local filesystem. + +-add path [...] Insert the given files or directory trees from filesystem + into the ISO image. + Use the same paths on ISO unless -graft-points is set and + the paths have the form iso_rr_path=disk_path . + +-path-list disk_path Like -add but read the pathspecs from file disk_path. + One pathspec per line. + +-cp_r disk_path [...] iso_rr_path + Insert the given files or directory trees from filesystem + into the ISO image. + Use the same rules for generating the ISO addresses as + would be done with shell command cp -r. + +( Needs enhancement in libisofs: + -cut_out disk_path startbyte bytecount iso_rr_path + Cut out a piece of file disk_path and insert it into the ISO + image under the given iso_rr_path. + This is advised for files > 2 GiB - 2 KiB if you are not + certain that all your systems with ISO filesystem driver can + handle such large files. Depending on the libisofs + implementation, files of larger size may generate SORRY + events if they are processed uncut. + When reading those files pieces from media, you will have to + concatenate them in the correct sequence: + cat /mnt/file_part1 /mnt/file_part2 > $HOME/file +) + +-rm iso_rr_path [...] Delete the given files from the ISO image. + +-rm_r iso_rr_path [...] + Delete the given files or directory trees from the ISO image. + +-mv iso_rr_path [...] iso_rr_path + Rename the given file objects in the ISO tree to the last + argument in the list. Use the same rules as with shell command + mv. + +-chown uid iso_rr_path [...] Equivalent to chown in the ISO image. +-chgrp gid iso_rr_path [...] Equivalent to chgrp in the ISO image. +-chmod mode iso_rr_path [...] Equivalent to chmod in the ISO image. + +-alter_date type timestring iso_rr_path [...] + Alter the date entries of a file in the ISO image. type is + one of "a", "m", "b" for access time, modification time, + both times. +>>> Can we set ctime ? Do we want to set ctime ? + +-mkdir iso_rr_path [...] Create empty directories if they do not exist yet. + Existence as directory generates a WARNING event, existence as + other file is a SORRY. + +-rmdir iso_rr_path [...] Delete empty directories. + +-- Mark end of particular action argument list. + +-rollback Discard the manipulated ISO image and reload it from indrive. + + +Writing the result: + +-commit Perform the write operation. Eventually make the outdrive + the new indrive and load the image from there. Check wether + this is what is expected and eventually warn or abort. + Switch from eventual modifiying mode to growing mode. + (A subsequent -outdev will activate modification mode.) + Commit is performed automatically at end of program if there + are uncommitted manipulations pending. + So to perform a final write operation with no new -dev + and no new loading of image, rather execute option -end. + To suppress a final write, execute -rollback -end. + +-eject "in"|"out"|"all" Eject the media in -indev, resp. -outdev, resp. both + drives. + Note: It is not possible yet to effectively eject disk files. + +-blank mode Blank media resp. invalidate ISO image on media. + This affects only the outdrive not the indrive. + If both drives are the same and if the ISO image was altered + then this command leads to a SORRY event. + Defined modes are: fast, all, format + "fast" and "all" make CD-RW and unformatted DVD-RW re-usable + or de-format overwriteable DVD-RW. + "format" converts unformatted DVD-RW into overwriteable ones. + + +Settings for data insertion: + +RockRidge info will be generated by the program unconditionally. + +-J Generate Joliet info additional to Rock Ridge info. + +-f Follow symbolic links. + +-uid uid User id to be used for all files when inserted into the + new ISO tree. +-gid gid Group id for the same purpose. + +-graft-points For xorriso action -add this enables pathspecs of the form + target=source like with mkisofs. + + +Settings for result writing: + +-V volid Specifies the volume ID. (I assume libisofs can do that) + +-speed number[k|m] Set the burn speed. Default is maximum speed. + Speed can be given in media dependent numbers or as a + desired throughput per second in kiB (= 1024) or MiB + (= 1024 kiB). + +-dummy "on"|"off" If "on" simulate burning or refuse with SORRY event if + no simulation is possible. + +-fs number["k"|"m"] Set the size of the fifo buffer which smoothens the data + stream from ISO image generation to media burning. Default + is 4 MiB. The number may be followed by letter "k" or"m" + which means unit is kiB (= 1024) or MiB (= 1024 kiB). + +-close "on"|"off" If "on" then mark the written media as not appendable + any more (if possible at all with the given type of target + media). + This is the contrary of cdrskin -multi. + + +Exception processing: + +-abort_on severity Set the threshhold for events to abort the program. + Events are classified by severity : + "NEVER", "ABORT", "FATAL", "SORRY", "WARNING", "HINT", + "NOTE", "UPDATE", "DEBUG", "ALL" + Severities "NEVER" and "ALL" do not occur but mark the extreme + ends of this potentially expandable range. + It may become necessary to abort the program anyway, despite + the setting by this option. Expect not many "ABORT" events to + be ignorable. + +-overwrite "on"|"off" Allow or disallow to overwrite existing files in the + ISO image by a file with the same user defined name. This is + the RockRidge name and not the plain ISO name. + With setting "off", RR name collisions cause SORRY-events. + + +Dialog mode control: + +-dialog "on"|"off" Enable or disable to enter dialog mode after all arguments + are processed. In dialog mode input lines get prompted via + readline or from stdin. + +-page len width Describe terminal to the text pager. + +-use_readline "on"|"off" If "on" then use readline for dialog. Esle use + plain stdin. + +-reassure "on"|"off" If "on" then ask the user for "y" or "n" with any file + before deleting or overwriting it in the ISO image. + + +Drive and media related inquiry actions: + +-toc Show media specific table of content. (MMC toc, not ISO.) + +-devices Show list of available MMC drives. + +-print-size Print the foreseeable consumption by next -commit. + +-tell_media_space Print available space on output media (minus already + foreseeable consumption by next -commit.) + + +Navigation in ISO image and disk filesystem: + +-cd iso_rr_path Change the current working directory in the emerging ISO + image as it is at the moment. +-cdx disk_path Change the current working directory on filesystem. + +-pwd Tell the current working directory in the ISO image. +-pwdx ... on local filesystem. + +-ls pattern List files from the current working directory in the ISO + image which match a shell pattern. (I.e. wildcards '*' '?') +-lsx pattern ... on local filesystem. + +-ls_l pattern Equivalent for ls -l. +-ls_lx pattern ... on filesystem. + +-find pattern Equivalent to find . -name pattern in the ISO image. +-findx pattern ... on filesystem. + + +Scripting, dialog and program control features: + +-no_rc Only if used as first command line argument this option + prevents reading and interpretation of eventual startup + files. See section FILES below. + +-help Print helptext. + +-version Print program name and version. + +-history textline Copy textline into libreadline history. + +-status [mode|filter] Print the current settings. + Modes: + short... print only important or altered settings + long ... print settings even if they are default values + long_history like long plus history lines + Filters begin with '-' and are compared literally against the + output lines of -status:long_history. A line is put out only + if its start matches the filter text. No wildcards. + +-status_history_max maximum number of history lines to be reported with + -status "long_history". + +-options_from_file fileaddress + Reads lines from fileaddress and executes them as dialog lines. + +-print text Print a text to result channel. +-prompt text Wait for the user to hit the Enter key resp. to send a line + via stdin. + +-end End program immediately + +# any text In dialog or file execution mode only and only as first + non-whitespace in line: + Do not execute the line but eventually store it in history. + + +Support for frontend programs talking into stdin and listening at stdout: + +-pkt_output "on"|"off" Consolidate text output on stdout and classify each + line by a channel indicator: 'R:' for result lines, + 'I:' for notes and error messages, 'M:' for -mark texts. +-logfile channel fileaddress Copy output of a channel to the given file. + +-mark text If text is not empty it will get put out each time an + action has been completed. + +-prog text Use text as this program's name in subsequent messages + +-prog_help text Use text as this program's name and perform -help. + + +EXAMPLES + +>>> to come + + +FILES + +Startup files: + +If not -no_rc is given as the first argument then xorriso attempts on startup +to read and execute lines from the following files: + /etc/default/xorriso + /etc/opt/xorriso/rc + /etc/xorriso/cdrskin.conf + $HOME/.xorrisorc +The files are read in the sequence given above, but none of them is required +for xorriso to function properly. + + +SEE ALSO + +For mounting xorriso generated ISO images + mount(8) + +Other programs which produce ISO images + mkisofs(8), genisoimage(8) + +Other programs which burn images to optical media + growisofs(1), cdrecord(1), wodim(1), cdrskin(1) + + +AUTHOR + +xorriso is not written at all. +This man page was written by Thomas Schmitt . + +