Re: [PATCH] /bin/rm Add "all" interactive option

看板DFBSD_submit作者時間21年前 (2004/12/19 05:01), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串2/7 (看更多)
I think this goes a bit beyond what 'rm' should be used for, and into what 'find' should be used for. -Matt Matthew Dillon <dillon@backplane.com> :This patch adds an "all" option to the rm utility's interactive mode as :described below. : : :The following is true in recursive mode: : :If "all" is specified to a directory, only that directory and everything :in it is removed. If "all" is specified to a file, all the files in the :same directory are deleted. If "all" is specified for a file on the :command line, all files listed on the command line are deleted. If "all" :is specified for a directory on the command line, only that directory :and everything in it is removed. : : :The following is true when NOT in recursive mode: : :If "all" is specified to one of the files or directories listed on the :command line, all the files and directories listed will be deleted :(directories have to be empty to be deleted when in NOT in recursive mode). : : :The follwing is true when the -I flag is specified: : :If "all" is specified, -f is assumed. : : : :- Jason : :--------------090304040006040702060209 :Content-Type: text/plain; : name="rm.c.diff" :Content-Transfer-Encoding: 7bit :Content-Disposition: inline; : filename="rm.c.diff" : :--- rm.c.orig Sat Dec 18 13:39:18 2004 :+++ rm.c Sat Dec 18 14:04:15 2004 :@@ -50,10 +50,13 @@ : #include <sysexits.h> : #include <unistd.h> : :-int dflag, eval, fflag, iflag, Pflag, vflag, Wflag, stdin_ok; :-int rflag, Iflag; :-uid_t uid; :+static int dflag, fflag, Iflag, iflag, Pflag, rflag, vflag, Wflag; :+static int eval; :+static int removeAll; :+static int stdin_ok; :+static uid_t uid; : :+static int rm_get_answeer(void); : static int check(const char *, const char *, struct stat *); : static int check2(char **); : static void checkdot(char **); :@@ -164,6 +167,7 @@ : int needstat; : int flags; : int rval; :+ int removeLevel; : : /* : * Remove a file hierarchy. If forcing removal (-f), or interactive :@@ -184,6 +188,7 @@ : flags |= FTS_WHITEOUT; : if (!(fts = fts_open(argv, flags, NULL))) : err(1, NULL); :+ removeLevel = -1; : while ((p = fts_read(fts)) != NULL) { : switch (p->fts_info) { : case FTS_DNR: :@@ -209,18 +214,35 @@ : } : continue; : case FTS_D: :- /* Pre-order: give user chance to skip. */ :+ /* :+ * Stop removing everything when we go to another :+ * directory at the same level or higher up in the :+ * directory hierarchy. :+ */ :+ if (removeAll && removeLevel >= p->fts_level) { :+ removeAll = 0; :+ removeLevel = -1; :+ } :+ : if (!fflag && !check(p->fts_path, p->fts_accpath, : p->fts_statp)) { : fts_set(fts, p, FTS_SKIP); : p->fts_number = SKIPPED; :+ } else { :+ /* :+ * Check if the user has just asked for everything :+ * in this directory to be removed. :+ */ :+ if (removeAll && removeLevel == -1) :+ removeLevel = p->fts_level; :+ :+ if (!uid :+ && (p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) :+ && !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)) :+ && chflags(p->fts_accpath, :+ p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)) < 0) :+ goto err; : } :- else if (!uid && :- (p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) && :- !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)) && :- chflags(p->fts_accpath, :- p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)) < 0) :- goto err; : continue; : case FTS_DP: : /* Post-order: see if user skipped. */ :@@ -228,9 +250,27 @@ : continue; : break; : default: :+ /* :+ * Stop removing everything when we go from :+ * directories to files at the same level, and :+ * when we go to files higher up in the directory :+ * hierarchy. :+ */ :+ if (removeAll && removeLevel >= p->fts_level) { :+ removeAll = 0; :+ removeLevel = -1; :+ } :+ : if (!fflag && : !check(p->fts_path, p->fts_accpath, p->fts_statp)) : continue; :+ :+ /* :+ * Check if the user has just asked for every file :+ * at this directory level to be removed. :+ */ :+ if (removeAll && removeLevel == -1) :+ removeLevel = p->fts_level - 1; : } : : rval = 0; :@@ -425,16 +465,33 @@ : return (0); : } : :+static int :+rm_get_answeer(void) :+{ :+ int c; :+ int answeer; :+ :+ answeer = getchar(); :+ :+ c = answeer; :+ while (c != '\n' && c != EOF) :+ c = getchar(); :+ :+ return answeer; :+} : : static int : check(const char *path, const char *name, struct stat *sp) : { :- int ch, first; :+ int answeer; : char modep[15], *flagsp; : :+ if (removeAll) :+ return 1; :+ : /* Check -i first. */ : if (iflag) :- fprintf(stderr, "remove %s? ", path); :+ fprintf(stderr, "remove %s? [y/n/a]: ", path); : else { : /* : * If it's not a symbolic link and it's unwritable and we're :@@ -453,7 +510,7 @@ : strmode(sp->st_mode, modep); : if ((flagsp = fflagstostr(sp->st_flags)) == NULL) : err(1, NULL); :- fprintf(stderr, "override %s%s%s/%s %s%sfor %s? ", :+ fprintf(stderr, "override %s%s%s/%s %s%sfor %s? [y/n/a]: ", : modep + 1, modep[9] == ' ' ? "" : " ", : user_from_uid(sp->st_uid, 0), : group_from_gid(sp->st_gid, 0), :@@ -463,18 +520,20 @@ : } : fflush(stderr); : :- first = ch = getchar(); :- while (ch != '\n' && ch != EOF) :- ch = getchar(); :- return (first == 'y' || first == 'Y'); :+ answeer = rm_get_answeer(); :+ if (answeer == 'a' || answeer == 'A') { :+ removeAll = 1; :+ return 1; :+ } else if (answeer == 'y' || answeer == 'Y') :+ return 1; :+ return 0; : } : : static int : check2(char **argv) : { : struct stat st; :- int first; :- int ch; :+ int answeer; : int fcount = 0; : int dcount = 0; : int i; :@@ -490,8 +549,7 @@ : } : } : } :- first = 0; :- while (first != 'n' && first != 'N' && first != 'y' && first != 'Y') { :+ for (;;) { : if (dcount && rflag) { : fprintf(stderr, "recursively remove"); : if (dcount == 1) :@@ -507,16 +565,27 @@ : } else { : return(1); : } :- fprintf(stderr, "? "); :+ fprintf(stderr, "? [y/n/a]: "); : fflush(stderr); : :- first = ch = getchar(); :- while (ch != '\n' && ch != EOF) :- ch = getchar(); :- if (ch == EOF) :+ answeer = rm_get_answeer(); :+ if (answeer == EOF) :+ break; :+ if (answeer == 'n' || answeer == 'N') : break; :+ if (answeer == 'y' || answeer == 'Y') :+ return 1; :+ if (answeer == 'a' || answeer == 'A') { :+ /* :+ * Since the user specified the -I flag and answeered :+ * "all" to this question, do not prompt them for :+ * confirmation again. :+ */ :+ fflag = 1; :+ return 1; :+ } : } :- return (first == 'y' || first == 'Y'); :+ return 0; : } : : #define ISDOT(a) ((a)[0] == '.' && (!(a)[1] || ((a)[1] == '.' && !(a)[2]))) : :--------------090304040006040702060209-- :
文章代碼(AID): #11n9gI00 (DFBSD_submit)
討論串 (同標題文章)
文章代碼(AID): #11n9gI00 (DFBSD_submit)