glenn@stsim.ocs.com (glenn ford) (03/28/90)
Here it is, I have tried posting to alt.sources and comp.sources.misc and have failed, so since this is for SCO XENIX people only, grab it! It should work under 386 Xenix as is, just type 'make' Glenn Ford BBS: 301-972-6131 HOME: 301-972-2310 UUCP: ..uunet!ocsmd!stsim #! /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
ron@mlfarm.uucp (Ronald Florence) (03/29/90)
In article <868@stsim.ocs.com> glenn@stsim.ocs.com (glenn ford) writes: > Here it is, I have tried posting to alt.sources and comp.sources.misc > and have failed, so since this is for SCO XENIX people only, grab it! > It should work under 386 Xenix as is, just type 'make' As far as I can see, the only changes from the original source are a couple of #ifdefs which effectively eliminate the calls to rename(). Since the source to LHARC and the source to rename (which seems not to be used in your code) have both been posted and are available in archive sites, why waste the bandwith for this re-posting? A short patch file would have sufficed. Some of us have to pay the phone bill for news. -- Ronald Florence {yale,uunet}!hsi!mlfarm!ron