data_list.c

00001 /*
00002  * netsnmp_data_list.c
00003  *
00004  * $Id: data_list.c 16612 2007-07-16 23:59:44Z hardaker $
00005  */
00006 #include <net-snmp/net-snmp-config.h>
00007 #include <net-snmp/net-snmp-includes.h>
00008 
00009 /*
00010  * prototypes
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"); /* always fail */
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"); /* always fail */
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)                    /* should always be true */
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     /* function which will save the data */
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     /* function which will read the data back in */
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 /* XXX */, 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             /* save begining of line */
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             /* call registered function to save the rest */
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     /* find the stashed information about what we're parsing */
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     /* read in the token */
00346     line =
00347         read_config_read_data(ASN_OCTET_STR, line,
00348                               &dataname, &dataname_len);
00349 
00350     if (!line || !dataname)
00351         return;
00352 
00353     /* call the sub-parser to read the rest */
00354     data = (info->data_list_read_ptr)(line, strlen(line));
00355 
00356     if (!data) {
00357         free(dataname);
00358         return;
00359     }
00360 
00361     /* add to the datalist */
00362     netsnmp_add_list_data(info->datalist,
00363                           netsnmp_create_data_list(dataname, data,
00364                                                    info->data_list_free_ptr));
00365 
00366     return;
00367 }

net-snmpに対してSat Sep 5 13:14:20 2009に生成されました。  doxygen 1.4.7