/*
 * table_array.c
 * $Id$
 */

#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_array.h>

#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif

#include <net-snmp/agent/table.h>
#include <net-snmp/library/container.h>
#include <net-snmp/library/snmp_assert.h>

/*
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_BEGIN        -1 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_RESERVE1     0 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_RESERVE2     1 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_ACTION       2 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_COMMIT       3 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_FREE         4 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_UNDO         5 
 */

static const char *mode_name[] = {
    "Reserve 1",
    "Reserve 2",
    "Action",
    "Commit",
    "Free",
    "Undo"
};

/*
 * PRIVATE structure for holding important info for each table.
 */
typedef struct table_container_data_s {

   /** registration info for the table */
    netsnmp_table_registration_info *tblreg_info;

   /** container for the table rows */
   netsnmp_container          *table;

    /*
     * mutex_type                lock;
     */

   /** do we want to group rows with the same index
    * together when calling callbacks? */
    int             group_rows;

   /** callbacks for this table */
    netsnmp_table_array_callbacks *cb;

} table_container_data;

/** @defgroup table_array table_array
 *  Helps you implement a table when data can be stored locally. The data is stored in a sorted array, using a binary search for lookups.
 *  @ingroup table
 *
 *  The table_array handler is used (automatically) in conjuntion
 *  with the @link table table@endlink handler. It is primarily
 *  intended to be used with the mib2c configuration file
 *  mib2c.array-user.conf.
 *
 *  The code generated by mib2c is useful when you have control of
 *  the data for each row. If you cannot control when rows are added
 *  and deleted (or at least be notified of changes to row data),
 *  then this handler is probably not for you.
 *
 *  This handler makes use of callbacks (function pointers) to
 *  handle various tasks. Code is generated for each callback,
 *  but will need to be reviewed and flushed out by the user.
 *
 *  NOTE NOTE NOTE: Once place where mib2c is somewhat lacking
 *  is with regards to tables with external indices. If your
 *  table makes use of one or more external indices, please
 *  review the generated code very carefully for comments
 *  regarding external indices.
 *
 *  NOTE NOTE NOTE: This helper, the API and callbacks are still
 *  being tested and may change.
 *
 *  The generated code will define a structure for storage of table
 *  related data. This structure must be used, as it contains the index
 *  OID for the row, which is used for keeping the array sorted. You can
 *  add addition fields or data to the structure for your own use.
 *
 *  The generated code will also have code to handle SNMP-SET processing.
 *  If your table does not support any SET operations, simply comment
 *  out the \#define \<PREFIX\>_SET_HANDLING (where \<PREFIX\> is your
 *  table name) in the header file.
 *
 *  SET processing modifies the row in-place. The duplicate_row
 *  callback will be called to save a copy of the original row.
 *  In the event of a failure before the commite phase, the
 *  row_copy callback will be called to restore the original row
 *  from the copy.
 *
 *  Code will be generated to handle row creation. This code may be
 *  disabled by commenting out the \#define \<PREFIX\>_ROW_CREATION
 *  in the header file.
 *
 *  If your table contains a RowStatus object, by default the
 *  code will not allow object in an active row to be modified.
 *  To allow active rows to be modified, remove the comment block
 *  around the \#define \<PREFIX\>_CAN_MODIFY_ACTIVE_ROW in the header
 *  file.
 *
 *  Code will be generated to maintain a secondary index for all
 *  rows, stored in a binary tree. This is very useful for finding
 *  rows by a key other than the OID index. By default, the functions
 *  for maintaining this tree will be based on a character string.
 *  NOTE: this will likely be made into a more generic mechanism,
 *  using new callback methods, in the near future.
 *
 *  The generated code contains many TODO comments. Make sure you
 *  check each one to see if it applies to your code. Examples include
 *  checking indices for syntax (ranges, etc), initializing default
 *  values in newly created rows, checking for row activation and
 *  deactivation requirements, etc.
 *
 * @{
 */

/**********************************************************************
 **********************************************************************
 *                                                                    *
 *                                                                    *
 * PUBLIC Registration functions                                      *
 *                                                                    *
 *                                                                    *
 **********************************************************************
 **********************************************************************/
/** register specified callbacks for the specified table/oid. If the
    group_rows parameter is set, the row related callbacks will be
    called once for each unique row index. Otherwise, each callback
    will be called only once, for all objects.
*/
int
netsnmp_table_container_register(netsnmp_handler_registration *reginfo,
                             netsnmp_table_registration_info *tabreg,
                             netsnmp_table_array_callbacks *cb,
                             netsnmp_container *container,
                             int group_rows)
{
    table_container_data *tad = SNMP_MALLOC_TYPEDEF(table_container_data);
    if (!tad)
        return SNMPERR_GENERR;
    tad->tblreg_info = tabreg;  /* we need it too, but it really is not ours */

    if (!cb) {
        snmp_log(LOG_ERR, "table_array registration with no callbacks\n" );
        free(tad); /* SNMP_FREE is overkill for local var */
        return SNMPERR_GENERR;
    }
    /*
     * check for required callbacks
     */
    if ((cb->can_set &&
         ((NULL==cb->duplicate_row) || (NULL==cb->delete_row) ||
          (NULL==cb->row_copy)) )) {
        snmp_log(LOG_ERR, "table_array registration with incomplete "
                 "callback structure.\n");
        free(tad); /* SNMP_FREE is overkill for local var */
        return SNMPERR_GENERR;
    }

    if (NULL==container) {
        tad->table = netsnmp_container_find("table_array");
        snmp_log(LOG_ERR, "table_array couldn't allocate container\n" );
        free(tad); /* SNMP_FREE is overkill for local var */
        return SNMPERR_GENERR;
    } else
        tad->table = container;
    if (NULL==tad->table->compare)
        tad->table->compare = netsnmp_compare_netsnmp_index;
    if (NULL==tad->table->ncompare)
        tad->table->ncompare = netsnmp_ncompare_netsnmp_index;
    
    tad->cb = cb;

    reginfo->handler->myvoid = tad;

    return netsnmp_register_table(reginfo, tabreg);
}

int
netsnmp_table_array_register(netsnmp_handler_registration *reginfo,
                             netsnmp_table_registration_info *tabreg,
                             netsnmp_table_array_callbacks *cb,
                             netsnmp_container *container,
                             int group_rows)
{
    netsnmp_inject_handler(reginfo,
                           netsnmp_create_handler(reginfo->handlerName,
                               netsnmp_table_array_helper_handler));
    return netsnmp_table_container_register(reginfo, tabreg, cb,
                                            container, group_rows);
}

/** find the handler for the table_array helper. */
netsnmp_mib_handler *
netsnmp_find_table_array_handler(netsnmp_handler_registration *reginfo)
{
    netsnmp_mib_handler *mh;
    if (!reginfo)
        return NULL;
    mh = reginfo->handler;
    while (mh) {
        if (mh->access_method == netsnmp_table_array_helper_handler)
            break;
        mh = mh->next;
    }

    return mh;
}

/** find the context data used by the table_array helper */
netsnmp_container      *
netsnmp_extract_array_context(netsnmp_request_info *request)
{
    return (netsnmp_container*)netsnmp_request_get_list_data(request, TABLE_ARRAY_NAME);
}

/** this function is called to validate RowStatus transitions. */
int
netsnmp_table_array_check_row_status(netsnmp_table_array_callbacks *cb,
                                     netsnmp_request_group *ag,
                                     long *rs_new, long *rs_old)
{
    netsnmp_index *row_ctx;
    netsnmp_index *undo_ctx;
    if (!ag || !cb)
        return SNMPERR_GENERR;
    row_ctx  = ag->existing_row;
    undo_ctx = ag->undo_info;
    
    /*
     * xxx-rks: revisit row delete scenario
     */
    if (row_ctx) {
        /*
         * either a new row, or change to old row
         */
        /*
         * is it set to active?
         */
        if (RS_IS_GOING_ACTIVE(*rs_new)) {
            /*
             * is it ready to be active?
             */
            if ((NULL==cb->can_activate) ||
                cb->can_activate(undo_ctx, row_ctx, ag))
                *rs_new = RS_ACTIVE;
            else
                return SNMP_ERR_INCONSISTENTVALUE;
        } else {
            /*
             * not going active
             */
            if (undo_ctx) {
                /*
                 * change
                 */
                if (RS_IS_ACTIVE(*rs_old)) {
                    /*
                     * check pre-reqs for deactivation
                     */
                    if (cb->can_deactivate &&
                        !cb->can_deactivate(undo_ctx, row_ctx, ag)) {
                        return SNMP_ERR_INCONSISTENTVALUE;
                    }
                }
            } else {
                /*
                 * new row
                 */
            }

            if (*rs_new != RS_DESTROY) {
                if ((NULL==cb->can_activate) ||
                    cb->can_activate(undo_ctx, row_ctx, ag))
                    *rs_new = RS_NOTINSERVICE;
                else
                    *rs_new = RS_NOTREADY;
            } else {
                if (cb->can_delete && !cb->can_delete(undo_ctx, row_ctx, ag)) {
                    return SNMP_ERR_INCONSISTENTVALUE;
                }
                ag->row_deleted = 1;
            }
        }
    } else {
        /*
         * check pre-reqs for delete row
         */
        if (cb->can_delete && !cb->can_delete(undo_ctx, row_ctx, ag)) {
            return SNMP_ERR_INCONSISTENTVALUE;
        }
    }

    return SNMP_ERR_NOERROR;
}

/** @} */

/** @cond */
/**********************************************************************
 **********************************************************************
 **********************************************************************
 **********************************************************************
 *                                                                    *
 *                                                                    *
 *                                                                    *
 *                                                                    *
 * EVERYTHING BELOW THIS IS PRIVATE IMPLEMENTATION DETAILS.           *
 *                                                                    *
 *                                                                    *
 *                                                                    *
 *                                                                    *
 **********************************************************************
 **********************************************************************
 **********************************************************************
 **********************************************************************/

/**********************************************************************
 **********************************************************************
 *                                                                    *
 *                                                                    *
 * Structures, Utility/convenience functions                          *
 *                                                                    *
 *                                                                    *
 **********************************************************************
 **********************************************************************/
/*
 * context info for SET requests
 */
typedef struct set_context_s {
    netsnmp_agent_request_info *agtreq_info;
    table_container_data *tad;
    int             status;
} set_context;

static void
release_netsnmp_request_group(netsnmp_index *g, void *v)
{
    netsnmp_request_group_item *tmp;
    netsnmp_request_group *group = (netsnmp_request_group *) g;

    if (!g)
        return;
    while (group->list) {
        tmp = group->list;
        group->list = tmp->next;
        free(tmp);
    }

    free(group);
}

static void
release_netsnmp_request_groups(void *vp)
{
    netsnmp_container *c = (netsnmp_container*)vp;
    CONTAINER_FOR_EACH(c, (netsnmp_container_obj_func*)
                       release_netsnmp_request_group, NULL);
    CONTAINER_FREE(c);
}

void
build_new_oid(netsnmp_handler_registration *reginfo,
              netsnmp_table_request_info *tblreq_info,
              netsnmp_index *row, netsnmp_request_info *current)
{
    oid             coloid[MAX_OID_LEN];

    if (!tblreq_info || !reginfo || !row || !current)
        return;

    memcpy(coloid, reginfo->rootoid, reginfo->rootoid_len * sizeof(oid));

    /** table.entry */
    coloid[reginfo->rootoid_len] = 1;

    /** table.entry.column */
    coloid[reginfo->rootoid_len + 1] = tblreq_info->colnum;

    /** table.entry.column.index */
    memcpy(&coloid[reginfo->rootoid_len + 2], row->oids,
           row->len * sizeof(oid));

    snmp_set_var_objid(current->requestvb, coloid,
                       reginfo->rootoid_len + 2 + row->len);
}

/**********************************************************************
 **********************************************************************
 *                                                                    *
 *                                                                    *
 * GET procession functions                                           *
 *                                                                    *
 *                                                                    *
 **********************************************************************
 **********************************************************************/
int
process_get_requests(netsnmp_handler_registration *reginfo,
                     netsnmp_agent_request_info *agtreq_info,
                     netsnmp_request_info *requests,
                     table_container_data * tad)
{
    int             rc = SNMP_ERR_NOERROR;
    netsnmp_request_info *current;
    netsnmp_index *row = NULL;
    netsnmp_table_request_info *tblreq_info;
    netsnmp_variable_list *var;

    /*
     * Loop through each of the requests, and
     * try to find the appropriate row from the container.
     */
    for (current = requests; current; current = current->next) {

        var = current->requestvb;
        DEBUGMSGTL(("table_array:get",
                    "  process_get_request oid:"));
        DEBUGMSGOID(("table_array:get", var->name,
                     var->name_length));
        DEBUGMSG(("table_array:get", "\n"));

        /*
         * skip anything that doesn't need processing.
         */
        if (current->processed != 0) {
            DEBUGMSGTL(("table_array:get", "already processed\n"));
            continue;
        }

        /*
         * Get pointer to the table information for this request. This
         * information was saved by table_helper_handler. When
         * debugging, we double check a few assumptions. For example,
         * the table_helper_handler should enforce column boundaries.
         */
        tblreq_info = netsnmp_extract_table_info(current);
        netsnmp_assert(tblreq_info->colnum <= tad->tblreg_info->max_column);

        if ((agtreq_info->mode == MODE_GETNEXT) ||
            (agtreq_info->mode == MODE_GETBULK)) {
            /*
             * find the row
             */
            row = netsnmp_table_index_find_next_row(tad->table, tblreq_info);
            if (!row) {
                /*
                 * no results found.
                 *
                 * xxx-rks: how do we skip this entry for the next handler,
                 * but still allow it a chance to hit another handler?
                 */
                DEBUGMSGTL(("table_array:get", "no row found\n"));
                netsnmp_set_request_error(agtreq_info, current,
                                          SNMP_ENDOFMIBVIEW);
                continue;
            }

            /*
             * * if data was found, make sure it has the column we want
             */
/* xxx-rks: add suport for sparse tables */

            /*
             * build new oid
             */
            build_new_oid(reginfo, tblreq_info, row, current);

        } /** GETNEXT/GETBULK */
        else {
            netsnmp_index index;
            index.oids = tblreq_info->index_oid;
            index.len = tblreq_info->index_oid_len;

            row = (netsnmp_index*)CONTAINER_FIND(tad->table, &index);
            if (!row) {
                DEBUGMSGTL(("table_array:get", "no row found\n"));
                netsnmp_set_request_error(agtreq_info, current,
                                          SNMP_NOSUCHINSTANCE);
                continue;
            }
        } /** GET */

        /*
         * get the data
         */
        rc = tad->cb->get_value(current, row, tblreq_info);

    } /** for ( ... requests ... ) */

    return rc;
}

/**********************************************************************
 **********************************************************************
 *                                                                    *
 *                                                                    *
 * SET procession functions                                           *
 *                                                                    *
 *                                                                    *
 **********************************************************************
 **********************************************************************/

void
group_requests(netsnmp_agent_request_info *agtreq_info,
               netsnmp_request_info *requests,
               netsnmp_container *request_group, table_container_data * tad)
{
    netsnmp_table_request_info *tblreq_info;
    netsnmp_index *row, *tmp, index;
    netsnmp_request_info *current;
    netsnmp_request_group *g;
    netsnmp_request_group_item *i;

    for (current = requests; current; current = current->next) {
        /*
         * skip anything that doesn't need processing.
         */
        if (current->processed != 0) {
            DEBUGMSGTL(("table_array:group",
                        "already processed\n"));
            continue;
        }

        /*
         * 3.2.1 Setup and paranoia
         * *
         * * Get pointer to the table information for this request. This
         * * information was saved by table_helper_handler. When
         * * debugging, we double check a few assumptions. For example,
         * * the table_helper_handler should enforce column boundaries.
         */
        row = NULL;
        tblreq_info = netsnmp_extract_table_info(current);
        netsnmp_assert(tblreq_info->colnum <= tad->tblreg_info->max_column);

        /*
         * search for index
         */
        index.oids = tblreq_info->index_oid;
        index.len = tblreq_info->index_oid_len;
        tmp = (netsnmp_index*)CONTAINER_FIND(request_group, &index);
        if (tmp) {
            DEBUGMSGTL(("table_array:group",
                        "    existing group:"));
            DEBUGMSGOID(("table_array:group", index.oids,
                         index.len));
            DEBUGMSG(("table_array:group", "\n"));
            g = (netsnmp_request_group *) tmp;
            i = SNMP_MALLOC_TYPEDEF(netsnmp_request_group_item);
            if (i == NULL)
                return;
            i->ri = current;
            i->tri = tblreq_info;
            i->next = g->list;
            g->list = i;

            /** xxx-rks: store map of colnum to request */
            continue;
        }

        DEBUGMSGTL(("table_array:group", "    new group"));
        DEBUGMSGOID(("table_array:group", index.oids,
                     index.len));
        DEBUGMSG(("table_array:group", "\n"));
        g = SNMP_MALLOC_TYPEDEF(netsnmp_request_group);
        i = SNMP_MALLOC_TYPEDEF(netsnmp_request_group_item);
        if (i == NULL || g == NULL) {
            SNMP_FREE(i);
            SNMP_FREE(g);
            return;
        }
        g->list = i;
        g->table = tad->table;
        i->ri = current;
        i->tri = tblreq_info;
        /** xxx-rks: store map of colnum to request */

        /*
         * search for row. all changes are made to the original row,
         * later, we'll make a copy in undo_info before we start processing.
         */
        row = g->existing_row = (netsnmp_index*)CONTAINER_FIND(tad->table, &index);
        if (!g->existing_row) {
            if (!tad->cb->create_row) {
                if(MODE_IS_SET(agtreq_info->mode))
                    netsnmp_set_request_error(agtreq_info, current,
                                              SNMP_ERR_NOTWRITABLE);
                else
                    netsnmp_set_request_error(agtreq_info, current,
                                              SNMP_NOSUCHINSTANCE);
                free(g);
                free(i);
                continue;
            }
            /** use undo_info temporarily */
            row = g->existing_row = tad->cb->create_row(&index);
            if (!row) {
                /* xxx-rks : parameter to create_row to allow
                 * for better error reporting. */
                netsnmp_set_request_error(agtreq_info, current,
                                          SNMP_ERR_GENERR);
                free(g);
                free(i);
                continue;
            }
            g->row_created = 1;
        }

        g->index.oids = row->oids;
        g->index.len = row->len;

        CONTAINER_INSERT(request_group, g);

    } /** for( current ... ) */
}

static void
process_set_group(netsnmp_index *o, void *c)
{
    /* xxx-rks: should we continue processing after an error?? */
    set_context           *context = (set_context *) c;
    netsnmp_request_group *ag = (netsnmp_request_group *) o;
    int                    rc = SNMP_ERR_NOERROR;

    switch (context->agtreq_info->mode) {

    case MODE_SET_RESERVE1:/** -> SET_RESERVE2 || SET_FREE */

        /*
         * if not a new row, save undo info
         */
        if (ag->row_created == 0) {
            if (context->tad->cb->duplicate_row)
                ag->undo_info = context->tad->cb->duplicate_row(ag->existing_row);
            else
                ag->undo_info = NULL;
            if (NULL == ag->undo_info) {
                rc = SNMP_ERR_RESOURCEUNAVAILABLE;
                break;
            }
        }
        
        if (context->tad->cb->set_reserve1)
            context->tad->cb->set_reserve1(ag);
        break;

    case MODE_SET_RESERVE2:/** -> SET_ACTION || SET_FREE */
        if (context->tad->cb->set_reserve2)
            context->tad->cb->set_reserve2(ag);
        break;

    case MODE_SET_ACTION:/** -> SET_COMMIT || SET_UNDO */
        if (context->tad->cb->set_action)
            context->tad->cb->set_action(ag);
        break;

    case MODE_SET_COMMIT:/** FINAL CHANCE ON SUCCESS */
        if (ag->row_created == 0) {
            /*
             * this is an existing row, has it been deleted?
             */
            if (ag->row_deleted == 1) {
                DEBUGMSGT((TABLE_ARRAY_NAME, "action: deleting row\n"));
                if (CONTAINER_REMOVE(ag->table, ag->existing_row) != 0) {
                    rc = SNMP_ERR_COMMITFAILED;
                    break;
                }
            }
        } else if (ag->row_deleted == 0) {
            /*
             * new row (that hasn't been deleted) should be inserted
             */
            DEBUGMSGT((TABLE_ARRAY_NAME, "action: inserting row\n"));
            if (CONTAINER_INSERT(ag->table, ag->existing_row) != 0) {
                rc = SNMP_ERR_COMMITFAILED;
                break;
            }
        }

        if (context->tad->cb->set_commit)
            context->tad->cb->set_commit(ag);

        /** no more use for undo_info, so free it */
        if (ag->undo_info) {
            context->tad->cb->delete_row(ag->undo_info);
            ag->undo_info = NULL;
        }

#if 0
        /* XXX-rks: finish row cooperative notifications
         * if the table has requested it, send cooperative notifications
         * for row operations.
         */
        if (context->tad->notifications) {
            if (ag->undo_info) {
                if (!ag->existing_row)
                    netsnmp_monitor_notify(EVENT_ROW_DEL);
                else
                    netsnmp_monitor_notify(EVENT_ROW_MOD);
            }
            else
                netsnmp_monitor_notify(EVENT_ROW_ADD);
        }
#endif

        if ((ag->row_created == 0) && (ag->row_deleted == 1)) {
            context->tad->cb->delete_row(ag->existing_row);
            ag->existing_row = NULL;
        }
        break;

    case MODE_SET_FREE:/** FINAL CHANCE ON FAILURE */
        if (context->tad->cb->set_free)
            context->tad->cb->set_free(ag);

        /** no more use for undo_info, so free it */
        if (ag->row_created == 1) {
            if (context->tad->cb->delete_row)
                context->tad->cb->delete_row(ag->existing_row);
            ag->existing_row = NULL;
        }
        else {
            if (context->tad->cb->delete_row)
                context->tad->cb->delete_row(ag->undo_info);
            ag->undo_info = NULL;
        }
        break;

    case MODE_SET_UNDO:/** FINAL CHANCE ON FAILURE */
        /*
         * status already set - don't change it now
         */
        if (context->tad->cb->set_undo)
            context->tad->cb->set_undo(ag);

        /*
         * no more use for undo_info, so free it
         */
        if (ag->row_created == 0) {
            /*
             * restore old values
             */
            context->tad->cb->row_copy(ag->existing_row, ag->undo_info);
            context->tad->cb->delete_row(ag->undo_info);
            ag->undo_info = NULL;
        }
        else {
            context->tad->cb->delete_row(ag->existing_row);
            ag->existing_row = NULL;
        }
        break;

    default:
        snmp_log(LOG_ERR, "unknown mode processing SET for "
                 "netsnmp_table_array_helper_handler\n");
        rc = SNMP_ERR_GENERR;
        break;
    }
    
    if (rc)
        netsnmp_set_request_error(context->agtreq_info,
                                  ag->list->ri, rc);
                                               
}

int
process_set_requests(netsnmp_agent_request_info *agtreq_info,
                     netsnmp_request_info *requests,
                     table_container_data * tad, char *handler_name)
{
    set_context         context;
    netsnmp_container  *request_group;

    /*
     * create and save structure for set info
     */
    request_group = (netsnmp_container*) netsnmp_agent_get_list_data
        (agtreq_info, handler_name);
    if (request_group == NULL) {
        netsnmp_data_list *tmp;
        request_group = netsnmp_container_find("request_group:"
                                               "table_container");
        request_group->compare = netsnmp_compare_netsnmp_index;
        request_group->ncompare = netsnmp_ncompare_netsnmp_index;

        DEBUGMSGTL(("table_array", "Grouping requests by oid\n"));

        tmp = netsnmp_create_data_list(handler_name,
                                       request_group,
                                       release_netsnmp_request_groups);
        netsnmp_agent_add_list_data(agtreq_info, tmp);
        /*
         * group requests.
         */
        group_requests(agtreq_info, requests, request_group, tad);
    }

    /*
     * process each group one at a time
     */
    context.agtreq_info = agtreq_info;
    context.tad = tad;
    context.status = SNMP_ERR_NOERROR;
    CONTAINER_FOR_EACH(request_group,
                       (netsnmp_container_obj_func*)process_set_group,
                       &context);

    return context.status;
}


/**********************************************************************
 **********************************************************************
 *                                                                    *
 *                                                                    *
 * netsnmp_table_array_helper_handler()                               *
 *                                                                    *
 *                                                                    *
 **********************************************************************
 **********************************************************************/
int
netsnmp_table_array_helper_handler(netsnmp_mib_handler *handler,
                                   netsnmp_handler_registration *reginfo,
                                   netsnmp_agent_request_info *agtreq_info,
                                   netsnmp_request_info *requests)
{

    /*
     * First off, get our pointer from the handler. This
     * lets us get to the table registration information we
     * saved in get_table_array_handler(), as well as the
     * container where the actual table data is stored.
     */
    int             rc = SNMP_ERR_NOERROR;
    table_container_data *tad = (table_container_data *)handler->myvoid;

    if (agtreq_info->mode < 0 || agtreq_info->mode > 5) {
        DEBUGMSGTL(("table_array", "Mode %d, Got request:\n",
                    agtreq_info->mode));
    } else {
        DEBUGMSGTL(("table_array", "Mode %s, Got request:\n",
                    mode_name[agtreq_info->mode]));
    }

    if (MODE_IS_SET(agtreq_info->mode)) {
        /*
         * netsnmp_mutex_lock(&tad->lock);
         */
        rc = process_set_requests(agtreq_info, requests,
                                  tad, handler->handler_name);
        /*
         * netsnmp_mutex_unlock(&tad->lock);
         */
    } else
        rc = process_get_requests(reginfo, agtreq_info, requests, tad);

    if (rc != SNMP_ERR_NOERROR) {
        DEBUGMSGTL(("table_array", "processing returned rc %d\n", rc));
    }
    
    /*
     * Now we've done our processing. If there is another handler below us,
     * call them.
     */
    if (handler->next) {
        rc = netsnmp_call_next_handler(handler, reginfo, agtreq_info, requests);
        if (rc != SNMP_ERR_NOERROR) {
            DEBUGMSGTL(("table_array", "next handler returned rc %d\n", rc));
        }
    }
    
    return rc;
}
/** @endcond */
