📄 tree.c
字号:
/* $Copyright: $ * Copyright (c) 1996 - 2007 by Steve Baker (ice@mama.indstate.edu) * All Rights reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <features.h>#include <stdlib.h>#include <stdio.h>#include <time.h>#include <string.h>#include <sys/time.h>#include <sys/types.h>#include <sys/stat.h>#include <dirent.h>#include <sys/file.h>#include <ctype.h>#include <unistd.h>#include <limits.h>#include <pwd.h>#include <grp.h>#ifdef __EMX__ /* for OS/2 systems */# define INCL_DOSFILEMGR# define INCL_DOSNLS# include <os2.h># include <sys/nls.h># include <io.h> /* On many systems stat() function is idential to lstat() function. * But the OS/2 does not support symbolic links and doesn't have lstat() function. */# define lstat stat# define strcasecmp stricmp /* Following two functions, getcwd() and chdir() don't support for drive letters. * To implement support them, use _getcwd2() and _chdir2(). */# define getcwd _getcwd2# define chdir _chdir2#endif#include <locale.h>#include <wchar.h>#include <wctype.h>static char *version ="$Version: $ tree v1.5.1 (c) 1996 - 2007 by Steve Baker, Thomas Moore, Francesc Rocher, Kyosuke Tokoro $";static char *hversion="\t\t\t tree v1.5.1 %s 1996 - 2007 by Steve Baker and Thomas Moore <br>\n" "\t\t\t HTML output hacked and copyleft %s 1998 by Francesc Rocher <br>\n" "\t\t\t Charsets / OS/2 support %s 2001 by Kyosuke Tokoro\n";#define scopy(x) strcpy(xmalloc(strlen(x)+1),(x))#define MINIT 30 /* number of dir entries to initially allocate */#define MINC 20 /* allocation increment */#ifndef TRUEenum bool {FALSE=0, TRUE};#endifstruct _info { char *name; char *lnk; u_char isdir : 1; u_char issok : 1; u_char isexe : 1; u_char isfifo : 1; u_char orphan : 1; u_short mode, lnkmode, uid, gid; off_t size; time_t atime, ctime, mtime; dev_t dev; ino_t inode;#ifdef __EMX__ long attr;#endif};/* Faster uid/gid -> name lookup with hash(tm)(r)(c) tables! */#define HASH(x) ((x)&255)struct xtable { u_short xid; char *name; struct xtable *nxt;} *gtable[256], *utable[256];/* Record inode numbers of followed sym-links to avoid refollowing them */#define inohash(x) ((x)&255)struct inotable { ino_t inode; dev_t device; struct inotable *nxt;} *itable[256];/* Hacked in DIR_COLORS support ---------------------------------------------- */enum { CMD_COLOR, CMD_OPTIONS, CMD_TERM, CMD_EIGHTBIT, COL_NORMAL, COL_FILE, COL_DIR, COL_LINK, COL_FIFO, COL_SOCK, COL_BLK, COL_CHR, COL_EXEC, DOT_EXTENSION, ERROR, COL_ORPHAN, COL_MISSING, COL_LEFTCODE, COL_RIGHTCODE, COL_ENDCODE};char colorize = FALSE, ansilines = FALSE;char *term, termmatch = FALSE, istty;char *leftcode = NULL, *rightcode = NULL, *endcode = NULL;char *norm_flgs = NULL, *file_flgs = NULL, *dir_flgs = NULL, *link_flgs = NULL;char *fifo_flgs = NULL, *sock_flgs = NULL, *block_flgs = NULL, *char_flgs = NULL;char *exec_flgs = NULL, *orphan_flgs = NULL, *missing_flgs = NULL;char *vgacolor[] = { "black", "red", "green", "yellow", "blue", "fuchsia", "aqua", "white", NULL, NULL, "transparent", "red", "green", "yellow", "blue", "fuchsia", "aqua", "black"};struct colortable { char *term_flg, *CSS_name, *font_fg, *font_bg;} colortable[11];struct extensions { char *ext; char *term_flg, *CSS_name, *web_fg, *web_bg, *web_extattr; struct extensions *nxt;} *ext = NULL;const struct linedraw { const char **name, *vert, *vert_left, *corner, *copy;} *linedraw;/* Hacked in DIR_COLORS support ---------------------------------------------- *//* Function prototypes: */int color(u_short, char *, char, char), cmd(char *), patmatch(char *, char *);int alnumsort(struct _info **, struct _info **);int reversealnumsort(struct _info **, struct _info **);int timesort(struct _info **, struct _info **);int dirsfirstsort(struct _info **, struct _info **);int findino(ino_t, dev_t);void *xmalloc(size_t), *xrealloc(void *, size_t);void listdir(char *, int *, int *, u_long, dev_t), usage(int);void parse_dir_colors(), printit(unsigned char *), free_dir(struct _info **), indent();void saveino(ino_t, dev_t);char **split(char *, char *, int *);char *gidtoname(int), *uidtoname(int), *do_date(time_t);char *gnu_getcwd();struct _info **read_dir(char *, int *);void html_encode(FILE *, char *), url_encode(FILE *, char *);const char *getcharset(void);void initlinedraw(int);void psize(char *buf, off_t size);#ifdef __EMX__ char *prot(long);#else char *prot(u_short);#endif/* Globals */int dflag, lflag, pflag, sflag, Fflag, aflag, fflag, uflag, gflag;int qflag, Nflag, Dflag, inodeflag, devflag, hflag;int noindent, force_color, nocolor, xdev, noreport, nolinks;char *pattern = NULL, *ipattern = NULL, *host = NULL, *title = "Directory Tree", *sp = " ";const char *charset=NULL;int (*cmpfunc)() = alnumsort;u_char Hflag, Rflag;int Level;char *sLevel, *curdir, *outfilename = NULL;FILE *outfile;int *dirs, maxdirs;#ifdef CYGWINextern int MB_CUR_MAX;#elseextern size_t MB_CUR_MAX;#endifint main(int argc, char **argv){ char **dirname = NULL; int i,j,n,p,q,dtotal,ftotal,colored = FALSE; struct stat st; q = p = dtotal = ftotal = 0; aflag = dflag = fflag = lflag = pflag = sflag = Fflag = uflag = gflag = FALSE; Dflag = qflag = Nflag = Hflag = Rflag = hflag = FALSE; noindent = force_color = nocolor = xdev = noreport = nolinks = FALSE; inodeflag = devflag = FALSE; dirs = xmalloc(sizeof(int) * (maxdirs=4096)); dirs[0] = 0; Level = -1; setlocale(LC_CTYPE, ""); memset(utable,0,sizeof(utable)); memset(gtable,0,sizeof(gtable)); memset(itable,0,sizeof(itable)); for(n=i=1;i<argc;i=n) { n++; if (argv[i][0] == '-' && argv[i][1]) { for(j=1;argv[i][j];j++) { switch(argv[i][j]) { case 'N': Nflag = TRUE; break; case 'q': qflag = TRUE; break; case 'd': dflag = TRUE; break; case 'l': lflag = TRUE; break; case 's': sflag = TRUE; break; case 'h': hflag = TRUE; sflag = TRUE; /* Assume they also want -s */ break; case 'u': uflag = TRUE; break; case 'g': gflag = TRUE; break; case 'f': fflag = TRUE; break; case 'F': Fflag = TRUE; break; case 'a': aflag = TRUE; break; case 'p': pflag = TRUE; break; case 'i': noindent = TRUE; break; case 'C': force_color = TRUE; break; case 'n': nocolor = TRUE; break; case 'x': xdev = TRUE; break; case 'P': if (argv[n] == NULL) { fprintf(stderr,"tree: missing argument to -P option.\n"); exit(1); } pattern = argv[n++]; break; case 'I': if (argv[n] == NULL) { fprintf(stderr,"tree: missing argument to -I option.\n"); exit(1); } ipattern = argv[n++]; break; case 'A': ansilines = TRUE; break; case 'S': charset="IBM437"; break; case 'D': Dflag = TRUE; break; case 't': cmpfunc = timesort; break; case 'r': cmpfunc = reversealnumsort; break; case 'H': Hflag = TRUE; if (argv[n] == NULL) { fprintf(stderr,"tree: missing argument to -H option.\n"); exit(1); } host = argv[n++]; sp = " "; break; case 'T': if (argv[n] == NULL) { fprintf(stderr,"tree: missing argument to -T option.\n"); exit(1); } title = argv[n++]; break; case 'R': Rflag = TRUE; break; case 'L': if ((sLevel = argv[n++]) == NULL) { fprintf(stderr,"tree: Missing argument to -L option.\n"); exit(1); } Level = strtoul(sLevel,NULL,0)-1; if (Level < 0) { fprintf(stderr,"tree: Invalid level, must be greater than 0.\n"); exit(1); } break; case 'o': if (argv[n] == NULL) { fprintf(stderr,"tree: missing argument to -o option.\n"); exit(1); } outfilename = argv[n++]; break; case '-': if (j == 1) { if (!strcmp("--help",argv[i])) usage(2); if (!strcmp("--version",argv[i])) { char *v = version+12; printf("%.*s\n",(int)strlen(v)-1,v); exit(0); } if (!strcmp("--inodes",argv[i])) { j = strlen(argv[i])-1; inodeflag=TRUE; break; } if (!strcmp("--device",argv[i])) { j = strlen(argv[i])-1; devflag=TRUE; break; } if (!strcmp("--noreport",argv[i])) { j = strlen(argv[i])-1; noreport = TRUE; break; } if (!strcmp("--nolinks",argv[i])) { j = strlen(argv[i])-1; nolinks = TRUE; break; } if (!strcmp("--dirsfirst",argv[i])) { j = strlen(argv[i])-1; cmpfunc = dirsfirstsort; break; } if (!strncmp("--charset",argv[i],9)){ j = 9; if (*(argv[i]+j) == '=') { fprintf(stderr,"argv[%d]+9 == '='\n",i); if (*(charset=(argv[i]+10))) { j = strlen(argv[i])-1; break; } } if (argv[n] != NULL) { charset=argv[n++]; j = strlen(argv[i])-1; fprintf(stderr,"charset = '%s' (n=%d)\n",charset,n-1); } else { initlinedraw(1); exit(1); } break; } } default: fprintf(stderr,"tree: Invalid argument -`%c'.\n",argv[i][j]); usage(1); exit(1); break; } } } else { if (!dirname) dirname = (char **)xmalloc(sizeof(char *) * (q=MINIT)); else if (p == (q-2)) dirname = (char **)xrealloc(dirname,sizeof(char *) * (q+=MINC)); dirname[p++] = scopy(argv[i]); } } if (p) dirname[p] = NULL; if (outfilename == NULL) {#ifdef __EMX__ _fsetmode(outfile=stdout,Hflag?"b":"t");#else outfile = stdout;#endif } else {#ifdef __EMX__ outfile = fopen(outfilename,Hflag?"wb":"wt");#else outfile = fopen(outfilename,"w");#endif if (outfile == NULL) { fprintf(stderr,"tree: invalid filename '%s'\n",outfilename); exit(1); } } parse_dir_colors(); initlinedraw(0); if (Rflag && (Level == -1)) Rflag = FALSE; if (Hflag) { fprintf(outfile,"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n"); fprintf(outfile,"<html>\n"); fprintf(outfile,"\t<head>\n"); if (charset) fprintf(outfile,"\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\">\n",charset); else fprintf(outfile,"\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n"); fprintf(outfile,"\t\t<meta name=\"Author\" content=\"Made by 'tree'\">\n"); fprintf(outfile,"\t\t<meta name=\"GENERATOR\" content=\"%s\">\n",version); fprintf(outfile,"\t\t<title>%s</title>\n",title);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -