Ticket #13914: 0001-bin-compress-Fix-minor-issues-with-compress.c.patch

File 0001-bin-compress-Fix-minor-issues-with-compress.c.patch, 68.3 KB (added by ohnx56, 6 years ago)
  • deleted file src/bin/compress/Jamfile

    From 0009d23ec61e22541f496502f6d80c17c3110bd0 Mon Sep 17 00:00:00 2001
    From: ohnx <me@masonx.ca>
    Date: Fri, 29 Dec 2017 20:25:16 +0000
    Subject: [PATCH] bin/compress: Fix minor issues with compress.c
    
    Per #10267, "Most (ported) third-party software should be removed
    from the Haiku source repository."
    
    Since HaikuPorts already has the ncompress package, this file
    should no longer exist.
    ---
     src/bin/compress/Jamfile    |    7 -
     src/bin/compress/README     |  283 -------
     src/bin/compress/compress.1 |  264 -------
     src/bin/compress/compress.c | 1781 -------------------------------------------
     src/bin/compress/usermem.sh |   83 --
     5 files changed, 2418 deletions(-)
     delete mode 100644 src/bin/compress/Jamfile
     delete mode 100644 src/bin/compress/README
     delete mode 100644 src/bin/compress/compress.1
     delete mode 100644 src/bin/compress/compress.c
     delete mode 100644 src/bin/compress/usermem.sh
    
    diff --git a/src/bin/compress/Jamfile b/src/bin/compress/Jamfile
    deleted file mode 100644
    index a4189fd6a3..0000000000
    + -  
    1 SubDir HAIKU_TOP src bin compress ;
    2 
    3 SubDirCcFlags -DSACREDMEM=256000 -D_FPOS_T -DUSERMEM=2097152 -DBEOS=1 -w ;
    4 
    5 BinCommand compress :
    6     compress.c
    7     ;
  • deleted file src/bin/compress/README

    diff --git a/src/bin/compress/README b/src/bin/compress/README
    deleted file mode 100644
    index 4eb44d1882..0000000000
    + -  
    1 
    2     @(#)README 1.1 86/09/25 SMI; from UCB 5.3 85/09/17
    3 
    4 Compress version 4.0 improvements over 3.0:
    5     o compress() speedup (10-50%) by changing division hash to xor
    6     o decompress() speedup (5-10%)
    7     o Memory requirements reduced (3-30%)
    8     o Stack requirements reduced to less than 4kb
    9     o Removed 'Big+Fast' compress code (FBITS) because of compress speedup
    10         o Portability mods for Z8000 and PC/XT (but not zeus 3.2)
    11     o Default to 'quiet' mode
    12     o Unification of 'force' flags
    13     o Manual page overhaul
    14     o Portability enhancement for M_XENIX
    15     o Removed text on #else and #endif
    16     o Added "-V" switch to print version and options
    17     o Added #defines for SIGNED_COMPARE_SLOW
    18     o Added Makefile and "usermem" program
    19     o Removed all floating point computations
    20     o New programs: [deleted]
    21 
    22 The "usermem" script attempts to determine the maximum process size.  Some
    23 editing of the script may be necessary (see the comments).  [It should work
    24 fine on 4.3 bsd.] If you can't get it to work at all, just create file
    25 "USERMEM" containing the maximum process size in decimal.
    26 
    27 The following preprocessor symbols control the compilation of "compress.c":
    28 
    29     o USERMEM       Maximum process memory on the system
    30     o SACREDMEM     Amount to reserve for other proceses
    31     o SIGNED_COMPARE_SLOW   Unsigned compare instructions are faster
    32     o NO_UCHAR      Don't use "unsigned char" types
    33     o BITS          Overrules default set by USERMEM-SACREDMEM
    34     o vax           Generate inline assembler
    35     o interdata     Defines SIGNED_COMPARE_SLOW
    36     o M_XENIX       Makes arrays < 65536 bytes each
    37     o pdp11         BITS=12, NO_UCHAR
    38     o z8000         BITS=12
    39     o pcxt          BITS=12
    40     o BSD4_2        Allow long filenames ( > 14 characters) &
    41                 Call setlinebuf(stderr)
    42 
    43 The difference "usermem-sacredmem" determines the maximum BITS that can be
    44 specified with the "-b" flag.
    45 
    46 memory: at least        BITS
    47 ------  -- -----                ----
    48      433,484             16
    49      229,600             15
    50      127,536             14
    51       73,464             13
    52            0             12
    53 
    54 The default is BITS=16.
    55 
    56 The maximum bits can be overrulled by specifying "-DBITS=bits" at
    57 compilation time.
    58 
    59 WARNING: files compressed on a large machine with more bits than allowed by
    60 a version of compress on a smaller machine cannot be decompressed!  Use the
    61 "-b12" flag to generate a file on a large machine that can be uncompressed
    62 on a 16-bit machine.
    63 
    64 The output of compress 4.0 is fully compatible with that of compress 3.0.
    65 In other words, the output of compress 4.0 may be fed into uncompress 3.0 or
    66 the output of compress 3.0 may be fed into uncompress 4.0.
    67 
    68 The output of compress 4.0 not compatible with that of
    69 compress 2.0.  However, compress 4.0 still accepts the output of
    70 compress 2.0.  To generate output that is compatible with compress
    71 2.0, use the undocumented "-C" flag.
    72 
    73     -from mod.sources, submitted by vax135!petsd!joe (Joe Orost), 8/1/85
    74 --------------------------------
    75 
    76 Enclosed is compress version 3.0 with the following changes:
    77 
    78 1.  "Block" compression is performed.  After the BITS run out, the
    79     compression ratio is checked every so often.  If it is decreasing,
    80     the table is cleared and a new set of substrings are generated.
    81 
    82     This makes the output of compress 3.0 not compatible with that of
    83     compress 2.0.  However, compress 3.0 still accepts the output of
    84     compress 2.0.  To generate output that is compatible with compress
    85     2.0, use the undocumented "-C" flag.
    86 
    87 2.  A quiet "-q" flag has been added for use by the news system.
    88 
    89 3.  The character chaining has been deleted and the program now uses
    90     hashing.  This improves the speed of the program, especially
    91     during decompression.  Other speed improvements have been made,
    92     such as using putc() instead of fwrite().
    93 
    94 4.  A large table is used on large machines when a relatively small
    95     number of bits is specified.  This saves much time when compressing
    96     for a 16-bit machine on a 32-bit virtual machine.  Note that the
    97     speed improvement only occurs when the input file is > 30000
    98     characters, and the -b BITS is less than or equal to the cutoff
    99     described below.
    100 
    101 Most of these changes were made by James A. Woods (ames!jaw).  Thank you
    102 James!
    103 
    104 To compile compress:
    105 
    106     cc -O -DUSERMEM=usermem -o compress compress.c
    107 
    108 Where "usermem" is the amount of physical user memory available (in bytes). 
    109 If any physical memory is to be reserved for other processes, put in
    110 "-DSACREDMEM sacredmem", where "sacredmem" is the amount to be reserved.
    111 
    112 The difference "usermem-sacredmem" determines the maximum BITS that can be
    113 specified, and the cutoff bits where the large+fast table is used.
    114 
    115 memory: at least        BITS        cutoff
    116 ------  -- -----                ----            ------
    117    4,718,592             16       13
    118    2,621,440             16       12
    119    1,572,864             16       11
    120    1,048,576             16       10
    121      631,808             16               --
    122      329,728             15               --
    123      178,176             14       --
    124       99,328             13       --
    125            0             12       --
    126 
    127 The default memory size is 750,000 which gives a maximum BITS=16 and no
    128 large+fast table.
    129 
    130 The maximum bits can be overruled by specifying "-DBITS=bits" at
    131 compilation time.
    132 
    133 If your machine doesn't support unsigned characters, define "NO_UCHAR"
    134 when compiling.
    135 
    136 If your machine has "int" as 16-bits, define "SHORT_INT" when compiling.
    137 
    138 After compilation, move "compress" to a standard executable location, such
    139 as /usr/local.  Then:
    140     cd /usr/local
    141     ln compress uncompress
    142     ln compress zcat
    143 
    144 On machines that have a fixed stack size (such as Perkin-Elmer), set the
    145 stack to at least 12kb.  ("setstack compress 12" on Perkin-Elmer).
    146 
    147 Next, install the manual (compress.l).
    148     cp compress.l /usr/man/manl
    149     cd /usr/man/manl
    150     ln compress.l uncompress.l
    151     ln compress.l zcat.l
    152 
    153         - or -
    154 
    155     cp compress.l /usr/man/man1/compress.1
    156     cd /usr/man/man1
    157     ln compress.1 uncompress.1
    158     ln compress.1 zcat.1
    159 
    160                     regards,
    161                     petsd!joe
    162 
    163 Here is a note from the net:
    164 
    165 >From hplabs!pesnta!amd!turtlevax!ken Sat Jan  5 03:35:20 1985
    166 Path: ames!hplabs!pesnta!amd!turtlevax!ken
    167 From: ken@turtlevax.UUCP (Ken Turkowski)
    168 Newsgroups: net.sources
    169 Subject: Re: Compress release 3.0 : sample Makefile
    170 Organization: CADLINC, Inc. @ Menlo Park, CA
    171 
    172 In the compress 3.0 source recently posted to mod.sources, there is a
    173 #define variable which can be set for optimum performance on a machine
    174 with a large amount of memory.  A program (usermem) to calculate the
    175 useable amount of physical user memory is enclosed, as well as a sample
    176 4.2bsd Vax Makefile for compress.
    177 
    178 Here is the README file from the previous version of compress (2.0):
    179 
    180 >Enclosed is compress.c version 2.0 with the following bugs fixed:
    181 >
    182 >1. The packed files produced by compress are different on different
    183 >   machines and dependent on the vax sysgen option.
    184 >       The bug was in the different byte/bit ordering on the
    185 >       various machines.  This has been fixed.
    186 >
    187 >       This version is NOT compatible with the original vax posting
    188 >       unless the '-DCOMPATIBLE' option is specified to the C
    189 >       compiler.  The original posting has a bug which I fixed,
    190 >       causing incompatible files.  I recommend you NOT to use this
    191 >       option unless you already have a lot of packed files from
    192 >       the original posting by thomas.
    193 >2. The exit status is not well defined (on some machines) causing the
    194 >   scripts to fail.
    195 >       The exit status is now 0,1 or 2 and is documented in
    196 >       compress.l.
    197 >3. The function getopt() is not available in all C libraries.
    198 >       The function getopt() is no longer referenced by the
    199 >       program.
    200 >4. Error status is not being checked on the fwrite() and fflush() calls.
    201 >       Fixed.
    202 >
    203 >The following enhancements have been made:
    204 >
    205 >1. Added facilities of "compact" into the compress program.  "Pack",
    206 >   "Unpack", and "Pcat" are no longer required (no longer supplied).
    207 >2. Installed work around for C compiler bug with "-O".
    208 >3. Added a magic number header (\037\235).  Put the bits specified
    209 >   in the file.
    210 >4. Added "-f" flag to force overwrite of output file.
    211 >5. Added "-c" flag and "zcat" program.  'ln compress zcat' after you
    212 >   compile.
    213 >6. The 'uncompress' script has been deleted; simply
    214 >   'ln compress uncompress' after you compile and it will work.
    215 >7. Removed extra bit masking for machines that support unsigned
    216 >   characters.  If your machine doesn't support unsigned characters,
    217 >   define "NO_UCHAR" when compiling.
    218 >
    219 >Compile "compress.c" with "-O -o compress" flags.  Move "compress" to a
    220 >standard executable location, such as /usr/local.  Then:
    221 >   cd /usr/local
    222 >   ln compress uncompress
    223 >   ln compress zcat
    224 >
    225 >On machines that have a fixed stack size (such as Perkin-Elmer), set the
    226 >stack to at least 12kb.  ("setstack compress 12" on Perkin-Elmer).
    227 >
    228 >Next, install the manual (compress.l).
    229 >   cp compress.l /usr/man/manl     - or -
    230 >   cp compress.l /usr/man/man1/compress.1
    231 >
    232 >Here is the README that I sent with my first posting:
    233 >
    234 >>Enclosed is a modified version of compress.c, along with scripts to make it
    235 >>run identically to pack(1), unpack(1), an pcat(1).  Here is what I
    236 >>(petsd!joe) and a colleague (petsd!peora!srd) did:
    237 >>
    238 >>1. Removed VAX dependencies.
    239 >>2. Changed the struct to separate arrays; saves mucho memory.
    240 >>3. Did comparisons in unsigned, where possible.  (Faster on Perkin-Elmer.)
    241 >>4. Sorted the character next chain and changed the search to stop
    242 >>prematurely.  This saves a lot on the execution time when compressing.
    243 >>
    244 >>This version is totally compatible with the original version.  Even though
    245 >>lint(1) -p has no complaints about compress.c, it won't run on a 16-bit
    246 >>machine, due to the size of the arrays.
    247 >>
    248 >>Here is the README file from the original author:
    249 >>
    250 >>>Well, with all this discussion about file compression (for news batching
    251 >>>in particular) going around, I decided to implement the text compression
    252 >>>algorithm described in the June Computer magazine.  The author claimed
    253 >>>blinding speed and good compression ratios.  It's certainly faster than
    254 >>>compact (but, then, what wouldn't be), but it's also the same speed as
    255 >>>pack, and gets better compression than both of them.  On 350K bytes of
    256 >>>unix-wizards, compact took about 8 minutes of CPU, pack took about 80
    257 >>>seconds, and compress (herein) also took 80 seconds.  But, compact and
    258 >>>pack got about 30% compression, whereas compress got over 50%.  So, I
    259 >>>decided I had something, and that others might be interested, too.
    260 >>>
    261 >>>As is probably true of compact and pack (although I haven't checked),
    262 >>>the byte order within a word is probably relevant here, but as long as
    263 >>>you stay on a single machine type, you should be ok.  (Can anybody
    264 >>>elucidate on this?)  There are a couple of asm's in the code (extv and
    265 >>>insv instructions), so anyone porting it to another machine will have to
    266 >>>deal with this anyway (and could probably make it compatible with Vax
    267 >>>byte order at the same time).  Anyway, I've linted the code (both with
    268 >>>and without -p), so it should run elsewhere.  Note the longs in the
    269 >>>code, you can take these out if you reduce BITS to <= 15.
    270 >>>
    271 >>>Have fun, and as always, if you make good enhancements, or bug fixes,
    272 >>>I'd like to see them.
    273 >>>
    274 >>>=Spencer (thomas@utah-20, {harpo,hplabs,arizona}!utah-cs!thomas)
    275 >>
    276 >>                  regards,
    277 >>                  joe
    278 >>
    279 >>--
    280 >>Full-Name:  Joseph M. Orost
    281 >>UUCP:       ..!{decvax,ucbvax,ihnp4}!vax135!petsd!joe
    282 >>US Mail:    MS 313; Perkin-Elmer; 106 Apple St; Tinton Falls, NJ 07724
    283 >>Phone:      (201) 870-5844
  • deleted file src/bin/compress/compress.1

    diff --git a/src/bin/compress/compress.1 b/src/bin/compress/compress.1
    deleted file mode 100644
    index 335eedd4da..0000000000
    + -  
    1 .PU
    2 .TH COMPRESS 1 local
    3 .SH NAME
    4 compress, uncompress, zcat  \-  compress and uncompress files
    5 .SH SYNOPSIS
    6 .ll +8
    7 .B compress
    8 [
    9 .B \-c
    10 ] [
    11 .B \-C
    12 ] [
    13 .B \-d
    14 ] [
    15 .B \-f
    16 ] [
    17 .B \-v
    18 ] [
    19 .B \-b
    20 .I bits
    21 ] [
    22 .I "filename \&..."
    23 ]
    24 .ll -8
    25 .br
    26 .B uncompress
    27 [
    28 .B \-c
    29 ] [
    30 .B \-f
    31 ] [
    32 .B \-v
    33 ] [
    34 .B \-V
    35 ] [
    36 .I "filename \&..."
    37 ]
    38 .br
    39 .B zcat
    40 [
    41 .I "filename \&..."
    42 ]
    43 .SH DESCRIPTION
    44 Compresses the specified files or standard input.
    45 Each file is replaced by a file with the extension
    46 .B "\&.Z,"
    47 but only if the file got smaller.
    48 If no files are specified,
    49 the compression is applied to the standard input
    50 and is written to standard output
    51 regardless of the results.
    52 Compressed files can be restored
    53 to their original form by specifying the
    54 .B \-d
    55 option, or by running
    56 .I uncompress
    57 (linked to
    58 .IR compress ),
    59 on the
    60 .B "\&.Z"
    61 files or the standard input.
    62 .PP
    63 If the output file exists, it will not be overwritten unless the
    64 .B \-f
    65 flag is given.  If
    66 .B \-f
    67 is not specified and
    68 .I compress
    69 is run in the foreground,
    70 the user is prompted
    71 as to whether the file should be overwritten.
    72 .PP
    73 If the
    74 .B \-f
    75 flag is given, all files specified are replaced with
    76 .B "\&.Z"
    77 files \- even if the file didn't get smaller.
    78 .PP
    79 When file names are given, the ownership (if run by root), modes, accessed
    80 and modified times are maintained between the file and its
    81 .B "\&.Z"
    82 version.  In this respect,
    83 .I compress
    84 can be used for archival purposes, yet can still be used with
    85 .IR make "(1)"
    86 after uncompression.
    87 .PP
    88 The
    89 .B \-c
    90 option causes the results of the compress/uncompress operation to be written
    91 to stdout; no files are changed.  The
    92 .I zcat
    93 program is the same as specifying
    94 .B \-c
    95 to
    96 .I uncompress
    97 (all files are unpacked and written to stdout).
    98 .PP
    99 .I Compress
    100 uses the modified Lempel-Ziv algorithm described in
    101 "A Technique for High Performance Data Compression",
    102 Terry A. Welch,
    103 .I "IEEE Computer"
    104 Vol 17, No 6 (June 1984), pp 8-19.
    105 Common substrings in the file are first replaced by 9-bit codes 257 and up.
    106 When code 512 is reached, the algorithm switches to 10-bit codes and
    107 continues to use more bits until the
    108 .I bits
    109 limit as specified by the
    110 .B \-b
    111 flag is reached (default 16).
    112 .I Bits
    113 must be between 9 and 16.  The default can be changed in the source to allow
    114 .I compress
    115 to be run on a smaller machine.
    116 .PP
    117 After the
    118 .I bits
    119 limit is reached,
    120 .I compress
    121 periodically checks the compression ratio.  If it is increasing,
    122 .I compress
    123 continues to use the codes that were previously found in the file.  However,
    124 if the compression ratio decreases,
    125 .I compress
    126 discards the table of substrings and rebuilds it from scratch.  This allows
    127 the algorithm to adapt to the next "block" of the file.  The
    128 .B \-C
    129 (compatibility) flag prevents subdivision of the file into blocks;
    130 this produces an output file that old versions of
    131 .I compress
    132 can read.
    133 .PP
    134 A two byte magic number is prepended to the file
    135 to ensure that neither uncompression of random text nor recompression of
    136 compressed text are attempted.  In addition, the
    137 .I bits
    138 specified during
    139 .I compress
    140 is written to the file so that the
    141 .B \-b
    142 flag can be omitted for
    143 .IR uncompress \.
    144 .PP
    145 .ne 8
    146 The amount of compression obtained depends on the size of the
    147 input file, the amount of
    148 .I bits
    149 per code, and the distribution of character substrings.
    150 Typically, text files, such as C programs,
    151 are reduced by 50\-60%.
    152 Compression is generally much better than that achieved by
    153 Huffman coding (as used in
    154 .IR pack ),
    155 or adaptive Huffman coding
    156 .RI ( compact ),
    157 and takes less time to compute.
    158 .PP
    159 .PP
    160 If the
    161 .B \-v
    162 (verbose) flag is given, then
    163 after each file is compressed, a message is printed giving the percentage of
    164 the input file that has been saved by compression.
    165 .PP
    166 If the
    167 .B \-V
    168 (version) flag is given, the program's version number is printed.
    169 .PP
    170 The exit status is normally 0;
    171 if the last file gets bigger after compression, the exit status is 2;
    172 if an error occurs, the exit status is 1.
    173 .SH "SEE ALSO"
    174 compact(1), pack(1)
    175 .SH "DIAGNOSTICS"
    176 Usage: compress [-cCdfvV] [-b maxbits] [file ...]
    177 .in +8
    178 Invalid options were specified on the command line.
    179 .in -8
    180 Missing maxbits
    181 .in +8
    182 Maxbits must follow
    183 .BR \-b \.
    184 .in -8
    185 Unknown flag:
    186 .I "\'x\';"
    187 .in +8
    188 Invalid flags were specified on the command line.
    189 .in -8
    190 .IR file :
    191 not in compressed format
    192 .in +8
    193 The specified file has not been compressed.
    194 .in -8
    195 .IR file :
    196 compressed with
    197 .I xx
    198 bits, can only handle
    199 .I yy
    200 bits
    201 .in +8
    202 The specified file was compressed by a compress program that could handle
    203 more
    204 .I bits
    205 than the current compress program.  Recompress the file with a smaller
    206 .IR bits \.
    207 .in -8
    208 .IR file :
    209 already has .Z suffix -- no change
    210 .in +8
    211 Cannot compress a file that has a ".Z" suffix.
    212 .IR mv "(1)"
    213 the file to a different name and try again.
    214 .in -8
    215 .IR file :
    216 filename too long to tack on .Z
    217 .in +8
    218 The specified file cannot be compressed because its filename is longer than
    219 12 characters.
    220 .IR mv "(1)"
    221 the file to a different name and try again.  This message does not occur on
    222 4.2BSD systems.
    223 .in -8
    224 .I file
    225 already exists; do you wish to overwrite (y or n)?
    226 .in +8
    227 Respond "y" if you want the output file to be replaced; "n" if you want it
    228 to be left alone.
    229 .in -8
    230 .IR file :
    231 .in +8
    232 This message fragment is written during the processing of a file.
    233 .in -8
    234 Compression:
    235 .I "xx.xx%"
    236 .in +8
    237 This message fragment gives the percentage of the input file that has been
    238 saved by compression.
    239 .in -8
    240 -- not a regular file: unchanged
    241 .in +8
    242 This message fragment is written when the input file is not a regular file.
    243 The input file is left unchanged.
    244 .in -8
    245 -- has
    246 .I xx
    247 other links: unchanged
    248 .in +8
    249 This message fragment is written when the input file has links.  The input
    250 file is left unchanged.  See
    251 .IR ln "(1)"
    252 for more information.
    253 .in -8
    254 -- file unchanged
    255 .in +8
    256 This message fragment is written when no savings are achieved by
    257 compression.  The input file is left unchanged.
    258 .in -8
    259 -- replaced with
    260 .I file
    261 .in +8
    262 This message fragment is written when a file has been sucessfully
    263 compressed/uncompressed.
    264 .in -8
  • deleted file src/bin/compress/compress.c

    diff --git a/src/bin/compress/compress.c b/src/bin/compress/compress.c
    deleted file mode 100644
    index b68283cc11..0000000000
    + -  
    1 /*
    2  * Compress - data compression program
    3  */
    4 
    5 /*
    6  * machine variants which require cc -Dmachine:  pdp11, z8000, pcxt
    7  */
    8 
    9 /*
    10  * Set USERMEM to the maximum amount of physical user memory available
    11  * in bytes.  USERMEM is used to determine the maximum BITS that can be used
    12  * for compression.
    13  *
    14  * SACREDMEM is the amount of physical memory saved for others; compress
    15  * will hog the rest.
    16  */
    17 #ifndef SACREDMEM
    18 #define SACREDMEM   0
    19 #endif
    20 
    21 #ifndef USERMEM
    22 # define USERMEM    450000  /* default user memory */
    23 #endif
    24 
    25 #ifdef interdata        /* (Perkin-Elmer) */
    26 #define SIGNED_COMPARE_SLOW /* signed compare is slower than unsigned */
    27 #endif
    28 
    29 #ifdef pdp11
    30 # define BITS   12  /* max bits/code for 16-bit machine */
    31 # define NO_UCHAR   /* also if "unsigned char" functions as signed char */
    32 # undef USERMEM
    33 #endif /* pdp11 */  /* don't forget to compile with -i */
    34 
    35 #ifdef z8000
    36 # define BITS   12
    37 # undef vax     /* weird preprocessor */
    38 # undef USERMEM
    39 #endif /* z8000 */
    40 
    41 #ifdef MSDOS        /* Microsoft C 3.0 for MS-DOS */
    42 # undef USERMEM
    43 # ifdef BIG     /* then this is a large data compilation */
    44 #  undef DEBUG      /*  DEBUG makes the executible too big */
    45 #  define BITS   16
    46 #  define XENIX_16
    47 # else          /* this is a small model compilation */
    48 #  define BITS   12
    49 # endif
    50 #else
    51 #undef BIG
    52 #endif /* MSDOS */
    53 
    54 #ifdef pcxt
    55 # define BITS   12
    56 # undef USERMEM
    57 #endif /* pcxt */
    58 
    59 #ifdef USERMEM
    60 # if USERMEM >= (433484+SACREDMEM)
    61 #  define PBITS 16
    62 # else
    63 #  if USERMEM >= (229600+SACREDMEM)
    64 #   define PBITS    15
    65 #  else
    66 #   if USERMEM >= (127536+SACREDMEM)
    67 #    define PBITS   14
    68 #   else
    69 #    if USERMEM >= (73464+SACREDMEM)
    70 #     define PBITS  13
    71 #    else
    72 #     define PBITS  12
    73 #    endif
    74 #   endif
    75 #  endif
    76 # endif
    77 # undef USERMEM
    78 #endif /* USERMEM */
    79 
    80 #ifdef PBITS        /* Preferred BITS for this memory size */
    81 # ifndef BITS
    82 #  define BITS PBITS
    83 # endif BITS
    84 #endif /* PBITS */
    85 
    86 #if BITS == 16
    87 # define HSIZE  69001       /* 95% occupancy */
    88 #endif
    89 #if BITS == 15
    90 # define HSIZE  35023       /* 94% occupancy */
    91 #endif
    92 #if BITS == 14
    93 # define HSIZE  18013       /* 91% occupancy */
    94 #endif
    95 #if BITS == 13
    96 # define HSIZE  9001        /* 91% occupancy */
    97 #endif
    98 #if BITS <= 12
    99 # define HSIZE  5003        /* 80% occupancy */
    100 #endif
    101 
    102 #ifdef M_XENIX          /* Stupid compiler can't handle arrays with */
    103 # if BITS == 16         /* more than 65535 bytes - so we fake it */
    104 #  define XENIX_16
    105 # else
    106 #  if BITS > 13         /* Code only handles BITS = 12, 13, or 16 */
    107 #   define BITS 13
    108 #  endif
    109 # endif
    110 #endif
    111 
    112 /*
    113  * a code_int must be able to hold 2**BITS values of type int, and also -1
    114  */
    115 #if BITS > 15
    116 typedef long int    code_int;
    117 #else
    118 typedef int     code_int;
    119 #endif
    120 
    121 #ifdef SIGNED_COMPARE_SLOW
    122 typedef unsigned long int count_int;
    123 typedef unsigned short int count_short;
    124 #else
    125 typedef long int      count_int;
    126 #endif
    127 
    128 #ifdef NO_UCHAR
    129  typedef char   char_type;
    130 #else
    131  typedef    unsigned char   char_type;
    132 #endif /* UCHAR */
    133 char_type magic_header[] = { "\037\235" };  /* 1F 9D */
    134 
    135 /* Defines for third byte of header */
    136 #define BIT_MASK    0x1f
    137 #define BLOCK_MASK  0x80
    138 /* Masks 0x40 and 0x20 are free.  I think 0x20 should mean that there is
    139    a fourth header byte (for expansion).
    140 */
    141 #define INIT_BITS 9         /* initial number of bits/code */
    142 
    143 #define min(a, b)   ((a) > (b) ? (b) : (a))
    144 
    145 /*
    146  * compress.c - File compression ala IEEE Computer, June 1984.
    147  *
    148  * Authors: Spencer W. Thomas   (decvax!harpo!utah-cs!utah-gr!thomas)
    149  *      Jim McKie       (decvax!mcvax!jim)
    150  *      Steve Davies        (decvax!vax135!petsd!peora!srd)
    151  *      Ken Turkowski       (decvax!decwrl!turtlevax!ken)
    152  *      James A. Woods      (decvax!ihnp4!ames!jaw)
    153  *      Joe Orost       (decvax!vax135!petsd!joe)
    154  *
    155  * $Header: /tmp/bonefish/open-beos/current/src/apps/bin/compress/compress.c,v 1.1 2004/06/07 21:23:09 korli Exp $
    156  * $Log: compress.c,v $
    157  * Revision 1.1  2004/06/07 21:23:09  korli
    158  * Added compress-4.0
    159  *
    160  * Revision 1.12  1996/02/24 02:45:03  cyril
    161  * got rid of Unix.h
    162  *
    163  * Revision 1.11  1996/02/18  23:50:39  cyril
    164  * final clean up for new resource policy.
    165  *
    166  * Revision 1.10  1996/01/25  09:53:14  dbg
    167  * deal with the now correct posix headers
    168  *
    169  * Revision 1.9  1996/01/23 19:17:39  btaylor
    170  * prep for CW8
    171  *
    172  * Revision 1.8  1996/01/11 18:28:19  dbg
    173  * deal with the new posix environment (i.e. we can now
    174  * include <sys/stat.h> and <sys/types.h> because they
    175  * exist and we don't need as many workarounds for missing
    176  * things in the posix environment).
    177  *
    178  * Revision 1.7  1995/12/21 18:58:15  erich
    179  * Add macro for isascii, which doesn't really exist.
    180  *
    181  * Revision 1.1  1995/12/13  22:51:52  ming
    182  * DR6 FROZEN ON 12/13/95 14:00:00
    183  *
    184  * Revision 1.6  1995/11/08  22:49:32  robert
    185  * FILE_NAME_LENGTH -> B_FILE_NAME_LENGTH
    186  *
    187  * Revision 1.5  1995/08/30  02:42:55  herold
    188  * ### API ### remove all traces of int type from OS.h.  Change
    189  * FILENAME_LENGTH to FILE_NAME_LENGTH.  Lotsa buck for not much
    190  * bang, but there it is...
    191  *
    192  * Revision 1.4  1995/06/05  22:34:07  erich
    193  * Attempt to make stuff in ./gnu compile...sort of.
    194  *
    195  * Revision 1.3  1995/02/22  19:38:43  peter
    196  * Update 'tar' and 'compress' tools to work with new resource/data files.
    197  * 'tar' as some glitches (when using the 'u' flag), but we'll worry about
    198  * that later.
    199  *
    200  * Revision 1.2  1994/10/04  17:38:00  herold
    201  * don't depend on /usr/include being around - use Unix.h instead
    202  *
    203  * Revision 1.1  1993/10/14  22:46:10  moofie
    204  * Initial revision
    205  *
    206  * Revision 4.0.1  87/11/27  21:45:00  rms (Richard Stallman)
    207  * Once copystat has run, don't delete output file on interrupt.
    208  * Mention more flags in the Usage string.
    209  *
    210  * Revision 4.0  85/07/30  12:50:00  joe
    211  * Removed ferror() calls in output routine on every output except first.
    212  * Prepared for release to the world.
    213  *
    214  * Revision 3.6  85/07/04  01:22:21  joe
    215  * Remove much wasted storage by overlaying hash table with the tables
    216  * used by decompress: tab_suffix[1<<BITS], stack[8000].  Updated USERMEM
    217  * computations.  Fixed dump_tab() DEBUG routine.
    218  *
    219  * Revision 3.5  85/06/30  20:47:21  jaw
    220  * Change hash function to use exclusive-or.  Rip out hash cache.  These
    221  * speedups render the megamemory version defunct, for now.  Make decoder
    222  * stack global.  Parts of the RCS trunks 2.7, 2.6, and 2.1 no longer apply.
    223  *
    224  * Revision 3.4  85/06/27  12:00:00  ken
    225  * Get rid of all floating-point calculations by doing all compression ratio
    226  * calculations in fixed point.
    227  *
    228  * Revision 3.3  85/06/24  21:53:24  joe
    229  * Incorporate portability suggestion for M_XENIX.  Got rid of text on #else
    230  * and #endif lines.  Cleaned up #ifdefs for vax and interdata.
    231  *
    232  * Revision 3.2  85/06/06  21:53:24  jaw
    233  * Incorporate portability suggestions for Z8000, IBM PC/XT from mailing list.
    234  * Default to "quiet" output (no compression statistics).
    235  *
    236  * Revision 3.1  85/05/12  18:56:13  jaw
    237  * Integrate decompress() stack speedups (from early pointer mods by McKie).
    238  * Repair multi-file USERMEM gaffe.  Unify 'force' flags to mimic semantics
    239  * of SVR2 'pack'.  Streamline block-compress table clear logic.  Increase
    240  * output byte count by magic number size.
    241  *
    242  * Revision 3.0   84/11/27  11:50:00  petsd!joe
    243  * Set HSIZE depending on BITS.  Set BITS depending on USERMEM.  Unrolled
    244  * loops in clear routines.  Added "-C" flag for 2.0 compatibility.  Used
    245  * unsigned compares on Perkin-Elmer.  Fixed foreground check.
    246  *
    247  * Revision 2.7   84/11/16  19:35:39  ames!jaw
    248  * Cache common hash codes based on input statistics; this improves
    249  * performance for low-density raster images.  Pass on #ifdef bundle
    250  * from Turkowski.
    251  *
    252  * Revision 2.6   84/11/05  19:18:21  ames!jaw
    253  * Vary size of hash tables to reduce time for small files.
    254  * Tune PDP-11 hash function.
    255  *
    256  * Revision 2.5   84/10/30  20:15:14  ames!jaw
    257  * Junk chaining; replace with the simpler (and, on the VAX, faster)
    258  * double hashing, discussed within.  Make block compression standard.
    259  *
    260  * Revision 2.4   84/10/16  11:11:11  ames!jaw
    261  * Introduce adaptive reset for block compression, to boost the rate
    262  * another several percent.  (See mailing list notes.)
    263  *
    264  * Revision 2.3   84/09/22  22:00:00  petsd!joe
    265  * Implemented "-B" block compress.  Implemented REVERSE sorting of tab_next.
    266  * Bug fix for last bits.  Changed fwrite to putchar loop everywhere.
    267  *
    268  * Revision 2.2   84/09/18  14:12:21  ames!jaw
    269  * Fold in news changes, small machine typedef from thomas,
    270  * #ifdef interdata from joe.
    271  *
    272  * Revision 2.1   84/09/10  12:34:56  ames!jaw
    273  * Configured fast table lookup for 32-bit machines.
    274  * This cuts user time in half for b <= FBITS, and is useful for news batching
    275  * from VAX to PDP sites.  Also sped up decompress() [fwrite->putc] and
    276  * added signal catcher [plus beef in writeerr()] to delete effluvia.
    277  *
    278  * Revision 2.0   84/08/28  22:00:00  petsd!joe
    279  * Add check for foreground before prompting user.  Insert maxbits into
    280  * compressed file.  Force file being uncompressed to end with ".Z".
    281  * Added "-c" flag and "zcat".  Prepared for release.
    282  *
    283  * Revision 1.10  84/08/24  18:28:00  turtlevax!ken
    284  * Will only compress regular files (no directories), added a magic number
    285  * header (plus an undocumented -n flag to handle old files without headers),
    286  * added -f flag to force overwriting of possibly existing destination file,
    287  * otherwise the user is prompted for a response.  Will tack on a .Z to a
    288  * filename if it doesn't have one when decompressing.  Will only replace
    289  * file if it was compressed.
    290  *
    291  * Revision 1.9  84/08/16  17:28:00  turtlevax!ken
    292  * Removed scanargs(), getopt(), added .Z extension and unlimited number of
    293  * filenames to compress.  Flags may be clustered (-Ddvb12) or separated
    294  * (-D -d -v -b 12), or combination thereof.  Modes and other status is
    295  * copied with copystat().  -O bug for 4.2 seems to have disappeared with
    296  * 1.8.
    297  *
    298  * Revision 1.8  84/08/09  23:15:00  joe
    299  * Made it compatible with vax version, installed jim's fixes/enhancements
    300  *
    301  * Revision 1.6  84/08/01  22:08:00  joe
    302  * Sped up algorithm significantly by sorting the compress chain.
    303  *
    304  * Revision 1.5  84/07/13  13:11:00  srd
    305  * Added C version of vax asm routines.  Changed structure to arrays to
    306  * save much memory.  Do unsigned compares where possible (faster on
    307  * Perkin-Elmer)
    308  *
    309  * Revision 1.4  84/07/05  03:11:11  thomas
    310  * Clean up the code a little and lint it.  (Lint complains about all
    311  * the regs used in the asm, but I'm not going to "fix" this.)
    312  *
    313  * Revision 1.3  84/07/05  02:06:54  thomas
    314  * Minor fixes.
    315  *
    316  * Revision 1.2  84/07/05  00:27:27  thomas
    317  * Add variable bit length output.
    318  *
    319  */
    320 static char rcs_ident[] = "$Header: /tmp/bonefish/open-beos/current/src/apps/bin/compress/compress.c,v 1.1 2004/06/07 21:23:09 korli Exp $";
    321 
    322 #include <stdio.h>
    323 #include <ctype.h>
    324 #include <signal.h>
    325 #include <sys/types.h>
    326 #include <sys/stat.h>
    327 #include <utime.h>
    328 
    329 #ifdef MSDOS
    330 #include <stdlib.h>
    331 #endif
    332 
    333 #ifdef  __HOBBIT__
    334 # undef putc
    335 #endif
    336 
    337 #define ARGVAL() (*++(*argv) || (--argc && *++argv))
    338 
    339 int n_bits;             /* number of bits/code */
    340 int maxbits = BITS;         /* user settable max # bits/code */
    341 code_int maxcode;           /* maximum code, given n_bits */
    342 code_int maxmaxcode = (code_int)1 << BITS; /* should NEVER generate this code */
    343 #ifdef COMPATIBLE       /* But wrong! */
    344 # define MAXCODE(n_bits)    ((code_int) 1 << (n_bits) - 1)
    345 #else
    346 # define MAXCODE(n_bits)    (((code_int) 1 << (n_bits)) - 1)
    347 #endif /* COMPATIBLE */
    348 
    349 #ifdef XENIX_16
    350 # ifdef MSDOS
    351 
    352 count_int far htab0[8192];
    353 count_int far htab1[8192];
    354 count_int far htab2[8192];
    355 count_int far htab3[8192];
    356 count_int far htab4[8192];
    357 count_int far htab5[8192];
    358 count_int far htab6[8192];
    359 count_int far htab7[8192];
    360 count_int far htab8[HSIZE-65536];
    361 count_int far * htab[9] = {
    362     htab0, htab1, htab2, htab3, htab4, htab5, htab6, htab7, htab8 };
    363 
    364 unsigned short far code0tab[16384];
    365 unsigned short far code1tab[16384];
    366 unsigned short far code2tab[16384];
    367 unsigned short far code3tab[16384];
    368 unsigned short far code4tab[16384];
    369 unsigned short far * codetab[5] = {
    370     code0tab, code1tab, code2tab, code3tab, code4tab };
    371 
    372 # else
    373 
    374 count_int htab0[8192];
    375 count_int htab1[8192];
    376 count_int htab2[8192];
    377 count_int htab3[8192];
    378 count_int htab4[8192];
    379 count_int htab5[8192];
    380 count_int htab6[8192];
    381 count_int htab7[8192];
    382 count_int htab8[HSIZE-65536];
    383 count_int * htab[9] = {
    384     htab0, htab1, htab2, htab3, htab4, htab5, htab6, htab7, htab8 };
    385 
    386 unsigned short code0tab[16384];
    387 unsigned short code1tab[16384];
    388 unsigned short code2tab[16384];
    389 unsigned short code3tab[16384];
    390 unsigned short code4tab[16384];
    391 unsigned short * codetab[5] = {
    392     code0tab, code1tab, code2tab, code3tab, code4tab };
    393 
    394 # endif /* MSDOS */
    395 
    396 #define htabof(i)   (htab[(i) >> 13][(i) & 0x1fff])
    397 #define codetabof(i)    (codetab[(i) >> 14][(i) & 0x3fff])
    398 
    399 #else   /* Normal machine */
    400 count_int htab [HSIZE];
    401 unsigned short codetab [HSIZE];
    402 #define htabof(i)   htab[i]
    403 #define codetabof(i)    codetab[i]
    404 
    405 #endif  /* XENIX_16 */
    406 code_int hsize = HSIZE;         /* for dynamic table sizing */
    407 count_int fsize;
    408 
    409 /*
    410  * To save much memory, we overlay the table used by compress() with those
    411  * used by decompress().  The tab_prefix table is the same size and type
    412  * as the codetab.  The tab_suffix table needs 2**BITS characters.  We
    413  * get this from the beginning of htab.  The output stack uses the rest
    414  * of htab, and contains characters.  There is plenty of room for any
    415  * possible stack (stack used to be 8000 characters).
    416  */
    417 
    418 #define tab_prefixof(i) codetabof(i)
    419 
    420 #ifdef XENIX_16
    421 # ifdef MSDOS
    422 #  define tab_suffixof(i)   ((char_type far *)htab[(i)>>15])[(i) & 0x7fff]
    423 #  define de_stack      ((char_type far *)(htab2))
    424 # else
    425 #  define tab_suffixof(i)   ((char_type *)htab[(i)>>15])[(i) & 0x7fff]
    426 #  define de_stack      ((char_type *)(htab2))
    427 # endif /* MSDOS */
    428 #else   /* Normal machine */
    429 # define tab_suffixof(i)    ((char_type *)(htab))[i]
    430 # define de_stack       ((char_type *)&tab_suffixof((code_int)1<<BITS))
    431 #endif  /* XENIX_16 */
    432 
    433 code_int free_ent = 0;          /* first unused entry */
    434 int exit_stat = 0;
    435 
    436 code_int getcode();
    437 
    438 Usage() {
    439 #ifdef DEBUG
    440 
    441 # ifdef MSDOS
    442     fprintf(stderr,"Usage: compress [-cdDfivV] [-b maxbits] [file ...]\n");
    443 # else
    444     fprintf(stderr,"Usage: compress [-cdDfvV] [-b maxbits] [file ...]\n");
    445 # endif /* MSDOS */
    446 
    447 }
    448 int debug = 0;
    449 #else
    450      
    451 # ifdef MSDOS
    452     fprintf(stderr,"Usage: compress [-cdfivV] [-b maxbits] [file ...]\n");
    453 # else
    454     fprintf(stderr,"Usage: compress [-cdfvV] [-b maxbits] [file ...]\n");
    455 # endif /* MSDOS */
    456 
    457 }
    458 #endif /* DEBUG */
    459 int nomagic = 0;    /* Use a 3-byte magic number header, unless old file */
    460 int zcat_flg = 0;   /* Write output on stdout, suppress messages */
    461 int precious = 1;   /* Don't unlink output file on interrupt */
    462 int quiet = 1;      /* don't tell me about compression */
    463 
    464 /*
    465  * block compression parameters -- after all codes are used up,
    466  * and compression rate changes, start over.
    467  */
    468 int block_compress = BLOCK_MASK;
    469 int clear_flg = 0;
    470 long int ratio = 0;
    471 #define CHECK_GAP 10000 /* ratio check interval */
    472 count_int checkpoint = CHECK_GAP;
    473 /*
    474  * the next two codes should not be changed lightly, as they must not
    475  * lie within the contiguous general code space.
    476  */
    477 #define FIRST   257 /* first free entry */
    478 #define CLEAR   256 /* table clear output code */
    479 
    480 int force = 0;
    481 char ofname [100];
    482          
    483 #ifdef MSDOS
    484 # define PATH_SEP '\\'
    485 int image = 2;      /* 1 <=> image (binary) mode; 2 <=> text mode */
    486 #else
    487 # define PATH_SEP '/'
    488 #endif
    489 
    490 #ifdef DEBUG
    491 int verbose = 0;
    492 #endif /* DEBUG */
    493 void (*bgnd_flag)();
    494 
    495 int do_decomp = 0;
    496 
    497 void compress(void);
    498 void decompress(void);
    499 void copystat(char *ifname, char *ofname);
    500 
    501 /*****************************************************************
    502  * TAG( main )
    503  *
    504  * Algorithm from "A Technique for High Performance Data Compression",
    505  * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.
    506  *
    507  * Usage: compress [-cdfivV] [-b bits] [file ...]
    508  * Inputs:
    509  *
    510  *  -c:     Write output on stdout, don't remove original.
    511  *
    512  *  -d:     If given, decompression is done instead.
    513  *
    514  *  -f:     Forces output file to be generated, even if one already
    515  *          exists, and even if no space is saved by compressing.
    516  *          If -f is not used, the user will be prompted if stdin is
    517  *          a tty, otherwise, the output file will not be overwritten.
    518  *
    519  *  -i:     Image mode (defined only under MS-DOS).  Prevents
    520  *          conversion between UNIX text representation (LF line
    521  *          termination) in compressed form and MS-DOS text
    522  *          representation (CR-LF line termination) in uncompressed
    523  *          form.  Useful with non-text files.
    524  *
    525  *  -v:     Write compression statistics
    526  *
    527  *  -V:     Write version and compilation options.
    528  *
    529  *  -b:     Parameter limits the max number of bits/code.
    530  *
    531  *  file ...:   Files to be compressed.  If none specified, stdin
    532  *          is used.
    533  * Outputs:
    534  *  file.Z:     Compressed form of file with same mode, owner, and utimes
    535  *  or stdout   (if stdin used as input)
    536  *
    537  * Assumptions:
    538  *  When filenames are given, replaces with the compressed version
    539  *  (.Z suffix) only if the file decreases in size.
    540  * Algorithm:
    541  *  Modified Lempel-Ziv method (LZW).  Basically finds common
    542  * substrings and replaces them with a variable size code.  This is
    543  * deterministic, and can be done on the fly.  Thus, the decompression
    544  * procedure needs no input table, but tracks the way the table was built.
    545  */
    546 
    547 main( argc, argv )
    548 register int argc; char **argv;
    549 {
    550     int overwrite = 0;  /* Do not overwrite unless given -f flag */
    551     char tempname[100];
    552     char **filelist, **fileptr;
    553     char *cp, *rindex(), *malloc();
    554     struct stat statbuf;
    555     extern void onintr();
    556 
    557 #ifdef MSDOS
    558     char *sufp;
    559 #else
    560     extern void oops();
    561 #endif
    562 
    563 #ifndef MSDOS
    564     if ( (bgnd_flag = signal ( SIGINT, SIG_IGN )) != SIG_IGN ) {
    565 #endif
    566 
    567     signal ( SIGINT, onintr );
    568 
    569 #ifndef MSDOS
    570     signal ( SIGSEGV, oops );
    571     }
    572 #endif
    573 
    574 #ifdef COMPATIBLE
    575     nomagic = 1;    /* Original didn't have a magic number */
    576 #endif /* COMPATIBLE */
    577 
    578     filelist = fileptr = (char **)(malloc(argc * sizeof(*argv)));
    579     *filelist = NULL;
    580 
    581     if((cp = rindex(argv[0], PATH_SEP)) != 0) {
    582     cp++;
    583     } else {
    584     cp = argv[0];
    585     }
    586 
    587 #ifdef MSDOS
    588     if(strcmp(cp, "UNCOMPRE.EXE") == 0) {
    589 #else
    590     if(strcmp(cp, "uncompress") == 0) {
    591 #endif
    592 
    593     do_decomp = 1;
    594    
    595 #ifdef MSDOS
    596     } else if(strcmp(cp, "ZCAT.EXE") == 0) {
    597 #else
    598     } else if(strcmp(cp, "zcat") == 0) {
    599 #endif
    600 
    601     do_decomp = 1;
    602     zcat_flg = 1;
    603     }
    604 
    605 #ifdef BSD4_2
    606     /* 4.2BSD dependent - take it out if not */
    607     setlinebuf( stderr );
    608 #endif /* BSD4_2 */
    609 
    610     /* Argument Processing
    611      * All flags are optional.
    612      * -D => debug
    613      * -V => print Version; debug verbose
    614      * -d => do_decomp
    615      * -v => unquiet
    616      * -f => force overwrite of output file
    617      * -n => no header: useful to uncompress old files
    618      * -b maxbits => maxbits.  If -b is specified, then maxbits MUST be
    619      *      given also.
    620      * -c => cat all output to stdout
    621      * -C => generate output compatible with compress 2.0.
    622      * if a string is left, must be an input filename.
    623      */
    624     for (argc--, argv++; argc > 0; argc--, argv++) {
    625     if (**argv == '-') {    /* A flag argument */
    626         while (*++(*argv)) {    /* Process all flags in this arg */
    627         switch (**argv) {
    628 #ifdef DEBUG
    629             case 'D':
    630             debug = 1;
    631             break;
    632             case 'V':
    633             verbose = 1;
    634             version();
    635             break;
    636 #else
    637             case 'V':
    638             version();
    639             break;
    640 #endif /* DEBUG */
    641 
    642 #ifdef MSDOS
    643             case 'i':
    644             image = 1;
    645             break;
    646 #endif
    647 
    648             case 'v':
    649             quiet = 0;
    650             break;
    651             case 'd':
    652             do_decomp = 1;
    653             break;
    654             case 'f':
    655             case 'F':
    656             overwrite = 1;
    657             force = 1;
    658             break;
    659             case 'n':
    660             nomagic = 1;
    661             break;
    662             case 'C':
    663             block_compress = 0;
    664             break;
    665             case 'b':
    666             if (!ARGVAL()) {
    667                 fprintf(stderr, "Missing maxbits\n");
    668                 Usage();
    669                 exit(1);
    670             }
    671             maxbits = atoi(*argv);
    672             goto nextarg;
    673             case 'c':
    674             zcat_flg = 1;
    675             break;
    676             case 'q':
    677             quiet = 1;
    678             break;
    679             default:
    680             fprintf(stderr, "Unknown flag: '%c'; ", **argv);
    681             Usage();
    682             exit(1);
    683         }
    684         }
    685     }
    686     else {      /* Input file name */
    687         *fileptr++ = *argv; /* Build input file list */
    688         *fileptr = NULL;
    689         /* process nextarg; */
    690     }
    691     nextarg: continue;
    692     }
    693 
    694     if(maxbits < INIT_BITS) maxbits = INIT_BITS;
    695     if (maxbits > BITS) maxbits = BITS;
    696     maxmaxcode = (code_int) 1 << maxbits;
    697 
    698     if (*filelist != NULL) {
    699     for (fileptr = filelist; *fileptr; fileptr++) {
    700         exit_stat = 0;
    701         if (do_decomp != 0) {           /* DECOMPRESSION */
    702 
    703 #ifdef MSDOS
    704         /* Check for .Z or XZ suffix; add one if necessary */
    705         cp = *fileptr + strlen(*fileptr) - 2;
    706         if ((*cp != '.' && *cp != 'X' && *cp != 'x') ||
    707             (*(++cp) != 'Z' && *cp != 'z')) {
    708             strcpy(tempname, *fileptr);
    709             if ((cp=rindex(tempname,'.')) == NULL)
    710             strcat(tempname, ".Z");
    711             else if(*(++cp) == '\0') strcat(tempname, "Z");
    712             else {
    713             *(++cp) = '\0';
    714             strcat(tempname, "XZ");
    715             }
    716             *fileptr = tempname;
    717         }
    718 #else
    719         /* Check for .Z suffix */
    720         if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") != 0) {
    721             /* No .Z: tack one on */
    722             strcpy(tempname, *fileptr);
    723             strcat(tempname, ".Z");
    724             *fileptr = tempname;
    725         }
    726 #endif /*MSDOS */
    727 
    728         /* Open input file for decompression */
    729 
    730 #ifdef MSDOS
    731         if ((freopen(*fileptr, "rb", stdin)) == NULL) {
    732 #else
    733         if ((freopen(*fileptr, "r", stdin)) == NULL) {
    734 #endif
    735 
    736             perror(*fileptr); continue;
    737         }
    738         /* Check the magic number */
    739         if (nomagic == 0) {
    740             if ((getchar() != (magic_header[0] & 0xFF))
    741              || (getchar() != (magic_header[1] & 0xFF))) {
    742             fprintf(stderr, "%s: not in compressed format\n",
    743                 *fileptr);
    744             continue;
    745             }
    746             maxbits = getchar();    /* set -b from file */
    747             block_compress = maxbits & BLOCK_MASK;
    748             maxbits &= BIT_MASK;
    749             maxmaxcode = (code_int) 1 << maxbits;
    750             if(maxbits > BITS) {
    751             fprintf(stderr,
    752             "%s: compressed with %d bits, can only handle %d bits\n",
    753             *fileptr, maxbits, BITS);
    754             continue;
    755             }
    756         }
    757         /* Generate output filename */
    758         strcpy(ofname, *fileptr);
    759         ofname[strlen(*fileptr) - 2] = '\0';  /* Strip off .Z */
    760         } else {                    /* COMPRESSION */
    761 
    762 #ifdef MSDOS
    763         cp = *fileptr + strlen(*fileptr) - 2;
    764         if ((*cp == '.' || *cp == 'X' || *cp == 'x') &&
    765             (*(++cp) == 'Z' || *cp == 'z')) {
    766             fprintf(stderr,"%s: already has %s suffix -- no change\n",
    767             *fileptr,--cp);
    768 #else
    769         if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") == 0) {
    770             fprintf(stderr, "%s: already has .Z suffix -- no change\n",
    771             *fileptr);
    772 #endif /* MSDOS */
    773 
    774             continue;
    775         }
    776         /* Open input file for compression */
    777 
    778 #ifdef MSDOS
    779         if ((freopen(*fileptr, image == 2 ? "rt" : "rb", stdin))
    780             == NULL) {
    781 #else
    782         if ((freopen(*fileptr, "r", stdin)) == NULL) {
    783 #endif
    784 
    785             perror(*fileptr); continue;
    786         }
    787         stat ( *fileptr, &statbuf );
    788         fsize = (long) statbuf.st_size;
    789         /*
    790          * tune hash table size for small files -- ad hoc,
    791          * but the sizes match earlier #defines, which
    792          * serve as upper bounds on the number of output codes.
    793          */
    794         hsize = HSIZE;
    795         if ( fsize < (1 << 12) )
    796             hsize = min ( 5003, HSIZE );
    797         else if ( fsize < (1 << 13) )
    798             hsize = min ( 9001, HSIZE );
    799         else if ( fsize < (1 << 14) )
    800             hsize = min ( 18013, HSIZE );
    801         else if ( fsize < (1 << 15) )
    802             hsize = min ( 35023, HSIZE );
    803         else if ( fsize < 47000 )
    804             hsize = min ( 50021, HSIZE );
    805 
    806         /* Generate output filename */
    807         strcpy(ofname, *fileptr);
    808 #if !defined BSD4_2 && !defined BEOS        /* Short filenames */
    809         if ((cp = rindex(ofname, PATH_SEP)) != NULL) cp++;
    810         else                    cp = ofname;
    811 # ifdef MSDOS
    812         if (zcat_flg == 0 && (sufp = rindex(cp, '.')) != NULL &&
    813             strlen(sufp) > 2) fprintf(stderr,
    814             "%s: part of filename extension will be replaced by XZ\n",
    815             cp);
    816 # else
    817         if (strlen(cp) > 12) {
    818             fprintf(stderr,"%s: filename too long to tack on .Z\n",cp);
    819             continue;
    820         }
    821 # endif
    822 #endif  /* BSD4_2       Long filenames allowed */
    823                              
    824 #ifdef MSDOS
    825         if ((cp = rindex(ofname, '.')) == NULL) strcat(ofname, ".Z");
    826         else {
    827            if(*(++cp) != '\0') *(++cp) = '\0';
    828            strcat(ofname, "XZ");
    829         }
    830 #else
    831         strcat(ofname, ".Z");
    832 #endif /* MSDOS */
    833 
    834         }
    835         precious = 0;
    836         /* Check for overwrite of existing file */
    837         if (overwrite == 0 && zcat_flg == 0) {
    838         if (stat(ofname, &statbuf) == 0) {
    839             char response[2];
    840             response[0] = 'n';
    841             fprintf(stderr, "%s already exists;", ofname);
    842 #ifndef MSDOS
    843             if (foreground()) {
    844 #endif
    845             fprintf(stderr,
    846                 " do you wish to overwrite %s (y or n)? ", ofname);
    847             fflush(stderr);
    848             read(2, response, 2);
    849             while (response[1] != '\n') {
    850                 if (read(2, response+1, 1) < 0) {   /* Ack! */
    851                     perror("stderr"); break;
    852                 }
    853             }
    854 #ifndef MSDOS
    855             }
    856 #endif
    857             if (response[0] != 'y') {
    858             fprintf(stderr, "\tnot overwritten\n");
    859             continue;
    860             }
    861         }
    862         }
    863         if(zcat_flg == 0) {     /* Open output file */
    864 
    865 #ifdef MSDOS
    866         if (freopen(ofname, do_decomp && image == 2 ? "wt" : "wb",
    867             stdout) == NULL) {
    868 #else       
    869         if (freopen(ofname, "w", stdout) == NULL) {
    870 #endif
    871 
    872             perror(ofname); continue;
    873         }
    874         if(!quiet)
    875             fprintf(stderr, "%s: ", *fileptr);
    876         }
    877 
    878         /* Actually do the compression/decompression */
    879         if (do_decomp == 0) compress();
    880 #ifndef DEBUG
    881         else            decompress();
    882 #else
    883         else if (debug == 0)    decompress();
    884         else            printcodes();
    885         if (verbose)        dump_tab();
    886 #endif /* DEBUG */
    887         if(zcat_flg == 0) {
    888         copystat(*fileptr, ofname); /* Copy stats */
    889         if((exit_stat == 1) || (!quiet))
    890             putc('\n', stderr);
    891         }
    892     }
    893     } else {        /* Standard input */
    894     if (do_decomp == 0) {
    895         compress();
    896 #ifdef DEBUG
    897         if(verbose)     dump_tab();
    898 #endif /* DEBUG */
    899         if(!quiet)
    900             putc('\n', stderr);
    901     } else {
    902         /* Check the magic number */
    903         if (nomagic == 0) {
    904         if ((getchar()!=(magic_header[0] & 0xFF))
    905          || (getchar()!=(magic_header[1] & 0xFF))) {
    906             fprintf(stderr, "stdin: not in compressed format\n");
    907             exit(1);
    908         }
    909         maxbits = getchar();    /* set -b from file */
    910         block_compress = maxbits & BLOCK_MASK;
    911         maxbits &= BIT_MASK;
    912         maxmaxcode = (code_int) 1 << maxbits;
    913         fsize = 100000;     /* assume stdin large for USERMEM */
    914         if(maxbits > BITS) {
    915             fprintf(stderr,
    916             "stdin: compressed with %d bits, can only handle %d bits\n",
    917             maxbits, BITS);
    918             exit(1);
    919         }
    920         }
    921 #ifndef DEBUG
    922         decompress();
    923 #else
    924         if (debug == 0) decompress();
    925         else        printcodes();
    926         if (verbose)    dump_tab();
    927 #endif /* DEBUG */
    928     }
    929     }
    930     exit(exit_stat);
    931 }
    932 
    933 static int offset;
    934 long int in_count = 1;          /* length of input */
    935 long int bytes_out;         /* length of compressed output */
    936 long int out_count = 0;         /* # of codes output (for debugging) */
    937 
    938 /*
    939  * compress stdin to stdout
    940  *
    941  * Algorithm:  use open addressing double hashing (no chaining) on the
    942  * prefix code / next character combination.  We do a variant of Knuth's
    943  * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
    944  * secondary probe.  Here, the modular division first probe is gives way
    945  * to a faster exclusive-or manipulation.  Also do block compression with
    946  * an adaptive reset, whereby the code table is cleared when the compression
    947  * ratio decreases, but after the table fills.  The variable-length output
    948  * codes are re-sized at this point, and a special CLEAR code is generated
    949  * for the decompressor.  Late addition:  construct the table according to
    950  * file size for noticeable speed improvement on small files.  Please direct
    951  * questions about this implementation to ames!jaw.
    952  */
    953 
    954 void
    955 compress() {
    956     register long fcode;
    957     register code_int i = 0;
    958     register int c;
    959     register code_int ent;
    960     register code_int disp;
    961     register code_int hsize_reg;
    962     register int hshift;
    963 
    964 #ifndef COMPATIBLE
    965     if (nomagic == 0) {
    966     putchar(magic_header[0]); putchar(magic_header[1]);
    967     putchar((char)(maxbits | block_compress));
    968     if(ferror(stdout))
    969         writeerr();
    970     }
    971 #endif /* COMPATIBLE */
    972 
    973     offset = 0;
    974     bytes_out = 3;      /* includes 3-byte header mojo */
    975     out_count = 0;
    976     clear_flg = 0;
    977     ratio = 0;
    978     in_count = 1;
    979     checkpoint = CHECK_GAP;
    980     maxcode = MAXCODE(n_bits = INIT_BITS);
    981     free_ent = ((block_compress) ? FIRST : 256 );
    982 
    983     ent = getchar ();
    984 
    985     hshift = 0;
    986     for ( fcode = (long) hsize;  fcode < 65536L; fcode *= 2L )
    987     hshift++;
    988     hshift = 8 - hshift;        /* set hash code range bound */
    989 
    990     hsize_reg = hsize;
    991     cl_hash( (count_int) hsize_reg);        /* clear hash table */
    992 
    993 #ifdef SIGNED_COMPARE_SLOW
    994     while ( (c = getchar()) != (unsigned) EOF ) {
    995 #else
    996     while ( (c = getchar()) != EOF ) {
    997 #endif
    998 
    999 #ifdef MSDOS
    1000     if (c == '\n') in_count += image; else /* include CR if text mode */
    1001 #endif
    1002 
    1003     in_count++;
    1004 
    1005     fcode = (long) (((long) c << maxbits) + ent);
    1006     i = (((code_int)c << hshift) ^ ent);    /* xor hashing */
    1007 
    1008     if ( htabof (i) == fcode ) {
    1009         ent = codetabof (i);
    1010         continue;
    1011     } else if ( (long)htabof (i) < 0 )  /* empty slot */
    1012         goto nomatch;
    1013     disp = hsize_reg - i;       /* secondary hash (after G. Knott) */
    1014     if ( i == 0 )
    1015         disp = 1;
    1016 probe:
    1017     if ( (i -= disp) < 0 )
    1018         i += hsize_reg;
    1019 
    1020     if ( htabof (i) == fcode ) {
    1021         ent = codetabof (i);
    1022         continue;
    1023     }
    1024     if ( (long)htabof (i) > 0 )
    1025         goto probe;
    1026 nomatch:
    1027     output ( (code_int) ent );
    1028     out_count++;
    1029     ent = c;
    1030 #ifdef SIGNED_COMPARE_SLOW
    1031     if ( (unsigned) free_ent < (unsigned) maxmaxcode) {
    1032 #else
    1033     if ( free_ent < maxmaxcode ) {
    1034 #endif
    1035         codetabof (i) = free_ent++; /* code -> hashtable */
    1036         htabof (i) = fcode;
    1037     }
    1038     else if ( (count_int)in_count >= checkpoint && block_compress )
    1039         cl_block ();
    1040     }
    1041     /*
    1042      * Put out the final code.
    1043      */
    1044     output( (code_int)ent );
    1045     out_count++;
    1046     output( (code_int)-1 );
    1047 
    1048     /*
    1049      * Print out stats on stderr
    1050      */
    1051     if(zcat_flg == 0 && !quiet) {
    1052 #ifdef DEBUG
    1053     fprintf( stderr,
    1054         "%ld chars in, %ld codes (%ld bytes) out, compression factor: ",
    1055         in_count, out_count, bytes_out );
    1056     prratio( stderr, in_count, bytes_out );
    1057     fprintf( stderr, "\n");
    1058     fprintf( stderr, "\tCompression as in compact: " );
    1059     prratio( stderr, in_count-bytes_out, in_count );
    1060     fprintf( stderr, "\n");
    1061     fprintf( stderr, "\tLargest code (of last block) was %d (%d bits)\n",
    1062         free_ent - 1, n_bits );
    1063 #else /* !DEBUG */
    1064     fprintf( stderr, "Compression: " );
    1065     prratio( stderr, in_count-bytes_out, in_count );
    1066 #endif /* DEBUG */
    1067     }
    1068     if(bytes_out > in_count)    /* exit(2) if no savings */
    1069     exit_stat = 2;
    1070     return;
    1071 }
    1072 
    1073 /*****************************************************************
    1074  * TAG( output )
    1075  *
    1076  * Output the given code.
    1077  * Inputs:
    1078  *  code:   A n_bits-bit integer.  If == -1, then EOF.  This assumes
    1079  *      that n_bits =< (long)wordsize - 1.
    1080  * Outputs:
    1081  *  Outputs code to the file.
    1082  * Assumptions:
    1083  *  Chars are 8 bits long.
    1084  * Algorithm:
    1085  *  Maintain a BITS character long buffer (so that 8 codes will
    1086  * fit in it exactly).  Use the VAX insv instruction to insert each
    1087  * code in turn.  When the buffer fills up empty it and start over.
    1088  */
    1089 
    1090 static char buf[BITS];
    1091 
    1092 #ifndef vax
    1093 char_type lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
    1094 char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
    1095 #endif /* vax */
    1096 
    1097 output( code )
    1098 code_int  code;
    1099 {
    1100 #ifdef DEBUG
    1101     static int col = 0;
    1102 #endif /* DEBUG */
    1103 
    1104     /*
    1105      * On the VAX, it is important to have the register declarations
    1106      * in exactly the order given, or the asm will break.
    1107      */
    1108     register int r_off = offset, bits= n_bits;
    1109     register char * bp = buf;
    1110 
    1111 #ifdef DEBUG
    1112     if ( verbose )
    1113         fprintf( stderr, "%5d%c", code,
    1114             (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
    1115 #endif /* DEBUG */
    1116     if ( code >= 0 ) {
    1117 #ifdef vax
    1118     /* VAX DEPENDENT!! Implementation on other machines is below.
    1119      *
    1120      * Translation: Insert BITS bits from the argument starting at
    1121      * offset bits from the beginning of buf.
    1122      */
    1123     0;  /* Work around for pcc -O bug with asm and if stmt */
    1124     asm( "insv  4(ap),r11,r10,(r9)" );
    1125 #else /* not a vax */
    1126 /*
    1127  * byte/bit numbering on the VAX is simulated by the following code
    1128  */
    1129     /*
    1130      * Get to the first byte.
    1131      */
    1132     bp += (r_off >> 3);
    1133     r_off &= 7;
    1134     /*
    1135      * Since code is always >= 8 bits, only need to mask the first
    1136      * hunk on the left.
    1137      */
    1138     *bp = (*bp & rmask[r_off]) | (code << r_off) & lmask[r_off];
    1139     bp++;
    1140     bits -= (8 - r_off);
    1141     code >>= 8 - r_off;
    1142     /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
    1143     if ( bits >= 8 ) {
    1144         *bp++ = code;
    1145         code >>= 8;
    1146         bits -= 8;
    1147     }
    1148     /* Last bits. */
    1149     if(bits)
    1150         *bp = code;
    1151 #endif /* vax */
    1152     offset += n_bits;
    1153     if ( offset == (n_bits << 3) ) {
    1154         bp = buf;
    1155         bits = n_bits;
    1156         bytes_out += bits;
    1157         do
    1158         putchar(*bp++);
    1159         while(--bits);
    1160         offset = 0;
    1161     }
    1162 
    1163     /*
    1164      * If the next entry is going to be too big for the code size,
    1165      * then increase it, if possible.
    1166      */
    1167     if ( free_ent > maxcode || (clear_flg > 0))
    1168     {
    1169         /*
    1170          * Write the whole buffer, because the input side won't
    1171          * discover the size increase until after it has read it.
    1172          */
    1173         if ( offset > 0 ) {
    1174         if( fwrite( buf, 1, n_bits, stdout ) != n_bits)
    1175             writeerr();
    1176         bytes_out += n_bits;
    1177         }
    1178         offset = 0;
    1179 
    1180         if ( clear_flg ) {
    1181         maxcode = MAXCODE (n_bits = INIT_BITS);
    1182         clear_flg = 0;
    1183         }
    1184         else {
    1185         n_bits++;
    1186         if ( n_bits == maxbits )
    1187             maxcode = maxmaxcode;
    1188         else
    1189             maxcode = MAXCODE(n_bits);
    1190         }
    1191 #ifdef DEBUG
    1192         if ( debug ) {
    1193         fprintf( stderr, "\nChange to %d bits\n", n_bits );
    1194         col = 0;
    1195         }
    1196 #endif /* DEBUG */
    1197     }
    1198     } else {
    1199     /*
    1200      * At EOF, write the rest of the buffer.
    1201      */
    1202     if ( offset > 0 )
    1203         fwrite( buf, 1, (offset + 7) / 8, stdout );
    1204     bytes_out += (offset + 7) / 8;
    1205     offset = 0;
    1206     fflush( stdout );
    1207 #ifdef DEBUG
    1208     if ( verbose )
    1209         fprintf( stderr, "\n" );
    1210 #endif /* DEBUG */
    1211     if( ferror( stdout ) )
    1212         writeerr();
    1213     }
    1214 }
    1215 
    1216 /*
    1217  * Decompress stdin to stdout.  This routine adapts to the codes in the
    1218  * file building the "string" table on-the-fly; requiring no table to
    1219  * be stored in the compressed file.  The tables used herein are shared
    1220  * with those of the compress() routine.  See the definitions above.
    1221  */
    1222 
    1223 void
    1224 decompress() {
    1225 
    1226 #ifdef BIG
    1227     register char_type far *stackp;
    1228 #else
    1229     register char_type *stackp;
    1230 #endif
    1231 
    1232     register int finchar;
    1233     register code_int code, oldcode, incode;
    1234 
    1235     /*
    1236      * As above, initialize the first 256 entries in the table.
    1237      */
    1238     maxcode = MAXCODE(n_bits = INIT_BITS);
    1239     for ( code = 255; code >= 0; code-- ) {
    1240     tab_prefixof(code) = 0;
    1241     tab_suffixof(code) = (char_type)code;
    1242     }
    1243     free_ent = ((block_compress) ? FIRST : 256 );
    1244 
    1245     finchar = oldcode = getcode();
    1246     if(oldcode == -1)   /* EOF already? */
    1247     return;         /* Get out of here */
    1248     putchar( (char)finchar );       /* first code must be 8 bits = char */
    1249     if(ferror(stdout))      /* Crash if can't write */
    1250     writeerr();
    1251     stackp = de_stack;
    1252 
    1253     while ( (code = getcode()) > -1 ) {
    1254 
    1255     if ( (code == CLEAR) && block_compress ) {
    1256         for ( code = 255; code >= 0; code-- )
    1257         tab_prefixof(code) = 0;
    1258         clear_flg = 1;
    1259         free_ent = FIRST - 1;
    1260         if ( (code = getcode ()) == -1 )    /* O, untimely death! */
    1261         break;
    1262     }
    1263     incode = code;
    1264     /*
    1265      * Special case for KwKwK string.
    1266      */
    1267     if ( code >= free_ent ) {
    1268         *stackp++ = finchar;
    1269         code = oldcode;
    1270     }
    1271 
    1272     /*
    1273      * Generate output characters in reverse order
    1274      */
    1275 #ifdef SIGNED_COMPARE_SLOW
    1276     while ( ((unsigned long)code) >= ((unsigned long)256) ) {
    1277 #else
    1278     while ( code >= 256 ) {
    1279 #endif
    1280         *stackp++ = tab_suffixof(code);
    1281         code = tab_prefixof(code);
    1282     }
    1283     *stackp++ = finchar = tab_suffixof(code);
    1284 
    1285     /*
    1286      * And put them out in forward order
    1287      */
    1288     do
    1289         putchar ( *--stackp );
    1290     while ( stackp > de_stack );
    1291 
    1292     /*
    1293      * Generate the new entry.
    1294      */
    1295     if ( (code=free_ent) < maxmaxcode ) {
    1296         tab_prefixof(code) = (unsigned short)oldcode;
    1297         tab_suffixof(code) = finchar;
    1298         free_ent = code+1;
    1299     }
    1300     /*
    1301      * Remember previous code.
    1302      */
    1303     oldcode = incode;
    1304     }
    1305     fflush( stdout );
    1306     if(ferror(stdout))
    1307     writeerr();
    1308 }
    1309 
    1310 /*****************************************************************
    1311  * TAG( getcode )
    1312  *
    1313  * Read one code from the standard input.  If EOF, return -1.
    1314  * Inputs:
    1315  *  stdin
    1316  * Outputs:
    1317  *  code or -1 is returned.
    1318  */
    1319 
    1320 code_int
    1321 getcode() {
    1322     /*
    1323      * On the VAX, it is important to have the register declarations
    1324      * in exactly the order given, or the asm will break.
    1325      */
    1326     register code_int code;
    1327     static int offset = 0, size = 0;
    1328     static char_type buf[BITS];
    1329     register int r_off, bits;
    1330     register char_type *bp = buf;
    1331 
    1332     if ( clear_flg > 0 || offset >= size || free_ent > maxcode ) {
    1333     /*
    1334      * If the next entry will be too big for the current code
    1335      * size, then we must increase the size.  This implies reading
    1336      * a new buffer full, too.
    1337      */
    1338     if ( free_ent > maxcode ) {
    1339         n_bits++;
    1340         if ( n_bits == maxbits )
    1341         maxcode = maxmaxcode;   /* won't get any bigger now */
    1342         else
    1343         maxcode = MAXCODE(n_bits);
    1344     }
    1345     if ( clear_flg > 0) {
    1346         maxcode = MAXCODE (n_bits = INIT_BITS);
    1347         clear_flg = 0;
    1348     }
    1349     size = fread( buf, 1, n_bits, stdin );
    1350     if ( size <= 0 )
    1351         return -1;          /* end of file */
    1352     offset = 0;
    1353     /* Round size down to integral number of codes */
    1354     size = (size << 3) - (n_bits - 1);
    1355     }
    1356     r_off = offset;
    1357     bits = n_bits;
    1358 #ifdef vax
    1359     asm( "extzv   r10,r9,(r8),r11" );
    1360 #else /* not a vax */
    1361     /*
    1362      * Get to the first byte.
    1363      */
    1364     bp += (r_off >> 3);
    1365     r_off &= 7;
    1366     /* Get first part (low order bits) */
    1367 #ifdef NO_UCHAR
    1368     code = ((*bp++ >> r_off) & rmask[8 - r_off]) & 0xff;
    1369 #else
    1370     code = (*bp++ >> r_off);
    1371 #endif /* NO_UCHAR */
    1372     bits -= (8 - r_off);
    1373     r_off = 8 - r_off;      /* now, offset into code word */
    1374     /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
    1375     if ( bits >= 8 ) {
    1376 #ifdef NO_UCHAR
    1377         code |= (*bp++ & 0xff) << r_off;
    1378 #else
    1379         code |= *bp++ << r_off;
    1380 #endif /* NO_UCHAR */
    1381         r_off += 8;
    1382         bits -= 8;
    1383     }
    1384     /* high order bits. */
    1385     code |= (*bp & rmask[bits]) << r_off;
    1386 #endif /* vax */
    1387     offset += n_bits;
    1388 
    1389     return code;
    1390 }
    1391 
    1392 char *
    1393 rindex(s, c)        /* For those who don't have it in libc.a */
    1394 register char *s, c;
    1395 {
    1396     char *p;
    1397     for (p = NULL; *s; s++)
    1398         if (*s == c)
    1399         p = s;
    1400     return(p);
    1401 }
    1402 
    1403 #ifdef DEBUG
    1404 printcodes()
    1405 {
    1406     /*
    1407      * Just print out codes from input file.  For debugging.
    1408      */
    1409     code_int code;
    1410     int col = 0, bits;
    1411 
    1412     bits = n_bits = INIT_BITS;
    1413     maxcode = MAXCODE(n_bits);
    1414     free_ent = ((block_compress) ? FIRST : 256 );
    1415     while ( ( code = getcode() ) >= 0 ) {
    1416     if ( (code == CLEAR) && block_compress ) {
    1417         free_ent = FIRST - 1;
    1418         clear_flg = 1;
    1419     }
    1420     else if ( free_ent < maxmaxcode )
    1421         free_ent++;
    1422     if ( bits != n_bits ) {
    1423         fprintf(stderr, "\nChange to %d bits\n", n_bits );
    1424         bits = n_bits;
    1425         col = 0;
    1426     }
    1427     fprintf(stderr, "%5d%c", code, (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
    1428     }
    1429     putc( '\n', stderr );
    1430     exit( 0 );
    1431 }
    1432 
    1433 code_int sorttab[1<<BITS];  /* sorted pointers into htab */
    1434 
    1435 dump_tab()  /* dump string table */
    1436 {
    1437     register int i, first;
    1438     register ent;
    1439 #define STACK_SIZE  15000
    1440     int stack_top = STACK_SIZE;
    1441     register c;
    1442 
    1443     if(do_decomp == 0) {    /* compressing */
    1444     register int flag = 1;
    1445 
    1446     for(i=0; i<hsize; i++) {    /* build sort pointers */
    1447         if((long)htabof(i) >= 0) {
    1448             sorttab[codetabof(i)] = i;
    1449         }
    1450     }
    1451     first = block_compress ? FIRST : 256;
    1452     for(i = first; i < free_ent; i++) {
    1453         fprintf(stderr, "%5d: \"", i);
    1454         de_stack[--stack_top] = '\n';
    1455         de_stack[--stack_top] = '"';
    1456         stack_top = in_stack((htabof(sorttab[i])>>maxbits)&0xff,
    1457                      stack_top);
    1458         for(ent=htabof(sorttab[i]) & ((1<<maxbits)-1);
    1459             ent > 256;
    1460             ent=htabof(sorttab[ent]) & ((1<<maxbits)-1)) {
    1461             stack_top = in_stack(htabof(sorttab[ent]) >> maxbits,
    1462                         stack_top);
    1463         }
    1464         stack_top = in_stack(ent, stack_top);
    1465         fwrite( &de_stack[stack_top], 1, STACK_SIZE-stack_top, stderr);
    1466         stack_top = STACK_SIZE;
    1467     }
    1468    } else if(!debug) {  /* decompressing */
    1469 
    1470        for ( i = 0; i < free_ent; i++ ) {
    1471        ent = i;
    1472        c = tab_suffixof(ent);
    1473        if ( isascii(c) && isprint(c) )
    1474            fprintf( stderr, "%5d: %5d/'%c'  \"",
    1475                ent, tab_prefixof(ent), c );
    1476        else
    1477            fprintf( stderr, "%5d: %5d/\\%03o \"",
    1478                ent, tab_prefixof(ent), c );
    1479        de_stack[--stack_top] = '\n';
    1480        de_stack[--stack_top] = '"';
    1481        for ( ; ent != NULL;
    1482            ent = (ent >= FIRST ? tab_prefixof(ent) : NULL) ) {
    1483            stack_top = in_stack(tab_suffixof(ent), stack_top);
    1484        }
    1485        fwrite( &de_stack[stack_top], 1, STACK_SIZE - stack_top, stderr );
    1486        stack_top = STACK_SIZE;
    1487        }
    1488     }
    1489 }
    1490 
    1491 int
    1492 in_stack(c, stack_top)
    1493     register c, stack_top;
    1494 {
    1495     if ( (isascii(c) && isprint(c) && c != '\\') || c == ' ' ) {
    1496         de_stack[--stack_top] = c;
    1497     } else {
    1498         switch( c ) {
    1499         case '\n': de_stack[--stack_top] = 'n'; break;
    1500         case '\t': de_stack[--stack_top] = 't'; break;
    1501         case '\b': de_stack[--stack_top] = 'b'; break;
    1502         case '\f': de_stack[--stack_top] = 'f'; break;
    1503         case '\r': de_stack[--stack_top] = 'r'; break;
    1504         case '\\': de_stack[--stack_top] = '\\'; break;
    1505         default:
    1506         de_stack[--stack_top] = '0' + c % 8;
    1507         de_stack[--stack_top] = '0' + (c / 8) % 8;
    1508         de_stack[--stack_top] = '0' + c / 64;
    1509         break;
    1510         }
    1511         de_stack[--stack_top] = '\\';
    1512     }
    1513     return stack_top;
    1514 }
    1515 #endif /* DEBUG */
    1516 
    1517 writeerr()
    1518 {
    1519     perror ( ofname );
    1520     unlink ( ofname );
    1521     exit ( 1 );
    1522 }
    1523 
    1524 void
    1525 copystat(char *ifname, char *ofname)
    1526 {
    1527     struct stat statbuf;
    1528     int mode;
    1529     struct utimbuf timep;
    1530 
    1531 #ifdef MSDOS
    1532     if (_osmajor < 3) freopen("CON","at",stdout); else    /* MS-DOS 2.xx bug */
    1533 #endif
    1534 
    1535     fclose(stdout);
    1536     if (stat(ifname, &statbuf)) {       /* Get stat on input file */
    1537         perror(ifname);
    1538         return;
    1539     }
    1540 
    1541 #ifndef MSDOS
    1542     if ((statbuf.st_mode & S_IFMT/*0170000*/) != S_IFREG/*0100000*/) {
    1543     if(quiet)
    1544         fprintf(stderr, "%s: ", ifname);
    1545     fprintf(stderr, " -- not a regular file: unchanged");
    1546     exit_stat = 1;
    1547     } else if (statbuf.st_nlink > 1) {
    1548     if(quiet)
    1549         fprintf(stderr, "%s: ", ifname);
    1550     fprintf(stderr, " -- has %d other links: unchanged",
    1551         statbuf.st_nlink - 1);
    1552     exit_stat = 1;
    1553     } else if (exit_stat == 2 && (!force)) { /* No compression: remove file.Z */
    1554 #else
    1555     if (exit_stat == 2 && (!force)) { /* No compression: remove file.Z */
    1556 #endif /* MSDOS */
    1557 
    1558     if(!quiet)
    1559         fprintf(stderr, " -- file unchanged");
    1560     } else {            /* ***** Successful Compression ***** */
    1561         exit_stat = 0;
    1562         mode = statbuf.st_mode & 07777;
    1563         if (chmod(ofname, mode))        /* Copy modes */
    1564             perror(ofname);
    1565 
    1566 #ifndef MSDOS
    1567         chown(ofname, statbuf.st_uid, statbuf.st_gid);  /* Copy ownership */
    1568 #endif
    1569 
    1570         timep.actime  = statbuf.st_atime;
    1571         timep.modtime = statbuf.st_mtime;
    1572         utime(ofname, &timep);  /* Update last accessed and modified times */
    1573         precious = 1;
    1574         fclose(stdin);
    1575         if (unlink(ifname)) {   /* Remove input file */
    1576             perror(ifname);
    1577         }
    1578         if(!quiet)
    1579             fprintf(stderr, " -- replaced with %s", ofname);
    1580         return;     /* Successful return */
    1581     }
    1582 
    1583     /* Unsuccessful return -- one of the tests failed */
    1584     if (unlink(ofname)) {
    1585         perror(ofname);
    1586     }
    1587 }
    1588 
    1589 #ifndef MSDOS
    1590 /*
    1591  * This routine returns 1 if we are running in the foreground and stderr
    1592  * is a tty.
    1593  */
    1594 foreground()
    1595 {
    1596     if(bgnd_flag != SIG_DFL) { /* background? */
    1597         return(0);
    1598     } else {            /* foreground */
    1599         if(isatty(2)) {     /* and stderr is a tty */
    1600             return(1);
    1601         } else {
    1602             return(0);
    1603         }
    1604     }
    1605 }
    1606 #endif
    1607 
    1608 void
    1609 onintr ( )
    1610 {
    1611     if (!precious)
    1612     unlink ( ofname );
    1613     exit ( 1 );
    1614 }
    1615 
    1616 #ifndef MSDOS
    1617 void
    1618 oops ( )    /* wild pointer -- assume bad input */
    1619 {
    1620     if ( do_decomp == 1 )
    1621     fprintf ( stderr, "uncompress: corrupt input\n" );
    1622     unlink ( ofname );
    1623     exit ( 1 );
    1624 }
    1625 #endif /* MSDOS */
    1626 
    1627 cl_block ()     /* table clear for block compress */
    1628 {
    1629     register long int rat;
    1630 
    1631     checkpoint = in_count + CHECK_GAP;
    1632 #ifdef DEBUG
    1633     if ( debug ) {
    1634         fprintf ( stderr, "count: %ld, ratio: ", in_count );
    1635         prratio ( stderr, in_count, bytes_out );
    1636         fprintf ( stderr, "\n");
    1637     }
    1638 #endif /* DEBUG */
    1639 
    1640     if(in_count > 0x007fffff) { /* shift will overflow */
    1641     rat = bytes_out >> 8;
    1642     if(rat == 0) {      /* Don't divide by zero */
    1643         rat = 0x7fffffff;
    1644     } else {
    1645         rat = in_count / rat;
    1646     }
    1647     } else {
    1648     rat = (in_count << 8) / bytes_out;  /* 8 fractional bits */
    1649     }
    1650     if ( rat > ratio ) {
    1651     ratio = rat;
    1652     } else {
    1653     ratio = 0;
    1654 #ifdef DEBUG
    1655     if(verbose)
    1656         dump_tab(); /* dump string table */
    1657 #endif
    1658     cl_hash ( (count_int) hsize );
    1659     free_ent = FIRST;
    1660     clear_flg = 1;
    1661     output ( (code_int) CLEAR );
    1662 #ifdef DEBUG
    1663     if(debug)
    1664         fprintf ( stderr, "clear\n" );
    1665 #endif /* DEBUG */
    1666     }
    1667 }
    1668 
    1669 cl_hash(hsize)      /* reset code table */
    1670     register count_int hsize;
    1671 {
    1672 
    1673 #ifdef XENIX_16
    1674     register j;
    1675     register long k = hsize;
    1676      
    1677 # ifdef MSDOS
    1678     register count_int far *htab_p;
    1679 # else
    1680     register count_int *htab_p;
    1681 # endif /* MSDOS */
    1682 
    1683 #else   /* Normal machine */
    1684     register count_int *htab_p = htab+hsize;
    1685 #endif  /* XENIX_16 */
    1686 
    1687     register long i;
    1688     register long m1 = -1;
    1689 
    1690 #ifdef XENIX_16
    1691     for(j=0; j<=8 && k>=0; j++,k-=8192) {
    1692     i = 8192;
    1693     if(k < 8192) {
    1694         i = k;
    1695     }
    1696     htab_p = &(htab[j][i]);
    1697     i -= 16;
    1698     if(i > 0) {
    1699 #else
    1700     i = hsize - 16;
    1701 #endif
    1702     do {                /* might use Sys V memset(3) here */
    1703         *(htab_p-16) = m1;
    1704         *(htab_p-15) = m1;
    1705         *(htab_p-14) = m1;
    1706         *(htab_p-13) = m1;
    1707         *(htab_p-12) = m1;
    1708         *(htab_p-11) = m1;
    1709         *(htab_p-10) = m1;
    1710         *(htab_p-9) = m1;
    1711         *(htab_p-8) = m1;
    1712         *(htab_p-7) = m1;
    1713         *(htab_p-6) = m1;
    1714         *(htab_p-5) = m1;
    1715         *(htab_p-4) = m1;
    1716         *(htab_p-3) = m1;
    1717         *(htab_p-2) = m1;
    1718         *(htab_p-1) = m1;
    1719         htab_p -= 16;
    1720     } while ((i -= 16) >= 0);
    1721 #ifdef XENIX_16
    1722     }
    1723     }
    1724 #endif
    1725     for ( i += 16; i > 0; i-- )
    1726         *--htab_p = m1;
    1727 }
    1728 
    1729 prratio(stream, num, den)
    1730 FILE *stream;
    1731 long int num, den;
    1732 {
    1733 
    1734 #ifdef DEBUG
    1735     register long q;        /* permits |result| > 655.36% */
    1736 #else
    1737     register int q;         /* Doesn't need to be long */
    1738 #endif
    1739 
    1740     if(num > 214748L) {     /* 2147483647/10000 */
    1741         q = num / (den / 10000L);
    1742     } else {
    1743         q = 10000L * num / den;     /* Long calculations, though */
    1744     }
    1745     if (q < 0) {
    1746         putc('-', stream);
    1747         q = -q;
    1748     }
    1749     fprintf(stream, "%d.%02d%%", (int)(q / 100), (int)(q % 100));
    1750 }
    1751 
    1752 version()
    1753 {
    1754     fprintf(stderr, "%s\n", rcs_ident);
    1755     fprintf(stderr, "Options: ");
    1756 #ifdef vax
    1757     fprintf(stderr, "vax, ");
    1758 #endif
    1759 #ifdef NO_UCHAR
    1760     fprintf(stderr, "NO_UCHAR, ");
    1761 #endif
    1762 #ifdef SIGNED_COMPARE_SLOW
    1763     fprintf(stderr, "SIGNED_COMPARE_SLOW, ");
    1764 #endif
    1765 #ifdef MSDOS
    1766     fprintf(stderr, "MSDOS, ");
    1767 #endif
    1768 #ifdef XENIX_16
    1769     fprintf(stderr, "XENIX_16, ");
    1770 #endif
    1771 #ifdef COMPATIBLE
    1772     fprintf(stderr, "COMPATIBLE, ");
    1773 #endif
    1774 #ifdef DEBUG
    1775     fprintf(stderr, "DEBUG, ");
    1776 #endif
    1777 #ifdef BSD4_2
    1778     fprintf(stderr, "BSD4_2, ");
    1779 #endif
    1780     fprintf(stderr, "BITS = %d\n", BITS);
    1781 }
  • deleted file src/bin/compress/usermem.sh

    diff --git a/src/bin/compress/usermem.sh b/src/bin/compress/usermem.sh
    deleted file mode 100644
    index ba63b8b423..0000000000
    + -  
    1 #! /bin/sh
    2 #
    3 #   @(#)usermem.sh 1.1 86/09/25 SMI; from UCB 5.4 85/09/17
    4 #
    5 : This shell script snoops around to find the maximum amount of available
    6 : user memory.  These variables need to be set only if there is no
    7 : /usr/adm/messages.  KMEM, UNIX, and CLICKSIZE can be set on the command
    8 : line, if desired, e.g. UNIX=/unix
    9 KMEM=/dev/kmem      # User needs read access to KMEM
    10 UNIX=
    11 # VAX           CLICKSIZE=512,  UNIX=/vmunix
    12 # PDP-11        CLICKSIZE=64,   UNIX=/unix
    13 # CADLINC 68000     CLICKSIZE=4096, UNIX=/unix
    14 # Perkin-Elmer 3205 CLICKSIZE=4096, UNIX=/edition7
    15 # Perkin-Elmer all others, CLICKSIZE=2048, UNIX=/edition7
    16 CLICKSIZE=512
    17 eval $*
    18 
    19 if test -n "$UNIX"
    20 then
    21     : User must have specified it already.
    22 elif test -r /vmunix
    23 then
    24     UNIX=/vmunix
    25     if [ -r /bin/sun2 ] && /bin/sun2
    26     then
    27         CLICKSIZE=2048  # Sun-2
    28     elif [ -r /bin/sun3 ] && /bin/sun3
    29     then
    30     CLICKSIZE=8192  # Sun-3
    31     else
    32     CLICKSIZE=512   # Probably VAX
    33     fi
    34 elif test -r /edition7
    35 then
    36     UNIX=/edition7
    37     CLICKSIZE=2048  # Perkin-Elmer: change to 4096 on a 3205
    38 elif test -r /unix
    39 then
    40     UNIX=/unix      # Could be anything
    41 fi
    42 
    43 SIZE=0
    44 # messages: probably the most transportable
    45 if test -r /usr/adm/messages -a -s /usr/adm/messages
    46 then
    47     SIZE=`grep avail /usr/adm/messages | sed -n '$s/.*[     ]//p'`
    48 fi
    49 
    50 if test 0$SIZE -le 0        # no SIZE in /usr/adm/messages
    51 then
    52     if test -r $KMEM        # Readable KMEM
    53     then
    54     if test -n "$UNIX"
    55     then
    56         SIZE=`echo maxmem/D | adb $UNIX $KMEM | sed -n '$s/.*[  ]//p'`
    57         if test 0$SIZE -le 0
    58         then
    59         SIZE=`echo physmem/D | adb $UNIX $KMEM | sed -n '$s/.*[     ]//p'`
    60         fi
    61         SIZE=`expr 0$SIZE '*' $CLICKSIZE`
    62     fi
    63     fi
    64 fi
    65 
    66 case $UNIX in
    67     /vmunix)        # Assume 4.2bsd: check for resource limits
    68     MAXSIZE=`csh -c limit | awk 'BEGIN  { MAXSIZE = 1000000 }
    69 /datasize|memoryuse/ && NF == 3 { if ($2 < MAXSIZE) MAXSIZE = $2 }
    70 END { print MAXSIZE * 1000 }'`
    71     if test $MAXSIZE -lt $SIZE
    72     then
    73         SIZE=$MAXSIZE
    74     fi
    75     ;;
    76 esac
    77 
    78 if test 0$SIZE -le 0
    79 then
    80     echo 0;exit 1
    81 else
    82     echo $SIZE
    83 fi