home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-04-03 | 102.4 KB | 4,506 lines |
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: clharc.cs clharc.def dir_dos.c dir_os2.c lharc.c lhdir.h
- # lhio.c lhio.h lzhuf.c makefile mktemp.c pipes.c readme rename.c
- # Wrapped by glenn@stsim on Tue Mar 27 19:12:19 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f clharc.cs -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"clharc.cs\"
- else
- echo shar: Extracting \"clharc.cs\" \(117 characters\)
- sed "s/^X//" >clharc.cs <<'END_OF_clharc.cs'
- X(-W1 lharc.c lhio.c dir_os2.c mktemp.c pipes.c)
- X(-W1 -Ox lzhuf.c)
- Xsetargv.obj
- Xclharc.def
- Xclharc.exe
- X-as -lb -s0x2000
- END_OF_clharc.cs
- if test 117 -ne `wc -c <clharc.cs`; then
- echo shar: \"clharc.cs\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f clharc.def -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"clharc.def\"
- else
- echo shar: Extracting \"clharc.def\" \(74 characters\)
- sed "s/^X//" >clharc.def <<'END_OF_clharc.def'
- XNAME CLHARC WINDOWCOMPAT
- XDESCRIPTION 'C-LHarc 1.00 - for MS-DOS and OS/2'
- END_OF_clharc.def
- if test 74 -ne `wc -c <clharc.def`; then
- echo shar: \"clharc.def\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f dir_dos.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"dir_dos.c\"
- else
- echo shar: Extracting \"dir_dos.c\" \(3587 characters\)
- sed "s/^X//" >dir_dos.c <<'END_OF_dir_dos.c'
- X/*
- X * @(#)dir.c 1.4 87/11/06 Public Domain.
- X *
- X * A public domain implementation of BSD directory routines for
- X * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield),
- X * August 1897
- X * Modified to use modern MS C library functions by Kai Uwe Rommel
- X * December 1989
- X */
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/dir.h>
- X#include <malloc.h>
- X#include <string.h>
- X
- X#include <dos.h>
- X
- X#ifndef NULL
- X# define NULL 0
- X#endif /* NULL */
- X
- X#ifndef MAXPATHLEN
- X# define MAXPATHLEN 255
- X#endif /* MAXPATHLEN */
- X
- X/* attribute stuff */
- X#define A_RONLY 0x01
- X#define A_HIDDEN 0x02
- X#define A_SYSTEM 0x04
- X#define A_LABEL 0x08
- X#define A_DIR 0x10
- X#define A_ARCHIVE 0x20
- X
- X
- X#define Newisnull(a, t) ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
- X
- X#define ATTRIBUTES (A_DIR)
- X/* #define ATTRIBUTES (A_DIR | A_HIDDEN | A_SYSTEM) */
- X/* #define ATTRIBUTES (A_RONLY | A_SYSTEM | A_DIR) */
- X
- Xstatic char *getdirent(char *);
- Xstatic void free_dircontents(struct _dircontents *);
- X
- Xstatic struct find_t find;
- X
- X
- XDIR *
- Xopendir(name)
- X char *name;
- X{
- X struct stat statb;
- X DIR *dirp;
- X char c;
- X char *s;
- X struct _dircontents *dp;
- X char nbuf[MAXPATHLEN + 1];
- X
- X if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
- X return (DIR *) NULL;
- X if (Newisnull(dirp, DIR))
- X return (DIR *) NULL;
- X if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
- X (void) strcat(strcpy(nbuf, name), "\\*.*");
- X else
- X (void) strcat(strcpy(nbuf, name), "*.*");
- X dirp->dd_loc = 0;
- X dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
- X
- X if ((s = getdirent(nbuf)) == (char *) NULL)
- X return dirp;
- X do {
- X if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
- X malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
- X {
- X if (dp)
- X free((char *) dp);
- X free_dircontents(dirp->dd_contents);
- X return (DIR *) NULL;
- X }
- X if (dirp->dd_contents)
- X dirp->dd_cp = dirp->dd_cp->_d_next = dp;
- X else
- X dirp->dd_contents = dirp->dd_cp = dp;
- X (void) strcpy(dp->_d_entry, s);
- X dp->_d_next = (struct _dircontents *) NULL;
- X } while ((s = getdirent((char *) NULL)) != (char *) NULL);
- X
- X dirp->dd_cp = dirp->dd_contents;
- X
- X return dirp;
- X}
- X
- Xvoid
- Xclosedir(dirp)
- X DIR *dirp;
- X{
- X free_dircontents(dirp->dd_contents);
- X free((char *) dirp);
- X}
- X
- Xstruct direct *
- Xreaddir(dirp)
- X DIR *dirp;
- X{
- X static struct direct dp;
- X
- X if (dirp->dd_cp == (struct _dircontents *) NULL)
- X return (struct direct *) NULL;
- X dp.d_namlen = dp.d_reclen =
- X strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
- X strlwr(dp.d_name); /* JF */
- X dp.d_ino = 0;
- X dirp->dd_cp = dirp->dd_cp->_d_next;
- X dirp->dd_loc++;
- X
- X return &dp;
- X}
- X
- Xvoid
- Xseekdir(dirp, off)
- X DIR *dirp;
- X long off;
- X{
- X long i = off;
- X struct _dircontents *dp;
- X
- X if (off < 0)
- X return;
- X for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
- X ;
- X dirp->dd_loc = off - (i + 1);
- X dirp->dd_cp = dp;
- X}
- X
- Xlong
- Xtelldir(dirp)
- X DIR *dirp;
- X{
- X return dirp->dd_loc;
- X}
- X
- Xstatic void
- Xfree_dircontents(dp)
- X struct _dircontents *dp;
- X{
- X struct _dircontents *odp;
- X
- X while (dp) {
- X if (dp->_d_entry)
- X free(dp->_d_entry);
- X dp = (odp = dp)->_d_next;
- X free((char *) odp);
- X }
- X}
- X
- Xstatic char *getdirent(dir)
- Xchar *dir;
- X{
- X int done;
- X
- X if (dir != (char *) NULL)
- X done = _dos_findfirst(dir, ATTRIBUTES, &find);
- X else /* get next entry */
- X done = _dos_findnext(&find);
- X
- X if (done==0)
- X return find.name;
- X else
- X return (char *) NULL;
- X}
- X
- X
- Xsetfilemode(char *name, unsigned attr)
- X{
- X _dos_setfileattr(name, attr);
- X}
- X
- Xgetfilemode(char *name, unsigned *attr)
- X{
- X _dos_getfileattr(name, attr);
- X}
- END_OF_dir_dos.c
- if test 3587 -ne `wc -c <dir_dos.c`; then
- echo shar: \"dir_dos.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f dir_os2.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"dir_os2.c\"
- else
- echo shar: Extracting \"dir_os2.c\" \(3837 characters\)
- sed "s/^X//" >dir_os2.c <<'END_OF_dir_os2.c'
- X/*
- X * @(#)dir.c 1.4 87/11/06 Public Domain.
- X *
- X * A public domain implementation of BSD directory routines for
- X * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield),
- X * August 1897
- X * Ported to OS/2 by Kai Uwe Rommel
- X * December 1989
- X */
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/dir.h>
- X#include <malloc.h>
- X#include <string.h>
- X
- X#define INCL_NOPM
- X#include <os2.h>
- X
- X#ifndef NULL
- X# define NULL 0
- X#endif /* NULL */
- X
- X#ifndef MAXPATHLEN
- X# define MAXPATHLEN 255
- X#endif /* MAXPATHLEN */
- X
- X/* attribute stuff */
- X#define A_RONLY 0x01
- X#define A_HIDDEN 0x02
- X#define A_SYSTEM 0x04
- X#define A_LABEL 0x08
- X#define A_DIR 0x10
- X#define A_ARCHIVE 0x20
- X
- X
- X#define Newisnull(a, t) ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
- X
- X#define ATTRIBUTES (A_DIR)
- X/* #define ATTRIBUTES (A_DIR | A_HIDDEN | A_SYSTEM) */
- X/* #define ATTRIBUTES (A_RONLY | A_SYSTEM | A_DIR) */
- X
- Xstatic char *getdirent(char *);
- Xstatic void free_dircontents(struct _dircontents *);
- X
- Xstatic HDIR hdir;
- Xstatic USHORT count;
- Xstatic FILEFINDBUF find;
- X
- X
- XDIR *
- Xopendir(name)
- X char *name;
- X{
- X struct stat statb;
- X DIR *dirp;
- X char c;
- X char *s;
- X struct _dircontents *dp;
- X char nbuf[MAXPATHLEN + 1];
- X
- X if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
- X return (DIR *) NULL;
- X if (Newisnull(dirp, DIR))
- X return (DIR *) NULL;
- X if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
- X (void) strcat(strcpy(nbuf, name), "\\*.*");
- X else
- X (void) strcat(strcpy(nbuf, name), "*.*");
- X dirp->dd_loc = 0;
- X dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
- X
- X if ((s = getdirent(nbuf)) == (char *) NULL)
- X return dirp;
- X do {
- X if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
- X malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
- X {
- X if (dp)
- X free((char *) dp);
- X free_dircontents(dirp->dd_contents);
- X return (DIR *) NULL;
- X }
- X if (dirp->dd_contents)
- X dirp->dd_cp = dirp->dd_cp->_d_next = dp;
- X else
- X dirp->dd_contents = dirp->dd_cp = dp;
- X (void) strcpy(dp->_d_entry, s);
- X dp->_d_next = (struct _dircontents *) NULL;
- X } while ((s = getdirent((char *) NULL)) != (char *) NULL);
- X
- X dirp->dd_cp = dirp->dd_contents;
- X
- X return dirp;
- X}
- X
- Xvoid
- Xclosedir(dirp)
- X DIR *dirp;
- X{
- X free_dircontents(dirp->dd_contents);
- X free((char *) dirp);
- X}
- X
- Xstruct direct *
- Xreaddir(dirp)
- X DIR *dirp;
- X{
- X static struct direct dp;
- X
- X if (dirp->dd_cp == (struct _dircontents *) NULL)
- X return (struct direct *) NULL;
- X dp.d_namlen = dp.d_reclen =
- X strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
- X strlwr(dp.d_name); /* JF */
- X dp.d_ino = 0;
- X dirp->dd_cp = dirp->dd_cp->_d_next;
- X dirp->dd_loc++;
- X
- X return &dp;
- X}
- X
- Xvoid
- Xseekdir(dirp, off)
- X DIR *dirp;
- X long off;
- X{
- X long i = off;
- X struct _dircontents *dp;
- X
- X if (off < 0)
- X return;
- X for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
- X ;
- X dirp->dd_loc = off - (i + 1);
- X dirp->dd_cp = dp;
- X}
- X
- Xlong
- Xtelldir(dirp)
- X DIR *dirp;
- X{
- X return dirp->dd_loc;
- X}
- X
- Xstatic void
- Xfree_dircontents(dp)
- X struct _dircontents *dp;
- X{
- X struct _dircontents *odp;
- X
- X while (dp) {
- X if (dp->_d_entry)
- X free(dp->_d_entry);
- X dp = (odp = dp)->_d_next;
- X free((char *) odp);
- X }
- X}
- X
- Xstatic char *getdirent(dir)
- Xchar *dir;
- X{
- X int done;
- X
- X if (dir != (char *) NULL)
- X { /* get first entry */
- X hdir = HDIR_CREATE;
- X count = 1;
- X done = DosFindFirst(dir, &hdir, ATTRIBUTES,
- X &find, sizeof(find), &count, 0L);
- X }
- X else /* get next entry */
- X done = DosFindNext(hdir, &find, sizeof(find), &count);
- X
- X if (done==0)
- X return find.achName;
- X else
- X {
- X DosFindClose(hdir);
- X return (char *) NULL;
- X }
- X}
- X
- X
- Xsetfilemode(char *name, unsigned attr)
- X{
- X DosSetFileMode(name, attr, 0L);
- X}
- X
- Xgetfilemode(char *name, unsigned *attr)
- X{
- X DosQFileMode(name, (PUSHORT) attr, 0L);
- X}
- END_OF_dir_os2.c
- if test 3837 -ne `wc -c <dir_os2.c`; then
- echo shar: \"dir_os2.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f lharc.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"lharc.c\"
- else
- echo shar: Extracting \"lharc.c\" \(49791 characters\)
- sed "s/^X//" >lharc.c <<'END_OF_lharc.c'
- X/*----------------------------------------------------------------------*/
- X/* LHarc Archiver Driver for UNIX */
- X/* */
- X/* Copyright(C) MCMLXXXIX Yooichi.Tagawa */
- X/* Thanks to H.Yoshizaki. (MS-DOS LHarc) */
- X/* */
- X/* V0.00 Original 1988.05.23 Y.Tagawa */
- X/* V0.01 Alpha Version (for 4.2BSD) 1989.05.28 Y.Tagawa */
- X/* V0.02 Alpha Version Rel.2 1989.05.29 Y.Tagawa */
- X/* V0.03 Release #3 Beta Version 1989.07.02 Y.Tagawa */
- X/* V0.03a Fix few bug 1989.07.03 Y.Tagawa */
- X/* V0.04 A lot of bugs fixed, strict mode 1990.01.13 Kai Uwe Rommel */
- X/* V1.00 f and t commands, v option added 1990.01.27 Kai Uwe Rommel */
- X/*----------------------------------------------------------------------*/
- X
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <signal.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <prototypes.h>
- X
- X#ifdef PROF
- X#include <profile.h>
- X#endif
- X
- X#define STRICT
- X#define FASTCOPY
- X
- X#ifdef MSDOS
- X#include <fcntl.h>
- Xextern unsigned char _osmode;
- Xextern FILE *popen();
- Xextern pclose();
- X#define ftruncate chsize
- X#define mktemp Mktemp
- X#define SYSTIME_HAS_NO_TM
- X#define NOBSTRING
- X#define SYSNAME (_osmode ? "OS/2" : "MS-DOS")
- X#define OUR_EXTEND (_osmode ? EXTEND_OS2 : EXTEND_MSDOS)
- X#define FILENAME_LENGTH 128
- X#define NULLFILE "nul"
- X#define TMP_FILENAME_TEMPLATE "lhXXXXXX"
- X#define NOT_COMPATIBLE_MODE
- X#define RMODE "rb"
- X#define WMODE "wb"
- X#else
- X#include <sys/file.h>
- X#include <time.h>
- X#define SYSNAME "UNIX"
- X#define ftruncate chsize
- X#define OUR_EXTEND EXTEND_UNIX
- X#define FILENAME_LENGTH 1024
- X#define NULLFILE "/dev/null"
- X#define RMODE "r"
- X#define WMODE "w"
- X#endif
- X
- X#ifdef SYSTIME_HAS_NO_TM
- X/* most of System V, define SYSTIME_HAS_NO_TM */
- X#include <time.h>
- X#endif
- X
- X/* #include <strings.h> */
- X#include <string.h>
- X#include <sys/select.h>
- X#include <sys/fcntl.h>
- X/*----------------------------------------------------------------------*/
- X/* DIRECTORY ACCESS STUFF */
- X/*----------------------------------------------------------------------*/
- X#ifndef NODIRECTORY
- X#ifdef SYSV_SYSTEM_DIR
- X
- X#include <dirent.h>
- X#define DIRENTRY struct dirent
- X#define NAMLEN(p) strlen (p->d_name)
- X
- X#else /* not SYSV_SYSTEM_DIR */
- X
- X#ifdef NONSYSTEM_DIR_LIBRARY
- X#include "lhdir.h"
- X#else /* not NONSYSTEM_DIR_LIBRARY */
- X#include <sys/dir.h>
- X#endif /* not NONSYSTEM_DIR_LIBRARY */
- X
- X#define DIRENTRY struct direct
- X#define NAMLEN(p) p->d_namlen
- X
- Xextern DIR *opendir ();
- Xextern struct direct *readdir ();
- X
- X#endif /* not SYSV_SYSTEM_DIR */
- X#endif
- X
- X/*----------------------------------------------------------------------*/
- X/* FILE ATTRIBUTES */
- X/*----------------------------------------------------------------------*/
- X
- X/* If file mode is not compatible between your Machine/OS and
- X LHarc standard UNIX file mode.
- X (See UNIX Manual stat(1), <sys/stat.h>,
- X and/or below UNIX_* difinitions. ) */
- X/* #define NOT_COMPATIBLE_MODE */
- X
- X
- X/*----------------------------------------------------------------------*/
- X/* MEMORY FUNCTIONS */
- X/*----------------------------------------------------------------------*/
- X
- X#ifdef NOBSTRING
- X#ifdef __ANSI__
- X#include "mem.h"
- X#define bcmp(a,b,n) memcmp ((a),(b),(n))
- X#define bcopy(s,d,n) memmove((d),(s),(n))
- X#define bzero(d,n) memset((d),0,(n))
- X#else /* not __ANSI__ */
- X#include "memory.h"
- X#define bcmp(a,b,n) memcmp ((a),(b),(n))
- X#define bcopy(s,d,n) memcpy ((d),(s),(n)) /* movmem((s),(d),(n)) */
- X#define bzero(d,n) memset((d),0,(n))
- X#endif /* not __ANSI__ */
- X#endif /* NOBSTRING */
- X
- X
- X/*----------------------------------------------------------------------*/
- X/* YOUR CUSTOMIZIES */
- X/*----------------------------------------------------------------------*/
- X/* These difinitions are changable to you like. */
- X #define ARCHIVENAME_EXTENTION ".lzh"
- X/* #define TMP_FILENAME_TEMPLATE "/tmp/lhXXXXXX" */
- X/* #define BACKUPNAME_EXTENTION ".BAK" */
- X/* #define MULTIBYTE_CHAR */
- X
- X
- X
- X#define SJC_FIRST_P(c) \
- X (((unsigned char)(c) >= 0x80) && \
- X (((unsigned char)(c) < 0xa0) || \
- X ((unsigned char)(c) >= 0xe0) && \
- X ((unsigned char)(c) < 0xfd)))
- X#define SJC_SECOND_P(c) \
- X (((unsigned char)(c) >= 0x40) && \
- X ((unsigned char)(c) < 0xfd) && \
- X ((ungigned char)(c) != 0x7f))
- X
- X#ifdef MULTIBYTE_CHAR
- X#define MULTIBYTE_FIRST_P SJC_FIRST_P
- X#define MULTIBYTE_SECOND_P SJC_SECOND_P
- X#endif
- X
- X/*----------------------------------------------------------------------*/
- X/* OTHER DIFINITIONS */
- X/*----------------------------------------------------------------------*/
- X
- X#ifndef SEEK_SET
- X#define SEEK_SET 0
- X#define SEEK_CUR 1
- X#define SEEK_END 2
- X#endif
- X
- X
- X/* non-integral functions */
- Xextern struct tm *localtime ();
- Xextern char *getenv ();
- Xextern char *malloc ();
- Xextern char *realloc ();
- X
- Xextern int rson[];
- X
- X/* external variables */
- Xextern int errno;
- X
- X
- X#define FALSE 0
- X#define TRUE 1
- Xtypedef int boolean;
- X
- X
- X/*----------------------------------------------------------------------*/
- X/* LHarc FILE DIFINITIONS */
- X/*----------------------------------------------------------------------*/
- X#define METHOD_TYPE_STRAGE 5
- X#define LZHUFF0_METHOD "-lh0-"
- X#define LZHUFF1_METHOD "-lh1-"
- X#define LARC4_METHOD "-lz4-"
- X#define LARC5_METHOD "-lz5-"
- X
- X#define I_HEADER_SIZE 0
- X#define I_HEADER_CHECKSUM 1
- X#define I_METHOD 2
- X#define I_PACKED_SIZE 7
- X#define I_ORIGINAL_SIZE 11
- X#define I_LAST_MODIFIED_STAMP 15
- X#define I_ATTRIBUTE 19
- X#define I_NAME_LENGTH 21
- X#define I_NAME 22
- X
- X#define I_CRC 22 /* + name_length */
- X#define I_EXTEND_TYPE 24 /* + name_length */
- X#define I_MINOR_VERSION 25 /* + name_length */
- X#define I_UNIX_LAST_MODIFIED_STAMP 26 /* + name_length */
- X#define I_UNIX_MODE 30 /* + name_length */
- X#define I_UNIX_UID 32 /* + name_length */
- X#define I_UNIX_GID 34 /* + name_length */
- X#define I_UNIX_EXTEND_BOTTOM 36 /* + name_length */
- X
- X
- X
- X#define EXTEND_GENERIC 0
- X#define EXTEND_UNIX 'U'
- X#define EXTEND_MSDOS 'M'
- X#define EXTEND_MACOS 'm'
- X#define EXTEND_OS9 '9'
- X#define EXTEND_OS2 '2'
- X#define EXTEND_OS68K 'K'
- X#define EXTEND_OS386 '3'
- X#define EXTEND_HUMAN 'H'
- X#define EXTEND_CPM 'C'
- X#define EXTEND_FLEX 'F'
- X
- X#define GENERIC_ATTRIBUTE 0x20
- X#define GENERIC_DIRECTORY_ATTRIBUTE 0x10
- X
- X#define CURRENT_UNIX_MINOR_VERSION 0x00
- X
- X
- X
- Xtypedef struct LzHeader {
- X unsigned char header_size;
- X char method[METHOD_TYPE_STRAGE];
- X long packed_size;
- X long original_size;
- X long last_modified_stamp;
- X unsigned short attribute;
- X char name[256];
- X unsigned short crc;
- X boolean has_crc;
- X unsigned char extend_type;
- X unsigned char minor_version;
- X /* extend_type == EXTEND_UNIX and convert from other type. */
- X time_t unix_last_modified_stamp;
- X unsigned short unix_mode;
- X unsigned short unix_uid;
- X unsigned short unix_gid;
- X} LzHeader;
- X
- X#define UNIX_FILE_TYPEMASK 0170000
- X#define UNIX_FILE_REGULAR 0100000
- X#define UNIX_FILE_DIRECTORY 0040000
- X#define UNIX_SETUID 0004000
- X#define UNIX_SETGID 0002000
- X#define UNIX_STYCKYBIT 0001000
- X#define UNIX_OWNER_READ_PERM 0000400
- X#define UNIX_OWNER_WRITE_PERM 0000200
- X#define UNIX_OWNER_EXEC_PERM 0000100
- X#define UNIX_GROUP_READ_PERM 0000040
- X#define UNIX_GROUP_WRITE_PERM 0000020
- X#define UNIX_GROUP_EXEC_PERM 0000010
- X#define UNIX_OTHER_READ_PERM 0000004
- X#define UNIX_OTHER_WRITE_PERM 0000002
- X#define UNIX_OTHER_EXEC_PERM 0000001
- X#define UNIX_RW_RW_RW 0000666
- X
- X#define LZHEADER_STRAGE 256
- X
- X/*----------------------------------------------------------------------*/
- X/* PROGRAM */
- X/*----------------------------------------------------------------------*/
- X
- X
- X#define CMD_UNKNOWN 0
- X#define CMD_EXTRACT 1
- X#define CMD_APPEND 2
- X#define CMD_VIEW 3
- X
- Xint cmd = CMD_UNKNOWN;
- Xchar **cmd_filev;
- Xint cmd_filec;
- Xchar *archive_name;
- X
- Xchar expanded_archive_name[FILENAME_LENGTH];
- Xchar temporary_name[FILENAME_LENGTH];
- Xchar pager[FILENAME_LENGTH];
- X
- X
- X/* options */
- Xboolean quiet = FALSE;
- Xboolean text_mode = FALSE;
- X/*boolean verbose = FALSE; */
- Xboolean noexec = FALSE; /* debugging option */
- Xboolean force = FALSE;
- Xboolean prof = FALSE;
- X
- X
- X/* view flags */
- Xboolean long_format_listing = FALSE;
- X
- X/* extract flags */
- Xboolean output_to_test = FALSE;
- Xboolean output_to_stdout = FALSE;
- X
- X/* append flags */
- Xboolean new_archive = FALSE;
- Xboolean update_if_newer = FALSE;
- Xboolean update_freshen = FALSE;
- Xboolean delete_after_append = FALSE;
- Xboolean delete_from_archive = FALSE;
- X
- Xboolean remove_temporary_at_error = FALSE;
- X
- X
- X/*----------------------------------------------------------------------*/
- X/* NOTES : Text File Format */
- X/* GENERATOR NewLine */
- X/* [generic] 0D 0A */
- X/* [MS-DOS] 0D 0A */
- X/* [MacOS] 0D */
- X/* [UNIX] 0A */
- X/*----------------------------------------------------------------------*/
- X
- Xchar *myname;
- X
- X
- Xvoid userbreak()
- X{
- X error("Interrupt.");
- X}
- X
- X
- Xmain (argc, argv)
- X int argc;
- X char *argv[];
- X{
- X char *p;
- X
- X myname = argv[0];
- X signal(SIGINT, userbreak);
- X
- X#ifdef PROF
- X PROFINIT(PT_USER|PT_USEKP, NULL);
- X PROFCLEAR(PT_USER);
- X PROFON(PT_USER);
- X#endif
- X
- X if (argc < 3)
- X print_tiny_usage_and_exit ();
- X
- X /* commands */
- X#ifdef MSDOS
- X switch (tolower(argv[1][0]))
- X#else
- X switch (argv[1][0])
- X#endif
- X {
- X case 'x':
- X case 'e':
- X cmd = CMD_EXTRACT;
- X break;
- X
- X case 't':
- X output_to_test = TRUE;
- X cmd = CMD_EXTRACT;
- X break;
- X
- X case 'p':
- X output_to_stdout = TRUE;
- X cmd = CMD_EXTRACT;
- X break;
- X
- X case 'c':
- X new_archive = TRUE;
- X cmd = CMD_APPEND;
- X break;
- X
- X case 'a':
- X cmd = CMD_APPEND;
- X break;
- X
- X case 'd':
- X delete_from_archive = TRUE;
- X cmd = CMD_APPEND;
- X break;
- X
- X case 'u':
- X update_if_newer = TRUE;
- X cmd = CMD_APPEND;
- X break;
- X
- X case 'f':
- X update_if_newer = update_freshen = TRUE;
- X cmd = CMD_APPEND;
- X break;
- X
- X case 'm':
- X delete_after_append = TRUE;
- X cmd = CMD_APPEND;
- X break;
- X
- X case 'v':
- X cmd = CMD_VIEW;
- X break;
- X
- X case 'l':
- X long_format_listing = TRUE;
- X cmd = CMD_VIEW;
- X break;
- X
- X case 'h':
- X default:
- X print_tiny_usage_and_exit ();
- X }
- X
- X /* options */
- X p = &argv[1][1];
- X for (p = &argv[1][1]; *p; p++)
- X {
- X#ifdef MSDOS
- X switch (tolower(*p))
- X#else
- X switch (*p)
- X#endif
- X {
- X case 'q': quiet = TRUE; break;
- X case 'f': force = TRUE; break;
- X/* case 'p': prof = TRUE; break; */
- X/* case 'v': verbose = TRUE; break; */
- X case 'v': strcpy(pager, p + 1); *(p + 1) = 0; break;
- X case 't': text_mode = TRUE; break;
- X case 'n': noexec = TRUE; break;
- X
- X default:
- X fprintf (stderr, "unknown option '%c'.\n", *p);
- X exit (1);
- X }
- X }
- X
- X /* archive file name */
- X archive_name = argv[2];
- X
- X /* target file name */
- X cmd_filec = argc - 3;
- X cmd_filev = argv + 3;
- X sort_files ();
- X
- X switch (cmd)
- X {
- X case CMD_EXTRACT: cmd_extract (); break;
- X case CMD_APPEND: cmd_append (); break;
- X case CMD_VIEW: cmd_view (); break;
- X }
- X
- X#ifdef PROF
- X PROFOFF(PT_USER);
- X PROFDUMP(PT_USER, "profile.out");
- X PROFFREE(PT_USER);
- X#endif
- X
- X exit (0);
- X}
- X
- Xprint_tiny_usage_and_exit ()
- X{
- X printf("\nC-LHarc for %s Version 1.00 (C) 1989-1990 Y.Tagawa, Kai Uwe Rommel\n"
- X "\nUsage: %s {axevlufdmctp}[qnftv] archive_file [files or directories...]\n",
- X SYSNAME, myname);
- X printf("\nCommands: Options:\n"
- X " a Append q quiet\n"
- X " x,e EXtract n no execute\n"
- X " v,l View/List f force (over write at extract)\n"
- X " u Update t files are TEXT files\n"
- X " f Freshen v<pager> use file pager for p command\n"
- X " d Delete\n"
- X " m Move\n"
- X " c re-Construct new archive\n"
- X " t Test archive\n"
- X " p Print to STDOUT\n");
- X exit (1);
- X}
- X
- Xmessage (title, msg)
- X char *title, *msg;
- X{
- X fprintf (stderr, "%s ", myname);
- X if (errno == 0)
- X fprintf (stderr, "%s %s\n", title, msg);
- X else
- X perror (msg);
- X}
- X
- Xwarning (msg)
- X char *msg;
- X{
- X message ("Warning:", msg);
- X}
- X
- Xerror (msg)
- X char *msg;
- X{
- X message ("Error:", msg);
- X
- X if (remove_temporary_at_error)
- X {
- X#ifdef MSDOS
- X fcloseall();
- X#endif
- X unlink (temporary_name);
- X }
- X
- X exit (1);
- X}
- X
- Xchar *writting_filename;
- Xchar *reading_filename;
- X
- Xwrite_error ()
- X{
- X error (writting_filename);
- X}
- X
- Xread_error ()
- X{
- X error (reading_filename);
- X}
- X
- X
- X
- X/*----------------------------------------------------------------------*/
- X/* */
- X/*----------------------------------------------------------------------*/
- X
- Xboolean expand_archive_name (dst, src)
- X char *dst, *src;
- X{
- X register char *p, *dot;
- X
- X strcpy (dst, src);
- X
- X for (p = dst, dot = (char*)0; *p; p++)
- X if (*p == '.')
- X dot = p;
- X else if (*p == '/' || *p == '\\')
- X dot = (char*)0;
- X
- X if (dot)
- X p = dot;
- X
- X#ifdef ARCHIVENAME_EXTENTION
- X strcpy (p, ARCHIVENAME_EXTENTION);
- X#else
- X strcpy (p, ".lzh");
- X#endif
- X return (strcmp (dst, src) != 0);
- X}
- X
- X#ifdef MSDOS
- X#define STRING_COMPARE(a,b) stricmp((a),(b))
- X#else
- X#define STRING_COMPARE(a,b) strcmp((a),(b))
- X#endif
- X
- Xint sort_by_ascii (a, b)
- X char **a, **b;
- X{
- X return STRING_COMPARE (*a, *b);
- X}
- X
- Xsort_files ()
- X{
- X qsort (cmd_filev, cmd_filec, sizeof (char*), sort_by_ascii);
- X}
- X
- X#ifndef MSDOS
- Xchar *strdup (string)
- X char *string;
- X{
- X int len = strlen (string) + 1;
- X char *p = malloc (len);
- X bcopy (string, p, len);
- X return p;
- X}
- X#endif
- X
- X#ifdef NODIRECTORY
- X/* please need your imprementation */
- Xboolean find_files (name, v_filec, v_filev)
- X char *name;
- X int *v_filec;
- X char ***v_filev;
- X{
- X return FALSE; /* DUMMY */
- X}
- X#else
- Xboolean find_files (name, v_filec, v_filev)
- X char *name;
- X int *v_filec;
- X char ***v_filev;
- X{
- X char newname[FILENAME_LENGTH];
- X int len, n;
- X DIR *dirp;
- X DIRENTRY *dp;
- X int alloc_size = 64; /* any (^_^) */
- X char **filev;
- X int filec = 0;
- X
- X if ( strcmp(name, ".") == 0 )
- X newname[0] = 0;
- X else
- X strcpy (newname, name);
- X
- X len = strlen (newname);
- X dirp = opendir (name);
- X
- X if (dirp)
- X {
- X filev = (char**)malloc (alloc_size * sizeof(char *));
- X if (!filev)
- X error ("not enough memory");
- X
- X for (dp = readdir (dirp); dp != NULL; dp = readdir (dirp))
- X {
- X n = NAMLEN (dp);
- X if (
- X#ifndef MSDOS
- X (dp->d_ino != 0) &&
- X#endif
- X ((dp->d_name[0] != '.') ||
- X ((n != 1) &&
- X ((dp->d_name[1] != '.') ||
- X (n != 2)))) && /* exclude '.' and '..' */
- X (strcmp (dp->d_name, temporary_name) != 0) &&
- X (strcmp (dp->d_name, archive_name) != 0))
- X {
- X if ((len != 0) && (newname[len-1] != '/') && (newname[len-1] != '\\'))
- X {
- X#ifdef MSDOS
- X newname[len] = '\\';
- X#else
- X newname[len] = '/';
- X#endif
- X strncpy (newname+len+1, dp->d_name, n);
- X newname[len+n+1] = '\0';
- X }
- X else
- X {
- X strncpy (newname+len, dp->d_name, n);
- X newname[len+n] = '\0';
- X }
- X
- X filev[filec++] = strdup (newname);
- X if (filec == alloc_size)
- X {
- X alloc_size += 64;
- X filev = (char**)realloc (filev, alloc_size * sizeof(char *));
- X }
- X }
- X }
- X closedir (dirp);
- X }
- X
- X *v_filev = filev;
- X *v_filec = filec;
- X if (dirp)
- X {
- X qsort (filev, filec, sizeof (char*), sort_by_ascii);
- X return TRUE;
- X }
- X else
- X return FALSE;
- X}
- X#endif
- X
- Xfree_files (filec, filev)
- X int filec;
- X char **filev;
- X{
- X int i;
- X
- X for (i = 0; i < filec; i ++)
- X free (filev[i]);
- X
- X free (filev);
- X}
- X
- X
- X/*----------------------------------------------------------------------*/
- X/* */
- X/*----------------------------------------------------------------------*/
- X
- Xint calc_sum (p, len)
- X register char *p;
- X register int len;
- X{
- X register int sum;
- X
- X for (sum = 0; len; len--)
- X sum += *p++;
- X
- X return sum & 0xff;
- X}
- X
- Xunsigned char *get_ptr;
- X#define setup_get(PTR) get_ptr = (unsigned char*)(PTR)
- X#define get_byte() (*get_ptr++)
- X#define put_ptr get_ptr
- X#define setup_put(PTR) put_ptr = (unsigned char*)(PTR)
- X#define put_byte(c) *put_ptr++ = (unsigned char)(c)
- X
- Xunsigned short get_word ()
- X{
- X int b0, b1;
- X
- X b0 = get_byte ();
- X b1 = get_byte ();
- X return (b1 << 8) + b0;
- X}
- X
- Xput_word (v)
- X unsigned int v;
- X{
- X put_byte (v);
- X put_byte (v >> 8);
- X}
- X
- Xlong get_longword ()
- X{
- X long b0, b1, b2, b3;
- X
- X b0 = get_byte ();
- X b1 = get_byte ();
- X b2 = get_byte ();
- X b3 = get_byte ();
- X return (b3 << 24) + (b2 << 16) + (b1 << 8) + b0;
- X}
- X
- Xput_longword (v)
- X long v;
- X{
- X put_byte (v);
- X put_byte (v >> 8);
- X put_byte (v >> 16);
- X put_byte (v >> 24);
- X}
- X
- X
- Xmsdos_to_unix_filename (name, len)
- X register char *name;
- X register int len;
- X{
- X register int i;
- X
- X#ifdef MULTIBYTE_CHAR
- X for (i = 0; i < len; i ++)
- X {
- X if (MULTIBYTE_FIRST_P (name[i]) &&
- X MULTIBYTE_SECOND_P (name[i+1]))
- X i ++;
- X#ifndef MSDOS
- X else if (name[i] == '\\')
- X name[i] = '/';
- X#endif
- X else if (isupper (name[i]))
- X name[i] = tolower (name[i]);
- X }
- X#else
- X for (i = 0; i < len; i ++)
- X {
- X#ifndef MSDOS
- X if (name[i] == '\\')
- X name[i] = '/';
- X else
- X#endif
- X if (isupper (name[i]))
- X name[i] = tolower (name[i]);
- X }
- X#endif
- X}
- X
- Xgeneric_to_unix_filename (name, len)
- X register char *name;
- X register int len;
- X{
- X register int i;
- X boolean lower_case_used = FALSE;
- X
- X#ifdef MULTIBYTE_CHAR
- X for (i = 0; i < len; i ++)
- X {
- X if (MULTIBYTE_FIRST_P (name[i]) &&
- X MULTIBYTE_SECOND_P (name[i+1]))
- X i ++;
- X else if (islower (name[i]))
- X {
- X lower_case_used = TRUE;
- X break;
- X }
- X }
- X for (i = 0; i < len; i ++)
- X {
- X if (MULTIBYTE_FIRST_P (name[i]) &&
- X MULTIBYTE_SECOND_P (name[i+1]))
- X i ++;
- X#ifndef MSDOS
- X else if (name[i] == '\\')
- X name[i] = '/';
- X#endif
- X else if (!lower_case_used && isupper (name[i]))
- X name[i] = tolower (name[i]);
- X }
- X#else
- X for (i = 0; i < len; i ++)
- X if (islower (name[i]))
- X {
- X lower_case_used = TRUE;
- X break;
- X }
- X for (i = 0; i < len; i ++)
- X {
- X#ifndef MSDOS
- X if (name[i] == '\\')
- X name[i] = '/';
- X else
- X#endif
- X if (!lower_case_used && isupper (name[i]))
- X name[i] = tolower (name[i]);
- X }
- X#endif
- X}
- X
- Xmacos_to_unix_filename (name, len)
- X register char *name;
- X register int len;
- X{
- X register int i;
- X
- X for (i = 0; i < len; i ++)
- X {
- X if (name[i] == ':')
- X name[i] = '/';
- X else if (name[i] == '/')
- X name[i] = ':';
- X }
- X}
- X
- X/*----------------------------------------------------------------------*/
- X/* */
- X/* Generic stamp format: */
- X/* */
- X/* 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 */
- X/* |<-------- year ------->|<- month ->|<-- day -->| */
- X/* */
- X/* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 */
- X/* |<--- hour --->|<---- minute --->|<- second*2 ->| */
- X/* */
- X/*----------------------------------------------------------------------*/
- X
- X
- Xlong gettz ()
- X{
- X#ifdef MSDOS
- X return timezone;
- X#else
- X struct timeval tp;
- X/* struct timezone tzp;*/
- X/* gettimeofday (&tp, &tzp);*/ /* specific to 4.3BSD */
- X/* return (tzp.tz_minuteswest * 60 + (tzp.tz_dsttime != 0 ? 60L * 60L : 0));*/
- X return (60);
- X#endif
- X}
- X
- X#ifdef NOT_USED
- Xstruct tm *msdos_to_unix_stamp_tm (a)
- X long a;
- X{
- X static struct tm t;
- X t.tm_sec = ( a & 0x1f) * 2;
- X t.tm_min = (a >> 5) & 0x3f;
- X t.tm_hour = (a >> 11) & 0x1f;
- X t.tm_mday = (a >> 16) & 0x1f;
- X t.tm_mon = (a >> 16+5) & 0x0f - 1;
- X t.tm_year = ((a >> 16+9) & 0x7f) + 80;
- X return &t;
- X}
- X#endif
- X
- Xtime_t generic_to_unix_stamp (t)
- X long t;
- X{
- X struct tm tm;
- X long longtime;
- X static unsigned int dsboy[12] =
- X { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
- X unsigned long days;
- X
- X tm.tm_year = ((int)(t >> 25) & 0x7f) + 80;
- X tm.tm_mon = ((int)(t >> 21) & 0x0f) - 1; /* 0..11 means Jan..Dec */
- X tm.tm_mday = (int)(t >> 16) & 0x1f; /* 1..31 means 1st,...31st */
- X
- X tm.tm_hour = ((int)t >> 11) & 0x1f;
- X tm.tm_min = ((int)t >> 5) & 0x3f;
- X tm.tm_sec = ((int)t & 0x1f) * 2;
- X
- X#ifdef MSDOS
- X longtime = mktime(&tm);
- X#else
- X /* Calculate days since 1970.01.01 */
- X days = (365 * (tm.tm_year - 70) + /* days due to whole years */
- X (tm.tm_year - 70 + 1) / 4 + /* days due to leap years */
- X dsboy[tm.tm_mon] + /* days since beginning of this year */
- X tm.tm_mday-1); /* days since beginning of month */
- X
- X if ((tm.tm_year % 4 == 0) &&
- X (tm.tm_year % 400 != 0) &&
- X (tm.tm_mon >= 2)) /* if this is a leap year and month */
- X days++; /* is March or later, add a day */
- X
- X /* Knowing the days, we can find seconds */
- X longtime = (((days * 24) + tm.tm_hour) * 60 + tm.tm_min) * 60 + tm.tm_sec;
- X longtime += gettz (); /* adjust for timezone */
- X#endif
- X
- X /* special case: if MSDOS format date and time were zero, then we set
- X time to be zero here too. */
- X if (t == 0)
- X longtime = 0;
- X
- X /* LONGTIME is now the time in seconds, since 1970/01/01 00:00:00. */
- X return (time_t)longtime;
- X}
- X
- Xlong unix_to_generic_stamp (t)
- X time_t t;
- X{
- X struct tm *tm = localtime (&t);
- X unsigned long stamp;
- X
- X stamp = ( ((long)(tm->tm_year - 80)) << 25 );
- X stamp += ( ((long)(tm->tm_mon + 1)) << 21 );
- X stamp += ( ((long)(tm->tm_mday)) << 16 );
- X stamp += ( ((long)(tm->tm_hour)) << 11 );
- X stamp += ( ((long)(tm->tm_min)) << 5 );
- X stamp += ( ((long)(tm->tm_sec)) >> 1 );
- X
- X return stamp;
- X}
- X
- X/*----------------------------------------------------------------------*/
- X/* */
- X/*----------------------------------------------------------------------*/
- X
- Xboolean get_header (fp, hdr)
- X FILE *fp;
- X register LzHeader *hdr;
- X{
- X int header_size;
- X int name_length;
- X char data[LZHEADER_STRAGE];
- X int checksum;
- X int i;
- X
- X bzero (hdr, sizeof (LzHeader));
- X
- X if (((header_size = getc (fp)) == EOF) || (header_size == 0))
- X {
- X return FALSE; /* finish */
- X }
- X
- X if (fread (data + I_HEADER_CHECKSUM,
- X sizeof (char), header_size + 1, fp) < header_size + 1)
- X {
- X error ("Invalid header (LHarc file ?)\a");
- X return FALSE; /* finish */
- X }
- X
- X setup_get (data + I_HEADER_CHECKSUM);
- X checksum = calc_sum (data + I_METHOD, header_size);
- X if (get_byte () != checksum)
- X warning ("Checksum error (LHarc file?)\a");
- X
- X hdr->header_size = header_size;
- X bcopy (data + I_METHOD, hdr->method, METHOD_TYPE_STRAGE);
- X#ifdef OLD
- X if ((bcmp (hdr->method, LZHUFF1_METHOD, METHOD_TYPE_STRAGE) != 0) &&
- X (bcmp (hdr->method, LZHUFF0_METHOD, METHOD_TYPE_STRAGE) != 0) &&
- X (bcmp (hdr->method, LARC5_METHOD, METHOD_TYPE_STRAGE) != 0) &&
- X (bcmp (hdr->method, LARC4_METHOD, METHOD_TYPE_STRAGE) != 0))
- X {
- X warning ("Unknown method (LHarc file ?)");
- X return FALSE; /* invalid method */
- X }
- X#endif
- X setup_get (data + I_PACKED_SIZE);
- X hdr->packed_size = get_longword ();
- X hdr->original_size = get_longword ();
- X hdr->last_modified_stamp = get_longword ();
- X hdr->attribute = get_word ();
- X name_length = get_byte ();
- X for (i = 0; i < name_length; i ++)
- X hdr->name[i] =(char)get_byte ();
- X hdr->name[name_length] = '\0';
- X
- X /* defaults for other type */
- X hdr->unix_mode = UNIX_FILE_REGULAR | UNIX_RW_RW_RW;
- X hdr->unix_gid = 0;
- X hdr->unix_uid = 0;
- X
- X if (header_size - name_length >= 24)
- X { /* EXTEND FORMAT */
- X hdr->crc = get_word ();
- X hdr->extend_type = get_byte ();
- X hdr->minor_version = get_byte ();
- X hdr->has_crc = TRUE;
- X }
- X else if (header_size - name_length == 22)
- X { /* Generic with CRC */
- X hdr->crc = get_word ();
- X hdr->extend_type = EXTEND_GENERIC;
- X hdr->has_crc = TRUE;
- X }
- X else if (header_size - name_length == 20)
- X { /* Generic no CRC */
- X hdr->extend_type = EXTEND_GENERIC;
- X hdr->has_crc = FALSE;
- X }
- X else
- X {
- X warning ("Unknown header (LHarc file ?)");
- X return FALSE;
- X }
- X
- X switch (hdr->extend_type)
- X {
- X case EXTEND_MSDOS:
- X msdos_to_unix_filename (hdr->name, name_length);
- X hdr->unix_last_modified_stamp =
- X generic_to_unix_stamp (hdr->last_modified_stamp);
- X break;
- X
- X case EXTEND_UNIX:
- X hdr->unix_last_modified_stamp = (time_t)get_longword ();
- X hdr->unix_mode = get_word ();
- X hdr->unix_uid = get_word ();
- X hdr->unix_gid = get_word ();
- X break;
- X
- X case EXTEND_MACOS:
- X macos_to_unix_filename (hdr->name, name_length);
- X hdr->unix_last_modified_stamp =
- X generic_to_unix_stamp (hdr->last_modified_stamp);
- X break;
- X
- X default:
- X generic_to_unix_filename (hdr->name, name_length);
- X hdr->unix_last_modified_stamp =
- X generic_to_unix_stamp (hdr->last_modified_stamp);
- X }
- X
- X return TRUE;
- X}
- X
- Xinit_header (name, v_stat, hdr)
- X char *name;
- X struct stat *v_stat;
- X LzHeader *hdr;
- X{
- X bcopy (LZHUFF1_METHOD, hdr->method, METHOD_TYPE_STRAGE);
- X hdr->packed_size = 0;
- X hdr->original_size = v_stat->st_size;
- X hdr->last_modified_stamp = unix_to_generic_stamp (v_stat->st_mtime);
- X#ifdef MSDOS
- X getfilemode(name, &(hdr->attribute));
- X#else
- X hdr->attribute = GENERIC_ATTRIBUTE;
- X#endif
- X strcpy (hdr->name, name);
- X hdr->crc = 0x0000;
- X hdr->extend_type = OUR_EXTEND;
- X hdr->unix_last_modified_stamp = v_stat->st_mtime;
- X /* 00:00:00 since JAN.1.1970 */
- X#ifdef NOT_COMPATIBLE_MODE
- X hdr->unix_mode = v_stat->st_mode;
- X#else
- X hdr->unix_mode = v_stat->st_mode;
- X#endif
- X
- X hdr->unix_uid = v_stat->st_uid;
- X hdr->unix_gid = v_stat->st_gid;
- X
- X if ((v_stat->st_mode & S_IFMT) == S_IFDIR)
- X {
- X bcopy (LZHUFF0_METHOD, hdr->method, METHOD_TYPE_STRAGE);
- X hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
- X hdr->original_size = 0;
- X strcat (hdr->name, "/");
- X }
- X}
- X
- X/* Write only unix extended header. */
- Xwrite_header (nafp, hdr)
- X FILE *nafp;
- X LzHeader *hdr;
- X{
- X int header_size;
- X int name_length;
- X char data[LZHEADER_STRAGE], *ptr;
- X int cnt;
- X
- X bzero (data, LZHEADER_STRAGE);
- X bcopy (hdr->method, data + I_METHOD, METHOD_TYPE_STRAGE);
- X setup_put (data + I_PACKED_SIZE);
- X put_longword (hdr->packed_size);
- X put_longword (hdr->original_size);
- X put_longword (hdr->last_modified_stamp);
- X put_word (hdr->attribute);
- X
- X#ifdef STRICT
- X
- X if ( hdr->name[1] == ':' )
- X {
- X name_length = strlen(hdr->name + 2);
- X put_byte (name_length);
- X bcopy (hdr->name + 2, data + I_NAME, name_length);
- X }
- X else
- X {
- X name_length = strlen(hdr->name);
- X put_byte (name_length);
- X bcopy (hdr->name, data + I_NAME, name_length);
- X }
- X
- X for ( ptr = data + I_NAME, cnt = 0; cnt < name_length; ptr++, cnt++ )
- X {
- X *ptr = toupper(*ptr);
- X
- X if ( *ptr == '/' )
- X *ptr = '\\';
- X }
- X#else
- X name_length = strlen (hdr->name);
- X put_byte (name_length);
- X bcopy (hdr->name, data + I_NAME, name_length);
- X#endif
- X
- X setup_put (data + I_NAME + name_length);
- X put_word (hdr->crc);
- X#ifdef STRICT
- X header_size = I_EXTEND_TYPE - 2 + name_length;
- X#else
- X put_byte (OUR_EXTEND);
- X put_byte (CURRENT_UNIX_MINOR_VERSION);
- X put_longword ((long)hdr->unix_last_modified_stamp);
- X put_word (hdr->unix_mode);
- X put_word (hdr->unix_uid);
- X put_word (hdr->unix_gid);
- X header_size = I_UNIX_EXTEND_BOTTOM - 2 + name_length;
- X#endif
- X data[I_HEADER_SIZE] = header_size;
- X data[I_HEADER_CHECKSUM] = calc_sum (data + I_METHOD, header_size);
- X
- X if (fwrite (data, sizeof (char), header_size + 2, nafp) == NULL)
- X error ("cannot write to temporary file");
- X}
- X
- Xboolean archive_is_msdos_sfx1 (name)
- X char *name;
- X{
- X int len = strlen (name);
- X return ((len >= 4) &&
- X (strcmp (name + len - 4, ".com") == 0 ||
- X strcmp (name + len - 4, ".exe") == 0));
- X}
- X
- Xboolean skip_msdos_sfx1_code (fp)
- X FILE *fp;
- X{
- X unsigned char buffer[2048];
- X unsigned char *p, *q;
- X int n;
- X
- X n = fread (buffer, sizeof (char), 2048, fp);
- X
- X for (p = buffer + 2, q = buffer + n - 5; p < q; p ++)
- X {
- X /* found "-l??-" keyword (as METHOD type string) */
- X if (p[0] == '-' && p[1] == 'l' && p[4] == '-')
- X {
- X /* size and checksum validate check */
- X if (p[-2] > 20 && p[-1] == calc_sum (p, p[-2]))
- X {
- X fseek (fp, (long) ((p - 2) - buffer) - n, SEEK_CUR);
- X return TRUE;
- X }
- X }
- X }
- X
- X fseek (fp, (long) -n, SEEK_CUR);
- X return FALSE;
- X}
- X
- X
- X/*----------------------------------------------------------------------*/
- X/* */
- X/*----------------------------------------------------------------------*/
- X
- Xmake_tmp_name (original, name)
- X char *original;
- X char *name;
- X{
- X#ifdef TMP_FILENAME_TEMPLATE
- X /* "/tmp/lhXXXXXX" etc. */
- X strcpy (name, TMP_FILENAME_TEMPLATE);
- X#else
- X char *p, *s;
- X
- X strcpy (name, original);
- X for (p = name, s = (char*)0; *p; p++)
- X if (*p == '/' || *p == '\\')
- X s = p;
- X
- X strcpy ((s ? s+1 : name), "lhXXXXXX");
- X#endif
- X
- X mktemp (name);
- X}
- X
- Xmake_backup_name (name, orginal)
- X char *name;
- X char *orginal;
- X{
- X register char *p, *dot;
- X
- X strcpy (name, orginal);
- X for (p = name, dot = (char*)0; *p; p ++)
- X {
- X if (*p == '.')
- X dot = p;
- X else if (*p == '/' || *p == '\\')
- X dot = (char*)0;
- X }
- X
- X if (dot)
- X p = dot;
- X
- X#ifdef BACKUPNAME_EXTENTION
- X strcpy (p, BACKUPNAME_EXTENTION)
- X#else
- X strcpy (p, ".bak");
- X#endif
- X}
- X
- Xmake_standard_archive_name (name, orginal)
- X char *name;
- X char *orginal;
- X{
- X register char *p, *dot;
- X
- X strcpy (name, orginal);
- X for (p = name, dot = (char*)0; *p; p ++)
- X {
- X if (*p == '.')
- X dot = p;
- X else if (*p == '/' || *p == '\\')
- X dot = (char*)0;
- X }
- X
- X if (dot)
- X p = dot;
- X
- X#ifdef ARCHIVENAME_EXTENTION
- X strcpy (p, ARCHIVENAME_EXTENTION);
- X#else
- X strcpy (p, ".lzh");
- X#endif
- X}
- X
- X/*----------------------------------------------------------------------*/
- X/* */
- X/*----------------------------------------------------------------------*/
- X
- X
- Xboolean need_file (name)
- X char *name;
- X{
- X int i;
- X
- X if (cmd_filec == 0)
- X return TRUE;
- X
- X for (i = 0; i < cmd_filec; i ++)
- X {
- X if (STRING_COMPARE (cmd_filev[i], name) == 0)
- X return TRUE;
- X }
- X
- X return FALSE;
- X}
- X
- XFILE *xfopen (name, mode)
- X char *name, *mode;
- X{
- X FILE *fp;
- X
- X if ((fp = fopen (name, mode)) == NULL)
- X error (name);
- X
- X return fp;
- X}
- X
- X
- X/*----------------------------------------------------------------------*/
- X/* Listing Stuff */
- X/*----------------------------------------------------------------------*/
- X
- X/* need 14 or 22 (when long_format_listing is TRUE) column spaces */
- Xprint_size (packed_size, original_size)
- X long packed_size, original_size;
- X{
- X if (long_format_listing)
- X printf ("%7ld ", packed_size);
- X
- X printf ("%7ld ", original_size);
- X
- X if (original_size == 0L)
- X printf ("******");
- X else
- X printf ("%3d.%1d%%",
- X (int)((packed_size * 100L) / original_size),
- X (int)((packed_size * 1000L) / original_size) % 10);
- X}
- X
- X/* need 12 or 17 (when long_format_listing is TRUE) column spaces */
- Xprint_stamp (t)
- X time_t t;
- X{
- X static boolean got_now = FALSE;
- X static time_t now;
- X static unsigned int threshold;
- X static char t_month[12*3+1] = "JanFebMarAprMayJunJulAugSepOctNovDec";
- X struct tm *p;
- X
- X if (t == 0)
- X {
- X if (long_format_listing)
- X printf (" "); /* 17 spaces */
- X else
- X printf (" "); /* 12 spaces */
- X
- X return;
- X }
- X
- X if (!got_now)
- X {
- X time (&now);
- X p = localtime (&now);
- X threshold = p->tm_year * 12 + p->tm_mon - 6;
- X got_now = TRUE;
- X }
- X
- X p = localtime (&t);
- X
- X if (long_format_listing)
- X printf ("%.3s %2d %02d:%02d %04d",
- X &t_month[p->tm_mon * 3], p->tm_mday,
- X p->tm_hour, p->tm_min, p->tm_year + 1900);
- X else
- X if (p->tm_year * 12 + p->tm_mon > threshold)
- X printf ("%.3s %2d %02d:%02d",
- X &t_month[p->tm_mon * 3], p->tm_mday, p->tm_hour, p->tm_min);
- X else
- X printf ("%.3s %2d %04d",
- X &t_month[p->tm_mon * 3], p->tm_mday, p->tm_year + 1900);
- X}
- X
- Xprint_bar ()
- X{
- X /* 17+1+(0 or 7+1)+7+1+6+1+(0 or 1+4)+(12 or 17)+1+20 */
- X /* 12345678901234567_ 1234567_123456 _123456789012 1234 */
- X if (long_format_listing)
- X#ifdef STRICT
- X printf ("------- ------- ------ ---- ----------------- -------------\n");
- X#else
- X printf ("----------------- ------- ------- ------ ---- ----------------- -------------\n");
- X#endif
- X else
- X#ifdef STRICT
- X printf ("------- ------ ------------ --------------------\n");
- X#else
- X printf ("----------------- ------- ------ ------------ --------------------\n");
- X#endif
- X}
- X
- X
- X/*
- X view
- X */
- Xcmd_view ()
- X{
- X FILE *fp;
- X LzHeader hdr;
- X register char *p;
- X long a_packed_size = 0L;
- X long a_original_size = 0L;
- X int n_files = 0;
- X struct stat v_stat;
- X
- X if ((fp = fopen (archive_name, RMODE)) == NULL)
- X if (!expand_archive_name (expanded_archive_name, archive_name))
- X error (archive_name);
- X else
- X {
- X errno = 0;
- X fp = xfopen (expanded_archive_name, RMODE);
- X archive_name = expanded_archive_name;
- X }
- X
- X if (archive_is_msdos_sfx1 (archive_name))
- X {
- X skip_msdos_sfx1_code (fp);
- X }
- X
- X if (!quiet)
- X {
- X /* 12345678901234567_ 1234567_123456 _ 123456789012 1234 */
- X#ifdef STRICT
- X printf ("%s SIZE RATIO%s %s STAMP %s NAME\n",
- X#else
- X printf (" PERMSSN UID GID %s SIZE RATIO%s %s STAMP %s NAME\n",
- X#endif
- X long_format_listing ? " PACKED " : "", /* 8,0 */
- X long_format_listing ? " CRC" : "", /* 5,0 */
- X long_format_listing ? " " : "", /* 2,0 */
- X long_format_listing ? " " : ""); /* 3,0 */
- X print_bar ();
- X }
- X
- X while (get_header (fp, &hdr))
- X {
- X if (need_file (hdr.name))
- X {
- X if (hdr.extend_type == EXTEND_UNIX)
- X {
- X#ifndef STRICT
- X printf ("%c%c%c%c%c%c%c%c%c%4d/%-4d",
- X ((hdr.unix_mode & UNIX_OWNER_READ_PERM) ? 'r' : '-'),
- X ((hdr.unix_mode & UNIX_OWNER_WRITE_PERM) ? 'w' : '-'),
- X ((hdr.unix_mode & UNIX_OWNER_EXEC_PERM) ? 'x' : '-'),
- X ((hdr.unix_mode & UNIX_GROUP_READ_PERM) ? 'r' : '-'),
- X ((hdr.unix_mode & UNIX_GROUP_WRITE_PERM) ? 'w' : '-'),
- X ((hdr.unix_mode & UNIX_GROUP_EXEC_PERM) ? 'x' : '-'),
- X ((hdr.unix_mode & UNIX_OTHER_READ_PERM) ? 'r' : '-'),
- X ((hdr.unix_mode & UNIX_OTHER_WRITE_PERM) ? 'w' : '-'),
- X ((hdr.unix_mode & UNIX_OTHER_EXEC_PERM) ? 'x' : '-'),
- X hdr.unix_uid, hdr.unix_gid);
- X#endif
- X }
- X else
- X {
- X switch (hdr.extend_type)
- X { /* max 18 characters */
- X case EXTEND_GENERIC: p = "[Generic]"; break;
- X
- X case EXTEND_CPM: p = "[CP/M]"; break;
- X
- X /* OS-9 and FLEX's CPU is MC-6809. I like it. :-) */
- X case EXTEND_FLEX: p = "[FLEX]"; break;
- X
- X case EXTEND_OS9: p = "[OS-9]"; break;
- X
- X /* I guessed from this ID. Is this right? */
- X case EXTEND_OS68K: p = "[OS-9/68K]"; break;
- X
- X case EXTEND_MSDOS: p = "[MS-DOS]"; break;
- X
- X /* I have Macintosh. :-) */
- X case EXTEND_MACOS: p = "[Mac OS]"; break;
- X
- X case EXTEND_OS2: p = "[OS/2]"; break;
- X
- X case EXTEND_HUMAN: p = "[Human68K]"; break;
- X
- X case EXTEND_OS386: p = "[OS-386]"; break;
- X
- X#ifdef EXTEND_TOWNSOS
- X /* This ID isn't fixed */
- X case EXTEND_TOWNSOS: p = "[TownsOS]"; break;
- X#endif
- X
- X /* Ouch! Please customize it's ID. */
- X default: p = "[Unknown]"; break;
- X }
- X#ifndef STRICT
- X printf ("%-18.18s", p);
- X#endif
- X }
- X
- X print_size (hdr.packed_size, hdr.original_size);
- X
- X if (long_format_listing)
- X if (hdr.has_crc)
- X printf (" %04x", hdr.crc);
- X else
- X printf (" ****");
- X
- X printf (" ");
- X print_stamp (hdr.unix_last_modified_stamp);
- X printf (" %s\n", hdr.name);
- X n_files ++;
- X a_packed_size += hdr.packed_size;
- X a_original_size += hdr.original_size;
- X }
- X fseek (fp, hdr.packed_size, SEEK_CUR);
- X }
- X
- X fclose (fp);
- X if (!quiet)
- X {
- X print_bar ();
- X
- X#ifndef STRICT
- X printf (" Total %4d file%c ",
- X n_files, (n_files == 1) ? ' ' : 's');
- X#endif
- X print_size (a_packed_size, a_original_size);
- X printf (" ");
- X
- X if (long_format_listing)
- X printf (" ");
- X
- X if (stat (archive_name, &v_stat) < 0)
- X print_stamp ((time_t)0);
- X else
- X print_stamp (v_stat.st_mtime);
- X
- X#ifdef STRICT
- X printf (" %4d file%c ",
- X n_files, (n_files == 1) ? ' ' : 's');
- X#endif
- X printf ("\n");
- X }
- X
- X return;
- X}
- X
- X
- Xboolean make_parent_path (name)
- X char *name;
- X{
- X char path[FILENAME_LENGTH];
- X struct stat v_stat;
- X register char *p;
- X
- X /* make parent directory name into PATH for recursive call */
- X strcpy (path, name);
- X for (p = path + strlen (path); p > path; p --)
- X if (p[-1] == '/' || p[-1] == '\\')
- X {
- X p[-1] = '\0';
- X break;
- X }
- X
- X if (p == path)
- X return FALSE; /* no more parent. */
- X
- X if (stat (path, &v_stat) >= 0)
- X {
- X if ((v_stat.st_mode & S_IFMT) != S_IFDIR)
- X return FALSE; /* already exist. but it isn't directory. */
- X return TRUE; /* already exist its directory. */
- X }
- X
- X errno = 0;
- X
- X if (!quiet)
- X message ("Making Directory", path);
- X
- X if (mkdir (path, 0777) >= 0) /* try */
- X return TRUE; /* successful done. */
- X
- X errno = 0;
- X
- X if (!make_parent_path (path))
- X return FALSE;
- X
- X if (mkdir (path, 0777) < 0) /* try again */
- X return FALSE;
- X
- X return TRUE;
- X}
- X
- XFILE *open_with_make_path (name)
- X char *name;
- X{
- X FILE *fp;
- X struct stat v_stat;
- X char buffer[1024];
- X
- X if (stat (name, &v_stat) >= 0)
- X {
- X if ((v_stat.st_mode & S_IFMT) != S_IFREG)
- X return NULL;
- X
- X if (!force)
- X {
- X for (;;)
- X {
- X fprintf (stderr, "%s OverWrite ?(Yes/No/All) ", name);
- X fflush (stderr);
- X gets (buffer);
- X if (buffer[0] == 'N' || buffer[0] == 'n')
- X return NULL;
- X if (buffer[0] == 'Y' || buffer[0] == 'y')
- X break;
- X if (buffer[0] == 'A' || buffer[0] == 'a')
- X {
- X force = TRUE;
- X break;
- X }
- X }
- X }
- X }
- X
- X fp = fopen (name, WMODE);
- X if (!fp)
- X {
- X errno = 0;
- X if (!make_parent_path (name))
- X return NULL;
- X
- X fp = fopen (name, WMODE);
- X if (!fp)
- X message ("Error:", name);
- X }
- X return fp;
- X}
- X
- X#ifdef MSDOS
- Xvoid dosname(char *name)
- X{
- X char *ptr, *first = NULL, *last = NULL;
- X char temp[8];
- X
- X for ( ptr = strchr(name, 0); ptr >= name; ptr-- )
- X if ( *ptr == '.' )
- X {
- X if ( last == NULL )
- X last = ptr;
- X }
- X else if ( (*ptr == '/') || (*ptr == '\\') )
- X {
- X first = ptr + 1;
- X break;
- X }
- X
- X if ( first == NULL )
- X first = name;
- X if ( last == NULL )
- X last = strchr(name, 0);
- X
- X for ( ptr = first; ptr < last; ptr++ )
- X if ( *ptr == '.' )
- X *ptr = '_';
- X
- X if ( strlen(last) > 4 )
- X last[4] = 0;
- X
- X if ( last - first > 8 )
- X {
- X strcpy(temp, last);
- X strcpy(first + 8, last);
- X }
- X}
- X#endif
- X
- Xextern int decode_lzhuf (), decode_larc ();
- Xextern int decode_stored_crc (), decode_stored_nocrc ();
- X
- Xextract_one (fp, hdr)
- X FILE *fp;
- X LzHeader *hdr;
- X{
- X FILE *ofp; /* output file */
- X char name[1024];
- X time_t utimebuf[2];
- X int crc;
- X int (*decode_proc)(); /* (ifp,ofp,original_size,name) */
- X int save_quiet;
- X
- X strcpy (name, hdr->name);
- X if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_REGULAR)
- X {
- X if (bcmp (hdr->method, LZHUFF1_METHOD, METHOD_TYPE_STRAGE) == 0)
- X decode_proc = decode_lzhuf;
- X else if ((bcmp (hdr->method, LZHUFF0_METHOD, METHOD_TYPE_STRAGE) == 0) ||
- X (bcmp (hdr->method, LARC4_METHOD, METHOD_TYPE_STRAGE) == 0))
- X decode_proc = (hdr->has_crc) ? decode_stored_crc : decode_stored_nocrc;
- X else if (bcmp (hdr->method, LARC5_METHOD, METHOD_TYPE_STRAGE) == 0)
- X decode_proc = decode_larc;
- X else
- X message ("Error:", "Sorry, Cannot Extract this method.");
- X
- X reading_filename = archive_name;
- X writting_filename = name;
- X if (output_to_stdout)
- X {
- X if (!quiet)
- X printf ("::::::::\r\n%s\r\n::::::::\r\n", name);
- X
- X if ( strlen(pager) != 0 )
- X ofp = popen(pager, WMODE);
- X else
- X ofp = stdout;
- X
- X save_quiet = quiet;
- X quiet = TRUE;
- X crc = (*decode_proc) (fp, ofp, hdr->original_size, name);
- X quiet = save_quiet;
- X
- X if ( strlen(pager) != 0 )
- X pclose(ofp);
- X }
- X else if (output_to_test)
- X {
- X ofp = fopen(NULLFILE, WMODE);
- X crc = (*decode_proc) (fp, ofp, hdr->original_size, name);
- X fclose(ofp);
- X }
- X else
- X {
- X#ifdef MSDOS
- X dosname(name);
- X#endif
- X if ((ofp = open_with_make_path (name)) == NULL)
- X return;
- X else
- X {
- X crc = (*decode_proc) (fp, ofp, hdr->original_size, name);
- X fclose (ofp);
- X }
- X }
- X
- X if (hdr->has_crc && (crc != hdr->crc))
- X if (output_to_test)
- X message ("Error:", "CRC failed\a");
- X else
- X error ("CRC failed\a");
- X }
- X else
- X {
- X /* NAME has trailing SLASH '/', (^_^) */
- X if (!output_to_stdout &&
- X !make_parent_path (name))
- X error (name);
- X }
- X
- X if (!output_to_stdout && !output_to_test)
- X {
- X utimebuf[0] = utimebuf[1] = hdr->unix_last_modified_stamp;
- X utime (name, utimebuf);
- X
- X#ifdef NOT_COMPATIBLE_MODE
- X setfilemode(name, hdr->attribute);
- X#else
- X chmod (name, hdr->unix_mode);
- X#endif
- X
- X#ifndef MSDOS
- X chown (name, hdr->unix_uid, hdr->unix_gid);
- X#endif
- X errno = 0;
- X }
- X}
- X
- X
- X/*
- X extract
- X */
- Xcmd_extract ()
- X{
- X LzHeader hdr;
- X long pos;
- X FILE *fp;
- X
- X if ((fp = fopen (archive_name, RMODE)) == NULL)
- X if (!expand_archive_name (expanded_archive_name, archive_name))
- X error (archive_name);
- X else
- X {
- X errno = 0;
- X fp = xfopen (expanded_archive_name, RMODE);
- X archive_name = expanded_archive_name;
- X }
- X
- X if (archive_is_msdos_sfx1 (archive_name))
- X {
- X skip_msdos_sfx1_code (fp);
- X }
- X
- X while (get_header (fp, &hdr))
- X {
- X if (need_file (hdr.name))
- X {
- X pos = ftell (fp);
- X extract_one (fp, &hdr);
- X fseek (fp, pos + hdr.packed_size, SEEK_SET);
- 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 return; /* previous write_header is not DUMMY. (^_^) */
- 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 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 extern rename();
- 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#ifdef ORIGINAL
- X if (rename(archive_name, backup_archive_name) < 0)
- X error (archive_name);
- X unlink(backup_archive_name);
- X#endif
- 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#ifdef ORIGINAL
- X if (!noexec && rename(temporary_name, new_archive_name) < 0)
- X#endif
- X
- X {
- X
- X if (stat (temporary_name, &v_stat) < 0)
- X error (temporary_name);
- 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}
- END_OF_lharc.c
- if test 49791 -ne `wc -c <lharc.c`; then
- echo shar: \"lharc.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f lhdir.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"lhdir.h\"
- else
- echo shar: Extracting \"lhdir.h\" \(1254 characters\)
- sed "s/^X//" >lhdir.h <<'END_OF_lhdir.h'
- X/*
- X * @(#) dir.h 1.4 87/11/06 Public Domain.
- X *
- X * A public domain implementation of BSD directory routines for
- X * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield),
- X * August 1897
- X * Ported to OS/2 by Kai Uwe Rommel and added scandir prototype
- X * December 1989
- X */
- X
- X#define rewinddir(dirp) seekdir(dirp, 0L)
- X
- X#define MAXNAMLEN 12
- X
- Xstruct direct
- X{
- X ino_t d_ino; /* a bit of a farce */
- X int d_reclen; /* more farce */
- X int d_namlen; /* length of d_name */
- X char d_name[MAXNAMLEN + 1]; /* garentee null termination */
- X};
- X
- Xstruct _dircontents
- X{
- X char *_d_entry;
- X struct _dircontents *_d_next;
- X};
- X
- Xtypedef struct _dirdesc
- X{
- X int dd_id; /* uniquely identify each open directory */
- X long dd_loc; /* where we are in directory entry is this */
- X struct _dircontents *dd_contents; /* pointer to contents of dir */
- X struct _dircontents *dd_cp; /* pointer to current position */
- X} DIR;
- X
- Xextern DIR *opendir(char *);
- Xextern struct direct *readdir(DIR *);
- Xextern void seekdir(DIR *, long);
- Xextern long telldir(DIR *);
- Xextern void closedir(DIR *);
- X
- Xextern int scandir(char *, struct direct ***,
- X int (*)(struct direct *), int (*)());
- END_OF_lhdir.h
- if test 1254 -ne `wc -c <lhdir.h`; then
- echo shar: \"lhdir.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f lhio.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"lhio.c\"
- else
- echo shar: Extracting \"lhio.c\" \(6280 characters\)
- sed "s/^X//" >lhio.c <<'END_OF_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}
- END_OF_lhio.c
- if test 6280 -ne `wc -c <lhio.c`; then
- echo shar: \"lhio.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f lhio.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"lhio.h\"
- else
- echo shar: Extracting \"lhio.h\" \(1388 characters\)
- sed "s/^X//" >lhio.h <<'END_OF_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
- END_OF_lhio.h
- if test 1388 -ne `wc -c <lhio.h`; then
- echo shar: \"lhio.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f lzhuf.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"lzhuf.c\"
- else
- echo shar: Extracting \"lzhuf.c\" \(22465 characters\)
- sed "s/^X//" >lzhuf.c <<'END_OF_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 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: */
- END_OF_lzhuf.c
- if test 22465 -ne `wc -c <lzhuf.c`; then
- echo shar: \"lzhuf.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f makefile -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"makefile\"
- else
- echo shar: Extracting \"makefile\" \(1707 characters\)
- sed "s/^X//" >makefile <<'END_OF_makefile'
- X# Makefile for LHArc UNIX
- X# Copyright(C) MCMLXXXIX Yooichi.Tagawa
- X# V0.01 Alpha Version 1989.05.28 Y.Tagawa
- X# V0.02 Alpha Version R2 1989.05.29 Y.Tagawa
- X# V0.03 Release #3 Beta Version 1989.07.02 Y.Tagawa
- X
- X#-----------------------------------------------------------------------
- X# DIRECTORY ACCESS DEPENDENDS...
- X# The default (no need swtich) is your machine has
- X# opendir(),readdir(),closedir() library and 'direct' structure used.
- X# If your machine has no opendir (), readdir (), closedir ()
- X# -DNONSYSTEM_DIR_LIBRARY
- X# and add lhdir.o into OBJS macro (see bellow)
- X# If your machine are 'dirent' (not 'direct') structure used,
- X# -DSYSV_SYSTEM_DIR
- X# Otherwise "Give up!"
- X# -DNODIRECTORY
- X#
- X#-----------------------------------------------------------------------
- X# MEMORY ACCESS STUFF
- X# Your machine has no BSTRING library (bcmp,bcopy,bzero).
- X# -DNOBSTRING
- X#
- X#-----------------------------------------------------------------------
- X# TIME STUFF
- X# Your include file '<sys/time.h>' has no 'struct tm', define this.
- X# -DSYSTIME_HAS_NO_TM
- X#
- X
- X# most of 4.[23]BSD
- X# - vax 4.[23]BSD, SONY NEWS 4.[23]BSD etc.
- X#SWITCHIES =
- X#OBJS = lharc.o lzhuf.o lhio.o
- X
- X# sample of System-V
- X# - NEC EWS4800
- X#-DSYSTIME_HAS_NO_TM
- XSWITCHIES = -DNOBSTRING -DSYSV_SYSTEM_DIR
- XOBJS = lharc.o lzhuf.o lhio.o rename.o
- X
- XCC = cc
- XCFLAGS = $(SWITCHIES)
- XLDFLAGS = -ldir -lx
- X
- X# Xlharc is test binary. Please rename to lharc at install.
- X# (see install target)
- Xall: xlharc
- X
- Xxlharc : $(OBJS)
- X $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS)
- X
- X# For Debugging LzHuff module.
- Xlzhuf : lzhuf.c
- X $(CC) $(CFLAGS) -DSELFMAIN -o $* $*.c
- X
- Xlzhuf.o lhio.o : lhio.h
- X
- Xclean:
- X rm -f core lharc.o lzhuf.o lhdir.o lhio.o lharc.tar lharc.tar.Z
- END_OF_makefile
- if test 1707 -ne `wc -c <makefile`; then
- echo shar: \"makefile\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f mktemp.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"mktemp.c\"
- else
- echo shar: Extracting \"mktemp.c\" \(412 characters\)
- sed "s/^X//" >mktemp.c <<'END_OF_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 */
- END_OF_mktemp.c
- if test 412 -ne `wc -c <mktemp.c`; then
- echo shar: \"mktemp.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f pipes.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"pipes.c\"
- else
- echo shar: Extracting \"pipes.c\" \(1116 characters\)
- sed "s/^X//" >pipes.c <<'END_OF_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}
- END_OF_pipes.c
- if test 1116 -ne `wc -c <pipes.c`; then
- echo shar: \"pipes.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f readme -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"readme\"
- else
- echo shar: Extracting \"readme\" \(1184 characters\)
- sed "s/^X//" >readme <<'END_OF_readme'
- X -*- Text -*-
- X
- XLHarc UNIX V0.03 Release #3 Beta Version
- X
- X This is FREEWARE. But it's BETA-VERSION.
- X
- X Please reply to me.
- X
- X Sorry, lharc.doc file are written in JAPANESE (Shift-JIS KANJI)
- X
- X Thank you.
- X
- X Yooichi.Tagawa
- X Nikkei-MIX ID: y.tagawa
- X------------------------------------------------------------------------
- X
- XHOW TO USE:
- X lharc {axevludmcp}[qnft] archive_file [files or directories...]
- X
- XCOMMAND:
- X KEY MEANS Like as (UNIX ar command)
- X --- ------------------------------ ------------------------------
- X a Append to archive. ar r AFILE files...
- X x,e EXtract from archive. ar x AFILE [files...]
- X v,l View/List archive contents. ar t AFILE [files...]
- X u append newer files to archive. ar ru AFILE files...
- X d Delete from archive. ar d AFILE files...
- X m Move to archive. ar m AFILE files...
- X c re-construct new archive file. rm AFILE; ar r AFILE files...
- X p Print to STANDARD-OUTPUT ar p AFILE [files...]
- X
- X
- XOPTIONS:
- X q quiet
- X n no execute (debugging option)
- X f force (over write at extract)
- X t text-mode (this is provisional option)
- X
- X------------------------------------------------------------------------------
- END_OF_readme
- if test 1184 -ne `wc -c <readme`; then
- echo shar: \"readme\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f rename.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"rename.c\"
- else
- echo shar: Extracting \"rename.c\" \(1793 characters\)
- sed "s/^X//" >rename.c <<'END_OF_rename.c'
- X/*
- X * $Author: chip $ $Date: 89/06/29 13:02:31 $
- X * $Header: rename.c,v 1.1 89/06/29 13:02:31 chip Exp $
- X * $Revision: 1.1 $
- X */
- X
- X/*
- X * Rename system call -- Replacement for Berzerkeley 4.2 rename system
- X * call that is missing in Xenix.
- X *
- X * By Marc Frajola and Chris Paris.
- X * Directory hack by Chip Salzenberg.
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <signal.h>
- X#include <errno.h>
- X
- Xrename(src,dest)
- X char *src; /* Source file to rename */
- X char *dest; /* Name for renamed file */
- X{
- X int status; /* Status returned from link system call */
- X struct stat stbuf; /* Buffer for statting destination file */
- X
- X /* Find out what the destination is: */
- X status = stat(dest,&stbuf);
- X if (status >= 0) {
- X /* See if the file is a regular file; if not, return error: */
- X if ((stbuf.st_mode & S_IFMT) != S_IFREG) {
- X return(-1);
- X }
- X }
- X
- X /* Unlink destination since it is a file: */
- X unlink(dest);
- X
- X /* Find out what the source is: */
- X status = stat(src,&stbuf);
- X if (status < 0)
- X return -1;
- X if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
- X {
- X /* Directory hack for SCO Xenix */
- X
- X static char mvdir[] = "/usr/lib/mv_dir";
- X void (*oldsigcld)();
- X int pid;
- X
- X oldsigcld = signal(SIGCLD, SIG_DFL);
- X while ((pid = fork()) == -1)
- X {
- X if (errno != EAGAIN)
- X return -1;
- X sleep(5);
- X }
- X if (pid == 0)
- X {
- X execl(mvdir, mvdir, src, dest, (char *) 0);
- X perror(mvdir);
- X exit(1);
- X }
- X if (wait(&status) != pid)
- X {
- X fprintf(stderr, "rename: wait failure\n");
- X status = -1;
- X }
- X (void) signal(SIGCLD, oldsigcld);
- X }
- X else
- X {
- X /* Link source to destination file: */
- X status = link(src,dest);
- X if (status != 0) {
- X return(-1);
- X }
- X status = unlink(src);
- X }
- X return((status == 0) ? 0 : (-1));
- X}
- END_OF_rename.c
- if test 1793 -ne `wc -c <rename.c`; then
- echo shar: \"rename.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of shell archive.
- exit 0
-
-
-