
/******************************************************************************
**
**  This program is free software; you can redistribute it and/or
**  modify it, however, you cannot sell it.
**
**  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.
**
**  You should have received a copy of the license attached to the
**  use of this software.  If not, visit www.shmoo.com/osiris for
**  details.
**
******************************************************************************/

/*****************************************************************************
**
**  File:    md_log.c
**  Date:    June 3, 2002
**
**  Author:  Brian Wotring
**  Purpose: interact with local file system to read in log information
**           from hosts directory.
**
******************************************************************************/

#include "libosiris.h"
#include "libosirism.h"
#include "libosirisdb.h"
#include "libosirisctl.h"
#include "libfileapi.h"

#include "md_hosts.h"
#include "md_log.h"
#include "md_config.h"
#include "md_compare.h"

#include "common.h"
#include "logging.h"

extern char root_path[MAX_PATH_LENGTH];



OSI_LOG_BRIEF * osi_host_read_log_brief_with_name( const char *host,
                                                   const char *name )
{
    OSI_LOG_BRIEF *log_brief = NULL;

    char path[MAX_PATH_LENGTH];
    char path_separator[2] = { PATH_SEPARATOR, '\0' };
  
    struct stat stats;

    if( ( host == NULL ) || ( name == NULL ) )
    {
        return NULL;
    }

    /* first, we construct path to configs directory. */

    osi_strlcpy( path, root_path, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, HOSTS_DIRECTORY_NAME, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, host, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, HOST_LOG_DIRECTORY_NAME, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, name, sizeof( path ) );
  
    if( stat( path, &stats ) == 0 )
    {
        log_brief = osi_malloc( sizeof( OSI_LOG_BRIEF ) );

        osi_strlcpy( log_brief->name, name, sizeof( log_brief->name ) );
        log_brief->timestamp = stats.st_mtime; 
    } 

    return log_brief;
}



int osi_host_read_log_briefs( OSI_HOST *host )
{
    char path[MAX_PATH_LENGTH];
    char path_separator[2] = { PATH_SEPARATOR, '\0' };

    OSI_DIRECTORY directory;
    memset( &directory, 0, sizeof( OSI_DIRECTORY ) );

    if( host == NULL )
    {
        return 0;
    }

    /* first, we construct path to log file. */

    osi_strlcpy( path, root_path, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, HOSTS_DIRECTORY_NAME, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, host->name, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, HOST_LOG_DIRECTORY_NAME, sizeof( path ) );

    log_info( LOG_HIGH, host->name, "looking for logs." );

    /* now traverse the directory, creating log objects and */
    /* adding them to this host's list of configs.             */

    if( osi_open_directory( path, &directory ) )
    {
        char file_path[MAX_PATH_LENGTH];

        log_info( LOG_HIGH, host->name, "opened log directory." );

        do
        {
            /* create full path to the current filename. */

            osi_strlcpy( file_path, path, sizeof( file_path ) );
            osi_strlcat( file_path, path_separator, sizeof( file_path ) );
            osi_strlcat( file_path, directory.filename, sizeof( file_path ) );

            if( osi_file_is_regular_file( file_path ) )
            {
                OSI_LOG_BRIEF *log_brief;

                if( ( log_brief = osi_host_read_log_brief_with_name( host->name,
                                               directory.filename ) ) != NULL )
                {
                    list_add( host->logs, log_brief );
                }

                else
                {
                    log_error( LOG_MEDIUM, host->name,
                               "cannot read log file: %s. ", file_path );
                }
            }

        } while( osi_get_next_file( &directory ) );

        osi_close_directory( &directory );
    }

    else
    {
        log_error( LOG_MEDIUM, host->name, "has no log directory." );
    }

    return ( list_get_size( host->logs ) );
}


string_list * osi_host_get_log_data( const char *host,
                                     const char *name )
{
    FILE *file = NULL;
    string_list *log_data = NULL;

    char *line;
    char temp_line[MAX_LOG_FILE_LINE_LENGTH];

    char path[MAX_PATH_LENGTH];
    char path_separator[2] = { PATH_SEPARATOR, '\0' };

    if( ( host == NULL ) || ( name == NULL ) )
    {
        return NULL;
    }

    /* first, we construct path to log file. */

    osi_strlcpy( path, root_path, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, HOSTS_DIRECTORY_NAME, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, host, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, HOST_LOG_DIRECTORY_NAME, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, name, sizeof( path ) );

    if( ( file = osi_fopen( path, "r", 0 ) ) != NULL )
    {
        log_data = string_list_new();

        for(;;)
        {
            line = fgets( temp_line, sizeof( temp_line ), file );

            if( line == NULL )
            {
                break;
            }

            line = trim_white_space( line );

            if( line != NULL )
            {
                string_list_add_item( log_data, line );
            }
        }
    }

    return log_data;
}

char * generate_log_file_name( const char *host )
{
    static char path[MAX_PATH_LENGTH];
    unsigned int number = 0;

    char filename[40];
    char path_separator[2] = { PATH_SEPARATOR, '\0' };

    OSI_DIRECTORY directory;

    path[0] = '\0';

    if( host == NULL )
    {
        return NULL;
    }

    memset( &directory, 0, sizeof( OSI_DIRECTORY ) );

    /* put the path to the logs directory first. */

    osi_strlcpy( path, root_path, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, HOSTS_DIRECTORY_NAME, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, host, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, HOST_LOG_DIRECTORY_NAME, sizeof( path ) );

    /* now find the next free number to use for the filename. */

    if( osi_open_directory( path, &directory ) == FALSE )
    {
        return NULL;
    }

    do
    {
        int num;

        if( directory.filename != NULL )
        {
            num = atoi( directory.filename );

            if( (unsigned int)num > number )
            {
                number = num;
            }
        }

    } while( osi_get_next_file( &directory ) );

    osi_close_directory( &directory );
    number++;

    /* turn number into string. */

    osi_snprintf( filename, sizeof( filename ), "%d", number );

    /* append the filename to the path. */

    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, filename, sizeof( path ) );

    return path;
}

char * generate_temp_log_file_name( const char *host )
{
    static char path[MAX_PATH_LENGTH];
    char path_separator[2] = { PATH_SEPARATOR, '\0' };

    path[0] = '\0';

    if( host == NULL )
    {
        return NULL;
    }

    /* put the path to the logs directory first. */

    osi_strlcpy( path, root_path, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, HOSTS_DIRECTORY_NAME, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, host, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, HOST_LOG_DIRECTORY_NAME, sizeof( path ) );
    osi_strlcat( path, path_separator, sizeof( path ) );
    osi_strlcat( path, TEMP_SCAN_LOG_FILE_NAME, sizeof( path ) ); 

    return path;
}
