/**************************************************************
 * Copyright (C) 2001 Alex Rozin, Optical Access 
 *
 *                     All Rights Reserved
 *
 * Permission to use, copy, modify and distribute this software and its
 * documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and that
 * both that copyright notice and this permission notice appear in
 * supporting documentation.
 * 
 * ALEX ROZIN DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 * ALEX ROZIN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 ******************************************************************/

#include <net-snmp/net-snmp-config.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>

#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

#include "agutil_api.h"
#include "rows.h"
#include "row_api.h"

#define MAX_CREATION_TIME	60

/*
 * *************************** 
 */
/*
 * static file scope functions 
 */
/*
 * *************************** 
 */

static void
rowapi_delete(RMON_ENTRY_T * eold)
{
    register RMON_ENTRY_T *eptr;
    register RMON_ENTRY_T *prev = NULL;
    TABLE_DEFINTION_T *table_ptr;

    table_ptr = (TABLE_DEFINTION_T *) eold->table_ptr;

    /*
     * delete timout scheduling 
     */
    snmp_alarm_unregister(eold->timer_id);
    ag_trace("Entry %ld in %s has been deleted",
             eold->ctrl_index, table_ptr->name);

    /*
     * It it was valid entry => deactivate it 
     */
    if (RMON1_ENTRY_VALID == eold->status) {
        if (table_ptr->ClbkDeactivate)
            table_ptr->ClbkDeactivate(eold);
    }

    /*
     * delete it in users's sence 
     */
    if (table_ptr->ClbkDelete)
        table_ptr->ClbkDelete((RMON_ENTRY_T *) eold->body);

    if (eold->body) {
        AGFREE(eold->body);
    }

    if (eold->owner)
        AGFREE(eold->owner);

    /*
     * delete it from the list in table 
     */

    table_ptr->current_number_of_entries--;

    for (eptr = table_ptr->first; eptr; eptr = eptr->next) {
        if (eptr == eold)
            break;
        prev = eptr;
    }

    if (prev)
        prev->next = eold->next;
    else
        table_ptr->first = eold->next;

    AGFREE(eold);
}

static void
rowapi_too_long_creation_callback(unsigned int clientreg, void *clientarg)
{
    RMON_ENTRY_T   *eptr;
    TABLE_DEFINTION_T *table_ptr;

    eptr = (RMON_ENTRY_T *) clientarg;
    table_ptr = (TABLE_DEFINTION_T *) eptr->table_ptr;
    if (RMON1_ENTRY_VALID != eptr->status) {
        ag_trace("row #%d in %s was under creation more then %ld sec.",
                 eptr->ctrl_index, table_ptr->name,
                 (long) MAX_CREATION_TIME);
        rowapi_delete(eptr);
    } else {
        snmp_alarm_unregister(eptr->timer_id);
    }
}

static int
rowapi_deactivate(TABLE_DEFINTION_T * table_ptr, RMON_ENTRY_T * eptr)
{
    if (RMON1_ENTRY_UNDER_CREATION == eptr->status) {
        /*
         * nothing to do 
         */
        return SNMP_ERR_NOERROR;
    }

    if (table_ptr->ClbkDeactivate)
        table_ptr->ClbkDeactivate(eptr);
    eptr->status = RMON1_ENTRY_UNDER_CREATION;
    eptr->timer_id = snmp_alarm_register(MAX_CREATION_TIME, 0,
                                         rowapi_too_long_creation_callback,
                                         eptr);
    ag_trace("Entry %ld in %s has been deactivated",
             eptr->ctrl_index, table_ptr->name);

    return SNMP_ERR_NOERROR;
}

static int
rowapi_activate(TABLE_DEFINTION_T * table_ptr, RMON_ENTRY_T * eptr)
{
    RMON1_ENTRY_STATUS_T prev_status = eptr->status;

    eptr->status = RMON1_ENTRY_VALID;

    if (table_ptr->ClbkActivate) {
        if (0 != table_ptr->ClbkActivate(eptr)) {
            ag_trace("Can't activate entry #%ld in %s",
                     eptr->ctrl_index, table_ptr->name);
            eptr->status = prev_status;
            return SNMP_ERR_BADVALUE;
        }
    }

    snmp_alarm_unregister(eptr->timer_id);
    eptr->timer_id = 0;
    ag_trace("Entry %ld in %s has been activated",
             eptr->ctrl_index, table_ptr->name);
    return SNMP_ERR_NOERROR;
}

/*
 * creates an entry, locats it in proper sorted order by index
 * Row is initialized to zero,
 * except: 'next', 'table_ptr', 'index',
 * 'timer_id' & 'status'=(RMON1_ENTRY_UNDER_CREATION)
 * Calls (if need) ClbkCreate.
 * Schedules for timeout under entry creation (id of this
 * scheduling is saved in 'timer_id').
 * Returns 0: OK,
 -1:max. number exedes;
 -2:malloc failed;
 -3:ClbkCreate failed */
int
ROWAPI_new(TABLE_DEFINTION_T * table_ptr, u_long ctrl_index)
{
    register RMON_ENTRY_T *eptr;
    register RMON_ENTRY_T *prev = NULL;
    register RMON_ENTRY_T *enew;

    /*
     * check on 'max.number' 
     */
    if (table_ptr->max_number_of_entries > 0 &&
        table_ptr->current_number_of_entries >=
        table_ptr->max_number_of_entries)
        return -1;

    /*
     * allocate memory for the header 
     */
    enew = (RMON_ENTRY_T *) AGMALLOC(sizeof(RMON_ENTRY_T));
    if (!enew)
        return -2;

    /*
     * init the header 
     */
    memset(enew, 0, sizeof(RMON_ENTRY_T));
    enew->ctrl_index = ctrl_index;
    enew->table_ptr = (void *) table_ptr;
    enew->status = RMON1_ENTRY_UNDER_CREATION;
    enew->only_just_created = 1;

    /*
     * create the body: alloc it and set defaults 
     */
    if (table_ptr->ClbkCreate) {
        if (0 != table_ptr->ClbkCreate(enew)) {
            AGFREE(enew);
            return -3;
        }
    }

    table_ptr->current_number_of_entries++;

    /*
     * find the place : before 'eptr' and after 'prev' 
     */
    for (eptr = table_ptr->first; eptr; eptr = eptr->next) {
        if (ctrl_index < eptr->ctrl_index)
            break;
        prev = eptr;
    }

    /*
     * insert it 
     */
    enew->next = eptr;
    if (prev)
        prev->next = enew;
    else
        table_ptr->first = enew;

    enew->timer_id = snmp_alarm_register(MAX_CREATION_TIME, 0,
                                         rowapi_too_long_creation_callback,
                                         enew);
    ag_trace("Entry %ld in %s has been created",
             enew->ctrl_index, table_ptr->name);
    return 0;
}

/*
 * ****************************** 
 */
/*
 * external usage (API) functions 
 */
/*
 * ****************************** 
 */

void
ROWAPI_init_table(TABLE_DEFINTION_T * table_ptr,
                  char *name,
                  u_long max_number_of_entries,
                  ENTRY_CALLBACK_T * ClbkCreate,
                  ENTRY_CALLBACK_T * ClbkClone,
                  ENTRY_CALLBACK_T * ClbkDelete,
                  ENTRY_CALLBACK_T * ClbkValidate,
                  ENTRY_CALLBACK_T * ClbkActivate,
                  ENTRY_CALLBACK_T * ClbkDeactivate,
                  ENTRY_CALLBACK_T * ClbkCopy)
{
    table_ptr->name = name;
    if (!table_ptr->name)
        table_ptr->name = NETSNMP_REMOVE_CONST(char*,"Unknown");

    table_ptr->max_number_of_entries = max_number_of_entries;
    table_ptr->ClbkCreate = ClbkCreate;
    table_ptr->ClbkClone = ClbkClone;
    table_ptr->ClbkDelete = ClbkDelete;
    table_ptr->ClbkValidate = ClbkValidate;
    table_ptr->ClbkActivate = ClbkActivate;
    table_ptr->ClbkDeactivate = ClbkDeactivate;
    table_ptr->ClbkCopy = ClbkCopy;

    table_ptr->first = NULL;
    table_ptr->current_number_of_entries = 0;
}

void
ROWAPI_delete_clone(TABLE_DEFINTION_T * table_ptr, u_long ctrl_index)
{
    register RMON_ENTRY_T *eptr;

    eptr = ROWAPI_find(table_ptr, ctrl_index);
    if (eptr) {
        if (eptr->new_owner)
            AGFREE(eptr->new_owner);

        if (eptr->tmp) {
            if (table_ptr->ClbkDelete)
                table_ptr->ClbkDelete((RMON_ENTRY_T *) eptr->tmp);
            AGFREE(eptr->tmp);
        }

        if (eptr->only_just_created) {
            rowapi_delete(eptr);
        }
    }
}

RMON_ENTRY_T   *
ROWAPI_get_clone(TABLE_DEFINTION_T * table_ptr,
                 u_long ctrl_index, size_t body_size)
{
    register RMON_ENTRY_T *eptr;

    if (ctrl_index < 1 || ctrl_index > 0xFFFFu) {
        ag_trace("%s: index %ld out of range (1..65535)",
                 table_ptr->name, (long) ctrl_index);
        return NULL;
    }

    /*
     * get it 
     */
    eptr = ROWAPI_find(table_ptr, ctrl_index);

    if (!eptr) {                /* try to create */
        if (0 != ROWAPI_new(table_ptr, ctrl_index)) {
            return NULL;
        }

        /*
         * get it 
         */
        eptr = ROWAPI_find(table_ptr, ctrl_index);
        if (!eptr)              /* it is unbelievable, but ... :( */
            return NULL;
    }

    eptr->new_status = eptr->status;

    eptr->tmp = AGMALLOC(body_size);
    if (!eptr->tmp) {
        if (eptr->only_just_created)
            rowapi_delete(eptr);
        return NULL;
    }

    memcpy(eptr->tmp, eptr->body, body_size);
    if (table_ptr->ClbkClone)
        table_ptr->ClbkClone(eptr);

    if (eptr->new_owner)
        AGFREE(eptr->new_owner);
    return eptr->tmp;
}

RMON_ENTRY_T   *
ROWAPI_first(TABLE_DEFINTION_T * table_ptr)
{
    return table_ptr->first;
}

/*
 * returns an entry with the smallest index
 * which index > prev_index
 */
RMON_ENTRY_T   *
ROWAPI_next(TABLE_DEFINTION_T * table_ptr, u_long prev_index)
{
    register RMON_ENTRY_T *eptr;

    for (eptr = table_ptr->first; eptr; eptr = eptr->next)
        if (eptr->ctrl_index > prev_index)
            return eptr;

    return NULL;
}

RMON_ENTRY_T   *
ROWAPI_find(TABLE_DEFINTION_T * table_ptr, u_long ctrl_index)
{
    register RMON_ENTRY_T *eptr;

    for (eptr = table_ptr->first; eptr; eptr = eptr->next) {
        if (eptr->ctrl_index == ctrl_index)
            return eptr;
        if (eptr->ctrl_index > ctrl_index)
            break;
    }

    return NULL;
}

int
ROWAPI_action_check(TABLE_DEFINTION_T * table_ptr, u_long ctrl_index)
{
    register RMON_ENTRY_T *eptr;

    eptr = ROWAPI_find(table_ptr, ctrl_index);
    if (!eptr) {
        ag_trace("Smth wrong ?");
        return SNMP_ERR_GENERR;
    }

    /*
     * test owner string 
     */
    if (RMON1_ENTRY_UNDER_CREATION != eptr->status) {
        /*
         * Only the same value is allowed 
         */
        if (eptr->new_owner &&
            (!eptr->owner
             || strncmp(eptr->new_owner, eptr->owner, MAX_OWNERSTRING))) {
            ag_trace("invalid owner string in ROWAPI_action_check");
            ag_trace("eptr->new_owner=%p eptr->owner=%p", eptr->new_owner,
                     eptr->owner);
            return SNMP_ERR_BADVALUE;
        }
    }

    switch (eptr->new_status) { /* this status we want to set */
    case RMON1_ENTRY_CREATE_REQUEST:
        if (RMON1_ENTRY_UNDER_CREATION != eptr->status)
            return SNMP_ERR_BADVALUE;
        break;
    case RMON1_ENTRY_INVALID:
        break;
    case RMON1_ENTRY_VALID:
        if (RMON1_ENTRY_VALID == eptr->status) {
            break;              /* nothing to do */
        }
        if (RMON1_ENTRY_UNDER_CREATION != eptr->status) {
            ag_trace("Validate %s: entry %ld has wrong status %d",
                     table_ptr->name, (long) ctrl_index,
                     (int) eptr->status);
            return SNMP_ERR_BADVALUE;
        }

        /*
         * Our MIB understanding extension: we permit to set
         * VALID when entry doesn't exit, in this case PDU has to have
         * the nessessary & valid set of non-default values 
         */
        if (table_ptr->ClbkValidate) {
            return table_ptr->ClbkValidate(eptr);
        }
        break;
    case RMON1_ENTRY_UNDER_CREATION:
        /*
         * Our MIB understanding extension: we permit to travel from 
         * VALID to 'UNDER_CREATION' state 
         */
        break;
    }

    return SNMP_ERR_NOERROR;
}

int
ROWAPI_commit(TABLE_DEFINTION_T * table_ptr, u_long ctrl_index)
{
    register RMON_ENTRY_T *eptr;

    eptr = ROWAPI_find(table_ptr, ctrl_index);
    if (!eptr) {
        ag_trace("Smth wrong ?");
        return SNMP_ERR_GENERR;
    }

    eptr->only_just_created = 0;

    switch (eptr->new_status) { /* this status we want to set */
    case RMON1_ENTRY_CREATE_REQUEST:   /* copy tmp => eprt */
        if (eptr->new_owner) {
            if (eptr->owner)
                AGFREE(eptr->owner);
            eptr->owner = AGSTRDUP(eptr->new_owner);
        }

        if (table_ptr->ClbkCopy && eptr->tmp)
            table_ptr->ClbkCopy(eptr);
        break;
    case RMON1_ENTRY_INVALID:
        ROWAPI_delete_clone(table_ptr, ctrl_index);
        rowapi_delete(eptr);
#if 0                           /* for debug */
        dbg_f_AG_MEM_REPORT();
#endif
        break;
    case RMON1_ENTRY_VALID:    /* copy tmp => eprt and activate */
        /*
         * Our MIB understanding extension: we permit to set
         * VALID when entry doesn't exit, in this case PDU has to have
         * the nessessary & valid set of non-default values 
         */
        if (eptr->new_owner) {
            if (eptr->owner)
                AGFREE(eptr->owner);
            eptr->owner = AGSTRDUP(eptr->new_owner);
        }
        if (table_ptr->ClbkCopy && eptr->tmp)
            table_ptr->ClbkCopy(eptr);
        if (RMON1_ENTRY_VALID != eptr->status) {
            rowapi_activate(table_ptr, eptr);
        }
        break;
    case RMON1_ENTRY_UNDER_CREATION:   /* deactivate (if need) and copy tmp => eprt */
        /*
         * Our MIB understanding extension: we permit to travel from
         * VALID to 'UNDER_CREATION' state 
         */
        rowapi_deactivate(table_ptr, eptr);
        if (eptr->new_owner) {
            if (eptr->owner)
                AGFREE(eptr->owner);
            eptr->owner = AGSTRDUP(eptr->new_owner);
        }
        if (table_ptr->ClbkCopy && eptr->tmp)
            table_ptr->ClbkCopy(eptr);
        break;
    }

    ROWAPI_delete_clone(table_ptr, ctrl_index);
    return SNMP_ERR_NOERROR;
}

RMON_ENTRY_T   *
ROWAPI_header_ControlEntry(struct variable * vp, oid * name,
                           size_t * length, int exact,
                           size_t * var_len,
                           TABLE_DEFINTION_T * table_ptr,
                           void *entry_ptr, size_t entry_size)
{
    long            ctrl_index;
    RMON_ENTRY_T   *hdr = NULL;

    if (0 != AGUTIL_advance_index_name(vp, name, length, exact)) {
        ag_trace("cannot advance_index_name");
        return NULL;
    }

    ctrl_index = vp->namelen >= *length ? 0 : name[vp->namelen];

    if (exact) {
        if (ctrl_index)
            hdr = ROWAPI_find(table_ptr, ctrl_index);
    } else {
        if (ctrl_index)
            hdr = ROWAPI_next(table_ptr, ctrl_index);
        else
            hdr = ROWAPI_first(table_ptr);

        if (hdr) {              /* set new index */
            name[vp->namelen] = hdr->ctrl_index;
            *length = vp->namelen + 1;
        }
    }

    if (hdr)
        memcpy(entry_ptr, hdr->body, entry_size);
    return hdr;
}

int
ROWAPI_do_another_action(oid * name, int tbl_first_index_begin,
                         int action, int *prev_action,
                         TABLE_DEFINTION_T * table_ptr, size_t entry_size)
{
    long            long_temp;
    RMON_ENTRY_T   *tmp;

    if (action == *prev_action)
        return SNMP_ERR_NOERROR;        /* I want to process it only once ! */
    *prev_action = action;

    long_temp = name[tbl_first_index_begin];

    switch (action) {
    case RESERVE1:
        tmp = ROWAPI_get_clone(table_ptr, long_temp, entry_size);
        if (!tmp) {
            ag_trace("RESERVE1: cannot get clone\n");
            return SNMP_ERR_TOOBIG;
        }
        break;

    case FREE:                 /* if RESERVEx failed: release any resources that have been allocated */
    case UNDO:                 /* if ACTION failed: release any resources that have been allocated */
        ROWAPI_delete_clone(table_ptr, long_temp);
        break;

    case ACTION:
        long_temp = ROWAPI_action_check(table_ptr, long_temp);
        if (0 != long_temp)
            return long_temp;
        break;

    case COMMIT:
        long_temp = ROWAPI_commit(table_ptr, long_temp);
        if (0 != long_temp)     /* it MUST NOT be */
            return long_temp;
        break;
    default:
        ag_trace("Unknown action %d", (int) action);
        return SNMP_ERR_GENERR;
    }                           /* of switch by actions */

    return SNMP_ERR_NOERROR;
}

/*
 * data tables API section 
 */

int
ROWDATAAPI_init(SCROLLER_T * scrlr,
                u_long data_requested,
                u_long max_number_of_entries,
                size_t data_size,
                int (*data_destructor) (struct data_scroller *, void *))
{
    scrlr->data_granted = 0;
    scrlr->data_created = 0;
    scrlr->data_total_number = 0;
    scrlr->first_data_ptr =
        scrlr->last_data_ptr = scrlr->current_data_ptr = NULL;

    scrlr->max_number_of_entries = max_number_of_entries;
    scrlr->data_size = data_size;

    scrlr->data_destructor = data_destructor;

    ROWDATAAPI_set_size(scrlr, data_requested, 0);

    return 0;
}

static int
delete_data_entry(SCROLLER_T * scrlr, void *delete_me)
{
    NEXTED_PTR_T   *data_ptr = delete_me;
    register NEXTED_PTR_T *tmp;

    if (data_ptr == scrlr->first_data_ptr) {
        scrlr->first_data_ptr = data_ptr->next;
        if (data_ptr == scrlr->last_data_ptr)
            scrlr->last_data_ptr = NULL;
    } else {                    /* not first */
        for (tmp = scrlr->first_data_ptr; tmp; tmp = tmp->next) {
            if (tmp->next == data_ptr) {
                if (data_ptr == scrlr->last_data_ptr)
                    scrlr->last_data_ptr = tmp;
                tmp->next = data_ptr->next;
                break;
            }
        }                       /* for */
    }                           /* not first */

    if (data_ptr == scrlr->current_data_ptr)
        scrlr->current_data_ptr = data_ptr->next;

    if (scrlr->data_destructor)
        scrlr->data_destructor(scrlr, data_ptr);
    AGFREE(data_ptr);
    scrlr->data_created--;
    scrlr->data_stored--;

    return 0;
}

static void
realloc_number_of_data(SCROLLER_T * scrlr, long dlong)
{
    void           *bptr;       /* DATA_ENTRY_T */
    NEXTED_PTR_T   *prev = NULL;
    void           *first = NULL;

    if (dlong > 0) {
        for (; dlong; dlong--, prev = bptr, scrlr->data_created++) {
            bptr = AGMALLOC(scrlr->data_size);
            if (!bptr) {
                ag_trace("Err: no memory for data");
                break;
            }
            memset(bptr, 0, scrlr->data_size);
            if (prev)
                prev->next = bptr;
            else
                first = bptr;
        }                       /* of loop by malloc bucket */

        if (!scrlr->current_data_ptr)
            scrlr->current_data_ptr = first;
        if (scrlr->last_data_ptr) {
            scrlr->last_data_ptr->next = first;
        } else
            scrlr->first_data_ptr = first;

        scrlr->last_data_ptr = bptr;

    } else {
        for (; dlong && scrlr->data_created > 0; dlong++) {
            if (scrlr->current_data_ptr)
                delete_data_entry(scrlr, scrlr->current_data_ptr);
            else
                delete_data_entry(scrlr, scrlr->first_data_ptr);
        }
    }
}

void
ROWDATAAPI_set_size(SCROLLER_T * scrlr,
                    u_long data_requested, u_char do_allocation)
{
    long            dlong;

    scrlr->data_requested = data_requested;
    scrlr->data_granted = (data_requested < scrlr->max_number_of_entries) ?
        data_requested : scrlr->max_number_of_entries;
    if (do_allocation) {
        dlong = (long) scrlr->data_granted - (long) scrlr->data_created;
        realloc_number_of_data(scrlr, dlong);
    }
}

void
ROWDATAAPI_descructor(SCROLLER_T * scrlr)
{
    register NEXTED_PTR_T *bptr;
    register void  *next;

    for (bptr = scrlr->first_data_ptr; bptr; bptr = next) {
        next = bptr->next;
        if (scrlr->data_destructor)
            scrlr->data_destructor(scrlr, bptr);
        AGFREE(bptr);
    }
    scrlr->data_created = 0;
    scrlr->data_granted = 0;
    scrlr->first_data_ptr =
        scrlr->last_data_ptr = scrlr->current_data_ptr = NULL;
}

void           *
ROWDATAAPI_locate_new_data(SCROLLER_T * scrlr)
{
    register NEXTED_PTR_T *bptr;

    if (!scrlr->current_data_ptr) {     /* there was wrap */
        bptr = scrlr->first_data_ptr;
        if (!bptr) {
            ag_trace("Err: SCROLLER_T:locate_new_data: internal error :(");
            return NULL;
        }
        scrlr->first_data_ptr = bptr->next;
        scrlr->last_data_ptr->next = bptr;
        scrlr->last_data_ptr = (NEXTED_PTR_T *) bptr;
        bptr->next = NULL;
    } else {
        bptr = scrlr->current_data_ptr;
        scrlr->current_data_ptr = bptr->next;
        ++scrlr->data_stored;
    }

    scrlr->data_total_number++;

    return bptr;
}

u_long
ROWDATAAPI_get_total_number(SCROLLER_T * scrlr)
{
    return scrlr->data_total_number;
}

RMON_ENTRY_T   *
ROWDATAAPI_header_DataEntry(struct variable * vp, oid * name,
                            size_t * length, int exact,
                            size_t * var_len,
                            TABLE_DEFINTION_T * table_ptr,
                            SCROLLER_T * (*extract_scroller) (void *body),
                            size_t data_size, void *entry_ptr)
{
    long            ctrl_indx, data_index;
    RMON_ENTRY_T   *hdr = NULL;
    SCROLLER_T     *scrlr;
    NEXTED_PTR_T   *bptr = NULL;
    register u_long iii;

    if (0 != AGUTIL_advance_index_name(vp, name, length, exact)) {
        ag_trace("cannot advance_index_name");
        return NULL;
    }

    ctrl_indx = vp->namelen >= *length ? 0 : name[vp->namelen];
    if (ctrl_indx)
        data_index =
            ((int)(vp->namelen + 1) >= (int)*length) ? 0 : name[vp->namelen + 1];
    else
        data_index = 0;

    if (exact) {
        if (ctrl_indx && data_index) {
            hdr = ROWAPI_find(table_ptr, ctrl_indx);
            if (hdr) {
                scrlr = extract_scroller(hdr->body);
                bptr = scrlr->first_data_ptr;
                for (iii = 0; iii < scrlr->data_stored && bptr;
                     iii++, bptr = bptr->next) {
                    if ((long)bptr->data_index == data_index)
                        break;
                }
                if (!bptr)
                    hdr = NULL;
            }
        }
    } else {
        if (ctrl_indx)
            hdr = ROWAPI_find(table_ptr, ctrl_indx);
        else
            hdr = ROWAPI_first(table_ptr);

        if (hdr) {
            scrlr = extract_scroller(hdr->body);
            /*
             * ag_trace ("get next after (%d %d)", (int) ctrl_indx, (int) data_index); 
             */
            bptr = scrlr->first_data_ptr;
            for (iii = 0; iii < scrlr->data_stored && bptr;
                 iii++, bptr = bptr->next) {
                if (bptr->data_index && (long)bptr->data_index > data_index)
                    break;
            }

            if (bptr && (long)bptr->data_index <= data_index)
                bptr = NULL;

            if (!bptr) {        /* travel to next row */
                /*
                 * ag_trace ("Dbg: travel to next row"); 
                 */
                for (hdr = hdr->next; hdr; hdr = hdr->next) {
                    if (RMON1_ENTRY_VALID != hdr->status)
                        continue;

                    scrlr = extract_scroller(hdr->body);
                    if (scrlr->data_stored <= 0)
                        continue;
                    for (bptr = scrlr->first_data_ptr; bptr;
                         bptr = bptr->next) {
                        if (bptr->data_index)
                            break;
                    }

                    if (bptr)
                        break;
                }
            }
            if (bptr) {         /* set new index */
                /*
                 * ag_trace ("Dbg: So (%d %d)", (int) hdr->index, (int) bptr->data_index); 
                 */
                name[vp->namelen] = hdr->ctrl_index;
                name[vp->namelen + 1] = bptr->data_index;
                *length = vp->namelen + 2;
            } else
                hdr = NULL;
        }
    }

    if (hdr)
        memcpy(entry_ptr, bptr, data_size);
    return hdr;
}

void
init_rows(void)
{
}
