FreeSWITCH API Documentation  1.7.0
Data Structures | Macros | Typedefs | Functions | Variables
switch_xml.c File Reference
#include <switch.h>
#include <sys/wait.h>
#include <switch_private.h>
#include <glob.h>
+ Include dependency graph for switch_xml.c:

Go to the source code of this file.

Data Structures

struct  switch_xml_root
 
struct  switch_xml_binding
 
struct  xml_section_t
 
struct  destroy_xml
 

Macros

#define SWITCH_XML_WS   "\t\r\n " /* whitespace */
 
#define SWITCH_XML_ERRL   128 /* maximum error string length */
 
#define XML_INDENT   " "
 

Typedefs

typedef struct switch_xml_rootswitch_xml_root_t
 

Functions

static void preprocess_exec_set (char *keyval)
 
static int preprocess (const char *cwd, const char *file, FILE *write_fd, int rlevel)
 
switch_xml_t __switch_xml_open_root (uint8_t reload, const char **err, void *user_data)
 
switch_xml_section_t switch_xml_parse_section_string (const char *str)
 
switch_status_t switch_xml_unbind_search_function (switch_xml_binding_t **binding)
 
switch_status_t switch_xml_unbind_search_function_ptr (switch_xml_search_function_t function)
 
void switch_xml_set_binding_sections (switch_xml_binding_t *binding, switch_xml_section_t sections)
 
void switch_xml_set_binding_user_data (switch_xml_binding_t *binding, void *user_data)
 
switch_xml_section_t switch_xml_get_binding_sections (switch_xml_binding_t *binding)
 
void * switch_xml_get_binding_user_data (switch_xml_binding_t *binding)
 
switch_status_t switch_xml_bind_search_function_ret (switch_xml_search_function_t function, switch_xml_section_t sections, void *user_data, switch_xml_binding_t **ret_binding)
 
switch_xml_t switch_xml_find_child (switch_xml_t node, const char *childname, const char *attrname, const char *value)
 
switch_xml_t switch_xml_find_child_multi (switch_xml_t node, const char *childname,...)
 
switch_xml_t switch_xml_child (switch_xml_t xml, const char *name)
 
switch_xml_t switch_xml_idx (switch_xml_t xml, int idx)
 
const char * switch_xml_attr_soft (switch_xml_t xml, const char *attr)
 
const char * switch_xml_attr (switch_xml_t xml, const char *attr)
 
static switch_xml_t switch_xml_vget (switch_xml_t xml, va_list ap)
 
switch_xml_t switch_xml_get (switch_xml_t xml,...)
 
const char ** switch_xml_pi (switch_xml_t xml, const char *target)
 
static switch_xml_t switch_xml_err (switch_xml_root_t root, char *s, const char *err,...)
 
static char * switch_xml_decode (char *s, char **ent, char t)
 
static void switch_xml_open_tag (switch_xml_root_t root, char *name, char **attr)
 
static void switch_xml_char_content (switch_xml_root_t root, char *s, switch_size_t len, char t)
 
static switch_xml_t switch_xml_close_tag (switch_xml_root_t root, char *name, char *s)
 
static int switch_xml_ent_ok (char *name, char *s, char **ent)
 
static void switch_xml_proc_inst (switch_xml_root_t root, char *s, switch_size_t len)
 
static short switch_xml_internal_dtd (switch_xml_root_t root, char *s, switch_size_t len)
 
static char * switch_xml_str2utf8 (char **s, switch_size_t *len)
 
static void switch_xml_free_attr (char **attr)
 
switch_xml_t switch_xml_parse_str_dynamic (char *s, switch_bool_t dup)
 
switch_xml_t switch_xml_parse_str (char *s, switch_size_t len)
 
switch_xml_t switch_xml_parse_fp (FILE *fp)
 
switch_xml_t switch_xml_parse_fd (int fd)
 A wrapper for switch_xml_parse_str() that accepts a file descriptor. First \ attempts to mem map the file. Failing that, reads the file into memory. \ Returns NULL on failure. More...
 
static char * expand_vars (char *buf, char *ebuf, switch_size_t elen, switch_size_t *newlen, const char **err)
 
static FILE * preprocess_exec (const char *cwd, const char *command, FILE *write_fd, int rlevel)
 
static FILE * preprocess_glob (const char *cwd, const char *pattern, FILE *write_fd, int rlevel)
 
switch_xml_t switch_xml_parse_file_simple (const char *file)
 
switch_xml_t switch_xml_parse_file (const char *file)
 
switch_status_t switch_xml_locate (const char *section, const char *tag_name, const char *key_name, const char *key_value, switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_bool_t clone)
 
switch_status_t switch_xml_locate_domain (const char *domain_name, switch_event_t *params, switch_xml_t *root, switch_xml_t *domain)
 
switch_status_t switch_xml_locate_group (const char *group_name, const char *domain_name, switch_xml_t *root, switch_xml_t *domain, switch_xml_t *group, switch_event_t *params)
 
static switch_status_t find_user_in_tag (switch_xml_t tag, const char *ip, const char *user_name, const char *key, switch_event_t *params, switch_xml_t *user)
 
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)
 
switch_xml_t switch_xml_dup (switch_xml_t xml)
 
static void do_merge (switch_xml_t in, switch_xml_t src, const char *container, const char *tag_name)
 
void switch_xml_merge_user (switch_xml_t user, switch_xml_t domain, switch_xml_t group)
 
uint32_t switch_xml_clear_user_cache (const char *key, const char *user_name, const char *domain_name)
 
static switch_status_t switch_xml_locate_user_cache (const char *key, const char *user_name, const char *domain_name, switch_xml_t *user)
 
static void switch_xml_user_cache (const char *key, const char *user_name, const char *domain_name, switch_xml_t user, switch_time_t expires)
 
switch_status_t switch_xml_locate_user_merged (const char *key, const char *user_name, const char *domain_name, const char *ip, switch_xml_t *user, switch_event_t *params)
 
switch_status_t switch_xml_locate_user (const char *key, const char *user_name, const char *domain_name, const char *ip, switch_xml_t *root, switch_xml_t *domain, switch_xml_t *user, switch_xml_t *ingroup, switch_event_t *params)
 
switch_xml_t switch_xml_root (void)
 retrieve the core XML root node More...
 
static void *SWITCH_THREAD_FUNC destroy_thread (switch_thread_t *thread, void *obj)
 
void switch_xml_free_in_thread (switch_xml_t xml, int stacksize)
 
switch_status_t switch_xml_set_root (switch_xml_t new_main)
 set new core xml root More...
 
switch_status_t switch_xml_set_open_root_function (switch_xml_open_root_function_t func, void *user_data)
 Set and alternate function for opening xml root. More...
 
switch_xml_t switch_xml_open_root (uint8_t reload, const char **err)
 
switch_status_t switch_xml_reload (const char **err)
 
switch_status_t switch_xml_init (switch_memory_pool_t *pool, const char **err)
 
switch_status_t switch_xml_destroy (void)
 
switch_xml_t switch_xml_open_cfg (const char *file_path, switch_xml_t *node, switch_event_t *params)
 
static char * switch_xml_ampencode (const char *s, switch_size_t len, char **dst, switch_size_t *dlen, switch_size_t *max, short a)
 
static 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)
 
char * switch_xml_toxml_nolock (switch_xml_t xml, switch_bool_t prn_header)
 
char * switch_xml_toxml (switch_xml_t xml, switch_bool_t prn_header)
 
char * switch_xml_tohtml (switch_xml_t xml, switch_bool_t prn_header)
 
char * switch_xml_toxml_buf (switch_xml_t xml, char *buf, switch_size_t buflen, switch_size_t offset, switch_bool_t prn_header)
 
void switch_xml_free (switch_xml_t xml)
 
const char * switch_xml_error (switch_xml_t xml)
 
switch_xml_t switch_xml_new (const char *name)
 
switch_xml_t switch_xml_insert (switch_xml_t xml, switch_xml_t dest, switch_size_t off)
 
switch_xml_t switch_xml_add_child (switch_xml_t xml, const char *name, switch_size_t off)
 
switch_xml_t switch_xml_set_txt (switch_xml_t xml, const char *txt)
 sets the character content for the given tag and returns the tag More...
 
switch_xml_t switch_xml_set_attr (switch_xml_t xml, const char *name, const char *value)
 Sets the given tag attribute or adds a new attribute if not found. A value \ of NULL will remove the specified attribute. More...
 
switch_xml_t switch_xml_set_flag (switch_xml_t xml, switch_xml_flag_t flag)
 sets a flag for the given tag and returns the tag More...
 
switch_xml_t switch_xml_cut (switch_xml_t xml)
 
int switch_xml_std_datetime_check (switch_xml_t xcond, int *offset, const char *tzname)
 
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)
 

Variables

static switch_bool_t USE_UTF_8_ENCODING = SWITCH_TRUE
 
char * SWITCH_XML_NIL [] = { NULL }
 
static switch_xml_binding_tBINDINGS = NULL
 
static switch_xml_t MAIN_XML_ROOT = NULL
 
static switch_memory_pool_tXML_MEMORY_POOL = NULL
 
static switch_thread_rwlock_tB_RWLOCK = NULL
 
static switch_mutex_tXML_LOCK = NULL
 
static switch_mutex_tCACHE_MUTEX = NULL
 
static switch_mutex_tREFLOCK = NULL
 
static switch_mutex_tFILE_LOCK = NULL
 
static
switch_xml_open_root_function_t 
XML_OPEN_ROOT_FUNCTION = (switch_xml_open_root_function_t)__switch_xml_open_root
 
static void * XML_OPEN_ROOT_FUNCTION_USER_DATA = NULL
 
static switch_hash_tCACHE_HASH = NULL
 
static switch_hash_tCACHE_EXPIRES_HASH = NULL
 
static struct xml_section_t SECTIONS []
 
static char not_so_threadsafe_error_buffer [256] = ""
 

Macro Definition Documentation

#define SWITCH_XML_ERRL   128 /* maximum error string length */

Definition at line 103 of file switch_xml.c.

Referenced by switch_xml_err().

#define SWITCH_XML_WS   "\t\r\n " /* whitespace */
#define XML_INDENT   " "

Definition at line 2503 of file switch_xml.c.

Referenced by switch_xml_toxml_r().

Typedef Documentation

Definition at line 146 of file switch_xml.c.

Function Documentation

switch_xml_t __switch_xml_open_root ( uint8_t  reload,
const char **  err,
void *  user_data 
)

Definition at line 2280 of file switch_xml.c.

References switch_directories::conf_dir, switch_filenames::conf_name, not_so_threadsafe_error_buffer, switch_copy_string(), SWITCH_GLOBAL_dirs, SWITCH_GLOBAL_filenames, SWITCH_PATH_SEPARATOR, switch_snprintf(), switch_xml_error(), switch_xml_free(), switch_xml_parse_file(), switch_xml_root(), switch_xml_set_root(), and zstr.

2281 {
2282  char path_buf[1024];
2283  uint8_t errcnt = 0;
2284  switch_xml_t new_main, r = NULL;
2285 
2286  if (MAIN_XML_ROOT) {
2287  if (!reload) {
2288  r = switch_xml_root();
2289  goto done;
2290  }
2291  }
2292 
2294  if ((new_main = switch_xml_parse_file(path_buf))) {
2295  *err = switch_xml_error(new_main);
2298  if (!zstr(*err)) {
2299  switch_xml_free(new_main);
2300  new_main = NULL;
2301  errcnt++;
2302  } else {
2303  *err = "Success";
2304  switch_xml_set_root(new_main);
2305 
2306  }
2307  } else {
2308  *err = "Cannot Open log directory or XML Root!";
2309  errcnt++;
2310  }
2311 
2312  if (errcnt == 0) {
2313  r = switch_xml_root();
2314  }
2315 
2316  done:
2317 
2318  return r;
2319 }
switch_xml_t switch_xml_parse_file(const char *file)
Definition: switch_xml.c:1583
switch_xml_t switch_xml_root(void)
retrieve the core XML root node
Definition: switch_xml.c:2166
const char * switch_xml_error(switch_xml_t xml)
Definition: switch_xml.c:2786
A representation of an XML tree.
Definition: switch_xml.h:76
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
#define zstr(x)
Definition: switch_utils.h:281
static char not_so_threadsafe_error_buffer[256]
Definition: switch_xml.c:2213
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:122
static switch_xml_t MAIN_XML_ROOT
Definition: switch_xml.c:174
switch_filenames SWITCH_GLOBAL_filenames
Definition: switch_core.c:61
char * switch_copy_string(_Out_z_cap_(dst_size) char *dst, _In_z_ const char *src, _In_ switch_size_t dst_size)
switch_directories SWITCH_GLOBAL_dirs
Definition: switch_core.c:60
switch_status_t switch_xml_set_root(switch_xml_t new_main)
set new core xml root
Definition: switch_xml.c:2215
void switch_xml_free(switch_xml_t xml)
Definition: switch_xml.c:2701
static void* SWITCH_THREAD_FUNC destroy_thread ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 2183 of file switch_xml.c.

References pool, destroy_xml::pool, switch_core_destroy_memory_pool, switch_xml_free(), and destroy_xml::xml.

Referenced by switch_xml_free_in_thread().

2184 {
2185  struct destroy_xml *dx = (struct destroy_xml *) obj;
2187  switch_xml_free(dx->xml);
2189  return NULL;
2190 }
switch_xml_t xml
Definition: switch_xml.c:2179
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
switch_memory_pool_t * pool
switch_memory_pool_t * pool
Definition: switch_xml.c:2180
struct apr_pool_t switch_memory_pool_t
void switch_xml_free(switch_xml_t xml)
Definition: switch_xml.c:2701
static void do_merge ( switch_xml_t  in,
switch_xml_t  src,
const char *  container,
const char *  tag_name 
)
static

Definition at line 1869 of file switch_xml.c.

References switch_xml::next, switch_xml_add_child_d, switch_xml_attr(), switch_xml_child(), and switch_xml_set_attr_d.

Referenced by switch_xml_merge_user().

1870 {
1871  switch_xml_t itag, tag, param, iparam, iitag;
1872 
1873  if (!(itag = switch_xml_child(in, container))) {
1874  itag = switch_xml_add_child_d(in, container, 0);
1875  }
1876 
1877  if ((tag = switch_xml_child(src, container))) {
1878  for (param = switch_xml_child(tag, tag_name); param; param = param->next) {
1879  const char *var = switch_xml_attr(param, "name");
1880  const char *val = switch_xml_attr(param, "value");
1881 
1882  int go = 1;
1883 
1884  for (iparam = switch_xml_child(itag, tag_name); iparam; iparam = iparam->next) {
1885  const char *ivar = switch_xml_attr(iparam, "name");
1886 
1887  if (var && ivar && !strcasecmp(var, ivar)) {
1888  go = 0;
1889  break;
1890  }
1891  }
1892 
1893  if (go) {
1894  iitag = switch_xml_add_child_d(itag, tag_name, 0);
1895  switch_xml_set_attr_d(iitag, "name", var);
1896  switch_xml_set_attr_d(iitag, "value", val);
1897  }
1898  }
1899  }
1900 
1901 }
const char * switch_xml_attr(switch_xml_t xml, const char *attr)
Definition: switch_xml.c:434
#define switch_xml_add_child_d(xml, name, off)
wrapper for switch_xml_add_child() that strdup()s name
Definition: switch_xml.h:269
A representation of an XML tree.
Definition: switch_xml.h:76
switch_xml_t next
Definition: switch_xml.h:88
#define switch_xml_set_attr_d(xml, name, value)
Wrapper for switch_xml_set_attr() that strdup()s name/value. Value cannot be NULL.
Definition: switch_xml.h:299
switch_xml_t switch_xml_child(switch_xml_t xml, const char *name)
Definition: switch_xml.c:409
static char* expand_vars ( char *  buf,
char *  ebuf,
switch_size_t  elen,
switch_size_t newlen,
const char **  err 
)
static

Definition at line 1184 of file switch_xml.c.

References buf, ep, switch_core_get_variable_dup(), and switch_find_end_paren().

Referenced by preprocess().

1185 {
1186  char *var, *val;
1187  char *rp = buf;
1188  char *wp = ebuf;
1189  char *ep = ebuf + elen - 1;
1190 
1191  if (!(var = strstr(rp, "$${"))) {
1192  *newlen = strlen(buf);
1193  return buf;
1194  }
1195 
1196  while (*rp && wp < ep) {
1197 
1198  if (*rp == '$' && *(rp + 1) == '$' && *(rp + 2) == '{') {
1199  char *e = switch_find_end_paren(rp + 2, '{', '}');
1200 
1201  if (e) {
1202  rp += 3;
1203  var = rp;
1204  *e++ = '\0';
1205  rp = e;
1206  if ((val = switch_core_get_variable_dup(var))) {
1207  char *p;
1208  for (p = val; p && *p && wp <= ep; p++) {
1209  *wp++ = *p;
1210  }
1211  free(val);
1212  }
1213  continue;
1214  } else if (err) {
1215  *err = "unterminated ${var}";
1216  }
1217  }
1218 
1219  *wp++ = *rp++;
1220  }
1221 
1222  if (wp == ep) {
1223  return NULL;
1224  }
1225 
1226  *wp++ = '\0';
1227  *newlen = strlen(ebuf);
1228 
1229  return ebuf;
1230 }
char * switch_find_end_paren(const char *s, char open, char close)
Definition: switch_utils.c:661
switch_byte_t switch_byte_t * buf
static const char * ep
Definition: switch_json.c:36
char * switch_core_get_variable_dup(_In_z_ const char *varname)
static switch_status_t find_user_in_tag ( switch_xml_t  tag,
const char *  ip,
const char *  user_name,
const char *  key,
switch_event_t params,
switch_xml_t user 
)
static

Definition at line 1804 of file switch_xml.c.

References switch_event_get_header, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_xml_find_child_multi().

Referenced by switch_xml_locate_user(), and switch_xml_locate_user_in_domain().

1806 {
1807  const char *type = "!pointer";
1808  const char *val;
1809 
1810  if (params && (val = switch_event_get_header(params, "user_type"))) {
1811  if (!strcasecmp(val, "any")) {
1812  type = NULL;
1813  } else {
1814  type = val;
1815  }
1816  }
1817 
1818  if (ip) {
1819  if ((*user = switch_xml_find_child_multi(tag, "user", "ip", ip, "type", type, NULL))) {
1820  return SWITCH_STATUS_SUCCESS;
1821  }
1822  }
1823 
1824  if (user_name) {
1825  if (!strcasecmp(key, "id")) {
1826  if ((*user = switch_xml_find_child_multi(tag, "user", key, user_name, "number-alias", user_name, "type", type, NULL))) {
1827  return SWITCH_STATUS_SUCCESS;
1828  }
1829  } else {
1830  if ((*user = switch_xml_find_child_multi(tag, "user", key, user_name, "type", type, NULL))) {
1831  return SWITCH_STATUS_SUCCESS;
1832  }
1833  }
1834  }
1835 
1836  return SWITCH_STATUS_FALSE;
1837 
1838 }
switch_xml_t switch_xml_find_child_multi(switch_xml_t node, const char *childname,...)
Definition: switch_xml.c:352
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172
static int preprocess ( const char *  cwd,
const char *  file,
FILE *  write_fd,
int  rlevel 
)
static

Definition at line 1339 of file switch_xml.c.

References buf, cur, expand_vars(), memset(), preprocess_exec(), preprocess_exec_set(), preprocess_glob(), SWITCH_CHANNEL_LOG, switch_core_set_variable(), switch_fp_read_dline(), SWITCH_LOG_ERROR, switch_log_printf(), switch_must_malloc(), switch_must_realloc(), switch_safe_free, and switch_stristr().

Referenced by preprocess_glob(), and switch_xml_parse_file().

1340 {
1341  FILE *read_fd = NULL;
1342  switch_size_t cur = 0, ml = 0;
1343  char *q, *cmd, *buf = NULL, *ebuf = NULL;
1344  char *tcmd, *targ;
1345  int line = 0;
1346  switch_size_t len = 0, eblen = 0;
1347 
1348  if (rlevel > 100) {
1349  return -1;
1350  }
1351 
1352  if (!(read_fd = fopen(file, "r"))) {
1353  const char *reason = strerror(errno);
1354  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't open %s (%s)\n", file, reason);
1355  return -1;
1356  }
1357 
1358  setvbuf(read_fd, (char *) NULL, _IOFBF, 65536);
1359 
1360  for(;;) {
1361  char *arg, *e;
1362  const char *err = NULL;
1363  char *bp;
1364 
1365  switch_safe_free(ebuf);
1366 
1367  if ((cur = switch_fp_read_dline(read_fd, &buf, &len)) <= 0) {
1368  break;
1369  }
1370 
1371  eblen = len * 2;
1372  ebuf = switch_must_malloc(eblen);
1373  memset(ebuf, 0, eblen);
1374 
1375  while (!(bp = expand_vars(buf, ebuf, eblen, &cur, &err))) {
1376  eblen *= 2;
1377  ebuf = switch_must_realloc(ebuf, eblen);
1378  memset(ebuf, 0, eblen);
1379  }
1380 
1381  line++;
1382 
1383  if (err) {
1384  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error [%s] in file %s line %d\n", err, file, line);
1385  }
1386 
1387  /* we ignore <include> or </include> for the sake of validators as well as <?xml version="1.0"?> type stuff */
1388  if (strstr(buf, "<include>") || strstr(buf, "</include>") || strstr(buf, "<?")) {
1389  continue;
1390  }
1391 
1392  if (ml) {
1393  if ((e = strstr(buf, "-->"))) {
1394  ml = 0;
1395  bp = e + 3;
1396  cur = strlen(bp);
1397  } else {
1398  continue;
1399  }
1400  }
1401 
1402  if ((tcmd = (char *) switch_stristr("X-pre-process", bp))) {
1403  if (*(tcmd - 1) != '<') {
1404  continue;
1405  }
1406  if ((e = strstr(tcmd, "/>"))) {
1407  *e += 2;
1408  *e = '\0';
1409  if (fwrite(e, 1, (unsigned) strlen(e), write_fd) != (int) strlen(e)) {
1411  }
1412  }
1413 
1414  if (!(tcmd = (char *) switch_stristr("cmd", tcmd))) {
1415  continue;
1416  }
1417 
1418  if (!(tcmd = (char *) switch_stristr("=", tcmd))) {
1419  continue;
1420  }
1421 
1422  if (!(tcmd = (char *) switch_stristr("\"", tcmd))) {
1423  continue;
1424  }
1425 
1426  tcmd++;
1427 
1428 
1429  if ((e = strchr(tcmd, '"'))) {
1430  *e++ = '\0';
1431  }
1432 
1433  if (!(targ = (char *) switch_stristr("data", e))) {
1434  continue;
1435  }
1436 
1437  if (!(targ = (char *) switch_stristr("=", targ))) {
1438  continue;
1439  }
1440 
1441  if (!(targ = (char *) switch_stristr("\"", targ))) {
1442  continue;
1443  }
1444 
1445  targ++;
1446 
1447  if ((e = strchr(targ, '"'))) {
1448  *e++ = '\0';
1449  }
1450 
1451  if (!strcasecmp(tcmd, "set")) {
1452  char *name = (char *) targ;
1453  char *val = strchr(name, '=');
1454 
1455  if (val) {
1456  char *ve = val++;
1457  while (*val && *val == ' ') {
1458  val++;
1459  }
1460  *ve-- = '\0';
1461  while (*ve && *ve == ' ') {
1462  *ve-- = '\0';
1463  }
1464  }
1465 
1466  if (name && val) {
1467  switch_core_set_variable(name, val);
1468  }
1469 
1470  } else if (!strcasecmp(tcmd, "exec-set")) {
1471  preprocess_exec_set(targ);
1472  } else if (!strcasecmp(tcmd, "include")) {
1473  preprocess_glob(cwd, targ, write_fd, rlevel + 1);
1474  } else if (!strcasecmp(tcmd, "exec")) {
1475  preprocess_exec(cwd, targ, write_fd, rlevel + 1);
1476  }
1477 
1478  continue;
1479  }
1480 
1481  if ((cmd = strstr(bp, "<!--#"))) {
1482  if (fwrite(bp, 1, (unsigned) (cmd - bp), write_fd) != (unsigned) (cmd - bp)) {
1484  }
1485  if ((e = strstr(cmd, "-->"))) {
1486  *e = '\0';
1487  e += 3;
1488  if (fwrite(e, 1, (unsigned) strlen(e), write_fd) != (int) strlen(e)) {
1490  }
1491  } else {
1492  ml++;
1493  }
1494 
1495  cmd += 5;
1496  if ((e = strchr(cmd, '\r')) || (e = strchr(cmd, '\n'))) {
1497  *e = '\0';
1498  }
1499 
1500  if ((arg = strchr(cmd, ' '))) {
1501  *arg++ = '\0';
1502  if ((q = strchr(arg, '"'))) {
1503  char *qq = q + 1;
1504 
1505  if ((qq = strchr(qq, '"'))) {
1506  *qq = '\0';
1507  arg = q + 1;
1508  }
1509  }
1510 
1511  if (!strcasecmp(cmd, "set")) {
1512  char *name = arg;
1513  char *val = strchr(name, '=');
1514 
1515  if (val) {
1516  char *ve = val++;
1517  while (*val && *val == ' ') {
1518  val++;
1519  }
1520  *ve-- = '\0';
1521  while (*ve && *ve == ' ') {
1522  *ve-- = '\0';
1523  }
1524  }
1525 
1526  if (name && val) {
1527  switch_core_set_variable(name, val);
1528  }
1529 
1530  } else if (!strcasecmp(cmd, "exec-set")) {
1531  preprocess_exec_set(arg);
1532  } else if (!strcasecmp(cmd, "include")) {
1533  preprocess_glob(cwd, arg, write_fd, rlevel + 1);
1534  } else if (!strcasecmp(cmd, "exec")) {
1535  preprocess_exec(cwd, arg, write_fd, rlevel + 1);
1536  }
1537  }
1538 
1539  continue;
1540  }
1541 
1542  if (fwrite(bp, 1, (unsigned) cur, write_fd) != (int) cur) {
1544  }
1545 
1546  }
1547 
1548  switch_safe_free(buf);
1549  switch_safe_free(ebuf);
1550 
1551  fclose(read_fd);
1552 
1553  return 0;
1554 }
#define SWITCH_CHANNEL_LOG
void switch_core_set_variable(_In_z_ const char *varname, _In_opt_z_ const char *value)
Add a global variable to the core.
static void * switch_must_malloc(size_t _b)
Definition: switch_core.h:231
pack cur
static void preprocess_exec_set(char *keyval)
Definition: switch_xml.c:108
switch_byte_t switch_byte_t * buf
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
static void * switch_must_realloc(void *_b, size_t _z)
Definition: switch_core.h:238
uintptr_t switch_size_t
switch_size_t switch_fp_read_dline(FILE *fd, char **buf, switch_size_t *len)
Definition: switch_utils.c:757
static FILE * preprocess_glob(const char *cwd, const char *pattern, FILE *write_fd, int rlevel)
Definition: switch_xml.c:1295
static char * expand_vars(char *buf, char *ebuf, switch_size_t elen, switch_size_t *newlen, const char **err)
Definition: switch_xml.c:1184
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
const char * switch_stristr(const char *instr, const char *str)
memset(buf, 0, buflen)
static FILE * preprocess_exec(const char *cwd, const char *command, FILE *write_fd, int rlevel)
Definition: switch_xml.c:1232
static FILE* preprocess_exec ( const char *  cwd,
const char *  command,
FILE *  write_fd,
int  rlevel 
)
static

Definition at line 1232 of file switch_xml.c.

References buf, SWITCH_CHANNEL_LOG, switch_close_extra_files(), switch_fork(), SWITCH_LOG_ERROR, switch_log_printf(), switch_snprintf(), switch_system(), and SWITCH_TRUE.

Referenced by preprocess().

1233 {
1234 #ifdef WIN32
1235  FILE *fp = NULL;
1236  char buffer[1024];
1237 
1238  if (!command || !strlen(command)) goto end;
1239 
1240  if ((fp = _popen(command, "r"))) {
1241  while (fgets(buffer, sizeof(buffer), fp) != NULL) {
1242  if (fwrite(buffer, 1, strlen(buffer), write_fd) <= 0) {
1243  break;
1244  }
1245  }
1246 
1247  if(feof(fp)) {
1248  _pclose(fp);
1249  } else {
1250  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exec failed to read the pipe of [%s] to the end\n", command);
1251  }
1252  } else {
1253  switch_snprintf(buffer, sizeof(buffer), "<!-- exec can not execute [%s] -->", command);
1254  fwrite( buffer, 1, strlen(buffer), write_fd);
1255  }
1256 #else
1257  int fds[2], pid = 0;
1258 
1259  if (pipe(fds)) {
1260  goto end;
1261  } else { /* good to go */
1262  pid = switch_fork();
1263 
1264  if (pid < 0) { /* ok maybe not */
1265  close(fds[0]);
1266  close(fds[1]);
1267  goto end;
1268  } else if (pid) { /* parent */
1269  char buf[1024] = "";
1270  int bytes;
1271  close(fds[1]);
1272  while ((bytes = read(fds[0], buf, sizeof(buf))) > 0) {
1273  if (fwrite(buf, 1, bytes, write_fd) <= 0) {
1274  break;
1275  }
1276  }
1277  close(fds[0]);
1278  waitpid(pid, NULL, 0);
1279  } else { /* child */
1280  switch_close_extra_files(fds, 2);
1281  close(fds[0]);
1282  dup2(fds[1], STDOUT_FILENO);
1283  switch_system(command, SWITCH_TRUE);
1284  close(fds[1]);
1285  exit(0);
1286  }
1287  }
1288 #endif
1289  end:
1290 
1291  return write_fd;
1292 
1293 }
void switch_close_extra_files(int *keep, int keep_ttl)
Definition: switch_core.c:3096
#define SWITCH_CHANNEL_LOG
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
int switch_system(const char *cmd, switch_bool_t wait)
Definition: switch_core.c:3194
switch_byte_t switch_byte_t * buf
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
pid_t switch_fork(void)
Definition: switch_core.c:3134
static void preprocess_exec_set ( char *  keyval)
static

Definition at line 108 of file switch_xml.c.

References switch_stream_handle::data, SWITCH_CHANNEL_LOG, switch_core_set_variable(), SWITCH_LOG_ERROR, switch_log_printf(), switch_safe_free, SWITCH_STANDARD_STREAM, switch_stream_system_fork(), and zstr.

Referenced by preprocess().

109 {
110  char *key = keyval;
111  char *val = 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);
127  if (switch_stream_system_fork(val, &exec_result) == 0) {
128  if (!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_LOG, SWITCH_LOG_ERROR, "Error while executing command: %s\n", val);
139  }
140  switch_safe_free(exec_result.data);
141  }
142 }
#define SWITCH_CHANNEL_LOG
int switch_stream_system_fork(const char *cmd, switch_stream_handle_t *stream)
Definition: switch_core.c:3206
void switch_core_set_variable(_In_z_ const char *varname, _In_opt_z_ const char *value)
Add a global variable to the core.
#define zstr(x)
Definition: switch_utils.h:281
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
#define SWITCH_STANDARD_STREAM(s)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
static FILE* preprocess_glob ( const char *  cwd,
const char *  pattern,
FILE *  write_fd,
int  rlevel 
)
static

Definition at line 1295 of file switch_xml.c.

References preprocess(), SWITCH_CHANNEL_LOG, switch_is_file_path(), SWITCH_LOG_ERROR, SWITCH_LOG_INFO, switch_log_printf(), switch_mprintf(), switch_must_strdup(), SWITCH_PATH_SEPARATOR, and switch_safe_free.

Referenced by preprocess().

1296 {
1297  char *full_path = NULL;
1298  char *dir_path = NULL, *e = NULL;
1299  glob_t glob_data;
1300  size_t n;
1301  int glob_return;
1302 
1303  if (!switch_is_file_path(pattern)) {
1304  full_path = switch_mprintf("%s%s%s", cwd, SWITCH_PATH_SEPARATOR, pattern);
1305  pattern = full_path;
1306  }
1307 
1308  glob_return = glob(pattern, GLOB_ERR, NULL, &glob_data);
1309  if (glob_return == GLOB_NOSPACE || glob_return == GLOB_ABORTED) {
1310  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error including %s\n", pattern);
1311  goto end;
1312  } else if (glob_return == GLOB_NOMATCH) {
1313  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "No files to include at %s\n", pattern);
1314  goto end;
1315  }
1316 
1317  for (n = 0; n < glob_data.gl_pathc; ++n) {
1318  dir_path = switch_must_strdup(glob_data.gl_pathv[n]);
1319 
1320  if ((e = strrchr(dir_path, *SWITCH_PATH_SEPARATOR))) {
1321  *e = '\0';
1322  }
1323  if (preprocess(dir_path, glob_data.gl_pathv[n], write_fd, rlevel) < 0) {
1324  if (rlevel > 100) {
1325  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error including %s (Maximum recursion limit reached)\n", pattern);
1326  }
1327  }
1328  free(dir_path);
1329  }
1330  globfree(&glob_data);
1331 
1332  end:
1333 
1334  switch_safe_free(full_path);
1335 
1336  return write_fd;
1337 }
#define SWITCH_CHANNEL_LOG
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:122
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
static char * switch_must_strdup(const char *_s)
Definition: switch_core.h:245
static switch_bool_t switch_is_file_path(const char *file)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
static int preprocess(const char *cwd, const char *file, FILE *write_fd, int rlevel)
Definition: switch_xml.c:1339
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)
switch_xml_t switch_xml_add_child ( switch_xml_t  xml,
const char *  name,
switch_size_t  off 
)

Definition at line 2852 of file switch_xml.c.

References switch_xml::attr, memset(), switch_xml::name, switch_xml::off, switch_xml::parent, switch_must_malloc(), switch_xml_insert(), SWITCH_XML_NIL, switch_xml::txt, and destroy_xml::xml.

Referenced by switch_xml_open_tag().

2853 {
2854  switch_xml_t child;
2855 
2856  if (!xml)
2857  return NULL;
2858  child = (switch_xml_t) switch_must_malloc(sizeof(struct switch_xml));
2859 
2860  memset(child, '\0', sizeof(struct switch_xml));
2861  child->name = (char *) name;
2862  child->attr = SWITCH_XML_NIL;
2863  child->off = off;
2864  child->parent = xml;
2865  child->txt = (char *) "";
2866 
2867  return switch_xml_insert(child, xml, off);
2868 }
char * name
Definition: switch_xml.h:78
switch_xml_t switch_xml_insert(switch_xml_t xml, switch_xml_t dest, switch_size_t off)
Definition: switch_xml.c:2811
switch_size_t off
Definition: switch_xml.h:86
struct switch_xml * switch_xml_t
switch_xml_t xml
Definition: switch_xml.c:2179
static void * switch_must_malloc(size_t _b)
Definition: switch_core.h:231
A representation of an XML tree.
Definition: switch_xml.h:76
char * txt
Definition: switch_xml.h:82
switch_xml_t parent
Definition: switch_xml.h:96
char ** attr
Definition: switch_xml.h:80
memset(buf, 0, buflen)
char * SWITCH_XML_NIL[]
Definition: switch_xml.c:163
static char* switch_xml_ampencode ( const char *  s,
switch_size_t  len,
char **  dst,
switch_size_t dlen,
switch_size_t max,
short  a 
)
static

Definition at line 2401 of file switch_xml.c.

References SWITCH_CHANNEL_LOG, switch_log_printf(), SWITCH_LOG_WARNING, switch_must_realloc(), and SWITCH_XML_BUFSIZE.

Referenced by switch_xml_tohtml(), and switch_xml_toxml_r().

2402 {
2403  const char *e = NULL;
2404  int immune = 0;
2405  int expecting_x_utf_8_char = 0;
2406  int unicode_char = 0x000000;
2407 
2408  if (!(s && *s))
2409  return *dst;
2410 
2411  if (len) {
2412  e = s + len;
2413  }
2414 
2415  while (s != e) {
2416  while (*dlen + 10 > *max) {
2417  *dst = (char *) switch_must_realloc(*dst, *max += SWITCH_XML_BUFSIZE);
2418  }
2419 
2420  if (immune) {
2421  if (*s == '\0') {
2422  return *dst;
2423  }
2424  (*dst)[(*dlen)++] = *s;
2425  } else
2426  switch (*s) {
2427  case '\0':
2428  return *dst;
2429  case '&':
2430  *dlen += sprintf(*dst + *dlen, "&amp;");
2431  break;
2432  case '<':
2433  if (*(s + 1) == '!') {
2434  (*dst)[(*dlen)++] = *s;
2435  immune++;
2436  break;
2437  }
2438  *dlen += sprintf(*dst + *dlen, "&lt;");
2439  break;
2440  case '>':
2441  *dlen += sprintf(*dst + *dlen, "&gt;");
2442  break;
2443  case '"':
2444  *dlen += sprintf(*dst + *dlen, (a) ? "&quot;" : "\"");
2445  break;
2446  case '\n':
2447  *dlen += sprintf(*dst + *dlen, (a) ? "&#xA;" : "\n");
2448  break;
2449  case '\t':
2450  *dlen += sprintf(*dst + *dlen, (a) ? "&#x9;" : "\t");
2451  break;
2452  case '\r':
2453  *dlen += sprintf(*dst + *dlen, "&#xD;");
2454  break;
2455  default:
2456  if (USE_UTF_8_ENCODING && expecting_x_utf_8_char == 0 && ((*s >> 8) & 0x01)) {
2457  int num = 1;
2458  for (;num<4;num++) {
2459  if (! ((*s >> (7-num)) & 0x01)) {
2460  break;
2461  }
2462  }
2463  switch (num) {
2464  case 2:
2465  unicode_char = *s & 0x1f;
2466  break;
2467  case 3:
2468  unicode_char = *s & 0x0f;
2469  break;
2470  case 4:
2471  unicode_char = *s & 0x07;
2472  break;
2473  default:
2474  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid UTF-8 Initial charactere, skip it\n");
2475  /* ERROR HERE */
2476  break;
2477  }
2478  expecting_x_utf_8_char = num - 1;
2479 
2480  } else if (USE_UTF_8_ENCODING && expecting_x_utf_8_char > 0) {
2481  if (((*s >> 6) & 0x03) == 0x2) {
2482 
2483  unicode_char = unicode_char << 6;
2484  unicode_char = unicode_char | (*s & 0x3f);
2485  } else {
2486  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid UTF-8 character to ampersand, skip it\n");
2487  expecting_x_utf_8_char = 0;
2488  break;
2489  }
2490  expecting_x_utf_8_char--;
2491  if (expecting_x_utf_8_char == 0) {
2492  *dlen += sprintf(*dst + *dlen, "&#x%X;", unicode_char);
2493  }
2494  } else {
2495  (*dst)[(*dlen)++] = *s;
2496  }
2497  }
2498  s++;
2499  }
2500  return *dst;
2501 }
#define SWITCH_CHANNEL_LOG
static switch_bool_t USE_UTF_8_ENCODING
Definition: switch_xml.c:106
static void * switch_must_realloc(void *_b, size_t _z)
Definition: switch_core.h:238
#define SWITCH_XML_BUFSIZE
Definition: switch_xml.h:67
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
const char* switch_xml_attr ( switch_xml_t  xml,
const char *  attr 
)

Definition at line 434 of file switch_xml.c.

References switch_xml_root::attr, if(), switch_xml::parent, and switch_xml_root::xml.

Referenced by do_merge(), switch_xml_attr_soft(), switch_xml_find_child(), switch_xml_find_child_multi(), switch_xml_locate(), switch_xml_locate_user_merged(), switch_xml_merge_user(), switch_xml_std_datetime_check(), and switch_xml_toxml_r().

435 {
436  int i = 0, j = 1;
438 
439  if (!xml || !xml->attr)
440  return NULL;
441  while (xml->attr[i] && attr && strcmp(attr, xml->attr[i]))
442  i += 2;
443  if (xml->attr[i])
444  return xml->attr[i + 1]; /* found attribute */
445 
446  while (root->xml.parent)
447  root = (switch_xml_root_t) root->xml.parent; /* root tag */
448 
449  if (!root->attr) {
450  return NULL;
451  }
452 
453  for (i = 0; root->attr[i] && xml->name && strcmp(xml->name, root->attr[i][0]); i++);
454  if (!root->attr[i])
455  return NULL; /* no matching default attributes */
456  while (root->attr[i][j] && attr && strcmp(attr, root->attr[i][j]))
457  j += 3;
458  return (root->attr[i][j]) ? root->attr[i][j + 1] : NULL; /* found default */
459 }
char * name
Definition: switch_xml.h:78
char *** attr
Definition: switch_xml.c:157
if((uint32_t)(unpack->cur-unpack->buf) > unpack->buflen)
struct switch_xml_root * switch_xml_root_t
Definition: switch_xml.c:146
switch_xml_t parent
Definition: switch_xml.h:96
struct switch_xml xml
Definition: switch_xml.c:148
char ** attr
Definition: switch_xml.h:80
const char* switch_xml_attr_soft ( switch_xml_t  xml,
const char *  attr 
)

Definition at line 426 of file switch_xml.c.

References switch_xml_attr().

427 {
428  const char *ret = switch_xml_attr(xml, attr);
429 
430  return ret ? ret : "";
431 }
const char * switch_xml_attr(switch_xml_t xml, const char *attr)
Definition: switch_xml.c:434
switch_status_t switch_xml_bind_search_function_ret ( switch_xml_search_function_t  function,
switch_xml_section_t  sections,
void *  user_data,
switch_xml_binding_t **  ret_binding 
)

Definition at line 302 of file switch_xml.c.

References switch_xml_binding::function, switch_xml_binding::next, switch_xml_binding::sections, switch_core_alloc, SWITCH_STATUS_MEMERR, SWITCH_STATUS_SUCCESS, switch_thread_rwlock_unlock(), switch_thread_rwlock_wrlock(), and switch_xml_binding::user_data.

304 {
305  switch_xml_binding_t *binding = NULL, *ptr = NULL;
306  assert(function != NULL);
307 
308  if (!(binding = (switch_xml_binding_t *) switch_core_alloc(XML_MEMORY_POOL, sizeof(*binding)))) {
309  return SWITCH_STATUS_MEMERR;
310  }
311 
312  binding->function = function;
313  binding->sections = sections;
314  binding->user_data = user_data;
315 
317  for (ptr = BINDINGS; ptr && ptr->next; ptr = ptr->next);
318 
319  if (ptr) {
320  ptr->next = binding;
321  } else {
322  BINDINGS = binding;
323  }
324 
325  if (ret_binding) {
326  *ret_binding = binding;
327  }
328 
330 
331  return SWITCH_STATUS_SUCCESS;
332 }
static switch_xml_binding_t * BINDINGS
Definition: switch_xml.c:173
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:263
switch_xml_section_t sections
Definition: switch_xml.c:167
struct switch_xml_binding * next
Definition: switch_xml.c:169
switch_status_t switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:237
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
switch_xml_search_function_t function
Definition: switch_xml.c:166
static switch_memory_pool_t * XML_MEMORY_POOL
Definition: switch_xml.c:175
static switch_thread_rwlock_t * B_RWLOCK
Definition: switch_xml.c:177
static void switch_xml_char_content ( switch_xml_root_t  root,
char *  s,
switch_size_t  len,
char  t 
)
static

Definition at line 651 of file switch_xml.c.

References switch_xml_root::cur, switch_xml_root::ent, switch_xml::flags, switch_xml::name, switch_must_malloc(), switch_must_realloc(), switch_xml_decode(), switch_xml_set_flag(), SWITCH_XML_TXTM, and switch_xml::txt.

Referenced by switch_xml_parse_str().

652 {
654  char *m = s;
655  switch_size_t l;
656 
657  if (!root || !root->cur) {
658  return;
659  }
660 
661  xml = root->cur;
662 
663  if (!xml || !xml->name || !len)
664  return; /* sanity check */
665 
666  s[len] = '\0'; /* null terminate text (calling functions anticipate this) */
667  len = strlen(s = switch_xml_decode(s, root->ent, t)) + 1;
668 
669  if (!*(xml->txt))
670  xml->txt = s; /* initial character content */
671  else { /* allocate our own memory and make a copy */
672  if ((xml->flags & SWITCH_XML_TXTM)) { /* allocate some space */
673  xml->txt = (char *) switch_must_realloc(xml->txt, (l = strlen(xml->txt)) + len);
674  } else {
675  char *tmp = (char *) switch_must_malloc((l = strlen(xml->txt)) + len);
676 
677  xml->txt = strcpy(tmp, xml->txt);
678  }
679  strcpy(xml->txt + l, s); /* add new char content */
680  if (s != m)
681  free(s); /* free s if it was malloced by switch_xml_decode() */
682  }
683 
684  if (xml->txt != m)
686 }
char * name
Definition: switch_xml.h:78
switch_xml_t switch_xml_set_flag(switch_xml_t xml, switch_xml_flag_t flag)
sets a flag for the given tag and returns the tag
Definition: switch_xml.c:2934
switch_xml_t xml
Definition: switch_xml.c:2179
static void * switch_must_malloc(size_t _b)
Definition: switch_core.h:231
A representation of an XML tree.
Definition: switch_xml.h:76
char * txt
Definition: switch_xml.h:82
static void * switch_must_realloc(void *_b, size_t _z)
Definition: switch_core.h:238
uintptr_t switch_size_t
switch_xml_t cur
Definition: switch_xml.c:149
uint32_t flags
Definition: switch_xml.h:98
static char * switch_xml_decode(char *s, char **ent, char t)
Definition: switch_xml.c:538
switch_xml_t switch_xml_child ( switch_xml_t  xml,
const char *  name 
)

Definition at line 409 of file switch_xml.c.

References switch_xml::child, and while().

Referenced by do_merge(), switch_xml_find_child(), switch_xml_find_child_multi(), switch_xml_locate(), switch_xml_locate_group(), switch_xml_locate_language(), switch_xml_locate_user(), switch_xml_locate_user_in_domain(), and switch_xml_vget().

410 {
411  xml = (xml) ? xml->child : NULL;
412  while (xml && strcmp(name, xml->name))
413  xml = xml->sibling;
414  return xml;
415 }
switch_xml_t sibling
Definition: switch_xml.h:90
char * name
Definition: switch_xml.h:78
switch_xml_t child
Definition: switch_xml.h:94
switch_xml_t xml
Definition: switch_xml.c:2179
while(unpack->bits_cur<=SWITCH_BITS_PER_BYTE)
static switch_xml_t switch_xml_close_tag ( switch_xml_root_t  root,
char *  name,
char *  s 
)
static

Definition at line 689 of file switch_xml.c.

References switch_xml_root::cur, switch_xml::name, switch_xml::parent, and switch_xml_err().

Referenced by switch_xml_parse_str().

690 {
691  if (!root || !root->cur || !root->cur->name || strcmp(name, root->cur->name))
692  return switch_xml_err(root, s, "unexpected closing tag </%s>", name);
693 
694  root->cur = root->cur->parent;
695  return NULL;
696 }
char * name
Definition: switch_xml.h:78
switch_xml_t parent
Definition: switch_xml.h:96
switch_xml_t cur
Definition: switch_xml.c:149
static switch_xml_t switch_xml_err(switch_xml_root_t root, char *s, const char *err,...)
Definition: switch_xml.c:510
switch_xml_t switch_xml_cut ( switch_xml_t  xml)

Definition at line 2942 of file switch_xml.c.

References switch_xml::child, cur, switch_xml::name, switch_xml::next, switch_xml::ordered, switch_xml::parent, switch_xml::sibling, and destroy_xml::xml.

2943 {
2944  switch_xml_t cur;
2945 
2946  if (!xml)
2947  return NULL; /* nothing to do */
2948  if (xml->next)
2949  xml->next->sibling = xml->sibling; /* patch sibling list */
2950 
2951  if (xml->parent) { /* not root tag */
2952  cur = xml->parent->child; /* find head of subtag list */
2953  if (cur == xml)
2954  xml->parent->child = xml->ordered; /* first subtag */
2955  else { /* not first subtag */
2956  while (cur->ordered != xml)
2957  cur = cur->ordered;
2958  cur->ordered = cur->ordered->ordered; /* patch ordered list */
2959 
2960  cur = xml->parent->child; /* go back to head of subtag list */
2961  if (strcmp(cur->name, xml->name)) { /* not in first sibling list */
2962  while (strcmp(cur->sibling->name, xml->name))
2963  cur = cur->sibling;
2964  if (cur->sibling == xml) { /* first of a sibling list */
2965  cur->sibling = (xml->next) ? xml->next : cur->sibling->sibling;
2966  } else
2967  cur = cur->sibling; /* not first of a sibling list */
2968  }
2969 
2970  while (cur->next && cur->next != xml)
2971  cur = cur->next;
2972  if (cur->next)
2973  cur->next = cur->next->next; /* patch next list */
2974  }
2975  }
2976  xml->ordered = xml->sibling = xml->next = NULL; /* prevent switch_xml_free() from clobbering ordered list */
2977  return xml;
2978 }
switch_xml_t sibling
Definition: switch_xml.h:90
char * name
Definition: switch_xml.h:78
switch_xml_t child
Definition: switch_xml.h:94
switch_xml_t xml
Definition: switch_xml.c:2179
A representation of an XML tree.
Definition: switch_xml.h:76
pack cur
switch_xml_t next
Definition: switch_xml.h:88
switch_xml_t ordered
Definition: switch_xml.h:92
switch_xml_t parent
Definition: switch_xml.h:96
static char* switch_xml_decode ( char *  s,
char **  ent,
char  t 
)
static

Definition at line 538 of file switch_xml.c.

References switch_must_malloc(), and switch_must_realloc().

Referenced by switch_xml_char_content(), switch_xml_internal_dtd(), and switch_xml_parse_str().

539 {
540  char *e, *r = s, *m = s;
541  unsigned long b, c, d, l;
542 
543  for (; *s; s++) { /* normalize line endings */
544  while (*s == '\r') {
545  *(s++) = '\n';
546  if (*s == '\n')
547  memmove(s, (s + 1), strlen(s));
548  }
549  }
550 
551  for (s = r;;) {
552  while (*s && *s != '&' && (*s != '%' || t != '%') && !isspace((unsigned char) (*s)))
553  s++;
554 
555  if (!*s)
556  break;
557  else if (t != 'c' && !strncmp(s, "&#", 2)) { /* character reference */
558  char *code = s + 2;
559  int base = 10;
560  if (*code == 'x') {
561  code++;
562  base = 16;
563  }
564  if (!isxdigit((int)*code)) { /* "&# 1;" and "&#-1;" are invalid */
565  s++;
566  continue;
567  }
568  c = strtoul(code, &e, base);
569  if (!c || *e != ';') {
570  s++;
571  continue;
572  }
573  /* not a character ref */
574  if (c < 0x80)
575  *(s++) = (char) c; /* US-ASCII subset */
576  else if (c > 0x7FFFFFFF) { /* out of UTF-8 range */
577  s++;
578  continue;
579  } else { /* multi-byte UTF-8 sequence */
580  for (b = 0, d = c; d; d /= 2)
581  b++; /* number of bits in c */
582  b = (b - 2) / 5; /* number of bytes in payload */
583  assert(b < 7); /* because c <= 0x7FFFFFFF */
584  *(s++) = (char) ((0xFF << (7 - b)) | (c >> (6 * b))); /* head */
585  while (b)
586  *(s++) = (char) (0x80 | ((c >> (6 * --b)) & 0x3F)); /* payload */
587  }
588 
589  memmove(s, strchr(s, ';') + 1, strlen(strchr(s, ';')));
590  } else if ((*s == '&' && (t == '&' || t == ' ' || t == '*')) || (*s == '%' && t == '%')) { /* entity reference */
591  for (b = 0; ent[b] && strncmp(s + 1, ent[b], strlen(ent[b])); b += 2); /* find entity in entity list */
592 
593  if (ent[b++]) { /* found a match */
594  if ((c = (unsigned long) strlen(ent[b])) - 1 > (e = strchr(s, ';')) - s) {
595  l = (d = (unsigned long) (s - r)) + c + (unsigned long) strlen(e); /* new length */
596  if (l) {
597  if (r == m) {
598  char *tmp = (char *) switch_must_malloc(l);
599  r = strcpy(tmp, r);
600  } else {
601  r = (char *) switch_must_realloc(r, l);
602  }
603  }
604  e = strchr((s = r + d), ';'); /* fix up pointers */
605  }
606 
607  memmove(s + c, e + 1, strlen(e)); /* shift rest of string */
608  strncpy(s, ent[b], c); /* copy in replacement text */
609  } else
610  s++; /* not a known entity */
611  } else if ((t == ' ' || t == '*') && isspace((int) (*s)))
612  *(s++) = ' ';
613  else
614  s++; /* no decoding needed */
615  }
616 
617  if (t == '*') { /* normalize spaces for non-cdata attributes */
618  for (s = r; *s; s++) {
619  if ((l = (unsigned long) strspn(s, " ")))
620  memmove(s, s + l, strlen(s + l) + 1);
621  while (*s && *s != ' ')
622  s++;
623  }
624  if (--s >= r && *s == ' ')
625  *s = '\0'; /* trim any trailing space */
626  }
627  return r;
628 }
static void * switch_must_malloc(size_t _b)
Definition: switch_core.h:231
static void * switch_must_realloc(void *_b, size_t _z)
Definition: switch_core.h:238
static int switch_xml_ent_ok ( char *  name,
char *  s,
char **  ent 
)
static

Definition at line 700 of file switch_xml.c.

Referenced by switch_xml_internal_dtd().

701 {
702  int i;
703 
704  for (;; s++) {
705  while (*s && *s != '&')
706  s++; /* find next entity reference */
707  if (!*s)
708  return 1;
709  if (!strncmp(s + 1, name, strlen(name)))
710  return 0; /* circular ref. */
711  for (i = 0; ent[i] && strncmp(ent[i], s + 1, strlen(ent[i])); i += 2);
712  if (ent[i] && !switch_xml_ent_ok(name, ent[i + 1], ent))
713  return 0;
714  }
715 }
static int switch_xml_ent_ok(char *name, char *s, char **ent)
Definition: switch_xml.c:700
static switch_xml_t switch_xml_err ( switch_xml_root_t  root,
char *  s,
const char *  err,
  ... 
)
static

Definition at line 510 of file switch_xml.c.

References switch_xml_root::err, switch_xml_root::s, switch_snprintf(), SWITCH_XML_ERRL, and switch_xml_root::xml.

Referenced by switch_xml_close_tag(), switch_xml_internal_dtd(), and switch_xml_parse_str().

511 {
512  va_list ap;
513  int line = 1;
514  char *t, fmt[SWITCH_XML_ERRL];
515 
516  if (!root || !root->s) {
517  return NULL;
518  }
519 
520  for (t = root->s; t && t < s; t++)
521  if (*t == '\n')
522  line++;
523  switch_snprintf(fmt, SWITCH_XML_ERRL, "[error near line %d]: %s", line, err);
524 
525  va_start(ap, err);
526  vsnprintf(root->err, SWITCH_XML_ERRL, fmt, ap);
527  va_end(ap);
528 
529  return &root->xml;
530 }
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
struct switch_xml xml
Definition: switch_xml.c:148
char err[SWITCH_XML_ERRL]
Definition: switch_xml.c:160
#define SWITCH_XML_ERRL
Definition: switch_xml.c:103
const char* switch_xml_error ( switch_xml_t  xml)

Definition at line 2786 of file switch_xml.c.

Referenced by __switch_xml_open_root(), and switch_xml_locate().

2787 {
2788  while (xml && xml->parent)
2789  xml = xml->parent; /* find root tag */
2790  return (xml) ? ((switch_xml_root_t) xml)->err : "";
2791 }
struct switch_xml_root * switch_xml_root_t
Definition: switch_xml.c:146
switch_xml_t parent
Definition: switch_xml.h:96
switch_xml_t switch_xml_find_child ( switch_xml_t  node,
const char *  childname,
const char *  attrname,
const char *  value 
)

Definition at line 334 of file switch_xml.c.

References switch_xml::next, switch_xml_attr(), and switch_xml_child().

Referenced by switch_xml_locate(), switch_xml_locate_group(), and switch_xml_locate_language().

335 {
336  switch_xml_t p = NULL;
337 
338  if (!(childname && attrname && value)) {
339  return node;
340  }
341 
342  for (p = switch_xml_child(node, childname); p; p = p->next) {
343  const char *aname = switch_xml_attr(p, attrname);
344  if (aname && value && !strcasecmp(aname, value)) {
345  break;
346  }
347  }
348 
349  return p;
350 }
const char * switch_xml_attr(switch_xml_t xml, const char *attr)
Definition: switch_xml.c:434
A representation of an XML tree.
Definition: switch_xml.h:76
switch_xml_t next
Definition: switch_xml.h:88
switch_xml_t switch_xml_child(switch_xml_t xml, const char *name)
Definition: switch_xml.c:409
switch_xml_t switch_xml_find_child_multi ( switch_xml_t  node,
const char *  childname,
  ... 
)

Definition at line 352 of file switch_xml.c.

References switch_xml::next, switch_xml_attr(), and switch_xml_child().

Referenced by find_user_in_tag().

353 {
354  switch_xml_t p = NULL;
355  const char *names[256] = { 0 };
356  const char *vals[256] = { 0 };
357  int x, i = 0;
358  va_list ap;
359  const char *attrname, *value = NULL;
360 
361  va_start(ap, childname);
362 
363  while (i < 255) {
364  if ((attrname = va_arg(ap, const char *))) {
365  value = va_arg(ap, const char *);
366  }
367  if (attrname && value) {
368  names[i] = attrname;
369  vals[i] = value;
370  } else {
371  break;
372  }
373  i++;
374  }
375 
376  va_end(ap);
377 
378  if (!(childname && i)) {
379  return node;
380  }
381 
382  for (p = switch_xml_child(node, childname); p; p = p->next) {
383  for (x = 0; x < i; x++) {
384  if (names[x] && vals[x]) {
385  const char *aname = switch_xml_attr(p, names[x]);
386 
387  if (aname) {
388  if (*vals[x] == '!') {
389  const char *sval = vals[x] + 1;
390  if (sval && strcasecmp(aname, sval)) {
391  goto done;
392  }
393  } else {
394  if (!strcasecmp(aname, vals[x])) {
395  goto done;
396  }
397  }
398  }
399  }
400  }
401  }
402 
403  done:
404 
405  return p;
406 }
const char * switch_xml_attr(switch_xml_t xml, const char *attr)
Definition: switch_xml.c:434
A representation of an XML tree.
Definition: switch_xml.h:76
switch_xml_t next
Definition: switch_xml.h:88
switch_xml_t switch_xml_child(switch_xml_t xml, const char *name)
Definition: switch_xml.c:409
void switch_xml_free ( switch_xml_t  xml)

Definition at line 2701 of file switch_xml.c.

References switch_xml_root::attr, switch_xml_root::dynamic, switch_xml_root::e, switch_xml_root::ent, switch_xml_root::m, switch_xml::ordered, switch_xml_root::pi, switch_xml_root::s, SWITCH_CHANNEL_LOG, switch_log_printf(), SWITCH_LOG_WARNING, switch_mutex_lock(), switch_mutex_unlock(), switch_safe_free, switch_test_flag, switch_xml_free_attr(), SWITCH_XML_NAMEM, SWITCH_XML_ROOT, SWITCH_XML_TXTM, switch_xml_root::u, and destroy_xml::xml.

Referenced by __switch_xml_open_root(), destroy_thread(), switch_xml_clear_user_cache(), switch_xml_destroy(), switch_xml_init(), switch_xml_locate(), switch_xml_locate_language(), switch_xml_locate_user(), switch_xml_locate_user_merged(), switch_xml_reload(), switch_xml_set_root(), and switch_xml_user_cache().

2702 {
2703  switch_xml_root_t root;
2704  int i, j;
2705  char **a, *s;
2706  switch_xml_t orig_xml;
2707  int refs = 0;
2708 
2709  tailrecurse:
2710  root = (switch_xml_root_t) xml;
2711  if (!xml) {
2712  return;
2713  }
2714 
2715  if (switch_test_flag(xml, SWITCH_XML_ROOT)) {
2717 
2718  if (xml->refs) {
2719  xml->refs--;
2720  refs = xml->refs;
2721  }
2723  }
2724 
2725  if (refs) {
2726  return;
2727  }
2728 
2729  if (xml->free_path) {
2730  if (unlink(xml->free_path) != 0) {
2731  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to delete file [%s]\n", xml->free_path);
2732  }
2734  }
2735 
2736  switch_xml_free(xml->child);
2737  /*switch_xml_free(xml->ordered); */
2738 
2739  if (!xml->parent) { /* free root tag allocations */
2740 #if (_MSC_VER >= 1400) // VC8+
2741  __analysis_assume(sizeof(root->ent) > 44); /* tail recursion confuses code analysis */
2742 #endif
2743  for (i = 10; root->ent[i]; i += 2) /* 0 - 9 are default entities (<>&"') */
2744  if ((s = root->ent[i + 1]) < root->s || s > root->e)
2745  free(s);
2746  free(root->ent); /* free list of general entities */
2747 
2748  for (i = 0; (a = root->attr[i]); i++) {
2749  for (j = 1; a[j++]; j += 2) /* free malloced attribute values */
2750  if (a[j] && (a[j] < root->s || a[j] > root->e))
2751  free(a[j]);
2752  free(a);
2753  }
2754  if (root->attr[0])
2755  free(root->attr); /* free default attribute list */
2756 
2757  for (i = 0; root->pi[i]; i++) {
2758  for (j = 1; root->pi[i][j]; j++);
2759  free(root->pi[i][j + 1]);
2760  free(root->pi[i]);
2761  }
2762  if (root->pi[0])
2763  free(root->pi); /* free processing instructions */
2764 
2765  if (root->dynamic == 1)
2766  free(root->m); /* malloced xml data */
2767  if (root->u)
2768  free(root->u); /* utf8 conversion */
2769  }
2770 
2771  switch_xml_free_attr(xml->attr); /* tag attributes */
2772  if ((xml->flags & SWITCH_XML_TXTM))
2773  free(xml->txt); /* character content */
2774  if ((xml->flags & SWITCH_XML_NAMEM))
2775  free(xml->name); /* tag name */
2776  if (xml->ordered) {
2777  orig_xml = xml;
2778  xml = xml->ordered;
2779  free(orig_xml);
2780  goto tailrecurse;
2781  }
2782  free(xml);
2783 }
uint32_t refs
Definition: switch_xml.h:101
char * name
Definition: switch_xml.h:78
#define SWITCH_CHANNEL_LOG
switch_xml_t child
Definition: switch_xml.h:94
char *** attr
Definition: switch_xml.c:157
static void switch_xml_free_attr(char **attr)
Definition: switch_xml.c:942
switch_xml_t xml
Definition: switch_xml.c:2179
static switch_mutex_t * REFLOCK
Definition: switch_xml.c:180
A representation of an XML tree.
Definition: switch_xml.h:76
char * txt
Definition: switch_xml.h:82
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
struct switch_xml_root * switch_xml_root_t
Definition: switch_xml.c:146
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
switch_xml_t ordered
Definition: switch_xml.h:92
switch_xml_t parent
Definition: switch_xml.h:96
char * free_path
Definition: switch_xml.h:84
char ** attr
Definition: switch_xml.h:80
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
uint8_t dynamic
Definition: switch_xml.c:152
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
uint32_t flags
Definition: switch_xml.h:98
void switch_xml_free(switch_xml_t xml)
Definition: switch_xml.c:2701
static void switch_xml_free_attr ( char **  attr)
static

Definition at line 942 of file switch_xml.c.

References SWITCH_XML_NAMEM, and SWITCH_XML_TXTM.

Referenced by switch_xml_free(), and switch_xml_parse_str().

943 {
944  int i = 0;
945  char *m;
946 
947  if (!attr || attr == SWITCH_XML_NIL)
948  return; /* nothing to free */
949  while (attr[i])
950  i += 2; /* find end of attribute list */
951  m = attr[i + 1]; /* list of which names and values are malloced */
952  for (i = 0; m[i]; i++) {
953  if (m[i] & SWITCH_XML_NAMEM)
954  free(attr[i * 2]);
955  if (m[i] & SWITCH_XML_TXTM)
956  free(attr[(i * 2) + 1]);
957  }
958  free(m);
959  free(attr);
960 }
char * SWITCH_XML_NIL[]
Definition: switch_xml.c:163
void switch_xml_free_in_thread ( switch_xml_t  xml,
int  stacksize 
)

Definition at line 2192 of file switch_xml.c.

References destroy_thread(), pool, destroy_xml::pool, switch_core_alloc, switch_core_new_memory_pool, switch_thread_create(), switch_threadattr_create(), switch_threadattr_detach_set(), switch_threadattr_stacksize_set(), thread, and destroy_xml::xml.

2193 {
2195  switch_threadattr_t *thd_attr;
2196  switch_memory_pool_t *pool = NULL;
2197  struct destroy_xml *dx;
2198 
2200 
2201  switch_threadattr_create(&thd_attr, pool);
2202  switch_threadattr_detach_set(thd_attr, 1);
2203  /* TBD figure out how much space we need by looking at the xml_t when stacksize == 0 */
2204  switch_threadattr_stacksize_set(thd_attr, stacksize);
2205 
2206  dx = switch_core_alloc(pool, sizeof(*dx));
2207  dx->pool = pool;
2208  dx->xml = xml;
2209 
2210  switch_thread_create(&thread, thd_attr, destroy_thread, dx, pool);
2211 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:660
switch_xml_t xml
Definition: switch_xml.c:2179
switch_memory_pool_t * pool
static switch_thread_t * thread
Definition: switch_log.c:279
switch_status_t switch_threadattr_detach_set(switch_threadattr_t *attr, int32_t on)
Definition: switch_apr.c:655
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
switch_memory_pool_t * pool
Definition: switch_xml.c:2180
static void *SWITCH_THREAD_FUNC destroy_thread(switch_thread_t *thread, void *obj)
Definition: switch_xml.c:2183
struct apr_thread_t switch_thread_t
Definition: switch_apr.h:941
struct apr_pool_t switch_memory_pool_t
switch_status_t switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool)
Definition: switch_apr.c:642
switch_status_t switch_thread_create(switch_thread_t **new_thread, switch_threadattr_t *attr, switch_thread_start_t func, void *data, switch_memory_pool_t *cont)
Definition: switch_apr.c:675
switch_xml_t switch_xml_get ( switch_xml_t  xml,
  ... 
)

Definition at line 480 of file switch_xml.c.

References switch_xml_vget().

481 {
482  va_list ap;
483  switch_xml_t r;
484 
485  va_start(ap, xml);
486  r = switch_xml_vget(xml, ap);
487  va_end(ap);
488  return r;
489 }
A representation of an XML tree.
Definition: switch_xml.h:76
static switch_xml_t switch_xml_vget(switch_xml_t xml, va_list ap)
Definition: switch_xml.c:462
switch_xml_section_t switch_xml_get_binding_sections ( switch_xml_binding_t binding)

Definition at line 292 of file switch_xml.c.

293 {
294  return binding->sections;
295 }
switch_xml_section_t sections
Definition: switch_xml.c:167
void* switch_xml_get_binding_user_data ( switch_xml_binding_t binding)

Definition at line 297 of file switch_xml.c.

298 {
299  return binding->user_data;
300 }
switch_xml_t switch_xml_idx ( switch_xml_t  xml,
int  idx 
)

Definition at line 418 of file switch_xml.c.

References switch_xml::next.

Referenced by switch_xml_vget().

419 {
420  for (; xml && idx; idx--)
421  xml = xml->next;
422  return xml;
423 }
switch_xml_t next
Definition: switch_xml.h:88
switch_status_t switch_xml_init ( switch_memory_pool_t pool,
const char **  err 
)

Definition at line 2333 of file switch_xml.c.

References CACHE_EXPIRES_HASH, CACHE_HASH, FALSE, pool, switch_core_hash_init, switch_mutex_init(), SWITCH_MUTEX_NESTED, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_thread_rwlock_create(), switch_xml_free(), switch_xml_open_root(), and destroy_xml::xml.

2334 {
2335  switch_xml_t xml;
2337  *err = "Success";
2338 
2345 
2347 
2348  assert(pool != NULL);
2349 
2350  if ((xml = switch_xml_open_root(FALSE, err))) {
2351  switch_xml_free(xml);
2352  return SWITCH_STATUS_SUCCESS;
2353  } else {
2354  return SWITCH_STATUS_FALSE;
2355  }
2356 }
#define switch_core_hash_init(_hash)
Definition: switch_core.h:1390
switch_xml_t xml
Definition: switch_xml.c:2179
switch_memory_pool_t * pool
switch_xml_t switch_xml_open_root(uint8_t reload, const char **err)
Definition: switch_xml.c:2256
static switch_mutex_t * REFLOCK
Definition: switch_xml.c:180
A representation of an XML tree.
Definition: switch_xml.h:76
static switch_hash_t * CACHE_HASH
Definition: switch_xml.c:188
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
static switch_hash_t * CACHE_EXPIRES_HASH
Definition: switch_xml.c:189
#define FALSE
switch_status_t switch_thread_rwlock_create(switch_thread_rwlock_t **rwlock, switch_memory_pool_t *pool)
Definition: switch_apr.c:212
static switch_mutex_t * CACHE_MUTEX
Definition: switch_xml.c:179
static switch_mutex_t * XML_LOCK
Definition: switch_xml.c:178
void switch_xml_free(switch_xml_t xml)
Definition: switch_xml.c:2701
static switch_mutex_t * FILE_LOCK
Definition: switch_xml.c:181
static switch_memory_pool_t * XML_MEMORY_POOL
Definition: switch_xml.c:175
static switch_thread_rwlock_t * B_RWLOCK
Definition: switch_xml.c:177
switch_xml_t switch_xml_insert ( switch_xml_t  xml,
switch_xml_t  dest,
switch_size_t  off 
)

Definition at line 2811 of file switch_xml.c.

References switch_xml::child, cur, switch_xml::name, switch_xml::next, switch_xml::off, switch_xml::ordered, switch_xml::sibling, and destroy_xml::xml.

Referenced by switch_xml_add_child().

2812 {
2813  switch_xml_t cur, prev, head;
2814 
2815  xml->next = xml->sibling = xml->ordered = NULL;
2816  xml->off = off;
2817  xml->parent = dest;
2818 
2819  if ((head = dest->child)) { /* already have sub tags */
2820  if (head->off <= off) { /* not first subtag */
2821  for (cur = head; cur->ordered && cur->ordered->off <= off; cur = cur->ordered);
2822  xml->ordered = cur->ordered;
2823  cur->ordered = xml;
2824  } else { /* first subtag */
2825  xml->ordered = head;
2826  dest->child = xml;
2827  }
2828 
2829  for (cur = head, prev = NULL; cur && strcmp(cur->name, xml->name); prev = cur, cur = cur->sibling); /* find tag type */
2830  if (cur && cur->off <= off) { /* not first of type */
2831  while (cur->next && cur->next->off <= off)
2832  cur = cur->next;
2833  xml->next = cur->next;
2834  cur->next = xml;
2835  } else { /* first tag of this type */
2836  if (prev && cur)
2837  prev->sibling = cur->sibling; /* remove old first */
2838  xml->next = cur; /* old first tag is now next */
2839  for (cur = head, prev = NULL; cur && cur->off <= off; prev = cur, cur = cur->sibling); /* new sibling insert point */
2840  xml->sibling = cur;
2841  if (prev)
2842  prev->sibling = xml;
2843  }
2844  } else
2845  dest->child = xml; /* only sub tag */
2846 
2847  return xml;
2848 }
switch_xml_t sibling
Definition: switch_xml.h:90
char * name
Definition: switch_xml.h:78
switch_size_t off
Definition: switch_xml.h:86
switch_xml_t child
Definition: switch_xml.h:94
switch_xml_t xml
Definition: switch_xml.c:2179
A representation of an XML tree.
Definition: switch_xml.h:76
pack cur
switch_xml_t next
Definition: switch_xml.h:88
switch_xml_t ordered
Definition: switch_xml.h:92
switch_xml_t parent
Definition: switch_xml.h:96
static short switch_xml_internal_dtd ( switch_xml_root_t  root,
char *  s,
switch_size_t  len 
)
static

Definition at line 771 of file switch_xml.c.

References switch_xml_root::attr, switch_xml_root::ent, switch_xml_root::err, switch_xml_root::standalone, switch_must_malloc(), switch_must_realloc(), switch_xml_decode(), switch_xml_ent_ok(), switch_xml_err(), SWITCH_XML_NIL, switch_xml_proc_inst(), and SWITCH_XML_WS.

Referenced by switch_xml_parse_str().

772 {
773  char q, *c, *t, *n = NULL, *v, **ent, **pe;
774  int i, j;
775  char **sstmp;
776 
777  pe = (char **) memcpy(switch_must_malloc(sizeof(SWITCH_XML_NIL)), SWITCH_XML_NIL, sizeof(SWITCH_XML_NIL));
778 
779  for (s[len] = '\0'; s;) {
780  while (*s && *s != '<' && *s != '%')
781  s++; /* find next declaration */
782 
783  if (!*s)
784  break;
785  else if (!strncmp(s, "<!ENTITY", 8)) { /* parse entity definitions */
786  c = s += strspn(s + 8, SWITCH_XML_WS) + 8; /* skip white space separator */
787  n = s + strspn(s, SWITCH_XML_WS "%"); /* find name */
788  *(s = n + strcspn(n, SWITCH_XML_WS)) = ';'; /* append ; to name */
789 
790  v = s + strspn(s + 1, SWITCH_XML_WS) + 1; /* find value */
791  if ((q = *(v++)) != '"' && q != '\'') { /* skip externals */
792  s = strchr(s, '>');
793  continue;
794  }
795 
796  for (i = 0, ent = (*c == '%') ? pe : root->ent; ent[i]; i++);
797  sstmp = (char **) switch_must_realloc(ent, (i + 3) * sizeof(char *)); /* space for next ent */
798  ent = sstmp;
799  if (*c == '%')
800  pe = ent;
801  else
802  root->ent = ent;
803 
804  *(++s) = '\0'; /* null terminate name */
805  if ((s = strchr(v, q)))
806  *(s++) = '\0'; /* null terminate value */
807  ent[i + 1] = switch_xml_decode(v, pe, '%'); /* set value */
808  ent[i + 2] = NULL; /* null terminate entity list */
809  if (!switch_xml_ent_ok(n, ent[i + 1], ent)) { /* circular reference */
810  if (ent[i + 1] != v)
811  free(ent[i + 1]);
812  switch_xml_err(root, v, "circular entity declaration &%s", n);
813  break;
814  } else
815  ent[i] = n; /* set entity name */
816  } else if (!strncmp(s, "<!ATTLIST", 9)) { /* parse default attributes */
817  t = s + strspn(s + 9, SWITCH_XML_WS) + 9; /* skip whitespace separator */
818  if (!*t) {
819  switch_xml_err(root, t, "unclosed <!ATTLIST");
820  break;
821  }
822  if (*(s = t + strcspn(t, SWITCH_XML_WS ">")) == '>')
823  continue;
824  else
825  *s = '\0'; /* null terminate tag name */
826  for (i = 0; root->attr[i] && strcmp(n, root->attr[i][0]); i++);
827 
828  //while (*(n = ++s + strspn(s, SWITCH_XML_WS)) && *n != '>') {
829  // gcc 4.4 you are a creep
830  for (;;) {
831  s++;
832  if (!(*(n = s + strspn(s, SWITCH_XML_WS)) && *n != '>')) {
833  break;
834  }
835  if (*(s = n + strcspn(n, SWITCH_XML_WS)))
836  *s = '\0'; /* attr name */
837  else {
838  switch_xml_err(root, t, "malformed <!ATTLIST");
839  break;
840  }
841 
842  s += strspn(s + 1, SWITCH_XML_WS) + 1; /* find next token */
843  c = (strncmp(s, "CDATA", 5)) ? (char *) "*" : (char *) " "; /* is it cdata? */
844  if (!strncmp(s, "NOTATION", 8))
845  s += strspn(s + 8, SWITCH_XML_WS) + 8;
846  s = (*s == '(') ? strchr(s, ')') : s + strcspn(s, SWITCH_XML_WS);
847  if (!s) {
848  switch_xml_err(root, t, "malformed <!ATTLIST");
849  break;
850  }
851 
852  s += strspn(s, SWITCH_XML_WS ")"); /* skip white space separator */
853  if (!strncmp(s, "#FIXED", 6))
854  s += strspn(s + 6, SWITCH_XML_WS) + 6;
855  if (*s == '#') { /* no default value */
856  s += strcspn(s, SWITCH_XML_WS ">") - 1;
857  if (*c == ' ')
858  continue; /* cdata is default, nothing to do */
859  v = NULL;
860  } else if ((*s == '"' || *s == '\'') && /* default value */
861  (s = strchr(v = s + 1, *s)))
862  *s = '\0';
863  else {
864  switch_xml_err(root, t, "malformed <!ATTLIST");
865  break;
866  }
867 
868  if (!root->attr[i]) { /* new tag name */
869  root->attr = (!i) ? (char ***) switch_must_malloc(2 * sizeof(char **))
870  : (char ***) switch_must_realloc(root->attr, (i + 2) * sizeof(char **));
871  root->attr[i] = (char **) switch_must_malloc(2 * sizeof(char *));
872  root->attr[i][0] = t; /* set tag name */
873  root->attr[i][1] = (char *) (root->attr[i + 1] = NULL);
874  }
875 
876  for (j = 1; root->attr[i][j]; j += 3); /* find end of list */
877  sstmp = (char **) switch_must_realloc(root->attr[i], (j + 4) * sizeof(char *));
878 
879  root->attr[i] = sstmp;
880  root->attr[i][j + 3] = NULL; /* null terminate list */
881  root->attr[i][j + 2] = c; /* is it cdata? */
882  root->attr[i][j + 1] = (v) ? switch_xml_decode(v, root->ent, *c) : NULL;
883  root->attr[i][j] = n; /* attribute name */
884  }
885  } else if (!strncmp(s, "<!--", 4))
886  s = strstr(s + 4, "-->"); /* comments */
887  else if (!strncmp(s, "<?", 2)) { /* processing instructions */
888  if ((s = strstr(c = s + 2, "?>")))
889  switch_xml_proc_inst(root, c, s++ - c);
890  } else if (*s == '<')
891  s = strchr(s, '>'); /* skip other declarations */
892  else if (*(s++) == '%' && !root->standalone)
893  break;
894  }
895 
896  free(pe);
897  return !*root->err;
898 }
char *** attr
Definition: switch_xml.c:157
static void * switch_must_malloc(size_t _b)
Definition: switch_core.h:231
static void switch_xml_proc_inst(switch_xml_root_t root, char *s, switch_size_t len)
Definition: switch_xml.c:718
#define SWITCH_XML_WS
Definition: switch_xml.c:102
static void * switch_must_realloc(void *_b, size_t _z)
Definition: switch_core.h:238
char err[SWITCH_XML_ERRL]
Definition: switch_xml.c:160
static int switch_xml_ent_ok(char *name, char *s, char **ent)
Definition: switch_xml.c:700
static char * switch_xml_decode(char *s, char **ent, char t)
Definition: switch_xml.c:538
static switch_xml_t switch_xml_err(switch_xml_root_t root, char *s, const char *err,...)
Definition: switch_xml.c:510
char * SWITCH_XML_NIL[]
Definition: switch_xml.c:163
switch_status_t switch_xml_locate ( const char *  section,
const char *  tag_name,
const char *  key_name,
const char *  key_value,
switch_xml_t root,
switch_xml_t node,
switch_event_t params,
switch_bool_t  clone 
)

Definition at line 1655 of file switch_xml.c.

References switch_xml_binding::function, switch_xml_binding::next, switch_xml_binding::sections, switch_assert, SWITCH_CHANNEL_LOG, SWITCH_FALSE, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_thread_rwlock_rdlock(), switch_thread_rwlock_unlock(), switch_xml_attr(), switch_xml_child(), switch_xml_error(), switch_xml_find_child(), switch_xml_free(), switch_xml_parse_section_string(), switch_xml_parse_str_dynamic(), switch_xml_root(), switch_xml_toxml(), switch_xml_binding::user_data, and zstr.

Referenced by switch_xml_locate_domain(), switch_xml_locate_language(), and switch_xml_open_cfg().

1660 {
1661  switch_xml_t conf = NULL;
1662  switch_xml_t tag = NULL;
1663  switch_xml_t xml = NULL;
1664  switch_xml_binding_t *binding;
1665  uint8_t loops = 0;
1667 
1669 
1670  for (binding = BINDINGS; binding; binding = binding->next) {
1671  if (binding->sections && !(sections & binding->sections)) {
1672  continue;
1673  }
1674 
1675  if ((xml = binding->function(section, tag_name, key_name, key_value, params, binding->user_data))) {
1676  const char *err = NULL;
1677 
1678  err = switch_xml_error(xml);
1679  if (zstr(err)) {
1680  if ((conf = switch_xml_find_child(xml, "section", "name", "result"))) {
1681  switch_xml_t p;
1682  const char *aname;
1683 
1684  if ((p = switch_xml_child(conf, "result"))) {
1685  aname = switch_xml_attr(p, "status");
1686  if (aname && !strcasecmp(aname, "not found")) {
1687  switch_xml_free(xml);
1688  xml = NULL;
1689  continue;
1690  }
1691  }
1692  }
1693  break;
1694  } else {
1696  switch_xml_free(xml);
1697  xml = NULL;
1698  }
1699  }
1700  }
1702 
1703  for (;;) {
1704  if (!xml) {
1705  if (!(xml = switch_xml_root())) {
1706  *node = NULL;
1707  *root = NULL;
1708  return SWITCH_STATUS_FALSE;
1709  }
1710  }
1711 
1712  if ((conf = switch_xml_find_child(xml, "section", "name", section)) && (tag = switch_xml_find_child(conf, tag_name, key_name, key_value))) {
1713  if (clone) {
1714  char *x = switch_xml_toxml(tag, SWITCH_FALSE);
1715  switch_assert(x);
1716  *node = *root = switch_xml_parse_str_dynamic(x, SWITCH_FALSE); /* x will be free()'d in switch_xml_free() */
1717  switch_xml_free(xml);
1718  } else {
1719  *node = tag;
1720  *root = xml;
1721  }
1722  return SWITCH_STATUS_SUCCESS;
1723  } else {
1724  switch_xml_free(xml);
1725  xml = NULL;
1726  *node = NULL;
1727  *root = NULL;
1728  if (loops++ > 1) {
1729  break;
1730  }
1731  }
1732  }
1733 
1734  return SWITCH_STATUS_FALSE;
1735 }
static switch_xml_binding_t * BINDINGS
Definition: switch_xml.c:173
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:263
#define SWITCH_CHANNEL_LOG
const char * switch_xml_attr(switch_xml_t xml, const char *attr)
Definition: switch_xml.c:434
switch_xml_t switch_xml_root(void)
retrieve the core XML root node
Definition: switch_xml.c:2166
switch_xml_t xml
Definition: switch_xml.c:2179
const char * switch_xml_error(switch_xml_t xml)
Definition: switch_xml.c:2786
A representation of an XML tree.
Definition: switch_xml.h:76
switch_xml_section_t sections
Definition: switch_xml.c:167
struct switch_xml_binding * next
Definition: switch_xml.c:169
#define zstr(x)
Definition: switch_utils.h:281
switch_status_t switch_thread_rwlock_rdlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:227
uint32_t switch_xml_section_t
Definition: switch_types.h:598
switch_xml_search_function_t function
Definition: switch_xml.c:166
switch_xml_t switch_xml_parse_str_dynamic(char *s, switch_bool_t dup)
Definition: switch_xml.c:962
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
void switch_xml_free(switch_xml_t xml)
Definition: switch_xml.c:2701
#define switch_assert(expr)
switch_xml_t switch_xml_find_child(switch_xml_t node, const char *childname, const char *attrname, const char *value)
Definition: switch_xml.c:334
switch_xml_t switch_xml_child(switch_xml_t xml, const char *name)
Definition: switch_xml.c:409
switch_xml_section_t switch_xml_parse_section_string(const char *str)
Definition: switch_xml.c:208
char * switch_xml_toxml(switch_xml_t xml, switch_bool_t prn_header)
Definition: switch_xml.c:2616
static switch_thread_rwlock_t * B_RWLOCK
Definition: switch_xml.c:177
switch_status_t switch_xml_locate_domain ( const char *  domain_name,
switch_event_t params,
switch_xml_t root,
switch_xml_t domain 
)

Definition at line 1737 of file switch_xml.c.

References switch_assert, switch_event_add_header_string(), switch_event_create, switch_event_destroy(), SWITCH_EVENT_REQUEST_PARAMS, SWITCH_FALSE, SWITCH_STACK_BOTTOM, and switch_xml_locate().

Referenced by switch_xml_locate_group(), and switch_xml_locate_user().

1738 {
1739  switch_event_t *my_params = NULL;
1740  switch_status_t status;
1741  *domain = NULL;
1742 
1743  if (!params) {
1745  switch_assert(my_params);
1746  switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "domain", domain_name);
1747  params = my_params;
1748  }
1749 
1750  status = switch_xml_locate("directory", "domain", "name", domain_name, root, domain, params, SWITCH_FALSE);
1751  if (my_params) {
1752  switch_event_destroy(&my_params);
1753  }
1754  return status;
1755 }
Representation of an event.
Definition: switch_event.h:80
switch_status_t switch_xml_locate(const char *section, const char *tag_name, const char *key_name, const char *key_value, switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_bool_t clone)
Definition: switch_xml.c:1655
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
switch_status_t
Common return values.
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:383
void switch_event_destroy(switch_event_t **event)
Destroy an event.
#define switch_assert(expr)
switch_status_t switch_xml_locate_group ( const char *  group_name,
const char *  domain_name,
switch_xml_t root,
switch_xml_t domain,
switch_xml_t group,
switch_event_t params 
)

Definition at line 1757 of file switch_xml.c.

References switch_assert, switch_event_add_header_string(), switch_event_create, switch_event_destroy(), SWITCH_EVENT_REQUEST_PARAMS, SWITCH_STACK_BOTTOM, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_xml_child(), switch_xml_find_child(), and switch_xml_locate_domain().

1760 {
1762  switch_event_t *my_params = NULL;
1763  switch_xml_t groups = NULL;
1764 
1765  *root = NULL;
1766  *group = NULL;
1767  *domain = NULL;
1768 
1769  if (!params) {
1771  switch_assert(my_params);
1772  params = my_params;
1773  }
1774 
1775  if (group_name) {
1776  switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "group_name", group_name);
1777  }
1778 
1779  if (domain_name) {
1780  switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain_name);
1781  }
1782 
1783  if ((status = switch_xml_locate_domain(domain_name, params, root, domain)) != SWITCH_STATUS_SUCCESS) {
1784  goto end;
1785  }
1786 
1787  status = SWITCH_STATUS_FALSE;
1788 
1789  if ((groups = switch_xml_child(*domain, "groups"))) {
1790  if ((*group = switch_xml_find_child(groups, "group", "name", group_name))) {
1791  status = SWITCH_STATUS_SUCCESS;
1792  }
1793  }
1794 
1795  end:
1796 
1797  if (my_params) {
1798  switch_event_destroy(&my_params);
1799  }
1800 
1801  return status;
1802 }
Representation of an event.
Definition: switch_event.h:80
A representation of an XML tree.
Definition: switch_xml.h:76
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
switch_status_t switch_xml_locate_domain(const char *domain_name, switch_event_t *params, switch_xml_t *root, switch_xml_t *domain)
Definition: switch_xml.c:1737
switch_status_t
Common return values.
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:383
void switch_event_destroy(switch_event_t **event)
Destroy an event.
#define switch_assert(expr)
switch_xml_t switch_xml_find_child(switch_xml_t node, const char *childname, const char *attrname, const char *value)
Definition: switch_xml.c:334
switch_xml_t switch_xml_child(switch_xml_t xml, const char *name)
Definition: switch_xml.c:409
switch_status_t switch_xml_locate_user ( const char *  key,
const char *  user_name,
const char *  domain_name,
const char *  ip,
switch_xml_t root,
switch_xml_t domain,
switch_xml_t user,
switch_xml_t ingroup,
switch_event_t params 
)

Definition at line 2089 of file switch_xml.c.

References find_user_in_tag(), switch_xml::next, switch_assert, switch_event_add_header_string(), switch_event_create, switch_event_destroy(), SWITCH_EVENT_REQUEST_PARAMS, SWITCH_STACK_BOTTOM, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_xml_child(), switch_xml_free(), and switch_xml_locate_domain().

Referenced by switch_xml_locate_user_merged().

2095 {
2097  switch_event_t *my_params = NULL;
2098  switch_xml_t group = NULL, groups = NULL, users = NULL;
2099 
2100  *root = NULL;
2101  *user = NULL;
2102  *domain = NULL;
2103 
2104  if (ingroup) {
2105  *ingroup = NULL;
2106  }
2107 
2108  if (!params) {
2110  switch_assert(my_params);
2111  params = my_params;
2112  }
2113 
2115 
2116  if (user_name) {
2117  switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "user", user_name);
2118  }
2119 
2120  if (domain_name) {
2121  switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain_name);
2122  }
2123 
2124  if (ip) {
2126  }
2127 
2128  if ((status = switch_xml_locate_domain(domain_name, params, root, domain)) != SWITCH_STATUS_SUCCESS) {
2129  goto end;
2130  }
2131 
2132  status = SWITCH_STATUS_FALSE;
2133 
2134  if ((groups = switch_xml_child(*domain, "groups"))) {
2135  for (group = switch_xml_child(groups, "group"); group; group = group->next) {
2136  if ((users = switch_xml_child(group, "users"))) {
2137  if ((status = find_user_in_tag(users, ip, user_name, key, params, user)) == SWITCH_STATUS_SUCCESS) {
2138  if (ingroup) {
2139  *ingroup = group;
2140  }
2141  break;
2142  }
2143  }
2144  }
2145  }
2146 
2147  if (status != SWITCH_STATUS_SUCCESS) {
2148  status = find_user_in_tag(*domain, ip, user_name, key, params, user);
2149  }
2150 
2151  end:
2152 
2153  if (my_params) {
2154  switch_event_destroy(&my_params);
2155  }
2156 
2157  if (status != SWITCH_STATUS_SUCCESS && root && *root) {
2158  switch_xml_free(*root);
2159  *root = NULL;
2160  *domain = NULL;
2161  }
2162 
2163  return status;
2164 }
Representation of an event.
Definition: switch_event.h:80
A representation of an XML tree.
Definition: switch_xml.h:76
switch_xml_t next
Definition: switch_xml.h:88
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
switch_status_t switch_xml_locate_domain(const char *domain_name, switch_event_t *params, switch_xml_t *root, switch_xml_t *domain)
Definition: switch_xml.c:1737
switch_status_t
Common return values.
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:383
static switch_status_t find_user_in_tag(switch_xml_t tag, const char *ip, const char *user_name, const char *key, switch_event_t *params, switch_xml_t *user)
Definition: switch_xml.c:1804
void switch_event_destroy(switch_event_t **event)
Destroy an event.
void switch_xml_free(switch_xml_t xml)
Definition: switch_xml.c:2701
#define switch_assert(expr)
switch_xml_t switch_xml_child(switch_xml_t xml, const char *name)
Definition: switch_xml.c:409
static switch_status_t switch_xml_locate_user_cache ( const char *  key,
const char *  user_name,
const char *  domain_name,
switch_xml_t user 
)
static

Definition at line 1970 of file switch_xml.c.

References CACHE_EXPIRES_HASH, CACHE_HASH, SWITCH_CHANNEL_LOG, switch_core_hash_find(), SWITCH_LOG_DEBUG, switch_log_printf(), switch_micro_time_now(), switch_mutex_lock(), switch_mutex_unlock(), switch_snprintf(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_xml_dup(), and time_now().

Referenced by switch_xml_locate_user_merged().

1971 {
1972  char mega_key[1024];
1974  switch_xml_t lookup;
1975 
1976  switch_snprintf(mega_key, sizeof(mega_key), "%s%s%s", key, user_name, domain_name);
1977 
1979  if ((lookup = switch_core_hash_find(CACHE_HASH, mega_key))) {
1980  char *expires_lookup = NULL;
1981 
1982  if ((expires_lookup = switch_core_hash_find(CACHE_EXPIRES_HASH, mega_key))) {
1983  switch_time_t time_expires = 0;
1984  switch_time_t time_now = 0;
1985 
1986  time_now = switch_micro_time_now();
1987  time_expires = atol(expires_lookup);
1988  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Cache Info\nTime Now:\t%ld\nExpires:\t%ld\n", (long)time_now, (long)time_expires);
1989  if (time_expires < time_now) {
1990  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Cache expired for %s@%s, doing fresh lookup\n", user_name, domain_name);
1991  } else {
1992  *user = switch_xml_dup(lookup);
1993  status = SWITCH_STATUS_SUCCESS;
1994  }
1995  } else {
1996  *user = switch_xml_dup(lookup);
1997  status = SWITCH_STATUS_SUCCESS;
1998  }
1999  }
2001 
2002  return status;
2003 }
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:310
#define SWITCH_CHANNEL_LOG
void * switch_core_hash_find(_In_ switch_hash_t *hash, _In_z_ const char *key)
Retrieve data from a given hash.
static switch_time_t time_now(int64_t offset)
Definition: switch_time.c:520
A representation of an XML tree.
Definition: switch_xml.h:76
static switch_hash_t * CACHE_HASH
Definition: switch_xml.c:188
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_xml_t switch_xml_dup(switch_xml_t xml)
Definition: switch_xml.c:1862
int64_t switch_time_t
Definition: switch_apr.h:188
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
static switch_hash_t * CACHE_EXPIRES_HASH
Definition: switch_xml.c:189
switch_status_t
Common return values.
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
static switch_mutex_t * CACHE_MUTEX
Definition: switch_xml.c:179
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 
)

Definition at line 1840 of file switch_xml.c.

References find_user_in_tag(), switch_xml::next, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_xml_child().

1841 {
1842  switch_xml_t group = NULL, groups = NULL, users = NULL;
1844 
1845  if ((groups = switch_xml_child(domain, "groups"))) {
1846  for (group = switch_xml_child(groups, "group"); group; group = group->next) {
1847  if ((users = switch_xml_child(group, "users"))) {
1848  if ((status = find_user_in_tag(users, NULL, user_name, "id", NULL, user)) == SWITCH_STATUS_SUCCESS) {
1849  if (ingroup) {
1850  *ingroup = group;
1851  }
1852  break;
1853  }
1854  }
1855  }
1856  }
1857 
1858  return status;
1859 }
A representation of an XML tree.
Definition: switch_xml.h:76
switch_xml_t next
Definition: switch_xml.h:88
switch_status_t
Common return values.
static switch_status_t find_user_in_tag(switch_xml_t tag, const char *ip, const char *user_name, const char *key, switch_event_t *params, switch_xml_t *user)
Definition: switch_xml.c:1804
switch_xml_t switch_xml_child(switch_xml_t xml, const char *name)
Definition: switch_xml.c:409
switch_xml_t switch_xml_new ( const char *  name)

Definition at line 2794 of file switch_xml.c.

References switch_xml::attr, switch_xml_root::attr, switch_xml_root::cur, switch_xml_root::ent, switch_xml_root::err, memset(), switch_xml::name, switch_xml_root::pi, switch_must_malloc(), switch_xml::txt, and switch_xml_root::xml.

Referenced by switch_xml_parse_str().

2795 {
2796  static const char *ent[] = { "lt;", "&#60;", "gt;", "&#62;", "quot;", "&#34;",
2797  "apos;", "&#39;", "amp;", "&#38;", NULL
2798  };
2800 
2801  memset(root, '\0', sizeof(struct switch_xml_root));
2802  root->xml.name = (char *) name;
2803  root->cur = &root->xml;
2804  strcpy(root->err, root->xml.txt = (char *) "");
2805  root->ent = (char **) memcpy(switch_must_malloc(sizeof(ent)), ent, sizeof(ent));
2806  root->attr = root->pi = (char ***) (root->xml.attr = SWITCH_XML_NIL);
2807  return &root->xml;
2808 }
char * name
Definition: switch_xml.h:78
char *** attr
Definition: switch_xml.c:157
static void * switch_must_malloc(size_t _b)
Definition: switch_core.h:231
char * txt
Definition: switch_xml.h:82
struct switch_xml_root * switch_xml_root_t
Definition: switch_xml.c:146
switch_xml_t cur
Definition: switch_xml.c:149
struct switch_xml xml
Definition: switch_xml.c:148
char err[SWITCH_XML_ERRL]
Definition: switch_xml.c:160
char ** attr
Definition: switch_xml.h:80
memset(buf, 0, buflen)
char * SWITCH_XML_NIL[]
Definition: switch_xml.c:163
switch_xml_t switch_xml_open_cfg ( const char *  file_path,
switch_xml_t node,
switch_event_t params 
)

Definition at line 2383 of file switch_xml.c.

References SWITCH_FALSE, SWITCH_STATUS_SUCCESS, switch_xml_locate(), and destroy_xml::xml.

2384 {
2385  switch_xml_t xml = NULL, cfg = NULL;
2386 
2387  *node = NULL;
2388 
2389  assert(MAIN_XML_ROOT != NULL);
2390 
2391  if (switch_xml_locate("configuration", "configuration", "name", file_path, &xml, &cfg, params, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
2392  *node = cfg;
2393  }
2394 
2395  return xml;
2396 
2397 }
switch_xml_t xml
Definition: switch_xml.c:2179
switch_status_t switch_xml_locate(const char *section, const char *tag_name, const char *key_name, const char *key_value, switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_bool_t clone)
Definition: switch_xml.c:1655
A representation of an XML tree.
Definition: switch_xml.h:76
static switch_xml_t MAIN_XML_ROOT
Definition: switch_xml.c:174
switch_xml_t switch_xml_open_root ( uint8_t  reload,
const char **  err 
)

Definition at line 2256 of file switch_xml.c.

References switch_event_create, switch_event_destroy(), switch_event_fire, SWITCH_EVENT_RELOADXML, switch_mutex_lock(), switch_mutex_unlock(), SWITCH_STATUS_SUCCESS, XML_OPEN_ROOT_FUNCTION, and XML_OPEN_ROOT_FUNCTION_USER_DATA.

Referenced by switch_xml_init(), and switch_xml_reload().

2257 {
2258  switch_xml_t root = NULL;
2259  switch_event_t *event;
2260 
2262 
2263  if (XML_OPEN_ROOT_FUNCTION) {
2265  }
2267 
2268 
2269  if (root) {
2271  if (switch_event_fire(&event) != SWITCH_STATUS_SUCCESS) {
2272  switch_event_destroy(&event);
2273  }
2274  }
2275  }
2276 
2277  return root;
2278 }
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:412
Representation of an event.
Definition: switch_event.h:80
A representation of an XML tree.
Definition: switch_xml.h:76
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
static void * XML_OPEN_ROOT_FUNCTION_USER_DATA
Definition: switch_xml.c:186
static switch_xml_open_root_function_t XML_OPEN_ROOT_FUNCTION
Definition: switch_xml.c:185
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:383
static switch_mutex_t * XML_LOCK
Definition: switch_xml.c:178
void switch_event_destroy(switch_event_t **event)
Destroy an event.
static void switch_xml_open_tag ( switch_xml_root_t  root,
char *  name,
char **  attr 
)
static

Definition at line 631 of file switch_xml.c.

References switch_xml::attr, switch_xml_root::cur, switch_xml::name, xml_section_t::name, switch_xml_add_child(), and switch_xml::txt.

Referenced by switch_xml_parse_str().

632 {
634 
635  if (!root || !root->cur) {
636  return;
637  }
638 
639  xml = root->cur;
640 
641  if (xml->name)
642  xml = switch_xml_add_child(xml, name, strlen(xml->txt));
643  else
644  xml->name = name; /* first open tag */
645 
646  xml->attr = attr;
647  root->cur = xml; /* update tag insertion point */
648 }
char * name
Definition: switch_xml.h:78
switch_xml_t xml
Definition: switch_xml.c:2179
A representation of an XML tree.
Definition: switch_xml.h:76
char * txt
Definition: switch_xml.h:82
switch_xml_t cur
Definition: switch_xml.c:149
switch_xml_t switch_xml_add_child(switch_xml_t xml, const char *name, switch_size_t off)
Definition: switch_xml.c:2852
char ** attr
Definition: switch_xml.h:80
switch_xml_t switch_xml_parse_file ( const char *  file)

Definition at line 1583 of file switch_xml.c.

References switch_directories::conf_dir, switch_filenames::conf_name, switch_xml::free_path, switch_directories::log_dir, preprocess(), SWITCH_GLOBAL_dirs, SWITCH_GLOBAL_filenames, switch_mprintf(), switch_mutex_lock(), switch_mutex_unlock(), SWITCH_PATH_SEPARATOR, switch_safe_free, and switch_xml_parse_fd().

Referenced by __switch_xml_open_root().

1584 {
1585  int fd = -1;
1586  FILE *write_fd = NULL;
1587  switch_xml_t xml = NULL;
1588  char *new_file = NULL;
1589  char *new_file_tmp = NULL;
1590  const char *abs, *absw;
1591 
1592  abs = strrchr(file, '/');
1593  absw = strrchr(file, '\\');
1594  if (abs || absw) {
1595  abs > absw ? abs++ : (abs = ++absw);
1596  } else {
1597  abs = file;
1598  }
1599 
1601 
1602  if (!(new_file = switch_mprintf("%s%s%s.fsxml", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, abs))) {
1603  goto done;
1604  }
1605 
1606  if (!(new_file_tmp = switch_mprintf("%s%s%s.fsxml.tmp", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, abs))) {
1607  goto done;
1608  }
1609 
1610  if ((write_fd = fopen(new_file_tmp, "w+")) == NULL) {
1611  goto done;
1612  }
1613 
1614  setvbuf(write_fd, (char *) NULL, _IOFBF, 65536);
1615 
1616  if (preprocess(SWITCH_GLOBAL_dirs.conf_dir, file, write_fd, 0) > -1) {
1617  fclose(write_fd);
1618  write_fd = NULL;
1619  unlink (new_file);
1620 
1621  if ( rename(new_file_tmp,new_file) ) {
1622  goto done;
1623  }
1624  if ((fd = open(new_file, O_RDONLY, 0)) > -1) {
1625  if ((xml = switch_xml_parse_fd(fd))) {
1626  if (strcmp(abs, SWITCH_GLOBAL_filenames.conf_name)) {
1627  xml->free_path = new_file;
1628  new_file = NULL;
1629  }
1630  }
1631  close(fd);
1632  fd = -1;
1633  }
1634  }
1635 
1636  done:
1637 
1639 
1640  if (write_fd) {
1641  fclose(write_fd);
1642  write_fd = NULL;
1643  }
1644 
1645  if (fd > -1) {
1646  close(fd);
1647  }
1648 
1649  switch_safe_free(new_file_tmp);
1650  switch_safe_free(new_file);
1651 
1652  return xml;
1653 }
switch_xml_t xml
Definition: switch_xml.c:2179
A representation of an XML tree.
Definition: switch_xml.h:76
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:122
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
switch_filenames SWITCH_GLOBAL_filenames
Definition: switch_core.c:61
switch_directories SWITCH_GLOBAL_dirs
Definition: switch_core.c:60
char * free_path
Definition: switch_xml.h:84
switch_xml_t switch_xml_parse_fd(int fd)
A wrapper for switch_xml_parse_str() that accepts a file descriptor. First \ attempts to mem map the ...
Definition: switch_xml.c:1157
static int preprocess(const char *cwd, const char *file, FILE *write_fd, int rlevel)
Definition: switch_xml.c:1339
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)
static switch_mutex_t * FILE_LOCK
Definition: switch_xml.c:181
switch_xml_t switch_xml_parse_file_simple ( const char *  file)

Definition at line 1556 of file switch_xml.c.

References switch_xml_root::dynamic, SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, switch_log_printf(), switch_must_malloc(), switch_xml_parse_str(), and switch_xml_root::xml.

1557 {
1558  int fd = -1;
1559  struct stat st;
1560  switch_ssize_t l;
1561  void *m;
1562  switch_xml_root_t root;
1563 
1564  if ((fd = open(file, O_RDONLY, 0)) > -1) {
1565  fstat(fd, &st);
1566  if (!st.st_size) goto error;
1567  m = switch_must_malloc(st.st_size);
1568 
1569  if (!(0<(l = read(fd, m, st.st_size)))) goto error;
1570  if (!(root = (switch_xml_root_t) switch_xml_parse_str((char *) m, l))) goto error;
1571  root->dynamic = 1;
1572  close(fd);
1573  return &root->xml;
1574  }
1575 
1576  error:
1577 
1578  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Parsing File [%s]\n", file);
1579 
1580  return NULL;
1581 }
#define SWITCH_CHANNEL_LOG
static void * switch_must_malloc(size_t _b)
Definition: switch_core.h:231
intptr_t switch_ssize_t
struct switch_xml xml
Definition: switch_xml.c:148
switch_xml_t switch_xml_parse_str(char *s, switch_size_t len)
Definition: switch_xml.c:982
uint8_t dynamic
Definition: switch_xml.c:152
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_xml_t switch_xml_parse_fp ( FILE *  fp)

Definition at line 1132 of file switch_xml.c.

References switch_xml_root::dynamic, switch_must_malloc(), switch_must_realloc(), SWITCH_XML_BUFSIZE, switch_xml_parse_str(), and switch_xml_root::xml.

1133 {
1134  switch_xml_root_t root;
1135  switch_size_t l, len = 0;
1136  char *s;
1137 
1138  s = (char *) switch_must_malloc(SWITCH_XML_BUFSIZE);
1139 
1140  do {
1141  len += (l = fread((s + len), 1, SWITCH_XML_BUFSIZE, fp));
1142  if (l == SWITCH_XML_BUFSIZE) {
1143  s = (char *) switch_must_realloc(s, len + SWITCH_XML_BUFSIZE);
1144  }
1145  } while (s && l == SWITCH_XML_BUFSIZE);
1146 
1147  if (!s)
1148  return NULL;
1149  root = (switch_xml_root_t) switch_xml_parse_str(s, len);
1150  root->dynamic = 1; /* so we know to free s in switch_xml_free() */
1151  return &root->xml;
1152 }
static void * switch_must_malloc(size_t _b)
Definition: switch_core.h:231
struct switch_xml_root * switch_xml_root_t
Definition: switch_xml.c:146
static void * switch_must_realloc(void *_b, size_t _z)
Definition: switch_core.h:238
uintptr_t switch_size_t
struct switch_xml xml
Definition: switch_xml.c:148
switch_xml_t switch_xml_parse_str(char *s, switch_size_t len)
Definition: switch_xml.c:982
#define SWITCH_XML_BUFSIZE
Definition: switch_xml.h:67
uint8_t dynamic
Definition: switch_xml.c:152
switch_xml_section_t switch_xml_parse_section_string ( const char *  str)

Definition at line 208 of file switch_xml.c.

References buf, xml_section_t::name, xml_section_t::section, and SWITCH_XML_SECTION_RESULT.

Referenced by switch_xml_locate().

209 {
210  size_t x;
211  char buf[1024] = "";
212  /*switch_xml_section_t sections = SWITCH_XML_SECTION_RESULT; */
213  uint32_t sections = SWITCH_XML_SECTION_RESULT;
214 
215  if (str) {
216  for (x = 0; x < strlen(str); x++) {
217  buf[x] = (char) tolower((int) str[x]);
218  }
219  for (x = 0;; x++) {
220  if (!SECTIONS[x].name) {
221  break;
222  }
223  if (strstr(buf, SECTIONS[x].name)) {
224  sections |= SECTIONS[x].section;
225  }
226  }
227  }
228  return (switch_xml_section_t) sections;
229 }
switch_byte_t switch_byte_t * buf
uint32_t switch_xml_section_t
Definition: switch_types.h:598
static struct xml_section_t SECTIONS[]
Definition: switch_xml.c:197
uint32_t section
Definition: switch_xml.c:194
switch_xml_t switch_xml_parse_str ( char *  s,
switch_size_t  len 
)

Definition at line 982 of file switch_xml.c.

References switch_xml_root::attr, switch_xml_root::cur, switch_xml_root::e, switch_xml_root::ent, switch_xml_root::m, switch_xml::name, switch_xml_root::s, switch_must_malloc(), switch_must_realloc(), switch_xml_char_content(), switch_xml_close_tag(), switch_xml_decode(), switch_xml_err(), switch_xml_free_attr(), switch_xml_internal_dtd(), switch_xml_new(), switch_xml_open_tag(), switch_xml_proc_inst(), switch_xml_str2utf8(), SWITCH_XML_TXTM, SWITCH_XML_WS, switch_xml_root::u, and switch_xml_root::xml.

Referenced by switch_xml_parse_fd(), switch_xml_parse_file_simple(), switch_xml_parse_fp(), and switch_xml_parse_str_dynamic().

983 {
985  char q, e, *d, **attr, **a = NULL; /* initialize a to avoid compile warning */
986  int l, i, j;
987 
988  root->m = s;
989  if (!len)
990  return switch_xml_err(root, s, "root tag missing");
991  root->u = switch_xml_str2utf8(&s, &len); /* convert utf-16 to utf-8 */
992  root->e = (root->s = s) + len; /* record start and end of work area */
993 
994  e = s[len - 1]; /* save end char */
995  s[len - 1] = '\0'; /* turn end char into null terminator */
996 
997  while (*s && *s != '<')
998  s++; /* find first tag */
999  if (!*s)
1000  return switch_xml_err(root, s, "root tag missing");
1001 
1002  for (;;) {
1003  attr = (char **) SWITCH_XML_NIL;
1004  d = ++s;
1005 
1006  if (isalpha((int) (*s)) || *s == '_' || *s == ':' || (int8_t) * s < '\0') { /* new tag */
1007  if (!root->cur)
1008  return switch_xml_err(root, d, "markup outside of root element");
1009 
1010  s += strcspn(s, SWITCH_XML_WS "/>");
1011  while (isspace((int) (*s)))
1012  *(s++) = '\0'; /* null terminate tag name */
1013 
1014  if (*s && *s != '/' && *s != '>') /* find tag in default attr list */
1015  for (i = 0; (a = root->attr[i]) && strcmp(a[0], d); i++);
1016 
1017  for (l = 0; *s && *s != '/' && *s != '>'; l += 2) { /* new attrib */
1018  attr = (l) ? (char **) switch_must_realloc(attr, (l + 4) * sizeof(char *))
1019  : (char **) switch_must_malloc(4 * sizeof(char *)); /* allocate space */
1020  attr[l + 3] = (l) ? (char *) switch_must_realloc(attr[l + 1], (l / 2) + 2)
1021  : (char *) switch_must_malloc(2); /* mem for list of maloced vals */
1022  strcpy(attr[l + 3] + (l / 2), " "); /* value is not malloced */
1023  attr[l + 2] = NULL; /* null terminate list */
1024  attr[l + 1] = (char *) ""; /* temporary attribute value */
1025  attr[l] = s; /* set attribute name */
1026 
1027  s += strcspn(s, SWITCH_XML_WS "=/>");
1028  if (*s == '=' || isspace((int) (*s))) {
1029  *(s++) = '\0'; /* null terminate tag attribute name */
1030  q = *(s += strspn(s, SWITCH_XML_WS "="));
1031  if (q == '"' || q == '\'') { /* attribute value */
1032  attr[l + 1] = ++s;
1033  while (*s && *s != q)
1034  s++;
1035  if (*s)
1036  *(s++) = '\0'; /* null terminate attribute val */
1037  else {
1038  switch_xml_free_attr(attr);
1039  return switch_xml_err(root, d, "missing %c", q);
1040  }
1041 
1042  for (j = 1; a && a[j] && strcmp(a[j], attr[l]); j += 3);
1043  attr[l + 1] = switch_xml_decode(attr[l + 1], root->ent, (a && a[j]) ? *a[j + 2] : ' ');
1044  if (attr[l + 1] < d || attr[l + 1] > s)
1045  attr[l + 3][l / 2] = SWITCH_XML_TXTM; /* value malloced */
1046  }
1047  }
1048  while (isspace((int) (*s)))
1049  s++;
1050  }
1051 
1052  if (*s == '/') { /* self closing tag */
1053  *(s++) = '\0';
1054  if ((*s && *s != '>') || (!*s && e != '>')) {
1055  if (l)
1056  switch_xml_free_attr(attr);
1057  return switch_xml_err(root, d, "missing >");
1058  }
1059  switch_xml_open_tag(root, d, attr);
1060  switch_xml_close_tag(root, d, s);
1061  } else if ((q = *s) == '>' || (!*s && e == '>')) { /* open tag */
1062  *s = '\0'; /* temporarily null terminate tag name */
1063  switch_xml_open_tag(root, d, attr);
1064  *s = q;
1065  } else {
1066  if (l)
1067  switch_xml_free_attr(attr);
1068  return switch_xml_err(root, d, "missing >");
1069  }
1070  } else if (*s == '/') { /* close tag */
1071  s += strcspn(d = s + 1, SWITCH_XML_WS ">") + 1;
1072  if (!(q = *s) && e != '>')
1073  return switch_xml_err(root, d, "missing >");
1074  *s = '\0'; /* temporarily null terminate tag name */
1075  if (switch_xml_close_tag(root, d, s))
1076  return &root->xml;
1077  if (isspace((int) (*s = q)))
1078  s += strspn(s, SWITCH_XML_WS);
1079  } else if (!strncmp(s, "!--", 3)) { /* xml comment */
1080  if (!(s = strstr(s + 3, "--")) || (*(s += 2) != '>' && *s) || (!*s && e != '>'))
1081  return switch_xml_err(root, d, "unclosed <!--");
1082  } else if (!strncmp(s, "![CDATA[", 8)) { /* cdata */
1083  if ((s = strstr(s, "]]>")))
1084  switch_xml_char_content(root, d + 8, (s += 2) - d - 10, 'c');
1085  else
1086  return switch_xml_err(root, d, "unclosed <![CDATA[");
1087  } else if (!strncmp(s, "!DOCTYPE", 8)) { /* dtd */
1088  for (l = 0; *s && ((!l && *s != '>') || (l && (*s != ']' || *(s + strspn(s + 1, SWITCH_XML_WS) + 1) != '>'))); l = (*s == '[') ? 1 : l)
1089  s += strcspn(s + 1, "[]>") + 1;
1090  if (!*s && e != '>')
1091  return switch_xml_err(root, d, "unclosed <!DOCTYPE");
1092  d = (l) ? strchr(d, '[') + 1 : d;
1093  if (l && !switch_xml_internal_dtd(root, d, s++ - d))
1094  return &root->xml;
1095  } else if (*s == '?') { /* <?...?> processing instructions */
1096  do {
1097  s = strchr(s, '?');
1098  } while (s && *(++s) && *s != '>');
1099  if (!s || (!*s && e != '>'))
1100  return switch_xml_err(root, d, "unclosed <?");
1101  else
1102  switch_xml_proc_inst(root, d + 1, s - d - 2);
1103  } else
1104  return switch_xml_err(root, d, "unexpected <");
1105 
1106  if (!s || !*s)
1107  break;
1108  *s = '\0';
1109  d = ++s;
1110  if (*s && *s != '<') { /* tag character content */
1111  while (*s && *s != '<')
1112  s++;
1113  if (*s)
1114  switch_xml_char_content(root, d, s - d, '&');
1115  else
1116  break;
1117  } else if (!*s)
1118  break;
1119  }
1120 
1121  if (!root->cur)
1122  return &root->xml;
1123  else if (!root->cur->name)
1124  return switch_xml_err(root, d, "root tag missing");
1125  else
1126  return switch_xml_err(root, d, "unclosed tag <%s>", root->cur->name);
1127 }
char * name
Definition: switch_xml.h:78
switch_xml_t switch_xml_new(const char *name)
Definition: switch_xml.c:2794
static short switch_xml_internal_dtd(switch_xml_root_t root, char *s, switch_size_t len)
Definition: switch_xml.c:771
char *** attr
Definition: switch_xml.c:157
static void switch_xml_free_attr(char **attr)
Definition: switch_xml.c:942
static void * switch_must_malloc(size_t _b)
Definition: switch_core.h:231
static void switch_xml_proc_inst(switch_xml_root_t root, char *s, switch_size_t len)
Definition: switch_xml.c:718
struct switch_xml_root * switch_xml_root_t
Definition: switch_xml.c:146
#define SWITCH_XML_WS
Definition: switch_xml.c:102
static void switch_xml_char_content(switch_xml_root_t root, char *s, switch_size_t len, char t)
Definition: switch_xml.c:651
static void * switch_must_realloc(void *_b, size_t _z)
Definition: switch_core.h:238
static void switch_xml_open_tag(switch_xml_root_t root, char *name, char **attr)
Definition: switch_xml.c:631
switch_xml_t cur
Definition: switch_xml.c:149
struct switch_xml xml
Definition: switch_xml.c:148
static char * switch_xml_str2utf8(char **s, switch_size_t *len)
Definition: switch_xml.c:902
static char * switch_xml_decode(char *s, char **ent, char t)
Definition: switch_xml.c:538
static switch_xml_t switch_xml_err(switch_xml_root_t root, char *s, const char *err,...)
Definition: switch_xml.c:510
char * SWITCH_XML_NIL[]
Definition: switch_xml.c:163
static switch_xml_t switch_xml_close_tag(switch_xml_root_t root, char *name, char *s)
Definition: switch_xml.c:689
switch_xml_t switch_xml_parse_str_dynamic ( char *  s,
switch_bool_t  dup 
)

Definition at line 962 of file switch_xml.c.

References switch_xml_root::dynamic, switch_assert, switch_must_strdup(), switch_xml_parse_str(), and switch_xml_root::xml.

Referenced by switch_xml_dup(), and switch_xml_locate().

963 {
964  switch_xml_root_t root;
965  char *data;
966 
967  switch_assert(s);
968  data = dup ? switch_must_strdup(s) : s;
969 
970  if ((root = (switch_xml_root_t) switch_xml_parse_str(data, strlen(data)))) {
971  root->dynamic = 1; /* Make sure we free the memory is switch_xml_free() */
972  return &root->xml;
973  } else {
974  if (dup) {
975  free(data);
976  }
977  return NULL;
978  }
979 }
static char * switch_must_strdup(const char *_s)
Definition: switch_core.h:245
struct switch_xml xml
Definition: switch_xml.c:148
switch_xml_t switch_xml_parse_str(char *s, switch_size_t len)
Definition: switch_xml.c:982
uint8_t dynamic
Definition: switch_xml.c:152
#define switch_assert(expr)
const char** switch_xml_pi ( switch_xml_t  xml,
const char *  target 
)

Definition at line 492 of file switch_xml.c.

References if(), switch_xml::parent, switch_xml_root::pi, SWITCH_XML_NIL, and switch_xml_root::xml.

493 {
495  int i = 0;
496 
497  if (!root)
498  return (const char **) SWITCH_XML_NIL;
499  while (root->xml.parent)
500  root = (switch_xml_root_t) root->xml.parent; /* root tag */
501  if (!root || !root->pi) {
502  return (const char **) SWITCH_XML_NIL;
503  }
504  while (root->pi[i] && strcmp(target, root->pi[i][0]))
505  i++; /* find target */
506  return (const char **) ((root->pi[i]) ? root->pi[i] + 1 : SWITCH_XML_NIL);
507 }
if((uint32_t)(unpack->cur-unpack->buf) > unpack->buflen)
struct switch_xml_root * switch_xml_root_t
Definition: switch_xml.c:146
switch_xml_t parent
Definition: switch_xml.h:96
struct switch_xml xml
Definition: switch_xml.c:148
char * SWITCH_XML_NIL[]
Definition: switch_xml.c:163
static void switch_xml_proc_inst ( switch_xml_root_t  root,
char *  s,
switch_size_t  len 
)
static

Definition at line 718 of file switch_xml.c.

References switch_xml::name, switch_xml_root::pi, switch_xml_root::standalone, switch_must_malloc(), switch_must_realloc(), switch_must_strdup(), SWITCH_XML_WS, and switch_xml_root::xml.

Referenced by switch_xml_internal_dtd(), and switch_xml_parse_str().

719 {
720  int i = 0, j = 1;
721  char *target = s;
722  char **sstmp;
723  char *stmp;
724 
725  s[len] = '\0'; /* null terminate instruction */
726  if (*(s += strcspn(s, SWITCH_XML_WS))) {
727  *s = '\0'; /* null terminate target */
728  s += strspn(s + 1, SWITCH_XML_WS) + 1; /* skip whitespace after target */
729  }
730 
731  if (!root)
732  return;
733 
734  if (!strcmp(target, "xml")) { /* <?xml ... ?> */
735  if ((s = strstr(s, "standalone")) && !strncmp(s + strspn(s + 10, SWITCH_XML_WS "='\"") + 10, "yes", 3))
736  root->standalone = 1;
737  return;
738  }
739 
740  if (!root->pi || !root->pi[0]) {
741  root->pi = (char ***) switch_must_malloc(sizeof(char **));
742  *(root->pi) = NULL; /* first pi */
743  }
744 
745  while (root->pi[i] && strcmp(target, root->pi[i][0]))
746  i++; /* find target */
747  if (!root->pi[i]) { /* new target */
748  char ***ssstmp = (char ***) switch_must_realloc(root->pi, sizeof(char **) * (i + 2));
749 
750  root->pi = ssstmp;
751  if (!root->pi)
752  return;
753  root->pi[i] = (char **) switch_must_malloc(sizeof(char *) * 3);
754  root->pi[i][0] = target;
755  root->pi[i][1] = (char *) (root->pi[i + 1] = NULL); /* terminate pi list */
756  root->pi[i][2] = switch_must_strdup(""); /* empty document position list */
757  }
758 
759  while (root->pi[i][j])
760  j++; /* find end of instruction list for this target */
761  sstmp = (char **) switch_must_realloc(root->pi[i], sizeof(char *) * (j + 3));
762  root->pi[i] = sstmp;
763  stmp = (char *) switch_must_realloc(root->pi[i][j + 1], j + 1);
764  root->pi[i][j + 2] = stmp;
765  strcpy(root->pi[i][j + 2] + j - 1, (root->xml.name) ? ">" : "<");
766  root->pi[i][j + 1] = NULL; /* null terminate pi list for this target */
767  root->pi[i][j] = s; /* set instruction */
768 }
char * name
Definition: switch_xml.h:78
static void * switch_must_malloc(size_t _b)
Definition: switch_core.h:231
#define SWITCH_XML_WS
Definition: switch_xml.c:102
static void * switch_must_realloc(void *_b, size_t _z)
Definition: switch_core.h:238
static char * switch_must_strdup(const char *_s)
Definition: switch_core.h:245
struct switch_xml xml
Definition: switch_xml.c:148
void switch_xml_set_binding_sections ( switch_xml_binding_t binding,
switch_xml_section_t  sections 
)

Definition at line 280 of file switch_xml.c.

References switch_assert.

281 {
282  switch_assert(binding);
283  binding->sections = sections;
284 }
switch_xml_section_t sections
Definition: switch_xml.c:167
#define switch_assert(expr)
void switch_xml_set_binding_user_data ( switch_xml_binding_t binding,
void *  user_data 
)

Definition at line 286 of file switch_xml.c.

References switch_assert.

287 {
288  switch_assert(binding);
289  binding->user_data = user_data;
290 }
#define switch_assert(expr)
static char* switch_xml_str2utf8 ( char **  s,
switch_size_t len 
)
static

Definition at line 902 of file switch_xml.c.

References switch_must_malloc(), switch_must_realloc(), and SWITCH_XML_BUFSIZE.

Referenced by switch_xml_parse_str().

903 {
904  char *u;
905  switch_size_t l = 0, sl, max = *len;
906  long c, d;
907  int b, be = (**s == '\xFE') ? 1 : (**s == '\xFF') ? 0 : -1;
908 
909  if (be == -1)
910  return NULL; /* not UTF-16 */
911 
912  u = (char *) switch_must_malloc(max);
913  for (sl = 2; sl < *len - 1; sl += 2) {
914  c = (be) ? (((*s)[sl] & 0xFF) << 8) | ((*s)[sl + 1] & 0xFF) /* UTF-16BE */
915  : (((*s)[sl + 1] & 0xFF) << 8) | ((*s)[sl] & 0xFF); /* UTF-16LE */
916  if (c >= 0xD800 && c <= 0xDFFF && (sl += 2) < *len - 1) { /* high-half */
917  d = (be) ? (((*s)[sl] & 0xFF) << 8) | ((*s)[sl + 1] & 0xFF)
918  : (((*s)[sl + 1] & 0xFF) << 8) | ((*s)[sl] & 0xFF);
919  c = (((c & 0x3FF) << 10) | (d & 0x3FF)) + 0x10000;
920  }
921 
922  while (l + 6 > max) {
923  char *tmp;
924  tmp = (char *) switch_must_realloc(u, max += SWITCH_XML_BUFSIZE);
925  u = tmp;
926  }
927  if (c < 0x80)
928  u[l++] = (char) c; /* US-ASCII subset */
929  else { /* multi-byte UTF-8 sequence */
930  for (b = 0, d = c; d; d /= 2)
931  b++; /* bits in c */
932  b = (b - 2) / 5; /* bytes in payload */
933  u[l++] = (char) ((0xFF << (7 - b)) | (c >> (6 * b))); /* head */
934  while (b)
935  u[l++] = (char) (0x80 | ((c >> (6 * --b)) & 0x3F)); /* payload */
936  }
937  }
938  return *s = (char *) switch_must_realloc(u, *len = l);
939 }
static void * switch_must_malloc(size_t _b)
Definition: switch_core.h:231
static void * switch_must_realloc(void *_b, size_t _z)
Definition: switch_core.h:238
uintptr_t switch_size_t
#define SWITCH_XML_BUFSIZE
Definition: switch_xml.h:67
char* switch_xml_tohtml ( switch_xml_t  xml,
switch_bool_t  prn_header 
)

Definition at line 2627 of file switch_xml.c.

References switch_must_malloc(), switch_safe_free, switch_xml_ampencode(), SWITCH_XML_BUFSIZE, and switch_xml_toxml_buf().

2628 {
2629  char *r, *s, *h;
2630  switch_size_t rlen = 0;
2632 
2633  s = (char *) switch_must_malloc(SWITCH_XML_BUFSIZE);
2634  h = (char *) switch_must_malloc(SWITCH_XML_BUFSIZE);
2635 
2636  r = switch_xml_toxml_buf(xml, s, SWITCH_XML_BUFSIZE, 0, prn_header);
2637  h = switch_xml_ampencode(r, 0, &h, &rlen, &len, 1);
2638  switch_safe_free(r);
2639  return h;
2640 }
static char * switch_xml_ampencode(const char *s, switch_size_t len, char **dst, switch_size_t *dlen, switch_size_t *max, short a)
Definition: switch_xml.c:2401
static void * switch_must_malloc(size_t _b)
Definition: switch_core.h:231
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
uintptr_t switch_size_t
#define SWITCH_XML_BUFSIZE
Definition: switch_xml.h:67
char * switch_xml_toxml_buf(switch_xml_t xml, char *buf, switch_size_t buflen, switch_size_t offset, switch_bool_t prn_header)
Definition: switch_xml.c:2644
char* switch_xml_toxml ( switch_xml_t  xml,
switch_bool_t  prn_header 
)

Definition at line 2616 of file switch_xml.c.

References switch_must_malloc(), SWITCH_XML_BUFSIZE, and switch_xml_toxml_buf().

Referenced by switch_xml_dup(), and switch_xml_locate().

2617 {
2618  char *r, *s;
2619 
2620  s = (char *) switch_must_malloc(SWITCH_XML_BUFSIZE);
2621 
2622  r = switch_xml_toxml_buf(xml, s, SWITCH_XML_BUFSIZE, 0, prn_header);
2623 
2624  return r;
2625 }
static void * switch_must_malloc(size_t _b)
Definition: switch_core.h:231
#define SWITCH_XML_BUFSIZE
Definition: switch_xml.h:67
char * switch_xml_toxml_buf(switch_xml_t xml, char *buf, switch_size_t buflen, switch_size_t offset, switch_bool_t prn_header)
Definition: switch_xml.c:2644
char* switch_xml_toxml_buf ( switch_xml_t  xml,
char *  buf,
switch_size_t  buflen,
switch_size_t  offset,
switch_bool_t  prn_header 
)

Definition at line 2644 of file switch_xml.c.

References buf, buflen, memset(), switch_xml::parent, switch_must_realloc(), SWITCH_XML_BUFSIZE, switch_xml_toxml_r(), and destroy_xml::xml.

Referenced by switch_xml_tohtml(), switch_xml_toxml(), and switch_xml_toxml_nolock().

2645 {
2646  switch_xml_t p = (xml) ? xml->parent : NULL;
2647  switch_xml_root_t root = (switch_xml_root_t) xml;
2648  switch_size_t len = 0, max = buflen;
2649  char *s, *t, *n;
2650  int i, j, k;
2651  uint32_t count = 0;
2652 
2653  s = buf;
2654  assert(s != NULL);
2655  memset(s, 0, max);
2656  len += offset;
2657  if (prn_header) {
2658  len += sprintf(s + len, "<?xml version=\"1.0\"?>\n");
2659  }
2660 
2661  if (!xml || !xml->name) {
2662  return (char *) switch_must_realloc(s, len + 1);
2663  }
2664 
2665  while (root->xml.parent) {
2666  root = (switch_xml_root_t) root->xml.parent; /* root tag */
2667  }
2668 
2669  for (i = 0; !p && root->pi[i]; i++) { /* pre-root processing instructions */
2670  for (k = 2; root->pi[i][k - 1]; k++);
2671  for (j = 1; (n = root->pi[i][j]); j++) {
2672  if (root->pi[i][k][j - 1] == '>') {
2673  continue; /* not pre-root */
2674  }
2675  while (len + strlen(t = root->pi[i][0]) + strlen(n) + 7 > max) {
2676  s = (char *) switch_must_realloc(s, max += SWITCH_XML_BUFSIZE);
2677  }
2678  len += sprintf(s + len, "<?%s%s%s?>", t, *n ? " " : "", n);
2679  }
2680  }
2681 
2682  s = switch_xml_toxml_r(xml, &s, &len, &max, 0, root->attr, &count, 1);
2683 
2684  for (i = 0; !p && root->pi[i]; i++) { /* post-root processing instructions */
2685  for (k = 2; root->pi[i][k - 1]; k++);
2686  for (j = 1; (n = root->pi[i][j]); j++) {
2687  if (root->pi[i][k][j - 1] == '<') {
2688  continue; /* not post-root */
2689  }
2690  while (len + strlen(t = root->pi[i][0]) + strlen(n) + 7 > max) {
2691  s = (char *) switch_must_realloc(s, max += SWITCH_XML_BUFSIZE);
2692  }
2693  len += sprintf(s + len, "\n<?%s%s%s?>", t, *n ? " " : "", n);
2694  }
2695  }
2696 
2697  return (char *) switch_must_realloc(s, len + 1);
2698 }
char * name
Definition: switch_xml.h:78
A representation of an XML tree.
Definition: switch_xml.h:76
switch_byte_t switch_byte_t * buf
struct switch_xml_root * switch_xml_root_t
Definition: switch_xml.c:146
static void * switch_must_realloc(void *_b, size_t _z)
Definition: switch_core.h:238
uintptr_t switch_size_t
switch_byte_t switch_byte_t uint32_t buflen
switch_xml_t parent
Definition: switch_xml.h:96
static 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)
Definition: switch_xml.c:2507
#define SWITCH_XML_BUFSIZE
Definition: switch_xml.h:67
char ** attr
Definition: switch_xml.h:80
memset(buf, 0, buflen)
char* switch_xml_toxml_nolock ( switch_xml_t  xml,
switch_bool_t  prn_header 
)

Definition at line 2608 of file switch_xml.c.

References switch_must_malloc(), SWITCH_XML_BUFSIZE, and switch_xml_toxml_buf().

2609 {
2610  char *s = (char *) switch_must_malloc(SWITCH_XML_BUFSIZE);
2611 
2612  return switch_xml_toxml_buf(xml, s, SWITCH_XML_BUFSIZE, 0, prn_header);
2613 }
static void * switch_must_malloc(size_t _b)
Definition: switch_core.h:231
#define SWITCH_XML_BUFSIZE
Definition: switch_xml.h:67
char * switch_xml_toxml_buf(switch_xml_t xml, char *buf, switch_size_t buflen, switch_size_t offset, switch_bool_t prn_header)
Definition: switch_xml.c:2644
static 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 
)
static

Definition at line 2507 of file switch_xml.c.

References switch_xml::attr, switch_xml::child, switch_xml::name, switch_xml::off, switch_xml::ordered, switch_xml::parent, switch_must_realloc(), switch_xml_ampencode(), switch_xml_attr(), SWITCH_XML_BUFSIZE, switch_xml::txt, and XML_INDENT.

Referenced by switch_xml_toxml_buf().

2508 {
2509  int i, j;
2510  char *txt;
2511  switch_size_t off;
2512  uint32_t lcount;
2513  uint32_t loops = 0;
2514 
2515  tailrecurse:
2516  off = 0;
2517  lcount = 0;
2518  txt = "";
2519 
2520  if (loops++) {
2521  isroot = 0;
2522  }
2523 
2524  if (!isroot && xml->parent) {
2525  txt = (char *) xml->parent->txt;
2526  }
2527 
2528  /* parent character content up to this tag */
2529  *s = switch_xml_ampencode(txt + start, xml->off - start, s, len, max, 0);
2530 
2531  while (*len + strlen(xml->name) + 5 + (strlen(XML_INDENT) * (*count)) + 1 > *max) { /* reallocate s */
2532  *s = (char *) switch_must_realloc(*s, *max += SWITCH_XML_BUFSIZE);
2533  }
2534 
2535  if (*len && *(*s + (*len) - 1) == '>') {
2536  *len += sprintf(*s + *len, "\n"); /* indent */
2537  }
2538  for (lcount = 0; lcount < *count; lcount++) {
2539  *len += sprintf(*s + *len, "%s", XML_INDENT); /* indent */
2540  }
2541 
2542  *len += sprintf(*s + *len, "<%s", xml->name); /* open tag */
2543  for (i = 0; xml->attr[i]; i += 2) { /* tag attributes */
2544  if (switch_xml_attr(xml, xml->attr[i]) != xml->attr[i + 1])
2545  continue;
2546  while (*len + strlen(xml->attr[i]) + 7 + (strlen(XML_INDENT) * (*count)) > *max) { /* reallocate s */
2547  *s = (char *) switch_must_realloc(*s, *max += SWITCH_XML_BUFSIZE);
2548  }
2549 
2550  *len += sprintf(*s + *len, " %s=\"", xml->attr[i]);
2551  switch_xml_ampencode(xml->attr[i + 1], 0, s, len, max, 1);
2552  *len += sprintf(*s + *len, "\"");
2553  }
2554 
2555  for (i = 0; attr[i] && strcmp(attr[i][0], xml->name); i++);
2556  for (j = 1; attr[i] && attr[i][j]; j += 3) { /* default attributes */
2557  if (!attr[i][j + 1] || switch_xml_attr(xml, attr[i][j]) != attr[i][j + 1])
2558  continue; /* skip duplicates and non-values */
2559  while (*len + strlen(attr[i][j]) + 8 + (strlen(XML_INDENT) * (*count)) > *max) { /* reallocate s */
2560  *s = (char *) switch_must_realloc(*s, *max += SWITCH_XML_BUFSIZE);
2561  }
2562 
2563  *len += sprintf(*s + *len, " %s=\"", attr[i][j]);
2564  switch_xml_ampencode(attr[i][j + 1], 0, s, len, max, 1);
2565  *len += sprintf(*s + *len, "\"");
2566  }
2567 
2568  *len += sprintf(*s + *len, (xml->child || xml->txt) ? ">" : "/>\n");
2569 
2570  if (xml->child) {
2571  (*count)++;
2572  *s = switch_xml_toxml_r(xml->child, s, len, max, 0, attr, count, 0);
2573 
2574  } else {
2575  *s = switch_xml_ampencode(xml->txt, 0, s, len, max, 0); /* data */
2576  }
2577 
2578  while (*len + strlen(xml->name) + 5 + (strlen(XML_INDENT) * (*count)) > *max) { /* reallocate s */
2579  *s = (char *) switch_must_realloc(*s, *max += SWITCH_XML_BUFSIZE);
2580  }
2581 
2582  if (xml->child || xml->txt) {
2583  if (*(*s + (*len) - 1) == '\n') {
2584  for (lcount = 0; lcount < *count; lcount++) {
2585  *len += sprintf(*s + *len, "%s", XML_INDENT); /* indent */
2586  }
2587  }
2588  *len += sprintf(*s + (*len), "</%s>\n", xml->name); /* close tag */
2589  }
2590 
2591  while (txt[off] && off < xml->off)
2592  off++; /* make sure off is within bounds */
2593 
2594  if (!isroot && xml->ordered) {
2595  xml = xml->ordered;
2596  start = off;
2597  goto tailrecurse;
2598 /*
2599  return switch_xml_toxml_r(xml->ordered, s, len, max, off, attr, count);
2600 */
2601  } else {
2602  if (*count > 0)
2603  (*count)--;
2604  return switch_xml_ampencode(txt + off, 0, s, len, max, 0);
2605  }
2606 }
char * name
Definition: switch_xml.h:78
switch_size_t off
Definition: switch_xml.h:86
const char * switch_xml_attr(switch_xml_t xml, const char *attr)
Definition: switch_xml.c:434
switch_xml_t child
Definition: switch_xml.h:94
static char * switch_xml_ampencode(const char *s, switch_size_t len, char **dst, switch_size_t *dlen, switch_size_t *max, short a)
Definition: switch_xml.c:2401
char * txt
Definition: switch_xml.h:82
static void * switch_must_realloc(void *_b, size_t _z)
Definition: switch_core.h:238
uintptr_t switch_size_t
switch_xml_t ordered
Definition: switch_xml.h:92
#define XML_INDENT
Definition: switch_xml.c:2503
switch_xml_t parent
Definition: switch_xml.h:96
static 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)
Definition: switch_xml.c:2507
#define SWITCH_XML_BUFSIZE
Definition: switch_xml.h:67
char ** attr
Definition: switch_xml.h:80
switch_status_t switch_xml_unbind_search_function ( switch_xml_binding_t **  binding)

Definition at line 231 of file switch_xml.c.

References switch_xml_binding::next, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_thread_rwlock_unlock(), and switch_thread_rwlock_wrlock().

232 {
233  switch_xml_binding_t *ptr, *last = NULL;
235 
236 
238  for (ptr = BINDINGS; ptr; ptr = ptr->next) {
239  if (ptr == *binding) {
240  if (last) {
241  last->next = (*binding)->next;
242  } else {
243  BINDINGS = (*binding)->next;
244  }
245  status = SWITCH_STATUS_SUCCESS;
246  break;
247  }
248  last = ptr;
249  }
251 
252  return status;
253 }
static switch_xml_binding_t * BINDINGS
Definition: switch_xml.c:173
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:263
struct switch_xml_binding * next
Definition: switch_xml.c:169
switch_status_t switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:237
switch_status_t
Common return values.
static switch_thread_rwlock_t * B_RWLOCK
Definition: switch_xml.c:177
switch_status_t switch_xml_unbind_search_function_ptr ( switch_xml_search_function_t  function)

Definition at line 255 of file switch_xml.c.

References switch_xml_binding::function, switch_xml_binding::next, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_thread_rwlock_unlock(), and switch_thread_rwlock_wrlock().

256 {
257  switch_xml_binding_t *ptr, *last = NULL;
259 
261  for (ptr = BINDINGS; ptr; ptr = ptr->next) {
262  if (ptr->function == function) {
263  status = SWITCH_STATUS_SUCCESS;
264 
265  if (last) {
266  last->next = ptr->next;
267  } else {
268  BINDINGS = ptr->next;
269  last = NULL;
270  continue;
271  }
272  }
273  last = ptr;
274  }
276 
277  return status;
278 }
static switch_xml_binding_t * BINDINGS
Definition: switch_xml.c:173
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:263
struct switch_xml_binding * next
Definition: switch_xml.c:169
switch_status_t switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:237
switch_xml_search_function_t function
Definition: switch_xml.c:166
switch_status_t
Common return values.
static switch_thread_rwlock_t * B_RWLOCK
Definition: switch_xml.c:177
static void switch_xml_user_cache ( const char *  key,
const char *  user_name,
const char *  domain_name,
switch_xml_t  user,
switch_time_t  expires 
)
static

Definition at line 2005 of file switch_xml.c.

References CACHE_EXPIRES_HASH, CACHE_HASH, switch_core_hash_delete(), switch_core_hash_find(), switch_core_hash_insert, switch_must_malloc(), switch_mutex_lock(), switch_mutex_unlock(), switch_safe_free, switch_snprintf(), switch_xml_dup(), and switch_xml_free().

Referenced by switch_xml_locate_user_merged().

2006 {
2007  char mega_key[1024];
2008  switch_xml_t lookup;
2009  char *expires_lookup;
2010 
2011  switch_snprintf(mega_key, sizeof(mega_key), "%s%s%s", key, user_name, domain_name);
2012 
2014  if ((lookup = switch_core_hash_find(CACHE_HASH, mega_key))) {
2016  switch_xml_free(lookup);
2017  }
2018  if ((expires_lookup = switch_core_hash_find(CACHE_EXPIRES_HASH, mega_key))) {
2020  switch_safe_free(expires_lookup);
2021  }
2022  if (expires) {
2023  char *expires_val = switch_must_malloc(1024);
2024  if (sprintf(expires_val, "%ld", (long)expires)) {
2025  switch_core_hash_insert(CACHE_EXPIRES_HASH, mega_key, expires_val);
2026  } else {
2027  switch_safe_free(expires_val);
2028  }
2029  }
2032 }
void * switch_core_hash_find(_In_ switch_hash_t *hash, _In_z_ const char *key)
Retrieve data from a given hash.
static void * switch_must_malloc(size_t _b)
Definition: switch_core.h:231
A representation of an XML tree.
Definition: switch_xml.h:76
static switch_hash_t * CACHE_HASH
Definition: switch_xml.c:188
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_xml_t switch_xml_dup(switch_xml_t xml)
Definition: switch_xml.c:1862
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
void * switch_core_hash_delete(_In_ switch_hash_t *hash, _In_z_ const char *key)
Delete data from a hash based on desired key.
static switch_hash_t * CACHE_EXPIRES_HASH
Definition: switch_xml.c:189
#define switch_core_hash_insert(_h, _k, _d)
Definition: switch_core.h:1410
static switch_mutex_t * CACHE_MUTEX
Definition: switch_xml.c:179
void switch_xml_free(switch_xml_t xml)
Definition: switch_xml.c:2701
static switch_xml_t switch_xml_vget ( switch_xml_t  xml,
va_list  ap 
)
static

Definition at line 462 of file switch_xml.c.

References xml_section_t::name, switch_xml_child(), and switch_xml_idx().

Referenced by switch_xml_get().

463 {
464  char *name = va_arg(ap, char *);
465  int idx = -1;
466 
467  if (name && *name) {
468  idx = va_arg(ap, int);
469  xml = switch_xml_child(xml, name);
470  }
471  return (idx < 0) ? xml : switch_xml_vget(switch_xml_idx(xml, idx), ap);
472 }
switch_xml_t switch_xml_idx(switch_xml_t xml, int idx)
Definition: switch_xml.c:418
static switch_xml_t switch_xml_vget(switch_xml_t xml, va_list ap)
Definition: switch_xml.c:462
switch_xml_t switch_xml_child(switch_xml_t xml, const char *name)
Definition: switch_xml.c:409

Variable Documentation

switch_thread_rwlock_t* B_RWLOCK = NULL
static

Definition at line 177 of file switch_xml.c.

switch_xml_binding_t* BINDINGS = NULL
static

Definition at line 173 of file switch_xml.c.

switch_hash_t* CACHE_EXPIRES_HASH = NULL
static
switch_hash_t* CACHE_HASH = NULL
static
switch_mutex_t* CACHE_MUTEX = NULL
static

Definition at line 179 of file switch_xml.c.

switch_mutex_t* FILE_LOCK = NULL
static

Definition at line 181 of file switch_xml.c.

switch_xml_t MAIN_XML_ROOT = NULL
static

Definition at line 174 of file switch_xml.c.

Referenced by switch_xml_destroy(), switch_xml_root(), and switch_xml_set_root().

char not_so_threadsafe_error_buffer[256] = ""
static

Definition at line 2213 of file switch_xml.c.

Referenced by __switch_xml_open_root().

switch_mutex_t* REFLOCK = NULL
static

Definition at line 180 of file switch_xml.c.

struct xml_section_t SECTIONS[]
static
char* SWITCH_XML_NIL[] = { NULL }

Definition at line 163 of file switch_xml.c.

Referenced by switch_xml_add_child(), switch_xml_internal_dtd(), and switch_xml_pi().

switch_bool_t USE_UTF_8_ENCODING = SWITCH_TRUE
static

Definition at line 106 of file switch_xml.c.

switch_mutex_t* XML_LOCK = NULL
static

Definition at line 178 of file switch_xml.c.

switch_memory_pool_t* XML_MEMORY_POOL = NULL
static

Definition at line 175 of file switch_xml.c.

Definition at line 185 of file switch_xml.c.

Referenced by switch_xml_open_root(), and switch_xml_set_open_root_function().

void* XML_OPEN_ROOT_FUNCTION_USER_DATA = NULL
static

Definition at line 186 of file switch_xml.c.

Referenced by switch_xml_open_root(), and switch_xml_set_open_root_function().