rows.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:24k
- /**************************************************************
- * 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 "util_funcs.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 clonen");
- 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 = 0;
- } 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)
- {
- }