📄 rows.c
字号:
/************************************************************** * 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 voidrowapi_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 voidrowapi_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 introwapi_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 introwapi_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 */intROWAPI_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 *//* * ****************************** */voidROWAPI_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;}voidROWAPI_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;}intROWAPI_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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -