syncing 2.3.0

parent 57a72759
PUAE 2.2.1 beta series
PUAE 2.3.0 beta series
============
PUAE tries to continue where E-UAE left off..
PUAE versioning is based on the merged WinUAE version..
......
......@@ -1717,7 +1717,9 @@ AC_CONFIG_LINKS(src/guidep:src/$GUI_DEP)
AC_CONFIG_FILES([Makefile
src/Makefile
src/dms/Makefile
src/archivers/dms/Makefile
src/archivers/lha/Makefile
src/archivers/zip/Makefile
src/caps/Makefile
src/md-generic/Makefile
src/md-i386-gcc/Makefile
......
......@@ -4,7 +4,7 @@ AM_CPPFLAGS += -I$(top_srcdir)/src/include -I$(top_builddir)/src -I$(top_srcdir)
SUBDIRS = \
tools @MACHDEP@ @THREADDEP@ @GFX_DEP@ @SND_DEP@ @JOY_DEP@ @GUI_DEP@ \
@OSDEP@ keymap dms caps
@OSDEP@ keymap archivers/dms archivers/lha archivers/zip caps
DIST_SUBDIRS = \
md-generic md-68k md-i386-gcc md-ppc md-ppc-gcc md-amd64-gcc \
......@@ -14,7 +14,7 @@ DIST_SUBDIRS = \
gui-none gui-beos gui-cocoa gui-gtk gui-muirexx \
od-generic od-amiga od-beos od-linux od-macosx od-win32 \
td-none td-amigaos td-beos td-posix td-sdl td-win32 \
keymap caps dms
keymap caps archivers/dms archivers/lha archivers/zip
BUILT_SOURCES = \
blit.h blitfunc.h blitfunc.c blittable.c \
......@@ -116,7 +116,6 @@ noinst_HEADERS = \
include/uae_malloc.h \
include/uae_string.h \
include/uae_types.h \
include/unzip.h \
include/version.h \
include/writelog.h \
include/xwin.h include/zfile.h include/diskutil.h \
......@@ -136,7 +135,7 @@ uae_SOURCES = \
blitter.c autoconf.c traps.c ersatz.c keybuf.c expansion.c \
diskutil.c zfile.c cfgfile.c picasso96.c inputdevice.c \
gfxutil.c audio.c sinctable.c drawing.c consolehook.c \
native2amiga.c disk.c crc32.c savestate.c unzip.c arcadia.c cdtv.c cd32_fmv.c \
native2amiga.c disk.c crc32.c savestate.c arcadia.c cdtv.c cd32_fmv.c \
uaeexe.c uaelib.c uaeresource.c fdi2raw.c hotkeys.c amax.c \
ar.c driveclick.c enforcer.c misc.c a2065.c gayle.c ncr_scsi.c \
missing.c readcpu.c
......@@ -158,7 +157,9 @@ uae_DEPENDENCIES = \
@GFX_DEP@/libgfxdep.a \
@GUI_DEP@/libguidep.a \
keymap/libkeymap.a \
dms/libdms.a \
archivers/dms/libdms.a \
archivers/lha/liblha.a \
archivers/zip/libzip.a \
caps/libcaps.a \
blitfunc.o blittable.o \
cpustbl.o cpudefs.o \
......@@ -180,7 +181,9 @@ uae_LDADD = \
@GFX_DEP@/libgfxdep.a \
@GUI_DEP@/libguidep.a \
keymap/libkeymap.a \
dms/libdms.a \
archivers/dms/libdms.a \
archivers/lha/liblha.a \
archivers/zip/libzip.a \
caps/libcaps.a \
blitfunc.o blittable.o \
cpustbl.o cpudefs.o \
......
......@@ -83,13 +83,13 @@ am_uae_OBJECTS = main.$(OBJEXT) newcpu.$(OBJEXT) memory.$(OBJEXT) \
inputdevice.$(OBJEXT) gfxutil.$(OBJEXT) audio.$(OBJEXT) \
sinctable.$(OBJEXT) drawing.$(OBJEXT) consolehook.$(OBJEXT) \
native2amiga.$(OBJEXT) disk.$(OBJEXT) crc32.$(OBJEXT) \
savestate.$(OBJEXT) unzip.$(OBJEXT) arcadia.$(OBJEXT) \
cdtv.$(OBJEXT) cd32_fmv.$(OBJEXT) uaeexe.$(OBJEXT) \
uaelib.$(OBJEXT) uaeresource.$(OBJEXT) fdi2raw.$(OBJEXT) \
hotkeys.$(OBJEXT) amax.$(OBJEXT) ar.$(OBJEXT) \
driveclick.$(OBJEXT) enforcer.$(OBJEXT) misc.$(OBJEXT) \
a2065.$(OBJEXT) gayle.$(OBJEXT) ncr_scsi.$(OBJEXT) \
missing.$(OBJEXT) readcpu.$(OBJEXT)
savestate.$(OBJEXT) arcadia.$(OBJEXT) cdtv.$(OBJEXT) \
cd32_fmv.$(OBJEXT) uaeexe.$(OBJEXT) uaelib.$(OBJEXT) \
uaeresource.$(OBJEXT) fdi2raw.$(OBJEXT) hotkeys.$(OBJEXT) \
amax.$(OBJEXT) ar.$(OBJEXT) driveclick.$(OBJEXT) \
enforcer.$(OBJEXT) misc.$(OBJEXT) a2065.$(OBJEXT) \
gayle.$(OBJEXT) ncr_scsi.$(OBJEXT) missing.$(OBJEXT) \
readcpu.$(OBJEXT)
uae_OBJECTS = $(am_uae_OBJECTS)
SCRIPTS = $(dist_noinst_SCRIPTS)
DEFAULT_INCLUDES = -I.@am__isrc@
......@@ -309,7 +309,7 @@ AM_CPPFLAGS = @UAE_CPPFLAGS@ -I$(top_srcdir)/src/include \
-I$(top_builddir)/src -I$(top_srcdir)/src -I$(top_srcdir)
SUBDIRS = \
tools @MACHDEP@ @THREADDEP@ @GFX_DEP@ @SND_DEP@ @JOY_DEP@ @GUI_DEP@ \
@OSDEP@ keymap dms caps
@OSDEP@ keymap archivers/dms archivers/lha archivers/zip caps
DIST_SUBDIRS = \
md-generic md-68k md-i386-gcc md-ppc md-ppc-gcc md-amd64-gcc \
......@@ -319,7 +319,7 @@ DIST_SUBDIRS = \
gui-none gui-beos gui-cocoa gui-gtk gui-muirexx \
od-generic od-amiga od-beos od-linux od-macosx od-win32 \
td-none td-amigaos td-beos td-posix td-sdl td-win32 \
keymap caps dms
keymap caps archivers/dms archivers/lha archivers/zip
BUILT_SOURCES = \
blit.h blitfunc.h blitfunc.c blittable.c \
......@@ -395,7 +395,6 @@ noinst_HEADERS = \
include/uae_malloc.h \
include/uae_string.h \
include/uae_types.h \
include/unzip.h \
include/version.h \
include/writelog.h \
include/xwin.h include/zfile.h include/diskutil.h \
......@@ -415,7 +414,7 @@ uae_SOURCES = \
blitter.c autoconf.c traps.c ersatz.c keybuf.c expansion.c \
diskutil.c zfile.c cfgfile.c picasso96.c inputdevice.c \
gfxutil.c audio.c sinctable.c drawing.c consolehook.c \
native2amiga.c disk.c crc32.c savestate.c unzip.c arcadia.c cdtv.c cd32_fmv.c \
native2amiga.c disk.c crc32.c savestate.c arcadia.c cdtv.c cd32_fmv.c \
uaeexe.c uaelib.c uaeresource.c fdi2raw.c hotkeys.c amax.c \
ar.c driveclick.c enforcer.c misc.c a2065.c gayle.c ncr_scsi.c \
missing.c readcpu.c
......@@ -437,7 +436,9 @@ uae_DEPENDENCIES = \
@GFX_DEP@/libgfxdep.a \
@GUI_DEP@/libguidep.a \
keymap/libkeymap.a \
dms/libdms.a \
archivers/dms/libdms.a \
archivers/lha/liblha.a \
archivers/zip/libzip.a \
caps/libcaps.a \
blitfunc.o blittable.o \
cpustbl.o cpudefs.o \
......@@ -454,11 +455,13 @@ uae_DEPENDENCIES = \
uae_LDADD = @MACHDEP@/libmachdep.a @JOY_DEP@/libjoydep.a \
@SND_DEP@/libsnddep.a @GFX_DEP@/libgfxdep.a \
@GUI_DEP@/libguidep.a keymap/libkeymap.a dms/libdms.a \
caps/libcaps.a blitfunc.o blittable.o cpustbl.o cpudefs.o \
libcpuemu.a @EXTRAOBJS@ @FILESYSOBJS@ @BSDSOCKOBJS@ @SCSIOBJS@ \
@CDOBJS@ @DEBUGOBJS@ @ASMOBJS@ @THREADDEP@/libthreaddep.a \
@OSDEP@/libosdep.a @UAE_LIBS@ @MATHLIB@
@GUI_DEP@/libguidep.a keymap/libkeymap.a \
archivers/dms/libdms.a archivers/lha/liblha.a \
archivers/zip/libzip.a caps/libcaps.a blitfunc.o blittable.o \
cpustbl.o cpudefs.o libcpuemu.a @EXTRAOBJS@ @FILESYSOBJS@ \
@BSDSOCKOBJS@ @SCSIOBJS@ @CDOBJS@ @DEBUGOBJS@ @ASMOBJS@ \
@THREADDEP@/libthreaddep.a @OSDEP@/libosdep.a @UAE_LIBS@ \
@MATHLIB@ $(am__empty)
readdisk_SOURCES = \
readdisk.c missing.c
......@@ -657,7 +660,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uaeexe.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uaelib.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uaeresource.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unzip.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writelog.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zfile.Po@am__quote@
......
......@@ -1689,3 +1689,4 @@ uae_u8 *restore_cd (int num, uae_u8 *src)
}
#endif
......@@ -416,7 +416,7 @@ static void *cdda_play_func (void *v)
whdr[i].lpData = (LPSTR)px[i];
mmr = waveOutPrepareHeader (cdda_wavehandle, &whdr[i], sizeof (WAVEHDR));
if (mmr != MMSYSERR_NOERROR) {
write_log ("CDDA: waveOutPrepareHeader %d:%d\n", i, mmr);
write_log ("IMAGE CDDA: waveOutPrepareHeader %d:%d\n", i, mmr);
goto end;
}
whdr[i].dwFlags |= WHDR_DONE;
......@@ -813,8 +813,13 @@ static int command_read (int unitnum, uae_u8 *data, int sector, int size)
sector += size;
} else {
offset = 16;
zfile_fseek (t->handle, t->offset + sector * t->size + offset, SEEK_SET);
zfile_fread (data, size, 2048, t->handle);
while (size-- > 0) {
zfile_fseek (t->handle, t->offset + sector * t->size + offset, SEEK_SET);
zfile_fread (data, size, 2048, t->handle);
data += 2048;
sector++;
}
}
cdu->cd_last_pos = sector;
return 1;
}
......@@ -866,7 +871,6 @@ static int command_toc (int unitnum, struct cd_toc_head *th)
toc++;
memcpy (&cdu->di.toc, th, sizeof (struct cd_toc_head));
gui_flicker_led (LED_CD, unitnum, 1);
return 1;
}
......@@ -1109,7 +1113,7 @@ static int parseccd (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img)
zimg = zfile_fopen (fname, "rb", ZFD_NORMAL);
if (!zimg) {
write_log ("CCD: can't open '%s'\n", fname);
//return 0;
return 0;
}
ext = _tcsrchr (fname, '.');
if (ext)
......
......@@ -243,35 +243,35 @@ volatile int bsd_int_requested;
void addtosigqueue (SB, int events)
{
locksigqueue ();
locksigqueue ();
if (events)
sb->sigstosend |= sb->eventsigs;
else
sb->sigstosend |= ((uae_u32) 1) << sb->signal;
if (events)
sb->sigstosend |= sb->eventsigs;
else
sb->sigstosend |= ((uae_u32) 1) << sb->signal;
if (!sb->dosignal) {
sb->nextsig = sbsigqueue;
sbsigqueue = sb;
}
sb->dosignal = 1;
if (!sb->dosignal) {
sb->nextsig = sbsigqueue;
sbsigqueue = sb;
}
sb->dosignal = 1;
bsd_int_requested = 1;
unlocksigqueue ();
unlocksigqueue ();
}
void bsdsock_fake_int_handler(void)
{
locksigqueue ();
locksigqueue ();
bsd_int_requested = 0;
if (sbsigqueue != NULL) {
if (sbsigqueue != NULL) {
SB;
for (sb = sbsigqueue; sb; sb = sb->nextsig) {
if (sb->dosignal == 1) {
for (sb = sbsigqueue; sb; sb = sb->nextsig) {
if (sb->dosignal == 1) {
uae_Signal (sb->ownertask, sb->sigstosend);
sb->sigstosend = 0;
}
......@@ -286,32 +286,32 @@ void bsdsock_fake_int_handler(void)
void waitsig (TrapContext *context, SB)
{
long sigs;
m68k_dreg (regs, 0) = (((uae_u32) 1) << sb->signal) | sb->eintrsigs;
long sigs;
m68k_dreg (regs, 0) = (((uae_u32) 1) << sb->signal) | sb->eintrsigs;
if ((sigs = CallLib (context, get_long (4), -0x13e)) & sb->eintrsigs) { /* Wait */
sockabort (sb);
bsdsocklib_seterrno (sb, 4); /* EINTR */
sockabort (sb);
bsdsocklib_seterrno (sb, 4); /* EINTR */
// Set signal
m68k_dreg (regs, 0) = sigs;
m68k_dreg (regs, 1) = sb->eintrsigs;
sigs = CallLib (context, get_long (4), -0x132); /* SetSignal() */
// Set signal
m68k_dreg (regs, 0) = sigs;
m68k_dreg (regs, 1) = sb->eintrsigs;
sigs = CallLib (context, get_long (4), -0x132); /* SetSignal() */
sb->eintr = 1;
} else
sb->eintr = 0;
sb->eintr = 1;
} else
sb->eintr = 0;
}
void cancelsig (TrapContext *context, SB)
{
locksigqueue ();
if (sb->dosignal)
sb->dosignal = 2;
unlocksigqueue ();
locksigqueue ();
if (sb->dosignal)
sb->dosignal = 2;
unlocksigqueue ();
m68k_dreg (regs, 0) = 0;
m68k_dreg (regs, 1) = ((uae_u32) 1) << sb->signal;
CallLib (context, get_long (4), -0x132); /* SetSignal() */
m68k_dreg (regs, 0) = 0;
m68k_dreg (regs, 1) = ((uae_u32) 1) << sb->signal;
CallLib (context, get_long (4), -0x132); /* SetSignal() */
}
......@@ -319,7 +319,7 @@ void cancelsig (TrapContext *context, SB)
static struct socketbase *alloc_socketbase (TrapContext *context)
{
SB;
int i;
int i;
if ((sb = xcalloc (struct socketbase, 1)) != NULL) {
sb->ownertask = gettask (context);
......@@ -329,8 +329,8 @@ static struct socketbase *alloc_socketbase (TrapContext *context)
if (sb->signal == -1) {
write_log ("bsdsocket: ERROR: Couldn't allocate signal for task 0x%lx.\n", sb->ownertask);
free (sb);
return NULL;
free (sb);
return NULL;
}
m68k_dreg (regs, 0) = SCRATCHBUFSIZE;
m68k_dreg (regs, 1) = 0;
......@@ -341,25 +341,25 @@ static struct socketbase *alloc_socketbase (TrapContext *context)
sb->ftable = (int*)malloc (sb->dtablesize * sizeof (*sb->ftable));
for (i = sb->dtablesize; i--;)
sb->dtable[i] = -1;
sb->dtable[i] = -1;
sb->eintrsigs = 0x1000; /* SIGBREAKF_CTRL_C */
sb->eintrsigs = 0x1000; /* SIGBREAKF_CTRL_C */
if (!host_sbinit (context, sb)) {
/* @@@ free everything */
/* @@@ free everything */
}
locksigqueue ();
locksigqueue();
if (socketbases)
sb->next = socketbases;
sb->next = socketbases;
socketbases = sb;
unlocksigqueue ();
unlocksigqueue();
return sb;
}
return NULL;
}
return NULL;
}
STATIC_INLINE struct socketbase *get_socketbase (TrapContext *context)
......@@ -369,28 +369,28 @@ STATIC_INLINE struct socketbase *get_socketbase (TrapContext *context)
static void free_socketbase (TrapContext *context)
{
struct socketbase *sb, *nsb;
struct socketbase *sb, *nsb;
if ((sb = get_socketbase (context)) != NULL) {
if ((sb = get_socketbase (context)) != NULL) {
m68k_dreg (regs, 0) = sb->signal;
CallLib (context, get_long (4), -0x150); /* FreeSignal */
CallLib (context, get_long (4), -0x150); /* FreeSignal */
if (sb->hostent) {
m68k_areg (regs, 1) = sb->hostent;
m68k_dreg (regs, 0) = sb->hostentsize;
CallLib (context, get_long (4), -0xD2); /* FreeMem */
m68k_areg (regs, 1) = sb->hostent;
m68k_dreg (regs, 0) = sb->hostentsize;
CallLib (context, get_long (4), -0xD2); /* FreeMem */
}
if (sb->protoent) {
m68k_areg (regs, 1) = sb->protoent;
m68k_dreg (regs, 0) = sb->protoentsize;
CallLib (context, get_long (4), -0xD2); /* FreeMem */
m68k_areg (regs, 1) = sb->protoent;
m68k_dreg (regs, 0) = sb->protoentsize;
CallLib (context, get_long (4), -0xD2); /* FreeMem */
}
if (sb->servent) {
m68k_areg (regs, 1) = sb->servent;
m68k_dreg (regs, 0) = sb->serventsize;
CallLib (context, get_long (4), -0xD2); /* FreeMem */
m68k_areg (regs, 1) = sb->servent;
m68k_dreg (regs, 0) = sb->serventsize;
CallLib (context, get_long (4), -0xD2); /* FreeMem */
}
host_sbcleanup (sb);
......@@ -401,50 +401,50 @@ static void free_socketbase (TrapContext *context)
locksigqueue ();
if (sb == socketbases)
socketbases = sb->next;
socketbases = sb->next;
else {
for (nsb = socketbases; nsb; nsb = nsb->next) {
for (nsb = socketbases; nsb; nsb = nsb->next) {
if (sb == nsb->next) {
nsb->next = sb->next;
break;
nsb->next = sb->next;
break;
}
}
}
}
if (sb == sbsigqueue)
sbsigqueue = sb->next;
sbsigqueue = sb->next;
else {
for (nsb = sbsigqueue; nsb; nsb = nsb->next) {
for (nsb = sbsigqueue; nsb; nsb = nsb->next) {
if (sb == nsb->next) {
nsb->next = sb->next;
break;
nsb->next = sb->next;
break;
}
}
}
}
unlocksigqueue ();
unlocksigqueue ();
free (sb);
}
free (sb);
}
}
static uae_u32 REGPARAM2 bsdsocklib_Expunge (TrapContext *context)
{
BSDTRACE (("Expunge() -> [ignored]\n"));
return 0;
return 0;
}
static uae_u32 functable, datatable, inittable;
static uae_u32 REGPARAM2 bsdsocklib_Open (TrapContext *context)
{
uae_u32 result = 0;
int opencount;
uae_u32 result = 0;
int opencount;
SB;
BSDTRACE (("OpenLibrary() -> "));
if ((sb = alloc_socketbase (context)) != NULL) {
if ((sb = alloc_socketbase (context)) != NULL) {
put_word (SockLibBase + 32, opencount = get_word (SockLibBase + 32) + 1);
m68k_areg (regs, 0) = functable;
......@@ -460,147 +460,147 @@ static uae_u32 REGPARAM2 bsdsocklib_Open (TrapContext *context)
} else
BSDTRACE (("failed (out of memory)\n"));
return result;
return result;
}
static uae_u32 REGPARAM2 bsdsocklib_Close (TrapContext *context)
{
int opencount;
int opencount;
uae_u32 base = m68k_areg (regs, 6);
uae_u32 negsize = get_word (base + 16);
uae_u32 base = m68k_areg (regs, 6);
uae_u32 negsize = get_word (base + 16);
free_socketbase (context);
free_socketbase (context);
put_word (SockLibBase + 32, opencount = get_word (SockLibBase + 32) - 1);
put_word (SockLibBase + 32, opencount = get_word (SockLibBase + 32) - 1);
m68k_areg (regs, 1) = base - negsize;
m68k_dreg (regs, 0) = negsize + get_word (base + 18);
CallLib (context, get_long (4), -0xD2); /* FreeMem */
m68k_areg (regs, 1) = base - negsize;
m68k_dreg (regs, 0) = negsize + get_word (base + 18);
CallLib (context, get_long (4), -0xD2); /* FreeMem */
BSDTRACE (("CloseLibrary() -> [%d]\n", opencount));
return 0;
return 0;
}
/* socket(domain, type, protocol)(d0/d1/d2) */
static uae_u32 REGPARAM2 bsdsocklib_socket (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
return host_socket (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1),
m68k_dreg (regs, 2));
struct socketbase *sb = get_socketbase (context);
return host_socket (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1),
m68k_dreg (regs, 2));
}
/* bind(s, name, namelen)(d0/a0/d1) */
static uae_u32 REGPARAM2 bsdsocklib_bind (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
return host_bind (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0),
m68k_dreg (regs, 1));
struct socketbase *sb = get_socketbase (context);
return host_bind (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0),
m68k_dreg (regs, 1));
}
/* listen(s, backlog)(d0/d1) */
static uae_u32 REGPARAM2 bsdsocklib_listen (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
return host_listen (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1));
struct socketbase *sb = get_socketbase (context);
return host_listen (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1));
}
/* accept(s, addr, addrlen)(d0/a0/a1) */
static uae_u32 REGPARAM2 bsdsocklib_accept (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
host_accept (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1));
return sb->resultval;
struct socketbase *sb = get_socketbase (context);
host_accept (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1));
return sb->resultval;
}
/* connect(s, name, namelen)(d0/a0/d1) */
static uae_u32 REGPARAM2 bsdsocklib_connect (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
host_connect (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1));
return sb->sb_errno ? -1 : 0;
struct socketbase *sb = get_socketbase (context);
host_connect (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1));
return sb->sb_errno ? -1 : 0;
}
/* sendto(s, msg, len, flags, to, tolen)(d0/a0/d1/d2/a1/d3) */
static uae_u32 REGPARAM2 bsdsocklib_sendto (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
host_sendto (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1),
m68k_dreg (regs, 2), m68k_areg (regs, 1), m68k_dreg (regs, 3));
return sb->resultval;
struct socketbase *sb = get_socketbase (context);
host_sendto (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1),
m68k_dreg (regs, 2), m68k_areg (regs, 1), m68k_dreg (regs, 3));
return sb->resultval;
}
/* send(s, msg, len, flags)(d0/a0/d1/d2) */
static uae_u32 REGPARAM2 bsdsocklib_send (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
host_sendto (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1),
m68k_dreg (regs, 2), 0, 0);
return sb->resultval;
struct socketbase *sb = get_socketbase (context);
host_sendto (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1),
m68k_dreg (regs, 2), 0, 0);
return sb->resultval;
}
/* recvfrom(s, buf, len, flags, from, fromlen)(d0/a0/d1/d2/a1/a2) */
static uae_u32 REGPARAM2 bsdsocklib_recvfrom (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
host_recvfrom (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1),
m68k_dreg (regs, 2), m68k_areg (regs, 1), m68k_areg (regs, 2));
return sb->resultval;
struct socketbase *sb = get_socketbase (context);
host_recvfrom (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1),
m68k_dreg (regs, 2), m68k_areg (regs, 1), m68k_areg (regs, 2));
return sb->resultval;
}
/* recv(s, buf, len, flags)(d0/a0/d1/d2) */
static uae_u32 REGPARAM2 bsdsocklib_recv (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
host_recvfrom (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1),
m68k_dreg (regs, 2), 0, 0);
return sb->resultval;
struct socketbase *sb = get_socketbase (context);
host_recvfrom (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1),
m68k_dreg (regs, 2), 0, 0);
return sb->resultval;
}
/* shutdown(s, how)(d0/d1) */
static uae_u32 REGPARAM2 bsdsocklib_shutdown (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
return host_shutdown (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1));
struct socketbase *sb = get_socketbase (context);
return host_shutdown (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1));
}
/* setsockopt(s, level, optname, optval, optlen)(d0/d1/d2/a0/d3) */
static uae_u32 REGPARAM2 bsdsocklib_setsockopt (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
host_setsockopt (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_dreg (regs, 2),
m68k_areg (regs, 0), m68k_dreg (regs, 3));
return sb->resultval;
struct socketbase *sb = get_socketbase (context);
host_setsockopt (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_dreg (regs, 2),
m68k_areg (regs, 0), m68k_dreg (regs, 3));
return sb->resultval;
}
/* getsockopt(s, level, optname, optval, optlen)(d0/d1/d2/a0/a1) */
static uae_u32 REGPARAM2 bsdsocklib_getsockopt (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
return host_getsockopt (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_dreg (regs, 2),
m68k_areg (regs, 0), m68k_areg (regs, 1));
struct socketbase *sb = get_socketbase (context);
return host_getsockopt (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_dreg (regs, 2),
m68k_areg (regs, 0), m68k_areg (regs, 1));
}
/* getsockname(s, hostname, namelen)(d0/a0/a1) */
static uae_u32 REGPARAM2 bsdsocklib_getsockname (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
return host_getsockname (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1));
struct socketbase *sb = get_socketbase (context);
return host_getsockname (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1));
}
/* getpeername(s, hostname, namelen)(d0/a0/a1) */
static uae_u32 REGPARAM2 bsdsocklib_getpeername (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
return host_getpeername (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1));
struct socketbase *sb = get_socketbase (context);
return host_getpeername (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1));
}
/* *------ generic system calls related to sockets */
/* IoctlSocket(d, request, argp)(d0/d1/a0) */
static uae_u32 REGPARAM2 bsdsocklib_IoctlSocket (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
struct socketbase *sb = get_socketbase (context);
return host_IoctlSocket (context, sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_areg (regs, 0));
}
......@@ -608,42 +608,42 @@ static uae_u32 REGPARAM2 bsdsocklib_IoctlSocket (TrapContext *context)
/* CloseSocket(d)(d0) */
static uae_u32 REGPARAM2 bsdsocklib_CloseSocket (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
struct socketbase *sb = get_socketbase (context);
return host_CloseSocket (context, sb, m68k_dreg (regs, 0));
}
/* WaitSelect(nfds, readfds, writefds, execptfds, timeout, maskp)(d0/a0/a1/a2/a3/d1) */
static uae_u32 REGPARAM2 bsdsocklib_WaitSelect (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
host_WaitSelect (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1),
m68k_areg (regs, 2), m68k_areg (regs, 3), m68k_dreg (regs, 1));
return sb->resultval;
struct socketbase *sb = get_socketbase (context);
host_WaitSelect (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1),
m68k_areg (regs, 2), m68k_areg (regs, 3), m68k_dreg (regs, 1));
return sb->resultval;
}
/* SetSocketSignals(SIGINTR, SIGIO, SIGURG)(d0/d1/d2) */
static uae_u32 REGPARAM2 bsdsocklib_SetSocketSignals (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
struct socketbase *sb = get_socketbase (context);
BSDTRACE (("SetSocketSignals(0x%08lx,0x%08lx,0x%08lx) -> ", m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_dreg (regs, 2)));
sb->eintrsigs = m68k_dreg (regs, 0);
sb->eventsigs = m68k_dreg (regs, 1);
sb->eintrsigs = m68k_dreg (regs, 0);
sb->eventsigs = m68k_dreg (regs, 1);
return 0;
return 0;
}
/* SetDTableSize(size)(d0) */
static uae_u32 bsdsocklib_SetDTableSize (SB, int newSize)
{
int *newdtable;
int *newftable;
int i;
int *newdtable;
int *newftable;
int i;
if (newSize < sb->dtablesize) {
if (newSize < sb->dtablesize) {
/* I don't support lowering the size */
return 0;
}
}
newdtable = xcalloc (int, newSize);
newftable = xcalloc (int, newSize);
......@@ -654,128 +654,129 @@ static uae_u32 bsdsocklib_SetDTableSize (SB, int newSize)
free (newdtable);
free (newftable);
return -1;
}
}
memcpy(newdtable, sb->dtable, sb->dtablesize * sizeof(*sb->dtable));
memcpy(newftable, sb->ftable, sb->dtablesize * sizeof(*sb->ftable));
for (i = sb->dtablesize + 1; i < newSize; i++)
memcpy (newdtable, sb->dtable, sb->dtablesize * sizeof(*sb->dtable));
memcpy (newftable, sb->ftable, sb->dtablesize * sizeof(*sb->ftable));
for (i = sb->dtablesize + 1; i < newSize; i++)
newdtable[i] = -1;
sb->dtablesize = newSize;
free(sb->dtable);
free(sb->ftable);
sb->dtablesize = newSize;
free(sb->dtable);
free(sb->ftable);
sb->dtable = (SOCKET*)newdtable;
sb->ftable = newftable;
sb->resultval = 0;
return 0;
sb->ftable = newftable;
sb->resultval = 0;
return 0;
}
static int sockpoolindex (long id)
{
int i;
int i;
for (i = 0; i < SOCKPOOLSIZE; i++)
for (i = 0; i < SOCKPOOLSIZE; i++)
if (sockdata->sockpoolids[i] == id)
return i;
return i;
return -1;
return -1;
}
/* ObtainSocket(id, domain, type, protocol)(d0/d1/d2/d3) */
static uae_u32 REGPARAM2 bsdsocklib_ObtainSocket (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
int sd;
long id;
struct socketbase *sb = get_socketbase (context);
int sd;
long id;
SOCKET_TYPE s;
int i;
int i;
id = m68k_dreg (regs, 0);
id = m68k_dreg (regs, 0);
BSDTRACE (("ObtainSocket(%d,%d,%d,%d) -> ", id, m68k_dreg (regs, 1), m68k_dreg (regs, 2), m68k_dreg (regs, 3)));
i = sockpoolindex (id);
i = sockpoolindex (id);
if (i == -1) {
if (i == -1) {
BSDTRACE (("[invalid key]\n"));
return -1;
}
}
s = sockdata->sockpoolsocks[i];
sd = getsd (sb, s);
sd = getsd (sb, s);
BSDTRACE (("%d, %d\n", s, sd));
if (sd != -1) {
if (sd != -1) {
sb->ftable[sd - 1] = sockdata->sockpoolflags[i];
sockdata->sockpoolids[i] = UNIQUE_ID;
return sd-1;
}
return sd - 1;
}
return -1;
return -1;
}
/* ReleaseSocket(fd, id)(d0/d1) */
static uae_u32 REGPARAM2 bsdsocklib_ReleaseSocket (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
int sd;
long id;
struct socketbase *sb = get_socketbase (context);
int sd;
long id;
SOCKET_TYPE s;
int i;
uae_u32 flags;
int i;
uae_u32 flags;
sd = m68k_dreg (regs, 0);
id = m68k_dreg (regs, 1);
sd = m68k_dreg (regs, 0);
id = m68k_dreg (regs, 1);
sd++;
BSDTRACE (("ReleaseSocket(%d,%d) -> ", sd, id));
s = getsock (sb, sd);
s = getsock (sb, sd);
if (s != -1) {
if (s != -1) {
flags = sb->ftable[sd - 1];
if (flags & REP_ALL) {
write_log ("bsdsocket: ERROR: ReleaseSocket() is not supported for sockets with async event notification enabled!\n");
return -1;
return -1;
}
releasesock (sb, sd);
if (id == UNIQUE_ID) {
for (;;) {
if (sockpoolindex (curruniqid) == -1)
break;
curruniqid += 129;
if ((unsigned long) (curruniqid + 1) < 65536)
curruniqid += 65537;
}
id = curruniqid;
} else if (id < 0 && id > 65535) {
if (sockpoolindex (id) != -1) {
if (id == UNIQUE_ID) {
for (;;) {
if (sockpoolindex (curruniqid) == -1)
break;
curruniqid += 129;
if ((unsigned long) (curruniqid + 1) < 65536)
curruniqid += 65537;
}
id = curruniqid;
} else if (id < 0 && id > 65535) {
if (sockpoolindex (id) != -1) {
BSDTRACE (("[unique ID already exists]\n"));
return -1;
}
}
i = sockpoolindex (-1);
return -1;
}
}
i = sockpoolindex (-1);
if (i == -1) {
if (i == -1) {
BSDTRACE (("-1\n"));
write_log ("bsdsocket: ERROR: Global socket pool overflow\n");
return -1;
}
return -1;
}
sockdata->sockpoolids[i] = id;
sockdata->sockpoolsocks[i] = s;
sockdata->sockpoolflags[i] = flags;
BSDTRACE (("id %d s 0x%x\n", id,s));
} else {
} else {
BSDTRACE (("[invalid socket descriptor]\n"));
return -1;
}
return -1;
}
return id;
return id;
}
/* ReleaseCopyOfSocket(fd, id)(d0/d1) */
......@@ -843,132 +844,132 @@ static uae_u32 REGPARAM2 bsdsocklib_ReleaseCopyOfSocket (TrapContext *context)
/* Errno()() */
static uae_u32 REGPARAM2 bsdsocklib_Errno (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
struct socketbase *sb = get_socketbase (context);
BSDTRACE (("Errno() -> %d\n", sb->sb_errno));
return sb->sb_errno;
return sb->sb_errno;
}
/* SetErrnoPtr(errno_p, size)(a0/d0) */
static uae_u32 REGPARAM2 bsdsocklib_SetErrnoPtr (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
uae_u32 errnoptr = m68k_areg (regs, 0), size = m68k_dreg (regs, 0);
struct socketbase *sb = get_socketbase (context);
uae_u32 errnoptr = m68k_areg (regs, 0), size = m68k_dreg (regs, 0);
BSDTRACE (("SetErrnoPtr(0x%lx,%d) -> ", errnoptr, size));
if (size == 1 || size == 2 || size == 4) {
sb->errnoptr = errnoptr;
sb->errnosize = size;
if (size == 1 || size == 2 || size == 4) {
sb->errnoptr = errnoptr;
sb->errnosize = size;
BSDTRACE (("OK\n"));
return 0;
}
bsdsocklib_seterrno (sb, 22); /* EINVAL */
return 0;
}
bsdsocklib_seterrno (sb, 22); /* EINVAL */
return -1;
return -1;
}
/* *------ inet library calls related to inet address manipulation */
/* Inet_NtoA(in)(d0) */
static uae_u32 REGPARAM2 bsdsocklib_Inet_NtoA (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
return host_Inet_NtoA (context, sb, m68k_dreg (regs, 0));
struct socketbase *sb = get_socketbase (context);
return host_Inet_NtoA (context, sb, m68k_dreg (regs, 0));
}
/* inet_addr(cp)(a0) */
static uae_u32 REGPARAM2 bsdsocklib_inet_addr (TrapContext *context)
{
return host_inet_addr (m68k_areg (regs, 0));
return host_inet_addr (m68k_areg (regs, 0));
}
/* Inet_LnaOf(in)(d0) */
static uae_u32 REGPARAM2 bsdsocklib_Inet_LnaOf (TrapContext *context)
{
write_log ("bsdsocket: UNSUPPORTED: Inet_LnaOf()\n");
return 0;
return 0;
}
/* Inet_NetOf(in)(d0) */
static uae_u32 REGPARAM2 bsdsocklib_Inet_NetOf (TrapContext *context)
{
write_log ("bsdsocket: UNSUPPORTED: Inet_NetOf()\n");
return 0;
return 0;
}
/* Inet_MakeAddr(net, host)(d0/d1) */
static uae_u32 REGPARAM2 bsdsocklib_Inet_MakeAddr (TrapContext *context)
{
write_log ("bsdsocket: UNSUPPORTED: Inet_MakeAddr()\n");
return 0;
return 0;
}
/* inet_network(cp)(a0) */
static uae_u32 REGPARAM2 bsdsocklib_inet_network (TrapContext *context)
{
return host_inet_addr (m68k_areg (regs, 0));
return host_inet_addr (m68k_areg (regs, 0));
}
/* *------ gethostbyname etc */
/* gethostbyname(name)(a0) */
static uae_u32 REGPARAM2 bsdsocklib_gethostbyname (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
host_gethostbynameaddr (context, sb, m68k_areg (regs, 0), 0, -1);
return sb->sb_herrno ? 0 : sb->hostent;
struct socketbase *sb = get_socketbase (context);
host_gethostbynameaddr (context, sb, m68k_areg (regs, 0), 0, -1);
return sb->sb_herrno ? 0 : sb->hostent;
}
/* gethostbyaddr(addr, len, type)(a0/d0/d1) */
static uae_u32 REGPARAM2 bsdsocklib_gethostbyaddr (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
host_gethostbynameaddr (context, sb, m68k_areg (regs, 0), m68k_dreg (regs, 0), m68k_dreg (regs, 1));
return sb->sb_herrno ? 0 : sb->hostent;
struct socketbase *sb = get_socketbase (context);
host_gethostbynameaddr (context, sb, m68k_areg (regs, 0), m68k_dreg (regs, 0), m68k_dreg (regs, 1));
return sb->sb_herrno ? 0 : sb->hostent;
}
/* getnetbyname(name)(a0) */
static uae_u32 REGPARAM2 bsdsocklib_getnetbyname (TrapContext *context)
{
write_log ("bsdsocket: UNSUPPORTED: getnetbyname()\n");
return 0;
return 0;
}
/* getnetbyaddr(net, type)(d0/d1) */
static uae_u32 REGPARAM2 bsdsocklib_getnetbyaddr (TrapContext *context)
{
write_log ("bsdsocket: UNSUPPORTED: getnetbyaddr()\n");
return 0;
return 0;
}
/* getservbyname(name, proto)(a0/a1) */
static uae_u32 REGPARAM2 bsdsocklib_getservbyname (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
host_getservbynameport (context, sb, m68k_areg (regs, 0), m68k_areg (regs, 1), 0);
return sb->sb_errno ? 0 : sb->servent;
struct socketbase *sb = get_socketbase (context);
host_getservbynameport (context, sb, m68k_areg (regs, 0), m68k_areg (regs, 1), 0);
return sb->sb_errno ? 0 : sb->servent;
}
/* getservbyport(port, proto)(d0/a0) */
static uae_u32 REGPARAM2 bsdsocklib_getservbyport (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
host_getservbynameport (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), 1);
return sb->sb_errno ? 0 : sb->servent;
struct socketbase *sb = get_socketbase (context);
host_getservbynameport (context, sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), 1);
return sb->sb_errno ? 0 : sb->servent;
}
/* getprotobyname(name)(a0) */
static uae_u32 REGPARAM2 bsdsocklib_getprotobyname (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
host_getprotobyname (context, sb, m68k_areg (regs, 0));
return sb->sb_errno ? 0 : sb->protoent;
struct socketbase *sb = get_socketbase (context);
host_getprotobyname (context, sb, m68k_areg (regs, 0));
return sb->sb_errno ? 0 : sb->protoent;
}
/* getprotobynumber(proto)(d0) */
static uae_u32 REGPARAM2 bsdsocklib_getprotobynumber (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
host_getprotobynumber (context, sb, m68k_dreg (regs, 0));
return sb->sb_errno ? 0 : sb->protoent;
struct socketbase *sb = get_socketbase (context);
host_getprotobynumber (context, sb, m68k_dreg (regs, 0));
return sb->sb_errno ? 0 : sb->protoent;
}
/* *------ syslog functions */
......@@ -976,42 +977,42 @@ static uae_u32 REGPARAM2 bsdsocklib_getprotobynumber (TrapContext *context)
static uae_u32 REGPARAM2 bsdsocklib_vsyslog (TrapContext *context)
{
write_log ("bsdsocket: UNSUPPORTED: vsyslog()\n");
return 0;
return 0;
}
/* *------ AmiTCP/IP 1.1 extensions */
/* Dup2Socket(fd1, fd2)(d0/d1) */
static uae_u32 REGPARAM2 bsdsocklib_Dup2Socket (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
return host_dup2socket (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1));
struct socketbase *sb = get_socketbase (context);
return host_dup2socket (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1));
}
static uae_u32 REGPARAM2 bsdsocklib_sendmsg (TrapContext *context)
{
write_log ("bsdsocket: UNSUPPORTED: sendmsg()\n");
return 0;
return 0;
}
static uae_u32 REGPARAM2 bsdsocklib_recvmsg (TrapContext *context)
{
write_log ("bsdsocket: UNSUPPORTED: recvmsg()\n");
return 0;
return 0;
}
static uae_u32 REGPARAM2 bsdsocklib_gethostname (TrapContext *context)
{
return host_gethostname (m68k_areg (regs, 0), m68k_dreg (regs, 0));
return host_gethostname (m68k_areg (regs, 0), m68k_dreg (regs, 0));
}
static uae_u32 REGPARAM2 bsdsocklib_gethostid (TrapContext *context)
{
write_log ("bsdsocket: WARNING: Process '%s' calls deprecated function gethostid() - returning 127.0.0.1\n",
get_real_address (get_long (gettask (context) + 10)));
return 0x7f000001;
return 0x7f000001;
}
const char * const errortexts[] =
static const TCHAR *errortexts[] =
{"No error", "Operation not permitted", "No such file or directory",
"No such process", "Interrupted system call", "Input/output error", "Device not configured",
"Argument list too long", "Exec format error", "Bad file descriptor", "No child processes",
......@@ -1037,58 +1038,58 @@ const char * const errortexts[] =
"RPC prog. not avail", "Program version wrong", "Bad procedure for program", "No locks available",
"Function not implemented", "Inappropriate file type or format", "PError 0"};
uae_u32 errnotextptrs[sizeof (errortexts) / sizeof (*errortexts)];
uae_u32 number_sys_error = sizeof (errortexts) / sizeof (*errortexts);
static uae_u32 errnotextptrs[sizeof (errortexts) / sizeof (*errortexts)];
static const uae_u32 number_sys_error = sizeof (errortexts) / sizeof (*errortexts);
const char * const herrortexts[] =
{"No error", "Unknown host", "Host name lookup failure", "Unknown server error",
static const TCHAR *herrortexts[] =
{"No error", "Unknown host", "Host name lookup failure", "Unknown server error",
"No address associated with name"};
uae_u32 herrnotextptrs[sizeof (herrortexts) / sizeof (*herrortexts)];
uae_u32 number_host_error = sizeof (herrortexts) / sizeof (*herrortexts);
static uae_u32 herrnotextptrs[sizeof (herrortexts) / sizeof (*herrortexts)];
static const uae_u32 number_host_error = sizeof (herrortexts) / sizeof (*herrortexts);
static const char * const strErr = "Errlist lookup error";
uae_u32 strErrptr;
static const TCHAR * const strErr = "Errlist lookup error";
static uae_u32 strErrptr;
#define TAG_DONE (0L) /* terminates array of TagItems. ti_Data unused */
#define TAG_IGNORE (1L) /* ignore this item, not end of array */
#define TAG_MORE (2L) /* ti_Data is pointer to another array of TagItems */
#define TAG_SKIP (3L) /* skip this and the next ti_Data items */
#define TAG_USER ((uae_u32)(1L<<31))
#define TAG_IGNORE (1L) /* ignore this item, not end of array */
#define TAG_MORE (2L) /* ti_Data is pointer to another array of TagItems */
#define TAG_SKIP (3L) /* skip this and the next ti_Data items */
#define TAG_USER ((uae_u32)(1L << 31))
#define SBTF_VAL 0x0000
#define SBTF_REF 0x8000
#define SBTB_CODE 1
#define SBTS_CODE 0x3FFF
#define SBTM_CODE(tag) ((((UWORD)(tag))>>SBTB_CODE) & SBTS_CODE)
#define SBTM_CODE(tag) ((((UWORD)(tag)) >> SBTB_CODE) & SBTS_CODE)
#define SBTF_GET 0x0
#define SBTF_SET 0x1
#define SBTM_GETREF(code) \
(TAG_USER | SBTF_REF | (((code) & SBTS_CODE) << SBTB_CODE))
(TAG_USER | SBTF_REF | (((code) & SBTS_CODE) << SBTB_CODE))
#define SBTM_GETVAL(code) (TAG_USER | (((code) & SBTS_CODE) << SBTB_CODE))
#define SBTM_SETREF(code) \
(TAG_USER | SBTF_REF | (((code) & SBTS_CODE) << SBTB_CODE) | SBTF_SET)
(TAG_USER | SBTF_REF | (((code) & SBTS_CODE) << SBTB_CODE) | SBTF_SET)
#define SBTM_SETVAL(code) \
(TAG_USER | (((code) & SBTS_CODE) << SBTB_CODE) | SBTF_SET)
#define SBTC_BREAKMASK 1
#define SBTC_SIGIOMASK 2
#define SBTC_SIGURGMASK 3
(TAG_USER | (((code) & SBTS_CODE) << SBTB_CODE) | SBTF_SET)
#define SBTC_BREAKMASK 1
#define SBTC_SIGIOMASK 2
#define SBTC_SIGURGMASK 3
#define SBTC_SIGEVENTMASK 4
#define SBTC_ERRNO 6
#define SBTC_HERRNO 7
#define SBTC_DTABLESIZE 8
#define SBTC_FDCALLBACK 9
#define SBTC_LOGSTAT 10
#define SBTC_LOGTAGPTR 11
#define SBTC_ERRNO 6
#define SBTC_HERRNO 7
#define SBTC_DTABLESIZE 8
#define SBTC_FDCALLBACK 9
#define SBTC_LOGSTAT 10
#define SBTC_LOGTAGPTR 11
#define SBTC_LOGFACILITY 12
#define SBTC_LOGMASK 13
#define SBTC_ERRNOSTRPTR 14 /* <sys/errno.h> */
#define SBTC_HERRNOSTRPTR 15 /* <netdb.h> */
#define SBTC_IOERRNOSTRPTR 16 /* <exec/errors.h> */
#define SBTC_S2ERRNOSTRPTR 17 /* <devices/sana2.h> */
#define SBTC_S2WERRNOSTRPTR 18 /* <devices/sana2.h> */
#define SBTC_LOGMASK 13
#define SBTC_ERRNOSTRPTR 14 /* <sys/errno.h> */
#define SBTC_HERRNOSTRPTR 15 /* <netdb.h> */
#define SBTC_IOERRNOSTRPTR 16 /* <exec/errors.h> */
#define SBTC_S2ERRNOSTRPTR 17 /* <devices/sana2.h> */
#define SBTC_S2WERRNOSTRPTR 18 /* <devices/sana2.h> */
#define SBTC_ERRNOBYTEPTR 21
#define SBTC_ERRNOWORDPTR 22
#define SBTC_ERRNOLONGPTR 24
......@@ -1097,36 +1098,36 @@ uae_u32 strErrptr;
static void tagcopy (uae_u32 currtag, uae_u32 currval, uae_u32 tagptr, uae_u32 * ptr)
{
switch (currtag & 0x8001) {
case 0x0000: /* SBTM_GETVAL */
switch (currtag & 0x8001) {
case 0x0000: /* SBTM_GETVAL */
put_long (tagptr + 4, *ptr);
break;
case 0x8000: /* SBTM_GETREF */
put_long (tagptr + 4, *ptr);
break;
case 0x8000: /* SBTM_GETREF */
put_long (currval, *ptr);
break;
case 0x0001: /* SBTM_SETVAL */
put_long (currval, *ptr);
break;
case 0x0001: /* SBTM_SETVAL */
*ptr = currval;
break;
default: /* SBTM_SETREF */
*ptr = currval;
break;
default: /* SBTM_SETREF */
*ptr = get_long (currval);
}
*ptr = get_long (currval);
}
}
static uae_u32 REGPARAM2 bsdsocklib_SocketBaseTagList (TrapContext *context)
{
struct socketbase *sb = get_socketbase (context);
uae_u32 tagptr = m68k_areg (regs, 0);
uae_u32 tagsprocessed = 1;
uae_u32 currtag;
uae_u32 currval;
struct socketbase *sb = get_socketbase (context);
uae_u32 tagptr = m68k_areg (regs, 0);
uae_u32 tagsprocessed = 1;
uae_u32 currtag;
uae_u32 currval;
BSDTRACE (("SocketBaseTagList("));
for (;;) {
for (;;) {
currtag = get_long (tagptr);
currval = get_long (tagptr + 4);
tagsprocessed++;
......@@ -1134,22 +1135,22 @@ static uae_u32 REGPARAM2 bsdsocklib_SocketBaseTagList (TrapContext *context)
switch (currtag) {
case TAG_DONE:
BSDTRACE (("TAG_DONE"));
tagsprocessed = 0;
goto done;
tagsprocessed = 0;
goto done;
case TAG_IGNORE:
BSDTRACE (("TAG_IGNORE"));
break;
break;
case TAG_MORE:
BSDTRACE (("TAG_MORE(0x%lx)", currval));
tagptr = currval;
break;
tagptr = currval;
break;
case TAG_SKIP:
BSDTRACE (("TAG_SKIP(%d)", currval));
tagptr += currval * 8;
break;
tagptr += currval * 8;
break;
default:
if (currtag & TAG_USER) {
if (currtag & TAG_USER) {
BSDTRACE (("SBTM_"));
BSDTRACE ((currtag & 0x0001 ? "SET" : "GET"));
BSDTRACE ((currtag & 0x8000 ? "REF(" : "VAL("));
......@@ -1157,24 +1158,24 @@ static uae_u32 REGPARAM2 bsdsocklib_SocketBaseTagList (TrapContext *context)
switch ((currtag >> 1) & SBTS_CODE) {
case SBTC_BREAKMASK:
BSDTRACE (("SBTC_BREAKMASK),0x%lx", currval));
tagcopy (currtag, currval, tagptr, &sb->eintrsigs);
break;
case SBTC_SIGEVENTMASK:
tagcopy (currtag, currval, tagptr, &sb->eintrsigs);
break;
case SBTC_SIGEVENTMASK:
BSDTRACE (("SBTC_SIGEVENTMASK),0x%lx", currval));
tagcopy (currtag, currval, tagptr, &sb->eventsigs);
break;
case SBTC_SIGIOMASK:
tagcopy (currtag, currval, tagptr, &sb->eventsigs);
break;
case SBTC_SIGIOMASK:
BSDTRACE (("SBTC_SIGEVENTMASK),0x%lx", currval));
tagcopy (currtag, currval, tagptr, &sb->eventsigs);
break;
tagcopy (currtag, currval, tagptr, &sb->eventsigs);
break;
case SBTC_ERRNO:
BSDTRACE (("SBTC_ERRNO),%d", currval));
tagcopy (currtag, currval, tagptr, (uae_u32 *)&sb->sb_errno);
break;
tagcopy (currtag, currval, tagptr, (uae_u32 *)&sb->sb_errno);
break;
case SBTC_HERRNO:
BSDTRACE (("SBTC_HERRNO),%d", currval));
tagcopy (currtag, currval, tagptr, (uae_u32 *)&sb->sb_herrno);
break;
tagcopy (currtag, currval, tagptr, (uae_u32 *)&sb->sb_herrno);
break;
case SBTC_DTABLESIZE:
BSDTRACE (("SBTC_DTABLESIZE),0x%lx", currval));
if (currtag & 1) {
......@@ -1186,65 +1187,65 @@ static uae_u32 REGPARAM2 bsdsocklib_SocketBaseTagList (TrapContext *context)
case SBTC_ERRNOSTRPTR:
if (currtag & 1) {
BSDTRACE (("ERRNOSTRPTR),invalid"));
} else {
} else {
unsigned long ulTmp;
if (currtag & 0x8000) { /* SBTM_GETREF */
ulTmp = get_long (currval);
ulTmp = get_long (currval);
} else { /* SBTM_GETVAL */
ulTmp = currval;
ulTmp = currval;
}
BSDTRACE (("ERRNOSTRPTR),%d", ulTmp));
if (ulTmp < number_sys_error) {
tagcopy (currtag, currval, tagptr, &errnotextptrs[ulTmp]);
tagcopy (currtag, currval, tagptr, &errnotextptrs[ulTmp]);
} else {
tagcopy (currtag, currval, tagptr, &strErrptr);
tagcopy (currtag, currval, tagptr, &strErrptr);
}
}
break;
case SBTC_HERRNOSTRPTR:
if (currtag & 1) {
}
break;
case SBTC_HERRNOSTRPTR:
if (currtag & 1) {
BSDTRACE (("HERRNOSTRPTR),invalid"));
} else {
} else {
unsigned long ulTmp;
if (currtag & 0x8000) { /* SBTM_GETREF */
ulTmp = get_long (currval);
ulTmp = get_long (currval);
} else { /* SBTM_GETVAL */
ulTmp = currval;
ulTmp = currval;
}
BSDTRACE (("HERRNOSTRPTR),%d", ulTmp));
if (ulTmp < number_host_error) {
tagcopy (currtag, currval, tagptr, &herrnotextptrs[ulTmp]);
tagcopy (currtag, currval, tagptr, &herrnotextptrs[ulTmp]);
} else {
tagcopy (currtag, currval, tagptr, &strErrptr);
}
tagcopy (currtag, currval, tagptr, &strErrptr);
}
}
break;
break;
case SBTC_ERRNOBYTEPTR:
BSDTRACE (("SBTC_ERRNOBYTEPTR),0x%lx", currval));
tagcopy (currtag, currval, tagptr, &sb->errnoptr);
sb->errnosize = 1;
break;
tagcopy (currtag, currval, tagptr, &sb->errnoptr);
sb->errnosize = 1;
break;
case SBTC_ERRNOWORDPTR:
BSDTRACE (("SBTC_ERRNOWORDPTR),0x%lx", currval));
tagcopy (currtag, currval, tagptr, &sb->errnoptr);
sb->errnosize = 2;
break;
tagcopy (currtag, currval, tagptr, &sb->errnoptr);
sb->errnosize = 2;
break;
case SBTC_ERRNOLONGPTR:
BSDTRACE (("SBTC_ERRNOLONGPTR),0x%lx", currval));
tagcopy (currtag, currval, tagptr, &sb->errnoptr);
sb->errnosize = 4;
break;
tagcopy (currtag, currval, tagptr, &sb->errnoptr);
sb->errnosize = 4;
break;
case SBTC_HERRNOLONGPTR:
BSDTRACE (("SBTC_HERRNOLONGPTR),0x%lx", currval));
tagcopy (currtag, currval, tagptr, &sb->herrnoptr);
sb->herrnosize = 4;
break;
tagcopy (currtag, currval, tagptr, &sb->herrnoptr);
sb->herrnosize = 4;
break;
default:
write_log ("bsdsocket: WARNING: Unsupported tag type (%08x) in SocketBaseTagList(%x)\n",
currtag, m68k_areg (regs, 0));
break;
}
} else {
} else {
BSDTRACE (("TAG_UNKNOWN(0x%x)", currtag));
/* Aminetradio uses 0x00004e55 as an ending tag */
if ((currtag & 0xffff8000) == 0) {
......@@ -1252,105 +1253,105 @@ static uae_u32 REGPARAM2 bsdsocklib_SocketBaseTagList (TrapContext *context)
m68k_areg (regs, 0), currtag);
goto done;
}
}
}
}
BSDTRACE ((","));
tagptr += 8;
}
}
done:
BSDTRACE ((") -> %d\n", tagsprocessed));
return tagsprocessed;
return tagsprocessed;
}
static uae_u32 REGPARAM2 bsdsocklib_GetSocketEvents (TrapContext *context)
{
#ifdef _WIN32
struct socketbase *sb = get_socketbase (context);
int i;
int flags;
uae_u32 ptr = m68k_areg (regs, 0);
struct socketbase *sb = get_socketbase (context);
int i;
int flags;
uae_u32 ptr = m68k_areg (regs, 0);
BSDTRACE (("GetSocketEvents(0x%x) -> ", ptr));
for (i = sb->dtablesize; i--; sb->eventindex++) {
for (i = sb->dtablesize; i--; sb->eventindex++) {
if (sb->eventindex >= sb->dtablesize)
sb->eventindex = 0;
sb->eventindex = 0;
if (sb->mtable[sb->eventindex]) {
flags = sb->ftable[sb->eventindex] & SET_ALL;
if (flags) {
flags = sb->ftable[sb->eventindex] & SET_ALL;
if (flags) {
sb->ftable[sb->eventindex] &= ~SET_ALL;
put_long (m68k_areg (regs, 0), flags >> 8);
BSDTRACE (("%d (0x%x)\n", sb->eventindex + 1, flags >> 8));
return sb->eventindex; // xxx
}
}
}
}
}
#endif
BSDTRACE (("-1\n"));
return -1;
return -1;
}
static uae_u32 REGPARAM2 bsdsocklib_getdtablesize (TrapContext *context)
{
return get_socketbase (context)->dtablesize;
return get_socketbase (context)->dtablesize;
}
static uae_u32 REGPARAM2 bsdsocklib_null (TrapContext *context)
{
return 0;
return 0;
}
static uae_u32 REGPARAM2 bsdsocklib_init (TrapContext *context)
{
uae_u32 tmp1;
int i;
uae_u32 tmp1;
int i;
write_log ("Creating UAE bsdsocket.library 4.1\n");
if (SockLibBase)
if (SockLibBase)
bsdlib_reset ();
m68k_areg (regs, 0) = functable;
m68k_areg (regs, 1) = datatable;
m68k_areg (regs, 2) = 0;
m68k_dreg (regs, 0) = LIBRARY_SIZEOF;
m68k_dreg (regs, 1) = 0;
m68k_areg (regs, 0) = functable;
m68k_areg (regs, 1) = datatable;
m68k_areg (regs, 2) = 0;
m68k_dreg (regs, 0) = LIBRARY_SIZEOF;
m68k_dreg (regs, 1) = 0;
tmp1 = CallLib (context, m68k_areg (regs, 6), -0x54); /* MakeLibrary */
if (!tmp1) {
if (!tmp1) {
write_log ("bsdoscket: FATAL: Cannot create bsdsocket.library!\n");
return 0;
}
m68k_areg (regs, 1) = tmp1;
}
m68k_areg (regs, 1) = tmp1;
CallLib (context, m68k_areg (regs, 6), -0x18c); /* AddLibrary */
SockLibBase = tmp1;
SockLibBase = tmp1;
/* Install error strings in Amiga memory */
tmp1 = 0;
for (i = number_sys_error; i--;)
/* Install error strings in Amiga memory */
tmp1 = 0;
for (i = number_sys_error; i--;)
tmp1 += _tcslen (errortexts[i]) + 1;
for (i = number_host_error; i--;)
for (i = number_host_error; i--;)
tmp1 += _tcslen (herrortexts[i]) + 1;
tmp1 += _tcslen (strErr) + 1;
m68k_dreg (regs, 0) = tmp1;
m68k_dreg (regs, 1) = 0;
m68k_dreg (regs, 0) = tmp1;
m68k_dreg (regs, 1) = 0;
tmp1 = CallLib (context, get_long (4), -0xC6); /* AllocMem */
if (!tmp1) {
if (!tmp1) {
write_log ("bsdsocket: FATAL: Ran out of memory while creating bsdsocket.library!\n");
return 0;
}
for (i = 0; i < (int) (number_sys_error); i++)
}
for (i = 0; i < (int) (number_sys_error); i++)
errnotextptrs[i] = addstr (&tmp1, errortexts[i]);
for (i = 0; i < (int) (number_host_error); i++)
for (i = 0; i < (int) (number_host_error); i++)
herrnotextptrs[i] = addstr (&tmp1, herrortexts[i]);
strErrptr = addstr (&tmp1, strErr);
strErrptr = addstr (&tmp1, strErr);
#if 0
/* @@@ someone please implement a proper interrupt handler setup here :) */
......@@ -1361,22 +1362,23 @@ static uae_u32 REGPARAM2 bsdsocklib_init (TrapContext *context)
put_long (context->regs.vbr + 0x78, tmp1);
#endif
m68k_dreg (regs, 0) = 1;
return 0;
m68k_dreg (regs, 0) = 1;
return 0;
}
void bsdlib_reset (void)
{
SB, *nsb;
int i;
SB, *nsb;
int i;
if (!SockLibBase)
return;
SockLibBase = 0;
SockLibBase = 0;
write_log ("BSDSOCK: cleanup start..\n");
for (sb = socketbases; sb; sb = nsb) {
host_sbcleanup (NULL);
for (sb = socketbases; sb; sb = nsb) {
nsb = sb->next;
write_log ("BSDSOCK: cleanup start socket %x\n", sb);
......@@ -1386,53 +1388,53 @@ void bsdlib_reset (void)
free (sb->ftable);
free (sb);
}
}
write_log ("BSDSOCK: cleanup end\n");
socketbases = NULL;
sbsigqueue = NULL;
socketbases = NULL;
sbsigqueue = NULL;
for (i = 0; i < SOCKPOOLSIZE; i++) {
for (i = 0; i < SOCKPOOLSIZE; i++) {
if (sockdata->sockpoolids[i] != UNIQUE_ID) {
sockdata->sockpoolids[i] = UNIQUE_ID;
host_closesocketquick (sockdata->sockpoolsocks[i]);
}
}
}
host_sbreset ();
host_sbreset ();
write_log ("BSDSOCK: cleanup finished\n");
}
static const TrapHandler sockfuncs[] = {
bsdsocklib_init, bsdsocklib_Open, bsdsocklib_Close, bsdsocklib_Expunge,
bsdsocklib_socket, bsdsocklib_bind, bsdsocklib_listen, bsdsocklib_accept,
bsdsocklib_connect, bsdsocklib_sendto, bsdsocklib_send, bsdsocklib_recvfrom, bsdsocklib_recv,
bsdsocklib_shutdown, bsdsocklib_setsockopt, bsdsocklib_getsockopt, bsdsocklib_getsockname,
bsdsocklib_getpeername, bsdsocklib_IoctlSocket, bsdsocklib_CloseSocket, bsdsocklib_WaitSelect,
bsdsocklib_SetSocketSignals, bsdsocklib_getdtablesize, bsdsocklib_ObtainSocket, bsdsocklib_ReleaseSocket,
bsdsocklib_ReleaseCopyOfSocket, bsdsocklib_Errno, bsdsocklib_SetErrnoPtr, bsdsocklib_Inet_NtoA,
bsdsocklib_inet_addr, bsdsocklib_Inet_LnaOf, bsdsocklib_Inet_NetOf, bsdsocklib_Inet_MakeAddr,
bsdsocklib_inet_network, bsdsocklib_gethostbyname, bsdsocklib_gethostbyaddr, bsdsocklib_getnetbyname,
bsdsocklib_getnetbyaddr, bsdsocklib_getservbyname, bsdsocklib_getservbyport, bsdsocklib_getprotobyname,
bsdsocklib_getprotobynumber, bsdsocklib_vsyslog, bsdsocklib_Dup2Socket, bsdsocklib_sendmsg,
bsdsocklib_recvmsg, bsdsocklib_gethostname, bsdsocklib_gethostid, bsdsocklib_SocketBaseTagList,
bsdsocklib_GetSocketEvents
bsdsocklib_init, bsdsocklib_Open, bsdsocklib_Close, bsdsocklib_Expunge,
bsdsocklib_socket, bsdsocklib_bind, bsdsocklib_listen, bsdsocklib_accept,
bsdsocklib_connect, bsdsocklib_sendto, bsdsocklib_send, bsdsocklib_recvfrom, bsdsocklib_recv,
bsdsocklib_shutdown, bsdsocklib_setsockopt, bsdsocklib_getsockopt, bsdsocklib_getsockname,
bsdsocklib_getpeername, bsdsocklib_IoctlSocket, bsdsocklib_CloseSocket, bsdsocklib_WaitSelect,
bsdsocklib_SetSocketSignals, bsdsocklib_getdtablesize, bsdsocklib_ObtainSocket, bsdsocklib_ReleaseSocket,
bsdsocklib_ReleaseCopyOfSocket, bsdsocklib_Errno, bsdsocklib_SetErrnoPtr, bsdsocklib_Inet_NtoA,
bsdsocklib_inet_addr, bsdsocklib_Inet_LnaOf, bsdsocklib_Inet_NetOf, bsdsocklib_Inet_MakeAddr,
bsdsocklib_inet_network, bsdsocklib_gethostbyname, bsdsocklib_gethostbyaddr, bsdsocklib_getnetbyname,
bsdsocklib_getnetbyaddr, bsdsocklib_getservbyname, bsdsocklib_getservbyport, bsdsocklib_getprotobyname,
bsdsocklib_getprotobynumber, bsdsocklib_vsyslog, bsdsocklib_Dup2Socket, bsdsocklib_sendmsg,
bsdsocklib_recvmsg, bsdsocklib_gethostname, bsdsocklib_gethostid, bsdsocklib_SocketBaseTagList,
bsdsocklib_GetSocketEvents
};
static const char * const funcnames[] = {
"bsdsocklib_init", "bsdsocklib_Open", "bsdsocklib_Close", "bsdsocklib_Expunge",
"bsdsocklib_socket", "bsdsocklib_bind", "bsdsocklib_listen", "bsdsocklib_accept",
"bsdsocklib_connect", "bsdsocklib_sendto", "bsdsocklib_send", "bsdsocklib_recvfrom", "bsdsocklib_recv",
"bsdsocklib_shutdown", "bsdsocklib_setsockopt", "bsdsocklib_getsockopt", "bsdsocklib_getsockname",
"bsdsocklib_getpeername", "bsdsocklib_IoctlSocket", "bsdsocklib_CloseSocket", "bsdsocklib_WaitSelect",
"bsdsocklib_SetSocketSignals", "bsdsocklib_getdtablesize", "bsdsocklib_ObtainSocket", "bsdsocklib_ReleaseSocket",
"bsdsocklib_ReleaseCopyOfSocket", "bsdsocklib_Errno", "bsdsocklib_SetErrnoPtr", "bsdsocklib_Inet_NtoA",
"bsdsocklib_inet_addr", "bsdsocklib_Inet_LnaOf", "bsdsocklib_Inet_NetOf", "bsdsocklib_Inet_MakeAddr",
"bsdsocklib_inet_network", "bsdsocklib_gethostbyname", "bsdsocklib_gethostbyaddr", "bsdsocklib_getnetbyname",
"bsdsocklib_getnetbyaddr", "bsdsocklib_getservbyname", "bsdsocklib_getservbyport", "bsdsocklib_getprotobyname",
"bsdsocklib_getprotobynumber", "bsdsocklib_vsyslog", "bsdsocklib_Dup2Socket", "bsdsocklib_sendmsg",
"bsdsocklib_recvmsg", "bsdsocklib_gethostname", "bsdsocklib_gethostid", "bsdsocklib_SocketBaseTagList",
"bsdsocklib_GetSocketEvents"
static const TCHAR * const funcnames[] = {
"bsdsocklib_init", "bsdsocklib_Open", "bsdsocklib_Close", "bsdsocklib_Expunge",
"bsdsocklib_socket", "bsdsocklib_bind", "bsdsocklib_listen", "bsdsocklib_accept",
"bsdsocklib_connect", "bsdsocklib_sendto", "bsdsocklib_send", "bsdsocklib_recvfrom", "bsdsocklib_recv",
"bsdsocklib_shutdown", "bsdsocklib_setsockopt", "bsdsocklib_getsockopt", "bsdsocklib_getsockname",
"bsdsocklib_getpeername", "bsdsocklib_IoctlSocket", "bsdsocklib_CloseSocket", "bsdsocklib_WaitSelect",
"bsdsocklib_SetSocketSignals", "bsdsocklib_getdtablesize", "bsdsocklib_ObtainSocket", "bsdsocklib_ReleaseSocket",
"bsdsocklib_ReleaseCopyOfSocket", "bsdsocklib_Errno", "bsdsocklib_SetErrnoPtr", "bsdsocklib_Inet_NtoA",
"bsdsocklib_inet_addr", "bsdsocklib_Inet_LnaOf", "bsdsocklib_Inet_NetOf", "bsdsocklib_Inet_MakeAddr",
"bsdsocklib_inet_network", "bsdsocklib_gethostbyname", "bsdsocklib_gethostbyaddr", "bsdsocklib_getnetbyname",
"bsdsocklib_getnetbyaddr", "bsdsocklib_getservbyname", "bsdsocklib_getservbyport", "bsdsocklib_getprotobyname",
"bsdsocklib_getprotobynumber", "bsdsocklib_vsyslog", "bsdsocklib_Dup2Socket", "bsdsocklib_sendmsg",
"bsdsocklib_recvmsg", "bsdsocklib_gethostname", "bsdsocklib_gethostid", "bsdsocklib_SocketBaseTagList",
"bsdsocklib_GetSocketEvents"
};
static uae_u32 sockfuncvecs[sizeof (sockfuncs) / sizeof (*sockfuncs)];
......@@ -1457,7 +1459,7 @@ uaecptr bsdlib_startup (uaecptr resaddr)
void bsdlib_install (void)
{
int i;
int i;
if (!sockdata) {
sockdata = xcalloc (struct sockd, 1);
......@@ -1465,57 +1467,57 @@ void bsdlib_install (void)
sockdata->sockpoolids[i] = UNIQUE_ID;
}
if (!init_socket_layer ())
if (!init_socket_layer ())
return;
res_name = ds ("bsdsocket.library");
res_id = ds ("UAE bsdsocket.library 4.1");
for (i = 0; i < (int) (sizeof (sockfuncs) / sizeof (sockfuncs[0])); i++) {
sockfuncvecs[i] = here ();
calltrap (deftrap2 (sockfuncs[i], TRAPFLAG_EXTRA_STACK, funcnames[i]));
dw (RTS);
}
/* FuncTable */
functable = here ();
for (i = 1; i < 4; i++)
dl (sockfuncvecs[i]); /* Open / Close / Expunge */
dl (EXPANSION_nullfunc); /* Null */
for (i = 4; i < (int) (sizeof (sockfuncs) / sizeof (sockfuncs[0])); i++)
dl (sockfuncvecs[i]);
dl (0xFFFFFFFF); /* end of table */
/* DataTable */
datatable = here ();
dw (0xE000); /* INITBYTE */
dw (0x0008); /* LN_TYPE */
dw (0x0900); /* NT_LIBRARY */
for (i = 0; i < (int) (sizeof (sockfuncs) / sizeof (sockfuncs[0])); i++) {
sockfuncvecs[i] = here ();
calltrap (deftrap2 (sockfuncs[i], TRAPFLAG_EXTRA_STACK, funcnames[i]));
dw (RTS);
}
/* FuncTable */
functable = here ();
for (i = 1; i < 4; i++)
dl (sockfuncvecs[i]); /* Open / Close / Expunge */
dl (EXPANSION_nullfunc); /* Null */
for (i = 4; i < (int) (sizeof (sockfuncs) / sizeof (sockfuncs[0])); i++)
dl (sockfuncvecs[i]);
dl (0xFFFFFFFF); /* end of table */
/* DataTable */
datatable = here ();
dw (0xE000); /* INITBYTE */
dw (0x0008); /* LN_TYPE */
dw (0x0900); /* NT_LIBRARY */
dw (0xE000); /* INITBYTE */
dw (0x0009); /* LN_PRI */
dw (0xCE00); /* -50 */
dw (0xC000); /* INITLONG */
dw (0x000A); /* LN_NAME */
dw (0xC000); /* INITLONG */
dw (0x000A); /* LN_NAME */
dl (res_name);
dw (0xE000); /* INITBYTE */
dw (0x000E); /* LIB_FLAGS */
dw (0x0600); /* LIBF_SUMUSED | LIBF_CHANGED */
dw (0xD000); /* INITWORD */
dw (0x0014); /* LIB_VERSION */
dw (0x0004);
dw (0xD000);
dw (0x0016); /* LIB_REVISION */
dw (0x0001);
dw (0xC000);
dw (0x0018); /* LIB_IDSTRING */
dw (0xE000); /* INITBYTE */
dw (0x000E); /* LIB_FLAGS */
dw (0x0600); /* LIBF_SUMUSED | LIBF_CHANGED */
dw (0xD000); /* INITWORD */
dw (0x0014); /* LIB_VERSION */
dw (0x0004);
dw (0xD000);
dw (0x0016); /* LIB_REVISION */
dw (0x0001);
dw (0xC000);
dw (0x0018); /* LIB_IDSTRING */
dl (res_id);
dl (0x00000000); /* end of table */
dl (0x00000000); /* end of table */
res_init = here ();
dl (512);
dl (functable);
dl (functable);
dl (datatable);
dl (*sockfuncvecs);
dl (*sockfuncvecs);
write_log ("bsdsocked.library installed\n");
}
......
/*
* UAE - The Un*x Amiga Emulator
*
* MC68881 emulation
*
* Copyright 1996 Herman ten Brugge
* Adapted for JIT compilation (c) Bernd Meyer, 2000
* Modified 2005 Peter Keunecke
*/
/*
* UAE - The Un*x Amiga Emulator
*
* MC68881 emulation
*
* Copyright 1996 Herman ten Brugge
* Adapted for JIT compilation (c) Bernd Meyer, 2000
* Modified 2005 Peter Keunecke
*/
#include <math.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 = 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/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/dms/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/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);
......@@ -11,6 +11,7 @@ struct zfile {
uae_u8 *data; // unpacked data
int dataseek; // use seek position even if real file
struct zfile *archiveparent; // set if parent is archive and this has not yet been unpacked (datasize < size)
int archiveid;
uae_s64 size; // real size
uae_s64 datasize; // available size (not yet unpacked completely?)
uae_s64 seek; // seek position
......@@ -98,6 +99,7 @@ struct zarchive_info
#define PEEK_BYTES 1024
#define FILE_PEEK 1
#define FILE_DELAYEDOPEN 2
extern int zfile_is_ignore_ext (const TCHAR *name);
......@@ -141,5 +143,6 @@ extern void archive_access_scan (struct zfile *zf, zfile_callback zc, void *user
extern void archive_access_close (void *handle, unsigned int id);
extern struct zfile *archive_getzfile (struct znode *zn, unsigned int id, int flags);
extern struct zfile *archive_unpackzfile (struct zfile *zf);
extern struct zfile *decompress_zfd (struct zfile*);
\ No newline at end of file
......@@ -33,6 +33,7 @@ typedef int (*zfile_callback)(struct zfile*, void*);
extern struct zfile *zfile_fopen (const TCHAR *, const TCHAR *, int mask);
extern struct zfile *zfile_fopen2 (const TCHAR *, const TCHAR *, int mask, int index);
extern struct zfile *zfile_fopen_empty (struct zfile*, const TCHAR *name, uae_u64 size);
extern struct zfile *zfile_fopen_empty2 (struct zfile*, const TCHAR *name);
extern struct zfile *zfile_fopen_data (const TCHAR *name, uae_u64 size, uae_u8 *data);
extern struct zfile *zfile_fopen_parent (struct zfile*, const TCHAR*, uae_u64 offset, uae_u64 size);
......@@ -42,7 +43,7 @@ extern uae_s64 zfile_fseek (struct zfile *z, uae_s64 offset, int mode);
extern uae_s64 zfile_ftell (struct zfile *z);
extern uae_s64 zfile_size (struct zfile *z);
extern size_t zfile_fread (void *b, size_t l1, size_t l2, struct zfile *z);
extern size_t zfile_fwrite (const void *b, size_t l1, size_t l2, struct zfile *z);
extern size_t zfile_fwrite (void *b, size_t l1, size_t l2, struct zfile *z);
extern TCHAR *zfile_fgets (TCHAR *s, int size, struct zfile *z);
extern char *zfile_fgetsa (char *s, int size, struct zfile *z);
extern size_t zfile_fputs (struct zfile *z, TCHAR *s);
......@@ -66,7 +67,6 @@ extern int zfile_is_diskimage (const TCHAR *name);
extern int iszip (struct zfile *z);
extern int zfile_convertimage (const TCHAR *src, const TCHAR *dst);
//extern struct zfile *zuncompress (struct znode*, struct zfile *z, int dodefault, int mask, int *retcode, int index);
static struct zfile *zuncompress (struct zfile *z);
extern void zfile_seterror (const TCHAR *format, ...);
extern TCHAR *zfile_geterror (void);
......@@ -79,6 +79,7 @@ extern TCHAR *zfile_geterror (void);
#define ZFD_CD 32 //cue/iso, cue has priority over iso
#define ZFD_DISKHISTORY 0x100 //allow diskhistory (if disk image)
#define ZFD_CHECKONLY 0x200 //file exists checkc
#define ZFD_DELAYEDOPEN 0x400 //do not unpack, just get metadata
#define ZFD_NORMAL (ZFD_ARCHIVE|ZFD_UNPACK)
#define ZFD_ALL 0x0000ffff
......@@ -101,17 +102,19 @@ extern const TCHAR *uae_ignoreextensions[];
extern const TCHAR *uae_diskimageextensions[];
extern struct zvolume *zfile_fopen_archive (const TCHAR *filename);
extern struct zvolume *zfile_fopen_archive2 (const TCHAR *filename, bool norecurse);
extern struct zvolume *zfile_fopen_archive_root (const TCHAR *filename);
extern void zfile_fclose_archive (struct zvolume *zv);
extern int zfile_fs_usage_archive (const TCHAR *path, const TCHAR *disk, struct fs_usage *fsp);
extern int zfile_stat_archive (const TCHAR *path, struct _stat64 *statbuf);
extern void *zfile_opendir_archive (const TCHAR *path);
extern void zfile_closedir_archive (void*);
extern int zfile_readdir_archive (void*, TCHAR*);
extern void zfile_resetdir_archive (void*);
extern zfile_fill_file_attrs_archive (const TCHAR *path, int *isdir, int *flags, TCHAR **comment);
extern uae_s64 zfile_lseek_archive (void *d, uae_s64 offset, int whence);
extern unsigned int zfile_read_archive (void *d, void *b, unsigned int size);
extern void zfile_close_archive (void *d);
extern void *zfile_open_archive (const TCHAR *path, int flags);
extern int zfile_exists_archive(const TCHAR *path, const TCHAR *rel);
extern struct zdirectory *zfile_opendir_archive (const TCHAR *path);
extern void zfile_closedir_archive (struct zdirectory *);
extern int zfile_readdir_archive (struct zdirectory *, TCHAR*);
extern int zfile_readdir_archive2 (struct zdirectory *, TCHAR*, bool fullpath);
extern void zfile_resetdir_archive (struct zdirectory *);
extern int zfile_fill_file_attrs_archive (const TCHAR *path, int *isdir, int *flags, TCHAR **comment);
extern uae_s64 zfile_lseek_archive (struct zfile *d, uae_s64 offset, int whence);
extern unsigned int zfile_read_archive (struct zfile *d, void *b, unsigned int size);
extern void zfile_close_archive (struct zfile *d);
extern struct zfile *zfile_open_archive (const TCHAR *path, int flags);
extern int zfile_exists_archive (const TCHAR *path, const TCHAR *rel);
......@@ -973,3 +973,24 @@ void clearallkeys (void)
{
inputdevice_updateconfig (&currprefs);
}
//fsdb_mywin32.c
FILE *my_opentext (const TCHAR *name)
{
FILE *f;
uae_u8 tmp[4];
int v;
f = _tfopen (name, "rb");
if (!f)
return NULL;
v = fread (tmp, 1, 4, f);
fclose (f);
if (v == 4) {
if (tmp[0] == 0xef && tmp[1] == 0xbb && tmp[2] == 0xbf)
return _tfopen (name, "r, ccs=UTF-8");
if (tmp[0] == 0xff && tmp[1] == 0xfe)
return _tfopen (name, "r, ccs=UTF-16LE");
}
return _tfopen (name, "r");
}
......@@ -28,8 +28,8 @@
<key>CFBundleName</key>
<string>PUAE</string>
<key>CFBundleGetInfoString</key>
<string>2.3.0</string>
<string>2.2.0</string>
<key>CFBundleVersion</key>
<string>2.3.0</string>
<string>2.2.0</string>
</dict>
</plist>
......@@ -293,7 +293,7 @@
#define PACKAGE_NAME "PUAE"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "PUAE 2.3.0"
#define PACKAGE_STRING "PUAE 2.2.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "puae"
......@@ -302,7 +302,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "2.3.0"
#define PACKAGE_VERSION "2.2.0"
/* Define to the necessary symbol if this constant uses a non-standard name on
your system. */
......@@ -395,7 +395,7 @@
/* Version number of package */
#define VERSION "2.3.0"
#define VERSION "2.2.0"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
......
......@@ -445,7 +445,7 @@ configure:4344: $? = 0
configure:4344: result: yes
configure:4350: checking for _doprnt
configure:4350: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5
/tmp/cc0HrNmb.o: In function `main':
/tmp/ccsRj39K.o: In function `main':
/home/gnostic/puaex/src/tools/conftest.c:67: undefined reference to `_doprnt'
collect2: ld returned 1 exit status
configure:4350: $? = 1
......@@ -533,7 +533,7 @@ configure:4364: $? = 0
configure:4364: result: yes
configure:4364: checking for strcmpi
configure:4364: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5
/tmp/ccicgnNt.o: In function `main':
/tmp/ccHamKwY.o: In function `main':
/home/gnostic/puaex/src/tools/conftest.c:69: undefined reference to `strcmpi'
collect2: ld returned 1 exit status
configure:4364: $? = 1
......@@ -613,7 +613,7 @@ configure: failed program was:
configure:4364: result: no
configure:4364: checking for stricmp
configure:4364: gcc -o conftest -g -O2 -Wall -W -Wno-unused conftest.c >&5
/tmp/ccl1sm5w.o: In function `main':
/tmp/ccfzHOQ3.o: In function `main':
/home/gnostic/puaex/src/tools/conftest.c:69: undefined reference to `stricmp'
collect2: ld returned 1 exit status
configure:4364: $? = 1
......@@ -817,7 +817,7 @@ PACKAGE_URL=''
PACKAGE_VERSION=''
PATH_SEPARATOR=':'
SET_MAKE=''
SHELL='/bin/bash'
SHELL='/bin/sh'
ac_ct_CC='gcc'
ac_cv_c_inline='inline'
bindir='${exec_prefix}/bin'
......
#! /bin/bash
#! /bin/sh
# Generated by configure.
# Run this file to recreate the current configuration.
# Compiler output produced by configure, useful for debugging
......@@ -8,7 +8,7 @@ debug=false
ac_cs_recheck=false
ac_cs_silent=false
SHELL=${CONFIG_SHELL-/bin/bash}
SHELL=${CONFIG_SHELL-/bin/sh}
export SHELL
## -------------------- ##
## M4sh Initialization. ##
......@@ -522,10 +522,10 @@ if $ac_cs_silent; then
fi
if $ac_cs_recheck; then
set X '/bin/bash' './configure' '--disable-option-checking' '--prefix=/usr/local' '--with-sdl' '--with-sdl-gl' '--with-sdl-gfx' '--with-sdl-sound' '--with-caps' '--with-gayle' '--enable-drvsnd' '--enable-amax' '--enable-cd32' '--enable-scsi-device' '--cache-file=/dev/null' '--srcdir=.' $ac_configure_extra_args --no-create --no-recursion
set X '/bin/sh' './configure' '--disable-option-checking' '--prefix=/usr/local' '--with-sdl' '--with-sdl-gl' '--with-sdl-gfx' '--with-sdl-sound' '--with-caps' '--with-gayle' '--enable-drvsnd' '--enable-amax' '--enable-cd32' '--enable-scsi-device' '--cache-file=/dev/null' '--srcdir=.' $ac_configure_extra_args --no-create --no-recursion
shift
$as_echo "running CONFIG_SHELL=/bin/bash $*" >&6
CONFIG_SHELL='/bin/bash'
$as_echo "running CONFIG_SHELL=/bin/sh $*" >&6
CONFIG_SHELL='/bin/sh'
export CONFIG_SHELL
exec "$@"
fi
......@@ -685,7 +685,7 @@ S["PACKAGE_VERSION"]=""
S["PACKAGE_TARNAME"]=""
S["PACKAGE_NAME"]=""
S["PATH_SEPARATOR"]=":"
S["SHELL"]="/bin/bash"
S["SHELL"]="/bin/sh"
_ACAWK
cat >>"$tmp/subs1.awk" <<_ACAWK &&
for (key in S) S_is_set[key] = 1
......
......@@ -369,7 +369,7 @@ static uae_u32 REGPARAM2 uaelib_demux2 (TrapContext *context)
#ifndef UAEGFX_INTERNAL
// if (ARG0 >= 16 && ARG0 <= 39)
// return picasso_demux (ARG0, context);
// return picasso_demux (ARG0, context);
#endif
switch (ARG0)
......
/* 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(fin,pi)
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 (fin,pX)
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 (fin,pX)
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 (fileName1,fileName2)
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 (fileName1,fileName2,iCaseSensitivity)
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(fin)
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 (fin)
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 (file)
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 (file,pglobal_info)
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 (ulDosDate, ptm)
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 (file,
pfile_info,
pfile_info_internal,
szFileName, fileNameBufferSize,
extraField, extraFieldBufferSize,
szComment, commentBufferSize)
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 (file,
pfile_info,
szFileName, fileNameBufferSize,
extraField, extraFieldBufferSize,
szComment, commentBufferSize)
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 (file)
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 (file)
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 (file, szFileName, iCaseSensitivity)
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 (s,piSizeVar,
poffset_local_extrafield,
psize_local_extrafield)
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 (file)
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);
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 (file, buf, len)
unzFile file;
voidp buf;
unsigned 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 (file)
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 (file)
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 (file,buf,len)
unzFile file;
voidp buf;
unsigned 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 (file)
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 (file, szComment, uSizeBuf)
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;
}
......@@ -25,9 +25,10 @@
#include "diskutil.h"
#include "fdi2raw.h"
#include "unzip.h"
#include "dms/cdata.h"
#include "dms/pfile.h"
#include "archivers/zip/unzip.h"
#include "archivers/dms/cdata.h"
#include "archivers/dms/pfile.h"
#include "archivers/wrp/warp.h"
#include <zlib.h>
#include <stdarg.h>
......@@ -193,10 +194,6 @@ void zfile_exit (void)
void zfile_fclose (struct zfile *f)
{
struct zfile *pl = NULL;
struct zfile *l = zlist;
struct zfile *nxt;
//write_log ("%p\n", f);
if (!f)
return;
......@@ -213,6 +210,9 @@ void zfile_fclose (struct zfile *f)
if (f->parent->opencnt <= 0)
zfile_fclose (f->parent);
}
struct zfile *pl = NULL;
struct zfile *nxt;
struct zfile *l = zlist;
while (l != f) {
if (l == 0) {
write_log ("zfile: tried to free already freed or nonexisting filehandle!\n");
......@@ -270,7 +270,7 @@ int zfile_gettype (struct zfile *z)
return ZFILE_NVR;
if (strcasecmp (ext, "uae") == 0)
return ZFILE_CONFIGURATION;
if (strcasecmp (ext, "cue") == 0 || strcasecmp (ext, "iso") == 0)
if (strcasecmp (ext, "cue") == 0 || strcasecmp (ext, "iso") == 0 || strcasecmp (ext, "ccd") == 0 || strcasecmp (ext, "mds") == 0)
return ZFILE_CDIMAGE;
}
memset (buf, 0, sizeof (buf));
......@@ -536,7 +536,7 @@ struct zfile *zfile_gunzip (struct zfile *z)
zfile_fread (aname + i, 1, 1, z);
} while (i < MAX_DPATH - 1 && aname[i++]);
aname[i] = 0;
memcpy (name, aname, MAX_DPATH);
au_copy (name, MAX_DPATH, aname);
}
if (flags & 16) { /* skip comment */
i = 0;
......@@ -569,7 +569,7 @@ struct zfile *zfile_gunzip (struct zfile *z)
zs.next_in = buffer;
zs.avail_in = zfile_fread (buffer, 1, sizeof (buffer), z);
if (first) {
if (inflateInit2 (&zs, -MAX_WBITS) != Z_OK)
if (inflateInit2_ (&zs, -MAX_WBITS, ZLIB_VERSION, sizeof (z_stream)) != Z_OK)
break;
first = 0;
}
......@@ -1032,6 +1032,7 @@ static struct zfile *dsq (struct zfile *z, int lzx)
static struct zfile *wrp (struct zfile *z)
{
//return unwarp (z);
return z;
}
static struct zfile *bunzip (const char *decompress, struct zfile *z)
......@@ -1249,155 +1250,139 @@ int iszip (struct zfile *z)
return 0;
}
static struct zfile *unzip (struct zfile *z)
struct zfile *zuncompress (struct znode *parent, struct zfile *z, int dodefault, int mask, int *retcode, int index)
{
unzFile uz;
unz_file_info file_info;
char filename_inzip[2048];
struct zfile *zf;
unsigned int err, zipcnt, i, we_have_file = 0;
int select;
char tmphist[MAX_DPATH];
int first = 1;
TCHAR *name = z->name;
TCHAR *ext = NULL;
uae_u8 header[32];
int i;
zf = 0;
uz = unzOpen (z);
if (!uz)
return z;
if (unzGoToFirstFile (uz) != UNZ_OK)
return z;
zipcnt = 1;
tmphist[0] = 0;
for (;;) {
err = unzGetCurrentFileInfo(uz,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
if (err != UNZ_OK)
return z;
if (file_info.uncompressed_size > 0) {
i = 0;
while (uae_ignoreextensions[i]) {
if (strlen(filename_inzip) > strlen (uae_ignoreextensions[i]) &&
!strcasecmp (uae_ignoreextensions[i], filename_inzip + strlen (filename_inzip) - strlen (uae_ignoreextensions[i])))
break;
i++;
}
if (!uae_ignoreextensions[i]) {
if (tmphist[0]) {
DISK_history_add (tmphist, -1, 0, 0);
tmphist[0] = 0;
first = 0;
}
if (first) {
if (zfile_is_diskimage (filename_inzip))
sprintf (tmphist,"%s/%s", z->name, filename_inzip);
} else {
sprintf (tmphist,"%s/%s", z->name, filename_inzip);
DISK_history_add (tmphist, -1, 0, 0);
tmphist[0] = 0;
}
select = 0;
if (!z->zipname)
select = 1;
if (z->zipname && !strcasecmp (z->zipname, filename_inzip))
select = -1;
if (z->zipname && z->zipname[0] == '#' && atol (z->zipname + 1) == (int)zipcnt)
select = -1;
if (select && !we_have_file) {
unsigned int err = unzOpenCurrentFile (uz);
if (err == UNZ_OK) {
zf = zfile_fopen_empty (NULL, filename_inzip, file_info.uncompressed_size);
if (zf) {
err = unzReadCurrentFile (uz, zf->data, file_info.uncompressed_size);
unzCloseCurrentFile (uz);
if (err == 0 || err == file_info.uncompressed_size) {
zf = zuncompress (zf);
if (select < 0 || zfile_gettype (zf)) {
we_have_file = 1;
}
}
}
if (!we_have_file) {
zfile_fclose (zf);
zf = 0;
}
}
}
}
if (retcode)
*retcode = 0;
if (!mask)
return NULL;
if (name) {
ext = _tcsrchr (name, '.');
if (ext)
ext++;
}
zipcnt++;
err = unzGoToNextFile (uz);
if (err != UNZ_OK)
break;
}
if (zf) {
zfile_fclose (z);
z = zf;
}
return z;
}
static struct zfile *zuncompress (struct zfile *z)
{
int retcode, index;
char *name = z->name;
char *ext = strrchr (name, '.');
uae_u8 header[4];
if (ext != NULL) {
ext++;
if (strcasecmp (ext, "zip") == 0)
return unzip (z);
if (strcasecmp (ext, "gz") == 0)
return zfile_gunzip (z);
if (strcasecmp (ext, "adz") == 0)
return zfile_gunzip (z);
if (strcasecmp (ext, "roz") == 0)
return zfile_gunzip (z);
if (strcasecmp (ext, "dms") == 0)
return dms (z, index, retcode);
if (strcasecmp (ext, "lha") == 0
|| strcasecmp (ext, "lzh") == 0)
return lha (z);
/* if (mask & ZFD_ARCHIVE) {
if (strcasecmp (ext, "7z") == 0)
return archive_access_select (parent, z, ArchiveFormat7Zip, dodefault, retcode, index);
if (strcasecmp (ext, "zip") == 0)
return archive_access_select (parent, z, ArchiveFormatZIP, dodefault, retcode, index);
if (strcasecmp (ext, "lha") == 0 || strcasecmp (ext, "lzh") == 0)
return archive_access_select (parent, z, ArchiveFormatLHA, dodefault, retcode, index);
if (strcasecmp (ext, "lzx") == 0)
return archive_access_select (parent, z, ArchiveFormatLZX, dodefault, retcode, index);
if (strcasecmp (ext, "rar") == 0)
return archive_access_select (parent, z, ArchiveFormatRAR, dodefault, retcode, index);
if (strcasecmp (ext, "tar") == 0)
return archive_access_select (parent, z, ArchiveFormatTAR, dodefault, retcode, index);
}*/
if (mask & ZFD_UNPACK) {
if (index == 0) {
// if (strcasecmp (ext, "zip") == 0)
// return unzip (z);
if (strcasecmp (ext, "gz") == 0)
return zfile_gunzip (z);
if (strcasecmp (ext, "adz") == 0)
return zfile_gunzip (z);
if (strcasecmp (ext, "roz") == 0)
return zfile_gunzip (z);
if (strcasecmp (ext, "hdz") == 0)
return zfile_gunzip (z);
if (strcasecmp (ext, "wrp") == 0)
return wrp (z);
// if (strcasecmp (ext, "xz") == 0)
// return xz (z);
}
if (strcasecmp (ext, "dms") == 0)
return dms (z, index, retcode);
}
if (mask & ZFD_RAWDISK) {
#ifdef CAPS
if (strcasecmp (ext, "ipf") == 0)
return ipf (z, index, retcode);
#endif
if (strcasecmp (ext, "fdi") == 0)
return fdi (z, index, retcode);
if (mask & (ZFD_RAWDISK_PC | ZFD_RAWDISK_AMIGA))
return NULL;
}
if (strcasecmp (ext, "lha") == 0 || strcasecmp (ext, "lzh") == 0)
return lha (z);
}
memset (header, 0, sizeof (header));
zfile_fseek (z, 0, SEEK_SET);
zfile_fread (header, sizeof (header), 1, z);
zfile_fseek (z, 0, SEEK_SET);
if (header[0] == 0x1f && header[1] == 0x8b)
return zfile_gunzip (z);
if (header[0] == 'P' && header[1] == 'K')
return unzip (z);
if (header[0] == 'D' && header[1] == 'M' && header[2] == 'S' && header[3] == '!')
return dms (z, index, retcode);
}
return z;
}
static FILE *openzip (char *name, char *zippath)
{
int i;
char v;
i = strlen (name) - 2;
if (zippath)
zippath[0] = 0;
while (i > 0) {
if ((name[i] == '/' || name[i] == '\\') && i > 4) {
v = name[i];
name[i] = 0;
if (!strcasecmp (name + i - 4, ".zip")) {
FILE *f = fopen (name, "rb");
if (f) {
if (zippath)
strcpy (zippath, name + i + 1);
return f;
if (!memcmp (header, "conectix", 8)) {
if (index > 0)
return NULL;
return vhd (z);
}
if (mask & ZFD_UNPACK) {
if (index == 0) {
if (header[0] == 0x1f && header[1] == 0x8b)
return zfile_gunzip (z);
// if (header[0] == 'P' && header[1] == 'K')
// return unzip (z);
if (header[0] == 'P' && header[1] == 'K' && header[2] == 'D')
return dsq (z, 0);
// if (header[0] == 0xfd && header[1] == 0x37 && header[2] == 0x7a && header[3] == 0x58 && header[4] == 0x5a && header[5] == 0)
// return xz (z);
}
}
name[i] = v;
if (header[0] == 'D' && header[1] == 'M' && header[2] == 'S' && header[3] == '!')
return dms (z, index, retcode);
}
if (mask & ZFD_RAWDISK) {
#ifdef CAPS
if (header[0] == 'C' && header[1] == 'A' && header[2] == 'P' && header[3] == 'S')
return ipf (z, index, retcode);
#endif
if (!memcmp (header, "Formatte", 8))
return fdi (z, index, retcode);
if (!memcmp (header, "UAE-1ADF", 8))
return extadf (z, index, retcode);
}
i--;
}
return 0;
if (index > 0)
return NULL;
/* if (mask & ZFD_ARCHIVE) {
if (header[0] == 'P' && header[1] == 'K')
return archive_access_select (parent, z, ArchiveFormatZIP, dodefault, retcode, index);
if (header[0] == 'R' && header[1] == 'a' && header[2] == 'r' && header[3] == '!')
return archive_access_select (parent, z, ArchiveFormatRAR, dodefault, retcode, index);
if (header[0] == 'L' && header[1] == 'Z' && header[2] == 'X')
return archive_access_select (parent, z, ArchiveFormatLZX, dodefault, retcode, index);
if (header[2] == '-' && header[3] == 'l' && header[4] == 'h' && header[6] == '-')
return archive_access_select (parent, z, ArchiveFormatLHA, dodefault, retcode, index);
}
if (mask & ZFD_ADF) {
if (header[0] == 'D' && header[1] == 'O' && header[2] == 'S' && (header[3] >= 0 && header[3] <= 7))
return archive_access_select (parent, z, ArchiveFormatADF, dodefault, retcode, index);
if (header[0] == 'S' && header[1] == 'F' && header[2] == 'S')
return archive_access_select (parent, z, ArchiveFormatADF, dodefault, retcode, index);
if (isfat (header))
return archive_access_select (parent, z, ArchiveFormatFAT, dodefault, retcode, index);
}*/
/* if (ext) {
if (mask & ZFD_UNPACK) {
if (strcasecmp (ext, "dsq") == 0)
return dsq (z, 1);
}
if (mask & ZFD_ADF) {
if (strcasecmp (ext, "adf") == 0 && !memcmp (header, "DOS", 3))
return archive_access_select (parent, z, ArchiveFormatADF, dodefault, retcode, index);
}
}*/
return NULL;
}
#ifdef SINGLEFILE
extern uae_u8 singlefile_data[];
......@@ -1436,45 +1421,389 @@ static struct zfile *zfile_opensinglefile(struct zfile *l)
}
#endif
/*
* fopen() for a compressed file
*/
struct zfile *zfile_fopen (const char *name, const char *mode, int mask)
static struct zfile *zfile_fopen_nozip (const TCHAR *name, const TCHAR *mode)
{
struct zfile *l;
FILE *f;
char zipname[1000];
if(*name == '\0')
return NULL;
l = zfile_create (NULL);
l->name = strdup (name);
l->mode = strdup (mode);
l->name = my_strdup (name);
l->mode = my_strdup (mode);
f = _tfopen (name, mode);
if (!f) {
zfile_fclose (l);
return 0;
}
l->f = f;
return l;
}
static struct zfile *openzip (const TCHAR *pname)
{
int i, j;
TCHAR v;
TCHAR name[MAX_DPATH];
TCHAR zippath[MAX_DPATH];
zippath[0] = 0;
_tcscpy (name, pname);
i = _tcslen (name) - 2;
while (i > 0) {
if (name[i] == '/' || name[i] == '\\' && i > 4) {
v = name[i];
name[i] = 0;
for (j = 0; plugins_7z[j]; j++) {
int len = _tcslen (plugins_7z[j]);
if (name[i - len - 1] == '.' && !strcasecmp (name + i - len, plugins_7z[j])) {
struct zfile *f = zfile_fopen_nozip (name, "rb");
if (f) {
f->zipname = my_strdup (name + i + 1);
return f;
}
break;
}
}
name[i] = v;
}
i--;
}
return 0;
}
static struct zfile *zfile_fopen_2 (const TCHAR *name, const TCHAR *mode, int mask)
{
struct zfile *l;
FILE *f;
if(*name == '\0')
return NULL;
#ifdef SINGLEFILE
if (zfile_opensinglefile (l))
return l;
#endif
f = openzip (l->name, zipname);
if (f) {
if (_tcsicmp (mode, "rb")) {
l = openzip (name);
if (l) {
if (_tcsicmp (mode, "rb") && _tcsicmp (mode, "r")) {
zfile_fclose (l);
fclose (f);
return 0;
return 0;
}
l->zfdmask = mask;
} else {
struct stat64 st;
l = zfile_create (NULL);
l->mode = my_strdup (mode);
l->name = my_strdup (name);
l->zfdmask = mask;
if (!_tcsicmp (mode, "r")) {
f = my_opentext (l->name);
l->textmode = 1;
} else {
f = _tfopen (l->name, mode);
}
if (!f) {
zfile_fclose (l);
return 0;
}
if (stat (l->name, &st) != -1)
l->size = st.st_size;
l->f = f;
}
l->zipname = strdup (zipname);
return l;
}
#ifdef _WIN32
#include "win32.h"
#define AF "%AMIGAFOREVERDATA%"
static void manglefilename (TCHAR *out, const TCHAR *in)
{
int i;
out[0] = 0;
if (!strncasecmp (in, AF, _tcslen (AF)))
_tcscpy (out, start_path_data);
if ((in[0] == '/' || in[0] == '\\') || (_tcslen(in) > 3 && in[1] == ':' && in[2] == '\\'))
out[0] = 0;
_tcscat (out, in);
for (i = 0; i < _tcslen (out); i++) {
// remove \\ or // in the middle of path
if ((out[i] == '/' || out[i] == '\\') && (out[i + 1] == '/' || out[i + 1] == '\\') && i > 0) {
memmove (out + i, out + i + 1, (_tcslen (out + i) + 1) * sizeof (TCHAR));
i--;
continue;
}
}
if (!f) {
f = fopen (name, mode);
if (!f) {
zfile_fclose (l);
}
#else
static void manglefilename(TCHAR *out, const TCHAR *in)
{
_tcscpy (out, in);
}
#endif
int zfile_zopen (const TCHAR *name, zfile_callback zc, void *user)
{
struct zfile *l;
int ztype;
TCHAR path[MAX_DPATH];
manglefilename (path, name);
l = zfile_fopen_2 (path, L"rb", ZFD_NORMAL);
if (!l)
return 0;
ztype = iszip (l);
if (ztype == 0)
zc (l, user);
/* else
archive_access_scan (l, zc, user, ztype);*/
zfile_fclose (l);
return 1;
}
/*
* fopen() for a compressed file
*/
static struct zfile *zfile_fopen_x (const TCHAR *name, const TCHAR *mode, int mask, int index)
{
int cnt = 10;
struct zfile *l, *l2;
TCHAR path[MAX_DPATH];
if (_tcslen (name) == 0)
return NULL;
manglefilename (path, name);
l = zfile_fopen_2 (path, mode, mask);
if (!l)
return 0;
if (_tcschr (mode, 'w') || _tcschr (mode, 'a'))
return l;
l2 = NULL;
while (cnt-- > 0) {
int rc;
zfile_fseek (l, 0, SEEK_SET);
l2 = zuncompress (NULL, l, 0, mask, &rc, index);
if (!l2) {
if (rc < 0) {
zfile_fclose (l);
return NULL;
}
zfile_fseek (l, 0, SEEK_SET);
break;
} else {
if (l2->parent == l)
l->opencnt--;
}
l = l2;
}
}
l->f = f;
l = zuncompress (l);
return l;
}
#ifdef _WIN32
static int isinternetfile (const TCHAR *name)
{
if (!_tcsnicmp (name, "http://", 7) || !_tcsnicmp (name, "https://", 8))
return 1;
if (!_tcsnicmp (name, "ftp://", 6))
return -1;
return 0;
}
#include <wininet.h>
#define INETBUFFERLEN 1000000
static struct zfile *zfile_fopen_internet (const TCHAR *name, const TCHAR *mode, int mask)
{
static HINTERNET hi;
HINTERNET i = NULL;
TCHAR tmp[MAX_DPATH];
DWORD ierr = 0;
DWORD outbuf = sizeof tmp / sizeof (TCHAR);
uae_u8 *data = 0;
int bufferlen = INETBUFFERLEN;
int datalen;
DWORD didread;
struct zfile *zf = NULL;
if (_tcschr (mode, 'w') || _tcschr (mode, 'a'))
return NULL;
tmp[0] = 0;
if (!hi) {
hi = InternetOpen (WINUAEAPPNAME, INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY, NULL, NULL, 0);
if (hi == NULL) {
write_log (L"InternetOpen() failed, %d\n", GetLastError ());
return NULL;
}
}
i = InternetOpenUrl (hi, name, NULL, 0, INTERNET_FLAG_NO_COOKIES, 0);
if (i == NULL) {
DWORD err = GetLastError ();
if (err == ERROR_INTERNET_EXTENDED_ERROR)
InternetGetLastResponseInfo (&ierr, tmp, &outbuf);
write_log (L"InternetOpenUrl(%s) failed %d (%d,%s)\n", name, err, ierr, tmp);
goto end;
}
if (isinternetfile (name) > 0) {
DWORD statuscode;
DWORD hindex = 0;
DWORD size = sizeof statuscode;
if (!HttpQueryInfo (i, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &statuscode, &size, &hindex)) {
DWORD err = GetLastError ();
write_log (L"HttpQueryInfo(%s) failed %d\n", name, err);
goto end;
}
if (statuscode != 200) {
write_log (L"HttpQueryInfo(%s)=%d\n", name, statuscode);
goto end;
}
}
if (mask & ZFD_CHECKONLY) {
zf = zfile_create (NULL);
goto end;
}
datalen = 0;
data = xmalloc (uae_u8, bufferlen);
for (;;) {
if (!InternetReadFile (i, data + datalen, INETBUFFERLEN, &didread)) {
DWORD err = GetLastError ();
if (err == ERROR_INTERNET_EXTENDED_ERROR)
InternetGetLastResponseInfo (&ierr, tmp, &outbuf);
write_log (L"InternetReadFile(%s) failed %d (%d,%s)\n", name, err, ierr, tmp);
break;
}
if (didread == 0)
break;
datalen += didread;
if (datalen > bufferlen - INETBUFFERLEN) {
bufferlen += INETBUFFERLEN;
data = xrealloc (uae_u8, data, bufferlen);
if (!data) {
datalen = 0;
break;
}
}
}
if (datalen > 0) {
zf = zfile_create (NULL);
if (zf) {
zf->size = datalen;
zf->data = data;
data = NULL;
}
}
end:
if (i)
InternetCloseHandle (i);
free (data);
return zf;
}
#endif
static struct zfile *zfile_fopenx2 (const TCHAR *name, const TCHAR *mode, int mask, int index)
{
struct zfile *f;
TCHAR tmp[MAX_DPATH];
TCHAR dirsep[2] = { FSDB_DIR_SEPARATOR, '\0' };
#ifdef _WIN32
if (isinternetfile (name))
return zfile_fopen_internet (name, mode, mask);
#endif
f = zfile_fopen_x (name, mode, mask, index);
if (f)
return f;
if (_tcslen (name) <= 2)
return NULL;
if (name[1] != ':') {
// _tcscpy (tmp, start_path_data);
_tcscpy (tmp, "./");
_tcscat (tmp, name);
f = zfile_fopen_x (tmp, mode, mask, index);
if (f)
return f;
}
#if 0
name += 2;
if (name[0] == '/' || name[0] == '\\')
name++;
for (;;) {
_tcscpy (tmp, start_path_data);
_tcscpy (tmp, name);
f = zfile_fopen_x (tmp, mode, mask);
if (f)
return f;
while (name[0]) {
name++;
if (name[-1] == '/' || name[-1] == '\\')
break;
}
if (name[0] == 0)
break;
}
#endif
return NULL;
}
static struct zfile *zfile_fopenx (const TCHAR *name, const TCHAR *mode, int mask, int index)
{
struct zfile *zf;
//write_log (L"zfile_fopen('%s','%s',%08x,%d)\n", name, mode, mask, index);
zf = zfile_fopenx2 (name, mode, mask, index);
//write_log (L"=%p\n", zf);
return zf;
}
struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode, int mask)
{
return zfile_fopenx (name, mode, mask, 0);
}
struct zfile *zfile_fopen2 (const TCHAR *name, const TCHAR *mode, int mask, int index)
{
return zfile_fopenx (name, mode, mask, index);
}
struct zfile *zfile_dup (struct zfile *zf)
{
struct zfile *nzf;
if (!zf)
return NULL;
if (zf->userdata)
return NULL;
if (!zf->data && zf->dataseek) {
nzf = zfile_create (zf);
} else if (zf->data) {
nzf = zfile_create (zf);
nzf->data = xmalloc (uae_u8, zf->size);
memcpy (nzf->data, zf->data, zf->size);
nzf->size = zf->size;
nzf->datasize = zf->datasize;
} else {
if (zf->zipname) {
nzf = openzip (zf->name);
if (nzf)
return nzf;
}
FILE *ff = _tfopen (zf->name, zf->mode);
if (!ff)
return NULL;
nzf = zfile_create (zf);
nzf->f = ff;
}
zfile_fseek (nzf, zf->seek, SEEK_SET);
if (zf->name)
nzf->name = my_strdup (zf->name);
if (nzf->zipname)
nzf->zipname = my_strdup (zf->zipname);
nzf->zfdmask = zf->zfdmask;
nzf->mode = my_strdup (zf->mode);
nzf->size = zf->size;
return nzf;
}
int zfile_exists (const TCHAR *name)
{
struct zfile *z;
......@@ -1642,7 +1971,7 @@ size_t zfile_fread (void *b, size_t l1, size_t l2, struct zfile *z)
return fread (b, l1, l2, z->f);
}
size_t zfile_fwrite (const void *b, size_t l1, size_t l2, struct zfile *z)
size_t zfile_fwrite (void *b, size_t l1, size_t l2, struct zfile *z)
{
if (z->zfilewrite)
return z->zfilewrite (b, l1, l2, z);
......@@ -1715,7 +2044,7 @@ TCHAR *zfile_fgets (TCHAR *s, int size, struct zfile *z)
*p = 0;
if (size > strlen (s2) + 1)
size = strlen (s2) + 1;
memcpy (s, s2, size);
au_copy (s, size, s2);
return s + size;
} else {
char s2[MAX_DPATH];
......@@ -1725,7 +2054,7 @@ TCHAR *zfile_fgets (TCHAR *s, int size, struct zfile *z)
return NULL;
if (size > strlen (s2) + 1)
size = strlen (s2) + 1;
memcpy (s, s2, size);
au_copy (s, size, s2);
return s + size;
}
}
......@@ -1764,14 +2093,10 @@ uae_u8 *zfile_getdata (struct zfile *z, uae_s64 offset, int len)
zfile_fseek (z, 0, SEEK_SET);
}
b = xmalloc (uae_u8, len);
if (z->data) {
memcpy (b, z->data + offset, len);
} else {
pos = zfile_ftell (z);
zfile_fseek (z, offset, SEEK_SET);
zfile_fread (b, len, 1, z);
zfile_fseek (z, pos, SEEK_SET);
}
pos = zfile_ftell (z);
zfile_fseek (z, offset, SEEK_SET);
zfile_fread (b, len, 1, z);
zfile_fseek (z, pos, SEEK_SET);
return b;
}
......@@ -1782,8 +2107,8 @@ int zfile_zuncompress (void *dst, int dstsize, struct zfile *src, int srcsize)
uae_u8 inbuf[4096];
int incnt;
memset (&zs, 0, sizeof(zs));
if (inflateInit (&zs) != Z_OK)
memset (&zs, 0, sizeof (zs));
if (inflateInit_ (&zs, ZLIB_VERSION, sizeof (z_stream)) != Z_OK)
return 0;
zs.next_out = (Bytef*)dst;
zs.avail_out = dstsize;
......@@ -1813,7 +2138,7 @@ int zfile_zcompress (struct zfile *f, void *src, int size)
uae_u8 outbuf[4096];
memset (&zs, 0, sizeof (zs));
if (deflateInit (&zs, Z_DEFAULT_COMPRESSION) != Z_OK)
if (deflateInit_ (&zs, Z_DEFAULT_COMPRESSION, ZLIB_VERSION, sizeof (z_stream)) != Z_OK)
return 0;
zs.next_in = (Bytef*)src;
zs.avail_in = size;
......@@ -1873,6 +2198,496 @@ uae_u32 zfile_crc32 (struct zfile *f)
return crc;
}
static struct zvolume *zvolume_list;
static void recurparent (TCHAR *newpath, struct znode *zn, int recurse)
{
TCHAR tmp[2] = { FSDB_DIR_SEPARATOR, 0 };
if (zn->parent && (&zn->volume->root != zn->parent || zn->volume->parentz == NULL)) {
if (&zn->volume->root == zn->parent && zn->volume->parentz == NULL && !_tcscmp (zn->name, zn->parent->name))
goto end;
recurparent (newpath, zn->parent, recurse);
} else {
struct zvolume *zv = zn->volume;
if (zv->parentz && recurse)
recurparent (newpath, zv->parentz, recurse);
}
end:
if (newpath[0])
_tcscat (newpath, tmp);
_tcscat (newpath, zn->name);
}
static struct znode *znode_alloc (struct znode *parent, const TCHAR *name)
{
TCHAR fullpath[MAX_DPATH];
TCHAR tmpname[MAX_DPATH];
struct znode *zn = xcalloc (struct znode, 1);
struct znode *zn2;
TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
_tcscpy (tmpname, name);
zn2 = parent->child;
while (zn2) {
if (!_tcscmp (zn2->name, tmpname)) {
TCHAR *ext = _tcsrchr (tmpname, '.');
if (ext && ext > tmpname + 2 && ext[-2] == '.') {
ext[-1]++;
} else if (ext) {
memmove (ext + 2, ext, (_tcslen (ext) + 1) * sizeof (TCHAR));
ext[0] = '.';
ext[1] = '1';
} else {
int len = _tcslen (tmpname);
tmpname[len] = '.';
tmpname[len + 1] = '1';
tmpname[len + 2] = 0;
}
zn2 = parent->child;
continue;
}
zn2 = zn2->sibling;
}
fullpath[0] = 0;
recurparent (fullpath, parent, 0);
_tcscat (fullpath, sep);
_tcscat (fullpath, tmpname);
#ifdef ZFILE_DEBUG
write_log ("znode_alloc vol='%s' parent='%s' name='%s'\n", parent->volume->root.name, parent->name, name);
#endif
zn->fullname = my_strdup (fullpath);
zn->name = my_strdup (tmpname);
zn->volume = parent->volume;
zn->volume->last->next = zn;
zn->prev = zn->volume->last;
zn->volume->last = zn;
return zn;
}
static struct znode *znode_alloc_child (struct znode *parent, const TCHAR *name)
{
struct znode *zn = znode_alloc (parent, name);
if (!parent->child) {
parent->child = zn;
} else {
struct znode *pn = parent->child;
while (pn->sibling)
pn = pn->sibling;
pn->sibling = zn;
}
zn->parent = parent;
return zn;
}
static struct znode *znode_alloc_sibling (struct znode *sibling, const TCHAR *name)
{
struct znode *zn = znode_alloc (sibling->parent, name);
if (!sibling->sibling) {
sibling->sibling = zn;
} else {
struct znode *pn = sibling->sibling;
while (pn->sibling)
pn = pn->sibling;
pn->sibling = zn;
}
zn->parent = sibling->parent;
return zn;
}
static void zvolume_addtolist (struct zvolume *zv)
{
if (!zv)
return;
if (!zvolume_list) {
zvolume_list = zv;
} else {
struct zvolume *v = zvolume_list;
while (v->next)
v = v->next;
v->next = zv;
}
}
static struct zvolume *zvolume_alloc_2 (const TCHAR *name, struct zfile *z, unsigned int id, void *handle, const TCHAR *volname)
{
struct zvolume *zv = xcalloc (struct zvolume, 1);
struct znode *root;
uae_s64 pos;
int i;
root = &zv->root;
zv->last = root;
zv->archive = z;
zv->handle = handle;
zv->id = id;
zv->blocks = 4;
if (z)
zv->zfdmask = z->zfdmask;
root->volume = zv;
root->type = ZNODE_DIR;
i = 0;
if (name[0] != '/' && name[0] != '\\') {
if (_tcschr (name, ':') == 0) {
for (i = _tcslen (name) - 1; i > 0; i--) {
if (name[i] == FSDB_DIR_SEPARATOR) {
i++;
break;
}
}
}
}
root->name = my_strdup (name + i);
root->fullname = my_strdup (name);
#ifdef ZFILE_DEBUG
write_log ("created zvolume: '%s' (%s)\n", root->name, root->fullname);
#endif
if (volname)
zv->volumename = my_strdup (volname);
if (z) {
pos = zfile_ftell (z);
zfile_fseek (z, 0, SEEK_END);
zv->archivesize = zfile_ftell (z);
zfile_fseek (z, pos, SEEK_SET);
}
return zv;
}
struct zvolume *zvolume_alloc (struct zfile *z, unsigned int id, void *handle, const TCHAR *volumename)
{
return zvolume_alloc_2 (zfile_getname (z), z, id, handle, volumename);
}
struct zvolume *zvolume_alloc_nofile (const TCHAR *name, unsigned int id, void *handle, const TCHAR *volumename)
{
return zvolume_alloc_2 (name, NULL, id, handle, volumename);
}
struct zvolume *zvolume_alloc_empty (struct zvolume *prev, const TCHAR *name)
{
struct zvolume *zv = zvolume_alloc_2(name, 0, 0, 0, NULL);
if (!zv)
return NULL;
if (prev)
zv->zfdmask = prev->zfdmask;
return zv;
}
static struct zvolume *get_zvolume (const TCHAR *path)
{
struct zvolume *zv = zvolume_list;
while (zv) {
TCHAR *s = zfile_getname (zv->archive);
if (!s)
s = zv->root.name;
if (_tcslen (path) >= _tcslen (s) && !memcmp (path, s, _tcslen (s) * sizeof (TCHAR)))
return zv;
zv = zv->next;
}
return NULL;
}
static struct zvolume *zfile_fopen_archive_ext (struct znode *parent, struct zfile *zf)
{
struct zvolume *zv = NULL;
TCHAR *name = zfile_getname (zf);
TCHAR *ext;
uae_u8 header[7];
if (!name)
return NULL;
memset (header, 0, sizeof (header));
zfile_fseek (zf, 0, SEEK_SET);
zfile_fread (header, sizeof (header), 1, zf);
zfile_fseek (zf, 0, SEEK_SET);
ext = _tcsrchr (name, '.');
if (ext != NULL) {
ext++;
if (strcasecmp (ext, "lha") == 0 || strcasecmp (ext, "lzh") == 0)
zv = archive_directory_lha (zf);
if (strcasecmp (ext, "zip") == 0)
zv = archive_directory_zip (zf);
if (strcasecmp (ext, "7z") == 0)
zv = archive_directory_7z (zf);
if (strcasecmp (ext, "lzx") == 0)
zv = archive_directory_lzx (zf);
if (strcasecmp (ext, "rar") == 0)
zv = archive_directory_rar (zf);
if (strcasecmp (ext, "tar") == 0)
zv = archive_directory_tar (zf);
if (strcasecmp (ext, "adf") == 0 && !memcmp (header, "DOS", 3))
zv = archive_directory_adf (parent, zf);
if (strcasecmp (ext, "hdf") == 0) {
if (!memcmp (header, "RDSK", 4))
zv = archive_directory_rdb (zf);
else
zv = archive_directory_adf (parent, zf);
}
}
return zv;
}
static struct zvolume *zfile_fopen_archive_data (struct znode *parent, struct zfile *zf)
{
struct zvolume *zv = NULL;
uae_u8 header[32];
memset (header, 0, sizeof (header));
zfile_fread (header, sizeof (header), 1, zf);
zfile_fseek (zf, 0, SEEK_SET);
if (header[0] == 'P' && header[1] == 'K')
zv = archive_directory_zip (zf);
if (header[0] == 'R' && header[1] == 'a' && header[2] == 'r' && header[3] == '!')
zv = archive_directory_rar (zf);
if (header[0] == 'L' && header[1] == 'Z' && header[2] == 'X')
zv = archive_directory_lzx (zf);
if (header[2] == '-' && header[3] == 'l' && header[4] == 'h' && header[6] == '-')
zv = archive_directory_lha (zf);
if (header[0] == 'D' && header[1] == 'O' && header[2] == 'S' && (header[3] >= 0 && header[3] <= 7))
zv = archive_directory_adf (parent, zf);
if (header[0] == 'R' && header[1] == 'D' && header[2] == 'S' && header[3] == 'K')
zv = archive_directory_rdb (zf);
if (isfat (header))
zv = archive_directory_fat (zf);
return zv;
}
static struct znode *get_znode (struct zvolume *zv, const TCHAR *ppath, int);
static void zfile_fopen_archive_recurse2 (struct zvolume *zv, struct znode *zn)
{
struct zvolume *zvnew;
struct znode *zndir;
TCHAR tmp[MAX_DPATH];
_stprintf (tmp, "%s.DIR", zn->fullname + _tcslen (zv->root.name) + 1);
zndir = get_znode (zv, tmp, 1);
if (!zndir) {
struct zarchive_info zai = { 0 };
zvnew = zvolume_alloc_empty (zv, tmp);
zvnew->parentz = zn;
zai.name = tmp;
zai.t = zn->mtime;
zai.comment = zv->volumename;
if (zn->flags < 0)
zai.flags = zn->flags;
zndir = zvolume_adddir_abs (zv, &zai);
zndir->type = ZNODE_VDIR;
zndir->vfile = zn;
zndir->vchild = zvnew;
zvnew->parent = zv;
zndir->offset = zn->offset;
zndir->offset2 = zn->offset2;
}
}
static int zfile_fopen_archive_recurse (struct zvolume *zv)
{
struct znode *zn;
int i, added;
added = 0;
zn = zv->root.child;
while (zn) {
int done = 0;
struct zfile *z;
TCHAR *ext = _tcsrchr (zn->name, '.');
if (ext && !zn->vchild && zn->type == ZNODE_FILE) {
for (i = 0; !done && archive_extensions[i]; i++) {
if (!strcasecmp (ext + 1, archive_extensions[i])) {
zfile_fopen_archive_recurse2 (zv, zn);
done = 1;
}
}
}
if (!done) {
z = archive_getzfile (zn, zv->method, 0);
if (z && iszip (z))
zfile_fopen_archive_recurse2 (zv, zn);
}
zn = zn->next;
}
return 0;
}
static struct zvolume *prepare_recursive_volume (struct zvolume *zv, const TCHAR *path)
{
struct zfile *zf = NULL;
struct zvolume *zvnew = NULL;
int done = 0;
#ifdef ZFILE_DEBUG
write_log ("unpacking '%s'\n", path);
#endif
zf = zfile_open_archive (path, 0);
if (!zf)
goto end;
zvnew = zfile_fopen_archive_ext (zv->parentz, zf);
if (!zvnew) {
#if 1
zvnew = archive_directory_plain (zf);
zfile_fopen_archive_recurse (zvnew);
done = 1;
#else
int rc;
int index;
struct zfile *zf2, *zf3;
TCHAR oldname[MAX_DPATH];
_tcscpy (oldname, zf->name);
index = 0;
for (;;) {
zf3 = zfile_dup (zf);
if (!zf3)
break;
zf2 = zuncompress (&zv->root, zf3, 0, ZFD_ALL, &rc, index);
if (zf2) {
zvnew = archive_directory_plain (zf2);
if (zvnew) {
zvnew->parent = zv->parent;
zfile_fopen_archive_recurse (zvnew);
done = 1;
}
} else {
zfile_fclose (zf3);
if (rc <= 0)
break;
}
index++;
break; // TODO
}
#endif
} else {
zvnew->parent = zv->parent;
zfile_fopen_archive_recurse (zvnew);
done = 1;
}
if (!done)
goto end;
zfile_fclose_archive (zv);
return zvnew;
end:
write_log ("unpack '%s' failed\n", path);
zfile_fclose_archive (zvnew);
zfile_fclose (zf);
return NULL;
}
static struct znode *get_znode (struct zvolume *zv, const TCHAR *ppath, int recurse)
{
struct znode *zn;
TCHAR path[MAX_DPATH], zpath[MAX_DPATH];
if (!zv)
return NULL;
_tcscpy (path, ppath);
zn = &zv->root;
while (zn) {
zpath[0] = 0;
recurparent (zpath, zn, recurse);
if (zn->type == ZNODE_FILE) {
if (!_tcsicmp (zpath, path))
return zn;
} else {
int len = _tcslen (zpath);
if (_tcslen (path) >= len && (path[len] == 0 || path[len] == FSDB_DIR_SEPARATOR) && !_tcsnicmp (zpath, path, len)) {
if (path[len] == 0)
return zn;
if (zn->vchild) {
/* jump to separate tree, recursive archives */
struct zvolume *zvdeep = zn->vchild;
if (zvdeep->archive == NULL) {
TCHAR newpath[MAX_DPATH];
newpath[0] = 0;
recurparent (newpath, zn, recurse);
#ifdef ZFILE_DEBUG
write_log ("'%s'\n", newpath);
#endif
zvdeep = prepare_recursive_volume (zvdeep, newpath);
if (!zvdeep) {
write_log ("failed to unpack '%s'\n", newpath);
return NULL;
}
/* replace dummy empty volume with real volume */
zn->vchild = zvdeep;
zvdeep->parentz = zn;
}
zn = zvdeep->root.child;
} else {
zn = zn->child;
}
continue;
}
}
zn = zn->sibling;
}
return NULL;
}
static void addvolumesize (struct zvolume *zv, uae_s64 size)
{
unsigned int blocks = (size + 511) / 512;
if (blocks == 0)
blocks++;
while (zv) {
zv->blocks += blocks;
zv->size += size;
zv = zv->parent;
}
}
struct znode *znode_adddir (struct znode *parent, const TCHAR *name, struct zarchive_info *zai)
{
struct znode *zn;
TCHAR path[MAX_DPATH];
TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
path[0] = 0;
//recurparent (path, parent, 0);
_tcscat (path, sep);
_tcscat (path, name);
//zn = get_znode (parent->volume, path, 0);
if (zn)
return zn;
zn = znode_alloc_child (parent, name);
zn->mtime = zai->t;
zn->type = ZNODE_DIR;
if (zai->comment)
zn->comment = my_strdup (zai->comment);
if (zai->flags < 0)
zn->flags = zai->flags;
addvolumesize (parent->volume, 0);
return zn;
}
struct znode *zvolume_adddir_abs (struct zvolume *zv, struct zarchive_info *zai)
{
struct znode *zn2;
TCHAR *path = my_strdup (zai->name);
TCHAR *p, *p2;
int i;
if (_tcslen (path) > 0) {
/* remove possible trailing / or \ */
TCHAR last;
last = path[_tcslen (path) - 1];
if (last == '/' || last == '\\')
path[_tcslen (path) - 1] = 0;
}
zn2 = &zv->root;
p = p2 = path;
for (i = 0; path[i]; i++) {
if (path[i] == '/' || path[i] == '\\') {
path[i] = 0;
zn2 = znode_adddir (zn2, p, zai);
path[i] = FSDB_DIR_SEPARATOR;
p = p2 = &path[i + 1];
}
}
return znode_adddir (zn2, p, zai);
}
#ifdef _CONSOLE
static TCHAR *zerror;
#define WRITE_LOG_BUF_SIZE 4096
......
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