Makefile 666 75616 51013 3235 5110114704 5710 # Makefile for LHArc UNIX # Copyright(C) MCMLXXXIX Yooichi.Tagawa # V0.01 Alpha Version 1989.05.28 Y.Tagawa # V0.02 Alpha Version R2 1989.05.29 Y.Tagawa # V0.03 Release #3 Beta Version 1989.07.02 Y.Tagawa #----------------------------------------------------------------------- # DIRECTORY ACCESS DEPENDENDS... # The default (no need swtich) is your machine has # opendir(),readdir(),closedir() library and 'direct' structure used. # If your machine has no opendir (), readdir (), closedir () # -DNONSYSTEM_DIR_LIBRARY # and add lhdir.o into OBJS macro (see bellow) # If your machine are 'dirent' (not 'direct') structure used, # -DSYSV_SYSTEM_DIR # Otherwise "Give up!" # -DNODIRECTORY # #----------------------------------------------------------------------- # MEMORY ACCESS STUFF # Your machine has no BSTRING library (bcmp,bcopy,bzero). # -DNOBSTRING # #----------------------------------------------------------------------- # TIME STUFF # Your include file '' has no 'struct tm', define this. # -DSYSTIME_HAS_NO_TM # # most of 4.[23]BSD # - vax 4.[23]BSD, SONY NEWS 4.[23]BSD etc. SWITCHIES = OBJS = lharc.o lzhuf.o lhio.o # sample of System-V # - NEC EWS4800 #SWITCHIES = -DNONSYSTEM_DIR_LIBRARY -DSYSTIME_HAS_NO_TM #OBJS = lharc.o lzhuf.o lhio.o lhdir.o CC = gcc CFLAGS = $(SWITCHIES) LDFLAGS = -s # Xlharc is test binary. Please rename to lharc at install. # (see install target) all: xlharc xlharc : $(OBJS) $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS) # For Debugging LzHuff module. lzhuf : lzhuf.c $(CC) $(CFLAGS) -DSELFMAIN -o $* $*.c lzhuf.o lhio.o : lhio.h clean: rm -f core lharc.o lzhuf.o lhdir.o lhio.o lharc.tar lharc.tar.Z dir.h 666 75616 51013 2346 5110114706 5203 /* * @(#) dir.h 1.4 87/11/06 Public Domain. * * A public domain implementation of BSD directory routines for * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), * August 1897 * Ported to OS/2 by Kai Uwe Rommel and added scandir prototype * December 1989 */ #define rewinddir(dirp) seekdir(dirp, 0L) #define MAXNAMLEN 12 struct direct { ino_t d_ino; /* a bit of a farce */ int d_reclen; /* more farce */ int d_namlen; /* length of d_name */ char d_name[MAXNAMLEN + 1]; /* garentee null termination */ }; struct _dircontents { char *_d_entry; struct _dircontents *_d_next; }; typedef struct _dirdesc { int dd_id; /* uniquely identify each open directory */ long dd_loc; /* where we are in directory entry is this */ struct _dircontents *dd_contents; /* pointer to contents of dir */ struct _dircontents *dd_cp; /* pointer to current position */ } DIR; extern DIR *opendir(char *); extern struct direct *readdir(DIR *); extern void seekdir(DIR *, long); extern long telldir(DIR *); extern void closedir(DIR *); extern int scandir(char *, struct direct ***, int (*)(struct direct *), int (*)()); AS_NO_TM #OBJS = lharc.o lzhuf.o lhio.o lhdir.o CC = gcc CFLAGS = $(SWITCHIES) LDFLAGS = -s # Xlharc is test binary. Please rename to lharc at install. # (see install target) all: xlharc xlharc : $(OBJS) $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS) # For Debugging LzHuff modudir_dos.c 666 75616 51013 7003 5110114707 6037 /* * @(#)dir.c 1.4 87/11/06 Public Domain. * * A public domain implementation of BSD directory routines for * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), * August 1897 * Modified to use modern MS C library functions by Kai Uwe Rommel * December 1989 */ #include #include #include #include #include #include #ifndef NULL # define NULL 0 #endif /* NULL */ #ifndef MAXPATHLEN # define MAXPATHLEN 255 #endif /* MAXPATHLEN */ /* attribute stuff */ #define A_RONLY 0x01 #define A_HIDDEN 0x02 #define A_SYSTEM 0x04 #define A_LABEL 0x08 #define A_DIR 0x10 #define A_ARCHIVE 0x20 #define Newisnull(a, t) ((a = (t *) malloc(sizeof(t))) == (t *) NULL) #define ATTRIBUTES (A_DIR) /* #define ATTRIBUTES (A_DIR | A_HIDDEN | A_SYSTEM) */ /* #define ATTRIBUTES (A_RONLY | A_SYSTEM | A_DIR) */ static char *getdirent(char *); static void free_dircontents(struct _dircontents *); static struct find_t find; DIR * opendir(name) char *name; { struct stat statb; DIR *dirp; char c; char *s; struct _dircontents *dp; char nbuf[MAXPATHLEN + 1]; if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR) return (DIR *) NULL; if (Newisnull(dirp, DIR)) return (DIR *) NULL; if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/') (void) strcat(strcpy(nbuf, name), "\\*.*"); else (void) strcat(strcpy(nbuf, name), "*.*"); dirp->dd_loc = 0; dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL; if ((s = getdirent(nbuf)) == (char *) NULL) return dirp; do { if (Newisnull(dp, struct _dircontents) || (dp->_d_entry = malloc((unsigned) (strlen(s) + 1))) == (char *) NULL) { if (dp) free((char *) dp); free_dircontents(dirp->dd_contents); return (DIR *) NULL; } if (dirp->dd_contents) dirp->dd_cp = dirp->dd_cp->_d_next = dp; else dirp->dd_contents = dirp->dd_cp = dp; (void) strcpy(dp->_d_entry, s); dp->_d_next = (struct _dircontents *) NULL; } while ((s = getdirent((char *) NULL)) != (char *) NULL); dirp->dd_cp = dirp->dd_contents; return dirp; } void closedir(dirp) DIR *dirp; { free_dircontents(dirp->dd_contents); free((char *) dirp); } struct direct * readdir(dirp) DIR *dirp; { static struct direct dp; if (dirp->dd_cp == (struct _dircontents *) NULL) return (struct direct *) NULL; dp.d_namlen = dp.d_reclen = strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry)); strlwr(dp.d_name); /* JF */ dp.d_ino = 0; dirp->dd_cp = dirp->dd_cp->_d_next; dirp->dd_loc++; return &dp; } void seekdir(dirp, off) DIR *dirp; long off; { long i = off; struct _dircontents *dp; if (off < 0) return; for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next) ; dirp->dd_loc = off - (i + 1); dirp->dd_cp = dp; } long telldir(dirp) DIR *dirp; { return dirp->dd_loc; } static void free_dircontents(dp) struct _dircontents *dp; { struct _dircontents *odp; while (dp) { if (dp->_d_entry) free(dp->_d_entry); dp = (odp = dp)->_d_next; free((char *) odp); } } static char *getdirent(dir) char *dir; { int done; if (dir != (char *) NULL) done = _dos_findfirst(dir, ATTRIBUTES, &find); else /* get next entry */ done = _dos_findnext(&find); if (done==0) return find.name; else return (char *) NULL; } setfilemode(char *name, unsigned attr) { _dos_setfileattr(name, attr); } getfilemode(char *name, unsigned *attr) { _dos_getfileattr(name, attr); } endif /* MAXPATHLEN */ /* attribute stuff */ #define A_RONLY 0x01 #define A_HIDDEN 0x02 #define A_SYSTEM 0x04 #define A_LABEL 0x08 #define A_DIR 0x10 #define A_ARCHIVE 0x20 #define Newisnull(a, t) ((a = (t *) malloc(sizeof(t))) == (t *) NULL) #define ATTRIBUTES (A_DIR) /* #define ATTRIBUTES (A_DIR | A_HIDDEN | A_SYSTEM) */ /* #define ATTRIBUTES (A_RONLY | A_SYSTEM | A_DIR) */ static char *getdirent(char *); static void free_dircontents(struct _dircontents *); static struct findir_os2.c 666 75616 51013 7375 5110114707 5771 /* * @(#)dir.c 1.4 87/11/06 Public Domain. * * A public domain implementation of BSD directory routines for * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), * August 1897 * Ported to OS/2 by Kai Uwe Rommel * December 1989 */ #include #include #include #include #include #define INCL_NOPM #include #ifndef NULL # define NULL 0 #endif /* NULL */ #ifndef MAXPATHLEN # define MAXPATHLEN 255 #endif /* MAXPATHLEN */ /* attribute stuff */ #define A_RONLY 0x01 #define A_HIDDEN 0x02 #define A_SYSTEM 0x04 #define A_LABEL 0x08 #define A_DIR 0x10 #define A_ARCHIVE 0x20 #define Newisnull(a, t) ((a = (t *) malloc(sizeof(t))) == (t *) NULL) #define ATTRIBUTES (A_DIR) /* #define ATTRIBUTES (A_DIR | A_HIDDEN | A_SYSTEM) */ /* #define ATTRIBUTES (A_RONLY | A_SYSTEM | A_DIR) */ static char *getdirent(char *); static void free_dircontents(struct _dircontents *); static HDIR hdir; static USHORT count; static FILEFINDBUF find; DIR * opendir(name) char *name; { struct stat statb; DIR *dirp; char c; char *s; struct _dircontents *dp; char nbuf[MAXPATHLEN + 1]; if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR) return (DIR *) NULL; if (Newisnull(dirp, DIR)) return (DIR *) NULL; if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/') (void) strcat(strcpy(nbuf, name), "\\*.*"); else (void) strcat(strcpy(nbuf, name), "*.*"); dirp->dd_loc = 0; dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL; if ((s = getdirent(nbuf)) == (char *) NULL) return dirp; do { if (Newisnull(dp, struct _dircontents) || (dp->_d_entry = malloc((unsigned) (strlen(s) + 1))) == (char *) NULL) { if (dp) free((char *) dp); free_dircontents(dirp->dd_contents); return (DIR *) NULL; } if (dirp->dd_contents) dirp->dd_cp = dirp->dd_cp->_d_next = dp; else dirp->dd_contents = dirp->dd_cp = dp; (void) strcpy(dp->_d_entry, s); dp->_d_next = (struct _dircontents *) NULL; } while ((s = getdirent((char *) NULL)) != (char *) NULL); dirp->dd_cp = dirp->dd_contents; return dirp; } void closedir(dirp) DIR *dirp; { free_dircontents(dirp->dd_contents); free((char *) dirp); } struct direct * readdir(dirp) DIR *dirp; { static struct direct dp; if (dirp->dd_cp == (struct _dircontents *) NULL) return (struct direct *) NULL; dp.d_namlen = dp.d_reclen = strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry)); strlwr(dp.d_name); /* JF */ dp.d_ino = 0; dirp->dd_cp = dirp->dd_cp->_d_next; dirp->dd_loc++; return &dp; } void seekdir(dirp, off) DIR *dirp; long off; { long i = off; struct _dircontents *dp; if (off < 0) return; for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next) ; dirp->dd_loc = off - (i + 1); dirp->dd_cp = dp; } long telldir(dirp) DIR *dirp; { return dirp->dd_loc; } static void free_dircontents(dp) struct _dircontents *dp; { struct _dircontents *odp; while (dp) { if (dp->_d_entry) free(dp->_d_entry); dp = (odp = dp)->_d_next; free((char *) odp); } } static char *getdirent(dir) char *dir; { int done; if (dir != (char *) NULL) { /* get first entry */ hdir = HDIR_CREATE; count = 1; done = DosFindFirst(dir, &hdir, ATTRIBUTES, &find, sizeof(find), &count, 0L); } else /* get next entry */ done = DosFindNext(hdir, &find, sizeof(find), &count); if (done==0) return find.achName; else { DosFindClose(hdir); return (char *) NULL; } } setfilemode(char *name, unsigned attr) { DosSetFileMode(name, attr, 0L); } getfilemode(char *name, unsigned *attr) { DosQFileMode(name, (PUSHORT) attr, 0L); } lharc.c 666 75616 51013 141107 5110115257 5552 /*----------------------------------------------------------------------*/ /* LHarc Archiver Driver for UNIX */ /* */ /* Copyright(C) MCMLXXXIX Yooichi.Tagawa */ /* Thanks to H.Yoshizaki. (MS-DOS LHarc) */ /* */ /* V0.00 Original 1988.05.23 Y.Tagawa */ /* V0.01 Alpha Version (for 4.2BSD) 1989.05.28 Y.Tagawa */ /* V0.02 Alpha Version Rel.2 1989.05.29 Y.Tagawa */ /* V0.03 Release #3 Beta Version 1989.07.02 Y.Tagawa */ /* V0.03a Fix few bug 1989.07.03 Y.Tagawa */ /* V0.04 A lot of bugs fixed, strict mode 1990.01.13 Kai Uwe Rommel */ /* V1.00 f and t commands, v option added 1990.01.27 Kai Uwe Rommel */ /*----------------------------------------------------------------------*/ #include #include #include #include #include #ifdef PROF #include #endif #define STRICT #define FASTCOPY #ifdef MSDOS #include extern unsigned char _osmode; extern FILE *popen(); extern pclose(); #define ftruncate chsize #define mktemp Mktemp #define SYSTIME_HAS_NO_TM #define NOBSTRING #define SYSNAME (_osmode ? "OS/2" : "MS-DOS") #define OUR_EXTEND (_osmode ? EXTEND_OS2 : EXTEND_MSDOS) #define FILENAME_LENGTH 128 #define NULLFILE "nul" #define TMP_FILENAME_TEMPLATE "lhXXXXXX" #define NOT_COMPATIBLE_MODE #define RMODE "rb" #define WMODE "wb" #else #include #include #define SYSNAME "UNIX" #define OUR_EXTEND EXTEND_UNIX #define FILENAME_LENGTH 1024 #define NULLFILE "/dev/null" #define RMODE "r" #define WMODE "w" #endif #ifdef SYSTIME_HAS_NO_TM /* most of System V, define SYSTIME_HAS_NO_TM */ #include #endif /* #include */ #include /*----------------------------------------------------------------------*/ /* DIRECTORY ACCESS STUFF */ /*----------------------------------------------------------------------*/ #ifndef NODIRECTORY #ifdef SYSV_SYSTEM_DIR #include #define DIRENTRY struct dirent #define NAMREN(p) strlen (p->d_name) #else /* not SYSV_SYSTEM_DIR */ #ifdef NONSYSTEM_DIR_LIBRARY #include "lhdir.h" #else /* not NONSYSTEM_DIR_LIBRARY */ #include #endif /* not NONSYSTEM_DIR_LIBRARY */ #define DIRENTRY struct direct #define NAMLEN(p) p->d_namlen extern DIR *opendir (); extern struct direct *readdir (); #endif /* not SYSV_SYSTEM_DIR */ #endif /*----------------------------------------------------------------------*/ /* FILE ATTRIBUTES */ /*----------------------------------------------------------------------*/ /* If file mode is not compatible between your Machine/OS and LHarc standard UNIX file mode. (See UNIX Manual stat(1), , and/or below UNIX_* difinitions. ) */ /* #define NOT_COMPATIBLE_MODE */ /*----------------------------------------------------------------------*/ /* MEMORY FUNCTIONS */ /*----------------------------------------------------------------------*/ #ifdef NOBSTRING #ifdef __ANSI__ #include "mem.h" #define bcmp(a,b,n) memcmp ((a),(b),(n)) #define bcopy(s,d,n) memmove((d),(s),(n)) #define bzero(d,n) memset((d),0,(n)) #else /* not __ANSI__ */ #include "memory.h" #define bcmp(a,b,n) memcmp ((a),(b),(n)) #define bcopy(s,d,n) memcpy ((d),(s),(n)) /* movmem((s),(d),(n)) */ #define bzero(d,n) memset((d),0,(n)) #endif /* not __ANSI__ */ #endif /* NOBSTRING */ /*----------------------------------------------------------------------*/ /* YOUR CUSTOMIZIES */ /*----------------------------------------------------------------------*/ /* These difinitions are changable to you like. */ /* #define ARCHIVENAME_EXTENTION ".LZH" */ /* #define TMP_FILENAME_TEMPLATE "/tmp/lhXXXXXX" */ /* #define BACKUPNAME_EXTENTION ".BAK" */ /* #define MULTIBYTE_CHAR */ #define SJC_FIRST_P(c) \ (((unsigned char)(c) >= 0x80) && \ (((unsigned char)(c) < 0xa0) || \ ((unsigned char)(c) >= 0xe0) && \ ((unsigned char)(c) < 0xfd))) #define SJC_SECOND_P(c) \ (((unsigned char)(c) >= 0x40) && \ ((unsigned char)(c) < 0xfd) && \ ((ungigned char)(c) != 0x7f)) #ifdef MULTIBYTE_CHAR #define MULTIBYTE_FIRST_P SJC_FIRST_P #define MULTIBYTE_SECOND_P SJC_SECOND_P #endif /*----------------------------------------------------------------------*/ /* OTHER DIFINITIONS */ /*----------------------------------------------------------------------*/ #ifndef SEEK_SET #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 #endif /* non-integral functions */ extern struct tm *localtime (); extern char *getenv (); extern char *malloc (); extern char *realloc (); extern int rson[]; /* external variables */ extern int errno; #define FALSE 0 #define TRUE 1 typedef int boolean; /*----------------------------------------------------------------------*/ /* LHarc FILE DIFINITIONS */ /*----------------------------------------------------------------------*/ #define METHOD_TYPE_STRAGE 5 #define LZHUFF0_METHOD "-lh0-" #define LZHUFF1_METHOD "-lh1-" #define LARC4_METHOD "-lz4-" #define LARC5_METHOD "-lz5-" #define I_HEADER_SIZE 0 #define I_HEADER_CHECKSUM 1 #define I_METHOD 2 #define I_PACKED_SIZE 7 #define I_ORIGINAL_SIZE 11 #define I_LAST_MODIFIED_STAMP 15 #define I_ATTRIBUTE 19 #define I_NAME_LENGTH 21 #define I_NAME 22 #define I_CRC 22 /* + name_length */ #define I_EXTEND_TYPE 24 /* + name_length */ #define I_MINOR_VERSION 25 /* + name_length */ #define I_UNIX_LAST_MODIFIED_STAMP 26 /* + name_length */ #define I_UNIX_MODE 30 /* + name_length */ #define I_UNIX_UID 32 /* + name_length */ #define I_UNIX_GID 34 /* + name_length */ #define I_UNIX_EXTEND_BOTTOM 36 /* + name_length */ #define EXTEND_GENERIC 0 #define EXTEND_UNIX 'U' #define EXTEND_MSDOS 'M' #define EXTEND_MACOS 'm' #define EXTEND_OS9 '9' #define EXTEND_OS2 '2' #define EXTEND_OS68K 'K' #define EXTEND_OS386 '3' #define EXTEND_HUMAN 'H' #define EXTEND_CPM 'C' #define EXTEND_FLEX 'F' #define GENERIC_ATTRIBUTE 0x20 #define GENERIC_DIRECTORY_ATTRIBUTE 0x10 #define CURRENT_UNIX_MINOR_VERSION 0x00 typedef struct LzHeader { unsigned char header_size; char method[METHOD_TYPE_STRAGE]; long packed_size; long original_size; long last_modified_stamp; unsigned short attribute; char name[256]; unsigned short crc; boolean has_crc; unsigned char extend_type; unsigned char minor_version; /* extend_type == EXTEND_UNIX and convert from other type. */ time_t unix_last_modified_stamp; unsigned short unix_mode; unsigned short unix_uid; unsigned short unix_gid; } LzHeader; #define UNIX_FILE_TYPEMASK 0170000 #define UNIX_FILE_REGULAR 0100000 #define UNIX_FILE_DIRECTORY 0040000 #define UNIX_SETUID 0004000 #define UNIX_SETGID 0002000 #define UNIX_STYCKYBIT 0001000 #define UNIX_OWNER_READ_PERM 0000400 #define UNIX_OWNER_WRITE_PERM 0000200 #define UNIX_OWNER_EXEC_PERM 0000100 #define UNIX_GROUP_READ_PERM 0000040 #define UNIX_GROUP_WRITE_PERM 0000020 #define UNIX_GROUP_EXEC_PERM 0000010 #define UNIX_OTHER_READ_PERM 0000004 #define UNIX_OTHER_WRITE_PERM 0000002 #define UNIX_OTHER_EXEC_PERM 0000001 #define UNIX_RW_RW_RW 0000666 #define LZHEADER_STRAGE 256 /*----------------------------------------------------------------------*/ /* PROGRAM */ /*----------------------------------------------------------------------*/ #define CMD_UNKNOWN 0 #define CMD_EXTRACT 1 #define CMD_APPEND 2 #define CMD_VIEW 3 int cmd = CMD_UNKNOWN; char **cmd_filev; int cmd_filec; char *archive_name; char expanded_archive_name[FILENAME_LENGTH]; char temporary_name[FILENAME_LENGTH]; char pager[FILENAME_LENGTH]; /* options */ boolean quiet = FALSE; boolean text_mode = FALSE; /*boolean verbose = FALSE; */ boolean noexec = FALSE; /* debugging option */ boolean force = FALSE; boolean prof = FALSE; /* view flags */ boolean long_format_listing = FALSE; /* extract flags */ boolean output_to_test = FALSE; boolean output_to_stdout = FALSE; /* append flags */ boolean new_archive = FALSE; boolean update_if_newer = FALSE; boolean update_freshen = FALSE; boolean delete_after_append = FALSE; boolean delete_from_archive = FALSE; boolean remove_temporary_at_error = FALSE; /*----------------------------------------------------------------------*/ /* NOTES : Text File Format */ /* GENERATOR NewLine */ /* [generic] 0D 0A */ /* [MS-DOS] 0D 0A */ /* [MacOS] 0D */ /* [UNIX] 0A */ /*----------------------------------------------------------------------*/ char *myname; void userbreak(void) { error("Interrupt."); } main (argc, argv) int argc; char *argv[]; { char *p; myname = argv[0]; signal(SIGINT, userbreak); #ifdef PROF PROFINIT(PT_USER|PT_USEKP, NULL); PROFCLEAR(PT_USER); PROFON(PT_USER); #endif if (argc < 3) print_tiny_usage_and_exit (); /* commands */ #ifdef MSDOS switch (tolower(argv[1][0])) #else switch (argv[1][0]) #endif { case 'x': case 'e': cmd = CMD_EXTRACT; break; case 't': output_to_test = TRUE; cmd = CMD_EXTRACT; break; case 'p': output_to_stdout = TRUE; cmd = CMD_EXTRACT; break; case 'c': new_archive = TRUE; cmd = CMD_APPEND; break; case 'a': cmd = CMD_APPEND; break; case 'd': delete_from_archive = TRUE; cmd = CMD_APPEND; break; case 'u': update_if_newer = TRUE; cmd = CMD_APPEND; break; case 'f': update_if_newer = update_freshen = TRUE; cmd = CMD_APPEND; break; case 'm': delete_after_append = TRUE; cmd = CMD_APPEND; break; case 'v': cmd = CMD_VIEW; break; case 'l': long_format_listing = TRUE; cmd = CMD_VIEW; break; case 'h': default: print_tiny_usage_and_exit (); } /* options */ p = &argv[1][1]; for (p = &argv[1][1]; *p; p++) { #ifdef MSDOS switch (tolower(*p)) #else switch (*p) #endif { case 'q': quiet = TRUE; break; case 'f': force = TRUE; break; /* case 'p': prof = TRUE; break; */ /* case 'v': verbose = TRUE; break; */ case 'v': strcpy(pager, p + 1); *(p + 1) = 0; break; case 't': text_mode = TRUE; break; case 'n': noexec = TRUE; break; default: fprintf (stderr, "unknown option '%c'.\n", *p); exit (1); } } /* archive file name */ archive_name = argv[2]; /* target file name */ cmd_filec = argc - 3; cmd_filev = argv + 3; sort_files (); switch (cmd) { case CMD_EXTRACT: cmd_extract (); break; case CMD_APPEND: cmd_append (); break; case CMD_VIEW: cmd_view (); break; } #ifdef PROF PROFOFF(PT_USER); PROFDUMP(PT_USER, "profile.out"); PROFFREE(PT_USER); #endif exit (0); } print_tiny_usage_and_exit () { printf("\nC-LHarc for %s Version 1.00 (C) 1989-1990 Y.Tagawa, Kai Uwe Rommel\n" "\nUsage: %s {axevlufdmctp}[qnftv] archive_file [files or directories...]\n", SYSNAME, myname); printf("\nCommands: Options:\n" " a Append q quiet\n" " x,e EXtract n no execute\n" " v,l View/List f force (over write at extract)\n" " u Update t files are TEXT files\n" " f Freshen v use file pager for p command\n" " d Delete\n" " m Move\n" " c re-Construct new archive\n" " t Test archive\n" " p Print to STDOUT\n"); exit (1); } message (title, msg) char *title, *msg; { fprintf (stderr, "%s ", myname); if (errno == 0) fprintf (stderr, "%s %s\n", title, msg); else perror (msg); } warning (msg) char *msg; { message ("Warning:", msg); } error (msg) char *msg; { message ("Error:", msg); if (remove_temporary_at_error) { #ifdef MSDOS fcloseall(); #endif unlink (temporary_name); } exit (1); } char *writting_filename; char *reading_filename; write_error () { error (writting_filename); } read_error () { error (reading_filename); } /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ boolean expand_archive_name (dst, src) char *dst, *src; { register char *p, *dot; strcpy (dst, src); for (p = dst, dot = (char*)0; *p; p++) if (*p == '.') dot = p; else if (*p == '/' || *p == '\\') dot = (char*)0; if (dot) p = dot; #ifdef ARCHIVENAME_EXTENTION strcpy (p, ARCHIVENAME_EXTENTION); #else strcpy (p, ".lzh"); #endif return (strcmp (dst, src) != 0); } #ifdef MSDOS #define STRING_COMPARE(a,b) stricmp((a),(b)) #else #define STRING_COMPARE(a,b) strcmp((a),(b)) #endif int sort_by_ascii (a, b) char **a, **b; { return STRING_COMPARE (*a, *b); } sort_files () { qsort (cmd_filev, cmd_filec, sizeof (char*), sort_by_ascii); } #ifndef MSDOS char *strdup (string) char *string; { int len = strlen (string) + 1; char *p = malloc (len); bcopy (string, p, len); return p; } #endif #ifdef NODIRECTORY /* please need your imprementation */ boolean find_files (name, v_filec, v_filev) char *name; int *v_filec; char ***v_filev; { return FALSE; /* DUMMY */ } #else boolean find_files (name, v_filec, v_filev) char *name; int *v_filec; char ***v_filev; { char newname[FILENAME_LENGTH]; int len, n; DIR *dirp; DIRENTRY *dp; int alloc_size = 64; /* any (^_^) */ char **filev; int filec = 0; if ( strcmp(name, ".") == 0 ) newname[0] = 0; else strcpy (newname, name); len = strlen (newname); dirp = opendir (name); if (dirp) { filev = (char**)malloc (alloc_size * sizeof(char *)); if (!filev) error ("not enough memory"); for (dp = readdir (dirp); dp != NULL; dp = readdir (dirp)) { n = NAMLEN (dp); if ( #ifndef MSDOS (dp->d_ino != 0) && #endif ((dp->d_name[0] != '.') || ((n != 1) && ((dp->d_name[1] != '.') || (n != 2)))) && /* exclude '.' and '..' */ (strcmp (dp->d_name, temporary_name) != 0) && (strcmp (dp->d_name, archive_name) != 0)) { if ((len != 0) && (newname[len-1] != '/') && (newname[len-1] != '\\')) { #ifdef MSDOS newname[len] = '\\'; #else newname[len] = '/'; #endif strncpy (newname+len+1, dp->d_name, n); newname[len+n+1] = '\0'; } else { strncpy (newname+len, dp->d_name, n); newname[len+n] = '\0'; } filev[filec++] = strdup (newname); if (filec == alloc_size) { alloc_size += 64; filev = (char**)realloc (filev, alloc_size * sizeof(char *)); } } } closedir (dirp); } *v_filev = filev; *v_filec = filec; if (dirp) { qsort (filev, filec, sizeof (char*), sort_by_ascii); return TRUE; } else return FALSE; } #endif free_files (filec, filev) int filec; char **filev; { int i; for (i = 0; i < filec; i ++) free (filev[i]); free (filev); } /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ int calc_sum (p, len) register char *p; register int len; { register int sum; for (sum = 0; len; len--) sum += *p++; return sum & 0xff; } unsigned char *get_ptr; #define setup_get(PTR) get_ptr = (unsigned char*)(PTR) #define get_byte() (*get_ptr++) #define put_ptr get_ptr #define setup_put(PTR) put_ptr = (unsigned char*)(PTR) #define put_byte(c) *put_ptr++ = (unsigned char)(c) unsigned short get_word () { int b0, b1; b0 = get_byte (); b1 = get_byte (); return (b1 << 8) + b0; } put_word (v) unsigned int v; { put_byte (v); put_byte (v >> 8); } long get_longword () { long b0, b1, b2, b3; b0 = get_byte (); b1 = get_byte (); b2 = get_byte (); b3 = get_byte (); return (b3 << 24) + (b2 << 16) + (b1 << 8) + b0; } put_longword (v) long v; { put_byte (v); put_byte (v >> 8); put_byte (v >> 16); put_byte (v >> 24); } msdos_to_unix_filename (name, len) register char *name; register int len; { register int i; #ifdef MULTIBYTE_CHAR for (i = 0; i < len; i ++) { if (MULTIBYTE_FIRST_P (name[i]) && MULTIBYTE_SECOND_P (name[i+1])) i ++; #ifndef MSDOS else if (name[i] == '\\') name[i] = '/'; #endif else if (isupper (name[i])) name[i] = tolower (name[i]); } #else for (i = 0; i < len; i ++) { #ifndef MSDOS if (name[i] == '\\') name[i] = '/'; else #endif if (isupper (name[i])) name[i] = tolower (name[i]); } #endif } generic_to_unix_filename (name, len) register char *name; register int len; { register int i; boolean lower_case_used = FALSE; #ifdef MULTIBYTE_CHAR for (i = 0; i < len; i ++) { if (MULTIBYTE_FIRST_P (name[i]) && MULTIBYTE_SECOND_P (name[i+1])) i ++; else if (islower (name[i])) { lower_case_used = TRUE; break; } } for (i = 0; i < len; i ++) { if (MULTIBYTE_FIRST_P (name[i]) && MULTIBYTE_SECOND_P (name[i+1])) i ++; #ifndef MSDOS else if (name[i] == '\\') name[i] = '/'; #endif else if (!lower_case_used && isupper (name[i])) name[i] = tolower (name[i]); } #else for (i = 0; i < len; i ++) if (islower (name[i])) { lower_case_used = TRUE; break; } for (i = 0; i < len; i ++) { #ifndef MSDOS if (name[i] == '\\') name[i] = '/'; else #endif if (!lower_case_used && isupper (name[i])) name[i] = tolower (name[i]); } #endif } macos_to_unix_filename (name, len) register char *name; register int len; { register int i; for (i = 0; i < len; i ++) { if (name[i] == ':') name[i] = '/'; else if (name[i] == '/') name[i] = ':'; } } /*----------------------------------------------------------------------*/ /* */ /* Generic stamp format: */ /* */ /* 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 */ /* |<-------- year ------->|<- month ->|<-- day -->| */ /* */ /* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 */ /* |<--- hour --->|<---- minute --->|<- second*2 ->| */ /* */ /*----------------------------------------------------------------------*/ long gettz () { #ifdef MSDOS return timezone; #else struct timeval tp; struct timezone tzp; gettimeofday (&tp, &tzp); /* specific to 4.3BSD */ /* return (tzp.tz_minuteswest * 60 + (tzp.tz_dsttime != 0 ? 60L * 60L : 0));*/ return (tzp.tz_minuteswest * 60); #endif } #ifdef NOT_USED struct tm *msdos_to_unix_stamp_tm (a) long a; { static struct tm t; t.tm_sec = ( a & 0x1f) * 2; t.tm_min = (a >> 5) & 0x3f; t.tm_hour = (a >> 11) & 0x1f; t.tm_mday = (a >> 16) & 0x1f; t.tm_mon = (a >> 16+5) & 0x0f - 1; t.tm_year = ((a >> 16+9) & 0x7f) + 80; return &t; } #endif time_t generic_to_unix_stamp (t) long t; { struct tm tm; long longtime; static unsigned int dsboy[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; unsigned long days; tm.tm_year = ((int)(t >> 25) & 0x7f) + 80; tm.tm_mon = ((int)(t >> 21) & 0x0f) - 1; /* 0..11 means Jan..Dec */ tm.tm_mday = (int)(t >> 16) & 0x1f; /* 1..31 means 1st,...31st */ tm.tm_hour = ((int)t >> 11) & 0x1f; tm.tm_min = ((int)t >> 5) & 0x3f; tm.tm_sec = ((int)t & 0x1f) * 2; #ifdef MSDOS longtime = mktime(&tm); #else /* Calculate days since 1970.01.01 */ days = (365 * (tm.tm_year - 70) + /* days due to whole years */ (tm.tm_year - 70 + 1) / 4 + /* days due to leap years */ dsboy[tm.tm_mon] + /* days since beginning of this year */ tm.tm_mday-1); /* days since beginning of month */ if ((tm.tm_year % 4 == 0) && (tm.tm_year % 400 != 0) && (tm.tm_mon >= 2)) /* if this is a leap year and month */ days++; /* is March or later, add a day */ /* Knowing the days, we can find seconds */ longtime = (((days * 24) + tm.tm_hour) * 60 + tm.tm_min) * 60 + tm.tm_sec; longtime += gettz (); /* adjust for timezone */ #endif /* special case: if MSDOS format date and time were zero, then we set time to be zero here too. */ if (t == 0) longtime = 0; /* LONGTIME is now the time in seconds, since 1970/01/01 00:00:00. */ return (time_t)longtime; } long unix_to_generic_stamp (t) time_t t; { struct tm *tm = localtime (&t); unsigned long stamp; stamp = ( ((long)(tm->tm_year - 80)) << 25 ); stamp += ( ((long)(tm->tm_mon + 1)) << 21 ); stamp += ( ((long)(tm->tm_mday)) << 16 ); stamp += ( ((long)(tm->tm_hour)) << 11 ); stamp += ( ((long)(tm->tm_min)) << 5 ); stamp += ( ((long)(tm->tm_sec)) >> 1 ); return stamp; } /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ boolean get_header (fp, hdr) FILE *fp; register LzHeader *hdr; { int header_size; int name_length; char data[LZHEADER_STRAGE]; int checksum; int i; bzero (hdr, sizeof (LzHeader)); if (((header_size = getc (fp)) == EOF) || (header_size == 0)) { return FALSE; /* finish */ } if (fread (data + I_HEADER_CHECKSUM, sizeof (char), header_size + 1, fp) < header_size + 1) { error ("Invalid header (LHarc file ?)\a"); return FALSE; /* finish */ } setup_get (data + I_HEADER_CHECKSUM); checksum = calc_sum (data + I_METHOD, header_size); if (get_byte () != checksum) warning ("Checksum error (LHarc file?)\a"); hdr->header_size = header_size; bcopy (data + I_METHOD, hdr->method, METHOD_TYPE_STRAGE); #ifdef OLD if ((bcmp (hdr->method, LZHUFF1_METHOD, METHOD_TYPE_STRAGE) != 0) && (bcmp (hdr->method, LZHUFF0_METHOD, METHOD_TYPE_STRAGE) != 0) && (bcmp (hdr->method, LARC5_METHOD, METHOD_TYPE_STRAGE) != 0) && (bcmp (hdr->method, LARC4_METHOD, METHOD_TYPE_STRAGE) != 0)) { warning ("Unknown method (LHarc file ?)"); return FALSE; /* invalid method */ } #endif setup_get (data + I_PACKED_SIZE); hdr->packed_size = get_longword (); hdr->original_size = get_longword (); hdr->last_modified_stamp = get_longword (); hdr->attribute = get_word (); name_length = get_byte (); for (i = 0; i < name_length; i ++) hdr->name[i] =(char)get_byte (); hdr->name[name_length] = '\0'; /* defaults for other type */ hdr->unix_mode = UNIX_FILE_REGULAR | UNIX_RW_RW_RW; hdr->unix_gid = 0; hdr->unix_uid = 0; if (header_size - name_length >= 24) { /* EXTEND FORMAT */ hdr->crc = get_word (); hdr->extend_type = get_byte (); hdr->minor_version = get_byte (); hdr->has_crc = TRUE; } else if (header_size - name_length == 22) { /* Generic with CRC */ hdr->crc = get_word (); hdr->extend_type = EXTEND_GENERIC; hdr->has_crc = TRUE; } else if (header_size - name_length == 20) { /* Generic no CRC */ hdr->extend_type = EXTEND_GENERIC; hdr->has_crc = FALSE; } else { warning ("Unknown header (LHarc file ?)"); return FALSE; } switch (hdr->extend_type) { case EXTEND_MSDOS: msdos_to_unix_filename (hdr->name, name_length); hdr->unix_last_modified_stamp = generic_to_unix_stamp (hdr->last_modified_stamp); break; case EXTEND_UNIX: hdr->unix_last_modified_stamp = (time_t)get_longword (); hdr->unix_mode = get_word (); hdr->unix_uid = get_word (); hdr->unix_gid = get_word (); break; case EXTEND_MACOS: macos_to_unix_filename (hdr->name, name_length); hdr->unix_last_modified_stamp = generic_to_unix_stamp (hdr->last_modified_stamp); break; default: generic_to_unix_filename (hdr->name, name_length); hdr->unix_last_modified_stamp = generic_to_unix_stamp (hdr->last_modified_stamp); } return TRUE; } init_header (name, v_stat, hdr) char *name; struct stat *v_stat; LzHeader *hdr; { bcopy (LZHUFF1_METHOD, hdr->method, METHOD_TYPE_STRAGE); hdr->packed_size = 0; hdr->original_size = v_stat->st_size; hdr->last_modified_stamp = unix_to_generic_stamp (v_stat->st_mtime); #ifdef MSDOS getfilemode(name, &(hdr->attribute)); #else hdr->attribute = GENERIC_ATTRIBUTE; #endif strcpy (hdr->name, name); hdr->crc = 0x0000; hdr->extend_type = OUR_EXTEND; hdr->unix_last_modified_stamp = v_stat->st_mtime; /* 00:00:00 since JAN.1.1970 */ #ifdef NOT_COMPATIBLE_MODE hdr->unix_mode = v_stat->st_mode; #else hdr->unix_mode = v_stat->st_mode; #endif hdr->unix_uid = v_stat->st_uid; hdr->unix_gid = v_stat->st_gid; if ((v_stat->st_mode & S_IFMT) == S_IFDIR) { bcopy (LZHUFF0_METHOD, hdr->method, METHOD_TYPE_STRAGE); hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE; hdr->original_size = 0; strcat (hdr->name, "/"); } } /* Write only unix extended header. */ write_header (nafp, hdr) FILE *nafp; LzHeader *hdr; { int header_size; int name_length; char data[LZHEADER_STRAGE], *ptr; int cnt; bzero (data, LZHEADER_STRAGE); bcopy (hdr->method, data + I_METHOD, METHOD_TYPE_STRAGE); setup_put (data + I_PACKED_SIZE); put_longword (hdr->packed_size); put_longword (hdr->original_size); put_longword (hdr->last_modified_stamp); put_word (hdr->attribute); #ifdef STRICT if ( hdr->name[1] == ':' ) { name_length = strlen(hdr->name + 2); put_byte (name_length); bcopy (hdr->name + 2, data + I_NAME, name_length); } else { name_length = strlen(hdr->name); put_byte (name_length); bcopy (hdr->name, data + I_NAME, name_length); } for ( ptr = data + I_NAME, cnt = 0; cnt < name_length; ptr++, cnt++ ) { if (islower(*ptr)) *ptr = toupper(*ptr); if ( *ptr == '/' ) *ptr = '\\'; } #else name_length = strlen (hdr->name); put_byte (name_length); bcopy (hdr->name, data + I_NAME, name_length); #endif setup_put (data + I_NAME + name_length); put_word (hdr->crc); #ifdef STRICT header_size = I_EXTEND_TYPE - 2 + name_length; #else put_byte (OUR_EXTEND); put_byte (CURRENT_UNIX_MINOR_VERSION); put_longword ((long)hdr->unix_last_modified_stamp); put_word (hdr->unix_mode); put_word (hdr->unix_uid); put_word (hdr->unix_gid); header_size = I_UNIX_EXTEND_BOTTOM - 2 + name_length; #endif data[I_HEADER_SIZE] = header_size; data[I_HEADER_CHECKSUM] = calc_sum (data + I_METHOD, header_size); if (fwrite (data, sizeof (char), header_size + 2, nafp) == NULL) error ("cannot write to temporary file"); } boolean archive_is_msdos_sfx1 (name) char *name; { int len = strlen (name); return ((len >= 4) && (strcmp (name + len - 4, ".com") == 0 || strcmp (name + len - 4, ".exe") == 0)); } boolean skip_msdos_sfx1_code (fp) FILE *fp; { unsigned char buffer[2048]; unsigned char *p, *q; int n; n = fread (buffer, sizeof (char), 2048, fp); for (p = buffer + 2, q = buffer + n - 5; p < q; p ++) { /* found "-l??-" keyword (as METHOD type string) */ if (p[0] == '-' && p[1] == 'l' && p[4] == '-') { /* size and checksum validate check */ if (p[-2] > 20 && p[-1] == calc_sum (p, p[-2])) { fseek (fp, (long) ((p - 2) - buffer) - n, SEEK_CUR); return TRUE; } } } fseek (fp, (long) -n, SEEK_CUR); return FALSE; } /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ make_tmp_name (original, name) char *original; char *name; { #ifdef TMP_FILENAME_TEMPLATE /* "/tmp/lhXXXXXX" etc. */ strcpy (name, TMP_FILENAME_TEMPLATE); #else char *p, *s; strcpy (name, original); for (p = name, s = (char*)0; *p; p++) if (*p == '/' || *p == '\\') s = p; strcpy ((s ? s+1 : name), "lhXXXXXX"); #endif mktemp (name); } make_backup_name (name, orginal) char *name; char *orginal; { register char *p, *dot; strcpy (name, orginal); for (p = name, dot = (char*)0; *p; p ++) { if (*p == '.') dot = p; else if (*p == '/' || *p == '\\') dot = (char*)0; } if (dot) p = dot; #ifdef BACKUPNAME_EXTENTION strcpy (p, BACKUPNAME_EXTENTION) #else strcpy (p, ".bak"); #endif } make_standard_archive_name (name, orginal) char *name; char *orginal; { register char *p, *dot; strcpy (name, orginal); for (p = name, dot = (char*)0; *p; p ++) { if (*p == '.') dot = p; else if (*p == '/' || *p == '\\') dot = (char*)0; } if (dot) p = dot; #ifdef ARCHIVENAME_EXTENTION strcpy (p, ARCHIVENAME_EXTENTION); #else strcpy (p, ".lzh"); #endif } /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ boolean need_file (name) char *name; { int i; if (cmd_filec == 0) return TRUE; for (i = 0; i < cmd_filec; i ++) { if (STRING_COMPARE (cmd_filev[i], name) == 0) return TRUE; } return FALSE; } FILE *xfopen (name, mode) char *name, *mode; { FILE *fp; if ((fp = fopen (name, mode)) == NULL) error (name); return fp; } /*----------------------------------------------------------------------*/ /* Listing Stuff */ /*----------------------------------------------------------------------*/ /* need 14 or 22 (when long_format_listing is TRUE) column spaces */ print_size (packed_size, original_size) long packed_size, original_size; { if (long_format_listing) printf ("%7ld ", packed_size); printf ("%7ld ", original_size); if (original_size == 0L) printf ("******"); else printf ("%3d.%1d%%", (int)((packed_size * 100L) / original_size), (int)((packed_size * 1000L) / original_size) % 10); } /* need 12 or 17 (when long_format_listing is TRUE) column spaces */ print_stamp (t) time_t t; { static boolean got_now = FALSE; static time_t now; static unsigned int threshold; static char t_month[12*3+1] = "JanFebMarAprMayJunJulAugSepOctNovDec"; struct tm *p; if (t == 0) { if (long_format_listing) printf (" "); /* 17 spaces */ else printf (" "); /* 12 spaces */ return; } if (!got_now) { time (&now); p = localtime (&now); threshold = p->tm_year * 12 + p->tm_mon - 6; got_now = TRUE; } p = localtime (&t); if (long_format_listing) printf ("%.3s %2d %02d:%02d %04d", &t_month[p->tm_mon * 3], p->tm_mday, p->tm_hour, p->tm_min, p->tm_year + 1900); else if (p->tm_year * 12 + p->tm_mon > threshold) printf ("%.3s %2d %02d:%02d", &t_month[p->tm_mon * 3], p->tm_mday, p->tm_hour, p->tm_min); else printf ("%.3s %2d %04d", &t_month[p->tm_mon * 3], p->tm_mday, p->tm_year + 1900); } print_bar () { /* 17+1+(0 or 7+1)+7+1+6+1+(0 or 1+4)+(12 or 17)+1+20 */ /* 12345678901234567_ 1234567_123456 _123456789012 1234 */ if (long_format_listing) #ifdef STRICT printf ("------- ------- ------ ---- ----------------- -------------\n"); #else printf ("----------------- ------- ------- ------ ---- ----------------- -------------\n"); #endif else #ifdef STRICT printf ("------- ------ ------------ --------------------\n"); #else printf ("----------------- ------- ------ ------------ --------------------\n"); #endif } /* view */ cmd_view () { FILE *fp; LzHeader hdr; register char *p; long a_packed_size = 0L; long a_original_size = 0L; int n_files = 0; struct stat v_stat; if ((fp = fopen (archive_name, RMODE)) == NULL) if (!expand_archive_name (expanded_archive_name, archive_name)) error (archive_name); else { errno = 0; fp = xfopen (expanded_archive_name, RMODE); archive_name = expanded_archive_name; } if (archive_is_msdos_sfx1 (archive_name)) { skip_msdos_sfx1_code (fp); } if (!quiet) { /* 12345678901234567_ 1234567_123456 _ 123456789012 1234 */ #ifdef STRICT printf ("%s SIZE RATIO%s %s STAMP %s NAME\n", #else printf (" PERMSSN UID GID %s SIZE RATIO%s %s STAMP %s NAME\n", #endif long_format_listing ? " PACKED " : "", /* 8,0 */ long_format_listing ? " CRC" : "", /* 5,0 */ long_format_listing ? " " : "", /* 2,0 */ long_format_listing ? " " : ""); /* 3,0 */ print_bar (); } while (get_header (fp, &hdr)) { if (need_file (hdr.name)) { if (hdr.extend_type == EXTEND_UNIX) { #ifndef STRICT printf ("%c%c%c%c%c%c%c%c%c%4d/%-4d", ((hdr.unix_mode & UNIX_OWNER_READ_PERM) ? 'r' : '-'), ((hdr.unix_mode & UNIX_OWNER_WRITE_PERM) ? 'w' : '-'), ((hdr.unix_mode & UNIX_OWNER_EXEC_PERM) ? 'x' : '-'), ((hdr.unix_mode & UNIX_GROUP_READ_PERM) ? 'r' : '-'), ((hdr.unix_mode & UNIX_GROUP_WRITE_PERM) ? 'w' : '-'), ((hdr.unix_mode & UNIX_GROUP_EXEC_PERM) ? 'x' : '-'), ((hdr.unix_mode & UNIX_OTHER_READ_PERM) ? 'r' : '-'), ((hdr.unix_mode & UNIX_OTHER_WRITE_PERM) ? 'w' : '-'), ((hdr.unix_mode & UNIX_OTHER_EXEC_PERM) ? 'x' : '-'), hdr.unix_uid, hdr.unix_gid); #endif } else { switch (hdr.extend_type) { /* max 18 characters */ case EXTEND_GENERIC: p = "[Generic]"; break; case EXTEND_CPM: p = "[CP/M]"; break; /* OS-9 and FLEX's CPU is MC-6809. I like it. :-) */ case EXTEND_FLEX: p = "[FLEX]"; break; case EXTEND_OS9: p = "[OS-9]"; break; /* I guessed from this ID. Is this right? */ case EXTEND_OS68K: p = "[OS-9/68K]"; break; case EXTEND_MSDOS: p = "[MS-DOS]"; break; /* I have Macintosh. :-) */ case EXTEND_MACOS: p = "[Mac OS]"; break; case EXTEND_OS2: p = "[OS/2]"; break; case EXTEND_HUMAN: p = "[Human68K]"; break; case EXTEND_OS386: p = "[OS-386]"; break; #ifdef EXTEND_TOWNSOS /* This ID isn't fixed */ case EXTEND_TOWNSOS: p = "[TownsOS]"; break; #endif /* Ouch! Please customize it's ID. */ default: p = "[Unknown]"; break; } #ifndef STRICT printf ("%-18.18s", p); #endif } print_size (hdr.packed_size, hdr.original_size); if (long_format_listing) if (hdr.has_crc) printf (" %04x", hdr.crc); else printf (" ****"); printf (" "); print_stamp (hdr.unix_last_modified_stamp); printf (" %s\n", hdr.name); n_files ++; a_packed_size += hdr.packed_size; a_original_size += hdr.original_size; } fseek (fp, hdr.packed_size, SEEK_CUR); } fclose (fp); if (!quiet) { print_bar (); #ifndef STRICT printf (" Total %4d file%c ", n_files, (n_files == 1) ? ' ' : 's'); #endif print_size (a_packed_size, a_original_size); printf (" "); if (long_format_listing) printf (" "); if (stat (archive_name, &v_stat) < 0) print_stamp ((time_t)0); else print_stamp (v_stat.st_mtime); #ifdef STRICT printf (" %4d file%c ", n_files, (n_files == 1) ? ' ' : 's'); #endif printf ("\n"); } return; } boolean make_parent_path (name) char *name; { char path[FILENAME_LENGTH]; struct stat v_stat; register char *p; /* make parent directory name into PATH for recursive call */ strcpy (path, name); for (p = path + strlen (path); p > path; p --) if (p[-1] == '/' || p[-1] == '\\') { p[-1] = '\0'; break; } if (p == path) return FALSE; /* no more parent. */ if (stat (path, &v_stat) >= 0) { if ((v_stat.st_mode & S_IFMT) != S_IFDIR) return FALSE; /* already exist. but it isn't directory. */ return TRUE; /* already exist its directory. */ } errno = 0; if (!quiet) message ("Making Directory", path); if (mkdir (path, 0777) >= 0) /* try */ return TRUE; /* successful done. */ errno = 0; if (!make_parent_path (path)) return FALSE; if (mkdir (path, 0777) < 0) /* try again */ return FALSE; return TRUE; } FILE *open_with_make_path (name) char *name; { FILE *fp; struct stat v_stat; char buffer[1024]; if (stat (name, &v_stat) >= 0) { if ((v_stat.st_mode & S_IFMT) != S_IFREG) return NULL; if (!force) { for (;;) { fprintf (stderr, "%s OverWrite ?(Yes/No/All) ", name); fflush (stderr); gets (buffer); if (buffer[0] == 'N' || buffer[0] == 'n') return NULL; if (buffer[0] == 'Y' || buffer[0] == 'y') break; if (buffer[0] == 'A' || buffer[0] == 'a') { force = TRUE; break; } } } } fp = fopen (name, WMODE); if (!fp) { errno = 0; if (!make_parent_path (name)) return NULL; fp = fopen (name, WMODE); if (!fp) message ("Error:", name); } return fp; } #ifdef MSDOS void dosname(char *name) { char *ptr, *first = NULL, *last = NULL; char temp[8]; for ( ptr = strchr(name, 0); ptr >= name; ptr-- ) if ( *ptr == '.' ) { if ( last == NULL ) last = ptr; } else if ( (*ptr == '/') || (*ptr == '\\') ) { first = ptr + 1; break; } if ( first == NULL ) first = name; if ( last == NULL ) last = strchr(name, 0); for ( ptr = first; ptr < last; ptr++ ) if ( *ptr == '.' ) *ptr = '_'; if ( strlen(last) > 4 ) last[4] = 0; if ( last - first > 8 ) { strcpy(temp, last); strcpy(first + 8, last); } } #endif extern int decode_lzhuf (), decode_larc (); extern int decode_stored_crc (), decode_stored_nocrc (); extract_one (fp, hdr) FILE *fp; LzHeader *hdr; { FILE *ofp; /* output file */ char name[1024]; time_t utimebuf[2]; int crc; int (*decode_proc)(); /* (ifp,ofp,original_size,name) */ int save_quiet; strcpy (name, hdr->name); if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_REGULAR) { if (bcmp (hdr->method, LZHUFF1_METHOD, METHOD_TYPE_STRAGE) == 0) decode_proc = decode_lzhuf; else if ((bcmp (hdr->method, LZHUFF0_METHOD, METHOD_TYPE_STRAGE) == 0) || (bcmp (hdr->method, LARC4_METHOD, METHOD_TYPE_STRAGE) == 0)) decode_proc = (hdr->has_crc) ? decode_stored_crc : decode_stored_nocrc; else if (bcmp (hdr->method, LARC5_METHOD, METHOD_TYPE_STRAGE) == 0) decode_proc = decode_larc; else message ("Error:", "Sorry, Cannot Extract this method."); reading_filename = archive_name; writting_filename = name; if (output_to_stdout) { if (!quiet) printf ("::::::::\r\n%s\r\n::::::::\r\n", name); if ( strlen(pager) != 0 ) ofp = popen(pager, WMODE); else ofp = stdout; save_quiet = quiet; quiet = TRUE; crc = (*decode_proc) (fp, ofp, hdr->original_size, name); quiet = save_quiet; if ( strlen(pager) != 0 ) pclose(ofp); } else if (output_to_test) { ofp = fopen(NULLFILE, WMODE); crc = (*decode_proc) (fp, ofp, hdr->original_size, name); fclose(ofp); } else { #ifdef MSDOS dosname(name); #endif if ((ofp = open_with_make_path (name)) == NULL) return; else { crc = (*decode_proc) (fp, ofp, hdr->original_size, name); fclose (ofp); } } if (hdr->has_crc && (crc != hdr->crc)) if (output_to_test) message ("Error:", "CRC failed\a"); else error ("CRC failed\a"); } else { /* NAME has trailing SLASH '/', (^_^) */ if (!output_to_stdout && !make_parent_path (name)) error (name); } if (!output_to_stdout && !output_to_test) { utimebuf[0] = utimebuf[1] = hdr->unix_last_modified_stamp; utime (name, utimebuf); #ifdef NOT_COMPATIBLE_MODE setfilemode(name, hdr->attribute); #else chmod (name, hdr->unix_mode); #endif #ifndef MSDOS chown (name, hdr->unix_uid, hdr->unix_gid); #endif errno = 0; } } /* extract */ cmd_extract () { LzHeader hdr; long pos; FILE *fp; if ((fp = fopen (archive_name, RMODE)) == NULL) if (!expand_archive_name (expanded_archive_name, archive_name)) error (archive_name); else { errno = 0; fp = xfopen (expanded_archive_name, RMODE); archive_name = expanded_archive_name; } if (archive_is_msdos_sfx1 (archive_name)) { skip_msdos_sfx1_code (fp); } while (get_header (fp, &hdr)) { if (need_file (hdr.name)) { pos = ftell (fp); extract_one (fp, &hdr); fseek (fp, pos + hdr.packed_size, SEEK_SET); } else { fseek (fp, hdr.packed_size, SEEK_CUR); } } fclose (fp); return; } /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ extern int encode_lzhuf (); extern int encode_storerd_crc (); append_one (fp, nafp, hdr) FILE *fp, *nafp; LzHeader *hdr; { long header_pos, next_pos, org_pos, data_pos; long v_original_size, v_packed_size; reading_filename = hdr->name; writting_filename = temporary_name; org_pos = ftell (fp); header_pos = ftell (nafp); write_header (nafp, hdr); /* DUMMY */ if (hdr->original_size == 0) { printf("%s - not frozen\n",hdr->name); return; /* previous write_header is not DUMMY. (^_^) */ } data_pos = ftell (nafp); hdr->crc = encode_lzhuf (fp, nafp, hdr->original_size, &v_original_size, &v_packed_size, hdr->name); if (v_packed_size < v_original_size) { next_pos = ftell (nafp); } else { /* retry by stored method */ fseek (fp, org_pos, SEEK_SET); fseek (nafp, data_pos, SEEK_SET); hdr->crc = encode_stored_crc (fp, nafp, hdr->original_size, &v_original_size, &v_packed_size); fflush (nafp); next_pos = ftell (nafp); ftruncate (fileno (nafp), next_pos); bcopy (LZHUFF0_METHOD, hdr->method, METHOD_TYPE_STRAGE); } hdr->original_size = v_original_size; hdr->packed_size = v_packed_size; fseek (nafp, header_pos, SEEK_SET); write_header (nafp, hdr); fseek (nafp, next_pos, SEEK_SET); } write_tail (nafp) FILE *nafp; { putc (0x00, nafp); } copy_old_one (oafp, nafp, hdr) FILE *oafp, *nafp; LzHeader *hdr; { if (noexec) { fseek (oafp, (long)(hdr->header_size + 2) + hdr->packed_size, SEEK_CUR); } else { reading_filename = archive_name; writting_filename = temporary_name; copy_file (oafp, nafp, (long)(hdr->header_size + 2) + hdr->packed_size); } } FILE *append_it (name, oafp, nafp) char *name; FILE *oafp, *nafp; { LzHeader ahdr, hdr; FILE *fp; long old_header; int cmp; int filec; char **filev; int i; struct stat v_stat; boolean directory; if (!delete_from_archive) if (stat (name, &v_stat) < 0) { message ("Error:", name); return oafp; } directory = ((v_stat.st_mode & S_IFMT) == S_IFDIR); init_header (name, &v_stat, &hdr); if (!delete_from_archive && !directory && !noexec) fp = xfopen (name, RMODE); while (oafp) { old_header = ftell (oafp); if (!get_header (oafp, &ahdr)) { fclose (oafp); oafp = NULL; break; } else { cmp = STRING_COMPARE (ahdr.name, hdr.name); if (cmp < 0) { /* SKIP */ fseek (oafp, old_header, SEEK_SET); copy_old_one (oafp, nafp, &ahdr); } else if (cmp == 0) { /* REPLACE */ fseek (oafp, ahdr.packed_size, SEEK_CUR); break; } else /* cmp > 0, INSERT */ { fseek (oafp, old_header, SEEK_SET); break; } } } if (delete_from_archive) { if (noexec) fprintf (stderr, "DELETE %s\n", name); else printf ("%s - Deleted\n", name); } else { if ( !oafp || (cmp > 0) || !update_if_newer || (ahdr.unix_last_modified_stamp < hdr.unix_last_modified_stamp) ) { if (noexec) fprintf (stderr, "APPEND %s\n", name); else #ifdef STRICT if ( !directory ) #endif if ( !update_freshen || (cmp == 0) ) append_one (fp, nafp, &hdr); } else { /* archive has old one */ fseek (oafp, old_header, SEEK_SET); copy_old_one (oafp, nafp, &ahdr); } if (!directory) { if (!noexec) fclose (fp); } else { /* recurcive call */ if (find_files (name, &filec, &filev)) { for (i = 0; i < filec; i ++) oafp = append_it (filev[i], oafp, nafp); free_files (filec, filev); } return oafp; } } return oafp; } remove_it (name) char *name; { struct stat v_stat; int i; char **filev; int filec; if (stat (name, &v_stat) < 0) { fprintf (stderr, "Cannot access \"%s\".\n", name); return; } if ((v_stat.st_mode & S_IFMT) == S_IFDIR) { if (!find_files (name, &filec, &filev)) { fprintf (stderr, "Cannot open directory \"%s\".\n", name); return; } for (i = 0; i < filec; i ++) remove_it (filev[i]); free_files (filec, filev); if (noexec) printf ("REMOVE DIR %s\n", name); else if (rmdir (name) < 0) fprintf (stderr, "Cannot remove directory \"%s\".\n", name); else if (!quiet) printf ("%s - Removed\n", name); } else { if (noexec) printf ("REMOVE %s\n", name); else if (unlink (name) < 0) fprintf (stderr, "Cannot delete \"%s\".\n", name); else if (!quiet) printf ("%s - Removed\n", name); } } #ifdef FASTCOPY #define BUFFER_SIZE 16384 #ifndef O_BINARY #define O_BINARY 0 #endif copy_archive(char *src, char *dst) { int ih, oh; unsigned chunk; char *buffer = (char *) rson; printf ("Copying temp to archive ... "); ih = open (src, O_RDONLY | O_BINARY); if ( ih == -1 ) error(src); oh = open (dst, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE); if ( oh == -1 ) error(dst); while ( (chunk = read(ih, buffer, BUFFER_SIZE)) > 0 ) if ( write(oh, buffer, chunk) != chunk ) error(dst); close (ih); close (oh); printf("\b\b\b\b \b\b\b\b.\n"); } #endif cmd_append () { LzHeader ahdr; FILE *oafp, *nafp; char backup_archive_name [ FILENAME_LENGTH ]; char new_archive_name_buffer [ FILENAME_LENGTH ]; char *new_archive_name; int i; long old_header; struct stat v_stat; boolean old_archive_exist; if (cmd_filec == 0) return; make_tmp_name (archive_name, temporary_name); if ((oafp = fopen (archive_name, RMODE)) == NULL) if (expand_archive_name (expanded_archive_name, archive_name)) { errno = 0; oafp = fopen (expanded_archive_name, RMODE); archive_name = expanded_archive_name; } old_archive_exist = (oafp) ? TRUE : FALSE; if (new_archive && oafp) { fclose (oafp); oafp = NULL; } if (oafp && archive_is_msdos_sfx1 (archive_name)) { skip_msdos_sfx1_code (oafp); make_standard_archive_name (new_archive_name_buffer, archive_name); new_archive_name = new_archive_name_buffer; } else { new_archive_name = archive_name; } errno = 0; if (!noexec) { nafp = xfopen (temporary_name, WMODE); remove_temporary_at_error = TRUE; } for (i = 0; i < cmd_filec; i ++) oafp = append_it (cmd_filev[i], oafp, nafp); if (oafp) { old_header = ftell (oafp); while (get_header (oafp, &ahdr)) { fseek (oafp, old_header, SEEK_SET); copy_old_one (oafp, nafp, &ahdr); old_header = ftell (oafp); } fclose (oafp); } if (!noexec) { write_tail (nafp); fclose (nafp); } make_backup_name (backup_archive_name, archive_name); if (!noexec && old_archive_exist) { unlink(backup_archive_name); if (rename (archive_name, backup_archive_name) < 0) error (archive_name); } if (!quiet && new_archive_name == new_archive_name_buffer) { /* warning at old archive is SFX */ printf ("New Archive File is \"%s\"\n", new_archive_name); } if (!noexec && rename (temporary_name, new_archive_name) < 0) { if (stat (temporary_name, &v_stat) < 0) error (temporary_name); #ifdef FASTCOPY copy_archive(temporary_name, archive_name); #else oafp = xfopen (temporary_name, RMODE); nafp = xfopen (archive_name, WMODE); reading_filename = temporary_name; writting_filename = archive_name; copy_file (oafp, nafp, (long)v_stat.st_size); fclose (nafp); fclose (oafp); #endif unlink (temporary_name); } remove_temporary_at_error = FALSE; if (delete_after_append) { if (!quiet && !noexec) printf ("Erasing...\n"); for (i = 0; i < cmd_filec; i ++) remove_it (cmd_filev[i]); } return; } -------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ extern int encode_lzhuf (); extern int encode_storerd_crc (); append_one (fp, nafp, hdr) FILE *fp, *nafp; LzHeader *hdr; { long header_pos, next_pos, org_pos, data_pos; long v_original_size, v_packed_size; reading_filename = hdr->name; writting_filename = temporary_nlharc.doc 666 75616 51013 6626 5110114712 6036 ------------------------------------------------------------------------------ LHarc UNIX Release #3 V0.03 beta version Copyright (C) 1989 Yooichi.Tagawa cl mj z oMIX ID: y.tagawa ------------------------------------------------------------------------------ 1Lv UNIX EL LHarc p H :AAIfgH"),hAUNIX E LHarc (LHarc UNIX) p LHarc F *5\7B yg"{z lharc {axevludmcp}[qnft] archive_file [files or directories...] R}hMAaxevludmcp L"Cj)PFBpwh5\7B(H*s B) IvVM qnft )gp"-BE`wh B\E7B (H* B\B3 yA[JCut@C / t A ?l*t/gjD"i1Fp>&5=hLgppS 7i1FB c. oCi 3. 4. 1Lv X5H"B 5. mH"B 6. 1Lv p5D`)\mH"B1Lj H-ALHarc F3"B 2. G [bZ[W*sKXH* i)`5j\9qB + 3. 1qH`qE""LE5e$)B(^_^) + 4. TufB Ng A[JCut@C IG ALbhpFhL<-1F*E+\5=B * 5. 3k/W E7B LArc type 4 yQAtype 5 I`N 5\5=B * 6. MS-DOS ELZ tGNXg NgLA[JCu `.` p $I5\5=B 7. MS-DOS E V1.13c LA[JCut@C * [MS-DOS] EH-A [generic] IHh\7*AMS-DOS ELLE =h(\*))gM [MS-DOS] FF/E+itH[}bgIHAD"iFv"\7B(^_^) 8. MS-DOS E V1.13c ELTufB Ng W 9. {M VAX 11/785 UNIX 4.2BSD E (`FbNRj* i)`5j\9q) + 10. d66)Fv"\7*AMS-DOS <--> UNIX L]MoCi * 11. System-V VLZApeUI * 12. v F l R}hL\& `TLO * 13. lzhuf.c )g @mK6pMT+\5=B(Fv$) G L V0.02: 1. verbose/quiet/text_mode option M\> "E7B 2. G [bZ[W*sKXH* i)`5j\9qB * 3. 1qH`qE""LE5e$)B(^_^) * 4. TufB Ng A[JCut@C IG ALbhpFhL<-1F*E+\5=B 5. 3k/W >Fv"\7B 6. ; 5D"\9qB 7. MS-DOS E V1.13c LA[JCut@C * [MS-DOS] EH-A [generic] IHh\7*AMS-DOS ELLE =h(\*))gM [MS-DOS] FF/E+itH[}bgIHAD"iFv"\7B(^_^) 8. MS-DOS E V1.13c ELTufB Ng W 9. {M vax 11/785 UNIX 4.2BSD E (`FbNRj* i)`5j\9q) * 10. d66)Fv"\7*AMS-DOS <--> UNIX L]MoCi G L V0.01: 1. verbose/quiet/text_mode option M\> "E7B 2. G [bZ[W*sKXH* i)`5j\9qB 3. 4. TufB Ng 5. 3k/W >Fv"\7B 6. ; 5D"\9qB 7. MS-DOS E V1.13c LA[JCut@C * [MS-DOS] EH-A [generic] IHh\7*AMS-DOS ELLE =h(\*))gM [MS-DOS] FF/E+itH[}bgIHAD"iFv"\7B(^_^) 8. MS-DOS E V1.13c ELTufB Ng W 9. {M vax 11/785 UNIX 4.2BSD E (`FbNRj* i)`5j\9q) ------------------------------------------------------------------------------ free_files (filec, filev); if (noexec) printf ("REMOVE DIR %s\n", name); else ilhio.c 666 75616 51013 14210 5110114712 5361 /*----------------------------------------------------------------------*/ /* File I/O module for LHarc UNIX */ /* */ /* Copyright(C) MCMLXXXIX Yooichi.Tagawa */ /* */ /* V0.00 Original 1989.06.25 Y.Tagawa */ /* V0.03 Release #3 Beta Version 1989.07.02 Y.Tagawa */ /* V0.03a Fix few bugs 1989.07.04 Y.Tagawa */ /*----------------------------------------------------------------------*/ #include #include "lhio.h" #ifndef BUFFER_SIZE #define BUFFER_SIZE 16384 #endif extern int text_mode; /* in lharc.c */ FILE *crc_infile, *crc_outfile; /* in lzhuf.c */ extern int rson[]; /* These functions are NO-RETURN */ extern read_error (); extern write_error (); int crc_getc_cashe; unsigned int crc_value; unsigned int crc_table[0x100]; long crc_size; crcsub (ptr, length) char *ptr; register int length; { register unsigned char *p; register unsigned int ctmp; if (length != 0) { ctmp = crc_value; p = (unsigned char*)ptr; for (; length; length --) { ctmp ^= (unsigned int)*p++; ctmp = (ctmp >> 8) ^ crc_table [ ctmp & 0xff ]; } crc_value = ctmp; } } #ifndef __GNUC__ void putc_crc (c) int c; { CRC_CHAR (c); if (!text_mode || (c != 0x0d && c != 0x1a)) { putc (c, crc_outfile); } } int getc_crc () { int c; if (crc_getc_cashe != EOF) { c = crc_getc_cashe; crc_getc_cashe = EOF; CRC_CHAR (c); crc_size++; } else if ((c = getc (crc_infile)) != EOF) { if (text_mode && c == 0x0a) { crc_getc_cashe = c; c = 0x0d; } CRC_CHAR (c); crc_size++; } return c; } #endif init_crc () { static int inited = 0; register unsigned int *p = crc_table; register int i, j; register unsigned int x; if (!inited) { for (j = 0; j < 256; j ++) { x = j; for (i = 0; i < 8; i ++) { if ((x & 1) != 0) { x = (x >> 1) ^ 0xa001; } else { x = (x >> 1); } } *p ++ = x; } inited = 1; } crc_value = 0; crc_getc_cashe = EOF; crc_size = 0; } /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ /* if return value is -1, see errno */ copy_binary_file (ifp, ofp, size, crc_flag) FILE *ifp, *ofp; long size; int crc_flag; /* as boolean value */ { char *buffer = (char *) rson; int read_size; int n; /* safty */ fflush (ofp); while (size > 0) { read_size = ((size < (long)BUFFER_SIZE) ? (int)size : BUFFER_SIZE); n = fread (buffer, sizeof (char), read_size, ifp); if (n == 0) read_error (); if (fwrite (buffer, sizeof (char), n, ofp) < n) write_error (); if (crc_flag) crcsub (buffer, n); size -= (long)n; } } /* read UNIX text file '0A' and write generic text file '0D0A' */ write_generic_text_file (ifp, ofp, size) FILE *ifp, *ofp; long size; { char buffer[BUFFER_SIZE]; int read_size, write_count, n, m; register char *p, *p1, *e; /* safty */ fflush (ofp); write_count = 0; while (size > 0) { read_size = ((size < BUFFER_SIZE) ? (int)size : BUFFER_SIZE); n = fread (buffer, sizeof (char), read_size, ifp); if (n == 0) read_error (); for (p1 = p = buffer, e = buffer + n; p < e; p++) { if (*p == '\n') { if ((m = p - p1) != 0) { if (fwrite (p1, sizeof (char), m, ofp) < m) write_error (); crcsub (p1, m); } putc (0x0d, ofp); if (feof (ofp)) write_error (); CRC_CHAR (0x0d); p1 = p; write_count ++; } } if ((m = p - p1) != 0) { if (fwrite (p1, sizeof (char), m, ofp) < m) write_error (); crcsub (p1, m); } write_count += (long)n; size -= (long)n; } crc_size = write_count; } /* read generic text file '0D0A' and write UNIX text file '0A' */ read_generic_text_file (ifp, ofp, size, crc_flag) FILE *ifp, *ofp; long size; int crc_flag; { char buffer[BUFFER_SIZE]; int read_size, write_size, n, m; register char *p, *p1, *e; /* safty */ fflush (ofp); while (size > 0) { read_size = ((size < BUFFER_SIZE) ? (int)size : BUFFER_SIZE); n = fread (buffer, sizeof (char), read_size, ifp); if (n == 0) read_error (); crcsub (buffer, n); for (p1 = p = buffer, e = buffer + n; p < e; p ++) { if (*p == 0x0d) { if ((m = p - p1) != 0) { if (fwrite (p1, sizeof (char), m, ofp) < m) write_error (); } p1 = p+1; } } if ((m = p - p1) != 0) { if (fwrite (p1, sizeof (char), m, ofp) < m) write_error (); } size -= (long)n; } } /*----------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------*/ copy_file (ifp, ofp, size) FILE *ifp, *ofp; long size; { copy_binary_file (ifp, ofp, size, 0); } /*ARGSUSED*/ int decode_stored_crc (ifp, ofp, original_size, name) FILE *ifp, *ofp; long original_size; char *name; { init_crc (); if (text_mode) { read_generic_text_file (ifp, ofp, original_size, 1); return crc_value; } else { copy_binary_file (ifp, ofp, original_size, 1); return crc_value; } } /*ARGSUSED*/ int decode_stored_nocrc (ifp, ofp, original_size, name) FILE *ifp, *ofp; long original_size; char *name; { if (text_mode) { read_generic_text_file (ifp, ofp, original_size, 0); return 0; /* DUMMY */ } else { copy_binary_file (ifp, ofp, original_size, 0); } return 0; /* DUMMY */ } int encode_stored_crc (ifp, ofp, size, original_size_var, write_size_var) FILE *ifp, *ofp; long size; long *original_size_var; long *write_size_var; { init_crc (); if (text_mode) { write_generic_text_file (ifp, ofp, size); *original_size_var = *write_size_var = crc_size; return crc_value; } else { copy_binary_file (ifp, ofp, size, 1); *original_size_var = size; *write_size_var = size; return crc_value; } } eturn c; } #endif init_crc () { static int inited = 0; register unsigned int *p = crc_table; register int i, j; register unsigned int x; if (!inited) { for (j = 0; j < 256; j ++) { x = j; for (i = 0; i < 8; i ++) { if ((x & 1) != 0) { x = (x >> 1) ^ 0xa001; } else { x = (x >> 1); } } *p ++ = x; } inited = 1; } lhio.h 666 75616 51013 2554 5110114713 5357 /*----------------------------------------------------------------------*/ /* File I/O module for LHarc UNIX */ /* */ /* Copyright(C) MCMLXXXIX Yooichi.Tagawa */ /* */ /* V0.00 Original 1989.06.25 Y.Tagawa */ /* V0.03 Release #3 Beta Version 1989.07.02 Y.Tagawa */ /*----------------------------------------------------------------------*/ extern int text_mode; extern unsigned int crc_table[0x100]; extern unsigned int crc_value; extern int crc_getc_cashe; extern FILE *crc_infile, *crc_outfile; extern long crc_size; #define CRC_CHAR(c) \ { register unsigned int ctmp = crc_value ^ c; \ crc_value = (ctmp >> 8) ^ crc_table [ ctmp & 0xff ]; } #if defined (__GNUC__) /*#define inlnie*/ /* DECODING */ /* '0D0A' -> '0A' conversion and strip '1A' when text_mode */ static inline putc_crc (int c) { CRC_CHAR (c); if (!text_mode || (c != 0x0d && c != 0x1a)) { putc (c, crc_outfile); } } /* ENCODING */ /* '0A' -> '0D0A' conversion when text_mode */ static inline int getc_crc () { int c; if (crc_getc_cashe != EOF) { c = crc_getc_cashe; crc_getc_cashe = EOF; CRC_CHAR (c); crc_size++; } else if ((c = getc (crc_infile)) != EOF) { if (text_mode && c == 0x0a) { crc_getc_cashe = c; c = 0x0d; } CRC_CHAR (c); crc_size++; } return c; } #endif write_generic_text_file (ifp, ofp, size); *original_size_var = *write_size_var = crc_size; return crc_value; } else { lzhuf.c 666 75616 51013 54167 5110115277 5604 /*----------------------------------------------------------------------*/ /* lzhuf.c : Encoding/Decoding module for LHarc */ /* */ /* LZSS Algorithm Haruhiko.Okumura */ /* Adaptic Huffman Encoding 1989.05.27 Haruyasu.Yoshizaki */ /* */ /* */ /* Modified for UNIX LHarc V0.01 1989.05.28 Y.Tagawa */ /* Modified for UNIX LHarc V0.02 1989.05.29 Y.Tagawa */ /* Modified for UNIX LHarc V0.03 1989.07.02 Y.Tagawa */ /*----------------------------------------------------------------------*/ /* Use ANSI sequences for using only one line per file but * indicator dots on next line */ /* #define ANSI */ #ifndef ANSI #define DOT '.' #define BALL 'o' #else #define DOT 249 #define BALL 3 #define CURSORUP "\033[A" #define ERASEEOL "\033[K" #endif #include #ifndef SELFMAIN #include "lhio.h" #else #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 #endif FILE *infile, *outfile; long textsize, codesize; #define INDICATOR_THRESHOLD 4096L #define MAX_INDICATOR_COUNT 78 long indicator_count; long indicator_threshold; #ifdef SELFMAIN int quiet = 0; #else extern int quiet; extern int output_to_test; #endif #ifdef SELFMAIN #define SETUP_PUTC_CRC(fp) /* nothing */ #define SETUP_GETC_CRC(fp) /* nothing */ #define PUTC_CRC(c) putc((c),(outfile)) #define GETC_CRC() getc(infile) #define END_PUTC_CRC() #define END_GETC_CRC() #else #define SETUP_PUTC_CRC(fp) crc_outfile = fp #define SETUP_GETC_CRC(fp) crc_infile = fp #define PUTC_CRC(c) putc_crc(c) #define GETC_CRC() getc_crc() #define END_PUTC_CRC() #define END_GETC_CRC() #endif #ifdef SELFMAIN void Error (message) char *message; { printf("\n%s\n", message); exit(EXIT_FAILURE); } #endif /*----------------------------------------------------------------------*/ /* */ /* LZSS ENCODING */ /* */ /*----------------------------------------------------------------------*/ #define N 4096 /* buffer size */ #define F 60 /* pre-sence buffer size */ #define THRESHOLD 2 #define NIL N /* term of tree */ unsigned char text_buf[N + F - 1]; unsigned int match_position, match_length; int lson[N + 1], rson[N + 1 + N], dad[N + 1]; unsigned char same[N + 1]; /* Initialize Tree */ InitTree () { register int *p, *e; for (p = rson + N + 1, e = rson + N + N; p <= e; ) *p++ = NIL; for (p = dad, e = dad + N; p < e; ) *p++ = NIL; } /* Insert to node */ InsertNode (r) register int r; { register int p; int cmp; register unsigned char *key; register unsigned int c; register unsigned int i, j; cmp = 1; key = &text_buf[r]; i = key[1] ^ key[2]; i ^= i >> 4; p = N + 1 + key[0] + ((i & 0x0f) << 8); rson[r] = lson[r] = NIL; match_length = 0; i = j = 1; for ( ; ; ) { if (cmp >= 0) { if (rson[p] != NIL) { p = rson[p]; j = same[p]; } else { rson[p] = r; dad[r] = p; same[r] = i; return; } } else { if (lson[p] != NIL) { p = lson[p]; j = same[p]; } else { lson[p] = r; dad[r] = p; same[r] = i; return; } } if (i > j) { i = j; cmp = key[i] - text_buf[p + i]; } else if (i == j) { for (; i < F; i++) if ((cmp = key[i] - text_buf[p + i]) != 0) break; } if (i > THRESHOLD) { if (i > match_length) { match_position = ((r - p) & (N - 1)) - 1; if ((match_length = i) >= F) break; } else if (i == match_length) { if ((c = ((r - p) & (N - 1)) - 1) < match_position) { match_position = c; } } } } same[r] = same[p]; dad[r] = dad[p]; lson[r] = lson[p]; rson[r] = rson[p]; dad[lson[p]] = r; dad[rson[p]] = r; if (rson[dad[p]] == p) rson[dad[p]] = r; else lson[dad[p]] = r; dad[p] = NIL; /* remove p */ } link (n, p, q) int n, p, q; { register unsigned char *s1, *s2, *s3; if (p >= NIL) { same[q] = 1; return; } s1 = text_buf + p + n; s2 = text_buf + q + n; s3 = text_buf + p + F; while (s1 < s3) { if (*s1++ != *s2++) { same[q] = s1 - 1 - text_buf - p; return; } } same[q] = F; } linknode (p, q, r) int p, q, r; { int cmp; if ((cmp = same[q] - same[r]) == 0) { link(same[q], p, r); } else if (cmp < 0) { same[r] = same[q]; } } DeleteNode (p) register int p; { register int q; if (dad[p] == NIL) return; /* has no linked */ if (rson[p] == NIL) { if ((q = lson[p]) != NIL) linknode(dad[p], p, q); } else if (lson[p] == NIL) { q = rson[p]; linknode(dad[p], p, q); } else { q = lson[p]; if (rson[q] != NIL) { do { q = rson[q]; } while (rson[q] != NIL); if (lson[q] != NIL) linknode(dad[q], q, lson[q]); link(1, q, lson[p]); rson[dad[q]] = lson[q]; dad[lson[q]] = dad[q]; lson[q] = lson[p]; dad[lson[p]] = q; } link(1, dad[p], q); link(1, q, rson[p]); rson[q] = rson[p]; dad[rson[p]] = q; } dad[q] = dad[p]; if (rson[dad[p]] == p) rson[dad[p]] = q; else lson[dad[p]] = q; dad[p] = NIL; } /*----------------------------------------------------------------------*/ /* */ /* HUFFMAN ENCODING */ /* */ /*----------------------------------------------------------------------*/ #define N_CHAR (256 - THRESHOLD + F) /* {code : 0 .. N_CHAR-1} */ #define T (N_CHAR * 2 - 1) /* size of table */ #define R (T - 1) /* root position */ #define MAX_FREQ 0x8000 /* tree update timing from frequency */ typedef unsigned char uchar; /* TABLE OF ENCODE/DECODE for upper 6bits position information */ /* for encode */ uchar p_len[64] = { 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }; uchar p_code[64] = { 0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C, 0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC, 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; /* for decode */ uchar d_code[256] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B, 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, }; uchar d_len[256] = { 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, }; unsigned freq[T + 1]; /* frequency table */ int prnt[T + N_CHAR]; /* points to parent node */ /* notes : prnt[T .. T + N_CHAR - 1] used by indicates leaf position that corresponding to code */ int son[T]; /* points to son node (son[i],son[i+]) */ unsigned getbuf = 0; uchar getlen = 0; /* get one bit */ /* returning in Bit 0 */ int GetBit () { register unsigned int dx = getbuf; register unsigned int c; if (getlen <= 8) { c = getc (infile); if ((int)c < 0) c = 0; dx |= c << (8 - getlen); getlen += 8; } getbuf = dx << 1; getlen--; return (dx & 0x8000) ? 1 : 0; } /* get one byte */ /* returning in Bit7...0 */ int GetByte () { register unsigned int dx = getbuf; register unsigned c; if (getlen <= 8) { c = getc (infile); if ((int)c < 0) c = 0; dx |= c << (8 - getlen); getlen += 8; } getbuf = dx << 8; getlen -= 8; return (dx >> 8) & 0xff; } /* get N bit */ /* returning in Bit(N-1)...Bit 0 */ int GetNBits (n) register unsigned int n; { register unsigned int dx = getbuf; register unsigned int c; static int mask[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x0fff, 0xffff }; static int shift[17] = { 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; if (getlen <= 8) { c = getc (infile); if ((int)c < 0) c = 0; dx |= c << (8 - getlen); getlen += 8; } getbuf = dx << n; getlen -= n; return (dx >> shift[n]) & mask[n]; } unsigned putbuf = 0; uchar putlen = 0; /* output C bits */ Putcode (l, c) register int l; register unsigned int c; { register len = putlen; register unsigned int b = putbuf; b |= c >> len; if ((len += l) >= 8) { putc (b >> 8, outfile); if ((len -= 8) >= 8) { putc (b, outfile); codesize += 2; len -= 8; b = c << (l - len); } else { b <<= 8; codesize++; } } putbuf = b; putlen = len; } /* Initialize tree */ StartHuff () { register int i, j; for (i = 0; i < N_CHAR; i++) { freq[i] = 1; son[i] = i + T; prnt[i + T] = i; } i = 0; j = N_CHAR; while (j <= R) { freq[j] = freq[i] + freq[i + 1]; son[j] = i; prnt[i] = prnt[i + 1] = j; i += 2; j++; } freq[T] = 0xffff; prnt[R] = 0; putlen = getlen = 0; putbuf = getbuf = 0; } /* reconstruct tree */ reconst () { register int i, j, k; register unsigned f; /* correct leaf node into of first half, and set these freqency to (freq+1)/2 */ j = 0; for (i = 0; i < T; i++) { if (son[i] >= T) { freq[j] = (freq[i] + 1) / 2; son[j] = son[i]; j++; } } /* build tree. Link sons first */ for (i = 0, j = N_CHAR; j < T; i += 2, j++) { k = i + 1; f = freq[j] = freq[i] + freq[k]; for (k = j - 1; f < freq[k]; k--); k++; { register unsigned *p, *e; for (p = &freq[j], e = &freq[k]; p > e; p--) p[0] = p[-1]; freq[k] = f; } { register int *p, *e; for (p = &son[j], e = &son[k]; p > e; p--) p[0] = p[-1]; son[k] = i; } } /* link parents */ for (i = 0; i < T; i++) { if ((k = son[i]) >= T) { prnt[k] = i; } else { prnt[k] = prnt[k + 1] = i; } } } /* update given code's frequency, and update tree */ update (c) unsigned int c; { register unsigned *p; register int i, j, k, l; if (freq[R] == MAX_FREQ) { reconst(); } c = prnt[c + T]; do { k = ++freq[c]; /* swap nodes when become wrong frequency order. */ if (k > freq[l = c + 1]) { for (p = freq+l+1; k > *p++; ) ; l = p - freq - 2; freq[c] = p[-2]; p[-2] = k; i = son[c]; prnt[i] = l; if (i < T) prnt[i + 1] = l; j = son[l]; son[l] = i; prnt[j] = c; if (j < T) prnt[j + 1] = c; son[c] = j; c = l; } } while ((c = prnt[c]) != 0); /* loop until reach to root */ } /* unsigned code, len; */ EncodeChar (c) unsigned c; { register int *p; register unsigned long i; register int j, k; i = 0; j = 0; p = prnt; k = p[c + T]; /* trace links from leaf node to root */ do { i >>= 1; /* if node index is odd, trace larger of sons */ if (k & 1) i += 0x80000000; j++; } while ((k = p[k]) != R) ; if (j > 16) { Putcode(16, (unsigned int)(i >> 16)); Putcode(j - 16, (unsigned int)i); } else { Putcode(j, (unsigned int)(i >> 16)); } /* code = i; */ /* len = j; */ update(c); } EncodePosition (c) unsigned c; { unsigned i; /* output upper 6bit from table */ i = c >> 6; Putcode((int)(p_len[i]), (unsigned int)(p_code[i]) << 8); /* output lower 6 bit */ Putcode(6, (unsigned int)(c & 0x3f) << 10); } EncodeEnd () { if (putlen) { putc(putbuf >> 8, outfile); codesize++; } } int DecodeChar () { register unsigned c; c = son[R]; /* trace from root to leaf, got bit is 0 to small(son[]), 1 to large (son[]+1) son node */ while (c < T) { c += GetBit(); c = son[c]; } c -= T; update(c); return c; } int DecodePosition () { unsigned i, j, c; /* decode upper 6bit from table */ i = GetByte(); c = (unsigned)d_code[i] << 6; j = d_len[i]; /* get lower 6bit */ j -= 2; return c | (((i << j) | GetNBits (j)) & 0x3f); } Encode () { register int i, c, len, r, s, last_match_length; if (textsize == 0) return; textsize = 0; StartHuff(); InitTree(); s = 0; r = N - F; for (i = s; i < r; i++) text_buf[i] = ' '; for (len = 0; len < F && (c = GETC_CRC()) != EOF; len++) text_buf[r + len] = c; textsize = len; for (i = 1; i <= F; i++) InsertNode(r - i); InsertNode(r); do { if (match_length > len) match_length = len; if (match_length <= THRESHOLD) { match_length = 1; EncodeChar(text_buf[r]); } else { EncodeChar(255 - THRESHOLD + match_length); EncodePosition(match_position); } last_match_length = match_length; for (i = 0; i < last_match_length && (c = GETC_CRC()) != EOF; i++) { DeleteNode(s); text_buf[s] = c; if (s < F - 1) text_buf[s + N] = c; s = (s + 1) & (N - 1); r = (r + 1) & (N - 1); InsertNode(r); } textsize += i; if ((textsize > indicator_count) && !quiet) { putchar (BALL); fflush (stdout); indicator_count += indicator_threshold; } while (i++ < last_match_length) { DeleteNode(s); s = (s + 1) & (N - 1); r = (r + 1) & (N - 1); if (--len) InsertNode(r); } } while (len > 0); EncodeEnd(); END_GETC_CRC (); } Decode () { register int i, j, k, r, c; register long count; #ifdef SELFMAIN if (textsize == 0) return; #endif StartHuff(); for (i = 0; i < N - F; i++) text_buf[i] = ' '; r = N - F; for (count = 0; count < textsize; ) { c = DecodeChar(); if (c < 256) { PUTC_CRC (c); text_buf[r++] = c; r &= (N - 1); count++; } else { i = (r - DecodePosition() - 1) & (N - 1); j = c - 255 + THRESHOLD; for (k = 0; k < j; k++) { c = text_buf[(i + k) & (N - 1)]; PUTC_CRC (c); text_buf[r++] = c; r &= (N - 1); count++; } } if (!quiet && (count > indicator_count)) { putchar (BALL); fflush (stdout); indicator_count += indicator_threshold; } } END_PUTC_CRC (); } /*----------------------------------------------------------------------*/ /* */ /* LARC */ /* */ /*----------------------------------------------------------------------*/ #define F_OLD 18 /* look ahead buffer size for LArc */ /* intialize buffer for LArc type 5 */ InitBuf () { register unsigned char *p = text_buf; register int i, j; for (i = 0; i < 256; i ++) for (j = 0; j < 13; j ++) *p ++ = i; for (i = 0; i < 256; i ++) *p ++ = i; for (i = 0; i < 256; i ++) *p ++ = 255 - i; for (i = 0; i < 128; i ++) *p ++ = 0; for (i = 0; i < 128; i ++) *p ++ = 0x20; } /* Decode LArc type 5 */ DecodeOld () { register int si, di; register long count; int dl, dh, al, cx; if (textsize == 0) return; InitBuf (); di = N - F_OLD; dl = 0x80; for (count = 0; count < textsize; ) { dl = ((dl << 1) | (dl >> 7)) & 0xff; if (dl & 0x01) dh = getc (infile); al = getc (infile); if ((dh & dl) != 0) { PUTC_CRC (al); text_buf[di] = al; di = (di + 1) & (N - 1); count ++; } else { cx = getc (infile); si = (al & 0x00ff) | ((cx << 4) & 0x0f00); cx = (cx & 0x000f) + 3; count += cx; do { text_buf[di] = al = text_buf[si]; PUTC_CRC (al); si = (si + 1) & (N - 1); di = (di + 1) & (N - 1); } while (--cx != 0) ; } if (!quiet && (count > indicator_count)) { putchar (BALL); fflush (stdout); indicator_count += indicator_threshold; } } END_PUTC_CRC (); } /*----------------------------------------------------------------------*/ /* */ /* Global Entries for Archiver Driver */ /* */ /*----------------------------------------------------------------------*/ start_indicator (name, size, msg) char *name; long size; char *msg; { long i; int m; if (quiet) return; #ifdef ANSI m = MAX_INDICATOR_COUNT; #else m = MAX_INDICATOR_COUNT - strlen (name); #endif if (m < 0) m = 3; /* (^_^) */ #ifdef ANSI printf ("\r%s - %s:\n", name, msg); #else printf ("\r%s - %s : ", name, msg); #endif indicator_threshold = ((size + (m * INDICATOR_THRESHOLD - 1)) / (m * INDICATOR_THRESHOLD) * INDICATOR_THRESHOLD); /* bug fix for files with size==0 28.03.1990 SB */ if (indicator_threshold == 0) indicator_threshold = INDICATOR_THRESHOLD; /************************************************/ i = ((size + (indicator_threshold - 1)) / indicator_threshold); while (i--) putchar (DOT); indicator_count = 0; #ifdef ANSI printf ("\r%s%s - %s:\n", CURSORUP, name, msg); #else printf ("\r%s - %s : ", name, msg); #endif fflush (stdout); } finish_indicator2 (name, msg, pcnt) char *name; char *msg; int pcnt; { if (quiet) return; if (pcnt > 100) pcnt = 100; /* (^_^) */ #ifdef ANSI printf ("\r%s%s - %s(%d%%)\n%s", CURSORUP, name, msg, pcnt, ERASEEOL); #else printf ("\r%s - %s(%d%%)\n", name, msg, pcnt); #endif fflush (stdout); } finish_indicator (name, msg) char *name; char *msg; { if (quiet) return; #ifdef ANSI printf ("\r%s%s - %s\n%s", CURSORUP, name, msg, ERASEEOL); #else printf ("\r%s - %s\n", name, msg); #endif fflush (stdout); } #ifndef SELFMAIN int encode_lzhuf (infp, outfp, size, original_size_var, packed_size_var, name) FILE *infp; FILE *outfp; long size; long *original_size_var; long *packed_size_var; char *name; { infile = infp; outfile = outfp; SETUP_GETC_CRC(infp); textsize = size; codesize = 0; init_crc (); start_indicator (name, size, "Freezing"); Encode (); finish_indicator2 (name, "Frozen", (int)((codesize * 100L) / crc_size)); *packed_size_var = codesize; *original_size_var = crc_size; return crc_value; } int decode_lzhuf (infp, outfp, original_size, name) FILE *infp; FILE *outfp; long original_size; char *name; { infile = infp; outfile = outfp; SETUP_PUTC_CRC(outfp); textsize = original_size; init_crc (); start_indicator (name, original_size, (output_to_test ? "Testing" : "Melting")); Decode (); finish_indicator (name, (output_to_test ? "Tested " : "Melted ")); return crc_value; } int decode_larc (infp, outfp, original_size, name) FILE *infp, *outfp; long original_size; char *name; { infile = infp; outfile = outfp; SETUP_PUTC_CRC(outfp); textsize = original_size; init_crc (); start_indicator (name, original_size, (output_to_test ? "Testing" : "Melting")); DecodeOld (); finish_indicator (name, (output_to_test ? "Tested " : "Melted ")); return crc_value; } #endif #ifdef SELFMAIN int main (argc, argv) int argc; char *argv[]; { char *s; int i; indicator_count = 0; indicator_threshold = 1024; textsize = codesize = 0; if (argc != 4) { printf ("\ usage: lzhuf e in_file out_file (packing)\n\ lzhuf d in_file out_file (unpacking)\n"); return EXIT_FAILURE; } if ((s = argv[1], ((*s != 'e') && (*s != 'd')) || s[1] != '\0') || (s = argv[2], (infile = fopen(s, "rb")) == NULL) || (s = argv[3], (outfile = fopen(s, "wb")) == NULL)) { printf("??? %s\n", s); return EXIT_FAILURE; } if (argv[1][0] == 'e') { /* Get original text size and output it */ fseek(infile, 0L, 2); textsize = ftell(infile); rewind (infile); if (fwrite(&textsize, sizeof textsize, 1, outfile) < 1) Error("cannot write"); start_indicator (argv[2], textsize, "Freezing"); Encode(); finith_indicator2 (argv[2], "Frozen", (int)((codesize * 100L) / textsize)); printf("input : %ld bytes\n", textsize); printf("output: %ld bytes\n", codesize); } else { /* Read original text size */ if (fread(&textsize, sizeof textsize, 1, infile) < 1) Error("cannot read"); start_indicator (argv[2], textsize, "Melting"); Decode(); finish_indicator (argv[2], "Melted "); } fclose(infile); fclose(outfile); return EXIT_SUCCESS; } #endif /* These lines are used in GNU-Emacs */ /* Local Variables: */ /* comment-column:40 */ /* tab-width:8 */ /* c-indent-level:8 */ /* c-continued-statement-offset:8 */ /* c-argdecl-indent:8 */ /* End: */ 6bit from table */ i = GetByte(); c = (unsigned)d_code[i] << 6; j = d_len[i]; /* get lower 6bit */ j -= 2; return c | (((i << j) | GetNBits (j)) & 0x3f); } Encode () { register int i, c, len, r, s, last_match_length; if (textsize == 0) return; textsize = 0; StartHuff(); InitTree(); s = 0; r = N - F; for (i = s; i < r; i++) text_buf[i] = ' '; for (len = 0; len < F &&mktemp.c 666 75616 51013 634 5110114714 5672 /* MKTEMP.C using TMP environment variable */ #include #include #include #include void Mktemp(char *file) { char fname[32], *tmp; tmp = getenv("TMP"); if ( tmp != NULL ) { strcpy(fname, file); strcpy(file, tmp); if ( file[strlen(file) - 1] != '\\' ) strcat(file, "\\"); strcat(file, fname); } mktemp(file); } /* End of MKTEMP.C */ nfp; outfile = outfp; SETUP_PUTC_CRC(outfp); textsize = original_size; init_crc (); starpipes.c 666 75616 51013 2134 5110114714 5532 /* a simulation for the Unix popen() and pclose() calls on MS-DOS */ /* only one pipe can be open at a time */ #include #include #include static char pipename[128], command[128]; static int wrpipe; extern void Mktemp(char *); FILE *popen(char *cmd, char *flags) { wrpipe = (strchr(flags, 'w') != NULL); if ( wrpipe ) { strcpy(command, cmd); strcpy(pipename, "~WXXXXXX"); Mktemp(pipename); return fopen(pipename, flags); /* ordinary file */ } else { strcpy(pipename, "~RXXXXXX"); Mktemp(pipename); strcpy(command, cmd); strcat(command, ">"); strcat(command, pipename); system(command); return fopen(pipename, flags); /* ordinary file */ } } int pclose(FILE *pipe) { int rc; if ( fclose(pipe) == EOF ) return EOF; if ( wrpipe ) { if ( command[strlen(command) - 1] == '!' ) command[strlen(command) - 1] = 0; else strcat(command, "<"); strcat(command, pipename); rc = system(command); unlink(pipename); return rc; } else { unlink(pipename); return 0; } } ted " : "Melted ")); return crc_value; } #endif #ifdef SELFMAIN int main (argc, argv) int argc; char *argv[]; { char *s; int i; indicator_count = 0; indicator_threshold = 1024; textsize = codesize = 0; if (argc != 4) { printf ("\ usage: lzhuf e in_file out_file (packing)\n\ lzhuf d in_file out_file (unpacking)\n"); return EXIT_FAILURE; } if ((s = argv[1], ((*s != 'e') && (*s != 'd')) || s[1clharc.cs 666 75616 51013 165 5110114706 6014 (-W1 lharc.c lhio.c dir_os2.c mktemp.c pipes.c) (-W1 -Ox lzhuf.c) setargv.obj clharc.def clharc.exe -as -lb -s0x2000 ude #include #include static char pipename[128], command[128]; static int wrpipe; extern void Mktemp(char *); FILE *popen(char *cmd, char *flags) { wrpipe = (strchr(flags, 'w') != NULL); if ( wrpipe ) { strcpy(command, cmd); strcpy(pipename, "~WXXXXXX"); Mktemp(pipename); return fopen(pipename, flags); /* ordinary file */ } else clharc.def 666 75616 51013 112 5110114706 6135 NAME CLHARC WINDOWCOMPAT DESCRIPTION 'C-LHarc 1.00 - for MS-DOS and OS/2' obj clharc.def clharc.exe -as -lb -s0x2000 ude #include #include static char pipename[128], command[128]; static int wrpipe; extern void Mktemp(char *); FILE *popen(char *cmd, char *flags) { wrpipe = (strchr(flags, 'w') != NULL); if ( wrpipe ) { strcpy(command, cmd); strcpy(pipename, "~WXXXXXX"); Mktemp(pipename); return fopen(pipename, flags); /* ordinary file */ } else esting" : "Melting")); DecodeOld (); finish_indicator (name, (output_to_test ? "Tested " : "Melted ")); return crc_value; } #endif #ifdef SELFMAIN int main (argc, argv) int argc; char *argv[]; { char *s; int i; indicator_count = 0; indicator_threshold = 1024; textsize = codesize = 0; if (argc != 4) { printf ("\ usage: lzhuf e in_file out_file (packing)\n\ lzhuf d in_file out_file (unpacking)\n"); return EXIT_FAILURE; } if ((s = argv[1], ((*s != 'e') && (*s != 'd')) || s[1] != '\0') || (s = argv[2], (infile = fopen(s, "rb")) == NULL) || (s = argv[3], (outfile = fopen(s, "wb")) == NULL)) { printf("??? %s\n", s); return EXIT_FAILURE; } if (argv[1][0] == 'e') { /* Get original text size and output it */ fseek(infile, 0L, 2); textsize = ftell(infile); rewind (infile); if (fwrite(&textsize, sizeof textsize, 1, outfile) < 1) Error("cannot write"); start_indicator (argv[2], textsize, "Freezing"); Encode(); finith_indicator2 (argv[2], "Frozen", (int)((codesize * 100L) / textsize)); printf("input : %ld bytes\n", textsize); printf("output: %ld bytes\n", codesize); } else { /* Read original text size */ if (fread(&textsize, sizeof textsize, 1, infile) < 1) Error("cannot read"); start_indicator (argv[2], textsize, "Melting"); Decode(); finish_indicator (argv[2], "Melted "); } fclose(infile); fclose(outfile); return EXIT_SUCCESS; } #endif /* These lines are used in GNU-Emacs */ /* Local Variables: */ /* comment-column:40 */ /* tab-width:8 */ /* c-indent-level:8 */ /* c-continued-statement-offset:8 */ /* c-argdecl-indent:8 */ /* End: */ 6bit from table */ i = GetByte(); c = (unsigned)d_code[i] << 6; j = d_len[i]; /* get lower 6bit */ j -= 2; return c | (((i << j) | GetNBits (j)) & 0x3f); } Encode () { register int i, c, len, r, s, last_match_length; if (textsize == 0) return; textsize = 0; StartHuff(); InitTree(); s = 0; r = N - F; for (i = s; i < r; i++) text_buf[i] = ' '; for (len = 0; len < F &&mktemp.c 666 75616 51013 634 5110114714 5672 /* MKTEMP.C using TMP environment variable */ #include #include #include #include void Mktemp(char *file) { char fname[32], *tmp; tmp = getenv("TMP"); if ( tmp != NULL ) { strcpy(fname, file); strcpy(file, tmp); if ( file[strlen(file) - 1] != '\\' ) strcat(file, "\\"); strcat(file, fname); } mktemp(file); } /* End of MKTEMP.C */ nfp; outfile = outfp; SETUP_PUTC_CRC(outfp); textsize = original_size; init_crc (); starpipes.c 666 75616 51013 2134 5110114714 5532 /* a simulation for the Unix popen() and pclose() calls on MS-DOS */ /* only one pipe can be open at a time */ #include #include #include static char pipename[128], command[128]; static int wrpipe; extern void Mktemp(char *); FILE *popen(char *cmd, char *flags) { wrpipe = (strchr(flags, 'w') != NULL); if ( wrpipe ) { strcpy(command, cmd); strcpy(pipename, "~WXXXXXX"); Mktemp(pipename); return fopen(pipename, flags); /* ordinary file */ } else { strcpy(pipename, "~RXXXXXX"); Mktemp(pipename); strcpy(command, cmd); strcat(command, ">"); strcat(command, pipename); system(command); return fopen(pipename, flags); /* ordinary file */ } } int pclose(FILE *pipe) { int rc; if ( fclose(pipe) == EOF ) return EOF; if ( wrpipe ) { if ( command[strlen(command) - 1] == '!' ) command[strlen(command) - 1] = 0; else strcat(command, "<"); strcat(command, pipename); rc = system(command); unlink(pipename); return rc; } else { unlink(pipename); return 0; } } ted " : "Melted ")); return crc_value; } #endif #ifdef SELFMAIN int main (argc, argv) int argc; char *argv[]; { char *s; int i; indicator_count = 0; indicator_threshold = 1024; textsize = codesize = 0; if (argc != 4) { printf ("\ usage: lzhuf e in_file out_file (packing)\n\ lzhuf d in_file out_file (unpacking)\n"); return EXIT_FAILURE; } if ((s = argv[1], ((*s != 'e') && (*s != 'd')) || s[1clharc.cs 666 75616 51013 165 5110114706 6014 (-W1 lharc.c lhio.c dir_os2.c mktemp.c pipes.c) (-W1 -Ox lzhuf.c) setargv.obj clharc.def clharc.exe -as -lb -s0x2000 ude #include #include static char pipename[128], command[128]; static int wrpipe; extern void Mktemp(char *); FILE *popen(char *cmd, char *flags) { wrpipe = (strchr(flags, 'w') != NULL); if ( wrpipe ) { strcpy(command, cmd); strcpy(pipename, "~WXXXXXX"); Mktemp(pipename); return fopen(pipename, flags); /* ordinary file */ } else clharc.def 666 75616 51013 112 5110114706 6135 NAME CLHARC WINDOWCOMPAT DESCRIPTION 'C-LHarc 1.00 - for MS-DOS and OS/2' obj clharc.def clharc.exe -as -lb -s0x2000 ude #include #include static char pipename[128], command[128]; static int wrpipe; extern void Mktemp(char *); FILE *popen(char *cmd, char *flags) { wrpipe = (strchr(flags, 'w') != NULL); if ( wrpipe ) { strcpy(command, cmd); strcpy(pipename, "~WXXXXXX"); Mktemp(pipename); return fopen(pipename, flags); /* ordinary file */ } else