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:
Bryan Petty
2000-07-15 19:51:35 +00:00
parent 8a693e6e04
commit f6bcfd974e
1835 changed files with 237729 additions and 67990 deletions

View 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;
}

View 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

View 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?

View 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

View 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

View 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
}
}

View 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);
}

View 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);
}
}

View 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;
}

View 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
}

View 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);
}