home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / misc / volume05 / trouble < prev    next >
Encoding:
Internet Message Format  |  1991-08-27  |  29.3 KB

  1. From decwrl!labrea!rutgers!tut.cis.ohio-state.edu!cwjcc!hal!ncoast!allbery Sun Dec 11 17:11:23 PST 1988
  2. Article 746 of comp.sources.misc:
  3. Path: granite!decwrl!labrea!rutgers!tut.cis.ohio-state.edu!cwjcc!hal!ncoast!allbery
  4. From: rjs@a.cs.okstate.edu (Roland Stolfa)
  5. Newsgroups: comp.sources.misc
  6. Subject: v05i071: Trouble Reporting System
  7. Message-ID: <4227@okstate.UUCP>
  8. Date: 7 Dec 88 00:22:58 GMT
  9. Sender: allbery@ncoast.UUCP
  10. Reply-To: rjs@a.cs.okstate.edu (Roland Stolfa)
  11. Organization: Oklahoma State Univ., Stillwater
  12. Lines: 1334
  13. Approved: allbery@ncoast.UUCP
  14.  
  15. Posting-number: Volume 5, Issue 71
  16. Submitted-by: "Roland Stolfa" <rjs@a.cs.okstate.edu>
  17. Archive-name: trouble
  18.  
  19. echo x - README
  20. sed '1,$s/^X//' <<\!FUNKY!STUFF! > README
  21. XINTRODUCTION:
  22. X
  23. X    This is the Trouble Report System (TRS) by
  24. X
  25. X    Roland J. Stolfa
  26. X    Department of Computing and Information Sciences
  27. X    Oklahoma State University
  28. X
  29. X    Internet:       rjs@a.cs.okstate.edu
  30. X
  31. X
  32. XDISCLAIMER:
  33. X
  34. X    All code is public domain.  No guarentee, expressed nor implied,
  35. X    covers this code.  I will NOT be responsible for it's use or
  36. X    misuse in your application.  I just hope (Underline that in red)
  37. X    that it may prove useful to you.  If something doesn't compile,
  38. X    I hope that the comments that surround the troble line will be
  39. X    sufficient to fix the problem.
  40. X
  41. X
  42. XDESCRIPTION:
  43. X
  44. X    This is a set of Bourne shell scrips and C programs intended
  45. X    to maintain a database of trouble reports.  The actions supported
  46. X    in this package are open a trouble report (trouble), post a followup
  47. X    on a trouble report (followup), remove a 'thread' of trouble reports
  48. X    (rmthread), report all open trouble report ticket numbers (opentr),
  49. X    and summarize a class of trouble reports (report).
  50. X
  51. X
  52. XINSTALLATION PROCEDURES:
  53. X
  54. X1.    Make a directory and put this shar in it.  Then say "sh <fn>".
  55. X
  56. X2.    Edit the file "Localize" to point the "ROOT", "BIN" and
  57. X    shell script escape sequences at the localally correct
  58. X    values.  Then type "sh Localize" to install these values
  59. X    on all files in this directory.  Then edit the Makefile
  60. X    and change the -DSYS5 to either -DSYS5 or -DULTRIX.
  61. X
  62. X3.    Say "make install".  This makes the various directories &
  63. X    sets the permissions to allow the next procedure to function.
  64. X
  65. X4.    Say "make all".
  66. X
  67. X5.    Done.
  68. X
  69. X
  70. XDIRECTORY STRUCTURE:
  71. X
  72. X                    Trs
  73. X                     |
  74. X        +-------+------------+----------+---------------+-------+
  75. X            |    |         |        |        |    |
  76. X          Entry <Soundex1>      ...     <SoundexN>           tmp     bin
  77. X        |       |                |        |
  78. X        +---+-----+    +-------+-+       +----+----+     +-----+
  79. X        |   ...   |       |   ...   |       |   ...   |     | ... |
  80. X    <Timestamp1> ... <Timestamp1> ..<Timestamp1> ...  trs.seq <temps>
  81. X
  82. XEach TRS record is first built in a temporary.  It is then linked into the
  83. X.../Trs/Entry/<Timestamp>" file.  Then it is linked into a subdirectory
  84. Xfor each SOUNDEX encoded keyword given during data entry.
  85. X
  86. X
  87. XNOTES:
  88. X
  89. X1.    If you need to move this datastructure, please use a program
  90. X    that preserves the link relationships.
  91. X
  92. X2.    If the average TRS record size is small and the default
  93. X    block size on the storage device is large, you loose...
  94. X
  95. X3.    This system typically uses a large number of links.  This
  96. X    implies that a large number of inodes will be used.  This
  97. X    can be a problem on smaller systems...
  98. X
  99. X4.    Each user can override the default "ROOT" setting by having
  100. X    an environment variable "TRSROOT" set to some directory
  101. X    that has the same structure as the one above.
  102. X
  103. X
  104. XFILES:
  105. X
  106. X    Localize
  107. X
  108. X        This shell script patches all the files in this system to
  109. X        work with the locally chosen directories.
  110. X
  111. X    Makefile
  112. X
  113. X        Used to create all the executables for each program.
  114. X
  115. X    README
  116. X
  117. X        This file.
  118. X
  119. X    followup.sh
  120. X
  121. X        This program is used to enter a follow up report onto
  122. X        the end of a TRS thread.  It walks the thread, from anywhere
  123. X        on the thread, to then end and then doubly links the end
  124. X        of the current thread to the new report.
  125. X
  126. X    mkpath.c
  127. X
  128. X        A utility program to generate directories along a given
  129. X        path without complaining.
  130. X
  131. X    opentr.sh
  132. X
  133. X        This shell script lists the initial trouble report ticket
  134. X        number for all active trouble reports.
  135. X
  136. X    parse.awk
  137. X
  138. X        This "awk(1)" program is used to parse the command line
  139. X        arguments to "report.sh".
  140. X
  141. X    print.c
  142. X
  143. X        This simple program is used to print all the command line
  144. X        arguments on a line by itself without a carriage return
  145. X        on the end.
  146. X
  147. X    report.sh
  148. X
  149. X        This shell script attempts to extract data from the TRS
  150. X        database given any combination of keys.
  151. X
  152. X    reporter.awk
  153. X
  154. X        This "awk(1)" program is used in one stage of the "report.sh"
  155. X        program.
  156. X
  157. X    rmthread.sh
  158. X
  159. X        This shell script removes an entire linked list of trouble
  160. X        reports, given a report anywhere in the list.
  161. X
  162. X    soundex.c
  163. X
  164. X        This C program implements a "SOUNDEX" algorithm and is used
  165. X        in the TRS to encode keywords within the database to ease
  166. X        searching.
  167. X
  168. X    trouble.sh
  169. X
  170. X        This shell script does the actual data entry for the TRS system.
  171. X        It attempts to prompt for all the relavant data, generates
  172. X        some stuff by default, and then builds all the linked files
  173. X        that constitue the database.
  174. !FUNKY!STUFF!
  175. echo x - Localize
  176. sed '1,$s/^X//' <<\!FUNKY!STUFF! > Localize
  177. X#
  178. X# Localizing script for the (T)rouble (R)eport (S)ystem
  179. X#
  180. X
  181. Xfor i in Makefile *.sh
  182. Xdo
  183. X
  184. X    #
  185. X    # Attach the "ROOT" to some clean point like /usr/local/lib/trs
  186. X    # as this will need to be a publically writable directory that
  187. X    # will hold all trouble reports.
  188. X    #
  189. X    # Attach the "BIN" to some global point like /usr/lbin for all
  190. X    # the executables
  191. X    #
  192. Xed - $i <<'EOF'
  193. Xg;^ROOT;s;=.*$;=/u/rjs/lib/Trs;
  194. Xg;^BIN;s;=.*$;=/u/rjs/bin;
  195. Xw
  196. Xq
  197. XEOF
  198. X
  199. Xdone
  200. X
  201. Xfor i in *.sh
  202. Xdo
  203. X
  204. X    #
  205. X    # The ":" in the ed script below is the first line of all shell
  206. X    # scripts for SYS5.  For ULTRIX, it should be "#!/bin/sh".
  207. X    #
  208. Xed - $i <<'EOF'
  209. X1 s;^.*$;:;
  210. Xw
  211. Xq
  212. XEOF
  213. X
  214. Xdone
  215. !FUNKY!STUFF!
  216. echo x - Makefile
  217. sed '1,$s/^X//' <<\!FUNKY!STUFF! > Makefile
  218. X#
  219. X# Package    : TRS
  220. X# Module    : (Makefile)
  221. X# Programmer    : R. Stolfa
  222. X#
  223. X# Purpose :    To maintain a Trouble Report System for an
  224. X#        university environment
  225. X#
  226. X# Modification History:
  227. X#   04/11/88    Created
  228. X#   10/25/88    Updated for distribution outside of OSU
  229. X#
  230. XROOT=/u/rjs/lib/Trs
  231. XLIB=$(ROOT)/lib
  232. XBIN=/u/rjs/bin
  233. XCFLAGS=    -O -DSYS5
  234. X
  235. XDuMb:
  236. X    @echo Make what?
  237. X
  238. Xfollowup:    $(BIN)/followup
  239. X$(BIN)/followup:    followup.sh
  240. X    cp followup.sh $(BIN)/followup
  241. X    chmod 755 $(BIN)/followup
  242. X
  243. Xmkpath:    $(LIB)/mkpath
  244. X$(LIB)/mkpath:    mkpath.c
  245. X    cc $(CFLAGS) mkpath.c -o $(LIB)/mkpath
  246. X    chmod 755 $(LIB)/mkpath
  247. X
  248. Xopentr:    $(BIN)/opentr
  249. X$(BIN)/opentr:    opentr.sh
  250. X    cp opentr.sh $(BIN)/opentr
  251. X    chmod 755 $(BIN)/opentr
  252. X
  253. XParse.awk:    $(LIB)/parse.awk
  254. X$(LIB)/parse.awk:    parse.awk
  255. X    cp parse.awk $(LIB)/parse.awk
  256. X    chmod 644 $(LIB)/parse.awk
  257. X
  258. Xprint:    $(LIB)/print
  259. X$(LIB)/print:    print.c
  260. X    cc print.c -o $(LIB)/print
  261. X    chmod 755 $(LIB)/print
  262. X
  263. Xreport:    Parse.awk Reporter.awk $(BIN)/report
  264. X$(BIN)/report:    report.sh
  265. X    cp report.sh $(BIN)/report
  266. X    chmod 755 $(BIN)/report
  267. X
  268. XReporter.awk:    $(LIB)/reporter.awk
  269. X$(LIB)/reporter.awk:    reporter.awk
  270. X    cp reporter.awk $(LIB)/reporter.awk
  271. X    chmod 644 $(LIB)/reporter.awk
  272. X
  273. Xrmthread:    $(BIN)/rmthread
  274. X$(BIN)/rmthread:    rmthread.sh
  275. X    cp rmthread.sh $(BIN)/rmthread
  276. X    chmod 755 $(BIN)/rmthread
  277. X
  278. Xsoundex:    $(LIB)/soundex
  279. X$(LIB)/soundex:    soundex.c
  280. X    cc soundex.c -o $(LIB)/soundex
  281. X    chmod 755 $(LIB)/soundex
  282. X
  283. Xtrouble:    $(BIN)/trouble
  284. X$(BIN)/trouble:    trouble.sh
  285. X    cp trouble.sh $(BIN)/trouble
  286. X    chmod 755 $(BIN)/trouble
  287. X
  288. X#
  289. X# Housekeeping
  290. X#
  291. X
  292. Xall:    followup opentr mkpath print report rmthread soundex trouble
  293. X    @echo "Don't forget 'make install' to setup sequence file"
  294. X
  295. Xbackout:    clean
  296. X    rm -rf $(ROOT)
  297. X    rm -if $(BIN)/followup $(BIN)/opentr $(BIN)/report $(BIN)/rmthread \
  298. X        $(BIN)/trouble
  299. X
  300. Xclean:
  301. X    rm -f *.o a.out core
  302. X
  303. Xinstall:
  304. X    -mkdir $(ROOT) $(ROOT)/Entry $(ROOT)/tmp $(ROOT)/lib
  305. X    chmod 777 $(ROOT) $(ROOT)/Entry $(ROOT)/tmp
  306. X    chmod 755 $(ROOT)/lib
  307. X    echo "0" > $(ROOT)/sequence
  308. X
  309. Xshar:
  310. X    shar README Localize Makefile [a-z]* > Trs.shar
  311. X
  312. X#
  313. X# Dependancies
  314. X#
  315. Xmkpath.o print.o soundex.o :    /usr/include/stdio.h
  316. !FUNKY!STUFF!
  317. echo x - followup.1
  318. sed '1,$s/^X//' <<\!FUNKY!STUFF! > followup.1
  319. X.TH FOLLOWUP L
  320. X.SH NAME
  321. Xfollowup - post a followup trouble report
  322. X.SH SYNOPSIS
  323. X.B followup [ ticket number ]
  324. X.br
  325. X.SH DESCRIPTION
  326. X.I followup
  327. Xis intended to be the method of posting a new report in a "thread" of
  328. Xreports assoicated with a reported problem in hardware/software.
  329. X.PP
  330. XIf 
  331. X.I followup
  332. Xis invoked without a ticket number, it prompts for one.  Then an entire
  333. Xnew trouble report is attached to a thread of reports assoicated together.
  334. XThis list of reports is doubly linked in the trouble report file and then
  335. Xlinked (using "ln(1)") to all soundex encoded subdirectories relating
  336. Xto the keywords specified.
  337. X.PP
  338. XAll of the files and directories contained in the system are all plain
  339. Xtext files, with an easy format that can be used to your advantage.
  340. X.sp 1
  341. X.SH "INTERNALS"
  342. X.I followup
  343. Xuses a tree structured file data-base to store all trouble reports.  Each
  344. Xreport occupies one file in the "../Trs/Entry" directory with the name
  345. Xbeing equal to that of the date (in YYMMDD format) and a sequence number
  346. Xappended (i.e. 881025.1).  This file is then linked (using "ln(1)") to
  347. Xa subdirectory for each keyword specified in the
  348. X.I followup
  349. Xkeyword prompt.  Each keyword is encoded via the
  350. X.I soundex
  351. Xalgorythm to be the "link" directory.  This allows fast searches of
  352. Xrecurring problems (see "report(L)").
  353. X.SH "FILES"
  354. X"/usr/local/lib/trs/...."    - Root directory for help
  355. X.br
  356. X"/usr/local/lib/trs/entry/..."    - Directory where ALL trouble reports reside
  357. X.br
  358. X"/usr/local/lib/trs/sequence"    - Sequence file
  359. X.PP
  360. X.SH DIAGNOSTICS
  361. XThere are no real diagnostics.
  362. X.SH AUTHOR
  363. XRoland J. Stolfa
  364. X.br
  365. XDepartment of Computing and Information Sciences
  366. X.br
  367. XOklahoma State University
  368. X.br
  369. Xrjs@a.cs.okstate.edu
  370. !FUNKY!STUFF!
  371. echo x - followup.sh
  372. sed '1,$s/^X//' <<\!FUNKY!STUFF! > followup.sh
  373. X:
  374. X#
  375. X# Package    : TRS
  376. X# Module    : followup.sh
  377. X# Programmer    : R. Stolfa
  378. X#
  379. X# Purpose :    To 'needle & thread' TRS records together.
  380. X#
  381. X# Modification History:
  382. X#   04/12/88    Created
  383. X#   10/25/88    Added user configurable "ROOT" to allow more than
  384. X#        one TRS to exist on a particular system.
  385. X#
  386. X
  387. X#
  388. X# Some variables
  389. X#
  390. Xumask 000
  391. Xif [ "$TRSROOT" != "" ]
  392. Xthen
  393. X    ROOT=$TRSROOT
  394. Xelse
  395. XROOT=/u/rjs/lib/Trs
  396. Xfi
  397. XBIN=/u/rjs/bin
  398. XENTRY=$ROOT/Entry
  399. XLIB=$ROOT/lib
  400. Xtrap "rm -f $ROOT/tmp/* ; exit 1" 1 2 15
  401. X
  402. X#
  403. X# Ok.  Get the 'trouble ticket' number.
  404. X#
  405. Xnum="$*"
  406. Xif test ! -s $ENTRY/$num
  407. Xthen
  408. X    echo "Invalid trouble ticket number.  Try again."
  409. X    num=""
  410. Xfi
  411. Xwhile [ "$num" = "" ]
  412. Xdo
  413. X    $LIB/print "Enter trouble ticket number? "
  414. X    read num
  415. X
  416. X    if test ! -s $ENTRY/$num
  417. X    then
  418. X        echo "Invalid trouble ticket number.  Try again."
  419. X        num=""
  420. X    fi
  421. Xdone
  422. X
  423. X#
  424. X# Follow it's threads until you reach the last one.
  425. X#
  426. Xthread="+"
  427. Xwhile [ "$thread" != "" ]
  428. Xdo
  429. X    thread="`grep '^thread=' $ENTRY/$num | awk -F= '{print $2}'`"
  430. X    if [ "$thread" != "" ]
  431. X    then
  432. X        num="$thread"
  433. X    fi
  434. Xdone
  435. X
  436. X#
  437. X# Display last entry.
  438. X#
  439. Xecho "Last entry as follows:"
  440. Xecho ""
  441. Xecho "ticket=$num"
  442. Xecho "reporter=`ls -l $ENTRY/$num | awk '{print $3}'`"
  443. Xmore $ENTRY/$num
  444. Xecho ""
  445. Xyesno=""
  446. Xwhile [ "$yesno" = "" ]
  447. Xdo
  448. X    $LIB/print "Is this the correct one? (Y/N) "
  449. X    read yesno
  450. Xdone
  451. X
  452. X#
  453. X# If incorrect, try again.
  454. X#
  455. Xif [ "$yesno" = "N" -o "$yesno" = "n" ]
  456. Xthen
  457. X    exec $BIN/followup
  458. Xfi
  459. X
  460. X#
  461. X# Ok.  Generate a new trouble report and then fix the threading.
  462. X# Do this by 'including' the trouble ticket generator.
  463. X#
  464. Xnumber=$num
  465. X. $BIN/trouble
  466. Xecho "thread=$NTN" >> $ENTRY/$number
  467. Xecho "needle=$num" >> $ENTRY/$NTN
  468. !FUNKY!STUFF!
  469. echo x - mkpath.c
  470. sed '1,$s/^X//' <<\!FUNKY!STUFF! > mkpath.c
  471. X/*
  472. X * Package    : TRS
  473. X * Module    : mkpath.c
  474. X * Programmer    : R. Stolfa
  475. X *
  476. X * Purpose :    To create all  the subdirectories that are needed
  477. X *        for a file specified on the command line.
  478. X *
  479. X * Usage:
  480. X *        % mkpath foo/bar/cat/dog
  481. X *            Will make the directories foo, foo/bar, and foo/bar/cat
  482. X *            if they don't already exist.
  483. X *
  484. X * Modification History:
  485. X *   02/15/88    Created
  486. X */
  487. X
  488. X#include    <stdio.h>
  489. X
  490. Xmain (argc, argv)
  491. Xint    argc;
  492. Xchar    *argv[];
  493. X{
  494. X    int    i;
  495. X
  496. X    for (i = 1; i < argc; i ++)
  497. X        mkpath (argv[i]);
  498. X}
  499. X
  500. Xmkpath (name)
  501. Xchar    name[];
  502. X{
  503. X
  504. X    char    buff[512];
  505. X    int    i,
  506. X        dumb;
  507. X#ifdef SYS5
  508. X    char    cmd[512];
  509. X#endif
  510. X
  511. X    for (i = 0; i < strlen(name); i ++) {
  512. X        buff[i] = '\0';
  513. X        if (name[i] == '/') {
  514. X#ifdef ULTRIX
  515. X            dumb = mkdir (buff, 0755);
  516. X#endif
  517. X
  518. X#ifdef SYS5
  519. X            sprintf (cmd, "mkdir %s > /dev/null 2>&1", buff);
  520. X            system (cmd);
  521. X#endif
  522. X        }
  523. X        buff[i] = name[i];
  524. X    }
  525. X}
  526. !FUNKY!STUFF!
  527. echo x - opentr.1
  528. sed '1,$s/^X//' <<\!FUNKY!STUFF! > opentr.1
  529. X.TH OPENTR L
  530. X.SH NAME
  531. Xopentr - report all open trouble reports
  532. X.SH SYNOPSIS
  533. X.B opentr
  534. X.br
  535. X.SH DESCRIPTION
  536. X.I opentr
  537. Xis intended to be used to find all open trouble reports to give
  538. Xthe trouble manager something to do in their spare time :-).
  539. X.SH AUTHOR
  540. XRoland J. Stolfa
  541. X.br
  542. XDepartment of Computing and Information Sciences
  543. X.br
  544. XOklahoma State University
  545. X.br
  546. Xrjs@a.cs.okstate.edu
  547. !FUNKY!STUFF!
  548. echo x - opentr.sh
  549. sed '1,$s/^X//' <<\!FUNKY!STUFF! > opentr.sh
  550. X:
  551. X#
  552. X# Package    : TRS
  553. X# Module    : opentr.sh
  554. X# Programmer    : R. Stolfa
  555. X#
  556. X# Purpose :    To list all open trouble report ticket numbers
  557. X#        in the TRS database.
  558. X#
  559. X# Modification History:
  560. X#   04/15/88    Created
  561. X#   10/25/88    Added a user configurable "ROOT" to allow more than
  562. X#        one TRS on a system.
  563. X#
  564. X
  565. X#
  566. X# Some variables
  567. X#
  568. Xumask 000
  569. Xif [ "$TRSROOT" != "" ]
  570. Xthen
  571. X    ROOT=$TRSROOT
  572. Xelse
  573. XROOT=/u/rjs/lib/Trs
  574. Xfi
  575. XENTRY=$ROOT/Entry
  576. XLIB=$ROOT/lib
  577. Xif [ `ls $ENTRY | wc -l` -gt 0 ]
  578. Xthen
  579. X    for i in $ENTRY/*
  580. X    do
  581. X        if [ `grep "^needle=" $i | wc -l` -eq 0 ]
  582. X        then
  583. X            echo `basename $i`
  584. X        fi
  585. X    done
  586. Xfi
  587. !FUNKY!STUFF!
  588. echo x - parse.awk
  589. sed '1,$s/^X//' <<\!FUNKY!STUFF! > parse.awk
  590. X#
  591. X# Package    : TRS
  592. X# Module    : parse.awk
  593. X# Programmer    : R. Stolfa
  594. X#
  595. X# Purpose :    To parse the command line arguments to "report.sh".
  596. X#
  597. X# Modification History:
  598. X#   04/12/88    Created
  599. X#
  600. X
  601. XBEGIN    {
  602. X    FS = "=";
  603. X}
  604. X
  605. X{
  606. X    if (NF == 2) {
  607. X        char = substr ($1, 0, 1);
  608. X        if ((char == "t") || (char == "T"))
  609. X            printf "T\n";
  610. X        else if ((char == "k") || (char == "K"))
  611. X            printf "K\n";
  612. X        else if ((char == "d") || (char == "D"))
  613. X            printf "D\n";
  614. X        else if ((char == "r") || (char == "R"))
  615. X            printf "R\n";
  616. X        else if ((char == "e") || (char == "E"))
  617. X            printf "E\n";
  618. X    }
  619. X}
  620. !FUNKY!STUFF!
  621. echo x - print.c
  622. sed '1,$s/^X//' <<\!FUNKY!STUFF! > print.c
  623. X/*
  624. X * Package    : TRS
  625. X * Module    : print.c
  626. X * Programmer    : R. Stolfa
  627. X *
  628. X * Purpose :    To provide a portable way of printing a string
  629. X *        of text on stdout without having a newline at the
  630. X *        end.
  631. X *
  632. X * Modification History:
  633. X *   04/01/88    Created
  634. X */
  635. X
  636. X#include    <stdio.h>
  637. X
  638. Xmain (argc, argv)
  639. Xint    argc;
  640. Xchar    *argv[];
  641. X{
  642. X    int    i;
  643. X
  644. X    if (argc > 1) {
  645. X        for (i = 1; i < argc - 1 ; i ++)
  646. X            printf ("%s ", argv[i]);
  647. X
  648. X        printf ("%s", argv[argc-1]);
  649. X    }
  650. X}
  651. !FUNKY!STUFF!
  652. echo x - report.1
  653. sed '1,$s/^X//' <<\!FUNKY!STUFF! > report.1
  654. X.TH REPORT L
  655. X.SH NAME
  656. Xreport - extract all requested trouble reports by selection criteria
  657. X.SH SYNOPSIS
  658. X.B report [ t=<thread> ] [ k=<keyword> ] [ d=<date> ] [ r=<reporter> ] [ e=<equipment> ]
  659. X.br
  660. X.SH DESCRIPTION
  661. X.I report
  662. Xis intended to extract the utmost information from the (T)rouble (R)eport
  663. X(S)ystem.  With this shell script, you can extract an entire thread
  664. Xusing the
  665. X.B [ t=<thread id> ]
  666. Xoption, or you may select all reports with a particular keyword
  667. Xusing the
  668. X.B [ k=<keyword> ]
  669. Xoption.  In addition, you may select all reports on a particular day
  670. Xusing the
  671. X.B [ d=<date> ]
  672. Xoption.  If that isn't enough, you can select a particular reporter (read that
  673. Xas UN*X user login id) by using the
  674. X.B [ r=<reporter> ]
  675. Xoption.  Lastly, you can use the
  676. X.B [ e=<equipment id string> ]
  677. Xoption to extract all info about a particular peice of equipment and or a class
  678. Xof equipment, depending on what you use for the
  679. X.B <equipment id string>.
  680. X.PP
  681. XIn addition, you can use the different options of 
  682. X.I report
  683. Xadditvely.  Several examples follow.
  684. X.PP
  685. Xreport t=881025.1 e="terminal"
  686. X.br
  687. Xextracts all trouble report entries in the thread assoicated with the head
  688. Xof the thread pointed to by 881025.1 that deal with the "terminal" class
  689. Xof devices.
  690. X.PP
  691. Xreport d=881025 r=joe e="terminal"
  692. X.br
  693. Xextracts all trouble reports on 10/25/88 by user "joe" involving a
  694. X"terminal".
  695. X.PP
  696. Xreport k=broken e="terminal"
  697. X.br
  698. Xextracts all trouble reports about "broken" "terminal"s.
  699. X.PP
  700. XIn short, you get the idea.
  701. X.sp 1
  702. X.SH "INTERNALS"
  703. X.I report
  704. Xuses a single pass over the arguments above
  705. X.B IN THE LISTED ORDER
  706. Xto refine the eventual list of trouble report tickets to be printed
  707. Xas the "report".  Note that any missordering of the arguments will be
  708. Xhandled by re-ordering them as listed above BEFORE selection occurs.
  709. X.sp 1
  710. X.SH DIAGNOSTICS
  711. XThere are no real diagnostics.  You are expected to be able to fathom
  712. Xthe deep-dark recesses of shell programming & have a good working knowledge
  713. Xof links in order to do ANY debugging of this system.
  714. X.sp 1
  715. X.SH AUTHOR
  716. XRoland J. Stolfa
  717. X.br
  718. XDepartment of Computing and Information Sciences
  719. X.br
  720. XOklahoma State University
  721. X.br
  722. Xrjs@a.cs.okstate.edu
  723. !FUNKY!STUFF!
  724. echo x - report.sh
  725. sed '1,$s/^X//' <<\!FUNKY!STUFF! > report.sh
  726. X:
  727. X#
  728. X# Package    : TRS
  729. X# Module    : report.sh
  730. X# Programmer    : R. Stolfa
  731. X#
  732. X# Purpose :    To scan the TRS database and extract "reasonable"
  733. X#        information.  This information will be presented
  734. X#        on the screen in a format suitable for printing
  735. X#
  736. X# Command line syntax:
  737. X#        report <flags>
  738. X#        where <flags> are some set of the following
  739. X#
  740. X#        t=<thread id>
  741. X#        k=<keyword to search on>
  742. X#        d=<date in YYMMDD format>
  743. X#        r=<reporter (userid)>
  744. X#        e=<equipment id string (inventory number?)>
  745. X#
  746. X# Modification History:
  747. X#   04/12/88    Created
  748. X#   10/25/88    Added a user configurable "ROOT" to allow more than
  749. X#        one TRS on a system
  750. X#
  751. X
  752. X#
  753. X# Some variables
  754. X#
  755. Xumask 000
  756. Xif [ "$TRSROOT" != "" ]
  757. Xthen
  758. X    ROOT=$TRSROOT
  759. Xelse
  760. XROOT=/u/rjs/lib/Trs
  761. Xfi
  762. XENTRY=$ROOT/Entry
  763. XLIB=$ROOT/lib
  764. XTEMP=$ROOT/tmp/trs.$$
  765. XTEMP2=$ROOT/tmp/trs2.$$
  766. XTEMP3=$ROOT/tmp/trs3.$$
  767. Xtrap "rm -f $ROOT/tmp/* ; exit 1" 1 2 15
  768. X
  769. Xthread=""
  770. Xkey="Entry"
  771. Xdate="*"
  772. Xreporter=""
  773. Xequip=""
  774. X
  775. X#
  776. X# Parse the command line with "parse.awk"
  777. X#
  778. Xfor i in $*
  779. Xdo
  780. X    case `echo $i | awk -f $LIB/parse.awk` in
  781. X    T)
  782. X        thread="`echo $i | awk -F= '{print $2}'`"
  783. X        continue;;
  784. X    K)
  785. X        item=`echo $i | awk -F= '{print $2}'`
  786. X        key=`$LIB/soundex $item`
  787. X        continue;;
  788. X    D)
  789. X        date="`echo $i | awk -F= '{print $2}'`"
  790. X        continue;;
  791. X    R)
  792. X        reporter="`echo $i | awk -F= '{print $2}'`"
  793. X        continue;;
  794. X    E)
  795. X        equip="`echo $i | awk -F= '{print $2}'`"
  796. X        continue;;
  797. X    esac
  798. Xdone
  799. X
  800. X#
  801. X# Separate out a thread (if required).
  802. X#
  803. Xif [ "$thread" != "" ]
  804. Xthen
  805. X    #
  806. X    # Ok.  Let's generate a thread list.
  807. X    #
  808. X    if test ! -s $ENTRY/$thread
  809. X    then
  810. X        echo "Invalid thread id.  Try again."
  811. X        exit
  812. X    fi
  813. X    rm -f $TEMP
  814. X    #
  815. X    # Find head of thread
  816. X    #
  817. X    needle=$thread
  818. X    while [ "$needle" != "" ]
  819. X    do
  820. X        thread=$needle
  821. X        needle="`grep '^needle=' $ENTRY/$needle | awk -F= '{print $2}'`"
  822. X    done
  823. X    #
  824. X    # List the members of the thread
  825. X    #
  826. X    while [ "$thread" != "" ]
  827. X    do
  828. X        echo "$ENTRY/$thread" >> $TEMP
  829. X        thread="`grep '^thread=' $ENTRY/$thread | awk -F= '{print $2}'`"
  830. X    done
  831. Xelse
  832. X    #
  833. X    # Get all files
  834. X    #
  835. X    ls $ROOT/$key/$date* > $TEMP2 2>/dev/null
  836. X    sort -u < $TEMP2 > $TEMP
  837. X    date="*"
  838. X    key=""
  839. Xfi
  840. X
  841. X#
  842. X# Now lets get the key field taken care of.
  843. X#
  844. Xif [ "$key" != "" ]
  845. Xthen
  846. X    for i in `cat $TEMP`
  847. X    do
  848. X        ls $ROOT/$key/`basename $i` 2>/dev/null
  849. X    done > $TEMP2
  850. X    mv $TEMP2 $TEMP
  851. Xfi
  852. X
  853. X#
  854. X# Ok.  Now let's generate the subset of the list that has occured on
  855. X# the date in question.
  856. X#
  857. Xif [ "$date" != "*" ]
  858. Xthen
  859. X    grep "$date" < $TEMP > $TEMP2
  860. X    mv $TEMP2 $TEMP
  861. Xfi
  862. X
  863. X#
  864. X# Do the awking for a particular reporter (if necessary).
  865. X#
  866. Xif [ "$reporter" != "" ]
  867. Xthen
  868. X    echo "$reporter" > $TEMP2
  869. X    ls -l `cat $TEMP` >> $TEMP2
  870. X    awk -f $LIB/reporter.awk < $TEMP2 > $TEMP
  871. X    rm $TEMP2
  872. Xfi
  873. X
  874. X#
  875. X# Do the greping for a particular piece of equipment (if necessary).
  876. X#
  877. Xif [ "$equip" != "" ]
  878. Xthen
  879. X    grep -l "^equipment=$equip" `cat $TEMP` > $TEMP
  880. Xfi
  881. X
  882. X#
  883. X# Ok.  More the junk to the screen...
  884. X#
  885. Xfor i in `cat $TEMP`
  886. Xdo
  887. X    echo "ticket=`basename $i`"
  888. X    echo "reporter=`ls -l $i | awk '{print $3}'`"
  889. X    cat $i
  890. X    echo ""
  891. Xdone | more
  892. X
  893. X#
  894. X# Now clean up and exit.
  895. X#
  896. Xrm -f $TEMP $TEMP2 $TEMP3
  897. !FUNKY!STUFF!
  898. echo x - reporter.awk
  899. sed '1,$s/^X//' <<\!FUNKY!STUFF! > reporter.awk
  900. X#
  901. X# Package    : TRS
  902. X# Module    : reporter.awk
  903. X# Programmer    : R. Stolfa
  904. X#
  905. X# Purpose :    This program returns only those lines with the
  906. X#        correct user field as the reporter.
  907. X#
  908. X# Modification History:
  909. X#   04/12/88    Created
  910. X#
  911. X
  912. X{
  913. X    if (NR == 1)
  914. X        reporter = $1;
  915. X    else if (NF > 1) {
  916. X        if (substr($3, 0, length(reporter)) == reporter)
  917. X            printf "%s\n", $NF;
  918. X    }
  919. X}
  920. !FUNKY!STUFF!
  921. echo x - rmthread.1
  922. sed '1,$s/^X//' <<\!FUNKY!STUFF! > rmthread.1
  923. X.TH RMTHREAD L
  924. X.SH NAME
  925. Xrmthread - remove a trouble report system thread from anywhere on the thread
  926. X.SH SYNOPSIS
  927. X.B rmthread [threadid]
  928. X.br
  929. X.SH DESCRIPTION
  930. X.I rmthread
  931. Xis to be used when an entire thread of trouble reports have been delt with
  932. Xand the ammased information is no longer of any use.  This program finds
  933. Xthe head of the list of trouble reports (on the thread given) and then builds
  934. Xa list of thread files to remove.  It then displays the entire thread and
  935. Xasks you if you really want to remove it.  If so, it then gets rid of all
  936. Xoccurances of the associated thread from the trouble report system.
  937. X.sp 1
  938. X.SH "INTERNALS"
  939. X.I rmthread
  940. Xuses an text line in the thread file to provide both a forward link to the
  941. Xnext trouble report and another text line to provide the backward link to
  942. Xthe previous trouble report.  This is why it is so slow at times.
  943. X.sp 1
  944. X.SH AUTHOR
  945. XRoland J. Stolfa
  946. X.br
  947. XDepartment of Computing and Information Sciences
  948. X.br
  949. XOklahoma State University
  950. X.br
  951. Xrjs@a.cs.okstate.edu
  952. !FUNKY!STUFF!
  953. echo x - rmthread.sh
  954. sed '1,$s/^X//' <<\!FUNKY!STUFF! > rmthread.sh
  955. X:
  956. X#
  957. X# Package    : TRS
  958. X# Module    : rmthread.sh
  959. X# Programmer    : R. Stolfa
  960. X#
  961. X# Purpose :    To delete a thread of trouble reports in the TRS
  962. X#        database system.
  963. X#
  964. X# Modification History:
  965. X#   04/12/88    Created
  966. X#   10/25/88    Added a user configurable "ROOT" to allow more than
  967. X#        one TRS on a system
  968. X#
  969. X
  970. X#
  971. X# Some variables
  972. X#
  973. Xumask 000
  974. Xif [ "$TRSROOT" != "" ]
  975. Xthen
  976. X    ROOT=$TRSROOT
  977. Xelse
  978. XROOT=/u/rjs/lib/Trs
  979. Xfi
  980. XENTRY=$ROOT/Entry
  981. XLIB=$ROOT/lib
  982. Xtrap "rm -f $ROOT/tmp/* ; exit 1" 1 2 15
  983. X
  984. X#
  985. X# Get the tread to delete.
  986. X#
  987. Xthread="$*"
  988. Xwhile [ "$thread" = "" ]
  989. Xdo
  990. X    $LIB/print "Enter thread to delete? "
  991. X    read thread
  992. X
  993. X    if test ! -s $ENTRY/$thread
  994. X    then
  995. X        echo "Invalid thread.  Try again"
  996. X        thread=""
  997. X    fi
  998. Xdone
  999. X
  1000. X#
  1001. X# Search backwards (if possible) for head of thread.
  1002. X#
  1003. Xneedle="+"
  1004. Xwhile [ "$needle" != "" ]
  1005. Xdo
  1006. X    needle="`grep '^needle=' $ENTRY/$thread | awk -F= '{print $2}'`"
  1007. X    if [ "$needle" != "" ]
  1008. X    then
  1009. X        thread="$needle"
  1010. X    fi
  1011. Xdone
  1012. X
  1013. X#
  1014. X# ASSERT:
  1015. X#    At this point, thread is the original trouble report ticket
  1016. X#    number.  Now let's keep that number safe and display the thread
  1017. X#    to assure that it is the one that needs to be removed.
  1018. X#
  1019. X
  1020. Xptr="$thread"
  1021. Xecho "The following is the listing of this thread."
  1022. Xecho ""
  1023. Xwhile [ "$ptr" != "" ]
  1024. Xdo
  1025. X    echo "ticket=$ptr"
  1026. X    echo "reporter=`ls -l $ENTRY/$ptr | awk '{print $3}'`"
  1027. X    cat $ENTRY/$ptr
  1028. X    echo ""
  1029. X    ptr="`grep '^thread=' $ENTRY/$ptr | awk -F= '{print $2}'`"
  1030. Xdone | more
  1031. X
  1032. X#
  1033. X# Prompt for removal.
  1034. X#
  1035. Xyesno=""
  1036. Xwhile [ "$yesno" = "" ]
  1037. Xdo
  1038. X    $LIB/print "Is this the thread you want to delete? (Y/N) "
  1039. X    read yesno
  1040. Xdone
  1041. X
  1042. Xif [ "$yesno" = "n" -o "$yesno" = "N" ]
  1043. Xthen
  1044. X    exit
  1045. Xfi
  1046. X
  1047. X#
  1048. X# Ok.  We have permission.  Just remove the whole stupid thing...
  1049. X#
  1050. Xptr="$thread"
  1051. Xwhile [ "$ptr" != "" ]
  1052. Xdo
  1053. X    thread="`grep '^thread=' $ENTRY/$ptr | awk -F= '{print $2}'`"
  1054. X    rm -f $ROOT/*/$ptr
  1055. X    ptr="$thread"
  1056. Xdone
  1057. !FUNKY!STUFF!
  1058. echo x - soundex.c
  1059. sed '1,$s/^X//' <<\!FUNKY!STUFF! > soundex.c
  1060. X/*
  1061. X * Package    : TRS
  1062. X * Program    : soundex.c
  1063. X * Programmer    : Roland Stolfa
  1064. X *
  1065. X * Function :    This program implements the SOUNDEX procedure as
  1066. X *        outlined on page 655 of "Database Design" by
  1067. X *        Gio Wiederhold.  This procedure was originally
  1068. X *        introduced by Odell & Russel (1918) and was
  1069. X *        described by McEwen (1974).
  1070. X *
  1071. X * Usage :    soundex <string1> <string2> ... <stringN>
  1072. X */
  1073. X
  1074. X#include    <stdio.h>
  1075. X
  1076. X#define        BS        200
  1077. X
  1078. Xmain (argc, argv)
  1079. Xint    argc;
  1080. Xchar    *argv[];
  1081. X{
  1082. X    char    sound[BS];
  1083. X    int    i;
  1084. X
  1085. X    if (argc == 1) {
  1086. X        fprintf (stderr,
  1087. X            "Usage: soundex <string1> <string2> ... <stringN>\n");
  1088. X        exit (-1);
  1089. X    }
  1090. X
  1091. X    for (i = 1; i < argc; i ++) {
  1092. X        soundex (argv[i], sound);
  1093. X        printf ("%s\n", sound);
  1094. X    }
  1095. X}
  1096. X
  1097. Xsoundex (word, sound)
  1098. Xchar    word[],        /* String to convert to SOUNDEX */
  1099. X    sound[];    /* Output SOUNDEX */
  1100. X{
  1101. X    int    outpos,        /* Current output position in SOUNDEX */
  1102. X        j;        /* Index into word */
  1103. X
  1104. X    /* Initialize return word */
  1105. X    outpos = 0;
  1106. X    sound[outpos] = '\0';
  1107. X
  1108. X    /* If the word is null, then the output should be null */
  1109. X    if (strlen(word) == 0)
  1110. X        return;
  1111. X
  1112. X    /* Copy first character of word to SOUNDEX */
  1113. X    sound[outpos] = toupper (word[0]);
  1114. X
  1115. X    for (j = 1; j < strlen (word); j ++) {
  1116. X
  1117. X        /* Convert each character to uppercase */
  1118. X        word[j] = toupper(word[j]);
  1119. X
  1120. X        switch (word[j]) {
  1121. X
  1122. X        /* Replace Labials with "1" */
  1123. X        case 'B':
  1124. X        case 'F':
  1125. X        case 'P':
  1126. X        case 'V':
  1127. X            if (sound[outpos] != '1') {
  1128. X                outpos ++;
  1129. X                sound[outpos] = '1';
  1130. X            }
  1131. X            break;
  1132. X
  1133. X        /* Replace Gutterals & sibilants with "2" */
  1134. X        case 'C':
  1135. X        case 'G':
  1136. X        case 'J':
  1137. X        case 'K':
  1138. X        case 'Q':
  1139. X        case 'S':
  1140. X        case 'X':
  1141. X        case 'Z':
  1142. X            if (sound[outpos] != '2') {
  1143. X                outpos ++;
  1144. X                sound[outpos] = '2';
  1145. X            }
  1146. X            break;
  1147. X
  1148. X        /* Replace Dentals with "3" */
  1149. X        case 'D':
  1150. X        case 'T':
  1151. X            if (sound[outpos] != '3') {
  1152. X                outpos ++;
  1153. X                sound[outpos] = '3';
  1154. X            }
  1155. X            break;
  1156. X
  1157. X        /* Replace Longliquids with "4" */
  1158. X        case 'L':
  1159. X            if (sound[outpos] != '4') {
  1160. X                outpos ++;
  1161. X                sound[outpos] = '4';
  1162. X            }
  1163. X            break;
  1164. X
  1165. X        /* Replace Nasals with "5" */
  1166. X        case 'M':
  1167. X        case 'N':
  1168. X            if (sound[outpos] != '5') {
  1169. X                outpos ++;
  1170. X                sound[outpos] = '5';
  1171. X            }
  1172. X            break;
  1173. X
  1174. X        /* Replace Shortliquids with "6" */
  1175. X        case 'R':
  1176. X            if (sound[outpos] != '6') {
  1177. X                outpos ++;
  1178. X                sound[outpos] = '6';
  1179. X            }
  1180. X            break;
  1181. X        }
  1182. X    }
  1183. X
  1184. X    /* Terminate the soundex string */
  1185. X    outpos ++;
  1186. X    sound[outpos] = '\0';
  1187. X
  1188. X    /* Forcably trunicate soundex to 4 characters */
  1189. X    sound[4] = '\0';
  1190. X}
  1191. X
  1192. !FUNKY!STUFF!
  1193. echo x - trouble.1
  1194. sed '1,$s/^X//' <<\!FUNKY!STUFF! > trouble.1
  1195. X.TH TROUBLE L
  1196. X.SH NAME
  1197. Xtrouble - enter an initial trouble report
  1198. X.SH SYNOPSIS
  1199. X.B trouble
  1200. X.br
  1201. X.SH DESCRIPTION
  1202. X.I trouble
  1203. Xenters the inital trouble report in the trouble report system.  It is
  1204. Xused also by
  1205. X.I followup
  1206. Xto enter all followup trouble reports in the current thread.
  1207. X.PP
  1208. XThis program is self prompting and fairly self explanitory.
  1209. X.sp 1
  1210. X.SH AUTHOR
  1211. XRoland J. Stolfa
  1212. X.br
  1213. XDepartment of Computing and Information Sciences
  1214. X.br
  1215. XOklahoma State University
  1216. X.br
  1217. Xrjs@a.cs.okstate.edu
  1218. !FUNKY!STUFF!
  1219. echo x - trouble.sh
  1220. sed '1,$s/^X//' <<\!FUNKY!STUFF! > trouble.sh
  1221. X:
  1222. X#
  1223. X# Package    : TRS
  1224. X# Module    : trouble.sh
  1225. X# Programmer    : R. Stolfa
  1226. X#
  1227. X# Purpose :    To enter trouble reports into the TRS database system.
  1228. X#
  1229. X# Modification History:
  1230. X#   04/11/88    Created
  1231. X#   04/12/88    Added hooks for recording the new trouble number in the
  1232. X#        environment variable NTN for use in "followup"
  1233. X#   10/25/88    Added user configurable "ROOT" to allow more than
  1234. X#        one TRS on a system
  1235. X#
  1236. X
  1237. X#
  1238. X# Some variables
  1239. X#
  1240. Xumask 000
  1241. Xif [ "$TRSROOT" != "" ]
  1242. Xthen
  1243. X    ROOT=$TRSROOT
  1244. Xelse
  1245. XROOT=/u/rjs/lib/Trs
  1246. Xfi
  1247. XENTRY=$ROOT/Entry
  1248. XLIB=$ROOT/lib
  1249. XSEQ=$ROOT/sequence
  1250. XTEMP=$ROOT/tmp/trs.$$
  1251. Xtrap "rm -f $ROOT/tmp/* ; exit 1" 1 2 15
  1252. X
  1253. Xrm -f $TEMP
  1254. X
  1255. X#
  1256. X# Prompt for what piece of equipment is down.
  1257. X#
  1258. Xequipment=""
  1259. Xwhile [ "$equipment" = "" ]
  1260. Xdo
  1261. X    $LIB/print "Enter equipment ID string? "
  1262. X    read equipment
  1263. Xdone
  1264. Xecho "equipment=$equipment" >> $TEMP
  1265. X
  1266. X#
  1267. X# Get the keywords to link the file in "Entry" to under each
  1268. X# of their respective "SOUNDEX" equivalents.
  1269. X#
  1270. Xecho "Enter the keywords that are to be associated with this"
  1271. Xecho "report one per line, ending with a blank line."
  1272. X$LIB/print "keywords=" >> $TEMP
  1273. Xkeywords=""
  1274. Xdummy="+"
  1275. Xwhile [ "$dummy" != "" ]
  1276. Xdo
  1277. X    read dummy
  1278. X    if [ "$dummy" != "" ]
  1279. X    then
  1280. X        $LIB/print "$dummy " >> $TEMP
  1281. X        keywords="$keywords`$LIB/soundex $dummy` "
  1282. X    fi
  1283. Xdone
  1284. Xecho "" >> $TEMP
  1285. X
  1286. X#
  1287. X# Enter the report.
  1288. X#
  1289. Xecho "Enter report, ending with a blank line"
  1290. Xdummy="+"
  1291. Xwhile [ "$dummy" != "" ]
  1292. Xdo
  1293. X    read dummy
  1294. X    if [ "$dummy" != "" ]
  1295. X    then
  1296. X        echo "desc=$dummy" >> $TEMP
  1297. X    fi
  1298. Xdone
  1299. X
  1300. X#
  1301. X# Attempt to link in to "Entry" directory.  This could be an area
  1302. X# of contension (for the sequence file).  The following sheme was
  1303. X# choosen to give some reasonable operation.
  1304. X#
  1305. Xcond=1
  1306. Xwhile test $cond -ne 0
  1307. Xdo
  1308. X    entry="`date '+%y%m%d'`.`cat $SEQ`"
  1309. X    seq=`cat $SEQ`
  1310. X    expr $seq + 1 > $SEQ
  1311. X    ln $TEMP $ENTRY/$entry
  1312. X    cond=$?
  1313. X    if test $cond -ne 0
  1314. X    then
  1315. X        echo "Collision.  Attempting fix..."
  1316. X    fi
  1317. Xdone
  1318. Xrm $TEMP
  1319. X
  1320. X#
  1321. X# Report the "trouble ticket" number for future 'threading'.
  1322. X#
  1323. Xecho " "
  1324. Xecho "Your trouble ticket number is $entry"
  1325. Xecho "save this number for future reference."
  1326. X
  1327. X#
  1328. X# Record the new trouble number in the environment variable NTN.
  1329. X#
  1330. XNTN=$entry
  1331. X
  1332. X#
  1333. X# Now link the "Entry" directory trouble report to a file with
  1334. X# the same timestamp.sequence filename in a directory for each of
  1335. X# the "SOUNDEX" keywords.  This is in an attempt to make the
  1336. X# system easier to search.
  1337. X#
  1338. Xfor i in $keywords
  1339. Xdo
  1340. X    $LIB/mkpath $ROOT/$i/$entry
  1341. X    ln $ENTRY/$entry $ROOT/$i/$entry
  1342. Xdone
  1343. X
  1344. X#
  1345. X# Ok.  Let's be clean...
  1346. X#
  1347. Xrm -f $TEMP
  1348. !FUNKY!STUFF!
  1349.  
  1350.  
  1351.