home *** CD-ROM | disk | FTP | other *** search
- From: jtn@potomac.ads.com (John T. Nelson)
- Newsgroups: alt.sources
- Subject: ASCIIFY and BINAFY... programs for exchanging binary files...
- Message-ID: <8743@potomac.ads.com>
- Date: 7 Jun 90 17:22:23 GMT
-
-
- Asciify and binafy are a pair of programs for converting arbitrary
- format files into ASCII representation for later transmission through
- network mailers. These programs are superior to Binhex, Mcvert, xbin,
- et al in that no assumptions are made concerning the type of file being
- encoded. Also, Asciify and Binafy were written with ease of protability
- in mind. A Macintosh port is now underway.
-
- I welcome bug reports and suggestions for future improvement of this
- program. I may be reached at kzin!speaker@mimsy.umd.edu or
- jtn@potomac.ads.com.
-
- unzip here [O ]-8-8-8-8-8-8-8-8-8-8-8-8-8-8-8-8-8-8-8-8-8-8-8-8-8-8-8-8-8-
-
- echo x - asciify
- mkdir asciify
- echo x - asciify/asciify.1
- sed 's/^x//' >asciify/asciify.1 <<'!Funky!Stuff!'
- x.\" @(#)asciify.1 1.0 90/06/1 SMI;
- x.TH ASCIIFY 1 "01 June 1990"
- x.SH NAME
- x.LP
- xasciify \- convert file contents into asciified format
- x.LP
- xbinafy \- convert asciified file back to original format
- x.SH SYNOPSIS
- x.LP
- x.B asciify
- x[
- x.IR -c
- x]
- x.IR file
- x[
- x.IR asciified_file
- x]
- x.LP
- x.B binafy
- x.IR asciified_file
- x[
- x.IR file
- x]
- x
- x.SH DESCRIPTION
- x.LP
- x.B Asciify
- xand
- x.B binafy
- xare a pair of programs for converting arbitrary format files into
- xASCII representation for later transmission through network mailers.
- xThis program is superior to Binhex, Mcvert, xbin, et al in that
- xno assumptions have been made concerning the type of file being encoded.
- xAlso, asciify and binafy were written for ease of porting
- xbetween different machine architectures and thus facilitating
- xa common interchange standard for files of any format.
- x
- xI believe this calls for some diabolical laughter... MWWAHHA HAH HAW
- xHA HA HA HA!!!
- x
- x.nf
- x.LP
- xHere's what an asciified file looks like:
- x
- x(This file must be decoded with Binafy)
- x!Asciify Version 1.00!File t!Chk!
- x7)GI;9*N*'3[;X7T*(+W>H[K=H>B:I+K;XCV$BK+=D#V<(6B;H_T;9/V*(_H*)3J!4327!
- x;4#P<8?J?"J,7XCC?$#K=8WQ>I3C=$#J:8[F*(_T*(7[;2J,2X_W=(2B;I+C=86B!4161!
- x .
- x .
- x .
- x?(C[*(;G:9+H?8RB>YGO=87V>IFa$d!2125!
- x!!
- x.fi
- x
- xAnything outside the parenthetical line and the final bangs are ignored.
- xAnything following the bang on each line is a checksum, used for error
- xdetection. Unlike Binhex, the binafy program will tell you which line
- xhad a checksum error if one occurs, although there isn't much that the
- xprogram can do to correct the error.
- x
- x.SH USING ASCIIFY
- x.LP
- xThe command line...
- x.IP
- x.B
- xexample% asciify binary_file asciified_file
- x.LP
- xconverts binary_file into the
- x.B
- xasciify
- xformat and puts it into file
- x.B
- xasciified_file.
- xIf no target file is specified then the output is placed onto
- xstandard output.
- x
- xThe command line...
- x.IP
- x.B
- xexample% binafy asciified_file file
- x.LP
- xconverts the asciified format file into its original format
- xand places it in
- x.B
- xfile.
- x
- xIf no target file is specified then the output is placed onto
- xstandard output so in the case of binafy you'll want to redirect output
- xsomeplace. For example:
- x.IP
- x.B
- xexample% binafy asciified_file > file
- x
- x.SH "SEE ALSO"
- x.BR binafy (1),
- x
- x.SH HOW IT WORKS
- x.LP
- xThree bytes of the original file are read and converted into 4
- xcharacters representing 6 bits each of the original 3 bytes. Note that
- x6 divides into 12 ( 3 bytes times 8 bits per byte) quite evenly. The 64
- xcharacters of the ASCII character set starting with the double quote
- x(hex 22) character are used. The exclamation point character is
- xreserved as a special delimeter.
- x
- xNote that we have used only 64 of the 94 some printable characters.
- x
- xIn case the number of bytes in a file is not evenly divisible by 3, a
- xspecial encoding is used to represent the remaining piece of the byte.
- xThe remaining pieces can be either 2 bits or 4 bits and thus consume 20
- xmore ASCII printable characters. Because these characters are unique in
- xthe encoding we will know when the end of a file has arrived and, more
- ximportantly, we will know what these characters represent because they
- xare outside of the main encoding scheme.
- x
- xThis encoding scheme yields a 4 for 3 decompression which I consider to
- xbe fairly effecient.
- x
- x.SH INSTALLATION
- x.LP
- xJust type
- x.B make asciify
- xto build
- x.B asciify
- xand
- x.B make binafy
- xto build
- x.B binafy
- x
- xBoth should compile and generate binaries called
- x.B asciify
- xand
- x.B binafy
- xrespectively.
- x
- x.SH FUTURE ENHANCEMENTS
- x.LP
- xSupport binafying of multipart files. It's simple enough
- xto split files apart with the Unix "split" program. It would
- xbe nice if asciify and binafy split and assembled multiple files
- xautomagically. Note that the above example has a "part of" spec in the
- xheader. That's how binafy will know what order to assemble the files
- xin.
- x
- xThe file format is incompatible with Binhex and uuencode/uudecode
- xformats. I should probably provide compatibility and cross-conversion
- xfor these too, but since I can't find their source code you'll just
- xhave to use
- x.B asciify
- xformat for now.
- x
- xMagic strings.
- x
- x.SH BUGS
- x.LP
- xThe ANSI C standard actually makes no assumptions concerning
- xthe size of a character or byte, therefore this program will
- xprobably do the wrong thing on machines with 13-bit bytes.
- xThis should not be an immediate concern as most machines use 8 bit
- xbytes.
- x
- xAlso note that I have avoided the use of the fscanf/sscanf whenever
- xpossible. This is because the behavior of these library routines
- xvaries from implementation to implementation.
- x
- x.SH AUTHOR
- x.LP
- x.nf
- x=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- xORGANIZATION: Kzinti Embassy GEOGRAPHIC: McLean, VA
- xUUCP: kzin!speaker@mimsy.umd.edu INTERNET: jtn@potomac.ads.com
- xSPOKEN: Hey Stupid Cat! PHONE: (703) 356-6514
- xPROJECT: The Conrail Locomotive/Harpsichord Fusion Program
- x=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- x.fi
- !Funky!Stuff!
- echo x - asciify/DOC
- cat >asciify/DOC <<'!Funky!Stuff!'
-
-
-
- ASCIIFY(1) USER COMMANDS ASCIIFY(1)
-
-
-
- NAME
- asciify - convert file contents into asciified format
-
- binafy - convert asciified file back to original format
-
- SYNOPSIS
- asciify [ -_c ] _f_i_l_e [ _a_s_c_i_i_f_i_e_d__f_i_l_e ]
-
- binafy _a_s_c_i_i_f_i_e_d__f_i_l_e [ _f_i_l_e ]
-
-
- DESCRIPTION
- Asciify and binafy are a pair of programs for converting
- arbitrary format files into ASCII representation for later
- transmission through network mailers. This program is supe-
- rior to Binhex, Mcvert, xbin, et al in that no assumptions
- have been made concerning the type of file being encoded.
- Also, asciify and binafy were written for ease of porting
- between different machine architectures and thus facilitat-
- ing a common interchange standard for files of any format.
-
- I believe this calls for some diabolical laughter...
- MWWAHHA HAH HAW HA HA HA HA!!!
-
-
- Here's what an asciified file looks like:
-
- (This file must be decoded with Binafy)
- !Asciify Version 1.00!File t!Chk!
- 7)GI;9*N*'3[;X7T*(+W>H[K=H>B:I+K;XCV$BK+=D#V<(6B;H_T;9/V*(_H*)3J!4327!
- ;4#P<8?J?"J,7XCC?$#K=8WQ>I3C=$#J:8[F*(_T*(7[;2J,2X_W=(2B;I+C=86B!4161!
- .
- .
- .
- ?(C[*(;G:9+H?8RB>YGO=87V>IFa$d!2125!
- !!
-
- Anything outside the parenthetical line and the final bangs
- are ignored. Anything following the bang on each line is a
- checksum, used for error detection. Unlike Binhex, the
- binafy program will tell you which line had a checksum error
- if one occurs, although there isn't much that the program
- can do to correct the error.
-
-
- USING ASCIIFY
- The command line...
-
- example% asciify binary_file asciified_file
-
- converts binary_file into the asciify format and puts it
- into file asciified_file. If no target file is specified
-
-
-
- Sun Release 4.0 Last change: 01 June 1990 1
-
-
-
-
-
-
- ASCIIFY(1) USER COMMANDS ASCIIFY(1)
-
-
-
- then the output is placed onto standard output.
-
- The command line...
-
- example% binafy asciified_file file
-
- converts the asciified format file into its original format
- and places it in file.
-
- If no target file is specified then the output is placed
- onto standard output so in the case of binafy you'll want to
- redirect output someplace. For example:
-
- example% binafy asciified_file > file
-
-
- SEE ALSO
- binafy(1),
-
-
- HOW IT WORKS
- Three bytes of the original file are read and converted into
- 4 characters representing 6 bits each of the original 3
- bytes. Note that 6 divides into 12 ( 3 bytes times 8 bits
- per byte) quite evenly. The 64 characters of the ASCII
- character set starting with the double quote (hex 22) char-
- acter are used. The exclamation point character is reserved
- as a special delimeter.
-
- Note that we have used only 64 of the 94 some printable
- characters.
-
- In case the number of bytes in a file is not evenly divisi-
- ble by 3, a special encoding is used to represent the
- remaining piece of the byte. The remaining pieces can be
- either 2 bits or 4 bits and thus consume 20 more ASCII
- printable characters. Because these characters are unique
- in the encoding we will know when the end of a file has
- arrived and, more importantly, we will know what these char-
- acters represent because they are outside of the main encod-
- ing scheme.
-
- This encoding scheme yields a 4 for 3 decompression which I
- consider to be fairly effecient.
-
-
- INSTALLATION
- Just type make asciify to build asciify and make binafy to
- build binafy
-
- Both should compile and generate binaries called asciify and
- binafy respectively.
-
-
-
- Sun Release 4.0 Last change: 01 June 1990 2
-
-
-
-
-
-
- ASCIIFY(1) USER COMMANDS ASCIIFY(1)
-
-
-
- FUTURE ENHANCEMENTS
- Support binafying of multipart files. It's simple enough to
- split files apart with the Unix "split" program. It would
- be nice if asciify could assemble multiple files automagi-
- cally. Note that the above example has a "part of" spec in
- the header. That's how binafy will know what order to
- assemble the files in.
-
- The file format is incompatible with Binhex and
- uuencode/uudecode formats. I should probably provide compa-
- tibility and cross-conversion for these too, but since I
- can't find their source code you'll just have to use asciify
- format for now.
-
- Magic strings.
-
-
- BUGS
- The ANSI C standard actually makes no assumptions concerning
- the size of a character or byte, therefore this program will
- probably do the wrong thing on machines with 13-bit bytes.
- This should not be an immediate concern as most machines use
- 8 bit bytes.
-
- Also note that I have avoided the use of the fscanf/sscanf
- whenever possible. This is because the behavior of these
- library routines varies from implementation to implementa-
- tion.
-
-
- AUTHOR
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- ORGANIZATION: Kzinti Embassy GEOGRAPHIC: McLean, VA
- UUCP: kzin!speaker@mimsy.umd.edu INTERNET: jtn@potomac.ads.com
- SPOKEN: Hey Stupid Cat! PHONE: (703) 356-6514
- PROJECT: The Conrail Locomotive/Harpsichord Fusion Program
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Sun Release 4.0 Last change: 01 June 1990 3
-
-
-
- !Funky!Stuff!
- echo x - asciify/Makefile
- cat >asciify/Makefile <<'!Funky!Stuff!'
- all: asciify binafy
-
- asciify: asciify.c globals.c asciifyCore.c definitions.h globals.h Makefile
- cc asciify.c globals.c asciifyCore.c -o asciify
-
- binafy: binafy.c globals.c binafyCore.c definitions.h globals.h Makefile
- cc binafy.c globals.c binafyCore.c -o binafy
-
- clean:
- rm -f *.o asciify binafy core #*
- !Funky!Stuff!
- echo x - asciify/README
- cat >asciify/README <<'!Funky!Stuff!'
- Asciify and binafy are a pair of programs for converting arbitrary
- format files into ASCII representation for later transmission through
- network mailers. These programs are superior to Binhex, Mcvert, xbin,
- et al in that no assumptions are made concerning the type of file being
- encoded. Also, Asciify and Binafy were written with ease of protability
- in mind. A Macintosh port is now underway.
-
- I welcome bug reports and suggestions for future improvement of this
- program. I may be reached at kzin!speaker@mimsy.umd.edu or
- jtn@potomac.ads.com.
-
-
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- ORGANIZATION: Advanced Decision Systems GEOGRAPHIC: Arlington, VA
- UUCP: kzin!speaker@mimsy.umd.edu INTERNET: jtn@potomac.ads.com
- SPOKEN: Yo... John! PHONE: (703) 243-1611
- PROJECT: The Conrail Locomotive/Harpsichord Fusion Program
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- !Funky!Stuff!
- echo x - asciify/asciify.c
- cat >asciify/asciify.c <<'!Funky!Stuff!'
- #include <stdio.h>
- #include <fcntl.h>
- #include "definitions.h"
- #include "globals.h"
-
- /*
- This is "asciify", a program for converting files of arbitrary
- format into an ASCII encoding for later transmission through network
- mailers. The program "binafy" should be used to convert the ASCII
- encoding back into the original file.
-
- Usage: asciify [ -c ] <original file> [ <asciified file> ]
-
- -- John T. Nelson (a.k.a. Speaker-To-Animals) mimsy!kzin!speaker
- */
-
- BOOLEAN parseFlags(argv)
- char *argv[];
- {
- char *s;
- unsigned int k;
-
- if ( *argv[0] == '-' ) {
- k = 1;
- header.useCheck = FALSE;
- for ( s = argv[0] + 1; *s != '\0'; s++ ) {
- switch ( *s ) {
- case 'c':
- header.useCheck = TRUE;
- break;
- }
- k++;
- }
- return TRUE;
- }
- else
- return FALSE;
- }
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int fi;
- FILE *fo;
-
- unsigned int counter;
- int status;
-
- if ( argc == 1 ) {
- printf("Usage: asciify [ -c ] <original file> <target file>\n");
- return;
- }
- argv++;
- if ( argc == 2 ) {
- if ( *argv[0] == '-' ) {
- printf("Usage: asciify [ -c ] <original file> <target file>\n");
- return;
- }
- else {
- fi = open( *argv, O_RDONLY);
- fo = stdout;
- strcpy(header.fileName, "stdout");
- }
- }
-
- if ( argc == 3 )
- if ( parseFlags(argv) ) {
- argv++;
- fi = open( *argv, O_RDONLY);
- fo = stdout;
- strcpy(header.fileName, "stdout");
- }
- else {
- fi = open( *argv, O_RDONLY);
- argv++;
- fo = fopen(*argv, "w");
- strcpy(header.fileName, *argv);
- }
-
- if ( argc == 4 )
- if ( parseFlags(argv) ) {
- argv++;
- fi = open( *argv, O_RDONLY);
- argv++;
- fo = fopen(*argv, "w");
- strcpy(header.fileName, *argv);
- }
- else {
- printf("More than 2 file names - I'm quiting\n");
- return;
- }
-
- if ( argc > 4 ) {
- printf("More than 2 file names - I'm quiting\n");
- return;
- }
-
- asciify(fi, fo);
- }
- !Funky!Stuff!
- echo x - asciify/asciifyCore.c
- cat >asciify/asciifyCore.c <<'!Funky!Stuff!'
- #include <stdio.h>
- #include <fcntl.h>
- #include "definitions.h"
- #include "globals.h"
-
- asciify(fi, fo)
- int fi;
- FILE *fo;
- {
- unsigned int counter;
- int status;
-
- num = 0;
- cur = buffer;
-
- putHerald(fo);
-
- counter = 0;
- status = 0;
-
- while ( status != EOF ) {
- status = convertThree(fi, fo, header.useCheck);
- fflush(fo);
- }
-
- fputc(DELIMETER, fo);
- fputc(DELIMETER, fo);
- fprintf(fo, "\n");
- fflush(fo);
-
- close(fi);
- fclose(fo);
- }
-
- errorCleanup(fi, fo)
- int fi;
- FILE *fo;
- {
- close(fi);
- fclose(fo);
- }
-
- /* No... don't look! It's EVIL! */
-
- convertThree(fi, fo, check)
- int fi;
- FILE *fo;
- BOOLEAN check;
- {
- int status;
- unsigned int i;
- char byte1, byte2, byte3;
- char c;
- unsigned int checksum;
-
- i = 1;
- checksum = 0;
- status = SUCCESS;
-
- while (i < LINE_LENGTH && status != EOF) {
- status = getAbyte(fi, &byte1);
- if ( status == EOF ) {
- break;
- }
- checksum = checksum + (unsigned char) byte1;
- convert1(&byte1, &c);
- fputc(c, fo);
- i++;
-
- status = getAbyte(fi, &byte2);
- if ( status == EOF ) {
- putShortTwo(fo, byte1);
- break;
- }
- checksum = checksum + (unsigned char) byte2;
- convert2(&byte1, &byte2, &c);
- fputc(c, fo);
- i++;
-
- status = getAbyte(fi, &byte3);
- if ( status == EOF ) {
- putShortFour(fo, byte2);
- break;
- }
- checksum = checksum + (unsigned char) byte3;
- convert3(&byte2, &byte3, &c);
- fputc(c, fo);
- i++;
-
- convert4(&byte3, &c);
- fputc(c, fo);
-
- i++;
- byte1 = 0;
- byte2 = 0;
- byte3 = 0;
- }
-
- if ( i == 1 )
- return EOF;
-
- putCheckSum(fo, checksum, check);
-
- return status;
- }
-
- putCheckSum(fo, checksum, check)
- FILE *fo;
- unsigned int checksum;
- BOOLEAN check;
- {
- if ( checksum < 0 )
- check = check;
- if ( check == YES )
- fprintf(fo,"%c%u%c\n", DELIMETER, checksum, DELIMETER);
- else {
- fputc(DELIMETER, fo);
- fputc('\n', fo);
- }
- }
-
- convert1(b1, c)
- char *c;
- char *b1;
- {
- char byte;
-
- byte = *b1;
-
- byte &= UPPER_SIX_BITS;
- byte = byte >> 2;
- byte &= LOWER_SIX_BITS;
- byte += CODING_START;
-
- *c = byte;
- return SUCCESS;
- }
-
- convert2(b1, b2, c)
- char *c;
- char *b1, *b2;
- {
- char byte1;
- char byte2;
-
- byte1 = *b1;
- byte2 = *b2;
-
- byte1 &= LOWER_TWO_BITS;
- byte2 &= UPPER_FOUR_BITS;
-
- byte1 = byte1 << 4;
- byte2 = byte2 >> 4;
-
- byte1 &= 0x30;
- byte2 &= LOWER_FOUR_BITS;
-
- byte1 |= byte2;
- byte1 &= LOWER_SIX_BITS;
- byte1 += CODING_START;
-
- *c = byte1;
- return SUCCESS;
- }
-
- convert3(b2, b3, c)
- char *c;
- char *b2, *b3;
- {
- char byte2;
- char byte3;
-
- byte2 = *b2;
- byte3 = *b3;
-
- byte2 &= LOWER_FOUR_BITS;
- byte3 &= UPPER_TWO_BITS;
-
- byte2 = byte2 << 2;
- byte3 = byte3 >> 6;
-
- byte2 &= 0x3C;
- byte3 &= LOWER_TWO_BITS;
-
- byte2 |= byte3;
- byte2 &= LOWER_SIX_BITS;
- byte2 += CODING_START;
-
- *c = byte2;
- return SUCCESS;
- }
-
- convert4(b3, c)
- char *c;
- char *b3;
- {
- char byte3;
-
- byte3 = *b3;
- byte3 &= LOWER_SIX_BITS;
- byte3 += CODING_START;
-
- *c = byte3;
- return SUCCESS;
- }
-
- processChecksum()
- {
- }
-
- getAbyte(fi, c)
- int fi;
- char *c;
- {
- if ( num == 0 ) {
- num = read(fi, buffer, BUFFER_SIZE);
- if ( num == 0 || num == EOF )
- return EOF;
- cur = buffer;
- }
- *c = *cur;
- cur += 1;
- num -= 1;
-
- return SUCCESS;
- }
-
- putShortTwo(fo, b)
- FILE *fo;
- char b;
- {
- char byte;
-
- byte = b;
- byte &= LOWER_TWO_BITS;
- byte += START_TWO;
- fputc(byte, fo);
- }
-
- putShortFour(fo, b)
- FILE *fo;
- char b;
- {
- char byte;
-
- byte = b;
- byte &= LOWER_FOUR_BITS;
- byte += START_FOUR;
- fputc(byte, fo);
- }
-
- putHerald(fo)
- FILE *fo;
- {
- fprintf(fo, "\n%s", HERALD);
-
- fputc(DELIMETER, fo);
- fprintf(fo, VERSION_STRING, VERSION_NUM);
-
- fputc(DELIMETER, fo);
- fprintf(fo, FILE_STRING, header.fileName);
-
- if ( header.useCheck == YES ) {
- fputc(DELIMETER, fo);
- fprintf(fo, CHECKSUM_STRING);
- }
- fputc(DELIMETER, fo);
- fprintf(fo, "\n");
- }
- !Funky!Stuff!
- echo x - asciify/binafy.c
- cat >asciify/binafy.c <<'!Funky!Stuff!'
- #include <stdio.h>
- #include <fcntl.h>
- #include "definitions.h"
- #include "globals.h"
-
- /*
- This is "binafy", a program for converting "asciified" files
- back into their original file formats.
-
- Usage: binafy <asciified file> <original file>
-
- -- John T. Nelson (a.k.a. Speaker-To-Animals) mimsy!kzin!speaker
- */
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- FILE *fi;
- int fo;
-
- if ( argc == 1 ) {
- printf("Usage: binafy <asciify'd file> <original file>\n");
- return;
- }
- if ( argc == 2 ) {
- fo = STANDARD_OUTPUT_FD; /* Assume the shmuck knows what he wants */
- }
- if ( argc == 2 || argc == 3) {
- argv++;
- fi = fopen( *argv, "r");
- }
- if ( argc == 3 ) {
- argv++;
- #ifndef THINK_C
- fo = open(*argv, O_WRONLY | O_CREAT, 0640);
- #else
- fo = open(*argv, O_WRONLY | O_CREAT);
- #endif
- }
- if ( argc > 3 ) {
- printf("More than 2 arguments - I'm quiting\n");
- return;
- }
-
- binafy(fi, fo);
- }
- !Funky!Stuff!
- echo x - asciify/binafyCore.c
- cat >asciify/binafyCore.c <<'!Funky!Stuff!'
- #include <stdio.h>
- #include <fcntl.h>
- #include "definitions.h"
- #include "globals.h"
-
- binafy(fi, fo)
- FILE *fi;
- int fo;
- {
-
- num = -1;
- header.line = 1;
-
- if ( flushHerald(fi) == FAILURE ) {
- fclose(fi);
- close(fo);
- exit();
- }
-
- if ( readHeader(fi, header.header) == FAILURE ) {
- fclose(fi);
- close(fo);
- exit();
- }
-
- parseHeader(&header);
-
- if ( header.useCheck == YES )
- processWithChecksums(fi, fo);
- else
- processWithoutChecksums(fi, fo);
-
- fclose(fi);
- flushBuffer(fo);
- close(fo);
- }
-
- processWithChecksums(fi, fo)
- int fi;
- FILE *fo;
- {
- int status;
-
- status = SUCCESS;
-
- while ( status != EOF ) {
- status = processLine(fi, fo, &header);
- if ( status == FAILURE )
- return;
- if ( checkChecksum(header) == FAILURE ) {
- printf("Checksum error detected on line %d!\n", header.line);
- return;
- }
- header.line += 1;
- }
- }
-
- processWithoutChecksums(fi, fo)
- int fi;
- FILE *fo;
- {
- int status;
-
- status = SUCCESS;
-
- while ( status != EOF ) {
- status = processLine(fi, fo, &header);
- if ( status == FAILURE )
- return;
- header.line += 1;
- }
- }
-
- processLine(fi, fo, header)
- FILE *fi;
- int fo;
- struct HEADER_STRUCT *header;
- {
- char string[NUM_DATA_CHARS];
- char errorChars[NUM_CHECKSUM_CHARS];
- unsigned int i;
- unsigned int lastChar;
- unsigned int checksum;
-
- char byte1;
- char byte2;
- char byte3;
- int status;
-
- switch ( collectStrings(fi, string, errorChars) ) {
- case SUCCESS:
- break;
- case FAILURE:
- return FAILURE;
- case DOUBLE_DELIMS:
- return EOF;
- default:
- return FAILURE;
- };
-
- i = 0;
- checksum = 0;
-
- lastChar = strlen(string) - 1;
- convertToNumber(errorChars, &(header -> checksumRead));
-
- while( i <= lastChar ) {
- if ( string[i] == DELIMETER ) {
- header -> checksum = checksum;
- return SUCCESS;
- }
-
- status = SUCCESS;
- status = convert1(string[i], &byte1);
- if ( status == TRAILING_CHARS ) {
- printf("Byte 1 started with a short byte!\n");
- return FAILURE;
- }
- i++;
- status = convert2(string[i], &byte1, &byte2);
- if ( status == TRAILING_FOUR ) {
- printf("Byte 1 decoded 4 bits not 2!\n");
- return FAILURE;
- }
- checksum += (unsigned char) byte1;
- if ( status == TRAILING_TWO ) {
- putAchar(byte1, fo);
- status = EOF;
- break;
- }
- putAchar(byte1, fo);
- i++;
- status = convert3(string[i], &byte2, &byte3);
- if ( status == TRAILING_TWO ) {
- printf("Byte 2 decoded 2 bits not 4!\n");
- return FAILURE;
- }
- checksum += (unsigned char) byte2;
- if ( status == TRAILING_FOUR ) {
- putAchar(byte2, fo);
- status = EOF;
- break;
- }
- putAchar(byte2, fo);
- i++;
- status = convert4(string[i], &byte3);
- if ( status == TRAILING_CHARS ) {
- printf("Byte 3 had a short byte!\n");
- return FAILURE;
- }
- putAchar(byte3, fo);
- checksum += (unsigned char) byte3;
- i++;
- byte1 = 0;
- byte2 = 0;
- byte3 = 0;
- }
-
- header -> checksum = checksum;
- return SUCCESS;
- }
-
- convert1(c, b1)
- char c;
- char *b1;
- {
- char byte;
-
- if ( c >= SHORT_START )
- return TRAILING_CHARS;
-
- byte = c - CODING_START;
- byte = byte << 2;
- byte &= UPPER_SIX_BITS;
-
- *b1 = byte;
- return SUCCESS;
- }
-
- convert2(c, b1, b2)
- char c;
- char *b1, *b2;
- {
- char byte1;
- char byte2;
- char byte;
- char cc;
-
- if ( c >= START_FOUR )
- return TRAILING_FOUR;
-
- byte1 = *b1;
- if ( c >= START_TWO && c < START_FOUR ) {
- byte = c - SHORT_START;
- byte1 |= byte;
- *b1 = byte1;
- return TRAILING_TWO;
- }
-
- cc = c - CODING_START;
- byte = cc >> 4; /* Extract the upper 2 bits */
- byte &= LOWER_TWO_BITS;
- byte1 |= byte;
-
- byte = cc << 4; /* The lower 4 bits */
- byte2 = byte & UPPER_FOUR_BITS;
-
- *b1 = byte1;
- *b2 = byte2;
- return SUCCESS;
- }
-
- convert3(c, b2, b3)
- char c;
- char *b2, *b3;
- {
- char byte2;
- char byte3;
- char byte;
- char cc;
-
- if ( c < START_FOUR && c >= SHORT_START )
- return TRAILING_TWO;
-
- byte2 = *b2;
- if ( c >= START_FOUR && c <= SHORT_STOP ) {
- byte = c - (SHORT_START + MASK_TWO);
- byte2 |= byte;
- *b2 = byte2;
- return TRAILING_FOUR;
- }
-
- cc = c - CODING_START;
- byte = cc >> 2; /* Extract the upper 4 bits */
- byte &= LOWER_FOUR_BITS;
- byte2 |= byte;
-
- byte = cc << 6; /* The lower 2 bits */
- byte3 = byte & UPPER_TWO_BITS;
-
- *b2 = byte2;
- *b3 = byte3;
- return SUCCESS;
- }
-
- convert4(c, b3)
- char c;
- char *b3;
- {
- char byte3;
- char byte;
-
- byte3 = SHORT_START;
-
- if ( c >= SHORT_START )
- return TRAILING_CHARS;
-
- byte3 = *b3;
- byte = c - CODING_START;
- byte &= LOWER_SIX_BITS;
- byte3 |= byte;
-
- *b3 = byte3;
- return SUCCESS;
- }
-
- flushHerald(fi)
- FILE *fi;
- {
- char string[MAX_LINE_LENGTH];
-
- while ( fgets(string, MAX_LINE_LENGTH, fi) != NULL ) {
- header.line++;
- if ( strcmp(string, HERALD) == 0 )
- return SUCCESS;
- }
- printf("Geeze... I didn't even get to the herald!\n");
- return FAILURE;
- }
-
- readHeader(fi, h)
- FILE *fi;
- char *h;
- {
-
- while ( fgets(h, MAX_LINE_LENGTH, fi) != NULL ) {
- header.line++;
- if ( h[0] == DELIMETER )
- return SUCCESS;
- }
- printf("Couldn't find the header!\n");
- return FAILURE;
- }
-
- putAchar(byte, fo)
- char byte;
- int fo;
- {
-
- num++;
- if ( num > BUFFER_SIZE - 1 ) {
- write(fo, buffer, BUFFER_SIZE);
- num = 0;
- }
- buffer[num] = byte;
- }
-
- flushBuffer(fo)
- int fo;
- {
- int n;
-
- if ( num > BUFFER_SIZE - 1 )
- num = BUFFER_SIZE;
- else
- num++;
-
- while ( num > 0 ) {
- n = write(fo, buffer, num);
- num -= n;
- }
- }
-
- parseHeader(header)
- struct HEADER_STRUCT *header;
- {
- char *s;
- char h[MAX_LINE_LENGTH];
-
- s = header -> header;
- header -> useCheck = FALSE;
-
- if ( *s != DELIMETER ) {
- printf("Bad header format!\n");
- return FAILURE;
- }
- s++;
- while ( *s != '\n' && *s != '\0' ) {
- if ( headerExtract(&s, h) == FAILURE )
- return FAILURE;
- if ( strcmp(h, CHECKSUM_STRING) == 0 )
- header -> useCheck = TRUE;
- }
- }
-
- headerExtract(s, h)
- char **s;
- char *h;
- {
-
- while ( **s == DELIMETER || **s == '\n' ) (*s)++;
-
- while ( **s != DELIMETER ) {
- if ( **s == '\0' )
- return FAILURE;
-
- *h = **s;
- h++;
- (*s)++;
- }
- *h = '\0';
- return SUCCESS;
- }
-
- collectStrings(fi, s, e)
- FILE *fi;
- char *s;
- char *e;
- {
- char c;
-
- if ( getAchar(fi, &c) == EOF )
- return FAILURE;
-
- while ( c != DELIMETER ) {
- *s = c;
- s++;
- if ( getAchar(fi, &c) == EOF )
- return FAILURE;
- }
- *s = '\0';
- if ( getAchar(fi, &c) == EOF )
- return FAILURE;
- if ( c == DELIMETER && *s == '\0' )
- return DOUBLE_DELIMS;
- if ( header.useCheck == NO ) {
- while ( c != '\n' ) {
- if ( getAchar(fi, &c) == EOF )
- return FAILURE;
- }
- }
- else {
- if ( c == DELIMETER || c == '\n' ) {
- printf("So where's the checksum?\n");
- return FAILURE;
- }
- while ( c != DELIMETER ) {
- *e = c;
- if ( getAchar(fi, &c) == EOF )
- return FAILURE;
- e++;
- }
- if ( getAchar(fi, &c) == EOF )
- return FAILURE;
- if ( c != '\n' ) {
- printf("Expected a new-line here\n");
- return FAILURE;
- }
- }
- *e = '\0';
- return SUCCESS;
- }
-
- checkChecksum(header)
- struct HEADER_STRUCT header;
- {
- if ( header.checksum != header.checksumRead )
- return FAILURE;
- else
- return SUCCESS;
- }
-
- getAchar(fi, c)
- FILE *fi;
- char *c;
- {
- if ( (*c = fgetc(fi)) == EOF ) {
- printf("Premature EOF encountered\n");
- return EOF;
- }
- }
-
- convertToNumber(errorChars, number)
- char *errorChars;
- unsigned int *number;
- {
- int s;
- int sum, n;
- unsigned int i;
- char c;
-
- s = strlen(errorChars) - 1;
- sum = 0;
- i = 0;
-
- while ( s >= 0 ) {
- c = errorChars[s];
- n = atoi(&c);
- if ( i == 0 )
- sum += n;
- else
- sum += (n * power(10, i));
- s--;
- i++;
- }
- *number = (unsigned int) sum;
- }
-
- power(base, n)
- int base, n;
- {
- int i, p;
-
- p = 1;
- for ( i = 1; i <= n; ++i )
- p = p * base;
- return p;
- }
- !Funky!Stuff!
- echo x - asciify/definitions.h
- cat >asciify/definitions.h <<'!Funky!Stuff!'
- #ifndef DEFINITIONS_DEFINED
- #define DEFINITIONS_DEFINED
-
- #define TRUE 1
- #define FALSE 0
- #define YES TRUE
- #define NO FALSE
-
- #define VERSION_NUM 1.0
- #define VERSION_STRING "Asciify Version %1.2f"
- #define FILE_STRING "File %s"
- #define CHECKSUM_STRING "Chk"
-
- #define DELIMETER 0x21
- #define CODING_START 0x22
- #define BIT_SPAN 0x3F /* 6 bits worth */
- #define SHORT_START (CODING_START + BIT_SPAN + 1)
- #define MASK_TWO 0x0003
- #define MASK_FOUR 0x000F
- #define START_TWO SHORT_START
- #define START_FOUR (SHORT_START + MASK_TWO + 1)
- #define SHORT_STOP 0x7E
- #define LOWER_CHAR 0x00FF
- #define UPPER_CHAR 0xFF00
-
- #define UPPER_TWO_BITS 0xC0
- #define UPPER_FOUR_BITS 0xF0
- #define UPPER_SIX_BITS 0xFC
- #define LOWER_TWO_BITS 0x03
- #define LOWER_FOUR_BITS 0x0F;
- #define LOWER_SIX_BITS 0x3F
-
- #define FAILURE 0
- #define SUCCESS 1
- #define NO_TRAILING 1
- #define TRAILING_CHARS 2
- #define TRAILING_TWO 3
- #define TRAILING_FOUR 4
- #define DOUBLE_DELIMS 5
-
- #define CHECKSUM 10
- #define NO_CHECKSUM 11
-
- #define BUFFER_SIZE 1024
- #define MAX_LINE_LENGTH 80
- #define LINE_LENGTH 64
- #define NUM_CHECKSUM_CHARS 10
- #define NUM_DATA_CHARS 80
-
- #define HERALD "(This file must be decoded with Binafy)\n"
-
- typedef short BOOLEAN;
-
- typedef struct HEADER_STRUCT {
- char fileName[MAX_LINE_LENGTH];
- char header[MAX_LINE_LENGTH];
- BOOLEAN useCheck;
- unsigned int checksum;
- unsigned int checksumRead;
- unsigned int line;
- };
-
- #define STANDARD_OUTPUT_FD 1
-
- #endif
- !Funky!Stuff!
- echo x - asciify/globals.c
- cat >asciify/globals.c <<'!Funky!Stuff!'
- #include "definitions.h"
-
- char buffer[BUFFER_SIZE];
- int num = 0;
- char *cur;
-
- struct HEADER_STRUCT header = {
- "", /* The file we are processing */
- "", /* The line read */
- NO, /* Perform checksums? */
- 0, /* CHecksum calculated */
- 0, /* Checksum read */
- 0 /* Line */
- };
- !Funky!Stuff!
- echo x - asciify/globals.h
- cat >asciify/globals.h <<'!Funky!Stuff!'
- #include "definitions.h"
-
- extern char buffer[BUFFER_SIZE];
- extern int num;
- extern char *cur;
-
- extern struct HEADER_STRUCT header;
- !Funky!Stuff!
- echo x - asciify/tyger
- cat >asciify/tyger <<'!Funky!Stuff!'
- Tyger, Tyger burning bright
-
- In the forest of the night
-
- What immortal hand or eye
-
- Could frame thy fearful symmetry?
- !Funky!Stuff!
-