00001 /* 00002 * netsnmp_data_list.c 00003 * 00004 * $Id: data__list_8c-source.html 17782 2009-09-28 19:33:13Z hardaker $ 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"); /* always fail */ 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"); /* always fail */ 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) /* should always be true */ 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 /* function which will save the data */ 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 /* function which will read the data back in */ 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 /* XXX */, 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 /* save begining of line */ 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 /* call registered function to save the rest */ 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 /* find the stashed information about what we're parsing */ 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 /* read in the token */ 00340 line = 00341 read_config_read_data(ASN_OCTET_STR, line, 00342 &dataname, &dataname_len); 00343 00344 if (!line || !dataname) 00345 return; 00346 00347 /* call the sub-parser to read the rest */ 00348 data = (info->data_list_read_ptr)(line, strlen(line)); 00349 00350 if (!data) { 00351 free(dataname); 00352 return; 00353 } 00354 00355 /* add to the datalist */ 00356 netsnmp_add_list_data(info->datalist, 00357 netsnmp_create_data_list(dataname, data, 00358 info->data_list_free_ptr)); 00359 00360 return; 00361 }
1.5.7.1
Last modified: Monday, 28-Sep-2009 20:19:10 UTC
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.