|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* netsnmp_data_list.c
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* Portions of this file are subject to the following copyright(s). See
|
|
Packit |
fcad23 |
* the Net-SNMP's COPYING file for more details and other copyrights
|
|
Packit |
fcad23 |
* that may apply:
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* Portions of this file are copyrighted by:
|
|
Packit |
fcad23 |
* Copyright (c) 2016 VMware, Inc. All rights reserved.
|
|
Packit |
fcad23 |
* Use is subject to license terms specified in the COPYING file
|
|
Packit |
fcad23 |
* distributed with the Net-SNMP package.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
#include <net-snmp/net-snmp-config.h>
|
|
Packit |
fcad23 |
#include <net-snmp/net-snmp-features.h>
|
|
Packit |
fcad23 |
#include <net-snmp/net-snmp-includes.h>
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_feature_child_of(data_list_all, libnetsnmp)
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_feature_child_of(data_list_add_data, data_list_all)
|
|
Packit |
fcad23 |
netsnmp_feature_child_of(data_list_get_list_node, data_list_all)
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** @defgroup data_list generic linked-list data handling with a string as a key.
|
|
Packit |
fcad23 |
* @ingroup library
|
|
Packit |
fcad23 |
* @{
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** frees the data and a name at a given data_list node.
|
|
Packit |
fcad23 |
* Note that this doesn't free the node itself.
|
|
Packit |
fcad23 |
* @param node the node for which the data should be freed
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
NETSNMP_INLINE void
|
|
Packit |
fcad23 |
netsnmp_free_list_data(netsnmp_data_list *node)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
Netsnmp_Free_List_Data *beer;
|
|
Packit |
fcad23 |
if (!node)
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
beer = node->free_func;
|
|
Packit |
fcad23 |
if (beer)
|
|
Packit |
fcad23 |
(beer) (node->data);
|
|
Packit |
fcad23 |
SNMP_FREE(node->name);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** frees all data and nodes in a list.
|
|
Packit |
fcad23 |
* @param head the top node of the list to be freed.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
NETSNMP_INLINE void
|
|
Packit |
fcad23 |
netsnmp_free_all_list_data(netsnmp_data_list *head)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_data_list *tmpptr;
|
|
Packit |
fcad23 |
for (; head;) {
|
|
Packit |
fcad23 |
netsnmp_free_list_data(head);
|
|
Packit |
fcad23 |
tmpptr = head;
|
|
Packit |
fcad23 |
head = head->next;
|
|
Packit |
fcad23 |
SNMP_FREE(tmpptr);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** adds creates a data_list node given a name, data and a free function ptr.
|
|
Packit |
fcad23 |
* @param name the name of the node to cache the data.
|
|
Packit |
fcad23 |
* @param data the data to be stored under that name
|
|
Packit |
fcad23 |
* @param beer A function that can free the data pointer (in the future)
|
|
Packit |
fcad23 |
* @return a newly created data_list node which can be given to the netsnmp_add_list_data function.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
NETSNMP_INLINE netsnmp_data_list *
|
|
Packit |
fcad23 |
netsnmp_create_data_list(const char *name, void *data,
|
|
Packit |
fcad23 |
Netsnmp_Free_List_Data * beer)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_data_list *node;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (!name)
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
node = SNMP_MALLOC_TYPEDEF(netsnmp_data_list);
|
|
Packit |
fcad23 |
if (!node)
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
node->name = strdup(name);
|
|
Packit |
fcad23 |
if (!node->name) {
|
|
Packit |
fcad23 |
free(node);
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
node->data = data;
|
|
Packit |
fcad23 |
node->free_func = beer;
|
|
Packit |
fcad23 |
return node;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** adds data to a datalist
|
|
Packit |
fcad23 |
* @param head a pointer to the head node of a data_list
|
|
Packit |
fcad23 |
* @param node a node to stash in the data_list
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
NETSNMP_INLINE void
|
|
Packit |
fcad23 |
netsnmp_data_list_add_node(netsnmp_data_list **head, netsnmp_data_list *node)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_data_list *ptr;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_assert(NULL != head);
|
|
Packit |
fcad23 |
netsnmp_assert(NULL != node);
|
|
Packit |
fcad23 |
if (!head || !node)
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_assert(NULL != node->name);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(("data_list","adding key '%s'\n", node->name));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (!*head) {
|
|
Packit |
fcad23 |
*head = node;
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (0 == strcmp(node->name, (*head)->name)) {
|
|
Packit |
fcad23 |
netsnmp_assert(!"list key == is unique"); /* always fail */
|
|
Packit |
fcad23 |
snmp_log(LOG_WARNING,
|
|
Packit |
fcad23 |
"WARNING: adding duplicate key '%s' to data list\n",
|
|
Packit |
fcad23 |
node->name);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
for (ptr = *head; ptr->next != NULL; ptr = ptr->next) {
|
|
Packit |
fcad23 |
netsnmp_assert(NULL != ptr->name);
|
|
Packit |
fcad23 |
if (0 == strcmp(node->name, ptr->name)) {
|
|
Packit |
fcad23 |
netsnmp_assert(!"list key == is unique"); /* always fail */
|
|
Packit |
fcad23 |
snmp_log(LOG_WARNING,
|
|
Packit |
fcad23 |
"WARNING: adding duplicate key '%s' to data list\n",
|
|
Packit |
fcad23 |
node->name);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_assert(NULL != ptr);
|
|
Packit |
fcad23 |
if (ptr) /* should always be true */
|
|
Packit |
fcad23 |
ptr->next = node;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** adds data to a datalist
|
|
Packit |
fcad23 |
* @note netsnmp_data_list_add_node is preferred
|
|
Packit |
fcad23 |
* @param head a pointer to the head node of a data_list
|
|
Packit |
fcad23 |
* @param node a node to stash in the data_list
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
/** */
|
|
Packit |
fcad23 |
NETSNMP_INLINE void
|
|
Packit |
fcad23 |
netsnmp_add_list_data(netsnmp_data_list **head, netsnmp_data_list *node)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_data_list_add_node(head, node);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** adds data to a datalist
|
|
Packit |
fcad23 |
* @param head a pointer to the head node of a data_list
|
|
Packit |
fcad23 |
* @param name the name of the node to cache the data.
|
|
Packit |
fcad23 |
* @param data the data to be stored under that name
|
|
Packit |
fcad23 |
* @param beer A function that can free the data pointer (in the future)
|
|
Packit |
fcad23 |
* @return a newly created data_list node which was inserted in the list
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
#ifndef NETSNMP_FEATURE_REMOVE_DATA_LIST_ADD_DATA
|
|
Packit |
fcad23 |
NETSNMP_INLINE netsnmp_data_list *
|
|
Packit |
fcad23 |
netsnmp_data_list_add_data(netsnmp_data_list **head, const char *name,
|
|
Packit |
fcad23 |
void *data, Netsnmp_Free_List_Data * beer)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_data_list *node;
|
|
Packit |
fcad23 |
if (!name) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR,"no name provided.");
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
node = netsnmp_create_data_list(name, data, beer);
|
|
Packit |
fcad23 |
if(NULL == node) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR,"could not allocate memory for node.");
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_add_list_data(head, node);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return node;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif /* NETSNMP_FEATURE_REMOVE_DATA_LIST_ADD_DATA */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** returns a data_list node's data for a given name within a data_list
|
|
Packit |
fcad23 |
* @param head the head node of a data_list
|
|
Packit |
fcad23 |
* @param name the name to find
|
|
Packit |
fcad23 |
* @return a pointer to the data cached at that node
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
NETSNMP_INLINE void *
|
|
Packit |
fcad23 |
netsnmp_get_list_data(netsnmp_data_list *head, const char *name)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
if (!name)
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
for (; head; head = head->next)
|
|
Packit |
fcad23 |
if (head->name && strcmp(head->name, name) == 0)
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
if (head)
|
|
Packit |
fcad23 |
return head->data;
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** returns a data_list node for a given name within a data_list
|
|
Packit |
fcad23 |
* @param head the head node of a data_list
|
|
Packit |
fcad23 |
* @param name the name to find
|
|
Packit |
fcad23 |
* @return a pointer to the data_list node
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
#ifndef NETSNMP_FEATURE_REMOVE_DATA_LIST_GET_LIST_NODE
|
|
Packit |
fcad23 |
NETSNMP_INLINE netsnmp_data_list *
|
|
Packit |
fcad23 |
netsnmp_get_list_node(netsnmp_data_list *head, const char *name)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
if (!name)
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
for (; head; head = head->next)
|
|
Packit |
fcad23 |
if (head->name && strcmp(head->name, name) == 0)
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
if (head)
|
|
Packit |
fcad23 |
return head;
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif /* NETSNMP_FEATURE_REMOVE_DATA_LIST_GET_LIST_NODE */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** Removes a named node from a data_list (and frees it)
|
|
Packit |
fcad23 |
* @param realhead a pointer to the head node of a data_list
|
|
Packit |
fcad23 |
* @param name the name to find and remove
|
|
Packit |
fcad23 |
* @return 0 on successful find-and-delete, 1 otherwise.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
netsnmp_remove_list_node(netsnmp_data_list **realhead, const char *name)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_data_list *head, *prev;
|
|
Packit |
fcad23 |
if (!name)
|
|
Packit |
fcad23 |
return 1;
|
|
Packit |
fcad23 |
for (head = *realhead, prev = NULL; head;
|
|
Packit |
fcad23 |
prev = head, head = head->next) {
|
|
Packit |
fcad23 |
if (head->name && strcmp(head->name, name) == 0) {
|
|
Packit |
fcad23 |
if (prev)
|
|
Packit |
fcad23 |
prev->next = head->next;
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
*realhead = head->next;
|
|
Packit |
fcad23 |
netsnmp_free_list_data(head);
|
|
Packit |
fcad23 |
free(head);
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
return 1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** used to store registered save/parse handlers (specifically, parsing info) */
|
|
Packit |
fcad23 |
static netsnmp_data_list *saveHead;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** registers to store a data_list set of data at persistent storage time
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* @param datalist the data to be saved
|
|
Packit |
fcad23 |
* @param type the name of the application to save the data as. If left NULL the default application name that was registered during the init_snmp call will be used (recommended).
|
|
Packit |
fcad23 |
* @param token the unique token identifier string to use as the first word in the persistent file line.
|
|
Packit |
fcad23 |
* @param data_list_save_ptr a function pointer which will be called to save the rest of the data to a buffer.
|
|
Packit |
fcad23 |
* @param data_list_read_ptr a function pointer which can read the remainder of a saved line and return the application specific void * pointer.
|
|
Packit |
fcad23 |
* @param data_list_free_ptr a function pointer which will be passed to the data node for freeing it in the future when/if the list/node is cleaned up or destroyed.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
netsnmp_register_save_list(netsnmp_data_list **datalist,
|
|
Packit |
fcad23 |
const char *type, const char *token,
|
|
Packit |
fcad23 |
Netsnmp_Save_List_Data *data_list_save_ptr,
|
|
Packit |
fcad23 |
Netsnmp_Read_List_Data *data_list_read_ptr,
|
|
Packit |
fcad23 |
Netsnmp_Free_List_Data *data_list_free_ptr)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_data_list_saveinfo *info;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (!data_list_save_ptr && !data_list_read_ptr)
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
info = SNMP_MALLOC_TYPEDEF(netsnmp_data_list_saveinfo);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (!info) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "couldn't malloc a netsnmp_data_list_saveinfo typedef");
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
info->datalist = datalist;
|
|
Packit |
fcad23 |
info->token = token;
|
|
Packit |
fcad23 |
info->type = type;
|
|
Packit |
fcad23 |
if (!info->type) {
|
|
Packit |
fcad23 |
info->type = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
|
|
Packit |
fcad23 |
NETSNMP_DS_LIB_APPTYPE);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/* function which will save the data */
|
|
Packit |
fcad23 |
info->data_list_save_ptr = data_list_save_ptr;
|
|
Packit |
fcad23 |
if (data_list_save_ptr)
|
|
Packit |
fcad23 |
snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
|
|
Packit |
fcad23 |
netsnmp_save_all_data_callback, info);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/* function which will read the data back in */
|
|
Packit |
fcad23 |
info->data_list_read_ptr = data_list_read_ptr;
|
|
Packit |
fcad23 |
if (data_list_read_ptr) {
|
|
Packit |
fcad23 |
/** @todo netsnmp_register_save_list should handle the same token name being saved from different types? */
|
|
Packit |
fcad23 |
netsnmp_add_list_data(&saveHead,
|
|
Packit |
fcad23 |
netsnmp_create_data_list(token, info, NULL));
|
|
Packit |
fcad23 |
register_config_handler(type, token, netsnmp_read_data_callback,
|
|
Packit |
fcad23 |
NULL /* XXX */, NULL);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
info->data_list_free_ptr = data_list_free_ptr;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** intended to be registerd as a callback operation.
|
|
Packit |
fcad23 |
* It should be registered using:
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA, netsnmp_save_all_data_callback, INFO_POINTER);
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* where INFO_POINTER is a pointer to a netsnmp_data_list_saveinfo object containing apporpriate registration information
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
netsnmp_save_all_data_callback(int major, int minor,
|
|
Packit |
fcad23 |
void *serverarg, void *clientarg) {
|
|
Packit |
fcad23 |
netsnmp_data_list_saveinfo *info = (netsnmp_data_list_saveinfo *)clientarg;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (!clientarg) {
|
|
Packit |
fcad23 |
snmp_log(LOG_WARNING, "netsnmp_save_all_data_callback called with no passed data");
|
|
Packit |
fcad23 |
return SNMP_ERR_NOERROR;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_save_all_data(*(info->datalist), info->type, info->token,
|
|
Packit |
fcad23 |
info->data_list_save_ptr);
|
|
Packit |
fcad23 |
return SNMP_ERR_NOERROR;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** intended to be called as a callback during persistent save operations.
|
|
Packit |
fcad23 |
* See the netsnmp_save_all_data_callback for where this is typically used. */
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
netsnmp_save_all_data(netsnmp_data_list *head,
|
|
Packit |
fcad23 |
const char *type, const char *token,
|
|
Packit |
fcad23 |
Netsnmp_Save_List_Data * data_list_save_ptr)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
char buf[SNMP_MAXBUF], *cp;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
for (; head; head = head->next) {
|
|
Packit |
fcad23 |
if (head->name) {
|
|
Packit |
fcad23 |
/* save begining of line */
|
|
Packit |
fcad23 |
snprintf(buf, sizeof(buf), "%s ", token);
|
|
Packit |
fcad23 |
cp = buf + strlen(buf);
|
|
Packit |
fcad23 |
cp = read_config_save_octet_string(cp, (u_char*)head->name,
|
|
Packit |
fcad23 |
strlen(head->name));
|
|
Packit |
fcad23 |
*cp++ = ' ';
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/* call registered function to save the rest */
|
|
Packit |
fcad23 |
if (!(data_list_save_ptr)(cp,
|
|
Packit |
fcad23 |
sizeof(buf) - strlen(buf),
|
|
Packit |
fcad23 |
head->data)) {
|
|
Packit |
fcad23 |
read_config_store(type, buf);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
return SNMP_ERR_NOERROR;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** intended to be registerd as a .conf parser
|
|
Packit |
fcad23 |
* It should be registered using:
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* register_app_config_handler("token", netsnmp_read_data_callback, XXX)
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* where INFO_POINTER is a pointer to a netsnmp_data_list_saveinfo object
|
|
Packit |
fcad23 |
* containing apporpriate registration information
|
|
Packit |
fcad23 |
* @todo make netsnmp_read_data_callback deal with a free routine
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
netsnmp_read_data_callback(const char *token, char *line) {
|
|
Packit |
fcad23 |
netsnmp_data_list_saveinfo *info;
|
|
Packit |
fcad23 |
char *dataname = NULL;
|
|
Packit |
fcad23 |
size_t dataname_len;
|
|
Packit |
fcad23 |
void *data = NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/* find the stashed information about what we're parsing */
|
|
Packit |
fcad23 |
info = (netsnmp_data_list_saveinfo *) netsnmp_get_list_data(saveHead, token);
|
|
Packit |
fcad23 |
if (!info) {
|
|
Packit |
fcad23 |
snmp_log(LOG_WARNING, "netsnmp_read_data_callback called without previously registered subparser");
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/* read in the token */
|
|
Packit |
fcad23 |
line =
|
|
Packit |
fcad23 |
read_config_read_data(ASN_OCTET_STR, line,
|
|
Packit |
fcad23 |
&dataname, &dataname_len);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (!line || !dataname)
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/* call the sub-parser to read the rest */
|
|
Packit |
fcad23 |
data = (info->data_list_read_ptr)(line, strlen(line));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (!data) {
|
|
Packit |
fcad23 |
free(dataname);
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/* add to the datalist */
|
|
Packit |
fcad23 |
netsnmp_add_list_data(info->datalist,
|
|
Packit |
fcad23 |
netsnmp_create_data_list(dataname, data,
|
|
Packit |
fcad23 |
info->data_list_free_ptr));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
shutdown_data_list(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_free_all_list_data(saveHead);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** @} */
|
|
Packit |
fcad23 |
|