Subject: bin/14802: enhancement for find (find -updated file)
To: None <gnats-bugs@gnats.netbsd.org>
From: Robert Elz <kre@brandenburg.cs.mu.OZ.AU>
List: netbsd-bugs
Date: 11/30/2001 23:48:45
>Number:         14802
>Category:       bin
>Synopsis:       enhancement for find (find -updated file)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Dec 01 03:01:02 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     Robert Elz
>Release:        NetBSD-current 20010129
>Organization:
	Prince of Songkla University
>Environment:
	
NetBSD fuchsia 1.5Y NetBSD 1.5Y (FUCHSIA) #2: Mon Nov 26 13:41:27 ICT 2001     kre@fuchsia:/usr/obj/sys/FUCHSIA i386

>Description:
	There is no (easy anyway) way with "find" to select files that
	have been changed more recently than time X (as in the files that
	should be backed up - or in my case, files that have been fetched
	at work via anon cvs, and I want to take home with me ...)
	find -newer is no good for this, as cvs back dates files to the
	time they were either updated in the repository, or more likely
	(and even worse for this) the time they were last edited before
	being checked in - which is totally unrelated to whether the file
	was in my checked out copy when I last copied it...
>How-To-Repeat:
	RTFM or UTSL.
>Fix:
	Apply the following patch.   Seems to work just fine.
	Feel free to change the "updated" label to something more
	reasonable ... I couldn't think of anything.

Common subdirectories: /usr/src/usr.bin/find/CVS and ./CVS
diff -u5 /usr/src/usr.bin/find/extern.h ./extern.h
--- /usr/src/usr.bin/find/extern.h	Sat Sep 22 04:32:54 2001
+++ ./extern.h	Fri Nov 30 18:25:50 2001
@@ -66,10 +66,11 @@
 PLAN	*c_ls __P((char ***, int));
 PLAN	*c_mmin __P((char ***, int));
 PLAN	*c_mtime __P((char ***, int));
 PLAN	*c_name __P((char ***, int));
 PLAN	*c_newer __P((char ***, int));
+PLAN	*c_updated __P((char ***, int));
 PLAN	*c_nogroup __P((char ***, int));
 PLAN	*c_nouser __P((char ***, int));
 PLAN	*c_path __P((char ***, int));
 PLAN	*c_perm __P((char ***, int));
 PLAN	*c_print __P((char ***, int));
diff -u5 /usr/src/usr.bin/find/find.1 ./find.1
--- /usr/src/usr.bin/find/find.1	Sat Jul  7 04:07:01 2001
+++ ./find.1	Fri Nov 30 23:41:35 2001
@@ -435,10 +435,14 @@
 FIFO
 .It Cm s
 socket
 .El
 .Pp
+.It Ic -updated Ar file 
+True if the current file has a more recent last change time than
+.Ar file  .
+.Pp
 .It Ic -user Ar uname 
 True if the file belongs to the user
 .Ar uname  .
 If
 .Ar uname
diff -u5 /usr/src/usr.bin/find/find.h ./find.h
--- /usr/src/usr.bin/find/find.h	Tue Jul 20 08:28:41 1999
+++ ./find.h	Fri Nov 30 18:22:52 2001
@@ -46,11 +46,11 @@
 	N_AMIN, N_ATIME, N_CLOSEPAREN, N_CMIN, N_CTIME, N_DEPTH, N_EXEC,
 	N_EXPR, N_FLAGS, N_FOLLOW, N_FSTYPE, N_GROUP, N_INUM, N_IREGEX,
 	N_LINKS, N_LS,
 	N_MMIN, N_MTIME, N_NAME, N_NEWER, N_NOGROUP, N_NOT, N_NOUSER, N_OK,
 	N_OPENPAREN, N_OR, N_PATH, N_PERM, N_PRINT, N_PRINT0, N_PRINTX,
-	N_PRUNE, N_REGEX, N_SIZE, N_TYPE, N_USER, N_XDEV,
+	N_PRUNE, N_REGEX, N_SIZE, N_TYPE, N_UPDATED, N_USER, N_XDEV,
 };
 
 /* node definition */
 typedef struct _plandata {
 	struct _plandata *next;			/* next node */
diff -u5 /usr/src/usr.bin/find/function.c ./function.c
--- /usr/src/usr.bin/find/function.c	Sat Sep 22 04:32:55 2001
+++ ./function.c	Fri Nov 30 18:23:23 2001
@@ -94,10 +94,11 @@
 	int	f_ls __P((PLAN *, FTSENT *));
 	int	f_mmin __P((PLAN *, FTSENT *));
 	int	f_mtime __P((PLAN *, FTSENT *));
 	int	f_name __P((PLAN *, FTSENT *));
 	int	f_newer __P((PLAN *, FTSENT *));
+	int	f_updated __P((PLAN *, FTSENT *));
 	int	f_nogroup __P((PLAN *, FTSENT *));
 	int	f_nouser __P((PLAN *, FTSENT *));
 	int	f_path __P((PLAN *, FTSENT *));
 	int	f_perm __P((PLAN *, FTSENT *));
 	int	f_print __P((PLAN *, FTSENT *));
@@ -840,10 +841,45 @@
 
 	if (stat(filename, &sb))
 		err(1, "%s", filename);
 	new = palloc(N_NEWER, f_newer);
 	new->t_data = sb.st_mtime;
+	return (new);
+}
+
+/*
+ * -updated file functions --
+ *
+ *	True if the current file has been changed more recently
+ *	then the changed time of the file named by the pathname
+ *	file.
+ */
+int
+f_updated(plan, entry)
+	PLAN *plan;
+	FTSENT *entry;
+{
+
+	return (entry->fts_statp->st_ctime > plan->t_data);
+}
+ 
+PLAN *
+c_updated(argvp, isok)
+	char ***argvp;
+	int isok;
+{
+	char *filename = **argvp;
+	PLAN *new;
+	struct stat sb;
+    
+	(*argvp)++;
+	ftsoptions &= ~FTS_NOSTAT;
+
+	if (stat(filename, &sb))
+		err(1, "%s", filename);
+	new = palloc(N_UPDATED, f_newer);
+	new->t_data = sb.st_ctime;
 	return (new);
 }
  
 /*
  * -nogroup functions --
diff -u5 /usr/src/usr.bin/find/option.c ./option.c
--- /usr/src/usr.bin/find/option.c	Wed Oct 18 15:58:11 2000
+++ ./option.c	Fri Nov 30 18:24:08 2001
@@ -96,10 +96,11 @@
 	{ "-printx",	N_PRINTX,	c_printx,	0 },
 	{ "-prune",	N_PRUNE,	c_prune,	0 },
 	{ "-regex",	N_REGEX,	c_regex,	1 },
 	{ "-size",	N_SIZE,		c_size,		1 },
 	{ "-type",	N_TYPE,		c_type,		1 },
+	{ "-updated",	N_UPDATED,	c_updated,	1 },
 	{ "-user",	N_USER,		c_user,		1 },
 	{ "-xdev",	N_XDEV,		c_xdev,		0 }
 };
 
 /*
>Release-Note:
>Audit-Trail:
>Unformatted: