From 6cbdb2d631c82f1031b95067c30b4c5db1b98c7d Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 23 Apr 2014 22:32:38 +0200 Subject: find: support tree 1.7.0 --- README | 2 +- contrib/tree-1.6.0-matchdirs.patch | 282 ------------------------------------- src/password-store.sh | 16 +-- 3 files changed, 3 insertions(+), 297 deletions(-) delete mode 100644 contrib/tree-1.6.0-matchdirs.patch diff --git a/README b/README index 47ed64b..8bee02a 100644 --- a/README +++ b/README @@ -23,7 +23,7 @@ Depends on: http://sourceforge.net/projects/xclip/ - pwgen http://sourceforge.net/projects/pwgen/ -- tree +- tree >= 1.7.0 http://mama.indstate.edu/users/ice/tree/ - GNU getopt http://www.kernel.org/pub/linux/utils/util-linux/ diff --git a/contrib/tree-1.6.0-matchdirs.patch b/contrib/tree-1.6.0-matchdirs.patch deleted file mode 100644 index 92cd561..0000000 --- a/contrib/tree-1.6.0-matchdirs.patch +++ /dev/null @@ -1,282 +0,0 @@ -From 59d7a2237500c9439b758910e951bcd5dc48c657 Mon Sep 17 00:00:00 2001 -From: "Jason A. Donenfeld" -Date: Thu, 4 Apr 2013 08:43:05 -0700 -Subject: [PATCH] Add --matchdirs and --caseinsensitive to matching - -The new --matchdirs option causes pattern matching to include -the full contents of any directories that match the pattern, -including sub-directories. - -The --caseinsensitive option simply makes pattern matching case -insensitive. ---- - CHANGES | 5 ++++ - README | 4 ++++ - doc/tree.1 | 17 +++++++++++++- - tree.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++----------- - 4 files changed, 91 insertions(+), 14 deletions(-) - -diff --git a/CHANGES b/CHANGES -index 10f2e20..004b86a 100644 ---- a/CHANGES -+++ b/CHANGES -@@ -1,3 +1,8 @@ -+Version 1.6.1 -+ - Added --matchdirs flag so that patterns match against directory names and -+ then subsequently descend into sub-directories. -+ - Added --caseinsensitive flag so patterns match without regards to case. -+ - Version 1.6.0 - - Re-org of code into multiple files, split HTML and Unix listdir() into - separate functions, various code cleanups and optimizations. -diff --git a/README b/README -index ab58d82..58767e8 100644 ---- a/README -+++ b/README -@@ -141,6 +141,10 @@ Ujjwal Kumar - - Suggested that tree backslash spaces like ls does for script use. Made - output more like ls. - -+Jason A. Donenfeld -+ - Added --matchdirs flag for matching patterns against directories. -+ - Added --caseinsensitive flag for case insensitive pattern matching. -+ - And many others whom I've failed to keep track of. I should have started - this list years ago. - -diff --git a/doc/tree.1 b/doc/tree.1 -index 4b80852..41d0815 100644 ---- a/doc/tree.1 -+++ b/doc/tree.1 -@@ -21,7 +21,7 @@ - .SH NAME - tree \- list contents of directories in a tree-like format. - .SH SYNOPSIS --\fBtree\fP [\fB-acdfghilnpqrstuvxACDFQNSUX\fP] [\fB-L\fP \fIlevel\fP [\fB-R\fP]] [\fB-H\fP \fIbaseHREF\fP] [\fB-T\fP \fItitle\fP] [\fB-o\fP \fIfilename\fP] [\fB--nolinks\fP] [\fB-P\fP \fIpattern\fP] [\fB-I\fP \fIpattern\fP] [\fB--inodes\fP] [\fB--device\fP] [\fB--noreport\fP] [\fB--dirsfirst\fP] [\fB--version\fP] [\fB--help\fP] [\fB--filelimit\fP \fI#\fP] [\fB--si\fP] [\fB--prune\fP] [\fB--du\fP] [\fB--timefmt\fP \fIformat\fP] [\fIdirectory\fP ...] -+\fBtree\fP [\fB-acdfghilnpqrstuvxACDFQNSUX\fP] [\fB-L\fP \fIlevel\fP [\fB-R\fP]] [\fB-H\fP \fIbaseHREF\fP] [\fB-T\fP \fItitle\fP] [\fB-o\fP \fIfilename\fP] [\fB--nolinks\fP] [\fB-P\fP \fIpattern\fP] [\fB-I\fP \fIpattern\fP] [\fB--inodes\fP] [\fB--device\fP] [\fB--noreport\fP] [\fB--dirsfirst\fP] [\fB--version\fP] [\fB--help\fP] [\fB--filelimit\fP \fI#\fP] [\fB--si\fP] [\fB--prune\fP] [\fB--du\fP] [\fB--timefmt\fP \fIformat\fP] [\fB--caseinsensitive\fP] [\fB--matchdirs\fP] [\fIdirectory\fP ...] - .br - .SH DESCRIPTION - \fITree\fP is a recursive directory listing program that produces a depth -@@ -123,6 +123,19 @@ Prints (implies -D) and formats the date according to the format string - which uses the \fBstrftime\fP(3) syntax. - .PP - .TP -+.B --caseinsensitive -+If a match pattern is specified by the -P option, this will cause the pattern -+to match without regards to the case of each letter. -+.PP -+.TP -+.B --matchdirs -+If a match pattern is specified by the -P option, this will cause the pattern -+to be applied to directory names (in addition to filenames). In the event of a -+match on the directory name, matching is disabled for the directory's -+contents. If the --prune option is used, empty folders that match the pattern -+will not be pruned. -+.PP -+.TP - .B -o \fIfilename\fP - Send output to \fIfilename\fP. - .PP -@@ -314,6 +327,8 @@ Steve Baker (ice@mama.indstate.edu) - HTML output hacked by Francesc Rocher (rocher@econ.udg.es) - .br - Charsets and OS/2 support by Kyosuke Tokoro (NBG01720@nifty.ne.jp) -+.br -+Directory and case matching by Jason A. Donenfeld (Jason@zx2c4.com) - - .SH BUGS AND NOTES - Tree does not prune "empty" directories when the -P and -I options are used by -diff --git a/tree.c b/tree.c -index 19cf368..388aae5 100644 ---- a/tree.c -+++ b/tree.c -@@ -19,16 +19,17 @@ - - #include "tree.h" - --static char *version ="$Version: $ tree v1.6.0 (c) 1996 - 2011 by Steve Baker, Thomas Moore, Francesc Rocher, Kyosuke Tokoro $"; --static char *hversion="\t\t tree v1.6.0 %s 1996 - 2011 by Steve Baker and Thomas Moore
\n" -+static char *version ="$Version: $ tree v1.6.0 (c) 1996 - 2014 by Steve Baker, Thomas Moore, Francesc Rocher, Kyosuke Tokoro, Jason A. Donenfeld $"; -+static char *hversion="\t\t tree v1.6.0 %s 1996 - 2014 by Steve Baker and Thomas Moore
\n" - "\t\t HTML output hacked and copyleft %s 1998 by Francesc Rocher
\n" -- "\t\t Charsets / OS/2 support %s 2001 by Kyosuke Tokoro\n"; -+ "\t\t Charsets / OS/2 support %s 2001 by Kyosuke Tokoro
\n" -+ "\t\t Directory and case matching %s 2014 by Jason A. Donenfeld\n"; - - /* Globals */ - bool dflag, lflag, pflag, sflag, Fflag, aflag, fflag, uflag, gflag; - bool qflag, Nflag, Qflag, Dflag, inodeflag, devflag, hflag, Rflag; - bool Hflag, siflag, cflag, Xflag, duflag, pruneflag; --bool noindent, force_color, nocolor, xdev, noreport, nolinks, flimit, dirsfirst, nosort; -+bool noindent, force_color, nocolor, xdev, noreport, nolinks, flimit, dirsfirst, nosort, matchdirs, caseinsensitive; - char *pattern = NULL, *ipattern = NULL, *host = NULL, *title = "Directory Tree", *sp = " "; - char *timefmt = NULL; - const char *charset = NULL; -@@ -75,12 +76,13 @@ int main(int argc, char **argv) - char sizebuf[64]; - off_t size = 0; - mode_t mt; -+ bool needfulltree; - - q = p = dtotal = ftotal = 0; - aflag = dflag = fflag = lflag = pflag = sflag = Fflag = uflag = gflag = FALSE; - Dflag = qflag = Nflag = Qflag = Rflag = hflag = Hflag = siflag = cflag = FALSE; - noindent = force_color = nocolor = xdev = noreport = nolinks = FALSE; -- dirsfirst = nosort = inodeflag = devflag = Xflag = FALSE; -+ caseinsensitive = matchdirs = dirsfirst = nosort = inodeflag = devflag = Xflag = FALSE; - duflag = pruneflag = FALSE; - flimit = 0; - dirs = xmalloc(sizeof(int) * (maxdirs=4096)); -@@ -350,6 +352,16 @@ int main(int argc, char **argv) - Dflag = TRUE; - break; - } -+ if (!strncmp("--matchdirs",argv[i],11)) { -+ j = strlen(argv[i])-1; -+ matchdirs = TRUE; -+ break; -+ } -+ if (!strncmp("--caseinsensitive",argv[i],17)) { -+ j = strlen(argv[i])-1; -+ caseinsensitive = TRUE; -+ break; -+ } - } - default: - fprintf(stderr,"tree: Invalid argument -`%c'.\n",argv[i][j]); -@@ -387,16 +399,17 @@ int main(int argc, char **argv) - parse_dir_colors(); - initlinedraw(0); - -+ needfulltree = duflag || pruneflag || matchdirs; - /* Set our listdir function and sanity check options. */ - if (Hflag) { -- listdir = (duflag || pruneflag)? html_rlistdir : html_listdir; -+ listdir = needfulltree ? html_rlistdir : html_listdir; - Xflag = FALSE; - } else if (Xflag) { -- listdir = (duflag || pruneflag)? xml_rlistdir : xml_listdir; -+ listdir = needfulltree ? xml_rlistdir : xml_listdir; - colorize = FALSE; - colored = FALSE; /* Do people want colored XML output? */ - } else { -- listdir = (duflag || pruneflag)? unix_rlistdir : unix_listdir; -+ listdir = needfulltree ? unix_rlistdir : unix_listdir; - } - if (dflag) pruneflag = FALSE; /* You'll just get nothing otherwise. */ - -@@ -517,7 +530,8 @@ void usage(int n) - "usage: tree [-acdfghilnpqrstuvxACDFQNSUX] [-H baseHREF] [-T title ] [-L level [-R]]\n" - "\t[-P pattern] [-I pattern] [-o filename] [--version] [--help] [--inodes]\n" - "\t[--device] [--noreport] [--nolinks] [--dirsfirst] [--charset charset]\n" -- "\t[--filelimit[=]#] [--si] [--timefmt[=]] []\n"); -+ "\t[--filelimit[=]#] [--si] [--timefmt[=]] [--matchdirs]\n" -+ "\t[--caseinsensitive] []\n"); - if (n < 2) exit(0); - fprintf(stderr, - " ------- Listing options -------\n" -@@ -534,6 +548,8 @@ void usage(int n) - " --charset X Use charset X for terminal/HTML and indentation line output.\n" - " --filelimit # Do not descend dirs with more than # files in them.\n" - " --timefmt Print and format time according to the format .\n" -+ " --matchdirs Include directory names in -P pattern matching.\n" -+ " --caseinsensitive Match files without regards to case in -P pattern matching.\n" - " -o filename Output to file instead of stdout.\n" - " -------- File options ---------\n" - " -q Print non-printable characters as '?'.\n" -@@ -689,6 +705,8 @@ struct _info **getfulltree(char *d, u_long lev, dev_t dev, off_t *size, char **e - struct _info **dir, **sav, **p, *sp; - struct stat sb; - int n; -+ u_long lev_tmp; -+ char *tmp_pattern = NULL, *start_rel_path; - - *err = NULL; - if (Level >= 0 && lev > Level) return NULL; -@@ -696,7 +714,29 @@ struct _info **getfulltree(char *d, u_long lev, dev_t dev, off_t *size, char **e - stat(d,&sb); - dev = sb.st_dev; - } -+ -+ // if the directory name matches, turn off pattern matching for contents -+ if (matchdirs && pattern) { -+ lev_tmp = lev; -+ for (start_rel_path = d + strlen(d); start_rel_path != d; --start_rel_path) { -+ if (*start_rel_path == '/') -+ --lev_tmp; -+ if (lev_tmp <= 0) { -+ if (*start_rel_path) -+ ++start_rel_path; -+ break; -+ } -+ } -+ if (patmatch(start_rel_path,pattern) == 1) { -+ tmp_pattern = pattern; -+ pattern = NULL; -+ } -+ } - sav = dir = read_dir(d,&n); -+ if (tmp_pattern) { -+ pattern = tmp_pattern; -+ tmp_pattern = NULL; -+ } - if (dir == NULL) { - *err = scopy("error opening dir"); - return NULL; -@@ -745,7 +785,9 @@ struct _info **getfulltree(char *d, u_long lev, dev_t dev, off_t *size, char **e - saveino((*dir)->inode, (*dir)->dev); - (*dir)->child = getfulltree(path,lev+1,dev,&((*dir)->size),&((*dir)->err)); - } -- if (pruneflag && (*dir)->child == NULL) { -+ // prune empty folders, unless they match the requested pattern -+ if (pruneflag && (*dir)->child == NULL && -+ !(matchdirs && pattern && patmatch((*dir)->name,pattern) == 1)) { - sp = *dir; - for(p=dir;*p;p++) *p = *(p+1); - n--; -@@ -869,8 +911,19 @@ char *gnu_getcwd() - } - - /* -+ * Returns a lower case version of the argument if case insensitive -+ * mode is enabled. Note that this is static and inline so that we -+ * do not incur penalty when this is running in a tight loop. -+ */ -+static inline char cond_lower(char c) -+{ -+ return caseinsensitive ? tolower(c) : c; -+} -+ -+/* - * Patmatch() code courtesy of Thomas Moore (dark@mama.indstate.edu) - * '|' support added by David MacMahon (davidm@astron.Berkeley.EDU) -+ * Case insensitive support added by Jason A. Donenfeld (Jason@zx2c4.com) - * returns: - * 1 on a match - * 0 on a mismatch -@@ -918,11 +971,11 @@ int patmatch(char *buf, char *pat) - pat += 2; - if(*pat == '\\' && *pat) - pat++; -- if(*buf >= m && *buf <= *pat) -+ if(cond_lower(*buf) >= cond_lower(m) && cond_lower(*buf) <= cond_lower(*pat)) - match = n; - if(!*pat) - pat--; -- } else if(*buf == *pat) match = n; -+ } else if(cond_lower(*buf) == cond_lower(*pat)) match = n; - pat++; - } - buf++; -@@ -940,7 +993,7 @@ int patmatch(char *buf, char *pat) - if(*pat) - pat++; - default: -- match = (*buf++ == *pat); -+ match = (cond_lower(*buf++) == cond_lower(*pat)); - break; - } - pat++; --- -1.9.2 - diff --git a/src/password-store.sh b/src/password-store.sh index daadac2..00a7fde 100755 --- a/src/password-store.sh +++ b/src/password-store.sh @@ -331,7 +331,7 @@ cmd_show() { else echo "${path%\/}" fi - tree -l --noreport "$PREFIX/$path" | tail -n +2 | sed 's/\.gpg$//' + tree -C -l --noreport "$PREFIX/$path" | tail -n +2 | sed 's/\.gpg$//' else echo "$path is not in the password store." exit 1 @@ -343,21 +343,9 @@ cmd_find() { echo "Usage: $PROGRAM $COMMAND pass-names..." exit 1 fi - if ! tree --version | grep -q "Jason A. Donenfeld"; then - cat <<-_EOF - Error: incompatible tree command. - - Your version of the tree command is missing the relevent patch to add the - --matchdirs and --caseinsensitive switches. Please ask your distribution - to patch your version of tree with: - http://git.zx2c4.com/password-store/plain/contrib/tree-1.6.0-matchdirs.patch - Sorry for the inconvenience. - _EOF - exit 1 - fi local terms="$@" echo "Search Terms: $terms" - tree -l --noreport -P "*${terms// /*|*}*" --prune --matchdirs --caseinsensitive "$PREFIX" | tail -n +2 | sed 's/\.gpg$//' + tree -C -l --noreport -P "*${terms// /*|*}*" --prune --matchdirs --ignore-case "$PREFIX" | tail -n +2 | sed 's/\.gpg$//' } cmd_grep() { -- cgit v1.2.3