hlb@loral.UUCP (10/04/89)
Article 145 of comp.binaries.apple2: Path: loral!ucsdhub!sdcsvax!ucsd!ucbvax!decwrl!sun!pitstop!sundc!seismo!uunet!mcvax!hp4nl!dutrun!duteca4!marcel From: marcel@duteca (Marcel Mol) Newsgroups: comp.binaries.apple2 Subject: binary 2, executioner, unsqueeze programs on Unix Message-ID: <465@duteca4.UUCP> Date: 28 Feb 89 17:48:31 GMT Reply-To: marcel@duteca.UUCP (Marcel J.E. Mol) Organization: Delft University of Technology, Dep. of Electrotechnical engineering. Lines: 987 Ok, here are my programs to handle executioner and binary 2 archives on unix machines. - Use unexec or unbit to create a file with binary data. - Use unblu to view an binary 2 archive or to extract files from it. - Use usq to unsqueeze squeezed files extracted from a binary 2 file. I use the unexec and unbit programs to recreate the binary files, which then can be transfered to my apple. With the unblu program I extract documentation and sources files so the can be printed on those beautiful laser printer connected to my Unix machine (If needed I usq them first of coarse). Do with the programs what you like, but don't use them for commercial business without my permission. If you have any bug reports, improvement and or sugestions please mail them to me (although I may not be able to spend much work on the programs anymore) - Marcel ================= CUT HERE ================= #!/bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #!/bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # unbit.c 1719 bytes # unblu.c 15128 bytes # unexec.c 2656 bytes # usq.c 7388 bytes # This archive created: Tue Feb 28 18:35:54 MET 1989 # By: Marcel J.E. Mol export PATH echo shar: extracting unbit.c if test -f 'unbit.c' then echo shar: over-writing existing file "'unbit.c'" fi sed -e 's/^-//' << \_E_O_F_ > unbit.c -/* - * unbit.c - * - * By Marcel J.E. Mol - * - * I hereby place this program into public domain ... - * ... all those all those if and whats etc.... - * I'm completely unresposible for any damage this program may cause you. - * - * - * Unbit expects a 6 bit encoding scheme of executioner output. - * Remove all stuff from the 'call -151' to 'F00G', and the last - * few lines containing the 'BSAVE ...' stuff. Fed the resulting - * ascii encoded data through unbit resulting in the binaru data. - * Thus each line in the input file should look something like this: - * - * 0A474CE30600AC02030053B2320F54B21E15020099030006444154452E430000 - * - * Usage: The program reads from a file or stdin, and outputs to - * stdout. I usually use the program as follows: - * - * unbit file.ex > file.blu - */ - -#include <stdio.h> - -char * copyright = "@(#) unbit.c 2.1 18/06/88 (c) M.J.E. Mol"; - -main(argc, argv) -int argc; -char **argv; -{ - FILE *fp; - - if ((argc == 1) || (!strcmp(argv[1], "-"))) - unbit(stdin); - else { - if ((fp = fopen(argv[1], "r")) == NULL) { - perror(argv[1]); - exit(1); - } - unbit(fp); - } - - exit(0); - - -} /* main */ - - - -unbit(fp) -FILE *fp; -{ - int c, co; - - while ((c = getc(fp)) != EOF) { - if ((c != ' ') && (c != '\n')) { - if ((c>='0') && (c<='9')) c-= '0'; - else if ((c>='a') && (c<='f')) c = c - 'a' + 10; - else if ((c>='A') && (c<='F')) c = c - 'A' + 10; - else fprintf(stderr, "illegal char %c\n",c); - co = c << 4; - c = getc(fp); - if ((c>='0') && (c<='9')) c-= '0'; - else if ((c>='a') && (c<='f')) c = c - 'a' + 10; - else if ((c>='A') && (c<='F')) c = c - 'A' + 10; - else fprintf(stderr, "illegal char %c\n",c); - co += c; - putchar(co); - } - } -} /* unbit */ _E_O_F_ if test 1719 -ne `wc -c < unbit.c `; then echo shar: "'unbit.c'" unpacked with wrong size! fi echo shar: extracting unblu.c if test -f 'unblu.c' then echo shar: over-writing existing file "'unblu.c'" fi sed -e 's/^-//' << \_E_O_F_ > unblu.c -/* @(#) unblu.c 2.2 23/09/88 */ -/************************************************************************* - ** ** - ** Name : unblu ** - ** Author : Marcel J.E. Mol ** - ** Date : 10/05/88 (first release) ** - ** Version : 2.20 ** - ** Files : unblu.c Main source file ** - ** ** - ** ------------------------- Revision List ------------------------- ** - ** Ver Date Name Remarks ** - ** 1.00 10/05/88 Marcel Mol Raw copy of a basic program** - ** 2.00 03/06/88 Marcel Mol Rewrite after blu info ** - ** was send to the net ** - ** 2.10 18/06/88 Marcel Mol Added filetype texts ** - ** 2.20 23/09/88 Marcel Mol Show mod and creation time ** - ** ** - ** ================================================================= ** - ** ** - ** Compile as follows: cc cc unblu.c -Oso unblu ** - ** ** - ** Usage: unblu [-vh] <arcfile> [<files-toextract>] ** - ** ** - ************************************************************************/ - - /************************************************************************ - ** ** - ** NAME ** - ** unblu - Extract files from an apple binary ][ archive. ** - ** ** - ** ** - ** SYNOPSIS ** - ** unblu [-vh] arcfile [files-to-extract] ** - ** ** - ** ** - ** DESCRIPTION ** - ** Unblu list the contents of a binary ][ archive (the -v option) ** - ** or extracts the listed files from the archive (without the ** - ** -v option). If no files are listed, the comlete archive is ** - ** extracted or listed. ** - ** The -h option gives a help message on the usage of unblu. ** - ** ** - ** AUTHOR ** - ** Marcel J.E. Mol ** - ** ** - ** BUGS ** - ** Mail bugs to: marcel@duteca ** - ** ** - ************************************************************************/ - -char * copyright = "@(#) unblu.c 2.1 18/06/88 (c) M.J.E. Mol"; -#include <stdio.h> -#include <fcntl.h> - -#define BUFSIZE 128 /* Blu block length */ -#define DEBUG - -/* Global variables */ -char * progname; -char * blufile; -int verbose = 0; - -char * filetypes[] = { - "$00", "bad", "pcd", "ptx", "txt", "pda", "bin", "fnt", - "fot", "ba3", "da3", "wpf", "sos", "$0D", "$0E", "dir", - "rpd", "rpi", "$12", "$13", "$14", "$15", "$16", "$17", - "$18", "adb", "awp", "asp", "$1C", "$1D", "$1E", "$1F", - "$20", "$21", "$22", "$23", "$24", "$25", "$26", "$27", - "$28", "$29", "$2A", "$2B", "$2C", "$2D", "$2E", "$2F", - "$30", "$31", "$32", "$33", "$34", "$35", "$36", "$37", - "$38", "$39", "$3A", "$3B", "$3C", "$3D", "$3E", "$3F", - "$40", "$41", "$42", "$43", "$44", "$45", "$46", "$47", - "$48", "$49", "$4A", "$4B", "$4C", "$4D", "$4E", "$4F", - "$50", "$51", "$52", "$53", "$54", "$55", "$56", "$57", - "$58", "$59", "$5A", "$5B", "$5C", "$5D", "$5E", "$5F", - "$60", "$61", "$62", "$63", "$64", "$65", "$66", "$67", - "$68", "$69", "$6A", "$6B", "$6C", "$6D", "$6E", "$6F", - "$70", "$71", "$72", "$73", "$74", "$75", "$76", "$77", - "$78", "$79", "$7A", "$7B", "$7C", "$7D", "$7E", "$7F", - "$80", "$81", "$82", "$83", "$84", "$85", "$86", "$87", - "$88", "$89", "$8A", "$8B", "$8C", "$8D", "$8E", "$8F", - "$90", "$91", "$92", "$93", "$94", "$95", "$96", "$97", - "$98", "$99", "$9A", "$9B", "$9C", "$9D", "$9E", "$9F", - "$A0", "$A1", "$A2", "$A3", "$A4", "$A5", "$A6", "$A7", - "$A8", "$A9", "$AA", "$AB", "$AC", "$AD", "$AE", "$AF", - "src", "obj", "lib", "s16", "rtl", "exe", "str", "tsf", - "nda", "cda", "tol", "drv", "$BC", "$BD", "$BE", "doc", - "pnt", "pic", "$C2", "$C3", "$C4", "$C5", "$C6", "$C7", - "fon", "$C9", "$CA", "$CB", "$CC", "$CD", "$CE", "$CF", - "$D0", "$D1", "$D2", "$D3", "$D4", "$D5", "$D6", "$D7", - "$D8", "$D9", "$DA", "$DB", "$DC", "$DD", "$DE", "$DF", - "$E0", "$E1", "$E2", "$E3", "$E4", "$E5", "$E6", "$E7", - "$E8", "$E9", "$EA", "$EB", "$EC", "$ED", "$EE", "pas", - "cmd", "$F1", "$F2", "$F3", "$F4", "$F5", "$F6", "$F7", - "$F8", "p16", "int", "ivr", "bas", "var", "rel", "sys", - }; - -/* -ProDOS Filetypes - -Num Name OS Meaning -======================================================================== -$00 typeless -$01 BAD both BAD blocks file -$02 PCD SOS Pascal CoDe file -$03 PTX SOS Pascal TeXt file -$04 TXT both ASCII text file -$05 PDA SOS Pascal DAta file -$06 BIN both BINary file -$07 CHR SOS CHaRacter font file -$08 PIC both PICture file -$09 BA3 SOS Business BASIC (SOS) program file -$0A DA3 SOS Business BASIC (SOS) data file -$0B WPD SOS Word Processor Document -$0C SOS SOS system file -$0D SOS SOS reserved file type -$0E SOS SOS reserved file type -$0F DIR Both subDIRectory file -$10 RPD SOS RPS data file -$11 RPI SOS RPS index file -$12 SOS Applefile diskcard file -$13 SOS Applefile model file -$14 SOS Applefile report format file -$15 SOS Screen library file -$16 SOS SOS reserved file type -$17 SOS SOS reserved file type -$18 SOS SOS reserved file type -$19 ADB ProDOS AppleWorks Database file -$1A AWP ProDOS AppleWorks WordProcessing file -$1B ASP ProDOS AppleWorks Spreadsheet file -$1C-$5F Reserved -$60-$6F ProDOS PC Transporter (Applied Engineering) reserved filetypes - $60 PRE ProDOS ProDOS preboot driver - $61-$6A ProDOS Reserved - $6B NIO ProDOS PC Transporter BIOS and drivers - $6C ProDOS Reserved - $6D DVR ProDOS PC Transporter device drivers - $6E ProDOS Reserved - $6F HDV ProDOS MSDOS HardDisk Volume -$70-$9F Reserved -$A0 WPF ProDOS WordPerfect document file -$A1 MAC ProDOS Macrofile -$A2 HLP ProDOS Help File -$A3 DAT ProDOS Data File -$A4 Reserved -$A5 LEX ProDOS Spelling dictionary -$A6-$AB Reserved -$AC ARC ProDOS General Purpose Archive file -$AD-$AF Reserved -$B0 SRC ProDOS ORCA/M & APW source file -$B1 OBJ ProDOS ORCA/M & APW object file -$B2 LIB ProDOS ORCA/M & APW library file -$B3 S16 ProDOS ProDOS16 system file -$B4 RTL ProDOS ProDOS16 runtime library -$B5 EXE ProDOS APW shell command file -$B6 STR ProDOS ProDOS16 startup init file -$B7 TSF ProDOS ProDOS16 temporary init file -$B8 NDA ProDOS ProDOS16 new desk accessory -$B9 CDA ProDOS ProDOS16 classic desk accessory -$BA TOL ProDOS ProDOS16 toolset file -$BB DRV ProDOS ProDOS16 driver file -$BC-$BE Reserved for ProDOS16 load file -$BF DOC ProDOS document file -$C0 PNT ProDOS //gs paint document -$C1 SCR ProDOS //gs screen file -$C2-$C7 Reserved -$C8 FNT ProDOS Printer font file -$C9 ProDOS finder files -$CA ProDOS finder icons -$CB-$DF Reserved -$E0 LBR ProDOS Apple archive library file -$E1 Unknown (unlisted) -$E2 ATI ProDOS Appletalk init file -$E3-$EE Reserved -$EF PAS ProDOS ProDOS Pascal file -$F0 CMD ProDOS added command file -$F1-$F8 ProDOS User defined filetypes (popular ones include:) - $F1 OVL ProDOS Overlay file - $F2 DBF ProDOS Database file - $F3 PAD ProDOS MouseWrite file - $F4 MCR ProDOS AE Pro macro file - $F5 ECP ProDOS ECP batch file - $F6 DSC ProDOS description file - $F7 TMP ProDOS temporary work file - $F8 RSX ProDOS linkable object module -$F9 IMG ProDOS ProDOS image file -$FA INT ProDOS Integer BASIC program -$FB IVR ProDOS Integer BASIC variables file -$FC BAS ProDOS AppleSoft BASIC program -$FD VAR ProDOS AppleSoft BASIC variables file -$FE REL ProDOS ProDOS EDASM relocatable object module file -$FF SYS ProDOS ProDOS8 system file -*/ - - -/* Function declarations */ -void main (); -void unblu (); -void process_file (); -void extract_file (); -void print_global_info (); -int want (); -void usage (); -void printhelp (); - - -void main(argc, argv) -int argc; -char ** argv; -{ - int flag; /* Flag for getopt */ - int bfd; /* File descriptor for blu file */ - extern int optind; /* For getopt */ - extern char * optarg; /* For getopt */ - - progname = argv[0]; - while ((flag = getopt(argc, argv, "vh")) != EOF) { /* Process options */ - switch (flag) { - case 'v': verbose = 1; /* Want only listing of archive */ - break; - case 'h': usage(); /* Give help */ - printhelp(); - exit(0); - default : fprintf(stderr, "%s: skipping unkown flag %c.\n", - progname, flag); - break; - } - } - - if (optind >= argc) { /* No archive given */ - usage(); - exit(1); - } - - blufile = argv[optind++]; /* Get archive name */ - if ((bfd = open(blufile, O_RDONLY)) == -1) { - perror(blufile); - exit(2); - } - - unblu(bfd, &argv[optind]); /* Process wanted files */ - - close(bfd); - - exit(0); - -} /* main */ - - -/* - * unblu -- process a binary II file fd, and process the filenames - * listed in wated. If wanted is \0, all files are processed. - */ -void unblu(fd, wanted) -int fd; -char ** wanted; -{ - char buf[BUFSIZE]; - int firstblock = 1; /* First block needs special processing */ - int tofollow = 1; /* Files to follow in the archive */ - int n; - - while (tofollow && ((n = read(fd, buf, BUFSIZE)) != -1)) { - /* If there is a header block */ - if (n != BUFSIZE) { - fprintf(stderr, "%s: %s file size is broken\n", progname, blufile); - exit(1); - } - if ((buf[0] != 10) || (buf[1] != 71) || - (buf[2] != 76) || (buf[18] != 2)) { - fprintf(stderr, "%s: %s not a binary II file\n", progname, blufile); - exit(1); - } - tofollow = buf[127]; /* How many files to follow */ - if (firstblock && verbose) { - print_global_info(buf); - firstblock = 0; - } - process_file(fd, buf, wanted); /* process the file for it */ - } - return; - -} /* unblu */ - - -/* - * process_file -- retrieve or print file information of file given - * in buf - */ -void process_file(fd, buf, wanted) -int fd; -char * buf; -char ** wanted; -{ - int tf; - int ftype; - int dflags; - int fnamelen; - int filelen; - char fname[64]; - int nblocks; - int modyear, modmonth, modday; - int creyear, cremonth, creday; - int modhour, modsec; - int crehour, cresec; - - /* - * Get fileinfo - */ - ftype = buf[4]; /* File type */ - fnamelen = buf[23]; /* filename */ - strncpy(fname, &buf[24], fnamelen); - fname[fnamelen] = '\0'; - dflags = buf[125]; /* Data flags */ - tf = buf[127]; /* Number of files to follow */ - filelen = buf[20] + (buf[21]<<8) + (buf[22]<<16);/* Calculate file length */ - nblocks = (filelen + BUFSIZE-1) / BUFSIZE; - modyear = buf[11] >>1; - modday = buf[10] & 0x1f; - modmonth= ((buf[11] & 0x01) << 3) + (buf[10] >> 5); - modhour = buf[13] & 0x1f; - modsec = buf[12] & 0x3f; - creyear = buf[15] >>1; - creday = buf[14] & 0x1f; - cremonth= ((buf[15] & 0x01) << 3) + (buf[14] >> 5); - crehour = buf[17] & 0x1f; - cresec = buf[16] & 0x3f; - - - if (*wanted == NULL || want(fname, wanted)) { - if (verbose) { /* print file information */ - printf("%-15s %3s", fname, filetypes[ftype]); - printf(" %02d/%02d/%02d(%02d:%02d)", modyear, modmonth, modday, - modhour, modsec); - printf(" - %02d/%02d/%02d(%02d:%02d)", creyear, cremonth, creday, - crehour, cresec); - printf(" %5d bytes ", filelen); - if (dflags == 0) - printf("stored"); - else { - if (dflags & 128) { - printf("squeezed"); - } - if (dflags & 64) { - printf("encrypted"); - } - if (dflags & 1) - printf("packed"); - } - putchar('\n'); - - if (ftype != 15) /* If not a directory */ - lseek(fd, BUFSIZE*nblocks, 1); /* Seek to next file */ - } - else if (ftype != 15) - extract_file(fd, fname, filelen); - } - else if (ftype != 15) /* If not a directory */ - lseek(fd, BUFSIZE*nblocks, 1); /* Seek to next file */ - - return; - -} /* process_file */ - - -/* - * extract_file -- extract file fname from the archive fd. Fname - * comtains filelen bytes. - */ -void extract_file(fd, fname, filelen) -int fd; -char * fname; -int filelen; -{ - int ofd; - int n; - char buf[BUFSIZE]; - - printf("x - %s\n", fname); - if ((ofd = open(fname, O_CREAT | O_WRONLY | O_TRUNC, 0644)) == -1) { - /* Open (PRODOS) file */ - perror(fname); - exit(1); - } - - while (filelen > 0) { - n = read(fd, buf, BUFSIZE); /* Read 128 bytes */ - if (n != BUFSIZE) { - fprintf(stderr, "%s: %s file size is broken\n", progname, blufile); - exit(1); - } - write(ofd, buf, (filelen >= BUFSIZE ? BUFSIZE : filelen)); - filelen -= BUFSIZE; - } - - close(ofd); /* Close (PRODOS) file */ - return; - -} /* extract_file */ - - - -/* - * print_global_info -- print global information of the binary II file - */ -void print_global_info(buf) -char * buf; -{ - int disk_blocks; - - disk_blocks = buf[117] + (buf[118]<<8) + (buf[119]<<16) + (buf[120]<<24); - printf("%s, by Blu %d, ", blufile, buf[126]); - printf("%d files, using %d blocks\n", buf[127]+1, disk_blocks); - return; - -} /* print_global_info */ - - - -/* - * want -- return 1 if name exists in array wantlist, - * else return 0 - */ -want(name, wantlist) -char * name; -char ** wantlist; -{ - while (*wantlist != NULL) { - if (strcmp(name, *wantlist++) == NULL) - return(1); - } - return(0); - -} /* want */ - - - -void usage() -{ - fprintf(stderr, "usage: %s [-hv] <blufile> [<filetoextract> ...]\n", - progname); - return; - -} /* usage */ - - - -void printhelp() -{ - fprintf(stderr, "\t-h show this help.\n"); - fprintf(stderr, "\t-v show contents of archive.\n"); -} _E_O_F_ if test 15128 -ne `wc -c < unblu.c `; then echo shar: "'unblu.c'" unpacked with wrong size! fi echo shar: extracting unexec.c if test -f 'unexec.c' then echo shar: over-writing existing file "'unexec.c'" fi sed -e 's/^-//' << \_E_O_F_ > unexec.c - -/* - * unexec.c - * - * By Marcel J.E. Mol - * - * I hereby place this program into public domain ... - * ... all those all those if and whats etc.... - * I'm completely unresposible for any damage this program may cause you. - * - * - * Unexec expects a input file consisting of lines which are usually - * entered in the apple monitor. Remove the 'CALL -151' line from the file, - * and the 'BSAVE ..' at the end of the file. Fed the resulting data to - * unexec and binary data is output. When unexec has processed the file, - * it prints the address of the first and last databyte on stderr. The binary - * data contains all the bytes between the first and last address, even - * if no data was in the input file for a specific address (unexec just - * initializes a 64k byte array of zeros). - * Thus each line in the input file looks like: - * - * 01F0: A2 00 A0 10 A9 00 BD 00 20 E8 D0 FA - * - * Usage: The program reads from a file or stdin, and outputs to - * stdout. I usually use the program as follows: - * - * unexec file.ex > binfile - */ - -#include <stdio.h> -#include <ctype.h> - -char * copyright = "@(#) unexec.c 2.1 18/06/88 (c) M.J.E. Mol"; - -char mem[66000]; -int addr; -int memmin, memmax; -int tmp; -int b; -char buf[128]; -int i; - - -main(argc, argv) -int argc; -char **argv; -{ - FILE *fp; - - if ((argc == 1) || (!strcmp(argv[1], "-"))) - fp = stdin; - else { - if ((fp = fopen(argv[1], "r")) == NULL) { - perror(argv[1]); - exit(1); - } - } - unexec(fp); - - exit(0); - - -} /* main */ - - - -unexec(fp) -FILE *fp; -{ - addr = -1; - memmin = 100000; - memmax = 0; - tmp = 0; - while (fgets(buf, 128, fp) != NULL) { - i = 0; - while (i <= strlen(buf)) { - if (buf[i] == ':') { - addr = tmp; - if ((addr < memmin) && (addr >= 0)) - memmin = addr; - tmp = 0; - i++; - skipblank(); - } - else if ((isspace(buf[i])) || (buf[i] == '\0')) { - if (tmp > 255) - fprintf(stderr, "Assuming %d to be $FF\n", tmp); - mem[addr++] = tmp; - tmp = 0; - skipblank(); - } - else { - if ((buf[i] >= '0') && (buf[i] <= '9')) - tmp = (tmp << 4) + buf[i] - '0'; - else if ((buf[i] >= 'a') && (buf[i] <= 'f')) - tmp = (tmp << 4) + buf[i] - 'a' + 10; - else if ((buf[i] >= 'A') && (buf[i] <= 'F')) - tmp = (tmp << 4) + buf[i] - 'A' + 10; - else fprintf(stderr, "Illegal character %c\n", buf[i]); - i++; - } - } - if (addr > memmax) - memmax = addr; - } - for (i = memmin; i<= memmax; i++) - putchar(mem[i]); - fprintf(stderr, "Lower address: %x\n", memmin); - fprintf(stderr, "Higher address: %x\n", memmax); - -} /* unexec */ - - - -skipblank() -{ - while ((isspace(buf[i]) || (buf[i] == '\0')) && i <= strlen(buf)) - i++; -} - - _E_O_F_ if test 2656 -ne `wc -c < unexec.c `; then echo shar: "'unexec.c'" unpacked with wrong size! fi echo shar: extracting usq.c if test -f 'usq.c' then echo shar: over-writing existing file "'usq.c'" fi sed -e 's/^-//' << \_E_O_F_ > usq.c - -/* - * usq.c - * - * By Marcel J.E. Mol - * - * I hereby place this program into public domain ... - * ... all those all those if and whats etc.... - * I'm completely unresposible for any damage this program may cause you. - * - * Usq unsqueezes a file squeezed with the apple sq3 program. - * Files extracted from a binary 2 file (using unblu for example) - * with a .QQ or .Q extensing are probably squeezed files. - * - * Usage: The program reads from a file or stdin, and outputs to - * stdout. I usually use the program as follows: - * - * usq file.QQ > file - * - * Remember that the newline character on apple is different from Unix. - * Thus files extracted with unblu, and possibly unsqueezed with usq - * may have an ^M character instead of a \n character at the end of each line. - * To create a proper Unix file use the following 'tr' command: - * - * tr '\015' '\012' < applefile > unixfile - */ - -#include <stdio.h> - -/* - * Squeezed file format: - * 2 bytes MAGIC - * 2 bytes dummy ??? - * filename ended by \0 - * 2 bytes node count - * node count node values, each 2 bytes - * squeezed data per byte - */ - -#define BUFSIZE 128 -#define MAGIC 0xff76 /* Squeezed file magic */ -#define DLE 0x90 /* repeat byte flag */ -#define NOHIST 0 /* no relevant history */ -#define INREP 1 /* sending a repeated value */ -#define SPEOF 256 /* special endfile token */ -#define NUMVALS 257 /* 256 data values plus SPEOF */ - -char * copyright = "@(#) usq.c 2.1 18/06/88 (c) M.J.E. Mol"; - -/* Global variable declarations */ -char *progname; -char *sfn; /* squeezed file name */ -struct nd { /* decoding tree */ - int child[2]; /* left, right */ -} node[NUMVALS]; /* use large buffer */ -int state; /* repeat unpacking state */ -int bpos; /* last bit position read */ -int curin; /* last byte value read */ -int numnodes; /* number of nodes in decode tree */ - - -/* Functions declarations */ -void main (); -int unsqueeze (); -void putc_ncr (); -int get_int (); -int init_usq (); -int getc_usq (); - - - -void main(argc, argv) -int argc; -char ** argv; -{ - - FILE *fp; /* File pointer for squeezed file */ - register int r = 0; /* Exit value */ - - progname = argv[0]; - - if (argc == 1) /* no args; unsqueeze standard input */ - r = unsqueeze(stdin); - else /* unsqueeze each file in arglist */ - while (--argc > 0) { - sfn = *++argv; - if ((fp = fopen(sfn, "r")) == NULL) { - perror(sfn); - continue; - } - r |= unsqueeze(fp); - fclose(fp); - } - - exit(r); - -} /* main */ - - - -int unsqueeze(sfp) -FILE *sfp; -{ - register int i; - register int c; /* one char of stream */ - char fname[BUFSIZE]; - int magic; - register FILE *dfp; - - magic = get_int(sfp); -#if defined(DEBUG) - fprintf(stderr, "Magic number: %x\n", magic); -#endif - if (magic != MAGIC) { /* Check magic number */ - fprintf(stderr, "%s: %s not a squeezed file\n", progname, sfn); - fprintf(stderr, "Wrong magic number: %x\n", magic); - return(1); - } - (void) get_int(sfp); /* two dummy bytes ??? */ - i = 0; /* get the original file name */ - while ((fname[i++] = getc(sfp)) != NULL) - ; - - if ((dfp = fopen(fname, "w")) == NULL) { /* open destination file */ - perror(fname); - return(1); - } - - state = NOHIST; /* initial repeat unpacking state */ - - if (init_usq(sfp)) /* init unsqueeze algorithm */ - return 1; - while ((c=getc_usq(sfp)) != EOF) /* and unsqueeze file */ - putc_ncr(c, dfp); - - return 0; /* file is okay */ - -} /* unsqueeze */ - - - - -/* putc-ncr -- decode non-repeat compression. Bytes are passed one - * at a time in coded format, and are written out uncoded. - * The data is stored normally, except that runs of more - * than two characters are represented as: - * - * <char> <DLE> <count> - * - * With a special case that a count of zero indicates a DLE - * as data, not as a repeat marker. - */ -void putc_ncr(c, t) /* put NCR coded bytes */ -unsigned char c; /* next byte of stream */ -FILE *t; /* file to receive data */ -{ - static int lastc; /* last character seen */ - - switch (state) { /* action depends on our state */ - case NOHIST: /* no previous history */ - if (c==DLE) /* if starting a series */ - state = INREP; /* then remember it next time */ - else putc(lastc=c, t); /* else nothing unusual */ - return; - - case INREP: /* in a repeat */ - if (c) /* if count is nonzero */ - while (--c) /* then repeatedly ... */ - putc(lastc, t); /* ... output the byte */ - else putc(DLE, t); /* else output DLE as data */ - state = NOHIST; /* back to no history */ - return; - - default: - fprintf(stderr, "%s: bad NCR unpacking state (%d)", - progname, state); - } - -} /* putc_ncr */ - - - - -int get_int(f) /* get an integer */ -FILE *f; /* file to get it from */ -{ - - return getc(f) | (getc(f) << 8); - -} /* get_int */ - - - -int init_usq(f) /* initialize Huffman unsqueezing */ -FILE *f; /* file containing squeezed data */ -{ - register int i; /* node index */ - - bpos = 99; /* force initial read */ - - numnodes = get_int(f); /* get number of nodes */ - - if (numnodes<0 || numnodes>=NUMVALS) { - fprintf(stderr, "%s: %s file has an invalid decode tree", - progname, sfn); - return 1; - } - - /* initialize for possible empty tree (SPEOF only) */ - - node[0].child[0] = -(SPEOF + 1); - node[0].child[1] = -(SPEOF + 1); - - for (i=0; i<numnodes; ++i) { /* get decoding tree from file */ - node[i].child[0] = get_int(f); - node[i].child[1] = get_int(f); - } - - return 0; - -} /* init_usq */ - - - - -int getc_usq(f) /* get byte from squeezed file */ -FILE *f; /* file containing squeezed data */ -{ - register int i; /* tree index */ - - /* follow bit stream in tree to a leaf */ - - for (i=0; (i < 0x8000) && (i>=0); )/* work down(up?) from root */ - { - if (++bpos > 7) { - if ((curin=getc(f)) == EOF) - return(EOF); - bpos = 0; - - /* move a level deeper in tree */ - i = node[i].child[1 & curin]; - } - else i = node[i].child[1 & (curin >>= 1)]; - } - - /* decode fake node index to original data value */ - i = i | 0xffff0000; /* Unix hack: have 32 bits instead of 16 */ - i = -(i + 1); - - - /* decode special endfile token to normal EOF */ - return ((i==SPEOF) ? EOF : i); - -} /* getc_usq */ _E_O_F_ if test 7388 -ne `wc -c < usq.c `; then echo shar: "'usq.c'" unpacked with wrong size! fi # end of shell archive exit 0 -- ######################################### # Marcel J.E. Mol # They hate you if your're clever # Delft, University of Technology # And they despise the fool # The Netherlands # Till you're so fucking crazy # UUCP: marcel@duteca.UUCP # You can't follow the rules. # duteca!marcel # ######################################### - Lennon