2003-07-29 15:48:06 +00:00
/*
2006-05-15 18:30:18 +00:00
* Copyright ( C ) 2002 - 2006 Tomasz Kojm < tkojm @ clamav . net >
2003-07-29 15:48:06 +00:00
*
* This program is free software ; you can redistribute it and / or modify
2007-03-31 20:31:04 +00:00
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
2003-07-29 15:48:06 +00:00
*
* 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
2006-04-09 19:59:28 +00:00
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston ,
* MA 02110 - 1301 , USA .
2003-07-29 15:48:06 +00:00
*/
2003-11-05 00:53:52 +00:00
2004-02-06 13:46:08 +00:00
# if HAVE_CONFIG_H
# include "clamav-config.h"
# endif
2003-07-29 15:48:06 +00:00
# include <stdio.h>
# include <stdlib.h>
2006-09-27 14:06:28 +00:00
# ifdef HAVE_UNISTD_H
2003-07-29 15:48:06 +00:00
# include <unistd.h>
2006-09-27 14:06:28 +00:00
# endif
2003-07-29 15:48:06 +00:00
# include <string.h>
2004-02-19 11:14:22 +00:00
# include <errno.h>
2003-11-05 00:53:52 +00:00
# include <signal.h>
2004-07-19 17:54:40 +00:00
# include <time.h>
2003-07-29 15:48:06 +00:00
# include <sys/types.h>
2009-09-24 19:23:21 +02:00
# ifndef _WIN32
2005-03-25 17:53:12 +00:00
# include <sys/wait.h>
2006-09-27 14:06:28 +00:00
# endif
2003-07-29 15:48:06 +00:00
# include <sys/stat.h>
# include <fcntl.h>
2009-09-24 16:21:51 +02:00
# ifdef HAVE_PWD_H
2003-07-29 15:48:06 +00:00
# include <pwd.h>
2009-09-24 16:21:51 +02:00
# endif
# ifdef HAVE_GRP_H
2003-07-29 15:48:06 +00:00
# include <grp.h>
2006-09-27 14:06:28 +00:00
# endif
2003-07-29 15:48:06 +00:00
2004-03-29 00:00:58 +00:00
# if defined(USE_SYSLOG) && !defined(C_AIX)
2004-03-14 20:45:58 +00:00
# include <syslog.h>
# endif
2004-06-13 02:11:26 +00:00
# include "target.h"
2006-08-30 22:41:21 +00:00
# include "clamav.h"
2012-12-07 19:54:59 -05:00
# include "freshclamcodes.h"
2006-08-30 22:41:21 +00:00
2010-05-12 14:59:50 +02:00
# include "libclamav/others.h"
2011-10-10 12:02:16 +03:00
# include "libclamav/str.h"
2010-05-12 14:59:50 +02:00
2008-12-18 19:42:53 +00:00
# include "shared/optparser.h"
2006-08-30 22:41:21 +00:00
# include "shared/output.h"
# include "shared/misc.h"
2005-03-25 17:53:12 +00:00
# include "execute.h"
2006-08-30 22:41:21 +00:00
# include "manager.h"
2007-01-06 16:00:14 +00:00
# include "mirman.h"
2003-07-29 15:48:06 +00:00
2004-02-19 11:14:22 +00:00
static short terminate = 0 ;
2005-03-25 17:53:12 +00:00
extern int active_children ;
2004-02-19 11:14:22 +00:00
2016-02-09 13:46:13 -05:00
static short foreground = - 1 ;
2010-12-22 12:12:18 +01:00
char updtmpdir [ 512 ] , dbdir [ 512 ] ;
2010-11-04 20:08:58 +02:00
int sigchld_wait = 1 ;
2011-09-15 14:44:43 +02:00
const char * pidfile = NULL ;
2014-01-15 17:27:17 +00:00
char hostid [ 37 ] ;
2005-06-07 01:40:08 +00:00
2014-01-15 17:27:17 +00:00
char * get_hostid ( void * cbdata ) ;
2014-07-11 09:30:58 -04:00
int is_valid_hostid ( void ) ;
2014-01-08 08:55:52 -05:00
2012-07-31 17:30:19 -04:00
static void
sighandler ( int sig )
{
2004-02-19 11:14:22 +00:00
2012-07-31 17:30:19 -04:00
switch ( sig )
{
2006-09-27 14:06:28 +00:00
# ifdef SIGCHLD
2012-07-31 17:30:19 -04:00
case SIGCHLD :
if ( sigchld_wait )
waitpid ( - 1 , NULL , WNOHANG ) ;
active_children - - ;
break ;
2006-09-27 14:06:28 +00:00
# endif
2005-03-25 17:53:12 +00:00
2010-11-04 20:08:58 +02:00
# ifdef SIGPIPE
2012-07-31 17:30:19 -04:00
case SIGPIPE :
/* no action, app will get EPIPE */
break ;
2010-11-04 20:08:58 +02:00
# endif
2006-09-27 14:06:28 +00:00
# ifdef SIGALRM
2012-07-31 17:30:19 -04:00
case SIGALRM :
terminate = - 1 ;
break ;
2006-09-27 14:06:28 +00:00
# endif
# ifdef SIGUSR1
2012-07-31 17:30:19 -04:00
case SIGUSR1 :
terminate = - 1 ;
break ;
2006-09-27 14:06:28 +00:00
# endif
2004-02-19 11:14:22 +00:00
2006-09-27 14:06:28 +00:00
# ifdef SIGHUP
2012-07-31 17:30:19 -04:00
case SIGHUP :
terminate = - 2 ;
break ;
2006-09-27 14:06:28 +00:00
# endif
2004-02-19 11:14:22 +00:00
2012-07-31 17:30:19 -04:00
default :
if ( * updtmpdir )
cli_rmdirs ( updtmpdir ) ;
if ( pidfile )
unlink ( pidfile ) ;
logg ( " Update process terminated \n " ) ;
2016-02-09 13:46:13 -05:00
exit ( 0 ) ;
2004-02-19 11:14:22 +00:00
}
2004-04-16 21:28:44 +00:00
2004-02-19 11:14:22 +00:00
return ;
}
2012-07-31 17:30:19 -04:00
static void
writepid ( const char * pidfile )
2006-08-30 22:41:21 +00:00
{
2012-07-31 17:30:19 -04:00
FILE * fd ;
int old_umask ;
old_umask = umask ( 0006 ) ;
if ( ( fd = fopen ( pidfile , " w " ) ) = = NULL )
{
logg ( " !Can't save PID to file %s: %s \n " , pidfile , strerror ( errno ) ) ;
}
else
{
2014-11-20 12:38:33 -05:00
fprintf ( fd , " %d \n " , ( int ) getpid ( ) ) ;
2012-07-31 17:30:19 -04:00
fclose ( fd ) ;
2004-02-19 11:14:22 +00:00
}
2012-07-31 17:30:19 -04:00
umask ( old_umask ) ;
2004-02-19 11:14:22 +00:00
}
2012-07-31 17:30:19 -04:00
static void
help ( void )
2006-08-30 22:41:21 +00:00
{
mprintf_stdout = 1 ;
2018-02-06 16:23:07 -05:00
mprintf ( " \n " ) ;
mprintf ( " Clam AntiVirus: Database Updater %s \n " , get_version ( ) ) ;
2018-03-27 13:06:46 -04:00
mprintf ( " By The ClamAV Team: https://www.clamav.net/about.html#credits \n " ) ;
2018-02-06 16:23:07 -05:00
mprintf ( " (C) 2007-2018 Cisco Systems, Inc. \n " ) ;
mprintf ( " \n " ) ;
mprintf ( " freshclam [options] \n " ) ;
mprintf ( " \n " ) ;
mprintf ( " --help -h Show this help \n " ) ;
mprintf ( " --version -V Print version number and exit \n " ) ;
mprintf ( " --verbose -v Be verbose \n " ) ;
mprintf ( " --debug Enable debug messages \n " ) ;
mprintf ( " --quiet Only output error messages \n " ) ;
mprintf ( " --no-warnings Don't print and log warnings \n " ) ;
mprintf ( " --stdout Write to stdout instead of stderr \n " ) ;
mprintf ( " --show-progress Show download progress percentage \n " ) ;
mprintf ( " \n " ) ;
mprintf ( " --config-file=FILE Read configuration from FILE. \n " ) ;
mprintf ( " --log=FILE -l FILE Log into FILE \n " ) ;
2009-09-24 16:08:52 +02:00
# ifndef _WIN32
2018-02-06 16:23:07 -05:00
mprintf ( " --daemon -d Run in daemon mode \n " ) ;
mprintf ( " --pid=FILE -p FILE Save daemon's pid in FILE \n " ) ;
mprintf ( " --user=USER -u USER Run as USER \n " ) ;
2009-09-24 16:08:52 +02:00
# endif
2018-02-06 16:23:07 -05:00
mprintf ( " --no-dns Force old non-DNS verification method \n " ) ;
mprintf ( " --checks=#n -c #n Number of checks per day, 1 <= n <= 50 \n " ) ;
mprintf ( " --datadir=DIRECTORY Download new databases into DIRECTORY \n " ) ;
2006-08-30 22:41:21 +00:00
# ifdef BUILD_CLAMD
2018-02-06 16:23:07 -05:00
mprintf ( " --daemon-notify[=/path/clamd.conf] Send RELOAD command to clamd \n " ) ;
2006-08-30 22:41:21 +00:00
# endif
2018-02-06 16:23:07 -05:00
mprintf ( " --local-address=IP -a IP Bind to IP for HTTP downloads \n " ) ;
mprintf ( " --on-update-execute=COMMAND Execute COMMAND after successful update \n " ) ;
mprintf ( " --on-error-execute=COMMAND Execute COMMAND if errors occurred \n " ) ;
mprintf ( " --on-outdated-execute=COMMAND Execute COMMAND when software is outdated \n " ) ;
mprintf ( " --list-mirrors Print mirrors from mirrors.dat \n " ) ;
mprintf ( " --update-db=DBNAME Only update database DBNAME \n " ) ;
2012-07-31 17:30:19 -04:00
mprintf ( " \n " ) ;
2006-08-30 22:41:21 +00:00
}
2012-07-31 17:30:19 -04:00
static int
download ( const struct optstruct * opts , const char * cfgfile )
2006-08-30 22:41:21 +00:00
{
2018-10-10 06:09:58 -07:00
time_t currtime ;
2018-12-03 12:37:58 -05:00
int ret = 0 , attempt = 1 , maxattempts = 0 ;
2012-07-31 17:30:19 -04:00
const struct optstruct * opt ;
2006-08-30 22:41:21 +00:00
2018-10-10 06:09:58 -07:00
time ( & currtime ) ;
logg ( " ClamAV update process started at %s " , ctime ( & currtime ) ) ;
logg ( " *Using IPv6 aware code \n " ) ;
2006-08-30 22:41:21 +00:00
2012-07-31 17:30:19 -04:00
maxattempts = optget ( opts , " MaxAttempts " ) - > numarg ;
logg ( " *Max retries == %d \n " , maxattempts ) ;
2006-08-30 22:41:21 +00:00
2012-07-31 17:30:19 -04:00
if ( ! ( opt = optget ( opts , " DatabaseMirror " ) ) - > enabled )
{
logg ( " ^You must specify at least one database mirror in %s \n " ,
cfgfile ) ;
2012-12-07 19:54:59 -05:00
return FCE_CONFIG ;
2012-07-31 17:30:19 -04:00
}
else
{
while ( opt )
{
2018-12-03 12:37:58 -05:00
ret = downloadmanager ( opts , opt - > strarg , attempt ) ;
2009-10-15 02:39:29 +02:00
# ifndef _WIN32
2012-07-31 17:30:19 -04:00
alarm ( 0 ) ;
2009-10-15 02:39:29 +02:00
# endif
2012-12-07 19:54:59 -05:00
if ( ret = = FCE_CONNECTION | | ret = = FCE_BADCVD
| | ret = = FCE_FAILEDGET | | ret = = FCE_MIRRORNOTSYNC )
2012-07-31 17:30:19 -04:00
{
2018-12-03 12:37:58 -05:00
if ( attempt < maxattempts )
2012-07-31 17:30:19 -04:00
{
logg ( " Trying again in 5 secs... \n " ) ;
2018-12-03 12:37:58 -05:00
attempt + + ;
2012-07-31 17:30:19 -04:00
sleep ( 5 ) ;
continue ;
}
else
{
logg ( " Giving up on %s... \n " , opt - > strarg ) ;
opt = ( struct optstruct * ) opt - > nextarg ;
if ( ! opt )
{
2018-03-27 13:06:46 -04:00
logg ( " Update failed. Your network may be down or none of the mirrors listed in %s is working. Check https://www.clamav.net/documents/official-mirror-faq for possible reasons. \n " , cfgfile ) ;
2012-07-31 17:30:19 -04:00
}
2018-12-03 12:37:58 -05:00
attempt = 1 ;
2012-07-31 17:30:19 -04:00
}
}
else
{
return ret ;
}
}
2006-08-30 22:41:21 +00:00
}
return ret ;
}
2012-07-31 17:30:19 -04:00
static void
msg_callback ( enum cl_msg severity , const char * fullmsg , const char * msg ,
void * ctx )
2010-11-10 14:05:04 +02:00
{
2014-07-11 09:30:58 -04:00
UNUSEDPARAM ( fullmsg ) ;
UNUSEDPARAM ( ctx ) ;
2012-07-31 17:30:19 -04:00
switch ( severity )
{
case CL_MSG_ERROR :
logg ( " ^[LibClamAV] %s " , msg ) ;
break ;
case CL_MSG_WARN :
logg ( " ~[LibClamAV] %s " , msg ) ;
2013-02-21 11:38:51 -05:00
break ;
2012-07-31 17:30:19 -04:00
default :
logg ( " *[LibClamAV] %s " , msg ) ;
break ;
2010-11-10 14:05:04 +02:00
}
}
2012-07-31 17:30:19 -04:00
int
main ( int argc , char * * argv )
2003-07-29 15:48:06 +00:00
{
2012-12-07 19:54:59 -05:00
int ret = FCE_CONNECTION , retcl ;
2012-07-31 17:30:19 -04:00
const char * cfgfile , * arg = NULL ;
char * pt ;
struct optstruct * opts ;
const struct optstruct * opt ;
2009-10-15 02:39:29 +02:00
# ifndef _WIN32
2012-07-31 17:30:19 -04:00
struct sigaction sigact ;
struct sigaction oldact ;
2006-09-27 14:06:28 +00:00
# endif
2009-09-24 19:23:21 +02:00
# ifdef HAVE_PWD_H
2012-07-31 17:30:19 -04:00
const char * dbowner ;
struct passwd * user ;
2003-12-29 05:31:52 +00:00
# endif
2012-07-31 17:30:19 -04:00
STATBUF statbuf ;
struct mirdat mdat ;
2016-02-09 13:46:13 -05:00
int j ;
2008-12-18 19:42:53 +00:00
2012-07-31 17:30:19 -04:00
if ( check_flevel ( ) )
2012-12-07 19:54:59 -05:00
exit ( FCE_INIT ) ;
2008-12-18 19:42:53 +00:00
2012-07-31 17:30:19 -04:00
if ( ( retcl = cl_init ( CL_INIT_DEFAULT ) ) )
{
mprintf ( " !Can't initialize libclamav: %s \n " , cl_strerror ( retcl ) ) ;
2012-12-07 19:54:59 -05:00
return FCE_INIT ;
2010-05-12 14:22:19 +02:00
}
2012-07-31 17:30:19 -04:00
if ( ( opts =
optparse ( NULL , argc , argv , 1 , OPT_FRESHCLAM , 0 , NULL ) ) = = NULL )
{
mprintf ( " !Can't parse command line options \n " ) ;
2012-12-07 19:54:59 -05:00
return FCE_INIT ;
2006-05-15 18:30:18 +00:00
}
2003-07-29 15:48:06 +00:00
2012-07-31 17:30:19 -04:00
if ( optget ( opts , " help " ) - > enabled )
{
help ( ) ;
optfree ( opts ) ;
2018-10-10 06:09:58 -07:00
return FC_SUCCESS ;
2006-08-30 22:41:21 +00:00
}
2016-02-09 13:46:13 -05:00
/* check foreground option from command line to override config file */
for ( j = 0 ; j < argc ; j + = 1 )
{
if ( ( memcmp ( argv [ j ] , " --foreground " , 12 ) = = 0 ) | | ( memcmp ( argv [ j ] , " -F " , 2 ) = = 0 ) )
{
/* found */
break ;
}
}
if ( j < argc ) {
if ( optget ( opts , " Foreground " ) - > enabled ) {
foreground = 1 ;
}
else {
foreground = 0 ;
}
}
2003-12-29 05:31:52 +00:00
/* parse the config file */
2012-07-31 17:30:19 -04:00
cfgfile = optget ( opts , " config-file " ) - > strarg ;
pt = strdup ( cfgfile ) ;
if ( ( opts =
optparse ( cfgfile , 0 , NULL , 1 , OPT_FRESHCLAM , 0 , opts ) ) = = NULL )
{
fprintf ( stderr , " ERROR: Can't open/parse the config file %s \n " , pt ) ;
free ( pt ) ;
2012-12-07 19:54:59 -05:00
return FCE_INIT ;
2003-12-29 05:31:52 +00:00
}
2012-07-31 17:30:19 -04:00
free ( pt ) ;
2003-12-29 05:31:52 +00:00
2012-07-31 17:30:19 -04:00
if ( optget ( opts , " version " ) - > enabled )
{
print_version ( optget ( opts , " DatabaseDirectory " ) - > strarg ) ;
optfree ( opts ) ;
2018-10-10 06:09:58 -07:00
return FC_SUCCESS ;
2008-01-22 10:42:30 +00:00
}
2012-07-31 17:30:19 -04:00
if ( optget ( opts , " HTTPProxyPassword " ) - > enabled )
{
2013-09-25 16:22:18 -04:00
if ( CLAMSTAT ( cfgfile , & statbuf ) = = - 1 )
2012-07-31 17:30:19 -04:00
{
logg ( " ^Can't stat %s (critical error) \n " , cfgfile ) ;
optfree ( opts ) ;
2012-12-07 19:54:59 -05:00
return FCE_CONFIG ;
2012-07-31 17:30:19 -04:00
}
2006-09-27 14:06:28 +00:00
2009-09-24 16:08:52 +02:00
# ifndef _WIN32
2012-07-31 17:30:19 -04:00
if ( statbuf .
st_mode & ( S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH |
S_IXOTH ) )
{
logg ( " ^Insecure permissions (for HTTPProxyPassword): %s must have no more than 0700 permissions. \n " , cfgfile ) ;
optfree ( opts ) ;
2012-12-07 19:54:59 -05:00
return FCE_CONFIG ;
2012-07-31 17:30:19 -04:00
}
2004-06-02 20:17:00 +00:00
# endif
2004-03-22 20:21:57 +00:00
}
2004-01-09 01:10:52 +00:00
2009-09-24 19:23:21 +02:00
# ifdef HAVE_PWD_H
2004-03-22 20:21:57 +00:00
/* freshclam shouldn't work with root privileges */
2012-07-31 17:30:19 -04:00
dbowner = optget ( opts , " DatabaseOwner " ) - > strarg ;
if ( ! geteuid ( ) )
{
if ( ( user = getpwnam ( dbowner ) ) = = NULL )
{
logg ( " ^Can't get information about user %s. \n " , dbowner ) ;
optfree ( opts ) ;
2012-12-07 19:54:59 -05:00
return FCE_USERINFO ;
2012-07-31 17:30:19 -04:00
}
2003-07-29 15:48:06 +00:00
2004-11-05 10:07:45 +00:00
# ifdef HAVE_INITGROUPS
2016-06-02 11:54:01 -04:00
if ( initgroups ( dbowner , user - > pw_gid ) ) {
logg ( " ^initgroups() failed. \n " ) ;
2016-06-13 11:16:39 -04:00
optfree ( opts ) ;
2016-06-02 11:54:01 -04:00
return FCE_USERORGROUP ;
}
# elif HAVE_SETGROUPS
if ( setgroups ( 1 , & user - > pw_gid ) ) {
logg ( " ^setgroups() failed. \n " ) ;
2016-06-13 11:16:39 -04:00
optfree ( opts ) ;
2016-06-02 11:54:01 -04:00
return FCE_USERORGROUP ;
}
2004-06-12 15:50:35 +00:00
# endif
2012-07-31 17:30:19 -04:00
if ( setgid ( user - > pw_gid ) )
{
logg ( " ^setgid(%d) failed. \n " , ( int ) user - > pw_gid ) ;
optfree ( opts ) ;
2012-12-07 19:54:59 -05:00
return FCE_USERORGROUP ;
2012-07-31 17:30:19 -04:00
}
if ( setuid ( user - > pw_uid ) )
{
logg ( " ^setuid(%d) failed. \n " , ( int ) user - > pw_uid ) ;
optfree ( opts ) ;
2012-12-07 19:54:59 -05:00
return FCE_USERORGROUP ;
2012-07-31 17:30:19 -04:00
}
2003-07-29 15:48:06 +00:00
}
2009-10-15 02:39:29 +02:00
# endif /* HAVE_PWD_H */
2003-07-29 15:48:06 +00:00
/* initialize some important variables */
2012-07-31 17:30:19 -04:00
if ( optget ( opts , " Debug " ) - > enabled | | optget ( opts , " debug " ) - > enabled )
cl_debug ( ) ;
2003-10-26 06:01:03 +00:00
2012-07-31 17:30:19 -04:00
if ( optget ( opts , " verbose " ) - > enabled )
mprintf_verbose = 1 ;
2003-07-29 15:48:06 +00:00
2012-07-31 17:30:19 -04:00
if ( optget ( opts , " quiet " ) - > enabled )
mprintf_quiet = 1 ;
2003-07-29 15:48:06 +00:00
2012-07-31 17:30:19 -04:00
if ( optget ( opts , " no-warnings " ) - > enabled )
{
mprintf_nowarn = 1 ;
logg_nowarn = 1 ;
2008-01-23 12:12:25 +00:00
}
2012-07-31 17:30:19 -04:00
if ( optget ( opts , " stdout " ) - > enabled )
mprintf_stdout = 1 ;
2003-07-29 15:48:06 +00:00
2016-02-11 15:56:47 -05:00
if ( optget ( opts , " show-progress " ) - > enabled )
mprintf_progress = 1 ;
2003-07-29 15:48:06 +00:00
/* initialize logger */
2012-07-31 17:30:19 -04:00
logg_verbose = mprintf_verbose ? 1 : optget ( opts , " LogVerbose " ) - > enabled ;
logg_time = optget ( opts , " LogTime " ) - > enabled ;
logg_size = optget ( opts , " LogFileMaxSize " ) - > numarg ;
2012-08-20 10:53:25 -04:00
if ( logg_size )
logg_rotate = optget ( opts , " LogRotate " ) - > enabled ;
2012-07-31 17:30:19 -04:00
if ( ( opt = optget ( opts , " UpdateLogFile " ) ) - > enabled )
{
logg_file = opt - > strarg ;
if ( logg ( " #-------------------------------------- \n " ) )
{
mprintf ( " !Problem with internal logger (UpdateLogFile = %s). \n " ,
logg_file ) ;
optfree ( opts ) ;
2012-12-07 19:54:59 -05:00
return FCE_LOGGING ;
2012-07-31 17:30:19 -04:00
}
}
else
logg_file = NULL ;
2003-07-29 15:48:06 +00:00
2004-03-29 00:00:58 +00:00
# if defined(USE_SYSLOG) && !defined(C_AIX)
2012-07-31 17:30:19 -04:00
if ( optget ( opts , " LogSyslog " ) - > enabled )
{
int fac = LOG_LOCAL6 ;
if ( ( opt = optget ( opts , " LogFacility " ) ) - > enabled )
{
if ( ( fac = logg_facility ( opt - > strarg ) ) = = - 1 )
{
mprintf ( " !LogFacility: %s: No such facility. \n " ,
opt - > strarg ) ;
optfree ( opts ) ;
2012-12-07 19:54:59 -05:00
return FCE_LOGGING ;
2012-07-31 17:30:19 -04:00
}
}
openlog ( " freshclam " , LOG_PID , fac ) ;
logg_syslog = 1 ;
2004-03-30 21:11:25 +00:00
}
2004-03-14 20:45:58 +00:00
# endif
2012-07-31 17:30:19 -04:00
cl_set_clcb_msg ( msg_callback ) ;
2003-12-29 05:31:52 +00:00
/* change the current working directory */
2012-07-31 17:30:19 -04:00
if ( chdir ( optget ( opts , " DatabaseDirectory " ) - > strarg ) )
{
logg ( " !Can't change dir to %s \n " ,
optget ( opts , " DatabaseDirectory " ) - > strarg ) ;
optfree ( opts ) ;
2012-12-07 19:54:59 -05:00
return FCE_DIRECTORY ;
2012-07-31 17:30:19 -04:00
}
else
{
if ( ! getcwd ( dbdir , sizeof ( dbdir ) ) )
{
logg ( " !getcwd() failed \n " ) ;
optfree ( opts ) ;
2012-12-07 19:54:59 -05:00
return FCE_DIRECTORY ;
2012-07-31 17:30:19 -04:00
}
logg ( " *Current working dir is %s \n " , dbdir ) ;
2010-08-31 16:13:31 +02:00
}
2003-07-29 15:48:06 +00:00
2007-01-06 16:00:14 +00:00
2012-07-31 17:30:19 -04:00
if ( optget ( opts , " list-mirrors " ) - > enabled )
{
2018-10-10 06:09:58 -07:00
if ( mirman_read ( " mirrors.dat " , & mdat , 1 ) ! = FC_SUCCESS )
2012-07-31 17:30:19 -04:00
{
printf ( " Can't read mirrors.dat \n " ) ;
optfree ( opts ) ;
2012-12-07 19:54:59 -05:00
return FCE_FILE ;
2012-07-31 17:30:19 -04:00
}
mirman_list ( & mdat ) ;
mirman_free ( & mdat ) ;
optfree ( opts ) ;
2018-10-10 06:09:58 -07:00
return FC_SUCCESS ;
2007-01-06 16:00:14 +00:00
}
2012-07-31 17:30:19 -04:00
if ( ( opt = optget ( opts , " PrivateMirror " ) ) - > enabled )
{
struct optstruct * dbm , * opth ;
dbm = ( struct optstruct * ) optget ( opts , " DatabaseMirror " ) ;
dbm - > active = dbm - > enabled = 1 ;
do
{
if ( cli_strbcasestr ( opt - > strarg , " .clamav.net " ) )
{
logg ( " !PrivateMirror: *.clamav.net is not allowed in this mode \n " ) ;
optfree ( opts ) ;
2012-12-07 19:54:59 -05:00
return FCE_PRIVATEMIRROR ;
2012-07-31 17:30:19 -04:00
}
if ( dbm - > strarg )
free ( dbm - > strarg ) ;
dbm - > strarg = strdup ( opt - > strarg ) ;
if ( ! dbm - > strarg )
{
logg ( " !strdup() failed \n " ) ;
optfree ( opts ) ;
2012-12-07 19:54:59 -05:00
return FCE_MEM ;
2012-07-31 17:30:19 -04:00
}
if ( ! dbm - > nextarg )
{
dbm - > nextarg =
( struct optstruct * ) calloc ( 1 ,
sizeof ( struct optstruct ) ) ;
if ( ! dbm - > nextarg )
{
logg ( " !calloc() failed \n " ) ;
optfree ( opts ) ;
2012-12-07 19:54:59 -05:00
return FCE_MEM ;
2012-07-31 17:30:19 -04:00
}
}
opth = dbm ;
dbm = dbm - > nextarg ;
}
while ( ( opt = opt - > nextarg ) ) ;
opth - > nextarg = NULL ;
while ( dbm )
{
free ( dbm - > name ) ;
free ( dbm - > cmd ) ;
free ( dbm - > strarg ) ;
opth = dbm ;
dbm = dbm - > nextarg ;
free ( opth ) ;
}
/* disable DNS db checks */
opth = ( struct optstruct * ) optget ( opts , " no-dns " ) ;
opth - > active = opth - > enabled = 1 ;
/* disable scripted updates */
opth = ( struct optstruct * ) optget ( opts , " ScriptedUpdates " ) ;
opth - > active = opth - > enabled = 0 ;
2011-09-12 16:29:56 +02:00
}
2010-05-12 14:22:19 +02:00
* updtmpdir = 0 ;
# ifdef _WIN32
2012-07-31 17:30:19 -04:00
signal ( SIGINT , sighandler ) ;
2010-05-12 14:22:19 +02:00
# else
2012-07-31 17:30:19 -04:00
memset ( & sigact , 0 , sizeof ( struct sigaction ) ) ;
2010-05-12 14:22:19 +02:00
sigact . sa_handler = sighandler ;
2012-07-31 17:30:19 -04:00
sigaction ( SIGINT , & sigact , NULL ) ;
sigaction ( SIGPIPE , & sigact , NULL ) ;
2010-05-12 14:22:19 +02:00
# endif
2012-07-31 17:30:19 -04:00
if ( optget ( opts , " daemon " ) - > enabled )
{
int bigsleep , checks ;
2009-10-15 02:39:29 +02:00
# ifndef _WIN32
2012-07-31 17:30:19 -04:00
time_t now , wakeup ;
2003-07-29 15:48:06 +00:00
2012-07-31 17:30:19 -04:00
sigaction ( SIGTERM , & sigact , NULL ) ;
sigaction ( SIGHUP , & sigact , NULL ) ;
sigaction ( SIGCHLD , & sigact , NULL ) ;
2006-09-27 14:06:28 +00:00
# endif
2004-01-09 01:10:52 +00:00
2012-07-31 17:30:19 -04:00
checks = optget ( opts , " Checks " ) - > numarg ;
2003-07-29 15:48:06 +00:00
2012-07-31 17:30:19 -04:00
if ( checks < = 0 )
{
logg ( " ^Number of checks must be a positive integer. \n " ) ;
optfree ( opts ) ;
2012-12-07 19:54:59 -05:00
return FCE_CHECKS ;
2012-07-31 17:30:19 -04:00
}
2003-07-29 15:48:06 +00:00
2012-07-31 17:30:19 -04:00
if ( ! optget ( opts , " DNSDatabaseInfo " ) - > enabled
| | optget ( opts , " no-dns " ) - > enabled )
{
if ( checks > 50 )
{
logg ( " ^Number of checks must be between 1 and 50. \n " ) ;
optfree ( opts ) ;
2012-12-07 19:54:59 -05:00
return FCE_CHECKS ;
2012-07-31 17:30:19 -04:00
}
}
2004-08-22 00:26:52 +00:00
2012-07-31 17:30:19 -04:00
bigsleep = 24 * 3600 / checks ;
2005-02-13 09:58:40 +00:00
2009-09-24 19:10:27 +02:00
# ifndef _WIN32
2016-02-09 13:46:13 -05:00
/* fork into background */
if ( foreground = = - 1 )
{
if ( optget ( opts , " Foreground " ) - > enabled )
{
foreground = 1 ;
}
else
{
foreground = 0 ;
}
}
if ( foreground = = 0 )
2012-07-31 17:30:19 -04:00
{
if ( daemonize ( ) = = - 1 )
{
logg ( " !daemonize() failed \n " ) ;
optfree ( opts ) ;
2012-12-07 19:54:59 -05:00
return FCE_FAILEDUPDATE ;
2012-07-31 17:30:19 -04:00
}
mprintf_disabled = 1 ;
2005-06-07 01:40:08 +00:00
}
2008-05-21 14:41:53 +00:00
# endif
2005-02-13 09:58:40 +00:00
2012-07-31 17:30:19 -04:00
if ( ( opt = optget ( opts , " PidFile " ) ) - > enabled )
{
pidfile = opt - > strarg ;
writepid ( pidfile ) ;
}
2004-06-13 02:11:26 +00:00
2012-07-31 17:30:19 -04:00
active_children = 0 ;
2005-03-25 17:53:12 +00:00
2012-07-31 17:30:19 -04:00
logg ( " #freshclam daemon %s (OS: " TARGET_OS_TYPE " , ARCH: "
TARGET_ARCH_TYPE " , CPU: " TARGET_CPU_TYPE " ) \n " ,
get_version ( ) ) ;
2003-07-29 15:48:06 +00:00
2012-07-31 17:30:19 -04:00
while ( ! terminate )
{
ret = download ( opts , cfgfile ) ;
2004-01-09 01:10:52 +00:00
2014-01-16 14:52:54 -05:00
if ( ret > 1 )
2012-07-31 17:30:19 -04:00
{
if ( ( opt = optget ( opts , " OnErrorExecute " ) ) - > enabled )
arg = opt - > strarg ;
2004-01-09 01:10:52 +00:00
2012-07-31 17:30:19 -04:00
if ( arg )
execute ( " OnErrorExecute " , arg , opts ) ;
2008-06-02 13:47:15 +00:00
2012-07-31 17:30:19 -04:00
arg = NULL ;
}
2003-07-29 15:48:06 +00:00
2012-07-31 17:30:19 -04:00
logg ( " #-------------------------------------- \n " ) ;
2006-09-27 14:06:28 +00:00
# ifdef SIGALRM
2012-07-31 17:30:19 -04:00
sigaction ( SIGALRM , & sigact , & oldact ) ;
2006-09-27 14:06:28 +00:00
# endif
# ifdef SIGUSR1
2012-07-31 17:30:19 -04:00
sigaction ( SIGUSR1 , & sigact , & oldact ) ;
2006-09-27 14:06:28 +00:00
# endif
2009-09-24 16:08:52 +02:00
# ifdef _WIN32
2012-07-31 17:30:19 -04:00
sleep ( bigsleep ) ;
# else
time ( & wakeup ) ;
wakeup + = bigsleep ;
alarm ( bigsleep ) ;
do
{
pause ( ) ;
time ( & now ) ;
}
while ( ! terminate & & now < wakeup ) ;
if ( terminate = = - 1 )
{
logg ( " Received signal: wake up \n " ) ;
terminate = 0 ;
}
else if ( terminate = = - 2 )
{
logg ( " Received signal: re-opening log file \n " ) ;
terminate = 0 ;
logg_close ( ) ;
}
2006-09-27 14:06:28 +00:00
# endif
2004-04-16 21:28:44 +00:00
2006-09-27 14:06:28 +00:00
# ifdef SIGALRM
2012-07-31 17:30:19 -04:00
sigaction ( SIGALRM , & oldact , NULL ) ;
2006-09-27 14:06:28 +00:00
# endif
# ifdef SIGUSR1
2012-07-31 17:30:19 -04:00
sigaction ( SIGUSR1 , & oldact , NULL ) ;
# endif
}
}
else
{
2014-01-16 14:52:54 -05:00
ret = download ( opts , cfgfile ) ;
2008-10-10 14:22:00 +00:00
}
2003-07-29 15:48:06 +00:00
2012-07-31 17:30:19 -04:00
if ( ret > 1 )
{
if ( ( opt = optget ( opts , " OnErrorExecute " ) ) - > enabled )
execute ( " OnErrorExecute " , opt - > strarg , opts ) ;
2004-01-09 01:10:52 +00:00
}
2008-06-02 13:47:15 +00:00
2012-07-31 17:30:19 -04:00
if ( pidfile )
{
unlink ( pidfile ) ;
2004-02-19 11:14:22 +00:00
}
2003-07-29 15:48:06 +00:00
2012-07-31 17:30:19 -04:00
optfree ( opts ) ;
2006-09-27 14:06:28 +00:00
2014-05-12 13:36:47 -04:00
cl_cleanup_crypto ( ) ;
2018-09-11 23:54:35 -04:00
return ret > 1 ? ret : 0 ;
2003-07-29 15:48:06 +00:00
}
2014-01-08 08:55:52 -05:00
2014-01-15 17:27:17 +00:00
int is_valid_hostid ( void )
{
int count , i ;
if ( strlen ( hostid ) ! = 36 )
return 0 ;
count = 0 ;
for ( i = 0 ; i < 36 ; i + + )
if ( hostid [ i ] = = ' - ' )
count + + ;
if ( count ! = 4 )
return 0 ;
if ( hostid [ 8 ] ! = ' - ' | | hostid [ 13 ] ! = ' - ' | | hostid [ 18 ] ! = ' - ' | | hostid [ 23 ] ! = ' - ' )
return 0 ;
return 1 ;
}
char * get_hostid ( void * cbdata )
{
2014-07-11 09:30:58 -04:00
UNUSEDPARAM ( cbdata ) ;
2014-01-15 17:27:17 +00:00
if ( ! strcmp ( hostid , " none " ) )
return NULL ;
if ( ! is_valid_hostid ( ) )
return strdup ( STATS_ANON_UUID ) ;
logg ( " HostID is valid: %s \n " , hostid ) ;
return strdup ( hostid ) ;
}