Print this page
3965 find does not support -delete option
@@ -85,11 +85,11 @@
PRINT,
ACL, AMIN, AND, ATIME, CMIN, CPIO, CSIZE, CTIME, DEPTH, EXEC, F_GROUP,
F_GROUPACL, F_USER, F_USERACL, FOLLOW, FSTYPE, INAME, INUM, IPATH,
IREGEX, LINKS, LOCAL, LPAREN, LS, MAXDEPTH, MINDEPTH, MMIN, MOUNT,
MTIME, NAME, NCPIO, NEWER, NOGRP, NOT, NOUSER, OK, OR, PATH, PERM,
- PRINT0, PRUNE, REGEX, RPAREN, SIZE, TYPE, VARARGS, XATTR
+ PRINT0, PRUNE, REGEX, RPAREN, SIZE, TYPE, VARARGS, XATTR, DELETE
};
enum Type
{
Unary, Id, Num, Str, Exec, Cpio, Op
@@ -117,10 +117,11 @@
"-atime", ATIME, Num,
"-cmin", CMIN, Num,
"-cpio", CPIO, Cpio,
"-ctime", CTIME, Num,
"-depth", DEPTH, Unary,
+ "-delete", DELETE, Unary,
"-exec", EXEC, Exec,
"-follow", FOLLOW, Unary,
"-fstype", FSTYPE, Str,
"-group", F_GROUP, Num,
"-groupacl", F_GROUPACL, Num,
@@ -202,10 +203,11 @@
static int compile();
static int execute();
static int doexec(char *, char **, int *);
+static int dodelete(char *, struct stat *, struct FTW *);
static struct Args *lookup();
static int ok();
static void usage(void) __NORETURN;
static struct Arglist *varargs();
static int list();
@@ -527,10 +529,15 @@
walkflags |= FTW_MOUNT;
break;
case DEPTH:
walkflags |= FTW_DEPTH;
break;
+ case DELETE:
+ walkflags |= (FTW_DEPTH | FTW_PHYS);
+ walkflags &= ~FTW_CHDIR;
+ (*actionp)++;
+ break;
case LOCAL:
np->first.l = 0L;
np->first.ll = 0LL;
np->second.i = '+';
@@ -965,10 +972,13 @@
val = ok(name, np->first.ap);
break;
case EXEC:
val = doexec(name, np->first.ap, NULL);
break;
+ case DELETE:
+ val = dodelete(name, statb, state);
+ break;
case VARARGS: {
struct Arglist *ap = np->first.vp;
char *cp;
cp = ap->nextstr - (strlen(name)+1);
@@ -1316,11 +1326,54 @@
*exitcode = 3; /* use to indicate error in cmd invocation */
return (!r);
}
+static int
+dodelete(char *name, struct stat *statb, struct FTW *state)
+{
+ char *fn;
+ int rc = 0;
+ /* restrict symlinks */
+ if ((walkflags & FTW_PHYS) == 0) {
+ (void) fprintf(stderr,
+ gettext("-delete is not allowed when symlinks are "
+ "followed.\n"));
+ return (1);
+ }
+
+ fn = name + state->base;
+ if (strcmp(fn, ".") == 0) {
+ /* nothing to do */
+ return (1);
+ }
+
+ if (strchr(fn, '/') != NULL) {
+ (void) fprintf(stderr,
+ gettext("-delete with relative path is unsafe."));
+ return (1);
+ }
+
+ if (S_ISDIR(statb->st_mode)) {
+ /* delete directory */
+ rc = rmdir(name);
+ } else {
+ /* delete file */
+ rc = unlink(name);
+ }
+
+ if (rc < 0) {
+ /* operation failed */
+ (void) fprintf(stderr, gettext("delete failed %s: %s\n"),
+ name, strerror(errno));
+ return (1);
+ }
+
+ return (1);
+}
+
/*
* Table lookup routine
*/
static struct Args *
lookup(word)