/*
 * Note: this file originally auto-generated by mib2c using
 *        : mib2c.iterate.conf,v 1.5 2001/12/04 21:36:27 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 "nsModuleTable.h"

netsnmp_feature_require(table_dataset)

void
nsModuleTable_free(void *context, netsnmp_iterator_info *dont_care)
{
    free(context);
}
    
/** Initialize the nsModuleTable table by defining it's contents and how it's structured */
void
initialize_table_nsModuleTable(void)
{
    const oid nsModuleTable_oid[] = { 1, 3, 6, 1, 4, 1, 8072, 1, 2, 1 };
    netsnmp_table_registration_info *table_info;
    netsnmp_handler_registration *my_handler;
    netsnmp_iterator_info *iinfo;

    /*
     * create the table structure itself 
     */
    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("nsModuleTable",
                                                     nsModuleTable_handler,
                                                     nsModuleTable_oid,
                                                     OID_LENGTH
                                                     (nsModuleTable_oid),
                                                     HANDLER_CAN_RWRITE);

    if (!my_handler || !table_info || !iinfo) {
        if (my_handler)
            netsnmp_handler_registration_free(my_handler);
        SNMP_FREE(table_info);
        SNMP_FREE(iinfo);
        return;                 /* mallocs failed */
    }

    /***************************************************
     * Setting up the table's definition
     */
    netsnmp_table_helper_add_indexes(table_info, ASN_OCTET_STR, /* context name */
                                     ASN_OBJECT_ID,     /* reg point */
                                     ASN_INTEGER,       /* priority */
                                     0);

    table_info->min_column = 4;
    table_info->max_column = 6;

    /*
     * iterator access routines 
     */
    iinfo->get_first_data_point = nsModuleTable_get_first_data_point;
    iinfo->get_next_data_point = nsModuleTable_get_next_data_point;
    iinfo->free_loop_context_at_end = nsModuleTable_free;
    iinfo->table_reginfo = table_info;

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

/** Initializes the nsModuleTable module */
void
init_nsModuleTable(void)
{

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

/** returns the first data point within the nsModuleTable table data.

    Set the my_loop_context variable to the first data point structure
    of your choice (from which you can find the next one).  This could
    be anything from the first node in a linked list, to an integer
    pointer containing the beginning of an array variable.

    Set the my_data_context variable to something to be returned to
    you later that will provide you with the data to return in a given
    row.  This could be the same pointer as what my_loop_context is
    set to, or something different.

    The put_index_data variable contains a list of snmp variable
    bindings, one for each index in your table.  Set the values of
    each appropriately according to the data matching the first row
    and return the put_index_data variable at the end of the function.
*/
typedef struct context_tree_ptr_s {
    netsnmp_subtree *tree;
    subtree_context_cache *context_ptr;
} context_tree_ptr;

netsnmp_variable_list *
nsModuleTable_get_first_data_point(void **my_loop_context,
                                   void **my_data_context,
                                   netsnmp_variable_list * put_index_data,
                                   netsnmp_iterator_info *otherstuff)
{

    struct variable_list *vptr;
    u_long          ultmp;
    context_tree_ptr *ctree;

    ctree = SNMP_MALLOC_TYPEDEF(context_tree_ptr);

    ctree->context_ptr = get_top_context_cache();
    /* Skip empty context registrations */
    while (!ctree->context_ptr->first_subtree) {
        ctree->context_ptr = ctree->context_ptr->next;
        if (!ctree->context_ptr) {
            SNMP_FREE(ctree);
            return NULL;
        }
    }
    ctree->tree = ctree->context_ptr->first_subtree;

    *my_loop_context = ctree;
    *my_data_context = ctree->tree;

    vptr = put_index_data;
    snmp_set_var_value(vptr, ctree->context_ptr->context_name,
                       strlen(ctree->context_ptr->context_name));

    vptr = vptr->next_variable;
    snmp_set_var_value(vptr,
                       ctree->context_ptr->first_subtree->name_a,
                       ctree->context_ptr->first_subtree->namelen *
                       sizeof(oid));

    ultmp = ctree->context_ptr->first_subtree->priority;
    vptr = vptr->next_variable;
    snmp_set_var_value(vptr, & ultmp, sizeof(ultmp));

    return put_index_data;
}

/** functionally the same as nsModuleTable_get_first_data_point, but
   my_loop_context has already been set to a previous value and should
   be updated to the next in the list.  For example, if it was a
   linked list, you might want to cast it and the return
   my_loop_context->next.  The my_data_context pointer should be set
   to something you need later and the indexes in put_index_data
   updated again. */

struct variable_list *
nsModuleTable_get_next_data_point(void **my_loop_context,
                                  void **my_data_context,
                                  struct variable_list *put_index_data,
                                  netsnmp_iterator_info *otherstuff)
{

    struct variable_list *vptr;
    context_tree_ptr *ctree = (context_tree_ptr *) * my_loop_context;
    u_long          ultmp;

    if (ctree->tree->next)
        ctree->tree = ctree->tree->next;
    else {
        ctree->context_ptr = ctree->context_ptr->next;
        if (!ctree->context_ptr) {
            return NULL;
        }
        ctree->tree = ctree->context_ptr->first_subtree;
    }

    *my_data_context = ctree->tree;

    vptr = put_index_data;
    snmp_set_var_value(vptr, ctree->context_ptr->context_name,
                       strlen(ctree->context_ptr->context_name));

    vptr = vptr->next_variable;
    snmp_set_var_value(vptr, ctree->tree->name_a,
                       ctree->tree->namelen * sizeof(oid));

    ultmp = ctree->tree->priority;
    vptr = vptr->next_variable;
    snmp_set_var_value(vptr, & ultmp, sizeof(ultmp));

    return put_index_data;
}

/** handles requests for the nsModuleTable table, if anything else needs to be done */
int
nsModuleTable_handler(netsnmp_mib_handler *handler,
                      netsnmp_handler_registration *reginfo,
                      netsnmp_agent_request_info *reqinfo,
                      netsnmp_request_info *requests)
{

    netsnmp_table_request_info *table_info;
    netsnmp_request_info *request;
    netsnmp_variable_list *var;
    netsnmp_subtree *tree;
    u_long          ultmp;
    u_char          modes[1];

    for (request = requests; request; request = request->next) {
        var = request->requestvb;
        if (request->processed != 0)
            continue;

        /*
         * perform anything here that you need to do.  The request have
         * already been processed by the master table_dataset handler, but
         * this gives you chance to act on the request in some other way if 
         * need be. 
         */

        /*
         * the following extracts the my_data_context pointer set in the
         * loop functions above.  You can then use the results to help
         * return data for the columns of the nsModuleTable table in
         * question 
         */
        tree = (netsnmp_subtree *)netsnmp_extract_iterator_context(request);
        if (tree == NULL) {
            if (reqinfo->mode == MODE_GET) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHINSTANCE);
                continue;
            }
            /*
             * XXX: no row existed, if you support creation and this is a
             * set, start dealing with it here, else continue 
             */
        }

        /*
         * 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) {
            /*
             * the table_iterator helper should change all GETNEXTs into
             * GETs for you automatically, so you don't have to worry
             * about the GETNEXT case.  Only GETs and SETs need to be
             * dealt with here 
             */
        case MODE_GET:
            switch (table_info->colnum) {
            case COLUMN_NSMODULENAME:
		if (tree->reginfo->handlerName) {
                    snmp_set_var_typed_value(var, ASN_OCTET_STR,
                                           tree->reginfo->handlerName,
                                           strlen(tree->reginfo->handlerName));
                } else {
                    snmp_set_var_typed_value(var, ASN_OCTET_STR, "", 0);
		}
                break;

            case COLUMN_NSMODULEMODES:
                /*
                 * basically, these BITS needs to be inverted in order 
                 */
                modes[0] =
                    ((HANDLER_CAN_GETANDGETNEXT & tree->reginfo->
                      modes) << 7) | ((HANDLER_CAN_SET & tree->reginfo->
                                       modes) << 5) | ((HANDLER_CAN_GETBULK
                                                        & tree->reginfo->
                                                        modes) << 3);
		/*  yuck  */
                snmp_set_var_typed_value(var, ASN_OCTET_STR, modes, 1);
                break;

            case COLUMN_NSMODULETIMEOUT:
                ultmp = tree->timeout;
                snmp_set_var_typed_value(var, ASN_INTEGER,
                                         (u_char *) & ultmp,
                                         sizeof(u_long));
                break;

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

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