dono@killer.DALLAS.TX.US (Don OConnell) (01/08/89)
Here is a program that prints a tree of directory structs(graphical or non-gr) as well as printing sizes of directories(similar to du). Enjoy! ------------------------------Cut Here------------------------------------- #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: compile.bat customize.h hash.c hash.h makefile # patchlevel.h readme vtree.1 vtree.c vtree.man # Wrapped by dono@killer on Sat Jan 7 14:50:55 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f compile.bat -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"compile.bat\" else echo shar: Extracting \"compile.bat\" \(213 characters\) sed "s/^X//" >compile.bat <<'END_OF_compile.bat' Xtcc -mt -I\minix\include -G -O -r -Z -1 -c *.c Xif errorlevel 1 goto end Xtlink /m/n/c/d \minix\lib\crtso vtree hash,vtree,,\minix\lib\tminix Xif errorlevel 1 goto end Xecho dos2out X..\commands\dos2out -d vtree X:end END_OF_compile.bat if test 213 -ne `wc -c <compile.bat`; then echo shar: \"compile.bat\" unpacked with wrong size! fi # end of overwriting check fi if test -f customize.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"customize.h\" else echo shar: Extracting \"customize.h\" \(429 characters\) sed "s/^X//" >customize.h <<'END_OF_customize.h' X/* agef X X SCCS ID @(#)customize.h 1.6 7/9/87 X X This is the customizations file. It changes our ideas of X how to read directories. X*/ X X/*#define FLOAT_FORMAT "%d %#4.1fM" /* if your printf does %# */ X#define FLOAT_FORMAT "%d %4.1fM" /* if it doesn't do %# */ X X#define NAMELEN 255 /* max size of a full pathname */ X X# include <dir.h> X# define OPEN DIR X# define READ struct direct X# define NAME(x) ((x).d_name) END_OF_customize.h if test 429 -ne `wc -c <customize.h`; then echo shar: \"customize.h\" unpacked with wrong size! fi # end of overwriting check fi if test -f hash.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"hash.c\" else echo shar: Extracting \"hash.c\" \(4351 characters\) sed "s/^X//" >hash.c <<'END_OF_hash.c' X/* hash.c X X SCCS ID @(#)hash.c 1.6 7/9/87 X X * Hash table routines for AGEF. These routines keep the program from X * counting the same inode twice. This can happen in the case of a X * file with multiple links, as in a news article posted to several X * groups. The use of a hashing scheme was suggested by Anders X * Andersson of Uppsala University, Sweden. (enea!kuling!andersa) X */ X X/* hash.c change history: X 28 March 1987 David S. Hayes (merlin@hqda-ai.UUCP) X Initial version. X*/ X X#include <stdio.h> X#include <sys/types.h> X#include "hash.h" X X Xstatic struct htable *tables[TABLES]; X X/* These are for statistical use later on. */ Xstatic int hs_tables = 0, /* number of tables allocated */ X hs_duplicates = 0, /* number of OLD's returned */ X hs_buckets = 0, /* number of buckets allocated */ X hs_extensions = 0, /* number of bucket extensions */ X hs_searches = 0,/* number of searches */ X hs_compares = 0,/* total key comparisons */ X hs_longsearch = 0; /* longest search */ X X X /* X * This routine takes in a device/inode, and tells whether it's been X * entered in the table before. If it hasn't, then the inode is added X * to the table. A separate table is maintained for each major device X * number, so separate file systems each have their own table. X */ X Xh_enter(dev, ino) X dev_t dev; X ino_t ino; X{ X static struct htable *tablep = (struct htable *) 0; X register struct hbucket *bucketp; X register ino_t *keyp; X int i; X X hs_searches++; /* stat, total number of calls */ X X /* X * Find the hash table for this device. We keep the table pointer X * around between calls to h_enter, so that we don't have to locate X * the correct hash table every time we're called. I don't expect X * to jump from device to device very often. X */ X if (!tablep || tablep->device != dev) { X for (i = 0; tables[i] && tables[i]->device != dev;) X i++; X if (!tables[i]) { X tables[i] = (struct htable *) malloc(sizeof(struct htable)); X if (tables[i] == NULL) { X perror("can't malloc hash table"); X return NEW; X }; X/* bzero(tables[i], sizeof(struct htable)); */ X memset((char *) tables[i], '\0', sizeof (struct htable)); X tables[i]->device = dev; X hs_tables++; /* stat, new table allocated */ X }; X tablep = tables[i]; X }; X X /* Which bucket is this inode assigned to? */ X bucketp = &tablep->buckets[ino % BUCKETS]; X X /* X * Now check the key list for that bucket. Just a simple linear X * search. X */ X keyp = bucketp->keys; X for (i = 0; i < bucketp->filled && *keyp != ino;) X i++, keyp++; X X hs_compares += i + 1; /* stat, total key comparisons */ X X if (i && *keyp == ino) { X hs_duplicates++; /* stat, duplicate inodes */ X return OLD; X }; X X /* Longest search. Only new entries could be the longest. */ X if (bucketp->filled >= hs_longsearch) X hs_longsearch = bucketp->filled + 1; X X /* Make room at the end of the bucket's key list. */ X if (bucketp->filled == bucketp->length) { X /* No room, extend the key list. */ X if (!bucketp->length) { X bucketp->keys = (ino_t *) calloc(EXTEND, sizeof(ino_t)); X if (bucketp->keys == NULL) { X perror("can't malloc hash bucket"); X return NEW; X }; X hs_buckets++; X } else { X bucketp->keys = (ino_t *) X realloc(bucketp->keys, X (EXTEND + bucketp->length) * sizeof(ino_t)); X if (bucketp->keys == NULL) { X perror("can't extend hash bucket"); X return NEW; X }; X hs_extensions++; X }; X bucketp->length += EXTEND; X }; X X bucketp->keys[++(bucketp->filled)] = ino; X return NEW; X} X X X /* Buffer statistics functions. Print 'em out. */ X X#ifdef HSTATS Xvoid Xh_stats() X{ X fprintf(stderr, "\nHash table management statistics:\n"); X fprintf(stderr, " Tables allocated: %d\n", hs_tables); X fprintf(stderr, " Buckets used: %d\n", hs_buckets); X fprintf(stderr, " Bucket extensions: %d\n\n", hs_extensions); X fprintf(stderr, " Total searches: %d\n", hs_searches); X fprintf(stderr, " Duplicate keys found: %d\n", hs_duplicates); X if (hs_searches) X fprintf(stderr, " Average key search: %d\n", X hs_compares / hs_searches); X fprintf(stderr, " Longest key search: %d\n", hs_longsearch); X fflush(stderr); X} X X#endif END_OF_hash.c if test 4351 -ne `wc -c <hash.c`; then echo shar: \"hash.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f hash.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"hash.h\" else echo shar: Extracting \"hash.h\" \(625 characters\) sed "s/^X//" >hash.h <<'END_OF_hash.h' X/* Defines for the agef hashing functions. X X SCCS ID @(#)hash.h 1.6 7/9/87 X */ X X#define BUCKETS 257 /* buckets per hash table */ X#define TABLES 50 /* hash tables */ X#define EXTEND 100 /* how much space to add to a bucket */ X Xstruct hbucket { X int length; /* key space allocated */ X int filled; /* key space used */ X ino_t *keys; X}; X Xstruct htable { X dev_t device; /* device this table is for */ X struct hbucket buckets[BUCKETS]; /* the buckets of the table */ X}; X X#define OLD 0 /* inode was in hash already */ X#define NEW 1 /* inode has been added to hash */ END_OF_hash.h if test 625 -ne `wc -c <hash.h`; then echo shar: \"hash.h\" unpacked with wrong size! fi # end of overwriting check fi if test -f makefile -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"makefile\" else echo shar: Extracting \"makefile\" \(1504 characters\) sed "s/^X//" >makefile <<'END_OF_makefile' X# Build VTREE X# X# Define the type of system we're working with. Three X# choices: X# X# 1. BSD Unix 4.2 or 4.3. Directory read support in the X# standard library, so we don't have to do much. Select BSD. X# X# 2. System V. I depend on Doug Gwyn's directory reading X# routines. They were posted to Usenet "comp.sources" early in X# May 1987. They're worth the effort to get, if you don't have X# them already. Select SYS_V. Be sure to define NLIB to be the X# 'cc' option to include the directory library. X# X# 3. System III, or machines without any directory read X# packages. I have a minimal kludge. Select SYS_III. X# X X# Case 1: X#SYS= -DBSD X#NLIB= X X# Case 2: XSYS= -DSYS_V XNLIB= -lndir X X# Case 3: X#SYS= -DSYS_III X#NLIB= X X X# Standard things you may wish to change: X# X# INSTALL directory to install vtree in X XINSTALL = /usr/local/bin X X X# The following OPTIONS may be defined: X# X# LSTAT we have the lstat(2) system call (BSD only) X# HSTATS print hashing statistics at end of run X# X# Define LSTAT, HSTATS here X XOPTIONS = X X# END OF USER-DEFINED OPTIONS X X XCFLAGS= -O $(SYS) $(OPTIONS) XSRCS= vtree.c hash.c direct.c \ X hash.h customize.h patchlevel.h XOBJS= vtree.o hash.o X Xvtree: $(OBJS) X cc -o vtree $(CFLAGS) $(OBJS) $(NLIB) X Xinstall: vtree X cp vtree $(INSTALL) X chown local $(INSTALL)/vtree X chgrp pd $(INSTALL)/vtree X chmod 755 $(INSTALL)/vtree X Xclean: X rm -f $(OBJS) vtree *~ X Xvtree.o: vtree.c direct.c hash.h customize.h patchlevel.h X Xhash.o: hash.c hash.h customize.h patchlevel.h END_OF_makefile if test 1504 -ne `wc -c <makefile`; then echo shar: \"makefile\" unpacked with wrong size! fi # end of overwriting check fi if test -f patchlevel.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"patchlevel.h\" else echo shar: Extracting \"patchlevel.h\" \(93 characters\) sed "s/^X//" >patchlevel.h <<'END_OF_patchlevel.h' X/* Patchlevel for VTREE X X*/ X X#define PATCHLEVEL V1.0 X#define VERSION "VTREE 1.0 4/26/88\n" END_OF_patchlevel.h if test 93 -ne `wc -c <patchlevel.h`; then echo shar: \"patchlevel.h\" unpacked with wrong size! fi # end of overwriting check fi if test -f readme -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"readme\" else echo shar: Extracting \"readme\" \(1130 characters\) sed "s/^X//" >readme <<'END_OF_readme' X This is the first release of the VTREE (please pronounce this XV-TREE, for "visual files") program. The program is designed to show Xthe layout of a directory tree or filesystem. It has options to show Xthe amount of storage being taken up in each directory, count the number Xof inodes, etc. X X VTREE is dependent on the UCB directory reading routines. XPublic-domain routines for System V have been released to the Usenet X(comp.sources.unix) by Doug Gwyn (gwyn@brl.mil). If you don't have Xthem, they're worth your trouble to get. Still, you may be able to use Xthe System III configuration of the Makefile as a stopgap measure. X X X The program was originally the program AGEF, written by David S. XHayes. As it stands now the hashing routines are untouched by myself, Xbut most of the rest of the program is different. The System III Xroutines are also his. X X X I hope this program will be useful to you. If you find bugs in Xit or have any suggestions for improvements, I'd like to hear about Xthem. X XJonathan B. Bayer XIntelligent Software Products, Inc. XRockville Centre, NY 11570 XPhone: (516) 766-2867 Xusenet: uunet!ispi!root X END_OF_readme if test 1130 -ne `wc -c <readme`; then echo shar: \"readme\" unpacked with wrong size! fi # end of overwriting check fi if test -f vtree.1 -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"vtree.1\" else echo shar: Extracting \"vtree.1\" \(1478 characters\) sed "s/^X//" >vtree.1 <<'END_OF_vtree.1' X.TH VTREE 1 local X.SH NAME Xvtree \- print a visual tree of a directory structure X.SH SYNOPSIS X.B vtree X[ \-d] [ \-h # ] [ \-i ] [ \-s ] [ \-q ] [ \-v ] [ \-V ] X.SH DESCRIPTION X.IP XVtree is a program which scans directories/filesystems and displays the structure on the Xstandard output. Normally it will ignore duplicate inodes. X.IP "\-d " XInstructs the program to include the duplicate inodes in the totals. X.PP X.IP "\-h #" XSpecifies how many levels down to display. X.PP X.IP \-i Xdisplays the number of inodes (excluding directories) in each directory X.PP X.IP \-s XInstructs the program to continue counting inodes and file sizes when it Xhas exceeded the levels specified. X.PP X.IP \-t XDisplays totals at the end of the report X.PP X.IP \-q XQuick display. No totals of any kind are kept. X.PP X.IP \-v XVisual display. Normally the program displays one directory on a line, Xindenting lines to indicate subdirectories. The visual display builds Xa tree on the screen showing the actual directory structure. This method Xof display excludes any totals other than the final totals. X.PP X.IP \-V XShows current version. Specifying 2 Vs (-VV) will also show all options in Xforce. X.SH AUTHOR XJonathan B. Bayer X.PP XIntelligent Software Products, Inc. X.PP XRockville Centre, NY 11570 X.SH ACKNOWLEDGMENTS XThe program uses the directory routines written and released to the Xpublic domain by Doug Gwyn. XThe program is originally based on a program called AGEF written by XDavid S. Hayes. END_OF_vtree.1 if test 1478 -ne `wc -c <vtree.1`; then echo shar: \"vtree.1\" unpacked with wrong size! fi # end of overwriting check fi if test -f vtree.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"vtree.c\" else echo shar: Extracting \"vtree.c\" \(9639 characters\) sed "s/^X//" >vtree.c <<'END_OF_vtree.c' X/* vtree X X +=======================================+ X | This program is in the public domain. | X +=======================================+ X X This program shows the directory structure of a filesystem or X part of one. It also shows the amount of space taken up by files X in each subdirectory. X X Call via X X vtree fn1 fn2 fn3 ... X X If any of the given filenames is a directory (the usual case), X vtree will recursively descend into it, and the output line will X reflect the accumulated totals for all files in the directory. X X This program is based upon "agef" written by David S. Hayes at the X Army Artificial Intelligence Center at the Pentagon. X X This program is dependent upon the new directory routines written by X Douglas A. Gwyn at the US Army Ballistic Research Laboratory at the X Aberdeen Proving Ground in Maryland. X*/ X X#include "patchlevel.h" X X#include <ctype.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <stdio.h> X X#include "customize.h" X#include "hash.h" X X#define SAME 0 /* for strcmp */ X#define BLOCKSIZE 512 /* size of a disk block */ X X#define K(x) ((x + 1023)/1024) /* convert stat(2) blocks into X * k's. On my machine, a block X * is 512 bytes. */ X X#define TRUE 1 X#define FALSE 0 X#define V_CHAR "|" /* Vertical character */ X#define H_CHAR "-" /* Horizontal character */ X#define A_CHAR ">" /* Arrow char */ X#define T_CHAR "+" /* Tee char */ X#define L_CHAR "\\" /* L char, bottom of a branch */ X X#define MAX_COL_WIDTH 15 X#define MAX_V_DEPTH 256 /* max depth for visual display */ X Xint indent = 0, /* current indent */ X depth = 9999, /* max depth */ X cur_depth = 0, X sum = FALSE, /* sum the subdirectories */ X dup = FALSE, /* use duplicate inodes */ X cnt_inodes = FALSE, /* count inodes */ X quick = FALSE; /* quick display */ Xint visual = FALSE; /* visual display */ Xint version = 0; /* = 1 display version, = 2 show options */ X sub_dirs[MAX_V_DEPTH]; X Xstruct stat stb; /* Normally not a good idea, but */ X /* this structure is used through- */ X /* out the program */ X Xextern char *optarg; /* from getopt(3) */ Xextern int optind, X opterr; X X Xchar *Program; /* our name */ Xshort sw_follow_links = 1; /* follow symbolic links */ Xshort sw_summary; /* print Grand Total line */ X Xint total_inodes, inodes; /* inode count */ Xlong total_sizes, sizes; /* block count */ X Xchar topdir[NAMELEN]; /* our starting directory */ X X X /* X * We ran into a subdirectory. Go down into it, and read everything X * in there. X */ Xint indented = FALSE; /* These had to be global since they */ Xint last_indent = 0; /* determine what gets displayed during */ X /* the visual display */ X Xdown(subdir) Xchar *subdir; X{ XOPEN *dp; /* stream from a directory */ XOPEN *opendir (); Xchar cwd[NAMELEN]; XREAD *file; /* directory entry */ XREAD *readdir (); Xint i; Xstruct stat stb; X X if ( (cur_depth == depth) && (!sum) ) X return; X X/* display the tree */ X X if (cur_depth < depth) { X if (visual) { X if (!indented) { X for (i = 1; i <cur_depth; i++) { X if (sub_dirs[i]) { X printf("%*s%s ",MAX_COL_WIDTH-4," ",V_CHAR); X } X else printf("%*s ",MAX_COL_WIDTH-3," "); X } X if (cur_depth>0) { X if (sub_dirs[cur_depth] == 0) { X printf("%*s%s%s%s ",MAX_COL_WIDTH-4," ",L_CHAR,H_CHAR,A_CHAR); X } X else printf("%*s%s%s%s ",MAX_COL_WIDTH-4," ",T_CHAR,H_CHAR,A_CHAR); X } X } else { X for (i = 1; i<MAX_COL_WIDTH-last_indent-3; i++) X printf("%s",H_CHAR); X printf("%s%s%s ",T_CHAR,H_CHAR,A_CHAR); X } X X/* This will only happen on the first entry into this routine */ X X if (strlen(subdir) > MAX_COL_WIDTH - 4) { X printf("%s\n",subdir); X printf("%s ",&subdir[strlen(subdir)-MAX_COL_WIDTH+5]); X last_indent = MAX_COL_WIDTH - 4; X } X else { X printf("%s ",subdir); X last_indent = strlen(subdir)+1; X } X indented = TRUE; X } X else printf("%*s%s",indent," ",subdir); X } X X/* open subdirectory */ X X if ((dp = opendir(subdir)) == NULL) { X printf(" - can't read %s\n", subdir); X indented = FALSE; X return; X } X X cur_depth++; X indent+=3; X X getcwd(cwd, sizeof(cwd)); /* remember where we are */ X chdir(subdir); /* go into subdir */ X if ( (!quick) && (!visual) ) { X X/* accumulate total sizes and inodes in current directory */ X X for (file = readdir(dp); file != NULL; file = readdir(dp)) X if (strcmp(NAME(*file), "..") != SAME) X get_data(NAME(*file),FALSE); X X if (cur_depth<depth) { X if (cnt_inodes) printf(" %d",inodes); X printf(" : %ld\n",sizes); X total_sizes += sizes; X total_inodes += inodes; X sizes = 0; X inodes = 0; X } X rewinddir(dp); X } else if (!visual) printf("\n"); X X if (visual) { X X/* count subdirectories */ X X for (file = readdir(dp); file != NULL; file = readdir(dp)) { X if ( (strcmp(NAME(*file), "..") != SAME) && X (strcmp(NAME(*file), ".") != SAME) ) { X if (chk_4_dir(NAME(*file))) { X sub_dirs[cur_depth]++; X } X } X } X rewinddir(dp); X } X X/* go down into the subdirectory */ X X for (file = readdir(dp); file != NULL; file = readdir(dp)) { X if ( (strcmp(NAME(*file), "..") != SAME) && X (strcmp(NAME(*file), ".") != SAME) ) { X if (chk_4_dir(NAME(*file))) X sub_dirs[cur_depth]--; X get_data(NAME(*file),TRUE); X } X } X X if ( (!quick) && (!visual) ) { X X/* print totals */ X X if (cur_depth == depth) { X if (cnt_inodes) printf(" %d",inodes); X printf(" : %ld\n",sizes); X total_sizes += sizes; X total_inodes += inodes; X sizes = 0; X inodes = 0; X } X } else if (visual && indented) { X printf("\n"); X indented = FALSE; X } X X indent-=3; X sub_dirs[cur_depth] = 0; X cur_depth--; X X chdir(cwd); /* go back where we were */ X closedir(dp); /* shut down the directory */ X} /* down */ X X X Xint chk_4_dir(path) Xchar *path; X{ X if (is_directory(path)) return TRUE; X else return FALSE; X X} /* chk_4_dir */ X X X X/* Is the specified path a directory ? */ X Xint is_directory(path) Xchar *path; X{ X X#ifdef LSTAT X if (sw_follow_links) X stat(path, &stb); /* follows symbolic links */ X else X lstat(path, &stb); /* doesn't follow symbolic links */ X#else X stat(path, &stb); X#endif X X if ((stb.st_mode & S_IFMT) == S_IFDIR) X return TRUE; X else return FALSE; X} /* is_directory */ X X X X /* X * Get the aged data on a file whose name is given. If the file is a X * directory, go down into it, and get the data from all files inside. X */ X Xget_data(path,cont) Xchar *path; Xint cont; X{ X/* struct stat stb; */ Xint i; X X if (cont) { X if (is_directory(path)) X down(path); X } X else { X if (is_directory(path)) return; X X /* Don't do it again if we've already done it once. */ X X if ( (h_enter(stb.st_dev, stb.st_ino) == OLD) && (!dup) ) X return; X inodes++; X sizes+= K(stb.st_size); X } X} /* get_data */ X X X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ Xint i, X j, X err = FALSE; Xint option; Xint user_file_list_supplied = 0; X X Program = *argv; /* save our name for error messages */ X X /* Pick up options from command line */ X X while ((option = getopt(argc, argv, "dh:istqvV")) != EOF) { X switch (option) { X case 'h': depth = atoi(optarg); X while (*optarg) { X if (!isdigit(*optarg)) { X err = TRUE; X break; X } X optarg++; X } X break; X case 'd': dup = TRUE; X break; X case 'i': cnt_inodes = TRUE; X break; X case 's': sum = TRUE; X break; X case 't': sw_summary = TRUE; X break; X case 'q': quick = TRUE; X dup = FALSE; X sum = FALSE; X cnt_inodes = FALSE; X break; X case 'v': visual = TRUE; X break; X case 'V': version++; X break; X default: err = TRUE; X } X if (err) { X fprintf(stderr,"%s: [ -d ] [ -h # ] [ -i ] [ -s ] [ -q ] [ -v ] [ -V ]\n",Program); X fprintf(stderr," -d count duplicate inodes\n"); X fprintf(stderr," -h # height of tree to look at\n"); X fprintf(stderr," -i count inodes\n"); X fprintf(stderr," -s include subdirectories not shown due to -h option\n"); X fprintf(stderr," -t totals at the end\n"); X fprintf(stderr," -q quick display, no counts\n"); X fprintf(stderr," -v visual display\n"); X fprintf(stderr," -V show current version\n"); X fprintf(stderr," (2 Vs shows specified options)\n"); X exit(-1); X } X X } X X if (version > 0 ) { X printf("%s",VERSION); X if (version>1) { X printf("Tree height: %d\n",depth); X if (dup) printf("Include duplicate inodes\n"); X if (cnt_inodes) printf("Count inodes\n"); X if (sum) printf("Include unseen subdirectories in totals\n"); X if (sw_summary) printf("Print totals at end\n"); X if (quick) printf("Quick display only\n"); X if (visual) printf("Visual tree\n"); X } X } X X /* If user didn't specify targets, inspect current directory. */ X X if (optind >= argc) { X user_file_list_supplied = 0; X } else { X user_file_list_supplied = 1; X } X X getcwd(topdir, sizeof (topdir)); /* find out where we are */ X X /* Zero out grand totals */ X total_inodes = total_sizes = 0; X /* Zero out sub_dirs */ X for (i=0; i<=MAX_V_DEPTH; i++) { X sub_dirs[i] = 0; X } X X /* Inspect each argument */ X for (i = optind; i < argc || (!user_file_list_supplied && i == argc); i++) { X cur_depth = inodes = sizes = 0; X X chdir(topdir); /* be sure to start from the same place */ X get_data(user_file_list_supplied?argv[i] : topdir, TRUE);/* this may change our cwd */ X X total_inodes += inodes; X total_sizes += sizes; X } X X if (sw_summary) { X printf("\n\nTotal space used: %ld\n",total_sizes); X if (cnt_inodes) printf("Total inodes: %d\n",inodes); X } X X#ifdef HSTATS X fflush(stdout); X h_stats(); X#endif X X exit(0); X} /* main */ X X END_OF_vtree.c if test 9639 -ne `wc -c <vtree.c`; then echo shar: \"vtree.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f vtree.man -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"vtree.man\" else echo shar: Extracting \"vtree.man\" \(1898 characters\) sed "s/^X//" >vtree.man <<'END_OF_vtree.man' X X X X VTREE(1) UNIX 5.0 (local) VTREE(1) X X X X NAME X vtree - print a visual tree of a directory structure X X SYNOPSIS X vtree [ -d] [ -h # ] [ -i ] [ -s ] [ -q ] [ -v ] [ -V ] X X DESCRIPTION X Vtree is a program which scans directories/filesystems X and displays the structure on the standard output. X Normally it will ignore duplicate inodes. X X -d Instructs the program to include the duplicate inodes X in the totals. X X -h # Specifies how many levels down to display. X X -i displays the number of inodes (excluding directories) X in each directory X X -s Instructs the program to continue counting inodes and X file sizes when it has exceeded the levels specified. X X -t Displays totals at the end of the report X X -q Quick display. No totals of any kind are kept. X X -v Visual display. Normally the program displays one X directory on a line, indenting lines to indicate X subdirectories. The visual display builds a tree on X the screen showing the actual directory structure. X This method of display excludes any totals other than X the final totals. X X -V Shows current version. Specifying 2 Vs (-VV) will also X show all options in force. X X AUTHOR X Jonathan B. Bayer X X Intelligent Software Products, Inc. X X Rockville Centre, NY 11570 X X ACKNOWLEDGMENTS X The program uses the directory routines written and released X to the public domain by Doug Gwyn. The program is X originally based on a program called AGEF written by David X S. Hayes. X X X X X X X X Page 1 (printed 12/27/88) X X X X END_OF_vtree.man if test 1898 -ne `wc -c <vtree.man`; then echo shar: \"vtree.man\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of shell archive. exit 0