2005-02-05  Dmitry V. Levin  <ldv@altlinux.org>

	Additional tweaks for -execdir/-okdir actions.

	* find/parser.c (new_insert_exec_ok): Disable ignore_readdir_race
	for -execdir/-okdir.
	(parse_help): Mention recently added options.
	* find/pred.c (pred_execdir, pred_okdir): Use state.rel_pathname
	instead of basename(pathname).
	* doc/find.texi, find/find.1: Additionally document new options.

diff -uprk.orig findutils-4.2.16.orig/doc/find.texi findutils-4.2.16/doc/find.texi
--- findutils-4.2.16.orig/doc/find.texi	2005-02-05 15:03:37 +0300
+++ findutils-4.2.16/doc/find.texi	2005-02-06 02:26:24 +0300
@@ -1926,10 +1926,10 @@ find bills -type f | xargs -iXX sort -o 
 @end example
 
 @noindent
-The equivalent command using @samp{find -exec} is:
+The equivalent command using @samp{find -execdir} is:
 
 @example
-find bills -type f -exec sort -o '@{@}.sorted' '@{@}' ';'
+find bills -type f -execdir sort -o '@{@}.sorted' '@{@}' ';'
 @end example
 @end table
 
@@ -1937,14 +1937,24 @@ find bills -type f -exec sort -o '@{@}.s
 @subsection Querying
 
 To ask the user whether to execute a command on a single file, you can
-use the @code{find} primary @samp{-ok} instead of @samp{-exec}:
+use the @code{find} primary @samp{-okdir} instead of @samp{-execdir},
+and the @code{find} primary @samp{-ok} instead of @samp{-exec}:
 
-@deffn Action -ok command ;
-Like @samp{-exec} (@pxref{Single File}), but ask the user first (on
+@deffn Action -okdir command ;
+Like @samp{-execdir} (@pxref{Single File}), but ask the user first (on
 the standard input); if the response does not start with @samp{y} or
 @samp{Y}, do not run the command, and return false.
 @end deffn
 
+@deffn Action -ok command ;
+This insecure variant of the @samp{-okdir} action is specified by
+POSIX.  The main difference is that the command is executed in the
+directory from which @code{find} was invoked, meaning that @samp{@{@}}
+is expanded to a relative path starting with the name of one of the
+starting directories, rather than just the basename of the matched
+file.
+@end deffn
+
 When processing multiple files with a single command, to query the user
 you give @code{xargs} the following option.  When using this option, you
 might find it useful to control the number of files processed per
@@ -2215,7 +2225,7 @@ the file name contains a character with 
 strip it off.  A more reliable way is:
 
 @example
-find . -maxdepth 1 @var{tests} -ok rm '@{@}' \;
+find . -maxdepth 1 @var{tests} -okdir rm '@{@}' \;
 @end example
 
 @noindent
@@ -2234,18 +2244,18 @@ have found that its inode number is 1234
 whether to remove it:
 
 @example
-find . -maxdepth 1 -inum 12345 -ok rm -f '@{@}' \;
+find . -maxdepth 1 -inum 12345 -okdir rm -f '@{@}' \;
 @end example
 
 If you don't want to be asked, perhaps because the file name may contain
 a strange character sequence that will mess up your screen when printed,
-then use @samp{-exec} instead of @samp{-ok}.
+then use @samp{-execdir} instead of @samp{-okdir}.
 
 If you want to rename the file instead, you can use @code{mv} instead of
 @code{rm}:
 
 @example
-find . -maxdepth 1 -inum 12345 -ok mv '@{@}' @var{new-file-name} \;
+find . -maxdepth 1 -inum 12345 -okdir mv '@{@}' @var{new-file-name} \;
 @end example
 
 @node Fixing Permissions
diff -uprk.orig findutils-4.2.16.orig/find/find.1 findutils-4.2.16/find/find.1
--- findutils-4.2.16.orig/find/find.1	2005-01-23 21:29:25 +0300
+++ findutils-4.2.16/find/find.1	2005-02-06 02:26:24 +0300
@@ -907,7 +907,7 @@ Determines the locale to be used for int
 Determines the location of the internationalisation message catalogues.
 .IP PATH
 Affects the directores which are searched to find the executables 
-invoked by `\-exec' and `\-ok'.
+invoked by `\-exec', `\-execdir', `\-ok' and `\-okdir'.
 .SH "EXAMPLES"
 .nf
 .B find /tmp \-name core \-type f \-print | xargs /bin/rm -f
diff -uprk.orig findutils-4.2.16.orig/find/parser.c findutils-4.2.16/find/parser.c
--- findutils-4.2.16.orig/find/parser.c	2005-02-01 02:18:55 +0300
+++ findutils-4.2.16/find/parser.c	2005-02-06 02:26:24 +0300
@@ -740,9 +740,10 @@ tests (N can be +N or -N or N): -amin N 
       -wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N\n\
       -used N -user NAME -xtype [bcdpfls]\n"));
   puts (_("\
-actions: -exec COMMAND ; -fprint FILE -fprint0 FILE -fprintf FILE FORMAT\n\
-      -fls FILE -ok COMMAND ; -print -print0 -printf FORMAT -prune -ls -delete\n\
-      -quit\n"));
+actions: -delete -exec COMMAND ; -exec COMMAND {} + -execdir COMMAND ;\n\
+      -execdir COMMAND {} + -fls FILE -fprint FILE -fprint0 FILE\n\
+      -fprintf FILE FORMAT -ls -ok COMMAND ; -ok COMMAND {} + -okdir COMMAND ;\n\
+      -okdir COMMAND {} + -print -print0 -printf FORMAT -prune -quit\n"));
   puts (_("Report (and track progress on fixing) bugs via the findutils bug-reporting\n\
 page at http://savannah.gnu.org/ or, if you have no web access, by sending\n\
 email to <bug-findutils@gnu.org>."));
@@ -1928,6 +1929,7 @@ new_insert_exec_ok (const char *action,
   
   if ((func == pred_execdir) || (func == pred_okdir))
     {
+      options.ignore_readdir_race = false;
       check_path_safety(action);
       execp->use_current_dir = true;
     }
diff -uprk.orig findutils-4.2.16.orig/find/pred.c findutils-4.2.16/find/pred.c
--- findutils-4.2.16.orig/find/pred.c	2005-02-05 13:21:47 +0300
+++ findutils-4.2.16/find/pred.c	2005-02-06 02:28:22 +0300
@@ -498,8 +498,8 @@ pred_exec (char *pathname, struct stat *
 boolean
 pred_execdir (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
 {
-  const char *s = basename(pathname);
-  return new_impl_pred_exec(s, stat_buf, pred_ptr, "./", 2);
+  (void) &pathname;
+  return new_impl_pred_exec (state.rel_pathname, stat_buf, pred_ptr, "./", 2);
 }
 
 boolean
@@ -1100,9 +1100,8 @@ pred_ok (char *pathname, struct stat *st
 boolean
 pred_okdir (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
 {
-  const char *s = basename(pathname);
   if (is_ok(pred_ptr->args.exec_vec.replace_vec[0], pathname))
-    return new_impl_pred_exec (s, stat_buf, pred_ptr, "b./", 2);
+    return new_impl_pred_exec (state.rel_pathname, stat_buf, pred_ptr, "./", 2);
   else
     return false;
 }
