git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@1895 77e5149b-7576-45b1-b177-96237e5ba77b
| ... | ... |
@@ -1,3 +1,9 @@ |
| 1 |
+Fri Apr 7 21:09:25 CEST 2006 (tk) |
|
| 2 |
+---------------------------------- |
|
| 3 |
+ * libclamav: initial support for Sensory Network's NodalCore Accelerator |
|
| 4 |
+ * clamscan: new option --hwaccel (only available on systems with hardware |
|
| 5 |
+ accelerators) |
|
| 6 |
+ |
|
| 1 | 7 |
Fri Apr 7 12:25:20 BST 2006 (njh) |
| 2 | 8 |
---------------------------------- |
| 3 | 9 |
* libclamav/mbox.c: Better handling of messages with lots of |
| ... | ... |
@@ -1,5 +1,5 @@ |
| 1 | 1 |
/* |
| 2 |
- * Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net> |
|
| 2 |
+ * Copyright (C) 2002 - 2006 Tomasz Kojm <tkojm@clamav.net> |
|
| 3 | 3 |
* |
| 4 | 4 |
* This program is free software; you can redistribute it and/or modify |
| 5 | 5 |
* it under the terms of the GNU General Public License as published by |
| ... | ... |
@@ -161,7 +161,10 @@ int clamscan(struct optstruct *opt) |
| 161 | 161 |
dms += (dms < 0) ? (1000000):(0); |
| 162 | 162 |
logg("\n----------- SCAN SUMMARY -----------\n");
|
| 163 | 163 |
logg("Known viruses: %d\n", claminfo.signs);
|
| 164 |
- logg("Engine version: %s\n", cl_retver());
|
|
| 164 |
+ if(optl(opt, "hwaccel")) |
|
| 165 |
+ logg("Engine version: %s [hwaccel]\n", cl_retver());
|
|
| 166 |
+ else |
|
| 167 |
+ logg("Engine version: %s\n", cl_retver());
|
|
| 165 | 168 |
logg("Scanned directories: %d\n", claminfo.dirs);
|
| 166 | 169 |
logg("Scanned files: %d\n", claminfo.files);
|
| 167 | 170 |
logg("Infected files: %d\n", claminfo.ifiles);
|
| ... | ... |
@@ -223,7 +226,9 @@ void help(void) |
| 223 | 223 |
mprintf(" --include=PATT Only scan file names containing PATT\n");
|
| 224 | 224 |
mprintf(" --include-dir=PATT Only scan directories containing PATT\n");
|
| 225 | 225 |
#endif |
| 226 |
- |
|
| 226 |
+#ifdef HAVE_HWACCEL |
|
| 227 |
+ mprintf("\n --hwaccel Use hardware acceleration\n");
|
|
| 228 |
+#endif |
|
| 227 | 229 |
mprintf("\n");
|
| 228 | 230 |
mprintf(" --no-mail Disable mail file support\n");
|
| 229 | 231 |
mprintf(" --no-phishing Disable phishing detection\n");
|
| ... | ... |
@@ -85,7 +85,10 @@ int scanmanager(const struct optstruct *opt) |
| 85 | 85 |
optl(opt, "tar") || optl(opt, "tgz") || optl(opt, "deb")) |
| 86 | 86 |
compression = 1; |
| 87 | 87 |
|
| 88 |
- /* now initialize the database */ |
|
| 88 |
+ |
|
| 89 |
+ if(optl(opt, "hwaccel")) |
|
| 90 |
+ dboptions |= CL_DB_HWACCEL; |
|
| 91 |
+ |
|
| 89 | 92 |
if(optl(opt, "no-phishing")) |
| 90 | 93 |
dboptions |= CL_DB_NOPHISHING; |
| 91 | 94 |
|
| ... | ... |
@@ -93,6 +93,9 @@ int main(int argc, char **argv) |
| 93 | 93 |
{"max-ratio", 1, 0, 0},
|
| 94 | 94 |
{"max-recursion", 1, 0, 0},
|
| 95 | 95 |
{"max-dir-recursion", 1, 0, 0},
|
| 96 |
+#ifdef HWACCEL |
|
| 97 |
+ {"hwaccel", 0, 0, 0},
|
|
| 98 |
+#endif |
|
| 96 | 99 |
{"disable-archive", 0, 0, 0},
|
| 97 | 100 |
{"no-archive", 0, 0, 0},
|
| 98 | 101 |
{"detect-broken", 0, 0, 0},
|
| ... | ... |
@@ -10825,13 +10825,160 @@ fi |
| 10825 | 10825 |
echo "$as_me:$LINENO: result: $ac_cv_lib_sn_sigscan_sn_sigscan_initdb" >&5 |
| 10826 | 10826 |
echo "${ECHO_T}$ac_cv_lib_sn_sigscan_sn_sigscan_initdb" >&6
|
| 10827 | 10827 |
if test $ac_cv_lib_sn_sigscan_sn_sigscan_initdb = yes; then |
| 10828 |
+ have_sigscan=yes |
|
| 10829 |
+fi |
|
| 10830 |
+ |
|
| 10831 |
+ if test "$have_sigscan" = "yes" |
|
| 10832 |
+ then |
|
| 10833 |
+ if test "${ac_cv_header_sn_sigscan_sn_sigscan_h+set}" = set; then
|
|
| 10834 |
+ echo "$as_me:$LINENO: checking for sn_sigscan/sn_sigscan.h" >&5 |
|
| 10835 |
+echo $ECHO_N "checking for sn_sigscan/sn_sigscan.h... $ECHO_C" >&6 |
|
| 10836 |
+if test "${ac_cv_header_sn_sigscan_sn_sigscan_h+set}" = set; then
|
|
| 10837 |
+ echo $ECHO_N "(cached) $ECHO_C" >&6 |
|
| 10838 |
+fi |
|
| 10839 |
+echo "$as_me:$LINENO: result: $ac_cv_header_sn_sigscan_sn_sigscan_h" >&5 |
|
| 10840 |
+echo "${ECHO_T}$ac_cv_header_sn_sigscan_sn_sigscan_h" >&6
|
|
| 10841 |
+else |
|
| 10842 |
+ # Is the header compilable? |
|
| 10843 |
+echo "$as_me:$LINENO: checking sn_sigscan/sn_sigscan.h usability" >&5 |
|
| 10844 |
+echo $ECHO_N "checking sn_sigscan/sn_sigscan.h usability... $ECHO_C" >&6 |
|
| 10845 |
+cat >conftest.$ac_ext <<_ACEOF |
|
| 10846 |
+/* confdefs.h. */ |
|
| 10847 |
+_ACEOF |
|
| 10848 |
+cat confdefs.h >>conftest.$ac_ext |
|
| 10849 |
+cat >>conftest.$ac_ext <<_ACEOF |
|
| 10850 |
+/* end confdefs.h. */ |
|
| 10851 |
+$ac_includes_default |
|
| 10852 |
+#include <sn_sigscan/sn_sigscan.h> |
|
| 10853 |
+_ACEOF |
|
| 10854 |
+rm -f conftest.$ac_objext |
|
| 10855 |
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
|
| 10856 |
+ (eval $ac_compile) 2>conftest.er1 |
|
| 10857 |
+ ac_status=$? |
|
| 10858 |
+ grep -v '^ *+' conftest.er1 >conftest.err |
|
| 10859 |
+ rm -f conftest.er1 |
|
| 10860 |
+ cat conftest.err >&5 |
|
| 10861 |
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
|
| 10862 |
+ (exit $ac_status); } && |
|
| 10863 |
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
|
| 10864 |
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
|
| 10865 |
+ (eval $ac_try) 2>&5 |
|
| 10866 |
+ ac_status=$? |
|
| 10867 |
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
|
| 10868 |
+ (exit $ac_status); }; } && |
|
| 10869 |
+ { ac_try='test -s conftest.$ac_objext'
|
|
| 10870 |
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
|
| 10871 |
+ (eval $ac_try) 2>&5 |
|
| 10872 |
+ ac_status=$? |
|
| 10873 |
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
|
| 10874 |
+ (exit $ac_status); }; }; then |
|
| 10875 |
+ ac_header_compiler=yes |
|
| 10876 |
+else |
|
| 10877 |
+ echo "$as_me: failed program was:" >&5 |
|
| 10878 |
+sed 's/^/| /' conftest.$ac_ext >&5 |
|
| 10828 | 10879 |
|
| 10880 |
+ac_header_compiler=no |
|
| 10881 |
+fi |
|
| 10882 |
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext |
|
| 10883 |
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 |
|
| 10884 |
+echo "${ECHO_T}$ac_header_compiler" >&6
|
|
| 10885 |
+ |
|
| 10886 |
+# Is the header present? |
|
| 10887 |
+echo "$as_me:$LINENO: checking sn_sigscan/sn_sigscan.h presence" >&5 |
|
| 10888 |
+echo $ECHO_N "checking sn_sigscan/sn_sigscan.h presence... $ECHO_C" >&6 |
|
| 10889 |
+cat >conftest.$ac_ext <<_ACEOF |
|
| 10890 |
+/* confdefs.h. */ |
|
| 10891 |
+_ACEOF |
|
| 10892 |
+cat confdefs.h >>conftest.$ac_ext |
|
| 10893 |
+cat >>conftest.$ac_ext <<_ACEOF |
|
| 10894 |
+/* end confdefs.h. */ |
|
| 10895 |
+#include <sn_sigscan/sn_sigscan.h> |
|
| 10896 |
+_ACEOF |
|
| 10897 |
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
|
|
| 10898 |
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 |
|
| 10899 |
+ ac_status=$? |
|
| 10900 |
+ grep -v '^ *+' conftest.er1 >conftest.err |
|
| 10901 |
+ rm -f conftest.er1 |
|
| 10902 |
+ cat conftest.err >&5 |
|
| 10903 |
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
|
| 10904 |
+ (exit $ac_status); } >/dev/null; then |
|
| 10905 |
+ if test -s conftest.err; then |
|
| 10906 |
+ ac_cpp_err=$ac_c_preproc_warn_flag |
|
| 10907 |
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag |
|
| 10908 |
+ else |
|
| 10909 |
+ ac_cpp_err= |
|
| 10910 |
+ fi |
|
| 10911 |
+else |
|
| 10912 |
+ ac_cpp_err=yes |
|
| 10913 |
+fi |
|
| 10914 |
+if test -z "$ac_cpp_err"; then |
|
| 10915 |
+ ac_header_preproc=yes |
|
| 10916 |
+else |
|
| 10917 |
+ echo "$as_me: failed program was:" >&5 |
|
| 10918 |
+sed 's/^/| /' conftest.$ac_ext >&5 |
|
| 10919 |
+ |
|
| 10920 |
+ ac_header_preproc=no |
|
| 10921 |
+fi |
|
| 10922 |
+rm -f conftest.err conftest.$ac_ext |
|
| 10923 |
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 |
|
| 10924 |
+echo "${ECHO_T}$ac_header_preproc" >&6
|
|
| 10925 |
+ |
|
| 10926 |
+# So? What about this header? |
|
| 10927 |
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in |
|
| 10928 |
+ yes:no: ) |
|
| 10929 |
+ { echo "$as_me:$LINENO: WARNING: sn_sigscan/sn_sigscan.h: accepted by the compiler, rejected by the preprocessor!" >&5
|
|
| 10930 |
+echo "$as_me: WARNING: sn_sigscan/sn_sigscan.h: accepted by the compiler, rejected by the preprocessor!" >&2;} |
|
| 10931 |
+ { echo "$as_me:$LINENO: WARNING: sn_sigscan/sn_sigscan.h: proceeding with the compiler's result" >&5
|
|
| 10932 |
+echo "$as_me: WARNING: sn_sigscan/sn_sigscan.h: proceeding with the compiler's result" >&2;} |
|
| 10933 |
+ ac_header_preproc=yes |
|
| 10934 |
+ ;; |
|
| 10935 |
+ no:yes:* ) |
|
| 10936 |
+ { echo "$as_me:$LINENO: WARNING: sn_sigscan/sn_sigscan.h: present but cannot be compiled" >&5
|
|
| 10937 |
+echo "$as_me: WARNING: sn_sigscan/sn_sigscan.h: present but cannot be compiled" >&2;} |
|
| 10938 |
+ { echo "$as_me:$LINENO: WARNING: sn_sigscan/sn_sigscan.h: check for missing prerequisite headers?" >&5
|
|
| 10939 |
+echo "$as_me: WARNING: sn_sigscan/sn_sigscan.h: check for missing prerequisite headers?" >&2;} |
|
| 10940 |
+ { echo "$as_me:$LINENO: WARNING: sn_sigscan/sn_sigscan.h: see the Autoconf documentation" >&5
|
|
| 10941 |
+echo "$as_me: WARNING: sn_sigscan/sn_sigscan.h: see the Autoconf documentation" >&2;} |
|
| 10942 |
+ { echo "$as_me:$LINENO: WARNING: sn_sigscan/sn_sigscan.h: section \"Present But Cannot Be Compiled\"" >&5
|
|
| 10943 |
+echo "$as_me: WARNING: sn_sigscan/sn_sigscan.h: section \"Present But Cannot Be Compiled\"" >&2;} |
|
| 10944 |
+ { echo "$as_me:$LINENO: WARNING: sn_sigscan/sn_sigscan.h: proceeding with the preprocessor's result" >&5
|
|
| 10945 |
+echo "$as_me: WARNING: sn_sigscan/sn_sigscan.h: proceeding with the preprocessor's result" >&2;} |
|
| 10946 |
+ { echo "$as_me:$LINENO: WARNING: sn_sigscan/sn_sigscan.h: in the future, the compiler will take precedence" >&5
|
|
| 10947 |
+echo "$as_me: WARNING: sn_sigscan/sn_sigscan.h: in the future, the compiler will take precedence" >&2;} |
|
| 10948 |
+ ( |
|
| 10949 |
+ cat <<\_ASBOX |
|
| 10950 |
+## ------------------------------------------ ## |
|
| 10951 |
+## Report this to the AC_PACKAGE_NAME lists. ## |
|
| 10952 |
+## ------------------------------------------ ## |
|
| 10953 |
+_ASBOX |
|
| 10954 |
+ ) | |
|
| 10955 |
+ sed "s/^/$as_me: WARNING: /" >&2 |
|
| 10956 |
+ ;; |
|
| 10957 |
+esac |
|
| 10958 |
+echo "$as_me:$LINENO: checking for sn_sigscan/sn_sigscan.h" >&5 |
|
| 10959 |
+echo $ECHO_N "checking for sn_sigscan/sn_sigscan.h... $ECHO_C" >&6 |
|
| 10960 |
+if test "${ac_cv_header_sn_sigscan_sn_sigscan_h+set}" = set; then
|
|
| 10961 |
+ echo $ECHO_N "(cached) $ECHO_C" >&6 |
|
| 10962 |
+else |
|
| 10963 |
+ ac_cv_header_sn_sigscan_sn_sigscan_h=$ac_header_preproc |
|
| 10964 |
+fi |
|
| 10965 |
+echo "$as_me:$LINENO: result: $ac_cv_header_sn_sigscan_sn_sigscan_h" >&5 |
|
| 10966 |
+echo "${ECHO_T}$ac_cv_header_sn_sigscan_sn_sigscan_h" >&6
|
|
| 10967 |
+ |
|
| 10968 |
+fi |
|
| 10969 |
+if test $ac_cv_header_sn_sigscan_sn_sigscan_h = yes; then |
|
| 10970 |
+ LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -lsn_sigscan"; |
|
| 10829 | 10971 |
cat >>confdefs.h <<\_ACEOF |
| 10830 | 10972 |
#define HAVE_HWACCEL 1 |
| 10831 | 10973 |
_ACEOF |
| 10832 | 10974 |
|
| 10975 |
+else |
|
| 10976 |
+ { echo "$as_me:$LINENO: WARNING: ****** hardware acceleration support disabled -- please install libsigscan-devel " >&5
|
|
| 10977 |
+echo "$as_me: WARNING: ****** hardware acceleration support disabled -- please install libsigscan-devel " >&2;} |
|
| 10833 | 10978 |
fi |
| 10834 | 10979 |
|
| 10980 |
+ |
|
| 10981 |
+ fi |
|
| 10835 | 10982 |
fi |
| 10836 | 10983 |
|
| 10837 | 10984 |
# Check whether --enable-dns or --disable-dns was given. |
| ... | ... |
@@ -1,5 +1,5 @@ |
| 1 | 1 |
dnl |
| 2 |
-dnl Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net> |
|
| 2 |
+dnl Copyright (C) 2002 - 2006 Tomasz Kojm <tkojm@clamav.net> |
|
| 3 | 3 |
dnl gethostbyname_r and readdir_r checks (c) COPYRIGHT MIT 1995 |
| 4 | 4 |
dnl |
| 5 | 5 |
dnl This program is free software; you can redistribute it and/or modify |
| ... | ... |
@@ -143,7 +143,11 @@ want_hwaccel=$enableval, want_hwaccel="yes") |
| 143 | 143 |
|
| 144 | 144 |
if test "$want_hwaccel" = "yes" |
| 145 | 145 |
then |
| 146 |
- AC_CHECK_LIB(sn_sigscan, sn_sigscan_initdb, AC_DEFINE(HAVE_HWACCEL,1,hardware acceleration),) |
|
| 146 |
+ AC_CHECK_LIB(sn_sigscan, sn_sigscan_initdb, have_sigscan=yes,) |
|
| 147 |
+ if test "$have_sigscan" = "yes" |
|
| 148 |
+ then |
|
| 149 |
+ AC_CHECK_HEADER(sn_sigscan/sn_sigscan.h,[LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -lsn_sigscan"; AC_DEFINE(HAVE_HWACCEL,1,hardware acceleration)], AC_MSG_WARN([****** hardware acceleration support disabled -- please install libsigscan-devel ])) |
|
| 150 |
+ fi |
|
| 147 | 151 |
fi |
| 148 | 152 |
|
| 149 | 153 |
AC_ARG_ENABLE(dns, |
| ... | ... |
@@ -34,6 +34,7 @@ extern "C" |
| 34 | 34 |
/* return codes */ |
| 35 | 35 |
#define CL_CLEAN 0 /* virus not found */ |
| 36 | 36 |
#define CL_VIRUS 1 /* virus found */ |
| 37 |
+#define CL_SUCCESS CL_CLEAN |
|
| 37 | 38 |
|
| 38 | 39 |
#define CL_EMAXREC 10 /* recursion level limit exceeded */ |
| 39 | 40 |
#define CL_EMAXSIZE 11 /* size limit exceeded */ |
| ... | ... |
@@ -63,6 +64,11 @@ extern "C" |
| 63 | 63 |
#define CL_EIO -12 /* general I/O error */ |
| 64 | 64 |
#define CL_EFORMAT -13 /* bad format or broken file */ |
| 65 | 65 |
|
| 66 |
+#define CL_EHWINIT -14 /* hardware initialization failed */ |
|
| 67 |
+#define CL_EHWLOAD -15 /* error loading hardware database */ |
|
| 68 |
+#define CL_EHWIO -16 /* general hardware I/O error */ |
|
| 69 |
+ |
|
| 70 |
+ |
|
| 66 | 71 |
/* db options */ |
| 67 | 72 |
#define CL_DB_HWACCEL 1 |
| 68 | 73 |
#define CL_DB_NOPHISHING 2 |
| ... | ... |
@@ -164,6 +170,8 @@ struct cl_engine {
|
| 164 | 164 |
/* RAR metadata */ |
| 165 | 165 |
struct cli_meta_node *rar_mlist; |
| 166 | 166 |
|
| 167 |
+ /* Hardware database handle */ |
|
| 168 |
+ void *hwdb; |
|
| 167 | 169 |
}; |
| 168 | 170 |
|
| 169 | 171 |
struct cl_limits {
|
| ... | ... |
@@ -293,8 +293,10 @@ int cli_addtypesigs(struct cl_engine *engine) |
| 293 | 293 |
} |
| 294 | 294 |
|
| 295 | 295 |
if(engine->hwaccel) {
|
| 296 |
+ /* |
|
| 296 | 297 |
cli_dbgmsg("cli_addtypesigs: AC depth 10 (hwaccel mode)\n");
|
| 297 | 298 |
cli_ac_setdepth(10); |
| 299 |
+ */ |
|
| 298 | 300 |
} |
| 299 | 301 |
|
| 300 | 302 |
root->ac_root = (struct cli_ac_node *) cli_calloc(1, sizeof(struct cli_ac_node)); |
| ... | ... |
@@ -1,5 +1,5 @@ |
| 1 | 1 |
/* |
| 2 |
- * Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net> |
|
| 2 |
+ * Copyright (C) 2002 - 2006 Tomasz Kojm <tkojm@clamav.net> |
|
| 3 | 3 |
* |
| 4 | 4 |
* This program is free software; you can redistribute it and/or modify |
| 5 | 5 |
* it under the terms of the GNU General Public License as published by |
| ... | ... |
@@ -45,16 +45,23 @@ static int targettab[CL_TARGET_TABLE_SIZE] = { 0, CL_TYPE_MSEXE, CL_TYPE_MSOLE2,
|
| 45 | 45 |
|
| 46 | 46 |
extern short cli_debug_flag; |
| 47 | 47 |
|
| 48 |
-#ifdef CL_THREAD_SAFE |
|
| 49 |
-# include <pthread.h> |
|
| 50 |
-static pthread_mutex_t cli_ref_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
| 48 |
+#ifdef HAVE_HWACCEL |
|
| 49 |
+#include <sn_sigscan/sn_sigscan.h> |
|
| 50 |
+#define HWBUFFSIZE 32768 |
|
| 51 | 51 |
#endif |
| 52 | 52 |
|
| 53 | 53 |
int cli_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_engine *engine, unsigned short ftype) |
| 54 | 54 |
{
|
| 55 |
- int ret, i, tid = 0, *partcnt; |
|
| 55 |
+ int ret = CL_CLEAN, i, tid = 0, *partcnt; |
|
| 56 | 56 |
unsigned long int *partoff; |
| 57 | 57 |
struct cli_matcher *groot, *troot = NULL; |
| 58 |
+#ifdef HAVE_HWACCEL |
|
| 59 |
+ void *streamhandle; |
|
| 60 |
+ void *resulthandle; |
|
| 61 |
+ uint32_t datamask[2] = { 1, 1 };
|
|
| 62 |
+ int count, hret; |
|
| 63 |
+ unsigned long long offset; |
|
| 64 |
+#endif |
|
| 58 | 65 |
|
| 59 | 66 |
|
| 60 | 67 |
if(!engine) {
|
| ... | ... |
@@ -62,6 +69,49 @@ int cli_scanbuff(const char *buffer, unsigned int length, const char **virname, |
| 62 | 62 |
return CL_ENULLARG; |
| 63 | 63 |
} |
| 64 | 64 |
|
| 65 |
+#ifdef HAVE_HWACCEL |
|
| 66 |
+ if(engine->hwaccel) {
|
|
| 67 |
+ /* TODO: Setup proper data bitmask (need specs) */ |
|
| 68 |
+ if((hret = sn_sigscan_createstream(engine->hwdb, datamask, 2, &streamhandle)) < 0) {
|
|
| 69 |
+ cli_errmsg("cli_scanbuff: can't create new hardware stream: %d\n", hret);
|
|
| 70 |
+ return CL_EHWIO; |
|
| 71 |
+ } |
|
| 72 |
+ |
|
| 73 |
+ if((hret = sn_sigscan_writestream(streamhandle, buffer, length)) < 0) {
|
|
| 74 |
+ cli_errmsg("cli_scanbuff: can't write %u bytes to hardware stream: %d\n", length, hret);
|
|
| 75 |
+ sn_sigscan_closestream(streamhandle, &resulthandle); |
|
| 76 |
+ return CL_EHWIO; |
|
| 77 |
+ } |
|
| 78 |
+ |
|
| 79 |
+ if((hret = sn_sigscan_closestream(streamhandle, &resulthandle)) < 0) {
|
|
| 80 |
+ cli_errmsg("cli_scanbuff: can't close hardware stream: %d\n", hret);
|
|
| 81 |
+ return CL_EHWIO; |
|
| 82 |
+ } |
|
| 83 |
+ |
|
| 84 |
+ count = sn_sigscan_resultcount(resulthandle); |
|
| 85 |
+ cli_dbgmsg("cli_scanbuff: number of results: %d\n", count);
|
|
| 86 |
+ |
|
| 87 |
+ if(count > 0) {
|
|
| 88 |
+ if((hret = sn_sigscan_resultget(resulthandle, 0, virname, &offset)) < 0) {
|
|
| 89 |
+ cli_errmsg("cli_scanbuff: can't get hardware match result: %d\n", hret);
|
|
| 90 |
+ sn_sigscan_resultfree(resulthandle); |
|
| 91 |
+ return CL_EHWIO; |
|
| 92 |
+ } else {
|
|
| 93 |
+ cli_dbgmsg("cli_scanbuff: hardware match %s at %u\n", *virname, offset);
|
|
| 94 |
+ ret = CL_VIRUS; |
|
| 95 |
+ } |
|
| 96 |
+ } |
|
| 97 |
+ |
|
| 98 |
+ if((hret = sn_sigscan_resultfree(resulthandle)) < 0) {
|
|
| 99 |
+ cli_errmsg("cli_scanbuff: can't free results: %d\n", ret);
|
|
| 100 |
+ return CL_EHWIO; |
|
| 101 |
+ } |
|
| 102 |
+ |
|
| 103 |
+ return ret; |
|
| 104 |
+ } |
|
| 105 |
+#endif /* HAVE_HWACCEL */ |
|
| 106 |
+ |
|
| 107 |
+ |
|
| 65 | 108 |
groot = engine->root[0]; /* generic signatures */ |
| 66 | 109 |
|
| 67 | 110 |
if(ftype) {
|
| ... | ... |
@@ -277,13 +327,20 @@ int cli_validatesig(unsigned short target, unsigned short ftype, const char *off |
| 277 | 277 |
int cli_scandesc(int desc, cli_ctx *ctx, unsigned short otfrec, unsigned short ftype, struct cli_matched_type **ftoffset) |
| 278 | 278 |
{
|
| 279 | 279 |
char *buffer, *buff, *endbl, *pt; |
| 280 |
- int ret, *gpartcnt, *tpartcnt, type = CL_CLEAN, i, tid = 0, bytes; |
|
| 280 |
+ int ret = CL_CLEAN, *gpartcnt, *tpartcnt, type = CL_CLEAN, i, tid = 0, bytes; |
|
| 281 | 281 |
unsigned int buffersize, length, maxpatlen, shift = 0; |
| 282 | 282 |
unsigned long int *gpartoff, *tpartoff, offset = 0; |
| 283 | 283 |
MD5_CTX md5ctx; |
| 284 | 284 |
unsigned char digest[16]; |
| 285 | 285 |
struct cli_md5_node *md5_node; |
| 286 | 286 |
struct cli_matcher *groot, *troot = NULL; |
| 287 |
+#ifdef HAVE_HWACCEL |
|
| 288 |
+ void *streamhandle; |
|
| 289 |
+ void *resulthandle; |
|
| 290 |
+ unsigned long long hoffset; |
|
| 291 |
+ uint32_t datamask[2] = { 1, 1 };
|
|
| 292 |
+ int count, hret; |
|
| 293 |
+#endif |
|
| 287 | 294 |
|
| 288 | 295 |
|
| 289 | 296 |
if(!ctx->engine) {
|
| ... | ... |
@@ -291,6 +348,61 @@ int cli_scandesc(int desc, cli_ctx *ctx, unsigned short otfrec, unsigned short f |
| 291 | 291 |
return CL_ENULLARG; |
| 292 | 292 |
} |
| 293 | 293 |
|
| 294 |
+#ifdef HAVE_HWACCEL |
|
| 295 |
+ if(ctx->engine->hwaccel) {
|
|
| 296 |
+ /* TODO: Setup proper data bitmask (need specs) */ |
|
| 297 |
+ if((hret = sn_sigscan_createstream(ctx->engine->hwdb, datamask, 2, &streamhandle)) < 0) {
|
|
| 298 |
+ cli_errmsg("cli_scandesc: can't create new hardware stream: %d\n", hret);
|
|
| 299 |
+ return CL_EHWIO; |
|
| 300 |
+ } |
|
| 301 |
+ |
|
| 302 |
+ if(!(buffer = (char *) cli_calloc(HWBUFFSIZE, sizeof(char)))) {
|
|
| 303 |
+ cli_dbgmsg("cli_scandesc: unable to cli_calloc(%u)\n", HWBUFFSIZE);
|
|
| 304 |
+ return CL_EMEM; |
|
| 305 |
+ } |
|
| 306 |
+ |
|
| 307 |
+ while((bytes = cli_readn(desc, buffer, HWBUFFSIZE)) > 0) {
|
|
| 308 |
+ if((hret = sn_sigscan_writestream(streamhandle, buffer, bytes)) < 0) {
|
|
| 309 |
+ cli_errmsg("cli_scandesc: can't write to hardware stream: %d\n", hret);
|
|
| 310 |
+ ret = CL_EHWIO; |
|
| 311 |
+ break; |
|
| 312 |
+ } else {
|
|
| 313 |
+ if(ctx->scanned) |
|
| 314 |
+ *ctx->scanned += bytes / CL_COUNT_PRECISION; |
|
| 315 |
+ } |
|
| 316 |
+ } |
|
| 317 |
+ |
|
| 318 |
+ free(buffer); |
|
| 319 |
+ |
|
| 320 |
+ if((hret = sn_sigscan_closestream(streamhandle, &resulthandle)) < 0) {
|
|
| 321 |
+ cli_errmsg("cli_scandesc: can't close hardware stream: %d\n", hret);
|
|
| 322 |
+ return CL_EHWIO; |
|
| 323 |
+ } |
|
| 324 |
+ |
|
| 325 |
+ count = sn_sigscan_resultcount(resulthandle); |
|
| 326 |
+ cli_dbgmsg("cli_scandesc: number of results: %d\n", count);
|
|
| 327 |
+ |
|
| 328 |
+ if(count > 0) {
|
|
| 329 |
+ if((hret = sn_sigscan_resultget(resulthandle, 0, ctx->virname, &hoffset)) < 0) {
|
|
| 330 |
+ cli_errmsg("cli_scandesc: can't get hardware match result: %d\n", hret);
|
|
| 331 |
+ sn_sigscan_resultfree(resulthandle); |
|
| 332 |
+ return CL_EHWIO; |
|
| 333 |
+ } else {
|
|
| 334 |
+ cli_dbgmsg("cli_scandesc: hardware match %s at %u\n", *ctx->virname, hoffset);
|
|
| 335 |
+ ret = CL_VIRUS; |
|
| 336 |
+ } |
|
| 337 |
+ } |
|
| 338 |
+ |
|
| 339 |
+ if((hret = sn_sigscan_resultfree(resulthandle)) < 0) {
|
|
| 340 |
+ cli_errmsg("cli_scandesc: can't free results: %d\n", ret);
|
|
| 341 |
+ return CL_EHWIO; |
|
| 342 |
+ } |
|
| 343 |
+ |
|
| 344 |
+ return ret; |
|
| 345 |
+ } |
|
| 346 |
+#endif /* HAVE_HWACCEL */ |
|
| 347 |
+ |
|
| 348 |
+ |
|
| 294 | 349 |
groot = ctx->engine->root[0]; /* generic signatures */ |
| 295 | 350 |
|
| 296 | 351 |
if(ftype) {
|
| ... | ... |
@@ -472,115 +584,3 @@ int cli_scandesc(int desc, cli_ctx *ctx, unsigned short otfrec, unsigned short f |
| 472 | 472 |
|
| 473 | 473 |
return otfrec ? type : CL_CLEAN; |
| 474 | 474 |
} |
| 475 |
- |
|
| 476 |
-int cl_build(struct cl_engine *engine) |
|
| 477 |
-{
|
|
| 478 |
- int i, ret; |
|
| 479 |
- struct cli_matcher *root; |
|
| 480 |
- |
|
| 481 |
- |
|
| 482 |
- if((ret = cli_addtypesigs(engine))) |
|
| 483 |
- return ret; |
|
| 484 |
- |
|
| 485 |
- for(i = 0; i < CL_TARGET_TABLE_SIZE; i++) |
|
| 486 |
- if((root = engine->root[i])) |
|
| 487 |
- cli_ac_buildtrie(root); |
|
| 488 |
- /* FIXME: check return values of cli_ac_buildtree */ |
|
| 489 |
- |
|
| 490 |
- return 0; |
|
| 491 |
-} |
|
| 492 |
- |
|
| 493 |
-struct cl_engine *cl_dup(struct cl_engine *engine) |
|
| 494 |
-{
|
|
| 495 |
- if(!engine) {
|
|
| 496 |
- cli_errmsg("cl_dup: engine == NULL\n");
|
|
| 497 |
- return NULL; |
|
| 498 |
- } |
|
| 499 |
- |
|
| 500 |
-#ifdef CL_THREAD_SAFE |
|
| 501 |
- pthread_mutex_lock(&cli_ref_mutex); |
|
| 502 |
-#endif |
|
| 503 |
- |
|
| 504 |
- engine->refcount++; |
|
| 505 |
- |
|
| 506 |
-#ifdef CL_THREAD_SAFE |
|
| 507 |
- pthread_mutex_unlock(&cli_ref_mutex); |
|
| 508 |
-#endif |
|
| 509 |
- |
|
| 510 |
- return engine; |
|
| 511 |
-} |
|
| 512 |
- |
|
| 513 |
-void cl_free(struct cl_engine *engine) |
|
| 514 |
-{
|
|
| 515 |
- int i; |
|
| 516 |
- struct cli_md5_node *md5pt, *md5h; |
|
| 517 |
- struct cli_meta_node *metapt, *metah; |
|
| 518 |
- struct cli_matcher *root; |
|
| 519 |
- |
|
| 520 |
- if(!engine) {
|
|
| 521 |
- cli_errmsg("cl_free: engine == NULL\n");
|
|
| 522 |
- return; |
|
| 523 |
- } |
|
| 524 |
- |
|
| 525 |
-#ifdef CL_THREAD_SAFE |
|
| 526 |
- pthread_mutex_lock(&cli_ref_mutex); |
|
| 527 |
-#endif |
|
| 528 |
- |
|
| 529 |
- engine->refcount--; |
|
| 530 |
- if(engine->refcount) {
|
|
| 531 |
-#ifdef CL_THREAD_SAFE |
|
| 532 |
- pthread_mutex_unlock(&cli_ref_mutex); |
|
| 533 |
-#endif |
|
| 534 |
- return; |
|
| 535 |
- } |
|
| 536 |
- |
|
| 537 |
-#ifdef CL_THREAD_SAFE |
|
| 538 |
- pthread_mutex_unlock(&cli_ref_mutex); |
|
| 539 |
-#endif |
|
| 540 |
- |
|
| 541 |
- for(i = 0; i < CL_TARGET_TABLE_SIZE; i++) {
|
|
| 542 |
- if((root = engine->root[i])) {
|
|
| 543 |
- cli_ac_free(root); |
|
| 544 |
- if(!engine->root[i]->ac_only) |
|
| 545 |
- cli_bm_free(root); |
|
| 546 |
- } |
|
| 547 |
- } |
|
| 548 |
- |
|
| 549 |
- if(engine->md5_hlist) {
|
|
| 550 |
- for(i = 0; i < 256; i++) {
|
|
| 551 |
- md5pt = engine->md5_hlist[i]; |
|
| 552 |
- while(md5pt) {
|
|
| 553 |
- md5h = md5pt; |
|
| 554 |
- md5pt = md5pt->next; |
|
| 555 |
- free(md5h->md5); |
|
| 556 |
- free(md5h->virname); |
|
| 557 |
- if(md5h->viralias) |
|
| 558 |
- free(md5h->viralias); |
|
| 559 |
- free(md5h); |
|
| 560 |
- } |
|
| 561 |
- } |
|
| 562 |
- free(engine->md5_hlist); |
|
| 563 |
- } |
|
| 564 |
- |
|
| 565 |
- metapt = engine->zip_mlist; |
|
| 566 |
- while(metapt) {
|
|
| 567 |
- metah = metapt; |
|
| 568 |
- metapt = metapt->next; |
|
| 569 |
- free(metah->virname); |
|
| 570 |
- if(metah->filename) |
|
| 571 |
- free(metah->filename); |
|
| 572 |
- free(metah); |
|
| 573 |
- } |
|
| 574 |
- |
|
| 575 |
- metapt = engine->rar_mlist; |
|
| 576 |
- while(metapt) {
|
|
| 577 |
- metah = metapt; |
|
| 578 |
- metapt = metapt->next; |
|
| 579 |
- free(metah->virname); |
|
| 580 |
- if(metah->filename) |
|
| 581 |
- free(metah->filename); |
|
| 582 |
- free(metah); |
|
| 583 |
- } |
|
| 584 |
- |
|
| 585 |
- free(engine); |
|
| 586 |
-} |
| ... | ... |
@@ -195,6 +195,12 @@ const char *cl_strerror(int clerror) |
| 195 | 195 |
return "Input/Output error"; |
| 196 | 196 |
case CL_EFORMAT: |
| 197 | 197 |
return "Bad format or broken data"; |
| 198 |
+ case CL_EHWINIT: |
|
| 199 |
+ return "Hardware initialization failure"; |
|
| 200 |
+ case CL_EHWLOAD: |
|
| 201 |
+ return "Error loading hardware database"; |
|
| 202 |
+ case CL_EHWIO: |
|
| 203 |
+ return "Hardware accelerator Input/Output error"; |
|
| 198 | 204 |
default: |
| 199 | 205 |
return "Unknown error code"; |
| 200 | 206 |
} |
| ... | ... |
@@ -1,5 +1,5 @@ |
| 1 | 1 |
/* |
| 2 |
- * Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net> |
|
| 2 |
+ * Copyright (C) 2002 - 2006 Tomasz Kojm <tkojm@clamav.net> |
|
| 3 | 3 |
* |
| 4 | 4 |
* This program is free software; you can redistribute it and/or modify |
| 5 | 5 |
* it under the terms of the GNU General Public License as published by |
| ... | ... |
@@ -58,6 +58,16 @@ |
| 58 | 58 |
# endif |
| 59 | 59 |
#endif |
| 60 | 60 |
|
| 61 |
+#ifdef CL_THREAD_SAFE |
|
| 62 |
+# include <pthread.h> |
|
| 63 |
+static pthread_mutex_t cli_ref_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
| 64 |
+#endif |
|
| 65 |
+ |
|
| 66 |
+#ifdef HAVE_HWACCEL |
|
| 67 |
+#include <sn_sigscan/sn_sigscan.h> |
|
| 68 |
+#endif |
|
| 69 |
+ |
|
| 70 |
+ |
|
| 61 | 71 |
/* TODO: clean up the code */ |
| 62 | 72 |
|
| 63 | 73 |
static int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hexsig, int sigid, int parts, int partno, unsigned short type, unsigned int mindist, unsigned int maxdist, char *offset, unsigned short target) |
| ... | ... |
@@ -962,14 +972,56 @@ static int cli_loadmd(FILE *fd, struct cl_engine **engine, unsigned int *signo, |
| 962 | 962 |
return 0; |
| 963 | 963 |
} |
| 964 | 964 |
|
| 965 |
+#ifdef HAVE_HWACCEL |
|
| 966 |
+static int cli_loadhw(const char *filename, struct cl_engine **engine, unsigned int *signo, unsigned int options) |
|
| 967 |
+{
|
|
| 968 |
+ int ret = 0; |
|
| 969 |
+ |
|
| 970 |
+ |
|
| 971 |
+ if((ret = cli_initengine(engine, options))) {
|
|
| 972 |
+ cl_free(*engine); |
|
| 973 |
+ return ret; |
|
| 974 |
+ } |
|
| 975 |
+ |
|
| 976 |
+ if((ret = sn_sigscan_initdb(&(*engine)->hwdb)) < 0) {
|
|
| 977 |
+ cli_errmsg("hwaccel: error initializing the matcher: %d\n", ret);
|
|
| 978 |
+ cl_free(*engine); |
|
| 979 |
+ return CL_EHWINIT; |
|
| 980 |
+ } |
|
| 981 |
+ |
|
| 982 |
+ (*engine)->hwaccel = 1; |
|
| 983 |
+ |
|
| 984 |
+ if((ret = sn_sigscan_loaddb((*engine)->hwdb, filename, 0, signo)) < 0) {
|
|
| 985 |
+ cli_errmsg("hwaccel: can't load hardware database: %d\n", ret);
|
|
| 986 |
+ cl_free(*engine); |
|
| 987 |
+ return CL_EHWLOAD; |
|
| 988 |
+ } |
|
| 989 |
+ |
|
| 990 |
+ return CL_SUCCESS; |
|
| 991 |
+} |
|
| 992 |
+#endif /* HAVE_HWACCEL */ |
|
| 993 |
+ |
|
| 965 | 994 |
static int cli_load(const char *filename, struct cl_engine **engine, unsigned int *signo, unsigned int options) |
| 966 | 995 |
{
|
| 967 | 996 |
FILE *fd; |
| 968 |
- int ret; |
|
| 997 |
+ int ret = CL_SUCCESS; |
|
| 998 |
+ |
|
| 969 | 999 |
|
| 1000 |
+#ifdef HAVE_HWACCEL |
|
| 1001 |
+ if(options & CL_DB_HWACCEL) {
|
|
| 1002 |
+ if(cli_strbcasestr(filename, ".hw")) {
|
|
| 1003 |
+ cli_dbgmsg("Loading %s\n", filename);
|
|
| 1004 |
+ ret = cli_loadhw(filename, engine, signo, options); |
|
| 1005 |
+ } else {
|
|
| 1006 |
+ cli_dbgmsg("Ignoring %s\n", filename);
|
|
| 1007 |
+ } |
|
| 1008 |
+ |
|
| 1009 |
+ return ret; |
|
| 1010 |
+ } |
|
| 1011 |
+#endif /* HAVE_HWACCEL */ |
|
| 970 | 1012 |
|
| 971 | 1013 |
if((fd = fopen(filename, "rb")) == NULL) {
|
| 972 |
- cli_errmsg("cli_loaddb(): Can't open file %s\n", filename);
|
|
| 1014 |
+ cli_errmsg("cli_load(): Can't open file %s\n", filename);
|
|
| 973 | 1015 |
return CL_EOPEN; |
| 974 | 1016 |
} |
| 975 | 1017 |
|
| ... | ... |
@@ -1005,7 +1057,7 @@ static int cli_load(const char *filename, struct cl_engine **engine, unsigned in |
| 1005 | 1005 |
ret = cli_loadmd(fd, engine, signo, 2, options); |
| 1006 | 1006 |
|
| 1007 | 1007 |
} else {
|
| 1008 |
- cli_dbgmsg("cli_loaddb: unknown extension - assuming old database format\n");
|
|
| 1008 |
+ cli_dbgmsg("cli_load: unknown extension - assuming old database format\n");
|
|
| 1009 | 1009 |
ret = cli_loaddb(fd, engine, signo, options); |
| 1010 | 1010 |
} |
| 1011 | 1011 |
|
| ... | ... |
@@ -1062,6 +1114,7 @@ static int cli_loaddbdir(const char *dirname, struct cl_engine **engine, unsigne |
| 1062 | 1062 |
cli_strbcasestr(dent->d_name, ".sdb") || |
| 1063 | 1063 |
cli_strbcasestr(dent->d_name, ".zmd") || |
| 1064 | 1064 |
cli_strbcasestr(dent->d_name, ".rmd") || |
| 1065 |
+ cli_strbcasestr(dent->d_name, ".hw") || |
|
| 1065 | 1066 |
cli_strbcasestr(dent->d_name, ".cvd"))) {
|
| 1066 | 1067 |
|
| 1067 | 1068 |
dbfile = (char *) cli_calloc(strlen(dent->d_name) + strlen(dirname) + 2, sizeof(char)); |
| ... | ... |
@@ -1107,14 +1160,7 @@ int cl_load(const char *path, struct cl_engine **engine, unsigned int *signo, un |
| 1107 | 1107 |
return ret; |
| 1108 | 1108 |
} |
| 1109 | 1109 |
|
| 1110 |
- if(options & CL_DB_HWACCEL) {
|
|
| 1111 |
- (*engine)->hwaccel = 1; |
|
| 1112 |
- |
|
| 1113 |
- /* load hw db */ |
|
| 1114 |
- |
|
| 1115 |
- return 0; |
|
| 1116 |
- |
|
| 1117 |
- } else switch(sb.st_mode & S_IFMT) {
|
|
| 1110 |
+ switch(sb.st_mode & S_IFMT) {
|
|
| 1118 | 1111 |
case S_IFREG: |
| 1119 | 1112 |
return cli_load(path, engine, signo, options); |
| 1120 | 1113 |
|
| ... | ... |
@@ -1178,11 +1224,12 @@ int cl_statinidir(const char *dirname, struct cl_stat *dbstat) |
| 1178 | 1178 |
cli_strbcasestr(dent->d_name, ".db2") || |
| 1179 | 1179 |
cli_strbcasestr(dent->d_name, ".db3") || |
| 1180 | 1180 |
cli_strbcasestr(dent->d_name, ".hdb") || |
| 1181 |
- cli_strbcasestr(dent->d_name, ".fp") || |
|
| 1181 |
+ cli_strbcasestr(dent->d_name, ".fp") || |
|
| 1182 | 1182 |
cli_strbcasestr(dent->d_name, ".ndb") || |
| 1183 | 1183 |
cli_strbcasestr(dent->d_name, ".sdb") || |
| 1184 | 1184 |
cli_strbcasestr(dent->d_name, ".zmd") || |
| 1185 | 1185 |
cli_strbcasestr(dent->d_name, ".rmd") || |
| 1186 |
+ cli_strbcasestr(dent->d_name, ".hw") || |
|
| 1186 | 1187 |
cli_strbcasestr(dent->d_name, ".cvd"))) {
|
| 1187 | 1188 |
|
| 1188 | 1189 |
dbstat->no++; |
| ... | ... |
@@ -1250,11 +1297,12 @@ int cl_statchkdir(const struct cl_stat *dbstat) |
| 1250 | 1250 |
cli_strbcasestr(dent->d_name, ".db2") || |
| 1251 | 1251 |
cli_strbcasestr(dent->d_name, ".db3") || |
| 1252 | 1252 |
cli_strbcasestr(dent->d_name, ".hdb") || |
| 1253 |
- cli_strbcasestr(dent->d_name, ".fp") || |
|
| 1253 |
+ cli_strbcasestr(dent->d_name, ".fp") || |
|
| 1254 | 1254 |
cli_strbcasestr(dent->d_name, ".ndb") || |
| 1255 | 1255 |
cli_strbcasestr(dent->d_name, ".sdb") || |
| 1256 | 1256 |
cli_strbcasestr(dent->d_name, ".zmd") || |
| 1257 | 1257 |
cli_strbcasestr(dent->d_name, ".rmd") || |
| 1258 |
+ cli_strbcasestr(dent->d_name, ".hw") || |
|
| 1258 | 1259 |
cli_strbcasestr(dent->d_name, ".cvd"))) {
|
| 1259 | 1260 |
|
| 1260 | 1261 |
fname = cli_calloc(strlen(dbstat->dir) + strlen(dent->d_name) + 2, sizeof(char)); |
| ... | ... |
@@ -1318,3 +1366,123 @@ int cl_statfree(struct cl_stat *dbstat) |
| 1318 | 1318 |
|
| 1319 | 1319 |
return 0; |
| 1320 | 1320 |
} |
| 1321 |
+ |
|
| 1322 |
+void cl_free(struct cl_engine *engine) |
|
| 1323 |
+{
|
|
| 1324 |
+ int i, ret; |
|
| 1325 |
+ struct cli_md5_node *md5pt, *md5h; |
|
| 1326 |
+ struct cli_meta_node *metapt, *metah; |
|
| 1327 |
+ struct cli_matcher *root; |
|
| 1328 |
+ |
|
| 1329 |
+ if(!engine) {
|
|
| 1330 |
+ cli_errmsg("cl_free: engine == NULL\n");
|
|
| 1331 |
+ return; |
|
| 1332 |
+ } |
|
| 1333 |
+ |
|
| 1334 |
+#ifdef CL_THREAD_SAFE |
|
| 1335 |
+ pthread_mutex_lock(&cli_ref_mutex); |
|
| 1336 |
+#endif |
|
| 1337 |
+ |
|
| 1338 |
+ engine->refcount--; |
|
| 1339 |
+ if(engine->refcount) {
|
|
| 1340 |
+#ifdef CL_THREAD_SAFE |
|
| 1341 |
+ pthread_mutex_unlock(&cli_ref_mutex); |
|
| 1342 |
+#endif |
|
| 1343 |
+ return; |
|
| 1344 |
+ } |
|
| 1345 |
+ |
|
| 1346 |
+#ifdef CL_THREAD_SAFE |
|
| 1347 |
+ pthread_mutex_unlock(&cli_ref_mutex); |
|
| 1348 |
+#endif |
|
| 1349 |
+ |
|
| 1350 |
+#ifdef HAVE_HWACCEL |
|
| 1351 |
+ if(engine->hwaccel) {
|
|
| 1352 |
+ if((ret = sn_sigscan_closedb(engine->hwdb)) < 0) {
|
|
| 1353 |
+ cli_errmsg("cl_free: can't close hardware database: %d\n", ret);
|
|
| 1354 |
+ } |
|
| 1355 |
+ } |
|
| 1356 |
+#endif |
|
| 1357 |
+ |
|
| 1358 |
+ for(i = 0; i < CL_TARGET_TABLE_SIZE; i++) {
|
|
| 1359 |
+ if((root = engine->root[i])) {
|
|
| 1360 |
+ cli_ac_free(root); |
|
| 1361 |
+ if(!engine->root[i]->ac_only) |
|
| 1362 |
+ cli_bm_free(root); |
|
| 1363 |
+ } |
|
| 1364 |
+ } |
|
| 1365 |
+ |
|
| 1366 |
+ if(engine->md5_hlist) {
|
|
| 1367 |
+ for(i = 0; i < 256; i++) {
|
|
| 1368 |
+ md5pt = engine->md5_hlist[i]; |
|
| 1369 |
+ while(md5pt) {
|
|
| 1370 |
+ md5h = md5pt; |
|
| 1371 |
+ md5pt = md5pt->next; |
|
| 1372 |
+ free(md5h->md5); |
|
| 1373 |
+ free(md5h->virname); |
|
| 1374 |
+ if(md5h->viralias) |
|
| 1375 |
+ free(md5h->viralias); |
|
| 1376 |
+ free(md5h); |
|
| 1377 |
+ } |
|
| 1378 |
+ } |
|
| 1379 |
+ free(engine->md5_hlist); |
|
| 1380 |
+ } |
|
| 1381 |
+ |
|
| 1382 |
+ metapt = engine->zip_mlist; |
|
| 1383 |
+ while(metapt) {
|
|
| 1384 |
+ metah = metapt; |
|
| 1385 |
+ metapt = metapt->next; |
|
| 1386 |
+ free(metah->virname); |
|
| 1387 |
+ if(metah->filename) |
|
| 1388 |
+ free(metah->filename); |
|
| 1389 |
+ free(metah); |
|
| 1390 |
+ } |
|
| 1391 |
+ |
|
| 1392 |
+ metapt = engine->rar_mlist; |
|
| 1393 |
+ while(metapt) {
|
|
| 1394 |
+ metah = metapt; |
|
| 1395 |
+ metapt = metapt->next; |
|
| 1396 |
+ free(metah->virname); |
|
| 1397 |
+ if(metah->filename) |
|
| 1398 |
+ free(metah->filename); |
|
| 1399 |
+ free(metah); |
|
| 1400 |
+ } |
|
| 1401 |
+ |
|
| 1402 |
+ free(engine); |
|
| 1403 |
+} |
|
| 1404 |
+ |
|
| 1405 |
+int cl_build(struct cl_engine *engine) |
|
| 1406 |
+{
|
|
| 1407 |
+ int i, ret; |
|
| 1408 |
+ struct cli_matcher *root; |
|
| 1409 |
+ |
|
| 1410 |
+ |
|
| 1411 |
+ if((ret = cli_addtypesigs(engine))) |
|
| 1412 |
+ return ret; |
|
| 1413 |
+ |
|
| 1414 |
+ for(i = 0; i < CL_TARGET_TABLE_SIZE; i++) |
|
| 1415 |
+ if((root = engine->root[i])) |
|
| 1416 |
+ cli_ac_buildtrie(root); |
|
| 1417 |
+ /* FIXME: check return values of cli_ac_buildtree */ |
|
| 1418 |
+ |
|
| 1419 |
+ return 0; |
|
| 1420 |
+} |
|
| 1421 |
+ |
|
| 1422 |
+struct cl_engine *cl_dup(struct cl_engine *engine) |
|
| 1423 |
+{
|
|
| 1424 |
+ if(!engine) {
|
|
| 1425 |
+ cli_errmsg("cl_dup: engine == NULL\n");
|
|
| 1426 |
+ return NULL; |
|
| 1427 |
+ } |
|
| 1428 |
+ |
|
| 1429 |
+#ifdef CL_THREAD_SAFE |
|
| 1430 |
+ pthread_mutex_lock(&cli_ref_mutex); |
|
| 1431 |
+#endif |
|
| 1432 |
+ |
|
| 1433 |
+ engine->refcount++; |
|
| 1434 |
+ |
|
| 1435 |
+#ifdef CL_THREAD_SAFE |
|
| 1436 |
+ pthread_mutex_unlock(&cli_ref_mutex); |
|
| 1437 |
+#endif |
|
| 1438 |
+ |
|
| 1439 |
+ return engine; |
|
| 1440 |
+} |