home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1256 < prev    next >
Encoding:
Internet Message Format  |  1990-12-28  |  49.7 KB

  1. From: istvan@hhb.UUCP (Istvan Mohos)
  2. Newsgroups: alt.sources
  3. Subject: treeD --- Unix file system diagrammer
  4. Message-ID: <508@hhb.UUCP>
  5. Date: 3 May 90 18:56:24 GMT
  6.  
  7.  
  8.  
  9. The utmost conceptual simplicity of file system trees belies the
  10. difficulty of memorizing actual nodal layouts of specific trees.
  11. In spite a plain topological essence of TREE no two trees are
  12. the same; and most users would have an equal chance of being able
  13. to recall the exact twig arrangement of last year's Christmas tree
  14. as they would in describing a 30 Meg Unix subdirectory.
  15.  
  16. Recursive listers such as 'find' obscure the tree structure by the
  17. one-dimensionality of their output: standard output mediums of
  18. pinfeed paper or the scrollable screen rigidly limit the width,
  19. while allowing infinitely long lists.
  20.  
  21. The treeD file system diagrammer erases the width limitation of
  22. the output medium, and constructs true two-dimensional maps of
  23. file systems.  To realize a hardcopy of a map, the internal diagram
  24. is output as equal-sized pages, each page bearing a letter/number
  25. coordinate analogous to lettered, numbered grids on a street map.
  26. Command line options fine tune the format of the output, control
  27. non-default grid sizes and the depth of the directory search.
  28.  
  29. -DREALUNIX should be enabled in the makefile when compiling under
  30. System V.  The 'man page' is in the file treeD.tex, and should be
  31. processed with "tex treeD" (assuming TeX capability at the site).
  32. The Bourne script treeX converts treeD's character-graphics
  33. depicting branching, to bold lines under plain TeX.
  34.  
  35. ===============================cut here===========================
  36. # This is a shell archive.  Remove anything before this line, then
  37. # unpack it by saving it in a file and typing "sh file".  (Files
  38. # unpacked will be owned by you and have default permissions.)
  39. #
  40. # This archive contains:
  41. # globals.h i.h ilib.h
  42. # goaway.c iego.c ierror.c illistn.c init.c iopt.c iread.c
  43. # listfiles.c mapper.c package.c split.c tile.c treeD.c
  44. # makefile treeX treeD.tex README
  45.  
  46. echo x - globals.h
  47. cat > "globals.h" << '//E*O*F globals.h//'
  48. /* globals.h */
  49.  
  50. #include "ilib.h"
  51. #include <signal.h>
  52. #include <sys/types.h>
  53. #include <sys/stat.h>
  54.  
  55. #define BLANK     0
  56. #define SINGLE    1
  57. #define DOUBLE    2
  58. #define TRIPLE    3
  59. #define LEAF      4
  60. #define BUD       5
  61. #define JOINT     6
  62. #define TWIG      7
  63. #define SPAN      8
  64. #define TAP       9
  65. #define TIP       10
  66.  
  67. #define MAXFN     15      /* fourteen name chars, 1 type char */
  68. #define SPACE     32      /* ASCII value */
  69.  
  70. #define ZERO      ((char *)NULL)
  71. #define TSIZ      (sizeof (struct tile))
  72.  
  73. #define BAILOUT   sprintf (Msg, "error at line %d of %s",\
  74.                   __LINE__, __FILE__), goaway()
  75.  
  76. int  goaway();
  77. int  fstat();
  78. int  stat();
  79. char *malloc();
  80. char *gets();
  81.  
  82. struct tile {
  83.     int ver;
  84.     int hor;
  85.     int linkc;
  86.     char line1[17];
  87.     char line2[17];
  88.     char line3[17];
  89. };
  90.  
  91. #ifdef MAIN
  92.  
  93. char Listfile[IQUARTK];   /* /tmp file for listing of current dir */
  94. char Tiles[IQUARTK];      /* /tmp filename for sequential output */
  95. char Msg[IQUARTK];        /* buffer for reporting errors to user */
  96. struct tile **Mp;         /* base of tile pointer matrix */
  97. int  Td;                  /* Tile descriptor */
  98. int  Tx;                  /* horizontal tile position */
  99. int  Ty = -1;             /* vertical tile position */
  100. int  Deepest;             /* greatest vertical depth reached */
  101. int  Wid = 72;            /* max column width of printed page */
  102. int  Lin = 66;            /* max lines on printed page */
  103. int  Widemod;             /* number of tiles/page horizontally */
  104. int  Deepmod;             /* number of tiles/page vertically */
  105. int  Depth;               /* max. recursion depth; 0=infty */
  106. int  Fstop;               /* max. file list page; 0=infty */
  107. int  Printblank;          /* print page even if no tiles on it */
  108. unsigned int Mcount;      /* width*height of rectangular tile matrix */
  109.  
  110. struct tile Blank;        /* one of each tile, initialized in init.c */
  111. struct tile Single;
  112. struct tile Double;
  113. struct tile Triple;
  114. struct tile Leaf;
  115. struct tile Bud;
  116. struct tile Joint;
  117. struct tile Twig;
  118. struct tile Span;
  119. struct tile Tap;
  120. struct tile Tip;
  121.  
  122. #else
  123. extern char Listfile[];
  124. extern char Tiles[];
  125. extern char Msg[];
  126. extern struct tile **Mp;
  127. extern int  Td;
  128. extern int  Tx;
  129. extern int  Ty;
  130. extern int  Deepest;
  131. extern int  Lin;
  132. extern int  Wid;
  133. extern int  Widemod;
  134. extern int  Deepmod;
  135. extern int  Depth;
  136. extern int  Fstop;
  137. extern int  Printblank;
  138. extern unsigned int Mcount;
  139.  
  140. extern struct tile Blank;
  141. extern struct tile Single;
  142. extern struct tile Double;
  143. extern struct tile Triple;
  144. extern struct tile Leaf;
  145. extern struct tile Bud;
  146. extern struct tile Joint;
  147. extern struct tile Twig;
  148. extern struct tile Span;
  149. extern struct tile Tap;
  150. extern struct tile Tip;
  151.  
  152. #endif
  153. //E*O*F globals.h//
  154.  
  155. echo x - i.h
  156. cat > "i.h" << '//E*O*F i.h//'
  157. /* i.h */
  158. /**************************************
  159. * local include file for ilib functions
  160. * Istvan Mohos, 1987
  161. ***************************************/
  162.  
  163. #ifdef pyr
  164. #include <sys/time.h>
  165. #else
  166. #include <time.h>
  167. #endif
  168.  
  169. #include <stdio.h>
  170. #include <signal.h>
  171. #include <sys/types.h>
  172. #include <sys/stat.h>
  173.  
  174. #ifndef X_OK
  175. #    ifdef REALUNIX
  176. #        define F_OK 0
  177. #        define X_OK 1
  178. #        define W_OK 2
  179. #        define R_OK 4
  180. #        include <fcntl.h>
  181. #    else
  182. #        include <sys/file.h>
  183. #    endif
  184. #endif
  185.  
  186. #define NUL          0    /* the ASCII 0 byte */
  187. #define MAXSTR       1892
  188. #define BIGBUFSIZ    4096
  189. #define SHORTSTR     256
  190. #define IFOURK       4096
  191. #define ITWOK        2048
  192. #define IONEK        1024
  193. #define IHALFK       512
  194. #define IQUARTK      256
  195. #define BADCHARP(p)  ((p) == (char *)NULL || *(p) == '\0')
  196. #define NULCHARP(p)  ((p) == (char *)NULL)
  197. #define WHITE(c)     ((c) < 33)
  198. #define BLACK(c)     ((c) > 32)
  199. #define SMALL(c)     ((c) < 32)
  200.  
  201. #define INITOKF      1    /* setup forward parsing */
  202. #define INITOKR     -1    /* setup reverse parsing */
  203. #define ITOKF        2    /* forward parse */
  204. #define ITOKR       -2    /* reverse parse */
  205.  
  206. int  fstat();
  207. int  stat();
  208. char *malloc();
  209. char *calloc();
  210. long lseek();
  211. long time();
  212.  
  213. struct tm *_igetdate();
  214.  
  215. char *ctime();
  216. char *iwhich();
  217. char *getenv();
  218. char *ilast();
  219. char *ianytok();
  220. char *ialntok();
  221. char *ictok();
  222. int  ierror();
  223. int  ifamily();
  224. int  ilongest();
  225. int  itexrect();
  226. int  iread();
  227.  
  228. extern int errno, sys_nerr;
  229. extern char *sys_errlist[];
  230.  
  231. #ifndef IAMIERROR
  232. extern char ierbuf[];
  233. extern int  ierflag;
  234. #endif
  235. //E*O*F i.h//
  236.  
  237. echo x - ilib.h
  238. cat > "ilib.h" << '//E*O*F ilib.h//'
  239. /* ilib.h */
  240. /*********************************************************************
  241. * This is the client's #include file for accessing functions in ilib.a
  242. * Istvan Mohos, 1987 --- in the Public Domain
  243. **********************************************************************/
  244.  
  245. /* functions archived in ilib.a: */
  246. char * ialntok();
  247. char * ianymatch();
  248. char * ianytok();
  249. int    ibcmp();
  250. void   ibcopy();
  251. void   iblank();
  252. int    ibreakl();
  253. char * ictok();
  254. char * icopy();
  255. int    icount();
  256. void   icue();
  257. int    idamage();
  258. char * idate();
  259. void   idump();
  260. int    iego();
  261. int    ierror();
  262. int    iexpect();
  263. int    ifamily();
  264. int    ifilter();
  265. int    igroup();
  266. int    ihash();
  267. int    ihasharg();
  268. char * ihms();
  269. int    iinput();
  270. char * ilast();
  271. int    iline();
  272. int    ilist();
  273. int    ilistn();
  274. int    illistn();
  275. int    ilongest();
  276. int    ilower();
  277. char * imatch();
  278. int    imode();
  279. int    imonth();
  280. int    inest();
  281. char * inl();
  282. char * inull();
  283. int    inumsearch();
  284. void   inumsort();
  285. int    inumstrcmp();
  286. char * inextl();
  287. int    ioctal();
  288. int    iopt();
  289. int    iread();
  290. int    irotate();
  291. int    iround();
  292. int    isearch();
  293. void   isort();
  294. char * istartl();
  295. int    istripcom();
  296. int    istripdq();
  297. int    istripsq();
  298. int    istripstr();
  299. int    iswap();
  300. int    itexrect();
  301. int    itoday();
  302. int    itohour();
  303. int    itok();
  304. int    itomin();
  305. int    itomonth();
  306. int    itosec();
  307. int    itoyear();
  308. int    itran();
  309. void   itwin();
  310. int    iuniq();
  311. int    iuniqa();
  312. int    iupper();
  313. char * iwhich();
  314. int    iwrite();
  315. int    iwritopn();
  316. char * ixmatch();
  317. int    ixsearch();
  318. int    ixswap();
  319.  
  320. char * malloc();
  321. char * calloc();
  322. long   lseek();
  323.  
  324. #include <stdio.h>
  325. #ifndef X_OK
  326. #    ifdef REALUNIX
  327. #        define F_OK 0
  328. #        define X_OK 1
  329. #        define W_OK 2
  330. #        define R_OK 4
  331. #        include <fcntl.h>
  332. #    else
  333. #        include <sys/file.h>
  334. #    endif
  335. #endif
  336.  
  337. extern char ierbuf[];
  338. extern int  ierflag;
  339.  
  340. /* imode symbolic constants, modeled after stat.h list */
  341. #define ISSOCK   0140000   /* socket */
  342. #define ISLNK    0120000   /* symbolic link */
  343. #define ISREG    0100000   /* regular */
  344. #define ISBLK    0060000   /* block special */
  345. #define ISDIR    0040000   /* directory */
  346. #define ISCHR    0020000   /* character special */
  347. #define ISFIFO   0010000   /* named pipe */
  348. #define ISUID    0004000   /* set uid on execution */
  349. #define ISGID    0002000   /* set gid on execution */
  350. #define ISSTICK  0001000   /* keep text in memory (sticky bit) */
  351. #define ISROWN   0000400   /* read, owner */
  352. #define ISWOWN   0000200   /* write, owner */
  353. #define ISXOWN   0000100   /* execute/search, owner */
  354. #define ISRGRP   0000040   /* read, group */
  355. #define ISWGRP   0000020   /* write, group */
  356. #define ISXGRP   0000010   /* execute/search, group */
  357. #define ISRALL   0000004   /* read, others */
  358. #define ISWALL   0000002   /* write, others */
  359. #define ISXALL   0000001   /* execute/search, others */
  360.  
  361. #define INITOKF       1    /* setup forward parsing */
  362. #define INITOKR      -1    /* setup reverse parsing */
  363. #define ITOKF         2    /* forward parse */
  364. #define ITOKR        -2    /* reverse parse */
  365.  
  366. #define DOUNCOUN(x,y) (y) = (x); --(y) >= 0
  367. #define BADCHARP(p)   ((p) == (char *)NULL || *(p) == '\0')
  368. #define NULCHARP(p)   ((p) == (char *)NULL)
  369. #define ZPT           (char *)NULL
  370.  
  371. #define IANYTOK       0
  372. #define IALNTOK       1
  373. #define ICTOK         2
  374.  
  375. #define SPACE_LINE   -1
  376. #define LINE_ONLY     0
  377. #define LINE_SPACE    1
  378.  
  379. #define IROTR         1 /* rotate 90 deg. to right */
  380. #define IROTL        -1 /* rotate 90 deg. to left */
  381. #define IROTOR        3 /* rotate 180 deg. over and 90 deg. to right */
  382. #define IROTOL       -3 /* rotate 180 deg. over and 90 deg. to left */
  383.  
  384. #define SHORTMO       0 /* idate format: Jun 23 1988 */
  385. #define SHORTUPMO     1 /* idate format: JUN 23 1988 */
  386. #define LONGMO        2 /* idate format: June 23, 1988 */
  387. #define LONGUPMO      3 /* idate format: JUNE 23, 1988 */
  388.  
  389. #define WHITE(c)      ((c) < 33)
  390. #define BLACK(c)      ((c) > 32)
  391. #define TONEXWHITE(p) while (*(p) && (*(p)>32)) (p)++
  392. #define TONEXBLACK(p) while (*(p) && (*(p)<33)) (p)++
  393.  
  394. #define IFOURK        4096
  395. #define ITWOK         2048
  396. #define IONEK         1024
  397. #define IHALFK        512
  398. #define IQUARTK       256
  399. //E*O*F ilib.h//
  400.  
  401. echo x - goaway.c
  402. cat > "goaway.c" << '//E*O*F goaway.c//'
  403. /* goaway.c */
  404.  
  405. #include "globals.h"
  406.  
  407. goaway ()
  408. {
  409.     signal(SIGINT, SIG_IGN);
  410.     signal(SIGHUP, SIG_IGN);
  411.     signal(SIGTERM, SIG_IGN);
  412.     signal(SIGQUIT, SIG_IGN);
  413.  
  414.     unlink (Tiles);
  415.     unlink (Listfile);
  416.     if (*Msg)
  417.         fprintf(stderr, "%s\n", Msg), exit (1);
  418.  
  419.     exit (0);
  420. }
  421.  
  422. //E*O*F goaway.c//
  423.  
  424. echo x - iego.c
  425. cat > "iego.c" << '//E*O*F iego.c//'
  426. /* iego.c */
  427. /*******************************************************
  428. * return file name in buf without path or .ext component
  429. * Istvan Mohos, 1987 --- in the Public Domain
  430. *******************************************************/
  431.  
  432. #include "i.h"
  433.  
  434. int
  435. iego (ptr, wbuf, delim, ext)
  436. char *ptr, *wbuf, delim, ext;
  437. {
  438.     char *fr, *to, *mark;
  439.  
  440.     if (BADCHARP(ptr))
  441.         return (ierror ("iego: invalid name pointer"));
  442.     if (delim == 0)
  443.         delim = '/';
  444.  
  445.     to = wbuf;
  446.     *to = '\0';
  447.     for (fr = ptr; *fr++;);
  448.     for (--fr; --fr > ptr;) {
  449.         if (*fr == delim) {
  450.             ++fr;
  451.             break;
  452.         }
  453.     }
  454.     if (*fr == delim)
  455.         ++fr;
  456.     
  457.     if (ext == 0)
  458.         for (mark = ptr; mark < fr; *to++ = *mark++);
  459.     else
  460.         for (;*fr && *fr != ext;)
  461.             *to++ = *fr++;
  462.     *to = '\0';
  463.  
  464.     return (strlen (wbuf));
  465. }
  466. //E*O*F iego.c//
  467.  
  468. echo x - ierror.c
  469. cat > "ierror.c" << '//E*O*F ierror.c//'
  470. /* ierror.c */
  471. /****************************************
  472. * report error via "ierbuf" and "ierflag"
  473. * Istvan Mohos, 1987 --- in the Public Domain
  474. ****************************************/
  475.  
  476. #define IAMIERROR
  477. #include "i.h"
  478.  
  479. char ierbuf[IHALFK];
  480. int  ierflag;
  481.  
  482. int
  483. ierror (ustr)
  484. char *ustr;
  485. {
  486.     if (errno > 0 && errno < sys_nerr) { /* system error */
  487.         ierflag = -errno;
  488.         if (NULCHARP (ustr))
  489.             strcpy(ierbuf, sys_errlist[errno]);
  490.         else
  491.             sprintf(ierbuf, "%s --- %.*s", sys_errlist[errno],
  492.                 IHALFK - strlen (sys_errlist[errno]) - 6, ustr);
  493.         errno = 0;
  494.         return (ierflag);
  495.     }
  496.  
  497.     ierflag = -sys_nerr; /* user error */
  498.     if (NULCHARP (ustr))
  499.         strcpy (ierbuf, "Error");
  500.     else
  501.         strncpy (ierbuf, ustr, IHALFK-1);
  502.     errno = 0;
  503.     return (ierflag);
  504. }
  505. //E*O*F ierror.c//
  506.  
  507. echo x - illistn.c
  508. cat > "illistn.c" << '//E*O*F illistn.c//'
  509. /* illistn.c */
  510. /********************************************
  511. * create array of pointers to lines in buffer
  512. * Istvan Mohos, 1987 --- in the Public Domain
  513. *********************************************/
  514.  
  515. #include "i.h"
  516.  
  517. int
  518. illistn (start, end, ptrlist)
  519. char *start;
  520. char *end;
  521. char **ptrlist;
  522. {
  523.     int ri;
  524.     char *rp;
  525.     char *savp, **work;
  526.  
  527.     if (end <= start || NULCHARP (start))
  528.         return (ierror ("illistn: zero-size or invalid buffer"));
  529.     *(end -1) = '\n'; /* just in case */
  530.     for (ri = 0, rp = end; --rp >= start;)
  531.         if (*rp == '\n')
  532.             ++ri;
  533.  
  534.     if (NULCHARP(savp=malloc((unsigned int)(ri*sizeof(char *)))))
  535.         return(ierror("illistn: can't allocate pointer array"));
  536.  
  537.     /* start one character to left of last byte in buffer */
  538.     *(end -1) = 0;
  539.     for (work=(char **)savp+ri, rp=end-1; --rp >= start;)
  540.         if (*rp == '\n')
  541.             *rp = 0, *--work = rp+1;
  542.  
  543.     /* rp == start-1 */
  544.     *--work = ++rp;
  545.  
  546.     *ptrlist = savp;
  547.     return(ri);
  548. }
  549. //E*O*F illistn.c//
  550.  
  551. echo x - init.c
  552. cat > "init.c" << '//E*O*F init.c//'
  553. /* init.c */
  554.  
  555. #include "globals.h"
  556.  
  557. init ()
  558. {
  559.     char  *mktemp();
  560.     struct tile *tp;
  561.  
  562.     /******************
  563.      *                *
  564.      *                *
  565.      *                *
  566.      ******************/
  567.     tp = &Blank;
  568.     strcpy (tp->line1, "                ");
  569.     strcpy (tp->line2, "                ");
  570.     strcpy (tp->line3, "                ");
  571.  
  572.  
  573.     /******************
  574.      *string1         *
  575.      *                *
  576.      *                *
  577.      ******************/
  578.     tp = &Single;
  579.     strcpy (tp->line2, "                ");
  580.     strcpy (tp->line3, "                ");
  581.  
  582.  
  583.     /******************
  584.      *string1         *
  585.      *string2         *
  586.      *                *
  587.      ******************/
  588.     tp = &Double;
  589.     strcpy (tp->line3, "                ");
  590.  
  591.  
  592.     /******************
  593.      *string1         *
  594.      *string2         *     Triple
  595.      *string3         *
  596.      ******************/
  597.  
  598.  
  599.     /******************
  600.      *  |             *
  601.      *string1         *
  602.      *string2         *
  603.      ******************/
  604.     tp = &Leaf;
  605.     strcpy (tp->line1, "  |             ");
  606.  
  607.  
  608.     /******************
  609.      *  |             *
  610.      *string1         *
  611.      *                *
  612.      ******************/
  613.     tp = &Bud;
  614.     strcpy (tp->line1, "  |             ");
  615.     strcpy (tp->line3, "                ");
  616.  
  617.  
  618.     /******************
  619.      *  |             *
  620.      *string1         *
  621.      *  |             *
  622.      ******************/
  623.     tp = &Joint;
  624.     strcpy (tp->line1, "  |             ");
  625.     strcpy (tp->line3, "  |             ");
  626.  
  627.  
  628.     /******************
  629.      *  |             *
  630.      *string1~~~~~~~~~*
  631.      *  |             *
  632.      ******************/
  633.     tp = &Twig;
  634.     strcpy (tp->line1, "  |             ");
  635.     strcpy (tp->line3, "  |             ");
  636.  
  637.  
  638.     /******************
  639.      *                *
  640.      *~~~~~~~~~~~~~~~~*
  641.      *                *
  642.      ******************/
  643.     tp = &Span;
  644.     strcpy (tp->line1, "                ");
  645.     strcpy (tp->line2, "~~~~~~~~~~~~~~~~");
  646.     strcpy (tp->line3, "                ");
  647.  
  648.  
  649.     /******************
  650.      *                *
  651.      *~~~~~~~~~~~~~~~~*
  652.      *  |             *
  653.      ******************/
  654.     tp = &Tap;
  655.     strcpy (tp->line1, "                ");
  656.     strcpy (tp->line2, "~~~~~~~~~~~~~~~~");
  657.     strcpy (tp->line3, "  |             ");
  658.  
  659.  
  660.     /******************
  661.      *                *
  662.      *~~>             *
  663.      *  |             *
  664.      ******************/
  665.     tp = &Tip;
  666.     strcpy (tp->line1, "                ");
  667.     strcpy (tp->line2, "~~>             ");
  668.     strcpy (tp->line3, "  |             ");
  669.  
  670.  
  671.     strcpy (Tiles, "/tmp/");
  672.     strcat (Tiles, mktemp ("treeDTXXXXXX"));
  673.     if ((Td = open (Tiles, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1)
  674.         fprintf (stderr, "can't write to %s\n", Tiles), exit (1);
  675.  
  676.     strcpy (Listfile, "/tmp/");
  677.     strcat (Listfile, mktemp ("treeDLXXXXXX"));
  678.  
  679.     if (signal(SIGHUP, SIG_IGN) == SIG_DFL)
  680.         signal(SIGHUP, goaway);
  681.     if (signal(SIGINT, SIG_IGN) == SIG_DFL)
  682.         signal(SIGINT, goaway);
  683.     if (signal(SIGTERM, SIG_IGN) == SIG_DFL)
  684.         signal(SIGTERM, goaway);
  685.     if (signal(SIGQUIT, SIG_IGN) == SIG_DFL)
  686.         signal(SIGQUIT, goaway);
  687.  
  688.     Widemod = (Wid-3)/16;
  689.     Deepmod = (Lin-3)/3;
  690. }
  691. //E*O*F init.c//
  692.  
  693. echo x - iopt.c
  694. cat > "iopt.c" << '//E*O*F iopt.c//'
  695. /* iopt.c */
  696. /*********************************************
  697. * command line option manager
  698. * Istvan Mohos, 1987 --- in the Public Domain
  699. *********************************************/
  700.  
  701. #include "i.h"
  702.  
  703. int
  704. iopt (ptr)
  705. char ***ptr;
  706. {
  707.     char *rp;
  708.     static char **olist;
  709.     static int first = 1;
  710.     int optlen;
  711.  
  712.     if (first) {
  713.         olist = *ptr;
  714.         first = 0;
  715.     }
  716.  
  717.     rp = *olist;
  718.     if (rp == NULL || *rp != '-') { /* no more options */
  719.         *ptr = olist;               /* set to first non-option */
  720.         first = 1;                  /* automatically re-init */
  721.         return (0);
  722.     }
  723.  
  724.     optlen = strlen (rp);
  725.     if (optlen > 2) {               /* flag, value combined */
  726.         rp += 2;
  727.         *olist = rp;                /* right past '-c' flag */
  728.         *ptr = olist;
  729.         ++olist;                    /* pre-increment for next time */
  730.         return (*--rp);
  731.     }
  732.  
  733.     if (optlen == 1) {              /* '-' by itself */
  734.         *ptr = olist;
  735.         ++olist;                    /* pre-increment for next time */
  736.         return (*rp);
  737.     }
  738.  
  739.     /* else (optlen == 2): normal '-c' flag */
  740.     ++rp;
  741.     ++olist;
  742.     if (*olist == NULL || **olist == 0) { /* no option value */
  743.         --olist;
  744.         *ptr = olist;               /* cough up entire option flag */
  745.         first = 1;                  /* automatically re-init */
  746.         return (0);
  747.     }
  748.  
  749.     *ptr = olist;
  750.     ++olist;                        /* pre-increment for next time */
  751.     return (*rp);
  752. }
  753. //E*O*F iopt.c//
  754.  
  755. echo x - iread.c
  756. cat > "iread.c" << '//E*O*F iread.c//'
  757. /* iread.c */
  758. /*************************************************
  759. * read file into malloc'd buffer, return file size
  760. * Istvan Mohos, 1987 --- in the Public Domain
  761. **************************************************/
  762.  
  763. #include "i.h"
  764.  
  765. int
  766. iread (fname, mallocp)
  767. char *fname;
  768. char **mallocp;
  769. {
  770.     struct stat sbuf;
  771.     int checkval, fd;
  772.     int count;
  773.  
  774.     if (BADCHARP (fname))
  775.         return (ierror ("iread: invalid file name"));
  776.  
  777.     if (mallocp == (char **) NULL) {
  778.         if (access (fname, R_OK) == -1)
  779.             return (-1); /* can't read it */
  780.         return (0);
  781.     }
  782.  
  783.     if ((fd = open (fname, 0)) == -1)
  784.         return (ierror ("iread: no file access"));
  785.         
  786.     if ((checkval = fstat (fd, &sbuf)) == -1)
  787.         return (ierror ("iread: fstat read error"));
  788.  
  789.     if ((count = (int)sbuf.st_size) == 0)
  790.         return (ierror ("iread: zero length file"));
  791.  
  792.     if (NULCHARP (*mallocp = malloc ((unsigned int) count+1)))
  793.         return (ierror ("iread: can't allocate read buffer"));
  794.  
  795.     if ((checkval = read (fd, *mallocp, count)) != count) {
  796.         sprintf (ierbuf+200,
  797.             "iread: expected: %d, read: %d", count, checkval);
  798.         return (ierror (ierbuf+200));
  799.     }
  800.     close (fd);
  801.     *(*mallocp + count) = 0;
  802.     return (checkval);
  803. }
  804. //E*O*F iread.c//
  805.  
  806. echo x - listfiles.c
  807. cat > "listfiles.c" << '//E*O*F listfiles.c//'
  808. /* listfiles.c */
  809.  
  810. #include "globals.h"
  811.  
  812. listfiles (ptr, ptrcount, fcount)
  813. char **ptr;
  814. int ptrcount, fcount;
  815. {
  816.     int fdeep;
  817.     int maxpgdeep;
  818.     int qi;
  819.     char *s1, *s2, *s3;
  820.     static char *more = "--- more ---";
  821.  
  822.     if ((fdeep = Ty + 1) > Deepest)
  823.         Deepest = fdeep;
  824.  
  825.     if (Fstop) {
  826.         maxpgdeep = Deepest / Deepmod +1; /* 1, 2... */
  827.         if (maxpgdeep < Fstop)
  828.             maxpgdeep = Fstop;
  829.     }
  830.  
  831.     /* list files only, skip directories; null out file names */
  832.     if (fcount == 1) {
  833.         for (DOUNCOUN (ptrcount, qi); ptr++) {
  834.             if (*(*ptr + strlen (*ptr) -1) != '/') {
  835.                 tile (fdeep, BUD, 0, *ptr, ZERO, ZERO);
  836.                 **ptr = 0;
  837.                 return;
  838.             }
  839.         }
  840.     }
  841.  
  842.     qi = ptrcount;
  843.     while (qi--) {
  844.         if (*(*ptr + strlen (*ptr) -1) != '/') {
  845.             --fcount;
  846.             s1 = *ptr;
  847.             ptr++;
  848.             break;
  849.         }
  850.         ptr++;
  851.     }
  852.     while (qi--) {
  853.         if (*(*ptr + strlen (*ptr) -1) != '/') {
  854.             --fcount;
  855.             if (Fstop && fcount && ((fdeep+1)/Deepmod >= maxpgdeep)) {
  856.                 s2 = more;
  857.                 tile (fdeep, LEAF, 0, s1, s2, ZERO);
  858.                 *s1 = 0;
  859.                 **ptr = 0;
  860.                 while (qi--) {
  861.                     ++ptr;
  862.                     if (*(*ptr + strlen (*ptr) -1) != '/')
  863.                         **ptr = 0;
  864.                 }
  865.                 return;
  866.             }
  867.             s2 = *ptr;
  868.             ptr++;
  869.             break;
  870.         }
  871.         ptr++;
  872.     }
  873.     tile (fdeep, LEAF, 0, s1, s2, ZERO);
  874.     *s1 = *s2 = 0;
  875.  
  876.     while (fcount >= 3) {
  877.         if (++fdeep > Deepest)
  878.             Deepest = fdeep;
  879.         while (qi--) {
  880.             if (*(*ptr + strlen (*ptr) -1) != '/') {
  881.                 --fcount;
  882.                 s1 = *ptr;
  883.                 ptr++;
  884.                 break;
  885.             }
  886.             ptr++;
  887.         }
  888.         while (qi--) {
  889.             if (*(*ptr + strlen (*ptr) -1) != '/') {
  890.                 --fcount;
  891.                 s2 = *ptr;
  892.                 ptr++;
  893.                 break;
  894.             }
  895.             ptr++;
  896.         }
  897.         while (qi--) {
  898.             if (*(*ptr + strlen (*ptr) -1) != '/') {
  899.                 --fcount;
  900.                 if (Fstop && fcount && ((fdeep+1)/Deepmod >= maxpgdeep)) {
  901.                     s3 = more;
  902.                     tile (fdeep, TRIPLE, 0, s1, s2, s3);
  903.                     *s1 = *s2 = 0;
  904.                     **ptr = 0;
  905.                     while (qi--) {
  906.                         ++ptr;
  907.                         if (*(*ptr + strlen (*ptr) -1) != '/')
  908.                             **ptr = 0;
  909.                     }
  910.                     return;
  911.                 }
  912.                 s3 = *ptr;
  913.                 ptr++;
  914.                 break;
  915.             }
  916.             ptr++;
  917.         }
  918.         tile (fdeep, TRIPLE, 0, s1, s2, s3);
  919.         *s1 = *s2 = *s3 = 0;
  920.     }
  921.     if (fcount == 2) {
  922.         if (++fdeep > Deepest)
  923.             Deepest = fdeep;
  924.         while (qi--) {
  925.             if (*(*ptr + strlen (*ptr) -1) != '/') {
  926.                 --fcount;
  927.                 s1 = *ptr;
  928.                 ptr++;
  929.                 break;
  930.             }
  931.             ptr++;
  932.         }
  933.         while (qi--) {
  934.             if (*(*ptr + strlen (*ptr) -1) != '/') {
  935.                 --fcount;
  936.                 s2 = *ptr;
  937.                 ptr++;
  938.                 break;
  939.             }
  940.             ptr++;
  941.         }
  942.         tile (fdeep, DOUBLE, 0, s1, s2, ZERO);
  943.         *s1 = *s2 = 0;
  944.     }
  945.     else if (fcount == 1) {
  946.         if (++fdeep > Deepest)
  947.             Deepest = fdeep;
  948.         while (qi--) {
  949.             if (*(*ptr + strlen (*ptr) -1) != '/') {
  950.                 --fcount;
  951.                 s1 = *ptr;
  952.                 ptr++;
  953.                 break;
  954.             }
  955.             ptr++;
  956.         }
  957.         tile (fdeep, SINGLE, 0, s1, ZERO, ZERO);
  958.         *s1 = 0;
  959.     }
  960. }
  961. //E*O*F listfiles.c//
  962.  
  963. echo x - mapper.c
  964. cat > "mapper.c" << '//E*O*F mapper.c//'
  965. /* mapper.c */
  966.  
  967. #include "globals.h"
  968.  
  969. extern int errno;
  970.  
  971. mapper (dirname)
  972. char *dirname;
  973. {
  974.     char dirego[IQUARTK];
  975.     char cmd[IHALFK];
  976.     char newpath[IONEK];
  977.     char *pathptr;
  978.     char *filebuf;
  979.     char *fileend;
  980.     char *ptrbuf;
  981.     char **ptr;
  982.     int  ccount;
  983.     int  fcount;
  984.     int  dcount;
  985.     int  ptrcount;
  986.     int  qi;
  987.     int  flush;
  988.  
  989.     if (++Ty > Deepest)
  990.         Deepest = Ty;
  991.     sprintf (cmd, "/bin/ls -aFq %s > %s",dirname, Listfile);
  992.     errno = 0;
  993.     system (cmd);
  994.     if (errno)
  995.         BAILOUT;
  996.  
  997.     iego (dirname, dirego, '/', '/');
  998.  
  999.     if ((ccount = iread (Listfile, &filebuf)) < 1)
  1000.         goaway();
  1001.     fileend = filebuf + ccount;
  1002.     if ((ptrcount = illistn (filebuf, fileend, &ptrbuf)) < 1)
  1003.         BAILOUT;
  1004.  
  1005.     /* count files and directories */
  1006.     ptr = (char **)ptrbuf;
  1007.     for (dcount = fcount = 0, DOUNCOUN (ptrcount, qi); ptr++)
  1008.         (*(*ptr + strlen (*ptr) -1) == '/') ? ++dcount : ++fcount;
  1009.  
  1010.     if (dcount < 2) {
  1011.         strcat (dirego, "!");
  1012.         tile (Ty, BUD, 0, dirego, ZERO, ZERO);
  1013.         free (filebuf);
  1014.         return;
  1015.     }
  1016.  
  1017.     if (dcount == 2 && !fcount) {
  1018.         strcat (dirego, "/");
  1019.         tile (Ty, BUD, 0, dirego, ZERO, ZERO);
  1020.         free (filebuf);
  1021.         return;
  1022.     }
  1023.  
  1024.     /* At this point, the next tile is a Twig if dirname contains
  1025.        both files and directories, or no files and multiple dirs.
  1026.        The next tile is a Joint if dirname contains files only, or
  1027.        a single directory.
  1028.     */
  1029.     if (dcount == 2) {
  1030.         strcat (dirego, "/");
  1031.         tile (Ty, JOINT, 0, dirego, ZERO, ZERO);
  1032.         ptr = (char **)ptrbuf;
  1033.         listfiles (ptr, ptrcount, fcount);
  1034.         free (filebuf);
  1035.         return;
  1036.     }
  1037.     if (dcount == 3 && !fcount) {
  1038.         strcat (dirego, "/");
  1039.         tile (Ty, JOINT, 0, dirego, ZERO, ZERO);
  1040.         strcpy (newpath, dirname);
  1041.         pathptr = newpath + strlen (newpath);
  1042.         *pathptr++ = '/';
  1043.         ptr = (char **)ptrbuf;
  1044.         for (DOUNCOUN (ptrcount, qi); ptr++) {
  1045.             if (strcmp (*ptr, "./") && strcmp (*ptr, "../")) {
  1046.                 if (!Depth || Ty < (Depth-1)) {
  1047.                     *(*ptr + strlen (*ptr) -1) = 0;
  1048.                     strcpy (pathptr, *ptr);
  1049.                     mapper (newpath);
  1050.                     Ty--;
  1051.                 }
  1052.                 else {
  1053.                     *(*ptr + strlen (*ptr) -1) = '!';
  1054.                     tile (Ty+1, BUD, 0, *ptr, ZERO, ZERO);
  1055.                     if (Ty+1 > Deepest)
  1056.                         Deepest = Ty+1;
  1057.                 }
  1058.                 free (filebuf);
  1059.                 return;
  1060.             }
  1061.         }
  1062.     }
  1063.     if (fcount) { /* and dcount > 2 */
  1064.         strcat (dirego, "/");
  1065.         tile (Ty, TWIG, dcount-2, dirego, ZERO, ZERO);
  1066.         ptr = (char **)ptrbuf;
  1067.         listfiles (ptr, ptrcount, fcount);
  1068.  
  1069.         strcpy (newpath, dirname);
  1070.         pathptr = newpath + strlen (newpath);
  1071.         *pathptr++ = '/';
  1072.         ptr = (char **)ptrbuf;
  1073.         for (DOUNCOUN (ptrcount, qi); ptr++) {
  1074.             if (**ptr) { /* not a file */
  1075.                 if (strcmp (*ptr, "./") && strcmp (*ptr, "../")) {
  1076.                     ++Tx;
  1077.                     if (!Depth || Ty < (Depth-1)) {
  1078.                         *(*ptr + strlen (*ptr) -1) = 0;
  1079.                         strcpy (pathptr, *ptr);
  1080.                         mapper (newpath);
  1081.                         Ty--;
  1082.                     }
  1083.                     else {
  1084.                         *(*ptr + strlen (*ptr) -1) = '!';
  1085.                         tile (Ty+1, BUD, 0, *ptr, ZERO, ZERO);
  1086.                         if (Ty+1 > Deepest)
  1087.                             Deepest = Ty+1;
  1088.                     }
  1089.                 }
  1090.             }
  1091.         }
  1092.         free (filebuf);
  1093.         return;
  1094.     }
  1095.  
  1096.     /* no files, multiple dirs */
  1097.     strcat (dirego, "/");
  1098.     tile (Ty, TWIG, dcount-3, dirego, ZERO, ZERO);
  1099.  
  1100.     flush = 1;
  1101.     strcpy (newpath, dirname);
  1102.     pathptr = newpath + strlen (newpath);
  1103.     *pathptr++ = '/';
  1104.     ptr = (char **)ptrbuf;
  1105.     for (DOUNCOUN (ptrcount, qi); ptr++) {
  1106.         if (strcmp (*ptr, "./") && strcmp (*ptr, "../")) {
  1107.             flush ? (flush = 0) : ++Tx;
  1108.             if (!Depth || Ty < (Depth-1)) {
  1109.                 *(*ptr + strlen (*ptr) -1) = 0;
  1110.                 strcpy (pathptr, *ptr);
  1111.                 mapper (newpath);
  1112.                 Ty--;
  1113.             }
  1114.             else {
  1115.                 *(*ptr + strlen (*ptr) -1) = '!';
  1116.                 tile (Ty+1, BUD, 0, *ptr, ZERO, ZERO);
  1117.                 if (Ty+1 > Deepest)
  1118.                     Deepest = Ty+1;
  1119.             }
  1120.         }
  1121.     }
  1122.     free (filebuf);
  1123.     return;
  1124. }
  1125.  
  1126. //E*O*F mapper.c//
  1127.  
  1128. echo x - package.c
  1129. cat > "package.c" << '//E*O*F package.c//'
  1130. /* package.c */
  1131.  
  1132. #include "globals.h"
  1133.  
  1134. package ()
  1135. {
  1136.     char *buf;
  1137.     struct tile *tp;
  1138.     struct tile **tmp;
  1139.     int tcount;
  1140.     int linkc;
  1141.     int depth = Deepest +1;
  1142.     int qi, qj;
  1143.  
  1144.     close (Td);
  1145.     if ((tcount = iread (Tiles, &buf)) < 1)
  1146.         BAILOUT;
  1147.     tcount /= TSIZ;
  1148.  
  1149.     Mcount = depth * (Tx+1);
  1150.     if ((Mp = (struct tile **)malloc (Mcount * sizeof (struct tile **)))
  1151.     == (struct tile **) NULL)
  1152.         BAILOUT;
  1153.  
  1154.     /* init all locations to Blank */
  1155.     for (tmp = Mp, DOUNCOUN (Mcount, qi); tmp++)
  1156.         *tmp = &Blank;
  1157.  
  1158.     /* remap tcount tiles in buf into a rectangular array, Y first:
  1159.        line 0:   0,0     /0,1     /0,2
  1160.        line 1:   1,0    / 1,1    / 1,2
  1161.        (6 deep)  2,0   /  2,1   /  2,2
  1162.        line 3:   3,0  /   3,1  /   3,2
  1163.        line 4:   4,0 /    4,1 /    4,2
  1164.        Deepest:  5,0/     5,1/     5,2
  1165.     */
  1166.     tp = (struct tile *)buf;
  1167.     for (DOUNCOUN (tcount, qi); tp++)
  1168.         Mp[tp->hor * depth + tp->ver] = tp;
  1169.  
  1170.     /* blank out leader to first tile (root) only */
  1171.     tp = Mp[0];
  1172.     strcpy (tp->line1, "                ");
  1173.  
  1174.     /* Find and complete every Twig, line-by-line left-to-right.
  1175.        Do not look for Twig in bottom line or at right edge.
  1176.        To right of each Twig, substitute Twig->linkc number of Blank
  1177.        tiles with Tap tiles (or Tip at the terminal tile).
  1178.        Tap or Tip tiles must be installed directly above non-blank
  1179.        tiles only: if next horizontal position is located above a Blank,
  1180.        a Span tile is laid instead.
  1181.     */
  1182.     for (qi = 0; qi < Deepest; qi++) {              /* Y loop */
  1183.         for (qj = 0; qj < Tx; qj++) {               /* X loop */
  1184.             if (linkc = (Mp[qj*depth+qi])->linkc) { /* a Twig? */
  1185.                 ++qj;                               /* next hor. tile */
  1186.                 for (--linkc; linkc; qj++) {        /* not incl. Tip */
  1187.                     if (Mp[qj*depth+qi+1] == &Blank) {
  1188.                         Mp[qj*depth+qi] = &Span;
  1189.                         continue;
  1190.                     }
  1191.                     Mp[qj*depth+qi] = &Tap;
  1192.                     linkc--;
  1193.                 }
  1194.                 while (Mp[qj*depth+qi+1] == &Blank) {
  1195.                     Mp[qj*depth+qi] = &Span;
  1196.                     qj++;
  1197.                 }
  1198.                 Mp[qj*depth+qi] = &Tip;
  1199.             }
  1200.         }
  1201.     }
  1202.  
  1203. /***** To print matrix data:
  1204.     for (tmp = Mp, DOUNCOUN (Mcount, qi); tmp++)
  1205.         printf ("%s]\n%s]\n%s]\n................\n",
  1206.         (*tmp)->line1, (*tmp)->line2, (*tmp)->line3);
  1207. */
  1208.  
  1209. /***** To print file data:
  1210.     tp = (struct tile *)buf;
  1211.     for (qi = tcount; qi--; tp++)
  1212.         printf ("Y:%d X:%d B:%d\n%s]\n%s]\n%s]\n................\n",
  1213.         tp->ver, tp->hor, tp->linkc, tp->line1, tp->line2, tp->line3);
  1214. */
  1215.  
  1216.  
  1217. }
  1218. //E*O*F package.c//
  1219.  
  1220. echo x - split.c
  1221. cat > "split.c" << '//E*O*F split.c//'
  1222. /* split.c */
  1223.  
  1224. #include "globals.h"
  1225.  
  1226. split ()
  1227. {
  1228.     static char alpha[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
  1229.     char   counter[32];        /* horiz. numerical id of page */
  1230.     char   pad[4];             /* 0, 1, or 2 newlines at end of page */
  1231.     char   verid[4];           /* vertical, alpha id of page */
  1232.     char   topline[IONEK];     /* top border of page */
  1233.     char   botline[IONEK];     /* bottom border of page */
  1234.     char   blankline[IONEK];
  1235.     char   strip[3*IONEK];     /* 3 lines: a horiz. strip of tiles */
  1236.     struct tile *tp;
  1237.     char   *s1, *s2, *s3;
  1238.     char   *pp;
  1239.     int    depth = Deepest +1;
  1240.     int    width = Tx +1;
  1241.     int    darktile;           /* any tile except Blank */
  1242.     int    skip = 0;           /* count of blank pages skipped */
  1243.     int    thishor;            /* number of tiles horiz. on this page */
  1244.     int    thisver;            /* number of tiles vert. on this page */
  1245.     int    horpcnt;            /* number of horizontal pages of data */
  1246.     int    verpcnt;            /* number of vertical pages of data */
  1247.     int    padline;            /* pad page at bottom with blank lines */
  1248.     int    realcols;           /* actual number of cols printed/page */
  1249.     int    stripsiz;           /* characters printed per strip */
  1250.     int    qy, qx;
  1251.     int    ty, tx;
  1252.  
  1253.     padline = Lin % 3;
  1254.     horpcnt = Tx/Widemod +1;
  1255.     verpcnt = Deepest/Deepmod +1;
  1256.     realcols = Widemod * 16 +3 +1;  /* newline at end */
  1257.     stripsiz = realcols * 3;
  1258.  
  1259.     fprintf (stderr, "Matrix of %d horizontal %s @ %d %s per list.\n",
  1260.         verpcnt, (verpcnt > 1) ? "lists" : "list",
  1261.         horpcnt, (horpcnt > 1) ? "pages" : "page");
  1262.  
  1263.     pp = topline;
  1264.     *pp++ = SPACE;
  1265.     *pp++ = SPACE;
  1266.     for (DOUNCOUN (realcols-4, qx); *pp++ = ':');
  1267.     *pp = '\n';
  1268.  
  1269.     pp = botline;
  1270.     *pp++ = SPACE;
  1271.     *pp++ = SPACE;
  1272.     for (DOUNCOUN (realcols-4, qx); *pp++ = ';');
  1273.     *pp = '\n';
  1274.  
  1275.     pp = blankline;
  1276.     *pp++ = SPACE;
  1277.     *pp++ = '(';
  1278.     for (DOUNCOUN (realcols-4, qx); *pp++ = SPACE);
  1279.     *pp++ = ')';
  1280.     *pp = '\n';
  1281.  
  1282.     if (padline)
  1283.        strcpy (pad, ((padline == 1) ? "\n" : "\n\n"));
  1284.  
  1285.     /* Output pages with number X coordinates and letter Y coordinates.
  1286.        Output pages in horizontal order first.
  1287.     */
  1288.     for (thisver = Deepmod, qy = 0; qy < verpcnt; qy++) {
  1289.         if (verpcnt < 26) {       /* one-character alpha coordinate */
  1290.             verid[0] = alpha[qy];
  1291.             verid[1] = SPACE;
  1292.             verid[2] = SPACE;
  1293.         }
  1294.         else if (verpcnt < 676) { /* two-character alpha coordinate */
  1295.             ty = qy % 676;        /* a number between 0 and 675 */
  1296.             tx = ty / 26;         /* a number between 0 and 25 */
  1297.             verid[0] = alpha[tx];
  1298.             tx = qy % 26;         /* a number between 0 and 25 */
  1299.             verid[1] = alpha[tx];
  1300.             verid[2] = SPACE;
  1301.         }
  1302.         else {                    /* three-character alpha coordinate */
  1303.             qx = qy % 17576;      /* a number between 0 and 17575 */
  1304.             tx = qx / 676;        /* a number between 0 and 25 */
  1305.             verid[0] = alpha[tx];
  1306.             ty = qx % 676;        /* a number between 0 and 675 */
  1307.             tx = ty / 26;         /* a number between 0 and 25 */
  1308.             verid[1] = alpha[tx];
  1309.             tx = qx % 26;         /* a number between 0 and 25 */
  1310.             verid[2] = alpha[tx];
  1311.         }
  1312.  
  1313.         /* Each horizontal pagelist already output contained
  1314.            width * Deepmod tiles.  When on the last pagelist, the
  1315.            remaining tilecount divided by the width of the tile matrix
  1316.            gives the count of tiles to print vertically.
  1317.         */
  1318.         if (qy+1 == verpcnt)
  1319.             thisver = (Mcount - qy * width * Deepmod) / width;
  1320.  
  1321.         for (thishor = Widemod, qx = 0; qx < horpcnt; qx++) {
  1322.             /* When on the last page of the horizontal pagelist,
  1323.                the number of horizontal tiles to print on the page is
  1324.                width % Widemod (if there is a remainder), or
  1325.                Widemod (if there is no remainder).
  1326.             */
  1327.             if (qx+1 == horpcnt)
  1328.                 if (!(thishor = width % Widemod))
  1329.                     thishor = Widemod;
  1330.  
  1331.             for (darktile = ty = 0; ty < thisver; ty++) {
  1332.                 for (tx = 0; tx < thishor; tx++) {
  1333.                     tp = Mp[qx*depth*Widemod+tx*depth+qy*Deepmod+ty];
  1334.                     if (tp != &Blank)
  1335.                         darktile = 1;
  1336.                     if (darktile)
  1337.                         break;
  1338.                 }
  1339.                 if (darktile)
  1340.                     break;
  1341.             }
  1342.             if (!Printblank && !darktile) {
  1343.                 ++skip;
  1344.                 goto skippage;
  1345.             }
  1346.  
  1347.             sprintf (counter, "  %d\n", qx +1);
  1348.             write (1, counter, strlen (counter));
  1349.             write (1, topline, realcols-1);
  1350.             for (ty = 0; ty < thisver; ty++) {
  1351.                 s1 = strip;
  1352.                 s2 = s1 + realcols;
  1353.                 s3 = s2 + realcols;
  1354.                 if (ty == 0) {
  1355.                     *s1++ = verid[0];
  1356.                     *s2++ = verid[1];
  1357.                     *s3++ = verid[2];
  1358.                 }
  1359.                 else {
  1360.                     *s1++ = SPACE;
  1361.                     *s2++ = SPACE;
  1362.                     *s3++ = SPACE;
  1363.                 }
  1364.                 *s1++ = '(';
  1365.                 *s2++ = '(';
  1366.                 *s3++ = '(';
  1367.                 for (tx = 0; tx < thishor; tx++) {
  1368.                     /* Each previous column (qx) of pages advanced the
  1369.                        Mp index of the current tile column by
  1370.                        depth * Widemod.  Each previous tile column on
  1371.                        this page advanced the Mp index by depth.  The
  1372.                        current pointer is the offset from the current
  1373.                        tile column start, by the current depth.
  1374.                     */
  1375.                     tp = Mp[qx*depth*Widemod+tx*depth+qy*Deepmod+ty];
  1376.                     strcpy (s1, tp->line1);
  1377.                     s1 += 16;
  1378.                     strcpy (s2, tp->line2);
  1379.                     s2 += 16;
  1380.                     strcpy (s3, tp->line3);
  1381.                     s3 += 16;
  1382.                 }
  1383.                 if (thishor < Widemod) {
  1384.                     for  (tp = &Blank; tx < Widemod; tx++) {
  1385.                         strcpy (s1, tp->line1);
  1386.                         s1 += 16;
  1387.                         strcpy (s2, tp->line2);
  1388.                         s2 += 16;
  1389.                         strcpy (s3, tp->line3);
  1390.                         s3 += 16;
  1391.                     }
  1392.                 }
  1393.                 *s1++ = ')';
  1394.                 *s2++ = ')';
  1395.                 *s3++ = ')';
  1396.                 *s1 = '\n';
  1397.                 *s2 = '\n';
  1398.                 *s3 = '\n';
  1399.                 write (1, strip, stripsiz);
  1400.             }
  1401.             if (thisver < Deepmod)
  1402.                 for (ty = 3 * (Deepmod-thisver); ty; ty--)
  1403.                     write (1, blankline, realcols);
  1404.  
  1405.             write (1, botline, realcols-1);
  1406.             if (padline)
  1407.                 write (1, pad, padline);
  1408. skippage:;
  1409.         }
  1410.     }
  1411.     if (skip)
  1412.         fprintf (stderr, "Skipped %d blank pages.\n", skip);
  1413. }
  1414. //E*O*F split.c//
  1415.  
  1416. echo x - tile.c
  1417. cat > "tile.c" << '//E*O*F tile.c//'
  1418. /* tile.c */
  1419.  
  1420. #include "globals.h"
  1421.  
  1422. tile (ver, kind, linkc, str1, str2, str3)
  1423. int kind, linkc;
  1424. char *str1, *str2, *str3;
  1425. {
  1426.     char *sp, *lim;
  1427.     struct tile *tp;
  1428.     int q1, q2, q3;
  1429.  
  1430.     if (!NULCHARP (str1) && ((q1 = strlen (str1)) > MAXFN)) {
  1431.         *(str1 + MAXFN -1) = '<';
  1432.         *(str1 + MAXFN) = 0;
  1433.         q1 = MAXFN;
  1434.     }
  1435.     if (!NULCHARP (str2) && ((q2 = strlen (str2)) > MAXFN)) {
  1436.         *(str2 + MAXFN -1) = '<';
  1437.         *(str2 + MAXFN) = 0;
  1438.         q2 = MAXFN;
  1439.     }
  1440.     if (!NULCHARP (str3) && ((q3 = strlen (str3)) > MAXFN)) {
  1441.         *(str3 + MAXFN -1) = '<';
  1442.         *(str3 + MAXFN) = 0;
  1443.         q3 = MAXFN;
  1444.     }
  1445.  
  1446.     switch (kind) {
  1447.         default:
  1448.         case BLANK:
  1449.             tp = &Blank;
  1450.         break;
  1451.  
  1452.         case SINGLE:
  1453.             tp = &Single;
  1454.             strcpy (tp->line1 , str1);
  1455.             lim = tp->line1 + MAXFN +1;
  1456.             sp = tp->line1 + q1;
  1457.             while (sp < lim)
  1458.                 *sp++ = SPACE;
  1459.         break;
  1460.  
  1461.         case DOUBLE:
  1462.             tp = &Double;
  1463.             strcpy (tp->line1 , str1);
  1464.             lim = tp->line1 + MAXFN +1;
  1465.             sp = tp->line1 + q1;
  1466.             while (sp < lim)
  1467.                 *sp++ = SPACE;
  1468.             strcpy (tp->line2 , str2);
  1469.             lim = tp->line2 + MAXFN +1;
  1470.             sp = tp->line2 + q2;
  1471.             while (sp < lim)
  1472.                 *sp++ = SPACE;
  1473.         break;
  1474.  
  1475.         case TRIPLE:
  1476.             tp = &Triple;
  1477.             strcpy (tp->line1 , str1);
  1478.             lim = tp->line1 + MAXFN +1;
  1479.             sp = tp->line1 + q1;
  1480.             while (sp < lim)
  1481.                 *sp++ = SPACE;
  1482.             strcpy (tp->line2 , str2);
  1483.             lim = tp->line2 + MAXFN +1;
  1484.             sp = tp->line2 + q2;
  1485.             while (sp < lim)
  1486.                 *sp++ = SPACE;
  1487.             strcpy (tp->line3 , str3);
  1488.             lim = tp->line3 + MAXFN +1;
  1489.             sp = tp->line3 + q3;
  1490.             while (sp < lim)
  1491.                 *sp++ = SPACE;
  1492.         break;
  1493.  
  1494.         case LEAF:
  1495.             tp = &Leaf;
  1496.             strcpy (tp->line2 , str1);
  1497.             lim = tp->line2 + MAXFN +1;
  1498.             sp = tp->line2 + q1;
  1499.             while (sp < lim)
  1500.                 *sp++ = SPACE;
  1501.             strcpy (tp->line3 , str2);
  1502.             lim = tp->line3 + MAXFN +1;
  1503.             sp = tp->line3 + q2;
  1504.             while (sp < lim)
  1505.                 *sp++ = SPACE;
  1506.         break;
  1507.  
  1508.         case BUD:
  1509.             tp = &Bud;
  1510.             strcpy (tp->line2 , str1);
  1511.             lim = tp->line2 + MAXFN +1;
  1512.             sp = tp->line2 + q1;
  1513.             while (sp < lim)
  1514.                 *sp++ = SPACE;
  1515.         break;
  1516.  
  1517.         case JOINT:
  1518.             tp = &Joint;
  1519.             strcpy (tp->line2 , str1);
  1520.             lim = tp->line2 + MAXFN +1;
  1521.             sp = tp->line2 + q1;
  1522.             while (sp < lim)
  1523.                 *sp++ = SPACE;
  1524.         break;
  1525.  
  1526.         case TWIG:
  1527.             tp = &Joint;
  1528.             strcpy (tp->line2 , str1);
  1529.             lim = tp->line2 + MAXFN +1;
  1530.             sp = tp->line2 + q1;
  1531.             while (sp < lim)
  1532.                 *sp++ = '~';
  1533.         break;
  1534.     }
  1535.  
  1536.     tp->ver = ver;
  1537.     tp->hor = Tx;
  1538.     tp->linkc = linkc;
  1539.  
  1540.     if (write (Td, tp, TSIZ) != TSIZ)
  1541.          BAILOUT;
  1542. }
  1543. //E*O*F tile.c//
  1544.  
  1545. echo x - treeD.c
  1546. cat > "treeD.c" << '//E*O*F treeD.c//'
  1547. /* treeD.c --- Unix file system diagrammer */
  1548. /******************************
  1549. * Author: Istvan Mohos
  1550. * March 1990
  1551. ******************************/
  1552.  
  1553. #define MAIN
  1554. #include "globals.h"
  1555.  
  1556. main (argc, argv)
  1557. int argc;
  1558. char *argv[];
  1559. {
  1560.     int  optchar;
  1561.     char **opt;
  1562.  
  1563.     if (argc == 1)
  1564. cmderr:
  1565.         fprintf(stderr,
  1566. "Usage: %s [-wN] [-lN] [-dN] [-fN] [-blank] dir\n%s%s%s%s%s", argv[0],
  1567. "\t-w N   maximum printable column width of page (min.19, max.1023)\n",
  1568. "\t-l N   maximum count of lines per page (min.6)\n",
  1569. "\t-d N   limit directory recursion to N depth\n",
  1570. "\t-f N   truncate long file lists beyond the Nth vertical page\n",
  1571. "\t-blank force the printing of blank pages (suppressed by default)\n"),
  1572.         exit(1);
  1573.  
  1574.     opt = &(argv[1]);
  1575.     while (optchar = iopt (&opt)) {
  1576.         switch (optchar) {
  1577.             default:
  1578.                 goto cmderr;
  1579.             case 'w':
  1580.                 if ((Wid = atoi (*opt)) < 19 || Wid > 1023)
  1581.                     fprintf(stderr,
  1582.                     "page width: 19 -- 1023 columns\n"), exit(1);
  1583.                 break;
  1584.             case 'l':
  1585.                 if ((Lin = atoi (*opt)) < 6)
  1586.                     fprintf(stderr,
  1587.                     "page length: minimum 6 lines\n"), exit(1);
  1588.                 break;
  1589.             case 'd':
  1590.                 if ((Depth = atoi (*opt)) < 1)
  1591.                     fprintf(stderr,
  1592.                     "minimum depth: 1 level\n"), exit(1);
  1593.                 break;
  1594.             case 'f':
  1595.                 if ((Fstop = atoi (*opt)) < 1)
  1596.                     fprintf(stderr,
  1597.                     "minimum depth: 1 page\n"), exit(1);
  1598.                 break;
  1599.             case 'b':
  1600.                 Printblank = 1;
  1601.                 break;
  1602.         }
  1603.     }
  1604.  
  1605.     init();
  1606.     mapper (*opt);
  1607.     package();
  1608.     split();
  1609.     goaway();
  1610. }
  1611. //E*O*F treeD.c//
  1612.  
  1613. echo x - makefile
  1614. cat > "makefile" << '//E*O*F makefile//'
  1615. #
  1616. CC=/bin/cc
  1617.  
  1618. # PC6300+ SysV
  1619. #CFLAGS=-O -DREALUNIX -DPLUS6300
  1620.  
  1621. # BSD
  1622. CFLAGS=-O
  1623.  
  1624. #.SILENT:
  1625.  
  1626. IFILES= iopt.o iego.o ierror.o iread.o illistn.o
  1627. FILES= treeD.o init.o tile.o listfiles.o mapper.o package.o goaway.o split.o
  1628.  
  1629. treeD: ${FILES} ${IFILES}
  1630.     $(CC) -o $@ ${FILES} ${IFILES}
  1631.  
  1632. ${IFILES}:i.h
  1633. ${FILES}: globals.h
  1634. //E*O*F makefile//
  1635.  
  1636. echo x - treeX
  1637. cat > "treeX" << '//E*O*F treeX//'
  1638. #!/bin/sh
  1639. # Istvan Mohos, May 1990
  1640. if test $# -eq 0
  1641. then echo "Usage: $0 dirname"
  1642.     exit 1
  1643. fi
  1644. name=`basename $0`
  1645. treeD -l79 -w115 -f1 $* > /tmp/$$.tex
  1646. tail -50 $0 > $name.tex
  1647. echo \\listing\{/tmp/$$.tex\} >> $name.tex
  1648. echo \\bye >> $name.tex
  1649. tex $name.tex
  1650. /bin/rm /tmp/$$.tex
  1651. exit 0
  1652.  
  1653. % TeX input begins here
  1654. \vsize 9.9in
  1655. \hsize 7.5in
  1656. \font\stt=cmtt8
  1657. \raggedbottom \nopagenumbers \stt
  1658. \baselineskip 9pt
  1659. % verbatim macros from Appendix D (pages 381, 391) of The TeXbook
  1660. % redefined ( ) : ; ~ > | for char graphics
  1661. \def\uncatcodespecials{\def\do##1{\catcode`##1=12 }\dospecials}
  1662. \def\setupverbatim{\stt
  1663.   \def\par{\leavevmode\egroup\box0\endgraf}
  1664.   \obeylines \uncatcodespecials \obeyspaces
  1665.   \catcode`\`=\active \catcode`\^^I=\active
  1666.   \catcode`(=\active \catcode`)=\active
  1667.   \catcode`:=\active \catcode`;=\active
  1668.   \catcode`\~=\active \catcode`>=\active \catcode`|=\active
  1669.   \everypar{\startbox}}
  1670. \newdimen\w \setbox0=\hbox{\stt\space} \w=4\wd0 % width of tab
  1671. \def\startbox{\setbox0=\hbox\bgroup}
  1672. {\catcode`\`=\active \gdef`{\relax\lq}}
  1673. {\catcode`\^^I=\active
  1674.   \gdef^^I{\leavevmode\egroup
  1675.     \dimen0=\wd0          % the width so far, or since the previous tab
  1676.     \divide\dimen0 by\w
  1677.     \multiply\dimen0 by\w % compute previous multiple of \w
  1678.     \advance\dimen0 by\w  % advance to next multiple of \w
  1679.     \wd0=\dimen0 \box0 \startbox}}
  1680. {\obeyspaces\global\let =\ } % let active space become control space
  1681. \def\listing#1{\par\begingroup\setupverbatim\input#1 \endgroup}
  1682. %
  1683. \newdimen\vsz % \vsz dimensions are relative to \baselineskip
  1684. \vsz=9pt
  1685. \newdimen\hsz % \hsz dimensions are a function of char width
  1686. \setbox0=\hbox{\stt m}
  1687. \hsz=\wd0
  1688. %
  1689. {\catcode`(=\active  % vertical left border
  1690. \gdef({\kern.6\hsz\vrule width.1\hsz height.8\vsz depth.2\vsz\kern.3\hsz}}
  1691. {\catcode`)=\active  % vertical right border
  1692. \gdef){\kern.2\hsz\vrule width.1\hsz height.8\vsz depth.2\vsz\kern.7\hsz}}
  1693. {\catcode`:=\active  % horizontal upper border
  1694. \gdef:{\kern-.4\hsz\vrule width1.7\hsz height-.17\vsz depth.22\vsz\kern-.3\hsz}}
  1695. {\catcode`;=\active  % horizontal lower border
  1696. \gdef;{\kern-.4\hsz\vrule width1.7\hsz height.78\vsz depth-.73\vsz\kern-.3\hsz}}
  1697. {\catcode`\~=\active % horizontal branch
  1698. \gdef~{\vrule width1\hsz height0\vsz depth.2\vsz}}
  1699. {\catcode`>=\active  % elbow (knob) moving horizontal branch to vertical
  1700. \gdef>{\vrule width.7\hsz height0\vsz depth.2\vsz\kern.3\hsz}}
  1701. {\catcode`|=\active  % vertical branch
  1702. \gdef|{\kern.3\hsz\vrule width.4\hsz height.8\vsz depth.2\vsz\kern.3\hsz}}
  1703. //E*O*F treeX//
  1704.  
  1705. echo x - treeD.tex
  1706. cat > "treeD.tex" << '//E*O*F treeD.tex//'
  1707. % XREF treeD treeX
  1708. \font\myit=cmti9
  1709. \font\mytt=cmtt9
  1710. \font\myletr=cmssq8
  1711. \font\bb=cmssbx10
  1712.  
  1713. \def\date{{\myletr May 4, 1990}}
  1714. \def\vers{{\myletr Version 1.1}}
  1715. \def\mansection{USER (1)}
  1716. \def\name{treeD}
  1717. \def\IT{{\bb treeD}}
  1718. \def\ALT{{\bb treeX}}
  1719.  
  1720. \hsize 5.6in
  1721. \vsize 8in
  1722. \raggedbottom
  1723. \parskip 0pt
  1724. \parindent 0pt
  1725. \myletr
  1726.  
  1727. % to enclose a horizontal upper-case string in a rectangle
  1728. \def\dx#1{\kern -.15em\setbox0=\hbox{\thinspace{#1}\thinspace}
  1729. \dimen0=\ht0 \advance\dimen0 by 2pt
  1730. \dimen1=\dimen0 \advance\dimen1 by -.3pt
  1731. \dimen3=\dp0 \advance\dimen3 by 2.3pt
  1732. \dimen4=\dimen3 \advance\dimen4 by -.3pt
  1733. \vrule height \dimen0 depth \dimen3 width .3pt
  1734. \vrule height \dimen0 depth -\dimen1 width \wd0
  1735. \vrule width -\wd0
  1736. \vrule height -\dimen4 depth \dimen3 width \wd0
  1737. \vrule width -\wd0
  1738. \box0
  1739. \vrule height \dimen0 depth \dimen3 width .3pt
  1740. }
  1741. % to enclose a single \tt key in a square
  1742. \def\key#1{\setbox0=\hbox{\thinspace{\mytt#1}\thinspace}
  1743. \dimen0=2ex \dimen1=\dimen0 \advance\dimen1 by -.3pt
  1744. \dimen3=.5ex \dimen4=\dimen3 \advance\dimen4 by -.3pt
  1745. \dimen5=\wd0
  1746. \vrule height \dimen0 depth \dimen3 width .3pt    % left vertical
  1747. \vrule height \dimen0 depth -\dimen1 width 1.05em % top horiz
  1748. \vrule width -1.05em                              % backup to left
  1749. \box0                                             % install text
  1750. \vrule width -\dimen5                             % backup to left
  1751. \vrule height -\dimen4 depth \dimen3 width 1.05em % bottom horiz
  1752. \vrule height \dimen0 depth \dimen3 width .3pt    % right vertical
  1753. \thinspace
  1754. }
  1755. \def\bs{{\char92}}       % \
  1756. \def\ul{{\char95}}       % _
  1757. \def\pipe{{\char124}}    % |
  1758. \def\lc{{\char123}}      % {
  1759. \def\rc{{\char125}}      % }
  1760. \def\lbrac{{\char91}}    % [
  1761. \def\rbrac{{\char93}}    % ]
  1762. \def\langle{{\char60}}   % <
  1763. \def\rangle{{\char62}}   % >
  1764. \def\circum{{\char94}}   % ^
  1765. \def\caret{{\char94}}    % ^
  1766. \def\tilde{{\char126}}   % ~
  1767. \def\dollar{{\char36}}   % $
  1768. \def\at{{\char64}}       % @
  1769.  
  1770. \headline={{\myletr\name\hfil\mansection\hfil\name}}
  1771. \footline={\ifodd\pageno\rightfoot\else\leftfoot\fi}
  1772. \def\leftfoot{\rlap{\myletr\folio}\hfil{\vers\ --- \date}\hfil}
  1773. \def\rightfoot{\hfil{\vers\ --- \date}\hfil\llap{\myletr\folio}}
  1774. \def\S#1{\leftline{}\par\leftskip=-20pt{\bb#1}\smallskip\leftskip=0pt}
  1775. \def\SU#1{\par\leftskip=-20pt{\bb#1}\smallskip\leftskip=0pt}
  1776. \def\L{\par\leftline{}\par}
  1777. \def\I#1{\leftskip=20pt{#1}\par\leftskip=0pt}
  1778.  
  1779. \S{NAME}
  1780. \IT\ --- Unix file system diagrammer
  1781.  
  1782. \ALT\ --- produce a file system diagram in \TeX
  1783.  
  1784. \S{SYNOPSIS}
  1785. \IT\
  1786. \lbrac --w N\rbrac\
  1787. \lbrac --l N\rbrac\
  1788. \lbrac --d N\rbrac\
  1789. \lbrac --f N\rbrac\
  1790. \lbrac --blank\rbrac\
  1791. dirname
  1792.  
  1793. \ALT\ dirname
  1794.  
  1795. \S{DESCRIPTION}
  1796. The \IT\ file system diagrammer bypasses text width limitations imposed
  1797. by fan-fold paper or scrollable screen output mediums, and
  1798. constructs a true two-dimensional map of the file
  1799. system ``{\myit dirname\/}'' specified on the command line.
  1800. To realize a hardcopy of this map, the internal diagram is
  1801. output in the form of
  1802. equal-sized pages, each page bearing a letter/number
  1803. coordinate analogous to lettered, numbered grids on a street map.
  1804. Command line options fine tune the format of the output, control
  1805. non-default grid sizes and the depth of the directory search
  1806. as follows:
  1807. \L
  1808. \item{{\bb --w} N}
  1809. specifies that the maximum printing width of a physical page
  1810. is N character columns.  The internal width of individual
  1811. grid rectangles will be expanded or reduced to the
  1812. nearest number of columns not greater
  1813. than N that will permit printing
  1814. full 16-column vertical file lists in parallel.  Each page must
  1815. be wide enough to contain at least one fixed width vertical file list,
  1816. two additional bytes per page for the vertical
  1817. grid boundary markers, and one leftmost byte for the vertical character
  1818. coordinate stamp of the grid: 19 bytes minimum.  The default page width
  1819. is nominally 72 bytes, 67 bytes of which is used to print a grid
  1820. rectangle.
  1821. \L
  1822. \item{{\bb --l} N}
  1823. specifies the maximum number of lines N, that can be printed on
  1824. a physical page.  Vertical lists of the map are arranged in
  1825. {\myit tiles\/}, each tile three lines in depth.  The smallest page
  1826. must be able to contain one tile, plus two lines for the top and bottom
  1827. horizontal grid markers, and a topmost line for the numerical
  1828. coordinate stamp of the grid: a minimum of 6 lines.  The default
  1829. page length is 66 lines, containing 21 tiles.
  1830. \L
  1831. \item{{\bb --d} N}
  1832. instructs \IT\ to halt directory recursion at N depth.  That is,
  1833. the command
  1834. \dx{treeD --d1 ../usr}\ results in diagramming the file structure of
  1835. {\myit ../usr\/}, but without descending into or listing the contents
  1836. of any of the
  1837. subdirectories.  The default N depth (zero) specifies infinite descent.
  1838. \L
  1839. \item{{\bb --f} N}
  1840. results in truncating long file lists beyond the Nth vertical page.
  1841. The default depth page can display 21 directory levels or
  1842. 63 plain files.  The structure of even complex file systems can often
  1843. be contained on a single horizontal grid strip, branches using up
  1844. map width much more readily than depth.  One or two directories with
  1845. many plain files may necessitate vertical expansion to show
  1846. excessively deep file lists; and can double or triple the total size of
  1847. the map while contributing little to the structural information.  The
  1848. {\myit --f\/} option truncates such long (plain) file lists beyond the
  1849. specified vertical page.
  1850. \L
  1851. \item{{\bb --blank}}
  1852. forces \IT\ to output blank ``filler'' pages.  If both the width and
  1853. the depth of the map is more than one grid rectangle,
  1854. the map may contain blank grids.
  1855. By default, such pages are not output.  With the {\myit --blank\/}
  1856. option any blank grids are also printed, each otherwise blank page
  1857. containing the number and letter coordinates and the outline
  1858. of the grid.
  1859. \L
  1860. The \IT\ process lists the files of the examined directories via the
  1861. \dx{ls -aFq}\ command, producing also the names of ``hidden files'',
  1862. and appending a single ``file type'' character to names of
  1863. directories, executable files, and a number of special files
  1864. (differently between System~V and BSD).  \IT\ does not display the
  1865. \key{.} and \key{..}
  1866. special directory links.  File names longer than
  1867. 14 characters are truncated in the map at 14 bytes, and the
  1868. ``name too long''
  1869. file type marker \key{\langle} is added as the fifteenth
  1870. character.  The file type marker of inaccessible directories
  1871. is changed from \key{/} to \key{!}, also in the cases when the
  1872. directory was made unreadable by the {\myit --d\/} option limiting
  1873. the descent.  The sixteenth byte of a printed plain filename is
  1874. always a space.
  1875. \L
  1876. The \ALT\ Bourne shell script first executes the
  1877. \smallskip
  1878. \I{\mytt treeD \ -l 79 \ -w 115 \ -f1 \ \dollar *}
  1879. \smallskip
  1880. command to diagram the directory specified on its command line,
  1881. then converts the output of the \IT\ command to
  1882. plain \TeX\ input.  Grid borders originally
  1883. marked by vertical \key{(} \key{)} and
  1884. horizontal \key{:} \key{;} characters are converted to
  1885. thin vertical and horizontal lines; file branch markers
  1886. \key{\tilde} \key{\pipe} \key{\rangle} are converted to
  1887. bold lines.  The {\myit treeX.tex\/} file thus produced, is then input
  1888. to \TeX, and yields the device independent output
  1889. {\myit treeX.dvi\/}, ready for printing.  The \IT\ command line
  1890. options embedded within \ALT\ can be overridden by specifying new
  1891. options on \ALT's command line before the final ``{\myit dirname\/}'',
  1892. however the \TeX\ format is expecting the exact 115-byte width and
  1893. 79-line pages shown above.
  1894. \bye
  1895. //E*O*F treeD.tex//
  1896.  
  1897. echo x - README
  1898. cat > "README" << '//E*O*F README//'
  1899. treeD --- Unix file system diagrammer
  1900.  
  1901. The utmost conceptual simplicity of file system trees belies the
  1902. difficulty of memorizing actual nodal layouts of specific trees.
  1903. In spite a plain topological essence of TREE no two trees are
  1904. the same; and most users would have an equal chance of being able
  1905. to recall the exact twig arrangement of last year's Christmas tree
  1906. as they would in describing a 30 Meg Unix subdirectory.
  1907.  
  1908. Recursive listers such as 'find' obscure the tree structure by the
  1909. one-dimensionality of their output: standard output mediums of
  1910. pinfeed paper or the scrollable screen rigidly limit the width,
  1911. while allowing infinitely long lists.
  1912.  
  1913. The treeD file system diagrammer erases the width limitation of
  1914. the output medium, and constructs true two-dimensional maps of
  1915. file systems.  To realize a hardcopy of a map, the internal diagram
  1916. is output as equal-sized pages, each page bearing a letter/number
  1917. coordinate analogous to lettered, numbered grids on a street map.
  1918. Command line options fine tune the format of the output, control
  1919. non-default grid sizes and the depth of the directory search.
  1920.  
  1921. -DREALUNIX should be enabled in the makefile when compiling under
  1922. System V.  The 'man page' is in the file treeD.tex, and should be
  1923. processed with "tex treeD" (assuming TeX capability at the site).
  1924. The Bourne script treeX converts treeD's character-graphics
  1925. depicting branching, to bold lines under plain TeX.
  1926. //E*O*F README//
  1927.  
  1928. echo Possible errors detected by \'wc\' [hopefully none]:
  1929. temp=/tmp/shar$$
  1930. trap "rm -f $temp; exit" 0 1 2 3 15
  1931. cat > $temp <<\!!!
  1932.      105     398    2671 globals.h
  1933.       78     213    1596 i.h
  1934.      160     591    4205 ilib.h
  1935.       19      30     262 goaway.c
  1936.       40     120     749 iego.c
  1937.       35      99     744 ierror.c
  1938.       40     137     914 illistn.c
  1939.      138     298    2905 init.c
  1940.       58     206    1330 iopt.c
  1941.       47     162    1143 iread.c
  1942.      153     457    2655 listfiles.c
  1943.      161     556    3553 mapper.c
  1944.       88     364    2351 package.c
  1945.      192     918    5652 split.c
  1946.      125     421    2371 tile.c
  1947.       64     198    1428 treeD.c
  1948.       19      38     311 makefile
  1949.       65     249    2480 treeX
  1950.      188    1047    7408 treeD.tex
  1951.       27     225    1419 README
  1952.     1802    6727   46147 total
  1953. !!!
  1954. wc  globals.h i.h ilib.h \
  1955. goaway.c iego.c ierror.c illistn.c init.c iopt.c iread.c \
  1956. listfiles.c mapper.c package.c split.c tile.c treeD.c \
  1957. makefile treeX treeD.tex README | sed 's=[^ ]*/==' | diff -b $temp -
  1958. exit 0
  1959. -- 
  1960.         Istvan Mohos
  1961.         ...uunet!pyrdc!pyrnj!hhb!istvan
  1962.         RACAL-REDAC/HHB 1000 Wyckoff Ave. Mahwah NJ 07430 201-848-8000
  1963. ======================================================================
  1964.