{"componentChunkName":"component---src-templates-post-template-js","path":"/clamav-simple-filescan-en","result":{"data":{"markdownRemark":{"id":"d8b38ed2-d26f-58b1-856d-3b7a060bc837","html":"<blockquote>\n<p>This page has been machine-translated from the <a href=\"/clamav-simple-filescan\">original page</a>.</p>\n</blockquote>\n<p>I’ve been reading through the ClamAV source code without any particular goal, but I’ve reached a natural stopping point, so I’m publishing notes on the sequence of operations that occur from the time ClamAV scans an Eicar file until it is detected.</p>\n<!-- omit in toc -->\n<h2 id=\"table-of-contents\" style=\"position:relative;\"><a href=\"#table-of-contents\" aria-label=\"table of contents permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Table of Contents</h2>\n<ul>\n<li>\n<p><a href=\"#scanning-a-file-with-clamscan-or-clamdscan\">Scanning a File with clamscan or clamdscan</a></p>\n<ul>\n<li><a href=\"#clamscan-options\">clamscan Options</a></li>\n<li><a href=\"#clamdscan-options\">clamdscan Options</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#scan-behavior-of-clamdscan\">Scan Behavior of clamdscan</a></p>\n<ul>\n<li><a href=\"#executing-the-client-function\">Executing the client Function</a></li>\n<li><a href=\"#setting-the-scantype\">Setting the scantype</a></li>\n<li><a href=\"#calling-the-scan-function\">Calling the Scan Function</a></li>\n<li><a href=\"#executing-the-cli_ftw-function\">Executing the cli_ftw Function</a></li>\n<li><a href=\"#calling-serial_callback\">Calling serial_callback</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#debugging-clamd\">Debugging clamd</a></p>\n<ul>\n<li><a href=\"#retrieving-the-file-path-on-the-clamd-side\">Retrieving the File Path on the clamd Side</a></li>\n<li><a href=\"#executing-the-scan-callback-function\">Executing the Scan Callback Function</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#about-the-fmap_t-structure\">About the fmap_t Structure</a></p>\n<ul>\n<li><a href=\"#file-mapping-process\">File Mapping Process</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#tracing-the-scanner-processing\">Tracing the Scanner Processing</a></p>\n<ul>\n<li><a href=\"#arguments-of-the-scan_common-function\">Arguments of the scan_common Function</a></li>\n<li><a href=\"#identifying-the-file-type\">Identifying the File Type</a></li>\n<li><a href=\"#cache-check\">Cache Check</a></li>\n<li><a href=\"#tracing-scan-behavior-after-the-cache-check\">Tracing Scan Behavior After the Cache Check</a></li>\n</ul>\n</li>\n<li><a href=\"#summary\">Summary</a></li>\n</ul>\n<h2 id=\"scanning-a-file-with-clamscan-or-clamdscan\" style=\"position:relative;\"><a href=\"#scanning-a-file-with-clamscan-or-clamdscan\" aria-label=\"scanning a file with clamscan or clamdscan permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Scanning a File with clamscan or clamdscan</h2>\n<p><code class=\"language-text\">clamdscan</code> is a client program that performs file scanning as a client of a running <code class=\"language-text\">clamd</code> instance.</p>\n<p><code class=\"language-text\">clamscan</code>, on the other hand, uses ClamAV’s <code class=\"language-text\">libclamav</code> to act as a scanner for files and directories.</p>\n<p>Unlike <code class=\"language-text\">clamdscan</code>, <code class=\"language-text\">clamscan</code> does not require a running <code class=\"language-text\">clamd</code> instance; instead, it creates a new scan engine and loads the virus database each time it is invoked.</p>\n<p>Reference: <a href=\"https://docs.clamav.net/manual/Usage/Scanning.html#clamscan\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Scanning - ClamAV Documentation</a></p>\n<p>Let’s start by actually trying scans with both <code class=\"language-text\">clamscan</code> and <code class=\"language-text\">clamdscan</code>.</p>\n<p>The following commands were used to fetch an Eicar test file and verify detection.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># Fetch the Eicar file</span>\n<span class=\"token function\">wget</span> https://secure.eicar.org/eicar.com\n\n<span class=\"token comment\"># Detection test</span>\nclamscan eicar.com\nclamdscan --fdpass eicar.com</code></pre></div>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 635px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/88600465942e290c9403a3f96dec3efa/1ddef/image-20250508154636592.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 48.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAABRElEQVQoz42S6U6EQBCEeQpgORaUm2G42cNdTdRE3/+Jyqneyxij+6NSA6E/qqfb6l8WjG97jK87LB9H6O0ANT+Z5090z+9oN3soVWFeZjS6gW416rpGP/RI0gTraI0gDBDHMaI4glXVFfIsQ1EUKEqjIheV53NulKYpsjxDllEp8vz0nt+wnrCqqkRWGIag+BcCa1Wj6zu0XQvf9+H5njjlui4cx7nJdmDbtjm74pTF6ExHSNM00tbheLgBPU+g9NVq9a+sZbOgNfdCIKWUEihbIoSpvotFF/8VOM2jpFHNCRQ/xNc0Pwv/Al2BbFmfE2oD5ACYLgiC8/2c7uuedAKUVdBa1oApp3nCMA5y5lTLqhS/DOXfhCzkUNg21Rlx0lwHZZwrEkXRXbBry/NmRpI8SsrdfitLzGGN0yjOdWL797T8BRAoF7k3+qhdAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/88600465942e290c9403a3f96dec3efa/8ac56/image-20250508154636592.webp 240w,\n/static/88600465942e290c9403a3f96dec3efa/d3be9/image-20250508154636592.webp 480w,\n/static/88600465942e290c9403a3f96dec3efa/a4521/image-20250508154636592.webp 635w\"\n              sizes=\"(max-width: 635px) 100vw, 635px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/88600465942e290c9403a3f96dec3efa/8ff5a/image-20250508154636592.png 240w,\n/static/88600465942e290c9403a3f96dec3efa/e85cb/image-20250508154636592.png 480w,\n/static/88600465942e290c9403a3f96dec3efa/1ddef/image-20250508154636592.png 635w\"\n            sizes=\"(max-width: 635px) 100vw, 635px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/88600465942e290c9403a3f96dec3efa/1ddef/image-20250508154636592.png\"\n            alt=\"image-20250508154636592\"\n            title=\"image-20250508154636592\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Note: when <code class=\"language-text\">clamd</code> is configured to run as the <code class=\"language-text\">clamav</code> user, <code class=\"language-text\">clamd</code> may be unable to access the file requested by <code class=\"language-text\">clamdscan</code>, causing the scan to fail with <code class=\"language-text\">File path check failure: Permission denied. ERROR</code>.</p>\n<p>For this reason, <code class=\"language-text\">clamd</code> was started in LocalSocket mode and scan requests were issued using the <code class=\"language-text\">--fdpass</code> option, which passes the file descriptor directly to <code class=\"language-text\">clamd</code>.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 631px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/a7522e7a362d155cba71e57ebf30bc18/4597d/image-20250509171828209.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 27.916666666666668%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA8klEQVQY041Q2Y6DMAzMV0C4mxCgNBwJAal7qqq0//9Js7G7fVypDyNPYns8tvAfB8LtCv954Li/g97WeRy3H6xvX9i/77hYC+cdwh5gJ4vzeGbuNx/h4Nwaay6cE33fodUtjDEw7SN2HYH4Ayd1gtYKSim0sUa3mrnhug5d1KiqCv3QQ1R1hbqpURQFf0zzFB2M7EBrjTzPUZYlg3iSJEjTlEH8CZlKjoJsL+uCeZl5BZqm/tzQMCklN2dZ9hIECdH+a7wD3WALG3MSpxwNGKPjoixYnJqe8V9BHzyapsEwDNiPEAUXFqUcnSDsG9/oFae/ePaqKWJd/2gAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/a7522e7a362d155cba71e57ebf30bc18/8ac56/image-20250509171828209.webp 240w,\n/static/a7522e7a362d155cba71e57ebf30bc18/d3be9/image-20250509171828209.webp 480w,\n/static/a7522e7a362d155cba71e57ebf30bc18/d3d2f/image-20250509171828209.webp 631w\"\n              sizes=\"(max-width: 631px) 100vw, 631px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/a7522e7a362d155cba71e57ebf30bc18/8ff5a/image-20250509171828209.png 240w,\n/static/a7522e7a362d155cba71e57ebf30bc18/e85cb/image-20250509171828209.png 480w,\n/static/a7522e7a362d155cba71e57ebf30bc18/4597d/image-20250509171828209.png 631w\"\n            sizes=\"(max-width: 631px) 100vw, 631px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/a7522e7a362d155cba71e57ebf30bc18/4597d/image-20250509171828209.png\"\n            alt=\"image-20250509171828209\"\n            title=\"image-20250509171828209\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Reference: <a href=\"https://stackoverflow.com/questions/25437940/configure-clamdscan-to-scan-all-files-on-a-system-on-ubuntu-12-04\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Configure clamdscan to scan all files on a system on Ubuntu 12.04 - Stack Overflow</a></p>\n<h3 id=\"clamscan-options\" style=\"position:relative;\"><a href=\"#clamscan-options\" aria-label=\"clamscan options permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>clamscan Options</h3>\n<p><code class=\"language-text\">clamscan</code> supports considerably more options than <code class=\"language-text\">clamdscan</code>.</p>\n<p>The following is the help text for version 0.104.0.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ clamscan --help\n\n                       Clam AntiVirus: Scanner <span class=\"token number\">0.104</span>.0\n           By The ClamAV Team: https://www.clamav.net/about.html<span class=\"token comment\">#credits</span>\n           <span class=\"token punctuation\">(</span>C<span class=\"token punctuation\">)</span> <span class=\"token number\">2021</span> Cisco Systems, Inc.\n\n    clamscan <span class=\"token punctuation\">[</span>options<span class=\"token punctuation\">]</span> <span class=\"token punctuation\">[</span>file/directory/-<span class=\"token punctuation\">]</span>\n\n    --help                -h             Show this <span class=\"token builtin class-name\">help</span>\n    --version             -V             Print version number\n    --verbose             -v             Be verbose\n    --archive-verbose     -a             Show filenames inside scanned archives\n    --debug                              Enable libclamav<span class=\"token string\">'s debug messages\n    --quiet                              Only output error messages\n    --stdout                             Write to stdout instead of stderr. Does not affect '</span>debug<span class=\"token string\">' messages.\n    --no-summary                         Disable summary at end of scanning\n    --infected            -i             Only print infected files\n    --suppress-ok-results -o             Skip printing OK files\n    --bell                               Sound bell on virus detection\n\n    --tempdir=DIRECTORY                  Create temporary files in DIRECTORY\n    --leave-temps[=yes/no(*)]            Do not remove temporary files\n    --gen-json[=yes/no(*)]               Generate JSON metadata for the scanned file(s). For testing &amp; development use ONLY.\n                                         JSON will be printed if --debug is enabled.\n                                         A JSON file will dropped to the temp directory if --leave-temps is enabled.\n    --database=FILE/DIR   -d FILE/DIR    Load virus database from FILE or load all supported db files from DIR\n    --official-db-only[=yes/no(*)]       Only load official signatures\n    --log=FILE            -l FILE        Save scan report to FILE\n    --recursive[=yes/no(*)]  -r          Scan subdirectories recursively\n    --allmatch[=yes/no(*)]   -z          Continue scanning within file after finding a match\n    --cross-fs[=yes(*)/no]               Scan files and directories on other filesystems\n    --follow-dir-symlinks[=0/1(*)/2]     Follow directory symlinks (0 = never, 1 = direct, 2 = always)\n    --follow-file-symlinks[=0/1(*)/2]    Follow file symlinks (0 = never, 1 = direct, 2 = always)\n    --file-list=FILE      -f FILE        Scan files from FILE\n    --remove[=yes/no(*)]                 Remove infected files. Be careful!\n    --move=DIRECTORY                     Move infected files into DIRECTORY\n    --copy=DIRECTORY                     Copy infected files into DIRECTORY\n    --exclude=REGEX                      Don'</span>t scan <span class=\"token function\">file</span> names matching REGEX\n    --exclude-dir<span class=\"token operator\">=</span>REGEX                  Don't scan directories matching REGEX\n    --include<span class=\"token operator\">=</span>REGEX                      Only scan <span class=\"token function\">file</span> names matching REGEX\n    --include-dir<span class=\"token operator\">=</span>REGEX                  Only scan directories matching REGEX\n\n    --bytecode<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span>/no<span class=\"token punctuation\">]</span>               Load bytecode from the database\n    --bytecode-unsigned<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes/no<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span>      Load unsigned bytecode\n                                         **Caution**: You should NEVER run bytecode signatures from untrusted sources.\n                                         Doing so may result <span class=\"token keyword\">in</span> arbitrary code execution.\n    --bytecode-timeout<span class=\"token operator\">=</span>N                 Set bytecode <span class=\"token function\">timeout</span> <span class=\"token punctuation\">(</span>in milliseconds<span class=\"token punctuation\">)</span>\n    --statistics<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>none<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span>/bytecode/pcre<span class=\"token punctuation\">]</span> Collect and print execution statistics\n    --detect-pua<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes/no<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span>             Detect Possibly Unwanted Applications\n    --exclude-pua<span class=\"token operator\">=</span>CAT                    Skip PUA sigs of category CAT\n    --include-pua<span class=\"token operator\">=</span>CAT                    Load PUA sigs of category CAT\n    --detect-structured<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes/no<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span>      Detect structured data <span class=\"token punctuation\">(</span>SSN, Credit Card<span class=\"token punctuation\">)</span>\n    --structured-ssn-format<span class=\"token operator\">=</span>X            SSN <span class=\"token function\">format</span> <span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token operator\">=</span>normal,1<span class=\"token operator\">=</span>stripped,2<span class=\"token operator\">=</span>both<span class=\"token punctuation\">)</span>\n    --structured-ssn-count<span class=\"token operator\">=</span>N             Min SSN count to generate a detect\n    --structured-cc-count<span class=\"token operator\">=</span>N              Min CC count to generate a detect\n    --structured-cc-mode<span class=\"token operator\">=</span>X               CC mode <span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token operator\">=</span>credit debit and private label, <span class=\"token assign-left variable\">1</span><span class=\"token operator\">=</span>credit cards only\n    --scan-mail<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span>/no<span class=\"token punctuation\">]</span>              Scan mail files\n    --phishing-sigs<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span>/no<span class=\"token punctuation\">]</span>          Enable email signature-based phishing detection\n    --phishing-scan-urls<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span>/no<span class=\"token punctuation\">]</span>     Enable URL signature-based phishing detection\n    --heuristic-alerts<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span>/no<span class=\"token punctuation\">]</span>       Heuristic alerts\n    --heuristic-scan-precedence<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes/no<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span> Stop scanning as soon as a heuristic match is found\n    --normalize<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span>/no<span class=\"token punctuation\">]</span>              Normalize html, script, and text files. Use <span class=\"token assign-left variable\">normalize</span><span class=\"token operator\">=</span>no <span class=\"token keyword\">for</span> yara compatibility\n    --scan-pe<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span>/no<span class=\"token punctuation\">]</span>                Scan PE files\n    --scan-elf<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span>/no<span class=\"token punctuation\">]</span>               Scan ELF files\n    --scan-ole2<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span>/no<span class=\"token punctuation\">]</span>              Scan OLE2 containers\n    --scan-pdf<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span>/no<span class=\"token punctuation\">]</span>               Scan PDF files\n    --scan-swf<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span>/no<span class=\"token punctuation\">]</span>               Scan SWF files\n    --scan-html<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span>/no<span class=\"token punctuation\">]</span>              Scan HTML files\n    --scan-xmldocs<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span>/no<span class=\"token punctuation\">]</span>           Scan xml-based document files\n    --scan-hwp3<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span>/no<span class=\"token punctuation\">]</span>              Scan HWP3 files\n    --scan-archive<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span>/no<span class=\"token punctuation\">]</span>           Scan archive files <span class=\"token punctuation\">(</span>supported by libclamav<span class=\"token punctuation\">)</span>\n    --alert-broken<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes/no<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span>           Alert on broken executable files <span class=\"token punctuation\">(</span>PE <span class=\"token operator\">&amp;</span> ELF<span class=\"token punctuation\">)</span>\n    --alert-broken-media<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes/no<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span>     Alert on broken graphics files <span class=\"token punctuation\">(</span>JPEG, TIFF, PNG, GIF<span class=\"token punctuation\">)</span>\n    --alert-encrypted<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes/no<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span>        Alert on encrypted archives and documents\n    --alert-encrypted-archive<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes/no<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span> Alert on encrypted archives\n    --alert-encrypted-doc<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes/no<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span>    Alert on encrypted documents\n    --alert-macros<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes/no<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span>           Alert on OLE2 files containing VBA macros\n    --alert-exceeds-max<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes/no<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span>      Alert on files that exceed max <span class=\"token function\">file</span> size, max scan size, or max recursion limit\n    --alert-phishing-ssl<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes/no<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span>     Alert on emails containing SSL mismatches <span class=\"token keyword\">in</span> URLs\n    --alert-phishing-cloak<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes/no<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span>   Alert on emails containing cloaked URLs\n    --alert-partition-intersection<span class=\"token punctuation\">[</span><span class=\"token operator\">=</span>yes/no<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span> Alert on raw DMG image files containing partition intersections\n    --nocerts                            Disable authenticode certificate chain verification <span class=\"token keyword\">in</span> PE files\n    --dumpcerts                          Dump authenticode certificate chain <span class=\"token keyword\">in</span> PE files\n\n    --max-scantime<span class=\"token operator\">=</span><span class=\"token comment\">#n                    Scan time longer than this will be skipped and assumed clean (milliseconds)</span>\n    --max-filesize<span class=\"token operator\">=</span><span class=\"token comment\">#n                    Files larger than this will be skipped and assumed clean</span>\n    --max-scansize<span class=\"token operator\">=</span><span class=\"token comment\">#n                    The maximum amount of data to scan for each container file (**)</span>\n    --max-files<span class=\"token operator\">=</span><span class=\"token comment\">#n                       The maximum number of files to scan for each container file (**)</span>\n    --max-recursion<span class=\"token operator\">=</span><span class=\"token comment\">#n                   Maximum archive recursion level for container file (**)</span>\n    --max-dir-recursion<span class=\"token operator\">=</span><span class=\"token comment\">#n               Maximum directory recursion level</span>\n    --max-embeddedpe<span class=\"token operator\">=</span><span class=\"token comment\">#n                  Maximum size file to check for embedded PE</span>\n    --max-htmlnormalize<span class=\"token operator\">=</span><span class=\"token comment\">#n               Maximum size of HTML file to normalize</span>\n    --max-htmlnotags<span class=\"token operator\">=</span><span class=\"token comment\">#n                  Maximum size of normalized HTML file to scan</span>\n    --max-scriptnormalize<span class=\"token operator\">=</span><span class=\"token comment\">#n             Maximum size of script file to normalize</span>\n    --max-ziptypercg<span class=\"token operator\">=</span><span class=\"token comment\">#n                  Maximum size zip to type reanalyze</span>\n    --max-partitions<span class=\"token operator\">=</span><span class=\"token comment\">#n                  Maximum number of partitions in disk image to be scanned</span>\n    --max-iconspe<span class=\"token operator\">=</span><span class=\"token comment\">#n                     Maximum number of icons in PE file to be scanned</span>\n    --max-rechwp3<span class=\"token operator\">=</span><span class=\"token comment\">#n                     Maximum recursive calls to HWP3 parsing function</span>\n    --pcre-match-limit<span class=\"token operator\">=</span><span class=\"token comment\">#n                Maximum calls to the PCRE match function.</span>\n    --pcre-recmatch-limit<span class=\"token operator\">=</span><span class=\"token comment\">#n             Maximum recursive calls to the PCRE match function.</span>\n    --pcre-max-filesize<span class=\"token operator\">=</span><span class=\"token comment\">#n               Maximum size file to perform PCRE subsig matching.</span>\n    --disable-cache                      Disable caching and cache checks <span class=\"token keyword\">for</span> <span class=\"token builtin class-name\">hash</span> sums of scanned files.\n\nPass <span class=\"token keyword\">in</span> - as the filename <span class=\"token keyword\">for</span> stdin.\n\n<span class=\"token punctuation\">(</span>*<span class=\"token punctuation\">)</span> Default scan settings\n<span class=\"token punctuation\">(</span>**<span class=\"token punctuation\">)</span> Certain files <span class=\"token punctuation\">(</span>e.g. documents, archives, etc.<span class=\"token punctuation\">)</span> may <span class=\"token keyword\">in</span> turn contain other\n   files inside. The above options ensure safe processing of this kind of data.</code></pre></div>\n<p><code class=\"language-text\">clamscan</code> provides options to control output (such as <code class=\"language-text\">--quiet</code>, <code class=\"language-text\">--infected</code>, and <code class=\"language-text\">--no-summary</code>), to specify the virus database used by the scan engine, and to remove or quarantine detected files.</p>\n<p>Many additional options are available for finely controlling scan targets and exclusion criteria.</p>\n<h3 id=\"clamdscan-options\" style=\"position:relative;\"><a href=\"#clamdscan-options\" aria-label=\"clamdscan options permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>clamdscan Options</h3>\n<p>Because <code class=\"language-text\">clamdscan</code> performs file scanning as a client of a running <code class=\"language-text\">clamd</code> instance, unlike <code class=\"language-text\">clamscan</code> — which loads the engine and virus database fresh on each invocation — <code class=\"language-text\">clamdscan</code> has far fewer runtime scan options. The tradeoff is reduced overhead since the already-running <code class=\"language-text\">clamd</code> handles the actual scanning.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ clamdscan --help\n\n                      Clam AntiVirus: Daemon Client <span class=\"token number\">0.104</span>.0\n           By The ClamAV Team: https://www.clamav.net/about.html<span class=\"token comment\">#credits</span>\n           <span class=\"token punctuation\">(</span>C<span class=\"token punctuation\">)</span> <span class=\"token number\">2021</span> Cisco Systems, Inc.\n\n    clamdscan <span class=\"token punctuation\">[</span>options<span class=\"token punctuation\">]</span> <span class=\"token punctuation\">[</span>file/directory/-<span class=\"token punctuation\">]</span>\n\n    --help              -h             Show this <span class=\"token builtin class-name\">help</span>\n    --version           -V             Print version number and <span class=\"token builtin class-name\">exit</span>\n    --verbose           -v             Be verbose\n    --quiet                            Be quiet, only output error messages\n    --stdout                           Write to stdout instead of stderr. Does not affect <span class=\"token string\">'debug'</span> messages.\n                                       <span class=\"token punctuation\">(</span>this <span class=\"token builtin class-name\">help</span> is always written to stdout<span class=\"token punctuation\">)</span>\n    --log<span class=\"token operator\">=</span>FILE          -l FILE        Save scan report <span class=\"token keyword\">in</span> FILE\n    --file-list<span class=\"token operator\">=</span>FILE    -f FILE        Scan files from FILE\n    --ping              -p A<span class=\"token punctuation\">[</span>:I<span class=\"token punctuation\">]</span>       Ping clamd up to <span class=\"token punctuation\">[</span>A<span class=\"token punctuation\">]</span> <span class=\"token builtin class-name\">times</span> at optional interval <span class=\"token punctuation\">[</span>I<span class=\"token punctuation\">]</span> <span class=\"token keyword\">until</span> it responds.\n    --wait              -w             Wait up to <span class=\"token number\">30</span> seconds <span class=\"token keyword\">for</span> clamd to start. Optionally use alongside --ping to <span class=\"token builtin class-name\">set</span> attempts <span class=\"token punctuation\">[</span>A<span class=\"token punctuation\">]</span> and interval <span class=\"token punctuation\">[</span>I<span class=\"token punctuation\">]</span> to check clamd.\n    --remove                           Remove infected files. Be careful<span class=\"token operator\">!</span>\n    --move<span class=\"token operator\">=</span>DIRECTORY                   Move infected files into DIRECTORY\n    --copy<span class=\"token operator\">=</span>DIRECTORY                   Copy infected files into DIRECTORY\n    --config-file<span class=\"token operator\">=</span>FILE                 Read configuration from FILE.\n    --allmatch            -z           Continue scanning within <span class=\"token function\">file</span> after finding a match.\n    --multiscan           -m           Force MULTISCAN mode\n    --infected            -i           Only print infected files\n    --no-summary                       Disable summary at end of scanning\n    --reload                           Request clamd to reload virus database\n    --fdpass                           Pass filedescriptor to clamd <span class=\"token punctuation\">(</span>useful <span class=\"token keyword\">if</span> clamd is running as a different user<span class=\"token punctuation\">)</span>\n    --stream                           Force streaming files to clamd <span class=\"token punctuation\">(</span>for debugging and unit testing<span class=\"token punctuation\">)</span></code></pre></div>\n<p>When using <code class=\"language-text\">clamdscan</code>, output control through <code class=\"language-text\">--quiet</code>, <code class=\"language-text\">--infected</code>, and <code class=\"language-text\">--no-summary</code> is available, similar to <code class=\"language-text\">clamscan</code>. Removing and quarantining detected files with <code class=\"language-text\">--remove</code> and <code class=\"language-text\">--move</code> is also supported.</p>\n<h2 id=\"scan-behavior-of-clamdscan\" style=\"position:relative;\"><a href=\"#scan-behavior-of-clamdscan\" aria-label=\"scan behavior of clamdscan permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Scan Behavior of clamdscan</h2>\n<p>In this section we trace the behavior when a scan is performed with <code class=\"language-text\">clamdscan</code>.</p>\n<p>In the <code class=\"language-text\">main</code> function of <code class=\"language-text\">clamdscan</code>, after parsing all runtime options, the following code is executed.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">date_start <span class=\"token operator\">=</span> <span class=\"token function\">time</span><span class=\"token punctuation\">(</span><span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">gettimeofday</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>t1<span class=\"token punctuation\">,</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nret <span class=\"token operator\">=</span> <span class=\"token function\">client</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>infected<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>err<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">optfree</span><span class=\"token punctuation\">(</span>clamdopts<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">/* TODO: Implement STATUS in clamd */</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span><span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"no-summary\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">tm</span> tmp<span class=\"token punctuation\">;</span>\n\n    date_end <span class=\"token operator\">=</span> <span class=\"token function\">time</span><span class=\"token punctuation\">(</span><span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">gettimeofday</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>t2<span class=\"token punctuation\">,</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    ds  <span class=\"token operator\">=</span> t2<span class=\"token punctuation\">.</span>tv_sec <span class=\"token operator\">-</span> t1<span class=\"token punctuation\">.</span>tv_sec<span class=\"token punctuation\">;</span>\n    dms <span class=\"token operator\">=</span> t2<span class=\"token punctuation\">.</span>tv_usec <span class=\"token operator\">-</span> t1<span class=\"token punctuation\">.</span>tv_usec<span class=\"token punctuation\">;</span>\n    ds <span class=\"token operator\">-=</span> <span class=\"token punctuation\">(</span>dms <span class=\"token operator\">&lt;</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">?</span> <span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    dms <span class=\"token operator\">+=</span> <span class=\"token punctuation\">(</span>dms <span class=\"token operator\">&lt;</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">?</span> <span class=\"token punctuation\">(</span><span class=\"token number\">1000000</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"\\n----------- SCAN SUMMARY -----------\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Infected files: %d\\n\"</span><span class=\"token punctuation\">,</span> infected<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span>\n        <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Total errors: %d\\n\"</span><span class=\"token punctuation\">,</span> err<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>notremoved<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Not removed: %d\\n\"</span><span class=\"token punctuation\">,</span> notremoved<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>notmoved<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Not moved: %d\\n\"</span><span class=\"token punctuation\">,</span> notmoved<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Time: %d.%3.3d sec (%d m %d s)\\n\"</span><span class=\"token punctuation\">,</span> ds<span class=\"token punctuation\">,</span> dms <span class=\"token operator\">/</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">,</span> ds <span class=\"token operator\">/</span> <span class=\"token number\">60</span><span class=\"token punctuation\">,</span> ds <span class=\"token operator\">%</span> <span class=\"token number\">60</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">ifdef</span> <span class=\"token expression\">_WIN32</span></span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token number\">0</span> <span class=\"token operator\">!=</span> <span class=\"token function\">localtime_s</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>tmp<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>date_start<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">else</span></span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span><span class=\"token function\">localtime_r</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>date_start<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>tmp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">endif</span></span>\n        <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"!Failed to get local time for Start Date.\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token function\">strftime</span><span class=\"token punctuation\">(</span>buffer<span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>buffer<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"%Y:%m:%d %H:%M:%S\"</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>tmp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Start Date: %s\\n\"</span><span class=\"token punctuation\">,</span> buffer<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">ifdef</span> <span class=\"token expression\">_WIN32</span></span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token number\">0</span> <span class=\"token operator\">!=</span> <span class=\"token function\">localtime_s</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>tmp<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>date_end<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">else</span></span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span><span class=\"token function\">localtime_r</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>date_end<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>tmp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">endif</span></span>\n        <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"!Failed to get local time for End Date.\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token function\">strftime</span><span class=\"token punctuation\">(</span>buffer<span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>buffer<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"%Y:%m:%d %H:%M:%S\"</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>tmp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"End Date:   %s\\n\"</span><span class=\"token punctuation\">,</span> buffer<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Reference: <a href=\"https://github.com/kash1064/clamav/blob/rel/0.104/clamdscan/clamdscan.c\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">clamav/clamdscan/clamdscan.c at rel/0.104 · kash1064/clamav</a></p>\n<h3 id=\"executing-the-client-function\" style=\"position:relative;\"><a href=\"#executing-the-client-function\" aria-label=\"executing the client function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Executing the client Function</h3>\n<p>First, the <code class=\"language-text\">client</code> function is called with a variable holding a pointer to the parsed options list.</p>\n<p>The <code class=\"language-text\">client</code> function receives the list via <code class=\"language-text\">const struct optstruct *opts</code>, extracts each option and configuration value, performs the scan of the target file, and returns the result.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">struct</span> <span class=\"token class-name\">optstruct</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>name<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>cmd<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>strarg<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">long</span> <span class=\"token keyword\">long</span> numarg<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">int</span> enabled<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">int</span> active<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">int</span> flags<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">int</span> idx<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">optstruct</span> <span class=\"token operator\">*</span>nextarg<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">optstruct</span> <span class=\"token operator\">*</span>next<span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span>filename<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* cmdline */</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">int</span> ds<span class=\"token punctuation\">,</span> dms<span class=\"token punctuation\">,</span> ret<span class=\"token punctuation\">,</span> infected <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> err <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">optstruct</span> <span class=\"token operator\">*</span>opts<span class=\"token punctuation\">;</span>\n\nret <span class=\"token operator\">=</span> <span class=\"token function\">client</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>infected<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>err<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The <code class=\"language-text\">client</code> function is implemented in <code class=\"language-text\">clamdscan/client.c</code> as follows.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">int</span> <span class=\"token function\">client</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">optstruct</span> <span class=\"token operator\">*</span>opts<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> <span class=\"token operator\">*</span>infected<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> <span class=\"token operator\">*</span>err<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">int</span> remote<span class=\"token punctuation\">,</span> scantype<span class=\"token punctuation\">,</span> session <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> errors <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> scandash <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> maxrec<span class=\"token punctuation\">,</span> flags <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>fname<span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"wait\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token class-name\">int16_t</span> ping_result <span class=\"token operator\">=</span> <span class=\"token function\">ping_clamd</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">switch</span> <span class=\"token punctuation\">(</span>ping_result<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">case</span> <span class=\"token number\">0</span><span class=\"token operator\">:</span>\n                <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n            <span class=\"token keyword\">case</span> <span class=\"token number\">1</span><span class=\"token operator\">:</span>\n                <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span>CL_ETIMEOUT<span class=\"token punctuation\">;</span>\n            <span class=\"token keyword\">default</span><span class=\"token operator\">:</span>\n                <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span>CL_ERROR<span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n\n    scandash <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>opts<span class=\"token operator\">-></span>filename <span class=\"token operator\">&amp;&amp;</span> opts<span class=\"token operator\">-></span>filename<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">&amp;&amp;</span> <span class=\"token operator\">!</span><span class=\"token function\">strcmp</span><span class=\"token punctuation\">(</span>opts<span class=\"token operator\">-></span>filename<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"-\"</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&amp;&amp;</span> <span class=\"token operator\">!</span><span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"file-list\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled <span class=\"token operator\">&amp;&amp;</span> <span class=\"token operator\">!</span>opts<span class=\"token operator\">-></span>filename<span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    remote   <span class=\"token operator\">=</span> <span class=\"token function\">isremote</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">)</span> <span class=\"token operator\">|</span> <span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"stream\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">;</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">ifdef</span> <span class=\"token expression\">HAVE_FD_PASSING</span></span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>remote <span class=\"token operator\">&amp;&amp;</span> <span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>clamdopts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"LocalSocket\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled <span class=\"token operator\">&amp;&amp;</span> <span class=\"token punctuation\">(</span><span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"fdpass\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled <span class=\"token operator\">||</span> scandash<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        scantype <span class=\"token operator\">=</span> FILDES<span class=\"token punctuation\">;</span>\n        session  <span class=\"token operator\">=</span> <span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"multiscan\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">endif</span></span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>remote <span class=\"token operator\">||</span> scandash<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        scantype <span class=\"token operator\">=</span> STREAM<span class=\"token punctuation\">;</span>\n        session  <span class=\"token operator\">=</span> <span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"multiscan\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"multiscan\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">)</span>\n        scantype <span class=\"token operator\">=</span> MULTI<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"allmatch\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">)</span>\n        scantype <span class=\"token operator\">=</span> ALLMATCH<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">else</span>\n        scantype <span class=\"token operator\">=</span> CONT<span class=\"token punctuation\">;</span>\n\n    maxrec    <span class=\"token operator\">=</span> <span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>clamdopts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"MaxDirectoryRecursion\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>numarg<span class=\"token punctuation\">;</span>\n    maxstream <span class=\"token operator\">=</span> <span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>clamdopts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"StreamMaxLength\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>numarg<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>clamdopts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"FollowDirectorySymlinks\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">)</span>\n        flags <span class=\"token operator\">|=</span> CLI_FTW_FOLLOW_DIR_SYMLINK<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>clamdopts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"FollowFileSymlinks\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">)</span>\n        flags <span class=\"token operator\">|=</span> CLI_FTW_FOLLOW_FILE_SYMLINK<span class=\"token punctuation\">;</span>\n    flags <span class=\"token operator\">|=</span> CLI_FTW_TRIM_SLASHES<span class=\"token punctuation\">;</span>\n\n    <span class=\"token operator\">*</span>infected <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>scandash<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">int</span> sockd<span class=\"token punctuation\">,</span> ret<span class=\"token punctuation\">;</span>\n        STATBUF sb<span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">FSTAT</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>sb<span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"client.c: fstat failed for file name \\\"%s\\\", with %s\\n.\"</span><span class=\"token punctuation\">,</span>\n                 opts<span class=\"token operator\">-></span>filename<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token function\">strerror</span><span class=\"token punctuation\">(</span>errno<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            <span class=\"token keyword\">return</span> <span class=\"token number\">2</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>sb<span class=\"token punctuation\">.</span>st_mode <span class=\"token operator\">&amp;</span> S_IFMT<span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> S_IFREG<span class=\"token punctuation\">)</span> scantype <span class=\"token operator\">=</span> STREAM<span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>sockd <span class=\"token operator\">=</span> <span class=\"token function\">dconnect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>=</span> <span class=\"token number\">0</span> <span class=\"token operator\">&amp;&amp;</span> <span class=\"token punctuation\">(</span>ret <span class=\"token operator\">=</span> <span class=\"token function\">dsresult</span><span class=\"token punctuation\">(</span>sockd<span class=\"token punctuation\">,</span> scantype<span class=\"token punctuation\">,</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>ret<span class=\"token punctuation\">,</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span>\n            <span class=\"token operator\">*</span>infected <span class=\"token operator\">=</span> ret<span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">else</span>\n            errors <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>sockd <span class=\"token operator\">>=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token function\">closesocket</span><span class=\"token punctuation\">(</span>sockd<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>opts<span class=\"token operator\">-></span>filename <span class=\"token operator\">||</span> <span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"file-list\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>opts<span class=\"token operator\">-></span>filename <span class=\"token operator\">&amp;&amp;</span> <span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"file-list\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">)</span>\n            <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"^Only scanning files from --file-list (files passed at cmdline are ignored)\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>fname <span class=\"token operator\">=</span> <span class=\"token function\">filelist</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span><span class=\"token function\">strcmp</span><span class=\"token punctuation\">(</span>fname<span class=\"token punctuation\">,</span> <span class=\"token string\">\"-\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n                <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"!Scanning from standard input requires \\\"-\\\" to be the only file argument\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n                <span class=\"token keyword\">continue</span><span class=\"token punctuation\">;</span>\n            <span class=\"token punctuation\">}</span>\n            errors <span class=\"token operator\">+=</span> <span class=\"token function\">client_scan</span><span class=\"token punctuation\">(</span>fname<span class=\"token punctuation\">,</span> scantype<span class=\"token punctuation\">,</span> infected<span class=\"token punctuation\">,</span> err<span class=\"token punctuation\">,</span> maxrec<span class=\"token punctuation\">,</span> session<span class=\"token punctuation\">,</span> flags<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            <span class=\"token comment\">/* this may be too strict\n    if(errors >= 10) {\nlogg(\"!Too many errors\\n\");\nbreak;\n    }\n    */</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n        errors <span class=\"token operator\">=</span> <span class=\"token function\">client_scan</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"\"</span><span class=\"token punctuation\">,</span> scantype<span class=\"token punctuation\">,</span> infected<span class=\"token punctuation\">,</span> err<span class=\"token punctuation\">,</span> maxrec<span class=\"token punctuation\">,</span> session<span class=\"token punctuation\">,</span> flags<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">return</span> <span class=\"token operator\">*</span>infected <span class=\"token operator\">?</span> <span class=\"token number\">1</span> <span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span>errors <span class=\"token operator\">?</span> <span class=\"token number\">2</span> <span class=\"token operator\">:</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Reference: <a href=\"https://github.com/kash1064/clamav/blob/rel/0.104/clamdscan/client.c\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">clamav/clamdscan/client.c at rel/0.104 · kash1064/clamav</a></p>\n<h3 id=\"setting-the-scantype\" style=\"position:relative;\"><a href=\"#setting-the-scantype\" aria-label=\"setting the scantype permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setting the scantype</h3>\n<p>Inside this function, two variables, <code class=\"language-text\">scandash</code> and <code class=\"language-text\">remote</code>, are declared first.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">scandash <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>opts<span class=\"token operator\">-></span>filename <span class=\"token operator\">&amp;&amp;</span> opts<span class=\"token operator\">-></span>filename<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">&amp;&amp;</span> <span class=\"token operator\">!</span><span class=\"token function\">strcmp</span><span class=\"token punctuation\">(</span>opts<span class=\"token operator\">-></span>filename<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"-\"</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&amp;&amp;</span> <span class=\"token operator\">!</span><span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"file-list\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled <span class=\"token operator\">&amp;&amp;</span> <span class=\"token operator\">!</span>opts<span class=\"token operator\">-></span>filename<span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nremote <span class=\"token operator\">=</span> <span class=\"token function\">isremote</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">)</span> <span class=\"token operator\">|</span> <span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"stream\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">;</span></code></pre></div>\n<p><code class=\"language-text\">scandash</code> stores the AND of <code class=\"language-text\">(opts->filename &amp;&amp; opts->filename[0] &amp;&amp; !strcmp(opts->filename[0], \"-\")</code> and <code class=\"language-text\">!optget(opts, \"file-list\")->enabled &amp;&amp; !opts->filename[1])</code> for the received <code class=\"language-text\">opts</code>.</p>\n<p>This appears to be a check for whether the <code class=\"language-text\">file-list</code> option is disabled and the input uses <code class=\"language-text\">-</code> (stdin).</p>\n<p>Reference: <a href=\"https://stackoverflow.com/questions/8045479/whats-the-magic-of-a-dash-in-command-line-parameters\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">linux - What’s the magic of ”-” (a dash) in command-line parameters? - Stack Overflow</a></p>\n<p><code class=\"language-text\">remote = isremote(opts) | optget(opts, \"stream\")->enabled;</code> checks whether <code class=\"language-text\">clamdscan</code> is running remotely or whether the Stream option is enabled.</p>\n<p>If either the <code class=\"language-text\">scandash</code> or <code class=\"language-text\">remote</code> flag is true, <code class=\"language-text\">scantype</code> is set to <code class=\"language-text\">STREAM</code>.</p>\n<p>In this case, however, we are using a LocalSocket and the <code class=\"language-text\">--fdpass</code> option, so <code class=\"language-text\">scantype</code> becomes <code class=\"language-text\">FILDES</code> and this branch is skipped.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">ifdef</span> <span class=\"token expression\">HAVE_FD_PASSING</span></span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>remote <span class=\"token operator\">&amp;&amp;</span> <span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>clamdopts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"LocalSocket\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled <span class=\"token operator\">&amp;&amp;</span> <span class=\"token punctuation\">(</span><span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"fdpass\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled <span class=\"token operator\">||</span> scandash<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        scantype <span class=\"token operator\">=</span> FILDES<span class=\"token punctuation\">;</span>\n        session  <span class=\"token operator\">=</span> <span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"multiscan\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">endif</span></span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>remote <span class=\"token operator\">||</span> scandash<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        scantype <span class=\"token operator\">=</span> STREAM<span class=\"token punctuation\">;</span>\n        session  <span class=\"token operator\">=</span> <span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"multiscan\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"multiscan\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">)</span>\n        scantype <span class=\"token operator\">=</span> MULTI<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"allmatch\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">)</span>\n        scantype <span class=\"token operator\">=</span> ALLMATCH<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">else</span>\n        scantype <span class=\"token operator\">=</span> CONT<span class=\"token punctuation\">;</span></code></pre></div>\n<h3 id=\"calling-the-scan-function\" style=\"position:relative;\"><a href=\"#calling-the-scan-function\" aria-label=\"calling the scan function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Calling the Scan Function</h3>\n<p>When <code class=\"language-text\">scandash</code> is false (as in this case), <code class=\"language-text\">client_scan</code> is called directly with the <code class=\"language-text\">scantype</code> and other variables.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token operator\">*</span>infected <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>scandash<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">/* omitted */</span>\n<span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n    errors <span class=\"token operator\">=</span> <span class=\"token function\">client_scan</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"\"</span><span class=\"token punctuation\">,</span> scantype<span class=\"token punctuation\">,</span> infected<span class=\"token punctuation\">,</span> err<span class=\"token punctuation\">,</span> maxrec<span class=\"token punctuation\">,</span> session<span class=\"token punctuation\">,</span> flags<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>   \n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Inside <code class=\"language-text\">client_scan</code>, the absolute path of the target file (<code class=\"language-text\">file</code>) is resolved.</p>\n<p>Based on the received <code class=\"language-text\">session</code> value (<code class=\"language-text\">session = optget(opts, \"multiscan\")->enabled;</code>), either <code class=\"language-text\">serial_client_scan</code> or <code class=\"language-text\">parallel_client_scan</code> is then called.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/* Recursively scans a path with the given scantype\n * Returns non zero for serious errors, zero otherwise */</span>\n<span class=\"token keyword\">static</span> <span class=\"token keyword\">int</span> <span class=\"token function\">client_scan</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>file<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> scantype<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> <span class=\"token operator\">*</span>infected<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> <span class=\"token operator\">*</span>err<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> maxlevel<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> session<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> flags<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">int</span> ret<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>real_path <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>fullpath  <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Convert relative path to fullpath */</span>\n    fullpath <span class=\"token operator\">=</span> <span class=\"token function\">makeabs</span><span class=\"token punctuation\">(</span>file<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Convert fullpath to the real path (evaluating symlinks and . and ..).\n       Doing this early on will ensure that the scan results will appear consistent\n       across regular scans, --fdpass scans, and --stream scans. */</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>CL_SUCCESS <span class=\"token operator\">!=</span> <span class=\"token function\">cli_realpath</span><span class=\"token punctuation\">(</span>fullpath<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>real_path<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"*client_scan: Failed to determine real filename of %s.\\n\"</span><span class=\"token punctuation\">,</span> fullpath<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">free</span><span class=\"token punctuation\">(</span>fullpath<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        fullpath <span class=\"token operator\">=</span> real_path<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>fullpath<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>session<span class=\"token punctuation\">)</span>\n        ret <span class=\"token operator\">=</span> <span class=\"token function\">serial_client_scan</span><span class=\"token punctuation\">(</span>fullpath<span class=\"token punctuation\">,</span> scantype<span class=\"token punctuation\">,</span> infected<span class=\"token punctuation\">,</span> err<span class=\"token punctuation\">,</span> maxlevel<span class=\"token punctuation\">,</span> flags<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">else</span>\n        ret <span class=\"token operator\">=</span> <span class=\"token function\">parallel_client_scan</span><span class=\"token punctuation\">(</span>fullpath<span class=\"token punctuation\">,</span> scantype<span class=\"token punctuation\">,</span> infected<span class=\"token punctuation\">,</span> err<span class=\"token punctuation\">,</span> maxlevel<span class=\"token punctuation\">,</span> flags<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">free</span><span class=\"token punctuation\">(</span>fullpath<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> ret<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>When the <code class=\"language-text\">multiscan</code> option is not used, the file path, <code class=\"language-text\">scantype</code>, and other information are passed to <code class=\"language-text\">serial_client_scan</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/* Non-IDSESSION handler\n * Returns non zero for serious errors, zero otherwise */</span>\n<span class=\"token keyword\">int</span> <span class=\"token function\">serial_client_scan</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>file<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> scantype<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> <span class=\"token operator\">*</span>infected<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> <span class=\"token operator\">*</span>err<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> maxlevel<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> flags<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_ftw_cbdata</span> data<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">client_serial_data</span> cdata<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">int</span> ftw<span class=\"token punctuation\">;</span>\n\n    cdata<span class=\"token punctuation\">.</span>infected <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    cdata<span class=\"token punctuation\">.</span>files    <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    cdata<span class=\"token punctuation\">.</span>errors   <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    cdata<span class=\"token punctuation\">.</span>printok  <span class=\"token operator\">=</span> printinfected <span class=\"token operator\">^</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n    cdata<span class=\"token punctuation\">.</span>scantype <span class=\"token operator\">=</span> scantype<span class=\"token punctuation\">;</span>\n    data<span class=\"token punctuation\">.</span>data      <span class=\"token operator\">=</span> <span class=\"token operator\">&amp;</span>cdata<span class=\"token punctuation\">;</span>\n\n    ftw <span class=\"token operator\">=</span> <span class=\"token function\">cli_ftw</span><span class=\"token punctuation\">(</span>file<span class=\"token punctuation\">,</span> flags<span class=\"token punctuation\">,</span> maxlevel <span class=\"token operator\">?</span> maxlevel <span class=\"token operator\">:</span> INT_MAX<span class=\"token punctuation\">,</span> serial_callback<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>data<span class=\"token punctuation\">,</span> ftw_chkpath<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token operator\">*</span>infected <span class=\"token operator\">+=</span> cdata<span class=\"token punctuation\">.</span>infected<span class=\"token punctuation\">;</span>\n    <span class=\"token operator\">*</span>err <span class=\"token operator\">+=</span> cdata<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>cdata<span class=\"token punctuation\">.</span>errors <span class=\"token operator\">&amp;&amp;</span> <span class=\"token punctuation\">(</span>ftw <span class=\"token operator\">==</span> CL_SUCCESS <span class=\"token operator\">||</span> ftw <span class=\"token operator\">==</span> CL_BREAK<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>cdata<span class=\"token punctuation\">.</span>printok<span class=\"token punctuation\">)</span>\n            <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"~%s: OK\\n\"</span><span class=\"token punctuation\">,</span> file<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>cdata<span class=\"token punctuation\">.</span>files<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"~%s: No files scanned\\n\"</span><span class=\"token punctuation\">,</span> file<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">return</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>A debugger confirms that <code class=\"language-text\">char *file</code> holds the full path of the target file at this point.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/ac4a4477dea0b0a68d8f95a3d75e0e31/25260/image-20250510113743604.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 64.58333333333334%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB7ElEQVQ4y31TWbLbIBDUHVIVSywSIBatdpznLb7/vToNtmPH7yUfXTMgNDPdDZUPAb0PsK6H6z1s399y70s01kHpFnUj0Aj5GVJBtBZCGwipUVlrWMghx97l6NC2HaQUhIQUouRKqZLXdY2meQHXj70cKxd6hGmEHyzipDHMAnHuMY5zmbYPEcMwMPeIZJP3dGfQdh0MGQQyUVwHfhNsWJXpnIWKE/yo4dM3Fv6OYbLo+XPpnqfYbO6TNC8TNgWPMxmVJc3OWDhOEmJC1zl20tjkA0K8QN5iI/7ez+usI/XLeTXOMyIpjVPCuh2x7iY40yFpjZG0LHW0LOaIlrk2Esp5GmH+GJWLCdWVBtX5ckJiwZQcrtcdzpeF64QfhxPW/Uf51hfTbIExpqDt2mJafTelrm+SVMfTATGSbjA4HCYcj3nihHl/xPLzjN1+D+8pfgyUoytua60YZTHhWfDu8kTKnvrFFArdeRl4BwNaGyBbR310oZLpvaN5UNb2dlYoVJKCZh1Pl9s007xg2W45USwO3syRT1O+Ams8GleKOszLjF/XCw7HA9aVBQlDY3pSzTTfaX3G5qmhalukccB2t6PLa7k6aRzLM8yQdLuu//HsvkCVdnwRwwQbZ14Jz4noYnbzDUqxcLnI4r/4DVSLYzz0DOD3AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/ac4a4477dea0b0a68d8f95a3d75e0e31/8ac56/image-20250510113743604.webp 240w,\n/static/ac4a4477dea0b0a68d8f95a3d75e0e31/d3be9/image-20250510113743604.webp 480w,\n/static/ac4a4477dea0b0a68d8f95a3d75e0e31/e46b2/image-20250510113743604.webp 960w,\n/static/ac4a4477dea0b0a68d8f95a3d75e0e31/9bbd4/image-20250510113743604.webp 1113w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/ac4a4477dea0b0a68d8f95a3d75e0e31/8ff5a/image-20250510113743604.png 240w,\n/static/ac4a4477dea0b0a68d8f95a3d75e0e31/e85cb/image-20250510113743604.png 480w,\n/static/ac4a4477dea0b0a68d8f95a3d75e0e31/d9199/image-20250510113743604.png 960w,\n/static/ac4a4477dea0b0a68d8f95a3d75e0e31/25260/image-20250510113743604.png 1113w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/ac4a4477dea0b0a68d8f95a3d75e0e31/d9199/image-20250510113743604.png\"\n            alt=\"image-20250510113743604\"\n            title=\"image-20250510113743604\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Inside this function, a <code class=\"language-text\">client_serial_data</code> struct variable <code class=\"language-text\">cdata</code> is initialized, stored into the <code class=\"language-text\">data</code> member of a <code class=\"language-text\">cli_ftw_cbdata</code> struct variable <code class=\"language-text\">data</code>, and then <code class=\"language-text\">cli_ftw</code> is called with the file information and other arguments.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/* wrap void*, so that we don't mix it with some other pointer */</span>\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_ftw_cbdata</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>data<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">/* Used by serial_callback() */</span>\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">client_serial_data</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">int</span> infected<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">int</span> scantype<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">int</span> printok<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">int</span> files<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">int</span> errors<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_ftw_cbdata</span> data<span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">client_serial_data</span> cdata<span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">int</span> ftw<span class=\"token punctuation\">;</span>\n\ncdata<span class=\"token punctuation\">.</span>infected <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\ncdata<span class=\"token punctuation\">.</span>files    <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\ncdata<span class=\"token punctuation\">.</span>errors   <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\ncdata<span class=\"token punctuation\">.</span>printok  <span class=\"token operator\">=</span> printinfected <span class=\"token operator\">^</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\ncdata<span class=\"token punctuation\">.</span>scantype <span class=\"token operator\">=</span> scantype<span class=\"token punctuation\">;</span>\ndata<span class=\"token punctuation\">.</span>data      <span class=\"token operator\">=</span> <span class=\"token operator\">&amp;</span>cdata<span class=\"token punctuation\">;</span>\n\nftw <span class=\"token operator\">=</span> <span class=\"token function\">cli_ftw</span><span class=\"token punctuation\">(</span>file<span class=\"token punctuation\">,</span> flags<span class=\"token punctuation\">,</span> maxlevel <span class=\"token operator\">?</span> maxlevel <span class=\"token operator\">:</span> INT_MAX<span class=\"token punctuation\">,</span> serial_callback<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>data<span class=\"token punctuation\">,</span> ftw_chkpath<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token operator\">*</span>infected <span class=\"token operator\">+=</span> cdata<span class=\"token punctuation\">.</span>infected<span class=\"token punctuation\">;</span>\n<span class=\"token operator\">*</span>err <span class=\"token operator\">+=</span> cdata<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">;</span></code></pre></div>\n<h3 id=\"executing-the-cli_ftw-function\" style=\"position:relative;\"><a href=\"#executing-the-cli_ftw-function\" aria-label=\"executing the cli_ftw function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Executing the cli_ftw Function</h3>\n<p><code class=\"language-text\">cli_ftw</code> is a function implemented in <code class=\"language-text\">others_common.c</code> in libclamav and performs roughly the following operations.</p>\n<ol>\n<li><code class=\"language-text\">handle_filetype</code> retrieves the file type and checks whether it should be skipped (if the type is <code class=\"language-text\">ft_skipped_link</code> or <code class=\"language-text\">ft_skipped_special</code>, the entry appears to be skipped).</li>\n<li><code class=\"language-text\">ft_skipped</code> checks whether to skip the entry (it appears to be skipped when <code class=\"language-text\">ft != ft_regular &amp;&amp; ft != ft_directory</code> is true).</li>\n<li>For directories, the callback function (in this case <code class=\"language-text\">serial_callback</code>) is called directly; for files, it is called via <code class=\"language-text\">handle_entry</code>.</li>\n</ol>\n<p>Reference: <a href=\"https://github.com/kash1064/clamav/blob/rel/0.104/libclamav/others_common.c\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">clamav/libclamav/others_common.c at rel/0.104 · kash1064/clamav</a></p>\n<p>As described above, when <code class=\"language-text\">clamdscan</code> is invoked with a specific file, the full path of the target file is stored in the <code class=\"language-text\">filename</code> member of a <code class=\"language-text\">dirent_data</code> struct variable <code class=\"language-text\">entry</code>, and then <code class=\"language-text\">handle_entry</code> is called.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/*\n * Now call handle_entry() to either call the callback for files,\n * or recurse deeper into the file tree walk.\n * TODO: Recursion is bad, this whole thing should be iterative\n */</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>entry<span class=\"token punctuation\">.</span>is_dir<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    entry<span class=\"token punctuation\">.</span>dirname <span class=\"token operator\">=</span> path<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">/* Allocate the filename for the callback function within the handle_entry function. TODO: this FTW code is spaghetti, refactor. */</span>\n    filename_for_handleentry <span class=\"token operator\">=</span> <span class=\"token function\">cli_strdup</span><span class=\"token punctuation\">(</span>path<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token constant\">NULL</span> <span class=\"token operator\">==</span> filename_for_handleentry<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">goto</span> done<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    entry<span class=\"token punctuation\">.</span>filename <span class=\"token operator\">=</span> filename_for_handleentry<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\nstatus <span class=\"token operator\">=</span> <span class=\"token function\">handle_entry</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>entry<span class=\"token punctuation\">,</span> flags<span class=\"token punctuation\">,</span> maxdepth<span class=\"token punctuation\">,</span> callback<span class=\"token punctuation\">,</span> data<span class=\"token punctuation\">,</span> pathchk<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Debugging the call to <code class=\"language-text\">handle_entry</code> confirms that the <code class=\"language-text\">filename</code> member holds the full path of <code class=\"language-text\">eicar.com</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token operator\">></span> print *<span class=\"token punctuation\">(</span>struct dirent_data *<span class=\"token punctuation\">)</span>entry\n\n<span class=\"token variable\">$3</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  filename <span class=\"token operator\">=</span> 0x55555559b0c0 <span class=\"token string\">\"/home/kash1064/Downloads/eicar.com\"</span>,\n  <span class=\"token function\">dirname</span> <span class=\"token operator\">=</span> 0x0,\n  statbuf <span class=\"token operator\">=</span> <span class=\"token operator\">&lt;</span>optimized out<span class=\"token operator\">></span>,\n  ino <span class=\"token operator\">=</span> <span class=\"token operator\">&lt;</span>optimized out<span class=\"token operator\">></span>,\n  is_dir <span class=\"token operator\">=</span> <span class=\"token operator\">&lt;</span>optimized out<span class=\"token operator\">></span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><code class=\"language-text\">handle_entry</code> simply calls the callback function (in this case <code class=\"language-text\">serial_callback</code>).</p>\n<p>The fourth argument <code class=\"language-text\">cli_ftw_reason</code> receives <code class=\"language-text\">visit_file</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">static</span> <span class=\"token keyword\">int</span> <span class=\"token function\">handle_entry</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">dirent_data</span> <span class=\"token operator\">*</span>entry<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> flags<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> maxdepth<span class=\"token punctuation\">,</span> cli_ftw_cb callback<span class=\"token punctuation\">,</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_ftw_cbdata</span> <span class=\"token operator\">*</span>data<span class=\"token punctuation\">,</span> cli_ftw_pathchk pathchk<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>entry<span class=\"token operator\">-></span>is_dir<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token function\">callback</span><span class=\"token punctuation\">(</span>entry<span class=\"token operator\">-></span>statbuf<span class=\"token punctuation\">,</span> entry<span class=\"token operator\">-></span>filename<span class=\"token punctuation\">,</span> entry<span class=\"token operator\">-></span>filename<span class=\"token punctuation\">,</span> visit_file<span class=\"token punctuation\">,</span> data<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token function\">cli_ftw_dir</span><span class=\"token punctuation\">(</span>entry<span class=\"token operator\">-></span>dirname<span class=\"token punctuation\">,</span> flags<span class=\"token punctuation\">,</span> maxdepth<span class=\"token punctuation\">,</span> callback<span class=\"token punctuation\">,</span> data<span class=\"token punctuation\">,</span> pathchk<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h3 id=\"calling-serial_callback\" style=\"position:relative;\"><a href=\"#calling-serial_callback\" aria-label=\"calling serial_callback permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Calling serial_callback</h3>\n<p><code class=\"language-text\">serial_callback</code> is implemented in <code class=\"language-text\">clamdscan/proto.c</code> and was passed as the callback function when <code class=\"language-text\">cli_ftw</code> was called from <code class=\"language-text\">serial_client_scan</code>.</p>\n<p>Reference: <a href=\"https://github.com/kash1064/clamav/blob/rel/0.104/clamdscan/proto.c\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">clamav/clamdscan/proto.c at rel/0.104 · kash1064/clamav</a></p>\n<p>After performing several checks, <code class=\"language-text\">dconnect</code> connects to the <code class=\"language-text\">clamd</code> daemon, and <code class=\"language-text\">dsresult</code> issues a scan request over the obtained socket.</p>\n<p><code class=\"language-text\">dsresult</code> returns the number of infected files as an integer.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>sockd <span class=\"token operator\">=</span> <span class=\"token function\">dconnect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    c<span class=\"token operator\">-></span>errors<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">goto</span> done<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\nret <span class=\"token operator\">=</span> <span class=\"token function\">dsresult</span><span class=\"token punctuation\">(</span>sockd<span class=\"token punctuation\">,</span> c<span class=\"token operator\">-></span>scantype<span class=\"token punctuation\">,</span> f<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>c<span class=\"token operator\">-></span>printok<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>c<span class=\"token operator\">-></span>errors<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">closesocket</span><span class=\"token punctuation\">(</span>sockd<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>ret <span class=\"token operator\">&lt;</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    c<span class=\"token operator\">-></span>errors<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">goto</span> done<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\nc<span class=\"token operator\">-></span>infected <span class=\"token operator\">+=</span> ret<span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>reason <span class=\"token operator\">==</span> visit_directory_toplev<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    status <span class=\"token operator\">=</span> CL_BREAK<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">goto</span> done<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Debugging the <code class=\"language-text\">dsresult</code> call confirms that the first argument <code class=\"language-text\">sockd</code> is 3 and the third argument <code class=\"language-text\">filename</code> holds the path of the target file.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/13661d06eff46bf754a1e5e370c55b5a/1cfc2/image-20250510140110609.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 15%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAAAsTAAALEwEAmpwYAAAApUlEQVQI102OWQ7CMAxEewggCQlkcVKWQgsI1Puf7OHwxcfT2JY1M0Oqmdv6YF6flHMljVlVkGmkTA0fjxzihph3ZGMpzmKNwSjOOaySvOfk9xxVh+1mi5TC5ToR0kjIJ9WGs45Wq94vtDYiUpFWySIU/Y8pYq39mRrVndL3oScVfVoeN17vOx9t+1kXRM2uajYvMzknvKYfQiAoffbaqBv0hu6PLwg/Un2w4m2cAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/13661d06eff46bf754a1e5e370c55b5a/8ac56/image-20250510140110609.webp 240w,\n/static/13661d06eff46bf754a1e5e370c55b5a/d3be9/image-20250510140110609.webp 480w,\n/static/13661d06eff46bf754a1e5e370c55b5a/131f1/image-20250510140110609.webp 900w\"\n              sizes=\"(max-width: 900px) 100vw, 900px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/13661d06eff46bf754a1e5e370c55b5a/8ff5a/image-20250510140110609.png 240w,\n/static/13661d06eff46bf754a1e5e370c55b5a/e85cb/image-20250510140110609.png 480w,\n/static/13661d06eff46bf754a1e5e370c55b5a/1cfc2/image-20250510140110609.png 900w\"\n            sizes=\"(max-width: 900px) 100vw, 900px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/13661d06eff46bf754a1e5e370c55b5a/1cfc2/image-20250510140110609.png\"\n            alt=\"image-20250510140110609\"\n            title=\"image-20250510140110609\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p><code class=\"language-text\">sockd</code> is the file descriptor of the socket obtained inside <code class=\"language-text\">dconnect</code> via <code class=\"language-text\">sockd = socket(AF_UNIX, SOCK_STREAM, 0)</code> when using LocalSocket mode.</p>\n<p>This can be confirmed by running <code class=\"language-text\">ls -la /proc/$(pgrep clamdscan)/fd/</code> or <code class=\"language-text\">lsof -p $(pgrep clamdscan)</code> to verify that <code class=\"language-text\">clamdscan</code> has the socket open using that file descriptor.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/4e0c06538bb7f485e2210bb40f714806/8a69d/image-20250510141238201.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 60%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAABwUlEQVQoz3WSy1KDQBBF+QfzRl4hwAwwZHiloq5d6EY/xLULf/7ad5JQVCwXXUzRPadv91zPDBbKVihMCW076KPFITsgL3IURYEoiuD7jwiCALvdDpvNBtvtdvreh6eUQhRGMHUNaxsXVV2hNjUOuUBVjo/PN5SVwsPDQqB/IXO4VzU1kjSBEVA3DOhPI472iObYQFclXp7P+Pn+wsf7K0JRycvz+KOwfxrRjBaVNWj6EWVjobVCekgRxzEqgRaitJRJeM65hji6hKyDkPV6PTXwuq51itrWou87ZLI/7i4IAyyXS/fN8swp5iqY06WeYr/fu/36vo/tjgqHHlZgrYB5VlpLKNedncMohGmMyw2nwUE7acw7FNL1rTuXop5w75a8AfUVGIYhVquV+7J4DrzB2Ij3qJ5TUKUDMskingnjy09AUViIhZgbxsHtcQKKE9r+AuS9NE3vFV6B+g6oCjcaa8oZkCD+o1L6lj79d+RphwKmJ0/nk1NIIGvnYYxBnMTXV74bmZ04Ml9usViIdSL3srexCGR9TtNLLXfHx6CN6AhvFCMTRHU8J/vE2YFQwqmAnsyyy0XCWEs1nGDuQcYv3qRewMfwybkAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/4e0c06538bb7f485e2210bb40f714806/8ac56/image-20250510141238201.webp 240w,\n/static/4e0c06538bb7f485e2210bb40f714806/d3be9/image-20250510141238201.webp 480w,\n/static/4e0c06538bb7f485e2210bb40f714806/e46b2/image-20250510141238201.webp 960w,\n/static/4e0c06538bb7f485e2210bb40f714806/69abc/image-20250510141238201.webp 1209w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/4e0c06538bb7f485e2210bb40f714806/8ff5a/image-20250510141238201.png 240w,\n/static/4e0c06538bb7f485e2210bb40f714806/e85cb/image-20250510141238201.png 480w,\n/static/4e0c06538bb7f485e2210bb40f714806/d9199/image-20250510141238201.png 960w,\n/static/4e0c06538bb7f485e2210bb40f714806/8a69d/image-20250510141238201.png 1209w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/4e0c06538bb7f485e2210bb40f714806/d9199/image-20250510141238201.png\"\n            alt=\"image-20250510141238201\"\n            title=\"image-20250510141238201\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Inside <code class=\"language-text\">dsresult</code>, after initializing several struct variables, a request is sent to <code class=\"language-text\">clamd</code> according to the value of <code class=\"language-text\">scantype</code>.</p>\n<p>In this case, with the <code class=\"language-text\">--fdpass</code> option and <code class=\"language-text\">scantype</code> set to <code class=\"language-text\">FILDES</code>, <code class=\"language-text\">len = send_fdpass(sockd, filename);</code> is called first.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">switch</span> <span class=\"token punctuation\">(</span>scantype<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">case</span> MULTI<span class=\"token operator\">:</span>\n    <span class=\"token keyword\">case</span> CONT<span class=\"token operator\">:</span>\n    <span class=\"token keyword\">case</span> ALLMATCH<span class=\"token operator\">:</span>\n        <span class=\"token comment\">/* omitted */</span>\n    <span class=\"token keyword\">case</span> STREAM<span class=\"token operator\">:</span>\n        <span class=\"token comment\">/* omitted */</span>\n\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">ifdef</span> <span class=\"token expression\">HAVE_FD_PASSING</span></span>\n    <span class=\"token keyword\">case</span> FILDES<span class=\"token operator\">:</span>\n        <span class=\"token comment\">/* NULL filename safe in send_fdpass() */</span>\n        len <span class=\"token operator\">=</span> <span class=\"token function\">send_fdpass</span><span class=\"token punctuation\">(</span>sockd<span class=\"token punctuation\">,</span> filename<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">endif</span></span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>In <code class=\"language-text\">send_fdpass</code>, the file descriptor of the scan target — obtained via <code class=\"language-text\">fd = open(filename, O_RDONLY)</code> — is sent to <code class=\"language-text\">clamd</code> using the <code class=\"language-text\">sendmsg</code> system call.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">iov<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span>iov_base <span class=\"token operator\">=</span> dummy<span class=\"token punctuation\">;</span>\niov<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span>iov_len  <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">memset</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>msg<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>msg<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nmsg<span class=\"token punctuation\">.</span>msg_control         <span class=\"token operator\">=</span> fdbuf<span class=\"token punctuation\">;</span>\nmsg<span class=\"token punctuation\">.</span>msg_iov             <span class=\"token operator\">=</span> iov<span class=\"token punctuation\">;</span>\nmsg<span class=\"token punctuation\">.</span>msg_iovlen          <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\nmsg<span class=\"token punctuation\">.</span>msg_controllen      <span class=\"token operator\">=</span> <span class=\"token function\">CMSG_LEN</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\ncmsg                    <span class=\"token operator\">=</span> <span class=\"token function\">CMSG_FIRSTHDR</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>msg<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\ncmsg<span class=\"token operator\">-></span>cmsg_len          <span class=\"token operator\">=</span> <span class=\"token function\">CMSG_LEN</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\ncmsg<span class=\"token operator\">-></span>cmsg_level        <span class=\"token operator\">=</span> SOL_SOCKET<span class=\"token punctuation\">;</span>\ncmsg<span class=\"token operator\">-></span>cmsg_type         <span class=\"token operator\">=</span> SCM_RIGHTS<span class=\"token punctuation\">;</span>\n<span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">CMSG_DATA</span><span class=\"token punctuation\">(</span>cmsg<span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> fd<span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">sendmsg</span><span class=\"token punctuation\">(</span>sockd<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>msg<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> <span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"!FD send failed: %s\\n\"</span><span class=\"token punctuation\">,</span> <span class=\"token function\">strerror</span><span class=\"token punctuation\">(</span>errno<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">close</span><span class=\"token punctuation\">(</span>fd<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h2 id=\"debugging-clamd\" style=\"position:relative;\"><a href=\"#debugging-clamd\" aria-label=\"debugging clamd permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Debugging clamd</h2>\n<p>First, compile ClamAV components including <code class=\"language-text\">clamd</code> as a Debug build using the following commands, following the steps described in <a href=\"/clamav-note01#%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E3%81%A8-systemd-%E3%82%92%E6%9C%89%E5%8A%B9%E5%8C%96%E3%81%97%E3%81%A6%E5%86%8D%E3%83%93%E3%83%AB%E3%83%89%E3%81%99%E3%82%8B\">Building ClamAV from Source and Setting Up OnAccessScan</a>.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">cmake <span class=\"token punctuation\">..</span> <span class=\"token punctuation\">\\</span>\n    -D <span class=\"token assign-left variable\">CMAKE_BUILD_TYPE</span><span class=\"token operator\">=</span>Debug <span class=\"token punctuation\">\\</span>\n    -D <span class=\"token assign-left variable\">OPTIMIZE</span><span class=\"token operator\">=</span>OFF <span class=\"token punctuation\">\\</span>\n    -D <span class=\"token assign-left variable\">ENABLE_EXAMPLES</span><span class=\"token operator\">=</span>OFF <span class=\"token punctuation\">\\</span>\n    -D <span class=\"token assign-left variable\">ENABLE_STATIC_LIB</span><span class=\"token operator\">=</span>ON <span class=\"token punctuation\">\\</span>\n    -D <span class=\"token assign-left variable\">ENABLE_SYSTEMD</span><span class=\"token operator\">=</span>ON\n\ncmake --build <span class=\"token builtin class-name\">.</span> --target <span class=\"token function\">install</span></code></pre></div>\n<p>Running <code class=\"language-text\">clamd</code> and attaching with <code class=\"language-text\">gdb -p $(pgrep clamd)</code>, the following debug output is produced when a scan is triggered by <code class=\"language-text\">clamdscan</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">Sat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$Got</span> new connection, FD <span class=\"token number\">12</span>\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$Received</span> POLLIN<span class=\"token operator\">|</span>POLLHUP on fd <span class=\"token number\">6</span>\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$fds_poll_recv</span><span class=\"token builtin class-name\">:</span> <span class=\"token function\">timeout</span> after <span class=\"token number\">30</span> seconds\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$Received</span> POLLIN<span class=\"token operator\">|</span>POLLHUP on fd <span class=\"token number\">12</span>\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$Receveived</span> a <span class=\"token function\">file</span> descriptor: <span class=\"token number\">13</span>\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$got</span> <span class=\"token builtin class-name\">command</span> FILDES <span class=\"token punctuation\">(</span><span class=\"token number\">7</span>, <span class=\"token number\">9</span><span class=\"token punctuation\">)</span>, argument:\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$RECVTH</span><span class=\"token builtin class-name\">:</span> FILDES <span class=\"token builtin class-name\">command</span> complete\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$mode</span> -<span class=\"token operator\">></span> MODE_WAITREPLY\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$Breaking</span> <span class=\"token builtin class-name\">command</span> loop, mode is no longer MODE_COMMAND\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$Consumed</span> entire <span class=\"token builtin class-name\">command</span>\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$Number</span> of <span class=\"token function\">file</span> descriptors polled: <span class=\"token number\">1</span> fds\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$fds_poll_recv</span><span class=\"token builtin class-name\">:</span> <span class=\"token function\">timeout</span> after <span class=\"token number\">600</span> seconds\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$THRMGR</span><span class=\"token builtin class-name\">:</span> queue <span class=\"token punctuation\">(</span>single<span class=\"token punctuation\">)</span> crossed low threshold -<span class=\"token operator\">></span> signaling\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$THRMGR</span><span class=\"token builtin class-name\">:</span> queue <span class=\"token punctuation\">(</span>bulk<span class=\"token punctuation\">)</span> crossed low threshold -<span class=\"token operator\">></span> signaling\nLibClamAV debug: cli_get_filepath_from_filedesc: File path <span class=\"token keyword\">for</span> fd <span class=\"token punctuation\">[</span><span class=\"token number\">13</span><span class=\"token punctuation\">]</span> is: /home/kash1064/Downloads/eicar.com\nLibClamAV debug: Recognized ASCII text\nLibClamAV debug: cache_check: 44d88612fea8a8f36de82e1278abb02f is negative\nLibClamAV debug: matcher_run: performing regex matching on full map: <span class=\"token number\">0</span>+68<span class=\"token punctuation\">(</span><span class=\"token number\">68</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>=</span> <span class=\"token number\">68</span>\nLibClamAV debug: FP SIGNATURE: 44d88612fea8a8f36de82e1278abb02f:68:Win.Test.EICAR_HDB-1\nLibClamAV debug: hashtab: Freeing hashset, elements: <span class=\"token number\">0</span>, capacity: <span class=\"token number\">0</span>\nLibClamAV debug: Win.Test.EICAR_HDB-1 found\nLibClamAV debug: cli_magic_scan_desc: returning <span class=\"token number\">1</span>  at line <span class=\"token number\">4605</span>\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> /home/kash1064/Downloads/eicar.com: Win.Test.EICAR_HDB-1<span class=\"token punctuation\">(</span>44d88612fea8a8f36de82e1278abb02f:68<span class=\"token punctuation\">)</span> FOUND\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$Closed</span> fd <span class=\"token number\">13</span>\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$Finished</span> scanthread\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$Scanthread</span><span class=\"token builtin class-name\">:</span> connection shut down <span class=\"token punctuation\">(</span>FD <span class=\"token number\">12</span><span class=\"token punctuation\">)</span>\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$THRMGR</span><span class=\"token builtin class-name\">:</span> queue <span class=\"token punctuation\">(</span>single<span class=\"token punctuation\">)</span> crossed low threshold -<span class=\"token operator\">></span> signaling\nSat May <span class=\"token number\">10</span> 06:59:27 <span class=\"token number\">2025</span> -<span class=\"token operator\">></span> <span class=\"token variable\">$THRMGR</span><span class=\"token builtin class-name\">:</span> queue <span class=\"token punctuation\">(</span>bulk<span class=\"token punctuation\">)</span> crossed low threshold -<span class=\"token operator\">></span> signaling</code></pre></div>\n<p>From this output we can see that functions such as <code class=\"language-text\">cli_get_filepath_from_filedesc</code>, implemented in <code class=\"language-text\">clamd</code>’s <code class=\"language-text\">scanner.c</code>, are being called.</p>\n<p>Reference: <a href=\"https://github.com/kash1064/clamav/blob/rel/0.104/clamd/scanner.c\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">clamav/clamd/scanner.c at rel/0.104 · kash1064/clamav</a></p>\n<h3 id=\"retrieving-the-file-path-on-the-clamd-side\" style=\"position:relative;\"><a href=\"#retrieving-the-file-path-on-the-clamd-side\" aria-label=\"retrieving the file path on the clamd side permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Retrieving the File Path on the clamd Side</h3>\n<p>The <code class=\"language-text\">cli_get_filepath_from_filedesc</code> function called here uses the <code class=\"language-text\">readlink</code> system call on the received file descriptor to obtain the full path of the scan target and stores it in <code class=\"language-text\">fname</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">char</span> fname<span class=\"token punctuation\">[</span>PATH_MAX<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">char</span> link<span class=\"token punctuation\">[</span><span class=\"token number\">32</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token function\">memset</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>fname<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> PATH_MAX<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token function\">snprintf</span><span class=\"token punctuation\">(</span>link<span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>link<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"/proc/self/fd/%u\"</span><span class=\"token punctuation\">,</span> desc<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nlink<span class=\"token punctuation\">[</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>link<span class=\"token punctuation\">)</span> <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token char\">'\\0'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">-</span><span class=\"token number\">1</span> <span class=\"token operator\">==</span> <span class=\"token punctuation\">(</span>linksz <span class=\"token operator\">=</span> <span class=\"token function\">readlink</span><span class=\"token punctuation\">(</span>link<span class=\"token punctuation\">,</span> fname<span class=\"token punctuation\">,</span> PATH_MAX <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">cli_dbgmsg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"cli_get_filepath_from_filedesc: Failed to resolve filename for descriptor %d (%s)\\n\"</span><span class=\"token punctuation\">,</span> desc<span class=\"token punctuation\">,</span> link<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    status <span class=\"token operator\">=</span> CL_EOPEN<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">goto</span> done<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The obtained file path is then saved as <code class=\"language-text\">evaluated_filepath</code> and assigned to the <code class=\"language-text\">filepath</code> argument received by the function.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token function\">cli_dbgmsg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"cli_get_filepath_from_filedesc: File path for fd [%d] is: %s\\n\"</span><span class=\"token punctuation\">,</span> desc<span class=\"token punctuation\">,</span> evaluated_filepath<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nstatus    <span class=\"token operator\">=</span> CL_SUCCESS<span class=\"token punctuation\">;</span>\n<span class=\"token operator\">*</span>filepath <span class=\"token operator\">=</span> evaluated_filepath<span class=\"token punctuation\">;</span></code></pre></div>\n<p>Tracing this function’s return in the debugger revealed that it is called from the <code class=\"language-text\">scanfd</code> function in <code class=\"language-text\">scanner.c</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/* Try and get the real filename, for logging purposes */</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>stream<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>CL_SUCCESS <span class=\"token operator\">!=</span> <span class=\"token function\">cli_get_filepath_from_filedesc</span><span class=\"token punctuation\">(</span>fd<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>filepath<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"*%s: Unable to determine the filepath given the file descriptor.\\n\"</span><span class=\"token punctuation\">,</span> fdstr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n        log_filename <span class=\"token operator\">=</span> filepath<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Reference: <a href=\"https://github.com/kash1064/clamav/blob/rel/0.104/clamd/scanner.c\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">clamav/clamd/scanner.c at rel/0.104 · kash1064/clamav</a></p>\n<h3 id=\"executing-the-scan-callback-function\" style=\"position:relative;\"><a href=\"#executing-the-scan-callback-function\" aria-label=\"executing the scan callback function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Executing the Scan Callback Function</h3>\n<p>The file path obtained from the file descriptor is saved as <code class=\"language-text\">log_filename</code> and then passed to the <code class=\"language-text\">cl_scandesc_callback</code> function.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token function\">thrmgr_setactivetask</span><span class=\"token punctuation\">(</span>fdstr<span class=\"token punctuation\">,</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\ncontext<span class=\"token punctuation\">.</span>filename <span class=\"token operator\">=</span> fdstr<span class=\"token punctuation\">;</span>\ncontext<span class=\"token punctuation\">.</span>virsize  <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\ncontext<span class=\"token punctuation\">.</span>scandata <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span>\nret              <span class=\"token operator\">=</span> <span class=\"token function\">cl_scandesc_callback</span><span class=\"token punctuation\">(</span>fd<span class=\"token punctuation\">,</span> log_filename<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>virname<span class=\"token punctuation\">,</span> scanned<span class=\"token punctuation\">,</span> engine<span class=\"token punctuation\">,</span> options<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>context<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">thrmgr_setactivetask</span><span class=\"token punctuation\">(</span><span class=\"token constant\">NULL</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">thrmgr_group_need_terminate</span><span class=\"token punctuation\">(</span>conn<span class=\"token operator\">-></span>group<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"*Client disconnected while scanjob was active\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    ret <span class=\"token operator\">=</span> ret <span class=\"token operator\">==</span> CL_ETIMEOUT <span class=\"token operator\">?</span> ret <span class=\"token operator\">:</span> CL_BREAK<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">goto</span> done<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>In the code above, <code class=\"language-text\">thrmgr_setactivetask</code> registers <code class=\"language-text\">fdstr</code> and <code class=\"language-text\">context</code> is initialized before calling <code class=\"language-text\">cl_scandesc_callback</code>. The function then receives the file descriptor and file path to perform the actual scan.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/**\n * @brief Scan a file, given a file descriptor.\n *\n * This callback variant allows the caller to provide a context structure that caller provided callback functions can interpret.\n *\n * @param desc              File descriptor of an open file. The caller must provide this or the map.\n * @param filename          (optional) Filepath of the open file descriptor or file map.\n * @param[out] virname      Will be set to a statically allocated (i.e. needs not be freed) signature name if the scan matches against a signature.\n * @param[out] scanned      The number of bytes scanned.\n * @param engine            The scanning engine.\n * @param scanoptions       Scanning options.\n * @param[in,out] context   An opaque context structure allowing the caller to record details about the sample being scanned.\n * @return cl_error_t       CL_CLEAN, CL_VIRUS, or an error code if an error occured during the scan.\n */</span>\n<span class=\"token keyword\">extern</span> <span class=\"token class-name\">cl_error_t</span> <span class=\"token function\">cl_scandesc_callback</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> desc<span class=\"token punctuation\">,</span> <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>filename<span class=\"token punctuation\">,</span> <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span>virname<span class=\"token punctuation\">,</span> <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span> <span class=\"token keyword\">int</span> <span class=\"token operator\">*</span>scanned<span class=\"token punctuation\">,</span> <span class=\"token keyword\">const</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cl_engine</span> <span class=\"token operator\">*</span>engine<span class=\"token punctuation\">,</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cl_scan_options</span> <span class=\"token operator\">*</span>scanoptions<span class=\"token punctuation\">,</span> <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>context<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p><code class=\"language-text\">cl_scandesc_callback</code> is implemented in libclamav’s <code class=\"language-text\">scanner.c</code>.</p>\n<p>Inside this function, <code class=\"language-text\">cli_basename</code> extracts the filename from the received file path as <code class=\"language-text\">filename_base</code>, and <code class=\"language-text\">fmap</code> maps the file as a <code class=\"language-text\">fmap_t</code> structure used for ClamAV file scanning.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token constant\">NULL</span> <span class=\"token operator\">!=</span> filename<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token punctuation\">)</span><span class=\"token function\">cli_basename</span><span class=\"token punctuation\">(</span>filename<span class=\"token punctuation\">,</span> <span class=\"token function\">strlen</span><span class=\"token punctuation\">(</span>filename<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>filename_base<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token constant\">NULL</span> <span class=\"token operator\">==</span> <span class=\"token punctuation\">(</span>map <span class=\"token operator\">=</span> <span class=\"token function\">fmap</span><span class=\"token punctuation\">(</span>desc<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> sb<span class=\"token punctuation\">.</span>st_size<span class=\"token punctuation\">,</span> filename_base<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">cli_errmsg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"CRITICAL: fmap() failed\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    status <span class=\"token operator\">=</span> CL_EMEM<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">goto</span> done<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\nstatus <span class=\"token operator\">=</span> <span class=\"token function\">scan_common</span><span class=\"token punctuation\">(</span>map<span class=\"token punctuation\">,</span> filename<span class=\"token punctuation\">,</span> virname<span class=\"token punctuation\">,</span> scanned<span class=\"token punctuation\">,</span> engine<span class=\"token punctuation\">,</span> scanoptions<span class=\"token punctuation\">,</span> context<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Reference: <a href=\"https://github.com/kash1064/clamav/blob/rel/0.104/libclamav/scanners.c\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">clamav/libclamav/scanners.c at rel/0.104 · kash1064/clamav</a></p>\n<p>The mapped structure is passed together with the file path and other information to <code class=\"language-text\">scan_common</code>, where the actual virus scan is performed.</p>\n<h2 id=\"about-the-fmap_t-structure\" style=\"position:relative;\"><a href=\"#about-the-fmap_t-structure\" aria-label=\"about the fmap_t structure permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>About the fmap_t Structure</h2>\n<p>ClamAV uses the <code class=\"language-text\">cl_fmap_t</code> (<code class=\"language-text\">fmap_t</code>) data structure to perform memory mapping for efficient file scanning.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">struct</span> <span class=\"token class-name\">cl_fmap</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">typedef</span> <span class=\"token class-name\">cl_fmap_t</span> <span class=\"token class-name\">fmap_t</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">cl_fmap</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">/* handle interface */</span>\n    <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>handle<span class=\"token punctuation\">;</span>\n    clcb_pread pread_cb<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* internal */</span>\n    <span class=\"token class-name\">time_t</span> mtime<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint64_t</span> pages<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint64_t</span> pgsz<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint64_t</span> paged<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint16_t</span> aging<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint16_t</span> dont_cache_flag<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint16_t</span> handle_is_fd<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* memory interface */</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>data<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* common interface */</span>\n    <span class=\"token class-name\">size_t</span> offset<span class=\"token punctuation\">;</span>        <span class=\"token comment\">/* file offset */</span>\n    <span class=\"token class-name\">size_t</span> nested_offset<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* buffer offset for nested scan*/</span>\n    <span class=\"token class-name\">size_t</span> real_len<span class=\"token punctuation\">;</span>      <span class=\"token comment\">/* amount of data mapped from file, starting at offset */</span>\n    <span class=\"token class-name\">size_t</span> len<span class=\"token punctuation\">;</span>           <span class=\"token comment\">/* length of data accessible via current fmap */</span>\n\n    <span class=\"token comment\">/* real_len = nested_offset + len\n     * file_offset = offset + nested_offset + need_offset\n     * maximum offset, length accessible via fmap API: len\n     * offset in cached buffer: nested_offset + need_offset\n     *\n     * This allows scanning a portion of an already mapped file without dumping\n     * to disk and remapping (for uncompressed archives for example) */</span>\n\n    <span class=\"token comment\">/* vtable for implementation */</span>\n    <span class=\"token keyword\">void</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>unmap<span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">fmap_t</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>need<span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">fmap_t</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">size_t</span> at<span class=\"token punctuation\">,</span> <span class=\"token class-name\">size_t</span> len<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> lock<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>need_offstr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">fmap_t</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">size_t</span> at<span class=\"token punctuation\">,</span> <span class=\"token class-name\">size_t</span> len_hint<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>gets<span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">fmap_t</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>dst<span class=\"token punctuation\">,</span> <span class=\"token class-name\">size_t</span> <span class=\"token operator\">*</span>at<span class=\"token punctuation\">,</span> <span class=\"token class-name\">size_t</span> max_len<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">void</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>unneed_off<span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">fmap_t</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">size_t</span> at<span class=\"token punctuation\">,</span> <span class=\"token class-name\">size_t</span> len<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">ifdef</span> <span class=\"token expression\">_WIN32</span></span>\n    HANDLE fh<span class=\"token punctuation\">;</span>\n    HANDLE mh<span class=\"token punctuation\">;</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">endif</span></span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">char</span> maphash<span class=\"token punctuation\">[</span><span class=\"token number\">16</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint64_t</span> <span class=\"token operator\">*</span>bitmap<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>name<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h3 id=\"file-mapping-process\" style=\"position:relative;\"><a href=\"#file-mapping-process\" aria-label=\"file mapping process permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>File Mapping Process</h3>\n<p>For a <code class=\"language-text\">clamdscan</code> request such as this one, the scan target file is mapped into memory as a <code class=\"language-text\">fmap_t</code> structure by the <code class=\"language-text\">fmap_check_empty</code> function.</p>\n<p>Reference: <a href=\"https://github.com/kash1064/clamav/blob/rel/0.104/libclamav/fmap.c\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">clamav/libclamav/fmap.c at rel/0.104 · kash1064/clamav</a></p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token class-name\">fmap_t</span> <span class=\"token operator\">*</span><span class=\"token function\">fmap_check_empty</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> fd<span class=\"token punctuation\">,</span> <span class=\"token class-name\">off_t</span> offset<span class=\"token punctuation\">,</span> <span class=\"token class-name\">size_t</span> len<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> <span class=\"token operator\">*</span>empty<span class=\"token punctuation\">,</span> <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>name<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    STATBUF st<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">fmap_t</span> <span class=\"token operator\">*</span>m <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token operator\">*</span>empty <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">FSTAT</span><span class=\"token punctuation\">(</span>fd<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>st<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">cli_warnmsg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"fmap: fstat failed\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>len<span class=\"token punctuation\">)</span> len <span class=\"token operator\">=</span> st<span class=\"token punctuation\">.</span>st_size <span class=\"token operator\">-</span> offset<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* bound checked later */</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>len<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">cli_dbgmsg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"fmap: attempted void mapping\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token operator\">*</span>empty <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span><span class=\"token function\">CLI_ISCONTAINED</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> st<span class=\"token punctuation\">.</span>st_size<span class=\"token punctuation\">,</span> offset<span class=\"token punctuation\">,</span> len<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">cli_warnmsg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"fmap: attempted oof mapping\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    m <span class=\"token operator\">=</span> <span class=\"token function\">cl_fmap_open_handle</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">ssize_t</span><span class=\"token punctuation\">)</span>fd<span class=\"token punctuation\">,</span> offset<span class=\"token punctuation\">,</span> len<span class=\"token punctuation\">,</span> pread_cb<span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>m<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span>\n    m<span class=\"token operator\">-></span>mtime <span class=\"token operator\">=</span> st<span class=\"token punctuation\">.</span>st_mtime<span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token constant\">NULL</span> <span class=\"token operator\">!=</span> name<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        m<span class=\"token operator\">-></span>name <span class=\"token operator\">=</span> <span class=\"token function\">cli_strdup</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token constant\">NULL</span> <span class=\"token operator\">==</span> m<span class=\"token operator\">-></span>name<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token function\">funmap</span><span class=\"token punctuation\">(</span>m<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            <span class=\"token keyword\">return</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">return</span> m<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>This function first uses <code class=\"language-text\">fstat</code> to store the state of the received file descriptor into a <code class=\"language-text\">STATBUF</code> struct (<code class=\"language-text\">stat</code> or <code class=\"language-text\">stat64</code>) variable <code class=\"language-text\">st</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">STATBUF st<span class=\"token punctuation\">;</span>\n<span class=\"token class-name\">fmap_t</span> <span class=\"token operator\">*</span>m <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token operator\">*</span>empty <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">FSTAT</span><span class=\"token punctuation\">(</span>fd<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>st<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">cli_warnmsg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"fmap: fstat failed\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>For the <code class=\"language-text\">eicar.com</code> file being scanned, <code class=\"language-text\">fstat</code> wrote the following information into <code class=\"language-text\">st</code>.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 332px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/e3fe831fe2e157b0bd46d21f44c20410/f8dc5/image-20250511102959585.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 179.16666666666669%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAkCAYAAACJ8xqgAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEGElEQVRIx41WaZraWAzkDMOO993GYBazG5J0T0++ucDc/yiaKtkQukPAP4SXbteTVKV6r1N838rqn6NU//2U8t9KvNCX1Xol5aaUxaKQaT6VxXIhw+FQxuPxy+gc386yqfYSzVIpDmvxA19c1xXHccQ0TQ3btmU0GrUDXBSFFIuFGBNDgjAUx/du2RDUdmx9vgK+Au4Men1xpql4eSZpdRC/mImDDKMolMv3i1TnSrO8B3sG2pngx0ef3DTRa7AsNLMwCOR4Osrb329yOp8kSZJWfeyMsRqz8gAWb9YSb9cSLuZaeogWzOYzsSxLo1XJBPRmyDBLJVwtNOJdKS4yDHxf0jRFCxwxDKNdyePRWLxppj1khtn5KP4sFwsAGd5Xl0rOlzOIK9qXrBmihwFKDZChFwYqld1hpz30kekVrFXJflNytF4qqA+GCbg/7uXj54eEeL7P7iXLThor4PRbJcl+Ky4ycqC/VbmS7W77KcOXJU8mE10xANMEZA9dMJxhgSzLpNvtthb1rWRqj4DsY3rai9OUTCKoybbl/iIFDDtJrFqMwDR7akN382Ku0ev1ZDAYtJVNDcjs4m0JDW7Ey2rt0WlWIMqyLYnjSMX9CrRhOYcWU0kOW4nKJWKF+53YBMEcr8u1sr2EpNrJZp5rVhnMgWDZqb4yoxyLMbt+vy8k8P7jR+A3YbNsjh2BQpBB6Vy9kW7DHl7jmZ3VOkyiepYbYROYpQaYZwIyU8/zbvHVKO5BOxPM7AAsmp5bTwzIIdM2zRXSYcm7/U7eP97VGxnsqW1bj0tWQJRhoTxmRqOYXk7oK3QJUBrE5dtZfrz/kP1hD6OoVJ9/ZJmN5ocG9w9kaWDkKGzes7/XcumNHEEGe3oP+Klk/sTonwXQiWWKgTKZNXtLD+TfScJ9PNPizbEpHeow2W8kQukOMouiWsxXZv8E+hspQ/YQhvCZFFvnmKRwj6Yvlni/gxvRJ7+W/RCQkqknZgfgWJyGZRLjYhS5AGXEnl5d6iEpBsLkP2J2HUwFZ5psm6ahZXOuOSmtSuZPAqch6IAfcRq6Pb3ef8yF7+MpKSH80MfokRxmF8CySAqlQqZpX7fAYl9N9zMpXBFyofbUdQCspKB/7FUCkvI81wMUD08kaINFTesZKSjV4uhBOrpZAdCBgAlKT+SEkOUtGD5WR50a9vXRPvOL5fvRw95CxsksHYejdoCl8cpMN9vNTfRf7UxLpt9xMoYNKSMSgaBp8N1oMJT+X91bRmScHw/69bZwfb6xrPoCKMlhZjY3+qanbAOlxOxt11GXYabXdnCS+MwrF+yot0Fv/JBHES0VRHDT0rMOFtHpoYMDhEA80XKSKHg+cyPjVQH5ktJR3eGsyPOi3lOPvG+eWf6o0WQt8scl/w+6Htz3oRlWsQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/e3fe831fe2e157b0bd46d21f44c20410/8ac56/image-20250511102959585.webp 240w,\n/static/e3fe831fe2e157b0bd46d21f44c20410/b76f7/image-20250511102959585.webp 332w\"\n              sizes=\"(max-width: 332px) 100vw, 332px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/e3fe831fe2e157b0bd46d21f44c20410/8ff5a/image-20250511102959585.png 240w,\n/static/e3fe831fe2e157b0bd46d21f44c20410/f8dc5/image-20250511102959585.png 332w\"\n            sizes=\"(max-width: 332px) 100vw, 332px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/e3fe831fe2e157b0bd46d21f44c20410/f8dc5/image-20250511102959585.png\"\n            alt=\"image-20250511102959585\"\n            title=\"image-20250511102959585\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>This matches the output of the <code class=\"language-text\">stat eicar.com</code> command, confirming that the stat information was retrieved correctly.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 739px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/2a05d73d4095721ee06c529f768232ca/f1d1f/image-20250511103420416.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 26.666666666666668%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA5ElEQVQY03WPWW6EMBBEuUMSxB6MAS/YZjFMIk1y/2NVuj2afCUfJawnUa86m6xCuHa4I8CdK5QzELOBtB5SWwzDgO69Q9/3EEKgbVtUVYWmaVL4Xdd1evM3G8cRRuuUUUoM9NPb6wu6toFzCySxaZqQ5zmKooAPHtroxKV8yJRWEINIwuy6XdiPHUc8cP++I6y01HvMav7lH583nNeJeMbEetGDh3CZXSw0jbGWriFBtm4rAUVrHLZ9S3YuNdakfJGEy5ix/Lm0LMs/kwU64bHKpTVcwhI2L3QyMxYxi1f8t+iZH2IskCOyahoBAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/2a05d73d4095721ee06c529f768232ca/8ac56/image-20250511103420416.webp 240w,\n/static/2a05d73d4095721ee06c529f768232ca/d3be9/image-20250511103420416.webp 480w,\n/static/2a05d73d4095721ee06c529f768232ca/26073/image-20250511103420416.webp 739w\"\n              sizes=\"(max-width: 739px) 100vw, 739px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/2a05d73d4095721ee06c529f768232ca/8ff5a/image-20250511103420416.png 240w,\n/static/2a05d73d4095721ee06c529f768232ca/e85cb/image-20250511103420416.png 480w,\n/static/2a05d73d4095721ee06c529f768232ca/f1d1f/image-20250511103420416.png 739w\"\n            sizes=\"(max-width: 739px) 100vw, 739px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/2a05d73d4095721ee06c529f768232ca/f1d1f/image-20250511103420416.png\"\n            alt=\"image-20250511103420416\"\n            title=\"image-20250511103420416\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>After validating the mapping range of the file, <code class=\"language-text\">cl_fmap_open_handle</code> is called with the file descriptor and other information.</p>\n<p>Inside <code class=\"language-text\">cl_fmap_open_handle</code>, memory is allocated by <code class=\"language-text\">cli_calloc</code> (which wraps <code class=\"language-text\">calloc</code>) and the resulting <code class=\"language-text\">fmap_t</code> struct region <code class=\"language-text\">m</code> is populated with file information and pointers to several callbacks.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">m<span class=\"token operator\">-></span>handle          <span class=\"token operator\">=</span> handle<span class=\"token punctuation\">;</span>\nm<span class=\"token operator\">-></span>pread_cb        <span class=\"token operator\">=</span> pread_cb<span class=\"token punctuation\">;</span>\nm<span class=\"token operator\">-></span>aging           <span class=\"token operator\">=</span> use_aging<span class=\"token punctuation\">;</span>\nm<span class=\"token operator\">-></span>offset          <span class=\"token operator\">=</span> offset<span class=\"token punctuation\">;</span>\nm<span class=\"token operator\">-></span>nested_offset   <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\nm<span class=\"token operator\">-></span>len             <span class=\"token operator\">=</span> len<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* m->nested_offset + m->len = m->real_len */</span>\nm<span class=\"token operator\">-></span>real_len        <span class=\"token operator\">=</span> len<span class=\"token punctuation\">;</span>\nm<span class=\"token operator\">-></span>pages           <span class=\"token operator\">=</span> pages<span class=\"token punctuation\">;</span>\nm<span class=\"token operator\">-></span>pgsz            <span class=\"token operator\">=</span> pgsz<span class=\"token punctuation\">;</span>\nm<span class=\"token operator\">-></span>paged           <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\nm<span class=\"token operator\">-></span>dont_cache_flag <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\nm<span class=\"token operator\">-></span>unmap           <span class=\"token operator\">=</span> unmap_handle<span class=\"token punctuation\">;</span>\nm<span class=\"token operator\">-></span>need            <span class=\"token operator\">=</span> handle_need<span class=\"token punctuation\">;</span>\nm<span class=\"token operator\">-></span>need_offstr     <span class=\"token operator\">=</span> handle_need_offstr<span class=\"token punctuation\">;</span>\nm<span class=\"token operator\">-></span>gets            <span class=\"token operator\">=</span> handle_gets<span class=\"token punctuation\">;</span>\nm<span class=\"token operator\">-></span>unneed_off      <span class=\"token operator\">=</span> handle_unneed_off<span class=\"token punctuation\">;</span>\nm<span class=\"token operator\">-></span>handle_is_fd    <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">/* Calculate the fmap hash to be used by the FP check later */</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>CL_SUCCESS <span class=\"token operator\">!=</span> <span class=\"token function\">fmap_get_MD5</span><span class=\"token punctuation\">(</span>hash<span class=\"token punctuation\">,</span> m<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">cli_warnmsg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"fmap: failed to get MD5\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">goto</span> done<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n<span class=\"token function\">memcpy</span><span class=\"token punctuation\">(</span>m<span class=\"token operator\">-></span>maphash<span class=\"token punctuation\">,</span> hash<span class=\"token punctuation\">,</span> <span class=\"token number\">16</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p><code class=\"language-text\">fmap_get_MD5</code> then computes the MD5 hash using the allocated <code class=\"language-text\">fmap_t</code> structure.</p>\n<p>After this processing, the <code class=\"language-text\">fmap_t</code> structure is confirmed to have the MD5 hash of <code class=\"language-text\">eicar.com</code> — <code class=\"language-text\">44d88612fea8a8f36de82e1278abb02f</code> — correctly written to it.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 777px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/f1014c2d0a6dd9ec6b8f0ba916a910ce/108f8/image-20250511112934199.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 7.916666666666666%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAeUlEQVQI1x2NSw7DIBBDcw2+A5VKqhIIpIFKSbro/Q/lllmNx5b9pqV2xFyQcsLedqxlRQgBQgg450BEkFLCe8/e+K21rP3NQykJYwzIEXuTK1+Ye8b2qpgfM7TWOD8n37pVpLRwofX2LysGD+jIj+vgoRif6O/O4B/lDTmHDiICqAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/f1014c2d0a6dd9ec6b8f0ba916a910ce/8ac56/image-20250511112934199.webp 240w,\n/static/f1014c2d0a6dd9ec6b8f0ba916a910ce/d3be9/image-20250511112934199.webp 480w,\n/static/f1014c2d0a6dd9ec6b8f0ba916a910ce/2e4ba/image-20250511112934199.webp 777w\"\n              sizes=\"(max-width: 777px) 100vw, 777px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/f1014c2d0a6dd9ec6b8f0ba916a910ce/8ff5a/image-20250511112934199.png 240w,\n/static/f1014c2d0a6dd9ec6b8f0ba916a910ce/e85cb/image-20250511112934199.png 480w,\n/static/f1014c2d0a6dd9ec6b8f0ba916a910ce/108f8/image-20250511112934199.png 777w\"\n            sizes=\"(max-width: 777px) 100vw, 777px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/f1014c2d0a6dd9ec6b8f0ba916a910ce/108f8/image-20250511112934199.png\"\n            alt=\"image-20250511112934199\"\n            title=\"image-20250511112934199\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Furthermore, inside <code class=\"language-text\">fmap_get_MD5</code>, the file data read via <code class=\"language-text\">m->need</code> (<code class=\"language-text\">handle_need</code>) — called through <code class=\"language-text\">fmap_need_off_once</code> — can be confirmed to be stored in <code class=\"language-text\">m->data</code>.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 878px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/37edc874a90c3e8768dd831bf418d548/94829/image-20250511115803611.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 5.416666666666667%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAQElEQVQI1x3JQQqAQAxDUa9SSJuSGRRc6f0PFqWrD+8feh/jvAzdXn/3Xi6WAZjNKRJjWWlJ7u55Y5nzSToi/AGVFB04JV0GxwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/37edc874a90c3e8768dd831bf418d548/8ac56/image-20250511115803611.webp 240w,\n/static/37edc874a90c3e8768dd831bf418d548/d3be9/image-20250511115803611.webp 480w,\n/static/37edc874a90c3e8768dd831bf418d548/6749f/image-20250511115803611.webp 878w\"\n              sizes=\"(max-width: 878px) 100vw, 878px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/37edc874a90c3e8768dd831bf418d548/8ff5a/image-20250511115803611.png 240w,\n/static/37edc874a90c3e8768dd831bf418d548/e85cb/image-20250511115803611.png 480w,\n/static/37edc874a90c3e8768dd831bf418d548/94829/image-20250511115803611.png 878w\"\n            sizes=\"(max-width: 878px) 100vw, 878px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/37edc874a90c3e8768dd831bf418d548/94829/image-20250511115803611.png\"\n            alt=\"image-20250511115803611\"\n            title=\"image-20250511115803611\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<h2 id=\"tracing-the-scanner-processing\" style=\"position:relative;\"><a href=\"#tracing-the-scanner-processing\" aria-label=\"tracing the scanner processing permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Tracing the Scanner Processing</h2>\n<p>Up to this point, the scan request from <code class=\"language-text\">clamdscan</code> triggered <code class=\"language-text\">cl_scandesc_callback</code>, inside which the <code class=\"language-text\">fmap_check_empty</code> function (called from <code class=\"language-text\">fmap</code>) mapped the scan target file into memory as a <code class=\"language-text\">fmap_t</code> structure.</p>\n<p>Next, <code class=\"language-text\">scan_common</code> is called from <code class=\"language-text\">cl_scandesc_callback</code> with this mapped file information as an argument.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/**\n * @brief   The main function to initiate a scan of an fmap.\n *\n * @param map               File map.\n * @param filepath          (optional, recommended) filepath of the open file descriptor or file map.\n * @param[out] virname      Will be set to a statically allocated (i.e. needs not be freed) signature name if the scan matches against a signature.\n * @param[out] scanned      The number of bytes scanned.\n * @param engine            The scanning engine.\n * @param scanoptions       Scanning options.\n * @param[inout] context    An opaque context structure allowing the caller to record details about the sample being scanned.\n * @return int              CL_CLEAN, CL_VIRUS, or an error code if an error occured during the scan.\n */</span>\n<span class=\"token keyword\">static</span> <span class=\"token class-name\">cl_error_t</span> <span class=\"token function\">scan_common</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">cl_fmap_t</span> <span class=\"token operator\">*</span>map<span class=\"token punctuation\">,</span> <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>filepath<span class=\"token punctuation\">,</span> <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span>virname<span class=\"token punctuation\">,</span> <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span> <span class=\"token keyword\">int</span> <span class=\"token operator\">*</span>scanned<span class=\"token punctuation\">,</span> <span class=\"token keyword\">const</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cl_engine</span> <span class=\"token operator\">*</span>engine<span class=\"token punctuation\">,</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cl_scan_options</span> <span class=\"token operator\">*</span>scanoptions<span class=\"token punctuation\">,</span> <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>context<span class=\"token punctuation\">)</span></code></pre></div>\n<p>Reference: <a href=\"https://github.com/Cisco-Talos/clamav/blob/main/libclamav/scanners.c\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">clamav/libclamav/scanners.c at main · Cisco-Talos/clamav</a></p>\n<h3 id=\"arguments-of-the-scan_common-function\" style=\"position:relative;\"><a href=\"#arguments-of-the-scan_common-function\" aria-label=\"arguments of the scan_common function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Arguments of the scan_common Function</h3>\n<p>Among the arguments passed to <code class=\"language-text\">scan_common</code>, the first argument <code class=\"language-text\">cl_fmap_t *map</code> contains the <code class=\"language-text\">fmap</code> structure mapped into memory as described in the previous section.</p>\n<p>The second argument <code class=\"language-text\">filepath</code> holds the full path of the scan target file (<code class=\"language-text\">/home/kash1064/Downloads/eicar.com</code>).</p>\n<p>The fifth argument <code class=\"language-text\">const struct cl_engine *engine</code> contains the configuration of the <code class=\"language-text\">cl_engine</code> structure used for scanning.</p>\n<p>This structure is defined as follows.</p>\n<p>Reference: <a href=\"https://github.com/Cisco-Talos/clamav/blob/main/libclamav/others.h\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">clamav/libclamav/others.h at main · Cisco-Talos/clamav</a></p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">struct</span> <span class=\"token class-name\">cl_engine</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token class-name\">uint32_t</span> refcount<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* reference counter */</span>\n    <span class=\"token class-name\">uint32_t</span> sdb<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint32_t</span> dboptions<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint32_t</span> dbversion<span class=\"token punctuation\">[</span><span class=\"token number\">2</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint32_t</span> ac_only<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint32_t</span> ac_mindepth<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint32_t</span> ac_maxdepth<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>tmpdir<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint32_t</span> keeptmp<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint64_t</span> engine_options<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Limits */</span>\n    <span class=\"token class-name\">uint32_t</span> maxscantime<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* Time limit (in milliseconds) */</span>\n    <span class=\"token class-name\">uint64_t</span> maxscansize<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* during the scanning of archives this size\n           * will never be exceeded\n           */</span>\n    <span class=\"token class-name\">uint64_t</span> maxfilesize<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* compressed files will only be decompressed\n           * and scanned up to this size\n           */</span>\n    <span class=\"token class-name\">uint32_t</span> maxreclevel<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* maximum recursion level for archives */</span>\n    <span class=\"token class-name\">uint32_t</span> maxfiles<span class=\"token punctuation\">;</span>    <span class=\"token comment\">/* maximum number of files to be scanned\n           * within a single archive\n           */</span>\n    <span class=\"token comment\">/* This is for structured data detection.  You can set the minimum\n     * number of occurrences of an CC# or SSN before the system will\n     * generate a notification.\n     */</span>\n    <span class=\"token class-name\">uint32_t</span> min_cc_count<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint32_t</span> min_ssn_count<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Roots table */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_matcher</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span>root<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* hash matcher for standard MD5 sigs */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_matcher</span> <span class=\"token operator\">*</span>hm_hdb<span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">/* hash matcher for MD5 sigs for PE sections */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_matcher</span> <span class=\"token operator\">*</span>hm_mdb<span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">/* hash matcher for MD5 sigs for PE import tables */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_matcher</span> <span class=\"token operator\">*</span>hm_imp<span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">/* hash matcher for allow list db */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_matcher</span> <span class=\"token operator\">*</span>hm_fp<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Container metadata */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_cdb</span> <span class=\"token operator\">*</span>cdb<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Phishing .pdb and .wdb databases*/</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">regex_matcher</span> <span class=\"token operator\">*</span>allow_list_matcher<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">regex_matcher</span> <span class=\"token operator\">*</span>domain_list_matcher<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">phishcheck</span> <span class=\"token operator\">*</span>phishcheck<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Dynamic configuration */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_dconf</span> <span class=\"token operator\">*</span>dconf<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Filetype definitions */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_ftype</span> <span class=\"token operator\">*</span>ftypes<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_ftype</span> <span class=\"token operator\">*</span>ptypes<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Container password storage */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_pwdb</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span>pwdbs<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Pre-loading test matcher\n     * Test for presence before using; cleared on engine compile.\n     */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_matcher</span> <span class=\"token operator\">*</span>test_root<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Ignored signatures */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_matcher</span> <span class=\"token operator\">*</span>ignored<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* PUA categories (to be included or excluded) */</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>pua_cats<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Icon reference storage */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">icon_matcher</span> <span class=\"token operator\">*</span>iconcheck<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Negative cache storage */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">CACHE</span> <span class=\"token operator\">*</span>cache<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Database information from .info files */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_dbinfo</span> <span class=\"token operator\">*</span>dbinfo<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Signature counting, for progress callbacks */</span>\n    <span class=\"token class-name\">size_t</span> num_total_signatures<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Used for memory pools */</span>\n    <span class=\"token class-name\">mpool_t</span> <span class=\"token operator\">*</span>mempool<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* crtmgr stuff */</span>\n    crtmgr cmgr<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Callback(s) */</span>\n    clcb_pre_cache cb_pre_cache<span class=\"token punctuation\">;</span>\n    clcb_pre_scan cb_pre_scan<span class=\"token punctuation\">;</span>\n    clcb_post_scan cb_post_scan<span class=\"token punctuation\">;</span>\n    clcb_virus_found cb_virus_found<span class=\"token punctuation\">;</span>\n    clcb_sigload cb_sigload<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>cb_sigload_ctx<span class=\"token punctuation\">;</span>\n    clcb_hash cb_hash<span class=\"token punctuation\">;</span>\n    clcb_meta cb_meta<span class=\"token punctuation\">;</span>\n    clcb_file_props cb_file_props<span class=\"token punctuation\">;</span>\n    clcb_progress cb_sigload_progress<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>cb_sigload_progress_ctx<span class=\"token punctuation\">;</span>\n    clcb_progress cb_engine_compile_progress<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>cb_engine_compile_progress_ctx<span class=\"token punctuation\">;</span>\n    clcb_progress cb_engine_free_progress<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>cb_engine_free_progress_ctx<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Used for bytecode */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_all_bc</span> bcs<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token operator\">*</span>hooks<span class=\"token punctuation\">[</span>_BC_LAST_HOOK <span class=\"token operator\">-</span> _BC_START_HOOKS<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">unsigned</span> hooks_cnt<span class=\"token punctuation\">[</span>_BC_LAST_HOOK <span class=\"token operator\">-</span> _BC_START_HOOKS<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">unsigned</span> hook_lsig_ids<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">enum</span> <span class=\"token class-name\">bytecode_security</span> bytecode_security<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint32_t</span> bytecode_timeout<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">enum</span> <span class=\"token class-name\">bytecode_mode</span> bytecode_mode<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Engine max settings */</span>\n    <span class=\"token class-name\">uint64_t</span> maxembeddedpe<span class=\"token punctuation\">;</span>      <span class=\"token comment\">/* max size to scan MSEXE for PE */</span>\n    <span class=\"token class-name\">uint64_t</span> maxhtmlnormalize<span class=\"token punctuation\">;</span>   <span class=\"token comment\">/* max size to normalize HTML */</span>\n    <span class=\"token class-name\">uint64_t</span> maxhtmlnotags<span class=\"token punctuation\">;</span>      <span class=\"token comment\">/* max size for scanning normalized HTML */</span>\n    <span class=\"token class-name\">uint64_t</span> maxscriptnormalize<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* max size to normalize scripts */</span>\n    <span class=\"token class-name\">uint64_t</span> maxziptypercg<span class=\"token punctuation\">;</span>      <span class=\"token comment\">/* max size to re-do zip filetype */</span>\n\n    <span class=\"token comment\">/* Statistics/intelligence gathering */</span>\n    <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>stats_data<span class=\"token punctuation\">;</span>\n    clcb_stats_add_sample cb_stats_add_sample<span class=\"token punctuation\">;</span>\n    clcb_stats_remove_sample cb_stats_remove_sample<span class=\"token punctuation\">;</span>\n    clcb_stats_decrement_count cb_stats_decrement_count<span class=\"token punctuation\">;</span>\n    clcb_stats_submit cb_stats_submit<span class=\"token punctuation\">;</span>\n    clcb_stats_flush cb_stats_flush<span class=\"token punctuation\">;</span>\n    clcb_stats_get_num cb_stats_get_num<span class=\"token punctuation\">;</span>\n    clcb_stats_get_size cb_stats_get_size<span class=\"token punctuation\">;</span>\n    clcb_stats_get_hostid cb_stats_get_hostid<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Raw disk image max settings */</span>\n    <span class=\"token class-name\">uint32_t</span> maxpartitions<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* max number of partitions to scan in a disk image */</span>\n\n    <span class=\"token comment\">/* Engine max settings */</span>\n    <span class=\"token class-name\">uint32_t</span> maxiconspe<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* max number of icons to scan for PE */</span>\n    <span class=\"token class-name\">uint32_t</span> maxrechwp3<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* max recursive calls for HWP3 parsing */</span>\n\n    <span class=\"token comment\">/* PCRE matching limitations */</span>\n    <span class=\"token class-name\">uint64_t</span> pcre_match_limit<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint64_t</span> pcre_recmatch_limit<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint64_t</span> pcre_max_filesize<span class=\"token punctuation\">;</span>\n\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">ifdef</span> <span class=\"token expression\">HAVE_YARA</span></span>\n    <span class=\"token comment\">/* YARA */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">_yara_global</span> <span class=\"token operator\">*</span>yara_global<span class=\"token punctuation\">;</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">endif</span></span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The sixth argument specifies scan options via the <code class=\"language-text\">cl_scan_options</code> structure.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/*** scan options ***/</span>\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">cl_scan_options</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token class-name\">uint32_t</span> general<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint32_t</span> parse<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint32_t</span> heuristic<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint32_t</span> mail<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">uint32_t</span> dev<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The options set during this <code class=\"language-text\">clamdscan</code> invocation were as follows.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 501px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/4fd122410dfd8973133a3f9e5d075b2b/55811/image-20250511133310869.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 35.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAAsTAAALEwEAmpwYAAAA3ElEQVQoz51R2U7DMBDMT+R0E9uxE9vxESgCKpB44P//aVibl4oWRPuwWu81O7OuHj9ecPw8wR0DpBBYzQpjDbbNQc4S1ln44IsPMcD7DcYYCClKX9oTAtVjitBao9oo0NSsqHjgHH3fYxxHdF1X3ueWc+f2M5fjapgm2PcT1B4xE7tEm/Lmuq7Rtu2vQNfAsq8OgmN9fsIcPaQzcCRLqRn7QyoSrjH9ywqgfXv9BqN7THQbxhiWZYGgm94BKApDnpkuK4ZhKFKbprmQ/C9Anj+CQBgboFV/MXgrwy+06rzrqfwOFgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/4fd122410dfd8973133a3f9e5d075b2b/8ac56/image-20250511133310869.webp 240w,\n/static/4fd122410dfd8973133a3f9e5d075b2b/d3be9/image-20250511133310869.webp 480w,\n/static/4fd122410dfd8973133a3f9e5d075b2b/52d01/image-20250511133310869.webp 501w\"\n              sizes=\"(max-width: 501px) 100vw, 501px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/4fd122410dfd8973133a3f9e5d075b2b/8ff5a/image-20250511133310869.png 240w,\n/static/4fd122410dfd8973133a3f9e5d075b2b/e85cb/image-20250511133310869.png 480w,\n/static/4fd122410dfd8973133a3f9e5d075b2b/55811/image-20250511133310869.png 501w\"\n            sizes=\"(max-width: 501px) 100vw, 501px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/4fd122410dfd8973133a3f9e5d075b2b/55811/image-20250511133310869.png\"\n            alt=\"image-20250511133310869\"\n            title=\"image-20250511133310869\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>These arguments received by <code class=\"language-text\">scan_common</code> are subsequently saved as members of the <code class=\"language-text\">cli_ctx</code> struct variable <code class=\"language-text\">ctx</code> after it is initialized.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token function\">memset</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>ctx<span class=\"token punctuation\">,</span> <span class=\"token char\">'\\0'</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>cli_ctx<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nctx<span class=\"token punctuation\">.</span>engine  <span class=\"token operator\">=</span> engine<span class=\"token punctuation\">;</span>\nctx<span class=\"token punctuation\">.</span>virname <span class=\"token operator\">=</span> virname<span class=\"token punctuation\">;</span>\nctx<span class=\"token punctuation\">.</span>scanned <span class=\"token operator\">=</span> scanned<span class=\"token punctuation\">;</span>\nctx<span class=\"token punctuation\">.</span>options <span class=\"token operator\">=</span> <span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">cl_scan_options</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">memcpy</span><span class=\"token punctuation\">(</span>ctx<span class=\"token punctuation\">.</span>options<span class=\"token punctuation\">,</span> scanoptions<span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">cl_scan_options</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nctx<span class=\"token punctuation\">.</span>found_possibly_unwanted <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\nctx<span class=\"token punctuation\">.</span>containers              <span class=\"token operator\">=</span> <span class=\"token function\">cli_calloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>cli_ctx_container<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> ctx<span class=\"token punctuation\">.</span>engine<span class=\"token operator\">-></span>maxreclevel <span class=\"token operator\">+</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>ctx<span class=\"token punctuation\">.</span>containers<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    rc <span class=\"token operator\">=</span> CL_EMEM<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">goto</span> done<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n<span class=\"token function\">cli_set_container</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>ctx<span class=\"token punctuation\">,</span> CL_TYPE_ANY<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nctx<span class=\"token punctuation\">.</span>dconf  <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_dconf</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>engine<span class=\"token operator\">-></span>dconf<span class=\"token punctuation\">;</span>\nctx<span class=\"token punctuation\">.</span>cb_ctx <span class=\"token operator\">=</span> context<span class=\"token punctuation\">;</span>\nfmap_head  <span class=\"token operator\">=</span> <span class=\"token function\">cli_calloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">fmap_t</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> ctx<span class=\"token punctuation\">.</span>engine<span class=\"token operator\">-></span>maxreclevel <span class=\"token operator\">+</span> <span class=\"token number\">3</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>fmap_head<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    rc <span class=\"token operator\">=</span> CL_EMEM<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">goto</span> done<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span><span class=\"token punctuation\">(</span>ctx<span class=\"token punctuation\">.</span>hook_lsig_matches <span class=\"token operator\">=</span> <span class=\"token function\">cli_bitset_init</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    rc <span class=\"token operator\">=</span> CL_EMEM<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">goto</span> done<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">/*\n * The first fmap in ctx.fmap must be NULL so we can fmap-- while not NULL.\n * But we need an fmap to be set so we can append viruses or report the\n * fmap's file descriptor in the virus found callback (like for deferred\n * low-seveerity alerts).\n */</span>\nctx<span class=\"token punctuation\">.</span>fmap  <span class=\"token operator\">=</span> fmap_head <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n<span class=\"token operator\">*</span>ctx<span class=\"token punctuation\">.</span>fmap <span class=\"token operator\">=</span> map<span class=\"token punctuation\">;</span></code></pre></div>\n<p>This structure contains the file path of the scan target and various other status information, as defined below.</p>\n<p>The structure is ultimately passed from <code class=\"language-text\">scan_common</code> to the actual scan function <code class=\"language-text\">cli_magic_scan</code> via <code class=\"language-text\">cli_magic_scan(&amp;ctx, CL_TYPE_ANY);</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/* internal clamav context */</span>\n<span class=\"token keyword\">typedef</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_ctx_tag</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>target_filepath<span class=\"token punctuation\">;</span>    <span class=\"token comment\">/**&lt; (optional) The filepath of the original scan target */</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>sub_filepath<span class=\"token punctuation\">;</span> <span class=\"token comment\">/**&lt; (optional) The filepath of the current file being parsed. May be a temp file. */</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>sub_tmpdir<span class=\"token punctuation\">;</span>         <span class=\"token comment\">/**&lt; The directory to store tmp files at this recursion depth. */</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span>virname<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">int</span> num_viruses<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span> <span class=\"token keyword\">int</span> <span class=\"token operator\">*</span>scanned<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_matcher</span> <span class=\"token operator\">*</span>root<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cl_engine</span> <span class=\"token operator\">*</span>engine<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span> scansize<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cl_scan_options</span> <span class=\"token operator\">*</span>options<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">int</span> recursion<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">int</span> scannedfiles<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">int</span> found_possibly_unwanted<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">int</span> corrupted_input<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">int</span> img_validate<span class=\"token punctuation\">;</span>\n    cli_ctx_container <span class=\"token operator\">*</span>containers<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* set container type after recurse */</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">char</span> handlertype_hash<span class=\"token punctuation\">[</span><span class=\"token number\">16</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_dconf</span> <span class=\"token operator\">*</span>dconf<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">fmap_t</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span>fmap<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* pointer to current fmap in an allocated array, incremented with recursion depth */</span>\n    <span class=\"token class-name\">bitset_t</span> <span class=\"token operator\">*</span>hook_lsig_matches<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>cb_ctx<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">cli_events_t</span> <span class=\"token operator\">*</span>perf<span class=\"token punctuation\">;</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">ifdef</span> <span class=\"token expression\">HAVE__INTERNAL__SHA_COLLECT</span></span>\n    <span class=\"token keyword\">int</span> sha_collect<span class=\"token punctuation\">;</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">endif</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">ifdef</span> <span class=\"token expression\">HAVE_JSON</span></span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">json_object</span> <span class=\"token operator\">*</span>properties<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">json_object</span> <span class=\"token operator\">*</span>wrkproperty<span class=\"token punctuation\">;</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">endif</span></span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">timeval</span> time_limit<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">int</span> limit_exceeded<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span> cli_ctx<span class=\"token punctuation\">;</span></code></pre></div>\n<p>Dumping <code class=\"language-text\">ctx</code> at the time <code class=\"language-text\">cli_magic_scan</code> is called reveals the following information.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 735px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/90ad1ab0d65d9193c2035f7d44152bba/7608e/image-20250511135301625.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 95%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAAAsTAAALEwEAmpwYAAACM0lEQVQ4y5VUWXbbMBDTIdpoobiKIrXRlh3HaXP/e6Eg0/ZlaRPnA2/0bGoEDMCp0vWE9brDOAvrHNquQ9sSQqLrFbpchUDf968gegEhXqPju1WvFOwyw8wT3HGDiSOkDeikRe8m9MPCZwPvB/jRYwwjQggYx7E8e+/hSMSRkGKvSvNQuF4w/bzCpwQdjjDpCXq+QPoV2ljEGLBuKwJrjLE0GviBOMWCjf/lqrVGpdjdn3f4PcHOCW5KhZkcVghlKb99L010Rd7b3/PZShoDl1ZKnaDGhbPp0dx9Q000dY2mab6EInl+eqTcI+y0F5nSb5Bk2XaiHMpfvhWV5DCH/UC5EdZHSp0hx1SQXW6a+osNrcV4f8JwTBiWBda60qjNeMHwVqaVym79uBaXJ9ZAtnHPbnsYzldK+a7ZR83J0JQcusNGczZYZsw6j5rhboiaxtR3d79rXeqfpv9qXBgWdjmHlG2XVNyOhwe4uGEY+QGOJWfMuuf6IUOdk/9wpsOc3+GxwGyPGJcjJK+XMbog3wJDNUqrzyTTZeZQU6qZs+wz6wnCRiIQEzrtKb/9K/1DyZp3Mlzo8kq52z1UWKBjKnkUvMP5HhfX88K4xZQ8wxwZlw7QnFdPRq1QZPP9mUW5LfXN8anU8HyXcxYtN41y3DaGWcwvvzl8SxarvNdybMLlDE+Drg8XnE77p27+3xS6l7Mo2KDPjnL75AX62fD/H5u8GDlHSemGO63P0VDqS9ftJX4BywgB+gw+c2EAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/90ad1ab0d65d9193c2035f7d44152bba/8ac56/image-20250511135301625.webp 240w,\n/static/90ad1ab0d65d9193c2035f7d44152bba/d3be9/image-20250511135301625.webp 480w,\n/static/90ad1ab0d65d9193c2035f7d44152bba/ed0c4/image-20250511135301625.webp 735w\"\n              sizes=\"(max-width: 735px) 100vw, 735px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/90ad1ab0d65d9193c2035f7d44152bba/8ff5a/image-20250511135301625.png 240w,\n/static/90ad1ab0d65d9193c2035f7d44152bba/e85cb/image-20250511135301625.png 480w,\n/static/90ad1ab0d65d9193c2035f7d44152bba/7608e/image-20250511135301625.png 735w\"\n            sizes=\"(max-width: 735px) 100vw, 735px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/90ad1ab0d65d9193c2035f7d44152bba/7608e/image-20250511135301625.png\"\n            alt=\"image-20250511135301625\"\n            title=\"image-20250511135301625\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<h3 id=\"identifying-the-file-type\" style=\"position:relative;\"><a href=\"#identifying-the-file-type\" aria-label=\"identifying the file type permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Identifying the File Type</h3>\n<p>After the context information is passed to <code class=\"language-text\">cli_magic_scan</code>, following several checks, the code below is executed.</p>\n<p>Here, <code class=\"language-text\">cli_determine_fmap_type</code> and <code class=\"language-text\">cli_ftname</code> identify the file type.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">hash        <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>ctx<span class=\"token operator\">-></span>fmap<span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>maphash<span class=\"token punctuation\">;</span>\nhashed_size <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>ctx<span class=\"token operator\">-></span>fmap<span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>len<span class=\"token punctuation\">;</span>\n\nold_hook_lsig_matches <span class=\"token operator\">=</span> ctx<span class=\"token operator\">-></span>hook_lsig_matches<span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>type <span class=\"token operator\">==</span> CL_TYPE_PART_ANY<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    typercg <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">/*\n * Perform file typing from the start of the file.\n */</span>\n<span class=\"token function\">perf_start</span><span class=\"token punctuation\">(</span>ctx<span class=\"token punctuation\">,</span> PERFT_FT<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>type <span class=\"token operator\">==</span> CL_TYPE_ANY<span class=\"token punctuation\">)</span> <span class=\"token operator\">||</span> type <span class=\"token operator\">==</span> CL_TYPE_PART_ANY<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    type <span class=\"token operator\">=</span> <span class=\"token function\">cli_determine_fmap_type</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>ctx<span class=\"token operator\">-></span>fmap<span class=\"token punctuation\">,</span> ctx<span class=\"token operator\">-></span>engine<span class=\"token punctuation\">,</span> type<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n<span class=\"token function\">perf_stop</span><span class=\"token punctuation\">(</span>ctx<span class=\"token punctuation\">,</span> PERFT_FT<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>type <span class=\"token operator\">==</span> CL_TYPE_ERROR<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">cli_dbgmsg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"cli_magic_scan: cli_determine_fmap_type returned CL_TYPE_ERROR\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    ret <span class=\"token operator\">=</span> CL_EREAD<span class=\"token punctuation\">;</span>\n    <span class=\"token function\">cli_dbgmsg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"cli_magic_scan: returning %d %s (no post, no cache)\\n\"</span><span class=\"token punctuation\">,</span> ret<span class=\"token punctuation\">,</span> __AT__<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">goto</span> early_ret<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\nfiletype <span class=\"token operator\">=</span> <span class=\"token function\">cli_ftname</span><span class=\"token punctuation\">(</span>type<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The list of file types is defined in <code class=\"language-text\">libclamav/filetypes.h</code>. The Eicar file in this case was identified as <code class=\"language-text\">CL_TYPE_TEXT_ASCII</code>.</p>\n<p>Reference: <a href=\"https://github.com/Cisco-Talos/clamav/blob/main/libclamav/filetypes.h\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">clamav/libclamav/filetypes.h at main · Cisco-Talos/clamav</a></p>\n<h3 id=\"cache-check\" style=\"position:relative;\"><a href=\"#cache-check\" aria-label=\"cache check permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Cache Check</h3>\n<p>After the file type is identified, <code class=\"language-text\">cli_magic_scan</code> also performs a check via <code class=\"language-text\">dispatch_prescan_callback</code>, but at this point <code class=\"language-text\">ctx->engine->cb_pre_cache</code> is NULL so nothing happens, and execution proceeds directly to the <code class=\"language-text\">cache_check</code> function.</p>\n<p>This function checks whether the MD5 hash of the scan target file is present in the <code class=\"language-text\">cacheset</code> stored in <code class=\"language-text\">ctx->engine->cache</code>. If it is, <code class=\"language-text\">CL_VIRUS</code> is returned.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/* Hashes a file onto the provided buffer and looks it up the cache.\n   Returns CL_VIRUS if found, CL_CLEAN if not FIXME or a recoverable error,\n   and returns CL_EREAD if unrecoverable */</span>\n<span class=\"token class-name\">cl_error_t</span> <span class=\"token function\">cache_check</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>hash<span class=\"token punctuation\">,</span> cli_ctx <span class=\"token operator\">*</span>ctx<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token class-name\">fmap_t</span> <span class=\"token operator\">*</span>map<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">int</span> ret<span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>ctx <span class=\"token operator\">||</span> <span class=\"token operator\">!</span>ctx<span class=\"token operator\">-></span>engine <span class=\"token operator\">||</span> <span class=\"token operator\">!</span>ctx<span class=\"token operator\">-></span>engine<span class=\"token operator\">-></span>cache<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> CL_VIRUS<span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>ctx<span class=\"token operator\">-></span>engine<span class=\"token operator\">-></span>engine_options <span class=\"token operator\">&amp;</span> ENGINE_OPTIONS_DISABLE_CACHE<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">cli_dbgmsg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"cache_check: Caching disabled. Returning CL_VIRUS.\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> CL_VIRUS<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    map <span class=\"token operator\">=</span> <span class=\"token operator\">*</span>ctx<span class=\"token operator\">-></span>fmap<span class=\"token punctuation\">;</span>\n    ret <span class=\"token operator\">=</span> <span class=\"token function\">cache_lookup_hash</span><span class=\"token punctuation\">(</span>hash<span class=\"token punctuation\">,</span> map<span class=\"token operator\">-></span>len<span class=\"token punctuation\">,</span> ctx<span class=\"token operator\">-></span>engine<span class=\"token operator\">-></span>cache<span class=\"token punctuation\">,</span> ctx<span class=\"token operator\">-></span>recursion<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">cli_dbgmsg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"cache_check: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x is %s\\n\"</span><span class=\"token punctuation\">,</span> hash<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> hash<span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> hash<span class=\"token punctuation\">[</span><span class=\"token number\">2</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> hash<span class=\"token punctuation\">[</span><span class=\"token number\">3</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> hash<span class=\"token punctuation\">[</span><span class=\"token number\">4</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> hash<span class=\"token punctuation\">[</span><span class=\"token number\">5</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> hash<span class=\"token punctuation\">[</span><span class=\"token number\">6</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> hash<span class=\"token punctuation\">[</span><span class=\"token number\">7</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> hash<span class=\"token punctuation\">[</span><span class=\"token number\">8</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> hash<span class=\"token punctuation\">[</span><span class=\"token number\">9</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> hash<span class=\"token punctuation\">[</span><span class=\"token number\">10</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> hash<span class=\"token punctuation\">[</span><span class=\"token number\">11</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> hash<span class=\"token punctuation\">[</span><span class=\"token number\">12</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> hash<span class=\"token punctuation\">[</span><span class=\"token number\">13</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> hash<span class=\"token punctuation\">[</span><span class=\"token number\">14</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> hash<span class=\"token punctuation\">[</span><span class=\"token number\">15</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span>ret <span class=\"token operator\">==</span> CL_VIRUS<span class=\"token punctuation\">)</span> <span class=\"token operator\">?</span> <span class=\"token string\">\"negative\"</span> <span class=\"token operator\">:</span> <span class=\"token string\">\"positive\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> ret<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>In this case, the Eicar hash was already registered in the engine’s <code class=\"language-text\">cacheset</code>, so it appeared that the file was detected as a virus at this point.</p>\n<p>Note: when the engine or <code class=\"language-text\">cacheset</code> is NULL, <code class=\"language-text\">cache_check</code> returns <code class=\"language-text\">CL_VIRUS</code> to allow scanning to proceed, so a return value of <code class=\"language-text\">CL_VIRUS</code> from this function alone does not necessarily mean the file will be reported as a virus.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>ctx <span class=\"token operator\">||</span> <span class=\"token operator\">!</span>ctx<span class=\"token operator\">-></span>engine <span class=\"token operator\">||</span> <span class=\"token operator\">!</span>ctx<span class=\"token operator\">-></span>engine<span class=\"token operator\">-></span>cache<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> CL_VIRUS<span class=\"token punctuation\">;</span></code></pre></div>\n<h3 id=\"tracing-scan-behavior-after-the-cache-check\" style=\"position:relative;\"><a href=\"#tracing-scan-behavior-after-the-cache-check\" aria-label=\"tracing scan behavior after the cache check permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Tracing Scan Behavior After the Cache Check</h3>\n<p>To make the scan flow easier to trace, disable the cache by setting <code class=\"language-text\">DisableCache yes</code> in <code class=\"language-text\">clamd.conf</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token macro property\"><span class=\"token directive-hash\">#</span> <span class=\"token expression\">This option allows you to disable clamd's caching feature<span class=\"token punctuation\">.</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span> <span class=\"token expression\">Default<span class=\"token operator\">:</span> no</span></span>\nDisableCache yes</code></pre></div>\n<p>With this change, repeating the <code class=\"language-text\">clamdscan</code> scan request skips the <code class=\"language-text\">cacheset</code> lookup in <code class=\"language-text\">cache_check</code>, and <code class=\"language-text\">cli_magic_scan</code> continues to subsequent processing.</p>\n<p>After several operations, <code class=\"language-text\">cli_magic_scan</code> calls various scan functions corresponding to the type of the scan target file.</p>\n<p>Since the Eicar file is classified as <code class=\"language-text\">CL_TYPE_TEXT_ASCII</code>, a check via <code class=\"language-text\">cli_scan_structured(ctx);</code> is performed.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">ctx<span class=\"token operator\">-></span>recursion<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">perf_nested_start</span><span class=\"token punctuation\">(</span>ctx<span class=\"token punctuation\">,</span> PERFT_CONTAINER<span class=\"token punctuation\">,</span> PERFT_SCAN<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">/* set current level as container AFTER recursing */</span>\n<span class=\"token function\">cli_set_container</span><span class=\"token punctuation\">(</span>ctx<span class=\"token punctuation\">,</span> type<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>ctx<span class=\"token operator\">-></span>fmap<span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>len<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">switch</span> <span class=\"token punctuation\">(</span>type<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">case</span> CL_TYPE_IGNORED<span class=\"token operator\">:</span>\n        <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">/* omitted */</span>\n    <span class=\"token keyword\">case</span> CL_TYPE_BINARY_DATA<span class=\"token operator\">:</span>\n    <span class=\"token keyword\">case</span> CL_TYPE_TEXT_UTF16BE<span class=\"token operator\">:</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>SCAN_HEURISTICS <span class=\"token operator\">&amp;&amp;</span> <span class=\"token punctuation\">(</span>DCONF_OTHER <span class=\"token operator\">&amp;</span> OTHER_CONF_MYDOOMLOG<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n            ret <span class=\"token operator\">=</span> <span class=\"token function\">cli_check_mydoom_log</span><span class=\"token punctuation\">(</span>ctx<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">case</span> CL_TYPE_TEXT_ASCII<span class=\"token operator\">:</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>SCAN_HEURISTIC_STRUCTURED <span class=\"token operator\">&amp;&amp;</span> <span class=\"token punctuation\">(</span>DCONF_OTHER <span class=\"token operator\">&amp;</span> OTHER_CONF_DLP<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n            <span class=\"token comment\">/* TODO: consider calling this from cli_scanscript() for\n             * a normalised text\n             */</span>\n\n            ret <span class=\"token operator\">=</span> <span class=\"token function\">cli_scan_structured</span><span class=\"token punctuation\">(</span>ctx<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">default</span><span class=\"token operator\">:</span>\n        <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n<span class=\"token function\">perf_nested_stop</span><span class=\"token punctuation\">(</span>ctx<span class=\"token punctuation\">,</span> PERFT_CONTAINER<span class=\"token punctuation\">,</span> PERFT_SCAN<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nctx<span class=\"token operator\">-></span>recursion<span class=\"token operator\">--</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>However, this function is used for DLP purposes to check whether credit card numbers or SSNs are present, so it can be ignored for this case.</p>\n<p>Continuing to trace <code class=\"language-text\">cli_magic_scan</code>, we find that it ultimately calls <code class=\"language-text\">scanraw(ctx, type, typercg, &amp;dettype, (ctx->engine->engine_options &amp; ENGINE_OPTIONS_DISABLE_CACHE) ? NULL : hash);</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/* CL_TYPE_HTML: raw HTML files are not scanned, unless safety measure activated via DCONF */</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>type <span class=\"token operator\">!=</span> CL_TYPE_IGNORED <span class=\"token operator\">&amp;&amp;</span> <span class=\"token punctuation\">(</span>type <span class=\"token operator\">!=</span> CL_TYPE_HTML <span class=\"token operator\">||</span> <span class=\"token operator\">!</span><span class=\"token punctuation\">(</span>SCAN_PARSE_HTML<span class=\"token punctuation\">)</span> <span class=\"token operator\">||</span> <span class=\"token operator\">!</span><span class=\"token punctuation\">(</span>DCONF_DOC <span class=\"token operator\">&amp;</span> DOC_CONF_HTML_SKIPRAW<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&amp;&amp;</span> <span class=\"token operator\">!</span>ctx<span class=\"token operator\">-></span>engine<span class=\"token operator\">-></span>sdb<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    res <span class=\"token operator\">=</span> <span class=\"token function\">scanraw</span><span class=\"token punctuation\">(</span>ctx<span class=\"token punctuation\">,</span> type<span class=\"token punctuation\">,</span> typercg<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>dettype<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span>ctx<span class=\"token operator\">-></span>engine<span class=\"token operator\">-></span>engine_options <span class=\"token operator\">&amp;</span> ENGINE_OPTIONS_DISABLE_CACHE<span class=\"token punctuation\">)</span> <span class=\"token operator\">?</span> <span class=\"token constant\">NULL</span> <span class=\"token operator\">:</span> hash<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>res <span class=\"token operator\">!=</span> CL_CLEAN<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">switch</span> <span class=\"token punctuation\">(</span>res<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token comment\">/* List of scan halts, runtime errors only! */</span>\n<span class=\"token comment\">/* omitted */</span>\n            <span class=\"token keyword\">case</span> CL_VIRUS<span class=\"token operator\">:</span>\n                ret <span class=\"token operator\">=</span> res<span class=\"token punctuation\">;</span>\n                <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>SCAN_ALLMATCHES<span class=\"token punctuation\">)</span>\n                    <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n                <span class=\"token function\">cli_bitset_free</span><span class=\"token punctuation\">(</span>ctx<span class=\"token operator\">-></span>hook_lsig_matches<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n                ctx<span class=\"token operator\">-></span>hook_lsig_matches <span class=\"token operator\">=</span> old_hook_lsig_matches<span class=\"token punctuation\">;</span>\n                <span class=\"token keyword\">goto</span> done<span class=\"token punctuation\">;</span>\n            <span class=\"token comment\">/* omitted */</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><code class=\"language-text\">scanraw</code> performs a raw scan of the <code class=\"language-text\">fmap</code> that contains the mapped scan target file, so the actual file scanning happens inside this function.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/**\n * @brief Perform raw scan of current fmap.\n *\n * @param ctx           Current scan context.\n * @param type          File type\n * @param typercg       Enable type recognition (file typing scan results).\n *                      If 0, will be a regular ac-mode scan.\n * @param[out] dettype  If typercg enabled and scan detects HTML or MAIL types,\n *                      will output HTML or MAIL types after performing HTML/MAIL scans\n * @param refhash       Hash of current fmap\n * @return cl_error_t\n */</span>\n<span class=\"token keyword\">static</span> <span class=\"token class-name\">cl_error_t</span> <span class=\"token function\">scanraw</span><span class=\"token punctuation\">(</span>cli_ctx <span class=\"token operator\">*</span>ctx<span class=\"token punctuation\">,</span> <span class=\"token class-name\">cli_file_t</span> type<span class=\"token punctuation\">,</span> <span class=\"token class-name\">uint8_t</span> typercg<span class=\"token punctuation\">,</span> <span class=\"token class-name\">cli_file_t</span> <span class=\"token operator\">*</span>dettype<span class=\"token punctuation\">,</span> <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>refhash<span class=\"token punctuation\">)</span></code></pre></div>\n<p>Within <code class=\"language-text\">scanraw</code>, various scan routines are again called depending on the file type. The actual Eicar detection occurs inside <code class=\"language-text\">cli_scan_fmap</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token function\">perf_start</span><span class=\"token punctuation\">(</span>ctx<span class=\"token punctuation\">,</span> PERFT_RAW<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nret <span class=\"token operator\">=</span> <span class=\"token function\">cli_scan_fmap</span><span class=\"token punctuation\">(</span>ctx<span class=\"token punctuation\">,</span> type <span class=\"token operator\">==</span> CL_TYPE_TEXT_ASCII <span class=\"token operator\">?</span> CL_TYPE_ANY <span class=\"token operator\">:</span> type<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>ftoffset<span class=\"token punctuation\">,</span> acmode<span class=\"token punctuation\">,</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">,</span> refhash<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">perf_stop</span><span class=\"token punctuation\">(</span>ctx<span class=\"token punctuation\">,</span> PERFT_RAW<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Inside <code class=\"language-text\">cli_scan_fmap</code>, two checks are performed: a signature-matcher scan that reads the file in fixed-size buffer chunks, and a hash-based scan.</p>\n<p>The hash-based scan uses the database (<code class=\"language-text\">hdb</code>) from <code class=\"language-text\">ctx->engine->hm_hdb</code>.</p>\n<p>The Eicar file used in this case was detected via hash-based scanning at the following location.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">hdb <span class=\"token operator\">=</span> ctx<span class=\"token operator\">-></span>engine<span class=\"token operator\">-></span>hm_hdb<span class=\"token punctuation\">;</span>\nfp  <span class=\"token operator\">=</span> ctx<span class=\"token operator\">-></span>engine<span class=\"token operator\">-></span>hm_fp<span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">/* omitted */</span>\n\nvirname <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span>hashtype <span class=\"token operator\">=</span> CLI_HASH_MD5<span class=\"token punctuation\">;</span> hashtype <span class=\"token operator\">&lt;</span> CLI_HASH_AVAIL_TYPES<span class=\"token punctuation\">;</span> hashtype<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>virname_w <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">int</span> found             <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* If no hash, skip to next type */</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>compute_hash<span class=\"token punctuation\">[</span>hashtype<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">continue</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Do hash scan */</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>ret <span class=\"token operator\">=</span> <span class=\"token function\">cli_hm_scan</span><span class=\"token punctuation\">(</span>digest<span class=\"token punctuation\">[</span>hashtype<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> map<span class=\"token operator\">-></span>len<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>virname<span class=\"token punctuation\">,</span> hdb<span class=\"token punctuation\">,</span> hashtype<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> CL_VIRUS<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        found <span class=\"token operator\">+=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>found <span class=\"token operator\">||</span> SCAN_ALLMATCHES<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>ret <span class=\"token operator\">=</span> <span class=\"token function\">cli_hm_scan_wild</span><span class=\"token punctuation\">(</span>digest<span class=\"token punctuation\">[</span>hashtype<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>virname_w<span class=\"token punctuation\">,</span> hdb<span class=\"token punctuation\">,</span> hashtype<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> CL_VIRUS<span class=\"token punctuation\">)</span>\n            found <span class=\"token operator\">+=</span> <span class=\"token number\">2</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token comment\">/* If found, do immediate hash-only FP check */</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>found <span class=\"token operator\">&amp;&amp;</span> fp<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span>hashtype2 <span class=\"token operator\">=</span> CLI_HASH_MD5<span class=\"token punctuation\">;</span> hashtype2 <span class=\"token operator\">&lt;</span> CLI_HASH_AVAIL_TYPES<span class=\"token punctuation\">;</span> hashtype2<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>compute_hash<span class=\"token punctuation\">[</span>hashtype2<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n                <span class=\"token keyword\">continue</span><span class=\"token punctuation\">;</span>\n            <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">cli_hm_scan</span><span class=\"token punctuation\">(</span>digest<span class=\"token punctuation\">[</span>hashtype2<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> map<span class=\"token operator\">-></span>len<span class=\"token punctuation\">,</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">,</span> fp<span class=\"token punctuation\">,</span> hashtype2<span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> CL_VIRUS<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n                found <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n                ret   <span class=\"token operator\">=</span> CL_CLEAN<span class=\"token punctuation\">;</span>\n                <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n            <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">cli_hm_scan_wild</span><span class=\"token punctuation\">(</span>digest<span class=\"token punctuation\">[</span>hashtype2<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">,</span> fp<span class=\"token punctuation\">,</span> hashtype2<span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> CL_VIRUS<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n                found <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n                ret   <span class=\"token operator\">=</span> CL_CLEAN<span class=\"token punctuation\">;</span>\n                <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n            <span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token comment\">/* If matched size-based hash ... */</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>found <span class=\"token operator\">%</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        viruses_found <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n        ret           <span class=\"token operator\">=</span> <span class=\"token function\">cli_append_virus</span><span class=\"token punctuation\">(</span>ctx<span class=\"token punctuation\">,</span> virname<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>SCAN_ALLMATCHES <span class=\"token operator\">||</span> ret <span class=\"token operator\">!=</span> CL_CLEAN<span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n        virname <span class=\"token operator\">=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token comment\">/* If matched size-agnostic hash ... */</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>found <span class=\"token operator\">></span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        viruses_found <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n        ret           <span class=\"token operator\">=</span> <span class=\"token function\">cli_append_virus</span><span class=\"token punctuation\">(</span>ctx<span class=\"token punctuation\">,</span> virname_w<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>SCAN_ALLMATCHES <span class=\"token operator\">||</span> ret <span class=\"token operator\">!=</span> CL_CLEAN<span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>For hash-based scanning, the <code class=\"language-text\">hm_scan</code> function is ultimately used.</p>\n<p>Inside it, the hash list contained in the <code class=\"language-text\">cli_sz_hash</code> structure is compared against the scan target’s hash using the <code class=\"language-text\">hm_cmp</code> function.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/* cli_hm_scan will scan only size-specific hashes, if any */</span>\n<span class=\"token keyword\">static</span> <span class=\"token keyword\">int</span> <span class=\"token function\">hm_scan</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>digest<span class=\"token punctuation\">,</span> <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span>virname<span class=\"token punctuation\">,</span> <span class=\"token keyword\">const</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cli_sz_hash</span> <span class=\"token operator\">*</span>szh<span class=\"token punctuation\">,</span> <span class=\"token keyword\">enum</span> <span class=\"token class-name\">CLI_HASH_TYPE</span> type<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">int</span> keylen<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">size_t</span> l<span class=\"token punctuation\">,</span> r<span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>digest <span class=\"token operator\">||</span> <span class=\"token operator\">!</span>szh <span class=\"token operator\">||</span> <span class=\"token operator\">!</span>szh<span class=\"token operator\">-></span>items<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> CL_CLEAN<span class=\"token punctuation\">;</span>\n\n    keylen <span class=\"token operator\">=</span> hashlen<span class=\"token punctuation\">[</span>type<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n    l <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    r <span class=\"token operator\">=</span> szh<span class=\"token operator\">-></span>items <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>l <span class=\"token operator\">&lt;=</span> r<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token class-name\">size_t</span> c <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>l <span class=\"token operator\">+</span> r<span class=\"token punctuation\">)</span> <span class=\"token operator\">/</span> <span class=\"token number\">2</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">int</span> res  <span class=\"token operator\">=</span> <span class=\"token function\">hm_cmp</span><span class=\"token punctuation\">(</span>digest<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>szh<span class=\"token operator\">-></span>hash_array<span class=\"token punctuation\">[</span>keylen <span class=\"token operator\">*</span> c<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> keylen<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>res <span class=\"token operator\">&lt;</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>c<span class=\"token punctuation\">)</span>\n                <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n            r <span class=\"token operator\">=</span> c <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>res <span class=\"token operator\">></span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span>\n            l <span class=\"token operator\">=</span> c <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>virname<span class=\"token punctuation\">)</span>\n                <span class=\"token operator\">*</span>virname <span class=\"token operator\">=</span> szh<span class=\"token operator\">-></span>virusnames<span class=\"token punctuation\">[</span>c<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n            <span class=\"token keyword\">return</span> CL_VIRUS<span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">return</span> CL_CLEAN<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Reference: <a href=\"https://github.com/kash1064/clamav/blob/rel/0.104/libclamav/matcher-hash.c\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">clamav/libclamav/matcher-hash.c at rel/0.104 · kash1064/clamav</a></p>\n<p>Because <code class=\"language-text\">hm_cmp</code> returns lexicographic comparison results, the hash list is searched using a binary search algorithm.</p>\n<p>The hash table itself is also relatively small, since <code class=\"language-text\">cli_htu32_find</code> is used beforehand to extract the first byte of the scan target’s hash as a key for lookup.</p>\n<p>This is how efficient hash-based scanning detects known viruses such as Eicar.</p>\n<p>After detecting the Eicar file through the above process, <code class=\"language-text\">cli_hm_scan</code> is also used to compare against the false-positive (<code class=\"language-text\">fp</code>) database.</p>\n<h2 id=\"summary\" style=\"position:relative;\"><a href=\"#summary\" aria-label=\"summary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Summary</h2>\n<p>The implementation turned out to be simpler than I expected, but the many branches and jumps still made reading the code quite exhausting.</p>\n<p>The second half got a bit rambling, but I managed to trace the full scan flow related to Eicar detection.</p>","fields":{"slug":"/clamav-simple-filescan-en","tagSlugs":["/tag/clam-av-en/","/tag/malware-en/","/tag/linux-en/","/tag/english/"]},"frontmatter":{"date":"2025-05-12","description":"Notes on tracing the scan behavior in ClamAV from invocation to detection of the Eicar test file.","tags":["ClamAV (en)","Malware (en)","Linux (en)","English"],"title":"Notes on Tracing the ClamAV Scan Process Until the Eicar Test File Is Detected","socialImage":{"publicURL":"/static/92427d7f750e6d3190ec4ea4cca00ed0/clamav-simple-filescan.png"}}}},"pageContext":{"slug":"/clamav-simple-filescan-en"}},"staticQueryHashes":["251939775","401334301","825871152"]}