2
0

rls_services_parser.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /*
  2. * Copyright (C) 2005 iptelorg GmbH
  3. *
  4. * This file is part of ser, a free SIP server.
  5. *
  6. * ser is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version
  10. *
  11. * For a license to use the ser software under conditions
  12. * other than those described here, or to purchase support for this
  13. * software, please contact iptel.org by e-mail at the following addresses:
  14. * [email protected]
  15. *
  16. * ser is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. */
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <time.h>
  28. #include <xcap/rls_services_parser.h>
  29. #include <xcap/xml_utils.h>
  30. #include <libxml/parser.h>
  31. #include <libxml/tree.h>
  32. #include <cds/sstr.h>
  33. #include <cds/logger.h>
  34. static char rls_namespace[] = "urn:ietf:params:xml:ns:rls-services";
  35. /*
  36. static int read_entry(xmlNode *entry_node, entry_t **dst)
  37. {
  38. xmlAttr *a;
  39. const char *a_val;
  40. / * allocate memory and prepare empty node * /
  41. if (!dst) return -1;
  42. *dst = (entry_t*)cds_malloc(sizeof(entry_t));
  43. if (!(*dst)) return -2;
  44. memset(*dst, 0, sizeof(entry_t));
  45. / * get attributes * /
  46. a = find_attr(entry_node->properties, "uri");
  47. if (a) {
  48. a_val = get_attr_value(a);
  49. if (a_val) (*dst)->uri = zt_strdup(a_val);
  50. }
  51. return 0;
  52. }*/
  53. static int read_package(xmlNode *n, package_t **dst)
  54. {
  55. const char *name;
  56. if (!dst) return -1;
  57. *dst = (package_t*)cds_malloc(sizeof(package_t));
  58. if (!(*dst)) return -2;
  59. memset(*dst, 0, sizeof(package_t));
  60. name = get_node_value(n);
  61. if (name) (*dst)->name = zt_strdup(name);
  62. return 0;
  63. }
  64. static int read_packages(xmlNode *list_node, packages_t **dst)
  65. {
  66. int res = 0;
  67. xmlNode *n;
  68. package_t *p, *last;
  69. /* allocate memory and prepare empty node */
  70. if (!dst) return -1;
  71. *dst = (packages_t*)cds_malloc(sizeof(packages_t));
  72. if (!(*dst)) return -2;
  73. memset(*dst, 0, sizeof(packages_t));
  74. /* read packages */
  75. n = list_node->children;
  76. last = NULL;
  77. while (n) {
  78. if (n->type == XML_ELEMENT_NODE) {
  79. if (cmp_node(n, "package", rls_namespace) >= 0) {
  80. res = read_package(n, &p);
  81. if ((res == 0) && p) {
  82. SEQUENCE_ADD((*dst)->package, last, p);
  83. }
  84. }
  85. }
  86. n = n->next;
  87. }
  88. return 0;
  89. }
  90. int read_service(xmlNode *list_node, service_t **dst)
  91. {
  92. int res = 0;
  93. xmlAttr *a;
  94. const char *a_val;
  95. xmlNode *n;
  96. int first_node;
  97. DEBUG_LOG("read_service(): called\n");
  98. /* allocate memory and prepare empty node */
  99. if (!dst) return -1;
  100. *dst = (service_t*)cds_malloc(sizeof(service_t));
  101. if (!(*dst)) return -2;
  102. memset(*dst, 0, sizeof(service_t));
  103. /* get attributes */
  104. a = find_attr(list_node->properties, "uri");
  105. if (a) {
  106. a_val = get_attr_value(a);
  107. if (a_val) (*dst)->uri = zt_strdup(a_val);
  108. }
  109. /* read child nodes */
  110. n = list_node->children;
  111. first_node = 1;
  112. while (n) {
  113. if (n->type == XML_ELEMENT_NODE) {
  114. if (first_node) {
  115. /* element must be list or resource-list */
  116. if (cmp_node(n, "list", rls_namespace) >= 0) {
  117. res = read_list(n, &(*dst)->content.list, 0);
  118. if ( (res == 0) && ((*dst)->content.list) ) {
  119. (*dst)->content_type = stc_list;
  120. }
  121. else return -1;
  122. }
  123. else if (cmp_node(n, "resource-list", rls_namespace) >= 0) {
  124. a_val = get_node_value(n);
  125. if (a_val)
  126. (*dst)->content.resource_list = zt_strdup(a_val);
  127. else
  128. (*dst)->content.resource_list = NULL;
  129. (*dst)->content_type = stc_resource_list;
  130. }
  131. else return -1;
  132. first_node = 0;
  133. }
  134. else { /* packages node */
  135. if (cmp_node(n, "packages", rls_namespace) >= 0) {
  136. res = read_packages(n, &(*dst)->packages);
  137. }
  138. break;
  139. }
  140. }
  141. n = n->next;
  142. }
  143. return 0;
  144. }
  145. static int read_rls_services(xmlNode *root, rls_services_t **dst)
  146. {
  147. /* xmlAttr *a; */
  148. xmlNode *n;
  149. service_t *l, *last_l;
  150. int res = 0;
  151. if (!root) return -1;
  152. if (!dst) return -1;
  153. if (cmp_node(root, "rls-services", rls_namespace) < 0) {
  154. ERROR_LOG("document is not a rls-services\n");
  155. return -1;
  156. }
  157. *dst = (rls_services_t*)cds_malloc(sizeof(rls_services_t));
  158. if (!(*dst)) return -2;
  159. (*dst)->rls_services = NULL;
  160. last_l = NULL;
  161. n = root->children;
  162. while (n) {
  163. if (n->type == XML_ELEMENT_NODE) {
  164. if (cmp_node(n, "service", rls_namespace) >= 0) {
  165. res = read_service(n, &l);
  166. if (res == 0) {
  167. if (l) SEQUENCE_ADD((*dst)->rls_services, last_l, l);
  168. }
  169. else break;
  170. }
  171. }
  172. n = n->next;
  173. }
  174. return res;
  175. }
  176. int parse_rls_services_xml(const char *data, int data_len, rls_services_t **dst)
  177. {
  178. int res = 0;
  179. xmlDocPtr doc; /* the resulting document tree */
  180. doc = xmlReadMemory(data, data_len, NULL, NULL, xml_parser_flags);
  181. if (doc == NULL) {
  182. ERROR_LOG("can't parse document\n");
  183. return -1;
  184. }
  185. res = read_rls_services(xmlDocGetRootElement(doc), dst);
  186. xmlFreeDoc(doc);
  187. return res;
  188. }
  189. int parse_service(const char *data, int data_len, service_t **dst)
  190. {
  191. int res = 0;
  192. xmlDocPtr doc; /* the resulting document tree */
  193. doc = xmlReadMemory(data, data_len, NULL, NULL, xml_parser_flags);
  194. if (doc == NULL) {
  195. ERROR_LOG("can't parse document\n");
  196. return -1;
  197. }
  198. res = read_service(xmlDocGetRootElement(doc), dst);
  199. xmlFreeDoc(doc);
  200. return res;
  201. }
  202. static void free_package(package_t *p)
  203. {
  204. if (!p) return;
  205. if (p->name) cds_free(p->name);
  206. cds_free(p);
  207. }
  208. static void free_packages(packages_t *p)
  209. {
  210. package_t *e, *f;
  211. if (!p) return;
  212. e = SEQUENCE_FIRST(p->package);
  213. while (e) {
  214. f = SEQUENCE_NEXT(e);
  215. free_package(e);
  216. e = f;
  217. }
  218. cds_free(p);
  219. }
  220. void free_service(service_t *s)
  221. {
  222. if (!s) return;
  223. if (s->uri) cds_free(s->uri);
  224. switch (s->content_type) {
  225. case stc_list: free_list(s->content.list); break;
  226. case stc_resource_list: cds_free(s->content.resource_list); break;
  227. }
  228. free_packages(s->packages);
  229. cds_free(s);
  230. }
  231. void free_rls_services(rls_services_t *rls)
  232. {
  233. service_t *e, *f;
  234. if (!rls) return;
  235. e = SEQUENCE_FIRST(rls->rls_services);
  236. while (e) {
  237. f = SEQUENCE_NEXT(e);
  238. free_service(e);
  239. e = f;
  240. }
  241. cds_free(rls);
  242. }