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)