示例#1
0
/** void LogCollectorStart() v0.4
 * Handle file management.
 */
void LogCollectorStart()
{
    int i = 0, r = 0;
    int max_file = 0;
    int f_check = 0;
    time_t curr_time = 0;
    char keepalive[1024];



    /* To check for inode changes */
    struct stat tmp_stat;


    #ifndef WIN32

    int int_error = 0;
    struct timeval fp_timeout;

    #else

    /* Checking if we are on vista. */
    checkVista();


    /* Reading vista descriptions. */
    if(isVista)
    {
        win_read_vista_sec();
    }

    #endif

    debug1("%s: DEBUG: Entering LogCollectorStart().", ARGV0);


    /* Initializing each file and structure */
    for(i = 0;;i++)
    {
        if(logff[i].file == NULL)
            break;


        /* Removing duplicate entries. */
        for(r = 0; r < i; r++)
        {
            if(logff[r].file && strcmp(logff[i].file, logff[r].file) == 0)
            {
                merror("%s: WARN: Duplicated log file given: '%s'.",
                       ARGV0, logff[i].file);
                logff[i].file = NULL;
                logff[i].command = NULL;
                logff[i].fp = NULL;

                break;
            }
        }

        if(logff[i].file == NULL)
        {
            /* do nothing, duplicated entry. */
        }

        else if(strcmp(logff[i].logformat,"eventlog") == 0)
        {
            #ifdef WIN32

            verbose(READING_EVTLOG, ARGV0, logff[i].file);
            win_startel(logff[i].file);

            #endif
            logff[i].file = NULL;
            logff[i].command = NULL;
            logff[i].fp = NULL;
        }

        else if(strcmp(logff[i].logformat, "eventchannel") == 0)
        {
			#ifdef WIN32

			#ifdef EVENTCHANNEL_SUPPORT
			verbose(READING_EVTLOG, ARGV0, logff[i].file);
			win_start_event_channel(logff[i].file, logff[i].future, logff[i].query);
			#else
			merror("%s: WARN: eventchannel not available on this version of OSSEC", ARGV0);
			#endif

			#endif

			logff[i].file = NULL;
			logff[i].command = NULL;
            logff[i].fp = NULL;
        }

        else if(strcmp(logff[i].logformat, "command") == 0)
        {
            logff[i].file = NULL;
            logff[i].fp = NULL;
            logff[i].size = 0;

            if(logff[i].command)
            {
                logff[i].read = read_command;

                verbose("%s: INFO: Monitoring output of command(%d): %s", ARGV0, logff[i].ign, logff[i].command);

                if(!logff[i].alias)
                {
                    os_strdup(logff[i].command, logff[i].alias);
                }
            }
            else
            {
                merror("%s: ERROR: Missing command argument. Ignoring it.",
                       ARGV0);
            }
        }
        else if(strcmp(logff[i].logformat, "full_command") == 0)
        {
            logff[i].file = NULL;
            logff[i].fp = NULL;
            logff[i].size = 0;
            if(logff[i].command)
            {
                logff[i].read = read_fullcommand;

                verbose("%s: INFO: Monitoring full output of command(%d): %s", ARGV0, logff[i].ign, logff[i].command);

                if(!logff[i].alias)
                    os_strdup(logff[i].command, logff[i].alias);
            }
            else
            {
                merror("%s: ERROR: Missing command argument. Ignoring it.",
                       ARGV0);
            }
        }

        else
        {
            logff[i].command = NULL;


            /* Initializing the files */
            if(logff[i].ffile)
            {
                /* Day must be zero for all files to be initialized */
                _cday = 0;
                if(update_fname(i))
                {
                    handle_file(i, 1, 1);
                }
                else
                {
                    ErrorExit(PARSE_ERROR, ARGV0, logff[i].ffile);
                }

            }
            else
            {
                handle_file(i, 1, 1);
            }

            verbose(READING_FILE, ARGV0, logff[i].file);

            /* Getting the log type */
            if(strcmp("snort-full", logff[i].logformat) == 0)
            {
                logff[i].read = read_snortfull;
            }
            #ifndef WIN32
            if(strcmp("ossecalert", logff[i].logformat) == 0)
            {
                logff[i].read = read_ossecalert;
            }
            #endif
            else if(strcmp("nmapg", logff[i].logformat) == 0)
            {
                logff[i].read = read_nmapg;
            }
            else if(strcmp("mysql_log", logff[i].logformat) == 0)
            {
                logff[i].read = read_mysql_log;
            }
            else if(strcmp("mssql_log", logff[i].logformat) == 0)
            {
                logff[i].read = read_mssql_log;
            }
            else if(strcmp("postgresql_log", logff[i].logformat) == 0)
            {
                logff[i].read = read_postgresql_log;
            }
            else if(strcmp("djb-multilog", logff[i].logformat) == 0)
            {
                if(!init_djbmultilog(i))
                {
                    merror(INV_MULTILOG, ARGV0, logff[i].file);
                    if(logff[i].fp)
                    {
                        fclose(logff[i].fp);
                        logff[i].fp = NULL;
                    }
                    logff[i].file = NULL;
                }
                logff[i].read = read_djbmultilog;
            }
            else if(logff[i].logformat[0] >= '0' && logff[i].logformat[0] <= '9')
            {
                logff[i].read = read_multiline;
            }
            else
            {
                logff[i].read = read_syslog;
            }

            /* More tweaks for Windows. For some reason IIS places
             * some wierd characters at the end of the files and getc
             * always returns 0 (even after clearerr).
             */
            #ifdef WIN32
            if(logff[i].fp)
            {
                logff[i].read(i, &r, 1);
            }
            #endif
        }

        if(logff[i].alias)
        {
            int ii = 0;
            while(logff[i].alias[ii] != '\0')
            {
                if(logff[i].alias[ii] == ':')
                {
                    logff[i].alias[ii] = '\\';
                }
                ii++;
            }
        }
    }


    /* Start up message */
    verbose(STARTUP_MSG, ARGV0, (int)getpid());

    max_file = i -1;


    /* Cannot be zero */
    if(max_file < 0)
    {
        max_file = 0;
    }


    /* Daemon loop */
    while(1)
    {
        #ifndef WIN32
        fp_timeout.tv_sec = loop_timeout;
        fp_timeout.tv_usec = 0;

        /* Waiting for the select timeout */
        if ((r = select(0, NULL, NULL, NULL, &fp_timeout)) < 0)
        {
            merror(SELECT_ERROR, ARGV0, errno, strerror(errno));
            int_error++;

            if(int_error >= 5)
            {
                ErrorExit(SYSTEM_ERROR, ARGV0);
            }
            continue;
        }
        #else

        /* Windows don't like select that way */
        sleep(loop_timeout + 2);


        /* Check for messages in the event viewer */
        win_readel();
        #endif

        f_check++;


        /* Checking which file is available */
        for(i = 0; i <= max_file; i++)
        {
            if(!logff[i].fp)
            {
                /* Run the command. */
                if(logff[i].command && (f_check %2))
                {
                    curr_time = time(0);
                    if((curr_time - logff[i].size) >= logff[i].ign)
                    {
                        logff[i].size = curr_time;
                        logff[i].read(i, &r, 0);
                    }
                }
                continue;
            }

            /* Windows with IIS logs is very strange.
             * For some reason it always returns 0 (not EOF)
             * the fgetc. To solve this problem, we always
             * pass it to the function pointer directly.
             */
            #ifndef WIN32
            /* We check for the end of file. If is returns EOF,
             * we don't attempt to read it.
             */
            if((r = fgetc(logff[i].fp)) == EOF)
            {
                clearerr(logff[i].fp);
                continue;
            }


            /* If it is not EOF, we need to return the read character */
            ungetc(r, logff[i].fp);
            #endif


            /* Finally, send to the function pointer to read it */
            logff[i].read(i, &r, 0);


            /* Checking for error */
            if(!ferror(logff[i].fp))
            {
                /* Clearing EOF */
                clearerr(logff[i].fp);

                /* Parsing error */
                if(r != 0)
                {
                    logff[i].ign++;
                }
            }
            /* If ferror is set */
            else
            {
                merror(FREAD_ERROR, ARGV0, logff[i].file, errno, strerror(errno));
                #ifndef WIN32
                if(fseek(logff[i].fp, 0, SEEK_END) < 0)
                #else
                if(1)
                #endif
                {

                    #ifndef WIN32
                    merror(FSEEK_ERROR, ARGV0, logff[i].file, errno, strerror(errno));
                    #endif

                    /* Closing the file */
                    if(logff[i].fp)
                    {
                        fclose(logff[i].fp);
                        #ifdef WIN32
                        CloseHandle(logff[i].h);
                        #endif
                    }
                    logff[i].fp = NULL;


                    /* Trying to open it again */
                    if(handle_file(i, 1, 1) != 0)
                    {
                        logff[i].ign++;
                        continue;
                    }

                    #ifdef WIN32
                    logff[i].read(i, &r, 1);
                    #endif
                }

                /* Increase the error count  */
                logff[i].ign++;
                clearerr(logff[i].fp);
            }
        }


        /* Only check bellow if check > VCHECK_FILES */
        if(f_check <= VCHECK_FILES)
            continue;


        /* Send keep alive message */

        rand_keepalive_str(keepalive, 700);
        SendMSG(logr_queue, keepalive, "ossec-keepalive", LOCALFILE_MQ);


        /* Zeroing f_check */
        f_check = 0;


        /* Checking if any file has been renamed/removed */
        for(i = 0; i <= max_file; i++)
        {
            /* These are the windows logs or ignored files */
            if(!logff[i].file)
                continue;


            /* Files with date -- check for day change */
            if(logff[i].ffile)
            {
                if(update_fname(i))
                {
                    if(logff[i].fp)
                    {
                        fclose(logff[i].fp);
                        #ifdef WIN32
                        CloseHandle(logff[i].h);
                        #endif
                    }
                    logff[i].fp = NULL;
                    handle_file(i, 0, 1);
                    continue;
                }

                /* Variable file name */
                else if(!logff[i].fp)
                {
                    handle_file(i, 0, 0);
                    continue;
                }
            }


            /* Check for file change -- if the file is open already */
            if(logff[i].fp)
            {
                #ifndef WIN32
                if(fstat(fileno(logff[i].fp), &tmp_stat) == -1)
                {
                    fclose(logff[i].fp);
                    logff[i].fp = NULL;

                    merror(FSTAT_ERROR, ARGV0, logff[i].file, errno, strerror(errno));
                }

                #else
                BY_HANDLE_FILE_INFORMATION lpFileInformation;
                HANDLE h1;

                h1 = CreateFile(logff[i].file, GENERIC_READ,
                            FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE,
                            NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
                if(h1 == INVALID_HANDLE_VALUE)
                {
                    fclose(logff[i].fp);
                    CloseHandle(logff[i].h);
                    logff[i].fp = NULL;
                    merror(FILE_ERROR, ARGV0, logff[i].file);
                }
                else if(GetFileInformationByHandle(h1, &lpFileInformation) == 0)
                {
                    fclose(logff[i].fp);
                    CloseHandle(logff[i].h);
                    CloseHandle(h1);
                    logff[i].fp = NULL;
                    merror(FILE_ERROR, ARGV0, logff[i].file);;
                }
                #endif


                #ifdef WIN32
                else if(logff[i].fd != (lpFileInformation.nFileIndexLow + lpFileInformation.nFileIndexHigh))
                #else
                else if(logff[i].fd != tmp_stat.st_ino)
                #endif
                {
                    char msg_alert[512 +1];

                    snprintf(msg_alert, 512, "ossec: File rotated (inode "
                                             "changed): '%s'.",
                                             logff[i].file);

                    /* Send message about log rotated  */
                    SendMSG(logr_queue, msg_alert,
                            "ossec-logcollector", LOCALFILE_MQ);

                    debug1("%s: DEBUG: File inode changed. %s",
                            ARGV0, logff[i].file);

                    fclose(logff[i].fp);

                    #ifdef WIN32
                    CloseHandle(logff[i].h);
                    CloseHandle(h1);
                    #endif

                    logff[i].fp = NULL;
                    handle_file(i, 0, 1);
                    continue;
                }
                #ifdef WIN32
                else if(logff[i].size > (lpFileInformation.nFileSizeHigh + lpFileInformation.nFileSizeLow))
                #else
                else if(logff[i].size > tmp_stat.st_size)
                #endif
                {
                    char msg_alert[512 +1];

                    snprintf(msg_alert, 512, "ossec: File size reduced "
                                             "(inode remained): '%s'.",
                                             logff[i].file);

                    /* Send message about log rotated  */
                    SendMSG(logr_queue, msg_alert,
                            "ossec-logcollector", LOCALFILE_MQ);

                    debug1("%s: DEBUG: File size reduced. %s",
                            ARGV0, logff[i].file);


                    /* Fixing size so we don't alert more than once */
                    logff[i].size = tmp_stat.st_size;


                    /* Getting new file. */
                    fclose(logff[i].fp);

                    #ifdef WIN32
                    CloseHandle(logff[i].h);
                    CloseHandle(h1);
                    #endif

                    logff[i].fp = NULL;
                    handle_file(i, 1, 1);
                }
                #ifdef WIN32
                else
                {
                    CloseHandle(h1);
                }
                #endif
            }


            /* Too many errors for the file */
            if(logff[i].ign > open_file_attempts)
            {
                /* 999 Maximum ignore */
                if(logff[i].ign == 999)
                {
                    continue;
                }

                merror(LOGC_FILE_ERROR, ARGV0, logff[i].file);
                if(logff[i].fp)
                {
                    fclose(logff[i].fp);
                    #ifdef WIN32
                    CloseHandle(logff[i].h);
                    #endif
                }

                logff[i].fp = NULL;


                /* If the file has a variable date, ignore it for
                 * today only.
                 */
                if(!logff[i].ffile)
                {
                    /* Variable log files should always be attempted
                     * to be open...
                     */
                    //logff[i].file = NULL;
                }
                logff[i].ign = 999;
                continue;
            }


            /* File not opened */
            if(!logff[i].fp)
            {
                if(logff[i].ign >= 999)
                    continue;
                else
                {
                    /* Try for a few times to open the file */
                    if(handle_file(i, 1, 1) < 0)
                    {
                        logff[i].ign++;
                    }
                    continue;
                }
            }
        }
    }
}
示例#2
0
文件: syslog.c 项目: Ar0xA/ossec-hids
/** void HandleSyslog() v0.2
 * Handle syslog connections
 */
void HandleSyslog()
{
    char buffer[OS_SIZE_1024 +2];
    char srcip[IPSIZE +1];

    char *buffer_pt = NULL;

    int recv_b;

    struct sockaddr_in peer_info;
    socklen_t peer_size;


    /* setting peer size */
    peer_size = sizeof(peer_info);


    /* Initializing some variables */
    memset(buffer, '\0', OS_SIZE_1024 +2);


    /* Connecting to the message queue
     * Exit if it fails.
     */
    if((logr.m_queue = StartMQ(DEFAULTQUEUE,WRITE)) < 0)
    {
        ErrorExit(QUEUE_FATAL,ARGV0, DEFAULTQUEUE);
    }


    /* Infinite loop in here */
    while(1)
    {
        /* Receiving message  */
        recv_b = recvfrom(logr.sock, buffer, OS_SIZE_1024, 0,
                (struct sockaddr *)&peer_info, &peer_size);

        /* Nothing received */
        if(recv_b <= 0)
            continue;


        /* null terminating the message */
        buffer[recv_b] = '\0';


        /* Removing new line */
        if(buffer[recv_b -1] == '\n')
        {
            buffer[recv_b -1] = '\0';
        }

        /* Setting the source ip */
        strncpy(srcip, inet_ntoa(peer_info.sin_addr), IPSIZE);
        srcip[IPSIZE] = '\0';


        /* Removing syslog header */
        if(buffer[0] == '<')
        {
            buffer_pt = strchr(buffer+1, '>');
            if(buffer_pt)
            {
                buffer_pt++;
            }
            else
            {
                buffer_pt = buffer;
            }
        }
        else
        {
            buffer_pt = buffer;
        }

        /* Checking if IP is allowed here */
        if(OS_IPNotAllowed(srcip))
        {
            merror(DENYIP_WARN,ARGV0,srcip);
        }

        else if(SendMSG(logr.m_queue, buffer_pt, srcip,
                        SYSLOG_MQ) < 0)
        {
            merror(QUEUE_ERROR,ARGV0,DEFAULTQUEUE, strerror(errno));
            if((logr.m_queue = StartMQ(DEFAULTQUEUE,READ)) < 0)
            {
                ErrorExit(QUEUE_FATAL,ARGV0,DEFAULTQUEUE);
            }
        }
    }
}
/* Read Output of commands */
void *read_fullcommand(int pos, int *rc, int drop_it)
{
    size_t n = 0;
    size_t cmd_size = 0;
    char *p;
    char str[OS_MAXSTR + 1];
    char strfinal[OS_MAXSTR + 1];
    FILE *cmd_output;

    str[OS_MAXSTR] = '\0';
    strfinal[OS_MAXSTR] = '\0';
    *rc = 0;

    debug2("%s: DEBUG: Running full command '%s'", ARGV0, logff[pos].command);

    cmd_output = popen(logff[pos].command, "r");
    if (!cmd_output) {
        merror("%s: ERROR: Unable to execute command: '%s'.",
               ARGV0, logff[pos].command);

        logff[pos].command = NULL;
        return (NULL);
    }

    snprintf(str, 256, "ossec: output: '%s':\n",
             (NULL != logff[pos].alias)
             ? logff[pos].alias
             : logff[pos].command);
    cmd_size = strlen(str);

    n = fread(str + cmd_size, 1, OS_MAXSTR - OS_LOG_HEADER - 256, cmd_output);
    if (n > 0) {
        str[cmd_size + n] = '\0';

        /* Get the last occurrence of \n */
        if ((p = strrchr(str, '\n')) != NULL) {
            *p = '\0';
        }

        debug2("%s: DEBUG: Reading command message: '%s'", ARGV0, str);

        /* Remove empty lines */
        n = 0;
        p = str;
        while (*p != '\0') {
            if (p[0] == '\r') {
                p++;
                continue;
            }

            if (p[0] == '\n' && p[1] == '\n') {
                p++;
            }
            strfinal[n] = *p;
            n++;
            p++;
        }
        strfinal[n] = '\0';

        /* Send message to queue */
        if (drop_it == 0) {
            if (SendMSG(logr_queue, strfinal,
                        (NULL != logff[pos].alias) ? logff[pos].alias : logff[pos].command,
                        LOCALFILE_MQ) < 0) {
                merror(QUEUE_SEND, ARGV0);
                if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) {
                    ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH);
                }
            }
        }
    }

    pclose(cmd_output);

    return (NULL);
}
示例#4
0
文件: secure.c 项目: Ar0xA/ossec-hids
/** void HandleSecure() v0.3
 * Handle the secure connections
 */
void HandleSecure()
{
    int agentid;

    char buffer[OS_MAXSTR +1];
    char cleartext_msg[OS_MAXSTR +1];
    char srcip[IPSIZE +1];
    char *tmp_msg;
    char srcmsg[OS_FLSIZE +1];


    int recv_b;

    struct sockaddr_in peer_info;
    socklen_t peer_size;


    /* Send msg init */
    send_msg_init();


    /* Initializing key mutex. */
    keyupdate_init();


    /* Initializing manager */
    manager_init(0);


    /* Creating Ar forwarder thread */
    if(CreateThread(AR_Forward, (void *)NULL) != 0)
    {
        ErrorExit(THREAD_ERROR, ARGV0);
    }

    /* Creating wait_for_msgs thread */
    if(CreateThread(wait_for_msgs, (void *)NULL) != 0)
    {
        ErrorExit(THREAD_ERROR, ARGV0);
    }


    /* Connecting to the message queue
     * Exit if it fails.
     */
    if((logr.m_queue = StartMQ(DEFAULTQUEUE,WRITE)) < 0)
    {
        ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE);
    }


    verbose(AG_AX_AGENTS, ARGV0, MAX_AGENTS);


    /* Reading authentication keys */
    verbose(ENC_READ, ARGV0);

    OS_ReadKeys(&keys);

    debug1("%s: DEBUG: OS_StartCounter.", ARGV0);
    OS_StartCounter(&keys);
    debug1("%s: DEBUG: OS_StartCounter completed.", ARGV0);


    /* setting up peer size */
    peer_size = sizeof(peer_info);
    logr.peer_size = sizeof(peer_info);


    /* Initializing some variables */
    memset(buffer, '\0', OS_MAXSTR +1);
    memset(cleartext_msg, '\0', OS_MAXSTR +1);
    memset(srcmsg, '\0', OS_FLSIZE +1);
    tmp_msg = NULL;



    /* loop in here */
    while(1)
    {
        /* Receiving message  */
        recv_b = recvfrom(logr.sock, buffer, OS_MAXSTR, 0,
                (struct sockaddr *)&peer_info, &peer_size);


        /* Nothing received */
        if(recv_b <= 0)
        {
            continue;
        }


        /* Setting the source ip */
        strncpy(srcip, inet_ntoa(peer_info.sin_addr), IPSIZE);
        srcip[IPSIZE] = '\0';



        /* Getting a valid agentid */
        if(buffer[0] == '!')
        {
            tmp_msg = buffer;
            tmp_msg++;


            /* We need to make sure that we have a valid id
             * and that we reduce the recv buffer size.
             */
            while(isdigit((int)*tmp_msg))
            {
                tmp_msg++;
                recv_b--;
            }

            if(*tmp_msg != '!')
            {
                merror(ENCFORMAT_ERROR, __local_name, srcip);
                continue;
            }

            *tmp_msg = '\0';
            tmp_msg++;
            recv_b-=2;

            agentid = OS_IsAllowedDynamicID(&keys, buffer +1, srcip);
            if(agentid == -1)
            {
                if(check_keyupdate())
                {
                    agentid = OS_IsAllowedDynamicID(&keys, buffer +1, srcip);
                    if(agentid == -1)
                    {
                        merror(ENC_IP_ERROR, ARGV0, srcip);
                        continue;
                    }
                }
                else
                {
                    merror(ENC_IP_ERROR, ARGV0, srcip);
                    continue;
                }
            }
        }
        else
        {
            agentid = OS_IsAllowedIP(&keys, srcip);
            if(agentid < 0)
            {
                if(check_keyupdate())
                {
                    agentid = OS_IsAllowedIP(&keys, srcip);
                    if(agentid == -1)
                    {
                        merror(DENYIP_WARN,ARGV0,srcip);
                        continue;
                    }
                }
                else
                {
                    merror(DENYIP_WARN,ARGV0,srcip);
                    continue;
                }
            }
            tmp_msg = buffer;
        }


        /* Decrypting the message */
        tmp_msg = ReadSecMSG(&keys, tmp_msg, cleartext_msg,
                             agentid, recv_b -1);
        if(tmp_msg == NULL)
        {
            /* If duplicated, a warning was already generated */
            continue;
        }


        /* Check if it is a control message */
        if(IsValidHeader(tmp_msg))
        {
            /* We need to save the peerinfo if it is a control msg */
            memcpy(&keys.keyentries[agentid]->peer_info, &peer_info, peer_size);
            keys.keyentries[agentid]->rcvd = time(0);

            save_controlmsg(agentid, tmp_msg);

            continue;
        }


        /* Generating srcmsg */
        snprintf(srcmsg, OS_FLSIZE,"(%s) %s",keys.keyentries[agentid]->name,
                                             keys.keyentries[agentid]->ip->ip);


        /* If we can't send the message, try to connect to the
         * socket again. If it not exit.
         */
        if(SendMSG(logr.m_queue, tmp_msg, srcmsg,
                   SECURE_MQ) < 0)
        {
            merror(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno));

            if((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0)
            {
                ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE);
            }
        }
    }
}
示例#5
0
void Monitord()
{
    time_t tm;
    struct tm *p;

    int today = 0;
    int thismonth = 0;
    int thisyear = 0;

    char str[OS_SIZE_1024 + 1];

    /* Wait a few seconds to settle */
    sleep(10);

    memset(str, '\0', OS_SIZE_1024 + 1);

    /* Get current time before starting */
    tm = time(NULL);
    p = localtime(&tm);

    today = p->tm_mday;
    thismonth = p->tm_mon;
    thisyear = p->tm_year + 1900;

    /* Connect to the message queue or exit */
    if ((mond.a_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) {
        ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE);
    }

    /* Send startup message */
    snprintf(str, OS_SIZE_1024 - 1, OS_AD_STARTED);
    if (SendMSG(mond.a_queue, str, ARGV0,
                LOCALFILE_MQ) < 0) {
        merror(QUEUE_SEND, ARGV0);
    }

    /* Main monitor loop */
    while (1) {
        tm = time(NULL);
        p = localtime(&tm);

        /* Check for unavailable agents */
        if (mond.monitor_agents) {
            monitor_agents();
        }

        /* Day changed, deal with log files */
        if (today != p->tm_mday) {
            /* Generate reports */
            generate_reports(today, thismonth, thisyear, p);
            manage_files(today, thismonth, thisyear);

            today = p->tm_mday;
            thismonth = p->tm_mon;
            thisyear = p->tm_year + 1900;
        }

        /* We only check every two minutes */
        sleep(120);
    }
}