Gzip 1.1
This commit is contained in:
parent
30154ac8a8
commit
222b83e890
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/misc-GNU/dist2/; revision=18
339
gnu/usr.bin/gzip/COPYING
Normal file
339
gnu/usr.bin/gzip/COPYING
Normal file
@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
450
gnu/usr.bin/gzip/ChangeLog
Normal file
450
gnu/usr.bin/gzip/ChangeLog
Normal file
@ -0,0 +1,450 @@
|
||||
Tue Jun 1 09:07:15 1993 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* version 1.1.1
|
||||
Fix serious bug in vms.c (== instead of =).
|
||||
Added --ascii option.
|
||||
Add workaround in configure.in for Ultrix (quote eval argument)
|
||||
Do not use unset in znew (not supported on Ultrix)
|
||||
Use tar.gz instead of tar.z for the distribution of gzip.
|
||||
Add missing menu item in gzip.texi.
|
||||
Use size_t instead of unsigned, add AC_SIZE_T in configure.in.
|
||||
|
||||
Fri May 28 11:40:01 1993 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* version 1.1
|
||||
Use .gz suffix by default, add --suffix option.
|
||||
Let gunzip accept a "_z" suffix (used by one 'compress' on Vax/VMS).
|
||||
Quit when reading garbage from stdin instead of reporting an error.
|
||||
Added sub.c and add.c for compression of 8 bit images.
|
||||
Added makefile for VAX/MMS and support for wildcards on VMS.
|
||||
Added support for MSC under OS/2.
|
||||
Added support for Prime/PRIMOS.
|
||||
Display compression ratio also when decompressing.
|
||||
Quit after --version (GNU standard)
|
||||
Use --force to bypass isatty() check.
|
||||
Accept --silent as synonym for --quiet (see longopts.table)
|
||||
Accept --to-stdout as synonym for --stdout (see longopts.table)
|
||||
Accept -H and -? in addition to -h and --help.
|
||||
Added comparison of zip and gzip in the readme file.
|
||||
Return an error code in all main compression/decompression functions.
|
||||
Continue processing other files in case of recoverable error.
|
||||
Add description of -f in znew.1.
|
||||
Do not keep uncompressed version for znew -t if .gz already exists.
|
||||
On Unix, use only st_ino and st_dev in same_file().
|
||||
Use S_IRUSR and S_IWUSR if they exist.
|
||||
"test $1 = -d" -> "test x$1 = x-d" in gzexe.
|
||||
In match.S, use symbol sysV68 to detect the Motorola Delta.
|
||||
Do not include memory.h with gcc (conflicting declarations on Sun).
|
||||
Fix more typos.
|
||||
On VMS, define unlink as delete also for gcc.
|
||||
In "make check", unset LANG because "wc -c" fails on Kanji.
|
||||
Renamed shdir as scriptdir.
|
||||
Use the 68020 code instead of 68000 code on the NeXT.
|
||||
Documented --uncompress as synonym for --decompress.
|
||||
Include the standard header files before gzip.h (needed on Bull).
|
||||
Do not assume that _POSIX_VERSION implies dirent.h present.
|
||||
Removed gzip-tar.patch since tar 1.11.2 handles gzip directly.
|
||||
Use less memory when compiled with -DSMALL_MEM (for MSDOS).
|
||||
Optimized updcrc().
|
||||
Don't complain if cc -E does not work correctly.
|
||||
Do not attempt reading 64K bytes on 16 bit Unix systems.
|
||||
Do not use the variable name 'overhead' which is reserved on Lynx!
|
||||
One BULL compiler does not like *p++ in inflate.c => *p, p++.
|
||||
Use casts on free and memcmp to avoid warnings.
|
||||
Remove the "off by more than one minute" time stamp kludge, but
|
||||
document how to avoid saving the time stamp on pipes if desired.
|
||||
Include crypt.h in inflate.c (one system predefines the CRYPT symbol).
|
||||
Add links to gunzip and (g)zcat in the default make rule.
|
||||
Create installation directories if they do not exist.
|
||||
Clarified --prefix option in INSTALL.
|
||||
Use symbol mc68k in match.S for the DIAB DS90.
|
||||
Guard against zero length _match.s in configure.in.
|
||||
In zmore, restore all tty options using stty -g.
|
||||
Added support for MacOS
|
||||
Simplified makecrc.c.
|
||||
Avoid warnings in getopt.c, util.c, unlzw.c.
|
||||
Use autoconf 1.4, in particular for INSTALL and AC_HAVE_POUNDBANG
|
||||
Use .so instead of hard links for zcat.1, gunzip.1 and zcmp.1.
|
||||
Fixed declration of sig_type.
|
||||
Make consistency check in fcfree.
|
||||
Added ztouch.
|
||||
Do not complain if utime fails on a directory (for OS/2).
|
||||
|
||||
Thu Mar 18 18:56:43 1993 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* version 1.0.7
|
||||
Allow zmore to read from standard input (like more).
|
||||
Support the 68000 (Atari ST) in match.S.
|
||||
Retry partial writes (required on Linux when gzip is suspended in
|
||||
a pipe).
|
||||
Allow full pathnames and renamings in gzexe.
|
||||
Don't let gzexe compress setuid executables or gzip itself.
|
||||
Added vms/Makefile.gcc for gcc on the Vax.
|
||||
Give a pointer to Solaris and VMS executables of gzip in README.
|
||||
Allow installation of binaries and shell scripts in different dirs.
|
||||
Do not use alloca on the Cray.
|
||||
Provide strspn and strcspn if string.h does not exist.
|
||||
Define O_CREAT and O_EXCL from FCREAT and FEXCL if necessary.
|
||||
Remove gzip.doc in make realclean.
|
||||
Fixed many typos. (Corrections to my English are welcome.)
|
||||
Put "make manext=l install" at the correct place in INSTALL.
|
||||
Fix incorrect examples in INSTALL and give more examples.
|
||||
Include zdiff.1 for install and uninstall.
|
||||
Allows complex PAGER variable in zmore (e.g.: PAGER="col -x | more")
|
||||
Avoid warning on unused indfound in getopt.c.
|
||||
Cast memset arg to void* (required by some buggy compilers).
|
||||
Include sys/types.h before dirent.h in acgeneral.m4.
|
||||
Fix acgeneral.m4 AC_COMPILE_CHECK to avoid warnings.
|
||||
Don't use alloca.c with gcc. (One NeXT user did not have alloca.h).
|
||||
Change all error messages according to GNU standards.
|
||||
Restore time stamp only if off by more than one minute.
|
||||
Allow installation of zcat as gzcat.
|
||||
Suppress help message and send compressed data to the terminal when
|
||||
gzip is invoked without parameters and without redirection.
|
||||
(Explicit request from Noah Friedman.)
|
||||
Add compile option GNU_STANDARD to respect the GNU coding standards:
|
||||
with -DGNU_STANDARD, behave as gzip even if invoked under the
|
||||
name gunzip. (Complaints to /dev/null or the FSF, not to me!)
|
||||
|
||||
Fri Mar 10 13:27:18 1993 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* version 1.0.6
|
||||
Let gzexe detect executables that are already gzexe'd.
|
||||
Don't try restoring record format on VMS (the simple 1.0.5 code
|
||||
worked correctly only on fixed-512 files). Suppress text_mode.
|
||||
Added asm version for 68000 in amiga/match.a.
|
||||
Use asm version for Atari TT.
|
||||
Fix "make clean" in vms/Makefile.vms.
|
||||
For OS/2, assume HPFS by default, add flag OS2FAT if necessary.
|
||||
Fixed some bugs in zdiff and define zcmp as a link to zdiff.
|
||||
Added zdiff.1
|
||||
Remove configure hack for NeXT; add general fix to autoconf instead
|
||||
Do not strip a ".z" extension if this results in an empty name.
|
||||
Avoid array overflow in get_prefix() for extensions > 10 chars.
|
||||
Accept either q or e to quit zmore.
|
||||
In zmore, try restoring tty mode in all cases.
|
||||
Use Motorola style for match.S on the NeXT.
|
||||
configure.in: unsetenv *hangs* with the Siemens csh...
|
||||
Update vms/gzip.hlp.
|
||||
|
||||
Thu Mar 4 14:13:34 1993 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* version 1.0.5
|
||||
For VMS, restore the file type for variable record format, otherwise
|
||||
extract in fixed length format (not perfect, but better than
|
||||
forcing all files to be in stream_LF format).
|
||||
Use "-z" suffix for VMS.
|
||||
Use only .z, .*-z, .tgz, .taz as valid gzip extensions; update
|
||||
zforce accordingly.
|
||||
Allow a version number in input file names for VMS.
|
||||
Added sample program zread.c.
|
||||
Fix "make check" for some implementations of /bin/sh.
|
||||
Don't rely on stat() for filenames with extension > 3 chars
|
||||
on MSDOS, OS2 and Atari.
|
||||
Garbage collect files in /tmp created by gzexe.
|
||||
Quote $opt in znew.
|
||||
Use TOUCH env variable in znew if it exists.
|
||||
Better error message for gunzip on empty or truncated file.
|
||||
Allow prototypes in getopt.h when __STDC__ defined but 0.
|
||||
Added "make clean" in vms/Makefile.vms.
|
||||
Removed -g from default CFLAGS (with Noah's permission!)
|
||||
Avoid too many HAVE_xxx_H for most systems; use common defaults.
|
||||
Moved default Atari flags into tailor.h for consistency.
|
||||
Use memzero() to clear the hash table.
|
||||
Update vms/gzip.hlp to reflect the VMS behavior.
|
||||
Fix OS_CODE (to fit in a byte).
|
||||
Add utime.h for the Amiga.
|
||||
Add gcc support for the Amiga.
|
||||
Work around incorrect dirent.h for NeXT 2.0.
|
||||
Added Makefile entry for Coherent.
|
||||
|
||||
Fri Feb 22 11:20:49 1993 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* version 1.0.4
|
||||
Added optimized asm version for 68020.
|
||||
Add support for DJGPP.
|
||||
Add support for the Atari ST.
|
||||
Added zforce to rename gzip'ed files with truncated names.
|
||||
Do not install with name uncompress (some systems rely on the
|
||||
absence of any check in the old uncompress).
|
||||
Added missing function (fcfree) in msdos/tailor.c
|
||||
Let gunzip handle .tgz files, and let gzip skip them.
|
||||
Added 'stty min 1' in zmore for SysV and fixed trap code.
|
||||
Suppress .PHONY in Makefile.in, which breaks old makes.
|
||||
Added documentation about pcat and unpack in INSTALL.
|
||||
Add cast to getenv for systems without stdlib.h.
|
||||
Use VAXC instead of VMS to avoid confusion for gcc.
|
||||
Add -K to znew.1.
|
||||
Add gzexe.1.
|
||||
Try preserving file permissions in gzexe.
|
||||
Added -d option for gzexe.
|
||||
Guard against spaces in file names in gzexe.
|
||||
Use CMP env. variable in zcmp.
|
||||
Return a warning exit status for gzip of file with .z suffix.
|
||||
Suppress usage of d_ino which is not portable to all systems.
|
||||
Use #ifdef instead of #if for consistency.
|
||||
For VMS, use "cc util.c" instead of "cc util" (pb with logical names)
|
||||
Added utime() for Amiga.
|
||||
Renamed gzcat.1 as zcat.1.
|
||||
Include fcntl.h for Amiga (for read and write).
|
||||
For VMS, add definition of symbols and links in the makefiles.
|
||||
Give a VMS look to vms/gzip.hlp.
|
||||
Save the original name only when necessary.
|
||||
Add a mode parameter for open in read mode (required by VMS).
|
||||
For VMS, remove the version suffix from the original name.
|
||||
Accept both / and \ as path separator for MSDOS.
|
||||
Let gunzip extract stored .zip files correctly.
|
||||
Added warning about VFC format in vms/gzip.hlp.
|
||||
In znew, skip a bad file but process the others.
|
||||
Cleanup tailor.h.
|
||||
Use GZIP_OPT for VMS to avoid conflict with program name.
|
||||
Added description of GZIP variable in gzip.texi.
|
||||
|
||||
Thu Feb 11 17:21:32 1993 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* version 1.0.3
|
||||
Add -K option for znew to keep old .Z files if smaller.
|
||||
Add -q option (quiet) to cancel -v in GZIP env variable.
|
||||
For Turbo C, normalize pointers before freeing them.
|
||||
Add more safety checks in add_envopt().
|
||||
Add do_exit() for uniform exit path (always free memory).
|
||||
Reduce MAX_PATH_LEN for MSDOS.
|
||||
Include sys/types.h before signal.h
|
||||
Avoid strdup, the NeXT does not have it.
|
||||
Made gzexe safer on systems with filename limitation to 14 chars.
|
||||
|
||||
Fri Feb 10 09:45:49 1993 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* version 1.0.2
|
||||
Added env variable GZIP for default options.
|
||||
Added support for the Amiga.
|
||||
znew now keeps the old .Z if it is smaller than the .z file.
|
||||
Added gzexe to compress rarely used executables.
|
||||
Reduce memory usage when using static allocation (no DYN_ALLOC).
|
||||
Better separation of warning and error return codes.
|
||||
Fix unlzw.c to make DYN_ALLOC and MAXSEG_64K independent options.
|
||||
Allow INBUFSIZ to be >= 32K in unlzw (don't use sign of rsize)
|
||||
Generate tar file in old format to avoid problems with old systems.
|
||||
Preserve time stamp in znew -P if touch -r works.
|
||||
Use ${PAGER-more} instead of ${PAGER:-more} in zmore.
|
||||
Do not use unsigned instead of mode_t.
|
||||
Better error message for trailing garbage in .z file; ignore this
|
||||
garbage on VMS.
|
||||
In zmore, use icanon instead of -cbreak on SYSV.
|
||||
Add trap handler in zmore.
|
||||
Use char* instead of void* for non STDC compilers.
|
||||
Added makefile entry for Xenix on 286.
|
||||
Return an error code when existing file was not overwritten.
|
||||
Use prototype of lzw.h for lzw.c.
|
||||
Fix znew with -P option alone.
|
||||
Give warning for directories even without -v.
|
||||
Close output file before unlink() in case of error.
|
||||
Suppress all target dependent ifdef from the portable files.
|
||||
Free all dynamically allocated variables upon exit.
|
||||
|
||||
Thu Feb 4 18:23:56 1993 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* version 1.0.1
|
||||
Fixed some trivial errors in msdos/Makefile.bor
|
||||
|
||||
Thu Feb 4 10:00:59 1993 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* version 1.0
|
||||
gzip now runs on Vax/VMS (Amiga support will come in next version).
|
||||
Do not overwrite files without -f when using /bin/sh.
|
||||
Support the test option -t for compressed (.Z) files.
|
||||
Flush output for bad compressed files. Add warning in README.
|
||||
Added makefiles for MSDOS.
|
||||
Don't rely on presence of csh in configure
|
||||
Added gunzip.1 and gzcat.1.
|
||||
Updated znew.1.
|
||||
Check reserved flags in unlzw().
|
||||
Return dummy value in main to avoid lint warning.
|
||||
Define OF in lzw.h for lint.
|
||||
Allow both "znew -v -t" and "znew -vt".
|
||||
Don't overwrite the output file name for multiple parts.
|
||||
Echo just a warning if configure is out of date.
|
||||
Use ; instead of , in trees.c (confuses the SAS Amiga compiler).
|
||||
In INSTALL, document "DEFS='-DM_XENIX' ./configure".
|
||||
Use OTHER_PATH_SEP for more portability (DOS, OS2, VMS, AMIGA).
|
||||
Make all directories world writable for broken versions of tar.
|
||||
Use gzip -cd instead of zcat in zmore, zcmp, zdiff.
|
||||
Don't use GNU tar for distributions, some systems can't untar.
|
||||
Do not exit() for gzip --version.
|
||||
|
||||
Mon Jan 26 10:26:42 1993 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* Beta version 0.8.2
|
||||
Avoid 'far' declarations for MSDOS.
|
||||
Use test -f instead of test -x in configure.in (for Ultrix)
|
||||
Add empty else part to if in Makefile.in for broken shells.
|
||||
Use NO_UNDERLINE instead of UNDERLINE (pb with Linux cpp)
|
||||
Accept continuation files with -ff (for damage recovery)
|
||||
Small patch to Makefile.os2
|
||||
Use memzero instead of bzero to avoid potential conflicts
|
||||
Document restriction on extraction of zip files.
|
||||
Fix quoting in ACL_HAVE_SHELL_HACK.
|
||||
Do not check file size on MSDOS because of bug in DIET.
|
||||
Allow zcat on a file with multiple links.
|
||||
Add fix in inflate.c for compatibility with pkzip 2.04c.
|
||||
Release gzip in tar.z and tar format. (No tar.Z).
|
||||
|
||||
Fri Jan 22 10:04:13 1993 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* Beta version 0.8.1
|
||||
Fixed Makefile.os2
|
||||
Fixed #if directives that TurboC does not like.
|
||||
Don't rely on uncompress in znew, use gzip -d.
|
||||
Add the pipe option -P in znew.
|
||||
Add some more ideas in TODO.
|
||||
Support both NDIR and SYSNDIR.
|
||||
|
||||
Sat Jan 21 15:46:38 1993 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* Beta version 0.8
|
||||
Support unpack.
|
||||
Check for _match.o in configure.in in addition to return status.
|
||||
Include <sys/types.h> in zip.c
|
||||
Define local variables and functions as local.
|
||||
Accept more alternative names for the program (pcat, gzcat, ...).
|
||||
Accept .exe as well as .EXE.
|
||||
Uncompress files with multiple links only with -f.
|
||||
Better error message for gunzip of non-existent file.z.
|
||||
Fix the entry for /etc/magic in INSTALL.
|
||||
Use AC_HAVE_HEADERS uniformly instead of special macros.
|
||||
Install the man pages as .1 by default instead of .l.
|
||||
Document crypt++.el in README.
|
||||
Fix for unlzw() on 16-bit machines (bitmask must be unsigned).
|
||||
Complain if input and output files are identical.
|
||||
Create a correct output name for files of exactly 13 chars.
|
||||
Do not overwrite CPP if set
|
||||
Check for i386 before trying to assemble match.s
|
||||
Check for underline in external name before assembling
|
||||
Add patch for tar 1.11.1.
|
||||
|
||||
Mon Jan 5 10:16:24 1993 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* Beta version 0.7
|
||||
Use "make check" instead of "make test".
|
||||
Do not rely on dirname in znew.
|
||||
Keep time stamp and pass options to gzip in znew.
|
||||
Rename .l files back to .1 to avoid conflict with lex
|
||||
Do not create .z.z files with gzip -r.
|
||||
Use nice_match in match.asm
|
||||
Unroll loops in deflate.c
|
||||
Do not attempt matches beyond the window end
|
||||
Allow again gunzip .zip files (was working in 0.5)
|
||||
Allow again compilation with TurboC 2.0 (was working in 0.4)
|
||||
|
||||
Tue Dec 30 20:00:19 1992 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* Beta version 0.6
|
||||
The .z extension is used by pack, not compact (README, gzip.1)
|
||||
Accept gzcat in addition to zcat.
|
||||
Use PAGER in zmore if defined.
|
||||
Man pages for /usr/local/man/manl should have extension .l.
|
||||
Don't redefine bzero on the NeXT
|
||||
Allow incomplete Huffman table if there is only one code.
|
||||
Don't lookahead more than 7 bits (caused premature EOF).
|
||||
Added "make test" to check for compiler bugs.
|
||||
Don't rely on `i386`; try to assemble directly
|
||||
Change magic header to avoid conflict with freeze 1.x.
|
||||
Added entry for /etc/magic in INSTALL.
|
||||
Do not destroy an input .zip file with more than one member.
|
||||
Display "untested" instead of "OK" for gzip -t foo.Z
|
||||
With -t, skip stdin in .Z format
|
||||
Allow multiple compressed members in an input file.
|
||||
Ignore a zero time stamp.
|
||||
Made znew safer.
|
||||
|
||||
Tue Dec 29 10:00:19 1992 Noah Friedman (friedman@gnu.ai.mit.edu)
|
||||
|
||||
Added test for #!/bin/sh in configure.in.
|
||||
Fix some references to $srcdir in Makefile.in
|
||||
|
||||
Mon Dec 21 17:33:35 1992 Jean-Loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* Beta version 0.5
|
||||
Put RCS ids in all files.
|
||||
Added znew to recompress old .Z files with gzip.
|
||||
Avoid "already .z suffix" messages for -r and no -v.
|
||||
Put back check for d_ino in treat_dir().
|
||||
Use HAVE_STRING_H instead of USG.
|
||||
Added os2/Makefile.os2
|
||||
Use SYSUTIME on OS/2.
|
||||
Info dir is $(prefix)/info, not $(prefix)/lib/info.
|
||||
Support long options, added getopt and alloca
|
||||
Support -V and -t
|
||||
Reorder configure.in according to suggestions in autoconf.info
|
||||
Allow links when not removing original file
|
||||
Allow either .z or .Z in zdiff
|
||||
|
||||
Wed Nov 25 11:40:04 1992 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* Beta version 0.4.1
|
||||
Save only the original base name, don't include any directory prefix.
|
||||
Don't use HAVE_LONG_FILE_NAMES (support multiple file system types).
|
||||
Fix declaration of abort_gzip in gzip.h.
|
||||
Include unistd.h when it exists to avoid warnings with gcc -Wall.
|
||||
|
||||
Mon Nov 23 12:39:01 1992 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* Beta version 0.4
|
||||
Lots of cleanup
|
||||
Use autoconf generated 'configure'
|
||||
Fixed the NO_MULTIPLE_DOTS code
|
||||
Fixed the save_orig_name code
|
||||
Support for MSDOS (Turbo C)
|
||||
|
||||
Thu Nov 19 15:18:22 1992 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* Beta version 0.3
|
||||
Added auto configuration. Just type "make" now.
|
||||
Don't overwrite compress by default in "make install". Use
|
||||
"make install_compress" to overwrite.
|
||||
Add match.s for 386 boxes.
|
||||
Added documentation in texinfo format.
|
||||
Provide help for "gunzip" invoked without redirected input.
|
||||
Save original file name when necessary.
|
||||
Support OS/2 (Kai-Uwe Rommel).
|
||||
|
||||
Tue Nov 17 14:32:53 1992 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* Alpha version 0.2.4
|
||||
Return 0 in get_istat() when ok (caused error with zcat).
|
||||
Don't update crc on compressed data (caused crc errors on
|
||||
large files).
|
||||
|
||||
Fri Nov 13 15:04:12 1992 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* Alpha version 0.2.3
|
||||
Initialize rsize in unlzw.c
|
||||
Initialize ofd for zcat.
|
||||
Do not use volatile ifname as argument of treat_dir.
|
||||
Add -1 to -9 in gzip.1.
|
||||
|
||||
Sat Oct 31 18:30:00 1992 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* Alpha version 0.2.2.
|
||||
Fix error messages.
|
||||
Accept gunzip on zip files.
|
||||
|
||||
Sat Oct 31 17:15:00 1992 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* Alpha version 0.2.1
|
||||
Use ctype.h in util.c (problem on SysV).
|
||||
Create BINDIR if it does not exist.
|
||||
Use cc by default.
|
||||
Added zcmp, zmore, zdiff.
|
||||
Fixed the man page gzip.1.
|
||||
|
||||
Sat Oct 31 17:00:00 1992 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* Alpha version 0.2
|
||||
Fixed compilation problems with gcc
|
||||
|
||||
Sat Oct 31 12:46:00 1992 Jean-loup Gailly (jloup@chorus.fr)
|
||||
|
||||
* Alpha version 0.1 released (under time pressure), so it's not
|
||||
much tested, sorry.
|
||||
|
25
gnu/usr.bin/gzip/Makefile
Normal file
25
gnu/usr.bin/gzip/Makefile
Normal file
@ -0,0 +1,25 @@
|
||||
# @(#)Makefile 5.3 (Berkeley) 5/12/90
|
||||
|
||||
PROG= gzip
|
||||
SRCS= gzip.c zip.c deflate.c trees.c bits.c unzip.c inflate.c util.c \
|
||||
crypt.c lzw.c unlzw.c unpack.c getopt.c match.S
|
||||
MAN1= gzexe.0 gzip.0 zdiff.0 zforce.0 zmore.0 znew.0
|
||||
CFLAGS+=-DASMV -DHAVE_UNISTD_H=1 -DDIRENT=1
|
||||
MLINKS= zdiff.1 zcmp.1 gzip.1 gunzip.1 gzip.1 zcat.1 gzip.1 gzcat.1
|
||||
LINKS+= ${DESTDIR}${BINDIR}/gzip ${DESTDIR}${BINDIR}/gunzip
|
||||
LINKS+= ${DESTDIR}${BINDIR}/gzip ${DESTDIR}${BINDIR}/gzcat
|
||||
LINKS+= ${DESTDIR}${BINDIR}/gzip ${DESTDIR}${BINDIR}/zcat
|
||||
|
||||
afterinstall:
|
||||
install -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
|
||||
${.CURDIR}/zforce ${.CURDIR}/gzexe ${.CURDIR}/znew \
|
||||
${.CURDIR}/zmore ${.CURDIR}/zdiff ${.CURDIR}/zcmp \
|
||||
${DESTDIR}${BINDIR}
|
||||
|
||||
match.o: ${.CURDIR}/match.S
|
||||
$(CPP) ${.CURDIR}/match.S >_match.s
|
||||
$(CC) -c _match.s
|
||||
mv _match.o match.o
|
||||
rm -f _match.s
|
||||
|
||||
.include <bsd.prog.mk>
|
158
gnu/usr.bin/gzip/NEWS
Normal file
158
gnu/usr.bin/gzip/NEWS
Normal file
@ -0,0 +1,158 @@
|
||||
Current Version: 1.1.1
|
||||
See the file ChangeLog for the details of all changes.
|
||||
|
||||
Major changes from 1.1 to 1.1.1.
|
||||
* Fix serious bug in vms.c (affects Vax/VMS only).
|
||||
* Added --ascii option.
|
||||
* Add workaround in configure.in for Ultrix (quote eval argument)
|
||||
|
||||
Major changes from 1.0.7 to 1.1.
|
||||
* Use .gz suffix by default, add --suffix option.
|
||||
* Let gunzip accept a "_z" suffix (used by one 'compress' on Vax/VMS).
|
||||
* Quit when reading garbage from stdin instead of reporting an error.
|
||||
* Added makefile for VAX/MMS and support for wildcards on VMS.
|
||||
* Added support for MSC under OS/2.
|
||||
* Added support for Prime/PRIMOS.
|
||||
* Display compression ratio also when decompressing (with --verbose).
|
||||
* Quit after --version (GNU standard)
|
||||
* Use --force to bypass isatty() check
|
||||
* Continue processing other files in case of recoverable error.
|
||||
* Added comparison of zip and gzip in the readme file.
|
||||
* Added small sample programs (ztouch, sub, add)
|
||||
* Use less memory when compiled with -DSMALL_MEM (for MSDOS).
|
||||
* Remove the "off by more than one minute" time stamp kludge
|
||||
|
||||
Major changes from 1.0.6 to 1.0.7.
|
||||
* Allow zmore to read from standard input (like more).
|
||||
* Support the 68000 (Atari ST) in match.S.
|
||||
* Retry partial writes (required on Linux when gzip is suspended in a pipe).
|
||||
* Allow full pathnames and renamings in gzexe.
|
||||
* Don't let gzexe compress setuid executables or gzip itself.
|
||||
* Added vms/Makefile.gcc for gcc on the Vax.
|
||||
* Allow installation of binaries and shell scripts in different dirs.
|
||||
* Allows complex PAGER variable in zmore (e.g.: PAGER="col -x | more")
|
||||
* Allow installation of zcat as gzcat.
|
||||
* Several small changes for portability to old or weird systems.
|
||||
* Suppress help message and send compressed data to the terminal when
|
||||
gzip is invoked without parameters and without redirection.
|
||||
* Add compile option GNU_STANDARD to respect the GNU coding standards:
|
||||
with -DGNU_STANDARD, behave as gzip even if invoked under the name gunzip.
|
||||
(I don't like the last two changes, which were requested by the FSF.)
|
||||
|
||||
Major changes from 1.0.5 to 1.0.6.
|
||||
* Let gzexe detect executables that are already gzexe'd.
|
||||
* Keep file attributes in znew and gzexe if cpmod is available.
|
||||
* Don't try restoring record format on VMS (1.0.5 did not work correctly)
|
||||
* Added asm version for 68000 in amiga/match.a.
|
||||
Use asm version for Atari TT and NeXT.
|
||||
* For OS/2, assume HPFS by default, add flag OS2FAT if necessary.
|
||||
* Fixed some bugs in zdiff and define zcmp as a link to zdiff.
|
||||
|
||||
|
||||
Major changes from 1.0.4 to 1.0.5.
|
||||
* For VMS, restore the file type for variable record format, otherwise
|
||||
extract in fixed length format (not perfect, but better than
|
||||
forcing all files to be in stream_LF format).
|
||||
* For VMS, use "-z" default suffix and accept a version number in file names.
|
||||
* For Unix, allow compression of files with name ending in 'z'. Use only
|
||||
.z, .*-z, .tgz, .taz as valid gzip extensions. In the last two cases,
|
||||
extract to .tar by default.
|
||||
* On some versions of MSDOS, files with a 3 character extension could not
|
||||
be compressed.
|
||||
* Garbage collect files in /tmp created by gzexe.
|
||||
* Fix the 'OS code' byte in the gzip header.
|
||||
* For the Amiga, add the missing utime.h and add support for gcc.
|
||||
|
||||
|
||||
Major changes from 1.0.3 to 1.0.4.
|
||||
* Added optimized asm version for 68020.
|
||||
* Add support for DJGPP.
|
||||
|
||||
* Add support for the Atari ST.
|
||||
* Added zforce to rename gzip'ed files with truncated names.
|
||||
* Do not install with name uncompress (some systems rely on the
|
||||
absence of any check in the old uncompress).
|
||||
* Added missing function (fcfree) in msdos/tailor.c
|
||||
* Let gunzip handle .tgz files, and let gzip skip them.
|
||||
* Added -d option (decompress) for gzexe and try preserving file permissions.
|
||||
* Suppress all warnings with -q.
|
||||
* Use GZIP_OPT for VMS to avoid conflict with program name.
|
||||
* ... and many other small changes (see ChangeLog)
|
||||
|
||||
|
||||
Major changes from 1.0.2 to 1.0.3
|
||||
* Added -K option for znew to keep old .Z files if smaller
|
||||
* Added -q option (quiet) to cancel -v in GZIP env variable.
|
||||
* Made gzexe safer on systems with filename limitation to 14 chars.
|
||||
* Fixed bugs in handling of GZIP env variable and incorrect free with Turbo C.
|
||||
|
||||
|
||||
Major changes from 1.0.1 to 1.0.2
|
||||
* Added env variable GZIP for default options. Example:
|
||||
for sh: GZIP="-8 -v"; export GZIP
|
||||
for csh: setenv GZIP "-8 -v"
|
||||
* Added support for the Amiga.
|
||||
* znew now keeps the old .Z if it is smaller than the .z file.
|
||||
This can happen for some large and very redundant files.
|
||||
* Do not complain about trailing garbage for record oriented IO (Vax/VMS).
|
||||
This implies however that multi-part gzip files are not supported
|
||||
on such systems.
|
||||
* Added gzexe to compress rarely used executables.
|
||||
* Reduce memory usage (required for MSDOS and useful on all systems).
|
||||
* Preserve time stamp in znew -P (pipe option) if touch -r works.
|
||||
|
||||
|
||||
Major changes from 1.0 to 1.0.1
|
||||
* fix trivial errors in the Borland makefile (msdos/Makefile.bor)
|
||||
|
||||
|
||||
Major changes from 0.8.2 to 1.0
|
||||
* gzip now runs on Vax/VMS
|
||||
* gzip will not not overwrite files without -f when using /bin/sh in
|
||||
background.
|
||||
* Support the test option -t for compressed (.Z) files.
|
||||
Allow some data recovery for bad .Z files.
|
||||
* Added makefiles for MSDOS (Only tested for MSC, not Borland).
|
||||
* still more changes to configure for several systems
|
||||
|
||||
|
||||
Major changes from 0.8.1 to 0.8.2:
|
||||
* yet more changes to configure for Linux and other systems
|
||||
* Allow zcat on a file with multiple links.
|
||||
|
||||
|
||||
Major changes from 0.8 to 0.8.1:
|
||||
* znew has now a pipe option -P to reduce the disk space requirements,
|
||||
but this option does not preserve timestamps.
|
||||
* Fixed some #if directives for compilation with TurboC.
|
||||
|
||||
|
||||
Major changes from 0.7 to 0.8:
|
||||
* gzip can now extract .z files created by 'pack'.
|
||||
* configure should no longer believe that every machine is a 386
|
||||
* Fix the entry for /etc/magic in INSTALL.
|
||||
* Add patch for GNU tar 1.11.1 and a pointer to crypt++.el
|
||||
* Uncompress files with multiple links only with -f.
|
||||
* Fix for uncompress of .Z files on 16-bit machines
|
||||
* Create a correct output name for file names of exactly N-1 chars when
|
||||
the system has a limit of N chars.
|
||||
|
||||
|
||||
Major changes from 0.6 to 0.7:
|
||||
* Use "make check" instead of "make test".
|
||||
* Keep time stamp and pass options to gzip in znew.
|
||||
* Do not create .z.z files with gzip -r.
|
||||
* Allow again gunzip .zip files (was working in 0.5)
|
||||
* Allow again compilation with TurboC 2.0 (was working in 0.4)
|
||||
|
||||
|
||||
Major changes form 0.5 to 0.6:
|
||||
* gunzip reported an error when extracting certain .z files. The .z files
|
||||
produced by gzip 0.5 are correct and can be read by gunzip 0.6.
|
||||
* gunzip now supports multiple compressed members within a single .z file.
|
||||
* Fix the check for i386 in configure.
|
||||
* Added "make test" to check for compiler bugs. (gcc -finline-functions
|
||||
is broken at least on the NeXT.)
|
||||
* Use environment variable PAGER in zmore if it is defined.
|
||||
* Accept gzcat in addition to zcat for people having /usr/bin before
|
||||
/usr/local/bin in their path.
|
147
gnu/usr.bin/gzip/README
Normal file
147
gnu/usr.bin/gzip/README
Normal file
@ -0,0 +1,147 @@
|
||||
This is the file README for the gzip distribution, version 1.1.1.
|
||||
|
||||
gzip (GNU zip) is a compression utility designed to be a replacement
|
||||
for 'compress'. Its main advantages over compress are much better
|
||||
compression and freedom from patented algorithms. The GNU Project
|
||||
uses it as the standard compression program for its system.
|
||||
|
||||
gzip currently uses by default the LZ77 algorithm used in zip 1.9 (the
|
||||
portable pkzip compatible archiver). The gzip format was however
|
||||
designed to accommodate several compression algorithms. See below
|
||||
for a comparison of zip and gzip.
|
||||
|
||||
gunzip can currently decompress files created by gzip, compress or
|
||||
pack. The detection of the input format is automatic. For the
|
||||
gzip format, gunzip checks a 32 bit CRC. For pack, gunzip checks the
|
||||
uncompressed length. The 'compress' format was not designed to allow
|
||||
consistency checks. However gunzip is sometimes able to detect a bad
|
||||
.Z file because there is some redundancy in the .Z compression format.
|
||||
If you get an error when uncompressing a .Z file, do not assume that
|
||||
the .Z file is correct simply because the standard uncompress does not
|
||||
complain. This generally means that the standard uncompress does not
|
||||
check its input, and happily generates garbage output.
|
||||
|
||||
gzip produces files with a .gz extension. Previous versions of gzip
|
||||
used the .z extension, which was already used by the 'pack'
|
||||
Huffman encoder. gunzip is able to decompress .z files (packed
|
||||
or gzip'ed).
|
||||
|
||||
Several planned features are not yet supported (see the file TODO).
|
||||
See the file NEWS for a summary of changes since 0.5. See the file
|
||||
INSTALL for installation instructions. Some answers to frequently
|
||||
asked questions are given in the file INSTALL, please read it. (In
|
||||
particular, please don't ask me once more for an /etc/magic entry.)
|
||||
|
||||
WARNINGS about broken optimizers:
|
||||
|
||||
- on the NeXT, "cc -finline-functions" is broken. gzip produces
|
||||
valid .z files but they are much too large because the string
|
||||
matching code misses most matches. Use "cc -O" instead.
|
||||
|
||||
- on the Mips R4000, gcc -O (version 2.3.1) generates bad code, use cc
|
||||
or just gcc -g instead.
|
||||
|
||||
- gcc 2.3.3 on the SGI Indigo IRIX 4.0.5 also produces bad code. Use
|
||||
instead: make CC='cc -O2' or gcc without -O.
|
||||
|
||||
- on Sparc with SunOS 4.1.1 and the SC1.0 compiler, the optimizer
|
||||
works up to -O3 but -O4 does not work.
|
||||
|
||||
- MSC 5.1 with -Ox and -DDYN_ALLOC generates bad code in inflate.c.
|
||||
The default is static allocation (no DYN_ALLOC) and -Ox works on inflate.c.
|
||||
But -Ox does not work on util.c, so you must use -Oait -Gs.
|
||||
|
||||
- On dnix 5.3 2.2 cc version 2.37c is buggy. Version 2.38d works.
|
||||
|
||||
For all machines, Use "make check" to check that gzip was compiled correctly.
|
||||
|
||||
Please send all comments and bug reports by electronic mail to:
|
||||
Jean-loup Gailly <jloup@chorus.fr>
|
||||
|
||||
or, if this fails, to bug-gnu-utils@prep.ai.mit.edu.
|
||||
Bug reports should ideally include:
|
||||
|
||||
* The complete output of "gzip -V" (or the contents of revision.h
|
||||
if you can't get gzip to compile)
|
||||
* The hardware and operating system (try "uname -a")
|
||||
* The compiler used to compile (if it is gcc, use "gcc -v")
|
||||
* A description of the bug behavior
|
||||
* The input to gzip, that triggered the bug
|
||||
|
||||
The package crypt++.el is highly recommended to manipulate gzip'ed
|
||||
file from emacs. It recognizes automatically encrypted and compressed
|
||||
files when they are first visited or written. It is available via
|
||||
anonymous ftp to roebling.poly.edu [128.238.5.31] in /pub/crypt++.el.
|
||||
The same directory contains also patches to dired, ange-ftp and info.
|
||||
GNU tar 1.11.2 has a -z option to invoke directly gzip, so you don't have
|
||||
to patch it.
|
||||
|
||||
The znew and gzexe shell scripts provided with gzip benefit from
|
||||
(but do not require) the cpmod utility to transfer file attributes.
|
||||
It is available by anonymous ftp on gatekeeper.dec.com in
|
||||
/.0/usenet/comp.sources.unix/volume11/cpmod.Z.
|
||||
|
||||
The sample programs zread.c, sub.c and add.c are provided as examples
|
||||
of useful complements to gzip. Read the comments inside each source file.
|
||||
The perl script ztouch is also provided as example (not installed
|
||||
by default since it relies on perl).
|
||||
|
||||
|
||||
gzip is free software, you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License, a copy of which is
|
||||
provided under the name COPYING. The latest version of gzip are always
|
||||
available by ftp in prep.ai.mit.edu:/pub/gnu, or in any of the prep
|
||||
mirror sites:
|
||||
|
||||
- sources in gzip-*.tar (or .shar or .tar.z)
|
||||
- Solaris 2 executables in sparc-sun-solaris2/gzip-binaries-*.tar
|
||||
- MSDOS lha self-extracting exe in gzip-msdos-*.exe. Once extracted,
|
||||
copy gzip.exe to gunzip.exe and zcat.exe, or use "gzip -d" to decompress.
|
||||
|
||||
A VMS executable is available in ftp.spc.edu:[.macro32.savesets]gzip-1-*.zip
|
||||
(use [.macro32]unzip.exe to extract).
|
||||
|
||||
Many thanks to those who provided me with bug reports and feedback.
|
||||
See the files THANKS and ChangeLog for more details.
|
||||
|
||||
|
||||
Note about zip vs. gzip:
|
||||
|
||||
The name 'gzip' was a very unfortunate choice, because zip and gzip
|
||||
are two really different programs, although the actual compression and
|
||||
decompression sources were written by the same persons. A different
|
||||
name should have been used for gzip, but it is too late to change now.
|
||||
|
||||
zip is an archiver: it compresses several files into a single archive
|
||||
file. gzip is a simple compressor: each file is compressed separately.
|
||||
Both share the same compression and decompression code for the
|
||||
'deflate' method. unzip can also decompress old zip archives
|
||||
(implode, shrink and reduce methods). gunzip can also decompress files
|
||||
created by compress and pack. zip 1.9 and gzip do not support
|
||||
compression methods other than deflation. (zip 1.0 supports shrink and
|
||||
implode). Better compression methods may be added in future versions
|
||||
of gzip. zip will always stick to absolute compatibility with pkzip,
|
||||
it is thus constrained by PKWare, which is a commercial company. The
|
||||
gzip header format is deliberately different from that of pkzip to
|
||||
avoid such a constraint.
|
||||
|
||||
On Unix, gzip is mostly useful in combination with tar. GNU tar
|
||||
1.11.2 has a -z option to invoke gzip automatically. "tar -z"
|
||||
compresses better than zip, since gzip can then take advantage of
|
||||
redundancy between distinct files. The drawback is that you must
|
||||
scan the whole tar.z file in order to extract a single file near
|
||||
the end; unzip can directly seek to the end of the zip file. There
|
||||
is no overhead when you extract the whole archive anyway.
|
||||
If a member of a .zip archive is damaged, other files can still
|
||||
be recovered. If a .tar.z file is damaged, files beyond the failure
|
||||
point cannot be recovered. (Future versions of gzip will have
|
||||
error recovery features.)
|
||||
|
||||
gzip and gunzip are distributed as a single program. zip and unzip
|
||||
are, for historical reasons, two separate programs, although the
|
||||
authors of these two programs work closely together in the info-zip
|
||||
team. zip and unzip are not associated with the GNU project.
|
||||
The sources are available by ftp in
|
||||
|
||||
oak.oakland.edu:/pub/misc/unix/zip19p1.zip
|
||||
oak.oakland.edu:/pub/misc/unix/unz50p1.tar-z
|
196
gnu/usr.bin/gzip/THANKS
Normal file
196
gnu/usr.bin/gzip/THANKS
Normal file
@ -0,0 +1,196 @@
|
||||
gzip was written by Jean-loup Gailly <jloup@chorus.fr>, with
|
||||
portions written by Mark Adler (inflate.c) and Peter Jannesen
|
||||
(unlzw.c). The zip deflate format was defined by Phil Katz.
|
||||
Thanks to those who reported problems and suggested
|
||||
various improvements. Here is a partial list of them:
|
||||
|
||||
Mark Adler madler@cco.caltech.edu
|
||||
Edwin Allum edwin@csri.toronto.edu
|
||||
Joseph Arceneaux jla@gnu.ai.mit.edu
|
||||
Tim Auckland tda10@cus.cam.ac.uk
|
||||
Ken-ichiro Aoki aoki@madonna.physics.ucla.edu
|
||||
David Ascher da@marlowe.cog.brown.edu
|
||||
Eric Backus ericb@lsid.hp.com
|
||||
Becky A. Badgett badgett@cs.utexas.edu
|
||||
Dave Barber dbarber@apocalypse.bbn.com
|
||||
Rene Beaulieu reneb@distri.hydro.qc.ca
|
||||
Neal Becker neal@ctd.comsat.com
|
||||
Dieter Becker becker@med-in.uni-sb.de
|
||||
Nelson H. F. Beebe beebe@geronimo.math.utah.edu
|
||||
Jeff Beadles jeff@onion.rain.com
|
||||
David J. N. Begley dbegley@st.nepean.uws.edu.au
|
||||
Jim Bernard jbernard@iola.mines.colorado.edu
|
||||
Karl Berry karl@cs.umb.edu
|
||||
James W. Birdsall jwbirdsa@picarefy.picarefy.com
|
||||
Wayne E. Bouchard web@paladine.hacks.arizona.edu
|
||||
Marc Boucher marc@cam.org
|
||||
Ola Brahammar pt90ob@pt.hk-r.se
|
||||
Dave Brennan brennan@hal.com
|
||||
Alan Brown dogbowl@dogbox.acme.gen.nz
|
||||
Rodney Brown rdb@mel.cocam.oz.au
|
||||
Bruce bde@runx.oz.au
|
||||
Leila Burrell-Davis leilabd@syma.sussex.ac.uk
|
||||
Roger Butenuth butenuth@ira.uka.de
|
||||
Bud Carlson bud@isle.pegasus.com
|
||||
Lim Fung Chai fclim@i1sin.daq.semi.harris.com
|
||||
Wes Chalfant wes@kofax.com
|
||||
Paul Close pdc@lunch.wpd.sgi.com
|
||||
Kevin Cosgrove kevinc@tekig6.pen.tek.com
|
||||
Stephen J Cowley s.j.cowley@amtp.cam.ac.uk
|
||||
Frank Crawford frank@photon.ansto.gov.au
|
||||
James R. Crawford qralston@cislabs.pitt.edu
|
||||
Lawrence Crowl crowl@research.cs.orst.edu
|
||||
Klaus Dahlenburg kdburg@incoahe.hanse.de
|
||||
William E Davidsen davidsen@ariel.crd.ge.com
|
||||
Jeff Deifik jdeifik@isi.edu
|
||||
Vince DeMarco vince@whatnxt.cuc.ab.ca
|
||||
Michael De La Rue p91152@cplab.physics.edinburgh.ac.uk
|
||||
Lawrence R. Dodd dodd@roebling.poly.edu
|
||||
Matthew Donadio donadio@mxd120.rh.psu.edu
|
||||
Andy Dougherty andy@crystal.phys.lafayette.edu
|
||||
John Eaton jwe@che.utexas.edu
|
||||
Brian Edmonds edmonds@edmonds.home.cs.ubc.ca
|
||||
Paul Eggert eggert@twinsun.com
|
||||
Enami enami@sys.ptg.sony.co.jp
|
||||
Kristoffer Eriksson ske@pkmab.se
|
||||
Daniel Eriksson m91der@bellatrix.tdb.uu.se
|
||||
Rik Faith faith@cs.unc.edu
|
||||
Larry Fahnoe fahnoe@c1mpls.mn.org
|
||||
Cristian Ferretti cfs@poincare.mat.puc.cl
|
||||
Karl-Jose Filler pla_jfi@pki-nbg.philips.de
|
||||
Per Foreby perf@efd.lth.se
|
||||
Alexander Fraser alex@cs.umb.edu
|
||||
Noah Friedman friedman@gnu.ai.mit.edu
|
||||
Bob Friesenhahn bfriesen@iphase.com
|
||||
Andy Fyfe andy@scp.caltech.edu
|
||||
Geoff geoff@frs.faxon.com
|
||||
Kaveh R. Ghazi ghazi@staccato.rutgers.edu
|
||||
Torbjorn Granlund tege@sics.se
|
||||
Carl Greco cgreco@parrot.creighton.edu
|
||||
Bruno Haible haible@ma2s2.mathematik.uni-karlsruhe.de
|
||||
Junio Hamano junio@shadow.twinsun.com
|
||||
Harald Hanche-Olsen hanche@ams.sunysb.edu
|
||||
Darrel R. Hankerson hankedr@mail.auburn.edu
|
||||
Ruediger Helsch ruediger@ramz.ing.tu-bs.de
|
||||
Mark C. Henderson mch@sqwest.wimsey.bc.ca
|
||||
Karl Heuer karl@kelp.boston.ma.us
|
||||
Thomas Hiller hiller@fzi.de
|
||||
Eiji Hirai hirai@cc.swarthmore.edu
|
||||
Kjetil Torgrim Homme kjetilho@ifi.uio.no
|
||||
Preston Hunt gt5708a@prism.gatech.edu
|
||||
Shane C Hutchins sch@nymph.msel.unh.edu
|
||||
Hutch hutchinson@wrair-emh1.army.mil
|
||||
Lester Ingber ingber@alumni.caltech.edu
|
||||
Ken Ishii ishii@sni-usa.com
|
||||
Per Steinar Iversen iversen@vsfys1.fi.uib.no
|
||||
Michal Jaegermann ntomczak@vm.ucs.ualberta.ca
|
||||
Brian Jones brianj@skat.usc.edu
|
||||
Denny de Jonge witaddj@dutrex.tudelft.nl
|
||||
Arne H. Juul arnej@lise.unit.no
|
||||
Dana Jacobsen jacobsd@solar.cor2.epa.gov
|
||||
Peter Jannesen peter@ncs.nl
|
||||
Sarantos Kapidakis sarantos%manteion@ics.forth.gr
|
||||
Amir J. Katz amir@matis.ingr.com
|
||||
Steve Kelem kelem@castor.xilinx.com
|
||||
Randy Kirchhof rkk@posms.aus.tx.us
|
||||
Ned Kittlitz kittlitz@seagoon.sw.stratus.com
|
||||
Pete Klammer pklammer@ouray.denver.colorado.edu
|
||||
Fritz Kleemann kleemann@informatik.uni-wuerzburg.dbp.de
|
||||
Tom Kloos tk@sequent.com
|
||||
Carsten Koch carsten.koch@icem.de
|
||||
Winfried Koenig win@in.rhein-main.de
|
||||
Steph Konigsdorfer s.konigsdorfer@frmy.bull.fr
|
||||
Michael D. Lawler mdlawler@bsu-cs.bsu.edu
|
||||
Kevin Layer layer@franz.com
|
||||
Howard D. Leadmon howardl@wb3ffv.ampr.org
|
||||
Alexander Lehmann alex@hal.rhein-main.de
|
||||
Simon Leinen simon@lia.di.epfl.ch
|
||||
Hugues Leroy hugues.leroy@irisa.fr
|
||||
Charles Levert charles@aramis.comm.polymtl.ca
|
||||
Torbj|rn Lindh toobii@elixir.e.kth.se
|
||||
David R. Linn drl@vuse.vanderbilt.edu
|
||||
Antonio Lioy cat@athena.polito.it
|
||||
Jamie Lokier u90jl@ecs.oxford.ac.uk
|
||||
David J. MacKenzie djm@eng.umd.edu
|
||||
John R MacMillan john@chance.gts.org
|
||||
Ron Male male@eso.mc.xerox.com
|
||||
Steeve McCauley steeve@pooh.geophys.mcgill.ca
|
||||
Tod McQuillin mcquill@ccit05.duq.edu
|
||||
Tye McQueen tye@spillman.com
|
||||
Bernd Melchers melchers@chemie.fu-berlin.de
|
||||
Jason Merrill jason@jarthur.claremont.edu
|
||||
Dean S. Messing deanm@medulla.labs.tek.com
|
||||
Luke Mewburn zak@rmit.edu.au
|
||||
Jim Meyering meyering@cs.utexas.edu
|
||||
Frederic Miserey miserey@laguna.ics.uci.edu
|
||||
Marcel J.E. Mol marcel@duteca.et.tudelft.nl
|
||||
Chris Moore moore@src.bae.co.uk
|
||||
Helmut Muelner hmuelner@fiicmds04.tu-graz.ac.at
|
||||
Urban D Mueller umueller@amiga.physik.unizh.ch
|
||||
Timothy Murphy tim@maths.tcd.ie
|
||||
Greg Naber greg@squally.halcyon.com
|
||||
Karl L. Noell noell@informatik.fh-wiesbaden.dbp.de
|
||||
Arthur David Olson ado@elsie.nci.nih.gov
|
||||
Piet van Oostrum piet@cs.ruu.nl
|
||||
Rafael R. Pappalardo rafapa@obelix.cica.es
|
||||
Hal Peterson hrp@pecan.cray.com
|
||||
Pascal Petit petit@cadillac.ibp.fr
|
||||
Bruno Pillard bp@chorus.fr
|
||||
Franc,ois Pinard pinard@iro.umontreal.ca
|
||||
Jay Pinkos pinkos@butyng.bu.edu
|
||||
Thomas Plass thomas@cogsci.ed.ac.uk
|
||||
Mike Polo mikep@cfsmo.honeywell.com
|
||||
Francesco Potorti pot@fly.cnuce.cnr.it
|
||||
David Purves purves@apogee.com
|
||||
Andreas Raab ar@nvmr.robin.de
|
||||
Eric S. Raymond esr@snark.thyrsus.com
|
||||
Klaus Reimann kr@cip.physik.uni-stuttgart.de
|
||||
Michael Rendell michael@mercury.cs.mun.ca
|
||||
Roland B Roberts roberts@nsrl31.nsrl.rochester.edu
|
||||
Kevin Rodgers kevin@rolling-stone.den.mmc.com
|
||||
Kai Uwe Rommel rommel@informatik.tu-muenchen.de
|
||||
Paul Rubin phr@america.telebit.com
|
||||
Wolfgang Rupprecht wolfgang@wsrcc.com
|
||||
Jonathan Ryshpan jon@amito.hitachi.com
|
||||
Paul A Sand pas@unh.edu
|
||||
Tony Sanders sanders@bsdi.com
|
||||
Mike Sangrey mike@sojurn.lns.pa.us
|
||||
Niimi Satoshi a01309@cfi.waseda.ac.jp
|
||||
Marc Schaefer sysadm@alphanet.ch
|
||||
Andreas Schwab schwab@lamothe.informatik.uni-dortmund.de
|
||||
Eric Schenk schenk@cs.toronto.edu
|
||||
Rick Sladkey jrs@world.std.com
|
||||
Daniel L Smith dls@autodesk.com
|
||||
Fred Smith fredex%fcshome@merk.merk.com
|
||||
Paul Southworth pauls@css.itd.umich.edu
|
||||
Rob Spencer robbie@winkle.bhpese.oz.au
|
||||
Richard Stallman rms@gnu.ai.mit.edu
|
||||
Carsten Steger carsten.steger@informatik.tu-muenchen.de
|
||||
Ed Sznyter ews@babel.babel.com
|
||||
Hideaki Tanabe arctanx@iyeyasu.ynl.t.u-tokyo.ac.jp
|
||||
Andrew Telford ajt@peregrin.resmel.bhp.com.au
|
||||
Glenn E. Thobe thobe@getunx.info.com
|
||||
Kei Thomsen kt@keihh.hanse.de
|
||||
Karsten Thygesen karthy@dannug.dk
|
||||
Mark Towfiq towfiq@microdyne.com
|
||||
Jeff Treece treece@sabbagh.com
|
||||
Oliver Trepte oliver@ikaros.fysik4.kth.se
|
||||
Stephane Tsacas slt@is21.isoft.fr
|
||||
Stephen Tweedie sct@dcs.ed.ac.uk
|
||||
Sotiris Vassilopoulos vassilopoulos@virginia.edu
|
||||
Pedro A. M. Vazquez vazquez@iqm.unicamp.br
|
||||
Arjan de Vet devet@win.tue.nl
|
||||
Vadim V. Vlasov vvlasov@inucres.msk.su
|
||||
Eduard Vopicka eduard.vopicka@vse.cs
|
||||
Theo Vosse vosse@ruls41.leidenuniv.nl
|
||||
Marcel Waldvogel marcel@nice.usergroup.ethz.ch
|
||||
Stephen J. Walick steve@nshore.org
|
||||
Gray Watson gray@antaire.com
|
||||
Scott Weikart scott@igc.apc.org
|
||||
Ivo Welch iwelch@agsm.ucla.edu
|
||||
Gijsb. Wiesenekker wiesenecker@sara.nl
|
||||
Wietze van Winden wietze@swi.psy.uva.nl
|
||||
Larry W. Virden lwv26@cas.org
|
||||
Bill Wohler wohler@sap-ag.de
|
||||
Jamie Zawinski jwz@lucid.com
|
||||
Christos Zoulas christos@deshaw.com
|
58
gnu/usr.bin/gzip/TODO
Normal file
58
gnu/usr.bin/gzip/TODO
Normal file
@ -0,0 +1,58 @@
|
||||
TODO file for gzip.
|
||||
|
||||
Some of the planned features include:
|
||||
|
||||
- Structure the sources so that the compression and decompression code
|
||||
form a library usable by any program, and write both gzip and zip on
|
||||
top of this library. This would ideally be a reentrant (thread safe)
|
||||
library, but this would degrade performance. In the meantime, you can
|
||||
look at the sample program zread.c.
|
||||
|
||||
- Make it convenient to define alternative user interfaces (in
|
||||
particular for windowing environments).
|
||||
|
||||
- Support in-memory compression for arbitrarily large amounts of data
|
||||
(zip currently supports in-memory compression only for a single buffer.)
|
||||
|
||||
- Map files in memory when possible, this is generally much faster
|
||||
than read/write. (zip currently maps entire files at once, this
|
||||
should be done in chunks to reduce memory usage.)
|
||||
|
||||
- Add a super-fast compression method, suitable for implementing
|
||||
file systems with transparent compression. One problem is that the
|
||||
best candidate (lzrw1) is patented twice (Waterworth 4,701,745
|
||||
and Gibson & Graybill 5,049,881). The lzrw series of algorithms
|
||||
are available by ftp in ftp.adelaide.edu.au:/pub/compression/lzrw*.
|
||||
|
||||
- Add a super-tight (but slow) compression method, suitable for long
|
||||
term archives. One problem is that the best versions of arithmetic
|
||||
coding are patented (4,286,256 4,295,125 4,463,342 4,467,317
|
||||
4,633,490 4,652,856 4,891,643 4,905,297 4,935,882 4,973,961
|
||||
5,023,611 5,025,258).
|
||||
|
||||
Note: I will introduce new compression methods only if they are
|
||||
significantly better in either speed or compression ratio than the
|
||||
existing method(s). So the total number of different methods should
|
||||
reasonably not exceed 3. (The current 9 compression levels are just
|
||||
tuning parameters for a single method, deflation.)
|
||||
|
||||
- Add optional error correction. One problem is that the current version
|
||||
of ecc cannot recover from inserted or missing bytes. It would be
|
||||
nice to recover from the most common error (transfer of a binary
|
||||
file in ascii mode).
|
||||
|
||||
- Add a block size (-b) option to improve error recovery in case of
|
||||
failure of a complete sector. Each block could be extracted
|
||||
independently, but this reduces the compression ratio.
|
||||
|
||||
- Use a larger window size to deal with some large redundant files that
|
||||
'compress' currently handles better than gzip.
|
||||
|
||||
- implement the following options:
|
||||
|
||||
-e encrypt
|
||||
-l list .z file contents
|
||||
|
||||
- support .Z files in SCO 'compress -H' format.
|
||||
|
||||
Send comments to Jean-loup Gailly <jloup@chorus.fr>.
|
141
gnu/usr.bin/gzip/algorithm.doc
Normal file
141
gnu/usr.bin/gzip/algorithm.doc
Normal file
@ -0,0 +1,141 @@
|
||||
1. Algorithm
|
||||
|
||||
The deflation algorithm used by zip and gzip is a variation of LZ77
|
||||
(Lempel-Ziv 1977, see reference below). It finds duplicated strings in
|
||||
the input data. The second occurrence of a string is replaced by a
|
||||
pointer to the previous string, in the form of a pair (distance,
|
||||
length). Distances are limited to 32K bytes, and lengths are limited
|
||||
to 258 bytes. When a string does not occur anywhere in the previous
|
||||
32K bytes, it is emitted as a sequence of literal bytes. (In this
|
||||
description, 'string' must be taken as an arbitrary sequence of bytes,
|
||||
and is not restricted to printable characters.)
|
||||
|
||||
Literals or match lengths are compressed with one Huffman tree, and
|
||||
match distances are compressed with another tree. The trees are stored
|
||||
in a compact form at the start of each block. The blocks can have any
|
||||
size (except that the compressed data for one block must fit in
|
||||
available memory). A block is terminated when zip determines that it
|
||||
would be useful to start another block with fresh trees. (This is
|
||||
somewhat similar to compress.)
|
||||
|
||||
Duplicated strings are found using a hash table. All input strings of
|
||||
length 3 are inserted in the hash table. A hash index is computed for
|
||||
the next 3 bytes. If the hash chain for this index is not empty, all
|
||||
strings in the chain are compared with the current input string, and
|
||||
the longest match is selected.
|
||||
|
||||
The hash chains are searched starting with the most recent strings, to
|
||||
favor small distances and thus take advantage of the Huffman encoding.
|
||||
The hash chains are singly linked. There are no deletions from the
|
||||
hash chains, the algorithm simply discards matches that are too old.
|
||||
|
||||
To avoid a worst-case situation, very long hash chains are arbitrarily
|
||||
truncated at a certain length, determined by a runtime option (zip -1
|
||||
to -9). So zip does not always find the longest possible match but
|
||||
generally finds a match which is long enough.
|
||||
|
||||
zip also defers the selection of matches with a lazy evaluation
|
||||
mechanism. After a match of length N has been found, zip searches for a
|
||||
longer match at the next input byte. If a longer match is found, the
|
||||
previous match is truncated to a length of one (thus producing a single
|
||||
literal byte) and the longer match is emitted afterwards. Otherwise,
|
||||
the original match is kept, and the next match search is attempted only
|
||||
N steps later.
|
||||
|
||||
The lazy match evaluation is also subject to a runtime parameter. If
|
||||
the current match is long enough, zip reduces the search for a longer
|
||||
match, thus speeding up the whole process. If compression ratio is more
|
||||
important than speed, zip attempts a complete second search even if
|
||||
the first match is already long enough.
|
||||
|
||||
|
||||
2. gzip file format
|
||||
|
||||
The pkzip format imposes a lot of overhead in various headers, which
|
||||
are useful for an archiver but not necessary when only one file is
|
||||
compressed. gzip uses a much simpler structure. Numbers are in little
|
||||
endian format, and bit 0 is the least significant bit.
|
||||
A gzip file is a sequence of compressed members. Each member has the
|
||||
following structure:
|
||||
|
||||
2 bytes magic header 0x1f, 0x8b (\037 \213)
|
||||
1 byte compression method (0..7 reserved, 8 = deflate)
|
||||
1 byte flags
|
||||
bit 0 set: file probably ascii text
|
||||
bit 1 set: continuation of multi-part gzip file
|
||||
bit 2 set: extra field present
|
||||
bit 3 set: original file name present
|
||||
bit 4 set: file comment present
|
||||
bit 5 set: file is encrypted
|
||||
bit 6,7: reserved
|
||||
4 bytes file modification time in Unix format
|
||||
1 byte extra flags (depend on compression method)
|
||||
1 byte operating system on which compression took place
|
||||
|
||||
2 bytes optional part number (second part=1)
|
||||
2 bytes optional extra field length
|
||||
? bytes optional extra field
|
||||
? bytes optional original file name, zero terminated
|
||||
? bytes optional file comment, zero terminated
|
||||
12 bytes optional encryption header
|
||||
? bytes compressed data
|
||||
4 bytes crc32
|
||||
4 bytes uncompressed input size modulo 2^32
|
||||
|
||||
The format was designed to allow single pass compression without any
|
||||
backwards seek, and without a priori knowledge of the uncompressed
|
||||
input size or the available size on the output media. If input does
|
||||
not come from a regular disk file, the file modification time is set
|
||||
to the time at which compression started.
|
||||
|
||||
The time stamp is useful mainly when one gzip file is transferred over
|
||||
a network. In this case it would not help to keep ownership
|
||||
attributes. In the local case, the ownership attributes are preserved
|
||||
by gzip when compressing/decompressing the file. A time stamp of zero
|
||||
is ignored.
|
||||
|
||||
Bit 0 in the flags is only an optional indication, which can be set by
|
||||
a small lookahead in the input data. In case of doubt, the flag is
|
||||
cleared indicating binary data. For systems which have different
|
||||
file formats for ascii text and binary data, the decompressor can
|
||||
use the flag to choose the appropriate format.
|
||||
|
||||
It must be possible to detect the end of the compressed data with any
|
||||
compression format, regardless of the actual size of the compressed
|
||||
data. If the compressed data cannot fit in one file (in particular for
|
||||
diskettes), each part starts with a header as described above, but
|
||||
only the last part has the crc32 and uncompressed size. A decompressor
|
||||
may prompt for additional data for multipart compressed files. It is
|
||||
desirable but not mandatory that multiple parts be extractable
|
||||
independently so that partial data can be recovered if one of the
|
||||
parts is damaged. This is possible only if no compression state is
|
||||
kept from one part to the other. The compression-type dependent flags
|
||||
can indicate this.
|
||||
|
||||
If the file being compressed is on a file system with case insensitive
|
||||
names, the original name field must be forced to lower case. There is
|
||||
no original file name if the data was compressed from standard input.
|
||||
|
||||
Compression is always performed, even if the compressed file is
|
||||
slightly larger than the original. The worst case expansion is
|
||||
a few bytes for the gzip file header, plus 5 bytes every 32K block,
|
||||
or an expansion ratio of 0.015% for large files. Note that the actual
|
||||
number of used disk blocks almost never increases.
|
||||
|
||||
The encryption is that of zip 1.9. For the encryption check, the
|
||||
last byte of the decoded encryption header must be zero. The time
|
||||
stamp of an encrypted file might be set to zero to avoid giving a clue
|
||||
about the construction of the random header.
|
||||
|
||||
Jean-loup Gailly
|
||||
jloup@chorus.fr
|
||||
|
||||
References:
|
||||
|
||||
[LZ77] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data
|
||||
Compression", IEEE Transactions on Information Theory", Vol. 23, No. 3,
|
||||
pp. 337-343.
|
||||
|
||||
APPNOTE.TXT documentation file in PKZIP 1.93a. It is available by
|
||||
ftp in ftp.cso.uiuc.edu:/pc/exec-pc/pkz193a.exe [128.174.5.59]
|
||||
Use "unzip pkz193a.exe APPNOTE.TXT" to extract.
|
205
gnu/usr.bin/gzip/bits.c
Normal file
205
gnu/usr.bin/gzip/bits.c
Normal file
@ -0,0 +1,205 @@
|
||||
/* bits.c -- output variable-length bit strings
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* PURPOSE
|
||||
*
|
||||
* Output variable-length bit strings. Compression can be done
|
||||
* to a file or to memory. (The latter is not supported in this version.)
|
||||
*
|
||||
* DISCUSSION
|
||||
*
|
||||
* The PKZIP "deflate" file format interprets compressed file data
|
||||
* as a sequence of bits. Multi-bit strings in the file may cross
|
||||
* byte boundaries without restriction.
|
||||
*
|
||||
* The first bit of each byte is the low-order bit.
|
||||
*
|
||||
* The routines in this file allow a variable-length bit value to
|
||||
* be output right-to-left (useful for literal values). For
|
||||
* left-to-right output (useful for code strings from the tree routines),
|
||||
* the bits must have been reversed first with bi_reverse().
|
||||
*
|
||||
* For in-memory compression, the compressed bit stream goes directly
|
||||
* into the requested output buffer. The input data is read in blocks
|
||||
* by the mem_read() function. The buffer is limited to 64K on 16 bit
|
||||
* machines.
|
||||
*
|
||||
* INTERFACE
|
||||
*
|
||||
* void bi_init (FILE *zipfile)
|
||||
* Initialize the bit string routines.
|
||||
*
|
||||
* void send_bits (int value, int length)
|
||||
* Write out a bit string, taking the source bits right to
|
||||
* left.
|
||||
*
|
||||
* int bi_reverse (int value, int length)
|
||||
* Reverse the bits of a bit string, taking the source bits left to
|
||||
* right and emitting them right to left.
|
||||
*
|
||||
* void bi_windup (void)
|
||||
* Write out any remaining bits in an incomplete byte.
|
||||
*
|
||||
* void copy_block(char *buf, unsigned len, int header)
|
||||
* Copy a stored block to the zip file, storing first the length and
|
||||
* its one's complement if requested.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tailor.h"
|
||||
#include "gzip.h"
|
||||
#include "crypt.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: bits.c,v 0.8 1993/02/04 13:21:06 jloup Exp $";
|
||||
#endif
|
||||
|
||||
/* ===========================================================================
|
||||
* Local data used by the "bit string" routines.
|
||||
*/
|
||||
|
||||
local file_t zfile; /* output gzip file */
|
||||
|
||||
local unsigned short bi_buf;
|
||||
/* Output buffer. bits are inserted starting at the bottom (least significant
|
||||
* bits).
|
||||
*/
|
||||
|
||||
#define Buf_size (8 * 2*sizeof(char))
|
||||
/* Number of bits used within bi_buf. (bi_buf might be implemented on
|
||||
* more than 16 bits on some systems.)
|
||||
*/
|
||||
|
||||
local int bi_valid;
|
||||
/* Number of valid bits in bi_buf. All bits above the last valid bit
|
||||
* are always zero.
|
||||
*/
|
||||
|
||||
int (*read_buf) OF((char *buf, unsigned size)) = file_read;
|
||||
/* Current input function. Set to mem_read for in-memory compression */
|
||||
|
||||
#ifdef DEBUG
|
||||
ulg bits_sent; /* bit length of the compressed data */
|
||||
#endif
|
||||
|
||||
/* ===========================================================================
|
||||
* Initialize the bit string routines.
|
||||
*/
|
||||
void bi_init (zipfile)
|
||||
file_t zipfile; /* output zip file, NO_FILE for in-memory compression */
|
||||
{
|
||||
zfile = zipfile;
|
||||
bi_buf = 0;
|
||||
bi_valid = 0;
|
||||
#ifdef DEBUG
|
||||
bits_sent = 0L;
|
||||
#endif
|
||||
|
||||
/* Set the defaults for file compression. They are set by memcompress
|
||||
* for in-memory compression.
|
||||
*/
|
||||
if (zfile != NO_FILE) {
|
||||
read_buf = file_read;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Send a value on a given number of bits.
|
||||
* IN assertion: length <= 16 and value fits in length bits.
|
||||
*/
|
||||
void send_bits(value, length)
|
||||
int value; /* value to send */
|
||||
int length; /* number of bits */
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Tracev((stderr," l %2d v %4x ", length, value));
|
||||
Assert(length > 0 && length <= 15, "invalid length");
|
||||
bits_sent += (ulg)length;
|
||||
#endif
|
||||
/* If not enough room in bi_buf, use (valid) bits from bi_buf and
|
||||
* (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
|
||||
* unused bits in value.
|
||||
*/
|
||||
if (bi_valid > (int)Buf_size - length) {
|
||||
bi_buf |= (value << bi_valid);
|
||||
put_short(bi_buf);
|
||||
bi_buf = (ush)value >> (Buf_size - bi_valid);
|
||||
bi_valid += length - Buf_size;
|
||||
} else {
|
||||
bi_buf |= value << bi_valid;
|
||||
bi_valid += length;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Reverse the first len bits of a code, using straightforward code (a faster
|
||||
* method would use a table)
|
||||
* IN assertion: 1 <= len <= 15
|
||||
*/
|
||||
unsigned bi_reverse(code, len)
|
||||
unsigned code; /* the value to invert */
|
||||
int len; /* its bit length */
|
||||
{
|
||||
register unsigned res = 0;
|
||||
do {
|
||||
res |= code & 1;
|
||||
code >>= 1, res <<= 1;
|
||||
} while (--len > 0);
|
||||
return res >> 1;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Write out any remaining bits in an incomplete byte.
|
||||
*/
|
||||
void bi_windup()
|
||||
{
|
||||
if (bi_valid > 8) {
|
||||
put_short(bi_buf);
|
||||
} else if (bi_valid > 0) {
|
||||
put_byte(bi_buf);
|
||||
}
|
||||
bi_buf = 0;
|
||||
bi_valid = 0;
|
||||
#ifdef DEBUG
|
||||
bits_sent = (bits_sent+7) & ~7;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Copy a stored block to the zip file, storing first the length and its
|
||||
* one's complement if requested.
|
||||
*/
|
||||
void copy_block(buf, len, header)
|
||||
char *buf; /* the input data */
|
||||
unsigned len; /* its length */
|
||||
int header; /* true if block header must be written */
|
||||
{
|
||||
bi_windup(); /* align on byte boundary */
|
||||
|
||||
if (header) {
|
||||
put_short((ush)len);
|
||||
put_short((ush)~len);
|
||||
#ifdef DEBUG
|
||||
bits_sent += 2*16;
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG
|
||||
bits_sent += (ulg)len<<3;
|
||||
#endif
|
||||
while (len--) {
|
||||
#ifdef CRYPT
|
||||
int t;
|
||||
if (key) zencode(*buf, t);
|
||||
#endif
|
||||
put_byte(*buf++);
|
||||
}
|
||||
}
|
6
gnu/usr.bin/gzip/crypt.c
Normal file
6
gnu/usr.bin/gzip/crypt.c
Normal file
@ -0,0 +1,6 @@
|
||||
/* crypt.c (dummy version) -- do not perform encryption
|
||||
* Hardly worth copyrighting :-)
|
||||
*/
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: crypt.c,v 0.6 1993/03/22 09:48:47 jloup Exp $";
|
||||
#endif
|
12
gnu/usr.bin/gzip/crypt.h
Normal file
12
gnu/usr.bin/gzip/crypt.h
Normal file
@ -0,0 +1,12 @@
|
||||
/* crypt.h (dummy version) -- do not perform encryption
|
||||
* Hardly worth copyrighting :-)
|
||||
*/
|
||||
|
||||
#ifdef CRYPT
|
||||
# undef CRYPT /* dummy version */
|
||||
#endif
|
||||
|
||||
#define RAND_HEAD_LEN 12 /* length of encryption random header */
|
||||
|
||||
#define zencode
|
||||
#define zdecode
|
730
gnu/usr.bin/gzip/deflate.c
Normal file
730
gnu/usr.bin/gzip/deflate.c
Normal file
@ -0,0 +1,730 @@
|
||||
/* deflate.c -- compress data using the deflation algorithm
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
/*
|
||||
* PURPOSE
|
||||
*
|
||||
* Identify new text as repetitions of old text within a fixed-
|
||||
* length sliding window trailing behind the new text.
|
||||
*
|
||||
* DISCUSSION
|
||||
*
|
||||
* The "deflation" process depends on being able to identify portions
|
||||
* of the input text which are identical to earlier input (within a
|
||||
* sliding window trailing behind the input currently being processed).
|
||||
*
|
||||
* The most straightforward technique turns out to be the fastest for
|
||||
* most input files: try all possible matches and select the longest.
|
||||
* The key feature of this algorithm is that insertions into the string
|
||||
* dictionary are very simple and thus fast, and deletions are avoided
|
||||
* completely. Insertions are performed at each input character, whereas
|
||||
* string matches are performed only when the previous match ends. So it
|
||||
* is preferable to spend more time in matches to allow very fast string
|
||||
* insertions and avoid deletions. The matching algorithm for small
|
||||
* strings is inspired from that of Rabin & Karp. A brute force approach
|
||||
* is used to find longer strings when a small match has been found.
|
||||
* A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
|
||||
* (by Leonid Broukhis).
|
||||
* A previous version of this file used a more sophisticated algorithm
|
||||
* (by Fiala and Greene) which is guaranteed to run in linear amortized
|
||||
* time, but has a larger average cost, uses more memory and is patented.
|
||||
* However the F&G algorithm may be faster for some highly redundant
|
||||
* files if the parameter max_chain_length (described below) is too large.
|
||||
*
|
||||
* ACKNOWLEDGEMENTS
|
||||
*
|
||||
* The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
|
||||
* I found it in 'freeze' written by Leonid Broukhis.
|
||||
* Thanks to many info-zippers for bug reports and testing.
|
||||
*
|
||||
* REFERENCES
|
||||
*
|
||||
* APPNOTE.TXT documentation file in PKZIP 1.93a distribution.
|
||||
*
|
||||
* A description of the Rabin and Karp algorithm is given in the book
|
||||
* "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
|
||||
*
|
||||
* Fiala,E.R., and Greene,D.H.
|
||||
* Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
|
||||
*
|
||||
* INTERFACE
|
||||
*
|
||||
* void lm_init (int pack_level, ush *flags)
|
||||
* Initialize the "longest match" routines for a new file
|
||||
*
|
||||
* ulg deflate (void)
|
||||
* Processes a new input file and return its compressed length. Sets
|
||||
* the compressed length, crc, deflate flags and internal file
|
||||
* attributes.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "tailor.h"
|
||||
#include "gzip.h"
|
||||
#include "lzw.h" /* just for consistency checking */
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: deflate.c,v 0.13 1993/05/25 16:25:40 jloup Exp $";
|
||||
#endif
|
||||
|
||||
/* ===========================================================================
|
||||
* Configuration parameters
|
||||
*/
|
||||
|
||||
/* Compile with MEDIUM_MEM to reduce the memory requirements or
|
||||
* with SMALL_MEM to use as little memory as possible. Use BIG_MEM if the
|
||||
* entire input file can be held in memory (not possible on 16 bit systems).
|
||||
* Warning: defining these symbols affects HASH_BITS (see below) and thus
|
||||
* affects the compression ratio. The compressed output
|
||||
* is still correct, and might even be smaller in some cases.
|
||||
*/
|
||||
|
||||
#ifdef SMALL_MEM
|
||||
# define HASH_BITS 13 /* Number of bits used to hash strings */
|
||||
#endif
|
||||
#ifdef MEDIUM_MEM
|
||||
# define HASH_BITS 14
|
||||
#endif
|
||||
#ifndef HASH_BITS
|
||||
# define HASH_BITS 15
|
||||
/* For portability to 16 bit machines, do not use values above 15. */
|
||||
#endif
|
||||
|
||||
/* To save space (see unlzw.c), we overlay prev+head with tab_prefix and
|
||||
* window with tab_suffix. Check that we can do this:
|
||||
*/
|
||||
#if WSIZE<<1 > 1<<BITS
|
||||
error: cannot overlay window with tab_suffix and prev with tab_prefix0
|
||||
#endif
|
||||
#if HASH_BITS > BITS-1
|
||||
error: cannot overlay head with tab_prefix1
|
||||
#endif
|
||||
|
||||
#define HASH_SIZE (unsigned)(1<<HASH_BITS)
|
||||
#define HASH_MASK (HASH_SIZE-1)
|
||||
#define WMASK (WSIZE-1)
|
||||
/* HASH_SIZE and WSIZE must be powers of two */
|
||||
|
||||
#define NIL 0
|
||||
/* Tail of hash chains */
|
||||
|
||||
#define FAST 4
|
||||
#define SLOW 2
|
||||
/* speed options for the general purpose bit flag */
|
||||
|
||||
#ifndef TOO_FAR
|
||||
# define TOO_FAR 4096
|
||||
#endif
|
||||
/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
|
||||
|
||||
/* ===========================================================================
|
||||
* Local data used by the "longest match" routines.
|
||||
*/
|
||||
|
||||
typedef ush Pos;
|
||||
typedef unsigned IPos;
|
||||
/* A Pos is an index in the character window. We use short instead of int to
|
||||
* save space in the various tables. IPos is used only for parameter passing.
|
||||
*/
|
||||
|
||||
/* DECLARE(uch, window, 2L*WSIZE); */
|
||||
/* Sliding window. Input bytes are read into the second half of the window,
|
||||
* and move to the first half later to keep a dictionary of at least WSIZE
|
||||
* bytes. With this organization, matches are limited to a distance of
|
||||
* WSIZE-MAX_MATCH bytes, but this ensures that IO is always
|
||||
* performed with a length multiple of the block size. Also, it limits
|
||||
* the window size to 64K, which is quite useful on MSDOS.
|
||||
* To do: limit the window size to WSIZE+BSZ if SMALL_MEM (the code would
|
||||
* be less efficient).
|
||||
*/
|
||||
|
||||
/* DECLARE(Pos, prev, WSIZE); */
|
||||
/* Link to older string with same hash index. To limit the size of this
|
||||
* array to 64K, this link is maintained only for the last 32K strings.
|
||||
* An index in this array is thus a window index modulo 32K.
|
||||
*/
|
||||
|
||||
/* DECLARE(Pos, head, 1<<HASH_BITS); */
|
||||
/* Heads of the hash chains or NIL. */
|
||||
|
||||
ulg window_size = (ulg)2*WSIZE;
|
||||
/* window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the
|
||||
* input file length plus MIN_LOOKAHEAD.
|
||||
*/
|
||||
|
||||
long block_start;
|
||||
/* window position at the beginning of the current output block. Gets
|
||||
* negative when the window is moved backwards.
|
||||
*/
|
||||
|
||||
local unsigned ins_h; /* hash index of string to be inserted */
|
||||
|
||||
#define H_SHIFT ((HASH_BITS+MIN_MATCH-1)/MIN_MATCH)
|
||||
/* Number of bits by which ins_h and del_h must be shifted at each
|
||||
* input step. It must be such that after MIN_MATCH steps, the oldest
|
||||
* byte no longer takes part in the hash key, that is:
|
||||
* H_SHIFT * MIN_MATCH >= HASH_BITS
|
||||
*/
|
||||
|
||||
unsigned int near prev_length;
|
||||
/* Length of the best match at previous step. Matches not greater than this
|
||||
* are discarded. This is used in the lazy match evaluation.
|
||||
*/
|
||||
|
||||
unsigned near strstart; /* start of string to insert */
|
||||
unsigned near match_start; /* start of matching string */
|
||||
local int eofile; /* flag set at end of input file */
|
||||
local unsigned lookahead; /* number of valid bytes ahead in window */
|
||||
|
||||
unsigned near max_chain_length;
|
||||
/* To speed up deflation, hash chains are never searched beyond this length.
|
||||
* A higher limit improves compression ratio but degrades the speed.
|
||||
*/
|
||||
|
||||
local unsigned int max_lazy_match;
|
||||
/* Attempt to find a better match only when the current match is strictly
|
||||
* smaller than this value.
|
||||
*/
|
||||
|
||||
int near good_match;
|
||||
/* Use a faster search when the previous match is longer than this */
|
||||
|
||||
|
||||
/* Values for max_lazy_match, good_match and max_chain_length, depending on
|
||||
* the desired pack level (0..9). The values given below have been tuned to
|
||||
* exclude worst case performance for pathological files. Better values may be
|
||||
* found for specific files.
|
||||
*/
|
||||
|
||||
typedef struct config {
|
||||
ush good_length; /* reduce lazy search above this match length */
|
||||
ush max_lazy; /* do not perform lazy search above this match length */
|
||||
ush nice_length; /* quit search above this match length */
|
||||
ush max_chain;
|
||||
} config;
|
||||
|
||||
#ifdef FULL_SEARCH
|
||||
# define nice_match MAX_MATCH
|
||||
#else
|
||||
int near nice_match; /* Stop searching when current match exceeds this */
|
||||
#endif
|
||||
|
||||
local config configuration_table[10] = {
|
||||
/* good lazy nice chain */
|
||||
/* 0 */ {0, 0, 0, 0}, /* store only */
|
||||
/* 1 */ {4, 4, 16, 16}, /* maximum speed */
|
||||
/* 2 */ {6, 8, 16, 16},
|
||||
/* 3 */ {8, 16, 32, 32},
|
||||
/* 4 */ {8, 16, 64, 64},
|
||||
/* 5 */ {8, 16, 128, 128},
|
||||
/* 6 */ {8, 32, 128, 256},
|
||||
/* 7 */ {8, 64, 128, 512},
|
||||
/* 8 */ {32, 128, 258, 1024},
|
||||
/* 9 */ {32, 258, 258, 4096}}; /* maximum compression */
|
||||
|
||||
/* Note: the current code requires max_lazy >= MIN_MATCH and max_chain >= 4
|
||||
* but these restrictions can easily be removed at a small cost.
|
||||
*/
|
||||
|
||||
#define EQUAL 0
|
||||
/* result of memcmp for equal strings */
|
||||
|
||||
/* ===========================================================================
|
||||
* Prototypes for local functions.
|
||||
*/
|
||||
local void fill_window OF((void));
|
||||
int longest_match OF((IPos cur_match));
|
||||
#ifdef ASMV
|
||||
void match_init OF((void)); /* asm code initialization */
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
local void check_match OF((IPos start, IPos match, int length));
|
||||
#endif
|
||||
|
||||
/* ===========================================================================
|
||||
* Update a hash value with the given input byte
|
||||
* IN assertion: all calls to to UPDATE_HASH are made with consecutive
|
||||
* input characters, so that a running hash key can be computed from the
|
||||
* previous key instead of complete recalculation each time.
|
||||
*/
|
||||
#define UPDATE_HASH(h,c) (h = (((h)<<H_SHIFT) ^ (c)) & HASH_MASK)
|
||||
|
||||
/* ===========================================================================
|
||||
* Insert string s in the dictionary and set match_head to the previous head
|
||||
* of the hash chain (the most recent string with same hash key). Return
|
||||
* the previous length of the hash chain.
|
||||
* IN assertion: all calls to to INSERT_STRING are made with consecutive
|
||||
* input characters and the first MIN_MATCH bytes of s are valid
|
||||
* (except for the last MIN_MATCH-1 bytes of the input file).
|
||||
*/
|
||||
#define INSERT_STRING(s, match_head) \
|
||||
(UPDATE_HASH(ins_h, window[(s) + MIN_MATCH-1]), \
|
||||
prev[(s) & WMASK] = match_head = head[ins_h], \
|
||||
head[ins_h] = (s))
|
||||
|
||||
/* ===========================================================================
|
||||
* Initialize the "longest match" routines for a new file
|
||||
*/
|
||||
void lm_init (pack_level, flags)
|
||||
int pack_level; /* 0: store, 1: best speed, 9: best compression */
|
||||
ush *flags; /* general purpose bit flag */
|
||||
{
|
||||
register unsigned j;
|
||||
|
||||
if (pack_level < 1 || pack_level > 9) error("bad pack level");
|
||||
|
||||
/* Initialize the hash table. */
|
||||
#if defined(MAXSEG_64K) && HASH_BITS == 15
|
||||
for (j = 0; j < HASH_SIZE; j++) head[j] = NIL;
|
||||
#else
|
||||
memzero((char*)head, HASH_SIZE*sizeof(*head));
|
||||
#endif
|
||||
/* prev will be initialized on the fly */
|
||||
|
||||
/* Set the default configuration parameters:
|
||||
*/
|
||||
max_lazy_match = configuration_table[pack_level].max_lazy;
|
||||
good_match = configuration_table[pack_level].good_length;
|
||||
#ifndef FULL_SEARCH
|
||||
nice_match = configuration_table[pack_level].nice_length;
|
||||
#endif
|
||||
max_chain_length = configuration_table[pack_level].max_chain;
|
||||
if (pack_level == 1) {
|
||||
*flags |= FAST;
|
||||
} else if (pack_level == 9) {
|
||||
*flags |= SLOW;
|
||||
}
|
||||
/* ??? reduce max_chain_length for binary files */
|
||||
|
||||
strstart = 0;
|
||||
block_start = 0L;
|
||||
#ifdef ASMV
|
||||
match_init(); /* initialize the asm code */
|
||||
#endif
|
||||
|
||||
lookahead = read_buf((char*)window,
|
||||
sizeof(int) <= 2 ? (unsigned)WSIZE : 2*WSIZE);
|
||||
|
||||
if (lookahead == 0 || lookahead == (unsigned)EOF) {
|
||||
eofile = 1, lookahead = 0;
|
||||
return;
|
||||
}
|
||||
eofile = 0;
|
||||
/* Make sure that we always have enough lookahead. This is important
|
||||
* if input comes from a device such as a tty.
|
||||
*/
|
||||
while (lookahead < MIN_LOOKAHEAD && !eofile) fill_window();
|
||||
|
||||
ins_h = 0;
|
||||
for (j=0; j<MIN_MATCH-1; j++) UPDATE_HASH(ins_h, window[j]);
|
||||
/* If lookahead < MIN_MATCH, ins_h is garbage, but this is
|
||||
* not important since only literal bytes will be emitted.
|
||||
*/
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Set match_start to the longest match starting at the given string and
|
||||
* return its length. Matches shorter or equal to prev_length are discarded,
|
||||
* in which case the result is equal to prev_length and match_start is
|
||||
* garbage.
|
||||
* IN assertions: cur_match is the head of the hash chain for the current
|
||||
* string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
|
||||
*/
|
||||
#ifndef ASMV
|
||||
/* For MSDOS, OS/2 and 386 Unix, an optimized version is in match.asm or
|
||||
* match.s. The code is functionally equivalent, so you can use the C version
|
||||
* if desired.
|
||||
*/
|
||||
int longest_match(cur_match)
|
||||
IPos cur_match; /* current match */
|
||||
{
|
||||
unsigned chain_length = max_chain_length; /* max hash chain length */
|
||||
register uch *scan = window + strstart; /* current string */
|
||||
register uch *match; /* matched string */
|
||||
register int len; /* length of current match */
|
||||
int best_len = prev_length; /* best match length so far */
|
||||
IPos limit = strstart > (IPos)MAX_DIST ? strstart - (IPos)MAX_DIST : NIL;
|
||||
/* Stop when cur_match becomes <= limit. To simplify the code,
|
||||
* we prevent matches with the string of window index 0.
|
||||
*/
|
||||
|
||||
/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
|
||||
* It is easy to get rid of this optimization if necessary.
|
||||
*/
|
||||
#if HASH_BITS < 8 || MAX_MATCH != 258
|
||||
error: Code too clever
|
||||
#endif
|
||||
|
||||
#ifdef UNALIGNED_OK
|
||||
/* Compare two bytes at a time. Note: this is not always beneficial.
|
||||
* Try with and without -DUNALIGNED_OK to check.
|
||||
*/
|
||||
register uch *strend = window + strstart + MAX_MATCH - 1;
|
||||
register ush scan_start = *(ush*)scan;
|
||||
register ush scan_end = *(ush*)(scan+best_len-1);
|
||||
#else
|
||||
register uch *strend = window + strstart + MAX_MATCH;
|
||||
register uch scan_end1 = scan[best_len-1];
|
||||
register uch scan_end = scan[best_len];
|
||||
#endif
|
||||
|
||||
/* Do not waste too much time if we already have a good match: */
|
||||
if (prev_length >= good_match) {
|
||||
chain_length >>= 2;
|
||||
}
|
||||
Assert(strstart <= window_size-MIN_LOOKAHEAD, "insufficient lookahead");
|
||||
|
||||
do {
|
||||
Assert(cur_match < strstart, "no future");
|
||||
match = window + cur_match;
|
||||
|
||||
/* Skip to next match if the match length cannot increase
|
||||
* or if the match length is less than 2:
|
||||
*/
|
||||
#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
|
||||
/* This code assumes sizeof(unsigned short) == 2. Do not use
|
||||
* UNALIGNED_OK if your compiler uses a different size.
|
||||
*/
|
||||
if (*(ush*)(match+best_len-1) != scan_end ||
|
||||
*(ush*)match != scan_start) continue;
|
||||
|
||||
/* It is not necessary to compare scan[2] and match[2] since they are
|
||||
* always equal when the other bytes match, given that the hash keys
|
||||
* are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
|
||||
* strstart+3, +5, ... up to strstart+257. We check for insufficient
|
||||
* lookahead only every 4th comparison; the 128th check will be made
|
||||
* at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
|
||||
* necessary to put more guard bytes at the end of the window, or
|
||||
* to check more often for insufficient lookahead.
|
||||
*/
|
||||
scan++, match++;
|
||||
do {
|
||||
} while (*(ush*)(scan+=2) == *(ush*)(match+=2) &&
|
||||
*(ush*)(scan+=2) == *(ush*)(match+=2) &&
|
||||
*(ush*)(scan+=2) == *(ush*)(match+=2) &&
|
||||
*(ush*)(scan+=2) == *(ush*)(match+=2) &&
|
||||
scan < strend);
|
||||
/* The funny "do {}" generates better code on most compilers */
|
||||
|
||||
/* Here, scan <= window+strstart+257 */
|
||||
Assert(scan <= window+(unsigned)(window_size-1), "wild scan");
|
||||
if (*scan == *match) scan++;
|
||||
|
||||
len = (MAX_MATCH - 1) - (int)(strend-scan);
|
||||
scan = strend - (MAX_MATCH-1);
|
||||
|
||||
#else /* UNALIGNED_OK */
|
||||
|
||||
if (match[best_len] != scan_end ||
|
||||
match[best_len-1] != scan_end1 ||
|
||||
*match != *scan ||
|
||||
*++match != scan[1]) continue;
|
||||
|
||||
/* The check at best_len-1 can be removed because it will be made
|
||||
* again later. (This heuristic is not always a win.)
|
||||
* It is not necessary to compare scan[2] and match[2] since they
|
||||
* are always equal when the other bytes match, given that
|
||||
* the hash keys are equal and that HASH_BITS >= 8.
|
||||
*/
|
||||
scan += 2, match++;
|
||||
|
||||
/* We check for insufficient lookahead only every 8th comparison;
|
||||
* the 256th check will be made at strstart+258.
|
||||
*/
|
||||
do {
|
||||
} while (*++scan == *++match && *++scan == *++match &&
|
||||
*++scan == *++match && *++scan == *++match &&
|
||||
*++scan == *++match && *++scan == *++match &&
|
||||
*++scan == *++match && *++scan == *++match &&
|
||||
scan < strend);
|
||||
|
||||
len = MAX_MATCH - (int)(strend - scan);
|
||||
scan = strend - MAX_MATCH;
|
||||
|
||||
#endif /* UNALIGNED_OK */
|
||||
|
||||
if (len > best_len) {
|
||||
match_start = cur_match;
|
||||
best_len = len;
|
||||
if (len >= nice_match) break;
|
||||
#ifdef UNALIGNED_OK
|
||||
scan_end = *(ush*)(scan+best_len-1);
|
||||
#else
|
||||
scan_end1 = scan[best_len-1];
|
||||
scan_end = scan[best_len];
|
||||
#endif
|
||||
}
|
||||
} while ((cur_match = prev[cur_match & WMASK]) > limit
|
||||
&& --chain_length != 0);
|
||||
|
||||
return best_len;
|
||||
}
|
||||
#endif /* ASMV */
|
||||
|
||||
#ifdef DEBUG
|
||||
/* ===========================================================================
|
||||
* Check that the match at match_start is indeed a match.
|
||||
*/
|
||||
local void check_match(start, match, length)
|
||||
IPos start, match;
|
||||
int length;
|
||||
{
|
||||
/* check that the match is indeed a match */
|
||||
if (memcmp((char*)window + match,
|
||||
(char*)window + start, length) != EQUAL) {
|
||||
fprintf(stderr,
|
||||
" start %d, match %d, length %d\n",
|
||||
start, match, length);
|
||||
error("invalid match");
|
||||
}
|
||||
if (verbose > 1) {
|
||||
fprintf(stderr,"\\[%d,%d]", start-match, length);
|
||||
do { putc(window[start++], stderr); } while (--length != 0);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define check_match(start, match, length)
|
||||
#endif
|
||||
|
||||
/* ===========================================================================
|
||||
* Fill the window when the lookahead becomes insufficient.
|
||||
* Updates strstart and lookahead, and sets eofile if end of input file.
|
||||
* IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0
|
||||
* OUT assertions: at least one byte has been read, or eofile is set;
|
||||
* file reads are performed for at least two bytes (required for the
|
||||
* translate_eol option).
|
||||
*/
|
||||
local void fill_window()
|
||||
{
|
||||
register unsigned n, m;
|
||||
unsigned more = (unsigned)(window_size - (ulg)lookahead - (ulg)strstart);
|
||||
/* Amount of free space at the end of the window. */
|
||||
|
||||
/* If the window is almost full and there is insufficient lookahead,
|
||||
* move the upper half to the lower one to make room in the upper half.
|
||||
*/
|
||||
if (more == (unsigned)EOF) {
|
||||
/* Very unlikely, but possible on 16 bit machine if strstart == 0
|
||||
* and lookahead == 1 (input done one byte at time)
|
||||
*/
|
||||
more--;
|
||||
} else if (strstart >= WSIZE+MAX_DIST) {
|
||||
/* By the IN assertion, the window is not empty so we can't confuse
|
||||
* more == 0 with more == 64K on a 16 bit machine.
|
||||
*/
|
||||
Assert(window_size == (ulg)2*WSIZE, "no sliding with BIG_MEM");
|
||||
|
||||
memcpy((char*)window, (char*)window+WSIZE, (unsigned)WSIZE);
|
||||
match_start -= WSIZE;
|
||||
strstart -= WSIZE; /* we now have strstart >= MAX_DIST: */
|
||||
|
||||
block_start -= (long) WSIZE;
|
||||
|
||||
for (n = 0; n < HASH_SIZE; n++) {
|
||||
m = head[n];
|
||||
head[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL);
|
||||
}
|
||||
for (n = 0; n < WSIZE; n++) {
|
||||
m = prev[n];
|
||||
prev[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL);
|
||||
/* If n is not on any hash chain, prev[n] is garbage but
|
||||
* its value will never be used.
|
||||
*/
|
||||
}
|
||||
more += WSIZE;
|
||||
}
|
||||
/* At this point, more >= 2 */
|
||||
if (!eofile) {
|
||||
n = read_buf((char*)window+strstart+lookahead, more);
|
||||
if (n == 0 || n == (unsigned)EOF) {
|
||||
eofile = 1;
|
||||
} else {
|
||||
lookahead += n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Flush the current block, with given end-of-file flag.
|
||||
* IN assertion: strstart is set to the end of the current match.
|
||||
*/
|
||||
#define FLUSH_BLOCK(eof) \
|
||||
flush_block(block_start >= 0L ? (char*)&window[(unsigned)block_start] : \
|
||||
(char*)NULL, (long)strstart - block_start, (eof))
|
||||
|
||||
/* ===========================================================================
|
||||
* Processes a new input file and return its compressed length.
|
||||
*/
|
||||
#ifdef NO_LAZY
|
||||
ulg deflate()
|
||||
{
|
||||
IPos hash_head; /* head of the hash chain */
|
||||
int flush; /* set if current block must be flushed */
|
||||
unsigned match_length = 0; /* length of best match */
|
||||
|
||||
prev_length = MIN_MATCH-1;
|
||||
while (lookahead != 0) {
|
||||
/* Insert the string window[strstart .. strstart+2] in the
|
||||
* dictionary, and set hash_head to the head of the hash chain:
|
||||
*/
|
||||
INSERT_STRING(strstart, hash_head);
|
||||
|
||||
/* Find the longest match, discarding those <= prev_length.
|
||||
* At this point we have always match_length < MIN_MATCH
|
||||
*/
|
||||
if (hash_head != NIL && strstart - hash_head <= MAX_DIST) {
|
||||
/* To simplify the code, we prevent matches with the string
|
||||
* of window index 0 (in particular we have to avoid a match
|
||||
* of the string with itself at the start of the input file).
|
||||
*/
|
||||
match_length = longest_match (hash_head);
|
||||
/* longest_match() sets match_start */
|
||||
if (match_length > lookahead) match_length = lookahead;
|
||||
}
|
||||
if (match_length >= MIN_MATCH) {
|
||||
check_match(strstart, match_start, match_length);
|
||||
|
||||
flush = ct_tally(strstart-match_start, match_length - MIN_MATCH);
|
||||
|
||||
lookahead -= match_length;
|
||||
match_length--; /* string at strstart already in hash table */
|
||||
do {
|
||||
strstart++;
|
||||
INSERT_STRING(strstart, hash_head);
|
||||
/* strstart never exceeds WSIZE-MAX_MATCH, so there are
|
||||
* always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
|
||||
* these bytes are garbage, but it does not matter since the
|
||||
* next lookahead bytes will always be emitted as literals.
|
||||
*/
|
||||
} while (--match_length != 0);
|
||||
} else {
|
||||
/* No match, output a literal byte */
|
||||
flush = ct_tally (0, window[strstart]);
|
||||
lookahead--;
|
||||
}
|
||||
strstart++;
|
||||
if (flush) FLUSH_BLOCK(0), block_start = strstart;
|
||||
|
||||
/* Make sure that we always have enough lookahead, except
|
||||
* at the end of the input file. We need MAX_MATCH bytes
|
||||
* for the next match, plus MIN_MATCH bytes to insert the
|
||||
* string following the next match.
|
||||
*/
|
||||
while (lookahead < MIN_LOOKAHEAD && !eofile) fill_window();
|
||||
|
||||
}
|
||||
return FLUSH_BLOCK(1); /* eof */
|
||||
}
|
||||
#else /* LAZY */
|
||||
/* ===========================================================================
|
||||
* Same as above, but achieves better compression. We use a lazy
|
||||
* evaluation for matches: a match is finally adopted only if there is
|
||||
* no better match at the next window position.
|
||||
*/
|
||||
ulg deflate()
|
||||
{
|
||||
IPos hash_head; /* head of hash chain */
|
||||
IPos prev_match; /* previous match */
|
||||
int flush; /* set if current block must be flushed */
|
||||
int match_available = 0; /* set if previous match exists */
|
||||
register unsigned match_length = MIN_MATCH-1; /* length of best match */
|
||||
#ifdef DEBUG
|
||||
extern long isize; /* byte length of input file, for debug only */
|
||||
#endif
|
||||
|
||||
/* Process the input block. */
|
||||
while (lookahead != 0) {
|
||||
/* Insert the string window[strstart .. strstart+2] in the
|
||||
* dictionary, and set hash_head to the head of the hash chain:
|
||||
*/
|
||||
INSERT_STRING(strstart, hash_head);
|
||||
|
||||
/* Find the longest match, discarding those <= prev_length.
|
||||
*/
|
||||
prev_length = match_length, prev_match = match_start;
|
||||
match_length = MIN_MATCH-1;
|
||||
|
||||
if (hash_head != NIL && prev_length < max_lazy_match &&
|
||||
strstart - hash_head <= MAX_DIST) {
|
||||
/* To simplify the code, we prevent matches with the string
|
||||
* of window index 0 (in particular we have to avoid a match
|
||||
* of the string with itself at the start of the input file).
|
||||
*/
|
||||
match_length = longest_match (hash_head);
|
||||
/* longest_match() sets match_start */
|
||||
if (match_length > lookahead) match_length = lookahead;
|
||||
|
||||
/* Ignore a length 3 match if it is too distant: */
|
||||
if (match_length == MIN_MATCH && strstart-match_start > TOO_FAR){
|
||||
/* If prev_match is also MIN_MATCH, match_start is garbage
|
||||
* but we will ignore the current match anyway.
|
||||
*/
|
||||
match_length--;
|
||||
}
|
||||
}
|
||||
/* If there was a match at the previous step and the current
|
||||
* match is not better, output the previous match:
|
||||
*/
|
||||
if (prev_length >= MIN_MATCH && match_length <= prev_length) {
|
||||
|
||||
check_match(strstart-1, prev_match, prev_length);
|
||||
|
||||
flush = ct_tally(strstart-1-prev_match, prev_length - MIN_MATCH);
|
||||
|
||||
/* Insert in hash table all strings up to the end of the match.
|
||||
* strstart-1 and strstart are already inserted.
|
||||
*/
|
||||
lookahead -= prev_length-1;
|
||||
prev_length -= 2;
|
||||
do {
|
||||
strstart++;
|
||||
INSERT_STRING(strstart, hash_head);
|
||||
/* strstart never exceeds WSIZE-MAX_MATCH, so there are
|
||||
* always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
|
||||
* these bytes are garbage, but it does not matter since the
|
||||
* next lookahead bytes will always be emitted as literals.
|
||||
*/
|
||||
} while (--prev_length != 0);
|
||||
match_available = 0;
|
||||
match_length = MIN_MATCH-1;
|
||||
strstart++;
|
||||
if (flush) FLUSH_BLOCK(0), block_start = strstart;
|
||||
|
||||
} else if (match_available) {
|
||||
/* If there was no match at the previous position, output a
|
||||
* single literal. If there was a match but the current match
|
||||
* is longer, truncate the previous match to a single literal.
|
||||
*/
|
||||
Tracevv((stderr,"%c",window[strstart-1]));
|
||||
if (ct_tally (0, window[strstart-1])) {
|
||||
FLUSH_BLOCK(0), block_start = strstart;
|
||||
}
|
||||
strstart++;
|
||||
lookahead--;
|
||||
} else {
|
||||
/* There is no previous match to compare with, wait for
|
||||
* the next step to decide.
|
||||
*/
|
||||
match_available = 1;
|
||||
strstart++;
|
||||
lookahead--;
|
||||
}
|
||||
Assert (strstart <= isize && lookahead <= isize, "a bit too far");
|
||||
|
||||
/* Make sure that we always have enough lookahead, except
|
||||
* at the end of the input file. We need MAX_MATCH bytes
|
||||
* for the next match, plus MIN_MATCH bytes to insert the
|
||||
* string following the next match.
|
||||
*/
|
||||
while (lookahead < MIN_LOOKAHEAD && !eofile) fill_window();
|
||||
}
|
||||
if (match_available) ct_tally (0, window[strstart-1]);
|
||||
|
||||
return FLUSH_BLOCK(1); /* eof */
|
||||
}
|
||||
#endif /* LAZY */
|
711
gnu/usr.bin/gzip/getopt.c
Normal file
711
gnu/usr.bin/gzip/getopt.c
Normal file
@ -0,0 +1,711 @@
|
||||
/* Getopt for GNU.
|
||||
NOTE: getopt is now part of the C library, so if you don't know what
|
||||
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
|
||||
before changing it!
|
||||
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* AIX requires this to be the first thing in the file. */
|
||||
#ifdef __GNUC__
|
||||
#define alloca __builtin_alloca
|
||||
#else /* not __GNUC__ */
|
||||
#if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__))))
|
||||
#include <alloca.h>
|
||||
#else
|
||||
#ifdef _AIX
|
||||
#pragma alloca
|
||||
#else
|
||||
char *alloca ();
|
||||
#endif
|
||||
#endif /* alloca.h */
|
||||
#endif /* not __GNUC__ */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(USG) || defined(STDC_HEADERS) || defined(__GNU_LIBRARY__)
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#undef alloca
|
||||
/* Don't include stdlib.h for non-GNU C libraries because some of them
|
||||
contain conflicting prototypes for getopt. */
|
||||
#include <stdlib.h>
|
||||
#else /* Not GNU C library. */
|
||||
#define __alloca alloca
|
||||
#endif /* GNU C library. */
|
||||
|
||||
#if !__STDC__
|
||||
#define const
|
||||
#endif
|
||||
|
||||
/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
|
||||
long-named option. Because this is not POSIX.2 compliant, it is
|
||||
being phased out. */
|
||||
#define GETOPT_COMPAT
|
||||
|
||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||
but it behaves differently for the user, since it allows the user
|
||||
to intersperse the options with the other arguments.
|
||||
|
||||
As `getopt' works, it permutes the elements of ARGV so that,
|
||||
when it is done, all the options precede everything else. Thus
|
||||
all application programs are extended to handle flexible argument order.
|
||||
|
||||
Setting the environment variable POSIXLY_CORRECT disables permutation.
|
||||
Then the behavior is completely standard.
|
||||
|
||||
GNU application programs can use a third alternative mode in which
|
||||
they can distinguish the relative order of options and other arguments. */
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
char *optarg = 0;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
int optind = 0;
|
||||
|
||||
/* The next char to be scanned in the option-element
|
||||
in which the last option character we returned was found.
|
||||
This allows us to pick up the scan where we left off.
|
||||
|
||||
If this is zero, or a null string, it means resume the scan
|
||||
by advancing to the next ARGV-element. */
|
||||
|
||||
static char *nextchar;
|
||||
|
||||
/* Callers store zero here to inhibit the error message
|
||||
for unrecognized options. */
|
||||
|
||||
int opterr = 1;
|
||||
|
||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
||||
|
||||
If the caller did not specify anything,
|
||||
the default is REQUIRE_ORDER if the environment variable
|
||||
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
||||
|
||||
REQUIRE_ORDER means don't recognize them as options;
|
||||
stop option processing when the first non-option is seen.
|
||||
This is what Unix does.
|
||||
This mode of operation is selected by either setting the environment
|
||||
variable POSIXLY_CORRECT, or using `+' as the first character
|
||||
of the list of option characters.
|
||||
|
||||
PERMUTE is the default. We permute the contents of ARGV as we scan,
|
||||
so that eventually all the non-options are at the end. This allows options
|
||||
to be given in any order, even with programs that were not written to
|
||||
expect this.
|
||||
|
||||
RETURN_IN_ORDER is an option available to programs that were written
|
||||
to expect options and other ARGV-elements in any order and that care about
|
||||
the ordering of the two. We describe each non-option ARGV-element
|
||||
as if it were the argument of an option with character code 1.
|
||||
Using `-' as the first character of the list of option characters
|
||||
selects this mode of operation.
|
||||
|
||||
The special argument `--' forces an end of option-scanning regardless
|
||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
|
||||
|
||||
static enum
|
||||
{
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
} ordering;
|
||||
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#include <string.h>
|
||||
#define my_index strchr
|
||||
#define my_bcopy(src, dst, n) memcpy ((dst), (src), (n))
|
||||
#else
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
whose names are inconsistent. */
|
||||
|
||||
char *getenv ();
|
||||
|
||||
static char *
|
||||
my_index (string, chr)
|
||||
char *string;
|
||||
int chr;
|
||||
{
|
||||
while (*string)
|
||||
{
|
||||
if (*string == chr)
|
||||
return string;
|
||||
string++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
my_bcopy (from, to, size)
|
||||
char *from, *to;
|
||||
int size;
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < size; i++)
|
||||
to[i] = from[i];
|
||||
}
|
||||
#endif /* GNU C library. */
|
||||
|
||||
/* Handle permutation of arguments. */
|
||||
|
||||
/* Describe the part of ARGV that contains non-options that have
|
||||
been skipped. `first_nonopt' is the index in ARGV of the first of them;
|
||||
`last_nonopt' is the index after the last of them. */
|
||||
|
||||
static int first_nonopt;
|
||||
static int last_nonopt;
|
||||
|
||||
/* Exchange two adjacent subsequences of ARGV.
|
||||
One subsequence is elements [first_nonopt,last_nonopt)
|
||||
which contains all the non-options that have been skipped so far.
|
||||
The other is elements [last_nonopt,optind), which contains all
|
||||
the options processed since those non-options were skipped.
|
||||
|
||||
`first_nonopt' and `last_nonopt' are relocated so that they describe
|
||||
the new indices of the non-options in ARGV after they are moved. */
|
||||
|
||||
static void
|
||||
exchange (argv)
|
||||
char **argv;
|
||||
{
|
||||
int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
|
||||
#ifdef _CRAY
|
||||
char *temp[last_nonopt - first_nonopt];
|
||||
#else
|
||||
char **temp = (char **) __alloca (nonopts_size);
|
||||
#endif
|
||||
|
||||
/* Interchange the two blocks of data in ARGV. */
|
||||
|
||||
my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size);
|
||||
my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt],
|
||||
(optind - last_nonopt) * sizeof (char *));
|
||||
my_bcopy ((char *) temp,
|
||||
(char *) &argv[first_nonopt + optind - last_nonopt],
|
||||
nonopts_size);
|
||||
|
||||
/* Update records for the slots the non-options now occupy. */
|
||||
|
||||
first_nonopt += (optind - last_nonopt);
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||
given in OPTSTRING.
|
||||
|
||||
If an element of ARGV starts with '-', and is not exactly "-" or "--",
|
||||
then it is an option element. The characters of this element
|
||||
(aside from the initial '-') are option characters. If `getopt'
|
||||
is called repeatedly, it returns successively each of the option characters
|
||||
from each of the option elements.
|
||||
|
||||
If `getopt' finds another option character, it returns that character,
|
||||
updating `optind' and `nextchar' so that the next call to `getopt' can
|
||||
resume the scan with the following option character or ARGV-element.
|
||||
|
||||
If there are no more option characters, `getopt' returns `EOF'.
|
||||
Then `optind' is the index in ARGV of the first ARGV-element
|
||||
that is not an option. (The ARGV-elements have been permuted
|
||||
so that those that are not options now come last.)
|
||||
|
||||
OPTSTRING is a string containing the legitimate option characters.
|
||||
If an option character is seen that is not listed in OPTSTRING,
|
||||
return '?' after printing an error message. If you set `opterr' to
|
||||
zero, the error message is suppressed but we still return '?'.
|
||||
|
||||
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
|
||||
so the following text in the same ARGV-element, or the text of the following
|
||||
ARGV-element, is returned in `optarg'. Two colons mean an option that
|
||||
wants an optional arg; if there is text in the current ARGV-element,
|
||||
it is returned in `optarg', otherwise `optarg' is set to zero.
|
||||
|
||||
If OPTSTRING starts with `-' or `+', it requests different methods of
|
||||
handling the non-option ARGV-elements.
|
||||
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
|
||||
|
||||
Long-named options begin with `--' instead of `-'.
|
||||
Their names may be abbreviated as long as the abbreviation is unique
|
||||
or is an exact match for some defined option. If they have an
|
||||
argument, it follows the option name in the same ARGV-element, separated
|
||||
from the option name by a `=', or else the in next ARGV-element.
|
||||
When `getopt' finds a long-named option, it returns 0 if that option's
|
||||
`flag' field is nonzero, the value of the option's `val' field
|
||||
if the `flag' field is zero.
|
||||
|
||||
The elements of ARGV aren't really const, because we permute them.
|
||||
But we pretend they're const in the prototype to be compatible
|
||||
with other systems.
|
||||
|
||||
LONGOPTS is a vector of `struct option' terminated by an
|
||||
element containing a name which is zero.
|
||||
|
||||
LONGIND returns the index in LONGOPT of the long-named option found.
|
||||
It is only valid when a long-named option has been found by the most
|
||||
recent call.
|
||||
|
||||
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
|
||||
long-named options. */
|
||||
|
||||
int
|
||||
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
const struct option *longopts;
|
||||
int *longind;
|
||||
int long_only;
|
||||
{
|
||||
int option_index;
|
||||
|
||||
optarg = 0;
|
||||
|
||||
/* Initialize the internal data when the first call is made.
|
||||
Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
|
||||
if (optind == 0)
|
||||
{
|
||||
first_nonopt = last_nonopt = optind = 1;
|
||||
|
||||
nextchar = NULL;
|
||||
|
||||
/* Determine how to handle the ordering of options and nonoptions. */
|
||||
|
||||
if (optstring[0] == '-')
|
||||
{
|
||||
ordering = RETURN_IN_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (optstring[0] == '+')
|
||||
{
|
||||
ordering = REQUIRE_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (getenv ("POSIXLY_CORRECT") != NULL)
|
||||
ordering = REQUIRE_ORDER;
|
||||
else
|
||||
ordering = PERMUTE;
|
||||
}
|
||||
|
||||
if (nextchar == NULL || *nextchar == '\0')
|
||||
{
|
||||
if (ordering == PERMUTE)
|
||||
{
|
||||
/* If we have just processed some options following some non-options,
|
||||
exchange them so that the options come first. */
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (last_nonopt != optind)
|
||||
first_nonopt = optind;
|
||||
|
||||
/* Now skip any additional non-options
|
||||
and extend the range of non-options previously skipped. */
|
||||
|
||||
while (optind < argc
|
||||
&& (argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
#ifdef GETOPT_COMPAT
|
||||
&& (longopts == NULL
|
||||
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
||||
#endif /* GETOPT_COMPAT */
|
||||
)
|
||||
optind++;
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* Special ARGV-element `--' means premature end of options.
|
||||
Skip it like a null option,
|
||||
then exchange with previous non-options as if it were an option,
|
||||
then skip everything else like a non-option. */
|
||||
|
||||
if (optind != argc && !strcmp (argv[optind], "--"))
|
||||
{
|
||||
optind++;
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (first_nonopt == last_nonopt)
|
||||
first_nonopt = optind;
|
||||
last_nonopt = argc;
|
||||
|
||||
optind = argc;
|
||||
}
|
||||
|
||||
/* If we have done all the ARGV-elements, stop the scan
|
||||
and back over any non-options that we skipped and permuted. */
|
||||
|
||||
if (optind == argc)
|
||||
{
|
||||
/* Set the next-arg-index to point at the non-options
|
||||
that we previously skipped, so the caller will digest them. */
|
||||
if (first_nonopt != last_nonopt)
|
||||
optind = first_nonopt;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* If we have come to a non-option and did not permute it,
|
||||
either stop the scan or describe it to the caller and pass it by. */
|
||||
|
||||
if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
#ifdef GETOPT_COMPAT
|
||||
&& (longopts == NULL
|
||||
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
||||
#endif /* GETOPT_COMPAT */
|
||||
)
|
||||
{
|
||||
if (ordering == REQUIRE_ORDER)
|
||||
return EOF;
|
||||
optarg = argv[optind++];
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We have found another option-ARGV-element.
|
||||
Start decoding its characters. */
|
||||
|
||||
nextchar = (argv[optind] + 1
|
||||
+ (longopts != NULL && argv[optind][1] == '-'));
|
||||
}
|
||||
|
||||
if (longopts != NULL
|
||||
&& ((argv[optind][0] == '-'
|
||||
&& (argv[optind][1] == '-' || long_only))
|
||||
#ifdef GETOPT_COMPAT
|
||||
|| argv[optind][0] == '+'
|
||||
#endif /* GETOPT_COMPAT */
|
||||
))
|
||||
{
|
||||
const struct option *p;
|
||||
char *s = nextchar;
|
||||
int exact = 0;
|
||||
int ambig = 0;
|
||||
const struct option *pfound = NULL;
|
||||
int indfound = 0;
|
||||
|
||||
while (*s && *s != '=')
|
||||
s++;
|
||||
|
||||
/* Test all options for either exact match or abbreviated matches. */
|
||||
for (p = longopts, option_index = 0; p->name;
|
||||
p++, option_index++)
|
||||
if (!strncmp (p->name, nextchar, s - nextchar))
|
||||
{
|
||||
if (s - nextchar == strlen (p->name))
|
||||
{
|
||||
/* Exact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
exact = 1;
|
||||
break;
|
||||
}
|
||||
else if (pfound == NULL)
|
||||
{
|
||||
/* First nonexact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
}
|
||||
else
|
||||
/* Second nonexact match found. */
|
||||
ambig = 1;
|
||||
}
|
||||
|
||||
if (ambig && !exact)
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `%s' is ambiguous\n",
|
||||
argv[0], argv[optind]);
|
||||
nextchar += strlen (nextchar);
|
||||
optind++;
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (pfound != NULL)
|
||||
{
|
||||
option_index = indfound;
|
||||
optind++;
|
||||
if (*s)
|
||||
{
|
||||
/* Don't test has_arg with >, because some C compilers don't
|
||||
allow it to be used on enums. */
|
||||
if (pfound->has_arg)
|
||||
optarg = s + 1;
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (argv[optind - 1][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr,
|
||||
"%s: option `--%s' doesn't allow an argument\n",
|
||||
argv[0], pfound->name);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr,
|
||||
"%s: option `%c%s' doesn't allow an argument\n",
|
||||
argv[0], argv[optind - 1][0], pfound->name);
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
else if (pfound->has_arg == 1)
|
||||
{
|
||||
if (optind < argc)
|
||||
optarg = argv[optind++];
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `%s' requires an argument\n",
|
||||
argv[0], argv[optind - 1]);
|
||||
nextchar += strlen (nextchar);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
if (longind != NULL)
|
||||
*longind = option_index;
|
||||
if (pfound->flag)
|
||||
{
|
||||
*(pfound->flag) = pfound->val;
|
||||
return 0;
|
||||
}
|
||||
return pfound->val;
|
||||
}
|
||||
/* Can't find it as a long option. If this is not getopt_long_only,
|
||||
or the option starts with '--' or is not a valid short
|
||||
option, then it's an error.
|
||||
Otherwise interpret it as a short option. */
|
||||
if (!long_only || argv[optind][1] == '-'
|
||||
#ifdef GETOPT_COMPAT
|
||||
|| argv[optind][0] == '+'
|
||||
#endif /* GETOPT_COMPAT */
|
||||
|| my_index ((char*)optstring, *nextchar) == NULL)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (argv[optind][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr, "%s: unrecognized option `--%s'\n",
|
||||
argv[0], nextchar);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
|
||||
argv[0], argv[optind][0], nextchar);
|
||||
}
|
||||
nextchar = (char *) "";
|
||||
optind++;
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
/* Look at and handle the next option-character. */
|
||||
|
||||
{
|
||||
char c = *nextchar++;
|
||||
char *temp = my_index ((char*)optstring, c);
|
||||
|
||||
/* Increment `optind' when we start to process its last character. */
|
||||
if (*nextchar == '\0')
|
||||
++optind;
|
||||
|
||||
if (temp == NULL || c == ':')
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (c < 040 || c >= 0177)
|
||||
fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
|
||||
argv[0], c);
|
||||
else
|
||||
fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
|
||||
}
|
||||
return '?';
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (temp[2] == ':')
|
||||
{
|
||||
/* This is an option that accepts an argument optionally. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
optind++;
|
||||
}
|
||||
else
|
||||
optarg = 0;
|
||||
nextchar = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
/* If we end this ARGV-element by taking the rest as an arg,
|
||||
we must advance to the next element now. */
|
||||
optind++;
|
||||
}
|
||||
else if (optind == argc)
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `-%c' requires an argument\n",
|
||||
argv[0], c);
|
||||
c = '?';
|
||||
}
|
||||
else
|
||||
/* We already incremented `optind' once;
|
||||
increment it again when taking next ARGV-elt as argument. */
|
||||
optarg = argv[optind++];
|
||||
nextchar = NULL;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
getopt (argc, argv, optstring)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
{
|
||||
return _getopt_internal (argc, argv, optstring,
|
||||
(const struct option *) 0,
|
||||
(int *) 0,
|
||||
0);
|
||||
}
|
||||
|
||||
int
|
||||
getopt_long (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
|
||||
If an option that starts with '-' (not '--') doesn't match a long option,
|
||||
but does match a short option, it is parsed as a short option
|
||||
instead. */
|
||||
|
||||
int
|
||||
getopt_long_only (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/* Compile with -DTEST to make an executable for use in testing
|
||||
the above definition of `getopt'. */
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
|
||||
c = getopt (argc, argv, "abc:d:0123456789");
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
128
gnu/usr.bin/gzip/getopt.h
Normal file
128
gnu/usr.bin/gzip/getopt.h
Normal file
@ -0,0 +1,128 @@
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
#define _GETOPT_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
extern char *optarg;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int optind;
|
||||
|
||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||
for unrecognized options. */
|
||||
|
||||
extern int opterr;
|
||||
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||
of `struct option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
no_argument (or 0) if the option does not take an argument,
|
||||
required_argument (or 1) if the option requires an argument,
|
||||
optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
To have a long-named option do something other than set an `int' to
|
||||
a compiled-in constant, such as set a value from `optarg', set the
|
||||
option's `flag' field to zero and its `val' field to a nonzero
|
||||
value (the equivalent single-letter option character, if there is
|
||||
one). For long options that have a zero `flag' field, `getopt'
|
||||
returns the contents of the `val' field. */
|
||||
|
||||
struct option
|
||||
{
|
||||
#if __STDC__
|
||||
const char *name;
|
||||
#else
|
||||
char *name;
|
||||
#endif
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||
|
||||
enum _argtype
|
||||
{
|
||||
no_argument,
|
||||
required_argument,
|
||||
optional_argument
|
||||
};
|
||||
|
||||
#if __STDC__ || defined(PROTO)
|
||||
#if defined(__GNU_LIBRARY__)
|
||||
/* Many other libraries have conflicting prototypes for getopt, with
|
||||
differences in the consts, in stdlib.h. To avoid compilation
|
||||
errors, only prototype getopt for the GNU C library. */
|
||||
extern int getopt (int argc, char *const *argv, const char *shortopts);
|
||||
#else /* not __GNU_LIBRARY__ */
|
||||
extern int getopt ();
|
||||
#endif /* not __GNU_LIBRARY__ */
|
||||
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
extern int getopt_long_only (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
|
||||
/* Internal only. Users should not call this directly. */
|
||||
extern int _getopt_internal (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind,
|
||||
int long_only);
|
||||
#else /* not __STDC__ */
|
||||
extern int getopt ();
|
||||
extern int getopt_long ();
|
||||
extern int getopt_long_only ();
|
||||
|
||||
extern int _getopt_internal ();
|
||||
#endif /* not __STDC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GETOPT_H */
|
134
gnu/usr.bin/gzip/gzexe
Normal file
134
gnu/usr.bin/gzip/gzexe
Normal file
@ -0,0 +1,134 @@
|
||||
#!/bin/sh
|
||||
# gzexe: compressor for Unix executables.
|
||||
# Use this only for binaries that you do not use frequently.
|
||||
#
|
||||
# The compressed version is a shell script which decompresses itself after
|
||||
# skipping $skip lines of shell commands. We try invoking the compressed
|
||||
# executable with the original name (for programs looking at their name).
|
||||
# We also try to retain the original file permissions on the compressed file.
|
||||
# For safety reasons, gzexe will not create setuid or setgid shell scripts.
|
||||
|
||||
# Warning: the first line of this file must be either : or #!/bin/sh
|
||||
# The : is required for some old versions of csh.
|
||||
|
||||
x=`basename $0`
|
||||
if test $# = 0; then
|
||||
echo compress executables. original file foo is renamed to foo~
|
||||
echo usage: ${x} [-d] files...
|
||||
echo " -d decompress the executables"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tmp=gz$$
|
||||
trap "rm -f $tmp; exit 1" 1 2 3 5 10 13 15
|
||||
|
||||
decomp=0
|
||||
res=0
|
||||
test "$x" = "ungzexe" && decomp=1
|
||||
if test "x$1" = "x-d"; then
|
||||
decomp=1
|
||||
shift
|
||||
fi
|
||||
|
||||
echo hi > zfoo1$$
|
||||
echo hi > zfoo2$$
|
||||
if test -z "`(${CPMOD-cpmod} zfoo1$$ zfoo2$$) 2>&1`"; then
|
||||
cpmod=${CPMOD-cpmod}
|
||||
fi
|
||||
rm -f zfoo[12]$$
|
||||
|
||||
for i do
|
||||
if test ! -f "$i" ; then
|
||||
echo ${x}: $i not a file
|
||||
res=1
|
||||
continue
|
||||
fi
|
||||
if test $decomp -eq 0; then
|
||||
if sed -e 1d -e 2q "$i" | grep "^skip=[0-9]*$" >/dev/null; then
|
||||
echo "${x}: $i is already gzexe'd"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
if ls -l "$i" | grep '^...[sS]' > /dev/null; then
|
||||
echo "${x}: $i has setuid permission, unchanged"
|
||||
continue
|
||||
fi
|
||||
if ls -l "$i" | grep '^......[sS]' > /dev/null; then
|
||||
echo "${x}: $i has setgid permission, unchanged"
|
||||
continue
|
||||
fi
|
||||
if test "`basename $i`" = gzip; then
|
||||
echo "${x}: cannot compress gzip itself"
|
||||
continue
|
||||
fi
|
||||
if test -z "$cpmod"; then
|
||||
cp -p "$i" $tmp 2>/dev/null || cp "$i" $tmp
|
||||
if test -w $tmp 2>/dev/null; then
|
||||
writable=1
|
||||
else
|
||||
writable=0
|
||||
chmod u+w $tmp 2>/dev/null
|
||||
fi
|
||||
fi
|
||||
if test $decomp -eq 0; then
|
||||
sed 1q $0 > $tmp
|
||||
cat >> $tmp <<'EOF'
|
||||
skip=18
|
||||
if tail +$skip $0 | gzip -cd > /tmp/gztmp$$; then
|
||||
chmod 755 /tmp/gztmp$$
|
||||
prog="`basename $0`"
|
||||
if ln /tmp/gztmp$$ "/tmp/$prog" 2>/dev/null; then
|
||||
trap '/bin/rm -f /tmp/gztmp$$ "/tmp/$prog"; exit $res' 0
|
||||
(sleep 5; /bin/rm -f /tmp/gztmp$$ "/tmp/$prog") 2>/dev/null &
|
||||
/tmp/"$prog" ${1+"$@"}; res=$?
|
||||
else
|
||||
trap '/bin/rm -f /tmp/gztmp$$; exit $res' 0
|
||||
(sleep 5; /bin/rm -f /tmp/gztmp$$) 2>/dev/null &
|
||||
/tmp/gztmp$$ ${1+"$@"}; res=$?
|
||||
fi
|
||||
else
|
||||
echo Cannot decompress $0; exit 1
|
||||
fi; exit $res
|
||||
EOF
|
||||
gzip -cv9 "$i" >> $tmp || {
|
||||
/bin/rm -f $tmp
|
||||
echo ${x}: compression not possible for $i, file unchanged.
|
||||
res=1
|
||||
continue
|
||||
}
|
||||
|
||||
else
|
||||
# decompression
|
||||
skip=18
|
||||
if sed -e 1d -e 2q "$i" | grep "^skip=[0-9]*$" >/dev/null; then
|
||||
eval `sed -e 1d -e 2q "$i"`
|
||||
fi
|
||||
if tail +$skip "$i" | gzip -cd > $tmp; then
|
||||
:
|
||||
else
|
||||
echo ${x}: $i probably not in gzexe format, file unchanged.
|
||||
res=1
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
rm -f "$i~"
|
||||
mv "$i" "$i~" || {
|
||||
echo ${x}: cannot backup $i as $i~
|
||||
rm -f $tmp
|
||||
res=1
|
||||
continue
|
||||
}
|
||||
mv $tmp "$i" || cp -p $tmp "$i" 2>/dev/null || cp $tmp "$i" || {
|
||||
echo ${x}: cannot create $i
|
||||
rm -f $tmp
|
||||
res=1
|
||||
continue
|
||||
}
|
||||
rm -f $tmp
|
||||
if test -n "$cpmod"; then
|
||||
$cpmod "$i~" "$i" 2>/dev/null
|
||||
elif test $writable -eq 0; then
|
||||
chmod u-w $i 2>/dev/null
|
||||
fi
|
||||
done
|
||||
exit $res
|
36
gnu/usr.bin/gzip/gzexe.1
Normal file
36
gnu/usr.bin/gzip/gzexe.1
Normal file
@ -0,0 +1,36 @@
|
||||
.TH GZEXE 1
|
||||
.SH NAME
|
||||
gzexe \- compress executable files in place
|
||||
.SH SYNOPSIS
|
||||
.B gzexe
|
||||
[ name ... ]
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.I gzexe
|
||||
utility allows you to compress executables in place and have them
|
||||
automatically uncompress and execute when you run them (at a penalty
|
||||
in performance). For example if you execute ``gzexe /bin/cat'' it
|
||||
will create the following two files:
|
||||
.nf
|
||||
.br
|
||||
-r-xr-xr-x 1 root bin 9644 Feb 11 11:16 /bin/cat
|
||||
-r-xr-xr-x 1 bin bin 24576 Nov 23 13:21 /bin/cat~
|
||||
.fi
|
||||
/bin/cat~ is the original file and /bin/cat is the self-uncompressing
|
||||
executable file. You can remove /bin/cat~ once you are sure that
|
||||
/bin/cat works properly.
|
||||
.PP
|
||||
This utility is most useful on systems with very small disks.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-d
|
||||
Decompress the given executables instead of compressing them.
|
||||
.SH "SEE ALSO"
|
||||
gzip(1), znew(1), zmore(1), zcmp(1), zforce(1)
|
||||
.SH "BUGS"
|
||||
.I gzexe
|
||||
attempts to retain the original file attributes on the compressed executable,
|
||||
but you may have to fix them manually in some cases, using
|
||||
.I chmod
|
||||
or
|
||||
.I chown.
|
135
gnu/usr.bin/gzip/gzexe.in
Normal file
135
gnu/usr.bin/gzip/gzexe.in
Normal file
@ -0,0 +1,135 @@
|
||||
:
|
||||
#!/bin/sh
|
||||
# gzexe: compressor for Unix executables.
|
||||
# Use this only for binaries that you do not use frequently.
|
||||
#
|
||||
# The compressed version is a shell script which decompresses itself after
|
||||
# skipping $skip lines of shell commands. We try invoking the compressed
|
||||
# executable with the original name (for programs looking at their name).
|
||||
# We also try to retain the original file permissions on the compressed file.
|
||||
# For safety reasons, gzexe will not create setuid or setgid shell scripts.
|
||||
|
||||
# Warning: the first line of this file must be either : or #!/bin/sh
|
||||
# The : is required for some old versions of csh.
|
||||
|
||||
x=`basename $0`
|
||||
if test $# = 0; then
|
||||
echo compress executables. original file foo is renamed to foo~
|
||||
echo usage: ${x} [-d] files...
|
||||
echo " -d decompress the executables"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tmp=gz$$
|
||||
trap "rm -f $tmp; exit 1" 1 2 3 5 10 13 15
|
||||
|
||||
decomp=0
|
||||
res=0
|
||||
test "$x" = "ungzexe" && decomp=1
|
||||
if test "x$1" = "x-d"; then
|
||||
decomp=1
|
||||
shift
|
||||
fi
|
||||
|
||||
echo hi > zfoo1$$
|
||||
echo hi > zfoo2$$
|
||||
if test -z "`(${CPMOD-cpmod} zfoo1$$ zfoo2$$) 2>&1`"; then
|
||||
cpmod=${CPMOD-cpmod}
|
||||
fi
|
||||
rm -f zfoo[12]$$
|
||||
|
||||
for i do
|
||||
if test ! -f "$i" ; then
|
||||
echo ${x}: $i not a file
|
||||
res=1
|
||||
continue
|
||||
fi
|
||||
if test $decomp -eq 0; then
|
||||
if sed -e 1d -e 2q "$i" | grep "^skip=[0-9]*$" >/dev/null; then
|
||||
echo "${x}: $i is already gzexe'd"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
if ls -l "$i" | grep '^...[sS]' > /dev/null; then
|
||||
echo "${x}: $i has setuid permission, unchanged"
|
||||
continue
|
||||
fi
|
||||
if ls -l "$i" | grep '^......[sS]' > /dev/null; then
|
||||
echo "${x}: $i has setgid permission, unchanged"
|
||||
continue
|
||||
fi
|
||||
if test "`basename $i`" = gzip; then
|
||||
echo "${x}: cannot compress gzip itself"
|
||||
continue
|
||||
fi
|
||||
if test -z "$cpmod"; then
|
||||
cp -p "$i" $tmp 2>/dev/null || cp "$i" $tmp
|
||||
if test -w $tmp 2>/dev/null; then
|
||||
writable=1
|
||||
else
|
||||
writable=0
|
||||
chmod u+w $tmp 2>/dev/null
|
||||
fi
|
||||
fi
|
||||
if test $decomp -eq 0; then
|
||||
sed 1q $0 > $tmp
|
||||
cat >> $tmp <<'EOF'
|
||||
skip=18
|
||||
if tail +$skip $0 | gzip -cd > /tmp/gztmp$$; then
|
||||
chmod 755 /tmp/gztmp$$
|
||||
prog="`basename $0`"
|
||||
if ln /tmp/gztmp$$ "/tmp/$prog" 2>/dev/null; then
|
||||
trap '/bin/rm -f /tmp/gztmp$$ "/tmp/$prog"; exit $res' 0
|
||||
(sleep 5; /bin/rm -f /tmp/gztmp$$ "/tmp/$prog") 2>/dev/null &
|
||||
/tmp/"$prog" ${1+"$@"}; res=$?
|
||||
else
|
||||
trap '/bin/rm -f /tmp/gztmp$$; exit $res' 0
|
||||
(sleep 5; /bin/rm -f /tmp/gztmp$$) 2>/dev/null &
|
||||
/tmp/gztmp$$ ${1+"$@"}; res=$?
|
||||
fi
|
||||
else
|
||||
echo Cannot decompress $0; exit 1
|
||||
fi; exit $res
|
||||
EOF
|
||||
gzip -cv9 "$i" >> $tmp || {
|
||||
/bin/rm -f $tmp
|
||||
echo ${x}: compression not possible for $i, file unchanged.
|
||||
res=1
|
||||
continue
|
||||
}
|
||||
|
||||
else
|
||||
# decompression
|
||||
skip=18
|
||||
if sed -e 1d -e 2q "$i" | grep "^skip=[0-9]*$" >/dev/null; then
|
||||
eval `sed -e 1d -e 2q "$i"`
|
||||
fi
|
||||
if tail +$skip "$i" | gzip -cd > $tmp; then
|
||||
:
|
||||
else
|
||||
echo ${x}: $i probably not in gzexe format, file unchanged.
|
||||
res=1
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
rm -f "$i~"
|
||||
mv "$i" "$i~" || {
|
||||
echo ${x}: cannot backup $i as $i~
|
||||
rm -f $tmp
|
||||
res=1
|
||||
continue
|
||||
}
|
||||
mv $tmp "$i" || cp -p $tmp "$i" 2>/dev/null || cp $tmp "$i" || {
|
||||
echo ${x}: cannot create $i
|
||||
rm -f $tmp
|
||||
res=1
|
||||
continue
|
||||
}
|
||||
rm -f $tmp
|
||||
if test -n "$cpmod"; then
|
||||
$cpmod "$i~" "$i" 2>/dev/null
|
||||
elif test $writable -eq 0; then
|
||||
chmod u-w $i 2>/dev/null
|
||||
fi
|
||||
done
|
||||
exit $res
|
360
gnu/usr.bin/gzip/gzip.1
Normal file
360
gnu/usr.bin/gzip/gzip.1
Normal file
@ -0,0 +1,360 @@
|
||||
.PU
|
||||
.TH GZIP 1
|
||||
.SH NAME
|
||||
gzip, gunzip, zcat \- compress or expand files
|
||||
.SH SYNOPSIS
|
||||
.ll +8
|
||||
.B gzip
|
||||
.RB [ " \-acdfhLrtvV19 " ]
|
||||
.RB [ \-S\ suffix ]
|
||||
[
|
||||
.I "name \&..."
|
||||
]
|
||||
.ll -8
|
||||
.br
|
||||
.B gunzip
|
||||
.RB [ " \-acfhLrtvV " ]
|
||||
.RB [ \-S\ suffix ]
|
||||
[
|
||||
.I "name \&..."
|
||||
]
|
||||
.br
|
||||
.B zcat
|
||||
.RB [ " \-hLV " ]
|
||||
[
|
||||
.I "name \&..."
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.I Gzip
|
||||
reduces the size of the named files using Lempel-Ziv coding (LZ77).
|
||||
Whenever possible,
|
||||
each file is replaced by one with the extension
|
||||
.B "\&.gz,"
|
||||
while keeping the same ownership modes, access and modification times.
|
||||
(The default extension is
|
||||
.B "\-gz"
|
||||
for VMS,
|
||||
.B "z"
|
||||
for MSDOS, OS/2 and Atari.)
|
||||
If no files are specified, the standard input is compressed to the
|
||||
standard output. If the new file name is too long,
|
||||
.I gzip
|
||||
truncates it and keeps the original file name in the compressed file.
|
||||
.I Gzip
|
||||
will only attempt to compress regular files.
|
||||
In particular, it will ignore symbolic links.
|
||||
.PP
|
||||
Compressed files can be restored to their original form using
|
||||
.I gzip -d
|
||||
or
|
||||
.I gunzip
|
||||
or
|
||||
.I zcat.
|
||||
.PP
|
||||
.I gunzip
|
||||
takes a list of files on its command line and replaces each
|
||||
file whose name ends with .gz, -gz, .z, -z, _z or .Z
|
||||
and which begins with the correct magic number with an uncompressed
|
||||
file without the original extension.
|
||||
.I gunzip
|
||||
also recognizes the special extensions
|
||||
.B "\&.tgz"
|
||||
and
|
||||
.B "\&.taz"
|
||||
as shorthands for
|
||||
.B "\&.tar.gz"
|
||||
and
|
||||
.B "\&.tar.Z"
|
||||
respectively.
|
||||
.PP
|
||||
.I gunzip
|
||||
can currently decompress files created by
|
||||
.I gzip, zip, compress
|
||||
or
|
||||
.I pack.
|
||||
The detection of the input format is automatic. When using
|
||||
the first two formats,
|
||||
.I gunzip
|
||||
checks a 32 bit CRC. For
|
||||
.I pack, gunzip
|
||||
checks the uncompressed length. The
|
||||
.I compress
|
||||
format was not designed to allow consistency checks. However
|
||||
.I gunzip
|
||||
is sometimes able to detect a bad .Z file. If you get an error
|
||||
when uncompressing a .Z file, do not assume that the .Z file is
|
||||
correct simply because the standard
|
||||
.I uncompress
|
||||
does not complain. This generally means that the standard
|
||||
.I uncompress
|
||||
does not check its input, and happily generates garbage output.
|
||||
.PP
|
||||
Files created by
|
||||
.I zip
|
||||
can be uncompressed by gzip only if they have a single member compressed
|
||||
with the 'deflation' method. This feature is only intended to help
|
||||
conversion of tar.zip files to the tar.gz format. To extract zip files
|
||||
with several members, use
|
||||
.I unzip
|
||||
instead of
|
||||
.I gunzip.
|
||||
.PP
|
||||
.I zcat
|
||||
is identical to
|
||||
.I gunzip
|
||||
.B \-c.
|
||||
(On some systems,
|
||||
.I zcat
|
||||
may be installed as
|
||||
.I gzcat
|
||||
to preserve the original link to
|
||||
.I compress.)
|
||||
.I zcat
|
||||
uncompresses either a list of files on the command line or its
|
||||
standard input and writes the uncompressed data on standard output.
|
||||
.I zcat
|
||||
will uncompress files that have the correct magic number whether
|
||||
they have a
|
||||
.B "\&.gz"
|
||||
suffix or not.
|
||||
.PP
|
||||
.I Gzip
|
||||
uses the Lempel-Ziv algorithm used in
|
||||
.I zip
|
||||
and PKZIP.
|
||||
The amount of compression obtained depends on the size of the
|
||||
input and the distribution of common substrings.
|
||||
Typically, text such as source code or English
|
||||
is reduced by 60\-70%.
|
||||
Compression is generally much better than that achieved by
|
||||
LZW (as used in
|
||||
.IR compress ),
|
||||
Huffman coding (as used in
|
||||
.IR pack ),
|
||||
or adaptive Huffman coding
|
||||
.RI ( compact ).
|
||||
.PP
|
||||
Compression is always performed, even if the compressed file is
|
||||
slightly larger than the original. The worst case expansion is
|
||||
a few bytes for the gzip file header, plus 5 bytes every 32K block,
|
||||
or an expansion ratio of 0.015% for large files. Note that the actual
|
||||
number of used disk blocks almost never increases.
|
||||
.I gzip
|
||||
preserves the mode, ownership and timestamps of files when compressing
|
||||
or decompressing.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-a --ascii
|
||||
Ascii text mode: convert end-of-lines using local conventions. This option
|
||||
is supported only on some non-Unix systems. For MSDOS, CR LF is converted
|
||||
to LF when compressing, and LF is converted to CR LF when decompressing.
|
||||
.TP
|
||||
.B \-c --stdout
|
||||
Write output on standard output; keep original files unchanged.
|
||||
If there are several input files, the output consists of a sequence of
|
||||
independently compressed members. To obtain better compression,
|
||||
concatenate all input files before compressing them.
|
||||
.TP
|
||||
.B \-d --decompress --uncompress
|
||||
Decompress.
|
||||
.TP
|
||||
.B \-f --force
|
||||
Force compression or decompression even if the file has multiple links
|
||||
or the corresponding file already exists, or if the compressed data
|
||||
is read from or written to a terminal. If
|
||||
.B \-f
|
||||
is not given,
|
||||
and when not running in the background,
|
||||
.I gzip
|
||||
prompts to verify whether an existing file should be overwritten.
|
||||
.TP
|
||||
.B \-h --help
|
||||
Display a help screen and quit.
|
||||
.TP
|
||||
.B \-L --license
|
||||
Display the
|
||||
.I gzip
|
||||
license.
|
||||
.TP
|
||||
.B \-q --quiet
|
||||
Suppress all warnings.
|
||||
.TP
|
||||
.B \-r --recurse
|
||||
Travel the directory structure recursively. If any of the file names
|
||||
specified on the command line are directories,
|
||||
.I gzip
|
||||
will descend into the directory and compress all the files it finds there
|
||||
(or decompress them in the case of
|
||||
.I gunzip
|
||||
).
|
||||
.TP
|
||||
.B \-S .z --suffix .z
|
||||
Use suffix .z instead of .gz. Any suffix can be given, but suffixes
|
||||
other than .z and .gz should be avoided to avoid confusion when files
|
||||
are transferred to other systems. Previous versions of gzip used
|
||||
the .z suffix. This was changed to avoid a conflict with
|
||||
.IR pack "(1)".
|
||||
.TP
|
||||
.B \-t --test
|
||||
Test. Check the compressed file integrity.
|
||||
.TP
|
||||
.B \-v --verbose
|
||||
Verbose. Display the name and percentage reduction for each file compressed.
|
||||
.TP
|
||||
.B \-V --version
|
||||
Version. Display the version number and compilation options then quit.
|
||||
.TP
|
||||
.B \-# --fast --best
|
||||
Regulate the speed of compression using the specified digit
|
||||
.IR # ,
|
||||
where
|
||||
.B \-1
|
||||
or
|
||||
.B \-\-fast
|
||||
indicates the fastest compression method (less compression)
|
||||
and
|
||||
.B \-9
|
||||
or
|
||||
.B \-\-best
|
||||
indicates the slowest compression method (optimal compression).
|
||||
The default compression level is
|
||||
.BR \-5.
|
||||
.SH "ADVANCED USAGE"
|
||||
Multiple compressed files can be concatenated. In this case,
|
||||
.I gunzip
|
||||
will extract all members at once. For example:
|
||||
|
||||
gzip -c file1 > foo.gz
|
||||
gzip -c file2 >> foo.gz
|
||||
|
||||
Then
|
||||
gunzip -c foo
|
||||
|
||||
is equivalent to
|
||||
|
||||
cat file1 file2
|
||||
|
||||
In case of damage to one member of a .gz file, other members can
|
||||
still be recovered (if the damaged member is removed). However,
|
||||
you can get better compression by compressing all members at once:
|
||||
|
||||
cat file1 file2 | gzip > foo.gz
|
||||
|
||||
compresses better than
|
||||
|
||||
gzip -c file1 file2 > foo.gz
|
||||
|
||||
If you want to recompress concatenated files to get better compression, do:
|
||||
|
||||
zcat old.gz | gzip > new.gz
|
||||
.SH "ENVIRONMENT"
|
||||
The environment variable
|
||||
.B GZIP
|
||||
can hold a set of default options for
|
||||
.I gzip.
|
||||
These options are interpreted first and can be overwritten by
|
||||
explicit command line parameters. For example:
|
||||
for sh: GZIP="-8 -v"; export GZIP
|
||||
for csh: setenv GZIP "-8 -v"
|
||||
for MSDOS: set GZIP=-8 -v
|
||||
|
||||
On Vax/VMS, the name of the environment variable is GZIP_OPT, to
|
||||
avoid a conflict with the symbol set for invocation of the program.
|
||||
.SH "SEE ALSO"
|
||||
znew(1), zcmp(1), zmore(1), zforce(1), gzexe(1), zip(1), unzip(1), compress(1),
|
||||
pack(1), compact(1)
|
||||
.SH "DIAGNOSTICS"
|
||||
Exit status is normally 0;
|
||||
if an error occurs, exit status is 1. If a warning occurs, exit status is 2.
|
||||
.PP
|
||||
Usage: gzip [-cdfhLrtvV19] [-S suffix] [file ...]
|
||||
.in +8
|
||||
Invalid options were specified on the command line.
|
||||
.in -8
|
||||
.IR file :
|
||||
not in gzip format
|
||||
.in +8
|
||||
The file specified to
|
||||
.I gunzip
|
||||
has not been compressed.
|
||||
.in -8
|
||||
.IR file:
|
||||
Corrupt input. Use zcat to recover some data.
|
||||
.in +8
|
||||
The compressed file has been damaged. The data up to the point of failure
|
||||
can be recovered using
|
||||
.in +8
|
||||
zcat file > recover
|
||||
.in -16
|
||||
.IR file :
|
||||
compressed with
|
||||
.I xx
|
||||
bits, can only handle
|
||||
.I yy
|
||||
bits
|
||||
.in +8
|
||||
.I File
|
||||
was compressed (using LZW) by a program that could deal with
|
||||
more
|
||||
.I bits
|
||||
than the decompress code on this machine.
|
||||
Recompress the file with gzip, which compresses better and uses
|
||||
less memory.
|
||||
.in -8
|
||||
.IR file :
|
||||
already has .gz suffix -- no change
|
||||
.in +8
|
||||
The file is assumed to be already compressed.
|
||||
Rename the file and try again.
|
||||
.in -8
|
||||
.I file
|
||||
already exists; do you wish to overwrite (y or n)?
|
||||
.in +8
|
||||
Respond "y" if you want the output file to be replaced; "n" if not.
|
||||
.in -8
|
||||
gunzip: corrupt input
|
||||
.in +8
|
||||
A SIGSEGV violation was detected which usually means that the input file has
|
||||
been corrupted.
|
||||
.in -8
|
||||
.I "xx.x%"
|
||||
.in +8
|
||||
Percentage of the input saved by compression.
|
||||
(Relevant only for
|
||||
.BR \-v \.)
|
||||
.in -8
|
||||
-- not a regular file or directory: ignored
|
||||
.in +8
|
||||
When the input file is not a regular file or directory,
|
||||
(e.g. a symbolic link, socket, FIFO, device file), it is
|
||||
left unaltered.
|
||||
.in -8
|
||||
-- has
|
||||
.I xx
|
||||
other links: unchanged
|
||||
.in +8
|
||||
The input file has links; it is left unchanged. See
|
||||
.IR ln "(1)"
|
||||
for more information. Use the
|
||||
.B \-f
|
||||
flag to force compression of multiply-linked files.
|
||||
.in -8
|
||||
.SH CAVEATS
|
||||
When writing compressed data to a tape, it is generally necessary to
|
||||
pad the output with zeroes up to a block boundary. When the data is
|
||||
read and the whole block is passed to
|
||||
.I gunzip
|
||||
for decompression,
|
||||
.I gunzip
|
||||
detects that there is extra trailing garbage after the compressed data
|
||||
and emits a warning by default. You have to use the --quiet option to
|
||||
suppress the warning. This option can be set in the
|
||||
.B GZIP
|
||||
environment variable as in:
|
||||
for sh: GZIP="-q" tar xfz /dev/rmt/datn
|
||||
for csh: (setenv GZIP "-q"; tar xfz /dev/rmt/datn)
|
||||
|
||||
In the above example, gzip is invoked implicitly by the -z option
|
||||
of GNU tar. Make sure that the same block size (-b option of
|
||||
tar) is used for reading and writing compressed data on tapes.
|
1458
gnu/usr.bin/gzip/gzip.c
Normal file
1458
gnu/usr.bin/gzip/gzip.c
Normal file
File diff suppressed because it is too large
Load Diff
302
gnu/usr.bin/gzip/gzip.h
Normal file
302
gnu/usr.bin/gzip/gzip.h
Normal file
@ -0,0 +1,302 @@
|
||||
/* gzip.h -- common declarations for all gzip modules
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
#if defined(__STDC__) || defined(PROTO)
|
||||
# define OF(args) args
|
||||
#else
|
||||
# define OF(args) ()
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
typedef void *voidp;
|
||||
#else
|
||||
typedef char *voidp;
|
||||
#endif
|
||||
|
||||
/* I don't like nested includes, but the string functions are used too often */
|
||||
#if !defined(NO_STRING_H) || defined(STDC_HEADERS)
|
||||
# include <string.h>
|
||||
# if !defined(STDC_HEADERS) && !defined(NO_MEMORY_H) && !defined(__GNUC__)
|
||||
# include <memory.h>
|
||||
# endif
|
||||
# define memzero(s, n) memset ((voidp)(s), 0, (n))
|
||||
#else
|
||||
# include <strings.h>
|
||||
# define strchr index
|
||||
# define strrchr rindex
|
||||
# define memcpy(d, s, n) bcopy((s), (d), (n))
|
||||
# define memcmp(s1, s2, n) bcmp((s1), (s2), (n))
|
||||
# define memzero(s, n) bzero((s), (n))
|
||||
#endif
|
||||
|
||||
#ifndef RETSIGTYPE
|
||||
# define RETSIGTYPE void
|
||||
#endif
|
||||
|
||||
#define local static
|
||||
|
||||
typedef unsigned char uch;
|
||||
typedef unsigned short ush;
|
||||
typedef unsigned long ulg;
|
||||
|
||||
/* Return codes from gzip */
|
||||
#define OK 0
|
||||
#define ERROR 1
|
||||
#define WARNING 2
|
||||
|
||||
/* Compression methods (see algorithm.doc) */
|
||||
#define STORED 0
|
||||
#define COMPRESSED 1
|
||||
#define PACKED 2
|
||||
/* methods 3 to 7 reserved */
|
||||
#define DEFLATED 8
|
||||
extern int method; /* compression method */
|
||||
|
||||
/* To save memory for 16 bit systems, some arrays are overlaid between
|
||||
* the various modules:
|
||||
* deflate: prev+head window d_buf l_buf outbuf
|
||||
* unlzw: tab_prefix tab_suffix stack inbuf outbuf
|
||||
* inflate: window inbuf
|
||||
* unpack: window inbuf
|
||||
* For compression, input is done in window[]. For decompression, output
|
||||
* is done in window except for unlzw.
|
||||
*/
|
||||
|
||||
#ifndef INBUFSIZ
|
||||
# ifdef SMALL_MEM
|
||||
# define INBUFSIZ 0x2000 /* input buffer size */
|
||||
# else
|
||||
# define INBUFSIZ 0x8000 /* input buffer size */
|
||||
# endif
|
||||
#endif
|
||||
#define INBUF_EXTRA 64 /* required by unlzw() */
|
||||
|
||||
#ifndef OUTBUFSIZ
|
||||
# ifdef SMALL_MEM
|
||||
# define OUTBUFSIZ 8192 /* output buffer size */
|
||||
# else
|
||||
# define OUTBUFSIZ 16384 /* output buffer size */
|
||||
# endif
|
||||
#endif
|
||||
#define OUTBUF_EXTRA 2048 /* required by unlzw() */
|
||||
|
||||
#ifndef DIST_BUFSIZE
|
||||
# ifdef SMALL_MEM
|
||||
# define DIST_BUFSIZE 0x2000 /* buffer for distances, see trees.c */
|
||||
# else
|
||||
# define DIST_BUFSIZE 0x8000 /* buffer for distances, see trees.c */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef DYN_ALLOC
|
||||
# define EXTERN(type, array) extern type * near array
|
||||
# define DECLARE(type, array, size) type * near array
|
||||
# define ALLOC(type, array, size) { \
|
||||
array = (type*)fcalloc((size_t)(((size)+1L)/2), 2*sizeof(type)); \
|
||||
if (array == NULL) error("insufficient memory"); \
|
||||
}
|
||||
# define FREE(array) {if (array != NULL) fcfree(array), array=NULL;}
|
||||
#else
|
||||
# define EXTERN(type, array) extern type array[]
|
||||
# define DECLARE(type, array, size) type array[size]
|
||||
# define ALLOC(type, array, size)
|
||||
# define FREE(array)
|
||||
#endif
|
||||
|
||||
EXTERN(uch, inbuf); /* input buffer */
|
||||
EXTERN(uch, outbuf); /* output buffer */
|
||||
EXTERN(ush, d_buf); /* buffer for distances, see trees.c */
|
||||
EXTERN(uch, window); /* Sliding window and suffix table (unlzw) */
|
||||
#define tab_suffix window
|
||||
#ifndef MAXSEG_64K
|
||||
# define tab_prefix prev /* hash link (see deflate.c) */
|
||||
# define head (prev+WSIZE) /* hash head (see deflate.c) */
|
||||
EXTERN(ush, tab_prefix); /* prefix code (see unlzw.c) */
|
||||
#else
|
||||
# define tab_prefix0 prev
|
||||
# define head tab_prefix1
|
||||
EXTERN(ush, tab_prefix0); /* prefix for even codes */
|
||||
EXTERN(ush, tab_prefix1); /* prefix for odd codes */
|
||||
#endif
|
||||
|
||||
extern unsigned insize; /* valid bytes in inbuf */
|
||||
extern unsigned inptr; /* index of next byte to be processed in inbuf */
|
||||
extern unsigned outcnt; /* bytes in output buffer */
|
||||
|
||||
extern long bytes_in; /* number of input bytes */
|
||||
extern long bytes_out; /* number of output bytes */
|
||||
extern long header_bytes;/* number of bytes in gzip header */
|
||||
|
||||
#define isize bytes_in
|
||||
/* for compatibility with old zip sources (to be cleaned) */
|
||||
|
||||
extern int ifd; /* input file descriptor */
|
||||
extern int ofd; /* output file descriptor */
|
||||
extern char ifname[]; /* input file name or "stdin" */
|
||||
extern char ofname[]; /* output file name or "stdout" */
|
||||
extern char *progname; /* program name */
|
||||
|
||||
extern ulg time_stamp; /* original time stamp (modification time) */
|
||||
extern long ifile_size; /* input file size, -1 for devices (debug only) */
|
||||
|
||||
typedef int file_t; /* Do not use stdio */
|
||||
#define NO_FILE (-1) /* in memory compression */
|
||||
|
||||
|
||||
#define GZIP_MAGIC "\037\213" /* Magic header for gzip files, 1F 8B */
|
||||
#define OLD_GZIP_MAGIC "\037\236" /* Magic header for gzip 0.5 = freeze 1.x */
|
||||
#define PKZIP_MAGIC "\120\113\003\004" /* Magic header for pkzip files */
|
||||
#define PACK_MAGIC "\037\036" /* Magic header for packed files */
|
||||
|
||||
/* gzip flag byte */
|
||||
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
|
||||
#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
|
||||
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
|
||||
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
|
||||
#define COMMENT 0x10 /* bit 4 set: file comment present */
|
||||
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
|
||||
#define RESERVED 0xC0 /* bit 6,7: reserved */
|
||||
|
||||
/* internal file attribute */
|
||||
#define UNKNOWN 0xffff
|
||||
#define BINARY 0
|
||||
#define ASCII 1
|
||||
|
||||
#ifndef WSIZE
|
||||
# define WSIZE 0x8000 /* window size--must be a power of two, and */
|
||||
#endif /* at least 32K for zip's deflate method */
|
||||
|
||||
#define MIN_MATCH 3
|
||||
#define MAX_MATCH 258
|
||||
/* The minimum and maximum match lengths */
|
||||
|
||||
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
|
||||
/* Minimum amount of lookahead, except at the end of the input file.
|
||||
* See deflate.c for comments about the MIN_MATCH+1.
|
||||
*/
|
||||
|
||||
#define MAX_DIST (WSIZE-MIN_LOOKAHEAD)
|
||||
/* In order to simplify the code, particularly on 16 bit machines, match
|
||||
* distances are limited to MAX_DIST instead of WSIZE.
|
||||
*/
|
||||
|
||||
extern int decrypt; /* flag to turn on decryption */
|
||||
extern int exit_code; /* program exit code */
|
||||
extern int verbose; /* be verbose (-v) */
|
||||
extern int quiet; /* be quiet (-q) */
|
||||
extern int level; /* compression level */
|
||||
extern int test; /* check .z file integrity */
|
||||
extern int to_stdout; /* output to stdout (-c) */
|
||||
extern int save_orig_name; /* set if original name must be saved */
|
||||
|
||||
#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
|
||||
|
||||
/* put_byte is used for the compressed output, put_ubyte for the
|
||||
* uncompressed output. However unlzw() uses window for its
|
||||
* suffix table instead of its output buffer, so it does not use put_ubyte
|
||||
* (to be cleaned up).
|
||||
*/
|
||||
#define put_byte(c) {outbuf[outcnt++]=(uch)(c); if (outcnt==OUTBUFSIZ)\
|
||||
flush_outbuf();}
|
||||
#define put_ubyte(c) {window[outcnt++]=(uch)(c); if (outcnt==WSIZE)\
|
||||
flush_window();}
|
||||
|
||||
/* Output a 16 bit value, lsb first */
|
||||
#define put_short(w) \
|
||||
{ if (outcnt < OUTBUFSIZ-2) { \
|
||||
outbuf[outcnt++] = (uch) ((w) & 0xff); \
|
||||
outbuf[outcnt++] = (uch) ((ush)(w) >> 8); \
|
||||
} else { \
|
||||
put_byte((uch)((w) & 0xff)); \
|
||||
put_byte((uch)((ush)(w) >> 8)); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Output a 32 bit value to the bit stream, lsb first */
|
||||
#define put_long(n) { \
|
||||
put_short((n) & 0xffff); \
|
||||
put_short(((ulg)(n)) >> 16); \
|
||||
}
|
||||
|
||||
#define seekable() 0 /* force sequential output */
|
||||
#define translate_eol 0 /* no option -a yet */
|
||||
|
||||
#define tolow(c) (isupper(c) ? (c)-'A'+'a' : (c)) /* force to lower case */
|
||||
|
||||
/* Macros for getting two-byte and four-byte header values */
|
||||
#define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8))
|
||||
#define LG(p) ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16))
|
||||
|
||||
/* Diagnostic functions */
|
||||
#ifdef DEBUG
|
||||
# define Assert(cond,msg) {if(!(cond)) error(msg);}
|
||||
# define Trace(x) fprintf x
|
||||
# define Tracev(x) {if (verbose) fprintf x ;}
|
||||
# define Tracevv(x) {if (verbose>1) fprintf x ;}
|
||||
# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
|
||||
# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
|
||||
#else
|
||||
# define Assert(cond,msg)
|
||||
# define Trace(x)
|
||||
# define Tracev(x)
|
||||
# define Tracevv(x)
|
||||
# define Tracec(c,x)
|
||||
# define Tracecv(c,x)
|
||||
#endif
|
||||
|
||||
#define WARN(msg) {if (!quiet) fprintf msg ; \
|
||||
if (exit_code == OK) exit_code = WARNING;}
|
||||
|
||||
/* in zip.c: */
|
||||
extern int zip OF((int in, int out));
|
||||
extern int file_read OF((char *buf, unsigned size));
|
||||
|
||||
/* in unzip.c */
|
||||
extern int unzip OF((int in, int out));
|
||||
extern int check_zipfile OF((int in));
|
||||
|
||||
/* in unpack.c */
|
||||
extern int unpack OF((int in, int out));
|
||||
|
||||
/* in gzip.c */
|
||||
RETSIGTYPE abort_gzip OF((void));
|
||||
|
||||
/* in deflate.c */
|
||||
void lm_init OF((int pack_level, ush *flags));
|
||||
ulg deflate OF((void));
|
||||
|
||||
/* in trees.c */
|
||||
void ct_init OF((ush *attr, int *method));
|
||||
int ct_tally OF((int dist, int lc));
|
||||
ulg flush_block OF((char *buf, ulg stored_len, int eof));
|
||||
|
||||
/* in bits.c */
|
||||
void bi_init OF((file_t zipfile));
|
||||
void send_bits OF((int value, int length));
|
||||
unsigned bi_reverse OF((unsigned value, int length));
|
||||
void bi_windup OF((void));
|
||||
void copy_block OF((char *buf, unsigned len, int header));
|
||||
extern int (*read_buf) OF((char *buf, unsigned size));
|
||||
|
||||
/* in util.c: */
|
||||
extern ulg updcrc OF((uch *s, unsigned n));
|
||||
extern void clear_bufs OF((void));
|
||||
extern int fill_inbuf OF((void));
|
||||
extern void flush_outbuf OF((void));
|
||||
extern void flush_window OF((void));
|
||||
extern void write_buf OF((int fd, voidp buf, unsigned cnt));
|
||||
extern char *strlwr OF((char *s));
|
||||
extern char *basename OF((char *fname));
|
||||
extern char *add_envopt OF((int *argcp, char ***argvp, char *env));
|
||||
extern void error OF((char *m));
|
||||
extern void warn OF((char *a, char *b));
|
||||
extern void read_error OF((void));
|
||||
extern void write_error OF((void));
|
||||
extern void display_ratio OF((long num, long den));
|
||||
extern voidp xmalloc OF((unsigned int size));
|
||||
|
||||
/* in inflate.c */
|
||||
extern int inflate OF((void));
|
954
gnu/usr.bin/gzip/inflate.c
Normal file
954
gnu/usr.bin/gzip/inflate.c
Normal file
@ -0,0 +1,954 @@
|
||||
/* inflate.c -- Not copyrighted 1992 by Mark Adler
|
||||
version c10p1, 10 January 1993 */
|
||||
|
||||
/* You can do whatever you like with this source file, though I would
|
||||
prefer that if you modify it and redistribute it that you include
|
||||
comments to that effect with your name and the date. Thank you.
|
||||
[The history has been moved to the file ChangeLog.]
|
||||
*/
|
||||
|
||||
/*
|
||||
Inflate deflated (PKZIP's method 8 compressed) data. The compression
|
||||
method searches for as much of the current string of bytes (up to a
|
||||
length of 258) in the previous 32K bytes. If it doesn't find any
|
||||
matches (of at least length 3), it codes the next byte. Otherwise, it
|
||||
codes the length of the matched string and its distance backwards from
|
||||
the current position. There is a single Huffman code that codes both
|
||||
single bytes (called "literals") and match lengths. A second Huffman
|
||||
code codes the distance information, which follows a length code. Each
|
||||
length or distance code actually represents a base value and a number
|
||||
of "extra" (sometimes zero) bits to get to add to the base value. At
|
||||
the end of each deflated block is a special end-of-block (EOB) literal/
|
||||
length code. The decoding process is basically: get a literal/length
|
||||
code; if EOB then done; if a literal, emit the decoded byte; if a
|
||||
length then get the distance and emit the referred-to bytes from the
|
||||
sliding window of previously emitted data.
|
||||
|
||||
There are (currently) three kinds of inflate blocks: stored, fixed, and
|
||||
dynamic. The compressor deals with some chunk of data at a time, and
|
||||
decides which method to use on a chunk-by-chunk basis. A chunk might
|
||||
typically be 32K or 64K. If the chunk is uncompressible, then the
|
||||
"stored" method is used. In this case, the bytes are simply stored as
|
||||
is, eight bits per byte, with none of the above coding. The bytes are
|
||||
preceded by a count, since there is no longer an EOB code.
|
||||
|
||||
If the data is compressible, then either the fixed or dynamic methods
|
||||
are used. In the dynamic method, the compressed data is preceded by
|
||||
an encoding of the literal/length and distance Huffman codes that are
|
||||
to be used to decode this block. The representation is itself Huffman
|
||||
coded, and so is preceded by a description of that code. These code
|
||||
descriptions take up a little space, and so for small blocks, there is
|
||||
a predefined set of codes, called the fixed codes. The fixed method is
|
||||
used if the block codes up smaller that way (usually for quite small
|
||||
chunks), otherwise the dynamic method is used. In the latter case, the
|
||||
codes are customized to the probabilities in the current block, and so
|
||||
can code it much better than the pre-determined fixed codes.
|
||||
|
||||
The Huffman codes themselves are decoded using a mutli-level table
|
||||
lookup, in order to maximize the speed of decoding plus the speed of
|
||||
building the decoding tables. See the comments below that precede the
|
||||
lbits and dbits tuning parameters.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Notes beyond the 1.93a appnote.txt:
|
||||
|
||||
1. Distance pointers never point before the beginning of the output
|
||||
stream.
|
||||
2. Distance pointers can point back across blocks, up to 32k away.
|
||||
3. There is an implied maximum of 7 bits for the bit length table and
|
||||
15 bits for the actual data.
|
||||
4. If only one code exists, then it is encoded using one bit. (Zero
|
||||
would be more efficient, but perhaps a little confusing.) If two
|
||||
codes exist, they are coded using one bit each (0 and 1).
|
||||
5. There is no way of sending zero distance codes--a dummy must be
|
||||
sent if there are none. (History: a pre 2.0 version of PKZIP would
|
||||
store blocks with no distance codes, but this was discovered to be
|
||||
too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
|
||||
zero distance codes, which is sent as one code of zero bits in
|
||||
length.
|
||||
6. There are up to 286 literal/length codes. Code 256 represents the
|
||||
end-of-block. Note however that the static length tree defines
|
||||
288 codes just to fill out the Huffman codes. Codes 286 and 287
|
||||
cannot be used though, since there is no length base or extra bits
|
||||
defined for them. Similarly, there are up to 30 distance codes.
|
||||
However, static trees define 32 codes (all 5 bits) to fill out the
|
||||
Huffman codes, but the last two had better not show up in the data.
|
||||
7. Unzip can check dynamic Huffman blocks for complete code sets.
|
||||
The exception is that a single code would not be complete (see #4).
|
||||
8. The five bits following the block type is really the number of
|
||||
literal codes sent minus 257.
|
||||
9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
|
||||
(1+6+6). Therefore, to output three times the length, you output
|
||||
three codes (1+1+1), whereas to output four times the same length,
|
||||
you only need two codes (1+3). Hmm.
|
||||
10. In the tree reconstruction algorithm, Code = Code + Increment
|
||||
only if BitLength(i) is not zero. (Pretty obvious.)
|
||||
11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
|
||||
12. Note: length code 284 can represent 227-258, but length code 285
|
||||
really is 258. The last length deserves its own, short code
|
||||
since it gets used a lot in very redundant files. The length
|
||||
258 is special since 258 - 3 (the min match length) is 255.
|
||||
13. The literal/length and distance code bit lengths are read as a
|
||||
single stream of lengths. It is possible (and advantageous) for
|
||||
a repeat code (16, 17, or 18) to go across the boundary between
|
||||
the two sets of lengths.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: inflate.c,v 0.13 1993/04/26 14:18:22 jloup Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "tailor.h"
|
||||
|
||||
#if defined(STDC_HEADERS) || !defined(NO_STDLIB_H)
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "gzip.h"
|
||||
#define slide window
|
||||
|
||||
/* Huffman code lookup table entry--this entry is four bytes for machines
|
||||
that have 16-bit pointers (e.g. PC's in the small or medium model).
|
||||
Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16
|
||||
means that v is a literal, 16 < e < 32 means that v is a pointer to
|
||||
the next table, which codes e - 16 bits, and lastly e == 99 indicates
|
||||
an unused code. If a code with e == 99 is looked up, this implies an
|
||||
error in the data. */
|
||||
struct huft {
|
||||
uch e; /* number of extra bits or operation */
|
||||
uch b; /* number of bits in this code or subcode */
|
||||
union {
|
||||
ush n; /* literal, length base, or distance base */
|
||||
struct huft *t; /* pointer to next level of table */
|
||||
} v;
|
||||
};
|
||||
|
||||
|
||||
/* Function prototypes */
|
||||
int huft_build OF((unsigned *, unsigned, unsigned, ush *, ush *,
|
||||
struct huft **, int *));
|
||||
int huft_free OF((struct huft *));
|
||||
int inflate_codes OF((struct huft *, struct huft *, int, int));
|
||||
int inflate_stored OF((void));
|
||||
int inflate_fixed OF((void));
|
||||
int inflate_dynamic OF((void));
|
||||
int inflate_block OF((int *));
|
||||
int inflate OF((void));
|
||||
|
||||
|
||||
/* The inflate algorithm uses a sliding 32K byte window on the uncompressed
|
||||
stream to find repeated byte strings. This is implemented here as a
|
||||
circular buffer. The index is updated simply by incrementing and then
|
||||
and'ing with 0x7fff (32K-1). */
|
||||
/* It is left to other modules to supply the 32K area. It is assumed
|
||||
to be usable as if it were declared "uch slide[32768];" or as just
|
||||
"uch *slide;" and then malloc'ed in the latter case. The definition
|
||||
must be in unzip.h, included above. */
|
||||
/* unsigned wp; current position in slide */
|
||||
#define wp outcnt
|
||||
#define flush_output(w) (wp=(w),flush_window())
|
||||
|
||||
/* Tables for deflate from PKZIP's appnote.txt. */
|
||||
static unsigned border[] = { /* Order of the bit length code lengths */
|
||||
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
|
||||
static ush cplens[] = { /* Copy lengths for literal codes 257..285 */
|
||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
||||
/* note: see note #13 above about the 258 in this list. */
|
||||
static ush cplext[] = { /* Extra bits for literal codes 257..285 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */
|
||||
static ush cpdist[] = { /* Copy offsets for distance codes 0..29 */
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||||
8193, 12289, 16385, 24577};
|
||||
static ush cpdext[] = { /* Extra bits for distance codes */
|
||||
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
|
||||
7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
|
||||
12, 12, 13, 13};
|
||||
|
||||
|
||||
|
||||
/* Macros for inflate() bit peeking and grabbing.
|
||||
The usage is:
|
||||
|
||||
NEEDBITS(j)
|
||||
x = b & mask_bits[j];
|
||||
DUMPBITS(j)
|
||||
|
||||
where NEEDBITS makes sure that b has at least j bits in it, and
|
||||
DUMPBITS removes the bits from b. The macros use the variable k
|
||||
for the number of bits in b. Normally, b and k are register
|
||||
variables for speed, and are initialized at the beginning of a
|
||||
routine that uses these macros from a global bit buffer and count.
|
||||
|
||||
If we assume that EOB will be the longest code, then we will never
|
||||
ask for bits with NEEDBITS that are beyond the end of the stream.
|
||||
So, NEEDBITS should not read any more bytes than are needed to
|
||||
meet the request. Then no bytes need to be "returned" to the buffer
|
||||
at the end of the last block.
|
||||
|
||||
However, this assumption is not true for fixed blocks--the EOB code
|
||||
is 7 bits, but the other literal/length codes can be 8 or 9 bits.
|
||||
(The EOB code is shorter than other codes because fixed blocks are
|
||||
generally short. So, while a block always has an EOB, many other
|
||||
literal/length codes have a significantly lower probability of
|
||||
showing up at all.) However, by making the first table have a
|
||||
lookup of seven bits, the EOB code will be found in that first
|
||||
lookup, and so will not require that too many bits be pulled from
|
||||
the stream.
|
||||
*/
|
||||
|
||||
ulg bb; /* bit buffer */
|
||||
unsigned bk; /* bits in bit buffer */
|
||||
|
||||
ush mask_bits[] = {
|
||||
0x0000,
|
||||
0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
|
||||
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
|
||||
};
|
||||
|
||||
#ifdef CRYPT
|
||||
uch cc;
|
||||
# define NEXTBYTE() \
|
||||
(decrypt ? (cc = get_byte(), zdecode(cc), cc) : get_byte())
|
||||
#else
|
||||
# define NEXTBYTE() (uch)get_byte()
|
||||
#endif
|
||||
#define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}}
|
||||
#define DUMPBITS(n) {b>>=(n);k-=(n);}
|
||||
|
||||
|
||||
/*
|
||||
Huffman code decoding is performed using a multi-level table lookup.
|
||||
The fastest way to decode is to simply build a lookup table whose
|
||||
size is determined by the longest code. However, the time it takes
|
||||
to build this table can also be a factor if the data being decoded
|
||||
is not very long. The most common codes are necessarily the
|
||||
shortest codes, so those codes dominate the decoding time, and hence
|
||||
the speed. The idea is you can have a shorter table that decodes the
|
||||
shorter, more probable codes, and then point to subsidiary tables for
|
||||
the longer codes. The time it costs to decode the longer codes is
|
||||
then traded against the time it takes to make longer tables.
|
||||
|
||||
This results of this trade are in the variables lbits and dbits
|
||||
below. lbits is the number of bits the first level table for literal/
|
||||
length codes can decode in one step, and dbits is the same thing for
|
||||
the distance codes. Subsequent tables are also less than or equal to
|
||||
those sizes. These values may be adjusted either when all of the
|
||||
codes are shorter than that, in which case the longest code length in
|
||||
bits is used, or when the shortest code is *longer* than the requested
|
||||
table size, in which case the length of the shortest code in bits is
|
||||
used.
|
||||
|
||||
There are two different values for the two tables, since they code a
|
||||
different number of possibilities each. The literal/length table
|
||||
codes 286 possible values, or in a flat code, a little over eight
|
||||
bits. The distance table codes 30 possible values, or a little less
|
||||
than five bits, flat. The optimum values for speed end up being
|
||||
about one bit more than those, so lbits is 8+1 and dbits is 5+1.
|
||||
The optimum values may differ though from machine to machine, and
|
||||
possibly even between compilers. Your mileage may vary.
|
||||
*/
|
||||
|
||||
|
||||
int lbits = 9; /* bits in base literal/length lookup table */
|
||||
int dbits = 6; /* bits in base distance lookup table */
|
||||
|
||||
|
||||
/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
|
||||
#define BMAX 16 /* maximum bit length of any code (16 for explode) */
|
||||
#define N_MAX 288 /* maximum number of codes in any set */
|
||||
|
||||
|
||||
unsigned hufts; /* track memory usage */
|
||||
|
||||
|
||||
int huft_build(b, n, s, d, e, t, m)
|
||||
unsigned *b; /* code lengths in bits (all assumed <= BMAX) */
|
||||
unsigned n; /* number of codes (assumed <= N_MAX) */
|
||||
unsigned s; /* number of simple-valued codes (0..s-1) */
|
||||
ush *d; /* list of base values for non-simple codes */
|
||||
ush *e; /* list of extra bits for non-simple codes */
|
||||
struct huft **t; /* result: starting table */
|
||||
int *m; /* maximum lookup bits, returns actual */
|
||||
/* Given a list of code lengths and a maximum table size, make a set of
|
||||
tables to decode that set of codes. Return zero on success, one if
|
||||
the given code set is incomplete (the tables are still built in this
|
||||
case), two if the input is invalid (all zero length codes or an
|
||||
oversubscribed set of lengths), and three if not enough memory. */
|
||||
{
|
||||
unsigned a; /* counter for codes of length k */
|
||||
unsigned c[BMAX+1]; /* bit length count table */
|
||||
unsigned f; /* i repeats in table every f entries */
|
||||
int g; /* maximum code length */
|
||||
int h; /* table level */
|
||||
register unsigned i; /* counter, current code */
|
||||
register unsigned j; /* counter */
|
||||
register int k; /* number of bits in current code */
|
||||
int l; /* bits per table (returned in m) */
|
||||
register unsigned *p; /* pointer into c[], b[], or v[] */
|
||||
register struct huft *q; /* points to current table */
|
||||
struct huft r; /* table entry for structure assignment */
|
||||
struct huft *u[BMAX]; /* table stack */
|
||||
unsigned v[N_MAX]; /* values in order of bit length */
|
||||
register int w; /* bits before this table == (l * h) */
|
||||
unsigned x[BMAX+1]; /* bit offsets, then code stack */
|
||||
unsigned *xp; /* pointer into x */
|
||||
int y; /* number of dummy codes added */
|
||||
unsigned z; /* number of entries in current table */
|
||||
|
||||
|
||||
/* Generate counts for each bit length */
|
||||
memzero(c, sizeof(c));
|
||||
p = b; i = n;
|
||||
do {
|
||||
Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"),
|
||||
n-i, *p));
|
||||
c[*p++]++; /* assume all entries <= BMAX */
|
||||
} while (--i);
|
||||
if (c[0] == n) /* null input--all zero length codes */
|
||||
{
|
||||
*t = (struct huft *)NULL;
|
||||
*m = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Find minimum and maximum length, bound *m by those */
|
||||
l = *m;
|
||||
for (j = 1; j <= BMAX; j++)
|
||||
if (c[j])
|
||||
break;
|
||||
k = j; /* minimum code length */
|
||||
if ((unsigned)l < j)
|
||||
l = j;
|
||||
for (i = BMAX; i; i--)
|
||||
if (c[i])
|
||||
break;
|
||||
g = i; /* maximum code length */
|
||||
if ((unsigned)l > i)
|
||||
l = i;
|
||||
*m = l;
|
||||
|
||||
|
||||
/* Adjust last length count to fill out codes, if needed */
|
||||
for (y = 1 << j; j < i; j++, y <<= 1)
|
||||
if ((y -= c[j]) < 0)
|
||||
return 2; /* bad input: more codes than bits */
|
||||
if ((y -= c[i]) < 0)
|
||||
return 2;
|
||||
c[i] += y;
|
||||
|
||||
|
||||
/* Generate starting offsets into the value table for each length */
|
||||
x[1] = j = 0;
|
||||
p = c + 1; xp = x + 2;
|
||||
while (--i) { /* note that i == g from above */
|
||||
*xp++ = (j += *p++);
|
||||
}
|
||||
|
||||
|
||||
/* Make a table of values in order of bit lengths */
|
||||
p = b; i = 0;
|
||||
do {
|
||||
if ((j = *p++) != 0)
|
||||
v[x[j]++] = i;
|
||||
} while (++i < n);
|
||||
|
||||
|
||||
/* Generate the Huffman codes and for each, make the table entries */
|
||||
x[0] = i = 0; /* first Huffman code is zero */
|
||||
p = v; /* grab values in bit order */
|
||||
h = -1; /* no tables yet--level -1 */
|
||||
w = -l; /* bits decoded == (l * h) */
|
||||
u[0] = (struct huft *)NULL; /* just to keep compilers happy */
|
||||
q = (struct huft *)NULL; /* ditto */
|
||||
z = 0; /* ditto */
|
||||
|
||||
/* go through the bit lengths (k already is bits in shortest code) */
|
||||
for (; k <= g; k++)
|
||||
{
|
||||
a = c[k];
|
||||
while (a--)
|
||||
{
|
||||
/* here i is the Huffman code of length k bits for value *p */
|
||||
/* make tables up to required level */
|
||||
while (k > w + l)
|
||||
{
|
||||
h++;
|
||||
w += l; /* previous table always l bits */
|
||||
|
||||
/* compute minimum size table less than or equal to l bits */
|
||||
z = (z = g - w) > (unsigned)l ? l : z; /* upper limit on table size */
|
||||
if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
|
||||
{ /* too few codes for k-w bit table */
|
||||
f -= a + 1; /* deduct codes from patterns left */
|
||||
xp = c + k;
|
||||
while (++j < z) /* try smaller tables up to z bits */
|
||||
{
|
||||
if ((f <<= 1) <= *++xp)
|
||||
break; /* enough codes to use up j bits */
|
||||
f -= *xp; /* else deduct codes from patterns */
|
||||
}
|
||||
}
|
||||
z = 1 << j; /* table entries for j-bit table */
|
||||
|
||||
/* allocate and link in new table */
|
||||
if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) ==
|
||||
(struct huft *)NULL)
|
||||
{
|
||||
if (h)
|
||||
huft_free(u[0]);
|
||||
return 3; /* not enough memory */
|
||||
}
|
||||
hufts += z + 1; /* track memory usage */
|
||||
*t = q + 1; /* link to list for huft_free() */
|
||||
*(t = &(q->v.t)) = (struct huft *)NULL;
|
||||
u[h] = ++q; /* table starts after link */
|
||||
|
||||
/* connect to last table, if there is one */
|
||||
if (h)
|
||||
{
|
||||
x[h] = i; /* save pattern for backing up */
|
||||
r.b = (uch)l; /* bits to dump before this table */
|
||||
r.e = (uch)(16 + j); /* bits in this table */
|
||||
r.v.t = q; /* pointer to this table */
|
||||
j = i >> (w - l); /* (get around Turbo C bug) */
|
||||
u[h-1][j] = r; /* connect to last table */
|
||||
}
|
||||
}
|
||||
|
||||
/* set up table entry in r */
|
||||
r.b = (uch)(k - w);
|
||||
if (p >= v + n)
|
||||
r.e = 99; /* out of values--invalid code */
|
||||
else if (*p < s)
|
||||
{
|
||||
r.e = (uch)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */
|
||||
r.v.n = (ush)(*p); /* simple code is just the value */
|
||||
p++; /* one compiler does not like *p++ */
|
||||
}
|
||||
else
|
||||
{
|
||||
r.e = (uch)e[*p - s]; /* non-simple--look up in lists */
|
||||
r.v.n = d[*p++ - s];
|
||||
}
|
||||
|
||||
/* fill code-like entries with r */
|
||||
f = 1 << (k - w);
|
||||
for (j = i >> w; j < z; j += f)
|
||||
q[j] = r;
|
||||
|
||||
/* backwards increment the k-bit code i */
|
||||
for (j = 1 << (k - 1); i & j; j >>= 1)
|
||||
i ^= j;
|
||||
i ^= j;
|
||||
|
||||
/* backup over finished tables */
|
||||
while ((i & ((1 << w) - 1)) != x[h])
|
||||
{
|
||||
h--; /* don't need to update q */
|
||||
w -= l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Return true (1) if we were given an incomplete table */
|
||||
return y != 0 && g != 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int huft_free(t)
|
||||
struct huft *t; /* table to free */
|
||||
/* Free the malloc'ed tables built by huft_build(), which makes a linked
|
||||
list of the tables it made, with the links in a dummy first entry of
|
||||
each table. */
|
||||
{
|
||||
register struct huft *p, *q;
|
||||
|
||||
|
||||
/* Go through linked list, freeing from the malloced (t[-1]) address. */
|
||||
p = t;
|
||||
while (p != (struct huft *)NULL)
|
||||
{
|
||||
q = (--p)->v.t;
|
||||
free((char*)p);
|
||||
p = q;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int inflate_codes(tl, td, bl, bd)
|
||||
struct huft *tl, *td; /* literal/length and distance decoder tables */
|
||||
int bl, bd; /* number of bits decoded by tl[] and td[] */
|
||||
/* inflate (decompress) the codes in a deflated (compressed) block.
|
||||
Return an error code or zero if it all goes ok. */
|
||||
{
|
||||
register unsigned e; /* table entry flag/number of extra bits */
|
||||
unsigned n, d; /* length and index for copy */
|
||||
unsigned w; /* current window position */
|
||||
struct huft *t; /* pointer to table entry */
|
||||
unsigned ml, md; /* masks for bl and bd bits */
|
||||
register ulg b; /* bit buffer */
|
||||
register unsigned k; /* number of bits in bit buffer */
|
||||
|
||||
|
||||
/* make local copies of globals */
|
||||
b = bb; /* initialize bit buffer */
|
||||
k = bk;
|
||||
w = wp; /* initialize window position */
|
||||
|
||||
/* inflate the coded data */
|
||||
ml = mask_bits[bl]; /* precompute masks for speed */
|
||||
md = mask_bits[bd];
|
||||
for (;;) /* do until end of block */
|
||||
{
|
||||
NEEDBITS((unsigned)bl)
|
||||
if ((e = (t = tl + ((unsigned)b & ml))->e) > 16)
|
||||
do {
|
||||
if (e == 99)
|
||||
return 1;
|
||||
DUMPBITS(t->b)
|
||||
e -= 16;
|
||||
NEEDBITS(e)
|
||||
} while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16);
|
||||
DUMPBITS(t->b)
|
||||
if (e == 16) /* then it's a literal */
|
||||
{
|
||||
slide[w++] = (uch)t->v.n;
|
||||
Tracevv((stderr, "%c", slide[w-1]));
|
||||
if (w == WSIZE)
|
||||
{
|
||||
flush_output(w);
|
||||
w = 0;
|
||||
}
|
||||
}
|
||||
else /* it's an EOB or a length */
|
||||
{
|
||||
/* exit if end of block */
|
||||
if (e == 15)
|
||||
break;
|
||||
|
||||
/* get length of block to copy */
|
||||
NEEDBITS(e)
|
||||
n = t->v.n + ((unsigned)b & mask_bits[e]);
|
||||
DUMPBITS(e);
|
||||
|
||||
/* decode distance of block to copy */
|
||||
NEEDBITS((unsigned)bd)
|
||||
if ((e = (t = td + ((unsigned)b & md))->e) > 16)
|
||||
do {
|
||||
if (e == 99)
|
||||
return 1;
|
||||
DUMPBITS(t->b)
|
||||
e -= 16;
|
||||
NEEDBITS(e)
|
||||
} while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16);
|
||||
DUMPBITS(t->b)
|
||||
NEEDBITS(e)
|
||||
d = w - t->v.n - ((unsigned)b & mask_bits[e]);
|
||||
DUMPBITS(e)
|
||||
Tracevv((stderr,"\\[%d,%d]", w-d, n));
|
||||
|
||||
/* do the copy */
|
||||
do {
|
||||
n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
|
||||
#if !defined(NOMEMCPY) && !defined(DEBUG)
|
||||
if (w - d >= e) /* (this test assumes unsigned comparison) */
|
||||
{
|
||||
memcpy(slide + w, slide + d, e);
|
||||
w += e;
|
||||
d += e;
|
||||
}
|
||||
else /* do it slow to avoid memcpy() overlap */
|
||||
#endif /* !NOMEMCPY */
|
||||
do {
|
||||
slide[w++] = slide[d++];
|
||||
Tracevv((stderr, "%c", slide[w-1]));
|
||||
} while (--e);
|
||||
if (w == WSIZE)
|
||||
{
|
||||
flush_output(w);
|
||||
w = 0;
|
||||
}
|
||||
} while (n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* restore the globals from the locals */
|
||||
wp = w; /* restore global window pointer */
|
||||
bb = b; /* restore global bit buffer */
|
||||
bk = k;
|
||||
|
||||
/* done */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int inflate_stored()
|
||||
/* "decompress" an inflated type 0 (stored) block. */
|
||||
{
|
||||
unsigned n; /* number of bytes in block */
|
||||
unsigned w; /* current window position */
|
||||
register ulg b; /* bit buffer */
|
||||
register unsigned k; /* number of bits in bit buffer */
|
||||
|
||||
|
||||
/* make local copies of globals */
|
||||
b = bb; /* initialize bit buffer */
|
||||
k = bk;
|
||||
w = wp; /* initialize window position */
|
||||
|
||||
|
||||
/* go to byte boundary */
|
||||
n = k & 7;
|
||||
DUMPBITS(n);
|
||||
|
||||
|
||||
/* get the length and its complement */
|
||||
NEEDBITS(16)
|
||||
n = ((unsigned)b & 0xffff);
|
||||
DUMPBITS(16)
|
||||
NEEDBITS(16)
|
||||
if (n != (unsigned)((~b) & 0xffff))
|
||||
return 1; /* error in compressed data */
|
||||
DUMPBITS(16)
|
||||
|
||||
|
||||
/* read and output the compressed data */
|
||||
while (n--)
|
||||
{
|
||||
NEEDBITS(8)
|
||||
slide[w++] = (uch)b;
|
||||
if (w == WSIZE)
|
||||
{
|
||||
flush_output(w);
|
||||
w = 0;
|
||||
}
|
||||
DUMPBITS(8)
|
||||
}
|
||||
|
||||
|
||||
/* restore the globals from the locals */
|
||||
wp = w; /* restore global window pointer */
|
||||
bb = b; /* restore global bit buffer */
|
||||
bk = k;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int inflate_fixed()
|
||||
/* decompress an inflated type 1 (fixed Huffman codes) block. We should
|
||||
either replace this with a custom decoder, or at least precompute the
|
||||
Huffman tables. */
|
||||
{
|
||||
int i; /* temporary variable */
|
||||
struct huft *tl; /* literal/length code table */
|
||||
struct huft *td; /* distance code table */
|
||||
int bl; /* lookup bits for tl */
|
||||
int bd; /* lookup bits for td */
|
||||
unsigned l[288]; /* length list for huft_build */
|
||||
|
||||
|
||||
/* set up literal table */
|
||||
for (i = 0; i < 144; i++)
|
||||
l[i] = 8;
|
||||
for (; i < 256; i++)
|
||||
l[i] = 9;
|
||||
for (; i < 280; i++)
|
||||
l[i] = 7;
|
||||
for (; i < 288; i++) /* make a complete, but wrong code set */
|
||||
l[i] = 8;
|
||||
bl = 7;
|
||||
if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0)
|
||||
return i;
|
||||
|
||||
|
||||
/* set up distance table */
|
||||
for (i = 0; i < 30; i++) /* make an incomplete code set */
|
||||
l[i] = 5;
|
||||
bd = 5;
|
||||
if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1)
|
||||
{
|
||||
huft_free(tl);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/* decompress until an end-of-block code */
|
||||
if (inflate_codes(tl, td, bl, bd))
|
||||
return 1;
|
||||
|
||||
|
||||
/* free the decoding tables, return */
|
||||
huft_free(tl);
|
||||
huft_free(td);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int inflate_dynamic()
|
||||
/* decompress an inflated type 2 (dynamic Huffman codes) block. */
|
||||
{
|
||||
int i; /* temporary variables */
|
||||
unsigned j;
|
||||
unsigned l; /* last length */
|
||||
unsigned m; /* mask for bit lengths table */
|
||||
unsigned n; /* number of lengths to get */
|
||||
struct huft *tl; /* literal/length code table */
|
||||
struct huft *td; /* distance code table */
|
||||
int bl; /* lookup bits for tl */
|
||||
int bd; /* lookup bits for td */
|
||||
unsigned nb; /* number of bit length codes */
|
||||
unsigned nl; /* number of literal/length codes */
|
||||
unsigned nd; /* number of distance codes */
|
||||
#ifdef PKZIP_BUG_WORKAROUND
|
||||
unsigned ll[288+32]; /* literal/length and distance code lengths */
|
||||
#else
|
||||
unsigned ll[286+30]; /* literal/length and distance code lengths */
|
||||
#endif
|
||||
register ulg b; /* bit buffer */
|
||||
register unsigned k; /* number of bits in bit buffer */
|
||||
|
||||
|
||||
/* make local bit buffer */
|
||||
b = bb;
|
||||
k = bk;
|
||||
|
||||
|
||||
/* read in table lengths */
|
||||
NEEDBITS(5)
|
||||
nl = 257 + ((unsigned)b & 0x1f); /* number of literal/length codes */
|
||||
DUMPBITS(5)
|
||||
NEEDBITS(5)
|
||||
nd = 1 + ((unsigned)b & 0x1f); /* number of distance codes */
|
||||
DUMPBITS(5)
|
||||
NEEDBITS(4)
|
||||
nb = 4 + ((unsigned)b & 0xf); /* number of bit length codes */
|
||||
DUMPBITS(4)
|
||||
#ifdef PKZIP_BUG_WORKAROUND
|
||||
if (nl > 288 || nd > 32)
|
||||
#else
|
||||
if (nl > 286 || nd > 30)
|
||||
#endif
|
||||
return 1; /* bad lengths */
|
||||
|
||||
|
||||
/* read in bit-length-code lengths */
|
||||
for (j = 0; j < nb; j++)
|
||||
{
|
||||
NEEDBITS(3)
|
||||
ll[border[j]] = (unsigned)b & 7;
|
||||
DUMPBITS(3)
|
||||
}
|
||||
for (; j < 19; j++)
|
||||
ll[border[j]] = 0;
|
||||
|
||||
|
||||
/* build decoding table for trees--single level, 7 bit lookup */
|
||||
bl = 7;
|
||||
if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0)
|
||||
{
|
||||
if (i == 1)
|
||||
huft_free(tl);
|
||||
return i; /* incomplete code set */
|
||||
}
|
||||
|
||||
|
||||
/* read in literal and distance code lengths */
|
||||
n = nl + nd;
|
||||
m = mask_bits[bl];
|
||||
i = l = 0;
|
||||
while ((unsigned)i < n)
|
||||
{
|
||||
NEEDBITS((unsigned)bl)
|
||||
j = (td = tl + ((unsigned)b & m))->b;
|
||||
DUMPBITS(j)
|
||||
j = td->v.n;
|
||||
if (j < 16) /* length of code in bits (0..15) */
|
||||
ll[i++] = l = j; /* save last length in l */
|
||||
else if (j == 16) /* repeat last length 3 to 6 times */
|
||||
{
|
||||
NEEDBITS(2)
|
||||
j = 3 + ((unsigned)b & 3);
|
||||
DUMPBITS(2)
|
||||
if ((unsigned)i + j > n)
|
||||
return 1;
|
||||
while (j--)
|
||||
ll[i++] = l;
|
||||
}
|
||||
else if (j == 17) /* 3 to 10 zero length codes */
|
||||
{
|
||||
NEEDBITS(3)
|
||||
j = 3 + ((unsigned)b & 7);
|
||||
DUMPBITS(3)
|
||||
if ((unsigned)i + j > n)
|
||||
return 1;
|
||||
while (j--)
|
||||
ll[i++] = 0;
|
||||
l = 0;
|
||||
}
|
||||
else /* j == 18: 11 to 138 zero length codes */
|
||||
{
|
||||
NEEDBITS(7)
|
||||
j = 11 + ((unsigned)b & 0x7f);
|
||||
DUMPBITS(7)
|
||||
if ((unsigned)i + j > n)
|
||||
return 1;
|
||||
while (j--)
|
||||
ll[i++] = 0;
|
||||
l = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* free decoding table for trees */
|
||||
huft_free(tl);
|
||||
|
||||
|
||||
/* restore the global bit buffer */
|
||||
bb = b;
|
||||
bk = k;
|
||||
|
||||
|
||||
/* build the decoding tables for literal/length and distance codes */
|
||||
bl = lbits;
|
||||
if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0)
|
||||
{
|
||||
if (i == 1) {
|
||||
fprintf(stderr, " incomplete literal tree\n");
|
||||
huft_free(tl);
|
||||
}
|
||||
return i; /* incomplete code set */
|
||||
}
|
||||
bd = dbits;
|
||||
if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0)
|
||||
{
|
||||
if (i == 1) {
|
||||
fprintf(stderr, " incomplete distance tree\n");
|
||||
#ifdef PKZIP_BUG_WORKAROUND
|
||||
i = 0;
|
||||
}
|
||||
#else
|
||||
huft_free(td);
|
||||
}
|
||||
huft_free(tl);
|
||||
return i; /* incomplete code set */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* decompress until an end-of-block code */
|
||||
if (inflate_codes(tl, td, bl, bd))
|
||||
return 1;
|
||||
|
||||
|
||||
/* free the decoding tables, return */
|
||||
huft_free(tl);
|
||||
huft_free(td);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int inflate_block(e)
|
||||
int *e; /* last block flag */
|
||||
/* decompress an inflated block */
|
||||
{
|
||||
unsigned t; /* block type */
|
||||
register ulg b; /* bit buffer */
|
||||
register unsigned k; /* number of bits in bit buffer */
|
||||
|
||||
|
||||
/* make local bit buffer */
|
||||
b = bb;
|
||||
k = bk;
|
||||
|
||||
|
||||
/* read in last block bit */
|
||||
NEEDBITS(1)
|
||||
*e = (int)b & 1;
|
||||
DUMPBITS(1)
|
||||
|
||||
|
||||
/* read in block type */
|
||||
NEEDBITS(2)
|
||||
t = (unsigned)b & 3;
|
||||
DUMPBITS(2)
|
||||
|
||||
|
||||
/* restore the global bit buffer */
|
||||
bb = b;
|
||||
bk = k;
|
||||
|
||||
|
||||
/* inflate that block type */
|
||||
if (t == 2)
|
||||
return inflate_dynamic();
|
||||
if (t == 0)
|
||||
return inflate_stored();
|
||||
if (t == 1)
|
||||
return inflate_fixed();
|
||||
|
||||
|
||||
/* bad block type */
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int inflate()
|
||||
/* decompress an inflated entry */
|
||||
{
|
||||
int e; /* last block flag */
|
||||
int r; /* result code */
|
||||
unsigned h; /* maximum struct huft's malloc'ed */
|
||||
|
||||
|
||||
/* initialize window, bit buffer */
|
||||
wp = 0;
|
||||
bk = 0;
|
||||
bb = 0;
|
||||
|
||||
|
||||
/* decompress until the last block */
|
||||
h = 0;
|
||||
do {
|
||||
hufts = 0;
|
||||
if ((r = inflate_block(&e)) != 0)
|
||||
return r;
|
||||
if (hufts > h)
|
||||
h = hufts;
|
||||
} while (!e);
|
||||
|
||||
/* Undo too much lookahead. The next read will be byte aligned so we
|
||||
* can discard unused bits in the last meaningful byte.
|
||||
*/
|
||||
while (bk >= 8) {
|
||||
bk -= 8;
|
||||
inptr--;
|
||||
}
|
||||
|
||||
/* flush out slide */
|
||||
flush_output(wp);
|
||||
|
||||
|
||||
/* return success */
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "<%u> ", h);
|
||||
#endif /* DEBUG */
|
||||
return 0;
|
||||
}
|
27
gnu/usr.bin/gzip/lzw.c
Normal file
27
gnu/usr.bin/gzip/lzw.c
Normal file
@ -0,0 +1,27 @@
|
||||
/* lzw.c -- compress files in LZW format.
|
||||
* This is a dummy version avoiding patent problems.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: lzw.c,v 0.8 1993/04/25 08:09:58 jloup Exp $";
|
||||
#endif
|
||||
|
||||
#include "tailor.h"
|
||||
#include "gzip.h"
|
||||
#include "lzw.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static int msg_done = 0;
|
||||
|
||||
/* Compress in to out with lzw method. */
|
||||
int lzw(in, out)
|
||||
int in, out;
|
||||
{
|
||||
if (msg_done) return ERROR;
|
||||
msg_done = 1;
|
||||
fprintf(stderr,"output in compress .Z format not supported\n");
|
||||
in++, out++; /* avoid warnings on unused variables */
|
||||
exit_code = ERROR;
|
||||
return ERROR;
|
||||
}
|
42
gnu/usr.bin/gzip/lzw.h
Normal file
42
gnu/usr.bin/gzip/lzw.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* lzw.h -- define the lzw functions.
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
#if !defined(OF) && defined(lint)
|
||||
# include "gzip.h"
|
||||
#endif
|
||||
|
||||
#ifndef BITS
|
||||
# define BITS 16
|
||||
#endif
|
||||
#define INIT_BITS 9 /* Initial number of bits per code */
|
||||
|
||||
#define LZW_MAGIC "\037\235" /* Magic header for lzw files, 1F 9D */
|
||||
|
||||
#define BIT_MASK 0x1f /* Mask for 'number of compression bits' */
|
||||
/* Mask 0x20 is reserved to mean a fourth header byte, and 0x40 is free.
|
||||
* It's a pity that old uncompress does not check bit 0x20. That makes
|
||||
* extension of the format actually undesirable because old compress
|
||||
* would just crash on the new format instead of giving a meaningful
|
||||
* error message. It does check the number of bits, but it's more
|
||||
* helpful to say "unsupported format, get a new version" than
|
||||
* "can only handle 16 bits".
|
||||
*/
|
||||
|
||||
#define BLOCK_MODE 0x80
|
||||
/* Block compression: if table is full and compression rate is dropping,
|
||||
* clear the dictionary.
|
||||
*/
|
||||
|
||||
#define LZW_RESERVED 0x60 /* reserved bits */
|
||||
|
||||
#define CLEAR 256 /* flush the dictionary */
|
||||
#define FIRST (CLEAR+1) /* first free entry */
|
||||
|
||||
extern int maxbits; /* max bits per code for LZW */
|
||||
extern int block_mode; /* block compress mode -C compatible with 2.0 */
|
||||
|
||||
extern int lzw OF((int in, int out));
|
||||
extern int unlzw OF((int in, int out));
|
379
gnu/usr.bin/gzip/match.S
Normal file
379
gnu/usr.bin/gzip/match.S
Normal file
@ -0,0 +1,379 @@
|
||||
/* match.s -- optional optimized asm version of longest match in deflate.c
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*
|
||||
* The 68020 version has been written by Francesco Potorti` <pot@cnuce.cnr.it>
|
||||
* with adaptations by Carsten Steger <stegerc@informatik.tu-muenchen.de>,
|
||||
* Andreas Schwab <schwab@lamothe.informatik.uni-dortmund.de> and
|
||||
* Kristoffer Eriksson <ske@pkmab.se>
|
||||
*/
|
||||
|
||||
/* $Id: match.S,v 0.13 1993/05/24 12:03:03 jloup Exp $ */
|
||||
|
||||
/* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix
|
||||
* external symbols with an underline character '_'.
|
||||
*/
|
||||
#ifdef NO_UNDERLINE
|
||||
# define _prev prev
|
||||
# define _window window
|
||||
# define _match_start match_start
|
||||
# define _prev_length prev_length
|
||||
# define _good_match good_match
|
||||
# define _nice_match nice_match
|
||||
# define _strstart strstart
|
||||
# define _max_chain_length max_chain_length
|
||||
|
||||
# define _match_init match_init
|
||||
# define _longest_match longest_match
|
||||
#endif
|
||||
|
||||
#ifdef DYN_ALLOC
|
||||
error: DYN_ALLOC not yet supported in match.s
|
||||
#endif
|
||||
|
||||
#if defined(i386) || defined(_I386)
|
||||
|
||||
/* This version is for 386 Unix or OS/2 in 32 bit mode.
|
||||
* Warning: it uses the AT&T syntax: mov source,dest
|
||||
* This file is only optional. If you want to force the C version,
|
||||
* add -DNO_ASM to CFLAGS in Makefile and set OBJA to an empty string.
|
||||
* If you have reduced WSIZE in gzip.h, then change its value below.
|
||||
* This version assumes static allocation of the arrays (-DDYN_ALLOC not used).
|
||||
*/
|
||||
|
||||
.file "match.S"
|
||||
|
||||
#define MAX_MATCH 258
|
||||
#define MAX_MATCH2 128 /* MAX_MATCH/2-1 */
|
||||
#define MIN_MATCH 3
|
||||
#define WSIZE 32768
|
||||
#define MAX_DIST WSIZE - MAX_MATCH - MIN_MATCH - 1
|
||||
|
||||
.globl _match_init
|
||||
.globl _longest_match
|
||||
|
||||
.text
|
||||
|
||||
_match_init:
|
||||
ret
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Set match_start to the longest match starting at the given string and
|
||||
* return its length. Matches shorter or equal to prev_length are discarded,
|
||||
* in which case the result is equal to prev_length and match_start is
|
||||
* garbage.
|
||||
* IN assertions: cur_match is the head of the hash chain for the current
|
||||
* string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
|
||||
*/
|
||||
|
||||
_longest_match: /* int longest_match(cur_match) */
|
||||
|
||||
#define cur_match 20(%esp)
|
||||
/* return address */ /* esp+16 */
|
||||
push %ebp /* esp+12 */
|
||||
push %edi /* esp+8 */
|
||||
push %esi /* esp+4 */
|
||||
push %ebx /* esp */
|
||||
|
||||
/*
|
||||
* match equ esi
|
||||
* scan equ edi
|
||||
* chain_length equ ebp
|
||||
* best_len equ ebx
|
||||
* limit equ edx
|
||||
*/
|
||||
mov cur_match,%esi
|
||||
mov _max_chain_length,%ebp /* chain_length = max_chain_length */
|
||||
mov _strstart,%edi
|
||||
mov %edi,%edx
|
||||
sub $ MAX_DIST,%edx /* limit = strstart-MAX_DIST */
|
||||
jae limit_ok
|
||||
sub %edx,%edx /* limit = NIL */
|
||||
limit_ok:
|
||||
add $ _window+2,%edi /* edi = offset(window+strstart+2) */
|
||||
mov _prev_length,%ebx /* best_len = prev_length */
|
||||
movw -3(%ebx,%edi),%ax /* ax = scan[best_len-1..best_len] */
|
||||
movw -2(%edi),%cx /* cx = scan[0..1] */
|
||||
cmp _good_match,%ebx /* do we have a good match already? */
|
||||
jb do_scan
|
||||
shr $2,%ebp /* chain_length >>= 2 */
|
||||
jmp do_scan
|
||||
|
||||
.align 4
|
||||
long_loop:
|
||||
/* at this point, edi == scan+2, esi == cur_match */
|
||||
movw -3(%ebx,%edi),%ax /* ax = scan[best_len-1..best_len] */
|
||||
movw -2(%edi),%cx /* cx = scan[0..1] */
|
||||
short_loop:
|
||||
/*
|
||||
* at this point, di == scan+2, si == cur_match,
|
||||
* ax = scan[best_len-1..best_len] and cx = scan[0..1]
|
||||
*/
|
||||
and $ WSIZE-1, %esi
|
||||
movw _prev(%esi,%esi),%si /* cur_match = prev[cur_match] */
|
||||
/* top word of esi is still 0 */
|
||||
cmp %edx,%esi /* cur_match <= limit ? */
|
||||
jbe the_end
|
||||
dec %ebp /* --chain_length */
|
||||
jz the_end
|
||||
do_scan:
|
||||
cmpw _window-1(%ebx,%esi),%ax/* check match at best_len-1 */
|
||||
jne short_loop
|
||||
cmpw _window(%esi),%cx /* check min_match_length match */
|
||||
jne short_loop
|
||||
|
||||
lea _window+2(%esi),%esi /* si = match */
|
||||
mov %edi,%eax /* ax = scan+2 */
|
||||
mov $ MAX_MATCH2,%ecx /* scan for at most MAX_MATCH bytes */
|
||||
rep; cmpsw /* loop until mismatch */
|
||||
je maxmatch /* match of length MAX_MATCH? */
|
||||
mismatch:
|
||||
movb -2(%edi),%cl /* mismatch on first or second byte? */
|
||||
subb -2(%esi),%cl /* cl = 0 if first bytes equal */
|
||||
xchg %edi,%eax /* edi = scan+2, eax = end of scan */
|
||||
sub %edi,%eax /* eax = len */
|
||||
sub %eax,%esi /* esi = cur_match + 2 + offset(window) */
|
||||
sub $ _window+2,%esi /* esi = cur_match */
|
||||
subb $1,%cl /* set carry if cl == 0 (cannot use DEC) */
|
||||
adc $0,%eax /* eax = carry ? len+1 : len */
|
||||
cmp %ebx,%eax /* len > best_len ? */
|
||||
jle long_loop
|
||||
mov %esi,_match_start /* match_start = cur_match */
|
||||
mov %eax,%ebx /* ebx = best_len = len */
|
||||
cmp _nice_match,%eax /* len >= nice_match ? */
|
||||
jl long_loop
|
||||
the_end:
|
||||
mov %ebx,%eax /* result = eax = best_len */
|
||||
pop %ebx
|
||||
pop %esi
|
||||
pop %edi
|
||||
pop %ebp
|
||||
ret
|
||||
maxmatch:
|
||||
cmpsb
|
||||
jmp mismatch
|
||||
|
||||
#else
|
||||
|
||||
/* ======================== 680x0 version ================================= */
|
||||
|
||||
#if defined(m68k)||defined(mc68k)||defined(__mc68000__)||defined(__MC68000__)
|
||||
# ifndef mc68000
|
||||
# define mc68000
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__mc68020__) || defined(__MC68020__) || defined(sysV68)
|
||||
# ifndef mc68020
|
||||
# define mc68020
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(mc68020) || defined(mc68000)
|
||||
|
||||
#if (defined(mc68020) || defined(NeXT)) && !defined(UNALIGNED_OK)
|
||||
# define UNALIGNED_OK
|
||||
#endif
|
||||
|
||||
#ifdef sysV68 /* Try Motorola Delta style */
|
||||
|
||||
# define GLOBAL(symbol) global symbol
|
||||
# define TEXT text
|
||||
# define FILE(filename) file filename
|
||||
# define invert_maybe(src,dst) dst,src
|
||||
# define imm(data) &data
|
||||
# define reg(register) %register
|
||||
|
||||
# define addl add.l
|
||||
# define addql addq.l
|
||||
# define blos blo.b
|
||||
# define bhis bhi.b
|
||||
# define bras bra.b
|
||||
# define clrl clr.l
|
||||
# define cmpmb cmpm.b
|
||||
# define cmpw cmp.w
|
||||
# define cmpl cmp.l
|
||||
# define lslw lsl.w
|
||||
# define lsrl lsr.l
|
||||
# define movel move.l
|
||||
# define movew move.w
|
||||
# define moveb move.b
|
||||
# define moveml movem.l
|
||||
# define subl sub.l
|
||||
# define subw sub.w
|
||||
# define subql subq.l
|
||||
|
||||
# define IndBase(bd,An) (bd,An)
|
||||
# define IndBaseNdxl(bd,An,Xn) (bd,An,Xn.l)
|
||||
# define IndBaseNdxw(bd,An,Xn) (bd,An,Xn.w)
|
||||
# define predec(An) -(An)
|
||||
# define postinc(An) (An)+
|
||||
|
||||
#else /* default style (Sun 3, NeXT, Amiga, Atari) */
|
||||
|
||||
# define GLOBAL(symbol) .globl symbol
|
||||
# define TEXT .text
|
||||
# define FILE(filename) .even
|
||||
# define invert_maybe(src,dst) src,dst
|
||||
# if defined(sun) || defined(mc68k)
|
||||
# define imm(data) #data
|
||||
# else
|
||||
# define imm(data) \#data
|
||||
# endif
|
||||
# define reg(register) register
|
||||
|
||||
# define blos bcss
|
||||
# if defined(sun) || defined(mc68k)
|
||||
# define movel movl
|
||||
# define movew movw
|
||||
# define moveb movb
|
||||
# endif
|
||||
# define IndBase(bd,An) An@(bd)
|
||||
# define IndBaseNdxl(bd,An,Xn) An@(bd,Xn:l)
|
||||
# define IndBaseNdxw(bd,An,Xn) An@(bd,Xn:w)
|
||||
# define predec(An) An@-
|
||||
# define postinc(An) An@+
|
||||
|
||||
#endif /* styles */
|
||||
|
||||
#define Best_Len reg(d0) /* unsigned */
|
||||
#define Cur_Match reg(d1) /* Ipos */
|
||||
#define Loop_Counter reg(d2) /* int */
|
||||
#define Scan_Start reg(d3) /* unsigned short */
|
||||
#define Scan_End reg(d4) /* unsigned short */
|
||||
#define Limit reg(d5) /* IPos */
|
||||
#define Chain_Length reg(d6) /* unsigned */
|
||||
#define Scan_Test reg(d7)
|
||||
#define Scan reg(a0) /* *uch */
|
||||
#define Match reg(a1) /* *uch */
|
||||
#define Prev_Address reg(a2) /* *Pos */
|
||||
#define Scan_Ini reg(a3) /* *uch */
|
||||
#define Match_Ini reg(a4) /* *uch */
|
||||
#define Stack_Pointer reg(sp)
|
||||
|
||||
#define MAX_MATCH 258
|
||||
#define MIN_MATCH 3
|
||||
#define WSIZE 32768
|
||||
#define MAX_DIST (WSIZE - MAX_MATCH - MIN_MATCH - 1)
|
||||
|
||||
GLOBAL (_match_init)
|
||||
GLOBAL (_longest_match)
|
||||
|
||||
TEXT
|
||||
|
||||
FILE ("match.S")
|
||||
|
||||
_match_init:
|
||||
rts
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Set match_start to the longest match starting at the given string and
|
||||
* return its length. Matches shorter or equal to prev_length are discarded,
|
||||
* in which case the result is equal to prev_length and match_start is
|
||||
* garbage.
|
||||
* IN assertions: cur_match is the head of the hash chain for the current
|
||||
* string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
|
||||
*/
|
||||
|
||||
/* int longest_match (cur_match) */
|
||||
|
||||
#ifdef UNALIGNED_OK
|
||||
# define pushreg 15928 /* d2-d6/a2-a4 */
|
||||
# define popreg 7292
|
||||
#else
|
||||
# define pushreg 16184 /* d2-d7/a2-a4 */
|
||||
# define popreg 7420
|
||||
#endif
|
||||
|
||||
_longest_match:
|
||||
movel IndBase(4,Stack_Pointer),Cur_Match
|
||||
moveml imm(pushreg),predec(Stack_Pointer)
|
||||
movel _max_chain_length,Chain_Length
|
||||
movel _prev_length,Best_Len
|
||||
movel imm(_prev),Prev_Address
|
||||
movel imm(_window+MIN_MATCH),Match_Ini
|
||||
movel _strstart,Limit
|
||||
movel Match_Ini,Scan_Ini
|
||||
addl Limit,Scan_Ini
|
||||
subw imm(MAX_DIST),Limit
|
||||
bhis L__limit_ok
|
||||
clrl Limit
|
||||
L__limit_ok:
|
||||
cmpl invert_maybe(_good_match,Best_Len)
|
||||
blos L__length_ok
|
||||
lsrl imm(2),Chain_Length
|
||||
L__length_ok:
|
||||
subql imm(1),Chain_Length
|
||||
#ifdef UNALIGNED_OK
|
||||
movew IndBase(-MIN_MATCH,Scan_Ini),Scan_Start
|
||||
movew IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
|
||||
#else
|
||||
moveb IndBase(-MIN_MATCH,Scan_Ini),Scan_Start
|
||||
lslw imm(8),Scan_Start
|
||||
moveb IndBase(-MIN_MATCH+1,Scan_Ini),Scan_Start
|
||||
moveb IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
|
||||
lslw imm(8),Scan_End
|
||||
moveb IndBaseNdxw(-MIN_MATCH,Scan_Ini,Best_Len),Scan_End
|
||||
#endif
|
||||
bras L__do_scan
|
||||
|
||||
L__long_loop:
|
||||
#ifdef UNALIGNED_OK
|
||||
movew IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
|
||||
#else
|
||||
moveb IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
|
||||
lslw imm(8),Scan_End
|
||||
moveb IndBaseNdxw(-MIN_MATCH,Scan_Ini,Best_Len),Scan_End
|
||||
#endif
|
||||
|
||||
L__short_loop:
|
||||
lslw imm(1),Cur_Match
|
||||
movew IndBaseNdxl(0,Prev_Address,Cur_Match),Cur_Match
|
||||
cmpw invert_maybe(Limit,Cur_Match)
|
||||
dbls Chain_Length,L__do_scan
|
||||
bras L__return
|
||||
|
||||
L__do_scan:
|
||||
movel Match_Ini,Match
|
||||
addl Cur_Match,Match
|
||||
#ifdef UNALIGNED_OK
|
||||
cmpw invert_maybe(IndBaseNdxw(-MIN_MATCH-1,Match,Best_Len),Scan_End)
|
||||
bne L__short_loop
|
||||
cmpw invert_maybe(IndBase(-MIN_MATCH,Match),Scan_Start)
|
||||
bne L__short_loop
|
||||
#else
|
||||
moveb IndBaseNdxw(-MIN_MATCH-1,Match,Best_Len),Scan_Test
|
||||
lslw imm(8),Scan_Test
|
||||
moveb IndBaseNdxw(-MIN_MATCH,Match,Best_Len),Scan_Test
|
||||
cmpw invert_maybe(Scan_Test,Scan_End)
|
||||
bne L__short_loop
|
||||
moveb IndBase(-MIN_MATCH,Match),Scan_Test
|
||||
lslw imm(8),Scan_Test
|
||||
moveb IndBase(-MIN_MATCH+1,Match),Scan_Test
|
||||
cmpw invert_maybe(Scan_Test,Scan_Start)
|
||||
bne L__short_loop
|
||||
#endif
|
||||
|
||||
movew imm((MAX_MATCH-MIN_MATCH+1)-1),Loop_Counter
|
||||
movel Scan_Ini,Scan
|
||||
L__scan_loop:
|
||||
cmpmb postinc(Match),postinc(Scan)
|
||||
dbne Loop_Counter,L__scan_loop
|
||||
|
||||
subl Scan_Ini,Scan
|
||||
addql imm(MIN_MATCH-1),Scan
|
||||
cmpl invert_maybe(Best_Len,Scan)
|
||||
bls L__short_loop
|
||||
movel Scan,Best_Len
|
||||
movel Cur_Match,_match_start
|
||||
cmpl invert_maybe(_nice_match,Best_Len)
|
||||
blos L__long_loop
|
||||
L__return:
|
||||
moveml postinc(Stack_Pointer),imm(popreg)
|
||||
rts
|
||||
|
||||
#else
|
||||
error: this asm version is for 386 or 680x0 only
|
||||
#endif /* mc68000 || mc68020 */
|
||||
#endif /* i386 || _I386 */
|
16
gnu/usr.bin/gzip/revision.h
Normal file
16
gnu/usr.bin/gzip/revision.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* revision.h -- define the version number
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
#define VERSION "1.1.1"
|
||||
#define PATCHLEVEL 0
|
||||
#define REVDATE "1 Jun 93"
|
||||
|
||||
/* This version does not support compression into old compress format: */
|
||||
#ifdef LZW
|
||||
# undef LZW
|
||||
#endif
|
||||
|
||||
/* $Id: revision.h,v 0.20 1993/06/01 14:03:17 jloup Exp $ */
|
268
gnu/usr.bin/gzip/tailor.h
Normal file
268
gnu/usr.bin/gzip/tailor.h
Normal file
@ -0,0 +1,268 @@
|
||||
/* tailor.h -- target dependent definitions
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
/* The target dependent definitions should be defined here only.
|
||||
* The target dependent functions should be defined in tailor.c.
|
||||
*/
|
||||
|
||||
/* $Id: tailor.h,v 0.16 1993/06/01 12:46:03 jloup Exp $ */
|
||||
|
||||
#if defined(__MSDOS__) && !defined(MSDOS)
|
||||
# define MSDOS
|
||||
#endif
|
||||
|
||||
#if defined(OS2) && defined(MSDOS) /* MS C under OS/2 */
|
||||
# undef MSDOS
|
||||
#endif
|
||||
|
||||
#ifdef MSDOS
|
||||
# ifdef __GNUC__
|
||||
/* DJGPP version 1.09+ on MS-DOS.
|
||||
* The DJGPP 1.09 stat() function must be upgraded before gzip will
|
||||
* fully work.
|
||||
* No need for DIRENT, since <unistd.h> defines POSIX_SOURCE which
|
||||
* implies DIRENT.
|
||||
*/
|
||||
# define near
|
||||
# else
|
||||
# define MAXSEG_64K
|
||||
# ifdef __TURBOC__
|
||||
# define NO_UTIME
|
||||
# else /* MSC */
|
||||
# define HAVE_SYS_UTIME_H
|
||||
# define NO_UTIME_H
|
||||
# endif
|
||||
# endif
|
||||
# define PATH_SEP2 '\\'
|
||||
# define PATH_SEP3 ':'
|
||||
# define MAX_PATH_LEN 128
|
||||
# define NO_MULTIPLE_DOTS
|
||||
# define MAX_EXT_CHARS 3
|
||||
# define Z_SUFFIX "z"
|
||||
# define NO_CHOWN
|
||||
# define PROTO
|
||||
# define STDC_HEADERS
|
||||
# define NO_SIZE_CHECK
|
||||
# define casemap(c) tolow(c) /* Force file names to lower case */
|
||||
# include <io.h>
|
||||
# define OS_CODE 0x00
|
||||
# define SET_BINARY_MODE(fd) setmode(fd, O_BINARY)
|
||||
# if !defined(NO_ASM) && !defined(ASMV)
|
||||
# define ASMV
|
||||
# endif
|
||||
#else
|
||||
# define near
|
||||
#endif
|
||||
|
||||
#ifdef OS2
|
||||
# define PATH_SEP2 '\\'
|
||||
# define PATH_SEP3 ':'
|
||||
# define MAX_PATH_LEN 260
|
||||
# ifdef OS2FAT
|
||||
# define NO_MULTIPLE_DOTS
|
||||
# define MAX_EXT_CHARS 3
|
||||
# define Z_SUFFIX "z"
|
||||
# endif
|
||||
# define NO_CHOWN
|
||||
# define PROTO
|
||||
# define STDC_HEADERS
|
||||
# define HAVE_SYS_UTIME_H
|
||||
# define NO_UTIME_H
|
||||
# define casemap(c) tolow(c)
|
||||
# include <io.h>
|
||||
# define OS_CODE 0x06
|
||||
# define SET_BINARY_MODE(fd) setmode(fd, O_BINARY)
|
||||
# ifdef _MSC_VER
|
||||
# define MAXSEG_64K
|
||||
# undef near
|
||||
# define near _near
|
||||
# endif
|
||||
# ifdef __EMX__
|
||||
# define DIRENT
|
||||
# define EXPAND(argc,argv) \
|
||||
{_response(&argc, &argv); _wildcard(&argc, &argv);}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef MSDOS
|
||||
# ifdef __TURBOC__
|
||||
# include <alloc.h>
|
||||
# define DYN_ALLOC
|
||||
/* Turbo C 2.0 does not accept static allocations of large arrays */
|
||||
void * fcalloc (unsigned items, unsigned size);
|
||||
void fcfree (void *ptr);
|
||||
# else /* MSC */
|
||||
# include <malloc.h>
|
||||
# define fcalloc(nitems,itemsize) halloc((long)(nitems),(itemsize))
|
||||
# define fcfree(ptr) hfree(ptr)
|
||||
# endif
|
||||
#else
|
||||
# ifdef MAXSEG_64K
|
||||
# define fcalloc(items,size) calloc((items),(size))
|
||||
# else
|
||||
# define fcalloc(items,size) malloc((size_t)(items)*(size_t)(size))
|
||||
# endif
|
||||
# define fcfree(ptr) free(ptr)
|
||||
#endif
|
||||
|
||||
#if defined(VAXC) || defined(VMS)
|
||||
# define PATH_SEP ']'
|
||||
# define PATH_SEP2 ':'
|
||||
# define SUFFIX_SEP ';'
|
||||
# define NO_MULTIPLE_DOTS
|
||||
# define Z_SUFFIX "-gz"
|
||||
# define RECORD_IO 1
|
||||
# define casemap(c) tolow(c)
|
||||
# define OS_CODE 0x02
|
||||
# define OPTIONS_VAR "GZIP_OPT"
|
||||
# define STDC_HEADERS
|
||||
# define NO_UTIME
|
||||
# define EXPAND(argc,argv) vms_expand_args(&argc,&argv);
|
||||
# include <file.h>
|
||||
# define unlink delete
|
||||
# ifdef VAXC
|
||||
# define NO_FCNTL_H
|
||||
# include <unixio.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef AMIGA
|
||||
# define PATH_SEP2 ':'
|
||||
# define STDC_HEADERS
|
||||
# define casemap(c) tolow(c) /* Force file names to lower case */
|
||||
# define OS_CODE 0x01
|
||||
# define ASMV
|
||||
# ifdef __GNUC__
|
||||
# define DIRENT
|
||||
# define HAVE_UNISTD_H
|
||||
# define RETSIGTYPE int
|
||||
# else /* SASC */
|
||||
# define NO_STDIN_FSTAT
|
||||
# define SYSDIR
|
||||
# define NO_SYMLINK
|
||||
# define NO_CHOWN
|
||||
# define NO_FCNTL_H
|
||||
# include <fcntl.h> /* for read() and write() */
|
||||
# define direct dirent
|
||||
extern void _expand_args(int *argc, char ***argv);
|
||||
# define EXPAND(argc,argv) _expand_args(&argc,&argv);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(ATARI) || defined(atarist)
|
||||
# ifndef STDC_HEADERS
|
||||
# define STDC_HEADERS
|
||||
# define HAVE_UNISTD_H
|
||||
# define DIRENT
|
||||
# endif
|
||||
# define ASMV
|
||||
# define OS_CODE 0x05
|
||||
# ifdef TOSFS
|
||||
# define NO_SYMLINK
|
||||
# define NO_MULTIPLE_DOTS
|
||||
# define MAX_EXT_CHARS 3
|
||||
# define Z_SUFFIX "z"
|
||||
# define NO_CHOWN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef MACOS
|
||||
# define PATH_SEP ':'
|
||||
# define DYN_ALLOC
|
||||
# define PROTO
|
||||
# define NO_STDIN_FSTAT
|
||||
# define NO_CHOWN
|
||||
# define NO_UTIME
|
||||
# define chmod(file, mode) (0)
|
||||
# define OPEN(name, flags, mode) open(name, flags)
|
||||
# define OS_CODE 0x07
|
||||
# ifdef MPW
|
||||
# define isatty(fd) ((fd) <= 2)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __50SERIES /* Prime/PRIMOS */
|
||||
# define PATH_SEP '>'
|
||||
# define STDC_HEADERS
|
||||
# define NO_MEMORY_H
|
||||
# define NO_UTIME_H
|
||||
# define NO_UTIME
|
||||
# define NO_CHOWN
|
||||
# define NO_STDIN_FSTAT
|
||||
# define NO_SIZE_CHECK
|
||||
# define NO_SYMLINK
|
||||
# define RECORD_IO 1
|
||||
# define casemap(c) tolow(c) /* Force file names to lower case */
|
||||
# define put_char(c) put_byte((c) & 0x7F)
|
||||
# define get_char(c) ascii2pascii(get_byte())
|
||||
# define OS_CODE 0x0F /* temporary, subject to change */
|
||||
# undef SIGTERM /* We don't want a signal handler for SIGTERM */
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# define OS_CODE 0x0b
|
||||
#endif
|
||||
|
||||
#ifdef TOPS20
|
||||
# define OS_CODE 0x0a
|
||||
#endif
|
||||
|
||||
#ifndef unix
|
||||
# define NO_ST_INO /* don't rely on inode numbers */
|
||||
#endif
|
||||
|
||||
|
||||
/* Common defaults */
|
||||
|
||||
#ifndef OS_CODE
|
||||
# define OS_CODE 0x03 /* assume Unix */
|
||||
#endif
|
||||
|
||||
#ifndef PATH_SEP
|
||||
# define PATH_SEP '/'
|
||||
#endif
|
||||
|
||||
#ifndef casemap
|
||||
# define casemap(c) (c)
|
||||
#endif
|
||||
|
||||
#ifndef OPTIONS_VAR
|
||||
# define OPTIONS_VAR "GZIP"
|
||||
#endif
|
||||
|
||||
#ifndef Z_SUFFIX
|
||||
# define Z_SUFFIX ".gz"
|
||||
#endif
|
||||
|
||||
#ifdef MAX_EXT_CHARS
|
||||
# define MAX_SUFFIX MAX_EXT_CHARS
|
||||
#else
|
||||
# define MAX_SUFFIX 30
|
||||
#endif
|
||||
|
||||
#ifndef EXPAND
|
||||
# define EXPAND(argc,argv)
|
||||
#endif
|
||||
|
||||
#ifndef RECORD_IO
|
||||
# define RECORD_IO 0
|
||||
#endif
|
||||
|
||||
#ifndef SET_BINARY_MODE
|
||||
# define SET_BINARY_MODE(fd)
|
||||
#endif
|
||||
|
||||
#ifndef OPEN
|
||||
# define OPEN(name, flags, mode) open(name, flags, mode)
|
||||
#endif
|
||||
|
||||
#ifndef get_char
|
||||
# define get_char() get_byte()
|
||||
#endif
|
||||
|
||||
#ifndef put_char
|
||||
# define put_char(c) put_byte(c)
|
||||
#endif
|
1076
gnu/usr.bin/gzip/trees.c
Normal file
1076
gnu/usr.bin/gzip/trees.c
Normal file
File diff suppressed because it is too large
Load Diff
369
gnu/usr.bin/gzip/unlzw.c
Normal file
369
gnu/usr.bin/gzip/unlzw.c
Normal file
@ -0,0 +1,369 @@
|
||||
/* unlzw.c -- decompress files in LZW format.
|
||||
* The code in this file is directly derived from the public domain 'compress'
|
||||
* written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
|
||||
* Ken Turkowski, Dave Mack and Peter Jannesen.
|
||||
*
|
||||
* This is a temporary version which will be rewritten in some future version
|
||||
* to accommodate in-memory decompression.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: unlzw.c,v 0.13 1993/05/27 10:32:55 jloup Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "tailor.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifndef NO_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include "gzip.h"
|
||||
#include "lzw.h"
|
||||
|
||||
typedef unsigned char char_type;
|
||||
typedef long code_int;
|
||||
typedef unsigned long count_int;
|
||||
typedef unsigned short count_short;
|
||||
typedef unsigned long cmp_code_int;
|
||||
|
||||
#define MAXCODE(n) (1L << (n))
|
||||
|
||||
#ifndef REGISTERS
|
||||
# define REGISTERS 2
|
||||
#endif
|
||||
#define REG1
|
||||
#define REG2
|
||||
#define REG3
|
||||
#define REG4
|
||||
#define REG5
|
||||
#define REG6
|
||||
#define REG7
|
||||
#define REG8
|
||||
#define REG9
|
||||
#define REG10
|
||||
#define REG11
|
||||
#define REG12
|
||||
#define REG13
|
||||
#define REG14
|
||||
#define REG15
|
||||
#define REG16
|
||||
#if REGISTERS >= 1
|
||||
# undef REG1
|
||||
# define REG1 register
|
||||
#endif
|
||||
#if REGISTERS >= 2
|
||||
# undef REG2
|
||||
# define REG2 register
|
||||
#endif
|
||||
#if REGISTERS >= 3
|
||||
# undef REG3
|
||||
# define REG3 register
|
||||
#endif
|
||||
#if REGISTERS >= 4
|
||||
# undef REG4
|
||||
# define REG4 register
|
||||
#endif
|
||||
#if REGISTERS >= 5
|
||||
# undef REG5
|
||||
# define REG5 register
|
||||
#endif
|
||||
#if REGISTERS >= 6
|
||||
# undef REG6
|
||||
# define REG6 register
|
||||
#endif
|
||||
#if REGISTERS >= 7
|
||||
# undef REG7
|
||||
# define REG7 register
|
||||
#endif
|
||||
#if REGISTERS >= 8
|
||||
# undef REG8
|
||||
# define REG8 register
|
||||
#endif
|
||||
#if REGISTERS >= 9
|
||||
# undef REG9
|
||||
# define REG9 register
|
||||
#endif
|
||||
#if REGISTERS >= 10
|
||||
# undef REG10
|
||||
# define REG10 register
|
||||
#endif
|
||||
#if REGISTERS >= 11
|
||||
# undef REG11
|
||||
# define REG11 register
|
||||
#endif
|
||||
#if REGISTERS >= 12
|
||||
# undef REG12
|
||||
# define REG12 register
|
||||
#endif
|
||||
#if REGISTERS >= 13
|
||||
# undef REG13
|
||||
# define REG13 register
|
||||
#endif
|
||||
#if REGISTERS >= 14
|
||||
# undef REG14
|
||||
# define REG14 register
|
||||
#endif
|
||||
#if REGISTERS >= 15
|
||||
# undef REG15
|
||||
# define REG15 register
|
||||
#endif
|
||||
#if REGISTERS >= 16
|
||||
# undef REG16
|
||||
# define REG16 register
|
||||
#endif
|
||||
|
||||
#ifndef BYTEORDER
|
||||
# define BYTEORDER 0000
|
||||
#endif
|
||||
|
||||
#ifndef NOALLIGN
|
||||
# define NOALLIGN 0
|
||||
#endif
|
||||
|
||||
|
||||
union bytes {
|
||||
long word;
|
||||
struct {
|
||||
#if BYTEORDER == 4321
|
||||
char_type b1;
|
||||
char_type b2;
|
||||
char_type b3;
|
||||
char_type b4;
|
||||
#else
|
||||
#if BYTEORDER == 1234
|
||||
char_type b4;
|
||||
char_type b3;
|
||||
char_type b2;
|
||||
char_type b1;
|
||||
#else
|
||||
# undef BYTEORDER
|
||||
int dummy;
|
||||
#endif
|
||||
#endif
|
||||
} bytes;
|
||||
};
|
||||
|
||||
#if BYTEORDER == 4321 && NOALLIGN == 1
|
||||
# define input(b,o,c,n,m){ \
|
||||
(c) = (*(long *)(&(b)[(o)>>3])>>((o)&0x7))&(m); \
|
||||
(o) += (n); \
|
||||
}
|
||||
#else
|
||||
# define input(b,o,c,n,m){ \
|
||||
REG1 char_type *p = &(b)[(o)>>3]; \
|
||||
(c) = ((((long)(p[0]))|((long)(p[1])<<8)| \
|
||||
((long)(p[2])<<16))>>((o)&0x7))&(m); \
|
||||
(o) += (n); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef MAXSEG_64K
|
||||
/* DECLARE(ush, tab_prefix, (1<<BITS)); -- prefix code */
|
||||
# define tab_prefixof(i) tab_prefix[i]
|
||||
# define clear_tab_prefixof() memzero(tab_prefix, 256);
|
||||
#else
|
||||
/* DECLARE(ush, tab_prefix0, (1<<(BITS-1)); -- prefix for even codes */
|
||||
/* DECLARE(ush, tab_prefix1, (1<<(BITS-1)); -- prefix for odd codes */
|
||||
ush *tab_prefix[2];
|
||||
# define tab_prefixof(i) tab_prefix[(i)&1][(i)>>1]
|
||||
# define clear_tab_prefixof() \
|
||||
memzero(tab_prefix0, 128), \
|
||||
memzero(tab_prefix1, 128);
|
||||
#endif
|
||||
#define de_stack ((char_type *)(&d_buf[DIST_BUFSIZE-1]))
|
||||
#define tab_suffixof(i) tab_suffix[i]
|
||||
|
||||
int block_mode = BLOCK_MODE; /* block compress mode -C compatible with 2.0 */
|
||||
|
||||
/* ============================================================================
|
||||
* Decompress in to out. This routine adapts to the codes in the
|
||||
* file building the "string" table on-the-fly; requiring no table to
|
||||
* be stored in the compressed file.
|
||||
* IN assertions: the buffer inbuf contains already the beginning of
|
||||
* the compressed data, from offsets iptr to insize-1 included.
|
||||
* The magic header has already been checked and skipped.
|
||||
* bytes_in and bytes_out have been initialized.
|
||||
*/
|
||||
int unlzw(in, out)
|
||||
int in, out; /* input and output file descriptors */
|
||||
{
|
||||
REG2 char_type *stackp;
|
||||
REG3 code_int code;
|
||||
REG4 int finchar;
|
||||
REG5 code_int oldcode;
|
||||
REG6 code_int incode;
|
||||
REG7 long inbits;
|
||||
REG8 long posbits;
|
||||
REG9 int outpos;
|
||||
/* REG10 int insize; (global) */
|
||||
REG11 unsigned bitmask;
|
||||
REG12 code_int free_ent;
|
||||
REG13 code_int maxcode;
|
||||
REG14 code_int maxmaxcode;
|
||||
REG15 int n_bits;
|
||||
REG16 int rsize;
|
||||
|
||||
#ifdef MAXSEG_64K
|
||||
tab_prefix[0] = tab_prefix0;
|
||||
tab_prefix[1] = tab_prefix1;
|
||||
#endif
|
||||
maxbits = get_byte();
|
||||
block_mode = maxbits & BLOCK_MODE;
|
||||
if ((maxbits & LZW_RESERVED) != 0) {
|
||||
WARN((stderr, "\n%s: %s: warning, unknown flags 0x%x\n",
|
||||
progname, ifname, maxbits & LZW_RESERVED));
|
||||
}
|
||||
maxbits &= BIT_MASK;
|
||||
maxmaxcode = MAXCODE(maxbits);
|
||||
|
||||
if (maxbits > BITS) {
|
||||
fprintf(stderr,
|
||||
"\n%s: %s: compressed with %d bits, can only handle %d bits\n",
|
||||
progname, ifname, maxbits, BITS);
|
||||
exit_code = ERROR;
|
||||
return ERROR;
|
||||
}
|
||||
rsize = insize;
|
||||
maxcode = MAXCODE(n_bits = INIT_BITS)-1;
|
||||
bitmask = (1<<n_bits)-1;
|
||||
oldcode = -1;
|
||||
finchar = 0;
|
||||
outpos = 0;
|
||||
posbits = inptr<<3;
|
||||
|
||||
free_ent = ((block_mode) ? FIRST : 256);
|
||||
|
||||
clear_tab_prefixof(); /* Initialize the first 256 entries in the table. */
|
||||
|
||||
for (code = 255 ; code >= 0 ; --code) {
|
||||
tab_suffixof(code) = (char_type)code;
|
||||
}
|
||||
do {
|
||||
REG1 int i;
|
||||
int e;
|
||||
int o;
|
||||
|
||||
resetbuf:
|
||||
e = insize-(o = (posbits>>3));
|
||||
|
||||
for (i = 0 ; i < e ; ++i) {
|
||||
inbuf[i] = inbuf[i+o];
|
||||
}
|
||||
insize = e;
|
||||
posbits = 0;
|
||||
|
||||
if (insize < INBUF_EXTRA) {
|
||||
if ((rsize = read(in, (char*)inbuf+insize, INBUFSIZ)) == EOF) {
|
||||
read_error();
|
||||
}
|
||||
insize += rsize;
|
||||
}
|
||||
inbits = ((rsize != 0) ? ((long)insize - insize%n_bits)<<3 :
|
||||
((long)insize<<3)-(n_bits-1));
|
||||
|
||||
while (inbits > posbits) {
|
||||
if (free_ent > maxcode) {
|
||||
posbits = ((posbits-1) +
|
||||
((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3)));
|
||||
++n_bits;
|
||||
if (n_bits == maxbits) {
|
||||
maxcode = maxmaxcode;
|
||||
} else {
|
||||
maxcode = MAXCODE(n_bits)-1;
|
||||
}
|
||||
bitmask = (1<<n_bits)-1;
|
||||
goto resetbuf;
|
||||
}
|
||||
input(inbuf,posbits,code,n_bits,bitmask);
|
||||
|
||||
if (oldcode == -1) {
|
||||
outbuf[outpos++] = (char_type)(finchar = (int)(oldcode=code));
|
||||
continue;
|
||||
}
|
||||
if (code == CLEAR && block_mode) {
|
||||
clear_tab_prefixof();
|
||||
free_ent = FIRST - 1;
|
||||
posbits = ((posbits-1) +
|
||||
((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3)));
|
||||
maxcode = MAXCODE(n_bits = INIT_BITS)-1;
|
||||
bitmask = (1<<n_bits)-1;
|
||||
goto resetbuf;
|
||||
}
|
||||
incode = code;
|
||||
stackp = de_stack;
|
||||
|
||||
if (code >= free_ent) { /* Special case for KwKwK string. */
|
||||
if (code > free_ent) {
|
||||
#ifdef DEBUG
|
||||
char_type *p;
|
||||
|
||||
posbits -= n_bits;
|
||||
p = &inbuf[posbits>>3];
|
||||
fprintf(stderr,
|
||||
"code:%ld free_ent:%ld n_bits:%d insize:%u\n",
|
||||
code, free_ent, n_bits, insize);
|
||||
fprintf(stderr,
|
||||
"posbits:%ld inbuf:%02X %02X %02X %02X %02X\n",
|
||||
posbits, p[-1],p[0],p[1],p[2],p[3]);
|
||||
#endif
|
||||
if (!test && outpos > 0) {
|
||||
write_buf(out, outbuf, outpos);
|
||||
}
|
||||
error("corrupt input. Use zcat to recover some data.");
|
||||
}
|
||||
*--stackp = (char_type)finchar;
|
||||
code = oldcode;
|
||||
}
|
||||
|
||||
while ((cmp_code_int)code >= (cmp_code_int)256) {
|
||||
/* Generate output characters in reverse order */
|
||||
*--stackp = tab_suffixof(code);
|
||||
code = tab_prefixof(code);
|
||||
}
|
||||
*--stackp = (char_type)(finchar = tab_suffixof(code));
|
||||
|
||||
/* And put them out in forward order */
|
||||
{
|
||||
REG1 int i;
|
||||
|
||||
if (outpos+(i = (de_stack-stackp)) >= OUTBUFSIZ) {
|
||||
do {
|
||||
if (i > OUTBUFSIZ-outpos) i = OUTBUFSIZ-outpos;
|
||||
|
||||
if (i > 0) {
|
||||
memcpy(outbuf+outpos, stackp, i);
|
||||
outpos += i;
|
||||
}
|
||||
if (outpos >= OUTBUFSIZ) {
|
||||
if (!test) write_buf(out, outbuf, outpos);
|
||||
outpos = 0;
|
||||
}
|
||||
stackp+= i;
|
||||
} while ((i = (de_stack-stackp)) > 0);
|
||||
} else {
|
||||
memcpy(outbuf+outpos, stackp, i);
|
||||
outpos += i;
|
||||
}
|
||||
}
|
||||
|
||||
if ((code = free_ent) < maxmaxcode) { /* Generate the new entry. */
|
||||
|
||||
tab_prefixof(code) = (unsigned short)oldcode;
|
||||
tab_suffixof(code) = (char_type)finchar;
|
||||
free_ent = code+1;
|
||||
}
|
||||
oldcode = incode; /* Remember previous code. */
|
||||
}
|
||||
bytes_in += rsize;
|
||||
|
||||
} while (rsize != 0);
|
||||
|
||||
if (!test && outpos > 0) write_buf(out, outbuf, outpos);
|
||||
return OK;
|
||||
}
|
241
gnu/usr.bin/gzip/unpack.c
Normal file
241
gnu/usr.bin/gzip/unpack.c
Normal file
@ -0,0 +1,241 @@
|
||||
/* unpack.c -- decompress files in pack format.
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: unpack.c,v 1.3 1993/05/28 17:56:07 jloup Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "tailor.h"
|
||||
#include "gzip.h"
|
||||
#include "crypt.h"
|
||||
|
||||
#define MIN(a,b) ((a) <= (b) ? (a) : (b))
|
||||
/* The arguments must not have side effects. */
|
||||
|
||||
#define MAX_BITLEN 25
|
||||
/* Maximum length of Huffman codes. (Minor modifications to the code
|
||||
* would be needed to support 32 bits codes, but pack never generates
|
||||
* more than 24 bits anyway.)
|
||||
*/
|
||||
|
||||
#define LITERALS 256
|
||||
/* Number of literals, excluding the End of Block (EOB) code */
|
||||
|
||||
#ifdef SMALL_MEM
|
||||
# define MAX_PEEK 10
|
||||
#else
|
||||
# define MAX_PEEK 12
|
||||
#endif
|
||||
/* Maximum number of 'peek' bits used to optimize traversal of the
|
||||
* Huffman tree.
|
||||
*/
|
||||
|
||||
local ulg orig_len; /* original uncompressed length */
|
||||
local int max_len; /* maximum bit length of Huffman codes */
|
||||
|
||||
local uch literal[LITERALS];
|
||||
/* The literal bytes present in the Huffman tree. The EOB code is not
|
||||
* represented.
|
||||
*/
|
||||
|
||||
local int lit_base[MAX_BITLEN+1];
|
||||
/* All literals of a given bit length are contiguous in literal[] and
|
||||
* have contiguous codes. literal[code+lit_base[len]] is the literal
|
||||
* for a code of len bits.
|
||||
*/
|
||||
|
||||
local int leaves [MAX_BITLEN+1]; /* Number of leaves for each bit length */
|
||||
local int parents[MAX_BITLEN+1]; /* Number of parents for each bit length */
|
||||
|
||||
local int peek_bits; /* Number of peek bits currently used */
|
||||
|
||||
local uch prefix_len[1 << MAX_PEEK];
|
||||
/* For each bit pattern b of peek_bits bits, prefix_len[b] is the length
|
||||
* of the Huffman code starting with a prefix of b (upper bits), or 0
|
||||
* if all codes of prefix b have more than peek_bits bits. It is not
|
||||
* necessary to have a huge table (large MAX_PEEK) because most of the
|
||||
* codes encountered in the input stream are short codes (by construction).
|
||||
* So for most codes a single lookup will be necessary.
|
||||
*/
|
||||
|
||||
local ulg bitbuf;
|
||||
/* Bits are added on the low part of bitbuf and read from the high part. */
|
||||
|
||||
local int valid; /* number of valid bits in bitbuf */
|
||||
/* all bits above the last valid bit are always zero */
|
||||
|
||||
/* Set code to the next 'bits' input bits without skipping them. code
|
||||
* must be the name of a simple variable and bits must not have side effects.
|
||||
* IN assertions: bits <= 25 (so that we still have room for an extra byte
|
||||
* when valid is only 24), and mask = (1<<bits)-1.
|
||||
*/
|
||||
#define look_bits(code,bits,mask) \
|
||||
{ \
|
||||
while (valid < (bits)) bitbuf = (bitbuf<<8) | (ulg)get_byte(), valid += 8; \
|
||||
code = (bitbuf >> (valid-(bits))) & (mask); \
|
||||
}
|
||||
|
||||
/* Skip the given number of bits (after having peeked at them): */
|
||||
#define skip_bits(bits) (valid -= (bits))
|
||||
|
||||
#define clear_bitbuf() (valid = 0, bitbuf = 0)
|
||||
|
||||
/* Local functions */
|
||||
|
||||
local void read_tree OF((void));
|
||||
local void build_tree OF((void));
|
||||
|
||||
/* ===========================================================================
|
||||
* Read the Huffman tree.
|
||||
*/
|
||||
local void read_tree()
|
||||
{
|
||||
int len; /* bit length */
|
||||
int base; /* base offset for a sequence of leaves */
|
||||
int n;
|
||||
|
||||
/* Read the original input size, MSB first */
|
||||
orig_len = 0;
|
||||
for (n = 1; n <= 4; n++) orig_len = (orig_len << 8) | (ulg)get_byte();
|
||||
|
||||
max_len = (int)get_byte(); /* maximum bit length of Huffman codes */
|
||||
if (max_len > MAX_BITLEN) {
|
||||
error("invalid compressed data -- Huffman code > 32 bits");
|
||||
}
|
||||
|
||||
/* Get the number of leaves at each bit length */
|
||||
n = 0;
|
||||
for (len = 1; len <= max_len; len++) {
|
||||
leaves[len] = (int)get_byte();
|
||||
n += leaves[len];
|
||||
}
|
||||
if (n > LITERALS) {
|
||||
error("too many leaves in Huffman tree");
|
||||
}
|
||||
Trace((stderr, "orig_len %ld, max_len %d, leaves %d\n",
|
||||
orig_len, max_len, n));
|
||||
/* There are at least 2 and at most 256 leaves of length max_len.
|
||||
* (Pack arbitrarily rejects empty files and files consisting of
|
||||
* a single byte even repeated.) To fit the last leaf count in a
|
||||
* byte, it is offset by 2. However, the last literal is the EOB
|
||||
* code, and is not transmitted explicitly in the tree, so we must
|
||||
* adjust here by one only.
|
||||
*/
|
||||
leaves[max_len]++;
|
||||
|
||||
/* Now read the leaves themselves */
|
||||
base = 0;
|
||||
for (len = 1; len <= max_len; len++) {
|
||||
/* Remember where the literals of this length start in literal[] : */
|
||||
lit_base[len] = base;
|
||||
/* And read the literals: */
|
||||
for (n = leaves[len]; n > 0; n--) {
|
||||
literal[base++] = (uch)get_byte();
|
||||
}
|
||||
}
|
||||
leaves[max_len]++; /* Now include the EOB code in the Huffman tree */
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Build the Huffman tree and the prefix table.
|
||||
*/
|
||||
local void build_tree()
|
||||
{
|
||||
int nodes = 0; /* number of nodes (parents+leaves) at current bit length */
|
||||
int len; /* current bit length */
|
||||
uch *prefixp; /* pointer in prefix_len */
|
||||
|
||||
for (len = max_len; len >= 1; len--) {
|
||||
/* The number of parent nodes at this level is half the total
|
||||
* number of nodes at parent level:
|
||||
*/
|
||||
nodes >>= 1;
|
||||
parents[len] = nodes;
|
||||
/* Update lit_base by the appropriate bias to skip the parent nodes
|
||||
* (which are not represented in the literal array):
|
||||
*/
|
||||
lit_base[len] -= nodes;
|
||||
/* Restore nodes to be parents+leaves: */
|
||||
nodes += leaves[len];
|
||||
}
|
||||
/* Construct the prefix table, from shortest leaves to longest ones.
|
||||
* The shortest code is all ones, so we start at the end of the table.
|
||||
*/
|
||||
peek_bits = MIN(max_len, MAX_PEEK);
|
||||
prefixp = &prefix_len[1<<peek_bits];
|
||||
for (len = 1; len <= peek_bits; len++) {
|
||||
int prefixes = leaves[len] << (peek_bits-len); /* may be 0 */
|
||||
while (prefixes--) *--prefixp = (uch)len;
|
||||
}
|
||||
/* The length of all other codes is unknown: */
|
||||
while (prefixp > prefix_len) *--prefixp = 0;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Unpack in to out. This routine does not support the old pack format
|
||||
* with magic header \037\037.
|
||||
*
|
||||
* IN assertions: the buffer inbuf contains already the beginning of
|
||||
* the compressed data, from offsets inptr to insize-1 included.
|
||||
* The magic header has already been checked. The output buffer is cleared.
|
||||
*/
|
||||
int unpack(in, out)
|
||||
int in, out; /* input and output file descriptors */
|
||||
{
|
||||
int len; /* Bit length of current code */
|
||||
unsigned eob; /* End Of Block code */
|
||||
register unsigned peek; /* lookahead bits */
|
||||
unsigned peek_mask; /* Mask for peek_bits bits */
|
||||
|
||||
ifd = in;
|
||||
ofd = out;
|
||||
|
||||
read_tree(); /* Read the Huffman tree */
|
||||
build_tree(); /* Build the prefix table */
|
||||
clear_bitbuf(); /* Initialize bit input */
|
||||
peek_mask = (1<<peek_bits)-1;
|
||||
|
||||
/* The eob code is the largest code among all leaves of maximal length: */
|
||||
eob = leaves[max_len]-1;
|
||||
Trace((stderr, "eob %d %x\n", max_len, eob));
|
||||
|
||||
/* Decode the input data: */
|
||||
for (;;) {
|
||||
/* Since eob is the longest code and not shorter than max_len,
|
||||
* we can peek at max_len bits without having the risk of reading
|
||||
* beyond the end of file.
|
||||
*/
|
||||
look_bits(peek, peek_bits, peek_mask);
|
||||
len = prefix_len[peek];
|
||||
if (len > 0) {
|
||||
peek >>= peek_bits - len; /* discard the extra bits */
|
||||
} else {
|
||||
/* Code of more than peek_bits bits, we must traverse the tree */
|
||||
ulg mask = peek_mask;
|
||||
len = peek_bits;
|
||||
do {
|
||||
len++, mask = (mask<<1)+1;
|
||||
look_bits(peek, len, mask);
|
||||
} while (peek < parents[len]);
|
||||
/* loop as long as peek is a parent node */
|
||||
}
|
||||
/* At this point, peek is the next complete code, of len bits */
|
||||
if (peek == eob && len == max_len) break; /* end of file? */
|
||||
put_ubyte(literal[peek+lit_base[len]]);
|
||||
Tracev((stderr,"%02d %04x %c\n", len, peek,
|
||||
literal[peek+lit_base[len]]));
|
||||
skip_bits(len);
|
||||
} /* for (;;) */
|
||||
|
||||
flush_window();
|
||||
Trace((stderr, "bytes_out %ld\n", bytes_out));
|
||||
if (orig_len != bytes_out) {
|
||||
error("invalid compressed data--length error");
|
||||
}
|
||||
return OK;
|
||||
}
|
201
gnu/usr.bin/gzip/unzip.c
Normal file
201
gnu/usr.bin/gzip/unzip.c
Normal file
@ -0,0 +1,201 @@
|
||||
/* unzip.c -- decompress files in gzip or pkzip format.
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*
|
||||
* The code in this file is derived from the file funzip.c written
|
||||
* and put in the public domain by Mark Adler.
|
||||
*/
|
||||
|
||||
/*
|
||||
This version can extract files in gzip or pkzip format.
|
||||
For the latter, only the first entry is extracted, and it has to be
|
||||
either deflated or stored.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: unzip.c,v 0.12 1993/05/28 17:56:23 jloup Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "tailor.h"
|
||||
#include "gzip.h"
|
||||
#include "crypt.h"
|
||||
|
||||
/* PKZIP header definitions */
|
||||
#define LOCSIG 0x04034b50L /* four-byte lead-in (lsb first) */
|
||||
#define LOCFLG 6 /* offset of bit flag */
|
||||
#define CRPFLG 1 /* bit for encrypted entry */
|
||||
#define EXTFLG 8 /* bit for extended local header */
|
||||
#define LOCHOW 8 /* offset of compression method */
|
||||
#define LOCTIM 10 /* file mod time (for decryption) */
|
||||
#define LOCCRC 14 /* offset of crc */
|
||||
#define LOCSIZ 18 /* offset of compressed size */
|
||||
#define LOCLEN 22 /* offset of uncompressed length */
|
||||
#define LOCFIL 26 /* offset of file name field length */
|
||||
#define LOCEXT 28 /* offset of extra field length */
|
||||
#define LOCHDR 30 /* size of local header, including sig */
|
||||
#define EXTHDR 16 /* size of extended local header, inc sig */
|
||||
|
||||
|
||||
/* Globals */
|
||||
|
||||
int decrypt; /* flag to turn on decryption */
|
||||
char *key; /* not used--needed to link crypt.c */
|
||||
int pkzip = 0; /* set for a pkzip file */
|
||||
int ext_header = 0; /* set if extended local header */
|
||||
|
||||
/* ===========================================================================
|
||||
* Check zip file and advance inptr to the start of the compressed data.
|
||||
* Get ofname from the local header if necessary.
|
||||
*/
|
||||
int check_zipfile(in)
|
||||
int in; /* input file descriptors */
|
||||
{
|
||||
uch *h = inbuf + inptr; /* first local header */
|
||||
|
||||
ifd = in;
|
||||
|
||||
/* Check validity of local header, and skip name and extra fields */
|
||||
inptr += LOCHDR + SH(h + LOCFIL) + SH(h + LOCEXT);
|
||||
|
||||
if (inptr > insize || LG(h) != LOCSIG) {
|
||||
fprintf(stderr, "\n%s: %s: not a valid zip file\n",
|
||||
progname, ifname);
|
||||
exit_code = ERROR;
|
||||
return ERROR;
|
||||
}
|
||||
method = h[LOCHOW];
|
||||
if (method != STORED && method != DEFLATED) {
|
||||
fprintf(stderr,
|
||||
"\n%s: %s: first entry not deflated or stored -- use unzip\n",
|
||||
progname, ifname);
|
||||
exit_code = ERROR;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* If entry encrypted, decrypt and validate encryption header */
|
||||
if ((decrypt = h[LOCFLG] & CRPFLG) != 0) {
|
||||
fprintf(stderr, "\n%s: %s: encrypted file -- use unzip\n",
|
||||
progname, ifname);
|
||||
exit_code = ERROR;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Save flags for unzip() */
|
||||
ext_header = (h[LOCFLG] & EXTFLG) != 0;
|
||||
pkzip = 1;
|
||||
|
||||
/* Get ofname and time stamp from local header (to be done) */
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Unzip in to out. This routine works on both gzip and pkzip files.
|
||||
*
|
||||
* IN assertions: the buffer inbuf contains already the beginning of
|
||||
* the compressed data, from offsets inptr to insize-1 included.
|
||||
* The magic header has already been checked. The output buffer is cleared.
|
||||
*/
|
||||
int unzip(in, out)
|
||||
int in, out; /* input and output file descriptors */
|
||||
{
|
||||
ulg orig_crc = 0; /* original crc */
|
||||
ulg orig_len = 0; /* original uncompressed length */
|
||||
int n;
|
||||
uch buf[EXTHDR]; /* extended local header */
|
||||
|
||||
ifd = in;
|
||||
ofd = out;
|
||||
|
||||
updcrc(NULL, 0); /* initialize crc */
|
||||
|
||||
if (pkzip && !ext_header) { /* crc and length at the end otherwise */
|
||||
orig_crc = LG(inbuf + LOCCRC);
|
||||
orig_len = LG(inbuf + LOCLEN);
|
||||
}
|
||||
|
||||
/* Decompress */
|
||||
if (method == DEFLATED) {
|
||||
|
||||
int res = inflate();
|
||||
|
||||
if (res == 3) {
|
||||
error("out of memory");
|
||||
} else if (res != 0) {
|
||||
error("invalid compressed data--format violated");
|
||||
}
|
||||
|
||||
} else if (pkzip && method == STORED) {
|
||||
|
||||
register ulg n = LG(inbuf + LOCLEN);
|
||||
|
||||
if (n != LG(inbuf + LOCSIZ) - (decrypt ? RAND_HEAD_LEN : 0)) {
|
||||
|
||||
fprintf(stderr, "len %ld, siz %ld\n", n, LG(inbuf + LOCSIZ));
|
||||
error("invalid compressed data--length mismatch");
|
||||
}
|
||||
while (n--) {
|
||||
uch c = (uch)get_byte();
|
||||
#ifdef CRYPT
|
||||
if (decrypt) zdecode(c);
|
||||
#endif
|
||||
put_ubyte(c);
|
||||
}
|
||||
flush_window();
|
||||
} else {
|
||||
error("internal error, invalid method");
|
||||
}
|
||||
|
||||
/* Get the crc and original length */
|
||||
if (!pkzip) {
|
||||
/* crc32 (see algorithm.doc)
|
||||
* uncompressed input size modulo 2^32
|
||||
*/
|
||||
for (n = 0; n < 8; n++) {
|
||||
buf[n] = (uch)get_byte(); /* may cause an error if EOF */
|
||||
}
|
||||
orig_crc = LG(buf);
|
||||
orig_len = LG(buf+4);
|
||||
|
||||
} else if (ext_header) { /* If extended header, check it */
|
||||
/* signature - 4bytes: 0x50 0x4b 0x07 0x08
|
||||
* CRC-32 value
|
||||
* compressed size 4-bytes
|
||||
* uncompressed size 4-bytes
|
||||
*/
|
||||
for (n = 0; n < EXTHDR; n++) {
|
||||
buf[n] = (uch)get_byte(); /* may cause an error if EOF */
|
||||
}
|
||||
orig_crc = LG(buf+4);
|
||||
orig_len = LG(buf+12);
|
||||
}
|
||||
|
||||
/* Validate decompression */
|
||||
if (orig_crc != updcrc(outbuf, 0)) {
|
||||
error("invalid compressed data--crc error");
|
||||
}
|
||||
if (orig_len != bytes_out) {
|
||||
error("invalid compressed data--length error");
|
||||
}
|
||||
|
||||
/* Check if there are more entries in a pkzip file */
|
||||
if (pkzip && inptr + 4 < insize && LG(inbuf+inptr) == LOCSIG) {
|
||||
if (to_stdout) {
|
||||
WARN((stderr,
|
||||
"%s: %s has more than one entry--rest ignored\n",
|
||||
progname, ifname));
|
||||
} else {
|
||||
/* Don't destroy the input zip file */
|
||||
fprintf(stderr,
|
||||
"%s: %s has more than one entry -- unchanged\n",
|
||||
progname, ifname);
|
||||
exit_code = ERROR;
|
||||
ext_header = pkzip = 0;
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
ext_header = pkzip = 0; /* for next file */
|
||||
return OK;
|
||||
}
|
419
gnu/usr.bin/gzip/util.c
Normal file
419
gnu/usr.bin/gzip/util.c
Normal file
@ -0,0 +1,419 @@
|
||||
/* util.c -- utility functions for gzip support
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: util.c,v 0.14 1993/05/27 10:31:52 jloup Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "tailor.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifndef NO_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#if defined(STDC_HEADERS) || !defined(NO_STDLIB_H)
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#include "gzip.h"
|
||||
#include "crypt.h"
|
||||
|
||||
extern ulg crc_32_tab[]; /* crc table, defined below */
|
||||
|
||||
/* ===========================================================================
|
||||
* Run a set of bytes through the crc shift register. If s is a NULL
|
||||
* pointer, then initialize the crc shift register contents instead.
|
||||
* Return the current crc in either case.
|
||||
*/
|
||||
ulg updcrc(s, n)
|
||||
uch *s; /* pointer to bytes to pump through */
|
||||
unsigned n; /* number of bytes in s[] */
|
||||
{
|
||||
register ulg c; /* temporary variable */
|
||||
|
||||
static ulg crc = (ulg)0xffffffffL; /* shift register contents */
|
||||
|
||||
if (s == NULL) {
|
||||
c = 0xffffffffL;
|
||||
} else {
|
||||
c = crc;
|
||||
if (n) do {
|
||||
c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8);
|
||||
} while (--n);
|
||||
}
|
||||
crc = c;
|
||||
return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Clear input and output buffers
|
||||
*/
|
||||
void clear_bufs()
|
||||
{
|
||||
outcnt = 0;
|
||||
insize = inptr = 0;
|
||||
bytes_in = bytes_out = 0L;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Fill the input buffer. This is called only when the buffer is empty
|
||||
* and at least one byte is really needed.
|
||||
*/
|
||||
int fill_inbuf()
|
||||
{
|
||||
int len;
|
||||
|
||||
/* Read as much as possible */
|
||||
insize = 0;
|
||||
errno = 0;
|
||||
do {
|
||||
len = read(ifd, (char*)inbuf+insize, INBUFSIZ-insize);
|
||||
if (len == 0 || len == EOF) break;
|
||||
insize += len;
|
||||
} while (insize < INBUFSIZ);
|
||||
|
||||
if (insize == 0) {
|
||||
read_error();
|
||||
}
|
||||
bytes_in += (ulg)insize;
|
||||
inptr = 1;
|
||||
return inbuf[0];
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Write the output buffer outbuf[0..outcnt-1] and update bytes_out.
|
||||
* (used for the compressed data only)
|
||||
*/
|
||||
void flush_outbuf()
|
||||
{
|
||||
if (outcnt == 0) return;
|
||||
|
||||
write_buf(ofd, (char *)outbuf, outcnt);
|
||||
bytes_out += (ulg)outcnt;
|
||||
outcnt = 0;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Write the output window window[0..outcnt-1] and update crc and bytes_out.
|
||||
* (Used for the decompressed data only.)
|
||||
*/
|
||||
void flush_window()
|
||||
{
|
||||
if (outcnt == 0) return;
|
||||
updcrc(window, outcnt);
|
||||
|
||||
if (!test) {
|
||||
write_buf(ofd, (char *)window, outcnt);
|
||||
}
|
||||
bytes_out += (ulg)outcnt;
|
||||
outcnt = 0;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Does the same as write(), but also handles partial pipe writes and checks
|
||||
* for error return.
|
||||
*/
|
||||
void write_buf(fd, buf, cnt)
|
||||
int fd;
|
||||
voidp buf;
|
||||
unsigned cnt;
|
||||
{
|
||||
unsigned n;
|
||||
|
||||
while ((n = write(fd, buf, cnt)) != cnt) {
|
||||
if (n == (unsigned)(-1)) {
|
||||
write_error();
|
||||
}
|
||||
cnt -= n;
|
||||
buf = (voidp)((char*)buf+n);
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* Put string s in lower case, return s.
|
||||
*/
|
||||
char *strlwr(s)
|
||||
char *s;
|
||||
{
|
||||
char *t;
|
||||
for (t = s; *t; t++) *t = tolow(*t);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* Return the base name of a file (remove any directory prefix and
|
||||
* any version suffix). For systems with file names that are not
|
||||
* case sensitive, force the base name to lower case.
|
||||
*/
|
||||
char *basename(fname)
|
||||
char *fname;
|
||||
{
|
||||
char *p;
|
||||
|
||||
if ((p = strrchr(fname, PATH_SEP)) != NULL) fname = p+1;
|
||||
#ifdef PATH_SEP2
|
||||
if ((p = strrchr(fname, PATH_SEP2)) != NULL) fname = p+1;
|
||||
#endif
|
||||
#ifdef PATH_SEP3
|
||||
if ((p = strrchr(fname, PATH_SEP3)) != NULL) fname = p+1;
|
||||
#endif
|
||||
#ifdef SUFFIX_SEP
|
||||
if ((p = strrchr(fname, SUFFIX_SEP)) != NULL) *p = '\0';
|
||||
#endif
|
||||
if (casemap('A') == 'a') strlwr(fname);
|
||||
return fname;
|
||||
}
|
||||
|
||||
#if defined(NO_STRING_H) && !defined(STDC_HEADERS)
|
||||
|
||||
/* Provide missing strspn and strcspn functions. */
|
||||
|
||||
# ifndef __STDC__
|
||||
# define const
|
||||
# endif
|
||||
|
||||
int strspn OF((const char *s, const char *accept));
|
||||
int strcspn OF((const char *s, const char *reject));
|
||||
|
||||
/* ========================================================================
|
||||
* Return the length of the maximum initial segment
|
||||
* of s which contains only characters in accept.
|
||||
*/
|
||||
int strspn(s, accept)
|
||||
const char *s;
|
||||
const char *accept;
|
||||
{
|
||||
register const char *p;
|
||||
register const char *a;
|
||||
register int count = 0;
|
||||
|
||||
for (p = s; *p != '\0'; ++p) {
|
||||
for (a = accept; *a != '\0'; ++a) {
|
||||
if (*p == *a) break;
|
||||
}
|
||||
if (*a == '\0') return count;
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* Return the length of the maximum inital segment of s
|
||||
* which contains no characters from reject.
|
||||
*/
|
||||
int strcspn(s, reject)
|
||||
const char *s;
|
||||
const char *reject;
|
||||
{
|
||||
register int count = 0;
|
||||
|
||||
while (*s != '\0') {
|
||||
if (strchr(reject, *s++) != NULL) return count;
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif /* NO_STRING_H */
|
||||
|
||||
/* ========================================================================
|
||||
* Add an environment variable (if any) before argv, and update argc.
|
||||
* Return the expanded environment variable to be freed later, or NULL
|
||||
* if no options were added to argv.
|
||||
*/
|
||||
#define SEPARATOR " \t" /* separators in env variable */
|
||||
|
||||
char *add_envopt(argcp, argvp, env)
|
||||
int *argcp; /* pointer to argc */
|
||||
char ***argvp; /* pointer to argv */
|
||||
char *env; /* name of environment variable */
|
||||
{
|
||||
char *p; /* running pointer through env variable */
|
||||
char **oargv; /* runs through old argv array */
|
||||
char **nargv; /* runs through new argv array */
|
||||
int oargc = *argcp; /* old argc */
|
||||
int nargc = 0; /* number of arguments in env variable */
|
||||
|
||||
env = (char*)getenv(env);
|
||||
if (env == NULL) return NULL;
|
||||
|
||||
p = (char*)xmalloc(strlen(env)+1);
|
||||
env = strcpy(p, env); /* keep env variable intact */
|
||||
|
||||
for (p = env; *p; nargc++ ) { /* move through env */
|
||||
p += strspn(p, SEPARATOR); /* skip leading separators */
|
||||
if (*p == '\0') break;
|
||||
|
||||
p += strcspn(p, SEPARATOR); /* find end of word */
|
||||
if (*p) *p++ = '\0'; /* mark it */
|
||||
}
|
||||
if (nargc == 0) {
|
||||
free(env); env = NULL;
|
||||
return NULL;
|
||||
}
|
||||
*argcp += nargc;
|
||||
/* Allocate the new argv array, with an extra element just in case
|
||||
* the original arg list did not end with a NULL.
|
||||
*/
|
||||
nargv = (char**)calloc(*argcp+1, sizeof(char *));
|
||||
if (nargv == NULL) error("out of memory");
|
||||
oargv = *argvp;
|
||||
*argvp = nargv;
|
||||
|
||||
/* Copy the program name first */
|
||||
if (oargc-- < 0) error("argc<=0");
|
||||
*(nargv++) = *(oargv++);
|
||||
|
||||
/* Then copy the environment args */
|
||||
for (p = env; nargc > 0; nargc--) {
|
||||
p += strspn(p, SEPARATOR); /* skip separators */
|
||||
*(nargv++) = p; /* store start */
|
||||
while (*p++) ; /* skip over word */
|
||||
}
|
||||
|
||||
/* Finally copy the old args and add a NULL (usual convention) */
|
||||
while (oargc--) *(nargv++) = *(oargv++);
|
||||
*nargv = NULL;
|
||||
return env;
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* Error handlers.
|
||||
*/
|
||||
void error(m)
|
||||
char *m;
|
||||
{
|
||||
fprintf(stderr, "\n%s: %s: %s\n", progname, ifname, m);
|
||||
abort_gzip();
|
||||
}
|
||||
|
||||
void warn(a, b)
|
||||
char *a, *b; /* message strings juxtaposed in output */
|
||||
{
|
||||
WARN((stderr, "%s: %s: warning: %s%s\n", progname, ifname, a, b));
|
||||
}
|
||||
|
||||
void read_error()
|
||||
{
|
||||
fprintf(stderr, "\n%s: ", progname);
|
||||
if (errno != 0) {
|
||||
perror(ifname);
|
||||
} else {
|
||||
fprintf(stderr, "%s: unexpected end of file\n", ifname);
|
||||
}
|
||||
abort_gzip();
|
||||
}
|
||||
|
||||
void write_error()
|
||||
{
|
||||
fprintf(stderr, "\n%s: ", progname);
|
||||
perror(ofname);
|
||||
abort_gzip();
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* Display compression ratio on stderr.
|
||||
*/
|
||||
void display_ratio(num, den)
|
||||
long num;
|
||||
long den;
|
||||
{
|
||||
long ratio; /* 1000 times the compression ratio */
|
||||
|
||||
if (den == 0) {
|
||||
ratio = 0; /* no compression */
|
||||
} else if (den < 2147483L) { /* (2**31 -1)/1000 */
|
||||
ratio = 1000L*num/den;
|
||||
} else {
|
||||
ratio = num/(den/1000L);
|
||||
}
|
||||
if (ratio < 0) {
|
||||
putc('-', stderr);
|
||||
ratio = -ratio;
|
||||
}
|
||||
fprintf(stderr, "%2ld.%ld%%", ratio / 10L, ratio % 10L);
|
||||
}
|
||||
|
||||
|
||||
/* ========================================================================
|
||||
* Semi-safe malloc -- never returns NULL.
|
||||
*/
|
||||
voidp xmalloc (size)
|
||||
unsigned size;
|
||||
{
|
||||
voidp cp = (voidp)malloc (size);
|
||||
|
||||
if (cp == NULL) error("out of memory");
|
||||
return cp;
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* Table of CRC-32's of all single-byte values (made by makecrc.c)
|
||||
*/
|
||||
ulg crc_32_tab[] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
|
||||
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
|
||||
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
|
||||
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
||||
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
|
||||
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
|
||||
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
|
||||
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
|
||||
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
|
||||
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
|
||||
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||||
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
|
||||
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
|
||||
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
|
||||
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
|
||||
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
|
||||
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
|
||||
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
||||
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
|
||||
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
|
||||
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
|
||||
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
|
||||
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
|
||||
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
|
||||
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
||||
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
|
||||
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
|
||||
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
|
||||
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
|
||||
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
|
||||
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
|
||||
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||||
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
|
||||
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
|
||||
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
|
||||
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
|
||||
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
|
||||
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
|
||||
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
||||
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
|
||||
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
|
||||
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
|
||||
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
|
||||
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
|
||||
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
|
||||
0x2d02ef8dL
|
||||
};
|
67
gnu/usr.bin/gzip/zcmp
Normal file
67
gnu/usr.bin/gzip/zcmp
Normal file
@ -0,0 +1,67 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Zcmp and zdiff are used to invoke the cmp or the diff pro-
|
||||
# gram on compressed files. All options specified are passed
|
||||
# directly to cmp or diff. If only 1 file is specified, then
|
||||
# the files compared are file1 and an uncompressed file1.gz.
|
||||
# If two files are specified, then they are uncompressed (if
|
||||
# necessary) and fed to cmp or diff. The exit status from cmp
|
||||
# or diff is preserved.
|
||||
|
||||
prog=`echo $0 | sed 's|.*/||'`
|
||||
case "$prog" in
|
||||
*cmp) comp=${CMP-cmp} ;;
|
||||
*) comp=${DIFF-diff} ;;
|
||||
esac
|
||||
|
||||
OPTIONS=
|
||||
FILES=
|
||||
for ARG
|
||||
do
|
||||
case "$ARG" in
|
||||
-*) OPTIONS="$OPTIONS $ARG";;
|
||||
*) if test -f "$ARG"; then
|
||||
FILES="$FILES $ARG"
|
||||
else
|
||||
echo "${prog}: $ARG not found or not a regular file"
|
||||
exit 1
|
||||
fi ;;
|
||||
esac
|
||||
done
|
||||
if test -z "$FILES"; then
|
||||
echo "Usage: $prog [${comp}_options] file [file]"
|
||||
exit 1
|
||||
fi
|
||||
set $FILES
|
||||
if test $# -eq 1; then
|
||||
FILE=`echo "$1" | sed 's/[-.][zZtga]*$//'`
|
||||
gzip -cd "$1" | $comp $OPTIONS - "$FILE"
|
||||
STAT="$?"
|
||||
|
||||
elif test $# -eq 2; then
|
||||
case "$1" in
|
||||
*[-.]gz | *[-.][zZ] | *.t[ga]z)
|
||||
case "$2" in
|
||||
*[-.]gz | *[-.][zZ] | *.t[ga]z)
|
||||
F=`echo "$2" | sed 's|.*/||;s|[-.][zZtga]*$||'`
|
||||
gzip -cd "$2" > /tmp/"$F".$$
|
||||
gzip -cd "$1" | $comp $OPTIONS - /tmp/"$F".$$
|
||||
STAT="$?"
|
||||
/bin/rm -f /tmp/"$F".$$;;
|
||||
|
||||
*) gzip -cd "$1" | $comp $OPTIONS - "$2"
|
||||
STAT="$?";;
|
||||
esac;;
|
||||
*) case "$2" in
|
||||
*[-.]gz | *[-.][zZ] | *.t[ga]z)
|
||||
gzip -cd "$2" | $comp $OPTIONS "$1" -
|
||||
STAT="$?";;
|
||||
*) $comp $OPTIONS "$1" "$2"
|
||||
STAT="$?";;
|
||||
esac;;
|
||||
esac
|
||||
exit "$STAT"
|
||||
else
|
||||
echo "Usage: $prog [${comp}_options] file [file]"
|
||||
exit 1
|
||||
fi
|
67
gnu/usr.bin/gzip/zdiff
Normal file
67
gnu/usr.bin/gzip/zdiff
Normal file
@ -0,0 +1,67 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Zcmp and zdiff are used to invoke the cmp or the diff pro-
|
||||
# gram on compressed files. All options specified are passed
|
||||
# directly to cmp or diff. If only 1 file is specified, then
|
||||
# the files compared are file1 and an uncompressed file1.gz.
|
||||
# If two files are specified, then they are uncompressed (if
|
||||
# necessary) and fed to cmp or diff. The exit status from cmp
|
||||
# or diff is preserved.
|
||||
|
||||
prog=`echo $0 | sed 's|.*/||'`
|
||||
case "$prog" in
|
||||
*cmp) comp=${CMP-cmp} ;;
|
||||
*) comp=${DIFF-diff} ;;
|
||||
esac
|
||||
|
||||
OPTIONS=
|
||||
FILES=
|
||||
for ARG
|
||||
do
|
||||
case "$ARG" in
|
||||
-*) OPTIONS="$OPTIONS $ARG";;
|
||||
*) if test -f "$ARG"; then
|
||||
FILES="$FILES $ARG"
|
||||
else
|
||||
echo "${prog}: $ARG not found or not a regular file"
|
||||
exit 1
|
||||
fi ;;
|
||||
esac
|
||||
done
|
||||
if test -z "$FILES"; then
|
||||
echo "Usage: $prog [${comp}_options] file [file]"
|
||||
exit 1
|
||||
fi
|
||||
set $FILES
|
||||
if test $# -eq 1; then
|
||||
FILE=`echo "$1" | sed 's/[-.][zZtga]*$//'`
|
||||
gzip -cd "$1" | $comp $OPTIONS - "$FILE"
|
||||
STAT="$?"
|
||||
|
||||
elif test $# -eq 2; then
|
||||
case "$1" in
|
||||
*[-.]gz | *[-.][zZ] | *.t[ga]z)
|
||||
case "$2" in
|
||||
*[-.]gz | *[-.][zZ] | *.t[ga]z)
|
||||
F=`echo "$2" | sed 's|.*/||;s|[-.][zZtga]*$||'`
|
||||
gzip -cd "$2" > /tmp/"$F".$$
|
||||
gzip -cd "$1" | $comp $OPTIONS - /tmp/"$F".$$
|
||||
STAT="$?"
|
||||
/bin/rm -f /tmp/"$F".$$;;
|
||||
|
||||
*) gzip -cd "$1" | $comp $OPTIONS - "$2"
|
||||
STAT="$?";;
|
||||
esac;;
|
||||
*) case "$2" in
|
||||
*[-.]gz | *[-.][zZ] | *.t[ga]z)
|
||||
gzip -cd "$2" | $comp $OPTIONS "$1" -
|
||||
STAT="$?";;
|
||||
*) $comp $OPTIONS "$1" "$2"
|
||||
STAT="$?";;
|
||||
esac;;
|
||||
esac
|
||||
exit "$STAT"
|
||||
else
|
||||
echo "Usage: $prog [${comp}_options] file [file]"
|
||||
exit 1
|
||||
fi
|
44
gnu/usr.bin/gzip/zdiff.1
Normal file
44
gnu/usr.bin/gzip/zdiff.1
Normal file
@ -0,0 +1,44 @@
|
||||
.TH ZDIFF 1
|
||||
.SH NAME
|
||||
zcmp, zdiff \- compare compressed files
|
||||
.SH SYNOPSIS
|
||||
.B zcmp
|
||||
[ cmp_options ] file1
|
||||
[ file2 ]
|
||||
.br
|
||||
.B zdiff
|
||||
[ diff_options ] file1
|
||||
[ file2 ]
|
||||
.SH DESCRIPTION
|
||||
.I Zcmp
|
||||
and
|
||||
.I zdiff
|
||||
are used to invoke the
|
||||
.I cmp
|
||||
or the
|
||||
.I diff
|
||||
program on compressed files. All options specified are passed directly to
|
||||
.I cmp
|
||||
or
|
||||
.IR diff "."
|
||||
If only 1 file is specified, then the files compared are
|
||||
.I file1
|
||||
and an uncompressed
|
||||
.IR file1 ".gz."
|
||||
If two files are specified, then they are uncompressed if necessary and fed to
|
||||
.I cmp
|
||||
or
|
||||
.IR diff "."
|
||||
The exit status from
|
||||
.I cmp
|
||||
or
|
||||
.I diff
|
||||
is preserved.
|
||||
.SH "SEE ALSO"
|
||||
cmp(1), diff(1), zmore(1), znew(1), zforce(1), gzip(1), gzexe(1)
|
||||
.SH BUGS
|
||||
Messages from the
|
||||
.I cmp
|
||||
or
|
||||
.I diff
|
||||
programs refer to temporary filenames instead of those specified.
|
39
gnu/usr.bin/gzip/zforce
Normal file
39
gnu/usr.bin/gzip/zforce
Normal file
@ -0,0 +1,39 @@
|
||||
#!/bin/sh
|
||||
# zforce: force a gz extension on all gzip files so that gzip will not
|
||||
# compress them twice.
|
||||
#
|
||||
# This can be useful for files with names truncated after a file transfer.
|
||||
# 12345678901234 is renamed to 12345678901.gz
|
||||
|
||||
x=`basename $0`
|
||||
if test $# = 0; then
|
||||
echo "force a '.gz' extension on all gzip files"
|
||||
echo usage: $x files...
|
||||
exit 1
|
||||
fi
|
||||
|
||||
res=0
|
||||
for i do
|
||||
if test ! -f "$i" ; then
|
||||
echo ${x}: $i not a file
|
||||
res=1
|
||||
continue
|
||||
fi
|
||||
test `expr "$i" : '.*[.-]z$'` -eq 0 || continue
|
||||
test `expr "$i" : '.*[.-]gz$'` -eq 0 || continue
|
||||
test `expr "$i" : '.*[.]t[ag]z$'` -eq 0 || continue
|
||||
|
||||
gzip -t "$i" 2>/dev/null || continue
|
||||
|
||||
if test `expr "$i" : '^............'` -eq 12; then
|
||||
new=`expr "$i" : '\(.*\)...$`.gz
|
||||
else
|
||||
new="$i.gz"
|
||||
fi
|
||||
if mv "$i" "$new" 2>/dev/null; then
|
||||
echo $i -- replaced with $new
|
||||
continue
|
||||
fi
|
||||
res=1; echo ${x}: cannot rename $i to $new
|
||||
done
|
||||
exit $res
|
20
gnu/usr.bin/gzip/zforce.1
Normal file
20
gnu/usr.bin/gzip/zforce.1
Normal file
@ -0,0 +1,20 @@
|
||||
.TH ZFORCE 1
|
||||
.SH NAME
|
||||
zforce \- force a '.gz' extension on all gzip files
|
||||
.SH SYNOPSIS
|
||||
.B zforce
|
||||
[ name ... ]
|
||||
.SH DESCRIPTION
|
||||
.I zforce
|
||||
forces a .gz extension on all
|
||||
.I gzip
|
||||
files so that
|
||||
.I gzip
|
||||
will not compress them twice.
|
||||
This can be useful for files with names truncated after a file transfer.
|
||||
On systems with a 14 char limitation on file names, the original name
|
||||
is truncated to make room for the .gz suffix. For example,
|
||||
12345678901234 is renamed to 12345678901.gz. A file name such as foo.tgz
|
||||
is left intact.
|
||||
.SH "SEE ALSO"
|
||||
gzip(1), znew(1), zmore(1), zcmp(1), gzexe(1)
|
118
gnu/usr.bin/gzip/zip.c
Normal file
118
gnu/usr.bin/gzip/zip.c
Normal file
@ -0,0 +1,118 @@
|
||||
/* zip.c -- compress files to the gzip or pkzip format
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: zip.c,v 0.16 1993/05/28 14:51:17 jloup Exp $";
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "tailor.h"
|
||||
#include "gzip.h"
|
||||
#include "crypt.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifndef NO_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
local ulg crc; /* crc on uncompressed file data */
|
||||
long header_bytes; /* number of bytes in gzip header */
|
||||
|
||||
/* ===========================================================================
|
||||
* Deflate in to out.
|
||||
* IN assertions: the input and output buffers are cleared.
|
||||
* The variables time_stamp and save_orig_name are initialized.
|
||||
*/
|
||||
int zip(in, out)
|
||||
int in, out; /* input and output file descriptors */
|
||||
{
|
||||
uch flags = 0; /* general purpose bit flags */
|
||||
ush attr = 0; /* ascii/binary flag */
|
||||
ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */
|
||||
|
||||
ifd = in;
|
||||
ofd = out;
|
||||
outcnt = 0;
|
||||
|
||||
/* Write the header to the gzip file. See algorithm.doc for the format */
|
||||
|
||||
method = DEFLATED;
|
||||
put_byte(GZIP_MAGIC[0]); /* magic header */
|
||||
put_byte(GZIP_MAGIC[1]);
|
||||
put_byte(DEFLATED); /* compression method */
|
||||
|
||||
if (save_orig_name) {
|
||||
flags |= ORIG_NAME;
|
||||
}
|
||||
put_byte(flags); /* general flags */
|
||||
put_long(time_stamp);
|
||||
|
||||
/* Write deflated file to zip file */
|
||||
crc = updcrc(0, 0);
|
||||
|
||||
bi_init(out);
|
||||
ct_init(&attr, &method);
|
||||
lm_init(level, &deflate_flags);
|
||||
|
||||
put_byte((uch)deflate_flags); /* extra flags */
|
||||
put_byte(OS_CODE); /* OS identifier */
|
||||
|
||||
if (save_orig_name) {
|
||||
char *p = basename(ifname); /* Don't save the directory part. */
|
||||
do {
|
||||
put_char(*p);
|
||||
} while (*p++);
|
||||
}
|
||||
header_bytes = (long)outcnt;
|
||||
|
||||
(void)deflate();
|
||||
|
||||
#if !defined(NO_SIZE_CHECK) && !defined(RECORD_IO)
|
||||
/* Check input size (but not in VMS -- variable record lengths mess it up)
|
||||
* and not on MSDOS -- diet in TSR mode reports an incorrect file size)
|
||||
*/
|
||||
if (ifile_size != -1L && isize != (ulg)ifile_size) {
|
||||
Trace((stderr, " actual=%ld, read=%ld ", ifile_size, isize));
|
||||
fprintf(stderr, "%s: %s: file size changed while zipping\n",
|
||||
progname, ifname);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Write the crc and uncompressed size */
|
||||
put_long(crc);
|
||||
put_long(isize);
|
||||
header_bytes += 2*sizeof(long);
|
||||
|
||||
flush_outbuf();
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/* ===========================================================================
|
||||
* Read a new buffer from the current input file, perform end-of-line
|
||||
* translation, and update the crc and input file size.
|
||||
* IN assertion: size >= 2 (for end-of-line translation)
|
||||
*/
|
||||
int file_read(buf, size)
|
||||
char *buf;
|
||||
unsigned size;
|
||||
{
|
||||
unsigned len;
|
||||
|
||||
Assert(insize == 0, "inbuf not empty");
|
||||
|
||||
len = read(ifd, buf, size);
|
||||
if (len == (unsigned)(-1) || len == 0) return (int)len;
|
||||
|
||||
crc = updcrc((uch*)buf, len);
|
||||
isize += (ulg)len;
|
||||
return (int)len;
|
||||
}
|
42
gnu/usr.bin/gzip/zmore
Normal file
42
gnu/usr.bin/gzip/zmore
Normal file
@ -0,0 +1,42 @@
|
||||
#!/bin/sh
|
||||
|
||||
if test "`echo -n a`" = "-n a"; then
|
||||
# looks like a SysV system:
|
||||
n1=''; n2='\c'
|
||||
else
|
||||
n1='-n'; n2=''
|
||||
fi
|
||||
if stty -cbreak 2>/dev/null; then
|
||||
cb='cbreak'; ncb='-cbreak'
|
||||
else
|
||||
# 'stty min 1' resets eof to ^a on both SunOS and SysV!
|
||||
cb='min 1 -icanon'; ncb='icanon eof ^d'
|
||||
fi
|
||||
oldtty=`stty -g`
|
||||
trap 'stty -g $oldtty 2>/dev/null; exit' 0 2 3 5 10 13 15
|
||||
|
||||
if test $# = 0; then
|
||||
gzip -cd | eval ${PAGER-more}
|
||||
else
|
||||
FIRST=1
|
||||
for FILE
|
||||
do
|
||||
if test $FIRST -eq 0; then
|
||||
echo $n1 "--More--(Next file: $FILE)$n2"
|
||||
stty $cb -echo 2>/dev/null
|
||||
ANS=`dd bs=1 count=1 2>/dev/null`
|
||||
stty $ncb echo 2>/dev/null
|
||||
echo " "
|
||||
if test "$ANS" = 'e' -o "$ANS" = 'q'; then
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
if test "$ANS" != 's'; then
|
||||
echo "------> $FILE <------"
|
||||
gzip -cd "$FILE" | eval ${PAGER-more}
|
||||
fi
|
||||
if test -t; then
|
||||
FIRST=0
|
||||
fi
|
||||
done
|
||||
fi
|
134
gnu/usr.bin/gzip/zmore.1
Normal file
134
gnu/usr.bin/gzip/zmore.1
Normal file
@ -0,0 +1,134 @@
|
||||
.TH ZMORE 1
|
||||
.SH NAME
|
||||
zmore \- file perusal filter for crt viewing of compressed text
|
||||
.SH SYNOPSIS
|
||||
.B zmore
|
||||
[ name ... ]
|
||||
.SH DESCRIPTION
|
||||
.I Zmore
|
||||
is a filter which allows examination of compressed text files
|
||||
one screenful at a time on a soft-copy terminal.
|
||||
It normally pauses after each screenful, printing --More--
|
||||
at the bottom of the screen.
|
||||
If the user then types a carriage return, one more line is displayed.
|
||||
If the user hits a space,
|
||||
another screenful is displayed. Other possibilities are enumerated later.
|
||||
.PP
|
||||
.I Zmore
|
||||
looks in the file
|
||||
.I /etc/termcap
|
||||
to determine terminal characteristics,
|
||||
and to determine the default window size.
|
||||
On a terminal capable of displaying 24 lines,
|
||||
the default window size is 22 lines.
|
||||
To use a pager other than the default
|
||||
.I more,
|
||||
set environment variable PAGER to the name of the desired program, such as
|
||||
.I less.
|
||||
.PP
|
||||
Other sequences which may be typed when
|
||||
.I zmore
|
||||
pauses, and their effects, are as follows (\fIi\fP is an optional integer
|
||||
argument, defaulting to 1) :
|
||||
.PP
|
||||
.IP \fIi\|\fP<space>
|
||||
display
|
||||
.I i
|
||||
more lines, (or another screenful if no argument is given)
|
||||
.PP
|
||||
.IP ^D
|
||||
display 11 more lines (a ``scroll'').
|
||||
If
|
||||
.I i
|
||||
is given, then the scroll size is set to \fIi\|\fP.
|
||||
.PP
|
||||
.IP d
|
||||
same as ^D (control-D)
|
||||
.PP
|
||||
.IP \fIi\|\fPz
|
||||
same as typing a space except that \fIi\|\fP, if present, becomes the new
|
||||
window size. Note that the window size reverts back to the default at the
|
||||
end of the current file.
|
||||
.PP
|
||||
.IP \fIi\|\fPs
|
||||
skip \fIi\|\fP lines and print a screenful of lines
|
||||
.PP
|
||||
.IP \fIi\|\fPf
|
||||
skip \fIi\fP screenfuls and print a screenful of lines
|
||||
.PP
|
||||
.IP "q or Q"
|
||||
quit reading the current file; go on to the next (if any)
|
||||
.PP
|
||||
.IP "e or q"
|
||||
When the prompt --More--(Next file:
|
||||
.IR file )
|
||||
is printed, this command causes zmore to exit.
|
||||
.PP
|
||||
.IP s
|
||||
When the prompt --More--(Next file:
|
||||
.IR file )
|
||||
is printed, this command causes zmore to skip the next file and continue.
|
||||
.PP
|
||||
.IP =
|
||||
Display the current line number.
|
||||
.PP
|
||||
.IP \fIi\|\fP/expr
|
||||
search for the \fIi\|\fP-th occurrence of the regular expression \fIexpr.\fP
|
||||
If the pattern is not found,
|
||||
.I zmore
|
||||
goes on to the next file (if any).
|
||||
Otherwise, a screenful is displayed, starting two lines before the place
|
||||
where the expression was found.
|
||||
The user's erase and kill characters may be used to edit the regular
|
||||
expression.
|
||||
Erasing back past the first column cancels the search command.
|
||||
.PP
|
||||
.IP \fIi\|\fPn
|
||||
search for the \fIi\|\fP-th occurrence of the last regular expression entered.
|
||||
.PP
|
||||
.IP !command
|
||||
invoke a shell with \fIcommand\|\fP.
|
||||
The character `!' in "command" are replaced with the
|
||||
previous shell command. The sequence "\\!" is replaced by "!".
|
||||
.PP
|
||||
.IP ":q or :Q"
|
||||
quit reading the current file; go on to the next (if any)
|
||||
(same as q or Q).
|
||||
.PP
|
||||
.IP .
|
||||
(dot) repeat the previous command.
|
||||
.PP
|
||||
The commands take effect immediately, i.e., it is not necessary to
|
||||
type a carriage return.
|
||||
Up to the time when the command character itself is given,
|
||||
the user may hit the line kill character to cancel the numerical
|
||||
argument being formed.
|
||||
In addition, the user may hit the erase character to redisplay the
|
||||
--More-- message.
|
||||
.PP
|
||||
At any time when output is being sent to the terminal, the user can
|
||||
hit the quit key (normally control\-\\).
|
||||
.I Zmore
|
||||
will stop sending output, and will display the usual --More--
|
||||
prompt.
|
||||
The user may then enter one of the above commands in the normal manner.
|
||||
Unfortunately, some output is lost when this is done, due to the
|
||||
fact that any characters waiting in the terminal's output queue
|
||||
are flushed when the quit signal occurs.
|
||||
.PP
|
||||
The terminal is set to
|
||||
.I noecho
|
||||
mode by this program so that the output can be continuous.
|
||||
What you type will thus not show on your terminal, except for the / and !
|
||||
commands.
|
||||
.PP
|
||||
If the standard output is not a teletype, then
|
||||
.I zmore
|
||||
acts just like
|
||||
.I zcat,
|
||||
except that a header is printed before each file.
|
||||
.SH FILES
|
||||
.DT
|
||||
/etc/termcap Terminal data base
|
||||
.SH "SEE ALSO"
|
||||
more(1), gzip(1), zcmp(1), znew(1), zforce(1), gzexe(1)
|
140
gnu/usr.bin/gzip/znew
Normal file
140
gnu/usr.bin/gzip/znew
Normal file
@ -0,0 +1,140 @@
|
||||
#!/bin/sh
|
||||
|
||||
check=0
|
||||
pipe=0
|
||||
opt=
|
||||
files=
|
||||
keep=0
|
||||
res=0
|
||||
old=0
|
||||
new=0
|
||||
block=1024
|
||||
# block is the disk block size (best guess, need not be exact)
|
||||
|
||||
warn="(does not preserve modes and timestamp)"
|
||||
tmp=/tmp/zfoo.$$
|
||||
echo hi > $tmp.1
|
||||
echo hi > $tmp.2
|
||||
if test -z "`(${CPMOD-cpmod} $tmp.1 $tmp.2) 2>&1`"; then
|
||||
cpmod=${CPMOD-cpmod}
|
||||
warn=""
|
||||
fi
|
||||
|
||||
if test -z "$cpmod" && ${TOUCH-touch} -r $tmp.1 $tmp.2 2>/dev/null; then
|
||||
cpmod="${TOUCH-touch}"
|
||||
cpmodarg="-r"
|
||||
warn="(does not preserve file modes)"
|
||||
fi
|
||||
rm -f $tmp.[12]
|
||||
|
||||
A=
|
||||
fileno=0
|
||||
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
-*) opt="$opt $arg";;
|
||||
*) fileno=`expr $fileno + 1`
|
||||
eval A$fileno=\$arg
|
||||
A="$A \"\$A$fileno\""
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if test $fileno -eq 0; then
|
||||
echo 'recompress .Z files into .gz (gzip) files'
|
||||
echo usage: `echo $0 | sed 's,^.*/,,'` "[-tv9P]" file.Z...
|
||||
echo " -t tests the new files before deleting originals"
|
||||
echo " -v be verbose"
|
||||
echo " -9 use the slowest compression method (optimal compression)"
|
||||
echo " -K keep a .Z file when it is smaller than the .gz file"
|
||||
echo " -P use pipes for the conversion $warn"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
eval set "$A" # the files are now in $1, $2, ...
|
||||
|
||||
opt=`echo "$opt" | sed -e 's/ //g' -e 's/-//g'`
|
||||
case "$opt" in
|
||||
*t*) check=1; opt=`echo "$opt" | sed 's/t//g'`
|
||||
esac
|
||||
case "$opt" in
|
||||
*K*) keep=1; opt=`echo "$opt" | sed 's/K//g'`
|
||||
esac
|
||||
case "$opt" in
|
||||
*P*) pipe=1; opt=`echo "$opt" | sed 's/P//g'`
|
||||
esac
|
||||
if test -n "$opt"; then
|
||||
opt="-$opt"
|
||||
fi
|
||||
|
||||
for i do
|
||||
n=`echo $i | sed 's/.Z$//'`
|
||||
if test ! -f "$n.Z" ; then
|
||||
echo $n.Z not found
|
||||
res=1; continue
|
||||
fi
|
||||
test $keep -eq 1 && old=`wc -c < "$n.Z"`
|
||||
if test $pipe -eq 1; then
|
||||
if gzip -d < "$n.Z" | gzip $opt > "$n.gz"; then
|
||||
# Copy file attributes from old file to new one, if possible.
|
||||
test -n "$cpmod" && $cpmod $cpmodarg "$n.Z" "$n.gz" 2> /dev/null
|
||||
else
|
||||
echo error while recompressing $n.Z
|
||||
res=1; continue
|
||||
fi
|
||||
else
|
||||
if test $check -eq 1; then
|
||||
if cp -p "$n.Z" "$n.$$" 2> /dev/null || cp "$n.Z" "$n.$$"; then
|
||||
:
|
||||
else
|
||||
echo cannot backup "$n.Z"
|
||||
res=1; continue
|
||||
fi
|
||||
fi
|
||||
if gzip -d "$n.Z"; then
|
||||
:
|
||||
else
|
||||
test $check -eq 1 && mv "$n.$$" "$n.Z"
|
||||
echo error while uncompressing $n.Z
|
||||
res=1; continue
|
||||
fi
|
||||
if gzip $opt "$n"; then
|
||||
:
|
||||
else
|
||||
if test $check -eq 1; then
|
||||
mv "$n.$$" "$n.Z" && rm -f "$n"
|
||||
echo error while recompressing $n
|
||||
else
|
||||
# compress $n (might be dangerous if disk full)
|
||||
echo error while recompressing $n, left uncompressed
|
||||
fi
|
||||
res=1; continue
|
||||
fi
|
||||
fi
|
||||
test $keep -eq 1 && new=`wc -c < "$n.gz"`
|
||||
if test $keep -eq 1 -a `expr \( $old + $block - 1 \) / $block` -lt \
|
||||
`expr \( $new + $block - 1 \) / $block`; then
|
||||
if test $pipe -eq 1; then
|
||||
rm -f "$n.gz"
|
||||
elif test $check -eq 1; then
|
||||
mv "$n.$$" "$n.Z" && rm -f "$n.gz"
|
||||
else
|
||||
gzip -d "$n.gz" && compress "$n" && rm -f "$n.gz"
|
||||
fi
|
||||
echo "$n.Z smaller than $n.gz -- unchanged"
|
||||
|
||||
elif test $check -eq 1; then
|
||||
if gzip -t "$n.gz" ; then
|
||||
rm -f "$n.$$" "$n.Z"
|
||||
else
|
||||
test $pipe -eq 0 && mv "$n.$$" "$n.Z"
|
||||
rm -f "$n.gz"
|
||||
echo error while testing $n.gz, $n.Z unchanged
|
||||
res=1; continue
|
||||
fi
|
||||
elif test $pipe -eq 1; then
|
||||
rm -f "$n.Z"
|
||||
fi
|
||||
done
|
||||
exit $res
|
36
gnu/usr.bin/gzip/znew.1
Normal file
36
gnu/usr.bin/gzip/znew.1
Normal file
@ -0,0 +1,36 @@
|
||||
.TH ZNEW 1
|
||||
.SH NAME
|
||||
znew \- recompress .Z files to .gz files
|
||||
.SH SYNOPSIS
|
||||
.B znew
|
||||
[ -ftv9PK] [ name.Z ... ]
|
||||
.SH DESCRIPTION
|
||||
.I Znew
|
||||
recompresses files from .Z (compress) format to .gz (gzip) format.
|
||||
.SH OPTIONS
|
||||
.B \-f
|
||||
Force recompression from .Z to .gz format even if a .gz file already exists.
|
||||
.TP
|
||||
.B \-t
|
||||
Tests the new files before deleting originals.
|
||||
.TP
|
||||
.B \-v
|
||||
Verbose. Display the name and percentage reduction for each file compressed.
|
||||
.TP
|
||||
.B \-9
|
||||
Use the slowest compression method (optimal compression).
|
||||
.TP
|
||||
.B \-P
|
||||
Use pipes for the conversion to reduce disk space usage.
|
||||
.TP
|
||||
.B \-K
|
||||
Keep a .Z file when it is smaller than the .gz file
|
||||
.SH "SEE ALSO"
|
||||
gzip(1), zmore(1), zcmp(1), zforce(1), gzexe(1), compress(1)
|
||||
.SH BUGS
|
||||
.I Znew
|
||||
does not maintain the time stamp with the -P option if
|
||||
.I cpmod(1)
|
||||
is not available and
|
||||
.I touch(1)
|
||||
does not support the -r option.
|
Loading…
Reference in New Issue
Block a user