Esempio n. 1
0
	int Load_As_Config(HWND hWnd, HINSTANCE hInst)
	{
		char Name[2048];
		OPENFILENAME ofn;

		SetCurrentDirectoryA(thisprocessPath);

		strcpy(&Name[0], defaultConfigFilename);
		memset(&ofn, 0, sizeof(OPENFILENAME));

		ofn.lStructSize = sizeof(OPENFILENAME);
		ofn.hwndOwner = hWnd;
		ofn.hInstance = hInst;
		ofn.lpstrFile = Name;
		ofn.nMaxFile = 2047;
		ofn.lpstrFilter = "Config Files\0*.cfg\0All Files\0*.*\0\0";
		ofn.nFilterIndex = 1;
		ofn.lpstrInitialDir = thisprocessPath;
		ofn.lpstrDefExt = "cfg";
		ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;

		if(GetOpenFileName(&ofn))
		{
			Load_Config(Name);
			return 1;
		}
		else return 0;
	}
bool AtlasResourceCompiler::Should_Compile()
{
	Platform* platform = Platform::Get();

	// If input dosen't exist, the wtf.
	if (!platform->Is_File(m_input_path.c_str()))
	{
		DBG_ASSERT_STR(false, "Attempt to compile non-existing resource '%s'.", m_input_path.c_str());
		return false;
	}

	// If input has been modified, compile is definitely required.
	if (Check_File_Timestamp(m_input_path))
	{
		return true;
	}

	// Read in the XML, so we can determine if there are any other dependent files.
	if (!Load_Config())
	{
		return false;
	}

	// Check dependent files.
	for (std::vector<std::string>::iterator iter = m_dependent_files.begin(); iter != m_dependent_files.end(); iter++)
	{
		std::string& path = *iter;
		if (Check_File_Timestamp(path.c_str()))
		{
			return true;
		}
	}

	return false;
}
Esempio n. 3
0
int main(int argc, char **argv)
{

    const struct option long_options[] =
    {
        { "help",         no_argument,          NULL,   'h' },
        { "debug",        required_argument,    NULL,   'd' },
        { "daemon",       no_argument,          NULL,   'D' },
        { "user",         required_argument,    NULL,   'u' },
        { "chroot",       required_argument,    NULL,   'c' },
        { "credits",	  no_argument,		NULL,	'C' },
        { "config",       required_argument,    NULL,   'f' },
        { "log",          required_argument,    NULL,   'l' },
        { "file",	  required_argument,    NULL,   'F' },
        {0, 0, 0, 0}
    };

    static const char *short_options =
        "l:f:u:d:c:pDhC";

    int option_index = 0;

    /****************************************************************************/
    /* libpcap/PLOG (syslog sniffer) local variables                            */
    /****************************************************************************/

#ifdef HAVE_LIBPCAP
    pthread_t pcap_thread;
    pthread_attr_t thread_pcap_attr;
    pthread_attr_init(&thread_pcap_attr);
    pthread_attr_setdetachstate(&thread_pcap_attr,  PTHREAD_CREATE_DETACHED);
#endif

    /****************************************************************************/
    /* Perfmonitor local variables                                              */
    /****************************************************************************/

    pthread_t perfmonitor_thread;
    pthread_attr_t thread_perfmonitor_attr;
    pthread_attr_init(&thread_perfmonitor_attr);
    pthread_attr_setdetachstate(&thread_perfmonitor_attr,  PTHREAD_CREATE_DETACHED);

    /****************************************************************************/
    /* Various local variables						        */
    /****************************************************************************/

    /* Block all signals,  we create a signal handling thread */

    sigset_t signal_set;
    pthread_t sig_thread;
    sigfillset( &signal_set );
    pthread_sigmask( SIG_BLOCK, &signal_set, NULL );

    /* Key board handler (displays stats, etc */

    pthread_t key_thread;
    pthread_attr_t key_thread_attr;
    pthread_attr_init(&key_thread_attr);
    pthread_attr_setdetachstate(&key_thread_attr,  PTHREAD_CREATE_DETACHED);

    struct sockaddr_in sa;
    char src_dns_lookup[20];
    int  dns_flag=0;

    sbool fifoerr=0;

    char *syslog_host=NULL;
    char *syslog_facility=NULL;
    char *syslog_priority=NULL;
    char *syslog_level=NULL;
    char *syslog_tag=NULL;
    char *syslog_date=NULL;
    char *syslog_time=NULL;
    char *syslog_program=NULL;
    char *syslog_msg=NULL;

    char syslogstring[MAX_SYSLOGMSG];

    signed char c;
    char *tok;
    int rc=0;

    int i;

    time_t t;
    struct tm *run;

    sbool debugflag=0;

    /* Allocate and clear memory for global structs */

    /* Allocate memory for global struct _SaganDebug */
    debug = malloc(sizeof(_SaganDebug));
    memset(debug, 0, sizeof(_SaganDebug));

    /* Allocate memroy for global struct _SaganConfig */
    config = malloc(sizeof(_SaganConfig));
    memset(config, 0, sizeof(_SaganConfig));

    struct _SaganSigArgs *sigargs;
    sigargs = malloc(sizeof(_SaganSigArgs));
    memset(sigargs, 0, sizeof(_SaganSigArgs));

    struct _SaganDNSCache *dnscache;
    dnscache = malloc(sizeof(_SaganDNSCache));
    memset(dnscache, 0, sizeof(_SaganDNSCache));

    counters = malloc(sizeof(_SaganCounters));
    memset(counters, 0, sizeof(_SaganCounters));

    flowbit = malloc(sizeof(_Sagan_Flowbit));
    memset(flowbit, 0, sizeof(_Sagan_Flowbit));

    t = time(NULL);
    run=localtime(&t);
    strftime(config->sagan_startutime, sizeof(config->sagan_startutime), "%s",  run);

    strlcpy(config->sagan_config, CONFIG_FILE_PATH, sizeof(config->sagan_config));

    /* We set the config->sagan_log_filepath to the system default.  It'll be fopen'ed
       shortly - 06/03/2011 - Champ Clark III */

    strlcpy(config->sagan_log_filepath, SAGANLOG, sizeof(config->sagan_log_filepath));
    config->sagan_runas = RUNAS;

    /* Get command line arg's */
    while ((c = getopt_long(argc, argv, short_options, long_options, &option_index)) != -1)
        {

            switch(c)
                {

                    if (c == -1) break;

                case 'h':
                    Sagan_Usage();
                    exit(0);
                    break;

                case 'C':
                    Sagan_Credits();
                    exit(0);
                    break;

                case 'd':

                    if (Sagan_strstr(optarg, "malformed"))
                        {
                            debug->debugmalformed=1;
                            debugflag=1;
                        }

                    if (Sagan_strstr(optarg, "limits"))
                        {
                            debug->debuglimits=1;
                            debugflag=1;
                        }

                    if (Sagan_strstr(optarg, "syslog"))
                        {
                            debug->debugsyslog=1;
                            debugflag=1;
                        }

                    if (Sagan_strstr(optarg, "load"))
                        {
                            debug->debugload=1;
                            debugflag=1;
                        }

                    if (Sagan_strstr(optarg, "fwsam"))
                        {
                            debug->debugfwsam=1;
                            debugflag=1;
                        }

                    if (Sagan_strstr(optarg, "external"))
                        {
                            debug->debugexternal=1;
                            debugflag=1;
                        }

                    if (Sagan_strstr(optarg, "threads"))
                        {
                            debug->debugthreads=1;
                            debugflag=1;
                        }

                    if (Sagan_strstr(optarg, "flowbit"))
                        {
                            debug->debugflowbit=1;
                            debugflag=1;
                        }

                    if (Sagan_strstr(optarg, "engine"))
                        {
                            debug->debugengine=1;
                            debugflag=1;
                        }

                    if (Sagan_strstr(optarg, "brointel"))
                        {
                            debug->debugbrointel=1;
                            debugflag=1;
                        }

#ifdef HAVE_LIBGEOIP
                    if (Sagan_strstr(optarg, "geoip"))
                        {
                            debug->debuggeoip=1;
                            debugflag=1;
                        }
#endif

#ifdef HAVE_LIBLOGNORM
                    if (Sagan_strstr(optarg, "normalize" ))
                        {
                            debug->debugnormalize=1;
                            debugflag=1;
                        }
#endif

#ifdef HAVE_LIBESMTP
                    if (Sagan_strstr(optarg, "smtp"))
                        {
                            debug->debugesmtp=1;
                            debugflag=1;
                        }
#endif

#ifdef HAVE_LIBPCAP
                    if (Sagan_strstr(optarg, "plog"))
                        {
                            debug->debugplog=1;
                            debugflag=1;
                        }
#endif

#ifdef WITH_WEBSENSE
                    if (Sagan_strstr(optarg, "websense"))
                        {
                            debug->debugwebsense=1;
                            debugflag=1;
                        }
#endif

                    /* If option is unknown */

                    if ( debugflag == 0 )
                        {
                            fprintf(stderr, "Unknown debug option %s!\n", optarg);
                            exit(1);
                        }


                    break;

                case 'D':
                    daemonize=1;
                    break;

                case 'u':
                    config->sagan_runas=optarg;
                    break;

                case 'c':
                    Sagan_Chroot(optarg);
                    break;

                case 'F':
                    config->sagan_fifo_flag=1;
                    strlcpy(config->sagan_fifo,optarg,sizeof(config->sagan_fifo) - 1);
                    break;

                case 'f':
                    strlcpy(config->sagan_config,optarg,sizeof(config->sagan_config) - 1);
                    break;

                case 'l':
                    strlcpy(config->sagan_log_filepath,optarg,sizeof(config->sagan_log_filepath) - 1);
                    break;

                default:
                    fprintf(stderr, "Invalid argument! See below for command line switches.\n");
                    Sagan_Usage();
                    exit(0);
                    break;
                }
        }

    Sagan_Open_Log_File(OPEN, SAGAN_LOG);

    Load_Config();

    Sagan_Engine_Init();

#ifdef HAVE_LIBLOGNORM
    Sagan_Liblognorm_Load();
#endif


    /* Load/init liblognorm definitions.  I tried to move this into a subroutine,
     * but that ended up causing segfaults on ln_normalize() or causing
     * liblognorm not to function correctly (not parsing fields).  Make reloading
     * a SIGHUP a issue as well.
     * 12/17/2010 - Champ
     */

    SaganProcSyslog = malloc(config->max_processor_threads * sizeof(struct _Sagan_Proc_Syslog));
    pthread_t processor_id[config->max_processor_threads];
    pthread_attr_t thread_processor_attr;
    pthread_attr_init(&thread_processor_attr);
    pthread_attr_setdetachstate(&thread_processor_attr,  PTHREAD_CREATE_DETACHED);

    Sagan_Log(S_NORMAL, "Configuration file %s loaded and %d rules loaded.", config->sagan_config, counters->rulecount);
    Sagan_Log(S_NORMAL, "Out of %d rules, %d Flowbit(s) are in use.", counters->rulecount, counters->flowbit_total_counter);
    Sagan_Log(S_NORMAL, "Sagan version %s is firing up!", VERSION);

    /* We go ahead and assign values to SaganSigArgs (struct sig_thread_args).  This
     * struct is always used by the sig_handler thread,  and sometimes used by the
     * plog_handler (below).  So we assign values now */

    sigargs->daemonize = daemonize;

#ifdef HAVE_LIBPCAP

    /* Spawn a thread to 'sniff' syslog traffic (sagan-plog.c).  This redirects syslog
       traffic to the /dev/log socket.  This needs "root" access,  so we drop priv's
       after this thread is started */

    if ( config->plog_flag )
        {

            rc = pthread_create( &pcap_thread, NULL, (void *)plog_handler, sigargs );

            if ( rc != 0 )
                {
                    Remove_Lock_File();
                    Sagan_Log(S_ERROR, "[%s, line %d] Error creating libpcap handler thread [error: %d].", __FILE__, __LINE__, rc);
                }

            sleep(1); 	/* Sleep to avoid race between main() and plog thread
		   	plog thread needs "root" rights before sagan_droppriv().
		   	In some cases main() run sagan_droppriv() before thread
		   	can complete - Champ Clark - 07/20/2011 */

        }
#endif


    Sagan_Droppriv();              /* Become the Sagan user */
    Sagan_Log(S_NORMAL, "---------------------------------------------------------------------------");


    if ( config->perfmonitor_flag )
        {

            if (( config->perfmonitor_file_stream = fopen(config->perfmonitor_file_name, "a" )) == NULL )
                {
                    Remove_Lock_File();
                    Sagan_Log(S_ERROR, "[%s, line %d] Can't open %s - %s!", __FILE__, __LINE__, config->perfmonitor_file_name, strerror(errno));
                }


            rc = pthread_create( &perfmonitor_thread, NULL, (void *)Sagan_Perfmonitor_Handler, sigargs );

            if ( rc != 0 )
                {
                    Remove_Lock_File();
                    Sagan_Log(S_ERROR, "[%s, line %d] Error creating Perfmonitor thread [error: %d].", __FILE__, __LINE__, rc);
                }
        }


    /* Open sagan alert file */

    Sagan_Open_Log_File(OPEN, ALERT_LOG);

    /****************************************************************************
     * Display processor information as we load
     ****************************************************************************/

    /* Sagan_Track_Clients processor ********************************************/

    if ( config->sagan_track_clients_flag)
        {
            if ( config->pp_sagan_track_clients ) Sagan_Log(S_NORMAL, "Client Tracking Processor: %d minute(s)", config->pp_sagan_track_clients);
            Sagan_Track_Clients_Init();
            Sagan_Load_Tracking_Cache();
        }

    /* Sagan Blacklist IP processor *********************************************/

    if ( config->blacklist_flag)
        {
            Sagan_Blacklist_Init();
            Sagan_Blacklist_Load();
        }

    /* Sagan Websense processor ************************************************/

#ifdef WITH_WEBSENSE
    if ( config->websense_flag )
        {

            curl_global_init(CURL_GLOBAL_ALL);
            config->websense_last_time = atol(config->sagan_startutime);
            Sagan_Websense_Init();

            Sagan_Log(S_NORMAL, "");
            Sagan_Log(S_NORMAL, "Websense URL: %s", config->websense_url);
            Sagan_Log(S_NORMAL, "Websense Auth: %s", config->websense_auth);
            Sagan_Log(S_NORMAL, "Websense Device ID: %s", config->websense_device_id);
            Sagan_Log(S_NORMAL, "Websense Categories File: %s", config->websense_cat);
            Sagan_Log(S_NORMAL, "Websense Max Cache: %d", config->websense_max_cache);
            Sagan_Log(S_NORMAL, "Websense Cache Timeout: %d minutes.", config->websense_timeout  / 60);
            Sagan_Log(S_NORMAL, "Websense loaded %d categories.", counters->websense_cat_count);

        }

#endif

    /* Sagan Bro Intel processor *******************************************/

    if ( config->brointel_flag )
        {

            Sagan_Log(S_NORMAL, "");

            Sagan_BroIntel_Init();
            Sagan_BroIntel_Load_File();

            Sagan_Log(S_NORMAL, "Bro Intel::ADDR Loaded: %d", counters->brointel_addr_count);
            Sagan_Log(S_NORMAL, "Bro Intel::DOMAIN Loaded: %d", counters->brointel_domain_count);
            Sagan_Log(S_NORMAL, "Bro Intel::FILE_HASH Loaded: %d", counters->brointel_file_hash_count);
            Sagan_Log(S_NORMAL, "Bro Intel::URL Loaded: %d", counters->brointel_url_count);
            Sagan_Log(S_NORMAL, "Bro Intel::SOFTWARE Loaded: %d", counters->brointel_software_count);
            Sagan_Log(S_NORMAL, "Bro Intel::EMAIL Loaded: %d", counters->brointel_email_count);
            Sagan_Log(S_NORMAL, "Bro Intel::USER_NAME Loaded: %d", counters->brointel_user_name_count);
            Sagan_Log(S_NORMAL, "Bro Intel::FILE_NAME Loaded: %d", counters->brointel_file_name_count);
            Sagan_Log(S_NORMAL, "Bro Intel::CERT_HASH Loaded: %d", counters->brointel_cert_hash_count);
            Sagan_Log(S_NORMAL, "Bro Intel Duplicates Detected: %d", counters->brointel_dups);

        }


    /***************************************************************************
     * Output plugins
     ***************************************************************************/

#ifdef HAVE_LIBESMTP
    if ( config->sagan_esmtp_flag )
        {
            Sagan_Log(S_NORMAL, "");
            if ( config->min_email_priority ) Sagan_Log(S_NORMAL, "E-mail on priority %d or higher.", config->min_email_priority);
            Sagan_Log(S_NORMAL, "E-Mail will be sent from: %s", config->sagan_esmtp_from);
            Sagan_Log(S_NORMAL, "SMTP server is set to: %s", config->sagan_esmtp_server);
        }
#endif

#ifdef WITH_SNORTSAM

    if ( config->sagan_fwsam_flag )
        {
            Sagan_Log(S_NORMAL, "");
            Sagan_Log(S_NORMAL, "Snortsam output plug in enabled.");
        }

#endif

    if ( config->sagan_external_output_flag )
        {
            Sagan_Log(S_NORMAL, "");
            Sagan_Log(S_NORMAL, "External program to be called: %s", config->sagan_extern);
        }

    /* Unified2 ****************************************************************/

#if defined(HAVE_DNET_H) || defined(HAVE_DUMBNET_H)

    if ( config->sagan_unified2_flag )
        {
            Sagan_Log(S_NORMAL, "");
            Sagan_Log(S_NORMAL, "Unified2 file: %s", config->unified2_filepath);
            Sagan_Log(S_NORMAL, "Unified2 limit: %dM", config->unified2_limit  / 1024 / 1024 );
            Unified2InitFile();
        }

#endif

    /***************************************************************************
     * Non-Processor/Output option
     ***************************************************************************/

    /* What to "ignore" ********************************************************/

    if ( config->sagan_droplist_flag )
        {
            Load_Ignore_List();
            Sagan_Log(S_NORMAL, "");
            Sagan_Log(S_NORMAL, "Loaded %d ignore/drop list item(s).", counters->droplist_count);
        }

    /***************************************************************************
     * Continue with normal startup!
     ***************************************************************************/

    Sagan_Log(S_NORMAL, "");
    Sagan_Log(S_NORMAL, " ,-._,-. 	-*> Sagan! <*-");
    Sagan_Log(S_NORMAL, " \\/)\"(\\/	Version %s", VERSION);
    Sagan_Log(S_NORMAL, "  (_o_)	Champ Clark III & The Quadrant InfoSec Team [quadrantsec.com]");
    Sagan_Log(S_NORMAL, "  /   \\/)	Copyright (C) 2009-2015 Quadrant Information Security, et al.");
    Sagan_Log(S_NORMAL, " (|| ||) 	Using PCRE version: %s", pcre_version());
    Sagan_Log(S_NORMAL, "  oo-oo     Sagan is processing events.....");
    Sagan_Log(S_NORMAL, "");

    /* Become a daemon if requested */

    if ( daemonize )
        {
            Sagan_Log(S_NORMAL, "Becoming a daemon!");

            pid_t pid = 0;
            setsid();
            pid = fork();
            if (pid == 0) {}
            else
                {
                    exit(0);
                }
        }

    /* Create the signal handlers thread _after_ the fork() so it can properly
     * handly signals - Champ Clark III - 06/13/2011 */

    rc = pthread_create( &sig_thread, NULL, (void *)Sig_Handler, sigargs );

    if ( rc != 0  )
        {
            Remove_Lock_File();
            Sagan_Log(S_ERROR, "[%s, line %d] Error creating signal handler thread. [error: %d]", __FILE__, __LINE__, rc);
        }


    /* We don't want the key_handler() if we're in daemon mode! */

    if (!daemonize)
        {

            rc = pthread_create( &key_thread, NULL, (void *)key_handler, NULL );

            if ( rc != 0 )
                {
                    Remove_Lock_File();
                    Sagan_Log(S_ERROR, "[%s, line %d] Error creating key_handler thread. [error: %d]", __FILE__, __LINE__, rc);
                }

        }

    /* We do this after forking so init scripts can complete */

    /* Check lock file _after_ thread.  If you don't it'll retreive the wrong pid
     * and incorrectly believe there is a stale lock file if --daemon */

    checklockfile();

    Sagan_Log(S_NORMAL, "Spawning %d Processor Threads.", config->max_processor_threads);

    for (i = 0; i < config->max_processor_threads; i++)
        {

            rc = pthread_create ( &processor_id[i], &thread_processor_attr, (void *)Sagan_Processor, NULL );

            if ( rc != 0 )
                {
                    Remove_Lock_File();
                    Sagan_Log(S_ERROR, "Could not pthread_create() for I/O processors [error: %d]", rc);
                }
        }

    Sagan_Log(S_NORMAL, "");

    if ( config->sagan_fifo_flag == 0 )
        {
            Sagan_Log(S_NORMAL, "Attempting to open syslog FIFO (%s).", config->sagan_fifo);
        }
    else
        {
            Sagan_Log(S_NORMAL, "Attempting to open syslog FILE (%s).", config->sagan_fifo);
        }



    while(1)
        {

            FILE *fd;
            fd = fopen(config->sagan_fifo, "r");

            if ( config->sagan_fifo_flag == 0 )
                {
                    Sagan_Log(S_NORMAL, "Successfully opened FIFO (%s).", config->sagan_fifo);
                }
            else
                {
                    Sagan_Log(S_NORMAL, "Successfully opened FILE (%s) and processing events.....", config->sagan_fifo);
                }

            while(fd != NULL)
                {


                    while(fgets(syslogstring, sizeof(syslogstring), fd) != NULL)
                        {

                            /* If the FIFO was in a error state,  let user know the FIFO writer has resumed */

                            if ( fifoerr == 1 )
                                {
                                    Sagan_Log(S_NORMAL, "FIFO writer has restarted. Processing events.");
                                    fifoerr=0;
                                }

                            counters->sagantotal++;

                            syslog_host = strtok_r(syslogstring, "|", &tok);

                            /* If we're using DNS (and we shouldn't be!),  we start DNS checks and lookups
                             * here.  We cache both good and bad lookups to not over load our DNS server(s).
                             * The only way DNS cache can be cleared is to restart Sagan */

                            if (config->syslog_src_lookup )
                                {
                                    if ( inet_pton(AF_INET, syslog_host, &(sa.sin_addr)) == 0 )   	/* Is inbound a valid IP? */
                                        {
                                            dns_flag=0;

                                            for(i=0; i <= counters->dns_cache_count ; i++)  			/* Check cache first */
                                                {
                                                    if (!strcmp( dnscache[i].hostname, syslog_host))
                                                        {
                                                            syslog_host = dnscache[i].src_ip;
                                                            dns_flag=1;
                                                        }
                                                }

                                            /* If entry was not found in cache,  look it up */

                                            if ( dns_flag == 0 )
                                                {

                                                    /* Do a DNS lookup */
                                                    strlcpy(src_dns_lookup, DNS_Lookup(syslog_host), sizeof(src_dns_lookup));

                                                    /* Invalid lookups get the config->sagan_host value */

                                                    if (src_dns_lookup[0] == '0' )
                                                        {
                                                            strlcpy(src_dns_lookup, config->sagan_host, sizeof(src_dns_lookup));
                                                            counters->dns_miss_count++;
                                                        }


                                                    /* Add entry to DNS Cache */

                                                    dnscache = (_SaganDNSCache *) realloc(dnscache, (counters->dns_cache_count+1) * sizeof(_SaganDNSCache));
                                                    strlcpy(dnscache[counters->dns_cache_count].hostname, syslog_host, sizeof(dnscache[counters->dns_cache_count].hostname));
                                                    strlcpy(dnscache[counters->dns_cache_count].src_ip, src_dns_lookup, sizeof(dnscache[counters->dns_cache_count].src_ip));
                                                    counters->dns_cache_count++;
                                                    syslog_host = src_dns_lookup;

                                                }
                                        }

                                }
                            else
                                {

                                    /* We check to see if values from our FIFO are valid.  If we aren't doing DNS related
                                    * stuff (above),  we start basic check with the syslog_host */

                                    if (syslog_host == NULL || inet_pton(AF_INET, syslog_host, &(sa.sin_addr)) == 0  )
                                        {
                                            syslog_host = config->sagan_host;

                                            pthread_mutex_lock(&SaganMalformedCounter);
                                            counters->malformed_host++;
                                            pthread_mutex_unlock(&SaganMalformedCounter);

                                            if ( debug->debugmalformed )
                                                {
                                                    Sagan_Log(S_WARN, "Sagan received a malformed 'host' (replaced with %s)", config->sagan_host);
                                                }

                                        }
                                }

//	        if ( config->home_any == 1) {

                            /* We know check the rest of the values */

                            syslog_facility=strtok_r(NULL, "|", &tok);
                            if ( syslog_facility == NULL )
                                {
                                    syslog_facility = "SAGAN: FACILITY ERROR";

                                    pthread_mutex_lock(&SaganMalformedCounter);
                                    counters->malformed_facility++;
                                    pthread_mutex_unlock(&SaganMalformedCounter);

                                    if ( debug->debugmalformed )
                                        {
                                            Sagan_Log(S_WARN, "Sagan received a malformed 'facility'");
                                        }
                                }

                            syslog_priority=strtok_r(NULL, "|", &tok);
                            if ( syslog_priority == NULL )
                                {
                                    syslog_priority = "SAGAN: PRIORITY ERROR";

                                    pthread_mutex_lock(&SaganMalformedCounter);
                                    counters->malformed_priority++;
                                    pthread_mutex_unlock(&SaganMalformedCounter);

                                    if ( debug->debugmalformed )
                                        {
                                            Sagan_Log(S_WARN, "Sagan received a malformed 'priority'");
                                        }
                                }

                            syslog_level=strtok_r(NULL, "|", &tok);
                            if ( syslog_level == NULL )
                                {
                                    syslog_level = "SAGAN: LEVEL ERROR";

                                    pthread_mutex_lock(&SaganMalformedCounter);
                                    counters->malformed_level++;
                                    pthread_mutex_unlock(&SaganMalformedCounter);

                                    if ( debug->debugmalformed )
                                        {
                                            Sagan_Log(S_WARN, "Sagan received a malformed 'level'");
                                        }
                                }

                            syslog_tag=strtok_r(NULL, "|", &tok);
                            if ( syslog_tag == NULL )
                                {
                                    syslog_tag = "SAGAN: TAG ERROR";

                                    pthread_mutex_lock(&SaganMalformedCounter);
                                    counters->malformed_tag++;
                                    pthread_mutex_unlock(&SaganMalformedCounter);

                                    if ( debug->debugmalformed )
                                        {
                                            Sagan_Log(S_WARN, "Sagan received a malformed 'tag'");
                                        }
                                }

                            syslog_date=strtok_r(NULL, "|", &tok);
                            if ( syslog_date == NULL )
                                {
                                    syslog_date = "SAGAN: DATE ERROR";

                                    pthread_mutex_lock(&SaganMalformedCounter);
                                    counters->malformed_date++;
                                    pthread_mutex_unlock(&SaganMalformedCounter);

                                    if ( debug->debugmalformed )
                                        {
                                            Sagan_Log(S_WARN, "Sagan received a malformed 'date'");
                                        }
                                }

                            syslog_time=strtok_r(NULL, "|", &tok);
                            if ( syslog_time == NULL )
                                {
                                    syslog_time = "SAGAN: TIME ERROR";

                                    pthread_mutex_lock(&SaganMalformedCounter);
                                    counters->malformed_time++;
                                    pthread_mutex_unlock(&SaganMalformedCounter);

                                    if ( debug->debugmalformed )
                                        {
                                            Sagan_Log(S_WARN, "Sagan received a malformed 'time'");
                                        }
                                }


                            syslog_program=strtok_r(NULL, "|", &tok);
                            if ( syslog_program == NULL )
                                {
                                    syslog_program = "SAGAN: PROGRAM ERROR";

                                    pthread_mutex_lock(&SaganMalformedCounter);
                                    counters->malformed_program++;
                                    pthread_mutex_unlock(&SaganMalformedCounter);

                                    if ( debug->debugmalformed )
                                        {
                                            Sagan_Log(S_WARN, "Sagan received a malformed 'program'");
                                        }
                                }

                            syslog_msg=strtok_r(NULL, "", &tok);		/* In case the message has | in it,  we delimit on "" */
                            if ( syslog_msg == NULL )
                                {
                                    syslog_msg = "SAGAN: MESSAGE ERROR";

                                    pthread_mutex_lock(&SaganMalformedCounter);
                                    counters->malformed_message++;
                                    pthread_mutex_unlock(&SaganMalformedCounter);

                                    if ( debug->debugmalformed )
                                        {
                                            Sagan_Log(S_WARN, "Sagan received a malformed 'message' [Syslog Host: %s]", syslog_host);
                                        }

                                    /* If the message is lost,  all is lost.  Typically,  you don't lose part of the message,
                                     * it's more likely to lose all  - Champ Clark III 11/17/2011 */

                                    counters->sagan_log_drop++;

                                }


                            /* Strip any \n or \r from the syslog_msg */

                            if ( strcspn ( syslog_msg, "\n" ) < strlen(syslog_msg) )
                                syslog_msg[strcspn ( syslog_msg, "\n" )] = '\0';

                            if ( proc_msgslot < config->max_processor_threads )
                                {

                                    pthread_mutex_lock(&SaganProcWorkMutex);

                                    strlcpy(SaganProcSyslog[proc_msgslot].syslog_host, syslog_host, sizeof(SaganProcSyslog[proc_msgslot].syslog_host));
                                    strlcpy(SaganProcSyslog[proc_msgslot].syslog_facility, syslog_facility, sizeof(SaganProcSyslog[proc_msgslot].syslog_facility));
                                    strlcpy(SaganProcSyslog[proc_msgslot].syslog_priority, syslog_priority, sizeof(SaganProcSyslog[proc_msgslot].syslog_priority));
                                    strlcpy(SaganProcSyslog[proc_msgslot].syslog_level, syslog_level, sizeof(SaganProcSyslog[proc_msgslot].syslog_level));
                                    strlcpy(SaganProcSyslog[proc_msgslot].syslog_tag, syslog_tag, sizeof(SaganProcSyslog[proc_msgslot].syslog_tag));
                                    strlcpy(SaganProcSyslog[proc_msgslot].syslog_date, syslog_date, sizeof(SaganProcSyslog[proc_msgslot].syslog_date));
                                    strlcpy(SaganProcSyslog[proc_msgslot].syslog_time, syslog_time, sizeof(SaganProcSyslog[proc_msgslot].syslog_time));
                                    strlcpy(SaganProcSyslog[proc_msgslot].syslog_program, syslog_program, sizeof(SaganProcSyslog[proc_msgslot].syslog_program));
                                    strlcpy(SaganProcSyslog[proc_msgslot].syslog_message, syslog_msg, sizeof(SaganProcSyslog[proc_msgslot].syslog_message));

                                    proc_msgslot++;

                                    pthread_cond_signal(&SaganProcDoWork);
                                    pthread_mutex_unlock(&SaganProcWorkMutex);
                                }
                            else
                                {
                                    counters->worker_thread_exhaustion++;
                                    counters->sagan_log_drop++;
                                }

                            if (debug->debugthreads) Sagan_Log(S_DEBUG, "Current \"proc_msgslot\": %d", proc_msgslot);

                            if (debug->debugsyslog)
                                {

                                    Sagan_Log(S_DEBUG, "[%s, line %d] **[RAW Syslog]*********************************", __FILE__, __LINE__);
                                    Sagan_Log(S_DEBUG, "[%s, line %d] Host: %s | Program: %s | Facility: %s | Priority: %s | Level: %s | Tag: %s", __FILE__, __LINE__, syslog_host, syslog_program, syslog_facility, syslog_priority, syslog_level, syslog_tag);
                                    Sagan_Log(S_DEBUG, "[%s, line %d] Raw message: %s", __FILE__, __LINE__, syslog_msg);

                                }


                        } /* while(fgets) */

                    /* fgets() has returned a error,  likely due to the FIFO writer leaving */

                    /* DEBUG : set a kill flag and join */
                    /* RMEOVE LOCK */

                    if ( fifoerr == 0 )
                        {
                            if ( config->sagan_fifo_flag != 0 )
                                {
                                    Sagan_Log(S_NORMAL, "EOF reached. Waiting for threads to catch up");
                                    sleep(5);
                                    fclose(fd);
                                    Sagan_Log(S_NORMAL, "Exiting.");		/* DEBUG: Rejoin threads */
                                    exit(0);
                                }
                            else
                                {
                                    Sagan_Log(S_WARN, "FIFO writer closed.  Waiting for FIFO writer to restart....");
                                    fifoerr=1; 			/* Set flag so our wile(fgets) knows */
                                }
                        }
                    sleep(1);		/* So we don't eat 100% CPU */

                } /* while(fd != NULL)  */

            fclose(fd); 			/* ???? */

        } /* End of while(1) */

} /* End of main */
bool AtlasResourceCompiler::Compile()
{
	Platform* platform = Platform::Get();

	// Load configuration if we haven't already.
	if (m_config_file == NULL)
	{
		if (!Load_Config())
		{
			return false;
		}
	}

	// Compile time.
	DBG_LOG("Compiling atlas resource '%s'.", m_input_path.c_str());

	// Create new atlas, and start adding rectangles.
	Atlas* atlas = new Atlas(m_config_file);
	atlas->Lock_Textures();

	// Add each of the source-images.
	std::vector<ConfigFileNode> images = m_config_file->Get<std::vector<ConfigFileNode>>("images/image");
	for (std::vector<ConfigFileNode>::iterator iter = images.begin(); iter != images.end(); iter++)
	{
		ConfigFileNode node = *iter;		

		const char* type = m_config_file->Get<const char*>("type", node, true);
		const char* file = m_config_file->Get<const char*>("file", node, true);

		Point origin = Point(0, 0);

		if (m_config_file->Contains("origin", node, true))
		{
			origin = m_config_file->Get<Point>("origin", node, true);
		}

		if (stricmp(type, "single") == 0)
		{
			const char* name = m_config_file->Get<const char*>("name", node, true);

			Texture* texture = TextureFactory::Load_Without_Handle(file, TextureFlags::None);
			DBG_ASSERT_STR(texture != NULL, "Could not load dependent texture '%s'.", file);
			
			atlas->Add_Frame(name, texture, Rect(0, 0, texture->Get_Width(), texture->Get_Height()), origin);
		}		
		else if (stricmp(type, "multiple") == 0)
		{
			const char* name = m_config_file->Get<const char*>("name", node, true);

			// Grab all the file paths.
			std::string name_str = name;
			std::vector<std::string> files;
			Expand_Multiple_Path(file, files);

			// Grab hash mark.
			int hash_mark = name_str.find('#');
			DBG_ASSERT_STR(hash_mark != std::string::npos, "Image marked as type 'multiple' does not contain replacement hash mark.");
			std::string split_left  = name_str.substr(0, hash_mark);
			std::string split_right = name_str.substr(hash_mark + 1);

			// Add each file.
			int counter = 0;
			for (std::vector<std::string>::iterator subiter = files.begin(); subiter != files.end(); subiter++)
			{
				std::string sub_path = *subiter;
				std::string sub_name = split_left + StringHelper::To_String(counter++) + split_right;
				
				Texture* texture = TextureFactory::Load_Without_Handle(sub_path.c_str(), TextureFlags::None);
				DBG_ASSERT_STR(texture != NULL, "Could not load dependent texture '%s'.", sub_path);

				atlas->Add_Frame(sub_name.c_str(), texture, Rect(0, 0, texture->Get_Width(), texture->Get_Height()), origin);
			}
		}
		else if (stricmp(type, "grid") == 0)
		{
			const char* name = m_config_file->Get<const char*>("name", node, true);

			Texture* texture = TextureFactory::Load_Without_Handle(file, TextureFlags::None);
			DBG_ASSERT_STR(texture != NULL, "Could not load dependent texture '%s'.", file);
		
			// Grab hash mark.
			std::string name_str = name;
			int hash_mark = name_str.find('#');
			DBG_ASSERT_STR(hash_mark != std::string::npos, "Image marked as type 'grid' does not contain replacement hash mark.");
			std::string split_left  = name_str.substr(0, hash_mark);
			std::string split_right = name_str.substr(hash_mark + 1);

			// Iterate over each sub-image.			
			int   frame_width		= m_config_file->Get<int>("width", node, true);
			int   frame_height		= m_config_file->Get<int>("height", node, true);
			int   frame_hspace		= m_config_file->Get<int>("hspace", node, true);
			int   frame_vspace		= m_config_file->Get<int>("vspace", node, true);			
			float texture_width		= (float)texture->Get_Width();
			float texture_height	= (float)texture->Get_Height();
			int	  cell_count_u		= texture_width  / (frame_width + frame_hspace);
			int	  cell_count_v		= texture_height / (frame_height + frame_vspace);
			int	  cell_count		= cell_count_u * cell_count_v;

			for (int i = 0; i < cell_count; i++)
			{
				int u = i % cell_count_u;
				int v = i / cell_count_u;

				int u_offset = floor(u * (frame_width + frame_hspace));
				int v_offset = floor(v * (frame_height + frame_vspace));
				
				std::string sub_name = split_left + StringHelper::To_String(i) + split_right;
				atlas->Add_Frame(sub_name.c_str(), texture, Rect(u_offset, v_offset, frame_width, frame_height), origin);
			}
		}
		else if (stricmp(type, "atlas") == 0)
		{
			Texture* texture = TextureFactory::Load_Without_Handle(file, TextureFlags::None);
			DBG_ASSERT_STR(texture != NULL, "Could not load dependent texture '%s'.", file);

			// Calculate frame positions for atlas.
			int frame_width			= m_config_file->Get<int>("width", node, true);
			int frame_height		= m_config_file->Get<int>("height", node, true);
			int frame_hspace		= m_config_file->Get<int>("hspace", node, true);
			int frame_vspace		= m_config_file->Get<int>("vspace", node, true);	
			float texture_width		= (float)texture->Get_Width();
			float texture_height	= (float)texture->Get_Height();
			int	  cell_count_u		= texture_width  / (frame_width + frame_hspace);
			int	  cell_count_v		= texture_height / (frame_height + frame_vspace);
			int	  cell_count		= cell_count_u * cell_count_v;

			// Iterate over each sub-image.	
			std::vector<ConfigFileNode> sub_images = m_config_file->Get<std::vector<ConfigFileNode>>("subimage", node);
			for (std::vector<ConfigFileNode>::iterator subiter = sub_images.begin(); subiter != sub_images.end(); subiter++)
			{
				ConfigFileNode sub_node = *subiter;	
				
				const char* sub_type = m_config_file->Get<const char*>("type", sub_node, true);
				const char* sub_name = m_config_file->Get<const char*>("name", sub_node, true);
				
				if (stricmp(sub_type, "single") == 0)
				{
					int frame		= m_config_file->Get<int>("frame", sub_node, true);
					int u			= frame % cell_count_u;
					int v			= frame / cell_count_u;
					int u_offset	= floor(u * (frame_width + frame_hspace));
					int v_offset	= floor(v * (frame_height + frame_vspace));
						
					atlas->Add_Frame(sub_name, texture, Rect(u_offset, v_offset, frame_width, frame_height), origin);
				}
				else if (stricmp(sub_type, "strip") == 0)
				{
					int to_frame   = m_config_file->Get<int>("to_frame", sub_node, true);
					int from_frame = m_config_file->Get<int>("from_frame", sub_node, true);
					DBG_ASSERT_STR(to_frame >= from_frame, "Invalid strip range %i to %i.", from_frame, to_frame);
					
					std::string sub_name_str	= sub_name;
					int			hash_mark		= sub_name_str.find('#');
					DBG_ASSERT_STR(hash_mark != std::string::npos, "Sub-image marked as type 'strip' does not contain replacement hash mark.");

					std::string split_left  = sub_name_str.substr(0, hash_mark);
					std::string split_right = sub_name_str.substr(hash_mark + 1);

					for(int frame = from_frame; frame <= to_frame; frame++)
					{
						int u			= frame % cell_count_u;
						int v			= frame / cell_count_u;
						int u_offset	= floor(u * (frame_width + frame_hspace));
						int v_offset	= floor(v * (frame_height + frame_vspace));
						
						std::string sub_sub_name = split_left + StringHelper::To_String(frame) + split_right;
						atlas->Add_Frame(sub_sub_name.c_str(), texture, Rect(u_offset, v_offset, frame_width, frame_height), origin);
					}
				}
				else
				{
					DBG_ASSERT_STR(false, "Unknown or invalid sub-image type '%s'", sub_type);
				}
			}
		}
		else
		{
			DBG_ASSERT_STR(false, "Unknown or invalid source-image type '%s'", type);
		}
	}

	// Add each of the animations.
	std::vector<ConfigFileNode> animations = m_config_file->Get<std::vector<ConfigFileNode>>("animations/animation");
	for (std::vector<ConfigFileNode>::iterator iter = animations.begin(); iter != animations.end(); iter++)
	{
		ConfigFileNode node = *iter;		
		
		const char* name = m_config_file->Get<const char*>("name", node, true);
		const char* mode = m_config_file->Get<const char*>("mode", node, true);
		float	   speed = m_config_file->Get<float>("speed", node, true);
		std::vector<AtlasFrame*> out_frames;
		
		// Decode the animation mode.
		AtlasAnimationMode::Type anim_mode;
		if (stricmp(mode, "once") == 0)
		{
			anim_mode = AtlasAnimationMode::Once;
		}
		else if (stricmp(mode, "loop") == 0)
		{
			anim_mode = AtlasAnimationMode::Loop;
		}
		else
		{
			DBG_ASSERT_STR(false, "Unknown or invalid animation mode '%s'", mode);
		}
		
		// Work out the names of each of the frames.
		std::vector<ConfigFileNode> frames = m_config_file->Get<std::vector<ConfigFileNode>>("frame", node);
		for (std::vector<ConfigFileNode>::iterator frameiter = frames.begin(); frameiter != frames.end(); frameiter++)
		{
			ConfigFileNode frame_node = *frameiter;			
			const char*	   frame_type = m_config_file->Get<const char*>("type", frame_node, true);
			const char*	   frame_name = m_config_file->Get<const char*>("name", frame_node, true);

			if (stricmp(frame_type, "single") == 0)
			{
				AtlasFrame* frame = atlas->Get_Frame(frame_name);
				DBG_ASSERT(frame != NULL, "Invalid frame name '%s' in animation '%s'.", frame_name, name);
				out_frames.push_back(frame);
			}
			else if (stricmp(frame_type, "multiple") == 0)
			{
				LinkedList<AtlasFrame*>& frames = atlas->Get_Frames_List();
				
				std::string name_str = frame_name;

				int hash_mark = name_str.find('#');
				DBG_ASSERT_STR(hash_mark != std::string::npos, "Animation marked as type 'multiple' does not contain replacement hash mark.");

				std::string split_left  = name_str.substr(0, hash_mark);
				std::string split_right = name_str.substr(hash_mark + 1);
				
				for (LinkedList<AtlasFrame*>::Iterator animiter = frames.Begin(); animiter != frames.End(); animiter++)
				{
					AtlasFrame* anim = *animiter;

					if (anim->Name.size() > split_left.size() + split_right.size())
					{
						if (anim->Name.substr(0, split_left.size()) == split_left &&
							anim->Name.substr((anim->Name.size() - split_right.size()), split_right.size()) == split_right)
						{
							AtlasFrame* frame = atlas->Get_Frame(anim->Name.c_str());
							DBG_ASSERT(frame != NULL, "Invalid frame name '%s' in animation '%s'.", anim->Name, name);
							out_frames.push_back(frame);
						}
					}
				}
			}
			else
			{
				DBG_ASSERT_STR(false, "Unknown or invalid frame type '%s'", frame_type);
			}
		}

		// Add the animation.
		atlas->Add_Animation(name, speed, anim_mode, out_frames);
	}

	// Save compiled file.
	atlas->Unlock_Textures();

	// Configuration settings.
	ConfigFile config;
	
	// Store configuration settings.
	config.Set<const char*>("settings/texture-size",		m_config_file->Get<const char*>("settings/texture-size"));
	config.Set<const char*>("settings/max-textures",		m_config_file->Get<const char*>("settings/max-textures"));

	// Save pngs.
	int texture_count = 0;
	AtlasTexture** textures = atlas->Get_Textures(texture_count);

	for (int i = 0; i < texture_count; i++)
	{
		AtlasTexture* texture = textures[i];		

		std::string output_path = (m_output_path + "." + StringHelper::To_String(i) + ".png");

		// Save texture file.
		TextureFactory::Save(output_path.c_str(), texture->Texture, TextureFlags::None);

		// Store texture spec in xml.
		ConfigFileNode node = config.New_Node("textures/texture");
		config.Set(NULL, output_path.c_str(), node, false);
	}

	// Save frame configuration.
	config.New_Node("frames");
	HashTable<AtlasFrame*, unsigned int>& frames = atlas->Get_Frames();
	for (HashTable<AtlasFrame*, unsigned int>::Iterator iter = frames.Begin(); iter != frames.End(); iter++)
	{
		AtlasFrame* frame = iter.Get_Value();
		
		// Store character spec in xml.
		ConfigFileNode node = config.New_Node("frames/frame");
		config.Set("name",			frame->Name.c_str(),				node, true);
		config.Set("namehash",		frame->NameHash,					node, true);
		config.Set("texture",		frame->TextureIndex,				node, true);
		config.Set("rectangle",		frame->Rectangle,					node, true);
		config.Set("uv",			frame->UV,							node, true);
		config.Set("origin",		frame->Origin,						node, true);
	}

	// Save animation configuration.
	config.New_Node("animations");
	HashTable<AtlasAnimation*, unsigned int>& anims = atlas->Get_Animations();
	for (HashTable<AtlasAnimation*, unsigned int>::Iterator iter = anims.Begin(); iter != anims.End(); iter++)
	{
		AtlasAnimation* frame = iter.Get_Value();
		
		// Store character spec in xml.
		ConfigFileNode node = config.New_Node("animations/animation");
		config.Set("name",			frame->Name.c_str(),				node, true);
		config.Set("namehash",		frame->NameHash,					node, true);
		switch (frame->Mode)
		{
			case AtlasAnimationMode::Loop: config.Set("mode", "loop", node, true); break;
			case AtlasAnimationMode::Once: config.Set("mode", "once", node, true); break;
			default: DBG_ASSERT_STR(false, "Invalid animation mode.");
		}
		config.Set("speed",			frame->Speed,						node, true);

		for (std::vector<AtlasFrame*>::iterator iter = frame->Frames.begin(); iter != frame->Frames.end(); iter++)
		{
			AtlasFrame* frame = (*iter);
			ConfigFileNode subnode = config.New_Node("frame", node);

			config.Set("name", frame->Name.c_str(), subnode, true);
			config.Set("namehash", frame->NameHash, subnode, true);
		}
	}

	// Save font xml configuration.
	config.Save(m_output_path.c_str());

	// Update timestamps.
	Update_File_Timestamp(m_input_path);

	// Update timestamps on dependent files.
	for (std::vector<std::string>::iterator iter = m_dependent_files.begin(); iter != m_dependent_files.end(); iter++)
	{
		std::string path = (*iter);
		DBG_ASSERT_STR(Platform::Get()->Is_File(path.c_str()), "Could not find dependent file '%s'.", path.c_str());

		Update_File_Timestamp(path.c_str());
	}

	DBG_LOG("Finished compiling to '%s'.", m_output_path.c_str());

	return true;
}
Esempio n. 5
0
void Sig_Handler( _SaganSigArgs *args )
{

    sigset_t signal_set;
    int sig;
    sbool orig_perfmon_value = 0;

#ifdef HAVE_LIBPCAP
    sbool orig_plog_value = 0;
#endif

    for(;;)
        {
            /* wait for any and all signals */
            sigfillset( &signal_set );
            sigwait( &signal_set, &sig );


            switch( sig )
                {
                    /* exit */
                case SIGQUIT:
                case SIGINT:
                case SIGTERM:
                case SIGSEGV:
                case SIGABRT:

                    Sagan_Log(S_NORMAL, "\n\n[Received signal %d. Sagan version %s shutting down]-------\n", sig, VERSION);
                    Sagan_Statistics();

#if defined(HAVE_DNET_H) || defined(HAVE_DUMBNET_H)
                    if ( sagan_unified2_flag )
                        {
                            Unified2CleanExit();
                        }
#endif

#ifdef HAVE_LIBMAXMINDDB

                    MMDB_close(&config->geoip2);

#endif

                    fflush(config->sagan_alert_stream);
                    fclose(config->sagan_alert_stream);             /* Close Sagan alert file */

                    fflush(config->sagan_log_stream);               /* Close the sagan.log */
                    fclose(config->sagan_log_stream);

                    if ( config->perfmonitor_flag )
                        {
                            Sagan_Perfmonitor_Close();
                        }

                    Remove_Lock_File();
                    exit(0);
                    break;

                case SIGHUP:

                    config->sagan_reload = 1;				/* Only this thread can alter this */

                    pthread_mutex_lock(&SaganReloadMutex);

                    Sagan_Log(S_NORMAL, "[Reloading Sagan version %s.]-------", VERSION);

                    /*
                    * Close and re-open log files.  This is for logrotate and such
                    * 04/14/2015 - Champ Clark III ([email protected])
                    */

                    Sagan_Open_Log_File(REOPEN, ALL_LOGS);

                    /******************/
                    /* Reset counters */
                    /******************/

                    counters->refcount=0;
                    counters->classcount=0;
                    counters->rulecount=0;
                    counters->ruletotal=0;
                    counters->genmapcount=0;
                    counters->flowbit_track_count=0;

                    memset(rulestruct, 0, sizeof(_Rule_Struct));
                    memset(classstruct, 0, sizeof(_Class_Struct));
                    memset(generator, 0, sizeof(_Sagan_Processor_Generator));
                    memset(flowbit, 0, sizeof(_Sagan_Flowbit));


                    /**********************************/
                    /* Disabled and reset processors. */
                    /**********************************/

                    /* Note: Processors that run as there own thread (perfmon, plog) cannot be
                     * loaded via SIGHUP.  They must be loaded at run time.  Once they are loaded,
                     * they can be disabled/re-enabled. */

                    /* Single Threaded processors */

                    if ( config->perfmonitor_flag == 1 && orig_perfmon_value == 0 )
                        {
                            Sagan_Perfmonitor_Close();
                            orig_perfmon_value = 1;
                        }

                    config->perfmonitor_flag = 0;

#ifdef HAVE_LIBPCAP

                    if ( config->plog_flag )
                        {
                            orig_plog_value = 1;
                        }

                    config->plog_flag = 0;
#endif

                    /* Multi Threaded processors */

                    config->blacklist_flag = 0;

                    if ( config->blacklist_flag )
                        {
                            free(SaganBlacklist);
                        }

                    config->blacklist_flag = 0;

                    if ( config->brointel_flag )
                        {
                            free(Sagan_BroIntel_Intel_Addr);
                            free(Sagan_BroIntel_Intel_Domain);
                            free(Sagan_BroIntel_Intel_File_Hash);
                            free(Sagan_BroIntel_Intel_URL);
                            free(Sagan_BroIntel_Intel_Software);
                            free(Sagan_BroIntel_Intel_Email);
                            free(Sagan_BroIntel_Intel_User_Name);
                            free(Sagan_BroIntel_Intel_File_Name);
                            free(Sagan_BroIntel_Intel_Cert_Hash);

                            counters->brointel_addr_count = 0;
                            counters->brointel_domain_count = 0;
                            counters->brointel_file_hash_count = 0;
                            counters->brointel_url_count = 0;
                            counters->brointel_software_count = 0;
                            counters->brointel_email_count = 0;
                            counters->brointel_user_name_count = 0;
                            counters->brointel_file_name_count = 0;
                            counters->brointel_cert_hash_count = 0;
                            counters->brointel_dups = 0;
                        }

                    config->brointel_flag = 0;

                    if ( config->sagan_track_clients_flag )
                        {
                            free(SaganTrackClients);
                            fclose(config->sagan_track_client_file);
                        }

                    config->sagan_track_clients_flag = 0;
                    counters->track_clients_client_count = 0;
                    counters->track_clients_down = 0;

                    /* Output formats */

                    config->sagan_ext_flag = 0;

#ifdef WITH_SYSLOG
                    config->sagan_syslog_flag = 0;
#endif


#ifdef HAVE_LIBESMTP
                    config->sagan_esmtp_flag = 0;
#endif

#ifdef WITH_SNORTSAM
                    config->sagan_fwsam_flag = 0;
#endif

                    /* Non-output / Processors */

                    if ( config->sagan_droplist_flag )
                        {
                            config->sagan_droplist_flag = 0;
                            free(SaganIgnorelist);
                        }

                    /************************************************************/
                    /* Re-load primary configuration (rules/classifictions/etc) */
                    /************************************************************/

                    Load_Config();	/* <- RELOAD */

                    /************************************************************/
                    /* Re-load primary configuration (rules/classifictions/etc) */
                    /************************************************************/

                    if ( config->perfmonitor_flag == 1 )
                        {
                            if ( orig_perfmon_value == 1 )
                                {
                                    Sagan_Perfmonitor_Open();
                                }
                            else
                                {
                                    Sagan_Log(S_WARN, "** 'perfmonitor' must be loaded at runtime! NOT loading 'perfmonitor'!");
                                    config->perfmonitor_flag = 0;
                                }
                        }


#ifdef HAVE_LIBPCAP

                    if ( config->plog_flag == 1 )
                        {
                            if ( orig_plog_value == 1 )
                                {
                                    config->plog_flag = 1;
                                }
                            else
                                {
                                    Sagan_Log(S_WARN, "** 'plog' must be loaded at runtime! NOT loading 'plog'!");
                                    config->plog_flag = 0;
                                }
                        }
#endif

                    /* Load Blacklist data */

                    if ( config->blacklist_flag )
                        {
                            counters->blacklist_count=0;
                            Sagan_Blacklist_Init();
                            Sagan_Blacklist_Load();
                        }

                    if ( config->brointel_flag )
                        {
                            Sagan_BroIntel_Init();
                            Sagan_BroIntel_Load_File();
                        }

                    if ( config->sagan_track_clients_flag )
                        {
                            Sagan_Load_Tracking_Cache();
                            Sagan_Log(S_NORMAL, "Reset Sagan Track Client.");
                        }


                    /* Non output / processors */

                    if ( config->sagan_droplist_flag )
                        {
                            Load_Ignore_List();
                            Sagan_Log(S_NORMAL, "Loaded %d ignore/drop list item(s).", counters->droplist_count);
                        }

#ifdef HAVE_LIBMAXMINDDB
                    Sagan_Log(S_NORMAL, "Reloading GeoIP2 data.");
                    Sagan_Open_GeoIP2_Database();
#endif

#ifdef HAVE_LIBLOGNORM
                    Sagan_Liblognorm_Load();
#endif


                    pthread_cond_signal(&SaganReloadCond);
                    pthread_mutex_unlock(&SaganReloadMutex);

                    config->sagan_reload = 0;

                    Sagan_Log(S_NORMAL, "Configuration reloaded.");
                    break;

                    /* Signals to ignore */
                case 17:		/* Child process has exited. */
                case 28:		/* Terminal 'resize'/alarm. */
                    break;

                case SIGUSR1:
                    Sagan_Statistics();
                    break;

                default:
                    Sagan_Log(S_NORMAL, "[Received signal %d. Sagan doesn't know how to deal with]", sig);
                }
        }
}