diff -ruN clamav-0.86.2/Makefile.in clamav-0.86.2.p1/Makefile.in
--- clamav-0.86.2/Makefile.in	Fri Jun 24 00:03:07 2005
+++ clamav-0.86.2.p1/Makefile.in	Wed Aug 10 07:24:57 2005
@@ -130,7 +130,7 @@
 CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
 CLAMD_LIBS = @CLAMD_LIBS@
 CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
+CPPFLAGS = @CPPFLAGS@ -O2 -DUNRAR3
 CYGPATH_W = @CYGPATH_W@
 DBDIR = @DBDIR@
 DEFS = @DEFS@
@@ -149,7 +149,7 @@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
+LDFLAGS = @LDFLAGS@ -lunrar3
 LIBCLAMAV_LIBS = @LIBCLAMAV_LIBS@
 LIBCLAMAV_VERSION = @LIBCLAMAV_VERSION@
 LIBOBJS = @LIBOBJS@
diff -ruN clamav-0.86.2/clamd/Makefile.in clamav-0.86.2.p1/clamd/Makefile.in
--- clamav-0.86.2/clamd/Makefile.in	Fri Jun 24 00:03:05 2005
+++ clamav-0.86.2.p1/clamd/Makefile.in	Wed Aug 10 07:20:36 2005
@@ -123,7 +123,7 @@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFGDIR = @CFGDIR@
-CFLAGS = @CFLAGS@
+CFLAGS = @CFLAGS@ -O2 -DUNRAR3
 CLAMAVGROUP = @CLAMAVGROUP@
 CLAMAVUSER = @CLAMAVUSER@
 CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
@@ -148,7 +148,7 @@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
+LDFLAGS = @LDFLAGS@ -lunrar3
 LIBCLAMAV_LIBS = @LIBCLAMAV_LIBS@
 LIBCLAMAV_VERSION = @LIBCLAMAV_VERSION@
 LIBOBJS = @LIBOBJS@
diff -ruN clamav-0.86.2/clamdscan/Makefile.in clamav-0.86.2.p1/clamdscan/Makefile.in
--- clamav-0.86.2/clamdscan/Makefile.in	Fri Jun 24 00:03:08 2005
+++ clamav-0.86.2.p1/clamdscan/Makefile.in	Wed Aug 10 07:21:13 2005
@@ -114,7 +114,7 @@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFGDIR = @CFGDIR@
-CFLAGS = @CFLAGS@
+CFLAGS = @CFLAGS@ -O2 -DUNRAR3
 CLAMAVGROUP = @CLAMAVGROUP@
 CLAMAVUSER = @CLAMAVUSER@
 CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
@@ -139,7 +139,7 @@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
+LDFLAGS = @LDFLAGS@ -lunrar3
 LIBCLAMAV_LIBS = @LIBCLAMAV_LIBS@
 LIBCLAMAV_VERSION = @LIBCLAMAV_VERSION@
 LIBOBJS = @LIBOBJS@
diff -ruN clamav-0.86.2/clamscan/Makefile.in clamav-0.86.2.p1/clamscan/Makefile.in
--- clamav-0.86.2/clamscan/Makefile.in	Fri Jun 24 00:03:09 2005
+++ clamav-0.86.2.p1/clamscan/Makefile.in	Wed Aug 10 07:20:02 2005
@@ -107,7 +107,7 @@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFGDIR = @CFGDIR@
-CFLAGS = @CFLAGS@
+CFLAGS = @CFLAGS@ -O2 -DUNRAR3
 CLAMAVGROUP = @CLAMAVGROUP@
 CLAMAVUSER = @CLAMAVUSER@
 CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
@@ -132,7 +132,7 @@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
+LDFLAGS = @LDFLAGS@ -lunrar3
 LIBCLAMAV_LIBS = @LIBCLAMAV_LIBS@
 LIBCLAMAV_VERSION = @LIBCLAMAV_VERSION@
 LIBOBJS = @LIBOBJS@
diff -ruN clamav-0.86.2/clamscan/clamscan.c clamav-0.86.2.p1/clamscan/clamscan.c
--- clamav-0.86.2/clamscan/clamscan.c	Mon Jul 25 02:19:05 2005
+++ clamav-0.86.2.p1/clamscan/clamscan.c	Tue Aug  9 13:49:30 2005
@@ -34,7 +34,7 @@
 #include "defaults.h"
 #include "treewalk.h"
 #include "misc.h"
-
+#include "/usr/local/include/libunrar3/dll.hpp"
 #include "output.h"
 
 #ifdef C_LINUX
diff -ruN clamav-0.86.2/libclamav/Makefile.in clamav-0.86.2.p1/libclamav/Makefile.in
--- clamav-0.86.2/libclamav/Makefile.in	Fri Jun 24 00:03:13 2005
+++ clamav-0.86.2.p1/libclamav/Makefile.in	Wed Aug 10 07:19:21 2005
@@ -120,7 +120,7 @@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFGDIR = @CFGDIR@
-CFLAGS = @CFLAGS@
+CFLAGS = @CFLAGS@ -O2 -DUNRAR3
 CLAMAVGROUP = @CLAMAVGROUP@
 CLAMAVUSER = @CLAMAVUSER@
 CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
@@ -145,7 +145,7 @@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
+LDFLAGS = @LDFLAGS@ -lunrar3
 LIBCLAMAV_LIBS = @LIBCLAMAV_LIBS@
 LIBCLAMAV_VERSION = @LIBCLAMAV_VERSION@
 LIBOBJS = @LIBOBJS@
diff -ruN clamav-0.86.2/libclamav/scanners.c clamav-0.86.2.p1/libclamav/scanners.c
--- clamav-0.86.2/libclamav/scanners.c	Fri Jun 24 00:03:12 2005
+++ clamav-0.86.2.p1/libclamav/scanners.c	Tue Aug  9 14:20:03 2005
@@ -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 */
@@ -69,6 +70,8 @@
 #include "untar.h"
 #include "special.h"
 #include "binhex.h"
+#include "unrarlib.h"
+#include "/usr/local/include/libunrar3/dll.hpp"
 
 #ifdef HAVE_ZLIB_H
 #include <zlib.h>
@@ -107,10 +110,17 @@
 #define BLOCKMAX	    (options & CL_SCAN_BLOCKMAX)
 
 #define MAX_MAIL_RECURSION  15
-
+/*
+HANDLE PASCAL RAROpenArchive(struct RAROpenArchiveData *ArchiveData);
+HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *ArchiveData);
+int    PASCAL RARCloseArchive(HANDLE hArcData);
+int    PASCAL RARProcessFile(HANDLE hArcData, struct RARHeaderData *HeaderData);
+*/
 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);
 
 
+#define UNRAR3
+
 #ifdef CL_THREAD_SAFE
 static void cli_unlock_mutex(void *mtx)
 {
@@ -119,218 +129,6 @@
 }
 #endif
 
-static int cli_scanrar(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)
-{
-	FILE *tmp = NULL;
-	int fd, ret = CL_CLEAN;
-	unsigned int files = 0, encrypted, afiles;
-	ArchiveList_struct *rarlist = NULL;
-	ArchiveList_struct *rarlist_head = NULL;
-	char *rar_data_ptr;
-	unsigned long rar_data_size;
-	struct cli_meta_node *mdata;
-
-
-    cli_dbgmsg("in scanrar()\n");
-
-#ifdef CL_THREAD_SAFE
-    pthread_cleanup_push(cli_unlock_mutex, &cli_scanrar_mutex);
-    pthread_mutex_lock(&cli_scanrar_mutex);
-    cli_scanrar_inuse = 1;
-#endif
-
-    if(!(afiles = urarlib_list(desc, (ArchiveList_struct *) &rarlist))) {
-#ifdef CL_THREAD_SAFE
-	pthread_mutex_unlock(&cli_scanrar_mutex);
-	cli_scanrar_inuse = 0;
-#endif
-	return CL_ERAR;
-    }
-
-    cli_dbgmsg("RAR: Number of archived files: %d\n", afiles);
-
-    rarlist_head = rarlist;
-
-    while(rarlist) {
-
-	files++;
-	encrypted = rarlist->item.Flags & 0x04;
-
-	cli_dbgmsg("RAR: %s, crc32: 0x%x, encrypted: %d, compressed: %u, normal: %u, method: %d, ratio: %d (max: %d)\n", rarlist->item.Name, rarlist->item.FileCRC, encrypted, rarlist->item.PackSize, rarlist->item.UnpSize, rarlist->item.Method, rarlist->item.PackSize ? ((unsigned int) rarlist->item.UnpSize / (unsigned int) rarlist->item.PackSize) : 0, limits ? limits->maxratio : 0);
-
-	/* Scan metadata */
-	mdata = root->rar_mlist;
-	if(mdata) do {
-	    if(mdata->encrypted != encrypted)
-		continue;
-
-	    if(mdata->crc32 && (unsigned int) mdata->crc32 != rarlist->item.FileCRC)
-		continue;
-
-	    if(mdata->csize > 0 && (unsigned int) mdata->csize != rarlist->item.PackSize)
-		continue;
-
-	    if(mdata->size >= 0 && (unsigned int) mdata->size != rarlist->item.UnpSize)
-		continue;
-
-	    if(mdata->method >= 0 && mdata->method != rarlist->item.Method)
-		continue;
-
-	    if(mdata->fileno && mdata->fileno != files)
-		continue;
-
-	    if(mdata->maxdepth && arec > mdata->maxdepth)
-		continue;
-
-	    /* TODO add support for regex */
-	    /*if(mdata->filename && !strstr(zdirent.d_name, mdata->filename))*/
-	    if(mdata->filename && strcmp(rarlist->item.Name, mdata->filename))
-		continue;
-
-	    break; /* matched */
-
-	} while((mdata = mdata->next));
-
-	if(mdata) {
-	    *virname = mdata->virname;
-	    ret = CL_VIRUS;
-	    break;
-	}
-
-	if(DETECT_ENCRYPTED && (rarlist->item.Flags & 0x04)) {
-	    cli_dbgmsg("RAR: Encrypted files found in archive.\n");
-	    lseek(desc, 0, SEEK_SET);
-	    ret = cli_scandesc(desc, virname, scanned, root, 0, 0);
-	    if(ret < 0) {
-		break;
-	    } else if(ret != CL_VIRUS) {
-		*virname = "Encrypted.RAR";
-		ret = CL_VIRUS;
-	    }
-	    break;
-	}
-
-	if((rarlist->item.Flags & 0x03) != 0) {
-	    cli_dbgmsg("RAR: Skipping %s (splitted)\n", rarlist->item.Name);
-	    rarlist = rarlist->next;
-	    continue;
-	}
-
-	if(limits) {
-
-	    if(limits->maxratio && rarlist->item.UnpSize && rarlist->item.PackSize) {
-		if((unsigned int) rarlist->item.UnpSize / (unsigned int) rarlist->item.PackSize >= limits->maxratio) {
-		    cli_dbgmsg("RAR: Max ratio reached (normal: %d, compressed: %d, max: %ld)\n", (int) rarlist->item.UnpSize, (int) rarlist->item.PackSize, limits->maxratio);
-		    *virname = "Oversized.RAR";
-		    ret = CL_VIRUS;
-		    break;
-		}
-	    }
-
-	    if(limits->maxfilesize && (rarlist->item.UnpSize > (unsigned int) limits->maxfilesize)) {
-		cli_dbgmsg("RAR: %s: Size exceeded (%u, max: %lu)\n", rarlist->item.Name, (unsigned int) rarlist->item.UnpSize, limits->maxfilesize);
-		rarlist = rarlist->next;
-		if(BLOCKMAX) {
-		    *virname = "RAR.ExceededFileSize";
-		    ret = CL_VIRUS;
-		    break;
-		}
-		continue;
-	    }
-
-	    if(limits->maxfiles && (files > limits->maxfiles)) {
-		cli_dbgmsg("RAR: Files limit reached (max: %d)\n", limits->maxfiles);
-		if(BLOCKMAX) {
-		    *virname = "RAR.ExceededFilesLimit";
-		    ret = CL_VIRUS;
-		    break;
-		}
-		break;
-	    }
-	}
-
-        if(rarlist->item.FileAttr & RAR_FENTRY_ATTR_DIRECTORY) {
-            rarlist = rarlist->next;
-            continue;
-        }
-
-	if((tmp = tmpfile()) == NULL) {
-	    cli_dbgmsg("RAR: Can't generate temporary file.\n");
-#ifdef CL_THREAD_SAFE
-	    pthread_mutex_unlock(&cli_scanrar_mutex);
-	    cli_scanrar_inuse = 0;
-#endif
-	    return CL_ETMPFILE;
-	}
-	fd = fileno(tmp);
-
-	if( urarlib_get(&rar_data_ptr, &rar_data_size, rarlist->item.Name, desc, "clam")) {
-	    cli_dbgmsg("RAR: Extracted: %s, size: %lu\n", rarlist->item.Name, rar_data_size);
-	    if(fwrite(rar_data_ptr, 1, rar_data_size, tmp) != rar_data_size) {
-		cli_dbgmsg("RAR: Can't write to file.\n");
-		fclose(tmp);
-		tmp = NULL;
-		ret = CL_ERAR;
-		if(rar_data_ptr) {
-		    free(rar_data_ptr);
-		    rar_data_ptr = NULL;
-		}
-		break;
-	    }
-
-	    if(rar_data_ptr) {
-		free(rar_data_ptr);
-		rar_data_ptr = NULL;
-	    }
-	    if(fflush(tmp) != 0) {
-		cli_dbgmsg("RAR: fflush() failed: %s\n", strerror(errno));
-		fclose(tmp);
-		urarlib_freelist(rarlist_head);
-#ifdef CL_THREAD_SAFE
-		pthread_mutex_unlock(&cli_scanrar_mutex);
-		cli_scanrar_inuse = 0;
-#endif
-		return CL_EFSYNC;
-	    }
-
-	    lseek(fd, 0, SEEK_SET);
-	    if((ret = cli_magic_scandesc(fd, virname, scanned, root, limits, options, arec, mrec)) == CL_VIRUS ) {
-		cli_dbgmsg("RAR: Infected with %s\n", *virname);
-
-		fclose(tmp);
-		urarlib_freelist(rarlist);
-#ifdef CL_THREAD_SAFE
-		pthread_mutex_unlock(&cli_scanrar_mutex);
-		cli_scanrar_inuse = 0;
-#endif
-  		return ret;
-	    }
-
-	} else {
-	    cli_dbgmsg("RAR: Can't decompress file %s\n", rarlist->item.Name);
-	    fclose(tmp);
-	    tmp = NULL;
-	    ret = CL_ERAR; /* WinRAR 3.0 ? */
-	    break;
-	}
-
-	fclose(tmp);
-	tmp = NULL;
-	rarlist = rarlist->next;
-    }
-
-    urarlib_freelist(rarlist_head);
-#ifdef CL_THREAD_SAFE
-    pthread_mutex_unlock(&cli_scanrar_mutex);
-    cli_scanrar_inuse = 0;
-    pthread_cleanup_pop(0);
-#endif
-    
-    cli_dbgmsg("RAR: Exit code: %d\n", ret);
-
-    return ret;
-}
-
 #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)
 {
@@ -562,6 +360,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, int *arec, 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_scangzip(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)
 {
 	int fd, bytes, ret = CL_CLEAN;
@@ -1403,8 +1238,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:
@@ -1541,8 +1381,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.86.2/libclamav/unrarlib.c clamav-0.86.2.p1/libclamav/unrarlib.c
--- clamav-0.86.2/libclamav/unrarlib.c	Fri Jun 24 00:03:12 2005
+++ clamav-0.86.2.p1/libclamav/unrarlib.c	Tue Aug  9 13:39:10 2005
@@ -1,2774 +1,91 @@
-/* It contains some changes needed for libclamav and isn't compatible with
- * the original version, --tk
- */
-/* ***************************************************************************
- **
- **  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.
- **
- ************************************************************************** */
+static char const rcsid[] = "$Id: unrarlib.c,v 1.0 2004/10/20 18:18:46 mcmcc Exp $";
 
-/* ***************************************************************************
- **
- **                           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"
-/* ------------------------------------------------------------------------ */
-
-
-
-/* -- 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 <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
-    }
-  }
-
-  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");
-    }
-#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);
-}
-
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/param.h>
+#include "/usr/local/include/libunrar3/dll.hpp"
+#include "clamav.h"
+#include "others.h"
+#include "unrarlib.h"
+#include "mbox.h"
+#include "blob.h"
 
-int ReadHeader(int BlockType)
+int cli_unrar3(const char *dir, int desc)
 {
-  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);
-}
-
-/* **************************************************************************
- ****************************************************************************
- ****************************************************************************
- ************************************************************************** */
-
-
-
-
-
-
-
-
 
+    struct RAROpenArchiveDataEx OpenArchiveData;
+    struct RARHeaderData HeaderData;
+    int iReadHeaderCode, iProcessFileCode, fd, s_buff;
+    char buff[4096], uname[48];
+    const char *tmpdir;
+    HANDLE hArcData;
+    FILE *out;
 
-
-
-
-
-
-
-
-/* **************************************************************************
- ****************************************************************************
- ****************************************************************************
- ****************************************************************************
- *******                                                              *******
- *******                                                              *******
- *******                                                              *******
- *******                  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);
-  }
+    if((tmpdir = getenv("TMPDIR")) == NULL)
+#ifdef P_tmpdir
+	tmpdir = P_tmpdir;
 #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);
+	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;
+	}
 
-  MainHeadSize=SIZEOF_NEWMHD;
+	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;
+		}
+	}
+	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;
 
-  return(TRUE);
+	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;
+		}
+	}
+  
+    RARCloseArchive(hArcData);
+    unlink(uname);
+    
+    /*
+    if (iProcessFileCode == ERAR_BAD_DATA)
+	return CL_ERAR;
+    */
+    return CL_CLEAN;
 }
-
-
-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.86.2/libclamav/unrarlib.h clamav-0.86.2.p1/libclamav/unrarlib.h
--- clamav-0.86.2/libclamav/unrarlib.h	Fri Jun 24 00:03:12 2005
+++ clamav-0.86.2.p1/libclamav/unrarlib.h	Tue Aug  9 13:03:34 2005
@@ -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);

