Subject: Re: multi find with different file outputs
To: None <tech-userlevel@NetBSD.org>
From: Jeremy C. Reed <reed@reedmedia.net>
List: tech-userlevel
Date: 10/03/2005 17:16:43
Please test and review the following diff in src/src/usr.bin/find.

Next I will add simple -fprint0 and -fprintx also.

Index: extern.h
===================================================================
RCS file: /cvsroot/src/usr.bin/find/extern.h,v
retrieving revision 1.20
diff -b -u -r1.20 extern.h
--- extern.h	7 Aug 2003 11:13:40 -0000	1.20
+++ extern.h	4 Oct 2005 00:13:27 -0000
@@ -58,6 +58,7 @@
  PLAN	*c_execdir __P((char ***, int));
  PLAN	*c_flags __P((char ***, int));
  PLAN	*c_follow __P((char ***, int));
+PLAN	*c_fprint __P((char ***, int));
  PLAN	*c_fstype __P((char ***, int));
  PLAN	*c_group __P((char ***, int));
  PLAN	*c_iname __P((char ***, int));
Index: find.1
===================================================================
RCS file: /cvsroot/src/usr.bin/find/find.1,v
retrieving revision 1.47.2.1
diff -b -u -r1.47.2.1 find.1
--- find.1	31 Mar 2004 18:08:25 -0000	1.47.2.1
+++ find.1	4 Oct 2005 00:13:28 -0000
@@ -259,6 +259,12 @@
  for more information about file flags.)
  .It Ic -follow
  Follow symbolic links.
+.It Ic -fprint Ar filename
+This creates
+.Ar filename
+or overwrites the file if it already exists.
+It writes the pathname of the current file to this file, followed
+by a newline character.
  .It Ic -fstype Ar type
  True if the file is contained in a file system of type
  .Ar type .
Index: find.h
===================================================================
RCS file: /cvsroot/src/usr.bin/find/find.h,v
retrieving revision 1.18
diff -b -u -r1.18 find.h
--- find.h	7 Aug 2003 11:13:41 -0000	1.18
+++ find.h	4 Oct 2005 00:13:29 -0000
@@ -41,7 +41,7 @@
  	N_AND = 1, 				/* must start > 0 */
  	N_AMIN, N_ANEWER, N_ATIME, N_CLOSEPAREN, N_CMIN, N_CNEWER, N_CTIME,
  	N_DEPTH, N_EMPTY,
-	N_EXEC, N_EXECDIR, N_EXPR, N_FLAGS, N_FOLLOW, N_FSTYPE, N_GROUP,
+	N_EXEC, N_EXECDIR, N_EXPR, N_FLAGS, N_FOLLOW, N_FPRINT, N_FSTYPE, N_GROUP,
  	N_INAME, N_INUM, N_IREGEX, N_LINKS, N_LS, N_MINDEPTH, N_MAXDEPTH,
  	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,
Index: function.c
===================================================================
RCS file: /cvsroot/src/usr.bin/find/function.c,v
retrieving revision 1.46
diff -b -u -r1.46 function.c
--- function.c	7 Aug 2003 11:13:41 -0000	1.46
+++ function.c	4 Oct 2005 00:13:31 -0000
@@ -59,6 +59,7 @@
  #include <string.h>
  #include <tzfile.h>
  #include <unistd.h>
+#include <fcntl.h>

  #include "find.h"
  #include "stat_flags.h"
@@ -88,6 +89,7 @@
  	int	f_exec __P((PLAN *, FTSENT *));
  	int	f_execdir __P((PLAN *, FTSENT *));
  	int	f_flags __P((PLAN *, FTSENT *));
+	int	f_fprint __P((PLAN *, FTSENT *));
  	int	f_fstype __P((PLAN *, FTSENT *));
  	int	f_group __P((PLAN *, FTSENT *));
  	int	f_iname __P((PLAN *, FTSENT *));
@@ -118,6 +120,7 @@
  static	PLAN   *palloc __P((enum ntype, int (*) __P((PLAN *, FTSENT *))));

  extern int dotfd;
+extern char *starting_directory;
  extern FTS *tree;
  extern time_t now;

@@ -708,6 +711,67 @@
  	return (palloc(N_FOLLOW, f_always_true));
  }

+/* -fprint functions --
+ *
+ *	Causes the current pathame to be written to the defined output file.
+ */
+int
+f_fprint(plan, entry)
+	PLAN *plan;
+	FTSENT *entry;
+{
+	if (plan->flags == -1) {	/* output file not opened yet */
+		int	fprint_file_handle;
+		fprint_file_handle = open(plan->c_data,
+			O_WRONLY | O_CREAT, DEFFILEMODE); 
+		if (fprint_file_handle == -1) {
+			warn("open");
+			_exit(1);
+		}
+		plan->flags = fprint_file_handle;
+	}
+
+	if ((write(plan->flags, entry->fts_path,
+		strlen(entry->fts_path)) == -1) ||
+	    (write(plan->flags, "\n", 1) == -1)) {
+		warn("write");
+		_exit(1);
+	}
+
+	return(0); /* return false so it will continue */
+
+	/* no descriptors are closed; they will be closed by
+	   operating system when this find command exits.  */
+}
+ 
+PLAN *
+c_fprint(argvp, isok)
+	char ***argvp;
+	int isok;
+{
+	char *filename = **argvp;
+	PLAN *new;
+
+	(*argvp)++;
+	new = palloc(N_FPRINT, f_fprint);
+	new->flags = -1;	/* to be used for file descriptor */ 
+	if (filename[0] != '/') {
+		/* for relative filename, prepend the
+		   original working directory */
+		if ((new->c_data = malloc(
+		     (strlen(starting_directory) + strlen(filename) + 2)
+                       * sizeof(char))) == NULL) {
+			warn("malloc");
+			_exit(1);
+		}
+		snprintf(new->c_data, strlen(starting_directory) +
+			strlen(filename) + 2, "%s/%s", starting_directory,
+			filename);
+	}
+	else new->c_data = filename;
+	return (new);
+}
+
  /*
   * -fstype functions --
   *
Index: main.c
===================================================================
RCS file: /cvsroot/src/usr.bin/find/main.c,v
retrieving revision 1.20
diff -b -u -r1.20 main.c
--- main.c	7 Aug 2003 11:13:42 -0000	1.20
+++ main.c	4 Oct 2005 00:13:32 -0000
@@ -62,6 +62,7 @@

  time_t now;			/* time find was run */
  int dotfd;			/* starting directory */
+char *starting_directory;	/* starting directory for -fprint */
  int ftsoptions;			/* options for the ftsopen(3) call */
  int isdeprecated;		/* using deprecated syntax */
  int isdepth;			/* do directories on post-order visit */
@@ -153,6 +154,8 @@

  	if ((dotfd = open(".", O_RDONLY, 0)) < 0)
  		err(1, ".");
+	if ((starting_directory = getcwd(NULL, 0)) < 0)
+		err(1, "getcwd");

  	exit(find_execute(find_formplan(argv), start));
  }
Index: option.c
===================================================================
RCS file: /cvsroot/src/usr.bin/find/option.c,v
retrieving revision 1.20
diff -b -u -r1.20 option.c
--- option.c	7 Aug 2003 11:13:43 -0000	1.20
+++ option.c	4 Oct 2005 00:13:32 -0000
@@ -74,6 +74,7 @@
  	{ "-execdir",	N_EXECDIR,	c_execdir,	1 },
  	{ "-flags",	N_FLAGS,	c_flags,	1 },
  	{ "-follow",	N_FOLLOW,	c_follow,	0 },
+	{ "-fprint",	N_FPRINT,	c_fprint,	1 },
  	{ "-fstype",	N_FSTYPE,	c_fstype,	1 },
  	{ "-group",	N_GROUP,	c_group,	1 },
  	{ "-iname",	N_INAME,	c_iname,	1 },

  Jeremy C. Reed

  	  	 	 technical support & remote administration
 	  	 	 http://www.pugetsoundtechnology.com/