home *** CD-ROM | disk | FTP | other *** search
- From: istvan@hhb.UUCP (Istvan Mohos)
- Newsgroups: alt.sources
- Subject: treeD --- Unix file system diagrammer
- Message-ID: <508@hhb.UUCP>
- Date: 3 May 90 18:56:24 GMT
-
-
-
- The utmost conceptual simplicity of file system trees belies the
- difficulty of memorizing actual nodal layouts of specific trees.
- In spite a plain topological essence of TREE no two trees are
- the same; and most users would have an equal chance of being able
- to recall the exact twig arrangement of last year's Christmas tree
- as they would in describing a 30 Meg Unix subdirectory.
-
- Recursive listers such as 'find' obscure the tree structure by the
- one-dimensionality of their output: standard output mediums of
- pinfeed paper or the scrollable screen rigidly limit the width,
- while allowing infinitely long lists.
-
- The treeD file system diagrammer erases the width limitation of
- the output medium, and constructs true two-dimensional maps of
- file systems. To realize a hardcopy of a map, the internal diagram
- is output as equal-sized pages, each page bearing a letter/number
- coordinate analogous to lettered, numbered grids on a street map.
- Command line options fine tune the format of the output, control
- non-default grid sizes and the depth of the directory search.
-
- -DREALUNIX should be enabled in the makefile when compiling under
- System V. The 'man page' is in the file treeD.tex, and should be
- processed with "tex treeD" (assuming TeX capability at the site).
- The Bourne script treeX converts treeD's character-graphics
- depicting branching, to bold lines under plain TeX.
-
- ===============================cut here===========================
- # This is a shell archive. Remove anything before this line, then
- # unpack it by saving it in a file and typing "sh file". (Files
- # unpacked will be owned by you and have default permissions.)
- #
- # This archive contains:
- # globals.h i.h ilib.h
- # goaway.c iego.c ierror.c illistn.c init.c iopt.c iread.c
- # listfiles.c mapper.c package.c split.c tile.c treeD.c
- # makefile treeX treeD.tex README
-
- echo x - globals.h
- cat > "globals.h" << '//E*O*F globals.h//'
- /* globals.h */
-
- #include "ilib.h"
- #include <signal.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #define BLANK 0
- #define SINGLE 1
- #define DOUBLE 2
- #define TRIPLE 3
- #define LEAF 4
- #define BUD 5
- #define JOINT 6
- #define TWIG 7
- #define SPAN 8
- #define TAP 9
- #define TIP 10
-
- #define MAXFN 15 /* fourteen name chars, 1 type char */
- #define SPACE 32 /* ASCII value */
-
- #define ZERO ((char *)NULL)
- #define TSIZ (sizeof (struct tile))
-
- #define BAILOUT sprintf (Msg, "error at line %d of %s",\
- __LINE__, __FILE__), goaway()
-
- int goaway();
- int fstat();
- int stat();
- char *malloc();
- char *gets();
-
- struct tile {
- int ver;
- int hor;
- int linkc;
- char line1[17];
- char line2[17];
- char line3[17];
- };
-
- #ifdef MAIN
-
- char Listfile[IQUARTK]; /* /tmp file for listing of current dir */
- char Tiles[IQUARTK]; /* /tmp filename for sequential output */
- char Msg[IQUARTK]; /* buffer for reporting errors to user */
- struct tile **Mp; /* base of tile pointer matrix */
- int Td; /* Tile descriptor */
- int Tx; /* horizontal tile position */
- int Ty = -1; /* vertical tile position */
- int Deepest; /* greatest vertical depth reached */
- int Wid = 72; /* max column width of printed page */
- int Lin = 66; /* max lines on printed page */
- int Widemod; /* number of tiles/page horizontally */
- int Deepmod; /* number of tiles/page vertically */
- int Depth; /* max. recursion depth; 0=infty */
- int Fstop; /* max. file list page; 0=infty */
- int Printblank; /* print page even if no tiles on it */
- unsigned int Mcount; /* width*height of rectangular tile matrix */
-
- struct tile Blank; /* one of each tile, initialized in init.c */
- struct tile Single;
- struct tile Double;
- struct tile Triple;
- struct tile Leaf;
- struct tile Bud;
- struct tile Joint;
- struct tile Twig;
- struct tile Span;
- struct tile Tap;
- struct tile Tip;
-
- #else
- extern char Listfile[];
- extern char Tiles[];
- extern char Msg[];
- extern struct tile **Mp;
- extern int Td;
- extern int Tx;
- extern int Ty;
- extern int Deepest;
- extern int Lin;
- extern int Wid;
- extern int Widemod;
- extern int Deepmod;
- extern int Depth;
- extern int Fstop;
- extern int Printblank;
- extern unsigned int Mcount;
-
- extern struct tile Blank;
- extern struct tile Single;
- extern struct tile Double;
- extern struct tile Triple;
- extern struct tile Leaf;
- extern struct tile Bud;
- extern struct tile Joint;
- extern struct tile Twig;
- extern struct tile Span;
- extern struct tile Tap;
- extern struct tile Tip;
-
- #endif
- //E*O*F globals.h//
-
- echo x - i.h
- cat > "i.h" << '//E*O*F i.h//'
- /* i.h */
- /**************************************
- * local include file for ilib functions
- * Istvan Mohos, 1987
- ***************************************/
-
- #ifdef pyr
- #include <sys/time.h>
- #else
- #include <time.h>
- #endif
-
- #include <stdio.h>
- #include <signal.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #ifndef X_OK
- # ifdef REALUNIX
- # define F_OK 0
- # define X_OK 1
- # define W_OK 2
- # define R_OK 4
- # include <fcntl.h>
- # else
- # include <sys/file.h>
- # endif
- #endif
-
- #define NUL 0 /* the ASCII 0 byte */
- #define MAXSTR 1892
- #define BIGBUFSIZ 4096
- #define SHORTSTR 256
- #define IFOURK 4096
- #define ITWOK 2048
- #define IONEK 1024
- #define IHALFK 512
- #define IQUARTK 256
- #define BADCHARP(p) ((p) == (char *)NULL || *(p) == '\0')
- #define NULCHARP(p) ((p) == (char *)NULL)
- #define WHITE(c) ((c) < 33)
- #define BLACK(c) ((c) > 32)
- #define SMALL(c) ((c) < 32)
-
- #define INITOKF 1 /* setup forward parsing */
- #define INITOKR -1 /* setup reverse parsing */
- #define ITOKF 2 /* forward parse */
- #define ITOKR -2 /* reverse parse */
-
- int fstat();
- int stat();
- char *malloc();
- char *calloc();
- long lseek();
- long time();
-
- struct tm *_igetdate();
-
- char *ctime();
- char *iwhich();
- char *getenv();
- char *ilast();
- char *ianytok();
- char *ialntok();
- char *ictok();
- int ierror();
- int ifamily();
- int ilongest();
- int itexrect();
- int iread();
-
- extern int errno, sys_nerr;
- extern char *sys_errlist[];
-
- #ifndef IAMIERROR
- extern char ierbuf[];
- extern int ierflag;
- #endif
- //E*O*F i.h//
-
- echo x - ilib.h
- cat > "ilib.h" << '//E*O*F ilib.h//'
- /* ilib.h */
- /*********************************************************************
- * This is the client's #include file for accessing functions in ilib.a
- * Istvan Mohos, 1987 --- in the Public Domain
- **********************************************************************/
-
- /* functions archived in ilib.a: */
- char * ialntok();
- char * ianymatch();
- char * ianytok();
- int ibcmp();
- void ibcopy();
- void iblank();
- int ibreakl();
- char * ictok();
- char * icopy();
- int icount();
- void icue();
- int idamage();
- char * idate();
- void idump();
- int iego();
- int ierror();
- int iexpect();
- int ifamily();
- int ifilter();
- int igroup();
- int ihash();
- int ihasharg();
- char * ihms();
- int iinput();
- char * ilast();
- int iline();
- int ilist();
- int ilistn();
- int illistn();
- int ilongest();
- int ilower();
- char * imatch();
- int imode();
- int imonth();
- int inest();
- char * inl();
- char * inull();
- int inumsearch();
- void inumsort();
- int inumstrcmp();
- char * inextl();
- int ioctal();
- int iopt();
- int iread();
- int irotate();
- int iround();
- int isearch();
- void isort();
- char * istartl();
- int istripcom();
- int istripdq();
- int istripsq();
- int istripstr();
- int iswap();
- int itexrect();
- int itoday();
- int itohour();
- int itok();
- int itomin();
- int itomonth();
- int itosec();
- int itoyear();
- int itran();
- void itwin();
- int iuniq();
- int iuniqa();
- int iupper();
- char * iwhich();
- int iwrite();
- int iwritopn();
- char * ixmatch();
- int ixsearch();
- int ixswap();
-
- char * malloc();
- char * calloc();
- long lseek();
-
- #include <stdio.h>
- #ifndef X_OK
- # ifdef REALUNIX
- # define F_OK 0
- # define X_OK 1
- # define W_OK 2
- # define R_OK 4
- # include <fcntl.h>
- # else
- # include <sys/file.h>
- # endif
- #endif
-
- extern char ierbuf[];
- extern int ierflag;
-
- /* imode symbolic constants, modeled after stat.h list */
- #define ISSOCK 0140000 /* socket */
- #define ISLNK 0120000 /* symbolic link */
- #define ISREG 0100000 /* regular */
- #define ISBLK 0060000 /* block special */
- #define ISDIR 0040000 /* directory */
- #define ISCHR 0020000 /* character special */
- #define ISFIFO 0010000 /* named pipe */
- #define ISUID 0004000 /* set uid on execution */
- #define ISGID 0002000 /* set gid on execution */
- #define ISSTICK 0001000 /* keep text in memory (sticky bit) */
- #define ISROWN 0000400 /* read, owner */
- #define ISWOWN 0000200 /* write, owner */
- #define ISXOWN 0000100 /* execute/search, owner */
- #define ISRGRP 0000040 /* read, group */
- #define ISWGRP 0000020 /* write, group */
- #define ISXGRP 0000010 /* execute/search, group */
- #define ISRALL 0000004 /* read, others */
- #define ISWALL 0000002 /* write, others */
- #define ISXALL 0000001 /* execute/search, others */
-
- #define INITOKF 1 /* setup forward parsing */
- #define INITOKR -1 /* setup reverse parsing */
- #define ITOKF 2 /* forward parse */
- #define ITOKR -2 /* reverse parse */
-
- #define DOUNCOUN(x,y) (y) = (x); --(y) >= 0
- #define BADCHARP(p) ((p) == (char *)NULL || *(p) == '\0')
- #define NULCHARP(p) ((p) == (char *)NULL)
- #define ZPT (char *)NULL
-
- #define IANYTOK 0
- #define IALNTOK 1
- #define ICTOK 2
-
- #define SPACE_LINE -1
- #define LINE_ONLY 0
- #define LINE_SPACE 1
-
- #define IROTR 1 /* rotate 90 deg. to right */
- #define IROTL -1 /* rotate 90 deg. to left */
- #define IROTOR 3 /* rotate 180 deg. over and 90 deg. to right */
- #define IROTOL -3 /* rotate 180 deg. over and 90 deg. to left */
-
- #define SHORTMO 0 /* idate format: Jun 23 1988 */
- #define SHORTUPMO 1 /* idate format: JUN 23 1988 */
- #define LONGMO 2 /* idate format: June 23, 1988 */
- #define LONGUPMO 3 /* idate format: JUNE 23, 1988 */
-
- #define WHITE(c) ((c) < 33)
- #define BLACK(c) ((c) > 32)
- #define TONEXWHITE(p) while (*(p) && (*(p)>32)) (p)++
- #define TONEXBLACK(p) while (*(p) && (*(p)<33)) (p)++
-
- #define IFOURK 4096
- #define ITWOK 2048
- #define IONEK 1024
- #define IHALFK 512
- #define IQUARTK 256
- //E*O*F ilib.h//
-
- echo x - goaway.c
- cat > "goaway.c" << '//E*O*F goaway.c//'
- /* goaway.c */
-
- #include "globals.h"
-
- goaway ()
- {
- signal(SIGINT, SIG_IGN);
- signal(SIGHUP, SIG_IGN);
- signal(SIGTERM, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
-
- unlink (Tiles);
- unlink (Listfile);
- if (*Msg)
- fprintf(stderr, "%s\n", Msg), exit (1);
-
- exit (0);
- }
-
- //E*O*F goaway.c//
-
- echo x - iego.c
- cat > "iego.c" << '//E*O*F iego.c//'
- /* iego.c */
- /*******************************************************
- * return file name in buf without path or .ext component
- * Istvan Mohos, 1987 --- in the Public Domain
- *******************************************************/
-
- #include "i.h"
-
- int
- iego (ptr, wbuf, delim, ext)
- char *ptr, *wbuf, delim, ext;
- {
- char *fr, *to, *mark;
-
- if (BADCHARP(ptr))
- return (ierror ("iego: invalid name pointer"));
- if (delim == 0)
- delim = '/';
-
- to = wbuf;
- *to = '\0';
- for (fr = ptr; *fr++;);
- for (--fr; --fr > ptr;) {
- if (*fr == delim) {
- ++fr;
- break;
- }
- }
- if (*fr == delim)
- ++fr;
-
- if (ext == 0)
- for (mark = ptr; mark < fr; *to++ = *mark++);
- else
- for (;*fr && *fr != ext;)
- *to++ = *fr++;
- *to = '\0';
-
- return (strlen (wbuf));
- }
- //E*O*F iego.c//
-
- echo x - ierror.c
- cat > "ierror.c" << '//E*O*F ierror.c//'
- /* ierror.c */
- /****************************************
- * report error via "ierbuf" and "ierflag"
- * Istvan Mohos, 1987 --- in the Public Domain
- ****************************************/
-
- #define IAMIERROR
- #include "i.h"
-
- char ierbuf[IHALFK];
- int ierflag;
-
- int
- ierror (ustr)
- char *ustr;
- {
- if (errno > 0 && errno < sys_nerr) { /* system error */
- ierflag = -errno;
- if (NULCHARP (ustr))
- strcpy(ierbuf, sys_errlist[errno]);
- else
- sprintf(ierbuf, "%s --- %.*s", sys_errlist[errno],
- IHALFK - strlen (sys_errlist[errno]) - 6, ustr);
- errno = 0;
- return (ierflag);
- }
-
- ierflag = -sys_nerr; /* user error */
- if (NULCHARP (ustr))
- strcpy (ierbuf, "Error");
- else
- strncpy (ierbuf, ustr, IHALFK-1);
- errno = 0;
- return (ierflag);
- }
- //E*O*F ierror.c//
-
- echo x - illistn.c
- cat > "illistn.c" << '//E*O*F illistn.c//'
- /* illistn.c */
- /********************************************
- * create array of pointers to lines in buffer
- * Istvan Mohos, 1987 --- in the Public Domain
- *********************************************/
-
- #include "i.h"
-
- int
- illistn (start, end, ptrlist)
- char *start;
- char *end;
- char **ptrlist;
- {
- int ri;
- char *rp;
- char *savp, **work;
-
- if (end <= start || NULCHARP (start))
- return (ierror ("illistn: zero-size or invalid buffer"));
- *(end -1) = '\n'; /* just in case */
- for (ri = 0, rp = end; --rp >= start;)
- if (*rp == '\n')
- ++ri;
-
- if (NULCHARP(savp=malloc((unsigned int)(ri*sizeof(char *)))))
- return(ierror("illistn: can't allocate pointer array"));
-
- /* start one character to left of last byte in buffer */
- *(end -1) = 0;
- for (work=(char **)savp+ri, rp=end-1; --rp >= start;)
- if (*rp == '\n')
- *rp = 0, *--work = rp+1;
-
- /* rp == start-1 */
- *--work = ++rp;
-
- *ptrlist = savp;
- return(ri);
- }
- //E*O*F illistn.c//
-
- echo x - init.c
- cat > "init.c" << '//E*O*F init.c//'
- /* init.c */
-
- #include "globals.h"
-
- init ()
- {
- char *mktemp();
- struct tile *tp;
-
- /******************
- * *
- * *
- * *
- ******************/
- tp = &Blank;
- strcpy (tp->line1, " ");
- strcpy (tp->line2, " ");
- strcpy (tp->line3, " ");
-
-
- /******************
- *string1 *
- * *
- * *
- ******************/
- tp = &Single;
- strcpy (tp->line2, " ");
- strcpy (tp->line3, " ");
-
-
- /******************
- *string1 *
- *string2 *
- * *
- ******************/
- tp = &Double;
- strcpy (tp->line3, " ");
-
-
- /******************
- *string1 *
- *string2 * Triple
- *string3 *
- ******************/
-
-
- /******************
- * | *
- *string1 *
- *string2 *
- ******************/
- tp = &Leaf;
- strcpy (tp->line1, " | ");
-
-
- /******************
- * | *
- *string1 *
- * *
- ******************/
- tp = &Bud;
- strcpy (tp->line1, " | ");
- strcpy (tp->line3, " ");
-
-
- /******************
- * | *
- *string1 *
- * | *
- ******************/
- tp = &Joint;
- strcpy (tp->line1, " | ");
- strcpy (tp->line3, " | ");
-
-
- /******************
- * | *
- *string1~~~~~~~~~*
- * | *
- ******************/
- tp = &Twig;
- strcpy (tp->line1, " | ");
- strcpy (tp->line3, " | ");
-
-
- /******************
- * *
- *~~~~~~~~~~~~~~~~*
- * *
- ******************/
- tp = &Span;
- strcpy (tp->line1, " ");
- strcpy (tp->line2, "~~~~~~~~~~~~~~~~");
- strcpy (tp->line3, " ");
-
-
- /******************
- * *
- *~~~~~~~~~~~~~~~~*
- * | *
- ******************/
- tp = &Tap;
- strcpy (tp->line1, " ");
- strcpy (tp->line2, "~~~~~~~~~~~~~~~~");
- strcpy (tp->line3, " | ");
-
-
- /******************
- * *
- *~~> *
- * | *
- ******************/
- tp = &Tip;
- strcpy (tp->line1, " ");
- strcpy (tp->line2, "~~> ");
- strcpy (tp->line3, " | ");
-
-
- strcpy (Tiles, "/tmp/");
- strcat (Tiles, mktemp ("treeDTXXXXXX"));
- if ((Td = open (Tiles, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1)
- fprintf (stderr, "can't write to %s\n", Tiles), exit (1);
-
- strcpy (Listfile, "/tmp/");
- strcat (Listfile, mktemp ("treeDLXXXXXX"));
-
- if (signal(SIGHUP, SIG_IGN) == SIG_DFL)
- signal(SIGHUP, goaway);
- if (signal(SIGINT, SIG_IGN) == SIG_DFL)
- signal(SIGINT, goaway);
- if (signal(SIGTERM, SIG_IGN) == SIG_DFL)
- signal(SIGTERM, goaway);
- if (signal(SIGQUIT, SIG_IGN) == SIG_DFL)
- signal(SIGQUIT, goaway);
-
- Widemod = (Wid-3)/16;
- Deepmod = (Lin-3)/3;
- }
- //E*O*F init.c//
-
- echo x - iopt.c
- cat > "iopt.c" << '//E*O*F iopt.c//'
- /* iopt.c */
- /*********************************************
- * command line option manager
- * Istvan Mohos, 1987 --- in the Public Domain
- *********************************************/
-
- #include "i.h"
-
- int
- iopt (ptr)
- char ***ptr;
- {
- char *rp;
- static char **olist;
- static int first = 1;
- int optlen;
-
- if (first) {
- olist = *ptr;
- first = 0;
- }
-
- rp = *olist;
- if (rp == NULL || *rp != '-') { /* no more options */
- *ptr = olist; /* set to first non-option */
- first = 1; /* automatically re-init */
- return (0);
- }
-
- optlen = strlen (rp);
- if (optlen > 2) { /* flag, value combined */
- rp += 2;
- *olist = rp; /* right past '-c' flag */
- *ptr = olist;
- ++olist; /* pre-increment for next time */
- return (*--rp);
- }
-
- if (optlen == 1) { /* '-' by itself */
- *ptr = olist;
- ++olist; /* pre-increment for next time */
- return (*rp);
- }
-
- /* else (optlen == 2): normal '-c' flag */
- ++rp;
- ++olist;
- if (*olist == NULL || **olist == 0) { /* no option value */
- --olist;
- *ptr = olist; /* cough up entire option flag */
- first = 1; /* automatically re-init */
- return (0);
- }
-
- *ptr = olist;
- ++olist; /* pre-increment for next time */
- return (*rp);
- }
- //E*O*F iopt.c//
-
- echo x - iread.c
- cat > "iread.c" << '//E*O*F iread.c//'
- /* iread.c */
- /*************************************************
- * read file into malloc'd buffer, return file size
- * Istvan Mohos, 1987 --- in the Public Domain
- **************************************************/
-
- #include "i.h"
-
- int
- iread (fname, mallocp)
- char *fname;
- char **mallocp;
- {
- struct stat sbuf;
- int checkval, fd;
- int count;
-
- if (BADCHARP (fname))
- return (ierror ("iread: invalid file name"));
-
- if (mallocp == (char **) NULL) {
- if (access (fname, R_OK) == -1)
- return (-1); /* can't read it */
- return (0);
- }
-
- if ((fd = open (fname, 0)) == -1)
- return (ierror ("iread: no file access"));
-
- if ((checkval = fstat (fd, &sbuf)) == -1)
- return (ierror ("iread: fstat read error"));
-
- if ((count = (int)sbuf.st_size) == 0)
- return (ierror ("iread: zero length file"));
-
- if (NULCHARP (*mallocp = malloc ((unsigned int) count+1)))
- return (ierror ("iread: can't allocate read buffer"));
-
- if ((checkval = read (fd, *mallocp, count)) != count) {
- sprintf (ierbuf+200,
- "iread: expected: %d, read: %d", count, checkval);
- return (ierror (ierbuf+200));
- }
- close (fd);
- *(*mallocp + count) = 0;
- return (checkval);
- }
- //E*O*F iread.c//
-
- echo x - listfiles.c
- cat > "listfiles.c" << '//E*O*F listfiles.c//'
- /* listfiles.c */
-
- #include "globals.h"
-
- listfiles (ptr, ptrcount, fcount)
- char **ptr;
- int ptrcount, fcount;
- {
- int fdeep;
- int maxpgdeep;
- int qi;
- char *s1, *s2, *s3;
- static char *more = "--- more ---";
-
- if ((fdeep = Ty + 1) > Deepest)
- Deepest = fdeep;
-
- if (Fstop) {
- maxpgdeep = Deepest / Deepmod +1; /* 1, 2... */
- if (maxpgdeep < Fstop)
- maxpgdeep = Fstop;
- }
-
- /* list files only, skip directories; null out file names */
- if (fcount == 1) {
- for (DOUNCOUN (ptrcount, qi); ptr++) {
- if (*(*ptr + strlen (*ptr) -1) != '/') {
- tile (fdeep, BUD, 0, *ptr, ZERO, ZERO);
- **ptr = 0;
- return;
- }
- }
- }
-
- qi = ptrcount;
- while (qi--) {
- if (*(*ptr + strlen (*ptr) -1) != '/') {
- --fcount;
- s1 = *ptr;
- ptr++;
- break;
- }
- ptr++;
- }
- while (qi--) {
- if (*(*ptr + strlen (*ptr) -1) != '/') {
- --fcount;
- if (Fstop && fcount && ((fdeep+1)/Deepmod >= maxpgdeep)) {
- s2 = more;
- tile (fdeep, LEAF, 0, s1, s2, ZERO);
- *s1 = 0;
- **ptr = 0;
- while (qi--) {
- ++ptr;
- if (*(*ptr + strlen (*ptr) -1) != '/')
- **ptr = 0;
- }
- return;
- }
- s2 = *ptr;
- ptr++;
- break;
- }
- ptr++;
- }
- tile (fdeep, LEAF, 0, s1, s2, ZERO);
- *s1 = *s2 = 0;
-
- while (fcount >= 3) {
- if (++fdeep > Deepest)
- Deepest = fdeep;
- while (qi--) {
- if (*(*ptr + strlen (*ptr) -1) != '/') {
- --fcount;
- s1 = *ptr;
- ptr++;
- break;
- }
- ptr++;
- }
- while (qi--) {
- if (*(*ptr + strlen (*ptr) -1) != '/') {
- --fcount;
- s2 = *ptr;
- ptr++;
- break;
- }
- ptr++;
- }
- while (qi--) {
- if (*(*ptr + strlen (*ptr) -1) != '/') {
- --fcount;
- if (Fstop && fcount && ((fdeep+1)/Deepmod >= maxpgdeep)) {
- s3 = more;
- tile (fdeep, TRIPLE, 0, s1, s2, s3);
- *s1 = *s2 = 0;
- **ptr = 0;
- while (qi--) {
- ++ptr;
- if (*(*ptr + strlen (*ptr) -1) != '/')
- **ptr = 0;
- }
- return;
- }
- s3 = *ptr;
- ptr++;
- break;
- }
- ptr++;
- }
- tile (fdeep, TRIPLE, 0, s1, s2, s3);
- *s1 = *s2 = *s3 = 0;
- }
- if (fcount == 2) {
- if (++fdeep > Deepest)
- Deepest = fdeep;
- while (qi--) {
- if (*(*ptr + strlen (*ptr) -1) != '/') {
- --fcount;
- s1 = *ptr;
- ptr++;
- break;
- }
- ptr++;
- }
- while (qi--) {
- if (*(*ptr + strlen (*ptr) -1) != '/') {
- --fcount;
- s2 = *ptr;
- ptr++;
- break;
- }
- ptr++;
- }
- tile (fdeep, DOUBLE, 0, s1, s2, ZERO);
- *s1 = *s2 = 0;
- }
- else if (fcount == 1) {
- if (++fdeep > Deepest)
- Deepest = fdeep;
- while (qi--) {
- if (*(*ptr + strlen (*ptr) -1) != '/') {
- --fcount;
- s1 = *ptr;
- ptr++;
- break;
- }
- ptr++;
- }
- tile (fdeep, SINGLE, 0, s1, ZERO, ZERO);
- *s1 = 0;
- }
- }
- //E*O*F listfiles.c//
-
- echo x - mapper.c
- cat > "mapper.c" << '//E*O*F mapper.c//'
- /* mapper.c */
-
- #include "globals.h"
-
- extern int errno;
-
- mapper (dirname)
- char *dirname;
- {
- char dirego[IQUARTK];
- char cmd[IHALFK];
- char newpath[IONEK];
- char *pathptr;
- char *filebuf;
- char *fileend;
- char *ptrbuf;
- char **ptr;
- int ccount;
- int fcount;
- int dcount;
- int ptrcount;
- int qi;
- int flush;
-
- if (++Ty > Deepest)
- Deepest = Ty;
- sprintf (cmd, "/bin/ls -aFq %s > %s",dirname, Listfile);
- errno = 0;
- system (cmd);
- if (errno)
- BAILOUT;
-
- iego (dirname, dirego, '/', '/');
-
- if ((ccount = iread (Listfile, &filebuf)) < 1)
- goaway();
- fileend = filebuf + ccount;
- if ((ptrcount = illistn (filebuf, fileend, &ptrbuf)) < 1)
- BAILOUT;
-
- /* count files and directories */
- ptr = (char **)ptrbuf;
- for (dcount = fcount = 0, DOUNCOUN (ptrcount, qi); ptr++)
- (*(*ptr + strlen (*ptr) -1) == '/') ? ++dcount : ++fcount;
-
- if (dcount < 2) {
- strcat (dirego, "!");
- tile (Ty, BUD, 0, dirego, ZERO, ZERO);
- free (filebuf);
- return;
- }
-
- if (dcount == 2 && !fcount) {
- strcat (dirego, "/");
- tile (Ty, BUD, 0, dirego, ZERO, ZERO);
- free (filebuf);
- return;
- }
-
- /* At this point, the next tile is a Twig if dirname contains
- both files and directories, or no files and multiple dirs.
- The next tile is a Joint if dirname contains files only, or
- a single directory.
- */
- if (dcount == 2) {
- strcat (dirego, "/");
- tile (Ty, JOINT, 0, dirego, ZERO, ZERO);
- ptr = (char **)ptrbuf;
- listfiles (ptr, ptrcount, fcount);
- free (filebuf);
- return;
- }
- if (dcount == 3 && !fcount) {
- strcat (dirego, "/");
- tile (Ty, JOINT, 0, dirego, ZERO, ZERO);
- strcpy (newpath, dirname);
- pathptr = newpath + strlen (newpath);
- *pathptr++ = '/';
- ptr = (char **)ptrbuf;
- for (DOUNCOUN (ptrcount, qi); ptr++) {
- if (strcmp (*ptr, "./") && strcmp (*ptr, "../")) {
- if (!Depth || Ty < (Depth-1)) {
- *(*ptr + strlen (*ptr) -1) = 0;
- strcpy (pathptr, *ptr);
- mapper (newpath);
- Ty--;
- }
- else {
- *(*ptr + strlen (*ptr) -1) = '!';
- tile (Ty+1, BUD, 0, *ptr, ZERO, ZERO);
- if (Ty+1 > Deepest)
- Deepest = Ty+1;
- }
- free (filebuf);
- return;
- }
- }
- }
- if (fcount) { /* and dcount > 2 */
- strcat (dirego, "/");
- tile (Ty, TWIG, dcount-2, dirego, ZERO, ZERO);
- ptr = (char **)ptrbuf;
- listfiles (ptr, ptrcount, fcount);
-
- strcpy (newpath, dirname);
- pathptr = newpath + strlen (newpath);
- *pathptr++ = '/';
- ptr = (char **)ptrbuf;
- for (DOUNCOUN (ptrcount, qi); ptr++) {
- if (**ptr) { /* not a file */
- if (strcmp (*ptr, "./") && strcmp (*ptr, "../")) {
- ++Tx;
- if (!Depth || Ty < (Depth-1)) {
- *(*ptr + strlen (*ptr) -1) = 0;
- strcpy (pathptr, *ptr);
- mapper (newpath);
- Ty--;
- }
- else {
- *(*ptr + strlen (*ptr) -1) = '!';
- tile (Ty+1, BUD, 0, *ptr, ZERO, ZERO);
- if (Ty+1 > Deepest)
- Deepest = Ty+1;
- }
- }
- }
- }
- free (filebuf);
- return;
- }
-
- /* no files, multiple dirs */
- strcat (dirego, "/");
- tile (Ty, TWIG, dcount-3, dirego, ZERO, ZERO);
-
- flush = 1;
- strcpy (newpath, dirname);
- pathptr = newpath + strlen (newpath);
- *pathptr++ = '/';
- ptr = (char **)ptrbuf;
- for (DOUNCOUN (ptrcount, qi); ptr++) {
- if (strcmp (*ptr, "./") && strcmp (*ptr, "../")) {
- flush ? (flush = 0) : ++Tx;
- if (!Depth || Ty < (Depth-1)) {
- *(*ptr + strlen (*ptr) -1) = 0;
- strcpy (pathptr, *ptr);
- mapper (newpath);
- Ty--;
- }
- else {
- *(*ptr + strlen (*ptr) -1) = '!';
- tile (Ty+1, BUD, 0, *ptr, ZERO, ZERO);
- if (Ty+1 > Deepest)
- Deepest = Ty+1;
- }
- }
- }
- free (filebuf);
- return;
- }
-
- //E*O*F mapper.c//
-
- echo x - package.c
- cat > "package.c" << '//E*O*F package.c//'
- /* package.c */
-
- #include "globals.h"
-
- package ()
- {
- char *buf;
- struct tile *tp;
- struct tile **tmp;
- int tcount;
- int linkc;
- int depth = Deepest +1;
- int qi, qj;
-
- close (Td);
- if ((tcount = iread (Tiles, &buf)) < 1)
- BAILOUT;
- tcount /= TSIZ;
-
- Mcount = depth * (Tx+1);
- if ((Mp = (struct tile **)malloc (Mcount * sizeof (struct tile **)))
- == (struct tile **) NULL)
- BAILOUT;
-
- /* init all locations to Blank */
- for (tmp = Mp, DOUNCOUN (Mcount, qi); tmp++)
- *tmp = &Blank;
-
- /* remap tcount tiles in buf into a rectangular array, Y first:
- line 0: 0,0 /0,1 /0,2
- line 1: 1,0 / 1,1 / 1,2
- (6 deep) 2,0 / 2,1 / 2,2
- line 3: 3,0 / 3,1 / 3,2
- line 4: 4,0 / 4,1 / 4,2
- Deepest: 5,0/ 5,1/ 5,2
- */
- tp = (struct tile *)buf;
- for (DOUNCOUN (tcount, qi); tp++)
- Mp[tp->hor * depth + tp->ver] = tp;
-
- /* blank out leader to first tile (root) only */
- tp = Mp[0];
- strcpy (tp->line1, " ");
-
- /* Find and complete every Twig, line-by-line left-to-right.
- Do not look for Twig in bottom line or at right edge.
- To right of each Twig, substitute Twig->linkc number of Blank
- tiles with Tap tiles (or Tip at the terminal tile).
- Tap or Tip tiles must be installed directly above non-blank
- tiles only: if next horizontal position is located above a Blank,
- a Span tile is laid instead.
- */
- for (qi = 0; qi < Deepest; qi++) { /* Y loop */
- for (qj = 0; qj < Tx; qj++) { /* X loop */
- if (linkc = (Mp[qj*depth+qi])->linkc) { /* a Twig? */
- ++qj; /* next hor. tile */
- for (--linkc; linkc; qj++) { /* not incl. Tip */
- if (Mp[qj*depth+qi+1] == &Blank) {
- Mp[qj*depth+qi] = &Span;
- continue;
- }
- Mp[qj*depth+qi] = &Tap;
- linkc--;
- }
- while (Mp[qj*depth+qi+1] == &Blank) {
- Mp[qj*depth+qi] = &Span;
- qj++;
- }
- Mp[qj*depth+qi] = &Tip;
- }
- }
- }
-
- /***** To print matrix data:
- for (tmp = Mp, DOUNCOUN (Mcount, qi); tmp++)
- printf ("%s]\n%s]\n%s]\n................\n",
- (*tmp)->line1, (*tmp)->line2, (*tmp)->line3);
- */
-
- /***** To print file data:
- tp = (struct tile *)buf;
- for (qi = tcount; qi--; tp++)
- printf ("Y:%d X:%d B:%d\n%s]\n%s]\n%s]\n................\n",
- tp->ver, tp->hor, tp->linkc, tp->line1, tp->line2, tp->line3);
- */
-
-
- }
- //E*O*F package.c//
-
- echo x - split.c
- cat > "split.c" << '//E*O*F split.c//'
- /* split.c */
-
- #include "globals.h"
-
- split ()
- {
- static char alpha[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
- char counter[32]; /* horiz. numerical id of page */
- char pad[4]; /* 0, 1, or 2 newlines at end of page */
- char verid[4]; /* vertical, alpha id of page */
- char topline[IONEK]; /* top border of page */
- char botline[IONEK]; /* bottom border of page */
- char blankline[IONEK];
- char strip[3*IONEK]; /* 3 lines: a horiz. strip of tiles */
- struct tile *tp;
- char *s1, *s2, *s3;
- char *pp;
- int depth = Deepest +1;
- int width = Tx +1;
- int darktile; /* any tile except Blank */
- int skip = 0; /* count of blank pages skipped */
- int thishor; /* number of tiles horiz. on this page */
- int thisver; /* number of tiles vert. on this page */
- int horpcnt; /* number of horizontal pages of data */
- int verpcnt; /* number of vertical pages of data */
- int padline; /* pad page at bottom with blank lines */
- int realcols; /* actual number of cols printed/page */
- int stripsiz; /* characters printed per strip */
- int qy, qx;
- int ty, tx;
-
- padline = Lin % 3;
- horpcnt = Tx/Widemod +1;
- verpcnt = Deepest/Deepmod +1;
- realcols = Widemod * 16 +3 +1; /* newline at end */
- stripsiz = realcols * 3;
-
- fprintf (stderr, "Matrix of %d horizontal %s @ %d %s per list.\n",
- verpcnt, (verpcnt > 1) ? "lists" : "list",
- horpcnt, (horpcnt > 1) ? "pages" : "page");
-
- pp = topline;
- *pp++ = SPACE;
- *pp++ = SPACE;
- for (DOUNCOUN (realcols-4, qx); *pp++ = ':');
- *pp = '\n';
-
- pp = botline;
- *pp++ = SPACE;
- *pp++ = SPACE;
- for (DOUNCOUN (realcols-4, qx); *pp++ = ';');
- *pp = '\n';
-
- pp = blankline;
- *pp++ = SPACE;
- *pp++ = '(';
- for (DOUNCOUN (realcols-4, qx); *pp++ = SPACE);
- *pp++ = ')';
- *pp = '\n';
-
- if (padline)
- strcpy (pad, ((padline == 1) ? "\n" : "\n\n"));
-
- /* Output pages with number X coordinates and letter Y coordinates.
- Output pages in horizontal order first.
- */
- for (thisver = Deepmod, qy = 0; qy < verpcnt; qy++) {
- if (verpcnt < 26) { /* one-character alpha coordinate */
- verid[0] = alpha[qy];
- verid[1] = SPACE;
- verid[2] = SPACE;
- }
- else if (verpcnt < 676) { /* two-character alpha coordinate */
- ty = qy % 676; /* a number between 0 and 675 */
- tx = ty / 26; /* a number between 0 and 25 */
- verid[0] = alpha[tx];
- tx = qy % 26; /* a number between 0 and 25 */
- verid[1] = alpha[tx];
- verid[2] = SPACE;
- }
- else { /* three-character alpha coordinate */
- qx = qy % 17576; /* a number between 0 and 17575 */
- tx = qx / 676; /* a number between 0 and 25 */
- verid[0] = alpha[tx];
- ty = qx % 676; /* a number between 0 and 675 */
- tx = ty / 26; /* a number between 0 and 25 */
- verid[1] = alpha[tx];
- tx = qx % 26; /* a number between 0 and 25 */
- verid[2] = alpha[tx];
- }
-
- /* Each horizontal pagelist already output contained
- width * Deepmod tiles. When on the last pagelist, the
- remaining tilecount divided by the width of the tile matrix
- gives the count of tiles to print vertically.
- */
- if (qy+1 == verpcnt)
- thisver = (Mcount - qy * width * Deepmod) / width;
-
- for (thishor = Widemod, qx = 0; qx < horpcnt; qx++) {
- /* When on the last page of the horizontal pagelist,
- the number of horizontal tiles to print on the page is
- width % Widemod (if there is a remainder), or
- Widemod (if there is no remainder).
- */
- if (qx+1 == horpcnt)
- if (!(thishor = width % Widemod))
- thishor = Widemod;
-
- for (darktile = ty = 0; ty < thisver; ty++) {
- for (tx = 0; tx < thishor; tx++) {
- tp = Mp[qx*depth*Widemod+tx*depth+qy*Deepmod+ty];
- if (tp != &Blank)
- darktile = 1;
- if (darktile)
- break;
- }
- if (darktile)
- break;
- }
- if (!Printblank && !darktile) {
- ++skip;
- goto skippage;
- }
-
- sprintf (counter, " %d\n", qx +1);
- write (1, counter, strlen (counter));
- write (1, topline, realcols-1);
- for (ty = 0; ty < thisver; ty++) {
- s1 = strip;
- s2 = s1 + realcols;
- s3 = s2 + realcols;
- if (ty == 0) {
- *s1++ = verid[0];
- *s2++ = verid[1];
- *s3++ = verid[2];
- }
- else {
- *s1++ = SPACE;
- *s2++ = SPACE;
- *s3++ = SPACE;
- }
- *s1++ = '(';
- *s2++ = '(';
- *s3++ = '(';
- for (tx = 0; tx < thishor; tx++) {
- /* Each previous column (qx) of pages advanced the
- Mp index of the current tile column by
- depth * Widemod. Each previous tile column on
- this page advanced the Mp index by depth. The
- current pointer is the offset from the current
- tile column start, by the current depth.
- */
- tp = Mp[qx*depth*Widemod+tx*depth+qy*Deepmod+ty];
- strcpy (s1, tp->line1);
- s1 += 16;
- strcpy (s2, tp->line2);
- s2 += 16;
- strcpy (s3, tp->line3);
- s3 += 16;
- }
- if (thishor < Widemod) {
- for (tp = &Blank; tx < Widemod; tx++) {
- strcpy (s1, tp->line1);
- s1 += 16;
- strcpy (s2, tp->line2);
- s2 += 16;
- strcpy (s3, tp->line3);
- s3 += 16;
- }
- }
- *s1++ = ')';
- *s2++ = ')';
- *s3++ = ')';
- *s1 = '\n';
- *s2 = '\n';
- *s3 = '\n';
- write (1, strip, stripsiz);
- }
- if (thisver < Deepmod)
- for (ty = 3 * (Deepmod-thisver); ty; ty--)
- write (1, blankline, realcols);
-
- write (1, botline, realcols-1);
- if (padline)
- write (1, pad, padline);
- skippage:;
- }
- }
- if (skip)
- fprintf (stderr, "Skipped %d blank pages.\n", skip);
- }
- //E*O*F split.c//
-
- echo x - tile.c
- cat > "tile.c" << '//E*O*F tile.c//'
- /* tile.c */
-
- #include "globals.h"
-
- tile (ver, kind, linkc, str1, str2, str3)
- int kind, linkc;
- char *str1, *str2, *str3;
- {
- char *sp, *lim;
- struct tile *tp;
- int q1, q2, q3;
-
- if (!NULCHARP (str1) && ((q1 = strlen (str1)) > MAXFN)) {
- *(str1 + MAXFN -1) = '<';
- *(str1 + MAXFN) = 0;
- q1 = MAXFN;
- }
- if (!NULCHARP (str2) && ((q2 = strlen (str2)) > MAXFN)) {
- *(str2 + MAXFN -1) = '<';
- *(str2 + MAXFN) = 0;
- q2 = MAXFN;
- }
- if (!NULCHARP (str3) && ((q3 = strlen (str3)) > MAXFN)) {
- *(str3 + MAXFN -1) = '<';
- *(str3 + MAXFN) = 0;
- q3 = MAXFN;
- }
-
- switch (kind) {
- default:
- case BLANK:
- tp = &Blank;
- break;
-
- case SINGLE:
- tp = &Single;
- strcpy (tp->line1 , str1);
- lim = tp->line1 + MAXFN +1;
- sp = tp->line1 + q1;
- while (sp < lim)
- *sp++ = SPACE;
- break;
-
- case DOUBLE:
- tp = &Double;
- strcpy (tp->line1 , str1);
- lim = tp->line1 + MAXFN +1;
- sp = tp->line1 + q1;
- while (sp < lim)
- *sp++ = SPACE;
- strcpy (tp->line2 , str2);
- lim = tp->line2 + MAXFN +1;
- sp = tp->line2 + q2;
- while (sp < lim)
- *sp++ = SPACE;
- break;
-
- case TRIPLE:
- tp = &Triple;
- strcpy (tp->line1 , str1);
- lim = tp->line1 + MAXFN +1;
- sp = tp->line1 + q1;
- while (sp < lim)
- *sp++ = SPACE;
- strcpy (tp->line2 , str2);
- lim = tp->line2 + MAXFN +1;
- sp = tp->line2 + q2;
- while (sp < lim)
- *sp++ = SPACE;
- strcpy (tp->line3 , str3);
- lim = tp->line3 + MAXFN +1;
- sp = tp->line3 + q3;
- while (sp < lim)
- *sp++ = SPACE;
- break;
-
- case LEAF:
- tp = &Leaf;
- strcpy (tp->line2 , str1);
- lim = tp->line2 + MAXFN +1;
- sp = tp->line2 + q1;
- while (sp < lim)
- *sp++ = SPACE;
- strcpy (tp->line3 , str2);
- lim = tp->line3 + MAXFN +1;
- sp = tp->line3 + q2;
- while (sp < lim)
- *sp++ = SPACE;
- break;
-
- case BUD:
- tp = &Bud;
- strcpy (tp->line2 , str1);
- lim = tp->line2 + MAXFN +1;
- sp = tp->line2 + q1;
- while (sp < lim)
- *sp++ = SPACE;
- break;
-
- case JOINT:
- tp = &Joint;
- strcpy (tp->line2 , str1);
- lim = tp->line2 + MAXFN +1;
- sp = tp->line2 + q1;
- while (sp < lim)
- *sp++ = SPACE;
- break;
-
- case TWIG:
- tp = &Joint;
- strcpy (tp->line2 , str1);
- lim = tp->line2 + MAXFN +1;
- sp = tp->line2 + q1;
- while (sp < lim)
- *sp++ = '~';
- break;
- }
-
- tp->ver = ver;
- tp->hor = Tx;
- tp->linkc = linkc;
-
- if (write (Td, tp, TSIZ) != TSIZ)
- BAILOUT;
- }
- //E*O*F tile.c//
-
- echo x - treeD.c
- cat > "treeD.c" << '//E*O*F treeD.c//'
- /* treeD.c --- Unix file system diagrammer */
- /******************************
- * Author: Istvan Mohos
- * March 1990
- ******************************/
-
- #define MAIN
- #include "globals.h"
-
- main (argc, argv)
- int argc;
- char *argv[];
- {
- int optchar;
- char **opt;
-
- if (argc == 1)
- cmderr:
- fprintf(stderr,
- "Usage: %s [-wN] [-lN] [-dN] [-fN] [-blank] dir\n%s%s%s%s%s", argv[0],
- "\t-w N maximum printable column width of page (min.19, max.1023)\n",
- "\t-l N maximum count of lines per page (min.6)\n",
- "\t-d N limit directory recursion to N depth\n",
- "\t-f N truncate long file lists beyond the Nth vertical page\n",
- "\t-blank force the printing of blank pages (suppressed by default)\n"),
- exit(1);
-
- opt = &(argv[1]);
- while (optchar = iopt (&opt)) {
- switch (optchar) {
- default:
- goto cmderr;
- case 'w':
- if ((Wid = atoi (*opt)) < 19 || Wid > 1023)
- fprintf(stderr,
- "page width: 19 -- 1023 columns\n"), exit(1);
- break;
- case 'l':
- if ((Lin = atoi (*opt)) < 6)
- fprintf(stderr,
- "page length: minimum 6 lines\n"), exit(1);
- break;
- case 'd':
- if ((Depth = atoi (*opt)) < 1)
- fprintf(stderr,
- "minimum depth: 1 level\n"), exit(1);
- break;
- case 'f':
- if ((Fstop = atoi (*opt)) < 1)
- fprintf(stderr,
- "minimum depth: 1 page\n"), exit(1);
- break;
- case 'b':
- Printblank = 1;
- break;
- }
- }
-
- init();
- mapper (*opt);
- package();
- split();
- goaway();
- }
- //E*O*F treeD.c//
-
- echo x - makefile
- cat > "makefile" << '//E*O*F makefile//'
- #
- CC=/bin/cc
-
- # PC6300+ SysV
- #CFLAGS=-O -DREALUNIX -DPLUS6300
-
- # BSD
- CFLAGS=-O
-
- #.SILENT:
-
- IFILES= iopt.o iego.o ierror.o iread.o illistn.o
- FILES= treeD.o init.o tile.o listfiles.o mapper.o package.o goaway.o split.o
-
- treeD: ${FILES} ${IFILES}
- $(CC) -o $@ ${FILES} ${IFILES}
-
- ${IFILES}:i.h
- ${FILES}: globals.h
- //E*O*F makefile//
-
- echo x - treeX
- cat > "treeX" << '//E*O*F treeX//'
- #!/bin/sh
- # Istvan Mohos, May 1990
- if test $# -eq 0
- then echo "Usage: $0 dirname"
- exit 1
- fi
- name=`basename $0`
- treeD -l79 -w115 -f1 $* > /tmp/$$.tex
- tail -50 $0 > $name.tex
- echo \\listing\{/tmp/$$.tex\} >> $name.tex
- echo \\bye >> $name.tex
- tex $name.tex
- /bin/rm /tmp/$$.tex
- exit 0
-
- % TeX input begins here
- \vsize 9.9in
- \hsize 7.5in
- \font\stt=cmtt8
- \raggedbottom \nopagenumbers \stt
- \baselineskip 9pt
- % verbatim macros from Appendix D (pages 381, 391) of The TeXbook
- % redefined ( ) : ; ~ > | for char graphics
- \def\uncatcodespecials{\def\do##1{\catcode`##1=12 }\dospecials}
- \def\setupverbatim{\stt
- \def\par{\leavevmode\egroup\box0\endgraf}
- \obeylines \uncatcodespecials \obeyspaces
- \catcode`\`=\active \catcode`\^^I=\active
- \catcode`(=\active \catcode`)=\active
- \catcode`:=\active \catcode`;=\active
- \catcode`\~=\active \catcode`>=\active \catcode`|=\active
- \everypar{\startbox}}
- \newdimen\w \setbox0=\hbox{\stt\space} \w=4\wd0 % width of tab
- \def\startbox{\setbox0=\hbox\bgroup}
- {\catcode`\`=\active \gdef`{\relax\lq}}
- {\catcode`\^^I=\active
- \gdef^^I{\leavevmode\egroup
- \dimen0=\wd0 % the width so far, or since the previous tab
- \divide\dimen0 by\w
- \multiply\dimen0 by\w % compute previous multiple of \w
- \advance\dimen0 by\w % advance to next multiple of \w
- \wd0=\dimen0 \box0 \startbox}}
- {\obeyspaces\global\let =\ } % let active space become control space
- \def\listing#1{\par\begingroup\setupverbatim\input#1 \endgroup}
- %
- \newdimen\vsz % \vsz dimensions are relative to \baselineskip
- \vsz=9pt
- \newdimen\hsz % \hsz dimensions are a function of char width
- \setbox0=\hbox{\stt m}
- \hsz=\wd0
- %
- {\catcode`(=\active % vertical left border
- \gdef({\kern.6\hsz\vrule width.1\hsz height.8\vsz depth.2\vsz\kern.3\hsz}}
- {\catcode`)=\active % vertical right border
- \gdef){\kern.2\hsz\vrule width.1\hsz height.8\vsz depth.2\vsz\kern.7\hsz}}
- {\catcode`:=\active % horizontal upper border
- \gdef:{\kern-.4\hsz\vrule width1.7\hsz height-.17\vsz depth.22\vsz\kern-.3\hsz}}
- {\catcode`;=\active % horizontal lower border
- \gdef;{\kern-.4\hsz\vrule width1.7\hsz height.78\vsz depth-.73\vsz\kern-.3\hsz}}
- {\catcode`\~=\active % horizontal branch
- \gdef~{\vrule width1\hsz height0\vsz depth.2\vsz}}
- {\catcode`>=\active % elbow (knob) moving horizontal branch to vertical
- \gdef>{\vrule width.7\hsz height0\vsz depth.2\vsz\kern.3\hsz}}
- {\catcode`|=\active % vertical branch
- \gdef|{\kern.3\hsz\vrule width.4\hsz height.8\vsz depth.2\vsz\kern.3\hsz}}
- //E*O*F treeX//
-
- echo x - treeD.tex
- cat > "treeD.tex" << '//E*O*F treeD.tex//'
- % XREF treeD treeX
- \font\myit=cmti9
- \font\mytt=cmtt9
- \font\myletr=cmssq8
- \font\bb=cmssbx10
-
- \def\date{{\myletr May 4, 1990}}
- \def\vers{{\myletr Version 1.1}}
- \def\mansection{USER (1)}
- \def\name{treeD}
- \def\IT{{\bb treeD}}
- \def\ALT{{\bb treeX}}
-
- \hsize 5.6in
- \vsize 8in
- \raggedbottom
- \parskip 0pt
- \parindent 0pt
- \myletr
-
- % to enclose a horizontal upper-case string in a rectangle
- \def\dx#1{\kern -.15em\setbox0=\hbox{\thinspace{#1}\thinspace}
- \dimen0=\ht0 \advance\dimen0 by 2pt
- \dimen1=\dimen0 \advance\dimen1 by -.3pt
- \dimen3=\dp0 \advance\dimen3 by 2.3pt
- \dimen4=\dimen3 \advance\dimen4 by -.3pt
- \vrule height \dimen0 depth \dimen3 width .3pt
- \vrule height \dimen0 depth -\dimen1 width \wd0
- \vrule width -\wd0
- \vrule height -\dimen4 depth \dimen3 width \wd0
- \vrule width -\wd0
- \box0
- \vrule height \dimen0 depth \dimen3 width .3pt
- }
- % to enclose a single \tt key in a square
- \def\key#1{\setbox0=\hbox{\thinspace{\mytt#1}\thinspace}
- \dimen0=2ex \dimen1=\dimen0 \advance\dimen1 by -.3pt
- \dimen3=.5ex \dimen4=\dimen3 \advance\dimen4 by -.3pt
- \dimen5=\wd0
- \vrule height \dimen0 depth \dimen3 width .3pt % left vertical
- \vrule height \dimen0 depth -\dimen1 width 1.05em % top horiz
- \vrule width -1.05em % backup to left
- \box0 % install text
- \vrule width -\dimen5 % backup to left
- \vrule height -\dimen4 depth \dimen3 width 1.05em % bottom horiz
- \vrule height \dimen0 depth \dimen3 width .3pt % right vertical
- \thinspace
- }
- \def\bs{{\char92}} % \
- \def\ul{{\char95}} % _
- \def\pipe{{\char124}} % |
- \def\lc{{\char123}} % {
- \def\rc{{\char125}} % }
- \def\lbrac{{\char91}} % [
- \def\rbrac{{\char93}} % ]
- \def\langle{{\char60}} % <
- \def\rangle{{\char62}} % >
- \def\circum{{\char94}} % ^
- \def\caret{{\char94}} % ^
- \def\tilde{{\char126}} % ~
- \def\dollar{{\char36}} % $
- \def\at{{\char64}} % @
-
- \headline={{\myletr\name\hfil\mansection\hfil\name}}
- \footline={\ifodd\pageno\rightfoot\else\leftfoot\fi}
- \def\leftfoot{\rlap{\myletr\folio}\hfil{\vers\ --- \date}\hfil}
- \def\rightfoot{\hfil{\vers\ --- \date}\hfil\llap{\myletr\folio}}
- \def\S#1{\leftline{}\par\leftskip=-20pt{\bb#1}\smallskip\leftskip=0pt}
- \def\SU#1{\par\leftskip=-20pt{\bb#1}\smallskip\leftskip=0pt}
- \def\L{\par\leftline{}\par}
- \def\I#1{\leftskip=20pt{#1}\par\leftskip=0pt}
-
- \S{NAME}
- \IT\ --- Unix file system diagrammer
-
- \ALT\ --- produce a file system diagram in \TeX
-
- \S{SYNOPSIS}
- \IT\
- \lbrac --w N\rbrac\
- \lbrac --l N\rbrac\
- \lbrac --d N\rbrac\
- \lbrac --f N\rbrac\
- \lbrac --blank\rbrac\
- dirname
-
- \ALT\ dirname
-
- \S{DESCRIPTION}
- The \IT\ file system diagrammer bypasses text width limitations imposed
- by fan-fold paper or scrollable screen output mediums, and
- constructs a true two-dimensional map of the file
- system ``{\myit dirname\/}'' specified on the command line.
- To realize a hardcopy of this map, the internal diagram is
- output in the form of
- equal-sized pages, each page bearing a letter/number
- coordinate analogous to lettered, numbered grids on a street map.
- Command line options fine tune the format of the output, control
- non-default grid sizes and the depth of the directory search
- as follows:
- \L
- \item{{\bb --w} N}
- specifies that the maximum printing width of a physical page
- is N character columns. The internal width of individual
- grid rectangles will be expanded or reduced to the
- nearest number of columns not greater
- than N that will permit printing
- full 16-column vertical file lists in parallel. Each page must
- be wide enough to contain at least one fixed width vertical file list,
- two additional bytes per page for the vertical
- grid boundary markers, and one leftmost byte for the vertical character
- coordinate stamp of the grid: 19 bytes minimum. The default page width
- is nominally 72 bytes, 67 bytes of which is used to print a grid
- rectangle.
- \L
- \item{{\bb --l} N}
- specifies the maximum number of lines N, that can be printed on
- a physical page. Vertical lists of the map are arranged in
- {\myit tiles\/}, each tile three lines in depth. The smallest page
- must be able to contain one tile, plus two lines for the top and bottom
- horizontal grid markers, and a topmost line for the numerical
- coordinate stamp of the grid: a minimum of 6 lines. The default
- page length is 66 lines, containing 21 tiles.
- \L
- \item{{\bb --d} N}
- instructs \IT\ to halt directory recursion at N depth. That is,
- the command
- \dx{treeD --d1 ../usr}\ results in diagramming the file structure of
- {\myit ../usr\/}, but without descending into or listing the contents
- of any of the
- subdirectories. The default N depth (zero) specifies infinite descent.
- \L
- \item{{\bb --f} N}
- results in truncating long file lists beyond the Nth vertical page.
- The default depth page can display 21 directory levels or
- 63 plain files. The structure of even complex file systems can often
- be contained on a single horizontal grid strip, branches using up
- map width much more readily than depth. One or two directories with
- many plain files may necessitate vertical expansion to show
- excessively deep file lists; and can double or triple the total size of
- the map while contributing little to the structural information. The
- {\myit --f\/} option truncates such long (plain) file lists beyond the
- specified vertical page.
- \L
- \item{{\bb --blank}}
- forces \IT\ to output blank ``filler'' pages. If both the width and
- the depth of the map is more than one grid rectangle,
- the map may contain blank grids.
- By default, such pages are not output. With the {\myit --blank\/}
- option any blank grids are also printed, each otherwise blank page
- containing the number and letter coordinates and the outline
- of the grid.
- \L
- The \IT\ process lists the files of the examined directories via the
- \dx{ls -aFq}\ command, producing also the names of ``hidden files'',
- and appending a single ``file type'' character to names of
- directories, executable files, and a number of special files
- (differently between System~V and BSD). \IT\ does not display the
- \key{.} and \key{..}
- special directory links. File names longer than
- 14 characters are truncated in the map at 14 bytes, and the
- ``name too long''
- file type marker \key{\langle} is added as the fifteenth
- character. The file type marker of inaccessible directories
- is changed from \key{/} to \key{!}, also in the cases when the
- directory was made unreadable by the {\myit --d\/} option limiting
- the descent. The sixteenth byte of a printed plain filename is
- always a space.
- \L
- The \ALT\ Bourne shell script first executes the
- \smallskip
- \I{\mytt treeD \ -l 79 \ -w 115 \ -f1 \ \dollar *}
- \smallskip
- command to diagram the directory specified on its command line,
- then converts the output of the \IT\ command to
- plain \TeX\ input. Grid borders originally
- marked by vertical \key{(} \key{)} and
- horizontal \key{:} \key{;} characters are converted to
- thin vertical and horizontal lines; file branch markers
- \key{\tilde} \key{\pipe} \key{\rangle} are converted to
- bold lines. The {\myit treeX.tex\/} file thus produced, is then input
- to \TeX, and yields the device independent output
- {\myit treeX.dvi\/}, ready for printing. The \IT\ command line
- options embedded within \ALT\ can be overridden by specifying new
- options on \ALT's command line before the final ``{\myit dirname\/}'',
- however the \TeX\ format is expecting the exact 115-byte width and
- 79-line pages shown above.
- \bye
- //E*O*F treeD.tex//
-
- echo x - README
- cat > "README" << '//E*O*F README//'
- treeD --- Unix file system diagrammer
-
- The utmost conceptual simplicity of file system trees belies the
- difficulty of memorizing actual nodal layouts of specific trees.
- In spite a plain topological essence of TREE no two trees are
- the same; and most users would have an equal chance of being able
- to recall the exact twig arrangement of last year's Christmas tree
- as they would in describing a 30 Meg Unix subdirectory.
-
- Recursive listers such as 'find' obscure the tree structure by the
- one-dimensionality of their output: standard output mediums of
- pinfeed paper or the scrollable screen rigidly limit the width,
- while allowing infinitely long lists.
-
- The treeD file system diagrammer erases the width limitation of
- the output medium, and constructs true two-dimensional maps of
- file systems. To realize a hardcopy of a map, the internal diagram
- is output as equal-sized pages, each page bearing a letter/number
- coordinate analogous to lettered, numbered grids on a street map.
- Command line options fine tune the format of the output, control
- non-default grid sizes and the depth of the directory search.
-
- -DREALUNIX should be enabled in the makefile when compiling under
- System V. The 'man page' is in the file treeD.tex, and should be
- processed with "tex treeD" (assuming TeX capability at the site).
- The Bourne script treeX converts treeD's character-graphics
- depicting branching, to bold lines under plain TeX.
- //E*O*F README//
-
- echo Possible errors detected by \'wc\' [hopefully none]:
- temp=/tmp/shar$$
- trap "rm -f $temp; exit" 0 1 2 3 15
- cat > $temp <<\!!!
- 105 398 2671 globals.h
- 78 213 1596 i.h
- 160 591 4205 ilib.h
- 19 30 262 goaway.c
- 40 120 749 iego.c
- 35 99 744 ierror.c
- 40 137 914 illistn.c
- 138 298 2905 init.c
- 58 206 1330 iopt.c
- 47 162 1143 iread.c
- 153 457 2655 listfiles.c
- 161 556 3553 mapper.c
- 88 364 2351 package.c
- 192 918 5652 split.c
- 125 421 2371 tile.c
- 64 198 1428 treeD.c
- 19 38 311 makefile
- 65 249 2480 treeX
- 188 1047 7408 treeD.tex
- 27 225 1419 README
- 1802 6727 46147 total
- !!!
- wc globals.h i.h ilib.h \
- goaway.c iego.c ierror.c illistn.c init.c iopt.c iread.c \
- listfiles.c mapper.c package.c split.c tile.c treeD.c \
- makefile treeX treeD.tex README | sed 's=[^ ]*/==' | diff -b $temp -
- exit 0
- --
- Istvan Mohos
- ...uunet!pyrdc!pyrnj!hhb!istvan
- RACAL-REDAC/HHB 1000 Wyckoff Ave. Mahwah NJ 07430 201-848-8000
- ======================================================================
-