diff --git a/test/xorriso.1 b/test/xorriso.1 index d4cefcb8..c0b35450 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 26, 2007" +.TH XORRISO 1 "December 30, 2007" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -975,17 +975,41 @@ 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 iso_rr_path [-name pattern] +\fB\-find\fR iso_rr_path [-name pattern] [-exec action [params]] -- A very restricted substitute for shell command find in the ISO image. -It prints the paths of matching file objects at or below iso_rr_path. +It performs an action on matching file objects at or below 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. +.br +If a file matches then the action is performed. Default action is "echo", +i.e. to print the address of the found file. Other actions are certain +xorriso commands which get performed on the found files. These commands +may have specific parameters. See also their particular descriptions. +.br +"chown" changes the ownership and gets the user id as param. +.br +"chgrp" changes the group attribute and gets the group id as param. +.br +"chmod" changes access permissions and gets a mode string as param. +Like: a-w,a+r +.br +"alter_date" changes the timestamps. +It gets a type character and a timestring as params. +Like: "m" "Dec 30 19:34:12 2007" +.br +"lsdl" prints file information like shell command ls -dl. It gets no params. +.br +If not used as last command in the line then the argument list +needs to get terminated by "--". .TP -\fB\-findx\fR disk_path [-name pattern] +\fB\-findx\fR disk_path [-name pattern] -- Like -find but operating on local filesystem and not on the ISO image. This action is subject to the settings of -follow. +.br +-findx accepts the -exec actions as does -find. But it will +always perform action "echo". .TP .B Scripting, dialog and program control features: .TP diff --git a/test/xorriso.c b/test/xorriso.c index cbad0cfa..da0f00ed 100644 --- a/test/xorriso.c +++ b/test/xorriso.c @@ -2450,6 +2450,24 @@ struct FindjoB { regmatch_t name_match; #endif + /* 0= echo + 1= rm + 2= rm_r + 3= mv target + 4= chown user + 5= chgrp group + 6= chmod mode + 7= alter_date type date + 8= lsdl + */ + int action; + char *target; + uid_t user; + gid_t group; + mode_t mode_and, mode_or; + int type; /* see Xorriso_set_time flag */ + time_t date; + }; int Findjob_destroy(struct FindjoB **job, int flag); @@ -2462,7 +2480,14 @@ int Findjob_new(struct FindjoB **o, char *start_path, int flag) m= *o= TSOB_FELD(struct FindjoB,1); if(m==NULL) return(-1); + m->start_path= NULL; m->name_expr= NULL; + m->action= 0; /* print */ + m->target= NULL; /* a mere pointer, not managed memory */ + m->user= 0; + m->group= 0; + m->type= 0; + m->date= 0; m->start_path= strdup(start_path); if(m->start_path==NULL) goto failed; @@ -2541,6 +2566,74 @@ int Findjob_test(struct FindjoB *o, char *name, } +int Findjob_get_action(struct FindjoB *o, int flag) +{ + return(o->action); +} + + +/* @return <0 error, >=0 see above struct FindjoB.action +*/ +int Findjob_get_action_parms(struct FindjoB *o, char **target, + uid_t *user, gid_t *group, + mode_t *mode_and, mode_t *mode_or, + int *type, time_t *date, int flag) +{ + *target= o->target; + *user= o->user; + *group= o->group; + *mode_and= o->mode_and; + *mode_or= o->mode_or; + *type= o->type; + *date= o->date; + return(o->action); +} + + +int Findjob_set_action_target(struct FindjoB *o, int action, char *target, + int flag) +{ + o->action= action; + o->target= target; + return(1); +} + + +int Findjob_set_action_chown(struct FindjoB *o, uid_t user,int flag) +{ + o->action= 4; + o->user= user; + return(1); +} + + +int Findjob_set_action_chgrp(struct FindjoB *o, gid_t group, int flag) +{ + o->action= 5; + o->group= group; + return(1); +} + + +int Findjob_set_action_chmod(struct FindjoB *o, + mode_t mode_and, mode_t mode_or, int flag) +{ + o->action= 6; + o->mode_and= mode_and; + o->mode_or= mode_or; + return(1); +} + + +int Findjob_set_action_ad(struct FindjoB *o, int type, time_t date, int flag) +{ + o->action= 7; + o->type= type; + o->date= date; + return(1); +} + + /* ------------------------------- Xorriso -------------------------------- */ /** The list of startup file names */ @@ -4695,6 +4788,136 @@ int Xorriso_convert_gidstring(struct XorrisO *xorriso, char *gid_string, } +int Xorriso_convert_modstring(struct XorrisO *xorriso, char *cmd, char *mode, + mode_t *mode_and, mode_t *mode_or, int flag) +{ + int who_val= 0; + char sfe[5*SfileadrL], *mpt, *vpt, *opt; + unsigned int num= 0; + mode_t mode_val,mask; + + *mode_and= ~1; + *mode_or= 0; + if(mode[0]=='0') { + *mode_and= 0; + sscanf(mode,"%o",&num); + *mode_or= num; + } else if(strchr(mode,'+')!=NULL || strchr(mode,'-')!=NULL + || strchr(mode,'=')!=NULL) { + /* [ugoa][+-][rwxst] */; + for(mpt= mode; mpt!=NULL; mpt= strchr(mpt, ',')) { + if(*mpt==',') + mpt++; + if(strlen(mpt)<3) + goto unrecognizable; + who_val= 0; + for(vpt= mpt; *vpt!='+' && *vpt!='-' && *vpt!='='; vpt++) { + if(*vpt=='u') + who_val|= 4; + else if(*vpt=='g') + who_val|= 2; + else if(*vpt=='o') + who_val|= 1; + else if(*vpt=='a') + who_val|= 7; + else + goto unrecognizable; + } + opt= vpt; + mode_val= 0; + for(vpt= opt+1; *vpt!=0 && *vpt!=','; vpt++) { + if(*vpt=='r') { + if(who_val&4) + mode_val|= S_IRUSR; + if(who_val&2) + mode_val|= S_IRGRP; + if(who_val&1) + mode_val|= S_IROTH; + } else if(*vpt=='w') { + if(who_val&4) + mode_val|= S_IWUSR; + if(who_val&2) + mode_val|= S_IWGRP; + if(who_val&1) + mode_val|= S_IWOTH; + } else if(*vpt=='x') { + if(who_val&4) + mode_val|= S_IXUSR; + if(who_val&2) + mode_val|= S_IXGRP; + if(who_val&1) + mode_val|= S_IXOTH; + } else if(*vpt=='s') { + if(who_val&4) + mode_val|= S_ISUID; + if(who_val&2) + mode_val|= S_ISGID; + } else if(*vpt=='t') { + if(who_val&1) + mode_val|= S_ISVTX; + } else + goto unrecognizable; + } + if(*opt=='+') { + (*mode_or)|= mode_val; + } else if(*opt=='=') { + mask= 0; + if(who_val&1) + mask|= S_IRWXO|S_ISVTX; + if(who_val&2) + mask|= S_IRWXG|S_ISGID; + if(who_val&4) + mask|= S_IRWXU|S_ISUID; + (*mode_and)&= ~(mask); + (*mode_or)= ((*mode_or) & ~mask) | mode_val; + } else if(*opt=='-') { + (*mode_or)&= ~mode_val; + (*mode_and)&= ~mode_val; + } + } + } else { +unrecognizable:; + sprintf(xorriso->info_text, + "%s: Unrecognizable or faulty permission mode %s\n", cmd, + Text_shellsafe(mode, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + return(1); +} + + +int Xorriso_convert_datestring(struct XorrisO *xorriso, char *cmd, + char *time_type, char *timestring, + int *t_type, time_t *t, int flag) +{ + int ret; + + if(strcmp(time_type, "a")==0) + (*t_type)|= 1; + else if(strcmp(time_type, "m")==0) + (*t_type)|= 4; + else if(strcmp(time_type, "b")==0) + (*t_type)|= 5; + else { + sprintf(xorriso->info_text, "%s: Unrecognized type '%s'", cmd, time_type); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + ret= Decode_timestring(timestring, t, 0); + if(ret<=0) { + sprintf(xorriso->info_text, "%s: Cannot decode timestring '%s'", cmd, + timestring); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + sprintf(xorriso->info_text, "Understanding timestring '%s' as: %s", + timestring, ctime(t)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + return(1); +} + + /* @param flag bit0=path is in source filesystem , bit1= unconditionally */ int Xorriso_much_too_long(struct XorrisO *xorriso, int len, int flag) { @@ -4708,6 +4931,7 @@ int Xorriso_much_too_long(struct XorrisO *xorriso, int len, int flag) 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) @@ -5638,6 +5862,8 @@ int Xorriso_option_alter_date(struct XorrisO *xorriso, int optc= 0; char **optv= NULL; +#ifdef NIX + if(strcmp(time_type, "a")==0) t_type|= 1; else if(strcmp(time_type, "m")==0) @@ -5661,6 +5887,15 @@ int Xorriso_option_alter_date(struct XorrisO *xorriso, timestring, ctime(&t)); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); +#else /* NIX */ + + ret= Xorriso_convert_datestring(xorriso, "-alter_date", time_type, timestring, + &t_type, &t, 0); + if(ret<=0) + goto ex; + +#endif /* ! NIX */ + ret= Xorriso_opt_args(xorriso, argc, argv, *idx, &end_idx, &optc, &optv, 0); if(ret<=0) goto ex; @@ -5911,13 +6146,19 @@ ex:; int Xorriso_option_chmodi(struct XorrisO *xorriso, char *mode, int argc, char **argv, int *idx, int flag) { - int i, ret, who_val= 0, was_failure= 0, end_idx, fret; - unsigned int num; - mode_t mode_and= ~0, mode_or= 0, mode_val, mask; - char sfe[5*SfileadrL], *mpt, *opt, *vpt; + int i, ret, was_failure= 0, end_idx, fret; + mode_t mode_and= ~0, mode_or= 0; int optc= 0; char **optv= NULL; +#ifdef NIX + + char sfe[5*SfileadrL], *mpt, *opt, *vpt; + unsigned int num; + int who_val= 0; + mode_t mode_val, mask; + + if(mode[0]=='0') { mode_and= 0; sscanf(mode,"%o",&num); @@ -6004,6 +6245,15 @@ unrecognizable:; ret= 0; goto ex; } +#else /* NIX */ + + ret= Xorriso_convert_modstring(xorriso, "-chmodi", + mode, &mode_and, &mode_or, 0); + if(ret<=0) + goto ex; + +#endif /* ! NIX */ + ret= Xorriso_opt_args(xorriso, argc, argv, *idx, &end_idx, &optc, &optv, 0); if(ret<=0) goto ex; @@ -6435,10 +6685,14 @@ sorry_ex: int Xorriso_option_find(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag) { - int ret, i, end_idx; + int ret, i, end_idx, type= 0; struct FindjoB *job= NULL; - char *start_path, sfe[5*SfileadrL]; + char *start_path, sfe[5*SfileadrL], *cpt; struct stat dir_stbuf; + uid_t user= 0; + gid_t group= 0; + time_t date= 0; + mode_t mode_or= 0, mode_and= ~1; end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); start_path= "."; @@ -6453,6 +6707,13 @@ int Xorriso_option_find(struct XorrisO *xorriso, int argc, char **argv, for(i= *idx+1; i=end_idx) { +not_enough_arguments:; + sprintf(xorriso->info_text, + "-find[ix]: not enough arguments with -exec %s", + Text_shellsafe(argv[i], sfe, 0)); + goto sorry_ex; + } i++; ret= Findjob_set_name_expr(job, argv[i], 0); if(ret<=0) { @@ -6460,6 +6721,70 @@ int Xorriso_option_find(struct XorrisO *xorriso, int argc, char **argv, Text_shellsafe(argv[i], sfe, 0)); goto sorry_ex; } + } else if(strcmp(argv[i], "-exec")==0) { + if(i+1>=end_idx) + goto not_enough_arguments; + i++; + cpt= argv[i]; + if(*cpt=='-') + cpt++; + if(strcmp(cpt, "echo")==0) { + Findjob_set_action_target(job, 0, NULL, 0); + +#ifdef NIX +/* >>> not implemented yet */; + } else if(strcmp(cpt, "rm")==0) { + Findjob_set_action_target(job, 1, NULL, 0); + } else if(strcmp(cpt, "rm_r")==0) { + Findjob_set_action_target(job, 2, NULL, 0); + } else if(strcmp(cpt, "mv")==0) { + if(i+1>=end_idx) + goto not_enough_arguments; + i++; + Findjob_set_action_target(job, 3, argv[i], 0); +#endif + + } else if(strcmp(cpt, "chown")==0) { + if(i+1>=end_idx) + goto not_enough_arguments; + i++; + ret= Xorriso_convert_uidstring(xorriso, argv[i], &user, 0); + if(ret<=0) + goto ex; + Findjob_set_action_chown(job, user, 0); + } else if(strcmp(cpt, "chgrp")==0) { + if(i+1>=end_idx) + goto not_enough_arguments; + i++; + ret= Xorriso_convert_gidstring(xorriso, argv[i], &group, 0); + if(ret<=0) + goto ex; + Findjob_set_action_chgrp(job, group, 0); + } else if(strcmp(cpt, "chmod")==0) { + if(i+1>=end_idx) + goto not_enough_arguments; + i++; + ret= Xorriso_convert_modstring(xorriso, "-find -exec chmod", + argv[i], &mode_and, &mode_or,0); + if(ret<=0) + goto ex; + Findjob_set_action_chmod(job, mode_and, mode_or, 0); + } else if(strcmp(cpt, "alter_date")==0) { + if(i+2>=end_idx) + goto not_enough_arguments; + i+= 2; + ret= Xorriso_convert_datestring(xorriso, "-find -exec alter_date", + argv[i-1], argv[i], &type, &date, 0); + if(ret<=0) + goto ex; + Findjob_set_action_ad(job, type, date, 0); + } else if(strcmp(cpt, "lsdl")==0) { + Findjob_set_action_target(job, 8, NULL, 0); + } else { + sprintf(xorriso->info_text, "-find -exec: unknown action %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)); diff --git a/test/xorriso.h b/test/xorriso.h index 3f293512..7a5744be 100644 --- a/test/xorriso.h +++ b/test/xorriso.h @@ -56,7 +56,7 @@ int Xorriso_msgs_submit(struct XorrisO *xorriso, and then it uses this status and the submitted return value ot the option function to evaluate the situation. @param xorriso The environment handle - @param ret The return value of the prviously called option function + @param ret The return value of the previously called option function @param flag bit0= do not issue own event messages bit1= take xorriso->request_to_abort as reason for abort @return Gives the advice: diff --git a/test/xorriso_private.h b/test/xorriso_private.h index be9f064d..0666534d 100644 --- a/test/xorriso_private.h +++ b/test/xorriso_private.h @@ -301,6 +301,18 @@ int Findjob_test(struct FindjoB *job, char *name, struct stat *boss_stbuf, struct stat *stbuf, int depth, int flag); +/* @return <0 error, >=0 see xorriso.c struct FindjoB.action +*/ +int Findjob_get_action(struct FindjoB *o, int flag); + +/* @return <0 error, >=0 see xorriso.c struct FindjoB.action +*/ +int Findjob_get_action_parms(struct FindjoB *o, char **target, + uid_t *user, gid_t *group, + mode_t *mode_and, mode_t *mode_or, + int *type, time_t *date, int flag); + + #endif /* Xorriso_private_includeD */ diff --git a/test/xorriso_timestamp.h b/test/xorriso_timestamp.h index 248528bd..2dcf1499 100644 --- a/test/xorriso_timestamp.h +++ b/test/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2007.12.28.132741" +#define Xorriso_timestamP "2007.12.30.190138" diff --git a/test/xorrisoburn.c b/test/xorrisoburn.c index a0e37453..cc561787 100644 --- a/test/xorrisoburn.c +++ b/test/xorrisoburn.c @@ -2818,31 +2818,80 @@ int Xorriso_set_time(struct XorrisO *xorriso, char *in_path, time_t t, } +int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, + char *abs_path, char *show_path, + struct iso_tree_node *node, int flag) +{ + int ret, type, action= 0; + uid_t user= 0; + gid_t group= 0; + time_t date= 0; + mode_t mode_or= 0, mode_and= ~1; + char *target, sfe[5*SfileadrL]; + + action= Findjob_get_action_parms(job, &target, &user, &group, + &mode_and, &mode_or, &type, &date, 0); + if(action<0) + action= 0; + + if(action==1) { + /* >>> rm */; + } else if(action==2) { + + /* >>> rm_r */; + + } else if(action==3) { + + /* >>> mv target */; + + } else if(action==4) { /* chown */ + ret= Xorriso_set_uid(xorriso, abs_path, user, 0); + } else if(action==5) { /* chgrp */ + ret= Xorriso_set_gid(xorriso, abs_path, group, 0); + } else if(action==6) { /* chmod */ + ret= Xorriso_set_st_mode(xorriso, abs_path, mode_and, mode_or, 0); + } else if(action==7) { /* alter_date */ + ret= Xorriso_set_time(xorriso, abs_path, date, type&7); + } else if(action==8) { /* lsdl */ + ret= Xorriso_ls_filev(xorriso, "", 1, &abs_path, (off_t) 0, 1|2|8); + } else { + sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0)); + Xorriso_result(xorriso, 0); + ret= 0; + } + return(ret); +} + + 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; + int ret, action= 0; 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; - #ifdef Xorriso_fat_local_meM char path[SfileadrL], sfe[5*SfileadrL]; #else /* Xorriso_fat_local_meM */ - char *path= NULL, *sfe= NULL; + char *path= NULL, *sfe= NULL, *abs_path= NULL; sfe= malloc(5*SfileadrL); path= malloc(SfileadrL); - if(sfe==NULL || path==NULL) { + abs_path= malloc(SfileadrL); + if(sfe==NULL || path==NULL || abs_path==NULL) { Xorriso_no_malloc_memory(xorriso, &sfe, 0); {ret= -1; goto ex;} } #endif /* ! Xorriso_fat_local_meM */ + action= Findjob_get_action(job, 0); + if(action<0) + action= 0; + dir_node= (struct iso_tree_node_dir *) dir_node_generic; if(dir_node==NULL) { ret= Xorriso_get_volume(xorriso, &volume, 0); @@ -2868,9 +2917,18 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, ret= Findjob_test(job, name, NULL, dir_stbuf, depth, 0); if(ret<0) goto ex; - if(ret>0) { + if(ret>0 && action==0) { + +#ifdef NIX sprintf(xorriso->result_line, "%s\n", Text_shellsafe(dir_path, sfe, 0)); Xorriso_result(xorriso, 0); +#else + ret= Xorriso_findi_action(xorriso, job, path, dir_path, + (struct iso_tree_node *) dir_node, 0); + if(ret<=0) + goto ex; +#endif /* ! NIX */ + } } if(!LIBISO_ISDIR((struct iso_tree_node *) dir_node)) @@ -2898,8 +2956,21 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, if(ret<0) goto ex; if(ret>0) { + +#ifdef NIX sprintf(xorriso->result_line, "%s\n", Text_shellsafe(path, sfe, 0)); Xorriso_result(xorriso, 0); +#else + ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, path, abs_path, 1|4); + if(ret<=0) + goto ex; + ret= Xorriso_findi_action(xorriso, job, abs_path, path, node, 0); + if(ret<=0) { + if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0) + goto ex; + } +#endif /* ! NIX */ + } if(S_ISDIR(stbuf.st_mode)) { @@ -2918,6 +2989,8 @@ ex:; free(sfe); if(path!=NULL) free(path); + if(abs_path!=NULL) + free(abs_path); #endif /* ! Xorriso_fat_local_meM */ Xorriso_process_msg_queues(xorriso,0);