/*
 * 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-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "nsModuleTable.h"

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_iterator(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, (u_char *) ctree->context_ptr->context_name,
                       strlen(ctree->context_ptr->context_name));

    vptr = vptr->next_variable;
    snmp_set_var_value(vptr,
                       (u_char *)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, (u_char *) & 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, (u_char *) ctree->context_ptr->context_name,
                       strlen(ctree->context_ptr->context_name));

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

    ultmp = ctree->tree->priority;
    vptr = vptr->next_variable;
    snmp_set_var_value(vptr, (u_char *) & 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;
}
