merged 2.2 branch
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@7748 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
134
utils/Install/packace/globals.c
Normal file
134
utils/Install/packace/globals.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* */
|
||||
/* Global variable declarations */
|
||||
/* */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#include "acestruc.h"
|
||||
#include "unace.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//-------- Ace sign
|
||||
const char *acesign = "**ACE**";
|
||||
|
||||
//-------- Version string for program
|
||||
const char *version="UNACE v1.1 public version\n";
|
||||
|
||||
#ifdef AMIGA
|
||||
//-------- Version string for VERSION program
|
||||
static char *_version="$VER: Unace Amiga 1.1 "__AMIGADATE__"\n\n";
|
||||
#endif
|
||||
|
||||
//-------- header buffer and pointers
|
||||
thead head;
|
||||
|
||||
tmhead *t_mhead = (tmhead *) & head;
|
||||
tfhead *t_fhead = (tfhead *) & head;
|
||||
|
||||
//-------- buffers
|
||||
ULONG *buf_rd =0;
|
||||
CHAR *buf =0;
|
||||
CHAR *buf_wr =0;
|
||||
UCHAR *readbuf =0;
|
||||
|
||||
//-------- decompressor variables
|
||||
SHORT rpos =0,
|
||||
dcpr_do =0,
|
||||
dcpr_do_max =0,
|
||||
blocksize =0,
|
||||
dcpr_dic =0,
|
||||
dcpr_oldnum =0,
|
||||
bits_rd =0,
|
||||
dcpr_frst_file =0;
|
||||
USHORT dcpr_code_mn[1 << maxwd_mn],
|
||||
dcpr_code_lg[1 << maxwd_lg];
|
||||
UCHAR dcpr_wd_mn[maxcode + 2],
|
||||
dcpr_wd_lg[maxcode + 2],
|
||||
wd_svwd[svwd_cnt];
|
||||
ULONG dcpr_dpos =0,
|
||||
cpr_dpos2 =0,
|
||||
dcpr_dicsiz =0,
|
||||
dcpr_dican =0,
|
||||
dcpr_size =0,
|
||||
dcpr_olddist[4]={0,0,0,0},
|
||||
code_rd =0;
|
||||
|
||||
CHAR *dcpr_text =0;
|
||||
|
||||
//-------- quicksort
|
||||
USHORT sort_org[maxcode + 2];
|
||||
UCHAR sort_freq[(maxcode + 2) * 2];
|
||||
|
||||
//-------- file handling
|
||||
CHAR aname[PATH_MAX];
|
||||
INT archan,
|
||||
wrhan;
|
||||
#if !defined(__EMX__) && !defined(__OS2__)
|
||||
FILE *farchan = NULL;
|
||||
#endif
|
||||
LONG skipsize=0;
|
||||
|
||||
//-------- structures for archive handling
|
||||
struct tadat adat;
|
||||
|
||||
//-------- flags
|
||||
INT f_err =0,
|
||||
f_ovrall =0,
|
||||
f_allvol_pr=0,
|
||||
f_curpas =0,
|
||||
f_criterr =0;
|
||||
|
||||
|
||||
void resetglobals(void)
|
||||
{
|
||||
t_mhead = (tmhead *) & head;
|
||||
t_fhead = (tfhead *) & head;
|
||||
|
||||
buf_rd =0;
|
||||
buf =0;
|
||||
buf_wr =0;
|
||||
readbuf =0;
|
||||
|
||||
rpos =0;
|
||||
dcpr_do =0;
|
||||
dcpr_do_max =0;
|
||||
blocksize =0;
|
||||
dcpr_dic =0;
|
||||
dcpr_oldnum =0;
|
||||
bits_rd =0;
|
||||
dcpr_frst_file =0;
|
||||
|
||||
memset(&dcpr_code_mn, 0, sizeof(dcpr_code_mn));
|
||||
memset(&dcpr_code_lg, 0, sizeof(dcpr_code_lg));
|
||||
memset(&dcpr_wd_mn, 0, sizeof(dcpr_wd_mn));
|
||||
memset(&dcpr_wd_lg, 0, sizeof(dcpr_wd_lg));
|
||||
memset(&wd_svwd, 0, sizeof(wd_svwd));
|
||||
dcpr_dpos =0;
|
||||
cpr_dpos2 =0;
|
||||
dcpr_dicsiz =0;
|
||||
dcpr_dican =0;
|
||||
dcpr_size =0;
|
||||
|
||||
memset(&dcpr_olddist, 0, sizeof(dcpr_olddist));
|
||||
|
||||
code_rd =0;
|
||||
dcpr_text =0;
|
||||
|
||||
memset(&sort_org, 0, sizeof(sort_org));
|
||||
memset(&sort_freq, 0, sizeof(sort_freq));
|
||||
|
||||
archan=0;
|
||||
wrhan=0;
|
||||
skipsize=0;
|
||||
|
||||
f_err =0;
|
||||
f_ovrall =0;
|
||||
f_allvol_pr=0;
|
||||
f_curpas =0;
|
||||
f_criterr =0;
|
||||
|
||||
}
|
46
utils/Install/packace/makefile
Normal file
46
utils/Install/packace/makefile
Normal file
@@ -0,0 +1,46 @@
|
||||
# Installer Makefile
|
||||
|
||||
CC = gcc
|
||||
RM = rm -f
|
||||
RC = rc
|
||||
MAKE = make
|
||||
|
||||
DEFS =
|
||||
LIBS =
|
||||
|
||||
CFLAGS = -O -g -I../incace -Wall
|
||||
LDFLAGS =
|
||||
|
||||
|
||||
OBJECTS = globals.o packinst.o uac_comm.o uac_crc.o \
|
||||
uac_crt.o uac_dcpr.o uac_sys.o unace.o
|
||||
|
||||
SOURCES = globals.c ../packinst/packinst.c uac_comm.c \
|
||||
uac_crc.c uac_crt.c uac_dcpr.c uac_sys.c unace.c
|
||||
|
||||
all: packinst
|
||||
|
||||
$(OBJECTS):
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
Include: ../incace/Makefile Makefile
|
||||
# cd include
|
||||
# $(MAKE) -f Makefile all
|
||||
|
||||
packinst: $(OBJECTS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $(DEFS) -o packinst $(OBJECTS)
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJECTS) packinst *~
|
||||
|
||||
globals.o: globals.c ../incace/globals.h ../incace/acestruc.h ../incace/unace.h
|
||||
packinst.o: ../packinst/packinst.c
|
||||
uac_comm.o: uac_comm.c ../incace/globals.h ../incace/uac_dcpr.h ../incace/uac_comm.h
|
||||
uac_crc.o: uac_crc.c ../incace/uac_crc.h
|
||||
uac_crt.o: uac_crt.c ../incace/os.h ../incace/attribs.h ../incace/globals.h ../incace/uac_crt.h ../incace/uac_sys.h
|
||||
uac_dcpr.o: uac_dcpr.c ../incace/os.h ../incace/globals.h ../incace/portable.h ../incace/uac_comm.h ../incace/uac_crc.h \
|
||||
../incace/uac_dcpr.h ../incace/uac_sys.h
|
||||
uac_sys.o: uac_sys.c ../incace/os.h ../incace/globals.h ../incace/uac_sys.h
|
||||
unace.o: unace.c ../incace/os.h ../incace/globals.h ../incace/portable.h ../incace/uac_comm.h ../incace/uac_crc.h ../incace/uac_crt.h \
|
||||
../incace/uac_dcpr.h ../incace/uac_sys.h
|
||||
|
41
utils/Install/packace/makefile.b32
Normal file
41
utils/Install/packace/makefile.b32
Normal file
@@ -0,0 +1,41 @@
|
||||
# Common settings for Borland 32-bit compilation (makefile.b32 files)
|
||||
|
||||
LINK=ilink32
|
||||
|
||||
OPT = -O2
|
||||
LDFLAGS = -lxncd -l-P
|
||||
CPPFLAGS = /I"..\incace" /DWIN32
|
||||
LINKFLAGS=/aa -L$(BCCDIR)\lib\psdk
|
||||
|
||||
DUMMY=dummy
|
||||
|
||||
SRCSUFF = cpp
|
||||
OBJSUFF = obj
|
||||
|
||||
TARGET = packinst
|
||||
OBJECTS = globals.obj uac_comm.obj uac_crc.obj uac_crt.obj uac_dcpr.obj uac_sys.obj unace.obj packinst.obj
|
||||
|
||||
all: $(TARGET).exe
|
||||
|
||||
packinst.exe: $(OBJECTS)
|
||||
bcc32 $(LDFLAGS) -epackinst.exe @&&|
|
||||
$(OBJECTS)
|
||||
|
|
||||
|
||||
.$(SRCSUFF).obj:
|
||||
bcc32 $(CPPFLAGS) -c {$< }
|
||||
|
||||
packinst.obj: ..\packinst\packinst.c
|
||||
bcc32 $(CPPFLAGS) -P- -c ..\packinst\packinst.c
|
||||
|
||||
.c.obj:
|
||||
bcc32 $(CPPFLAGS) -P- -c {$< }
|
||||
|
||||
clean:
|
||||
-erase *.obj
|
||||
-erase *.exe
|
||||
-erase *.res
|
||||
-erase *.map
|
||||
-erase *.rws
|
||||
-erase *.tds
|
||||
-erase *.il?
|
46
utils/Install/packace/makefile.g95
Normal file
46
utils/Install/packace/makefile.g95
Normal file
@@ -0,0 +1,46 @@
|
||||
# Installer Makefile
|
||||
|
||||
CC = gcc
|
||||
RM = rm -f
|
||||
RC = rc
|
||||
MAKE = make
|
||||
|
||||
DEFS =
|
||||
LIBS =
|
||||
|
||||
CFLAGS = -mno-cygwin -O -g -I../incace -Wall -DWIN32
|
||||
LDFLAGS = -mno-cygwin
|
||||
|
||||
|
||||
OBJECTS = globals.o packinst.o uac_comm.o uac_crc.o \
|
||||
uac_crt.o uac_dcpr.o uac_sys.o unace.o
|
||||
|
||||
SOURCES = globals.c ../packinst/packinst.c uac_comm.c \
|
||||
uac_crc.c uac_crt.c uac_dcpr.c uac_sys.c unace.c
|
||||
|
||||
all: packinst
|
||||
|
||||
$(OBJECTS):
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
Include: ../incace/Makefile Makefile
|
||||
# cd include
|
||||
# $(MAKE) -f Makefile all
|
||||
|
||||
packinst: $(OBJECTS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $(DEFS) -o packinst $(OBJECTS)
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJECTS) packinst *~
|
||||
|
||||
globals.o: globals.c ../incace/globals.h ../incace/acestruc.h ../incace/unace.h
|
||||
packinst.o: ../packinst/packinst.c
|
||||
uac_comm.o: uac_comm.c ../incace/globals.h ../incace/uac_dcpr.h ../incace/uac_comm.h
|
||||
uac_crc.o: uac_crc.c ../incace/uac_crc.h
|
||||
uac_crt.o: uac_crt.c ../incace/os.h ../incace/attribs.h ../incace/globals.h ../incace/uac_crt.h ../incace/uac_sys.h
|
||||
uac_dcpr.o: uac_dcpr.c ../incace/os.h ../incace/globals.h ../incace/portable.h ../incace/uac_comm.h ../incace/uac_crc.h \
|
||||
../incace/uac_dcpr.h ../incace/uac_sys.h
|
||||
uac_sys.o: uac_sys.c ../incace/os.h ../incace/globals.h ../incace/uac_sys.h
|
||||
unace.o: unace.c ../incace/os.h ../incace/globals.h ../incace/portable.h ../incace/uac_comm.h ../incace/uac_crc.h ../incace/uac_crt.h \
|
||||
../incace/uac_dcpr.h ../incace/uac_sys.h
|
||||
|
46
utils/Install/packace/makefile.gcc
Normal file
46
utils/Install/packace/makefile.gcc
Normal file
@@ -0,0 +1,46 @@
|
||||
# Installer Makefile
|
||||
|
||||
CC = gcc
|
||||
RM = rm -f
|
||||
RC = rc
|
||||
MAKE = make
|
||||
|
||||
DEFS =
|
||||
LIBS =
|
||||
|
||||
CFLAGS = -O -g -I../incace -Wall
|
||||
LDFLAGS =
|
||||
|
||||
|
||||
OBJECTS = globals.o packinst.o uac_comm.o uac_crc.o \
|
||||
uac_crt.o uac_dcpr.o uac_sys.o unace.o
|
||||
|
||||
SOURCES = globals.c ../packinst/packinst.c uac_comm.c \
|
||||
uac_crc.c uac_crt.c uac_dcpr.c uac_sys.c unace.c
|
||||
|
||||
all: packinst
|
||||
|
||||
$(OBJECTS):
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
Include: ../incace/Makefile Makefile
|
||||
# cd include
|
||||
# $(MAKE) -f Makefile all
|
||||
|
||||
packinst: $(OBJECTS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $(DEFS) -o packinst $(OBJECTS)
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJECTS) packinst *~
|
||||
|
||||
globals.o: globals.c ../incace/globals.h ../incace/acestruc.h ../incace/unace.h
|
||||
packinst.o: ../packinst/packinst.c
|
||||
uac_comm.o: uac_comm.c ../incace/globals.h ../incace/uac_dcpr.h ../incace/uac_comm.h
|
||||
uac_crc.o: uac_crc.c ../incace/uac_crc.h
|
||||
uac_crt.o: uac_crt.c ../incace/os.h ../incace/attribs.h ../incace/globals.h ../incace/uac_crt.h ../incace/uac_sys.h
|
||||
uac_dcpr.o: uac_dcpr.c ../incace/os.h ../incace/globals.h ../incace/portable.h ../incace/uac_comm.h ../incace/uac_crc.h \
|
||||
../incace/uac_dcpr.h ../incace/uac_sys.h
|
||||
uac_sys.o: uac_sys.c ../incace/os.h ../incace/globals.h ../incace/uac_sys.h
|
||||
unace.o: unace.c ../incace/os.h ../incace/globals.h ../incace/portable.h ../incace/uac_comm.h ../incace/uac_crc.h ../incace/uac_crt.h \
|
||||
../incace/uac_dcpr.h ../incace/uac_sys.h
|
||||
|
51
utils/Install/packace/uac_comm.c
Normal file
51
utils/Install/packace/uac_comm.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* */
|
||||
/* Decompresses and outputs comment if present. */
|
||||
/* */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#include <stdio.h> // printf()
|
||||
|
||||
#include "globals.h"
|
||||
#include "uac_dcpr.h"
|
||||
#include "uac_comm.h"
|
||||
|
||||
INT comm_cpr_size=0;
|
||||
CHAR *comm;
|
||||
|
||||
void comment_out(CHAR *top) // outputs comment if present
|
||||
{
|
||||
INT i;
|
||||
|
||||
if (head.HEAD_FLAGS & ACE_COMM)
|
||||
{ // comment present?
|
||||
if (head.HEAD_TYPE == MAIN_BLK)
|
||||
{ // get begin and size of comment data
|
||||
comm = (CHAR *)MCOMM;
|
||||
comm_cpr_size = MCOMM_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
comm = (CHAR *)FCOMM;
|
||||
comm_cpr_size = FCOMM_SIZE;
|
||||
} // limit comment size if too big
|
||||
i = sizeof(head) - (INT)(comm - (CHAR*) &head);
|
||||
if (comm_cpr_size > i)
|
||||
comm_cpr_size = i;
|
||||
dcpr_comm(i); // decompress comment
|
||||
|
||||
#ifdef AMIGA
|
||||
{
|
||||
char *p=comm;
|
||||
while (*p)
|
||||
{
|
||||
if (*p==0x0D)
|
||||
*p=0x0A; // Replace ms-dos line termination
|
||||
p++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
pipeit("%s\n\n%s\n\n", top, comm); // output comment
|
||||
}
|
||||
}
|
36
utils/Install/packace/uac_crc.c
Normal file
36
utils/Install/packace/uac_crc.c
Normal file
@@ -0,0 +1,36 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* */
|
||||
/* CRC-calculation routines. */
|
||||
/* */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#include "uac_crc.h"
|
||||
|
||||
|
||||
ULONG crctable[256];
|
||||
ULONG rd_crc=0;
|
||||
|
||||
|
||||
void make_crctable(void) // initializes CRC table
|
||||
{
|
||||
ULONG r,
|
||||
i,
|
||||
j;
|
||||
|
||||
for (i = 0; i <= 255; i++)
|
||||
{
|
||||
for (r = i, j = 8; j; j--)
|
||||
r = (r & 1) ? (r >> 1) ^ CRCPOLY : (r >> 1);
|
||||
crctable[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
// Updates crc from addr till addr+len-1
|
||||
//
|
||||
ULONG getcrc(ULONG crc, UCHAR * addr, INT len)
|
||||
{
|
||||
while (len--)
|
||||
crc = crctable[(unsigned char) crc ^ (*addr++)] ^ (crc >> 8);
|
||||
return (crc);
|
||||
}
|
||||
|
149
utils/Install/packace/uac_crt.c
Normal file
149
utils/Install/packace/uac_crt.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* */
|
||||
/* Creates/Replaces files or directories. */
|
||||
/* */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h> // AMIGA: open()
|
||||
#include <stdio.h> // pipeit() remove()
|
||||
#include <string.h> // strncpy()
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h> // struct stat
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#if defined(DOS) || defined(WINNT) || defined(WIN16)
|
||||
#include <io.h> // access()
|
||||
#endif
|
||||
#if defined(__IBMC__)
|
||||
#include <direct.h>
|
||||
#endif
|
||||
|
||||
#define DIRSEP '\\'
|
||||
|
||||
#include "attribs.h"
|
||||
#include "globals.h"
|
||||
#include "uac_crt.h"
|
||||
#include "uac_sys.h"
|
||||
|
||||
/* gets file name from header
|
||||
*/
|
||||
CHAR *ace_fname(CHAR * s, thead * head, INT nopath)
|
||||
{
|
||||
INT i;
|
||||
char *cp;
|
||||
|
||||
strncpy(s, (CHAR *)(*(tfhead *) head).FNAME, i = (*(tfhead *) head).FNAME_SIZE);
|
||||
s[i] = 0;
|
||||
|
||||
if (nopath)
|
||||
{
|
||||
cp=strrchr(s, '\\');
|
||||
if (cp)
|
||||
memmove(s, cp+1, strlen(cp));
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void check_ext_dir(CHAR * f) // checks/creates path of file
|
||||
{
|
||||
CHAR *cp,
|
||||
d[PATH_MAX];
|
||||
INT i;
|
||||
|
||||
d[0] = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ((cp = (CHAR *) strchr(&f[strlen(d) + 1], DIRSEP))!=NULL)
|
||||
{
|
||||
i = cp - f;
|
||||
strncpy(d, f, i);
|
||||
d[i] = 0;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
if (!fileexists(d))
|
||||
#if (defined(__OS2__) && !defined(__EMX__)) || (defined(WINNT) && !defined(__CYGWIN__))
|
||||
if (mkdir(d))
|
||||
#else
|
||||
if (mkdir(d, 0))
|
||||
#endif
|
||||
{
|
||||
f_err = ERR_WRITE;
|
||||
pipeit("\n Error while creating directory.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INT ovr_delete(CHAR * n) // deletes directory or file
|
||||
{
|
||||
if (remove(n) && rmdir(n))
|
||||
{
|
||||
pipeit("\n Could not delete file or directory. Access denied.\n");
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
INT create_dest_file(CHAR * file, INT a) // creates file or directory
|
||||
{
|
||||
INT han,
|
||||
i = 0,
|
||||
ex = fileexists(file);
|
||||
struct stat st;
|
||||
|
||||
check_ext_dir(file);
|
||||
if (f_err)
|
||||
return (-1);
|
||||
if (a & _A_SUBDIR)
|
||||
{ // create dir or file?
|
||||
if (ex)
|
||||
stat(file, &st);
|
||||
#if (defined(__OS2__) && !defined(__EMX__)) || (!defined(__CYGWIN__) && defined(WINNT))
|
||||
if ((!ex && mkdir(file)) || (ex && (st.st_mode & S_IFDIR)))
|
||||
#else
|
||||
if ((!ex && mkdir(file, 0)) || (ex && (st.st_mode & S_IFDIR)))
|
||||
#endif
|
||||
{
|
||||
pipeit("\n Could not create directory.\n");
|
||||
return (-1);
|
||||
}
|
||||
#ifdef DOS
|
||||
_dos_setfileattr(file, a); // set directory attributes
|
||||
#endif
|
||||
return (-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ex)
|
||||
{ // does the file already exist
|
||||
if (!f_ovrall)
|
||||
{
|
||||
i = wrask("Overwrite existing file?"); // prompt for overwrite
|
||||
f_ovrall = (i == 1);
|
||||
if (i == 3)
|
||||
f_err = ERR_USER;
|
||||
}
|
||||
if ((i && !f_ovrall) || ovr_delete(file))
|
||||
return (-1); // delete?
|
||||
}
|
||||
#if defined(__OS2_) || defined(__EMX__) || defined(WIN32)
|
||||
if ((han = open(file, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY,
|
||||
S_IREAD | S_IWRITE | S_IEXEC | S_IDELETE |
|
||||
S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH )) < 0)
|
||||
#else
|
||||
if ((han = open(file, O_WRONLY | O_TRUNC | O_CREAT,
|
||||
S_IREAD | S_IWRITE | S_IEXEC | S_IDELETE |
|
||||
S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH )) < 0)
|
||||
#endif
|
||||
pipeit("\n Could not create destination file.\n");
|
||||
return (han);
|
||||
}
|
||||
}
|
||||
|
553
utils/Install/packace/uac_dcpr.c
Normal file
553
utils/Install/packace/uac_dcpr.c
Normal file
@@ -0,0 +1,553 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* */
|
||||
/* These are the decompression algorithms. */
|
||||
/* Don't change here anything (apart from memory allocation perhaps). */
|
||||
/* Any changes will very likely cause bugs! */
|
||||
/* */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#if defined(AMIGA)
|
||||
#include <string.h> // mem*()
|
||||
#endif
|
||||
#if defined(DOS) || defined(WIN16) || defined(WINNT) || defined(OS2) || defined(UNIX)
|
||||
#if !defined(__CYGWIN__)
|
||||
#include <mem.h> // mem*()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h> // pipeit()
|
||||
#include <stdlib.h> // malloc()
|
||||
#include <string.h>
|
||||
|
||||
#include "globals.h"
|
||||
#include "portable.h"
|
||||
#include "uac_comm.h"
|
||||
#include "uac_crc.h"
|
||||
#include "uac_dcpr.h"
|
||||
#include "uac_sys.h"
|
||||
#ifdef CRYPT
|
||||
#include "unace_ps.h"
|
||||
#endif /* CRYPT */
|
||||
|
||||
|
||||
//------------------------------ QUICKSORT ---------------------------------//
|
||||
#define xchg_def(v1,v2) {INT dummy;\
|
||||
dummy=v1; \
|
||||
v1=v2; \
|
||||
v2=dummy;}
|
||||
|
||||
void sortrange(INT left, INT right)
|
||||
{
|
||||
INT zl = left,
|
||||
zr = right,
|
||||
hyphen;
|
||||
|
||||
hyphen = sort_freq[right];
|
||||
|
||||
//divides by hyphen the given range into 2 parts
|
||||
do
|
||||
{
|
||||
while (sort_freq[zl] > hyphen)
|
||||
zl++;
|
||||
while (sort_freq[zr] < hyphen)
|
||||
zr--;
|
||||
//found a too small (left side) and
|
||||
//a too big (right side) element-->exchange them
|
||||
if (zl <= zr)
|
||||
{
|
||||
xchg_def(sort_freq[zl], sort_freq[zr]);
|
||||
xchg_def(sort_org[zl], sort_org[zr]);
|
||||
zl++;
|
||||
zr--;
|
||||
}
|
||||
}
|
||||
while (zl < zr);
|
||||
|
||||
//sort partial ranges - when very small, sort directly
|
||||
if (left < zr)
|
||||
{
|
||||
if (left < zr - 1)
|
||||
sortrange(left, zr);
|
||||
else if (sort_freq[left] < sort_freq[zr])
|
||||
{
|
||||
xchg_def(sort_freq[left], sort_freq[zr]);
|
||||
xchg_def(sort_org[left], sort_org[zr]);
|
||||
}
|
||||
}
|
||||
|
||||
if (right > zl)
|
||||
{
|
||||
if (zl < right - 1)
|
||||
sortrange(zl, right);
|
||||
else if (sort_freq[zl] < sort_freq[right])
|
||||
{
|
||||
xchg_def(sort_freq[zl], sort_freq[right]);
|
||||
xchg_def(sort_org[zl], sort_org[right]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void quicksort(INT n)
|
||||
{
|
||||
INT i;
|
||||
|
||||
for (i = n + 1; i--;)
|
||||
sort_org[i] = i;
|
||||
sortrange(0, n);
|
||||
}
|
||||
|
||||
//------------------------------ read bits ---------------------------------//
|
||||
void readdat(void)
|
||||
{
|
||||
UINT i;
|
||||
|
||||
i = (size_rdb - 2) << 2;
|
||||
rpos -= size_rdb - 2;
|
||||
buf_rd[0] = buf_rd[size_rdb - 2];
|
||||
buf_rd[1] = buf_rd[size_rdb - 1];
|
||||
read_adds_blk((CHAR *) & buf_rd[2], i);
|
||||
#ifdef HI_LO_BYTE_ORDER
|
||||
{
|
||||
ULONG *p;
|
||||
i>>=2; // count LONGs not BYTEs
|
||||
p=&buf_rd[2];
|
||||
while (i--)
|
||||
{
|
||||
LONGswap(p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define addbits(bits) \
|
||||
{ \
|
||||
rpos+=(bits_rd+=bits)>>5; \
|
||||
bits_rd&=31; \
|
||||
if (rpos==(size_rdb-2)) readdat(); \
|
||||
code_rd=(buf_rd[rpos] << bits_rd) \
|
||||
+((buf_rd[rpos+1] >> (32-bits_rd))&(!bits_rd-1)); \
|
||||
}
|
||||
|
||||
|
||||
//---------------------- COMMENT DECOMPRESSION -----------------------------//
|
||||
|
||||
#define comm_cpr_hf(a,b) (a+b)
|
||||
|
||||
void dcpr_comm_init(void)
|
||||
{
|
||||
INT i;
|
||||
|
||||
i = comm_cpr_size > size_rdb * sizeof(LONG) ? size_rdb * sizeof(LONG) : comm_cpr_size;
|
||||
if (!f_err)
|
||||
memcpy(buf_rd, comm, i);
|
||||
#ifdef HI_LO_BYTE_ORDER
|
||||
{
|
||||
ULONG *p;
|
||||
i>>=2; // count LONGs not BYTEs
|
||||
p=buf_rd;
|
||||
while (i--)
|
||||
{
|
||||
LONGswap(p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
code_rd = buf_rd[0];
|
||||
rpos = bits_rd = 0;
|
||||
}
|
||||
|
||||
void dcpr_comm(INT comm_size)
|
||||
{
|
||||
SHORT hash[comm_cpr_hf(255, 255) + 1];
|
||||
INT dpos = 0,
|
||||
c,
|
||||
pos = 0,
|
||||
len,
|
||||
hs;
|
||||
|
||||
memset(&hash, 0, sizeof(hash));
|
||||
if (comm_cpr_size)
|
||||
{
|
||||
dcpr_comm_init();
|
||||
len = code_rd >> (32 - 15);
|
||||
addbits(15);
|
||||
if (len >= comm_size)
|
||||
len = comm_size - 1;
|
||||
if (read_wd(maxwd_mn, dcpr_code_mn, dcpr_wd_mn, max_cd_mn))
|
||||
do
|
||||
{
|
||||
if (dpos > 1)
|
||||
{
|
||||
pos = hash[hs = comm_cpr_hf(comm[dpos - 1], comm[dpos - 2])];
|
||||
hash[hs] = dpos;
|
||||
}
|
||||
addbits(dcpr_wd_mn[(c = dcpr_code_mn[code_rd >> (32 - maxwd_mn)])]);
|
||||
if (rpos == size_rdb - 3)
|
||||
rpos = 0;
|
||||
if (c > 255)
|
||||
{
|
||||
c -= 256;
|
||||
c += 2;
|
||||
while (c--)
|
||||
comm[dpos++] = comm[pos++];
|
||||
}
|
||||
else
|
||||
{
|
||||
comm[dpos++] = c;
|
||||
}
|
||||
}
|
||||
while (dpos < len);
|
||||
comm[len] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------- LZW1 DECOMPRESSION -----------------------------//
|
||||
void wrchar(CHAR ch)
|
||||
{
|
||||
dcpr_do++;
|
||||
|
||||
dcpr_text[dcpr_dpos] = ch;
|
||||
dcpr_dpos++;
|
||||
dcpr_dpos &= dcpr_dican;
|
||||
}
|
||||
|
||||
void copystr(LONG d, INT l)
|
||||
{
|
||||
INT mpos;
|
||||
|
||||
dcpr_do += l;
|
||||
|
||||
mpos = dcpr_dpos - d;
|
||||
mpos &= dcpr_dican;
|
||||
|
||||
if ((mpos >= dcpr_dicsiz - maxlength) || (dcpr_dpos >= dcpr_dicsiz - maxlength))
|
||||
{
|
||||
while (l--)
|
||||
{
|
||||
dcpr_text[dcpr_dpos] = dcpr_text[mpos];
|
||||
dcpr_dpos++;
|
||||
dcpr_dpos &= dcpr_dican;
|
||||
mpos++;
|
||||
mpos &= dcpr_dican;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (l--)
|
||||
dcpr_text[dcpr_dpos++] = dcpr_text[mpos++];
|
||||
dcpr_dpos &= dcpr_dican;
|
||||
}
|
||||
}
|
||||
|
||||
void decompress(void)
|
||||
{
|
||||
INT c,
|
||||
lg,
|
||||
i,
|
||||
k;
|
||||
ULONG dist;
|
||||
|
||||
while (dcpr_do < dcpr_do_max)
|
||||
{
|
||||
if (!blocksize)
|
||||
if (!calc_dectabs())
|
||||
return;
|
||||
|
||||
addbits(dcpr_wd_mn[(c = dcpr_code_mn[code_rd >> (32 - maxwd_mn)])]);
|
||||
blocksize--;
|
||||
if (c > 255)
|
||||
{
|
||||
if (c > 259)
|
||||
{
|
||||
if ((c -= 260) > 1)
|
||||
{
|
||||
dist = (code_rd >> (33 - c)) + (1L << (c - 1));
|
||||
addbits(c - 1);
|
||||
}
|
||||
else
|
||||
dist = c;
|
||||
dcpr_olddist[(dcpr_oldnum = (dcpr_oldnum + 1) & 3)] = dist;
|
||||
i = 2;
|
||||
if (dist > maxdis2)
|
||||
{
|
||||
i++;
|
||||
if (dist > maxdis3)
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dist = dcpr_olddist[(dcpr_oldnum - (c &= 255)) & 3];
|
||||
for (k = c + 1; k--;)
|
||||
dcpr_olddist[(dcpr_oldnum - k) & 3] = dcpr_olddist[(dcpr_oldnum - k + 1) & 3];
|
||||
dcpr_olddist[dcpr_oldnum] = dist;
|
||||
i = 2;
|
||||
if (c > 1)
|
||||
i++;
|
||||
}
|
||||
addbits(dcpr_wd_lg[(lg = dcpr_code_lg[code_rd >> (32 - maxwd_lg)])]);
|
||||
dist++;
|
||||
lg += i;
|
||||
copystr(dist, lg);
|
||||
}
|
||||
else
|
||||
wrchar(c);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------- HUFFMAN ROUTINES ------------------------------//
|
||||
INT makecode(UINT maxwd, UINT size1_t, UCHAR * wd, USHORT * code)
|
||||
{
|
||||
UINT maxc,
|
||||
size2_t,
|
||||
l,
|
||||
c,
|
||||
i,
|
||||
max_make_code;
|
||||
|
||||
memcpy(&sort_freq, wd, (size1_t + 1) * sizeof(CHAR));
|
||||
if (size1_t)
|
||||
quicksort(size1_t);
|
||||
else
|
||||
sort_org[0] = 0;
|
||||
sort_freq[size1_t + 1] = size2_t = c = 0;
|
||||
while (sort_freq[size2_t])
|
||||
size2_t++;
|
||||
if (size2_t < 2)
|
||||
{
|
||||
i = sort_org[0];
|
||||
wd[i] = 1;
|
||||
size2_t += (size2_t == 0);
|
||||
}
|
||||
size2_t--;
|
||||
|
||||
max_make_code = 1 << maxwd;
|
||||
for (i = size2_t + 1; i-- && c < max_make_code;)
|
||||
{
|
||||
maxc = 1 << (maxwd - sort_freq[i]);
|
||||
l = sort_org[i];
|
||||
if (c + maxc > max_make_code)
|
||||
{
|
||||
dcpr_do = dcpr_do_max;
|
||||
return (0);
|
||||
}
|
||||
memset16(&code[c], l, maxc);
|
||||
c += maxc;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
INT read_wd(UINT maxwd, USHORT * code, UCHAR * wd, INT max_el)
|
||||
{
|
||||
UINT c,
|
||||
i,
|
||||
j,
|
||||
num_el,
|
||||
l,
|
||||
uplim,
|
||||
lolim;
|
||||
|
||||
memset(wd, 0, max_el * sizeof(CHAR));
|
||||
memset(code, 0, (1 << maxwd) * sizeof(SHORT));
|
||||
|
||||
num_el = code_rd >> (32 - 9);
|
||||
addbits(9);
|
||||
if (num_el > max_el)
|
||||
num_el = max_el;
|
||||
|
||||
lolim = code_rd >> (32 - 4);
|
||||
addbits(4);
|
||||
uplim = code_rd >> (32 - 4);
|
||||
addbits(4);
|
||||
|
||||
for (i = -1; ++i <= uplim;)
|
||||
{
|
||||
wd_svwd[i] = code_rd >> (32 - 3);
|
||||
addbits(3);
|
||||
}
|
||||
if (!makecode(maxwd_svwd, uplim, wd_svwd, code))
|
||||
return (0);
|
||||
j = 0;
|
||||
while (j <= num_el)
|
||||
{
|
||||
c = code[code_rd >> (32 - maxwd_svwd)];
|
||||
addbits(wd_svwd[c]);
|
||||
if (c < uplim)
|
||||
wd[j++] = c;
|
||||
else
|
||||
{
|
||||
l = (code_rd >> 28) + 4;
|
||||
addbits(4);
|
||||
while (l-- && j <= num_el)
|
||||
wd[j++] = 0;
|
||||
}
|
||||
}
|
||||
if (uplim)
|
||||
for (i = 0; ++i <= num_el;)
|
||||
wd[i] = (wd[i] + wd[i - 1]) % uplim;
|
||||
for (i = -1; ++i <= num_el;)
|
||||
if (wd[i])
|
||||
wd[i] += lolim;
|
||||
|
||||
return (makecode(maxwd, num_el, wd, code));
|
||||
|
||||
}
|
||||
|
||||
INT calc_dectabs(void)
|
||||
{
|
||||
if (!read_wd(maxwd_mn, dcpr_code_mn, dcpr_wd_mn, max_cd_mn)
|
||||
|| !read_wd(maxwd_lg, dcpr_code_lg, dcpr_wd_lg, max_cd_lg))
|
||||
return (0);
|
||||
|
||||
blocksize = code_rd >> (32 - 15);
|
||||
addbits(15);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
//---------------------------- BLOCK ROUTINES ------------------------------//
|
||||
INT decompress_blk(CHAR * buf, UINT len)
|
||||
{
|
||||
LONG old_pos = dcpr_dpos;
|
||||
INT i;
|
||||
|
||||
dcpr_do = 0;
|
||||
if ((dcpr_do_max = len - maxlength) > dcpr_size)
|
||||
dcpr_do_max = dcpr_size;
|
||||
if ((LONG) dcpr_size > 0 && dcpr_do_max)
|
||||
{
|
||||
decompress();
|
||||
if (old_pos + dcpr_do > dcpr_dicsiz)
|
||||
{
|
||||
i = dcpr_dicsiz - old_pos;
|
||||
memcpy(buf, &dcpr_text[old_pos], i);
|
||||
memcpy(&buf[i], dcpr_text, dcpr_do - i);
|
||||
}
|
||||
else
|
||||
memcpy(buf, &dcpr_text[old_pos], dcpr_do);
|
||||
}
|
||||
dcpr_size -= dcpr_do;
|
||||
return (dcpr_do);
|
||||
}
|
||||
|
||||
INT unstore(CHAR * buf, UINT len)
|
||||
{
|
||||
UINT rd = 0,
|
||||
i,
|
||||
pos = 0;
|
||||
|
||||
#ifdef CRYPT
|
||||
len = crypt_len(len - 8); /* because of decryption */
|
||||
#endif /* CRYPT */
|
||||
|
||||
while ((i = read_adds_blk((CHAR *) buf_rd, (INT) ((i = ((len > dcpr_size) ? dcpr_size : len)) > size_rdb ? size_rdb : i))) != 0)
|
||||
{
|
||||
rd += i;
|
||||
len -= i;
|
||||
memcpy(&buf[pos], buf_rd, i);
|
||||
pos += i;
|
||||
}
|
||||
dcpr_size -= rd;
|
||||
for (i = 0; i < rd; i++)
|
||||
{
|
||||
dcpr_text[dcpr_dpos] = buf[i];
|
||||
dcpr_dpos++;
|
||||
dcpr_dpos &= dcpr_dican;
|
||||
}
|
||||
return (INT)rd;
|
||||
}
|
||||
|
||||
INT dcpr_adds_blk(CHAR * buf, UINT len)
|
||||
{
|
||||
INT r;
|
||||
|
||||
switch (fhead.TECH.TYPE)
|
||||
{
|
||||
case TYPE_STORE:
|
||||
r = unstore(buf, len);
|
||||
break;
|
||||
case TYPE_LZW1:
|
||||
r = decompress_blk(buf, len);
|
||||
break;
|
||||
default:
|
||||
pipeit("\nFile compressed with unknown method. Decompression not possible.\n");
|
||||
f_err = ERR_OTHER;
|
||||
r = 0;
|
||||
}
|
||||
rd_crc = getcrc(rd_crc, (UCHAR *)buf, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------- INIT ROUTINES ------------------------------//
|
||||
void dcpr_init(void)
|
||||
{
|
||||
dcpr_frst_file = 1;
|
||||
|
||||
dcpr_dic = 20;
|
||||
while ((dcpr_text = malloc(dcpr_dicsiz = (LONG) 1 << dcpr_dic))==NULL)
|
||||
dcpr_dic--;
|
||||
dcpr_dican = dcpr_dicsiz - 1;
|
||||
}
|
||||
|
||||
void dcpr_init_file(void)
|
||||
{
|
||||
UINT i;
|
||||
|
||||
#ifdef CRYPT
|
||||
|
||||
reset_cryptkey();
|
||||
|
||||
#else /* CRYPT */
|
||||
|
||||
if (head.HEAD_FLAGS & ACE_PASSW)
|
||||
{
|
||||
pipeit("\nFound passworded file. Decryption not supported.\n");
|
||||
f_err = ERR_OTHER;
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* CRYPT */
|
||||
|
||||
rd_crc = CRC_MASK;
|
||||
dcpr_size = fhead.SIZE;
|
||||
if (fhead.TECH.TYPE == TYPE_LZW1)
|
||||
{
|
||||
if ((fhead.TECH.PARM & 15) + 10 > dcpr_dic)
|
||||
{
|
||||
pipeit("\nNot enough memory or dictionary of archive too large.\n");
|
||||
f_err = ERR_MEM;
|
||||
return;
|
||||
}
|
||||
|
||||
i = size_rdb * sizeof(LONG);
|
||||
read_adds_blk((CHAR *) buf_rd, i);
|
||||
#ifdef HI_LO_BYTE_ORDER
|
||||
{
|
||||
ULONG *p;
|
||||
i>>=2; // count LONGs not BYTEs
|
||||
p=buf_rd;
|
||||
while (i--)
|
||||
{
|
||||
LONGswap(p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
code_rd = buf_rd[0];
|
||||
bits_rd = rpos = 0;
|
||||
|
||||
blocksize = 0;
|
||||
}
|
||||
if (!adat.sol || dcpr_frst_file)
|
||||
dcpr_dpos = 0;
|
||||
|
||||
dcpr_oldnum = 0;
|
||||
memset(&dcpr_olddist, 0, sizeof(dcpr_olddist));
|
||||
|
||||
dcpr_frst_file = 0;
|
||||
}
|
||||
|
105
utils/Install/packace/uac_sys.c
Normal file
105
utils/Install/packace/uac_sys.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* */
|
||||
/* Some basic things. */
|
||||
/* */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#include <signal.h> // signal()
|
||||
#include <stdio.h> // fprintf() fflush() getch() putc()
|
||||
|
||||
#if defined(DOS) || defined(WINNT) || defined(WIN16)
|
||||
#if !defined(__CYGWIN__)
|
||||
#include <conio.h> // getch()
|
||||
#endif
|
||||
#endif
|
||||
#if defined(DOS)
|
||||
#include <dos.h> // delay() sound()
|
||||
#endif
|
||||
|
||||
#include "globals.h"
|
||||
#include "uac_sys.h"
|
||||
|
||||
|
||||
void memset16(USHORT * dest, SHORT val, INT len) // fills short-array with
|
||||
{ // value
|
||||
while (len--)
|
||||
*(dest++) = val;
|
||||
}
|
||||
|
||||
INT cancel(void) // checks whether to interrupt the program
|
||||
{
|
||||
#ifdef DOS
|
||||
while (kbhit())
|
||||
{
|
||||
if (getch() == 27)
|
||||
f_err = ERR_USER;
|
||||
}
|
||||
#endif
|
||||
return (f_err);
|
||||
}
|
||||
|
||||
INT wrask(CHAR * s) // prompt-routine
|
||||
{
|
||||
CHAR ch = 0;
|
||||
|
||||
fprintf(stderr, "\n %s (Yes,Always,No,Cancel) ", s);
|
||||
fflush(stderr);
|
||||
do
|
||||
{
|
||||
/*ch = getch();
|
||||
ch = upcase(ch);*/
|
||||
}
|
||||
while (ch != 'Y' && ch != 'A' && ch != 'N' && ch != 'C' && ch != 27);
|
||||
fprintf(stderr, "%s", ch == 'Y' ? "Yes" : (ch == 'A' ? "Always" : (ch == 'N' ? "No" : "Cancel")));
|
||||
fflush(stderr);
|
||||
return (ch == 'Y' ? 0 : (ch == 'A' ? 1 : (ch == 'N' ? 2 : 3)));
|
||||
}
|
||||
|
||||
void beep(void) // makes some noise
|
||||
{
|
||||
#ifdef DOS
|
||||
sound(800);
|
||||
delay(250);
|
||||
nosound();
|
||||
#endif
|
||||
#ifdef AMIGA
|
||||
putc(0x07, stderr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void my_signalhandler(INT sig_number) // sets f_err if ctrl+c or ctrl+brk
|
||||
{
|
||||
f_err = ERR_USER;
|
||||
pipeit("\nUser break\n");
|
||||
}
|
||||
|
||||
#ifdef DOS // handles hardware errors
|
||||
#ifdef __BORLANDC__
|
||||
INT harderrhandler(UINT deverr, UINT errc, UINT * devhdr)
|
||||
#else
|
||||
INT __far harderrhandler(UINT deverr, UINT errc, UINT * devhdr)
|
||||
#endif
|
||||
{
|
||||
f_criterr = 'A' + deverr & 0xff;
|
||||
f_err = ERR_OTHER;
|
||||
return (0x3);
|
||||
}
|
||||
#endif
|
||||
|
||||
void set_handler(void) // initializes handlers
|
||||
{
|
||||
#if defined(DOS) && !defined(__BORLANDC__)
|
||||
signal(SIGBREAK, my_signalhandler); // set ctrl-break/-c handlers
|
||||
#endif
|
||||
signal(SIGINT, my_signalhandler);
|
||||
#if defined(DOS) && !defined(__CONSOLE__) // set hardware error handler
|
||||
#ifdef __BORLANDC__
|
||||
harderr(harderrhandler);
|
||||
#else
|
||||
_harderr(harderrhandler);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
584
utils/Install/packace/unace.c
Normal file
584
utils/Install/packace/unace.c
Normal file
@@ -0,0 +1,584 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* */
|
||||
/* Main file of public UNACE. */
|
||||
/* */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
|
||||
//--------------- include general files ------------------------------------//
|
||||
#include <ctype.h> // tolower()
|
||||
#include <fcntl.h> // open()
|
||||
#include <stdio.h> // printf() sprintf() remove()
|
||||
#include <stdlib.h> // malloc()
|
||||
#include <string.h> // str*()
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h> // S_I* AMIGA: fstat()
|
||||
|
||||
#define DIRSEP '\\'
|
||||
|
||||
#if (!defined(__EMX__) && !defined(__OS2__) && !defined(WINNT) && !defined(WIN32)) || defined(__CYGWIN__)
|
||||
#include <sys/errno.h>
|
||||
#endif
|
||||
|
||||
|
||||
//--------------- include unace specific header files ----------------------//
|
||||
#include "os.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "portable.h"
|
||||
#include "uac_comm.h"
|
||||
#include "uac_crc.h"
|
||||
#include "uac_crt.h"
|
||||
#include "uac_dcpr.h"
|
||||
#include "uac_sys.h"
|
||||
|
||||
#ifdef CRYPT
|
||||
#include "unace_ps.h"
|
||||
#endif /* CRYPT */
|
||||
int files=0;
|
||||
|
||||
//--------------- BEGIN OF UNACE ROUTINES ----------------------------------//
|
||||
|
||||
int pipeit(char *format, ...) {
|
||||
/* Do nothing ... perhaps pipe this somewhere in the future */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void init_unace(void) // initializes unace
|
||||
{
|
||||
buf_rd =malloc(size_rdb * sizeof(ULONG)); // Allocate buffers: increase
|
||||
buf =malloc(size_buf); // sizes when possible to speed
|
||||
buf_wr =malloc(size_wrb); // up the program
|
||||
readbuf=malloc(size_headrdb);
|
||||
|
||||
if (buf_rd ==NULL ||
|
||||
buf ==NULL ||
|
||||
buf_wr ==NULL ||
|
||||
readbuf==NULL )
|
||||
f_err = ERR_MEM;
|
||||
|
||||
make_crctable(); // initialize CRC table
|
||||
dcpr_init(); // initialize decompression
|
||||
|
||||
set_handler(); // ctrl+break etc.
|
||||
}
|
||||
|
||||
void done_unace(void)
|
||||
{
|
||||
if (buf_rd ) free(buf_rd );
|
||||
if (buf ) free(buf );
|
||||
if (buf_wr ) free(buf_wr );
|
||||
if (readbuf ) free(readbuf );
|
||||
if (dcpr_text) free(dcpr_text);
|
||||
}
|
||||
|
||||
INT read_header(INT print_err) // reads any header from archive
|
||||
{
|
||||
USHORT rd,
|
||||
head_size,
|
||||
crc_ok;
|
||||
LONG crc;
|
||||
UCHAR *tp=readbuf;
|
||||
|
||||
lseek(archan, skipsize, SEEK_CUR); // skip ADDSIZE block
|
||||
|
||||
if (read(archan, &head, 4)<4)
|
||||
return (0); // read CRC and header size
|
||||
|
||||
#ifdef HI_LO_BYTE_ORDER
|
||||
WORDswap(&head.HEAD_CRC);
|
||||
WORDswap(&head.HEAD_SIZE);
|
||||
#endif
|
||||
// read size_headrdb bytes into
|
||||
head_size = head.HEAD_SIZE; // header structure
|
||||
rd = (head_size > size_headrdb) ? size_headrdb : head_size;
|
||||
if (read(archan, readbuf, rd) < rd)
|
||||
return (0);
|
||||
head_size -= rd;
|
||||
crc = getcrc(CRC_MASK, readbuf, rd);
|
||||
|
||||
while (head_size) // skip rest of header
|
||||
{
|
||||
rd = (head_size > size_buf) ? size_buf : head_size;
|
||||
if (read(archan, buf, rd) < rd)
|
||||
return (0);
|
||||
head_size -= rd;
|
||||
crc = getcrc(crc, (UCHAR *)buf, rd);
|
||||
}
|
||||
|
||||
head.HEAD_TYPE =*tp++; // generic buffer to head conversion
|
||||
head.HEAD_FLAGS=BUFP2WORD(tp);
|
||||
|
||||
if (head.HEAD_FLAGS & ACE_ADDSIZE)
|
||||
skipsize = head.ADDSIZE = BUF2LONG(tp); // get ADDSIZE
|
||||
else
|
||||
skipsize = 0;
|
||||
|
||||
// check header CRC
|
||||
if (!(crc_ok = head.HEAD_CRC == (crc & 0xffff)) && print_err)
|
||||
pipeit("\nError: archive is broken\n");
|
||||
else
|
||||
switch (head.HEAD_TYPE) // specific buffer to head conversion
|
||||
{
|
||||
case MAIN_BLK:
|
||||
memcpy(mhead.ACESIGN, tp, acesign_len); tp+=acesign_len;
|
||||
mhead.VER_MOD=*tp++;
|
||||
mhead.VER_CR =*tp++;
|
||||
mhead.HOST_CR=*tp++;
|
||||
mhead.VOL_NUM=*tp++;
|
||||
mhead.TIME_CR=BUFP2LONG(tp);
|
||||
mhead.RES1 =BUFP2WORD(tp);
|
||||
mhead.RES2 =BUFP2WORD(tp);
|
||||
mhead.RES =BUFP2LONG(tp);
|
||||
mhead.AV_SIZE=*tp++;
|
||||
memcpy(mhead.AV, tp, rd-(USHORT)(tp-readbuf));
|
||||
break;
|
||||
case FILE_BLK:
|
||||
fhead.PSIZE =BUFP2LONG(tp);
|
||||
fhead.SIZE =BUFP2LONG(tp);
|
||||
fhead.FTIME =BUFP2LONG(tp);
|
||||
fhead.ATTR =BUFP2LONG(tp);
|
||||
fhead.CRC32 =BUFP2LONG(tp);
|
||||
fhead.TECH.TYPE =*tp++;
|
||||
fhead.TECH.QUAL =*tp++;
|
||||
fhead.TECH.PARM =BUFP2WORD(tp);
|
||||
fhead.RESERVED =BUFP2WORD(tp);
|
||||
fhead.FNAME_SIZE=BUFP2WORD(tp);
|
||||
memcpy(fhead.FNAME, tp, rd-(USHORT)(tp-readbuf));
|
||||
break;
|
||||
// default: (REC_BLK and future things):
|
||||
// do nothing 'cause isn't needed for extraction
|
||||
}
|
||||
|
||||
return (crc_ok);
|
||||
}
|
||||
// maximum SFX module size
|
||||
#define max_sfx_size 65536 // (needed by read_arc_head)
|
||||
|
||||
INT read_arc_head(void) // searches for the archive header and reads it
|
||||
{
|
||||
INT i,
|
||||
flags,
|
||||
buf_pos = 0;
|
||||
LONG arc_head_pos,
|
||||
old_fpos,
|
||||
fpos = 0;
|
||||
struct stat st;
|
||||
|
||||
fstat(archan, &st);
|
||||
|
||||
memset(buf, 0, size_buf);
|
||||
|
||||
#if !defined(__EMX__) && !defined(__OS2__)
|
||||
while (ftell(farchan)<st.st_size && fpos < max_sfx_size)
|
||||
#else
|
||||
while (tell(archan)<st.st_size && fpos < max_sfx_size)
|
||||
#endif
|
||||
{
|
||||
old_fpos = fpos;
|
||||
fpos += read(archan, &buf[buf_pos], size_buf - buf_pos);
|
||||
|
||||
for (i = 0; i < size_buf; i++) // look for the acesign
|
||||
{
|
||||
if (!memcmp(acesign, &buf[i], acesign_len))
|
||||
{
|
||||
// seek to the probable begin
|
||||
// of the archive
|
||||
arc_head_pos = old_fpos + i - buf_pos - bytes_before_acesign;
|
||||
lseek(archan, arc_head_pos, SEEK_SET);
|
||||
if (read_header(0)) // try to read archive header
|
||||
{
|
||||
flags = mhead.HEAD_FLAGS;
|
||||
adat.sol = (flags & ACE_SOLID) > 0;
|
||||
adat.vol = (flags & ACE_MULT_VOL) > 0;
|
||||
adat.vol_num = mhead.VOL_NUM;
|
||||
adat.time_cr = mhead.TIME_CR;
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// was no archive header,
|
||||
// continue search
|
||||
lseek(archan, fpos, SEEK_SET);
|
||||
memcpy(buf, &buf[size_buf - 512], 512);
|
||||
buf_pos = 512; // keep 512 old bytes
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
INT open_archive(INT print_err) // opens archive (or volume)
|
||||
{
|
||||
CHAR av_str[80];
|
||||
|
||||
|
||||
#if defined(__OS2_) || defined(__EMX__) || defined(WIN32)
|
||||
archan = open(aname, O_RDONLY | O_BINARY); // open file
|
||||
#else
|
||||
archan = open(aname, O_RDONLY); // open file
|
||||
#endif
|
||||
#if !defined(__EMX__) && !defined(__OS2__)
|
||||
farchan = fdopen(archan, "rb");
|
||||
#endif
|
||||
if (archan == -1)
|
||||
{
|
||||
pipeit("\nError opening file %s", aname);
|
||||
return (0);
|
||||
}
|
||||
if (!read_arc_head()) // read archive header
|
||||
{
|
||||
if (print_err)
|
||||
pipeit("\nInvalid archive file: %s\n", aname);
|
||||
#if !defined(__EMX__) && !defined(__OS2__)
|
||||
fclose(farchan);
|
||||
#endif
|
||||
close(archan);
|
||||
return (0);
|
||||
}
|
||||
|
||||
pipeit("\nProcessing archive: %s\n\n", aname);
|
||||
if (head.HEAD_FLAGS & ACE_AV)
|
||||
{
|
||||
pipeit("Authenticity Verification:"); // print the AV
|
||||
sprintf(av_str, "\ncreated on %d.%d.%d by ",
|
||||
ts_day(adat.time_cr), ts_month(adat.time_cr), ts_year(adat.time_cr));
|
||||
pipeit(av_str);
|
||||
strncpy(av_str, (char *)mhead.AV, mhead.AV_SIZE);
|
||||
av_str[mhead.AV_SIZE] = 0;
|
||||
pipeit("%s\n\n", av_str);
|
||||
}
|
||||
comment_out("Main comment:"); // print main comment
|
||||
return (1);
|
||||
}
|
||||
|
||||
void get_next_volname(void) // get file name of next volume
|
||||
{
|
||||
CHAR *cp;
|
||||
INT num;
|
||||
|
||||
if ((cp = (CHAR *) strrchr(aname, '.')) == NULL || !*(cp + 1))
|
||||
num = -1;
|
||||
else
|
||||
{
|
||||
cp++;
|
||||
num = (*(cp + 1) - '0') * 10 + *(cp + 2) - '0';
|
||||
if (!in(num, 0, 99))
|
||||
num = -1;
|
||||
if (in(*cp, '0', '9'))
|
||||
num += (*cp - '0') * 100;
|
||||
}
|
||||
num++;
|
||||
|
||||
if (num < 100)
|
||||
*cp = 'C';
|
||||
else
|
||||
*cp = num / 100 + '0';
|
||||
*(cp + 1) = (num / 10) % 10 + '0';
|
||||
*(cp + 2) = num % 10 + '0';
|
||||
}
|
||||
|
||||
INT proc_vol(void) // opens volume
|
||||
{
|
||||
INT i;
|
||||
CHAR s[80];
|
||||
|
||||
if (!fileexists(aname) || !f_allvol_pr)
|
||||
{
|
||||
do
|
||||
{
|
||||
sprintf(s, "Ready to process %s?", aname);
|
||||
#if !defined(__MINGW32__)
|
||||
beep();
|
||||
#else
|
||||
beep(500,500);
|
||||
#endif
|
||||
i = wrask(s); // ask whether ready or not
|
||||
f_allvol_pr = (i == 1); // "Always" --> process all volumes
|
||||
if (i >= 2)
|
||||
{
|
||||
f_err = ERR_FOUND;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
while (!fileexists(aname));
|
||||
}
|
||||
|
||||
if (!open_archive(1)) // open volume
|
||||
{
|
||||
pipeit("\nError while opening archive. File not found or archive broken.\n");
|
||||
f_err = ERR_OPEN;
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
INT proc_next_vol(void) // opens next volume to process
|
||||
{
|
||||
#if !defined(__EMX__) && !defined(__OS2__)
|
||||
fclose(farchan);
|
||||
#endif
|
||||
close(archan); // close handle
|
||||
get_next_volname(); // get file name of next volume
|
||||
|
||||
if (!proc_vol()) // try to open volume, read archive header
|
||||
return 0;
|
||||
if (!read_header(1)) // read 2nd header
|
||||
{
|
||||
f_err=ERR_READ;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
INT read_adds_blk(CHAR * buffer, INT len) // reads part of ADD_SIZE block
|
||||
{
|
||||
INT rd = 0,
|
||||
l = len;
|
||||
LONG i;
|
||||
|
||||
#ifdef CRYPT
|
||||
char *cbuffer=buffer;
|
||||
|
||||
if (head.HEAD_TYPE == FILE_BLK && (head.HEAD_FLAGS & ACE_PASSW))
|
||||
len = crypt_len(len);
|
||||
#endif /* CRYPT */
|
||||
while (!f_err && len && skipsize)
|
||||
{
|
||||
i = (skipsize > len) ? len : skipsize;
|
||||
skipsize -= i;
|
||||
|
||||
/* How do I check error condition when comping -mno-cygwin? */
|
||||
#if !defined(__MINGW32__)
|
||||
errno = 0;
|
||||
#endif
|
||||
rd += read(archan, buffer, i);
|
||||
#if !defined(__MINGW32__)
|
||||
if (errno)
|
||||
{
|
||||
pipeit("\nRead error\n");
|
||||
f_err = ERR_READ;
|
||||
}
|
||||
#endif
|
||||
|
||||
buffer += i;
|
||||
len -= i;
|
||||
|
||||
if (!skipsize) // if block is continued on next volume
|
||||
if (head.HEAD_FLAGS & ACE_SP_AFTER && !proc_next_vol())
|
||||
break;
|
||||
}
|
||||
#ifdef CRYPT
|
||||
if (head.HEAD_TYPE == FILE_BLK && (head.HEAD_FLAGS & ACE_PASSW))
|
||||
decrypt(cbuffer, rd);
|
||||
#endif /* CRYPT */
|
||||
|
||||
return (rd > l ? l : rd);
|
||||
}
|
||||
|
||||
void crc_print(void) // checks CRC, prints message
|
||||
{
|
||||
INT crc_not_ok = rd_crc != fhead.CRC32; /* check CRC of file */
|
||||
|
||||
if (!f_err) // print message
|
||||
{
|
||||
pipeit(crc_not_ok ? " CRC-check error" : " CRC OK");
|
||||
flush;
|
||||
}
|
||||
}
|
||||
|
||||
void analyze_file(void) // analyzes one file (for solid archives)
|
||||
{
|
||||
pipeit("\n Analyzing");
|
||||
flush;
|
||||
while (!cancel() && (dcpr_adds_blk(buf_wr, size_wrb))) // decompress only
|
||||
;
|
||||
crc_print();
|
||||
}
|
||||
|
||||
void extract_file(void) // extracts one file
|
||||
{
|
||||
INT rd;
|
||||
|
||||
pipeit("\n Extracting");
|
||||
flush; // decompress block
|
||||
while (!cancel() && (rd = dcpr_adds_blk(buf_wr, size_wrb)))
|
||||
{
|
||||
if (write(wrhan, buf_wr, rd) != rd) // write block
|
||||
{
|
||||
pipeit("\nWrite error\n");
|
||||
f_err = ERR_WRITE;
|
||||
}
|
||||
}
|
||||
crc_print();
|
||||
}
|
||||
|
||||
/* extracts or tests all files of the archive
|
||||
*/
|
||||
void extract_files(int nopath, int test)
|
||||
{
|
||||
CHAR file[PATH_MAX];
|
||||
|
||||
while (!cancel() && read_header(1))
|
||||
{
|
||||
if (head.HEAD_TYPE == FILE_BLK)
|
||||
{
|
||||
comment_out("File comment:"); // show file comment
|
||||
ace_fname(file, &head, nopath); // get file name
|
||||
pipeit("\n%s", file);
|
||||
flush;
|
||||
dcpr_init_file(); // initialize decompression of file
|
||||
if (!f_err)
|
||||
{
|
||||
if (test ||
|
||||
(wrhan = create_dest_file(file, (INT) fhead.ATTR))<0)
|
||||
{
|
||||
if (test || adat.sol)
|
||||
analyze_file(); // analyze file
|
||||
}
|
||||
else
|
||||
{
|
||||
extract_file(); // extract it
|
||||
#ifdef DOS // set file time
|
||||
_dos_setftime(wrhan, (USHORT) (fhead.FTIME >> 16), (USHORT) fhead.FTIME);
|
||||
#endif
|
||||
close(wrhan);
|
||||
#ifdef DOS // set file attributes
|
||||
_dos_setfileattr(file, (UINT) fhead.ATTR);
|
||||
#endif
|
||||
#ifdef AMIGA
|
||||
{ // set file date and time
|
||||
struct DateTime dt;
|
||||
char Date[9], Time[9];
|
||||
ULONG tstamp=fhead.FTIME;
|
||||
|
||||
sprintf(Date, "%02d-%02d-%02d", ts_year(tstamp)-1900, ts_month(tstamp), ts_day(tstamp));
|
||||
sprintf(Time, "%02d:%02d:%02d", ts_hour(tstamp), ts_min(tstamp), ts_sec(tstamp));
|
||||
|
||||
dt.dat_Format = FORMAT_INT;
|
||||
dt.dat_Flags = 0;
|
||||
dt.dat_StrDate= Date;
|
||||
dt.dat_StrTime= Time;
|
||||
|
||||
if (StrToDate(&dt))
|
||||
SetFileDate(file, &dt.dat_Stamp);
|
||||
}
|
||||
#endif
|
||||
if (f_err)
|
||||
remove(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned percentage(ULONG p, ULONG d)
|
||||
{
|
||||
return (unsigned)( d ? (d/2+p*100)/d : 100 );
|
||||
}
|
||||
|
||||
void list_files(int verbose)
|
||||
{
|
||||
ULONG size =0,
|
||||
psize=0,
|
||||
tpsize;
|
||||
CHAR file[PATH_MAX];
|
||||
|
||||
pipeit("Date |Time |Packed |Size |Ratio|File\n");
|
||||
|
||||
while (!cancel() && read_header(1))
|
||||
{
|
||||
if (head.HEAD_TYPE == FILE_BLK)
|
||||
{
|
||||
ULONG ti=fhead.FTIME;
|
||||
ace_fname(file, &head, verbose ? 0 : 1); // get file name
|
||||
|
||||
size += fhead.SIZE;
|
||||
psize +=
|
||||
tpsize = fhead.PSIZE;
|
||||
files++;
|
||||
|
||||
while (head.HEAD_FLAGS & ACE_SP_AFTER)
|
||||
{
|
||||
skipsize=0;
|
||||
if (!proc_next_vol())
|
||||
break;
|
||||
psize += fhead.PSIZE;
|
||||
tpsize+= fhead.PSIZE;
|
||||
}
|
||||
if (!f_err)
|
||||
pipeit("%02u.%02u.%02u|%02u:%02u|%c%c%9lu|%9lu|%4u%%|%c%s\n",
|
||||
ts_day (ti), ts_month(ti), ts_year(ti)%100,
|
||||
ts_hour(ti), ts_min (ti),
|
||||
fhead.HEAD_FLAGS & ACE_SP_BEF ? '<' : ' ',
|
||||
fhead.HEAD_FLAGS & ACE_SP_AFTER ? '>' : ' ',
|
||||
tpsize, fhead.SIZE, percentage(tpsize, fhead.SIZE),
|
||||
fhead.HEAD_FLAGS & ACE_PASSW ? '*' : ' ',
|
||||
file
|
||||
);
|
||||
}
|
||||
}
|
||||
if (!f_err)
|
||||
{
|
||||
pipeit("\n %9lu|%9lu|%4u%%| %u file%s",
|
||||
psize,
|
||||
size,
|
||||
percentage(psize, size),
|
||||
files,
|
||||
(char*)(files == 1 ? "" : "s")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void showhelp(void)
|
||||
{
|
||||
pipeit("\n"
|
||||
"Usage: UNACE <command> <archive[.ace]>\n"
|
||||
"\n"
|
||||
"Where <command> is one of:\n"
|
||||
"\n"
|
||||
" e Extract files\n"
|
||||
" l List archive\n"
|
||||
" t Test archive integrity\n"
|
||||
" v List archive (verbose)\n"
|
||||
" x Extract files with full path"
|
||||
);
|
||||
}
|
||||
|
||||
int include_unpack(char *bleah) // processes the archive
|
||||
{
|
||||
CHAR *s;
|
||||
|
||||
strcpy(aname, bleah);
|
||||
|
||||
init_unace(); // initialize unace
|
||||
|
||||
if (!(s = (CHAR *) strrchr(aname, DIRSEP)))
|
||||
s = aname;
|
||||
if (!strrchr(s, '.'))
|
||||
strcat(aname, ".ACE");
|
||||
|
||||
if (open_archive(1)) // open archive to process
|
||||
{
|
||||
if (adat.vol_num)
|
||||
pipeit("\nFirst volume of archive required!\n");
|
||||
else
|
||||
list_files (0 );
|
||||
|
||||
#if !defined(__EMX__) && !defined(__OS2__)
|
||||
fclose(farchan);
|
||||
#endif
|
||||
close(archan);
|
||||
if (f_err)
|
||||
{
|
||||
pipeit("\nError occurred\n");
|
||||
if (f_criterr)
|
||||
pipeit("Critical error on drive %c\n", f_criterr);
|
||||
}
|
||||
}
|
||||
else
|
||||
f_err = ERR_CLINE;
|
||||
|
||||
done_unace();
|
||||
return (f_err);
|
||||
}
|
||||
|
Reference in New Issue
Block a user