summaryrefslogtreecommitdiff
path: root/usr/src/cmd
diff options
context:
space:
mode:
authorPrasad Joshi <pjoshi@stec-inc.com>2013-08-07 16:17:12 +0530
committerRobert Mustacchi <rm@joyent.com>2013-08-31 10:17:23 -0700
commitab823b7f933f787dbdf7a0bb790639210c583869 (patch)
tree4dd994bd955e4fb2c2d0d6c025912d33876cdc21 /usr/src/cmd
parenta81df0a5d715363cc1841810a87818dfa95675c0 (diff)
downloadillumos-joyent-ab823b7f933f787dbdf7a0bb790639210c583869.tar.gz
3965 find does not support -delete option
Reviewed by: Andy Stormont <andyjstormont@gmail.com> Approved by: Robert Mustacchi <rm@joyent.com>
Diffstat (limited to 'usr/src/cmd')
-rw-r--r--usr/src/cmd/find/find.c55
1 files changed, 54 insertions, 1 deletions
diff --git a/usr/src/cmd/find/find.c b/usr/src/cmd/find/find.c
index c6fc469e15..fdd24124eb 100644
--- a/usr/src/cmd/find/find.c
+++ b/usr/src/cmd/find/find.c
@@ -87,7 +87,7 @@ enum Command
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
@@ -119,6 +119,7 @@ static struct Args commands[] =
"-cpio", CPIO, Cpio,
"-ctime", CTIME, Num,
"-depth", DEPTH, Unary,
+ "-delete", DELETE, Unary,
"-exec", EXEC, Exec,
"-follow", FOLLOW, Unary,
"-fstype", FSTYPE, Str,
@@ -204,6 +205,7 @@ struct Arglist
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;
@@ -529,6 +531,11 @@ int *actionp;
case DEPTH:
walkflags |= FTW_DEPTH;
break;
+ case DELETE:
+ walkflags |= (FTW_DEPTH | FTW_PHYS);
+ walkflags &= ~FTW_CHDIR;
+ (*actionp)++;
+ break;
case LOCAL:
np->first.l = 0L;
@@ -967,6 +974,9 @@ struct FTW *state;
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;
@@ -1318,6 +1328,49 @@ doexec(char *name, char *argv[], int *exitcode)
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