home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume1 / 8707 / 71 < prev    next >
Encoding:
Internet Message Format  |  1990-07-13  |  7.7 KB

  1. From: lee@minnow.UUCP (Gene Lee )
  2. Newsgroups: comp.sources.misc
  3. Subject: VTREE - draws directory tree structure (System V)
  4. Message-ID: <3682@ncoast.UUCP>
  5. Date: 29 Jul 87 22:26:06 GMT
  6. Sender: allbery@ncoast.UUCP
  7. Organization: Unisys Corporation - Roseville, MN
  8. Lines: 263
  9. Approved: allbery@ncoast.UUCP
  10. X-Archive: comp.sources.misc/8707/71
  11.  
  12. [MUNCH]
  13.  
  14. ----------------------------- cut here ----------------------------------
  15.  
  16. /*
  17.              VTREE
  18.  
  19.     "vtree path" draws the directory tree structure starting at the path
  20.     given as the parameter.
  21.  
  22.     Gene Lee  UUCP: ...ihnp4!{meccts,dayton,rosevax}!ems!minnow!lee
  23.     UNISYS Corporation     ATT:  (612) 635-6334
  24. */
  25.  
  26. #include <stdio.h>
  27. #include <ftw.h>
  28. #include <sys/types.h> /* included because <sys/stat.h> needs it */
  29. #include <sys/stat.h>  /* included to use STAT(2) structure in fn() */
  30. #include <errno.h>     /* included to pick up error number */
  31. #include <string.h>   /* included to use string functions */
  32.  
  33. int fn();
  34. char *tail();
  35.  
  36. #define MAXDEPTH 100     /* maximum directory depth allowed */
  37. #define DIRNAME_LENGTH 15 /* maximum number of chars in a directory name */
  38. #define LEADGAP 5      /* number of spaces in to start drawing first col */
  39. #define CONNECT_CHAR "_" /* char used to connect node names in drawing */
  40. #define BLANK_CHAR " "   /* char used to draw blanks when drawing */
  41. #define BRANCH_CHAR "L"  /* char used to draw branch from parent node */
  42. #define NEWLINE_CHAR "\n" /* char used to perform a line feed-carriage ret */
  43. #define VERT_CONNECT "|"  /* char used to draw vertical lines */
  44.  
  45. main(argc,argv)
  46. int argc;
  47. char *argv[];
  48. {
  49.     int ftw_stat;
  50.     int i;
  51.  
  52.     if (argc != 2) {
  53.         fprintf(stderr, "Call: vtree path\n");
  54.         exit(-1);
  55.     }
  56.  
  57.     fprintf(stdout, "VTREE\n\n\n%s\n", argv[1]);
  58.     for (i=0; i < strlen(argv[1]); i++)
  59.         fprintf(stdout, "_");
  60.     fprintf(stdout, "\n%s\n%s", VERT_CONNECT, VERT_CONNECT);
  61.  
  62.     ftw_stat = ftw(argv[1], fn, 10);
  63.     fprintf(stdout, "%s%s", NEWLINE_CHAR, NEWLINE_CHAR);
  64.  
  65.     if (ftw_stat != 0)
  66.         printf("FTW error = %d\n",errno);
  67.  
  68. }
  69.  
  70. /*_________________________________________________________________________*/
  71.  
  72. int fn(name,ptr,type)
  73. char *name;          /* name of the directory entity */
  74. struct stat *ptr;    /* pointer to a STAT(2) structure */
  75. int type;            /* entity type according to <ftw.h> */
  76. {
  77.     static char table[MAXDEPTH][DIRNAME_LENGTH];
  78.     static int tablecount=0;  /* count of how many entries in the table
  79.             are currently valid */
  80.     static int column=0;  /* what column are we printing output in */
  81.     static match_found;  /* has a match been found yet */
  82.     static firsttime=1;  /* the first time this routine is called */
  83.  
  84.     switch (type) {
  85.     case FTW_D:
  86.         /* printf("%s\n",name); */
  87.         break;
  88.     case FTW_DNR:
  89.         /* printf("%s",name);
  90.         printf("    directory that can't be read\n"); */
  91.         break;
  92.     default:
  93.         return(0);  /* other types of entity need no processing */
  94.     }
  95.  
  96.     if (firsttime) {
  97.         loadtable(table, &tablecount, name);
  98.         firsttime =0;
  99.         return(0);
  100.     }
  101.  
  102.     match_found=0;
  103.     do {
  104.         /* if this path is a extension of the last path */
  105.         if (tablecount == 0 || match(table,tablecount, name) ==0) {
  106.             strcpy(table[tablecount++], tail(name)); /* add last node to
  107.                                 table */
  108.             column++;  /* were going to print new name in next column */
  109.             drawlevel(column, tail(name));
  110.             match_found =1;  /* we just found a new directory level */
  111.         } else {
  112.             tablecount--;  /* back up one node level and try again */
  113.             column--;    /* printout column goes back with dir level */
  114.         }
  115.     if (tablecount < 0) {
  116.         fprintf(stderr, "Internal Program Error\n");
  117.         exit(-1);
  118.     }    
  119.     } while (!match_found);
  120.  
  121.     return(0);
  122. }
  123.  
  124. /* _________________________________________________________________________ */
  125.  
  126. /*
  127.   This function returns a pointer into path of the last node in the path 
  128. */
  129. char *tail(path)
  130. char *path;
  131. {
  132.     char *ptr;
  133.  
  134.     if ((ptr =strrchr(path,'/')) == NULL)
  135.         return(path);      /* it didn't have a path seperator */
  136.     else
  137.         return(ptr +1);   /* return pointer to last node in path */
  138. }
  139.  
  140. /* _________________________________________________________________________ */
  141.  
  142. /*
  143.     match checks to see if the first nodes in the path name match to 
  144.     node names in the table
  145. */
  146. int match(table,tablecount,name)
  147. char table[MAXDEPTH][DIRNAME_LENGTH];
  148. int tablecount;    /* how many entries in the table are valid and need to be
  149. checked */
  150.  
  151. char *name;        /* the directory path of node names */
  152. {
  153.     int i;
  154.     char *ptr;
  155.     char path[200];   /* make a copy of their pathname to strtok on */
  156.  
  157.     strcpy(path, name);
  158.  
  159.     /* check first node name against first table entry */
  160.     if (strcmp(table[0], (ptr =strtok(path,"/"))) != 0) {
  161.         return(-1); /* return no match */
  162.     }
  163.  
  164.     /* check the rest of the table up to the last valid entry against
  165.         each node name in the path */
  166.     for (i=1; i < tablecount; i++)
  167.         if (strcmp(table[i], strtok(NULL, "/")) != 0)
  168.             return(-1);      /* return no match */
  169.  
  170.     return(0);
  171. }
  172.  
  173. /* ______________________________________________________________________ */
  174.  
  175. loadtable(table, tablecount, name)
  176. char table[MAXDEPTH][DIRNAME_LENGTH];
  177. int *tablecount;
  178. char *name;
  179. {
  180.     char path[160];   /* make a copy of the path so as not to chg it */
  181.     char *ptr;
  182.  
  183.     strcpy(path, name);
  184.  
  185.     *tablecount =0;        /* nothing in the table yet */
  186.  
  187.     if ((ptr = strtok(path, "/")) == NULL)  /* if only a '/' for ex */
  188.         return;
  189.     else {
  190.         strcpy(table[*tablecount], ptr); /* load table entry */
  191.         (*tablecount)++;  /* add the node name found to the count */
  192.     }
  193.  
  194.     while ((ptr = strtok(NULL, "/")) != NULL) { /* while a node name is
  195.     found */
  196.         strcpy(table[*tablecount], ptr);
  197.         (*tablecount)++;
  198.     }
  199. }
  200.  
  201. /* ______________________________________________________________________ */
  202.  
  203. drawlevel(column,name)
  204. int column;   /* column to print nodename in */
  205. char *name;   /* nodename to print */
  206. {
  207.     static int lastcolumn=MAXDEPTH;  /* last column a name was printed in */
  208.     static int lastlength;   /* length of last nodename printed */
  209.  
  210.     if (column <= lastcolumn)    /* this means we need to start a new row */
  211.         startnewrow(column, name);
  212.     else                    /* add name to end of last row */
  213.         addtorow(lastlength, name);
  214.  
  215.     lastcolumn =column;      /* remember the last column printed in */
  216.     lastlength =strlen(name); /* remember length of last name printed */
  217. }
  218.  
  219. /*_________________________________________________________________________*/
  220.  
  221. addtorow(lastlength, name)
  222. int lastlength;      /* length of the previously printed name */
  223. char *name;         /* name to be printed */
  224. {
  225.     int i;
  226.  
  227.     /* move over and print it */
  228.     for (i=0; i < DIRNAME_LENGTH +1 -lastlength; i++)  
  229.         fprintf(stdout, CONNECT_CHAR);
  230.  
  231.     fprintf(stdout, name);    /* print the node name */
  232. }
  233.  
  234. /*_________________________________________________________________________*/
  235.  
  236. startnewrow(column, name)
  237. int column;   /* column to print nodename in */
  238. char *name;   /* nodename to print */
  239. {
  240.     int i,j;
  241.  
  242.     fprintf(stdout, NEWLINE_CHAR);   /* start the new line */
  243.  
  244.        /* move away from left edge */
  245.     if (column ==1) {  /* if printing in first column */
  246.         fprintf(stdout, BRANCH_CHAR);  /* char along left edge */
  247.         for (i=0; i < LEADGAP -1; i++)  
  248.             fprintf(stdout, CONNECT_CHAR);
  249.     } else {
  250.         fprintf(stdout, VERT_CONNECT);  /* char along left edge */
  251.         for (i=0; i < LEADGAP -1; i++)  
  252.             fprintf(stdout, BLANK_CHAR);
  253.     }
  254.  
  255.     /* move over to its parents column in above row */
  256.     for (i=0; i < (column -2); i++) 
  257.         for (j=0; j < DIRNAME_LENGTH +1; j++)
  258.             fprintf(stdout, BLANK_CHAR);
  259.  
  260.     if (column > 1) {  /* LEADGAP did this already for column ones */
  261.         fprintf(stdout, BRANCH_CHAR); /* branch down from prev row */
  262.         for (i=0; i < DIRNAME_LENGTH; i++)
  263.             fprintf(stdout, CONNECT_CHAR);
  264.     }
  265.  
  266.     fprintf(stdout, name);    /* print the node name */
  267. }
  268.  
  269. /*  ----------------- end of source ------------------------------------ */
  270.  
  271. -- 
  272. Gene Lee  UUCP: ...ihnp4!{meccts,dayton,rosevax}!ems!minnow!lee
  273. UNISYS Corporation     ATT:  (612) 635-6334
  274. If not for the courage of the fearless crew, the minnow would be lost.
  275.