home *** CD-ROM | disk | FTP | other *** search
- From: lee@minnow.UUCP (Gene Lee )
- Newsgroups: comp.sources.misc
- Subject: VTREE - draws directory tree structure (System V)
- Message-ID: <3682@ncoast.UUCP>
- Date: 29 Jul 87 22:26:06 GMT
- Sender: allbery@ncoast.UUCP
- Organization: Unisys Corporation - Roseville, MN
- Lines: 263
- Approved: allbery@ncoast.UUCP
- X-Archive: comp.sources.misc/8707/71
-
- [MUNCH]
-
- ----------------------------- cut here ----------------------------------
-
- /*
- VTREE
-
- "vtree path" draws the directory tree structure starting at the path
- given as the parameter.
-
- Gene Lee UUCP: ...ihnp4!{meccts,dayton,rosevax}!ems!minnow!lee
- UNISYS Corporation ATT: (612) 635-6334
- */
-
- #include <stdio.h>
- #include <ftw.h>
- #include <sys/types.h> /* included because <sys/stat.h> needs it */
- #include <sys/stat.h> /* included to use STAT(2) structure in fn() */
- #include <errno.h> /* included to pick up error number */
- #include <string.h> /* included to use string functions */
-
- int fn();
- char *tail();
-
- #define MAXDEPTH 100 /* maximum directory depth allowed */
- #define DIRNAME_LENGTH 15 /* maximum number of chars in a directory name */
- #define LEADGAP 5 /* number of spaces in to start drawing first col */
- #define CONNECT_CHAR "_" /* char used to connect node names in drawing */
- #define BLANK_CHAR " " /* char used to draw blanks when drawing */
- #define BRANCH_CHAR "L" /* char used to draw branch from parent node */
- #define NEWLINE_CHAR "\n" /* char used to perform a line feed-carriage ret */
- #define VERT_CONNECT "|" /* char used to draw vertical lines */
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int ftw_stat;
- int i;
-
- if (argc != 2) {
- fprintf(stderr, "Call: vtree path\n");
- exit(-1);
- }
-
- fprintf(stdout, "VTREE\n\n\n%s\n", argv[1]);
- for (i=0; i < strlen(argv[1]); i++)
- fprintf(stdout, "_");
- fprintf(stdout, "\n%s\n%s", VERT_CONNECT, VERT_CONNECT);
-
- ftw_stat = ftw(argv[1], fn, 10);
- fprintf(stdout, "%s%s", NEWLINE_CHAR, NEWLINE_CHAR);
-
- if (ftw_stat != 0)
- printf("FTW error = %d\n",errno);
-
- }
-
- /*_________________________________________________________________________*/
-
- int fn(name,ptr,type)
- char *name; /* name of the directory entity */
- struct stat *ptr; /* pointer to a STAT(2) structure */
- int type; /* entity type according to <ftw.h> */
- {
- static char table[MAXDEPTH][DIRNAME_LENGTH];
- static int tablecount=0; /* count of how many entries in the table
- are currently valid */
- static int column=0; /* what column are we printing output in */
- static match_found; /* has a match been found yet */
- static firsttime=1; /* the first time this routine is called */
-
- switch (type) {
- case FTW_D:
- /* printf("%s\n",name); */
- break;
- case FTW_DNR:
- /* printf("%s",name);
- printf(" directory that can't be read\n"); */
- break;
- default:
- return(0); /* other types of entity need no processing */
- }
-
- if (firsttime) {
- loadtable(table, &tablecount, name);
- firsttime =0;
- return(0);
- }
-
- match_found=0;
- do {
- /* if this path is a extension of the last path */
- if (tablecount == 0 || match(table,tablecount, name) ==0) {
- strcpy(table[tablecount++], tail(name)); /* add last node to
- table */
- column++; /* were going to print new name in next column */
- drawlevel(column, tail(name));
- match_found =1; /* we just found a new directory level */
- } else {
- tablecount--; /* back up one node level and try again */
- column--; /* printout column goes back with dir level */
- }
- if (tablecount < 0) {
- fprintf(stderr, "Internal Program Error\n");
- exit(-1);
- }
- } while (!match_found);
-
- return(0);
- }
-
- /* _________________________________________________________________________ */
-
- /*
- This function returns a pointer into path of the last node in the path
- */
- char *tail(path)
- char *path;
- {
- char *ptr;
-
- if ((ptr =strrchr(path,'/')) == NULL)
- return(path); /* it didn't have a path seperator */
- else
- return(ptr +1); /* return pointer to last node in path */
- }
-
- /* _________________________________________________________________________ */
-
- /*
- match checks to see if the first nodes in the path name match to
- node names in the table
- */
- int match(table,tablecount,name)
- char table[MAXDEPTH][DIRNAME_LENGTH];
- int tablecount; /* how many entries in the table are valid and need to be
- checked */
-
- char *name; /* the directory path of node names */
- {
- int i;
- char *ptr;
- char path[200]; /* make a copy of their pathname to strtok on */
-
- strcpy(path, name);
-
- /* check first node name against first table entry */
- if (strcmp(table[0], (ptr =strtok(path,"/"))) != 0) {
- return(-1); /* return no match */
- }
-
- /* check the rest of the table up to the last valid entry against
- each node name in the path */
- for (i=1; i < tablecount; i++)
- if (strcmp(table[i], strtok(NULL, "/")) != 0)
- return(-1); /* return no match */
-
- return(0);
- }
-
- /* ______________________________________________________________________ */
-
- loadtable(table, tablecount, name)
- char table[MAXDEPTH][DIRNAME_LENGTH];
- int *tablecount;
- char *name;
- {
- char path[160]; /* make a copy of the path so as not to chg it */
- char *ptr;
-
- strcpy(path, name);
-
- *tablecount =0; /* nothing in the table yet */
-
- if ((ptr = strtok(path, "/")) == NULL) /* if only a '/' for ex */
- return;
- else {
- strcpy(table[*tablecount], ptr); /* load table entry */
- (*tablecount)++; /* add the node name found to the count */
- }
-
- while ((ptr = strtok(NULL, "/")) != NULL) { /* while a node name is
- found */
- strcpy(table[*tablecount], ptr);
- (*tablecount)++;
- }
- }
-
- /* ______________________________________________________________________ */
-
- drawlevel(column,name)
- int column; /* column to print nodename in */
- char *name; /* nodename to print */
- {
- static int lastcolumn=MAXDEPTH; /* last column a name was printed in */
- static int lastlength; /* length of last nodename printed */
-
- if (column <= lastcolumn) /* this means we need to start a new row */
- startnewrow(column, name);
- else /* add name to end of last row */
- addtorow(lastlength, name);
-
- lastcolumn =column; /* remember the last column printed in */
- lastlength =strlen(name); /* remember length of last name printed */
- }
-
- /*_________________________________________________________________________*/
-
- addtorow(lastlength, name)
- int lastlength; /* length of the previously printed name */
- char *name; /* name to be printed */
- {
- int i;
-
- /* move over and print it */
- for (i=0; i < DIRNAME_LENGTH +1 -lastlength; i++)
- fprintf(stdout, CONNECT_CHAR);
-
- fprintf(stdout, name); /* print the node name */
- }
-
- /*_________________________________________________________________________*/
-
- startnewrow(column, name)
- int column; /* column to print nodename in */
- char *name; /* nodename to print */
- {
- int i,j;
-
- fprintf(stdout, NEWLINE_CHAR); /* start the new line */
-
- /* move away from left edge */
- if (column ==1) { /* if printing in first column */
- fprintf(stdout, BRANCH_CHAR); /* char along left edge */
- for (i=0; i < LEADGAP -1; i++)
- fprintf(stdout, CONNECT_CHAR);
- } else {
- fprintf(stdout, VERT_CONNECT); /* char along left edge */
- for (i=0; i < LEADGAP -1; i++)
- fprintf(stdout, BLANK_CHAR);
- }
-
- /* move over to its parents column in above row */
- for (i=0; i < (column -2); i++)
- for (j=0; j < DIRNAME_LENGTH +1; j++)
- fprintf(stdout, BLANK_CHAR);
-
- if (column > 1) { /* LEADGAP did this already for column ones */
- fprintf(stdout, BRANCH_CHAR); /* branch down from prev row */
- for (i=0; i < DIRNAME_LENGTH; i++)
- fprintf(stdout, CONNECT_CHAR);
- }
-
- fprintf(stdout, name); /* print the node name */
- }
-
- /* ----------------- end of source ------------------------------------ */
-
- --
- Gene Lee UUCP: ...ihnp4!{meccts,dayton,rosevax}!ems!minnow!lee
- UNISYS Corporation ATT: (612) 635-6334
- If not for the courage of the fearless crew, the minnow would be lost.
-