From c478dd41933431354da7a97e1235de8e5bd70531 Mon Sep 17 00:00:00 2001 From: millert Date: Mon, 23 Dec 1996 04:58:08 +0000 Subject: [PATCH] Add -execdir support. --- usr.bin/find/extern.h | 3 +- usr.bin/find/find.1 | 12 ++++- usr.bin/find/find.h | 8 ++-- usr.bin/find/function.c | 104 +++++++++++++++++++++++++++++++++++++++- usr.bin/find/option.c | 5 +- 5 files changed, 122 insertions(+), 10 deletions(-) diff --git a/usr.bin/find/extern.h b/usr.bin/find/extern.h index dcaa1e93ef0..cb373cb4e80 100644 --- a/usr.bin/find/extern.h +++ b/usr.bin/find/extern.h @@ -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 *)); diff --git a/usr.bin/find/find.1 b/usr.bin/find/find.1 index 64d43635e96..45145d77a23 100644 --- a/usr.bin/find/find.1 +++ b/usr.bin/find/find.1 @@ -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 diff --git a/usr.bin/find/find.h b/usr.bin/find/find.h index b1b71021186..78a314f37dd 100644 --- a/usr.bin/find/find.h +++ b/usr.bin/find/find.h @@ -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; diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c index 9264442dd1f..d1089935ba9 100644 --- a/usr.bin/find/function.c +++ b/usr.bin/find/function.c @@ -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 @@ -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 -- * diff --git a/usr.bin/find/option.c b/usr.bin/find/option.c index d5db954baa2..13a643098b1 100644 --- a/usr.bin/find/option.c +++ b/usr.bin/find/option.c @@ -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 @@ -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 }, -- 2.20.1