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

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

static netsnmp_data_list *auto_tables;

typedef struct data_set_tables_s {
    netsnmp_table_data_set *table_set;
} data_set_tables;

typedef struct data_set_cache_s {
    void           *data;
    size_t          data_len;
} data_set_cache;

#define STATE_ACTION   1
#define STATE_COMMIT   2
#define STATE_UNDO     3
#define STATE_FREE     4

typedef struct newrow_stash_s {
    netsnmp_table_row *newrow;
    int             state;
    int             created;
    int             deleted;
} newrow_stash;

/** @defgroup table_dataset table_dataset
 *  Helps you implement a table with automatted storage.
 *  @ingroup table_data
 *
 *  This handler helps you implement a table where all the data is
 *  expected to be stored within the agent itself and not in some
 *  external storage location.  It handles all MIB requests including
 *  GETs, GETNEXTs and SETs.  It's possible to simply create a table
 *  without actually ever defining a handler to be called when SNMP
 *  requests come in.  To use the data, you can either attach a
 *  sub-handler that merely uses/manipulates the data further when
 *  requests come in, or you can loop through it externally when it's
 *  actually needed.  This handler is most useful in cases where a
 *  table is holding configuration data for something which gets
 *  triggered via another event.
 *
 *  NOTE NOTE NOTE: This helper isn't complete and is likely to change
 *  somewhat over time.  Specifically, the way it stores data
 *  internally may change drastically.
 *  
 *  @{
 */

void
netsnmp_init_table_dataset(void) {
#ifndef NETSNMP_DISABLE_MIB_LOADING
    register_app_config_handler("table",
                                netsnmp_config_parse_table_set, NULL,
                                "tableoid");
#endif /* NETSNMP_DISABLE_MIB_LOADING */
    register_app_config_handler("add_row", netsnmp_config_parse_add_row,
                                NULL, "table_name indexes... values...");
}

/* ==================================
 *
 * Data Set API: Table maintenance
 *
 * ================================== */

/** deletes a single dataset table data.
 *  returns the (possibly still good) next pointer of the deleted data object.
 */
NETSNMP_STATIC_INLINE netsnmp_table_data_set_storage *
netsnmp_table_dataset_delete_data(netsnmp_table_data_set_storage *data)
{
    netsnmp_table_data_set_storage *nextPtr = NULL;
    if (data) {
        nextPtr = data->next;
        SNMP_FREE(data->data.voidp);
    }
    SNMP_FREE(data);
    return nextPtr;
}

/** deletes all the data from this node and beyond in the linked list */
NETSNMP_INLINE void
netsnmp_table_dataset_delete_all_data(netsnmp_table_data_set_storage *data)
{

    while (data) {
        data = netsnmp_table_dataset_delete_data(data);
    }
}

/** deletes all the data from this node and beyond in the linked list */
NETSNMP_INLINE void
netsnmp_table_dataset_delete_row(netsnmp_table_row *row)
{
    netsnmp_table_data_set_storage *data;

    if (!row)
        return;

    data = (netsnmp_table_data_set_storage*)netsnmp_table_data_delete_row(row);
    netsnmp_table_dataset_delete_all_data(data);
}

/** adds a new row to a dataset table */
NETSNMP_INLINE void
netsnmp_table_dataset_add_row(netsnmp_table_data_set *table,
                              netsnmp_table_row *row)
{
    if (!table)
        return;
    netsnmp_table_data_add_row(table->table, row);
}

/** adds a new row to a dataset table */
NETSNMP_INLINE void
netsnmp_table_dataset_replace_row(netsnmp_table_data_set *table,
                                  netsnmp_table_row *origrow,
                                  netsnmp_table_row *newrow)
{
    if (!table)
        return;
    netsnmp_table_data_replace_row(table->table, origrow, newrow);
}

/** removes a row from the table, but doesn't delete/free the column values */
NETSNMP_INLINE void
netsnmp_table_dataset_remove_row(netsnmp_table_data_set *table,
                                 netsnmp_table_row *row)
{
    if (!table)
        return;

    netsnmp_table_data_remove_and_delete_row(table->table, row);
}

/** removes a row from the table and then deletes it (and all its data) */
NETSNMP_INLINE void
netsnmp_table_dataset_remove_and_delete_row(netsnmp_table_data_set *table,
                                            netsnmp_table_row *row)
{
    netsnmp_table_data_set_storage *data;

    if (!table)
        return;

    data = (netsnmp_table_data_set_storage *)
        netsnmp_table_data_remove_and_delete_row(table->table, row);

    netsnmp_table_dataset_delete_all_data(data);
}

/** Create a netsnmp_table_data_set structure given a table_data definition */
netsnmp_table_data_set *
netsnmp_create_table_data_set(const char *table_name)
{
    netsnmp_table_data_set *table_set =
        SNMP_MALLOC_TYPEDEF(netsnmp_table_data_set);
    if (!table_set)
        return NULL;
    table_set->table = netsnmp_create_table_data(table_name);
    return table_set;
}

void netsnmp_delete_table_data_set(netsnmp_table_data_set *table_set)
{
    netsnmp_table_data_set_storage *ptr, *next;
    netsnmp_table_row *prow, *pnextrow;

    for (ptr = table_set->default_row; ptr; ptr = next) {
        next = ptr->next;
        free(ptr);
    }
    table_set->default_row = NULL;
    for (prow = table_set->table->first_row; prow; prow = pnextrow) {
        pnextrow = prow->next;
        netsnmp_table_dataset_remove_and_delete_row(table_set, prow);
    }
    table_set->table->first_row = NULL;
    netsnmp_table_data_delete_table(table_set->table);
    free(table_set);
}

/** clones a dataset row, including all data. */
netsnmp_table_row *
netsnmp_table_data_set_clone_row(netsnmp_table_row *row)
{
    netsnmp_table_data_set_storage *data, **newrowdata;
    netsnmp_table_row *newrow;

    if (!row)
        return NULL;

    newrow = netsnmp_table_data_clone_row(row);
    if (!newrow)
        return NULL;

    data = (netsnmp_table_data_set_storage *) row->data;

    if (data) {
        for (newrowdata =
             (netsnmp_table_data_set_storage **) &(newrow->data); data;
             newrowdata = &((*newrowdata)->next), data = data->next) {

            *newrowdata = netsnmp_memdup(data,
                sizeof(netsnmp_table_data_set_storage));
            if (!*newrowdata) {
                netsnmp_table_dataset_delete_row(newrow);
                return NULL;
            }

            if (data->data.voidp) {
                (*newrowdata)->data.voidp =
                    netsnmp_memdup(data->data.voidp, data->data_len);
                if (!(*newrowdata)->data.voidp) {
                    netsnmp_table_dataset_delete_row(newrow);
                    return NULL;
                }
            }
        }
    }
    return newrow;
}

/* ==================================
 *
 * Data Set API: Default row operations
 *
 * ================================== */

/** creates a new row from an existing defined default set */
netsnmp_table_row *
netsnmp_table_data_set_create_row_from_defaults
    (netsnmp_table_data_set_storage *defrow)
{
    netsnmp_table_row *row;
    row = netsnmp_create_table_data_row();
    if (!row)
        return NULL;
    for (; defrow; defrow = defrow->next) {
        netsnmp_set_row_column(row, defrow->column, defrow->type,
                               defrow->data.voidp, defrow->data_len);
        if (defrow->writable)
            netsnmp_mark_row_column_writable(row, defrow->column, 1);

    }
    return row;
}

/** adds a new default row to a table_set.
 * Arguments should be the table_set, column number, variable type and
 * finally a 1 if it is allowed to be writable, or a 0 if not.  If the
 * default_value field is not NULL, it will be used to populate new
 * valuse in that column fro newly created rows. It is copied into the
 * storage template (free your calling argument).
 *
 * returns SNMPERR_SUCCESS or SNMPERR_FAILURE
 */
int
netsnmp_table_set_add_default_row(netsnmp_table_data_set *table_set,
                                  unsigned int column,
                                  int type, int writable,
                                  void *default_value,
                                  size_t default_value_len)
{
    netsnmp_table_data_set_storage *new_col, *ptr, *pptr;

    if (!table_set)
        return SNMPERR_GENERR;

    /*
     * double check 
     */
    new_col =
        netsnmp_table_data_set_find_column(table_set->default_row, column);
    if (new_col != NULL) {
        if (new_col->type == type && new_col->writable == writable)
            return SNMPERR_SUCCESS;
        return SNMPERR_GENERR;
    }

    new_col = SNMP_MALLOC_TYPEDEF(netsnmp_table_data_set_storage);
    if (new_col == NULL)
        return SNMPERR_GENERR;
    new_col->type = type;
    new_col->writable = writable;
    new_col->column = column;
    if (default_value) {
        new_col->data.voidp = netsnmp_memdup(default_value, default_value_len);
        new_col->data_len = default_value_len;
    }
    if (table_set->default_row == NULL)
        table_set->default_row = new_col;
    else {
        /* sort in order just because (needed for add_row support) */
        for (ptr = table_set->default_row, pptr = NULL;
             ptr;
             pptr = ptr, ptr = ptr->next) {
            if (ptr->column > column) {
                new_col->next = ptr;
                if (pptr)
                    pptr->next = new_col;
                else
                    table_set->default_row = new_col;
                return SNMPERR_SUCCESS;
            }
        }
        if (pptr)
            pptr->next = new_col;
        else
            snmp_log(LOG_ERR,"Shouldn't have gotten here: table_dataset/add_row");
    }
    return SNMPERR_SUCCESS;
}

/** adds multiple data column definitions to each row.  Functionally,
 *  this is a wrapper around calling netsnmp_table_set_add_default_row
 *  repeatedly for you.
 */
void
netsnmp_table_set_multi_add_default_row(netsnmp_table_data_set *tset, ...)
{
    va_list         debugargs;
    unsigned int    column;
    int             type, writable;
    void           *data;
    size_t          data_len;

    va_start(debugargs, tset);

    while ((column = va_arg(debugargs, unsigned int)) != 0) {
        type = va_arg(debugargs, int);
        writable = va_arg(debugargs, int);
        data = va_arg(debugargs, void *);
        data_len = va_arg(debugargs, size_t);
        netsnmp_table_set_add_default_row(tset, column, type, writable,
                                          data, data_len);
    }

    va_end(debugargs);
}


/* ==================================
 *
 * Data Set API: MIB maintenance
 *
 * ================================== */

/** Given a netsnmp_table_data_set definition, create a handler for it */
netsnmp_mib_handler *
netsnmp_get_table_data_set_handler(netsnmp_table_data_set *data_set)
{
    netsnmp_mib_handler *ret = NULL;

    if (!data_set) {
        snmp_log(LOG_INFO,
                 "netsnmp_get_table_data_set_handler(NULL) called\n");
        return NULL;
    }

    ret =
        netsnmp_create_handler(TABLE_DATA_SET_NAME,
                               netsnmp_table_data_set_helper_handler);
    if (ret) {
        ret->flags |= MIB_HANDLER_AUTO_NEXT;
        ret->myvoid = (void *) data_set;
    }
    return ret;
}

/** register a given data_set at a given oid (specified in the
    netsnmp_handler_registration pointer).  The
    reginfo->handler->access_method *may* be null if the call doesn't
    ever want to be called for SNMP operations.
*/
int
netsnmp_register_table_data_set(netsnmp_handler_registration *reginfo,
                                netsnmp_table_data_set *data_set,
                                netsnmp_table_registration_info *table_info)
{
    if (NULL == table_info) {
        /*
         * allocate the table if one wasn't allocated 
         */
        table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
        if (table_info == NULL)
            return SNMP_ERR_GENERR;
    }

    if (NULL == table_info->indexes && data_set->table->indexes_template) {
        /*
         * copy the indexes in 
         */
        table_info->indexes =
            snmp_clone_varbind(data_set->table->indexes_template);
    }

    if ((!table_info->min_column || !table_info->max_column) &&
        (data_set->default_row)) {
        /*
         * determine min/max columns 
         */
        unsigned int    mincol = 0xffffffff, maxcol = 0;
        netsnmp_table_data_set_storage *row;

        for (row = data_set->default_row; row; row = row->next) {
            mincol = SNMP_MIN(mincol, row->column);
            maxcol = SNMP_MAX(maxcol, row->column);
        }
        if (!table_info->min_column)
            table_info->min_column = mincol;
        if (!table_info->max_column)
            table_info->max_column = maxcol;
    }

    netsnmp_inject_handler(reginfo,
                           netsnmp_get_table_data_set_handler(data_set));
    return netsnmp_register_table_data(reginfo, data_set->table,
                                       table_info);
}

newrow_stash   *
netsnmp_table_data_set_create_newrowstash
    (netsnmp_table_data_set     *datatable,
     netsnmp_table_request_info *table_info)
{
    newrow_stash   *newrowstash = NULL;
    netsnmp_table_row *newrow   = NULL;

    newrowstash = SNMP_MALLOC_TYPEDEF(newrow_stash);

    if (newrowstash != NULL) {
        newrowstash->created = 1;
        newrow = netsnmp_table_data_set_create_row_from_defaults
            (datatable->default_row);
        newrow->indexes = snmp_clone_varbind(table_info->indexes);
        newrowstash->newrow = newrow;
    }

    return newrowstash;
}

/* implements the table data helper.  This is the routine that takes
 *  care of all SNMP requests coming into the table. */
int
netsnmp_table_data_set_helper_handler(netsnmp_mib_handler *handler,
                                      netsnmp_handler_registration
                                      *reginfo,
                                      netsnmp_agent_request_info *reqinfo,
                                      netsnmp_request_info *requests)
{
    netsnmp_table_data_set_storage *data = NULL;
    newrow_stash   *newrowstash = NULL;
    netsnmp_table_row *row, *newrow = NULL;
    netsnmp_table_request_info *table_info;
    netsnmp_request_info *request;
    netsnmp_oid_stash_node **stashp = NULL;

    if (!handler)
        return SNMPERR_GENERR;
        
    DEBUGMSGTL(("netsnmp_table_data_set", "handler starting\n"));
    for (request = requests; request; request = request->next) {
        netsnmp_table_data_set *datatable =
            (netsnmp_table_data_set *) handler->myvoid;
        const oid * const suffix =
            requests->requestvb->name + reginfo->rootoid_len + 2;
        const size_t suffix_len =
            requests->requestvb->name_length - (reginfo->rootoid_len + 2);

        if (request->processed)
            continue;

        /*
         * extract our stored data and table info 
         */
        row = netsnmp_extract_table_row(request);
        table_info = netsnmp_extract_table_info(request);

        if (MODE_IS_SET(reqinfo->mode)) {

            /*
             * use a cached copy of the row for modification 
             */

            /*
             * cache location: may have been created already by other
             * SET requests in the same master request. 
             */
            stashp = netsnmp_table_dataset_get_or_create_stash(reqinfo,
                                                               datatable,
                                                               table_info);
            if (NULL == stashp) {
                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_GENERR);
                continue;
            }

            newrowstash
                = (newrow_stash*)netsnmp_oid_stash_get_data(*stashp, suffix, suffix_len);

            if (!newrowstash) {
                if (!row) {
                    if (datatable->allow_creation) {
                        /*
                         * entirely new row.  Create the row from the template 
                         */
                        newrowstash =
                             netsnmp_table_data_set_create_newrowstash(
                                                 datatable, table_info);
                        newrow = newrowstash->newrow;
                    } else if (datatable->rowstatus_column == 0) {
                        /*
                         * A RowStatus object may be used to control the
                         *  creation of a new row.  But if this object
                         *  isn't declared (and the table isn't marked as
                         *  'auto-create'), then we can't create a new row.
                         */
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_NOCREATION);
                        continue;
                    }
                } else {
                    /*
                     * existing row that needs to be modified 
                     */
                    newrowstash = SNMP_MALLOC_TYPEDEF(newrow_stash);
                    if (newrowstash == NULL) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_GENERR);
                        continue;
                    }
                    newrow = netsnmp_table_data_set_clone_row(row);
                    newrowstash->newrow = newrow;
                }
                netsnmp_oid_stash_add_data(stashp, suffix, suffix_len,
                                           newrowstash);
            } else {
                newrow = newrowstash->newrow;
            }
            /*
             * all future SET data modification operations use this
             * temp pointer 
             */
            if (reqinfo->mode == MODE_SET_RESERVE1 ||
                reqinfo->mode == MODE_SET_RESERVE2)
                row = newrow;
        }

        if (row)
            data = (netsnmp_table_data_set_storage *) row->data;

        if (!row || !table_info || !data) {
            if (!MODE_IS_SET(reqinfo->mode) || !table_info) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHINSTANCE);
                continue;
            }
        }

        data =
            netsnmp_table_data_set_find_column(data, table_info->colnum);

        switch (reqinfo->mode) {
        case MODE_GET:
        case MODE_GETNEXT:
        case MODE_GETBULK:     /* XXXWWW */
            if (!data || data->type == SNMP_NOSUCHINSTANCE) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHINSTANCE);
            } else {
                /*
                 * Note: data->data.voidp can be NULL, e.g. when a zero-length
                 * octet string has been stored in the table cache.
                 */
                netsnmp_table_data_build_result(reginfo, reqinfo, request,
                                                row,
                                                table_info->colnum,
                                                data->type,
                                       (u_char*)data->data.voidp,
                                                data->data_len);
            }
            break;

        case MODE_SET_RESERVE1:
            if (data) {
                /*
                 * Can we modify the existing row?
                 */
                if (!data->writable) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_NOTWRITABLE);
                } else if (request->requestvb->type != data->type) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGTYPE);
                }
            } else if (datatable->rowstatus_column == table_info->colnum) {
                /*
                 * Otherwise, this is where we create a new row using
                 * the RowStatus object (essentially duplicating the
                 * steps followed earlier in the 'allow_creation' case)
                 */
                switch (*(request->requestvb->val.integer)) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    newrowstash =
                             netsnmp_table_data_set_create_newrowstash(
                                                 datatable, table_info);
                    newrow = newrowstash->newrow;
                    row    = newrow;
                    netsnmp_oid_stash_add_data(stashp, suffix, suffix_len,
                                               newrowstash);
                }
            }
            break;

        case MODE_SET_RESERVE2:
            /*
             * If the agent receives a SET request for an object in a non-existant
             *  row, then the RESERVE1 pass will create the row automatically.
             *
             * But since the row doesn't exist at that point, the test for whether
             *  the object is writable or not will be skipped.  So we need to check
             *  for this possibility again here.
             *
             * Similarly, if row creation is under the control of the RowStatus
             *  object (i.e. allow_creation == 0), but this particular request
             *  doesn't include such an object, then the row won't have been created,
             *  and the writable check will also have been skipped.  Again - check here.
             */
            if (data && data->writable == 0) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOTWRITABLE);
                continue;
            }
            if (datatable->rowstatus_column == table_info->colnum) {
                switch (*(request->requestvb->val.integer)) {
                case RS_ACTIVE:
                case RS_NOTINSERVICE:
                    /*
                     * Can only operate on pre-existing rows.
                     */
                    if (!newrowstash || newrowstash->created) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        continue;
                    }
                    break;

                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    /*
                     * Can only operate on newly created rows.
                     */
                    if (!(newrowstash && newrowstash->created)) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        continue;
                    }
                    break;

                case RS_DESTROY:
                    /*
                     * Can operate on new or pre-existing rows.
                     */
                    break;

                case RS_NOTREADY:
                default:
                    /*
                     * Not a valid value to Set 
                     */
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGVALUE);
                    continue;
                }
            }
            if (!data ) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOCREATION);
                continue;
            }

            /*
             * modify row and set new value 
             */
            SNMP_FREE(data->data.string);
            data->data.string = (u_char *)
                netsnmp_strdup_and_null(request->requestvb->val.string,
                                        request->requestvb->val_len);
            if (!data->data.string) {
                netsnmp_set_request_error(reqinfo, requests,
                                          SNMP_ERR_RESOURCEUNAVAILABLE);
            }
            data->data_len = request->requestvb->val_len;

            if (datatable->rowstatus_column == table_info->colnum) {
                switch (*(request->requestvb->val.integer)) {
                case RS_CREATEANDGO:
                    /*
                     * XXX: check legality 
                     */
                    *(data->data.integer) = RS_ACTIVE;
                    break;

                case RS_CREATEANDWAIT:
                    /*
                     * XXX: check legality 
                     */
                    *(data->data.integer) = RS_NOTINSERVICE;
                    break;

                case RS_DESTROY:
                    newrowstash->deleted = 1;
                    break;
                }
            }
            break;

        case MODE_SET_ACTION:

            /*
             * Install the new row into the stored table.
	     * Do this only *once* per row ....
             */
            if (newrowstash->state != STATE_ACTION) {
                newrowstash->state = STATE_ACTION;
		if (newrowstash->created) {
                    netsnmp_table_dataset_add_row(datatable, newrow);
                } else {
                    netsnmp_table_dataset_replace_row(datatable,
                                                      row, newrow);
                }
            }
            /*
             * ... but every (relevant) varbind in the request will
	     * need to know about this new row, so update the
	     * per-request row information regardless
             */
            if (newrowstash->created) {
		netsnmp_request_add_list_data(request,
			netsnmp_create_data_list(TABLE_DATA_NAME,
						 newrow, NULL));
            }
            break;

        case MODE_SET_UNDO:
            /*
             * extract the new row, replace with the old or delete 
             */
            if (newrowstash->state != STATE_UNDO) {
                newrowstash->state = STATE_UNDO;
                if (newrowstash->created) {
                    netsnmp_table_dataset_remove_and_delete_row(datatable, newrow);
                } else {
                    netsnmp_table_dataset_replace_row(datatable,
                                                      newrow, row);
                    netsnmp_table_dataset_delete_row(newrow);
                }
                newrow = NULL;
            }
            break;

        case MODE_SET_COMMIT:
            if (newrowstash->state != STATE_COMMIT) {
                newrowstash->state = STATE_COMMIT;
                if (!newrowstash->created) {
		    netsnmp_request_info       *req;
                    netsnmp_table_dataset_delete_row(row);

		    /* Walk the request list to update the reference to the old row w/ th new one */
    		    for (req = requests; req; req=req->next) {
        
		    	/*
                         * For requests that have the old row values,
                         * so add the newly-created row information.
                         */
        	    	if ((netsnmp_table_row *) netsnmp_extract_table_row(req) == row) {
	    			netsnmp_request_remove_list_data(req, TABLE_DATA_ROW);
            			netsnmp_request_add_list_data(req,
                		    netsnmp_create_data_list(TABLE_DATA_ROW, newrow, NULL));
        	    	}
    		    }

		    row = NULL;
                }
                if (newrowstash->deleted) {
                    netsnmp_table_dataset_remove_and_delete_row(datatable, newrow);
                    newrow = NULL;
                }
            }
            break;

        case MODE_SET_FREE:
            if (newrowstash && newrowstash->state != STATE_FREE) {
                newrowstash->state = STATE_FREE;
                netsnmp_table_dataset_delete_row(newrow);
		newrow = NULL;
            }
            break;
        }
    }

    /* next handler called automatically - 'AUTO_NEXT' */
    return SNMP_ERR_NOERROR;
}

/**
 * extracts a netsnmp_table_data_set pointer from a given request
 */
NETSNMP_INLINE netsnmp_table_data_set *
netsnmp_extract_table_data_set(netsnmp_request_info *request)
{
    return (netsnmp_table_data_set *)
        netsnmp_request_get_list_data(request, TABLE_DATA_SET_NAME);
}

/**
 * extracts a netsnmp_table_data_set pointer from a given request
 */
netsnmp_table_data_set_storage *
netsnmp_extract_table_data_set_column(netsnmp_request_info *request,
                                     unsigned int column)
{
    netsnmp_table_data_set_storage *data =
        (netsnmp_table_data_set_storage*)netsnmp_extract_table_row_data( request );
    if (data) {
        data = netsnmp_table_data_set_find_column(data, column);
    }
    return data;
}


/* ==================================
 *
 * Data Set API: Config-based operation
 *
 * ================================== */

/** registers a table_dataset so that the "add_row" snmpd.conf token
  * can be used to add data to this table.  If registration_name is
  * NULL then the name used when the table was created will be used
  * instead.
  *
  * @todo create a properly free'ing registeration pointer for the
  * datalist, and get the datalist freed at shutdown.
  */
void
netsnmp_register_auto_data_table(netsnmp_table_data_set *table_set,
                                 char *registration_name)
{
    data_set_tables *tables;
    tables = SNMP_MALLOC_TYPEDEF(data_set_tables);
    if (!tables)
        return;
    tables->table_set = table_set;
    if (!registration_name) {
        registration_name = table_set->table->name;
    }
    netsnmp_add_list_data(&auto_tables, netsnmp_create_data_list(registration_name, tables, NULL));     /* XXX */
}

#ifndef NETSNMP_DISABLE_MIB_LOADING
static void
_table_set_add_indexes(netsnmp_table_data_set *table_set, struct tree *tp)
{
    oid             name[MAX_OID_LEN];
    size_t          name_length = MAX_OID_LEN;
    struct index_list *index;
    struct tree     *indexnode;
    u_char          type;
    int             fixed_len = 0;
    
    /*
     * loop through indexes and add types 
     */
    for (index = tp->indexes; index; index = index->next) {
        if (!snmp_parse_oid(index->ilabel, name, &name_length) ||
            (NULL ==
             (indexnode = get_tree(name, name_length, get_tree_head())))) {
            config_pwarn("can't instatiate table since "
                         "I don't know anything about one index");
            snmp_log(LOG_WARNING, "  index %s not found in tree\n",
                     index->ilabel);
            return;             /* xxx mem leak */
        }
            
        type = mib_to_asn_type(indexnode->type);
        if (type == (u_char) - 1) {
            config_pwarn("unknown index type");
            return;             /* xxx mem leak */
        }
        /*
         * if implied, mark it as such. also mark fixed length
         * octet strings as implied (ie no length prefix) as well.
         * */
        if ((TYPE_OCTETSTR == indexnode->type) &&  /* octet str */
            (NULL != indexnode->ranges) &&         /* & has range */
            (NULL == indexnode->ranges->next) &&   /*   but only one */
            (indexnode->ranges->high ==            /*   & high==low */
             indexnode->ranges->low)) {
            type |= ASN_PRIVATE;
            fixed_len = indexnode->ranges->high;
        }
        else if (index->isimplied)
            type |= ASN_PRIVATE;
        
        DEBUGMSGTL(("table_set_add_table",
                    "adding default index of type %d\n", type));
        netsnmp_table_dataset_add_index(table_set, type);

        /*
         * hack alert: for fixed lenght strings, save the
         * lenght for use during oid parsing.
         */
        if (fixed_len) {
            /*
             * find last (just added) index
             */
            netsnmp_variable_list *var =  table_set->table->indexes_template;
            while (NULL != var->next_variable)
                var = var->next_variable;
            var->val_len = fixed_len;
        }
    }
}
/** @internal */
void
netsnmp_config_parse_table_set(const char *token, char *line)
{
    oid             table_name[MAX_OID_LEN];
    size_t          table_name_length = MAX_OID_LEN;
    struct tree    *tp;
    netsnmp_table_data_set *table_set;
    data_set_tables *tables;
    unsigned int    mincol = 0xffffff, maxcol = 0;
    char           *pos;

    /*
     * instatiate a fake table based on MIB information 
     */
    DEBUGMSGTL(("9:table_set_add_table", "processing '%s'\n", line));
    if (NULL != (pos = strchr(line,' '))) {
        config_pwarn("ignoring extra tokens on line");
        snmp_log(LOG_WARNING,"  ignoring '%s'\n", pos);
        *pos = '\0';
    }

    /*
     * check for duplicate table
     */
    tables = (data_set_tables *) netsnmp_get_list_data(auto_tables, line);
    if (NULL != tables) {
        config_pwarn("duplicate table definition");
        return;
    }

    /*
     * parse oid and find tree structure
     */
    if (!snmp_parse_oid(line, table_name, &table_name_length)) {
        config_pwarn
            ("can't instatiate table since I can't parse the table name");
        return;
    }
    if(NULL == (tp = get_tree(table_name, table_name_length,
                              get_tree_head()))) {
        config_pwarn("can't instatiate table since "
                     "I can't find mib information about it");
        return;
    }

    if (NULL == (tp = tp->child_list) || NULL == tp->child_list) {
        config_pwarn("can't instatiate table since it doesn't appear to be "
                     "a proper table (no children)");
        return;
    }

    table_set = netsnmp_create_table_data_set(line);

    /*
     * check for augments indexes
     */
    if (NULL != tp->augments) {
        oid             name[MAX_OID_LEN];
        size_t          name_length = MAX_OID_LEN;
        struct tree    *tp2;
    
        if (!snmp_parse_oid(tp->augments, name, &name_length)) {
            config_pwarn("I can't parse the augment table name");
            snmp_log(LOG_WARNING, "  can't parse %s\n", tp->augments);
            SNMP_FREE (table_set);
            return;
        }
        if(NULL == (tp2 = get_tree(name, name_length, get_tree_head()))) {
            config_pwarn("can't instatiate table since "
                         "I can't find mib information about augment table");
            snmp_log(LOG_WARNING, "  table %s not found in tree\n",
                     tp->augments);
            SNMP_FREE (table_set);
            return;
        }
        _table_set_add_indexes(table_set, tp2);
    }

    _table_set_add_indexes(table_set, tp);
    
    /*
     * loop through children and add each column info 
     */
    for (tp = tp->child_list; tp; tp = tp->next_peer) {
        int             canwrite = 0;
        u_char          type;
        type = mib_to_asn_type(tp->type);
        if (type == (u_char) - 1) {
            config_pwarn("unknown column type");
	    SNMP_FREE (table_set);
            return;             /* xxx mem leak */
        }

        DEBUGMSGTL(("table_set_add_table",
                    "adding column %s(%ld) of type %d (access %d)\n",
                    tp->label, tp->subid, type, tp->access));

        switch (tp->access) {
        case MIB_ACCESS_CREATE:
            table_set->allow_creation = 1;
            /* fallthrough */
        case MIB_ACCESS_READWRITE:
        case MIB_ACCESS_WRITEONLY:
            canwrite = 1;
            /* fallthrough */
        case MIB_ACCESS_READONLY:
            DEBUGMSGTL(("table_set_add_table",
                        "adding column %ld of type %d\n", tp->subid, type));
            netsnmp_table_set_add_default_row(table_set, tp->subid, type,
                                              canwrite, NULL, 0);
            mincol = SNMP_MIN(mincol, tp->subid);
            maxcol = SNMP_MAX(maxcol, tp->subid);
            break;

        case MIB_ACCESS_NOACCESS:
        case MIB_ACCESS_NOTIFY:
            break;

        default:
            config_pwarn("unknown column access type");
            break;
        }
    }

    /*
     * register the table 
     */
    netsnmp_register_table_data_set(netsnmp_create_handler_registration
                                    (line, NULL, table_name,
                                     table_name_length,
                                     HANDLER_CAN_RWRITE), table_set, NULL);

    netsnmp_register_auto_data_table(table_set, NULL);
}
#endif /* NETSNMP_DISABLE_MIB_LOADING */

/** @internal */
void
netsnmp_config_parse_add_row(const char *token, char *line)
{
    char            buf[SNMP_MAXBUF_MEDIUM];
    char            tname[SNMP_MAXBUF_MEDIUM];
    size_t          buf_size;
    int             rc;

    data_set_tables *tables;
    netsnmp_variable_list *vb;  /* containing only types */
    netsnmp_table_row *row;
    netsnmp_table_data_set_storage *dr;

    line = copy_nword(line, tname, sizeof(tname));

    tables = (data_set_tables *) netsnmp_get_list_data(auto_tables, tname);
    if (!tables) {
        config_pwarn("Unknown table trying to add a row");
        return;
    }

    /*
     * do the indexes first 
     */
    row = netsnmp_create_table_data_row();

    for (vb = tables->table_set->table->indexes_template; vb;
         vb = vb->next_variable) {
        if (!line) {
            config_pwarn("missing an index value");
            SNMP_FREE (row);
            return;
        }

        DEBUGMSGTL(("table_set_add_row", "adding index of type %d\n",
                    vb->type));
        buf_size = sizeof(buf);
        line = read_config_read_memory(vb->type, line, buf, &buf_size);
        netsnmp_table_row_add_index(row, vb->type, buf, buf_size);
    }

    /*
     * then do the data 
     */
    for (dr = tables->table_set->default_row; dr; dr = dr->next) {
        if (!line) {
            config_pwarn("missing a data value. "
                         "All columns must be specified.");
            snmp_log(LOG_WARNING,"  can't find value for column %d\n",
                     dr->column - 1);
            SNMP_FREE (row);
            return;
        }

        buf_size = sizeof(buf);
        line = read_config_read_memory(dr->type, line, buf, &buf_size);
        DEBUGMSGTL(("table_set_add_row",
                    "adding data at column %d of type %d\n", dr->column,
                    dr->type));
        netsnmp_set_row_column(row, dr->column, dr->type, buf, buf_size);
        if (dr->writable)
            netsnmp_mark_row_column_writable(row, dr->column, 1);       /* make writable */
    }
    rc = netsnmp_table_data_add_row(tables->table_set->table, row);
    if (SNMPERR_SUCCESS != rc) {
        config_pwarn("error adding table row");
    }
    if (NULL != line) {
        config_pwarn("extra data value. Too many columns specified.");
        snmp_log(LOG_WARNING,"  extra data '%s'\n", line);
    }
}


netsnmp_oid_stash_node **
netsnmp_table_dataset_get_or_create_stash(netsnmp_agent_request_info *reqinfo,
                                          netsnmp_table_data_set *datatable,
                                          netsnmp_table_request_info *table_info)
{
    netsnmp_oid_stash_node **stashp = NULL;
    char                     buf[256]; /* is this reasonable size?? */
    size_t                   len;
    int                      rc;

    rc = snprintf(buf, sizeof(buf), "dataset_row_stash:%s:",
                  datatable->table->name);
    if ((-1 == rc) || ((size_t)rc >= sizeof(buf))) {
        snmp_log(LOG_ERR,"%s handler name too long\n", datatable->table->name);
        return NULL;
    }

    len = sizeof(buf) - rc;
    rc = snprint_objid(&buf[rc], len, table_info->index_oid,
                       table_info->index_oid_len);
    if (-1 == rc) {
        snmp_log(LOG_ERR,"%s oid or name too long\n", datatable->table->name);
        return NULL;
    }

    stashp = (netsnmp_oid_stash_node **)
        netsnmp_table_get_or_create_row_stash(reqinfo, (u_char *) buf);
    return stashp;
}

netsnmp_table_row *
netsnmp_table_dataset_get_newrow(netsnmp_request_info *request,
                                 netsnmp_agent_request_info *reqinfo,
                                 int rootoid_len,
                                 netsnmp_table_data_set *datatable,
                                 netsnmp_table_request_info *table_info)
{
    oid * const suffix = request->requestvb->name + rootoid_len + 2;
    size_t suffix_len = request->requestvb->name_length - (rootoid_len + 2);
    netsnmp_oid_stash_node **stashp;
    newrow_stash   *newrowstash;

    stashp = netsnmp_table_dataset_get_or_create_stash(reqinfo, datatable,
                                                       table_info);
    if (NULL == stashp)
        return NULL;

    newrowstash = (newrow_stash*)netsnmp_oid_stash_get_data(*stashp, suffix, suffix_len);
    if (NULL == newrowstash)
        return NULL;

    return newrowstash->newrow;
}

/* ==================================
 *
 * Data Set API: Row operations
 *
 * ================================== */

/** returns the first row in the table */
netsnmp_table_row *
netsnmp_table_data_set_get_first_row(netsnmp_table_data_set *table)
{
    return netsnmp_table_data_get_first_row(table->table);
}

/** returns the next row in the table */
netsnmp_table_row *
netsnmp_table_data_set_get_next_row(netsnmp_table_data_set *table,
                                    netsnmp_table_row      *row)
{
    return netsnmp_table_data_get_next_row(table->table, row);
}

int
netsnmp_table_set_num_rows(netsnmp_table_data_set *table)
{
    if (!table)
        return 0;
    return netsnmp_table_data_num_rows(table->table);
}

/* ==================================
 *
 * Data Set API: Column operations
 *
 * ================================== */

/** Finds a column within a given storage set, given the pointer to
   the start of the storage set list.
*/
netsnmp_table_data_set_storage *
netsnmp_table_data_set_find_column(netsnmp_table_data_set_storage *start,
                                   unsigned int column)
{
    while (start && start->column != column)
        start = start->next;
    return start;
}

/**
 * marks a given column in a row as writable or not.
 */
int
netsnmp_mark_row_column_writable(netsnmp_table_row *row, int column,
                                 int writable)
{
    netsnmp_table_data_set_storage *data;

    if (!row)
        return SNMPERR_GENERR;

    data = (netsnmp_table_data_set_storage *) row->data;
    data = netsnmp_table_data_set_find_column(data, column);

    if (!data) {
        /*
         * create it 
         */
        data = SNMP_MALLOC_TYPEDEF(netsnmp_table_data_set_storage);
        if (!data) {
            snmp_log(LOG_CRIT, "no memory in netsnmp_set_row_column");
            return SNMPERR_MALLOC;
        }
        data->column = column;
        data->writable = writable;
        data->next = (struct netsnmp_table_data_set_storage_s*)row->data;
        row->data = data;
    } else {
        data->writable = writable;
    }
    return SNMPERR_SUCCESS;
}

/**
 * Sets a given column in a row with data given a type, value,
 * and length. Data is memdup'ed by the function, at least if
 * type != SNMP_NOSUCHINSTANCE and if value_len > 0.
 *
 * @param[in] row       Pointer to the row to be modified.
 * @param[in] column    Index of the column to be modified.
 * @param[in] type      Either the ASN type of the value to be set or
 *   SNMP_NOSUCHINSTANCE.
 * @param[in] value     If type != SNMP_NOSUCHINSTANCE, pointer to the
 *   new value. May be NULL if value_len == 0, e.g. when storing a
 *   zero-length octet string. Ignored when type == SNMP_NOSUCHINSTANCE.
 * @param[in] value_len If type != SNMP_NOSUCHINSTANCE, number of bytes
 *   occupied by *value. Ignored when type == SNMP_NOSUCHINSTANCE.
 *
 * @return SNMPERR_SUCCESS upon success; SNMPERR_MALLOC when out of memory;
 *   or SNMPERR_GENERR when row == 0 or when type does not match the datatype
 *   of the data stored in *row. 
 *
 */
int
netsnmp_set_row_column(netsnmp_table_row *row, unsigned int column,
                       int type, const void *value, size_t value_len)
{
    netsnmp_table_data_set_storage *data;

    if (!row)
        return SNMPERR_GENERR;

    data = (netsnmp_table_data_set_storage *) row->data;
    data = netsnmp_table_data_set_find_column(data, column);

    if (!data) {
        /*
         * create it 
         */
        data = SNMP_MALLOC_TYPEDEF(netsnmp_table_data_set_storage);
        if (!data) {
            snmp_log(LOG_CRIT, "no memory in netsnmp_set_row_column");
            return SNMPERR_MALLOC;
        }

        data->column = column;
        data->type = type;
        data->next = (struct netsnmp_table_data_set_storage_s*)row->data;
        row->data = data;
    }

    /* Transitions from / to SNMP_NOSUCHINSTANCE are allowed, but no other transitions. */
    if (data->type != type && data->type != SNMP_NOSUCHINSTANCE
        && type != SNMP_NOSUCHINSTANCE)
        return SNMPERR_GENERR;

    /* Return now if neither the type nor the data itself has been modified. */
    if (data->type == type && data->data_len == value_len
        && (value == NULL || memcmp(&data->data.string, value, value_len) == 0))
            return SNMPERR_SUCCESS;

    /* Reallocate memory and store the new value. */
    data->data.voidp = realloc(data->data.voidp, value ? value_len : 0);
    if (value && value_len && !data->data.voidp) {
        data->data_len = 0;
        data->type = SNMP_NOSUCHINSTANCE;
        snmp_log(LOG_CRIT, "no memory in netsnmp_set_row_column");
        return SNMPERR_MALLOC;
    }
    if (value && value_len)
        memcpy(data->data.string, value, value_len);
    data->type = type;
    data->data_len = value_len;
    return SNMPERR_SUCCESS;
}

/* ==================================
 *
 * Data Set API: Index operations
 *
 * ================================== */

/** adds an index to the table.  Call this repeatly for each index. */
void
netsnmp_table_dataset_add_index(netsnmp_table_data_set *table, u_char type)
{
    if (!table)
        return;
    netsnmp_table_data_add_index(table->table, type);
}

/** adds multiple indexes to a table_dataset helper object.
 *  To end the list, use a 0 after the list of ASN index types. */
void
netsnmp_table_set_add_indexes(netsnmp_table_data_set *tset,
                              ...)
{
    va_list         debugargs;
    int             type;

    va_start(debugargs, tset);

    if (tset)
        while ((type = va_arg(debugargs, int)) != 0)
            netsnmp_table_data_add_index(tset->table, (u_char)type);

    va_end(debugargs);
}

/** @} 
 */
