From 11d712622e1bac12e195c14c1ef469ce0c89d0e3 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Thu, 1 Nov 2007 19:11:56 +0000 Subject: [PATCH] Implemented option -du --- test/xorriso.1 | 8 ++ test/xorriso.c | 79 +++++++---- test/xorriso.h | 8 +- test/xorriso_timestamp.h | 2 +- test/xorrisoburn.c | 289 ++++++++++++++++++++++++++++++--------- test/xorrisoburn.h | 4 +- 6 files changed, 288 insertions(+), 102 deletions(-) diff --git a/test/xorriso.1 b/test/xorriso.1 index ea3fc281..8d9ab1b4 100644 --- a/test/xorriso.1 +++ b/test/xorriso.1 @@ -568,6 +568,14 @@ Output format resembles shell command ls -ldn. > \fB\-ls_lx\fR 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, +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. +.TP > \fB\-find\fR pattern Equivalent to shell command find . -name pattern in the ISO image. .TP diff --git a/test/xorriso.c b/test/xorriso.c index 16417760..3c9cafef 100644 --- a/test/xorriso.c +++ b/test/xorriso.c @@ -3780,14 +3780,16 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) "images with Rock Ridge extensions. Write targets can be drives with optical", "media or local filesystem objects.", "", +"Note: Options marked by prefix \"> \" are not implemented yet.", +"", "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", +"> -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.", @@ -3795,7 +3797,7 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " Blank media resp. invalidate ISO image on media.", " -format \"full\"", " Format DVD-RW to overwriteable state or de-ice DVD+RW.", -" -V volume_id Specifies the volume ID text.", +"> -V volume_id Specifies the volume ID text.", "", " -J Generate Joliet info additional to Rock Ridge info.", "", @@ -3826,7 +3828,7 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " 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", +"> -cp_r disk_path [...] iso_rr_path", " Insert the given files or directory trees from filesystem", " into the ISO image.", " -rm iso_rr_path [...]", @@ -3836,27 +3838,27 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " -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 [...]", +"> -chown uid iso_rr_path [...]", " Equivalent to chown in the ISO image.", -" -chgrp gid iso_rr_path [...]", +"> -chgrp gid iso_rr_path [...]", " Equivalent to chgrp in the ISO image.", -" -chmod mode iso_rr_path [...]", +"> -chmod mode iso_rr_path [...]", " Equivalent to chmod in the ISO image.", -" -alter_date type timestring iso_rr_path [...]", +"> -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 [...]", +"> -rmdir iso_rr_path [...]", " Delete empty directories.", " -- Mark end of particular action argument list.", "", -" -f Follow symbolic links within disk_path.", +"> -f Follow symbolic links within disk_path.", "", -" -overwrite \"on\"|\"off\"", +"> -overwrite \"on\"|\"off\"", " Allow or disallow to overwrite existing files in ISO image.", -" -reassure \"on\"|\"off\"", +"> -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.", "", @@ -3894,20 +3896,27 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " -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 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", +" 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_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", +" -du pattern [...] recursively lists sizes of files or directories which", +" match one of the shell parser patterns.", +" -dui pattern [...] same as -du.", +" -du_s pattern [...] like -du but summing up subdirectories without", +" listing them explicitely.", +" -dui pattern [...] same as -du_s.", +"", +"> -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", +"> -findi pattern same as -find.", +"> -findx pattern lists matching files below current working directory in", " the local filesystem.", "", "General options:", @@ -4028,15 +4037,18 @@ 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) +/* Options -ls alias -lsi and -ls_l alias -ls_li + and -du alias -dui and -du_s alias -du_si + @param flag bit0= long format (-ls_l , -du) bit1= do not expand patterns but use literally + bit2= du rather than ls */ int Xorriso_option_lsi(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag) { int ret, end_idx, filec= 0, nump, i; char **filev= NULL, **patterns= NULL; + off_t mem= 0; end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); @@ -4067,15 +4079,16 @@ no_memory:; } } if(flag&2) { - ret= Xorriso_ls_filev(xorriso, nump, argv + (*idx), flag&1); - } else if(nump==1 && strcmp(patterns[0],"*")==0){ + ret= Xorriso_ls_filev(xorriso, nump, argv + (*idx), mem, flag&1); + } else if(nump==1 && strcmp(patterns[0],"*")==0 && !(flag&4)){ /* save temporary memory by calling simpler function */ ret= Xorriso_ls(xorriso, (flag&1)|4); } else { - ret= Xorriso_expand_pattern(xorriso, nump, patterns, &filec, &filev, 0); + ret= Xorriso_expand_pattern(xorriso, nump, patterns, &filec, &filev, + &mem, 0); if(ret<=0) {ret= 0; goto ex;} - ret= Xorriso_ls_filev(xorriso, filec, filev, flag&1); + ret= Xorriso_ls_filev(xorriso, filec, filev, mem, flag&(1|4)); } if(ret<=0) {ret= 0; goto ex;} @@ -4943,6 +4956,10 @@ next_command:; (*idx)++; ret= Xorriso_option_dialog(xorriso, arg1, 0); + } else if(strcmp(cmd,"-du")==0 || strcmp(cmd,"-dui")==0 || + strcmp(cmd,"-du_s")==0 || strcmp(cmd,"-du_si")==0) { + ret= Xorriso_option_lsi(xorriso, argc, argv, idx, (strlen(cmd)<5)|4); + } else if(strcmp(cmd,"-eject")==0) { (*idx)++; ret= Xorriso_option_eject(xorriso, arg1, 0); @@ -5161,14 +5178,16 @@ next_command:; /* tis ok */; } else if(cmd[0]=='-') { +unknown_option:; sprintf(xorriso->info_text, - "=== Input line beginning with '-' is not a known option\n"); + "=== Not a known option:\n"); sprintf(xorriso->info_text+strlen(xorriso->info_text), "=== '%s'\n",cmd); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); {ret= 0; goto ex;} } else { + goto unknown_option; /* >>> ??? pathspecs for option -add */; diff --git a/test/xorriso.h b/test/xorriso.h index 1f8fde4a..675c4ec8 100644 --- a/test/xorriso.h +++ b/test/xorriso.h @@ -217,8 +217,12 @@ 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) */ +/* Options -ls alias -lsi and -ls_l alias -ls_li + and -du alias -dui and -du_s alias -du_si + @param flag bit0= long format (-ls_l , -du) + bit1= do not expand patterns but use literally + bit2= du rather than ls +*/ int Xorriso_option_lsi(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag); diff --git a/test/xorriso_timestamp.h b/test/xorriso_timestamp.h index e2fe5729..dafb0bb9 100644 --- a/test/xorriso_timestamp.h +++ b/test/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2007.11.01.111351" +#define Xorriso_timestamP "2007.11.01.191106" diff --git a/test/xorrisoburn.c b/test/xorrisoburn.c index 0bd0fb8d..a5fb74b5 100644 --- a/test/xorrisoburn.c +++ b/test/xorrisoburn.c @@ -1237,9 +1237,193 @@ int Xorriso_rmi(struct XorrisO *xorriso, char *path, int flag) } -/* @param flag bit0= long format */ +int Xorriso__node_name_cmp(const void *node1, const void *node2) +{ + char *name1, *name2; + + name1= (char *) iso_tree_node_get_name(*((struct iso_tree_node **) node1)); + name2= (char *) iso_tree_node_get_name(*((struct iso_tree_node **) node2)); + return(strcmp(name1,name2)); +} + + +/* @param flag bit0= only accept directory nodes + bit1= do not report memory usage as DEBUG + bit2= do not apply search pattern but accept any node +*/ +int Xorriso_sorted_node_array(struct XorrisO *xorriso, + struct iso_tree_node_dir *dir_node, + int *nodec, struct iso_tree_node ***node_array, + off_t boss_mem, int flag) +{ + int i, ret, failed_at; + char *npt, mem_text[80], limit_text[80]; + 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); + } + + *node_array= calloc(sizeof(struct iso_tree_node *), (*nodec)+1); + if(*node_array==NULL) { + sprintf(xorriso->info_text, + "Cannot allocate memory for %d directory entries", *nodec); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + return(-1); + } + + iter= iso_tree_node_children(dir_node); + for(i= 0; (node= iso_tree_iter_next(iter)) != NULL && i<*nodec; ) { + npt= (char *) iso_tree_node_get_name(node); + if(!(flag&4)) { + ret= Xorriso_regexec(xorriso, npt, &failed_at, 0); + if(ret) + continue; /* no match */ + } + if(flag&1) + if(!LIBISO_ISDIR(node)) + continue; + (*node_array)[i++]= node; + } + *nodec= i; + if(*nodec<=0) + return(1); + qsort(*node_array, *nodec, sizeof(struct iso_tree *), Xorriso__node_name_cmp); + return(1); +} + + +/* @param flag bit0= do not only sum up sizes but also print subdirs +*/ +int Xorriso_show_du_subs(struct XorrisO *xorriso, + struct iso_tree_node_dir *dir_node, + char *abs_path, char *rel_path, off_t *size, + off_t boss_mem, int flag) +{ + int i, ret, no_sort= 0, filec= 0, l; + struct iso_tree_iter *iter= NULL; + struct iso_tree_node *node, **node_array= NULL; + char path[SfileadrL], show_path[SfileadrL], *name, sfe[4*SfileadrL]; + off_t sub_size, report_size, mem= 0; + + *size= 0; + 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;} + } + for(i= 0; (node= iso_tree_iter_next(iter)) != NULL; ) { + sub_size= 0; + name= (char *) iso_tree_node_get_name(node); + strcpy(show_path, rel_path); + if(Sfile_add_to_path(show_path, name, 0)<=0) + goto much_too_long; + if(LIBISO_ISDIR(node)) { + strcpy(path, abs_path); + if(Sfile_add_to_path(path, name, 0)<=0) { +much_too_long:; + sprintf(xorriso->info_text, + "Path for subdirectory gets much too long (%d)", + strlen(path)+strlen(name)+1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + {ret= -1; goto ex;} + } + filec++; + mem+= strlen(rel_path)+1; + if(l % sizeof(char *)) + mem+= sizeof(char *)-(l % sizeof(char *)); + ret= Xorriso_show_du_subs(xorriso, (struct iso_tree_node_dir *) node, + path, show_path, &sub_size, boss_mem, 0); + if(ret<0) + goto ex; + if(ret==0) + continue; + } + sub_size+= iso_tree_node_get_size(node)+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;} + + /* Reset iteration */ + iso_tree_iter_free(iter); + iter= NULL; + Xorriso_process_msg_queues(xorriso,0); + + ret= Xorriso_sorted_node_array(xorriso, dir_node, &filec, &node_array, + boss_mem, 1|2|4); + if(ret<0) + goto ex; + if(ret==0) { + no_sort= 1; + iter= iso_tree_node_children(dir_node); + } + + for(i= 0; iresult_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:; + if(iter!=NULL) + iso_tree_iter_free(iter); + if(node_array!=NULL) + free((char *) node_array); + Xorriso_process_msg_queues(xorriso,0); + return(ret); +} + + +/* @param flag bit0= long format + bit2= du format +*/ int Xorriso_ls_filev(struct XorrisO *xorriso, int filec, char **filev, - int flag) + off_t boss_mem, int flag) { int i, ret, was_error= 0; struct iso_tree_node *node; @@ -1287,10 +1471,12 @@ much_too_long:; } } - sprintf(xorriso->info_text, "Valid ISO nodes found: %d\n", filec-was_error); - Xorriso_info(xorriso,0); - if(filec-was_error<=0) - return(!was_error); + if(!(flag&4)) { + sprintf(xorriso->info_text, "Valid ISO nodes found: %d\n", filec-was_error); + Xorriso_info(xorriso,0); + if(filec-was_error<=0) + return(!was_error); + } for(i= 0; iresult_line+strlen(xorriso->result_line), "%s\n", Text_shellsafe(filev[i], sfe, 0)); @@ -1358,16 +1554,6 @@ much_too_long:; } -int Xorriso__node_name_cmp(const void *node1, const void *node2) -{ - char *name1, *name2; - - name1= (char *) iso_tree_node_get_name(*((struct iso_tree_node **) node1)); - name2= (char *) iso_tree_node_get_name(*((struct iso_tree_node **) node2)); - return(strcmp(name1,name2)); -} - - /* This function needs less buffer memory than Xorriso_ls_filev() but cannot perform structured pattern matching. @param flag bit0= long format @@ -1381,9 +1567,9 @@ int Xorriso_ls(struct XorrisO *xorriso, int flag) struct iso_tree_node_dir *dir_node; struct iso_volume *volume; struct iso_tree_iter *iter= NULL; - char sfe[4*SfileadrL], *npt, *rpt, perms[10], mem_text[80], limit_text[80]; + char sfe[4*SfileadrL], *npt, *rpt, perms[10]; mode_t st_mode; - off_t size, mem= 0; + off_t size; time_t mtime; struct tm tms, *tmpt; static char months[12][4]= { "Jan", "Feb", "Mar", "Apr", "May", "Jun", @@ -1426,48 +1612,18 @@ wdi_is_not_a_dir:; /* Reset iteration */ iso_tree_iter_free(iter); iter= NULL; - iter= iso_tree_node_children(dir_node); Xorriso_process_msg_queues(xorriso,0); - mem= (filec+1)*sizeof(struct iso_tree_node *); - Sfile_scale((double) mem, mem_text,5,1e4,0); - 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); - no_sort= 1; - } - sprintf(xorriso->info_text, "Valid ISO nodes found: %d\n", filec); Xorriso_info(xorriso,0); - if(!no_sort) { - node_array= calloc(sizeof(struct iso_tree_node *), filec+1); - if(node_array==NULL) { - sprintf(xorriso->info_text, - "Cannot allocate memory for %d directory entries", filec); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - ret= -1; goto ex; - } - - for(i= 0; (node= iso_tree_iter_next(iter)) != NULL && iinfo_text, "Temporary memory needed for pattern expansion : %s", mem_text); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - if(mem > xorriso->temp_mem_limit) { + 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)", @@ -1897,7 +2052,7 @@ cannot_compile:; (*filev)= (char **) calloc(sizeof(char *), count); if(*filev==NULL) { no_memory:; - Sfile_scale((double) mem, mem_text,5,1e4,1); + Sfile_scale((double) *mem, mem_text,5,1e4,1); sprintf(xorriso->info_text, "Cannot allocate enough memory (%s) for pattern expansion", mem_text); @@ -1905,7 +2060,7 @@ no_memory:; ret= -1; goto ex; } - /* now store store addresses */ + /* now store addresses */ for(i= 0; i