lost: added civic address parsing via xpath
[kamailio] / src / modules / lost / pidf.c
1 /*
2  * $Id: pidf.c 1953 2007-04-04 08:50:33Z anca_vamanu $
3  *
4  * presence module - presence server implementation
5  *
6  * Copyright (C) 2006 Voice Sistem S.R.L.
7  *
8  * This file is part of Kamailio, a free SIP server.
9  *
10  * Kamailio is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version
14  *
15  * Kamailio is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23  *
24  */
25
26 /*! \file
27  * \brief Kamailio lost ::  PIDF handling
28  * \ingroup lost
29  */
30
31
32 /**
33  * make strptime available
34  * use 600 for 'Single UNIX Specification, Version 3'
35  * _XOPEN_SOURCE creates conflict in header definitions in Solaris
36  */
37 #ifndef __OS_solaris
38 #define _XOPEN_SOURCE 600 /* glibc2 on linux, bsd */
39 #define _BSD_SOURCE \
40         1                                         /* needed on linux to "fix" the effect
41                                                                                   of the above define on
42                                                                                   features.h/unistd.h syscall() */
43 #define _DEFAULT_SOURCE 1 /* _BSD_SOURCE is deprecated */
44 #define _DARWIN_C_SOURCE 1
45 #else
46 #define _XOPEN_SOURCE_EXTENDED 1 /* solaris */
47 #endif
48
49 #include <time.h>
50
51 #undef _XOPEN_SOURCE
52 #undef _XOPEN_SOURCE_EXTENDED
53
54 #include <string.h>
55 #include <stdlib.h>
56 #include <libxml/parser.h>
57
58 #include "../../core/mem/mem.h"
59 #include "../../core/dprint.h"
60
61 #include "pidf.h"
62
63 xmlAttrPtr xmlNodeGetAttrByName(xmlNodePtr node, const char *name)
64 {
65         xmlAttrPtr attr = node->properties;
66         while(attr) {
67                 if(xmlStrcasecmp(attr->name, (unsigned char *)name) == 0)
68                         return attr;
69                 attr = attr->next;
70         }
71         return NULL;
72 }
73
74 char *xmlNodeGetAttrContentByName(xmlNodePtr node, const char *name)
75 {
76         xmlAttrPtr attr = xmlNodeGetAttrByName(node, name);
77         if(attr)
78                 return (char *)xmlNodeGetContent(attr->children);
79         else
80                 return NULL;
81 }
82
83 xmlNodePtr xmlNodeGetChildByName(xmlNodePtr node, const char *name)
84 {
85         xmlNodePtr cur = node->children;
86         while(cur) {
87                 if(xmlStrcasecmp(cur->name, (unsigned char *)name) == 0)
88                         return cur;
89                 cur = cur->next;
90         }
91         return NULL;
92 }
93
94 xmlNodePtr xmlNodeGetNodeByName(
95                 xmlNodePtr node, const char *name, const char *ns)
96 {
97         xmlNodePtr cur = node;
98         while(cur) {
99                 xmlNodePtr match = NULL;
100                 if(xmlStrcasecmp(cur->name, (unsigned char *)name) == 0) {
101                         if(!ns || (cur->ns &&
102                                 xmlStrcasecmp(cur->ns->prefix, (unsigned char *)ns) == 0))
103                                 return cur;
104                 }
105                 match = xmlNodeGetNodeByName(cur->children, name, ns);
106                 if(match)
107                         return match;
108                 cur = cur->next;
109         }
110         return NULL;
111 }
112
113 char *xmlNodeGetNodeContentByName(
114                 xmlNodePtr root, const char *name, const char *ns)
115 {
116         xmlNodePtr node = xmlNodeGetNodeByName(root, name, ns);
117         if(node)
118                 return (char *)xmlNodeGetContent(node->children);
119         else
120                 return NULL;
121 }
122
123 xmlNodePtr xmlDocGetNodeByName(xmlDocPtr doc, const char *name, const char *ns)
124 {
125         xmlNodePtr cur = doc->children;
126         return xmlNodeGetNodeByName(cur, name, ns);
127 }
128
129 char *xmlDocGetNodeContentByName(
130                 xmlDocPtr doc, const char *name, const char *ns)
131 {
132         xmlNodePtr node = xmlDocGetNodeByName(doc, name, ns);
133         if(node)
134                 return (char *)xmlNodeGetContent(node->children);
135         else
136                 return NULL;
137 }
138
139 xmlXPathObjectPtr xmlGetNodeSet(xmlDocPtr doc, xmlChar *xpath, xmlChar *ns)
140 {
141
142         xmlXPathContextPtr context = NULL;
143         xmlXPathObjectPtr result = NULL;
144
145         context = xmlXPathNewContext(doc);
146         if(context == NULL) {
147                 return NULL;
148         }
149
150         if((ns != NULL) && (xmlRegisterNamespaces(context, ns) < 0)) {
151                 xmlXPathFreeContext(context);
152                 return NULL;
153         }
154
155         result = xmlXPathEvalExpression(xpath, context);
156         xmlXPathFreeContext(context);
157
158         if(result == NULL) {
159                 LM_ERR("xmlXPathEvalExpression() failed\n");
160                 return NULL;
161         }
162         if(xmlXPathNodeSetIsEmpty(result->nodesetval)) {
163                 xmlXPathFreeObject(result);
164                 LM_DBG("xmlXPathEvalExpression() returned no result\n");
165                 return NULL;
166         }
167
168         return result;
169 }
170
171 int xmlRegisterNamespaces(xmlXPathContextPtr context, const xmlChar *ns)
172 {
173         xmlChar *nsListDup;
174         xmlChar *prefix;
175         xmlChar *href;
176         xmlChar *next;
177
178         nsListDup = xmlStrdup(ns);
179         if(nsListDup == NULL) {
180                 return -1;
181         }
182
183         next = nsListDup;
184         while(next != NULL) {
185                 /* skip spaces */
186                 while((*next) == ' ')
187                         next++;
188                 if((*next) == '\0')
189                         break;
190
191                 /* find prefix */
192                 prefix = next;
193                 next = (xmlChar *)xmlStrchr(next, '=');
194                 if(next == NULL) {
195                         xmlFree(nsListDup);
196                         return -1;
197                 }
198                 *(next++) = '\0';
199
200                 /* find href */
201                 href = next;
202                 next = (xmlChar *)xmlStrchr(next, ' ');
203                 if(next != NULL) {
204                         *(next++) = '\0';
205                 }
206
207                 /* register namespace */
208                 if(xmlXPathRegisterNs(context, prefix, href) != 0) {
209                         xmlFree(nsListDup);
210                         return -1;
211                 }
212         }
213
214         xmlFree(nsListDup);
215         return 0;
216 }