root/src/noit_conf.c

Revision e102af344eb4afacdeeb549fb60d77715f815a53, 7.8 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 6 years ago)

modules actually load now.

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  */
5
6 #include "noit_defines.h"
7
8 #include <stdio.h>
9 #include <assert.h>
10 #include <libxml/parser.h>
11 #include <libxml/tree.h>
12 #include <libxml/xpath.h>
13
14 #include "noit_conf.h"
15 #include "utils/noit_hash.h"
16
17 /* tmp hash impl, replace this with something nice */
18 static noit_hash_table _tmp_config = NOIT_HASH_EMPTY;
19 static xmlDocPtr master_config = NULL;
20 static xmlXPathContextPtr xpath_ctxt = NULL;
21
22 static noit_hash_table _compiled_fallback = NOIT_HASH_EMPTY;
23 static struct {
24   const char *key;
25   const char *val;
26 } config_info[] = {
27   /*
28    * These are compile-time fallbacks to be used in the event
29    * that the current running config does not have values for
30    * these config paths.
31    *
32    * PLEASE: keep them alphabetically sorted.
33    */
34   { "/global/modules/directory", MODULES_DIR },
35
36   { NULL, NULL }
37 };
38
39
40 void noit_conf_init() {
41   int i;
42   for(i = 0; config_info[i].key != NULL; i++) {
43     noit_hash_store(&_compiled_fallback,
44                     strdup(config_info[i].key), strlen(config_info[i].key),
45                     (void *)strdup(config_info[i].val));
46   }
47   xmlInitParser();
48   xmlXPathInit();
49 }
50
51 int noit_conf_load(const char *path) {
52   xmlDocPtr new_config;
53   new_config = xmlParseFile(path);
54   if(new_config) {
55     if(master_config) xmlFreeDoc(master_config);
56     if(xpath_ctxt) xmlXPathFreeContext(xpath_ctxt);
57
58     master_config = new_config;
59     xpath_ctxt = xmlXPathNewContext(master_config);
60     return 0;
61   }
62   return -1;
63 }
64 int noit_conf_save(const char *path) {
65   return -1;
66 }
67
68 noit_hash_table *noit_conf_get_hash(noit_conf_section_t section,
69                                     const char *path) {
70   int i, cnt;
71   noit_hash_table *table;
72   xmlXPathObjectPtr pobj;
73   xmlXPathContextPtr current_ctxt;
74   xmlNodePtr current_node = (xmlNodePtr)section;
75   xmlNodePtr node;
76
77   table = calloc(1, sizeof(*table));
78   current_ctxt = xpath_ctxt;
79   if(current_node) {
80     current_ctxt = xmlXPathNewContext(master_config);
81     current_ctxt->node = current_node;
82   }
83   pobj = xmlXPathEval((xmlChar *)path, current_ctxt);
84   if(!pobj) goto out;
85   if(pobj->type != XPATH_NODESET) goto out;
86   if(xmlXPathNodeSetIsEmpty(pobj->nodesetval)) goto out;
87   cnt = xmlXPathNodeSetGetLength(pobj->nodesetval);
88   for(i=0; i<cnt; i++) {
89     char *value;
90     node = xmlXPathNodeSetItem(pobj->nodesetval, i);
91     value = (char *)xmlXPathCastNodeSetToString(pobj->nodesetval);
92     noit_hash_replace(table,
93                       strdup((char *)node->name), strlen((char *)node->name),
94                       strdup(value), free, free);
95   }
96  out:
97   if(current_ctxt && current_ctxt != xpath_ctxt)
98     xmlXPathFreeContext(current_ctxt);
99   return table;
100 }
101 noit_conf_section_t noit_conf_get_section(noit_conf_section_t section,
102                                           const char *path) {
103   noit_conf_section_t subsection = NULL;
104   xmlXPathObjectPtr pobj;
105   xmlXPathContextPtr current_ctxt;
106   xmlNodePtr current_node = (xmlNodePtr)section;
107
108   current_ctxt = xpath_ctxt;
109   if(current_node) {
110     current_ctxt = xmlXPathNewContext(master_config);
111     current_ctxt->node = current_node;
112   }
113   pobj = xmlXPathEval((xmlChar *)path, current_ctxt);
114   if(!pobj) goto out;
115   if(pobj->type != XPATH_NODESET) goto out;
116   if(xmlXPathNodeSetIsEmpty(pobj->nodesetval)) goto out;
117   subsection = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0);
118  out:
119   if(current_ctxt && current_ctxt != xpath_ctxt)
120     xmlXPathFreeContext(current_ctxt);
121   return subsection;
122 }
123 noit_conf_section_t *noit_conf_get_sections(noit_conf_section_t section,
124                                             const char *path,
125                                             int *cnt) {
126   int i;
127   noit_conf_section_t *sections;
128   xmlXPathObjectPtr pobj;
129   xmlXPathContextPtr current_ctxt;
130   xmlNodePtr current_node = (xmlNodePtr)section;
131
132   *cnt = 0;
133   current_ctxt = xpath_ctxt;
134   if(current_node) {
135     current_ctxt = xmlXPathNewContext(master_config);
136     current_ctxt->node = current_node;
137   }
138   pobj = xmlXPathEval((xmlChar *)path, current_ctxt);
139   if(!pobj) goto out;
140   if(pobj->type != XPATH_NODESET) goto out;
141   if(xmlXPathNodeSetIsEmpty(pobj->nodesetval)) goto out;
142   *cnt = xmlXPathNodeSetGetLength(pobj->nodesetval);
143   sections = calloc(*cnt, sizeof(*sections));
144   for(i=0; i<*cnt; i++)
145     sections[i] = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i);
146  out:
147   if(current_ctxt && current_ctxt != xpath_ctxt)
148     xmlXPathFreeContext(current_ctxt);
149   return sections;
150 }
151 int _noit_conf_get_string(noit_conf_section_t section,
152                           const char *path, char **value) {
153   char *str;
154   int i;
155   xmlXPathObjectPtr pobj;
156   xmlXPathContextPtr current_ctxt;
157   xmlNodePtr current_node = (xmlNodePtr)section;
158
159   current_ctxt = xpath_ctxt;
160   if(current_node) {
161     current_ctxt = xmlXPathNewContext(master_config);
162     current_ctxt->node = current_node;
163   }
164   pobj = xmlXPathEval((xmlChar *)path, current_ctxt);
165   if(pobj) {
166     switch(pobj->type) {
167       case XPATH_NODESET:
168         if(xmlXPathNodeSetIsEmpty(pobj->nodesetval)) return 0;
169         i = xmlXPathNodeSetGetLength(pobj->nodesetval);
170         assert(i == 1);
171         *value = (char *)xmlXPathCastNodeSetToString(pobj->nodesetval);
172         break;
173       default:
174         *value = (char *)xmlXPathCastToString(pobj);
175     }
176     goto found;
177   }
178   if(noit_hash_retrieve(&_compiled_fallback,
179                         path, strlen(path), (void **)&str)) {
180     *value = str;
181     goto found;
182   }
183   return 0;
184  found:
185   if(current_ctxt && current_ctxt != xpath_ctxt)
186     xmlXPathFreeContext(current_ctxt);
187   return 1;
188 }
189 int noit_conf_get_string(noit_conf_section_t section,
190                          const char *path, char **value) {
191   char *str;
192   if(_noit_conf_get_string(section,path,&str)) {
193     *value = strdup(str);
194     return 1;
195   }
196   return 0;
197 }
198 int noit_conf_get_stringbuf(noit_conf_section_t section,
199                             const char *path, char *buf, int len) {
200   char *str;
201   if(_noit_conf_get_string(section,path,&str)) {
202     strlcpy(buf, str, len);
203     return 1;
204   }
205   return 0;
206 }
207 int noit_conf_set_string(noit_conf_section_t section,
208                          const char *path, const char *value) {
209   noit_hash_replace(&_tmp_config,
210                     strdup(path), strlen(path), (void *)strdup(value),
211                     free, free);
212   return 1;
213 }
214 int noit_conf_get_int(noit_conf_section_t section,
215                       const char *path, int *value) {
216   char *str;
217   long longval;
218   if(noit_conf_get_string(section,path,&str)) {
219     int base = 10;
220     if(str[0] == '0') {
221       if(str[1] == 'x') base = 16;
222       else base = 8;
223     }
224     longval = strtol(str, NULL, base);
225     free(str);
226     *value = (int)longval;
227     return 1;
228   }
229   return 0;
230 }
231 int noit_conf_set_int(noit_conf_section_t section,
232                       const char *path, int value) {
233   char buffer[32];
234   snprintf(buffer, 32, "%d", value);
235   return noit_conf_set_string(section,path,buffer);
236 }
237 int noit_conf_get_float(noit_conf_section_t section,
238                         const char *path, float *value) {
239   char *str;
240   if(noit_conf_get_string(section,path,&str)) {
241     *value = atof(str);
242     free(str);
243     return 1;
244   }
245   return 0;
246 }
247 int noit_conf_set_float(noit_conf_section_t section,
248                         const char *path, float value) {
249   char buffer[32];
250   snprintf(buffer, 32, "%f", value);
251   return noit_conf_set_string(section,path,buffer);
252 }
253 int noit_conf_get_boolean(noit_conf_section_t section,
254                           const char *path, noit_conf_boolean *value) {
255   char *str;
256   if(noit_conf_get_string(section,path,&str)) {
257     if(!strcasecmp(str, "true")) *value = noit_true;
258     else *value = noit_false;
259     free(str);
260     return 1;
261   }
262   return 0;
263 }
264 int noit_conf_set_boolean(noit_conf_section_t section,
265                           const char *path, noit_conf_boolean value) {
266   if(value == noit_true)
267     return noit_conf_set_string(section,path,"true");
268   return noit_conf_set_string(section,path,"false");
269 }
270
Note: See TracBrowser for help on using the browser.