/*
 * Note: this file originally auto-generated by mib2c using
 *        : mib2c.iterate_access.conf,v 1.4 2003/07/01 00:15:11 hardaker Exp $
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-features.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "netSnmpHostsTable.h"
#include "netSnmpHostsTable_checkfns.h"
#include "netSnmpHostsTable_access.h"

netsnmp_feature_require(oid_stash)
netsnmp_feature_require(oid_stash_get_data)
netsnmp_feature_require(oid_stash_add_data)

static netsnmp_oid_stash_node *undoStorage = NULL;
static netsnmp_oid_stash_node *commitStorage = NULL;

struct undoInfo {
    void           *ptr;
    size_t          len;
};

struct commitInfo {
    void           *data_context;
    int             have_committed;
    int             new_row;
};

void
netSnmpHostsTable_free_undoInfo(void *vptr)
{
    struct undoInfo *ui = vptr;
    if (!ui)
        return;
    SNMP_FREE(ui->ptr);
    SNMP_FREE(ui);
}

/** Initialize the netSnmpHostsTable table by defining its contents and how it's structured */
void
initialize_table_netSnmpHostsTable(void)
{
    static oid      netSnmpHostsTable_oid[] =
        { 1, 3, 6, 1, 4, 1, 8072, 2, 2, 2 };
    netsnmp_table_registration_info *table_info;
    netsnmp_handler_registration *my_handler;
    netsnmp_iterator_info *iinfo;

    /** create the table registration information structures */
    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);

    /** if your table is read only, it's easiest to change the
        HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */
    my_handler = netsnmp_create_handler_registration("netSnmpHostsTable",
                                                     netSnmpHostsTable_handler,
                                                     netSnmpHostsTable_oid,
                                                     OID_LENGTH
                                                     (netSnmpHostsTable_oid),
                                                     HANDLER_CAN_RWRITE);

    if (!my_handler || !table_info || !iinfo) {
        snmp_log(LOG_ERR,
                 "malloc failed in initialize_table_netSnmpHostsTable");
        return; /** Serious error. */
    }

    /***************************************************
     * Setting up the table's definition
     */
    netsnmp_table_helper_add_indexes(table_info, ASN_OCTET_STR,
                                                 /** index: netSnmpHostName */
                                     0);

    /** Define the minimum and maximum accessible columns.  This
        optimizes retrieval. */
    table_info->min_column = 2;
    table_info->max_column = 5;

    /** iterator access routines */
    iinfo->get_first_data_point = netSnmpHostsTable_get_first_data_point;
    iinfo->get_next_data_point = netSnmpHostsTable_get_next_data_point;

    /** you may wish to set these as well */
    iinfo->make_data_context = netSnmpHostsTable_context_convert_function;
    iinfo->free_data_context = netSnmpHostsTable_data_free;
    iinfo->free_loop_context_at_end = netSnmpHostsTable_loop_free;

    /** tie the two structures together */
    iinfo->table_reginfo = table_info;

    /***************************************************
     * registering the table with the master agent
     */
    DEBUGMSGTL(("initialize_table_netSnmpHostsTable",
                "Registering table netSnmpHostsTable as a table iterator\n"));
    netsnmp_register_table_iterator2(my_handler, iinfo);
}

/** Initializes the netSnmpHostsTable module */
void
init_netSnmpHostsTable(void)
{

  /** here we initialize all the tables we're planning on supporting */
    initialize_table_netSnmpHostsTable();
}

/** handles requests for the netSnmpHostsTable table, if anything else needs to be done */
int
netSnmpHostsTable_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;
    struct commitInfo *ci = NULL;

    void           *data_context = NULL;

    for (request = requests; request; request = request->next) {
        /* column and row index encoded portion */
        netsnmp_variable_list *var = request->requestvb;
        const oid * const suffix = var->name + reginfo->rootoid_len + 1;
        const size_t suffix_len = var->name_length - (reginfo->rootoid_len + 1);

        if (request->processed != 0)
            continue;

        switch (reqinfo->mode) {
        case MODE_GET:
        case MODE_SET_RESERVE1:
            data_context = netsnmp_extract_iterator_context(request);
            if (data_context == NULL) {
                if (reqinfo->mode == MODE_GET) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
            }
            break;

        default:               /* == the other SET modes */
            ci = netsnmp_oid_stash_get_data(commitStorage,
                                            suffix + 1, suffix_len - 1);
            break;

        }

        /** extracts the information about the table from the request */
        table_info = netsnmp_extract_table_info(request);
        /** table_info->colnum contains the column number requested */
        /** table_info->indexes contains a linked list of snmp variable
           bindings for the indexes of the table.  Values in the list
           have been set corresponding to the indexes of the
           request */
        if (table_info == NULL) {
            continue;
        }

        switch (reqinfo->mode) {
        case MODE_GET:
            switch (table_info->colnum) {
            case COLUMN_NETSNMPHOSTADDRESSTYPE:
                {
                    long           *retval;
                    size_t          retval_len = 0;
                    retval =
                        get_netSnmpHostAddressType(data_context,
                                                   &retval_len);
                    snmp_set_var_typed_value(var, ASN_INTEGER,
                                             (const u_char *) retval,
                                             retval_len);
                }
                break;

            case COLUMN_NETSNMPHOSTADDRESS:
                {
                    char           *retval;
                    size_t          retval_len = 0;
                    retval =
                        get_netSnmpHostAddress(data_context, &retval_len);
                    snmp_set_var_typed_value(var, ASN_OCTET_STR,
                                             (const u_char *) retval,
                                             retval_len);
                }
                break;

            case COLUMN_NETSNMPHOSTSTORAGE:
                {
                    long           *retval;
                    size_t          retval_len = 0;
                    retval =
                        get_netSnmpHostStorage(data_context, &retval_len);
                    snmp_set_var_typed_value(var, ASN_INTEGER,
                                             (const u_char *) retval,
                                             retval_len);
                }
                break;

            case COLUMN_NETSNMPHOSTROWSTATUS:
                {
                    long           *retval;
                    size_t          retval_len = 0;
                    retval =
                        get_netSnmpHostRowStatus(data_context,
                                                 &retval_len);
                    snmp_set_var_typed_value(var, ASN_INTEGER,
                                             (const u_char *) retval,
                                             retval_len);
                }
                break;

            default:
                /** We shouldn't get here */
                snmp_log(LOG_ERR,
                         "problem encountered in netSnmpHostsTable_handler: unknown column\n");
            }
            break;

        case MODE_SET_RESERVE1:
            ci = netsnmp_oid_stash_get_data(commitStorage,
                                            suffix + 1, suffix_len - 1);

            if (!ci) {
                    /** create the commit storage info */
                ci = SNMP_MALLOC_STRUCT(commitInfo);
                if (!data_context) {
                    ci->data_context =
                        netSnmpHostsTable_create_data_context(table_info->
                                                              indexes);
                    ci->new_row = 1;
                } else {
                    ci->data_context = data_context;
                }
                netsnmp_oid_stash_add_data(&commitStorage,
                                           suffix + 1, suffix_len - 1, ci);
            }
            break;

        case MODE_SET_RESERVE2:
            switch (table_info->colnum) {
            case COLUMN_NETSNMPHOSTADDRESSTYPE:
                {
                    long           *retval;
                    size_t          retval_len = 0;
                    struct undoInfo *ui = NULL;
                    int             ret;

                    /** first, get the old value */
                    retval =
                        get_netSnmpHostAddressType(ci->data_context,
                                                   &retval_len);
                    if (retval) {
                        ui = SNMP_MALLOC_STRUCT(undoInfo);
                        ui->len = retval_len;
                        memdup((u_char **) & ui->ptr,
                               (u_char *) retval, ui->len);
                    }

                    /** check the new value, possibly against the
                        older value for a valid state transition */
                    ret =
                        check_netSnmpHostAddressType(request->requestvb->
                                                     type,
                                                     (long *) request->
                                                     requestvb->val.string,
                                                     request->requestvb->
                                                     val_len, retval,
                                                     retval_len);
                    if (ret != 0) {
                        netsnmp_set_request_error(reqinfo, request, ret);
                        netSnmpHostsTable_free_undoInfo(ui);
                    } else if (ui) {
                        /** remember information for undo purposes later */
                        netsnmp_oid_stash_add_data(&undoStorage,
                                                   suffix, suffix_len, ui);
                    }

                }
                break;
            case COLUMN_NETSNMPHOSTADDRESS:
                {
                    char           *retval;
                    size_t          retval_len = 0;
                    struct undoInfo *ui = NULL;
                    int             ret;

                    /** first, get the old value */
                    retval =
                        get_netSnmpHostAddress(ci->data_context,
                                               &retval_len);
                    if (retval) {
                        ui = SNMP_MALLOC_STRUCT(undoInfo);
                        ui->len = retval_len;
                        memdup((u_char **) & ui->ptr,
                               (u_char *) retval, ui->len);
                    }

                    /** check the new value, possibly against the
                        older value for a valid state transition */
                    ret =
                        check_netSnmpHostAddress(request->requestvb->type,
                                                 (char *) request->
                                                 requestvb->val.string,
                                                 request->requestvb->
                                                 val_len, retval,
                                                 retval_len);
                    if (ret != 0) {
                        netsnmp_set_request_error(reqinfo, request, ret);
                        netSnmpHostsTable_free_undoInfo(ui);
                    } else if (ui) {
                        /** remember information for undo purposes later */
                        netsnmp_oid_stash_add_data(&undoStorage,
                                                   suffix, suffix_len, ui);
                    }

                }
                break;
            case COLUMN_NETSNMPHOSTSTORAGE:
                {
                    long           *retval;
                    size_t          retval_len = 0;
                    struct undoInfo *ui = NULL;
                    int             ret;

                    /** first, get the old value */
                    retval =
                        get_netSnmpHostStorage(ci->data_context,
                                               &retval_len);
                    if (retval) {
                        ui = SNMP_MALLOC_STRUCT(undoInfo);
                        ui->len = retval_len;
                        memdup((u_char **) & ui->ptr,
                               (u_char *) retval, ui->len);
                    }

                    /** check the new value, possibly against the
                        older value for a valid state transition */
                    ret =
                        check_netSnmpHostStorage(request->requestvb->type,
                                                 (long *) request->
                                                 requestvb->val.string,
                                                 request->requestvb->
                                                 val_len, retval,
                                                 retval_len);
                    if (ret != 0) {
                        netsnmp_set_request_error(reqinfo, request, ret);
                        netSnmpHostsTable_free_undoInfo(ui);
                    } else if (ui) {
                        /** remember information for undo purposes later */
                        netsnmp_oid_stash_add_data(&undoStorage,
                                                   suffix, suffix_len, ui);
                    }

                }
                break;
            case COLUMN_NETSNMPHOSTROWSTATUS:
                {
                    long           *retval;
                    size_t          retval_len = 0;
                    struct undoInfo *ui = NULL;
                    int             ret;

                    /** first, get the old value */
                    retval =
                        get_netSnmpHostRowStatus(ci->data_context,
                                                 &retval_len);
                    if (retval) {
                        ui = SNMP_MALLOC_STRUCT(undoInfo);
                        ui->len = retval_len;
                        memdup((u_char **) & ui->ptr,
                               (u_char *) retval, ui->len);
                    }

                    /** check the new value, possibly against the
                        older value for a valid state transition */
                    ret =
                        check_netSnmpHostRowStatus(request->requestvb->
                                                   type,
                                                   (long *) request->
                                                   requestvb->val.string,
                                                   request->requestvb->
                                                   val_len, retval,
                                                   retval_len);
                    if (ret != 0) {
                        netsnmp_set_request_error(reqinfo, request, ret);
                        netSnmpHostsTable_free_undoInfo(ui);
                    } else if (ui) {
                        /** remember information for undo purposes later */
                        netsnmp_oid_stash_add_data(&undoStorage,
                                                   suffix, suffix_len, ui);
                    }

                }
                break;
            default:
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOTWRITABLE);
                break;
            }
            break;

        case MODE_SET_ACTION:
            /** save a variable copy */
            switch (table_info->colnum) {
            case COLUMN_NETSNMPHOSTADDRESSTYPE:
                {
                    int             ret;
                    ret = set_netSnmpHostAddressType(ci->data_context,
                                                     (long *) request->
                                                     requestvb->val.string,
                                                     request->requestvb->
                                                     val_len);
                    if (ret) {
                        netsnmp_set_request_error(reqinfo, request, ret);
                    }
                }
                break;
            case COLUMN_NETSNMPHOSTADDRESS:
                {
                    int             ret;
                    ret = set_netSnmpHostAddress(ci->data_context,
                                                 (char *) request->
                                                 requestvb->val.string,
                                                 request->requestvb->
                                                 val_len);
                    if (ret) {
                        netsnmp_set_request_error(reqinfo, request, ret);
                    }
                }
                break;
            case COLUMN_NETSNMPHOSTSTORAGE:
                {
                    int             ret;
                    ret = set_netSnmpHostStorage(ci->data_context,
                                                 (long *) request->
                                                 requestvb->val.string,
                                                 request->requestvb->
                                                 val_len);
                    if (ret) {
                        netsnmp_set_request_error(reqinfo, request, ret);
                    }
                }
                break;
            case COLUMN_NETSNMPHOSTROWSTATUS:
                {
                    int             ret;
                    ret = set_netSnmpHostRowStatus(ci->data_context,
                                                   (long *) request->
                                                   requestvb->val.string,
                                                   request->requestvb->
                                                   val_len);
                    if (ret) {
                        netsnmp_set_request_error(reqinfo, request, ret);
                    }
                    if (*request->requestvb->val.integer == RS_DESTROY) {
                        ci->new_row = -1;
                    }
                }
                break;
            }
            break;

        case MODE_SET_COMMIT:
            if (!ci->have_committed) {
                    /** do this once per row only */
                netSnmpHostsTable_commit_row(&ci->data_context,
                                             ci->new_row);
                ci->have_committed = 1;
            }
            break;

        case MODE_SET_UNDO:
             /** save a variable copy */
            switch (table_info->colnum) {
            case COLUMN_NETSNMPHOSTADDRESSTYPE:
                {
                    int             retval;
                    struct undoInfo *ui;
                    ui = netsnmp_oid_stash_get_data(undoStorage,
                                                    suffix, suffix_len);
                    retval =
                        set_netSnmpHostAddressType(ci->data_context,
                                                   ui->ptr, ui->len);
                    if (retval) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_UNDOFAILED);
                    }
                }
                break;
            case COLUMN_NETSNMPHOSTADDRESS:
                {
                    int             retval;
                    struct undoInfo *ui;
                    ui = netsnmp_oid_stash_get_data(undoStorage,
                                                    suffix, suffix_len);
                    retval =
                        set_netSnmpHostAddress(ci->data_context, ui->ptr,
                                               ui->len);
                    if (retval) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_UNDOFAILED);
                    }
                }
                break;
            case COLUMN_NETSNMPHOSTSTORAGE:
                {
                    int             retval;
                    struct undoInfo *ui;
                    ui = netsnmp_oid_stash_get_data(undoStorage,
                                                    suffix, suffix_len);
                    retval =
                        set_netSnmpHostStorage(ci->data_context, ui->ptr,
                                               ui->len);
                    if (retval) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_UNDOFAILED);
                    }
                }
                break;
            case COLUMN_NETSNMPHOSTROWSTATUS:
                {
                    int             retval;
                    struct undoInfo *ui;
                    ui = netsnmp_oid_stash_get_data(undoStorage,
                                                    suffix, suffix_len);
                    retval =
                        set_netSnmpHostRowStatus(ci->data_context, ui->ptr,
                                                 ui->len);
                    if (retval) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_UNDOFAILED);
                    }
                }
                break;
            }
            break;

        case MODE_SET_FREE:
            break;

        default:
            snmp_log(LOG_ERR,
                     "problem encountered in netSnmpHostsTable_handler: unsupported mode\n");
        }
    }

    /** clean up after all requset processing has ended */
    switch (reqinfo->mode) {
    case MODE_SET_UNDO:
    case MODE_SET_FREE:
    case MODE_SET_COMMIT:
        /** clear out the undo cache */
        netsnmp_oid_stash_free(&undoStorage,
                               netSnmpHostsTable_free_undoInfo);
        netsnmp_oid_stash_free(&commitStorage, netsnmp_oid_stash_no_free);
    }


    return SNMP_ERR_NOERROR;
}
