lharc for unix (02/02)
Wm E Davidsen Jr
davidsen at crdos1.crd.ge.COM
Fri Dec 7 02:03:45 AEST 1990
#!/bin/sh
# this is part 2 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file lharc.c continued
#
CurArch=2
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
exit 1; fi
( read Scheck
if test "$Scheck" != $CurArch
then echo "Please unpack part $Scheck next!"
exit 1;
else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file lharc.c"
sed 's/^X//' << 'SHAR_EOF' >> lharc.c
X } else {
X fseek (fp, hdr.packed_size, SEEK_CUR);
X }
X }
X
X fclose (fp);
X
X return;
X}
X
X/*----------------------------------------------------------------------*/
X/* */
X/*----------------------------------------------------------------------*/
X
Xextern int encode_lzhuf ();
Xextern int encode_storerd_crc ();
X
Xappend_one (fp, nafp, hdr)
X FILE *fp, *nafp;
X LzHeader *hdr;
X{
X long header_pos, next_pos, org_pos, data_pos;
X long v_original_size, v_packed_size;
X
X reading_filename = hdr->name;
X writting_filename = temporary_name;
X
X org_pos = ftell (fp);
X header_pos = ftell (nafp);
X write_header (nafp, hdr); /* DUMMY */
X
X if (hdr->original_size == 0)
X {
X printf("%s - not frozen\n",hdr->name);
X return; /* previous write_header is not DUMMY. (^_^) */
X }
X
X data_pos = ftell (nafp);
X hdr->crc = encode_lzhuf (fp, nafp, hdr->original_size,
X &v_original_size, &v_packed_size, hdr->name);
X if (v_packed_size < v_original_size)
X {
X next_pos = ftell (nafp);
X }
X else
X { /* retry by stored method */
X fseek (fp, org_pos, SEEK_SET);
X fseek (nafp, data_pos, SEEK_SET);
X hdr->crc = encode_stored_crc (fp, nafp, hdr->original_size,
X &v_original_size, &v_packed_size);
X fflush (nafp);
X next_pos = ftell (nafp);
X ftruncate (fileno (nafp), next_pos);
X bcopy (LZHUFF0_METHOD, hdr->method, METHOD_TYPE_STRAGE);
X }
X hdr->original_size = v_original_size;
X hdr->packed_size = v_packed_size;
X fseek (nafp, header_pos, SEEK_SET);
X write_header (nafp, hdr);
X fseek (nafp, next_pos, SEEK_SET);
X}
X
Xwrite_tail (nafp)
X FILE *nafp;
X{
X putc (0x00, nafp);
X}
X
Xcopy_old_one (oafp, nafp, hdr)
X FILE *oafp, *nafp;
X LzHeader *hdr;
X{
X if (noexec)
X {
X fseek (oafp, (long)(hdr->header_size + 2) + hdr->packed_size, SEEK_CUR);
X }
X else
X {
X reading_filename = archive_name;
X writting_filename = temporary_name;
X copy_file (oafp, nafp, (long)(hdr->header_size + 2) + hdr->packed_size);
X }
X}
X
X
XFILE *append_it (name, oafp, nafp)
X char *name;
X FILE *oafp, *nafp;
X{
X LzHeader ahdr, hdr;
X FILE *fp;
X long old_header;
X int cmp;
X int filec;
X char **filev;
X int i;
X
X struct stat v_stat;
X boolean directory;
X
X /* check that any added name is not the same as the archive name */
X if (strcmp(name, archive_name) == 0) return oafp;
X
X if (!delete_from_archive)
X if (stat (name, &v_stat) < 0)
X {
X message ("Error:", name);
X return oafp;
X }
X
X directory = ((v_stat.st_mode & S_IFMT) == S_IFDIR);
X
X init_header (name, &v_stat, &hdr);
X
X if (!delete_from_archive && !directory && !noexec)
X fp = xfopen (name, RMODE);
X
X while (oafp)
X {
X old_header = ftell (oafp);
X if (!get_header (oafp, &ahdr))
X {
X fclose (oafp);
X oafp = NULL;
X break;
X }
X else
X {
X cmp = STRING_COMPARE (ahdr.name, hdr.name);
X if (cmp < 0)
X { /* SKIP */
X fseek (oafp, old_header, SEEK_SET);
X copy_old_one (oafp, nafp, &ahdr);
X }
X else if (cmp == 0)
X { /* REPLACE */
X fseek (oafp, ahdr.packed_size, SEEK_CUR);
X break;
X }
X else /* cmp > 0, INSERT */
X {
X fseek (oafp, old_header, SEEK_SET);
X break;
X }
X }
X }
X
X if (delete_from_archive)
X {
X if (noexec)
X fprintf (stderr, "DELETE %s\n", name);
X else
X printf ("%s - Deleted\n", name);
X }
X else
X {
X if ( !oafp || (cmp > 0) || !update_if_newer
X || (ahdr.unix_last_modified_stamp < hdr.unix_last_modified_stamp) )
X {
X if (noexec)
X fprintf (stderr, "APPEND %s\n", name);
X else
X#ifdef STRICT
X if ( !directory )
X#endif
X if ( !update_freshen || (cmp == 0) )
X append_one (fp, nafp, &hdr);
X }
X else
X { /* archive has old one */
X fseek (oafp, old_header, SEEK_SET);
X copy_old_one (oafp, nafp, &ahdr);
X }
X
X if (!directory)
X {
X if (!noexec)
X fclose (fp);
X }
X else
X { /* recurcive call */
X if (find_files (name, &filec, &filev))
X {
X for (i = 0; i < filec; i ++)
X oafp = append_it (filev[i], oafp, nafp);
X free_files (filec, filev);
X }
X return oafp;
X }
X }
X
X return oafp;
X}
X
X
Xremove_it (name)
X char *name;
X{
X struct stat v_stat;
X int i;
X char **filev;
X int filec;
X
X if (stat (name, &v_stat) < 0)
X {
X fprintf (stderr, "Cannot access \"%s\".\n", name);
X return;
X }
X
X if ((v_stat.st_mode & S_IFMT) == S_IFDIR)
X {
X if (!find_files (name, &filec, &filev))
X {
X fprintf (stderr, "Cannot open directory \"%s\".\n", name);
X return;
X }
X
X for (i = 0; i < filec; i ++)
X remove_it (filev[i]);
X
X free_files (filec, filev);
X
X if (noexec)
X printf ("REMOVE DIR %s\n", name);
X else if (rmdir (name) < 0)
X fprintf (stderr, "Cannot remove directory \"%s\".\n", name);
X else if (!quiet)
X printf ("%s - Removed\n", name);
X }
X else
X {
X if (noexec)
X printf ("REMOVE %s\n", name);
X else if (unlink (name) < 0)
X fprintf (stderr, "Cannot delete \"%s\".\n", name);
X else if (!quiet)
X printf ("%s - Removed\n", name);
X }
X}
X
X#ifdef FASTCOPY
X#define BUFFER_SIZE 16384
X
X#ifndef O_BINARY
X#define O_BINARY 0
X#endif
X
Xcopy_archive(src, dst)
Xchar *src;
Xchar *dst;
X{
X int ih, oh;
X unsigned chunk;
X char *buffer = (char *) rson;
X
X printf ("Copying temp to archive ... ");
X
X ih = open (src, O_RDONLY | O_BINARY);
X if ( ih == -1 )
X error(src);
X oh = open (dst, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
X if ( oh == -1 )
X error(dst);
X
X while ( (chunk = read(ih, buffer, BUFFER_SIZE)) > 0 )
X if ( write(oh, buffer, chunk) != chunk )
X error(dst);
X
X close (ih);
X close (oh);
X
X printf("\b\b\b\b \b\b\b\b.\n");
X}
X#endif
X
Xcmd_append ()
X{
X LzHeader ahdr;
X FILE *oafp, *nafp;
X char backup_archive_name [ FILENAME_LENGTH ];
X char new_archive_name_buffer [ FILENAME_LENGTH ];
X char *new_archive_name;
X int i;
X long old_header;
X struct stat v_stat;
X boolean old_archive_exist;
X
X if (cmd_filec == 0)
X return;
X
X make_tmp_name (archive_name, temporary_name);
X
X if ((oafp = fopen (archive_name, RMODE)) == NULL)
X if (expand_archive_name (expanded_archive_name, archive_name))
X {
X errno = 0;
X oafp = fopen (expanded_archive_name, RMODE);
X archive_name = expanded_archive_name;
X }
X
X old_archive_exist = (oafp) ? TRUE : FALSE;
X if (new_archive && oafp)
X {
X fclose (oafp);
X oafp = NULL;
X }
X
X if (oafp && archive_is_msdos_sfx1 (archive_name))
X {
X skip_msdos_sfx1_code (oafp);
X make_standard_archive_name (new_archive_name_buffer, archive_name);
X new_archive_name = new_archive_name_buffer;
X }
X else
X {
X new_archive_name = archive_name;
X }
X
X errno = 0;
X if (!noexec)
X {
X nafp = xfopen (temporary_name, WMODE);
X remove_temporary_at_error = TRUE;
X }
X
X for (i = 0; i < cmd_filec; i ++)
X oafp = append_it (cmd_filev[i], oafp, nafp);
X
X if (oafp)
X {
X old_header = ftell (oafp);
X while (get_header (oafp, &ahdr))
X {
X fseek (oafp, old_header, SEEK_SET);
X copy_old_one (oafp, nafp, &ahdr);
X old_header = ftell (oafp);
X }
X fclose (oafp);
X }
X
X if (!noexec)
X {
X write_tail (nafp);
X fclose (nafp);
X }
X
X make_backup_name (backup_archive_name, archive_name);
X
X if (!noexec && old_archive_exist)
X {
X unlink(backup_archive_name);
X
X if (rename (archive_name, backup_archive_name) < 0)
X error (archive_name);
X }
X
X if (!quiet && new_archive_name == new_archive_name_buffer)
X { /* warning at old archive is SFX */
X printf ("New Archive File is \"%s\"\n", new_archive_name);
X }
X
X if (!noexec && rename (temporary_name, new_archive_name) < 0)
X {
X if (stat (temporary_name, &v_stat) < 0)
X error (temporary_name);
X
X#ifdef FASTCOPY
X copy_archive(temporary_name, archive_name);
X#else
X oafp = xfopen (temporary_name, RMODE);
X nafp = xfopen (archive_name, WMODE);
X reading_filename = temporary_name;
X writting_filename = archive_name;
X copy_file (oafp, nafp, (long)v_stat.st_size);
X fclose (nafp);
X fclose (oafp);
X#endif
X
X unlink (temporary_name);
X }
X remove_temporary_at_error = FALSE;
X
X if (delete_after_append)
X {
X if (!quiet && !noexec)
X printf ("Erasing...\n");
X for (i = 0; i < cmd_filec; i ++)
X remove_it (cmd_filev[i]);
X }
X
X return;
X}
X
X/* XENIX kludges */
X#ifdef M_XENIX
Xrename(old, new)
Xchar *old, *new;
X{
X char cmd[256];
X
X sprintf(cmd, "/bin/mv %s %s", old, new);
X system(cmd);
X}
X#endif /* XENIX */
SHAR_EOF
echo "File lharc.c is complete"
chmod 0666 lharc.c || echo "restore of lharc.c fails"
echo "x - extracting lharc.doc (Text)"
sed 's/^X//' << 'SHAR_EOF' > lharc.doc &&
X------------------------------------------------------------------------------
X LHarc UNIX Release #3 V0.03 beta version
X Copyright (C) 1989 Yooichi.Tagawa
X
X cl mj
X zoMIX ID: y.tagawa
X------------------------------------------------------------------------------
X 1Lv
X
X UNIX EL LHarc p
X
X
X H :AAIfgH"),hAUNIX E LHarc (LHarc UNIX) p LHarc F
X *5\7B
X
X
Xyg"{z
X lharc {axevludmcp}[qnft] archive_file [files or directories...]
X
X R}hMAaxevludmcp L"Cj)PFBpwh5\7B(H*s B)
X IvVM qnft )gp"-BE`wh B\E7B
X (H* B\B3
X
X
XyA[JCut at C<z
X wh5=t at C<Lt at C*H/jNA.lzh pt at C<LckIt
X A5D5\7B5=*AD;Lj
X AIKhM h\9q*A ^pcATtBbNXF5D .lzh Ij7
X iL*G")F]\5")Fv"\7B
X .com (fQ .exe LTbtBNXLj
X 3j= SFX ().W
X 5\7B5)5ALHarc UNIX EMASFX `.Lt at Cp
X ME+\9qBSFX `.LA[JCut at CIN5DG A/
X =j
X
X
X
XyR}hjz
X a A[JCut at CIwh5=t at CpG A
X fBNg
X WD
X x \=M e A[JCut at CL)gwh5=t at C)7WDLt@
X Cp
X v \=M l A[JCut at C`I
X WDLt at CLjp\&5\7Bl Lj
X qpoM5\7B
X u wh5=t at C*A[JCut at C`I
X CfhV5")AA[JCut at C`I
X jN
X d A[JCut at CL)gwh5=t at Cp
X m A[JCut at CIwh5=t at Cp
X 5=t at Cp
X c A[JCut at CL`epj
X p
X p A[JCut at CL)gwh5=t at C)7WDL`e
X pW
X
XyIvVjz
X q bZ[WL}'p
X n @
X f
X t eLXg[hBMS-DOS EELeLXgt at CL |
X O
X dl*Omi)`5j\9qB)
X
X
Xy]
X MS-DOS LHarc V1.13c ( i"MA;jHO) E
X CF]
X Z[W*oi)`5j\9qB
X LHarc UNIX E
X h*
X
X
XyzzKhz
X H :LpEA
X
X 1.
X 2. zz`eIB"DMA
X a. zzL
X v
X
X gppS7i1FB
X b. LHarc IN7it A ?l*t/gjD
X jg`E+i>/
X t A ?l*t/gjD"i1Fp>&5=hLgppS
X 7i1FB
X c. oCi
X 3.
X 4. 1Lv
X X5H"B
X 5.
X mH"B
X 6. 1Lv
X p5D`)\mH"B1Lj
X H-ALHarc F<fADM"/H"B
X 7. $pI
X F_iB
X a. 1Lv
X b. $pL
X =j
X c. CXg[LhiF5Dgp7ij
X $1Fp
X \=A;LF+L9
X d. $ppt A ?lF5D
X $pRMA;LT|[gp
X
X
Xy
X LZHUF @L
X ;jp Nifty IP n5A\=ALArc L
X 1jgLvv)g LZHUF @yQAMS-DOS E LHarc p
X A
X N
X qI
X
X
X
XGL V0.03:
X * 1. quiet F text_mode LIvVpt/D]\5=B
X text_mode LIvVMAdl*Omi)`5j\9qLE
X 5DgAD->3"B
X 2. G [bZ[W*sKXH* i)`5j\9qB
X + 3.
X 1qH`qE""LE5e$)B(^_^)
X + 4. TufBNg
X A[JCut at CIG ALbhpFhL<-1F*E+\5=B
X * 5. 3k/W
X E7B LArc type 4 yQAtype 5 I`N 5\5=B
X * 6. MS-DOS ELZtGNXg NgLA[JCu`.` p
X $I5\5=B
X 7. MS-DOS E V1.13c LA[JCut at C* [MS-DOS] EH-A
X [generic] IHh\7*AMS-DOS ELLE =h(\*))gM
X [MS-DOS] FF/E+itH[}bgIHAD"iFv"\7B(^_^)
X 8. MS-DOS E V1.13c ELTufBNg
X W
X 9. {M VAX 11/785 UNIX 4.2BSD E
X (`FbNRj* i)`5j\9q)
X + 10. d66)Fv"\7*AMS-DOS <--> UNIX
X L]MoCi
X * 11. System-V VLZApeUI
X * 12. v F l R}hL\&`TLO
X * 13. lzhuf.c )g @mK6pMT+\5=B(Fv$)
X
XGL V0.02:
X 1. verbose/quiet/text_mode option M\>"E7B
X 2. G [bZ[W*sKXH* i)`5j\9qB
X * 3.
X 1qH`qE""LE5e$)B(^_^)
X * 4. TufBNg
X A[JCut at CIG ALbhpFhL<-1F*E+\5=B
X 5. 3k/W
X >Fv"\7B
X 6. ;
X 5D"\9qB
X 7. MS-DOS E V1.13c LA[JCut at C* [MS-DOS] EH-A
X [generic] IHh\7*AMS-DOS ELLE =h(\*))gM
X [MS-DOS] FF/E+itH[}bgIHAD"iFv"\7B(^_^)
X 8. MS-DOS E V1.13c ELTufBNg
X W
X 9. {M vax 11/785 UNIX 4.2BSD E
X (`FbNRj* i)`5j\9q)
X * 10. d66)Fv"\7*AMS-DOS <--> UNIX
X L]MoCi
X
XGL V0.01:
X 1. verbose/quiet/text_mode option M\>"E7B
X 2. G [bZ[W*sKXH* i)`5j\9qB
X 3.
X 4. TufBNg
X 5. 3k/W
X >Fv"\7B
X 6. ;
X 5D"\9qB
X 7. MS-DOS E V1.13c LA[JCut at C* [MS-DOS] EH-A
X [generic] IHh\7*AMS-DOS ELLE =h(\*))gM
X [MS-DOS] FF/E+itH[}bgIHAD"iFv"\7B(^_^)
X 8. MS-DOS E V1.13c ELTufBNg
X W
X 9. {M vax 11/785 UNIX 4.2BSD E
X (`FbNRj* i)`5j\9q)
X
X
X------------------------------------------------------------------------------
SHAR_EOF
chmod 0666 lharc.doc || echo "restore of lharc.doc fails"
echo "x - extracting lhdir.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > lhdir.c &&
X/*----------------------------------------------------------------------*/
X/* Directory access routine for LHarc UNIX */
X/* */
X/* Copyright(C) MCMLXXXIX Yooichi.Tagawa */
X/* */
X/* Emulate opendir(),readdir(),closedir() function for LHarc */
X/* */
X/* V0.00 Original 1988.05.31 Y.Tagawa */
X/* V0.03 Release #3 for LHarc UNIX 1988.07.02 Y.Tagawa */
X/*----------------------------------------------------------------------*/
X
X
X#include <sys/types.h>
X
X/* Where is O_RDONLY ? (^_^) */
X#include <sys/file.h>
X#ifndef O_RDONLY
X#include <fcntl.h>
X#endif
X
X#define direct old_direct
X#include <sys/dir.h>
X#undef direct
X
X#include "lhdir.h"
X
XDIR *opendir (name)
X char *name;
X{
X register DIR *dirp;
X register int fd;
X if ((fd = open (name, O_RDONLY)) >= 0)
X {
X if ((dirp = (DIR*)malloc (sizeof (DIR))) != (DIR*)0)
X {
X dirp->dd_fd = fd;
X dirp->dd_loc = 0;
X dirp->dd_size = 0;
X return dirp;
X }
X
X close (fd);
X }
X
X return (DIR*)0;
X}
X
Xstruct direct *readdir (dirp)
X register DIR *dirp;
X{
X static struct direct lhdir;
X register struct old_direct *dp;
X
X do {
X if (dirp->dd_loc >= dirp->dd_size)
X {
X dirp->dd_loc = 0;
X if ((dirp->dd_size = read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
X return (struct direct *)0;
X }
X
X dp = (struct old_direct *)(dirp->dd_buf + dirp->dd_loc);
X
X if (dirp->dd_loc + sizeof (struct old_direct) > dirp->dd_size)
X return (struct direct *)0;
X
X dirp->dd_loc += sizeof (struct old_direct);
X
X } while (dp->d_ino == 0) ;
X
X /* construct new format */
X lhdir.d_ino = dp->d_ino;
X strncpy (lhdir.d_name, dp->d_name, DIRSIZ);
X lhdir.d_name[DIRSIZ] = '\0';
X lhdir.d_namlen = strlen (lhdir.d_name);
X
X return &lhdir;
X}
X
Xclosedir (dirp)
X DIR *dirp;
X{
X close (dirp->dd_fd);
X free (dirp);
X}
X
SHAR_EOF
chmod 0600 lhdir.c || echo "restore of lhdir.c fails"
echo "x - extracting lhdir.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > lhdir.h &&
X/*----------------------------------------------------------------------*/
X/* Directory access routine for LHarc UNIX */
X/* */
X/* Copyright(C) MCMLXXXIX Yooichi.Tagawa */
X/* Emulate opendir(),readdir(),closedir() function for LHarc */
X/* */
X/* V0.00 Original 1988.05.31 Y.Tagawa */
X/* V0.03 Release #3 for LHarc UNIX 1988.07.02 Y.Tagawa */
X/*----------------------------------------------------------------------*/
X
X
X/* DIRBLKSIZ must be sizeof (SYSTEM struct direct) * N !!! */
X
X#ifndef DIRBLKSIZ
X#define DIRBLKSIZ 512
X#endif
X
Xstruct direct {
X int d_ino;
X int d_namlen;
X char d_name[256];
X};
X
Xtypedef struct {
X int dd_fd;
X int dd_loc;
X int dd_size;
X char dd_buf[DIRBLKSIZ];
X} DIR;
X
X
Xextern DIR *opendir ();
Xextern struct direct *readdir ();
Xextern closedir ();
X
SHAR_EOF
chmod 0600 lhdir.h || echo "restore of lhdir.h fails"
echo "x - extracting lhio.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > lhio.c &&
X/*----------------------------------------------------------------------*/
X/* File I/O module for LHarc UNIX */
X/* */
X/* Copyright(C) MCMLXXXIX Yooichi.Tagawa */
X/* */
X/* V0.00 Original 1989.06.25 Y.Tagawa */
X/* V0.03 Release #3 Beta Version 1989.07.02 Y.Tagawa */
X/* V0.03a Fix few bugs 1989.07.04 Y.Tagawa */
X/*----------------------------------------------------------------------*/
X
X#include <stdio.h>
X#include "lhio.h"
X
X#ifndef BUFFER_SIZE
X#define BUFFER_SIZE 16384
X#endif
X
X
Xextern int text_mode; /* in lharc.c */
XFILE *crc_infile, *crc_outfile; /* in lzhuf.c */
X
Xextern int rson[];
X
X/* These functions are NO-RETURN */
Xextern read_error ();
Xextern write_error ();
X
X
Xint crc_getc_cashe;
Xunsigned int crc_value;
Xunsigned int crc_table[0x100];
Xlong crc_size;
X
X
Xcrcsub (ptr, length)
X char *ptr;
X register int length;
X{
X register unsigned char *p;
X register unsigned int ctmp;
X
X if (length != 0)
X {
X ctmp = crc_value;
X p = (unsigned char*)ptr;
X for (; length; length --)
X {
X ctmp ^= (unsigned int)*p++;
X ctmp = (ctmp >> 8) ^ crc_table [ ctmp & 0xff ];
X }
X crc_value = ctmp;
X }
X}
X
X#ifndef __GNUC__
Xvoid putc_crc (c)
X int c;
X{
X CRC_CHAR (c);
X if (!text_mode || (c != 0x0d && c != 0x1a))
X {
X putc (c, crc_outfile);
X }
X}
X
Xint getc_crc ()
X{
X int c;
X
X if (crc_getc_cashe != EOF)
X {
X c = crc_getc_cashe;
X crc_getc_cashe = EOF;
X CRC_CHAR (c);
X crc_size++;
X }
X else if ((c = getc (crc_infile)) != EOF)
X {
X if (text_mode && c == 0x0a)
X {
X crc_getc_cashe = c;
X c = 0x0d;
X }
X CRC_CHAR (c);
X crc_size++;
X }
X return c;
X}
X#endif
X
X
X
Xinit_crc ()
X{
X static int inited = 0;
X register unsigned int *p = crc_table;
X register int i, j;
X register unsigned int x;
X
X if (!inited) {
X for (j = 0; j < 256; j ++) {
X x = j;
X for (i = 0; i < 8; i ++) {
X if ((x & 1) != 0) {
X x = (x >> 1) ^ 0xa001;
X } else {
X x = (x >> 1);
X }
X }
X *p ++ = x;
X }
X inited = 1;
X }
X crc_value = 0;
X crc_getc_cashe = EOF;
X crc_size = 0;
X}
X
X/*----------------------------------------------------------------------*/
X/* */
X/*----------------------------------------------------------------------*/
X
X/* if return value is -1, see errno */
Xcopy_binary_file (ifp, ofp, size, crc_flag)
X FILE *ifp, *ofp;
X long size;
X int crc_flag; /* as boolean value */
X{
X char *buffer = (char *) rson;
X int read_size;
X int n;
X
X /* safty */
X fflush (ofp);
X
X while (size > 0)
X {
X read_size = ((size < (long)BUFFER_SIZE) ? (int)size : BUFFER_SIZE);
X
X n = fread (buffer, sizeof (char), read_size, ifp);
X
X if (n == 0)
X read_error ();
X
X if (fwrite (buffer, sizeof (char), n, ofp) < n)
X write_error ();
X
X if (crc_flag)
X crcsub (buffer, n);
X
X size -= (long)n;
X }
X}
X
X/* read UNIX text file '0A' and write generic text file '0D0A' */
Xwrite_generic_text_file (ifp, ofp, size)
X FILE *ifp, *ofp;
X long size;
X{
X char buffer[BUFFER_SIZE];
X int read_size, write_count, n, m;
X register char *p, *p1, *e;
X
X /* safty */
X fflush (ofp);
X
X write_count = 0;
X
X while (size > 0)
X {
X read_size = ((size < BUFFER_SIZE) ? (int)size : BUFFER_SIZE);
X
X n = fread (buffer, sizeof (char), read_size, ifp);
X
X if (n == 0)
X read_error ();
X
X for (p1 = p = buffer, e = buffer + n; p < e; p++)
X {
X if (*p == '\n')
X {
X if ((m = p - p1) != 0)
X {
X if (fwrite (p1, sizeof (char), m, ofp) < m)
X write_error ();
X crcsub (p1, m);
X }
X putc (0x0d, ofp);
X if (feof (ofp))
X write_error ();
X CRC_CHAR (0x0d);
X p1 = p;
X write_count ++;
X }
X }
X if ((m = p - p1) != 0)
X {
X if (fwrite (p1, sizeof (char), m, ofp) < m)
X write_error ();
X crcsub (p1, m);
X }
X
X write_count += (long)n;
X size -= (long)n;
X }
X
X crc_size = write_count;
X}
X
X/* read generic text file '0D0A' and write UNIX text file '0A' */
Xread_generic_text_file (ifp, ofp, size, crc_flag)
X FILE *ifp, *ofp;
X long size;
X int crc_flag;
X{
X char buffer[BUFFER_SIZE];
X int read_size, write_size, n, m;
X register char *p, *p1, *e;
X
X /* safty */
X fflush (ofp);
X
X while (size > 0)
X {
X read_size = ((size < BUFFER_SIZE) ? (int)size : BUFFER_SIZE);
X
X n = fread (buffer, sizeof (char), read_size, ifp);
X
X if (n == 0)
X read_error ();
X
X crcsub (buffer, n);
X
X for (p1 = p = buffer, e = buffer + n; p < e; p ++)
X {
X if (*p == 0x0d)
X {
X if ((m = p - p1) != 0)
X {
X if (fwrite (p1, sizeof (char), m, ofp) < m)
X write_error ();
X }
X p1 = p+1;
X }
X }
X if ((m = p - p1) != 0)
X {
X if (fwrite (p1, sizeof (char), m, ofp) < m)
X write_error ();
X }
X
X size -= (long)n;
X }
X}
X
X
X/*----------------------------------------------------------------------*/
X/* */
X/*----------------------------------------------------------------------*/
X
X
Xcopy_file (ifp, ofp, size)
X FILE *ifp, *ofp;
X long size;
X{
X copy_binary_file (ifp, ofp, size, 0);
X}
X
X/*ARGSUSED*/
Xint decode_stored_crc (ifp, ofp, original_size, name)
X FILE *ifp, *ofp;
X long original_size;
X char *name;
X{
X init_crc ();
X
X if (text_mode)
X {
X read_generic_text_file (ifp, ofp, original_size, 1);
X return crc_value;
X }
X else
X {
X copy_binary_file (ifp, ofp, original_size, 1);
X return crc_value;
X }
X}
X
X/*ARGSUSED*/
Xint decode_stored_nocrc (ifp, ofp, original_size, name)
X FILE *ifp, *ofp;
X long original_size;
X char *name;
X{
X if (text_mode)
X {
X read_generic_text_file (ifp, ofp, original_size, 0);
X return 0; /* DUMMY */
X }
X else
X {
X copy_binary_file (ifp, ofp, original_size, 0);
X }
X return 0; /* DUMMY */
X}
X
Xint encode_stored_crc (ifp, ofp, size, original_size_var, write_size_var)
X FILE *ifp, *ofp;
X long size;
X long *original_size_var;
X long *write_size_var;
X{
X init_crc ();
X
X if (text_mode)
X {
X write_generic_text_file (ifp, ofp, size);
X *original_size_var = *write_size_var = crc_size;
X return crc_value;
X }
X else
X {
X copy_binary_file (ifp, ofp, size, 1);
X *original_size_var = size;
X *write_size_var = size;
X return crc_value;
X }
X}
SHAR_EOF
chmod 0666 lhio.c || echo "restore of lhio.c fails"
echo "x - extracting lhio.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > lhio.h &&
X/*----------------------------------------------------------------------*/
X/* File I/O module for LHarc UNIX */
X/* */
X/* Copyright(C) MCMLXXXIX Yooichi.Tagawa */
X/* */
X/* V0.00 Original 1989.06.25 Y.Tagawa */
X/* V0.03 Release #3 Beta Version 1989.07.02 Y.Tagawa */
X/*----------------------------------------------------------------------*/
X
Xextern int text_mode;
X
Xextern unsigned int crc_table[0x100];
Xextern unsigned int crc_value;
Xextern int crc_getc_cashe;
Xextern FILE *crc_infile, *crc_outfile;
Xextern long crc_size;
X
X
X#define CRC_CHAR(c) \
X{ register unsigned int ctmp = crc_value ^ c; \
X crc_value = (ctmp >> 8) ^ crc_table [ ctmp & 0xff ]; }
X
X
X
X#if defined (__GNUC__)
X/*#define inlnie*/
X
X/* DECODING */
X/* '0D0A' -> '0A' conversion and strip '1A' when text_mode */
Xstatic inline putc_crc (int c)
X{
X CRC_CHAR (c);
X if (!text_mode || (c != 0x0d && c != 0x1a))
X {
X putc (c, crc_outfile);
X }
X}
X
X/* ENCODING */
X/* '0A' -> '0D0A' conversion when text_mode */
Xstatic inline int getc_crc ()
X{
X int c;
X
X if (crc_getc_cashe != EOF)
X {
X c = crc_getc_cashe;
X crc_getc_cashe = EOF;
X CRC_CHAR (c);
X crc_size++;
X }
X else if ((c = getc (crc_infile)) != EOF)
X {
X if (text_mode && c == 0x0a)
X {
X crc_getc_cashe = c;
X c = 0x0d;
X }
X CRC_CHAR (c);
X crc_size++;
X }
X return c;
X}
X#endif
SHAR_EOF
chmod 0666 lhio.h || echo "restore of lhio.h fails"
echo "x - extracting lzhuf.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > lzhuf.c &&
X/*----------------------------------------------------------------------*/
X/* lzhuf.c : Encoding/Decoding module for LHarc */
X/* */
X/* LZSS Algorithm Haruhiko.Okumura */
X/* Adaptic Huffman Encoding 1989.05.27 Haruyasu.Yoshizaki */
X/* */
X/* */
X/* Modified for UNIX LHarc V0.01 1989.05.28 Y.Tagawa */
X/* Modified for UNIX LHarc V0.02 1989.05.29 Y.Tagawa */
X/* Modified for UNIX LHarc V0.03 1989.07.02 Y.Tagawa */
X/*----------------------------------------------------------------------*/
X
X/* Use ANSI sequences for using only one line per file but
X * indicator dots on next line */
X/* #define ANSI */
X
X#ifndef ANSI
X#define DOT '.'
X#define BALL 'o'
X#else
X#define DOT 249
X#define BALL 3
X#define CURSORUP "\033[A"
X#define ERASEEOL "\033[K"
X#endif
X
X#include <stdio.h>
X
X#ifndef SELFMAIN
X#include "lhio.h"
X#else
X#define EXIT_SUCCESS 0
X#define EXIT_FAILURE 1
X#endif
X
X
X
XFILE *infile, *outfile;
Xlong textsize, codesize;
X
X
X#define INDICATOR_THRESHOLD 4096L
X#define MAX_INDICATOR_COUNT 78
Xlong indicator_count;
Xlong indicator_threshold;
X
X#ifdef SELFMAIN
Xint quiet = 0;
X#else
Xextern int quiet;
Xextern int output_to_test;
X#endif
X
X
X#ifdef SELFMAIN
X#define SETUP_PUTC_CRC(fp) /* nothing */
X#define SETUP_GETC_CRC(fp) /* nothing */
X#define PUTC_CRC(c) putc((c),(outfile))
X#define GETC_CRC() getc(infile)
X#define END_PUTC_CRC()
X#define END_GETC_CRC()
X#else
X#define SETUP_PUTC_CRC(fp) crc_outfile = fp
X#define SETUP_GETC_CRC(fp) crc_infile = fp
X#define PUTC_CRC(c) putc_crc(c)
X#define GETC_CRC() getc_crc()
X#define END_PUTC_CRC()
X#define END_GETC_CRC()
X#endif
X
X
X
X
X#ifdef SELFMAIN
Xvoid Error (message)
X char *message;
X{
X printf("\n%s\n", message);
X exit(EXIT_FAILURE);
X}
X#endif
X
X/*----------------------------------------------------------------------*/
X/* */
X/* LZSS ENCODING */
X/* */
X/*----------------------------------------------------------------------*/
X
X#define N 4096 /* buffer size */
X#define F 60 /* pre-sence buffer size */
X#define THRESHOLD 2
X#define NIL N /* term of tree */
X
Xunsigned char text_buf[N + F - 1];
Xunsigned int match_position, match_length;
Xint lson[N + 1], rson[N + 1 + N], dad[N + 1];
Xunsigned char same[N + 1];
X
X
X/* Initialize Tree */
XInitTree ()
X{
X register int *p, *e;
X
X for (p = rson + N + 1, e = rson + N + N; p <= e; )
X *p++ = NIL;
X for (p = dad, e = dad + N; p < e; )
X *p++ = NIL;
X}
X
X
X/* Insert to node */
XInsertNode (r)
X register int r;
X{
X register int p;
X int cmp;
X register unsigned char *key;
X register unsigned int c;
X register unsigned int i, j;
X
X cmp = 1;
X key = &text_buf[r];
X i = key[1] ^ key[2];
X i ^= i >> 4;
X p = N + 1 + key[0] + ((i & 0x0f) << 8);
X rson[r] = lson[r] = NIL;
X match_length = 0;
X i = j = 1;
X for ( ; ; ) {
X if (cmp >= 0) {
X if (rson[p] != NIL) {
X p = rson[p];
X j = same[p];
X } else {
X rson[p] = r;
X dad[r] = p;
X same[r] = i;
X return;
X }
X } else {
X if (lson[p] != NIL) {
X p = lson[p];
X j = same[p];
X } else {
X lson[p] = r;
X dad[r] = p;
X same[r] = i;
X return;
X }
X }
X
X if (i > j) {
X i = j;
X cmp = key[i] - text_buf[p + i];
X } else
X if (i == j) {
X for (; i < F; i++)
X if ((cmp = key[i] - text_buf[p + i]) != 0)
X break;
X }
X
X if (i > THRESHOLD) {
X if (i > match_length) {
X match_position = ((r - p) & (N - 1)) - 1;
X if ((match_length = i) >= F)
X break;
X } else
X if (i == match_length) {
X if ((c = ((r - p) & (N - 1)) - 1) < match_position) {
X match_position = c;
X }
X }
X }
X }
X same[r] = same[p];
X dad[r] = dad[p];
X lson[r] = lson[p];
X rson[r] = rson[p];
X dad[lson[p]] = r;
X dad[rson[p]] = r;
X if (rson[dad[p]] == p)
X rson[dad[p]] = r;
X else
X lson[dad[p]] = r;
X dad[p] = NIL; /* remove p */
X}
X
X
Xlink (n, p, q)
X int n, p, q;
X{
X register unsigned char *s1, *s2, *s3;
X if (p >= NIL) {
X same[q] = 1;
X return;
X }
X s1 = text_buf + p + n;
X s2 = text_buf + q + n;
X s3 = text_buf + p + F;
X while (s1 < s3) {
X if (*s1++ != *s2++) {
X same[q] = s1 - 1 - text_buf - p;
X return;
X }
X }
X same[q] = F;
X}
X
X
Xlinknode (p, q, r)
X int p, q, r;
X{
X int cmp;
X
X if ((cmp = same[q] - same[r]) == 0) {
X link(same[q], p, r);
X } else if (cmp < 0) {
X same[r] = same[q];
X }
X}
X
XDeleteNode (p)
X register int p;
X{
X register int q;
X
X if (dad[p] == NIL)
X return; /* has no linked */
X if (rson[p] == NIL) {
X if ((q = lson[p]) != NIL)
X linknode(dad[p], p, q);
X } else
X if (lson[p] == NIL) {
X q = rson[p];
X linknode(dad[p], p, q);
X } else {
X q = lson[p];
X if (rson[q] != NIL) {
X do {
X q = rson[q];
X } while (rson[q] != NIL);
X if (lson[q] != NIL)
X linknode(dad[q], q, lson[q]);
X link(1, q, lson[p]);
X rson[dad[q]] = lson[q];
X dad[lson[q]] = dad[q];
X lson[q] = lson[p];
X dad[lson[p]] = q;
X }
X link(1, dad[p], q);
X link(1, q, rson[p]);
X rson[q] = rson[p];
X dad[rson[p]] = q;
X }
X dad[q] = dad[p];
X if (rson[dad[p]] == p)
X rson[dad[p]] = q;
X else
X lson[dad[p]] = q;
X dad[p] = NIL;
X}
X
X/*----------------------------------------------------------------------*/
X/* */
X/* HUFFMAN ENCODING */
X/* */
X/*----------------------------------------------------------------------*/
X
X#define N_CHAR (256 - THRESHOLD + F) /* {code : 0 .. N_CHAR-1} */
X#define T (N_CHAR * 2 - 1) /* size of table */
X#define R (T - 1) /* root position */
X#define MAX_FREQ 0x8000 /* tree update timing from frequency */
X
Xtypedef unsigned char uchar;
X
X
X
X/* TABLE OF ENCODE/DECODE for upper 6bits position information */
X
X/* for encode */
Xuchar p_len[64] = {
X 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
X 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06,
X 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
X 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
X 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
X 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
X 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
X 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
X};
X
Xuchar p_code[64] = {
X 0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68,
X 0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C,
X 0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC,
X 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE,
X 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE,
X 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE,
X 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
X 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
X};
X
X/* for decode */
Xuchar d_code[256] = {
X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
X 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
X 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
X 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
X 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
X 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
X 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
X 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
X 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
X 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
X 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
X 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
X 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
X 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
X 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
X 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
X 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
X 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
X 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
X 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
X 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
X 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
X 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
X 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
X 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
X 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
X};
X
Xuchar d_len[256] = {
X 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
X 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
X 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
X 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
X 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
X 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
X 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
X 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
X 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
X 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
X 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
X 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
X 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
X 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
X 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
X 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
X 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
X 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
X 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
X 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
X 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
X 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
X 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
X};
X
Xunsigned freq[T + 1]; /* frequency table */
X
Xint prnt[T + N_CHAR]; /* points to parent node */
X/* notes :
X prnt[T .. T + N_CHAR - 1] used by
X indicates leaf position that corresponding to code */
X
Xint son[T]; /* points to son node (son[i],son[i+]) */
X
Xunsigned getbuf = 0;
Xuchar getlen = 0;
X
X
X/* get one bit */
X/* returning in Bit 0 */
Xint GetBit ()
X{
X register unsigned int dx = getbuf;
X register unsigned int c;
X
X if (getlen <= 8)
X {
X c = getc (infile);
X if ((int)c < 0) c = 0;
X dx |= c << (8 - getlen);
X getlen += 8;
X }
X getbuf = dx << 1;
X getlen--;
X return (dx & 0x8000) ? 1 : 0;
X}
X
X/* get one byte */
X/* returning in Bit7...0 */
Xint GetByte ()
X{
X register unsigned int dx = getbuf;
X register unsigned c;
X
X if (getlen <= 8) {
X c = getc (infile);
X if ((int)c < 0) c = 0;
X dx |= c << (8 - getlen);
X getlen += 8;
X }
X getbuf = dx << 8;
X getlen -= 8;
X return (dx >> 8) & 0xff;
X}
X
X/* get N bit */
X/* returning in Bit(N-1)...Bit 0 */
Xint GetNBits (n)
X register unsigned int n;
X{
X register unsigned int dx = getbuf;
X register unsigned int c;
X static int mask[17] = {
X 0x0000,
X 0x0001, 0x0003, 0x0007, 0x000f,
X 0x001f, 0x003f, 0x007f, 0x00ff,
X 0x01ff, 0x03ff, 0x07ff, 0x0fff,
X 0x1fff, 0x3fff, 0x0fff, 0xffff };
X static int shift[17] = {
X 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
X
X if (getlen <= 8)
X {
X c = getc (infile);
X if ((int)c < 0) c = 0;
X dx |= c << (8 - getlen);
X getlen += 8;
X }
X getbuf = dx << n;
X getlen -= n;
X return (dx >> shift[n]) & mask[n];
X}
X
Xunsigned putbuf = 0;
Xuchar putlen = 0;
X
X/* output C bits */
XPutcode (l, c)
X register int l;
X register unsigned int c;
X{
X register len = putlen;
X register unsigned int b = putbuf;
X b |= c >> len;
X if ((len += l) >= 8) {
X putc (b >> 8, outfile);
X if ((len -= 8) >= 8) {
X putc (b, outfile);
X codesize += 2;
X len -= 8;
X b = c << (l - len);
X } else {
X b <<= 8;
X codesize++;
X }
X }
X putbuf = b;
X putlen = len;
X}
X
X
X/* Initialize tree */
X
XStartHuff ()
X{
X register int i, j;
X
X for (i = 0; i < N_CHAR; i++) {
X freq[i] = 1;
X son[i] = i + T;
X prnt[i + T] = i;
X }
X i = 0; j = N_CHAR;
X while (j <= R) {
X freq[j] = freq[i] + freq[i + 1];
X son[j] = i;
X prnt[i] = prnt[i + 1] = j;
X i += 2; j++;
X }
X freq[T] = 0xffff;
X prnt[R] = 0;
X putlen = getlen = 0;
X putbuf = getbuf = 0;
X}
X
X
X/* reconstruct tree */
Xreconst ()
X{
X register int i, j, k;
X register unsigned f;
X
X /* correct leaf node into of first half,
X and set these freqency to (freq+1)/2 */
X j = 0;
X for (i = 0; i < T; i++) {
X if (son[i] >= T) {
X freq[j] = (freq[i] + 1) / 2;
X son[j] = son[i];
X j++;
X }
X }
X /* build tree. Link sons first */
X for (i = 0, j = N_CHAR; j < T; i += 2, j++) {
X k = i + 1;
X f = freq[j] = freq[i] + freq[k];
X for (k = j - 1; f < freq[k]; k--);
X k++;
X { register unsigned *p, *e;
X for (p = &freq[j], e = &freq[k]; p > e; p--)
X p[0] = p[-1];
X freq[k] = f;
X }
X { register int *p, *e;
X for (p = &son[j], e = &son[k]; p > e; p--)
X p[0] = p[-1];
X son[k] = i;
X }
X }
X /* link parents */
X for (i = 0; i < T; i++) {
X if ((k = son[i]) >= T) {
X prnt[k] = i;
X } else {
X prnt[k] = prnt[k + 1] = i;
X }
X }
X}
X
X
X/* update given code's frequency, and update tree */
X
Xupdate (c)
X unsigned int c;
X{
X register unsigned *p;
X register int i, j, k, l;
X
X if (freq[R] == MAX_FREQ) {
X reconst();
X }
X c = prnt[c + T];
X do {
X k = ++freq[c];
X
X /* swap nodes when become wrong frequency order. */
X if (k > freq[l = c + 1]) {
X for (p = freq+l+1; k > *p++; ) ;
X l = p - freq - 2;
X freq[c] = p[-2];
X p[-2] = k;
X
X i = son[c];
X prnt[i] = l;
X if (i < T) prnt[i + 1] = l;
X
X j = son[l];
X son[l] = i;
X
X prnt[j] = c;
X if (j < T) prnt[j + 1] = c;
X son[c] = j;
X
X c = l;
X }
X } while ((c = prnt[c]) != 0); /* loop until reach to root */
X}
X
X/* unsigned code, len; */
X
XEncodeChar (c)
X unsigned c;
X{
X register int *p;
X register unsigned long i;
X register int j, k;
X
X i = 0;
X j = 0;
X p = prnt;
X k = p[c + T];
X
X /* trace links from leaf node to root */
X do {
X i >>= 1;
X
X /* if node index is odd, trace larger of sons */
X if (k & 1) i += 0x80000000;
X
X j++;
X } while ((k = p[k]) != R) ;
X if (j > 16) {
X Putcode(16, (unsigned int)(i >> 16));
X Putcode(j - 16, (unsigned int)i);
X } else {
X Putcode(j, (unsigned int)(i >> 16));
X }
X/* code = i; */
X/* len = j; */
X update(c);
X}
X
XEncodePosition (c)
X unsigned c;
X{
X unsigned i;
X
X /* output upper 6bit from table */
X i = c >> 6;
X Putcode((int)(p_len[i]), (unsigned int)(p_code[i]) << 8);
X
X /* output lower 6 bit */
X Putcode(6, (unsigned int)(c & 0x3f) << 10);
X}
X
XEncodeEnd ()
X{
X if (putlen) {
X putc(putbuf >> 8, outfile);
X codesize++;
X }
X}
X
Xint DecodeChar ()
X{
X register unsigned c;
X
X c = son[R];
X
X /* trace from root to leaf,
X got bit is 0 to small(son[]), 1 to large (son[]+1) son node */
X while (c < T) {
X c += GetBit();
X c = son[c];
X }
X c -= T;
X update(c);
X return c;
X}
X
Xint DecodePosition ()
X{
X unsigned i, j, c;
X
X /* decode upper 6bit from table */
X i = GetByte();
X c = (unsigned)d_code[i] << 6;
X j = d_len[i];
X
X /* get lower 6bit */
X j -= 2;
X return c | (((i << j) | GetNBits (j)) & 0x3f);
X}
X
X
XEncode ()
X{
X register int i, c, len, r, s, last_match_length;
X
X if (textsize == 0)
X return;
X
X textsize = 0;
X StartHuff();
X InitTree();
X s = 0;
X r = N - F;
X for (i = s; i < r; i++)
X text_buf[i] = ' ';
X for (len = 0; len < F && (c = GETC_CRC()) != EOF; len++)
X text_buf[r + len] = c;
X textsize = len;
X for (i = 1; i <= F; i++)
X InsertNode(r - i);
X InsertNode(r);
X do {
X if (match_length > len)
X match_length = len;
X if (match_length <= THRESHOLD) {
X match_length = 1;
X EncodeChar(text_buf[r]);
X } else {
X EncodeChar(255 - THRESHOLD + match_length);
X EncodePosition(match_position);
X }
X last_match_length = match_length;
X for (i = 0; i < last_match_length &&
X (c = GETC_CRC()) != EOF; i++) {
X DeleteNode(s);
X text_buf[s] = c;
X if (s < F - 1)
X text_buf[s + N] = c;
X s = (s + 1) & (N - 1);
X r = (r + 1) & (N - 1);
X InsertNode(r);
X }
X
X textsize += i;
X if ((textsize > indicator_count) && !quiet) {
X putchar (BALL);
X fflush (stdout);
X indicator_count += indicator_threshold;
X }
X while (i++ < last_match_length) {
X DeleteNode(s);
X s = (s + 1) & (N - 1);
X r = (r + 1) & (N - 1);
X if (--len) InsertNode(r);
X }
X } while (len > 0);
X EncodeEnd();
X END_GETC_CRC ();
X}
X
XDecode ()
X{
X register int i, j, k, r, c;
X register long count;
X
X#ifdef SELFMAIN
X if (textsize == 0)
X return;
X#endif
X StartHuff();
X for (i = 0; i < N - F; i++)
X text_buf[i] = ' ';
X r = N - F;
X for (count = 0; count < textsize; ) {
X c = DecodeChar();
X if (c < 256) {
X PUTC_CRC (c);
X text_buf[r++] = c;
X r &= (N - 1);
X count++;
X } else {
X i = (r - DecodePosition() - 1) & (N - 1);
X j = c - 255 + THRESHOLD;
X for (k = 0; k < j; k++) {
X c = text_buf[(i + k) & (N - 1)];
X PUTC_CRC (c);
X text_buf[r++] = c;
X r &= (N - 1);
X count++;
X }
X }
X
X if (!quiet && (count > indicator_count)) {
X putchar (BALL);
X fflush (stdout);
X indicator_count += indicator_threshold;
X }
X }
X END_PUTC_CRC ();
X}
X
X
X/*----------------------------------------------------------------------*/
X/* */
X/* LARC */
X/* */
X/*----------------------------------------------------------------------*/
X
X#define F_OLD 18 /* look ahead buffer size for LArc */
X
X/* intialize buffer for LArc type 5 */
XInitBuf ()
X{
X register unsigned char *p = text_buf;
X register int i, j;
X for (i = 0; i < 256; i ++)
X for (j = 0; j < 13; j ++)
X *p ++ = i;
X for (i = 0; i < 256; i ++)
X *p ++ = i;
X for (i = 0; i < 256; i ++)
X *p ++ = 255 - i;
X for (i = 0; i < 128; i ++)
X *p ++ = 0;
X for (i = 0; i < 128; i ++)
X *p ++ = 0x20;
X}
X
X/* Decode LArc type 5 */
XDecodeOld ()
X{
X register int si, di;
X register long count;
X int dl, dh, al, cx;
X if (textsize == 0)
X return;
X
X InitBuf ();
X di = N - F_OLD;
X dl = 0x80;
X
X for (count = 0; count < textsize; ) {
X dl = ((dl << 1) | (dl >> 7)) & 0xff;
X if (dl & 0x01)
X dh = getc (infile);
X al = getc (infile);
X if ((dh & dl) != 0) {
X PUTC_CRC (al);
X text_buf[di] = al;
X di = (di + 1) & (N - 1);
X count ++;
X } else {
X cx = getc (infile);
X si = (al & 0x00ff) | ((cx << 4) & 0x0f00);
X cx = (cx & 0x000f) + 3;
X count += cx;
X do {
X text_buf[di] = al = text_buf[si];
X PUTC_CRC (al);
X si = (si + 1) & (N - 1);
X di = (di + 1) & (N - 1);
X } while (--cx != 0) ;
X }
X
X if (!quiet && (count > indicator_count)) {
X putchar (BALL);
X fflush (stdout);
X indicator_count += indicator_threshold;
X }
X }
X END_PUTC_CRC ();
X}
X
X
X
X/*----------------------------------------------------------------------*/
X/* */
X/* Global Entries for Archiver Driver */
X/* */
X/*----------------------------------------------------------------------*/
X
X
Xstart_indicator (name, size, msg)
X char *name;
X long size;
X char *msg;
X{
X long i;
X int m;
X
X if (quiet)
X return;
X
X#ifdef ANSI
X m = MAX_INDICATOR_COUNT;
X#else
X m = MAX_INDICATOR_COUNT - strlen (name);
X#endif
X if (m < 0)
X m = 3; /* (^_^) */
X
X#ifdef ANSI
X printf ("\r%s - %s:\n", name, msg);
X#else
X printf ("\r%s - %s : ", name, msg);
X#endif
X
X indicator_threshold =
X ((size + (m * INDICATOR_THRESHOLD - 1)) /
X (m * INDICATOR_THRESHOLD) *
X INDICATOR_THRESHOLD);
X
X /* bug fix for files with size==0 28.03.1990 SB */
X if (indicator_threshold == 0)
X indicator_threshold = INDICATOR_THRESHOLD;
X /************************************************/
X
X i = ((size + (indicator_threshold - 1)) / indicator_threshold);
X while (i--)
X putchar (DOT);
X indicator_count = 0;
X#ifdef ANSI
X printf ("\r%s%s - %s:\n", CURSORUP, name, msg);
X#else
X printf ("\r%s - %s : ", name, msg);
X#endif
X fflush (stdout);
X}
X
Xfinish_indicator2 (name, msg, pcnt)
X char *name;
X char *msg;
X int pcnt;
X{
X if (quiet)
X return;
X
X if (pcnt > 100) pcnt = 100; /* (^_^) */
X#ifdef ANSI
X printf ("\r%s%s - %s(%d%%)\n%s", CURSORUP, name, msg, pcnt, ERASEEOL);
X#else
X printf ("\r%s - %s(%d%%)\n", name, msg, pcnt);
X#endif
X fflush (stdout);
X}
X
Xfinish_indicator (name, msg)
X char *name;
X char *msg;
X{
X if (quiet)
X return;
X
X#ifdef ANSI
X printf ("\r%s%s - %s\n%s", CURSORUP, name, msg, ERASEEOL);
X#else
X printf ("\r%s - %s\n", name, msg);
X#endif
X fflush (stdout);
X}
X
X
X#ifndef SELFMAIN
Xint encode_lzhuf (infp, outfp, size, original_size_var, packed_size_var, name)
X FILE *infp;
X FILE *outfp;
X long size;
X long *original_size_var;
X long *packed_size_var;
X char *name;
X{
X infile = infp;
X outfile = outfp;
X SETUP_GETC_CRC(infp);
X textsize = size;
X codesize = 0;
X init_crc ();
X start_indicator (name, size, "Freezing");
X Encode ();
X finish_indicator2 (name, "Frozen",
X (int)((codesize * 100L) / crc_size));
X *packed_size_var = codesize;
X *original_size_var = crc_size;
X return crc_value;
X}
X
Xint decode_lzhuf (infp, outfp, original_size, name)
X FILE *infp;
X FILE *outfp;
X long original_size;
X char *name;
X{
X infile = infp;
X outfile = outfp;
X SETUP_PUTC_CRC(outfp);
X textsize = original_size;
X init_crc ();
X start_indicator (name, original_size,
X (output_to_test ? "Testing" : "Melting"));
X Decode ();
X finish_indicator (name, (output_to_test ? "Tested " : "Melted "));
X return crc_value;
X}
X
X
Xint decode_larc (infp, outfp, original_size, name)
X FILE *infp, *outfp;
X long original_size;
X char *name;
X{
X infile = infp;
X outfile = outfp;
X SETUP_PUTC_CRC(outfp);
X textsize = original_size;
X init_crc ();
X start_indicator (name, original_size,
X (output_to_test ? "Testing" : "Melting"));
X DecodeOld ();
X finish_indicator (name, (output_to_test ? "Tested " : "Melted "));
X return crc_value;
X}
X#endif
X
X#ifdef SELFMAIN
Xint main (argc, argv)
X int argc;
X char *argv[];
X{
X char *s;
X int i;
X
X indicator_count = 0;
X indicator_threshold = 1024;
X textsize = codesize = 0;
X if (argc != 4) {
X printf ("\
Xusage: lzhuf e in_file out_file (packing)\n\
X lzhuf d in_file out_file (unpacking)\n");
X return EXIT_FAILURE;
X }
X if ((s = argv[1], ((*s != 'e') && (*s != 'd')) || s[1] != '\0') ||
X (s = argv[2], (infile = fopen(s, "rb")) == NULL) ||
X (s = argv[3], (outfile = fopen(s, "wb")) == NULL)) {
X printf("??? %s\n", s);
X return EXIT_FAILURE;
X }
X if (argv[1][0] == 'e') {
X /* Get original text size and output it */
X fseek(infile, 0L, 2);
X textsize = ftell(infile);
X rewind (infile);
X if (fwrite(&textsize, sizeof textsize, 1, outfile) < 1)
X Error("cannot write");
X
X start_indicator (argv[2], textsize, "Freezing");
X Encode();
X finith_indicator2 (argv[2], "Frozen",
X (int)((codesize * 100L) / textsize));
X
X printf("input : %ld bytes\n", textsize);
X printf("output: %ld bytes\n", codesize);
X } else {
X /* Read original text size */
X if (fread(&textsize, sizeof textsize, 1, infile) < 1)
X Error("cannot read");
X
X start_indicator (argv[2], textsize, "Melting");
X Decode();
X finish_indicator (argv[2], "Melted ");
X }
X fclose(infile);
X fclose(outfile);
X return EXIT_SUCCESS;
X}
X#endif
X
X
X/* These lines are used in GNU-Emacs */
X/* Local Variables: */
X/* comment-column:40 */
X/* tab-width:8 */
X/* c-indent-level:8 */
X/* c-continued-statement-offset:8 */
X/* c-argdecl-indent:8 */
X/* End: */
SHAR_EOF
chmod 0666 lzhuf.c || echo "restore of lzhuf.c fails"
echo "x - extracting mktemp.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > mktemp.c &&
X/* MKTEMP.C using TMP environment variable */
X
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X#include <io.h>
X
Xvoid Mktemp(char *file)
X{
X char fname[32], *tmp;
X
X tmp = getenv("TMP");
X
X if ( tmp != NULL )
X {
X strcpy(fname, file);
X strcpy(file, tmp);
X
X if ( file[strlen(file) - 1] != '\\' )
X strcat(file, "\\");
X
X strcat(file, fname);
X }
X
X mktemp(file);
X}
X
X/* End of MKTEMP.C */
SHAR_EOF
chmod 0666 mktemp.c || echo "restore of mktemp.c fails"
echo "x - extracting pipes.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > pipes.c &&
X/* a simulation for the Unix popen() and pclose() calls on MS-DOS */
X/* only one pipe can be open at a time */
X
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X
Xstatic char pipename[128], command[128];
Xstatic int wrpipe;
X
Xextern void Mktemp(char *);
X
XFILE *popen(char *cmd, char *flags)
X{
X wrpipe = (strchr(flags, 'w') != NULL);
X
X if ( wrpipe )
X {
X strcpy(command, cmd);
X strcpy(pipename, "~WXXXXXX");
X Mktemp(pipename);
X return fopen(pipename, flags); /* ordinary file */
X }
X else
X {
X strcpy(pipename, "~RXXXXXX");
X Mktemp(pipename);
X strcpy(command, cmd);
X strcat(command, ">");
X strcat(command, pipename);
X system(command);
X return fopen(pipename, flags); /* ordinary file */
X }
X}
X
Xint pclose(FILE *pipe)
X{
X int rc;
X
X if ( fclose(pipe) == EOF )
X return EOF;
X
X if ( wrpipe )
X {
X if ( command[strlen(command) - 1] == '!' )
X command[strlen(command) - 1] = 0;
X else
X strcat(command, "<");
X
X strcat(command, pipename);
X rc = system(command);
X unlink(pipename);
X return rc;
X }
X else
X {
X unlink(pipename);
X return 0;
X }
X}
SHAR_EOF
chmod 0666 pipes.c || echo "restore of pipes.c fails"
rm -f s2_seq_.tmp
echo "You have unpacked the last part"
exit 0
--
bill davidsen (davidsen at crdos1.crd.GE.COM -or- uunet!crdgw1!crdos1!davidsen)
VMS is a text-only adventure game. If you win you can use unix.
More information about the Alt.sources
mailing list