[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
find -delete
- To: bugs_(_at_)_openbsd_(_dot_)_org
- Subject: find -delete
- From: Daniel Cavanagh <nofsk_(_at_)_vtown_(_dot_)_com_(_dot_)_au>
- Date: Sat, 10 Jan 2004 16:37:06 +1000
this patch adds the "-delete" functionality to find. it removes all the
found files and directories and implies -depth. the code is from
freebsd.
diff -uN find.orig/extern.h find/extern.h
--- find.orig/extern.h 2003-06-26 17:27:29.000000000 +1000
+++ find/extern.h 2004-01-10 14:22:20.000000000 +1000
@@ -52,6 +52,7 @@
PLAN *c_cmin(char *, char ***, int);
PLAN *c_cnewer(char *, char ***, int);
PLAN *c_ctime(char *, char ***, int);
+PLAN *c_delete(char *, char ***, int);
PLAN *c_depth(char *, char ***, int);
PLAN *c_empty(char *, char ***, int);
PLAN *c_exec(char *, char ***, int);
diff -uN find.orig/find.1 find/find.1
--- find.orig/find.1 2003-09-03 04:50:06.000000000 +1000
+++ find/find.1 2004-01-10 14:22:20.000000000 +1000
@@ -168,6 +168,9 @@
was started, rounded up to the next full 24-hour period, is
.Ar n
24-hour periods.
+.It Ic -delete
+Delete the found files and directories. Always true. Implies
+.Fl d .
.It Ic -empty
True if the current file or directory is empty.
.It Ic -exec Ar utility Op argument ... ;
@@ -500,8 +503,7 @@
.It Li "$ find / -newer ttt -user wnj -print"
Print out a list of all the files owned by user
.Dq wnj
-that are newer
-than the file
+that are newer than the file
.Dq ttt .
.It Li "$ find / \e! \e( -newer ttt -user wnj \e) -print"
Print out a list of all the files which are not both newer than
@@ -511,8 +513,7 @@
.It Li "$ find / \e( -newer ttt -or -user wnj \e) -print"
Print out a list of all the files that are either owned by
.Dq wnj
-or
-that are newer than
+or that are newer than
.Dq ttt .
.It Li "$ find / \e! -fstype local -prune -or -name '*.core' -print"
Print out a list of all core files on local file systems.
diff -uN find.orig/find.h find/find.h
--- find.orig/find.h 2003-06-26 17:27:29.000000000 +1000
+++ find/find.h 2004-01-10 14:22:20.000000000 +1000
@@ -37,7 +37,7 @@
enum ntype {
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_DELETE, N_DEPTH, N_EMPTY, N_EXEC, N_EXECDIR, N_EXPR,
N_FLAGS, N_FOLLOW, N_FSTYPE, N_GROUP, N_INAME, N_INUM, N_LINKS, N_LS,
N_MMIN, N_MAXDEPTH,
N_MINDEPTH, N_MTIME, N_NAME, N_NEWER, N_NOGROUP, N_NOT, N_NOUSER,
diff -uN find.orig/function.c find/function.c
--- find.orig/function.c 2003-06-26 17:27:29.000000000 +1000
+++ find/function.c 2004-01-10 16:33:53.000000000 +1000
@@ -115,6 +115,7 @@
int f_expr(PLAN *, FTSENT *);
int f_not(PLAN *, FTSENT *);
int f_or(PLAN *, FTSENT *);
+int f_delete(PLAN *, FTSENT *);
extern int dotfd;
extern time_t now;
@@ -292,6 +293,62 @@
}
/*
+ * -delete functions --
+ *
+ * True always. Makes its best shot and continues on regardless.
+ */
+int
+f_delete(PLAN *plan, FTSENT *entry)
+{
+ /* ignore these from fts */
+ if (strcmp(entry->fts_accpath, ".") == 0 ||
+ strcmp(entry->fts_accpath, "..") == 0)
+ return (1);
+
+ /* sanity check */
+ if (isdepth == 0 || /* depth off */
+ (ftsoptions & FTS_NOSTAT) || /* not stat()ing */
+ !(ftsoptions & FTS_PHYSICAL) || /* physical off */
+ (ftsoptions & FTS_LOGICAL)) /* or finally, logical on */
+ errx(1, "-delete: insecure options got turned on");
+
+ /* Potentially unsafe - do not accept relative paths whatsoever */
+ if (strchr(entry->fts_accpath, '/') != NULL)
+ errx(1, "-delete: %s: relative path potentially not safe",
+ entry->fts_accpath);
+
+ /* Turn off user immutable bits if running as root */
+ if ((entry->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) &&
+ !(entry->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)) &&
+ geteuid() == 0)
+ chflags(entry->fts_accpath,
+ entry->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE));
+
+ /* rmdir directories, unlink everything else */
+ if (S_ISDIR(entry->fts_statp->st_mode)) {
+ if (rmdir(entry->fts_accpath) < 0 && errno != ENOTEMPTY)
+ warn("-delete: rmdir(%s)", entry->fts_path);
+ } else {
+ if (unlink(entry->fts_accpath) < 0)
+ warn("-delete: unlink(%s)", entry->fts_path);
+ }
+
+ return (1);
+}
+
+PLAN *
+c_delete(char *ignore, char ***ignored, int unused)
+{
+ ftsoptions &= ~FTS_NOSTAT; /* no optimise */
+ ftsoptions |= FTS_PHYSICAL; /* disable -follow */
+ ftsoptions &= ~FTS_LOGICAL; /* disable -follow */
+ isoutput = 1; /* possible output */
+ isdepth = 1; /* -depth implied */
+
+ return (palloc(N_DELETE, f_delete));
+}
+
+/*
* -depth functions --
*
* Always true, causes descent of the directory hierarchy to be done
diff -uN find.orig/option.c find/option.c
--- find.orig/option.c 2003-07-03 07:04:10.000000000 +1000
+++ find/option.c 2004-01-10 14:22:21.000000000 +1000
@@ -64,6 +64,7 @@
{ "-cmin", N_CMIN, c_cmin, O_ARGV },
{ "-cnewer", N_CNEWER, c_cnewer, O_ARGV },
{ "-ctime", N_CTIME, c_ctime, O_ARGV },
+ { "-delete", N_DELETE, c_delete, O_ZERO },
{ "-depth", N_DEPTH, c_depth, O_ZERO },
{ "-empty", N_EMPTY, c_empty, O_ZERO },
{ "-exec", N_EXEC, c_exec, O_ARGVP },
Visit your host, monkey.org