home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume34 / freeze / part01 < prev    next >
Encoding:
Text File  |  1993-01-18  |  52.6 KB  |  1,977 lines

  1. Newsgroups: comp.sources.misc
  2. From: leo@ipmce.su (Leonid A. Broukhis)
  3. Subject: v34i125:  freeze - Freeze/melt compression program vers. 2.4, Part01/03
  4. Message-ID: <csm-v34i125=freeze.223348@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 6cc50bca6e4ae33375f9885d303e2ae2
  6. Date: Tue, 19 Jan 1993 04:35:13 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: leo@ipmce.su (Leonid A. Broukhis)
  10. Posting-number: Volume 34, Issue 125
  11. Archive-name: freeze/part01
  12. Environment: ISC, Xenix, SunOS, MS-DOS
  13. Supersedes: freeze: Volume 25, Issue 12-13
  14.  
  15. This is version 2.4 of the Freeze/melt compression program. The 
  16. central algorithm has been rewritten so it runs now at least 20%
  17. faster than before.
  18.  
  19. Memory requirements have been reduced so now it is possible to
  20. build freeze in small model for segmented 16-bit architectures.
  21.  
  22. Many small shanges have been made, e.g. `--' option prefix
  23. is now handled as well as `+'.
  24.  
  25. Configure script has been added to simplify installation.
  26.  
  27. Leonid A. Broukhis
  28. ---------------------
  29. #! /bin/sh
  30. # This is a shell archive.  Remove anything before this line, then feed it
  31. # into a shell via "sh file" or similar.  To overwrite existing files,
  32. # type "sh file -c".
  33. # Contents:  README configure encode.c freeze.c
  34. # Wrapped by kent@sparky on Mon Jan 18 22:27:48 1993
  35. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  36. echo If this archive is complete, you will see the following message:
  37. echo '          "shar: End of archive 1 (of 3)."'
  38. if test -f 'README' -a "${1}" != "-c" ; then 
  39.   echo shar: Will not clobber existing file \"'README'\"
  40. else
  41.   echo shar: Extracting \"'README'\" \(7049 characters\)
  42.   sed "s/^X//" >'README' <<'END_OF_FILE'
  43. X        FREEZE / MELT COMPRESSION PROGRAM
  44. X
  45. XThis version is tested under SunOS 4.1.2, Xenix 2.3.2, MS-DOS.
  46. X
  47. XThe following preprocessor symbols control the compilation of Freeze
  48. Xpackage (these can be added by hand into config.h after running ./configure):
  49. X
  50. X    o COMPAT                Turns on backwards compatibility
  51. X                with Freeze 1.0 (have you ever heard
  52. X                about it? :-) )
  53. X    o FASTHASH              Uses another hash function which gives
  54. X                some speedup, thus reducing the compression
  55. X                rate (!)
  56. X    o TEXT_DEFAULT          (For MS-DOS only!) Define, if you
  57. X                freeze text files more often than binary
  58. X                ones. In this case don't forget to use "-i"
  59. X                to freeze binary files!!
  60. X    o TINY                  For segmented architectures -
  61. X                allows to build freeze in small model
  62. X                (data segment is less than 64K).
  63. X    o SMALL                 Decreases the amount of memory
  64. X                but without 64K restriction
  65. X
  66. X    o DEFFILE               Full name of the file with freeze's
  67. X                Huffman values; it is the only
  68. X                symbol defined in the Makefile
  69. X                to allow correlation with installation place.
  70. X
  71. XOther preprocessor symbols (DEBUG, GATHER_STAT) are for internal use
  72. Xonly.
  73. X
  74. XThe format of frozen (2.X) file is incompatible with that of frozen (1.0),
  75. Xbut if this package is compiled with -DCOMPAT switch, you will able to
  76. Xunpack frozen (1.0) files, if you have them.
  77. X
  78. X------------------- COMPILING -----------------------
  79. X
  80. XType "./configure", or "sh configure". If it runs successfully,
  81. Xyou will see messages "creating config.h" and "creating Makefile".
  82. XYou should check them and probably you may have to make some corrections.
  83. XAfter that simply type "make".
  84. X
  85. X------------------- LINT ----------------------------
  86. X
  87. XSome lint's complaints about `used/declared inconsistently' are (in my
  88. Xcase) due to inconsistencies of /usr/include/* and /usr/lib/llib*ln. It
  89. Xisn't dangerous.
  90. X
  91. X------------------- BUGS ----------------------------
  92. X
  93. XPlease send descriptions of found bugs, incompatibilities, etc.  to
  94. Xleo@ipmce.su.
  95. X
  96. X------------ SPEED & COMPRESSION RATE ---------------
  97. X
  98. XCompression rate depends somewhat of the hash table size and may vary
  99. Xwith different static Huffman tables.
  100. X
  101. XNote: if you see 16-bits Compress works nearly as Freeze (on some big files),
  102. Xthis means the maximum is gained, so LHA and ARJ won't do their job better
  103. Xby more than 1-1.5%. There are some files (I have one) that freeze compresses
  104. Xbetter than ARJ 2.20.
  105. X
  106. XPlease! If your computer supports the string operations, try to write
  107. X"asm" instructions (GNU style) which realize the memory comparison
  108. X"(s1, s2, maxlength) --> matched length" in the minimum number of clock
  109. Xcycles.  If a noticeable (5% or more) speedup is gained, please send
  110. Xme a message.
  111. X
  112. X--------------- POSSIBLE IMPROVEMENTS ---------------
  113. X
  114. XThe high-level routines (freeze, melt) are almost independent from
  115. Xlow-level routines (Get_Next_Match, Insert/Delete_Node,
  116. XEncode/Decode_Char/Position), so if you want the speed and/or compression
  117. Xrate `a la vogue' you may replace the low-level routines with the homebrew
  118. X(e. g.) ones and enjoy the results.
  119. X
  120. X(I tried to implement splay trees instead of Huffman ones and instead of
  121. Xstatic table for position information, but this gives nothing, alas.)
  122. X
  123. X--------- CALGARY COMPRESSION CORPUS RESULTS --------
  124. X
  125. Xtotal 1114
  126. X  41159 bib.F
  127. X 340525 book1.F
  128. X 229230 book2.F
  129. X  68694 geo.F
  130. X 155270 news.F
  131. X  10559 obj1.F
  132. X  86383 obj2.F
  133. X  19931 paper1.F
  134. X  32444 paper2.F
  135. X  56128 pic.F
  136. X  14190 progc.F
  137. X  17189 progl.F
  138. X  11817 progp.F
  139. X  22953 trans.F
  140. X
  141. XAverage bits/byte on the standard set (except paper3-6) =
  142. X    1106472 * 8 / 3141622 = 2.818
  143. X
  144. X--------------- BACKGROUND INFORMATION -----------------
  145. X
  146. X    The format of a frozen file is as follows:
  147. X    (version 1.0 had only 2-bytes header)
  148. X
  149. Xoffset    type      value    comment
  150. X  0       byte       037     2 byte magic header
  151. X  1       byte       0237    (version 1.0 - 0236)
  152. X  2       short       X      (little endian)
  153. X  4       byte        Y
  154. X
  155. XX = 0 e e e e e d d d d c c c b b a   \
  156. X                       > [a-f] are binary digits
  157. XY = 0 0 f f f f f f                   /
  158. X
  159. Xa - number of 1-bit static Huffman codes in the `matching positions'
  160. Xtable (see freeze.1)
  161. Xbb - number of 2-bit codes,
  162. X    etc.
  163. X
  164. XThe numbers of 7- and 8-bits codes are evaluated from the
  165. Xconditions: sum(codes) = 62(dec), max code = 1111111(bin).
  166. X
  167. XE.g. values are: 0 1 1 1 4 10 27 18, what means:
  168. Xno 1-bit codes,
  169. Xone 2-bit, 3-bit and 4-bit codes, etc., so Huffman codes are:
  170. X00, 010, 0110, 01110, 01111, 10000, .... , 11111111.
  171. X
  172. XGeneral format of frozen file is:
  173. X
  174. Xmagic header - table description - stream of bits
  175. X
  176. XThe stream of bits is considered as a sequence of variable length dynamic
  177. XHuffman codes (if their values are in the range of 0-255, they mean single
  178. Xbytes, special value of 256 means EOF, and further values mean the lengths
  179. Xof matched string.) If we have the value greater than 256, we get a static
  180. XHuffman code from the stream (his value is 6 higher bits of matched
  181. Xstring's position in the buffer), and then we get 7 bits literally.
  182. X
  183. XBecause buffer length is 8192 bytes and maximum match length is 256 bytes,
  184. Xthe position of matched string cannot be greater than 8192-256, that's why
  185. Xthere is only (8192-256)/2^7 = 62 static codes.
  186. X
  187. X            *        *       *
  188. X
  189. XThe default table is tuned for both C texts and executable files (as in
  190. XLHARC). If you freeze any other files (databases, images, fonts,
  191. Xetc.) you can calculate the matching positions distribution using the
  192. X`statist' program, which calculates and displays the mentioned
  193. Xdistribution for the given file. It is useful for large (100K or more)
  194. Xfiles.
  195. X
  196. XThough the built-in position table is polyvalent, the tuning can increase
  197. Xthe compression rate up to one additional percent.  (Or even more, if the
  198. Xmatching strings distribution is very bizarre!)
  199. X
  200. XUsage: statist < sample_file ; you can also see the intermediate values
  201. Xand watch their changes by pressing INTR key when you wish.
  202. X
  203. XNote: If you use "gensample | statist", remember that INTR influence BOTH
  204. Xprocesses !!
  205. X
  206. XYou may create the /etc/default/freeze (or rather /usr/local/lib/freeze.cnf,
  207. Xwhich is now the default, NOTE IT!) file (in MS-DOS it is FREEZE.CNF in
  208. Xthe directory of FREEZE.EXE), which has the following format:  name =
  209. X``statist's output (8 numbers)'', e.g.:
  210. X
  211. X---------- cut here -----------
  212. X# This is freeze's defaults file
  213. Xgif =   0 0 0 0 2 60 0 0        # This is NOT! optimal data
  214. X                # for GIF files
  215. Xdoc=0 0 1 2 7 16 36 0           # The sample was gcc.lp
  216. Xgreedy2=0,1,1,2,5,8,11,34       # Both space- and comma-separated
  217. X                # lists are allowed
  218. X
  219. X# End of file
  220. X---------- cut here -----------
  221. X
  222. XIf you find values which are better THAN DEFAULT both for text (C
  223. Xprograms) and binary (executable) files, please send them to me.
  224. X
  225. XImportant note: statist.c is NOT a part of freeze package, it is an
  226. Xadditional feature.
  227. X
  228. X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  229. X
  230. XThere is yet another additional feature since this version:
  231. X
  232. Xshowhuf - shows Huffman table in a frozen file.
  233. XIt can be used to find files frozen with freeze 1.0, too.
  234. END_OF_FILE
  235.   if test 7049 -ne `wc -c <'README'`; then
  236.     echo shar: \"'README'\" unpacked with wrong size!
  237.   fi
  238.   # end of 'README'
  239. fi
  240. if test -f 'configure' -a "${1}" != "-c" ; then 
  241.   echo shar: Will not clobber existing file \"'configure'\"
  242. else
  243.   echo shar: Extracting \"'configure'\" \(12452 characters\)
  244.   sed "s/^X//" >'configure' <<'END_OF_FILE'
  245. X#!/bin/sh
  246. X# Guess values for system-dependent variables and create Makefiles.
  247. X# Generated automatically using autoconf.
  248. X# Copyright (C) 1991, 1992 Free Software Foundation, Inc.
  249. X
  250. X# This program is free software; you can redistribute it and/or modify
  251. X# it under the terms of the GNU General Public License as published by
  252. X# the Free Software Foundation; either version 2, or (at your option)
  253. X# any later version.
  254. X
  255. X# This program is distributed in the hope that it will be useful,
  256. X# but WITHOUT ANY WARRANTY; without even the implied warranty of
  257. X# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  258. X# GNU General Public License for more details.
  259. X
  260. X# You should have received a copy of the GNU General Public License
  261. X# along with this program; if not, write to the Free Software
  262. X# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  263. X
  264. X# Usage: configure [--srcdir=DIR] [--host=HOST] [--gas] [--nfp] [--no-create]
  265. X#        [--prefix=PREFIX] [--exec_prefix=PREFIX] [--with-PROGRAM] [TARGET]
  266. X# Ignores all args except --srcdir, --prefix, --exec_prefix, and --no-create.
  267. X
  268. Xtrap 'rm -f conftest* core; exit 1' 1 3 15
  269. X
  270. Xfor arg
  271. Xdo
  272. X  # Handle --exec_prefix with a space before the argument.
  273. X  if test x$next_exec_prefix = xyes; then exec_prefix=$arg; next_exec_prefix=
  274. X  # Handle --host with a space before the argument.
  275. X  elif test x$next_host = xyes; then next_host=
  276. X  # Handle --prefix with a space before the argument.
  277. X  elif test x$next_prefix = xyes; then prefix=$arg; next_prefix=
  278. X  # Handle --srcdir with a space before the argument.
  279. X  elif test x$next_srcdir = xyes; then srcdir=$arg; next_srcdir=
  280. X  else
  281. X    case $arg in
  282. X     -exec_prefix=* | --exec_prefix=* | --exec_prefi=* | --exec_pref=* | --exec_pre=* | --exec_pr=* | --exec_p=* | --exec_=* | --exec=* | --exe=* | --ex=* | --e=*)
  283. X    exec_prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;;
  284. X     -exec_prefix | --exec_prefix | --exec_prefi | --exec_pref | --exec_pre | --exec_pr | --exec_p | --exec_ | --exec | --exe | --ex | --e)
  285. X    next_exec_prefix=yes ;;
  286. X
  287. X     -gas | --gas | --ga | --g) ;;
  288. X
  289. X     -host=* | --host=* | --hos=* | --ho=* | --h=*) ;;
  290. X     -host | --host | --hos | --ho | --h)
  291. X    next_host=yes ;;
  292. X
  293. X     -nfp | --nfp | --nf) ;;
  294. X
  295. X     -no-create | --no-create | --no-creat | --no-crea | --no-cre | --no-cr | --no-c | --no- | --no)
  296. X        no_create=1 ;;
  297. X
  298. X     -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
  299. X    prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;;
  300. X     -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
  301. X    next_prefix=yes ;;
  302. X
  303. X     -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=* | --s=*)
  304. X    srcdir=`echo $arg | sed 's/[-a-z_]*=//'` ;;
  305. X     -srcdir | --srcdir | --srcdi | --srcd | --src | --sr | --s)
  306. X    next_srcdir=yes ;;
  307. X
  308. X     -with-* | --with-*) ;;
  309. X
  310. X     *) ;;
  311. X    esac
  312. X  fi
  313. Xdone
  314. X
  315. Xrm -f conftest*
  316. Xcompile='${CC-cc} $DEFS conftest.c -o conftest $LIBS >/dev/null 2>&1'
  317. X
  318. X# A filename unique to this package, relative to the directory that
  319. X# configure is in, which we can look for to find out if srcdir is correct.
  320. Xunique_file=freeze.h
  321. X
  322. X# Find the source files, if location was not specified.
  323. Xif test -z "$srcdir"; then
  324. X  srcdirdefaulted=yes; srcdir=.
  325. X  if test ! -r $unique_file; then srcdir=..; fi
  326. Xfi
  327. Xif test ! -r $srcdir/$unique_file; then
  328. X  if test x$srcdirdefaulted = xyes; then
  329. X    echo "configure: Can not find sources in \`.' or \`..'." 1>&2
  330. X  else
  331. X    echo "configure: Can not find sources in \`${srcdir}'." 1>&2
  332. X  fi
  333. X  exit 1
  334. Xfi
  335. X# Preserve a srcdir of `.' to avoid automounter screwups with pwd.
  336. X# But we can't avoid them for `..', to make subdirectories work.
  337. Xcase $srcdir in
  338. X  .|/*|~*) ;;
  339. X  *) srcdir=`cd $srcdir; pwd` ;; # Make relative path absolute.
  340. Xesac
  341. X
  342. X
  343. Xcompile='rm -f conftest.t;
  344. X  mv conftest.c conftest.t;
  345. X  echo "$DEFS" > conftest.c;
  346. X  cat conftest.t >> conftest.c;
  347. X  rm -f conftest.t;
  348. X  ${CC-cc} conftest.c -o conftest $LIBS >/dev/null 2>&1'
  349. X
  350. Xif test -z "$CC"; then
  351. X  echo checking for gcc
  352. X  saveifs="$IFS"; IFS="${IFS}:"
  353. X  for dir in $PATH; do
  354. X    test -z "$dir" && dir=.
  355. X    if test -f $dir/gcc; then
  356. X      CC="gcc"
  357. X      break
  358. X    fi
  359. X  done
  360. X  IFS="$saveifs"
  361. Xfi
  362. Xtest -z "$CC" && CC="cc"
  363. X
  364. X# Find out if we are using GNU C, under whatever name.
  365. Xcat <<EOF > conftest.c
  366. X#ifdef __GNUC__
  367. X  yes
  368. X#endif
  369. XEOF
  370. X${CC-cc} -E conftest.c > conftest.out 2>&1
  371. Xif egrep yes conftest.out >/dev/null 2>&1; then
  372. X  GCC=1 # For later tests.
  373. X  CC="$CC -O"
  374. Xfi
  375. Xrm -f conftest*
  376. X
  377. Xecho checking how to run the C preprocessor
  378. Xif test -z "$CPP"; then
  379. X  CPP='${CC-cc} -E'
  380. X  cat <<EOF > conftest.c
  381. X$DEFS
  382. X#include <stdio.h>
  383. XEOF
  384. Xerr=`eval "$CPP conftest.c 2>&1 >/dev/null"`
  385. Xif test -z "$err"; then
  386. X  :
  387. Xelse
  388. X  CPP=/lib/cpp
  389. Xfi
  390. Xrm -f conftest*
  391. Xfi
  392. X
  393. Xecho "${DEFS}#include <signal.h>" > conftest.c
  394. Xeval "$CPP conftest.c > conftest.out 2>&1"
  395. Xif egrep "(void|sighandler_t).*signal" conftest.out >/dev/null 2>&1; then
  396. X  :
  397. Xelse 
  398. X  DEFS="${DEFS}#define RETSIGTYPE int
  399. X"
  400. Xfi
  401. Xrm -f conftest*
  402. X
  403. X
  404. Xecho checking for unaligned access
  405. Xcat <<EOF > conftest.c
  406. X#include <signal.h>
  407. XRETSIGTYPE onintr() { exit(1); }
  408. Xint x[2] = { 12345, 67890 };
  409. Xmain() { int *i;
  410. Xchar * p = (char*) x;
  411. Xsignal(SIGBUS, onintr);
  412. Xi = (int*) (p + 1);
  413. Xexit(*i != x[0]); /* check for LSB mask on word access */
  414. X}
  415. XEOF
  416. Xeval $compile
  417. Xif test -s conftest && (./conftest 2>/dev/null) 2>/dev/null; then
  418. X  DEFS="${DEFS}#define ALLOW_MISALIGN 1
  419. X" misalign=1
  420. Xfi
  421. Xrm -f conftest*
  422. Xif test "$misalign"; then
  423. Xecho checking integer size
  424. Xcat <<EOF > conftest.c
  425. Xmain() { exit(!(sizeof(long) > sizeof(int))); }
  426. XEOF
  427. Xeval $compile
  428. Xif test -s conftest && (./conftest 2>/dev/null) 2>/dev/null; then
  429. X  DEFS="${DEFS}#define INT_16_BITS 1
  430. X"
  431. Xfi
  432. Xrm -f conftest*
  433. Xfi
  434. Xecho checking for 64K segments
  435. Xcat <<EOF > conftest.c
  436. Xchar x[69001];
  437. Xmain () {
  438. Xx[12345] = ' ';
  439. Xexit(0);
  440. X}
  441. XEOF
  442. Xeval $compile
  443. Xif test -s conftest && (./conftest 2>/dev/null) 2>/dev/null; then
  444. X  :
  445. Xelse
  446. X  DEFS="${DEFS}#define SEGMENTED 1
  447. X" segmented=1
  448. Xfi
  449. Xrm -f conftest*
  450. Xif test "$segmented"; then
  451. Xecho It seems that your computer supports different memory models.
  452. Xecho If it is so, you may wish to build freeze in small model
  453. Xecho in order to speed it up.
  454. Xecho To do that, you will need to additionally define TINY
  455. Xecho in config.h file you will get after the configuration.
  456. Xfi
  457. Xecho checking for long file names
  458. X(echo 1 > conftest9012345) 2>/dev/null
  459. X(echo 2 > conftest9012346) 2>/dev/null
  460. Xval=`cat conftest9012345 2>/dev/null`
  461. Xtest -f conftest9012345 && test "$val" = 1 && DEFS="${DEFS}#define HAVE_LONG_FILE_NAMES 1
  462. X"
  463. Xrm -f conftest9012345 conftest9012346
  464. X
  465. Xecho checking for directory library header
  466. Xecho checking for dirent.h
  467. Xcat <<EOF > conftest.c
  468. X$DEFS
  469. X#include <dirent.h>
  470. XEOF
  471. Xerr=`eval "$CPP conftest.c 2>&1 >/dev/null"`
  472. Xif test -z "$err"; then
  473. X  DEFS="${DEFS}#define DIRENT 1
  474. X" dirheader=dirent.h
  475. Xfi
  476. Xrm -f conftest*
  477. X
  478. Xif test -z "$dirheader"; then
  479. Xecho checking for sys/ndir.h
  480. Xcat <<EOF > conftest.c
  481. X$DEFS
  482. X#include <sys/ndir.h>
  483. XEOF
  484. Xerr=`eval "$CPP conftest.c 2>&1 >/dev/null"`
  485. Xif test -z "$err"; then
  486. X  DEFS="${DEFS}#define SYSNDIR 1
  487. X" dirheader=sys/ndir.h
  488. Xfi
  489. Xrm -f conftest*
  490. X
  491. Xfi
  492. Xif test -z "$dirheader"; then
  493. Xecho checking for sys/dir.h
  494. Xcat <<EOF > conftest.c
  495. X$DEFS
  496. X#include <sys/dir.h>
  497. XEOF
  498. Xerr=`eval "$CPP conftest.c 2>&1 >/dev/null"`
  499. Xif test -z "$err"; then
  500. X  DEFS="${DEFS}#define SYSDIR 1
  501. X" dirheader=sys/dir.h
  502. Xfi
  503. Xrm -f conftest*
  504. X
  505. Xfi
  506. X
  507. Xecho checking for closedir return value
  508. Xcat <<EOF > conftest.c
  509. X#include <sys/types.h>
  510. X#include <$dirheader>
  511. Xint closedir(); main() { exit(0); }
  512. XEOF
  513. Xeval $compile
  514. Xif test -s conftest && (./conftest 2>/dev/null) 2>/dev/null; then
  515. X  :
  516. Xelse
  517. X  DEFS="${DEFS}#define VOID_CLOSEDIR 1
  518. X"
  519. Xfi
  520. Xrm -f conftest*
  521. X
  522. Xfor hdr in sys/stdtypes.h
  523. Xdo
  524. Xtrfrom='[a-z]./' trto='[A-Z]__'
  525. Xecho checking for $hdr
  526. Xcat <<EOF > conftest.c
  527. X$DEFS
  528. X#include <$hdr>
  529. XEOF
  530. Xerr=`eval "$CPP conftest.c 2>&1 >/dev/null"`
  531. Xif test -z "$err"; then
  532. X  DEFS="${DEFS}#define HAVE_`echo $hdr|tr "$trfrom" "$trto"` 1
  533. X"
  534. Xfi
  535. Xrm -f conftest*
  536. Xdone
  537. X
  538. Xfor func in rindex setlinebuf
  539. Xdo
  540. Xtrfrom='[a-z]' trto='[A-Z]'
  541. Xecho checking for ${func}
  542. Xecho "
  543. Xmain() { exit(0); } t() { 
  544. X/* Override any gcc2 internal prototype to avoid an error.  */
  545. Xextern char ${func}(); ${func}(); }" > conftest.c
  546. Xif eval $compile; then
  547. X  DEFS="${DEFS}#define HAVE_`echo $func|tr "$trfrom" "$trto"` 1
  548. X"
  549. Xfi
  550. Xrm -f conftest*
  551. Xdone
  552. X
  553. Xecho "${DEFS}#include <utime.h>" > conftest.c
  554. Xeval "$CPP conftest.c > conftest.out 2>&1"
  555. Xif egrep "utimbuf" conftest.out >/dev/null 2>&1; then
  556. X  DEFS="${DEFS}#define UTIME 1
  557. X" utimes=1
  558. Xfi
  559. Xrm -f conftest*
  560. X
  561. Xif test -z "$utimes"; then
  562. Xecho "${DEFS}#include <sys/utime.h>" > conftest.c
  563. Xeval "$CPP conftest.c > conftest.out 2>&1"
  564. Xif egrep "utimbuf" conftest.out >/dev/null 2>&1; then
  565. X  DEFS="${DEFS}#define SYSUTIME 1
  566. X" utimes=1
  567. Xfi
  568. Xrm -f conftest*
  569. X
  570. Xfi
  571. Xif test -z "$utimes"; then
  572. Xecho "${DEFS}#include <sys/time.h>" > conftest.c
  573. Xeval "$CPP conftest.c > conftest.out 2>&1"
  574. Xif egrep "timeval" conftest.out >/dev/null 2>&1; then
  575. X  DEFS="${DEFS}#define SYSTIME 1
  576. X"
  577. Xfi
  578. Xrm -f conftest*
  579. X
  580. Xfi
  581. X# Make sure to not get the incompatible SysV /etc/install and
  582. X# /usr/sbin/install, which might be in PATH before a BSD-like install,
  583. X# or the SunOS /usr/etc/install directory.
  584. Xif test -z "$INSTALL"; then
  585. X  echo checking for install
  586. X  saveifs="$IFS"; IFS="${IFS}:"
  587. X  for dir in $PATH; do
  588. X    test -z "$dir" && dir=.
  589. X    case $dir in
  590. X    /etc|/usr/sbin|/usr/etc) ;;
  591. X    *)
  592. X      if test -f $dir/install; then
  593. X    INSTALL="$dir/install -c"
  594. X    INSTALL_PROGRAM='$(INSTALL)'
  595. X    INSTALL_DATA='$(INSTALL) -m 644'
  596. X    break
  597. X      fi
  598. X      ;;
  599. X    esac
  600. X  done
  601. X  IFS="$saveifs"
  602. Xfi
  603. XINSTALL=${INSTALL-cp}
  604. XINSTALL_PROGRAM=${INSTALL_PROGRAM-'$(INSTALL)'}
  605. XINSTALL_DATA=${INSTALL_DATA-'$(INSTALL)'}
  606. X
  607. Xecho checking for freeze to derive installation directory prefix
  608. Xif test -z "$prefix"
  609. Xthen
  610. X  saveifs="$IFS"; IFS="$IFS:"
  611. X  for dir in $PATH; do
  612. X    test -z "$dir" && dir=.
  613. X    if test $dir != . && test -f $dir/freeze; then
  614. X      # Not all systems have dirname.
  615. X      prefix=`echo $dir|sed 's,/[^/][^/]*$,,'`
  616. X      break
  617. X    fi
  618. X  done
  619. X  IFS="$saveifs"
  620. Xfi
  621. X
  622. Xif test -n "$prefix"; then
  623. X  test -z "$exec_prefix" && exec_prefix='$(prefix)'
  624. X  prsub="s,^prefix[     ]*=.*$,prefix = $prefix,"
  625. Xfi
  626. Xif test -n "$exec_prefix"; then
  627. X  prsub="$prsub
  628. Xs,^exec_prefix[     ]*=.*$,exec_prefix = $exec_prefix,"
  629. Xfi
  630. X
  631. Xtrap 'rm -f config.status; exit 1' 1 3 15
  632. Xecho creating config.status
  633. Xrm -f config.status
  634. Xcat <<EOF > config.status
  635. X#!/bin/sh
  636. X# Generated automatically by configure.
  637. X# Run this file to recreate the current configuration.
  638. X# This directory was configured as follows:
  639. X# $0 $*
  640. X
  641. Xcase "\$1" in
  642. X  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
  643. X  exec /bin/sh $0 $* ;;
  644. Xesac
  645. X
  646. Xtrap 'rm -f Makefile config.h; exit 1' 1 3 15
  647. XCC='$CC'
  648. XCPP='$CPP'
  649. XINSTALL='$INSTALL'
  650. XINSTALL_PROGRAM='$INSTALL_PROGRAM'
  651. XINSTALL_DATA='$INSTALL_DATA'
  652. XLIBS='$LIBS'
  653. Xsrcdir='$srcdir'
  654. XDEFS='$DEFS'
  655. Xprefix='$prefix'
  656. Xexec_prefix='$exec_prefix'
  657. Xprsub='$prsub'
  658. XEOF
  659. Xcat <<\EOF >> config.status
  660. X
  661. Xtop_srcdir=$srcdir
  662. Xfor file in Makefile; do
  663. X  srcdir=$top_srcdir
  664. X  # Remove last slash and all that follows it.  Not all systems have dirname.
  665. X  dir=`echo $file|sed 's,/[^/][^/]*$,,'`
  666. X  if test "$dir" != "$file"; then
  667. X    test "$top_srcdir" != . && srcdir=$top_srcdir/$dir
  668. X    test ! -d $dir && mkdir $dir
  669. X  fi
  670. X  echo creating $file
  671. X  rm -f $file
  672. X  echo "# Generated automatically from `basename $file`.in by configure." > $file
  673. X  sed -e "
  674. X$prsub
  675. Xs,@CC@,$CC,
  676. Xs,@CPP@,$CPP,
  677. Xs,@INSTALL@,$INSTALL,
  678. Xs,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,
  679. Xs,@INSTALL_DATA@,$INSTALL_DATA,
  680. Xs,@LIBS@,$LIBS,
  681. Xs,@srcdir@,$srcdir,
  682. X" $top_srcdir/${file}.in >> $file
  683. Xdone
  684. X
  685. Xecho creating config.h
  686. X# Ultrix awk loses trailing comments from the header file, but
  687. X# that's not fatal.
  688. Xrm -f conftest.h
  689. Xecho "/* config.h.  Generated automatically by configure.  */" > conftest.h
  690. Xecho "$DEFS
  691. X/* END_OF_DEFS */" |
  692. Xawk '
  693. X# The escaped newlines are to work around a bug in GNU m4 0.99
  694. X# in quoting more than 2 arguments in a single line.
  695. XBEGIN { filenum = 1 }
  696. Xfilenum == 1 && $1 == "#define" \
  697. X{ defs[$2] = $3
  698. X  for (i = 4; i <= NF; i++)
  699. X    defs[$2] = defs[$2] " " $i
  700. X}
  701. X/END_OF_DEFS/ { filenum = 2; next }
  702. Xfilenum == 2 && $1 == "#define" && \
  703. Xdefs[$2] != "" {
  704. X  $3 = defs[$2]
  705. X  print; next
  706. X}
  707. Xfilenum == 2 && $1 == "#undef" && \
  708. Xdefs[$2] != "" {
  709. X  $1 = "#define"
  710. X  $2 = $2 " " defs[$2]
  711. X  print; next
  712. X}
  713. Xfilenum == 2 { print }
  714. X' - $top_srcdir/config.h.in >> conftest.h
  715. Xif cmp -s config.h conftest.h 2>/dev/null; then
  716. X  # The file exists and we would not be changing it.
  717. X  rm -f conftest.h
  718. Xelse
  719. X  rm -f config.h
  720. X  mv conftest.h config.h
  721. Xfi
  722. X
  723. XEOF
  724. Xchmod +x config.status
  725. Xtest -n "$no_create" || ./config.status
  726. X
  727. END_OF_FILE
  728.   if test 12452 -ne `wc -c <'configure'`; then
  729.     echo shar: \"'configure'\" unpacked with wrong size!
  730.   fi
  731.   chmod +x 'configure'
  732.   # end of 'configure'
  733. fi
  734. if test -f 'encode.c' -a "${1}" != "-c" ; then 
  735.   echo shar: Will not clobber existing file \"'encode.c'\"
  736. else
  737.   echo shar: Extracting \"'encode.c'\" \(5424 characters\)
  738.   sed "s/^X//" >'encode.c' <<'END_OF_FILE'
  739. X
  740. X#include "freeze.h"
  741. X#include "lz.h"
  742. X#include "huf.h"
  743. X#include "bitio.h"
  744. X
  745. X/* for future versions ?... */
  746. X
  747. X#define LENGTH_OFFSET   256
  748. X#define EncodeLiteral(l)        EncodeChar((int)l)
  749. X#define EncodeLength(l)         EncodeChar((int)l + LENGTH_OFFSET)
  750. X
  751. X/*
  752. X * Freezes stdin to stdout
  753. X */
  754. X
  755. Xvoid 
  756. Xfreeze()
  757. X{
  758. X  register int i, len, s, c;
  759. X  register hash_t r;
  760. X  int     match_length;
  761. X
  762. X  putchar(MAGIC1);
  763. X  putchar(MAGIC2_2);
  764. X
  765. X/* Huffman-dependent part */
  766. X  write_header();
  767. X  StartHuff(N_CHAR2);
  768. X  init(Table2);
  769. X/* end of Huffman-dependent part */
  770. X
  771. X  InitTree();            /* LZ dependent */
  772. X  InitIO();
  773. X
  774. X  r = MAXDIST + 1;              /* to make zero links "too old" */
  775. X  s = (r + LOOKAHEAD) & WINMASK;
  776. X
  777. X  for (len = 0; len < LOOKAHEAD && (c = getchar()) != EOF; len++)
  778. X    text_buf[r + len] = c;
  779. X
  780. X /* check for magic header */
  781. X  if (!topipe && !force && text_buf[r] == MAGIC1 &&
  782. X    text_buf[r + 1] >= MAGIC2_1) {
  783. X    if (quiet != 1)
  784. X      fprintf(stderr, " already frozen ");
  785. X    exit_stat = 2;
  786. X    return;
  787. X  }
  788. X  in_count = len;
  789. X
  790. X  /* Insert 256 "initial" spaces and the very first char into hash table */
  791. X  for (i = r - LOOKAHEAD; i < r; i++)
  792. X    text_buf[i] = ' ';
  793. X  for (i = r - LOOKAHEAD; i <= r; i++) {
  794. X    register uc_t  *key = &text_buf[i];
  795. X    register unsigned p = hashof(key);
  796. X    next[i] = hashtab[p];
  797. X    hashtab[p] = i;
  798. X  }
  799. X
  800. X /* here the main loop begins */
  801. X
  802. X  while (len != 0) {
  803. X    match_length = LOOKAHEAD + get_next_match(THRESHOLD - LOOKAHEAD, r);
  804. X    if (match_length > len)
  805. X      match_length = len;
  806. X
  807. X    if (match_length <= THRESHOLD) {
  808. X      match_length = 1;
  809. X      EncodeLiteral(text_buf[r & WINMASK]);
  810. X#ifdef DEBUG
  811. X      symbols_out++;
  812. X      if (verbose)
  813. X    fprintf(stderr, "'%s'\n",
  814. X      pr_char(text_buf[r & WINMASK]));
  815. X#endif                /* DEBUG */
  816. X    } else if (match_length >= chain_length) {
  817. X
  818. X/* GREEDY parsing (if match_length is big enough, put it right away) */
  819. X
  820. X#if defined(GATHER_STAT) || defined (DEBUG)
  821. X      refers_out++;
  822. X#endif
  823. X      EncodeLength(match_length - THRESHOLD);
  824. X      EncodePosition((int) ((r - match_position) & WINMASK) - 1);
  825. X
  826. X    } else {
  827. X      register int orig_length, orig_position;
  828. X      register us_t oldchar;
  829. X
  830. X/* This fragment (delayed coding, non-greedy) is due to ideas of
  831. X    Jan Mark Wams' <jms@cs.vu.nl> COMIC:
  832. X*/
  833. X      oldchar = text_buf[r & WINMASK];
  834. X      orig_length = match_length;
  835. X      orig_position = match_position;
  836. X
  837. X      Next_Char(WINSIZE, LOOKAHEAD);
  838. X      match_length = LOOKAHEAD + get_next_match(match_length - LOOKAHEAD, r);
  839. X
  840. X      if (match_length > len)
  841. X    match_length = len;
  842. X
  843. X      if (orig_length >= match_length) {
  844. X    EncodeLength(orig_length - THRESHOLD);
  845. X    EncodePosition((int) ((r - 1 - orig_position) & WINMASK) - 1);
  846. X#ifdef DEBUG
  847. X    match_position = orig_position;
  848. X#endif                /* DEBUG */
  849. X    match_length = orig_length - 1;
  850. X      } else {
  851. X    EncodeLiteral(oldchar);
  852. X#ifdef DEBUG
  853. X    symbols_out++;
  854. X    if (verbose)
  855. X      fprintf(stderr, "'%s'\n",
  856. X        pr_char(oldchar));
  857. X#endif                /* DEBUG */
  858. X    EncodeLength(match_length - THRESHOLD);
  859. X    EncodePosition((int) ((r - match_position) & WINMASK) - 1);
  860. X      }
  861. X
  862. X#if defined(GATHER_STAT) || defined (DEBUG)
  863. X      refers_out++;
  864. X#endif
  865. X#ifdef DEBUG
  866. X      if (verbose) {
  867. X    register pos = match_position, leng = match_length;
  868. X    fputc('"', stderr);
  869. X    for (; leng; leng--, pos++)
  870. X      fprintf(stderr, "%s",
  871. X        pr_char(text_buf[pos]));
  872. X    fprintf(stderr, "\"\n");
  873. X      }
  874. X#endif                /* DEBUG */
  875. X    }
  876. X
  877. X/* Process the rest of the matched sequence (insertion in the list
  878. X    only, without any matching !!!)
  879. X*/
  880. X
  881. X    for (i = 0; i < match_length &&
  882. X      (c = getchar()) != EOF; i++) {
  883. X      text_buf[s] = c;
  884. X      if (s < LOOKAHEAD - 1)
  885. X    text_buf[s + WINSIZE] = c;
  886. X      s = (s + 1) & WINMASK;
  887. X      r++;
  888. X      InsertNode();
  889. X    }
  890. X
  891. X    in_count += i;
  892. X
  893. X    INDICATOR
  894. X
  895. X      while (i++ < match_length) {
  896. X      len--;
  897. X      r++;
  898. X      InsertNode();
  899. X    }
  900. X
  901. X  }
  902. X
  903. X /* to flush literals */
  904. X  EncodeLength((short) ENDOF - LENGTH_OFFSET);
  905. X#ifdef DEBUG
  906. X  symbols_out++;
  907. X#endif
  908. X  EncodeEnd();
  909. X /* Print out stats on stderr */
  910. X  if (quiet != 1) {
  911. X#ifdef GATHER_STAT
  912. X    fprintf(stderr, "Average number of compares per matching: %d.%02d\n",
  913. X      (int) (node_compares / node_matches),
  914. X      (int) ((node_compares * 100 / node_matches) % 100));
  915. X    fprintf(stderr, "Average number of prolongations per reference: %d.%02d\n",
  916. X      (int) (node_prolongations / refers_out),
  917. X      (int) ((node_prolongations * 100 / refers_out) % 100));
  918. X    fprintf(stderr, "Average number of compares per prolongation: %d.%02d\n",
  919. X      (int) (node_compares / node_prolongations),
  920. X      (int) ((node_compares * 100 / node_prolongations) % 100));
  921. X    fprintf(stderr, "Prolongations/compares: %d/%d\n", node_prolongations,
  922. X      node_compares);
  923. X#endif
  924. X#ifdef DEBUG
  925. X    fprintf(stderr,
  926. X      "%ld chars in, %ld codes (%ld bytes) out, freezing factor: ",
  927. X      in_count, symbols_out + refers_out, bytes_out);
  928. X    prratio(stderr, in_count, bytes_out);
  929. X    fprintf(stderr, "\n");
  930. X    fprintf(stderr, "\tFreezing as in compact: ");
  931. X    prratio(stderr, in_count - bytes_out, in_count);
  932. X    prbits(stderr, in_count, bytes_out);
  933. X    fprintf(stderr, "\n");
  934. X    fprintf(stderr, "\tSymbols: %ld; references: %ld.\n",
  935. X      symbols_out, refers_out);
  936. X#else                /* !DEBUG */
  937. X    fprintf(stderr, "Freezing: ");
  938. X    prratio(stderr, in_count - bytes_out, in_count);
  939. X    prbits(stderr, in_count, bytes_out);
  940. X#endif                /* DEBUG */
  941. X  }
  942. X  if (bytes_out >= in_count)    /* exit(2) if no savings */
  943. X    exit_stat = 2;
  944. X  return;
  945. X}
  946. END_OF_FILE
  947.   if test 5424 -ne `wc -c <'encode.c'`; then
  948.     echo shar: \"'encode.c'\" unpacked with wrong size!
  949.   fi
  950.   # end of 'encode.c'
  951. fi
  952. if test -f 'freeze.c' -a "${1}" != "-c" ; then 
  953.   echo shar: Will not clobber existing file \"'freeze.c'\"
  954. else
  955.   echo shar: Extracting \"'freeze.c'\" \(23757 characters\)
  956.   sed "s/^X//" >'freeze.c' <<'END_OF_FILE'
  957. X#include "freeze.h"
  958. X#include "lz.h"
  959. X#include "patchlev.h"
  960. X
  961. X/*
  962. X * Freeze - data freezing program
  963. X * Version 1.0:
  964. X * This program is made from GNU compress.c and Yoshizaki/Tagawa's
  965. X * lzhuf.c. (Thanks to all of them.)
  966. X * The algorithm is modified for using in pipe
  967. X * (added ENDOF symbol in Huffman table).
  968. X * Version 1.1:
  969. X * Check for lack of bytes in frozen file when melting.
  970. X * Put the GetBit routine into DecodeChar for reduce function-
  971. X * call overhead when melting.
  972. X * Version 1.2:
  973. X * Added delayed coding a la COMIC.
  974. X * Now freeze works on Intels (*NIX, Microsoft, Turbo),
  975. X * Sun (SunOS).
  976. X * Version 2.0:
  977. X * Buffer size is now 8192 bytes, maximum match length - 256 bytes.
  978. X * Improved hash function (with tuning of hash-table)
  979. X * Version 2.1: Noticeable speedup: Insert_Node and Get_Next_Match
  980. X * are now separated. (Boyer-Moore string matching)
  981. X * Version 2.2: Tunable static Huffman table for position information,
  982. X * this info may be given in the command string now.
  983. X * Version 2.2.3: Bug fixes, 10% freezing speedup.
  984. X * Version 2.3: Minor bug fixes (DOS filenames handling, backward
  985. X * compatibility feature improved, "bits" compression ratio display,
  986. X * preventive check for special files), speedups, more comments added.
  987. X * Version 2.3.1: Typedefs cleaned, utime bug on the m88k corrected
  988. X * (pa@verano.sba.ca.us, clewis@ferret.ocunix.on.ca (Chris Lewis)),
  989. X * "chain threshold" euristic used for speedup (in "greedy" mode) -
  990. X * a la ZIP (Jean-Loup Gailly). Max. hash bits reduced to 16.
  991. X * Version 2.3.2: Adaptation to TOS 1.04 (fifi@hiss.han.de), UTIMES
  992. X * handling (jik@athena.mit.edu).
  993. X * Version 2.3.3: More accurate adaptation for XENIX 286.
  994. X * Version 2.3.4: Minor bug fixes, HP-UX (longnames w/o BSD) handling,
  995. X * greedy_threshold added.
  996. X * Version 2.3.5: Noticeable speedup (on RISCs, don't know for sure
  997. X * about CISCs).
  998. X * Version 2.4: Yet another speedup, many general changes...
  999. X */
  1000. X
  1001. Xstatic char ident[] = "@(#) freeze.c 2.4.%d %s leo@ipmce.su\n";
  1002. X
  1003. Xint     exit_stat = 0;
  1004. X
  1005. Xvoid 
  1006. XUsage()
  1007. X{
  1008. X#ifdef DEBUG
  1009. X
  1010. X# ifdef DOS
  1011. X  fprintf(stderr, "Usage: freeze [-cdDfitvVg] [file | +type ...]\n");
  1012. X# else
  1013. X  fprintf(stderr, "Usage: freeze [-cdDfvVg] [file | +type ...]\n");
  1014. X# endif                /* DOS */
  1015. X
  1016. X#else
  1017. X
  1018. X# ifdef DOS
  1019. X  fprintf(stderr, "Usage: freeze [-cdfitvVg] [file | +type ...]\n");
  1020. X# else
  1021. X  fprintf(stderr, "Usage: freeze [-cdfvVg] [file | +type ...]\n");
  1022. X# endif                /* DOS */
  1023. X
  1024. X#endif                /* DEBUG */
  1025. X}
  1026. X
  1027. Xvoid    (*meltfunc) ();        /* To call something for melting */
  1028. X
  1029. Xshort   topipe = 0,        /* Write output on stdout, suppress messages */
  1030. X        precious = 1,        /* Don't unlink output file on interrupt */
  1031. X        quiet = 1,        /* Don't tell me about freezing */
  1032. X        do_melt = 0,        /* freeze means "freeze" */
  1033. X        greedy = 0,        /* GREEDY parsing */
  1034. X        force = 0;        /* "Force" flag */
  1035. X
  1036. Xchar    ofname[MAXNAMLEN];
  1037. Xstatic struct stat statbuf;    /* Used by 'main' and 'copystat' routines */
  1038. X
  1039. X#ifdef DOS
  1040. Xchar   *last_sep();        /* last slash, backslash, or colon */
  1041. Xchar    tail[3];        /* 2nd and 3rd chars of file extension */
  1042. X# ifdef TEXT_DEFAULT
  1043. Xshort   image = O_TEXT;
  1044. X# else
  1045. Xshort   image = O_BINARY;
  1046. X# endif
  1047. X#else
  1048. X#  define last_sep(s) strrchr((s), '/')    /* Unix always uses slashes */
  1049. X#  ifndef DEFFILE
  1050. X#   define DEFFILE "/usr/local/lib/freeze.cnf"
  1051. X#  endif
  1052. Xchar    deffile[] = DEFFILE;
  1053. X#endif
  1054. X
  1055. X#ifdef DEBUG
  1056. Xshort   debug = 0;
  1057. Xshort   verbose = 0;
  1058. Xchar   *pr_char();
  1059. X#endif                /* DEBUG */
  1060. X
  1061. X#if defined(GATHER_STAT) || defined(DEBUG)
  1062. Xlong    refers_out = 0, symbols_out = 0;
  1063. X#endif
  1064. X
  1065. X/* Do not sleep when freeze works :-) */
  1066. Xlong    indc_count, indc_threshold;
  1067. Xoff_t   file_length = 0;    /* initial length of file */
  1068. X
  1069. XRETSIGTYPE      (*bgnd_flag)();
  1070. X
  1071. Xvoid    writeerr(), copystat(), version(), tune_table();
  1072. X
  1073. X/*****************************************************************
  1074. X *
  1075. X * Usage: freeze [-cdfivV] [-t] [-g...] [-x...] [type] [file ...]
  1076. X * Inputs:
  1077. X *
  1078. X *      -c:         Write output on stdout, don't remove original.
  1079. X *
  1080. X *      -d:         If given, melting is done instead.
  1081. X *
  1082. X *      -g:         Use "greedy" parsing (1.5% worse, 40% faster).
  1083. X *                  (Means nothing when melting). May be repeated.
  1084. X *
  1085. X *      -f:         Forces output file to be generated, even if one already
  1086. X *                  exists, and even if no space is saved by freezeing.
  1087. X *                  If -f is not used, the user will be prompted if stdin is
  1088. X *                  a tty, otherwise, the output file will not be overwritten.
  1089. X *
  1090. X *      -i:         Image mode (defined only under MS-DOS).  Prevents
  1091. X *                  conversion between UNIX text representation (LF line
  1092. X *                  termination) in frozen form and MS-DOS text
  1093. X *                  representation (CR-LF line termination) in melted
  1094. X *                  form.  Useful with non-text files.  Default unless
  1095. X *                  TEXT_DEFAULT specified.
  1096. X *
  1097. X *      -b:         Binary mode.  Synonym for -i.  MS-DOS only.
  1098. X *
  1099. X *      -t:         Text mode (defined only under MS-DOS).  Treat file
  1100. X *                  as text (CR-LF and ^Z special) in melted form.  Default
  1101. X *                  if TEXT_DEFAULT specified.
  1102. X *
  1103. X *      -g:         Greedy parsing - increases speed, decreases
  1104. X *                  compression rate. Can be repeated.
  1105. X *
  1106. X *      -x:         "Anti- -g".
  1107. X *
  1108. X *      -v:         Write freezing statistics. -vv means "draw progress
  1109. X *                  indicator".
  1110. X *
  1111. X *      -V:         Write version and compilation options.
  1112. X *
  1113. X *      file ...:   Files to be frozen.  If none specified, stdin
  1114. X *            is used.
  1115. X * Outputs:
  1116. X *      file.F:     Frozen form of file with same mode, owner, and utimes
  1117. X *    or stdout   (if stdin used as input)
  1118. X *
  1119. X * Assumptions:
  1120. X *      When filenames are given, replaces with the frozen version
  1121. X *      (.F suffix) only if the file decreases in size.
  1122. X * Algorithm:
  1123. X *      Modified Lempel-Ziv-SS method (LZSS), adaptive Huffman coding
  1124. X *      for literal symbols and length info.
  1125. X *      Static Huffman coding for position info. (Is it optimal ?)
  1126. X *      Lower bits of position info are put in output
  1127. X *      file without any coding because of their random distribution.
  1128. X */
  1129. X
  1130. X/* From compress.c. Replace .Z --> .F etc */
  1131. X
  1132. Xvoid 
  1133. Xmain(argc, argv)
  1134. Xregister int argc;
  1135. Xchar  **argv;
  1136. X{
  1137. X  short   overwrite = 0;    /* Do not overwrite unless given -f flag */
  1138. X  char    tempname[100];
  1139. X  char  **filelist, **fileptr;
  1140. X  char   *cp;
  1141. X
  1142. X#ifdef TOS
  1143. X
  1144. X  char   *argv0 = "freeze.ttp";    /* argv[0] is not defined :-( */
  1145. X
  1146. X#endif
  1147. X
  1148. X#ifndef DOS
  1149. X  char   *malloc();
  1150. X#endif
  1151. X
  1152. X  extern RETSIGTYPE onintr();
  1153. X
  1154. X#ifdef DOS
  1155. X  char   *sufp;
  1156. X#else
  1157. X  extern RETSIGTYPE oops();
  1158. X#endif
  1159. X
  1160. X#ifndef DOS
  1161. X  if ((bgnd_flag = signal(SIGINT, SIG_IGN)) != SIG_IGN)
  1162. X#endif
  1163. X  {
  1164. X    (void) signal(SIGINT, onintr);
  1165. X#ifdef __TURBOC__
  1166. X
  1167. X#ifndef TOS
  1168. X    setcbrk(1);
  1169. X
  1170. X#endif
  1171. X#endif
  1172. X#ifndef DOS
  1173. X    (void) signal(SIGSEGV, oops);
  1174. X#endif
  1175. X  }
  1176. X  filelist = fileptr = (char **) (malloc(argc * sizeof(*argv)));
  1177. X  *filelist = NULL;
  1178. X
  1179. X  if ((cp = last_sep(argv[0])) != 0) {
  1180. X    cp++;
  1181. X  } else {
  1182. X
  1183. X#ifdef TOS
  1184. X
  1185. X    cp = argv0;
  1186. X
  1187. X#else
  1188. X    cp = argv[0];
  1189. X
  1190. X#endif
  1191. X  }
  1192. X
  1193. X#ifdef DOS
  1194. X/* use case-insensitive match: parent may not be command.com */
  1195. X#ifdef MSDOS
  1196. X  if (!stricmp(cp, "unfreeze.exe") || !stricmp(cp, "melt.exe")) {
  1197. X#else                /* TOS */
  1198. X  if (!stricmp(cp, "unfreeze.ttp") || !stricmp(cp, "melt.ttp")) {
  1199. X#endif
  1200. X#else
  1201. X  if (!strcmp(cp, "unfreeze") || !strcmp(cp, "melt")) {
  1202. X#endif
  1203. X
  1204. X    do_melt = 1;
  1205. X
  1206. X#ifdef DOS
  1207. X#ifdef MSDOS
  1208. X  } else if (stricmp(cp, "fcat.exe") == 0) {
  1209. X#else                /* TOS */
  1210. X  } else if (stricmp(cp, "fcat.ttp") == 0) {
  1211. X#endif
  1212. X#else
  1213. X  } else if (strcmp(cp, "fcat") == 0) {
  1214. X#endif
  1215. X
  1216. X    do_melt = 1;
  1217. X    topipe = 1;
  1218. X
  1219. X  } else {
  1220. X  /* Freezing */
  1221. X
  1222. X#ifndef DOS
  1223. X    (void) defopen(deffile);
  1224. X#else
  1225. X    cp = strrchr(cp, '.');
  1226. X    *++cp = 'C';
  1227. X    *++cp = 'N';
  1228. X    *++cp = 'F';
  1229. X    *++cp = '\0';
  1230. X
  1231. X#ifdef TOS
  1232. X    (void) defopen(argv0);
  1233. X#else
  1234. X    (void) defopen(argv[0]);
  1235. X#endif                /* TOS */
  1236. X#endif                /* DOS */
  1237. X
  1238. X  }
  1239. X#ifdef HAVE_SETLINEBUF
  1240. X /* 4.2BSD dependent - take it out if not */
  1241. X  setlinebuf(stderr);
  1242. X#endif                /* BSD */
  1243. X
  1244. X    /* Argument Processing
  1245. X     * All flags are optional.
  1246. X     * -D => debug
  1247. X     * -V => print Version; debug verbose
  1248. X     * -d => do_melt
  1249. X     * -v => unquiet
  1250. X     * -g => greedy
  1251. X     * -f => force overwrite of output file
  1252. X     * -c => cat all output to stdout
  1253. X     * if a string is left, must be an input filename.
  1254. X     */
  1255. X
  1256. X  for (argc--, argv++; argc > 0; argc--, argv++) {
  1257. X    if (**argv == '-' && (*argv)[1] != '-') {        /* A flag argument */
  1258. X      while (*++(*argv)) {    /* Process all flags in this arg */
  1259. X    switch (**argv) {
  1260. X#ifdef DEBUG
  1261. X    case 'D':
  1262. X      debug = 1;
  1263. X      break;
  1264. X    case 'V':
  1265. X      verbose = 1;
  1266. X#else
  1267. X    case 'V':
  1268. X      version();
  1269. X#endif                /* DEBUG */
  1270. X      break;
  1271. X#ifdef DOS
  1272. X    case 'i':
  1273. X    case 'b':
  1274. X      image = O_BINARY;    /* binary (aka image) mode */
  1275. X      break;
  1276. X
  1277. X    case 't':        /* text mode */
  1278. X      image = O_TEXT;
  1279. X      break;
  1280. X#endif
  1281. X    case 'v':
  1282. X      quiet--;
  1283. X      break;
  1284. X    case 'g':
  1285. X      greedy++;
  1286. X      break;
  1287. X    case 'x':
  1288. X      greedy--;
  1289. X      break;
  1290. X    case 'd':
  1291. X      do_melt = 1;
  1292. X      break;
  1293. X    case 'f':
  1294. X    case 'F':
  1295. X      overwrite = 1;
  1296. X      force = 1;
  1297. X      break;
  1298. X    case 'c':
  1299. X      topipe = 1;
  1300. X      break;
  1301. X    case 'q':
  1302. X      quiet = 1;
  1303. X      break;
  1304. X    default:
  1305. X      fprintf(stderr, "Unknown flag: '%c'; ", **argv);
  1306. X      Usage();
  1307. X      exit(1);
  1308. X    }
  1309. X      }
  1310. X    } else {            /* Input file name */
  1311. X      *fileptr++ = *argv;    /* Build input file list */
  1312. X      *fileptr = NULL;
  1313. X    }
  1314. X  }
  1315. X
  1316. X#ifdef DEBUG
  1317. X  if (verbose && !debug)
  1318. X    version();
  1319. X#endif
  1320. X
  1321. X  if (*filelist != NULL) {
  1322. X    for (fileptr = filelist; *fileptr; fileptr++) {
  1323. X      if ((**fileptr == '+' || **fileptr == '-') && do_melt == 0) {
  1324. X    tune_table(*fileptr + 1 + (**fileptr == '-'));
  1325. X    /* If a file type is given and no file names, a pipe
  1326. X     * operation is requested, but
  1327. X     * we will ignore an idiotic case of setting an resetting
  1328. X     * tables without any filename.
  1329. X     */
  1330. X    if (filelist[1] == NULL)
  1331. X      goto Pipe;
  1332. X    continue;
  1333. X      }
  1334. X      exit_stat = 0;
  1335. X      if (do_melt != 0) {    /* MELTING */
  1336. X
  1337. X#ifdef DOS
  1338. X      /* Check for .F or XF suffix; add one if necessary */
  1339. X    cp = *fileptr + strlen(*fileptr) - 2;
  1340. X    if ((*cp != '.' && *cp != 'X' && *cp != 'x') ||
  1341. X      (*(++cp) != 'F' && *cp != 'f')) {
  1342. X      (void) strcpy(tempname, *fileptr);
  1343. X      *tail = '\0';
  1344. X      if ((cp = strrchr(tempname, '.')) == NULL)
  1345. X        (void) strcat(tempname, ".F");
  1346. X      else if (*(++cp) == '\0')
  1347. X      /* pseudo-extension: FOOBAR. */
  1348. X        (void) strcat(tempname, "F");
  1349. X      else {
  1350. X      /* cp now points to file extension */
  1351. X        tail[0] = cp[1];    /* save two chars */
  1352. X        tail[1] = cp[2];
  1353. X        tail[2] = '\0';
  1354. X        *(++cp) = '\0';
  1355. X        (void) strcat(tempname, "XF");
  1356. X      }
  1357. X      *fileptr = tempname;
  1358. X    }
  1359. X#else
  1360. X      /* Check for .F suffix */
  1361. X    if (strcmp(*fileptr + strlen(*fileptr) - 2, ".F") != 0) {
  1362. X    /* No .F: tack one on */
  1363. X      (void) strcpy(tempname, *fileptr);
  1364. X      (void) strcat(tempname, ".F");
  1365. X      *fileptr = tempname;
  1366. X    }
  1367. X#endif                /* DOS */
  1368. X
  1369. X      /* Open input file for melting */
  1370. X
  1371. X    if (checkstat(*fileptr))
  1372. X      continue;
  1373. X
  1374. X#ifdef DOS
  1375. X    if ((freopen(*fileptr, "rb", stdin)) == NULL)
  1376. X#else
  1377. X    if ((freopen(*fileptr, "r", stdin)) == NULL)
  1378. X#endif
  1379. X    {
  1380. X      perror(*fileptr);
  1381. X      continue;
  1382. X    }
  1383. X      /* Check the magic number */
  1384. X    if (getchar() != MAGIC1)
  1385. X      goto reject;
  1386. X    switch (getchar()) {
  1387. X#ifdef COMPAT
  1388. X    case MAGIC2_1:
  1389. X      meltfunc = melt1;
  1390. X      break;
  1391. X#endif
  1392. X    case MAGIC2_2:
  1393. X      meltfunc = melt2;
  1394. X      break;
  1395. X    default:
  1396. X      reject:
  1397. X      fprintf(stderr, "%s: not in frozen format\n",
  1398. X        *fileptr);
  1399. X      continue;
  1400. X    }
  1401. X
  1402. X      /* Generate output filename */
  1403. X    precious = 1;
  1404. X    (void) strcpy(ofname, *fileptr);
  1405. X    ofname[strlen(*fileptr) - 2] = '\0';    /* Strip off .F */
  1406. X#ifdef DOS
  1407. X    (void) strcat(ofname, tail);
  1408. X#endif
  1409. X      } else {
  1410. X
  1411. X      /* FREEZING */
  1412. X#ifdef DOS
  1413. X    cp = *fileptr + strlen(*fileptr) - 2;
  1414. X    if ((*cp == '.' || *cp == 'X' || *cp == 'x') &&
  1415. X      (*(++cp) == 'F' || *cp == 'f')) {
  1416. X      fprintf(stderr, "%s: already has %s suffix -- no change\n",
  1417. X        *fileptr, --cp);    /* } */
  1418. X#else
  1419. X    if (strcmp(*fileptr + strlen(*fileptr) - 2, ".F") == 0) {
  1420. X      fprintf(stderr, "%s: already has .F suffix -- no change\n",
  1421. X        *fileptr);
  1422. X#endif                /* DOS */
  1423. X
  1424. X      continue;
  1425. X    }
  1426. X      /* Open input file for freezing */
  1427. X
  1428. X    if (checkstat(*fileptr))
  1429. X      continue;
  1430. X
  1431. X#ifdef DOS
  1432. X    if ((freopen(*fileptr, image == O_TEXT ? "rt" : "rb", stdin))
  1433. X      == NULL)
  1434. X#else
  1435. X    if ((freopen(*fileptr, "r", stdin)) == NULL)
  1436. X#endif
  1437. X    {
  1438. X      perror(*fileptr);
  1439. X      continue;
  1440. X    }
  1441. X      /* Generate output filename */
  1442. X    (void) strcpy(ofname, *fileptr);
  1443. X
  1444. X#ifndef HAVE_LONG_FILE_NAMES
  1445. X    if ((cp = last_sep(ofname)) != NULL)
  1446. X      cp++;
  1447. X    else
  1448. X      cp = ofname;
  1449. X# ifdef DOS
  1450. X    if (topipe == 0 && (sufp = strrchr(cp, '.')) != NULL &&
  1451. X      strlen(sufp) > 2)
  1452. X      fprintf(stderr,
  1453. X        "%s: part of filename extension will be replaced by XF\n",
  1454. X        cp);
  1455. X# else
  1456. X    if (topipe == 0 && strlen(cp) > 12) {
  1457. X      fprintf(stderr, "%s: filename too long to tack on .F\n", cp);
  1458. X      continue;
  1459. X    }
  1460. X# endif                /* DOS */
  1461. X#endif                /* LONGNAMES */
  1462. X
  1463. X#ifdef DOS
  1464. X      /* There is no difference between FOOBAR and FOOBAR. names */
  1465. X    if ((cp = strrchr(ofname, '.')) == NULL)
  1466. X      (void) strcat(ofname, ".F");
  1467. X    else if (cp[1] == '\0')
  1468. X    /* FOOBAR. case */
  1469. X      (void) strcat(ofname, "F");
  1470. X    else {
  1471. X      cp[2] = '\0';
  1472. X      (void) strcat(ofname, "XF");
  1473. X    }
  1474. X#else
  1475. X    (void) strcat(ofname, ".F");
  1476. X#endif                /* DOS */
  1477. X
  1478. X      }
  1479. X    /* Check for overwrite of existing file */
  1480. X      if (overwrite == 0 && topipe == 0) {
  1481. X    if (stat(ofname, &statbuf) == 0) {
  1482. X      char    response[2];
  1483. X      response[0] = 'n';
  1484. X      fprintf(stderr, "%s already exists;", ofname);
  1485. X#ifndef DOS
  1486. X      if (foreground()) {
  1487. X#endif
  1488. X        fprintf(stderr,
  1489. X          " do you wish to overwrite %s (y or n)? ", ofname);
  1490. X        (void) fflush(stderr);
  1491. X        (void) read(2, response, 2);
  1492. X        while (response[1] != '\n') {
  1493. X          if (read(2, response + 1, 1) < 0) {    /* Ack! */
  1494. X        perror("stderr");
  1495. X        break;
  1496. X          }
  1497. X        }
  1498. X#ifndef DOS
  1499. X      }
  1500. X#endif
  1501. X      if (response[0] != 'y') {
  1502. X        fprintf(stderr, "\tnot overwritten\n");
  1503. X        continue;
  1504. X      }
  1505. X    }
  1506. X      }
  1507. X      if (topipe == 0) {    /* Open output file */
  1508. X
  1509. X#ifdef DEBUG
  1510. X    if (do_melt == 0 || debug == 0) {
  1511. X#endif
  1512. X#ifdef DOS
  1513. X      if (freopen(ofname, do_melt && image == O_TEXT ? "wt" : "wb",
  1514. X          stdout) == NULL)
  1515. X#else
  1516. X      if (freopen(ofname, "w", stdout) == NULL)
  1517. X#endif
  1518. X      {
  1519. X        perror(ofname);
  1520. X        continue;
  1521. X      }
  1522. X#ifdef DEBUG
  1523. X    }
  1524. X#endif
  1525. X    precious = 0;
  1526. X    if (quiet != 1) {
  1527. X      fprintf(stderr, "%s:", *fileptr);
  1528. X      indc_count = 1024;
  1529. X    }
  1530. X      } else {            /* output is to stdout */
  1531. X#ifdef MSDOS
  1532. X      /* freeze output always binary; melt output is binary if image ==
  1533. X         O_BINARY */
  1534. X    if (do_melt == 0 || image == O_BINARY)
  1535. X      setmode(fileno(stdout), O_BINARY);
  1536. X#endif
  1537. X      }
  1538. X    /* Actually do the freezing/melting */
  1539. X      if (do_melt == 0)
  1540. X    freeze();
  1541. X#ifndef DEBUG
  1542. X      else
  1543. X    (*meltfunc) ();
  1544. X#else
  1545. X      else if (debug && verbose)
  1546. X    printcodes(meltfunc == (void (*) ()) melt2);
  1547. X      else
  1548. X    (*meltfunc) ();
  1549. X#endif                /* DEBUG */
  1550. X
  1551. X    /* check output status, and close to make sure data is written */
  1552. X      if (ferror(stdout) || (!topipe && fclose(stdout) < 0))
  1553. X    writeerr();
  1554. X
  1555. X      if (topipe == 0)
  1556. X    copystat(*fileptr);    /* Copy stats */
  1557. X      precious = 1;
  1558. X    }
  1559. X  } else {            /* Standard input */
  1560. XPipe:
  1561. X    if (fstat(fileno(stdin), &statbuf)) {
  1562. X      perror("stdin");
  1563. X      exit(1);
  1564. X    }
  1565. X    file_length = statbuf.st_mode & S_IFREG ? statbuf.st_size : 0;
  1566. X
  1567. X    indc_threshold = file_length / 100;
  1568. X    if (indc_threshold < 4096)
  1569. X      indc_threshold = 4096;
  1570. X    if (do_melt)
  1571. X      indc_threshold *= 3;
  1572. X
  1573. X    topipe = 1;
  1574. X    if (do_melt == 0) {
  1575. X#ifdef MSDOS
  1576. X    /* freeze output always binary */
  1577. X    /* freeze input controlled by -i -t -b switches */
  1578. X      setmode(fileno(stdout), O_BINARY);
  1579. X      setmode(fileno(stdin), image);
  1580. X#endif
  1581. X      freeze();
  1582. X      if (quiet != 1)
  1583. X    putc('\n', stderr);
  1584. X    } else {
  1585. X#ifdef MSDOS
  1586. X    /* melt input always binary */
  1587. X    /* melt output to stdout binary if so requested */
  1588. X      setmode(fileno(stdin), O_BINARY);
  1589. X      setmode(fileno(stdout), image);
  1590. X#endif
  1591. X    /* Check the magic number */
  1592. X      if (getchar() != MAGIC1)
  1593. X    goto badstdin;
  1594. X      switch (getchar()) {
  1595. X#ifdef COMPAT
  1596. X      case MAGIC2_1:
  1597. X    meltfunc = melt1;
  1598. X    break;
  1599. X#endif
  1600. X      case MAGIC2_2:
  1601. X    meltfunc = melt2;
  1602. X    break;
  1603. X      default:
  1604. X    badstdin:
  1605. X    fprintf(stderr, "stdin: not in frozen format\n");
  1606. X    exit(1);
  1607. X      }
  1608. X
  1609. X#ifndef DEBUG
  1610. X      (*meltfunc) ();
  1611. X#else
  1612. X      if (debug && verbose)
  1613. X    printcodes(meltfunc == (void (*) ()) melt2);
  1614. X      else
  1615. X    (*meltfunc) ();
  1616. X#endif                /* DEBUG */
  1617. X    }
  1618. X  }
  1619. X  exit(exit_stat);
  1620. X /* NOTREACHED */
  1621. X}
  1622. X
  1623. Xlong    in_count = 1;        /* length of input */
  1624. Xlong    bytes_out;        /* length of frozen output */
  1625. X
  1626. X/* Calculates and prints the compression ratio w/o floating point OPs */
  1627. X
  1628. Xvoid 
  1629. Xprratio(stream, was, is)
  1630. XFILE   *stream;
  1631. Xlong    was, is;
  1632. X{
  1633. X  register long q;        /* This works everywhere */
  1634. X
  1635. X  if (!is)
  1636. X    is++;
  1637. X
  1638. X  if (was > 214748L) {        /* 2147483647/10000 */
  1639. X    q = was / (is / 10000L);
  1640. X  } else {
  1641. X    q = 10000L * was / is;    /* Long calculations, though */
  1642. X  }
  1643. X  if (q < 0) {
  1644. X    putc('-', stream);
  1645. X    q = -q;
  1646. X  }
  1647. X  fprintf(stream, "%d.%02d%%", (int) (q / 100), (int) (q % 100));
  1648. X#ifdef GATHER_STAT
  1649. X  fprintf(stream, "(%ld / %ld)", was, is);
  1650. X#endif
  1651. X}
  1652. X/* Calculates and prints bits/byte compression ratio as above */
  1653. X
  1654. Xvoid 
  1655. Xprbits(stream, was, is)
  1656. XFILE   *stream;
  1657. Xlong    was, is;
  1658. X{
  1659. X  register long q;
  1660. X
  1661. X  if (!was)
  1662. X    was++;
  1663. X
  1664. X  if (is > 2684354L) {        /* 2147483647/800 */
  1665. X    q = is / (was / 800L);
  1666. X  } else {
  1667. X    q = 800L * is / was;
  1668. X  }
  1669. X  fprintf(stream, " (%d.%02d bits)", (int) (q / 100), (int) (q % 100));
  1670. X}
  1671. X/* There was an error when reading or writing files */
  1672. X
  1673. Xvoid 
  1674. Xwriteerr()
  1675. X{
  1676. X  if (!topipe) {
  1677. X    perror(ofname);
  1678. X    (void) unlink(ofname);
  1679. X  }
  1680. X  exit(1);
  1681. X}
  1682. X
  1683. Xvoid 
  1684. Xcopystat(ifname)
  1685. Xchar   *ifname;
  1686. X{
  1687. X#ifdef __TURBOC__
  1688. X  struct ftime utimbuf;
  1689. X#else
  1690. X#ifdef UTIMES
  1691. X  struct timeval timep[2];
  1692. X#else
  1693. X  struct utimbuf timep;
  1694. X#endif
  1695. X#endif
  1696. X
  1697. X  int     mode;
  1698. X
  1699. X#ifdef MSDOS
  1700. X  if (_osmajor < 3)
  1701. X    freopen("CON", "at", stdout);
  1702. X  else                /* MS-DOS 2.xx bug */
  1703. X# endif
  1704. X
  1705. X    (void) fclose(stdout);
  1706. X
  1707. X  if (exit_stat == 2 && (!force)) {    /* No freezing: remove file.F */
  1708. X
  1709. X    if (quiet != 1)
  1710. X      fprintf(stderr, "-- file unchanged\n");
  1711. X
  1712. X  } else {            /* ***** Successful Freezing ***** */
  1713. X
  1714. X    if (stat(ifname, &statbuf)) {    /* file disappeared ?! */
  1715. X      perror(ifname);
  1716. X      exit_stat = 1;
  1717. X      return;
  1718. X    }
  1719. X    exit_stat = 0;
  1720. X
  1721. X#ifdef TOS
  1722. X
  1723. X    Fattrib(ofname, 1, Fattrib(ifname, 0, 0));
  1724. X
  1725. X#else
  1726. X    mode = statbuf.st_mode & 07777;
  1727. X    if (chmod(ofname, mode))    /* Copy modes */
  1728. X      perror(ofname);
  1729. X#endif
  1730. X#ifndef DOS
  1731. X  /* Copy ownership */
  1732. X    (void) chown(ofname, (int) statbuf.st_uid, (int) statbuf.st_gid);
  1733. X#endif
  1734. X
  1735. X#ifdef __TURBOC__
  1736. X    getftime(fileno(stdin), &utimbuf);
  1737. X    freopen(ofname, "rb", stdout);
  1738. X    setftime(fileno(stdout), &utimbuf);
  1739. X    (void) fclose(stdout);
  1740. X#else
  1741. X#ifdef UTIMES
  1742. X    timep[0].tv_sec = statbuf.st_atime;
  1743. X    timep[1].tv_sec = statbuf.st_mtime;
  1744. X    timep[0].tv_usec = timep[1].tv_usec = 0;
  1745. X    (void) utimes(ofname, timep);
  1746. X#else
  1747. X    timep.actime = statbuf.st_atime;
  1748. X    timep.modtime = statbuf.st_mtime;
  1749. X
  1750. X#if defined(__m88k__)
  1751. X    timep.acusec = statbuf.st_ausec;    /* pa@verano */
  1752. X    timep.modusec = statbuf.st_musec;
  1753. X#endif                /* !m88k */
  1754. X
  1755. X  /* Update last accessed and modified times */
  1756. X    (void) utime(ofname, &timep);
  1757. X#endif                /* UTIMES */
  1758. X#endif                /* __TURBOC__ */
  1759. X    if (unlink(ifname))        /* Remove input file */
  1760. X      perror(ifname);
  1761. X    if (quiet != 1)
  1762. X      fprintf(stderr, " -- replaced with %s\n", ofname);
  1763. X    return;            /* Successful return */
  1764. X  }
  1765. X
  1766. X /* Unsuccessful return -- one of the tests failed */
  1767. X  if (unlink(ofname))
  1768. X    perror(ofname);
  1769. X}
  1770. X/* Checks status of a file, returns 0 if the file may be frozen,
  1771. X    or 1 otherwise; assigns this value to exit_stat
  1772. X*/
  1773. Xint 
  1774. Xcheckstat(ifname)
  1775. Xchar   *ifname;
  1776. X{
  1777. X  if (stat(ifname, &statbuf)) {
  1778. X    perror(ifname);
  1779. X    return exit_stat = 1;
  1780. X  }
  1781. X /* Do NOT try to freeze /dev/null or /dev/tty...   */
  1782. X /* but you may freeze or melt everything to stdout */
  1783. X
  1784. X#ifndef DOS
  1785. X  if (!topipe) {
  1786. X    if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
  1787. X      fprintf(stderr, "%s: ", ifname);
  1788. X      fprintf(stderr, " not a regular file -- unchanged\n");
  1789. X      return exit_stat = 1;
  1790. X
  1791. X    } else if (statbuf.st_nlink > 1) {
  1792. X      fprintf(stderr, "%s: ", ifname);
  1793. X      fprintf(stderr, " has %d other links -- unchanged\n",
  1794. X    statbuf.st_nlink - 1);
  1795. X      return exit_stat = 1;
  1796. X    }
  1797. X  }
  1798. X#endif                /* MSDOS */
  1799. X
  1800. X  file_length = statbuf.st_size;
  1801. X
  1802. X  indc_threshold = file_length / 100;
  1803. X  if (indc_threshold < 4096)
  1804. X    indc_threshold = 4096;
  1805. X  if (do_melt)
  1806. X    indc_threshold *= 3;
  1807. X
  1808. X  return exit_stat = 0;
  1809. X}
  1810. X#ifndef DOS
  1811. X/*
  1812. X * This routine returns 1 if we are running in the foreground and stderr
  1813. X * is a tty. (as in compress(1))
  1814. X */
  1815. Xint 
  1816. Xforeground()
  1817. X{
  1818. X  if (bgnd_flag != SIG_DFL)    /* background? */
  1819. X    return (0);
  1820. X  else {            /* foreground */
  1821. X    if (isatty(2)) {        /* and stderr is a tty */
  1822. X      return (1);
  1823. X    } else {
  1824. X      return (0);
  1825. X    }
  1826. X  }
  1827. X}
  1828. X#endif
  1829. X
  1830. X/* Exception handler (SIGINT) */
  1831. X
  1832. XRETSIGTYPE
  1833. Xonintr()
  1834. X{
  1835. X  if (!precious) {        /* topipe == 1 implies precious == 1 */
  1836. X    (void) fclose(stdout);
  1837. X    (void) unlink(ofname);
  1838. X  }
  1839. X  exit(1);
  1840. X}
  1841. X/* Exception handler (SIGSEGV) */
  1842. X
  1843. XRETSIGTYPE
  1844. Xoops()
  1845. X{                /* file is corrupt or internal error */
  1846. X  (void) fflush(stdout);
  1847. X  fprintf(stderr, "Segmentation violation occured (this shouldn't happen)\n");
  1848. X  exit(1);
  1849. X}
  1850. X/* Prints version and compilation options */
  1851. X
  1852. Xvoid 
  1853. Xversion()
  1854. X{
  1855. X  fprintf(stderr, ident, PATCHLEVEL, PATCHDATE);
  1856. X  fprintf(stderr, "LZSS 8192/256 + Huffman coding\nOptions: ");
  1857. X#ifdef COMPAT
  1858. X  fprintf(stderr, "compatible with vers. 1.0, ");
  1859. X#endif
  1860. X#ifdef DEBUG
  1861. X  fprintf(stderr, "DEBUG, ");
  1862. X#endif
  1863. X#if defined(INT_16_BITS) || defined(SMALL) || defined(TINY)
  1864. X  fprintf(stderr, "SMALL, ");
  1865. X#endif
  1866. X#ifdef ALLOW_MISALIGN
  1867. X  fprintf(stderr, "ALLOW_MISALIGN, ");
  1868. X#endif
  1869. X#ifdef GATHER_STAT
  1870. X  fprintf(stderr, "GATHER_STAT, ");
  1871. X#endif
  1872. X  fprintf(stderr, "HASH: %d bits\n", BITS);
  1873. X  fprintf(stderr, "Static Huffman table: %d %d %d %d %d %d %d %d\n",
  1874. X    Table2[1], Table2[2], Table2[3], Table2[4],
  1875. X    Table2[5], Table2[6], Table2[7], Table2[8]);
  1876. X#ifdef DOS
  1877. X  fprintf(stderr, "Default melted mode: %s\n",
  1878. X    image == O_BINARY ? "binary" : "text");
  1879. X#endif
  1880. X  exit(0);
  1881. X}
  1882. X/* Deals with static Huffman table parameters.
  1883. X    Input: command line option w/o leading `+' or `--'.
  1884. X    Output: fills the array `Table2' if OK, exit(1) otherwise.
  1885. X*/
  1886. X
  1887. Xvoid 
  1888. Xtune_table(type)
  1889. Xchar   *type;
  1890. X{
  1891. X  extern char *defread();
  1892. X  register char *s = defread(type), *t;
  1893. X  static int v[8];
  1894. X  int     i, is_list = 0;
  1895. X  if (!s) {
  1896. X  /* try to consider 'type' as a list of values: n1,n2, ... */
  1897. X    if (strrchr(type, ','))
  1898. X      is_list = 1;
  1899. X    else {
  1900. X      fprintf(stderr, "\"%s\" - no such file type\n", type);
  1901. X      exit(1);
  1902. X    }
  1903. X    if (sscanf(type, "%d,%d,%d,%d,%d,%d,%d,%d",
  1904. X    v, v + 1, v + 2, v + 3, v + 4, v + 5, v + 6, v + 7) != 8) {
  1905. X      fprintf(stderr,
  1906. X    "%s - a list of 8 numbers expected\n", type);
  1907. X      exit(1);
  1908. X    }
  1909. X  }
  1910. X
  1911. X  /* both space-separated and comma-separated lists are allowed */
  1912. X
  1913. X  if (!is_list && (!(t = strrchr(s, '=')) ||
  1914. X      sscanf(++t, "%d %d %d %d %d %d %d %d",
  1915. X    v, v + 1, v + 2, v + 3, v + 4, v + 5, v + 6, v + 7) != 8 &&
  1916. X      sscanf(t, "%d,%d,%d,%d,%d,%d,%d,%d",
  1917. X    v, v + 1, v + 2, v + 3, v + 4, v + 5, v + 6, v + 7) != 8)) {
  1918. X    fprintf(stderr,
  1919. X      "\"%s\" - invalid entry\n", type);
  1920. X    exit(1);
  1921. X  }
  1922. X  for (i = 0; i < 8; i++)
  1923. X    Table2[i + 1] = v[i];
  1924. X  if (quiet < 0) {
  1925. X    if (!is_list) {
  1926. X      t = s;
  1927. X    /* make full word */
  1928. X      while (*s != '=' && *s != ' ' && *s != '\t')
  1929. X    s++;
  1930. X      *s = '\0';
  1931. X    } else
  1932. X      t = "";
  1933. X    fprintf(stderr, "Using \"%s%s\" type\n", type, t);
  1934. X  }
  1935. X}
  1936. X#ifdef DOS
  1937. X
  1938. X/* MSDOS typically has ':' and '\\' separators, but some command
  1939. X  processors (and the int 21h function handler) support '/' too.
  1940. X  Find the last of these.
  1941. X*/
  1942. X
  1943. Xchar   *
  1944. Xlast_sep(s)
  1945. Xregister char *s;
  1946. X{
  1947. X  char   *p;
  1948. X  for (p = NULL; *s; s++)
  1949. X    if (*s == '/' || *s == '\\' || *s == ':')
  1950. X      p = s;
  1951. X  return (p);
  1952. X}
  1953. X#endif                /* DOS */
  1954. END_OF_FILE
  1955.   if test 23757 -ne `wc -c <'freeze.c'`; then
  1956.     echo shar: \"'freeze.c'\" unpacked with wrong size!
  1957.   fi
  1958.   # end of 'freeze.c'
  1959. fi
  1960. echo shar: End of archive 1 \(of 3\).
  1961. cp /dev/null ark1isdone
  1962. MISSING=""
  1963. for I in 1 2 3 ; do
  1964.     if test ! -f ark${I}isdone ; then
  1965.     MISSING="${MISSING} ${I}"
  1966.     fi
  1967. done
  1968. if test "${MISSING}" = "" ; then
  1969.     echo You have unpacked all 3 archives.
  1970.     rm -f ark[1-9]isdone
  1971. else
  1972.     echo You still must unpack the following archives:
  1973.     echo "        " ${MISSING}
  1974. fi
  1975. exit 0
  1976. exit 0 # Just in case...
  1977.