diff --git a/src/include/switch_apr.h b/src/include/switch_apr.h index 8ed7c98621..d11a9db32a 100644 --- a/src/include/switch_apr.h +++ b/src/include/switch_apr.h @@ -742,6 +742,20 @@ SWITCH_DECLARE(switch_status_t) switch_file_exists(const char *filename, switch_ typedef struct switch_dir switch_dir_t; +struct switch_array_header_t { + /** The pool the array is allocated out of */ + switch_memory_pool_t *pool; + /** The amount of memory allocated for each element of the array */ + int elt_size; + /** The number of active elements in the array */ + int nelts; + /** The number of elements allocated in the array */ + int nalloc; + /** The elements in the array */ + char *elts; +}; +typedef struct switch_array_header_t switch_array_header_t; + SWITCH_DECLARE(switch_status_t) switch_dir_open(switch_dir_t **new_dir, const char *dirname, switch_memory_pool_t *pool); SWITCH_DECLARE(switch_status_t) switch_dir_close(switch_dir_t *thedir); SWITCH_DECLARE(const char *) switch_dir_next_file(switch_dir_t *thedir, char *buf, switch_size_t len); @@ -1143,6 +1157,8 @@ SWITCH_DECLARE(switch_status_t) switch_poll(switch_pollfd_t * aprset, int32_t nu */ SWITCH_DECLARE(switch_status_t) switch_socket_create_pollfd(switch_pollfd_t ** poll, switch_socket_t * sock, int16_t flags, switch_memory_pool_t *pool); +SWITCH_DECLARE(switch_status_t) switch_match_glob(const char *pattern, switch_array_header_t **result, switch_memory_pool_t *p); + /** @} */ diff --git a/src/switch_apr.c b/src/switch_apr.c index 1637290041..b02680471b 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -53,6 +53,9 @@ #define APR_WANT_STDIO #define APR_WANT_STRFUNC #include +#include +#include +#include /* apr_vformatter_buff_t definition*/ #include @@ -714,7 +717,12 @@ SWITCH_DECLARE(int) switch_vasprintf(char **ret, const char *fmt, va_list ap) #endif } +SWITCH_DECLARE(switch_status_t) switch_match_glob(const char *pattern, switch_array_header_t **result, switch_memory_pool_t *p) +{ + return apr_match_glob(pattern, (apr_array_header_t **)result, p); +} + /* For Emacs: * Local Variables: * mode:c diff --git a/src/switch_xml.c b/src/switch_xml.c index d33ce357b1..9a6c39ac82 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -68,6 +68,8 @@ extern int madvise(caddr_t, size_t, int); #define SWITCH_XML_WS "\t\r\n " // whitespace #define SWITCH_XML_ERRL 128 // maximum error string length +static int preprocess(const char *file, int write_fd, int rlevel); + typedef struct switch_xml_root *switch_xml_root_t; struct switch_xml_root { // additional data for the root tag struct switch_xml xml; // is a super-struct built on top of switch_xml struct @@ -933,6 +935,57 @@ static char *expand_vars(char *buf, char *ebuf, switch_size_t elen, switch_size_ } +/* for apr file and directory handling */ +#include + +static int preprocess_glob(const char *pattern, int write_fd, int rlevel) +{ + + switch_array_header_t *result; + switch_memory_pool_t *pool; + char **list; + int i; + char *p, *dir_path = NULL; + + switch_core_new_memory_pool(&pool); + assert(pool != NULL); + + if (switch_is_file_path(pattern)) { + dir_path = switch_core_strdup(pool, pattern); + if ((p = strrchr(dir_path, *SWITCH_PATH_SEPARATOR))) { + *p = '\0'; + } + } else { + dir_path = SWITCH_GLOBAL_dirs.conf_dir; + p = switch_core_sprintf(pool, "%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, pattern); + pattern = p; + } + + switch_match_glob(pattern, &result, pool); + + list = (char **)result->elts; + + for (i = 0; i < result->nelts; i++) { + char *path = list[i]; + + if (strcmp(path, ".") && strcmp(path, "..")) { + p = switch_core_sprintf(pool, "%s%s%s", dir_path, SWITCH_PATH_SEPARATOR, path); + if (preprocess(p, write_fd, rlevel) < 0) { + const char *reason = strerror(errno); + if (rlevel > 100) { + reason = "Maximum recursion limit reached"; + } + fprintf(stderr, "Error including %s (%s)\n", p, reason); + } + } + } + + switch_core_destroy_memory_pool(&pool); + + + return write_fd; +} + static int preprocess(const char *file, int write_fd, int rlevel) { int read_fd = -1; @@ -1016,17 +1069,8 @@ static int preprocess(const char *file, int write_fd, int rlevel) } } else if (!strcasecmp(cmd, "include")) { - char *fme = NULL, *ifile = arg; - - if (!switch_is_file_path(ifile)) { - fme = switch_mprintf("%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, arg); - ifile = fme; - } - if (preprocess(ifile, write_fd, rlevel + 1) < 0) { - fprintf(stderr, "Error including %s (%s)\n", ifile, strerror(errno)); - } - switch_safe_free(fme); - } /* else NO OP */ + preprocess_glob(arg, write_fd, rlevel + 1); + } } continue;