├── third_party └── tree │ ├── doc │ ├── tree.1.fr │ ├── xml.dtd │ └── tree.1 │ ├── strverscmp.c │ ├── INSTALL │ ├── BUILD.gn │ ├── TODO │ ├── Makefile │ ├── hash.c │ ├── tree.h │ ├── README │ ├── unix.c │ ├── xml.c │ ├── json.c │ ├── CHANGES │ ├── html.c │ ├── color.c │ ├── LICENSE │ └── tree.c ├── packages └── gn │ └── tree ├── README.md └── .gitignore /third_party/tree/doc/tree.1.fr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucab85/tree-for-FuchsiaOS/HEAD/third_party/tree/doc/tree.1.fr -------------------------------------------------------------------------------- /third_party/tree/strverscmp.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucab85/tree-for-FuchsiaOS/HEAD/third_party/tree/strverscmp.c -------------------------------------------------------------------------------- /packages/gn/tree: -------------------------------------------------------------------------------- 1 | { 2 | "labels": [ 3 | "//third_party/tree" 4 | ], 5 | "binaries": [ 6 | { 7 | "binary": "tree", 8 | "bootfs_path": "bin/tree" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tree for FuchsiaOS 2 | 3 | Port of [tree](http://mama.indstate.edu/users/ice/tree/) util for Fuchsia OS. 4 | 5 | 6 | Step by step guide: 7 | 8 | 1. copy directory "third_party/tree" under "third_party" 9 | 10 | 1. under "packages/gn" 11 | * copy "packages/gn/tree" receipe file 12 | 13 | * add the "tree" receipe to "default" file: 14 | 15 | ``{ 16 | "imports": [ 17 | ... 18 | "tree" 19 | .... 20 | } 21 | `` 22 | -------------------------------------------------------------------------------- /third_party/tree/INSTALL: -------------------------------------------------------------------------------- 1 | Installation instructions: 2 | 3 | 1. Edit the Makefile for your OS. Comment out the Linux options and uncomment 4 | the options for your OS. 5 | 2. Type: make 6 | 3. Type: make install 7 | 4. Enjoy colorful directory trees. 8 | 9 | I cannot test on non-Linux machines, so please feel free to contribute 10 | porting information, bug reports, compile options, patches, etc for porting to 11 | other OS's to ice@mama.indstate.edu. 12 | 13 | I would also welcome any localization efforts, particularly translating the 14 | man page to other languages. And of course feel free to suggest options and 15 | improvements you would like to see in tree. 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | -------------------------------------------------------------------------------- /third_party/tree/BUILD.gn: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The Fuchsia Authors. All rights reserved. 2 | # 3 | # Redistribution and use in source and binary forms, with or without 4 | # modification, are permitted provided that the following conditions are 5 | # met: 6 | # 7 | # * Redistributions of source code must retain the above copyright 8 | # notice, this list of conditions and the following disclaimer. 9 | # * Redistributions in binary form must reproduce the above 10 | # copyright notice, this list of conditions and the following disclaimer 11 | # in the documentation and/or other materials provided with the 12 | # distribution. 13 | # * Neither the name of Google Inc. nor the names of its 14 | # contributors may be used to endorse or promote products derived from 15 | # this software without specific prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | config("tree_config") { 30 | cflags = [ 31 | "-Wno-sign-compare", 32 | "-Wno-format", 33 | ] 34 | } 35 | 36 | executable("tree") { 37 | output_name = "tree" 38 | 39 | sources = [ 40 | "color.c", 41 | "hash.c", 42 | "html.c", 43 | "json.c", 44 | "strverscmp.c", 45 | "tree.c", 46 | "tree.h", 47 | "unix.c", 48 | "xml.c", 49 | ] 50 | 51 | configs += [ 52 | ":tree_config", 53 | ] 54 | 55 | } 56 | -------------------------------------------------------------------------------- /third_party/tree/TODO: -------------------------------------------------------------------------------- 1 | Should do: 2 | - Should be a better way code the various tree formats (XML/HTML/Unix) to 3 | share more code. Probably make a generic tree crawling routine that calls 4 | various function pointers to emit the file information based on the kind 5 | of tree we want. 6 | 7 | - Make wide character support less of a hack. 8 | 9 | - Fully support HTML colorization properly. 10 | 11 | - Go over the -R option for HTML output and make it cleaner & less of a hack. 12 | Should do -R internally so we don't have to rebuild a command line or use 13 | something awful like system(). Should be doable by saving some state and 14 | recursing and also separating out parts of main. 15 | 16 | - Should probably make it so that options like -p, -u, etc print out info for 17 | the top directory, if people think that would be desirable. 18 | 19 | - Might be nice to prune files by things like type, mode, access/modify/change 20 | time, uid/gid, etc. ala find. 21 | 22 | - Just incorporate the stat structure into _info, since we now need most of 23 | the structure anyway. 24 | 25 | Maybe do: 26 | 27 | - With the addition of TREE_COLORS, add some custom options to perhaps colorize 28 | metadata like the permissions, date, username, etc, and change the color of 29 | the tree lines and so on. 30 | 31 | - Make tree look for a .comments file in a directory and append the text from 32 | that file to the output of the files and directories, so that the output 33 | looks like Slackware's README file, like: 34 | 35 | > tree -F --comments 36 | ... 37 | |-- kernels/ Precompiled Linux 2.6.37.6 kernel images. 38 | | | 39 | | |-- hugesmp.s The default standard install kernel for Slackware. 40 | | | This supports pretty much everything in the 41 | | | 2.6.37.6 kernel, and includes support for Speakup. 42 | | | This kernel requires at least a Pentium-Pro processor. 43 | | | 44 | | `-- huge.s A single-processor version of huge.s that will 45 | | function with older hardware such as a 486 with 46 | | 128MB (64MB _might_ work) or more of RAM. 47 | | This kernel also supports Speakup. 48 | ... 49 | 50 | Might be particularly nice for the HTML output, where the comments could be 51 | made as mouse-over popups or the like. 52 | 53 | -------------------------------------------------------------------------------- /third_party/tree/doc/xml.dtd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 29 | 41 | 52 | 63 | 74 | 85 | 96 | 107 | 118 | -------------------------------------------------------------------------------- /third_party/tree/Makefile: -------------------------------------------------------------------------------- 1 | # $Copyright: $ 2 | # Copyright (c) 1996 - 2014 by Steve Baker 3 | # All Rights reserved 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | 19 | prefix = /usr 20 | 21 | CC=gcc 22 | 23 | VERSION=1.7.0 24 | TREE_DEST=tree 25 | BINDIR=${prefix}/bin 26 | MAN=tree.1 27 | MANDIR=${prefix}/man/man1 28 | OBJS=tree.o unix.o html.o xml.o json.o hash.o color.o 29 | 30 | # Uncomment options below for your particular OS: 31 | 32 | # Linux defaults: 33 | CFLAGS=-ggdb -Wall -DLINUX -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 34 | #CFLAGS=-O4 -Wall -DLINUX -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 35 | #LDFLAGS=-s 36 | 37 | # Uncomment for FreeBSD: 38 | #CFLAGS=-O2 -Wall -fomit-frame-pointer 39 | #LDFLAGS=-s 40 | #OBJS+=strverscmp.o 41 | 42 | # Uncomment for Solaris: 43 | #CC=cc 44 | #CFLAGS=-xO0 -v 45 | #LDFLAGS= 46 | #OBJS+=strverscmp.o 47 | #MANDIR=${prefix}/share/man/man1 48 | 49 | # Uncomment for Cygwin: 50 | #CFLAGS=-O2 -Wall -fomit-frame-pointer -DCYGWIN 51 | #LDFLAGS=-s 52 | #TREE_DEST=tree.exe 53 | #OBJS+=strverscmp.o 54 | 55 | # Uncomment for OS X: 56 | #CC=cc 57 | #CFLAGS=-O2 -Wall -fomit-frame-pointer -no-cpp-precomp 58 | #LDFLAGS= 59 | #MANDIR=/usr/share/man/man1 60 | #OBJS+=strverscmp.o 61 | 62 | # Uncomment for HP/UX: 63 | #CC=cc 64 | #CFLAGS=-O2 -DAportable -Wall 65 | #LDFLAGS= 66 | #OBJS+=strverscmp.o 67 | 68 | # Uncomment for OS/2: 69 | #CFLAGS=-02 -Wall -fomit-frame-pointer -Zomf -Zsmall-conv 70 | #LDFLAGS=-s -Zomf -Zsmall-conv 71 | #OBJS+=strverscmp.o 72 | 73 | # Uncomment for HP NonStop: 74 | #prefix = /opt 75 | #CC=c89 76 | #CFLAGS=-Wextensions -WIEEE_float -g -Wnowarn=1506 -D_XOPEN_SOURCE_EXTENDED=1 \ 77 | # -Wallow_cplusplus_comments 78 | #LDFLAGS= 79 | #OBJS+=strverscmp.o 80 | 81 | 82 | #------------------------------------------------------------ 83 | 84 | all: tree 85 | 86 | tree: $(OBJS) 87 | $(CC) $(LDFLAGS) -o $(TREE_DEST) $(OBJS) 88 | 89 | $(OBJS): %.o: %.c tree.h 90 | $(CC) $(CFLAGS) -c -o $@ $< 91 | 92 | clean: 93 | if [ -x $(TREE_DEST) ]; then rm $(TREE_DEST); fi 94 | if [ -f tree.o ]; then rm *.o; fi 95 | rm -f *~ 96 | 97 | install: tree 98 | install -d $(BINDIR) 99 | install -d $(MANDIR) 100 | if [ -e $(TREE_DEST) ]; then \ 101 | install $(TREE_DEST) $(BINDIR)/$(TREE_DEST); \ 102 | fi 103 | install doc/$(MAN) $(MANDIR)/$(MAN) 104 | 105 | distclean: 106 | if [ -f tree.o ]; then rm *.o; fi 107 | rm -f *~ 108 | 109 | 110 | dist: distclean 111 | tar zcf ../tree-$(VERSION).tgz -C .. `cat .tarball` 112 | -------------------------------------------------------------------------------- /third_party/tree/hash.c: -------------------------------------------------------------------------------- 1 | /* $Copyright: $ 2 | * Copyright (c) 1996 - 2014 by Steve Baker (ice@mama.indstate.edu) 3 | * All Rights reserved 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | #include "tree.h" 20 | 21 | /* Faster uid/gid -> name lookup with hash(tm)(r)(c) tables! */ 22 | #define HASH(x) ((x)&255) 23 | struct xtable *gtable[256], *utable[256]; 24 | 25 | #define inohash(x) ((x)&255) 26 | struct inotable *itable[256]; 27 | 28 | char *uidtoname(uid_t uid) 29 | { 30 | struct xtable *o, *p, *t; 31 | struct passwd *ent; 32 | char ubuf[32]; 33 | int uent = HASH(uid); 34 | 35 | for(o = p = utable[uent]; p ; p=p->nxt) { 36 | if (uid == p->xid) return p->name; 37 | else if (uid < p->xid) break; 38 | o = p; 39 | } 40 | /* Not found, do a real lookup and add to table */ 41 | t = xmalloc(sizeof(struct xtable)); 42 | if ((ent = getpwuid(uid)) != NULL) t->name = scopy(ent->pw_name); 43 | else { 44 | snprintf(ubuf,30,"%d",uid); 45 | ubuf[31] = 0; 46 | t->name = scopy(ubuf); 47 | } 48 | t->xid = uid; 49 | t->nxt = p; 50 | if (p == utable[uent]) utable[uent] = t; 51 | else o->nxt = t; 52 | return t->name; 53 | } 54 | 55 | char *gidtoname(gid_t gid) 56 | { 57 | struct xtable *o, *p, *t; 58 | struct group *ent; 59 | char gbuf[32]; 60 | int gent = HASH(gid); 61 | 62 | for(o = p = gtable[gent]; p ; p=p->nxt) { 63 | if (gid == p->xid) return p->name; 64 | else if (gid < p->xid) break; 65 | o = p; 66 | } 67 | /* Not found, do a real lookup and add to table */ 68 | t = xmalloc(sizeof(struct xtable)); 69 | if ((ent = getgrgid(gid)) != NULL) t->name = scopy(ent->gr_name); 70 | else { 71 | snprintf(gbuf,30,"%d",gid); 72 | gbuf[31] = 0; 73 | t->name = scopy(gbuf); 74 | } 75 | t->xid = gid; 76 | t->nxt = p; 77 | if (p == gtable[gent]) gtable[gent] = t; 78 | else o->nxt = t; 79 | return t->name; 80 | } 81 | 82 | /* Record inode numbers of followed sym-links to avoid refollowing them */ 83 | void saveino(ino_t inode, dev_t device) 84 | { 85 | struct inotable *it, *ip, *pp; 86 | int hp = inohash(inode); 87 | 88 | for(pp = ip = itable[hp];ip;ip = ip->nxt) { 89 | if (ip->inode > inode) break; 90 | if (ip->inode == inode && ip->device >= device) break; 91 | pp = ip; 92 | } 93 | 94 | if (ip && ip->inode == inode && ip->device == device) return; 95 | 96 | it = xmalloc(sizeof(struct inotable)); 97 | it->inode = inode; 98 | it->device = device; 99 | it->nxt = ip; 100 | if (ip == itable[hp]) itable[hp] = it; 101 | else pp->nxt = it; 102 | } 103 | 104 | int findino(ino_t inode, dev_t device) 105 | { 106 | struct inotable *it; 107 | 108 | for(it=itable[inohash(inode)]; it; it=it->nxt) { 109 | if (it->inode > inode) break; 110 | if (it->inode == inode && it->device >= device) break; 111 | } 112 | 113 | if (it && it->inode == inode && it->device == device) return TRUE; 114 | return FALSE; 115 | } 116 | -------------------------------------------------------------------------------- /third_party/tree/tree.h: -------------------------------------------------------------------------------- 1 | /* $Copyright: $ 2 | * Copyright (c) 1996 - 2014 by Steve Baker (ice@mama.indstate.edu) 3 | * All Rights reserved 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | 20 | #define _GNU_SOURCE 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #ifdef __EMX__ /* for OS/2 systems */ 37 | # define INCL_DOSFILEMGR 38 | # define INCL_DOSNLS 39 | # include 40 | # include 41 | # include 42 | /* On many systems stat() function is idential to lstat() function. 43 | * But the OS/2 does not support symbolic links and doesn't have lstat() function. 44 | */ 45 | # define lstat stat 46 | # define strcasecmp stricmp 47 | /* Following two functions, getcwd() and chdir() don't support for drive letters. 48 | * To implement support them, use _getcwd2() and _chdir2(). 49 | */ 50 | # define getcwd _getcwd2 51 | # define chdir _chdir2 52 | #endif 53 | 54 | #include 55 | #include 56 | #include 57 | #include 58 | 59 | #ifdef __ANDROID 60 | #define mbstowcs(w,m,x) mbsrtowcs(w,(const char**)(& #m),x,NULL) 61 | #endif 62 | 63 | /* Should probably use strdup(), but we like our xmalloc() */ 64 | #define scopy(x) strcpy(xmalloc(strlen(x)+1),(x)) 65 | #define MINIT 30 /* number of dir entries to initially allocate */ 66 | #define MINC 20 /* allocation increment */ 67 | 68 | #ifndef TRUE 69 | typedef enum {FALSE=0, TRUE} bool; 70 | #else 71 | typedef int bool; 72 | #endif 73 | 74 | struct _info { 75 | char *name; 76 | char *lnk; 77 | bool isdir; 78 | bool issok; 79 | bool isfifo; 80 | bool isexe; 81 | bool orphan; 82 | mode_t mode, lnkmode; 83 | uid_t uid; 84 | gid_t gid; 85 | off_t size; 86 | time_t atime, ctime, mtime; 87 | dev_t dev; 88 | ino_t inode; 89 | #ifdef __EMX__ 90 | long attr; 91 | #endif 92 | char *err; 93 | struct _info **child; 94 | }; 95 | /* hash.c */ 96 | struct xtable { 97 | unsigned int xid; 98 | char *name; 99 | struct xtable *nxt; 100 | }; 101 | struct inotable { 102 | ino_t inode; 103 | dev_t device; 104 | struct inotable *nxt; 105 | }; 106 | 107 | /* color.c */ 108 | struct colortable { 109 | char *term_flg, *CSS_name, *font_fg, *font_bg; 110 | }; 111 | struct extensions { 112 | char *ext; 113 | char *term_flg, *CSS_name, *web_fg, *web_bg, *web_extattr; 114 | struct extensions *nxt; 115 | }; 116 | struct linedraw { 117 | const char **name, *vert, *vert_left, *corner, *copy; 118 | }; 119 | 120 | /* Function prototypes: */ 121 | /* tree.c */ 122 | void usage(int); 123 | struct _info **getfulltree(char *d, u_long lev, dev_t dev, off_t *size, char **err); 124 | struct _info **read_dir(char *, int *); 125 | 126 | int alnumsort(struct _info **, struct _info **); 127 | int versort(struct _info **a, struct _info **b); 128 | int reversealnumsort(struct _info **, struct _info **); 129 | int mtimesort(struct _info **, struct _info **); 130 | int ctimesort(struct _info **, struct _info **); 131 | int sizecmp(off_t a, off_t b); 132 | int fsizesort(struct _info **a, struct _info **b); 133 | 134 | void *xmalloc(size_t), *xrealloc(void *, size_t); 135 | char *gnu_getcwd(); 136 | int patmatch(char *, char *); 137 | void indent(int maxlevel); 138 | void free_dir(struct _info **); 139 | #ifdef __EMX__ 140 | char *prot(long); 141 | #else 142 | char *prot(mode_t); 143 | #endif 144 | char *do_date(time_t); 145 | void printit(char *); 146 | int psize(char *buf, off_t size); 147 | char Ftype(mode_t mode); 148 | char *fillinfo(char *buf, struct _info *ent); 149 | 150 | /* unix.c */ 151 | off_t unix_listdir(char *d, int *dt, int *ft, u_long lev, dev_t dev); 152 | off_t unix_rlistdir(char *d, int *dt, int *ft, u_long lev, dev_t dev); 153 | void r_listdir(struct _info **dir, char *d, int *dt, int *ft, u_long lev); 154 | 155 | /* html.c */ 156 | void emit_html_header(const char *charset, char *title, char *version); 157 | off_t html_listdir(char *d, int *dt, int *ft, u_long lev, dev_t dev); 158 | off_t html_rlistdir(char *d, int *dt, int *ft, u_long lev, dev_t dev); 159 | void htmlr_listdir(struct _info **dir, char *d, int *dt, int *ft, u_long lev); 160 | void html_encode(FILE *fd, char *s); 161 | 162 | /* xml.c */ 163 | off_t xml_listdir(char *d, int *dt, int *ft, u_long lev, dev_t dev); 164 | off_t xml_rlistdir(char *d, int *dt, int *ft, u_long lev, dev_t dev); 165 | void xmlr_listdir(struct _info **dir, char *d, int *dt, int *ft, u_long lev); 166 | void xml_indent(int maxlevel); 167 | void xml_fillinfo(struct _info *ent); 168 | 169 | /* json.c */ 170 | off_t json_listdir(char *d, int *dt, int *ft, u_long lev, dev_t dev); 171 | off_t json_rlistdir(char *d, int *dt, int *ft, u_long lev, dev_t dev); 172 | void jsonr_listdir(struct _info **dir, char *d, int *dt, int *ft, u_long lev); 173 | void json_indent(int maxlevel); 174 | void json_fillinfo(struct _info *ent); 175 | 176 | /* color.c */ 177 | void parse_dir_colors(); 178 | int color(u_short mode, char *name, bool orphan, bool islink); 179 | const char *getcharset(void); 180 | void initlinedraw(int); 181 | 182 | /* hash.c */ 183 | char *uidtoname(uid_t uid); 184 | char *gidtoname(gid_t gid); 185 | int findino(ino_t, dev_t); 186 | void saveino(ino_t, dev_t); 187 | 188 | /* We use the strverscmp.c file if we're not linux */ 189 | #if ! defined (LINUX) 190 | int strverscmp (const char *s1, const char *s2); 191 | #endif 192 | -------------------------------------------------------------------------------- /third_party/tree/README: -------------------------------------------------------------------------------- 1 | Please read the INSTALL file for installation instructions, particularly if 2 | you are installing on a non-Linux machine. 3 | 4 | This is a handy little utility to display a tree view of directories that 5 | I wrote some time ago and just added color support to. I've decided that 6 | since no one else has done something similar I would go ahead and release 7 | it, even though it's barely a 1st year CS student hack. I've found it damn 8 | handy to peruse a directory tree though, especially when someone is trying to 9 | hide something from you. 10 | 11 | The main distribution site for tree is here: 12 | 13 | http://mama.indstate.edu/users/ice/tree/ 14 | ftp://mama.indstate.edu/linux/tree/ 15 | 16 | If you don't like the way it looks let me know how you think it should be 17 | formatted. Feel free to suggest modifications and additions. 18 | 19 | Thanks go out so the following people who have helped bring tree to the 20 | pinnacle of perfection that it is: ;) 21 | 22 | Francesc Rocher 23 | - Added HTML output (-H). 24 | - Added options -o, -L and -R. 25 | 26 | Gerald Scheidl 27 | - Added -S option to print ASCII graphics lines for use under linux 28 | console when an alternate console font has been selected (might also 29 | work under DOS telnet). 30 | 31 | Guido Socher (and others) 32 | - Made tree more portable. Should compile under solaris. 33 | 34 | Mitja Lacen 35 | - Discovered bug where tree will segmentation fault on long pathnames. 36 | - Discovered in -L argument processing. 37 | 38 | Nathaniel Delage 39 | - Discovered problem with recursive symlink detection 40 | 41 | A. Karthik 42 | - Suggested option to remove file and directory report at end of tree 43 | listing. 44 | 45 | Roger Luethi 46 | - Spotted memory over-allocation bug in read_dir(). 47 | - Submitted several patches to fix various memory leaks. 48 | 49 | Daniel Lee 50 | - Reported that Tru64 defines TRUE/FALSE in sys/types.h (OSF1 standard?) 51 | 52 | Paolo Violini 53 | - Found bug in tree that caused it to seg-fault if 50 file arguments where 54 | given and directory coloring was turned on. 55 | 56 | Mitsuaki Masuhara 57 | - Discovered tree crashed on missing arguments. 58 | - Discovered that tree did not properly encode characters in filenames 59 | when used as URLs when using the -H option. 60 | - Fixed issue with --charset option processing. 61 | 62 | Johan Fredrik 63 | - Pointed out that tree did not list large files. 64 | 65 | Ted Tiberio 66 | - Submitted patch which fixed a compiler issue and cleaned up HTML and CSS 67 | code, applied CSS to all output, and fixed up HTML to 4.01 strict 68 | standards. 69 | 70 | David MacMahon 71 | - Added '|' support to the pattern matching routines. 72 | 73 | Dan Jacobson 74 | - Pointed out that -t did not sort properly for files with the same 75 | timestamp. 76 | - Suggested option to change HTML title and H1 string. 77 | - Suggested -r option for reversed alphanumeric sort ala 'ls -r'. 78 | 79 | Kyosuke Tokoro 80 | - Provided patch to support OS/2, fix HTML encoding, provide charset 81 | support. Added to authors list. 82 | 83 | Florian Ernst 84 | - Debian maintainer who pointed out problems and applied fire to feet to fix 85 | stuff. 86 | 87 | Jack Cuyler 88 | - Suggested -h option for human readable output for -s, ala ls -lh. 89 | 90 | Jonathon Cranford 91 | - Supplied patch to make tree under cygwin. 92 | 93 | Richard Houser 94 | - Provided patch to fix a colorization bug when dealing with special 95 | files and directories that seem to have an extension. 96 | 97 | Zurd (?) 98 | - Suggested removing trailing slash on user supplied directory names if -f 99 | option is used. 100 | 101 | John Nintendud 102 | - Pointed out broken HTML output in 1.5.1. 103 | 104 | Mark Braker 105 | - Suggested --filelimit option. 106 | 107 | Michael Vogt 108 | - Suggested -v option (version sort). 109 | 110 | Wang Quanhong 111 | - Provided build options for Solaris. 112 | 113 | Craig McDaniel 114 | - Provided build options and source mods for HP NonStop support. 115 | 116 | Christian Grigis 117 | - Noted that setlocale() should come before MB_CUR_MAX check. 118 | 119 | Kamaraju Kusumanchi 120 | - Submitted patch to remove compiler warnings for Solaris. 121 | 122 | Martin Nagy 123 | - Provided patch which fixes issue where indent may output more than it 124 | should when dirs[*] is not properly cleared before use. 125 | 126 | William C. Lathan III 127 | - Showed that tree was not properly quoting arguments to recursively called 128 | tree instances when using -R. 129 | 130 | Ulrich Eckhardt 131 | - Submitted patch for --si option. 132 | 133 | Tim Waugh (redhat) 134 | - Pointed out a potential memory leak in listdir(). 135 | 136 | Markus Schnalke 137 | - Tracked down bug where tree would print "argetm" before the filename of a 138 | symbolic link when the "target" option was specified for LINK in dircolors. 139 | 140 | Ujjwal Kumar 141 | - Suggested that tree backslash spaces like ls does for script use. Made 142 | output more like ls. 143 | 144 | Ivan Shmakov 145 | - Pointed out multiple CLI defenciencies (via Debian) 146 | 147 | Mantas Mikulnas 148 | - Provided patch to make tree more reliably detect the UTF-8 locale. 149 | 150 | Tim Mooney 151 | - Noticed S_ISDOOR/S_IFDOOR spelling mistake for under Solaris. 152 | 153 | Han Hui 154 | - Pointed out possible memory overflow in read_dir (path/lbuf not equal in size 155 | to pathsize/lbufsize.) 156 | 157 | Ryan Hollis 158 | - Pointed out problems with the Makefile w/ respect to OSX. 159 | 160 | Philipp M?ller 161 | - Provided patch for filesize sorting. 162 | 163 | Sascha Zorn 164 | - Pointed out that the HTML output was broken when -L 1 option was used. 165 | 166 | Alexandre Wendling 167 | - Pointed out that modern systems may use 32 bit uid/gids which could lead 168 | to a potential buffer overflow in the uid/gid to name mapping functions. 169 | 170 | Florian Sesser 171 | - Provided patch to add JSON support. 172 | 173 | Brian Mattern & Jason A. Donenfeld 174 | - Provided patch to add --matchdirs functionality. 175 | 176 | Jason A. Donenfeld 177 | - Added --caseinsentive, renamed --ignore-case option. 178 | - Bugged me a lot. 179 | 180 | 181 | And many others whom I've failed to keep track of. I should have started 182 | this list years ago. 183 | 184 | - Steve Baker 185 | ice@mama.indstate.edu 186 | -------------------------------------------------------------------------------- /third_party/tree/unix.c: -------------------------------------------------------------------------------- 1 | /* $Copyright: $ 2 | * Copyright (c) 1996 - 2014 by Steve Baker (ice@mama.indstate.edu) 3 | * All Rights reserved 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | #include "tree.h" 20 | 21 | extern bool dflag, lflag, pflag, sflag, Fflag, aflag, fflag, uflag, gflag; 22 | extern bool Dflag, inodeflag, devflag, Rflag, duflag, pruneflag; 23 | extern bool noindent, force_color, xdev, nolinks, flimit; 24 | 25 | extern void (*listdir)(char *, int *, int *, u_long, dev_t); 26 | extern int (*cmpfunc)(); 27 | extern FILE *outfile; 28 | extern int Level, *dirs, maxdirs; 29 | 30 | extern bool colorize, linktargetcolor; 31 | extern char *endcode; 32 | 33 | off_t unix_listdir(char *d, int *dt, int *ft, u_long lev, dev_t dev) 34 | { 35 | char *path; 36 | bool nlf = FALSE, colored = FALSE; 37 | long pathsize = 0; 38 | struct _info **dir, **sav; 39 | struct stat sb; 40 | int n, c; 41 | 42 | if ((Level >= 0) && (lev > Level)) { 43 | fputc('\n',outfile); 44 | return 0; 45 | } 46 | 47 | if (xdev && lev == 0) { 48 | stat(d,&sb); 49 | dev = sb.st_dev; 50 | } 51 | 52 | sav = dir = read_dir(d,&n); 53 | if (!dir && n) { 54 | fprintf(outfile," [error opening dir]\n"); 55 | return 0; 56 | } 57 | if (!n) { 58 | fputc('\n', outfile); 59 | free_dir(sav); 60 | return 0; 61 | } 62 | if (flimit > 0 && n > flimit) { 63 | fprintf(outfile," [%d entries exceeds filelimit, not opening dir]\n",n); 64 | free_dir(sav); 65 | return 0; 66 | } 67 | 68 | if (cmpfunc) qsort(dir,n,sizeof(struct _info *), cmpfunc); 69 | if (lev >= maxdirs-1) { 70 | dirs = xrealloc(dirs,sizeof(int) * (maxdirs += 1024)); 71 | memset(dirs+(maxdirs-1024), 0, sizeof(int) * 1024); 72 | } 73 | dirs[lev] = 1; 74 | if (!*(dir+1)) dirs[lev] = 2; 75 | fprintf(outfile,"\n"); 76 | 77 | path = malloc(pathsize=4096); 78 | 79 | while(*dir) { 80 | if (!noindent) indent(lev); 81 | 82 | fillinfo(path,*dir); 83 | if (path[0] == ' ') { 84 | path[0] = '['; 85 | fprintf(outfile, "%s] ",path); 86 | } 87 | 88 | if (colorize) { 89 | if ((*dir)->lnk && linktargetcolor) colored = color((*dir)->lnkmode,(*dir)->name,(*dir)->orphan,FALSE); 90 | else colored = color((*dir)->mode,(*dir)->name,(*dir)->orphan,FALSE); 91 | } 92 | 93 | if (fflag) { 94 | if (sizeof(char) * (strlen(d)+strlen((*dir)->name)+2) > pathsize) 95 | path=xrealloc(path,pathsize=(sizeof(char) * (strlen(d)+strlen((*dir)->name)+1024))); 96 | if (!strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name); 97 | else sprintf(path,"%s/%s",d,(*dir)->name); 98 | } else { 99 | if (sizeof(char) * (strlen((*dir)->name)+1) > pathsize) 100 | path=xrealloc(path,pathsize=(sizeof(char) * (strlen((*dir)->name)+1024))); 101 | sprintf(path,"%s",(*dir)->name); 102 | } 103 | 104 | printit(path); 105 | 106 | if (colored) fprintf(outfile,"%s",endcode); 107 | if (Fflag && !(*dir)->lnk) { 108 | if ((c = Ftype((*dir)->mode))) fputc(c, outfile); 109 | } 110 | 111 | if ((*dir)->lnk) { 112 | fprintf(outfile," -> "); 113 | if (colorize) colored = color((*dir)->lnkmode,(*dir)->lnk,(*dir)->orphan,TRUE); 114 | printit((*dir)->lnk); 115 | if (colored) fprintf(outfile,"%s",endcode); 116 | if (Fflag) { 117 | if ((c = Ftype((*dir)->lnkmode))) fputc(c, outfile); 118 | } 119 | } 120 | 121 | if ((*dir)->isdir) { 122 | if ((*dir)->lnk) { 123 | if (lflag && !(xdev && dev != (*dir)->dev)) { 124 | if (findino((*dir)->inode,(*dir)->dev)) { 125 | fprintf(outfile," [recursive, not followed]"); 126 | } else { 127 | saveino((*dir)->inode, (*dir)->dev); 128 | if (*(*dir)->lnk == '/') 129 | listdir((*dir)->lnk,dt,ft,lev+1,dev); 130 | else { 131 | if (strlen(d)+strlen((*dir)->lnk)+2 > pathsize) path=xrealloc(path,pathsize=(strlen(d)+strlen((*dir)->name)+1024)); 132 | if (fflag && !strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->lnk); 133 | else sprintf(path,"%s/%s",d,(*dir)->lnk); 134 | listdir(path,dt,ft,lev+1,dev); 135 | } 136 | nlf = TRUE; 137 | } 138 | } 139 | } else if (!(xdev && dev != (*dir)->dev)) { 140 | if (strlen(d)+strlen((*dir)->name)+2 > pathsize) path=xrealloc(path,pathsize=(strlen(d)+strlen((*dir)->name)+1024)); 141 | if (fflag && !strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name); 142 | else sprintf(path,"%s/%s",d,(*dir)->name); 143 | saveino((*dir)->inode, (*dir)->dev); 144 | listdir(path,dt,ft,lev+1,dev); 145 | nlf = TRUE; 146 | } 147 | *dt += 1; 148 | } else *ft += 1; 149 | if (*(dir+1) && !*(dir+2)) dirs[lev] = 2; 150 | if (nlf) nlf = FALSE; 151 | else fprintf(outfile,"\n"); 152 | dir++; 153 | } 154 | dirs[lev] = 0; 155 | free(path); 156 | free_dir(sav); 157 | return 0; 158 | } 159 | 160 | off_t unix_rlistdir(char *d, int *dt, int *ft, u_long lev, dev_t dev) 161 | { 162 | struct _info **dir; 163 | off_t size = 0; 164 | char *err; 165 | 166 | dir = getfulltree(d, lev, dev, &size, &err); 167 | 168 | memset(dirs, 0, sizeof(int) * maxdirs); 169 | 170 | r_listdir(dir, d, dt, ft, lev); 171 | 172 | return size; 173 | } 174 | 175 | void r_listdir(struct _info **dir, char *d, int *dt, int *ft, u_long lev) 176 | { 177 | char *path; 178 | long pathsize = 0; 179 | struct _info **sav = dir; 180 | bool nlf = FALSE, colored = FALSE; 181 | int c; 182 | 183 | if (dir == NULL) return; 184 | 185 | dirs[lev] = 1; 186 | if (!*(dir+1)) dirs[lev] = 2; 187 | fprintf(outfile,"\n"); 188 | 189 | path = malloc(pathsize=4096); 190 | 191 | while(*dir) { 192 | if (!noindent) indent(lev); 193 | 194 | fillinfo(path,*dir); 195 | if (path[0] == ' ') { 196 | path[0] = '['; 197 | fprintf(outfile, "%s] ",path); 198 | } 199 | 200 | if (colorize) { 201 | if ((*dir)->lnk && linktargetcolor) colored = color((*dir)->lnkmode,(*dir)->name,(*dir)->orphan,FALSE); 202 | else colored = color((*dir)->mode,(*dir)->name,(*dir)->orphan,FALSE); 203 | } 204 | 205 | if (fflag) { 206 | if (sizeof(char) * (strlen(d)+strlen((*dir)->name)+2) > pathsize) 207 | path=xrealloc(path,pathsize=(sizeof(char) * (strlen(d)+strlen((*dir)->name)+1024))); 208 | if (!strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name); 209 | else sprintf(path,"%s/%s",d,(*dir)->name); 210 | } else { 211 | if (sizeof(char) * (strlen((*dir)->name)+1) > pathsize) 212 | path=xrealloc(path,pathsize=(sizeof(char) * (strlen((*dir)->name)+1024))); 213 | sprintf(path,"%s",(*dir)->name); 214 | } 215 | 216 | printit(path); 217 | 218 | if (colored) fprintf(outfile,"%s",endcode); 219 | if (Fflag && !(*dir)->lnk) { 220 | if ((c = Ftype((*dir)->mode))) fputc(c, outfile); 221 | } 222 | 223 | if ((*dir)->lnk) { 224 | fprintf(outfile," -> "); 225 | if (colorize) colored = color((*dir)->lnkmode,(*dir)->lnk,(*dir)->orphan,TRUE); 226 | printit((*dir)->lnk); 227 | if (colored) fprintf(outfile,"%s",endcode); 228 | if (Fflag) { 229 | if ((c = Ftype((*dir)->lnkmode))) fputc(c, outfile); 230 | } 231 | } 232 | 233 | if ((*dir)->err) { 234 | fprintf(outfile," [%s]", (*dir)->err); 235 | free((*dir)->err); 236 | (*dir)->err = NULL; 237 | } 238 | if ((*dir)->child) { 239 | if (fflag) { 240 | if (strlen(d)+strlen((*dir)->name)+2 > pathsize) path=xrealloc(path,pathsize=(strlen(d)+strlen((*dir)->name)+1024)); 241 | if (!strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name); 242 | else sprintf(path,"%s/%s",d,(*dir)->name); 243 | } 244 | r_listdir((*dir)->child, fflag? path : NULL, dt, ft, lev+1); 245 | nlf = TRUE; 246 | *dt += 1; 247 | } else { 248 | if ((*dir)->isdir) *dt += 1; 249 | else *ft += 1; 250 | } 251 | 252 | if (*(dir+1) && !*(dir+2)) dirs[lev] = 2; 253 | if (nlf) nlf = FALSE; 254 | else fprintf(outfile,"\n"); 255 | dir++; 256 | } 257 | dirs[lev] = 0; 258 | free(path); 259 | free_dir(sav); 260 | } 261 | -------------------------------------------------------------------------------- /third_party/tree/xml.c: -------------------------------------------------------------------------------- 1 | /* $Copyright: $ 2 | * Copyright (c) 1996 - 2014 by Steve Baker (ice@mama.indstate.edu) 3 | * All Rights reserved 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | #include "tree.h" 20 | 21 | extern bool dflag, lflag, pflag, sflag, Fflag, aflag, fflag, uflag, gflag; 22 | extern bool Dflag, inodeflag, devflag, Rflag, cflag; 23 | extern bool noindent, force_color, xdev, nolinks, flimit; 24 | 25 | extern const int ifmt[]; 26 | extern const char fmt[], *ftype[]; 27 | 28 | extern void (*listdir)(char *, int *, int *, u_long, dev_t); 29 | extern int (*cmpfunc)(); 30 | extern FILE *outfile; 31 | extern int Level, *dirs, maxdirs; 32 | 33 | extern char *endcode; 34 | 35 | /* 36 | 37 | 38 | 39 | ... if link is followed, otherwise this is empty. 40 | 41 | 42 | some error 43 | 44 | 45 | 46 | 47 | 48 | ... 49 | 50 | 51 | # 52 | # 53 | # 54 | 55 | 56 | */ 57 | 58 | 59 | off_t xml_listdir(char *d, int *dt, int *ft, u_long lev, dev_t dev) 60 | { 61 | char *path; 62 | bool nlf = FALSE; 63 | long pathsize = 0; 64 | struct _info **dir, **sav; 65 | struct stat sb; 66 | int t, n, mt; 67 | 68 | if ((Level >= 0) && (lev > Level)) { 69 | if (!noindent) fputc('\n',outfile); 70 | return 0; 71 | } 72 | 73 | if (xdev && lev == 0) { 74 | stat(d,&sb); 75 | dev = sb.st_dev; 76 | } 77 | 78 | sav = dir = read_dir(d,&n); 79 | if (!dir && n) { 80 | fprintf(outfile,"opening dir\n"); 81 | return 0; 82 | } 83 | if (!n) { 84 | if (!noindent) fputc('\n', outfile); 85 | free_dir(sav); 86 | return 0; 87 | } 88 | if (flimit > 0 && n > flimit) { 89 | fprintf(outfile,"%d entries exceeds filelimit, not opening dir%s",n,noindent?"":"\n"); 90 | free_dir(sav); 91 | return 0; 92 | } 93 | 94 | if (cmpfunc) qsort(dir,n,sizeof(struct _info *), cmpfunc); 95 | if (lev >= maxdirs-1) { 96 | dirs = xrealloc(dirs,sizeof(int) * (maxdirs += 1024)); 97 | memset(dirs+(maxdirs-1024), 0, sizeof(int) * 1024); 98 | } 99 | dirs[lev] = 1; 100 | if (!*(dir+1)) dirs[lev] = 2; 101 | if (!noindent) fprintf(outfile,"\n"); 102 | 103 | path = malloc(pathsize=4096); 104 | 105 | while(*dir) { 106 | if (!noindent) xml_indent(lev); 107 | 108 | if ((*dir)->lnk) mt = (*dir)->mode & S_IFMT; 109 | else mt = (*dir)->mode & S_IFMT; 110 | for(t=0;ifmt[t];t++) 111 | if (ifmt[t] == mt) break; 112 | fprintf(outfile,"<%s", ftype[t]); 113 | 114 | if (fflag) { 115 | if (sizeof(char) * (strlen(d)+strlen((*dir)->name)+2) > pathsize) 116 | path=xrealloc(path,pathsize=(sizeof(char) * (strlen(d)+strlen((*dir)->name)+1024))); 117 | if (!strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name); 118 | else sprintf(path,"%s/%s",d,(*dir)->name); 119 | } else { 120 | if (sizeof(char) * (strlen((*dir)->name)+1) > pathsize) 121 | path=xrealloc(path,pathsize=(sizeof(char) * (strlen((*dir)->name)+1024))); 122 | sprintf(path,"%s",(*dir)->name); 123 | } 124 | 125 | fprintf(outfile, " name=\""); 126 | html_encode(outfile,path); 127 | fputc('"',outfile); 128 | 129 | if ((*dir)->lnk) { 130 | fprintf(outfile, " target=\""); 131 | html_encode(outfile,(*dir)->lnk); 132 | fputc('"',outfile); 133 | } 134 | xml_fillinfo(*dir); 135 | fputc('>',outfile); 136 | 137 | if ((*dir)->isdir) { 138 | if ((*dir)->lnk) { 139 | if (lflag && !(xdev && dev != (*dir)->dev)) { 140 | if (findino((*dir)->inode,(*dir)->dev)) { 141 | fprintf(outfile,"recursive, not followed"); 142 | } else { 143 | saveino((*dir)->inode, (*dir)->dev); 144 | if (*(*dir)->lnk == '/') 145 | listdir((*dir)->lnk,dt,ft,lev+1,dev); 146 | else { 147 | if (strlen(d)+strlen((*dir)->lnk)+2 > pathsize) path=xrealloc(path,pathsize=(strlen(d)+strlen((*dir)->name)+1024)); 148 | if (fflag && !strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->lnk); 149 | else sprintf(path,"%s/%s",d,(*dir)->lnk); 150 | listdir(path,dt,ft,lev+1,dev); 151 | } 152 | nlf = TRUE; 153 | } 154 | } 155 | } else if (!(xdev && dev != (*dir)->dev)) { 156 | if (strlen(d)+strlen((*dir)->name)+2 > pathsize) path=xrealloc(path,pathsize=(strlen(d)+strlen((*dir)->name)+1024)); 157 | if (fflag && !strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name); 158 | else sprintf(path,"%s/%s",d,(*dir)->name); 159 | saveino((*dir)->inode, (*dir)->dev); 160 | listdir(path,dt,ft,lev+1,dev); 161 | nlf = TRUE; 162 | } 163 | *dt += 1; 164 | } else *ft += 1; 165 | if (*(dir+1) && !*(dir+2)) dirs[lev] = 2; 166 | if (nlf) { 167 | nlf = FALSE; 168 | if (!noindent) xml_indent(lev); 169 | } 170 | fprintf(outfile,"%s",ftype[t],noindent?"":"\n"); 171 | dir++; 172 | } 173 | dirs[lev] = 0; 174 | free(path); 175 | free_dir(sav); 176 | return 0; 177 | } 178 | 179 | off_t xml_rlistdir(char *d, int *dt, int *ft, u_long lev, dev_t dev) 180 | { 181 | struct _info **dir; 182 | off_t size = 0; 183 | char *err; 184 | 185 | dir = getfulltree(d, lev, dev, &size, &err); 186 | 187 | memset(dirs, 0, sizeof(int) * maxdirs); 188 | 189 | xmlr_listdir(dir, d, dt, ft, lev); 190 | 191 | return size; 192 | } 193 | 194 | void xmlr_listdir(struct _info **dir, char *d, int *dt, int *ft, u_long lev) 195 | { 196 | char *path; 197 | long pathsize = 0; 198 | struct _info **sav = dir; 199 | bool nlf = FALSE; 200 | int mt, t; 201 | 202 | if (dir == NULL) return; 203 | 204 | dirs[lev] = 1; 205 | if (!*(dir+1)) dirs[lev] = 2; 206 | fprintf(outfile,"\n"); 207 | 208 | path = malloc(pathsize=4096); 209 | 210 | while(*dir) { 211 | if (!noindent) xml_indent(lev); 212 | 213 | if ((*dir)->lnk) mt = (*dir)->mode & S_IFMT; 214 | else mt = (*dir)->mode & S_IFMT; 215 | for(t=0;ifmt[t];t++) 216 | if (ifmt[t] == mt) break; 217 | fprintf(outfile,"<%s", ftype[t]); 218 | 219 | if (fflag) { 220 | if (sizeof(char) * (strlen(d)+strlen((*dir)->name)+2) > pathsize) 221 | path=xrealloc(path,pathsize=(sizeof(char) * (strlen(d)+strlen((*dir)->name)+1024))); 222 | if (!strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name); 223 | else sprintf(path,"%s/%s",d,(*dir)->name); 224 | } else { 225 | if (sizeof(char) * (strlen((*dir)->name)+1) > pathsize) 226 | path=xrealloc(path,pathsize=(sizeof(char) * (strlen((*dir)->name)+1024))); 227 | sprintf(path,"%s",(*dir)->name); 228 | } 229 | 230 | fprintf(outfile, " name=\""); 231 | html_encode(outfile,path); 232 | fputc('"',outfile); 233 | 234 | if ((*dir)->lnk) { 235 | fprintf(outfile, " target=\""); 236 | html_encode(outfile,(*dir)->lnk); 237 | fputc('"',outfile); 238 | } 239 | 240 | xml_fillinfo(*dir); 241 | if (mt != S_IFDIR && mt != S_IFLNK && (*dir)->err == NULL) fprintf(outfile,"/>"); 242 | else fputc('>',outfile); 243 | 244 | if ((*dir)->err) { 245 | fprintf(outfile,"%s", (*dir)->err); 246 | free((*dir)->err); 247 | (*dir)->err = NULL; 248 | } 249 | if ((*dir)->child) { 250 | if (fflag) { 251 | if (strlen(d)+strlen((*dir)->name)+2 > pathsize) path=xrealloc(path,pathsize=(strlen(d)+strlen((*dir)->name)+1024)); 252 | if (!strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name); 253 | else sprintf(path,"%s/%s",d,(*dir)->name); 254 | } 255 | xmlr_listdir((*dir)->child, fflag? path : NULL, dt, ft, lev+1); 256 | nlf = TRUE; 257 | *dt += 1; 258 | } else { 259 | if ((*dir)->isdir) *dt += 1; 260 | else *ft += 1; 261 | } 262 | 263 | if (*(dir+1) && !*(dir+2)) dirs[lev] = 2; 264 | if (nlf) { 265 | nlf = FALSE; 266 | if (!noindent) xml_indent(lev); 267 | } 268 | if (mt == S_IFDIR || mt == S_IFLNK || (*dir)->err != NULL) fprintf(outfile,"\n",ftype[t]); 269 | else putc('\n',outfile); 270 | dir++; 271 | } 272 | dirs[lev] = 0; 273 | free(path); 274 | free_dir(sav); 275 | } 276 | 277 | void xml_indent(int maxlevel) 278 | { 279 | int i; 280 | 281 | fprintf(outfile, " "); 282 | for(i=0; iinode); 290 | #else 291 | if (inodeflag) fprintf(outfile," inode=\"%ld\"",(long int)ent->inode); 292 | #endif 293 | if (devflag) fprintf(outfile, " dev=\"%d\"", (int)ent->dev); 294 | #ifdef __EMX__ 295 | if (pflag) fprintf(outfile, " mode=\"%04o\" prot=\"%s\"",ent->attr, prot(ent->attr)); 296 | #else 297 | if (pflag) fprintf(outfile, " mode=\"%04o\" prot=\"%s\"", ent->mode & (S_IRWXU|S_IRWXG|S_IRWXO|S_ISUID|S_ISGID|S_ISVTX), prot(ent->mode)); 298 | #endif 299 | if (uflag) fprintf(outfile, " user=\"%s\"", uidtoname(ent->uid)); 300 | if (gflag) fprintf(outfile, " group=\"%s\"", gidtoname(ent->gid)); 301 | if (sflag) fprintf(outfile, " size=\"%lld\"", (long long int)(ent->size)); 302 | if (Dflag) fprintf(outfile, " time=\"%s\"", do_date(cflag? ent->ctime : ent->mtime)); 303 | } 304 | -------------------------------------------------------------------------------- /third_party/tree/json.c: -------------------------------------------------------------------------------- 1 | /* $Copyright: $ 2 | * Copyright (c) 1996 - 2014 by Steve Baker (ice@mama.indstate.edu) 3 | * All Rights reserved 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | #include "tree.h" 20 | 21 | extern bool dflag, lflag, pflag, sflag, Fflag, aflag, fflag, uflag, gflag; 22 | extern bool Dflag, inodeflag, devflag, Rflag, cflag; 23 | extern bool noindent, force_color, xdev, nolinks, flimit; 24 | 25 | extern const int ifmt[]; 26 | extern const char fmt[], *ftype[]; 27 | 28 | extern void (*listdir)(char *, int *, int *, u_long, dev_t); 29 | extern int (*cmpfunc)(); 30 | extern FILE *outfile; 31 | extern int Level, *dirs, maxdirs; 32 | 33 | extern char *endcode; 34 | 35 | /* JSON code courtesy of Florian Sesser 36 | [ 37 | {"type": "directory", "name": "name", "mode": "0777", "user": "user", "group": "group", "inode": ###, "dev": ####, "time": "00:00 00-00-0000", "contents": [ 38 | {"type": "link", "name": "name", "target": "name", "contents": [... if link is followed, otherwise this is empty.]} 39 | {"type": "file", "name": "name", "mode": "0777", "size": ###, "group": "group", "inode": ###, "dev": ###, "time": "00:00 00-00-0000"} 40 | {"type": "socket", "name": "", "error": "some error" ...} 41 | {"type": "block", "name": "" ...}, 42 | {"type": "char", "name": "" ...}, 43 | {"type": "fifo", "name": "" ...}, 44 | {"type": "door", "name": "" ...}, 45 | {"type": "port", "name": "" ...} 46 | ]}, 47 | {"type": "report", "size": ###, "files": ###, "directories": ###} 48 | ] 49 | */ 50 | 51 | off_t json_listdir(char *d, int *dt, int *ft, u_long lev, dev_t dev) 52 | { 53 | char *path; 54 | bool nlf = FALSE; 55 | long pathsize = 0; 56 | struct _info **dir, **sav; 57 | struct stat sb; 58 | int t, n, mt; 59 | 60 | if ((Level >= 0) && (lev > Level)) { 61 | if (!noindent) fputc('\n',outfile); 62 | return 0; 63 | } 64 | 65 | if (xdev && lev == 0) { 66 | stat(d,&sb); 67 | dev = sb.st_dev; 68 | } 69 | 70 | sav = dir = read_dir(d,&n); 71 | if (!dir && n) { 72 | fprintf(outfile,"{\"error\": \"opening dir\"}%s",noindent?"":"\n"); 73 | return 0; 74 | } 75 | if (!n) { 76 | if (!noindent) fputc('\n', outfile); 77 | free_dir(sav); 78 | return 0; 79 | } 80 | if (flimit > 0 && n > flimit) { 81 | fprintf(outfile,", \"error\": \"%d entries exceeds filelimit, not opening dir\"\n",n); 82 | free_dir(sav); 83 | return 0; 84 | } 85 | 86 | if (cmpfunc) qsort(dir,n,sizeof(struct _info *),cmpfunc); 87 | if (lev >= maxdirs-1) { 88 | dirs = xrealloc(dirs,sizeof(int) * (maxdirs += 1024)); 89 | memset(dirs+(maxdirs-1024), 0, sizeof(int) * 1024); 90 | } 91 | dirs[lev] = 1; 92 | if (!*(dir+1)) dirs[lev] = 2; 93 | if (!noindent) fprintf(outfile,"\n"); 94 | 95 | path = malloc(pathsize=4096); 96 | 97 | while(*dir) { 98 | if (!noindent) json_indent(lev); 99 | 100 | if ((*dir)->lnk) mt = (*dir)->mode & S_IFMT; 101 | else mt = (*dir)->mode & S_IFMT; 102 | for(t=0;ifmt[t];t++) 103 | if (ifmt[t] == mt) break; 104 | fprintf(outfile,"{\"type\":\"%s\"", ftype[t]); 105 | 106 | if (fflag) { 107 | if (sizeof(char) * (strlen(d)+strlen((*dir)->name)+2) > pathsize) 108 | path=xrealloc(path,pathsize=(sizeof(char) * (strlen(d)+strlen((*dir)->name)+1024))); 109 | if (!strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name); 110 | else sprintf(path,"%s/%s",d,(*dir)->name); 111 | } else { 112 | if (sizeof(char) * (strlen((*dir)->name)+1) > pathsize) 113 | path=xrealloc(path,pathsize=(sizeof(char) * (strlen((*dir)->name)+1024))); 114 | sprintf(path,"%s",(*dir)->name); 115 | } 116 | 117 | fprintf(outfile, ",\"name\":\""); 118 | html_encode(outfile,path); 119 | fputc('"',outfile); 120 | 121 | if ((*dir)->lnk) { 122 | fprintf(outfile, ",\"target\":\""); 123 | html_encode(outfile,(*dir)->lnk); 124 | fputc('"',outfile); 125 | } 126 | json_fillinfo(*dir); 127 | if (!(*dir)->isdir && !(*dir)->lnk) { 128 | fputc('}',outfile); 129 | if (*(dir+1)) fputc(',',outfile); 130 | } else 131 | fprintf(outfile, ",\"contents\":["); 132 | 133 | if ((*dir)->isdir) { 134 | if ((*dir)->lnk) { 135 | if (lflag && !(xdev && dev != (*dir)->dev)) { 136 | if (findino((*dir)->inode,(*dir)->dev)) { 137 | fprintf(outfile,"{\"error\":\"recursive, not followed\"}"); 138 | } else { 139 | saveino((*dir)->inode, (*dir)->dev); 140 | if (*(*dir)->lnk == '/') 141 | listdir((*dir)->lnk,dt,ft,lev+1,dev); 142 | else { 143 | if (strlen(d)+strlen((*dir)->lnk)+2 > pathsize) path=xrealloc(path,pathsize=(strlen(d)+strlen((*dir)->name)+1024)); 144 | if (fflag && !strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->lnk); 145 | else sprintf(path,"%s/%s",d,(*dir)->lnk); 146 | listdir(path,dt,ft,lev+1,dev); 147 | } 148 | nlf = TRUE; 149 | } 150 | } 151 | } else if (!(xdev && dev != (*dir)->dev)) { 152 | if (strlen(d)+strlen((*dir)->name)+2 > pathsize) path=xrealloc(path,pathsize=(strlen(d)+strlen((*dir)->name)+1024)); 153 | if (fflag && !strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name); 154 | else sprintf(path,"%s/%s",d,(*dir)->name); 155 | saveino((*dir)->inode, (*dir)->dev); 156 | listdir(path,dt,ft,lev+1,dev); 157 | nlf = TRUE; 158 | } 159 | *dt += 1; 160 | } else *ft += 1; 161 | if (*(dir+1) && !*(dir+2)) dirs[lev] = 2; 162 | if (nlf) { 163 | nlf = FALSE; 164 | if (!noindent) json_indent(lev); 165 | } 166 | if ((*dir)->isdir || (*dir)->lnk) { 167 | fprintf(outfile, "]}"); 168 | if (*(dir+1)) fputc(',',outfile); 169 | } 170 | if (!noindent) fputc('\n', outfile); 171 | dir++; 172 | } 173 | dirs[lev] = 0; 174 | free(path); 175 | free_dir(sav); 176 | return 0; 177 | } 178 | 179 | off_t json_rlistdir(char *d, int *dt, int *ft, u_long lev, dev_t dev) 180 | { 181 | struct _info **dir; 182 | off_t size = 0; 183 | char *err; 184 | 185 | dir = getfulltree(d, lev, dev, &size, &err); 186 | 187 | memset(dirs, 0, sizeof(int) * maxdirs); 188 | 189 | jsonr_listdir(dir, d, dt, ft, lev); 190 | 191 | return size; 192 | } 193 | 194 | void jsonr_listdir(struct _info **dir, char *d, int *dt, int *ft, u_long lev) 195 | { 196 | char *path; 197 | long pathsize = 0; 198 | struct _info **sav = dir; 199 | bool nlf = FALSE; 200 | int mt, t; 201 | 202 | if (dir == NULL) return; 203 | 204 | dirs[lev] = 1; 205 | if (!*(dir+1)) dirs[lev] = 2; 206 | if (!noindent) fprintf(outfile,"\n"); 207 | 208 | path = malloc(pathsize=4096); 209 | 210 | while(*dir) { 211 | if (!noindent) json_indent(lev); 212 | 213 | if ((*dir)->lnk) mt = (*dir)->mode & S_IFMT; 214 | else mt = (*dir)->mode & S_IFMT; 215 | for(t=0;ifmt[t];t++) 216 | if (ifmt[t] == mt) break; 217 | fprintf(outfile,"{\"type\":\"%s\"", ftype[t]); 218 | 219 | if (fflag) { 220 | if (sizeof(char) * (strlen(d)+strlen((*dir)->name)+2) > pathsize) 221 | path=xrealloc(path,pathsize=(sizeof(char) * (strlen(d)+strlen((*dir)->name)+1024))); 222 | if (!strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name); 223 | else sprintf(path,"%s/%s",d,(*dir)->name); 224 | } else { 225 | if (sizeof(char) * (strlen((*dir)->name)+1) > pathsize) 226 | path=xrealloc(path,pathsize=(sizeof(char) * (strlen((*dir)->name)+1024))); 227 | sprintf(path,"%s",(*dir)->name); 228 | } 229 | 230 | fprintf(outfile, ",\"name\":\""); 231 | html_encode(outfile,path); 232 | fputc('"',outfile); 233 | 234 | if ((*dir)->lnk) { 235 | fprintf(outfile, ",\"target\":\""); 236 | html_encode(outfile,(*dir)->lnk); 237 | fputc('"',outfile); 238 | } 239 | 240 | json_fillinfo(*dir); 241 | if (mt != S_IFDIR && mt != S_IFLNK && (*dir)->err == NULL) fprintf(outfile,"},"); 242 | else fprintf(outfile, ",\"contents\":["); 243 | 244 | if ((*dir)->err) { 245 | fprintf(outfile,",\"error\":\"%s\"", (*dir)->err); 246 | free((*dir)->err); 247 | (*dir)->err = NULL; 248 | } 249 | if ((*dir)->child) { 250 | if (fflag) { 251 | if (strlen(d)+strlen((*dir)->name)+2 > pathsize) path=xrealloc(path,pathsize=(strlen(d)+strlen((*dir)->name)+1024)); 252 | if (!strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name); 253 | else sprintf(path,"%s/%s",d,(*dir)->name); 254 | } 255 | jsonr_listdir((*dir)->child, fflag? path : NULL, dt, ft, lev+1); 256 | nlf = TRUE; 257 | *dt += 1; 258 | } else { 259 | if ((*dir)->isdir) *dt += 1; 260 | else *ft += 1; 261 | } 262 | 263 | if (*(dir+1) && !*(dir+2)) dirs[lev] = 2; 264 | if (nlf) { 265 | nlf = FALSE; 266 | if (!noindent) json_indent(lev); 267 | } 268 | if (mt == S_IFDIR || mt == S_IFLNK || (*dir)->err != NULL) fprintf(outfile,"]},%s",noindent?"":"\n"); 269 | else { 270 | if (!noindent) putc('\n',outfile); 271 | } 272 | dir++; 273 | } 274 | dirs[lev] = 0; 275 | free(path); 276 | free_dir(sav); 277 | } 278 | 279 | void json_indent(int maxlevel) 280 | { 281 | int i; 282 | 283 | fprintf(outfile, " "); 284 | for(i=0; iinode); 292 | #else 293 | if (inodeflag) fprintf(outfile,",\"inode\":%ld",(long int)ent->inode); 294 | #endif 295 | if (devflag) fprintf(outfile, ",\"dev\":%d", (int)ent->dev); 296 | #ifdef __EMX__ 297 | if (pflag) fprintf(outfile, ",\"mode\":\"%04o\",\"prot\":\"%s\"",ent->attr, prot(ent->attr)); 298 | #else 299 | if (pflag) fprintf(outfile, ",\"mode\":\"%04o\",\"prot\":\"%s\"", ent->mode & (S_IRWXU|S_IRWXG|S_IRWXO|S_ISUID|S_ISGID|S_ISVTX), prot(ent->mode)); 300 | #endif 301 | if (uflag) fprintf(outfile, ",\"user\":\"%s\"", uidtoname(ent->uid)); 302 | if (gflag) fprintf(outfile, ",\"group\":\"%s\"", gidtoname(ent->gid)); 303 | if (sflag) fprintf(outfile, ",\"size\":%lld", (long long int)ent->size); 304 | if (Dflag) fprintf(outfile, ",\"time\":\"%s\"", do_date(cflag? ent->ctime : ent->mtime)); 305 | } 306 | -------------------------------------------------------------------------------- /third_party/tree/CHANGES: -------------------------------------------------------------------------------- 1 | Version 1.7.0 2 | - Allow user/group names up to 32 characters before clipping. 3 | - Made -i compress XML and JSON output as much as possible by eliminating 4 | extraneous whitespace. 5 | - Added --caseinsensitive (renamed --ignore-case ala grep) flag so patterns 6 | match without regard to case, courtesy of Jason A Donenfeld. 7 | - Added --matchdirs option courtesy of Brian Mattern & Jason A. Donenfeld 8 | . 9 | - Fixed possible buffer overflow on large uid/gids w/o user names/group 10 | names (Alexandre Wendling ) 11 | - Added JSON support courtesy of Florian Sesser . 12 | - Fixed formatting error with HTML output when -L 1 specified. (Sascha Zorn 13 | ) 14 | - Added file size sorting (Philipp M?ller ) 15 | - Added '--sort[=]' option, ala ls. 16 | - Fixed OS X makefile problems (Ryan Hollis ) 17 | - Fixed possible memory overflow in read_dir (path/lbuf not equal in size 18 | to pathsize/lbufsize.) (Han Hui ) 19 | - Fix S_ISDOOR/S_IFDOOR spelling mistake for Solaris. (Tim Mooney 20 | ) 21 | - Make tree more reliably detect UTF-8 locales. (Mantas Mikulnas 22 | and others.) 23 | - Return non-zero exit status on option errors, print usage to stdout when 24 | not an error, add the posix '--' option terminator, Change -S description 25 | to mean CP437 (console) output codes, not ASCII. (Ivan Shmakov 26 | ) 27 | 28 | Version 1.6.0 29 | - Re-org of code into multiple files, split HTML and Unix listdir() into 30 | separate functions, various code cleanups and optimizations. 31 | - Fixed a memory leak in listdir() when memory was allocated early and not 32 | freed before function exit. 33 | - Fixed possible buffer overflow where symbolic links are followed. 34 | - Fixed links printing "argetm" before the name of the link when the LINK 35 | setting for DIR_COLORS is set to target (Markus Schnalke 36 | ) 37 | - More fully support dir colors -- added support for su, sg, tw, ow, & st 38 | options (and "do" in theory). 39 | - Use the environment variable "TREE_COLORS" instead of "LS_COLORS" for 40 | color information if it exists. 41 | - Added --si flag to print filesizes in SI (powers of 1000) units (Ulrich 42 | Eckhardt) 43 | - Added -Q to quote filenames in double quotes. Does not override -N or -q. 44 | - Control characters are no longer printed in carrot notation, but as 45 | backslashed octal, ala ls, except for codes 7-13 which are printed as 46 | \a, \b, \t, \n, \v, \f and \r respectively. Spaces and backslashes are 47 | also now backslashed as per ls, for better input to scripts unless -Q 48 | is in use (where "'s are backslashed.) (Ujjwal Kumar) 49 | - Added -U for unsorted listings (directory order). 50 | - Added -c for sorting by last status change (ala ls -c). 51 | - --dirsfirst is now a meta-sort and does not override -c, -v, -r or -t, but 52 | is disabled by -U. 53 | - After many requests, added the ability to process the entire tree before 54 | emitting output. Used for the new options --du, which works like the du 55 | command: sums the amount of space under each directory and prints a total 56 | amount used in the report and the --prune option which will prune all empty 57 | directories from the output (makes the -P option output much more readable.) 58 | It should be noted that this will be slow to output when processing large 59 | directory trees and can consume copious amounts of memory, use at your own 60 | peril. 61 | - Added -X option to emit the directory tree in XML format (turns colorization 62 | off always.) 63 | - Added --timefmt option to specify the format of time display (implies -D). 64 | Uses the strftime format. 65 | 66 | Version 1.5.3 67 | - Properly quote directories for the system command when tree is relaunched 68 | using the -R option. 69 | - Fixed possible indentation problem if dirs[*] is not properly zeroed 70 | (Martin Nagy). 71 | - Use strcoll() instead of strcmp() to sort files based on locale if set. 72 | - Change "const static" to "static const" to remove some compiler warnings 73 | for Solaris (Kamaraju Kusumanchi). 74 | - Actually use TREE_CHARSET if it's defined. 75 | - Automatically select UTF-8 charset if TREE_CHARSET is not set, and the 76 | locale is set to *UTF-8 (overridden with --charset option.) 77 | 78 | Version 1.5.2.2 79 | - Set locale before checking MB_CUR_MAX. 80 | - Added HP-NonStop platform support (Craig McDaniel ) 81 | - Fixed to support 32 bit UID/GIDs. 82 | - Added Solaris build options to Makefile (edit and uncomment to use). 83 | Provided by Wang Quanhong 84 | 85 | Version 1.5.2.1 86 | - Added strverscmp.c file for os's without strverscmp. Source file is 87 | attributed to: Jean-Franois Bignolles 88 | - Try different approach to MB_CUR_MAX problem. 89 | - Changed the argument to printit() to be signed char to avoid warnings. 90 | 91 | Version 1.5.2 92 | - Added --filelimit X option to not descend directories that have more than 93 | X number of files in them. 94 | - Added -v option for version sorting (also called natural sorting) ala ls. 95 | 96 | Version 1.5.1.2 97 | - Fixed compile issues related to MB_CUR_MAX on non-linux machines. 98 | - Removed unecessary features.h 99 | 100 | Version 1.5.1.1 101 | - Regression in HTML output, fixed formatting issues. 102 | 103 | Version 1.5.1 104 | - Remove extraneous / at end of user input directory names when using -f 105 | option (Zurd) 106 | - List available charsets if --charset option is missing charset argument. 107 | - Fixed --charset option processing bug. 108 | - Fixed missing
's when -i option used with -H. 109 | - Added -h option for human readable output. 110 | - Colorization bugfix for special files and directories (make tree behave as 111 | ls does) 112 | 113 | Version 1.5.0 114 | - Added -T option to change title and H1 header in HTML output. 115 | - Added -r option to reverse alpha sort output, ala. 'ls -r'. 116 | - '|' wildcard support added by David MacMahon . 117 | - Remove extraneous '/' at the end of dirs and dir-symlinks in HTML output. 118 | - Removed several possible overflow problems by dynamically allocating 119 | arrays in several places. 120 | - Better support for Locales and printing utf-8 encoded characters in 121 | filenames (still hackish). 122 | - Fixed -t to alphasort files with same time-stamps. 123 | - Fixed encoding of filenames in HTML output, Kyosuke and others. 124 | - Patches by Kyosuke Tokoro : 125 | - Now, runs OS/2 systems. 126 | + Print the file attributes in 'adhrs' format for each file, instead 127 | of the protections in 'drwxrwxrwx' format, when running the tree 128 | on OS/2 with option -p. 129 | - Added --charset option, to specify which character set is used for 130 | output. 131 | + You can specify any IANA registered character set name. But I have 132 | tested only following character sets: 133 | Shift_JIS EUC-JP IBM850 134 | UTF-8 ISO-8859-1 US-ASCII 135 | + Now, `-S' option is equal to `--charset=IBM437'. 136 | + When running on OS/2 systems, the default value of this option 137 | is according to current codepage. On the other systems, no default. 138 | - Change font-weight to font-size in CSS .VERSION. 139 | - Change version to standard major.minor.patch format. 140 | - Switch from artistic license to GPLv2. 141 | 142 | Version 1.4 143 | - Added large file support under Linux. 144 | - Fixed crashing on missing command line arguments. 145 | - Fixed several memory leaks 146 | - Added --dirsfirst option to list directories first. 147 | - Fixed formatting error when unable to open directories. 148 | - Fixed bug in parse_dir_colors(). 149 | - Changed -I to also ignore directories. 150 | - Added --nolinks command to turn off hyperlinks with the HTML output. 151 | - Fixed several memory leaks in listdir(). 152 | - Some additional code cleanup in listdir(). 153 | - Some systems may define TRUE/FALSE, so don't create the enums for TRUE 154 | and FALSE if that's the case. 155 | - Fixed over-allocation bug in read_dir(). 156 | - Added crude beginnings of color output for HTML via CSS (Ted Tiberio 157 | ttiberio@rochester.rr.com). 158 | - Fixed buffer overflow problem in dircolors parsing. 159 | - Fixed recursive symlink detection. 160 | - Added --inodes and --device options. 161 | - Added --noreport option. 162 | 163 | Version 1.3 164 | - Fixed long pathname problem by dynamically allocating the path. 165 | - Added recursive symlink detection. 166 | - Added --help and --version options. 167 | - When -C is used and LS_COLORS is undefined, tree uses a default color 168 | scheme (thus -C always forces color output now). 169 | - Added -S to show ASCII tree lines (Gerald Scheidl) 170 | - Made tree more portable (Guido Socher and others) 171 | 172 | Following options courtesy of Francesc Rocher: 173 | - Added -o to redirect the output. 174 | - Added -H to print the tree in HTML format. 175 | - Added -L to set the maximum level of directories to print. 176 | - Added -R to recursively restart the search at the level given by `-L' 177 | option (adding as well `-o 00Tree.html'). 178 | 179 | Version 1.2 180 | - Added -D to print the date of the last modification. 181 | - Added -t option to sort by last modification time (ala ls -t). 182 | - Added -I , similar to the -P option except tree does not print 183 | those files which match the pattern. 184 | - Made tree print non-printable characters in filenames in standard unix 185 | carrot notation. 186 | - Added -N option to make tree print filenames without any processing. 187 | - Added -q option to make tree print non-printable characters in filenames 188 | as question marks. 189 | - Added `|' to -F output and made it only print character type after the 190 | link on sym-links, not on the symlink name itself. 191 | - Added -u option to display username/uid, and -g option to display group 192 | name/gid. 193 | - Fully (pass the salt) implemented dircolors support. 194 | 195 | Version 1.1 196 | - Made some changes to the Makefile to insure proper installation and for 197 | multi-architecture support and a bug-fix. 198 | - Made root directory colorized if dircolors is enabled. 199 | - Put []'s around permission and size info, 'cause I think it looks better. 200 | - Added -A option to enable ANSI-lines hack. 201 | - Added some sanity checks for dircolors support. 202 | - Added -P to list only those files that match the wildcard 203 | given in . 204 | - Fixed error where relative symbolic links to directories would not be 205 | followed when the -l option was used. 206 | - Made uid 0 the same as anyone else (-a was default for uid 0) 207 | - Added -x directive to stay on one filesystem (ala find -xdev). 208 | 209 | Version 1.0 210 | - The original, a model of perfection... 211 | -------------------------------------------------------------------------------- /third_party/tree/doc/tree.1: -------------------------------------------------------------------------------- 1 | .\" $Copyright: $ 2 | .\" Copyright (c) 1996 - 2012 by Steve Baker 3 | .\" All Rights reserved 4 | .\" 5 | .\" This program is free software; you can redistribute it and/or modify 6 | .\" it under the terms of the GNU General Public License as published by 7 | .\" the Free Software Foundation; either version 2 of the License, or 8 | .\" (at your option) any later version. 9 | .\" 10 | .\" This program is distributed in the hope that it will be useful, 11 | .\" but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | .\" GNU General Public License for more details. 14 | .\" 15 | .\" You should have received a copy of the GNU General Public License 16 | .\" along with this program; if not, write to the Free Software 17 | .\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | .\" 19 | ... 20 | .TH TREE 1 "" "Tree 1.7.0" 21 | .SH NAME 22 | tree \- list contents of directories in a tree-like format. 23 | .SH SYNOPSIS 24 | \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--matchdirs\fP] [\fB--\fP] [\fIdirectory\fP ...] 25 | 26 | .br 27 | .SH DESCRIPTION 28 | \fITree\fP is a recursive directory listing program that produces a depth 29 | indented listing of files, which is colorized ala \fIdircolors\fP if the 30 | \fBLS_COLORS\fP environment variable is set and output is to tty. With no 31 | arguments, \fItree\fP lists the files in the current directory. When directory 32 | arguments are given, \fItree\fP lists all the files and/or directories found in 33 | the given directories each in turn. Upon completion of listing all 34 | files/directories found, \fItree\fP returns the total number of files and/or 35 | directories listed. 36 | 37 | By default, when a symbolic link is encountered, the path that the symbolic 38 | link refers to is printed after the name of the link in the format: 39 | .br 40 | 41 | name -> real-path 42 | .br 43 | 44 | If the `\fB-l\fP' option is given and the symbolic link refers to an actual 45 | directory, then \fItree\fP will follow the path of the symbolic link as if 46 | it were a real directory. 47 | .br 48 | 49 | .SH OPTIONS 50 | \fITree\fP understands the following command line switches: 51 | 52 | .SH LISTING OPTIONS 53 | 54 | .TP 55 | .B -a 56 | All files are printed. By default tree does not print hidden files (those 57 | beginning with a dot `.'). In no event does tree print the file system 58 | constructs `.' (current directory) and `..' (previous directory). 59 | .PP 60 | .TP 61 | .B -d 62 | List directories only. 63 | .PP 64 | .TP 65 | .B -l 66 | Follows symbolic links if they point to directories, as if they were 67 | directories. Symbolic links that will result in recursion are avoided when 68 | detected. 69 | .PP 70 | .TP 71 | .B -f 72 | Prints the full path prefix for each file. 73 | .PP 74 | .TP 75 | .B -x 76 | Stay on the current file-system only. Ala \fBfind \fI-xdev\fP. 77 | .PP 78 | .TP 79 | .B -L \fIlevel\fP 80 | Max display depth of the directory tree. 81 | .PP 82 | .TP 83 | .B -R 84 | Recursively cross down the tree each \fIlevel\fP directories (see \fB-L\fP 85 | option), and at each of them execute \fBtree\fP again adding `-o 00Tree.html' 86 | as a new option. 87 | .PP 88 | .TP 89 | .B -P \fIpattern\fP 90 | List only those files that match the wild-card \fIpattern\fP. Note: you must 91 | use the \fI-a\fP option to also consider those files beginning with a dot `.' 92 | for matching. Valid wildcard operators are `*' (any zero or more characters), 93 | `?' (any single character), `[...]' (any single character listed between 94 | brackets (optional - (dash) for character range may be used: ex: [A-Z]), and 95 | `[^...]' (any single character not listed in brackets) and `|' separates 96 | alternate patterns. 97 | .PP 98 | .TP 99 | .B -I \fIpattern\fP 100 | Do not list those files that match the wild-card \fIpattern\fP. 101 | .PP 102 | .TP 103 | .B --ignore-case 104 | If a match pattern is specified by the \fB-P\fP or \fB-I\fP option, this will 105 | cause the pattern to match without regards to the case of each letter. 106 | .PP 107 | .TP 108 | .B --matchdirs 109 | If a match pattern is specified by the \fB-P\fP option, this will cause the 110 | pattern to be applied to directory names (in addition to filenames). In the 111 | event of a match on the directory name, matching is disabled for the directory's 112 | contents. If the \fB--prune\fP option is used, empty folders that match the 113 | pattern will not be pruned. 114 | .PP 115 | .TP 116 | .B --prune 117 | Makes tree prune empty directories from the output, useful when used in 118 | conjunction with \fB-P\fP or \fB-I\fP. See \fBBUGS AND NOTES\fP below for 119 | more information on this option. 120 | .PP 121 | .TP 122 | .B --noreport 123 | Omits printing of the file and directory report at the end of the tree 124 | listing. 125 | .PP 126 | .TP 127 | .B --charset \fIcharset\fP 128 | Set the character set to use when outputting HTML and for line drawing. 129 | .PP 130 | .TP 131 | .B --filelimit \fI#\fP 132 | Do not descend directories that contain more than \fI#\fP entries. 133 | .PP 134 | .TP 135 | .B --timefmt \fIformat\fP 136 | Prints (implies -D) and formats the date according to the format string 137 | which uses the \fBstrftime\fP(3) syntax. 138 | .PP 139 | .TP 140 | .B -o \fIfilename\fP 141 | Send output to \fIfilename\fP. 142 | .PP 143 | 144 | .SH FILE OPTIONS 145 | 146 | .TP 147 | .B -q 148 | Print non-printable characters in filenames as question marks instead of the 149 | default. 150 | .PP 151 | .TP 152 | .B -N 153 | Print non-printable characters as is instead of as escaped octal numbers. 154 | .PP 155 | .TP 156 | .B -Q 157 | Quote the names of files in double quotes. 158 | .PP 159 | .TP 160 | .B -p 161 | Print the file type and permissions for each file (as per ls -l). 162 | .PP 163 | .TP 164 | .B -u 165 | Print the username, or UID # if no username is available, of the file. 166 | .PP 167 | .TP 168 | .B -g 169 | Print the group name, or GID # if no group name is available, of the file. 170 | .PP 171 | .TP 172 | .B -s 173 | Print the size of each file in bytes along with the name. 174 | .PP 175 | .TP 176 | .B -h 177 | Print the size of each file but in a more human readable way, e.g. appending a 178 | size letter for kilobytes (K), megabytes (M), gigabytes (G), terabytes (T), 179 | petabytes (P) and exabytes (E). 180 | .PP 181 | .TP 182 | .B --si 183 | Like \fB-h\fP but use SI units (powers of 1000) instead. 184 | .PP 185 | .TP 186 | .B --du 187 | For each directory report its size as the accumulation of sizes of all its files 188 | and sub-directories (and their files, and so on). The total amount of used 189 | space is also given in the final report (like the 'du -c' command.) This option 190 | requires tree to read the entire directory tree before emitting it, see 191 | \fBBUGS AND NOTES\fP below. Implies \fB-s\fP. 192 | .PP 193 | .TP 194 | .B -D 195 | Print the date of the last modification time or if \fB-c\fP is used, the last 196 | status change time for the file listed. 197 | .PP 198 | .TP 199 | .B -F 200 | Append a `/' for directories, a `=' for socket files, a `*' for executable 201 | files, a `>' for doors (Solaris) and a `|' for FIFO's, as per ls -F 202 | .PP 203 | .TP 204 | .B --inodes 205 | Prints the inode number of the file or directory 206 | .PP 207 | .TP 208 | .B --device 209 | Prints the device number to which the file or directory belongs 210 | .PP 211 | 212 | .SH SORTING OPTIONS 213 | 214 | .TP 215 | .B -v 216 | Sort the output by version. 217 | .PP 218 | .TP 219 | .B -t 220 | Sort the output by last modification time instead of alphabetically. 221 | .PP 222 | .TP 223 | .B -c 224 | Sort the output by last status change instead of alphabetically. Modifies the 225 | \fB-D\fP option (if used) to print the last status change instead of 226 | modification time. 227 | .PP 228 | .TP 229 | .B -U 230 | Do not sort. Lists files in directory order. Disables \fB--dirsfirst\fP. 231 | .PP 232 | .TP 233 | .B -r 234 | Sort the output in reverse order. This is a meta-sort that alter the above sorts. 235 | This option is disabled when \fB-U\fP is used. 236 | .PP 237 | .TP 238 | .B --dirsfirst 239 | List directories before files. This is a meta-sort that alters the above sorts. 240 | This option is disabled when \fB-U\fP is used. 241 | .PP 242 | .TP 243 | .B --sort[=] 244 | Sort the output by name (as per ls): name (default), ctime (\fP-c\fP), mtime 245 | (\fP-t\fB), size or version (\fP-v\fB). 246 | .SH GRAPHICS OPTIONS 247 | 248 | .TP 249 | .B -i 250 | Makes tree not print the indentation lines, useful when used in conjunction 251 | with the \fB-f\fP option. Also removes as much whitespace as possible when used 252 | with the \fB-J\fP or \fB-x\fP options. 253 | .PP 254 | .TP 255 | .B -A 256 | Turn on ANSI line graphics hack when printing the indentation lines. 257 | .PP 258 | .TP 259 | .B -S 260 | Turn on CP437 line graphics (useful when using Linux console mode fonts). This 261 | option is now equivalent to `--charset=IBM437' and may eventually be depreciated. 262 | .PP 263 | .TP 264 | .B -n 265 | Turn colorization off always, over-ridden by the \fB-C\fP option. 266 | .PP 267 | .TP 268 | .B -C 269 | Turn colorization on always, using built-in color defaults if the LS_COLORS 270 | environment variable is not set. Useful to colorize output to a pipe. 271 | .PP 272 | 273 | .SH XML/JSON/HTML OPTIONS 274 | 275 | .TP 276 | .B -X 277 | Turn on XML output. Outputs the directory tree as an XML formatted file. 278 | .PP 279 | .TP 280 | .B -J 281 | Turn on JSON output. Outputs the directory tree as an JSON formatted array. 282 | .PP 283 | .TP 284 | .B -H \fIbaseHREF\fP 285 | Turn on HTML output, including HTTP references. Useful for ftp sites. 286 | \fIbaseHREF\fP gives the base ftp location when using HTML output. That is, the 287 | local directory may be `/local/ftp/pub', but it must be referenced as 288 | `ftp://hostname.organization.domain/pub' (\fIbaseHREF\fP should be 289 | `ftp://hostname.organization.domain'). Hint: don't use ANSI lines with this 290 | option, and don't give more than one directory in the directory list. If you 291 | wish to use colors via CCS style-sheet, use the -C option in addition to this 292 | option to force color output. 293 | .PP 294 | .TP 295 | .B -T \fItitle\fP 296 | Sets the title and H1 header string in HTML output mode. 297 | .PP 298 | .TP 299 | .B --nolinks 300 | Turns off hyperlinks in HTML output. 301 | .PP 302 | 303 | .SH MISC OPTIONS 304 | 305 | .TP 306 | .B --help 307 | Outputs a verbose usage listing. 308 | .PP 309 | .TP 310 | .B --version 311 | Outputs the version of tree. 312 | .PP 313 | .TP 314 | .B -- 315 | Option processing terminator. No further options will be processed after this. 316 | .PP 317 | 318 | .br 319 | .SH FILES 320 | /etc/DIR_COLORS System color database. 321 | .br 322 | ~/.dircolors Users color database. 323 | .br 324 | 325 | .SH ENVIRONMENT 326 | \fBLS_COLORS\fP Color information created by dircolors 327 | .br 328 | \fBTREE_COLORS\fP Uses this for color information over LS_COLORS if it is set. 329 | .br 330 | \fBTREE_CHARSET\fP Character set for tree to use in HTML mode. 331 | .br 332 | \fBLC_CTYPE\fP Locale for filename output. 333 | .br 334 | \fBLC_TIME\fP Locale for timefmt output, see \fBstrftime\fP(3). 335 | .br 336 | \fBTZ\fP Timezone for timefmt output, see \fBstrftime\fP(3). 337 | 338 | .SH AUTHOR 339 | Steve Baker (ice@mama.indstate.edu) 340 | .br 341 | HTML output hacked by Francesc Rocher (rocher@econ.udg.es) 342 | .br 343 | Charsets and OS/2 support by Kyosuke Tokoro (NBG01720@nifty.ne.jp) 344 | 345 | .SH BUGS AND NOTES 346 | Tree does not prune "empty" directories when the -P and -I options are used by 347 | default. Use the --prune option. 348 | 349 | The -h and --si options round to the nearest whole number unlike the ls 350 | implementations which rounds up always. 351 | 352 | Pruning files and directories with the -I, -P and --filelimit options will 353 | lead to incorrect file/directory count reports. 354 | 355 | The --prune and --du options cause tree to accumulate the entire tree in memory 356 | before emitting it. For large directory trees this can cause a significant delay 357 | in output and the use of large amounts of memory. 358 | 359 | The timefmt expansion buffer is limited to a ridiculously large 255 characters. 360 | Output of time strings longer than this will be undefined, but are guaranteed 361 | to not exceed 255 characters. 362 | 363 | XML/JSON trees are not colored, which is a bit of a shame. 364 | 365 | Probably more. 366 | 367 | .SH SEE ALSO 368 | .BR dircolors (1), 369 | .BR ls (1), 370 | .BR find (1), 371 | .BR du (1), 372 | .BR strftime (3) 373 | -------------------------------------------------------------------------------- /third_party/tree/html.c: -------------------------------------------------------------------------------- 1 | /* $Copyright: $ 2 | * Copyright (c) 1996 - 2014 by Steve Baker (ice@mama.indstate.edu) 3 | * All Rights reserved 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | #include "tree.h" 20 | 21 | extern bool dflag, lflag, pflag, sflag, Fflag, aflag, fflag, uflag, gflag; 22 | extern bool Dflag, inodeflag, devflag, Rflag; 23 | extern bool noindent, force_color, xdev, nolinks, flimit; 24 | //extern char *title, 25 | extern char *host, *sp; 26 | 27 | extern void (*listdir)(char *, int *, int *, u_long, dev_t); 28 | extern int (*cmpfunc)(); 29 | extern FILE *outfile; 30 | extern int Level, *dirs, maxdirs; 31 | 32 | extern bool colorize, linktargetcolor; 33 | extern char *endcode; 34 | 35 | void html_encode(FILE *, char *), url_encode(FILE *, char *); 36 | void url_encode(FILE *fd, char *s); 37 | 38 | void emit_html_header(const char *charset, char *title, char *version) 39 | { 40 | fprintf(outfile, 41 | "\n" 42 | "\n" 43 | "\n" 44 | " \n" 45 | " \n" 46 | " \n" 47 | " %s\n" 48 | " \n" 66 | "\n" 67 | "\n" 68 | "\t

%s

\n\t",charset ? charset : "iso-8859-1", version, title, title); 69 | } 70 | 71 | off_t html_listdir(char *d, int *dt, int *ft, u_long lev, dev_t dev) 72 | { 73 | char *path; 74 | bool nlf = FALSE, colored = FALSE; 75 | long pathsize = 0; 76 | struct _info **dir, **sav; 77 | struct stat sb; 78 | int i,n,c; 79 | char hclr[20], *hdir, *hcmd; 80 | 81 | if ((Level >= 0) && (lev > Level)) { 82 | fprintf(outfile, "
\n"); 83 | return 0; 84 | } 85 | 86 | if (xdev && lev == 0) { 87 | stat(d,&sb); 88 | dev = sb.st_dev; 89 | } 90 | 91 | sav = dir = read_dir(d,&n); 92 | if (!dir && n) { 93 | fprintf(outfile," [error opening dir]
\n"); 94 | return 0; 95 | } 96 | if (!n) { 97 | fprintf(outfile,"
\n"); 98 | free_dir(sav); 99 | return 0; 100 | } 101 | if (flimit > 0 && n > flimit) { 102 | fprintf(outfile," [%d entries exceeds filelimit, not opening dir]
\n",n); 103 | free_dir(sav); 104 | return 0; 105 | } 106 | 107 | if (cmpfunc) qsort(dir,n,sizeof(struct _info *),cmpfunc); 108 | if (lev >= maxdirs-1) { 109 | dirs = xrealloc(dirs,sizeof(int) * (maxdirs += 1024)); 110 | memset(dirs+(maxdirs-1024), 0, sizeof(int) * 1024); 111 | } 112 | dirs[lev] = 1; 113 | if (!*(dir+1)) dirs[lev] = 2; 114 | fprintf(outfile,"
\n"); 115 | 116 | path = malloc(pathsize=4096); 117 | 118 | while(*dir) { 119 | if (!noindent) indent(lev); 120 | 121 | fillinfo(path,*dir); 122 | if (path[0] == ' ') { 123 | path[0] = '['; 124 | for(i=0;path[i];i++) { 125 | if (path[i] == ' ') fprintf(outfile,"%s",sp); 126 | else fprintf(outfile,"%c", path[i]); 127 | } 128 | fprintf(outfile,"]%s%s", sp, sp); 129 | } 130 | 131 | if (colorize) { 132 | if ((*dir)->lnk && linktargetcolor) colored = color((*dir)->lnkmode,(*dir)->name,(*dir)->orphan,FALSE); 133 | else colored = color((*dir)->mode,(*dir)->name,(*dir)->orphan,FALSE); 134 | } 135 | 136 | if (fflag) { 137 | if (sizeof(char) * (strlen(d)+strlen((*dir)->name)+2) > pathsize) 138 | path=xrealloc(path,pathsize=(sizeof(char) * (strlen(d)+strlen((*dir)->name)+1024))); 139 | if (!strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name); 140 | else sprintf(path,"%s/%s",d,(*dir)->name); 141 | } else { 142 | if (sizeof(char) * (strlen((*dir)->name)+1) > pathsize) 143 | path=xrealloc(path,pathsize=(sizeof(char) * (strlen((*dir)->name)+1024))); 144 | sprintf(path,"%s",(*dir)->name); 145 | } 146 | 147 | /* This is really hackish and should be done over. */ 148 | if (Rflag && (lev == Level) && (*dir)->isdir) { 149 | if (nolinks) fprintf(outfile,"%s",(*dir)->name); 150 | else { 151 | fprintf(outfile,"name); 155 | fprintf(outfile,"/00Tree.html\">"); 156 | html_encode(outfile,(*dir)->name); 157 | fprintf(outfile,"
\n"); 158 | } 159 | 160 | hdir = gnu_getcwd(); 161 | if (sizeof(char) * (strlen(hdir)+strlen(d)+strlen((*dir)->name)+2) > pathsize) 162 | path = xrealloc(path, pathsize = sizeof(char) * (strlen(hdir)+strlen(d)+strlen((*dir)->name) + 1024)); 163 | 164 | sprintf(path,"%s%s/%s",hdir,d+1,(*dir)->name); 165 | fprintf(stderr,"Entering directory %s\n",path); 166 | 167 | hcmd = xmalloc(sizeof(char) * (49 + strlen(host) + strlen(d) + strlen((*dir)->name)) + 10 + (2*strlen(path))); 168 | sprintf(hcmd,"tree -n -H \"%s%s/%s\" -L %d -R -o \"%s/00Tree.html\" \"%s\"\n", host,d+1,(*dir)->name,Level+1,path,path); 169 | system(hcmd); 170 | free(hdir); 171 | free(hcmd); 172 | } else { 173 | if (nolinks) { 174 | if (force_color) { 175 | /* 176 | * Note that the B element has been set to normal weight in the 177 | * style portion of the output. so using will just gives us a element 178 | * for which we can assign a color class to. 179 | */ 180 | fprintf(outfile, "%s", 181 | (*dir)->isdir ? "DIR" : 182 | (*dir)->isexe ? "EXEC" : 183 | (*dir)->isfifo ? "FIFO" : 184 | (*dir)->issok ? "SOCK" : "NORM", (*dir)->name); 185 | } else 186 | fprintf(outfile,"%s",(*dir)->name); 187 | } else { 188 | if (force_color) { 189 | sprintf(hclr, "%s", 190 | (*dir)->isdir ? "DIR" : 191 | (*dir)->isexe ? "EXEC" : 192 | (*dir)->isfifo ? "FIFO" : 193 | (*dir)->issok ? "SOCK" : "NORM"); 194 | fprintf(outfile,"%s", hclr, host,d+1,(*dir)->name, 195 | ((*dir)->isdir?"/":""),(*dir)->name); 196 | } else { 197 | fprintf(outfile,"name); 201 | fprintf(outfile,"%s\">",((*dir)->isdir?"/":"")); 202 | html_encode(outfile,(*dir)->name); 203 | fprintf(outfile,""); 204 | } 205 | } 206 | } 207 | 208 | if (colored) fprintf(outfile,"%s",endcode); 209 | if (Fflag && !(*dir)->lnk) { 210 | if ((c = Ftype((*dir)->mode))) fputc(c, outfile); 211 | } 212 | 213 | if ((*dir)->isdir) { 214 | if ((*dir)->lnk) { 215 | if (lflag && !(xdev && dev != (*dir)->dev)) { 216 | if (findino((*dir)->inode,(*dir)->dev)) { 217 | fprintf(outfile," [recursive, not followed]"); 218 | } else { 219 | saveino((*dir)->inode, (*dir)->dev); 220 | if (*(*dir)->lnk == '/') 221 | listdir((*dir)->lnk,dt,ft,lev+1,dev); 222 | else { 223 | if (strlen(d)+strlen((*dir)->lnk)+2 > pathsize) path=xrealloc(path,pathsize=(strlen(d)+strlen((*dir)->name)+1024)); 224 | if (fflag && !strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->lnk); 225 | else sprintf(path,"%s/%s",d,(*dir)->lnk); 226 | listdir(path,dt,ft,lev+1,dev); 227 | } 228 | nlf = TRUE; 229 | } 230 | } 231 | } else if (!(xdev && dev != (*dir)->dev)) { 232 | if (strlen(d)+strlen((*dir)->name)+2 > pathsize) path=xrealloc(path,pathsize=(strlen(d)+strlen((*dir)->name)+1024)); 233 | if (fflag && !strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name); 234 | else sprintf(path,"%s/%s",d,(*dir)->name); 235 | saveino((*dir)->inode, (*dir)->dev); 236 | listdir(path,dt,ft,lev+1,dev); 237 | nlf = TRUE; 238 | } 239 | *dt += 1; 240 | } else *ft += 1; 241 | if (*(dir+1) && !*(dir+2)) dirs[lev] = 2; 242 | if (nlf) nlf = FALSE; 243 | else fprintf(outfile,"
\n"); 244 | dir++; 245 | } 246 | dirs[lev] = 0; 247 | free(path); 248 | free_dir(sav); 249 | return 0; 250 | } 251 | 252 | off_t html_rlistdir(char *d, int *dt, int *ft, u_long lev, dev_t dev) 253 | { 254 | struct _info **dir; 255 | off_t size = 0; 256 | char *err; 257 | 258 | dir = getfulltree(d, lev, dev, &size, &err); 259 | 260 | memset(dirs, 0, sizeof(int) * maxdirs); 261 | 262 | htmlr_listdir(dir, d, dt, ft, lev); 263 | 264 | return size; 265 | } 266 | 267 | void htmlr_listdir(struct _info **dir, char *d, int *dt, int *ft, u_long lev) 268 | { 269 | char *path; 270 | long pathsize = 0; 271 | bool nlf = FALSE, colored = FALSE; 272 | struct _info **sav = dir; 273 | int i,c; 274 | char hclr[20], *hdir, *hcmd; 275 | 276 | if (dir == NULL) return; 277 | 278 | dirs[lev] = 1; 279 | if (!*(dir+1)) dirs[lev] = 2; 280 | fprintf(outfile,"
\n"); 281 | 282 | path = malloc(pathsize=4096); 283 | 284 | while(*dir) { 285 | if (!noindent) indent(lev); 286 | 287 | fillinfo(path,*dir); 288 | if (path[0] == ' ') { 289 | path[0] = '['; 290 | for(i=0;path[i];i++) { 291 | if (path[i] == ' ') fprintf(outfile,"%s",sp); 292 | else fprintf(outfile,"%c", path[i]); 293 | } 294 | fprintf(outfile,"]%s%s", sp, sp); 295 | } 296 | 297 | if (colorize) { 298 | if ((*dir)->lnk && linktargetcolor) colored = color((*dir)->lnkmode,(*dir)->name,(*dir)->orphan,FALSE); 299 | else colored = color((*dir)->mode,(*dir)->name,(*dir)->orphan,FALSE); 300 | } 301 | 302 | if (fflag) { 303 | if (sizeof(char) * (strlen(d)+strlen((*dir)->name)+2) > pathsize) 304 | path=xrealloc(path,pathsize=(sizeof(char) * (strlen(d)+strlen((*dir)->name)+1024))); 305 | if (!strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name); 306 | else sprintf(path,"%s/%s",d,(*dir)->name); 307 | } else { 308 | if (sizeof(char) * (strlen((*dir)->name)+1) > pathsize) 309 | path=xrealloc(path,pathsize=(sizeof(char) * (strlen((*dir)->name)+1024))); 310 | sprintf(path,"%s",(*dir)->name); 311 | } 312 | 313 | /* This is really hackish and should be done over. */ 314 | if (Rflag && (lev == Level) && (*dir)->isdir) { 315 | if (nolinks) fprintf(outfile,"%s",(*dir)->name); 316 | else { 317 | fprintf(outfile,"name); 321 | fprintf(outfile,"/00Tree.html\">"); 322 | html_encode(outfile,(*dir)->name); 323 | fprintf(outfile,"
\n"); 324 | } 325 | 326 | hdir = gnu_getcwd(); 327 | if (sizeof(char) * (strlen(hdir)+strlen(d)+strlen((*dir)->name)+2) > pathsize) 328 | path = xrealloc(path, pathsize = sizeof(char) * (strlen(hdir)+strlen(d)+strlen((*dir)->name) + 1024)); 329 | 330 | sprintf(path,"%s%s/%s",hdir,d+1,(*dir)->name); 331 | fprintf(stderr,"Entering directory %s\n",path); 332 | 333 | hcmd = xmalloc(sizeof(char) * (49 + strlen(host) + strlen(d) + strlen((*dir)->name)) + 10 + (2*strlen(path))); 334 | sprintf(hcmd,"tree -n -H \"%s%s/%s\" -L %d -R -o \"%s/00Tree.html\" \"%s\"\n", host,d+1,(*dir)->name,Level+1,path,path); 335 | system(hcmd); 336 | free(hdir); 337 | free(hcmd); 338 | } else { 339 | if (nolinks) { 340 | if (force_color) { 341 | /* 342 | * Note that the B element has been set to normal weight in the 343 | * style portion of the output. so using will just gives us a element 344 | * for which we can assign a color class to. 345 | */ 346 | fprintf(outfile, "%s", 347 | (*dir)->isdir ? "DIR" : 348 | (*dir)->isexe ? "EXEC" : 349 | (*dir)->isfifo ? "FIFO" : 350 | (*dir)->issok ? "SOCK" : "NORM", (*dir)->name); 351 | } else 352 | fprintf(outfile,"%s",(*dir)->name); 353 | } else { 354 | if (force_color) { 355 | sprintf(hclr, "%s", 356 | (*dir)->isdir ? "DIR" : 357 | (*dir)->isexe ? "EXEC" : 358 | (*dir)->isfifo ? "FIFO" : 359 | (*dir)->issok ? "SOCK" : "NORM"); 360 | fprintf(outfile,"%s", hclr, host,d+1,(*dir)->name, 361 | ((*dir)->isdir?"/":""),(*dir)->name); 362 | } else { 363 | fprintf(outfile,"name); 367 | fprintf(outfile,"%s\">",((*dir)->isdir?"/":"")); 368 | html_encode(outfile,(*dir)->name); 369 | fprintf(outfile,""); 370 | } 371 | } 372 | } 373 | 374 | if (colored) fprintf(outfile,"%s",endcode); 375 | if (Fflag && !(*dir)->lnk) { 376 | if ((c = Ftype((*dir)->mode))) fputc(c, outfile); 377 | } 378 | 379 | if ((*dir)->child) { 380 | if (strlen(d)+strlen((*dir)->name)+2 > pathsize) path=xrealloc(path,pathsize=(strlen(d)+strlen((*dir)->name)+1024)); 381 | if (!strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name); 382 | else sprintf(path,"%s/%s",d,(*dir)->name); 383 | htmlr_listdir((*dir)->child, path, dt, ft, lev+1); 384 | nlf = TRUE; 385 | *dt += 1; 386 | } else { 387 | if ((*dir)->isdir) *dt += 1; 388 | else *ft += 1; 389 | } 390 | 391 | if (*(dir+1) && !*(dir+2)) dirs[lev] = 2; 392 | if (nlf) nlf = FALSE; 393 | else fprintf(outfile,"
\n"); 394 | dir++; 395 | } 396 | dirs[lev] = 0; 397 | free(path); 398 | free_dir(sav); 399 | return; 400 | } 401 | 402 | void html_encode(FILE *fd, char *s) 403 | { 404 | for(;*s;s++) { 405 | switch(*s) { 406 | case '<': 407 | fputs("<",fd); 408 | break; 409 | case '>': 410 | fputs(">",fd); 411 | break; 412 | case '&': 413 | fputs("&",fd); 414 | break; 415 | case '"': 416 | fputs(""",fd); 417 | break; 418 | default: 419 | fputc(*s,fd); 420 | // fputc(isprint(*s)?*s:'?',fd); 421 | break; 422 | } 423 | } 424 | } 425 | 426 | void url_encode(FILE *fd, char *s) 427 | { 428 | for(;*s;s++) { 429 | switch(*s) { 430 | case ' ': 431 | case '"': 432 | case '#': 433 | case '%': 434 | case '<': 435 | case '>': 436 | case '[': 437 | case ']': 438 | case '^': 439 | case '\\': 440 | case '?': 441 | case '+': 442 | fprintf(fd,"%%%02X",*s); 443 | break; 444 | case '&': 445 | fprintf(fd,"&"); 446 | break; 447 | default: 448 | fprintf(fd,isprint((u_int)*s)?"%c":"%%%02X",(u_char)*s); 449 | break; 450 | } 451 | } 452 | } 453 | 454 | -------------------------------------------------------------------------------- /third_party/tree/color.c: -------------------------------------------------------------------------------- 1 | /* $Copyright: $ 2 | * Copyright (c) 1996 - 2014 by Steve Baker (ice@mama.indstate.edu) 3 | * All Rights reserved 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | #include "tree.h" 20 | 21 | /* 22 | * Hacked in DIR_COLORS support for linux. ------------------------------ 23 | */ 24 | /* 25 | * If someone asked me, I'd extend dircolors, to provide more generic 26 | * color support so that more programs could take advantage of it. This 27 | * is really just hacked in support. The dircolors program should: 28 | * 1) Put the valid terms in a environment var, like: 29 | * COLOR_TERMS=linux:console:xterm:vt100... 30 | * 2) Put the COLOR and OPTIONS directives in a env var too. 31 | * 3) Have an option to dircolors to silently ignore directives that it 32 | * doesn't understand (directives that other programs would 33 | * understand). 34 | * 4) Perhaps even make those unknown directives environment variables. 35 | * 36 | * The environment is the place for cryptic crap no one looks at, but 37 | * programs. No one is going to care if it takes 30 variables to do 38 | * something. 39 | */ 40 | enum { 41 | CMD_COLOR, CMD_OPTIONS, CMD_TERM, CMD_EIGHTBIT, COL_NORMAL, COL_FILE, COL_DIR, 42 | COL_LINK, COL_FIFO, COL_DOOR, COL_BLK, COL_CHR, COL_ORPHAN, COL_SOCK, 43 | COL_SETUID, COL_SETGID, COL_STICKY_OTHER_WRITABLE, COL_OTHER_WRITABLE, 44 | COL_STICKY, COL_EXEC, COL_MISSING, COL_LEFTCODE, COL_RIGHTCODE, COL_ENDCODE, 45 | DOT_EXTENSION, ERROR 46 | }; 47 | 48 | bool colorize = FALSE, ansilines = FALSE, linktargetcolor = FALSE; 49 | char *term, termmatch = FALSE, istty; 50 | char *leftcode = NULL, *rightcode = NULL, *endcode = NULL; 51 | 52 | char *norm_flgs = NULL, *file_flgs = NULL, *dir_flgs = NULL, *link_flgs = NULL; 53 | char *fifo_flgs = NULL, *door_flgs = NULL, *block_flgs = NULL, *char_flgs = NULL; 54 | char *orphan_flgs = NULL, *sock_flgs = NULL, *suid_flgs = NULL, *sgid_flgs = NULL; 55 | char *stickyow_flgs = NULL, *otherwr_flgs = NULL, *sticky_flgs = NULL; 56 | char *exec_flgs = NULL, *missing_flgs = NULL; 57 | 58 | char *vgacolor[] = { 59 | "black", "red", "green", "yellow", "blue", "fuchsia", "aqua", "white", 60 | NULL, NULL, 61 | "transparent", "red", "green", "yellow", "blue", "fuchsia", "aqua", "black" 62 | }; 63 | 64 | struct colortable colortable[11]; 65 | struct extensions *ext = NULL; 66 | const struct linedraw *linedraw; 67 | 68 | char **split(char *str, char *delim, int *nwrds); 69 | int cmd(char *s); 70 | 71 | extern FILE *outfile; 72 | extern bool Hflag, force_color, nocolor; 73 | extern const char *charset; 74 | 75 | void parse_dir_colors() 76 | { 77 | char buf[1025], **arg, **c, *colors, *s; 78 | int i, n; 79 | struct extensions *e; 80 | 81 | if (Hflag) return; 82 | 83 | if (getenv("TERM") == NULL) { 84 | colorize = FALSE; 85 | return; 86 | } 87 | 88 | s = getenv("TREE_COLORS"); 89 | if (s == NULL) s = getenv("LS_COLORS"); 90 | if ((s == NULL || strlen(s) == 0) && force_color) s = ":no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.bat=01;32:*.BAT=01;32:*.btm=01;32:*.BTM=01;32:*.cmd=01;32:*.CMD=01;32:*.com=01;32:*.COM=01;32:*.dll=01;32:*.DLL=01;32:*.exe=01;32:*.EXE=01;32:*.arj=01;31:*.bz2=01;31:*.deb=01;31:*.gz=01;31:*.lzh=01;31:*.rpm=01;31:*.tar=01;31:*.taz=01;31:*.tb2=01;31:*.tbz2=01;31:*.tbz=01;31:*.tgz=01;31:*.tz2=01;31:*.z=01;31:*.Z=01;31:*.zip=01;31:*.ZIP=01;31:*.zoo=01;31:*.asf=01;35:*.ASF=01;35:*.avi=01;35:*.AVI=01;35:*.bmp=01;35:*.BMP=01;35:*.flac=01;35:*.FLAC=01;35:*.gif=01;35:*.GIF=01;35:*.jpg=01;35:*.JPG=01;35:*.jpeg=01;35:*.JPEG=01;35:*.m2a=01;35:*.M2a=01;35:*.m2v=01;35:*.M2V=01;35:*.mov=01;35:*.MOV=01;35:*.mp3=01;35:*.MP3=01;35:*.mpeg=01;35:*.MPEG=01;35:*.mpg=01;35:*.MPG=01;35:*.ogg=01;35:*.OGG=01;35:*.ppm=01;35:*.rm=01;35:*.RM=01;35:*.tga=01;35:*.TGA=01;35:*.tif=01;35:*.TIF=01;35:*.wav=01;35:*.WAV=01;35:*.wmv=01;35:*.WMV=01;35:*.xbm=01;35:*.xpm=01;35:"; 91 | 92 | 93 | if (s == NULL || (!force_color && (nocolor || !isatty(1)))) { 94 | colorize = FALSE; 95 | return; 96 | } else { 97 | colorize = TRUE; 98 | /* You can uncomment the below line and tree will always try to ANSI-fy the indentation lines */ 99 | /* ansilines = TRUE; */ 100 | } 101 | 102 | colors = scopy(s); 103 | 104 | arg = split(colors,":",&n); 105 | 106 | for(i=0;arg[i];i++) { 107 | c = split(arg[i],"=",&n); 108 | switch(cmd(c[0])) { 109 | case COL_NORMAL: 110 | if (c[1]) norm_flgs = scopy(c[1]); 111 | break; 112 | case COL_FILE: 113 | if (c[1]) file_flgs = scopy(c[1]); 114 | break; 115 | case COL_DIR: 116 | if (c[1]) dir_flgs = scopy(c[1]); 117 | break; 118 | case COL_LINK: 119 | if (c[1]) { 120 | if (strcasecmp("target",c[1]) == 0) { 121 | linktargetcolor = TRUE; 122 | link_flgs = "01;36"; /* Should never actually be used */ 123 | } else link_flgs = scopy(c[1]); 124 | } 125 | break; 126 | case COL_FIFO: 127 | if (c[1]) fifo_flgs = scopy(c[1]); 128 | break; 129 | case COL_DOOR: 130 | if (c[1]) door_flgs = scopy(c[1]); 131 | break; 132 | case COL_BLK: 133 | if (c[1]) block_flgs = scopy(c[1]); 134 | break; 135 | case COL_CHR: 136 | if (c[1]) char_flgs = scopy(c[1]); 137 | break; 138 | case COL_ORPHAN: 139 | if (c[1]) orphan_flgs = scopy(c[1]); 140 | break; 141 | case COL_SOCK: 142 | if (c[1]) sock_flgs = scopy(c[1]); 143 | break; 144 | case COL_SETUID: 145 | if (c[1]) suid_flgs = scopy(c[1]); 146 | break; 147 | case COL_SETGID: 148 | if (c[1]) sgid_flgs = scopy(c[1]); 149 | break; 150 | case COL_STICKY_OTHER_WRITABLE: 151 | if (c[1]) stickyow_flgs = scopy(c[1]); 152 | break; 153 | case COL_OTHER_WRITABLE: 154 | if (c[1]) otherwr_flgs = scopy(c[1]); 155 | break; 156 | case COL_STICKY: 157 | if (c[1]) sticky_flgs = scopy(c[1]); 158 | break; 159 | case COL_EXEC: 160 | if (c[1]) exec_flgs = scopy(c[1]); 161 | break; 162 | case COL_MISSING: 163 | if (c[1]) missing_flgs = scopy(c[1]); 164 | break; 165 | case COL_LEFTCODE: 166 | if (c[1]) leftcode = scopy(c[1]); 167 | break; 168 | case COL_RIGHTCODE: 169 | if (c[1]) rightcode = scopy(c[1]); 170 | break; 171 | case COL_ENDCODE: 172 | if (c[1]) endcode = scopy(c[1]); 173 | break; 174 | case DOT_EXTENSION: 175 | if (c[1]) { 176 | e = xmalloc(sizeof(struct extensions)); 177 | e->ext = scopy(c[0]+1); 178 | e->term_flg = scopy(c[1]); 179 | e->nxt = ext; 180 | ext = e; 181 | } 182 | } 183 | free(c); 184 | } 185 | free(arg); 186 | 187 | /* make sure at least norm_flgs is defined. We're going to assume vt100 support */ 188 | if (!leftcode) leftcode = scopy("\033["); 189 | if (!rightcode) rightcode = scopy("m"); 190 | if (!norm_flgs) norm_flgs = scopy("00"); 191 | 192 | if (!endcode) { 193 | sprintf(buf,"%s%s%s",leftcode,norm_flgs,rightcode); 194 | endcode = scopy(buf); 195 | } 196 | 197 | free(colors); 198 | 199 | /* if (!termmatch) colorize = FALSE; */ 200 | } 201 | 202 | /* 203 | * You must free the pointer that is allocated by split() after you 204 | * are done using the array. 205 | */ 206 | char **split(char *str, char *delim, int *nwrds) 207 | { 208 | int n = 128; 209 | char **w = xmalloc(sizeof(char *) * n); 210 | 211 | w[*nwrds = 0] = strtok(str,delim); 212 | 213 | while (w[*nwrds]) { 214 | if (*nwrds == (n-2)) w = xrealloc(w,sizeof(char *) * (n+=256)); 215 | w[++(*nwrds)] = strtok(NULL,delim); 216 | } 217 | 218 | w[*nwrds] = NULL; 219 | return w; 220 | } 221 | 222 | int cmd(char *s) 223 | { 224 | static struct { 225 | char *cmd; 226 | char cmdnum; 227 | } cmds[] = { 228 | {"no", COL_NORMAL}, {"fi", COL_FILE}, {"di", COL_DIR}, {"ln", COL_LINK}, {"pi", COL_FIFO}, 229 | {"do", COL_DOOR}, {"bd", COL_BLK}, {"cd", COL_CHR}, {"or", COL_ORPHAN}, {"so", COL_SOCK}, 230 | {"su", COL_SETUID}, {"sg", COL_SETGID}, {"tw", COL_STICKY_OTHER_WRITABLE}, {"ow", COL_OTHER_WRITABLE}, 231 | {"st", COL_STICKY}, {"ex", COL_EXEC}, {"mi", COL_MISSING}, {"lc", COL_LEFTCODE}, {"rc", COL_RIGHTCODE}, 232 | {"ec", COL_ENDCODE}, {NULL, 0} 233 | }; 234 | int i; 235 | 236 | for(i=0;cmds[i].cmdnum;i++) 237 | if (!strcmp(cmds[i].cmd,s)) return cmds[i].cmdnum; 238 | if (s[0] == '*') return DOT_EXTENSION; 239 | return ERROR; 240 | } 241 | 242 | int color(u_short mode, char *name, bool orphan, bool islink) 243 | { 244 | struct extensions *e; 245 | int l, xl; 246 | 247 | if (orphan) { 248 | if (islink) { 249 | if (missing_flgs) { 250 | fprintf(outfile,"%s%s%s",leftcode,missing_flgs,rightcode); 251 | return TRUE; 252 | } 253 | } else { 254 | if (orphan_flgs) { 255 | fprintf(outfile,"%s%s%s",leftcode,orphan_flgs,rightcode); 256 | return TRUE; 257 | } 258 | } 259 | } 260 | switch(mode & S_IFMT) { 261 | case S_IFIFO: 262 | if (!fifo_flgs) return FALSE; 263 | fprintf(outfile,"%s%s%s",leftcode,fifo_flgs,rightcode); 264 | return TRUE; 265 | case S_IFCHR: 266 | if (!char_flgs) return FALSE; 267 | fprintf(outfile,"%s%s%s",leftcode,char_flgs,rightcode); 268 | return TRUE; 269 | case S_IFDIR: 270 | if (mode & S_ISVTX) { 271 | if ((mode & S_IWOTH) && stickyow_flgs) { 272 | fprintf(outfile, "%s%s%s",leftcode,stickyow_flgs,rightcode); 273 | return TRUE; 274 | } 275 | if (!(mode & S_IWOTH) && sticky_flgs) { 276 | fprintf(outfile, "%s%s%s",leftcode,sticky_flgs,rightcode); 277 | return TRUE; 278 | } 279 | } 280 | if ((mode & S_IWOTH) && otherwr_flgs) { 281 | fprintf(outfile,"%s%s%s",leftcode,otherwr_flgs,rightcode); 282 | return TRUE; 283 | } 284 | if (!dir_flgs) return FALSE; 285 | fprintf(outfile,"%s%s%s",leftcode,dir_flgs,rightcode); 286 | return TRUE; 287 | #ifndef __EMX__ 288 | case S_IFBLK: 289 | if (!block_flgs) return FALSE; 290 | fprintf(outfile,"%s%s%s",leftcode,block_flgs,rightcode); 291 | return TRUE; 292 | case S_IFLNK: 293 | if (!link_flgs) return FALSE; 294 | fprintf(outfile,"%s%s%s",leftcode,link_flgs,rightcode); 295 | return TRUE; 296 | #ifdef S_IFDOOR 297 | case S_IFDOOR: 298 | if (!door_flgs) return FALSE; 299 | fprintf(outfile,"%s%s%s",leftcode,door_flgs,rightcode); 300 | return TRUE; 301 | #endif 302 | #endif 303 | case S_IFSOCK: 304 | if (!sock_flgs) return FALSE; 305 | fprintf(outfile,"%s%s%s",leftcode,sock_flgs,rightcode); 306 | return TRUE; 307 | case S_IFREG: 308 | if ((mode & S_ISUID) && suid_flgs) { 309 | fprintf(outfile,"%s%s%s",leftcode,suid_flgs,rightcode); 310 | return TRUE; 311 | } 312 | if ((mode & S_ISGID) && sgid_flgs) { 313 | fprintf(outfile,"%s%s%s",leftcode,sgid_flgs,rightcode); 314 | return TRUE; 315 | } 316 | if (!exec_flgs) return FALSE; 317 | if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) { 318 | fprintf(outfile,"%s%s%s",leftcode,exec_flgs,rightcode); 319 | return TRUE; 320 | } 321 | /* not a directory, link, special device, etc, so check for extension match */ 322 | l = strlen(name); 323 | for(e=ext;e;e=e->nxt) { 324 | xl = strlen(e->ext); 325 | if (!strcmp((l>xl)?name+(l-xl):name,e->ext)) { 326 | fprintf(outfile,"%s%s%s",leftcode,e->term_flg,rightcode); 327 | return TRUE; 328 | } 329 | } 330 | return FALSE; 331 | } 332 | return FALSE; 333 | } 334 | 335 | /* 336 | * Charsets provided by Kyosuke Tokoro (NBG01720@nifty.ne.jp) 337 | */ 338 | const char *getcharset(void) 339 | { 340 | #ifndef __EMX__ 341 | return getenv("TREE_CHARSET"); 342 | #else 343 | static char buffer[13]; 344 | ULONG aulCpList[3],ulListSize,codepage=0; 345 | char*charset=getenv("TREE_CHARSET"); 346 | if(charset) 347 | return charset; 348 | 349 | if(!getenv("WINDOWID")) 350 | if(!DosQueryCp(sizeof aulCpList,aulCpList,&ulListSize)) 351 | if(ulListSize>=sizeof*aulCpList) 352 | codepage=*aulCpList; 353 | 354 | switch(codepage){ 355 | case 437: case 775: case 850: case 851: case 852: case 855: 356 | case 857: case 860: case 861: case 862: case 863: case 864: 357 | case 865: case 866: case 868: case 869: case 891: case 903: 358 | case 904: 359 | sprintf(buffer,"IBM%03lu",codepage); 360 | break; 361 | case 367: 362 | return"US-ASCII"; 363 | case 813: 364 | return"ISO-8859-7"; 365 | case 819: 366 | return"ISO-8859-1"; 367 | case 881: case 882: case 883: case 884: case 885: 368 | sprintf(buffer,"ISO-8859-%lu",codepage-880); 369 | break; 370 | case 858: case 924: 371 | sprintf(buffer,"IBM%05lu",codepage); 372 | break; 373 | case 874: 374 | return"TIS-620"; 375 | case 897: case 932: case 942: case 943: 376 | return"Shift_JIS"; 377 | case 912: 378 | return"ISO-8859-2"; 379 | case 915: 380 | return"ISO-8859-5"; 381 | case 916: 382 | return"ISO-8859-8"; 383 | case 949: case 970: 384 | return"EUC-KR"; 385 | case 950: 386 | return"Big5"; 387 | case 954: 388 | return"EUC-JP"; 389 | case 1051: 390 | return"hp-roman8"; 391 | case 1089: 392 | return"ISO-8859-6"; 393 | case 1250: case 1251: case 1253: case 1254: case 1255: case 1256: 394 | case 1257: case 1258: 395 | sprintf(buffer,"windows-%lu",codepage); 396 | break; 397 | case 1252: 398 | return"ISO-8859-1-Windows-3.1-Latin-1"; 399 | default: 400 | return NULL; 401 | } 402 | #endif 403 | } 404 | 405 | void initlinedraw(int flag) 406 | { 407 | static const char*latin1_3[]={ 408 | "ISO-8859-1", "ISO-8859-1:1987", "ISO_8859-1", "latin1", "l1", "IBM819", 409 | "CP819", "csISOLatin1", "ISO-8859-3", "ISO_8859-3:1988", "ISO_8859-3", 410 | "latin3", "ls", "csISOLatin3", NULL 411 | }; 412 | static const char*iso8859_789[]={ 413 | "ISO-8859-7", "ISO_8859-7:1987", "ISO_8859-7", "ELOT_928", "ECMA-118", 414 | "greek", "greek8", "csISOLatinGreek", "ISO-8859-8", "ISO_8859-8:1988", 415 | "iso-ir-138", "ISO_8859-8", "hebrew", "csISOLatinHebrew", "ISO-8859-9", 416 | "ISO_8859-9:1989", "iso-ir-148", "ISO_8859-9", "latin5", "l5", 417 | "csISOLatin5", NULL 418 | }; 419 | static const char*shift_jis[]={ 420 | "Shift_JIS", "MS_Kanji", "csShiftJIS", NULL 421 | }; 422 | static const char*euc_jp[]={ 423 | "EUC-JP", "Extended_UNIX_Code_Packed_Format_for_Japanese", 424 | "csEUCPkdFmtJapanese", NULL 425 | }; 426 | static const char*euc_kr[]={ 427 | "EUC-KR", "csEUCKR", NULL 428 | }; 429 | static const char*iso2022jp[]={ 430 | "ISO-2022-JP", "csISO2022JP", "ISO-2022-JP-2", "csISO2022JP2", NULL 431 | }; 432 | static const char*ibm_pc[]={ 433 | "IBM437", "cp437", "437", "csPC8CodePage437", "IBM852", "cp852", "852", 434 | "csPCp852", "IBM863", "cp863", "863", "csIBM863", "IBM855", "cp855", 435 | "855", "csIBM855", "IBM865", "cp865", "865", "csIBM865", "IBM866", 436 | "cp866", "866", "csIBM866", NULL 437 | }; 438 | static const char*ibm_ps2[]={ 439 | "IBM850", "cp850", "850", "csPC850Multilingual", "IBM00858", "CCSID00858", 440 | "CP00858", "PC-Multilingual-850+euro", NULL 441 | }; 442 | static const char*ibm_gr[]={ 443 | "IBM869", "cp869", "869", "cp-gr", "csIBM869", NULL 444 | }; 445 | static const char*gb[]={ 446 | "GB2312", "csGB2312", NULL 447 | }; 448 | static const char*utf8[]={ 449 | "UTF-8", "utf8", NULL 450 | }; 451 | static const char*big5[]={ 452 | "Big5", "csBig5", NULL 453 | }; 454 | static const char*viscii[]={ 455 | "VISCII", "csVISCII", NULL 456 | }; 457 | static const char*koi8ru[]={ 458 | "KOI8-R", "csKOI8R", "KOI8-U", NULL 459 | }; 460 | static const char*windows[]={ 461 | "ISO-8859-1-Windows-3.1-Latin-1", "csWindows31Latin1", 462 | "ISO-8859-2-Windows-Latin-2", "csWindows31Latin2", "windows-1250", 463 | "windows-1251", "windows-1253", "windows-1254", "windows-1255", 464 | "windows-1256", "windows-1256", "windows-1257", NULL 465 | }; 466 | static const struct linedraw cstable[]={ 467 | { latin1_3, "| ", "|--", "·--", "©" }, 468 | { iso8859_789, "| ", "|--", "·--", "(c)" }, 469 | { shift_jis, "\204\240 ", "\204\245", "\204\244", "(c)" }, 470 | { euc_jp, "\250\242 ", "\250\247", "\250\246", "(c)" }, 471 | { euc_kr, "\246\242 ", "\246\247", "\246\246", "(c)" }, 472 | { iso2022jp, "\033$B(\"\033(B ", "\033$B('\033(B", "\033$B(&\033(B", "(c)" }, 473 | { ibm_pc, "\263 ", "\303\304\304", "\300\304\304", "(c)" }, 474 | { ibm_ps2, "\263 ", "\303\304\304", "\300\304\304", "\227" }, 475 | { ibm_gr, "\263 ", "\303\304\304", "\300\304\304", "\270" }, 476 | { gb, "\251\246 ", "\251\300", "\251\270", "(c)" }, 477 | { utf8, "\342\224\202\302\240\302\240", 478 | "\342\224\234\342\224\200\342\224\200", "\342\224\224\342\224\200\342\224\200", "\302\251" }, 479 | { big5, "\242x ", "\242u", "\242|", "(c)" }, 480 | { viscii, "| ", "|--", "`--", "\371" }, 481 | { koi8ru, "\201 ", "\206\200\200", "\204\200\200", "\277" }, 482 | { windows, "| ", "|--", "`--", "\251" }, 483 | { NULL, "| ", "|--", "`--", "(c)" } 484 | }; 485 | const char**s; 486 | 487 | if (flag) { 488 | fprintf(stderr,"tree: missing argument to --charset, valid charsets include:\n"); 489 | for(linedraw=cstable;linedraw->name;++linedraw) 490 | for(s=linedraw->name;*s;++s) 491 | fprintf(stderr," %s\n",*s); 492 | return; 493 | } 494 | if (charset) { 495 | for(linedraw=cstable;linedraw->name;++linedraw) 496 | for(s=linedraw->name;*s;++s) 497 | if(!strcasecmp(charset,*s)) return; 498 | } 499 | linedraw=cstable+sizeof cstable/sizeof*cstable-1; 500 | } 501 | -------------------------------------------------------------------------------- /third_party/tree/LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 309 | 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) year name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | -------------------------------------------------------------------------------- /third_party/tree/tree.c: -------------------------------------------------------------------------------- 1 | /* $Copyright: $ 2 | * Copyright (c) 1996 - 2014 by Steve Baker (ice@mama.indstate.edu) 3 | * All Rights reserved 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | 20 | #include "tree.h" 21 | 22 | static char *version ="$Version: $ tree v1.7.0 (c) 1996 - 2014 by Steve Baker, Thomas Moore, Francesc Rocher, Florian Sesser, Kyosuke Tokoro $"; 23 | static char *hversion="\t\t tree v1.7.0 %s 1996 - 2014 by Steve Baker and Thomas Moore
\n" 24 | "\t\t HTML output hacked and copyleft %s 1998 by Francesc Rocher
\n" 25 | "\t\t JSON output hacked and copyleft %s 2014 by Florian Sesser
\n" 26 | "\t\t Charsets / OS/2 support %s 2001 by Kyosuke Tokoro\n"; 27 | 28 | /* Globals */ 29 | bool dflag, lflag, pflag, sflag, Fflag, aflag, fflag, uflag, gflag; 30 | bool qflag, Nflag, Qflag, Dflag, inodeflag, devflag, hflag, Rflag; 31 | bool Hflag, siflag, cflag, Xflag, Jflag, duflag, pruneflag; 32 | bool noindent, force_color, nocolor, xdev, noreport, nolinks, flimit, dirsfirst; 33 | bool ignorecase, matchdirs; 34 | bool reverse; 35 | char *pattern = NULL, *ipattern = NULL, *host = NULL, *title = "Directory Tree", *sp = " ", *_nl = "\n"; 36 | char *timefmt = NULL; 37 | const char *charset = NULL; 38 | 39 | off_t (*listdir)(char *, int *, int *, u_long, dev_t) = unix_listdir; 40 | int (*cmpfunc)() = alnumsort; 41 | 42 | char *sLevel, *curdir, *outfilename = NULL; 43 | FILE *outfile; 44 | int Level, *dirs, maxdirs; 45 | 46 | int mb_cur_max; 47 | 48 | #ifdef __EMX__ 49 | const u_short ifmt[]={ FILE_ARCHIVED, FILE_DIRECTORY, FILE_SYSTEM, FILE_HIDDEN, FILE_READONLY, 0}; 50 | #else 51 | #ifdef S_IFPORT 52 | const u_int ifmt[] = {S_IFREG, S_IFDIR, S_IFLNK, S_IFCHR, S_IFBLK, S_IFSOCK, S_IFIFO, S_IFDOOR, S_IFPORT, 0}; 53 | const char fmt[] = "-dlcbspDP?"; 54 | const char *ftype[] = {"file", "directory", "link", "char", "block", "socket", "fifo", "door", "port", "unknown", NULL}; 55 | #else 56 | const u_int ifmt[] = {S_IFREG, S_IFDIR, S_IFLNK, S_IFCHR, S_IFBLK, S_IFSOCK, S_IFIFO, 0}; 57 | const char fmt[] = "-dlcbsp?"; 58 | const char *ftype[] = {"file", "directory", "link", "char", "block", "socket", "fifo", "unknown", NULL}; 59 | #endif 60 | #endif 61 | 62 | struct sorts { 63 | char *name; 64 | int (*cmpfunc)(); 65 | } sorts[] = { 66 | {"name", alnumsort}, 67 | {"version", versort}, 68 | {"size", fsizesort}, 69 | {"mtime", mtimesort}, 70 | {"ctime", ctimesort}, 71 | {NULL, NULL} 72 | }; 73 | 74 | /* Externs */ 75 | /* hash.c */ 76 | extern struct xtable *gtable[256], *utable[256]; 77 | extern struct inotable *itable[256]; 78 | /* color.c */ 79 | extern bool colorize, ansilines, linktargetcolor; 80 | extern char *leftcode, *rightcode, *endcode; 81 | extern const struct linedraw *linedraw; 82 | 83 | 84 | int main(int argc, char **argv) 85 | { 86 | char **dirname = NULL; 87 | int i,j=0,k,n,optf,p,q,dtotal,ftotal,colored = FALSE; 88 | struct stat st; 89 | char sizebuf[64], *stmp; 90 | off_t size = 0; 91 | mode_t mt; 92 | bool needfulltree; 93 | 94 | q = p = dtotal = ftotal = 0; 95 | aflag = dflag = fflag = lflag = pflag = sflag = Fflag = uflag = gflag = FALSE; 96 | Dflag = qflag = Nflag = Qflag = Rflag = hflag = Hflag = siflag = cflag = FALSE; 97 | noindent = force_color = nocolor = xdev = noreport = nolinks = reverse = FALSE; 98 | ignorecase = matchdirs = dirsfirst = inodeflag = devflag = Xflag = Jflag = FALSE; 99 | duflag = pruneflag = FALSE; 100 | flimit = 0; 101 | dirs = xmalloc(sizeof(int) * (maxdirs=4096)); 102 | memset(dirs, 0, sizeof(int) * maxdirs); 103 | dirs[0] = 0; 104 | Level = -1; 105 | 106 | setlocale(LC_CTYPE, ""); 107 | setlocale(LC_COLLATE, ""); 108 | 109 | charset = getcharset(); 110 | if (charset == NULL && strcmp(nl_langinfo(CODESET), "UTF-8") == 0) { 111 | charset = "UTF-8"; 112 | } 113 | 114 | /* Until I get rid of this hack, make it linux/cygwin/HP nonstop only: */ 115 | #if defined (LINUX) || defined (CYGWIN) || defined (__TANDEM) 116 | mb_cur_max = (int)MB_CUR_MAX; 117 | #else 118 | mb_cur_max = 1; 119 | #endif 120 | 121 | memset(utable,0,sizeof(utable)); 122 | memset(gtable,0,sizeof(gtable)); 123 | memset(itable,0,sizeof(itable)); 124 | 125 | optf = TRUE; 126 | for(n=i=1;i%s
",host); 487 | else fprintf(outfile,"%s",host); 488 | } else { 489 | if (force_color) fprintf(outfile,"%s",host,host); 490 | else fprintf(outfile,"%s",host,host); 491 | } 492 | curdir = gnu_getcwd(); 493 | } else if (Xflag) { 494 | fprintf(outfile,"%s%s",_nl,_nl); 497 | } else if (Jflag) 498 | fputc('[',outfile); 499 | 500 | if (dirname) { 501 | for(colored=i=0;dirname[i];i++,colored=0) { 502 | if (fflag) { 503 | do { 504 | j=strlen(dirname[i]); 505 | if (j > 1 && dirname[i][j-1] == '/') dirname[i][--j] = 0; 506 | } while (j > 1 && dirname[i][j-1] == '/'); 507 | } 508 | if ((n = lstat(dirname[i],&st)) >= 0) { 509 | saveino(st.st_ino, st.st_dev); 510 | if (colorize) colored = color(st.st_mode,dirname[i],n<0,FALSE); 511 | size += st.st_size; 512 | } 513 | if (Xflag || Jflag) { 514 | mt = st.st_mode & S_IFMT; 515 | for(j=0;ifmt[j];j++) 516 | if (ifmt[j] == mt) break; 517 | if (Xflag) 518 | fprintf(outfile,"%s<%s name=\"%s\">", noindent?"":" ", ftype[j], dirname[i]); 519 | else if (Jflag) { 520 | if (i) fprintf(outfile, ","); 521 | fprintf(outfile,"%s{\"type\":\"%s\",\"name\":\"%s\",\"contents\":[", noindent?"":"\n ", ftype[j], dirname[i]); 522 | } 523 | } else if (!Hflag) printit(dirname[i]); 524 | if (colored) fprintf(outfile,"%s",endcode); 525 | if (!Hflag) size += listdir(dirname[i],&dtotal,&ftotal,0,0); 526 | else { 527 | if (chdir(dirname[i])) { 528 | fprintf(outfile,"%s [error opening dir]\n",dirname[i]); 529 | exit(1); 530 | } else { 531 | size += listdir(".",&dtotal,&ftotal,0,0); 532 | chdir(curdir); 533 | } 534 | } 535 | if (Xflag) fprintf(outfile,"%s\n",noindent?"":" ", ftype[j]); 536 | if (Jflag) fprintf(outfile,"%s]}",noindent?"":" "); 537 | } 538 | } else { 539 | if ((n = lstat(".",&st)) >= 0) { 540 | saveino(st.st_ino, st.st_dev); 541 | if (colorize) colored = color(st.st_mode,".",n<0,FALSE); 542 | size = st.st_size; 543 | } 544 | if (Xflag) fprintf(outfile,"%s",noindent?"":" "); 545 | else if (Jflag) fprintf(outfile, "{\"type\":\"directory\",\"name\": \".\",\"contents\":["); 546 | else if (!Hflag) fprintf(outfile,"."); 547 | if (colored) fprintf(outfile,"%s",endcode); 548 | size += listdir(".",&dtotal,&ftotal,0,0); 549 | if (Xflag) fprintf(outfile,"%s%s",noindent?"":" ", _nl); 550 | if (Jflag) fprintf(outfile,"%s]}",noindent?"":" "); 551 | } 552 | 553 | if (Hflag) 554 | fprintf(outfile,"\t

\n\t

\n\t

\n"); 555 | 556 | if (!noreport) { 557 | if (Xflag) { 558 | fprintf(outfile,"%s%s",noindent?"":" ", _nl); 559 | if (duflag) fprintf(outfile,"%s%lld%s", noindent?"":" ", (long long int)size, _nl); 560 | fprintf(outfile,"%s%d%s", noindent?"":" ", dtotal, _nl); 561 | if (!dflag) fprintf(outfile,"%s%d%s", noindent?"":" ", ftotal, _nl); 562 | fprintf(outfile,"%s%s",noindent?"":" ", _nl); 563 | } else if (Jflag) { 564 | fprintf(outfile, ",%s{\"type\":\"report\"",noindent?"":"\n "); 565 | if (duflag) fprintf(outfile,",\"size\":%lld", (long long int)size); 566 | fprintf(outfile,",\"directories\":%d", dtotal); 567 | if (!dflag) fprintf(outfile,",\"files\":%d", ftotal); 568 | fprintf(outfile, "}"); 569 | } else { 570 | if (duflag) { 571 | psize(sizebuf, size); 572 | fprintf(outfile,"\n%s%s used in ", sizebuf, hflag || siflag? "" : " bytes"); 573 | } else fputc('\n', outfile); 574 | if (dflag) 575 | fprintf(outfile,"%d director%s\n",dtotal,(dtotal==1? "y":"ies")); 576 | else 577 | fprintf(outfile,"%d director%s, %d file%s\n",dtotal,(dtotal==1? "y":"ies"),ftotal,(ftotal==1? "":"s")); 578 | } 579 | } 580 | 581 | if (Hflag) { 582 | fprintf(outfile,"\t

\n\t

\n"); 583 | fprintf(outfile,"\t
\n"); 584 | fprintf(outfile,"\t

\n"); 585 | fprintf(outfile,hversion,linedraw->copy, linedraw->copy, linedraw->copy, linedraw->copy); 586 | fprintf(outfile,"\t

\n"); 587 | fprintf(outfile,"\n"); 588 | fprintf(outfile,"\n"); 589 | } else if (Xflag) { 590 | fprintf(outfile,"\n"); 591 | } else if (Jflag) { 592 | fprintf(outfile, "%s]\n",_nl); 593 | } 594 | 595 | if (outfilename != NULL) fclose(outfile); 596 | 597 | return 0; 598 | } 599 | 600 | void usage(int n) 601 | { 602 | /* 123456789!123456789!123456789!123456789!123456789!123456789!123456789!123456789! */ 603 | /* \t9!123456789!123456789!123456789!123456789!123456789!123456789!123456789! */ 604 | fprintf(n < 2? stderr: stdout, 605 | "usage: tree [-acdfghilnpqrstuvxACDFJQNSUX] [-H baseHREF] [-T title ]\n" 606 | "\t[-L level [-R]] [-P pattern] [-I pattern] [-o filename] [--version]\n" 607 | "\t[--help] [--inodes] [--device] [--noreport] [--nolinks] [--dirsfirst]\n" 608 | "\t[--charset charset] [--filelimit[=]#] [--si] [--timefmt[=]]\n" 609 | "\t[--sort[=]] [--matchdirs] [--ignore-case] [--] []\n"); 610 | if (n < 2) return; 611 | fprintf(stdout, 612 | " ------- Listing options -------\n" 613 | " -a All files are listed.\n" 614 | " -d List directories only.\n" 615 | " -l Follow symbolic links like directories.\n" 616 | " -f Print the full path prefix for each file.\n" 617 | " -x Stay on current filesystem only.\n" 618 | " -L level Descend only level directories deep.\n" 619 | " -R Rerun tree when max dir level reached.\n" 620 | " -P pattern List only those files that match the pattern given.\n" 621 | " -I pattern Do not list files that match the given pattern.\n" 622 | " --ignore-case Ignore case when pattern matching.\n" 623 | " --matchdirs Include directory names in -P pattern matching.\n" 624 | " --noreport Turn off file/directory count at end of tree listing.\n" 625 | " --charset X Use charset X for terminal/HTML and indentation line output.\n" 626 | " --filelimit # Do not descend dirs with more than # files in them.\n" 627 | " --timefmt Print and format time according to the format .\n" 628 | " -o filename Output to file instead of stdout.\n" 629 | " -------- File options ---------\n" 630 | " -q Print non-printable characters as '?'.\n" 631 | " -N Print non-printable characters as is.\n" 632 | " -Q Quote filenames with double quotes.\n" 633 | " -p Print the protections for each file.\n" 634 | " -u Displays file owner or UID number.\n" 635 | " -g Displays file group owner or GID number.\n" 636 | " -s Print the size in bytes of each file.\n" 637 | " -h Print the size in a more human readable way.\n" 638 | " --si Like -h, but use in SI units (powers of 1000).\n" 639 | " -D Print the date of last modification or (-c) status change.\n" 640 | " -F Appends '/', '=', '*', '@', '|' or '>' as per ls -F.\n" 641 | " --inodes Print inode number of each file.\n" 642 | " --device Print device ID number to which each file belongs.\n" 643 | " ------- Sorting options -------\n" 644 | " -v Sort files alphanumerically by version.\n" 645 | " -t Sort files by last modification time.\n" 646 | " -c Sort files by last status change time.\n" 647 | " -U Leave files unsorted.\n" 648 | " -r Reverse the order of the sort.\n" 649 | " --dirsfirst List directories before files (-U disables).\n" 650 | " --sort X Select sort: name,version,size,mtime,ctime.\n" 651 | " ------- Graphics options ------\n" 652 | " -i Don't print indentation lines.\n" 653 | " -A Print ANSI lines graphic indentation lines.\n" 654 | " -S Print with CP437 (console) graphics indentation lines.\n" 655 | " -n Turn colorization off always (-C overrides).\n" 656 | " -C Turn colorization on always.\n" 657 | " ------- XML/HTML/JSON options -------\n" 658 | " -X Prints out an XML representation of the tree.\n" 659 | " -J Prints out an JSON representation of the tree.\n" 660 | " -H baseHREF Prints out HTML format with baseHREF as top directory.\n" 661 | " -T string Replace the default HTML title and H1 header with string.\n" 662 | " --nolinks Turn off hyperlinks in HTML output.\n" 663 | " ---- Miscellaneous options ----\n" 664 | " --version Print version and exit.\n" 665 | " --help Print usage and this help message and exit.\n" 666 | " -- Options processing terminator.\n"); 667 | exit(0); 668 | } 669 | 670 | 671 | struct _info **read_dir(char *dir, int *n) 672 | { 673 | static char *path = NULL, *lbuf = NULL; 674 | static long pathsize, lbufsize; 675 | struct _info **dl; 676 | struct dirent *ent; 677 | struct stat lst,st; 678 | DIR *d; 679 | int ne, p = 0, len, rs; 680 | 681 | if (path == NULL) { 682 | pathsize = lbufsize = strlen(dir)+4096; 683 | path=xmalloc(pathsize); 684 | lbuf=xmalloc(lbufsize); 685 | } 686 | 687 | *n = 1; 688 | if ((d=opendir(dir)) == NULL) return NULL; 689 | 690 | dl = (struct _info **)xmalloc(sizeof(struct _info *) * (ne = MINIT)); 691 | 692 | while((ent = (struct dirent *)readdir(d))) { 693 | if (!strcmp("..",ent->d_name) || !strcmp(".",ent->d_name)) continue; 694 | if (Hflag && !strcmp(ent->d_name,"00Tree.html")) continue; 695 | if (!aflag && ent->d_name[0] == '.') continue; 696 | 697 | if (strlen(dir)+strlen(ent->d_name)+2 > pathsize) path = xrealloc(path,pathsize=(strlen(dir)+strlen(ent->d_name)+4096)); 698 | sprintf(path,"%s/%s",dir,ent->d_name); 699 | if (lstat(path,&lst) < 0) continue; 700 | if ((lst.st_mode & S_IFMT) == S_IFLNK) { 701 | if ((rs = stat(path,&st)) < 0) st.st_mode = 0; 702 | } else { 703 | rs = 0; 704 | st.st_mode = lst.st_mode; 705 | st.st_dev = lst.st_dev; 706 | st.st_ino = lst.st_ino; 707 | } 708 | 709 | #ifndef __EMX__ 710 | if ((lst.st_mode & S_IFMT) != S_IFDIR && !(((lst.st_mode & S_IFMT) == S_IFLNK) && lflag)) { 711 | if (pattern && patmatch(ent->d_name,pattern) != 1) continue; 712 | } 713 | if (ipattern && patmatch(ent->d_name,ipattern) == 1) continue; 714 | #endif 715 | 716 | if (dflag && ((st.st_mode & S_IFMT) != S_IFDIR)) continue; 717 | #ifndef __EMX__ 718 | if (pattern && ((lst.st_mode & S_IFMT) == S_IFLNK) && !lflag) continue; 719 | #endif 720 | 721 | if (p == (ne-1)) dl = (struct _info **)xrealloc(dl,sizeof(struct _info *) * (ne += MINC)); 722 | dl[p] = (struct _info *)xmalloc(sizeof(struct _info)); 723 | 724 | dl[p]->name = scopy(ent->d_name); 725 | /* We should just incorporate struct stat into _info, and elminate this unecessary copying. 726 | * Made sense long ago when we had fewer options and didn't need half of stat. 727 | */ 728 | dl[p]->mode = lst.st_mode; 729 | dl[p]->uid = lst.st_uid; 730 | dl[p]->gid = lst.st_gid; 731 | dl[p]->size = lst.st_size; 732 | dl[p]->dev = st.st_dev; 733 | dl[p]->inode = st.st_ino; 734 | dl[p]->lnk = NULL; 735 | dl[p]->orphan = FALSE; 736 | dl[p]->err = NULL; 737 | dl[p]->child = NULL; 738 | 739 | dl[p]->atime = lst.st_atime; 740 | dl[p]->ctime = lst.st_ctime; 741 | dl[p]->mtime = lst.st_mtime; 742 | 743 | #ifdef __EMX__ 744 | dl[p]->attr = lst.st_attr; 745 | #else 746 | 747 | if ((lst.st_mode & S_IFMT) == S_IFLNK) { 748 | if (lst.st_size+1 > lbufsize) lbuf = xrealloc(lbuf,lbufsize=(lst.st_size+8192)); 749 | if ((len=readlink(path,lbuf,lbufsize-1)) < 0) { 750 | dl[p]->lnk = scopy("[Error reading symbolic link information]"); 751 | dl[p]->isdir = FALSE; 752 | dl[p++]->lnkmode = st.st_mode; 753 | continue; 754 | } else { 755 | lbuf[len] = 0; 756 | dl[p]->lnk = scopy(lbuf); 757 | if (rs < 0) dl[p]->orphan = TRUE; 758 | dl[p]->lnkmode = st.st_mode; 759 | } 760 | } 761 | #endif 762 | 763 | /* These should be elminiated, as they're barely used */ 764 | dl[p]->isdir = ((st.st_mode & S_IFMT) == S_IFDIR); 765 | dl[p]->issok = ((st.st_mode & S_IFMT) == S_IFSOCK); 766 | dl[p]->isfifo = ((st.st_mode & S_IFMT) == S_IFIFO); 767 | dl[p++]->isexe = (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) ? 1 : 0; 768 | } 769 | closedir(d); 770 | *n = p; 771 | dl[p] = NULL; 772 | return dl; 773 | } 774 | 775 | /* This is for all the impossible things people wanted the old tree to do. 776 | * This can and will use a large amount of memory for large directory trees 777 | * and also take some time. 778 | */ 779 | struct _info **getfulltree(char *d, u_long lev, dev_t dev, off_t *size, char **err) 780 | { 781 | char *path; 782 | long pathsize = 0; 783 | struct _info **dir, **sav, **p, *sp; 784 | struct stat sb; 785 | int n; 786 | u_long lev_tmp; 787 | char *tmp_pattern = NULL, *start_rel_path; 788 | 789 | *err = NULL; 790 | if (Level >= 0 && lev > Level) return NULL; 791 | if (xdev && lev == 0) { 792 | stat(d,&sb); 793 | dev = sb.st_dev; 794 | } 795 | // if the directory name matches, turn off pattern matching for contents 796 | if (matchdirs && pattern) { 797 | lev_tmp = lev; 798 | start_rel_path = d + strlen(d); 799 | for (start_rel_path = d + strlen(d); start_rel_path != d; --start_rel_path) { 800 | if (*start_rel_path == '/') 801 | --lev_tmp; 802 | if (lev_tmp <= 0) { 803 | if (*start_rel_path) 804 | ++start_rel_path; 805 | break; 806 | } 807 | } 808 | if (*start_rel_path && patmatch(start_rel_path,pattern) == 1) { 809 | tmp_pattern = pattern; 810 | pattern = NULL; 811 | } 812 | } 813 | sav = dir = read_dir(d,&n); 814 | if (tmp_pattern) { 815 | pattern = tmp_pattern; 816 | tmp_pattern = NULL; 817 | } 818 | if (dir == NULL) { 819 | *err = scopy("error opening dir"); 820 | return NULL; 821 | } 822 | if (n == 0) { 823 | free_dir(sav); 824 | return NULL; 825 | } 826 | path = malloc(pathsize=4096); 827 | 828 | if (flimit > 0 && n > flimit) { 829 | sprintf(path,"%d entries exceeds filelimit, not opening dir",n); 830 | *err = scopy(path); 831 | free_dir(sav); 832 | free(path); 833 | return NULL; 834 | } 835 | if (cmpfunc) qsort(dir,n,sizeof(struct _info *),cmpfunc); 836 | 837 | if (lev >= maxdirs-1) { 838 | dirs = xrealloc(dirs,sizeof(int) * (maxdirs += 1024)); 839 | } 840 | 841 | while (*dir) { 842 | if ((*dir)->isdir && !(xdev && dev != (*dir)->dev)) { 843 | if ((*dir)->lnk) { 844 | if (lflag) { 845 | if (findino((*dir)->inode,(*dir)->dev)) { 846 | (*dir)->err = scopy("recursive, not followed"); 847 | } else { 848 | saveino((*dir)->inode, (*dir)->dev); 849 | if (*(*dir)->lnk == '/') 850 | (*dir)->child = getfulltree((*dir)->lnk,lev+1,dev,&((*dir)->size),&((*dir)->err)); 851 | else { 852 | if (strlen(d)+strlen((*dir)->lnk)+2 > pathsize) path=xrealloc(path,pathsize=(strlen(d)+strlen((*dir)->name)+1024)); 853 | if (fflag && !strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->lnk); 854 | else sprintf(path,"%s/%s",d,(*dir)->lnk); 855 | (*dir)->child = getfulltree(path,lev+1,dev,&((*dir)->size),&((*dir)->err)); 856 | } 857 | } 858 | } 859 | } else { 860 | if (strlen(d)+strlen((*dir)->name)+2 > pathsize) path=xrealloc(path,pathsize=(strlen(d)+strlen((*dir)->name)+1024)); 861 | if (fflag && !strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name); 862 | else sprintf(path,"%s/%s",d,(*dir)->name); 863 | saveino((*dir)->inode, (*dir)->dev); 864 | (*dir)->child = getfulltree(path,lev+1,dev,&((*dir)->size),&((*dir)->err)); 865 | } 866 | // prune empty folders, unless they match the requested pattern 867 | if (pruneflag && (*dir)->child == NULL && 868 | !(matchdirs && pattern && patmatch((*dir)->name,pattern) == 1)) { 869 | sp = *dir; 870 | for(p=dir;*p;p++) *p = *(p+1); 871 | n--; 872 | free(sp->name); 873 | if (sp->lnk) free(sp->lnk); 874 | free(sp); 875 | continue; 876 | } 877 | } 878 | if (duflag) *size += (*dir)->size; 879 | dir++; 880 | } 881 | free(path); 882 | if (n == 0) { 883 | free_dir(sav); 884 | return NULL; 885 | } 886 | return sav; 887 | } 888 | 889 | /* Sorting functions */ 890 | int alnumsort(struct _info **a, struct _info **b) 891 | { 892 | int v; 893 | 894 | if (dirsfirst && ((*a)->isdir != (*b)->isdir)) { 895 | return (*a)->isdir ? -1 : 1; 896 | } 897 | v = strcoll((*a)->name,(*b)->name); 898 | return reverse? -v : v; 899 | } 900 | 901 | int versort(struct _info **a, struct _info **b) 902 | { 903 | int v; 904 | 905 | if (dirsfirst && ((*a)->isdir != (*b)->isdir)) { 906 | return (*a)->isdir ? -1 : 1; 907 | } 908 | v = strverscmp((*a)->name,(*b)->name); 909 | return reverse? -v : v; 910 | } 911 | 912 | int mtimesort(struct _info **a, struct _info **b) 913 | { 914 | int v; 915 | 916 | if (dirsfirst && ((*a)->isdir != (*b)->isdir)) { 917 | return (*a)->isdir ? -1 : 1; 918 | } 919 | if ((*a)->mtime == (*b)->mtime) { 920 | v = strcoll((*a)->name,(*b)->name); 921 | return reverse? -v : v; 922 | } 923 | v = (*a)->mtime == (*b)->mtime? 0 : ((*a)->mtime < (*b)->mtime ? -1 : 1); 924 | return reverse? -v : v; 925 | } 926 | 927 | int ctimesort(struct _info **a, struct _info **b) 928 | { 929 | int v; 930 | 931 | if (dirsfirst && ((*a)->isdir != (*b)->isdir)) { 932 | return (*a)->isdir ? -1 : 1; 933 | } 934 | if ((*a)->ctime == (*b)->ctime) { 935 | v = strcoll((*a)->name,(*b)->name); 936 | return reverse? -v : v; 937 | } 938 | v = (*a)->ctime == (*b)->ctime? 0 : ((*a)->ctime < (*b)->ctime? -1 : 1); 939 | return reverse? -v : v; 940 | } 941 | 942 | int sizecmp(off_t a, off_t b) 943 | { 944 | return (a == b)? 0 : ((a < b)? 1 : -1); 945 | } 946 | 947 | int fsizesort(struct _info **a, struct _info **b) 948 | { 949 | int v; 950 | 951 | if (dirsfirst && ((*a)->isdir != (*b)->isdir)) { 952 | return (*a)->isdir ? -1 : 1; 953 | } 954 | v = sizecmp((*a)->size, (*b)->size); 955 | if (v == 0) v = strcoll((*a)->name,(*b)->name); 956 | return reverse? -v : v; 957 | } 958 | 959 | 960 | void *xmalloc (size_t size) 961 | { 962 | register void *value = malloc (size); 963 | if (value == 0) { 964 | fprintf(stderr,"tree: virtual memory exhausted.\n"); 965 | exit(1); 966 | } 967 | return value; 968 | } 969 | 970 | void *xrealloc (void *ptr, size_t size) 971 | { 972 | register void *value = realloc (ptr,size); 973 | if (value == 0) { 974 | fprintf(stderr,"tree: virtual memory exhausted.\n"); 975 | exit(1); 976 | } 977 | return value; 978 | } 979 | 980 | void free_dir(struct _info **d) 981 | { 982 | int i; 983 | 984 | for(i=0;d[i];i++) { 985 | free(d[i]->name); 986 | if (d[i]->lnk) free(d[i]->lnk); 987 | free(d[i]); 988 | } 989 | free(d); 990 | } 991 | 992 | char *gnu_getcwd() 993 | { 994 | int size = 100; 995 | char *buffer = (char *) xmalloc (size); 996 | 997 | while (1) 998 | { 999 | char *value = getcwd (buffer, size); 1000 | if (value != 0) 1001 | return buffer; 1002 | size *= 2; 1003 | free (buffer); 1004 | buffer = (char *) xmalloc (size); 1005 | } 1006 | } 1007 | 1008 | static inline char cond_lower(char c) 1009 | { 1010 | return ignorecase ? tolower(c) : c; 1011 | } 1012 | 1013 | /* 1014 | * Patmatch() code courtesy of Thomas Moore (dark@mama.indstate.edu) 1015 | * '|' support added by David MacMahon (davidm@astron.Berkeley.EDU) 1016 | * Case insensitive support added by Jason A. Donenfeld (Jason@zx2c4.com) 1017 | * returns: 1018 | * 1 on a match 1019 | * 0 on a mismatch 1020 | * -1 on a syntax error in the pattern 1021 | */ 1022 | int patmatch(char *buf, char *pat) 1023 | { 1024 | int match = 1,m,n; 1025 | char *bar = strchr(pat, '|'); 1026 | 1027 | /* If a bar is found, call patmatch recursively on the two sub-patterns */ 1028 | 1029 | if (bar) { 1030 | /* If the bar is the first or last character, it's a syntax error */ 1031 | if (bar == pat || !bar[1]) { 1032 | return -1; 1033 | } 1034 | /* Break pattern into two sub-patterns */ 1035 | *bar = '\0'; 1036 | match = patmatch(buf, pat); 1037 | if (!match) { 1038 | match = patmatch(buf,bar+1); 1039 | } 1040 | /* Join sub-patterns back into one pattern */ 1041 | *bar = '|'; 1042 | return match; 1043 | } 1044 | 1045 | while(*pat && match) { 1046 | switch(*pat) { 1047 | case '[': 1048 | pat++; 1049 | if(*pat != '^') { 1050 | n = 1; 1051 | match = 0; 1052 | } else { 1053 | pat++; 1054 | n = 0; 1055 | } 1056 | while(*pat != ']'){ 1057 | if(*pat == '\\') pat++; 1058 | if(!*pat /* || *pat == '/' */ ) return -1; 1059 | if(pat[1] == '-'){ 1060 | m = *pat; 1061 | pat += 2; 1062 | if(*pat == '\\' && *pat) 1063 | pat++; 1064 | if(cond_lower(*buf) >= cond_lower(m) && cond_lower(*buf) <= cond_lower(*pat)) 1065 | match = n; 1066 | if(!*pat) 1067 | pat--; 1068 | } else if(cond_lower(*buf) == cond_lower(*pat)) match = n; 1069 | pat++; 1070 | } 1071 | buf++; 1072 | break; 1073 | case '*': 1074 | pat++; 1075 | if(!*pat) return 1; 1076 | while(*buf && !(match = patmatch(buf++,pat))); 1077 | return match; 1078 | case '?': 1079 | if(!*buf) return 0; 1080 | buf++; 1081 | break; 1082 | case '\\': 1083 | if(*pat) 1084 | pat++; 1085 | default: 1086 | match = (cond_lower(*buf++) == cond_lower(*pat)); 1087 | break; 1088 | } 1089 | pat++; 1090 | if(match<1) return match; 1091 | } 1092 | if(!*buf) return match; 1093 | return 0; 1094 | } 1095 | 1096 | 1097 | /* 1098 | * They cried out for ANSI-lines (not really), but here they are, as an option 1099 | * for the xterm and console capable among you, as a run-time option. 1100 | */ 1101 | void indent(int maxlevel) 1102 | { 1103 | int i; 1104 | 1105 | if (ansilines) { 1106 | if (dirs[0]) fprintf(outfile,"\033(0"); 1107 | for(i=0; dirs[i] && i <= maxlevel; i++) { 1108 | if (dirs[i+1]) { 1109 | if (dirs[i] == 1) fprintf(outfile,"\170 "); 1110 | else printf(" "); 1111 | } else { 1112 | if (dirs[i] == 1) fprintf(outfile,"\164\161\161 "); 1113 | else fprintf(outfile,"\155\161\161 "); 1114 | } 1115 | } 1116 | if (dirs[0]) fprintf(outfile,"\033(B"); 1117 | } else { 1118 | if (Hflag) fprintf(outfile,"\t"); 1119 | for(i=0; dirs[i] && i <= maxlevel; i++) { 1120 | fprintf(outfile,"%s ", 1121 | dirs[i+1] ? (dirs[i]==1 ? linedraw->vert : (Hflag? "   " : " ") ) 1122 | : (dirs[i]==1 ? linedraw->vert_left:linedraw->corner)); 1123 | } 1124 | } 1125 | } 1126 | 1127 | 1128 | #ifdef __EMX__ 1129 | char *prot(long m) 1130 | #else 1131 | char *prot(mode_t m) 1132 | #endif 1133 | { 1134 | #ifdef __EMX__ 1135 | const u_short *p; 1136 | static char buf[6]; 1137 | char*cp; 1138 | 1139 | for(p=ifmt,cp=strcpy(buf,"adshr");*cp;++p,++cp) 1140 | if(!(m&*p)) 1141 | *cp='-'; 1142 | #else 1143 | static char buf[11], perms[] = "rwxrwxrwx"; 1144 | int i, b; 1145 | 1146 | for(i=0;ifmt[i] && (m&S_IFMT) != ifmt[i];i++); 1147 | buf[0] = fmt[i]; 1148 | 1149 | /* Nice, but maybe not so portable, it is should be no less portable than the old code. */ 1150 | for(b=S_IRUSR,i=0; i<9; b>>=1,i++) 1151 | buf[i+1] = (m & (b)) ? perms[i] : '-'; 1152 | if (m & S_ISUID) buf[3] = (buf[3]=='-')? 'S' : 's'; 1153 | if (m & S_ISGID) buf[6] = (buf[6]=='-')? 'S' : 's'; 1154 | if (m & S_ISVTX) buf[9] = (buf[9]=='-')? 'T' : 't'; 1155 | 1156 | buf[10] = 0; 1157 | #endif 1158 | return buf; 1159 | } 1160 | 1161 | static char *month[] = { 1162 | "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 1163 | }; 1164 | 1165 | #define SIXMONTHS (6*31*24*60*60) 1166 | 1167 | char *do_date(time_t t) 1168 | { 1169 | static char buf[256]; /* More than enough rope to hang em */ 1170 | struct tm *tm; 1171 | 1172 | tm = localtime(&t); 1173 | 1174 | if (timefmt) { 1175 | strftime(buf,255,timefmt,tm); 1176 | buf[255] = 0; 1177 | } else { 1178 | time_t c = time(0); 1179 | if (t > c) return " The Future "; 1180 | sprintf(buf,"%s %2d",month[tm->tm_mon],tm->tm_mday); 1181 | if (t+SIXMONTHS < c) sprintf(buf+6," %4d",1900+tm->tm_year); 1182 | else sprintf(buf+6," %2d:%02d",tm->tm_hour,tm->tm_min); 1183 | } 1184 | return buf; 1185 | } 1186 | 1187 | 1188 | void printit(char *s) 1189 | { 1190 | int c; 1191 | 1192 | if (Nflag) { 1193 | if (Qflag) fprintf(outfile, "\"%s\"",s); 1194 | else fprintf(outfile,"%s",s); 1195 | return; 1196 | } 1197 | if (mb_cur_max > 1) { 1198 | wchar_t *ws, *tp; 1199 | ws = xmalloc(sizeof(wchar_t)* (c=(strlen(s)+1))); 1200 | if (mbstowcs(ws,s,c) > 0) { 1201 | if (Qflag) putc('"',outfile); 1202 | for(tp=ws;*tp;tp++) { 1203 | if (iswprint(*tp)) fprintf(outfile,"%lc",(wint_t)*tp); 1204 | else { 1205 | if (qflag) putc('?',outfile); 1206 | else fprintf(outfile,"\\%03o",(unsigned int)*tp); 1207 | } 1208 | } 1209 | if (Qflag) putc('"',outfile); 1210 | free(ws); 1211 | return; 1212 | } 1213 | free(ws); 1214 | } 1215 | if (Qflag) putc('"',outfile); 1216 | for(;*s;s++) { 1217 | c = (unsigned char)*s; 1218 | #ifdef __EMX__ 1219 | if(_nls_is_dbcs_lead(*(unsigned char*)s)){ 1220 | putc(*s,outfile); 1221 | putc(*++s,outfile); 1222 | continue; 1223 | } 1224 | #endif 1225 | if((c >= 7 && c <= 13) || c == '\\' || (c == '"' && Qflag) || (c == ' ' && !Qflag)) { 1226 | putc('\\',outfile); 1227 | if (c > 13) putc(c, outfile); 1228 | else putc("abtnvfr"[c-7], outfile); 1229 | } else if (isprint(c)) putc(c,outfile); 1230 | else { 1231 | if (qflag) { 1232 | if (mb_cur_max > 1 && c > 127) putc(c,outfile); 1233 | else putc('?',outfile); 1234 | } else fprintf(outfile,"\\%03o",c); 1235 | } 1236 | } 1237 | if (Qflag) putc('"',outfile); 1238 | } 1239 | 1240 | int psize(char *buf, off_t size) 1241 | { 1242 | static char *iec_unit="BKMGTPEZY", *si_unit = "dkMGTPEZY"; 1243 | char *unit = siflag ? si_unit : iec_unit; 1244 | int idx, usize = siflag ? 1000 : 1024; 1245 | 1246 | if (hflag || siflag) { 1247 | for (idx=size= (usize*usize); idx++,size/=usize); 1248 | if (!idx) return sprintf(buf, " %4d", (int)size); 1249 | else return sprintf(buf, ((size/usize) >= 10)? " %3.0f%c" : " %3.1f%c" , (float)size/(float)usize,unit[idx]); 1250 | } else return sprintf(buf, sizeof(off_t) == sizeof(long long)? " %11lld" : " %9ld", (long long int)size); 1251 | } 1252 | 1253 | char Ftype(mode_t mode) 1254 | { 1255 | int m = mode & S_IFMT; 1256 | if (!dflag && m == S_IFDIR) return '/'; 1257 | else if (m == S_IFSOCK) return '='; 1258 | else if (m == S_IFIFO) return '|'; 1259 | else if (m == S_IFLNK) return '@'; /* Here, but never actually used though. */ 1260 | #ifdef S_IFDOOR 1261 | else if (m == S_ISDOOR) return '>'; 1262 | #endif 1263 | else if ((m == S_IFREG) && (mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return '*'; 1264 | return 0; 1265 | } 1266 | 1267 | char *fillinfo(char *buf, struct _info *ent) 1268 | { 1269 | int n; 1270 | buf[n=0] = 0; 1271 | #ifdef __USE_FILE_OFFSET64 1272 | if (inodeflag) n += sprintf(buf," %7lld",(long long)ent->inode); 1273 | #else 1274 | if (inodeflag) n += sprintf(buf," %7ld",(long int)ent->inode); 1275 | #endif 1276 | if (devflag) n += sprintf(buf+n, " %3d", (int)ent->dev); 1277 | #ifdef __EMX__ 1278 | if (pflag) n += sprintf(buf+n, " %s",prot(ent->attr)); 1279 | #else 1280 | if (pflag) n += sprintf(buf+n, " %s", prot(ent->mode)); 1281 | #endif 1282 | if (uflag) n += sprintf(buf+n, " %-8.32s", uidtoname(ent->uid)); 1283 | if (gflag) n += sprintf(buf+n, " %-8.32s", gidtoname(ent->gid)); 1284 | if (sflag) n += psize(buf+n,ent->size); 1285 | if (Dflag) n += sprintf(buf+n, " %s", do_date(cflag? ent->ctime : ent->mtime)); 1286 | 1287 | return buf; 1288 | } 1289 | --------------------------------------------------------------------------------