Add -execdir support.
authormillert <millert@openbsd.org>
Mon, 23 Dec 1996 04:58:08 +0000 (04:58 +0000)
committermillert <millert@openbsd.org>
Mon, 23 Dec 1996 04:58:08 +0000 (04:58 +0000)
usr.bin/find/extern.h
usr.bin/find/find.1
usr.bin/find/find.h
usr.bin/find/function.c
usr.bin/find/option.c

index dcaa1e9..cb373cb 100644 (file)
@@ -1,4 +1,4 @@
-/* *      $OpenBSD: extern.h,v 1.6 1996/10/24 03:46:03 tholo Exp $*/
+/* *      $OpenBSD: extern.h,v 1.7 1996/12/23 04:58:08 millert Exp $*/
 /*-
  * Copyright (c) 1991, 1993
  *     The Regents of the University of California.  All rights reserved.
@@ -55,6 +55,7 @@ PLAN  *c_ctime __P((char *));
 PLAN   *c_depth __P((void));
 PLAN   *c_empty __P((void));
 PLAN   *c_exec __P((char ***, int));
+PLAN   *c_execdir __P((char ***));
 PLAN   *c_follow __P((void));
 PLAN   *c_fstype __P((char *));
 PLAN   *c_group __P((char *));
index 64d4363..45145d7 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: find.1,v 1.9 1996/09/01 07:26:45 tholo Exp $
+.\"    $OpenBSD: find.1,v 1.10 1996/12/23 04:58:09 millert Exp $
 .\" Copyright (c) 1990, 1993
 .\"    The Regents of the University of California.  All rights reserved.
 .\"
@@ -156,6 +156,16 @@ arguments it is replaced by the pathname of the current file.
 will be executed from the directory from which
 .Nm find
 was executed.
+.It Ic -execdir Ar utility Op argument ... ; 
+The
+.Ic \&-execdir
+primary is identical to the
+.Ic -exec
+primary with the exception that
+.Ar Utility
+will be executed from the directory that holds
+the current file.  The filename substituted for
+the string ``{}'' is not qualified.
 .It Ic -follow
 Follow symbolic links.
 .It Ic -fstype Ar type 
index b1b7102..78a314f 100644 (file)
@@ -1,4 +1,4 @@
-/* *   $OpenBSD: find.h,v 1.5 1996/09/01 04:56:26 tholo Exp $*/
+/* *   $OpenBSD: find.h,v 1.6 1996/12/23 04:58:09 millert Exp $*/
 /*-
  * Copyright (c) 1990, 1993
  *     The Regents of the University of California.  All rights reserved.
@@ -40,8 +40,8 @@
 /* node type */
 enum ntype {
        N_AND = 1,                              /* must start > 0 */
-       N_ATIME, N_CLOSEPAREN, N_CTIME, N_DEPTH, N_EMPTY, N_EXEC, N_EXPR,
-       N_FOLLOW, N_FSTYPE, N_GROUP, N_INUM, N_LINKS, N_LS, N_MAXDEPTH,
+       N_ATIME, N_CLOSEPAREN, N_CTIME, N_DEPTH, N_EMPTY, N_EXEC, N_EXECDIR,
+       N_EXPR, N_FOLLOW, N_FSTYPE, N_GROUP, N_INUM, N_LINKS, N_LS, N_MAXDEPTH,
        N_MINDEPTH, 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_PRUNE,
        N_SIZE, N_TYPE, N_USER, N_XDEV,
@@ -106,7 +106,7 @@ typedef struct _option {
 #define        O_NONE          0x01            /* no call required */
 #define        O_ZERO          0x02            /* pass: nothing */
 #define        O_ARGV          0x04            /* pass: argv, increment argv */
-#define        O_ARGVP         0x08            /* pass: *argv, N_OK || N_EXEC */
+#define        O_ARGVP         0x08            /* pass: *argv, N_OK || N_EXEC || N_EXECDIR */
        int flags;
 } OPTION;
 
index 9264442..d108993 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: function.c,v 1.7 1996/09/01 04:56:26 tholo Exp $      */
+/*     $OpenBSD: function.c,v 1.8 1996/12/23 04:58:10 millert Exp $    */
 
 /*-
  * Copyright (c) 1990, 1993
@@ -38,7 +38,7 @@
 
 #ifndef lint
 /*static char sccsid[] = "from: @(#)function.c 8.1 (Berkeley) 6/6/93";*/
-static char rcsid[] = "$OpenBSD: function.c,v 1.7 1996/09/01 04:56:26 tholo Exp $";
+static char rcsid[] = "$OpenBSD: function.c,v 1.8 1996/12/23 04:58:10 millert Exp $";
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -361,6 +361,106 @@ c_exec(argvp, isok)
        return (new);
 }
  
+/*
+ * -execdir utility [arg ... ] ; functions --
+ *
+ *     True if the executed utility returns a zero value as exit status.
+ *     The end of the primary expression is delimited by a semicolon.  If
+ *     "{}" occurs anywhere, it gets replaced by the unqualified pathname.
+ *     The current directory for the execution of utility is the same as
+ *     the directory where the file lives.
+ */
+int
+f_execdir(plan, entry)
+       register PLAN *plan;
+       FTSENT *entry;
+{
+       extern int dotfd;
+       register int cnt;
+       pid_t pid;
+       int status;
+       char *file;
+
+       /* XXX - if file/dir ends in '/' this will not work -- can it? */
+       if ((file = strrchr(entry->fts_path, '/')))
+           file++;
+       else
+           file = entry->fts_path;
+
+       for (cnt = 0; plan->e_argv[cnt]; ++cnt)
+               if (plan->e_len[cnt])
+                       brace_subst(plan->e_orig[cnt], &plan->e_argv[cnt],
+                           file, plan->e_len[cnt]);
+
+       /* don't mix output of command with find output */
+       fflush(stdout);
+       fflush(stderr);
+
+       switch (pid = vfork()) {
+       case -1:
+               err(1, "fork");
+               /* NOTREACHED */
+       case 0:
+               execvp(plan->e_argv[0], plan->e_argv);
+               warn("%s", plan->e_argv[0]);
+               _exit(1);
+       }
+       pid = waitpid(pid, &status, 0);
+       return (pid != -1 && WIFEXITED(status) && !WEXITSTATUS(status));
+}
+/*
+ * c_execdir --
+ *     build three parallel arrays, one with pointers to the strings passed
+ *     on the command line, one with (possibly duplicated) pointers to the
+ *     argv array, and one with integer values that are lengths of the
+ *     strings, but also flags meaning that the string has to be massaged.
+ */
+PLAN *
+c_execdir(argvp)
+       char ***argvp;
+{
+       PLAN *new;                      /* node returned */
+       register int cnt;
+       register char **argv, **ap, *p;
+
+       ftsoptions &= ~FTS_NOSTAT;
+       isoutput = 1;
+    
+       new = palloc(N_EXECDIR, f_execdir);
+
+       for (ap = argv = *argvp;; ++ap) {
+               if (!*ap)
+                       errx(1,
+                           "-execdir: no terminating \";\"");
+               if (**ap == ';')
+                       break;
+       }
+
+       cnt = ap - *argvp + 1;
+       new->e_argv = (char **)emalloc((u_int)cnt * sizeof(char *));
+       new->e_orig = (char **)emalloc((u_int)cnt * sizeof(char *));
+       new->e_len = (int *)emalloc((u_int)cnt * sizeof(int));
+
+       for (argv = *argvp, cnt = 0; argv < ap; ++argv, ++cnt) {
+               new->e_orig[cnt] = *argv;
+               for (p = *argv; *p; ++p)
+                       if (p[0] == '{' && p[1] == '}') {
+                               new->e_argv[cnt] = emalloc((u_int)MAXPATHLEN);
+                               new->e_len[cnt] = MAXPATHLEN;
+                               break;
+                       }
+               if (!*p) {
+                       new->e_argv[cnt] = *argv;
+                       new->e_len[cnt] = 0;
+               }
+       }
+       new->e_argv[cnt] = new->e_orig[cnt] = NULL;
+
+       *argvp = argv + 1;
+       return (new);
+}
 /*
  * -follow functions --
  *
index d5db954..13a6430 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: option.c,v 1.5 1996/09/01 04:56:27 tholo Exp $        */
+/*     $OpenBSD: option.c,v 1.6 1996/12/23 04:58:11 millert Exp $      */
 
 /*-
  * Copyright (c) 1990, 1993
@@ -38,7 +38,7 @@
 
 #ifndef lint
 /*static char sccsid[] = "from: @(#)option.c   8.1 (Berkeley) 6/6/93";*/
-static char rcsid[] = "$OpenBSD: option.c,v 1.5 1996/09/01 04:56:27 tholo Exp $";
+static char rcsid[] = "$OpenBSD: option.c,v 1.6 1996/12/23 04:58:11 millert Exp $";
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -64,6 +64,7 @@ static OPTION options[] = {
        { "-depth",     N_DEPTH,        c_depth,        O_ZERO },
        { "-empty",     N_EMPTY,        c_empty,        O_ZERO },
        { "-exec",      N_EXEC,         c_exec,         O_ARGVP },
+       { "-execdir",   N_EXECDIR,      c_execdir,      O_ARGVP },
        { "-follow",    N_FOLLOW,       c_follow,       O_ZERO },
        { "-fstype",    N_FSTYPE,       c_fstype,       O_ARGV },
        { "-group",     N_GROUP,        c_group,        O_ARGV },