diff options
author | Vsevolod Stakhov <vsevolod@FreeBSD.org> | 2005-10-11 23:07:39 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@FreeBSD.org> | 2005-10-11 23:07:39 +0000 |
commit | 81a74240a0b228bc003c588eaa7e93bbf47915b3 (patch) | |
tree | eb55e0f40d6c2d4b30be34baf173ae672b437f4a /security/clamav | |
parent | 187ecf1c86fc0f35e266748d6deec488d9ff1fb5 (diff) | |
download | ports-81a74240a0b228bc003c588eaa7e93bbf47915b3.tar.gz ports-81a74240a0b228bc003c588eaa7e93bbf47915b3.zip |
Allow clamav to use rar 3 archives using archivers/libunrar.
PR: 86510
Submitted by: Alex Samorukov <samm@os2.kiev.ua>,
Rob <r.evers@nedstat.com> (maintainer)
Notes
Notes:
svn path=/head/; revision=145036
Diffstat (limited to 'security/clamav')
-rw-r--r-- | security/clamav/Makefile | 20 | ||||
-rw-r--r-- | security/clamav/files/clamav-0.87-libunrar3.patch | 3236 |
2 files changed, 3255 insertions, 1 deletions
diff --git a/security/clamav/Makefile b/security/clamav/Makefile index da8acdc2b4cf..8917221165f8 100644 --- a/security/clamav/Makefile +++ b/security/clamav/Makefile @@ -7,6 +7,7 @@ PORTNAME= clamav PORTVERSION= 0.87 +PORTREVISION= 1 CATEGORIES= security MASTER_SITES= ${MASTER_SITE_SOURCEFORGE_EXTENDED} MASTER_SITE_SUBDIR= clamav @@ -23,7 +24,8 @@ RUN_DEPENDS= lha:${PORTSDIR}/archivers/lha \ unzip:${PORTSDIR}/archivers/unzip OPTIONS= MILTER "Compile the milter interface" Off \ - CURL "Support URL downloading" Off + CURL "Support URL downloading" Off \ + UNRAR "Support for external Unrar library" Off USE_REINPLACE= yes USE_LIBTOOL_VER=15 CONFIGURE_TARGET= --build=${MACHINE_ARCH}-portbld-freebsd${OSREL} @@ -124,9 +126,25 @@ CONFIGURE_ARGS+= --with-libcurl CONFIGURE_ARGS+= --without-libcurl .endif +.if defined(WITH_LIBUNRAR) +WANT_AUTOMAKE_VER= 19 +USE_AUTOCONF_VER= 259 +LIB_DEPENDS+= unrar.3:${PORTSDIR}/archivers/libunrar + +pre-configure: + cd ${WRKSRC} && \ + ${ACLOCAL} && \ + ${AUTOHEADER} && \ + ${AUTOCONF} && \ + ${AUTOMAKE} +.endif + post-patch: @${REINPLACE_CMD} -e 's|-pthread -lc_r|${PTHREAD_LIBS}|g' \ ${CONFIGURE_WRKSRC}/${CONFIGURE_SCRIPT} +.if defined(WITH_LIBUNRAR) + ${PATCH} -d ${WRKSRC}/libclamav < ${PORTSDIR}/security/clamav/files/clamav-0.87-libunrar3.patch +.endif pre-build: @if ${LDCONFIG} -r | ${GREP} -qw -e -lclamav; then \ diff --git a/security/clamav/files/clamav-0.87-libunrar3.patch b/security/clamav/files/clamav-0.87-libunrar3.patch new file mode 100644 index 000000000000..a349b3d0ec96 --- /dev/null +++ b/security/clamav/files/clamav-0.87-libunrar3.patch @@ -0,0 +1,3236 @@ +diff -ruN clamav-0.84.orig/libclamav/Makefile.am clamav-0.84/libclamav/Makefile.am +--- clamav-0.84.orig/libclamav/Makefile.am 2005-04-20 03:33:17.000000000 +0400 ++++ clamav-0.84/libclamav/Makefile.am 2005-05-04 02:12:02.540693464 +0400 +@@ -17,6 +17,8 @@ + + + INCLUDES = -I$(top_srcdir) -I@srcdir@/zziplib -I@srcdir@/mspack ++CFLAGS = @CFLAGS@ -DUNRAR3 ++LDFLAGS = @LDFLAGS@ -lunrar + + libclamav_la_LIBADD = @LIBCLAMAV_LIBS@ + +diff -ruN clamav-0.84.orig/libclamav/scanners.c clamav-0.84/libclamav/scanners.c +--- clamav-0.84.orig/libclamav/scanners.c 2005-04-29 05:31:10.000000000 +0400 ++++ clamav-0.84/libclamav/scanners.c 2005-05-04 02:12:02.543693008 +0400 +@@ -42,12 +42,13 @@ + + #include <mspack.h> + ++#ifndef UNRAR3 + #ifdef CL_THREAD_SAFE + # include <pthread.h> + pthread_mutex_t cli_scanrar_mutex = PTHREAD_MUTEX_INITIALIZER; + #endif + int cli_scanrar_inuse = 0; +- ++#endif + extern short cli_leavetemps_flag; + + extern int cli_mbox(const char *dir, int desc, unsigned int options); /* FIXME */ +@@ -111,6 +112,7 @@ + static int cli_scanfile(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_node *root, const struct cl_limits *limits, unsigned int options, unsigned int arec, unsigned int mrec); + + ++#ifndef UNRAR3 + #ifdef CL_THREAD_SAFE + static void cli_unlock_mutex(void *mtx) + { +@@ -330,6 +332,7 @@ + + return ret; + } ++#endif + + #ifdef HAVE_ZLIB_H + static int cli_scanzip(int desc, const char **virname, long int *scanned, const struct cl_node *root, const struct cl_limits *limits, unsigned int options, unsigned int arec, unsigned int mrec) +@@ -1213,6 +1216,43 @@ + return ret; + } + ++#ifdef UNRAR3 ++static int cli_scanrar3(int desc, const char **virname, long int *scanned, const struct cl_node *root, const struct cl_limits *limits, unsigned int options, unsigned int arec, unsigned int mrec) ++{ ++ const char *tmpdir; ++ char *dir; ++ int ret = CL_CLEAN; ++ ++ ++ cli_dbgmsg("in cli_scanrar3()\n"); ++ ++ if((tmpdir = getenv("TMPDIR")) == NULL) ++#ifdef P_tmpdir ++ tmpdir = P_tmpdir; ++#else ++ tmpdir = "/tmp"; ++#endif ++ ++ /* generate temporary directory */ ++ dir = cli_gentemp(tmpdir); ++ if(mkdir(dir, 0700)) { ++ cli_errmsg("Rar3: Can't create temporary directory %s\n", dir); ++ return CL_ETMPDIR; ++ } ++ ++ if((ret = cli_unrar3(dir, desc))) ++ cli_dbgmsg("Rar3: %s\n", cl_strerror(ret)); ++ else ++ ret = cli_scandir(dir, virname, scanned, root, limits, options, arec, mrec); ++ ++ if(!cli_leavetemps_flag) ++ cli_rmdirs(dir); ++ ++ free(dir); ++ return ret; ++} ++#endif ++ + static int cli_scanmschm(int desc, const char **virname, long int *scanned, const struct cl_node *root, const struct cl_limits *limits, unsigned int options, unsigned int arec, unsigned int mrec) + { + char *tempname; +@@ -1400,8 +1440,13 @@ + + switch(type) { + case CL_TYPE_RAR: ++#ifdef UNRAR3 ++ if(!DISABLE_RAR && SCAN_ARCHIVE) ++ ret = cli_scanrar3(desc, virname, scanned, root, limits, options, arec, mrec); ++#else + if(!DISABLE_RAR && SCAN_ARCHIVE && !cli_scanrar_inuse) + ret = cli_scanrar(desc, virname, scanned, root, limits, options, arec, mrec); ++#endif + break; + + case CL_TYPE_ZIP: +@@ -1538,8 +1583,17 @@ + * in raw mode. Now we will try to unpack them + */ + case CL_TYPE_MSEXE: ++#ifdef UNRAR3 ++ if(!DISABLE_RAR && SCAN_ARCHIVE) ++ ret = cli_scanrar3(desc, virname, scanned, root, limits, options, arec, mrec); ++ if(SCAN_PE && ret != CL_VIRUS) ++#else + if(SCAN_PE) ++#endif ++ { ++ lseek(desc, 0, SEEK_SET); + ret = cli_scanpe(desc, virname, scanned, root, limits, options, arec, mrec); ++ } + break; + + default: +diff -ruN clamav-0.84.orig/libclamav/unrarlib.c clamav-0.84/libclamav/unrarlib.c +--- clamav-0.84.orig/libclamav/unrarlib.c 2005-04-20 03:33:17.000000000 +0400 ++++ clamav-0.84/libclamav/unrarlib.c 2005-05-04 02:12:27.131955024 +0400 +@@ -1,2774 +1,119 @@ +-/* It contains some changes needed for libclamav and isn't compatible with +- * the original version, --tk ++/* ++ * Copyright (C) 2004 McMCC <mcmcc@mail.ru> ++ * ++ * Support check archives RAR v.3.x ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * + */ +-/* *************************************************************************** +- ** +- ** This file is part of the UniquE RAR File Library. +- ** +- ** Copyright (C) 2000-2002 by Christian Scheurer (www.ChristianScheurer.ch) +- ** UNIX port copyright (c) 2000-2002 by Johannes Winkelmann (jw@tks6.net) +- ** +- ** The contents of this file are subject to the UniquE RAR File Library +- ** License (the "unrarlib-license.txt"). You may not use this file except +- ** in compliance with the License. You may obtain a copy of the License +- ** at http://www.unrarlib.org/license.html. +- ** Software distributed under the License is distributed on an "AS IS" +- ** basis, WITHOUT WARRANTY OF ANY KIND, either express or implied warranty. +- ** +- ** Alternatively, the contents of this file may be used under the terms +- ** of the GNU General Public License Version 2 or later (the "GPL"), in +- ** which case the provisions of the GPL are applicable instead of those +- ** above. If you wish to allow use of your version of this file only +- ** under the terms of the GPL and not to allow others to use your version +- ** of this file under the terms of the UniquE RAR File Library License, +- ** indicate your decision by deleting the provisions above and replace +- ** them with the notice and other provisions required by the GPL. If you +- ** do not delete the provisions above, a recipient may use your version +- ** of this file under the terms of the GPL or the UniquE RAR File Library +- ** License. +- ** +- ************************************************************************** */ +- +-/* *************************************************************************** +- ** +- ** UniquE RAR File Library +- ** The free file lib for the demoscene +- ** multi-OS version (Win32, Linux and SunOS) +- ** +- ***************************************************************************** +- ** +- ** ==> Please configure the program in "unrarlib.h". <== +- ** +- ** RAR decompression code: +- ** (C) Eugene Roshal +- ** Modifications to a FileLib: +- ** (C) 2000-2002 Christian Scheurer aka. UniquE/Vantage (cs@unrarlib.org) +- ** Linux port: +- ** (C) 2000-2002 Johannes Winkelmann (jw@tks6.net) +- ** +- ** The UniquE RAR File Library gives you the ability to access RAR archives +- ** (any compression method supported in RAR v2.0 including Multimedia +- ** Compression and encryption) directly from your program with ease an by +- ** adding only 12kB (6kB UPX-compressed) additional code to your program. +- ** Both solid and normal (recommended for fast random access to the files!) +- ** archives are supported. This FileLib is made for the Demo scene, so it's +- ** designed for easy use within your demos and intros. +- ** Please read "licence.txt" to learn more about how you may use URARFileLib +- ** in your productions. +- ** +- ***************************************************************************** +- ** +- ** ==> see the "CHANGES" file to see what's new +- ** +- ************************************************************************** */ +- +-/* -- include files ------------------------------------------------------- */ +-#if HAVE_CONFIG_H +-#include "clamav-config.h" +-#endif +- +-#include "unrarlib.h" /* include global configuration */ +-#include "others.h" +-/* ------------------------------------------------------------------------ */ +- ++static char const rcsid[] = "$Id: unrarlib.c,v 1.0 2004/10/20 18:18:46 mcmcc Exp $"; + +- +-/* -- global stuff -------------------------------------------------------- */ +-#ifdef _WIN_32 +- +-#include <windows.h> /* WIN32 definitions */ + #include <stdio.h> +-#include <string.h> +- +- +-#define ENABLE_ACCESS +- +-#define HOST_OS WIN_32 +- +-#define FM_NORMAL 0x00 +-#define FM_RDONLY 0x01 +-#define FM_HIDDEN 0x02 +-#define FM_SYSTEM 0x04 +-#define FM_LABEL 0x08 +-#define FM_DIREC 0x10 +-#define FM_ARCH 0x20 +- +-#define PATHDIVIDER "\\" +-#define CPATHDIVIDER '\\' +-#define MASKALL "*.*" +- +-#define READBINARY "rb" +-#define READTEXT "rt" +-#define UPDATEBINARY "r+b" +-#define CREATEBINARY "w+b" +-#define CREATETEXT "w" +-#define APPENDTEXT "at" +- +-#endif +- +-#ifdef _UNIX +- +-#include <stdio.h> /* LINUX/UNIX definitions */ + #include <stdlib.h> +-#include <unistd.h> +-#include <ctype.h> +-#include <string.h> + #include <errno.h> +- +-#define ENABLE_ACCESS +- +-#define HOST_OS UNIX +- +-#define FM_LABEL 0x0000 +-#define FM_DIREC 0x4000 +- +-#define PATHDIVIDER "/" +-#define CPATHDIVIDER '/' +-#define MASKALL "*.*" +- +-#define READBINARY "r" +-#define READTEXT "r" +-#define UPDATEBINARY "r+" +-#define CREATEBINARY "w+" +-#define CREATETEXT "w" +-#define APPENDTEXT "a" +- +- +-/* emulation of the windows API and data types */ +-/* 20-08-2000 Johannes Winkelmann, jw@tks6.net */ +- +-typedef long DWORD; +-typedef short BOOL; +-#define TRUE 1 +-#define FALSE 0 +- +- +-#ifdef _DEBUG_LOG /* define macros for debugging */ ++#include <string.h> + #include <unistd.h> +-#include <sys/time.h> +- +-DWORD GetTickCount() +-{ +- struct timeval tv; +- gettimeofday( &tv, 0 ); +- return (tv.tv_usec / 1000); +-} +-#endif +- +-#endif +- +- +- +- +- +-#ifdef _DEBUG_LOG /* define macros for debugging */ +- +-BOOL debug_log_first_start = TRUE; +- +-#define debug_log(a); debug_log_proc(a, __FILE__, __LINE__); +-#define debug_init(a); debug_init_proc(a); +- +-void debug_log_proc(char *text, char *sourcefile, int sourceline); +-void debug_init_proc(char *file_name); +- +-#else +-#define debug_log(a); cli_dbgmsg("%s:%d %s\n", __FILE__, __LINE__, a); +-#define debug_init(a); /* no debug this time */ +-#endif +- +- +- +- +- +-#define MAXWINSIZE 0x100000 +-#define MAXWINMASK (MAXWINSIZE-1) +-#define UNP_MEMORY MAXWINSIZE +-#define Min(x,y) (((x)<(y)) ? (x):(y)) +-#define Max(x,y) (((x)>(y)) ? (x):(y)) +-#define NM 260 +- +-#define SIZEOF_MARKHEAD 7 +-#define SIZEOF_OLDMHD 7 +-#define SIZEOF_NEWMHD 13 +-#define SIZEOF_OLDLHD 21 +-#define SIZEOF_NEWLHD 32 +-#define SIZEOF_SHORTBLOCKHEAD 7 +-#define SIZEOF_LONGBLOCKHEAD 11 +-#define SIZEOF_COMMHEAD 13 +-#define SIZEOF_PROTECTHEAD 26 +- +- +-#define PACK_VER 20 /* version of decompression code*/ +-#define UNP_VER 20 +-#define PROTECT_VER 20 +- +- +-enum { M_DENYREAD,M_DENYWRITE,M_DENYNONE,M_DENYALL }; +-enum { FILE_EMPTY,FILE_ADD,FILE_UPDATE,FILE_COPYOLD,FILE_COPYBLOCK }; +-enum { SUCCESS,WARNING,FATAL_ERROR,CRC_ERROR,LOCK_ERROR,WRITE_ERROR, +- OPEN_ERROR,USER_ERROR,MEMORY_ERROR,USER_BREAK=255,IMM_ABORT=0x8000 }; +-enum { EN_LOCK=1,EN_VOL=2 }; +-enum { SD_MEMORY=1,SD_FILES=2 }; +-enum { NAMES_DONTCHANGE }; +-enum { LOG_ARC=1,LOG_FILE=2 }; +-enum { OLD_DECODE=0,OLD_ENCODE=1,NEW_CRYPT=2 }; +-enum { OLD_UNPACK,NEW_UNPACK }; +- +- +-#define MHD_COMMENT 2 +-#define MHD_LOCK 4 +-#define MHD_PACK_COMMENT 16 +-#define MHD_AV 32 +-#define MHD_PROTECT 64 +- +-#define LHD_SPLIT_BEFORE 1 +-#define LHD_SPLIT_AFTER 2 +-#define LHD_PASSWORD 4 +-#define LHD_COMMENT 8 +-#define LHD_SOLID 16 +- +-#define LHD_WINDOWMASK 0x00e0 +-#define LHD_WINDOW64 0 +-#define LHD_WINDOW128 32 +-#define LHD_WINDOW256 64 +-#define LHD_WINDOW512 96 +-#define LHD_WINDOW1024 128 +-#define LHD_DIRECTORY 0x00e0 +- +-#define LONG_BLOCK 0x8000 +-#define READSUBBLOCK 0x8000 +- +-enum { ALL_HEAD=0,MARK_HEAD=0x72,MAIN_HEAD=0x73,FILE_HEAD=0x74, +- COMM_HEAD=0x75,AV_HEAD=0x76,SUB_HEAD=0x77,PROTECT_HEAD=0x78}; +-enum { EA_HEAD=0x100 }; +-enum { MS_DOS=0,OS2=1,WIN_32=2,UNIX=3 }; +- +- +-struct MarkHeader +-{ +- UBYTE Mark[7]; +-}; +- +- +-struct NewMainArchiveHeader +-{ +- UWORD HeadCRC; +- UBYTE HeadType; +- UWORD Flags; +- UWORD HeadSize; +- UWORD Reserved; +- UDWORD Reserved1; +-}; +- +- +-struct NewFileHeader +-{ +- UWORD HeadCRC; +- UBYTE HeadType; +- UWORD Flags; +- UWORD HeadSize; +- UDWORD PackSize; +- UDWORD UnpSize; +- UBYTE HostOS; +- UDWORD FileCRC; +- UDWORD FileTime; +- UBYTE UnpVer; +- UBYTE Method; +- UWORD NameSize; +- UDWORD FileAttr; +-}; +- +- +-struct BlockHeader +-{ +- UWORD HeadCRC; +- UBYTE HeadType; +- UWORD Flags; +- UWORD HeadSize; +- UDWORD DataSize; +-}; +- +- +-struct Decode +-{ +- unsigned int MaxNum; +- unsigned int DecodeLen[16]; +- unsigned int DecodePos[16]; +- unsigned int DecodeNum[2]; +-}; +- +- +-static struct MarkHeader MarkHead; +-static struct NewMainArchiveHeader NewMhd; +-static struct NewFileHeader NewLhd; +-static struct BlockHeader BlockHead; +- +-static UBYTE *TempMemory = NULL; /* temporary unpack-buffer */ +-static char *CommMemory = NULL; +- +- +-static UBYTE *UnpMemory = NULL; +-static char ArgName[NM]; /* current file in rar archive */ +-static char ArcFileName[NM]; /* file to decompress */ +- +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION /* mem-to-mem decompression */ +-static MemoryFile *MemRARFile; /* pointer to RAR file in memory*/ +-#else +-static FILE *ArcPtr; /* input RAR file handler */ +-#endif +-static char Password[255]; /* password to decrypt files */ +- +-static unsigned char *temp_output_buffer; /* extract files to this pointer*/ +-static unsigned long *temp_output_buffer_offset; /* size of temp. extract buffer */ +- +-static int MainHeadSize; +- +-static long CurBlockPos,NextBlockPos; +- +-static unsigned long CurUnpRead; +-static long UnpPackedSize; +-static long DestUnpSize; +- +-static UDWORD HeaderCRC; +-static int Encryption; +- +-static unsigned int UnpPtr,WrPtr; +- +-static unsigned char PN1,PN2,PN3; +-static unsigned short OldKey[4]; +- +- +- +-/* function header definitions */ +-static int ReadHeader(int BlockType); +-static BOOL ExtrFile(int desc); +-static int tread(void *stream,void *buf,unsigned len); +-static int tseek(void *stream,long offset,int fromwhere); +-/* static BOOL UnstoreFile(void); */ +-static int IsArchive(void); +-static int ReadBlock(int BlockType); +-static unsigned int UnpRead(unsigned char *Addr,unsigned int Count); +-static void UnpInitData(void); +-static void Unpack(unsigned char *UnpAddr, BOOL FileFound); +-static UBYTE DecodeAudio(int Delta); +-static void DecodeNumber(struct Decode *Dec); +-static void UpdKeys(UBYTE *Buf); +-static void SetCryptKeys(char* NewPassword); +-static void SetOldKeys(char *NewPassword); +-static void DecryptBlock(unsigned char *Buf); +-static void InitCRC(void); +-static UDWORD CalcCRC32(UDWORD StartCRC,UBYTE *Addr,UDWORD Size); +-static void UnpReadBuf(int FirstBuf); +-static void ReadTables(void); +-static void ReadLastTables(void); +-static void MakeDecodeTables(unsigned char *LenTab, +- struct Decode *Dec, +- int Size); +-static int stricomp(char *Str1,char *Str2); +-/* ------------------------------------------------------------------------ */ +- +- +-/* -- global functions ---------------------------------------------------- */ +- +-int urarlib_get(void *output, +- unsigned long *size, +- char *filename, +- int desc, +- char *libpassword) +-/* Get a file from a RAR file to the "output" buffer. The UniquE RAR FileLib +- * does everything from allocating memory, decrypting and unpacking the file +- * from the archive. TRUE is returned if the file could be successfully +- * extracted, else a FALSE indicates a failure. +- */ +-{ +- BOOL retcode = FALSE; +- +-#ifdef _DEBUG_LOG +- int str_offs; /* used for debug-strings */ +- char DebugMsg[500]; /* used to compose debug msg */ +- +- if(debug_log_first_start) +- { +- debug_log_first_start=FALSE; /* only create a new log file */ +- debug_init(_DEBUG_LOG_FILE); /* on startup */ +- } +- +-#endif +- +- InitCRC(); /* init some vars */ +- +- strcpy(ArgName, filename); /* set file(s) to extract */ +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- MemRARFile = rarfile; /* set pointer to mem-RAR file */ +-#endif +- if(libpassword != NULL) +- strcpy(Password, libpassword); /* init password */ +- +- temp_output_buffer = NULL; +- temp_output_buffer_offset=size; /* set size of the temp buffer */ +- +- retcode = ExtrFile(desc); /* unpack file now! */ +- +- +- memset(Password,0,sizeof(Password)); /* clear password */ +- +-#ifndef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- if (ArcPtr!=NULL){ +- /* FIXME: possible FILE* leak */ +- cli_dbgmsg("%s:%d NOT Close ArcPtr from fd %d\n", __FILE__, __LINE__, desc); +- /* +- fclose(ArcPtr); +- lseek(desc, 0, SEEK_SET); +- ArcPtr = NULL; +- */ +- } +-#endif +- +- if(UnpMemory) +- free(UnpMemory); +- +- if(TempMemory) +- free(TempMemory); +- +- if(CommMemory) +- free(CommMemory); +- +- UnpMemory=NULL; +- TempMemory=NULL; +- CommMemory=NULL; +- +- +- if(retcode == FALSE) +- { +- if(temp_output_buffer) +- free(temp_output_buffer); /* free memory and return NULL */ +- temp_output_buffer=NULL; +- *(DWORD*)output=0; /* pointer on errors */ +- *size=0; +-#ifdef _DEBUG_LOG +- +- +- /* sorry for this ugly code, but older SunOS gcc compilers don't support */ +- /* white spaces within strings */ +- str_offs = sprintf(DebugMsg, "Error - couldn't extract "); +- str_offs += sprintf(DebugMsg + str_offs, ">%s<", filename); +- str_offs += sprintf(DebugMsg + str_offs, " and allocated "); +- str_offs += sprintf(DebugMsg + str_offs, "%u Bytes", (unsigned int)*size); +- str_offs += sprintf(DebugMsg + str_offs, " of unused memory!"); +- +- } else +- { +- sprintf(DebugMsg, "Extracted %u Bytes.", (unsigned int)*size); +- } +- debug_log(DebugMsg); +-#else +- } +-#endif +- *(DWORD*)output=(DWORD)temp_output_buffer;/* return pointer for unpacked*/ +- /* data */ +- +- return retcode; +-} +- +- +-int urarlib_list(int desc, ArchiveList_struct *list) +-{ +- ArchiveList_struct *tmp_List = NULL; +- int NoOfFilesInArchive = 0; /* number of files in archive */ +- int newdesc; +- +-#ifdef _DEBUG_LOG +- if(debug_log_first_start) +- { +- debug_log_first_start=FALSE; /* only create a new log file */ +- debug_init(_DEBUG_LOG_FILE); /* on startup */ +- } +-#endif +- +- InitCRC(); /* init some vars */ +- +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- MemRARFile = rarfile; /* assign pointer to RAR file */ +- MemRARFile->offset = 0; +- if (!IsArchive()) +- { +- debug_log("Not a RAR file"); +- return NoOfFilesInArchive; /* error => exit! */ +- } +-#else +- /* open and identify archive */ +- newdesc = dup(desc); +- cli_dbgmsg("ExtrFile(): dup(%d) = %d\n", desc, newdesc); +- if ((ArcPtr=fdopen(newdesc,READBINARY))!=NULL) +- { +- if (!IsArchive()) +- { +- cli_dbgmsg("urarlib_list(): Not a valid archive."); +- debug_log("Not a RAR file"); +- fclose(ArcPtr); +- lseek(desc, 0, SEEK_SET); +- ArcPtr = NULL; +- return NoOfFilesInArchive; /* error => exit! */ +- } +- } +- else { +- cli_dbgmsg("urarlib_list(): Error opening file: %s", strerror(errno)); +- debug_log("Error opening file."); +- cli_dbgmsg("%s:%d Close fd %d\n", __FILE__, __LINE__, newdesc); +- close(newdesc); +- return NoOfFilesInArchive; +- } +-#endif +- +- if ((UnpMemory=malloc(UNP_MEMORY))==NULL) +- { +- cli_dbgmsg("urarlib_list(): out of memory."); +- debug_log("Can't allocate memory for decompression!"); +- fclose(ArcPtr); +- return NoOfFilesInArchive; +- } +- +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- MemRARFile->offset+=NewMhd.HeadSize-MainHeadSize; +-#else +- tseek(ArcPtr,NewMhd.HeadSize-MainHeadSize,SEEK_CUR); +-#endif +- (*(DWORD*)list) = (DWORD)NULL; /* init file list */ +- /* do while file is not extracted and there's no error */ +- for(;;) +- { +- int ReadBlockResult; +- if ((ReadBlockResult = ReadBlock(FILE_HEAD | READSUBBLOCK)) <= 0) /* read name of the next */ +- { /* file within the RAR archive */ +- cli_dbgmsg("Couldn't read next filename from archive (I/O error): %d\n", ReadBlockResult); +- break; /* error, file not found in */ +- } /* archive or I/O error */ +- if (BlockHead.HeadType==SUB_HEAD) +- { +- debug_log("Sorry, sub-headers not supported."); +- NoOfFilesInArchive = 0; +- break; /* error => exit */ +- } +- +- if((void*)(*(DWORD*)list) == NULL) /* first entry */ +- { +- tmp_List = malloc(sizeof(ArchiveList_struct)); +- tmp_List->next = NULL; +- +- (*(DWORD*)list) = (DWORD)tmp_List; +- +- } else /* add entry */ +- { +- tmp_List->next = malloc(sizeof(ArchiveList_struct)); +- tmp_List = (ArchiveList_struct*) tmp_List->next; +- tmp_List->next = NULL; +- } +- +- tmp_List->item.Name = malloc(NewLhd.NameSize + 1); +- strcpy(tmp_List->item.Name, ArcFileName); +- tmp_List->item.NameSize = NewLhd.NameSize; +- tmp_List->item.PackSize = NewLhd.PackSize; +- tmp_List->item.UnpSize = NewLhd.UnpSize; +- tmp_List->item.HostOS = NewLhd.HostOS; +- tmp_List->item.FileCRC = NewLhd.FileCRC; +- tmp_List->item.FileTime = NewLhd.FileTime; +- tmp_List->item.UnpVer = NewLhd.UnpVer; +- tmp_List->item.Method = NewLhd.Method; +- tmp_List->item.FileAttr = NewLhd.FileAttr; +- tmp_List->item.Flags = NewLhd.Flags; +- +- NoOfFilesInArchive++; /* count files */ +- +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- MemRARFile->offset = NextBlockPos; +-#else +- if (ArcPtr!=NULL) tseek(ArcPtr,NextBlockPos,SEEK_SET); +-#endif +- +- }; +- +- /* free memory, clear password and close archive */ +- memset(Password,0,sizeof(Password)); /* clear password */ +-#ifndef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- if (ArcPtr!=NULL){ +- fclose(ArcPtr); +- ArcPtr = NULL; +- lseek(desc, 0, SEEK_SET); +- } +-#endif +- +- if(UnpMemory) +- free(UnpMemory); +- +- if(TempMemory) +- free(TempMemory); +- +- if(CommMemory) +- free(CommMemory); +- +- UnpMemory=NULL; +- TempMemory=NULL; +- CommMemory=NULL; +- +- return NoOfFilesInArchive; +-} +- +- +- +-/* urarlib_freelist: +- * (after the suggestion and code of Duy Nguyen, Sean O'Blarney +- * and Johannes Winkelmann who independently wrote a patch) +- * free the memory of a ArchiveList_struct created by urarlib_list. +- * +- * input: *list pointer to an ArchiveList_struct +- * output: - +- */ +- +-void urarlib_freelist(ArchiveList_struct *list) +-{ +- ArchiveList_struct* tmp = list; +- +- while ( list ) { +- tmp = list->next; +- free( list->item.Name ); +- free( list ); +- list = tmp; +- } +-} +- +- +-/* ------------------------------------------------------------------------ */ +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-/**************************************************************************** +- **************************************************************************** +- **************************************************************************** +- **************************************************************************** +- ******* ******* +- ******* ******* +- ******* ******* +- ******* B L O C K I / O ******* +- ******* ******* +- ******* ******* +- ******* ******* +- **************************************************************************** +- **************************************************************************** +- **************************************************************************** +- ****************************************************************************/ +- +- +- +-#define GetHeaderByte(N) Header[N] +- +-#define GetHeaderWord(N) (Header[N]+((UWORD)Header[N+1]<<8)) +- +-#define GetHeaderDword(N) (Header[N]+((UWORD)Header[N+1]<<8)+\ +- ((UDWORD)Header[N+2]<<16)+\ +- ((UDWORD)Header[N+3]<<24)) +- +- +-int ReadBlock(int BlockType) +-{ +- struct NewFileHeader SaveFileHead; +- int Size=0,ReadSubBlock=0; +- static int LastBlock; +- memcpy(&SaveFileHead,&NewLhd,sizeof(SaveFileHead)); +- if (BlockType & READSUBBLOCK) { +- ReadSubBlock=1; +- BlockType &= 0xff; +- } +- { +- while (1) +- { +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- CurBlockPos=MemRARFile->offset; /* get offset of mem-file */ +-#else +- CurBlockPos=ftell(ArcPtr); +-#endif +- Size=ReadHeader(FILE_HEAD); +- if (Size!=0) +- { +- if (NewLhd.HeadSize<SIZEOF_SHORTBLOCKHEAD) +- return(0); +- NextBlockPos=CurBlockPos+NewLhd.HeadSize; +- if (NewLhd.Flags & LONG_BLOCK) +- NextBlockPos+=NewLhd.PackSize; +- if (NextBlockPos<=CurBlockPos) +- return(0); +- } +- +- if (Size > 0 && BlockType!=SUB_HEAD) +- LastBlock=BlockType; +- if (Size==0 || BlockType==ALL_HEAD || NewLhd.HeadType==BlockType || +- (NewLhd.HeadType==SUB_HEAD && ReadSubBlock && LastBlock==BlockType)) +- break; +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- MemRARFile->offset = NextBlockPos; +-#else +- tseek(ArcPtr, NextBlockPos, SEEK_SET); +-#endif ++#include <sys/stat.h> ++#include <fcntl.h> ++#include <sys/param.h> ++#include <libunrar3/dll.hpp> ++#include "clamav.h" ++#include "others.h" ++#include "unrarlib.h" ++#include "mbox.h" ++#include "blob.h" ++ ++int cli_unrar3(const char *dir, int desc) ++{ ++ ++ struct RAROpenArchiveDataEx OpenArchiveData; ++ struct RARHeaderData HeaderData; ++ int iReadHeaderCode, iProcessFileCode, fd, s_buff; ++ char buff[4096], uname[48]; ++ const char *tmpdir; ++ HANDLE hArcData; ++ FILE *out; ++ ++ if((tmpdir = getenv("TMPDIR")) == NULL) ++#ifdef P_tmpdir ++ tmpdir = P_tmpdir; ++#else ++ tmpdir = "/tmp"; ++#endif ++ ++ sprintf(uname, "%s/rarXXXXXX", tmpdir); ++ ++ if((fd = mkstemp(uname)) < 0 || (out = fdopen(fd, "w+")) == NULL) ++ { ++ ++ cli_dbgmsg("cli_unrar3: can't generate temporary file %s or open descriptor %d.\n", ++ uname, fd); ++ if(fd >= 0) ++ close(fd); ++ unlink(uname); ++ return CL_ETMPFILE; ++ } ++ ++ while((s_buff=read(desc, buff, sizeof(buff))) > 0) ++ { ++ if(fwrite(buff, 1, s_buff, out) != s_buff) ++ { ++ cli_dbgmsg("cli_unrar3: can't write to file %s.\n", uname); ++ fclose(out); ++ close(fd); ++ unlink(uname); ++ return CL_EOPEN; ++ } + } +- } +- +- BlockHead.HeadCRC=NewLhd.HeadCRC; +- BlockHead.HeadType=NewLhd.HeadType; +- BlockHead.Flags=NewLhd.Flags; +- BlockHead.HeadSize=NewLhd.HeadSize; +- BlockHead.DataSize=NewLhd.PackSize; +- +- if (BlockType!=NewLhd.HeadType) BlockType=ALL_HEAD; +- +- if((FILE_HEAD == BlockType) && (Size>0)) +- { +- NewLhd.NameSize=Min(NewLhd.NameSize,sizeof(ArcFileName)-1); +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- tread(MemRARFile, ArcFileName, NewLhd.NameSize); +-#else +- tread(ArcPtr,ArcFileName,NewLhd.NameSize); +-#endif +- ArcFileName[NewLhd.NameSize]=0; +-#ifdef _DEBUG_LOG +- if (NewLhd.HeadCRC!=(UWORD)~CalcCRC32(HeaderCRC,(UBYTE*)&ArcFileName[0], +- NewLhd.NameSize)) +- { +- debug_log("file header broken"); ++ fclose(out); ++ close(fd); ++ ++ memset(&OpenArchiveData, 0, sizeof(OpenArchiveData)); ++ ++ OpenArchiveData.ArcName = uname; /* name arch */ ++ OpenArchiveData.CmtBuf = NULL; ++ OpenArchiveData.OpenMode = RAR_OM_EXTRACT; ++ ++ hArcData = RAROpenArchiveEx(&OpenArchiveData); ++ ++ if (OpenArchiveData.OpenResult != 0) ++ { ++ cli_dbgmsg("cli_unrar3: error archive open (%d)\n", OpenArchiveData.OpenResult); ++ unlink(uname); ++ return CL_EOPEN; ++ } ++ ++ HeaderData.CmtBuf = NULL; ++ ++ while ((iReadHeaderCode = RARReadHeader(hArcData, &HeaderData)) == 0) ++ { ++ iProcessFileCode = RARProcessFile(hArcData, RAR_EXTRACT, (char *)dir, NULL); ++ if (iProcessFileCode != 0) ++ { ++ cli_dbgmsg("cli_unrar3: error archive extract (%d)\n", iProcessFileCode); ++ break; ++ } ++ + } +-#endif +- Size+=NewLhd.NameSize; +- } else +- { +- memcpy(&NewLhd,&SaveFileHead,sizeof(NewLhd)); +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- MemRARFile->offset = CurBlockPos; +-#else +- tseek(ArcPtr,CurBlockPos,SEEK_SET); +-#endif +- } +- +- +- return(Size); +-} +- +- +-int ReadHeader(int BlockType) +-{ +- int Size = 0; +- unsigned char Header[64]; +- memset(Header, 0, sizeof(Header)); +- switch(BlockType) +- { +- case MAIN_HEAD: +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- Size=tread(MemRARFile, Header, SIZEOF_NEWMHD); +-#else +- Size=tread(ArcPtr,Header,SIZEOF_NEWMHD); +-#endif +- NewMhd.HeadCRC=(unsigned short)GetHeaderWord(0); +- NewMhd.HeadType=GetHeaderByte(2); +- NewMhd.Flags=(unsigned short)GetHeaderWord(3); +- NewMhd.HeadSize=(unsigned short)GetHeaderWord(5); +- NewMhd.Reserved=(unsigned short)GetHeaderWord(7); +- NewMhd.Reserved1=GetHeaderDword(9); +- HeaderCRC=CalcCRC32(0xFFFFFFFFL,&Header[2],SIZEOF_NEWMHD-2); +- break; +- case FILE_HEAD: +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- Size=tread(MemRARFile, Header, SIZEOF_NEWLHD); +-#else +- Size=tread(ArcPtr,Header,SIZEOF_NEWLHD); +-#endif +- NewLhd.HeadCRC=(unsigned short)GetHeaderWord(0); +- NewLhd.HeadType=GetHeaderByte(2); +- NewLhd.Flags=(unsigned short)GetHeaderWord(3); +- NewLhd.HeadSize=(unsigned short)GetHeaderWord(5); +- NewLhd.PackSize=GetHeaderDword(7); +- NewLhd.UnpSize=GetHeaderDword(11); +- NewLhd.HostOS=GetHeaderByte(15); +- NewLhd.FileCRC=GetHeaderDword(16); +- NewLhd.FileTime=GetHeaderDword(20); +- NewLhd.UnpVer=GetHeaderByte(24); +- NewLhd.Method=GetHeaderByte(25); +- NewLhd.NameSize=(unsigned short)GetHeaderWord(26); +- NewLhd.FileAttr=GetHeaderDword(28); +- HeaderCRC=CalcCRC32(0xFFFFFFFFL,Header+2,SIZEOF_NEWLHD-2); +- break; +- +-#ifdef _DEBUG_LOG +- case COMM_HEAD: /* log errors in case of debug */ +- debug_log("Comment headers not supported! "\ +- "Please create archives without comments."); +- break; +- case PROTECT_HEAD: +- debug_log("Protected headers not supported!"); +- break; +- case ALL_HEAD: +- debug_log("ShortBlockHeader not supported!"); +- break; +- default: +- debug_log("Unknown//unsupported !"); +-#else +- default: /* else do nothing */ +- break; +-#endif +- } +- return(Size); ++ ++ RARCloseArchive(hArcData); ++ unlink(uname); ++ ++ /* ++ if (iProcessFileCode == ERAR_BAD_DATA) ++ return CL_ERAR; ++ */ ++ return CL_CLEAN; + } +- +-/* ************************************************************************** +- **************************************************************************** +- **************************************************************************** +- ************************************************************************** */ +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-/* ************************************************************************** +- **************************************************************************** +- **************************************************************************** +- **************************************************************************** +- ******* ******* +- ******* ******* +- ******* ******* +- ******* E X T R A C T L O O P ******* +- ******* ******* +- ******* ******* +- ******* ******* +- **************************************************************************** +- **************************************************************************** +- **************************************************************************** +- ************************************************************************** */ +- +- +-int IsArchive(void) +-{ +-#ifdef _DEBUG_LOG +- int str_offs; /* used for debug-strings */ +- char DebugMsg[500]; /* used to compose debug msg */ +-#endif +- +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- if (tread(MemRARFile, MarkHead.Mark, SIZEOF_MARKHEAD) != SIZEOF_MARKHEAD) { +- debug_log("IsArchive(): short read: FALSE"); +- return(FALSE); +- } +-#else +- if (tread(ArcPtr,MarkHead.Mark,SIZEOF_MARKHEAD)!=SIZEOF_MARKHEAD) { +- debug_log("IsArchive(): short read: FALSE"); +- return(FALSE); +- } +-#endif +- /* Old archive => error */ +- if (MarkHead.Mark[0]==0x52 && MarkHead.Mark[1]==0x45 && +- MarkHead.Mark[2]==0x7e && MarkHead.Mark[3]==0x5e) +- { +- debug_log("Attention: format as OLD detected! Can't handle archive!"); +- } +- else +- /* original RAR v2.0 */ +- if ((MarkHead.Mark[0]==0x52 && MarkHead.Mark[1]==0x61 && /* original */ +- MarkHead.Mark[2]==0x72 && MarkHead.Mark[3]==0x21 && /* RAR header*/ +- MarkHead.Mark[4]==0x1a && MarkHead.Mark[5]==0x07 && +- MarkHead.Mark[6]==0x00) || +- /* "UniquE!" - header */ +- (MarkHead.Mark[0]=='U' && MarkHead.Mark[1]=='n' && /* "UniquE!" */ +- MarkHead.Mark[2]=='i' && MarkHead.Mark[3]=='q' && /* header */ +- MarkHead.Mark[4]=='u' && MarkHead.Mark[5]=='E' && +- MarkHead.Mark[6]=='!')) +- +- { +- if (ReadHeader(MAIN_HEAD)!=SIZEOF_NEWMHD) { +- debug_log("IsArchive(): ReadHeader() failed"); +- return(FALSE); +- } +- } else +- { +- +-#ifdef _DEBUG_LOG +- /* sorry for this ugly code, but older SunOS gcc compilers don't */ +- /* support white spaces within strings */ +- str_offs = sprintf(DebugMsg, "unknown archive type (only plain RAR "); +- str_offs += sprintf(DebugMsg + str_offs, "supported (normal and solid "); +- str_offs += sprintf(DebugMsg + str_offs, "archives), SFX and Volumes "); +- str_offs += sprintf(DebugMsg + str_offs, "are NOT supported!)"); +- +- debug_log(DebugMsg); +-#endif +- +- } +- +- +- MainHeadSize=SIZEOF_NEWMHD; +- +- return(TRUE); +-} +- +- +-BOOL ExtrFile(int desc) +-{ +- BOOL ReturnCode=TRUE; +- BOOL FileFound=FALSE; /* TRUE=use current extracted */ +- /* data FALSE=throw data away, */ +- /* wrong file */ +- int newdesc; +- +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- MemRARFile->offset = 0; /* start reading from offset 0 */ +- if (!IsArchive()) +- { +- debug_log("Not a RAR file"); +- return FALSE; /* error => exit! */ +- } +- +-#else +- /* open and identify archive */ +- newdesc = dup(desc); +- cli_dbgmsg("ExtrFile(): dup(%d) = %d\n", desc, newdesc); +- if ((ArcPtr=fdopen(newdesc,READBINARY))!=NULL) +- { +- if (!IsArchive()) +- { +- debug_log("Not a RAR file"); +- fclose(ArcPtr); +- ArcPtr = NULL; +- return FALSE; /* error => exit! */ +- } +- } else +- { +- debug_log("Error opening file."); +- return FALSE; +- } +-#endif +- +- +- if ((UnpMemory=malloc(UNP_MEMORY))==NULL) +- { +- cli_dbgmsg("unrarlib: Can't allocate memory for decompression!"); +- return FALSE; +- } else cli_dbgmsg("unrarlib: Allocated %d bytes.\n", UNP_MEMORY); +- +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- MemRARFile->offset+=NewMhd.HeadSize-MainHeadSize; +-#else +- tseek(ArcPtr,NewMhd.HeadSize-MainHeadSize,SEEK_CUR); +-#endif +- +- /* do while file is not extracted and there's no error */ +- do +- { +- +- if (ReadBlock(FILE_HEAD | READSUBBLOCK) <= 0) /* read name of the next */ +- { /* file within the RAR archive */ +-/* +- * +- * 21.11.2000 UnQ There's a problem with some linux distros when a file +- * can not be found in an archive. +- * 07.09.2004 ThL Seems more like a logical bug in this lib, since it +- * appears to occur once for every archive. +- */ +- +- /* +- debug_log("Couldn't read next filename from archive (I/O error)."); +- */ +- ReturnCode=FALSE; +- break; /* error, file not found in */ +- } /* archive or I/O error */ +- if (BlockHead.HeadType==SUB_HEAD) +- { +- debug_log("Sorry, sub-headers not supported."); +- ReturnCode=FALSE; +- break; /* error => exit */ +- } +- +- +- if(TRUE == (FileFound=(stricomp(ArgName, ArcFileName) == 0))) +- /* *** file found! *** */ +- { +- { +- cli_dbgmsg("unrarlib: Allocating %d bytes\n", NewLhd.UnpSize); +- if((temp_output_buffer=malloc(NewLhd.UnpSize)) == NULL) { ;/* allocate memory for the*/ +- cli_errmsg("unrarlib: Can't malloc %d bytes\n", NewLhd.UnpSize); +- ReturnCode = FALSE; +- break; +- } +- } +- *temp_output_buffer_offset=0; /* file. The default offset */ +- /* within the buffer is 0 */ +- } +- +- /* in case of a solid archive, we need to decompress any single file till +- * we have found the one we are looking for. In case of normal archives +- * (recommended!!), we skip the files until we are sure that it is the +- * one we want. +- */ +- if((NewMhd.Flags & 0x08) || FileFound) +- { +- if (NewLhd.UnpVer<13 || NewLhd.UnpVer>UNP_VER) +- { +- cli_dbgmsg("unknown compression method: %d (min=13 max=%d)\n", NewLhd.UnpVer, UNP_VER); +- ReturnCode=FALSE; +- break; /* error, can't extract file! */ +- } +- +- CurUnpRead=0; +- if ((*Password!=0) && (NewLhd.Flags & LHD_PASSWORD)) +- Encryption=NewLhd.UnpVer; +- else +- Encryption=0; +- if (Encryption) SetCryptKeys(Password); +- +- UnpPackedSize=NewLhd.PackSize; +- DestUnpSize=NewLhd.UnpSize; +- +- if (NewLhd.Method==0x30) +- { +- cli_dbgmsg("unrarlib: Unstore method temporarily not supported\n"); +- /* UnstoreFile(); */ +- ReturnCode=FALSE; +- break; /* error, can't extract file! */ +- } else +- { +- cli_dbgmsg("unrarlib: Unpack()\n"); +- Unpack(UnpMemory, FileFound); +- } +- +- +-#ifdef _DO_CRC32_CHECK /* calculate CRC32 */ +- if((UBYTE*)temp_output_buffer != NULL) +- { +- if(NewLhd.FileCRC!=~CalcCRC32(0xFFFFFFFFL, +- (UBYTE*)temp_output_buffer, +- NewLhd.UnpSize)) +- { +- debug_log("CRC32 error - file couldn't be decompressed correctly!"); +- ReturnCode=FALSE; +- break; /* error, can't extract file! */ +- } +- } +-#endif +- +- } +- +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- MemRARFile->offset = NextBlockPos; +-#else +- if (ArcPtr!=NULL) tseek(ArcPtr,NextBlockPos,SEEK_SET); +-#endif +- } while(stricomp(ArgName, ArcFileName) != 0);/* exit if file is extracted */ +- +- /* free memory, clear password and close archive */ +- if(UnpMemory) +- free(UnpMemory); +- +- UnpMemory=NULL; +-#ifndef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- if (ArcPtr!=NULL){ +- fclose(ArcPtr); +- lseek(desc, 0, SEEK_SET); +- ArcPtr = NULL; +- } +-#endif +- +- return ReturnCode; +-} +- +-/* ************************************************************************** +- **************************************************************************** +- **************************************************************************** +- ************************************************************************** */ +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-/* ************************************************************************** +- **************************************************************************** +- **************************************************************************** +- **************************************************************************** +- ******* ******* +- ******* ******* +- ******* ******* +- ******* G L O B A L F U N C T I O N S ******* +- ******* ******* +- ******* ******* +- ******* ******* +- **************************************************************************** +- **************************************************************************** +- **************************************************************************** +- ************************************************************************** */ +- +- +-int tread(void *stream,void *buf,unsigned len) +-{ +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- +- if(((MemRARFile->offset + len) > MemRARFile->size) || (len == 0)) +- return 0; +- +- memcpy(buf, +- (BYTE*)(((MemoryFile*)stream)->data)+((MemoryFile*)stream)->offset, +- len % ((((MemoryFile*)stream)->size) - 1)); +- +- MemRARFile->offset+=len; /* update read pointer */ +- return len % ((((MemoryFile*)stream)->size) - 1); +-#else +- return(fread(buf,1,len,(FILE*)stream)); +-#endif +-} +- +- +-#ifndef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +-int tseek(void *stream,long offset,int fromwhere) +-{ +- return(fseek((FILE*)stream,offset,fromwhere)); +-} +-#endif +- +- +-static char* strupper(char *Str) +-{ +- char *ChPtr; +- for (ChPtr=Str;*ChPtr;ChPtr++) +- *ChPtr=(char)toupper(*ChPtr); +- return(Str); +-} +- +- +-int stricomp(char *Str1,char *Str2) +-/* compare strings without regard of '\' and '/' */ +-{ +- char S1[512],S2[512]; +- char *chptr; +- +- strncpy(S1,Str1,sizeof(S1)); +- strncpy(S2,Str2,sizeof(S2)); +- +- while((chptr = strchr(S1, '\\')) != NULL) /* ignore backslash */ +- { +- *chptr = '_'; +- } +- +- while((chptr = strchr(S2, '\\')) != NULL) /* ignore backslash */ +- { +- *chptr = '_'; +- } +- +- while((chptr = strchr(S1, '/')) != NULL) /* ignore slash */ +- { +- *chptr = '_'; +- } +- +- while((chptr = strchr(S2, '/')) != NULL) /* ignore slash */ +- { +- *chptr = '_'; +- } +- +- return(strcmp(strupper(S1),strupper(S2))); +-} +- +- +-/* ************************************************************************** +- **************************************************************************** +- **************************************************************************** +- ************************************************************************** */ +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-/* ************************************************************************** +- **************************************************************************** +- **************************************************************************** +- **************************************************************************** +- ******* ******* +- ******* ******* +- ******* ******* +- ******* U N P A C K C O D E ******* +- ******* ******* +- ******* ******* +- ******* ******* +- **************************************************************************** +- **************************************************************************** +- **************************************************************************** +- ************************************************************************** */ +- +- +-/* ***************************** +- * ** unpack stored RAR files ** +- * *****************************/ +- +-/* +-BOOL UnstoreFile(void) +-{ +- if ((long)(*temp_output_buffer_offset=UnpRead(temp_output_buffer, +- NewLhd.UnpSize))==-1) +- { +- cli_dbgmsg("unrarlib: Read error of stored file!"); +- return FALSE; +- } +- return TRUE; +-} +-*/ +- +- +-/* **************************************** +- * ** RAR decompression code starts here ** +- * ****************************************/ +- +-#define NC 298 /* alphabet = {0,1,2, .,NC - 1} */ +-#define DC 48 +-#define RC 28 +-#define BC 19 +-#define MC 257 +- +-enum {CODE_HUFFMAN=0,CODE_LZ=1,CODE_LZ2=2,CODE_REPEATLZ=3,CODE_CACHELZ=4, +- CODE_STARTFILE=5,CODE_ENDFILE=6,CODE_STARTMM=8,CODE_ENDMM=7, +- CODE_MMDELTA=9}; +- +-struct AudioVariables +-{ +- int K1,K2,K3,K4,K5; +- int D1,D2,D3,D4; +- int LastDelta; +- unsigned int Dif[11]; +- unsigned int ByteCount; +- int LastChar; +-}; +- +- +-#define NC 298 /* alphabet = {0, 1, 2, ..., NC - 1} */ +-#define DC 48 +-#define RC 28 +-#define BC 19 +-#define MC 257 +- +- +-static struct AudioVariables AudV[4]; +- +-#define GetBits() \ +- BitField = ( ( ( (UDWORD)InBuf[InAddr] << 16 ) | \ +- ( (UWORD) InBuf[InAddr+1] << 8 ) | \ +- ( InBuf[InAddr+2] ) ) \ +- >> (8-InBit) ) & 0xffff; +- +- +-#define AddBits(Bits) \ +- InAddr += ( InBit + (Bits) ) >> 3; \ +- InBit = ( InBit + (Bits) ) & 7; +- +-static unsigned char *UnpBuf; +-static unsigned int BitField; +-static unsigned int Number; +- +-static unsigned char InBuf[8192]; /* input read buffer */ +- +-static unsigned char UnpOldTable[MC*4]; +- +-static unsigned int InAddr,InBit,ReadTop; +- +-static unsigned int LastDist,LastLength; +-static unsigned int Length,Distance; +- +-static unsigned int OldDist[4],OldDistPtr; +- +- +-static struct LitDecode +-{ +- unsigned int MaxNum; +- unsigned int DecodeLen[16]; +- unsigned int DecodePos[16]; +- unsigned int DecodeNum[NC]; +-} LD; +- +-static struct DistDecode +-{ +- unsigned int MaxNum; +- unsigned int DecodeLen[16]; +- unsigned int DecodePos[16]; +- unsigned int DecodeNum[DC]; +-} DD; +- +-static struct RepDecode +-{ +- unsigned int MaxNum; +- unsigned int DecodeLen[16]; +- unsigned int DecodePos[16]; +- unsigned int DecodeNum[RC]; +-} RD; +- +-static struct MultDecode +-{ +- unsigned int MaxNum; +- unsigned int DecodeLen[16]; +- unsigned int DecodePos[16]; +- unsigned int DecodeNum[MC]; +-} MD[4]; +- +-static struct BitDecode +-{ +- unsigned int MaxNum; +- unsigned int DecodeLen[16]; +- unsigned int DecodePos[16]; +- unsigned int DecodeNum[BC]; +-} BD; +- +-static struct MultDecode *MDPtr[4]={&MD[0],&MD[1],&MD[2],&MD[3]}; +- +-static int UnpAudioBlock,UnpChannels,CurChannel,ChannelDelta; +- +- +-void Unpack(unsigned char *UnpAddr, BOOL FileFound) +-/* *** 38.3% of all CPU time is spent within this function!!! */ +-{ +- static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32, +- 40,48,56,64,80,96,112,128,160,192,224}; +- static unsigned char LBits[]= {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3, +- 3,3,3,4,4,4,4,5,5,5,5}; +- static int DDecode[]={0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384, +- 512,768,1024,1536,2048,3072,4096,6144,8192,12288, +- 16384,24576,32768U,49152U,65536,98304,131072,196608, +- 262144,327680,393216,458752,524288,589824,655360, +- 720896,786432,851968,917504,983040}; +- static unsigned char DBits[]= {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9, +- 9,10,10,11,11,12,12,13,13,14,14,15,15,16, +- 16,16,16,16,16,16,16,16,16,16,16,16,16}; +- static unsigned char SDDecode[]={0,4,8,16,32,64,128,192}; +- static unsigned char SDBits[]={2,2,3, 4, 5, 6, 6, 6}; +- unsigned int Bits; +- +- +- UnpBuf=UnpAddr; /* UnpAddr is a pointer to the */ +- UnpInitData(); /* unpack buffer */ +- UnpReadBuf(1); +- if (!(NewLhd.Flags & LHD_SOLID)) +- ReadTables(); +- DestUnpSize--; +- +- while (DestUnpSize>=0) +- { +- UnpPtr&=MAXWINMASK; +- +- if (InAddr>sizeof(InBuf)-30) +- UnpReadBuf(0); +- if (((WrPtr-UnpPtr) & MAXWINMASK)<270 && WrPtr!=UnpPtr) +- { +- +- +- if (FileFound) +- { +- +- if (UnpPtr<WrPtr) +- { +- if((*temp_output_buffer_offset + ((0-WrPtr) & MAXWINMASK) + UnpPtr) > NewLhd.UnpSize) +- { +- debug_log("Fatal! Buffer overrun during decompression!"); +- DestUnpSize=-1; +- +- } else +- { +- /* copy extracted data to output buffer */ +- memcpy(temp_output_buffer + *temp_output_buffer_offset, +- &UnpBuf[WrPtr], (0-WrPtr) & MAXWINMASK); +- /* update offset within buffer */ +- *temp_output_buffer_offset+= (0-WrPtr) & MAXWINMASK; +- /* copy extracted data to output buffer */ +- memcpy(temp_output_buffer + *temp_output_buffer_offset, UnpBuf, +- UnpPtr); +- /* update offset within buffer */ +- *temp_output_buffer_offset+=UnpPtr; +- } +- } else +- { +- if((*temp_output_buffer_offset + (UnpPtr-WrPtr)) > NewLhd.UnpSize) +- { +- debug_log("Fatal! Buffer overrun during decompression!"); +- DestUnpSize=-1; +- } else +- { +- /* copy extracted data to output buffer */ +- memcpy(temp_output_buffer + *temp_output_buffer_offset, +- &UnpBuf[WrPtr], UnpPtr-WrPtr); +- *temp_output_buffer_offset+=UnpPtr-WrPtr; /* update offset within buffer */ +- } +- +- } +- } +- +- WrPtr=UnpPtr; +- } +- +- if (UnpAudioBlock) +- { +- DecodeNumber((struct Decode *)MDPtr[CurChannel]); +- if (Number==256) +- { +- ReadTables(); +- continue; +- } +- UnpBuf[UnpPtr++]=DecodeAudio(Number); +- if (++CurChannel==UnpChannels) +- CurChannel=0; +- DestUnpSize--; +- continue; +- } +- +- DecodeNumber((struct Decode *)&LD); +- if (Number<256) +- { +- UnpBuf[UnpPtr++]=(UBYTE)Number; +- DestUnpSize--; +- continue; +- } +- if (Number>269) +- { +- Length=LDecode[Number-=270]+3; +- if ((Bits=LBits[Number])>0) +- { +- GetBits(); +- Length+=BitField>>(16-Bits); +- AddBits(Bits); +- } +- +- DecodeNumber((struct Decode *)&DD); +- Distance=DDecode[Number]+1; +- if ((Bits=DBits[Number])>0) +- { +- GetBits(); +- Distance+=BitField>>(16-Bits); +- AddBits(Bits); +- } +- +- if (Distance>=0x40000L) +- Length++; +- +- if (Distance>=0x2000) +- Length++; +- +- LastDist=OldDist[OldDistPtr++ & 3]=Distance; +- DestUnpSize-=(LastLength=Length); +- while (Length--) +- { +- UnpBuf[UnpPtr]=UnpBuf[(UnpPtr-Distance) & MAXWINMASK]; +- UnpPtr=(UnpPtr+1) & MAXWINMASK; +- } +- +- continue; +- } +- if (Number==269) +- { +- ReadTables(); +- continue; +- } +- if (Number==256) +- { +- Length=LastLength; +- Distance=LastDist; +- LastDist=OldDist[OldDistPtr++ & 3]=Distance; +- DestUnpSize-=(LastLength=Length); +- while (Length--) +- { +- UnpBuf[UnpPtr]=UnpBuf[(UnpPtr-Distance) & MAXWINMASK]; +- UnpPtr=(UnpPtr+1) & MAXWINMASK; +- } +- continue; +- } +- if (Number<261) +- { +- Distance=OldDist[(OldDistPtr-(Number-256)) & 3]; +- DecodeNumber((struct Decode *)&RD); +- Length=LDecode[Number]+2; +- if ((Bits=LBits[Number])>0) +- { +- GetBits(); +- Length+=BitField>>(16-Bits); +- AddBits(Bits); +- } +- if (Distance>=0x40000) +- Length++; +- if (Distance>=0x2000) +- Length++; +- if (Distance>=0x101) +- Length++; +- LastDist=OldDist[OldDistPtr++ & 3]=Distance; +- DestUnpSize-=(LastLength=Length); +- while (Length--) +- { +- UnpBuf[UnpPtr]=UnpBuf[(UnpPtr-Distance) & MAXWINMASK]; +- UnpPtr=(UnpPtr+1) & MAXWINMASK; +- } +- continue; +- } +- if (Number<270) +- { +- Distance=SDDecode[Number-=261]+1; +- if ((Bits=SDBits[Number])>0) +- { +- GetBits(); +- Distance+=BitField>>(16-Bits); +- AddBits(Bits); +- } +- Length=2; +- LastDist=OldDist[OldDistPtr++ & 3]=Distance; +- DestUnpSize-=(LastLength=Length); +- while (Length--) +- { +- UnpBuf[UnpPtr]=UnpBuf[(UnpPtr-Distance) & MAXWINMASK]; +- UnpPtr=(UnpPtr+1) & MAXWINMASK; +- } +- continue; +- } +- } +- ReadLastTables(); +- +- if (FileFound) /* flush buffer */ +- { +- +- if (UnpPtr<WrPtr) +- { +- if((*temp_output_buffer_offset + ((0-WrPtr) & MAXWINMASK) + UnpPtr) > NewLhd.UnpSize) +- { +- debug_log("Fatal! Buffer overrun during decompression!"); +- DestUnpSize=-1; +- } else +- { +- /* copy extracted data to output buffer */ +- memcpy(temp_output_buffer + *temp_output_buffer_offset, &UnpBuf[WrPtr], +- (0-WrPtr) & MAXWINMASK); +- /* update offset within buffer */ +- *temp_output_buffer_offset+= (0-WrPtr) & MAXWINMASK; +- /* copy extracted data to output buffer */ +- memcpy(temp_output_buffer + *temp_output_buffer_offset, UnpBuf, UnpPtr); +- /* update offset within buffer */ +- *temp_output_buffer_offset+=UnpPtr; +- } +- } else +- { +- if((*temp_output_buffer_offset + (UnpPtr-WrPtr)) > NewLhd.UnpSize) +- { +- debug_log("Fatal! Buffer overrun during decompression!"); +- DestUnpSize=-1; +- } else +- { +- /* copy extracted data to output buffer */ +- memcpy(temp_output_buffer + *temp_output_buffer_offset, &UnpBuf[WrPtr], +- UnpPtr-WrPtr); +- /* update offset within buffer */ +- *temp_output_buffer_offset+=UnpPtr-WrPtr; +- } +- } +- } +- +- WrPtr=UnpPtr; +-} +- +- +-unsigned int UnpRead(unsigned char *Addr,unsigned int Count) +-{ +- int RetCode=0; +- unsigned int I,ReadSize,TotalRead=0; +- unsigned char *ReadAddr; +- ReadAddr=Addr; +- while (Count > 0) +- { +- ReadSize=(unsigned int)((Count>(unsigned long)UnpPackedSize) ? +- UnpPackedSize : Count); +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +- cli_dbgmsg("unrarlib: UnpREAD: Using memory->memory decompression\n"); +- if(MemRARFile->data == NULL) +- return(0); +- RetCode=tread(MemRARFile, ReadAddr, ReadSize); +-#else +- if (ArcPtr==NULL) +- return(0); +- RetCode=tread(ArcPtr,ReadAddr,ReadSize); +-#endif +- CurUnpRead+=RetCode; +- ReadAddr+=RetCode; +- TotalRead+=RetCode; +- Count-=RetCode; +- UnpPackedSize-=RetCode; +- break; +- } +- +- cli_dbgmsg("CurUnpRead == %d, TotalRead == %d, Count == %d, UnpPackedSize == %d\n", CurUnpRead, TotalRead, Count, UnpPackedSize); +- +- if (RetCode!= -1) +- { +- RetCode=TotalRead; +- if (Encryption) +- { +- if (Encryption<20) +- { +- cli_dbgmsg("unrarlib: Old Crypt() not supported!"); +- } +- else +- { +- for (I=0;I<(unsigned int)RetCode;I+=16) +- DecryptBlock(&Addr[I]); +- } +- } +- } +- return(RetCode); +-} +- +- +-void UnpReadBuf(int FirstBuf) +-{ +- int RetCode; +- if (FirstBuf) +- { +- ReadTop=UnpRead(InBuf,sizeof(InBuf)); +- InAddr=0; +- } +- else +- { +- memcpy(InBuf,&InBuf[sizeof(InBuf)-32],32); +- InAddr&=0x1f; +- RetCode=UnpRead(&InBuf[32],sizeof(InBuf)-32); +- if (RetCode>0) +- ReadTop=RetCode+32; +- else +- ReadTop=InAddr; +- } +-} +- +- +-void ReadTables(void) +-{ +- UBYTE BitLength[BC]; +- unsigned char Table[MC*4]; +- int TableSize,N,I; +- if (InAddr>sizeof(InBuf)-25) +- UnpReadBuf(0); +- GetBits(); +- UnpAudioBlock=(BitField & 0x8000); +- +- if (!(BitField & 0x4000)) +- memset(UnpOldTable,0,sizeof(UnpOldTable)); +- AddBits(2); +- +- +- if (UnpAudioBlock) +- { +- UnpChannels=((BitField>>12) & 3)+1; +- if (CurChannel>=UnpChannels) +- CurChannel=0; +- AddBits(2); +- TableSize=MC*UnpChannels; +- } +- else +- TableSize=NC+DC+RC; +- +- +- for (I=0;I<BC;I++) +- { +- GetBits(); +- BitLength[I]=(UBYTE)(BitField >> 12); +- AddBits(4); +- } +- MakeDecodeTables(BitLength,(struct Decode *)&BD,BC); +- I=0; +- while (I<TableSize) +- { +- if (InAddr>sizeof(InBuf)-5) +- UnpReadBuf(0); +- DecodeNumber((struct Decode *)&BD); +- if (Number<16) { +- Table[I]=(Number+UnpOldTable[I]) & 0xf; +- I++; +- } +- else +- if (Number==16) +- { +- GetBits(); +- N=(BitField >> 14)+3; +- AddBits(2); +- while (N-- > 0 && I<TableSize) +- { +- Table[I]=Table[I-1]; +- I++; +- } +- } +- else +- { +- if (Number==17) +- { +- GetBits(); +- N=(BitField >> 13)+3; +- AddBits(3); +- } +- else +- { +- GetBits(); +- N=(BitField >> 9)+11; +- AddBits(7); +- } +- while (N-- > 0 && I<TableSize) +- Table[I++]=0; +- } +- } +- if (UnpAudioBlock) +- for (I=0;I<UnpChannels;I++) +- MakeDecodeTables(&Table[I*MC],(struct Decode *)MDPtr[I],MC); +- else +- { +- MakeDecodeTables(&Table[0],(struct Decode *)&LD,NC); +- MakeDecodeTables(&Table[NC],(struct Decode *)&DD,DC); +- MakeDecodeTables(&Table[NC+DC],(struct Decode *)&RD,RC); +- } +- memcpy(UnpOldTable,Table,sizeof(UnpOldTable)); +-} +- +- +-static void ReadLastTables(void) +-{ +- if (ReadTop>=InAddr+5) +- { +- if (UnpAudioBlock) +- { +- DecodeNumber((struct Decode *)MDPtr[CurChannel]); +- if (Number==256) +- ReadTables(); +- } +- else +- { +- DecodeNumber((struct Decode *)&LD); +- if (Number==269) +- ReadTables(); +- } +- } +-} +- +- +-static void MakeDecodeTables(unsigned char *LenTab, +- struct Decode *Dec, +- int Size) +-{ +- int LenCount[16],TmpPos[16],I; +- long M,N; +- memset(LenCount,0,sizeof(LenCount)); +- for (I=0;I<Size;I++) +- LenCount[LenTab[I] & 0xF]++; +- +- LenCount[0]=0; +- for (TmpPos[0]=Dec->DecodePos[0]=Dec->DecodeLen[0]=0,N=0,I=1;I<16;I++) +- { +- N=2*(N+LenCount[I]); +- M=N<<(15-I); +- if (M>0xFFFF) +- M=0xFFFF; +- Dec->DecodeLen[I]=(unsigned int)M; +- TmpPos[I]=Dec->DecodePos[I]=Dec->DecodePos[I-1]+LenCount[I-1]; +- } +- +- for (I=0;I<Size;I++) +- if (LenTab[I]!=0) +- Dec->DecodeNum[TmpPos[LenTab[I] & 0xF]++]=I; +- Dec->MaxNum=Size; +-} +- +- +-static void DecodeNumber(struct Decode *Deco) +-/* *** 52.6% of all CPU time is spent within this function!!! */ +-{ +- unsigned int I; +- register unsigned int N; +- GetBits(); +- +-#ifdef _USE_ASM +- +-#ifdef _WIN_32 +- __asm { +- +- xor eax, eax +- mov eax, BitField /* N=BitField & 0xFFFE; */ +- and eax, 0xFFFFFFFE +- mov [N], eax +- mov edx, [Deco] /* EAX=N, EDX=Deco */ +- +- cmp eax, dword ptr[edx + 8*4 + 4] /* if (N<Dec->DecodeLen[8]) */ +- jae else_G +- +- cmp eax, dword ptr[edx + 4*4 + 4] /* if (N<Dec->DecodeLen[4]) */ +- jae else_F +- +- +- cmp eax, dword ptr[edx + 2*4 + 4] /* if (N<Dec->DecodeLen[2]) */ +- jae else_C +- +- cmp eax, dword ptr[edx + 1*4 + 4] /* if (N<Dec->DecodeLen[1]) */ +- jae else_1 +- mov I, 1 /* I=1; */ +- jmp next_1 +- else_1: /* else */ +- mov I, 2 /* I=2; */ +- next_1: +- +- jmp next_C +- else_C: /* else */ +- +- cmp eax, dword ptr[edx + 3*4 + 4] /* if (N<Dec->DecodeLen[3]) */ +- jae else_2 +- mov I, 3 /* I=3; */ +- jmp next_2 +- else_2: /* else */ +- mov I, 4 /* I=4; */ +- next_2: +- +- next_C: /* else */ +- +- jmp next_F +- else_F: +- +- +- cmp eax, dword ptr[edx + 6*4 + 4] /* if (N<Dec->DecodeLen[6]) */ +- jae else_E +- +- cmp eax, dword ptr[edx + 5*4 + 4] /* if (N<Dec->DecodeLen[5]) */ +- jae else_3 +- mov I, 5 /* I=5; */ +- jmp next_3 +- else_3: /* else */ +- mov I, 6 /* I=6; */ +- next_3: +- +- jmp next_E +- else_E: /* else */ +- +- cmp eax, dword ptr[edx + 7*4 + 4] /* if (N<Dec->DecodeLen[7]) */ +- jae else_4 +- mov I, 7 /* I=7; */ +- jmp next_4 +- else_4: /* else */ +- mov I, 8 /* I=8; */ +- next_4: +- +- next_E: +- +- next_F: +- +- jmp next_G +- else_G: +- +- cmp eax, dword ptr[edx + 12*4 + 4] /* if (N<Dec->DecodeLen[12]) */ +- jae else_D +- +- cmp eax, dword ptr[edx + 10*4 + 4] /* if (N<Dec->DecodeLen[10]) */ +- jae else_B +- +- cmp eax, dword ptr[edx + 9*4 + 4] /* if (N<Dec->DecodeLen[9]) */ +- jae else_5 +- mov I, 9 /* I=9; */ +- jmp next_5 +- else_5: /* else */ +- mov I, 10 /* I=10; */ +- next_5: +- +- jmp next_B +- else_B: /* else */ +- +- cmp eax, dword ptr[edx + 11*4 + 4] /* if (N<Dec->DecodeLen[11]) */ +- jae else_6 +- mov I, 11 /* I=11; */ +- jmp next_6 +- else_6: /* else */ +- mov I, 12 /* I=12; */ +- next_6: +- +- next_B: +- +- +- jmp next_D +- else_D: /* else */ +- +- cmp eax, dword ptr[edx + 14*4 + 4] /* if (N<Dec->DecodeLen[14]) */ +- jae else_A +- +- cmp eax, dword ptr[edx + 13*4 + 4] /* if (N<Dec->DecodeLen[13]) */ +- jae else_7 +- mov I, 13 /* I=13; */ +- jmp next_7 +- else_7: /* else */ +- mov I, 14 /* I=14; */ +- next_7: +- +- jmp next_A +- else_A: /* else */ +- mov I, 15 /* I=15; */ +- next_A: +- +- next_D: +- next_G: +-} +-#else +- __asm__ __volatile__ ( +- "andl $0xFFFFFFFE, %%eax" +-" movl %%eax, %1" +-" cmpl 8*4(%%edx), %%eax /* 5379 */" +-" jae else_G" +-"" +-" cmpl 4*4(%%edx), %%eax" +-" jae else_F" +-"" +-" cmpl 2*4(%%edx), %%eax" +-" jae else_C" +-"" +-" cmpl 1*4(%%edx), %%eax" +-"" +-" jae else_1" +-" movl $1, %0" +-" jmp next_1" +-" else_1: " +-" movl $2, %0" +-" next_1:" +-" " +-" jmp next_C" +-" else_C: " +-"" +-" cmpl 3*4(%%edx), %%eax " +-" jae else_2" +-" movl $3, %0" +-" jmp next_2" +-" else_2: " +-" movl $4, %0" +-" next_2:" +-"" +-" next_C: " +-"" +-" jmp next_F" +-" else_F:" +-"" +-" cmpl 6*4(%%edx), %%eax" +-" jae else_E" +-"" +-" cmpl 5*4(%%edx), %%eax" +-" jae else_3" +-" movl $5, %0 " +-" jmp next_3" +-" else_3: " +-" movl $6, %0 " +-" next_3:" +-"" +-" jmp next_E" +-" else_E: " +-"" +-" cmpl 7*4(%%edx), %%eax" +-" jae else_4" +-" movl $7, %0 " +-" jmp next_4" +-" else_4: " +-" movl $8, %0 " +-" next_4:" +-"" +-" next_E:" +-"" +-" next_F:" +-"" +-" jmp next_G" +-" else_G:" +-"" +-" cmpl 12*4(%%edx), %%eax" +-" jae else_D" +-"" +-" cmpl 10*4(%%edx), %%eax" +-" jae else_B" +-"" +-" cmpl 9*4(%%edx), %%eax" +-" jae else_5" +-" movl $9, %0 " +-" jmp next_5" +-" else_5: " +-" movl $10, %0 " +-" next_5:" +-"" +-" jmp next_B" +-" else_B: " +-"" +-" cmpl 11*4(%%edx), %%eax" +-" " +-" jae else_6" +-" movl $11, %0 " +-" jmp next_6" +-" else_6: " +-" movl $12, %0 " +-" next_6:" +-"" +-" next_B:" +-" " +-" " +-" jmp next_D" +-" else_D: " +-"" +-" cmpl 14*4(%%edx), %%eax" +-" jae else_A" +-"" +-" cmpl 13*4(%%edx), %%eax" +-" jae else_7" +-" movl $13, %0" +-" jmp next_7" +-" else_7: " +-" movl $14, %0" +-" next_7:" +-"" +-" jmp next_A" +-" else_A: " +-" movl $15, %0 " +-" next_A:" +-" " +-" next_D: " +-" next_G:" +- : "=g" (I), "=r"(N) +- : "eax" ((long)BitField), "edx"((long)Deco->DecodeLen) +- : "memory" +- ); +-#endif /* #ifdef _WIN_32 ... #elif defined _X86_ASM_ */ +- +-#else +- N=BitField & 0xFFFE; +- if (N<Deco->DecodeLen[8]) { +- if (N<Deco->DecodeLen[4]) { +- if (N<Deco->DecodeLen[2]) { +- if (N<Deco->DecodeLen[1]) +- I=1; +- else +- I=2; +- } else { +- if (N<Deco->DecodeLen[3]) +- I=3; +- else +- I=4; +- } +- } else { +- if (N<Deco->DecodeLen[6]) { +- if (N<Deco->DecodeLen[5]) +- I=5; +- else +- I=6; +- } else { +- if (N<Deco->DecodeLen[7]) +- I=7; +- else +- I=8; +- } +- } +- } else { +- if (N<Deco->DecodeLen[12]) { +- if (N<Deco->DecodeLen[10]) { +- if (N<Deco->DecodeLen[9]) +- I=9; +- else +- I=10; +- } else { +- if (N<Deco->DecodeLen[11]) +- I=11; +- else +- I=12; +- } +- } else { +- if (N<Deco->DecodeLen[14]) { +- if (N<Deco->DecodeLen[13]) +- I=13; +- else +- I=14; +- +- } else { +- I=15; +- } +- } +- +- } +-#endif +- +- AddBits(I); +- if ((N=Deco->DecodePos[I]+((N-Deco->DecodeLen[I-1])>>(16-I)))>=Deco->MaxNum) +- N=0; +- Number=Deco->DecodeNum[N]; +-} +- +- +-void UnpInitData() +-{ +- InAddr=InBit=0; +- if (!(NewLhd.Flags & LHD_SOLID)) +- { +- ChannelDelta=CurChannel=0; +- +-#ifdef _USE_ASM +- +-#ifdef _WIN_32 /* Win32 with VisualC */ +- +- __asm { +- push edi +- push eax +- push ecx +- +- cld /* increment EDI and ESI */ +- mov al, 0x00 +- mov ecx, SIZE AudV +- mov edi, Offset AudV +- rep stosb /* clear memory */ +- +- mov ecx, SIZE OldDist +- mov edi, Offset OldDist +- rep stosb /* clear memory */ +- +- mov ecx, SIZE UnpOldTable +- mov edi, Offset UnpOldTable +- rep stosb /* clear memory */ +- +- pop ecx +- pop eax +- pop edi +- +- +- mov [OldDistPtr], 0 +- mov [LastDist], 0 +- mov [LastLength], 0 +- mov [UnpPtr], 0 +- mov [WrPtr], 0 +- mov [OldDistPtr], 0 +- mov [LastLength], 0 +- mov [LastDist], 0 +- mov [UnpPtr], 0 +- mov [WrPtr], 0 +- +- } +- memset(UnpBuf,0,MAXWINSIZE); +- +- +-#else /* unix/linux on i386 cpus */ +- __asm__ __volatile ( +-" cld /* increment EDI and ESI */" +-" movb $0x00, %%al" +-" movl %0, %%ecx" +-" movl %1, %%edi" +-" rep " +-" stosb /* clear memory */" +-"" +-" movl %2, %%ecx" +-" mov %3, %%edi" +-" rep " +-" stosb /* clear memory */" +-"" +-" movl %4, %%ecx" +-" movl %5, %%edi" +-" rep " +-" stosb /* clear memory */" +-"" +-" movl $0, (OldDistPtr)" +-" movl $0, (LastDist)" +-" movl $0, (LastLength)" +-" movl $0, (UnpPtr)" +-" movl $0, (WrPtr)" +-" movl $0, (OldDistPtr)" +-" movl $0, (LastLength)" +-" movl $0, (LastDist)" +-" movl $0, (UnpPtr)" +-" movl $0, (WrPtr)" +- : +- : "m" ((long)sizeof(AudV)), +- "m" ((long)AudV), +- "m" ((long)sizeof(OldDist)), +- "m" ((long)OldDist), +- "m" ((long)sizeof(UnpOldTable)), +- "m" ((long)UnpOldTable) +- : "memory", "edi", "eax", "ecx" +- ); +- memset(UnpBuf,0,MAXWINSIZE); +-#endif +- +-#else /* unix/linux on non-i386 cpu */ +- memset(AudV,0,sizeof(AudV)); +- memset(OldDist,0,sizeof(OldDist)); +- OldDistPtr=0; +- LastDist=LastLength=0; +- memset(UnpBuf,0,MAXWINSIZE); +- memset(UnpOldTable,0,sizeof(UnpOldTable)); +- UnpPtr=WrPtr=0; +-#endif +- +- } +-} +- +- +-UBYTE DecodeAudio(int Delta) +-{ +- struct AudioVariables *V; +- unsigned int Ch; +- unsigned int NumMinDif,MinDif; +- int PCh,I; +- +- V=&AudV[CurChannel]; +- V->ByteCount++; +- V->D4=V->D3; +- V->D3=V->D2; +- V->D2=V->LastDelta-V->D1; +- V->D1=V->LastDelta; +- PCh=8*V->LastChar+V->K1*V->D1+V->K2*V->D2+ +- V->K3*V->D3+V->K4*V->D4+V->K5*ChannelDelta; +- PCh=(PCh>>3) & 0xFF; +- +- Ch=PCh-Delta; +- +- I=((signed char)Delta)<<3; +- +- V->Dif[0]+=abs(I); +- V->Dif[1]+=abs(I-V->D1); +- V->Dif[2]+=abs(I+V->D1); +- V->Dif[3]+=abs(I-V->D2); +- V->Dif[4]+=abs(I+V->D2); +- V->Dif[5]+=abs(I-V->D3); +- V->Dif[6]+=abs(I+V->D3); +- V->Dif[7]+=abs(I-V->D4); +- V->Dif[8]+=abs(I+V->D4); +- V->Dif[9]+=abs(I-ChannelDelta); +- V->Dif[10]+=abs(I+ChannelDelta); +- +- ChannelDelta=V->LastDelta=(signed char)(Ch-V->LastChar); +- V->LastChar=Ch; +- +- if ((V->ByteCount & 0x1F)==0) +- { +- MinDif=V->Dif[0]; +- NumMinDif=0; +- V->Dif[0]=0; +- for (I=1;(unsigned int)I<sizeof(V->Dif)/sizeof(V->Dif[0]);I++) +- { +- if (V->Dif[I]<MinDif) +- { +- MinDif=V->Dif[I]; +- NumMinDif=I; +- } +- V->Dif[I]=0; +- } +- switch(NumMinDif) +- { +- case 1: +- if (V->K1>=-16) +- V->K1--; +- break; +- case 2: +- if (V->K1<16) +- V->K1++; +- break; +- case 3: +- if (V->K2>=-16) +- V->K2--; +- break; +- case 4: +- if (V->K2<16) +- V->K2++; +- break; +- case 5: +- if (V->K3>=-16) +- V->K3--; +- break; +- case 6: +- if (V->K3<16) +- V->K3++; +- break; +- case 7: +- if (V->K4>=-16) +- V->K4--; +- break; +- case 8: +- if (V->K4<16) +- V->K4++; +- break; +- case 9: +- if (V->K5>=-16) +- V->K5--; +- break; +- case 10: +- if (V->K5<16) +- V->K5++; +- break; +- } +- } +- return((UBYTE)Ch); +-} +- +- +- +- +- +- +- +-/* *************************************************** +- * ** CRCCrypt Code - decryption engine starts here ** +- * ***************************************************/ +- +- +-#define NROUNDS 32 +- +-#define rol(x,n) (((x)<<(n)) | ((x)>>(8*sizeof(x)-(n)))) +-#define ror(x,n) (((x)>>(n)) | ((x)<<(8*sizeof(x)-(n)))) +- +-#define substLong(t) ( (UDWORD)SubstTable[(int)t&255] | \ +- ((UDWORD)SubstTable[(int)(t>> 8)&255]<< 8) | \ +- ((UDWORD)SubstTable[(int)(t>>16)&255]<<16) | \ +- ((UDWORD)SubstTable[(int)(t>>24)&255]<<24) ) +- +- +-static UDWORD CRCTab[256]; +- +-static UBYTE SubstTable[256]; +-static const UBYTE InitSubstTable[256]={ +- 215, 19,149, 35, 73,197,192,205,249, 28, 16,119, 48,221, 2, 42, +- 232, 1,177,233, 14, 88,219, 25,223,195,244, 90, 87,239,153,137, +- 255,199,147, 70, 92, 66,246, 13,216, 40, 62, 29,217,230, 86, 6, +- 71, 24,171,196,101,113,218,123, 93, 91,163,178,202, 67, 44,235, +- 107,250, 75,234, 49,167,125,211, 83,114,157,144, 32,193,143, 36, +- 158,124,247,187, 89,214,141, 47,121,228, 61,130,213,194,174,251, +- 97,110, 54,229,115, 57,152, 94,105,243,212, 55,209,245, 63, 11, +- 164,200, 31,156, 81,176,227, 21, 76, 99,139,188,127, 17,248, 51, +- 207,120,189,210, 8,226, 41, 72,183,203,135,165,166, 60, 98, 7, +- 122, 38,155,170, 69,172,252,238, 39,134, 59,128,236, 27,240, 80, +- 131, 3, 85,206,145, 79,154,142,159,220,201,133, 74, 64, 20,129, +- 224,185,138,103,173,182, 43, 34,254, 82,198,151,231,180, 58, 10, +- 118, 26,102, 12, 50,132, 22,191,136,111,162,179, 45, 4,148,108, +- 161, 56, 78,126,242,222, 15,175,146, 23, 33,241,181,190, 77,225, +- 0, 46,169,186, 68, 95,237, 65, 53,208,253,168, 9, 18,100, 52, +- 116,184,160, 96,109, 37, 30,106,140,104,150, 5,204,117,112, 84 +-}; +- +-static UDWORD Key[4]; +- +- +-static void EncryptBlock(UBYTE *Buf) +-{ +- int I; +- +- UDWORD A,B,C,D,T,TA,TB; +-#ifdef NON_INTEL_BYTE_ORDER +- A=((UDWORD)Buf[0]|((UDWORD)Buf[1]<<8)|((UDWORD)Buf[2]<<16)| +- ((UDWORD)Buf[3]<<24))^Key[0]; +- B=((UDWORD)Buf[4]|((UDWORD)Buf[5]<<8)|((UDWORD)Buf[6]<<16)| +- ((UDWORD)Buf[7]<<24))^Key[1]; +- C=((UDWORD)Buf[8]|((UDWORD)Buf[9]<<8)|((UDWORD)Buf[10]<<16)| +- ((UDWORD)Buf[11]<<24))^Key[2]; +- D=((UDWORD)Buf[12]|((UDWORD)Buf[13]<<8)|((UDWORD)Buf[14]<<16)| +- ((UDWORD)Buf[15]<<24))^Key[3]; +-#else +- UDWORD *BufPtr; +- BufPtr=(UDWORD *)Buf; +- A=BufPtr[0]^Key[0]; +- B=BufPtr[1]^Key[1]; +- C=BufPtr[2]^Key[2]; +- D=BufPtr[3]^Key[3]; +-#endif +- for(I=0;I<NROUNDS;I++) +- { +- T=((C+rol(D,11))^Key[I&3]); +- TA=A^substLong(T); +- T=((D^rol(C,17))+Key[I&3]); +- TB=B^substLong(T); +- A=C; +- B=D; +- C=TA; +- D=TB; +- } +-#ifdef NON_INTEL_BYTE_ORDER +- C^=Key[0]; +- Buf[0]=(UBYTE)C; +- Buf[1]=(UBYTE)(C>>8); +- Buf[2]=(UBYTE)(C>>16); +- Buf[3]=(UBYTE)(C>>24); +- D^=Key[1]; +- Buf[4]=(UBYTE)D; +- Buf[5]=(UBYTE)(D>>8); +- Buf[6]=(UBYTE)(D>>16); +- Buf[7]=(UBYTE)(D>>24); +- A^=Key[2]; +- Buf[8]=(UBYTE)A; +- Buf[9]=(UBYTE)(A>>8); +- Buf[10]=(UBYTE)(A>>16); +- Buf[11]=(UBYTE)(A>>24); +- B^=Key[3]; +- Buf[12]=(UBYTE)B; +- Buf[13]=(UBYTE)(B>>8); +- Buf[14]=(UBYTE)(B>>16); +- Buf[15]=(UBYTE)(B>>24); +-#else +- BufPtr[0]=C^Key[0]; +- BufPtr[1]=D^Key[1]; +- BufPtr[2]=A^Key[2]; +- BufPtr[3]=B^Key[3]; +-#endif +- UpdKeys(Buf); +-} +- +- +-void DecryptBlock(UBYTE *Buf) +-{ +- int I; +- UBYTE InBuf[16]; +- UDWORD A,B,C,D,T,TA,TB; +-#ifdef NON_INTEL_BYTE_ORDER +- A=((UDWORD)Buf[0]|((UDWORD)Buf[1]<<8)|((UDWORD)Buf[2]<<16)| +- ((UDWORD)Buf[3]<<24))^Key[0]; +- B=((UDWORD)Buf[4]|((UDWORD)Buf[5]<<8)|((UDWORD)Buf[6]<<16)| +- ((UDWORD)Buf[7]<<24))^Key[1]; +- C=((UDWORD)Buf[8]|((UDWORD)Buf[9]<<8)|((UDWORD)Buf[10]<<16)| +- ((UDWORD)Buf[11]<<24))^Key[2]; +- D=((UDWORD)Buf[12]|((UDWORD)Buf[13]<<8)|((UDWORD)Buf[14]<<16)| +- ((UDWORD)Buf[15]<<24))^Key[3]; +-#else +- UDWORD *BufPtr; +- BufPtr=(UDWORD *)Buf; +- A=BufPtr[0]^Key[0]; /* xxx may be this can be */ +- B=BufPtr[1]^Key[1]; /* optimized in assembler */ +- C=BufPtr[2]^Key[2]; +- D=BufPtr[3]^Key[3]; +-#endif +- memcpy(InBuf,Buf,sizeof(InBuf)); +- for(I=NROUNDS-1;I>=0;I--) +- { +- T=((C+rol(D,11))^Key[I&3]); +- TA=A^substLong(T); +- T=((D^rol(C,17))+Key[I&3]); +- TB=B^substLong(T); +- A=C; +- B=D; +- C=TA; +- D=TB; +- } +-#ifdef NON_INTEL_BYTE_ORDER +- C^=Key[0]; +- Buf[0]=(UBYTE)C; +- Buf[1]=(UBYTE)(C>>8); +- Buf[2]=(UBYTE)(C>>16); +- Buf[3]=(UBYTE)(C>>24); +- D^=Key[1]; +- Buf[4]=(UBYTE)D; +- Buf[5]=(UBYTE)(D>>8); +- Buf[6]=(UBYTE)(D>>16); +- Buf[7]=(UBYTE)(D>>24); +- A^=Key[2]; +- Buf[8]=(UBYTE)A; +- Buf[9]=(UBYTE)(A>>8); +- Buf[10]=(UBYTE)(A>>16); +- Buf[11]=(UBYTE)(A>>24); +- B^=Key[3]; +- Buf[12]=(UBYTE)B; +- Buf[13]=(UBYTE)(B>>8); +- Buf[14]=(UBYTE)(B>>16); +- Buf[15]=(UBYTE)(B>>24); +-#else +- BufPtr[0]=C^Key[0]; +- BufPtr[1]=D^Key[1]; +- BufPtr[2]=A^Key[2]; +- BufPtr[3]=B^Key[3]; +-#endif +- UpdKeys(InBuf); +-} +- +- +-void UpdKeys(UBYTE *Buf) +-{ +- int I; +- for (I=0;I<16;I+=4) +- { +- Key[0]^=CRCTab[Buf[I]]; /* xxx may be I'll rewrite this */ +- Key[1]^=CRCTab[Buf[I+1]]; /* in asm for speedup */ +- Key[2]^=CRCTab[Buf[I+2]]; +- Key[3]^=CRCTab[Buf[I+3]]; +- } +-} +- +-static void SetCryptKeys(char *NewPassword) +-{ +- unsigned int I,J,K,PswLength; +- unsigned char N1,N2; +- unsigned char Psw[256]; +- +-#if !defined _USE_ASM +- UBYTE Ch; +-#endif +- +- SetOldKeys(NewPassword); +- +- Key[0]=0xD3A3B879L; +- Key[1]=0x3F6D12F7L; +- Key[2]=0x7515A235L; +- Key[3]=0xA4E7F123L; +- memset(Psw,0,sizeof(Psw)); +- strcpy((char *)Psw,NewPassword); +- PswLength=strlen(NewPassword); +- memcpy(SubstTable,InitSubstTable,sizeof(SubstTable)); +- +- for (J=0;J<256;J++) +- for (I=0;I<PswLength;I+=2) +- { +- N2=(unsigned char)CRCTab[(Psw[I+1]+J)&0xFF]; +- for (K=1, N1=(unsigned char)CRCTab[(Psw[I]-J)&0xFF]; +- (N1!=N2); +- N1++, K++) +- { +-#ifdef _USE_ASM +- +-#ifdef _WIN_32 +- __asm { +- +- mov ebx, Offset SubstTable +- mov edx, ebx +- +- xor ecx, ecx /* read SubstTable[N1]... */ +- mov cl, N1 +- add ebx, ecx +- mov al, byte ptr[ebx] +- +- mov cl, N1 /* read SubstTable[(N1+I+K)&0xFF]... */ +- add ecx, I +- add ecx, K +- and ecx, 0xFF +- add edx, ecx +- mov ah, byte ptr[edx] +- +- mov byte ptr[ebx], ah /* and write back */ +- mov byte ptr[edx], al +- +- } +-#else +- __asm__ __volatile__ ( +-" xorl %%ecx, %%ecx" +-" movl %2, %%ecx /* ecx = N1 */" +-" mov %%ebx, %%edx" +-" addl %%ecx, %%ebx" +-"" +-" addl %0, %%ecx" +-" addl %1, %%ecx" +-" andl $0x000000FF, %%ecx" +-" addl %%ecx, %%edx" +-" " +-" movb (%%ebx), %%al" +-" movb (%%edx), %%ah" +-"" +-" movb %%ah, (%%ebx) /* and write back */" +-" movb %%al, (%%edx)" +- : : "g" ((long)I), +- "g" ((long)K), +- "g" ((long)N1), +- "ebx"((long)SubstTable) +- : "ecx", "edx" +- +- ); +-#endif +- +-#else +- /* Swap(&SubstTable[N1],&SubstTable[(N1+I+K)&0xFF]); */ +- Ch=SubstTable[N1]; +- SubstTable[N1]=SubstTable[(N1+I+K)&0xFF]; +- SubstTable[(N1+I+K)&0xFF]=Ch; +-#endif +- } +- } +- for (I=0;I<PswLength;I+=16) +- EncryptBlock(&Psw[I]); +-} +- +- +-void SetOldKeys(char *NewPassword) +-{ +- UDWORD PswCRC; +- UBYTE Ch; +- PswCRC=CalcCRC32(0xFFFFFFFFL,(UBYTE*)NewPassword,strlen(NewPassword)); +- OldKey[0]=(UWORD)PswCRC; +- OldKey[1]=(UWORD)(PswCRC>>16); +- OldKey[2]=OldKey[3]=0; +- PN1=PN2=PN3=0; +- while ((Ch=*NewPassword)!=0) +- { +- PN1+=Ch; +- PN2^=Ch; +- PN3+=Ch; +- PN3=(UBYTE)rol(PN3,1); +- OldKey[2]^=((UWORD)(Ch^CRCTab[Ch])); +- OldKey[3]+=((UWORD)(Ch+(CRCTab[Ch]>>16))); +- NewPassword++; +- } +-} +- +-static short crcInitialized = 0; +-void InitCRC(void) +-{ +- int I, J; +- UDWORD C; +- if (crcInitialized) return; +- +- cli_dbgmsg("%s:%d:%s Initialize CRC table\n", __FILE__, __LINE__, "InitCRC"); +- for (I=0;I<256;I++) +- { +- for (C=I,J=0;J<8;J++) +- C=(C & 1) ? (C>>1)^0xEDB88320L : (C>>1); +- CRCTab[I]=C; +- } +- crcInitialized = 1; +-} +- +- +-static UDWORD CalcCRC32(UDWORD StartCRC,UBYTE *Addr,UDWORD Size) +-{ +- unsigned int I; +- for (I=0; I<Size; I++) +- StartCRC = CRCTab[(UBYTE)StartCRC ^ Addr[I]] ^ (StartCRC >> 8); +- return(StartCRC); +-} +- +- +-/* ************************************************************************** +- **************************************************************************** +- **************************************************************************** +- ************************************************************************** */ +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-/* ************************************************************************** +- **************************************************************************** +- **************************************************************************** +- **************************************************************************** +- ******* ******* +- ******* ******* +- ******* ******* +- ******* D E B U G F U N C T I O N S ******* +- ******* ******* +- ******* ******* +- ******* ******* +- **************************************************************************** +- **************************************************************************** +- **************************************************************************** +- ************************************************************************** */ +-#ifdef _DEBUG_LOG +- +- +-/* -- global stuff -------------------------------------------------------- */ +-char log_file_name[256]; /* file name for the log file */ +-DWORD debug_start_time; /* starttime of debug */ +-BOOL debug_started = FALSE; /* debug_log writes only if */ +- /* this is TRUE */ +-/* ------------------------------------------------------------------------ */ +- +- +-/* -- global functions ---------------------------------------------------- */ +-void debug_init_proc(char *file_name) +-/* Create/Rewrite a log file */ +-{ +- FILE *fp; +- char date[] = __DATE__; +- char time[] = __TIME__; +- +- debug_start_time = GetTickCount(); /* get start time */ +- strcpy(log_file_name, file_name); /* save file name */ +- +- if((fp = fopen(log_file_name, CREATETEXT)) != NULL) +- { +- debug_started = TRUE; /* enable debug */ +- fprintf(fp, "Debug log of UniquE's RARFileLib\n"\ +- "~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~\n"); +- fprintf(fp, "(executable compiled on %s at %s)\n\n", date, time); +- fclose(fp); +- } +-} +- +- +-void debug_log_proc(char *text, char *sourcefile, int sourceline) +-/* add a line to the log file */ +-{ +- FILE *fp; +- +- if(debug_started == FALSE) return; /* exit if not initialized */ +- +- if((fp = fopen(log_file_name, APPENDTEXT)) != NULL) /* append to logfile */ +- +- { +- fprintf(fp, " %8u ms (line %u in %s):\n - %s\n", +- (unsigned int)(GetTickCount() - debug_start_time), +- sourceline, sourcefile, text); +- fclose(fp); +- } +-} +- +-/* ------------------------------------------------------------------------ */ +-#endif +-/* ************************************************************************** +- **************************************************************************** +- **************************************************************************** +- ************************************************************************** */ +- +- +-/* end of file urarlib.c */ +diff -ruN clamav-0.84.orig/libclamav/unrarlib.h clamav-0.84/libclamav/unrarlib.h +--- clamav-0.84.orig/libclamav/unrarlib.h 2005-04-20 03:33:17.000000000 +0400 ++++ clamav-0.84/libclamav/unrarlib.h 2005-05-04 02:12:02.551691792 +0400 +@@ -1,205 +1,22 @@ +-/* *************************************************************************** +- ** +- ** This file is part of the UniquE RAR File Library. +- ** +- ** Copyright (C) 2000-2002 by Christian Scheurer (www.ChristianScheurer.ch) +- ** UNIX port copyright (c) 2000-2002 by Johannes Winkelmann (jw@tks6.net) +- ** +- ** The contents of this file are subject to the UniquE RAR File Library +- ** License (the "unrarlib-license.txt"). You may not use this file except +- ** in compliance with the License. You may obtain a copy of the License +- ** at http://www.unrarlib.org/license.html. +- ** Software distributed under the License is distributed on an "AS IS" +- ** basis, WITHOUT WARRANTY OF ANY KIND, either express or implied warranty. +- ** +- ** Alternatively, the contents of this file may be used under the terms +- ** of the GNU General Public License Version 2 or later (the "GPL"), in +- ** which case the provisions of the GPL are applicable instead of those +- ** above. If you wish to allow use of your version of this file only +- ** under the terms of the GPL and not to allow others to use your version +- ** of this file under the terms of the UniquE RAR File Library License, +- ** indicate your decision by deleting the provisions above and replace +- ** them with the notice and other provisions required by the GPL. If you +- ** do not delete the provisions above, a recipient may use your version +- ** of this file under the terms of the GPL or the UniquE RAR File Library +- ** License. +- ** +- ************************************************************************** */ +- +-/* include file for the "UniquE RAR File Library" */ +-/* (C) 2000-2002 by Christian Scheurer aka. UniquE */ +-/* multi-OS version (Win32, Linux and SUN) */ +- +-#ifndef __URARLIB_H +-#define __URARLIB_H +- +-#ifdef __cplusplus +-extern "C" +-{ +-#endif +- +- +-/* ************************************************************************ */ +-/* ************************************************************************ */ +-/* ** ** */ +-/* ** CONFIGURATION of the UniquE RAR FileLib ** */ +-/* ** ==> you may change the setting for the lib HERE! ** */ +-/* ** ** */ +-/* ************************************************************************ */ +-/* ************************************************************************ */ +- +- +-/* #define _DEBUG_LOG */ /* generate debug messages */ +- +-#define _DO_CRC32_CHECK /* perform cyclical redundancy */ +- /* check (CRC32) - disable this */ +- /* for a little speed-up */ +-/*#define _USE_ASM*/ /* +- * enable assembly extensions +- * x86 cpus. +- */ +- +-/*#define _USE_MEMORY_TO_MEMORY_DECOMPRESSION*/ /* read file from memory or a */ +- /* resource instead of reading */ +- /* from a file. NOTE: you wont't*/ +- /* be able to decompress from */ +- /* file if you enable this */ +- /* option! */ +- +- +-#ifdef WIN32 /* autodetect Win32 and Linux */ +-#define _WIN_32 /* Win32 with VisualC */ +-#define _DEBUG_LOG_FILE "C:\\temp\\debug_unrar.txt" /* log file path */ +-#else +-#define _UNIX /* Linux or Unix with GCC */ +-#define _DEBUG_LOG_FILE "/tmp/debug_unrar.txt" /* log file path */ +-/*#define NON_INTEL_BYTE_ORDER*/ /* GCC on motorola systems */ +- +-#endif +- +-/* ------------------------------------------------------------------------ */ +- +-/* detected by clamav/configure */ +-#if 1 - WORDS_BIGENDIAN +-#define NON_INTEL_BYTE_ORDER +-#endif +- +-/* -- global type definitions --------------------------------------------- */ +- +-#ifdef NON_INTEL_BYTE_ORDER +-#ifdef _USE_ASM +-#warning Disabling assembly because NON_INTEL_BYTE_ORDER is set +-#undef _USE_ASM +-#endif +-#endif +- +-#ifdef _WIN_32 +-typedef unsigned char UBYTE; /* WIN32 definitions */ +-typedef unsigned short UWORD; +-typedef unsigned long UDWORD; +-#endif +- +-#ifdef _UNIX /* LINUX/UNIX definitions */ +-typedef unsigned char UBYTE; +-typedef unsigned short UWORD; +-typedef unsigned long UDWORD; +-#endif +- +-#define RAR_FENTRY_ATTR_DIRECTORY ( 0x10 | 0x4000 ) +- +-/* This structure is used for listing archive content */ +-struct RAR20_archive_entry /* These infos about files are */ +-{ /* stored in RAR v2.0 archives */ +- char *Name; +- UWORD NameSize; +- UDWORD PackSize; +- UDWORD UnpSize; +- UBYTE HostOS; /* MSDOS=0,OS2=1,WIN32=2,UNIX=3 */ +- UDWORD FileCRC; +- UDWORD FileTime; +- UBYTE UnpVer; +- UBYTE Method; +- UDWORD FileAttr; +- UWORD Flags; +-}; +- +-typedef struct archivelist /* used to list archives */ +-{ +- struct RAR20_archive_entry item; +- struct archivelist *next; +-} ArchiveList_struct; +- +- +-#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION +-typedef struct memory_file /* used to decompress files in */ +-{ /* memory */ +- void *data; /* pointer to the file data */ +- unsigned long size; /* total size of the file data */ +- unsigned long offset; /* offset within "memory-file" */ +-} MemoryFile; +-#endif +- +-/* -- global functions ---------------------------------------------------- */ +- +-/* urarlib_get: +- * decompresses and decrypt data from a RAR file to a buffer in system memory. ++/* ++ * Copyright (C) 2004 McMCC <mcmcc@mail.ru> + * +- * input: *output pointer to an empty char*. This pointer will show +- * to the extracted data +- * *size shows where to write the size of the decompressed +- * file +- * (**NOTE: URARLib _does_ memory allocation etc.!**) +- * *filename pointer to string containing the file to decompress +- * *rarfile pointer to a string with the full name and path of +- * the RAR file or pointer to a RAR file in memory if +- * memory-to-memory decompression is active. +- * *libpassword pointer to a string with the password used to +- * en-/decrypt the RAR +- * output: int returns TRUE on success or FALSE on error +- * (FALSE=0, TRUE=1) +- */ +- +-extern int urarlib_get(void *output, +- unsigned long *size, +- char *filename, +- int desc, +- char *libpassword); +- +- +- +-/* urarlib_list: +- * list the content of a RAR archive. ++ * Support check archives RAR v.3.x + * +- * input: *rarfile pointer to a string with the full name and path of +- * the RAR file or pointer to a RAR file in memory if +- * memory-to-memory decompression is active. +- * *list pointer to an ArchiveList_struct that can be +- * filled with details about the archive +- * to the extracted data +- * output: int number of files/directories within archive +- */ +- +-extern int urarlib_list(int desc, ArchiveList_struct *list); +- +- +-/* urarlib_freelist: +- * (after the suggestion and code of Duy Nguyen, Sean O'Blarney +- * and Johannes Winkelmann who independently wrote a patch) +- * free the memory of a ArchiveList_struct created by urarlib_list. ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * +- * input: *list pointer to an ArchiveList_struct +- * output: - + */ + +-extern void urarlib_freelist(ArchiveList_struct *list); +- +-/* ------------------------------------------------------------------------ */ +- +- +- +-#ifdef __cplusplus +-} +-#endif +- +-#endif +- ++int cli_unrar3(const char *dir, int desc); |