00001
00002
00003
00004
00005
00006 #include <net-snmp/net-snmp-config.h>
00007 #include <net-snmp/net-snmp-includes.h>
00008
00009
00010
00011
00012 NETSNMP_INLINE void
00013 netsnmp_data_list_add_node(netsnmp_data_list **head, netsnmp_data_list *node);
00014
00015
00025 NETSNMP_INLINE void
00026 netsnmp_free_list_data(netsnmp_data_list *node)
00027 {
00028 Netsnmp_Free_List_Data *beer;
00029 if (!node)
00030 return;
00031
00032 beer = node->free_func;
00033 if (beer)
00034 (beer) (node->data);
00035 SNMP_FREE(node->name);
00036 }
00037
00041 NETSNMP_INLINE void
00042 netsnmp_free_all_list_data(netsnmp_data_list *head)
00043 {
00044 netsnmp_data_list *tmpptr;
00045 for (; head;) {
00046 netsnmp_free_list_data(head);
00047 tmpptr = head;
00048 head = head->next;
00049 SNMP_FREE(tmpptr);
00050 }
00051 }
00052
00059 NETSNMP_INLINE netsnmp_data_list *
00060 netsnmp_create_data_list(const char *name, void *data,
00061 Netsnmp_Free_List_Data * beer)
00062 {
00063 netsnmp_data_list *node;
00064
00065 if (!name)
00066 return NULL;
00067 node = SNMP_MALLOC_TYPEDEF(netsnmp_data_list);
00068 if (!node)
00069 return NULL;
00070 node->name = strdup(name);
00071 node->data = data;
00072 node->free_func = beer;
00073 return node;
00074 }
00075
00082 NETSNMP_INLINE void
00083 netsnmp_add_list_data(netsnmp_data_list **head, netsnmp_data_list *node)
00084 {
00085 netsnmp_data_list_add_node(head, node);
00086 }
00087
00092 NETSNMP_INLINE void
00093 netsnmp_data_list_add_node(netsnmp_data_list **head, netsnmp_data_list *node)
00094 {
00095 netsnmp_data_list *ptr;
00096
00097 netsnmp_assert(NULL != head);
00098 netsnmp_assert(NULL != node);
00099 netsnmp_assert(NULL != node->name);
00100
00101 if (!*head) {
00102 *head = node;
00103 return;
00104 }
00105
00106 DEBUGMSGTL(("data_list","adding key '%s'\n", node->name));
00107 if (0 == strcmp(node->name, (*head)->name)) {
00108 netsnmp_assert(!"list key == is unique");
00109 snmp_log(LOG_WARNING,
00110 "WARNING: adding duplicate key '%s' to data list\n",
00111 node->name);
00112 }
00113
00114 for (ptr = *head; ptr->next != NULL; ptr = ptr->next) {
00115 netsnmp_assert(NULL != ptr->name);
00116 if (0 == strcmp(node->name, ptr->name)) {
00117 netsnmp_assert(!"list key == is unique");
00118 snmp_log(LOG_WARNING,
00119 "WARNING: adding duplicate key '%s' to data list\n",
00120 node->name);
00121 }
00122 }
00123
00124 netsnmp_assert(NULL != ptr);
00125 if (ptr)
00126 ptr->next = node;
00127 }
00128
00136 NETSNMP_INLINE netsnmp_data_list *
00137 netsnmp_data_list_add_data(netsnmp_data_list **head, const char *name,
00138 void *data, Netsnmp_Free_List_Data * beer)
00139 {
00140 netsnmp_data_list *node;
00141 if (!name) {
00142 snmp_log(LOG_ERR,"no name provided.");
00143 return NULL;
00144 }
00145 node = netsnmp_create_data_list(name, data, beer);
00146 if(NULL == node) {
00147 snmp_log(LOG_ERR,"could not allocate memory for node.");
00148 return NULL;
00149 }
00150
00151 netsnmp_add_list_data(head, node);
00152
00153 return node;
00154 }
00155
00161 NETSNMP_INLINE void *
00162 netsnmp_get_list_data(netsnmp_data_list *head, const char *name)
00163 {
00164 if (!name)
00165 return NULL;
00166 for (; head; head = head->next)
00167 if (head->name && strcmp(head->name, name) == 0)
00168 break;
00169 if (head)
00170 return head->data;
00171 return NULL;
00172 }
00173
00179 NETSNMP_INLINE netsnmp_data_list *
00180 netsnmp_get_list_node(netsnmp_data_list *head, const char *name)
00181 {
00182 if (!name)
00183 return NULL;
00184 for (; head; head = head->next)
00185 if (head->name && strcmp(head->name, name) == 0)
00186 break;
00187 if (head)
00188 return head;
00189 return NULL;
00190 }
00191
00197 int
00198 netsnmp_remove_list_node(netsnmp_data_list **realhead, const char *name)
00199 {
00200 netsnmp_data_list *head, *prev;
00201 if (!name)
00202 return 1;
00203 for (head = *realhead, prev = NULL; head;
00204 prev = head, head = head->next) {
00205 if (head->name && strcmp(head->name, name) == 0) {
00206 if (prev)
00207 prev->next = head->next;
00208 else
00209 *realhead = head->next;
00210 netsnmp_free_list_data(head);
00211 free(head);
00212 return 0;
00213 }
00214 }
00215 return 1;
00216 }
00217
00219 static netsnmp_data_list *saveHead;
00220
00230 void
00231 netsnmp_register_save_list(netsnmp_data_list **datalist,
00232 const char *type, const char *token,
00233 Netsnmp_Save_List_Data *data_list_save_ptr,
00234 Netsnmp_Read_List_Data *data_list_read_ptr,
00235 Netsnmp_Free_List_Data *data_list_free_ptr) {
00236 netsnmp_data_list_saveinfo *info =
00237 SNMP_MALLOC_TYPEDEF(netsnmp_data_list_saveinfo);
00238
00239 if (!info) {
00240 snmp_log(LOG_ERR, "couldn't malloc a netsnmp_data_list_saveinfo typedef");
00241 return;
00242 }
00243
00244 info->datalist = datalist;
00245 info->token = token;
00246 info->type = type;
00247 if (!info->type) {
00248 info->type = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
00249 NETSNMP_DS_LIB_APPTYPE);
00250 }
00251
00252
00253 info->data_list_save_ptr = data_list_save_ptr;
00254 if (data_list_save_ptr)
00255 snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
00256 netsnmp_save_all_data_callback, info);
00257
00258
00259 info->data_list_read_ptr = data_list_read_ptr;
00260 if (data_list_read_ptr) {
00262 netsnmp_add_list_data(&saveHead,
00263 netsnmp_create_data_list(token, info, NULL));
00264 register_config_handler(type, token, netsnmp_read_data_callback,
00265 NULL , NULL);
00266 }
00267
00268 info->data_list_free_ptr = data_list_free_ptr;
00269 }
00270
00271
00279 int
00280 netsnmp_save_all_data_callback(int major, int minor,
00281 void *serverarg, void *clientarg) {
00282 netsnmp_data_list_saveinfo *info = clientarg;
00283
00284 if (!clientarg) {
00285 snmp_log(LOG_WARNING, "netsnmp_save_all_data_callback called with no passed data");
00286 return SNMP_ERR_NOERROR;
00287 }
00288
00289 netsnmp_save_all_data(*(info->datalist), info->type, info->token,
00290 info->data_list_save_ptr);
00291 return SNMP_ERR_NOERROR;
00292 }
00293
00296 int
00297 netsnmp_save_all_data(netsnmp_data_list *head,
00298 const char *type, const char *token,
00299 Netsnmp_Save_List_Data * data_list_save_ptr)
00300 {
00301 char buf[SNMP_MAXBUF], *cp;
00302
00303 for (; head; head = head->next) {
00304 if (head->name) {
00305
00306 snprintf(buf, sizeof(buf), "%s ", token);
00307 cp = buf + strlen(buf);
00308 cp = read_config_save_octet_string(cp, (u_char*)head->name,
00309 strlen(head->name));
00310 *cp++ = ' ';
00311
00312
00313 if (!(data_list_save_ptr)(cp,
00314 sizeof(buf) - strlen(buf),
00315 head->data)) {
00316 read_config_store(type, buf);
00317 }
00318 }
00319 }
00320 return SNMP_ERR_NOERROR;
00321 }
00322
00331 void
00332 netsnmp_read_data_callback(const char *token, char *line) {
00333 netsnmp_data_list_saveinfo *info;
00334 char *dataname = NULL;
00335 size_t dataname_len;
00336 void *data = NULL;
00337
00338
00339 info = netsnmp_get_list_data(saveHead, token);
00340 if (!info) {
00341 snmp_log(LOG_WARNING, "netsnmp_read_data_callback called without previously registered subparser");
00342 return;
00343 }
00344
00345
00346 line =
00347 read_config_read_data(ASN_OCTET_STR, line,
00348 &dataname, &dataname_len);
00349
00350 if (!line || !dataname)
00351 return;
00352
00353
00354 data = (info->data_list_read_ptr)(line, strlen(line));
00355
00356 if (!data) {
00357 free(dataname);
00358 return;
00359 }
00360
00361
00362 netsnmp_add_list_data(info->datalist,
00363 netsnmp_create_data_list(dataname, data,
00364 info->data_list_free_ptr));
00365
00366 return;
00367 }