Bug Summary

File:src/switch_xml.c
Location:line 1598, column 2
Description:Potential leak of memory pointed to by 'm'

Annotated Source Code

1/*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18 *
19 * The Initial Developer of the Original Code is
20 * Anthony Minessale II <anthm@freeswitch.org>
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Anthony Minessale II <anthm@freeswitch.org>
27 * Simon Capper <skyjunky@sbcglobal.net>
28 * Marc Olivier Chouinard <mochouinard@moctel.com>
29 * Raymond Chandler <intralanman@freeswitch.org>
30 *
31 * switch_xml.c -- XML PARSER
32 *
33 * Derived from ezxml http://ezxml.sourceforge.net
34 * Original Copyright
35 *
36 * Copyright 2004, 2006 Aaron Voisine <aaron@voisine.org>
37 *
38 * Permission is hereby granted, free of charge, to any person obtaining
39 * a copy of this software and associated documentation files (the
40 * "Software"), to deal in the Software without restriction, including
41 * without limitation the rights to use, copy, modify, merge, publish,
42 * distribute, sublicense, and/or sell copies of the Software, and to
43 * permit persons to whom the Software is furnished to do so, subject to
44 * the following conditions:
45 *
46 * The above copyright notice and this permission notice shall be included
47 * in all copies or substantial portions of the Software.
48 *
49 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
50 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
51 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
52 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
53 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
54 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
55 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
56 */
57
58#include <switch.h>
59#ifndef WIN32
60#include <sys/wait.h>
61#include <switch_private.h>
62#include <glob.h>
63#else /* we're on windoze :( */
64/* glob functions at end of this file */
65#include <apr_file_io.h>
66
67typedef struct {
68 size_t gl_pathc; /* Count of total paths so far. */
69 size_t gl_matchc; /* Count of paths matching pattern. */
70 size_t gl_offs; /* Reserved at beginning of gl_pathv. */
71 int gl_flags; /* Copy of flags parameter to glob. */
72 char **gl_pathv; /* List of paths matching pattern. */
73 /* Copy of errfunc parameter to glob. */
74 int (*gl_errfunc) (const char *, int);
75} glob_t;
76
77/* Believed to have been introduced in 1003.2-1992 */
78#define GLOB_APPEND(1 << 5) 0x0001 /* Append to output from previous call. */
79#define GLOB_DOOFFS(1 << 3) 0x0002 /* Use gl_offs. */
80#define GLOB_ERR(1 << 0) 0x0004 /* Return on error. */
81#define GLOB_MARK(1 << 1) 0x0008 /* Append / to matching directories. */
82#define GLOB_NOCHECK(1 << 4) 0x0010 /* Return pattern itself if nothing matches. */
83#define GLOB_NOSORT(1 << 2) 0x0020 /* Don't sort. */
84
85/* Error values returned by glob(3) */
86#define GLOB_NOSPACE1 (-1) /* Malloc call failed. */
87#define GLOB_ABORTED2 (-2) /* Unignored error. */
88#define GLOB_NOMATCH3 (-3) /* No match and GLOB_NOCHECK was not set. */
89#define GLOB_NOSYS4 (-4) /* Obsolete: source comptability only. */
90
91#define GLOB_ALTDIRFUNC(1 << 9) 0x0040 /* Use alternately specified directory funcs. */
92#define GLOB_MAGCHAR(1 << 8) 0x0100 /* Pattern had globbing characters. */
93#define GLOB_NOMAGIC(1 << 11) 0x0200 /* GLOB_NOCHECK without magic chars (csh). */
94#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */
95#define GLOB_LIMIT 0x1000 /* limit number of returned paths */
96
97int glob(const char *, int, int (*)(const char *, int), glob_t *);
98void globfree(glob_t *);
99
100#endif
101
102#define SWITCH_XML_WS"\t\r\n " "\t\r\n " /* whitespace */
103#define SWITCH_XML_ERRL128 128 /* maximum error string length */
104
105/* Use UTF-8 as the general encoding */
106static switch_bool_t USE_UTF_8_ENCODING = SWITCH_TRUE;
107
108static void preprocess_exec_set(char *keyval)
109{
110 char *key = keyval;
111 char *val = strchr(key, '=')(__extension__ (__builtin_constant_p ('=') && !__builtin_constant_p
(key) && ('=') == '\0' ? (char *) __rawmemchr (key, '='
) : __builtin_strchr (key, '=')))
;
112
113 if (val) {
114 char *ve = val++;
115 while (*val && *val == ' ') {
116 val++;
117 }
118 *ve-- = '\0';
119 while (*ve && *ve == ' ') {
120 *ve-- = '\0';
121 }
122 }
123
124 if (key && val) {
125 switch_stream_handle_t exec_result = { 0 };
126 SWITCH_STANDARD_STREAM(exec_result)memset(&exec_result, 0, sizeof(exec_result)); exec_result
.data = malloc(1024); ((exec_result.data) ? (void) (0) : __assert_fail
("exec_result.data", "src/switch_xml.c", 126, __PRETTY_FUNCTION__
)); memset(exec_result.data, 0, 1024); exec_result.end = exec_result
.data; exec_result.data_size = 1024; exec_result.write_function
= switch_console_stream_write; exec_result.raw_write_function
= switch_console_stream_raw_write; exec_result.alloc_len = 1024
; exec_result.alloc_chunk = 1024
;
127 if (switch_stream_system_fork(val, &exec_result) == 0) {
128 if (!zstr(exec_result.data)_zstr(exec_result.data)) {
129 char *tmp = (char *) exec_result.data;
130 tmp = &tmp[strlen(tmp)-1];
131 while (tmp >= (char *) exec_result.data && ( tmp[0] == ' ' || tmp[0] == '\n') ) {
132 tmp[0] = '\0'; /* remove trailing spaces and newlines */
133 tmp--;
134 }
135 switch_core_set_variable(key, exec_result.data);
136 }
137 } else {
138 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 138, ((void*)0)
, SWITCH_LOG_ERROR, "Error while executing command: %s\n", val);
139 }
140 switch_safe_free(exec_result.data)if (exec_result.data) {free(exec_result.data);exec_result.data
=((void*)0);}
;
141 }
142}
143
144static int preprocess(const char *cwd, const char *file, FILE *write_fd, int rlevel);
145
146typedef struct switch_xml_root *switch_xml_root_t;
147struct switch_xml_root { /* additional data for the root tag */
148 struct switch_xml xml; /* is a super-struct built on top of switch_xml struct */
149 switch_xml_t cur; /* current xml tree insertion point */
150 char *m; /* original xml string */
151 switch_size_t len; /* length of allocated memory */
152 uint8_t dynamic; /* Free the original string when calling switch_xml_free */
153 char *u; /* UTF-8 conversion of string if original was UTF-16 */
154 char *s; /* start of work area */
155 char *e; /* end of work area */
156 char **ent; /* general entities (ampersand sequences) */
157 char ***attr; /* default attributes */
158 char ***pi; /* processing instructions */
159 short standalone; /* non-zero if <?xml standalone="yes"?> */
160 char err[SWITCH_XML_ERRL128]; /* error string */
161};
162
163char *SWITCH_XML_NIL[] = { NULL((void*)0) }; /* empty, null terminated array of strings */
164
165struct switch_xml_binding {
166 switch_xml_search_function_t function;
167 switch_xml_section_t sections;
168 void *user_data;
169 struct switch_xml_binding *next;
170};
171
172
173static switch_xml_binding_t *BINDINGS = NULL((void*)0);
174static switch_xml_t MAIN_XML_ROOT = NULL((void*)0);
175static switch_memory_pool_t *XML_MEMORY_POOL = NULL((void*)0);
176
177static switch_thread_rwlock_t *B_RWLOCK = NULL((void*)0);
178static switch_mutex_t *XML_LOCK = NULL((void*)0);
179static switch_mutex_t *CACHE_MUTEX = NULL((void*)0);
180static switch_mutex_t *REFLOCK = NULL((void*)0);
181static switch_mutex_t *FILE_LOCK = NULL((void*)0);
182
183SWITCH_DECLARE_NONSTD(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t __switch_xml_open_root(uint8_t reload, const char **err, void *user_data);
184
185static switch_xml_open_root_function_t XML_OPEN_ROOT_FUNCTION = (switch_xml_open_root_function_t)__switch_xml_open_root;
186static void *XML_OPEN_ROOT_FUNCTION_USER_DATA = NULL((void*)0);
187
188static switch_hash_t *CACHE_HASH = NULL((void*)0);
189static switch_hash_t *CACHE_EXPIRES_HASH = NULL((void*)0);
190
191struct xml_section_t {
192 const char *name;
193 /* switch_xml_section_t section; */
194 uint32_t section;
195};
196
197static struct xml_section_t SECTIONS[] = {
198 {"result", SWITCH_XML_SECTION_RESULT},
199 {"config", SWITCH_XML_SECTION_CONFIG},
200 {"directory", SWITCH_XML_SECTION_DIRECTORY},
201 {"dialplan", SWITCH_XML_SECTION_DIALPLAN},
202 {"languages", SWITCH_XML_SECTION_LANGUAGES},
203 {"chatplan", SWITCH_XML_SECTION_CHATPLAN},
204 {NULL((void*)0), 0}
205};
206
207SWITCH_DECLARE(switch_xml_section_t)__attribute__((visibility("default"))) switch_xml_section_t switch_xml_parse_section_string(const char *str)
208{
209 size_t x;
210 char buf[1024] = "";
211 /*switch_xml_section_t sections = SWITCH_XML_SECTION_RESULT; */
212 uint32_t sections = SWITCH_XML_SECTION_RESULT;
213
214 if (str) {
215 for (x = 0; x < strlen(str); x++) {
216 buf[x] = (char) tolower((int) str[x])(__extension__ ({ int __res; if (sizeof ((int) str[x]) > 1
) { if (__builtin_constant_p ((int) str[x])) { int __c = ((int
) str[x]); __res = __c < -128 || __c > 255 ? __c : (*__ctype_tolower_loc
())[__c]; } else __res = tolower ((int) str[x]); } else __res
= (*__ctype_tolower_loc ())[(int) ((int) str[x])]; __res; })
)
;
217 }
218 for (x = 0;; x++) {
219 if (!SECTIONS[x].name) {
220 break;
221 }
222 if (strstr(buf, SECTIONS[x].name)) {
223 sections |= SECTIONS[x].section;
224 }
225 }
226 }
227 return (switch_xml_section_t) sections;
228}
229
230SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_xml_unbind_search_function(switch_xml_binding_t **binding)
231{
232 switch_xml_binding_t *ptr, *last = NULL((void*)0);
233 switch_status_t status = SWITCH_STATUS_FALSE;
234
235
236 switch_thread_rwlock_wrlock(B_RWLOCK);
237 for (ptr = BINDINGS; ptr; ptr = ptr->next) {
238 if (ptr == *binding) {
239 if (last) {
240 last->next = (*binding)->next;
241 } else {
242 BINDINGS = (*binding)->next;
243 }
244 status = SWITCH_STATUS_SUCCESS;
245 break;
246 }
247 last = ptr;
248 }
249 switch_thread_rwlock_unlock(B_RWLOCK);
250
251 return status;
252}
253
254SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_xml_unbind_search_function_ptr(switch_xml_search_function_t function)
255{
256 switch_xml_binding_t *ptr, *last = NULL((void*)0);
257 switch_status_t status = SWITCH_STATUS_FALSE;
258
259 switch_thread_rwlock_wrlock(B_RWLOCK);
260 for (ptr = BINDINGS; ptr; ptr = ptr->next) {
261 if (ptr->function == function) {
262 status = SWITCH_STATUS_SUCCESS;
263
264 if (last) {
265 last->next = ptr->next;
266 } else {
267 BINDINGS = ptr->next;
268 last = NULL((void*)0);
269 continue;
270 }
271 }
272 last = ptr;
273 }
274 switch_thread_rwlock_unlock(B_RWLOCK);
275
276 return status;
277}
278
279SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_xml_set_binding_sections(switch_xml_binding_t *binding, switch_xml_section_t sections)
280{
281 switch_assert(binding)((binding) ? (void) (0) : __assert_fail ("binding", "src/switch_xml.c"
, 281, __PRETTY_FUNCTION__))
;
282 binding->sections = sections;
283}
284
285SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_xml_set_binding_user_data(switch_xml_binding_t *binding, void *user_data)
286{
287 switch_assert(binding)((binding) ? (void) (0) : __assert_fail ("binding", "src/switch_xml.c"
, 287, __PRETTY_FUNCTION__))
;
288 binding->user_data = user_data;
289}
290
291SWITCH_DECLARE(switch_xml_section_t)__attribute__((visibility("default"))) switch_xml_section_t switch_xml_get_binding_sections(switch_xml_binding_t *binding)
292{
293 return binding->sections;
294}
295
296SWITCH_DECLARE(void *)__attribute__((visibility("default"))) void * switch_xml_get_binding_user_data(switch_xml_binding_t *binding)
297{
298 return binding->user_data;
299}
300
301SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_xml_bind_search_function_ret(switch_xml_search_function_t function,
302 switch_xml_section_t sections, void *user_data, switch_xml_binding_t **ret_binding)
303{
304 switch_xml_binding_t *binding = NULL((void*)0), *ptr = NULL((void*)0);
305 assert(function != NULL)((function != ((void*)0)) ? (void) (0) : __assert_fail ("function != ((void*)0)"
, "src/switch_xml.c", 305, __PRETTY_FUNCTION__))
;
306
307 if (!(binding = (switch_xml_binding_t *) switch_core_alloc(XML_MEMORY_POOL, sizeof(*binding))switch_core_perform_alloc(XML_MEMORY_POOL, sizeof(*binding), "src/switch_xml.c"
, (const char *)__func__, 307)
)) {
308 return SWITCH_STATUS_MEMERR;
309 }
310
311 binding->function = function;
312 binding->sections = sections;
313 binding->user_data = user_data;
314
315 switch_thread_rwlock_wrlock(B_RWLOCK);
316 for (ptr = BINDINGS; ptr && ptr->next; ptr = ptr->next);
317
318 if (ptr) {
319 ptr->next = binding;
320 } else {
321 BINDINGS = binding;
322 }
323
324 if (ret_binding) {
325 *ret_binding = binding;
326 }
327
328 switch_thread_rwlock_unlock(B_RWLOCK);
329
330 return SWITCH_STATUS_SUCCESS;
331}
332
333SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_find_child(switch_xml_t node, const char *childname, const char *attrname, const char *value)
334{
335 switch_xml_t p = NULL((void*)0);
336
337 if (!(childname && attrname && value)) {
338 return node;
339 }
340
341 for (p = switch_xml_child(node, childname); p; p = p->next) {
342 const char *aname = switch_xml_attr(p, attrname);
343 if (aname && value && !strcasecmp(aname, value)) {
344 break;
345 }
346 }
347
348 return p;
349}
350
351SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_find_child_multi(switch_xml_t node, const char *childname,...)
352{
353 switch_xml_t p = NULL((void*)0);
354 const char *names[256] = { 0 };
355 const char *vals[256] = { 0 };
356 int x, i = 0;
357 va_list ap;
358 const char *attrname, *value = NULL((void*)0);
359
360 va_start(ap, childname)__builtin_va_start(ap, childname);
361
362 while (i < 255) {
363 if ((attrname = va_arg(ap, const char *)__builtin_va_arg(ap, const char *))) {
364 value = va_arg(ap, const char *)__builtin_va_arg(ap, const char *);
365 }
366 if (attrname && value) {
367 names[i] = attrname;
368 vals[i] = value;
369 } else {
370 break;
371 }
372 i++;
373 }
374
375 va_end(ap)__builtin_va_end(ap);
376
377 if (!(childname && i)) {
378 return node;
379 }
380
381 for (p = switch_xml_child(node, childname); p; p = p->next) {
382 for (x = 0; x < i; x++) {
383 if (names[x] && vals[x]) {
384 const char *aname = switch_xml_attr(p, names[x]);
385
386 if (aname) {
387 if (*vals[x] == '!') {
388 const char *sval = vals[x] + 1;
389 if (sval && strcasecmp(aname, sval)) {
390 goto done;
391 }
392 } else {
393 if (!strcasecmp(aname, vals[x])) {
394 goto done;
395 }
396 }
397 }
398 }
399 }
400 }
401
402 done:
403
404 return p;
405}
406
407/* returns the first child tag with the given name or NULL if not found */
408SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_child(switch_xml_t xml, const char *name)
409{
410 xml = (xml) ? xml->child : NULL((void*)0);
411 while (xml && strcmp(name, xml->name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(name) && __builtin_constant_p (xml->name) &&
(__s1_len = __builtin_strlen (name), __s2_len = __builtin_strlen
(xml->name), (!((size_t)(const void *)((name) + 1) - (size_t
)(const void *)(name) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)((xml->name) + 1) - (size_t)(const
void *)(xml->name) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(name, xml->name) : (__builtin_constant_p (name) &&
((size_t)(const void *)((name) + 1) - (size_t)(const void *)
(name) == 1) && (__s1_len = __builtin_strlen (name), __s1_len
< 4) ? (__builtin_constant_p (xml->name) && ((
size_t)(const void *)((xml->name) + 1) - (size_t)(const void
*)(xml->name) == 1) ? __builtin_strcmp (name, xml->name
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (xml->name); int __result = (((const
unsigned char *) (const char *) (name))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (name))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (name))[2] - __s2[2]); if (__s1_len > 2
&& __result == 0) __result = (((const unsigned char *
) (const char *) (name))[3] - __s2[3]); } } __result; }))) : (
__builtin_constant_p (xml->name) && ((size_t)(const
void *)((xml->name) + 1) - (size_t)(const void *)(xml->
name) == 1) && (__s2_len = __builtin_strlen (xml->
name), __s2_len < 4) ? (__builtin_constant_p (name) &&
((size_t)(const void *)((name) + 1) - (size_t)(const void *)
(name) == 1) ? __builtin_strcmp (name, xml->name) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (name); int __result = (((const unsigned char *) (const
char *) (xml->name))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (xml->name))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (xml->name))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (xml->name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(name, xml->name)))); })
)
412 xml = xml->sibling;
413 return xml;
414}
415
416/* returns the Nth tag with the same name in the same subsection or NULL if not found */
417switch_xml_t switch_xml_idx(switch_xml_t xml, int idx)
418{
419 for (; xml && idx; idx--)
420 xml = xml->next;
421 return xml;
422}
423
424/* returns the value of the requested tag attribute or "" if not found */
425SWITCH_DECLARE(const char *)__attribute__((visibility("default"))) const char * switch_xml_attr_soft(switch_xml_t xml, const char *attr)
426{
427 const char *ret = switch_xml_attr(xml, attr);
428
429 return ret ? ret : "";
430}
431
432/* returns the value of the requested tag attribute or NULL if not found */
433SWITCH_DECLARE(const char *)__attribute__((visibility("default"))) const char * switch_xml_attr(switch_xml_t xml, const char *attr)
434{
435 int i = 0, j = 1;
436 switch_xml_root_t root = (switch_xml_root_t) xml;
437
438 if (!xml || !xml->attr)
439 return NULL((void*)0);
440 while (xml->attr[i] && attr && strcmp(attr, xml->attr[i])__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(attr) && __builtin_constant_p (xml->attr[i]) &&
(__s1_len = __builtin_strlen (attr), __s2_len = __builtin_strlen
(xml->attr[i]), (!((size_t)(const void *)((attr) + 1) - (
size_t)(const void *)(attr) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((xml->attr[i]) + 1) - (size_t)(
const void *)(xml->attr[i]) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(attr, xml->attr[i]) : (__builtin_constant_p (attr) &&
((size_t)(const void *)((attr) + 1) - (size_t)(const void *)
(attr) == 1) && (__s1_len = __builtin_strlen (attr), __s1_len
< 4) ? (__builtin_constant_p (xml->attr[i]) &&
((size_t)(const void *)((xml->attr[i]) + 1) - (size_t)(const
void *)(xml->attr[i]) == 1) ? __builtin_strcmp (attr, xml
->attr[i]) : (__extension__ ({ const unsigned char *__s2 =
(const unsigned char *) (const char *) (xml->attr[i]); int
__result = (((const unsigned char *) (const char *) (attr))[
0] - __s2[0]); if (__s1_len > 0 && __result == 0) {
__result = (((const unsigned char *) (const char *) (attr))[
1] - __s2[1]); if (__s1_len > 1 && __result == 0) {
__result = (((const unsigned char *) (const char *) (attr))[
2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (attr))[3] - __s2
[3]); } } __result; }))) : (__builtin_constant_p (xml->attr
[i]) && ((size_t)(const void *)((xml->attr[i]) + 1
) - (size_t)(const void *)(xml->attr[i]) == 1) && (
__s2_len = __builtin_strlen (xml->attr[i]), __s2_len < 4
) ? (__builtin_constant_p (attr) && ((size_t)(const void
*)((attr) + 1) - (size_t)(const void *)(attr) == 1) ? __builtin_strcmp
(attr, xml->attr[i]) : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (attr); int
__result = (((const unsigned char *) (const char *) (xml->
attr[i]))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
xml->attr[i]))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (xml->attr[i]))[2] - __s2[2]); if (__s2_len > 2
&& __result == 0) __result = (((const unsigned char *
) (const char *) (xml->attr[i]))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (attr, xml->attr[i])))); })
)
441 i += 2;
442 if (xml->attr[i])
443 return xml->attr[i + 1]; /* found attribute */
444
445 while (root->xml.parent)
446 root = (switch_xml_root_t) root->xml.parent; /* root tag */
447
448 if (!root->attr) {
449 return NULL((void*)0);
450 }
451
452 for (i = 0; root->attr[i] && xml->name && strcmp(xml->name, root->attr[i][0])__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(xml->name) && __builtin_constant_p (root->attr
[i][0]) && (__s1_len = __builtin_strlen (xml->name
), __s2_len = __builtin_strlen (root->attr[i][0]), (!((size_t
)(const void *)((xml->name) + 1) - (size_t)(const void *)(
xml->name) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)((root->attr[i][0]) + 1) - (size_t)(const void
*)(root->attr[i][0]) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(xml->name, root->attr[i][0]) : (__builtin_constant_p (
xml->name) && ((size_t)(const void *)((xml->name
) + 1) - (size_t)(const void *)(xml->name) == 1) &&
(__s1_len = __builtin_strlen (xml->name), __s1_len < 4
) ? (__builtin_constant_p (root->attr[i][0]) && ((
size_t)(const void *)((root->attr[i][0]) + 1) - (size_t)(const
void *)(root->attr[i][0]) == 1) ? __builtin_strcmp (xml->
name, root->attr[i][0]) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (root->
attr[i][0]); int __result = (((const unsigned char *) (const char
*) (xml->name))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (xml->name))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (xml->name))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (xml->name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(root->attr[i][0]) && ((size_t)(const void *)((root
->attr[i][0]) + 1) - (size_t)(const void *)(root->attr[
i][0]) == 1) && (__s2_len = __builtin_strlen (root->
attr[i][0]), __s2_len < 4) ? (__builtin_constant_p (xml->
name) && ((size_t)(const void *)((xml->name) + 1) -
(size_t)(const void *)(xml->name) == 1) ? __builtin_strcmp
(xml->name, root->attr[i][0]) : (- (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(xml->name); int __result = (((const unsigned char *) (const
char *) (root->attr[i][0]))[0] - __s2[0]); if (__s2_len >
0 && __result == 0) { __result = (((const unsigned char
*) (const char *) (root->attr[i][0]))[1] - __s2[1]); if (
__s2_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) (root->attr[i][0]))[2] - __s2
[2]); if (__s2_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (root->attr[i][0
]))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (xml
->name, root->attr[i][0])))); })
; i++);
453 if (!root->attr[i])
454 return NULL((void*)0); /* no matching default attributes */
455 while (root->attr[i][j] && attr && strcmp(attr, root->attr[i][j])__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(attr) && __builtin_constant_p (root->attr[i][j])
&& (__s1_len = __builtin_strlen (attr), __s2_len = __builtin_strlen
(root->attr[i][j]), (!((size_t)(const void *)((attr) + 1)
- (size_t)(const void *)(attr) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((root->attr[i][j]) + 1) - (size_t
)(const void *)(root->attr[i][j]) == 1) || __s2_len >= 4
)) ? __builtin_strcmp (attr, root->attr[i][j]) : (__builtin_constant_p
(attr) && ((size_t)(const void *)((attr) + 1) - (size_t
)(const void *)(attr) == 1) && (__s1_len = __builtin_strlen
(attr), __s1_len < 4) ? (__builtin_constant_p (root->attr
[i][j]) && ((size_t)(const void *)((root->attr[i][
j]) + 1) - (size_t)(const void *)(root->attr[i][j]) == 1) ?
__builtin_strcmp (attr, root->attr[i][j]) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (root->attr[i][j]); int __result = (((const unsigned
char *) (const char *) (attr))[0] - __s2[0]); if (__s1_len >
0 && __result == 0) { __result = (((const unsigned char
*) (const char *) (attr))[1] - __s2[1]); if (__s1_len > 1
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (attr))[2] - __s2[2]); if (__s1_len > 2
&& __result == 0) __result = (((const unsigned char *
) (const char *) (attr))[3] - __s2[3]); } } __result; }))) : (
__builtin_constant_p (root->attr[i][j]) && ((size_t
)(const void *)((root->attr[i][j]) + 1) - (size_t)(const void
*)(root->attr[i][j]) == 1) && (__s2_len = __builtin_strlen
(root->attr[i][j]), __s2_len < 4) ? (__builtin_constant_p
(attr) && ((size_t)(const void *)((attr) + 1) - (size_t
)(const void *)(attr) == 1) ? __builtin_strcmp (attr, root->
attr[i][j]) : (- (__extension__ ({ const unsigned char *__s2 =
(const unsigned char *) (const char *) (attr); int __result =
(((const unsigned char *) (const char *) (root->attr[i][j
]))[0] - __s2[0]); if (__s2_len > 0 && __result ==
0) { __result = (((const unsigned char *) (const char *) (root
->attr[i][j]))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (root->attr[i][j]))[2] - __s2[2]); if (__s2_len >
2 && __result == 0) __result = (((const unsigned char
*) (const char *) (root->attr[i][j]))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (attr, root->attr[i][j])))); })
)
456 j += 3;
457 return (root->attr[i][j]) ? root->attr[i][j + 1] : NULL((void*)0); /* found default */
458}
459
460/* same as switch_xml_get but takes an already initialized va_list */
461static switch_xml_t switch_xml_vget(switch_xml_t xml, va_list ap)
462{
463 char *name = va_arg(ap, char *)__builtin_va_arg(ap, char *);
464 int idx = -1;
465
466 if (name && *name) {
467 idx = va_arg(ap, int)__builtin_va_arg(ap, int);
468 xml = switch_xml_child(xml, name);
469 }
470 return (idx < 0) ? xml : switch_xml_vget(switch_xml_idx(xml, idx), ap);
471}
472
473/* Traverses the xml tree to retrieve a specific subtag. Takes a variable
474 length list of tag names and indexes. The argument list must be terminated
475 by either an index of -1 or an empty string tag name. Example:
476 title = switch_xml_get(library, "shelf", 0, "book", 2, "title", -1);
477 This retrieves the title of the 3rd book on the 1st shelf of library.
478 Returns NULL if not found. */
479SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_get(switch_xml_t xml,...)
480{
481 va_list ap;
482 switch_xml_t r;
483
484 va_start(ap, xml)__builtin_va_start(ap, xml);
485 r = switch_xml_vget(xml, ap);
486 va_end(ap)__builtin_va_end(ap);
487 return r;
488}
489
490/* returns a null terminated array of processing instructions for the given target */
491SWITCH_DECLARE(const char **)__attribute__((visibility("default"))) const char ** switch_xml_pi(switch_xml_t xml, const char *target)
492{
493 switch_xml_root_t root = (switch_xml_root_t) xml;
494 int i = 0;
495
496 if (!root)
497 return (const char **) SWITCH_XML_NIL;
498 while (root->xml.parent)
499 root = (switch_xml_root_t) root->xml.parent; /* root tag */
500 if (!root || !root->pi) {
501 return (const char **) SWITCH_XML_NIL;
502 }
503 while (root->pi[i] && strcmp(target, root->pi[i][0])__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(target) && __builtin_constant_p (root->pi[i][0])
&& (__s1_len = __builtin_strlen (target), __s2_len =
__builtin_strlen (root->pi[i][0]), (!((size_t)(const void
*)((target) + 1) - (size_t)(const void *)(target) == 1) || __s1_len
>= 4) && (!((size_t)(const void *)((root->pi[i
][0]) + 1) - (size_t)(const void *)(root->pi[i][0]) == 1) ||
__s2_len >= 4)) ? __builtin_strcmp (target, root->pi[i
][0]) : (__builtin_constant_p (target) && ((size_t)(const
void *)((target) + 1) - (size_t)(const void *)(target) == 1)
&& (__s1_len = __builtin_strlen (target), __s1_len <
4) ? (__builtin_constant_p (root->pi[i][0]) && ((
size_t)(const void *)((root->pi[i][0]) + 1) - (size_t)(const
void *)(root->pi[i][0]) == 1) ? __builtin_strcmp (target,
root->pi[i][0]) : (__extension__ ({ const unsigned char *
__s2 = (const unsigned char *) (const char *) (root->pi[i]
[0]); int __result = (((const unsigned char *) (const char *)
(target))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
target))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
target))[2] - __s2[2]); if (__s1_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (target
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
root->pi[i][0]) && ((size_t)(const void *)((root->
pi[i][0]) + 1) - (size_t)(const void *)(root->pi[i][0]) ==
1) && (__s2_len = __builtin_strlen (root->pi[i][0
]), __s2_len < 4) ? (__builtin_constant_p (target) &&
((size_t)(const void *)((target) + 1) - (size_t)(const void *
)(target) == 1) ? __builtin_strcmp (target, root->pi[i][0]
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (target); int __result = (((const unsigned
char *) (const char *) (root->pi[i][0]))[0] - __s2[0]); if
(__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) (root->pi[i][0]))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (root->pi[i][0
]))[2] - __s2[2]); if (__s2_len > 2 && __result ==
0) __result = (((const unsigned char *) (const char *) (root
->pi[i][0]))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(target, root->pi[i][0])))); })
)
504 i++; /* find target */
505 return (const char **) ((root->pi[i]) ? root->pi[i] + 1 : SWITCH_XML_NIL);
506}
507
508/* set an error string and return root */
509static switch_xml_t switch_xml_err(switch_xml_root_t root, char *s, const char *err, ...)
510{
511 va_list ap;
512 int line = 1;
513 char *t, fmt[SWITCH_XML_ERRL128];
514
515 if (!root || !root->s) {
516 return NULL((void*)0);
517 }
518
519 for (t = root->s; t && t < s; t++)
520 if (*t == '\n')
521 line++;
522 switch_snprintf(fmt, SWITCH_XML_ERRL128, "[error near line %d]: %s", line, err);
523
524 va_start(ap, err)__builtin_va_start(ap, err);
525 vsnprintf(root->err, SWITCH_XML_ERRL128, fmt, ap);
526 va_end(ap)__builtin_va_end(ap);
527
528 return &root->xml;
529}
530
531/* Recursively decodes entity and character references and normalizes new lines
532 ent is a null terminated array of alternating entity names and values. set t
533 to '&' for general entity decoding, '%' for parameter entity decoding, 'c'
534 for cdata sections, ' ' for attribute normalization, or '*' for non-cdata
535 attribute normalization. Returns s, or if the decoded string is longer than
536 s, returns a malloced string that must be freed. */
537static char *switch_xml_decode(char *s, char **ent, char t)
538{
539 char *e, *r = s, *m = s;
540 long b, c, d, l;
541
542 for (; *s; s++) { /* normalize line endings */
543 while (*s == '\r') {
544 *(s++) = '\n';
545 if (*s == '\n')
546 memmove(s, (s + 1), strlen(s));
547 }
548 }
549
550 for (s = r;;) {
551 while (*s && *s != '&' && (*s != '%' || t != '%') && !isspace((unsigned char) (*s))((*__ctype_b_loc ())[(int) (((unsigned char) (*s)))] & (unsigned
short int) _ISspace)
)
552 s++;
553
554 if (!*s)
555 break;
556 else if (t != 'c' && !strncmp(s, "&#", 2)(__extension__ (__builtin_constant_p (2) && ((__builtin_constant_p
(s) && strlen (s) < ((size_t) (2))) || (__builtin_constant_p
("&#") && strlen ("&#") < ((size_t) (2)))
) ? __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(s) && __builtin_constant_p ("&#") && (__s1_len
= __builtin_strlen (s), __s2_len = __builtin_strlen ("&#"
), (!((size_t)(const void *)((s) + 1) - (size_t)(const void *
)(s) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)(("&#") + 1) - (size_t)(const void *)("&#") == 1) ||
__s2_len >= 4)) ? __builtin_strcmp (s, "&#") : (__builtin_constant_p
(s) && ((size_t)(const void *)((s) + 1) - (size_t)(const
void *)(s) == 1) && (__s1_len = __builtin_strlen (s)
, __s1_len < 4) ? (__builtin_constant_p ("&#") &&
((size_t)(const void *)(("&#") + 1) - (size_t)(const void
*)("&#") == 1) ? __builtin_strcmp (s, "&#") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("&#"); int __result = (((const unsigned char *)
(const char *) (s))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (s))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
s))[2] - __s2[2]); if (__s1_len > 2 && __result ==
0) __result = (((const unsigned char *) (const char *) (s))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("&#"
) && ((size_t)(const void *)(("&#") + 1) - (size_t
)(const void *)("&#") == 1) && (__s2_len = __builtin_strlen
("&#"), __s2_len < 4) ? (__builtin_constant_p (s) &&
((size_t)(const void *)((s) + 1) - (size_t)(const void *)(s)
== 1) ? __builtin_strcmp (s, "&#") : (- (__extension__ (
{ const unsigned char *__s2 = (const unsigned char *) (const char
*) (s); int __result = (((const unsigned char *) (const char
*) ("&#"))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("&#"))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("&#"))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("&#"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(s, "&#")))); }) : strncmp (s, "&#", 2)))
) { /* character reference */
557 if (s[2] == 'x')
558 c = strtol(s + 3, &e, 16); /* base 16 */
559 else
560 c = strtol(s + 2, &e, 10); /* base 10 */
561 if (!c || *e != ';') {
562 s++;
563 continue;
564 }
565 /* not a character ref */
566 if (c < 0x80)
567 *(s++) = (char) c; /* US-ASCII subset */
568 else { /* multi-byte UTF-8 sequence */
569 for (b = 0, d = c; d; d /= 2)
570 b++; /* number of bits in c */
571 b = (b - 2) / 5; /* number of bytes in payload */
572 *(s++) = (char) ((0xFF << (7 - b)) | (c >> (6 * b))); /* head */
573 while (b)
574 *(s++) = (char) (0x80 | ((c >> (6 * --b)) & 0x3F)); /* payload */
575 }
576
577 memmove(s, strchr(s, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(s) && (';') == '\0' ? (char *) __rawmemchr (s, ';')
: __builtin_strchr (s, ';')))
+ 1, strlen(strchr(s, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(s) && (';') == '\0' ? (char *) __rawmemchr (s, ';')
: __builtin_strchr (s, ';')))
));
578 } else if ((*s == '&' && (t == '&' || t == ' ' || t == '*')) || (*s == '%' && t == '%')) { /* entity reference */
579 for (b = 0; ent[b] && strncmp(s + 1, ent[b], strlen(ent[b]))(__extension__ (__builtin_constant_p (strlen(ent[b])) &&
((__builtin_constant_p (s + 1) && strlen (s + 1) <
((size_t) (strlen(ent[b])))) || (__builtin_constant_p (ent[b
]) && strlen (ent[b]) < ((size_t) (strlen(ent[b]))
))) ? __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(s + 1) && __builtin_constant_p (ent[b]) && (
__s1_len = __builtin_strlen (s + 1), __s2_len = __builtin_strlen
(ent[b]), (!((size_t)(const void *)((s + 1) + 1) - (size_t)(
const void *)(s + 1) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)((ent[b]) + 1) - (size_t)(const void *
)(ent[b]) == 1) || __s2_len >= 4)) ? __builtin_strcmp (s +
1, ent[b]) : (__builtin_constant_p (s + 1) && ((size_t
)(const void *)((s + 1) + 1) - (size_t)(const void *)(s + 1) ==
1) && (__s1_len = __builtin_strlen (s + 1), __s1_len
< 4) ? (__builtin_constant_p (ent[b]) && ((size_t
)(const void *)((ent[b]) + 1) - (size_t)(const void *)(ent[b]
) == 1) ? __builtin_strcmp (s + 1, ent[b]) : (__extension__ (
{ const unsigned char *__s2 = (const unsigned char *) (const char
*) (ent[b]); int __result = (((const unsigned char *) (const
char *) (s + 1))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (s + 1))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (s + 1))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (s + 1))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(ent[b]) && ((size_t)(const void *)((ent[b]) + 1) - (
size_t)(const void *)(ent[b]) == 1) && (__s2_len = __builtin_strlen
(ent[b]), __s2_len < 4) ? (__builtin_constant_p (s + 1) &&
((size_t)(const void *)((s + 1) + 1) - (size_t)(const void *
)(s + 1) == 1) ? __builtin_strcmp (s + 1, ent[b]) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (s + 1); int __result = (((const unsigned char *) (const
char *) (ent[b]))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (ent[b]))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (ent[b]))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (ent[b]))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(s + 1, ent[b])))); }) : strncmp (s + 1, ent[b], strlen(ent[
b]))))
; b += 2); /* find entity in entity list */
580
581 if (ent[b++]) { /* found a match */
582 if ((c = (long) strlen(ent[b])) - 1 > (e = strchr(s, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(s) && (';') == '\0' ? (char *) __rawmemchr (s, ';')
: __builtin_strchr (s, ';')))
) - s) {
583 l = (d = (long) (s - r)) + c + (long) strlen(e); /* new length */
584 if (l) {
585 if (r == m) {
586 char *tmp = (char *) malloc(l);
587 if (tmp) {
588 r = strcpy(tmp, r);
589 } else {
590 if (r)
591 free(r);
592 return NULL((void*)0);
593 }
594 } else {
595 char *tmp = (char *) realloc(r, l);
596 if (tmp) {
597 r = tmp;
598 } else {
599 if (r)
600 free(r);
601 return NULL((void*)0);
602 }
603 }
604 }
605 e = strchr((s = r + d), ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
((s = r + d)) && (';') == '\0' ? (char *) __rawmemchr
((s = r + d), ';') : __builtin_strchr ((s = r + d), ';')))
; /* fix up pointers */
606 }
607
608 memmove(s + c, e + 1, strlen(e)); /* shift rest of string */
609 strncpy(s, ent[b], c)__builtin_strncpy (s, ent[b], c); /* copy in replacement text */
610 } else
611 s++; /* not a known entity */
612 } else if ((t == ' ' || t == '*') && isspace((int) (*s))((*__ctype_b_loc ())[(int) (((int) (*s)))] & (unsigned short
int) _ISspace)
)
613 *(s++) = ' ';
614 else
615 s++; /* no decoding needed */
616 }
617
618 if (t == '*') { /* normalize spaces for non-cdata attributes */
619 for (s = r; *s; s++) {
620 if ((l = (long) strspn(s, " ")__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
(" ") && ((size_t)(const void *)((" ") + 1) - (size_t
)(const void *)(" ") == 1) ? ((__builtin_constant_p (s) &&
((size_t)(const void *)((s) + 1) - (size_t)(const void *)(s)
== 1)) ? __builtin_strspn (s, " ") : ((__a0 = ((const char *
) (" "))[0], __a0 == '\0') ? ((void) (s), (size_t) 0) : ((__a1
= ((const char *) (" "))[1], __a1 == '\0') ? __strspn_c1 (s,
__a0) : ((__a2 = ((const char *) (" "))[2], __a2 == '\0') ? __strspn_c2
(s, __a0, __a1) : (((const char *) (" "))[3] == '\0' ? __strspn_c3
(s, __a0, __a1, __a2) : __builtin_strspn (s, " ")))))) : __builtin_strspn
(s, " ")); })
))
621 memmove(s, s + l, strlen(s + l) + 1);
622 while (*s && *s != ' ')
623 s++;
624 }
625 if (--s >= r && *s == ' ')
626 *s = '\0'; /* trim any trailing space */
627 }
628 return r;
629}
630
631/* called when parser finds start of new tag */
632static void switch_xml_open_tag(switch_xml_root_t root, char *name, char **attr)
633{
634 switch_xml_t xml;
635
636 if (!root || !root->cur) {
637 return;
638 }
639
640 xml = root->cur;
641
642 if (xml->name)
643 xml = switch_xml_add_child(xml, name, strlen(xml->txt));
644 else
645 xml->name = name; /* first open tag */
646
647 xml->attr = attr;
648 root->cur = xml; /* update tag insertion point */
649}
650
651/* called when parser finds character content between open and closing tag */
652static void switch_xml_char_content(switch_xml_root_t root, char *s, switch_size_t len, char t)
653{
654 switch_xml_t xml;
655 char *m = s;
656 switch_size_t l;
657
658 if (!root || !root->cur) {
659 return;
660 }
661
662 xml = root->cur;
663
664 if (!xml || !xml->name || !len)
665 return; /* sanity check */
666
667 s[len] = '\0'; /* null terminate text (calling functions anticipate this) */
668 len = strlen(s = switch_xml_decode(s, root->ent, t)) + 1;
669
670 if (!*(xml->txt))
671 xml->txt = s; /* initial character content */
672 else { /* allocate our own memory and make a copy */
673 if ((xml->flags & SWITCH_XML_TXTM)) { /* allocate some space */
674 char *tmp = (char *) realloc(xml->txt, (l = strlen(xml->txt)) + len);
675 if (tmp) {
676 xml->txt = tmp;
677 } else {
678 return;
679 }
680 } else {
681 char *tmp = (char *) malloc((l = strlen(xml->txt)) + len);
682 if (tmp) {
683 xml->txt = strcpy(tmp, xml->txt);
684 } else {
685 return;
686 }
687 }
688 strcpy(xml->txt + l, s); /* add new char content */
689 if (s != m)
690 free(s); /* free s if it was malloced by switch_xml_decode() */
691 }
692
693 if (xml->txt != m)
694 switch_xml_set_flag(xml, SWITCH_XML_TXTM);
695}
696
697/* called when parser finds closing tag */
698static switch_xml_t switch_xml_close_tag(switch_xml_root_t root, char *name, char *s)
699{
700 if (!root || !root->cur || !root->cur->name || strcmp(name, root->cur->name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(name) && __builtin_constant_p (root->cur->name
) && (__s1_len = __builtin_strlen (name), __s2_len = __builtin_strlen
(root->cur->name), (!((size_t)(const void *)((name) + 1
) - (size_t)(const void *)(name) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((root->cur->name) + 1) - (size_t
)(const void *)(root->cur->name) == 1) || __s2_len >=
4)) ? __builtin_strcmp (name, root->cur->name) : (__builtin_constant_p
(name) && ((size_t)(const void *)((name) + 1) - (size_t
)(const void *)(name) == 1) && (__s1_len = __builtin_strlen
(name), __s1_len < 4) ? (__builtin_constant_p (root->cur
->name) && ((size_t)(const void *)((root->cur->
name) + 1) - (size_t)(const void *)(root->cur->name) ==
1) ? __builtin_strcmp (name, root->cur->name) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (root->cur->name); int __result = (((const unsigned
char *) (const char *) (name))[0] - __s2[0]); if (__s1_len >
0 && __result == 0) { __result = (((const unsigned char
*) (const char *) (name))[1] - __s2[1]); if (__s1_len > 1
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (name))[2] - __s2[2]); if (__s1_len > 2
&& __result == 0) __result = (((const unsigned char *
) (const char *) (name))[3] - __s2[3]); } } __result; }))) : (
__builtin_constant_p (root->cur->name) && ((size_t
)(const void *)((root->cur->name) + 1) - (size_t)(const
void *)(root->cur->name) == 1) && (__s2_len = __builtin_strlen
(root->cur->name), __s2_len < 4) ? (__builtin_constant_p
(name) && ((size_t)(const void *)((name) + 1) - (size_t
)(const void *)(name) == 1) ? __builtin_strcmp (name, root->
cur->name) : (- (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) (name); int __result
= (((const unsigned char *) (const char *) (root->cur->
name))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
root->cur->name))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (root->cur->name))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (root->cur->name))[3] - __s2[3]
); } } __result; })))) : __builtin_strcmp (name, root->cur
->name)))); })
)
701 return switch_xml_err(root, s, "unexpected closing tag </%s>", name);
702
703 root->cur = root->cur->parent;
704 return NULL((void*)0);
705}
706
707/* checks for circular entity references, returns non-zero if no circular
708 references are found, zero otherwise */
709static int switch_xml_ent_ok(char *name, char *s, char **ent)
710{
711 int i;
712
713 for (;; s++) {
714 while (*s && *s != '&')
715 s++; /* find next entity reference */
716 if (!*s)
717 return 1;
718 if (!strncmp(s + 1, name, strlen(name))(__extension__ (__builtin_constant_p (strlen(name)) &&
((__builtin_constant_p (s + 1) && strlen (s + 1) <
((size_t) (strlen(name)))) || (__builtin_constant_p (name) &&
strlen (name) < ((size_t) (strlen(name))))) ? __extension__
({ size_t __s1_len, __s2_len; (__builtin_constant_p (s + 1) &&
__builtin_constant_p (name) && (__s1_len = __builtin_strlen
(s + 1), __s2_len = __builtin_strlen (name), (!((size_t)(const
void *)((s + 1) + 1) - (size_t)(const void *)(s + 1) == 1) ||
__s1_len >= 4) && (!((size_t)(const void *)((name
) + 1) - (size_t)(const void *)(name) == 1) || __s2_len >=
4)) ? __builtin_strcmp (s + 1, name) : (__builtin_constant_p
(s + 1) && ((size_t)(const void *)((s + 1) + 1) - (size_t
)(const void *)(s + 1) == 1) && (__s1_len = __builtin_strlen
(s + 1), __s1_len < 4) ? (__builtin_constant_p (name) &&
((size_t)(const void *)((name) + 1) - (size_t)(const void *)
(name) == 1) ? __builtin_strcmp (s + 1, name) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (name); int __result = (((const unsigned char *) (const
char *) (s + 1))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (s + 1))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (s + 1))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (s + 1))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(name) && ((size_t)(const void *)((name) + 1) - (size_t
)(const void *)(name) == 1) && (__s2_len = __builtin_strlen
(name), __s2_len < 4) ? (__builtin_constant_p (s + 1) &&
((size_t)(const void *)((s + 1) + 1) - (size_t)(const void *
)(s + 1) == 1) ? __builtin_strcmp (s + 1, name) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (s + 1); int __result = (((const unsigned char *) (const
char *) (name))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (name))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (name))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(s + 1, name)))); }) : strncmp (s + 1, name, strlen(name))))
)
719 return 0; /* circular ref. */
720 for (i = 0; ent[i] && strncmp(ent[i], s + 1, strlen(ent[i]))(__extension__ (__builtin_constant_p (strlen(ent[i])) &&
((__builtin_constant_p (ent[i]) && strlen (ent[i]) <
((size_t) (strlen(ent[i])))) || (__builtin_constant_p (s + 1
) && strlen (s + 1) < ((size_t) (strlen(ent[i]))))
) ? __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(ent[i]) && __builtin_constant_p (s + 1) && (
__s1_len = __builtin_strlen (ent[i]), __s2_len = __builtin_strlen
(s + 1), (!((size_t)(const void *)((ent[i]) + 1) - (size_t)(
const void *)(ent[i]) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)((s + 1) + 1) - (size_t)(const void *
)(s + 1) == 1) || __s2_len >= 4)) ? __builtin_strcmp (ent[
i], s + 1) : (__builtin_constant_p (ent[i]) && ((size_t
)(const void *)((ent[i]) + 1) - (size_t)(const void *)(ent[i]
) == 1) && (__s1_len = __builtin_strlen (ent[i]), __s1_len
< 4) ? (__builtin_constant_p (s + 1) && ((size_t)
(const void *)((s + 1) + 1) - (size_t)(const void *)(s + 1) ==
1) ? __builtin_strcmp (ent[i], s + 1) : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(s + 1); int __result = (((const unsigned char *) (const char
*) (ent[i]))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
ent[i]))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
ent[i]))[2] - __s2[2]); if (__s1_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (ent
[i]))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(s + 1) && ((size_t)(const void *)((s + 1) + 1) - (size_t
)(const void *)(s + 1) == 1) && (__s2_len = __builtin_strlen
(s + 1), __s2_len < 4) ? (__builtin_constant_p (ent[i]) &&
((size_t)(const void *)((ent[i]) + 1) - (size_t)(const void *
)(ent[i]) == 1) ? __builtin_strcmp (ent[i], s + 1) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (ent[i]); int __result = (((const unsigned char *) (
const char *) (s + 1))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (s + 1))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (s + 1))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (s + 1))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(ent[i], s + 1)))); }) : strncmp (ent[i], s + 1, strlen(ent[
i]))))
; i += 2);
721 if (ent[i] && !switch_xml_ent_ok(name, ent[i + 1], ent))
722 return 0;
723 }
724}
725
726/* called when the parser finds a processing instruction */
727static void switch_xml_proc_inst(switch_xml_root_t root, char *s, switch_size_t len)
728{
729 int i = 0, j = 1;
730 char *target = s;
731 char **sstmp;
732 char *stmp;
733
734 s[len] = '\0'; /* null terminate instruction */
735 if (*(s += strcspn(s, SWITCH_XML_WS)__extension__ ({ char __r0, __r1, __r2; (__builtin_constant_p
("\t\r\n ") && ((size_t)(const void *)(("\t\r\n ") +
1) - (size_t)(const void *)("\t\r\n ") == 1) ? ((__builtin_constant_p
(s) && ((size_t)(const void *)((s) + 1) - (size_t)(const
void *)(s) == 1)) ? __builtin_strcspn (s, "\t\r\n ") : ((__r0
= ((const char *) ("\t\r\n "))[0], __r0 == '\0') ? strlen (s
) : ((__r1 = ((const char *) ("\t\r\n "))[1], __r1 == '\0') ?
__strcspn_c1 (s, __r0) : ((__r2 = ((const char *) ("\t\r\n "
))[2], __r2 == '\0') ? __strcspn_c2 (s, __r0, __r1) : (((const
char *) ("\t\r\n "))[3] == '\0' ? __strcspn_c3 (s, __r0, __r1
, __r2) : __builtin_strcspn (s, "\t\r\n ")))))) : __builtin_strcspn
(s, "\t\r\n ")); })
)) {
736 *s = '\0'; /* null terminate target */
737 s += strspn(s + 1, SWITCH_XML_WS)__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("\t\r\n ") && ((size_t)(const void *)(("\t\r\n ") +
1) - (size_t)(const void *)("\t\r\n ") == 1) ? ((__builtin_constant_p
(s + 1) && ((size_t)(const void *)((s + 1) + 1) - (size_t
)(const void *)(s + 1) == 1)) ? __builtin_strspn (s + 1, "\t\r\n "
) : ((__a0 = ((const char *) ("\t\r\n "))[0], __a0 == '\0') ?
((void) (s + 1), (size_t) 0) : ((__a1 = ((const char *) ("\t\r\n "
))[1], __a1 == '\0') ? __strspn_c1 (s + 1, __a0) : ((__a2 = (
(const char *) ("\t\r\n "))[2], __a2 == '\0') ? __strspn_c2 (
s + 1, __a0, __a1) : (((const char *) ("\t\r\n "))[3] == '\0'
? __strspn_c3 (s + 1, __a0, __a1, __a2) : __builtin_strspn (
s + 1, "\t\r\n ")))))) : __builtin_strspn (s + 1, "\t\r\n "))
; })
+ 1; /* skip whitespace after target */
738 }
739
740 if (!root)
741 return;
742
743 if (!strcmp(target, "xml")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(target) && __builtin_constant_p ("xml") && (
__s1_len = __builtin_strlen (target), __s2_len = __builtin_strlen
("xml"), (!((size_t)(const void *)((target) + 1) - (size_t)(
const void *)(target) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)(("xml") + 1) - (size_t)(const void *
)("xml") == 1) || __s2_len >= 4)) ? __builtin_strcmp (target
, "xml") : (__builtin_constant_p (target) && ((size_t
)(const void *)((target) + 1) - (size_t)(const void *)(target
) == 1) && (__s1_len = __builtin_strlen (target), __s1_len
< 4) ? (__builtin_constant_p ("xml") && ((size_t)
(const void *)(("xml") + 1) - (size_t)(const void *)("xml") ==
1) ? __builtin_strcmp (target, "xml") : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
("xml"); int __result = (((const unsigned char *) (const char
*) (target))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
target))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
target))[2] - __s2[2]); if (__s1_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (target
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
"xml") && ((size_t)(const void *)(("xml") + 1) - (size_t
)(const void *)("xml") == 1) && (__s2_len = __builtin_strlen
("xml"), __s2_len < 4) ? (__builtin_constant_p (target) &&
((size_t)(const void *)((target) + 1) - (size_t)(const void *
)(target) == 1) ? __builtin_strcmp (target, "xml") : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (target); int __result = (((const unsigned char *) (
const char *) ("xml"))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("xml"))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("xml"))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("xml"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(target, "xml")))); })
) { /* <?xml ... ?> */
744 if ((s = strstr(s, "standalone")) && !strncmp(s + strspn(s + 10, SWITCH_XML_WS "='\"") + 10, "yes", 3)(__extension__ (__builtin_constant_p (3) && ((__builtin_constant_p
(s + __extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("\t\r\n " "='\"") && ((size_t)(const void *)(("\t\r\n "
"='\"") + 1) - (size_t)(const void *)("\t\r\n " "='\"") == 1
) ? ((__builtin_constant_p (s + 10) && ((size_t)(const
void *)((s + 10) + 1) - (size_t)(const void *)(s + 10) == 1)
) ? __builtin_strspn (s + 10, "\t\r\n " "='\"") : ((__a0 = ((
const char *) ("\t\r\n " "='\""))[0], __a0 == '\0') ? ((void)
(s + 10), (size_t) 0) : ((__a1 = ((const char *) ("\t\r\n " "='\""
))[1], __a1 == '\0') ? __strspn_c1 (s + 10, __a0) : ((__a2 = (
(const char *) ("\t\r\n " "='\""))[2], __a2 == '\0') ? __strspn_c2
(s + 10, __a0, __a1) : (((const char *) ("\t\r\n " "='\""))[
3] == '\0' ? __strspn_c3 (s + 10, __a0, __a1, __a2) : __builtin_strspn
(s + 10, "\t\r\n " "='\"")))))) : __builtin_strspn (s + 10, "\t\r\n "
"='\"")); }) + 10) && strlen (s + __extension__ ({ char
__a0, __a1, __a2; (__builtin_constant_p ("\t\r\n " "='\"") &&
((size_t)(const void *)(("\t\r\n " "='\"") + 1) - (size_t)(const
void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p (s +
10) && ((size_t)(const void *)((s + 10) + 1) - (size_t
)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10, "\t\r\n "
"='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""))[0], __a0
== '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1 = ((const char
*) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1 (s + 10
, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\""))[2], __a2
== '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const char *
) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10, __a0,
__a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""))))
)) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10) <
((size_t) (3))) || (__builtin_constant_p ("yes") && strlen
("yes") < ((size_t) (3)))) ? __extension__ ({ size_t __s1_len
, __s2_len; (__builtin_constant_p (s + __extension__ ({ char __a0
, __a1, __a2; (__builtin_constant_p ("\t\r\n " "='\"") &&
((size_t)(const void *)(("\t\r\n " "='\"") + 1) - (size_t)(const
void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p (s +
10) && ((size_t)(const void *)((s + 10) + 1) - (size_t
)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10, "\t\r\n "
"='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""))[0], __a0
== '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1 = ((const char
*) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1 (s + 10
, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\""))[2], __a2
== '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const char *
) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10, __a0,
__a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""))))
)) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10) &&
__builtin_constant_p ("yes") && (__s1_len = __builtin_strlen
(s + __extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("\t\r\n " "='\"") && ((size_t)(const void *)(("\t\r\n "
"='\"") + 1) - (size_t)(const void *)("\t\r\n " "='\"") == 1
) ? ((__builtin_constant_p (s + 10) && ((size_t)(const
void *)((s + 10) + 1) - (size_t)(const void *)(s + 10) == 1)
) ? __builtin_strspn (s + 10, "\t\r\n " "='\"") : ((__a0 = ((
const char *) ("\t\r\n " "='\""))[0], __a0 == '\0') ? ((void)
(s + 10), (size_t) 0) : ((__a1 = ((const char *) ("\t\r\n " "='\""
))[1], __a1 == '\0') ? __strspn_c1 (s + 10, __a0) : ((__a2 = (
(const char *) ("\t\r\n " "='\""))[2], __a2 == '\0') ? __strspn_c2
(s + 10, __a0, __a1) : (((const char *) ("\t\r\n " "='\""))[
3] == '\0' ? __strspn_c3 (s + 10, __a0, __a1, __a2) : __builtin_strspn
(s + 10, "\t\r\n " "='\"")))))) : __builtin_strspn (s + 10, "\t\r\n "
"='\"")); }) + 10), __s2_len = __builtin_strlen ("yes"), (!(
(size_t)(const void *)((s + __extension__ ({ char __a0, __a1,
__a2; (__builtin_constant_p ("\t\r\n " "='\"") && ((
size_t)(const void *)(("\t\r\n " "='\"") + 1) - (size_t)(const
void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p (s +
10) && ((size_t)(const void *)((s + 10) + 1) - (size_t
)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10, "\t\r\n "
"='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""))[0], __a0
== '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1 = ((const char
*) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1 (s + 10
, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\""))[2], __a2
== '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const char *
) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10, __a0,
__a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""))))
)) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10) +
1) - (size_t)(const void *)(s + __extension__ ({ char __a0, __a1
, __a2; (__builtin_constant_p ("\t\r\n " "='\"") && (
(size_t)(const void *)(("\t\r\n " "='\"") + 1) - (size_t)(const
void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p (s +
10) && ((size_t)(const void *)((s + 10) + 1) - (size_t
)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10, "\t\r\n "
"='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""))[0], __a0
== '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1 = ((const char
*) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1 (s + 10
, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\""))[2], __a2
== '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const char *
) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10, __a0,
__a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""))))
)) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10) ==
1) || __s1_len >= 4) && (!((size_t)(const void *)
(("yes") + 1) - (size_t)(const void *)("yes") == 1) || __s2_len
>= 4)) ? __builtin_strcmp (s + __extension__ ({ char __a0
, __a1, __a2; (__builtin_constant_p ("\t\r\n " "='\"") &&
((size_t)(const void *)(("\t\r\n " "='\"") + 1) - (size_t)(const
void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p (s +
10) && ((size_t)(const void *)((s + 10) + 1) - (size_t
)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10, "\t\r\n "
"='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""))[0], __a0
== '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1 = ((const char
*) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1 (s + 10
, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\""))[2], __a2
== '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const char *
) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10, __a0,
__a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""))))
)) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10, "yes"
) : (__builtin_constant_p (s + __extension__ ({ char __a0, __a1
, __a2; (__builtin_constant_p ("\t\r\n " "='\"") && (
(size_t)(const void *)(("\t\r\n " "='\"") + 1) - (size_t)(const
void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p (s +
10) && ((size_t)(const void *)((s + 10) + 1) - (size_t
)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10, "\t\r\n "
"='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""))[0], __a0
== '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1 = ((const char
*) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1 (s + 10
, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\""))[2], __a2
== '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const char *
) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10, __a0,
__a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""))))
)) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10) &&
((size_t)(const void *)((s + __extension__ ({ char __a0, __a1
, __a2; (__builtin_constant_p ("\t\r\n " "='\"") && (
(size_t)(const void *)(("\t\r\n " "='\"") + 1) - (size_t)(const
void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p (s +
10) && ((size_t)(const void *)((s + 10) + 1) - (size_t
)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10, "\t\r\n "
"='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""))[0], __a0
== '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1 = ((const char
*) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1 (s + 10
, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\""))[2], __a2
== '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const char *
) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10, __a0,
__a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""))))
)) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10) +
1) - (size_t)(const void *)(s + __extension__ ({ char __a0, __a1
, __a2; (__builtin_constant_p ("\t\r\n " "='\"") && (
(size_t)(const void *)(("\t\r\n " "='\"") + 1) - (size_t)(const
void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p (s +
10) && ((size_t)(const void *)((s + 10) + 1) - (size_t
)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10, "\t\r\n "
"='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""))[0], __a0
== '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1 = ((const char
*) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1 (s + 10
, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\""))[2], __a2
== '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const char *
) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10, __a0,
__a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""))))
)) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10) ==
1) && (__s1_len = __builtin_strlen (s + __extension__
({ char __a0, __a1, __a2; (__builtin_constant_p ("\t\r\n " "='\""
) && ((size_t)(const void *)(("\t\r\n " "='\"") + 1) -
(size_t)(const void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p
(s + 10) && ((size_t)(const void *)((s + 10) + 1) - (
size_t)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10
, "\t\r\n " "='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""
))[0], __a0 == '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1
= ((const char *) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1
(s + 10, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\"")
)[2], __a2 == '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const
char *) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10
, __a0, __a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""
)))))) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10
), __s1_len < 4) ? (__builtin_constant_p ("yes") &&
((size_t)(const void *)(("yes") + 1) - (size_t)(const void *
)("yes") == 1) ? __builtin_strcmp (s + __extension__ ({ char __a0
, __a1, __a2; (__builtin_constant_p ("\t\r\n " "='\"") &&
((size_t)(const void *)(("\t\r\n " "='\"") + 1) - (size_t)(const
void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p (s +
10) && ((size_t)(const void *)((s + 10) + 1) - (size_t
)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10, "\t\r\n "
"='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""))[0], __a0
== '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1 = ((const char
*) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1 (s + 10
, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\""))[2], __a2
== '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const char *
) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10, __a0,
__a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""))))
)) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10, "yes"
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("yes"); int __result = (((const unsigned
char *) (const char *) (s + __extension__ ({ char __a0, __a1
, __a2; (__builtin_constant_p ("\t\r\n " "='\"") && (
(size_t)(const void *)(("\t\r\n " "='\"") + 1) - (size_t)(const
void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p (s +
10) && ((size_t)(const void *)((s + 10) + 1) - (size_t
)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10, "\t\r\n "
"='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""))[0], __a0
== '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1 = ((const char
*) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1 (s + 10
, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\""))[2], __a2
== '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const char *
) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10, __a0,
__a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""))))
)) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10))[
0] - __s2[0]); if (__s1_len > 0 && __result == 0) {
__result = (((const unsigned char *) (const char *) (s + __extension__
({ char __a0, __a1, __a2; (__builtin_constant_p ("\t\r\n " "='\""
) && ((size_t)(const void *)(("\t\r\n " "='\"") + 1) -
(size_t)(const void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p
(s + 10) && ((size_t)(const void *)((s + 10) + 1) - (
size_t)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10
, "\t\r\n " "='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""
))[0], __a0 == '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1
= ((const char *) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1
(s + 10, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\"")
)[2], __a2 == '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const
char *) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10
, __a0, __a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""
)))))) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10
))[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (s + __extension__
({ char __a0, __a1, __a2; (__builtin_constant_p ("\t\r\n " "='\""
) && ((size_t)(const void *)(("\t\r\n " "='\"") + 1) -
(size_t)(const void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p
(s + 10) && ((size_t)(const void *)((s + 10) + 1) - (
size_t)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10
, "\t\r\n " "='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""
))[0], __a0 == '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1
= ((const char *) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1
(s + 10, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\"")
)[2], __a2 == '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const
char *) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10
, __a0, __a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""
)))))) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (s + __extension__
({ char __a0, __a1, __a2; (__builtin_constant_p ("\t\r\n " "='\""
) && ((size_t)(const void *)(("\t\r\n " "='\"") + 1) -
(size_t)(const void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p
(s + 10) && ((size_t)(const void *)((s + 10) + 1) - (
size_t)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10
, "\t\r\n " "='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""
))[0], __a0 == '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1
= ((const char *) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1
(s + 10, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\"")
)[2], __a2 == '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const
char *) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10
, __a0, __a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""
)))))) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
"yes") && ((size_t)(const void *)(("yes") + 1) - (size_t
)(const void *)("yes") == 1) && (__s2_len = __builtin_strlen
("yes"), __s2_len < 4) ? (__builtin_constant_p (s + __extension__
({ char __a0, __a1, __a2; (__builtin_constant_p ("\t\r\n " "='\""
) && ((size_t)(const void *)(("\t\r\n " "='\"") + 1) -
(size_t)(const void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p
(s + 10) && ((size_t)(const void *)((s + 10) + 1) - (
size_t)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10
, "\t\r\n " "='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""
))[0], __a0 == '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1
= ((const char *) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1
(s + 10, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\"")
)[2], __a2 == '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const
char *) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10
, __a0, __a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""
)))))) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10
) && ((size_t)(const void *)((s + __extension__ ({ char
__a0, __a1, __a2; (__builtin_constant_p ("\t\r\n " "='\"") &&
((size_t)(const void *)(("\t\r\n " "='\"") + 1) - (size_t)(const
void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p (s +
10) && ((size_t)(const void *)((s + 10) + 1) - (size_t
)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10, "\t\r\n "
"='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""))[0], __a0
== '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1 = ((const char
*) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1 (s + 10
, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\""))[2], __a2
== '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const char *
) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10, __a0,
__a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""))))
)) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10) +
1) - (size_t)(const void *)(s + __extension__ ({ char __a0, __a1
, __a2; (__builtin_constant_p ("\t\r\n " "='\"") && (
(size_t)(const void *)(("\t\r\n " "='\"") + 1) - (size_t)(const
void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p (s +
10) && ((size_t)(const void *)((s + 10) + 1) - (size_t
)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10, "\t\r\n "
"='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""))[0], __a0
== '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1 = ((const char
*) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1 (s + 10
, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\""))[2], __a2
== '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const char *
) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10, __a0,
__a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""))))
)) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10) ==
1) ? __builtin_strcmp (s + __extension__ ({ char __a0, __a1,
__a2; (__builtin_constant_p ("\t\r\n " "='\"") && ((
size_t)(const void *)(("\t\r\n " "='\"") + 1) - (size_t)(const
void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p (s +
10) && ((size_t)(const void *)((s + 10) + 1) - (size_t
)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10, "\t\r\n "
"='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""))[0], __a0
== '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1 = ((const char
*) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1 (s + 10
, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\""))[2], __a2
== '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const char *
) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10, __a0,
__a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""))))
)) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10, "yes"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (s + __extension__ ({ char __a0, __a1
, __a2; (__builtin_constant_p ("\t\r\n " "='\"") && (
(size_t)(const void *)(("\t\r\n " "='\"") + 1) - (size_t)(const
void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p (s +
10) && ((size_t)(const void *)((s + 10) + 1) - (size_t
)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10, "\t\r\n "
"='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""))[0], __a0
== '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1 = ((const char
*) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1 (s + 10
, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\""))[2], __a2
== '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const char *
) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10, __a0,
__a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""))))
)) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10); int
__result = (((const unsigned char *) (const char *) ("yes"))
[0] - __s2[0]); if (__s2_len > 0 && __result == 0)
{ __result = (((const unsigned char *) (const char *) ("yes"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("yes"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("yes")
)[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (s + __extension__
({ char __a0, __a1, __a2; (__builtin_constant_p ("\t\r\n " "='\""
) && ((size_t)(const void *)(("\t\r\n " "='\"") + 1) -
(size_t)(const void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p
(s + 10) && ((size_t)(const void *)((s + 10) + 1) - (
size_t)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10
, "\t\r\n " "='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""
))[0], __a0 == '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1
= ((const char *) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1
(s + 10, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\"")
)[2], __a2 == '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const
char *) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10
, __a0, __a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""
)))))) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10
, "yes")))); }) : strncmp (s + __extension__ ({ char __a0, __a1
, __a2; (__builtin_constant_p ("\t\r\n " "='\"") && (
(size_t)(const void *)(("\t\r\n " "='\"") + 1) - (size_t)(const
void *)("\t\r\n " "='\"") == 1) ? ((__builtin_constant_p (s +
10) && ((size_t)(const void *)((s + 10) + 1) - (size_t
)(const void *)(s + 10) == 1)) ? __builtin_strspn (s + 10, "\t\r\n "
"='\"") : ((__a0 = ((const char *) ("\t\r\n " "='\""))[0], __a0
== '\0') ? ((void) (s + 10), (size_t) 0) : ((__a1 = ((const char
*) ("\t\r\n " "='\""))[1], __a1 == '\0') ? __strspn_c1 (s + 10
, __a0) : ((__a2 = ((const char *) ("\t\r\n " "='\""))[2], __a2
== '\0') ? __strspn_c2 (s + 10, __a0, __a1) : (((const char *
) ("\t\r\n " "='\""))[3] == '\0' ? __strspn_c3 (s + 10, __a0,
__a1, __a2) : __builtin_strspn (s + 10, "\t\r\n " "='\""))))
)) : __builtin_strspn (s + 10, "\t\r\n " "='\"")); }) + 10, "yes"
, 3)))
)
745 root->standalone = 1;
746 return;
747 }
748
749 if (!root->pi || !root->pi[0]) {
750 root->pi = (char ***) malloc(sizeof(char **));
751 if (!root->pi)
752 return;
753 *(root->pi) = NULL((void*)0); /* first pi */
754 }
755
756 while (root->pi[i] && strcmp(target, root->pi[i][0])__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(target) && __builtin_constant_p (root->pi[i][0])
&& (__s1_len = __builtin_strlen (target), __s2_len =
__builtin_strlen (root->pi[i][0]), (!((size_t)(const void
*)((target) + 1) - (size_t)(const void *)(target) == 1) || __s1_len
>= 4) && (!((size_t)(const void *)((root->pi[i
][0]) + 1) - (size_t)(const void *)(root->pi[i][0]) == 1) ||
__s2_len >= 4)) ? __builtin_strcmp (target, root->pi[i
][0]) : (__builtin_constant_p (target) && ((size_t)(const
void *)((target) + 1) - (size_t)(const void *)(target) == 1)
&& (__s1_len = __builtin_strlen (target), __s1_len <
4) ? (__builtin_constant_p (root->pi[i][0]) && ((
size_t)(const void *)((root->pi[i][0]) + 1) - (size_t)(const
void *)(root->pi[i][0]) == 1) ? __builtin_strcmp (target,
root->pi[i][0]) : (__extension__ ({ const unsigned char *
__s2 = (const unsigned char *) (const char *) (root->pi[i]
[0]); int __result = (((const unsigned char *) (const char *)
(target))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
target))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
target))[2] - __s2[2]); if (__s1_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (target
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
root->pi[i][0]) && ((size_t)(const void *)((root->
pi[i][0]) + 1) - (size_t)(const void *)(root->pi[i][0]) ==
1) && (__s2_len = __builtin_strlen (root->pi[i][0
]), __s2_len < 4) ? (__builtin_constant_p (target) &&
((size_t)(const void *)((target) + 1) - (size_t)(const void *
)(target) == 1) ? __builtin_strcmp (target, root->pi[i][0]
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (target); int __result = (((const unsigned
char *) (const char *) (root->pi[i][0]))[0] - __s2[0]); if
(__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) (root->pi[i][0]))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (root->pi[i][0
]))[2] - __s2[2]); if (__s2_len > 2 && __result ==
0) __result = (((const unsigned char *) (const char *) (root
->pi[i][0]))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(target, root->pi[i][0])))); })
)
757 i++; /* find target */
758 if (!root->pi[i]) { /* new target */
759 char ***ssstmp = (char ***) realloc(root->pi, sizeof(char **) * (i + 2));
760 if (!ssstmp)
761 return;
762 root->pi = ssstmp;
763 if (!root->pi)
764 return;
765 root->pi[i] = (char **) malloc(sizeof(char *) * 3);
766 if (!root->pi[i])
767 return;
768 root->pi[i][0] = target;
769 root->pi[i][1] = (char *) (root->pi[i + 1] = NULL((void*)0)); /* terminate pi list */
770 root->pi[i][2] = strdup("")(__extension__ (__builtin_constant_p ("") && ((size_t
)(const void *)(("") + 1) - (size_t)(const void *)("") == 1) ?
(((const char *) (""))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen ("") + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "", __len); __retval; })) : __strdup
("")))
; /* empty document position list */
771 }
772
773 while (root->pi[i][j])
774 j++; /* find end of instruction list for this target */
775 sstmp = (char **) realloc(root->pi[i], sizeof(char *) * (j + 3));
776 if (!sstmp)
777 return;
778 root->pi[i] = sstmp;
779 stmp = (char *) realloc(root->pi[i][j + 1], j + 1);
780 if (!stmp)
781 return;
782 root->pi[i][j + 2] = stmp;
783 strcpy(root->pi[i][j + 2] + j - 1, (root->xml.name) ? ">" : "<");
784 root->pi[i][j + 1] = NULL((void*)0); /* null terminate pi list for this target */
785 root->pi[i][j] = s; /* set instruction */
786}
787
788/* called when the parser finds an internal doctype subset */
789static short switch_xml_internal_dtd(switch_xml_root_t root, char *s, switch_size_t len)
790{
791 char q, *c, *t, *n = NULL((void*)0), *v, **ent, **pe;
792 int i, j;
793 char **sstmp;
794
795 pe = (char **) memcpy(malloc(sizeof(SWITCH_XML_NIL)), SWITCH_XML_NIL, sizeof(SWITCH_XML_NIL));
796
797 for (s[len] = '\0'; s;) {
798 while (*s && *s != '<' && *s != '%')
799 s++; /* find next declaration */
800
801 if (!*s)
802 break;
803 else if (!strncmp(s, "<!ENTITY", 8)(__extension__ (__builtin_constant_p (8) && ((__builtin_constant_p
(s) && strlen (s) < ((size_t) (8))) || (__builtin_constant_p
("<!ENTITY") && strlen ("<!ENTITY") < ((size_t
) (8)))) ? __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(s) && __builtin_constant_p ("<!ENTITY") &&
(__s1_len = __builtin_strlen (s), __s2_len = __builtin_strlen
("<!ENTITY"), (!((size_t)(const void *)((s) + 1) - (size_t
)(const void *)(s) == 1) || __s1_len >= 4) && (!((
size_t)(const void *)(("<!ENTITY") + 1) - (size_t)(const void
*)("<!ENTITY") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(s, "<!ENTITY") : (__builtin_constant_p (s) && ((
size_t)(const void *)((s) + 1) - (size_t)(const void *)(s) ==
1) && (__s1_len = __builtin_strlen (s), __s1_len <
4) ? (__builtin_constant_p ("<!ENTITY") && ((size_t
)(const void *)(("<!ENTITY") + 1) - (size_t)(const void *)
("<!ENTITY") == 1) ? __builtin_strcmp (s, "<!ENTITY") :
(__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("<!ENTITY"); int __result = (((const
unsigned char *) (const char *) (s))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (s))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (s))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (s))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("<!ENTITY") && ((size_t)(const void *)(("<!ENTITY"
) + 1) - (size_t)(const void *)("<!ENTITY") == 1) &&
(__s2_len = __builtin_strlen ("<!ENTITY"), __s2_len < 4
) ? (__builtin_constant_p (s) && ((size_t)(const void
*)((s) + 1) - (size_t)(const void *)(s) == 1) ? __builtin_strcmp
(s, "<!ENTITY") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (s); int __result
= (((const unsigned char *) (const char *) ("<!ENTITY"))[
0] - __s2[0]); if (__s2_len > 0 && __result == 0) {
__result = (((const unsigned char *) (const char *) ("<!ENTITY"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("<!ENTITY"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("<!ENTITY"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (s, "<!ENTITY"
)))); }) : strncmp (s, "<!ENTITY", 8)))
) { /* parse entity definitions */
804 c = s += strspn(s + 8, SWITCH_XML_WS)__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("\t\r\n ") && ((size_t)(const void *)(("\t\r\n ") +
1) - (size_t)(const void *)("\t\r\n ") == 1) ? ((__builtin_constant_p
(s + 8) && ((size_t)(const void *)((s + 8) + 1) - (size_t
)(const void *)(s + 8) == 1)) ? __builtin_strspn (s + 8, "\t\r\n "
) : ((__a0 = ((const char *) ("\t\r\n "))[0], __a0 == '\0') ?
((void) (s + 8), (size_t) 0) : ((__a1 = ((const char *) ("\t\r\n "
))[1], __a1 == '\0') ? __strspn_c1 (s + 8, __a0) : ((__a2 = (
(const char *) ("\t\r\n "))[2], __a2 == '\0') ? __strspn_c2 (
s + 8, __a0, __a1) : (((const char *) ("\t\r\n "))[3] == '\0'
? __strspn_c3 (s + 8, __a0, __a1, __a2) : __builtin_strspn (
s + 8, "\t\r\n ")))))) : __builtin_strspn (s + 8, "\t\r\n "))
; })
+ 8; /* skip white space separator */
805 n = s + strspn(s, SWITCH_XML_WS "%")__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("\t\r\n " "%") && ((size_t)(const void *)(("\t\r\n "
"%") + 1) - (size_t)(const void *)("\t\r\n " "%") == 1) ? ((
__builtin_constant_p (s) && ((size_t)(const void *)((
s) + 1) - (size_t)(const void *)(s) == 1)) ? __builtin_strspn
(s, "\t\r\n " "%") : ((__a0 = ((const char *) ("\t\r\n " "%"
))[0], __a0 == '\0') ? ((void) (s), (size_t) 0) : ((__a1 = ((
const char *) ("\t\r\n " "%"))[1], __a1 == '\0') ? __strspn_c1
(s, __a0) : ((__a2 = ((const char *) ("\t\r\n " "%"))[2], __a2
== '\0') ? __strspn_c2 (s, __a0, __a1) : (((const char *) ("\t\r\n "
"%"))[3] == '\0' ? __strspn_c3 (s, __a0, __a1, __a2) : __builtin_strspn
(s, "\t\r\n " "%")))))) : __builtin_strspn (s, "\t\r\n " "%"
)); })
; /* find name */
806 *(s = n + strcspn(n, SWITCH_XML_WS)__extension__ ({ char __r0, __r1, __r2; (__builtin_constant_p
("\t\r\n ") && ((size_t)(const void *)(("\t\r\n ") +
1) - (size_t)(const void *)("\t\r\n ") == 1) ? ((__builtin_constant_p
(n) && ((size_t)(const void *)((n) + 1) - (size_t)(const
void *)(n) == 1)) ? __builtin_strcspn (n, "\t\r\n ") : ((__r0
= ((const char *) ("\t\r\n "))[0], __r0 == '\0') ? strlen (n
) : ((__r1 = ((const char *) ("\t\r\n "))[1], __r1 == '\0') ?
__strcspn_c1 (n, __r0) : ((__r2 = ((const char *) ("\t\r\n "
))[2], __r2 == '\0') ? __strcspn_c2 (n, __r0, __r1) : (((const
char *) ("\t\r\n "))[3] == '\0' ? __strcspn_c3 (n, __r0, __r1
, __r2) : __builtin_strcspn (n, "\t\r\n ")))))) : __builtin_strcspn
(n, "\t\r\n ")); })
) = ';'; /* append ; to name */
807
808 v = s + strspn(s + 1, SWITCH_XML_WS)__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("\t\r\n ") && ((size_t)(const void *)(("\t\r\n ") +
1) - (size_t)(const void *)("\t\r\n ") == 1) ? ((__builtin_constant_p
(s + 1) && ((size_t)(const void *)((s + 1) + 1) - (size_t
)(const void *)(s + 1) == 1)) ? __builtin_strspn (s + 1, "\t\r\n "
) : ((__a0 = ((const char *) ("\t\r\n "))[0], __a0 == '\0') ?
((void) (s + 1), (size_t) 0) : ((__a1 = ((const char *) ("\t\r\n "
))[1], __a1 == '\0') ? __strspn_c1 (s + 1, __a0) : ((__a2 = (
(const char *) ("\t\r\n "))[2], __a2 == '\0') ? __strspn_c2 (
s + 1, __a0, __a1) : (((const char *) ("\t\r\n "))[3] == '\0'
? __strspn_c3 (s + 1, __a0, __a1, __a2) : __builtin_strspn (
s + 1, "\t\r\n ")))))) : __builtin_strspn (s + 1, "\t\r\n "))
; })
+ 1; /* find value */
809 if ((q = *(v++)) != '"' && q != '\'') { /* skip externals */
810 s = strchr(s, '>')(__extension__ (__builtin_constant_p ('>') && !__builtin_constant_p
(s) && ('>') == '\0' ? (char *) __rawmemchr (s, '>'
) : __builtin_strchr (s, '>')))
;
811 continue;
812 }
813
814 for (i = 0, ent = (*c == '%') ? pe : root->ent; ent[i]; i++);
815 sstmp = (char **) realloc(ent, (i + 3) * sizeof(char *)); /* space for next ent */
816 if (!sstmp) {
817 switch_xml_err(root, v, "Allocation Error!");
818 break;
819 }
820 ent = sstmp;
821 if (*c == '%')
822 pe = ent;
823 else
824 root->ent = ent;
825
826 *(++s) = '\0'; /* null terminate name */
827 if ((s = strchr(v, q)(__extension__ (__builtin_constant_p (q) && !__builtin_constant_p
(v) && (q) == '\0' ? (char *) __rawmemchr (v, q) : __builtin_strchr
(v, q)))
))
828 *(s++) = '\0'; /* null terminate value */
829 ent[i + 1] = switch_xml_decode(v, pe, '%'); /* set value */
830 ent[i + 2] = NULL((void*)0); /* null terminate entity list */
831 if (!switch_xml_ent_ok(n, ent[i + 1], ent)) { /* circular reference */
832 if (ent[i + 1] != v)
833 free(ent[i + 1]);
834 switch_xml_err(root, v, "circular entity declaration &%s", n);
835 break;
836 } else
837 ent[i] = n; /* set entity name */
838 } else if (!strncmp(s, "<!ATTLIST", 9)(__extension__ (__builtin_constant_p (9) && ((__builtin_constant_p
(s) && strlen (s) < ((size_t) (9))) || (__builtin_constant_p
("<!ATTLIST") && strlen ("<!ATTLIST") < ((size_t
) (9)))) ? __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(s) && __builtin_constant_p ("<!ATTLIST") &&
(__s1_len = __builtin_strlen (s), __s2_len = __builtin_strlen
("<!ATTLIST"), (!((size_t)(const void *)((s) + 1) - (size_t
)(const void *)(s) == 1) || __s1_len >= 4) && (!((
size_t)(const void *)(("<!ATTLIST") + 1) - (size_t)(const void
*)("<!ATTLIST") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(s, "<!ATTLIST") : (__builtin_constant_p (s) && (
(size_t)(const void *)((s) + 1) - (size_t)(const void *)(s) ==
1) && (__s1_len = __builtin_strlen (s), __s1_len <
4) ? (__builtin_constant_p ("<!ATTLIST") && ((size_t
)(const void *)(("<!ATTLIST") + 1) - (size_t)(const void *
)("<!ATTLIST") == 1) ? __builtin_strcmp (s, "<!ATTLIST"
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("<!ATTLIST"); int __result = (((const
unsigned char *) (const char *) (s))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (s))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (s))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (s))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("<!ATTLIST") && ((size_t)(const void *)(("<!ATTLIST"
) + 1) - (size_t)(const void *)("<!ATTLIST") == 1) &&
(__s2_len = __builtin_strlen ("<!ATTLIST"), __s2_len <
4) ? (__builtin_constant_p (s) && ((size_t)(const void
*)((s) + 1) - (size_t)(const void *)(s) == 1) ? __builtin_strcmp
(s, "<!ATTLIST") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (s); int __result
= (((const unsigned char *) (const char *) ("<!ATTLIST"))
[0] - __s2[0]); if (__s2_len > 0 && __result == 0)
{ __result = (((const unsigned char *) (const char *) ("<!ATTLIST"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("<!ATTLIST"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("<!ATTLIST"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (s, "<!ATTLIST"
)))); }) : strncmp (s, "<!ATTLIST", 9)))
) { /* parse default attributes */
839 t = s + strspn(s + 9, SWITCH_XML_WS)__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("\t\r\n ") && ((size_t)(const void *)(("\t\r\n ") +
1) - (size_t)(const void *)("\t\r\n ") == 1) ? ((__builtin_constant_p
(s + 9) && ((size_t)(const void *)((s + 9) + 1) - (size_t
)(const void *)(s + 9) == 1)) ? __builtin_strspn (s + 9, "\t\r\n "
) : ((__a0 = ((const char *) ("\t\r\n "))[0], __a0 == '\0') ?
((void) (s + 9), (size_t) 0) : ((__a1 = ((const char *) ("\t\r\n "
))[1], __a1 == '\0') ? __strspn_c1 (s + 9, __a0) : ((__a2 = (
(const char *) ("\t\r\n "))[2], __a2 == '\0') ? __strspn_c2 (
s + 9, __a0, __a1) : (((const char *) ("\t\r\n "))[3] == '\0'
? __strspn_c3 (s + 9, __a0, __a1, __a2) : __builtin_strspn (
s + 9, "\t\r\n ")))))) : __builtin_strspn (s + 9, "\t\r\n "))
; })
+ 9; /* skip whitespace separator */
840 if (!*t) {
841 switch_xml_err(root, t, "unclosed <!ATTLIST");
842 break;
843 }
844 if (*(s = t + strcspn(t, SWITCH_XML_WS ">")__extension__ ({ char __r0, __r1, __r2; (__builtin_constant_p
("\t\r\n " ">") && ((size_t)(const void *)(("\t\r\n "
">") + 1) - (size_t)(const void *)("\t\r\n " ">") == 1
) ? ((__builtin_constant_p (t) && ((size_t)(const void
*)((t) + 1) - (size_t)(const void *)(t) == 1)) ? __builtin_strcspn
(t, "\t\r\n " ">") : ((__r0 = ((const char *) ("\t\r\n " ">"
))[0], __r0 == '\0') ? strlen (t) : ((__r1 = ((const char *) (
"\t\r\n " ">"))[1], __r1 == '\0') ? __strcspn_c1 (t, __r0)
: ((__r2 = ((const char *) ("\t\r\n " ">"))[2], __r2 == '\0'
) ? __strcspn_c2 (t, __r0, __r1) : (((const char *) ("\t\r\n "
">"))[3] == '\0' ? __strcspn_c3 (t, __r0, __r1, __r2) : __builtin_strcspn
(t, "\t\r\n " ">")))))) : __builtin_strcspn (t, "\t\r\n "
">")); })
) == '>')
845 continue;
846 else
847 *s = '\0'; /* null terminate tag name */
848 for (i = 0; root->attr[i] && strcmp(n, root->attr[i][0])__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(n) && __builtin_constant_p (root->attr[i][0]) &&
(__s1_len = __builtin_strlen (n), __s2_len = __builtin_strlen
(root->attr[i][0]), (!((size_t)(const void *)((n) + 1) - (
size_t)(const void *)(n) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((root->attr[i][0]) + 1) - (size_t
)(const void *)(root->attr[i][0]) == 1) || __s2_len >= 4
)) ? __builtin_strcmp (n, root->attr[i][0]) : (__builtin_constant_p
(n) && ((size_t)(const void *)((n) + 1) - (size_t)(const
void *)(n) == 1) && (__s1_len = __builtin_strlen (n)
, __s1_len < 4) ? (__builtin_constant_p (root->attr[i][
0]) && ((size_t)(const void *)((root->attr[i][0]) +
1) - (size_t)(const void *)(root->attr[i][0]) == 1) ? __builtin_strcmp
(n, root->attr[i][0]) : (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (root->attr
[i][0]); int __result = (((const unsigned char *) (const char
*) (n))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
n))[1] - __s2[1]); if (__s1_len > 1 && __result ==
0) { __result = (((const unsigned char *) (const char *) (n)
)[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (n))[3]
- __s2[3]); } } __result; }))) : (__builtin_constant_p (root
->attr[i][0]) && ((size_t)(const void *)((root->
attr[i][0]) + 1) - (size_t)(const void *)(root->attr[i][0]
) == 1) && (__s2_len = __builtin_strlen (root->attr
[i][0]), __s2_len < 4) ? (__builtin_constant_p (n) &&
((size_t)(const void *)((n) + 1) - (size_t)(const void *)(n)
== 1) ? __builtin_strcmp (n, root->attr[i][0]) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (n); int __result = (((const unsigned char *) (const
char *) (root->attr[i][0]))[0] - __s2[0]); if (__s2_len >
0 && __result == 0) { __result = (((const unsigned char
*) (const char *) (root->attr[i][0]))[1] - __s2[1]); if (
__s2_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) (root->attr[i][0]))[2] - __s2
[2]); if (__s2_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (root->attr[i][0
]))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (n,
root->attr[i][0])))); })
; i++);
849
850 //while (*(n = ++s + strspn(s, SWITCH_XML_WS)) && *n != '>') {
851 // gcc 4.4 you are a creep
852 for (;;) {
853 s++;
854 if (!(*(n = s + strspn(s, SWITCH_XML_WS)__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("\t\r\n ") && ((size_t)(const void *)(("\t\r\n ") +
1) - (size_t)(const void *)("\t\r\n ") == 1) ? ((__builtin_constant_p
(s) && ((size_t)(const void *)((s) + 1) - (size_t)(const
void *)(s) == 1)) ? __builtin_strspn (s, "\t\r\n ") : ((__a0
= ((const char *) ("\t\r\n "))[0], __a0 == '\0') ? ((void) (
s), (size_t) 0) : ((__a1 = ((const char *) ("\t\r\n "))[1], __a1
== '\0') ? __strspn_c1 (s, __a0) : ((__a2 = ((const char *) (
"\t\r\n "))[2], __a2 == '\0') ? __strspn_c2 (s, __a0, __a1) :
(((const char *) ("\t\r\n "))[3] == '\0' ? __strspn_c3 (s, __a0
, __a1, __a2) : __builtin_strspn (s, "\t\r\n ")))))) : __builtin_strspn
(s, "\t\r\n ")); })
) && *n != '>')) {
855 break;
856 }
857 if (*(s = n + strcspn(n, SWITCH_XML_WS)__extension__ ({ char __r0, __r1, __r2; (__builtin_constant_p
("\t\r\n ") && ((size_t)(const void *)(("\t\r\n ") +
1) - (size_t)(const void *)("\t\r\n ") == 1) ? ((__builtin_constant_p
(n) && ((size_t)(const void *)((n) + 1) - (size_t)(const
void *)(n) == 1)) ? __builtin_strcspn (n, "\t\r\n ") : ((__r0
= ((const char *) ("\t\r\n "))[0], __r0 == '\0') ? strlen (n
) : ((__r1 = ((const char *) ("\t\r\n "))[1], __r1 == '\0') ?
__strcspn_c1 (n, __r0) : ((__r2 = ((const char *) ("\t\r\n "
))[2], __r2 == '\0') ? __strcspn_c2 (n, __r0, __r1) : (((const
char *) ("\t\r\n "))[3] == '\0' ? __strcspn_c3 (n, __r0, __r1
, __r2) : __builtin_strcspn (n, "\t\r\n ")))))) : __builtin_strcspn
(n, "\t\r\n ")); })
))
858 *s = '\0'; /* attr name */
859 else {
860 switch_xml_err(root, t, "malformed <!ATTLIST");
861 break;
862 }
863
864 s += strspn(s + 1, SWITCH_XML_WS)__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("\t\r\n ") && ((size_t)(const void *)(("\t\r\n ") +
1) - (size_t)(const void *)("\t\r\n ") == 1) ? ((__builtin_constant_p
(s + 1) && ((size_t)(const void *)((s + 1) + 1) - (size_t
)(const void *)(s + 1) == 1)) ? __builtin_strspn (s + 1, "\t\r\n "
) : ((__a0 = ((const char *) ("\t\r\n "))[0], __a0 == '\0') ?
((void) (s + 1), (size_t) 0) : ((__a1 = ((const char *) ("\t\r\n "
))[1], __a1 == '\0') ? __strspn_c1 (s + 1, __a0) : ((__a2 = (
(const char *) ("\t\r\n "))[2], __a2 == '\0') ? __strspn_c2 (
s + 1, __a0, __a1) : (((const char *) ("\t\r\n "))[3] == '\0'
? __strspn_c3 (s + 1, __a0, __a1, __a2) : __builtin_strspn (
s + 1, "\t\r\n ")))))) : __builtin_strspn (s + 1, "\t\r\n "))
; })
+ 1; /* find next token */
865 c = (strncmp(s, "CDATA", 5)(__extension__ (__builtin_constant_p (5) && ((__builtin_constant_p
(s) && strlen (s) < ((size_t) (5))) || (__builtin_constant_p
("CDATA") && strlen ("CDATA") < ((size_t) (5)))) ?
__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(s) && __builtin_constant_p ("CDATA") && (__s1_len
= __builtin_strlen (s), __s2_len = __builtin_strlen ("CDATA"
), (!((size_t)(const void *)((s) + 1) - (size_t)(const void *
)(s) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)(("CDATA") + 1) - (size_t)(const void *)("CDATA") == 1) ||
__s2_len >= 4)) ? __builtin_strcmp (s, "CDATA") : (__builtin_constant_p
(s) && ((size_t)(const void *)((s) + 1) - (size_t)(const
void *)(s) == 1) && (__s1_len = __builtin_strlen (s)
, __s1_len < 4) ? (__builtin_constant_p ("CDATA") &&
((size_t)(const void *)(("CDATA") + 1) - (size_t)(const void
*)("CDATA") == 1) ? __builtin_strcmp (s, "CDATA") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("CDATA"); int __result = (((const unsigned char *) (
const char *) (s))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (s))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
s))[2] - __s2[2]); if (__s1_len > 2 && __result ==
0) __result = (((const unsigned char *) (const char *) (s))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("CDATA"
) && ((size_t)(const void *)(("CDATA") + 1) - (size_t
)(const void *)("CDATA") == 1) && (__s2_len = __builtin_strlen
("CDATA"), __s2_len < 4) ? (__builtin_constant_p (s) &&
((size_t)(const void *)((s) + 1) - (size_t)(const void *)(s)
== 1) ? __builtin_strcmp (s, "CDATA") : (- (__extension__ ({
const unsigned char *__s2 = (const unsigned char *) (const char
*) (s); int __result = (((const unsigned char *) (const char
*) ("CDATA"))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
"CDATA"))[1] - __s2[1]); if (__s2_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
"CDATA"))[2] - __s2[2]); if (__s2_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) ("CDATA"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (s, "CDATA"
)))); }) : strncmp (s, "CDATA", 5)))
) ? (char *) "*" : (char *) " "; /* is it cdata? */
866 if (!strncmp(s, "NOTATION", 8)(__extension__ (__builtin_constant_p (8) && ((__builtin_constant_p
(s) && strlen (s) < ((size_t) (8))) || (__builtin_constant_p
("NOTATION") && strlen ("NOTATION") < ((size_t) (
8)))) ? __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(s) && __builtin_constant_p ("NOTATION") && (
__s1_len = __builtin_strlen (s), __s2_len = __builtin_strlen (
"NOTATION"), (!((size_t)(const void *)((s) + 1) - (size_t)(const
void *)(s) == 1) || __s1_len >= 4) && (!((size_t)
(const void *)(("NOTATION") + 1) - (size_t)(const void *)("NOTATION"
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (s, "NOTATION"
) : (__builtin_constant_p (s) && ((size_t)(const void
*)((s) + 1) - (size_t)(const void *)(s) == 1) && (__s1_len
= __builtin_strlen (s), __s1_len < 4) ? (__builtin_constant_p
("NOTATION") && ((size_t)(const void *)(("NOTATION")
+ 1) - (size_t)(const void *)("NOTATION") == 1) ? __builtin_strcmp
(s, "NOTATION") : (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) ("NOTATION"); int __result
= (((const unsigned char *) (const char *) (s))[0] - __s2[0]
); if (__s1_len > 0 && __result == 0) { __result =
(((const unsigned char *) (const char *) (s))[1] - __s2[1]);
if (__s1_len > 1 && __result == 0) { __result = (
((const unsigned char *) (const char *) (s))[2] - __s2[2]); if
(__s1_len > 2 && __result == 0) __result = (((const
unsigned char *) (const char *) (s))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p ("NOTATION") && ((size_t
)(const void *)(("NOTATION") + 1) - (size_t)(const void *)("NOTATION"
) == 1) && (__s2_len = __builtin_strlen ("NOTATION"),
__s2_len < 4) ? (__builtin_constant_p (s) && ((size_t
)(const void *)((s) + 1) - (size_t)(const void *)(s) == 1) ? __builtin_strcmp
(s, "NOTATION") : (- (__extension__ ({ const unsigned char *
__s2 = (const unsigned char *) (const char *) (s); int __result
= (((const unsigned char *) (const char *) ("NOTATION"))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("NOTATION"))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("NOTATION"))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("NOTATION"))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (s, "NOTATION"
)))); }) : strncmp (s, "NOTATION", 8)))
)
867 s += strspn(s + 8, SWITCH_XML_WS)__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("\t\r\n ") && ((size_t)(const void *)(("\t\r\n ") +
1) - (size_t)(const void *)("\t\r\n ") == 1) ? ((__builtin_constant_p
(s + 8) && ((size_t)(const void *)((s + 8) + 1) - (size_t
)(const void *)(s + 8) == 1)) ? __builtin_strspn (s + 8, "\t\r\n "
) : ((__a0 = ((const char *) ("\t\r\n "))[0], __a0 == '\0') ?
((void) (s + 8), (size_t) 0) : ((__a1 = ((const char *) ("\t\r\n "
))[1], __a1 == '\0') ? __strspn_c1 (s + 8, __a0) : ((__a2 = (
(const char *) ("\t\r\n "))[2], __a2 == '\0') ? __strspn_c2 (
s + 8, __a0, __a1) : (((const char *) ("\t\r\n "))[3] == '\0'
? __strspn_c3 (s + 8, __a0, __a1, __a2) : __builtin_strspn (
s + 8, "\t\r\n ")))))) : __builtin_strspn (s + 8, "\t\r\n "))
; })
+ 8;
868 s = (*s == '(') ? strchr(s, ')')(__extension__ (__builtin_constant_p (')') && !__builtin_constant_p
(s) && (')') == '\0' ? (char *) __rawmemchr (s, ')')
: __builtin_strchr (s, ')')))
: s + strcspn(s, SWITCH_XML_WS)__extension__ ({ char __r0, __r1, __r2; (__builtin_constant_p
("\t\r\n ") && ((size_t)(const void *)(("\t\r\n ") +
1) - (size_t)(const void *)("\t\r\n ") == 1) ? ((__builtin_constant_p
(s) && ((size_t)(const void *)((s) + 1) - (size_t)(const
void *)(s) == 1)) ? __builtin_strcspn (s, "\t\r\n ") : ((__r0
= ((const char *) ("\t\r\n "))[0], __r0 == '\0') ? strlen (s
) : ((__r1 = ((const char *) ("\t\r\n "))[1], __r1 == '\0') ?
__strcspn_c1 (s, __r0) : ((__r2 = ((const char *) ("\t\r\n "
))[2], __r2 == '\0') ? __strcspn_c2 (s, __r0, __r1) : (((const
char *) ("\t\r\n "))[3] == '\0' ? __strcspn_c3 (s, __r0, __r1
, __r2) : __builtin_strcspn (s, "\t\r\n ")))))) : __builtin_strcspn
(s, "\t\r\n ")); })
;
869 if (!s) {
870 switch_xml_err(root, t, "malformed <!ATTLIST");
871 break;
872 }
873
874 s += strspn(s, SWITCH_XML_WS ")")__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("\t\r\n " ")") && ((size_t)(const void *)(("\t\r\n "
")") + 1) - (size_t)(const void *)("\t\r\n " ")") == 1) ? ((
__builtin_constant_p (s) && ((size_t)(const void *)((
s) + 1) - (size_t)(const void *)(s) == 1)) ? __builtin_strspn
(s, "\t\r\n " ")") : ((__a0 = ((const char *) ("\t\r\n " ")"
))[0], __a0 == '\0') ? ((void) (s), (size_t) 0) : ((__a1 = ((
const char *) ("\t\r\n " ")"))[1], __a1 == '\0') ? __strspn_c1
(s, __a0) : ((__a2 = ((const char *) ("\t\r\n " ")"))[2], __a2
== '\0') ? __strspn_c2 (s, __a0, __a1) : (((const char *) ("\t\r\n "
")"))[3] == '\0' ? __strspn_c3 (s, __a0, __a1, __a2) : __builtin_strspn
(s, "\t\r\n " ")")))))) : __builtin_strspn (s, "\t\r\n " ")"
)); })
; /* skip white space separator */
875 if (!strncmp(s, "#FIXED", 6)(__extension__ (__builtin_constant_p (6) && ((__builtin_constant_p
(s) && strlen (s) < ((size_t) (6))) || (__builtin_constant_p
("#FIXED") && strlen ("#FIXED") < ((size_t) (6)))
) ? __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(s) && __builtin_constant_p ("#FIXED") && (__s1_len
= __builtin_strlen (s), __s2_len = __builtin_strlen ("#FIXED"
), (!((size_t)(const void *)((s) + 1) - (size_t)(const void *
)(s) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)(("#FIXED") + 1) - (size_t)(const void *)("#FIXED") == 1) ||
__s2_len >= 4)) ? __builtin_strcmp (s, "#FIXED") : (__builtin_constant_p
(s) && ((size_t)(const void *)((s) + 1) - (size_t)(const
void *)(s) == 1) && (__s1_len = __builtin_strlen (s)
, __s1_len < 4) ? (__builtin_constant_p ("#FIXED") &&
((size_t)(const void *)(("#FIXED") + 1) - (size_t)(const void
*)("#FIXED") == 1) ? __builtin_strcmp (s, "#FIXED") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("#FIXED"); int __result = (((const unsigned char *)
(const char *) (s))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (s))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
s))[2] - __s2[2]); if (__s1_len > 2 && __result ==
0) __result = (((const unsigned char *) (const char *) (s))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("#FIXED"
) && ((size_t)(const void *)(("#FIXED") + 1) - (size_t
)(const void *)("#FIXED") == 1) && (__s2_len = __builtin_strlen
("#FIXED"), __s2_len < 4) ? (__builtin_constant_p (s) &&
((size_t)(const void *)((s) + 1) - (size_t)(const void *)(s)
== 1) ? __builtin_strcmp (s, "#FIXED") : (- (__extension__ (
{ const unsigned char *__s2 = (const unsigned char *) (const char
*) (s); int __result = (((const unsigned char *) (const char
*) ("#FIXED"))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("#FIXED"))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("#FIXED"))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("#FIXED"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(s, "#FIXED")))); }) : strncmp (s, "#FIXED", 6)))
)
876 s += strspn(s + 6, SWITCH_XML_WS)__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("\t\r\n ") && ((size_t)(const void *)(("\t\r\n ") +
1) - (size_t)(const void *)("\t\r\n ") == 1) ? ((__builtin_constant_p
(s + 6) && ((size_t)(const void *)((s + 6) + 1) - (size_t
)(const void *)(s + 6) == 1)) ? __builtin_strspn (s + 6, "\t\r\n "
) : ((__a0 = ((const char *) ("\t\r\n "))[0], __a0 == '\0') ?
((void) (s + 6), (size_t) 0) : ((__a1 = ((const char *) ("\t\r\n "
))[1], __a1 == '\0') ? __strspn_c1 (s + 6, __a0) : ((__a2 = (
(const char *) ("\t\r\n "))[2], __a2 == '\0') ? __strspn_c2 (
s + 6, __a0, __a1) : (((const char *) ("\t\r\n "))[3] == '\0'
? __strspn_c3 (s + 6, __a0, __a1, __a2) : __builtin_strspn (
s + 6, "\t\r\n ")))))) : __builtin_strspn (s + 6, "\t\r\n "))
; })
+ 6;
877 if (*s == '#') { /* no default value */
878 s += strcspn(s, SWITCH_XML_WS ">")__extension__ ({ char __r0, __r1, __r2; (__builtin_constant_p
("\t\r\n " ">") && ((size_t)(const void *)(("\t\r\n "
">") + 1) - (size_t)(const void *)("\t\r\n " ">") == 1
) ? ((__builtin_constant_p (s) && ((size_t)(const void
*)((s) + 1) - (size_t)(const void *)(s) == 1)) ? __builtin_strcspn
(s, "\t\r\n " ">") : ((__r0 = ((const char *) ("\t\r\n " ">"
))[0], __r0 == '\0') ? strlen (s) : ((__r1 = ((const char *) (
"\t\r\n " ">"))[1], __r1 == '\0') ? __strcspn_c1 (s, __r0)
: ((__r2 = ((const char *) ("\t\r\n " ">"))[2], __r2 == '\0'
) ? __strcspn_c2 (s, __r0, __r1) : (((const char *) ("\t\r\n "
">"))[3] == '\0' ? __strcspn_c3 (s, __r0, __r1, __r2) : __builtin_strcspn
(s, "\t\r\n " ">")))))) : __builtin_strcspn (s, "\t\r\n "
">")); })
- 1;
879 if (*c == ' ')
880 continue; /* cdata is default, nothing to do */
881 v = NULL((void*)0);
882 } else if ((*s == '"' || *s == '\'') && /* default value */
883 (s = strchr(v = s + 1, *s)(__extension__ (__builtin_constant_p (*s) && !__builtin_constant_p
(v = s + 1) && (*s) == '\0' ? (char *) __rawmemchr (
v = s + 1, *s) : __builtin_strchr (v = s + 1, *s)))
))
884 *s = '\0';
885 else {
886 switch_xml_err(root, t, "malformed <!ATTLIST");
887 break;
888 }
889
890 if (!root->attr[i]) { /* new tag name */
891 root->attr = (!i) ? (char ***) malloc(2 * sizeof(char **))
892 : (char ***) realloc(root->attr, (i + 2) * sizeof(char **));
893 root->attr[i] = (char **) malloc(2 * sizeof(char *));
894 root->attr[i][0] = t; /* set tag name */
895 root->attr[i][1] = (char *) (root->attr[i + 1] = NULL((void*)0));
896 }
897
898 for (j = 1; root->attr[i][j]; j += 3); /* find end of list */
899 sstmp = (char **) realloc(root->attr[i], (j + 4) * sizeof(char *));
900
901 if (!sstmp) {
902 switch_xml_err(root, t, "Allocation Error!");
903 break;
904 }
905
906 root->attr[i] = sstmp;
907 root->attr[i][j + 3] = NULL((void*)0); /* null terminate list */
908 root->attr[i][j + 2] = c; /* is it cdata? */
909 root->attr[i][j + 1] = (v) ? switch_xml_decode(v, root->ent, *c) : NULL((void*)0);
910 root->attr[i][j] = n; /* attribute name */
911 }
912 } else if (!strncmp(s, "<!--", 4)(__extension__ (__builtin_constant_p (4) && ((__builtin_constant_p
(s) && strlen (s) < ((size_t) (4))) || (__builtin_constant_p
("<!--") && strlen ("<!--") < ((size_t) (4)
))) ? __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(s) && __builtin_constant_p ("<!--") && (
__s1_len = __builtin_strlen (s), __s2_len = __builtin_strlen (
"<!--"), (!((size_t)(const void *)((s) + 1) - (size_t)(const
void *)(s) == 1) || __s1_len >= 4) && (!((size_t)
(const void *)(("<!--") + 1) - (size_t)(const void *)("<!--"
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (s, "<!--"
) : (__builtin_constant_p (s) && ((size_t)(const void
*)((s) + 1) - (size_t)(const void *)(s) == 1) && (__s1_len
= __builtin_strlen (s), __s1_len < 4) ? (__builtin_constant_p
("<!--") && ((size_t)(const void *)(("<!--") +
1) - (size_t)(const void *)("<!--") == 1) ? __builtin_strcmp
(s, "<!--") : (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) ("<!--"); int __result
= (((const unsigned char *) (const char *) (s))[0] - __s2[0]
); if (__s1_len > 0 && __result == 0) { __result =
(((const unsigned char *) (const char *) (s))[1] - __s2[1]);
if (__s1_len > 1 && __result == 0) { __result = (
((const unsigned char *) (const char *) (s))[2] - __s2[2]); if
(__s1_len > 2 && __result == 0) __result = (((const
unsigned char *) (const char *) (s))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p ("<!--") && ((size_t
)(const void *)(("<!--") + 1) - (size_t)(const void *)("<!--"
) == 1) && (__s2_len = __builtin_strlen ("<!--"), __s2_len
< 4) ? (__builtin_constant_p (s) && ((size_t)(const
void *)((s) + 1) - (size_t)(const void *)(s) == 1) ? __builtin_strcmp
(s, "<!--") : (- (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) (s); int __result =
(((const unsigned char *) (const char *) ("<!--"))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("<!--"))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("<!--"))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("<!--"))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (s, "<!--"
)))); }) : strncmp (s, "<!--", 4)))
)
913 s = strstr(s + 4, "-->"); /* comments */
914 else if (!strncmp(s, "<?", 2)(__extension__ (__builtin_constant_p (2) && ((__builtin_constant_p
(s) && strlen (s) < ((size_t) (2))) || (__builtin_constant_p
("<?") && strlen ("<?") < ((size_t) (2)))) ?
__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(s) && __builtin_constant_p ("<?") && (__s1_len
= __builtin_strlen (s), __s2_len = __builtin_strlen ("<?"
), (!((size_t)(const void *)((s) + 1) - (size_t)(const void *
)(s) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)(("<?") + 1) - (size_t)(const void *)("<?") == 1) ||
__s2_len >= 4)) ? __builtin_strcmp (s, "<?") : (__builtin_constant_p
(s) && ((size_t)(const void *)((s) + 1) - (size_t)(const
void *)(s) == 1) && (__s1_len = __builtin_strlen (s)
, __s1_len < 4) ? (__builtin_constant_p ("<?") &&
((size_t)(const void *)(("<?") + 1) - (size_t)(const void
*)("<?") == 1) ? __builtin_strcmp (s, "<?") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("<?"); int __result = (((const unsigned char *) (
const char *) (s))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (s))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
s))[2] - __s2[2]); if (__s1_len > 2 && __result ==
0) __result = (((const unsigned char *) (const char *) (s))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("<?"
) && ((size_t)(const void *)(("<?") + 1) - (size_t
)(const void *)("<?") == 1) && (__s2_len = __builtin_strlen
("<?"), __s2_len < 4) ? (__builtin_constant_p (s) &&
((size_t)(const void *)((s) + 1) - (size_t)(const void *)(s)
== 1) ? __builtin_strcmp (s, "<?") : (- (__extension__ ({
const unsigned char *__s2 = (const unsigned char *) (const char
*) (s); int __result = (((const unsigned char *) (const char
*) ("<?"))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
"<?"))[1] - __s2[1]); if (__s2_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
"<?"))[2] - __s2[2]); if (__s2_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) ("<?"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (s, "<?"
)))); }) : strncmp (s, "<?", 2)))
) { /* processing instructions */
915 if ((s = strstr(c = s + 2, "?>")))
916 switch_xml_proc_inst(root, c, s++ - c);
917 } else if (*s == '<')
918 s = strchr(s, '>')(__extension__ (__builtin_constant_p ('>') && !__builtin_constant_p
(s) && ('>') == '\0' ? (char *) __rawmemchr (s, '>'
) : __builtin_strchr (s, '>')))
; /* skip other declarations */
919 else if (*(s++) == '%' && !root->standalone)
920 break;
921 }
922
923 free(pe);
924 return !*root->err;
925}
926
927/* Converts a UTF-16 string to UTF-8. Returns a new string that must be freed
928 or NULL if no conversion was needed. */
929static char *switch_xml_str2utf8(char **s, switch_size_t *len)
930{
931 char *u;
932 switch_size_t l = 0, sl, max = *len;
933 long c, d;
934 int b, be = (**s == '\xFE') ? 1 : (**s == '\xFF') ? 0 : -1;
935
936 if (be == -1)
937 return NULL((void*)0); /* not UTF-16 */
938
939 u = (char *) malloc(max);
940 for (sl = 2; sl < *len - 1; sl += 2) {
941 c = (be) ? (((*s)[sl] & 0xFF) << 8) | ((*s)[sl + 1] & 0xFF) /* UTF-16BE */
942 : (((*s)[sl + 1] & 0xFF) << 8) | ((*s)[sl] & 0xFF); /* UTF-16LE */
943 if (c >= 0xD800 && c <= 0xDFFF && (sl += 2) < *len - 1) { /* high-half */
944 d = (be) ? (((*s)[sl] & 0xFF) << 8) | ((*s)[sl + 1] & 0xFF)
945 : (((*s)[sl + 1] & 0xFF) << 8) | ((*s)[sl] & 0xFF);
946 c = (((c & 0x3FF) << 10) | (d & 0x3FF)) + 0x10000;
947 }
948
949 while (l + 6 > max) {
950 char *tmp;
951 tmp = (char *) realloc(u, max += SWITCH_XML_BUFSIZE1024);
952 if (!tmp)
953 return NULL((void*)0);
954 u = tmp;
955 }
956 if (c < 0x80)
957 u[l++] = (char) c; /* US-ASCII subset */
958 else { /* multi-byte UTF-8 sequence */
959 for (b = 0, d = c; d; d /= 2)
960 b++; /* bits in c */
961 b = (b - 2) / 5; /* bytes in payload */
962 u[l++] = (char) ((0xFF << (7 - b)) | (c >> (6 * b))); /* head */
963 while (b)
964 u[l++] = (char) (0x80 | ((c >> (6 * --b)) & 0x3F)); /* payload */
965 }
966 }
967 return *s = (char *) realloc(u, *len = l);
968}
969
970/* frees a tag attribute list */
971static void switch_xml_free_attr(char **attr)
972{
973 int i = 0;
974 char *m;
975
976 if (!attr || attr == SWITCH_XML_NIL)
977 return; /* nothing to free */
978 while (attr[i])
979 i += 2; /* find end of attribute list */
980 m = attr[i + 1]; /* list of which names and values are malloced */
981 for (i = 0; m[i]; i++) {
982 if (m[i] & SWITCH_XML_NAMEM)
983 free(attr[i * 2]);
984 if (m[i] & SWITCH_XML_TXTM)
985 free(attr[(i * 2) + 1]);
986 }
987 free(m);
988 free(attr);
989}
990
991SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_parse_str_dynamic(char *s, switch_bool_t dup)
992{
993 switch_xml_root_t root;
994 char *data;
995
996 switch_assert(s)((s) ? (void) (0) : __assert_fail ("s", "src/switch_xml.c", 996
, __PRETTY_FUNCTION__))
;
997 data = dup ? strdup(s)(__extension__ (__builtin_constant_p (s) && ((size_t)
(const void *)((s) + 1) - (size_t)(const void *)(s) == 1) ? (
((const char *) (s))[0] == '\0' ? (char *) calloc ((size_t) 1
, (size_t) 1) : ({ size_t __len = strlen (s) + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, s, __len); __retval; })) : __strdup
(s)))
: s;
998
999 if ((root = (switch_xml_root_t) switch_xml_parse_str(data, strlen(data)))) {
1000 root->dynamic = 1; /* Make sure we free the memory is switch_xml_free() */
1001 return &root->xml;
1002 } else {
1003 if (dup) {
1004 free(data);
1005 }
1006 return NULL((void*)0);
1007 }
1008}
1009
1010/* parse the given xml string and return a switch_xml structure */
1011SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_parse_str(char *s, switch_size_t len)
1012{
1013 switch_xml_root_t root = (switch_xml_root_t) switch_xml_new(NULL((void*)0));
1014 char q, e, *d, **attr, **a = NULL((void*)0); /* initialize a to avoid compile warning */
1015 int l, i, j;
1016
1017 root->m = s;
1018 if (!len)
1019 return switch_xml_err(root, s, "root tag missing");
1020 root->u = switch_xml_str2utf8(&s, &len); /* convert utf-16 to utf-8 */
1021 root->e = (root->s = s) + len; /* record start and end of work area */
1022
1023 e = s[len - 1]; /* save end char */
1024 s[len - 1] = '\0'; /* turn end char into null terminator */
1025
1026 while (*s && *s != '<')
1027 s++; /* find first tag */
1028 if (!*s)
1029 return switch_xml_err(root, s, "root tag missing");
1030
1031 for (;;) {
1032 attr = (char **) SWITCH_XML_NIL;
1033 d = ++s;
1034
1035 if (isalpha((int) (*s))((*__ctype_b_loc ())[(int) (((int) (*s)))] & (unsigned short
int) _ISalpha)
|| *s == '_' || *s == ':' || (int8_t) * s < '\0') { /* new tag */
1036 if (!root->cur)
1037 return switch_xml_err(root, d, "markup outside of root element");
1038
1039 s += strcspn(s, SWITCH_XML_WS "/>")__extension__ ({ char __r0, __r1, __r2; (__builtin_constant_p
("\t\r\n " "/>") && ((size_t)(const void *)(("\t\r\n "
"/>") + 1) - (size_t)(const void *)("\t\r\n " "/>") ==
1) ? ((__builtin_constant_p (s) && ((size_t)(const void
*)((s) + 1) - (size_t)(const void *)(s) == 1)) ? __builtin_strcspn
(s, "\t\r\n " "/>") : ((__r0 = ((const char *) ("\t\r\n "
"/>"))[0], __r0 == '\0') ? strlen (s) : ((__r1 = ((const char
*) ("\t\r\n " "/>"))[1], __r1 == '\0') ? __strcspn_c1 (s,
__r0) : ((__r2 = ((const char *) ("\t\r\n " "/>"))[2], __r2
== '\0') ? __strcspn_c2 (s, __r0, __r1) : (((const char *) (
"\t\r\n " "/>"))[3] == '\0' ? __strcspn_c3 (s, __r0, __r1,
__r2) : __builtin_strcspn (s, "\t\r\n " "/>")))))) : __builtin_strcspn
(s, "\t\r\n " "/>")); })
;
1040 while (isspace((int) (*s))((*__ctype_b_loc ())[(int) (((int) (*s)))] & (unsigned short
int) _ISspace)
)
1041 *(s++) = '\0'; /* null terminate tag name */
1042
1043 if (*s && *s != '/' && *s != '>') /* find tag in default attr list */
1044 for (i = 0; (a = root->attr[i]) && strcmp(a[0], d)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(a[0]) && __builtin_constant_p (d) && (__s1_len
= __builtin_strlen (a[0]), __s2_len = __builtin_strlen (d), (
!((size_t)(const void *)((a[0]) + 1) - (size_t)(const void *)
(a[0]) == 1) || __s1_len >= 4) && (!((size_t)(const
void *)((d) + 1) - (size_t)(const void *)(d) == 1) || __s2_len
>= 4)) ? __builtin_strcmp (a[0], d) : (__builtin_constant_p
(a[0]) && ((size_t)(const void *)((a[0]) + 1) - (size_t
)(const void *)(a[0]) == 1) && (__s1_len = __builtin_strlen
(a[0]), __s1_len < 4) ? (__builtin_constant_p (d) &&
((size_t)(const void *)((d) + 1) - (size_t)(const void *)(d)
== 1) ? __builtin_strcmp (a[0], d) : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(d); int __result = (((const unsigned char *) (const char *)
(a[0]))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
a[0]))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
a[0]))[2] - __s2[2]); if (__s1_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (a
[0]))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(d) && ((size_t)(const void *)((d) + 1) - (size_t)(const
void *)(d) == 1) && (__s2_len = __builtin_strlen (d)
, __s2_len < 4) ? (__builtin_constant_p (a[0]) && (
(size_t)(const void *)((a[0]) + 1) - (size_t)(const void *)(a
[0]) == 1) ? __builtin_strcmp (a[0], d) : (- (__extension__ (
{ const unsigned char *__s2 = (const unsigned char *) (const char
*) (a[0]); int __result = (((const unsigned char *) (const char
*) (d))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
d))[1] - __s2[1]); if (__s2_len > 1 && __result ==
0) { __result = (((const unsigned char *) (const char *) (d)
)[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (d))[3]
- __s2[3]); } } __result; })))) : __builtin_strcmp (a[0], d)
))); })
; i++);
1045
1046 for (l = 0; *s && *s != '/' && *s != '>'; l += 2) { /* new attrib */
1047 attr = (l) ? (char **) realloc(attr, (l + 4) * sizeof(char *))
1048 : (char **) malloc(4 * sizeof(char *)); /* allocate space */
1049 attr[l + 3] = (l) ? (char *) realloc(attr[l + 1], (l / 2) + 2)
1050 : (char *) malloc(2); /* mem for list of maloced vals */
1051 strcpy(attr[l + 3] + (l / 2), " "); /* value is not malloced */
1052 attr[l + 2] = NULL((void*)0); /* null terminate list */
1053 attr[l + 1] = (char *) ""; /* temporary attribute value */
1054 attr[l] = s; /* set attribute name */
1055
1056 s += strcspn(s, SWITCH_XML_WS "=/>")__extension__ ({ char __r0, __r1, __r2; (__builtin_constant_p
("\t\r\n " "=/>") && ((size_t)(const void *)(("\t\r\n "
"=/>") + 1) - (size_t)(const void *)("\t\r\n " "=/>") ==
1) ? ((__builtin_constant_p (s) && ((size_t)(const void
*)((s) + 1) - (size_t)(const void *)(s) == 1)) ? __builtin_strcspn
(s, "\t\r\n " "=/>") : ((__r0 = ((const char *) ("\t\r\n "
"=/>"))[0], __r0 == '\0') ? strlen (s) : ((__r1 = ((const
char *) ("\t\r\n " "=/>"))[1], __r1 == '\0') ? __strcspn_c1
(s, __r0) : ((__r2 = ((const char *) ("\t\r\n " "=/>"))[2
], __r2 == '\0') ? __strcspn_c2 (s, __r0, __r1) : (((const char
*) ("\t\r\n " "=/>"))[3] == '\0' ? __strcspn_c3 (s, __r0,
__r1, __r2) : __builtin_strcspn (s, "\t\r\n " "=/>"))))))
: __builtin_strcspn (s, "\t\r\n " "=/>")); })
;
1057 if (*s == '=' || isspace((int) (*s))((*__ctype_b_loc ())[(int) (((int) (*s)))] & (unsigned short
int) _ISspace)
) {
1058 *(s++) = '\0'; /* null terminate tag attribute name */
1059 q = *(s += strspn(s, SWITCH_XML_WS "=")__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("\t\r\n " "=") && ((size_t)(const void *)(("\t\r\n "
"=") + 1) - (size_t)(const void *)("\t\r\n " "=") == 1) ? ((
__builtin_constant_p (s) && ((size_t)(const void *)((
s) + 1) - (size_t)(const void *)(s) == 1)) ? __builtin_strspn
(s, "\t\r\n " "=") : ((__a0 = ((const char *) ("\t\r\n " "="
))[0], __a0 == '\0') ? ((void) (s), (size_t) 0) : ((__a1 = ((
const char *) ("\t\r\n " "="))[1], __a1 == '\0') ? __strspn_c1
(s, __a0) : ((__a2 = ((const char *) ("\t\r\n " "="))[2], __a2
== '\0') ? __strspn_c2 (s, __a0, __a1) : (((const char *) ("\t\r\n "
"="))[3] == '\0' ? __strspn_c3 (s, __a0, __a1, __a2) : __builtin_strspn
(s, "\t\r\n " "=")))))) : __builtin_strspn (s, "\t\r\n " "="
)); })
);
1060 if (q == '"' || q == '\'') { /* attribute value */
1061 attr[l + 1] = ++s;
1062 while (*s && *s != q)
1063 s++;
1064 if (*s)
1065 *(s++) = '\0'; /* null terminate attribute val */
1066 else {
1067 switch_xml_free_attr(attr);
1068 return switch_xml_err(root, d, "missing %c", q);
1069 }
1070
1071 for (j = 1; a && a[j] && strcmp(a[j], attr[l])__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(a[j]) && __builtin_constant_p (attr[l]) && (
__s1_len = __builtin_strlen (a[j]), __s2_len = __builtin_strlen
(attr[l]), (!((size_t)(const void *)((a[j]) + 1) - (size_t)(
const void *)(a[j]) == 1) || __s1_len >= 4) && (!(
(size_t)(const void *)((attr[l]) + 1) - (size_t)(const void *
)(attr[l]) == 1) || __s2_len >= 4)) ? __builtin_strcmp (a[
j], attr[l]) : (__builtin_constant_p (a[j]) && ((size_t
)(const void *)((a[j]) + 1) - (size_t)(const void *)(a[j]) ==
1) && (__s1_len = __builtin_strlen (a[j]), __s1_len <
4) ? (__builtin_constant_p (attr[l]) && ((size_t)(const
void *)((attr[l]) + 1) - (size_t)(const void *)(attr[l]) == 1
) ? __builtin_strcmp (a[j], attr[l]) : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(attr[l]); int __result = (((const unsigned char *) (const char
*) (a[j]))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
a[j]))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
a[j]))[2] - __s2[2]); if (__s1_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (a
[j]))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(attr[l]) && ((size_t)(const void *)((attr[l]) + 1) -
(size_t)(const void *)(attr[l]) == 1) && (__s2_len =
__builtin_strlen (attr[l]), __s2_len < 4) ? (__builtin_constant_p
(a[j]) && ((size_t)(const void *)((a[j]) + 1) - (size_t
)(const void *)(a[j]) == 1) ? __builtin_strcmp (a[j], attr[l]
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (a[j]); int __result = (((const unsigned
char *) (const char *) (attr[l]))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (attr[l]))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (attr[l]))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (attr[l]))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (a[j], attr[l])))); })
; j += 3);
1072 attr[l + 1] = switch_xml_decode(attr[l + 1], root->ent, (a && a[j]) ? *a[j + 2] : ' ');
1073 if (attr[l + 1] < d || attr[l + 1] > s)
1074 attr[l + 3][l / 2] = SWITCH_XML_TXTM; /* value malloced */
1075 }
1076 }
1077 while (isspace((int) (*s))((*__ctype_b_loc ())[(int) (((int) (*s)))] & (unsigned short
int) _ISspace)
)
1078 s++;
1079 }
1080
1081 if (*s == '/') { /* self closing tag */
1082 *(s++) = '\0';
1083 if ((*s && *s != '>') || (!*s && e != '>')) {
1084 if (l)
1085 switch_xml_free_attr(attr);
1086 return switch_xml_err(root, d, "missing >");
1087 }
1088 switch_xml_open_tag(root, d, attr);
1089 switch_xml_close_tag(root, d, s);
1090 } else if ((q = *s) == '>' || (!*s && e == '>')) { /* open tag */
1091 *s = '\0'; /* temporarily null terminate tag name */
1092 switch_xml_open_tag(root, d, attr);
1093 *s = q;
1094 } else {
1095 if (l)
1096 switch_xml_free_attr(attr);
1097 return switch_xml_err(root, d, "missing >");
1098 }
1099 } else if (*s == '/') { /* close tag */
1100 s += strcspn(d = s + 1, SWITCH_XML_WS ">")__extension__ ({ char __r0, __r1, __r2; (__builtin_constant_p
("\t\r\n " ">") && ((size_t)(const void *)(("\t\r\n "
">") + 1) - (size_t)(const void *)("\t\r\n " ">") == 1
) ? ((__builtin_constant_p (d = s + 1) && ((size_t)(const
void *)((d = s + 1) + 1) - (size_t)(const void *)(d = s + 1)
== 1)) ? __builtin_strcspn (d = s + 1, "\t\r\n " ">") : (
(__r0 = ((const char *) ("\t\r\n " ">"))[0], __r0 == '\0')
? strlen (d = s + 1) : ((__r1 = ((const char *) ("\t\r\n " ">"
))[1], __r1 == '\0') ? __strcspn_c1 (d = s + 1, __r0) : ((__r2
= ((const char *) ("\t\r\n " ">"))[2], __r2 == '\0') ? __strcspn_c2
(d = s + 1, __r0, __r1) : (((const char *) ("\t\r\n " ">"
))[3] == '\0' ? __strcspn_c3 (d = s + 1, __r0, __r1, __r2) : __builtin_strcspn
(d = s + 1, "\t\r\n " ">")))))) : __builtin_strcspn (d = s
+ 1, "\t\r\n " ">")); })
+ 1;
1101 if (!(q = *s) && e != '>')
1102 return switch_xml_err(root, d, "missing >");
1103 *s = '\0'; /* temporarily null terminate tag name */
1104 if (switch_xml_close_tag(root, d, s))
1105 return &root->xml;
1106 if (isspace((int) (*s = q))((*__ctype_b_loc ())[(int) (((int) (*s = q)))] & (unsigned
short int) _ISspace)
)
1107 s += strspn(s, SWITCH_XML_WS)__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("\t\r\n ") && ((size_t)(const void *)(("\t\r\n ") +
1) - (size_t)(const void *)("\t\r\n ") == 1) ? ((__builtin_constant_p
(s) && ((size_t)(const void *)((s) + 1) - (size_t)(const
void *)(s) == 1)) ? __builtin_strspn (s, "\t\r\n ") : ((__a0
= ((const char *) ("\t\r\n "))[0], __a0 == '\0') ? ((void) (
s), (size_t) 0) : ((__a1 = ((const char *) ("\t\r\n "))[1], __a1
== '\0') ? __strspn_c1 (s, __a0) : ((__a2 = ((const char *) (
"\t\r\n "))[2], __a2 == '\0') ? __strspn_c2 (s, __a0, __a1) :
(((const char *) ("\t\r\n "))[3] == '\0' ? __strspn_c3 (s, __a0
, __a1, __a2) : __builtin_strspn (s, "\t\r\n ")))))) : __builtin_strspn
(s, "\t\r\n ")); })
;
1108 } else if (!strncmp(s, "!--", 3)(__extension__ (__builtin_constant_p (3) && ((__builtin_constant_p
(s) && strlen (s) < ((size_t) (3))) || (__builtin_constant_p
("!--") && strlen ("!--") < ((size_t) (3)))) ? __extension__
({ size_t __s1_len, __s2_len; (__builtin_constant_p (s) &&
__builtin_constant_p ("!--") && (__s1_len = __builtin_strlen
(s), __s2_len = __builtin_strlen ("!--"), (!((size_t)(const void
*)((s) + 1) - (size_t)(const void *)(s) == 1) || __s1_len >=
4) && (!((size_t)(const void *)(("!--") + 1) - (size_t
)(const void *)("!--") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(s, "!--") : (__builtin_constant_p (s) && ((size_t)(
const void *)((s) + 1) - (size_t)(const void *)(s) == 1) &&
(__s1_len = __builtin_strlen (s), __s1_len < 4) ? (__builtin_constant_p
("!--") && ((size_t)(const void *)(("!--") + 1) - (size_t
)(const void *)("!--") == 1) ? __builtin_strcmp (s, "!--") : (
__extension__ ({ const unsigned char *__s2 = (const unsigned char
*) (const char *) ("!--"); int __result = (((const unsigned char
*) (const char *) (s))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (s))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
s))[2] - __s2[2]); if (__s1_len > 2 && __result ==
0) __result = (((const unsigned char *) (const char *) (s))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("!--"
) && ((size_t)(const void *)(("!--") + 1) - (size_t)(
const void *)("!--") == 1) && (__s2_len = __builtin_strlen
("!--"), __s2_len < 4) ? (__builtin_constant_p (s) &&
((size_t)(const void *)((s) + 1) - (size_t)(const void *)(s)
== 1) ? __builtin_strcmp (s, "!--") : (- (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(s); int __result = (((const unsigned char *) (const char *)
("!--"))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
"!--"))[1] - __s2[1]); if (__s2_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
"!--"))[2] - __s2[2]); if (__s2_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) ("!--"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (s, "!--"
)))); }) : strncmp (s, "!--", 3)))
) { /* xml comment */
1109 if (!(s = strstr(s + 3, "--")) || (*(s += 2) != '>' && *s) || (!*s && e != '>'))
1110 return switch_xml_err(root, d, "unclosed <!--");
1111 } else if (!strncmp(s, "![CDATA[", 8)(__extension__ (__builtin_constant_p (8) && ((__builtin_constant_p
(s) && strlen (s) < ((size_t) (8))) || (__builtin_constant_p
("![CDATA[") && strlen ("![CDATA[") < ((size_t) (
8)))) ? __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(s) && __builtin_constant_p ("![CDATA[") && (
__s1_len = __builtin_strlen (s), __s2_len = __builtin_strlen (
"![CDATA["), (!((size_t)(const void *)((s) + 1) - (size_t)(const
void *)(s) == 1) || __s1_len >= 4) && (!((size_t)
(const void *)(("![CDATA[") + 1) - (size_t)(const void *)("![CDATA["
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (s, "![CDATA["
) : (__builtin_constant_p (s) && ((size_t)(const void
*)((s) + 1) - (size_t)(const void *)(s) == 1) && (__s1_len
= __builtin_strlen (s), __s1_len < 4) ? (__builtin_constant_p
("![CDATA[") && ((size_t)(const void *)(("![CDATA[")
+ 1) - (size_t)(const void *)("![CDATA[") == 1) ? __builtin_strcmp
(s, "![CDATA[") : (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) ("![CDATA["); int __result
= (((const unsigned char *) (const char *) (s))[0] - __s2[0]
); if (__s1_len > 0 && __result == 0) { __result =
(((const unsigned char *) (const char *) (s))[1] - __s2[1]);
if (__s1_len > 1 && __result == 0) { __result = (
((const unsigned char *) (const char *) (s))[2] - __s2[2]); if
(__s1_len > 2 && __result == 0) __result = (((const
unsigned char *) (const char *) (s))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p ("![CDATA[") && ((size_t
)(const void *)(("![CDATA[") + 1) - (size_t)(const void *)("![CDATA["
) == 1) && (__s2_len = __builtin_strlen ("![CDATA["),
__s2_len < 4) ? (__builtin_constant_p (s) && ((size_t
)(const void *)((s) + 1) - (size_t)(const void *)(s) == 1) ? __builtin_strcmp
(s, "![CDATA[") : (- (__extension__ ({ const unsigned char *
__s2 = (const unsigned char *) (const char *) (s); int __result
= (((const unsigned char *) (const char *) ("![CDATA["))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("![CDATA["))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("![CDATA["))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("![CDATA["))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (s, "![CDATA["
)))); }) : strncmp (s, "![CDATA[", 8)))
) { /* cdata */
1112 if ((s = strstr(s, "]]>")))
1113 switch_xml_char_content(root, d + 8, (s += 2) - d - 10, 'c');
1114 else
1115 return switch_xml_err(root, d, "unclosed <![CDATA[");
1116 } else if (!strncmp(s, "!DOCTYPE", 8)(__extension__ (__builtin_constant_p (8) && ((__builtin_constant_p
(s) && strlen (s) < ((size_t) (8))) || (__builtin_constant_p
("!DOCTYPE") && strlen ("!DOCTYPE") < ((size_t) (
8)))) ? __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(s) && __builtin_constant_p ("!DOCTYPE") && (
__s1_len = __builtin_strlen (s), __s2_len = __builtin_strlen (
"!DOCTYPE"), (!((size_t)(const void *)((s) + 1) - (size_t)(const
void *)(s) == 1) || __s1_len >= 4) && (!((size_t)
(const void *)(("!DOCTYPE") + 1) - (size_t)(const void *)("!DOCTYPE"
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (s, "!DOCTYPE"
) : (__builtin_constant_p (s) && ((size_t)(const void
*)((s) + 1) - (size_t)(const void *)(s) == 1) && (__s1_len
= __builtin_strlen (s), __s1_len < 4) ? (__builtin_constant_p
("!DOCTYPE") && ((size_t)(const void *)(("!DOCTYPE")
+ 1) - (size_t)(const void *)("!DOCTYPE") == 1) ? __builtin_strcmp
(s, "!DOCTYPE") : (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) ("!DOCTYPE"); int __result
= (((const unsigned char *) (const char *) (s))[0] - __s2[0]
); if (__s1_len > 0 && __result == 0) { __result =
(((const unsigned char *) (const char *) (s))[1] - __s2[1]);
if (__s1_len > 1 && __result == 0) { __result = (
((const unsigned char *) (const char *) (s))[2] - __s2[2]); if
(__s1_len > 2 && __result == 0) __result = (((const
unsigned char *) (const char *) (s))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p ("!DOCTYPE") && ((size_t
)(const void *)(("!DOCTYPE") + 1) - (size_t)(const void *)("!DOCTYPE"
) == 1) && (__s2_len = __builtin_strlen ("!DOCTYPE"),
__s2_len < 4) ? (__builtin_constant_p (s) && ((size_t
)(const void *)((s) + 1) - (size_t)(const void *)(s) == 1) ? __builtin_strcmp
(s, "!DOCTYPE") : (- (__extension__ ({ const unsigned char *
__s2 = (const unsigned char *) (const char *) (s); int __result
= (((const unsigned char *) (const char *) ("!DOCTYPE"))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("!DOCTYPE"))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("!DOCTYPE"))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("!DOCTYPE"))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (s, "!DOCTYPE"
)))); }) : strncmp (s, "!DOCTYPE", 8)))
) { /* dtd */
1117 for (l = 0; *s && ((!l && *s != '>') || (l && (*s != ']' || *(s + strspn(s + 1, SWITCH_XML_WS)__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
("\t\r\n ") && ((size_t)(const void *)(("\t\r\n ") +
1) - (size_t)(const void *)("\t\r\n ") == 1) ? ((__builtin_constant_p
(s + 1) && ((size_t)(const void *)((s + 1) + 1) - (size_t
)(const void *)(s + 1) == 1)) ? __builtin_strspn (s + 1, "\t\r\n "
) : ((__a0 = ((const char *) ("\t\r\n "))[0], __a0 == '\0') ?
((void) (s + 1), (size_t) 0) : ((__a1 = ((const char *) ("\t\r\n "
))[1], __a1 == '\0') ? __strspn_c1 (s + 1, __a0) : ((__a2 = (
(const char *) ("\t\r\n "))[2], __a2 == '\0') ? __strspn_c2 (
s + 1, __a0, __a1) : (((const char *) ("\t\r\n "))[3] == '\0'
? __strspn_c3 (s + 1, __a0, __a1, __a2) : __builtin_strspn (
s + 1, "\t\r\n ")))))) : __builtin_strspn (s + 1, "\t\r\n "))
; })
+ 1) != '>'))); l = (*s == '[') ? 1 : l)
1118 s += strcspn(s + 1, "[]>")__extension__ ({ char __r0, __r1, __r2; (__builtin_constant_p
("[]>") && ((size_t)(const void *)(("[]>") + 1
) - (size_t)(const void *)("[]>") == 1) ? ((__builtin_constant_p
(s + 1) && ((size_t)(const void *)((s + 1) + 1) - (size_t
)(const void *)(s + 1) == 1)) ? __builtin_strcspn (s + 1, "[]>"
) : ((__r0 = ((const char *) ("[]>"))[0], __r0 == '\0') ? strlen
(s + 1) : ((__r1 = ((const char *) ("[]>"))[1], __r1 == '\0'
) ? __strcspn_c1 (s + 1, __r0) : ((__r2 = ((const char *) ("[]>"
))[2], __r2 == '\0') ? __strcspn_c2 (s + 1, __r0, __r1) : (((
const char *) ("[]>"))[3] == '\0' ? __strcspn_c3 (s + 1, __r0
, __r1, __r2) : __builtin_strcspn (s + 1, "[]>")))))) : __builtin_strcspn
(s + 1, "[]>")); })
+ 1;
1119 if (!*s && e != '>')
1120 return switch_xml_err(root, d, "unclosed <!DOCTYPE");
1121 d = (l) ? strchr(d, '[')(__extension__ (__builtin_constant_p ('[') && !__builtin_constant_p
(d) && ('[') == '\0' ? (char *) __rawmemchr (d, '[')
: __builtin_strchr (d, '[')))
+ 1 : d;
1122 if (l && !switch_xml_internal_dtd(root, d, s++ - d))
1123 return &root->xml;
1124 } else if (*s == '?') { /* <?...?> processing instructions */
1125 do {
1126 s = strchr(s, '?')(__extension__ (__builtin_constant_p ('?') && !__builtin_constant_p
(s) && ('?') == '\0' ? (char *) __rawmemchr (s, '?')
: __builtin_strchr (s, '?')))
;
1127 } while (s && *(++s) && *s != '>');
1128 if (!s || (!*s && e != '>'))
1129 return switch_xml_err(root, d, "unclosed <?");
1130 else
1131 switch_xml_proc_inst(root, d + 1, s - d - 2);
1132 } else
1133 return switch_xml_err(root, d, "unexpected <");
1134
1135 if (!s || !*s)
1136 break;
1137 *s = '\0';
1138 d = ++s;
1139 if (*s && *s != '<') { /* tag character content */
1140 while (*s && *s != '<')
1141 s++;
1142 if (*s)
1143 switch_xml_char_content(root, d, s - d, '&');
1144 else
1145 break;
1146 } else if (!*s)
1147 break;
1148 }
1149
1150 if (!root->cur)
1151 return &root->xml;
1152 else if (!root->cur->name)
1153 return switch_xml_err(root, d, "root tag missing");
1154 else
1155 return switch_xml_err(root, d, "unclosed tag <%s>", root->cur->name);
1156}
1157
1158/* Wrapper for switch_xml_parse_str() that accepts a file stream. Reads the entire
1159 stream into memory and then parses it. For xml files, use switch_xml_parse_file()
1160 or switch_xml_parse_fd() */
1161SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_parse_fp(FILE * fp)
1162{
1163 switch_xml_root_t root;
1164 switch_size_t l, len = 0;
1165 char *s;
1166
1167 if (!(s = (char *) malloc(SWITCH_XML_BUFSIZE1024)))
1168 return NULL((void*)0);
1169 do {
1170 len += (l = fread((s + len), 1, SWITCH_XML_BUFSIZE1024, fp));
1171 if (l == SWITCH_XML_BUFSIZE1024) {
1172 char *tmp = s;
1173 s = (char *) realloc(s, len + SWITCH_XML_BUFSIZE1024);
1174 if (!s) {
1175 free(tmp);
1176 return NULL((void*)0);
1177 }
1178 }
1179 } while (s && l == SWITCH_XML_BUFSIZE1024);
1180
1181 if (!s)
1182 return NULL((void*)0);
1183 root = (switch_xml_root_t) switch_xml_parse_str(s, len);
1184 root->dynamic = 1; /* so we know to free s in switch_xml_free() */
1185 return &root->xml;
1186}
1187
1188/* A wrapper for switch_xml_parse_str() that accepts a file descriptor. First
1189 attempts to mem map the file. Failing that, reads the file into memory.
1190 Returns NULL on failure. */
1191SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_parse_fd(int fd)
1192{
1193 switch_xml_root_t root;
1194 struct stat st;
1195 switch_ssize_t l;
1196 void *m;
1197
1198 if (fd < 0)
1199 return NULL((void*)0);
1200 fstat(fd, &st);
1201
1202 if (!st.st_size) {
1203 return NULL((void*)0);
1204 }
1205
1206 m = malloc(st.st_size);
1207 if (!m)
1208 return NULL((void*)0);
1209 if (!(0<(l = read(fd, m, st.st_size)))
1210 || !(root = (switch_xml_root_t) switch_xml_parse_str((char *) m, l))) {
1211 free(m);
1212 return NULL((void*)0);
1213 }
1214 root->dynamic = 1; /* so we know to free s in switch_xml_free() */
1215
1216 return &root->xml;
1217}
1218
1219static char *expand_vars(char *buf, char *ebuf, switch_size_t elen, switch_size_t *newlen, const char **err)
1220{
1221 char *var, *val;
1222 char *rp = buf;
1223 char *wp = ebuf;
1224 char *ep = ebuf + elen - 1;
1225
1226 if (!(var = strstr(rp, "$${"))) {
1227 *newlen = strlen(buf);
1228 return buf;
1229 }
1230
1231 while (*rp && wp < ep) {
1232
1233 if (*rp == '$' && *(rp + 1) == '$' && *(rp + 2) == '{') {
1234 char *e = switch_find_end_paren(rp + 2, '{', '}');
1235
1236 if (e) {
1237 rp += 3;
1238 var = rp;
1239 *e++ = '\0';
1240 rp = e;
1241 if ((val = switch_core_get_variable_dup(var))) {
1242 char *p;
1243 for (p = val; p && *p && wp <= ep; p++) {
1244 *wp++ = *p;
1245 }
1246 free(val);
1247 }
1248 continue;
1249 } else if (err) {
1250 *err = "unterminated ${var}";
1251 }
1252 }
1253
1254 *wp++ = *rp++;
1255 }
1256 *wp++ = '\0';
1257 *newlen = strlen(ebuf);
1258
1259 return ebuf;
1260}
1261
1262static FILE *preprocess_exec(const char *cwd, const char *command, FILE *write_fd, int rlevel)
1263{
1264#ifdef WIN32
1265 FILE *fp = NULL((void*)0);
1266 char buffer[1024];
1267
1268 if (!command || !strlen(command)) goto end;
1269
1270 if ((fp = _popen(command, "r"))) {
1271 while (fgets(buffer, sizeof(buffer), fp) != NULL((void*)0)) {
1272 if (fwrite(buffer, 1, strlen(buffer), write_fd) <= 0) {
1273 break;
1274 }
1275 }
1276
1277 if(feof(fp)) {
1278 _pclose(fp);
1279 } else {
1280 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 1280, ((void*)0)
, SWITCH_LOG_ERROR, "Exec failed to read the pipe of [%s] to the end\n", command);
1281 }
1282 } else {
1283 switch_snprintf(buffer, sizeof(buffer), "<!-- exec can not execute [%s] -->", command);
1284 fwrite( buffer, 1, strlen(buffer), write_fd);
1285 }
1286#else
1287 int fds[2], pid = 0;
1288
1289 if (pipe(fds)) {
1290 goto end;
1291 } else { /* good to go */
1292 pid = switch_fork();
1293
1294 if (pid < 0) { /* ok maybe not */
1295 close(fds[0]);
1296 close(fds[1]);
1297 goto end;
1298 } else if (pid) { /* parent */
1299 char buf[1024] = "";
1300 int bytes;
1301 close(fds[1]);
1302 while ((bytes = read(fds[0], buf, sizeof(buf))) > 0) {
1303 if (fwrite(buf, 1, bytes, write_fd) <= 0) {
1304 break;
1305 }
1306 }
1307 close(fds[0]);
1308 waitpid(pid, NULL((void*)0), 0);
1309 } else { /* child */
1310 switch_close_extra_files(fds, 2);
1311 close(fds[0]);
1312 dup2(fds[1], STDOUT_FILENO1);
1313 switch_system(command, SWITCH_TRUE);
1314 close(fds[1]);
1315 exit(0);
1316 }
1317 }
1318#endif
1319 end:
1320
1321 return write_fd;
1322
1323}
1324
1325static FILE *preprocess_glob(const char *cwd, const char *pattern, FILE *write_fd, int rlevel)
1326{
1327 char *full_path = NULL((void*)0);
1328 char *dir_path = NULL((void*)0), *e = NULL((void*)0);
1329 glob_t glob_data;
1330 size_t n;
1331
1332 if (!switch_is_file_path(pattern)) {
1333 full_path = switch_mprintf("%s%s%s", cwd, SWITCH_PATH_SEPARATOR"/", pattern);
1334 pattern = full_path;
1335 }
1336
1337 if (glob(pattern, GLOB_NOCHECK(1 << 4), NULL((void*)0), &glob_data) != 0) {
1338 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 1338, ((void*)0)
, SWITCH_LOG_ERROR, "Error including %s\n", pattern);
1339 goto end;
1340 }
1341
1342 for (n = 0; n < glob_data.gl_pathc; ++n) {
1343 dir_path = strdup(glob_data.gl_pathv[n])(__extension__ (__builtin_constant_p (glob_data.gl_pathv[n]) &&
((size_t)(const void *)((glob_data.gl_pathv[n]) + 1) - (size_t
)(const void *)(glob_data.gl_pathv[n]) == 1) ? (((const char *
) (glob_data.gl_pathv[n]))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (glob_data.gl_pathv
[n]) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, glob_data
.gl_pathv[n], __len); __retval; })) : __strdup (glob_data.gl_pathv
[n])))
;
1344 switch_assert(dir_path)((dir_path) ? (void) (0) : __assert_fail ("dir_path", "src/switch_xml.c"
, 1344, __PRETTY_FUNCTION__))
;
1345 if ((e = strrchr(dir_path, *SWITCH_PATH_SEPARATOR"/"))) {
1346 *e = '\0';
1347 }
1348 if (preprocess(dir_path, glob_data.gl_pathv[n], write_fd, rlevel) < 0) {
1349 if (rlevel > 100) {
1350 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 1350, ((void*)0)
, SWITCH_LOG_ERROR, "Error including %s (Maximum recursion limit reached)\n", pattern);
1351 }
1352 }
1353 free(dir_path);
1354 }
1355 globfree(&glob_data);
1356
1357 end:
1358
1359 switch_safe_free(full_path)if (full_path) {free(full_path);full_path=((void*)0);};
1360
1361 return write_fd;
1362}
1363
1364static int preprocess(const char *cwd, const char *file, FILE *write_fd, int rlevel)
1365{
1366 FILE *read_fd = NULL((void*)0);
1367 switch_size_t cur = 0, ml = 0;
1368 char *q, *cmd, *buf = NULL((void*)0), *ebuf = NULL((void*)0);
1369 char *tcmd, *targ;
1370 int line = 0;
1371 switch_size_t len = 0, eblen = 0;
1372
1373 if (rlevel > 100) {
1374 return -1;
1375 }
1376
1377 if (!(read_fd = fopen(file, "r"))) {
1378 const char *reason = strerror(errno(*__errno_location ()));
1379 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 1379, ((void*)0)
, SWITCH_LOG_ERROR, "Couldn't open %s (%s)\n", file, reason);
1380 return -1;
1381 }
1382
1383 setvbuf(read_fd, (char *) NULL((void*)0), _IOFBF0, 65536);
1384
1385 for(;;) {
1386 char *arg, *e;
1387 const char *err = NULL((void*)0);
1388 char *bp;
1389
1390 switch_safe_free(ebuf)if (ebuf) {free(ebuf);ebuf=((void*)0);};
1391
1392 if ((cur = switch_fp_read_dline(read_fd, &buf, &len)) <= 0) {
1393 break;
1394 }
1395
1396 eblen = len *2;
1397 ebuf = malloc(eblen);
1398 memset(ebuf, 0, eblen);
1399
1400 bp = expand_vars(buf, ebuf, eblen, &cur, &err);
1401 line++;
1402
1403 if (err) {
1404 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 1404, ((void*)0)
, SWITCH_LOG_ERROR, "Error [%s] in file %s line %d\n", err, file, line);
1405 }
1406
1407 /* we ignore <include> or </include> for the sake of validators as well as <?xml version="1.0"?> type stuff */
1408 if (strstr(buf, "<include>") || strstr(buf, "</include>") || strstr(buf, "<?")) {
1409 continue;
1410 }
1411
1412 if (ml) {
1413 if ((e = strstr(buf, "-->"))) {
1414 ml = 0;
1415 bp = e + 3;
1416 cur = strlen(bp);
1417 } else {
1418 continue;
1419 }
1420 }
1421
1422 if ((tcmd = (char *) switch_stristr("X-pre-process", bp))) {
1423 if (*(tcmd - 1) != '<') {
1424 continue;
1425 }
1426 if ((e = strstr(tcmd, "/>"))) {
1427 *e += 2;
1428 *e = '\0';
1429 if (fwrite(e, 1, (unsigned) strlen(e), write_fd) != (int) strlen(e)) {
1430 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 1430, ((void*)0)
, SWITCH_LOG_ERROR, "Short write!\n");
1431 }
1432 }
1433
1434 if (!(tcmd = (char *) switch_stristr("cmd", tcmd))) {
1435 continue;
1436 }
1437
1438 if (!(tcmd = (char *) switch_stristr("=", tcmd))) {
1439 continue;
1440 }
1441
1442 if (!(tcmd = (char *) switch_stristr("\"", tcmd))) {
1443 continue;
1444 }
1445
1446 tcmd++;
1447
1448
1449 if ((e = strchr(tcmd, '"')(__extension__ (__builtin_constant_p ('"') && !__builtin_constant_p
(tcmd) && ('"') == '\0' ? (char *) __rawmemchr (tcmd
, '"') : __builtin_strchr (tcmd, '"')))
)) {
1450 *e++ = '\0';
1451 }
1452
1453 if (!(targ = (char *) switch_stristr("data", e))) {
1454 continue;
1455 }
1456
1457 if (!(targ = (char *) switch_stristr("=", targ))) {
1458 continue;
1459 }
1460
1461 if (!(targ = (char *) switch_stristr("\"", targ))) {
1462 continue;
1463 }
1464
1465 targ++;
1466
1467 if ((e = strchr(targ, '"')(__extension__ (__builtin_constant_p ('"') && !__builtin_constant_p
(targ) && ('"') == '\0' ? (char *) __rawmemchr (targ
, '"') : __builtin_strchr (targ, '"')))
)) {
1468 *e++ = '\0';
1469 }
1470
1471 if (!strcasecmp(tcmd, "set")) {
1472 char *name = (char *) targ;
1473 char *val = strchr(name, '=')(__extension__ (__builtin_constant_p ('=') && !__builtin_constant_p
(name) && ('=') == '\0' ? (char *) __rawmemchr (name
, '=') : __builtin_strchr (name, '=')))
;
1474
1475 if (val) {
1476 char *ve = val++;
1477 while (*val && *val == ' ') {
1478 val++;
1479 }
1480 *ve-- = '\0';
1481 while (*ve && *ve == ' ') {
1482 *ve-- = '\0';
1483 }
1484 }
1485
1486 if (name && val) {
1487 switch_core_set_variable(name, val);
1488 }
1489
1490 } else if (!strcasecmp(tcmd, "exec-set")) {
1491 preprocess_exec_set(targ);
1492 } else if (!strcasecmp(tcmd, "include")) {
1493 preprocess_glob(cwd, targ, write_fd, rlevel + 1);
1494 } else if (!strcasecmp(tcmd, "exec")) {
1495 preprocess_exec(cwd, targ, write_fd, rlevel + 1);
1496 }
1497
1498 continue;
1499 }
1500
1501 if ((cmd = strstr(bp, "<!--#"))) {
1502 if (fwrite(bp, 1, (unsigned) (cmd - bp), write_fd) != (unsigned) (cmd - bp)) {
1503 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 1503, ((void*)0)
, SWITCH_LOG_ERROR, "Short write!\n");
1504 }
1505 if ((e = strstr(cmd, "-->"))) {
1506 *e = '\0';
1507 e += 3;
1508 if (fwrite(e, 1, (unsigned) strlen(e), write_fd) != (int) strlen(e)) {
1509 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 1509, ((void*)0)
, SWITCH_LOG_ERROR, "Short write!\n");
1510 }
1511 } else {
1512 ml++;
1513 }
1514
1515 cmd += 5;
1516 if ((e = strchr(cmd, '\r')(__extension__ (__builtin_constant_p ('\r') && !__builtin_constant_p
(cmd) && ('\r') == '\0' ? (char *) __rawmemchr (cmd,
'\r') : __builtin_strchr (cmd, '\r')))
) || (e = strchr(cmd, '\n')(__extension__ (__builtin_constant_p ('\n') && !__builtin_constant_p
(cmd) && ('\n') == '\0' ? (char *) __rawmemchr (cmd,
'\n') : __builtin_strchr (cmd, '\n')))
)) {
1517 *e = '\0';
1518 }
1519
1520 if ((arg = strchr(cmd, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(cmd) && (' ') == '\0' ? (char *) __rawmemchr (cmd, ' '
) : __builtin_strchr (cmd, ' ')))
)) {
1521 *arg++ = '\0';
1522 if ((q = strchr(arg, '"')(__extension__ (__builtin_constant_p ('"') && !__builtin_constant_p
(arg) && ('"') == '\0' ? (char *) __rawmemchr (arg, '"'
) : __builtin_strchr (arg, '"')))
)) {
1523 char *qq = q + 1;
1524
1525 if ((qq = strchr(qq, '"')(__extension__ (__builtin_constant_p ('"') && !__builtin_constant_p
(qq) && ('"') == '\0' ? (char *) __rawmemchr (qq, '"'
) : __builtin_strchr (qq, '"')))
)) {
1526 *qq = '\0';
1527 arg = q + 1;
1528 }
1529 }
1530
1531 if (!strcasecmp(cmd, "set")) {
1532 char *name = arg;
1533 char *val = strchr(name, '=')(__extension__ (__builtin_constant_p ('=') && !__builtin_constant_p
(name) && ('=') == '\0' ? (char *) __rawmemchr (name
, '=') : __builtin_strchr (name, '=')))
;
1534
1535 if (val) {
1536 char *ve = val++;
1537 while (*val && *val == ' ') {
1538 val++;
1539 }
1540 *ve-- = '\0';
1541 while (*ve && *ve == ' ') {
1542 *ve-- = '\0';
1543 }
1544 }
1545
1546 if (name && val) {
1547 switch_core_set_variable(name, val);
1548 }
1549
1550 } else if (!strcasecmp(cmd, "exec-set")) {
1551 preprocess_exec_set(arg);
1552 } else if (!strcasecmp(cmd, "include")) {
1553 preprocess_glob(cwd, arg, write_fd, rlevel + 1);
1554 } else if (!strcasecmp(cmd, "exec")) {
1555 preprocess_exec(cwd, arg, write_fd, rlevel + 1);
1556 }
1557 }
1558
1559 continue;
1560 }
1561
1562 if (fwrite(bp, 1, (unsigned) cur, write_fd) != (int) cur) {
1563 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 1563, ((void*)0)
, SWITCH_LOG_ERROR, "Short write!\n");
1564 }
1565
1566 }
1567
1568 switch_safe_free(buf)if (buf) {free(buf);buf=((void*)0);};
1569 switch_safe_free(ebuf)if (ebuf) {free(ebuf);ebuf=((void*)0);};
1570
1571 fclose(read_fd);
1572
1573 return 0;
1574}
1575
1576SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_parse_file_simple(const char *file)
1577{
1578 int fd = -1;
1579 struct stat st;
1580 switch_ssize_t l;
1581 void *m;
1582 switch_xml_root_t root;
1583
1584 if ((fd = open(file, O_RDONLY00, 0)) > -1) {
1
Taking true branch
1585 fstat(fd, &st);
1586 if (!st.st_size) goto error;
2
Taking false branch
1587 m = malloc(st.st_size);
3
Memory is allocated
1588 switch_assert(m)((m) ? (void) (0) : __assert_fail ("m", "src/switch_xml.c", 1588
, __PRETTY_FUNCTION__))
;
4
Within the expansion of the macro 'switch_assert':
a
Assuming 'm' is non-null
1589 if (!(0<(l = read(fd, m, st.st_size)))) goto error;
5
Taking true branch
6
Control jumps to line 1598
1590 if (!(root = (switch_xml_root_t) switch_xml_parse_str((char *) m, l))) goto error;
1591 root->dynamic = 1;
1592 close(fd);
1593 return &root->xml;
1594 }
1595
1596 error:
1597
1598 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 1598, ((void*)0)
, SWITCH_LOG_ERROR, "Error Parsing File [%s]\n", file);
7
Potential leak of memory pointed to by 'm'
1599
1600 return NULL((void*)0);
1601}
1602
1603SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_parse_file(const char *file)
1604{
1605 int fd = -1;
1606 FILE *write_fd = NULL((void*)0);
1607 switch_xml_t xml = NULL((void*)0);
1608 char *new_file = NULL((void*)0);
1609 char *new_file_tmp = NULL((void*)0);
1610 const char *abs, *absw;
1611
1612 abs = strrchr(file, '/');
1613 absw = strrchr(file, '\\');
1614 if (abs || absw) {
1615 abs > absw ? abs++ : (abs = ++absw);
1616 } else {
1617 abs = file;
1618 }
1619
1620 switch_mutex_lock(FILE_LOCK);
1621
1622 if (!(new_file = switch_mprintf("%s%s%s.fsxml", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR"/", abs))) {
1623 goto done;
1624 }
1625
1626 if (!(new_file_tmp = switch_mprintf("%s%s%s.fsxml.tmp", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR"/", abs))) {
1627 goto done;
1628 }
1629
1630 if ((write_fd = fopen(new_file_tmp, "w+")) == NULL((void*)0)) {
1631 goto done;
1632 }
1633
1634 setvbuf(write_fd, (char *) NULL((void*)0), _IOFBF0, 65536);
1635
1636 if (preprocess(SWITCH_GLOBAL_dirs.conf_dir, file, write_fd, 0) > -1) {
1637 fclose(write_fd);
1638 write_fd = NULL((void*)0);
1639 unlink (new_file);
1640
1641 if ( rename(new_file_tmp,new_file) ) {
1642 goto done;
1643 }
1644 if ((fd = open(new_file, O_RDONLY00, 0)) > -1) {
1645 if ((xml = switch_xml_parse_fd(fd))) {
1646 if (strcmp(abs, SWITCH_GLOBAL_filenames.conf_name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(abs) && __builtin_constant_p (SWITCH_GLOBAL_filenames
.conf_name) && (__s1_len = __builtin_strlen (abs), __s2_len
= __builtin_strlen (SWITCH_GLOBAL_filenames.conf_name), (!((
size_t)(const void *)((abs) + 1) - (size_t)(const void *)(abs
) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)((SWITCH_GLOBAL_filenames.conf_name) + 1) - (size_t)(const
void *)(SWITCH_GLOBAL_filenames.conf_name) == 1) || __s2_len
>= 4)) ? __builtin_strcmp (abs, SWITCH_GLOBAL_filenames.conf_name
) : (__builtin_constant_p (abs) && ((size_t)(const void
*)((abs) + 1) - (size_t)(const void *)(abs) == 1) &&
(__s1_len = __builtin_strlen (abs), __s1_len < 4) ? (__builtin_constant_p
(SWITCH_GLOBAL_filenames.conf_name) && ((size_t)(const
void *)((SWITCH_GLOBAL_filenames.conf_name) + 1) - (size_t)(
const void *)(SWITCH_GLOBAL_filenames.conf_name) == 1) ? __builtin_strcmp
(abs, SWITCH_GLOBAL_filenames.conf_name) : (__extension__ ({
const unsigned char *__s2 = (const unsigned char *) (const char
*) (SWITCH_GLOBAL_filenames.conf_name); int __result = (((const
unsigned char *) (const char *) (abs))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (abs))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (abs))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (abs))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(SWITCH_GLOBAL_filenames.conf_name) && ((size_t)(const
void *)((SWITCH_GLOBAL_filenames.conf_name) + 1) - (size_t)(
const void *)(SWITCH_GLOBAL_filenames.conf_name) == 1) &&
(__s2_len = __builtin_strlen (SWITCH_GLOBAL_filenames.conf_name
), __s2_len < 4) ? (__builtin_constant_p (abs) && (
(size_t)(const void *)((abs) + 1) - (size_t)(const void *)(abs
) == 1) ? __builtin_strcmp (abs, SWITCH_GLOBAL_filenames.conf_name
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (abs); int __result = (((const unsigned
char *) (const char *) (SWITCH_GLOBAL_filenames.conf_name))[
0] - __s2[0]); if (__s2_len > 0 && __result == 0) {
__result = (((const unsigned char *) (const char *) (SWITCH_GLOBAL_filenames
.conf_name))[1] - __s2[1]); if (__s2_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
SWITCH_GLOBAL_filenames.conf_name))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (SWITCH_GLOBAL_filenames.conf_name))[
3] - __s2[3]); } } __result; })))) : __builtin_strcmp (abs, SWITCH_GLOBAL_filenames
.conf_name)))); })
) {
1647 xml->free_path = new_file;
1648 new_file = NULL((void*)0);
1649 }
1650 }
1651 close(fd);
1652 fd = -1;
1653 }
1654 }
1655
1656 done:
1657
1658 switch_mutex_unlock(FILE_LOCK);
1659
1660 if (write_fd) {
1661 fclose(write_fd);
1662 write_fd = NULL((void*)0);
1663 }
1664
1665 if (fd > -1) {
1666 close(fd);
1667 }
1668
1669 switch_safe_free(new_file_tmp)if (new_file_tmp) {free(new_file_tmp);new_file_tmp=((void*)0)
;}
;
1670 switch_safe_free(new_file)if (new_file) {free(new_file);new_file=((void*)0);};
1671
1672 return xml;
1673}
1674
1675SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_xml_locate(const char *section,
1676 const char *tag_name,
1677 const char *key_name,
1678 const char *key_value,
1679 switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_bool_t clone)
1680{
1681 switch_xml_t conf = NULL((void*)0);
1682 switch_xml_t tag = NULL((void*)0);
1683 switch_xml_t xml = NULL((void*)0);
1684 switch_xml_binding_t *binding;
1685 uint8_t loops = 0;
1686 switch_xml_section_t sections = BINDINGS ? switch_xml_parse_section_string(section) : 0;
1687
1688 switch_thread_rwlock_rdlock(B_RWLOCK);
1689
1690 for (binding = BINDINGS; binding; binding = binding->next) {
1691 if (binding->sections && !(sections & binding->sections)) {
1692 continue;
1693 }
1694
1695 if ((xml = binding->function(section, tag_name, key_name, key_value, params, binding->user_data))) {
1696 const char *err = NULL((void*)0);
1697
1698 err = switch_xml_error(xml);
1699 if (zstr(err)_zstr(err)) {
1700 if ((conf = switch_xml_find_child(xml, "section", "name", "result"))) {
1701 switch_xml_t p;
1702 const char *aname;
1703
1704 if ((p = switch_xml_child(conf, "result"))) {
1705 aname = switch_xml_attr(p, "status");
1706 if (aname && !strcasecmp(aname, "not found")) {
1707 switch_xml_free(xml);
1708 xml = NULL((void*)0);
1709 continue;
1710 }
1711 }
1712 }
1713 break;
1714 } else {
1715 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 1715, ((void*)0)
, SWITCH_LOG_ERROR, "Error[%s]\n", err);
1716 switch_xml_free(xml);
1717 xml = NULL((void*)0);
1718 }
1719 }
1720 }
1721 switch_thread_rwlock_unlock(B_RWLOCK);
1722
1723 for (;;) {
1724 if (!xml) {
1725 if (!(xml = switch_xml_root())) {
1726 *node = NULL((void*)0);
1727 *root = NULL((void*)0);
1728 return SWITCH_STATUS_FALSE;
1729 }
1730 }
1731
1732 if ((conf = switch_xml_find_child(xml, "section", "name", section)) && (tag = switch_xml_find_child(conf, tag_name, key_name, key_value))) {
1733 if (clone) {
1734 char *x = switch_xml_toxml(tag, SWITCH_FALSE);
1735 switch_assert(x)((x) ? (void) (0) : __assert_fail ("x", "src/switch_xml.c", 1735
, __PRETTY_FUNCTION__))
;
1736 *node = *root = switch_xml_parse_str_dynamic(x, SWITCH_FALSE); /* x will be free()'d in switch_xml_free() */
1737 switch_xml_free(xml);
1738 } else {
1739 *node = tag;
1740 *root = xml;
1741 }
1742 return SWITCH_STATUS_SUCCESS;
1743 } else {
1744 switch_xml_free(xml);
1745 xml = NULL((void*)0);
1746 *node = NULL((void*)0);
1747 *root = NULL((void*)0);
1748 if (loops++ > 1) {
1749 break;
1750 }
1751 }
1752 }
1753
1754 return SWITCH_STATUS_FALSE;
1755}
1756
1757SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_xml_locate_domain(const char *domain_name, switch_event_t *params, switch_xml_t *root, switch_xml_t *domain)
1758{
1759 switch_event_t *my_params = NULL((void*)0);
1760 switch_status_t status;
1761 *domain = NULL((void*)0);
1762
1763 if (!params) {
1764 switch_event_create(&my_params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("src/switch_xml.c", (const
char * )(const char *)__func__, 1764, &my_params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
1765 switch_assert(my_params)((my_params) ? (void) (0) : __assert_fail ("my_params", "src/switch_xml.c"
, 1765, __PRETTY_FUNCTION__))
;
1766 switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "domain", domain_name);
1767 params = my_params;
1768 }
1769
1770 status = switch_xml_locate("directory", "domain", "name", domain_name, root, domain, params, SWITCH_FALSE);
1771 if (my_params) {
1772 switch_event_destroy(&my_params);
1773 }
1774 return status;
1775}
1776
1777SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_xml_locate_group(const char *group_name,
1778 const char *domain_name,
1779 switch_xml_t *root, switch_xml_t *domain, switch_xml_t *group, switch_event_t *params)
1780{
1781 switch_status_t status = SWITCH_STATUS_FALSE;
1782 switch_event_t *my_params = NULL((void*)0);
1783 switch_xml_t groups = NULL((void*)0);
1784
1785 *root = NULL((void*)0);
1786 *group = NULL((void*)0);
1787 *domain = NULL((void*)0);
1788
1789 if (!params) {
1790 switch_event_create(&my_params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("src/switch_xml.c", (const
char * )(const char *)__func__, 1790, &my_params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
1791 switch_assert(my_params)((my_params) ? (void) (0) : __assert_fail ("my_params", "src/switch_xml.c"
, 1791, __PRETTY_FUNCTION__))
;
1792 params = my_params;
1793 }
1794
1795 if (group_name) {
1796 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "group_name", group_name);
1797 }
1798
1799 if (domain_name) {
1800 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain_name);
1801 }
1802
1803 if ((status = switch_xml_locate_domain(domain_name, params, root, domain)) != SWITCH_STATUS_SUCCESS) {
1804 goto end;
1805 }
1806
1807 status = SWITCH_STATUS_FALSE;
1808
1809 if ((groups = switch_xml_child(*domain, "groups"))) {
1810 if ((*group = switch_xml_find_child(groups, "group", "name", group_name))) {
1811 status = SWITCH_STATUS_SUCCESS;
1812 }
1813 }
1814
1815 end:
1816
1817 if (my_params) {
1818 switch_event_destroy(&my_params);
1819 }
1820
1821 return status;
1822}
1823
1824static switch_status_t find_user_in_tag(switch_xml_t tag, const char *ip, const char *user_name,
1825 const char *key, switch_event_t *params, switch_xml_t *user)
1826{
1827 const char *type = "!pointer";
1828 const char *val;
1829
1830 if (params && (val = switch_event_get_header(params, "user_type")switch_event_get_header_idx(params, "user_type", -1))) {
1831 if (!strcasecmp(val, "any")) {
1832 type = NULL((void*)0);
1833 } else {
1834 type = val;
1835 }
1836 }
1837
1838 if (ip) {
1839 if ((*user = switch_xml_find_child_multi(tag, "user", "ip", ip, "type", type, NULL((void*)0)))) {
1840 return SWITCH_STATUS_SUCCESS;
1841 }
1842 }
1843
1844 if (user_name) {
1845 if (!strcasecmp(key, "id")) {
1846 if ((*user = switch_xml_find_child_multi(tag, "user", key, user_name, "number-alias", user_name, "type", type, NULL((void*)0)))) {
1847 return SWITCH_STATUS_SUCCESS;
1848 }
1849 } else {
1850 if ((*user = switch_xml_find_child_multi(tag, "user", key, user_name, "type", type, NULL((void*)0)))) {
1851 return SWITCH_STATUS_SUCCESS;
1852 }
1853 }
1854 }
1855
1856 return SWITCH_STATUS_FALSE;
1857
1858}
1859
1860SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_xml_locate_user_in_domain(const char *user_name, switch_xml_t domain, switch_xml_t *user, switch_xml_t *ingroup)
1861{
1862 switch_xml_t group = NULL((void*)0), groups = NULL((void*)0), users = NULL((void*)0);
1863 switch_status_t status = SWITCH_STATUS_FALSE;
1864
1865 if ((groups = switch_xml_child(domain, "groups"))) {
1866 for (group = switch_xml_child(groups, "group"); group; group = group->next) {
1867 if ((users = switch_xml_child(group, "users"))) {
1868 if ((status = find_user_in_tag(users, NULL((void*)0), user_name, "id", NULL((void*)0), user)) == SWITCH_STATUS_SUCCESS) {
1869 if (ingroup) {
1870 *ingroup = group;
1871 }
1872 break;
1873 }
1874 }
1875 }
1876 }
1877
1878 return status;
1879}
1880
1881
1882SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_dup(switch_xml_t xml)
1883{
1884 char *x = switch_xml_toxml(xml, SWITCH_FALSE);
1885 return switch_xml_parse_str_dynamic(x, SWITCH_FALSE);
1886}
1887
1888
1889static void do_merge(switch_xml_t in, switch_xml_t src, const char *container, const char *tag_name)
1890{
1891 switch_xml_t itag, tag, param, iparam, iitag;
1892
1893 if (!(itag = switch_xml_child(in, container))) {
1894 itag = switch_xml_add_child_d(in, container, 0)switch_xml_set_flag(switch_xml_add_child(in, (__extension__ (
__builtin_constant_p (container) && ((size_t)(const void
*)((container) + 1) - (size_t)(const void *)(container) == 1
) ? (((const char *) (container))[0] == '\0' ? (char *) calloc
((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (container
) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, container
, __len); __retval; })) : __strdup (container))), 0), SWITCH_XML_NAMEM
)
;
1895 }
1896
1897 if ((tag = switch_xml_child(src, container))) {
1898 for (param = switch_xml_child(tag, tag_name); param; param = param->next) {
1899 const char *var = switch_xml_attr(param, "name");
1900 const char *val = switch_xml_attr(param, "value");
1901
1902 int go = 1;
1903
1904 for (iparam = switch_xml_child(itag, tag_name); iparam; iparam = iparam->next) {
1905 const char *ivar = switch_xml_attr(iparam, "name");
1906
1907 if (var && ivar && !strcasecmp(var, ivar)) {
1908 go = 0;
1909 break;
1910 }
1911 }
1912
1913 if (go) {
1914 iitag = switch_xml_add_child_d(itag, tag_name, 0)switch_xml_set_flag(switch_xml_add_child(itag, (__extension__
(__builtin_constant_p (tag_name) && ((size_t)(const void
*)((tag_name) + 1) - (size_t)(const void *)(tag_name) == 1) ?
(((const char *) (tag_name))[0] == '\0' ? (char *) calloc ((
size_t) 1, (size_t) 1) : ({ size_t __len = strlen (tag_name) +
1; char *__retval = (char *) malloc (__len); if (__retval !=
((void*)0)) __retval = (char *) memcpy (__retval, tag_name, __len
); __retval; })) : __strdup (tag_name))), 0), SWITCH_XML_NAMEM
)
;
1915 switch_xml_set_attr_d(iitag, "name", var)switch_xml_set_attr(switch_xml_set_flag(iitag, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("name") && (
(size_t)(const void *)(("name") + 1) - (size_t)(const void *)
("name") == 1) ? (((const char *) ("name"))[0] == '\0' ? (char
*) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen
("name") + 1; char *__retval = (char *) malloc (__len); if (
__retval != ((void*)0)) __retval = (char *) memcpy (__retval,
"name", __len); __retval; })) : __strdup ("name"))), (__extension__
(__builtin_constant_p ((var ? var : "")) && ((size_t
)(const void *)(((var ? var : "")) + 1) - (size_t)(const void
*)((var ? var : "")) == 1) ? (((const char *) ((var ? var : ""
)))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : (
{ size_t __len = strlen ((var ? var : "")) + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, (var ? var : ""), __len); __retval
; })) : __strdup ((var ? var : "")))))
;
1916 switch_xml_set_attr_d(iitag, "value", val)switch_xml_set_attr(switch_xml_set_flag(iitag, SWITCH_XML_DUP
), (__extension__ (__builtin_constant_p ("value") && (
(size_t)(const void *)(("value") + 1) - (size_t)(const void *
)("value") == 1) ? (((const char *) ("value"))[0] == '\0' ? (
char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen
("value") + 1; char *__retval = (char *) malloc (__len); if (
__retval != ((void*)0)) __retval = (char *) memcpy (__retval,
"value", __len); __retval; })) : __strdup ("value"))), (__extension__
(__builtin_constant_p ((val ? val : "")) && ((size_t
)(const void *)(((val ? val : "")) + 1) - (size_t)(const void
*)((val ? val : "")) == 1) ? (((const char *) ((val ? val : ""
)))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : (
{ size_t __len = strlen ((val ? val : "")) + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, (val ? val : ""), __len); __retval
; })) : __strdup ((val ? val : "")))))
;
1917 }
1918 }
1919 }
1920
1921}
1922
1923
1924SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_xml_merge_user(switch_xml_t user, switch_xml_t domain, switch_xml_t group)
1925{
1926 const char *domain_name = switch_xml_attr(domain, "name");
1927
1928 do_merge(user, group, "params", "param");
1929 do_merge(user, group, "variables", "variable");
1930 do_merge(user, group, "profile-variables", "variable");
1931 do_merge(user, domain, "params", "param");
1932 do_merge(user, domain, "variables", "variable");
1933 do_merge(user, domain, "profile-variables", "variable");
1934
1935 if (!zstr(domain_name)_zstr(domain_name)) {
1936 switch_xml_set_attr_d(user, "domain-name", domain_name)switch_xml_set_attr(switch_xml_set_flag(user, SWITCH_XML_DUP)
, (__extension__ (__builtin_constant_p ("domain-name") &&
((size_t)(const void *)(("domain-name") + 1) - (size_t)(const
void *)("domain-name") == 1) ? (((const char *) ("domain-name"
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen ("domain-name") + 1; char *__retval = (
char *) malloc (__len); if (__retval != ((void*)0)) __retval =
(char *) memcpy (__retval, "domain-name", __len); __retval; }
)) : __strdup ("domain-name"))), (__extension__ (__builtin_constant_p
((domain_name ? domain_name : "")) && ((size_t)(const
void *)(((domain_name ? domain_name : "")) + 1) - (size_t)(const
void *)((domain_name ? domain_name : "")) == 1) ? (((const char
*) ((domain_name ? domain_name : "")))[0] == '\0' ? (char *)
calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (
(domain_name ? domain_name : "")) + 1; char *__retval = (char
*) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, (domain_name ? domain_name : ""), __len
); __retval; })) : __strdup ((domain_name ? domain_name : "")
))))
;
1937 }
1938}
1939
1940SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_xml_clear_user_cache(const char *key, const char *user_name, const char *domain_name)
1941{
1942 switch_hash_index_t *hi = NULL((void*)0);
1943 void *val;
1944 const void *var;
1945 char mega_key[1024];
1946 int r = 0;
1947 switch_xml_t lookup;
1948 char *expires_val = NULL((void*)0);
1949
1950 switch_mutex_lock(CACHE_MUTEX);
1951
1952 if (key && user_name && domain_name) {
1953 switch_snprintf(mega_key, sizeof(mega_key), "%s%s%s", key, user_name, domain_name);
1954
1955 if ((lookup = switch_core_hash_find(CACHE_HASH, mega_key))) {
1956 switch_core_hash_delete(CACHE_HASH, mega_key);
1957 if ((expires_val = switch_core_hash_find(CACHE_EXPIRES_HASH, mega_key))) {
1958 switch_core_hash_delete(CACHE_EXPIRES_HASH, mega_key);
1959 free(expires_val);
1960 expires_val = NULL((void*)0);
1961 }
1962 switch_xml_free(lookup);
1963 r++;
1964 }
1965
1966 } else {
1967
1968 while ((hi = switch_core_hash_first_iter( CACHE_HASH, hi))) {
1969 switch_core_hash_this(hi, &var, NULL((void*)0), &val);
1970 switch_xml_free(val);
1971 switch_core_hash_delete(CACHE_HASH, var);
1972 r++;
1973 }
1974
1975 while ((hi = switch_core_hash_first_iter( CACHE_EXPIRES_HASH, hi))) {
1976 switch_core_hash_this(hi, &var, NULL((void*)0), &val);
1977 switch_safe_free(val)if (val) {free(val);val=((void*)0);};
1978 switch_core_hash_delete(CACHE_EXPIRES_HASH, var);
1979 }
1980
1981 switch_safe_free(hi)if (hi) {free(hi);hi=((void*)0);};
1982 }
1983
1984 switch_mutex_unlock(CACHE_MUTEX);
1985
1986 return r;
1987
1988}
1989
1990static switch_status_t switch_xml_locate_user_cache(const char *key, const char *user_name, const char *domain_name, switch_xml_t *user)
1991{
1992 char mega_key[1024];
1993 switch_status_t status = SWITCH_STATUS_FALSE;
1994 switch_xml_t lookup;
1995
1996 switch_snprintf(mega_key, sizeof(mega_key), "%s%s%s", key, user_name, domain_name);
1997
1998 switch_mutex_lock(CACHE_MUTEX);
1999 if ((lookup = switch_core_hash_find(CACHE_HASH, mega_key))) {
2000 char *expires_lookup = NULL((void*)0);
2001
2002 if ((expires_lookup = switch_core_hash_find(CACHE_EXPIRES_HASH, mega_key))) {
2003 switch_time_t time_expires = 0;
2004 switch_time_t time_now = 0;
2005
2006 time_now = switch_micro_time_now();
2007 time_expires = atol(expires_lookup);
2008 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 2008, ((void*)0)
, SWITCH_LOG_DEBUG, "Cache Info\nTime Now:\t%ld\nExpires:\t%ld\n", (long)time_now, (long)time_expires);
2009 if (time_expires < time_now) {
2010 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 2010, ((void*)0)
, SWITCH_LOG_DEBUG, "Cache expired for %s@%s, doing fresh lookup\n", user_name, domain_name);
2011 } else {
2012 *user = switch_xml_dup(lookup);
2013 status = SWITCH_STATUS_SUCCESS;
2014 }
2015 } else {
2016 *user = switch_xml_dup(lookup);
2017 status = SWITCH_STATUS_SUCCESS;
2018 }
2019 }
2020 switch_mutex_unlock(CACHE_MUTEX);
2021
2022 return status;
2023}
2024
2025static void switch_xml_user_cache(const char *key, const char *user_name, const char *domain_name, switch_xml_t user, switch_time_t expires)
2026{
2027 char mega_key[1024];
2028 switch_xml_t lookup;
2029 char *expires_lookup;
2030
2031 switch_snprintf(mega_key, sizeof(mega_key), "%s%s%s", key, user_name, domain_name);
2032
2033 switch_mutex_lock(CACHE_MUTEX);
2034 if ((lookup = switch_core_hash_find(CACHE_HASH, mega_key))) {
2035 switch_core_hash_delete(CACHE_HASH, mega_key);
2036 switch_xml_free(lookup);
2037 }
2038 if ((expires_lookup = switch_core_hash_find(CACHE_EXPIRES_HASH, mega_key))) {
2039 switch_core_hash_delete(CACHE_EXPIRES_HASH, mega_key);
2040 switch_safe_free(expires_lookup)if (expires_lookup) {free(expires_lookup);expires_lookup=((void
*)0);}
;
2041 }
2042 if (expires) {
2043 char *expires_val = malloc(1024);
2044 if (sprintf(expires_val, "%ld", (long)expires)) {
2045 switch_core_hash_insert(CACHE_EXPIRES_HASH, mega_key, expires_val)switch_core_hash_insert_destructor(CACHE_EXPIRES_HASH, mega_key
, expires_val, ((void*)0))
;
2046 } else {
2047 switch_safe_free(expires_val)if (expires_val) {free(expires_val);expires_val=((void*)0);};
2048 }
2049 }
2050 switch_core_hash_insert(CACHE_HASH, mega_key, switch_xml_dup(user))switch_core_hash_insert_destructor(CACHE_HASH, mega_key, switch_xml_dup
(user), ((void*)0))
;
2051 switch_mutex_unlock(CACHE_MUTEX);
2052}
2053
2054SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_xml_locate_user_merged(const char *key, const char *user_name, const char *domain_name,
2055 const char *ip, switch_xml_t *user, switch_event_t *params)
2056{
2057 switch_xml_t xml, domain, group, x_user, x_user_dup;
2058 switch_status_t status = SWITCH_STATUS_FALSE;
2059 char *kdup = NULL((void*)0);
2060 char *keys[10] = {0};
2061 int i, nkeys;
2062
2063 if (strchr(key, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(key) && (':') == '\0' ? (char *) __rawmemchr (key, ':'
) : __builtin_strchr (key, ':')))
) {
2064 kdup = strdup(key)(__extension__ (__builtin_constant_p (key) && ((size_t
)(const void *)((key) + 1) - (size_t)(const void *)(key) == 1
) ? (((const char *) (key))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (key) + 1; char *
__retval = (char *) malloc (__len); if (__retval != ((void*)0
)) __retval = (char *) memcpy (__retval, key, __len); __retval
; })) : __strdup (key)))
;
2065 nkeys = switch_split(kdup, ':', keys)switch_separate_string(kdup, ':', keys, (sizeof(keys) / sizeof
(keys[0])))
;
2066 } else {
2067 keys[0] = (char *)key;
2068 nkeys = 1;
2069 }
2070
2071 for(i = 0; i < nkeys; i++) {
2072 if ((status = switch_xml_locate_user_cache(keys[i], user_name, domain_name, &x_user)) == SWITCH_STATUS_SUCCESS) {
2073 *user = x_user;
2074 break;
2075 } else if ((status = switch_xml_locate_user(keys[i], user_name, domain_name, ip, &xml, &domain, &x_user, &group, params)) == SWITCH_STATUS_SUCCESS) {
2076 const char *cacheable = NULL((void*)0);
2077
2078 x_user_dup = switch_xml_dup(x_user);
2079 switch_xml_merge_user(x_user_dup, domain, group);
2080
2081 cacheable = switch_xml_attr(x_user_dup, "cacheable");
2082 if (!zstr(cacheable)_zstr(cacheable)) {
2083 switch_time_t expires = 0;
2084 switch_time_t time_now = 0;
2085
2086 if (switch_is_number(cacheable)) {
2087 int cache_ms = atol(cacheable);
2088 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 2088, ((void*)0)
, SWITCH_LOG_DEBUG, "caching lookup for user %s@%s for %d milliseconds\n",
2089 user_name, domain_name, cache_ms);
2090 time_now = switch_micro_time_now();
2091 expires = time_now + (cache_ms * 1000);
2092 } else {
2093 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 2093, ((void*)0)
, SWITCH_LOG_DEBUG, "caching lookup for user %s@%s indefinitely\n", user_name, domain_name);
2094 }
2095 switch_xml_user_cache(keys[i], user_name, domain_name, x_user_dup, expires);
2096 }
2097 *user = x_user_dup;
2098 switch_xml_free(xml);
2099 break;
2100 }
2101 }
2102
2103 switch_safe_free(kdup)if (kdup) {free(kdup);kdup=((void*)0);};
2104
2105 return status;
2106
2107}
2108
2109SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_xml_locate_user(const char *key,
2110 const char *user_name,
2111 const char *domain_name,
2112 const char *ip,
2113 switch_xml_t *root,
2114 switch_xml_t *domain, switch_xml_t *user, switch_xml_t *ingroup, switch_event_t *params)
2115{
2116 switch_status_t status = SWITCH_STATUS_FALSE;
2117 switch_event_t *my_params = NULL((void*)0);
2118 switch_xml_t group = NULL((void*)0), groups = NULL((void*)0), users = NULL((void*)0);
2119
2120 *root = NULL((void*)0);
2121 *user = NULL((void*)0);
2122 *domain = NULL((void*)0);
2123
2124 if (ingroup) {
2125 *ingroup = NULL((void*)0);
2126 }
2127
2128 if (!params) {
2129 switch_event_create(&my_params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("src/switch_xml.c", (const
char * )(const char *)__func__, 2129, &my_params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
2130 switch_assert(my_params)((my_params) ? (void) (0) : __assert_fail ("my_params", "src/switch_xml.c"
, 2130, __PRETTY_FUNCTION__))
;
2131 params = my_params;
2132 }
2133
2134 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "key", key);
2135
2136 if (user_name) {
2137 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "user", user_name);
2138 }
2139
2140 if (domain_name) {
2141 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain_name);
2142 }
2143
2144 if (ip) {
2145 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "ip", ip);
2146 }
2147
2148 if ((status = switch_xml_locate_domain(domain_name, params, root, domain)) != SWITCH_STATUS_SUCCESS) {
2149 goto end;
2150 }
2151
2152 status = SWITCH_STATUS_FALSE;
2153
2154 if ((groups = switch_xml_child(*domain, "groups"))) {
2155 for (group = switch_xml_child(groups, "group"); group; group = group->next) {
2156 if ((users = switch_xml_child(group, "users"))) {
2157 if ((status = find_user_in_tag(users, ip, user_name, key, params, user)) == SWITCH_STATUS_SUCCESS) {
2158 if (ingroup) {
2159 *ingroup = group;
2160 }
2161 break;
2162 }
2163 }
2164 }
2165 }
2166
2167 if (status != SWITCH_STATUS_SUCCESS) {
2168 status = find_user_in_tag(*domain, ip, user_name, key, params, user);
2169 }
2170
2171 end:
2172
2173 if (my_params) {
2174 switch_event_destroy(&my_params);
2175 }
2176
2177 if (status != SWITCH_STATUS_SUCCESS && root && *root) {
2178 switch_xml_free(*root);
2179 *root = NULL((void*)0);
2180 *domain = NULL((void*)0);
2181 }
2182
2183 return status;
2184}
2185
2186SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_root(void)
2187{
2188 switch_xml_t xml;
2189
2190 switch_mutex_lock(REFLOCK);
2191 xml = MAIN_XML_ROOT;
2192 xml->refs++;
2193 switch_mutex_unlock(REFLOCK);
2194
2195 return xml;
2196}
2197
2198struct destroy_xml {
2199 switch_xml_t xml;
2200 switch_memory_pool_t *pool;
2201};
2202
2203static void *SWITCH_THREAD_FUNC destroy_thread(switch_thread_t *thread, void *obj)
2204{
2205 struct destroy_xml *dx = (struct destroy_xml *) obj;
2206 switch_memory_pool_t *pool = dx->pool;
2207 switch_xml_free(dx->xml);
2208 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_xml.c"
, (const char *)__func__, 2208)
;
2209 return NULL((void*)0);
2210}
2211
2212SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_xml_free_in_thread(switch_xml_t xml, int stacksize)
2213{
2214 switch_thread_t *thread;
2215 switch_threadattr_t *thd_attr;
2216 switch_memory_pool_t *pool = NULL((void*)0);
2217 struct destroy_xml *dx;
2218
2219 switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_xml.c"
, (const char *)__func__, 2219)
;
2220
2221 switch_threadattr_create(&thd_attr, pool);
2222 switch_threadattr_detach_set(thd_attr, 1);
2223 /* TBD figure out how much space we need by looking at the xml_t when stacksize == 0 */
2224 switch_threadattr_stacksize_set(thd_attr, stacksize);
2225
2226 dx = switch_core_alloc(pool, sizeof(*dx))switch_core_perform_alloc(pool, sizeof(*dx), "src/switch_xml.c"
, (const char *)__func__, 2226)
;
2227 dx->pool = pool;
2228 dx->xml = xml;
2229
2230 switch_thread_create(&thread, thd_attr, destroy_thread, dx, pool);
2231}
2232
2233static char not_so_threadsafe_error_buffer[256] = "";
2234
2235SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_xml_set_root(switch_xml_t new_main)
2236{
2237 switch_xml_t old_root = NULL((void*)0);
2238
2239 switch_mutex_lock(REFLOCK);
2240
2241 old_root = MAIN_XML_ROOT;
2242 MAIN_XML_ROOT = new_main;
2243 switch_set_flag(MAIN_XML_ROOT, SWITCH_XML_ROOT)(MAIN_XML_ROOT)->flags |= (SWITCH_XML_ROOT);
2244 MAIN_XML_ROOT->refs++;
2245
2246 if (old_root) {
2247 if (old_root->refs) {
2248 old_root->refs--;
2249 }
2250
2251 if (!old_root->refs) {
2252 switch_xml_free(old_root);
2253 }
2254 }
2255
2256 switch_mutex_unlock(REFLOCK);
2257
2258 return SWITCH_STATUS_SUCCESS;
2259}
2260
2261SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_xml_set_open_root_function(switch_xml_open_root_function_t func, void *user_data)
2262{
2263 if (XML_LOCK) {
2264 switch_mutex_lock(XML_LOCK);
2265 }
2266
2267 XML_OPEN_ROOT_FUNCTION = func;
2268 XML_OPEN_ROOT_FUNCTION_USER_DATA = user_data;
2269
2270 if (XML_LOCK) {
2271 switch_mutex_unlock(XML_LOCK);
2272 }
2273 return SWITCH_STATUS_SUCCESS;
2274}
2275
2276SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_open_root(uint8_t reload, const char **err)
2277{
2278 switch_xml_t root = NULL((void*)0);
2279 switch_event_t *event;
2280
2281 switch_mutex_lock(XML_LOCK);
2282
2283 if (XML_OPEN_ROOT_FUNCTION) {
2284 root = XML_OPEN_ROOT_FUNCTION(reload, err, XML_OPEN_ROOT_FUNCTION_USER_DATA);
2285 }
2286 switch_mutex_unlock(XML_LOCK);
2287
2288
2289 if (root) {
2290 if (switch_event_create(&event, SWITCH_EVENT_RELOADXML)switch_event_create_subclass_detailed("src/switch_xml.c", (const
char * )(const char *)__func__, 2290, &event, SWITCH_EVENT_RELOADXML
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
2291 if (switch_event_fire(&event)switch_event_fire_detailed("src/switch_xml.c", (const char * )
(const char *)__func__, 2291, &event, ((void*)0))
!= SWITCH_STATUS_SUCCESS) {
2292 switch_event_destroy(&event);
2293 }
2294 }
2295 }
2296
2297 return root;
2298}
2299
2300SWITCH_DECLARE_NONSTD(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t __switch_xml_open_root(uint8_t reload, const char **err, void *user_data)
2301{
2302 char path_buf[1024];
2303 uint8_t errcnt = 0;
2304 switch_xml_t new_main, r = NULL((void*)0);
2305
2306 if (MAIN_XML_ROOT) {
2307 if (!reload) {
2308 r = switch_xml_root();
2309 goto done;
2310 }
2311 }
2312
2313 switch_snprintf(path_buf, sizeof(path_buf), "%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR"/", SWITCH_GLOBAL_filenames.conf_name);
2314 if ((new_main = switch_xml_parse_file(path_buf))) {
2315 *err = switch_xml_error(new_main);
2316 switch_copy_string(not_so_threadsafe_error_buffer, *err, sizeof(not_so_threadsafe_error_buffer));
2317 *err = not_so_threadsafe_error_buffer;
2318 if (!zstr(*err)_zstr(*err)) {
2319 switch_xml_free(new_main);
2320 new_main = NULL((void*)0);
2321 errcnt++;
2322 } else {
2323 *err = "Success";
2324 switch_xml_set_root(new_main);
2325
2326 }
2327 } else {
2328 *err = "Cannot Open log directory or XML Root!";
2329 errcnt++;
2330 }
2331
2332 if (errcnt == 0) {
2333 r = switch_xml_root();
2334 }
2335
2336 done:
2337
2338 return r;
2339}
2340
2341SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_xml_reload(const char **err)
2342{
2343 switch_xml_t xml_root;
2344
2345 if ((xml_root = switch_xml_open_root(1, err))) {
2346 switch_xml_free(xml_root);
2347 return SWITCH_STATUS_SUCCESS;
2348 }
2349
2350 return SWITCH_STATUS_GENERR;
2351}
2352
2353SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_xml_init(switch_memory_pool_t *pool, const char **err)
2354{
2355 switch_xml_t xml;
2356 XML_MEMORY_POOL = pool;
2357 *err = "Success";
2358
2359 switch_mutex_init(&CACHE_MUTEX, SWITCH_MUTEX_NESTED0x1, XML_MEMORY_POOL);
2360 switch_mutex_init(&XML_LOCK, SWITCH_MUTEX_NESTED0x1, XML_MEMORY_POOL);
2361 switch_mutex_init(&REFLOCK, SWITCH_MUTEX_NESTED0x1, XML_MEMORY_POOL);
2362 switch_mutex_init(&FILE_LOCK, SWITCH_MUTEX_NESTED0x1, XML_MEMORY_POOL);
2363 switch_core_hash_init(&CACHE_HASH)switch_core_hash_init_case(&CACHE_HASH, SWITCH_TRUE);
2364 switch_core_hash_init(&CACHE_EXPIRES_HASH)switch_core_hash_init_case(&CACHE_EXPIRES_HASH, SWITCH_TRUE
)
;
2365
2366 switch_thread_rwlock_create(&B_RWLOCK, XML_MEMORY_POOL);
2367
2368 assert(pool != NULL)((pool != ((void*)0)) ? (void) (0) : __assert_fail ("pool != ((void*)0)"
, "src/switch_xml.c", 2368, __PRETTY_FUNCTION__))
;
2369
2370 if ((xml = switch_xml_open_root(FALSE0, err))) {
2371 switch_xml_free(xml);
2372 return SWITCH_STATUS_SUCCESS;
2373 } else {
2374 return SWITCH_STATUS_FALSE;
2375 }
2376}
2377
2378SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_xml_destroy(void)
2379{
2380 switch_status_t status = SWITCH_STATUS_FALSE;
2381
2382
2383 switch_mutex_lock(XML_LOCK);
2384 switch_mutex_lock(REFLOCK);
2385
2386 if (MAIN_XML_ROOT) {
2387 switch_xml_t xml = MAIN_XML_ROOT;
2388 MAIN_XML_ROOT = NULL((void*)0);
2389 switch_xml_free(xml);
2390 status = SWITCH_STATUS_SUCCESS;
2391 }
2392
2393 switch_mutex_unlock(XML_LOCK);
2394 switch_mutex_unlock(REFLOCK);
2395
2396 switch_xml_clear_user_cache(NULL((void*)0), NULL((void*)0), NULL((void*)0));
2397
2398 switch_core_hash_destroy(&CACHE_HASH);
2399
2400 return status;
2401}
2402
2403SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_open_cfg(const char *file_path, switch_xml_t *node, switch_event_t *params)
2404{
2405 switch_xml_t xml = NULL((void*)0), cfg = NULL((void*)0);
2406
2407 *node = NULL((void*)0);
2408
2409 assert(MAIN_XML_ROOT != NULL)((MAIN_XML_ROOT != ((void*)0)) ? (void) (0) : __assert_fail (
"MAIN_XML_ROOT != ((void*)0)", "src/switch_xml.c", 2409, __PRETTY_FUNCTION__
))
;
2410
2411 if (switch_xml_locate("configuration", "configuration", "name", file_path, &xml, &cfg, params, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
2412 *node = cfg;
2413 }
2414
2415 return xml;
2416
2417}
2418
2419/* Encodes ampersand sequences appending the results to *dst, reallocating *dst
2420 if length exceeds max. a is non-zero for attribute encoding. Returns *dst */
2421static char *switch_xml_ampencode(const char *s, switch_size_t len, char **dst, switch_size_t *dlen, switch_size_t *max, short a)
2422{
2423 const char *e = NULL((void*)0);
2424 int immune = 0;
2425 int expecting_x_utf_8_char = 0;
2426 int unicode_char = 0x000000;
2427
2428 if (!(s && *s))
2429 return *dst;
2430
2431 if (len) {
2432 e = s + len;
2433 }
2434
2435 while (s != e) {
2436 while (*dlen + 10 > *max) {
2437 char *tmp = (char *) realloc(*dst, *max += SWITCH_XML_BUFSIZE1024);
2438 if (!tmp)
2439 return *dst;
2440 *dst = tmp;
2441 }
2442
2443 if (immune) {
2444 if (*s == '\0') {
2445 return *dst;
2446 }
2447 (*dst)[(*dlen)++] = *s;
2448 } else
2449 switch (*s) {
2450 case '\0':
2451 return *dst;
2452 case '&':
2453 *dlen += sprintf(*dst + *dlen, "&amp;");
2454 break;
2455 case '<':
2456 if (*(s + 1) == '!') {
2457 (*dst)[(*dlen)++] = *s;
2458 immune++;
2459 break;
2460 }
2461 *dlen += sprintf(*dst + *dlen, "&lt;");
2462 break;
2463 case '>':
2464 *dlen += sprintf(*dst + *dlen, "&gt;");
2465 break;
2466 case '"':
2467 *dlen += sprintf(*dst + *dlen, (a) ? "&quot;" : "\"");
2468 break;
2469 case '\n':
2470 *dlen += sprintf(*dst + *dlen, (a) ? "&#xA;" : "\n");
2471 break;
2472 case '\t':
2473 *dlen += sprintf(*dst + *dlen, (a) ? "&#x9;" : "\t");
2474 break;
2475 case '\r':
2476 *dlen += sprintf(*dst + *dlen, "&#xD;");
2477 break;
2478 default:
2479 if (USE_UTF_8_ENCODING && expecting_x_utf_8_char == 0 && ((*s >> 8) & 0x01)) {
2480 int num = 1;
2481 for (;num<4;num++) {
2482 if (! ((*s >> (7-num)) & 0x01)) {
2483 break;
2484 }
2485 }
2486 switch (num) {
2487 case 2:
2488 unicode_char = *s & 0x1f;
2489 break;
2490 case 3:
2491 unicode_char = *s & 0x0f;
2492 break;
2493 case 4:
2494 unicode_char = *s & 0x07;
2495 break;
2496 default:
2497 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 2497, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid UTF-8 Initial charactere, skip it\n");
2498 /* ERROR HERE */
2499 break;
2500 }
2501 expecting_x_utf_8_char = num - 1;
2502
2503 } else if (USE_UTF_8_ENCODING && expecting_x_utf_8_char > 0) {
2504 if (((*s >> 6) & 0x03) == 0x2) {
2505
2506 unicode_char = unicode_char << 6;
2507 unicode_char = unicode_char | (*s & 0x3f);
2508 } else {
2509 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 2509, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid UTF-8 character to ampersand, skip it\n");
2510 expecting_x_utf_8_char = 0;
2511 break;
2512 }
2513 expecting_x_utf_8_char--;
2514 if (expecting_x_utf_8_char == 0) {
2515 *dlen += sprintf(*dst + *dlen, "&#x%X;", unicode_char);
2516 }
2517 } else {
2518 (*dst)[(*dlen)++] = *s;
2519 }
2520 }
2521 s++;
2522 }
2523 return *dst;
2524}
2525
2526#define XML_INDENT" " " "
2527/* Recursively converts each tag to xml appending it to *s. Reallocates *s if
2528 its length exceeds max. start is the location of the previous tag in the
2529 parent tag's character content. Returns *s. */
2530static char *switch_xml_toxml_r(switch_xml_t xml, char **s, switch_size_t *len, switch_size_t *max, switch_size_t start, char ***attr, uint32_t *count, int isroot)
2531{
2532 int i, j;
2533 char *txt;
2534 switch_size_t off;
2535 uint32_t lcount;
2536 uint32_t loops = 0;
2537
2538 tailrecurse:
2539 off = 0;
2540 lcount = 0;
2541 txt = "";
2542
2543 if (loops++) {
2544 isroot = 0;
2545 }
2546
2547 if (!isroot && xml->parent) {
2548 txt = (char *) xml->parent->txt;
2549 }
2550
2551 /* parent character content up to this tag */
2552 *s = switch_xml_ampencode(txt + start, xml->off - start, s, len, max, 0);
2553
2554 while (*len + strlen(xml->name) + 5 + (strlen(XML_INDENT" ") * (*count)) + 1 > *max) { /* reallocate s */
2555 char *tmp = *s;
2556 *s = (char *) realloc(*s, *max += SWITCH_XML_BUFSIZE1024);
2557 if (!*s)
2558 return tmp;
2559 }
2560
2561 if (*len && *(*s + (*len) - 1) == '>') {
2562 *len += sprintf(*s + *len, "\n"); /* indent */
2563 }
2564 for (lcount = 0; lcount < *count; lcount++) {
2565 *len += sprintf(*s + *len, "%s", XML_INDENT" "); /* indent */
2566 }
2567
2568 *len += sprintf(*s + *len, "<%s", xml->name); /* open tag */
2569 for (i = 0; xml->attr[i]; i += 2) { /* tag attributes */
2570 if (switch_xml_attr(xml, xml->attr[i]) != xml->attr[i + 1])
2571 continue;
2572 while (*len + strlen(xml->attr[i]) + 7 + (strlen(XML_INDENT" ") * (*count)) > *max) { /* reallocate s */
2573 char *tmp = (char *) realloc(*s, *max += SWITCH_XML_BUFSIZE1024);
2574 if (!tmp)
2575 return *s;
2576 *s = tmp;
2577 }
2578
2579 *len += sprintf(*s + *len, " %s=\"", xml->attr[i]);
2580 switch_xml_ampencode(xml->attr[i + 1], 0, s, len, max, 1);
2581 *len += sprintf(*s + *len, "\"");
2582 }
2583
2584 for (i = 0; attr[i] && strcmp(attr[i][0], xml->name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(attr[i][0]) && __builtin_constant_p (xml->name) &&
(__s1_len = __builtin_strlen (attr[i][0]), __s2_len = __builtin_strlen
(xml->name), (!((size_t)(const void *)((attr[i][0]) + 1) -
(size_t)(const void *)(attr[i][0]) == 1) || __s1_len >= 4
) && (!((size_t)(const void *)((xml->name) + 1) - (
size_t)(const void *)(xml->name) == 1) || __s2_len >= 4
)) ? __builtin_strcmp (attr[i][0], xml->name) : (__builtin_constant_p
(attr[i][0]) && ((size_t)(const void *)((attr[i][0])
+ 1) - (size_t)(const void *)(attr[i][0]) == 1) && (
__s1_len = __builtin_strlen (attr[i][0]), __s1_len < 4) ? (
__builtin_constant_p (xml->name) && ((size_t)(const
void *)((xml->name) + 1) - (size_t)(const void *)(xml->
name) == 1) ? __builtin_strcmp (attr[i][0], xml->name) : (
__extension__ ({ const unsigned char *__s2 = (const unsigned char
*) (const char *) (xml->name); int __result = (((const unsigned
char *) (const char *) (attr[i][0]))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (attr[i][0]))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (attr[i][0]))[2] - __s2[2]); if (__s1_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (attr[i][0]))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p (xml->name) && ((size_t
)(const void *)((xml->name) + 1) - (size_t)(const void *)(
xml->name) == 1) && (__s2_len = __builtin_strlen (
xml->name), __s2_len < 4) ? (__builtin_constant_p (attr
[i][0]) && ((size_t)(const void *)((attr[i][0]) + 1) -
(size_t)(const void *)(attr[i][0]) == 1) ? __builtin_strcmp (
attr[i][0], xml->name) : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (attr[i]
[0]); int __result = (((const unsigned char *) (const char *)
(xml->name))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (xml->name))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (xml->name))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (xml->name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(attr[i][0], xml->name)))); })
; i++);
2585 for (j = 1; attr[i] && attr[i][j]; j += 3) { /* default attributes */
2586 if (!attr[i][j + 1] || switch_xml_attr(xml, attr[i][j]) != attr[i][j + 1])
2587 continue; /* skip duplicates and non-values */
2588 while (*len + strlen(attr[i][j]) + 8 + (strlen(XML_INDENT" ") * (*count)) > *max) { /* reallocate s */
2589 char *tmp = (char *) realloc(*s, *max += SWITCH_XML_BUFSIZE1024);
2590 if (!tmp)
2591 return *s;
2592 *s = tmp;
2593 }
2594
2595 *len += sprintf(*s + *len, " %s=\"", attr[i][j]);
2596 switch_xml_ampencode(attr[i][j + 1], 0, s, len, max, 1);
2597 *len += sprintf(*s + *len, "\"");
2598 }
2599
2600 *len += sprintf(*s + *len, (xml->child || xml->txt) ? ">" : "/>\n");
2601
2602 if (xml->child) {
2603 (*count)++;
2604 *s = switch_xml_toxml_r(xml->child, s, len, max, 0, attr, count, 0);
2605
2606 } else {
2607 *s = switch_xml_ampencode(xml->txt, 0, s, len, max, 0); /* data */
2608 }
2609
2610 while (*len + strlen(xml->name) + 5 + (strlen(XML_INDENT" ") * (*count)) > *max) { /* reallocate s */
2611 char *tmp = *s;
2612 *s = (char *) realloc(*s, *max += SWITCH_XML_BUFSIZE1024);
2613 if (!*s)
2614 return tmp;
2615 }
2616
2617 if (xml->child || xml->txt) {
2618 if (*(*s + (*len) - 1) == '\n') {
2619 for (lcount = 0; lcount < *count; lcount++) {
2620 *len += sprintf(*s + *len, "%s", XML_INDENT" "); /* indent */
2621 }
2622 }
2623 *len += sprintf(*s + (*len), "</%s>\n", xml->name); /* close tag */
2624 }
2625
2626 while (txt[off] && off < xml->off)
2627 off++; /* make sure off is within bounds */
2628
2629 if (!isroot && xml->ordered) {
2630 xml = xml->ordered;
2631 start = off;
2632 goto tailrecurse;
2633/*
2634 return switch_xml_toxml_r(xml->ordered, s, len, max, off, attr, count);
2635*/
2636 } else {
2637 if (*count > 0)
2638 (*count)--;
2639 return switch_xml_ampencode(txt + off, 0, s, len, max, 0);
2640 }
2641}
2642
2643SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_xml_toxml_nolock(switch_xml_t xml, switch_bool_t prn_header)
2644{
2645 char *s = (char *) malloc(SWITCH_XML_BUFSIZE1024);
2646 switch_assert(s)((s) ? (void) (0) : __assert_fail ("s", "src/switch_xml.c", 2646
, __PRETTY_FUNCTION__))
;
2647 return switch_xml_toxml_buf(xml, s, SWITCH_XML_BUFSIZE1024, 0, prn_header);
2648}
2649
2650
2651SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_xml_toxml(switch_xml_t xml, switch_bool_t prn_header)
2652{
2653 char *r, *s;
2654
2655 s = (char *) malloc(SWITCH_XML_BUFSIZE1024);
2656 switch_assert(s)((s) ? (void) (0) : __assert_fail ("s", "src/switch_xml.c", 2656
, __PRETTY_FUNCTION__))
;
2657
2658 r = switch_xml_toxml_buf(xml, s, SWITCH_XML_BUFSIZE1024, 0, prn_header);
2659
2660 return r;
2661}
2662
2663SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_xml_tohtml(switch_xml_t xml, switch_bool_t prn_header)
2664{
2665 char *r, *s, *h;
2666 switch_size_t rlen = 0;
2667 switch_size_t len = SWITCH_XML_BUFSIZE1024;
2668 s = (char *) malloc(SWITCH_XML_BUFSIZE1024);
2669 switch_assert(s)((s) ? (void) (0) : __assert_fail ("s", "src/switch_xml.c", 2669
, __PRETTY_FUNCTION__))
;
2670 h = (char *) malloc(SWITCH_XML_BUFSIZE1024);
2671 switch_assert(h)((h) ? (void) (0) : __assert_fail ("h", "src/switch_xml.c", 2671
, __PRETTY_FUNCTION__))
;
2672 r = switch_xml_toxml_buf(xml, s, SWITCH_XML_BUFSIZE1024, 0, prn_header);
2673 h = switch_xml_ampencode(r, 0, &h, &rlen, &len, 1);
2674 switch_safe_free(r)if (r) {free(r);r=((void*)0);};
2675 return h;
2676}
2677
2678/* converts a switch_xml structure back to xml, returning a string of xml data that
2679 must be freed */
2680SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_xml_toxml_buf(switch_xml_t xml, char *buf, switch_size_t buflen, switch_size_t offset, switch_bool_t prn_header)
2681{
2682 switch_xml_t p = (xml) ? xml->parent : NULL((void*)0);
2683 switch_xml_root_t root = (switch_xml_root_t) xml;
2684 switch_size_t len = 0, max = buflen;
2685 char *s, *t, *n, *r;
2686 int i, j, k;
2687 uint32_t count = 0;
2688
2689 s = buf;
2690 assert(s != NULL)((s != ((void*)0)) ? (void) (0) : __assert_fail ("s != ((void*)0)"
, "src/switch_xml.c", 2690, __PRETTY_FUNCTION__))
;
2691 memset(s, 0, max);
2692 len += offset;
2693 if (prn_header) {
2694 len += sprintf(s + len, "<?xml version=\"1.0\"?>\n");
2695 }
2696
2697 if (!xml || !xml->name) {
2698 if (!(r = (char *) realloc(s, len + 1))) {
2699 abort();
2700 }
2701 return r;
2702 }
2703
2704 while (root->xml.parent) {
2705 root = (switch_xml_root_t) root->xml.parent; /* root tag */
2706 }
2707
2708 for (i = 0; !p && root->pi[i]; i++) { /* pre-root processing instructions */
2709 for (k = 2; root->pi[i][k - 1]; k++);
2710 for (j = 1; (n = root->pi[i][j]); j++) {
2711 if (root->pi[i][k][j - 1] == '>') {
2712 continue; /* not pre-root */
2713 }
2714 while (len + strlen(t = root->pi[i][0]) + strlen(n) + 7 > max) {
2715 if (!(r = (char *) realloc(s, max += SWITCH_XML_BUFSIZE1024))) {
2716 abort();
2717 }
2718 s = r;
2719 }
2720 len += sprintf(s + len, "<?%s%s%s?>", t, *n ? " " : "", n);
2721 }
2722 }
2723
2724 s = switch_xml_toxml_r(xml, &s, &len, &max, 0, root->attr, &count, 1);
2725
2726 for (i = 0; !p && root->pi[i]; i++) { /* post-root processing instructions */
2727 for (k = 2; root->pi[i][k - 1]; k++);
2728 for (j = 1; (n = root->pi[i][j]); j++) {
2729 if (root->pi[i][k][j - 1] == '<') {
2730 continue; /* not post-root */
2731 }
2732 while (len + strlen(t = root->pi[i][0]) + strlen(n) + 7 > max) {
2733 if (!(r = (char *) realloc(s, max += SWITCH_XML_BUFSIZE1024))) {
2734 abort();
2735 }
2736 s = r;
2737 }
2738 len += sprintf(s + len, "\n<?%s%s%s?>", t, *n ? " " : "", n);
2739 }
2740 }
2741
2742 if (!(r = (char *) realloc(s, len + 1))) {
2743 abort();
2744 }
2745
2746 return r;
2747}
2748
2749/* free the memory allocated for the switch_xml structure */
2750SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_xml_free(switch_xml_t xml)
2751{
2752 switch_xml_root_t root;
2753 int i, j;
2754 char **a, *s;
2755 switch_xml_t orig_xml;
2756 int refs = 0;
2757
2758 tailrecurse:
2759 root = (switch_xml_root_t) xml;
2760 if (!xml) {
2761 return;
2762 }
2763
2764 if (switch_test_flag(xml, SWITCH_XML_ROOT)((xml)->flags & SWITCH_XML_ROOT)) {
2765 switch_mutex_lock(REFLOCK);
2766
2767 if (xml->refs) {
2768 xml->refs--;
2769 refs = xml->refs;
2770 }
2771 switch_mutex_unlock(REFLOCK);
2772 }
2773
2774 if (refs) {
2775 return;
2776 }
2777
2778 if (xml->free_path) {
2779 if (unlink(xml->free_path) != 0) {
2780 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 2780, ((void*)0)
, SWITCH_LOG_WARNING, "Failed to delete file [%s]\n", xml->free_path);
2781 }
2782 switch_safe_free(xml->free_path)if (xml->free_path) {free(xml->free_path);xml->free_path
=((void*)0);}
;
2783 }
2784
2785 switch_xml_free(xml->child);
2786 /*switch_xml_free(xml->ordered); */
2787
2788 if (!xml->parent) { /* free root tag allocations */
2789#if (_MSC_VER >= 1400) // VC8+
2790 __analysis_assume(sizeof(root->ent) > 44); /* tail recursion confuses code analysis */
2791#endif
2792 for (i = 10; root->ent[i]; i += 2) /* 0 - 9 are default entities (<>&"') */
2793 if ((s = root->ent[i + 1]) < root->s || s > root->e)
2794 free(s);
2795 free(root->ent); /* free list of general entities */
2796
2797 for (i = 0; (a = root->attr[i]); i++) {
2798 for (j = 1; a[j++]; j += 2) /* free malloced attribute values */
2799 if (a[j] && (a[j] < root->s || a[j] > root->e))
2800 free(a[j]);
2801 free(a);
2802 }
2803 if (root->attr[0])
2804 free(root->attr); /* free default attribute list */
2805
2806 for (i = 0; root->pi[i]; i++) {
2807 for (j = 1; root->pi[i][j]; j++);
2808 free(root->pi[i][j + 1]);
2809 free(root->pi[i]);
2810 }
2811 if (root->pi[0])
2812 free(root->pi); /* free processing instructions */
2813
2814 if (root->dynamic == 1)
2815 free(root->m); /* malloced xml data */
2816 if (root->u)
2817 free(root->u); /* utf8 conversion */
2818 }
2819
2820 switch_xml_free_attr(xml->attr); /* tag attributes */
2821 if ((xml->flags & SWITCH_XML_TXTM))
2822 free(xml->txt); /* character content */
2823 if ((xml->flags & SWITCH_XML_NAMEM))
2824 free(xml->name); /* tag name */
2825 if (xml->ordered) {
2826 orig_xml = xml;
2827 xml = xml->ordered;
2828 free(orig_xml);
2829 goto tailrecurse;
2830 }
2831 free(xml);
2832}
2833
2834/* return parser error message or empty string if none */
2835SWITCH_DECLARE(const char *)__attribute__((visibility("default"))) const char * switch_xml_error(switch_xml_t xml)
2836{
2837 while (xml && xml->parent)
2838 xml = xml->parent; /* find root tag */
2839 return (xml) ? ((switch_xml_root_t) xml)->err : "";
2840}
2841
2842/* returns a new empty switch_xml structure with the given root tag name */
2843SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_new(const char *name)
2844{
2845 static const char *ent[] = { "lt;", "&#60;", "gt;", "&#62;", "quot;", "&#34;",
2846 "apos;", "&#39;", "amp;", "&#38;", NULL((void*)0)
2847 };
2848 switch_xml_root_t root = (switch_xml_root_t) malloc(sizeof(struct switch_xml_root));
2849 if (!root)
2850 return NULL((void*)0);
2851 memset(root, '\0', sizeof(struct switch_xml_root));
2852 root->xml.name = (char *) name;
2853 root->cur = &root->xml;
2854 strcpy(root->err, root->xml.txt = (char *) "");
2855 root->ent = (char **) memcpy(malloc(sizeof(ent)), ent, sizeof(ent));
2856 root->attr = root->pi = (char ***) (root->xml.attr = SWITCH_XML_NIL);
2857 return &root->xml;
2858}
2859
2860/* inserts an existing tag into a switch_xml structure */
2861SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_insert(switch_xml_t xml, switch_xml_t dest, switch_size_t off)
2862{
2863 switch_xml_t cur, prev, head;
2864
2865 xml->next = xml->sibling = xml->ordered = NULL((void*)0);
2866 xml->off = off;
2867 xml->parent = dest;
2868
2869 if ((head = dest->child)) { /* already have sub tags */
2870 if (head->off <= off) { /* not first subtag */
2871 for (cur = head; cur->ordered && cur->ordered->off <= off; cur = cur->ordered);
2872 xml->ordered = cur->ordered;
2873 cur->ordered = xml;
2874 } else { /* first subtag */
2875 xml->ordered = head;
2876 dest->child = xml;
2877 }
2878
2879 for (cur = head, prev = NULL((void*)0); cur && strcmp(cur->name, xml->name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(cur->name) && __builtin_constant_p (xml->name
) && (__s1_len = __builtin_strlen (cur->name), __s2_len
= __builtin_strlen (xml->name), (!((size_t)(const void *)
((cur->name) + 1) - (size_t)(const void *)(cur->name) ==
1) || __s1_len >= 4) && (!((size_t)(const void *)
((xml->name) + 1) - (size_t)(const void *)(xml->name) ==
1) || __s2_len >= 4)) ? __builtin_strcmp (cur->name, xml
->name) : (__builtin_constant_p (cur->name) && (
(size_t)(const void *)((cur->name) + 1) - (size_t)(const void
*)(cur->name) == 1) && (__s1_len = __builtin_strlen
(cur->name), __s1_len < 4) ? (__builtin_constant_p (xml
->name) && ((size_t)(const void *)((xml->name) +
1) - (size_t)(const void *)(xml->name) == 1) ? __builtin_strcmp
(cur->name, xml->name) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (xml->
name); int __result = (((const unsigned char *) (const char *
) (cur->name))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (cur->name))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (cur->name))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (cur->name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(xml->name) && ((size_t)(const void *)((xml->name
) + 1) - (size_t)(const void *)(xml->name) == 1) &&
(__s2_len = __builtin_strlen (xml->name), __s2_len < 4
) ? (__builtin_constant_p (cur->name) && ((size_t)
(const void *)((cur->name) + 1) - (size_t)(const void *)(cur
->name) == 1) ? __builtin_strcmp (cur->name, xml->name
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (cur->name); int __result = (((const
unsigned char *) (const char *) (xml->name))[0] - __s2[0]
); if (__s2_len > 0 && __result == 0) { __result =
(((const unsigned char *) (const char *) (xml->name))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (xml->name))[2
] - __s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (xml->name))[3
] - __s2[3]); } } __result; })))) : __builtin_strcmp (cur->
name, xml->name)))); })
; prev = cur, cur = cur->sibling); /* find tag type */
2880 if (cur && cur->off <= off) { /* not first of type */
2881 while (cur->next && cur->next->off <= off)
2882 cur = cur->next;
2883 xml->next = cur->next;
2884 cur->next = xml;
2885 } else { /* first tag of this type */
2886 if (prev && cur)
2887 prev->sibling = cur->sibling; /* remove old first */
2888 xml->next = cur; /* old first tag is now next */
2889 for (cur = head, prev = NULL((void*)0); cur && cur->off <= off; prev = cur, cur = cur->sibling); /* new sibling insert point */
2890 xml->sibling = cur;
2891 if (prev)
2892 prev->sibling = xml;
2893 }
2894 } else
2895 dest->child = xml; /* only sub tag */
2896
2897 return xml;
2898}
2899
2900/* Adds a child tag. off is the offset of the child tag relative to the start
2901 of the parent tag's character content. Returns the child tag */
2902SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_add_child(switch_xml_t xml, const char *name, switch_size_t off)
2903{
2904 switch_xml_t child;
2905
2906 if (!xml)
2907 return NULL((void*)0);
2908 if (!(child = (switch_xml_t) malloc(sizeof(struct switch_xml))))
2909 return NULL((void*)0);
2910 memset(child, '\0', sizeof(struct switch_xml));
2911 child->name = (char *) name;
2912 child->attr = SWITCH_XML_NIL;
2913 child->off = off;
2914 child->parent = xml;
2915 child->txt = (char *) "";
2916
2917 return switch_xml_insert(child, xml, off);
2918}
2919
2920/* sets the character content for the given tag and returns the tag */
2921SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_set_txt(switch_xml_t xml, const char *txt)
2922{
2923 if (!xml)
2924 return NULL((void*)0);
2925 if (xml->flags & SWITCH_XML_TXTM)
2926 free(xml->txt); /* existing txt was malloced */
2927 xml->flags &= ~SWITCH_XML_TXTM;
2928 xml->txt = (char *) txt;
2929 return xml;
2930}
2931
2932/* Sets the given tag attribute or adds a new attribute if not found. A value
2933 of NULL will remove the specified attribute. Returns the tag given */
2934SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_set_attr(switch_xml_t xml, const char *name, const char *value)
2935{
2936 int l = 0, c;
2937
2938 if (!xml)
2939 return NULL((void*)0);
2940 while (xml->attr[l] && strcmp(xml->attr[l], name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(xml->attr[l]) && __builtin_constant_p (name) &&
(__s1_len = __builtin_strlen (xml->attr[l]), __s2_len = __builtin_strlen
(name), (!((size_t)(const void *)((xml->attr[l]) + 1) - (
size_t)(const void *)(xml->attr[l]) == 1) || __s1_len >=
4) && (!((size_t)(const void *)((name) + 1) - (size_t
)(const void *)(name) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(xml->attr[l], name) : (__builtin_constant_p (xml->attr
[l]) && ((size_t)(const void *)((xml->attr[l]) + 1
) - (size_t)(const void *)(xml->attr[l]) == 1) && (
__s1_len = __builtin_strlen (xml->attr[l]), __s1_len < 4
) ? (__builtin_constant_p (name) && ((size_t)(const void
*)((name) + 1) - (size_t)(const void *)(name) == 1) ? __builtin_strcmp
(xml->attr[l], name) : (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (name); int __result
= (((const unsigned char *) (const char *) (xml->attr[l])
)[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (xml->
attr[l]))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
xml->attr[l]))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (xml->attr[l]))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(name) && ((size_t)(const void *)((name) + 1) - (size_t
)(const void *)(name) == 1) && (__s2_len = __builtin_strlen
(name), __s2_len < 4) ? (__builtin_constant_p (xml->attr
[l]) && ((size_t)(const void *)((xml->attr[l]) + 1
) - (size_t)(const void *)(xml->attr[l]) == 1) ? __builtin_strcmp
(xml->attr[l], name) : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (xml->
attr[l]); int __result = (((const unsigned char *) (const char
*) (name))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
name))[1] - __s2[1]); if (__s2_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
name))[2] - __s2[2]); if (__s2_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (name
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (xml
->attr[l], name)))); })
)
2941 l += 2;
2942 if (!xml->attr[l]) { /* not found, add as new attribute */
2943 if (!value)
2944 return xml; /* nothing to do */
2945 if (xml->attr == SWITCH_XML_NIL) { /* first attribute */
2946 xml->attr = (char **) malloc(4 * sizeof(char *));
2947 if (!xml->attr)
2948 return NULL((void*)0);
2949 xml->attr[1] = strdup("")(__extension__ (__builtin_constant_p ("") && ((size_t
)(const void *)(("") + 1) - (size_t)(const void *)("") == 1) ?
(((const char *) (""))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen ("") + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "", __len); __retval; })) : __strdup
("")))
; /* empty list of malloced names/vals */
2950 } else {
2951 char **tmp = (char **) realloc(xml->attr, (l + 4) * sizeof(char *));
2952 if (!tmp)
2953 return xml;
2954 xml->attr = tmp;
2955 }
2956
2957 xml->attr[l] = (char *) name; /* set attribute name */
2958 xml->attr[l + 2] = NULL((void*)0); /* null terminate attribute list */
2959 xml->attr[l + 3] = (char *) realloc(xml->attr[l + 1], (c = (int) strlen(xml->attr[l + 1])) + 2);
2960 strcpy(xml->attr[l + 3] + c, " "); /* set name/value as not malloced */
2961 if (xml->flags & SWITCH_XML_DUP)
2962 xml->attr[l + 3][c] = SWITCH_XML_NAMEM;
2963 } else if (xml->flags & SWITCH_XML_DUP)
2964 free((char *) name); /* name was strduped */
2965
2966 for (c = l; xml->attr[c]; c += 2); /* find end of attribute list */
2967 if (xml->attr[c + 1][l / 2] & SWITCH_XML_TXTM)
2968 free(xml->attr[l + 1]); /* old val */
2969 if (xml->flags & SWITCH_XML_DUP)
2970 xml->attr[c + 1][l / 2] |= SWITCH_XML_TXTM;
2971 else
2972 xml->attr[c + 1][l / 2] &= ~SWITCH_XML_TXTM;
2973
2974 if (value)
2975 xml->attr[l + 1] = (char *) value; /* set attribute value */
2976 else { /* remove attribute */
2977 char **tmp;
2978 if (xml->attr[c + 1][l / 2] & SWITCH_XML_NAMEM)
2979 free(xml->attr[l]);
2980 memmove(xml->attr + l, xml->attr + l + 2, (c - l + 2) * sizeof(char *));
2981 tmp = (char **) realloc(xml->attr, (c + 2) * sizeof(char *));
2982 if (!tmp)
2983 return xml;
2984 xml->attr = tmp;
2985 memmove(xml->attr[c + 1] + (l / 2), xml->attr[c + 1] + (l / 2) + 1, (c / 2) - (l / 2)); /* fix list of which name/vals are malloced */
2986 }
2987 xml->flags &= ~SWITCH_XML_DUP; /* clear strdup() flag */
2988
2989 return xml;
2990}
2991
2992/* sets a flag for the given tag and returns the tag */
2993SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_set_flag(switch_xml_t xml, switch_xml_flag_t flag)
2994{
2995 if (xml)
2996 xml->flags |= flag;
2997 return xml;
2998}
2999
3000/* removes a tag along with its subtags without freeing its memory */
3001SWITCH_DECLARE(switch_xml_t)__attribute__((visibility("default"))) switch_xml_t switch_xml_cut(switch_xml_t xml)
3002{
3003 switch_xml_t cur;
3004
3005 if (!xml)
3006 return NULL((void*)0); /* nothing to do */
3007 if (xml->next)
3008 xml->next->sibling = xml->sibling; /* patch sibling list */
3009
3010 if (xml->parent) { /* not root tag */
3011 cur = xml->parent->child; /* find head of subtag list */
3012 if (cur == xml)
3013 xml->parent->child = xml->ordered; /* first subtag */
3014 else { /* not first subtag */
3015 while (cur->ordered != xml)
3016 cur = cur->ordered;
3017 cur->ordered = cur->ordered->ordered; /* patch ordered list */
3018
3019 cur = xml->parent->child; /* go back to head of subtag list */
3020 if (strcmp(cur->name, xml->name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(cur->name) && __builtin_constant_p (xml->name
) && (__s1_len = __builtin_strlen (cur->name), __s2_len
= __builtin_strlen (xml->name), (!((size_t)(const void *)
((cur->name) + 1) - (size_t)(const void *)(cur->name) ==
1) || __s1_len >= 4) && (!((size_t)(const void *)
((xml->name) + 1) - (size_t)(const void *)(xml->name) ==
1) || __s2_len >= 4)) ? __builtin_strcmp (cur->name, xml
->name) : (__builtin_constant_p (cur->name) && (
(size_t)(const void *)((cur->name) + 1) - (size_t)(const void
*)(cur->name) == 1) && (__s1_len = __builtin_strlen
(cur->name), __s1_len < 4) ? (__builtin_constant_p (xml
->name) && ((size_t)(const void *)((xml->name) +
1) - (size_t)(const void *)(xml->name) == 1) ? __builtin_strcmp
(cur->name, xml->name) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (xml->
name); int __result = (((const unsigned char *) (const char *
) (cur->name))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (cur->name))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (cur->name))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (cur->name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(xml->name) && ((size_t)(const void *)((xml->name
) + 1) - (size_t)(const void *)(xml->name) == 1) &&
(__s2_len = __builtin_strlen (xml->name), __s2_len < 4
) ? (__builtin_constant_p (cur->name) && ((size_t)
(const void *)((cur->name) + 1) - (size_t)(const void *)(cur
->name) == 1) ? __builtin_strcmp (cur->name, xml->name
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (cur->name); int __result = (((const
unsigned char *) (const char *) (xml->name))[0] - __s2[0]
); if (__s2_len > 0 && __result == 0) { __result =
(((const unsigned char *) (const char *) (xml->name))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (xml->name))[2
] - __s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (xml->name))[3
] - __s2[3]); } } __result; })))) : __builtin_strcmp (cur->
name, xml->name)))); })
) { /* not in first sibling list */
3021 while (strcmp(cur->sibling->name, xml->name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(cur->sibling->name) && __builtin_constant_p (
xml->name) && (__s1_len = __builtin_strlen (cur->
sibling->name), __s2_len = __builtin_strlen (xml->name)
, (!((size_t)(const void *)((cur->sibling->name) + 1) -
(size_t)(const void *)(cur->sibling->name) == 1) || __s1_len
>= 4) && (!((size_t)(const void *)((xml->name)
+ 1) - (size_t)(const void *)(xml->name) == 1) || __s2_len
>= 4)) ? __builtin_strcmp (cur->sibling->name, xml->
name) : (__builtin_constant_p (cur->sibling->name) &&
((size_t)(const void *)((cur->sibling->name) + 1) - (size_t
)(const void *)(cur->sibling->name) == 1) && (__s1_len
= __builtin_strlen (cur->sibling->name), __s1_len <
4) ? (__builtin_constant_p (xml->name) && ((size_t
)(const void *)((xml->name) + 1) - (size_t)(const void *)(
xml->name) == 1) ? __builtin_strcmp (cur->sibling->name
, xml->name) : (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) (xml->name); int
__result = (((const unsigned char *) (const char *) (cur->
sibling->name))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (cur->sibling->name))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (cur->sibling->name))[2] - __s2
[2]); if (__s1_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (cur->sibling->
name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(xml->name) && ((size_t)(const void *)((xml->name
) + 1) - (size_t)(const void *)(xml->name) == 1) &&
(__s2_len = __builtin_strlen (xml->name), __s2_len < 4
) ? (__builtin_constant_p (cur->sibling->name) &&
((size_t)(const void *)((cur->sibling->name) + 1) - (size_t
)(const void *)(cur->sibling->name) == 1) ? __builtin_strcmp
(cur->sibling->name, xml->name) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (cur->sibling->name); int __result = (((const unsigned
char *) (const char *) (xml->name))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (xml->name))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (xml->name))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (xml->name))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (cur->sibling->name, xml->
name)))); })
)
3022 cur = cur->sibling;
3023 if (cur->sibling == xml) { /* first of a sibling list */
3024 cur->sibling = (xml->next) ? xml->next : cur->sibling->sibling;
3025 } else
3026 cur = cur->sibling; /* not first of a sibling list */
3027 }
3028
3029 while (cur->next && cur->next != xml)
3030 cur = cur->next;
3031 if (cur->next)
3032 cur->next = cur->next->next; /* patch next list */
3033 }
3034 }
3035 xml->ordered = xml->sibling = xml->next = NULL((void*)0); /* prevent switch_xml_free() from clobbering ordered list */
3036 return xml;
3037}
3038
3039SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_xml_std_datetime_check(switch_xml_t xcond, int *offset, const char *tzname)
3040{
3041
3042 const char *xdt = switch_xml_attr(xcond, "date-time");
3043 const char *xyear = switch_xml_attr(xcond, "year");
3044 const char *xyday = switch_xml_attr(xcond, "yday");
3045 const char *xmon = switch_xml_attr(xcond, "mon");
3046 const char *xmday = switch_xml_attr(xcond, "mday");
3047 const char *xweek = switch_xml_attr(xcond, "week");
3048 const char *xmweek = switch_xml_attr(xcond, "mweek");
3049 const char *xwday = switch_xml_attr(xcond, "wday");
3050 const char *xhour = switch_xml_attr(xcond, "hour");
3051 const char *xminute = switch_xml_attr(xcond, "minute");
3052 const char *xminday = switch_xml_attr(xcond, "minute-of-day");
3053 const char *xtod = switch_xml_attr(xcond, "time-of-day");
3054 const char *tzoff = switch_xml_attr(xcond, "tz-offset");
3055 const char *isdst = switch_xml_attr(xcond, "dst");
3056
3057 int loffset = -1000;
3058 int eoffset = -1000;
3059 int dst = -1000;
3060 switch_time_t ts = switch_micro_time_now();
3061 int time_match = -1;
3062 switch_time_exp_t tm, tm2;
3063
3064 if (!zstr(isdst)_zstr(isdst)) {
3065 dst = switch_true(isdst);
3066 }
3067
3068 if (!zstr(tzoff)_zstr(tzoff) && switch_is_number(tzoff)) {
3069 loffset = atoi(tzoff);
3070 }
3071
3072 switch_time_exp_lt(&tm2, ts);
3073
3074 if (offset) {
3075 eoffset = *offset;
3076 switch_time_exp_tz(&tm, ts, *offset * 3600);
3077 } else if (!zstr(tzname)_zstr(tzname)) {
3078 switch_time_exp_tz_name(tzname, &tm, ts);
3079 } else {
3080 tm = tm2;
3081 }
3082
3083 if (eoffset == -1000) {
3084 eoffset = tm.tm_gmtoff / 3600;
3085 }
3086
3087 if (loffset == -1000) {
3088 loffset = eoffset;
3089 }
3090
3091
3092 if (time_match && tzoff) {
3093 time_match = loffset == eoffset;
3094 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3094, ((void*)0)
, SWITCH_LOG_DEBUG9,
3095 "XML DateTime Check: TZOFFSET[%d] == %d (%s)\n", eoffset, loffset, time_match ? "PASS" : "FAIL");
3096
3097 }
3098
3099 if (time_match && dst > -1) {
3100 time_match = (tm2.tm_isdst > 0 && dst > 0);
3101 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3101, ((void*)0)
, SWITCH_LOG_DEBUG9,
3102 "XML DateTime Check: DST[%s] == %s (%s)\n",
3103 tm2.tm_isdst > 0 ? "true" : "false", dst > 0 ? "true" : "false", time_match ? "PASS" : "FAIL");
3104
3105 }
3106
3107 if (time_match && xdt) {
3108 char tmpdate[80];
3109 switch_size_t retsize;
3110 switch_strftime(tmpdate, &retsize, sizeof(tmpdate), "%Y-%m-%d %H:%M:%S", &tm);
3111 time_match = switch_fulldate_cmp(xdt, &ts);
3112 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3112, ((void*)0)
, SWITCH_LOG_DEBUG,
3113 "XML DateTime Check: date time[%s] =~ %s (%s)\n", tmpdate, xdt, time_match ? "PASS" : "FAIL");
3114 }
3115
3116 if (time_match && xyear) {
3117 int test = tm.tm_year + 1900;
3118 time_match = switch_number_cmp(xyear, test);
3119 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3119, ((void*)0)
, SWITCH_LOG_DEBUG9,
3120 "XML DateTime Check: year[%d] =~ %s (%s)\n", test, xyear, time_match ? "PASS" : "FAIL");
3121 }
3122
3123 if (time_match && xyday) {
3124 int test = tm.tm_yday + 1;
3125 time_match = switch_number_cmp(xyday, test);
3126 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3126, ((void*)0)
, SWITCH_LOG_DEBUG9,
3127 "XML DateTime Check: day of year[%d] =~ %s (%s)\n", test, xyday, time_match ? "PASS" : "FAIL");
3128 }
3129
3130 if (time_match && xmon) {
3131 int test = tm.tm_mon + 1;
3132 time_match = switch_number_cmp(xmon, test);
3133 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3133, ((void*)0)
, SWITCH_LOG_DEBUG9,
3134 "XML DateTime Check: month[%d] =~ %s (%s)\n", test, xmon, time_match ? "PASS" : "FAIL");
3135 }
3136
3137 if (time_match && xmday) {
3138 int test = tm.tm_mday;
3139 time_match = switch_number_cmp(xmday, test);
3140 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3140, ((void*)0)
, SWITCH_LOG_DEBUG9,
3141 "XML DateTime Check: day of month[%d] =~ %s (%s)\n", test, xmday, time_match ? "PASS" : "FAIL");
3142 }
3143
3144 if (time_match && xweek) {
3145 int test = (int) (tm.tm_yday / 7 + 1);
3146 time_match = switch_number_cmp(xweek, test);
3147 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3147, ((void*)0)
, SWITCH_LOG_DEBUG9,
3148 "XML DateTime Check: week of year[%d] =~ %s (%s)\n", test, xweek, time_match ? "PASS" : "FAIL");
3149 }
3150 if (time_match && xweek) {
3151 int test = (int) (tm.tm_yday / 7 + 1);
3152 time_match = switch_number_cmp(xweek, test);
3153 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3153, ((void*)0)
, SWITCH_LOG_DEBUG9,
3154 "XML DateTime Check: week of year[%d] =~ %s (%s)\n", test, xweek, time_match ? "PASS" : "FAIL");
3155 }
3156
3157 if (time_match && xmweek) {
3158 /* calculate the day of the week of the first of the month (0-6) */
3159 int firstdow = (int) (7 - (tm.tm_mday - (tm.tm_wday + 1)) % 7) % 7;
3160 /* calculate the week of the month (1-6)*/
3161 int test = (int) ceil((tm.tm_mday + firstdow) / 7.0);
3162 time_match = switch_number_cmp(xmweek, test);
3163 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3163, ((void*)0)
, SWITCH_LOG_DEBUG9,
3164 "XML DateTime: week of month[%d] =~ %s (%s)\n", test, xmweek, time_match ? "PASS" : "FAIL");
3165 }
3166
3167 if (time_match && xwday) {
3168 int test = tm.tm_wday + 1;
3169 time_match = switch_dow_cmp(xwday, test);
3170 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3170, ((void*)0)
, SWITCH_LOG_DEBUG9,
3171 "XML DateTime Check: day of week[%s] =~ %s (%s)\n", switch_dow_int2str(test), xwday, time_match ? "PASS" : "FAIL");
3172 }
3173 if (time_match && xhour) {
3174 int test = tm.tm_hour;
3175 time_match = switch_number_cmp(xhour, test);
3176 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3176, ((void*)0)
, SWITCH_LOG_DEBUG9,
3177 "XML DateTime Check: hour[%d] =~ %s (%s)\n", test, xhour, time_match ? "PASS" : "FAIL");
3178 }
3179
3180 if (time_match && xminute) {
3181 int test = tm.tm_min;
3182 time_match = switch_number_cmp(xminute, test);
3183 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3183, ((void*)0)
, SWITCH_LOG_DEBUG9,
3184 "XML DateTime Check: minute[%d] =~ %s (%s)\n", test, xminute, time_match ? "PASS" : "FAIL");
3185 }
3186
3187 if (time_match && xminday) {
3188 int test = (tm.tm_hour * 60) + (tm.tm_min + 1);
3189 time_match = switch_number_cmp(xminday, test);
3190 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3190, ((void*)0)
, SWITCH_LOG_DEBUG9,
3191 "XML DateTime Check: minute of day[%d] =~ %s (%s)\n", test, xminday, time_match ? "PASS" : "FAIL");
3192 }
3193
3194 if (time_match && xtod) {
3195 int test = (tm.tm_hour * 60 * 60) + (tm.tm_min * 60) + tm.tm_sec;
3196 char tmpdate[10];
3197 switch_snprintf(tmpdate, 10, "%d:%d:%d", tm.tm_hour, tm.tm_min, tm.tm_sec);
3198 time_match = switch_tod_cmp(xtod, test);
3199 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3199, ((void*)0)
, SWITCH_LOG_DEBUG9,
3200 "XML DateTime Check: time of day[%s] =~ %s (%s)\n", tmpdate, xtod, time_match ? "PASS" : "FAIL");
3201 }
3202
3203 return time_match;
3204}
3205
3206SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_xml_locate_language(switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_xml_t *language, switch_xml_t *phrases, switch_xml_t *macros, const char *str_language) {
3207 switch_status_t status = SWITCH_STATUS_FALSE;
3208
3209 if (switch_xml_locate("languages", NULL((void*)0), NULL((void*)0), NULL((void*)0), root, node, params, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
3210 switch_xml_t sub_macros;
3211
3212 if (switch_xml_locate("phrases", NULL((void*)0), NULL((void*)0), NULL((void*)0), root, node, params, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
3213 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3213, ((void*)0)
, SWITCH_LOG_ERROR, "Open of languages and phrases failed.\n");
3214 goto done;
3215 }
3216 if (!(sub_macros = switch_xml_child(*node, "macros"))) {
3217 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3217, ((void*)0)
, SWITCH_LOG_ERROR, "Can't find macros tag.\n");
3218 switch_xml_free(*root);
3219 *root = NULL((void*)0);
3220 *node = NULL((void*)0);
3221 goto done;
3222 }
3223 if (!(*language = switch_xml_find_child(sub_macros, "language", "name", str_language))) {
3224 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3224, ((void*)0)
, SWITCH_LOG_ERROR, "Can't find language %s.\n", str_language);
3225 switch_xml_free(*root);
3226 *root = NULL((void*)0);
3227 *node = NULL((void*)0);
3228 goto done;
3229 }
3230 *macros = *language;
3231 } else {
3232 if (!(*language = switch_xml_find_child(*node, "language", "name", str_language))) {
3233 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3233, ((void*)0)
, SWITCH_LOG_ERROR, "Can't find language %s.\n", str_language);
3234 switch_xml_free(*root);
3235 *root = NULL((void*)0);
3236 goto done;
3237 }
3238 if (!(*phrases = switch_xml_child(*language, "phrases"))) {
3239 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3239, ((void*)0)
, SWITCH_LOG_ERROR, "Can't find phrases tag.\n");
3240 switch_xml_free(*root);
3241 *root = NULL((void*)0);
3242 *node = NULL((void*)0);
3243 *language = NULL((void*)0);
3244 goto done;
3245 }
3246
3247 if (!(*macros = switch_xml_child(*phrases, "macros"))) {
3248 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_xml.c", (const char *)__func__
, 3248, ((void*)0)
, SWITCH_LOG_ERROR, "Can't find macros tag.\n");
3249 switch_xml_free(*root);
3250 *root = NULL((void*)0);
3251 *node = NULL((void*)0);
3252 *language = NULL((void*)0);
3253 *phrases = NULL((void*)0);
3254 goto done;
3255 }
3256 }
3257 status = SWITCH_STATUS_SUCCESS;
3258
3259done:
3260 return status;
3261}
3262
3263#ifdef WIN32
3264/*
3265 * globbing functions for windows, part of libc on unix, this code was cut and paste from
3266 * freebsd lib and distilled a bit to work with windows
3267 */
3268
3269/*
3270 * Copyright (c) 1989, 1993
3271 * The Regents of the University of California. All rights reserved.
3272 *
3273 * This code is derived from software contributed to Berkeley by
3274 * Guido van Rossum.
3275 *
3276 * Redistribution and use in source and binary forms, with or without
3277 * modification, are permitted provided that the following conditions
3278 * are met:
3279 * 1. Redistributions of source code must retain the above copyright
3280 * notice, this list of conditions and the following disclaimer.
3281 * 2. Redistributions in binary form must reproduce the above copyright
3282 * notice, this list of conditions and the following disclaimer in the
3283 * documentation and/or other materials provided with the distribution.
3284 * 4. Neither the name of the University nor the names of its contributors
3285 * may be used to endorse or promote products derived from this software
3286 * without specific prior written permission.
3287 *
3288 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
3289 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3290 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3291 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3292 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3293 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3294 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3295 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3296 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3297 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3298 * SUCH DAMAGE.
3299 */
3300
3301#define DOLLAR '$'
3302#define DOT '.'
3303#define EOS '\0'
3304#define LBRACKET '['
3305#define NOT '!'
3306#define QUESTION '?'
3307#define RANGE '-'
3308#define RBRACKET ']'
3309#define SEP '/'
3310#define WIN_SEP '/'
3311#define STAR '*'
3312#define TILDE '~'
3313#define UNDERSCORE '_'
3314#define LBRACE '{'
3315#define RBRACE '}'
3316#define SLASH '/'
3317#define COMMA ','
3318
3319#define M_QUOTE (char)0x80
3320#define M_PROTECT (char)0x40
3321#define M_MASK (char)0xff
3322#define M_ASCII (char)0x7f
3323
3324#define CHAR(c) ((char)((c)&M_ASCII))
3325#define META(c) ((char)((c)|M_QUOTE))
3326#define M_ALL META('*')
3327#define M_END META(']')
3328#define M_NOT META('!')
3329#define M_ONE META('?')
3330#define M_RNG META('-')
3331#define M_SET META('[')
3332#define ismeta(c) (((c)&M_QUOTE) != 0)
3333
3334#ifndef MAXPATHLEN
3335#define MAXPATHLEN 256
3336#endif
3337
3338static int compare(const void *, const void *);
3339static int glob0(const char *, glob_t *, size_t *);
3340static int glob1(char *, glob_t *, size_t *);
3341static int glob2(char *, char *, char *, char *, glob_t *, size_t *);
3342static int glob3(char *, char *, char *, char *, char *, glob_t *, size_t *);
3343static int globextend(const char *, glob_t *, size_t *);
3344static int match(char *, char *, char *);
3345
3346#pragma warning(push)
3347#pragma warning(disable:4310)
3348
3349int glob(const char *pattern, int flags, int (*errfunc) (const char *, int), glob_t *pglob)
3350{
3351 const unsigned char *patnext;
3352 size_t limit;
3353 char c;
3354 char *bufnext, *bufend, patbuf[MAXPATHLEN];
3355
3356 patnext = (unsigned char *) pattern;
3357 if (!(flags & GLOB_APPEND(1 << 5))) {
3358 pglob->gl_pathc = 0;
3359 pglob->gl_pathv = NULL((void*)0);
3360 if (!(flags & GLOB_DOOFFS(1 << 3)))
3361 pglob->gl_offs = 0;
3362 }
3363 if (flags & GLOB_LIMIT) {
3364 limit = pglob->gl_matchc;
3365 if (limit == 0)
3366 limit = 9999999;
3367 } else
3368 limit = 0;
3369 pglob->gl_flags = flags & ~GLOB_MAGCHAR(1 << 8);
3370 pglob->gl_errfunc = errfunc;
3371 pglob->gl_matchc = 0;
3372
3373 bufnext = patbuf;
3374 bufend = bufnext + MAXPATHLEN - 1;
3375 while (bufnext < bufend && (c = *patnext++) != EOS)
3376 *bufnext++ = c;
3377 *bufnext = EOS;
3378
3379 return glob0(patbuf, pglob, &limit);
3380}
3381
3382/*
3383 * The main glob() routine: compiles the pattern (optionally processing
3384 * quotes), calls glob1() to do the real pattern matching, and finally
3385 * sorts the list (unless unsorted operation is requested). Returns 0
3386 * if things went well, nonzero if errors occurred.
3387 */
3388static int glob0(const char *pattern, glob_t *pglob, size_t *limit)
3389{
3390 const char *qpatnext;
3391 int c, err;
3392 size_t oldpathc;
3393 char *bufnext, patbuf[MAXPATHLEN];
3394
3395 qpatnext = pattern;
3396 oldpathc = pglob->gl_pathc;
3397 bufnext = patbuf;
3398
3399 /* We don't need to check for buffer overflow any more. */
3400 while ((c = *qpatnext++) != EOS) {
3401 switch (c) {
3402 case SEP:
3403 *bufnext++ = WIN_SEP;
3404 break;
3405 case LBRACKET:
3406 c = *qpatnext;
3407 if (c == NOT)
3408 ++qpatnext;
3409 if (*qpatnext == EOS || strchr((char *) qpatnext + 1, RBRACKET)(__extension__ (__builtin_constant_p (RBRACKET) && !__builtin_constant_p
((char *) qpatnext + 1) && (RBRACKET) == '\0' ? (char
*) __rawmemchr ((char *) qpatnext + 1, RBRACKET) : __builtin_strchr
((char *) qpatnext + 1, RBRACKET)))
== NULL((void*)0)) {
3410 *bufnext++ = LBRACKET;
3411 if (c == NOT)
3412 --qpatnext;
3413 break;
3414 }
3415 *bufnext++ = M_SET;
3416 if (c == NOT)
3417 *bufnext++ = M_NOT;
3418 c = *qpatnext++;
3419 do {
3420 *bufnext++ = CHAR(c);
3421 if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) {
3422 *bufnext++ = M_RNG;
3423 *bufnext++ = CHAR(c);
3424 qpatnext += 2;
3425 }
3426 } while ((c = *qpatnext++) != RBRACKET);
3427 pglob->gl_flags |= GLOB_MAGCHAR(1 << 8);
3428 *bufnext++ = M_END;
3429 break;
3430 case QUESTION:
3431 pglob->gl_flags |= GLOB_MAGCHAR(1 << 8);
3432 *bufnext++ = M_ONE;
3433 break;
3434 case STAR:
3435 pglob->gl_flags |= GLOB_MAGCHAR(1 << 8);
3436 /* collapse adjacent stars to one,
3437 * to avoid exponential behavior
3438 */
3439 if (bufnext == patbuf || bufnext[-1] != M_ALL)
3440 *bufnext++ = M_ALL;
3441 break;
3442 default:
3443 *bufnext++ = CHAR(c);
3444 break;
3445 }
3446 }
3447 *bufnext = EOS;
3448
3449 if ((err = glob1(patbuf, pglob, limit)) != 0)
3450 return (err);
3451
3452 /*
3453 * If there was no match we are going to append the pattern
3454 * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
3455 * and the pattern did not contain any magic characters
3456 * GLOB_NOMAGIC is there just for compatibility with csh.
3457 */
3458 if (pglob->gl_pathc == oldpathc) {
3459 if (((pglob->gl_flags & GLOB_NOCHECK(1 << 4)) || ((pglob->gl_flags & GLOB_NOMAGIC(1 << 11)) && !(pglob->gl_flags & GLOB_MAGCHAR(1 << 8)))))
3460 return (globextend(pattern, pglob, limit));
3461 else
3462 return (GLOB_NOMATCH3);
3463 }
3464 if (!(pglob->gl_flags & GLOB_NOSORT(1 << 2)))
3465 qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare);
3466 return (0);
3467}
3468
3469static int compare(const void *p, const void *q)
3470{
3471 return (strcmp(*(char **) p, *(char **) q)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(*(char **) p) && __builtin_constant_p (*(char **) q
) && (__s1_len = __builtin_strlen (*(char **) p), __s2_len
= __builtin_strlen (*(char **) q), (!((size_t)(const void *)
((*(char **) p) + 1) - (size_t)(const void *)(*(char **) p) ==
1) || __s1_len >= 4) && (!((size_t)(const void *)
((*(char **) q) + 1) - (size_t)(const void *)(*(char **) q) ==
1) || __s2_len >= 4)) ? __builtin_strcmp (*(char **) p, *
(char **) q) : (__builtin_constant_p (*(char **) p) &&
((size_t)(const void *)((*(char **) p) + 1) - (size_t)(const
void *)(*(char **) p) == 1) && (__s1_len = __builtin_strlen
(*(char **) p), __s1_len < 4) ? (__builtin_constant_p (*(
char **) q) && ((size_t)(const void *)((*(char **) q)
+ 1) - (size_t)(const void *)(*(char **) q) == 1) ? __builtin_strcmp
(*(char **) p, *(char **) q) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (*(char *
*) q); int __result = (((const unsigned char *) (const char *
) (*(char **) p))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (*(char **) p))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (*(char **) p))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (*(char **) p))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(*(char **) q) && ((size_t)(const void *)((*(char **
) q) + 1) - (size_t)(const void *)(*(char **) q) == 1) &&
(__s2_len = __builtin_strlen (*(char **) q), __s2_len < 4
) ? (__builtin_constant_p (*(char **) p) && ((size_t)
(const void *)((*(char **) p) + 1) - (size_t)(const void *)(*
(char **) p) == 1) ? __builtin_strcmp (*(char **) p, *(char *
*) q) : (- (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) (*(char **) p); int __result
= (((const unsigned char *) (const char *) (*(char **) q))[0
] - __s2[0]); if (__s2_len > 0 && __result == 0) {
__result = (((const unsigned char *) (const char *) (*(char *
*) q))[1] - __s2[1]); if (__s2_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
*(char **) q))[2] - __s2[2]); if (__s2_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (*
(char **) q))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(*(char **) p, *(char **) q)))); })
);
3472}
3473
3474static int glob1(char *pattern, glob_t *pglob, size_t *limit)
3475{
3476 char pathbuf[MAXPATHLEN];
3477
3478 /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
3479 if (*pattern == EOS)
3480 return (0);
3481 return (glob2(pathbuf, pathbuf, pathbuf + MAXPATHLEN - 1, pattern, pglob, limit));
3482}
3483
3484/*
3485 * The functions glob2 and glob3 are mutually recursive; there is one level
3486 * of recursion for each segment in the pattern that contains one or more
3487 * meta characters.
3488 */
3489static int glob2(char *pathbuf, char *pathend, char *pathend_last, char *pattern, glob_t *pglob, size_t *limit)
3490{
3491 struct stat sb;
3492 char *p, *q;
3493 int anymeta;
3494
3495 /*
3496 * Loop over pattern segments until end of pattern or until
3497 * segment with meta character found.
3498 */
3499 for (anymeta = 0;;) {
3500 if (*pattern == EOS) { /* End of pattern? */
3501 *pathend = EOS;
3502 if (stat(pathbuf, &sb))
3503 return (0);
3504
3505 if (((pglob->gl_flags & GLOB_MARK(1 << 1)) && pathend[-1] != SEP && pathend[-1] != WIN_SEP) && (_S_IFDIR & sb.st_mode)) {
3506 if (pathend + 1 > pathend_last)
3507 return (GLOB_ABORTED2);
3508 *pathend++ = WIN_SEP;
3509 *pathend = EOS;
3510 }
3511 ++pglob->gl_matchc;
3512 return (globextend(pathbuf, pglob, limit));
3513 }
3514
3515 /* Find end of next segment, copy tentatively to pathend. */
3516 q = pathend;
3517 p = pattern;
3518 while (*p != EOS && *p != SEP && *p != WIN_SEP) {
3519 if (ismeta(*p))
3520 anymeta = 1;
3521 if (q + 1 > pathend_last)
3522 return (GLOB_ABORTED2);
3523 *q++ = *p++;
3524 }
3525
3526 if (!anymeta) { /* No expansion, do next segment. */
3527 pathend = q;
3528 pattern = p;
3529 while (*pattern == SEP || *pattern == WIN_SEP) {
3530 if (pathend + 1 > pathend_last)
3531 return (GLOB_ABORTED2);
3532 *pathend++ = *pattern++;
3533 }
3534 } else /* Need expansion, recurse. */
3535 return (glob3(pathbuf, pathend, pathend_last, pattern, p, pglob, limit));
3536 }
3537 /* NOTREACHED */
3538}
3539
3540static int glob3(char *pathbuf, char *pathend, char *pathend_last, char *pattern, char *restpattern, glob_t *pglob, size_t *limit)
3541{
3542 int err;
3543 apr_dir_t *dirp;
3544 apr_pool_t *pool;
3545
3546 apr_pool_create(&pool, NULL((void*)0));
3547
3548 if (pathend > pathend_last)
3549 return (GLOB_ABORTED2);
3550 *pathend = EOS;
3551 errno(*__errno_location ()) = 0;
3552
3553 if (apr_dir_open(&dirp, pathbuf, pool) != APR_SUCCESS) {
3554 /* TODO: don't call for ENOENT or ENOTDIR? */
3555 apr_pool_destroy(pool);
3556 if (pglob->gl_errfunc) {
3557 if (pglob->gl_errfunc(pathbuf, errno(*__errno_location ())) || pglob->gl_flags & GLOB_ERR(1 << 0))
3558 return (GLOB_ABORTED2);
3559 }
3560 return (0);
3561 }
3562
3563 err = 0;
3564
3565 /* Search directory for matching names. */
3566 while (dirp) {
3567 apr_finfo_t dp;
3568 unsigned char *sc;
3569 char *dc;
3570
3571 if (apr_dir_read(&dp, APR_FINFO_NAME, dirp) != APR_SUCCESS)
3572 break;
3573 if (!(dp.valid & APR_FINFO_NAME) || !(dp.name) || !strlen(dp.name))
3574 break;
3575
3576 /* Initial DOT must be matched literally. */
3577 if (dp.name[0] == DOT && *pattern != DOT)
3578 continue;
3579 dc = pathend;
3580 sc = (unsigned char *) dp.name;
3581
3582 while (dc < pathend_last && (*dc++ = *sc++) != EOS);
3583
3584 if (!match(pathend, pattern, restpattern)) {
3585 *pathend = EOS;
3586 continue;
3587 }
3588 err = glob2(pathbuf, --dc, pathend_last, restpattern, pglob, limit);
3589 if (err)
3590 break;
3591 }
3592
3593 if (dirp)
3594 apr_dir_close(dirp);
3595 apr_pool_destroy(pool);
3596 return (err);
3597}
3598
3599
3600/*
3601 * Extend the gl_pathv member of a glob_t structure to accommodate a new item,
3602 * add the new item, and update gl_pathc.
3603 *
3604 * This assumes the BSD realloc, which only copies the block when its size
3605 * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic
3606 * behavior.
3607 *
3608 * Return 0 if new item added, error code if memory couldn't be allocated.
3609 *
3610 * Invariant of the glob_t structure:
3611 * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
3612 * gl_pathv points to (gl_offs + gl_pathc + 1) items.
3613 */
3614static int globextend(const char *path, glob_t *pglob, size_t *limit)
3615{
3616 char **pathv;
3617 char *copy;
3618 size_t i;
3619 size_t newsize, len;
3620 const char *p;
3621
3622 if (*limit && pglob->gl_pathc > *limit) {
3623 errno(*__errno_location ()) = 0;
3624 return (GLOB_NOSPACE1);
3625 }
3626
3627 newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
3628 pathv = pglob->gl_pathv ? realloc((char *) pglob->gl_pathv, newsize) : malloc(newsize);
3629 if (pathv == NULL((void*)0)) {
3630 if (pglob->gl_pathv) {
3631 free(pglob->gl_pathv);
3632 pglob->gl_pathv = NULL((void*)0);
3633 }
3634 return (GLOB_NOSPACE1);
3635 }
3636
3637 if (pglob->gl_pathv == NULL((void*)0) && pglob->gl_offs > 0) {
3638 /* first time around -- clear initial gl_offs items */
3639 pathv += pglob->gl_offs;
3640 for (i = pglob->gl_offs; i-- > 0;)
3641 *--pathv = NULL((void*)0);
3642 }
3643 pglob->gl_pathv = pathv;
3644
3645 for (p = path; *p++;)
3646 continue;
3647 len = (size_t) (p - path);
3648 if ((copy = malloc(len)) != NULL((void*)0)) {
3649 memcpy(copy, path, len);
3650 pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
3651 }
3652 pathv[pglob->gl_offs + pglob->gl_pathc] = NULL((void*)0);
3653 return (copy == NULL((void*)0) ? GLOB_NOSPACE1 : 0);
3654}
3655
3656/*
3657 * pattern matching function for filenames. Each occurrence of the *
3658 * pattern causes a recursion level.
3659 */
3660static int match(char *name, char *pat, char *patend)
3661{
3662 int ok, negate_range;
3663 char c, k;
3664 char s1[6];
3665
3666 while (pat < patend) {
3667 c = *pat++;
3668 switch (c & M_MASK) {
3669 case M_ALL:
3670 if (pat == patend)
3671 return (1);
3672 do
3673 if (match(name, pat, patend))
3674 return (1);
3675 while (*name++ != EOS);
3676 return (0);
3677 case M_ONE:
3678 if (*name++ == EOS)
3679 return (0);
3680 break;
3681 case M_SET:
3682 ok = 0;
3683 if ((k = *name++) == EOS)
3684 return (0);
3685 if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
3686 ++pat;
3687 while (((c = *pat++) & M_MASK) != M_END)
3688 if ((*pat & M_MASK) == M_RNG) {
3689 memset(s1, 0, sizeof(s1));
3690 s1[0] = c;
3691 s1[2] = k;
3692 s1[4] = pat[1];
3693 if (strcoll(&s1[0], &s1[2]) <= 0 && strcoll(&s1[2], &s1[4]) <= 0)
3694 ok = 1;
3695 pat += 2;
3696 } else if (c == k)
3697 ok = 1;
3698 if (ok == negate_range)
3699 return (0);
3700 break;
3701 default:
3702 if (*name++ != c)
3703 return (0);
3704 break;
3705 }
3706 }
3707 return (*name == EOS);
3708}
3709
3710/* Free allocated data belonging to a glob_t structure. */
3711void globfree(glob_t *pglob)
3712{
3713 size_t i;
3714 char **pp;
3715
3716 if (pglob->gl_pathv != NULL((void*)0)) {
3717 pp = pglob->gl_pathv + pglob->gl_offs;
3718 for (i = pglob->gl_pathc; i--; ++pp)
3719 if (*pp)
3720 free(*pp);
3721 free(pglob->gl_pathv);
3722 pglob->gl_pathv = NULL((void*)0);
3723 }
3724}
3725
3726#pragma warning(pop)
3727#endif
3728
3729/* For Emacs:
3730 * Local Variables:
3731 * mode:c
3732 * indent-tabs-mode:t
3733 * tab-width:4
3734 * c-basic-offset:4
3735 * End:
3736 * For VIM:
3737 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
3738 */