summaryrefslogtreecommitdiffstats
path: root/bin/rm
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2004-10-28 08:25:30 +0000
committerdelphij <delphij@FreeBSD.org>2004-10-28 08:25:30 +0000
commit169dc919b8eccc8395d3b89e0bccdb8dfc61b13c (patch)
treea070af7791626abd13bcf3d6db2a57b1889e86ca /bin/rm
parent5a159b2d78bc926a669b419529f653f247d76c37 (diff)
downloadFreeBSD-src-169dc919b8eccc8395d3b89e0bccdb8dfc61b13c.zip
FreeBSD-src-169dc919b8eccc8395d3b89e0bccdb8dfc61b13c.tar.gz
Add -I, an option that asks for confirmation once if recursively
removing directories or if more than 3 files are listed in the command line. This feature is intended to provide a safe net but not being too annoying like having "rm -i" for every deleting operations, and is generally good for both newbies and power users, preventing them from being so easily run into ``rm -rf /'', ``rm -rf *'' and so forth. Originally implemented by Matthew Dillon for DragonFly, plus some improvements done by various DragonFly contributors. Approved by: murray (mentor; the original dillon's version) Discussed with: des Obtained from: DragonFly's bin/rm/ rm.c rev. 1.4 - 1.8 rm.1 rev. 1.3 - 1.4 MFC After: 1 month
Diffstat (limited to 'bin/rm')
-rw-r--r--bin/rm/rm.110
-rw-r--r--bin/rm/rm.c65
2 files changed, 70 insertions, 5 deletions
diff --git a/bin/rm/rm.1 b/bin/rm/rm.1
index c31ecaa..5fb6f05 100644
--- a/bin/rm/rm.1
+++ b/bin/rm/rm.1
@@ -31,7 +31,7 @@
.\" @(#)rm.1 8.5 (Berkeley) 12/5/94
.\" $FreeBSD$
.\"
-.Dd October 4, 2004
+.Dd October 28, 2004
.Dt RM 1
.Os
.Sh NAME
@@ -40,7 +40,7 @@
.Nd remove directory entries
.Sh SYNOPSIS
.Nm
-.Op Fl dfiPRrvW
+.Op Fl dfiIPRrvW
.Ar
.Nm unlink
.Ar file
@@ -76,6 +76,12 @@ The
option overrides any previous
.Fl f
options.
+.It Fl I
+Request confirmation once if more then three files are being removed or if a
+directory is being recursively removed. This is a far less intrusive option
+than
+.Fl i
+yet provides almost the same level of protection against mistakes.
.It Fl P
Overwrite regular files before deleting them.
Files are overwritten three times, first with the byte pattern 0xff,
diff --git a/bin/rm/rm.c b/bin/rm/rm.c
index c313282..52ead50 100644
--- a/bin/rm/rm.c
+++ b/bin/rm/rm.c
@@ -58,9 +58,11 @@ __FBSDID("$FreeBSD$");
#include <unistd.h>
int dflag, eval, fflag, iflag, Pflag, vflag, Wflag, stdin_ok;
+int rflag, Iflag;
uid_t uid;
int check(char *, char *, struct stat *);
+int check2(char **);
void checkdot(char **);
void checkslash(char **);
void rm_file(char **);
@@ -78,7 +80,7 @@ void usage(void);
int
main(int argc, char *argv[])
{
- int ch, rflag;
+ int ch;
char *p;
/*
@@ -102,7 +104,7 @@ main(int argc, char *argv[])
}
Pflag = rflag = 0;
- while ((ch = getopt(argc, argv, "dfiPRrvW")) != -1)
+ while ((ch = getopt(argc, argv, "dfiIPRrvW")) != -1)
switch(ch) {
case 'd':
dflag = 1;
@@ -115,6 +117,9 @@ main(int argc, char *argv[])
fflag = 0;
iflag = 1;
break;
+ case 'I':
+ Iflag = 1;
+ break;
case 'P':
Pflag = 1;
break;
@@ -148,6 +153,10 @@ main(int argc, char *argv[])
if (*argv) {
stdin_ok = isatty(STDIN_FILENO);
+ if (Iflag) {
+ if (check2(argv) == 0)
+ exit (1);
+ }
if (rflag)
rm_tree(argv);
else
@@ -489,6 +498,56 @@ checkslash(char **argv)
}
}
+int
+check2(char **argv)
+{
+ struct stat st;
+ int first;
+ int ch;
+ int fcount = 0;
+ int dcount = 0;
+ int i;
+ const char *dname = NULL;
+
+ for (i = 0; argv[i]; ++i) {
+ if (lstat(argv[i], &st) == 0) {
+ if (S_ISDIR(st.st_mode)) {
+ ++dcount;
+ dname = argv[i]; /* only used if 1 dir */
+ } else {
+ ++fcount;
+ }
+ }
+ }
+ first = 0;
+ while (first != 'n' && first != 'N' && first != 'y' && first != 'Y') {
+ if (dcount && rflag) {
+ fprintf(stderr, "recursively remove");
+ if (dcount == 1)
+ fprintf(stderr, " %s", dname);
+ else
+ fprintf(stderr, " %d dirs", dcount);
+ if (fcount == 1)
+ fprintf(stderr, " and 1 file");
+ else if (fcount > 1)
+ fprintf(stderr, " and %d files", fcount);
+ } else if (dcount + fcount > 3) {
+ fprintf(stderr, "remove %d files", dcount + fcount);
+ } else {
+ return(1);
+ }
+ fprintf(stderr, "? ");
+ fflush(stderr);
+
+ first = ch = getchar();
+ while (ch != '\n' && ch != EOF)
+ ch = getchar();
+ if (ch == EOF)
+ break;
+ }
+ return (first == 'y' || first == 'Y');
+}
+
#define ISDOT(a) ((a)[0] == '.' && (!(a)[1] || ((a)[1] == '.' && !(a)[2])))
void
checkdot(char **argv)
@@ -519,7 +578,7 @@ usage(void)
{
(void)fprintf(stderr, "%s\n%s\n",
- "usage: rm [-f | -i] [-dPRrvW] file ...",
+ "usage: rm [-f | -i] [-dIPRrvW] file ...",
" unlink file");
exit(EX_USAGE);
}
OpenPOWER on IntegriCloud