diff -NBur findutils-4.1.7-sort0.5/find/defs.h findutils-4.1.7-dirslast/find/defs.h --- findutils-4.1.7-sort0.5/find/defs.h 2002-11-12 15:31:25.000000000 +0100 +++ findutils-4.1.7-dirslast/find/defs.h 2002-11-12 15:32:20.000000000 +0100 @@ -408,6 +408,7 @@ extern boolean no_leaf_check; extern boolean dir_sort; extern boolean dir_isort; +extern boolean sort_dirs_last; extern boolean stay_on_filesystem; extern boolean stop_at_current_level; extern boolean have_stat; diff -NBur findutils-4.1.7-sort0.5/find/find.1 findutils-4.1.7-dirslast/find/find.1 --- findutils-4.1.7-sort0.5/find/find.1 2002-11-12 15:31:25.000000000 +0100 +++ findutils-4.1.7-dirslast/find/find.1 2002-11-12 15:32:20.000000000 +0100 @@ -44,6 +44,10 @@ .IP \-daystart Measure times (for \-amin, \-atime, \-cmin, \-ctime, \-mmin, and \-mtime) from the beginning of today rather than from 24 hours ago. +.IP \-dirslast +Process subdirs in a directory only after having processed all non directory +entries. That option is used to generate databases in a format similar to +locatedb .IP \-depth Process each directory's contents before the directory itself. .IP \-follow diff -NBur findutils-4.1.7-sort0.5/find/find.c findutils-4.1.7-dirslast/find/find.c --- findutils-4.1.7-sort0.5/find/find.c 2002-11-12 15:31:25.000000000 +0100 +++ findutils-4.1.7-dirslast/find/find.c 2002-11-12 15:42:11.000000000 +0100 @@ -55,7 +55,7 @@ (*(node)->pred_func)((pathname), (stat_buf_ptr), (node)) static void process_top_path PARAMS((char *pathname)); -static int process_path PARAMS((char *pathname, char *name, boolean leaf, char *parent)); +static int process_path PARAMS((char *pathname, char *name, boolean leaf, char *parent, int pass)); static void process_dir PARAMS((char *pathname, char *name, int pathlen, struct stat *statp, char *parent)); static boolean no_side_effects PARAMS((struct predicate *pred)); static boolean default_prints PARAMS((struct predicate *pred)); @@ -110,6 +110,9 @@ /* If true, don't cross filesystem boundaries. */ boolean stay_on_filesystem; +/* If true, sort filenames like dir_sort, but sort dirs after files. */ +boolean sort_dirs_last; + /* If true, don't descend past current directory. Can be set by -prune, -maxdepth, and -xdev/-mount. */ boolean stop_at_current_level; @@ -186,6 +189,7 @@ stay_on_filesystem = false; dir_isort = false; dir_sort = false; + sort_dirs_last = false; exit_status = 0; dereference = false; #ifdef DEBUG_STAT @@ -358,11 +362,11 @@ cur_stat_buf.st_ino != stat_buf.st_ino) error (1, 0, _("%s changed during execution of %s"), pathname, program_name); - process_path (pathname, ".", false, "."); + process_path (pathname, ".", false, ".", 0); chdir_back (); } else - process_path (pathname, pathname, false, "."); + process_path (pathname, pathname, false, ".", 0); } /* Info on each directory in the current tree branch, to avoid @@ -396,7 +400,7 @@ Return nonzero iff PATHNAME is a directory. */ static int -process_path (char *pathname, char *name, boolean leaf, char *parent) +process_path (char *pathname, char *name, boolean leaf, char *parent, int pass) { struct stat stat_buf; static dev_t root_dev; /* Device ID of current argument pathname. */ @@ -424,6 +428,8 @@ if (!S_ISDIR (stat_buf.st_mode)) { + if (pass == 2) + return 0; /* pass 2: directories only */ if (curdepth >= mindepth) apply_predicate (pathname, &stat_buf, eval_tree); return 0; @@ -431,6 +437,9 @@ /* From here on, we're working on a directory. */ + if (pass == 1) + return 0; /* pass 1: no directories */ + stop_at_current_level = maxdepth >= 0 && curdepth >= maxdepth; /* If we've already seen this directory on this branch, @@ -521,7 +530,7 @@ unsigned cur_path_size; /* Bytes allocated for `cur_path'. */ register unsigned file_len; /* Length of each path to process. */ register unsigned pathname_len; /* PATHLEN plus trailing '/'. */ - register unsigned i,n_items; /* Temporary counters. */ + register unsigned cnt,cnt0,i,n_items; /* Temporary counters. */ if (pathname[pathlen - 1] == '/') pathname_len = pathlen + 1; /* For '\0'; already have '/'. */ @@ -555,6 +564,9 @@ qsort(namep_list,n_items,sizeof(char *),strpcmp); } + cnt0 = 0; + if (sort_dirs_last) cnt0 = 1; + for (cnt = cnt0; cnt <=2*cnt0; cnt++) { for (i = 0; i < n_items; i++) { @@ -585,11 +597,11 @@ that the rest of the entries are non-directories -- in other words, leaf files. */ subdirs_left -= process_path (cur_path, cur_name, - subdirs_left == 0, pathname); + subdirs_left == 0, pathname, cnt); else /* There might be weird (e.g., CD-ROM or MS-DOS) filesystems mounted, which don't have Unix-like directory link counts. */ - process_path (cur_path, cur_name, false, pathname); + process_path (cur_path, cur_name, false, pathname, cnt); curdepth--; } } /* end loop on cnt */ diff -NBur findutils-4.1.7-sort0.5/find/parser.c findutils-4.1.7-dirslast/find/parser.c --- findutils-4.1.7-sort0.5/find/parser.c 2002-11-12 15:31:25.000000000 +0100 +++ findutils-4.1.7-dirslast/find/parser.c 2002-11-12 15:32:20.000000000 +0100 @@ -63,6 +63,7 @@ static boolean parse_ctime PARAMS((char *argv[], int *arg_ptr)); static boolean parse_daystart PARAMS((char *argv[], int *arg_ptr)); static boolean parse_depth PARAMS((char *argv[], int *arg_ptr)); +static boolean parse_dirslast PARAMS((char *argv[], int *arg_ptr)); static boolean parse_empty PARAMS((char *argv[], int *arg_ptr)); static boolean parse_exec PARAMS((char *argv[], int *arg_ptr)); static boolean parse_false PARAMS((char *argv[], int *arg_ptr)); @@ -163,6 +164,7 @@ {"ctime", parse_ctime}, {"daystart", parse_daystart}, /* GNU */ {"depth", parse_depth}, + {"dirslast", parse_dirslast}, /* WF */ {"empty", parse_empty}, /* GNU */ {"exec", parse_exec}, {"false", parse_false}, /* GNU */ @@ -181,7 +183,7 @@ {"inum", parse_inum}, /* GNU, Unix */ {"ipath", parse_ipath}, /* GNU */ {"iregex", parse_iregex}, /* GNU */ - {"isort", parse_isort}, + {"isort", parse_isort}, /* WF */ {"links", parse_links}, {"lname", parse_lname}, /* GNU */ {"ls", parse_ls}, /* GNU, Unix */ @@ -209,7 +211,7 @@ {"prune", parse_prune}, {"regex", parse_regex}, /* GNU */ {"size", parse_size}, - {"sort", parse_sort}, + {"sort", parse_sort}, /* GNU */ {"true", parse_true}, /* GNU */ {"type", parse_type}, {"uid", parse_uid}, /* GNU */ @@ -416,6 +418,13 @@ } static boolean +parse_dirslast (char **argv,int *arg_ptr) +{ + sort_dirs_last = true; + return true; +} + +static boolean parse_exec (char **argv, int *arg_ptr) { return (insert_exec_ok (pred_exec, argv, arg_ptr));