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/