{"componentChunkName":"component---src-templates-post-template-js","path":"/clamav-clamscan-en","result":{"data":{"markdownRemark":{"id":"f40026c4-d899-5c72-9d28-395fa4682e31","html":"<blockquote>\n<p>This page has been machine-translated from the <a href=\"/clamav-clamscan\">original page</a>.</p>\n</blockquote>\n<p>I have been reading through the ClamAV codebase without any particular goal, and I am publishing these notes on how clamscan works before it performs a file scan.</p>\n<p>This time, I will summarize the <code class=\"language-text\">clamscan</code> tool from ClamAV, the open-source antivirus software.</p>\n<p>Previously, in the article below, I summarized what I found when checking how <code class=\"language-text\">clamdscan</code> detects the Eicar file. This time, I wanted to look into how <code class=\"language-text\">libclamav</code> is initialized and how signatures are loaded, so I decided to use <code class=\"language-text\">clamscan</code>, which is a one-time scanner.</p>\n<p>Reference: <a href=\"/clamav-simple-filescan\">Notes on tracing the scan behavior until ClamAV detects the Eicar test file - かえるのひみつきち</a></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><a href=\"#overview-of-clamscan\">Overview of clamscan</a></li>\n<li><a href=\"#clamscan-options\">clamscan Options</a></li>\n<li><a href=\"#detecting-the-eicar-file-with-clamscan\">Detecting the Eicar File with clamscan</a></li>\n<li>\n<p><a href=\"#calling-the-scanmanager-function\">Calling the scanmanager Function</a></p>\n<ul>\n<li><a href=\"#initializing-libclamav\">Initializing libclamav</a></li>\n<li><a href=\"#retrieving-scan-options\">Retrieving Scan Options</a></li>\n<li><a href=\"#configuring-dboptions\">Configuring dboptions</a></li>\n<li><a href=\"#cl_init-and-cl_engine_new\">cl<em>init and cl</em>engine_new</a></li>\n<li><a href=\"#assigning-the-virus-detection-callback\">Assigning the Virus-Detection Callback</a></li>\n<li><a href=\"#displaying-the-progress-bar\">Displaying the Progress Bar</a></li>\n<li><a href=\"#setting-engine-options\">Setting Engine Options</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#performing-the-file-scan\">Performing the File Scan</a></p>\n<ul>\n<li><a href=\"#scan_files\">scan_files</a></li>\n<li><a href=\"#resolving-the-file-path\">Resolving the File Path</a></li>\n<li><a href=\"#scanning-the-file\">Scanning the File</a></li>\n<li><a href=\"#scan_common\">scan_common</a></li>\n<li><a href=\"#cli_magic_scan\">cli<em>magic</em>scan</a></li>\n<li><a href=\"#scanraw\">scanraw</a></li>\n</ul>\n</li>\n<li><a href=\"#summary\">Summary</a></li>\n</ul>\n<h2 id=\"overview-of-clamscan\" style=\"position:relative;\"><a href=\"#overview-of-clamscan\" aria-label=\"overview of clamscan 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>Overview of clamscan</h2>\n<p>The <code class=\"language-text\">clamscan</code> tool is a command-line tool for scanning files by using <em>libclamav</em>.</p>\n<p>Unlike <code class=\"language-text\">clamdscan</code>, <code class=\"language-text\">clamscan</code> can perform scans even when the <code class=\"language-text\">clamd</code> daemon is not running on the system.</p>\n<p>Because of that, <code class=\"language-text\">clamscan</code> generally loads signatures at runtime, so it takes a little time from command execution until the scan actually starts.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 850px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/b9e86aa51170879af3e1e65bd3fde10f/ae694/image-20251018151701287.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: 52.5%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAABWklEQVQoz5VS23KCMBTkOxSQOyLKJSTITUTLlP//ou05mcp02gfLw06Sk2Sz2T1GtLRwPxWcSSCaFJLqiUtZY+h7SKVQliWUVPA8D77vrzgcbARBgCiK9PiqG89xgiwEfNeDEhJ5ntGGh7woUBS5hhACFaNiVJCygk8PRHGMrutQ1zV6EpAkCYyMCC5ZhpBe4sL5fMHpdNLIqH48HuE4DlzXXcFr27ZhmtZa4x+YpgmDSfhSEIRIv4kK+mZMr/M8DEN90LKsP2BSHnmfwWsjTVPERMhq2rbBPM9omoY8OqzKeP4ieAdjGAbyRBJZq0nZE1a33+9XBT/VvCVclgXjbcR9HMlcpT3k1H4f/LdCTogVykpqD/nibrfTCrcoWwlHUvZ4PHXsfd/her3qkLg9WOlWUoMbl3tNKqmbmIm474QodcKbFc4fMzgYbmTtJymepgmP6a7rWxJmfAHy+j8R+mxqpwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/b9e86aa51170879af3e1e65bd3fde10f/8ac56/image-20251018151701287.webp 240w,\n/static/b9e86aa51170879af3e1e65bd3fde10f/d3be9/image-20251018151701287.webp 480w,\n/static/b9e86aa51170879af3e1e65bd3fde10f/10237/image-20251018151701287.webp 850w\"\n              sizes=\"(max-width: 850px) 100vw, 850px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/b9e86aa51170879af3e1e65bd3fde10f/8ff5a/image-20251018151701287.png 240w,\n/static/b9e86aa51170879af3e1e65bd3fde10f/e85cb/image-20251018151701287.png 480w,\n/static/b9e86aa51170879af3e1e65bd3fde10f/ae694/image-20251018151701287.png 850w\"\n            sizes=\"(max-width: 850px) 100vw, 850px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/b9e86aa51170879af3e1e65bd3fde10f/ae694/image-20251018151701287.png\"\n            alt=\"image-20251018151701287\"\n            title=\"image-20251018151701287\"\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://docs.clamav.net/manual/Usage/Scanning.html#one-time-scanning\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Scanning - ClamAV Documentation</a></p>\n<p>In this article, I want to understand how ClamAV malware scanning works by analyzing the implementation of <code class=\"language-text\">clamscan</code>.</p>\n<h2 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</h2>\n<p>The <code class=\"language-text\">clamscan</code> tool in ClamAV 1.5.0, which I use here, provides many options as shown below.</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\">1.5</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\">2025</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 help.\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    --force-to-disk[=yes/no(*)]          Create temporary files for nested file scans that would otherwise be in-memory only.\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    --json-store-html-uris[=yes(*)/no]   Store html URIs in metadata.\n                                         URIs will be written to the metadata.json file in an array called '</span>URIs<span class=\"token string\">'.\n    --json-store-pdf-uris[=yes(*)/no]    Store pdf URIs in metadata.\n                                         URIs will be written to the metadata.json file in an array called '</span>URIs<span class=\"token string\">'.\n    --json-store-extra-hashes[=yes(*)/no] Store md5 and sha1 in addition to sha2-256 in metadata.\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    --fail-if-cvd-older-than=days        Return with a nonzero error code if virus database outdated.\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<span class=\"token string\">'t scan directories matching REGEX.\n    --include=REGEX                      Only scan file names matching REGEX.\n    --include-dir=REGEX                  Only scan directories matching REGEX.\n\n    --bytecode[=yes(*)/no]               Load bytecode from the database.\n    --bytecode-unsigned[=yes/no(*)]      Load unsigned bytecode.\n                                         **Caution**: You should NEVER run bytecode signatures from untrusted sources.\n                                         Doing so may result in arbitrary code execution.\n    --bytecode-timeout=N                 Set bytecode timeout (in milliseconds).\n    --statistics[=none(*)/bytecode/pcre] Collect and print execution statistics.\n    --detect-pua[=yes/no(*)]             Detect Possibly Unwanted Applications.\n    --exclude-pua=CAT                    Skip PUA sigs of category CAT.\n    --include-pua=CAT                    Load PUA sigs of category CAT.\n    --detect-structured[=yes/no(*)]      Detect structured data (SSN, Credit Card).\n    --structured-ssn-format=X            SSN format (0=normal,1=stripped,2=both).\n    --structured-ssn-count=N             Min SSN count to generate a detect.\n    --structured-cc-count=N              Min CC count to generate a detect.\n    --structured-cc-mode=X               CC mode (0=credit debit and private label, 1=credit cards only.\n    --scan-mail[=yes(*)/no]              Scan mail files.\n    --phishing-sigs[=yes(*)/no]          Enable email signature-based phishing detection.\n    --phishing-scan-urls[=yes(*)/no]     Enable URL signature-based phishing detection.\n    --heuristic-alerts[=yes(*)/no]       Heuristic alerts.\n    --heuristic-scan-precedence[=yes/no(*)] Stop scanning as soon as a heuristic match is found.\n    --normalize[=yes(*)/no]              Normalize html, script, and text files. Use normalize=no for yara compatibility.\n    --scan-pe[=yes(*)/no]                Scan PE files.\n    --scan-elf[=yes(*)/no]               Scan ELF files.\n    --scan-ole2[=yes(*)/no]              Scan OLE2 containers.\n    --scan-pdf[=yes(*)/no]               Scan PDF files.\n    --scan-swf[=yes(*)/no]               Scan SWF files.\n    --scan-html[=yes(*)/no]              Scan HTML files.\n    --scan-xmldocs[=yes(*)/no]           Scan xml-based document files.\n    --scan-hwp3[=yes(*)/no]              Scan HWP3 files.\n    --scan-onenote[=yes(*)/no]           Scan OneNote files.\n    --scan-archive[=yes(*)/no]           Scan archive files (supported by libclamav).\n    --scan-image[=yes(*)/no]             Scan image (graphics) files.\n    --scan-image-fuzzy-hash[=yes(*)/no]  Detect files by calculating image (graphics) fuzzy hashes.\n    --alert-broken[=yes/no(*)]           Alert on broken executable files (PE &amp; ELF).\n    --alert-broken-media[=yes/no(*)]     Alert on broken graphics files (JPEG, TIFF, PNG, GIF).\n    --alert-encrypted[=yes/no(*)]        Alert on encrypted archives and documents.\n    --alert-encrypted-archive[=yes/no(*)] Alert on encrypted archives.\n    --alert-encrypted-doc[=yes/no(*)]    Alert on encrypted documents.\n    --alert-macros[=yes/no(*)]           Alert on OLE2 files containing VBA macros.\n    --alert-exceeds-max[=yes/no(*)]      Alert on files that exceed max file size, max scan size, or max recursion limit.\n    --alert-phishing-ssl[=yes/no(*)]     Alert on emails containing SSL mismatches in URLs.\n    --alert-phishing-cloak[=yes/no(*)]   Alert on emails containing cloaked URLs.\n    --alert-partition-intersection[=yes/no(*)] Alert on raw DMG image files containing partition intersections.\n    --nocerts                            Disable authenticode certificate chain verification in PE files.\n    --dumpcerts                          Dump authenticode certificate chain in PE files.\n\n    --max-scantime=#n                    Scan time longer than this will be skipped and assumed clean (milliseconds).\n    --max-filesize=#n                    Files larger than this will be skipped and assumed clean.\n    --max-scansize=#n                    The maximum amount of data to scan for each container file (**).\n    --max-files=#n                       The maximum number of files to scan for each container file (**).\n    --max-recursion=#n                   Maximum archive recursion level for container file (**).\n    --max-dir-recursion=#n               Maximum directory recursion level.\n    --max-embeddedpe=#n                  Maximum size file to check for embedded PE.\n    --max-htmlnormalize=#n               Maximum size of HTML file to normalize.\n    --max-htmlnotags=#n                  Maximum size of normalized HTML file to scan.\n    --max-scriptnormalize=#n             Maximum size of script file to normalize.\n    --max-ziptypercg=#n                  Maximum size zip to type reanalyze.\n    --max-partitions=#n                  Maximum number of partitions in disk image to be scanned.\n    --max-iconspe=#n                     Maximum number of icons in PE file to be scanned.\n    --max-rechwp3=#n                     Maximum recursive calls to HWP3 parsing function.\n    --pcre-match-limit=#n                Maximum calls to the PCRE match function.\n    --pcre-recmatch-limit=#n             Maximum recursive calls to the PCRE match function.\n    --pcre-max-filesize=#n               Maximum size file to perform PCRE subsig matching.\n    --disable-cache                      Disable caching and cache checks for hash sums of scanned files.\n    --hash-hint                          The file hash so that libclamav does not need to calculate it.\n                                         The type of hash must match the '</span>--hash-alg<span class=\"token string\">'.\n    --log-hash                           Print the file hash after each file scanned.\n                                         The type of hash printed will match the '</span>--hash-alg<span class=\"token string\">'.\n    --hash-alg                           The hashing algorithm used for either '</span>--hash-hint<span class=\"token string\">' or '</span>--log-hash<span class=\"token string\">'.\n                                         Supported algorithms are '</span>md5<span class=\"token string\">', '</span>sha1<span class=\"token string\">', '</span>sha2-256<span class=\"token string\">'.\n                                         If not specified, the default is '</span>sha2-256<span class=\"token string\">'.\n    --file-type-hint                     The file type hint so that libclamav can optimize scanning.\n                                         E.g. '</span>pe<span class=\"token string\">', '</span>elf<span class=\"token string\">', '</span><span class=\"token function\">zip</span><span class=\"token string\">', etc.\n                                         You may also use ClamAV type names such as '</span>CL_TYPE_PE<span class=\"token string\">'.\n                                         ClamAV will ignore the hint if it is not familiar with the specified type.\n                                         See also: https://docs.clamav.net/appendix/FileTypes.html#file-types\n    --log-file-type                      Print the file type after each file scanned.\n    --cvdcertsdir=DIRECTORY              Specify a directory containing the root\n                                         CA cert needed to verify detached CVD digital signatures.\n                                         If not provided, then clamscan will look in the default directory.\n    --fips-limits                        Enforce FIPS-like limits on using hash algorithms for\n                                         cryptographic purposes. Will disable MD5 &amp; SHA1.\n                                         FP sigs and will require '</span>.sign' files to verify CVD\n                                         authenticity.\n\nEnvironment Variables:\n\n    LD_LIBRARY_PATH                      May be used on startup to <span class=\"token function\">find</span> the libclamunrar_iface\n                                         shared library module to <span class=\"token builtin class-name\">enable</span> RAR archive support.\n    CVD_CERTS_DIR                        Specify a directory containing the root CA cert needed\n                                         to verify detached CVD digital signatures.\n                                         If not provided, <span class=\"token keyword\">then</span> clamscan will <span class=\"token function\">look</span> <span class=\"token keyword\">in</span> the default directory.\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<h2 id=\"detecting-the-eicar-file-with-clamscan\" style=\"position:relative;\"><a href=\"#detecting-the-eicar-file-with-clamscan\" aria-label=\"detecting the eicar file with clamscan 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>Detecting the Eicar File with clamscan</h2>\n<p>First, I will save the debug log showing how <code class=\"language-text\">clamscan</code> detects the Eicar test malware to a file with the command below.</p>\n<p>Because <code class=\"language-text\">clamscan</code>’s debug information is output to <code class=\"language-text\">stderr</code> rather than <code class=\"language-text\">stdout</code>, I redirect <code class=\"language-text\">stderr</code> to <code class=\"language-text\">stdout</code> with <code class=\"language-text\">2>&amp;1</code> and then pipe it onward.</p>\n<p>(The <code class=\"language-text\">--stdout</code> option, which changes the normal output destination to <code class=\"language-text\">stdout</code>, does not affect debug messages.)</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">clamscan --debug --disable-cache --verbose --stdout eicar <span class=\"token operator\"><span class=\"token file-descriptor important\">2</span>></span><span class=\"token file-descriptor important\">&amp;1</span> <span class=\"token operator\">|</span> <span class=\"token function\">tee</span> logfile.txt</code></pre></div>\n<p>When debugging with <code class=\"language-text\">gdb</code>, you can use <code class=\"language-text\">gdb --args</code> as shown below.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">gdb --args clamscan --debug --disable-cache --verbose --stdout eicar <span class=\"token operator\"><span class=\"token file-descriptor important\">2</span>></span><span class=\"token file-descriptor important\">&amp;1</span></code></pre></div>\n<p>The debug log produced this way contained roughly 1,500 lines of information.</p>\n<p>Also, because I did not use an option to disable the summary this time, the final output included a summary like the one below together with a message indicating that <code class=\"language-text\">clamscan</code> detected the Eicar 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: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/0b20bca300680e9f76757ad3d7751797/adef7/image-20251019125033073.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.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAABbUlEQVQoz5WT226DMBBE+Y/cSBTIFQVIbAzGNKS3l6rt///MdHcToyalrfIwMkbaw8zuElhr4RoHrTXyPCPlSJIEm81GtN1u5VytVqIwDDEcDjEajTAej+X0z6ygrms0TYOyqsBwY0q5s5xzaNsW7bGVD2ZZJtA4jjGfz69AHdDVTopNaVAR1BiDglSVJYqiwH6/x263ExBDwukUUxI77QVae3bIoJqeSwJpXZDb6uzu1EIpJYDBYNBF7INdIlsCOnKjCWgFyHAf0TtcLpeYTCZXoO9wr8A9v6N5/YR9ekPz8gFtKoGkaYr1ei3yA2Io92+xWCCOoq6XLH4X0T2oH05wx0dU7ghjySkNpSB3h4OCJfcMZ6cJTZun2xfzJjL10NUC4fg8GF4VdhORCx7AbDaT83ZVeiPzzqXkgBvvY3ERu/H7drt3fzrkifIAuGe+8Lei/2Bd5JKmys442j3FvUClNJRWl18v/7Ea9+oLJopg2aX+QfUAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/0b20bca300680e9f76757ad3d7751797/8ac56/image-20251019125033073.webp 240w,\n/static/0b20bca300680e9f76757ad3d7751797/d3be9/image-20251019125033073.webp 480w,\n/static/0b20bca300680e9f76757ad3d7751797/e46b2/image-20251019125033073.webp 960w,\n/static/0b20bca300680e9f76757ad3d7751797/f992d/image-20251019125033073.webp 1440w,\n/static/0b20bca300680e9f76757ad3d7751797/211fa/image-20251019125033073.webp 1716w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/0b20bca300680e9f76757ad3d7751797/8ff5a/image-20251019125033073.png 240w,\n/static/0b20bca300680e9f76757ad3d7751797/e85cb/image-20251019125033073.png 480w,\n/static/0b20bca300680e9f76757ad3d7751797/d9199/image-20251019125033073.png 960w,\n/static/0b20bca300680e9f76757ad3d7751797/07a9c/image-20251019125033073.png 1440w,\n/static/0b20bca300680e9f76757ad3d7751797/adef7/image-20251019125033073.png 1716w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/0b20bca300680e9f76757ad3d7751797/d9199/image-20251019125033073.png\"\n            alt=\"image-20251019125033073\"\n            title=\"image-20251019125033073\"\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>From here on, I will follow the sequence that leads up to <code class=\"language-text\">clamscan</code> detecting the Eicar file.</p>\n<h2 id=\"calling-the-scanmanager-function\" style=\"position:relative;\"><a href=\"#calling-the-scanmanager-function\" aria-label=\"calling the scanmanager 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 scanmanager Function</h2>\n<p>The very first debug messages that appeared were the following lines.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">LibClamAV debug: searching <span class=\"token keyword\">for</span> unrar, user-searchpath: /usr/local/lib\nLibClamAV debug: <span class=\"token function\">unrar</span> support loaded from /usr/local/lib/libclamunrar_iface.so.12.1.0\nLibClamAV debug: Initialized <span class=\"token number\">1.5</span>.0 engine\nLibClamAV debug: Initializing phishcheck module\nLibClamAV debug: Phishcheck: Compiling regex: ^ *<span class=\"token punctuation\">(</span>http<span class=\"token operator\">|</span>https<span class=\"token operator\">|</span>ftp:<span class=\"token punctuation\">(</span>//<span class=\"token punctuation\">)</span>?<span class=\"token punctuation\">)</span>?<span class=\"token punctuation\">[</span><span class=\"token number\">0</span>-9<span class=\"token punctuation\">]</span><span class=\"token punctuation\">{</span><span class=\"token number\">1,3</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">\\</span>.<span class=\"token punctuation\">[</span><span class=\"token number\">0</span>-9<span class=\"token punctuation\">]</span><span class=\"token punctuation\">{</span><span class=\"token number\">1,3</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span><span class=\"token number\">3</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">[</span>/?:<span class=\"token punctuation\">]</span>? *$\nLibClamAV debug: Phishcheck module initialized\nLibClamAV debug: Bytecode initialized <span class=\"token keyword\">in</span> interpreter mode\nLibClamAV debug: clean_cache_init: Caching disabled.\nLibClamAV debug: clean_cache_init: Cache initialized successfully.\nLibClamAV debug: Adding certificate to verifier store: X509 <span class=\"token punctuation\">{</span> serial_number: <span class=\"token string\">\"0493F2B851C5D5BED1\"</span>, signature_algorithm: sha512WithRSAEncryption, issuer: <span class=\"token punctuation\">[</span>organizationalUnitName <span class=\"token operator\">=</span> <span class=\"token string\">\"Arbor\"</span>, organizationName <span class=\"token operator\">=</span> <span class=\"token string\">\"Cisco\"</span>, commonName <span class=\"token operator\">=</span> <span class=\"token string\">\"Cisco Software Identity Root CA RSA 4096 SHA512 2099\"</span><span class=\"token punctuation\">]</span>, subject: <span class=\"token punctuation\">[</span>organizationalUnitName <span class=\"token operator\">=</span> <span class=\"token string\">\"Arbor\"</span>, organizationName <span class=\"token operator\">=</span> <span class=\"token string\">\"Cisco\"</span>, commonName <span class=\"token operator\">=</span> <span class=\"token string\">\"Cisco Software Identity Root CA RSA 4096 SHA512 2099\"</span><span class=\"token punctuation\">]</span>, not_before: Jan <span class=\"token number\">24</span> <span class=\"token number\">18</span>:45:25 <span class=\"token number\">2024</span> GMT, not_after: Jan <span class=\"token number\">24</span> <span class=\"token number\">18</span>:45:25 <span class=\"token number\">2099</span> GMT, public_key: PKey <span class=\"token punctuation\">{</span> algorithm: <span class=\"token string\">\"RSA\"</span> <span class=\"token punctuation\">}</span> <span class=\"token punctuation\">}</span>\nLibClamAV debug: Verifier created successfully</code></pre></div>\n<p>Judging from the message content, the output on the first line seems to come from the following location inside <code class=\"language-text\">*load_module(const char *name, const char *featurename)</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/*\n* Search in \"&lt;prefix>/lib\" checking with each of the different possible suffixes.\n*/</span>\n<span class=\"token function\">cli_dbgmsg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"searching for %s, user-searchpath: %s\\n\"</span><span class=\"token punctuation\">,</span> featurename<span class=\"token punctuation\">,</span> SEARCH_LIBDIR<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Reference: <a href=\"https://sourcegraph.com/github.com/Cisco-Talos/clamav@clamav-1.5.0/-/blob/libclamav/others.c?L219\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">others.c - libclamav - Cisco-Talos/clamav - Sourcegraph</a></p>\n<p>It also appears that this method is called from the <code class=\"language-text\">rarload</code> function in the same 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: 765px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/16ce136204e258f935d65a31d1e7b7be/bbb77/image-20251018175708668.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: 44.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAABWUlEQVQoz42RSW7bQBBFdQg7oticyebcbDGcQg0W6ASGvfTW97/HS4dRtDAQWIuPqkXVw6/6m3p/ZOtW2NkPrKDhMe6J04ZGaUrVI7IZJ1RsdwmWSL/UxosaRKAQcYvl18iwIPAyZFSRGG1tuQ5u1wX5NTCI9wg5sGt+IfID3fyC7haKVBtgeQOuUPsOYJT2OOmIXS8EqQGHxnGkV0eP1zP/gO6BrUDXnLuLWmz1jEg6Hr6FPFixUbIC7wXdgH6s8fIZS/0kqY+orCEKS0qpkFJjOdlfh7clueqf68/a+OY8IXt21cWEcw0lKEhMDcP6v4u3N3yqm7w5m991RPWJYnqjGF+R1UQ/nZiOC6fzQj88MbRnDsOFub+wbw5M38/s9YGsHBnbE1ofSYrBpCw7HL/EckviaqZVA1GsqNoL08sH4/JOmpvg3AI/qPDMrOMVuNdqu/nai2v/G6zw/1az5qIVAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/16ce136204e258f935d65a31d1e7b7be/8ac56/image-20251018175708668.webp 240w,\n/static/16ce136204e258f935d65a31d1e7b7be/d3be9/image-20251018175708668.webp 480w,\n/static/16ce136204e258f935d65a31d1e7b7be/33b41/image-20251018175708668.webp 765w\"\n              sizes=\"(max-width: 765px) 100vw, 765px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/16ce136204e258f935d65a31d1e7b7be/8ff5a/image-20251018175708668.png 240w,\n/static/16ce136204e258f935d65a31d1e7b7be/e85cb/image-20251018175708668.png 480w,\n/static/16ce136204e258f935d65a31d1e7b7be/bbb77/image-20251018175708668.png 765w\"\n            sizes=\"(max-width: 765px) 100vw, 765px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/16ce136204e258f935d65a31d1e7b7be/bbb77/image-20251018175708668.png\"\n            alt=\"image-20251018175708668\"\n            title=\"image-20251018175708668\"\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, when I captured the call stack up to this point with the debugger, I confirmed that these <code class=\"language-text\">libclamav</code> functions are called from the <code class=\"language-text\">scanmanager</code> function in <code class=\"language-text\">clamscan</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: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/fc5d25a7199e7f0a068c65162370e911/2b36a/image-20251018220749733.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: 10.416666666666668%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAfklEQVQI1x3NSw6CMBgAYQ/SSuGnL6SElopggjvvf6SxcTH5lnML+4Wki5yFRwmErRLqgtSE2Wbu64xNEy54jAxo26PGlhh0q+ubWqOU+nuL9cO4f6mvyPMU8rGSzjfTueGOwlBXZC9IyYR5wYdIjJHOWUybjNHReY91DhHhB5ktOzl4uMpWAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/fc5d25a7199e7f0a068c65162370e911/8ac56/image-20251018220749733.webp 240w,\n/static/fc5d25a7199e7f0a068c65162370e911/d3be9/image-20251018220749733.webp 480w,\n/static/fc5d25a7199e7f0a068c65162370e911/e46b2/image-20251018220749733.webp 960w,\n/static/fc5d25a7199e7f0a068c65162370e911/f992d/image-20251018220749733.webp 1440w,\n/static/fc5d25a7199e7f0a068c65162370e911/882b9/image-20251018220749733.webp 1920w,\n/static/fc5d25a7199e7f0a068c65162370e911/dc083/image-20251018220749733.webp 2268w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/fc5d25a7199e7f0a068c65162370e911/8ff5a/image-20251018220749733.png 240w,\n/static/fc5d25a7199e7f0a068c65162370e911/e85cb/image-20251018220749733.png 480w,\n/static/fc5d25a7199e7f0a068c65162370e911/d9199/image-20251018220749733.png 960w,\n/static/fc5d25a7199e7f0a068c65162370e911/07a9c/image-20251018220749733.png 1440w,\n/static/fc5d25a7199e7f0a068c65162370e911/29114/image-20251018220749733.png 1920w,\n/static/fc5d25a7199e7f0a068c65162370e911/2b36a/image-20251018220749733.png 2268w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/fc5d25a7199e7f0a068c65162370e911/d9199/image-20251018220749733.png\"\n            alt=\"image-20251018220749733\"\n            title=\"image-20251018220749733\"\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>I will not describe this entire sequence in detail here, but at a high level it seems to work as follows.</p>\n<ul>\n<li>In <code class=\"language-text\">clamscan::main</code>, command-line arguments are stored in the <code class=\"language-text\">opts</code> structure, and several options are enabled by reading the command-line arguments with the <code class=\"language-text\">optget</code> function.</li>\n</ul>\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></code></pre></div>\n<ul>\n<li>The memory region of the <code class=\"language-text\">info</code> variable of type <code class=\"language-text\">s_info</code>, defined as a global variable, is initialized with <code class=\"language-text\">memset</code>.</li>\n</ul>\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\">s_info</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">int</span> sigs<span class=\"token punctuation\">;</span>         <span class=\"token comment\">/* number of signatures */</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">int</span> dirs<span class=\"token punctuation\">;</span>         <span class=\"token comment\">/* number of scanned directories */</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">int</span> files<span class=\"token punctuation\">;</span>        <span class=\"token comment\">/* number of scanned files */</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">int</span> ifiles<span class=\"token punctuation\">;</span>       <span class=\"token comment\">/* number of infected files */</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">int</span> errors<span class=\"token punctuation\">;</span>       <span class=\"token comment\">/* number of errors */</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span> <span class=\"token keyword\">int</span> blocks<span class=\"token punctuation\">;</span>  <span class=\"token comment\">/* number of *scanned* 16kb blocks */</span>\n    <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span> <span class=\"token keyword\">int</span> rblocks<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* number of *read* 16kb blocks */</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<ul>\n<li>The <code class=\"language-text\">scanmanager</code> function is called together with the command-line arguments.</li>\n<li>The <code class=\"language-text\">scanmanager</code> function initializes <code class=\"language-text\">libclamav</code>, determines the scan target, and performs the scan.</li>\n</ul>\n<p>In the flow above, the <code class=\"language-text\">scanmanager</code> function effectively serves as the main driver that requests file scanning in <code class=\"language-text\">clamscan</code>.</p>\n<p>For that reason, once <code class=\"language-text\">scanmanager</code> returns its result, the <code class=\"language-text\">clamscan</code> execution also ends.</p>\n<p>Reference: <a href=\"https://sourcegraph.com/github.com/Cisco-Talos/clamav@clamav-1.5.0/-/blob/clamscan/clamscan.c?L185\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">clamscan.c - clamscan - Cisco-Talos/clamav - Sourcegraph</a></p>\n<h3 id=\"initializing-libclamav\" style=\"position:relative;\"><a href=\"#initializing-libclamav\" aria-label=\"initializing libclamav 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>Initializing libclamav</h3>\n<h3 id=\"retrieving-scan-options\" style=\"position:relative;\"><a href=\"#retrieving-scan-options\" aria-label=\"retrieving scan 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>Retrieving Scan Options</h3>\n<p>When the <code class=\"language-text\">scanmanager</code> function is called, it first initializes the <code class=\"language-text\">options</code> variable of type <code class=\"language-text\">cl_scan_options</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/* Initalize scan options struct */</span>\n<span class=\"token function\">memset</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>options<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><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></code></pre></div>\n<p>This structure stores the scan options used during scanning.</p>\n<p>The <code class=\"language-text\">cl_scan_options</code> structure defines members such as <code class=\"language-text\">general</code> and <code class=\"language-text\">heuristic</code>, and it appears that options are changed by manipulating these bitmasks.</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 first set of options, <code class=\"language-text\">general</code>, seems to be manipulated mainly by the following code.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/* general */</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_GENERAL_ALLMATCHES</span>                  <span class=\"token expression\"><span class=\"token number\">0x1</span>  </span><span class=\"token comment\">/* scan in all-match mode */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_GENERAL_COLLECT_METADATA</span>            <span class=\"token expression\"><span class=\"token number\">0x2</span>  </span><span class=\"token comment\">/* collect metadata (--gen-json) */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_GENERAL_HEURISTICS</span>                  <span class=\"token expression\"><span class=\"token number\">0x4</span>  </span><span class=\"token comment\">/* option to enable heuristic alerts */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_GENERAL_HEURISTIC_PRECEDENCE</span>        <span class=\"token expression\"><span class=\"token number\">0x8</span>  </span><span class=\"token comment\">/* allow heuristic match to take precedence. */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_GENERAL_UNPRIVILEGED</span>                <span class=\"token expression\"><span class=\"token number\">0x10</span> </span><span class=\"token comment\">/* scanner will not have read access to files. */</span></span>\n\n<span class=\"token comment\">/* set scan options */</span>\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\">\"allmatch\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    options<span class=\"token punctuation\">.</span>general <span class=\"token operator\">|=</span> CL_SCAN_GENERAL_ALLMATCHES<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 function\">optget</span><span class=\"token punctuation\">(</span>opts<span class=\"token punctuation\">,</span> <span class=\"token string\">\"heuristic-scan-precedence\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">)</span>\n    options<span class=\"token punctuation\">.</span>general <span class=\"token operator\">|=</span> CL_SCAN_GENERAL_HEURISTIC_PRECEDENCE<span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">/* TODO: Remove deprecated option in a future feature release */</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</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\">\"algorithmic-detection\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">)</span> <span class=\"token operator\">&amp;&amp;</span> <span class=\"token comment\">/* &amp;&amp; used due to default-yes for both options */</span>\n    <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\">\"heuristic-alerts\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    options<span class=\"token punctuation\">.</span>general <span class=\"token operator\">|=</span> CL_SCAN_GENERAL_HEURISTICS<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">/* JSON check to prevent engine loading if specified without libjson-c  */</span>\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\">\"gen-json\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled<span class=\"token punctuation\">)</span>\n    options<span class=\"token punctuation\">.</span>general <span class=\"token operator\">|=</span> CL_SCAN_GENERAL_COLLECT_METADATA<span class=\"token punctuation\">;</span></code></pre></div>\n<p>Among the options above, <code class=\"language-text\">heuristic-scan-precedence</code> specifies that scanning should stop immediately when a heuristic match is found.</p>\n<p>Also, the <code class=\"language-text\">gen-json</code> option is intended for testing and development, and instructs <code class=\"language-text\">clamscan</code> to generate JSON-formatted information including metadata for the scanned file.</p>\n<p>When this option is used in debug mode, JSON-formatted information like the following seems to be displayed.</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/b7987a97d79bfa840cde02c4d0b0015c/1cfc2/image-20251019132207507.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: 77.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsTAAALEwEAmpwYAAABq0lEQVQ4y51U2ZKCMBDMb4gnKocICB4ghyXqavn/P9SbHsVCdy2XfehKMoFOz/QkqqoqZFmO3a5EEAaI4yU2mw3CcAF/PtfrGJGGN5shCAJEUYw4ijAcDtHv9zEYDJ6g9vtKEyTI8wxlWcL35/Jhr9d7gOvfYiR4JVWH6oDr9SqqjsejVpvBdV3ZpIpXBZ+g1us1kiTBcrnEZDKR07nR6XRgGMZDUbfbvaF3G59id1Ctqg4HfJ3PQrperST9NE2RF4XU07KmGhYcx9FwYds2HA3GZC5xR+bMSNEQpinFjxZS+Lr4YozvY67NCcNQxyLZ45zxes7vOJqmCWXZlvzAE6bTKcbjsT7Rls1mOkyfqOcyNuKGcU95NBrheDphu92iKEpJnSfTmH+ZQsIsz5GkiaTBU2oz3rXGK5r7isWluwTTpaqmsk9kPxSyXegSSQyj86hRG4VPhFRF9zzP07ULH27OZt7b6/WxhufLRRtS6OuXC1ldhraGCCFVxDpt9iGdbbbHa9p/UavoLPuv7kFCTLrHTL1uVUO5GX4gT5frOrp2t2fKv98CNnwbwm9vJMWZDbCaxQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/b7987a97d79bfa840cde02c4d0b0015c/8ac56/image-20251019132207507.webp 240w,\n/static/b7987a97d79bfa840cde02c4d0b0015c/d3be9/image-20251019132207507.webp 480w,\n/static/b7987a97d79bfa840cde02c4d0b0015c/131f1/image-20251019132207507.webp 900w\"\n              sizes=\"(max-width: 900px) 100vw, 900px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/b7987a97d79bfa840cde02c4d0b0015c/8ff5a/image-20251019132207507.png 240w,\n/static/b7987a97d79bfa840cde02c4d0b0015c/e85cb/image-20251019132207507.png 480w,\n/static/b7987a97d79bfa840cde02c4d0b0015c/1cfc2/image-20251019132207507.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/b7987a97d79bfa840cde02c4d0b0015c/1cfc2/image-20251019132207507.png\"\n            alt=\"image-20251019132207507\"\n            title=\"image-20251019132207507\"\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>The second group, the <code class=\"language-text\">parse</code> option, appears to be a set of flags specifying which file types the engine should parse.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/* parsing capabilities options */</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_PARSE_ARCHIVE</span>                       <span class=\"token expression\"><span class=\"token number\">0x1</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_PARSE_ELF</span>                           <span class=\"token expression\"><span class=\"token number\">0x2</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_PARSE_PDF</span>                           <span class=\"token expression\"><span class=\"token number\">0x4</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_PARSE_SWF</span>                           <span class=\"token expression\"><span class=\"token number\">0x8</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_PARSE_HWP3</span>                          <span class=\"token expression\"><span class=\"token number\">0x10</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_PARSE_XMLDOCS</span>                       <span class=\"token expression\"><span class=\"token number\">0x20</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_PARSE_MAIL</span>                          <span class=\"token expression\"><span class=\"token number\">0x40</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_PARSE_OLE2</span>                          <span class=\"token expression\"><span class=\"token number\">0x80</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_PARSE_HTML</span>                          <span class=\"token expression\"><span class=\"token number\">0x100</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_PARSE_PE</span>                            <span class=\"token expression\"><span class=\"token number\">0x200</span></span></span></code></pre></div>\n<p>The <code class=\"language-text\">heuristic</code> option then enables several heuristic alerts.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/* heuristic alerting options */</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_HEURISTIC_BROKEN</span>                    <span class=\"token expression\"><span class=\"token number\">0x2</span>    </span><span class=\"token comment\">/* alert on broken PE and broken ELF files */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_HEURISTIC_EXCEEDS_MAX</span>               <span class=\"token expression\"><span class=\"token number\">0x4</span>    </span><span class=\"token comment\">/* alert when files exceed scan limits (filesize, max scansize, or max recursion depth) */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_HEURISTIC_PHISHING_SSL_MISMATCH</span>     <span class=\"token expression\"><span class=\"token number\">0x8</span>    </span><span class=\"token comment\">/* alert on SSL mismatches */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_HEURISTIC_PHISHING_CLOAK</span>            <span class=\"token expression\"><span class=\"token number\">0x10</span>   </span><span class=\"token comment\">/* alert on cloaked URLs in emails */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_HEURISTIC_MACROS</span>                    <span class=\"token expression\"><span class=\"token number\">0x20</span>   </span><span class=\"token comment\">/* alert on OLE2 files containing macros */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_HEURISTIC_ENCRYPTED_ARCHIVE</span>         <span class=\"token expression\"><span class=\"token number\">0x40</span>   </span><span class=\"token comment\">/* alert if archive is encrypted (rar, zip, etc) */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_HEURISTIC_ENCRYPTED_DOC</span>             <span class=\"token expression\"><span class=\"token number\">0x80</span>   </span><span class=\"token comment\">/* alert if a document is encrypted (pdf, docx, etc) */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_HEURISTIC_PARTITION_INTXN</span>           <span class=\"token expression\"><span class=\"token number\">0x100</span>  </span><span class=\"token comment\">/* alert if partition table size doesn't make sense */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_HEURISTIC_STRUCTURED</span>                <span class=\"token expression\"><span class=\"token number\">0x200</span>  </span><span class=\"token comment\">/* data loss prevention options, i.e. alert when detecting personal information */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_HEURISTIC_STRUCTURED_SSN_NORMAL</span>     <span class=\"token expression\"><span class=\"token number\">0x400</span>  </span><span class=\"token comment\">/* alert when detecting social security numbers */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_HEURISTIC_STRUCTURED_SSN_STRIPPED</span>   <span class=\"token expression\"><span class=\"token number\">0x800</span>  </span><span class=\"token comment\">/* alert when detecting stripped social security numbers */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_HEURISTIC_STRUCTURED_CC</span>             <span class=\"token expression\"><span class=\"token number\">0x1000</span> </span><span class=\"token comment\">/* alert when detecting credit card numbers */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_HEURISTIC_BROKEN_MEDIA</span>              <span class=\"token expression\"><span class=\"token number\">0x2000</span> </span><span class=\"token comment\">/* alert if a file does not match the identified file format, works with JPEG, TIFF, GIF, PNG */</span></span></code></pre></div>\n<p>And the <code class=\"language-text\">mail</code> and <code class=\"language-text\">dev</code> options enable the following capabilities, respectively.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/* mail scanning options */</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_MAIL_PARTIAL_MESSAGE</span>                <span class=\"token expression\"><span class=\"token number\">0x1</span></span></span>\n\n<span class=\"token comment\">/* dev options */</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_DEV_COLLECT_SHA</span>                     <span class=\"token expression\"><span class=\"token number\">0x1</span> </span><span class=\"token comment\">/* Enables hash output in sha-collect builds - for internal use only */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_SCAN_DEV_COLLECT_PERFORMANCE_INFO</span>        <span class=\"token expression\"><span class=\"token number\">0x2</span> </span><span class=\"token comment\">/* collect performance timings */</span></span></code></pre></div>\n<h3 id=\"configuring-dboptions\" style=\"position:relative;\"><a href=\"#configuring-dboptions\" aria-label=\"configuring dboptions 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>Configuring dboptions</h3>\n<p>Inside the <code class=\"language-text\">scanmanager</code> function, a bitmask is also configured in <code class=\"language-text\">dboptions</code>, which is initialized with <code class=\"language-text\">unsigned int dboptions = 0</code>.</p>\n<p>The flags that can be set in <code class=\"language-text\">dboptions</code> are defined as follows.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/* db options */</span>\n<span class=\"token comment\">// clang-format off</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_PHISHING</span>          <span class=\"token expression\"><span class=\"token number\">0x2</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_PHISHING_URLS</span>     <span class=\"token expression\"><span class=\"token number\">0x8</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_PUA</span>               <span class=\"token expression\"><span class=\"token number\">0x10</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_CVDNOTMP</span>          <span class=\"token expression\"><span class=\"token number\">0x20</span>    </span><span class=\"token comment\">/* obsolete */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_OFFICIAL</span>          <span class=\"token expression\"><span class=\"token number\">0x40</span>    </span><span class=\"token comment\">/* internal */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_PUA_MODE</span>          <span class=\"token expression\"><span class=\"token number\">0x80</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_PUA_INCLUDE</span>       <span class=\"token expression\"><span class=\"token number\">0x100</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_PUA_EXCLUDE</span>       <span class=\"token expression\"><span class=\"token number\">0x200</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_COMPILED</span>          <span class=\"token expression\"><span class=\"token number\">0x400</span>   </span><span class=\"token comment\">/* internal */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_DIRECTORY</span>         <span class=\"token expression\"><span class=\"token number\">0x800</span>   </span><span class=\"token comment\">/* internal */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_OFFICIAL_ONLY</span>     <span class=\"token expression\"><span class=\"token number\">0x1000</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_BYTECODE</span>          <span class=\"token expression\"><span class=\"token number\">0x2000</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_SIGNED</span>            <span class=\"token expression\"><span class=\"token number\">0x4000</span>  </span><span class=\"token comment\">/* internal */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_BYTECODE_UNSIGNED</span> <span class=\"token expression\"><span class=\"token number\">0x8000</span>  </span><span class=\"token comment\">/* Caution: You should never run bytecode signatures from untrusted sources. Doing so may result in arbitrary code execution. */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_UNSIGNED</span>          <span class=\"token expression\"><span class=\"token number\">0x10000</span> </span><span class=\"token comment\">/* internal */</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_BYTECODE_STATS</span>    <span class=\"token expression\"><span class=\"token number\">0x20000</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_ENHANCED</span>          <span class=\"token expression\"><span class=\"token number\">0x40000</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_PCRE_STATS</span>        <span class=\"token expression\"><span class=\"token number\">0x80000</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_YARA_EXCLUDE</span>      <span class=\"token expression\"><span class=\"token number\">0x100000</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_YARA_ONLY</span>         <span class=\"token expression\"><span class=\"token number\">0x200000</span></span></span>\n\n<span class=\"token comment\">/* recommended db settings */</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">CL_DB_STDOPT</span> <span class=\"token expression\"><span class=\"token punctuation\">(</span>CL_DB_PHISHING <span class=\"token operator\">|</span> CL_DB_PHISHING_URLS <span class=\"token operator\">|</span> CL_DB_BYTECODE<span class=\"token punctuation\">)</span></span></span></code></pre></div>\n<p>These <code class=\"language-text\">dboptions</code> values are used as arguments when <code class=\"language-text\">scanmanager</code> calls the <code class=\"language-text\">cl_load</code> function to load the virus database.</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>opt <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\">\"database\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>active<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>opt<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\">cl_load</span><span class=\"token punctuation\">(</span>opt<span class=\"token operator\">-></span>strarg<span class=\"token punctuation\">,</span> engine<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>info<span class=\"token punctuation\">.</span>sigs<span class=\"token punctuation\">,</span> dboptions<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\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"!%s\\n\"</span><span class=\"token punctuation\">,</span> <span class=\"token function\">cl_strerror</span><span class=\"token punctuation\">(</span>ret<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n            ret <span class=\"token operator\">=</span> <span class=\"token number\">2</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        opt <span class=\"token operator\">=</span> opt<span class=\"token operator\">-></span>nextarg<span class=\"token punctuation\">;</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    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>dbdir <span class=\"token operator\">=</span> <span class=\"token function\">freshdbdir</span><span class=\"token punctuation\">(</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 punctuation\">(</span>ret <span class=\"token operator\">=</span> <span class=\"token function\">cl_load</span><span class=\"token punctuation\">(</span>dbdir<span class=\"token punctuation\">,</span> engine<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>info<span class=\"token punctuation\">.</span>sigs<span class=\"token punctuation\">,</span> dboptions<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\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"!%s\\n\"</span><span class=\"token punctuation\">,</span> <span class=\"token function\">cl_strerror</span><span class=\"token punctuation\">(</span>ret<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token function\">free</span><span class=\"token punctuation\">(</span>dbdir<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        ret <span class=\"token operator\">=</span> <span class=\"token number\">2</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    <span class=\"token function\">free</span><span class=\"token punctuation\">(</span>dbdir<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>For example, when <code class=\"language-text\">CL_DB_PHISHING</code> is enabled, phishing signatures are loaded, and when <code class=\"language-text\">CL_DB_PUA</code> is enabled, PUA signatures are loaded.</p>\n<p>Reference: <a href=\"https://docs.clamav.net/manual/Development/libclamav.html#database-loading\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">libclamav - ClamAV Documentation</a></p>\n<h3 id=\"clinit-and-clengine_new\" style=\"position:relative;\"><a href=\"#clinit-and-clengine_new\" aria-label=\"clinit and clengine_new 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>cl<em>init and cl</em>engine_new</h3>\n<p>Inside the <code class=\"language-text\">scanmanager</code> function, the following functions are called in order to initialize <code class=\"language-text\">libclamav</code>.</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\">cl_init</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">int</span> options<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">cl_engine</span> <span class=\"token operator\">*</span><span class=\"token function\">cl_engine_new</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The resources of the allocated engine are freed with <code class=\"language-text\">int cl_engine_free(struct cl_engine *engine);</code>.</p>\n<p>The engine initialized by <code class=\"language-text\">cl_engine_new</code> is defined as the <code class=\"language-text\">cl_engine</code> structure shown below.</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>Reference: <a href=\"https://docs.clamav.net/manual/Development/libclamav.html#initialization\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">libclamav - ClamAV Documentation</a></p>\n<h3 id=\"assigning-the-virus-detection-callback\" style=\"position:relative;\"><a href=\"#assigning-the-virus-detection-callback\" aria-label=\"assigning the virus detection 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>Assigning the Virus-Detection Callback</h3>\n<p>After engine initialization is complete, <code class=\"language-text\">cl_engine_set_clcb_virus_found</code> can be used to assign the callback function that the engine executes when it detects a virus.</p>\n<p>By default, the following <code class=\"language-text\">clamscan_virus_found_cb</code> function is assigned as the callback, and it contains code that displays the file and detection name.</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\">void</span> <span class=\"token function\">clamscan_virus_found_cb</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> fd<span class=\"token punctuation\">,</span> <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>virname<span class=\"token punctuation\">,</span> <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>context<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">clamscan_cb_data</span> <span class=\"token operator\">*</span>data <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">clamscan_cb_data</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>context<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>filename<span class=\"token punctuation\">;</span>\n\n    <span class=\"token function\">UNUSEDPARAM</span><span class=\"token punctuation\">(</span>fd<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>data <span class=\"token operator\">==</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>data<span class=\"token operator\">-></span>filename <span class=\"token operator\">!=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span>\n        filename <span class=\"token operator\">=</span> data<span class=\"token operator\">-></span>filename<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">else</span>\n        filename <span class=\"token operator\">=</span> <span class=\"token string\">\"(filename not set)\"</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"~%s: %s FOUND\\n\"</span><span class=\"token punctuation\">,</span> filename<span class=\"token punctuation\">,</span> virname<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">cl_engine_set_clcb_virus_found</span><span class=\"token punctuation\">(</span>engine<span class=\"token punctuation\">,</span> clamscan_virus_found_cb<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h3 id=\"displaying-the-progress-bar\" style=\"position:relative;\"><a href=\"#displaying-the-progress-bar\" aria-label=\"displaying the progress bar 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>Displaying the Progress Bar</h3>\n<p>In the following code, time-consuming tasks such as loading signatures and compiling the engine are executed with a progress bar only when the output target is a terminal and several options are not set.</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 function\">isatty</span><span class=\"token punctuation\">(</span><span class=\"token function\">fileno</span><span class=\"token punctuation\">(</span><span class=\"token constant\">stdout</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&amp;&amp;</span>\n    <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\">\"debug\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled <span class=\"token operator\">&amp;&amp;</span>\n    <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\">\"quiet\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled <span class=\"token operator\">&amp;&amp;</span>\n    <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\">\"infected\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>enabled <span class=\"token operator\">&amp;&amp;</span>\n    <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 comment\">/* set progress callbacks */</span>\n    <span class=\"token function\">cl_engine_set_clcb_sigload_progress</span><span class=\"token punctuation\">(</span>engine<span class=\"token punctuation\">,</span> sigload_callback<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>sigload_progress_ctx<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">cl_engine_set_clcb_engine_compile_progress</span><span class=\"token punctuation\">(</span>engine<span class=\"token punctuation\">,</span> engine_compile_callback<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>engine_compile_progress_ctx<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\">ENABLE_ENGINE_FREE_PROGRESSBAR</span></span>\n    <span class=\"token function\">cl_engine_set_clcb_engine_free_progress</span><span class=\"token punctuation\">(</span>engine<span class=\"token punctuation\">,</span> engine_free_callback<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>engine_free_progress_ctx<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 punctuation\">}</span></code></pre></div>\n<p>The progress bar is displayed like this.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 837px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/e3b63f5a58d471f88a820c30ec35b64a/ddc81/image-20251115183346232.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: 10.833333333333334%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAeElEQVQI1yWNSQ7CMBRDe5RClaE/gcw0FHXD/e/0SMvCerIt2ZNsifDduW0PVI9IzdjwRg+5epBL49UapRRqrTgnWGtZljtKKbz3iMjFM59abRz7h6fzGKVJMY1SWFdDTmH4SAyDaTD+eY4brZnnmTJOSsn03q/BH2L7PaXLNoBSAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/e3b63f5a58d471f88a820c30ec35b64a/8ac56/image-20251115183346232.webp 240w,\n/static/e3b63f5a58d471f88a820c30ec35b64a/d3be9/image-20251115183346232.webp 480w,\n/static/e3b63f5a58d471f88a820c30ec35b64a/a6125/image-20251115183346232.webp 837w\"\n              sizes=\"(max-width: 837px) 100vw, 837px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/e3b63f5a58d471f88a820c30ec35b64a/8ff5a/image-20251115183346232.png 240w,\n/static/e3b63f5a58d471f88a820c30ec35b64a/e85cb/image-20251115183346232.png 480w,\n/static/e3b63f5a58d471f88a820c30ec35b64a/ddc81/image-20251115183346232.png 837w\"\n            sizes=\"(max-width: 837px) 100vw, 837px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/e3b63f5a58d471f88a820c30ec35b64a/ddc81/image-20251115183346232.png\"\n            alt=\"image-20251115183346232\"\n            title=\"image-20251115183346232\"\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=\"setting-engine-options\" style=\"position:relative;\"><a href=\"#setting-engine-options\" aria-label=\"setting engine 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>Setting Engine Options</h3>\n<p>In the code called after that, various options are set on the engine by using functions such as <code class=\"language-text\">cl_engine_set_str</code> and <code class=\"language-text\">cl_engine_set_num</code>.</p>\n<p>Reference: <a href=\"https://docs.clamav.net/manual/Development/libclamav.html#limits\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">libclamav - ClamAV Documentation</a></p>\n<p>The options used there are defined as follows.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/**\n * @brief Allocate a new scanning engine and initialize default settings.\n *\n * The engine should be freed with `cl_engine_free()`.\n *\n * @return struct cl_engine* Pointer to the scanning engine.\n */</span>\n<span class=\"token keyword\">extern</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">cl_engine</span> <span class=\"token operator\">*</span><span class=\"token function\">cl_engine_new</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">enum</span> <span class=\"token class-name\">cl_engine_field</span> <span class=\"token punctuation\">{</span>\n    CL_ENGINE_MAX_SCANSIZE<span class=\"token punctuation\">,</span>        <span class=\"token comment\">/* uint64_t */</span>\n    CL_ENGINE_MAX_FILESIZE<span class=\"token punctuation\">,</span>        <span class=\"token comment\">/* uint64_t */</span>\n    CL_ENGINE_MAX_RECURSION<span class=\"token punctuation\">,</span>       <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_MAX_FILES<span class=\"token punctuation\">,</span>           <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_MIN_CC_COUNT<span class=\"token punctuation\">,</span>        <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_MIN_SSN_COUNT<span class=\"token punctuation\">,</span>       <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_PUA_CATEGORIES<span class=\"token punctuation\">,</span>      <span class=\"token comment\">/* (char *) */</span>\n    CL_ENGINE_DB_OPTIONS<span class=\"token punctuation\">,</span>          <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_DB_VERSION<span class=\"token punctuation\">,</span>          <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_DB_TIME<span class=\"token punctuation\">,</span>             <span class=\"token comment\">/* time_t */</span>\n    CL_ENGINE_AC_ONLY<span class=\"token punctuation\">,</span>             <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_AC_MINDEPTH<span class=\"token punctuation\">,</span>         <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_AC_MAXDEPTH<span class=\"token punctuation\">,</span>         <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_TMPDIR<span class=\"token punctuation\">,</span>              <span class=\"token comment\">/* (char *) */</span>\n    CL_ENGINE_KEEPTMP<span class=\"token punctuation\">,</span>             <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_BYTECODE_SECURITY<span class=\"token punctuation\">,</span>   <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_BYTECODE_TIMEOUT<span class=\"token punctuation\">,</span>    <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_BYTECODE_MODE<span class=\"token punctuation\">,</span>       <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_MAX_EMBEDDEDPE<span class=\"token punctuation\">,</span>      <span class=\"token comment\">/* uint64_t */</span>\n    CL_ENGINE_MAX_HTMLNORMALIZE<span class=\"token punctuation\">,</span>   <span class=\"token comment\">/* uint64_t */</span>\n    CL_ENGINE_MAX_HTMLNOTAGS<span class=\"token punctuation\">,</span>      <span class=\"token comment\">/* uint64_t */</span>\n    CL_ENGINE_MAX_SCRIPTNORMALIZE<span class=\"token punctuation\">,</span> <span class=\"token comment\">/* uint64_t */</span>\n    CL_ENGINE_MAX_ZIPTYPERCG<span class=\"token punctuation\">,</span>      <span class=\"token comment\">/* uint64_t */</span>\n    CL_ENGINE_FORCETODISK<span class=\"token punctuation\">,</span>         <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_DISABLE_CACHE<span class=\"token punctuation\">,</span>       <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_DISABLE_PE_STATS<span class=\"token punctuation\">,</span>    <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_STATS_TIMEOUT<span class=\"token punctuation\">,</span>       <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_MAX_PARTITIONS<span class=\"token punctuation\">,</span>      <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_MAX_ICONSPE<span class=\"token punctuation\">,</span>         <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_MAX_RECHWP3<span class=\"token punctuation\">,</span>         <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_MAX_SCANTIME<span class=\"token punctuation\">,</span>        <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_PCRE_MATCH_LIMIT<span class=\"token punctuation\">,</span>    <span class=\"token comment\">/* uint64_t */</span>\n    CL_ENGINE_PCRE_RECMATCH_LIMIT<span class=\"token punctuation\">,</span> <span class=\"token comment\">/* uint64_t */</span>\n    CL_ENGINE_PCRE_MAX_FILESIZE<span class=\"token punctuation\">,</span>   <span class=\"token comment\">/* uint64_t */</span>\n    CL_ENGINE_DISABLE_PE_CERTS<span class=\"token punctuation\">,</span>    <span class=\"token comment\">/* uint32_t */</span>\n    CL_ENGINE_PE_DUMPCERTS<span class=\"token punctuation\">,</span>        <span class=\"token comment\">/* uint32_t */</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h2 id=\"performing-the-file-scan\" style=\"position:relative;\"><a href=\"#performing-the-file-scan\" aria-label=\"performing the file scan 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>Performing the File Scan</h2>\n<p>After initializing <code class=\"language-text\">libclamav</code> and the engine, ClamAV then performs the scan.</p>\n<p>In this case, because I specify the <code class=\"language-text\">eicar</code> file directly, it appears that the scan is carried out by the <code class=\"language-text\">scan_files</code> function.</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 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\">||</span> opts<span class=\"token operator\">-></span>filename<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">/* scan the files listed in the --file-list, or it that's not specified, then\n     * scan the list of file arguments (including data from stdin, if `-` specified) */</span>\n    ret <span class=\"token operator\">=</span> <span class=\"token function\">scan_files</span><span class=\"token punctuation\">(</span>engine<span class=\"token punctuation\">,</span> opts<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>options<span class=\"token punctuation\">,</span> dirlnk<span class=\"token punctuation\">,</span> filelnk<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 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\">\"memory\"</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 comment\">/* scan only memory */</span>\n    ret <span class=\"token operator\">=</span> <span class=\"token function\">scan_memory</span><span class=\"token punctuation\">(</span>engine<span class=\"token punctuation\">,</span> opts<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>options<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\">endif</span></span>\n<span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">/* No list of files provided to scan, and no request to scan memory,\n     * so just scan the current directory. */</span>\n    <span class=\"token keyword\">char</span> cwd<span class=\"token punctuation\">[</span><span class=\"token number\">1024</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* Get the current working directory.\n     * we need full path for some reasons (eg. archive handling) */</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span><span class=\"token function\">getcwd</span><span class=\"token punctuation\">(</span>cwd<span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>cwd<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\">logg</span><span class=\"token punctuation\">(</span>LOGG_ERROR<span class=\"token punctuation\">,</span> <span class=\"token string\">\"Can't get absolute pathname of current working directory\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        ret <span class=\"token operator\">=</span> <span class=\"token number\">2</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\">CLAMSTAT</span><span class=\"token punctuation\">(</span>cwd<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>sb<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token function\">scandirs</span><span class=\"token punctuation\">(</span>cwd<span class=\"token punctuation\">,</span> engine<span class=\"token punctuation\">,</span> opts<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>options<span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> sb<span class=\"token punctuation\">.</span>st_dev<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=\"scan_files\" style=\"position:relative;\"><a href=\"#scan_files\" aria-label=\"scan_files 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_files</h3>\n<p>The <code class=\"language-text\">scan_files</code> function receives the following arguments and scans the files.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/**\n* @brief Scan the files from the --file-list option, or scan the files listed as individual arguments.\n*\n* If the user uses both --file-list &lt;LISTFILE> AND one or more files, then clam will only\n* scan the files listed in the LISTFILE and emit a warning about not scanning the other file parameters.\n*\n* @param opts\n* @param options\n* @return int\n*/</span>\n<span class=\"token keyword\">static</span> <span class=\"token keyword\">int</span> <span class=\"token function\">scan_files</span><span class=\"token punctuation\">(</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\">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\">struct</span> <span class=\"token class-name\">cl_scan_options</span> <span class=\"token operator\">*</span>options<span class=\"token punctuation\">,</span> <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">int</span> dirlnk<span class=\"token punctuation\">,</span> <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">int</span> filelnk<span class=\"token punctuation\">)</span></code></pre></div>\n<p>For a single-file scan like this one, <code class=\"language-text\">scanfile</code> is called to scan the file.</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\">void</span> <span class=\"token function\">scanfile</span><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\">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\">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\">struct</span> <span class=\"token class-name\">cl_scan_options</span> <span class=\"token operator\">*</span>options<span class=\"token punctuation\">)</span></code></pre></div>\n<h3 id=\"resolving-the-file-path\" style=\"position:relative;\"><a href=\"#resolving-the-file-path\" aria-label=\"resolving the file path 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>Resolving the File Path</h3>\n<p>To scan the file in the <code class=\"language-text\">scanfile</code> function, it first stores the actual scan target path in <code class=\"language-text\">real_filename</code> by using <code class=\"language-text\">cli_realpath</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">ret <span class=\"token operator\">=</span> <span class=\"token function\">cli_realpath</span><span class=\"token punctuation\">(</span><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 punctuation\">)</span>filename<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>real_filename<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> ret<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span>LOGG_DEBUG<span class=\"token punctuation\">,</span> <span class=\"token string\">\"Failed to determine real filename of %s.\\n\"</span><span class=\"token punctuation\">,</span> filename<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">logg</span><span class=\"token punctuation\">(</span>LOGG_DEBUG<span class=\"token punctuation\">,</span> <span class=\"token string\">\"Quarantine of the file may fail if file path contains symlinks.\\n\"</span><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    filename <span class=\"token operator\">=</span> real_filename<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>In this case, on the command line at runtime, I pass <code class=\"language-text\">filename</code> as <code class=\"language-text\">\"eicar\"</code>.</p>\n<p>From there, <code class=\"language-text\">cli_realpath</code> is called, the library function <code class=\"language-text\">realpath</code> is used to obtain the absolute path of the scan target file, and then the data in the <code class=\"language-text\">filename</code> variable is replaced with that resolved full path.</p>\n<h3 id=\"scanning-the-file\" style=\"position:relative;\"><a href=\"#scanning-the-file\" aria-label=\"scanning the file 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 the File</h3>\n<p>Once the scan target path has been obtained, the code performs several checks such as access permissions, gets the file descriptor for the target file, and then calls <code class=\"language-text\">cl_scandesc_ex</code>.</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\">metachain</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span>chains<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">size_t</span> lastadd<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">size_t</span> lastvir<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">size_t</span> level<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">size_t</span> nchains<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\">clamscan_cb_data</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">metachain</span> <span class=\"token operator\">*</span>chain<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>filename<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n\n<span class=\"token function\">logg</span><span class=\"token punctuation\">(</span>LOGG_DEBUG<span class=\"token punctuation\">,</span> <span class=\"token string\">\"Scanning %s\\n\"</span><span class=\"token punctuation\">,</span> filename<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 punctuation\">(</span>fd <span class=\"token operator\">=</span> <span class=\"token function\">safe_open</span><span class=\"token punctuation\">(</span>filename<span class=\"token punctuation\">,</span> O_RDONLY <span class=\"token operator\">|</span> O_BINARY<span class=\"token punctuation\">)</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>LOGG_WARNING<span class=\"token punctuation\">,</span> <span class=\"token string\">\"Can't open file %s: %s\\n\"</span><span class=\"token punctuation\">,</span> filename<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    info<span class=\"token punctuation\">.</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>\n\ndata<span class=\"token punctuation\">.</span>chain    <span class=\"token operator\">=</span> <span class=\"token operator\">&amp;</span>chain<span class=\"token punctuation\">;</span>\ndata<span class=\"token punctuation\">.</span>filename <span class=\"token operator\">=</span> filename<span class=\"token punctuation\">;</span>\nret <span class=\"token operator\">=</span> <span class=\"token function\">cl_scandesc_ex</span><span class=\"token punctuation\">(</span>\n    fd<span class=\"token punctuation\">,</span>\n    filename<span class=\"token punctuation\">,</span>\n    <span class=\"token operator\">&amp;</span>verdict<span class=\"token punctuation\">,</span>\n    <span class=\"token operator\">&amp;</span>alert_name<span class=\"token punctuation\">,</span>\n    <span class=\"token operator\">&amp;</span>info<span class=\"token punctuation\">.</span>bytes_scanned<span class=\"token punctuation\">,</span>\n    engine<span class=\"token punctuation\">,</span> options<span class=\"token punctuation\">,</span>\n    <span class=\"token operator\">&amp;</span>data<span class=\"token punctuation\">,</span>\n    hash_hint<span class=\"token punctuation\">,</span>\n    hash_out<span class=\"token punctuation\">,</span>\n    hash_alg<span class=\"token punctuation\">,</span>\n    file_type_hint<span class=\"token punctuation\">,</span>\n    file_type_out<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The <code class=\"language-text\">cl_scandesc_ex</code> function scans the received file descriptor and returns the result in the <code class=\"language-text\">verdict_out</code> variable.</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\n * caller provided callback functions can interpret.\n *\n * This extended version of cl_scanmap_callback allows the caller to provide\n * additional hints to the scanning engine, such as a file hash and file type.\n *\n * This variant also upgrades the `scanned` output parameter to a 64-bit integer.\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] verdict_out   A pointer to a cl_verdict_t that will be set to the scan verdict.\n *                           You should check the verdict even if the function returns an error.\n * @param[out] last_alert_out Will be set to a statically allocated (i.e. needs not be freed) signature name if the scan\n *                           matches against a signature.\n * @param[out] scanned_out   The (exact) number of bytes scanned.\n * @param engine             The scanning engine.\n * @param scanoptions        Scanning options.\n * @param[in,out] context    (Optional) An application-defined context struct, opaque to libclamav.\n *                           May be used within your callback functions.\n * @param hash_hint          (Optional) A NULL terminated string of the file hash so that\n *                           libclamav does not need to calculate it.\n * @param[out] hash_out      (Optional) A NULL terminated string of the file hash.\n *                           The caller is responsible for freeing the string.\n * @param hash_alg           The hashing algorithm used for either `hash_hint` or `hash_out`.\n *                           Supported algorithms are \"md5\", \"sha1\", \"sha2-256\".\n *                           If not specified, the default is \"sha2-256\".\n * @param file_type_hint     (Optional) A NULL terminated string of the file type hint.\n *                           E.g. \"pe\", \"elf\", \"zip\", etc.\n *                           You may also use ClamAV type names such as \"CL_TYPE_PE\".\n *                           ClamAV will ignore the hint if it is not familiar with the specified type.\n *                           See also: https://docs.clamav.net/appendix/FileTypes.html#file-types\n * @param[out] file_type_out (Optional) A NULL terminated string of the file type\n *                           of the top layer as determined by ClamAV.\n *                           Will take the form of the standard ClamAV file type format. E.g. \"CL_TYPE_PE\".\n *                           See also: https://docs.clamav.net/appendix/FileTypes.html#file-types\n * @return cl_error_t        CL_SUCCESS if no error occured.\n *                           Otherwise a CL_E* error code.\n *                           Does NOT return CL_VIRUS for a signature match. Check the `verdict_out` parameter instead.\n */</span>\n<span class=\"token keyword\">extern</span> <span class=\"token class-name\">cl_error_t</span> <span class=\"token function\">cl_scandesc_ex</span><span class=\"token punctuation\">(</span>\n    <span class=\"token keyword\">int</span> desc<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>filename<span class=\"token punctuation\">,</span>\n    <span class=\"token class-name\">cl_verdict_t</span> <span class=\"token operator\">*</span>verdict_out<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span>last_alert_out<span class=\"token punctuation\">,</span>\n    <span class=\"token class-name\">uint64_t</span> <span class=\"token operator\">*</span>scanned_out<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\">struct</span> <span class=\"token class-name\">cl_scan_options</span> <span class=\"token operator\">*</span>scanoptions<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>context<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>hash_hint<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span>hash_out<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>hash_alg<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>file_type_hint<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span>file_type_out<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The <code class=\"language-text\">verdict_out</code> variable is defined as the following <code class=\"language-text\">cl_verdict_t</code> enum.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/**\n * @brief Scan verdicts for cl_scanmap_ex(), cl_scanfile_ex(), and cl_scandesc_ex().\n */</span>\n<span class=\"token keyword\">typedef</span> <span class=\"token keyword\">enum</span> <span class=\"token class-name\">cl_verdict_t</span> <span class=\"token punctuation\">{</span>\n    CL_VERDICT_NOTHING_FOUND <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span>    <span class=\"token comment\">/**&lt; No alerting signatures matched. */</span>\n    CL_VERDICT_TRUSTED<span class=\"token punctuation\">,</span>              <span class=\"token comment\">/**&lt; The scan target has been deemed trusted (e.g. by FP signature or Authenticode). */</span>\n    CL_VERDICT_STRONG_INDICATOR<span class=\"token punctuation\">,</span>     <span class=\"token comment\">/**&lt; One or more strong indicator signatures matched. */</span>\n    CL_VERDICT_POTENTIALLY_UNWANTED<span class=\"token punctuation\">,</span> <span class=\"token comment\">/**&lt; One or more potentially unwanted signatures matched. */</span>\n<span class=\"token punctuation\">}</span> <span class=\"token class-name\">cl_verdict_t</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Inside <code class=\"language-text\">cl_scandesc_ex</code>, the received file descriptor is first passed to <code class=\"language-text\">fmap_new</code> and mapped into the <code class=\"language-text\">map</code> variable of type <code class=\"language-text\">cl_fmap_t</code> (<code class=\"language-text\">cl_fmap</code>), and then <code class=\"language-text\">scan_common</code> is called.</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> <span class=\"token punctuation\">(</span>map <span class=\"token operator\">=</span> <span class=\"token function\">fmap_new</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> filename<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_new() 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>\n    map<span class=\"token punctuation\">,</span>\n    filename<span class=\"token punctuation\">,</span>\n    verdict_out<span class=\"token punctuation\">,</span>\n    last_alert_out<span class=\"token punctuation\">,</span>\n    scanned_out<span class=\"token punctuation\">,</span>\n    engine<span class=\"token punctuation\">,</span>\n    scanoptions<span class=\"token punctuation\">,</span>\n    context<span class=\"token punctuation\">,</span>\n    hash_hint<span class=\"token punctuation\">,</span>\n    hash_out<span class=\"token punctuation\">,</span>\n    hash_alg<span class=\"token punctuation\">,</span>\n    file_type_hint<span class=\"token punctuation\">,</span>\n    file_type_out<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The <code class=\"language-text\">cl_fmap</code> structure is defined as follows, and it seems to be used to abstract file maps so they can be accessed from various APIs.</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 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\">/* 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\">/* internal */</span>\n    <span class=\"token class-name\">uint64_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    bool aging<span class=\"token punctuation\">;</span>           <span class=\"token comment\">/** Indicates if we should age off memory mapped pages */</span>\n    bool dont_cache_flag<span class=\"token punctuation\">;</span> <span class=\"token comment\">/** Indicates if we should not cache scan results for this fmap. Used if limits exceeded */</span>\n    bool handle_is_fd<span class=\"token punctuation\">;</span>    <span class=\"token comment\">/** Non-zero if `map->handle` is an fd. This is needed so that `fmap_fd()` knows if it can\n                              return a file descriptor. If it's some other kind of handle, then `fmap_fd()` has to return -1. */</span>\n    <span class=\"token class-name\">size_t</span> offset<span class=\"token punctuation\">;</span>        <span class=\"token comment\">/** File offset representing start of original fmap, if the fmap created reading from a file starting at offset other than 0.\n                              `offset` &amp; `len` are critical information for anyone using the file descriptor/handle */</span>\n    <span class=\"token class-name\">size_t</span> nested_offset<span class=\"token punctuation\">;</span> <span class=\"token comment\">/** Offset from start of original fmap (data) for nested scan. 0 for orig fmap. */</span>\n    <span class=\"token class-name\">size_t</span> real_len<span class=\"token punctuation\">;</span>      <span class=\"token comment\">/** Length from start of original fmap (data) to end of current (possibly nested) map.\n                              `real_len == nested_offset + len`.\n                              `real_len` is needed for nested maps because we only reference the original mapping data.\n                              We convert caller's fmap offsets &amp; lengths to real data offsets using `nested_offset` &amp; `real_len`. */</span>\n\n    <span class=\"token comment\">/* external */</span>\n    <span class=\"token class-name\">size_t</span> len<span class=\"token punctuation\">;</span> <span class=\"token comment\">/** Length of data from nested_offset, 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 keyword\">void</span> <span class=\"token operator\">*</span>windows_file_handle<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>windows_map_handle<span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* flags to indicate if we should calculate a hash next time we calculate any hashes */</span>\n    bool will_need_hash<span class=\"token punctuation\">[</span>CLI_HASH_AVAIL_TYPES<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* flags to indicate if we have calculated a hash */</span>\n    bool have_hash<span class=\"token punctuation\">[</span>CLI_HASH_AVAIL_TYPES<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">/* hash values */</span>\n    <span class=\"token class-name\">uint8_t</span> hash<span class=\"token punctuation\">[</span>CLI_HASH_AVAIL_TYPES<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span>CLI_HASHLEN_MAX<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\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> <span class=\"token comment\">/* name of the file, e.g. as recorded in a zip file entry record */</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>path<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* path to the file/tempfile, if fmap was created from a file descriptor */</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h3 id=\"scan_common\" style=\"position:relative;\"><a href=\"#scan_common\" aria-label=\"scan_common 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_common</h3>\n<p>The file abstracted as a <code class=\"language-text\">cl_fmap</code> is then passed to <code class=\"language-text\">scan_common</code>.</p>\n<p>This function starts a scan of the <code class=\"language-text\">cl_fmap</code>.</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] verdict_out    A pointer to a cl_verdict_t that will be set to the scan verdict.\n *                            You should check the verdict even if the function returns an error.\n * @param[out] last_alert_out 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_out    (Optional) The number of bytes scanned.\n * @param engine              The scanning engine.\n * @param scanoptions         Scanning options.\n * @param[in,out] context     (Optional) An application-defined context struct, opaque to libclamav.\n *                            May be used within your callback functions.\n * @param hash_hint           (Optional) A NULL terminated string of the file hash so that\n *                            libclamav does not need to calculate it.\n * @param[out] hash_out       (Optional) A NULL terminated string of the file hash.\n *                            The caller is responsible for freeing this string.\n * @param hash_alg            The hashing algorithm used for either `hash_hint` or `hash_out`.\n *                            Supported algorithms are \"md5\", \"sha1\", \"sha2-256\".\n *                            Required only if you provide a `hash_hint` or want to receive a `hash_out`.\n * @param file_type_hint      (Optional) A NULL terminated string of the file type hint.\n *                            E.g. \"pe\", \"elf\", \"zip\", etc.\n *                            You may also use ClamAV type names such as \"CL_TYPE_PE\".\n *                            ClamAV will ignore the hint if it is not familiar with the specified type.\n * @param file_type_out       (Optional) A NULL terminated string of the file type\n *                            of the top layer as determined by ClamAV.\n *                            Will take the form of the standard ClamAV file type format. E.g. \"CL_TYPE_PE\".\n *                            The caller is responsible for freeing this string.\n * @return cl_error_t         CL_SUCCESS if no error occured.\n *                            Otherwise a CL_E* error code.\n *                            Does NOT return CL_VIRUS for a signature match. Check the `verdict_out` parameter instead.\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>\n    <span class=\"token class-name\">cl_fmap_t</span> <span class=\"token operator\">*</span>map<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>filepath<span class=\"token punctuation\">,</span>\n    <span class=\"token class-name\">cl_verdict_t</span> <span class=\"token operator\">*</span>verdict_out<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span>last_alert_out<span class=\"token punctuation\">,</span>\n    <span class=\"token class-name\">uint64_t</span> <span class=\"token operator\">*</span>scanned_out<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\">struct</span> <span class=\"token class-name\">cl_scan_options</span> <span class=\"token operator\">*</span>scanoptions<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>context<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>hash_hint<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span>hash_out<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>hash_alg<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>file_type_hint<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span>file_type_out<span class=\"token punctuation\">)</span></code></pre></div>\n<p>Inside this function, ClamAV context information defined as the <code class=\"language-text\">cli_ctx</code> structure is initialized, and information such as the engine and scan options received as arguments is registered into that context.</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\">/* (optional) The filepath of the original scan target. */</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>this_layer_tmpdir<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* Pointer to current temporary directory, MAY vary with recursion depth. For convenience. */</span>\n    <span class=\"token class-name\">uint64_t</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 class-name\">uint64_t</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 class-name\">uint32_t</span> scannedfiles<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>      <span class=\"token comment\">/* Setting this flag will prevent the PE parser from reporting \"broken executable\" for unpacked/reconstructed files that may not be 100% to spec. */</span>\n    <span class=\"token class-name\">cli_scan_layer_t</span> <span class=\"token operator\">*</span>recursion_stack<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* Array of recursion levels used as a stack. */</span>\n    <span class=\"token class-name\">uint32_t</span> recursion_stack_size<span class=\"token punctuation\">;</span>     <span class=\"token comment\">/* stack size must == engine->max_recursion_level */</span>\n    <span class=\"token class-name\">uint32_t</span> recursion_level<span class=\"token punctuation\">;</span>          <span class=\"token comment\">/* Index into recursion_stack; current fmap recursion level from start of scan. */</span>\n    <span class=\"token class-name\">evidence_t</span> this_layer_evidence<span class=\"token punctuation\">;</span>    <span class=\"token comment\">/* Pointer to current evidence in recursion_stack, varies with recursion depth. For convenience. */</span>\n    <span class=\"token class-name\">fmap_t</span> <span class=\"token operator\">*</span>fmap<span class=\"token punctuation\">;</span>                      <span class=\"token comment\">/* Pointer to current fmap in recursion_stack, varies with recursion depth. For convenience. */</span>\n    <span class=\"token class-name\">size_t</span> object_count<span class=\"token punctuation\">;</span>               <span class=\"token comment\">/* Counter for number of unique entities/contained files (including normalized files) processed. */</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\">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 keyword\">struct</span> <span class=\"token class-name\">json_object</span> <span class=\"token operator\">*</span>metadata_json<span class=\"token punctuation\">;</span>            <span class=\"token comment\">/* Top level metadata JSON object for the whole scan. */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">json_object</span> <span class=\"token operator\">*</span>this_layer_metadata_json<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* Pointer to current metadata JSON object in recursion_stack, varies with recursion depth. For convenience. */</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">timeval</span> time_limit<span class=\"token punctuation\">;</span>\n    bool limit_exceeded<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* To guard against alerting on limits exceeded more than once, or storing that in the JSON metadata more than once. */</span>\n    bool abort_scan<span class=\"token punctuation\">;</span>     <span class=\"token comment\">/* So we can guarantee a scan is aborted, even if CL_ETIMEOUT/etc. status is lost in the scan recursion stack. */</span>\n<span class=\"token punctuation\">}</span> cli_ctx<span class=\"token punctuation\">;</span></code></pre></div>\n<p>After several initialization steps and checks, it calls <code class=\"language-text\">cli_magic_scan</code> with the initialized context information.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/*\n * DO THE SCAN!\n */</span>\nstatus <span class=\"token operator\">=</span> <span class=\"token function\">cli_magic_scan</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>ctx<span class=\"token punctuation\">,</span> file_type<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h3 id=\"climagicscan\" style=\"position:relative;\"><a href=\"#climagicscan\" aria-label=\"climagicscan 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>cli<em>magic</em>scan</h3>\n<p><code class=\"language-text\">cli_magic_scan</code> is responsible for behavior that is very close to the actual scan based on real signature matching.</p>\n<p>After this function is called and some checks are performed, the <code class=\"language-text\">pre_hash</code> callback is invoked.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/*\n * Run the pre_hash callback.\n */</span>\nret <span class=\"token operator\">=</span> <span class=\"token function\">cli_dispatch_scan_callback</span><span class=\"token punctuation\">(</span>ctx<span class=\"token punctuation\">,</span> CL_SCAN_CALLBACK_PRE_HASH<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> ret<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    status <span class=\"token operator\">=</span> ret<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 <code class=\"language-text\">pre_hash</code> callback is called by passing <code class=\"language-text\">CL_SCAN_CALLBACK_PRE_HASH</code> as the second argument to <code class=\"language-text\">cli_dispatch_scan_callback</code>.</p>\n<p>In <code class=\"language-text\">cli_dispatch_scan_callback</code>, a predefined callback function is selected and executed according to the specified flag as follows.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/*\n * Determine which callback to use.\n */</span>\n<span class=\"token keyword\">switch</span> <span class=\"token punctuation\">(</span>location<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">case</span> CL_SCAN_CALLBACK_PRE_HASH<span class=\"token operator\">:</span>\n        callback <span class=\"token operator\">=</span> ctx<span class=\"token operator\">-></span>engine<span class=\"token operator\">-></span>cb_scan_pre_hash<span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">case</span> CL_SCAN_CALLBACK_PRE_SCAN<span class=\"token operator\">:</span>\n        callback <span class=\"token operator\">=</span> ctx<span class=\"token operator\">-></span>engine<span class=\"token operator\">-></span>cb_scan_pre_scan<span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">case</span> CL_SCAN_CALLBACK_POST_SCAN<span class=\"token operator\">:</span>\n        callback <span class=\"token operator\">=</span> ctx<span class=\"token operator\">-></span>engine<span class=\"token operator\">-></span>cb_scan_post_scan<span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">case</span> CL_SCAN_CALLBACK_ALERT<span class=\"token operator\">:</span>\n        callback <span class=\"token operator\">=</span> ctx<span class=\"token operator\">-></span>engine<span class=\"token operator\">-></span>cb_scan_alert<span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">case</span> CL_SCAN_CALLBACK_FILE_TYPE<span class=\"token operator\">:</span>\n        callback <span class=\"token operator\">=</span> ctx<span class=\"token operator\">-></span>engine<span class=\"token operator\">-></span>cb_scan_file_type<span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">default</span><span class=\"token operator\">:</span>\n        status <span class=\"token operator\">=</span> CL_EARG<span class=\"token punctuation\">;</span>\n        <span class=\"token function\">cli_errmsg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"dispatch_scan_callback: Invalid callback location\\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\n<span class=\"token comment\">// 中略</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> callback<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">/*\n     * Callback is not set.\n     */</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>location <span class=\"token operator\">==</span> CL_SCAN_CALLBACK_ALERT<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token comment\">// Accept the alert.</span>\n        status <span class=\"token operator\">=</span> CL_VIRUS<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\">// Keep scanning.</span>\n        status <span class=\"token operator\">=</span> CL_SUCCESS<span class=\"token punctuation\">;</span>\n    <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\ncurrent_layer <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">cl_scan_layer_t</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token operator\">&amp;</span>ctx<span class=\"token operator\">-></span>recursion_stack<span class=\"token punctuation\">[</span>ctx<span class=\"token operator\">-></span>recursion_level<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">/*\n * Call the callback function.\n */</span>\n<span class=\"token comment\">// TODO: Add performance measurements around the new callback specific to each callback location.</span>\n<span class=\"token comment\">// perf_start(ctx, PERFT_PRECB);</span>\nstatus <span class=\"token operator\">=</span> <span class=\"token function\">callback</span><span class=\"token punctuation\">(</span>\n    current_layer<span class=\"token punctuation\">,</span> <span class=\"token comment\">// current scan layer</span>\n    ctx<span class=\"token operator\">-></span>cb_ctx    <span class=\"token comment\">// application context</span>\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">// perf_stop(ctx, PERFT_PRECB);</span></code></pre></div>\n<p>However, the callback function invoked here apparently needs to be defined on the client side. When <code class=\"language-text\">cb_scan_pre_hash</code> was invoked from the <code class=\"language-text\">clamscan</code> command used this time, <code class=\"language-text\">NULL == callback</code> became true, so in practice no callback was called.</p>\n<p>After that, several similar calls are made, the file type is checked, and execution finally reaches a call to <code class=\"language-text\">scanraw</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/*\n * Perform pattern matching for malware detections AND embedded file type recognition.\n * Embedded file type recognition may re-assign the current file as a new type, or\n * it may detect embedded files. E.g. ZIP entries in a PE file (i.e. self-extracting ZIP).\n */</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_IGNORED<span class=\"token punctuation\">)</span> <span class=\"token operator\">&amp;&amp;</span>\n    <span class=\"token comment\">/* CL_TYPE_HTML: raw HTML files are not scanned, unless safety measure activated via DCONF */</span>\n    <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>\n    <span class=\"token punctuation\">(</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> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token function\">cli_dbgmsg</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"cli_magic_scan: Performing raw scan to pattern match and/or detect embedded files\\n\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    ret <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>\n\n    <span class=\"token comment\">// Evaluate the result from the scan to see if it end the scan of this layer early,</span>\n    <span class=\"token comment\">// and to decid if we should propagate an error or not.</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">result_should_goto_done</span><span class=\"token punctuation\">(</span>ctx<span class=\"token punctuation\">,</span> ret<span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>status<span class=\"token punctuation\">)</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 punctuation\">}</span></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: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/2dcbb098834f0d467edbd1457e7eb7ee/7a720/image-20251123212552823.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: 21.666666666666668%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA0klEQVQY0z2P227CMBAF81psIE6Cb/E1paEV/P/vTZeo6sPoWJZ29uyQU6bWxrIs/Ow7j/ud1/PF1hpriGzbRimFYB05Z7xzBOdJKRFjlL+CNRNaabTWDD55Yo6ok6LVyr5/yYJVJIFcIk3oPWHtLEtHyenA+5nbX4Yw4+wNMxqGkANJBO8NaV1prR6NSski6kfT3psMOhHOTJPBmFGGR6Z3ClorlFLiUAwxJKnd+DhpYvtk/36KVM6sXRo24ppJMR/vebGcL6NwFQznqz1S6cs/v1rFZk0b+ZGlAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/2dcbb098834f0d467edbd1457e7eb7ee/8ac56/image-20251123212552823.webp 240w,\n/static/2dcbb098834f0d467edbd1457e7eb7ee/d3be9/image-20251123212552823.webp 480w,\n/static/2dcbb098834f0d467edbd1457e7eb7ee/e46b2/image-20251123212552823.webp 960w,\n/static/2dcbb098834f0d467edbd1457e7eb7ee/f992d/image-20251123212552823.webp 1440w,\n/static/2dcbb098834f0d467edbd1457e7eb7ee/3ea93/image-20251123212552823.webp 1649w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/2dcbb098834f0d467edbd1457e7eb7ee/8ff5a/image-20251123212552823.png 240w,\n/static/2dcbb098834f0d467edbd1457e7eb7ee/e85cb/image-20251123212552823.png 480w,\n/static/2dcbb098834f0d467edbd1457e7eb7ee/d9199/image-20251123212552823.png 960w,\n/static/2dcbb098834f0d467edbd1457e7eb7ee/07a9c/image-20251123212552823.png 1440w,\n/static/2dcbb098834f0d467edbd1457e7eb7ee/7a720/image-20251123212552823.png 1649w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/2dcbb098834f0d467edbd1457e7eb7ee/d9199/image-20251123212552823.png\"\n            alt=\"image-20251123212552823\"\n            title=\"image-20251123212552823\"\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=\"scanraw\" style=\"position:relative;\"><a href=\"#scanraw\" aria-label=\"scanraw 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>scanraw</h3>\n<p>This function appears to be implemented as a function that performs a raw scan against a file map.</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 * @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></code></pre></div>\n<p>The actual implementation is about 1,000 lines long, but the scan itself is carried out by calling <code class=\"language-text\">cli_scan_fmap</code> further down.</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>\n                    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>\n                    false<span class=\"token punctuation\">,</span>\n                    <span class=\"token operator\">&amp;</span>ftoffset<span class=\"token punctuation\">,</span>\n                    acmode<span class=\"token punctuation\">,</span>\n                    <span class=\"token constant\">NULL</span><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<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>I wrote this pretty roughly, but I am exhausted for now, so I will stop the article here.</p>\n<p>I plan to write about the next function, <code class=\"language-text\">cli_scan_fmap</code>, in <a href=\"/clamav-scan-fmap\">this article</a>.</p>","fields":{"slug":"/clamav-clamscan-en","tagSlugs":["/tag/clam-av/","/tag/malware/","/tag/linux/","/tag/english/"]},"frontmatter":{"date":"2025-11-24","description":"These are notes on how clamscan works before it performs a file scan (unfinished).","tags":["ClamAV","Malware","Linux","English"],"title":"Notes on How clamscan Works Before It Performs a File Scan (unfinished)","socialImage":{"publicURL":"/static/15b8d4cb31e0209f93411f0a5cb6069e/clamav-clamscan.png"}}}},"pageContext":{"slug":"/clamav-clamscan-en"}},"staticQueryHashes":["251939775","401334301","825871152"]}