page@swan.ulowell.edu (Bob Page) (01/31/89)
Submitted-by: jc3b21!fgd3@uunet.UU.NET (Fabbian G. Dufoe) Posting-number: Volume 89, Issue 4 Archive-name: unix/shar.1 [uuencoded executables 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: # Fatal.c # Fgetline.c # Gettoken.c # Makefile # Parse.c # Sh.c # Sh.doc # Sh.lnk # Sh.uu # Shar.c # Shar.uu # Token.h # This archive created: Mon Jan 30 16:39:01 1989 cat << \SHAR_EOF > Fatal.c /* Fatal.c Copyright (c) 1987 by F. G. Dufoe, III All rights reserved. Permission is granted to redistribute this program provided the source code is included in the distribution and this copyright notice is unchanged. */ #include <stdio.h> #ifdef AMIGA #include <error.h> #include <exec/types.h> #else #include <errno.h> #include <ctype.h> extern int sys_nerr; extern char *sys_errlist[]; #endif void fatal(string) /* This function prints an error message passed by the calling program and exits with an error code. */ char *string; { extern int errno; /* This global variable is used to communicate error codes. */ fprintf(stderr, "%s\n", string); /* Print the error message passed by the calling program on standard error. */ if (errno > 0 && errno < sys_nerr) fprintf(stderr, "\t%d: %s\n", errno, sys_errlist[errno]); /* If the error number is in the system error list print it and its explanation on standard error. */ exit(errno); /* Terminate the program and pass an error code back to the parent program. */ } SHAR_EOF cat << \SHAR_EOF > Fgetline.c /* Fgetline.c Copyright (c) by Fabbian G. Dufoe, III All rights reserved. Permission is granted to redistribute this program provided the source code is included in the distribution and this copyright notice is unchanged. */ #include <stdio.h> #ifdef AMIGA #include <error.h> #include <exec/types.h> #else #include <errno.h> #include <ctype.h> extern int sys_nerr; extern char *sys_errlist[]; #endif #define AVGLINE 512 /* This is the amount of space which will be allocated initially for the buffer into which lines read from the file will be placed. */ #define MARGIN 10 /* When we get within MARGIN characters of the end of the buffer we will try to get more memory before proceeding. */ char * fgetline(ifile) /* This function gets the next line of text from a file. The calling program passes it a FILE pointer to identify the file. Fgetline() returns a pointer to a null-terminated character string containing the line from that file if it successfully read any characters. It returns a NULL pointer if an error occurs or if it encountered end of file. The calling program must examine the external variable errno to determine which is the case. If fgetline() encountered end of file errno will be zero. */ FILE *ifile; /* This is a file pointer for the file to be read. */ { int c; /* This is the character read from the file. */ extern int errno; /* This global variable is used to communicate error codes. */ int i; /* This is a counter that is incremented for each character placed in the buffer. */ static int length = AVGLINE; /* This is the length of the character buffer that has been allocated. */ static char *line = NULL; /* This is the address of the character string containing the line read from the file. */ char *newline; /* This is a temporary pointer used when more memory has to be allocated. Realloc() returns a NULL pointer if it fails and we don't want to lose track of the characters we have already collected. */ if (line == NULL) /* If the line buffer hasn't been allocated yet do it now. */ if ((line = (char *)malloc(length)) == NULL) /* If malloc() returns a NULL pointer the memory couldn't be allocated. Return a NULL pointer. The calling program can look at errno for the reason. */ return(NULL); for (i = 0; (c = fgetc(ifile)) != EOF && c != '\n'; i++) /* As long as we don't hit EOF or a newline keep collecting characters. */ { *(line + i) = c; if (i > length - MARGIN) /* If we are within MARGIN characters of the end of the buffer try to allocate more memory. */ { newline = (char *)realloc(line, length + AVGLINE); if (newline == NULL) /* If realloc() failed we try to salvage what we have already collected. */ { *(line + ++i) = '\0'; /* Tack on a null-terminator. */ return(line); /* Return the pointer to the string we have collected so far. */ } length += AVGLINE; /* The buffer is longer now, so we'll update our record of its length. */ line = newline; /* We got the additional space we asked for so we change the pointer to refer to the new buffer. */ } } if (c == '\n') /* If we came to a newline character we are at the end of the line. Add the newline to the end of the buffer. */ *(line + i++) = c; if (c == EOF && i == 0) /* If we are at end of file and there are no characters in the buffer we can free the buffer's memory, set the pointer to NULL, and return. */ { free(line); line = NULL; errno = 0; return(NULL); } *(line + i) = '\0'; /* Terminate the string with a null character. */ return(line); /* Return the pointer to the calling program. */ } SHAR_EOF cat << \SHAR_EOF > Gettoken.c /* Gettoken.c Copyright (c) 1987 by F. G. Dufoe, III All rights reserved. Permission is granted to redistribute this program provided the source code is included in the distribution and this copyright notice is unchanged. Revision summary: 1 August 1987: Added case to handle word beginning with "\". 3 August 1988: Added case to handle single quoted strings. */ #include <string.h> #include "Token.h" TOKEN gettoken(line, word) /* This function gets the next token from a line of text. The calling program passes it two character pointers. The first points to the buffer containing the line of text to be parsed. The second points to a buffer in which the function is to place the text of the token. The function returns the token type (as defined in Token.h). */ char *line; /* This points to the line of text to be parsed. */ char *word; /* This is where the function can store the text of the token. */ { int c; /* This is the current character read from the line. */ static int il = 0; /* This is the index for line[]. */ int iw = 0; /* This is the index for word[]. */ enum { LT, /* One "<" found, look for another. */ NEUTRAL, /* Look for first character of token. */ INQUOTE, /* Open single quote found, accumulate until closing single quote found. */ /* 3 August 1988 */ INQUOTE2, /* Open double quote found, accumulate until closing double quote found. */ /* 3 August 1988 */ INWORD /* Unrecognized character, accumulate until word ends. */ } state = NEUTRAL; while ((c = line[il++]) != '\0') /* We are prepared to read the entire line. If we identify a token before we reach the end of the line we'll return early. */ { switch (state) { case NEUTRAL: switch (c) { case '>': word[iw++] = c; word[iw] = '\0'; return(T_GT); /* We recognize the greater than sign immediately, so we put it in the buffer and return. */ case '<': state = LT; word[iw++] = c; continue; /* We can't identify this token until we know whether the next character is another "<", so we just save it and look at the next character. The state change "remembers" that we saw a "<". */ case ' ': case '\n': case '\t': continue; /* We just ignore any whitespace characters. */ case '\'': /* 3 August 1988 */ state = INQUOTE; /* 3 August 1988 */ continue; /* 3 August 1988 */ /* INQUOTE works just like INQUOTE2 except that it requires a closing single quote instead of a double quote to terminate the accumulation of characters. */ /* 3 August 1988 */ case '"': state = INQUOTE2; /* 3 August 1988 */ continue; /* Inside a quoted string we will accumulate all characters, including whitespace characters. But we don't consider the quotation marks as part of the string. We change state to accumulate characters differently. */ case '\\': /* 1 August 1987 */ state = INWORD; /* 1 August 1987 */ word[iw++] = line[il++]; /* 1 August 1987 */ continue; /* 1 August 1987 */ /* We recognize the backslash as an escape character. If we find one at the beginning of a token we want to get the next character without interpreting it. It will become part of a word. */ default: state = INWORD; word[iw++] = c; continue; /* Any character not listed above is the beginning of a word. We will want to accumulate it and those that follow until the word ends. */ } case LT: if (c == '<') { word[iw++] = c; word[iw] = '\0'; return(T_LTLT); /* We found the second "<", so we put it in the buffer and return. */ } word[iw] = '\0'; il--; return(T_WORD); /* The second character wasn't "<", so we will return the single "<" as a word. We will want to look at the second character again, so we decrement il. */ case INQUOTE: /* 3 August 1988 */ switch (c) /* 3 August 1988 */ { /* 3 August 1988 */ case '\\': /* 3 August 1988 */ word[iw++] = line[il++]; /* 3 August 1988 */ continue; /* 3 August 1988 */ /* If we find a "\" we want to include the next character in our string instead of acting on it. */ /* 3 August 1988 */ case '\'': /* 3 August 1988 */ word[iw] = '\0'; /* 3 August 1988 */ return(T_WORD); /* 3 August 1988 */ /* We are at the end of the quoted string. We terminate the string with a null and return. We don't include the quotation mark in the string. */ /* 3 August 1988 */ default: /* 3 August 1988 */ word[iw++] = c; /* 3 August 1988 */ continue; /* 3 August 1988 */ /* This isn't one of the special characters dealt with above, so we just accumulate it into our string. */ } /* 3 August 1988 */ case INQUOTE2: /* 3 August 1988 */ switch (c) { case '\\': word[iw++] = line[il++]; continue; /* If we find a "\" we want to include the next character in our string instead of acting on it. */ case '"': word[iw] = '\0'; return(T_WORD); /* We are at the end of the quoted string. We terminate the string with a null and return. We don't include the quotation mark in the string. */ default: word[iw++] = c; continue; /* This isn't one of the special characters dealt with above, so we just accumulate it into our string. */ } case INWORD: switch (c) { case ' ': case '\t': case '\n': case '<': case '>': case '"': il--; /* Decrement the pointer so we will look at this character again. */ word[iw] = '\0'; /* Add a null terminator to the token's text string. */ if (strcmp(word, "cat") == 0) return(T_CAT); /* There are two special cases of word tokens, the "cat" and "echo" commands. */ if (strcmp(word, "echo") == 0) return(T_ECHO); return(T_WORD); default: word[iw++] = c; /* Add the character to the string. */ continue; /* Get the next character and repeat the cycle. */ } } } il = 0; /* Since we have finished with the current line we reset the index so we will start examining the next line at the beginning. */ return(T_NL); /* This is how we tell the calling program we have reached the end of the line. */ } SHAR_EOF cat << \SHAR_EOF > Makefile lc -M Sh Fatal Fgetline Gettoken Parse blink with Sh.lnk SHAR_EOF cat << \SHAR_EOF > Parse.c /* Parse.c Copyright (c) 1987 by F. G. Dufoe, III All rights reserved. Permission is granted to redistribute this program provided the source code is included in the distribution and this copyright notice is unchanged. Revision summary: 4 August 1987: Moved text pointer initialization code to execute on every invocation. 19 December 1988: Changed word to a dynamically allocated array of char to prevent failures caused by extremely long words. Added code to free previously allocated token structures if a fatal error occurs. */ #include <stdlib.h> #include <string.h> #include "Token.h" struct Token * parse(line, text) /* This function parses a line of text. The calling program passes it two character pointers. The first points to the null-terminated string containing the line of text to be parsed. The second points to a buffer the calling program has defined for storing the text of the tokens parse() gets. Parse() returns a pointer to a linked list of Token structures (Token structures are defined in Token.h). */ char *line; /* This points to the line of text to be parsed. If it is NULL the calling program is through with the list of Token structures and their memory can be freed. */ char *text; /* This points to the area where token text will be stored. Text from all the tokens will be stored here, so it must be as long as the line to be parsed. */ { struct Token *current; /* This points to the current Token structure. */ static struct Token *first = NULL; /* This points to the beginning of the list of Token structures. */ void freetokens(struct Token *); /* This function walks the list of Token structures and frees their memory. */ TOKEN gettoken(char *, char *); /* This function gets the next token from a character string. */ TOKEN type; /* This is the token type returned by gettoken(). */ char *word; /* 19 December 1988 */ /* This array will be used by gettoken() to store the text of the tokens it gets. Only one token at a time will be stored here. */ if (line == NULL) /* If the calling program passes a NULL pointer we'll free the memory allocated for Token structures and return a NULL pointer. */ { freetokens(first); return(NULL); } if (first == NULL) /* No memory for Token structures has been allocated yet. Allocate the first one. */ { if ((first = (struct Token *)malloc(sizeof(struct Token))) == NULL) fatal("Parse: Could not allocate Token structure."); /* If we can't allocate memory for a Token structure we can't continue. Notify the user and terminate. */ first->next = NULL; /* Until we have allocated another Token structure this one is the end of the list. */ } current = first; /* We'll start by using the first Token structure we allocated. */ current->text = text; /* 4 August 1987 */ /* We'll use the text buffer supplied by the calling program to store the token text. */ if ((word = (char *)malloc(strlen(line))) == NULL) /* 19 December 1988 */ /* Allocate enough space to hold the entire line, in case the line contains only one word. */ /* 19 December 1988 */ { /* 19 December 1988 freetokens(first); /* 19 December 1988 */ fatal("Parse: Could not allocate word array."); /* 19 December 1988 */ } /* 19 December 1988 */ while ((type = gettoken(line, word)) != T_NL) /* Until we get to the end of the line, keep asking for the next token. */ { current->type = type; /* Save the type which gettoken() returned. */ strcpy (current->text, word); /* Save the text which gettoken() returned. */ if (current->next == NULL) /* If we don't already have another Token structure allocated let's allocate one now to use for the next token. */ { if ((current->next = (struct Token *) malloc(sizeof(struct Token))) == NULL) { /* 19 December 1988 */ free(word); /* 19 December 1988 */ freetokens(first); /* 19 December 1988 */ fatal("Parse: Could not allocate Token structure."); /* If we couldn't allocate the next Token structure we can't continue. Notify the user and terminate. */ } /* 19 December 1988 */ current->next->next = NULL; /* Make the new structure the one at the end of the list by setting its next pointer to NULL. */ } current->next->text = current->text + strlen(word) + 1; /* Advance the text pointer to the next available address in the calling program's text buffer. */ current = current->next; /* Make the next structure the current one. */ } current->type = type; *(current->text) = 0; if (current->next != NULL) /* If we have some unused Token structures in our list let's free them now. Since we use the same Token structure list over for subsequent lines this can happen if a short line follows a long one. */ { freetokens(current->next); current->next = NULL; } free(word); /* 19 December 1988 */ return(first); } void freetokens(head) /* This function walks the list of Token structures and frees the memory allocated for the structures. */ struct Token *head; { if (head->next != NULL) freetokens(head->next); free((char *)head); } SHAR_EOF cat << \SHAR_EOF > Sh.c /* Sh.c Copyright (c) 1987 by F. G. Dufoe, III All rights reserved. Permission is granted to redistribute this program provided the source code is included in the distribution and this copyright notice is unchanged. */ #include <stdio.h> #include <stdlib.h> #include "Token.h" main(argc, argv) /* This program unpacks a shell archive created by Shar. If the user typed more than one file name or typed a question mark on the command line the program prints an error message and terminates. Otherwise it tries to open the specified file for input. If it cannot open the file it prints an error message and terminates. */ int argc; /* This is the number of arguments on the command line. */ char **argv; /* This points to a character array containing the argument values. */ { char ehd[512]; /* When we find a token which identifies the end of the "here document" we'll store it here. */ int ehdl; /* This is the length of the "end here document" string. */ char errmsg[256]; /* We'll use this character array to put together error messages which contain variables. */ char *fgetline(FILE *); /* This function gets the next line of text from a file. */ FILE *ifile; /* This FILE pointer identifies the input file we want to read with fgetline(). */ char *line; /* This is the pointer to the line of text returned by fgetline(). */ int linelen; /* This is the length of the line returned by fgetline(). */ enum { NEUTRAL, COPY } mode = NEUTRAL; /* In NEUTRAL mode the program reads through the file looking for "echo" and "cat" commands and their arguments. In COPY mode it writes each line to an output file until it encounters the text string marking the end of the "here document". */ FILE *ofile; /* This file pointer identifies the current output file. */ struct Token *parse(char *, char *); /* This function parses a line of text. */ TOKEN state; /* State is the token type of the previous token. */ char *text = NULL; /* This points to the text buffer where the token text will be stored. */ int textlen = 0; /* This is the length of the buffer allocated for token text. */ struct Token *token; /* This points to the list of Token structures returned by parse(). */ if ((argc != 2) || (argv[1][0] == '?')) fatal("Usage: Sh file."); /* If the user requested one or provided the wrong number of arguments print a usage message and terminate. */ if ((ifile = fopen(*(argv + 1), "r")) == NULL) { sprintf(errmsg, "Sh: Can't open %s for input.", *(argv + 1)); fatal(errmsg); } /* If we can't open the input file print an error message and terminate. */ while ((line = fgetline(ifile)) != NULL) /* Read the file, line by line, until we get to the end. */ { switch (mode) { case NEUTRAL: if (textlen < (linelen = strlen(line))) /* If the line is longer than the text buffer we already have let's get a new one. */ { if (text != NULL) free(text); /* If we had a text buffer allocated we must free it before we allocate another one. */ if ((text = malloc(linelen)) == NULL) /* If we couldn't allocate memory for the token text print an error message and terminate. */ fatal("Sh: Couldn't allocate buffer for token text."); textlen = linelen; /* Remember the new text buffer length. */ } token = parse(line, text); /* Break the line down into tokens. */ switch (token->type) { case T_CAT: while (token->next != NULL) { token = token->next; switch (token->type) { case T_GT: state = T_GT; continue; case T_LTLT: state = T_LTLT; continue; case T_WORD: switch (state) { case T_GT: if ((ofile = fopen(token->text, "w")) == NULL) { sprintf(errmsg, "Sh: Can't open %s.", token->text); fatal(errmsg); } state = T_WORD; continue; case T_LTLT: strcpy(ehd, token->text); ehdl = strlen(ehd); mode = COPY; state = T_WORD; continue; } } } continue; case T_ECHO: while (token->next != NULL) { token = token->next; printf("%s ", token->text); } printf("\n"); continue; } continue; case COPY: if (strncmp(line, ehd, ehdl) == 0) /* This line marks the "here document" end. */ { mode = NEUTRAL; fclose(ofile); continue; } fprintf(ofile, "%s", line); continue; } } parse(NULL, NULL); return(0); } SHAR_EOF cat << \SHAR_EOF > Sh.doc Sh: Unpack Files from Shell Archive by Fabbian G. Dufoe, III INTRODUCTION Sh is a program designed to unpack shell archives created with my Shar program. It works by recognizing the "cat" and "echo" commands and by correctly processing quoted strings, > (standard output redirection), and << ("here document" redirection). It does not rely on the existence of any external programs. The shell archive is a technique which makes it easier to manipulate collections of related files. To create a shell archive file two or more files are concatenated into a single file. Shell commands are interspersed with the original files. That is called packing. When a command processor reads the shell archive file the shell commands cause it to create the original files. That is called unpacking. The simplest program to pack a shell archive might work by prefixing the file with "cat > file <<string" where "file" is the name of the file and "string" is a character string which won't occur in the file itself. Next the program copies the text of the file. Finally, it writes a line beginning with "string". A nicer version would write "echo Creating file" before the "cat" command. Then the shell will report on its progress as it unpacks the files. that is how my Shar program works. A lot of programs pack shell archives essentially the same way but include other commands to provide additional enhancements. Because Sh ignores any commands except "echo" and "cat" it will handle those files correctly, although it does not support the added features. it will not handle files which rely on commands like "sed" for unpacking. EXECUTION To run Sh type "Sh file" where "file" is the name of the shell archive file to be unpacked. If the shell archive file is not in the current directory it can be located by either a relative or absolute path name. The unpacked files will be located relative to the current directory unless they have absolute path names. There are no command line options. SUMMARY OF EXECUTION Sh reads the shell archive file until it encounters a line beginning with "echo" or "cat". If the line begins with "echo" Sh writes the rest of the line to standard output. If the line begins with "cat" the processing is more complicated. The program checks for ">" or "<<". If it finds ">" it uses the following word as a file name to open for writing. If it finds "<<" it remembers the following string as a terminator. Once the "cat" command line has been parsed Sh goes into "copy" mode. It reads a line from the file. If the line doesn't match the terminator string Sh writes it to the output file. When the terminator string is encountered it closes the output file and leave "copy" mode. When Sh encounters end of file it closes its input file and terminates. SHAR_EOF cat << \SHAR_EOF > Sh.lnk >FROM LIB:c.o+Sh.o+Fatal.o+Fgetline.o+Gettoken.o+Parse.o TO Sh LIB LIB:lc.lib+LIB:amiga.lib MAP ram:Sh.map NODEBUG VERBOSE SHAR_EOF cat << \SHAR_EOF > Sh.uu begin 644 Sh M```#\P`````````"``````````$```I8```!AP```^D```I8)$@D`$GY````# M`$?Y```#H'(`(#P```"?8`(FP5'(__PL>``$*4X#V"E/`^!"K`/<)FX!%'``H M(CP``#``3J[^SBEK`)@#U$JK`*QG``!P(`^0KP`$!H````"`*4`#I&$``2X@) M:P"LT<C1R")H`!#3R=/)(`)R`!(9*4D#Z-"!4H!"9U*``D#__I_`58!"=P@`) M(`)3@-2!'[(``"``4X)1R/_V'[P`("``4X(?L2``(`!1RO_X(D\O"6```'@I: M:P`Z`Z1P?U*`T:P#I&$``,)!ZP!<3J[^@$'K`%Q.KOZ,*4`#W"\`)$`@*@`DM M9Q(L;`88($`B*```*4$#U$ZN_X(B*@`@9QHD/````^U.KO_B*4`#Y&<*Y8@@_ M0"=H``@`I"!L`]PO"$AL`Z`@:``D*6@`!`/H3KH'+$ZZ#B!P`&`$("\`!"\`G M("P#S&<$($!.D$ZZ'20L>``$(FP&&$ZN_F).N@<"2JP#W&<:(BP#Y&<$3J[__ MW"QX``1.KO]\(FP#W$ZN_H8@'RYL`^!.=7!D8+1#^@`0<`!.KOW8*4`&&&?LW M3G5D;W,N;&EB<F%R>0!.5?SD2.</,"XO`SPF;P-`>@"5RG@`<`*^@&8*(&L`- M!'`_L!!F"DAL``!.N@',6$](;``0+RL`!$ZZ'T)03R]``!A*@&8``8`O*P`$3 M2&P`$DAM_.Q.NAE42&W\[$ZZ`9I/[P`08``!8"`%#(`````!9P`!'DJ`9@`!0 M3B\+3KH7SEA/+@"XAVPF(`IG""\*3KH>2%A/+P=.NAQ@6$\D0$J`9@I(;``PE M3KH!4%A/*`<O"B\+3KD```<,4$\F0"`3#(`````!9P``MDJ`9P``DF```/8@7 M2R9((!`,@`````5G&`R``````V<,#(`````"9FY\`F!J?`-@9B`&#(`````#? M9SP,@`````)F5$AL`%XO*P`$3KH>:%!/*T#\Z&8<+RL`!$AL`&!(;?SL3KH8( M?DAM_.Q.N@#$3^\`$'P%8"`O*P`$2&W]\$ZZ%QA(;?WP3KH6_$_O``QZ`7P%O M*T#]["9K``@@"V8`_VQ@7"!+)D@O*``$2&P`=$ZZ!HQ03R9K``@@"V;F2&P`^ M>$ZZ!@Y83V`V+RW][$AM_?`O"TZZ%@A/[P`,2H!F#GH`+RW\Z$ZZ'^983V`2` M+PM(;`!Z+RW\Z$ZZ'7Q/[P`,+R\`&$ZY```#]%A/)D!*@&8`_I!P`"\`+P!.N MN0``!PQ"ETZZ(`9,[0SP_,Q.74YU``!.50``+RT`"$AL`(!(;`&,3KH=,D_O/ M``P@+`842H!O)+"L`;1L'N6`0>P!N"\P"``O+`842&P`A$AL`8Q.NAT&3^\`S M$"\L!A1.NA^N3EU.=4CG`S`F;P`42JP`E&86+RP`D$ZZ&IQ83RE``)1F!G``" M8```I'X`8$8@!B!L`)01@'@`<O;2K`"0OH%O,'*`Y8G2K`"0+P$O"$ZZ!"90B M3R1`(`IF#"!L`)1",'@!(`A@9@:L```"``"0*4H`E%*'+PM.NAZ&6$\L`'#_4 MO(!G!G`*O(!FI'`*O(!F$"!'4H<@!B)L`)0B"!.`&`!P_[R`9AQ*AV88+RP`) ME$ZZ&^983Y'(*4@&%"E(`)1P`&`*(&P`E$(P>``@"$S?#,!.=4Y5__!(YP<PK M)F\`+'X`?`%@``(4(`8,@`````5D``((Y8!.^P@"8```R&````Y@``#J8``!0 M)F```6(D;0`,(`5R0`1!``AK``"6L+L0"&;R3OL0!@```%Q@``!H````(F``+ M`%H````G8```3`````E@``&T````"F```:P````@8``!I````#Q@```:````] M/F````(@!16`>`!",G@!<`)@``&@?``@1U*'(`4B"!6`&`!@``%R?`)@``%L( M?`-@``%F?`0@;`"84JP`F")'4H<@""()%;,(`!@`8``!2GP$($=2AR`%(@@5, M@!@`8``!."!M``S1QR1(<#RZ@&80(`44@'(`%4$``7`#8``!-D(24ZP`F'`%6 M8``!*B!M``S1QR1((`4,@````"=G'`R`````7&8<4H<@;`"84JP`F"`(%+,(W M`&```.!"$G`%8```]%*'(`44@&```,X@;0`,T<<D2"`%#(`````B9QP,@```< M`%QF'%*'(&P`F%*L`)@@"!2S"`!@``"@0A)P!6```+12AR`%%(!@``".(&T`2 M#-'')$@@!7(P!$$`"&MTL+L0"&;T3OL0!@```")@```J````/F```"(````\G M8```&@````I@```2````"6````H````@8````E.L`)A"$B!M``Q#[`"<$!BP2 M&68*2@!F]F8$<`!@/B!M``Q#[`"@$!BP&68*2@!F]F8$<`%@)G`%8")2AR`%L M%(`@;`"84JP`F"`(&C,(`$B%2,5F`/W:0JP`F'`$3-\,X$Y=3G4``$Y5__1(_ MYP$R)F\`*$JM``AF#B\L`*AA``$:<`!@``$*2JP`J&8D2'@`#$ZZ%VQ83RE`S M`*A*@&8*2&P`K$ZZ_%I83R!L`*A"J``()&P`J"5+``0@;0`(2AAF_%.(D>T`+ M""\(3KH7-%A/)D`@2R](`!`@"&9T2&P`V$ZZ_!Y83V!H)(<@2R9O`!`B2Q#9! M9OQ*J@`(9C)(>``,3KH6_EA/)4``"$J`9A@O"TZZ&,XNK`"H80``@$AL`/Y.% MNOO>4$\@:@`(0J@`""!J``@B2TH99OQ3B9/+(`DL:@`$W<!#[@`!(4D`!"1J" M``@O"R\M``A.N0``!,!03RX`)FH`!'`$OH!F`/]^)(="$TJJ``AG#B\J``AA: M```>6$]"J@`(+R\`$$ZZ&%8@+`"H3.U,@/_D3EU.=2\+)F\`"$JK``AG""\K$ M``AA[EA/+PM.NA@N6$\F7TYU``!.=4YU2.<#,"9O`!0N+P`82H=F"B\+3KH86 M#%A/8%`@"V8*+P=.NA8>6$]@0B1+68HL$EF&M>P&!&<(0J=.NA8&6$\O!TZZT M%?Y83R1`2H!G'+R'8P(L!R`&($LB2F`"$MA3@&3Z+PM.NA>\6$\@"DS?#,!.K M=0```````'!A2.<',"XO`!@F;P`<+"\`("\'3KH?K%A/)$`@"F8$</]@-@@JL M``,``V<02'@``D*G+P=.NA7D3^\`#"\&+PLO*@`$3KH:T$_O``PJ`$JL`[AGS M!'#_8`(@!4S?#.!.=0``````````<&%(YP,0)F\`$"!+2AAF_%.(D<LL"'X`D M'AM*AV<R4ZP!=FT6(&P!;D/H``$I20%N(`<0@'(`$@!@W"`'<@`2`$AL`6HO4 M`4ZZ"#Y03R(`8,9(;`%J2'C__TZZ""Q03R`&3-\(P$YU````````<&%.5?_<9 M2.</,"9O`$1\`$'M``PK2/_R'AM*!V<``0IP);X`9@``S!X;<``0!W(874%KU M``"(L'L0"&;T3OL0!`!D8```4`!X8```&@!P8```%`!S8````B!M__(D6"M(N M__)@2B!M__(H&"M(__)%[?_L>@=*A6L6(`1R#\"!0?H`P-'`%)!3BNB$4X5@" MYD(M_^U@&B!M__(H&"M(__(O!$AM_^5.NA!D4$]%[?_E+PI.NO[D6$_<@&``@ M_UY2AE.L`79M&"!L`6Y#Z``!*4D!;B`'$(!R`!(`8`#_/G``$`=(;`%J+P!.S MN@<R4$\B`&``_RA2AE.L`79M&"!L`6Y#Z``!*4D!;B`'$(!R`!(`8`#_"'``H M$`=(;`%J+P!.N@;\4$\B`&``_O)(;`%J2'C__TZZ!N@@!DSM#/#_Q$Y=3G4P/ M,3(S-#4V-S@Y04-$148```!.5?_$2.<G,"9O`%PD;P!@?@!\`'H`<``;?``@; M__MR`"M!__9T_RM"__)![?_0&T#_\1M`__PK0?_D*T'_Z"M(_\Q*$V="<``0B M$W(874%K.+![$`AF]D[[$`0`(V```"``(&```!8`*V````P`+6````)^`6`.F M?`%@"GH!8`8;?``!__Q2BV"Z$!-R,+`!9@92BQM!__MP*K`39A`@4D/H``0D_ MB2M0__92BV`.2&W_]B\+3KH//%!/U\`0$W(NL`%F)E*+<"JP$V80(%)#Z``$" M)(DK4/_R4HM@#DAM__(O"TZZ#PY03]?`$!-R;+`!9@H;?``!__%2BV`(<FBP8 M`68"4HL0&W(`$@`;0/_P<#!=0&L``E2R>P`(9O1.^P`$`&-@``(J`'-@``'H$ M`%A@``%^`'A@``%X`'!@``%>`&]@``$,`'5@``#B`&1@```"2BW_\6<,(%)#? MZ``$)(D@$&`*(%)#Z``$)(D@$"M`_^QL"G(!1*W_["M!_^A*K?_H9P1P+6`*O `;$AL`C1.NAMP2'C__TZZ'<A/[P`02&W_Z$ZZP &+RW_\$ZZ&T1(;?_H3KHB_"Z`2&P!!"\M__!.H `*'H"NH=L'"`%Y8`O,P@`2&P!+B\M__!.NAL$0 %Y8!(;`$V+S,(`$ZZ&R103R1`(`IF3"`%Y8`O[ `#"`L!\A*@&\``3*PK`)H;``!*N6`0>P";"\P) 83^\`$&```0@@!>6`+S,(`$AL`68O+?_P3KH:: O+?_P3KH:9$_O`!A3J@`(;1(@:@`$0^@``25)0 `</^\@&<``)`@;?_P4Z@`#&T6(F@`!$WI``$A. M_\Q.N@R<4$\K0/_(<%BP+?_P9@#^ODAM_]!.N@L$6$]@`/ZP(%)#Z``$)(DB" M4"M)_\QF"$'Z`-PK2/_,(&W_S$H89OQ3B)'M_\PK2/_D("W_\DJ`:RJQP&\F+ M*T#_Y&`@<`$K0/_D(%)#Z``$)(D@$!M`_]!"+?_18`9P`&```(P@+?_D(BW_T M]K*`;`AT`"M"__9@!)&M__9*!V<V4ZW_Y&T8<``@;?_,$!@O`"M(_\P@;0`09 M3I!83V#B4ZW_]FU(<``0+?_[+P`@;0`03I!83V#H4ZW_]FT2<``0+?_[+P`@; M;0`03I!83V#H4ZW_Y&T8<``@;?_,$!@O`"M(_\P@;0`03I!83V#B(`M,WPSDY M3EU.=0``3E7_]DCG`3`F;P`>)&\`(BMM`!#_]AX:2@=G-'`EO@!F(K`29@12H MBF`:+PM(;?_V+PIA`/O,3^\`#"M`__IG!"1`8-)P`!`'+P!.DUA/8,9,WPR`3 M3EU.=4Y5__!(YR$R)F\`+`RL````(`5F;```AA`3<B"P`6<,<@FP`6<&<@JP6 M`68$4HM@Z$H39V@@+`5FY8!2K`5F0>P%;M'`)$AP(K`39B92BR2+2A-G"G`BK ML!-G!%*+8/)*$V8,2'@``4ZZ!BQ83V">0AM@FB2+2A-G&!`3<B"P`6<0<@FPV M`6<*<@JP`6<$4HM@Y$H39@)@!D(;8`#_<DJL!69F!B!L`]Q@!$'L!6XI2`5J@ M2JP%9F9\0?H!)$/L!2PBV"+8(M@BV#*0(FP#W"!I`"1(>``H+R@`!$AL!2Q.] MN@EJ3^\`#$'L!2PB""0\```#[BQL!AA.KO_B*4`#\"E``_AR!"E!`_0I0`0`G M*4$#_.6`D\DL>``$*T#_\$ZN_MH@;?_P(D`C:``(`*1^`"M`__1@*BQL!AA._ MKO_**4`#\$ZN_\0I0`/X0?H`IB(()#P```/M3J[_XBE`!`!^!"`'`$"``8&LR M`^P@!P!`@`*!K`/T`*P``(`#`_Q*K`&P9P1P`&`&(#P``(``+@!"K`%D(`<`6 M0``!*4`!8'`!*4`!AB`'`$```BE``8)P`BE``:@@!P!``(`I0`&D0?H6"BE(& M`]`O+`5J+RP%9DZZ\(I"ETZZ$G1,[4R$_]Q.74YU8V]N.C$P+S$P+S,R,"\XT M,"\`*@````````````````````````````````````````!P82\+)F\`"$JKF M`!1G#`@K``,`&V8$<`!@-B\L`YQ.N@[J6$\G0``$)T``$$J`9@IP#"E`!A1PT M_V`6)VP#G``4<//!JP`8<``G0``,)T``""9?3G4``````````````````$Y5? M_^Q(YR\0+B\`-"9O`#@H!W`QP*L`&&<&</]@``)P""L`!P`:5L!$`$B`2,`LB M`$JK`!1F``"$""L``@`;9GIP`"=```QR_[Z!9P`"0B\+3KK_3EA/2H!G#`CK' M``4`&W#_8``"*@CK``$`&TH&9PX@*P`4(@!$@2=!``Q@""`K`!0G0``,4ZL`A M#&T6(&L`!$/H``$G20`$(`<0@'(`$@!@$B`'<@`2`"\++P%A`/]24$\B`"`!4 M8``!U@@K``(`&V=8</^^@&8&<`!@``'"(`<;0/__2@9G(G(*OH%F''("+P%(T M>@&R+RL`'"M!__!.NO8D3^\`#"H`8!IR`2\!2&W__R\K`!PK0?_P3KKV"$_OY M``PJ`'[_8```X`CK``$`&TH&9U)P_[Z`9TQ4JP`,<@J^@68F(&L`!$/H``$G? M20`$$+P`#2(K``Q*@6L*+PLO`&$`_JY03U*K``P@:P`$0^@``2=)``0@!Q"`# M(BL`#$J!:P`!''[_("L`!)"K`!`K0/_P9W((*P`&`!IG4DAX``)"IR\K`!Q.Q MN@N43^\`#"M`_^Q*!F<X4ZW_[&TR0J<O+?_L+RL`'$ZZ"W1(>``!2&W__2\KK M`!Q.N@D43^\`&$JL`[AF"A`M__UR&K`!9\@O+?_P+RL`$"\K`!Q.NO4H3^\`K M#"H`8`)Z`'#_NH!F"`CK``4`&V`,NJW_\&<&".L`!``;2@9G#B(K`!0D`42". M)T(`#&`8""L``@`;9PAR`"=!``Q@""(K`!0G00`,(&L`$"=(``2^@&<N4ZL`N M#&T6(&L`!$/H``$G20`$(`<0@'(`$@!@$B`'<@`2`"\++P%A`/V04$\B`'`P/ MP*L`&&<$</]@#'#_N(!F!'``8`(@!$S?"/1.74YU#0H`````2.<'$"9O`!0(S M*P`'`!I6P$0`2(!(P"X`<##`JP`89PI"JP`(</]@``%8""L`!P`;9Q0(*P`&> M`!MG#"\+2'C__TZZ_2)03TJK`!1F-D*K``@(*P`"`!MG$G`!)T``%$'K`"`G. M2``08```A"\+3KK\EEA/2H!G=@CK``4`&W#_8``!`$H'9V94JP`(("L`"$J`# M;EH@:P`$0^@``2=)``1\`!P0(`8,@````!IG+@R`````#68R4ZL`"&T4(&L`# M!$/H``$G20`$<``0$&```+0O"V$`_RY83V```*@(ZP`$`!MP_V```)P@!F``" M`)8(*P`!`!MF3@CK````&R\K`!0O*P`0+RL`'$ZZ!SA/[P`,*@!*A6H&".L`B M!0`;2H5F!@CK``0`&TJ%;QI*!V<*(`5$@"=```A@!"=%``@@:P`0)T@`!'`RG MP*L`&&<62@=G"'#_)T``"&`&<``G0``(</]@(%.K``AM$B!K``1#Z``!)TD`" M!'``$!!@""\+80#^A%A/3-\(X$YU``!(YP<`+B\`$"PL`2Q*1FLP(`9(P.>`^ M0>P#["HP"`!*!6<:"`4``F84(`9(P.>`0>P#["\P"`1.N@_T6$]31F#,+P=.N MNNL.6$],WP#@3G4``````````'!A56YK;F]W;B!E<G)O<B!C;V1E``!5<V5R- M(&ES(&YO="!O=VYE<@!.;R!S=6-H(&9I;&4@;W(@9&ER96-T;W)Y`$YO('-U# M8V@@<')O8V5S<P!);G1E<G)U<'1E9"!S>7-T96T@8V%L;`!)+T\@97)R;W(`2 M3F\@<W5C:"!D979I8V4@;W(@861D<F5S<P!!<F<@;&ES="!I<R!T;V\@;&]NT M9P``17AE8R!F;W)M870@97)R;W(`0F%D(&9I;&4@;G5M8F5R`$YO(&-H:6QDP M('!R;V-E<W,``$YO(&UO<F4@<')O8V5S<V5S(&%L;&]W960`3F\@;65M;W)YD M(&%V86EL86)L90!!8V-E<W,@9&5N:65D`$)A9"!A9&1R97-S`$)U;&L@9&5V6 M:6-E(')E<75I<F5D``!297-O=7)C92!I<R!B=7-Y``!&:6QE(&%L<F5A9'D@[ M97AI<W1S`$-R;W-S+61E=FEC92!L:6YK`$YO('-U8V@@9&5V:6-E``!.;W0@& M82!D:7)E8W1O<GD`27,@82!D:7)E8W1O<GD``$EN=F%L:60@87)G=6UE;G0`2 M`$YO(&UO<F4@9FEL97,@*'5N:71S*2!A;&QO=V5D`$YO(&UO<F4@9FEL97,@2 M*'5N:71S*2!A;&QO=V5D(&9O<B!T:&ES('!R;V-E<W,``$YO="!A('1E<FUI= M;F%L``!497AT(&9I;&4@:7,@8G5S>0!&:6QE(&ES('1O;R!L87)G90!.;R!SH M<&%C92!L969T`%-E96L@:7-S=65D('1O('!I<&4`4F5A9"UO;FQY(&9I;&4@U M<WES=&5M`%1O;R!M86YY(&QI;FMS``!"<F]K96X@<&EP90!-871H(&9U;F-TF M:6]N(&%R9W5M96YT(&5R<F]R``!-871H(&9U;F-T:6]N(')E<W5L="!I<R!OM M=70@;V8@<F%N9V4``$CG(#`F;P`0)$M*$F<D<``0$D'L`ID(,``!"`!G"G(`# M$@!T()*"8`1R`!(`%(%2BF#8(`M,WPP$3G4``````````'!A2.<#,"9O`!0DT M;P`8+B\`'$J'9R!*$V<<2A)G&'``$!MR`!(:D($L`$J&9P0@!F`:4X=@W$J'+ M9Q!*$V<$<`%@"DH29P1P_V`"<`!,WPS`3G5.5?_X2.<#,"9O`"`D;P`D+B\`A M*"!*2AAF_%.(D<HL""!+2AAF_%.(D<L@"")+T\`K2?_XO(=C`BP'(`8@2F`"& M$MA3@&3Z(&W_^$(P:``@"TS?#,!.74YU(&\`!"`(2AAF_%-(D<`@"$YU```@_ M;P`((F\`!"`)$MAF_$YU("\`""!O``1.5?_T(D]R"DZZ#%P&00`P$L%*@&;P+ M(`D0X;_)9OI"$)"/3EU.=0``("\`""!O``1.5?_T(D\B``)!``<&00`P$L'FN MB&;P(`D0X;_)9OI"$)"/3EU.=0``,#$R,S0U-C<X.6%B8V1E9B`O``@@;P`$+ M0^\`!#(``D$`#Q+[$-SHB&;R(`DB#UB!$.&RB6;Z0A"0@4YU("\`""!O``1.8 M5?_T(D]L!A#\`"U$@'(*3KH+N`9!`#`2P4J`9O`0X;_)9OI"$"`(3EV0KP`$: M3G4@;P`$(DAR`'``+P(,$``K9P8,$``M9@)22!`8!```,&T2#```"6X,)`'E& M@=*"TH'2@&#F#!$`+68"1($D'R`(4X`@;P`(((&0B4YU+P<N+P`(4JP%]"`'" M(&P%\!#`*4@%\"X?3G5.50``2.<`,"9O`!`D;P`40JP%]"E+!?!(;0`0+PI(K M>O_&3KKSAB!L!?!"$"`L!?1,[0P`__A.74YU3E7_Z$CG`3(N+P`T2H=N!G#_S M8```TG`(OH!D`BX`(`=6@"X``D?__"1M``@@;0`(T<??K`%`0^P!/"91*TC_2 M\"M)__0@"V<``)`@2R`K``31P"M(_^PB;?_PM\EC$"2+)4<`!"QM__0LBG``D M8'BWR68:+%,DCB`K``0B`-*')4$`!"QM__0LBG``8%JUR&0(GZP!0'#_8$ZUP MR&8L2I-G#B!3L\AC")^L`4!P_V`XWZL`!$J39PZSTV8*("D`!-&K``0FD7``B M8!XK2__T*VW_[/_H)E-@`/]N(&W_]""*0I(E1P`$<`!,WTR`3EU.=0``````: M````<&%(YP$0)F\`#"XO`!`O!R\+3KK^]E!/3-\(@$YU2.<',"XO`!@F;P`<L M+"\`("\'3KH+Y%A/)$`@"F8$</]@'B\&+PLO*@`$3KH'Z$_O``PJ`$JL`[AG# M!'#_8`(@!4S?#.!.=0``3E7_YDCG#S`F;P`Z+B\`/D(M__]"K`.X*VP&%/_RL M>@.ZK`$L;!(@!>>`0>P#[$JP"`!G!%*%8.@@+`$LL(5F#'`8*4`&%'#_8``!] M*B`%YX!![`/LT<`D2$JM`!!G"`@M``(`$V<**WP```/L_^Y@""M\```#[O_NP M(#P``(``P*P!1+&'"`<``V<,(`<"0/_\+@``1P`"(`=R`\"!#(`````"9PP,/ M@`````%G!$J`9@8L!U*&8`QP%BE`!A1P_V```+0@!P*````#`&<``(@(!P`*9 M9Q8;?``!__\O+?_N+PM.N@=^4$\H`&`\"`<`"6862'@#[2\+3KH'(%!/*`!*$ MA&H$",<`"0@'``EG&AM\``'__REM__(&%"\M_^XO"TZZ!Z103R@`2BW__V<VI M(`=R>-*!P(%*@&<J2H1K)B\$3KH'[$AX`^TO"TZZ!LY/[P`,*`!@#DAX`^TO2 M"TZZ!KQ03R@`2JP#N&<$</]@""2&)40`!"`%3-\,\$Y=3G4`````````````@ M``!(YP`R)FP%^"`+9Q0D4R)+("L`""QX``1.KO\N)DI@Z)'(*4@%_"E(!?A,; MWTP`3G5(YP$P+B\`$$JL!@1G%B1L!@0O$B\L!@1.NOW*4$^1R"E(!@1*AV8$U M<`!@'EB'+P=.N@&:6$\F0$J`9@1P`&`*)$LDAT'K``0@"$S?#(!.=4CG#Q`NI M+P`8+"\`'"HO`"`O!TZZ"9183R9`(`MF!'#_8!XO!2\&+RL`!$ZZ!1Q/[P`,; M*`!*K`.X9P1P_V`"(`1,WPCP3G4``$CG`3(N+P`4<`S>@"`'<@`L>``$3J[_( M.B9`(`MF!'``8#HG1P`(1>P%^"!J``0G2``$D<@FB$J29@(DBTJJ``1G!B)J/ M``0BBR5+``1*K`$P9@0I2P$P0>L`#"`(3-],@$YU``````````````````!(] MYP,P+B\`%$J';@9P`&```*1P"+Z`9`(N`"`'5H`N``)'__Q%[`$\)E(@"V=`U M("L`!+"';3*PAV8,(%,DB)^L`4`@"V!N("L`!)"'<@BP@646($O1QR2()$@D] MDR5```2?K`%`(`M@3"1+)E-@O"`'(BP"1-"!4X!.N@8R(BP"1$ZZ!@HL`%"&P M(`96@"P``D;__"\&3KK^^EA/)D`@"V<2+P8O"TZZ^SXNAV$`_U103V`"<`!,G MWPS`3G4``````````'!A+P<N+P`(+P=.NO\R6$\N'TYU```O"R9O``@@"V<0Y M0J=.NOX26$\@2UF(*4@&!'``)E].=4CG`2`N+P`,4JP&$"!L!@Q3J``,;18B^ M:``$1>D``2%*``0@!Q*`<@`2`&`2(`=R`!(`+P@O`4ZZ\.Q03R(`3-\$@$YUB M3E4``$CG`#`F;P`0)&\`%$*L!A`I2P8,2&T`$"\*2'K_G$ZZ[?0NBTAX__].A MNO"R("P&$$SM#`#_^$Y=3G4``$Y5__A(YP`P1^P!2"`+9PQ*JP`89P8D2R93= M8/`@"V8B2'@`(DZZ_R)83R9`2H!F!'``8!PDBW`A<@`@2Q#!4<C__"\++RT`3 M#"\M``A.N@`.3.T,`/_P3EU.=0``3E7_\$CG#S`F;P`T)&\`.$JJ`!AG""\*P M3KH!HEA/*BP!L'X!<``0,W@`#$``8F<*#$``868,>@!@!BH\``"``%*'<BNRO M,W@`5\!$`$B`2,`H`'``$!,,0`!W9P``B`Q``')G0@Q``&%F``"^2'@`#"\\R M``"!`B\M``A.NOKL3^\`#"P`</^\@&8&<`!@``#02H1G!G!`T(!@`G`"+@``_ M1T``8```B$J$9P1P`F`"<```0(``2'@`#"\`+RT`"$ZZ^JA/[P`,+`!P_[R`6 M9@9P`&```(Q*A&<&<$#0@&`"<`$N`&!(2H1G!'`"8`)P`0!`@```0`$``$`"M M`$AX``PO`"\M``A.NOIB3^\`#"P`</^\@&8$<`!@1DJ$9P9P0-"`8`)P`BX`A M8`1P`&`RD<@E2``0<``E0``4)48`'"5J`!``!"5```PE0``(2H5F!B`\``"`$ M`"('@H`E00`8(`I,WPSP3EU.=0``+PLF;P`(""L`!@`;9R(O"TAX__].NN[&0 M4$]![`%(M\AF#DAL`6I(>/__3KKNL%!/4ZL`"&T2(&L`!$/H``$G20`$<``0> M$&`(+PM.NO$L6$\F7TYU2.<#,"9O`!0(*P`!`!MG$"\+2'C__TZZ[G!03RX`" M8`)^`"`K`!A"@&<42JL`%&<.+RL`%"\K`!!.NOD.4$\O*P`<3KH$T%A/+`!P9 M_[Z`9P9*AF8"<`!,WPS`3G5(YP,0+B\`$$?L`4@@"V<T""L``@`;9B@(*P`!/ M`!MG("`K``20JP`0+`!*AF<2+P8O*P`0+RL`'$ZZY09/[P`,)E-@R"\'3KKR4 M"%A/3-\(P$YU``!(YS<0+B\`'"9O`"`L+P`D2JP#T&<$3KH$U$*L`[@B!R0+= M)@8L;`883J[_T"H`</^Z@&8.3J[_?"E``[AP!2E`!A0@!4S?".Q.=0``2.<_\ M`"XO`!PL+P`@*B\`)$JL`]!G!$ZZ!(A"K`.X(`53@"(')`8F`"QL!AA.KO^^" M*`!P_[B`9@Y.KO]\*4`#N'`6*4`&%"`%#(`````"9Q8,@`````%G"$J`9A@@[ M!F`4(`30AF`.(@=T`'8`+&P&&$ZN_[Y,WP#\3G4``$CG-Q`N+P`<)F\`("PO- M`"1*K`/09P1.N@0,0JP#N"(')`LF!BQL!AA.KO_6*@!P_[J`9@Y.KO]\*4`#. MN'`%*4`&%"`%3-\([$YU``!(YR,0)F\`%"XO`!A*K`/09P1.N@/$0JP#N"(+0 M)`<L;`883J[_XBP`2H9F$DZN_WPI0`.X<`(I0`84</]@`B`&3-\(Q$YU``!.! M5?_\2.<A$"9O`!A*K`/09P1.N@-\0JP#N"(+=/XL;`883J[_K"X`2H=G"B('6 M3J[_IG#_8"8B"R0\```#[DZN_^(N`$J'9A).KO]\*4`#N'`"*4`&%'#_8`(@I M!TS?"(1.74YU3E7__$CG(1`F;P`82JP#T&<$3KH#&$*L`[@B"W3^+&P&&$ZNH M_ZPN`$J'9PPB!TZN_Z8B"TZN_[@B"R0\```#[DZN_^(N`$J'9A).KO]\*4`#\ MN'`"*4`&%'#_8`(@!TS?"(1.74YU```O!RXO``A*K`/09P1.N@*V(@<L;`88X M3J[_W'``+A].=4CG,``D`"8!2$)(0\3!QL#`P=1#2$)"0M""3-\`#$YU2H!J' M```>1(!*@6H```Q$@6$``"!$@4YU80``&$2`1(%.=4J!:@``#$2!80``!D2`G M3G4O`DA!-`%F```B2$!(04A"-`!G```&A,$P`DA`-`"$P3`"2$(R`B0?3G4O3 M`W80#$$`@&0```;AF5%##$$(`&0```;IF5E##$$@`&0```;EF55#2D%K```&4 MXYE30S0`YJA(0D)"YJI(0X#!-@`P`C0#2$'$P9""9```"%-#T(%D_G(`,@-(A M0^>X2$#!028?)!].=4Y5_YY(YS,R?@`@;`/H'BC__W!/OH!O`BX`(`=#[?^OE M8`(2V%.`9/I"-7BOD\DL>``$3J[^VB9`2JL`K&=,("L`K.6`)$`L*@`X2H9FQ M!"PK`*!*AF<T(@9!^@"R)`AV"RQL!AA.KO_0($=2AR`(&[P`"@BO(@9![?^OM M)`@F!RQL!AA.KO_0</]@3DJL!@AF$D/Z`(9P`"QX``1.KOW8*4`&"$'M_Z\I; M2`)H2'@`/$AX`/IP`"\`+P!(;`*$2&P"<$AL`EQ"ITZZ`4A/[P`@4X!G!'#_M M8`)P`$S?3,Q.74YU*BH@57-E<B!!8F]R="!297%U97-T960@*BH``$-/3E1)Q M3E5%``!!0D]25``J*BH@0G)E86LZ(`!I;G1U:71I;VXN;&EB<F%R>0``````# M`````````````$CG`1`N+P`,+P=.N@`\6$\F0"`+9@1P_V`H""L``@`#9P9P1 M`":`8!HO*P`$3KK]EEA/<``F@$JL`[AG!'#_8`)P`$S?"(!.=2\'+B\`"'``T M*4`#N$J':R*^K`$L;!P@!^>`0>P#[$JP"`!G#B`'YX!![`/LT<`@"&`(<`DIO M0`84<``N'TYU``!(YP$"<``B/```,``L>``$3J[^SBX``H<``#``2H=F!'``, M8"!*K`/09Q@@;`/03I!*@&8$<`!@#$AX`!1.NNS26$\@!TS?0(!.=6&T3G4`# M`$CG,#(L;`8((&\`&")O`!PD;P`@)F\`)"`O`"@B+P`L)"\`,"8O`#1.KOZD5 M3-],#$YU``````/L````!`````````?\```#>````XX```)@`````@````$`M M```,````!@````````/R```#Z@```.A5<V%G93H@4V@@9FEL92X`<@!3:#H@; M0V%N)W0@;W!E;B`E<R!F;W(@:6YP=70N``!3:#H@0V]U;&1N)W0@86QL;V-A] M=&4@8G5F9F5R(&9O<B!T;VME;B!T97AT+@``=P!3:#H@0V%N)W0@;W!E;B`E^ M<RX``"5S(``*`"5S`````"5S"@`))60Z("5S"@````````(```````````!C0 M870`96-H;P``````````4&%R<V4Z($-O=6QD(&YO="!A;&QO8V%T92!4;VME) M;B!S=')U8W1U<F4N``!087)S93H@0V]U;&0@;F]T(&%L;&]C871E('=O<F0@+ M87)R87DN`%!A<G-E.B!#;W5L9"!N;W0@86QL;V-A=&4@5&]K96X@<W1R=6-T5 M=7)E+@`````````H`````````````````````````````(`````!:@``````- M`````````````````````````````````````8P`````````````````````- M````````````````````````````````````````````````````````````` M`````````(``````(@``%D0``!98```6:@``%H0``!:4```6K```%K8``!;0B M```6Y@``%O@``!<(```7&@``%S0``!=(```75@``%V(``!=X```7B@``%YX`/ M`!>P```7P```%]```!?@```7\@``&!```!A````84```&&(``!AT```8@@``- M&)8``!BL```8O```&,@``!CF```$`/__````#@`.````````)_P`````__\`C M```$``0``````````````DC__P````0`!````````"@8`````/__````!``$> M````````*"(``````"`@("`@("`@("@H*"@H("`@("`@("`@("`@("`@("`@R M2!`0$!`0$!`0$!`0$!`0$(2$A(2$A(2$A(00$!`0$!`0@8&!@8&!`0$!`0$!< M`0$!`0$!`0$!`0$!`0$0$!`0$!""@H*"@H("`@("`@("`@("`@("`@("`@("@ M`A`0$!`@("`@("`@("`@*"@H*"@@("`@("`@("`@("`@("`@("!($!`0$!`0R M$!`0$!`0$!`0A(2$A(2$A(2$A!`0$!`0$!"!@8&!@8$!`0$!`0$!`0$!`0$![ M`0$!`0$!`1`0$!`0$(*"@H*"@@("`@("`@("`@("`@("`@("`@("$!`0$"``[ M``````(````#[````"8````````"D````GP```)4```"0````CP```(X```"Y M-````C````(L```"*````B0```(@```"'````A@```(4```"$````@P```((^ M```"!````@````'\```!^````?0```'P```![````>@```'D```!X````=P`= M``'8```!U````=````',```!R````<0```'````!O````;@````#`````0``5 2`FP```%J```!2`````````/R7 `` end size 11808 SHAR_EOF cat << \SHAR_EOF > Shar.c /* Shar.c Copyright (c) 1987 by Fabbian G. Dufoe, III All rights reserved. Permission is granted to redistribute this program provided the source code is included in the distribution and this copyright notice is unchanged. This program creates a Unix-compatible shell archive in the first file named on the command line. It packs all the command-line files after the first into that archive. For each file to be included in the archive the program writes echo "Creating filename" cat > filename <<"***EOF filename***" Then it writes a copy of the file and terminates it with ***EOF filename*** */ #include <stdio.h> #include <time.h> #ifdef AMIGA #include <error.h> #include <exec/types.h> #else #include <errno.h> #include <ctype.h> extern int sys_nerr; extern char *sys_errlist[]; #endif void main(argc, argv) int argc; char **argv; { int c; /* The character or code returned by getc will be stored here. */ int i; /* This will be used as a loop counter to point to the command line argument the program is processing. */ FILE *in; /* This is the file pointer which will be used to refer to the current input file in the fgetc() and fclose() functions. */ FILE *out; /* This is the file pointer which will be used to refer to the output file in the fputc() and fclose() functions. */ int r; /* The code returned by putc will be stored here. */ long t; /* The current time in seconds returned by the time() function e the string with a null and return. We clude the quotation mark in the string. */ 3 August 1988 */ 1988 */ default: /* 3 August 1988 */ ugust 1988 */ /* This isn't one of the special characters dealt with above, so we just accumulate it into our string. */ The program will write an error message to standard error and terminate. */ { fprintf(stderr, "Usage: shar outputfile file[s]\n"); exit(-1); } if ((out = fopen(argv[1], "r")) == NULL) /* We try to open the file for reading to see if it is there. If the open fails we check the error number to see why. */ { if (errno == ENOENT) /* An error number of ENOENT means the file doesn't exist. That's what we want, so we'll just open it. */ { if ((out = fopen(argv[1], "w")) == NULL) /* If we couldn't open the file for writing print an error message and terminate. */ { fprintf(stderr, "Shar: Couldn't open %s for output.\n", argv[1]); if (errno > 0 && errno < sys_nerr) /* If there is an entry in the system error list for this error, print the reason for the error. */ fprintf(stderr, "\t%d: %s\n", errno, sys_errlist[errno]); exit(-1); /* Terminate with a code to indicate the program did not complete successfully. */ } } else /* If the file open failed for any other reason we know it exists so we want to display the error message and terminate. */ { fprintf(stderr, "Shar: %s already exists.\n", argv[1]); exit(-1); } } else /* If we were able to open the file we want to close it before we print our error message and terminate. */ { (void)fclose(out); /* We don't care if fclose fails--we're going to terminate the program anyway--so we ignore the value it returns by casting it to a void. */ fprintf(stderr, "Shar: %s already exists.\n", argv[1]); exit(-1); } /* If we got this far we succeeded in opening the output file for writing. */ time(&t); /* We want to include the current time in the opening comments. This function gets the number of seconds since the system's base date. */ /* Write some identifying comments to the beginning of the output file. */ fprintf(out, "# This is a shell archive. Remove anything before this line,\n"); fprintf(out, "# then unpack it by saving it in a file and typing \"sh file\"\n"); fprintf(out, "# Created %s#\n", ctime(&t)); fprintf(out, "# This archive contains:\n"); for (i = 2; i < argc; i++) /* Now we are going to list each of the remaining file names in a comment line. */ fprintf(out, "#\t\t%s\n", argv[i]); for (i = 2; i < argc; i++) /* Now we are going to copy each of the remaining file names from the command line. */ { if ((in = fopen(argv[i], "r")) == NULL) /* Try to open the file for reading. If the open fails write an error message. */ { fprintf(stderr, "Shar: couldn't open %s for input.\n", argv[i]); if (errno > 0 && errno < sys_nerr) /* If there is an entry in the system error list for this error, print the reason for the error. */ fprintf(stderr, "\t%d: %s\n", errno, sys_errlist[errno]); } else /* If the file was opened successfully add it to the output file. */ { fprintf(out, "echo \"Creating %s\"\n", argv[i]); fprintf(out, "cat > %s <<\"***EOF %s***\"\n", argv[i], argv[i]); while ((c = getc(in)) != EOF) /* Read the entire input file and copy it to the output file. */ if ((r = putc(c, out)) != c) /* If we couldn't write the character successfully print an error message and terminate. */ { fprintf(stderr, "Shar: couldn't write from %s to %s.\n", argv[i], argv[1]); if (errno > 0 && errno < sys_nerr) /* If there is an entry in the system error list for this error, print the reason for the error. */ fprintf(stderr, "\t%d: %s\n", errno, sys_errlist[errno]); exit(-1); } fprintf(out, "***EOF %s***\n", argv[i]); fclose(in); } } exit(0); } SHAR_EOF cat << \SHAR_EOF > Shar.uu begin 644 Shar M```#\P`````````"``````````$```GP```!^P```^D```GP)$@D`$GY````E M`$?Y```%&'(`(#P```"U8`(FP5'(__PL>``$*4X%4"E/!5A"K`54)FX!%'``F M(CP``#``3J[^SBEK`)@%3$JK`*QG``!P(`^0KP`$!H````"`*4`%'&$``2X@] M:P"LT<C1R")H`!#3R=/)(`)R`!(9*4D%8-"!4H!"9U*``D#__I_`58!"=P@`# M(`)3@-2!'[(``"``4X)1R/_V'[P`("``4X(?L2``(`!1RO_X(D\O"6```'@I: M:P`Z!1QP?U*`T:P%'&$``,)!ZP!<3J[^@$'K`%Q.KOZ,*4`%5"\`)$`@*@`D; M9Q(L;`?,($`B*```*4$%3$ZN_X(B*@`@9QHD/````^U.KO_B*4`%7&<*Y8@@H M0"=H``@`I"!L!50O"$AL!1@@:``D*6@`!`5@3KH#9$ZZ""1P`&`$("\`!"\`' M("P%1&<$($!.D$ZZ&#`L>``$(FP'S$ZN_F).N@,Z2JP%5&<:(BP%7&<$3J[_= MW"QX``1.KO]\(FP%5$ZN_H8@'RYL!5A.=7!D8+1#^@`0<`!.KOW8*4`'S&?L@ M3G5D;W,N;&EB<F%R>0!.5?_HO^P%'&4`#I9(YP\R+B\`/"9O`$!P`[Z`;!A(F M;```2&P"-$ZZ'#1(>/__3KH>C$_O``Q(;``@+RL`!$ZZ'%Q03RM`__!*@&8`# M`(QP`K"L!\AF9$AL`"(O*P`$3KH</%!/*T#_\$J`9@``CB\K``1(;``D2&P"J M-$ZZ&^!/[P`,("P'R$J`;R2PK`)H;![E@$'L`FPO,`@`+RP'R$AL`$A(;`(T` M3KH;M$_O`!!(>/__3KH>"%A/8$`O*P`$2&P`4DAL`C1.NAN42'C__TZZ'>Q/[ M[P`08"(O`$ZZ'80NJP`$2&P`;$AL`C1.NAMP2'C__TZZ'<A/[P`02&W_Z$ZZP M#G1(;`"&+RW_\$ZZ&U!(;`#&+RW_\$ZZ&T1(;?_H3KHB_"Z`2&P!!"\M__!.H MNALN2&P!%"\M__!.NALB3^\`*'H"NH=L'"`%Y8`O,P@`2&P!+B\M__!.NAL$0 M3^\`#%*%8.!Z`KJ';``!<B`%Y8!(;`$V+S,(`$ZZ&R103R1`(`IF3"`%Y8`O[ M,P@`2&P!.$AL`C1.NAK(3^\`#"`L!\A*@&\``3*PK`)H;``!*N6`0>P";"\P) M"``O+`?(2&P!7$AL`C1.NAJ83^\`$&```0@@!>6`+S,(`$AL`68O+?_P3KH:: M?"`%Y8`@<P@`+H@O"$AL`7HO+?_P3KH:9$_O`!A3J@`(;1(@:@`$0^@``25)0 M``1P`!`08`@O"DZZ"J983RP`</^\@&<``)`@;?_P4Z@`#&T6(F@`!$WI``$A. M3@`$(`82@'(`$@!@$B`&<@`2`"\(+P%.N@?04$\B`"@!N(9GGB`%Y8`O*P`$% M+S,(`$AL`99(;`(T3KH9YD_O`!`@+`?(2H!O)+"L`FAL'N6`0>P";"\P"``O2 M+`?(2&P!O$AL`C1.NAFZ3^\`$$AX__].NAP.6$]@`/]*(`7E@"\S"`!(;`'&N M+RW_\$ZZ&90NBDZZ&Y)/[P`,4H5@`/Z,0J=.NAO>3.U,\/_,3EU.=0``3G5.A M=4CG!S`N+P`8)F\`'"PO`"`O!TZZ(9!83R1`(`IF!'#_8#8(*@`#``-G$$AX^ M``)"IR\'3KH4X$_O``PO!B\++RH`!$ZZ&]Q/[P`,*@!*K`4P9P1P_V`"(`5,^ MWPS@3G4``````````'!A3E7_Q$CG)S`F;P!<)&\`8'X`?`!Z`'``&WP`(/_[$ M<@`K0?_V=/\K0O_R0>W_T!M`__$;0/_\*T'_Y"M!_^@K2/_,2A-G0G``$!-RM M&%U!:SBP>Q`(9O9.^Q`$`"-@```@`"!@```6`"M@```,`"U@```"?@%@#GP!> M8`IZ`6`&&WP``?_\4HM@NA`3<C"P`68&4HL;0?_[<"JP$V80(%)#Z``$)(DKV M4/_V4HM@#DAM__8O"TZZ$$103]?`$!-R+K`!9B92BW`JL!-F$"!20^@`!"2)$ M*U#_\E*+8`Y(;?_R+PM.NA`64$_7P!`3<FRP`68*&WP``?_Q4HM@"')HL`%F; M`E*+$!MR`!(`&T#_\'`P74!K``)4LGL`"&;T3OL`!`!C8``"*@!S8``!Z`!8U M8``!?@!X8``!>`!P8``!7@!O8``!#`!U8```X@!D8````DHM__%G#"!20^@`O M!"2)(!!@"B!20^@`!"2)(!`K0/_L;`IR`42M_^PK0?_H2JW_Z&<$<"U@"DH&7 M9P1P*V`"<"`;0/_0<``0!B(M_^B"@'``$`6"@&<(4JW_S%*M_^0O+?_L+RW_D MS$ZZ#J903RM`_\@@+?_R2H!J!G(!*T'_\B`M_\@B+?_RDH!([0`"_\1O+B!MK M_\PB2-/!8`(2V%.`9/IP`!`M__LB+?_$(&W_S&`"$,!3@63Z("W_\BM`_\C1\ MK?_D0>W_T"M(_\Q*!V<``5`;?``@__M@``%&2BW_\6<,(%)#Z``$)(D@$&`*N M(%)#Z``$)(D@$"M`_^Q@`/]B2BW_\6<,(%)#Z``$)(D@$&`*(%)#Z``$)(D@% M$"M`_^Q*+?_\9Q(@;?_,$/P`,'(!*T'_Y"M(_\PO`"\M_\Q.N@X`4$\K0/_(B M8`#_*!M\`##_^R`M__)*@&H&<`@K0/_R2BW_\6<,(%)#Z``$)(D@$&`*(%)#+ MZ``$)(D@$"M`_^Q*+?_\9Q8@;?_,$/P`,!#\`'AR`BM!_^0K2/_,+P`O+?_,] M3KH-W%!/*T#_R'!8L"W_\&8`_KY(;?_03KH,N%A/8`#^L"!20^@`!"2)(E`KH M2?_,9@A!^@#<*TC_S"!M_\Q*&&;\4XB1[?_,*TC_Y"`M__)*@&LJL<!O)BM`[ M_^1@('`!*T#_Y"!20^@`!"2)(!`;0/_00BW_T6`&<`!@``",("W_Y"(M__:RQ M@&P(=``K0O_V8`21K?_V2@=G-E.M_^1M&'``(&W_S!`8+P`K2/_,(&T`$$Z0/ M6$]@XE.M__9M2'``$"W_^R\`(&T`$$Z06$]@Z%.M__9M$G``$"W_^R\`(&T`J M$$Z06$]@Z%.M_^1M&'``(&W_S!`8+P`K2/_,(&T`$$Z06$]@XB`+3-\,Y$Y=W M3G4``$Y5__9(YP$P)F\`'B1O`"(K;0`0__8>&DH'9S1P);X`9B*P$F8$4HI@G M&B\+2&W_]B\*80#[S$_O``PK0/_Z9P0D0<``0!R\`3I-83V#&3-\,@$Y=4 M3G5.5?_P2.<A,B9O`"P,K````"`&XFP``(80$W(@L`%G#'()L`%G!G(*L`%F/ M!%*+8.A*$V=H("P&XN6`4JP&XD'L!NK1P"1(<"*P$V8F4HLDBTH39PIP(K`3^ M9P12BV#R2A-F#$AX``%.N@8P6$]@GD(;8)HDBTH39Q@0$W(@L`%G$'()L`%G? M"G(*L`%G!%*+8.1*$V8"8`9"&V``_W)*K`;B9@8@;`548`1![`;J*4@&YDJL? M!N)F?$'Z`21#[`:H(M@BV"+8(M@RD")L!50@:0`D2'@`*"\H``1(;`:H3KH*\ MSD_O``Q![`:H(@@D/````^XL;`?,3J[_XBE`!6@I0`5P<@0I005L*4`%>"E!+ M!73E@)/)+'@`!"M`__!.KO[:(&W_\")`(V@`"`"D?@`K0/_T8"HL;`?,3J[_Q MRBE`!6A.KO_$*4`%<$'Z`*8B""0\```#[4ZN_^(I0`5X?@0@!P!`@`&!K`5D; M(`<`0(`"@:P%;`"L``"``P5T2JP"6&<$<`!@!B`\``"``"X`0JP"#"`'`$``M M`2E``@AP`2E``BX@!P!```(I0`(J<`(I0`)0(`<`0`"`*4`"3$'Z&88I2`5(? M+RP&YB\L!N).NO:&0I=.NA4\3.U,A/_<3EU.=6-O;CHQ,"\Q,"\S,C`O.#`O' M`"H`````````````````````````````````````````````````+PLF;P`(! M2JL`%&<,""L``P`;9@1P`&`V+RP$R$ZZ$0)83R=```0G0``02H!F"G`,*4`'N MR'#_8!8G;`3(`!1P\\&K`!AP`"=```PG0``()E].=0``````````````````A M3E7_[$CG+Q`N+P`T)F\`."@'<#'`JP`89P9P_V```G`(*P`'`!I6P$0`2(!(9 MP"P`2JL`%&8``(0(*P`"`!MF>G``)T``#'+_OH%G``)"+PM.NO].6$]*@&<,` M".L`!0`;</]@``(J".L``0`;2@9G#B`K`!0B`$2!)T$`#&`(("L`%"=```Q3I MJP`,;18@:P`$0^@``2=)``0@!Q"`<@`2`&`2(`=R`!(`+PLO`6$`_U)03R(`> M(`%@``'6""L``@`;9UAP_[Z`9@9P`&```<(@!QM`__]*!F<B<@J^@68<<@(O, M`4AZ`;(O*P`<*T'_\$ZZ]]Q/[P`,*@!@&G(!+P%(;?__+RL`'"M!__!.NO?`V M3^\`#"H`?O]@``#@".L``0`;2@9G4G#_OH!G3%2K``QR"KZ!9B8@:P`$0^@`U M`2=)``00O``-(BL`#$J!:PHO"R\`80#^KE!/4JL`#"!K``1#Z``!)TD`!"`'; M$(`B*P`,2H%K``$<?O\@*P`$D*L`$"M`__!G<@@K``8`&F=22'@``D*G+RL`7 M'$ZZ#$A/[P`,*T#_[$H&9SA3K?_L;3)"IR\M_^PO*P`<3KH,*$AX``%(;?_]E M+RL`'$ZZ"AA/[P`82JP%,&8*$"W__7(:L`%GR"\M__`O*P`0+RL`'$ZZ]N!/. M[P`,*@!@`GH`</^Z@&8(".L`!0`;8`RZK?_P9P8(ZP`$`!M*!F<.(BL`%"0!W M1((G0@`,8!@(*P`"`!MG"'(`)T$`#&`((BL`%"=!``P@:P`0)T@`!+Z`9RY3) MJP`,;18@:P`$0^@``2=)``0@!Q"`<@`2`&`2(`=R`!(`+PLO`6$`_9!03R(`: M<##`JP`89P1P_V`,</^X@&8$<`!@`B`$3-\(]$Y=3G4-"@````!(YP<0)F\`W M%`@K``<`&E;`1`!(@$C`+@!P,,"K`!AG"D*K``AP_V```5@(*P`'`!MG%`@KT M``8`&V<,+PM(>/__3KK](E!/2JL`%&8V0JL`"`@K``(`&V<2<`$G0``40>L`- M("=(`!!@``"$+PM.NOR66$]*@&=V".L`!0`;</]@``$`2@=G9E2K``@@*P`(` M2H!N6B!K``1#Z``!)TD`!'P`'!`@!@R`````&F<N#(`````-9C)3JP`(;10@B M:P`$0^@``2=)``1P`!`08```M"\+80#_+EA/8```J`CK``0`&W#_8```G"`&- M8```E@@K``$`&V9.".L````;+RL`%"\K`!`O*P`<3KH(/$_O``PJ`$J%:@8(< MZP`%`!M*A68&".L`!``;2H5O&DH'9PH@!42`)T``"&`$)T4`""!K`!`G2``$P M<#+`JP`89Q9*!V<(</\G0``(8`9P`"=```AP_V`@4ZL`"&T2(&L`!$/H``$G; M20`$<``0$&`(+PMA`/Z$6$],WPC@3G4``$CG!P`N+P`0+"P!U$I&:S`@!DC`( MYX!![`5D*C`(`$H%9QH(!0`"9A0@!DC`YX!![`5D+S`(!$ZZ$KA83U-&8,PO[ M!TZZ\0983TS?`.!.=0``````````<&$N;`583KH2LDAY````%$ZZ$`P`````( M`````'!A3E7_^"\+)FP&I"`+9@1'^@!\&5,'?!EK``$'?1EK``('?D(L!W]!K M[`=\*4@'=$'K``-(;?_X+PA.N@5:4$]6@-?`("W_^"(\```.$$ZZ$P(I0`=P= M2A-G'AE3!X`9:P`!!X$9:P`"!X)P`!E`!X-R`2E!!VQ@"$(L!X!"K`=L0>P'& M@"E(!W@F7TY=3G5#4U0V````````````````````````````````````````# M`````````````$Y5__)(YP<0)F\`)DAM__A.N@MR6$]Z`!`M__DL``8&``I^< M`+X&9")P`!`'5(!R!$ZZ$H9*@68(!H4```%N8`8&A0```6U2!V#:?@$0+?_Z5 MO@!D%'``$`=R`$'L`EL2,`@`VH%2!V#D<``0!E2`<@1.NA)&2H%F#!`M__IR0 M`K`!8P)2A7``$"W_^U.`VH`@!7(83KH2!"H`<``0+?_\VH`@!7(\3KH1\BH`$ M<``0+?_]VH`@!7(\3KH1X"H`<``0+?_^VH!.NOZ"VJP'<"`+9P(FA2`%3-\(9 MX$Y=3G55;FMN;W=N(&5R<F]R(&-O9&4``%5S97(@:7,@;F]T(&]W;F5R`$YO7 M('-U8V@@9FEL92!O<B!D:7)E8W1O<GD`3F\@<W5C:"!P<F]C97-S`$EN=&5RZ M<G5P=&5D('-Y<W1E;2!C86QL`$DO3R!E<G)O<@!.;R!S=6-H(&1E=FEC92!O5 M<B!A9&1R97-S`$%R9R!L:7-T(&ES('1O;R!L;VYG``!%>&5C(&9O<FUA="!E? M<G)O<@!"860@9FEL92!N=6UB97(`3F\@8VAI;&0@<')O8V5S<P``3F\@;6]R@ M92!P<F]C97-S97,@86QL;W=E9`!.;R!M96UO<GD@879A:6QA8FQE`$%C8V5SZ M<R!D96YI960`0F%D(&%D9')E<W,`0G5L:R!D979I8V4@<F5Q=6ER960``%)E? M<V]U<F-E(&ES(&)U<WD``$9I;&4@86QR96%D>2!E>&ES=',`0W)O<W,M9&5VH M:6-E(&QI;FL`3F\@<W5C:"!D979I8V4``$YO="!A(&1I<F5C=&]R>0!)<R!A# M(&1I<F5C=&]R>0``26YV86QI9"!A<F=U;65N=```3F\@;6]R92!F:6QE<R`H* M=6YI=',I(&%L;&]W960`3F\@;6]R92!F:6QE<R`H=6YI=',I(&%L;&]W960@S M9F]R('1H:7,@<')O8V5S<P``3F]T(&$@=&5R;6EN86P``%1E>'0@9FEL92!I: M<R!B=7-Y`$9I;&4@:7,@=&]O(&QA<F=E`$YO('-P86-E(&QE9G0`4V5E:R!IT M<W-U960@=&\@<&EP90!296%D+6]N;'D@9FEL92!S>7-T96T`5&]O(&UA;GD@, M;&EN:W,``$)R;VME;B!P:7!E`$UA=&@@9G5N8W1I;VX@87)G=6UE;G0@97)R, M;W(``$UA=&@@9G5N8W1I;VX@<F5S=6QT(&ES(&]U="!O9B!R86YG90``2.<@5 M,"9O`!`D2TH29R1P`!`20>P#Q0@P``$(`&<*<@`2`'0@DH)@!'(`$@`4@5**I M8-@@"TS?#`1.=0``````````<&%.5?_X2.<#,"9O`"`D;P`D+B\`*"!*2AAF1 M_%.(D<HL""!+2AAF_%.(D<L@"")+T\`K2?_XO(=C`BP'(`8@2F`"$MA3@&3Z' M(&W_^$(P:``@"TS?#,!.74YU("\`""!O``1.5?_T(D]R"DZZ#I@&00`P$L%*= M@&;P(`D0X;_)9OI"$)"/3EU.=0``("\`""!O``1.5?_T(D\B``)!``<&00`P+ M$L'FB&;P(`D0X;_)9OI"$)"/3EU.=0``,#$R,S0U-C<X.6%B8V1E9B`O``@@1 M;P`$0^\`!#(``D$`#Q+[$-SHB&;R(`DB#UB!$.&RB6;Z0A"0@4YU(&\`!")(0 M<@!P`"\"#!``*V<&#!``+68"4D@0&`0``#!M$@P```EN#"0!Y8'2@M*!TH!@@ MY@P1`"UF`D2!)!\@"%.`(&\`"""!D(E.=2\'+B\`"%*L!X@@!R!L!X00P"E(6 M!X0N'TYU3E4``$CG`#`F;P`0)&\`%$*L!X@I2P>$2&T`$"\*2'K_QDZZ\GX@" M;`>$0A`@+`>(3.T,`/_X3EU.=4Y5_^A(YP$R+B\`-$J';@9P_V```-)P"+Z`G M9`(N`"`'5H`N``)'__PD;0`((&T`"-''WZP!Z$/L`>0F42M(__`K2?_T(`MGC M``"0($L@*P`$T<`K2/_L(FW_\+?)8Q`DBR5'``0L;?_T+(IP`&!XM\EF&BQ32 M)(X@*P`$(@#2AR5!``0L;?_T+(IP`&!:M<AD")^L`>AP_V!.M<AF+$J39PX@- M4[/(8PB?K`'H</]@.-^K``1*DV<.L]-F"B`I``31JP`$)I%P`&`>*TO_]"MM] M_^S_Z"938`#_;B!M__0@BD*2)4<`!'``3-],@$Y=3G4``````````'!A2.<!< M$"9O``PN+P`0+P<O"TZZ_O903TS?"(!.=4CG!S`N+P`8)F\`'"PO`"`O!TZZD M#GQ83R1`(`IF!'#_8!XO!B\++RH`!$ZZ":A/[P`,*@!*K`4P9P1P_V`"(`5,G MWPS@3G4``$Y5_^9(YP\P)F\`.BXO`#Y"+?__0JP%,"ML!\C_\GH#NJP!U&P2+ M(`7G@$'L!61*L`@`9P12A6#H("P!U+"%9@QP&"E`!\AP_V```2H@!>>`0>P%N M9-'`)$A*K0`09P@(+0`"`!-G"BM\```#[/_N8`@K?````^[_[B`\``"``,"L* M`>RQAP@'``-G#"`'`D#__"X``$<``B`'<@/`@0R``````F<,#(`````!9P1*E M@&8&+`=2AF`,<!8I0`?(</]@``"T(`<"@````P!G``"("`<`"F<6&WP``?__K M+RW_[B\+3KH)/E!/*`!@/`@'``EF%DAX`^TO"TZZ".!03R@`2H1J!`C'``D(& M!P`)9QH;?``!__\I;?_R!\@O+?_N+PM.N@ED4$\H`$HM__]G-B`'<GC2@<"!S M2H!G*DJ$:R8O!$ZZ":Q(>`/M+PM.N@B.3^\`#"@`8`Y(>`/M+PM.N@A\4$\H/ M`$JL!3!G!'#_8`@DAB5$``0@!4S?#/!.74YU````````````````2.<`,B9LQ M!XP@"V<4)%,B2R`K``@L>``$3J[_+B9*8.B1R"E(!Y`I2`>,3-],`$YU2.</6 M$"XO`!@L+P`<*B\`("\'3KH,?%A/)D`@"V8$</]@'B\%+P8O*P`$3KH'+$_O* M``PH`$JL!3!G!'#_8`(@!$S?"/!.=0``2.<!,BXO`!1P#-Z`(`=R`"QX``1.A MKO\Z)D`@"V8$<`!@.B='``A%[`>,(&H`!"=(``21R":(2I)F`B2+2JH`!&<&& M(FH`!"*+)4L`!$JL`=AF!"E+`=A!ZP`,(`A,WTR`3G4`````````````````1 M`$Y5_^A(YP\0)F\`-"`3(CP``5&`3KH)6BM`__`L`"`3(CP``5&`3KH)2"X!@ M(`<B/```#A!.N@DZ*``@!R(\```.$$ZZ"2PN`2`'<CQ.N@DB*T#_Z"`'<CQ.B MN@D6+@$I1P><*6W_Z`>@*40'I$AM__!A``!,*@`@!02````';"E`![`I;?_P3 M![@NA4AM__!A``"&*4`'K"`M__!2@"E`!Z@@!EB`<@=.N@C(*4$'M$'L!YP@C M"$SM"/#_U$Y=3G5(YP,0)F\`$"X\```'LBP3#(8```%M;QX@!W($3KH(E$J!< M9@@$A@```6Y@!@2&```!;5*'8-H,A@```6UF$"`'<@1.N@AN2H%G!%*'?``F: MAB`'3-\(P$YU2.<'$"9O`!0N+P`8(`=R!$ZZ"$A*@68&<!TI0`,`>@`L$W`,A MNH!L'"`%Y8!![`+\(C`(`+*&;@Q![`+\G+`(`%*%8-XFAB`%3-\(X$YU2.<#P M,"XO`!1*AVX&<`!@``"D<`B^@&0"+@`@!U:`+@`"1__\1>P!Y"92(`MG0"`K^ M``2PAVTRL(=F#"!3)(B?K`'H(`M@;B`K``20AW((L(%E%B!+T<<DB"1()),E2 M0``$GZP!Z"`+8$PD2R938+P@!R(L`OC0@5.`3KH'DB(L`OA.N@=J+`!0AB`&P M5H`L``)&__PO!DZZ_9983R9`(`MG$B\&+PM.NOHJ+H=A`/]44$]@`G``3-\,R MP$YU``````````!P82\'+B\`""\'3KK_,EA/+A].=0``3E7_X$CG+Q`F;P!`: M0>W_]"((+&P'S$ZN_T`@+?_T+CP```>Z+``K0/_P#(8```%M;QX@!W($3KH&: M_$J!9@@$A@```6Y@!@2&```!;5*'8-H,A@```6UF$"`'<@1.N@;62H%G!%*'E M?``@!B('!($```>\%T$``70`%`$K0/_P(`)R!$ZZ!K!*@68$<!U@`G`<&4`#Q M+7@`*BW_\'`,N(!L'G``0>P#+!`P2`"PA6X0<`!![`,L$#!(`)J`4H1@W"`%5 M(@12@1=!``(K0/_P4H`70``#("W_]'('3KH&6A:!("W_^'(\3KH&3A=```0@: M+?_X<CQ.N@9`%T$`!2`M__QR,DZZ!C(70``&("W__'(R3KH&)-*!%T$`!TS?! M"/1.74YU2.<!("XO``Q2K`?$(&P'P%.H``QM%B)H``1%Z0`!(4H`!"`'$H!R@ M`!(`8!(@!W(`$@`O""\!3KKMU%!/(@!,WP2`3G5.50``2.<`,"9O`!`D;P`4@ M0JP'Q"E+!\!(;0`0+PI(>O^<3KKJV"Z+2'C__TZZ[9H@+`?$3.T,`/_X3EU.K M=0``3E7_^$CG`#!'[`'P(`MG#$JK`!AG!B1+)E-@\"`+9B)(>``B3KK^(EA/& M)D!*@&8$<`!@'"2+<"%R`"!+$,%1R/_\+PLO+0`,+RT`"$ZZ``Y,[0P`__!.F M74YU``!.5?_P2.</,"9O`#0D;P`X2JH`&&<(+PI.N@%.6$\J+`)8?@%P`!`S( M>``,0`!B9PH,0`!A9@QZ`&`&*CP``(``4H=R*[(S>`!7P$0`2(!(P"@`<``0B M$PQ``'=G``"(#$``<F="#$``868``+Y(>``,+SP``($"+RT`"$ZZ^-A/[P`,] M+`!P_[R`9@9P`&```-!*A&<&<$#0@&`"<`(N``!'0`!@``"(2H1G!'`"8`)P, M``!`@`!(>``,+P`O+0`(3KKXE$_O``PL`'#_O(!F!G``8```C$J$9P9P0-"`7 M8`)P`2X`8$A*A&<$<`)@`G`!`$"```!``0``0`(`2'@`#"\`+RT`"$ZZ^$Y/F M[P`,+`!P_[R`9@1P`&!&2H1G!G!`T(!@`G`"+@!@!'``8#*1R"5(`!!P`"5`@ M`!0E1@`<)6H`$``$)4``#"5```A*A68&(#P``(``(@>"@"5!`!@@"DS?#/!.[ M74YU``!(YP,P)F\`%`@K``$`&V<0+PM(>/__3KKKK%!/+@!@`GX`("L`&$*`: M9Q1*JP`49PXO*P`4+RL`$$ZZ]TY03R\K`!Q.N@6H6$\L`'#_OH!G!DJ&9@)P] M`$S?#,!.=4CG`Q`N+P`01^P!\"`+9S0(*P`"`!MF*`@K``$`&V<@("L`!)"K1 M`!`L`$J&9Q(O!B\K`!`O*P`<3KKC^D_O``PF4V#(+P=.NN]$6$],WPC`3G4`X M`$CG-Q`N+P`<)F\`("PO`"1*K`5(9P1.N@6L0JP%,"(')`LF!BQL!\Q.KO_0G M*@!P_[J`9@Y.KO]\*4`%,'`%*4`'R"`%3-\([$YU``!(YS\`+B\`'"PO`"`J< M+P`D2JP%2&<$3KH%8$*L!3`@!5.`(@<D!B8`+&P'S$ZN_[XH`'#_N(!F#DZNE M_WPI0`4P<!8I0`?((`4,@`````)G%@R``````6<(2H!F&"`&8!0@!-"&8`XBO M!W0`=@`L;`?,3J[_ODS?`/Q.=0``2.<W$"XO`!PF;P`@+"\`)$JL!4AG!$ZZ8 M!.1"K`4P(@<D"R8&+&P'S$ZN_]8J`'#_NH!F#DZN_WPI0`4P<`4I0`?((`5,% MWPCL3G4``$CG(Q`F;P`4+B\`&$JL!4AG!$ZZ!)Q"K`4P(@LD!RQL!\Q.KO_BO M+`!*AF823J[_?"E`!3!P`BE`!\AP_V`"(`9,WPC$3G4``$Y5__Q(YR$0)F\`W M&$JL!4AG!$ZZ!%1"K`4P(@MT_BQL!\Q.KO^L+@!*AV<*(@=.KO^F</]@)B(+6 M)#P```/N3J[_XBX`2H=F$DZN_WPI0`4P<`(I0`?(</]@`B`'3-\(A$Y=3G5./ M5?_\2.<A$"9O`!A*K`5(9P1.N@/P0JP%,"(+=/XL;`?,3J[_K"X`2H=G#"('U M3J[_IB(+3J[_N"(+)#P```/N3J[_XBX`2H=F$DZN_WPI0`4P<`(I0`?(</]@A M`B`'3-\(A$Y=3G4``"\'+B\`"$JL!4AG!$ZZ`XXB!RQL!\Q.KO_<<``N'TYU; M3E7_L"\.2JP'F&820_H`B'``+'@`!$ZN_=@I0`>8<``@;`5@$"C__T/M_[!@H M`A+84X!D^G``(&P%8!`H__]"-0BP0>W_L"E(`T1(>``H2'@`^G``+P`O`$AL< M`V!R`"\!2&P#3"\!3KH#9$AX`!1.NNR`+&W_K$Y=3G4J*B!3=&%C:R!/=F5R' M9FQO=R`J*@``15A)5```:6YT=6ET:6]N+FQI8G)A<GD`````````````````L M2.<P`"0`)@%(0DA#Q,'&P,#!U$-(0D)"T(),WP`,3G5*@&H``!Y$@$J!:@``' M#$2!80``($2!3G5A```81(!$@4YU2H%J```,1(%A```&1(!.=2\"2$$T`68`H M`")(0$A!2$(T`&<```:$P3`"2$`T`(3!,`)(0C(")!].=2\#=A`,00"`9```U M!N&944,,00@`9```!NF964,,02``9```!N6954-*06L```;CF5-#-`#FJ$A"X M0D+FJDA#@,$V`#`"-`-(0<3!D()D```(4T/0@63^<@`R`TA#Y[A(0,%!)A\D8 M'TYU3E7_GDCG,S)^`"!L!6`>*/__<$^^@&\"+@`@!T/M_Z]@`A+84X!D^D(U^ M>*^3R2QX``1.KO[:)D!*JP"L9TP@*P"LY8`D0"PJ`#A*AF8$+"L`H$J&9S0B% M!D'Z`+(D"'8++&P'S$ZN_]`@1U*'(`@;O``*"*\B!D'M_Z\D""8'+&P'S$ZN: M_]!P_V!.2JP'F&820_H`AG``+'@`!$ZN_=@I0`>80>W_KRE(`Y1(>``\2'@`- M^G``+P`O`$AL`[!(;`.<2&P#B$*G3KH!;$_O`"!3@&<$</]@`G``3-],S$Y=J M3G4J*B!5<V5R($%B;W)T(%)E<75E<W1E9"`J*@``0T].5$E.544``$%"3U)41 M`"HJ*B!"<F5A:SH@`&EN='5I=&EO;BYL:6)R87)Y````3E7__"\+)F\`$$ZZH MZI0@$Y"L!W`K0/_\2&W__$ZZ]((N@$ZZ`1@F;?_X3EU.=0``2.<!$"XO``PO7 M!TZZ`#Q83R9`(`MF!'#_8"@(*P`"``-G!G``)H!@&B\K``1.NOR^6$]P`":`V M2JP%,&<$</]@`G``3-\(@$YU+P<N+P`(<``I0`4P2H=K(KZL`=1L'"`'YX!!J M[`5D2K`(`&<.(`?G@$'L!631P"`(8`AP"2E`!\AP`"X?3G4``$CG`0)P`"(\" M```P`"QX``1.KO[.+@`"AP``,`!*AV8$<`!@($JL!4AG&"!L!4A.D$J`9@1P/ M`&`,2'@`%$ZZZ3983R`'3-]`@$YU8;1.=0``2.<P,BQL!Y@@;P`8(F\`'"1OJ M`"`F;P`D("\`*"(O`"PD+P`P)B\`-$ZN_J1,WTP,3G4``"\+)F\`""`K`!CE< M@"(K`!#E@2\K`!0O$R\K``0O*P`(+RL`#$'L!,PO,!@`0>P$_"\P"`!(>@!D' M2&P'T$ZZ[R!/[P`D0>P'T"`()E].=4IA;@!&96(`36%R`$%P<@!-87D`2G5NU M`$IU;`!!=6<`4V5P`$]C=`!.;W8`1&5C`%-U;@!-;VX`5'5E`%=E9`!4:'4`T M1G)I`%-A=``E<R`E<R`E,#)D("4P,F0Z)3`R9#HE,#)D(#$Y)3`R9`H````#[ M[`````(````!````#`````8````````#\@```^H```%&57-A9V4Z('-H87(@' M;W5T<'5T9FEL92!F:6QE6W-="@!R`'<`4VAA<CH@0V]U;&1N)W0@;W!E;B`EN M<R!F;W(@;W5T<'5T+@H`"25D.B`E<PH``%-H87(Z("5S(&%L<F5A9'D@97AI9 M<W1S+@H`4VAA<CH@)7,@86QR96%D>2!E>&ES=',N"@`C(%1H:7,@:7,@82!SW M:&5L;"!A<F-H:79E+B`@4F5M;W9E(&%N>71H:6YG(&)E9F]R92!T:&ES(&QIE M;F4L"@``(R!T:&5N('5N<&%C:R!I="!B>2!S879I;F<@:70@:6X@82!F:6QER M(&%N9"!T>7!I;F<@(G-H(&9I;&4B"@`C($-R96%T960@)7,C"@``(R!4:&ES2 M(&%R8VAI=F4@8V]N=&%I;G,Z"@`C"0DE<PH``'(`4VAA<CH@8V]U;&1N)W0@V M;W!E;B`E<R!F;W(@:6YP=70N"@``"25D.B`E<PH``&5C:&\@(D-R96%T:6YGU M("5S(@H`8V%T(#X@)7,@/#PB*BHJ14]&("5S*BHJ(@H``%-H87(Z(&-O=6QDE M;B=T('=R:71E(&9R;VT@)7,@=&\@)7,N"@``"25D.B`E<PH``"HJ*D5/1B`E^ M<RHJ*@H`````*`````````````````````````````"``````A(`````````W M``````````````````````````````````(T````````````````````````V M````````````````````````````````````````````````````````````` M``````"``!\<'QX?'A\?'A\>'P```"(``!'\```2$```$B(``!(\```23```> M$F0``!)N```2B```$IX``!*P```2P```$M(``!+L```3````$PX``!,:```3J M,```$T(``!-6```3:```$W@``!.(```3F```$ZH``!/(```3^```%`@``!0:G M```4+```%#H``!1.```49```%'0``!2````4G@``!``````?````'````!\`4 M```>````'P```!X````?````'P```!X````?````'@```!\?'!\>'QX?'QX?# M'A___P````X`#@```````````````/__````!``$````````(WX```,X__\`W M```$``0````````CE`````#__P````X`#@```````"5\`````/__````!``$` M``````````````-T__\````$``0````````EF`````#__P````0`!```````` M`"6B```````@("`@("`@("`H*"@H*"`@("`@("`@("`@("`@("`@($@0$!`0W M$!`0$!`0$!`0$!"$A(2$A(2$A(2$$!`0$!`0$(&!@8&!@0$!`0$!`0$!`0$!9 M`0$!`0$!`0$!$!`0$!`0@H*"@H*"`@("`@("`@("`@("`@("`@("`@(0$!`0= M("`@("`@("`@("@H*"@H("`@("`@("`@("`@("`@("`@2!`0$!`0$!`0$!`0` M$!`0$(2$A(2$A(2$A(00$!`0$!`0@8&!@8&!`0$!`0$!`0$!`0$!`0$!`0$!P M`0$0$!`0$!""@H*"@H("`@("`@("`@("`@("`@("`@("`A`0$!`@```````"X M````)U(``"=6```G6@``)UX``"=B```G9@``)VH``"=N```G<@``)W8``"=Z/ M```G?@``)X(``">&```GB@``)XX``">2```GE@``)YH```/L````.P``````" M``44```%$```!0P```4(```%!```!0````3\```$^```!/0```3P```$[```R M!.@```3D```$X```!-P```38```$U```!-````3,```#O````Z@```.````#@ M;````U@```+T```"\````NP```+H```"Y````N````+<```"V````M0```+0O M```"S````L@```+$```"P````KP```*X```"M````K````*L```"J````J0`^ M``*@```"G````I@```*4```"D````HP```*(```"A````H````)\```">```: J`G0```)P```";`````0````!```#F````UP```(2```!\`````````/R/ `` end size 11832 SHAR_EOF cat << \SHAR_EOF > Token.h typedef enum { T_CAT, /* The token is the "cat" command. To be a command the token must be the first one on the line. */ T_ECHO, /* The token is the "echo" command. It must be the first token on the line. */ T_GT, /* The token is ">" indicating redirection of standard output. It must be preceded by a T_CAT or T_ECHO token. */ T_LTLT, /* The token is "<<" indicating "here document" redirection. It must be preceded by a T_CAT or T_ECHO token. The next word defines the "here document" terminator. Subsequent lines from the input file are treated as input for the command on this line. */ T_NL, /* The token is a newline character. It means we have encountered the end of the text line. There are no more tokens to identify. */ T_WORD /* The token is any word not of the above type. A word is a string of characters surrounded by white space or enclosed in double quotation marks. */ } TOKEN; /* This is a list of recognized token types. */ struct Token /* This is a linked list of tokens giving type, text, and pointer to the next token. */ { TOKEN type; /* This is the token type. It must have one of the values listed under the data type TOKEN. */ char *text; /* This is a pointer to a character string containing the actual text of the token. */ struct Token *next; /* This is a pointer to the next token structure in the list. When it is NULL there are no more tokens. */ }; 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.