syncing 2.3.0

parent b7c7e36d
AM_CPPFLAGS = @UAE_CPPFLAGS@
AM_CPPFLAGS += -I$(top_srcdir)/src/include -I$(top_builddir)/src -I$(top_srcdir)/src
AM_CFLAGS = @UAE_CFLAGS@
noinst_LIBRARIES = libdms.a
libdms_a_SOURCES = crc_csum.c getbits.c maketbl.c pfile.c tables.c \
u_deep.c u_heavy.c u_init.c u_medium.c u_quick.c \
u_rle.c
noinst_HEADERS = cdata.h crc_csum.h getbits.h maketbl.h pfile.h tables.h \
u_deep.h u_heavy.h u_init.h u_medium.h u_quick.h u_rle.h
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = src/archivers/dms
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \
$(top_srcdir)/m4/as-objc.m4 \
$(top_srcdir)/m4/ax_check_compiler_flags.m4 \
$(top_srcdir)/m4/ax_gcc_archflag.m4 \
$(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \
$(top_srcdir)/m4/framework.m4 $(top_srcdir)/m4/fsusage.m4 \
$(top_srcdir)/m4/gtk-2.0.m4 $(top_srcdir)/m4/gtk.m4 \
$(top_srcdir)/m4/sdl.m4 $(top_srcdir)/m4/type_socklen_t.m4 \
$(top_srcdir)/m4/uintmax_t.m4 $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/sysconfig.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LIBRARIES = $(noinst_LIBRARIES)
ARFLAGS = cru
libdms_a_AR = $(AR) $(ARFLAGS)
libdms_a_LIBADD =
am_libdms_a_OBJECTS = crc_csum.$(OBJEXT) getbits.$(OBJEXT) \
maketbl.$(OBJEXT) pfile.$(OBJEXT) tables.$(OBJEXT) \
u_deep.$(OBJEXT) u_heavy.$(OBJEXT) u_init.$(OBJEXT) \
u_medium.$(OBJEXT) u_quick.$(OBJEXT) u_rle.$(OBJEXT)
libdms_a_OBJECTS = $(am_libdms_a_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libdms_a_SOURCES)
DIST_SOURCES = $(libdms_a_SOURCES)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
ASMOBJS = @ASMOBJS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BSDSOCKOBJS = @BSDSOCKOBJS@
CC = @CC@
CCAS = @CCAS@
CCASDEPMODE = @CCASDEPMODE@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CDOBJS = @CDOBJS@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPUOBJS = @CPUOBJS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEBUGOBJS = @DEBUGOBJS@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
EXTRAOBJS = @EXTRAOBJS@
FILEPRG = @FILEPRG@
FILESYSOBJS = @FILESYSOBJS@
GENCPUOPTS = @GENCPUOPTS@
GFX_DEP = @GFX_DEP@
GREP = @GREP@
GTK_CFLAGS = @GTK_CFLAGS@
GTK_CONFIG = @GTK_CONFIG@
GTK_LIBS = @GTK_LIBS@
GUI_DEP = @GUI_DEP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JITOBJS = @JITOBJS@
JOY_DEP = @JOY_DEP@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MACHDEP = @MACHDEP@
MAKEDEPPRG = @MAKEDEPPRG@
MAKEINFO = @MAKEINFO@
MATHLIB = @MATHLIB@
MKDIR_P = @MKDIR_P@
NO_SCHED_CFLAGS = @NO_SCHED_CFLAGS@
OBJC = @OBJC@
OBJCDEPMODE = @OBJCDEPMODE@
OBJC_LDFLAGS = @OBJC_LDFLAGS@
OBJEXT = @OBJEXT@
OSDEP = @OSDEP@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PRTDIAG = @PRTDIAG@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
RCLPRG = @RCLPRG@
RESOBJS = @RESOBJS@
SCSIOBJS = @SCSIOBJS@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SND_DEP = @SND_DEP@
STRIP = @STRIP@
TARGET = @TARGET@
THREADDEP = @THREADDEP@
UAE_CFLAGS = @UAE_CFLAGS@
UAE_CPPFLAGS = @UAE_CPPFLAGS@
UAE_LIBS = @UAE_LIBS@
UAE_RSRCFILE = @UAE_RSRCFILE@
VERSION = @VERSION@
WRCPRG = @WRCPRG@
XMKMF = @XMKMF@
X_CFLAGS = @X_CFLAGS@
X_EXTRA_LIBS = @X_EXTRA_LIBS@
X_LIBS = @X_LIBS@
X_PRE_LIBS = @X_PRE_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_OBJC = @ac_ct_OBJC@
ac_cv_c_inline = @ac_cv_c_inline@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CPPFLAGS = @UAE_CPPFLAGS@ -I$(top_srcdir)/src/include \
-I$(top_builddir)/src -I$(top_srcdir)/src
AM_CFLAGS = @UAE_CFLAGS@
noinst_LIBRARIES = libdms.a
libdms_a_SOURCES = crc_csum.c getbits.c maketbl.c pfile.c tables.c \
u_deep.c u_heavy.c u_init.c u_medium.c u_quick.c \
u_rle.c
noinst_HEADERS = cdata.h crc_csum.h getbits.h maketbl.h pfile.h tables.h \
u_deep.h u_heavy.h u_init.h u_medium.h u_quick.h u_rle.h
all: all-am
.SUFFIXES:
.SUFFIXES: .c .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/archivers/dms/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/archivers/dms/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
libdms.a: $(libdms_a_OBJECTS) $(libdms_a_DEPENDENCIES)
-rm -f libdms.a
$(libdms_a_AR) libdms.a $(libdms_a_OBJECTS) $(libdms_a_LIBADD)
$(RANLIB) libdms.a
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc_csum.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getbits.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maketbl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pfile.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tables.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_deep.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_heavy.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_init.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_medium.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_quick.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u_rle.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LIBRARIES) $(HEADERS)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-noinstLIBRARIES ctags distclean distclean-compile \
distclean-generic distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* Main types of variables used in xDMS, some implementation
* dependant features and other global stuff
*/
#ifndef UCHAR
#define UCHAR unsigned char
#endif
#ifndef USHORT
#define USHORT unsigned short
#endif
#ifndef SHORT
#define SHORT short
#endif
#ifndef ULONG
#define ULONG unsigned long
#endif
#ifndef INLINE
#ifdef __cplusplus
#define INLINE inline
#else
#ifdef __GNUC__
#define INLINE inline
#else
#ifdef __SASC
#define INLINE __inline
#else
#define INLINE static
#endif
#endif
#endif
#endif
#ifndef UNDER_DOS
#ifdef __MSDOS__
#define UNDER_DOS
#else
#ifdef __MSDOS
#define UNDER_DOS
#else
#ifdef _OS2
#define UNDER_DOS
#else
#ifdef _QC
#define UNDER_DOS
#endif
#endif
#endif
#endif
#endif
#ifndef DIR_CHAR
#ifdef UNDER_DOS
/* running under MSDOS or DOS-like OS */
#define DIR_CHAR '\\'
#else
#define DIR_CHAR '/'
#endif
#endif
#define DIR_SEPARATORS ":\\/"
extern UCHAR *dms_text;
extern USHORT dms_lastlen, dms_np;
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* CRC16 & CheckSum16 calculation functions
* CreateCRC was written (aparently) by Bjorn Stenberg
*
*/
#include "cdata.h"
#include "crc_csum.h"
USHORT dms_Calc_CheckSum(UCHAR *mem, ULONG size){
USHORT u=0;
while(size--) u += *mem++;
return (USHORT)(u & 0xffff);
}
USHORT dms_CreateCRC(UCHAR* mem, ULONG size ){
static USHORT CRCTab[256]={
0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,
0xC601,0x06C0,0x0780,0xC741,0x0500,0xC5C1,0xC481,0x0440,
0xCC01,0x0CC0,0x0D80,0xCD41,0x0F00,0xCFC1,0xCE81,0x0E40,
0x0A00,0xCAC1,0xCB81,0x0B40,0xC901,0x09C0,0x0880,0xC841,
0xD801,0x18C0,0x1980,0xD941,0x1B00,0xDBC1,0xDA81,0x1A40,
0x1E00,0xDEC1,0xDF81,0x1F40,0xDD01,0x1DC0,0x1C80,0xDC41,
0x1400,0xD4C1,0xD581,0x1540,0xD701,0x17C0,0x1680,0xD641,
0xD201,0x12C0,0x1380,0xD341,0x1100,0xD1C1,0xD081,0x1040,
0xF001,0x30C0,0x3180,0xF141,0x3300,0xF3C1,0xF281,0x3240,
0x3600,0xF6C1,0xF781,0x3740,0xF501,0x35C0,0x3480,0xF441,
0x3C00,0xFCC1,0xFD81,0x3D40,0xFF01,0x3FC0,0x3E80,0xFE41,
0xFA01,0x3AC0,0x3B80,0xFB41,0x3900,0xF9C1,0xF881,0x3840,
0x2800,0xE8C1,0xE981,0x2940,0xEB01,0x2BC0,0x2A80,0xEA41,
0xEE01,0x2EC0,0x2F80,0xEF41,0x2D00,0xEDC1,0xEC81,0x2C40,
0xE401,0x24C0,0x2580,0xE541,0x2700,0xE7C1,0xE681,0x2640,
0x2200,0xE2C1,0xE381,0x2340,0xE101,0x21C0,0x2080,0xE041,
0xA001,0x60C0,0x6180,0xA141,0x6300,0xA3C1,0xA281,0x6240,
0x6600,0xA6C1,0xA781,0x6740,0xA501,0x65C0,0x6480,0xA441,
0x6C00,0xACC1,0xAD81,0x6D40,0xAF01,0x6FC0,0x6E80,0xAE41,
0xAA01,0x6AC0,0x6B80,0xAB41,0x6900,0xA9C1,0xA881,0x6840,
0x7800,0xB8C1,0xB981,0x7940,0xBB01,0x7BC0,0x7A80,0xBA41,
0xBE01,0x7EC0,0x7F80,0xBF41,0x7D00,0xBDC1,0xBC81,0x7C40,
0xB401,0x74C0,0x7580,0xB541,0x7700,0xB7C1,0xB681,0x7640,
0x7200,0xB2C1,0xB381,0x7340,0xB101,0x71C0,0x7080,0xB041,
0x5000,0x90C1,0x9181,0x5140,0x9301,0x53C0,0x5280,0x9241,
0x9601,0x56C0,0x5780,0x9741,0x5500,0x95C1,0x9481,0x5440,
0x9C01,0x5CC0,0x5D80,0x9D41,0x5F00,0x9FC1,0x9E81,0x5E40,
0x5A00,0x9AC1,0x9B81,0x5B40,0x9901,0x59C0,0x5880,0x9841,
0x8801,0x48C0,0x4980,0x8941,0x4B00,0x8BC1,0x8A81,0x4A40,
0x4E00,0x8EC1,0x8F81,0x4F40,0x8D01,0x4DC0,0x4C80,0x8C41,
0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641,
0x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040
};
register USHORT CRC = 0;
while(size--)
CRC = (USHORT) (CRCTab[((CRC ^ *mem++) & 255)] ^ ((CRC >> 8) & 255));
return CRC;
}
USHORT dms_Calc_CheckSum(UCHAR *, ULONG);
USHORT dms_CreateCRC(UCHAR *, ULONG);
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
* Functions/macros to get a variable number of bits
*
*/
#include "cdata.h"
#include "getbits.h"
ULONG dms_mask_bits[]={
0x000000L,0x000001L,0x000003L,0x000007L,0x00000fL,0x00001fL,
0x00003fL,0x00007fL,0x0000ffL,0x0001ffL,0x0003ffL,0x0007ffL,
0x000fffL,0x001fffL,0x003fffL,0x007fffL,0x00ffffL,0x01ffffL,
0x03ffffL,0x07ffffL,0x0fffffL,0x1fffffL,0x3fffffL,0x7fffffL,
0xffffffL
};
UCHAR *dms_indata, dms_bitcount;
ULONG dms_bitbuf;
void initbitbuf(UCHAR *in){
dms_bitbuf = 0;
dms_bitcount = 0;
dms_indata = in;
DROPBITS(0);
}
extern ULONG dms_mask_bits[], dms_bitbuf;
extern UCHAR *dms_indata, dms_bitcount;
#define GETBITS(n) ((USHORT)(dms_bitbuf >> (dms_bitcount-(n))))
#define DROPBITS(n) {dms_bitbuf &= dms_mask_bits[dms_bitcount-=(n)]; while (dms_bitcount<16) {dms_bitbuf = (dms_bitbuf << 8) | *dms_indata++; dms_bitcount += 8;}}
void initbitbuf(UCHAR *);
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* Makes decoding table for Heavy LZH decompression
* From UNIX LHA made by Masaru Oki
*
*/
#include "cdata.h"
#include "maketbl.h"
static SHORT c;
static USHORT n, tblsiz, len, depth, maxdepth, avail;
static USHORT codeword, bit, *tbl, TabErr;
static UCHAR *blen;
static USHORT mktbl(void);
USHORT dms_make_table(USHORT nchar, UCHAR bitlen[],USHORT tablebits, USHORT table[]){
n = avail = nchar;
blen = bitlen;
tbl = table;
tblsiz = (USHORT) (1U << tablebits);
bit = (USHORT) (tblsiz / 2);
maxdepth = (USHORT)(tablebits + 1);
depth = len = 1;
c = -1;
codeword = 0;
TabErr = 0;
mktbl(); /* left subtree */
if (TabErr) return TabErr;
mktbl(); /* right subtree */
if (TabErr) return TabErr;
if (codeword != tblsiz) return 5;
return 0;
}
static USHORT mktbl(void){
USHORT i=0;
if (TabErr) return 0;
if (len == depth) {
while (++c < n)
if (blen[c] == len) {
i = codeword;
codeword += bit;
if (codeword > tblsiz) {
TabErr=1;
return 0;
}
while (i < codeword) tbl[i++] = (USHORT)c;
return (USHORT)c;
}
c = -1;
len++;
bit >>= 1;
}
depth++;
if (depth < maxdepth) {
mktbl();
mktbl();
} else if (depth > 32) {
TabErr = 2;
return 0;
} else {
if ((i = avail++) >= 2 * n - 1) {
TabErr = 3;
return 0;
}
dms_left[i] = mktbl();
dms_right[i] = mktbl();
if (codeword >= tblsiz) {
TabErr = 4;
return 0;
}
if (depth == maxdepth) tbl[codeword++] = i;
}
depth--;
return i;
}
extern USHORT dms_left[], dms_right[];
USHORT dms_make_table(USHORT nchar, UCHAR bitlen[], USHORT tablebits, USHORT table[]);
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* Handles the processing of a single DMS archive
*
*/
#define HEADLEN 56
#define THLEN 20
#define TRACK_BUFFER_LEN 32000
#define TEMP_BUFFER_LEN 32000
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "sysconfig.h"
#include "sysdeps.h"
#include "zfile.h"
#include "cdata.h"
#include "u_init.h"
#include "u_rle.h"
#include "u_quick.h"
#include "u_medium.h"
#include "u_deep.h"
#include "u_heavy.h"
#include "crc_csum.h"
#include "pfile.h"
static int dolog = 0;
#define DMSFLAG_ENCRYPTED 2
#define DMSFLAG_HD 16
static USHORT Process_Track(struct zfile *, struct zfile *, UCHAR *, UCHAR *, USHORT, USHORT, int, struct zfile **extra);
static USHORT Unpack_Track(UCHAR *, UCHAR *, USHORT, USHORT, UCHAR, UCHAR, USHORT, USHORT, USHORT, int);
static void printbandiz(UCHAR *, USHORT);
static int passfound, passretries;
static TCHAR modes[7][7]={"NOCOMP","SIMPLE","QUICK ","MEDIUM","DEEP ","HEAVY1","HEAVY2"};
static USHORT PWDCRC;
UCHAR *dms_text;
static void log_error(int track)
{
write_log ("DMS: Ignored error on track %d!\n", track);
}
static void addextra(TCHAR *name, struct zfile **extra, uae_u8 *p, int size)
{
int i;
struct zfile *zf = NULL;
if (!extra)
return;
for (i = 0; i < DMS_EXTRA_SIZE; i++) {
if (!extra[i])
break;
}
if (i == DMS_EXTRA_SIZE)
return;
zf = zfile_fopen_empty (NULL, name, size);
if (!zf)
return;
zfile_fwrite (p, size, 1, zf);
zfile_fseek (zf, 0, SEEK_SET);
extra[i] = zf;
}
USHORT DMS_Process_File(struct zfile *fi, struct zfile *fo, USHORT cmd, USHORT opt, USHORT PCRC, USHORT pwd, int part, struct zfile **extra)
{
USHORT from, to, geninfo, c_version, cmode, hcrc, disktype, pv, ret;
ULONG pkfsize, unpkfsize;
UCHAR *b1, *b2;
time_t date;
passfound = 0;
passretries = 2;
b1 = xcalloc(UCHAR,TRACK_BUFFER_LEN);
if (!b1) return ERR_NOMEMORY;
b2 = xcalloc(UCHAR,TRACK_BUFFER_LEN);
if (!b2) {
free(b1);
return ERR_NOMEMORY;
}
dms_text = xcalloc(UCHAR,TEMP_BUFFER_LEN);
if (!dms_text) {
free(b1);
free(b2);
return ERR_NOMEMORY;
}
/* if iname is NULL, input is stdin; if oname is NULL, output is stdout */
if (zfile_fread(b1,1,HEADLEN,fi) != HEADLEN) {
free(b1);
free(b2);
free(dms_text);
return ERR_SREAD;
}
if ( (b1[0] != 'D') || (b1[1] != 'M') || (b1[2] != 'S') || (b1[3] != '!') ) {
/* Check the first 4 bytes of file to see if it is "DMS!" */
free(b1);
free(b2);
free(dms_text);
return ERR_NOTDMS;
}
hcrc = (USHORT)((b1[HEADLEN-2]<<8) | b1[HEADLEN-1]);
/* Header CRC */
if (hcrc != dms_CreateCRC(b1+4,(ULONG)(HEADLEN-6))) {
free(b1);
free(b2);
free(dms_text);
return ERR_HCRC;
}
geninfo = (USHORT) ((b1[10]<<8) | b1[11]); /* General info about archive */
date = (time_t) ((((ULONG)b1[12])<<24) | (((ULONG)b1[13])<<16) | (((ULONG)b1[14])<<8) | (ULONG)b1[15]); /* date in standard UNIX/ANSI format */
from = (USHORT) ((b1[16]<<8) | b1[17]); /* Lowest track in archive. May be incorrect if archive is "appended" */
to = (USHORT) ((b1[18]<<8) | b1[19]); /* Highest track in archive. May be incorrect if archive is "appended" */
if (part && from < 30) {
free(b1);
free(b2);
free(dms_text);
return DMS_FILE_END;
}
pkfsize = (ULONG) ((((ULONG)b1[21])<<16) | (((ULONG)b1[22])<<8) | (ULONG)b1[23]); /* Length of total packed data as in archive */
unpkfsize = (ULONG) ((((ULONG)b1[25])<<16) | (((ULONG)b1[26])<<8) | (ULONG)b1[27]); /* Length of unpacked data. Usually 901120 bytes */
c_version = (USHORT) ((b1[46]<<8) | b1[47]); /* version of DMS used to generate it */
disktype = (USHORT) ((b1[50]<<8) | b1[51]); /* Type of compressed disk */
cmode = (USHORT) ((b1[52]<<8) | b1[53]); /* Compression mode mostly used in this archive */
PWDCRC = PCRC;
if (dolog) {
pv = (USHORT)(c_version/100);
write_log (" Created with DMS version %d.%02d ",pv,c_version-pv*100);
if (geninfo & 0x80)
write_log ("Registered\n");
else
write_log ("Evaluation\n");
write_log (" Creation date : %s",ctime(&date));
write_log (" Lowest track in archive : %d\n",from);
write_log (" Highest track in archive : %d\n",to);
write_log (" Packed data size : %lu\n",pkfsize);
write_log (" Unpacked data size : %lu\n",unpkfsize);
write_log (" Disk type of archive : ");
/* The original DMS from SDS software (DMS up to 1.11) used other values */
/* in disk type to indicate formats as MS-DOS, AMax and Mac, but it was */
/* not suported for compression. It was for future expansion and was never */
/* used. The newer versions of DMS made by ParCon Software changed it to */
/* add support for new Amiga disk types. */
switch (disktype) {
case 0:
case 1:
/* Can also be a non-dos disk */
write_log ("AmigaOS 1.0 OFS\n");
break;
case 2:
write_log ("AmigaOS 2.0 FFS\n");
break;
case 3:
write_log ("AmigaOS 3.0 OFS / International\n");
break;
case 4:
write_log ("AmigaOS 3.0 FFS / International\n");
break;
case 5:
write_log ("AmigaOS 3.0 OFS / Dir Cache\n");
break;
case 6:
write_log ("AmigaOS 3.0 FFS / Dir Cache\n");
break;
case 7:
write_log ("FMS Amiga System File\n");
break;
default:
write_log ("Unknown\n");
}
write_log (" Compression mode used : ");
if (cmode>6)
write_log ("Unknown !\n");
else
write_log ("%s\n",modes[cmode]);
write_log (" General info : ");
if ((geninfo==0)||(geninfo==0x80)) write_log ("None");
if (geninfo & 1) write_log ("NoZero ");
if (geninfo & 2) write_log ("Encrypted ");
if (geninfo & 4) write_log ("Appends ");
if (geninfo & 8) write_log ("Banner ");
if (geninfo & 16) write_log ("HD ");
if (geninfo & 32) write_log ("MS-DOS ");
if (geninfo & 64) write_log ("DMS_DEV_Fixed ");
if (geninfo & 256) write_log ("FILEID.DIZ");
write_log ("\n");
write_log (" Info Header CRC : %04X\n\n",hcrc);
}
if (disktype == 7) {
/* It's not a DMS compressed disk image, but a FMS archive */
free(b1);
free(b2);
free(dms_text);
return ERR_FMS;
}
if (dolog) {
write_log (" Track Plength Ulength Cmode USUM HCRC DCRC Cflag\n");
write_log (" ------ ------- ------- ------ ---- ---- ---- -----\n");
}
// if (((cmd==CMD_UNPACK) || (cmd==CMD_SHOWBANNER)) && (geninfo & 2) && (!pwd))
// return ERR_NOPASSWD;
ret=NO_PROBLEM;
Init_Decrunchers();
if (cmd != CMD_VIEW) {
if (cmd == CMD_SHOWBANNER) /* Banner is in the first track */
ret = Process_Track(fi,NULL,b1,b2,cmd,opt,geninfo,extra);
else {
for (;;) {
int ok = 0;
ret = Process_Track(fi,fo,b1,b2,cmd,opt,geninfo,extra);
if (ret == DMS_FILE_END)
break;
if (ret == NO_PROBLEM)
continue;
break;
#if 0
while (!ok) {
uae_u8 b1[THLEN];
if (zfile_fread(b1,1,THLEN,fi) != 1) {
write_log ("DMS: unexpected end of file\n");
break;
}
write_log ("DMS: corrupted track, searching for next track header..\n");
if (b1[0] == 'T' && b1[1] == 'R') {
USHORT hcrc = (USHORT)((b1[THLEN-2] << 8) | b1[THLEN-1]);
if (CreateCRC(b1,(ULONG)(THLEN-2)) == hcrc) {
write_log ("DMS: found checksum correct track header, retrying..\n");
zfile_fseek (fi, SEEK_CUR, -THLEN);
ok = 1;
break;
}
}
if (!ok)
zfile_fseek (fi, SEEK_CUR, -(THLEN - 1));
}
#endif
}
}
}
if ((cmd == CMD_VIEWFULL) || (cmd == CMD_SHOWDIZ) || (cmd == CMD_SHOWBANNER)) write_log ("\n");
if (ret == DMS_FILE_END) ret = NO_PROBLEM;
/* Used to give an error message, but I have seen some DMS */
/* files with texts or zeros at the end of the valid data */
/* So, when we find something that is not a track header, */
/* we suppose that the valid data is over. And say it's ok. */
if (ret == ERR_NOTTRACK) ret = NO_PROBLEM;
free(b1);
free(b2);
free(dms_text);
return ret;
}
static USHORT Process_Track(struct zfile *fi, struct zfile *fo, UCHAR *b1, UCHAR *b2, USHORT cmd, USHORT opt, int dmsflags, struct zfile **extra){
USHORT hcrc, dcrc, usum, number, pklen1, pklen2, unpklen, l;
UCHAR cmode, flags;
int crcerr = 0;
l = (USHORT)zfile_fread(b1,1,THLEN,fi);
if (l != THLEN) {
if (l==0)
return DMS_FILE_END;
else
return ERR_SREAD;
}
/* "TR" identifies a Track Header */
if ((b1[0] != 'T')||(b1[1] != 'R')) return ERR_NOTTRACK;
/* Track Header CRC */
hcrc = (USHORT)((b1[THLEN-2] << 8) | b1[THLEN-1]);
if (dms_CreateCRC(b1,(ULONG)(THLEN-2)) != hcrc) return ERR_THCRC;
number = (USHORT)((b1[2] << 8) | b1[3]); /* Number of track */
pklen1 = (USHORT)((b1[6] << 8) | b1[7]); /* Length of packed track data as in archive */
pklen2 = (USHORT)((b1[8] << 8) | b1[9]); /* Length of data after first unpacking */
unpklen = (USHORT)((b1[10] << 8) | b1[11]); /* Length of data after subsequent rle unpacking */
flags = b1[12]; /* control flags */
cmode = b1[13]; /* compression mode used */
usum = (USHORT)((b1[14] << 8) | b1[15]); /* Track Data CheckSum AFTER unpacking */
dcrc = (USHORT)((b1[16] << 8) | b1[17]); /* Track Data CRC BEFORE unpacking */
if (dolog)
write_log ("DMS: track=%d\n", number);
if (dolog) {
if (number==80)
write_log (" FileID ");
else if (number==0xffff)
write_log (" Banner ");
else if ((number==0) && (unpklen==1024))
write_log (" FakeBB ");
else
write_log (" %2d ",(short)number);
write_log ("%5d %5d %s %04X %04X %04X %0d\n", pklen1, unpklen, modes[cmode], usum, hcrc, dcrc, flags);
}
if ((pklen1 > TRACK_BUFFER_LEN) || (pklen2 >TRACK_BUFFER_LEN) || (unpklen > TRACK_BUFFER_LEN)) return ERR_BIGTRACK;
if (zfile_fread(b1,1,(size_t)pklen1,fi) != pklen1) return ERR_SREAD;
if (dms_CreateCRC(b1,(ULONG)pklen1) != dcrc) {
log_error (number);
crcerr = 1;
}
/* track 80 is FILEID.DIZ, track 0xffff (-1) is Banner */
/* and track 0 with 1024 bytes only is a fake boot block with more advertising */
/* FILE_ID.DIZ is never encrypted */
//if (pwd && (number!=80)) dms_decrypt(b1,pklen1);
if ((cmd == CMD_UNPACK) && (number<80) && (unpklen>2048)) {
memset(b2, 0, unpklen);
if (!crcerr)
Unpack_Track(b1, b2, pklen2, unpklen, cmode, flags, number, pklen1, usum, dmsflags & DMSFLAG_ENCRYPTED);
if (number == 0 && zfile_ftell (fo) == 512 * 22) {
// did we have another cylinder 0 already?
uae_u8 *p;
zfile_fseek (fo, 0, SEEK_SET);
p = xcalloc (uae_u8, 512 * 22);
zfile_fread (p, 512 * 22, 1, fo);
addextra("BigFakeBootBlock", extra, p, 512 * 22);
xfree (p);
}
zfile_fseek (fo, number * 512 * 22 * ((dmsflags & DMSFLAG_HD) ? 2 : 1), SEEK_SET);
if (zfile_fwrite(b2,1,(size_t)unpklen,fo) != unpklen)
return ERR_CANTWRITE;
} else if (number == 0 && unpklen == 1024) {
memset(b2, 0, unpklen);
if (!crcerr)
Unpack_Track(b1, b2, pklen2, unpklen, cmode, flags, number, pklen1, usum, dmsflags & DMSFLAG_ENCRYPTED);
addextra("FakeBootBlock", extra, b2, unpklen);
}
if (crcerr)
return NO_PROBLEM;
if (number == 0xffff && extra){
Unpack_Track(b1, b2, pklen2, unpklen, cmode, flags, number, pklen1, usum, dmsflags & DMSFLAG_ENCRYPTED);
addextra("Banner", extra, b2, unpklen);
//printbandiz(b2,unpklen);
}
if (number == 80 && extra) {
Unpack_Track(b1, b2, pklen2, unpklen, cmode, flags, number, pklen1, usum, dmsflags & DMSFLAG_ENCRYPTED);
addextra("FILEID.DIZ", extra, b2, unpklen);
//printbandiz(b2,unpklen);
}
return NO_PROBLEM;
}
static USHORT Unpack_Track_2(UCHAR *b1, UCHAR *b2, USHORT pklen2, USHORT unpklen, UCHAR cmode, UCHAR flags){
switch (cmode){
case 0:
/* No Compression */
memcpy(b2,b1,(size_t)unpklen);
break;
case 1:
/* Simple Compression */
if (Unpack_RLE(b1,b2,unpklen)) return ERR_BADDECR;
break;
case 2:
/* Quick Compression */
if (Unpack_QUICK(b1,b2,pklen2)) return ERR_BADDECR;
if (Unpack_RLE(b2,b1,unpklen)) return ERR_BADDECR;
memcpy(b2,b1,(size_t)unpklen);
break;
case 3:
/* Medium Compression */
if (Unpack_MEDIUM(b1,b2,pklen2)) return ERR_BADDECR;
if (Unpack_RLE(b2,b1,unpklen)) return ERR_BADDECR;
memcpy(b2,b1,(size_t)unpklen);
break;
case 4:
/* Deep Compression */
if (Unpack_DEEP(b1,b2,pklen2)) return ERR_BADDECR;
if (Unpack_RLE(b2,b1,unpklen)) return ERR_BADDECR;
memcpy(b2,b1,(size_t)unpklen);
break;
case 5:
case 6:
/* Heavy Compression */
if (cmode==5) {
/* Heavy 1 */
if (Unpack_HEAVY(b1,b2,flags & 7,pklen2)) return ERR_BADDECR;
} else {
/* Heavy 2 */
if (Unpack_HEAVY(b1,b2,flags | 8,pklen2)) return ERR_BADDECR;
}
if (flags & 4) {
/* Unpack with RLE only if this flag is set */
if (Unpack_RLE(b2,b1,unpklen)) return ERR_BADDECR;
memcpy(b2,b1,(size_t)unpklen);
}
break;
default:
return ERR_UNKNMODE;
}
if (!(flags & 1)) Init_Decrunchers();
return NO_PROBLEM;
}
/* DMS uses a lame encryption */
static void dms_decrypt(UCHAR *p, USHORT len, UCHAR *src){
USHORT t;
while (len--){
t = (USHORT) *src++;
*p++ = t ^ (UCHAR)PWDCRC;
PWDCRC = (USHORT)((PWDCRC >> 1) + t);
}
}
static USHORT Unpack_Track(UCHAR *b1, UCHAR *b2, USHORT pklen2, USHORT unpklen, UCHAR cmode, UCHAR flags, USHORT number, USHORT pklen1, USHORT usum1, int enc)
{
USHORT r, err = NO_PROBLEM;
static USHORT pass;
int maybeencrypted;
int pwrounds;
UCHAR *tmp;
USHORT prevpass = 0;
if (passfound) {
if (number != 80)
dms_decrypt(b1, pklen1, b1);
r = Unpack_Track_2(b1, b2, pklen2, unpklen, cmode, flags);
if (r == NO_PROBLEM) {
if (usum1 == dms_Calc_CheckSum(b2,(ULONG)unpklen))
return NO_PROBLEM;
}
log_error(number);
if (passretries <= 0)
return ERR_CSUM;
}
passretries--;
pwrounds = 0;
maybeencrypted = 0;
tmp = (unsigned char*)malloc (pklen1);
memcpy (tmp, b1, pklen1);
memset(b2, 0, unpklen);
for (;;) {
r = Unpack_Track_2(b1, b2, pklen2, unpklen, cmode, flags);
if (r == NO_PROBLEM) {
if (usum1 == dms_Calc_CheckSum(b2,(ULONG)unpklen)) {
passfound = maybeencrypted;
if (passfound)
write_log ("DMS: decryption key = 0x%04X\n", prevpass);
err = NO_PROBLEM;
pass = prevpass;
break;
}
}
if (number == 80 || !enc) {
err = ERR_CSUM;
break;
}
maybeencrypted = 1;
prevpass = pass;
PWDCRC = pass;
pass++;
dms_decrypt(b1, pklen1, tmp);
pwrounds++;
if (pwrounds == 65536) {
err = ERR_CSUM;
passfound = 0;
break;
}
}
free (tmp);
return err;
}
static void printbandiz(UCHAR *m, USHORT len){
UCHAR *i,*j;
i=j=m;
while (i<m+len) {
if (*i == 10) {
*i=0;
write_log ("%s\n",j);
j=i+1;
}
i++;
}
}
/* Functions return codes */
#define NO_PROBLEM 0
#define DMS_FILE_END 1
#define ERR_NOMEMORY 2
#define ERR_CANTOPENIN 3
#define ERR_CANTOPENOUT 4
#define ERR_NOTDMS 5
#define ERR_SREAD 6
#define ERR_HCRC 7
#define ERR_NOTTRACK 8
#define ERR_BIGTRACK 9
#define ERR_THCRC 10
#define ERR_TDCRC 11
#define ERR_CSUM 12
#define ERR_CANTWRITE 13
#define ERR_BADDECR 14
#define ERR_UNKNMODE 15
#define ERR_NOPASSWD 16
#define ERR_BADPASSWD 17
#define ERR_FMS 18
#define ERR_GZIP 19
#define ERR_READDISK 20
/* Command to execute */
#define CMD_VIEW 1
#define CMD_VIEWFULL 2
#define CMD_SHOWDIZ 3
#define CMD_SHOWBANNER 4
#define CMD_TEST 5
#define CMD_UNPACK 6
#define CMD_UNPKGZ 7
#define CMD_EXTRACT 8
#define OPT_VERBOSE 1
#define OPT_QUIET 2
#define DMS_EXTRA_SIZE 10
USHORT DMS_Process_File(struct zfile *, struct zfile *, USHORT, USHORT, USHORT, USHORT, int, struct zfile **extra);
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* Tables used in Medium and Deep compression modes
*
*/
#include "cdata.h"
#include "tables.h"
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,
};
extern UCHAR d_code[], d_len[];
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* Lempel-Ziv-DynamicHuffman decompression functions used in Deep
* mode.
* Most routines ripped from LZHUF written by Haruyasu Yoshizaki
*
*/
#include <string.h>
#include "cdata.h"
#include "tables.h"
#include "u_deep.h"
#include "getbits.h"
INLINE USHORT DecodeChar(void);
INLINE USHORT DecodePosition(void);
INLINE void update(USHORT c);
static void reconst(void);
USHORT dms_deep_text_loc;
int dms_init_deep_tabs=1;
#define DBITMASK 0x3fff /* uses 16Kb dictionary */
#define F 60 /* lookahead buffer size */
#define THRESHOLD 2
#define N_CHAR (256 - THRESHOLD + F) /* kinds of characters (character code = 0..N_CHAR-1) */
#define T (N_CHAR * 2 - 1) /* size of table */
#define R (T - 1) /* position of root */
#define MAX_FREQ 0x8000 /* updates tree when the */
static USHORT freq[T + 1]; /* frequency table */
static USHORT prnt[T + N_CHAR]; /* pointers to parent nodes, except for the */
/* elements [T..T + N_CHAR - 1] which are used to get */
/* the positions of leaves corresponding to the codes. */
static USHORT son[T]; /* pointers to child nodes (son[], son[] + 1) */
void Init_DEEP_Tabs(void){
USHORT i, j;
for (i = 0; i < N_CHAR; i++) {
freq[i] = 1;
son[i] = (USHORT)(i + T);
prnt[i + T] = i;
}
i = 0; j = N_CHAR;
while (j <= R) {
freq[j] = (USHORT) (freq[i] + freq[i + 1]);
son[j] = i;
prnt[i] = prnt[i + 1] = j;
i += 2; j++;
}
freq[T] = 0xffff;
prnt[R] = 0;
dms_init_deep_tabs = 0;
}
USHORT Unpack_DEEP(UCHAR *in, UCHAR *out, USHORT origsize){
USHORT i, j, c;
UCHAR *outend;
initbitbuf(in);
if (dms_init_deep_tabs) Init_DEEP_Tabs();
outend = out+origsize;
while (out < outend) {
c = DecodeChar();
if (c < 256) {
*out++ = dms_text[dms_deep_text_loc++ & DBITMASK] = (UCHAR)c;
} else {
j = (USHORT) (c - 255 + THRESHOLD);
i = (USHORT) (dms_deep_text_loc - DecodePosition() - 1);
while (j--) *out++ = dms_text[dms_deep_text_loc++ & DBITMASK] = dms_text[i++ & DBITMASK];
}
}
dms_deep_text_loc = (USHORT)((dms_deep_text_loc+60) & DBITMASK);
return 0;
}
INLINE USHORT DecodeChar(void){
USHORT c;
c = son[R];
/* travel from root to leaf, */
/* choosing the smaller child node (son[]) if the read bit is 0, */
/* the bigger (son[]+1} if 1 */
while (c < T) {
c = son[c + GETBITS(1)];
DROPBITS(1);
}
c -= T;
update(c);
return c;
}
INLINE USHORT DecodePosition(void){
USHORT i, j, c;
i = GETBITS(8); DROPBITS(8);
c = (USHORT) (d_code[i] << 8);
j = d_len[i];
i = (USHORT) (((i << j) | GETBITS(j)) & 0xff); DROPBITS(j);
return (USHORT) (c | i) ;
}
/* reconstruction of tree */
static void reconst(void){
USHORT i, j, k, f, l;
/* collect leaf nodes in the first half of the table */
/* and replace the freq by (freq + 1) / 2. */
j = 0;
for (i = 0; i < T; i++) {
if (son[i] >= T) {
freq[j] = (USHORT) ((freq[i] + 1) / 2);
son[j] = son[i];
j++;
}
}
/* begin constructing tree by connecting sons */
for (i = 0, j = N_CHAR; j < T; i += 2, j++) {
k = (USHORT) (i + 1);
f = freq[j] = (USHORT) (freq[i] + freq[k]);
for (k = (USHORT)(j - 1); f < freq[k]; k--);
k++;
l = (USHORT)((j - k) * 2);
memmove(&freq[k + 1], &freq[k], (size_t)l);
freq[k] = f;
memmove(&son[k + 1], &son[k], (size_t)l);
son[k] = i;
}
/* connect prnt */
for (i = 0; i < T; i++) {
if ((k = son[i]) >= T) {
prnt[k] = i;
} else {
prnt[k] = prnt[k + 1] = i;
}
}
}
/* increment frequency of given code by one, and update tree */
INLINE void update(USHORT c){
USHORT i, j, k, l;
if (freq[R] == MAX_FREQ) {
reconst();
}
c = prnt[c + T];
do {
k = ++freq[c];
/* if the order is disturbed, exchange nodes */
if (k > freq[l = (USHORT)(c + 1)]) {
while (k > freq[++l]);
l--;
freq[c] = freq[l];
freq[l] = 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); /* repeat up to root */
}
USHORT Unpack_DEEP(UCHAR *, UCHAR *, USHORT);
extern int dms_init_deep_tabs;
extern USHORT dms_deep_text_loc;
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* Lempel-Ziv-Huffman decompression functions used in Heavy 1 & 2
* compression modes. Based on LZH decompression functions from
* UNIX LHA made by Masaru Oki
*
*/
#include "cdata.h"
#include "u_heavy.h"
#include "getbits.h"
#include "maketbl.h"
#define NC 510
#define NPT 20
#define N1 510
#define OFFSET 253
USHORT dms_left[2 * NC - 1], dms_right[2 * NC - 1 + 9];
static UCHAR c_len[NC], pt_len[NPT];
static USHORT c_table[4096], pt_table[256];
USHORT dms_lastlen, dms_np;
USHORT dms_heavy_text_loc;
static USHORT read_tree_c(void);
static USHORT read_tree_p(void);
INLINE USHORT decode_c(void);
INLINE USHORT decode_p(void);
USHORT Unpack_HEAVY(UCHAR *in, UCHAR *out, UCHAR flags, USHORT origsize){
USHORT j, i, c, bitmask;
UCHAR *outend;
/* Heavy 1 uses a 4Kb dictionary, Heavy 2 uses 8Kb */
if (flags & 8) {
dms_np = 15;
bitmask = 0x1fff;
} else {
dms_np = 14;
bitmask = 0x0fff;
}
initbitbuf(in);
if (flags & 2) {
if (read_tree_c()) return 1;
if (read_tree_p()) return 2;
}
outend = out+origsize;
while (out<outend) {
c = decode_c();
if (c < 256) {
*out++ = dms_text[dms_heavy_text_loc++ & bitmask] = (UCHAR)c;
} else {
j = (USHORT) (c - OFFSET);
i = (USHORT) (dms_heavy_text_loc - decode_p() - 1);
while(j--) *out++ = dms_text[dms_heavy_text_loc++ & bitmask] = dms_text[i++ & bitmask];
}
}
return 0;
}
INLINE USHORT decode_c(void){
USHORT i, j, m;
j = c_table[GETBITS(12)];
if (j < N1) {
DROPBITS(c_len[j]);
} else {
DROPBITS(12);
i = GETBITS(16);
m = 0x8000;
do {
if (i & m) j = dms_right[j];
else j = dms_left [j];
m >>= 1;
} while (j >= N1);
DROPBITS(c_len[j] - 12);
}
return j;
}
INLINE USHORT decode_p(void){
USHORT i, j, m;
j = pt_table[GETBITS(8)];
if (j < dms_np) {
DROPBITS(pt_len[j]);
} else {
DROPBITS(8);
i = GETBITS(16);
m = 0x8000;
do {
if (i & m) j = dms_right[j];
else j = dms_left [j];
m >>= 1;
} while (j >= dms_np);
DROPBITS(pt_len[j] - 8);
}
if (j != dms_np-1) {
if (j > 0) {
j = (USHORT)(GETBITS(i=(USHORT)(j-1)) | (1U << (j-1)));
DROPBITS(i);
}
dms_lastlen=j;
}
return dms_lastlen;
}
static USHORT read_tree_c(void){
USHORT i,n;
n = GETBITS(9);
DROPBITS(9);
if (n>0){
for (i=0; i<n; i++) {
c_len[i] = (UCHAR)GETBITS(5);
DROPBITS(5);
}
for (i=n; i<510; i++) c_len[i] = 0;
if (dms_make_table(510,c_len,12,c_table)) return 1;
} else {
n = GETBITS(9);
DROPBITS(9);
for (i=0; i<510; i++) c_len[i] = 0;
for (i=0; i<4096; i++) c_table[i] = n;
}
return 0;
}
static USHORT read_tree_p(void){
USHORT i,n;
n = GETBITS(5);
DROPBITS(5);
if (n>0){
for (i=0; i<n; i++) {
pt_len[i] = (UCHAR)GETBITS(4);
DROPBITS(4);
}
for (i=n; i<dms_np; i++) pt_len[i] = 0;
if (dms_make_table(dms_np,pt_len,8,pt_table)) return 1;
} else {
n = GETBITS(5);
DROPBITS(5);
for (i=0; i<dms_np; i++) pt_len[i] = 0;
for (i=0; i<256; i++) pt_table[i] = n;
}
return 0;
}
USHORT Unpack_HEAVY(UCHAR *, UCHAR *, UCHAR, USHORT);
extern USHORT dms_heavy_text_loc;
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* Decruncher reinitialization
*
*/
#include <string.h>
#include "cdata.h"
#include "u_init.h"
#include "u_quick.h"
#include "u_medium.h"
#include "u_deep.h"
#include "u_heavy.h"
void Init_Decrunchers(void){
dms_quick_text_loc = 251;
dms_medium_text_loc = 0x3fbe;
dms_heavy_text_loc = 0;
dms_deep_text_loc = 0x3fc4;
dms_init_deep_tabs = 1;
memset(dms_text,0,0x3fc8);
dms_lastlen = 0;
dms_np = 0;
}
void Init_Decrunchers(void);
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* Main decompression functions used in MEDIUM mode
*
*/
#include <string.h>
#include "cdata.h"
#include "u_medium.h"
#include "getbits.h"
#include "tables.h"
#define MBITMASK 0x3fff
USHORT dms_medium_text_loc;
USHORT Unpack_MEDIUM(UCHAR *in, UCHAR *out, USHORT origsize){
USHORT i, j, c;
UCHAR u, *outend;
initbitbuf(in);
outend = out+origsize;
while (out < outend) {
if (GETBITS(1)!=0) {
DROPBITS(1);
*out++ = dms_text[dms_medium_text_loc++ & MBITMASK] = (UCHAR)GETBITS(8);
DROPBITS(8);
} else {
DROPBITS(1);
c = GETBITS(8); DROPBITS(8);
j = (USHORT) (d_code[c]+3);
u = d_len[c];
c = (USHORT) (((c << u) | GETBITS(u)) & 0xff); DROPBITS(u);
u = d_len[c];
c = (USHORT) ((d_code[c] << 8) | (((c << u) | GETBITS(u)) & 0xff)); DROPBITS(u);
i = (USHORT) (dms_medium_text_loc - c - 1);
while(j--) *out++ = dms_text[dms_medium_text_loc++ & MBITMASK] = dms_text[i++ & MBITMASK];
}
}
dms_medium_text_loc = (USHORT)((dms_medium_text_loc+66) & MBITMASK);
return 0;
}
USHORT Unpack_MEDIUM(UCHAR *, UCHAR *, USHORT);
extern USHORT dms_medium_text_loc;
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
*
*/
#include <string.h>
#include "cdata.h"
#include "u_quick.h"
#include "getbits.h"
#define QBITMASK 0xff
USHORT dms_quick_text_loc;
USHORT Unpack_QUICK(UCHAR *in, UCHAR *out, USHORT origsize){
USHORT i, j;
UCHAR *outend;
initbitbuf(in);
outend = out+origsize;
while (out < outend) {
if (GETBITS(1)!=0) {
DROPBITS(1);
*out++ = dms_text[dms_quick_text_loc++ & QBITMASK] = (UCHAR)GETBITS(8); DROPBITS(8);
} else {
DROPBITS(1);
j = (USHORT) (GETBITS(2)+2); DROPBITS(2);
i = (USHORT) (dms_quick_text_loc - GETBITS(8) - 1); DROPBITS(8);
while(j--) {
*out++ = dms_text[dms_quick_text_loc++ & QBITMASK] = dms_text[i++ & QBITMASK];
}
}
}
dms_quick_text_loc = (USHORT)((dms_quick_text_loc+5) & QBITMASK);
return 0;
}
USHORT Unpack_QUICK(UCHAR *, UCHAR *, USHORT);
extern USHORT dms_quick_text_loc;
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* Run Length Encoding decompression function used in most
* modes after decompression by other algorithm
*
*/
#include <string.h>
#include "cdata.h"
#include "u_rle.h"
USHORT Unpack_RLE(UCHAR *in, UCHAR *out, USHORT origsize){
USHORT n;
UCHAR a,b, *outend;
outend = out+origsize;
while (out<outend){
if ((a = *in++) != 0x90)
*out++ = a;
else if (!(b = *in++))
*out++ = a;
else {
a = *in++;
if (b == 0xff) {
n = *in++;
n = (USHORT)((n<<8) + *in++);
} else
n = b;
if (out+n > outend) return 1;
memset(out,a,(size_t) n);
out += n;
}
}
return 0;
}
USHORT Unpack_RLE(UCHAR *, UCHAR *, USHORT);
AM_CPPFLAGS = @UAE_CPPFLAGS@
AM_CPPFLAGS += -I$(top_srcdir)/src/include -I$(top_builddir)/src -I$(top_srcdir)/src
AM_CFLAGS = @UAE_CFLAGS@
noinst_LIBRARIES = liblha.a
liblha_a_SOURCES = crcio.c dhuf.c header.c huf.c larc.c \
lhamaketbl.c lharc.c shuf.c slide.c uae_lha.c \
util.c
noinst_HEADERS = lha.h lha_macro.h
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = src/archivers/lha
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \
$(top_srcdir)/m4/as-objc.m4 \
$(top_srcdir)/m4/ax_check_compiler_flags.m4 \
$(top_srcdir)/m4/ax_gcc_archflag.m4 \
$(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \
$(top_srcdir)/m4/framework.m4 $(top_srcdir)/m4/fsusage.m4 \
$(top_srcdir)/m4/gtk-2.0.m4 $(top_srcdir)/m4/gtk.m4 \
$(top_srcdir)/m4/sdl.m4 $(top_srcdir)/m4/type_socklen_t.m4 \
$(top_srcdir)/m4/uintmax_t.m4 $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/sysconfig.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LIBRARIES = $(noinst_LIBRARIES)
ARFLAGS = cru
liblha_a_AR = $(AR) $(ARFLAGS)
liblha_a_LIBADD =
am_liblha_a_OBJECTS = crcio.$(OBJEXT) dhuf.$(OBJEXT) header.$(OBJEXT) \
huf.$(OBJEXT) larc.$(OBJEXT) lhamaketbl.$(OBJEXT) \
lharc.$(OBJEXT) shuf.$(OBJEXT) slide.$(OBJEXT) \
uae_lha.$(OBJEXT) util.$(OBJEXT)
liblha_a_OBJECTS = $(am_liblha_a_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(liblha_a_SOURCES)
DIST_SOURCES = $(liblha_a_SOURCES)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
ASMOBJS = @ASMOBJS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BSDSOCKOBJS = @BSDSOCKOBJS@
CC = @CC@
CCAS = @CCAS@
CCASDEPMODE = @CCASDEPMODE@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CDOBJS = @CDOBJS@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPUOBJS = @CPUOBJS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEBUGOBJS = @DEBUGOBJS@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
EXTRAOBJS = @EXTRAOBJS@
FILEPRG = @FILEPRG@
FILESYSOBJS = @FILESYSOBJS@
GENCPUOPTS = @GENCPUOPTS@
GFX_DEP = @GFX_DEP@
GREP = @GREP@
GTK_CFLAGS = @GTK_CFLAGS@
GTK_CONFIG = @GTK_CONFIG@
GTK_LIBS = @GTK_LIBS@
GUI_DEP = @GUI_DEP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JITOBJS = @JITOBJS@
JOY_DEP = @JOY_DEP@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MACHDEP = @MACHDEP@
MAKEDEPPRG = @MAKEDEPPRG@
MAKEINFO = @MAKEINFO@
MATHLIB = @MATHLIB@
MKDIR_P = @MKDIR_P@
NO_SCHED_CFLAGS = @NO_SCHED_CFLAGS@
OBJC = @OBJC@
OBJCDEPMODE = @OBJCDEPMODE@
OBJC_LDFLAGS = @OBJC_LDFLAGS@
OBJEXT = @OBJEXT@
OSDEP = @OSDEP@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PRTDIAG = @PRTDIAG@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
RCLPRG = @RCLPRG@
RESOBJS = @RESOBJS@
SCSIOBJS = @SCSIOBJS@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SND_DEP = @SND_DEP@
STRIP = @STRIP@
TARGET = @TARGET@
THREADDEP = @THREADDEP@
UAE_CFLAGS = @UAE_CFLAGS@
UAE_CPPFLAGS = @UAE_CPPFLAGS@
UAE_LIBS = @UAE_LIBS@
UAE_RSRCFILE = @UAE_RSRCFILE@
VERSION = @VERSION@
WRCPRG = @WRCPRG@
XMKMF = @XMKMF@
X_CFLAGS = @X_CFLAGS@
X_EXTRA_LIBS = @X_EXTRA_LIBS@
X_LIBS = @X_LIBS@
X_PRE_LIBS = @X_PRE_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_OBJC = @ac_ct_OBJC@
ac_cv_c_inline = @ac_cv_c_inline@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CPPFLAGS = @UAE_CPPFLAGS@ -I$(top_srcdir)/src/include \
-I$(top_builddir)/src -I$(top_srcdir)/src
AM_CFLAGS = @UAE_CFLAGS@
noinst_LIBRARIES = liblha.a
liblha_a_SOURCES = crcio.c dhuf.c header.c huf.c larc.c \
lhamaketbl.c lharc.c shuf.c slide.c uae_lha.c \
util.c
noinst_HEADERS = lha.h lha_macro.h
all: all-am
.SUFFIXES:
.SUFFIXES: .c .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/archivers/lha/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/archivers/lha/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
liblha.a: $(liblha_a_OBJECTS) $(liblha_a_DEPENDENCIES)
-rm -f liblha.a
$(liblha_a_AR) liblha.a $(liblha_a_OBJECTS) $(liblha_a_LIBADD)
$(RANLIB) liblha.a
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crcio.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dhuf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/header.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/huf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/larc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lhamaketbl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lharc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shuf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slide.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uae_lha.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LIBRARIES) $(HEADERS)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-noinstLIBRARIES ctags distclean distclean-compile \
distclean-generic distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
/* ------------------------------------------------------------------------ */
/* LHa for UNIX */
/* crcio.c -- crc input / output */
/* */
/* Modified Nobutaka Watazaki */
/* */
/* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
/* ------------------------------------------------------------------------ */
#include "lha.h"
/* ------------------------------------------------------------------------ */
static unsigned short crctable[UCHAR_MAX + 1];
static unsigned char subbitbuf, bitcount;
#ifdef EUC
static int putc_euc_cache;
#endif
static int getc_euc_cache;
/* ------------------------------------------------------------------------ */
void
make_crctable( /* void */ )
{
unsigned int i, j, r;
for (i = 0; i <= UCHAR_MAX; i++) {
r = i;
for (j = 0; j < CHAR_BIT; j++)
if (r & 1)
r = (r >> 1) ^ CRCPOLY;
else
r >>= 1;
crctable[i] = r;
}
}
/* ------------------------------------------------------------------------ */
#ifdef NEED_INCREMENTAL_INDICATOR
static void
put_indicator(count)
long int count;
{
if (!quiet && indicator_threshold) {
while (count > indicator_count) {
putchar('o');
fflush(stdout);
indicator_count += indicator_threshold;
}
}
}
#endif
/* ------------------------------------------------------------------------ */
unsigned short
calccrc(unsigned char *p, unsigned int n)
{
reading_size += n;
#ifdef NEED_INCREMENTAL_INDICATOR
put_indicator(reading_size);
#endif
while (n-- > 0)
UPDATE_CRC(*p++);
return crc;
}
/* ------------------------------------------------------------------------ */
void
fillbuf(unsigned char n) /* Shift bitbuf n bits left, read n bits */
{
while (n > bitcount) {
n -= bitcount;
lhabitbuf = (lhabitbuf << bitcount) + (subbitbuf >> (CHAR_BIT - bitcount));
if (compsize != 0) {
compsize--;
subbitbuf = (unsigned char) zfile_getc(infile);
}
else
subbitbuf = 0;
bitcount = CHAR_BIT;
}
bitcount -= n;
lhabitbuf = (lhabitbuf << n) + (subbitbuf >> (CHAR_BIT - n));
subbitbuf <<= n;
}
/* ------------------------------------------------------------------------ */
unsigned short
getbits(unsigned char n)
{
unsigned short x;
x = lhabitbuf >> (2 * CHAR_BIT - n);
fillbuf(n);
return x;
}
#if 0
/* ------------------------------------------------------------------------ */
void
putcode(n, x) /* Write rightmost n bits of x */
unsigned char n;
unsigned short x;
{
while (n >= bitcount) {
n -= bitcount;
subbitbuf += x >> (USHRT_BIT - bitcount);
x <<= bitcount;
if (compsize < origsize) {
if (fwrite(&subbitbuf, 1, 1, outfile) == 0) {
/* fileerror(WTERR, outfile); */
fatal_error("Write error in crcio.c(putcode)\n");
/* exit(errno); */
}
compsize++;
}
else
unpackable = 1;
subbitbuf = 0;
bitcount = CHAR_BIT;
}
subbitbuf += x >> (USHRT_BIT - bitcount);
bitcount -= n;
}
/* ------------------------------------------------------------------------ */
void
putbits(n, x) /* Write rightmost n bits of x */
unsigned char n;
unsigned short x;
{
x <<= USHRT_BIT - n;
while (n >= bitcount) {
n -= bitcount;
subbitbuf += x >> (USHRT_BIT - bitcount);
x <<= bitcount;
if (compsize < origsize) {
if (fwrite(&subbitbuf, 1, 1, outfile) == 0) {
/* fileerror(WTERR, outfile); */
fatal_error("Write error in crcio.c(putbits)\n");
/* exit(errno); */
}
compsize++;
}
else
unpackable = 1;
subbitbuf = 0;
bitcount = CHAR_BIT;
}
subbitbuf += x >> (USHRT_BIT - bitcount);
bitcount -= n;
}
#endif
/* ------------------------------------------------------------------------ */
int
fread_crc(unsigned char *p, int n, struct zfile *fp)
{
n = zfile_fread(p, 1, n, fp);
calccrc(p, n);
return n;
}
/* ------------------------------------------------------------------------ */
void
fwrite_crc(unsigned char *p, int n, struct zfile *fp)
{
calccrc(p, n);
if (verify_mode)
return;
if (fp) {
zfile_fwrite(p, 1, n, fp);
}
}
/* ------------------------------------------------------------------------ */
void
init_code_cache(void)
{ /* called from copyfile() in util.c */
#ifdef EUC
putc_euc_cache = EOF;
#endif
getc_euc_cache = EOF;
}
void
init_getbits(void)
{
lhabitbuf = 0;
subbitbuf = 0;
bitcount = 0;
fillbuf(2 * CHAR_BIT);
#ifdef EUC
putc_euc_cache = EOF;
#endif
}
/* ------------------------------------------------------------------------ */
void
init_putbits( /* void */ )
{
bitcount = CHAR_BIT;
subbitbuf = 0;
getc_euc_cache = EOF;
}
/* ------------------------------------------------------------------------ */
#ifdef EUC
void
putc_euc(c, fd)
int c;
FILE *fd;
{
int d;
if (putc_euc_cache == EOF) {
if (!euc_mode || c < 0x81 || c > 0xFC) {
putc(c, fd);
return;
}
if (c >= 0xA0 && c < 0xE0) {
putc(0x8E, fd); /* single shift */
putc(c, fd);
return;
}
putc_euc_cache = c; /* save first byte */
return;
}
d = putc_euc_cache;
putc_euc_cache = EOF;
if (d >= 0xA0)
d -= 0xE0 - 0xA0;
if (c > 0x9E) {
c = c - 0x9F + 0x21;
d = (d - 0x81) * 2 + 0x22;
}
else {
if (c > 0x7E)
c--;
c -= 0x1F;
d = (d - 0x81) * 2 + 0x21;
}
putc(0x80 | d, fd);
putc(0x80 | c, fd);
}
#endif
/* ------------------------------------------------------------------------ */
int
fwrite_txt(unsigned char *p, int n, FILE *fp)
{
while (--n >= 0) {
if (*p != '\015' && *p != '\032') {
#ifdef EUC
putc_euc(*p, fp);
#else
putc(*p, fp);
#endif
}
prev_char = *p++;
}
return (ferror(fp));
}
/* ------------------------------------------------------------------------ */
int
fread_txt(unsigned char *p, int n, FILE *fp)
{
int c;
int cnt = 0;
while (cnt < n) {
if (getc_euc_cache != EOF) {
c = getc_euc_cache;
getc_euc_cache = EOF;
}
else {
if ((c = fgetc(fp)) == EOF)
break;
if (c == '\n') {
getc_euc_cache = c;
++origsize;
c = '\r';
}
#ifdef EUC
else if (euc_mode && (c == 0x8E || 0xA0 < c && c < 0xFF)) {
int d = fgetc(fp);
if (d == EOF) {
*p++ = c;
cnt++;
break;
}
if (c == 0x8E) { /* single shift (KANA) */
if ((0x20 < d && d < 0x7F) || (0xA0 < d && d < 0xFF))
c = d | 0x80;
else
getc_euc_cache = d;
}
else {
if (0xA0 < d && d < 0xFF) { /* if GR */
c &= 0x7F; /* convert to MS-kanji */
d &= 0x7F;
if (!(c & 1)) {
c--;
d += 0x7F - 0x21;
}
if ((d += 0x40 - 0x21) > 0x7E)
d++;
if ((c = (c >> 1) + 0x71) >= 0xA0)
c += 0xE0 - 0xA0;
}
getc_euc_cache = d;
}
}
#endif
}
*p++ = c;
cnt++;
}
return cnt;
}
/* ------------------------------------------------------------------------ */
unsigned short
calc_header_crc(unsigned char *p, unsigned int n) /* Thanks T.Okamoto */
{
crc = 0;
while (n-- > 0)
UPDATE_CRC(*p++);
return crc;
}
/* ------------------------------------------------------------------------ */
/* LHa for UNIX */
/* dhuf.c -- Dynamic Hufffman routine */
/* */
/* Modified H.Yoshizaki */
/* */
/* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
/* ------------------------------------------------------------------------ */
#include "lha.h"
/* ------------------------------------------------------------------------ */
static short child[TREESIZE], parent[TREESIZE], block[TREESIZE], edge[TREESIZE], stock[TREESIZE],
s_node[TREESIZE / 2]; /* Changed N.Watazaki */
/* node[..] -> s_node[..] */
static unsigned short freq[TREESIZE];
static unsigned short total_p;
static int avail, n1;
static int most_p, nn;
static unsigned long nextcount;
/* ------------------------------------------------------------------------ */
void
start_c_dyn(void)
{
int i, j, f;
n1 = (n_max >= 256 + maxmatch - THRESHOLD + 1) ? 512 : n_max - 1;
for (i = 0; i < TREESIZE_C; i++) {
stock[i] = i;
block[i] = 0;
}
for (i = 0, j = n_max * 2 - 2; i < n_max; i++, j--) {
freq[j] = 1;
child[j] = ~i;
s_node[i] = j;
block[j] = 1;
}
avail = 2;
edge[1] = n_max - 1;
i = n_max * 2 - 2;
while (j >= 0) {
f = freq[j] = freq[i] + freq[i - 1];
child[j] = i;
parent[i] = parent[i - 1] = j;
if (f == freq[j + 1]) {
edge[block[j] = block[j + 1]] = j;
}
else {
edge[block[j] = stock[avail++]] = j;
}
i -= 2;
j--;
}
}
/* ------------------------------------------------------------------------ */
static void
start_p_dyn(void)
{
freq[ROOT_P] = 1;
child[ROOT_P] = ~(N_CHAR);
s_node[N_CHAR] = ROOT_P;
edge[block[ROOT_P] = stock[avail++]] = ROOT_P;
most_p = ROOT_P;
total_p = 0;
nn = 1 << dicbit;
nextcount = 64;
}
/* ------------------------------------------------------------------------ */
void
decode_start_dyn(void)
{
n_max = 286;
maxmatch = MAXMATCH;
init_getbits();
start_c_dyn();
start_p_dyn();
}
/* ------------------------------------------------------------------------ */
static void
reconst(int start, int end)
{
int i, j, k, l, b;
unsigned int f, g;
for (i = j = start; i < end; i++) {
if ((k = child[i]) < 0) {
freq[j] = (freq[i] + 1) / 2;
child[j] = k;
j++;
}
if (edge[b = block[i]] == i) {
stock[--avail] = b;
}
}
j--;
i = end - 1;
l = end - 2;
while (i >= start) {
while (i >= l) {
freq[i] = freq[j];
child[i] = child[j];
i--, j--;
}
f = freq[l] + freq[l + 1];
for (k = start; f < freq[k]; k++);
while (j >= k) {
freq[i] = freq[j];
child[i] = child[j];
i--, j--;
}
freq[i] = f;
child[i] = l + 1;
i--;
l -= 2;
}
f = 0;
for (i = start; i < end; i++) {
if ((j = child[i]) < 0)
s_node[~j] = i;
else
parent[j] = parent[j - 1] = i;
if ((g = freq[i]) == f) {
block[i] = b;
}
else {
edge[b = block[i] = stock[avail++]] = i;
f = g;
}
}
}
/* ------------------------------------------------------------------------ */
static int
swap_inc(int p)
{
int b, q, r, s;
b = block[p];
if ((q = edge[b]) != p) { /* swap for leader */
r = child[p];
s = child[q];
child[p] = s;
child[q] = r;
if (r >= 0)
parent[r] = parent[r - 1] = q;
else
s_node[~r] = q;
if (s >= 0)
parent[s] = parent[s - 1] = p;
else
s_node[~s] = p;
p = q;
goto Adjust;
}
else if (b == block[p + 1]) {
Adjust:
edge[b]++;
if (++freq[p] == freq[p - 1]) {
block[p] = block[p - 1];
}
else {
edge[block[p] = stock[avail++]] = p; /* create block */
}
}
else if (++freq[p] == freq[p - 1]) {
stock[--avail] = b; /* delete block */
block[p] = block[p - 1];
}
return parent[p];
}
/* ------------------------------------------------------------------------ */
static void
update_c(int p)
{
int q;
if (freq[ROOT_C] == 0x8000) {
reconst(0, n_max * 2 - 1);
}
freq[ROOT_C]++;
q = s_node[p];
do {
q = swap_inc(q);
} while (q != ROOT_C);
}
/* ------------------------------------------------------------------------ */
static void
update_p(int p)
{
int q;
if (total_p == 0x8000) {
reconst(ROOT_P, most_p + 1);
total_p = freq[ROOT_P];
freq[ROOT_P] = 0xffff;
}
q = s_node[p + N_CHAR];
while (q != ROOT_P) {
q = swap_inc(q);
}
total_p++;
}
/* ------------------------------------------------------------------------ */
static void
make_new_node(int p)
{
int q, r;
r = most_p + 1;
q = r + 1;
s_node[~(child[r] = child[most_p])] = r;
child[q] = ~(p + N_CHAR);
child[most_p] = q;
freq[r] = freq[most_p];
freq[q] = 0;
block[r] = block[most_p];
if (most_p == ROOT_P) {
freq[ROOT_P] = 0xffff;
edge[block[ROOT_P]]++;
}
parent[r] = parent[q] = most_p;
edge[block[q] = stock[avail++]] = s_node[p + N_CHAR] = most_p = q;
update_p(p);
}
#if 0
/* ------------------------------------------------------------------------ */
static void
encode_c_dyn(c)
unsigned int c;
{
unsigned int bits;
int p, d, cnt;
d = c - n1;
if (d >= 0) {
c = n1;
}
cnt = bits = 0;
p = s_node[c];
do {
bits >>= 1;
if (p & 1) {
bits |= 0x8000;
}
if (++cnt == 16) {
putcode(16, bits);
cnt = bits = 0;
}
} while ((p = parent[p]) != ROOT_C);
putcode(cnt, bits);
if (d >= 0)
putbits(8, d);
update_c(c);
}
#endif
/* ------------------------------------------------------------------------ */
unsigned short
decode_c_dyn(void)
{
int c;
short buf, cnt;
c = child[ROOT_C];
buf = lhabitbuf;
cnt = 0;
do {
c = child[c - (buf < 0)];
buf <<= 1;
if (++cnt == 16) {
fillbuf(16);
buf = lhabitbuf;
cnt = 0;
}
} while (c > 0);
fillbuf(cnt);
c = ~c;
update_c(c);
if (c == n1)
c += getbits(8);
return c;
}
/* ------------------------------------------------------------------------ */
unsigned short
decode_p_dyn(void)
{
int c;
short buf, cnt;
while (count > nextcount) {
make_new_node(nextcount / 64);
if ((nextcount += 64) >= nn)
nextcount = 0xffffffff;
}
c = child[ROOT_P];
buf = lhabitbuf;
cnt = 0;
while (c > 0) {
c = child[c - (buf < 0)];
buf <<= 1;
if (++cnt == 16) {
fillbuf(16);
buf = lhabitbuf;
cnt = 0;
}
}
fillbuf(cnt);
c = (~c) - N_CHAR;
update_p(c);
return (c << 6) + getbits(6);
}
#if 0
/* ------------------------------------------------------------------------ */
void
output_dyn(code, pos)
unsigned int code;
unsigned int pos;
{
encode_c_dyn(code);
if (code >= 0x100) {
encode_p_st0(pos);
}
}
/* ------------------------------------------------------------------------ */
void
encode_end_dyn( /* void */ )
{
putcode(7, 0);
}
#endif
/* Local Variables: */
/* mode:c */
/* tab-width:4 */
/* End: */
/* ------------------------------------------------------------------------ */
/* LHa for UNIX */
/* header.c -- header manipulate functions */
/* */
/* Modified Nobutaka Watazaki */
/* */
/* Original Y.Tagawa */
/* modified 1991.12.16 M.Oki */
/* Ver. 1.10 Symbolic Link added 1993.10.01 N.Watazaki */
/* Ver. 1.13b Symbolic Link Bug Fix 1994.08.22 N.Watazaki */
/* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
/* Ver. 1.14i bug fixed 2000.10.06 t.okamoto */
/* ------------------------------------------------------------------------ */
#define FALSE 0
#define TRUE 1
#include "lha.h"
/* ------------------------------------------------------------------------ */
static char *get_ptr;
/* ------------------------------------------------------------------------ */
int calc_sum(char *p, int len)
{
register int sum;
for (sum = 0; len; len--)
sum += *p++;
return sum & 0xff;
}
/* ------------------------------------------------------------------------ */
static unsigned short get_word (void)
{
int b0, b1;
b0 = get_byte ();
b1 = get_byte ();
return (b1 << 8) + b0;
}
/* ------------------------------------------------------------------------ */
static void put_word (unsigned int v)
{
put_byte (v);
put_byte (v >> 8);
}
/* ------------------------------------------------------------------------ */
static long get_longword(void)
{
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;
}
/* ------------------------------------------------------------------------ */
static void put_longword(long v)
{
put_byte (v);
put_byte (v >> 8);
put_byte (v >> 16);
put_byte (v >> 24);
}
/* ------------------------------------------------------------------------ */
static void msdos_to_unix_filename(char *name, 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++;
else if (name[i] == '\\')
name[i] = '/';
else if (!noconvertcase && isupper(name[i]))
name[i] = tolower(name[i]);
}
#else
for (i = 0; i < len; i++) {
if (name[i] == '\\')
name[i] = '/';
else if (!noconvertcase && isupper(name[i]))
name[i] = tolower(name[i]);
}
#endif
}
/* ------------------------------------------------------------------------ */
static void generic_to_unix_filename(char *name, int len)
{
register int i;
bool 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++;
else if (name[i] == '\\')
name[i] = '/';
else if (!noconvertcase && !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++) {
if (name[i] == '\\')
name[i] = '/';
else if (!noconvertcase && !lower_case_used && isupper(name[i]))
name[i] = tolower(name[i]);
}
#endif
}
/* ------------------------------------------------------------------------ */
static void
macos_to_unix_filename(char *name, int len)
{
register int i;
for (i = 0; i < len; i++) {
if (name[i] == ':')
name[i] = '/';
else if (name[i] == '/')
name[i] = ':';
}
}
/* ------------------------------------------------------------------------ */
static void
unix_to_generic_filename(char *name, int len)
{
register int i;
for (i = 0; i < len; i++) {
if (name[i] == '/')
name[i] = '\\';
else if (islower(name[i]))
name[i] = toupper(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 ->| */
/* */
/* ------------------------------------------------------------------------ */
/*
* NOTE : If you don't have `gettimeofday(2)', or your gettimeofday(2)
* returns bogus timezone information, try FTIME, MKTIME, TIMELOCAL or TZSET.
*/
/* choose one */
#if defined(MKTIME)
#ifdef TIMELOCAL
#undef TIMELOCAL
#endif
#endif /* defined(MKTIME) */
#if defined(MKTIME) || defined(TIMELOCAL)
#ifdef TZSET
#undef TZSET
#endif
#endif /* defined(MKTIME) || defined(TIMELOCAL) */
#if defined(MKTIME) || defined(TIMELOCAL) || defined(TZSET)
#ifdef FTIME
#undef FTIME
#endif
#endif
#if defined(MKTIME) || defined(TIMELOCAL) || defined(TZSET) || defined(FTIME)
#ifdef GETTIMEOFDAY
#undef GETTIMEOFDAY
#endif
#else
#ifndef GETTIMEOFDAY
#define GETTIMEOFDAY /* use gettimeofday() */
#endif
#endif
#ifdef FTIME
#include <sys/timeb.h>
#endif
/*
* You may define as : #define TIMEZONE_HOOK \ extern long
* timezone ; \ extern void tzset();
*/
#ifdef TIMEZONE_HOOK
TIMEZONE_HOOK
/* Which do you like better, `TIMEZONE_HOOK' or `TIMEZONE_HOOK;' ? */
#endif
#if defined(TZSET) && defined(_MINIX)
extern long timezone; /* not defined in time.h */
#endif
/* ------------------------------------------------------------------------ */
#if defined(FTIME) || defined(GETTIMEOFDAY) || defined(TZSET)
static long
gettz()
#ifdef TZSET
{
tzset();
return timezone;
}
#endif
/* ------------------------------------------------------------------------ */
#if !defined(TZSET) && defined(FTIME)
{
struct timeb buf;
ftime(&buf);
return buf.timezone * 60L;
}
#endif
/* ------------------------------------------------------------------------ */
#if !defined(TZSET) && !defined(FTIME) /* maybe defined(GETTIMEOFDAY) */
{
#ifdef HAVE_TM_ZONE
time_t tt;
time(&tt);
return -localtime(&tt)->tm_gmtoff;
#else /* HAVE_TM_ZONE */
struct timeval tp;
struct timezone tzp;
gettimeofday(&tp, &tzp);/* specific to 4.3BSD */
/*
* return (tzp.tz_minuteswest * 60L + (tzp.tz_dsttime != 0 ? 60L *
* 60L : 0));
*/
return (tzp.tz_minuteswest * 60L);
#endif /* HAVE_TM_ZONE */
}
#endif
#endif /* defined(FTIME) || defined(GETTIMEOFDAY) ||
* defined(TZSET) */
/* ------------------------------------------------------------------------ */
#ifdef NOT_USED
static 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
/* ------------------------------------------------------------------------ */
static time_t generic_to_unix_stamp(long t)
#if defined(MKTIME) || defined(TIMELOCAL)
{
struct tm dostm;
/*
* special case: if MSDOS format date and time were zero, then we
* set time to be zero here too.
*/
if (t == 0)
return (time_t) 0;
dostm.tm_sec = (t & 0x1f) * 2;
dostm.tm_min = t >> 5 & 0x3f;
dostm.tm_hour = t >> 11 & 0x1f;
dostm.tm_mday = t >> 16 & 0x1f;
dostm.tm_mon = ((t >> 16) + 5 & 0x0f) - 1; /* 0..11 */
dostm.tm_year = ((t >> 16) + 9 & 0x7f) + 80;
#if 0
dostm.tm_isdst = 0; /* correct? */
#endif
dostm.tm_isdst = -1; /* correct? */
#ifdef MKTIME
return (time_t) mktime(&dostm);
#else /* maybe defined(TIMELOCAL) */
return (time_t) timelocal(&dostm);
#endif
}
#else /* defined(MKTIME) || defined(TIMELOCAL) */
{
int year, month, day, hour, min, sec;
long longtime;
static unsigned int dsboy[12] = {0, 31, 59, 90, 120, 151,
181, 212, 243, 273, 304, 334};
unsigned int days;
/*
* special case: if MSDOS format date and time were zero, then we
* set time to be zero here too.
*/
if (t == 0)
return (time_t) 0;
year = ((int) ((t >> 16) + 9) & 0x7f) + 1980;
month = (int) ((t >> 16) + 5) & 0x0f; /* 1..12 means Jan..Dec */
day = (int) (t >> 16) & 0x1f; /* 1..31 means 1st,...31st */
hour = ((int) t >> 11) & 0x1f;
min = ((int) t >> 5) & 0x3f;
sec = ((int) t & 0x1f) * 2;
/* Calculate days since 1970.01.01 */
days = (365 * (year - 1970) + /* days due to whole years */
(year - 1970 + 1) / 4 + /* days due to leap years */
dsboy[month - 1] + /* days since beginning of this year */
day - 1); /* days since beginning of month */
if ((year % 4 == 0) &&
(year % 100 != 0 || year % 400 == 0) && /* 1999.5.24 t.oka */
(month >= 3)) /* 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) + hour) * 60 + min) * 60 + sec;
longtime += gettz(); /* adjust for timezone */
/* LONGTIME is now the time in seconds, since 1970/01/01 00:00:00. */
return (time_t) longtime;
}
#endif /* defined(MKTIME) || defined(TIMELOCAL) */
/* ------------------------------------------------------------------------ */
static long unix_to_generic_stamp(time_t t)
{
struct tm *tm = localtime(&t);
return ((((long) (tm->tm_year - 80)) << 25) +
(((long) (tm->tm_mon + 1)) << 21) +
(((long) tm->tm_mday) << 16) +
(long) ((tm->tm_hour << 11) +
(tm->tm_min << 5) +
(tm->tm_sec / 2)));
}
/* ------------------------------------------------------------------------ */
/* build header functions */
/* ------------------------------------------------------------------------ */
bool get_header(struct zfile *fp, LzHeader *hdr)
{
int header_size;
int name_length;
char data[LZHEADER_STRAGE];
char dirname[FILENAME_LENGTH];
int dir_length = 0;
int checksum;
int i;
char *ptr;
int extend_size;
int dmy;
bzero(hdr, sizeof(LzHeader));
if (((header_size = zfile_getc(fp)) == EOF) || (header_size == 0)) {
return FALSE; /* finish */
}
if (zfile_fread(data + I_HEADER_CHECKSUM,
sizeof(char), header_size - 1, fp) < header_size - 1) {
fatal_error(L"Invalid header (LHarc file ?)");
return FALSE; /* finish */
}
setup_get(data + I_HEADER_LEVEL);
hdr->header_level = get_byte ();
if (hdr->header_level != 2 &&
zfile_fread(data + header_size, sizeof(char), 2, fp) < 2) {
fatal_error(L"Invalid header (LHarc file ?)");
return FALSE; /* finish */
}
if (hdr->header_level >= 3) {
fatal_error(L"Unknown level header");
return FALSE;
}
setup_get(data + I_HEADER_CHECKSUM);
checksum = get_byte ();
if (hdr->header_level == 2) {
hdr->header_size = header_size + checksum*256;
} else {
hdr->header_size = header_size;
}
bcopy(data + I_METHOD, hdr->method, METHOD_TYPE_STRAGE);
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_byte ();
if ((hdr->header_level = get_byte ()) != 2) {
if (calc_sum(data + I_METHOD, header_size) != checksum)
warning(L"Checksum error (LHarc file?)", L"");
name_length = get_byte ();
for (i = 0; i < name_length; i++)
hdr->name[i] = (char) get_byte ();
hdr->name[name_length] = '\0';
}
else {
hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
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 (hdr->header_level == 0) {
extend_size = header_size - name_length -22;
if (extend_size < 0) {
if (extend_size == -2) {
hdr->extend_type = EXTEND_GENERIC;
hdr->has_crc = FALSE;
} else {
fatal_error(L"Unkonwn header (lha file?)");
return FALSE;
}
} else {
hdr->has_crc = TRUE;
hdr->crc = get_word ();
}
if (extend_size >= 1) {
hdr->extend_type = get_byte ();
extend_size--;
}
if (hdr->extend_type == EXTEND_UNIX || hdr->extend_type == EXTEND_AMIGAOS) {
if (extend_size >= 11) {
hdr->minor_version = get_byte ();
hdr->unix_last_modified_stamp = (time_t) get_longword();
hdr->unix_mode = get_word ();
hdr->unix_uid = get_word ();
hdr->unix_gid = get_word ();
extend_size -= 11;
} else {
hdr->extend_type = EXTEND_GENERIC;
}
}
while (extend_size-- > 0)
dmy = get_byte ();
if (hdr->extend_type == EXTEND_UNIX)
return TRUE;
} else if (hdr->header_level == 1) {
hdr->has_crc = TRUE;
extend_size = header_size - name_length-25;
hdr->crc = get_word ();
hdr->extend_type = get_byte ();
while (extend_size-- > 0)
dmy = get_byte ();
} else { /* level 2 */
hdr->has_crc = TRUE;
hdr->crc = get_word ();
hdr->extend_type = get_byte ();
}
if (hdr->header_level > 0) {
/* Extend Header */
if (hdr->header_level != 2)
setup_get(data + hdr->header_size);
ptr = get_ptr;
while ((header_size = get_word ()) != 0) {
if (hdr->header_level != 2 &&
((data + LZHEADER_STRAGE - get_ptr < header_size) ||
zfile_fread(get_ptr, sizeof(char), header_size, fp) < header_size)) {
fatal_error(L"Invalid header (LHa file ?)");
return FALSE;
}
switch (get_byte ()) {
case 0:
/*
* header crc
*/
setup_get(get_ptr + header_size - 3);
break;
case 1:
/*
* filename
*/
if (header_size >= 256)
return FALSE;
for (i = 0; i < header_size - 3; i++)
hdr->name[i] = (char) get_byte ();
hdr->name[header_size - 3] = '\0';
name_length = header_size - 3;
break;
case 2:
/*
* directory
*/
if (header_size >= FILENAME_LENGTH)
return FALSE;
for (i = 0; i < header_size - 3; i++)
dirname[i] = (char) get_byte ();
dirname[header_size - 3] = '\0';
convdelim((unsigned char*)dirname, DELIM);
dir_length = header_size - 3;
break;
case 0x40:
/*
* MS-DOS attribute
*/
if (hdr->extend_type == EXTEND_MSDOS ||
hdr->extend_type == EXTEND_HUMAN ||
hdr->extend_type == EXTEND_AMIGAOS ||
hdr->extend_type == EXTEND_GENERIC)
hdr->attribute = get_word ();
break;
case 0x50:
/*
* UNIX permission
*/
if (hdr->extend_type == EXTEND_UNIX)
hdr->unix_mode = get_word ();
break;
case 0x51:
/*
* UNIX gid and uid
*/
if (hdr->extend_type == EXTEND_UNIX) {
hdr->unix_gid = get_word ();
hdr->unix_uid = get_word ();
}
break;
case 0x52:
/*
* UNIX group name
*/
setup_get(get_ptr + header_size - 3);
break;
case 0x53:
/*
* UNIX user name
*/
setup_get(get_ptr + header_size - 3);
break;
case 0x54:
/*
* UNIX last modified time
*/
if (hdr->extend_type == EXTEND_UNIX || hdr->extend_type == EXTEND_AMIGAOS)
hdr->unix_last_modified_stamp = (time_t) get_longword();
break;
default:
/*
* other headers
*/
setup_get(get_ptr + header_size - 3);
break;
}
}
if (hdr->header_level != 2 && get_ptr - ptr != 2) {
hdr->packed_size -= get_ptr - ptr - 2;
hdr->header_size += get_ptr - ptr - 2;
}
}
switch (hdr->extend_type) {
case EXTEND_MSDOS:
msdos_to_unix_filename(hdr->name, name_length);
msdos_to_unix_filename(dirname, dir_length);
case EXTEND_HUMAN:
if (hdr->header_level == 2)
hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
else
hdr->unix_last_modified_stamp =
generic_to_unix_stamp(hdr->last_modified_stamp);
break;
#ifdef OSK
case EXTEND_OS68K:
case EXTEND_XOSK:
#endif
case EXTEND_AMIGAOS:
case EXTEND_UNIX:
break;
case EXTEND_MACOS:
macos_to_unix_filename(hdr->name, name_length);
/* macos_to_unix_filename(dirname, dir_length); */
hdr->unix_last_modified_stamp =
generic_to_unix_stamp(hdr->last_modified_stamp);
break;
default:
generic_to_unix_filename(hdr->name, name_length);
generic_to_unix_filename(dirname, dir_length);
if (hdr->header_level == 2)
hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
else
hdr->unix_last_modified_stamp =
generic_to_unix_stamp(hdr->last_modified_stamp);
}
if (dir_length) {
strcat(dirname, hdr->name);
strcpy(hdr->name, dirname);
name_length += dir_length;
}
return TRUE;
}
/* ------------------------------------------------------------------------ */
void init_header(char *name, struct stat *v_stat, LzHeader *hdr)
{
int len;
if (compress_method == LZHUFF5_METHOD_NUM) /* Changed N.Watazaki */
bcopy(LZHUFF5_METHOD, hdr->method, METHOD_TYPE_STRAGE);
else if (compress_method)
bcopy(LZHUFF1_METHOD, hdr->method, METHOD_TYPE_STRAGE);
else
bcopy(LZHUFF0_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);
hdr->attribute = GENERIC_ATTRIBUTE;
hdr->header_level = header_level;
strcpy(hdr->name, name);
len = strlen(name);
hdr->crc = 0x0000;
hdr->extend_type = EXTEND_UNIX;
hdr->unix_last_modified_stamp = v_stat->st_mtime;
/* since 00:00:00 JAN.1.1970 */
#ifdef NOT_COMPATIBLE_MODE
/* Please need your modification in this space. */
#else
hdr->unix_mode = v_stat->st_mode;
#endif
hdr->unix_uid = v_stat->st_uid;
hdr->unix_gid = v_stat->st_gid;
if (is_directory(v_stat)) {
bcopy(LZHDIRS_METHOD, hdr->method, METHOD_TYPE_STRAGE);
hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
hdr->original_size = 0;
if (len > 0 && hdr->name[len - 1] != '/')
strcpy(&hdr->name[len++], "/");
}
#ifdef S_IFLNK
if (is_symlink(v_stat)) {
char lkname[257];
int len;
bcopy(LZHDIRS_METHOD, hdr->method, METHOD_TYPE_STRAGE);
hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
hdr->original_size = 0;
len = readlink(name, lkname, 256);
lkname[len] = (char)'\0';
sprintf(hdr->name, "%s|%s", hdr->name, lkname);
}
#endif
if (generic_format)
unix_to_generic_filename(hdr->name, len);
}
/* ------------------------------------------------------------------------ */
/* LHa for UNIX */
/* huf.c -- new static Huffman */
/* */
/* Modified Nobutaka Watazaki */
/* */
/* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
/* Ver. 1.14i Support LH7 & Bug Fixed 2000.10. 6 t.okamoto */
/* ------------------------------------------------------------------------ */
#include "lha.h"
#ifdef sony_news
#include <sys/param.h>
#endif
#if defined(__STDC__) || defined(NEWSOS)
#include <stdlib.h>
#endif
/* ------------------------------------------------------------------------ */
unsigned short h_left[2 * NC - 1], h_right[2 * NC - 1];
unsigned char c_len[NC], pt_len[NPT];
unsigned short c_freq[2 * NC - 1], c_table[4096], c_code[NC], p_freq[2 * NP - 1],
pt_table[256], pt_code[NPT], t_freq[2 * NT - 1];
static unsigned char *buf;
static unsigned int bufsiz;
static unsigned short blocksize;
static unsigned short output_pos, output_mask;
static int pbit;
static int np;
/* ------------------------------------------------------------------------ */
/* Encording */
/* ------------------------------------------------------------------------ */
static void count_t_freq(void)
{
short i, k, n, count;
for (i = 0; i < NT; i++)
t_freq[i] = 0;
n = NC;
while (n > 0 && c_len[n - 1] == 0)
n--;
i = 0;
while (i < n) {
k = c_len[i++];
if (k == 0) {
count = 1;
while (i < n && c_len[i] == 0) {
i++;
count++;
}
if (count <= 2)
t_freq[0] += count;
else if (count <= 18)
t_freq[1]++;
else if (count == 19) {
t_freq[0]++;
t_freq[1]++;
}
else
t_freq[2]++;
} else
t_freq[k + 2]++;
}
}
/* ------------------------------------------------------------------------ */
#if 0
static void
write_pt_len(n, nbit, i_special)
short n;
short nbit;
short i_special;
{
short i, k;
while (n > 0 && pt_len[n - 1] == 0)
n--;
putbits(nbit, n);
i = 0;
while (i < n) {
k = pt_len[i++];
if (k <= 6)
putbits(3, k);
else
putbits(k - 3, USHRT_MAX << 1);
if (i == i_special) {
while (i < 6 && pt_len[i] == 0)
i++;
putbits(2, i - 3);
}
}
}
/* ------------------------------------------------------------------------ */
static void
write_c_len(/*void*/)
{
short i, k, n, count;
n = NC;
while (n > 0 && c_len[n - 1] == 0)
n--;
putbits(CBIT, n);
i = 0;
while (i < n) {
k = c_len[i++];
if (k == 0) {
count = 1;
while (i < n && c_len[i] == 0) {
i++;
count++;
}
if (count <= 2) {
for (k = 0; k < count; k++)
putcode(pt_len[0], pt_code[0]);
}
else if (count <= 18) {
putcode(pt_len[1], pt_code[1]);
putbits(4, count - 3);
}
else if (count == 19) {
putcode(pt_len[0], pt_code[0]);
putcode(pt_len[1], pt_code[1]);
putbits(4, 15);
}
else {
putcode(pt_len[2], pt_code[2]);
putbits(CBIT, count - 20);
}
}
else
putcode(pt_len[k + 2], pt_code[k + 2]);
}
}
/* ------------------------------------------------------------------------ */
static void
encode_c(c)
short c;
{
putcode(c_len[c], c_code[c]);
}
/* ------------------------------------------------------------------------ */
static void
encode_p(p)
unsigned short p;
{
unsigned short c, q;
c = 0;
q = p;
while (q) {
q >>= 1;
c++;
}
putcode(pt_len[c], pt_code[c]);
if (c > 1)
putbits(c - 1, p);
}
/* ------------------------------------------------------------------------ */
static void
send_block( /* void */ )
{
unsigned char flags;
unsigned short i, k, root, pos, size;
root = make_tree(NC, c_freq, c_len, c_code);
size = c_freq[root];
putbits(16, size);
if (root >= NC) {
count_t_freq();
root = make_tree(NT, t_freq, pt_len, pt_code);
if (root >= NT) {
write_pt_len(NT, TBIT, 3);
} else {
putbits(TBIT, 0);
putbits(TBIT, root);
}
write_c_len();
} else {
putbits(TBIT, 0);
putbits(TBIT, 0);
putbits(CBIT, 0);
putbits(CBIT, root);
}
root = make_tree(np, p_freq, pt_len, pt_code);
if (root >= np) {
write_pt_len(np, pbit, -1);
}
else {
putbits(pbit, 0);
putbits(pbit, root);
}
pos = 0;
for (i = 0; i < size; i++) {
if (i % CHAR_BIT == 0)
flags = buf[pos++];
else
flags <<= 1;
if (flags & (1 << (CHAR_BIT - 1))) {
encode_c(buf[pos++] + (1 << CHAR_BIT));
k = buf[pos++] << CHAR_BIT;
k += buf[pos++];
encode_p(k);
} else
encode_c(buf[pos++]);
if (unpackable)
return;
}
for (i = 0; i < NC; i++)
c_freq[i] = 0;
for (i = 0; i < np; i++)
p_freq[i] = 0;
}
/* ------------------------------------------------------------------------ */
void
output_st1(c, p)
unsigned short c;
unsigned short p;
{
static unsigned short cpos;
output_mask >>= 1;
if (output_mask == 0) {
output_mask = 1 << (CHAR_BIT - 1);
if (output_pos >= bufsiz - 3 * CHAR_BIT) {
send_block();
if (unpackable)
return;
output_pos = 0;
}
cpos = output_pos++;
buf[cpos] = 0;
}
buf[output_pos++] = (unsigned char) c;
c_freq[c]++;
if (c >= (1 << CHAR_BIT)) {
buf[cpos] |= output_mask;
buf[output_pos++] = (unsigned char) (p >> CHAR_BIT);
buf[output_pos++] = (unsigned char) p;
c = 0;
while (p) {
p >>= 1;
c++;
}
p_freq[c]++;
}
}
#endif
/* ------------------------------------------------------------------------ */
unsigned char *alloc_buf(void)
{
bufsiz = 16 * 1024 *2; /* 65408U; */ /* t.okamoto */
while ((buf = (unsigned char *) malloc(bufsiz)) == NULL) {
bufsiz = (bufsiz / 10) * 9;
if (bufsiz < 4 * 1024)
break;
}
return buf;
}
/* ------------------------------------------------------------------------ */
#if 0
void
encode_start_st1( /* void */ )
{
int i;
#if 0
if (dicbit <= (MAX_DICBIT - 2)) {
pbit = 4; /* lh4,5 etc. */
np = 14;
} else {
pbit = 5; /* lh6 */
np = 16;
}
#endif
if (dicbit <= 13) {
pbit = 4; /* lh4,5 etc. */
np = 14;
} else {
pbit = 5; /* lh6,7 */
if (dicbit == 16)
np = 17;
else
np = 16;
}
for (i = 0; i < NC; i++)
c_freq[i] = 0;
for (i = 0; i < np; i++)
p_freq[i] = 0;
output_pos = output_mask = 0;
init_putbits();
buf[0] = 0;
}
/* ------------------------------------------------------------------------ */
void
encode_end_st1( /* void */ )
{
if (!unpackable) {
send_block();
putbits(CHAR_BIT - 1, 0); /* flush remaining bits */
}
}
#endif
/* ------------------------------------------------------------------------ */
/* decoding */
/* ------------------------------------------------------------------------ */
static void read_pt_len(short nn, short nbit, short i_special)
{
int i, c, n;
n = getbits(nbit);
if (n == 0) {
c = getbits(nbit);
for (i = 0; i < nn; i++)
pt_len[i] = 0;
for (i = 0; i < 256; i++)
pt_table[i] = c;
}
else {
i = 0;
while (i < n) {
c = lhabitbuf >> (16 - 3);
if (c == 7) {
unsigned short mask = 1 << (16 - 4);
while (mask & lhabitbuf) {
mask >>= 1;
c++;
}
}
fillbuf((c < 7) ? 3 : c - 3);
pt_len[i++] = c;
if (i == i_special) {
c = getbits(2);
while (--c >= 0)
pt_len[i++] = 0;
}
}
while (i < nn)
pt_len[i++] = 0;
lha_make_table(nn, pt_len, 8, pt_table);
}
}
/* ------------------------------------------------------------------------ */
static void read_c_len(void)
{
short i, c, n;
n = getbits(CBIT);
if (n == 0) {
c = getbits(CBIT);
for (i = 0; i < NC; i++)
c_len[i] = 0;
for (i = 0; i < 4096; i++)
c_table[i] = c;
} else {
i = 0;
while (i < n) {
c = pt_table[lhabitbuf >> (16 - 8)];
if (c >= NT) {
unsigned short mask = 1 << (16 - 9);
do {
if (lhabitbuf & mask)
c = h_right[c];
else
c = h_left[c];
mask >>= 1;
} while (c >= NT);
}
fillbuf(pt_len[c]);
if (c <= 2) {
if (c == 0)
c = 1;
else if (c == 1)
c = getbits(4) + 3;
else
c = getbits(CBIT) + 20;
while (--c >= 0)
c_len[i++] = 0;
}
else
c_len[i++] = c - 2;
}
while (i < NC)
c_len[i++] = 0;
lha_make_table(NC, c_len, 12, c_table);
}
}
/* ------------------------------------------------------------------------ */
unsigned short decode_c_st1(void)
{
unsigned short j, mask;
if (blocksize == 0) {
blocksize = getbits(16);
read_pt_len(NT, TBIT, 3);
read_c_len();
read_pt_len(np, pbit, -1);
}
blocksize--;
j = c_table[lhabitbuf >> 4];
if (j < NC)
fillbuf(c_len[j]);
else {
fillbuf(12);
mask = 1 << (16 - 1);
do {
if (lhabitbuf & mask)
j = h_right[j];
else
j = h_left[j];
mask >>= 1;
} while (j >= NC);
fillbuf(c_len[j] - 12);
}
return j;
}
/* ------------------------------------------------------------------------ */
unsigned short decode_p_st1(void)
{
unsigned short j, mask;
j = pt_table[lhabitbuf >> (16 - 8)];
if (j < np)
fillbuf(pt_len[j]);
else {
fillbuf(8);
mask = 1 << (16 - 1);
do {
if (lhabitbuf & mask)
j = h_right[j];
else
j = h_left[j];
mask >>= 1;
} while (j >= np);
fillbuf(pt_len[j] - 8);
}
if (j != 0)
j = (1 << (j - 1)) + getbits(j - 1);
return j;
}
/* ------------------------------------------------------------------------ */
void decode_start_st1(void)
{
if (dicbit <= 13) {
np = 14;
pbit = 4;
} else {
if (dicbit == 16) {
np = 17; /* for -lh7- */
} else {
np = 16;
}
pbit = 5;
}
#if 0
if (dicbit <= 13) { /* 13 ... Changed N.Watazaki */
np = 14;
pbit = 4;
} else {
np = 16;
pbit = 5;
}
#endif
init_getbits();
blocksize = 0;
}
/* Local Variables: */
/* mode:c */
/* tab-width:4 */
/* End: */
/* ------------------------------------------------------------------------ */
/* LHa for UNIX */
/* larc.c -- extra *.lzs */
/* */
/* Modified Nobutaka Watazaki */
/* */
/* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
/* ------------------------------------------------------------------------ */
#include "lha.h"
/* ------------------------------------------------------------------------ */
static int flag, flagcnt, matchpos;
/* ------------------------------------------------------------------------ */
unsigned short decode_c_lzs(void)
{
if (getbits(1)) {
return getbits(8);
}
else {
matchpos = getbits(11);
return getbits(4) + 0x100;
}
}
/* ------------------------------------------------------------------------ */
unsigned short decode_p_lzs(void)
{
return (loc - matchpos - MAGIC0) & 0x7ff;
}
/* ------------------------------------------------------------------------ */
void decode_start_lzs(void)
{
init_getbits();
}
/* ------------------------------------------------------------------------ */
unsigned short decode_c_lz5(void)
{
int c;
if (flagcnt == 0) {
flagcnt = 8;
flag = zfile_getc(infile);
}
flagcnt--;
c = zfile_getc(infile);
if ((flag & 1) == 0) {
matchpos = c;
c = zfile_getc(infile);
matchpos += (c & 0xf0) << 4;
c &= 0x0f;
c += 0x100;
}
flag >>= 1;
return c;
}
/* ------------------------------------------------------------------------ */
unsigned short decode_p_lz5(void)
{
return (loc - matchpos - MAGIC5) & 0xfff;
}
/* ------------------------------------------------------------------------ */
void decode_start_lz5(void)
{
int i;
flagcnt = 0;
for (i = 0; i < 256; i++)
memset(&text[i * 13 + 18], i, 13);
for (i = 0; i < 256; i++)
text[256 * 13 + 18 + i] = i;
for (i = 0; i < 256; i++)
text[256 * 13 + 256 + 18 + i] = 255 - i;
memset(&text[256 * 13 + 512 + 18], 0, 128);
memset(&text[256 * 13 + 512 + 128 + 18], ' ', 128 - 18);
}
#include "sysconfig.h"
#include "sysdeps.h"
#include "zfile.h"
#define SYSTIME_HAS_NO_TM
#define NODIRECTORY
#define FTIME
#define NOBSTRING
#define NOINDEX
#define MKTIME
/* ------------------------------------------------------------------------ */
/* LHa for UNIX Archiver Driver */
/* */
/* Modified Nobutaka Watazaki */
/* */
/* Ver. 1.14 Soruce All chagned 1995.01.14 N.Watazaki */
/* Ver. 1.14i Modified and bug fixed 2000.10.06 t.okamoto */
/* ------------------------------------------------------------------------ */
/*
Included...
lharc.h interface.h slidehuf.h
*/
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include "lha_macro.h"
struct encode_option {
#if 1 || defined(__STDC__) || defined(AIX)
void (*output) ();
void (*encode_start) ();
void (*encode_end) ();
#else
int (*output) ();
int (*encode_start) ();
int (*encode_end) ();
#endif
};
struct decode_option {
unsigned short (*decode_c) ();
unsigned short (*decode_p) ();
#if 1 || defined(__STDC__) || defined(AIX)
void (*decode_start) ();
#else
int (*decode_start) ();
#endif
};
/* ------------------------------------------------------------------------ */
/* LHa File Type Definition */
/* ------------------------------------------------------------------------ */
struct string_pool {
int used;
int size;
int n;
char *buffer;
};
typedef struct LzHeader {
unsigned char header_size;
char method[METHOD_TYPE_STRAGE];
long packed_size;
long original_size;
long last_modified_stamp;
unsigned char attribute;
unsigned char header_level;
char name[256];
unsigned short crc;
bool 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;
struct interfacing {
struct zfile *infile;
struct zfile *outfile;
unsigned long original;
unsigned long packed;
int dicbit;
int method;
};
/* ------------------------------------------------------------------------ */
/* Option switch variable */
/* ------------------------------------------------------------------------ */
/* command line options (common options) */
EXTERN bool quiet;
EXTERN bool text_mode;
EXTERN bool verbose;
EXTERN bool noexec; /* debugging option */
EXTERN bool force;
EXTERN bool prof;
EXTERN bool delete_after_append;
EXTERN int compress_method;
EXTERN int header_level;
/* EXTERN int quiet_mode; */ /* 1996.8.13 t.okamoto */
#ifdef EUC
EXTERN bool euc_mode;
#endif
/* list command flags */
EXTERN bool verbose_listing;
/* extract/print command flags */
EXTERN bool output_to_stdout;
/* add/update/delete command flags */
EXTERN bool new_archive;
EXTERN bool update_if_newer;
EXTERN bool generic_format;
EXTERN bool remove_temporary_at_error;
EXTERN bool recover_archive_when_interrupt;
EXTERN bool remove_extracting_file_when_interrupt;
EXTERN bool get_filename_from_stdin;
EXTERN bool ignore_directory;
EXTERN bool verify_mode;
/* Indicator flag */
EXTERN int quiet_mode;
/* ------------------------------------------------------------------------ */
/* Globale Variable */
/* ------------------------------------------------------------------------ */
EXTERN char **cmd_filev;
EXTERN int cmd_filec;
EXTERN char *archive_name;
EXTERN char expanded_archive_name[FILENAME_LENGTH];
EXTERN char temporary_name[FILENAME_LENGTH];
EXTERN char backup_archive_name[FILENAME_LENGTH];
EXTERN char *reading_filename, *writting_filename;
/* 1996.8.13 t.okamoto */
#if 0
EXTERN bool remove_temporary_at_error;
EXTERN bool recover_archive_when_interrupt;
EXTERN bool remove_extracting_file_when_interrupt;
#endif
EXTERN int archive_file_mode;
EXTERN int archive_file_gid;
EXTERN node *next;
/* EXTERN unsigned short crc; */ /* 1996.8.13 t.okamoto */
EXTERN int noconvertcase; /* 2000.10.6 */
/* slide.c */
EXTERN int unpackable;
EXTERN unsigned long origsize, compsize;
EXTERN unsigned short dicbit;
EXTERN unsigned short maxmatch;
EXTERN unsigned long count;
EXTERN unsigned long loc; /* short -> long .. Changed N.Watazaki */
EXTERN unsigned char *text;
EXTERN int prev_char;
/* huf.c */
#ifndef LHA_MAIN_SRC /* t.okamoto 96/2/20 */
EXTERN unsigned short h_left[], h_right[];
EXTERN unsigned char c_len[], pt_len[];
EXTERN unsigned short c_freq[], c_table[], c_code[];
EXTERN unsigned short p_freq[], pt_table[], pt_code[], t_freq[];
#endif
/* append.c */
#ifdef NEED_INCREMENTAL_INDICATOR
EXTERN long indicator_count;
EXTERN long indicator_threshold;
#endif
/* crcio.c */
EXTERN struct zfile *infile, *outfile;
EXTERN unsigned short crc, lhabitbuf;
EXTERN int dispflg;
EXTERN long reading_size;
/* from dhuf.c */
EXTERN unsigned int n_max;
/* lhadd.c */
EXTERN FILE *temporary_fp;
/* ------------------------------------------------------------------------ */
/* Functions */
/* ------------------------------------------------------------------------ */
/* from lharc.c */
extern int patmatch();
extern void interrupt();
extern void message();
extern void warning();
extern void error();
extern void fatal_error();
extern bool need_file();
extern int inquire();
extern FILE *xfopen();
extern bool find_files();
extern void free_files();
extern void init_sp();
extern void add_sp();
extern void finish_sp();
extern void free_sp();
extern void cleaning_files();
extern void build_temporary_name();
extern void build_backup_file_name();
extern void build_standard_archive_name();
extern FILE *open_old_archive();
extern void init_header();
extern bool get_header(struct zfile *fp, LzHeader *hdr);
extern bool archive_is_msdos_sfx1();
extern bool skip_msdos_sfx1_code();
extern void write_header();
extern void write_archive_tail();
extern void copy_old_one();
extern unsigned char *convdelim(unsigned char *path, unsigned char delim);
extern long copyfile();
extern void cmd_list(), cmd_extract(), cmd_add(), cmd_delete();
extern char *extract_directory;
/* from slide.c */
extern int encode_alloc();
extern void encode();
extern int decode(struct interfacing*);
/* from append.c */
extern void start_indicator();
extern void finish_indicator();
extern void finish_indicator2();
/* slide.c */
extern void output_st1();
extern unsigned char *alloc_buf();
extern void encode_start_st1();
extern void encode_end_st1();
extern unsigned short decode_c_st1();
extern unsigned short decode_p_st1();
extern void decode_start_st1();
/* from shuf.c */
extern void decode_start_st0();
extern void encode_p_st0( /* unsigned short j */ );
extern void encode_start_fix();
extern void decode_start_fix();
extern unsigned short decode_c_st0();
extern unsigned short decode_p_st0();
/* from dhuf.c */
extern void start_c_dyn();
extern void decode_start_dyn();
extern unsigned short decode_c_dyn();
extern unsigned short decode_p_dyn();
extern void output_dyn( /* int code, unsigned int pos */ );
extern void encode_end_dyn();
extern int decode_lzhuf();
/* from larc.c */
extern unsigned short decode_c_lzs();
extern unsigned short decode_p_lzs();
extern unsigned short decode_c_lz5();
extern unsigned short decode_p_lz5();
extern void decode_start_lzs();
extern void decode_start_lz5();
extern void lha_make_table(short nchar, unsigned char bitlen[], short tablebits, unsigned short table[]);
/* from maketree.c */
/*
* void make_code(short n, uchar len[], ushort code[]); short make_tree(short
* nparm, ushort freqparm[], uchar lenparm[], ushort codeparam[]);
*/
extern void make_code( /* int n, uchar len[], ushort code[] */ );
extern short make_tree( /* int nparm, ushort freqparm[], uchar lenparm[],
ushort codeparam[] */ );
/* from crcio.c */
extern void make_crctable();
extern unsigned short calccrc(unsigned char *p, unsigned int n);
extern void fillbuf(unsigned char n);
extern unsigned short getbits(unsigned char n);
extern void putcode(unsigned char n, unsigned short x);
extern void putbits(unsigned char n, unsigned short x);
extern int fread_crc(unsigned char *p, int n, struct zfile *f);
extern void fwrite_crc(unsigned char *p, int n, struct zfile *f);
extern void init_getbits();
extern void init_putbits();
extern void make_crctable();
extern unsigned short calccrc();
/* from lhadd.c */
extern int encode_lzhuf();
extern int encode_stored_crc();
#define warning write_log
#define fatal_error write_log
#define error write_log
/* ------------------------------------------------------------------------ */
/* LHa for UNIX Archiver Driver macro define */
/* */
/* Modified Nobutaka Watazaki */
/* */
/* Ver. 1.14 Soruce All chagned 1995.01.14 N.Watazaki */
/* Ver. 1.14g modified 2000.05.06 T.OKAMOTO */
/* ------------------------------------------------------------------------ */
/* external variables */
//extern int errno;
/* used by qsort() for alphabetic-sort */
#define STRING_COMPARE(a,b) strcmp((a),(b))
#define FILENAME_LENGTH 1024
/* ------------------------------------------------------------------------ */
/* YOUR CUSTOMIZIES */
/* ------------------------------------------------------------------------ */
#ifndef ARCHIVENAME_EXTENTION
#define ARCHIVENAME_EXTENTION ".lzh"
#endif
#ifndef BACKUPNAME_EXTENTION
#define BACKUPNAME_EXTENTION ".bak"
#endif
#ifndef TMP_FILENAME_TEMPLATE
#define TMP_FILENAME_TEMPLATE "/tmp/lhXXXXXX"
#endif
#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) && \
((unsigned char)(c) != 0x7f))
#ifdef MULTIBYTE_CHAR
#define MULTIBYTE_FIRST_P SJC_FIRST_P
#define MULTIBYTE_SECOND_P SJC_SECOND_P
#endif /* MULTIBYTE_CHAR */
/* ------------------------------------------------------------------------ */
/* LHa File Definitions */
/* ------------------------------------------------------------------------ */
#ifdef S_IFLNK
#define GETSTAT lstat
#else
#define GETSTAT stat
#endif
#ifdef LHA_MAIN_SRC
#define EXTERN
#else
#define EXTERN extern
#endif /* LHA_MAIN_SRC */
#define LZHUFF0_METHOD "-lh0-"
#define LZHUFF1_METHOD "-lh1-"
#define LZHUFF2_METHOD "-lh2-"
#define LZHUFF3_METHOD "-lh3-"
#define LZHUFF4_METHOD "-lh4-"
#define LZHUFF5_METHOD "-lh5-"
#define LZHUFF6_METHOD "-lh6-"
#define LZHUFF7_METHOD "-lh7-"
#define LARC_METHOD "-lzs-"
#define LARC5_METHOD "-lz5-"
#define LARC4_METHOD "-lz4-"
#define LZHDIRS_METHOD "-lhd-"
#define METHOD_TYPE_STRAGE 5
/* Added N.Watazaki ..V */
#define LZHUFF0_METHOD_NUM 0
#define LZHUFF1_METHOD_NUM 1
#define LZHUFF2_METHOD_NUM 2
#define LZHUFF3_METHOD_NUM 3
#define LZHUFF4_METHOD_NUM 4
#define LZHUFF5_METHOD_NUM 5
#define LZHUFF6_METHOD_NUM 6
#define LZHUFF7_METHOD_NUM 7
#define LARC_METHOD_NUM 8
#define LARC5_METHOD_NUM 9
#define LARC4_METHOD_NUM 10
#define LZHDIRS_METHOD_NUM 11
/* Added N.Watazaki ..^ */
#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_HEADER_LEVEL 20
#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 I_GENERIC_HEADER_BOTTOM I_EXTEND_TYPE
#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' /* OS-9000??? */
#define EXTEND_HUMAN 'H'
#define EXTEND_CPM 'C'
#define EXTEND_FLEX 'F'
#define EXTEND_RUNSER 'R'
#define EXTEND_AMIGAOS 'A'
/* this OS type is not official */
#define EXTEND_TOWNSOS 'T'
#define EXTEND_XOSK 'X'
/*---------------------------------------------------------------------------*/
#define GENERIC_ATTRIBUTE 0x20
#define GENERIC_DIRECTORY_ATTRIBUTE 0x10
#define HEADER_LEVEL0 0x00
#define HEADER_LEVEL1 0x01
#define HEADER_LEVEL2 0x02
#define CURRENT_UNIX_MINOR_VERSION 0x00
#define DELIM ('/')
#define DELIM2 (0xff)
#define DELIMSTR "/"
#define OSK_RW_RW_RW 0000033
#define OSK_FILE_REGULAR 0000000
#define OSK_DIRECTORY_PERM 0000200
#define OSK_SHARED_PERM 0000100
#define OSK_OTHER_EXEC_PERM 0000040
#define OSK_OTHER_WRITE_PERM 0000020
#define OSK_OTHER_READ_PERM 0000010
#define OSK_OWNER_EXEC_PERM 0000004
#define OSK_OWNER_WRITE_PERM 0000002
#define OSK_OWNER_READ_PERM 0000001
#define UNIX_FILE_TYPEMASK 0170000
#define UNIX_FILE_REGULAR 0100000
#define UNIX_FILE_DIRECTORY 0040000
#define UNIX_FILE_SYMLINK 0120000
#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 4096
#define MAX_INDICATOR_COUNT 64
typedef short node;
/* ------------------------------------------------------------------------ */
/* Slide relation */
/* ------------------------------------------------------------------------ */
#if defined(__STDC__) || defined(AIX)
#include <limits.h>
#else
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
#ifndef UCHAR_MAX
#define UCHAR_MAX ((1<<(sizeof(unsigned char)*8))-1)
#endif
#ifndef USHRT_MAX
#define USHRT_MAX ((1<<(sizeof(unsigned short)*8))-1)
#endif
#ifndef SHRT_MAX
#define SHRT_MAX ((1<<(sizeof(short)*8-1))-1)
#endif
#ifndef SHRT_MIN
#define SHRT_MIN (SHRT_MAX-USHRT_MAX)
#endif
#ifndef ULONG_MAX
#define ULONG_MAX ((1<<(sizeof(unsigned long)*8))-1)
#endif
#ifndef LONG_MAX
#define LONG_MAX ((1<<(sizeof(long)*8-1))-1)
#endif
#ifndef LONG_MIN
#define LONG_MIN (LONG_MAX-ULONG_MAX)
#endif
#endif /* not __STDC__ */
/* ------------------------------------------------------------------------ */
/* FILE Attribute */
/* ------------------------------------------------------------------------ */
#define is_directory(statp) (((statp)->st_mode & S_IFMT) == S_IFDIR)
#define is_symlink(statp) (((statp)->st_mode & S_IFMT) == S_IFLNK)
#define is_regularfile(statp) (((statp)->st_mode & S_IFMT) == S_IFREG)
#ifdef MSDOS
#define WRITE_BINARY "wb"
#define READ_BINARY "rb"
#else
#define WRITE_BINARY "w"
#define READ_BINARY "r"
#endif
/* ------------------------------------------------------------------------ */
/* Memory and String function */
/* ------------------------------------------------------------------------ */
#include <string.h>
#ifdef NOINDEX
#define index strchr
#define rindex strrchr
#endif /* NOINDEX */
#ifdef NOBSTRING
#define bcmp(a,b,n) memcmp ((a),(b),(n))
#define bzero(d,n) memset((d),0,(n))
#define bcopy(s,d,n) memmove((d),(s),(n))
#endif /* NOBSTRING */
#ifdef USESTRCASECMP
#define strucmp(p,q) strcasecmp((p),(q))
#endif
/* ------------------------------------------------------------------------ */
/* Individual macro define */
/* ------------------------------------------------------------------------ */
/* from crcio.c */
#define CRCPOLY 0xA001 /* CRC-16 */
#define UPDATE_CRC(c) crc = crctable[(crc ^ (c)) & 0xFF] ^ (crc >> CHAR_BIT)
/* dhuf.c */
#define N_CHAR (256 + 60 - THRESHOLD + 1)
#define TREESIZE_C (N_CHAR * 2)
#define TREESIZE_P (128 * 2)
#define TREESIZE (TREESIZE_C + TREESIZE_P)
#define ROOT_C 0
#define ROOT_P TREESIZE_C
/* header.c */
#define setup_get(PTR) (get_ptr = (PTR))
#define get_byte() (*get_ptr++ & 0xff)
#define put_ptr get_ptr
#define setup_put(PTR) (put_ptr = (PTR))
#define put_byte(c) (*put_ptr++ = (char)(c))
/* huf.c */
#define NP (MAX_DICBIT + 1)
#define NT (USHRT_BIT + 3)
#if 0
#define PBIT 4 /* smallest integer such that (1 << PBIT) > * NP */
#define TBIT 5 /* smallest integer such that (1 << TBIT) > * NT */
#endif
#define PBIT 5 /* smallest integer such that (1 << PBIT) > * NP */
#define TBIT 5 /* smallest integer such that (1 << TBIT) > * NT */
#define NC (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD)
/* #if NT > NP #define NPT NT #else #define NPT NP #endif */
#define NPT 0x80
/* larc.c */
#define MAGIC0 18
#define MAGIC5 19
/* lharc.c */
#define CMD_UNKNOWN 0
#define CMD_EXTRACT 1
#define CMD_ADD 2
#define CMD_LIST 3
#define CMD_DELETE 4
#define STREQU(a,b) (((a)[0] == (b)[0]) ? (strcmp ((a),(b)) == 0) : FALSE)
/* shuf.c */
#define N1 286 /* alphabet size */
#define N2 (2 * N1 - 1) /* # of nodes in Huffman tree */
#define EXTRABITS 8 /* >= log2(F-THRESHOLD+258-N1) */
#define BUFBITS 16 /* >= log2(MAXBUF) */
#define LENFIELD 4 /* bit size of length field for tree output */
/* util.c */
#define BUFFERSIZE 2048
#define MAXSFXCODE 1024*64
#ifndef NULL
#define NULL (char *)0
#endif
/* slide.c */
/*
#define PERCOLATE 1
#define NIL 0
#define HASH(p, c) ((p) + ((c) << hash1) + hash2)
*/
/* slide.c */
#ifdef SUPPORT_LH7
#define MAX_DICBIT 16 /* lh7 use 16bits */
#endif
#ifndef SUPPORT_LH7
#define MAX_DICBIT 15 /* lh6 use 15bits */
#endif
#define MAX_DICSIZ (1 << MAX_DICBIT)
#define MATCHBIT 8 /* bits for MAXMATCH - THRESHOLD */
#define MAXMATCH 256 /* formerly F (not more than UCHAR_MAX + 1) */
#define THRESHOLD 3 /* choose optimal value */
/* from huf.c */
/* alphabet = {0, 1, 2, ..., NC - 1} */
#define CBIT 9 /* $\lfloor \log_2 NC \rfloor + 1$ */
#define USHRT_BIT 16 /* (CHAR_BIT * sizeof(ushort)) */
/* Local Variables: */
/* mode:c */
/* tab-width:4 */
/* End: */
/* ------------------------------------------------------------------------ */
/* LHa for UNIX */
/* maketbl.c -- makes decoding table */
/* */
/* Modified Nobutaka Watazaki */
/* */
/* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
/* ------------------------------------------------------------------------ */
#include "lha.h"
void lha_make_table(short nchar, unsigned char bitlen[], short tablebits, unsigned short table[])
{
unsigned short count[17]; /* count of bitlen */
unsigned short weight[17]; /* 0x10000ul >> bitlen */
unsigned short start[17]; /* first code of bitlen */
unsigned short total;
unsigned int i, l;
int j, k, m, n, avail;
unsigned short *p;
avail = nchar;
/* initialize */
for (i = 1; i <= 16; i++) {
count[i] = 0;
weight[i] = 1 << (16 - i);
}
/* count */
for (i = 0; i < nchar; i++)
count[bitlen[i]]++;
/* calculate first code */
total = 0;
for (i = 1; i <= 16; i++) {
start[i] = total;
total += weight[i] * count[i];
}
if ((total & 0xffff) != 0)
error(L"make_table()", L"Bad table (5)\n");
/* shift data for make table. */
m = 16 - tablebits;
for (i = 1; i <= tablebits; i++) {
start[i] >>= m;
weight[i] >>= m;
}
/* initialize */
j = start[tablebits + 1] >> m;
k = 1 << tablebits;
if (j != 0)
for (i = j; i < k; i++)
table[i] = 0;
/* create table and tree */
for (j = 0; j < nchar; j++) {
k = bitlen[j];
if (k == 0)
continue;
l = start[k] + weight[k];
if (k <= tablebits) {
/* code in table */
for (i = start[k]; i < l; i++)
table[i] = j;
}
else {
/* code not in table */
p = &table[(i = start[k]) >> m];
i <<= tablebits;
n = k - tablebits;
/* make tree (n length) */
while (--n >= 0) {
if (*p == 0) {
h_right[avail] = h_left[avail] = 0;
*p = avail++;
}
if (i & 0x8000)
p = &h_right[*p];
else
p = &h_left[*p];
i <<= 1;
}
*p = j;
}
start[k] = l;
}
}
/* Local Variables: */
/* mode:c */
/* tab-width:4 */
/* End: */
/* ------------------------------------------------------------------------ */
/* LHa for UNIX */
/* lharc.c -- append to archive */
/* */
/* Copyright (C) MCMLXXXIX Yooichi.Tagawa */
/* Modified Nobutaka Watazaki */
/* Thanks to H.Yoshizaki. (MS-DOS LHarc) */
/* */
/* Ver. 0.00 Original 1988.05.23 Y.Tagawa */
/* Ver. 0.01 Alpha Version (for 4.2BSD) 1989.05.28 Y.Tagawa */
/* Ver. 0.02 Alpha Version Rel.2 1989.05.29 Y.Tagawa */
/* Ver. 0.03 Release #3 Beta Version 1989.07.02 Y.Tagawa */
/* Ver. 0.03a Debug 1989.07.03 Y.Tagawa */
/* Ver. 0.03b Modified 1989.07.13 Y.Tagawa */
/* Ver. 0.03c Debug (Thanks to void@rena.dit.junet) */
/* 1989.08.09 Y.Tagawa */
/* Ver. 0.03d Modified (quiet and verbose) 1989.09.14 Y.Tagawa */
/* V1.00 Fixed 1989.09.22 Y.Tagawa */
/* V1.01 Bug Fixed 1989.12.25 Y.Tagawa */
/* */
/* DOS-Version Original LHx V C2.01 (C) H.Yohizaki */
/* */
/* V2.00 UNIX Lharc + DOS LHx -> OSK LHx 1990.11.01 Momozou */
/* V2.01 Minor Modified 1990.11.24 Momozou */
/* */
/* Ver. 0.02 LHx for UNIX 1991.11.18 M.Oki */
/* Ver. 0.03 LHa for UNIX 1991.12.17 M.Oki */
/* Ver. 0.04 LHa for UNIX beta version 1992.01.20 M.Oki */
/* Ver. 1.00 LHa for UNIX Fixed 1992.03.19 M.Oki */
/* */
/* Ver. 1.10 for Symblic Link 1993.06.25 N.Watazaki */
/* Ver. 1.11 for Symblic Link Bug Fixed 1993.08.18 N.Watazaki */
/* Ver. 1.12 for File Date Check 1993.10.28 N.Watazaki */
/* Ver. 1.13 Bug Fixed (Idicator calcurate) 1994.02.21 N.Watazaki */
/* Ver. 1.13a Bug Fixed (Sym. Link delete) 1994.03.11 N.Watazaki */
/* Ver. 1.13b Bug Fixed (Sym. Link delete) 1994.07.29 N.Watazaki */
/* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
/* Ver. 1.14b,c Bug Fixed 1996.03.07 t.okamoto */
/* Ver. 1.14d Version up 1997.01.12 t.okamoto */
/* Ver. 1.14g Bug Fixed 2000.05.06 t.okamoto */
/* Ver. 1.14i Modified 2000.10.06 t.okamoto */
/* ------------------------------------------------------------------------ */
#define TRUE 1
#define FALSE 0
#define LHA_MAIN_SRC
#include "lha.h"
/* ------------------------------------------------------------------------ */
/* PROGRAM */
/* ------------------------------------------------------------------------ */
static int cmd = CMD_UNKNOWN;
/* 1996.8.13 t.okamoto */
#if 0
char **cmd_filev;
int cmd_filec;
char *archive_name;
char expanded_archive_name[FILENAME_LENGTH];
char temporary_name[FILENAME_LENGTH];
char backup_archive_name[FILENAME_LENGTH];
#endif
/* static functions */
static void sort_files();
static void print_version();
char *extract_directory = NULL;
char **xfilev;
int xfilec = 257;
/* 1996.8.13 t.okamoto */
#if 0
char *writting_filename;
char *reading_filename;
int archive_file_mode;
int archive_file_gid;
#endif
/* ------------------------------------------------------------------------ */
static void
init_variable() /* Added N.Watazaki */
{
/* options */
quiet = FALSE;
text_mode = FALSE;
verbose = FALSE;
noexec = FALSE; /* debugging option */
force = FALSE;
prof = FALSE;
#ifndef SUPPORT_LH7
compress_method = LZHUFF5_METHOD_NUM;
#endif
#ifdef SUPPORT_LH7
compress_method = LZHUFF7_METHOD_NUM;
#endif
header_level = HEADER_LEVEL1;
quiet_mode = 0;
#ifdef EUC
euc_mode = FALSE;
#endif
/* view command flags */
verbose_listing = FALSE;
/* extract command flags */
output_to_stdout = FALSE;
/* append command flags */
new_archive = FALSE;
update_if_newer = FALSE;
delete_after_append = FALSE;
generic_format = FALSE;
remove_temporary_at_error = FALSE;
recover_archive_when_interrupt = FALSE;
remove_extracting_file_when_interrupt = FALSE;
get_filename_from_stdin = FALSE;
ignore_directory = FALSE;
verify_mode = FALSE;
noconvertcase = FALSE;
extract_directory = NULL;
xfilec = 257;
}
/* ------------------------------------------------------------------------ */
/* */
/* ------------------------------------------------------------------------ */
static int sort_by_ascii(char **a, char **b)
{
register char *p, *q;
register int c1, c2;
p = *a, q = *b;
if (generic_format) {
do {
c1 = *(unsigned char *) p++;
c2 = *(unsigned char *) q++;
if (!c1 || !c2)
break;
if (islower(c1))
c1 = toupper(c1);
if (islower(c2))
c2 = toupper(c2);
}
while (c1 == c2);
return c1 - c2;
}
else {
while (*p == *q && *p != '\0')
p++, q++;
return *(unsigned char *) p - *(unsigned char *) q;
}
}
/* ------------------------------------------------------------------------ */
char *xxrealloc(char *old, int size)
{
char *p = (char *) xrealloc(char, old, size);
if (!p)
fatal_error(L"Not enough memory");
return p;
}
/* ------------------------------------------------------------------------ */
/* STRING POOL */
/* ------------------------------------------------------------------------ */
/*
string pool :
+-------------+-------------+------+-------------+----------+
| N A M E 1 \0| N A M E 2 \0| .... | N A M E n \0| |
+-------------+-------------+------+-------------+----------+
^ ^ ^ buffer+0 buffer+used buffer+size
vector :
+---------------+---------------+------------- -----------------+
| pointer to | pointer to | pointer to ... pointer to |
| stringpool | N A M E 1 | N A M E 2 ... N A M E n |
+---------------+---------------+------------- -------------+
^ malloc base returned
*/
/* ------------------------------------------------------------------------ */
void init_sp(struct string_pool *sp)
{
sp->size = 1024 - 8; /* any ( >=0 ) */
sp->used = 0;
sp->n = 0;
sp->buffer = (char *) xmalloc(char, sp->size);
}
/* ------------------------------------------------------------------------ */
void add_sp(struct string_pool *sp, char *name, int len)
{
while (sp->used + len > sp->size) {
sp->size *= 2;
sp->buffer = (char *) xxrealloc(sp->buffer, sp->size * sizeof(char));
}
bcopy(name, sp->buffer + sp->used, len);
sp->used += len;
sp->n++;
}
/* ------------------------------------------------------------------------ */
void finish_sp(struct string_pool *sp, int *v_count, char ***v_vector)
{
int i;
register char *p;
char **v;
v = (char **) xmalloc(char*, sp->n + 1);
*v++ = sp->buffer;
*v_vector = v;
*v_count = sp->n;
p = sp->buffer;
for (i = sp->n; i; i--) {
*v++ = p;
if (i - 1)
p += strlen(p) + 1;
}
}
/* ------------------------------------------------------------------------ */
void free_sp(char **vector)
{
vector--;
free(*vector); /* free string pool */
free(vector);
}
/* ------------------------------------------------------------------------ */
/* READ DIRECTORY FILES */
/* ------------------------------------------------------------------------ */
static bool include_path_p(char *path, char *name)
{
char *n = name;
while (*path)
if (*path++ != *n++)
return (path[-1] == '/' && *n == '\0');
return (*n == '/' || (n != name && path[-1] == '/' && n[-1] == '/'));
}
/* ------------------------------------------------------------------------ */
/* LHa for UNIX */
/* shuf.c -- extract static Huffman coding */
/* */
/* Modified Nobutaka Watazaki */
/* */
/* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
/* ------------------------------------------------------------------------ */
#include "lha.h"
/* ------------------------------------------------------------------------ */
#undef NP
#undef NP2
#define NP (8 * 1024 / 64)
#define NP2 (NP * 2 - 1)
/* ------------------------------------------------------------------------ */
static unsigned int np;
static int h_fixed[2][16] = {
{3, 0x01, 0x04, 0x0c, 0x18, 0x30, 0}, /* old compatible */
{2, 0x01, 0x01, 0x03, 0x06, 0x0D, 0x1F, 0x4E, 0} /* 8K buf */
};
/* ------------------------------------------------------------------------ */
void decode_start_st0(void)
{
n_max = 286;
maxmatch = MAXMATCH;
init_getbits();
#ifdef SUPPORT_LH7
np = 1 << (MAX_DICBIT - 7);
#endif
#ifndef SUPPORT_LH7
np = 1 << (MAX_DICBIT - 6);
#endif
}
#if 0
/* ------------------------------------------------------------------------ */
void
encode_p_st0(j)
unsigned short j;
{
unsigned short i;
i = j >> 6;
putcode(pt_len[i], pt_code[i]);
putbits(6, j & 0x3f);
}
#endif
/* ------------------------------------------------------------------------ */
static void ready_made(int method)
{
int i, j;
unsigned int code, weight;
int *tbl;
tbl = h_fixed[method];
j = *tbl++;
weight = 1 << (16 - j);
code = 0;
for (i = 0; i < np; i++) {
while (*tbl == i) {
j++;
tbl++;
weight >>= 1;
}
pt_len[i] = j;
pt_code[i] = code;
code += weight;
}
}
/* ------------------------------------------------------------------------ */
#if 0
void
encode_start_fix( /*void*/ )
{
n_max = 314;
maxmatch = 60;
np = 1 << (12 - 6);
init_putbits();
start_c_dyn();
ready_made(0);
}
#endif
/* ------------------------------------------------------------------------ */
static void read_tree_c(void)
{ /* read tree from file */
int i, c;
i = 0;
while (i < N1) {
if (getbits(1))
c_len[i] = getbits(LENFIELD) + 1;
else
c_len[i] = 0;
if (++i == 3 && c_len[0] == 1 && c_len[1] == 1 && c_len[2] == 1) {
c = getbits(CBIT);
for (i = 0; i < N1; i++)
c_len[i] = 0;
for (i = 0; i < 4096; i++)
c_table[i] = c;
return;
}
}
lha_make_table(N1, c_len, 12, c_table);
}
/* ------------------------------------------------------------------------ */
static void read_tree_p(void)
{ /* read tree from file */
int i, c;
i = 0;
while (i < NP) {
pt_len[i] = getbits(LENFIELD);
if (++i == 3 && pt_len[0] == 1 && pt_len[1] == 1 && pt_len[2] == 1) {
#ifdef SUPPORT_LH7
c = getbits(MAX_DICBIT - 7);
#else
c = getbits(MAX_DICBIT - 6);
#endif
for (i = 0; i < NP; i++)
c_len[i] = 0;
for (i = 0; i < 256; i++)
c_table[i] = c;
return;
}
}
}
/* ------------------------------------------------------------------------ */
void decode_start_fix(void)
{
n_max = 314;
maxmatch = 60;
init_getbits();
np = 1 << (12 - 6);
start_c_dyn();
ready_made(0);
lha_make_table(np, pt_len, 8, pt_table);
}
/* ------------------------------------------------------------------------ */
unsigned short decode_c_st0(void)
{
int i, j;
static unsigned short blocksize = 0;
if (blocksize == 0) { /* read block head */
blocksize = getbits(BUFBITS); /* read block blocksize */
read_tree_c();
if (getbits(1)) {
read_tree_p();
}
else {
ready_made(1);
}
lha_make_table(NP, pt_len, 8, pt_table);
}
blocksize--;
j = c_table[lhabitbuf >> 4];
if (j < N1)
fillbuf(c_len[j]);
else {
fillbuf(12);
i = lhabitbuf;
do {
if ((short) i < 0)
j = h_right[j];
else
j = h_left[j];
i <<= 1;
} while (j >= N1);
fillbuf(c_len[j] - 12);
}
if (j == N1 - 1)
j += getbits(EXTRABITS);
return j;
}
/* ------------------------------------------------------------------------ */
unsigned short decode_p_st0(void)
{
int i, j;
j = pt_table[lhabitbuf >> 8];
if (j < np) {
fillbuf(pt_len[j]);
}
else {
fillbuf(8);
i = lhabitbuf;
do {
if ((short) i < 0)
j = h_right[j];
else
j = h_left[j];
i <<= 1;
} while (j >= np);
fillbuf(pt_len[j] - 8);
}
return (j << 6) + getbits(6);
}
/* Local Variables: */
/* mode:c */
/* tab-width:4 */
/* End: */
/* ------------------------------------------------------------------------ */
/* LHa for UNIX */
/* slice.c -- sliding dictionary with percolating update */
/* */
/* Modified Nobutaka Watazaki */
/* */
/* Ver. 1.14d Exchanging a search algorithm 1997.01.11 T.Okamoto */
/* ------------------------------------------------------------------------ */
#if 0
#define DEBUG 1
#endif
#include "lha.h"
#ifdef DEBUG
FILE *fout = NULL;
static int noslide = 1;
#endif
/* ------------------------------------------------------------------------ */
static unsigned long encoded_origsize;
/* ------------------------------------------------------------------------ */
static unsigned int *hash;
static unsigned int *prev;
/* static unsigned char *text; */
unsigned char *too_flag;
#if 0
static struct encode_option encode_define[2] = {
#if 1 || defined(__STDC__) || defined(AIX)
/* lh1 */
{(void (*) ()) output_dyn,
(void (*) ()) encode_start_fix,
(void (*) ()) encode_end_dyn},
/* lh4, 5,6 */
{(void (*) ()) output_st1,
(void (*) ()) encode_start_st1,
(void (*) ()) encode_end_st1}
#else
/* lh1 */
{(int (*) ()) output_dyn,
(int (*) ()) encode_start_fix,
(int (*) ()) encode_end_dyn},
/* lh4, 5,6 */
{(int (*) ()) output_st1,
(int (*) ()) encode_start_st1,
(int (*) ()) encode_end_st1}
#endif
};
#endif
static struct decode_option decode_define[] = {
/* lh1 */
{decode_c_dyn, decode_p_st0, decode_start_fix},
/* lh2 */
{decode_c_dyn, decode_p_dyn, decode_start_dyn},
/* lh3 */
{decode_c_st0, decode_p_st0, decode_start_st0},
/* lh4 */
{decode_c_st1, decode_p_st1, decode_start_st1},
/* lh5 */
{decode_c_st1, decode_p_st1, decode_start_st1},
/* lh6 */
{decode_c_st1, decode_p_st1, decode_start_st1},
/* lh7 */
{decode_c_st1, decode_p_st1, decode_start_st1},
/* lzs */
{decode_c_lzs, decode_p_lzs, decode_start_lzs},
/* lz5 */
{decode_c_lz5, decode_p_lz5, decode_start_lz5}
};
static struct encode_option encode_set;
static struct decode_option decode_set;
#if 0
static node pos, matchpos, avail, *position, *parent, *prev;
static int remainder, matchlen;
static unsigned char *level, *childcount;
static unsigned long dicsiz; /* t.okamoto */
static unsigned short max_hash_val;
static unsigned short hash1, hash2;
#endif
#ifdef SUPPORT_LH7
#define DICSIZ (1L << 16)
#define TXTSIZ (DICSIZ * 2L + MAXMATCH)
#else
#define DICSIZ (((unsigned long)1) << 15)
#define TXTSIZ (DICSIZ * 2 + MAXMATCH)
#endif
#define HSHSIZ (((unsigned long)1) <<15)
#define NIL 0
#define LIMIT 0x100 /* chain 長の limit */
static unsigned int txtsiz;
static unsigned long dicsiz;
static unsigned int hval;
static int matchlen;
static unsigned int matchpos;
static unsigned int pos;
static unsigned int remainder;
#if 0
/* ------------------------------------------------------------------------ */
int
encode_alloc(method)
int method;
{
if (method == LZHUFF1_METHOD_NUM) { /* Changed N.Watazaki */
encode_set = encode_define[0];
maxmatch = 60;
dicbit = 12; /* 12 Changed N.Watazaki */
} else { /* method LH4(12),LH5(13),LH6(15) */
encode_set = encode_define[1];
maxmatch = MAXMATCH;
if (method == LZHUFF7_METHOD_NUM)
dicbit = MAX_DICBIT; /* 16 bits */
else if (method == LZHUFF6_METHOD_NUM)
dicbit = MAX_DICBIT-1; /* 15 bits */
else /* LH5 LH4 is not used */
dicbit = MAX_DICBIT - 3; /* 13 bits */
}
dicsiz = (((unsigned long)1) << dicbit);
txtsiz = dicsiz*2+maxmatch;
if (hash) return method;
if (alloc_buf() == NULL) exit(207); /* I don't know this 207. */
hash = (unsigned int*)malloc(HSHSIZ * sizeof(unsigned int));
prev = (unsigned int*)malloc(DICSIZ * sizeof(unsigned int));
text = (unsigned char*)malloc(TXTSIZ);
too_flag = (unsigned char*)malloc(HSHSIZ);
if (hash == NULL || prev == NULL || text == NULL || too_flag == NULL)
exit(207);
return method;
}
/* ------------------------------------------------------------------------ */
/* ポインタの初期化 */
static void init_slide()
{
unsigned int i;
for (i = 0; i < HSHSIZ; i++) {
hash[i] = NIL;
too_flag[i] = 0;
}
/*
for (i = 0; i < DICSIZ; i++) {
prev[i] = NIL;
}
*/
}
/* 辞書を DICSIZ 分 前にずらす */
static void update()
{
unsigned int i, j;
unsigned int k;
long n;
#if 0
memmove(&text[0], &text[dicsiz], (unsigned)(txtsiz - dicsiz));
#else
{
int m;
i = 0; j = dicsiz; m = txtsiz-dicsiz;
while (m-- > 0) {
text[i++] = text[j++];
}
}
#endif
n = fread_crc(&text[(unsigned)(txtsiz - dicsiz)],
(unsigned)dicsiz, infile);
remainder += n;
encoded_origsize += n;
pos -= dicsiz;
for (i = 0; i < HSHSIZ; i++) {
j = hash[i];
hash[i] = (j > dicsiz) ? j - dicsiz : NIL;
too_flag[i] = 0;
}
for (i = 0; i < dicsiz; i++) {
j = prev[i];
prev[i] = (j > dicsiz) ? j - dicsiz : NIL;
}
}
/* 現在の文字列をチェーンに追加する */
static void insert()
{
prev[pos & (dicsiz - 1)] = hash[hval];
hash[hval] = pos;
}
/* 現在の文字列と最長一致する文字列を検索し、チェーンに追加する */
static void match_insert()
{
unsigned int scan_pos, scan_end, len;
unsigned char *a, *b;
unsigned int chain, off, h, max;
max = maxmatch; /* MAXMATCH; */
if (matchlen < THRESHOLD - 1) matchlen = THRESHOLD - 1;
matchpos = pos;
off = 0;
for (h = hval; too_flag[h] && off < maxmatch - THRESHOLD; ) {
h = ((h << 5) ^ text[pos + (++off) + 2]) & (unsigned)(HSHSIZ - 1);
}
if (off == maxmatch - THRESHOLD) off = 0;
for (;;) {
chain = 0;
scan_pos = hash[h];
scan_end = (pos > dicsiz) ? pos + off - dicsiz : off;
while (scan_pos > scan_end) {
chain++;
if (text[scan_pos + matchlen - off] == text[pos + matchlen]) {
{
a = text + scan_pos - off; b = text + pos;
for (len = 0; len < max && *a++ == *b++; len++);
}
if (len > matchlen) {
matchpos = scan_pos - off;
if ((matchlen = len) == max) {
break;
}
#ifdef DEBUG
if (noslide) {
if (matchpos < dicsiz) {
printf("matchpos=%u scan_pos=%u dicsiz=%u\n"
,matchpos, scan_pos, dicsiz);
}
}
#endif
}
}
scan_pos = prev[scan_pos & (dicsiz - 1)];
}
if (chain >= LIMIT)
too_flag[h] = 1;
if (matchlen > off + 2 || off == 0)
break;
max = off + 2;
off = 0;
h = hval;
}
prev[pos & (dicsiz - 1)] = hash[hval];
hash[hval] = pos;
}
/* ポインタを進め、辞書を更新し、ハッシュ値を更新する */
static void get_next()
{
remainder--;
if (++pos >= txtsiz - maxmatch) {
update();
#ifdef DEBUG
noslide = 0;
#endif
}
hval = ((hval << 5) ^ text[pos + 2]) & (unsigned)(HSHSIZ - 1);
}
void encode(lhinterface)
struct interfacing *lhinterface;
{
int lastmatchlen;
unsigned int lastmatchoffset;
#ifdef DEBUG
unsigned int addr;
addr = 0;
fout = fopen("en", "wt");
if (fout == NULL) exit(1);
#endif
infile = lhinterface->infile;
outfile = lhinterface->outfile;
origsize = lhinterface->original;
compsize = count = 0L;
crc = unpackable = 0;
/* encode_alloc(); */ /* allocate_memory(); */
init_slide();
encode_set.encode_start();
memset(&text[0], ' ', (long)TXTSIZ);
remainder = fread_crc(&text[dicsiz], txtsiz-dicsiz, infile);
encoded_origsize = remainder;
matchlen = THRESHOLD - 1;
pos = dicsiz;
if (matchlen > remainder) matchlen = remainder;
hval = ((((text[dicsiz] << 5) ^ text[dicsiz + 1]) << 5)
^ text[dicsiz + 2]) & (unsigned)(HSHSIZ - 1);
insert();
while (remainder > 0 && ! unpackable) {
lastmatchlen = matchlen; lastmatchoffset = pos - matchpos - 1;
--matchlen;
get_next(); match_insert();
if (matchlen > remainder) matchlen = remainder;
if (matchlen > lastmatchlen || lastmatchlen < THRESHOLD) {
encode_set.output(text[pos - 1], 0);
#ifdef DEBUG
fprintf(fout, "%u C %02X\n", addr, text[pos-1]);
addr++;
#endif
count++;
} else {
encode_set.output(lastmatchlen + (UCHAR_MAX + 1 - THRESHOLD),
(lastmatchoffset) & (dicsiz-1) );
--lastmatchlen;
#ifdef DEBUG
fprintf(fout, "%u M %u %u ", addr,
lastmatchoffset & (dicsiz-1), lastmatchlen+1);
addr += lastmatchlen +1 ;
{
int t,cc;
for (t=0; t<lastmatchlen+1; t++) {
cc = text[(pos-(lastmatchoffset)) & (dicsiz-1)];
fprintf(fout, "%02X ", cc);
}
fprintf(fout, "\n");
}
#endif
while (--lastmatchlen > 0) {
get_next(); insert();
count++;
}
get_next();
matchlen = THRESHOLD - 1;
match_insert();
if (matchlen > remainder) matchlen = remainder;
}
}
encode_set.encode_end();
interface->packed = compsize;
interface->original = encoded_origsize;
}
/* ------------------------------------------------------------------------ */
#endif
int decode(struct interfacing *lhinterface)
{
unsigned int i, j, k, c;
unsigned int dicsiz1, offset;
unsigned char *dtext;
#ifdef DEBUG
fout = fopen("de", "wt");
if (fout == NULL) exit(1);
#endif
infile = lhinterface->infile;
outfile = lhinterface->outfile;
dicbit = lhinterface->dicbit;
origsize = lhinterface->original;
compsize = lhinterface->packed;
decode_set = decode_define[lhinterface->method - 1];
crc = 0;
prev_char = -1;
dicsiz = 1L << dicbit;
dtext = (unsigned char *) malloc(dicsiz);
if (dtext == NULL)
return 0;
for (i=0; i<dicsiz; i++) dtext[i] = 0x20;
decode_set.decode_start();
dicsiz1 = dicsiz - 1;
offset = (lhinterface->method == LARC_METHOD_NUM) ? 0x100 - 2 : 0x100 - 3;
count = 0;
loc = 0;
while (count < origsize) {
c = decode_set.decode_c();
if (c <= UCHAR_MAX) {
#ifdef DEBUG
fprintf(fout, "%u C %02X\n", count, c);
#endif
dtext[loc++] = c;
if (loc == dicsiz) {
fwrite_crc(dtext, dicsiz, outfile);
loc = 0;
}
count++;
}
else {
j = c - offset;
i = (loc - decode_set.decode_p() - 1) & dicsiz1;
#ifdef DEBUG
fprintf(fout, "%u M %u %u ", count, (loc-1-i) & dicsiz1, j);
#endif
count += j;
for (k = 0; k < j; k++) {
c = dtext[(i + k) & dicsiz1];
#ifdef DEBUG
fprintf(fout, "%02X ", c & 0xff);
#endif
dtext[loc++] = c;
if (loc == dicsiz) {
fwrite_crc(dtext, dicsiz, outfile);
loc = 0;
}
}
#ifdef DEBUG
fprintf(fout, "\n");
#endif
}
}
if (loc != 0) {
fwrite_crc(dtext, loc, outfile);
}
free(dtext);
return 1;
}
/* Local Variables: */
/* mode:c */
/* tab-width:4 */
/* End: */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "sysconfig.h"
#include "sysdeps.h"
#include "lha.h"
#include "zarchive.h"
static char *methods[] =
{
LZHUFF0_METHOD, LZHUFF1_METHOD, LZHUFF2_METHOD, LZHUFF3_METHOD,
LZHUFF4_METHOD, LZHUFF5_METHOD, LZHUFF6_METHOD, LZHUFF7_METHOD,
LARC_METHOD, LARC5_METHOD, LARC4_METHOD,
LZHDIRS_METHOD,
NULL
};
struct zvolume *archive_directory_lha (struct zfile *zf)
{
struct zvolume *zv;
struct zarchive_info zai;
LzHeader hdr;
int i;
_tzset();
zv = zvolume_alloc (zf, ArchiveFormatLHA, NULL, NULL);
while (get_header(zf, &hdr)) {
struct znode *zn;
int method;
for (i = 0; methods[i]; i++) {
if (!strcmp (methods[i], hdr.method))
method = i;
}
memset (&zai, 0, sizeof zai);
zai.name = au (hdr.name);
zai.size = hdr.original_size;
zai.flags = hdr.attribute;
zai.t = hdr.unix_last_modified_stamp -= timezone;
if (hdr.name[strlen(hdr.name) + 1] != 0)
zai.comment = au (&hdr.name[strlen(hdr.name) + 1]);
if (method == LZHDIRS_METHOD_NUM) {
zvolume_adddir_abs (zv, &zai);
} else {
zn = zvolume_addfile_abs (zv, &zai);
zn->offset = zfile_ftell(zf);
zn->packedsize = hdr.packed_size;
zn->method = method;
}
xfree (zai.name);
xfree (zai.comment);
zfile_fseek (zf, hdr.packed_size, SEEK_CUR);
}
return zv;
}
struct zfile *archive_access_lha (struct znode *zn)
{
struct zfile *zf = zn->volume->archive;
struct zfile *out = zfile_fopen_empty (zf, zn->name, zn->size);
struct interfacing lhinterface;
zfile_fseek(zf, zn->offset, SEEK_SET);
lhinterface.method = zn->method;
lhinterface.dicbit = 13; /* method + 8; -lh5- */
lhinterface.infile = zf;
lhinterface.outfile = out;
lhinterface.original = zn->size;
lhinterface.packed = zn->packedsize;
switch (zn->method) {
case LZHUFF0_METHOD_NUM:
case LARC4_METHOD_NUM:
zfile_fread(out->data, zn->size, 1, zf);
break;
case LARC_METHOD_NUM: /* -lzs- */
lhinterface.dicbit = 11;
decode(&lhinterface);
break;
case LZHUFF1_METHOD_NUM: /* -lh1- */
case LZHUFF4_METHOD_NUM: /* -lh4- */
case LARC5_METHOD_NUM: /* -lz5- */
lhinterface.dicbit = 12;
decode(&lhinterface);
break;
case LZHUFF6_METHOD_NUM: /* -lh6- */ /* Added N.Watazaki (^_^) */
case LZHUFF7_METHOD_NUM: /* -lh7- */
lhinterface.dicbit = (zn->method - LZHUFF6_METHOD_NUM) + 15;
default:
decode(&lhinterface);
}
return out;
}
/* ------------------------------------------------------------------------ */
/* LHa for UNIX */
/* util.c -- LHarc Util */
/* */
/* Modified Nobutaka Watazaki */
/* */
/* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
/* Ver. 1.14e Support for sfx archives 1999.05.28 T.Okamoto */
/* ------------------------------------------------------------------------ */
#include "lha.h"
/*
* util.c - part of LHa for UNIX Feb 26 1992 modified by Masaru Oki Mar 4
* 1992 modified by Masaru Oki #ifndef USESTRCASECMP added. Mar 31 1992
* modified by Masaru Oki #ifdef NOMEMSET added.
*/
/* ------------------------------------------------------------------------ */
extern unsigned short crc;
/* ------------------------------------------------------------------------ */
/* convert path delimit
erreturns *filename */
/* ------------------------------------------------------------------------ */
unsigned char *convdelim(unsigned char *path, unsigned char delim)
{
unsigned char c;
unsigned char *p;
#ifdef MULTIBYTE_CHAR
int kflg;
kflg = 0;
#endif
for (p = path; (c = *p) != 0; p++) {
#ifdef MULTIBYTE_CHAR
if (kflg) {
kflg = 0;
}
else if (MULTIBYTE_FIRST_P(c)) {
kflg = 1;
}
else
#endif
if (c == '\\' || c == DELIM || c == DELIM2) {
*p = delim;
path = p + 1;
}
}
return path;
}
/*
* strdup(3)
*/
/* ------------------------------------------------------------------------ */
#ifdef NOSTRDUP
char *
strdup(buf)
char *buf;
{
char *p;
if ((p = (char *) malloc(strlen(buf) + 1)) == NULL)
return NULL;
strcpy(p, buf);
return p;
}
#endif
/*
* memmove( char *dst , char *src , size_t cnt )
*/
/* ------------------------------------------------------------------------ */
#if 0 && defined(NOBSTRING) && !defined(__STDC__)
void *
memmove(dst, src, cnt)
register char *dst, *src;
register int cnt;
{
if (dst == src)
return dst;
if (src > dst) {
while (--cnt >= 0)
*dst++ = *src++;
}
else {
dst += cnt;
src += cnt;
while (--cnt >= 0)
*--dst = *--src;
}
return dst;
}
#endif
/*
* rename - change the name of file 91.11.02 by Tomohiro Ishikawa
* (ishikawa@gaia.cow.melco.CO.JP) 92.01.20 little modified (added #ifdef) by
* Masaru Oki 92.01.28 added mkdir() and rmdir() by Tomohiro Ishikawa
*/
#if defined(NOFTRUNCATE) && !defined(_MINIX)
/* ------------------------------------------------------------------------ */
int
rename(from, to)
char *from, *to;
{
struct stat s1, s2;
extern int errno;
if (stat(from, &s1) < 0)
return (-1);
/* is 'FROM' file a directory? */
if ((s1.st_mode & S_IFMT) == S_IFDIR) {
errno = ENOTDIR;
return (-1);
}
if (stat(to, &s2) >= 0) { /* 'TO' exists! */
/* is 'TO' file a directory? */
if ((s2.st_mode & S_IFMT) == S_IFDIR) {
errno = EISDIR;
return (-1);
}
if (unlink(to) < 0)
return (-1);
}
if (link(from, to) < 0)
return (-1);
if (unlink(from) < 0)
return (-1);
return (0);
}
#endif /* NOFTRUNCATE */
/* ------------------------------------------------------------------------ */
#ifdef NOMKDIR
#ifndef MKDIRPATH
#define MKDIRPATH "/bin/mkdir"
#endif
#ifndef RMDIRPATH
#define RMDIRPATH "/bin/rmdir"
#endif
int
rmdir(path)
char *path;
{
int stat, rtn = 0;
char *cmdname;
if ((cmdname = (char *) malloc(strlen(RMDIRPATH) + 1 + strlen(path) + 1))
== 0)
return (-1);
strcpy(cmdname, RMDIRPATH);
*(cmdname + strlen(RMDIRPATH)) = ' ';
strcpy(cmdname + strlen(RMDIRPATH) + 1, path);
if ((stat = system(cmdname)) < 0)
rtn = -1; /* fork or exec error */
else if (stat) { /* RMDIR command error */
errno = EIO;
rtn = -1;
}
free(cmdname);
return (rtn);
}
/* ------------------------------------------------------------------------ */
int
mkdir(path, mode)
char *path;
int mode;
{
int child, stat;
char *cmdname, *cmdpath = MKDIRPATH;
if ((cmdname = (char *) strrchr(cmdpath, '/')) == (char *) 0)
cmdname = cmdpath;
if ((child = fork()) < 0)
return (-1); /* fork error */
else if (child) { /* parent process */
while (child != wait(&stat)) /* ignore signals */
continue;
}
else { /* child process */
int maskvalue;
maskvalue = umask(0); /* get current umask() value */
umask(maskvalue | (0777 & ~mode)); /* set it! */
execl(cmdpath, cmdname, path, (char *) 0);
/* never come here except execl is error */
return (-1);
}
if (stat != 0) {
errno = EIO; /* cannot get error num. */
return (-1);
}
return (0);
}
#endif
/*
* strucmp modified: Oct 29 1991 by Masaru Oki
*/
#ifndef USESTRCASECMP
static int my_toupper(int n)
{
if (n >= 'a' && n <= 'z')
return n & (~('a' - 'A'));
return n;
}
/* ------------------------------------------------------------------------ */
int strucmp(char *s, char *t)
{
while (my_toupper(*s++) == my_toupper(*t++))
if (!*s || !*t)
break;
if (!*s && !*t)
return 0;
return 1;
}
#endif
/* ------------------------------------------------------------------------ */
#ifdef NOMEMSET
/* Public Domain memset(3) */
char *
memset(s, c, n)
char *s;
int c, n;
{
char *p = s;
while (n--)
*p++ = (char) c;
return s;
}
#endif
/* Local Variables: */
/* mode:c */
/* tab-width:4 */
/* compile-command:"gcc -c util.c" */
/* End: */
/* $VER: unlzx.c 1.0 (22.2.98) */
/* Created: 11.2.98 */
/* Added Pipe support to read from stdin (03.4.01, Erik Meusel) */
/* LZX Extract in (supposedly) portable C. */
/* ********************* WINDOWS PORTING NOTES STARTS *********************/
/* Ported to Windows Platform by Stefano Coletta on 22.5.02 */
/* creator@mindcreations.com or visit http://creator.mindcreations.com */
/* Changes to original code include: */
/* - Using #include <direct.h> to substitute the mkdir() function call */
/* - Added #include "getopt.h" to support getopt() function */
/* Compile with: */
/* Microsoft Visual Studio 6.0 SP5 using supplied project file */
/* ********************** WINDOWS PORTING NOTES END ***********************/
/* Thanks to Dan Fraser for decoding the coredumps and helping me track */
/* down some HIDEOUSLY ANNOYING bugs. */
/* Everything is accessed as unsigned char's to try and avoid problems */
/* with byte order and alignment. Most of the decrunch functions */
/* encourage overruns in the buffers to make things as fast as possible. */
/* All the time is taken up in crc_calc() and decrunch() so they are */
/* pretty damn optimized. Don't try to understand this program. */
/* ---------------------------------------------------------------------- */
/* - minimal UAE specific version 13-14.06.2007 by Toni Wilen */
#include <stdlib.h>
#include <stdio.h>
#include "sysconfig.h"
#include "sysdeps.h"
#include "zfile.h"
#include "zarchive.h"
/* ---------------------------------------------------------------------- */
static unsigned char *source;
static unsigned char *destination;
static unsigned char *source_end;
static unsigned char *destination_end;
static unsigned int decrunch_method;
static unsigned int decrunch_length;
static unsigned int last_offset;
static unsigned int global_control;
static int global_shift;
static unsigned char offset_len[8];
static unsigned short offset_table[128];
static unsigned char huffman20_len[20];
static unsigned short huffman20_table[96];
static unsigned char literal_len[768];
static unsigned short literal_table[5120];
/* ---------------------------------------------------------------------- */
static unsigned int sum;
static const unsigned int crc_table[256]=
{
0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,
0xE963A535,0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,
0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91,0x1DB71064,0x6AB020F2,
0xF3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7,
0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9,
0xFA0F3D63,0x8D080DF5,0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172,
0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C,
0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59,
0x26D930AC,0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,
0xCFBA9599,0xB8BDA50F,0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,
0x2F6F7C87,0x58684C11,0xC1611DAB,0xB6662D3D,0x76DC4190,0x01DB7106,
0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,0x9FBFE4A5,0xE8B8D433,
0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,0x086D3D2D,
0x91646C97,0xE6635C01,0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,
0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,0x65B0D9C6,0x12B7E950,
0x8BBEB8EA,0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65,
0x4DB26158,0x3AB551CE,0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,
0xA4D1C46D,0xD3D6F4FB,0x4369E96A,0x346ED9FC,0xAD678846,0xDA60B8D0,
0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9,0x5005713C,0x270241AA,
0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,0xCE61E49F,
0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,
0xB7BD5C3B,0xC0BA6CAD,0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,
0xEAD54739,0x9DD277AF,0x04DB2615,0x73DC1683,0xE3630B12,0x94643B84,
0x0D6D6A3E,0x7A6A5AA8,0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1,
0xF00F9344,0x8708A3D2,0x1E01F268,0x6906C2FE,0xF762575D,0x806567CB,
0x196C3671,0x6E6B06E7,0xFED41B76,0x89D32BE0,0x10DA7A5A,0x67DD4ACC,
0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,0xD6D6A3E8,0xA1D1937E,
0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B,
0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,
0x316E8EEF,0x4669BE79,0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,
0xCC0C7795,0xBB0B4703,0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28,
0x2BB45A92,0x5CB36A04,0xC2D7FFA7,0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D,
0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,0x9C0906A9,0xEB0E363F,
0x72076785,0x05005713,0x95BF4A82,0xE2B87A14,0x7BB12BAE,0x0CB61B38,
0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21,0x86D3D2D4,0xF1D4E242,
0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777,
0x88085AE6,0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,
0x616BFFD3,0x166CCF45,0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,
0xA7672661,0xD06016F7,0x4969474D,0x3E6E77DB,0xAED16A4A,0xD9D65ADC,
0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,0x47B2CF7F,0x30B5FFE9,
0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,0xCDD70693,
0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,
0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D
};
/* ---------------------------------------------------------------------- */
static const unsigned char table_one[32]=
{
0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14
};
static const unsigned int table_two[32]=
{
0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,
1536,2048,3072,4096,6144,8192,12288,16384,24576,32768,49152
};
static const unsigned int table_three[16]=
{
0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767
};
static const unsigned char table_four[34]=
{
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
};
/* ---------------------------------------------------------------------- */
/* Possible problems with 64 bit machines here. It kept giving warnings */
/* for people so I changed back to ~. */
static void crc_calc(unsigned char *memory, unsigned int length)
{
register unsigned int temp;
if(length)
{
temp = ~sum; /* was (sum ^ 4294967295) */
do
{
temp = crc_table[(*memory++ ^ temp) & 255] ^ (temp >> 8);
} while(--length);
sum = ~temp; /* was (temp ^ 4294967295) */
}
}
/* ---------------------------------------------------------------------- */
/* Build a fast huffman decode table from the symbol bit lengths. */
/* There is an alternate algorithm which is faster but also more complex. */
static int make_decode_table(int number_symbols, int table_size,
unsigned char *length, unsigned short *table)
{
register unsigned char bit_num = 0;
register int symbol;
unsigned int leaf; /* could be a register */
unsigned int table_mask, bit_mask, pos, fill, next_symbol, reverse;
int abort = 0;
pos = 0; /* consistantly used as the current position in the decode table */
bit_mask = table_mask = 1 << table_size;
bit_mask >>= 1; /* don't do the first number */
bit_num++;
while((!abort) && (bit_num <= table_size))
{
for(symbol = 0; symbol < number_symbols; symbol++)
{
if(length[symbol] == bit_num)
{
reverse = pos; /* reverse the order of the position's bits */
leaf = 0;
fill = table_size;
do /* reverse the position */
{
leaf = (leaf << 1) + (reverse & 1);
reverse >>= 1;
} while(--fill);
if((pos += bit_mask) > table_mask)
{
abort = 1;
break; /* we will overrun the table! abort! */
}
fill = bit_mask;
next_symbol = 1 << bit_num;
do
{
table[leaf] = symbol;
leaf += next_symbol;
} while(--fill);
}
}
bit_mask >>= 1;
bit_num++;
}
if((!abort) && (pos != table_mask))
{
for(symbol = pos; symbol < table_mask; symbol++) /* clear the rest of the table */
{
reverse = symbol; /* reverse the order of the position's bits */
leaf = 0;
fill = table_size;
do /* reverse the position */
{
leaf = (leaf << 1) + (reverse & 1);
reverse >>= 1;
} while(--fill);
table[leaf] = 0;
}
next_symbol = table_mask >> 1;
pos <<= 16;
table_mask <<= 16;
bit_mask = 32768;
while((!abort) && (bit_num <= 16))
{
for(symbol = 0; symbol < number_symbols; symbol++)
{
if(length[symbol] == bit_num)
{
reverse = pos >> 16; /* reverse the order of the position's bits */
leaf = 0;
fill = table_size;
do /* reverse the position */
{
leaf = (leaf << 1) + (reverse & 1);
reverse >>= 1;
} while(--fill);
for(fill = 0; fill < bit_num - table_size; fill++)
{
if(table[leaf] == 0)
{
table[(next_symbol << 1)] = 0;
table[(next_symbol << 1) + 1] = 0;
table[leaf] = next_symbol++;
}
leaf = table[leaf] << 1;
leaf += (pos >> (15 - fill)) & 1;
}
table[leaf] = symbol;
if((pos += bit_mask) > table_mask)
{
abort = 1;
break; /* we will overrun the table! abort! */
}
}
}
bit_mask >>= 1;
bit_num++;
}
}
if(pos != table_mask) abort = 1; /* the table is incomplete! */
return(abort);
}
/* ---------------------------------------------------------------------- */
/* Read and build the decrunch tables. There better be enough data in the */
/* source buffer or it's stuffed. */
static int read_literal_table()
{
register unsigned int control;
register int shift;
unsigned int temp; /* could be a register */
unsigned int symbol, pos, count, fix, max_symbol;
int abort = 0;
control = global_control;
shift = global_shift;
if(shift < 0) /* fix the control word if necessary */
{
shift += 16;
control += *source++ << (8 + shift);
control += *source++ << shift;
}
/* read the decrunch method */
decrunch_method = control & 7;
control >>= 3;
if((shift -= 3) < 0)
{
shift += 16;
control += *source++ << (8 + shift);
control += *source++ << shift;
}
/* Read and build the offset huffman table */
if((!abort) && (decrunch_method == 3))
{
for(temp = 0; temp < 8; temp++)
{
offset_len[temp] = control & 7;
control >>= 3;
if((shift -= 3) < 0)
{
shift += 16;
control += *source++ << (8 + shift);
control += *source++ << shift;
}
}
abort = make_decode_table(8, 7, offset_len, offset_table);
}
/* read decrunch length */
if(!abort)
{
decrunch_length = (control & 255) << 16;
control >>= 8;
if((shift -= 8) < 0)
{
shift += 16;
control += *source++ << (8 + shift);
control += *source++ << shift;
}
decrunch_length += (control & 255) << 8;
control >>= 8;
if((shift -= 8) < 0)
{
shift += 16;
control += *source++ << (8 + shift);
control += *source++ << shift;
}
decrunch_length += (control & 255);
control >>= 8;
if((shift -= 8) < 0)
{
shift += 16;
control += *source++ << (8 + shift);
control += *source++ << shift;
}
}
/* read and build the huffman literal table */
if((!abort) && (decrunch_method != 1))
{
pos = 0;
fix = 1;
max_symbol = 256;
do
{
for(temp = 0; temp < 20; temp++)
{
huffman20_len[temp] = control & 15;
control >>= 4;
if((shift -= 4) < 0)
{
shift += 16;
control += *source++ << (8 + shift);
control += *source++ << shift;
}
}
abort = make_decode_table(20, 6, huffman20_len, huffman20_table);
if(abort) break; /* argh! table is corrupt! */
do
{
if((symbol = huffman20_table[control & 63]) >= 20)
{
do /* symbol is longer than 6 bits */
{
symbol = huffman20_table[((control >> 6) & 1) + (symbol << 1)];
if(!shift--)
{
shift += 16;
control += *source++ << 24;
control += *source++ << 16;
}
control >>= 1;
} while(symbol >= 20);
temp = 6;
}
else
{
temp = huffman20_len[symbol];
}
control >>= temp;
if((shift -= temp) < 0)
{
shift += 16;
control += *source++ << (8 + shift);
control += *source++ << shift;
}
switch(symbol)
{
case 17:
case 18:
{
if(symbol == 17)
{
temp = 4;
count = 3;
}
else /* symbol == 18 */
{
temp = 6 - fix;
count = 19;
}
count += (control & table_three[temp]) + fix;
control >>= temp;
if((shift -= temp) < 0)
{
shift += 16;
control += *source++ << (8 + shift);
control += *source++ << shift;
}
while((pos < max_symbol) && (count--))
literal_len[pos++] = 0;
break;
}
case 19:
{
count = (control & 1) + 3 + fix;
if(!shift--)
{
shift += 16;
control += *source++ << 24;
control += *source++ << 16;
}
control >>= 1;
if((symbol = huffman20_table[control & 63]) >= 20)
{
do /* symbol is longer than 6 bits */
{
symbol = huffman20_table[((control >> 6) & 1) + (symbol << 1)];
if(!shift--)
{
shift += 16;
control += *source++ << 24;
control += *source++ << 16;
}
control >>= 1;
} while(symbol >= 20);
temp = 6;
}
else
{
temp = huffman20_len[symbol];
}
control >>= temp;
if((shift -= temp) < 0)
{
shift += 16;
control += *source++ << (8 + shift);
control += *source++ << shift;
}
symbol = table_four[literal_len[pos] + 17 - symbol];
while((pos < max_symbol) && (count--))
literal_len[pos++] = symbol;
break;
}
default:
{
symbol = table_four[literal_len[pos] + 17 - symbol];
literal_len[pos++] = symbol;
break;
}
}
} while(pos < max_symbol);
fix--;
max_symbol += 512;
} while(max_symbol == 768);
if(!abort)
abort = make_decode_table(768, 12, literal_len, literal_table);
}
global_control = control;
global_shift = shift;
return(abort);
}
/* ---------------------------------------------------------------------- */
/* Fill up the decrunch buffer. Needs lots of overrun for both destination */
/* and source buffers. Most of the time is spent in this routine so it's */
/* pretty damn optimized. */
static void decrunch(void)
{
register unsigned int control;
register int shift;
unsigned int temp; /* could be a register */
unsigned int symbol, count;
unsigned char *string;
control = global_control;
shift = global_shift;
do
{
if((symbol = literal_table[control & 4095]) >= 768)
{
control >>= 12;
if((shift -= 12) < 0)
{
shift += 16;
control += *source++ << (8 + shift);
control += *source++ << shift;
}
do /* literal is longer than 12 bits */
{
symbol = literal_table[(control & 1) + (symbol << 1)];
if(!shift--)
{
shift += 16;
control += *source++ << 24;
control += *source++ << 16;
}
control >>= 1;
} while(symbol >= 768);
}
else
{
temp = literal_len[symbol];
control >>= temp;
if((shift -= temp) < 0)
{
shift += 16;
control += *source++ << (8 + shift);
control += *source++ << shift;
}
}
if(symbol < 256)
{
*destination++ = symbol;
}
else
{
symbol -= 256;
count = table_two[temp = symbol & 31];
temp = table_one[temp];
if((temp >= 3) && (decrunch_method == 3))
{
temp -= 3;
count += ((control & table_three[temp]) << 3);
control >>= temp;
if((shift -= temp) < 0)
{
shift += 16;
control += *source++ << (8 + shift);
control += *source++ << shift;
}
count += (temp = offset_table[control & 127]);
temp = offset_len[temp];
}
else
{
count += control & table_three[temp];
if(!count) count = last_offset;
}
control >>= temp;
if((shift -= temp) < 0)
{
shift += 16;
control += *source++ << (8 + shift);
control += *source++ << shift;
}
last_offset = count;
count = table_two[temp = (symbol >> 5) & 15] + 3;
temp = table_one[temp];
count += (control & table_three[temp]);
control >>= temp;
if((shift -= temp) < 0)
{
shift += 16;
control += *source++ << (8 + shift);
control += *source++ << shift;
}
string = destination - last_offset;
do
{
*destination++ = *string++;
} while(--count);
}
} while((destination < destination_end) && (source < source_end));
global_control = control;
global_shift = shift;
}
struct zfile *archive_access_lzx (struct znode *zn)
{
unsigned int startpos;
struct znode *znfirst, *znlast;
struct zfile *zf = zn->volume->archive;
struct zfile *dstf, *newzf;
uae_u8 *buf, *dbuf;
unsigned int compsize, unpsize;
dstf = NULL;
buf = dbuf = NULL;
newzf = NULL;
/* find first file in compressed block */
unpsize = 0;
znfirst = zn;
while (znfirst->prev) {
struct znode *zt = znfirst->prev;
if (!zt || zt->offset != 0)
break;
znfirst = zt;
unpsize += znfirst->size;
}
/* find last file in compressed block */
znlast = zn;
while (znlast) {
unpsize += znlast->size;
if (znlast->offset != 0)
break;
znlast = znlast->next;
}
if (!znlast)
return NULL;
/* start offset to compressed block */
startpos = znlast->offset;
compsize = znlast->packedsize;
zfile_fseek (zf, startpos, SEEK_SET);
buf = xmalloc (uae_u8, compsize);
zfile_fread (buf, compsize, 1, zf);
dbuf = xcalloc (uae_u8, unpsize);
/* unpack complete block */
memset(offset_len, 0, sizeof offset_len);
memset(literal_len, 0, sizeof literal_len);
sum = 0;
source = buf;
source_end = buf + compsize;
global_control = 0;
global_shift = -16;
last_offset = 1;
destination = dbuf;
if (compsize == unpsize) {
memcpy (dbuf, buf, unpsize);
} else {
while (unpsize > 0) {
uae_u8 *pdest = destination;
if (!read_literal_table()) {
destination_end = destination + decrunch_length;
decrunch();
unpsize -= decrunch_length;
crc_calc (pdest, decrunch_length);
} else {
write_log (L"LZX corrupt compressed data %s\n", zn->name);
goto end;
}
}
}
/* pre-cache all files we just decompressed */
for (;;) {
if (znfirst->size && !znfirst->f) {
dstf = zfile_fopen_empty (zf, znfirst->name, znfirst->size);
zfile_fwrite(dbuf + znfirst->offset2, znfirst->size, 1, dstf);
znfirst->f = dstf;
if (znfirst == zn)
newzf = zfile_dup (dstf);
}
if (znfirst == znlast)
break;
znfirst = znfirst->next;
}
end:
xfree(buf);
xfree(dbuf);
return newzf;
}
struct zvolume *archive_directory_lzx (struct zfile *in_file)
{
unsigned int temp;
unsigned int total_pack = 0;
unsigned int total_unpack = 0;
unsigned int total_files = 0;
unsigned int merge_size = 0;
int actual;
int abort;
int result = 1; /* assume an error */
struct zvolume *zv;
struct znode *zn;
struct zarchive_info zai;
struct tm tm;
unsigned int crc;
unsigned int pack_size;
unsigned int unpack_size;
unsigned char archive_header[31];
char header_filename[256];
char header_comment[256];
if (zfile_fread(archive_header, 1, 10, in_file) != 10)
return 0;
if (memcmp(archive_header, "LZX", 3))
return 0;
zv = zvolume_alloc (in_file, ArchiveFormatLZX, NULL, NULL);
do
{
abort = 1; /* assume an error */
actual = zfile_fread(archive_header, 1, 31, in_file);
if(!zfile_ferror(in_file))
{
if(actual) /* 0 is normal and means EOF */
{
if(actual == 31)
{
sum = 0; /* reset CRC */
crc = (archive_header[29] << 24) + (archive_header[28] << 16) + (archive_header[27] << 8) + archive_header[26];
archive_header[29] = 0; /* Must set the field to 0 before calculating the crc */
archive_header[28] = 0;
archive_header[27] = 0;
archive_header[26] = 0;
crc_calc(archive_header, 31);
temp = archive_header[30]; /* filename length */
actual = zfile_fread(header_filename, 1, temp, in_file);
if(!zfile_ferror(in_file))
{
if(actual == temp)
{
header_filename[temp] = 0;
crc_calc((unsigned char*)header_filename, temp);
temp = archive_header[14]; /* comment length */
actual = zfile_fread(header_comment, 1, temp, in_file);
if(!zfile_ferror(in_file))
{
if(actual == temp)
{
header_comment[temp] = 0;
crc_calc((unsigned char*)header_comment, temp);
if(sum == crc)
{
unsigned int year, month, day;
unsigned int hour, minute, second;
unsigned char attributes;
attributes = archive_header[0]; /* file protection modes */
unpack_size = (archive_header[5] << 24) + (archive_header[4] << 16) + (archive_header[3] << 8) + archive_header[2]; /* unpack size */
pack_size = (archive_header[9] << 24) + (archive_header[8] << 16) + (archive_header[7] << 8) + archive_header[6]; /* packed size */
temp = (archive_header[18] << 24) + (archive_header[19] << 16) + (archive_header[20] << 8) + archive_header[21]; /* date */
year = ((temp >> 17) & 63) + 1970;
month = (temp >> 23) & 15;
day = (temp >> 27) & 31;
hour = (temp >> 12) & 31;
minute = (temp >> 6) & 63;
second = temp & 63;
memset(&zai, 0, sizeof zai);
zai.name = au (header_filename);
if (header_comment[0])
zai.comment = au (header_comment);
zai.flags |= (attributes & 32) ? 0x80 : 0;
zai.flags |= (attributes & 64) ? 0x40 : 0;
zai.flags |= (attributes & 128) ? 0x20 : 0;
zai.flags |= (attributes & 16) ? 0x10 : 0;
zai.flags |= (attributes & 1) ? 0x08 : 0;
zai.flags |= (attributes & 2) ? 0x04 : 0;
zai.flags |= (attributes & 8) ? 0x02 : 0;
zai.flags |= (attributes & 4) ? 0x01 : 0;
zai.flags ^= 15;
memset(&tm, 0, sizeof tm);
tm.tm_hour = hour;
tm.tm_min = minute;
tm.tm_sec = second;
tm.tm_year = year - 1900;
tm.tm_mon = month;
tm.tm_mday = day;
zai.t = mktime(&tm);
zai.size = unpack_size;
zn = zvolume_addfile_abs(zv, &zai);
zn->offset2 = merge_size;
xfree (zai.name);
xfree (zai.comment);
total_pack += pack_size;
total_unpack += unpack_size;
total_files++;
merge_size += unpack_size;
if(pack_size) /* seek past the packed data */
{
merge_size = 0;
zn->offset = zfile_ftell(in_file);
zn->packedsize = pack_size;
if(!zfile_fseek(in_file, pack_size, SEEK_CUR))
{
abort = 0; /* continue */
}
}
else
abort = 0; /* continue */
//write_log (L"unp=%6d mrg=%6d pack=%6d off=%6d %s\n", unpack_size, merge_size, pack_size, zn->offset, zai.name);
}
}
}
}
}
}
}
else
{
result = 0; /* normal termination */
}
}
} while(!abort);
return zv;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "sysconfig.h"
#include "sysdeps.h"
#include "zfile.h"
#include "crc32.h"
/* based on http://libxad.cvs.sourceforge.net/libxad/libxad/portable/clients/ by Dirk Stoecker */
#define XADERR_ILLEGALDATA 1
#define XADERR_DECRUNCH 2
#define XADERR_NOMEMORY 3
struct rledata {
uae_u32 rledatav;
};
struct fout {
struct zfile *zf;
int xio_BitNum;
int xio_BitBuf;
int err;
};
static void putrle (uae_u8 data, struct zfile *out, struct rledata *rled)
{
int num;
uae_u32 a;
if (!rled) {
zfile_putc (data, out);
return;
}
a = rled->rledatav;
if (a & 0x100) /* was RLE mode */
{
if (!data || (data == 1 && (a & 0x80000000))) {
a = 0x90; num = 1;
} else {
a &= 0xFF; num = data - 1;
}
} else if (data == 0x90) {
num = 0; a |= 0x100;
} else {
num = 1; a = data;
}
rled->rledatav = a;
while (num--)
zfile_putc (a, out);
}
static uae_u32 xadIOGetBitsLow(struct fout *io, uae_u8 bits)
{
uae_u32 x;
io->err = 0;
while(io->xio_BitNum < bits)
{
int v = zfile_getc (io->zf);
if (v == -1) {
io->err = 1;
return 0;
}
io->xio_BitBuf |= v << io->xio_BitNum;
io->xio_BitNum += 8;
}
x = io->xio_BitBuf & ((1<<bits)-1);
io->xio_BitBuf >>= bits;
io->xio_BitNum -= bits;
return x;
}
#define ARCSQSPEOF 256 /* special endfile token */
#define ARCSQNUMVALS 257 /* 256 data values plus SPEOF */
static uae_s32 ARCunsqueeze(struct zfile *in, struct zfile *out, struct rledata *rled)
{
uae_s32 err = 0;
uae_s32 i, numnodes;
uae_s16 *node;
struct fout io;
io.zf = in;
io.xio_BitBuf = 0;
io.xio_BitNum = 0;
io.err = 0;
if((node = (uae_s16 *) xcalloc(uae_s16, 2*ARCSQNUMVALS)))
{
numnodes = xadIOGetBitsLow(&io, 16);
if(numnodes < 0 || numnodes >= ARCSQNUMVALS)
err = XADERR_DECRUNCH;
else
{ /* initialize for possible empty tree (SPEOF only) */
node[0] = node[1] = -(ARCSQSPEOF + 1);
numnodes *= 2; i = 0;
while(i < numnodes && !io.err) /* get decoding tree from file */
{
node[i++] = xadIOGetBitsLow(&io, 16);
node[i++] = xadIOGetBitsLow(&io, 16);
}
do
{
/* follow bit stream in tree to a leaf */
i = 0;
while(i >= 0 && !io.err)
i = node[2*i + xadIOGetBitsLow(&io, 1)];
i = -(i + 1); /* decode fake node index to original data value */
if(i != ARCSQSPEOF)
putrle (i, out, rled);
} while(i != ARCSQSPEOF);
}
xfree(node);
}
else
err = XADERR_NOMEMORY;
return err;
}
#define UCOMPMAXCODE(n) (((uae_u32) 1 << (n)) - 1)
#define UCOMPBITS 16
#define UCOMPSTACKSIZE 8000
#define UCOMPFIRST 257 /* first free entry */
#define UCOMPCLEAR 256 /* table clear output code */
#define UCOMPINIT_BITS 9 /* initial number of bits/code */
#define UCOMPBIT_MASK 0x1f
#define UCOMPBLOCK_MASK 0x80
struct UCompData {
uae_s16 clear_flg;
uae_u16 n_bits; /* number of bits/code */
uae_u16 maxbits; /* user settable max # bits/code */
uae_u32 maxcode; /* maximum code, given n_bits */
uae_u32 maxmaxcode;
uae_s32 free_ent;
uae_s32 offset;
uae_s32 size;
uae_u16 *tab_prefixof;
uae_u8 *tab_suffixof;
uae_u8 stack[UCOMPSTACKSIZE];
uae_u8 buf[UCOMPBITS];
int insize;
struct rledata *rled;
};
/* Read one code from input. If EOF, return -1. */
static uae_s32 UCompgetcode(struct zfile *in, struct UCompData *cd)
{
uae_s32 code, r_off, bits;
uae_u8 *bp = cd->buf;
if(cd->clear_flg > 0 || cd->offset >= cd->size || cd->free_ent > cd->maxcode)
{
/*
* If the next entry will be too big for the current code
* size, then we must increase the size. This implies reading
* a new buffer full, too.
*/
if(cd->free_ent > cd->maxcode)
{
if(++cd->n_bits == cd->maxbits)
cd->maxcode = cd->maxmaxcode; /* won't get any bigger now */
else
cd->maxcode = UCOMPMAXCODE(cd->n_bits);
}
if(cd->clear_flg > 0)
{
cd->maxcode = UCOMPMAXCODE(cd->n_bits = UCOMPINIT_BITS);
cd->clear_flg = 0;
}
/* This reads maximum n_bits characters into buf */
cd->size = 0;
while(cd->size < cd->n_bits) {
int v;
if (cd->insize == 0)
break;
v = zfile_getc (in);
if (v == -1)
break;
cd->insize--;
cd->buf[cd->size++] = v;
}
if(cd->size <= 0)
return -1;
cd->offset = 0;
/* Round size down to integral number of codes */
cd->size = (cd->size << 3) - (cd->n_bits - 1);
}
r_off = cd->offset;
bits = cd->n_bits;
/* Get to the first byte. */
bp += (r_off >> 3);
r_off &= 7;
/* Get first part (low order bits) */
code = (*bp++ >> r_off);
bits -= (8 - r_off);
r_off = 8 - r_off; /* now, offset into code word */
/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
if(bits >= 8)
{
code |= *bp++ << r_off;
r_off += 8;
bits -= 8;
}
/* high order bits. */
code |= (*bp & ((1<<bits)-1)) << r_off;
cd->offset += cd->n_bits;
return code;
}
static uae_u32 xadIO_Compress(struct zfile *in, struct zfile *out, int insize, struct rledata *rled, uae_u8 bitinfo)
{
int err = 0;
struct UCompData *cd;
if((bitinfo & UCOMPBIT_MASK) < UCOMPINIT_BITS)
return XADERR_ILLEGALDATA;
if((cd = xcalloc(struct UCompData, 1)))
{
int finchar, code, oldcode, incode, blockcomp;
uae_u8 *stackp, *stack, *stackend;
stackp = stack = cd->stack;
stackend = stack + UCOMPSTACKSIZE;
cd->maxbits = bitinfo & UCOMPBIT_MASK;
blockcomp = bitinfo & UCOMPBLOCK_MASK;
cd->maxmaxcode = 1 << cd->maxbits;
cd->maxcode = UCOMPMAXCODE(cd->n_bits = UCOMPINIT_BITS);
cd->free_ent = blockcomp ? UCOMPFIRST : 256;
cd->insize = insize;
cd->rled = rled;
if((cd->tab_prefixof = xcalloc(uae_u16, cd->maxmaxcode)))
{
if((cd->tab_suffixof = xcalloc(uae_u8, cd->maxmaxcode)))
{
/* Initialize the first 256 entries in the table. */
for(code = 255; code >= 0; code--)
cd->tab_suffixof[code] = code;
if((finchar = oldcode = UCompgetcode(in, cd)) == -1)
err = XADERR_DECRUNCH;
else
{
putrle (finchar, out, cd->rled); /* first code must be 8 bits = uae_u8 */
while((code = UCompgetcode(in, cd)) > -1)
{
if((code == UCOMPCLEAR) && blockcomp)
{
for(code = 255; code >= 0; code--)
cd->tab_prefixof[code] = 0;
cd->clear_flg = 1;
cd->free_ent = UCOMPFIRST - 1;
if((code = UCompgetcode(in, cd)) == -1)
break; /* O, untimely death! */
}
incode = code;
/* Special case for KwKwK string. */
if(code >= cd->free_ent)
{
if(code > cd->free_ent)
{
err = XADERR_ILLEGALDATA;
break;
}
*stackp++ = finchar;
code = oldcode;
}
/* Generate output characters in reverse order */
while(stackp < stackend && code >= 256)
{
*stackp++ = cd->tab_suffixof[code];
code = cd->tab_prefixof[code];
}
if(stackp >= stackend)
{
err = XADERR_ILLEGALDATA;
break;
}
*(stackp++) = finchar = cd->tab_suffixof[code];
/* And put them out in forward order */
do
{
putrle (*(--stackp), out, cd->rled);
} while(stackp > stack);
/* Generate the new entry. */
if((code = cd->free_ent) < cd->maxmaxcode)
{
cd->tab_prefixof[code] = (uae_u16) oldcode;
cd->tab_suffixof[code] = finchar;
cd->free_ent = code+1;
}
/* Remember previous code. */
oldcode = incode;
}
}
xfree (cd->tab_suffixof);
}
else
err = XADERR_NOMEMORY;
xfree(cd->tab_prefixof);
}
else
err = XADERR_NOMEMORY;
xfree(cd);
}
else
err = XADERR_NOMEMORY;
return err;
}
static void MakeCRC16(uae_u16 *buf, uae_u16 ID)
{
uae_u16 i, j, k;
for(i = 0; i < 256; ++i)
{
k = i;
for(j = 0; j < 8; ++j)
{
if(k & 1)
k = (k >> 1) ^ ID;
else
k >>= 1;
}
buf[i] = k;
}
}
static uae_u16 wrpcrc16 (uae_u16 *tab, uae_u8 *buf, int len)
{
uae_u16 crc = 0;
while (len-- > 0)
crc = tab[(crc ^ *buf++) & 0xFF] ^ (crc >> 8);
return crc;
}
static int iswrp (uae_u8 *data)
{
if(data[0] == 'W' && data[1] == 'a' && data[2] == 'r' && data[3] == 'p'
&& data[4] == ' ' && data[5] == 'v' && data[6] == '1' && data[7] == '.'
&& data[8] == '1' && !data[9] && !data[18] && data[19] <= 3)
return 1;
return 0;
}
#define COMPBUF 30000
struct zfile *unwarp(struct zfile *zf)
{
int err = 0;
uae_u8 buf[26] = { 0 };
int algo, side, track;
int pos, dstpos, olddstpos;
uae_u16 crc;
uae_u32 size;
struct zfile *nf = NULL, *tmpf = NULL;
uae_u8 *zero, *data;
int outsize = 11 * 512;
int outsize2 = 11 * (512 + 16);
struct rledata rled;
uae_u16 wrpcrc16table[256];
MakeCRC16 (wrpcrc16table, 0xa001);
zero = xcalloc (uae_u8, outsize2);
olddstpos = 0;
for (;;) {
if (zfile_fread (buf, sizeof buf, 1, zf) == 0)
break;
if (!iswrp (buf))
break;
if (!nf) {
nf = zfile_fopen_empty (zf, L"zipped.wrp", 1760 * 512);
tmpf = zfile_fopen_empty (zf, L"tmp", outsize2);
}
track = (buf[10] << 8) | buf[11];
algo = buf[19];
side = -1;
if (!memcmp (buf + 12, "BOT\0", 4))
side = 1;
if (!memcmp (buf + 12, "TOP\0", 4))
side = 0;
crc = (buf[20] << 8) | buf[21];
pos = zfile_ftell (zf);
dstpos = -1;
if (side >= 0 && track >= 0 && track <= 79)
dstpos = track * 22 * 512 + (side * 11 * 512);
zfile_fseek (tmpf, 0, SEEK_SET);
zfile_fwrite (zero, outsize2, 1, tmpf);
zfile_fseek (tmpf, 0, SEEK_SET);
size = (buf[22] << 24) | (buf[23] << 16) | (buf[24] << 8) | buf[25];
err = 0;
memset (&rled, 0, sizeof rled);
switch (algo)
{
case 1:
if (zfile_getc (zf) != 12)
err = XADERR_ILLEGALDATA;
else
err = xadIO_Compress (zf, tmpf, size - 1, &rled, 12 | UCOMPBLOCK_MASK);
break;
case 2:
err = ARCunsqueeze (zf, tmpf, &rled);
break;
case 0:
case 3:
{
int i;
for (i = 0; i < size; i++) {
uae_u8 v = zfile_getc (zf);
putrle (v, tmpf, algo == 3 ? &rled : NULL);
}
}
break;
default:
write_log (L"WRP unknown compression method %d, track=%d,size=%d\n", algo, track, side);
goto end;
break;
}
if (err) {
write_log (L"WRP corrupt data, track=%d,side=%d,err=%d\n", track, side, err);
} else {
uae_u16 crc2;
int os = zfile_ftell (tmpf);
data = zfile_getdata (tmpf, 0, os);
crc2 = wrpcrc16 (wrpcrc16table, data, os);
if (crc != crc2)
write_log (L"WRP crc error %04x<>%04x, track=%d,side=%d\n", crc, crc2, track, side);
xfree (data);
}
if (dstpos >= 0) {
zfile_fseek (nf, dstpos, SEEK_SET);
data = zfile_getdata (tmpf, 0, outsize);
zfile_fwrite (data, outsize, 1, nf);
}
zfile_fseek (zf, pos + size, SEEK_SET);
}
end:
xfree (zero);
zfile_fclose (tmpf);
if (nf) {
zfile_fclose (zf);
zf = nf;
}
return zf;
}
extern struct zfile *unwarp(struct zfile*);
#include <stdio.h>
void *xmalloc(int v)
{
return malloc(v);
}
void *zfile_fopen(const char *name, const char *mode)
{
return fopen(name, mode);
}
void zfile_fclose(void *z)
{
fclose(z);
}
/*
* UAE - The Un*x Amiga Emulator
*
* Emulate very basic Amiga-like environment for XFD slaves
*
* All this only because there is no portable XFD replacement..
*
* (c) 2007 Toni Wilen
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "sysconfig.h"
#include "sysdeps.h"
#include "zfile.h"
#include "fsdb.h"
#include "uae.h"
#include "custom.h"
#include "memory.h"
#include "newcpu.h"
#include "cpu_small.h"
#include "cputbl_small.h"
/* memory structure
*
* 0x000676 execbase
* 0x000ffc current start of free memory
* 0x001000 allocmem code (exec)
* 0x001080 freemem code, dummy (exec)
* 0x001f00 XFD buffer info
* 0x002000 first XFD slave
* 0x?????? next XFD slave
* ....
* 0x?????? decrunched data
* 0x?????? free memory (available for slave)
* 0xxxf000 end of decompression buffer
* end stack
*/
static uaecptr exec = 0x676;
static uaecptr freememaddr = 0x0ffc;
static uaecptr allocmem = 0x1000;
static uaecptr freemem = 0x1080;
static uaecptr bufferinfo = 0x1f00;
static uaecptr stacksize = 0x1000;
struct xfdslave
{
struct xfdslave *next;
uaecptr start;
char *name;
};
static struct xfdslave *xfdslaves;
#define FAKEMEM_SIZE 524288
static uae_u32 gl(uae_u8 *p)
{
uae_u32 v;
v = p[0] << 24;
v |= p[1] << 16;
v |= p[2] << 8;
v |= p[3] << 0;
return v;
}
static uae_u16 gw(uae_u8 *p)
{
uae_u16 v;
v = p[0] << 8;
v |= p[1] << 0;
return v;
}
static void pl(uae_u8 *p, uae_u32 v)
{
p[0] = v >> 24;
p[1] = v >> 16;
p[2] = v >> 8;
p[3] = v >> 0;
}
static uae_u8 *codeptr, *xfdmemory;
static uaecptr codememory;
static uae_u32 xfdmem_mask;
static int load_xfd(char *path)
{
struct zfile *z;
uae_u8 *buf, *p;
int size;
int first, last, numhunks;
int hunksize;
uae_u8 *prevhunk;
int i, j;
uaecptr hunks[10];
uaecptr startaddr;
z = zfile_fopen(path, "rb");
if (!z)
return 0;
zfile_fseek(z, 0, SEEK_END);
size = zfile_ftell(z);
zfile_fseek(z, 0, SEEK_SET);
buf = xmalloc(size);
zfile_fread(buf, size, 1, z);
zfile_fclose(z);
p = buf;
if (gl(p) != 0x3f3)
goto end;
p += 4 + 8;
first = gl(p);
p += 4;
last = gl(p);
p += 4;
numhunks = last - first + 1;
prevhunk = 0;
startaddr = codememory;
for (i = 0; i < numhunks; i++) {
uaecptr out = codememory;
hunksize = gl(p) * 4;
p += 4;
pl(codeptr + out, hunksize);
if (prevhunk) {
pl(prevhunk, out);
prevhunk = codeptr + out;
}
hunks[i] = out + 8;
codememory += hunksize + 8;
}
for (i = 0; i < numhunks; i++) {
uae_u32 htype = gl(p);
uae_u32 hsize = gl(p + 4) * 4;
uaecptr haddr = hunks[i];
uaecptr srchunk;
uae_u32 relocnum, relochunknum;
p += 8;
if (htype == 0x3e9 || htype == 0x3ea) {
memcpy (codeptr + haddr, p, hsize);
p += hsize;
} else if (htype != 0x3eb) {
write_log ("RELOC: unknown hunk %08X\n", htype);
goto end;
}
htype = gl(p);
p += 4;
if (htype == 0x3f2)
continue;
if (htype != 0x3ec) {
write_log ("RELOC: expected 000003EC but got %08X\n", htype);
goto end;
}
relocnum = gl(p);
p += 4;
relochunknum = gl(p);
p += 4;
srchunk = hunks[relochunknum];
for (j = 0; j < relocnum; j++) {
uae_u32 off = gl(p);
p += 4;
pl(codeptr + haddr + off, gl(codeptr + haddr + off) + srchunk);
}
}
write_log ("XFD slave '%s' loaded and relocated @%08X (%d bytes) succesfully\n", path, startaddr, codememory - startaddr);
p = codeptr + startaddr + 8;
if (gl(p + 4) != 'XFDF') {
write_log ("XFD header corrupt\n");
goto end;
}
p = codeptr + gl(p + 20);
for (;;) {
int version = gw(p + 4);
int mversion = gw(p + 6);
uaecptr name = gl(p + 8);
int flags = gw(p + 12);
int minsize = gl(p + 28);
uae_u8 *nameptr = codeptr + name;
struct xfdslave *xfds;
write_log ("- '%s' ver %d, master ver %d, minsize %d\n",
nameptr, version, mversion, minsize);
xfds = xcalloc(sizeof(struct xfdslave), 1);
xfds->name = nameptr;
xfds->start = p - codeptr;
if (!xfdslaves) {
xfdslaves = xfds;
} else {
struct xfdslave *x = xfdslaves;
while(x->next)
x = x->next;
x->next = xfds;
}
if (!gl(p))
break;
p = codeptr + gl(p);
}
return 1;
end:
return 0;
}
static void initexec(void)
{
pl(codeptr + 4, exec);
// fake memory allocation functions
pl(codeptr + exec - 198, allocmem);
pl(codeptr + exec - 210, freemem);
// lea -4(pc),a0
pl(codeptr + allocmem + 0, 0x41fafffa);
// move.l (a0),d1; add.l d0,(a0)
pl(codeptr + allocmem + 4, 0x2210d190);
// move.l d1,d0; rts
pl(codeptr + allocmem + 8, 0x20014e75);
pl(codeptr + freemem, 0x4e750000); // rts
}
int init_xfd(void)
{
static int init;
char tmp[MAX_DPATH];
void *d;
if (init > 0)
return 1;
if (init < 0)
return 0;
init = -1;
init_cpu_small();
codememory = 0x2000;
codeptr = malloc (FAKEMEM_SIZE);
sprintf (tmp, "%splugins%cxfd", start_path_data, FSDB_DIR_SEPARATOR);
d = my_opendir(tmp);
if (d) {
while(my_readdir(d, tmp)) {
char tmp2[MAX_DPATH];
sprintf (tmp2, "%splugins%cxfd%c%s", start_path_data, FSDB_DIR_SEPARATOR, FSDB_DIR_SEPARATOR, tmp);
load_xfd(tmp2);
}
my_closedir(d);
}
initexec();
codeptr = realloc(codeptr, codememory);
xfdmemory = malloc (FAKEMEM_SIZE);
init = 1;
return 1;
}
void xop_illg (uae_u32 opcode)
{
write_log("minicpu illegal opcode %04.4x\n", opcode);
xm68k_setpc(0);
}
static int execute68k(void)
{
uaecptr stack = xm68k_areg(7);
xm68k_areg(7) = stack - 4;
for (;;) {
uae_u32 pc;
uae_u32 opcode = xget_iword (0);
(*xcpufunctbl[opcode])(opcode);
if (xm68k_areg(7) == stack)
return 1;
pc = xm68k_getpc();
if (pc <= 0x100 || pc >= FAKEMEM_SIZE) {
write_log("minicpu crash, pc=%x\n", pc);
return 0;
}
}
}
static struct zfile *decomp(struct zfile *zf, struct xfdslave *xfds, uae_u32 size)
{
uae_u8 *p;
uae_u32 decompsize;
uaecptr decompaddr;
struct zfile *zfout;
p = xfdmemory + bufferinfo;
memset(p, 0, 20 * 4);
xregs.regs[8] = bufferinfo; // A0
decompsize = gl (p + 16 * 4);
if (decompsize <= 0)
return 0;
decompaddr = FAKEMEM_SIZE - stacksize - decompsize;
pl (p + 6 * 4, decompaddr); // TargetBuffer
pl (p + 8 * 4, decompsize);
if (!execute68k())
return 0;
if (!xregs.regs[0])
return 0;
decompsize = gl (p + 16 * 4);
zfout = zfile_fopen_empty (zfile_getname(zf), decompsize);
zfile_fwrite (xfdmemory + decompaddr, decompsize, 1, zf);
return zfout;
}
uae_u32 xget_long (uaecptr addr)
{
uae_u32 *m;
addr &= xfdmem_mask;
m = (uae_u32 *)(xfdmemory + addr);
return do_get_mem_long (m);
}
uae_u32 xget_word (uaecptr addr)
{
uae_u16 *m;
addr &= xfdmem_mask;
m = (uae_u16 *)(xfdmemory + addr);
return do_get_mem_word (m);
}
uae_u32 xget_byte (uaecptr addr)
{
addr &= xfdmem_mask;
return xfdmemory[addr];
}
void xput_long (uaecptr addr, uae_u32 l)
{
uae_u32 *m;
addr &= xfdmem_mask;
m = (uae_u32 *)(xfdmemory + addr);
do_put_mem_long (m, l);
}
void xput_word (uaecptr addr, uae_u32 w)
{
uae_u16 *m;
addr &= xfdmem_mask;
m = (uae_u16 *)(xfdmemory + addr);
do_put_mem_word (m, w);
}
void xput_byte (uaecptr addr, uae_u32 b)
{
addr &= xfdmem_mask;
xfdmemory[addr] = b;
}
struct zfile *decompress_zfd(struct zfile *z)
{
unsigned int size;
uae_u8 *p;
struct xfdslave *xfds;
struct zfile *zfout = z;
if (!init_xfd())
return zfout;
memset (xfdmemory, 0, FAKEMEM_SIZE);
memcpy (xfdmemory, codeptr, codememory);
xfdmem_mask = FAKEMEM_SIZE - 1;
p = xfdmemory + codememory;
zfile_fseek (z, 0, SEEK_END);
size = zfile_ftell (z);
zfile_fseek (z, 0, SEEK_SET);
zfile_fread (p, size, 1, z);
xfds = xfdslaves;
while (xfds) {
uaecptr start = xfds->start;
memset(&xregs, 0, sizeof xregs);
pl(codeptr + freememaddr, codememory + size); // reset start of "free memory"
xregs.regs[0] = size; // D0
xregs.regs[8] = codememory; // A0
xregs.regs[9] = bufferinfo; // A1
xregs.regs[15] = FAKEMEM_SIZE; // A7
pl(xfdmemory + bufferinfo + 0x00, codememory); // SourceBuffer
pl(xfdmemory + bufferinfo + 0x04, size); // SourceBufLen
xm68k_setpc(gl(xfdmemory + start + 16)); // recog code
if (xregs.pc) {
if (execute68k()) {
if (xregs.regs[0]) {
write_log("XFD slave '%s' recognised the compressed data\n", xfds->name);
xm68k_setpc(gl(xfdmemory + start + 20)); // decomp code
if (xregs.pc) {
struct zfile *zz = decomp(z, xfds, size);
if (zz) {
zfout = zz;
break;
}
}
}
}
}
xfds = xfds->next;
}
return zfout;
}
#ifndef LIBRARIES_XFDMASTER_H
#define LIBRARIES_XFDMASTER_H
/*
** $VER: xfdmaster.h 39.5 (31.08.2002)
**
** Copyright 1994-2002 by Georg Hrmann, Dirk Stcker
** All Rights Reserved.
*/
#ifndef EXEC_LIBRARIES_H
#include <exec/libraries.h>
#endif
/*********************
* *
* Library Base *
* *
*********************/
struct xfdMasterBase {
struct Library LibNode;
ULONG xfdm_SegList; /* PRIVATE! */
struct DosLibrary * xfdm_DosBase; /* May be used for I/O etc. */
struct xfdSlave * xfdm_FirstSlave; /* List of available slaves */
struct xfdForeMan * xfdm_FirstForeMan; /* PRIVATE! */
ULONG xfdm_MinBufferSize;/* (V36) Min. BufSize for xfdRecogBuffer() */
ULONG xfdm_MinLinkerSize;/* (V36) Min. BufSize for xfdRecogLinker() */
struct ExecBase * xfdm_ExecBase; /* (V38.2) Cached for fast access */
};
#define XFDM_VERSION 39 /* for OpenLibrary() */
#define XFDM_NAME "xfdmaster.library"
/***************************
* *
* Object Types (V36) *
* *
***************************/
#define XFDOBJ_BUFFERINFO 1 /* xfdBufferInfo structure */
#define XFDOBJ_SEGMENTINFO 2 /* xfdSegmentInfo structure */
#define XFDOBJ_LINKERINFO 3 /* xfdLinkerInfo structure */
#define XFDOBJ_SCANNODE 4 /* (V37) xfdScanNode structure */
#define XFDOBJ_SCANHOOK 5 /* (V37) xfdScanHook structure */
#define XFDOBJ_MAX 5 /* PRIVATE! */
/********************
* *
* Buffer Info *
* *
********************/
struct xfdBufferInfo {
APTR xfdbi_SourceBuffer; /* Pointer to source buffer */
ULONG xfdbi_SourceBufLen; /* Length of source buffer */
struct xfdSlave *xfdbi_Slave; /* PRIVATE! */
STRPTR xfdbi_PackerName; /* Name of recognized packer */
UWORD xfdbi_PackerFlags; /* Flags for recognized packer */
UWORD xfdbi_Error; /* Error return code */
APTR xfdbi_TargetBuffer; /* Pointer to target buffer */
ULONG xfdbi_TargetBufMemType;/* Memtype of target buffer */
ULONG xfdbi_TargetBufLen; /* Full length of buffer */
ULONG xfdbi_TargetBufSaveLen;/* Used length of buffer */
ULONG xfdbi_DecrAddress; /* Address to load decrunched file */
ULONG xfdbi_JmpAddress; /* Address to jump in file */
APTR xfdbi_Special; /* Special decrunch info (eg. password) */
UWORD xfdbi_Flags; /* (V37) Flags to influence recog/decr */
UWORD xfdbi_Reserved0; /* (V38) PRIVATE! */
ULONG xfdbi_MinTargetLen; /* (V38) Required length of target buffer */
ULONG xfdbi_FinalTargetLen; /* (V38) Final length of decrunched file */
APTR xfdbi_UserTargetBuf; /* (V38) Target buffer allocated by user */
ULONG xfdbi_UserTargetBufLen;/* (V38) Target buffer length */
ULONG xfdbi_MinSourceLen; /* (V39) minimum source length (tested by
master library */
};
#define xfdbi_MaxSpecialLen xfdbi_Error /* Max. length of special info */
/*********************
* *
* Segment Info *
* *
*********************/
struct xfdSegmentInfo {
ULONG xfdsi_SegList; /* BPTR to segment list */
struct xfdSlave *xfdsi_Slave; /* PRIVATE! */
STRPTR xfdsi_PackerName; /* Name of recognized packer */
UWORD xfdsi_PackerFlags; /* Flags for recognized packer */
UWORD xfdsi_Error; /* Error return code */
APTR xfdsi_Special; /* Special decrunch info (eg. password) */
UWORD xfdsi_RelMode; /* (V34) Relocation mode */
UWORD xfdsi_Flags; /* (V37) Flags to influence recog/decr */
};
#define xfdsi_MaxSpecialLen xfdsi_Error /* Max. length of special info */
/**************************
* *
* Linker Info (V36) *
* *
**************************/
struct xfdLinkerInfo {
APTR xfdli_Buffer; /* Pointer to buffer */
ULONG xfdli_BufLen; /* Length of buffer */
STRPTR xfdli_LinkerName; /* Name of recognized linker */
APTR xfdli_Unlink; /* PRIVATE! */
UWORD xfdli_Reserved; /* Set to NULL */
UWORD xfdli_Error; /* Error return code */
ULONG xfdli_Hunk1; /* PRIVATE! */
ULONG xfdli_Hunk2; /* PRIVATE! */
ULONG xfdli_Amount1; /* PRIVATE! */
ULONG xfdli_Amount2; /* PRIVATE! */
APTR xfdli_Save1; /* Pointer to first unlinked file */
APTR xfdli_Save2; /* Pointer to second unlinked file */
ULONG xfdli_SaveLen1; /* Length of first unlinked file */
ULONG xfdli_SaveLen2; /* Length of second unlinked file */
};
/************************
* *
* Scan Node (V37) *
* *
************************/
struct xfdScanNode {
struct xfdScanNode *xfdsn_Next; /* Pointer to next xfdScanNode or NULL */
APTR xfdsn_Save; /* Pointer to data */
ULONG xfdsn_SaveLen; /* Length of data */
STRPTR xfdsn_PackerName; /* Name of recognized packer */
UWORD xfdsn_PackerFlags;/* Flags for recognized packer */
};
/************************
* *
* Scan Hook (V37) *
* *
************************/
struct xfdScanHook {
BOOL (* xfdsh_Entry)(); /* Entrypoint of hook code */
APTR xfdsh_Data; /* Private data of hook */
ULONG xfdsh_ToDo; /* Bytes still to scan (READ ONLY) */
ULONG xfdsh_ScanNode; /* Found data right now (or NULL) (READ ONLY) */
};
/********************
* *
* Error Codes *
* *
********************/
#define XFDERR_OK 0x0000 /* No errors */
#define XFDERR_NOMEMORY 0x0001 /* Error allocating memory */
#define XFDERR_NOSLAVE 0x0002 /* No slave entry in info structure */
#define XFDERR_NOTSUPPORTED 0x0003 /* Slave doesn't support called function */
#define XFDERR_UNKNOWN 0x0004 /* Unknown file */
#define XFDERR_NOSOURCE 0x0005 /* No sourcebuffer/seglist specified */
#define XFDERR_WRONGPASSWORD 0x0006 /* Wrong password for decrunching */
#define XFDERR_BADHUNK 0x0007 /* Bad hunk structure */
#define XFDERR_CORRUPTEDDATA 0x0008 /* Crunched data is corrupted */
#define XFDERR_MISSINGRESOURCE 0x0009 /* (V34) Missing resource (eg. library) */
#define XFDERR_WRONGKEY 0x000a /* (V35) Wrong 16/32 bit key */
#define XFDERR_BETTERCPU 0x000b /* (V37) Better CPU required */
#define XFDERR_HOOKBREAK 0x000c /* (V37) Hook caused break */
#define XFDERR_DOSERROR 0x000d /* (V37) Dos error */
#define XFDERR_NOTARGET 0x000e /* (V38) No user target given */
#define XFDERR_TARGETTOOSMALL 0x000f /* (V38) User target is too small */
#define XFDERR_TARGETNOTSUPPORTED 0x0010 /* (V38) User target not supported */
#define XFDERR_UNDEFINEDHUNK 0x1000 /* (V34) Undefined hunk type */
#define XFDERR_NOHUNKHEADER 0x1001 /* (V34) File is not executable */
#define XFDERR_BADEXTTYPE 0x1002 /* (V34) Bad hunk_ext type */
#define XFDERR_BUFFERTRUNCATED 0x1003 /* (V34) Unexpected end of file */
#define XFDERR_WRONGHUNKAMOUNT 0x1004 /* (V34) Wrong amount of hunks */
#define XFDERR_NOOVERLAYS 0x1005 /* (V36) Overlays not allowed */
#define XFDERR_UNSUPPORTEDHUNK 0x2000 /* (V34) Hunk type not supported */
#define XFDERR_BADRELMODE 0x2001 /* (V34) Unknown XFDREL_#? mode */
/*******************************
* *
* Relocation Modes (V34) *
* *
*******************************/
#define XFDREL_DEFAULT 0x0000 /* Use memory types given by hunk_header */
#define XFDREL_FORCECHIP 0x0001 /* Force all hunks to chip ram */
#define XFDREL_FORCEFAST 0x0002 /* Force all hunks to fast ram */
/*************************************
* *
* Values for xfd??_PackerFlags *
* *
*************************************/
/* Bit numbers */
#define XFDPFB_RELOC 0 /* Relocatible file packer */
#define XFDPFB_ADDR 1 /* Absolute address file packer */
#define XFDPFB_DATA 2 /* Data file packer */
#define XFDPFB_PASSWORD 4 /* Packer requires password */
#define XFDPFB_RELMODE 5 /* (V34) Decruncher supports xfdsi_RelMode */
#define XFDPFB_KEY16 6 /* (V35) Packer requires 16 bit key */
#define XFDPFB_KEY32 7 /* (V35) Packer requires 32 bit key */
#define XFDPFB_RECOGLEN 8 /* (V38) slave recognizes target lengths */
#define XFDPFB_USERTARGET 9 /* (V38) slave supports user target buffer */
#define XFDPFB_EXTERN 15 /* (V37) PRIVATE */
/* Bit masks */
#define XFDPFF_RELOC (1<<XFDPFB_RELOC)
#define XFDPFF_ADDR (1<<XFDPFB_ADDR)
#define XFDPFF_DATA (1<<XFDPFB_DATA)
#define XFDPFF_PASSWORD (1<<XFDPFB_PASSWORD)
#define XFDPFF_RELMODE (1<<XFDPFB_RELMODE)
#define XFDPFF_KEY16 (1<<XFDPFB_KEY16)
#define XFDPFF_KEY32 (1<<XFDPFB_KEY32)
#define XFDPFF_RECOGLEN (1<<XFDPFB_RECOGLEN)
#define XFDPFF_USERTARGET (1<<XFDPFB_USERTARGET)
#define XFDPFF_EXTERN (1<<XFDPFB_EXTERN)
/************************************
* *
* Values for xfd??_Flags (V37) *
* *
************************************/
/* Bit numbers */
#define XFDFB_RECOGEXTERN 0 /* xfdRecog#?() uses external slaves */
#define XFDFB_RECOGTARGETLEN 1 /* (V38) xfdRecogBuffer() uses only slaves
that recognize target lengths */
#define XFDFB_RECOGUSERTARGET 2 /* (V38) xfdRecogBuffer() uses only slaves
that support user targets */
#define XFDFB_USERTARGET 3 /* (V38) xfdbi_DecrunchBuffer() decrunchs
to given xfdbi_UserTarget */
#define XFDFB_MASTERALLOC 4 /* (V39) master allocated decrunch buffer */
/* Bit masks */
#define XFDFF_RECOGEXTERN (1<<XFDFB_RECOGEXTERN)
#define XFDFF_RECOGTARGETLEN (1<<XFDFB_RECOGTARGETLEN)
#define XFDFF_RECOGUSERTARGET (1<<XFDFB_RECOGUSERTARGET)
#define XFDFF_USERTARGET (1<<XFDFB_USERTARGET)
#define XFDFF_MASTERALLOC (1<<XFDFB_MASTERALLOC)
/****************************************************
* *
* Flags for xfdTestHunkStructureFlags() (V36) *
* *
****************************************************/
/* Bit numbers */
#define XFDTHB_NOOVERLAYS 0 /* Abort on hunk_overlay */
/* Bit masks */
#define XFDTHF_NOOVERLAYS (1<<XFDTHB_NOOVERLAYS)
/****************************************
* *
* Flags for xfdStripHunks() (V36) *
* *
****************************************/
/* Bit numbers */
#define XFDSHB_NAME 0 /* Strip hunk_name */
#define XFDSHB_SYMBOL 1 /* Strip hunk_symbol */
#define XFDSHB_DEBUG 2 /* Strip hunk_debug */
/* Bit masks */
#define XFDSHF_NAME (1<<XFDSHB_NAME)
#define XFDSHF_SYMBOL (1<<XFDSHB_SYMBOL)
#define XFDSHF_DEBUG (1<<XFDSHB_DEBUG)
/**************************************
* *
* Flags for xfdScanData() (V37) *
* *
**************************************/
/* Bit numbers */
#define XFDSDB_USEEXTERN 0 /* Use external slaves for scanning */
#define XFDSDB_SCANODD 1 /* Scan at odd addresses too */
/* Bit masks */
#define XFDSDF_USEEXTERN (1<<XFDSDB_USEEXTERN)
#define XFDSDF_SCANODD (1<<XFDSDB_SCANODD)
/****************
* *
* Foreman *
* *
****************/
struct xfdForeMan {
ULONG xfdf_Security; /* moveq #-1,d0 ; rts */
ULONG xfdf_ID; /* Set to XFDF_ID */
UWORD xfdf_Version; /* Set to XFDF_VERSION */
UWORD xfdf_Reserved; /* Not used by now, set to NULL */
ULONG xfdf_Next; /* PRIVATE! */
ULONG xfdf_SegList; /* PRIVATE! */
struct xfdSlave *xfdf_FirstSlave; /* First slave (see below) */
};
#define XFDF_ID (('X'<<24)|('F'<<16)|('D'<<8)|('F'))
#define XFDF_VERSION 1
/**************
* *
* Slave *
* *
**************/
struct xfdSlave {
struct xfdSlave *xfds_Next; /* Next slave (or NULL) */
UWORD xfds_Version; /* Set to XFDS_VERSION */
UWORD xfds_MasterVersion; /* Minimum XFDM_VERSION required */
STRPTR xfds_PackerName; /* Name of packer ('\0' terminated) */
UWORD xfds_PackerFlags; /* Flags for packer */
UWORD xfds_MaxSpecialLen; /* Max. length of special info (eg. password) */
BOOL (* xfds_RecogBuffer)(); /* buffer recognition code (or NULL) */
BOOL (* xfds_DecrunchBuffer)(); /* buffer decrunch code (or NULL) */
BOOL (* xfds_RecogSegment)(); /* segment recognition code (or NULL) */
BOOL (* xfds_DecrunchSegment)();/* segment decrunch code (or NULL) */
UWORD xfds_SlaveID; /* (V36) Slave ID (only internal slaves) */
UWORD xfds_ReplaceID; /* (V36) ID of slave to be replaced */
ULONG xfds_MinBufferSize; /* (V36) Min. BufSize for RecogBufferXYZ() */
};
#define xfds_ScanData xfds_RecogSegment /* (V37) XFDPFB_DATA: Scan code (or NULL) */
#define xfds_VerifyData xfds_DecrunchSegment /* (V37) XFDPFB_DATA: Verify code (or NULL) */
#define XFDS_VERSION 2
/*********************************************
* *
* Additional Recognition Results (V38) *
* *
*********************************************/
struct xfdRecogResult {
ULONG xfdrr_MinTargetLen; /* Min. required length of target buffer */
ULONG xfdrr_FinalTargetLen; /* Final length of decrunched file */
ULONG xfdrr_MinSourceLen; /* (V39) minimum size of source file */
};
/*********************************
* *
* Internal Slave IDs (V36) *
* *
*********************************/
#define XFDID_BASE 0x8000
#define XFDID_PowerPacker23 (XFDID_BASE+0x0001)
#define XFDID_PowerPacker30 (XFDID_BASE+0x0003)
#define XFDID_PowerPacker30Enc (XFDID_BASE+0x0005)
#define XFDID_PowerPacker30Ovl (XFDID_BASE+0x0007)
#define XFDID_PowerPacker40 (XFDID_BASE+0x0009)
#define XFDID_PowerPacker40Lib (XFDID_BASE+0x000a)
#define XFDID_PowerPacker40Enc (XFDID_BASE+0x000b)
#define XFDID_PowerPacker40LibEnc (XFDID_BASE+0x000c)
#define XFDID_PowerPacker40Ovl (XFDID_BASE+0x000d)
#define XFDID_PowerPacker40LibOvl (XFDID_BASE+0x000e)
#define XFDID_PowerPackerData (XFDID_BASE+0x000f)
#define XFDID_PowerPackerDataEnc (XFDID_BASE+0x0010)
#define XFDID_ByteKiller13 (XFDID_BASE+0x0011)
#define XFDID_ByteKiller20 (XFDID_BASE+0x0012)
#define XFDID_ByteKiller30 (XFDID_BASE+0x0013)
#define XFDID_ByteKillerPro10 (XFDID_BASE+0x0014)
#define XFDID_ByteKillerPro10Pro (XFDID_BASE+0x0015)
#define XFDID_DragPack10 (XFDID_BASE+0x0016)
#define XFDID_TNMCruncher11 (XFDID_BASE+0x0017)
#define XFDID_HQCCruncher20 (XFDID_BASE+0x0018)
#define XFDID_RSICruncher14 (XFDID_BASE+0x0019)
#define XFDID_ANCCruncher (XFDID_BASE+0x001a)
#define XFDID_ReloKit10 (XFDID_BASE+0x001b)
#define XFDID_HighPressureCruncher (XFDID_BASE+0x001c)
#define XFDID_STPackedSong (XFDID_BASE+0x001d)
#define XFDID_TSKCruncher (XFDID_BASE+0x001e)
#define XFDID_LightPack15 (XFDID_BASE+0x001f)
#define XFDID_CrunchMaster10 (XFDID_BASE+0x0020)
#define XFDID_HQCCompressor100 (XFDID_BASE+0x0021)
#define XFDID_FlashSpeed10 (XFDID_BASE+0x0022)
#define XFDID_CrunchManiaData (XFDID_BASE+0x0023)
#define XFDID_CrunchManiaDataEnc (XFDID_BASE+0x0024)
#define XFDID_CrunchManiaLib (XFDID_BASE+0x0025)
#define XFDID_CrunchManiaNormal (XFDID_BASE+0x0026)
#define XFDID_CrunchManiaSimple (XFDID_BASE+0x0027)
#define XFDID_CrunchManiaAddr (XFDID_BASE+0x0028)
#define XFDID_DefJamCruncher32 (XFDID_BASE+0x0029)
#define XFDID_DefJamCruncher32Pro (XFDID_BASE+0x002a)
#define XFDID_TetraPack102 (XFDID_BASE+0x002b)
#define XFDID_TetraPack11 (XFDID_BASE+0x002c)
#define XFDID_TetraPack21 (XFDID_BASE+0x002d)
#define XFDID_TetraPack21Pro (XFDID_BASE+0x002e)
#define XFDID_TetraPack22 (XFDID_BASE+0x002f)
#define XFDID_TetraPack22Pro (XFDID_BASE+0x0030)
#define XFDID_DoubleAction10 (XFDID_BASE+0x0031)
#define XFDID_DragPack252Data (XFDID_BASE+0x0032)
#define XFDID_DragPack252 (XFDID_BASE+0x0033)
#define XFDID_FCG10 (XFDID_BASE+0x0034)
#define XFDID_Freeway07 (XFDID_BASE+0x0035)
#define XFDID_IAMPacker10ATM5Data (XFDID_BASE+0x0036)
#define XFDID_IAMPacker10ATM5 (XFDID_BASE+0x0037)
#define XFDID_IAMPacker10ICEData (XFDID_BASE+0x0038)
#define XFDID_IAMPacker10ICE (XFDID_BASE+0x0039)
#define XFDID_Imploder (XFDID_BASE+0x003a)
#define XFDID_ImploderLib (XFDID_BASE+0x003b)
#define XFDID_ImploderOvl (XFDID_BASE+0x003c)
#define XFDID_FileImploder (XFDID_BASE+0x003d)
#define XFDID_MasterCruncher30Addr (XFDID_BASE+0x003f)
#define XFDID_MasterCruncher30 (XFDID_BASE+0x0040)
#define XFDID_MaxPacker12 (XFDID_BASE+0x0041)
#define XFDID_PackIt10Data (XFDID_BASE+0x0042)
#define XFDID_PackIt10 (XFDID_BASE+0x0043)
#define XFDID_PMCNormal (XFDID_BASE+0x0044)
#define XFDID_PMCSample (XFDID_BASE+0x0045)
#define XFDID_XPKPacked (XFDID_BASE+0x0046)
#define XFDID_XPKCrypted (XFDID_BASE+0x0047)
#define XFDID_TimeCruncher17 (XFDID_BASE+0x0048)
#define XFDID_TFACruncher154 (XFDID_BASE+0x0049)
#define XFDID_TurtleSmasher13 (XFDID_BASE+0x004a)
#define XFDID_MegaCruncher10 (XFDID_BASE+0x004b)
#define XFDID_MegaCruncher12 (XFDID_BASE+0x004c)
#define XFDID_ProPack (XFDID_BASE+0x004d)
#define XFDID_ProPackData (XFDID_BASE+0x004e)
#define XFDID_ProPackDataKey (XFDID_BASE+0x004f)
#define XFDID_STCruncher10 (XFDID_BASE+0x0050)
#define XFDID_STCruncher10Data (XFDID_BASE+0x0051)
#define XFDID_SpikeCruncher (XFDID_BASE+0x0052)
#define XFDID_SyncroPacker46 (XFDID_BASE+0x0053)
#define XFDID_SyncroPacker46Pro (XFDID_BASE+0x0054)
#define XFDID_TitanicsCruncher11 (XFDID_BASE+0x0055)
#define XFDID_TitanicsCruncher12 (XFDID_BASE+0x0056)
#define XFDID_TryItCruncher101 (XFDID_BASE+0x0057)
#define XFDID_TurboSqueezer61 (XFDID_BASE+0x0058)
#define XFDID_TurboSqueezer80 (XFDID_BASE+0x0059)
#define XFDID_TurtleSmasher200 (XFDID_BASE+0x005a)
#define XFDID_TurtleSmasher200Data (XFDID_BASE+0x005b)
#define XFDID_StoneCracker270 (XFDID_BASE+0x005c)
#define XFDID_StoneCracker270Pro (XFDID_BASE+0x005d)
#define XFDID_StoneCracker292 (XFDID_BASE+0x005e)
#define XFDID_StoneCracker299 (XFDID_BASE+0x005f)
#define XFDID_StoneCracker299d (XFDID_BASE+0x0060)
#define XFDID_StoneCracker300 (XFDID_BASE+0x0061)
#define XFDID_StoneCracker300Data (XFDID_BASE+0x0062)
#define XFDID_StoneCracker310 (XFDID_BASE+0x0063)
#define XFDID_StoneCracker310Data (XFDID_BASE+0x0064)
#define XFDID_StoneCracker311 (XFDID_BASE+0x0065)
#define XFDID_StoneCracker400 (XFDID_BASE+0x0066)
#define XFDID_StoneCracker400Data (XFDID_BASE+0x0067)
#define XFDID_StoneCracker401 (XFDID_BASE+0x0068)
#define XFDID_StoneCracker401Data (XFDID_BASE+0x0069)
#define XFDID_StoneCracker401Addr (XFDID_BASE+0x006a)
#define XFDID_StoneCracker401BetaAddr (XFDID_BASE+0x006b)
#define XFDID_StoneCracker403Data (XFDID_BASE+0x006c)
#define XFDID_StoneCracker404 (XFDID_BASE+0x006d)
#define XFDID_StoneCracker404Data (XFDID_BASE+0x006e)
#define XFDID_StoneCracker404Addr (XFDID_BASE+0x006f)
#define XFDID_ChryseisCruncher09 (XFDID_BASE+0x0070)
#define XFDID_QuickPowerPacker10 (XFDID_BASE+0x0071)
#define XFDID_GNUPacker12 (XFDID_BASE+0x0072)
#define XFDID_GNUPacker12Seg (XFDID_BASE+0x0073)
#define XFDID_GNUPacker12Data (XFDID_BASE+0x0074)
#define XFDID_TrashEliminator10 (XFDID_BASE+0x0075)
#define XFDID_MasterCruncher30Data (XFDID_BASE+0x0076)
#define XFDID_SuperCruncher27 (XFDID_BASE+0x0077)
#define XFDID_UltimatePacker11 (XFDID_BASE+0x0078)
#define XFDID_ProPackOld (XFDID_BASE+0x0079)
#define XFDID_SACFPQCruncher (XFDID_BASE+0x007a) /* disabled */
#define XFDID_PowerPackerPatch10 (XFDID_BASE+0x007b)
#define XFDID_CFP135 (XFDID_BASE+0x007c)
#define XFDID_BOND (XFDID_BASE+0x007d)
#define XFDID_PowerPackerLoadSeg (XFDID_BASE+0x007e)
#define XFDID_StoneCracker299b (XFDID_BASE+0x007f)
#define XFDID_CrunchyDat10 (XFDID_BASE+0x0080)
#define XFDID_PowerPacker20 (XFDID_BASE+0x0081)
#define XFDID_StoneCracker403 (XFDID_BASE+0x0082)
#define XFDID_PKProtector200 (XFDID_BASE+0x0083)
#define XFDID_PPbk (XFDID_BASE+0x0084)
#define XFDID_StoneCracker292Data (XFDID_BASE+0x0085)
#define XFDID_MegaCruncherObj (XFDID_BASE+0x0086)
#define XFDID_DeluxeCruncher1 (XFDID_BASE+0x0087)
#define XFDID_DeluxeCruncher3 (XFDID_BASE+0x0088)
#define XFDID_ByteKiller97 (XFDID_BASE+0x0089)
#define XFDID_TurboSqueezer51 (XFDID_BASE+0x008A)
#define XFDID_SubPacker10 (XFDID_BASE+0x008B)
#define XFDID_StoneCracker404Lib (XFDID_BASE+0x008C)
#define XFDID_ISC_Pass1 (XFDID_BASE+0x008D)
#define XFDID_ISC_Pass2 (XFDID_BASE+0x008E)
#define XFDID_ISC_Pass3 (XFDID_BASE+0x008F)
#define XFDID_PCompressFALH (XFDID_BASE+0x0090)
#define XFDID_PCompressHILH (XFDID_BASE+0x0091)
#define XFDID_SMF (XFDID_BASE+0x0092)
#define XFDID_DefJamCruncher32T (XFDID_BASE+0x0093)
#endif /* LIBRARIES_XFDMASTER_H */
AM_CPPFLAGS = @UAE_CPPFLAGS@
AM_CPPFLAGS += -I$(top_srcdir)/src/include -I$(top_builddir)/src -I$(top_srcdir)/src
AM_CFLAGS = @UAE_CFLAGS@
noinst_LIBRARIES = libzip.a
libzip_a_SOURCES = unzip.c
noinst_HEADERS = unzip.h
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = src/archivers/zip
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \
$(top_srcdir)/m4/as-objc.m4 \
$(top_srcdir)/m4/ax_check_compiler_flags.m4 \
$(top_srcdir)/m4/ax_gcc_archflag.m4 \
$(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \
$(top_srcdir)/m4/framework.m4 $(top_srcdir)/m4/fsusage.m4 \
$(top_srcdir)/m4/gtk-2.0.m4 $(top_srcdir)/m4/gtk.m4 \
$(top_srcdir)/m4/sdl.m4 $(top_srcdir)/m4/type_socklen_t.m4 \
$(top_srcdir)/m4/uintmax_t.m4 $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/sysconfig.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LIBRARIES = $(noinst_LIBRARIES)
ARFLAGS = cru
libzip_a_AR = $(AR) $(ARFLAGS)
libzip_a_LIBADD =
am_libzip_a_OBJECTS = unzip.$(OBJEXT)
libzip_a_OBJECTS = $(am_libzip_a_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libzip_a_SOURCES)
DIST_SOURCES = $(libzip_a_SOURCES)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
ASMOBJS = @ASMOBJS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BSDSOCKOBJS = @BSDSOCKOBJS@
CC = @CC@
CCAS = @CCAS@
CCASDEPMODE = @CCASDEPMODE@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CDOBJS = @CDOBJS@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPUOBJS = @CPUOBJS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEBUGOBJS = @DEBUGOBJS@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
EXTRAOBJS = @EXTRAOBJS@
FILEPRG = @FILEPRG@
FILESYSOBJS = @FILESYSOBJS@
GENCPUOPTS = @GENCPUOPTS@
GFX_DEP = @GFX_DEP@
GREP = @GREP@
GTK_CFLAGS = @GTK_CFLAGS@
GTK_CONFIG = @GTK_CONFIG@
GTK_LIBS = @GTK_LIBS@
GUI_DEP = @GUI_DEP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JITOBJS = @JITOBJS@
JOY_DEP = @JOY_DEP@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MACHDEP = @MACHDEP@
MAKEDEPPRG = @MAKEDEPPRG@
MAKEINFO = @MAKEINFO@
MATHLIB = @MATHLIB@
MKDIR_P = @MKDIR_P@
NO_SCHED_CFLAGS = @NO_SCHED_CFLAGS@
OBJC = @OBJC@
OBJCDEPMODE = @OBJCDEPMODE@
OBJC_LDFLAGS = @OBJC_LDFLAGS@
OBJEXT = @OBJEXT@
OSDEP = @OSDEP@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PRTDIAG = @PRTDIAG@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
RCLPRG = @RCLPRG@
RESOBJS = @RESOBJS@
SCSIOBJS = @SCSIOBJS@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SND_DEP = @SND_DEP@
STRIP = @STRIP@
TARGET = @TARGET@
THREADDEP = @THREADDEP@
UAE_CFLAGS = @UAE_CFLAGS@
UAE_CPPFLAGS = @UAE_CPPFLAGS@
UAE_LIBS = @UAE_LIBS@
UAE_RSRCFILE = @UAE_RSRCFILE@
VERSION = @VERSION@
WRCPRG = @WRCPRG@
XMKMF = @XMKMF@
X_CFLAGS = @X_CFLAGS@
X_EXTRA_LIBS = @X_EXTRA_LIBS@
X_LIBS = @X_LIBS@
X_PRE_LIBS = @X_PRE_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_OBJC = @ac_ct_OBJC@
ac_cv_c_inline = @ac_cv_c_inline@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CPPFLAGS = @UAE_CPPFLAGS@ -I$(top_srcdir)/src/include \
-I$(top_builddir)/src -I$(top_srcdir)/src
AM_CFLAGS = @UAE_CFLAGS@
noinst_LIBRARIES = libzip.a
libzip_a_SOURCES = unzip.c
noinst_HEADERS = unzip.h
all: all-am
.SUFFIXES:
.SUFFIXES: .c .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/archivers/zip/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/archivers/zip/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
libzip.a: $(libzip_a_OBJECTS) $(libzip_a_DEPENDENCIES)
-rm -f libzip.a
$(libzip_a_AR) libzip.a $(libzip_a_OBJECTS) $(libzip_a_LIBADD)
$(RANLIB) libzip.a
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unzip.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LIBRARIES) $(HEADERS)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-noinstLIBRARIES ctags distclean distclean-compile \
distclean-generic distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
/* unzip.c -- IO on .zip files using zlib
Version 0.15 beta, Mar 19th, 1998,
Read unzip.h for more info
*/
#include "sysconfig.h"
#include "sysdeps.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "zlib.h"
#include "zfile.h"
#include "unzip.h"
#ifdef STDC
# include <stddef.h>
# include <string.h>
# include <stdlib.h>
#endif
#ifdef NO_ERRNO_H
extern int errno;
#else
# include <errno.h>
#endif
#ifndef local
# define local static
#endif
/* compile with -Dlocal if your debugger can't find static symbols */
#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
!defined(CASESENSITIVITYDEFAULT_NO)
#define CASESENSITIVITYDEFAULT_NO
#endif
#ifndef UNZ_BUFSIZE
#define UNZ_BUFSIZE (16384)
#endif
#ifndef UNZ_MAXFILENAMEINZIP
#define UNZ_MAXFILENAMEINZIP (256)
#endif
#ifndef ALLOC
# define ALLOC(size) (malloc(size))
#endif
#ifndef TRYFREE
# define TRYFREE(p) {if (p) free(p);}
#endif
#define SIZECENTRALDIRITEM (0x2e)
#define SIZEZIPLOCALHEADER (0x1e)
/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
#ifndef SEEK_CUR
#define SEEK_CUR 1
#endif
#ifndef SEEK_END
#define SEEK_END 2
#endif
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
const char unz_copyright[] =
" unzip 0.15 Copyright 1998 Gilles Vollant ";
/* unz_file_info_interntal contain internal info about a file in zipfile*/
typedef struct unz_file_info_internal_s
{
uLong offset_curfile;/* relative offset of local header 4 bytes */
} unz_file_info_internal;
/* file_in_zip_read_info_s contain internal information about a file in zipfile,
when reading and decompress it */
typedef struct
{
char *read_buffer; /* internal buffer for compressed data */
z_stream stream; /* zLib stream structure for inflate */
uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
uLong stream_initialised; /* flag set if stream structure is initialised*/
uLong offset_local_extrafield;/* offset of the local extra field */
uInt size_local_extrafield;/* size of the local extra field */
uLong pos_local_extrafield; /* position in the local extra field in read*/
uLong crc32; /* crc32 of all data uncompressed */
uLong crc32_wait; /* crc32 we must obtain after decompress all */
uLong rest_read_compressed; /* number of byte to be decompressed */
uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
struct zfile *file; /* io structore of the zipfile */
uLong compression_method; /* compression method (0==store) */
uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
} file_in_zip_read_info_s;
/* unz_s contain internal information about the zipfile
*/
typedef struct
{
struct zfile* file; /* io structore of the zipfile */
unz_global_info gi; /* public global information */
uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
uLong num_file; /* number of the current file in the zipfile*/
uLong pos_in_central_dir; /* pos of the current file in the central dir*/
uLong current_file_ok; /* flag about the usability of the current file*/
uLong central_pos; /* position of the beginning of the central dir*/
uLong size_central_dir; /* size of the central directory */
uLong offset_central_dir; /* offset of start of central directory with
respect to the starting disk number */
unz_file_info cur_file_info; /* public info about the current file in zip*/
unz_file_info_internal cur_file_info_internal; /* private info about it*/
file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
file if we are decompressing it */
} unz_s;
/* ===========================================================================
Read a byte from a gz_stream; update next_in and avail_in. Return EOF
for end of file.
IN assertion: the stream s has been sucessfully opened for reading.
*/
local int unzlocal_getByte(struct zfile *fin,int *pi)
{
unsigned char c;
int err = zfile_fread(&c, 1, 1, fin);
if (err==1)
{
*pi = (int)c;
return UNZ_OK;
}
else
{
return UNZ_EOF;
}
}
/* ===========================================================================
Reads a long in LSB order from the given gz_stream. Sets
*/
local int unzlocal_getShort (struct zfile *fin,uLong *pX)
{
uLong x ;
int i;
int err;
err = unzlocal_getByte(fin,&i);
x = (uLong)i;
if (err==UNZ_OK)
err = unzlocal_getByte(fin,&i);
x += ((uLong)i)<<8;
if (err==UNZ_OK)
*pX = x;
else
*pX = 0;
return err;
}
local int unzlocal_getLong (struct zfile *fin, uLong *pX)
{
uLong x ;
int i;
int err;
err = unzlocal_getByte(fin,&i);
x = (uLong)i;
if (err==UNZ_OK)
err = unzlocal_getByte(fin,&i);
x += ((uLong)i)<<8;
if (err==UNZ_OK)
err = unzlocal_getByte(fin,&i);
x += ((uLong)i)<<16;
if (err==UNZ_OK)
err = unzlocal_getByte(fin,&i);
x += ((uLong)i)<<24;
if (err==UNZ_OK)
*pX = x;
else
*pX = 0;
return err;
}
/* My own strcmpi / strcasecmp */
local int strcmpcasenosensitive_internal (const char *fileName1, const char *fileName2)
{
for (;;)
{
char c1=*(fileName1++);
char c2=*(fileName2++);
if ((c1>='a') && (c1<='z'))
c1 -= 0x20;
if ((c2>='a') && (c2<='z'))
c2 -= 0x20;
if (c1=='\0')
return ((c2=='\0') ? 0 : -1);
if (c2=='\0')
return 1;
if (c1<c2)
return -1;
if (c1>c2)
return 1;
}
}
#ifdef CASESENSITIVITYDEFAULT_NO
#define CASESENSITIVITYDEFAULTVALUE 2
#else
#define CASESENSITIVITYDEFAULTVALUE 1
#endif
#ifndef STRCMPCASENOSENTIVEFUNCTION
#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
#endif
/*
Compare two filename (fileName1,fileName2).
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
or strcasecmp)
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
(like 1 on Unix, 2 on Windows)
*/
extern int ZEXPORT unzStringFileNameCompare (const char*fileName1, const char*fileName2, int iCaseSensitivity)
{
if (iCaseSensitivity==0)
iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
if (iCaseSensitivity==1)
return strcmp(fileName1,fileName2);
return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
}
#define BUFREADCOMMENT (0x400)
/*
Locate the Central directory of a zipfile (at the end, just before
the global comment)
*/
local uLong unzlocal_SearchCentralDir(struct zfile *fin)
{
unsigned char* buf;
uLong uSizeFile;
uLong uBackRead;
uLong uMaxBack=0xffff; /* maximum size of global comment */
uLong uPosFound=0;
if (zfile_fseek(fin,0,SEEK_END) != 0)
return 0;
uSizeFile = zfile_ftell( fin );
if (uMaxBack>uSizeFile)
uMaxBack = uSizeFile;
buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
if (buf==NULL)
return 0;
uBackRead = 4;
while (uBackRead<uMaxBack)
{
uLong uReadSize,uReadPos ;
int i;
if (uBackRead+BUFREADCOMMENT>uMaxBack)
uBackRead = uMaxBack;
else
uBackRead+=BUFREADCOMMENT;
uReadPos = uSizeFile-uBackRead ;
uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
(BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
if (zfile_fseek(fin,uReadPos,SEEK_SET)!=0)
break;
if (zfile_fread(buf,(uInt)uReadSize,1,fin)!=1)
break;
for (i=(int)uReadSize-3; (i--)>0;)
if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
{
uPosFound = uReadPos+i;
break;
}
if (uPosFound!=0)
break;
}
TRYFREE(buf);
return uPosFound;
}
/*
Open a Zip file. path contain the full pathname (by example,
on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
"zlib/zlib109.zip".
If the zipfile cannot be opened (file don't exist or in not valid), the
return value is NULL.
Else, the return value is a unzFile Handle, usable with other function
of this unzip package.
*/
extern unzFile ZEXPORT unzOpen (struct zfile *fin)
{
unz_s us;
unz_s *s;
uLong central_pos,uL;
uLong number_disk; /* number of the current dist, used for
spaning ZIP, unsupported, always 0*/
uLong number_disk_with_CD; /* number the the disk with central dir, used
for spaning ZIP, unsupported, always 0*/
uLong number_entry_CD; /* total number of entries in
the central dir
(same than number_entry on nospan) */
int err=UNZ_OK;
if (unz_copyright[0]!=' ')
return NULL;
central_pos = unzlocal_SearchCentralDir(fin);
if (central_pos==0)
err=UNZ_ERRNO;
if (zfile_fseek(fin,central_pos,SEEK_SET)!=0)
err=UNZ_ERRNO;
/* the signature, already checked */
if (unzlocal_getLong(fin,&uL)!=UNZ_OK)
err=UNZ_ERRNO;
/* number of this disk */
if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK)
err=UNZ_ERRNO;
/* number of the disk with the start of the central directory */
if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK)
err=UNZ_ERRNO;
/* total number of entries in the central dir on this disk */
if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK)
err=UNZ_ERRNO;
/* total number of entries in the central dir */
if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK)
err=UNZ_ERRNO;
if ((number_entry_CD!=us.gi.number_entry) ||
(number_disk_with_CD!=0) ||
(number_disk!=0))
err=UNZ_BADZIPFILE;
/* size of the central directory */
if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK)
err=UNZ_ERRNO;
/* offset of start of central directory with respect to the
starting disk number */
if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK)
err=UNZ_ERRNO;
/* zipfile comment length */
if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK)
err=UNZ_ERRNO;
if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
(err==UNZ_OK))
err=UNZ_BADZIPFILE;
if (err!=UNZ_OK)
return NULL;
us.file=fin;
us.byte_before_the_zipfile = central_pos -
(us.offset_central_dir+us.size_central_dir);
us.central_pos = central_pos;
us.pfile_in_zip_read = NULL;
s=(unz_s*)ALLOC(sizeof(unz_s));
*s=us;
unzGoToFirstFile((unzFile)s);
return (unzFile)s;
}
/*
Close a ZipFile opened with unzipOpen.
If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
return UNZ_OK if there is no problem. */
extern int ZEXPORT unzClose (unzFile file)
{
unz_s* s;
if (file==NULL)
return UNZ_PARAMERROR;
s=(unz_s*)file;
if (s->pfile_in_zip_read!=NULL)
unzCloseCurrentFile(file);
zfile_fclose(s->file);
TRYFREE(s);
return UNZ_OK;
}
/*
Write info about the ZipFile in the *pglobal_info structure.
No preparation of the structure is needed
return UNZ_OK if there is no problem. */
extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info *pglobal_info)
{
unz_s* s;
if (file==NULL)
return UNZ_PARAMERROR;
s=(unz_s*)file;
*pglobal_info=s->gi;
return UNZ_OK;
}
/*
Translate date/time from Dos format to tm_unz (readable more easilty)
*/
local void unzlocal_DosDateToTmuDate (uLong ulDosDate, tm_unz *ptm)
{
uLong uDate;
uDate = (uLong)(ulDosDate>>16);
ptm->tm_mday = (uInt)(uDate&0x1f) ;
ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
}
/*
Get Info about the current file in the zipfile, with internal only info
*/
local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
unz_file_info *pfile_info,
unz_file_info_internal
*pfile_info_internal,
char *szFileName,
uLong fileNameBufferSize,
void *extraField,
uLong extraFieldBufferSize,
char *szComment,
uLong commentBufferSize));
local int unzlocal_GetCurrentFileInfoInternal (unzFile file,
unz_file_info *pfile_info,
unz_file_info_internal *pfile_info_internal,
char *szFileName, uLong fileNameBufferSize,
void *extraField, uLong extraFieldBufferSize,
char *szComment, uLong commentBufferSize)
{
unz_s* s;
unz_file_info file_info;
unz_file_info_internal file_info_internal;
int err=UNZ_OK;
uLong uMagic;
long lSeek=0;
if (file==NULL)
return UNZ_PARAMERROR;
s=(unz_s*)file;
if (zfile_fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0)
err=UNZ_ERRNO;
/* we check the magic */
if (err==UNZ_OK)
if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
err=UNZ_ERRNO;
else if (uMagic!=0x02014b50)
err=UNZ_BADZIPFILE;
if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
err=UNZ_ERRNO;
if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK)
err=UNZ_ERRNO;
if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK)
err=UNZ_ERRNO;
if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK)
err=UNZ_ERRNO;
if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK)
err=UNZ_ERRNO;
unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK)
err=UNZ_ERRNO;
if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK)
err=UNZ_ERRNO;
if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK)
err=UNZ_ERRNO;
if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK)
err=UNZ_ERRNO;
if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK)
err=UNZ_ERRNO;
if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK)
err=UNZ_ERRNO;
if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK)
err=UNZ_ERRNO;
if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK)
err=UNZ_ERRNO;
if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK)
err=UNZ_ERRNO;
if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK)
err=UNZ_ERRNO;
lSeek+=file_info.size_filename;
if ((err==UNZ_OK) && (szFileName!=NULL))
{
uLong uSizeRead ;
if (file_info.size_filename<fileNameBufferSize)
{
*(szFileName+file_info.size_filename)='\0';
uSizeRead = file_info.size_filename;
}
else
uSizeRead = fileNameBufferSize;
if ((file_info.size_filename>0) && (fileNameBufferSize>0))
if (zfile_fread(szFileName,(uInt)uSizeRead,1,s->file)!=1)
err=UNZ_ERRNO;
lSeek -= uSizeRead;
}
if ((err==UNZ_OK) && (extraField!=NULL))
{
uLong uSizeRead ;
if (file_info.size_file_extra<extraFieldBufferSize)
uSizeRead = file_info.size_file_extra;
else
uSizeRead = extraFieldBufferSize;
if (lSeek!=0)
if (zfile_fseek(s->file,lSeek,SEEK_CUR)==0)
lSeek=0;
else
err=UNZ_ERRNO;
if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
if (zfile_fread(extraField,(uInt)uSizeRead,1,s->file)!=1)
err=UNZ_ERRNO;
lSeek += file_info.size_file_extra - uSizeRead;
}
else
lSeek+=file_info.size_file_extra;
if ((err==UNZ_OK) && (szComment!=NULL))
{
uLong uSizeRead ;
if (file_info.size_file_comment<commentBufferSize)
{
*(szComment+file_info.size_file_comment)='\0';
uSizeRead = file_info.size_file_comment;
}
else
uSizeRead = commentBufferSize;
if (lSeek!=0)
if (zfile_fseek(s->file,lSeek,SEEK_CUR)==0)
lSeek=0;
else
err=UNZ_ERRNO;
if ((file_info.size_file_comment>0) && (commentBufferSize>0))
if (zfile_fread(szComment,(uInt)uSizeRead,1,s->file)!=1)
err=UNZ_ERRNO;
lSeek+=file_info.size_file_comment - uSizeRead;
}
else
lSeek+=file_info.size_file_comment;
if ((err==UNZ_OK) && (pfile_info!=NULL))
*pfile_info=file_info;
if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
*pfile_info_internal=file_info_internal;
return err;
}
/*
Write info about the ZipFile in the *pglobal_info structure.
No preparation of the structure is needed
return UNZ_OK if there is no problem.
*/
extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
unz_file_info *pfile_info,
char *szFileName, uLong fileNameBufferSize,
void *extraField, uLong extraFieldBufferSize,
char *szComment, uLong commentBufferSize)
{
return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
szFileName,fileNameBufferSize,
extraField,extraFieldBufferSize,
szComment,commentBufferSize);
}
/*
Set the current file of the zipfile to the first file.
return UNZ_OK if there is no problem
*/
extern int ZEXPORT unzGoToFirstFile (unzFile file)
{
int err=UNZ_OK;
unz_s* s;
if (file==NULL)
return UNZ_PARAMERROR;
s=(unz_s*)file;
s->pos_in_central_dir=s->offset_central_dir;
s->num_file=0;
err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
&s->cur_file_info_internal,
NULL,0,NULL,0,NULL,0);
s->current_file_ok = (err == UNZ_OK);
return err;
}
/*
Set the current file of the zipfile to the next file.
return UNZ_OK if there is no problem
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
*/
extern int ZEXPORT unzGoToNextFile (unzFile file)
{
unz_s* s;
int err;
if (file==NULL)
return UNZ_PARAMERROR;
s=(unz_s*)file;
if (!s->current_file_ok)
return UNZ_END_OF_LIST_OF_FILE;
if (s->num_file+1==s->gi.number_entry)
return UNZ_END_OF_LIST_OF_FILE;
s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
s->num_file++;
err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
&s->cur_file_info_internal,
NULL,0,NULL,0,NULL,0);
s->current_file_ok = (err == UNZ_OK);
return err;
}
/*
Try locate the file szFileName in the zipfile.
For the iCaseSensitivity signification, see unzipStringFileNameCompare
return value :
UNZ_OK if the file is found. It becomes the current file.
UNZ_END_OF_LIST_OF_FILE if the file is not found
*/
extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
{
unz_s* s;
int err;
uLong num_fileSaved;
uLong pos_in_central_dirSaved;
if (file==NULL)
return UNZ_PARAMERROR;
if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
return UNZ_PARAMERROR;
s=(unz_s*)file;
if (!s->current_file_ok)
return UNZ_END_OF_LIST_OF_FILE;
num_fileSaved = s->num_file;
pos_in_central_dirSaved = s->pos_in_central_dir;
err = unzGoToFirstFile(file);
while (err == UNZ_OK)
{
char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
unzGetCurrentFileInfo(file,NULL,
szCurrentFileName,sizeof(szCurrentFileName)-1,
NULL,0,NULL,0);
if (unzStringFileNameCompare(szCurrentFileName,
szFileName,iCaseSensitivity)==0)
return UNZ_OK;
err = unzGoToNextFile(file);
}
s->num_file = num_fileSaved ;
s->pos_in_central_dir = pos_in_central_dirSaved ;
return err;
}
/*
Read the local header of the current zipfile
Check the coherency of the local header and info in the end of central
directory about this file
store in *piSizeVar the size of extra info in local header
(filename and size of extra field data)
*/
local int unzlocal_CheckCurrentFileCoherencyHeader (unz_s *s, uInt *piSizeVar,
uLong *poffset_local_extrafield,
uInt *psize_local_extrafield)
{
uLong uMagic,uData,uFlags;
uLong size_filename;
uLong size_extra_field;
int err=UNZ_OK;
*piSizeVar = 0;
*poffset_local_extrafield = 0;
*psize_local_extrafield = 0;
if (zfile_fseek(s->file,s->cur_file_info_internal.offset_curfile +
s->byte_before_the_zipfile,SEEK_SET)!=0)
return UNZ_ERRNO;
if (err==UNZ_OK)
if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
err=UNZ_ERRNO;
else if (uMagic!=0x04034b50)
err=UNZ_BADZIPFILE;
if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
err=UNZ_ERRNO;
/*
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
err=UNZ_BADZIPFILE;
*/
if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK)
err=UNZ_ERRNO;
if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
err=UNZ_ERRNO;
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
err=UNZ_BADZIPFILE;
if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
(s->cur_file_info.compression_method!=Z_DEFLATED))
err=UNZ_BADZIPFILE;
if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */
err=UNZ_ERRNO;
if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */
err=UNZ_ERRNO;
else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
((uFlags & 8)==0))
err=UNZ_BADZIPFILE;
if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */
err=UNZ_ERRNO;
/* else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
((uFlags & 8)==0))
err=UNZ_BADZIPFILE;
*/
if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */
err=UNZ_ERRNO;
/* else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
((uFlags & 8)==0))
err=UNZ_BADZIPFILE;
*/
if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK)
err=UNZ_ERRNO;
else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
err=UNZ_BADZIPFILE;
*piSizeVar += (uInt)size_filename;
if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK)
err=UNZ_ERRNO;
*poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
SIZEZIPLOCALHEADER + size_filename;
*psize_local_extrafield = (uInt)size_extra_field;
*piSizeVar += (uInt)size_extra_field;
return err;
}
/*
Open for reading data the current file in the zipfile.
If there is no error and the file is opened, the return value is UNZ_OK.
*/
extern int ZEXPORT unzOpenCurrentFile (unzFile file)
{
int err=UNZ_OK;
int Store;
uInt iSizeVar;
unz_s* s;
file_in_zip_read_info_s* pfile_in_zip_read_info;
uLong offset_local_extrafield; /* offset of the local extra field */
uInt size_local_extrafield; /* size of the local extra field */
if (file==NULL)
return UNZ_PARAMERROR;
s=(unz_s*)file;
if (!s->current_file_ok)
return UNZ_PARAMERROR;
if (s->pfile_in_zip_read != NULL)
unzCloseCurrentFile(file);
if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
&offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
return UNZ_BADZIPFILE;
pfile_in_zip_read_info = (file_in_zip_read_info_s*)
ALLOC(sizeof(file_in_zip_read_info_s));
if (pfile_in_zip_read_info==NULL)
return UNZ_INTERNALERROR;
pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
pfile_in_zip_read_info->pos_local_extrafield=0;
if (pfile_in_zip_read_info->read_buffer==NULL)
{
TRYFREE(pfile_in_zip_read_info);
return UNZ_INTERNALERROR;
}
pfile_in_zip_read_info->stream_initialised=0;
if ((s->cur_file_info.compression_method!=0) &&
(s->cur_file_info.compression_method!=Z_DEFLATED))
err=UNZ_BADZIPFILE;
Store = s->cur_file_info.compression_method==0;
pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
pfile_in_zip_read_info->crc32=0;
pfile_in_zip_read_info->compression_method =
s->cur_file_info.compression_method;
pfile_in_zip_read_info->file=s->file;
pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
pfile_in_zip_read_info->stream.total_out = 0;
if (!Store)
{
pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
pfile_in_zip_read_info->stream.zfree = (free_func)0;
pfile_in_zip_read_info->stream.opaque = (voidpf)0;
err=inflateInit2_(&pfile_in_zip_read_info->stream, -MAX_WBITS, ZLIB_VERSION, sizeof(z_stream));
if (err == Z_OK)
pfile_in_zip_read_info->stream_initialised=1;
/* windowBits is passed < 0 to tell that there is no zlib header.
* Note that in this case inflate *requires* an extra "dummy" byte
* after the compressed stream in order to complete decompression and
* return Z_STREAM_END.
* In unzip, i don't wait absolutely Z_STREAM_END because I known the
* size of both compressed and uncompressed data
*/
}
pfile_in_zip_read_info->rest_read_compressed =
s->cur_file_info.compressed_size ;
pfile_in_zip_read_info->rest_read_uncompressed =
s->cur_file_info.uncompressed_size ;
pfile_in_zip_read_info->pos_in_zipfile =
s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
iSizeVar;
pfile_in_zip_read_info->stream.avail_in = (uInt)0;
s->pfile_in_zip_read = pfile_in_zip_read_info;
return UNZ_OK;
}
/*
Read bytes from the current file.
buf contain buffer where data must be copied
len the size of buf.
return the number of byte copied if somes bytes are copied
return 0 if the end of file was reached
return <0 with error code if there is an error
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
*/
extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned int len)
{
int err=UNZ_OK;
uInt iRead = 0;
unz_s* s;
file_in_zip_read_info_s* pfile_in_zip_read_info;
if (file==NULL)
return UNZ_PARAMERROR;
s=(unz_s*)file;
pfile_in_zip_read_info=s->pfile_in_zip_read;
if (pfile_in_zip_read_info==NULL)
return UNZ_PARAMERROR;
if ((pfile_in_zip_read_info->read_buffer == NULL))
return UNZ_END_OF_LIST_OF_FILE;
if (len==0)
return 0;
pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
pfile_in_zip_read_info->stream.avail_out = (uInt)len;
if (len>pfile_in_zip_read_info->rest_read_uncompressed)
pfile_in_zip_read_info->stream.avail_out =
(uInt)pfile_in_zip_read_info->rest_read_uncompressed;
while (pfile_in_zip_read_info->stream.avail_out>0)
{
if ((pfile_in_zip_read_info->stream.avail_in==0) &&
(pfile_in_zip_read_info->rest_read_compressed>0))
{
uInt uReadThis = UNZ_BUFSIZE;
if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
if (uReadThis == 0)
return UNZ_EOF;
if (zfile_fseek(pfile_in_zip_read_info->file,
pfile_in_zip_read_info->pos_in_zipfile +
pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
return UNZ_ERRNO;
if (zfile_fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
pfile_in_zip_read_info->file)!=1)
return UNZ_ERRNO;
pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
pfile_in_zip_read_info->stream.next_in =
(Bytef*)pfile_in_zip_read_info->read_buffer;
pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
}
if (pfile_in_zip_read_info->compression_method==0)
{
uInt uDoCopy,i ;
if (pfile_in_zip_read_info->stream.avail_out <
pfile_in_zip_read_info->stream.avail_in)
uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
else
uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
for (i=0;i<uDoCopy;i++)
*(pfile_in_zip_read_info->stream.next_out+i) =
*(pfile_in_zip_read_info->stream.next_in+i);
pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
pfile_in_zip_read_info->stream.next_out,
uDoCopy);
pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
pfile_in_zip_read_info->stream.next_out += uDoCopy;
pfile_in_zip_read_info->stream.next_in += uDoCopy;
pfile_in_zip_read_info->stream.total_out += uDoCopy;
iRead += uDoCopy;
}
else
{
uLong uTotalOutBefore,uTotalOutAfter;
const Bytef *bufBefore;
uLong uOutThis;
int flush=Z_SYNC_FLUSH;
uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
bufBefore = pfile_in_zip_read_info->stream.next_out;
/*
if ((pfile_in_zip_read_info->rest_read_uncompressed ==
pfile_in_zip_read_info->stream.avail_out) &&
(pfile_in_zip_read_info->rest_read_compressed == 0))
flush = Z_FINISH;
*/
err=inflate(&pfile_in_zip_read_info->stream,flush);
uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
uOutThis = uTotalOutAfter-uTotalOutBefore;
pfile_in_zip_read_info->crc32 =
crc32(pfile_in_zip_read_info->crc32,bufBefore,
(uInt)(uOutThis));
pfile_in_zip_read_info->rest_read_uncompressed -=
uOutThis;
iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
if (err==Z_STREAM_END)
return (iRead==0) ? UNZ_EOF : iRead;
if (err!=Z_OK)
break;
}
}
if (err==Z_OK)
return iRead;
return err;
}
/*
Give the current position in uncompressed data
*/
extern z_off_t ZEXPORT unztell (unzFile file)
{
unz_s* s;
file_in_zip_read_info_s* pfile_in_zip_read_info;
if (file==NULL)
return UNZ_PARAMERROR;
s=(unz_s*)file;
pfile_in_zip_read_info=s->pfile_in_zip_read;
if (pfile_in_zip_read_info==NULL)
return UNZ_PARAMERROR;
return (z_off_t)pfile_in_zip_read_info->stream.total_out;
}
/*
return 1 if the end of file was reached, 0 elsewhere
*/
extern int ZEXPORT unzeof (unzFile file)
{
unz_s* s;
file_in_zip_read_info_s* pfile_in_zip_read_info;
if (file==NULL)
return UNZ_PARAMERROR;
s=(unz_s*)file;
pfile_in_zip_read_info=s->pfile_in_zip_read;
if (pfile_in_zip_read_info==NULL)
return UNZ_PARAMERROR;
if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
return 1;
else
return 0;
}
/*
Read extra field from the current file (opened by unzOpenCurrentFile)
This is the local-header version of the extra field (sometimes, there is
more info in the local-header version than in the central-header)
if buf==NULL, it return the size of the local extra field that can be read
if buf!=NULL, len is the size of the buffer, the extra header is copied in
buf.
the return value is the number of bytes copied in buf, or (if <0)
the error code
*/
extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned int len)
{
unz_s* s;
file_in_zip_read_info_s* pfile_in_zip_read_info;
uInt read_now;
uLong size_to_read;
if (file==NULL)
return UNZ_PARAMERROR;
s=(unz_s*)file;
pfile_in_zip_read_info=s->pfile_in_zip_read;
if (pfile_in_zip_read_info==NULL)
return UNZ_PARAMERROR;
size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
pfile_in_zip_read_info->pos_local_extrafield);
if (buf==NULL)
return (int)size_to_read;
if (len>size_to_read)
read_now = (uInt)size_to_read;
else
read_now = (uInt)len ;
if (read_now==0)
return 0;
if (zfile_fseek(pfile_in_zip_read_info->file,
pfile_in_zip_read_info->offset_local_extrafield +
pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0)
return UNZ_ERRNO;
if (zfile_fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1)
return UNZ_ERRNO;
return (int)read_now;
}
/*
Close the file in zip opened with unzipOpenCurrentFile
Return UNZ_CRCERROR if all the file was read but the CRC is not good
*/
extern int ZEXPORT unzCloseCurrentFile (unzFile file)
{
int err=UNZ_OK;
unz_s* s;
file_in_zip_read_info_s* pfile_in_zip_read_info;
if (file==NULL)
return UNZ_PARAMERROR;
s=(unz_s*)file;
pfile_in_zip_read_info=s->pfile_in_zip_read;
if (pfile_in_zip_read_info==NULL)
return UNZ_PARAMERROR;
if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
{
if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
err=UNZ_CRCERROR;
}
TRYFREE(pfile_in_zip_read_info->read_buffer);
pfile_in_zip_read_info->read_buffer = NULL;
if (pfile_in_zip_read_info->stream_initialised)
inflateEnd(&pfile_in_zip_read_info->stream);
pfile_in_zip_read_info->stream_initialised = 0;
TRYFREE(pfile_in_zip_read_info);
s->pfile_in_zip_read=NULL;
return err;
}
/*
Get the global comment string of the ZipFile, in the szComment buffer.
uSizeBuf is the size of the szComment buffer.
return the number of byte copied or an error code <0
*/
extern int ZEXPORT unzGetGlobalComment (unzFile file, char *szComment, uLong uSizeBuf)
{
int err=UNZ_OK;
unz_s* s;
uLong uReadThis ;
if (file==NULL)
return UNZ_PARAMERROR;
s=(unz_s*)file;
uReadThis = uSizeBuf;
if (uReadThis>s->gi.size_comment)
uReadThis = s->gi.size_comment;
if (zfile_fseek(s->file,s->central_pos+22,SEEK_SET)!=0)
return UNZ_ERRNO;
if (uReadThis>0)
{
*szComment='\0';
if (zfile_fread(szComment,(uInt)uReadThis,1,s->file)!=1)
return UNZ_ERRNO;
}
if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
*(szComment+s->gi.size_comment)='\0';
return (int)uReadThis;
}
/* unzip.h -- IO for uncompress .zip files using zlib
Version 0.15 beta, Mar 19th, 1998,
Copyright (C) 1998 Gilles Vollant
This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
WinZip, InfoZip tools and compatible.
Encryption and multi volume ZipFile (span) are not supported.
Old compressions used by old PKZip 1.x are not supported
THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE
CAN CHANGE IN FUTURE VERSION !!
I WAIT FEEDBACK at mail info@winimage.com
Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
Condition of use and distribution are the same than zlib :
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* for more info about .ZIP format, see
ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
PkWare has also a specification at :
ftp://ftp.pkware.com/probdesc.zip */
#ifndef _unz_H
#define _unz_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _ZLIB_H
#include "zlib.h"
#endif
typedef int (ZEXPORT *INFLATEINIT2)(z_streamp strm, int windowBits, const char *version, int stream_size);
typedef int (ZEXPORT *INFLATEINIT)(z_streamp strm, const char *version, int stream_size);
typedef int (ZEXPORT *INFLATEEND)(z_streamp strm);
typedef int (ZEXPORT *INFLATE)(z_streamp strm, int flush);
typedef int (ZEXPORT *DEFLATEINIT)(z_streamp strm, int level, const char *version, int stream_size);
typedef int (ZEXPORT *DEFLATEEND)(z_streamp strm);
typedef int (ZEXPORT *DEFLATE)(z_streamp strm, int flush);
typedef uLong (ZEXPORT *CRC32)(uLong crc, const Bytef *buf, uInt len);
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
/* like the STRICT of WIN32, we define a pointer that cannot be converted
from (void*) without cast */
typedef struct TagunzFile__ { int unused; } unzFile__;
typedef unzFile__ *unzFile;
#else
typedef voidp unzFile;
#endif
#define UNZ_OK (0)
#define UNZ_END_OF_LIST_OF_FILE (-100)
#define UNZ_ERRNO (Z_ERRNO)
#define UNZ_EOF (0)
#define UNZ_PARAMERROR (-102)
#define UNZ_BADZIPFILE (-103)
#define UNZ_INTERNALERROR (-104)
#define UNZ_CRCERROR (-105)
/* tm_unz contain date/time info */
typedef struct tm_unz_s
{
uInt tm_sec; /* seconds after the minute - [0,59] */
uInt tm_min; /* minutes after the hour - [0,59] */
uInt tm_hour; /* hours since midnight - [0,23] */
uInt tm_mday; /* day of the month - [1,31] */
uInt tm_mon; /* months since January - [0,11] */
uInt tm_year; /* years - [1980..2044] */
} tm_unz;
/* unz_global_info structure contain global data about the ZIPfile
These data comes from the end of central dir */
typedef struct unz_global_info_s
{
uLong number_entry; /* total number of entries in
the central dir on this disk */
uLong size_comment; /* size of the global comment of the zipfile */
} unz_global_info;
/* unz_file_info contain information about a file in the zipfile */
typedef struct unz_file_info_s
{
uLong version; /* version made by 2 bytes */
uLong version_needed; /* version needed to extract 2 bytes */
uLong flag; /* general purpose bit flag 2 bytes */
uLong compression_method; /* compression method 2 bytes */
uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
uLong crc; /* crc-32 4 bytes */
uLong compressed_size; /* compressed size 4 bytes */
uLong uncompressed_size; /* uncompressed size 4 bytes */
uLong size_filename; /* filename length 2 bytes */
uLong size_file_extra; /* extra field length 2 bytes */
uLong size_file_comment; /* file comment length 2 bytes */
uLong disk_num_start; /* disk number start 2 bytes */
uLong internal_fa; /* internal file attributes 2 bytes */
uLong external_fa; /* external file attributes 4 bytes */
tm_unz tmu_date;
} unz_file_info;
extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
const char* fileName2,
int iCaseSensitivity));
/*
Compare two filename (fileName1,fileName2).
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
or strcasecmp)
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
(like 1 on Unix, 2 on Windows)
*/
//extern unzFile ZEXPORT unzOpen OF((struct zfile *path));
/*
Open a Zip file. path contain the full pathname (by example,
on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer
"zlib/zlib111.zip".
If the zipfile cannot be opened (file don't exist or in not valid), the
return value is NULL.
Else, the return value is a unzFile Handle, usable with other function
of this unzip package.
*/
extern int ZEXPORT unzClose OF((unzFile file));
/*
Close a ZipFile opened with unzipOpen.
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
return UNZ_OK if there is no problem. */
extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
unz_global_info *pglobal_info));
/*
Write info about the ZipFile in the *pglobal_info structure.
No preparation of the structure is needed
return UNZ_OK if there is no problem. */
extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
char *szComment,
uLong uSizeBuf));
/*
Get the global comment string of the ZipFile, in the szComment buffer.
uSizeBuf is the size of the szComment buffer.
return the number of byte copied or an error code <0
*/
/***************************************************************************/
/* Unzip package allow you browse the directory of the zipfile */
extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
/*
Set the current file of the zipfile to the first file.
return UNZ_OK if there is no problem
*/
extern int ZEXPORT unzGoToNextFile OF((unzFile file));
/*
Set the current file of the zipfile to the next file.
return UNZ_OK if there is no problem
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
*/
extern int ZEXPORT unzLocateFile OF((unzFile file,
const char *szFileName,
int iCaseSensitivity));
/*
Try locate the file szFileName in the zipfile.
For the iCaseSensitivity signification, see unzStringFileNameCompare
return value :
UNZ_OK if the file is found. It becomes the current file.
UNZ_END_OF_LIST_OF_FILE if the file is not found
*/
extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
unz_file_info *pfile_info,
char *szFileName,
uLong fileNameBufferSize,
void *extraField,
uLong extraFieldBufferSize,
char *szComment,
uLong commentBufferSize));
/*
Get Info about the current file
if pfile_info!=NULL, the *pfile_info structure will contain somes info about
the current file
if szFileName!=NULL, the filemane string will be copied in szFileName
(fileNameBufferSize is the size of the buffer)
if extraField!=NULL, the extra field information will be copied in extraField
(extraFieldBufferSize is the size of the buffer).
This is the Central-header version of the extra field
if szComment!=NULL, the comment string of the file will be copied in szComment
(commentBufferSize is the size of the buffer)
*/
/***************************************************************************/
/* for reading the content of the current zipfile, you can open it, read data
from it, and close it (you can close it before reading all the file)
*/
extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
/*
Open for reading data the current file in the zipfile.
If there is no error, the return value is UNZ_OK.
*/
extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
/*
Close the file in zip opened with unzOpenCurrentFile
Return UNZ_CRCERROR if all the file was read but the CRC is not good
*/
extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
voidp buf,
unsigned len));
/*
Read bytes from the current file (opened by unzOpenCurrentFile)
buf contain buffer where data must be copied
len the size of buf.
return the number of byte copied if somes bytes are copied
return 0 if the end of file was reached
return <0 with error code if there is an error
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
*/
extern z_off_t ZEXPORT unztell OF((unzFile file));
/*
Give the current position in uncompressed data
*/
extern int ZEXPORT unzeof OF((unzFile file));
/*
return 1 if the end of file was reached, 0 elsewhere
*/
extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
voidp buf,
unsigned len));
/*
Read extra field from the current file (opened by unzOpenCurrentFile)
This is the local-header version of the extra field (sometimes, there is
more info in the local-header version than in the central-header)
if buf==NULL, it return the size of the local extra field
if buf!=NULL, len is the size of the buffer, the extra header is copied in
buf.
the return value is the number of bytes copied in buf, or (if <0)
the error code
*/
#ifdef __cplusplus
}
#endif
#endif /* _unz_H */
/*
* UAE - The Un*x Amiga Emulator
*
* transparent archive handling
*
* 2007 Toni Wilen
*/
#include "sysconfig.h"
#include "sysdeps.h"
#ifdef _WIN32
#include <windows.h>
#include "win32.h"
#endif
#include "options.h"
#include "zfile.h"
#include "archivers/zip/unzip.h"
#include "archivers/dms/pfile.h"
#include "crc32.h"
#include "zarchive.h"
#include "disk.h"
#include <zlib.h>
#define unpack_log write_log
#undef unpack_log
#define unpack_log
static time_t fromdostime (uae_u32 dd)
{
struct tm tm;
time_t t;
memset (&tm, 0, sizeof tm);
tm.tm_hour = (dd >> 11) & 0x1f;
tm.tm_min = (dd >> 5) & 0x3f;
tm.tm_sec = ((dd >> 0) & 0x1f) * 2;
tm.tm_year = ((dd >> 25) & 0x7f) + 80;
tm.tm_mon = ((dd >> 21) & 0x0f) - 1;
tm.tm_mday = (dd >> 16) & 0x1f;
t = mktime (&tm);
_tzset ();
t -= _timezone;
return t;
}
static struct zvolume *getzvolume (struct znode *parent, struct zfile *zf, unsigned int id)
{
struct zvolume *zv = NULL;
switch (id)
{
case ArchiveFormatZIP:
zv = archive_directory_zip (zf);
break;
case ArchiveFormat7Zip:
zv = archive_directory_7z (zf);
break;
case ArchiveFormatRAR:
zv = archive_directory_rar (zf);
break;
case ArchiveFormatLHA:
zv = archive_directory_lha (zf);
break;
case ArchiveFormatLZX:
zv = archive_directory_lzx (zf);
break;
case ArchiveFormatPLAIN:
zv = archive_directory_plain (zf);
break;
case ArchiveFormatADF:
zv = archive_directory_adf (parent, zf);
break;
case ArchiveFormatRDB:
zv = archive_directory_rdb (zf);
break;
case ArchiveFormatTAR:
zv = archive_directory_tar (zf);
break;
case ArchiveFormatFAT:
zv = archive_directory_fat (zf);
break;
}
if (!zv)
zv = archive_directory_arcacc (zf, id);
return zv;
}
struct zfile *archive_access_select (struct znode *parent, struct zfile *zf, unsigned int id, int dodefault, int *retcode, int index)
{
struct zvolume *zv;
struct znode *zn;
int zipcnt, first, select;
TCHAR tmphist[MAX_DPATH];
struct zfile *z = NULL;
int we_have_file;
int diskimg;
int mask = zf->zfdmask;
int canhistory = (mask & ZFD_DISKHISTORY) && !(mask & ZFD_CHECKONLY);
int getflag = (mask & ZFD_DELAYEDOPEN) ? FILE_DELAYEDOPEN : 0;
if (retcode)
*retcode = 0;
if (index > 0)
return NULL;
zv = getzvolume (parent, zf, id);
if (!zv)
return NULL;
we_have_file = 0;
tmphist[0] = 0;
zipcnt = 1;
first = 1;
zn = &zv->root;
while (zn) {
int isok = 1;
diskimg = -1;
if (zn->type != ZNODE_FILE)
isok = 0;
if (zfile_is_ignore_ext (zn->fullname))
isok = 0;
diskimg = zfile_is_diskimage (zn->fullname);
if (isok) {
if (tmphist[0]) {
#ifndef _CONSOLE
if (diskimg >= 0 && canhistory)
DISK_history_add (tmphist, -1, diskimg, 1);
#endif
tmphist[0] = 0;
first = 0;
}
if (first) {
if (diskimg >= 0)
_tcscpy (tmphist, zn->fullname);
} else {
_tcscpy (tmphist, zn->fullname);
#ifndef _CONSOLE
if (diskimg >= 0 && canhistory)
DISK_history_add (tmphist, -1, diskimg, 1);
#endif
tmphist[0] = 0;
}
select = 0;
if (!zf->zipname)
select = 1;
if (zf->zipname && _tcslen (zn->fullname) >= _tcslen (zf->zipname) && !strcasecmp (zf->zipname, zn->fullname + _tcslen (zn->fullname) - _tcslen (zf->zipname)))
select = -1;
if (zf->zipname && zf->zipname[0] == '#' && _tstol (zf->zipname + 1) == zipcnt)
select = -1;
if (select && we_have_file < 10) {
struct zfile *zt = NULL;
TCHAR *ext = _tcsrchr (zn->fullname, '.');
int whf = 1;
int ft = 0;
if (mask & ZFD_CD) {
if (ext && !_tcsicmp (ext, ".iso")) {
whf = 2;
ft = ZFILE_CDIMAGE;
}
if (ext && !_tcsicmp (ext, ".ccd")) {
whf = 9;
ft = ZFILE_CDIMAGE;
}
if (ext && !_tcsicmp (ext, ".cue")) {
whf = 10;
ft = ZFILE_CDIMAGE;
}
} else {
zt = archive_getzfile (zn, id, getflag);
ft = zfile_gettype (zt);
}
if ((select < 0 || ft) && whf > we_have_file) {
if (!zt)
zt = archive_getzfile (zn, id, getflag);
we_have_file = whf;
if (z)
zfile_fclose (z);
z = zt;
zt = NULL;
}
zfile_fclose (zt);
}
}
zipcnt++;
zn = zn->next;
}
#ifndef _CONSOLE
diskimg = zfile_is_diskimage (zfile_getname (zf));
if (diskimg >= 0 && first && tmphist[0] && canhistory)
DISK_history_add (zfile_getname (zf), -1, diskimg, 1);
#endif
zfile_fclose_archive (zv);
if (z) {
zfile_fclose (zf);
zf = z;
} else if (!dodefault && zf->zipname && zf->zipname[0]) {
if (retcode)
*retcode = -1;
zf = NULL;
} else {
zf = NULL;
}
return zf;
}
struct zfile *archive_access_arcacc_select (struct zfile *zf, unsigned int id, int *retcode)
{
return zf;
}
void archive_access_scan (struct zfile *zf, zfile_callback zc, void *user, unsigned int id)
{
struct zvolume *zv;
struct znode *zn;
zv = getzvolume (NULL, zf, id);
if (!zv)
return;
zn = &zv->root;
while (zn) {
if (zn->type == ZNODE_FILE) {
struct zfile *zf2 = archive_getzfile (zn, id, 0);
if (zf2) {
int ztype = iszip (zf2);
if (ztype) {
zfile_fclose (zf2);
} else {
int ret = zc (zf2, user);
zfile_fclose (zf2);
if (ret)
break;
}
}
}
zn = zn->next;
}
zfile_fclose_archive (zv);
}
/* TAR */
static void archive_close_tar (void *handle)
{
}
struct zvolume *archive_directory_tar (struct zfile *z)
{
struct zvolume *zv;
struct znode *zn;
_tzset ();
zv = zvolume_alloc (z, ArchiveFormatTAR, NULL, NULL);
for (;;) {
uae_u8 block[512];
char name[MAX_DPATH];
int ustar = 0;
struct zarchive_info zai;
int valid = 1;
uae_u64 size;
if (zfile_fread (block, 512, 1, z) != 1)
break;
if (block[0] == 0)
break;
if (!memcmp (block + 257, "ustar ", 8))
ustar = 1;
name[0] = 0;
if (ustar)
strcpy (name, (char*)block + 345);
strcat (name, (char*)block);
if (name[0] == 0)
valid = 0;
if (block[156] != '0')
valid = 0;
if (ustar && (block[256] != 0 && block[256] != '0'))
valid = 0;
size = _strtoui64 ((char*)block + 124, NULL, 8);
if (valid) {
memset (&zai, 0, sizeof zai);
zai.name = au (name);
zai.size = size;
zai.t = _strtoui64 ((char*)block + 136, NULL, 8);
zai.t += _timezone;
if (_daylight)
zai.t -= 1 * 60 * 60;
if (zai.name[_tcslen (zai.name) - 1] == '/') {
zn = zvolume_adddir_abs (zv, &zai);
} else {
zn = zvolume_addfile_abs (zv, &zai);
if (zn)
zn->offset = zfile_ftell (z);
}
xfree (zai.name);
}
zfile_fseek (z, (size + 511) & ~511, SEEK_CUR);
}
zv->method = ArchiveFormatTAR;
return zv;
}
struct zfile *archive_access_tar (struct znode *zn)
{
#if 0
struct zfile *zf = zfile_fopen_empty (zn->volume->archive, zn->fullname, zn->size);
zfile_fseek (zn->volume->archive, zn->offset, SEEK_SET);
zfile_fwrite (zf->data, zn->size, 1, zn->volume->archive);
return zf;
#else
return zfile_fopen_parent (zn->volume->archive, zn->fullname, zn->offset, zn->size);
#endif
}
/* ZIP */
static void archive_close_zip (void *handle)
{
}
struct zvolume *archive_directory_zip (struct zfile *z)
{
unzFile uz;
unz_file_info file_info;
struct zvolume *zv;
int err;
uz = unzOpen (z);
if (!uz)
return 0;
if (unzGoToFirstFile (uz) != UNZ_OK)
return 0;
zv = zvolume_alloc (z, ArchiveFormatZIP, NULL, NULL);
for (;;) {
char filename_inzip2[MAX_DPATH];
TCHAR c;
struct zarchive_info zai;
time_t t;
unsigned int dd;
TCHAR *filename_inzip;
err = unzGetCurrentFileInfo (uz, &file_info, filename_inzip2, sizeof (filename_inzip2), NULL, 0, NULL, 0);
if (err != UNZ_OK)
return 0;
filename_inzip = au (filename_inzip2);
dd = file_info.dosDate;
t = fromdostime (dd);
memset (&zai, 0, sizeof zai);
zai.name = filename_inzip;
zai.t = t;
zai.flags = -1;
c = filename_inzip[_tcslen (filename_inzip) - 1];
if (c != '/' && c != '\\') {
int err = unzOpenCurrentFile (uz);
if (err == UNZ_OK) {
struct znode *zn;
zai.size = file_info.uncompressed_size;
zn = zvolume_addfile_abs (zv, &zai);
}
} else {
filename_inzip[_tcslen (filename_inzip) - 1] = 0;
zvolume_adddir_abs (zv, &zai);
}
xfree (filename_inzip);
err = unzGoToNextFile (uz);
if (err != UNZ_OK)
break;
}
unzClose (uz);
zv->method = ArchiveFormatZIP;
return zv;
}
static struct zfile *archive_do_zip (struct znode *zn, struct zfile *z, int flags)
{
unzFile uz;
int i;
TCHAR tmp[MAX_DPATH];
TCHAR *name = z ? z->archiveparent->name : zn->volume->root.fullname;
char *s;
uz = unzOpen (z ? z->archiveparent : zn->volume->archive);
if (!uz)
return 0;
if (z)
_tcscpy (tmp, z->archiveparent->name);
else
_tcscpy (tmp, zn->fullname + _tcslen (zn->volume->root.fullname) + 1);
if (unzGoToFirstFile (uz) != UNZ_OK)
goto error;
for (i = 0; tmp[i]; i++) {
if (tmp[i] == '\\')
tmp[i] = '/';
}
s = ua (tmp);
if (unzLocateFile (uz, s, 1) != UNZ_OK) {
xfree (s);
for (i = 0; tmp[i]; i++) {
if (tmp[i] == '/')
tmp[i] = '\\';
}
s = ua (tmp);
if (unzLocateFile (uz, s, 1) != UNZ_OK) {
xfree (s);
goto error;
}
}
xfree (s);
s = NULL;
if (unzOpenCurrentFile (uz) != UNZ_OK)
goto error;
if (!z)
z = zfile_fopen_empty (NULL, zn->fullname, zn->size);
if (z) {
int err = -1;
if (!(flags & FILE_DELAYEDOPEN) || z->size <= PEEK_BYTES) {
unpack_log ("ZIP: unpacking %s, flags=%d\n", name, flags);
err = unzReadCurrentFile (uz, z->data, z->datasize);
unpack_log ("ZIP: unpacked, code=%d\n", err);
} else {
z->archiveparent = zfile_dup (zn->volume->archive);
if (z->archiveparent) {
unpack_log ("ZIP: delayed open '%s'\n", name);
xfree (z->archiveparent->name);
z->archiveparent->name = my_strdup (tmp);
z->datasize = PEEK_BYTES;
err = unzReadCurrentFile (uz, z->data, z->datasize);
unpack_log ("ZIP: unpacked, code=%d\n", err);
} else {
unpack_log ("ZIP: unpacking %s (failed DELAYEDOPEN)\n", name);
err = unzReadCurrentFile (uz, z->data, z->datasize);
unpack_log ("ZIP: unpacked, code=%d\n", err);
}
}
}
unzCloseCurrentFile (uz);
unzClose (uz);
return z;
error:
unzClose (uz);
return NULL;
}
static struct zfile *archive_access_zip (struct znode *zn, int flags)
{
return archive_do_zip (zn, NULL, flags);
}
static struct zfile *archive_unpack_zip (struct zfile *zf)
{
return archive_do_zip (NULL, zf, 0);
}
/* ArchiveAccess */
#if defined(ARCHIVEACCESS)
struct aaFILETIME
{
uae_u32 dwLowDateTime;
uae_u32 dwHighDateTime;
};
typedef void* aaHandle;
// This struct contains file information from an archive. The caller may store
// this information for accessing this file after calls to findFirst, findNext
#define FileInArchiveInfoStringSize 1024
struct aaFileInArchiveInfo {
int ArchiveHandle; // handle for Archive/class pointer
uae_u64 CompressedFileSize;
uae_u64 UncompressedFileSize;
uae_u32 attributes;
int IsDir;
struct aaFILETIME LastWriteTime;
char path[FileInArchiveInfoStringSize];
};
typedef HRESULT (__stdcall *aaReadCallback)(int StreamID, uae_u64 offset, uae_u32 count, void* buf, uae_u32 *processedSize);
typedef HRESULT (__stdcall *aaWriteCallback)(int StreamID, uae_u64 offset, uae_u32 count, const void *buf, uae_u32 *processedSize);
typedef aaHandle (__stdcall *aapOpenArchive)(aaReadCallback function, int StreamID, uae_u64 FileSize, int ArchiveType, int *result, TCHAR *password);
typedef int (__stdcall *aapGetFileCount)(aaHandle ArchiveHandle);
typedef int (__stdcall *aapGetFileInfo)(aaHandle ArchiveHandle, int FileNum, struct aaFileInArchiveInfo *FileInfo);
typedef int (__stdcall *aapExtract)(aaHandle ArchiveHandle, int FileNum, int StreamID, aaWriteCallback WriteFunc, uae_u64 *written);
typedef int (__stdcall *aapCloseArchive)(aaHandle ArchiveHandle);
static aapOpenArchive aaOpenArchive;
static aapGetFileCount aaGetFileCount;
static aapGetFileInfo aaGetFileInfo;
static aapExtract aaExtract;
static aapCloseArchive aaCloseArchive;
#ifdef _WIN32
static HMODULE arcacc_mod;
static void arcacc_free (void)
{
if (arcacc_mod)
FreeLibrary (arcacc_mod);
arcacc_mod = NULL;
}
static int arcacc_init (struct zfile *zf)
{
if (arcacc_mod)
return 1;
arcacc_mod = WIN32_LoadLibrary (L"archiveaccess.dll");
if (!arcacc_mod) {
write_log (L"failed to open archiveaccess.dll ('%s')\n", zfile_getname (zf));
return 0;
}
aaOpenArchive = (aapOpenArchive) GetProcAddress (arcacc_mod, "aaOpenArchive");
aaGetFileCount = (aapGetFileCount) GetProcAddress (arcacc_mod, "aaGetFileCount");
aaGetFileInfo = (aapGetFileInfo) GetProcAddress (arcacc_mod, "aaGetFileInfo");
aaExtract = (aapExtract) GetProcAddress (arcacc_mod, "aaExtract");
aaCloseArchive = (aapCloseArchive) GetProcAddress (arcacc_mod, "aaCloseArchive");
if (!aaOpenArchive || !aaGetFileCount || !aaGetFileInfo || !aaExtract || !aaCloseArchive) {
write_log (L"Missing functions in archiveaccess.dll. Old version?\n");
arcacc_free ();
return 0;
}
return 1;
}
#endif
#define ARCACC_STACKSIZE 10
static struct zfile *arcacc_stack[ARCACC_STACKSIZE];
static int arcacc_stackptr = -1;
static int arcacc_push (struct zfile *f)
{
if (arcacc_stackptr == ARCACC_STACKSIZE - 1)
return -1;
arcacc_stackptr++;
arcacc_stack[arcacc_stackptr] = f;
return arcacc_stackptr;
}
static void arcacc_pop (void)
{
arcacc_stackptr--;
}
static HRESULT __stdcall readCallback (int StreamID, uae_u64 offset, uae_u32 count, void *buf, uae_u32 *processedSize)
{
struct zfile *f = arcacc_stack[StreamID];
int ret;
zfile_fseek (f, (long)offset, SEEK_SET);
ret = zfile_fread (buf, 1, count, f);
if (processedSize)
*processedSize = ret;
return 0;
}
static HRESULT __stdcall writeCallback (int StreamID, uae_u64 offset, uae_u32 count, const void *buf, uae_u32 *processedSize)
{
struct zfile *f = arcacc_stack[StreamID];
int ret;
ret = zfile_fwrite ((void*)buf, 1, count, f);
if (processedSize)
*processedSize = ret;
if (ret != count)
return -1;
return 0;
}
struct zvolume *archive_directory_arcacc (struct zfile *z, unsigned int id)
{
aaHandle ah;
int id_r, status;
int fc, f;
struct zvolume *zv;
int skipsize = 0;
if (!arcacc_init (z))
return NULL;
zv = zvolume_alloc (z, ArchiveFormatAA, NULL, NULL);
id_r = arcacc_push (z);
ah = aaOpenArchive (readCallback, id_r, zv->archivesize, id, &status, NULL);
if (!status) {
zv->handle = ah;
fc = aaGetFileCount (ah);
for (f = 0; f < fc; f++) {
struct aaFileInArchiveInfo fi;
TCHAR *name;
struct znode *zn;
struct zarchive_info zai;
memset (&fi, 0, sizeof (fi));
aaGetFileInfo (ah, f, &fi);
if (fi.IsDir)
continue;
name = au (fi.path);
memset (&zai, 0, sizeof zai);
zai.name = name;
zai.flags = -1;
zai.size = (unsigned int)fi.UncompressedFileSize;
zn = zvolume_addfile_abs (zv, &zai);
xfree (name);
zn->offset = f;
zn->method = id;
if (id == ArchiveFormat7Zip) {
if (fi.CompressedFileSize)
skipsize = 0;
skipsize += (int)fi.UncompressedFileSize;
}
}
aaCloseArchive (ah);
}
arcacc_pop ();
zv->method = ArchiveFormatAA;
return zv;
}
static struct zfile *archive_access_arcacc (struct znode *zn)
{
struct zfile *zf;
struct zfile *z = zn->volume->archive;
int status, id_r, id_w;
aaHandle ah;
int ok = 0;
id_r = arcacc_push (z);
ah = aaOpenArchive (readCallback, id_r, zn->volume->archivesize, zn->method, &status, NULL);
if (!status) {
int err;
uae_u64 written = 0;
struct aaFileInArchiveInfo fi;
memset (&fi, 0, sizeof (fi));
aaGetFileInfo (ah, zn->offset, &fi);
zf = zfile_fopen_empty (z, zn->fullname, zn->size);
id_w = arcacc_push (zf);
err = aaExtract(ah, zn->offset, id_w, writeCallback, &written);
if (zf->seek == fi.UncompressedFileSize)
ok = 1;
arcacc_pop();
}
aaCloseArchive(ah);
arcacc_pop();
if (ok)
return zf;
zfile_fclose(zf);
return NULL;
}
#endif
/* plain single file */
static struct znode *addfile (struct zvolume *zv, struct zfile *zf, const TCHAR *path, uae_u8 *data, int size)
{
struct zarchive_info zai;
struct znode *zn;
struct zfile *z;
z = zfile_fopen_empty (zf, path, size);
zfile_fwrite (data, size, 1, z);
memset (&zai, 0, sizeof zai);
zai.name = my_strdup (path);
zai.flags = -1;
zai.size = size;
zn = zvolume_addfile_abs (zv, &zai);
if (zn)
zn->f = z;
else
zfile_fclose (z);
xfree (zai.name);
return zn;
}
static uae_u8 exeheader[]={0x00,0x00,0x03,0xf3,0x00,0x00,0x00,0x00};
struct zvolume *archive_directory_plain (struct zfile *z)
{
struct zfile *zf, *zf2;
struct zvolume *zv;
struct znode *zn;
struct zarchive_info zai;
uae_u8 id[8];
int rc, index;
memset (&zai, 0, sizeof zai);
zv = zvolume_alloc (z, ArchiveFormatPLAIN, NULL, NULL);
memset(id, 0, sizeof id);
zai.name = zfile_getfilename (z);
zai.flags = -1;
zfile_fseek(z, 0, SEEK_END);
zai.size = zfile_ftell (z);
zai.t =
zfile_fseek(z, 0, SEEK_SET);
zfile_fread(id, sizeof id, 1, z);
zfile_fseek(z, 0, SEEK_SET);
zn = zvolume_addfile_abs (zv, &zai);
if (!memcmp (id, exeheader, sizeof id)) {
char *an = ua (zai.name);
char *data = xmalloc (char, 1 + strlen (an) + 1 + 1 + 1);
sprintf (data, "\"%s\"\n", an);
zn = addfile (zv, z, L"s/startup-sequence", (uae_u8*)data, strlen (data));
xfree (data);
xfree (an);
}
index = 0;
for (;;) {
zf = zfile_dup (z);
if (!zf)
break;
zf2 = zuncompress (NULL, zf, 0, ZFD_ALL & ~ZFD_ADF, &rc, index);
if (zf2) {
zf = NULL;
zai.name = zfile_getfilename (zf2);
zai.flags = -1;
zfile_fseek (zf2, 0, SEEK_END);
zai.size = zfile_ftell (zf2);
zfile_fseek (zf2, 0, SEEK_SET);
zn = zvolume_addfile_abs (zv, &zai);
zn->f = zf2;
// if (zn)
// zn->offset = index + 1;
// zfile_fclose (zf2);
} else {
if (rc == 0) {
zfile_fclose (zf);
break;
}
}
index++;
zfile_fclose (zf);
}
return zv;
}
static struct zfile *archive_access_plain (struct znode *zn)
{
struct zfile *z;
if (zn->offset) {
struct zfile *zf;
z = zfile_fopen_empty (zn->volume->archive, zn->fullname, zn->size);
zf = zfile_fopen2 (zfile_getname (zn->volume->archive), L"rb", zn->volume->archive->zfdmask & ~ZFD_ADF, zn->offset - 1);
if (zf) {
zfile_fread (z->data, zn->size, 1, zf);
zfile_fclose (zf);
}
} else {
z = zfile_fopen_empty (zn->volume->archive, zn->fullname, zn->size);
if (z) {
zfile_fseek (zn->volume->archive, 0, SEEK_SET);
zfile_fread (z->data, zn->size, 1, zn->volume->archive);
}
}
return z;
}
struct adfhandle {
int size;
int highblock;
int blocksize;
int rootblock;
struct zfile *z;
uae_u8 block[65536];
uae_u32 dostype;
};
static int dos_checksum (uae_u8 *p, int blocksize)
{
uae_u32 cs = 0;
int i;
for (i = 0; i < blocksize; i += 4)
cs += (p[i] << 24) | (p[i + 1] << 16) | (p[i + 2] << 8) | (p[i + 3] << 0);
return cs;
}
static int sfs_checksum (uae_u8 *p, int blocksize, int sfs2)
{
uae_u32 cs = sfs2 ? 2 : 1;
int i;
for (i = 0; i < blocksize; i += 4)
cs += (p[i] << 24) | (p[i + 1] << 16) | (p[i + 2] << 8) | (p[i + 3] << 0);
return cs;
}
static TCHAR *getBSTR (uae_u8 *bstr)
{
int n = *bstr++;
uae_char buf[257];
int i;
for (i = 0; i < n; i++)
buf[i] = *bstr++;
buf[i] = 0;
return au (buf);
}
static uae_u32 gl (struct adfhandle *adf, int off)
{
uae_u8 *p = adf->block + off;
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
}
static uae_u32 glx (uae_u8 *p)
{
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
}
static uae_u32 gwx (uae_u8 *p)
{
return (p[0] << 8) | (p[1] << 0);
}
static const int secs_per_day = 24 * 60 * 60;
static const int diff = (8 * 365 + 2) * (24 * 60 * 60);
static const int diff2 = (-8 * 365 - 2) * (24 * 60 * 60);
static time_t put_time (long days, long mins, long ticks)
{
time_t t;
if (days < 0)
days = 0;
if (days > 9900 * 365)
days = 9900 * 365; // in future far enough?
if (mins < 0 || mins >= 24 * 60)
mins = 0;
if (ticks < 0 || ticks >= 60 * 50)
ticks = 0;
t = ticks / 50;
t += mins * 60;
t += ((uae_u64)days) * secs_per_day;
t += diff;
return t;
}
static int adf_read_block (struct adfhandle *adf, int block)
{
memset (adf->block, 0, adf->blocksize);
if (block >= adf->highblock || block < 0)
return 0;
zfile_fseek (adf->z, block * adf->blocksize, SEEK_SET);
zfile_fread (adf->block, adf->blocksize, 1, adf->z);
return 1;
}
static void recurseadf (struct znode *zn, int root, TCHAR *name)
{
int i;
struct zvolume *zv = zn->volume;
struct adfhandle *adf = (struct adfhandle*)zv->handle;
TCHAR name2[MAX_DPATH];
int bs = adf->blocksize;
for (i = 0; i < bs / 4 - 56; i++) {
int block;
if (!adf_read_block (adf, root))
return;
block = gl (adf, (i + 6) * 4);
while (block > 0 && block < adf->size / bs) {
struct zarchive_info zai;
TCHAR *fname;
uae_u32 size, secondary;
if (!adf_read_block (adf, block))
return;
if (gl (adf, 0) != 2)
break;
if (gl (adf, 1 * 4) != block)
break;
secondary = gl (adf, bs - 1 * 4);
if (secondary != -3 && secondary != 2)
break;
memset (&zai, 0, sizeof zai);
fname = getBSTR (adf->block + bs - 20 * 4);
size = gl (adf, bs - 47 * 4);
name2[0] = 0;
if (name[0]) {
TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
_tcscpy (name2, name);
_tcscat (name2, sep);
}
_tcscat (name2, fname);
zai.name = name2;
if (size < 0 || size > 0x7fffffff)
size = 0;
zai.size = size;
zai.flags = gl (adf, bs - 48 * 4);
zai.t = put_time (gl (adf, bs - 23 * 4), gl (adf, bs - 22 * 4),gl (adf, bs - 21 * 4));
if (secondary == -3) {
struct znode *znnew = zvolume_addfile_abs (zv, &zai);
znnew->offset = block;
} else {
struct znode *znnew = zvolume_adddir_abs (zv, &zai);
znnew->offset = block;
recurseadf (znnew, block, name2);
if (!adf_read_block (adf, block))
return;
}
xfree (fname);
block = gl (adf, bs - 4 * 4);
}
}
}
static void recursesfs (struct znode *zn, int root, TCHAR *name, int sfs2)
{
struct zvolume *zv = zn->volume;
struct adfhandle *adf = (struct adfhandle*)zv->handle;
TCHAR name2[MAX_DPATH];
int bs = adf->blocksize;
int block;
uae_u8 *p, *s;
struct zarchive_info zai;
block = root;
while (block) {
if (!adf_read_block (adf, block))
return;
p = adf->block + 12 + 3 * 4;
while (glx (p + 4) && p < adf->block + adf->blocksize - 27) {
TCHAR *fname;
int i;
int align;
memset (&zai, 0, sizeof zai);
zai.flags = glx (p + 8) ^ 0x0f;
s = p + (sfs2 ? 27 : 25);
fname = au ((char*)s);
i = 0;
while (*s) {
s++;
i++;
}
s++;
i++;
if (*s)
zai.comment = au ((char*)s);
while (*s) {
s++;
i++;
}
s++;
i++;
i += sfs2 ? 27 : 25;
align = i & 1;
name2[0] = 0;
if (name[0]) {
TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
_tcscpy (name2, name);
_tcscat (name2, sep);
}
_tcscat (name2, fname);
zai.name = name2;
if (sfs2)
zai.t = glx (p + 22) - diff2;
else
zai.t = glx (p + 20) - diff;
if (p[sfs2 ? 26 : 24] & 0x80) { // dir
struct znode *znnew = zvolume_adddir_abs (zv, &zai);
int newblock = glx (p + 16);
if (newblock) {
znnew->offset = block;
recursesfs (znnew, newblock, name2, sfs2);
}
if (!adf_read_block (adf, block))
return;
} else {
struct znode *znnew;
if (sfs2) {
uae_u64 b1 = p[16];
uae_u64 b2 = p[17];
zai.size = (b1 << 40) | (b2 << 32) | glx (p + 18) ;
} else {
zai.size = glx (p + 16);
}
znnew = zvolume_addfile_abs (zv, &zai);
znnew->offset = block;
znnew->offset2 = p - adf->block;
}
xfree (zai.comment);
xfree (fname);
p += i + align;
}
block = gl (adf, 12 + 4);
}
}
struct zvolume *archive_directory_adf (struct znode *parent, struct zfile *z)
{
struct zvolume *zv;
struct adfhandle *adf;
TCHAR *volname = NULL;
TCHAR name[MAX_DPATH];
int gotroot = 0;
adf = xcalloc (struct adfhandle, 1);
zfile_fseek (z, 0, SEEK_END);
adf->size = zfile_ftell (z);
zfile_fseek (z, 0, SEEK_SET);
adf->blocksize = 512;
if (parent && parent->offset2) {
if (parent->offset2 == 1024 || parent->offset2 == 2048 || parent->offset2 == 4096 || parent->offset2 == 8192 ||
parent->offset2 == 16384 || parent->offset2 == 32768 || parent->offset2 == 65536) {
adf->blocksize = parent->offset2;
gotroot = 1;
}
}
adf->highblock = adf->size / adf->blocksize;
adf->z = z;
if (!adf_read_block (adf, 0))
goto fail;
adf->dostype = gl (adf, 0);
if ((adf->dostype & 0xffffff00) == 'DOS\0') {
int bs = adf->blocksize;
int res;
adf->rootblock = ((adf->size / bs) - 1 + 2) / 2;
if (!gotroot) {
for (res = 2; res >= 1; res--) {
for (bs = 512; bs < 65536; bs <<= 1) {
adf->blocksize = bs;
adf->rootblock = ((adf->size / bs) - 1 + res) / 2;
if (!adf_read_block (adf, adf->rootblock))
continue;
if (gl (adf, 0) != 2 || gl (adf, bs - 1 * 4) != 1)
continue;
if (dos_checksum (adf->block, bs) != 0)
continue;
gotroot = 1;
break;
}
if (gotroot)
break;
}
}
if (!gotroot) {
bs = adf->blocksize = 512;
if (adf->size < 2000000 && adf->rootblock != 880) {
adf->rootblock = 880;
if (!adf_read_block (adf, adf->rootblock))
goto fail;
if (gl (adf, 0) != 2 || gl (adf, bs - 1 * 4) != 1)
goto fail;
if (dos_checksum (adf->block, bs) != 0)
goto fail;
}
}
if (!adf_read_block (adf, adf->rootblock))
goto fail;
if (gl (adf, 0) != 2 || gl (adf, bs - 1 * 4) != 1)
goto fail;
if (dos_checksum (adf->block, adf->blocksize) != 0)
goto fail;
adf->blocksize = bs;
adf->highblock = adf->size / adf->blocksize;
volname = getBSTR (adf->block + adf->blocksize - 20 * 4);
zv = zvolume_alloc (z, ArchiveFormatADF, NULL, NULL);
zv->method = ArchiveFormatADF;
zv->handle = adf;
name[0] = 0;
recurseadf (&zv->root, adf->rootblock, name);
} else if ((adf->dostype & 0xffffff00) == 'SFS\0') {
uae_u16 version, sfs2;
for (;;) {
for (;;) {
version = gl (adf, 12) >> 16;
sfs2 = version > 3;
if (version > 4)
break;
adf->rootblock = gl (adf, 104);
if (!adf_read_block (adf, adf->rootblock))
break;
if (gl (adf, 0) != 'OBJC')
break;
if (sfs_checksum (adf->block, adf->blocksize, sfs2))
break;
adf->rootblock = gl (adf, 40);
if (!adf_read_block (adf, adf->rootblock))
break;
if (gl (adf, 0) != 'OBJC')
break;
if (sfs_checksum (adf->block, adf->blocksize, sfs2))
break;
gotroot = 1;
break;
}
if (gotroot)
break;
adf->blocksize <<= 1;
if (adf->blocksize == 65536)
break;
}
if (!gotroot)
goto fail;
zv = zvolume_alloc (z, ArchiveFormatADF, NULL, NULL);
zv->method = ArchiveFormatADF;
zv->handle = adf;
name[0] = 0;
recursesfs (&zv->root, adf->rootblock, name, version > 3);
} else {
goto fail;
}
xfree (volname);
return zv;
fail:
xfree (adf);
return NULL;
}
struct sfsblock
{
int block;
int length;
};
static int sfsfindblock (struct adfhandle *adf, int btree, int theblock, struct sfsblock **sfsb, int *sfsblockcnt, int *sfsmaxblockcnt, int sfs2)
{
int nodecount, isleaf, nodesize;
int i;
uae_u8 *p;
if (!btree)
return 0;
if (!adf_read_block (adf, btree))
return 0;
if (memcmp (adf->block, "BNDC", 4))
return 0;
nodecount = gwx (adf->block + 12);
isleaf = adf->block[14];
nodesize = adf->block[15];
p = adf->block + 16;
for (i = 0; i < nodecount; i++) {
if (isleaf) {
uae_u32 key = glx (p);
uae_u32 next = glx (p + 4);
uae_u32 prev = glx (p + 8);
uae_u32 blocks;
if (sfs2)
blocks = glx (p + 12);
else
blocks = gwx (p + 12);
if (key == theblock) {
struct sfsblock *sb;
if (*sfsblockcnt >= *sfsmaxblockcnt) {
*sfsmaxblockcnt += 100;
*sfsb = xrealloc (struct sfsblock, *sfsb, *sfsmaxblockcnt);
}
sb = *sfsb + (*sfsblockcnt);
sb->block = key;
sb->length = blocks;
(*sfsblockcnt)++;
return next;
}
} else {
uae_u32 key = glx (p);
uae_u32 data = glx (p + 4);
int newblock = sfsfindblock (adf, data, theblock, sfsb, sfsblockcnt, sfsmaxblockcnt, sfs2);
if (newblock)
return newblock;
if (!adf_read_block (adf, btree))
return 0;
if (memcmp (adf->block, "BNDC", 4))
return 0;
}
p += nodesize;
}
return 0;
}
static struct zfile *archive_access_adf (struct znode *zn)
{
struct zfile *z = NULL;
int root, ffs;
struct adfhandle *adf = (struct adfhandle*)zn->volume->handle;
int size, bs;
int i;
uae_u8 *dst;
size = zn->size;
bs = adf->blocksize;
z = zfile_fopen_empty (zn->volume->archive, zn->fullname, size);
if (!z)
return NULL;
if ((adf->dostype & 0xffffff00) == 'DOS\0') {
ffs = adf->dostype & 1;
root = zn->offset;
dst = z->data;
for (;;) {
adf_read_block (adf, root);
for (i = bs / 4 - 51; i >= 6; i--) {
int bsize = ffs ? bs : bs - 24;
int block = gl (adf, i * 4);
if (size < bsize)
bsize = size;
if (ffs)
zfile_fseek (adf->z, block * adf->blocksize, SEEK_SET);
else
zfile_fseek (adf->z, block * adf->blocksize + 24, SEEK_SET);
zfile_fread (dst, bsize, 1, adf->z);
size -= bsize;
dst += bsize;
if (size <= 0)
break;
}
if (size <= 0)
break;
root = gl (adf, bs - 2 * 4);
}
} else if ((adf->dostype & 0xffffff00) == 'SFS\0') {
struct sfsblock *sfsblocks;
int sfsblockcnt, sfsmaxblockcnt, i;
int bsize;
int block = zn->offset;
int dblock;
int btree, version, sfs2;
uae_u8 *p;
if (!adf_read_block (adf, 0))
goto end;
btree = glx (adf->block + 108);
version = gwx (adf->block + 12);
sfs2 = version > 3;
if (!adf_read_block (adf, block))
goto end;
p = adf->block + zn->offset2;
dblock = glx (p + 12);
sfsblockcnt = 0;
sfsmaxblockcnt = 0;
sfsblocks = NULL;
if (size > 0) {
int nextblock = dblock;
while (nextblock) {
nextblock = sfsfindblock (adf, btree, nextblock, &sfsblocks, &sfsblockcnt, &sfsmaxblockcnt, sfs2);
}
}
bsize = 0;
for (i = 0; i < sfsblockcnt; i++)
bsize += sfsblocks[i].length * adf->blocksize;
if (bsize < size)
write_log (L"SFS extracting error, %s size mismatch %d<%d\n", z->name, bsize, size);
dst = z->data;
block = zn->offset;
for (i = 0; i < sfsblockcnt; i++) {
block = sfsblocks[i].block;
bsize = sfsblocks[i].length * adf->blocksize;
zfile_fseek (adf->z, block * adf->blocksize, SEEK_SET);
if (bsize > size)
bsize = size;
zfile_fread (dst, bsize, 1, adf->z);
dst += bsize;
size -= bsize;
}
xfree (sfsblocks);
}
return z;
end:
zfile_fclose (z);
return NULL;
}
static void archive_close_adf (void *v)
{
struct adfhandle *adf = (struct adfhandle*)v;
xfree (adf);
}
static int rl (uae_u8 *p)
{
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]);
}
static TCHAR *tochar (uae_u8 *s, int len)
{
int i, j;
uae_char tmp[256];
j = 0;
for (i = 0; i < len; i++) {
uae_char c = *s++;
if (c >= 0 && c <= 9) {
tmp[j++] = '\\';
tmp[j++] = '0' + c;
} else if (c < ' ' || c > 'z') {
tmp[j++] = '.';
} else {
tmp[j++] = c;
}
tmp[j] = 0;
}
return au (tmp);
}
struct zvolume *archive_directory_rdb (struct zfile *z)
{
uae_u8 buf[512] = { 0 };
int partnum, bs;
TCHAR *devname;
struct zvolume *zv;
struct zarchive_info zai;
uae_u8 *p;
struct znode *zn;
zv = zvolume_alloc (z, ArchiveFormatRDB, NULL, NULL);
zfile_fseek (z, 0, SEEK_SET);
zfile_fread (buf, 1, 512, z);
partnum = 0;
for (;;) {
int partblock;
TCHAR tmp[MAX_DPATH];
int surf, spt, spb, lowcyl, highcyl, reserved;
int size, block, blocksize, rootblock;
TCHAR comment[81], *dos;
if (partnum == 0)
partblock = rl (buf + 28);
else
partblock = rl (buf + 4 * 4);
partnum++;
if (partblock <= 0)
break;
zfile_fseek (z, partblock * 512, SEEK_SET);
zfile_fread (buf, 1, 512, z);
if (memcmp (buf, "PART", 4))
break;
p = buf + 128 - 16;
surf = rl (p + 28);
spb = rl (p + 32);
spt = rl (p + 36);
reserved = rl (p + 40);
lowcyl = rl (p + 52);
highcyl = rl (p + 56);
blocksize = rl (p + 20) * 4 * spb;
block = lowcyl * surf * spt;
size = (highcyl - lowcyl + 1) * surf * spt;
size *= blocksize;
dos = tochar (buf + 192, 4);
if (!memcmp (dos, L"DOS", 3))
rootblock = ((size / blocksize) - 1 + 2) / 2;
else
rootblock = 0;
devname = getBSTR (buf + 36);
_stprintf (tmp, L"%s.hdf", devname);
memset (&zai, 0, sizeof zai);
_stprintf (comment, L"FS=%s LO=%d HI=%d HEADS=%d SPT=%d RES=%d BLOCK=%d ROOT=%d",
dos, lowcyl, highcyl, surf, spt, reserved, blocksize, rootblock);
zai.comment = comment;
xfree (dos);
zai.name = tmp;
zai.size = size;
zai.flags = -1;
zn = zvolume_addfile_abs (zv, &zai);
zn->offset = partblock;
zn->offset2 = blocksize; // rp?
}
zfile_fseek (z, 0, SEEK_SET);
p = buf;
zfile_fread (buf, 1, 512, z);
zai.name = L"rdb_dump.dat";
bs = rl (p + 16);
zai.size = rl (p + 140) * bs;
zai.comment = NULL;
zn = zvolume_addfile_abs (zv, &zai);
zn->offset = 0;
zv->method = ArchiveFormatRDB;
return zv;
}
static struct zfile *archive_access_rdb (struct znode *zn)
{
struct zfile *z = zn->volume->archive;
struct zfile *zf;
uae_u8 buf[512] = { 0 };
int surf, spb, spt, lowcyl, highcyl;
int size, block, blocksize;
uae_u8 *p;
if (zn->offset) {
zfile_fseek (z, zn->offset * 512, SEEK_SET);
zfile_fread (buf, 1, 512, z);
p = buf + 128 - 16;
surf = rl (p + 28);
spb = rl (p + 32);
spt = rl (p + 36);
lowcyl = rl (p + 52);
highcyl = rl (p + 56);
blocksize = rl (p + 20) * 4;
block = lowcyl * surf * spt;
size = (highcyl - lowcyl + 1) * surf * spt;
size *= blocksize;
} else {
zfile_fseek (z, 0, SEEK_SET);
zfile_fread (buf, 1, 512, z);
p = buf;
blocksize = rl (p + 16);
block = 0;
size = zn->size;
}
zf = zfile_fopen_parent (z, zn->fullname, block * blocksize, size);
return zf;
}
int isfat (uae_u8 *p)
{
int i, b;
if ((p[0x15] & 0xf0) != 0xf0)
return 0;
if (p[0x0b] != 0x00 || p[0x0c] != 0x02)
return 0;
b = 0;
for (i = 0; i < 8; i++) {
if (p[0x0d] & (1 << i))
b++;
}
if (b != 1)
return 0;
if (p[0x0f] != 0)
return 0;
if (p[0x0e] > 8 || p[0x0e] == 0)
return 0;
if (p[0x10] == 0 || p[0x10] > 8)
return 0;
b = (p[0x12] << 8) | p[0x11];
if (b > 8192 || b <= 0)
return 0;
b = p[0x16] | (p[0x17] << 8);
if (b == 0 || b > 8192)
return 0;
return 1;
}
/*
* The epoch of FAT timestamp is 1980.
* : bits : value
* date: 0 - 4: day (1 - 31)
* date: 5 - 8: month (1 - 12)
* date: 9 - 15: year (0 - 127) from 1980
* time: 0 - 4: sec (0 - 29) 2sec counts
* time: 5 - 10: min (0 - 59)
* time: 11 - 15: hour (0 - 23)
*/
#define SECS_PER_MIN 60
#define SECS_PER_HOUR (60 * 60)
#define SECS_PER_DAY (SECS_PER_HOUR * 24)
#define UNIX_SECS_1980 315532800L
#if BITS_PER_LONG == 64
#define UNIX_SECS_2108 4354819200L
#endif
/* days between 1.1.70 and 1.1.80 (2 leap days) */
#define DAYS_DELTA (365 * 10 + 2)
/* 120 (2100 - 1980) isn't leap year */
#define YEAR_2100 120
#define IS_LEAP_YEAR(y) (!((y) & 3) && (y) != YEAR_2100)
/* Linear day numbers of the respective 1sts in non-leap years. */
static time_t days_in_year[] = {
/* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */
0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0,
};
/* Convert a FAT time/date pair to a UNIX date (seconds since 1 1 70). */
static time_t fat_time_fat2unix (uae_u16 time, uae_u16 date, int fat12)
{
time_t second, day, leap_day, month, year;
if (0 && fat12) {
year = date & 0x7f;
month = (date >> 7) & 0x0f;
day = (date >> 11);
} else {
year = date >> 9;
month = max(1, (date >> 5) & 0xf);
day = max(1, date & 0x1f) - 1;
}
leap_day = (year + 3) / 4;
if (year > YEAR_2100) /* 2100 isn't leap year */
leap_day--;
if (IS_LEAP_YEAR(year) && month > 2)
leap_day++;
second = (time & 0x1f) << 1;
second += ((time >> 5) & 0x3f) * SECS_PER_MIN;
second += (time >> 11) * SECS_PER_HOUR;
second += (year * 365 + leap_day
+ days_in_year[month] + day
+ DAYS_DELTA) * SECS_PER_DAY;
return second;
}
static int getcluster (struct zfile *z, int cluster, int fatstart, int fatbits)
{
uae_u32 fat = 0;
uae_u8 p[4];
int offset = cluster * fatbits;
zfile_fseek (z, fatstart * 512 + offset / 8, SEEK_SET);
if (fatbits == 12) {
zfile_fread (p, 2, 1, z);
if ((offset & 4))
fat = ((p[0] & 0xf0) >> 4) | (p[1] << 4);
else
fat = (p[0]) | ((p[1] & 0x0f) << 8);
if (fat >= 0xff0)
return -1;
} else if (fatbits == 16) {
zfile_fread (p, 2, 1, z);
fat = p[0] | (p[1] << 8);
if (fat >= 0xfff0)
return -1;
} else if (fatbits == 32) {
zfile_fread (p, 4, 1, z);
fat = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
fat &= ~0x0fffffff;
if (fat >= 0x0ffffff0)
return -1;
}
return fat;
}
static void fatdirectory (struct zfile *z, struct zvolume *zv, TCHAR *name, int startblock, int entries, int sectorspercluster, int fatstart, int dataregion, int fatbits)
{
struct zarchive_info zai;
struct znode *znnew;
int i, j;
for (i = 0; i < entries; i++) {
TCHAR name2[MAX_DPATH], *fname;
uae_s64 size;
uae_u8 fatname[16];
uae_u8 buf[32];
int attr, cnt, ext;
int startcluster;
memset (buf, 0, sizeof buf);
memset (&zai, 0, sizeof zai);
zfile_fseek (z, startblock * 512 + i * 32, SEEK_SET);
zfile_fread (buf, 32, 1, z);
if (buf[0] == 0)
break;
if (buf[0] == 0xe5)
continue;
if (buf[0] == 0x05)
buf[0] = 0xe5;
size = buf[0x1c] | (buf[0x1d] << 8) | (buf[0x1e] << 16) | (buf[0x1f] << 24);
attr = buf[0x0b];
startcluster = buf[0x1a] | (buf[0x1b] << 8);
if ((attr & (0x4 | 0x2)) == 0x06) // system+hidden
continue;
if (attr & 8) // disk name
continue;
if (attr & 1) // read-only
zai.flags |= 1 << 3;
if (!(attr & 32)) // archive
zai.flags |= 1 << 4;
cnt = 0;
ext = 0;
for (j = 0; j < 8 && buf[j] != 0x20 && buf[j] != 0; j++)
fatname[cnt++] = buf[j];
for (j = 0; j < 3 && buf[8 + j] != 0x20 && buf[8 + j] != 0; j++) {
if (ext == 0)
fatname[cnt++] = '.';
ext = 1;
fatname[cnt++] = buf[8 + j];
}
fatname[cnt] = 0;
fname = au ((char*)fatname);
name2[0] = 0;
if (name[0]) {
TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
_tcscpy (name2, name);
_tcscat (name2, sep);
}
_tcscat (name2, fname);
zai.name = name2;
zai.t = fat_time_fat2unix (buf[0x16] | (buf[0x17] << 8), buf[0x18] | (buf[0x19] << 8), 1);
if (attr & (16 | 8)) {
int nextblock, cluster;
nextblock = dataregion + (startcluster - 2) * sectorspercluster;
cluster = getcluster (z, startcluster, fatstart, fatbits);
if ((cluster < 0 || cluster >= 3) && nextblock != startblock) {
znnew = zvolume_adddir_abs (zv, &zai);
fatdirectory (z, zv, name2, nextblock, sectorspercluster * 512 / 32, sectorspercluster, fatstart, dataregion, fatbits);
while (cluster >= 3) {
nextblock = dataregion + (cluster - 2) * sectorspercluster;
fatdirectory (z, zv, name2, nextblock, sectorspercluster * 512 / 32, sectorspercluster, fatstart, dataregion, fatbits);
cluster = getcluster (z, cluster, fatstart, fatbits);
}
}
} else {
zai.size = size;
znnew = zvolume_addfile_abs (zv, &zai);
znnew->offset = startcluster;
}
xfree (fname);
}
}
struct zvolume *archive_directory_fat (struct zfile *z)
{
uae_u8 buf[512] = { 0 };
int fatbits = 12;
struct zvolume *zv;
int rootdir, reserved, sectorspercluster;
int numfats, sectorsperfat, rootentries;
int dataregion;
zfile_fseek (z, 0, SEEK_SET);
zfile_fread (buf, 1, 512, z);
if (!isfat (buf))
return NULL;
reserved = buf[0x0e] | (buf[0x0f] << 8);
numfats = buf[0x10];
sectorsperfat = buf[0x16] | (buf[0x17] << 8);
rootentries = buf[0x11] | (buf[0x12] << 8);
sectorspercluster = buf[0x0d];
rootdir = reserved + numfats * sectorsperfat;
dataregion = rootdir + rootentries * 32 / 512;
zv = zvolume_alloc (z, ArchiveFormatFAT, NULL, NULL);
fatdirectory (z, zv, L"", rootdir, rootentries, sectorspercluster, reserved, dataregion, fatbits);
zv->method = ArchiveFormatFAT;
return zv;
}
static struct zfile *archive_access_fat (struct znode *zn)
{
uae_u8 buf[512] = { 0 };
int fatbits = 12;
int size = zn->size;
struct zfile *sz, *dz;
int rootdir, reserved, sectorspercluster;
int numfats, sectorsperfat, rootentries;
int dataregion;
int offset, cluster;
sz = zn->volume->archive;
zfile_fseek (sz, 0, SEEK_SET);
zfile_fread (buf, 1, 512, sz);
if (!isfat (buf))
return NULL;
reserved = buf[0x0e] | (buf[0x0f] << 8);
numfats = buf[0x10];
sectorsperfat = buf[0x16] | (buf[0x17] << 8);
rootentries = buf[0x11] | (buf[0x12] << 8);
sectorspercluster = buf[0x0d];
rootdir = reserved + numfats * sectorsperfat;
dataregion = rootdir + rootentries * 32 / 512;
dz = zfile_fopen_empty (sz, zn->fullname, size);
if (!dz)
return NULL;
offset = 0;
cluster = zn->offset;
while (size && cluster >= 2) {
int left = size > sectorspercluster * 512 ? sectorspercluster * 512 : size;
int sector = dataregion + (cluster - 2) * sectorspercluster;
zfile_fseek (sz, sector * 512, SEEK_SET);
zfile_fread (dz->data + offset, 1, left, sz);
size -= left;
offset += left;
cluster = getcluster (sz, cluster, reserved, fatbits);
}
return dz;
}
void archive_access_close (void *handle, unsigned int id)
{
switch (id)
{
case ArchiveFormatZIP:
archive_close_zip (handle);
break;
case ArchiveFormat7Zip:
archive_close_7z (handle);
break;
case ArchiveFormatRAR:
archive_close_rar (handle);
break;
case ArchiveFormatLHA:
break;
case ArchiveFormatADF:
archive_close_adf (handle);
break;
case ArchiveFormatTAR:
archive_close_tar (handle);
break;
}
}
static struct zfile *archive_access_dir (struct znode *zn)
{
return zfile_fopen (zn->fullname, L"rb", 0);
}
struct zfile *archive_unpackzfile (struct zfile *zf)
{
struct zfile *zout = NULL;
if (!zf->archiveparent)
return NULL;
unpack_log (L"delayed unpack '%s'\n", zf->name);
zf->datasize = zf->size;
switch (zf->archiveid)
{
case ArchiveFormatZIP:
zout = archive_unpack_zip (zf);
break;
}
zfile_fclose (zf->archiveparent);
zf->archiveparent = NULL;
zf->archiveid = 0;
return NULL;
}
struct zfile *archive_getzfile (struct znode *zn, unsigned int id, int flags)
{
struct zfile *zf = NULL;
switch (id)
{
case ArchiveFormatZIP:
zf = archive_access_zip (zn, flags);
break;
case ArchiveFormat7Zip:
zf = archive_access_7z (zn);
break;
case ArchiveFormatRAR:
zf = archive_access_rar (zn);
break;
case ArchiveFormatLHA:
zf = archive_access_lha (zn);
break;
case ArchiveFormatLZX:
zf = archive_access_lzx (zn);
break;
case ArchiveFormatPLAIN:
zf = archive_access_plain (zn);
break;
case ArchiveFormatADF:
zf = archive_access_adf (zn);
break;
case ArchiveFormatRDB:
zf = archive_access_rdb (zn);
break;
case ArchiveFormatFAT:
zf = archive_access_fat (zn);
break;
case ArchiveFormatDIR:
zf = archive_access_dir (zn);
break;
case ArchiveFormatTAR:
zf = archive_access_tar (zn);
break;
}
if (zf)
zf->archiveid = id;
return zf;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment