mirror of https://github.com/Cisco-Talos/clamav
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
332 lines
8.9 KiB
332 lines
8.9 KiB
/*
|
|
* Copyright (C) 2009 Sourcefire, Inc.
|
|
* Author: Tomasz Kojm <tkojm@clamav.net>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
* MA 02110-1301, USA.
|
|
*/
|
|
|
|
#if HAVE_CONFIG_H
|
|
#include "clamav-config.h"
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
#include <time.h>
|
|
|
|
#include "shared/optparser.h"
|
|
#include "shared/misc.h"
|
|
|
|
#include "libclamav/str.h"
|
|
#include "libclamav/clamav.h"
|
|
#include "libclamav/others.h"
|
|
#include "libclamav/bytecode.h"
|
|
|
|
#ifndef _WIN32
|
|
extern const struct clam_option *clam_options;
|
|
#else
|
|
__declspec(dllimport) extern const struct clam_option *clam_options;
|
|
#endif
|
|
|
|
static struct _cfgfile {
|
|
const char *name;
|
|
int tool;
|
|
} cfgfile[] = {
|
|
{ "clamd.conf", OPT_CLAMD },
|
|
{ "freshclam.conf", OPT_FRESHCLAM },
|
|
{ "clamav-milter.conf", OPT_MILTER },
|
|
{ NULL, 0 }
|
|
};
|
|
|
|
static const char *dbnames[] = { "main.cvd", "main.cld", "daily.cvd",
|
|
"daily.cld", "safebrowsing.cvd",
|
|
"safebrowsing.cld", NULL };
|
|
|
|
static void printopts(struct optstruct *opts, int nondef)
|
|
{
|
|
const struct optstruct *opt;
|
|
|
|
while(opts) {
|
|
if(!opts->name) {
|
|
opts = opts->next;
|
|
continue;
|
|
}
|
|
if(clam_options[opts->idx].owner & OPT_DEPRECATED) {
|
|
if(opts->active)
|
|
printf("*** %s is DEPRECATED ***\n", opts->name);
|
|
opts = opts->next;
|
|
continue;
|
|
}
|
|
if(nondef && (opts->numarg == clam_options[opts->idx].numarg) && ((opts->strarg == clam_options[opts->idx].strarg) || (opts->strarg && clam_options[opts->idx].strarg && !strcmp(opts->strarg, clam_options[opts->idx].strarg)))) {
|
|
opts = opts->next;
|
|
continue;
|
|
}
|
|
if(!opts->enabled)
|
|
printf("%s disabled\n", opts->name);
|
|
else switch(clam_options[opts->idx].argtype) {
|
|
case TYPE_STRING:
|
|
printf("%s = \"%s\"", opts->name, opts->strarg);
|
|
opt = opts;
|
|
while((opt = opt->nextarg))
|
|
printf(", \"%s\"", opt->strarg);
|
|
printf("\n");
|
|
break;
|
|
|
|
case TYPE_NUMBER:
|
|
case TYPE_SIZE:
|
|
printf("%s = \"%lld\"", opts->name, opts->numarg);
|
|
opt = opts;
|
|
while((opt = opt->nextarg))
|
|
printf(", \"%lld\"", opt->numarg);
|
|
printf("\n");
|
|
break;
|
|
|
|
case TYPE_BOOL:
|
|
printf("%s = \"yes\"\n", opts->name);
|
|
break;
|
|
|
|
default:
|
|
printf("!!! %s: UNKNOWN INTERNAL TYPE !!!\n", opts->name);
|
|
}
|
|
opts = opts->next;
|
|
}
|
|
}
|
|
|
|
static int printconf(const char *name)
|
|
{
|
|
int i, j, tool = 0, tokens_count;
|
|
char buffer[1025];
|
|
const char *tokens[128];
|
|
const struct clam_option *cpt;
|
|
|
|
for(i = 0; cfgfile[i].name; i++) {
|
|
if(!strcmp(name, cfgfile[i].name)) {
|
|
tool = cfgfile[i].tool;
|
|
break;
|
|
}
|
|
}
|
|
if(!tool) {
|
|
printf("ERROR: Unknown config file\nAvailable options:");
|
|
for(i = 0; cfgfile[i].name; i++)
|
|
printf(" %s", cfgfile[i].name);
|
|
printf("\n");
|
|
return 1;
|
|
}
|
|
|
|
printf("##\n## %s - automatically generated by clamconf "VERSION"\n##\n", name);
|
|
printf("\n# Comment out or remove the line below.\nExample\n");
|
|
|
|
for(i = 0; clam_options[i].owner; i++) {
|
|
cpt = &clam_options[i];
|
|
if(cpt->name && (cpt->owner & tool) && !(cpt->owner & OPT_DEPRECATED) && !(cpt->flags & 4)) {
|
|
strncpy(buffer, cpt->description, 1024);
|
|
buffer[1024] = 0;
|
|
tokens_count = cli_strtokenize(buffer, '\n', 128, tokens);
|
|
printf("\n");
|
|
for(j = 0; j < tokens_count; j++)
|
|
printf("# %s\n", tokens[j]);
|
|
|
|
switch(cpt->argtype) {
|
|
case TYPE_STRING:
|
|
if(cpt->strarg)
|
|
printf("# Default: %s\n", cpt->strarg);
|
|
else
|
|
printf("# Default: disabled\n");
|
|
break;
|
|
|
|
case TYPE_NUMBER:
|
|
if(cpt->numarg != -1)
|
|
printf("# Default: %lld\n", cpt->numarg);
|
|
else
|
|
printf("# Default: disabled\n");
|
|
break;
|
|
|
|
case TYPE_SIZE:
|
|
printf("# You may use 'M' or 'm' for megabytes (1M = 1m = 1048576 bytes)\n# and 'K' or 'k' for kilobytes (1K = 1k = 1024 bytes). To specify the size\n# in bytes just don't use modifiers.\n");
|
|
if(cpt->numarg != -1)
|
|
printf("# Default: %lld\n", cpt->numarg);
|
|
else
|
|
printf("# Default: disabled\n");
|
|
break;
|
|
|
|
case TYPE_BOOL:
|
|
if(cpt->numarg != -1)
|
|
printf("# Default: %s\n", cpt->numarg ? "yes" : "no");
|
|
else
|
|
printf("# Default: disabled\n");
|
|
break;
|
|
|
|
default:
|
|
printf("!!! %s: UNKNOWN INTERNAL TYPE !!!\n", cpt->name);
|
|
}
|
|
|
|
if(cpt->suggested && strchr(cpt->suggested, '\n')) {
|
|
strncpy(buffer, cpt->suggested, 1024);
|
|
buffer[1024] = 0;
|
|
tokens_count = cli_strtokenize(buffer, '\n', 128, tokens);
|
|
for(j = 0; j < tokens_count; j++)
|
|
printf("#%s %s\n", cpt->name, tokens[j]);
|
|
} else {
|
|
printf("#%s %s\n", cpt->name, cpt->suggested ? cpt->suggested : "ARG");
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void help(void)
|
|
{
|
|
printf("\n");
|
|
printf(" Clam AntiVirus: Configuration Tool %s\n", get_version());
|
|
printf(" By The ClamAV Team: http://www.clamav.net/team\n");
|
|
printf(" (C) 2009 Sourcefire, Inc.\n\n");
|
|
|
|
printf(" --help -h Show help\n");
|
|
printf(" --version -V Show version\n");
|
|
printf(" --config-dir=DIR -c DIR Read configuration files from DIR\n");
|
|
printf(" --non-default -n Only display non-default settings\n");
|
|
printf(" --generate-config=NAME -g NAME Generate example config file\n");
|
|
printf("\n");
|
|
return;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
const char *dir;
|
|
char path[512], dbdir[512], *pt;
|
|
struct optstruct *opts, *toolopts;
|
|
const struct optstruct *opt;
|
|
unsigned int i, j;
|
|
struct cl_cvd *cvd;
|
|
unsigned int flevel;
|
|
|
|
|
|
opts = optparse(NULL, argc, argv, 1, OPT_CLAMCONF, 0, NULL);
|
|
if(!opts) {
|
|
printf("ERROR: Can't parse command line options\n");
|
|
return 1;
|
|
}
|
|
|
|
if(optget(opts, "help")->enabled) {
|
|
help();
|
|
optfree(opts);
|
|
return 0;
|
|
}
|
|
|
|
if(optget(opts, "version")->enabled) {
|
|
printf("Clam AntiVirus Configuration Tool %s\n", get_version());
|
|
optfree(opts);
|
|
return 0;
|
|
}
|
|
|
|
if((opt = optget(opts, "generate-config"))->enabled) {
|
|
printconf(opt->strarg);
|
|
optfree(opts);
|
|
return 0;
|
|
}
|
|
|
|
dbdir[0] = 0;
|
|
dir = optget(opts, "config-dir")->strarg;
|
|
printf("Checking configuration files in %s\n", dir);
|
|
for(i = 0; cfgfile[i].name; i++) {
|
|
snprintf(path, sizeof(path), "%s"PATHSEP"%s", dir, cfgfile[i].name);
|
|
path[511] = 0;
|
|
if(access(path, R_OK)) {
|
|
printf("\n%s not found\n", cfgfile[i].name);
|
|
continue;
|
|
}
|
|
printf("\nConfig file: %s\n", cfgfile[i].name);
|
|
for(j = 0; j < strlen(cfgfile[i].name) + 13; j++)
|
|
printf("-");
|
|
printf("\n");
|
|
toolopts = optparse(path, 0, NULL, 1, cfgfile[i].tool | OPT_DEPRECATED, 0, NULL);
|
|
if(!toolopts)
|
|
continue;
|
|
printopts(toolopts, optget(opts, "non-default")->enabled);
|
|
if(cfgfile[i].tool == OPT_FRESHCLAM) {
|
|
opt = optget(toolopts, "DatabaseDirectory");
|
|
strncpy(dbdir, opt->strarg, sizeof(dbdir));
|
|
dbdir[sizeof(dbdir) - 1] = 0;
|
|
}
|
|
optfree(toolopts);
|
|
}
|
|
optfree(opts);
|
|
|
|
printf("\nSoftware settings\n-----------------\n");
|
|
printf("Version: %s\n", cl_retver());
|
|
if(strcmp(cl_retver(), get_version()))
|
|
printf("WARNING: Version mismatch: libclamav=%s, clamconf=%s\n", cl_retver(), get_version());
|
|
cl_init(CL_INIT_DEFAULT);
|
|
printf("Optional features supported: ");
|
|
#ifdef USE_MPOOL
|
|
printf("MEMPOOL ");
|
|
#endif
|
|
#ifdef SUPPORT_IPv6
|
|
printf("IPv6 ");
|
|
#endif
|
|
#ifdef CLAMUKO
|
|
printf("CLAMUKO ");
|
|
#endif
|
|
#ifdef C_BIGSTACK
|
|
printf("BIGSTACK ");
|
|
#endif
|
|
#ifdef FRESHCLAM_DNS_FIX
|
|
printf("FRESHCLAM_DNS_FIX ");
|
|
#endif
|
|
#ifdef FPU_WORDS_BIGENDIAN
|
|
printf("AUTOIT_EA06 ");
|
|
#endif
|
|
#ifdef HAVE_BZLIB_H
|
|
printf("BZIP2 ");
|
|
#endif
|
|
if(have_rar)
|
|
printf("RAR ");
|
|
if (have_clamjit)
|
|
printf("JIT");
|
|
printf("\n");
|
|
|
|
if(!strlen(dbdir)) {
|
|
pt = freshdbdir();
|
|
if(pt) {
|
|
strncpy(dbdir, pt, sizeof(dbdir));
|
|
free(pt);
|
|
} else {
|
|
strncpy(dbdir, DATADIR, sizeof(dbdir));
|
|
}
|
|
dbdir[sizeof(dbdir) - 1] = 0;
|
|
}
|
|
printf("Database directory: %s\n", dbdir);
|
|
flevel = cl_retflevel();
|
|
for(i = 0; dbnames[i]; i++) {
|
|
snprintf(path, sizeof(path), "%s"PATHSEP"%s", dbdir, dbnames[i]);
|
|
path[511] = 0;
|
|
if(!access(path, R_OK)) {
|
|
cvd = cl_cvdhead(path);
|
|
if(!cvd) {
|
|
printf("%s: Can't get information about the database\n", dbnames[i]);
|
|
} else {
|
|
const time_t t = cvd->stime;
|
|
printf("%s: version %u, sigs: %u, built on %s", dbnames[i], cvd->version, cvd->sigs, ctime(&t));
|
|
if(cvd->fl > flevel)
|
|
printf("%s: WARNING: This database requires f-level %u (current f-level: %u)\n", dbnames[i], cvd->fl, flevel);
|
|
cl_cvdfree(cvd);
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|