diff --git a/test/xorriso.1 b/test/xorriso.1 index f38d57ca..99075635 100644 --- a/test/xorriso.1 +++ b/test/xorriso.1 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH XORRISO 1 "November 14, 2007" +.TH XORRISO 1 "December 4, 2007" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -244,9 +244,9 @@ with a fixed list length. .PP .B Pattern expansion is a property of some particular commands and not a general -feature. It gets controlled by command -iso_rr_pattern. Commands which -eventually use pattern expansion all have variable argument lists which -are marked in this man page by "[***]" rather than "[...]". +feature. It gets controlled by commands -iso_rr_pattern and -disk_pattern. +Commands which eventually use pattern expansion all have variable argument +lists which are marked in this man page by "[***]" rather than "[...]". .br Some other commands perform pattern matching unconditionally. .PP @@ -352,18 +352,44 @@ Pattern matching supports the usual shell parser wildcards '*' '?' '[xyz]' and respects '/' as separator which may only be matched literally. .br Setting "off" disables this feature for all commands which are marked in this -man page by "iso_rr_path [***]" or "pattern [***]". +man page by "iso_rr_path [***]" or "iso_rr_pattern [***]". +.br Setting "on" enables it for all those commands. -Setting "ls" enables it only for those which are marked by "pattern [***]". +.br +Setting "ls" enables it only for those which are marked by +"iso_rr_pattern [***]". .br Default is "on". .TP -\fB\-add\fR path [...] +\fB\-disk_pattern\fR "on"|"ls"|"off" +Set the pattern expansion mode for the disk_path arguments of several +commands which support this feature. +.br +Setting "off" disables this feature for all commands which are marked in this +man page by "disk_path [***]" or "disk_pattern [***]". +.br +Setting "on" enables it for all those commands. +.br +Setting "ls" enables it only for those which are marked by +"disk_pattern [***]". +.TP +\fB\-add\fR pathspec [...] | disk_path [***] Insert the given files or directory trees from filesystem into the ISO image. .br -Use the same paths on ISO unless -graft-points is set and -the paths have the form iso_rr_path=disk_path . +If -graft-points is set then pattern expansion is always disabled and +character '=' has a special meaning. It eventually divides the ISO image path +from the disk path: iso_rr_path=disk_path . '=' can be escaped by '\\'. +If iso_rr_path does not begin with '/' then -cd is prepended. +If disk_path does not begin with '/' then -cdx is prepended. +.br +If no '=' is given then the word is used as both, iso_rr_path and disk path. +If in this case the word does not begin with '/' then -cdx is prepended, +not -cd. +.br +If -graft-points-off is set then eventual -disk_pattern expansion applies. +The resulting words are used as both, iso_rr_path and disk path. Eventually +-cdx gets prepended. .TP \fB\-path-list\fR disk_path Like -add but read the pathspecs from file disk_path. @@ -547,7 +573,12 @@ Follow symbolic links. \fB\-graft-points\fR For xorriso action -add this enables pathspecs of the form .B target=source -like with program mkisofs. +like with program mkisofs. It also disables pattern expansion for +command -add. +.TP +\fB\-graft-points-off\fR +For xorriso action -add this disables pathspecs of the form target=source +and eventually enables -disk_pattern expansion for command -add. .TP .B Settings for result writing: .TP @@ -596,8 +627,8 @@ which means unit is kiB (= 1024) or MiB (= 1024 kiB). If "on" then mark the written media as not appendable any more (if possible at all with the given type of target media). .br -This is the contrary of cdrecord, wodim, cdrskin -multi, -and is one aspect of growisofs -dvd-compat. +This is the contrary of cdrecord, wodim, cdrskin option -multi, +and is one aspect of growisofs option -dvd-compat. .TP .B Exception processing: .TP @@ -711,29 +742,43 @@ Tell the current working directory in the ISO image. \fB\-pwdx\fR Tell the current working directory on local filesystem. .TP -\fB\-ls\fR pattern [***] -List files from the current working directory in the ISO -image which match shell patterns (i.e. with wildcards '*' '?' '[a-z]'). +\fB\-ls\fR iso_rr_pattern [***] +List files in the ISO image which match shell patterns (i.e. with wildcards '*' +'?' '[a-z]'). +If a pattern does not begin with '/' then it is compared with addresses +relative to -cd, the current working directory in the ISO image. Note that this resembles rather shell command ls -d than command ls. .TP -> \fB\-lsx\fR pattern [...] -List files from the current working directory on local filesystem -which match shell patterns. +\fB\-lsx\fR disk_pattern [***] +List files on local filesystem which match shell patterns. Patterns which do +not begin with '/' are used relative to -cdx, the current working directory in +the local filesystem. .TP -\fB\-ls_l\fR pattern [***] +\fB\-ls_l\fR iso_rr_pattern [***] Like -ls but also list some of the file attributes. Output format resembles shell command ls -ldn. .TP -> \fB\-ls_lx\fR pattern [...] +\fB\-ls_lx\fR disk_pattern [***] Like -lsx but also list some of the file attributes. .TP -\fB\-du\fR pattern [***] -Recursively list size of directories and files matching one of the patterns, +\fB\-du\fR iso_rr_pattern [***] +Recursively list size of directories and files in the ISO image +which match one of the patterns. similar to shell command du -k. .TP -\fB\-du_s\fR pattern [***] -List size of directories and files matching one of the patterns, -similar to shell command du -sk. +\fB\-dux\fR disk_pattern [***] +Recursively list size of directories and files in the local filesystem +which match one of the patterns, similar to shell command du -k. +.TP +\fB\-du_s\fR iso_rr_pattern [***] +List size of directories and files in the ISO image +which match one of the patterns. +Similar to shell command du -sk. +.TP +\fB\-du_sx\fR disk_pattern [***] +List size of directories and files in the local filesystem +which match one of the patterns. +Similar to shell command du -sk. .TP > \fB\-find\fR pattern Equivalent to shell command find . -name pattern in the ISO image. @@ -864,7 +909,7 @@ with addresses from the hard disk. .B A dialog session doing about the same .br -graft-points is already given as start argument. The other activities -are done as dialog input. The pager gets set to 20 lines of 80 chracters. +are done as dialog input. The pager gets set to 20 lines of 80 characters. .br The drive is aquired by option -dev rather than -outdev in order to see the message about its current content. By option -blank this content is @@ -909,8 +954,7 @@ Load image from drive. Remove (i.e. hide) directory /sounds and its subordinates. Rename directory /pictures/confidential to /pictures/restricted. Change access permissions of directory /pictures/restricted. -Add dummy as replacement of /pictures/confidential. -Add new directory tree /movies. Burn to the same DVD and eject. +Add new directory trees /sounds and /movies. Burn to the same DVD and eject. .br \fB$\fR xorriso -dev /dev/sr2 \\ -rm_r /sounds -- \\ diff --git a/test/xorriso.c b/test/xorriso.c index 781d0b76..c644f63b 100644 --- a/test/xorriso.c +++ b/test/xorriso.c @@ -1989,20 +1989,21 @@ static int Cleanup_set_handlers(void *handle, #endif /* ! Xorriso_cleanup_externaL */ -#ifndef Xorriso_dirseq_externaL - /* ------------------------------------------------------------------------ */ /* DirseQ : crawl along a directory's content list */ -static int Dirseq_buffer_sizE= 1000; +static int Dirseq_buffer_sizE= 100; struct DirseQ { + char adr[SfileadrL]; DIR *dirpt; int count; char **buffer; int buffer_size; int buffer_fill; int buffer_rpt; + + struct DirseQ *next; }; int Dirseq_destroy(struct DirseQ **o, int flag); @@ -2010,7 +2011,7 @@ 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) +int Dirseq_new(struct DirseQ **o, char *adr, int flag) /* bit0= do not complain about failed opendir() */ @@ -2021,25 +2022,29 @@ int Dirseq_new(struct DirseQ **o, char *dir, int flag) m= *o= TSOB_FELD(struct DirseQ,1); if(m==NULL) return(-1); + m->adr[0]= 0; m->dirpt= NULL; m->count= 0; m->buffer= NULL; m->buffer_size= 0; m->buffer_fill= 0; m->buffer_rpt= 0; + m->next= NULL; + if(Sfile_str(m->adr, adr, 0)<=0) + {ret= 0; goto failed;} 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) + if(adr[0]==0) m->dirpt= opendir("."); else - m->dirpt= opendir(dir); + m->dirpt= opendir(adr); if(m->dirpt==NULL) { if(!(flag&1)) - fprintf(stderr,"opendir(%s) failed : %s\n",dir,strerror(errno)); + fprintf(stderr,"opendir(%s) failed : %s\n",adr,strerror(errno)); ret= 0; goto failed; } return(1); @@ -2069,6 +2074,27 @@ int Dirseq_destroy(struct DirseQ **o, int flag) } +int Dirseq_set_next(struct DirseQ *o, struct DirseQ *next, int flag) +{ + o->next= next; + return(1); +} + + +int Dirseq_get_next(struct DirseQ *o, struct DirseQ **next, int flag) +{ + *next= o->next; + return(1); +} + + +int Dirseq_get_adr(struct DirseQ *o, char **adrpt, int flag) +{ + *adrpt= o->adr; + return(1); +} + + int Dirseq_rewind(struct DirseQ *o, int flag) { rewinddir(o->dirpt); @@ -2179,7 +2205,130 @@ return: } -#endif /* ! Xorriso_dirseq_externaL */ +/* ------------------------------- TreeseQ -------------------------------- */ +/* DirseQ : crawl along a filesystem subtree */ + +struct TreeseQ { + char adr[SfileadrL]; + char path[SfileadrL]; + struct DirseQ *dir_stack; + struct stat stbuf; + int follow_links; + int unused_yet; +}; + + +int Treeseq_destroy(struct TreeseQ **o, int flag); + + +/* @param flag bit0= follow symbolic links */ +int Treeseq_new(struct TreeseQ **o, char *adr, int flag) +{ + int ret; + struct TreeseQ *m; + + m= *o= TSOB_FELD(struct TreeseQ,1); + if(m==NULL) + return(-1); + m->adr[0]= 0; + m->path[0]= 0; + m->dir_stack= NULL; + m->follow_links= (flag&1); + m->unused_yet= 1; + if(Sfile_str(m->adr, adr, 0)<=0) + {ret= 0; goto failed;} + strcpy(m->path, adr); + if(m->follow_links) + ret= stat(adr, &(m->stbuf)); + else + ret= lstat(adr, &(m->stbuf)); + if(ret==-1) + {ret= 0; goto failed;} + if(S_ISDIR(m->stbuf.st_mode)) { + ret= Dirseq_new(&(m->dir_stack), adr, 0); + if(ret<=0) + goto failed; + } + return(1); +failed:; + Treeseq_destroy(o,0); + return(ret); +} + + +int Treeseq_destroy(struct TreeseQ **o, int flag) +{ + struct DirseQ *dirseq, *next; + + for(dirseq= (*o)->dir_stack; dirseq!=NULL; dirseq= next) { + next= dirseq->next; + Dirseq_destroy(&dirseq,0); + } + free((char *) *o); + (*o)= NULL; + return(1); +} + + +/* @return <0 error, 0= no more entries available, 1= ok, reply is valid +*/ +int Treeseq_next(struct TreeseQ *o, char adr[SfileadrL], struct stat **stbuf, + int flag) +{ + int ret; + char next_name[SfileadrL], *spt; + struct DirseQ *next_dirseq; + + if(o->dir_stack==NULL) { + if(!o->unused_yet) + return(0); + strcpy(adr, o->adr); + *stbuf= &(o->stbuf); + o->unused_yet= 0; + return(1); + } + o->unused_yet= 0; +next_in_dirseq:; + ret= Dirseq_next_adr(o->dir_stack, next_name, 1); + if(ret<0) + return(ret); + if(ret>0) { + strcpy(adr, o->path); + ret= Sfile_add_to_path(adr, next_name, 0); + if(ret<=0) + return(-1); + if(o->follow_links) + ret= stat(adr, &(o->stbuf)); + else + ret= lstat(adr, &(o->stbuf)); + *stbuf= &(o->stbuf); + + if(!S_ISDIR(o->stbuf.st_mode)) + return(1); + + /* Directory found: push new DirseQ on stack */ + ret= Dirseq_new(&next_dirseq, adr, 0); + if(ret<=0) + return(-1); + Dirseq_set_next(next_dirseq, o->dir_stack, 0); + o->dir_stack= next_dirseq; + strcpy(o->path, adr); + return(1); + } + + /* pop DirseQ from stack */ + Dirseq_get_next(o->dir_stack, &next_dirseq, 0); + Dirseq_destroy(&(o->dir_stack), 0); + o->dir_stack= next_dirseq; + spt= strrchr(o->path, '/'); + if(spt!=NULL) + (*spt)= 0; + else + o->path[0]= 0; + if(o->dir_stack!=NULL) + goto next_in_dirseq; + return(0); /* it is done */ +} /* ------------------------------- Xorriso -------------------------------- */ @@ -2246,6 +2395,7 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) m->search_mode= 0; m->structured_search= 1; m->do_iso_rr_pattern= 1; + m->do_disk_pattern= 2; m->temp_mem_limit= 16*1024*1024; m->use_stdin= 0; m->result_page_length= 0; @@ -2804,15 +2954,20 @@ int Xorriso__bourne_to_reg(char bourne_expr[], char reg_expr[], int flag) /* @param flag bit0= do not augment relative structured search by xorriso->wdi - bit1= return 2 if bonked at root + bit1= return 2 if bonked at start point by .. (caller then aborts or retries without bit0) - @return <=0 error, 1= ok , 2 + bit2= eventually prepend wdx rather than wdi + @return <=0 error, 1= ok, 2= with bit1: relative pattern exceeds start point */ int Xorriso_prepare_regex(struct XorrisO *xorriso, char *adr, int flag) { - int l,ret,i,count,bonked= 0,is_constant; - char *cpt,*npt,adr_part[2*SfileadrL],absolute_adr[2*SfileadrL],*adr_start; + int l,ret,i,count,bonked= 0,is_constant,is_still_relative= 0; + char *cpt,*npt,adr_part[2*SfileadrL],absolute_adr[2*SfileadrL],*adr_start,*wd; + if(flag&2) + wd= xorriso->wdx; + else + wd= xorriso->wdi; #ifndef Xorriso_with_regeX if(xorriso->search_mode==2 || @@ -2828,7 +2983,7 @@ no_regex_available:; 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; + l= strlen(adr)+strlen(wd)+1; if(l*2+2>sizeof(xorriso->reg_expr) || l*2+2>sizeof(adr_part)) { sprintf(xorriso->info_text,"Search pattern too long"); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); @@ -2837,11 +2992,14 @@ no_regex_available:; } Xorriso_destroy_re(xorriso,0); if(xorriso->structured_search && xorriso->search_mode==3) { - if(adr[0]!='/' && !(flag&1)) { + if(adr[0]!='/') + is_still_relative= 1; + if(is_still_relative && !(flag&1)) { /* relative expression : prepend working directory */ - sprintf(absolute_adr,"%s/%s",xorriso->wdi,adr); + sprintf(absolute_adr,"%s/%s",wd,adr); adr_start= absolute_adr; xorriso->prepended_wd= 1; + is_still_relative= 0; } else adr_start= adr; /* count slashes */; @@ -2949,8 +3107,10 @@ next_adr_part:; if(bonked) { if(flag&2) return(2); - sprintf(xorriso->info_text, "Your '..' bonked at the root directory."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING",0); + sprintf(xorriso->info_text, "Your '..' bonked at the %s directory.", + is_still_relative ? "working" : "root"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY",0); + return(0); } Xorriso__bourne_to_reg(adr_start,xorriso->reg_expr,0); /* just for show */ @@ -3263,6 +3423,13 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag) if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); + is_default= (xorriso->do_disk_pattern==2); + sprintf(line,"-disk_pattern %s\n", + (xorriso->do_disk_pattern == 1 ? "on" : + (xorriso->do_disk_pattern == 2 ? "ls" : "off"))); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + is_default= (xorriso->volid[0]==0); sprintf(line,"-V %s\n",Text_shellsafe(xorriso->volid,sfe,0)); if(!(is_default && no_defaults)) @@ -3286,6 +3453,9 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag) if(xorriso->allow_graft_points) { sprintf(line,"-graft-points\n"); Xorriso_status_result(xorriso,filter,fp,flag&2); + } else if(!no_defaults) { + sprintf(line,"-graft-points-off\n"); + Xorriso_status_result(xorriso,filter,fp,flag&2); } if(xorriso->do_follow_links) { @@ -3446,6 +3616,297 @@ ex: } +/* @param flag bit2= this is a disk_pattern + @return <=0 failure , 1 pattern ok , 2 pattern needed prepended wd */ +int Xorriso_prepare_expansion_pattern(struct XorrisO *xorriso, char *pattern, + int flag) +{ + int ret, prepwd= 0; + + ret= Xorriso_prepare_regex(xorriso, pattern, 1|2|(flag&4)); + if(ret==2) { + ret= Xorriso_prepare_regex(xorriso, pattern, flag&4); + prepwd= 1; + } + if(ret<=0) { + sprintf(xorriso->info_text, + "Cannot compile pattern to regular expression: %s", pattern); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + return(1+prepwd); +} + + +/* @param flag bit0= count results rather than storing them + bit1= this is a recursion + bit2= prepend wd (automatically done if wd[0]!=0) + @return <=0 error , 1 ok , 2 could not open directory +*/ +int Xorriso_obtain_disk_files( + struct XorrisO *xorriso, char *wd, char *dir_adr, + int *filec, char **filev, int count_limit, off_t *mem, + int *dive_count, int flag) +{ + int ret, failed_at, l; + char adr[SfileadrL], name[SfileadrL]; + struct DirseQ *dirseq; + + if(!(flag&2)) + *dive_count= 0; + else + (*dive_count)++; + if(xorriso->re_fill==0) { /* This is the empty pattern representing root */ + if(flag&1) { + (*filec)++; + (*mem)+= 8; + {ret= 1; goto ex;} + } else { + if(*filec >= count_limit) + goto unexpected_change; + filev[*filec]= strdup("/"); + if(filev[*filec]==NULL) + goto out_of_memory; + (*filec)++; + {ret= 1; goto ex;} + } + } + + ret= Dirseq_new(&dirseq, dir_adr, 1); + if(ret<0) { + sprintf(xorriso->info_text, "Cannot obtain disk directory iterator"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + {ret= -1; goto ex;} + } + if(ret==0) + {ret= 2; goto ex;} + + while(1) { + ret= Dirseq_next_adr(dirseq,name,0); + if(ret==0) + break; + if(ret<0) { + sprintf(xorriso->info_text,"Failed to obtain next directory entry"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + {ret= -1; goto ex;} + } + if(wd[0]!=0 || (flag&4)) { + if(strlen(wd)+1>=SfileadrL) + goto much_too_long; + strcpy(adr, wd); + if(Sfile_add_to_path(adr, name, 0)<=0) { +much_too_long:; + sprintf(xorriso->info_text, + "Path for pattern matching gets much too long (%d)", + (int) (strlen(adr)+strlen(name)+1)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + {ret= 0; goto ex;} + } + } else { + if(strlen(name)+1>=SfileadrL) + goto much_too_long; + strcpy(adr, name); + } + + ret= Xorriso_regexec(xorriso, adr, &failed_at, 1); + if(ret>0) { /* no match */ + if(failed_at <= *dive_count) /* no hope for a match */ + continue; + + ret= Sfile_type(adr, 1|((xorriso->do_follow_links || !(flag&2))<<2)); + if(ret!=2) + continue; + /* dive deeper */ + ret= Xorriso_obtain_disk_files(xorriso, adr, adr, + filec, filev, count_limit, mem, dive_count, flag|2); + if(ret<=0) + goto ex; + } else { + if(flag&1) { + (*filec)++; + l= strlen(adr)+1; + (*mem)+= sizeof(char *)+l; + if(l % sizeof(char *)) + (*mem)+= sizeof(char *)-(l % sizeof(char *)); + } else { + if(*filec >= count_limit) { +unexpected_change:; + sprintf(xorriso->info_text, + "Number of matching files changed unexpectedly (> %d)", + count_limit); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + {ret= -1; goto ex;} + } + filev[*filec]= strdup(adr); + if(filev[*filec]==NULL) { +out_of_memory:; + sprintf(xorriso->info_text, + "Cannot allocate enough memory (%d bytes) for pattern expansion", + (int) strlen(adr)+1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + {ret= -1; goto ex;} + } + (*filec)++; + } + } + } + ret= 1; +ex:; + if(flag&2) + (*dive_count)--; + return(ret); +} + + +/* @param flag bit0= a match count !=1 is a SORRY event + bit1= with bit0 tolerate 0 matches if pattern is a constant +*/ +int Xorriso_expand_disk_pattern(struct XorrisO *xorriso, + int num_patterns, char **patterns, int extra_filec, + int *filec, char ***filev, off_t *mem, int flag) +{ + int ret, count= 0, abs_adr= 0, i, l, was_count, was_filec, k; + int nonconst_mismatches= 0, dive_count= 0; + char mem_text[80], limit_text[80], sfe[5*SfileadrL], dir_adr[SfileadrL]; + + *filec= 0; + *filev= NULL; + + xorriso->search_mode= 3; + xorriso->structured_search= 1; + + for(i= 0; iwdx); + ret= Sfile_type(dir_adr, 1|4); + if(ret!=2) { + sprintf(xorriso->info_text, + "Address set by -cdx is not a directory: %s", + Text_shellsafe(dir_adr, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + ret= 0; goto ex; + } + } + + /* count the matches */ + was_count= count; + ret= Xorriso_obtain_disk_files(xorriso, "", dir_adr, &count, NULL, 0, mem, + &dive_count, 1 | abs_adr); + if(ret<=0) + goto ex; + if(was_count==count && strcmp(patterns[i],"*")!=0 && (flag&3)!=1) { + count++; + + /* Is this a constant pattern ? */ + for(k= 0; kre_fill; k++) { + if(xorriso->re_constants[k]==NULL) + break; + if(xorriso->re_constants[k][0]==0) + break; + } + if(kre_fill) + nonconst_mismatches++; /* it is not */ + + l= strlen(patterns[i])+1; + (*mem)+= sizeof(char *)+l; + if(l % sizeof(char *)) + (*mem)+= sizeof(char *)-(l % sizeof(char *)); + } + } + + if((flag&1) && (count!=1 || nonconst_mismatches)){ + if(count-nonconst_mismatches>0) + sprintf(xorriso->info_text, + "Pattern match with more than one file object"); + else + sprintf(xorriso->info_text, "No pattern match with any file object"); + if(num_patterns==1) + sprintf(xorriso->info_text+strlen(xorriso->info_text), ": %s", + Text_shellsafe(patterns[0], sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + ret= 0; goto ex; + } + + count+= extra_filec; + mem+= extra_filec*sizeof(char *); + + if(count<=0) + {ret= 0; goto ex;} + + Sfile_scale((double) *mem, mem_text,5,1e4,0); + sprintf(xorriso->info_text, + "Temporary memory needed for pattern expansion : %s", mem_text); + if(!(flag&1)) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + if(*mem > xorriso->temp_mem_limit) { + Sfile_scale((double) xorriso->temp_mem_limit, limit_text,5,1e4,1); + sprintf(xorriso->info_text, + "List of matching file addresses exceeds -temp_mem_limit (%s > %s)", + mem_text, limit_text); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + ret= 0; goto ex; + } + + (*filev)= (char **) calloc(sizeof(char *), count); + if(*filev==NULL) { +no_memory:; + Sfile_scale((double) *mem, mem_text,5,1e4,1); + sprintf(xorriso->info_text, + "Cannot allocate enough memory (%s) for pattern expansion", + mem_text); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + ret= -1; goto ex; + } + + /* now store addresses */ + for(i= 0; iwdx); + + was_filec= *filec; + ret= Xorriso_obtain_disk_files(xorriso, "", dir_adr, filec, *filev, count, + mem, &dive_count, abs_adr); + if(ret<=0) + goto ex; + if(was_filec == *filec && strcmp(patterns[i],"*")!=0) { + (*filev)[*filec]= strdup(patterns[i]); + if((*filev)[*filec]==NULL) { + (*mem)= strlen(patterns[i])+1; + goto no_memory; + } + (*filec)++; + } + } + + ret= 1; +ex:; + if(ret<=0) { + if(filev!=NULL) + Sfile_destroy_argv(&count, filev, 0); + *filec= 0; + } + return(ret); +} + + int Xorriso_warn_of_wildcards(struct XorrisO *xorriso, char *path, int flag) { if(strchr(path,'*')!=NULL || strchr(path,'?')!=NULL || @@ -3461,6 +3922,7 @@ int Xorriso_warn_of_wildcards(struct XorrisO *xorriso, char *path, int flag) /* @param flag bit0= do not warn of wildcards + bit1= these are disk_paths */ int Xorriso_end_idx(struct XorrisO *xorriso, int argc, char **argv, int idx, int flag) @@ -3508,7 +3970,10 @@ int Xorriso_opt_args(struct XorrisO *xorriso, char **filev= NULL, **patterns= NULL; off_t mem= 0; - do_expand= xorriso->do_iso_rr_pattern==1 && (!(flag&4)) && (!(flag&2)); + if(flag&2) + do_expand= xorriso->do_disk_pattern==1 && !(flag&4); + else + do_expand= xorriso->do_iso_rr_pattern==1 && !(flag&4); if(flag&256) { if(*optv=argv+argc) Sfile_destroy_argv(optc, optv, 0); @@ -3554,8 +4019,12 @@ no_memory:; free(patterns); return(1); } - ret= Xorriso_expand_pattern(xorriso, nump, patterns, was_empty, - &filec, &filev, &mem, (flag>>5)&3); + if(flag&2) + ret= Xorriso_expand_disk_pattern(xorriso, nump, patterns, was_empty, + &filec, &filev, &mem, (flag>>5)&3); + else + ret= Xorriso_expand_pattern(xorriso, nump, patterns, was_empty, + &filec, &filev, &mem, (flag>>5)&3); if(ret<=0) {ret= 0; goto ex;} for(i= 0; i=SfileadrL || (flag&2)) { + sprintf(xorriso->info_text, + "Path given for %s is much too long (%d)", + ((flag&1) ? "local filesystem" : "ISO image"), len); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + return(1); +} + +/* @param flag bit1= do not report memory usage as DEBUG +*/ +int Xorriso_check_temp_mem_limit(struct XorrisO *xorriso, off_t mem, int flag) +{ + char mem_text[80], limit_text[80]; + + Sfile_scale((double) mem, mem_text,5,1e4,0); + if(!(flag&2)) { + sprintf(xorriso->info_text, + "Temporary memory needed for result sorting : %s", mem_text); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + } + if(mem > xorriso->temp_mem_limit) { + Sfile_scale((double) xorriso->temp_mem_limit,limit_text,5,1e4,1); + sprintf(xorriso->info_text, + "Cannot sort. List of matching files exceeds -temp_mem_limit (%s > %s)", + mem_text, limit_text); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + return(0); + } + return(1); +} + + +/* @param flag bit0= do not only sum up sizes but also print subdirs + @return <=0 error , 1 ok , 2 could not open directory +*/ +int Xorriso_show_dux_subs(struct XorrisO *xorriso, + char *abs_path, char *rel_path, off_t *size, + off_t boss_mem, int flag) +{ + int i, ret, no_sort= 0, filec= 0, l, j, fc; + char path[SfileadrL], show_path[SfileadrL], name[SfileadrL], sfe[5*SfileadrL]; + char **filev= NULL, *namept; + off_t sub_size, report_size, mem= 0; + struct DirseQ *dirseq= NULL; + struct stat stbuf; + + namept= name; + *size= 0; + + ret= Dirseq_new(&dirseq, abs_path, 1); + if(ret<0) { + sprintf(xorriso->info_text, "Cannot obtain disk directory iterator"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + {ret= -1; goto ex;} + } + if(ret==0) + {ret= 2; goto ex;} + + while(1) { + ret= Dirseq_next_adr(dirseq,name,0); + if(ret<0) + goto ex; + if(ret==0) + break; + + sub_size= 0; + strcpy(show_path, rel_path); + if(Sfile_add_to_path(show_path, name, 0)<=0) + goto much_too_long; + + strcpy(path, abs_path); + if(Sfile_add_to_path(path, name, 0)<=0) { +much_too_long:; + Xorriso_much_too_long(xorriso, strlen(path)+strlen(name)+1, 2); + {ret= -1; goto ex;} + } + ret= lstat(path, &stbuf); + if(ret==-1) + continue; + if(S_ISDIR(stbuf.st_mode)) { + filec++; + l= strlen(rel_path)+1; + mem+= l; + if(l % sizeof(char *)) + mem+= sizeof(char *)-(l % sizeof(char *)); + ret= Xorriso_show_dux_subs(xorriso, path,show_path,&sub_size,boss_mem,0); + if(ret<0) + goto ex; + if(ret==0) + continue; + } + + sub_size+= stbuf.st_size+strlen(name)+1; + if(sub_size>0) + (*size)+= sub_size; + Xorriso_process_msg_queues(xorriso,0); + } + + if(filec<=0 || !(flag&1)) + {ret= 1; goto ex;} + + /* Try to get a sorted list of directory names */ + mem+= (filec+1)*sizeof(char *); + ret= Xorriso_check_temp_mem_limit(xorriso, mem+boss_mem, 2); + if(ret<0) + goto ex; + Dirseq_rewind(dirseq, 0); + if(ret==0) { +no_sort_possible:; + no_sort= 1; + } else { + filev= (char **) calloc(sizeof(char *), filec+1); + if(filev==NULL) + goto no_sort_possible; + else { + for(i= 0; i1) + Sort_argv(filec, filev, 0); + } + } + + for(i= 0; (no_sort || irequest_to_abort); i++) { + + if(no_sort) { + ret= Dirseq_next_adr(dirseq,name,0); + if(ret<0) + goto ex; + if(ret==0) + break; + ret= lstat(path, &stbuf); + if(ret==-1) + continue; + if(!S_ISDIR(stbuf.st_mode)) + continue; + } else + namept= filev[i]; + sub_size= 0; + strcpy(show_path, rel_path); + if(Sfile_add_to_path(show_path, namept, 0)<=0) + goto much_too_long; + strcpy(path, abs_path); + if(Sfile_add_to_path(path, namept, 0)<=0) + goto much_too_long; + + ret= Xorriso_show_dux_subs(xorriso, + path, show_path, &sub_size, boss_mem+mem, flag&1); + if(ret<0) + goto ex; + report_size= sub_size/1024; + if(report_size*1024result_line, "%7.f ",(double) (report_size)); + sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n", + Text_shellsafe(show_path, sfe, 0)); + Xorriso_result(xorriso, 0); + } + + ret= 1; +ex:; + Dirseq_destroy(&dirseq, 0); + if(filev!=NULL) { + for(i=0; iresult_line; + + Sort_argv(filec, filev, 0); + + /* Count valid nodes, warn of invalid ones */ + for(i= 0; iwdx); + if(Sfile_add_to_path(path, filev[i], 0)<=0) { +much_too_long:; + sprintf(xorriso->info_text, + "Path for file listing gets much too long (%d)", + (int) (strlen(path)+strlen(filev[i])+1)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + was_error++; + continue; + } + } else + if(Sfile_str(path, filev[i], 0)<=0) + goto much_too_long; + + if(xorriso->do_follow_links) + ret= stat(path, &stbuf); + else + ret= lstat(path, &stbuf); + if(ret==-1) { + sprintf(xorriso->info_text, "Not found in local filesystem: %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + was_error++; + continue; + } + } + + if(!(flag&(2|4))) { + sprintf(xorriso->info_text,"Valid local files found: %d\n",filec-was_error); + Xorriso_info(xorriso,1); + if(filec-was_error<=0) + return(!was_error); + } + + for(i= 0; irequest_to_abort); i++) { + if(filev[i][0]!='/') { + strcpy(path, xorriso->wdx); + if(Sfile_add_to_path(path, filev[i], 0)<=0) + continue; + } else + if(Sfile_str(path, filev[i], 0)<=0) + continue; + + if(xorriso->do_follow_links) + ret= stat(path, &stbuf); + else + ret= lstat(path, &stbuf); + if(ret==-1) + continue; + + size= stbuf.st_size; + rpt[0]= 0; + st_mode= stbuf.st_mode; + if((flag&5)==1) { /* -ls_lx */ + if(S_ISDIR(st_mode)) + strcat(rpt, "d"); + else if(S_ISREG(st_mode)) + strcat(rpt, "-"); + else if(S_ISLNK(st_mode)) + strcat(rpt, "l"); + else if(S_ISBLK(st_mode)) + strcat(rpt, "b"); + else if(S_ISCHR(st_mode)) + strcat(rpt, "c"); + else if(S_ISFIFO(st_mode)) + strcat(rpt, "p"); + else if(S_ISSOCK(st_mode)) + strcat(rpt, "s"); + else + strcat(rpt, "?"); + + Xorriso__mode_to_perms(st_mode, perms, 0); + strcat(rpt, perms); + + sprintf(rpt+strlen(rpt),"%4u ",(unsigned int) stbuf.st_nlink); + + sprintf(rpt+strlen(rpt), "%-8lu ", (unsigned long) stbuf.st_uid); + sprintf(rpt+strlen(rpt), "%-8lu ", (unsigned long) stbuf.st_gid); + sprintf(rpt+strlen(rpt), "%8.f ",(double) size); + mtime= stbuf.st_mtime; + tmpt= localtime_r(&mtime, &tms); + if(tmpt==0) + sprintf(rpt+strlen(rpt), "%12.f ",(double) mtime); + else if(time(NULL)-mtime < 180*86400 && time(NULL)-mtime >= 0) + sprintf(rpt+strlen(rpt), "%3s %2d %2.2d:%2.2d ", + months[tms.tm_mon], tms.tm_mday, tms.tm_hour, tms.tm_min); + else + sprintf(rpt+strlen(rpt), "%3s %2d %4.4d ", + months[tms.tm_mon], tms.tm_mday, 1900+tms.tm_year); + + } else if(flag&4) { /* -du or -du_s */ + + if(S_ISDIR(st_mode)) { + ret= Xorriso_show_dux_subs(xorriso, + path, filev[i], &size, boss_mem, flag&1); + if(ret<0) + return(-1); + if(ret==0) + continue; + } + sprintf(rpt, "%7.f ",(double) (size/1024)); + + } + sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n", + Text_shellsafe(filev[i], sfe, 0)); + Xorriso_result(xorriso, 0); + } + return(!was_error); +} + + /* ---------------------------- Options API ------------------------ */ @@ -3809,32 +4649,52 @@ int Xorriso_option_abort_on(struct XorrisO *xorriso, char *severity, int flag) int Xorriso_option_add(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag) { - int i, end_idx, ret, was_failure= 0, fret; + int i, end_idx, ret, was_failure= 0, fret, optc= 0, split; char target[SfileadrL], source[SfileadrL], *ept, eff_path[SfileadrL]; + char **optv= NULL, *rpt, *wpt; - end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 0); + ret= Xorriso_opt_args(xorriso, argc, argv, *idx, &end_idx, &optc, &optv, + ((!!xorriso->allow_graft_points)<<2)|2); + if(ret<=0) + goto ex; - for(i= *idx; iallow_graft_points) { ret= Fileliste__target_source_limit(target, '=', &ept, 0); if(ret>0) { *ept= 0; strcpy(source, ept+1); + split= 1; } - } - if(target[0]!='/') { - ret= Sfile_prepend_path(xorriso->wdi, target, 0); - if(ret<=0) - goto problem_handler; + /* unescape \= */; + if(split) + rpt= wpt= target; + else + rpt= wpt= source; + for(; *rpt!=0; rpt++) { + if(*rpt=='\\') + if(*(rpt+1)=='=') + continue; + *(wpt++)= *rpt; + } + *wpt= 0; } if(source[0]!='/') { ret= Sfile_prepend_path(xorriso->wdx, source, 0); if(ret<=0) goto problem_handler; } + if(split==0) { + strcpy(target, source); + } else if(target[0]!='/') { + ret= Sfile_prepend_path(xorriso->wdi, target, 0); + if(ret<=0) + goto problem_handler; + } ret= Xorriso_normalize_img_path(xorriso, target, eff_path, 2); if(ret<=0) @@ -3864,6 +4724,7 @@ problem_handler:; ret= 1; ex:; (*idx)= end_idx; + Xorriso_opt_args(xorriso, argc, argv, *idx, &end_idx, &optc, &optv, 256); if(ret<=0) return(ret); return(!was_failure); @@ -4474,6 +5335,24 @@ int Xorriso_option_dialog(struct XorrisO *xorriso, char *mode, int flag) } +/* Option -disk_pattern "on"|"ls"|"off" */ +int Xorriso_option_disk_pattern(struct XorrisO *xorriso, char *mode, int flag) +{ + if(strcmp(mode, "off")==0) + xorriso->do_disk_pattern= 0; + else if(strcmp(mode, "on")==0) + xorriso->do_disk_pattern= 1; + else if(strcmp(mode, "ls")==0) + xorriso->do_disk_pattern= 2; + else { + sprintf(xorriso->info_text, "-disk_pattern: unknown mode '%s'", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + return(1); +} + + /* Option -dummy "on"|"off" */ int Xorriso_option_dummy(struct XorrisO *xorriso, char *mode, int flag) { @@ -4612,9 +5491,10 @@ int Xorriso_option_gid(struct XorrisO *xorriso, char *gid, int flag) /* Option -graft-points */ +/* @param flag bit0= disable graft points */ int Xorriso_option_graft_points(struct XorrisO *xorriso, int flag) { - xorriso->allow_graft_points= 1; + xorriso->allow_graft_points= !(flag&1); return(1); } @@ -4642,9 +5522,9 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) "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", +" -indev address Set input drive and load eventual ISO image. Switch from", " growing to modifying.", -"> -outdev address", +" -outdev address", " Set output drive and switch from growing to modifying.", " -ban_stdio_write", " Allow for writing only the usage of optical drives.", @@ -4677,13 +5557,16 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) "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.", "Options marked by [***] have variable argument length and perform pattern", -"expansion if enabled by -iso_rr_pattern.", +"expansion if enabled by -iso_rr_pattern resp. -disk_pattern.", "", -" -add pathspec [...] Insert the given files or directory trees from", +" -add pathspec [...] | disk_path [***]", +" 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", +" -graft-points-off Disallow pathspecs of form iso_rr_path=disk_path", +" but allow eventual -disk_pattern expansion.", "", "> -cp_r disk_path [...] iso_rr_path", " Insert the given files or directory trees from filesystem", @@ -4692,7 +5575,7 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " 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", +" -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 [***]", @@ -4754,25 +5637,33 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " -pwdx tells the current working directory in the local filesystem.", "", " -iso_rr_pattern \"on\"|\"ls\"|\"off\"", -" Enable or disable pattern expansions for commands marked", -" by [***]. \"ls\" restricts it to -ls and -du.", +" Enable or disable pattern expansions for ISO image commands", +" marked by [***]. \"ls\" restricts it to -ls and -du.", +" -disk_pattern \"on\"|\"ls\"|\"off\"", +" Enable or disable pattern expansions for local filesystem", +" commands marked by [***]. \"ls\" restricts to -lsx and -dux.", "", " -ls pattern [***] lists files of the ISO image which match one of the", " given shell parser patterns. (I.e. wildcards '*' '?')", " -lsi pattern [***] same as -ls.", -"> -lsx pattern [...] lists files of the local filesystem which match one", +" -lsx pattern [***] lists files of the local filesystem which match one", " of the patterns.", "", " -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.", +" -ls_lx pattern [***] like -lsx but also telling some file attributes.", "", -" -du pattern [***] recursively lists sizes of files or directories which", -" match one of the shell parser patterns.", +" -du pattern [***] recursively lists sizes of files or directories in the", +" ISO image which match one of the shell parser patterns.", " -dui pattern [***] same as -du.", +" -dux pattern [***] recursively lists sizes of files or directories in the", +" local filesystem which match one of the shell parser", +" patterns.", " -du_s pattern [***] like -du but summing up subdirectories without", " listing them explicitely.", " -du_si pattern [***] same as -du_s.", +" -du_sx pattern [***] like -dux but summing up subdirectories without", +" listing them explicitely.", "", "> -find pattern lists matching files below current working directory in", " the ISO image.", @@ -4916,9 +5807,8 @@ int Xorriso_option_lsi(struct XorrisO *xorriso, int argc, char **argv, flag|= 2; nump= end_idx - *idx; - if(flag&2) { - if(nump <= 0) - return(0); + if((flag&2) && nump>0 ) { + ; } else if(nump <= 0) { patterns= calloc(sizeof(char *), 1); if(patterns == NULL) { @@ -4930,6 +5820,7 @@ no_memory:; } nump= 1; patterns[0]= "*"; + flag&= ~2; } else { patterns= calloc(sizeof(char *), nump); if(patterns==NULL) @@ -4942,7 +5833,7 @@ no_memory:; } } if(flag&2) { - ret= Xorriso_ls_filev(xorriso, nump, argv + (*idx), mem, flag&1); + ret= Xorriso_ls_filev(xorriso, nump, argv + (*idx), mem, flag&(1|4)); } else if(nump==1 && strcmp(patterns[0],"*")==0 && !(flag&4)){ /* save temporary memory by calling simpler function */ ret= Xorriso_ls(xorriso, (flag&1)|4); @@ -4966,19 +5857,75 @@ ex:; } -/* Options -lsx and -ls_lx */ -/* @param flag bit0= long format (-ls_l) */ -int Xorriso_option_lsx(struct XorrisO *xorriso, char *pattern, int flag) +/* Options -lsx , -ls_lx , + -dux , -du_sx + @param flag bit0= long format (-ls_lx , -dux) + bit1= do not expand patterns but use literally + bit2= du rather than ls +*/ +int Xorriso_option_lsx(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) { - char sfe[5*SfileadrL]; + int ret, end_idx, filec= 0, nump, i; + char **filev= NULL, **patterns= NULL; + off_t mem= 0; - fprintf(stderr, ">>> XORRISO : filter by pattern %s\n", pattern); - /* >>> prepare regex */ + end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1|2); + if(xorriso->do_disk_pattern==0) + flag|= 2; - fprintf(stderr, ">>> XORRISO : -ls of disk directory %s\n", - Text_shellsafe(xorriso->wdx, sfe, 0)); + nump= end_idx - *idx; + if((flag&2) && nump>0) { + ; + } else if(nump <= 0) { + patterns= calloc(sizeof(char *), 1); + if(patterns == NULL) { +no_memory:; + sprintf(xorriso->info_text, + "Cannot allocate enough memory for pattern expansion"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + {ret= -1; goto ex;} + } + nump= 1; + patterns[0]= "*"; + flag&= ~2; + } else { + patterns= calloc(sizeof(char *), nump); + if(patterns==NULL) + goto no_memory; + for(i= 0; i4); + ret= Xorriso_option_lsx(xorriso, argc, argv, idx, strlen(cmd)>4); } else if(strcmp(cmd,"-logfile")==0) { (*idx)+= 2; @@ -6073,25 +7030,36 @@ next_command:; ret= Xorriso_option_temp_mem_limit(xorriso, arg1, 0); } else if(strcmp(cmd,"-test")==0) { /* This option does not exist. */ - char line[4096],**hargv= NULL; - int hargc, i; + char line[4096]; + struct TreeseQ *seq; + struct stat *stbufpt; - printf("XORRISO: -test : enter a line for test parsing\n"); + printf("XORRISO: -test : enter a file address for tree crawling\n"); ret= Xorriso_dialog_input(xorriso,line,sizeof(line),4); if(ret<=0) goto eval_any_problems; - ret= Sfile_make_argv(xorriso->progname, line, &hargc, &hargv, 4|8); + ret= Treeseq_new(&seq, line, 0); if(ret<=0) { - fprintf(stderr, "--- Malformed quotation marking encountered\n"); + sprintf(xorriso->info_text,"Failed to create TreeseQ"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); goto eval_any_problems; } - for(i=0; iresult_line,"%d : |%s|\n", i, hargv[i]); - ret= Xorriso_result(xorriso,0); + while(1) { + ret= Treeseq_next(seq, line, &stbufpt, 0); if(ret<=0) - goto eval_any_problems; + break; + sprintf(xorriso->result_line,"%s%s\n",line, + S_ISDIR(stbufpt->st_mode) ? "/" : ""); + Xorriso_result(xorriso,0); + if(xorriso->request_to_abort) + break; + } + Treeseq_destroy(&seq, 0); + if(ret<0) { + sprintf(xorriso->info_text,"Tree crawling aborted"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + goto eval_any_problems; } - Sfile_make_argv(xorriso->progname, line, &hargc, &hargv, 2); } else if(strcmp(cmd,"-toc")==0) { Xorriso_option_toc(xorriso, 0); diff --git a/test/xorriso.h b/test/xorriso.h index 5d085271..fdf40779 100644 --- a/test/xorriso.h +++ b/test/xorriso.h @@ -185,6 +185,9 @@ 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 -disk_pattern "on"|"ls"|"off" */ +int Xorriso_option_disk_pattern(struct XorrisO *xorriso, char *mode, int flag); + /* Option -dummy "on"|"off" */ int Xorriso_option_dummy(struct XorrisO *xorriso, char *mode, int flag); @@ -214,6 +217,7 @@ int Xorriso_option_fs(struct XorrisO *xorriso, char *size, int flag); int Xorriso_option_gid(struct XorrisO *xorriso, char *gid, int flag); /* Option -graft-points */ +/* @param flag bit0= disable graft points */ int Xorriso_option_graft_points(struct XorrisO *xorriso, int flag); /* Option -help and part of -prog_help */ @@ -238,6 +242,15 @@ int Xorriso_option_lsi(struct XorrisO *xorriso, int argc, char **argv, int Xorriso_option_logfile(struct XorrisO *xorriso, char *channel, char *fileadr, int flag); +/* Options -lsx , -ls_lx , + -dux , -du_sx + @param flag bit0= long format (-ls_lx , -dux) + bit1= do not expand patterns but use literally + bit2= du rather than ls +*/ +int Xorriso_option_lsx(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag); + /* Option -mark */ int Xorriso_option_mark(struct XorrisO *xorriso, char *mark, int flag); diff --git a/test/xorriso_private.h b/test/xorriso_private.h index 6cb3bb72..811cdfe5 100644 --- a/test/xorriso_private.h +++ b/test/xorriso_private.h @@ -123,6 +123,7 @@ struct XorrisO { /* the global context of xorriso */ */ int do_iso_rr_pattern; /* 0=off, 1=on, 2=ls */ + int do_disk_pattern; /* 0=off, 1=on, 2=ls */ int temp_mem_limit; @@ -196,6 +197,17 @@ int Xorriso_execute_option(struct XorrisO *xorriso, char *line, int flag); int Xorriso_regexec(struct XorrisO *xorriso, char *to_match, int *failed_at, int flag); +int Xorriso_prepare_expansion_pattern(struct XorrisO *xorriso, char *pattern, + int flag); + +int Xorriso__mode_to_perms(mode_t st_mode, char perms[10], int flag); + +int Xorriso_much_too_long(struct XorrisO *xorriso, int len, int flag); + +int Xorriso_check_temp_mem_limit(struct XorrisO *xorriso, off_t mem, int flag); + + + int Sfile_str(char target[SfileadrL], char *source, int flag); double Sfile_microtime(int flag); @@ -212,7 +224,7 @@ int Sort_argv(int argc, char **argv, int flag); struct DirseQ; -int Dirseq_new(struct DirseQ **o, char *dir, int flag); +int Dirseq_new(struct DirseQ **o, char *adr, int flag); int Dirseq_destroy(struct DirseQ **o, int flag); diff --git a/test/xorriso_timestamp.h b/test/xorriso_timestamp.h index 8fa386e4..1395f898 100644 --- a/test/xorriso_timestamp.h +++ b/test/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2007.11.26.192113" +#define Xorriso_timestamP "2007.12.04.074340" diff --git a/test/xorrisoburn.c b/test/xorrisoburn.c index 212823a0..e49f8624 100644 --- a/test/xorrisoburn.c +++ b/test/xorrisoburn.c @@ -101,20 +101,6 @@ int Xorriso_startup_libraries(struct XorrisO *xorriso, int flag) } -/* @param flag bit0=path is in source filesystem , bit1= unconditionally */ -int Xorriso_much_too_long(struct XorrisO *xorriso, int len, int flag) -{ - if(len>=SfileadrL || (flag&2)) { - sprintf(xorriso->info_text, - "Path given for %s is much too long (%d)", - ((flag&1) ? "local filesystem" : "ISO image"), len); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - return(1); -} - - /* @param flag bit1= obtain outdrive, else indrive */ int Xorriso_get_drive_handles(struct XorrisO *xorriso, struct burn_drive_info **dinfo, @@ -852,6 +838,7 @@ int Xorriso_add_tree(struct XorrisO *xorriso, struct iso_tree_node_dir *dir, Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); ret=0; goto was_problem; } + xorriso->volset_change_pending= 1; /* name always equal to disk. Obsolete: iso_tree_node_set_name(node,name);*/ if(source_is_dir) { ret= Xorriso_add_tree(xorriso, (struct iso_tree_node_dir *) node, @@ -891,8 +878,10 @@ int Xorriso_graft_in(struct XorrisO *xorriso, char *disk_path, char *img_path, struct stat stbuf; for(cpt= img_path; 1; cpt++) { +/* if(cpt[0]!='/') break; +*/ cpt= strstr(cpt,"/."); if(cpt==NULL) break; @@ -943,6 +932,7 @@ int Xorriso_graft_in(struct XorrisO *xorriso, char *disk_path, char *img_path, "Source '%s' is not a directory. Target '%s' would be.", disk_path, img_path); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); } } } @@ -1011,6 +1001,7 @@ handle_path_node:; Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); return(0); } + xorriso->volset_change_pending= 1; iso_tree_node_set_ctime((struct iso_tree_node *) dir, time(NULL)); /* >>> copy properties from correspondent directory in disk_path @@ -1048,13 +1039,13 @@ attach_source:; Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); return(0); } + xorriso->volset_change_pending= 1; iso_tree_node_set_name(node, apt); } } else *npt= '/'; } Xorriso_process_msg_queues(xorriso,0); - xorriso->volset_change_pending= 1; return(1+!!is_dir); } @@ -1720,26 +1711,15 @@ int Xorriso_sorted_node_array(struct XorrisO *xorriso, off_t boss_mem, int flag) { int i, ret, failed_at; - char *npt, mem_text[80], limit_text[80]; + char *npt; struct iso_tree_iter *iter= NULL; struct iso_tree_node *node; off_t mem; mem= ((*nodec)+1)*sizeof(struct iso_tree_node *); - Sfile_scale((double) mem, mem_text,5,1e4,0); - if(!(flag&2)) { - sprintf(xorriso->info_text, - "Temporary memory needed for result sorting : %s", mem_text); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - } - if(mem > xorriso->temp_mem_limit - boss_mem) { - Sfile_scale((double) xorriso->temp_mem_limit - boss_mem,limit_text,5,1e4,1); - sprintf(xorriso->info_text, - "Cannot sort. List of matching files exceeds -temp_mem_limit (%s > %s)", - mem_text, limit_text); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - return(0); - } + ret= Xorriso_check_temp_mem_limit(xorriso, mem+boss_mem, flag&2); + if(ret<=0) + return(ret); *node_array= calloc(sizeof(struct iso_tree_node *), (*nodec)+1); if(*node_array==NULL) { @@ -1839,7 +1819,7 @@ much_too_long:; iter= iso_tree_node_children(dir_node); } - for(i= 0; irequest_to_abort); i++) { + for(i= 0; (no_sort || irequest_to_abort); i++) { if(no_sort) { node= iso_tree_iter_next(iter); if(node==NULL) @@ -1880,40 +1860,6 @@ ex:; } -int Xorriso__mode_to_perms(mode_t st_mode, char perms[10], int flag) -{ - strcpy(perms,"---------"); - if(st_mode&S_IRUSR) perms[0]= 'r'; - if(st_mode&S_IWUSR) perms[1]= 'w'; - if(st_mode&S_IXUSR) perms[2]= 'x'; - if(st_mode&S_ISUID) { - if(st_mode&S_IXUSR) - perms[2]= 's'; - else - perms[2]= 'S'; - } - if(st_mode&S_IRGRP) perms[3]= 'r'; - if(st_mode&S_IWGRP) perms[4]= 'w'; - if(st_mode&S_IXGRP) perms[5]= 'x'; - if(st_mode&S_ISGID) { - if(st_mode&S_IXGRP) - perms[5]= 's'; - else - perms[5]= 'S'; - } - if(st_mode&S_IROTH) perms[6]= 'r'; - if(st_mode&S_IWOTH) perms[7]= 'w'; - if(st_mode&S_IXOTH) perms[8]= 'x'; - if(st_mode&S_ISVTX) { - if(st_mode&S_IXOTH) - perms[8]= 't'; - else - perms[8]= 'T'; - } - return(1); -} - - /* @param flag bit0= long format bit1= do not print count of nodes bit2= du format @@ -2004,7 +1950,7 @@ much_too_long:; /* >>> With directories this should be : number of subdirs + 2 */ /* >>> ??? How to obtain RR hardlink number for other types ? */ - strcat(rpt," 1 "); + strcat(rpt," 1 "); sprintf(rpt+strlen(rpt), "%-8lu ", (unsigned long) iso_tree_node_get_uid(node)); @@ -2337,13 +2283,13 @@ int Xorriso_mkdir(struct XorrisO *xorriso, char *path, int flag) /* @param flag bit0= count results rather than storing them bit1= this is a recursion - bit2= prepend / + bit2= prepend wd (automatically done if wd[0]!=0) */ int Xorriso_obtain_pattern_files( struct XorrisO *xorriso, char *wd, struct iso_tree_node_dir *dir, int *filec, char **filev, int count_limit, off_t *mem, int flag) { - int i, ret, failed_at, l; + int ret, failed_at, l; struct iso_tree_iter *iter= NULL; struct iso_tree_node *node; char adr[SfileadrL], *name; @@ -2370,7 +2316,7 @@ int Xorriso_obtain_pattern_files( Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); return(-1); } - for(i= 0; (node= iso_tree_iter_next(iter)) != NULL; ) { + while((node= iso_tree_iter_next(iter)) != NULL) { name= (char *) iso_tree_node_get_name(node); if(wd[0]!=0 || (flag&4)) { if(strlen(wd)+1>=SfileadrL) @@ -2465,21 +2411,11 @@ int Xorriso_expand_pattern(struct XorrisO *xorriso, } for(i= 0; iinfo_text, - "Cannot compile pattern to regular expression: %s", patterns[i]); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - - if(patterns[i][0]=='/' || abs_adr) { dir= root_dir; abs_adr= 4; @@ -2578,13 +2514,12 @@ no_memory:; /* now store addresses */ for(i= 0; i