00001
00002
00003
00004
00005
00006 #include <net-snmp/net-snmp-config.h>
00007 #include <net-snmp/net-snmp-includes.h>
00008
00018 NETSNMP_INLINE void
00019 netsnmp_free_list_data(netsnmp_data_list *node)
00020 {
00021 Netsnmp_Free_List_Data *beer;
00022 if (!node)
00023 return;
00024
00025 beer = node->free_func;
00026 if (beer)
00027 (beer) (node->data);
00028 SNMP_FREE(node->name);
00029 }
00030
00034 NETSNMP_INLINE void
00035 netsnmp_free_all_list_data(netsnmp_data_list *head)
00036 {
00037 netsnmp_data_list *tmpptr;
00038 for (; head;) {
00039 netsnmp_free_list_data(head);
00040 tmpptr = head;
00041 head = head->next;
00042 SNMP_FREE(tmpptr);
00043 }
00044 }
00045
00052 NETSNMP_INLINE netsnmp_data_list *
00053 netsnmp_create_data_list(const char *name, void *data,
00054 Netsnmp_Free_List_Data * beer)
00055 {
00056 netsnmp_data_list *node;
00057
00058 if (!name)
00059 return NULL;
00060 node = SNMP_MALLOC_TYPEDEF(netsnmp_data_list);
00061 if (!node)
00062 return NULL;
00063 node->name = strdup(name);
00064 node->data = data;
00065 node->free_func = beer;
00066 return node;
00067 }
00068
00073 NETSNMP_INLINE void
00074 netsnmp_data_list_add_node(netsnmp_data_list **head, netsnmp_data_list *node)
00075 {
00076 netsnmp_data_list *ptr;
00077
00078 netsnmp_assert(NULL != head);
00079 netsnmp_assert(NULL != node);
00080 netsnmp_assert(NULL != node->name);
00081
00082 if (!*head) {
00083 *head = node;
00084 return;
00085 }
00086
00087 DEBUGMSGTL(("data_list","adding key '%s'\n", node->name));
00088 if (0 == strcmp(node->name, (*head)->name)) {
00089 netsnmp_assert(!"list key == is unique");
00090 snmp_log(LOG_WARNING,
00091 "WARNING: adding duplicate key '%s' to data list\n",
00092 node->name);
00093 }
00094
00095 for (ptr = *head; ptr->next != NULL; ptr = ptr->next) {
00096 netsnmp_assert(NULL != ptr->name);
00097 if (0 == strcmp(node->name, ptr->name)) {
00098 netsnmp_assert(!"list key == is unique");
00099 snmp_log(LOG_WARNING,
00100 "WARNING: adding duplicate key '%s' to data list\n",
00101 node->name);
00102 }
00103 }
00104
00105 netsnmp_assert(NULL != ptr);
00106 if (ptr)
00107 ptr->next = node;
00108 }
00109
00116 NETSNMP_INLINE void
00117 netsnmp_add_list_data(netsnmp_data_list **head, netsnmp_data_list *node)
00118 {
00119 netsnmp_data_list_add_node(head, node);
00120 }
00121
00129 NETSNMP_INLINE netsnmp_data_list *
00130 netsnmp_data_list_add_data(netsnmp_data_list **head, const char *name,
00131 void *data, Netsnmp_Free_List_Data * beer)
00132 {
00133 netsnmp_data_list *node;
00134 if (!name) {
00135 snmp_log(LOG_ERR,"no name provided.");
00136 return NULL;
00137 }
00138 node = netsnmp_create_data_list(name, data, beer);
00139 if(NULL == node) {
00140 snmp_log(LOG_ERR,"could not allocate memory for node.");
00141 return NULL;
00142 }
00143
00144 netsnmp_add_list_data(head, node);
00145
00146 return node;
00147 }
00148
00154 NETSNMP_INLINE void *
00155 netsnmp_get_list_data(netsnmp_data_list *head, const char *name)
00156 {
00157 if (!name)
00158 return NULL;
00159 for (; head; head = head->next)
00160 if (head->name && strcmp(head->name, name) == 0)
00161 break;
00162 if (head)
00163 return head->data;
00164 return NULL;
00165 }
00166
00172 NETSNMP_INLINE netsnmp_data_list *
00173 netsnmp_get_list_node(netsnmp_data_list *head, const char *name)
00174 {
00175 if (!name)
00176 return NULL;
00177 for (; head; head = head->next)
00178 if (head->name && strcmp(head->name, name) == 0)
00179 break;
00180 if (head)
00181 return head;
00182 return NULL;
00183 }
00184
00190 int
00191 netsnmp_remove_list_node(netsnmp_data_list **realhead, const char *name)
00192 {
00193 netsnmp_data_list *head, *prev;
00194 if (!name)
00195 return 1;
00196 for (head = *realhead, prev = NULL; head;
00197 prev = head, head = head->next) {
00198 if (head->name && strcmp(head->name, name) == 0) {
00199 if (prev)
00200 prev->next = head->next;
00201 else
00202 *realhead = head->next;
00203 netsnmp_free_list_data(head);
00204 free(head);
00205 return 0;
00206 }
00207 }
00208 return 1;
00209 }
00210
00212 static netsnmp_data_list *saveHead;
00213
00223 void
00224 netsnmp_register_save_list(netsnmp_data_list **datalist,
00225 const char *type, const char *token,
00226 Netsnmp_Save_List_Data *data_list_save_ptr,
00227 Netsnmp_Read_List_Data *data_list_read_ptr,
00228 Netsnmp_Free_List_Data *data_list_free_ptr) {
00229 netsnmp_data_list_saveinfo *info =
00230 SNMP_MALLOC_TYPEDEF(netsnmp_data_list_saveinfo);
00231
00232 if (!info) {
00233 snmp_log(LOG_ERR, "couldn't malloc a netsnmp_data_list_saveinfo typedef");
00234 return;
00235 }
00236
00237 info->datalist = datalist;
00238 info->token = token;
00239 info->type = type;
00240 if (!info->type) {
00241 info->type = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
00242 NETSNMP_DS_LIB_APPTYPE);
00243 }
00244
00245
00246 info->data_list_save_ptr = data_list_save_ptr;
00247 if (data_list_save_ptr)
00248 snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
00249 netsnmp_save_all_data_callback, info);
00250
00251
00252 info->data_list_read_ptr = data_list_read_ptr;
00253 if (data_list_read_ptr) {
00255 netsnmp_add_list_data(&saveHead,
00256 netsnmp_create_data_list(token, info, NULL));
00257 register_config_handler(type, token, netsnmp_read_data_callback,
00258 NULL , NULL);
00259 }
00260
00261 info->data_list_free_ptr = data_list_free_ptr;
00262 }
00263
00264
00272 int
00273 netsnmp_save_all_data_callback(int major, int minor,
00274 void *serverarg, void *clientarg) {
00275 netsnmp_data_list_saveinfo *info = (netsnmp_data_list_saveinfo *)clientarg;
00276
00277 if (!clientarg) {
00278 snmp_log(LOG_WARNING, "netsnmp_save_all_data_callback called with no passed data");
00279 return SNMP_ERR_NOERROR;
00280 }
00281
00282 netsnmp_save_all_data(*(info->datalist), info->type, info->token,
00283 info->data_list_save_ptr);
00284 return SNMP_ERR_NOERROR;
00285 }
00286
00289 int
00290 netsnmp_save_all_data(netsnmp_data_list *head,
00291 const char *type, const char *token,
00292 Netsnmp_Save_List_Data * data_list_save_ptr)
00293 {
00294 char buf[SNMP_MAXBUF], *cp;
00295
00296 for (; head; head = head->next) {
00297 if (head->name) {
00298
00299 snprintf(buf, sizeof(buf), "%s ", token);
00300 cp = buf + strlen(buf);
00301 cp = read_config_save_octet_string(cp, (u_char*)head->name,
00302 strlen(head->name));
00303 *cp++ = ' ';
00304
00305
00306 if (!(data_list_save_ptr)(cp,
00307 sizeof(buf) - strlen(buf),
00308 head->data)) {
00309 read_config_store(type, buf);
00310 }
00311 }
00312 }
00313 return SNMP_ERR_NOERROR;
00314 }
00315
00325 void
00326 netsnmp_read_data_callback(const char *token, char *line) {
00327 netsnmp_data_list_saveinfo *info;
00328 char *dataname = NULL;
00329 size_t dataname_len;
00330 void *data = NULL;
00331
00332
00333 info = (netsnmp_data_list_saveinfo *) netsnmp_get_list_data(saveHead, token);
00334 if (!info) {
00335 snmp_log(LOG_WARNING, "netsnmp_read_data_callback called without previously registered subparser");
00336 return;
00337 }
00338
00339
00340 line =
00341 read_config_read_data(ASN_OCTET_STR, line,
00342 &dataname, &dataname_len);
00343
00344 if (!line || !dataname)
00345 return;
00346
00347
00348 data = (info->data_list_read_ptr)(line, strlen(line));
00349
00350 if (!data) {
00351 free(dataname);
00352 return;
00353 }
00354
00355
00356 netsnmp_add_list_data(info->datalist,
00357 netsnmp_create_data_list(dataname, data,
00358 info->data_list_free_ptr));
00359
00360 return;
00361 }