From dae40ca9fa8078c987e08d5f0dcc418451868d23 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Fri, 21 Dec 2007 13:16:49 +0000 Subject: [PATCH] Implemented option -find alias -findi --- test/xorriso.1 | 13 +++- test/xorriso.c | 164 +++++++++++++++++++++++++++++++++++---- test/xorriso.h | 3 +- test/xorriso_private.h | 20 ++++- test/xorriso_timestamp.h | 2 +- test/xorrisoburn.c | 94 +++++++++++++++++++++- test/xorrisoburn.h | 6 ++ 7 files changed, 274 insertions(+), 28 deletions(-) diff --git a/test/xorriso.1 b/test/xorriso.1 index 1b9a9448..ebce880a 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 "December 19, 2007" +.TH XORRISO 1 "December 21, 2007" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -968,11 +968,16 @@ 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. +\fB\-find\fR iso_rr_path [-name pattern] +A very restricted sunstitute for to shell command find in the ISO image. +It prints the paths of matchin file objects beginning with iso_rr_path. +.br +Optional -name pattern is not expanded but used for comparison with +the particular file names of the eventual directory tree underneath +iso_rr_path. If no -name pattern is given, then any file name matches. .TP > \fB\-findx\fR pattern -Equivalent to shell command find . -name pattern on filesystem. +Like -find but operating on loacl filesystem and not on ISO image. .TP .B Scripting, dialog and program control features: .TP diff --git a/test/xorriso.c b/test/xorriso.c index be249d1a..1ca95e34 100644 --- a/test/xorriso.c +++ b/test/xorriso.c @@ -2417,6 +2417,109 @@ int Linkitem_find(struct LinkiteM *stack, dev_t target_dev, ino_t target_ino, } +/* ------------------------------- FindjoB -------------------------------- */ + + +struct FindjoB { + char *start_path; + + char *name_expr; +#ifdef Xorriso_with_regeX + regex_t name_re; + regmatch_t name_match; +#endif + +}; + +int Findjob_destroy(struct FindjoB **job, int flag); + + +int Findjob_new(struct FindjoB **o, char *start_path, int flag) +{ + struct FindjoB *m; + + m= *o= TSOB_FELD(struct FindjoB,1); + if(m==NULL) + return(-1); + m->name_expr= NULL; + m->start_path= strdup(start_path); + if(m->start_path==NULL) + goto failed; + return(1); +failed:; + Findjob_destroy(o, 0); + return(-1); +} + + +int Findjob_destroy(struct FindjoB **o, int flag) +{ + struct FindjoB *m; + + m= *o; + if(m==NULL) + return(0); + if(m->start_path!=NULL) + free(m->start_path); + if(m->name_expr!=NULL) { +#ifdef Xorriso_with_regeX + regfree(&(m->name_re)); +#endif + free(m->name_expr); + } + free((char *) m); + *o= NULL; + return(1); +} + + +int Findjob_set_name_expr(struct FindjoB *o, char *name_expr, int flag) +{ + char regexpr[2*SfileadrL+2]; + + if(o->name_expr!=NULL) { +#ifdef Xorriso_with_regeX + regfree(&(o->name_re)); +#endif + free(o->name_expr); + o->name_expr= NULL; + } + if(strlen(name_expr)>=SfileadrL) + return(0); + o->name_expr= strdup(name_expr); + if(o->name_expr==NULL) + return(-1); + Xorriso__bourne_to_reg(name_expr, regexpr, 0); + if(regcomp(&(o->name_re), regexpr, 0)!=0) + return(0); + return(1); +} + + +/* @return 0=no match , 1=match , <0 = error +*/ +int Findjob_test(struct FindjoB *o, char *name, + struct stat *boss_stbuf, struct stat *stbuf, + int depth, int flag) +{ + int ret; + + if(o->name_expr!=NULL) { +#ifdef Xorriso_with_regeX + ret= regexec(&(o->name_re),name,1,&(o->name_match),0); +#else + ret= !(strcmp(name, o->name_expr)==0 || strcmp(o->name_expr, "*")==0); +#endif + if(ret!=0) + return(0); + } + + /* ??? >>> more tests to come ?*/; + + return(1); +} + + /* ------------------------------- Xorriso -------------------------------- */ /** The list of startup file names */ @@ -3260,6 +3363,8 @@ cannot_compile:; } +/* @return 0=match , else no match +*/ int Xorriso_regexec(struct XorrisO *xorriso, char *to_match, int *failed_at, int flag) /* @@ -3860,7 +3965,7 @@ int Xorriso_check_for_root_pattern(struct XorrisO *xorriso, /* @param flag bit0= prepend wd only if name does not begin by '/' bit2= prepend wd (automatically done if wd[0]!=0) */ -int Xorriso_make_pattern_adr(struct XorrisO *xorriso, char *wd, char *name, +int Xorriso_make_abs_adr(struct XorrisO *xorriso, char *wd, char *name, char adr[], int flag) { if((wd[0]!=0 || (flag&4)) && !((flag&1) && name[0]=='/')) { @@ -3972,7 +4077,7 @@ int Xorriso_obtain_pattern_files_x( {ret= -1; goto ex;} } - ret= Xorriso_make_pattern_adr(xorriso, wd, name, adr, flag&4); + ret= Xorriso_make_abs_adr(xorriso, wd, name, adr, flag&4); if(ret<=0) goto ex; @@ -3983,7 +4088,7 @@ int Xorriso_obtain_pattern_files_x( path= adr; if(adr[0]!='/') { path= path_data; - ret= Xorriso_make_pattern_adr(xorriso, xorriso->wdx, adr, path, 1|4); + ret= Xorriso_make_abs_adr(xorriso, xorriso->wdx, adr, path, 1|4); if(ret<=0) goto ex; } @@ -5059,7 +5164,7 @@ int Xorriso_lsx_filev(struct XorrisO *xorriso, char *wd, /* Count valid nodes, warn of invalid ones */ for(i= 0; irequest_to_abort); i++) { - ret= Xorriso_make_pattern_adr(xorriso, wd, filev[i], path, 1|4); + ret= Xorriso_make_abs_adr(xorriso, wd, filev[i], path, 1|4); if(ret<=0) continue; ret= lstat(path, &stbuf); @@ -6036,17 +6141,47 @@ sorry_ex: /* Option -find alias -findi */ -int Xorriso_option_findi(struct XorrisO *xorriso, char *pattern, int flag) +int Xorriso_option_findi(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) { - char sfe[5*SfileadrL]; + int ret, i, end_idx; + struct FindjoB *job= NULL; + char *start_path, sfe[5*SfileadrL]; + struct stat dir_stbuf; - fprintf(stderr, ">>> XORRISO : filter by pattern %s\n", pattern); - /* >>> prepare regex */ + end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); + start_path= xorriso->wdi; + if(end_idx > *idx) + start_path= argv[*idx]; + ret= Findjob_new(&job, start_path, 0); + if(ret<=0) { + sprintf(xorriso->info_text, "-find[ix]: cannot set create find job object"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + {ret= -1; goto ex;} + } - fprintf(stderr, ">>> LIBISOFS : traverse ISO tree beginning at %s\n", - Text_shellsafe(xorriso->wdi, sfe, 0)); - - return(1); + for(i= *idx+1; iinfo_text, "-find[ix]: cannot set -name expression %s", + Text_shellsafe(argv[i], sfe, 0)); + goto sorry_ex; + } + } else { + sprintf(xorriso->info_text, "-find[ix]: unknown option %s", + Text_shellsafe(argv[i], sfe, 0)); +sorry_ex:; + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + {ret= 0; goto ex;} + } + } + ret= Xorriso_findi(xorriso, job, NULL, start_path, &dir_stbuf, 0, 0); +ex:; + Findjob_destroy(&job, 0); + (*idx)= end_idx; + return(ret); } @@ -7486,8 +7621,7 @@ next_command:; ret= Xorriso_option_follow(xorriso, arg1, 0); } else if(strcmp(cmd,"find")==0 || strcmp(cmd,"findi")==0) { - (*idx)++; - ret= Xorriso_option_findi(xorriso, arg1, 0); + ret= Xorriso_option_findi(xorriso, argc, argv, idx, 0); } else if(strcmp(cmd,"findx")==0) { (*idx)++; diff --git a/test/xorriso.h b/test/xorriso.h index 5a862774..6843bb7e 100644 --- a/test/xorriso.h +++ b/test/xorriso.h @@ -205,7 +205,8 @@ int Xorriso_option_iso_rr_pattern(struct XorrisO *xorriso, char *mode, int Xorriso_option_follow(struct XorrisO *xorriso, char *mode, int flag); /* Option -find alias -findi */ -int Xorriso_option_findi(struct XorrisO *xorriso, char *pattern, int flag); +int Xorriso_option_findi(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag); /* Option -findx */ int Xorriso_option_findx(struct XorrisO *xorriso, char *pattern, int flag); diff --git a/test/xorriso_private.h b/test/xorriso_private.h index fd4d9e14..bb6077d6 100644 --- a/test/xorriso_private.h +++ b/test/xorriso_private.h @@ -199,6 +199,8 @@ int Xorriso_prescan_args(struct XorrisO *xorriso, int argc, char **argv, int Xorriso_execute_option(struct XorrisO *xorriso, char *line, int flag); +/* @return 0=match , else no match +*/ int Xorriso_regexec(struct XorrisO *xorriso, char *to_match, int *failed_at, int flag); @@ -232,9 +234,10 @@ int Xorriso_alloc_pattern_mem(struct XorrisO *xorriso, off_t mem, int Xorriso_check_for_root_pattern(struct XorrisO *xorriso, int *filec, char **filev, int count_limit, off_t *mem, int flag); -/* @param flag bit2= prepend wd (automatically done if wd[0]!=0) +/* @param flag bit0= prepend wd only if name does not begin by '/' + bit2= prepend wd (automatically done if wd[0]!=0) */ -int Xorriso_make_pattern_adr(struct XorrisO *xorriso, char *wd, char *name, +int Xorriso_make_abs_adr(struct XorrisO *xorriso, char *wd, char *name, char adr[], int flag); /* @param flag bit0= count result rather than storing it @@ -256,6 +259,9 @@ int Xorriso_resolve_link(struct XorrisO *xorriso, int Xorriso_hop_link(struct XorrisO *xorriso, char *link_path, struct LinkiteM **link_stack, struct stat *stbuf, int flag); +/* reg_expr should be twice as large as bourne_expr ( + 2 to be exact) */ +/* return: 2= bourne_expr is surely a constant */ +int Xorriso__bourne_to_reg(char bourne_expr[], char reg_expr[], int flag); int Sfile_str(char target[SfileadrL], char *source, int flag); @@ -281,9 +287,17 @@ int Dirseq_destroy(struct DirseQ **o, int flag); int Dirseq_next_adr(struct DirseQ *o, char reply[SfileadrL], int flag); - int Linkitem_reset_stack(struct LinkiteM **o, struct LinkiteM *to, int flag); +struct FindjoB; + +/* @return 0=no match , 1=match , <0 = error +*/ +int Findjob_test(struct FindjoB *job, char *name, + struct stat *boss_stbuf, struct stat *stbuf, + int depth, int flag); + + #endif /* Xorriso_private_includeD */ diff --git a/test/xorriso_timestamp.h b/test/xorriso_timestamp.h index f2ffc197..6ed5a5ba 100644 --- a/test/xorriso_timestamp.h +++ b/test/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2007.12.20.111338" +#define Xorriso_timestamP "2007.12.21.131538" diff --git a/test/xorrisoburn.c b/test/xorrisoburn.c index 464e3692..98b6579d 100644 --- a/test/xorrisoburn.c +++ b/test/xorrisoburn.c @@ -1951,11 +1951,11 @@ int Xorriso_fake_stbuf(struct XorrisO *xorriso, char *path, struct stat *stbuf, int ret; struct iso_volume *volume; + memset((char *) stbuf, 0, sizeof(struct stat)); if(!(flag&1)) { ret= Xorriso_get_volume(xorriso, &volume, 0); if(ret<=0) return(-1); - memset((char *) stbuf, 0, sizeof(struct stat)); *node= iso_tree_volume_path_to_node(volume,path); } if(*node==NULL) @@ -2081,7 +2081,7 @@ int Xorriso_ls_filev(struct XorrisO *xorriso, char *wd, /* Count valid nodes, warn of invalid ones */ for(i= 0; irequest_to_abort); i++) { rpt[0]= 0; - ret= Xorriso_make_pattern_adr(xorriso, wd, filev[i], path, 1|4); + ret= Xorriso_make_abs_adr(xorriso, wd, filev[i], path, 1|4); if(ret<=0) continue; ret= Xorriso_fake_stbuf(xorriso, path, &stbuf, &node, 0); @@ -2481,7 +2481,7 @@ int Xorriso_obtain_pattern_files_i( } while((node= iso_tree_iter_next(iter)) != NULL) { name= (char *) iso_tree_node_get_name(node); - ret= Xorriso_make_pattern_adr(xorriso, wd, name, adr, flag&4); + ret= Xorriso_make_abs_adr(xorriso, wd, name, adr, flag&4); if(ret<=0) goto ex; ret= Xorriso_regexec(xorriso, adr, &failed_at, 1); @@ -2714,3 +2714,89 @@ int Xorriso_set_time(struct XorrisO *xorriso, char *in_path, time_t t, } +int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, + void *dir_node_generic, char *dir_path, + struct stat *dir_stbuf, int depth, int flag) +{ + int ret; + struct iso_tree_iter *iter= NULL; + struct iso_tree_node_dir *dir_node; + struct iso_tree_node *node; + struct iso_volume *volume; + struct stat stbuf; + char *name, path[SfileadrL], sfe[5*SfileadrL]; + + dir_node= (struct iso_tree_node_dir *) dir_node_generic; + if(dir_node==NULL) { + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + {ret= -1; goto ex;} + ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, dir_path, path, 1); + if(ret<=0) + goto ex; + dir_node= (struct iso_tree_node_dir *) + iso_tree_volume_path_to_node(volume, path); + if(dir_node==NULL) + {ret= 0; goto ex;} + ret= Xorriso_fake_stbuf(xorriso, "", dir_stbuf, + (struct iso_tree_node **) &dir_node, 1); + if(ret<0) + goto ex; + + name= strrchr(dir_path, '/'); + if(name==NULL) + name= dir_path; + else + name++; + ret= Findjob_test(job, name, NULL, dir_stbuf, depth, 0); + if(ret<0) + goto ex; + if(ret>0) { + sprintf(xorriso->result_line, "%s\n", Text_shellsafe(dir_path, sfe, 0)); + Xorriso_result(xorriso, 0); + } + } + if(!LIBISO_ISDIR((struct iso_tree_node *) dir_node)) + {ret= 2; goto ex;} + + iter= iso_tree_node_children(dir_node); + if(iter==NULL) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, "Cannot obtain ISO directory iterator"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + {ret= -1; goto ex;} + } + while((node= iso_tree_iter_next(iter)) != NULL && !xorriso->request_to_abort){ + name= (char *) iso_tree_node_get_name(node); + ret= Xorriso_make_abs_adr(xorriso, dir_path, name, path, 4); + if(ret<=0) + goto ex; + ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1); + if(ret<0) + goto ex; + if(ret==0) + continue; + + ret= Findjob_test(job, name, dir_stbuf, &stbuf, depth, 0); + if(ret<0) + goto ex; + if(ret>0) { + sprintf(xorriso->result_line, "%s\n", Text_shellsafe(path, sfe, 0)); + Xorriso_result(xorriso, 0); + } + + if(S_ISDIR(stbuf.st_mode)) { + ret= Xorriso_findi(xorriso, job, (void *) node, path, + &stbuf, depth+1, flag); + if(ret<0) + goto ex; + } + } + + ret= 1; +ex:; + if(iter!=NULL) + iso_tree_iter_free(iter); + return(ret); +} + diff --git a/test/xorrisoburn.h b/test/xorrisoburn.h index d5d48bd9..57442f0a 100644 --- a/test/xorrisoburn.h +++ b/test/xorrisoburn.h @@ -15,6 +15,7 @@ #define Xorrisoburn_includeD yes struct XorrisO; +struct FindjoB; int Xorriso_startup_libraries(struct XorrisO *xorriso, int flag); @@ -122,5 +123,10 @@ int Xorriso_set_gid(struct XorrisO *xorriso, char *in_path, gid_t gid, int Xorriso_set_time(struct XorrisO *xorriso, char *in_path, time_t t, int flag); +int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, + void *dir_node_generic, char *dir_path, + struct stat *dir_stbuf, int depth, int flag); + + #endif /* Xorrisoburn_includeD */