commit 76ed377d6d3e4a83a00cabd401f751b37ecd1e7b
Author: James Youngman <jay@gnu.org>
Date:   Sat Feb 20 13:11:45 2010 +0000

    Fix Savannah bug# 28824: "-ctime x" yields "missing argument to `-ctime'".
    
    * find/parser.c (parse_fls): If the argument is invalid, reverse
    the change that collect_arg() made to *arg_ptr (that is, don't
    consume the argument).
    (parse_fprint0): Likewise.
    (parse_gid): Likewise.
    (parse_group): Likewise.
    (parse_inum): Likewise.
    (parse_links): Likewise.
    (do_parse_xmin): Likewise.
    (parse_name): Likewise.
    (parse_printf): Likewise.
    (parse_uid): Likewise.
    (parse_used): Likewise.
    (parse_time): Likewise.
    
    Signed-off-by: James Youngman <jay@gnu.org>

diff --git a/ChangeLog b/ChangeLog
index d0ce1fe..13539a4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,0 +1,19 @@
+2010-02-20  James Youngman  <jay@gnu.org>
+
+	Fix Savannah bug# 28824: "-ctime x" yields "missing argument to
+	`-ctime'".
+	* find/parser.c (parse_fls): If the argument is invalid, reverse
+	the change that collect_arg() made to *arg_ptr (that is, don't
+	consume the argument).
+	(parse_fprint0): Likewise.
+	(parse_gid): Likewise.
+	(parse_group): Likewise.
+	(parse_inum): Likewise.
+	(parse_links): Likewise.
+	(do_parse_xmin): Likewise.
+	(parse_name): Likewise.
+	(parse_printf): Likewise.
+	(parse_uid): Likewise.
+	(parse_used): Likewise.
+	(parse_time): Likewise.
+
diff --git a/NEWS b/NEWS
index 5394311..4e910df 100644
--- a/NEWS
+++ b/NEWS
@@ -4,5 +4,8 @@ GNU findutils NEWS - User visible changes.	-*- outline -*- (allout)
 
 ** Bug Fixes
 
+#28824: Corrected error message for "-ctime x".
+        Likewise for -gid, -inum, -links, -mmin, -cmin, -amin,
+	-uid, -used, -atime, -mtime, -ctime.
 #26537: find -prune now makes sure it has valid stat() information.
 
diff --git a/find/parser.c b/find/parser.c
index 2e6b989..08758ee 100644
--- a/find/parser.c
+++ b/find/parser.c
@@ -886,8 +886,14 @@ static boolean
 parse_fls (const struct parser_table* entry, char **argv, int *arg_ptr)
 {
   const char *filename;
-  return collect_arg(argv, arg_ptr, &filename)
-    &&  insert_fls(entry, filename);
+  if (collect_arg(argv, arg_ptr, &filename))
+    {
+      if (insert_fls(entry, filename))
+	return true;
+      else
+	--*arg_ptr;		/* don't consume the invalid arg. */
+    }
+  return false;
 }
 
 static boolean
@@ -937,9 +943,13 @@ parse_fprint0 (const struct parser_table* entry, char **argv, int *arg_ptr)
 {
   const char *filename;
   if (collect_arg(argv, arg_ptr, &filename))
-    return insert_fprint(entry, filename);
-  else
-    return false;
+    {
+      if (insert_fprint(entry, filename))
+	return true;
+      else
+	--*arg_ptr;		/* don't consume the bad arg. */
+    }
+  return false;
 }
 
 static float estimate_fstype_success_rate(const char *fsname)
@@ -993,6 +1003,7 @@ parse_gid (const struct parser_table* entry, char **argv, int *arg_ptr)
     }
   else
     {
+      --*arg_ptr;		/* don't consume the invalid argument. */
       return false;
     }
 }
@@ -1049,6 +1060,7 @@ static boolean
 parse_group (const struct parser_table* entry, char **argv, int *arg_ptr)
 {
   const char *groupname;
+  const int saved_argc = *arg_ptr;
 
   if (collect_arg(argv, arg_ptr, &groupname))
     {
@@ -1077,6 +1089,7 @@ parse_group (const struct parser_table* entry, char **argv, int *arg_ptr)
 				"because it has the unexpected suffix %s"),
 			quotearg_n_style(0, options.err_quoting_style, groupname),
 			quotearg_n_style(1, options.err_quoting_style, groupname+gid_len));
+		  *arg_ptr = saved_argc; /* don't consume the invalid argument. */
 		  return false;
 		}
 	    }
@@ -1092,6 +1105,7 @@ parse_group (const struct parser_table* entry, char **argv, int *arg_ptr)
 		{
 		  error(1, 0, _("argument to -group is empty, but should be a group name"));
 		}
+	      *arg_ptr = saved_argc; /* don't consume the invalid argument. */
 	      return false;
 	    }
 	}
@@ -1256,6 +1270,7 @@ parse_inum (const struct parser_table* entry, char **argv, int *arg_ptr)
     }
   else
     {
+      --*arg_ptr;		/* don't consume the invalid argument. */
       return false;
     }
 }
@@ -1310,6 +1325,7 @@ parse_links (const struct parser_table* entry, char **argv, int *arg_ptr)
     }
   else
     {
+      --*arg_ptr;		/* don't consume the invalid argument. */
       return false;
     }
 }
@@ -1358,6 +1374,7 @@ insert_depthspec(const struct parser_table* entry, char **argv, int *arg_ptr,
       error(1, 0, _("Expected a positive decimal integer argument to %s, but got %s"),
 	    predicate,
 	    quotearg_n_style(0, options.err_quoting_style, depthstr));
+      /* NOTREACHED */
       return false;
     }
   /* missing argument */
@@ -1385,6 +1402,7 @@ do_parse_xmin (const struct parser_table* entry,
 	       enum xval xv)
 {
   const char *minutes;
+  const int saved_argc = *arg_ptr;
 
   if (collect_arg(argv, arg_ptr, &minutes))
     {
@@ -1401,6 +1419,11 @@ do_parse_xmin (const struct parser_table* entry,
 	  our_pred->est_success_rate = estimate_timestamp_success_rate(tval.ts.tv_sec);
 	  return true;
 	}
+      else
+	{
+	  /* Don't consume the invalid argument. */
+	  *arg_ptr = saved_argc;
+	}
     }
   return false;
 }
@@ -1427,6 +1450,8 @@ static boolean
 parse_name (const struct parser_table* entry, char **argv, int *arg_ptr)
 {
   const char *name;
+  const int saved_argc = *arg_ptr;
+
   if (collect_arg(argv, arg_ptr, &name))
     {
       fnmatch_sanitycheck();
@@ -1438,6 +1463,10 @@ parse_name (const struct parser_table* entry, char **argv, int *arg_ptr)
 	  our_pred->est_success_rate = estimate_pattern_match_rate(name, 0);
 	  return true;
 	}
+      else
+	{
+	  *arg_ptr = saved_argc; /* don't consume the invalid argument. */
+	}
     }
   return false;
 }
@@ -1954,11 +1983,21 @@ static boolean
 parse_printf (const struct parser_table* entry, char **argv, int *arg_ptr)
 {
   const char *format;
+  const int saved_argc = *arg_ptr;
+
   if (collect_arg(argv, arg_ptr, &format))
     {
       struct format_val fmt;
       open_stdout(&fmt);
-      return insert_fprintf (&fmt, entry, pred_fprintf, format);
+      if (insert_fprintf (&fmt, entry, pred_fprintf, format))
+	{
+	  return true;
+	}
+      else
+	{
+	  *arg_ptr = saved_argc; /* don't consume the invalid argument. */
+	  return false;
+	}
     }
   return false;
 }
@@ -1967,15 +2006,21 @@ static boolean
 parse_fprintf (const struct parser_table* entry, char **argv, int *arg_ptr)
 {
   const char *format, *filename;
+  int saved_argc = *arg_ptr;
+
   if (collect_arg(argv, arg_ptr, &filename))
     {
       if (collect_arg(argv, arg_ptr, &format))
 	{
 	  struct format_val fmt;
 	  open_output_file (filename, &fmt);
-	  return insert_fprintf (&fmt, entry, pred_fprintf, format);
+	  saved_argc = *arg_ptr;
+
+	  if (insert_fprintf (&fmt, entry, pred_fprintf, format))
+	    return true;
 	}
     }
+  *arg_ptr = saved_argc; /* don't consume the invalid argument. */
   return false;
 }
 
@@ -2405,6 +2450,7 @@ parse_uid (const struct parser_table* entry, char **argv, int *arg_ptr)
     }
   else
     {
+      --*arg_ptr;		/* don't consume the invalid argument. */
       return false;
     }
 }
@@ -2431,6 +2477,7 @@ parse_used (const struct parser_table* entry, char **argv, int *arg_ptr)
       else
 	{
 	  error(1, 0, _("Invalid argument %s to -used"), offset_str);
+	  /*NOTREACHED*/
 	  return false;
 	}
     }
@@ -2610,6 +2657,7 @@ insert_type (char **argv, int *arg_ptr,
       if (strlen(typeletter) != 1u)
 	{
 	  error(1, 0, _("Arguments to -type should contain only one letter"));
+	  /*NOTREACHED*/
 	  return false;
 	}
 
@@ -2657,6 +2705,7 @@ insert_type (char **argv, int *arg_ptr,
 #endif
 	default:			/* None of the above ... nuke 'em. */
 	  error(1, 0, _("Unknown argument to -type: %c"), (*typeletter));
+	  /*NOTREACHED*/
 	  return false;
 	}
       our_pred = insert_primary_withpred (entry, which_pred, typeletter);
@@ -3349,6 +3398,7 @@ parse_time (const struct parser_table* entry, char *argv[], int *arg_ptr)
   const char *errmsg = "arithmetic overflow while converting %s "
     "days to a number of seconds";
   struct timespec origin;
+  const int saved_argc = *arg_ptr;
 
   if (!collect_arg(argv, arg_ptr, &timearg))
     return false;
@@ -3381,7 +3431,10 @@ parse_time (const struct parser_table* entry, char *argv[], int *arg_ptr)
   timearg = orig_timearg;
 
   if (!get_relative_timestamp(timearg, &tval, origin, DAYSECS, errmsg))
-    return false;
+    {
+      *arg_ptr = saved_argc;	/* don't consume the invalid argument */
+      return false;
+    }
 
   our_pred = insert_primary (entry, orig_timearg);
   our_pred->args.reftime = tval;
