Submitted-by: Dan Bernstein <brns...@stealth.acf.nyu.edu> Posting-number: Volume 21, Issue 1 Archive-name: squeeze1.711 squeeze, unsqueeze -- compress data with Miller-Wegman encoding. Edit the options in Makefile and type make. squeeze and unsqueeze will be the executable programs; the nroff'ed man files will go into squeeze.1, unsqueeze.1, etc. squeeze and unsqueeze are filters only; sqz, sqzdir, unsqz, unsqzdir, and mwcat apply them to files. Note that the shell scripts need filterfile version 1.2 or later. I don't pretend to know your machine's setup so there's no make install. Read CHANGES for a list of changes. Type squeeze -C and squeeze -W for copyright and warranty information, squeeze -H for help; similarly for unsqueeze. #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: README CHANGES mwcat.man squeeze.man sqz.man sqzdir.man # unsqueeze.man squeeze.c unsqueeze.c sqz sqzdir unsqz unsqzdir # mwcat Makefile PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(1543 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' Xsqueeze, unsqueeze - compress data with Miller-Wegman encoding X Xsqueeze version 1.711, October 28, 1989. XCopyright (c) 1989, Daniel J. Bernstein. XAll rights reserved. X XThis distribution packaged October 28, 1989. X XFiles: XCHANGES Description of changes since first distributed version XREADME This document XMakefile Installation commands Xsqueeze.c The squeeze program Xunsqueeze.c The unsqueeze program Xsqz A shell script to apply squeeze to files Xsqzdir A shell script to apply squeeze to a directory hierarchy Xunsqz A shell script to apply unsqueeze to files Xunsqzdir A shell script to apply unsqueeze to a directory unhierary Xmwcat A shell script to apply cat to squeezed files Xsqueeze.man Documentation for squeeze Xunsqueeze.man Documentation for unsqueeze Xsqz.man Documentation for sqz, unsqz Xsqzdir.man Documentation for sqzdir, unsqzdir Xmwcat.man Documentation for mwcat X XEdit the options in Makefile and type make. squeeze and unsqueeze Xwill be the executable programs; the nroff'ed man files will go into Xsqueeze.1, unsqueeze.1, etc. squeeze and unsqueeze are filters only; Xsqz, sqzdir, unsqz, unsqzdir, and mwcat apply them to files. XNote that the shell scripts need filterfile version 1.2 or later. X XI don't pretend to know your machine's setup so there's no make install. X XRead CHANGES for a list of changes. Type squeeze -C and squeeze -W Xfor copyright and warranty information, squeeze -H for help; similarly Xfor unsqueeze. END_OF_FILE if test 1543 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'CHANGES' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'CHANGES'\" else echo shar: Extracting \"'CHANGES'\" \(261 characters\) sed "s/^X//" >'CHANGES' <<'END_OF_FILE' XVersion 1.711, 10/28/89. (Can't wait for 1.7111, 1.71111111, ... :-) ) X XPut in new copyright notice and warranty. X XVersion 1.71, 9/27/89. X Xsqueeze and unsqueeze now complain about being given a filename. XAdded sqz, sqzdir, unsqz, unsqzdir, mwcat. X XVersion 1.7. END_OF_FILE if test 261 -ne `wc -c <'CHANGES'`; then echo shar: \"'CHANGES'\" unpacked with wrong size! fi # end of 'CHANGES' fi if test -f 'mwcat.man' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mwcat.man'\" else echo shar: Extracting \"'mwcat.man'\" \(1122 characters\) sed "s/^X//" >'mwcat.man' <<'END_OF_FILE' X.TH mwcat 1 X.SH NAME Xmwcat \- print the contents of X\fIsqueeze\fBd Xfiles X.SH SYNTAX Xmwcat X[ options and files ] X.SH DESCRIPTION X.I mwcat Xapplies X.I unsqueeze Xto one or more files, Xprinting the result. XIt passes all options through to X.I unsqueeze. X.PP XRead the X.I squeeze Xand X.I unsqueeze Xdocumentation for a description of options and Xof the compression method. X.SH EXAMPLES XTo view foo.MW: X.PP X.EX Xmwcat foo | more X.EE X.PP XFor a display revealing common substrings (try it): X.PP X.EX Xmwcat -d~ foo | more X.EE X.SH DIAGNOSTICS X.TP X\fIfatal: must specify filenames; use unsqueeze for a filter\fB XSelf-explanatory. X.PP X.I unsqueeze Xwill print compression statistics if you specify X.B\-v. X.SH MACHINES X.I mwcat Xhas been tested on an Astronautics ZS-2 Xrunning ZSUnix, Xa Convex C1 running Convex UNIX, Xand an HP9000 running HP-UX. X.SH FILES XNone. X.SH BUGS XNone known. X.SH RESTRICTIONS X.I mwcat Xis truly obnoxious in insisting upon a single MW suffix Xfor X\fIsqueeze\fBd Xfiles. X.SH VERSION Xmwcat, dated September 27, 1989. X.SH AUTHOR XCopyright 1989, Daniel J. Bernstein. X.SH "SEE ALSO" Xsqueeze(1), Xunsqueeze(1), Xsqz(1), Xsqzdir(1) END_OF_FILE if test 1122 -ne `wc -c <'mwcat.man'`; then echo shar: \"'mwcat.man'\" unpacked with wrong size! fi # end of 'mwcat.man' fi if test -f 'squeeze.man' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'squeeze.man'\" else echo shar: Extracting \"'squeeze.man'\" \(4581 characters\) sed "s/^X//" >'squeeze.man' <<'END_OF_FILE' X.TH squeeze 1 X.SH NAME Xsqueeze \- compress data with Miller\-Wegman encoding X.SH SYNTAX Xsqueeze X[ X\fB\-eErRbBv\fI X] [ X\fB\-ACHUVW\fI X] X.SH DESCRIPTION X.I squeeze Xcompresses its standard input Xand writes the result to its standard output. X\fIsqueeze\fBd Xfiles can be restored Xwith X\fIunsqueeze\fB. X.PP XOptions X.B ACHUVW Xprint the authorship notice, Xcopyright notice, Xhelp notice, Xshort usage summary, Xversion number, Xand warranty information respectively. X.PP X.I squeeze Xhas several flags: X.TP 12 X.B -e XLeave an explicit end-of-file marker in the output. XIf you use this flag, you can add any Xsort of random garbage onto the end of the compressed data Xwithout affecting the decompressed form. X.TP X.B -E XDo not leave an end-of-file marker. This is the default. X.TP X.B -r XProduce ``randomized'' output. X.I squeeze Xwill use the time of day to introduce Xrandom bits of information Xinto the output. XNormally, for efficiency and so that X.I squeeze Xcan produce output before seeing the end of the input, Xthere must be slight output redundancy. XUnder X.B -r, Xthis redundancy disappears Xand almost all X\fIsqueeze\fBd Xtexts are possible. XSince X.I squeeze Xdoes not output a recognizable header, Xand since Miller-Wegman encoding is so good at removing Xredundancy, X.I squeeze -r Xis a very useful step before encryption. X(Caveat: the beginning of the output depends only Xon the beginning of the input, so you should make sure Xto X.I precede the uncompressed input X.I by unpredictable data Xbefore feeding it to X.I squeeze.) X.TP X.B -R XDo not randomize output. This is the default. X.TP X.B -b X.I squeeze Xmaintains a X``dictionary'' Xof strings Xadapted to the data seen so far. XWhen X.I squeeze Xruns out of memory, Xit will adapt to the next X``block'' of the file Xby throwing out the dictionary and starting over. XThis is the default behavior and is given explicitly as X.B -b. X.TP X.B -B XGiven this flag, X.I squeeze Xwill simply freeze its old dictionary Xwhen it runs out of memory, Xrather than hope to do better on the Xsucceeding data. XThis will produce better (and faster) results Xif the first ``block'' of the file Xhas similar characteristics to the rest of the file. X.TP X.B -v X.I squeeze Xwill be ``verbose'' and report compression statistics Xto standard error. X.PP X.I squeeze Xuses Miller-Wegman encoding, Xa variant on Ziv-Lempel encoding. XThe amount of compression obtained depends on the size of the Xinput, the amount of memory X.I squeeze Xuses, Xand the distribution of common substrings. XTypically, text such as source code or English Xis reduced by 70\-80%. X.PP XIt is natural to compare X.I squeeze Xto X.I compress, Xwhich uses straightforward Ziv-Lempel encoding. XIn the author's experience, XMiller-Wegman encoding produces output X10\-40% Xsmaller than the corresponding Ziv-Lempel output; Xand the best case is much better. XOn the other hand, XMiller-Wegman encoding fares slightly worse Xon patternless data, Xand since it requires general string matching Xwhile Ziv-Lempel requires only a restricted type Xof string matching, X.I squeeze Xhas been somewhat slower than X.I compress Xin the author's tests. X.PP XFor files longer than a megabyte, X.I squeeze Xoften produces output under one third the size of the output from X.I compress, Xbut may do twice as much computation. XIt should also be noted that X.I squeeze Xis much more of a memory hog than X.I compress, Xsince it uses a more complex algorithm. X.PP XThe choices between X.B -e Xand X.B -E, Xand between X.B -b Xand X.B -B, Xchange the structure of the compressed file. XBe careful to select the same flags for X.I unsqueeze. X.SH DIAGNOSTICS X.TP X\fIIn:\fB xxx \fIchars Out:\fB xxx \fIchars Squeezed to:\fB xx% XThe utilizer of the computational machinery Xhas specified the ``verbose'' option Xto X.I squeeze Xvia the Xestablishment of the character v Xwithin an argument Xpreceded by a hyphen. X.TP X\fII am a filter, try sqz for squeezing files\fB XSelf-explanatory. X.SH MACHINES X.I squeeze Xhas been tested on an Astronautics ZS-2 Xrunning ZSUnix, Xa Convex C1 running Convex UNIX, Xand an HP9000 running HP-UX. X.SH FILES XNone. X.SH BUGS XNone known. X.SH RESTRICTIONS X.I squeeze Xdoes not adapt to the amount of memory available; Xits memory use is set at compile time. X.PP X.I squeeze Xdoes not provide a more advanced blocking method. X.SH VERSION Xsqueeze version 1.711, dated October 28, 1989. X.SH AUTHOR XCopyright 1989, Daniel J. Bernstein. X.SH REFERENCES XVictor S. Miller, X"Data Compression Algorithms" Xin Proceedings of Symposia in Applied Mathematics XVolume 34, 1986. XA readable summary of major coding methods. X.SH "SEE ALSO" Xunsqueeze(1), Xsqz(1), Xsqzdir(1), Xmwcat(1), Xcompress(1) END_OF_FILE if test 4581 -ne `wc -c <'squeeze.man'`; then echo shar: \"'squeeze.man'\" unpacked with wrong size! fi # end of 'squeeze.man' fi if test -f 'sqz.man' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sqz.man'\" else echo shar: Extracting \"'sqz.man'\" \(1777 characters\) sed "s/^X//" >'sqz.man' <<'END_OF_FILE' X.TH sqz 1 X.SH NAME Xsqz \- apply X.I squeeze Xto a file X.PP Xunsqz \- apply X.I unsqueeze Xto a file X.SH SYNTAX Xsqz X[ options and files ] X.PP Xunsqz X[ options and files ] X.SH DESCRIPTION X.I sqz Xuses X.I filterfile Xto apply X.I squeeze Xto one or more files. XIt passes all options through to X.I squeeze. X.I unsqz Xbears the same relation to X.I unsqeeze. X.PP XEach original file is removed; Xthe X\fIsqueeze\fBd Xdata is placed into a file having the same name Xwith a suffix of X\fIMW\fB. X.I sqz Xstrips this suffix from its input file names. X.PP XFile protections and access/modification times are preserved. X.PP X.I unsqz Xsimply reverses the operations of X.I sqz. X.PP XRead the X.I squeeze Xand X.I unsqueeze Xdocumentation for a description of options and Xof the compression method. X.SH DIAGNOSTICS X.TP X\fIfatal: must specify filenames; use squeeze for a filter\fB XSelf-explanatory. X.PP X.I squeeze Xand X.I unsqueeze Xwill print compression statistics if you specify X.B\-v. X.PP X.I filterfile Xmay produce error messages if Xa file does not exist or has more than one link, Xor if you move the file during Xthe operation. X.SH MACHINES X.I sqz Xand X.I unsqz Xhave been tested on an Astronautics ZS-2 Xrunning ZSUnix, Xa Convex C1 running Convex UNIX, Xand an HP9000 running HP-UX. X.SH FILES XNone. X.SH BUGS XNone known. X.SH RESTRICTIONS X.I sqz Xand X.I unsqz Xare truly obnoxious in insisting upon a single MW suffix Xfor X\fIsqueeze\fBd Xfiles. X.PP X.I sqz Xand X.I unsqz Xdo not provide for overwriting an existing file. X.PP XBecause Xthese programs are not integrated, Xthe error messages may seem a bit strange at times. X.SH VERSION Xsqz, dated September 27, 1989. X.PP Xunsqz, dated September 27, 1989. X.SH AUTHOR XCopyright 1989, Daniel J. Bernstein. X.SH "SEE ALSO" Xsqueeze(1), Xunsqueeze(1), Xsqzdir(1), Xmwcat(1), Xfilterfile(1) END_OF_FILE if test 1777 -ne `wc -c <'sqz.man'`; then echo shar: \"'sqz.man'\" unpacked with wrong size! fi # end of 'sqz.man' fi if test -f 'sqzdir.man' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sqzdir.man'\" else echo shar: Extracting \"'sqzdir.man'\" \(1964 characters\) sed "s/^X//" >'sqzdir.man' <<'END_OF_FILE' X.TH sqz 1 X.SH NAME Xsqzdir \- apply X.I squeeze Xto a directory hierarchy X.PP Xunsqzdir \- apply X.I unsqueeze Xto a directory hierarchy X.SH SYNTAX Xsqzdir X[ options and directories ] X.PP Xunsqzdir X[ options and directories ] X.SH DESCRIPTION X.I sqzdir Xuses X.I find Xand X.I filterfile Xto apply X.I squeeze Xto one or more directories, Xpassing down through the entire tree beneath each directory. XIt passes all options through to X.I squeeze. X.I unsqzdir Xbears the same relation to X.I unsqeeze. X.PP XEach original file is removed; Xthe X\fIsqueeze\fBd Xdata is placed into a file having the same name Xwith a suffix of X\fIMW\fB. X.I sqzdir Xstrips this suffix from its input file names. X.PP XFile protections and access/modification times are preserved. X.PP X.I unsqzdir Xsimply reverses the operations of X.I sqzdir. X.PP XIf you do not specify a filename, X.I sqzdir Xand X.I unsqzdir Xassume the current directory. X.PP XRead the X.I squeeze Xand X.I unsqueeze Xdocumentation for a description of options and Xof the compression method. X.SH DIAGNOSTICS X.PP X.I squeeze Xand X.I unsqueeze Xwill print compression statistics if you specify X.B\-v. X.PP X.I filterfile Xmay produce error messages if Xa file does not exist or has more than one link, Xor if you move the file during Xthe operation. X.SH MACHINES X.I sqzdir Xand X.I unsqzdir Xhave been tested on an Astronautics ZS-2 Xrunning ZSUnix, Xa Convex C1 running Convex UNIX, Xand an HP9000 running HP-UX. X.SH FILES XNone. X.SH BUGS XNone known. X.SH RESTRICTIONS X.I sqzdir Xand X.I unsqzdir Xare truly obnoxious in insisting upon a single MW suffix Xfor X\fIsqueeze\fBd Xfiles. X.PP X.I sqzdir Xand X.I unsqzdir Xdo not provide for overwriting an existing file. X.PP XBecause Xthese programs are not integrated, Xthe error messages may seem a bit strange at times. X.SH VERSION Xsqzdir, dated September 27, 1989. X.PP Xunsqzdir, dated September 27, 1989. X.SH AUTHOR XCopyright 1989, Daniel J. Bernstein. X.SH "SEE ALSO" Xsqueeze(1), Xunsqueeze(1), Xsqz(1), Xmwcat(1), Xfilterfile(1), Xfind(1) END_OF_FILE if test 1964 -ne `wc -c <'sqzdir.man'`; then echo shar: \"'sqzdir.man'\" unpacked with wrong size! fi # end of 'sqzdir.man' fi if test -f 'unsqueeze.man' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'unsqueeze.man'\" else echo shar: Extracting \"'unsqueeze.man'\" \(3588 characters\) sed "s/^X//" >'unsqueeze.man' <<'END_OF_FILE' X.TH unsqueeze 1 X.SH NAME Xunsqueeze \- decompress data squeezed with Miller\-Wegman encoding X.SH SYNTAX Xunsqueeze X[ X\fB\-eErRbBv\fI X] [ X\fB\-d\fIstring X] [ X\fB\-ACHUVW\fI X] X.SH DESCRIPTION X.I unsqueeze Xdecompresses its standard input Xand writes the result to its standard output. XThe input should be a file compressed with X.I squeeze. X.PP XOptions X.B ACHUVW Xprint the authorship notice, Xcopyright notice, Xhelp notice, Xshort usage summary, Xversion number, Xand warranty information respectively. X.PP X.I unsqueeze Xhas several flags: X.TP 12 X.B -e XExpect an explicit end-of-file marker in the output. X.TP X.B -E XDo not expect an explicit end-of-file marker. This is the default. X.TP X.B -r XAccept any input string, including X``randomized'' output from X.I squeeze. XThis is the default. X.TP X.B -R XComplain about randomized inputs. XThis will catch most inputs that come from X\fIsqueeze\fB -r; Xit will also tend to catch inputs that don't come Xfrom X.I squeeze Xat all. X.TP X.B -b XExpect ``blocked'' input and accept ``next block'' codes. XThis is the default. X.TP X.B -B XExpect unblocked input. X.TP X\fB-d\fIstring XInsert X.I string Xbetween output bunches. XIf you want to get a feel for the workings Xof Miller-Wegman compression, try this. X.TP X.B -v X.I unsqueeze Xwill be ``verbose'' and report compression statistics Xto standard error. X.PP XSee X.I squeeze(1) Xfor a discussion of the time-space tradeoff Xinvolved in using Miller-Wegman encoding rather than XZiv-Lempel encoding. XNote that X.I unsqueeze Xruns nearly as quickly as X.I uncompress, Xfor the same size decompressed text, Xand can run faster for huge texts. X.PP XThe choices between X.B -e Xand X.B -E, Xand between X.B -b Xand X.B -B, Xchange the structure of the compressed file. XBe careful to select the same flags as X.I squeeze Xwas given. X.SH DIAGNOSTICS X.TP 1.5i X.I bad (randomized) input XYou gave the flag X.B -R Xand the input cannot have come from X.I squeeze Xwith the same flags. X.TP X.I out of memory XThe file was X\fIsqueeze\fBd Xin much more memory than X.I unsqueeze Xhas available. X.TP X.I EOF not signalled? XYou gave the flag X.B -e Xbut the input did not signal end-of-file. X.TP X\fIIn:\fB xxx \fIchars Out:\fB xxx \fIchars Squeezed to:\fB xx% XThe utilizer of the computational machinery Xhas specified the ``verbose'' option Xto X.I unsqueeze Xvia the Xestablishment of the character v Xwithin an argument Xpreceded by a hyphen. X.TP X\fII am a filter, try unsqz for unsqueezing files\fB XSelf-explanatory. X.SH MACHINES X.I unsqueeze Xhas been tested on an Astronautics ZS-2 Xrunning ZSUnix, Xa Convex C-1 running Convex UNIX, Xand an HP9000 running HP-UX. X.SH FILES XNone. X.SH BUGS XNone known. X.SH RESTRICTIONS X.I unsqueeze Xdoes not adapt to the amount of memory available; Xits memory use is set at compile time. X.PP XUnlike X.I uncompress, X.I unsqueeze Xcarefully checks bounds on its variables Xand cannot be made to loop. X(\fIuncompress\fB Xdepends upon receiving signal SEGV when it uses out-of-bounds Xvariables.) XFor efficiency, X.I unsqueeze Xmakes one exception Xthat could, conceivably, cause a segmentation fault. XThis exception can only happen for certain Xspecially constructed files of length at least Xhalf a billion bytes. XOf course, that doesn't excuse the author, Xwho begs forgiveness for this lapse of judgment. X.SH VERSION Xunsqueeze version 1.711, dated October 28, 1989. X.SH AUTHOR XCopyright 1989, Daniel J. Bernstein. X.SH REFERENCES XVictor S. Miller, X"Data Compression Algorithms" Xin Proceedings of Symposia in Applied Mathematics XVolume 34, 1986. XA readable summary of major coding methods. X.SH "SEE ALSO" Xsqueeze(1), Xsqz(1), Xsqzdir(1), Xmwcat(1), Xcompress(1) END_OF_FILE if test 3588 -ne `wc -c <'unsqueeze.man'`; then echo shar: \"'unsqueeze.man'\" unpacked with wrong size! fi # end of 'unsqueeze.man' fi if test -f 'squeeze.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'squeeze.c'\" else echo shar: Extracting \"'squeeze.c'\" \(11779 characters\) sed "s/^X//" >'squeeze.c' <<'END_OF_FILE' X/* Xsqueeze.c: Adaptive data compression with Miller-Wegman method. X*/ X X/* explicit blocking char? <-- */ X/* go from file to file and delete old file... .M? .W? .S? */ X/* alloc() instead of huge array? less obnoxious? */ X/* maybe stick to shorts for codes? half the memory */ X/* how else to reduce memory requirement? */ X/* signals? */ X/* LRU? I think not */ X/* option to decompress instead? I think not */ X/* needs option for not searching dictionary after memory freeze? no */ X/* is transition through clearing table ok? yes */ X/* other blocking methods? not yet */ X/* trie at top levels? like first version? hmmm */ X Xstatic char squeezeauthor[] = X"squeeze was written by Daniel J. Bernstein.\n\ XInternet address: brns...@acf10.nyu.edu.\n\ XThanks to Herbert J. Bernstein for suggesting the data structures used.\n"; X Xstatic char squeezeversion[] = X"squeeze version 1.711, October 28, 1989.\n\ XCopyright (c) 1989, Daniel J. Bernstein.\n\ XAll rights reserved.\n"; X Xstatic char squeezecopyright[] = X"squeeze version 1.711, October 28, 1989.\n\ XCopyright (c) 1989, Daniel J. Bernstein.\n\ XAll rights reserved.\n\ X\n\ XYou are granted the following rights: A. To make copies of this work in\n\ Xoriginal form, so long as (1) the copies are exact and complete; (2) the\n\ Xcopies include the copyright notice, this paragraph, and the disclaimer\n\ Xof warranty in their entirety. B. To distribute this work, or copies made\n\ Xunder the provisions above, so long as (1) this is the original work and\n\ Xnot a derivative form; (2) you do not charge a fee for copying or for\n\ Xdistribution; (3) you ensure that the distributed form includes the\n\ Xcopyright notice, this paragraph, and the disclaimer of warranty in their\n\ Xentirety. These rights are temporary and revocable upon written, oral, or\n\ Xother notice by Daniel J. Bernstein. This copyright notice shall be\n\ Xgoverned by the laws of the state of New York.\n\ X\n\ XIf you have questions about squeeze or about this copyright notice,\n\ Xor if you would like additional rights beyond those granted above,\n\ Xplease feel free to contact the author at brns...@acf10.nyu.edu\n\ Xon the Internet.\n"; X Xstatic char squeezewarranty[] = X"To the extent permitted by applicable law, Daniel J. Bernstein disclaims\n\ Xall warranties, explicit or implied, including but not limited to the\n\ Ximplied warranties of merchantability and fitness for a particular purpose.\n\ XDaniel J. Bernstein is not and shall not be liable for any damages,\n\ Xincidental or consequential, arising from the use of this program, even\n\ Xif you inform him of the possibility of such damages. This disclaimer\n\ Xshall be governed by the laws of the state of New York.\n\ X\n\ XIn other words, use this program at your own risk.\n\ X\n\ XIf you have questions about squeeze or about this disclaimer of warranty,\n\ Xplease feel free to contact the author at brns...@acf10.nyu.edu\n\ Xon the Internet.\n"; X Xstatic char squeezeusage[] = X"Usage: squeeze [ -eErRbBvACHUVW ]\n\ XHelp: squeeze -H\n"; X Xstatic char squeezehelp[] = X"squeeze compresses its input and prints the result, using adaptive Miller-\n\ XWegman encoding, a variation on Ziv-Lempel encoding. It usually produces\n\ Xfiles 10-40%% shorter than compress does. To decompress, use unsqueeze.\n\ X\n\ Xsqueeze -A: print authorship notice\n\ Xsqueeze -C: print copyright notice\n\ Xsqueeze -H: print this notice\n\ Xsqueeze -U: print short usage summary\n\ Xsqueeze -V: print version number\n\ Xsqueeze -W: print disclaimer of warranty\n\ X\n\ Xsqueeze [ -eErRbBv ]: compress\n\ X -e: explicitly indicate EOF\n\ X -E: do not explicitly indicate EOF (default)\n\ X -r: ``randomize'' output; useful before encryption\n\ X -R: do not randomize output (default)\n\ X -b: readapt to next block when out of memory (default)\n\ X -B: freeze working adaptation when out of memory\n\ X -v: announce compression results (``verbose'')\n\ X\n\ XIf you have questions about or suggestions for squeeze, please feel free\n\ Xto contact the author, Daniel J. Bernstein, at brns...@acf10.nyu.edu\n\ Xon the Internet.\n"; X X#include <stdio.h> X#include <sys/time.h> X X#define ALPHABET 256 X#define BUFSIZE 300000 X#define DICTSIZE BUFSIZE X#define MOD 354621 X#define OUTBUFSIZE 2000 X Xint flagrandom = 0; Xint flageof = 0; Xint flagblocking = 1; /* sigh */ Xint flagverbose = 0; X Xint numberin = 0; Xint numberout = 0; X Xint table[MOD]; X Xint parent[DICTSIZE]; Xint num[DICTSIZE]; Xint next[DICTSIZE]; X X#define morehash(curhash,ch) ( ( curhash * 256 + ch + 1) % MOD ) X/* Rules on hash: For same curhash and different ch, must produce Xdifferent hash. Must produce values between 0 and MOD - 1. X*/ X Xcleartable() X{ X register int h; X X for (h = 0;h < MOD;) X table[h++] = 0; X} X Xgoaheadandbeverbose() X{ X fprintf(stderr,"In: %d chars Out: %d chars Squeezed to: %d%%\n", X numberin,numberout,(100 * numberout + numberin / 2) / numberin); X} X Xinitdictionary() X{ X register int ch; X X for (ch = 0;ch < ALPHABET;ch++) X { X parent[ch + 1] = 0; X num[ch + 1] = ch; X next[ch + 1] = 0; X table[morehash(0,ch)] = ch + 1; X } X} X Xint y[55]; Xint j; Xint k; X Xinitrandom() X{ X struct timeval t; X X gettimeofday(&t,(struct timezone *) NULL); X for (j = 0;j < 20;j++) X y[j] = ((t.tv_usec >> j) + (t.tv_sec >> j)) % 2; X gettimeofday(&t,(struct timezone *) NULL); X for (j = 0;j < 20;j++) X y[j + 20] = (t.tv_usec >> j) % 2; X y[54] = 1; X j = 24; X k = 0; X} X Xint randombit() X{ X j = (j + 54) % 55; X k = (k + 54) % 55; X return(y[k] = y[k] ^ y[j]); X} X X/* input routines */ X Xunsigned char buf[BUFSIZE]; Xint bufstart = 0; Xint bufend = 0; X X/* getchar() with readable buffer */ X#define inchar() ( bufstart != bufend ? ((result = buf[bufstart]), \ X (bufstart = (bufstart + 1) % BUFSIZE), result) : ((result = getchar()), \ X result == EOF ? EOF : ((buf[bufstart] = result = (unsigned char) result), \ X (bufend = (bufstart = (bufstart + 1) % BUFSIZE)), result ))) X/* uses register int result --- down in main */ X X/* reread last n buffered characters */ X#define inrepeat(n) { bufstart = (bufstart + BUFSIZE - (n)) % BUFSIZE; } X/* stupid C mod... note: need not check n > BUFSIZE since n < DICTSIZE */ X X/* un-reread n buffered characters */ X#define uninrepeat(n) { bufstart = (bufstart + (n)) % BUFSIZE; } X/* stupid C mod... note: need not check n > BUFSIZE since n < DICTSIZE */ X X/* output routines */ X Xint outn[OUTBUFSIZE]; Xint outb[OUTBUFSIZE]; Xint outbitpos = 0; Xint outword = 0; Xint outbuf = 0; X Xoutnum(ch,max) Xregister int ch; Xregister int max; X{ X register int m = (max + flageof + flagblocking) >> 8; X /* skipping eight steps because max >= 128 */ X X outb[outbuf] = 8; X while (m) X outb[outbuf]++, m >>= 1; X X if (flagrandom) X if (ch < (1 << outb[outbuf]) - max - flageof - flagblocking - 1) X if (randombit()) X ch += (max + flageof + flagblocking + 1); X outn[outbuf] = ch; X outbuf++; X if (outbuf == OUTBUFSIZE) X { X for (outbuf = 0;outbuf < OUTBUFSIZE;outbuf++) X { X outword += (outn[outbuf] << outbitpos); X outbitpos += outb[outbuf]; X while (outbitpos > 7) X { X putchar((outword & 255)); X numberout++; X outword >>= 8; X outbitpos -= 8; X } X } X outbuf = 0; X } X} X Xoutfinish() X{ X register int i; X X for (i = 0;i < outbuf;i++) X { X outword += (outn[i] << outbitpos); X outbitpos += outb[i]; X while (outbitpos > 7) X { X putchar((outword & 255)); X numberout++; X outword >>= 8; X outbitpos -= 8; X } X } X if (flagrandom) X { X while (outbitpos < 7) X { X outword += (randombit() << outbitpos); X outbitpos++; /* fill the final byte with random bits */ X } X } X putchar(outword); /* the final byte */ X numberout++; X} X X/* the real stuff */ X Xmain(argc,argv,envp) Xint argc; Xchar *argv[]; Xchar *envp[]; X{ X register int ch; X register int maxnum; X register int maxnode; X register int i; X register int match; X register int matchlen; X register int curhash; X register int dictmatch; X register int dictmatchlen; X register int dictmatchhash; X register int oldmatch; X register int oldmatchhash; X register int result; /* for inchar() */ X X while (*(++argv)) X if (**argv == '-') X while (*(++(*argv))) X switch(**argv) X { X case 'e': flageof = 1; break; X case 'E': flageof = 0; break; X case 'r': flagrandom = 1; break; X case 'R': flagrandom = 0; break; X case 'b': flagblocking = 1; break; X case 'B': flagblocking = 0; break; X case 'v': flagverbose = 1; break; X case 'A': printf(squeezeauthor); exit(0); X case 'C': printf(squeezecopyright); exit(0); X case 'V': printf(squeezeversion); exit(0); X case 'W': printf(squeezewarranty); exit(0); X case 'H': printf(squeezehelp); exit(0); X case 'U': printf(squeezeusage); exit(0); X default: ; X } X else X { X fprintf(stderr,"squeeze: I am a filter, try sqz for squeezing files\n"); X exit(1); X } X X if (flagrandom) X initrandom(); X Xstart_over: X initdictionary(); X maxnum = ALPHABET - 1; X maxnode = ALPHABET; X X if ((ch = inchar()) == EOF) X { X if (flageof) /* can't leave without saying goodbye! */ X outnum(maxnum + 1,maxnum); X outfinish(); X if (flagverbose) X goaheadandbeverbose(); X exit(0); X } X outnum(ch,maxnum); X numberin++; X oldmatch = table[oldmatchhash = morehash(0,ch)]; X X for (;;) X { X match = matchlen = curhash = 0; X dictmatch = dictmatchlen = dictmatchhash = 0; X X for (;;) X { Xtop_of_loop: X if ((ch = inchar()) == EOF) X if (matchlen == 0) X { X if (flageof) /* can't leave without saying goodbye! */ X outnum(maxnum + 1,maxnum); X outfinish(); X if (flagverbose) X goaheadandbeverbose(); X exit(0); X } X else X break; X curhash = morehash(curhash,ch); X for (i = table[curhash];i;i = next[i]) X if (parent[i] == match) X { X match = i; matchlen++; X if (num[i] != -1) X { X dictmatch = match; X dictmatchlen = matchlen; X dictmatchhash = curhash; X } X goto top_of_loop; /* I wish C had real control structures */ X } X /* i is zero; we didn't match on this character. */ X break; /* could stick the reread(1) here */ X } X X numberin += dictmatchlen; X outnum(num[dictmatch],maxnum); X inrepeat((ch != EOF) + matchlen); X /* Reread first dictmatchlen and extend onto laststring. */ X match = oldmatch; X curhash = oldmatchhash; X while (dictmatchlen-- > 0) X { X ch = inchar(); /* can't be EOF---repetition of previous */ X curhash = morehash(curhash,ch); X for (i = table[curhash];i;i = next[i]) X if (parent[i] == match) X { X match = i; X break; X } X if (!i) /* we're out of the tree---zoom on down! */ X { X if (maxnode + dictmatchlen + 1 < DICTSIZE) X { X maxnode++; X parent[maxnode] = match; X next[maxnode] = table[curhash]; X num[maxnode] = -1; X match = maxnode; X table[curhash] = maxnode; X while (dictmatchlen-- > 0) X { X ch = inchar(); /* can't be EOF */ X curhash = morehash(curhash,ch); X maxnode++; X parent[maxnode] = match; X next[maxnode] = table[curhash]; X num[maxnode] = -1; X match = maxnode; X table[curhash] = maxnode; X } X break; X } X else X { X /* oh, dear, we've run out of memory. */ X maxnode = DICTSIZE; X uninrepeat(dictmatchlen); X dictmatchlen = 0; /* is this necessary? */ X if (flagblocking) /* let's start over! */ X { X outnum(maxnum + flageof + 2,maxnum + 1); X cleartable(); X goto start_over; /* I wish C had real control structures */ X } X break; X } X } X } X maxnum++; X if (maxnode < DICTSIZE) X if (num[match] == -1) X num[match] = maxnum; X else /* oops, a conflict */ X if (flagrandom) X if (randombit()) X num[match] = maxnum; X /* The other repeated inchars are saved for the next match. */ X oldmatch = dictmatch; X oldmatchhash = dictmatchhash; X } X} END_OF_FILE if test 11779 -ne `wc -c <'squeeze.c'`; then echo shar: \"'squeeze.c'\" unpacked with wrong size! fi # end of 'squeeze.c' fi if test -f 'unsqueeze.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'unsqueeze.c'\" else echo shar: Extracting \"'unsqueeze.c'\" \(7995 characters\) sed "s/^X//" >'unsqueeze.c' <<'END_OF_FILE' X/* Xunsqeeze.c: Adaptive data decompression with Miller-Wegman method. X*/ X X/* perhaps a memoryfreeze state bit to delay the out-of-memory? */ X/* go from file to file and delete old file... .M? .W? .S? */ X/* alloc() instead of huge array? less obnoxious? */ X/* stick to shorts? */ X/* signals? */ X/* option to compress instead? I think not */ X/* concatenate strings at low levels? not worth it---or is it? */ X Xstatic char unsqueezeauthor[] = X"unsqueeze was written by Daniel J. Bernstein.\n\ XInternet address: brns...@acf10.nyu.edu.\n"; X Xstatic char unsqueezeversion[] = X"unsqueeze version 1.711, October 28, 1989.\n\ XCopyright (c) 1989, Daniel J. Bernstein.\n\ XAll rights reserved.\n"; X Xstatic char unsqueezecopyright[] = X"unsqueeze version 1.711, October 28, 1989.\n\ XCopyright (c) 1989, Daniel J. Bernstein.\n\ XAll rights reserved.\n\ X\n\ XYou are granted the following rights: A. To make copies of this work in\n\ Xoriginal form, so long as (1) the copies are exact and complete; (2) the\n\ Xcopies include the copyright notice, this paragraph, and the disclaimer\n\ Xof warranty in their entirety. B. To distribute this work, or copies made\n\ Xunder the provisions above, so long as (1) this is the original work and\n\ Xnot a derivative form; (2) you do not charge a fee for copying or for\n\ Xdistribution; (3) you ensure that the distributed form includes the\n\ Xcopyright notice, this paragraph, and the disclaimer of warranty in their\n\ Xentirety. These rights are temporary and revocable upon written, oral, or\n\ Xother notice by Daniel J. Bernstein. This copyright notice shall be\n\ Xgoverned by the laws of the state of New York.\n\ X\n\ XIf you have questions about unsqueeze or about this copyright notice,\n\ Xor if you would like additional rights beyond those granted above,\n\ Xplease feel free to contact the author at brns...@acf10.nyu.edu\n\ Xon the Internet.\n"; X Xstatic char unsqueezewarranty[] = X"To the extent permitted by applicable law, Daniel J. Bernstein disclaims\n\ Xall warranties, explicit or implied, including but not limited to the\n\ Ximplied warranties of merchantability and fitness for a particular purpose.\n\ XDaniel J. Bernstein is not and shall not be liable for any damages,\n\ Xincidental or consequential, arising from the use of this program, even\n\ Xif you inform him of the possibility of such damages. This disclaimer\n\ Xshall be governed by the laws of the state of New York.\n\ X\n\ XIn other words, use this program at your own risk.\n\ X\n\ XIf you have questions about unsqueeze or about this disclaimer of warranty,\n\ Xplease feel free to contact the author at brns...@acf10.nyu.edu\n\ Xon the Internet.\n"; X Xstatic char unsqueezeusage[] = X"Usage: unsqueeze [ -eErRbBACHUVW ] [ -dstring ]\n\ XHelp: unsqueeze -H\n"; X Xstatic char unsqueezehelp[] = X"unsqueeze decompresses its input and prints the result. The input is a\n\ Xfile compressed with squeeze, which uses adaptive Miller-Wegman encoding.\n\ X\n\ Xunsqueeze -A: print authorship notice\n\ Xunsqueeze -C: print copyright notice\n\ Xunsqueeze -H: print this notice\n\ Xunsqueeze -U: print short usage summary\n\ Xunsqueeze -V: print version number\n\ Xunsqueeze -W: print disclaimer of warranty\n\ X\n\ Xunsqueeze [ -eErRbBdv ]: decompress\n\ X -e: look for explicit indication of EOF\n\ X -E: don't look for explicit EOF (default)\n\ X -r: accept ``randomized'' input (default)\n\ X -R: do not accept randomized input\n\ X -b: assume input is ``blocked'' (default)\n\ X -B: assume input is not blocked\n\ X -dstring: display string between output bunches, for debugging\n\ X -v: announce decompression results (``verbose'')\n\ X\n\ XIf you have questions about or suggestions for unsqueeze, please feel free\n\ Xto contact the author, Daniel J. Bernstein, at brns...@acf10.nyu.edu\n\ Xon the Internet.\n"; X X#include <stdio.h> X X#define ALPHABET 256 X#define DICTSIZE 2000000 X#define STACKSIZE 50000 X Xint flageof = 0; Xint flagrandom = 1; Xint flagdisplay = 0; Xint flagblocking = 1; Xint flagverbose = 0; X Xint numberin = 0; Xint numberout = 0; X Xint startch; Xint d[DICTSIZE]; /* dictionary in normal form */ X Xint stack[STACKSIZE]; X Xgoaheadandbeverbose() X{ X fprintf(stderr,"In: %d chars Out: %d chars Unsqueezed from: %d%%\n", X numberin,numberout,(100 * numberin + numberout / 2) / numberout); X} X Xoutput(ch) Xregister int ch; X{ X register int stackpos = 1; X X stack[0] = ch; X while (stackpos) X { X ch = stack[--stackpos]; X while (ch >= ALPHABET) X { X stack[stackpos++] = d[ch]; X ch = (ch == ALPHABET ? startch : d[ch - 1]); /* tail recursion */ X } X putchar((char) ch); X numberout++; X } X} X X/* input routines */ X X#define INBUFSIZE 2000 X Xint inbuf[INBUFSIZE]; Xint inbufnum = INBUFSIZE; Xint inbufstart = INBUFSIZE; Xint inword = 0; Xint inwordbits = 0; X Xint inchar(max) Xregister int max; X{ X register int result; X register int inb = 8; X X max = (max + flageof + flagblocking) >> 8; X /* skipping eight steps because max >= 128 */ X X while (max) X inb++, max >>= 1; X X while (inb > inwordbits) X { X if (inbufstart == inbufnum) X { X if (inbufnum == INBUFSIZE) X { X for (inbufnum = 0;inbufnum < INBUFSIZE;inbufnum++) X { X if ((inbuf[inbufnum] = getchar()) == EOF) X break; X else X numberin++; X } X inbufstart = 0; X } X if (inbufstart == inbufnum) /* end of file! */ X return(EOF); X } X inword += inbuf[inbufstart++] << inwordbits; X inwordbits += 8; X } X result = inword % (1 << inb); X inword >>= inb; X inwordbits -= inb; X return(result); X} X Xmain(argc,argv,envp) Xint argc; Xchar *argv[]; Xchar *envp[]; X{ X register int ch; X register int max; X register char *display; X X while (*(++argv)) X if (**argv == '-') X while (*(++(*argv))) X switch(**argv) X { X case 'e': flageof = 1; break; X case 'E': flageof = 0; break; X case 'r': flagrandom = 1; break; X case 'R': flagrandom = 0; break; X case 'b': flagblocking = 1; break; X case 'B': flagblocking = 0; break; X case 'd': flagdisplay = 1; display = *argv + 1; X while (*(++(*argv))) /* null */ ; X --(*argv); break; /* we want breakbreak here */ X case 'v': flagverbose = 1; break; X case 'A': printf(unsqueezeauthor); exit(0); X case 'C': printf(unsqueezecopyright); exit(0); X case 'V': printf(unsqueezeversion); exit(0); X case 'W': printf(unsqueezewarranty); exit(0); X case 'H': printf(unsqueezehelp); exit(0); X case 'U': printf(unsqueezeusage); exit(0); X default: ; X } X else X { X fprintf(stderr, X "unsqueeze: I am a filter, try unsqz for unsqueezing files\n"); X exit(1); X } X Xstart_over: X max = ALPHABET - 1; /* last spot in dictionary */ X X if ((ch = inchar(max)) != EOF) X { X if (ch > max + flageof + flagblocking) X if (flagrandom) X ch = ch % (max + flageof + flagblocking + 1); X else X { X fprintf(stderr,"unsqueeze: bad (randomized?) input\n"); X exit(1); X } X if (flageof && (ch == max + 1)) /* EOF signalled! */ X goto eof_signalled; X if (flagblocking && (ch == max + flageof + 1)) X goto start_over; X startch = ch; X output(ch); X if (flagdisplay) X printf(display); X while ((ch = inchar(max)) != EOF) X { X if (max >= DICTSIZE) X { X fprintf(stderr,"unsqueeze: not enough memory\n"); X exit(1); X } X if (ch > max + flageof + flagblocking) X if (flagrandom) X ch = ch % (max + flageof + flagblocking + 1); X else X { X fprintf(stderr,"unsqueeze: bad (randomized?) input\n"); X exit(1); X } X if (flageof && (ch == max + 1)) /* EOF signalled! */ X goto eof_signalled; X if (flagblocking && (ch == max + flageof + 1)) X goto start_over; X d[++max] = ch; X output(ch); X if (flagdisplay) X printf(display); X } X } X if (flageof) /* EOF not signalled? */ X { X fprintf(stderr,"unsqueeze: EOF not signalled?\n"); X if (flagverbose) X goaheadandbeverbose(); X exit(1); X } Xeof_signalled: X if (flagverbose) X goaheadandbeverbose(); X exit(0); X} END_OF_FILE if test 7995 -ne `wc -c <'unsqueeze.c'`; then echo shar: \"'unsqueeze.c'\" unpacked with wrong size! fi # end of 'unsqueeze.c' fi if test -f 'sqz' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sqz'\" else echo shar: Extracting \"'sqz'\" \(405 characters\) sed "s/^X//" >'sqz' <<'END_OF_FILE' X#!/bin/sh XOPTIONS= XFILES= XFILTERFILEEXT=MW; export FILTERFILEEXT Xfor ARG Xdo X case "$ARG" in X -*) OPTIONS="$OPTIONS $ARG";; X *) ARG="`expr $ARG : '\(.*\)\.MW' '|' $ARG`" X FILES="$FILES $ARG";; X esac Xdone Xif test -z "$FILES" Xthen X echo 'sqz: fatal: must specify filenames; use squeeze for a filter' 1>&2 X exit 1 Xfi Xset $FILES Xfor ARG Xdo X filterfile -dpt "$ARG" squeeze $OPTIONS Xdone Xexit 0 END_OF_FILE if test 405 -ne `wc -c <'sqz'`; then echo shar: \"'sqz'\" unpacked with wrong size! fi chmod +x 'sqz' # end of 'sqz' fi if test -f 'sqzdir' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sqzdir'\" else echo shar: Extracting \"'sqzdir'\" \(381 characters\) sed "s/^X//" >'sqzdir' <<'END_OF_FILE' X#!/bin/sh XOPTIONS= XFILES= XFILTERFILEEXT=MW; export FILTERFILEEXT Xfor ARG Xdo X case "$ARG" in X -*) OPTIONS="$OPTIONS $ARG";; X *) FILES="$FILES $ARG";; X esac Xdone Xif test -z "$FILES" Xthen X FILES=. Xfi Xset $FILES Xfind $@ -type f -links 1 \! \( -name '*.MW' -o -name '.*.MW' \) -exec filterfile -dpt {} squeeze $OPTIONS \; X# stupid find, thinks * doesn't match dot files Xexit 0 END_OF_FILE if test 381 -ne `wc -c <'sqzdir'`; then echo shar: \"'sqzdir'\" unpacked with wrong size! fi chmod +x 'sqzdir' # end of 'sqzdir' fi if test -f 'unsqz' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'unsqz'\" else echo shar: Extracting \"'unsqz'\" \(415 characters\) sed "s/^X//" >'unsqz' <<'END_OF_FILE' X#!/bin/sh XOPTIONS= XFILES= XFILTERFILEEXT=.MW; export FILTERFILEEXT Xfor ARG Xdo X case "$ARG" in X -*) OPTIONS="$OPTIONS $ARG";; X *) ARG="`expr $ARG : '\(.*\.MW\)' '|' $ARG.MW`" X FILES="$FILES $ARG";; X esac Xdone Xif test -z "$FILES" Xthen X echo 'unsqz: fatal: must specify filenames; use unsqueeze for a filter' 1>&2 X exit 1 Xfi Xset $FILES Xfor ARG Xdo X filterfile -dpt "$ARG" unsqueeze $OPTIONS Xdone Xexit 0 END_OF_FILE if test 415 -ne `wc -c <'unsqz'`; then echo shar: \"'unsqz'\" unpacked with wrong size! fi chmod +x 'unsqz' # end of 'unsqz' fi if test -f 'unsqzdir' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'unsqzdir'\" else echo shar: Extracting \"'unsqzdir'\" \(381 characters\) sed "s/^X//" >'unsqzdir' <<'END_OF_FILE' X#!/bin/sh XOPTIONS= XFILES= XFILTERFILEEXT=.MW; export FILTERFILEEXT Xfor ARG Xdo X case "$ARG" in X -*) OPTIONS="$OPTIONS $ARG";; X *) FILES="$FILES $ARG";; X esac Xdone Xif test -z "$FILES" Xthen X FILES=. Xfi Xset $FILES Xfind $@ -type f -links 1 \( -name '*.MW' -o -name '.*.MW' \) -exec filterfile -dpt {} unsqueeze $OPTIONS \; X# stupid find, thinks * doesn't match dot files Xexit 0 END_OF_FILE if test 381 -ne `wc -c <'unsqzdir'`; then echo shar: \"'unsqzdir'\" unpacked with wrong size! fi chmod +x 'unsqzdir' # end of 'unsqzdir' fi if test -f 'mwcat' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mwcat'\" else echo shar: Extracting \"'mwcat'\" \(361 characters\) sed "s/^X//" >'mwcat' <<'END_OF_FILE' X#!/bin/sh XOPTIONS= XFILES= Xfor ARG Xdo X case "$ARG" in X -*) OPTIONS="$OPTIONS $ARG";; X *) ARG="`expr $ARG : '\(.*\.MW\)' '|' $ARG.MW`" X FILES="$FILES $ARG";; X esac Xdone Xif test -z "$FILES" Xthen X echo 'mwcat: fatal: must specify filenames; use unsqueeze for a filter' 1>&2 X exit 1 Xfi Xset $FILES Xfor ARG Xdo X unsqueeze $OPTIONS < "$ARG" Xdone Xexit 0 END_OF_FILE if test 361 -ne `wc -c <'mwcat'`; then echo shar: \"'mwcat'\" unpacked with wrong size! fi chmod +x 'mwcat' # end of 'mwcat' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(619 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' XCCOPTS=-O XNROFFOPTS=-man X Xdefault: all X Xall: squeeze unsqueeze squeeze.1 unsqueeze.1 sqz.1 sqzdir.1 mwcat.1 X Xsqueeze: squeeze.c Makefile X cc $(CCOPTS) -o squeeze squeeze.c X Xunsqueeze: unsqueeze.c Makefile X cc $(CCOPTS) -o unsqueeze unsqueeze.c X Xsqueeze.1: squeeze.man Makefile X nroff $(NROFFOPTS) < squeeze.man > squeeze.1 X Xunsqueeze.1: unsqueeze.man Makefile X nroff $(NROFFOPTS) < unsqueeze.man > unsqueeze.1 X Xsqz.1: sqz.man Makefile X nroff $(NROFFOPTS) < sqz.man > sqz.1 X Xsqzdir.1: sqzdir.man Makefile X nroff $(NROFFOPTS) < sqzdir.man > sqzdir.1 X Xmwcat.1: mwcat.man Makefile X nroff $(NROFFOPTS) < mwcat.man > mwcat.1 END_OF_FILE if test 619 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi echo shar: End of shell archive. exit 0