[comp.sources.amiga] v89i202: sweep - do commands on a directory tree

page%swap@Sun.COM (Bob Page) (11/13/89)

Submitted-by: utoddl@uncecs.edu (Todd M. Lewis)
Posting-number: Volume 89, Issue 202
Archive-name: dos/fs/sweep.1

SWEEP takes CLI commands and executes them in the current directory and
in all directories below the current directory.
  * The directory tree can be traversed top-down or bottom-up.
  * Multiple commands can be issued.
  * I/O streams can be redirected for SWEEP and the executed commands.

[uuencoded executable included. ..bob]

# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
#	makefile
#	sweep.c
#	sweep.doc
#	sweep.uu
# This is archive 1 of a 1-part kit.
# This archive created: Sun Nov 12 17:49:40 1989
echo "extracting makefile"
sed 's/^X//' << \SHAR_EOF > makefile
Xsweep: sweep.o
X    ln sweep.o -lc
X
Xsweep.o: sweep.c
X    cc sweep.c
X
SHAR_EOF
echo "extracting sweep.c"
sed 's/^X//' << \SHAR_EOF > sweep.c
X#include <stdio.h>
X#include <exec/memory.h>
X#include <functions.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X
X#define MAXCMDLEN  1024L
X
Xint   cmdTooLong;
Xchar  cmdstr[MAXCMDLEN+1]; /* This is where we put the command string.      */
Xchar  firstchar;           /* '-' Do a pre-order tree traversal.            */
X                           /* '+' Do a post-order tree traversal. (default) */
X                           /* '?' Show command usage.                       */
X                           /* Otherwise, it is part of the command string.  */
X
X/* NOTE: dos.library is openned by the compiler startup code.
X * _cli_parse() is called during program startup to parse the command line.
X * We don't really want the command line parsed, so we replace it with our own
X * parser.  This works with Manx C.  I don't know what you would do to
X * make it work with Lattice.
X */
X
Xvoid _cli_parse( pp, alen, aptr )
X  struct Process *pp;               /* Program's process structure */
X  long            alen;             /* Length of the command string */
X  char           *aptr;             /* The command string itself */
X  {
X    long   i, j;
X    char *p;
X
X    p         = aptr;
X    firstchar = *p;
X    j         = alen;
X
X    switch (*p) {
X       case '-' :
X       case '+' :
X       case '?' : p += 1; j -= 1; break;
X       default  : ;
X       }
X
X    if ( alen < MAXCMDLEN ) {
X         cmdTooLong = 0;
X         for( i=0; i<j; i++)    /* Copy the pertinent parts of the command   */
X             cmdstr[i] = p[i];  /* string to our buffer.  Make sure it fits. */
X         cmdstr[i] = '\0';      /* Tack on a null char, just to be safe.     */
X         }
X       else
X         cmdTooLong = 1;
X
X    }
X
X/*
X * _wb_parse() is called by Manx startup. Since we are only running from
X * the CLI, we can stub this out and reduce our program size.
X */
X
Xvoid _wb_parse() { }
X
X
Xvoid Syntax()
X{
X   printf("Sweep: Execute CLI command(s) in current directory and all\n"
X          "       subdirectories.                           tml 11/89\n\n");
X   printf("USAGE: SWEEP [+|-|?] cmd [ + \n cmd... ]\n\n"
X          " '+'  Do a post-order (bottom up) tree traversal.  (default)\n"
X          " '-'  Do a pre-order  (top  down) tree traversal.\n");
X   printf(" '?'  Show command usage.  (this display)\n"
X          " cmd  Command(s) you want executed in each directory.\n"
X          "      Multiple commands can be issued as with the RUN command.\n");
X   }
X
Xmain()
X{
X
X    if (firstchar == '?') {
X        Syntax();
X        exit();
X        }
X
X    doDir( "\0" );
X    }
X
XdoDir( topDirName )
X  char *topDirName;
X  {
X    struct FileLock *topLock, *tmpLock;
X    struct FileInfoBlock *fib;
X
X
X    /* Get a lock on the Current Directory */
X    topLock = Lock( topDirName, ACCESS_READ );
X
X    if (topLock == NULL) {
X        return();
X        }
X
X    tmpLock = CurrentDir( topLock );
X
X    if (firstchar == '-')                /* Do a pre-order traversal. */
X       Execute( cmdstr , 0L, Output() );
X
X    /* The FileInfoBlock structure has to be long-word alligned, so */
X    /* we should use AllocMem to insure this condition is met.      */
X
X    fib = AllocMem( (long) sizeof( struct FileInfoBlock ), MEMF_PUBLIC );
X
X    if ( Examine( topLock, fib ) )  /* We know this is our mother dir, so */
X                                    /* don't recurse on this one.         */
X       while ( ExNext( topLock, fib) ) {
X            if ( fib->fib_DirEntryType > 0 ) {      /* It's a directory */
X                    doDir( fib->fib_FileName);
X                    }
X            };
X
X    if (firstchar != '-')                /* Do a Post-order traversal. */
X       Execute( cmdstr , 0L, Output() );
X
X    FreeMem( fib, ( long ) sizeof ( struct FileInfoBlock ) );
X
X    topLock = CurrentDir( tmpLock );
X
X    UnLock( topLock );
X    }
X
SHAR_EOF
echo "extracting sweep.doc"
sed 's/^X//' << \SHAR_EOF > sweep.doc
XSWEEP is a CLI program which takes CLI commands and executes them in the
Xcurrent directory and in all directories below the current directory.
X
X * The directory tree can be traversed in a pre-order (top down) fashion,
X     or in a post-order (bottom up) fashion.  The latter is the default.
X * Multiple commands can be issued in the same manner as with the RUN
X     command.
X * Input and output can be redirected for SWEEP as well as for the
X     commands it executes.
X
XThe command syntax is:
X    SWEEP [+|-|?] cmd [+ <return> cmd] ...
X
X    +   As the first character, '+' forces the directory tree to be
X        traversed in a post-order (bottom up) fashion.  This is the
X        default behavior, thus this parameter is useless.  In this mode,
X        the command(s) will be executed in the lowest-level directories
X        first.
X
X    -   forces the directory tree to be traversed in a pre-order (top down)
X        fashion.  In this mode, the command(s) will be executed in the
X        current directory first, then in the lower-level subdirectories.
X
X    ?   Causes the command syntax to be displayed.  In this case, any
X        command is ignored.
X
XSome examples are in order.
X
X    Assume we have a disk with the following directory structure:
X            Volume Name: MyDisk
X                                          (root)
X                                         /      \
X                                      Test     Real
X                                     /   \      /  \
X                                   A      Q    S    T
X                                 /   \
X                                /     \
X                              B         F
X                            / | \     /   \
X                           C  D  E   G     H
X
XSWEEP list           Assuming our current directory is A, the list
X                     command will be executed in the following
X                     directories: C D E B G H F A
X
XSWEEP -list          Assuming our current directory is A, the list
X                     command will be executed in the following
X                     directories: A B C D E F G H
X
XSWEEP s:spat protect #? -wed
X                     This command would execute the spat script in all
X                     the directories, making all the files and
X                     directories read-only.
X
XSWEEP delete #?      With A as our current directory, this will delete
X                     all the files in C, then in D, then E, then
X                     go to B and delete all B's files, including
X                     the now-empty directories C, D, and E.  It
X                     then cleans out G, H, F (getting rid of the empty
X                     G and H directories there) and finally back
X                     to A to delete A's files and the two empty
X                     directories B and F.  Use with care!
X
XSWEEP -delete #?     This command is just like the last one, but it
X                     would not delete the directories that were
X                     not empty from the start.  This is because the
X                     directory tree is traversed top-down.  The delete
X                     command in the A directory would remove all of A's
X                     files, but because neither B nor F is empty, those
X                     directories will remain.  All the files in and below
X                     A, however, would be deleted, just like the last
X                     example.
X
XSWEEP >ram:EditMe -echo "*N" +
Xcd +
Xlist
X                     Assume the F directory is our current directory.
X                     This command would execute the echo, cd, and
X                     list commands in each directory from the current
X                     directory on down, in top-down fashon, producing a
X                     file on RAM: called "EditMe" which could be printed
X                     to provide a reference of what was on the disk.
X                     It would look like this:
X
XMyDisk:Test/A/F
X.info                         76 ----rwed 30-Oct-89 21:12:37
XG                            Dir ----rwed 15-Jul-89 15:27:56
XH                            Dir ----rwed 24-Oct-88 19:04:37
XSomeFile                     894 ----rwed 13-Aug-88 18:11:51
XAnotherFile                  370 ----rwed 13-Aug-88 18:11:55
XSomeFile.info                894 ----rwed 13-Aug-88 18:12:05
X6 files - 2 directories - 9 blocks used
X
X
XMyDisk:Test/A/F/G
X.info                         16 ----rwed 24-Oct-88 19:48:47
X1 file - 2 blocks used
X
X
XMyDisk:Test/A/F/H
XDirectory "current directory" is empty
X
X
X
X
SHAR_EOF
echo "extracting sweep.uu"
sed 's/^X//' << \SHAR_EOF > sweep.uu
X
Xbegin 644 sweep
XM```#\P`````````#``````````(```13```!J@````$```/I```$4T[Z`WI.4
XM5?_T*VT`$/_T(&W_]!E0AF$K;0`,__@@;?_T$!!(@$C`8`Q2K?_T4ZW_^&`8+
XM8!:0O````"MG[%6`9^B0O````!)GX&#H#*T```0```QL/$)L@EY"K?_\8!H@4
XM+?_\(&W_]"(M__Q#[()@$[`(`!@`4JW__"`M__RPK?_X;=P@+?_\0>R"8$(P.
XM"`!@!CE\``&"7DY=3G5.50``3EU.=4Y5``!(>@`@3KH$@EA/2'H`CDZZ!'A8I
XM3TAZ`1U.N@1N6$].74YU4W=E97`Z($5X96-U=&4@0TQ)(&-O;6UA;F0H<RD@*
XM:6X@8W5R<F5N="!D:7)E8W1O<GD@86YD(&%L;`H@("`@("`@<W5B9&ER96-T*
XM;W)I97,N("`@("`@("`@("`@("`@("`@("`@("`@("`@=&UL(#$Q+S@Y"@H`S
XM55-!1T4Z(%-71450(%LK?"U\/UT@8VUD(%L@*R`*(&-M9"XN+B!="@H@)RLG&
XM("!$;R!A('!O<W0M;W)D97(@*&)O='1O;2!U<"D@=')E92!T<F%V97)S86PN@
XM("`H9&5F875L="D*("<M)R`@1&\@82!P<F4M;W)D97(@("AT;W`@(&1O=VXI;
XM('1R964@=')A=F5R<V%L+@H`("<_)R`@4VAO=R!C;VUM86YD('5S86=E+B`@L
XM*'1H:7,@9&ES<&QA>2D*(&-M9"`@0V]M;6%N9"AS*2!Y;W4@=V%N="!E>&5C<
XM=71E9"!I;B!E86-H(&1I<F5C=&]R>2X*("`@("`@375L=&EP;&4@8V]M;6%NN
XM9',@8V%N(&)E(&ES<W5E9"!A<R!W:71H('1H92!254X@8V]M;6%N9"X*``!.(
XM50``#"P`/X9A9@A.NOX:3KH+[DAZ``IA"%A/3EU.=0``3E7_]$AX__XO+0`(#
XM3KH-R%!/*T#__$JM__QF!$Y=3G4O+?_\3KH-2EA/*T#_^`PL`"V&86843KH-&
XMOB\`0J=(;()@3KH-6D_O``Q(>``!2'@!!$ZZ#?!03RM`__0O+?_T+RW__$ZZ;
XM#2903TI`9RPO+?_T+RW__$ZZ#3103TI`9QH@;?_T2J@`!&\.(&W_]%"(+PA.8
XMNO]L6$]@U`PL`"V&86<43KH-4B\`0J=(;()@3KH,[D_O``Q(>`$$+RW_]$ZZ$
XM#:I03R\M__A.N@RF6$\K0/_\+RW__$ZZ#2I83V``_SYA<$/L@EI%[():M<EF7
XM#C(\`1-K"'0`(L)1R?_\*4^&8BQX``0I3H9F2.>`@`@N``0!*6<02_H`"$ZNN
XM_^)@!D*G\U].<T/Z`"!.KOYH*4"&:F8,+CP``X`'3J[_E&`$3KH`&E!/3G5D<
XM;W,N;&EB<F%R>0!)^0``?_Y.=4Y5```O"DAY``$``#`L@D[!_``&+P!.N@S6M
XM*4"&;E!/9A1"ITAY``$``$ZZ#)I03RYLAF).=2!LAFY":``$(&R&;C%\``$`/
XM$"!LAFXQ?``!``H@;(9B("R&8I"H``10@"E`AG(@;(9R(+Q-04Y80J=.N@R*X
XM)$!*J@"L6$]G+B\M``PO+0`(+PI.NON$.7P``89V(&R&;@!H@```!"!LAFX`J
XM:(````I/[P`,8$)(:@!<3KH,F$AJ`%Q.N@QJ*4"&>"!LAGA*J``D4$]G$"!L-
XMAG@B:``D+Q%.N@M"6$\O+(9X+PI.NOO`*6R&>(9\4$].N@MP(&R&;B"`3KH+G
XMIB!LAFXA0``&9Q9(>`/M2'H`*DZZ"WX@;(9N(4``#%!/+RR&?#\LAH!.NOU>T
XM0F=.N@E84$\D7TY=3G4J`$Y5``!(;0`,+RT`"$AZ!&!.N@"83^\`#$Y=3G5.@
XM50``2.<(("1M``X,;0`$`!)F""!M``@H$&`<2FT`#&\,(&T`"'``,!`H`&`*F
XM(&T`"#`02,`H`$)M`!)*;0`,;!!$;0`,2H1L"$2$.WP``0`2,BT`#$C!(`1.\
XMN@.00>R``E.*%+```#(M``Q(P2`$3KH#AB@`9MI*;0`29P93BA2\`"T@"DS?3
XM!!!.74YU3E7_(DCG"#`D;0`()FT`#$)M__HK;0`0__P@2U*+$!!(@#@`9P`"!
XM[KA\`"5F``+,0BW_,#M\``'_^#M\`"#_]CM\)Q#_]"!+4HL0$$B`.`"P?``MV
XM9@Y";?_X($M2BQ`02(`X`+A\`#!F$#M\`##_]B!+4HL0$$B`.`"X?``J9A@@<
XM;?_\5*W__#M0__(@2U*+$!!(@#@`8#)";?_R8!PP+?_RP?P`"M!$D'P`,#M`6
XM__(@2U*+$!!(@#@`,`120$'L@!0(,``"``!FU+A\`"YF6B!+4HL0$$B`.`"P.
XM?``J9A@@;?_\5*W__#M0__0@2U*+$!!(@#@`8#)";?_T8!PP+?_TP?P`"M!$I
XMD'P`,#M`__0@2U*+$!!(@#@`,`120$'L@!0(,``"``!FU#M\``+_\+A\`&QF[
XM$B!+4HL0$$B`.``[?``$__!@$+A\`&AF"B!+4HL0$$B`.``P!$C`8'H[?``(=
XM_^Y@%CM\``K_[F`..WP`$/_N8`8[?/_V_^X_+?_P2&W_,#\M_^XO+?_\3KK]F
XMY"M`_^HP+?_P2,#1K?_\3^\`#&!<(&W__%BM__PB4"M)_^H@"4H99OR3P%.)_
XM.TG_\&!*(&W__%2M__PX$$'M_R\K2/_J$(1@*)"\````8V?B4X!GDI"\````-
XM"V<`_W)9@&>R58!G`/]P5X!G`/]R8,Q![?\PD>W_ZCM(__`P+?_PL&W_]&\&B
XM.VW_]/_P2FW_^&=H(&W_Z@P0`"UG"B!M_^H,$``K9BX,;0`P__9F)E-M__(@#
XM;?_J4JW_ZA`02(`_`$Z2L'S__U1/9@IP_TS?#!!.74YU8!8_+?_V3I*P?/__'
XM5$]F!'#_8.12;?_Z,"W_\E-M__*P;?_P;MQ";?_N8"`@;?_J4JW_ZA`02(`_N
XM`$Z2L'S__U1/9@1P_V"P4FW_[B!M_^I*$&<*,"W_[K!M__1MSC`M_^[1;?_Z9
XM2FW_^&8H8!@_/``@3I*P?/__5$]F!G#_8`#_>%)M__HP+?_R4VW_\K!M__!N?
XMVF`6/P1.DK!\__]43V8&</]@`/]24FW_^F``_0@P+?_Z8`#_0DCG2`!"A$J`G
XM:@1$@%)$2H%J!D2!"D0``6$^2D1G`D2`3-\`$DJ`3G5(YT@`0H1*@&H$1(!2&
XM1$J!:@)$@6$:(`%@V"\!81(@`2(?2H!.=2\!808B'TJ`3G5(YS``2$%*068@$
XM2$$V`30`0D!(0(##(@!(0#("@L,P`4)!2$%,WP`,3G5(028!(@!"04A!2$!"#
XM0'0/T(#3@;:!8@22@U)`4<K_\DS?``Q.=4Y5``!(;("L/RT`"$ZZ``A<3TY=.
XM3G5.50``+P0X+0`(+RT`"C\$3KH`,+A\``I<3V8D(&T`"A`H``Q(@`@```=GS
XM%#\\__\O+0`*3KH`]%Q/*!].74YU8/A.50``+PHD;0`*(%*QZ@`$91@P+0`(1
XMP'P`_S\`+PI.N@#(7$\D7TY=3G4@4E*2$"T`"1"`2(#`?`#_8.A.50``+PI!S
XM[("6)$@@2M7\````%B\(81!83T'L@DZUR&7J)%].74YU3E4``$CG""`D;0`(;
XM>``@"F8*</],WP003EU.=4HJ``QG4`@J``(`#&<,/SS__R\*85(X`%Q/$"H`:
XM#4B`/P!.N@4<B$`(*@`!``Q43V<*+RH`"$ZZ`BY83P@J``4`#&<2+RH`$DZZ'
XM`L`O*@`23KH"%%!/0I)"J@`$0JH`"$(J``PP!&"03E7__DCG""`D;0`(0?K_(
XM1BE(AH((*@`$``QG"G#_3-\$$$Y=3G4(*@`"``QG,"!2D>H`"#@(/P0O*@`(^
XM$"H`#4B`/P!.N@*`L$103V<0".H`!``,0I)"J@`$</]@P`QM__\`#&80"*H`B
XM`@`,0I)"J@`$<`!@J$JJ``AF""\*3KH`FEA/#&H``0`09BH;;0`-__\_/``!<
XM2&W__Q`J``U(@#\`3KH"(K!\``%03V:@,"T`#&``_VHDJ@`(,"H`$$C`T*H`S
XM""5```0(Z@`"``P@4E*2$"T`#1"`2(#`?`#_8`#_/DY5```O"D'L@)8D2$HJ`
XM``QG&-7\````%D'L@DZUR&4(<``D7TY=3G5@XD*20JH`!$*J``@@"F#J3E7_*
XM_"\*)&T`"#\\!`!.N@#`*T#__%1/9A@U?``!`!`@2M'\````#B5(``@D7TY=&
XM3G4U?`0``!`(Z@`!``PE;?_\``@0*@`-2(`_`$ZZ`.)*0%1/9P8`*@"```Q@$
XMSDY5``!(YP`P)&R"6F`4)E(@*@`$4(`O`"\*3KH$FE!/)$L@"F;H0JR"6DS?/
XM#`!.74YU3E4``"\*0?K_QBE(AH9"IR`M``A0@"\`3KH$1"1`2H!03V8(<``DO
XM7TY=3G4DK():)6T`"``$*4J"6B`*4(!@YDY5``!P`#`M``@O`&&R6$].74YUU
XM3E4``$CG`#"7RR1L@EI@#B!M``A1B+'*9Q(F2B12(`IF[G#_3-\,`$Y=3G4@X
XM"V<$)I)@!"E2@EH@*@`$4(`O`"\*3KH#['``4$]@V$Y5```O"C`M``C!_``&Q
XM)$#5[(9N2FT`"&T.,"T`"+!L@DYL!$J29@XY?``"AHIP_R1?3EU.=3`M``C!Q
XM_``&(&R&;B\P"`!.N@+X2H!83V<$<`%@`G``8-A.50``+RT`"$ZZ`I1*@%A/8
XM9@Y.N@+,.4"&BG#_3EU.=7``8/A.50``2.<,(#@M``A.N@!P,`3!_``&)$#5+
XM[(9N2D1M"KAL@DYL!$J29A`Y?``"AHIP_TS?!#!.74YU,"H`!,!\``-F"CE\@
XM``6&BG#_8.1P`#`M``XO`"\M``HO$DZZ`JXJ`+"\_____T_O``QF#$ZZ`DPY.
XM0(:*</]@N"`%8+1.5?_\2'@0`$*G3KH#!BM`__P(```,4$]G$DILAG9F""`MW
XM__Q.74YU3KH`!G``8/1.50``2'@`!$AZ`!Q.N@(X+P!.N@)*/SP``4ZZ``Y/F
XM[P`.3EU.=5Y#"@!.50``2JR&@F<&(&R&@DZ0/RT`"$ZZ``A43TY=3G5.5?_\)
XM+P0P+0`(2,`K0/_\2JR&;F<H>`!@"C\$3KH`_E1/4D2X;().;?`P+().P?P`=
XM!B\`+RR&;DZZ`CA03TJLAH9G!B!LAH9.D$JL@E1G"B\L@E1.N@&P6$]*K(:,@
XM9P@@;(:,(*R&D$JLAI1G"B\LAI1.N@'(6$]*K(:89PHO+(:83KH!N%A/2JR&_
XMG&<*+RR&G$ZZ`:A83TJLAJ!G"B\LAJ!.N@&86$\L>``$""X`!`$I9Q0O#4OZ`
XM``I.KO_B*E]@!D*G\U].<TJLAGAF,$JLAJ1G*#`LAJA(P"\`+RR&I$ZZ`9`P:
XM+(:`4D!(P.6`+P`O+(9\3KH!?$_O`!!@#DZZ`68O+(9X3KH!AEA/("W__"YL>
XMAF).=2@?3EU.=4Y5``!(YPX@."T`"#`$P?P`!B1`U>R&;DI$;0JX;().;`1*0
XMDF80.7P``H:*</],WP1P3EU.=0@J``<`!&8(+Q).N@`*6$]"DG``8.(B+P`$+
XM+&R&:D[N_]Q.^@`"(B\`!"QLAFI.[O^"(B\`!"QLAFI.[O^X3OH``DSO``8`>
XM!"QLAFI.[O^:3.\`#@`$+&R&:D[N_R),[P`&``0L;(9J3N[_E"QLAFI.[O_*\
XM+&R&:D[N_WPB+P`$+&R&:D[N_RA.^@`"3.\`!@`$+&R&:D[N_ZQ,[P`&``0LN
XM;(9J3N[_XD[Z``(L;(9J3N[_Q$[Z``(B+P`$+&R&:D[N_Z9,[P`.``0L;(9JG
XM3N[_T$CG`01,[R"```PL;(9F3J[_E$S?((!.=2)O``0L;(9F3N[^8D[Z``),2
XM[P`#``0L;(9F3N[_.B)O``0L;(9F3N[^VBQLAF9.[O]\3OH``B)O``0@+P`(-
XM+&R&9D[N_RX@;P`$+&R&9D[N_HPB;P`$+&R&9D[N_H9,[P`#``0L;(9F3N[^C
XMSB!O``0L;(9F3N[^@````^P````!`````0```_`````````#\@```^H```"6[
XM,#$R,S0U-C<X.6%B8V1E9@```"`@("`@("`@(#`P,#`P("`@("`@("`@("`@R
XM("`@("`@D$!`0$!`0$!`0$!`0$!`0`P,#`P,#`P,#`Q`0$!`0$!`"0D)"0D)^
XM`0$!`0$!`0$!`0$!`0$!`0$!`0%`0$!`0$`*"@H*"@H"`@("`@("`@("`@("J
XM`@("`@("`D!`0$`@``````````````````$``````0``````````````````P
XM```!`0````$``````````````````````0(````!````````````````````'
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
X?`````!0````````````````#\@```^L````!```#\@``M
X``
Xend
Xsize 5116
SHAR_EOF
echo "End of archive 1 (of 1)"
# if you want to concatenate archives, remove anything after this line
exit