(linenum→info "unix/slp.c:2238")

tree/1.5.1.1/tree.c

    1: /* $Copyright: $
    2:  * Copyright (c) 1996 - 2007 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 <features.h>
   21: #include <stdlib.h>
   22: #include <stdio.h>
   23: #include <time.h>
   24: #include <string.h>
   25: #include <sys/time.h>
   26: #include <sys/types.h>
   27: #include <sys/stat.h>
   28: #include <dirent.h>
   29: #include <sys/file.h>
   30: #include <ctype.h>
   31: #include <unistd.h>
   32: #include <limits.h>
   33: #include <pwd.h>
   34: #include <grp.h>
   35: #ifdef __EMX__  /* for OS/2 systems */
   36: #  define INCL_DOSFILEMGR
   37: #  define INCL_DOSNLS
   38: #  include <os2.h>
   39: #  include <sys/nls.h>
   40: #  include <io.h>
   41:   /* On many systems stat() function is idential to lstat() function.
   42:    * But the OS/2 does not support symbolic links and doesn't have lstat() function.
   43:    */
   44: #  define         lstat          stat
   45: #  define         strcasecmp     stricmp
   46:   /* Following two functions, getcwd() and chdir() don't support for drive letters.
   47:    * To implement support them, use _getcwd2() and _chdir2().
   48:    */
   49: #  define getcwd _getcwd2
   50: #  define chdir _chdir2
   51: #endif
   52: 
   53: #include <locale.h>
   54: #include <wchar.h>
   55: #include <wctype.h>
   56: 
   57: static char *version ="$Version: $ tree v1.5.1.1 (c) 1996 - 2007 by Steve Baker, Thomas Moore, Francesc Rocher, Kyosuke Tokoro $";
   58: static char *hversion="\t\t\t tree v1.5.1.1 %s 1996 - 2007 by Steve Baker and Thomas Moore <br>\n"
   59:                       "\t\t\t HTML output hacked and copyleft %s 1998 by Francesc Rocher <br>\n"
   60:                       "\t\t\t Charsets / OS/2 support %s 2001 by Kyosuke Tokoro\n";
   61: 
   62: 
   63: #define scopy(x)        strcpy(xmalloc(strlen(x)+1),(x))
   64: #define MINIT           30       /* number of dir entries to initially allocate */
   65: #define MINC            20        /* allocation increment */
   66: 
   67: #ifndef TRUE
   68: enum bool {FALSE=0, TRUE};
   69: #endif
   70: 
   71: struct _info {
   72:   char *name;
   73:   char *lnk;
   74:   u_char isdir  : 1;
   75:   u_char issok  : 1;
   76:   u_char isexe  : 1;
   77:   u_char isfifo : 1;
   78:   u_char orphan : 1;
   79:   u_short mode, lnkmode, uid, gid;
   80:   off_t size;
   81:   time_t atime, ctime, mtime;
   82:   dev_t dev;
   83:   ino_t inode;
   84: #ifdef __EMX__
   85:   long attr;
   86: #endif
   87: };
   88: 
   89: /* Faster uid/gid -> name lookup with hash(tm)(r)(c) tables! */
   90: #define HASH(x)         ((x)&255)
   91: struct xtable {
   92:   u_short xid;
   93:   char *name;
   94:   struct xtable *nxt;
Permalink to this note guest: tree/1.5.1.1/tree.c:91-94 on Thu Jan 17 05:12:00 +0900 2008

リストの宣言

95: } *gtable[256], *utable[256];
Permalink to this note gniibe: tree/1.5.1.1/tree.c:95-95 on Tue Jan 08 10:17:55 +0900 2008

Should be static?

96: 97: /* Record inode numbers of followed sym-links to avoid refollowing them */ 98: #define inohash(x) ((x)&255) 99: struct inotable { 100: ino_t inode; 101: dev_t device; 102: struct inotable *nxt;
Permalink to this note guest: tree/1.5.1.1/tree.c:99-102 on Thu Jan 17 05:13:19 +0900 2008

リストの宣言

103: } *itable[256];
Permalink to this note gniibe: tree/1.5.1.1/tree.c:103-103 on Tue Jan 08 10:18:28 +0900 2008

Should be static?

104: 105: /* Hacked in DIR_COLORS support ---------------------------------------------- */ 106: enum { 107: CMD_COLOR, CMD_OPTIONS, CMD_TERM, CMD_EIGHTBIT, COL_NORMAL, COL_FILE, COL_DIR, 108: COL_LINK, COL_FIFO, COL_SOCK, COL_BLK, COL_CHR, COL_EXEC, DOT_EXTENSION, ERROR, 109: COL_ORPHAN, COL_MISSING, COL_LEFTCODE, COL_RIGHTCODE, COL_ENDCODE 110: }; 111: 112: char colorize = FALSE, ansilines = FALSE; 113: char *term, termmatch = FALSE, istty; 114: char *leftcode = NULL, *rightcode = NULL, *endcode = NULL; 115: 116: char *norm_flgs = NULL, *file_flgs = NULL, *dir_flgs = NULL, *link_flgs = NULL; 117: char *fifo_flgs = NULL, *sock_flgs = NULL, *block_flgs = NULL, *char_flgs = NULL; 118: char *exec_flgs = NULL, *orphan_flgs = NULL, *missing_flgs = NULL; 119: 120: char *vgacolor[] = { 121: "black", "red", "green", "yellow", "blue", "fuchsia", "aqua", "white", 122: NULL, NULL, 123: "transparent", "red", "green", "yellow", "blue", "fuchsia", "aqua", "black" 124: }; 125: 126: struct colortable { 127: char *term_flg, *CSS_name, *font_fg, *font_bg; 128: } colortable[11]; 129: 130: struct extensions { 131: char *ext; 132: char *term_flg, *CSS_name, *web_fg, *web_bg, *web_extattr; 133: struct extensions *nxt; 134: } *ext = NULL; 135: 136: const struct linedraw { 137: const char **name, *vert, *vert_left, *corner, *copy; 138: } *linedraw;
Permalink to this note gniibe: tree/1.5.1.1/tree.c:112-138 on Tue Jan 08 10:19:48 +0900 2008

Should be static?

139: 140: /* Hacked in DIR_COLORS support ---------------------------------------------- */ 141: 142: /* Function prototypes: */ 143: int color(u_short, char *, char, char), cmd(char *), patmatch(char *, char *); 144: int alnumsort(struct _info **, struct _info **); 145: int reversealnumsort(struct _info **, struct _info **); 146: int timesort(struct _info **, struct _info **); 147: int dirsfirstsort(struct _info **, struct _info **); 148: int findino(ino_t, dev_t); 149: void *xmalloc(size_t), *xrealloc(void *, size_t); 150: void listdir(char *, int *, int *, u_long, dev_t), usage(int); 151: void parse_dir_colors(), printit(unsigned char *), free_dir(struct _info **), indent(); 152: void saveino(ino_t, dev_t); 153: char **split(char *, char *, int *); 154: char *gidtoname(int), *uidtoname(int), *do_date(time_t); 155: char *gnu_getcwd(); 156: struct _info **read_dir(char *, int *); 157: void html_encode(FILE *, char *), url_encode(FILE *, char *); 158: const char *getcharset(void); 159: void initlinedraw(int); 160: void psize(char *buf, off_t size); 161: #ifdef __EMX__ 162: char *prot(long); 163: #else 164: char *prot(u_short); 165: #endif 166: 167: /* Globals */ 168: int dflag, lflag, pflag, sflag, Fflag, aflag, fflag, uflag, gflag; 169: int qflag, Nflag, Dflag, inodeflag, devflag, hflag; 170: int noindent, force_color, nocolor, xdev, noreport, nolinks; 171: char *pattern = NULL, *ipattern = NULL, *host = NULL, *title = "Directory Tree", *sp = " "; 172: const char *charset=NULL; 173: 174: int (*cmpfunc)() = alnumsort; 175: 176: u_char Hflag, Rflag; 177: int Level; 178: char *sLevel, *curdir, *outfilename = NULL; 179: FILE *outfile; 180: int *dirs, maxdirs;
Permalink to this note gniibe: tree/1.5.1.1/tree.c:142-180 on Tue Jan 08 10:20:36 +0900 2008

Most of them should be static?

181: 182: #ifdef CYGWIN 183: extern int MB_CUR_MAX; 184: #else 185: extern size_t MB_CUR_MAX; 186: #endif 187: 188: int main(int argc, char **argv) 189: { 190: char **dirname = NULL; 191: int i,j,n,p,q,dtotal,ftotal,colored = FALSE; 192: struct stat st; 193: 194: q = p = dtotal = ftotal = 0; 195: aflag = dflag = fflag = lflag = pflag = sflag = Fflag = uflag = gflag = FALSE; 196: Dflag = qflag = Nflag = Hflag = Rflag = hflag = FALSE; 197: noindent = force_color = nocolor = xdev = noreport = nolinks = FALSE; 198: inodeflag = devflag = FALSE; 199: dirs = xmalloc(sizeof(int) * (maxdirs=4096)); 200: dirs[0] = 0; 201: Level = -1; 202: 203: setlocale(LC_CTYPE, ""); 204: 205: memset(utable,0,sizeof(utable)); 206: memset(gtable,0,sizeof(gtable)); 207: memset(itable,0,sizeof(itable)); 208: 209: for(n=i=1;i<argc;i=n) { 210: n++; 211: if (argv[i][0] == '-' && argv[i][1]) { 212: for(j=1;argv[i][j];j++) { 213: switch(argv[i][j]) {
Permalink to this note guest: tree/1.5.1.1/tree.c:213-213 on Thu Jan 10 10:28:26 +0900 2008

ケースによって場合分け

214: case 'N': 215: Nflag = TRUE; 216: break; 217: case 'q': 218: qflag = TRUE; 219: break; 220: case 'd': 221: dflag = TRUE; 222: break; 223: case 'l': 224: lflag = TRUE; 225: break; 226: case 's': 227: sflag = TRUE; 228: break; 229: case 'h': 230: hflag = TRUE; 231: sflag = TRUE; /* Assume they also want -s */ 232: break; 233: case 'u': 234: uflag = TRUE; 235: break; 236: case 'g': 237: gflag = TRUE; 238: break; 239: case 'f': 240: fflag = TRUE; 241: break; 242: case 'F': 243: Fflag = TRUE; 244: break; 245: case 'a': 246: aflag = TRUE; 247: break; 248: case 'p': 249: pflag = TRUE; 250: break; 251: case 'i': 252: noindent = TRUE; 253: break; 254: case 'C': 255: force_color = TRUE; 256: break; 257: case 'n': 258: nocolor = TRUE; 259: break; 260: case 'x': 261: xdev = TRUE; 262: break; 263: case 'P': 264: if (argv[n] == NULL) { 265: fprintf(stderr,"tree: missing argument to -P option.\n"); 266: exit(1); 267: } 268: pattern = argv[n++]; 269: break; 270: case 'I': 271: if (argv[n] == NULL) { 272: fprintf(stderr,"tree: missing argument to -I option.\n"); 273: exit(1); 274: } 275: ipattern = argv[n++]; 276: break; 277: case 'A': 278: ansilines = TRUE; 279: break; 280: case 'S': 281: charset="IBM437"; 282: break; 283: case 'D': 284: Dflag = TRUE; 285: break; 286: case 't': 287: cmpfunc = timesort; 288: break; 289: case 'r': 290: cmpfunc = reversealnumsort; 291: break; 292: case 'H': 293: Hflag = TRUE; 294: if (argv[n] == NULL) { 295: fprintf(stderr,"tree: missing argument to -H option.\n"); 296: exit(1); 297: } 298: host = argv[n++]; 299: sp = "&nbsp;"; 300: break; 301: case 'T': 302: if (argv[n] == NULL) { 303: fprintf(stderr,"tree: missing argument to -T option.\n"); 304: exit(1); 305: } 306: title = argv[n++]; 307: break; 308: case 'R': 309: Rflag = TRUE; 310: break; 311: case 'L': 312: if ((sLevel = argv[n++]) == NULL) { 313: fprintf(stderr,"tree: Missing argument to -L option.\n"); 314: exit(1); 315: } 316: Level = strtoul(sLevel,NULL,0)-1; 317: if (Level < 0) { 318: fprintf(stderr,"tree: Invalid level, must be greater than 0.\n"); 319: exit(1); 320: } 321: break; 322: case 'o': 323: if (argv[n] == NULL) { 324: fprintf(stderr,"tree: missing argument to -o option.\n"); 325: exit(1); 326: } 327: outfilename = argv[n++]; 328: break; 329: case '-': 330: if (j == 1) { 331: if (!strcmp("--help",argv[i])) usage(2); 332: if (!strcmp("--version",argv[i])) { 333: char *v = version+12; 334: printf("%.*s\n",(int)strlen(v)-1,v); 335: exit(0); 336: } 337: if (!strcmp("--inodes",argv[i])) { 338: j = strlen(argv[i])-1; 339: inodeflag=TRUE; 340: break; 341: } 342: if (!strcmp("--device",argv[i])) { 343: j = strlen(argv[i])-1; 344: devflag=TRUE; 345: break; 346: } 347: if (!strcmp("--noreport",argv[i])) { 348: j = strlen(argv[i])-1; 349: noreport = TRUE; 350: break; 351: } 352: if (!strcmp("--nolinks",argv[i])) { 353: j = strlen(argv[i])-1; 354: nolinks = TRUE; 355: break; 356: } 357: if (!strcmp("--dirsfirst",argv[i])) { 358: j = strlen(argv[i])-1; 359: cmpfunc = dirsfirstsort; 360: break; 361: } 362: if (!strncmp("--charset",argv[i],9)){ 363: j = 9; 364: if (*(argv[i]+j) == '=') { 365: if (*(charset=(argv[i]+10))) { 366: j = strlen(argv[i])-1; 367: break; 368: } 369: } 370: if (argv[n] != NULL) { 371: charset=argv[n++]; 372: j = strlen(argv[i])-1; 373: } else { 374: initlinedraw(1); 375: exit(1); 376: } 377: break; 378: } 379: } 380: default: 381: fprintf(stderr,"tree: Invalid argument -`%c'.\n",argv[i][j]); 382: usage(1); 383: exit(1); 384: break; 385: } 386: } 387: } else { 388: if (!dirname) dirname = (char **)xmalloc(sizeof(char *) * (q=MINIT)); 389: else if (p == (q-2)) dirname = (char **)xrealloc(dirname,sizeof(char *) * (q+=MINC)); 390: dirname[p++] = scopy(argv[i]); 391: } 392: } 393: if (p) dirname[p] = NULL; 394: 395: if (outfilename == NULL) { 396: #ifdef __EMX__ 397: _fsetmode(outfile=stdout,Hflag?"b":"t"); 398: #else 399: outfile = stdout; 400: #endif 401: } else { 402: #ifdef __EMX__ 403: outfile = fopen(outfilename,Hflag?"wb":"wt"); 404: #else 405: outfile = fopen(outfilename,"w"); 406: #endif 407: if (outfile == NULL) { 408: fprintf(stderr,"tree: invalid filename '%s'\n",outfilename); 409: exit(1); 410: } 411: } 412: 413: parse_dir_colors(); 414: initlinedraw(0); 415: 416: if (Rflag && (Level == -1)) 417: Rflag = FALSE; 418: 419: if (Hflag) { 420: fprintf(outfile,"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n"); 421: fprintf(outfile,"<html>\n"); 422: fprintf(outfile,"\t<head>\n"); 423: if (charset) 424: fprintf(outfile,"\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\">\n",charset); 425: else 426: fprintf(outfile,"\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n"); 427: 428: fprintf(outfile,"\t\t<meta name=\"Author\" content=\"Made by 'tree'\">\n"); 429: fprintf(outfile,"\t\t<meta name=\"GENERATOR\" content=\"%s\">\n",version); 430: fprintf(outfile,"\t\t<title>%s</title>\n",title); 431: fprintf(outfile,"\t\t<style type=\"text/css\">\n\t\t\t<!-- \n"); 432: fprintf(outfile,"\t\t\tBODY { font-family : courier, monospace, sans-serif; }\n"); 433: fprintf(outfile,"\t\t\tP { font-weight: normal; font-family : courier, monospace, sans-serif; color: black; background-color: transparent;}\n"); 434: fprintf(outfile,"\t\t\tB { font-weight: normal; color: black; background-color: transparent;}\n"); 435: fprintf(outfile,"\t\t\tA:visited { font-weight : normal; text-decoration : none; background-color : transparent; margin : 0px 0px 0px 0px; padding : 0px 0px 0px 0px; display: inline; }\n"); 436: fprintf(outfile,"\t\t\tA:link { font-weight : normal; text-decoration : none; margin : 0px 0px 0px 0px; padding : 0px 0px 0px 0px; display: inline; }\n"); 437: fprintf(outfile,"\t\t\tA:hover { color : #000000; font-weight : normal; text-decoration : underline; background-color : yellow; margin : 0px 0px 0px 0px; padding : 0px 0px 0px 0px; display: inline; }\n"); 438: fprintf(outfile,"\t\t\tA:active { color : #000000; font-weight: normal; background-color : transparent; margin : 0px 0px 0px 0px; padding : 0px 0px 0px 0px; display: inline; }\n"); 439: fprintf(outfile,"\t\t\t.VERSION { font-size: small; font-family : arial, sans-serif; }\n"); 440: 441: /* We can use CSS for nolinks as well */ 442: fprintf(outfile,"\t\t\t.NORM { color: black; background-color: transparent;}\n"); 443: fprintf(outfile,"\t\t\t.FIFO { color: purple; background-color: transparent;}\n"); 444: fprintf(outfile,"\t\t\t.CHAR { color: yellow; background-color: transparent;}\n"); 445: fprintf(outfile,"\t\t\t.DIR { color: blue; background-color: transparent;}\n"); 446: fprintf(outfile,"\t\t\t.BLOCK { color: yellow; background-color: transparent;}\n"); 447: fprintf(outfile,"\t\t\t.LINK { color: aqua; background-color: transparent;}\n"); 448: fprintf(outfile,"\t\t\t.SOCK { color: fuchsia; background-color: transparent;}\n"); 449: fprintf(outfile,"\t\t\t.EXEC { color: green; background-color: transparent;}\n"); 450: 451: fprintf(outfile,"\t\t\t-->\n\t\t</style>\n"); 452: fprintf(outfile,"\t</head>\n"); 453: fprintf(outfile,"\t<body>\n"); 454: fprintf(outfile,"\t\t<h1>%s</h1>\n\t\t\t<p>",title); 455: 456: fflag = FALSE; 457: if (nolinks) { 458: if (force_color) fprintf(outfile, "<b class=\"NORM\">%s</b>\n",host); 459: else fprintf(outfile,"%s\n",host); 460: } else { 461: if (force_color) fprintf(outfile,"<a class=\"NORM\" href=\"%s\">%s</a>\n",host,host); 462: else fprintf(outfile,"<a href=\"%s\">%s</a>\n",host,host); 463: } 464: curdir = gnu_getcwd(); 465: } 466: 467: if (dirname) { 468: for(colored=i=0;dirname[i];i++,colored=0) { 469: if (fflag) { 470: do { 471: j=strlen(dirname[i]); 472: if (j > 1 && dirname[i][j-1] == '/') dirname[i][--j] = 0; 473: } while (j > 1 && dirname[i][j-1] == '/'); 474: } 475: if ((n = lstat(dirname[i],&st)) >= 0) { 476: saveino(st.st_ino, st.st_dev); 477: if (colorize) colored = color(st.st_mode,dirname[i],n<0,FALSE); 478: } 479: if (!Hflag) printit(dirname[i]); 480: if (colored) fprintf(outfile,"%s",endcode); 481: if (!Hflag) listdir(dirname[i],&dtotal,&ftotal,0,0); 482: else { 483: if (chdir(dirname[i])) { 484: fprintf(outfile,"%s [error opening dir]\n",dirname[i]); 485: exit(1); 486: } else { 487: listdir(".",&dtotal,&ftotal,0,0); 488: chdir(curdir); 489: } 490: } 491: } 492: } else { 493: if ((n = lstat(".",&st)) >= 0) { 494: saveino(st.st_ino, st.st_dev); 495: if (colorize) colored = color(st.st_mode,".",n<0,FALSE); 496: } 497: if (!Hflag) fprintf(outfile,"."); 498: if (colored) fprintf(outfile,"%s",endcode); 499: listdir(".",&dtotal,&ftotal,0,0); 500: } 501: 502: if (Hflag) 503: fprintf(outfile,"\t\t<br><br>\n\t\t</p>\n\t\t<p>\n"); 504: 505: if (!noreport) { 506: if (dflag) 507: fprintf(outfile,"\n%d director%s\n",dtotal,(dtotal