Article Listing 1 Listing 2 Listing 3 Listing 4
Listing 5 Listing 6 Listing 7 Listing 8 Listing 9
Listing 10 apr2004.tar

Listing 5 send_globals

# Listing 5:
# send_globals: This file contains the global variables and 
# function definitions for the send_alerts script.
#**************************************************************
. $(dirname $0)/setenv_monitor

#**********
# CONSTANTS
#**********

integer TRUE=0
readonly TRUE
integer FALSE=1
readonly FALSE
integer UNDEFINED=-1
readonly UNDEFINED
readonly THIS_HOST=$(uname -n)
readonly TEMP_CONFIG_FILE=/tmp/monitor_conf.$$
readonly TEMP_STRINGS_FILE=/tmp/strings.$$
readonly TEMP_HEADER=/tmp/summary_header.$$
readonly TEMP_HEADER_2=/tmp/summary_header_2.$$
readonly TEMP_BODY=/tmp/summary_body.$$

#*********************
# INITIALIZE VARIABLES
#*********************

integer message_count=0
integer file_count=0
integer send_high_alerts=$TRUE
integer send_medium_alerts=$TRUE
integer send_low_alerts=$TRUE
integer send_info_alerts=$TRUE
class_list=""
priority_list=""

# "Config" Variables

integer days_old=$UNDEFINED
integer begin_hour=$UNDEFINED
integer end_hour=$UNDEFINED
message_types=""
priorities=""
include_classes=""
exclude_classes=""
address_type=""
addresses=""
addresses_files=""
users=""
users_files=""
clients=""
clients_files=""
servers=""
servers_files=""
sudoers_users=""
sudoers_clients=""
sudoers_servers=""
days=""
TZ=""

reset_config_variables()
{
    days_old=1
    begin_hour=$UNDEFINED
    end_hour=$UNDEFINED
    message_types=""
    priorities=""
    include_classes=""
    exclude_classes=""
    address_type="email"
    addresses=""
    addresses_files=""
    users=""
    users_files=""
    clients=""
    clients_files=""
    servers=""
    servers_files=""
    sudoers_users=""
    sudoers_clients=""
    sudoers_servers=""
    days=""
    TZ=$(grep "^TZ=" /etc/TIMEZONE | cut -d= -f2)
}

#*****************************************************
# FUNCTIONS THAT MAY REQUIRE ALTERNATE IMPLEMENTATIONS
#*****************************************************

#==========================================================
# Function: username_to_email_address
# Purpose:  Translates a username to an email address.
#==========================================================

username_to_email_address()
{
    disp_username -f email $1 | sort -u
}

#==========================================================
# Function: username_to_pager_address
# Purpose:  Translates a username to a pager address.
#==========================================================

username_to_pager_address()
{
    disp_username -f pager $1 | sort -u
}

#==========================================================
# Function: sudoers_alias_to_users
# Purpose:  Translates an alias defined in /etc/sudoers to
#           a list of user names.
#==========================================================

sudoers_alias_to_users()
{
    sudo /opt/users/sbin/sudoers_local-users $1
}

#==========================================================
# Function: sudoers_alias_to_hosts
# Purpose:  Translates an alias defined in /etc/sudoers to
#           a list of host names.
#==========================================================

sudoers_alias_to_hosts()
{
    sudo /opt/users/sbin/sudoers_hosts $1
}

#************************
# PLUG-AND-PLAY FUNCTIONS
#************************

remove_duplicates()
{
    list=$1
    for item in $list
    do
        echo $item
    done | sort -u
}

#==========================================================
# Function: get_alert_attribute
# Purpose:  Returns the value of an alert file attribute.
#           Valid attributes include: host, class, and
#           priority.
#==========================================================

get_alert_attribute()
{
    alert_file=$1
    attribute=$2
    head -4 $alert_file | grep "$attribute=" | cut -d= -f2
}

#==========================================================
# Function: get_options
# Purpose:  Parses the command line options for send_alerts
#           and send_summary. Sets the variables class_list
#            and priority_list, which determine whether to
#           process alert files based on class and priority.
#==========================================================

get_options()
{
    while getopts c:p:f: OPTION
    do
        case "$OPTION"
        in
        c) class_list=$OPTARG ;;
        p) priority_list=$OPTARG ;;
        f) [[ -f $OPTARG ]] && CONFIG_FILE=$OPTARG ;;
        esac
    done

    readonly CONFIG_FILE

    if [[ -n $priority_list ]]
    then
        send_high_alerts=$FALSE
        send_medium_alerts=$FALSE
        send_low_alerts=$FALSE
        send_info_alerts=$FALSE

        for priority in $priority_list
        do
            case $priority in
            h*|H*) send_high_alerts=$TRUE ;;
            m*|M*) send_medium_alerts=$TRUE ;;
            l*|L*) send_low_alerts=$TRUE ;;
            i*|I*) send_info_alerts=$TRUE ;;
            esac
        done
    fi
}

#==========================================================
# Function: strip_config_file
# Purpose:  Strips comments from the config file. Saves
#           non-comments in a temporary file.
#==========================================================

strip_config_file()
{
    while read line
    do
        #------------------------------------
        # Skip past blank lines and comments.
        #------------------------------------

        while [[ -z "$line" ]] || [[ -z $(echo ${line%%#*}) ]]
        do
            if ! read line
            then
                break
            fi
        done

        #---------------------------------------------------------
        # If the last line read was blank or a comment, then
        # we've reached the end of file, so break out of the loop.
        #---------------------------------------------------------

        if [[ -z "$line" ]] || [[ -z $(echo ${line%%#*}) ]]
        then
            break
        fi

        #--------------------------------------------
        # Append a blank line to separate the blocks.
        #--------------------------------------------

        echo >> $STRIPPED_CONFIG_FILE

        #-----------------------------------
        # Copy the next configuration block.
        #-----------------------------------

        while [[ -n "$line" ]]
        do
            if [[ -n $(echo ${line%%#*}) ]]
            then
                echo ${line%%#*} >> $STRIPPED_CONFIG_FILE
            fi
            if ! read line
            then
                break
            fi
        done
    done < $CONFIG_FILE
}
    
#==========================================================
# Function: read_config_block
# Purpose:  Reads a stripped configuration block from
#           $STRIPPED_CONFIG_FILE. Writes the block to
#           $TEMP_CONFIG_FILE.
#==========================================================

read_config_block()
{
    #------------------------------------
    # Skip past blank lines and comments.
    #------------------------------------

    while [[ -z "$line" ]]
    do
        if ! read line
        then
            break
        fi
    done

    #---------------------------------------------------------
    # If the last line read was blank or a comment, then
    # we've reached the end of file, so break out of the loop.
    #---------------------------------------------------------

    if [[ -z "$line" ]]
    then
        break
    fi

    #-----------------------
    # Wipe TEMP_CONFIG_FILE.
    #-----------------------

    > $TEMP_CONFIG_FILE

    #--------------------------------------------------
    # Copy the next configuration block to a temp file.
    #--------------------------------------------------

    while [[ -n "$line" ]]
    do
        echo $line >> $TEMP_CONFIG_FILE
        if ! read line
        then
            break
        fi
    done
}

#==========================================================
# Function: check_priority
# Purpose:  Determines whether to skip the remainder of a
#           while loop and continue with the next iteration
#           based on the current value of the variable
#           alert_priority and the corresponding
#           send_*_alerts variable.
#==========================================================

check_priority()
{
    alert_priority=$1
    case $alert_priority in
    h*|H*) (( $send_high_alerts == $FALSE )) && continue ;;
    m*|M*) (( $send_medium_alerts == $FALSE )) && continue ;;
    l*|L*) (( $send_low_alerts == $FALSE )) && continue ;;
    i*|I*) (( $send_info_alerts == $FALSE )) && continue ;;
    esac
}

#==========================================================
# Function: check_class
# Purpose:  Determines whether to skip the remainder of a
#           while loop and continue with the next iteration
#           based on the current value of the variables
#           alert_class and class_list.
#==========================================================

check_class()
{
    alert_class=$1
    if [[ -n $class_list ]]
    then
        send_this_alert=$FALSE
        for class in $class_list
        do
            if [[ $class = $alert_class ]]
            then
                send_this_alert=$TRUE
            fi
        done
        if (( $send_this_alert == $FALSE )) 
        then
            continue
        fi
    fi
}

#==========================================================
# Function: should_include
# Purpose:  Determines whether an alert file should be
#           included in the set of alerts that may be sent
#           based on characteristics of the alert itself.
#==========================================================

should_include()
{
    if (( $(echo $priorities | grep -c -w "$alert_priority") > 0 ))
    then
        if [[ -z "$exclude_classes" ]] \
        || (( $(echo $exclude_classes | grep -c -w "$alert_class") == 0 ))
        then
            if [[ -z "$include_classes" ]] \
            || (( $(echo $include_classes | grep -c -w "$alert_class") > 0 ))
            then
                if (( $(echo $clients | grep -c -w $alert_host) > 0 ))
                then
                    return 0
                fi
            fi
        fi
    fi
    return 1
}

#==========================================================
# Function: should_send
# Purpose:  Determines whether an alert should be sent
#           based on characteristics of the environment
#           that are independent of the alert file itself.
#==========================================================

should_send()
{
    if [[ -n "$addresses" ]] \
    && (( $(echo $servers | grep -i -c -w $THIS_HOST) > 0 ))
    then
        if [[ -z $days ]]
        then
            if (( $begin_hour == $UNDEFINED )) \
            && (( $end_hour == $UNDEFINED ))
            then
                return 0
            elif (( $begin_hour == $UNDEFINED ))
            then
                if (( $current_hour <= $end_hour ))
                then
                    return 0
                fi
            elif (( $end_hour == $UNDEFINED ))
            then
                if (( $begin_hour <= $current_hour ))
                then
                    return 0
                fi
            else
                if (( $begin_hour <= $current_hour )) \
                && (( $current_hour <= $end_hour ))
                then
                    return 0
                fi
            fi
        elif (( $(echo $days | grep -i -c $current_day) > 0 ))
        then 
            if (( $begin_hour == $UNDEFINED )) \
            || (( $end_hour == $UNDEFINED ))
            then
                return 0
            else
                if (( $begin_hour <= $current_hour )) \
                && (( $current_hour <= $end_hour )) 
                then
                    return 0
                fi
            fi
        fi
    fi
    return 1
}

#==========================================================
# Function: get_config
# Purpose:  Reads lines from a configuration block and sets
#           parameters accordingly.
#==========================================================

get_config()
{
    while read line
    do
        name=$(echo $line | cut -d: -f1)
        value=$(echo $line | cut -d: -f2)

        #-------------------------------------------------------
        # Check to see if "name" is a valid key word. If so, set
        # the corresponding variable to "value".
        #-------------------------------------------------------

        case $name in
            message_types) message_types=$(echo $value $message_types);;
            days_old) days_old=$(echo $value);;
            priorities) priorities=$(echo $value $priorities);;
            include_classes) include_classes=$(echo $value $include_classes);;
            exclude_classes) exclude_classes=$(echo $value $exclude_classes);;
            address_type) address_type=$(echo $value);;
            addresses) addresses=$(echo $value $addresses);;
            addresses_files) addresses_files=$(echo $value $addresses_files);;
            users) users=$(echo $value $users);;
            users_files) users_files=$(echo $value $users_files);;
            clients) clients=$(echo $value $clients);;
            clients_files) clients_files=$(echo $value $clients_files);;
            servers) servers=$(echo $value $servers);;
            servers_files) servers_files=$(echo $value $servers_files);;
            sudoers_users) sudoers_users=$(echo $value $sudoers_users);;
            sudoers_clients) sudoers_clients=$(echo $value $sudoers_clients);;
            sudoers_servers) sudoers_servers=$(echo $value $sudoers_servers);;
            days) days=$(echo $value $days);;
            begin_hour) begin_hour=$(echo $value);;
            end_hour) end_hour=$(echo $value);;
            timezone) TZ=$(echo $value);;
        esac
    done

    if [[ -f /usr/share/lib/zoneinfo/$TZ ]]
    then
        export TZ
    fi

    current_hour=$(date '+%H')
    current_hour=$(( $current_hour + 0 ))
    current_day=$(date '+%a')

    for addresses_file in $addresses_files
    do
        if [[ -f "$addresses_file" ]]
        then
            addresses="$addresses $(cat $addresses_file)"
        fi
    done

    for users_file in $users_files
    do
        if [[ -f "$users_file" ]]
        then
            users="$users $(cat $users_file)"
        fi
    done

    if [[ -n "$sudoers_users" ]]
    then
        users=$(echo $users $(sudoers_alias_to_users $sudoers_users))
    fi

    if [[ "$address_type" = email ]] && [[ -n "$users" ]]
    then
        for user in $users
        do
            addresses="$addresses $(username_to_email_address $user)"
        done
    fi

    if [[ "$address_type" = pager ]] && [[ -n "$users" ]]
    then
        for user in $users
        do
            addresses="$addresses $(username_to_pager_address $user)"
        done
    fi

    for clients_file in $clients_files
    do
        if [[ -f $clients_file ]]
        then
            clients=$(echo $clients $(cat $clients_file))
        fi
    done

    for servers_file in $servers_files
    do
        if [[ -f $servers_file ]]
        then
            servers=$(echo $servers $(cat $servers_file))
        fi
    done

    for sudoers_client in $sudoers_clients
    do
        clients=$(echo $clients $(sudoers_alias_to_hosts $sudoers_client))
    done

    for sudoers_server in $sudoers_servers
    do
        servers=$(echo $servers $(sudoers_alias_to_hosts $sudoers_server))
    done
}

#==========================================================
# Function: clean_up
# Purpose:  Removes temporary files.
#==========================================================

clean_up()
{
    rm -f \
    $TEMP_CONFIG_FILE \
    $TEMP_HEADER \
    $TEMP_HEADER_2 \
    $TEMP_BODY \
    $TEMP_STRINGS_FILE \
    $STRIPPED_CONFIG_FILE
}