rm -I patch (Re: Protection from the dreaded "rm -fr /")
Matthew Dillon
dillon at apollo.backplane.com
Tue Oct 5 18:57:17 PDT 2004
I think I'll commit something like this to DragonFly (you might
get patch errors w/ FreeBSD but this is the basic idea).
-Matt
Index: rm.1
===================================================================
RCS file: /cvs/src/bin/rm/rm.1,v
retrieving revision 1.2
diff -u -r1.2 rm.1
--- rm.1 17 Jun 2003 04:22:50 -0000 1.2
+++ rm.1 6 Oct 2004 01:34:12 -0000
@@ -81,6 +81,11 @@
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 less intrusive dumb-user
+option then
+.Fl i
.It Fl P
Overwrite regular files before deleting them.
Files are overwritten three times, first with the byte pattern 0xff,
Index: rm.c
===================================================================
RCS file: /cvs/src/bin/rm/rm.c,v
retrieving revision 1.3
diff -u -r1.3 rm.c
--- rm.c 30 Aug 2004 19:27:21 -0000 1.3
+++ rm.c 6 Oct 2004 01:52:46 -0000
@@ -51,9 +51,11 @@
#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 rm_file(char **);
void rm_overwrite(char *, struct stat *);
@@ -70,7 +72,7 @@
int
main(int argc, char *argv[])
{
- int ch, rflag;
+ int ch;
char *p;
/*
@@ -94,7 +96,7 @@
}
Pflag = rflag = 0;
- while ((ch = getopt(argc, argv, "dfiPRrvW")) != -1)
+ while ((ch = getopt(argc, argv, "dfiIPRrvW")) != -1)
switch(ch) {
case 'd':
dflag = 1;
@@ -107,6 +109,9 @@
fflag = 0;
iflag = 1;
break;
+ case 'I':
+ Iflag = 1;
+ break;
case 'P':
Pflag = 1;
break;
@@ -138,6 +143,10 @@
if (*argv) {
stdin_ok = isatty(STDIN_FILENO);
+ if (Iflag) {
+ if (check2(argv) == 0)
+ exit (1);
+ }
if (rflag)
rm_tree(argv);
else
@@ -442,6 +451,47 @@
return (first == 'y' || first == 'Y');
}
+int
+check2(char **argv)
+{
+ struct stat st;
+ int first;
+ int ch;
+ int fcount = 0;
+ int dcount = 0;
+ int i;
+
+ for (i = 0; argv[i]; ++i) {
+ if (lstat(argv[i], &st) == 0) {
+ if (S_ISDIR(st.st_mode))
+ ++dcount;
+ else
+ ++fcount;
+ }
+ }
+ first = 0;
+ while (first != 'n' && first != 'N' && first != 'y' && first != 'Y') {
+ if (dcount && fcount && rflag) {
+ fprintf(stderr,
+ "recursively remove %d dirs and %d files? ",
+ dcount, fcount);
+ } else if (dcount && rflag) {
+ fprintf(stderr,
+ "recursively remove %d dirs? ", dcount);
+ } else if (dcount + fcount > 3) {
+ fprintf(stderr, "remove %d files? ", dcount + fcount);
+ } else {
+ return(1);
+ }
+ fflush(stderr);
+
+ first = ch = getchar();
+ while (ch != '\n' && ch != EOF)
+ ch = getchar();
+ }
+ return (first == 'y' || first == 'Y');
+}
+
#define ISDOT(a) ((a)[0] == '.' && (!(a)[1] || ((a)[1] == '.' && !(a)[2])))
void
checkdot(char **argv)
More information about the freebsd-hackers
mailing list