Step 3: Install ClamAV eCAP AdapterΒΆ

Checking downloaded files for viruses will be implemented using eCAP ClamAV adapter by Measurement Factory, see http://www.e-cap.org/downloads. To download and compile all required packages, navigate to core.debian12 sub folder and run script 03_clamav.sh .

#!/bin/bash

# all packages are installed as root
if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi

# install clamav
apt-get install -y clamav clamav-daemon libclamav-dev g++ make patch libecap3 libecap3-dev pkg-config

# from now on every error is fatal
set -e

# download the sources
wget https://www.e-cap.org/archive/ecap_clamav_adapter-2.0.0.tar.gz

# unpack
tar -xvzf ecap_clamav_adapter-2.0.0.tar.gz

# patch the CL_SCAN_STDOPT error
cp ecap_clamav_adapter-2.0.0/src/ClamAv.cc ecap_clamav_adapter-2.0.0/src/ClamAv.cc.old
patch ecap_clamav_adapter-2.0.0/src/ClamAv.cc < ClamAv.cc.patch

# and RPI compilation
patch ecap_clamav_adapter-2.0.0/src/Xaction.cc < Xaction.cc.patch

# change into working dir
pushd ecap_clamav_adapter-2.0.0

# build
./configure && make && make install

# revert back
popd

The following patch fixes CL_SCAN_STDOPT error, as indicated on https://bugs.launchpad.net/ecap/+bug/1813962 as well as some minor changes or modern g++ used in Debian 12.

--- ClamAv.cc.old	2023-08-08 08:43:01.319301759 -0400
+++ ClamAv.cc	2023-08-08 08:45:04.093333050 -0400
@@ -44,8 +44,13 @@
     // We assume that cl_*() functions used here are threadsafe.
 
     const char *virname = 0;
-    const int eScanResult = cl_scanfile(answer.fileName.c_str(), &virname, 0, engine, CL_SCAN_STDOPT);
 
+    static struct cl_scan_options options = {};
+    {
+        options.parse |= ~0; // enable all parsers
+    }
+    const int eScanResult = cl_scanfile(answer.fileName.c_str(), &virname, 0, engine, &options);
+    
     switch (eScanResult) {
     case CL_CLEAN:
         answer.statusCode = Answer::scClean;
@@ -58,7 +63,7 @@
 
     default:
         answer.statusCode = Answer::scError;
-        answer.errorMsg = cl_strerror(eScanResult);
+        answer.errorMsg = cl_strerror(static_cast<cl_error_t>(eScanResult));
     }
 }
 
@@ -71,7 +76,7 @@
     if (!initialized) {
         const int ret = cl_init(CL_INIT_DEFAULT);
         if (ret != CL_SUCCESS)
-            Throw("Can't initialize libclamav: ", cl_strerror(ret));
+            Throw("Can't initialize libclamav: ", cl_strerror(static_cast<cl_error_t>(ret)));
         initialized = true;
     }
 
@@ -136,13 +141,13 @@
         /* load all available databases from default directory */
         int ret = cl_load(cl_retdbdir(), engine, &sigs, CL_DB_STDOPT);
         if (ret != CL_SUCCESS)
-            Throw("cl_load: ", cl_strerror(ret));
+            Throw("cl_load: ", cl_strerror(static_cast<cl_error_t>(ret)));
 
         // printf("Loaded %u signatures from %s\n", sigs, cl_retdbdir());
 
         // build engine
         if ((ret = cl_engine_compile(engine)) != CL_SUCCESS)
-            Throw("Database initialization error: ", cl_strerror(ret));;
+            Throw("Database initialization error: ", cl_strerror(static_cast<cl_error_t>(ret)));;
 
         memset(&dbstat, 0, sizeof(struct cl_stat));
         cl_statinidir(cl_retdbdir(), &dbstat);

And the next patch fixes the error when compiling eCAP adapter on Raspberry PI as explained at https://launchpadlibrarian.net/359347434/min-deduction-v2p0p0.patch

--- Xaction.cc.original	2020-04-13 10:35:15.231335505 +0100
+++ Xaction.cc	2020-04-13 10:36:13.841324633 +0100
@@ -302,7 +302,7 @@
         // We are here because we are or were trickling. If we stopped trickling,
         // we should not give more than we had trickled (until the final action).
         const Size tricklingMax = (trickledSize > pos) ? trickledSize - pos : 0;
-        bufSize = std::min(bufSize, tricklingMax);
+        bufSize = std::min(static_cast<Size>(bufSize), tricklingMax);
         // fall through to also obey actAllow limits
     }
 

Press Next to continue to Step 4.