PageRenderTime 42ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/fpm/xml_config.c

http://github.com/dreamcat4/php-fpm
C | 278 lines | 212 code | 64 blank | 2 comment | 49 complexity | 4c59d6414a78eb59f769a7c0ee0a53ce MD5 | raw file
  1. /* $Id: xml_config.c,v 1.9 2008/08/26 15:09:15 anight Exp $ */
  2. /* (c) 2004-2007 Andrei Nigmatulin */
  3. #include "fpm_config.h"
  4. #ifdef HAVE_ALLOCA_H
  5. #include <alloca.h>
  6. #endif
  7. #include <string.h>
  8. #include <stdio.h>
  9. #include <stddef.h>
  10. #include <stdlib.h>
  11. #include <libxml/parser.h>
  12. #include <libxml/tree.h>
  13. #include "xml_config.h"
  14. static struct xml_conf_section **xml_conf_sections = 0;
  15. static int xml_conf_sections_allocated = 0;
  16. static int xml_conf_sections_used = 0;
  17. char *xml_conf_set_slot_boolean(void **conf, char *name, void *vv, intptr_t offset)
  18. {
  19. char *value = vv;
  20. long value_y = !strcasecmp(value, "yes") || !strcmp(value, "1") || !strcasecmp(value, "on");
  21. long value_n = !strcasecmp(value, "no") || !strcmp(value, "0") || !strcasecmp(value, "off");
  22. if (!value_y && !value_n) {
  23. return "xml_conf_set_slot(): invalid boolean value";
  24. }
  25. #ifdef XML_CONF_DEBUG
  26. fprintf(stderr, "setting boolean '%s' => %s\n", name, value_y ? "TRUE" : "FALSE");
  27. #endif
  28. * (int *) ((char *) *conf + offset) = value_y ? 1 : 0;
  29. return NULL;
  30. }
  31. char *xml_conf_set_slot_string(void **conf, char *name, void *vv, intptr_t offset)
  32. {
  33. char *value = vv;
  34. char *v = strdup(value);
  35. if (!v) { return "xml_conf_set_slot_string(): strdup() failed"; }
  36. #ifdef XML_CONF_DEBUG
  37. fprintf(stderr, "setting string '%s' => '%s'\n", name, v);
  38. #endif
  39. * (char **) ((char *) *conf + offset) = v;
  40. return NULL;
  41. }
  42. char *xml_conf_set_slot_integer(void **conf, char *name, void *vv, intptr_t offset)
  43. {
  44. char *value = vv;
  45. int v = atoi(value);
  46. * (int *) ((char *) *conf + offset) = v;
  47. #ifdef XML_CONF_DEBUG
  48. fprintf(stderr, "setting integer '%s' => %d\n", name, v);
  49. #endif
  50. return NULL;
  51. }
  52. char *xml_conf_set_slot_time(void **conf, char *name, void *vv, intptr_t offset)
  53. {
  54. char *value = vv;
  55. int len = strlen(value);
  56. char suffix;
  57. int seconds;
  58. if (!len) { return "xml_conf_set_slot_timeval(): invalid timeval value"; }
  59. suffix = value[len-1];
  60. value[len-1] = '\0';
  61. switch (suffix) {
  62. case 's' :
  63. seconds = atoi(value);
  64. break;
  65. case 'm' :
  66. seconds = 60 * atoi(value);
  67. break;
  68. case 'h' :
  69. seconds = 60 * 60 * atoi(value);
  70. break;
  71. case 'd' :
  72. seconds = 24 * 60 * 60 * atoi(value);
  73. break;
  74. default :
  75. return "xml_conf_set_slot_timeval(): unknown suffix used in timeval value";
  76. }
  77. * (int *) ((char *) *conf + offset) = seconds;
  78. #ifdef XML_CONF_DEBUG
  79. fprintf(stderr, "setting time '%s' => %d:%02d:%02d:%02d\n", name, expand_dhms(seconds));
  80. #endif
  81. return NULL;
  82. }
  83. char *xml_conf_parse_section(void **conf, struct xml_conf_section *section, void *xml_node)
  84. {
  85. xmlNode *element = xml_node;
  86. char *ret = 0;
  87. #ifdef XML_CONF_DEBUG
  88. fprintf(stderr, "processing a section %s\n", section->path);
  89. #endif
  90. for ( ; element; element = element->next) {
  91. if (element->type == XML_ELEMENT_NODE && !strcmp((const char *) element->name, "value") && element->children) {
  92. xmlChar *name = xmlGetProp(element, (unsigned char *) "name");
  93. if (name) {
  94. int i;
  95. #ifdef XML_CONF_DEBUG
  96. fprintf(stderr, "found a value: %s\n", name);
  97. #endif
  98. for (i = 0; section->parsers[i].parser; i++) {
  99. if (!section->parsers[i].name || !strcmp(section->parsers[i].name, (char *) name)) {
  100. break;
  101. }
  102. }
  103. if (section->parsers[i].parser) {
  104. if (section->parsers[i].type == XML_CONF_SCALAR) {
  105. if (element->children->type == XML_TEXT_NODE) {
  106. ret = section->parsers[i].parser(conf, (char *) name, element->children->content, section->parsers[i].offset);
  107. }
  108. else {
  109. ret = "XML_TEXT_NODE is expected, something different is given";
  110. }
  111. }
  112. else {
  113. ret = section->parsers[i].parser(conf, (char *) name, element->children, section->parsers[i].offset);
  114. }
  115. xmlFree(name);
  116. if (ret) { return ret; }
  117. else { continue; }
  118. }
  119. fprintf(stderr, "Warning, unknown setting '%s' in section '%s'\n", (char *) name, section->path);
  120. xmlFree(name);
  121. }
  122. }
  123. }
  124. return NULL;
  125. }
  126. static char *xml_conf_parse_file(xmlNode *element)
  127. {
  128. char *ret = 0;
  129. for ( ; element; element = element->next) {
  130. if (element->parent && element->type == XML_ELEMENT_NODE && !strcmp((const char *) element->name, "section")) {
  131. xmlChar *name = xmlGetProp(element, (unsigned char *) "name");
  132. if (name) {
  133. char *parent_name = (char *) xmlGetNodePath(element->parent);
  134. char *full_name;
  135. int i;
  136. struct xml_conf_section *section = NULL;
  137. #ifdef XML_CONF_DEBUG
  138. fprintf(stderr, "got a section: %s/%s\n", parent_name, name);
  139. #endif
  140. full_name = alloca(strlen(parent_name) + strlen((char *) name) + 1 + 1);
  141. sprintf(full_name, "%s/%s", parent_name, (char *) name);
  142. xmlFree(parent_name);
  143. xmlFree(name);
  144. for (i = 0; i < xml_conf_sections_used; i++) {
  145. if (!strcmp(xml_conf_sections[i]->path, full_name)) {
  146. section = xml_conf_sections[i];
  147. }
  148. }
  149. if (section) { /* found a registered section */
  150. void *conf = section->conf();
  151. ret = xml_conf_parse_section(&conf, section, element->children);
  152. if (ret) { break; }
  153. }
  154. }
  155. }
  156. if (element->children) {
  157. ret = xml_conf_parse_file(element->children);
  158. if (ret) { break; }
  159. }
  160. }
  161. return ret;
  162. }
  163. char *xml_conf_load_file(char *file)
  164. {
  165. char *ret = 0;
  166. xmlDoc *doc;
  167. LIBXML_TEST_VERSION
  168. doc = xmlParseFile(file);
  169. if (doc) {
  170. ret = xml_conf_parse_file(doc->children);
  171. xmlFreeDoc(doc);
  172. }
  173. else {
  174. ret = "failed to parse conf file";
  175. }
  176. xmlCleanupParser();
  177. return ret;
  178. }
  179. int xml_conf_init()
  180. {
  181. return 0;
  182. }
  183. void xml_conf_clean()
  184. {
  185. if (xml_conf_sections) {
  186. free(xml_conf_sections);
  187. }
  188. }
  189. int xml_conf_section_register(struct xml_conf_section *section)
  190. {
  191. if (xml_conf_sections_allocated == xml_conf_sections_used) {
  192. int new_size = xml_conf_sections_used + 10;
  193. void *new_ptr = realloc(xml_conf_sections, sizeof(struct xml_conf_section *) * new_size);
  194. if (new_ptr) {
  195. xml_conf_sections = new_ptr;
  196. xml_conf_sections_allocated = new_size;
  197. }
  198. else {
  199. fprintf(stderr, "xml_conf_section_register(): out of memory\n");
  200. return -1;
  201. }
  202. }
  203. xml_conf_sections[xml_conf_sections_used++] = section;
  204. return 0;
  205. }
  206. int xml_conf_sections_register(struct xml_conf_section *sections[])
  207. {
  208. for ( ; sections && *sections; sections++) {
  209. if (0 > xml_conf_section_register(*sections)) {
  210. return -1;
  211. }
  212. }
  213. return 0;
  214. }