changeset 14177:432cf6600cdd

3965 find does not support -delete option Reviewed by: Andy Stormont <andyjstormont@gmail.com> Approved by: Robert Mustacchi <rm@joyent.com>
author Prasad Joshi <pjoshi@stec-inc.com>
date Wed, 07 Aug 2013 16:17:12 +0530
parents c584b682c5c8
children b02c4a353739
files usr/src/cmd/find/find.c
diffstat 1 files changed, 54 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/find/find.c	Tue Mar 29 15:47:25 2011 -0700
+++ b/usr/src/cmd/find/find.c	Wed Aug 07 16:17:12 2013 +0530
@@ -87,7 +87,7 @@
 	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 @@
 	"-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 @@
 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 @@
 		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 @@
 		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 @@
 	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