Path: utzoo!utgpu!cs.utexas.edu!wuarchive!zaphod.mps.ohio-state.edu!rpi!crdgw1!crdos1!davidsen From: davidsen@crdos1.crd.ge.COM (Wm E Davidsen Jr) Newsgroups: alt.sources Subject: lharc for unix (02/02) Message-ID: <3007@crdos1.crd.ge.COM> Date: 6 Dec 90 15:03:45 GMT Reply-To: davidsen@crdos1.crd.ge.com (bill davidsen) Distribution: alt Organization: GE Corp R&D Center Lines: 2306 #!/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 z oMIX 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@C / 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 F3"B X 2. G [bZ[W*sKXH* i)`5j\9qB X + 3. X 1qH`qE""LE5e$)B(^_^) X + 4. TufB Ng X A[JCut@C IG 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 ELZ tGNXg NgLA[JCu `.` p X $I5\5=B X 7. MS-DOS E V1.13c LA[JCut@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 ELTufB Ng 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 XG L 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. TufB Ng X A[JCut@C IG 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@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 ELTufB Ng 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 XG L V0.01: X 1. verbose/quiet/text_mode option M\> "E7B X 2. G [bZ[W*sKXH* i)`5j\9qB X 3. X 4. TufB Ng X 5. 3k/W X >Fv"\7B X 6. ; X 5D"\9qB X 7. MS-DOS E V1.13c LA[JCut@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 ELTufB Ng 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 X X/* Where is O_RDONLY ? (^_^) */ X#include X#ifndef O_RDONLY X#include X#endif X X#define direct old_direct X#include 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 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 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 X#include X#include X#include 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 X#include X#include 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@crdos1.crd.GE.COM -or- uunet!crdgw1!crdos1!davidsen) VMS is a text-only adventure game. If you win you can use unix.