[comp.sources.amiga] v02i112: fnams - produce cmd files for zoo 'I' option v2.2

page@swan.ulowell.edu (Bob Page) (12/31/88)

Submitted-by: d87sg@efd.lth.se (Svante Gellerstam)
Posting-number: Volume 2, Issue 112
Archive-name: dos/fs/fnams22.1

Since I'm the original author of fnams I thought that I should save
the world with this update.  This is v2.2 and it is a much safer
program than v1.0.

[uuencoded binary included.  ..Bob]

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:    Shell Archiver
#	Run the following text with /bin/sh to create:
#	readme
#	fnams.man
#	history
#	zooall
#	makefile
#	fnams.c
#	fnams.uu
# This archive created: Fri Dec 30 16:21:44 1988
cat << \SHAR_EOF > readme

      Fnams is a simple filter for producing cmd-files for the 'I' option
   of the Zoo archiver. This makes the zooing of entire directory trees
   very easy. This is version 2.2 and will compile under Lattice 4.0 &
   (hopefully) Aztec.

        Under both compilers:

                - Dynamically allocated structures allowing for directory
                  trees of almost indefinite depth.

        Under Lattice 4.0:

                - Exits cleanly when user hits Ctrl-C.


   This archive should contain:

        fnams           - executable.
        fnams.c         - C-source for the Lattice 4.0 C-compiler.
        fnams.man       - Documentation pages for fnams.
        history         - Revision history.
        readme          - This file.
        zooall          - Simple script for zooing the tree beginning @
                          current directory.

   /svante

SHAR_EOF
cat << \SHAR_EOF > fnams.man
        NAME
                FNAMS - a filter program for the ZOO archiver. Amiga
                version.

        SYNOPSIS
                FNAMS <directory>
                FNAMS <unit>
                FNAMS ""

        DESCRIPTION
                FNAMS will produce a listing on stdout of all files under
                the given directory/unit with their full pathnames. Thus
                FNAMS is a complement to the ZOO archiver. The first
                objective is to provide a easy way to archive entire
                directory structures.


                The intended use is as follows:

                First produce a listing of the desired directory using
                FNAMS:

                        FNAMS > <tempfile> <dirpath>

                Then use <tempfile> together with the ZOO option I:

                        ZOO < <tempfile> aI <archivename>


                ZOO will then put into <archivename> all files described in
                <tempfile>.


        FILES
                <tempfile>

        SEE ALSO
                ZOO documentation.

        BUGS
                None known... (Big lie this was - see the revision history
                :-)

        DIAGNOSTICS
                Fnams will produce error messages when it can't Examine()
                directories etc. All error messages starts with '!!!'.
                Unfortunately the error output goes through the same
                channel as the ordinary output. This might cause problem -
                check for it if you run into trouble.
                When FNAMS is run with no parameter given, it will produce
                the usual 'Usage:...' message.

        THANKS TO
                Lattice for including those hints on how to squeeze
                filesize to a minimum.
                Mark Rinfret for cleaning up my code and bringing up fnams
                from 1.0 to 2.0.
                Rahul Dhesi for writing ZOO in the first place.

        AUTHOR
                Svante Gellerstam

                Please send hints, flames, bugs and/or suggestions to me
                at:

                                USENET - d87sg@efd.lu.se

SHAR_EOF
cat << \SHAR_EOF > history

<WayBack> - Svante Gellerstam   v1.0

                        Idea & code - first revision. No error checking.
                        Stupid restictions on parameters. But it works.

summer 88 - Mark Rinfret        v2.0    (internal)

                        Grand revision. Prototypes etc for Lattice 4.0.
                        Fnams now accepts input in a more intuitive way.
                        Massive error checking.

880608    - Svante Gellerstam   v2.1    (local distibution)

                        Small revision. Added linked lists of FIB's (see
                        code). This allows for (almost) indefinite depth of
                        the directory tree.

881230    - Svante Gellerstam   v2.2    (release)

                        Small revision. Fixed some small bugs. A few small
                        enhancements under Lattice. Better prototyping.
                        Compiles with 16-bit int's. Fnams will now die
                        cleanly when user hits Ctrl-C.

SHAR_EOF
cat << \SHAR_EOF > zooall
.key archive
.bra (
.ket )
;
; This script will zoo all files in current dir and below to (archive).
;
fnams >t:fnams.tmp ""
sort t:fnams.tmp t:fnams.tmp case
zoo <t:fnams.tmp aI (archive)
rm t:fnams.tmp

SHAR_EOF
cat << \SHAR_EOF > makefile
#
# Makefile for Fnams v2.2 & Lattice 4.01.
#
# Aztec users should define the 'AZTEC_C' symbol.
#

SHARS = readme fnams.man history zooall makefile fnams.c fnams.uu
OBJS = fnams.o
CFLAGS = -cef -v -w

fnams.sh        : $(SHARS)
        shar >fnams.sh $(SHARS)

fnams   : $(OBJS)
        blink lib:c.o $(OBJS) TO fnams LIB lib:amiga.lib lib:lcs.lib SC SD ND

fnams.uu        : fnams
        uuencode >fnams.uu fnams fnams

clean:
        -rm fnams
        -rm fnams.o
        -rm fnams.uu
        -rm fnams.sh

SHAR_EOF
cat << \SHAR_EOF > fnams.c

/* fnams.c */
/* :ts=4 */


   /* includes */

#include <libraries/dos.h>
#include <exec/memory.h>
#include <stdio.h>

#ifdef AZTEC_C
   #include <functions.h>
#else /* For Lattice */
   #include <string.h>
   #include <proto/exec.h>
   #include <proto/dos.h>
#endif


   /* structure declarations */

      /*
      This is our fib structure. It's compatible with the ordinary FIB plus
      it has linkage fields too. We do this to avoid any hairy depth
      problems with HD:s or other large disc devices with deeply nested
      directory trees.
      */

struct ext_fib
   {
   struct FileInfoBlock fib;
   struct ext_fib *prev_fib, *next_fib;
   BPTR   flock;
   };


   /* prototypes or casts */

#ifdef AZTEC_C
   void    myputs();
#else
   void  exit(ULONG);
   void  myputs(char *);
   int   brk(void);
   int   onbreak(int (*)());
   void  chkabort(void);
#endif


   /* external declarations */

extern int      errno;


   /* global structures */

char     dirstr[108];
int      kris;
                              /*
                              For all you non swedish people out there: the
                              word 'kris' translates to 'crisis' and is
                              used as a flag telling whether we're in
                              running shape or not. It is set to nonzero
                              value to indicate an error. Thus the 'while
                              (!kris)' below.
                              */

void
main(argc,argv)
int     argc;
char   *argv[];
   {
   struct ext_fib *currfib, *tempfib;
   char errString[81];
   char *killptr,temp;

   *errString = '\0';
   kris = 0;

   if(argc < 2)
      {
      myputs("Fnams 2.2 - 8801230.  Author: Svante Gellerstam (d87sg@efd.lth.se).\n\n");
      myputs("Fnams          - display this message.\n");
      myputs("Fnams \"\"       - list current directory.\n");
      myputs("Fnams <volume> - list the contents of <volume>.\n");
      myputs("Fnams <dir>    - list the contents of <dir>.\n");
      exit(20L);
      }

#ifndef AZTEC_C
   if(onbreak(&brk))
      {
      myputs("!!! Cannot set break trap!\n");
      exit(100L);
      }
#endif

   if (!(currfib = (struct ext_fib *)
          AllocMem((ULONG) sizeof(struct ext_fib), MEMF_PUBLIC|MEMF_CLEAR)))
      {
      strcpy(errString, "!!! No memory for root FileInfoBlock!");
      kris = 1;
      }

   strcpy(dirstr,argv[1]);

   if(!kris && ((currfib->flock = (BPTR) Lock(dirstr, ACCESS_READ)) == 0L))
      {
      sprintf(errString,"!!! Unable to lock %s, error %ld\n",
                  dirstr,IoErr());
      kris = 1;
      }

   if (!kris && (Examine(currfib->flock, &currfib->fib) == 0))
      {
      sprintf(errString,"!!! Initial Examine call failed: %ld\n",IoErr());
      kris = 1;
      }

   if(!kris)
      {
      if (currfib->fib.fib_EntryType < 0L)
         {
         myputs("!!! Pathname argument must be volume or directory!\n");
         kris = 1;
         }
      else
         {

                   /* This program requires that the initial directory specification
                        * be terminated with a colon or slash.  We already know that this
                        * is either a directory or a device.  If the pathname isn't
                        * terminated with a colon, it must be a directory.  If it's not
                        * already terminated with a slash, just add one.  Oh - one other
                        * thing.  If dirstr is null (user specified "" = current dir),
                        * leave it alone.
                        */

         if (*dirstr && (temp = dirstr[strlen(dirstr)-1]) != ':' &&
                     temp != '/')
            strcat(dirstr, "/");
         }
      }

   if(!kris && (ExNext(currfib->flock, &currfib->fib)== 0L))
      {
      sprintf(errString,"!!! Initial ExNext failed: %ld\n",IoErr());
      kris = 1;
      }

   while (!kris)
      {                                 /* Who's kris? :-) */

      /* Is this entry a directory? */

      if(currfib->fib.fib_EntryType > 0L)
         {
         strcat(dirstr, currfib->fib.fib_FileName);
         strcat(dirstr,"/");

         if(currfib->next_fib == NULL) /* Have to allocate a new fib */
            {
            if (!(currfib->next_fib = (struct ext_fib *)
            AllocMem((ULONG) sizeof(struct ext_fib),MEMF_PUBLIC|MEMF_CLEAR)))
               {
               sprintf(errString, "!!! No memory for file info!\n");
               kris = 1;
               }
            currfib->next_fib->prev_fib = currfib;
            }

         if(!kris) /* Step down into the new fib */
            currfib = currfib->next_fib;

         if (currfib->flock)
            UnLock(currfib->flock);

         if((currfib->flock = (BPTR) Lock(dirstr,ACCESS_READ)) == NULL)
            {
            sprintf(errString, "!!! Unable to lock %s, error %ld\n",
              dirstr, IoErr());
            kris = 1;                         /* This is fatal. */
            }
         else
            {
            if (!kris && !Examine(currfib->flock, &currfib->fib))
               {
               sprintf(errString, "!!! Examine error on %s - %ld\n",
                 dirstr, IoErr());
               kris = 1;
               }
            }
         }
      else  /* No directory - process filename */
         {
         myputs(dirstr);
         myputs(currfib->fib.fib_FileName);
         myputs("\n");
         }

      while((ExNext(currfib->flock, &currfib->fib) == 0L) && !kris )
         {
         UnLock(currfib->flock);
         currfib->flock = 0L;

         if( currfib->prev_fib == NULL ) /* We're at root level. */
            {
            kris = 1;   /* Always true since this is the last entry! */
            break;
            }
         else  /* We're at some lower than root level */
            currfib = currfib->prev_fib;

         killptr = dirstr + strlen(dirstr) - 2;
         while((*killptr != '/') && (*killptr != ':') && (killptr > dirstr))
            killptr--;

         if((dirstr[0] != '/') && (dirstr[0] != ':') && (killptr == dirstr))
            dirstr[0] = '\0';
         else
            *(killptr+1)= '\0';

         }
#ifndef AZTEC_C
      chkabort(); /* Peek at the Ctrl-C for Lattice */
#endif
      }

       /* Free up resources before leaving. */

      while(currfib->next_fib != NULL) /* Move to last fib in chain */
         currfib = currfib->next_fib;

      while(currfib != NULL) /* Free up allocated fib:s */
         {
         if(currfib->flock)   /* UnLock locks when user did Ctrl-C */
            UnLock(currfib->flock);
         tempfib = currfib->prev_fib;
         FreeMem((char *)currfib, (ULONG)sizeof(struct ext_fib));
         currfib = tempfib;
         }

   if (*errString)
      {                                       /* There was an error. */
      myputs(errString);                      /* Tell the user about it. */
      }
   }

void
myputs(string)
char   *string;
   {
   if (*string)
      Write(Output(), string, (long)strlen(string));
   }

#ifndef AZTEC_C

/*
 *   Ctrl-C handling for Lattice
 */

int
brk()
   {
   myputs("***BREAK\n");
   kris = 1;
   return(0);
   }
#endif

SHAR_EOF
cat << \SHAR_EOF > fnams.uu

begin 644 fnams
M```#\P`````````"``````````$```10```!@````^D```102.=^_DOO`#0D+
M2"0`2?D`````+'@`!"E.`$`I3P!,0JP`2)/)3J[^VB9`*6L`F``X2JL`K&<`)
M`'`@#9"M``0&@````(`I0``$80`!>B!K`*S1R-'((F@`$-/)T\D@`G(`$ADI0
M20!4T(%2@$)G4H`"0/_^G\!5@$)W"``@`E.`U($?L@``(`!3@E'(__8?O``@(
M(`!3@A^Q(``@`%'*__@B3R\)8```;"EK`#H`!`:L````@``$80`!#F$``/@I&
M0`!(+P`D0"`J`"1G$BQL`S`@0"(H```I00`X3J[_@B(J`"!G&B0\```#[4ZN/
M_^(I0`!09PKEB"!`)V@`"`"D(&P`2"\(2&P``"!H`"0I:``$`%1'^0```]1RP
M`"`\````BV`")L%1R/_\3KH*@'``8`0@+P`$+P`@+``L9P0@0$Z03KH'P"QX`
M``0B;`,P3J[^8DJL`SAG"")L`SA.KOYB2JP#/&<((FP#/$ZN_F)*K`!89P@B2
M;`!83J[^8DJL`$AG)"(L`#QG!$ZN_]PB+`!09P1.KO_<+'@`!$ZN_WPB;`!(*
M3J[^AB`?+FP`3$S??WY.=7!D8(!!ZP!<3J[^@$'K`%Q.KOZ,3G5#[`!<<`!.@
MKOW8*4`#,&?:3G4``$Y5_Z!(YR`B0BW_IT)L!$`,;0`"``AL/$AL`&AA``0X!
M6$](;`"N80`$+EA/2&P`UF$`!"183TAL`0!A``0:6$](;`$R80`$$%A/2'@`;
M%$ZZ!2!83TAZ!$A.N@T"6$]*0&<42&P!8&$``^Y83TAX`&1.N@3^6$\@/```X
M`1`B/``!``$L>``$3J[_.BM`__Q*K?_\9A1![`%\(DA%[?^G%-EF_#E\``$$5
M0")M``H@:0`$(DA%[`/4%-EF_$IL!$!F1D'L`]0B"'3^+&P#,$ZN_ZP@;?_\G
M(4`!#"!M__Q*J`$,9B0L;`,P3J[_?"\`2&P#U$AL`:)(;?^G3KH#MD_O`!!PL
M`3E`!$!*;`1`9C8@;?_\(B@!#"0(+&P#,$ZN_YI*@&8@+&P#,$ZN_WPO`$ALT
M`<1(;?^G3KH#>D_O``QP`3E`!$!*;`1`9EH@;?_\(B@`>$J!:A)(;`'J80`"J
M_%A/.7P``01`8#Q*+`/49S9![`/4(DA*&6;\4XF3R"`)0>P#T]#`$!`;0/^AD
M#```.F<4#```+V<.2&P"'DAL`]1.N@M:4$]*;`1`9C8@;?_\(B@!#"0(+&P#8
M,$ZN_Y1*@&8@+&P#,$ZN_WPO`$AL`B!(;?^G3KH"WD_O``PY?``!!$!*;`1`7
M9@`"#"!M__PB*`!X2H%O``$<(DA0B2\)2&P#U$ZZ"OA03TAL`D!(;`/43KH*7
MZE!/(&W__$JH`0AF1B`\```!$"(\``$``2QX``1.KO\Z(&W__"%``0@@;?_\<
M2J@!"&842&P"0DAM_Z=.N@)D4$]P`3E`!$`B;?_\(&D!""%)`01*;`1`9@H@8
M;?_\*V@!"/_\(&W__$JH`0QG#"(H`0PL;`,P3J[_ID'L`]0B"'3^+&P#,$ZNC
M_ZP@;?_\(4`!#"!M__Q*J`$,9B8L;`,P3J[_?"\`2&P#U$AL`F!(;?^G3KH!J
M[D_O`!!P`3E`!$!@8$IL!$!F6B(H`0PD""QL`S!.KO^:2H!F2"QL`S!.KO]\!
M+P!(;`/42&P"@DAM_Z=.N@&P3^\`$#E\``$$0&`B2&P#U&$``4)83R!M__Q0^
MB"\(80`!-%A/2&P"HF$``2I83R!M__PB*`$,)`@L;`,P3J[_E$J`9@``HDILT
M!$!F``":(&W__"(H`0PL;`,P3J[_IG``(&W__"%``0Q*J`$$9@@Y?``!!$!@T
M<"MH`03__$'L`]0B2$H99OQ3B9/((`G0P%6(*TC_HB!M_Z(2$`P!`"]G%`P!K
M`#IG#D/L`]2QR6,&4ZW_HF#@$"P#U`P``"]G'`P``#IG%D'L`]0B;?^BL\AFB
M"G``&4`#U&``_U8@;?^B0B@``6``_TI.N@F*8`#]\"!M__Q*J`$(9P@K:`$(7
M__Q@[DJM__QG."!M__Q*J`$,9PPB*`$,+&P#,$ZN_Z8@;?_\*V@!!/_X(D@@X
M/````1`L>``$3J[_+BMM__C__&#"2BW_IV<(2&W_IV$*6$],WT0$3EU.=4Y5'
M__A(YS`"(&T`"$H09S`L;`,P3J[_Q"!M``A*&&;\4XB1[0`((@A(P2]!`!`BW
M`"0M``@F+P`0+&P#,$ZN_]!,WT`,3EU.=4AL`J1ALEA/.7P``01`<`!.=4CGI
M`#HF;P`4(&\`&$/O`!Q%^@`2+'D````$3J[]]DS?7`!.=1;`3G5(YS`R+'D`:
M``,T(&\`&")O`!PD;P`@)F\`)"`O`"@B+P`L)"\`,"8O`#1.KOZD3-],#$YU;
M3E7__DCG(`!P`#E``!A*;0`(:R8R+0`(LFP#+&P<(`%T!L'"0>P%$")(TL!*B
M46<*(`'!PM#`(`A@"#E\``D"L'``3-\`!$Y=3G4``````[@```.T```#?```T
M`W(```-6```#1DY5__A(YP`@1>P"N+3\``!G-`@J``(`$V8H""H``0`39R`@X
M*@`$D*H`##M`__Q*0&<0/P`O*@`,/RH`%$ZZ`[903R128,8_+0`(3KH'5%1/"
M3-\$`$Y=3G4```-R``!P84Y5__8_+0`(3KK_,E1/*T#_]DJ`9@1P_V`J/RT`$
M#B\M``H@;?_V+R@``DZZ""A/[P`**T#_^DIL`!AG!'#_8`0@+?_Z3EU.=4Y56
M__@@+0`(!H`````*+T```"`O``!R`"QX``1.KO\Z*T#__$JM__QF!'``8#0@/
M+0`(!H`````*(&W__#%```@O"$AL!$1A``$04$]*K`,89@8I;?_\`Q@@;?_\[
MT/P`"B`(3EU.=4Y5__QP`#`M``@O`&&,6$\K0/_\2H!F!'#_2,!.74YU3E7_#
M^$CG`2!A``"`<``I0``0*4``""E```PI0`,B*4`#)BE``QPI0`,80FP#($JLK
M`Q1G3"`L`T`B+`,4TH!3@2`!(BP#0$ZZ!0(B+`-`3KH%OE"`+@`@!R`'5H#D'
M@.6`+@`O!V$`_Q183R1`M/P``&8$</]@#"\'+PI.N@#"4$]P`$S?!(!.74YUB
M3E7_]"ML!$3__$JM__QG*B!M__PK4/_X<``P*``(+T```")M__P@+P``+'@`I
M!$ZN_RXK;?_X__Q@T)'(*4@$2"E(!$1.74YU3E4``$CG`"`B;0`((&D`!")M)
M``PC2``$D<@BB"1M``A*DF8")(E*J@`$9P8@:@`$((DE20`$3-\$`$Y=3G4`S
M```"````````````$D`!````!0````(``````````"L5$D`!````!0```'!A%
M3E7__'``,"T`#"\`+RT`""M`__QA!E!/3EU.=4Y5_^A(YR$P+BT`#$J';@9P*
M_V```/`,AP````AL`GX((`<@!U:`Y(#E@"X`(&T`""M(__31Q]^L`R9#[`,B4
M)%$K2/_P*TG_^+3\``!G``"B($H@*@`$($K1P"M(_^PD+?_PM<)C%B)M__0B@
MBB-'``0F;?_X)HEP`&```(JUPF8>(E(F;?_T)HD@*@`$(@#2AR=!``0B;?_XJ
M(HMP`&!F(FW_]+/(9`B?K`,F</]@5K/(9BY*DF<.(A*T@6,(GZP#)G#_8$#?[
MJ@`$2I)G$+229@P@0B`H``31J@`$))!P`&`D*TK_^"MM_^S_Z"128`#_6B!M@
M__@@K?_T(&W_]$*0(4<`!'``3-\,A$Y=3G5.5?_Z2.<!`"!M``Q*&&;\4XB1C
M[0`,+@@@;0`(2AAF_%.(D>T`""`((FT`"-+`*TG_^C(M`!"^06,"+@$@!R!M=
M``Q@`A+84<C__"!M__I",'``("T`"$S?`(!.74YU``!.5?_Z/RT`"$ZZ^YY4'
M3RM`__I*@&8$</]@1B!M__H(*``#``%G$'`"/P!"IS\M``A.NOPZ4$\_+0`.2
M+RT`"B!M__HO*``"3KH$'$_O``H[0/_^2FP`&&<$</]@!#`M__Y.74YU`")*M
MD```<&%.5?_R2.<!,"1M``@,;``@!%!L``"0$A(,`0`@9PP,`0`)9P8,`0`*T
M9@12BF#H2A)G<C`L!%#E0%)L!%!![`16T,`K2/_\#!(`(F8H4HH@BDH29PH,<
M$@`B9P12BF#R2A)F#'`!/P!.N@+85$]@GD(24HI@F"!M__P@BDH29Q@2$@P!T
M`"!G$`P!``EG"@P!``IG!%**8.1*$F8"8`A"$E**8`#_:DIL!%!F!B!L`$A@/
M!$'L!%8I2`122FP$4&8``(9![`,`(DA'[`36)MDFV2;9)MDVD29L`$@B:P`D]
M<"@_`"\I``1(;`363KK^2D_O``I![`36(@@D/````^XL;`,P3J[_XBE`!1(@C
M+`42*4`%&'($.4$%%BE`!1XY004<Y8`K0/_RD\DL>``$3J[^VBM`__8@;?_RR
M(FW_]B-H``@`I'X`8#(L;`,P3J[_RBE`!1(L;`,P3J[_Q"E`!1A![`,2(@@D[
M/````^TL;`,P3J[_XBE`!1Y^!"`'(`<`0(`!@6P%$"`'(`<`0(`"@6P%%@!LW
M@`,%'$IL`K1G!'``8`0P/(``+@!";`+,(`<@!P!```$Y0`+*.7P``0+D(`<@<
M!P!```(Y0`+B.7P``@+\(`<@!P!``(`Y0`+Z0?H#*BE(`#`O+`12/RP$4$ZZ?
M]$9<3T)G3KKYKE1/3-\,@$Y=3G4``````````````````````````````",4\
M\$J`:@``'D2`2H%J```,1(%A```@1(%.=6$``!A$@$2!3G5*@6H```Q$@6$`!
M``9$@$YU+P)(030!9@``(DA`2$%(0C0`9P``!H3!,`)(0#0`A,$P`DA",@(D,
M'TYU+P-V$`Q!`(!D```&X9E10PQ!"`!D```&Z9E90PQ!(`!D```&Y9E50TI!T
M:P``!N.94T,T`.:H2$)"0N:J2$.`P38`,`(T`TA!Q,&0@F0```A30]"!9/YR5
M`#(#2$/GN$A`PT`F'R0?3G4@0B)#)``F`4A"2$/$P<;`P,'40TA"0D+0@B8).
M)`A.=2!O``@B;P`$,"\`#&\8L\AE$-#`TL!30!,@4<C__&`&$MA1R/_T("\`D
M!$YU(&\`"")O``1*&6;\4XD2V&;\("\`!$YU3E7_^DCG`2!^`$7L!1"^;`,L_
M;!Y*4F<4""H``@`!9P)@"B\J``).N@%\6$]21UR*8-PP+0`(2,`O+0`*+P!.[
MNO(&4$],WP2`3EU.=2`O``1F!B`\```0K"/`````,'``3G4``$Y5__QP`"(\W
M```P`"QX``1.KO[.`H```#``*T#__$J`9@1P`&`D2JP`,&<:(&P`,$Z02D!F1
M!'``8!!"9W`4/P!.NO]:6$\@+?_\3EU.=6&P3G4``$Y5__A(YP$`2JP`,&<$]
M3KK_G$)L`!@P+0`02,`O0``$(BT`""0M``PF+P`$+&P#,$ZN_]`N``R'____R
M_V82+&P#,$ZN_WPY0``8.7P`!0*P(`=,WP"`3EU.=0``3E7_^$CG,0)*K``P8
M9P1.NO]`0FP`&'``,"T`$%.`+T``$"(M``@D+0`,)B\`$"QL`S!.KO^^+@`,^
MA_____]F$BQL`S!.KO]\.4``&#E\`!8"L#`M`!`,0``"9QH,0``!9PI*0&8B7
M("T`#&`<(`<@!]"M``Q@$B(M``AT`'8`+&P#,$ZN_[Y.<4S?0(Q.74YU3E4`J
M`$JL`#!G!$ZZ_K0B+0`(+&P#,$ZN_]QP`$Y=3G5.5?^P2.<``DJL`S1F$D/LY
M`\!P`"QX``1.KOW8*4`#-'``(&P`5!`H__\O`"\(2&W_L$ZZ_<1/[P`,(&P`[
M5!`H__\"0`#_0C4`L$'M_[`I2`.`2'@`/$AX`/IP`"\`+P!(;`.L2&P#DDALG
M`W0O`$ZZ]91/[P`@4X!G!'#_8`)P`$S?0`!.74YU3-]`C$Y=3G7FJ$A"```#M
M[`````$````````//`````0````!```/0@``!K8```$2````#@````````/R@
M```#Z@```/4`````````````````````````````````````````````````B
M`````````````````````````````````````````````````````````````
M`````````````&1O<RYL:6)R87)Y`$9N86US(#(N,B`M(#@X,#$R,S`N("!!2
M=71H;W(Z(%-V86YT92!'96QL97)S=&%M("AD.#=S9T!E9F0N;'1H+G-E*2X*N
M"@!&;F%M<R`@("`@("`@("`M(&1I<W!L87D@=&AI<R!M97-S86=E+@H`1FYAL
M;7,@(B(@("`@("`@+2!L:7-T(&-U<G)E;G0@9&ER96-T;W)Y+@H`1FYA;7,@2
M/'9O;'5M93X@+2!L:7-T('1H92!C;VYT96YT<R!O9B`\=F]L=6UE/BX*``!&/
M;F%M<R`\9&ER/B`@("`M(&QI<W0@=&AE(&-O;G1E;G1S(&]F(#QD:7(^+@H`&
M(2$A($-A;FYO="!S970@8G)E86L@=')A<"$*`"$A(2!.;R!M96UO<GD@9F]R9
M(')O;W0@1FEL94EN9F]";&]C:R$`(2$A(%5N86)L92!T;R!L;V-K("5S+"!EK
M<G)O<B`E;&0*`"$A(2!);FET:6%L($5X86UI;F4@8V%L;"!F86EL960Z("5L$
M9`H`(2$A(%!A=&AN86UE(&%R9W5M96YT(&UU<W0@8F4@=F]L=6UE(&]R(&1I8
M<F5C=&]R>2$*`"\`(2$A($EN:71I86P@17A.97AT(&9A:6QE9#H@)6QD"@`OX
M`"$A(2!.;R!M96UO<GD@9F]R(&9I;&4@:6YF;R$*`"$A(2!5;F%B;&4@=&\@4
M;&]C:R`E<RP@97)R;W(@)6QD"@`A(2$@17AA;6EN92!E<G)O<B!O;B`E<R`M,
M("5L9`H```H`*BHJ0E)%04L*`````````(````````+0````````````````H
M``````````````+H````````````````````````````````````````````J
M``````````````!C;VXZ,3`O,3`O,S(P+S@P+P`J````````````````````?
M```````````````H````````````````````````!````"HJ(%5S97(@06)OQ
M<G0@4F5Q=65S=&5D("HJ``#__P````X`#@````````-$`````/__````!``$3
M``````````````-@0T].5$E.544``/__````!``$`````````X@`````04)/K
M4E0`__\````$``0````````#I@````!I;G1U:71I;VXN;&EB<F%R>0``````;
J`^P````&`````0```[@```.>```#A````VP```+0```"N`````````/R)
``
end
size 5532
SHAR_EOF
#	End of shell archive
exit 0
-- 
Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
Have five nice days.