git-svn: trunk@1895
Tomasz Kojm authored on 2006/04/08 04:22:21... | ... |
@@ -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 |
+} |