/*
 * Note: this file originally auto-generated by mib2c using
 *  : mib2c.container.conf,v 1.8 2006/07/26 15:58:26 dts12 Exp $
 */
/* Portions of this file are subject to the following copyright(s).  See
 * the Net-SNMP's COPYING file for more details and other copyrights
 * that may apply:
 */
/*
 * Portions of this file are copyrighted by:
 * Copyright (C) 2007 Apple, Inc. All rights reserved.
 * Use is subject to license terms specified in the COPYING file
 * distributed with the Net-SNMP package.
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/table_container.h>
#include <net-snmp/data_access/swrun.h>
#include <net-snmp/agent/cache_handler.h>
#include "data_access/swrun.h"
#include "hrSWRunTable.h"

#include <signal.h>

#define MYTABLE "hrSWRunTable"

/** Initializes the hrSWRunTable module */
void
init_hrSWRunTable(void)
{
    /*
     * here we initialize all the tables we're planning on supporting 
     */
    initialize_table_hrSWRunTable();
}

oid      hrSWRunTable_oid[] = { 1, 3, 6, 1, 2, 1, 25, 4, 2 };
size_t   hrSWRunTable_oid_len = OID_LENGTH(hrSWRunTable_oid);

/** Initialize the hrSWRunTable table by defining its contents and how it's structured */
void
initialize_table_hrSWRunTable(void)
{
    netsnmp_handler_registration *reg;
    netsnmp_mib_handler *handler = NULL;
    netsnmp_table_registration_info *table_info = NULL;

#ifdef NETSNMP_INCLUDE_HRSWRUN_WRITE_SUPPORT
#  define SWRUN_ACCESS_LEVEL HANDLER_CAN_RWRITE
#else
#  define SWRUN_ACCESS_LEVEL HANDLER_CAN_RONLY
#endif
    reg =
        netsnmp_create_handler_registration(MYTABLE,
                                            hrSWRunTable_handler,
                                            hrSWRunTable_oid,
                                            hrSWRunTable_oid_len,
                                            SWRUN_ACCESS_LEVEL);
    if (NULL == reg) {
        snmp_log(LOG_ERR,"error creating handler registration for "
                 MYTABLE "\n");
        goto bail;
    }
    reg->modes |= HANDLER_CAN_NOT_CREATE;

    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (NULL == table_info) {
        snmp_log(LOG_ERR,"error allocating table registration for "
                 MYTABLE "\n");
        goto bail;
    }

    netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER,   /* index: hrSWRunIndex */
                                     0);
    table_info->min_column = COLUMN_HRSWRUNINDEX;
    table_info->max_column = COLUMN_HRSWRUNSTATUS;

    /*************************************************
     *
     * inject container_table helper
     */
    handler = netsnmp_container_table_handler_get(table_info, netsnmp_swrun_container(),
                                                  TABLE_CONTAINER_KEY_NETSNMP_INDEX);
    if (NULL == handler) {
        snmp_log(LOG_ERR,"error allocating table registration for "
                 MYTABLE "\n");
        goto bail;
    }
    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,"error injecting container_table handler for "
                 MYTABLE "\n");
        goto bail;
    }
    handler = NULL; /* reg has it, will reuse below */

    /*************************************************
     *
     * inject cache helper
     */
    handler = netsnmp_cache_handler_get(netsnmp_swrun_cache());
    if (NULL == handler) {
        snmp_log(LOG_ERR, "error creating cache handler for " MYTABLE "\n");
        goto bail;
    }

    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,"error injecting cache handler for "
                 MYTABLE "\n");
        goto bail;
    }
    handler = NULL; /* reg has it*/

    if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
        snmp_log(LOG_ERR,"error registering table handler for "
                 MYTABLE "\n");
        reg = NULL; /* it was freed inside netsnmp_register_table */
        goto bail;
    }

    return; /* ok */


  bail: /* not ok */
    
    if (handler)
        netsnmp_handler_free(handler);

    if (table_info)
        netsnmp_table_registration_info_free(table_info);

    if (reg) 
        netsnmp_handler_registration_free(reg);

}

/** handles requests for the hrSWRunTable table */
int
hrSWRunTable_handler(netsnmp_mib_handler *handler,
                     netsnmp_handler_registration *reginfo,
                     netsnmp_agent_request_info *reqinfo,
                     netsnmp_request_info *requests)
{
    netsnmp_request_info *request;
    netsnmp_table_request_info *table_info;
    netsnmp_swrun_entry *table_entry;

    switch (reqinfo->mode) {
        /*
         * Read-support (also covers GetNext requests)
         */
    case MODE_GET:
        for (request = requests; request; request = request->next) {
            if (request->processed)
               continue;
            table_entry = (netsnmp_swrun_entry *)
                netsnmp_container_table_extract_context(request);
            table_info = netsnmp_extract_table_info(request);
            if ((NULL == table_entry) || (NULL == table_info)) {
                snmp_log(LOG_ERR, "could not extract table entry or info for "
                 MYTABLE "\n");
                snmp_set_var_typed_value(request->requestvb,
                                         SNMP_ERR_GENERR, NULL, 0);
                continue;
            }

            switch (table_info->colnum) {
            case COLUMN_HRSWRUNINDEX:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           table_entry->hrSWRunIndex);
                break;
            case COLUMN_HRSWRUNNAME:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                         (u_char *) table_entry->
                                         hrSWRunName,
                                         table_entry->hrSWRunName_len);
                break;
            case COLUMN_HRSWRUNID:
                snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID,
#ifdef NETSNMP_SWRUN_HAVE_ID
                                         (u_char *) table_entry->hrSWRunID,
                                         table_entry->hrSWRunID_len
#else
                                         (u_char *) &nullOid, nullOidLen
#endif
                    );
                break;
            case COLUMN_HRSWRUNPATH:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                         (u_char *) table_entry->
                                         hrSWRunPath,
                                         table_entry->hrSWRunPath_len);
                break;
            case COLUMN_HRSWRUNPARAMETERS:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                         (u_char *) table_entry->
                                         hrSWRunParameters,
                                         table_entry->
                                         hrSWRunParameters_len);
                break;
            case COLUMN_HRSWRUNTYPE:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           table_entry->hrSWRunType);
                break;
            case COLUMN_HRSWRUNSTATUS:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           table_entry->hrSWRunStatus);
                break;
            default:
                /*
                 * An unsupported/unreadable column (if applicable) 
                 */
                snmp_set_var_typed_value(request->requestvb,
                                         SNMP_NOSUCHOBJECT, NULL, 0);
            }
        }
        break;

#ifdef NETSNMP_INCLUDE_HRSWRUN_WRITE_SUPPORT
        /*
         * Write-support
         */
    case MODE_SET_RESERVE1:
        for (request = requests; request; request = request->next) {
            int pid;
            if (request->processed)
               continue;
            table_entry = (netsnmp_swrun_entry *)
                netsnmp_container_table_extract_context(request);
            table_info = netsnmp_extract_table_info(request);
            if ((NULL == table_entry) || (NULL == table_info)) {
                snmp_log(LOG_ERR, "could not extract table entry or info for "
                 MYTABLE "\n");
                snmp_set_var_typed_value(request->requestvb,
                                         SNMP_ERR_GENERR, NULL, 0);
                continue;
            }

            switch (table_info->colnum) {
            case COLUMN_HRSWRUNSTATUS:
                if (*request->requestvb->val.integer != HRSWRUNSTATUS_INVALID) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGVALUE);
                    return SNMP_ERR_NOERROR;
                }
                pid = request->requestvb->name[request->requestvb->name_length-1];
                if (1 == pid) {
                    snmp_log(LOG_WARNING,"refusing to kill pid 1\n");
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_NOACCESS);
                    return SNMP_ERR_NOERROR;
                }
                break;
            default:
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOTWRITABLE);
                return SNMP_ERR_NOERROR;
            }
        }
        break;

    case MODE_SET_RESERVE2:
        break;

    case MODE_SET_FREE:
        break;

    case MODE_SET_ACTION:
        for (request = requests; request; request = request->next) {
            if (request->processed)
               continue;
            table_entry = (netsnmp_swrun_entry *)
                netsnmp_container_table_extract_context(request);
            table_info = netsnmp_extract_table_info(request);
            if ((NULL == table_entry) || (NULL == table_info)) {
                snmp_log(LOG_ERR, "could not extract table entry or info for "
                 MYTABLE "\n");
                snmp_set_var_typed_value(request->requestvb,
                                         SNMP_ERR_GENERR, NULL, 0);
                continue;
            }

            switch (table_info->colnum) {
            case COLUMN_HRSWRUNSTATUS:
                table_entry->old_hrSWRunStatus =
                    table_entry->hrSWRunStatus;
                table_entry->hrSWRunStatus =
                    *request->requestvb->val.integer;
                break;
            }
        }
        break;

    case MODE_SET_UNDO:
        for (request = requests; request; request = request->next) {
            if (request->processed)
               continue;
            container = netsnmp_container_table_extract_context(request);
            table_entry = (netsnmp_swrun_entry *)
                netsnmp_container_table_extract_context(request);
            table_info = netsnmp_extract_table_info(request);
            if ((NULL == table_entry) || (NULL == table_info)) {
                snmp_log(LOG_ERR, "could not extract table entry or info for "
                 MYTABLE "\n");
                snmp_set_var_typed_value(request->requestvb,
                                         SNMP_ERR_GENERR, NULL, 0);
                continue;
            }

            switch (table_info->colnum) {
            case COLUMN_HRSWRUNSTATUS:
                table_entry->hrSWRunStatus =
                    table_entry->old_hrSWRunStatus;
                table_entry->old_hrSWRunStatus = 0;
                break;
            }
        }
        break;

    case MODE_SET_COMMIT:
        for (request = requests; request; request = request->next) {
            int pid;
            if (request->processed)
               continue;
            pid = request->requestvb->name[request->requestvb->name_length-1];
            DEBUGMSGTL(("hrSWRunTable:commit", "kill(%d,TERM)\n", pid));
            kill(pid, SIGTERM);
        }
        break;
#endif /* NETSNMP_INCLUDE_HRSWRUN_WRITE_SUPPORT */
    }
    return SNMP_ERR_NOERROR;
}

