/**************************************************************
 * 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 = "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)
{
}
