]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
revert
authorAnthony Minessale <anthm@freeswitch.org>
Tue, 20 Nov 2012 16:13:05 +0000 (10:13 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Tue, 20 Nov 2012 16:13:05 +0000 (10:13 -0600)
src/switch_core.c

index 9bbb11956dabca4cf40b254abd6ab5c4bcc804f4..4682d3c0022d12183a9920a1a4c8c3871cc774bd 100644 (file)
-/* \r
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application\r
- * Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>\r
- *\r
- * Version: MPL 1.1\r
- *\r
- * The contents of this file are subject to the Mozilla Public License Version\r
- * 1.1 (the "License"); you may not use this file except in compliance with\r
- * the License. You may obtain a copy of the License at\r
- * http://www.mozilla.org/MPL/\r
- *\r
- * Software distributed under the License is distributed on an "AS IS" basis,\r
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\r
- * for the specific language governing rights and limitations under the\r
- * License.\r
- *\r
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application\r
- *\r
- * The Initial Developer of the Original Code is\r
- * Anthony Minessale II <anthm@freeswitch.org>\r
- * Portions created by the Initial Developer are Copyright (C)\r
- * the Initial Developer. All Rights Reserved.\r
- *\r
- * Contributor(s):\r
- * \r
- * Anthony Minessale II <anthm@freeswitch.org>\r
- * Michael Jerris <mike@jerris.com>\r
- * Paul D. Tinsley <pdt at jackhammer.org>\r
- * Marcel Barbulescu <marcelbarbulescu@gmail.com>\r
- * Joseph Sullivan <jossulli@amazon.com>\r
- *\r
- *\r
- * switch_core.c -- Main Core Library\r
- *\r
- */\r
-\r
-\r
-\r
-#include <switch.h>\r
-#include <switch_ssl.h>\r
-#include <switch_stun.h>\r
-#include <switch_nat.h>\r
-#include <switch_version.h>\r
-#include "private/switch_core_pvt.h"\r
-#include <switch_curl.h>\r
-#ifndef WIN32\r
-#include <switch_private.h>\r
-#ifdef HAVE_SETRLIMIT\r
-#include <sys/resource.h>\r
-#endif\r
-#endif\r
-#include <errno.h>\r
-\r
-\r
-SWITCH_DECLARE_DATA switch_directories SWITCH_GLOBAL_dirs = { 0 };\r
-\r
-/* The main runtime obj we keep this hidden for ourselves */\r
-struct switch_runtime runtime = { 0 };\r
-static void switch_load_core_config(const char *file);\r
-\r
-static void send_heartbeat(void)\r
-{\r
-       switch_event_t *event;\r
-       switch_core_time_duration_t duration;\r
-\r
-       switch_core_measure_time(switch_core_uptime(), &duration);\r
-\r
-       if (switch_event_create(&event, SWITCH_EVENT_HEARTBEAT) == SWITCH_STATUS_SUCCESS) {\r
-               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready");\r
-               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Up-Time",\r
-                                                               "%u year%s, "\r
-                                                               "%u day%s, "\r
-                                                               "%u hour%s, "\r
-                                                               "%u minute%s, "\r
-                                                               "%u second%s, "\r
-                                                               "%u millisecond%s, "\r
-                                                               "%u microsecond%s",\r
-                                                               duration.yr, duration.yr == 1 ? "" : "s",\r
-                                                               duration.day, duration.day == 1 ? "" : "s",\r
-                                                               duration.hr, duration.hr == 1 ? "" : "s",\r
-                                                               duration.min, duration.min == 1 ? "" : "s",\r
-                                                               duration.sec, duration.sec == 1 ? "" : "s",\r
-                                                               duration.ms, duration.ms == 1 ? "" : "s", duration.mms, duration.mms == 1 ? "" : "s");\r
-\r
-               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FreeSWITCH-Version", SWITCH_VERSION_FULL);\r
-               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Uptime-msec", "%"SWITCH_TIME_T_FMT, switch_core_uptime() / 1000);\r
-               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Count", "%u", switch_core_session_count());\r
-               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Max-Sessions", "%u", switch_core_session_limit(0));\r
-               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec", "%u", runtime.sps);\r
-               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Since-Startup", "%" SWITCH_SIZE_T_FMT, switch_core_session_id() - 1);\r
-               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Idle-CPU", "%f", switch_core_idle_cpu());\r
-               switch_event_fire(&event);\r
-       }\r
-}\r
-\r
-static char main_ip4[256] = "";\r
-static char main_ip6[256] = "";\r
-\r
-static void check_ip(void)\r
-{\r
-       char guess_ip4[256] = "";\r
-       char guess_ip6[256] = "";\r
-       char old_ip4[256] = "";\r
-       char old_ip6[256] = "";\r
-       int ok4 = 1, ok6 = 1;\r
-       int mask = 0;\r
-\r
-       gethostname(runtime.hostname, sizeof(runtime.hostname));\r
-       switch_core_set_variable("hostname", runtime.hostname);\r
-\r
-       switch_find_local_ip(guess_ip4, sizeof(guess_ip4), &mask, AF_INET);\r
-       switch_find_local_ip(guess_ip6, sizeof(guess_ip6), NULL, AF_INET6);\r
-\r
-       if (!*main_ip4) {\r
-               switch_set_string(main_ip4, guess_ip4);\r
-       } else {\r
-               if (!(ok4 = !strcmp(main_ip4, guess_ip4))) {\r
-                       struct in_addr in;\r
-\r
-                       in.s_addr = mask;\r
-                       switch_set_string(old_ip4, main_ip4);\r
-                       switch_set_string(main_ip4, guess_ip4);\r
-                       switch_core_set_variable("local_ip_v4", guess_ip4);\r
-                       switch_core_set_variable("local_mask_v4", inet_ntoa(in));\r
-               }\r
-       }\r
-\r
-       if (!*main_ip6) {\r
-               switch_set_string(main_ip6, guess_ip6);\r
-       } else {\r
-               if (!(ok6 = !strcmp(main_ip6, guess_ip6))) {\r
-                       switch_set_string(old_ip6, main_ip6);\r
-                       switch_set_string(main_ip6, guess_ip6);\r
-                       switch_core_set_variable("local_ip_v6", guess_ip6);\r
-               }\r
-       }\r
-\r
-       if (!ok4 || !ok6) {\r
-               switch_event_t *event;\r
-\r
-               if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {\r
-                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "network-address-change");\r
-                       if (!ok4) {\r
-                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v4", old_ip4);\r
-                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v4", main_ip4);\r
-                       }\r
-                       if (!ok6) {\r
-                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v6", old_ip6);\r
-                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v6", main_ip6);\r
-                       }\r
-                       switch_event_fire(&event);\r
-               }\r
-       }\r
-}\r
-\r
-SWITCH_STANDARD_SCHED_FUNC(heartbeat_callback)\r
-{\r
-       send_heartbeat();\r
-\r
-       /* reschedule this task */\r
-       task->runtime = switch_epoch_time_now(NULL) + 20;\r
-}\r
-\r
-\r
-SWITCH_STANDARD_SCHED_FUNC(check_ip_callback)\r
-{\r
-       check_ip();\r
-\r
-       /* reschedule this task */\r
-       task->runtime = switch_epoch_time_now(NULL) + 60;\r
-}\r
-\r
-\r
-SWITCH_DECLARE(switch_status_t) switch_core_set_console(const char *console)\r
-{\r
-       if ((runtime.console = fopen(console, "a")) == 0) {\r
-               fprintf(stderr, "Cannot open output file %s.\n", console);\r
-               return SWITCH_STATUS_FALSE;\r
-       }\r
-\r
-       return SWITCH_STATUS_SUCCESS;\r
-}\r
-\r
-SWITCH_DECLARE(FILE *) switch_core_get_console(void)\r
-{\r
-       return runtime.console;\r
-}\r
-\r
-#ifdef HAVE_SYS_IOCTL_H\r
-#include <sys/ioctl.h>\r
-#endif\r
-SWITCH_DECLARE(void) switch_core_screen_size(int *x, int *y)\r
-{\r
-\r
-#ifdef WIN32\r
-       CONSOLE_SCREEN_BUFFER_INFO csbi;\r
-       int ret;\r
-\r
-       if ((ret = GetConsoleScreenBufferInfo(GetStdHandle( STD_OUTPUT_HANDLE ), &csbi))) {\r
-               if (x) *x = csbi.dwSize.X;\r
-               if (y) *y = csbi.dwSize.Y;\r
-       }\r
-\r
-#elif defined(TIOCGWINSZ)\r
-       struct winsize w;\r
-       ioctl(0, TIOCGWINSZ, &w);\r
-\r
-       if (x) *x = w.ws_col;\r
-       if (y) *y = w.ws_row;\r
-#else\r
-       if (x) *x = 80;\r
-       if (y) *y = 24;\r
-#endif\r
-\r
-}\r
-\r
-SWITCH_DECLARE(FILE *) switch_core_data_channel(switch_text_channel_t channel)\r
-{\r
-       FILE *handle = stdout;\r
-\r
-       switch (channel) {\r
-       case SWITCH_CHANNEL_ID_LOG:\r
-       case SWITCH_CHANNEL_ID_LOG_CLEAN:\r
-               handle = runtime.console;\r
-               break;\r
-       default:\r
-               handle = runtime.console;\r
-               break;\r
-       }\r
-\r
-       return handle;\r
-}\r
-\r
-\r
-SWITCH_DECLARE(void) switch_core_remove_state_handler(const switch_state_handler_table_t *state_handler)\r
-{\r
-       int index, tmp_index = 0;\r
-       const switch_state_handler_table_t *tmp[SWITCH_MAX_STATE_HANDLERS + 1] = { 0 };\r
-\r
-       switch_mutex_lock(runtime.global_mutex);\r
-\r
-       for (index = 0; index < runtime.state_handler_index; index++) {\r
-               const switch_state_handler_table_t *cur = runtime.state_handlers[index];\r
-               runtime.state_handlers[index] = NULL;\r
-               if (cur == state_handler) {\r
-                       continue;\r
-               }\r
-               tmp[tmp_index++] = cur;\r
-       }\r
-\r
-       runtime.state_handler_index = 0;\r
-\r
-       for (index = 0; index < tmp_index; index++) {\r
-               runtime.state_handlers[runtime.state_handler_index++] = tmp[index];\r
-       }\r
-       switch_mutex_unlock(runtime.global_mutex);\r
-}\r
-\r
-\r
-SWITCH_DECLARE(int) switch_core_add_state_handler(const switch_state_handler_table_t *state_handler)\r
-{\r
-       int index;\r
-\r
-       switch_mutex_lock(runtime.global_mutex);\r
-       index = runtime.state_handler_index++;\r
-\r
-       if (runtime.state_handler_index >= SWITCH_MAX_STATE_HANDLERS) {\r
-               index = -1;\r
-       } else {\r
-               runtime.state_handlers[index] = state_handler;\r
-       }\r
-\r
-       switch_mutex_unlock(runtime.global_mutex);\r
-       return index;\r
-}\r
-\r
-SWITCH_DECLARE(const switch_state_handler_table_t *) switch_core_get_state_handler(int index)\r
-{\r
-\r
-       if (index >= SWITCH_MAX_STATE_HANDLERS || index > runtime.state_handler_index) {\r
-               return NULL;\r
-       }\r
-\r
-       return runtime.state_handlers[index];\r
-}\r
-\r
-SWITCH_DECLARE(void) switch_core_dump_variables(switch_stream_handle_t *stream)\r
-{\r
-       switch_event_header_t *hi;\r
-\r
-       switch_mutex_lock(runtime.global_mutex);\r
-       for (hi = runtime.global_vars->headers; hi; hi = hi->next) {\r
-               stream->write_function(stream, "%s=%s\n", hi->name, hi->value);\r
-       }\r
-       switch_mutex_unlock(runtime.global_mutex);\r
-}\r
-\r
-SWITCH_DECLARE(const char *) switch_core_get_hostname(void)\r
-{\r
-       return runtime.hostname;\r
-}\r
-\r
-SWITCH_DECLARE(const char *) switch_core_get_switchname(void)\r
-{\r
-    if (!zstr(runtime.switchname)) return runtime.switchname;\r
-       return runtime.hostname;\r
-}\r
-\r
-\r
-SWITCH_DECLARE(char *) switch_core_get_variable(const char *varname)\r
-{\r
-       char *val;\r
-       switch_thread_rwlock_rdlock(runtime.global_var_rwlock);\r
-       val = (char *) switch_event_get_header(runtime.global_vars, varname);\r
-       switch_thread_rwlock_unlock(runtime.global_var_rwlock);\r
-       return val;\r
-}\r
-\r
-SWITCH_DECLARE(char *) switch_core_get_variable_dup(const char *varname)\r
-{\r
-       char *val = NULL, *v;\r
-\r
-       switch_thread_rwlock_rdlock(runtime.global_var_rwlock);\r
-       if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) {\r
-               val = strdup(v);\r
-       }\r
-       switch_thread_rwlock_unlock(runtime.global_var_rwlock);\r
-\r
-       return val;\r
-}\r
-\r
-SWITCH_DECLARE(char *) switch_core_get_variable_pdup(const char *varname, switch_memory_pool_t *pool)\r
-{\r
-       char *val = NULL, *v;\r
-\r
-       switch_thread_rwlock_rdlock(runtime.global_var_rwlock);\r
-       if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) {\r
-               val = switch_core_strdup(pool, v);\r
-       }\r
-       switch_thread_rwlock_unlock(runtime.global_var_rwlock);\r
-\r
-       return val;\r
-}\r
-\r
-static void switch_core_unset_variables(void)\r
-{\r
-       switch_thread_rwlock_wrlock(runtime.global_var_rwlock);\r
-       switch_event_destroy(&runtime.global_vars);\r
-       switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA);\r
-       switch_thread_rwlock_unlock(runtime.global_var_rwlock);\r
-}\r
-\r
-SWITCH_DECLARE(void) switch_core_set_variable(const char *varname, const char *value)\r
-{\r
-       char *val;\r
-\r
-       if (varname) {\r
-               switch_thread_rwlock_wrlock(runtime.global_var_rwlock);\r
-               val = (char *) switch_event_get_header(runtime.global_vars, varname);\r
-               if (val) {\r
-                       switch_event_del_header(runtime.global_vars, varname);\r
-               }\r
-               if (value) {\r
-                       char *v = strdup(value);\r
-                       switch_string_var_check(v, SWITCH_TRUE);\r
-                       switch_event_add_header_string(runtime.global_vars, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, varname, v);\r
-               } else {\r
-                       switch_event_del_header(runtime.global_vars, varname);\r
-               }\r
-               switch_thread_rwlock_unlock(runtime.global_var_rwlock);\r
-       }\r
-}\r
-\r
-SWITCH_DECLARE(switch_bool_t) switch_core_set_var_conditional(const char *varname, const char *value, const char *val2)\r
-{\r
-       char *val;\r
-\r
-       if (varname) {\r
-               switch_thread_rwlock_wrlock(runtime.global_var_rwlock);\r
-               val = (char *) switch_event_get_header(runtime.global_vars, varname);\r
-\r
-               if (val) {\r
-                       if (!val2 || strcmp(val, val2) != 0) {\r
-                               switch_thread_rwlock_unlock(runtime.global_var_rwlock);\r
-                               return SWITCH_FALSE;\r
-                       }\r
-                       switch_event_del_header(runtime.global_vars, varname);\r
-               } else if (!zstr(val2)) {\r
-                       switch_thread_rwlock_unlock(runtime.global_var_rwlock);\r
-                       return SWITCH_FALSE;\r
-               }\r
-\r
-               if (value) {\r
-                       char *v = strdup(value);\r
-                       switch_string_var_check(v, SWITCH_TRUE);\r
-                       switch_event_add_header_string(runtime.global_vars, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, varname, v);\r
-               } else {\r
-                       switch_event_del_header(runtime.global_vars, varname);\r
-               }\r
-               switch_thread_rwlock_unlock(runtime.global_var_rwlock);\r
-       }\r
-       return SWITCH_TRUE;\r
-}\r
-\r
-SWITCH_DECLARE(char *) switch_core_get_uuid(void)\r
-{\r
-       return runtime.uuid_str;\r
-}\r
-\r
-\r
-static void *SWITCH_THREAD_FUNC switch_core_service_thread(switch_thread_t *thread, void *obj)\r
-{\r
-       switch_core_session_t *session = obj;\r
-       switch_channel_t *channel;\r
-       switch_frame_t *read_frame;\r
-\r
-//  switch_assert(thread != NULL);\r
-//  switch_assert(session != NULL);\r
-\r
-       if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {\r
-               return NULL;\r
-       }\r
-\r
-       switch_mutex_lock(session->frame_read_mutex);\r
-\r
-       channel = switch_core_session_get_channel(session);\r
-\r
-       switch_channel_set_flag(channel, CF_SERVICE);\r
-       while (switch_channel_test_flag(channel, CF_SERVICE)) {\r
-\r
-               if (switch_channel_test_flag(channel, CF_SERVICE_AUDIO)) {\r
-                       switch (switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) {\r
-                       case SWITCH_STATUS_SUCCESS:\r
-                       case SWITCH_STATUS_TIMEOUT:\r
-                       case SWITCH_STATUS_BREAK:\r
-                               break;\r
-                       default:\r
-                               switch_channel_clear_flag(channel, CF_SERVICE);\r
-                               break;\r
-                       }\r
-               }\r
-\r
-               if (switch_channel_test_flag(channel, CF_SERVICE_VIDEO) && switch_channel_test_flag(channel, CF_VIDEO)) {\r
-                       switch (switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) {\r
-                       case SWITCH_STATUS_SUCCESS:\r
-                       case SWITCH_STATUS_TIMEOUT:\r
-                       case SWITCH_STATUS_BREAK:\r
-                               break;\r
-                       default:\r
-                               switch_channel_clear_flag(channel, CF_SERVICE);\r
-                               break;\r
-                       }\r
-               }\r
-       }\r
-\r
-       switch_mutex_unlock(session->frame_read_mutex);\r
-\r
-       switch_channel_clear_flag(channel, CF_SERVICE_AUDIO);\r
-       switch_channel_clear_flag(channel, CF_SERVICE_VIDEO);\r
-\r
-       switch_core_session_rwunlock(session);\r
-\r
-       return NULL;\r
-}\r
-\r
-/* Either add a timeout here or make damn sure the thread cannot get hung somehow (my preference) */\r
-SWITCH_DECLARE(void) switch_core_thread_session_end(switch_core_session_t *session)\r
-{\r
-       switch_channel_t *channel;\r
-       switch_assert(session);\r
-\r
-       channel = switch_core_session_get_channel(session);\r
-       switch_assert(channel);\r
-\r
-       switch_channel_clear_flag(channel, CF_SERVICE);\r
-       switch_channel_clear_flag(channel, CF_SERVICE_AUDIO);\r
-       switch_channel_clear_flag(channel, CF_SERVICE_VIDEO);\r
-\r
-       switch_core_session_kill_channel(session, SWITCH_SIG_BREAK);\r
-       \r
-}\r
-\r
-SWITCH_DECLARE(void) switch_core_service_session_av(switch_core_session_t *session, switch_bool_t audio, switch_bool_t video)\r
-{\r
-       switch_channel_t *channel;\r
-       switch_assert(session);\r
-\r
-       channel = switch_core_session_get_channel(session);\r
-       switch_assert(channel);\r
-\r
-       if (audio) switch_channel_set_flag(channel, CF_SERVICE_AUDIO);\r
-       if (video) switch_channel_set_flag(channel, CF_SERVICE_VIDEO);\r
-\r
-       switch_core_session_launch_thread(session, (void *(*)(switch_thread_t *,void *))switch_core_service_thread, session);\r
-}\r
-\r
-/* This function abstracts the thread creation for modules by allowing you to pass a function ptr and\r
-   a void object and trust that that the function will be run in a thread with arg  This lets\r
-   you request and activate a thread without giving up any knowledge about what is in the thread\r
-   neither the core nor the calling module know anything about each other.\r
-\r
-   This thread is expected to never exit until the application exits so the func is responsible\r
-   to make sure that is the case.\r
-\r
-   The typical use for this is so switch_loadable_module.c can start up a thread for each module\r
-   passing the table of module methods as a session obj into the core without actually allowing\r
-   the core to have any clue and keeping switch_loadable_module.c from needing any thread code.\r
-\r
-*/\r
-\r
-SWITCH_DECLARE(switch_thread_t *) switch_core_launch_thread(switch_thread_start_t func, void *obj, switch_memory_pool_t *pool)\r
-{\r
-       switch_thread_t *thread = NULL;\r
-       switch_threadattr_t *thd_attr = NULL;\r
-       switch_core_thread_session_t *ts;\r
-       int mypool;\r
-\r
-       mypool = pool ? 0 : 1;\r
-\r
-       if (!pool && switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {\r
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory pool\n");\r
-               return NULL;\r
-       }\r
-\r
-       switch_threadattr_create(&thd_attr, pool);\r
-\r
-       if ((ts = switch_core_alloc(pool, sizeof(*ts))) == 0) {\r
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory\n");\r
-       } else {\r
-               if (mypool) {\r
-                       ts->pool = pool;\r
-               }\r
-               ts->objs[0] = obj;\r
-               ts->objs[1] = thread;\r
-               switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);\r
-               switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);\r
-               switch_thread_create(&thread, thd_attr, func, ts, pool);\r
-       }\r
-\r
-       return thread;\r
-}\r
-\r
-SWITCH_DECLARE(void) switch_core_set_globals(void)\r
-{\r
-#define BUFSIZE 1024\r
-#ifdef WIN32\r
-       char lpPathBuffer[BUFSIZE];\r
-       DWORD dwBufSize = BUFSIZE;\r
-       char base_dir[1024];\r
-       char *lastbacklash;\r
-       char *tmp;\r
-\r
-       GetModuleFileName(NULL, base_dir, BUFSIZE);\r
-       lastbacklash = strrchr(base_dir, '\\');\r
-       base_dir[(lastbacklash - base_dir)] = '\0';\r
-       /* set base_dir as cwd, to be able to use relative paths in scripting languages (e.g. mod_lua) when FS is running as a service or while debugging FS using visual studio */\r
-       SetCurrentDirectory(base_dir);\r
-       tmp = switch_string_replace(base_dir, "\\", "/");\r
-       strcpy(base_dir, tmp);\r
-       free(tmp);\r
-\r
-#else\r
-       char base_dir[1024] = SWITCH_PREFIX_DIR;\r
-#endif\r
-\r
-       if (!SWITCH_GLOBAL_dirs.base_dir && (SWITCH_GLOBAL_dirs.base_dir = (char *) malloc(BUFSIZE))) {\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.base_dir, BUFSIZE, "%s", base_dir);\r
-       }\r
-\r
-       if (!SWITCH_GLOBAL_dirs.mod_dir && (SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(BUFSIZE))) {\r
-#ifdef SWITCH_MOD_DIR\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s", SWITCH_MOD_DIR);\r
-#else\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s%smod", base_dir, SWITCH_PATH_SEPARATOR);\r
-#endif\r
-       }\r
-\r
-       if (!SWITCH_GLOBAL_dirs.lib_dir && (SWITCH_GLOBAL_dirs.lib_dir = (char *) malloc(BUFSIZE))) {\r
-#ifdef SWITCH_LIB_DIR\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s", SWITCH_LIB_DIR);\r
-#else\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s%slib", base_dir, SWITCH_PATH_SEPARATOR);\r
-#endif\r
-       }\r
-\r
-       if (!SWITCH_GLOBAL_dirs.conf_dir && (SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(BUFSIZE))) {\r
-#ifdef SWITCH_CONF_DIR\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s", SWITCH_CONF_DIR);\r
-#else\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s%sconf", base_dir, SWITCH_PATH_SEPARATOR);\r
-#endif\r
-       }\r
-\r
-       if (!SWITCH_GLOBAL_dirs.log_dir && (SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(BUFSIZE))) {\r
-#ifdef SWITCH_LOG_DIR\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s", SWITCH_LOG_DIR);\r
-#else\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s%slog", base_dir, SWITCH_PATH_SEPARATOR);\r
-#endif\r
-       }\r
-\r
-       if (!SWITCH_GLOBAL_dirs.run_dir && (SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(BUFSIZE))) {\r
-#ifdef SWITCH_RUN_DIR\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE, "%s", SWITCH_RUN_DIR);\r
-#else\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE, "%s%srun", base_dir, SWITCH_PATH_SEPARATOR);\r
-#endif\r
-       }\r
-\r
-       if (!SWITCH_GLOBAL_dirs.recordings_dir && (SWITCH_GLOBAL_dirs.recordings_dir = (char *) malloc(BUFSIZE))) {\r
-#ifdef SWITCH_RECORDINGS_DIR\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE, "%s", SWITCH_RECORDINGS_DIR);\r
-#else\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE, "%s%srecordings", base_dir, SWITCH_PATH_SEPARATOR);\r
-#endif\r
-       }\r
-\r
-       if (!SWITCH_GLOBAL_dirs.sounds_dir && (SWITCH_GLOBAL_dirs.sounds_dir = (char *) malloc(BUFSIZE))) {\r
-#ifdef SWITCH_SOUNDS_DIR\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE, "%s", SWITCH_SOUNDS_DIR);\r
-#else\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE, "%s%ssounds", base_dir, SWITCH_PATH_SEPARATOR);\r
-#endif\r
-       }\r
-\r
-       if (!SWITCH_GLOBAL_dirs.storage_dir && (SWITCH_GLOBAL_dirs.storage_dir = (char *) malloc(BUFSIZE))) {\r
-#ifdef SWITCH_STORAGE_DIR\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE, "%s", SWITCH_STORAGE_DIR);\r
-#else\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE, "%s%sstorage", base_dir, SWITCH_PATH_SEPARATOR);\r
-#endif\r
-       }\r
-\r
-       if (!SWITCH_GLOBAL_dirs.db_dir && (SWITCH_GLOBAL_dirs.db_dir = (char *) malloc(BUFSIZE))) {\r
-#ifdef SWITCH_DB_DIR\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s", SWITCH_DB_DIR);\r
-#else\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s%sdb", base_dir, SWITCH_PATH_SEPARATOR);\r
-#endif\r
-       }\r
-\r
-       if (!SWITCH_GLOBAL_dirs.script_dir && (SWITCH_GLOBAL_dirs.script_dir = (char *) malloc(BUFSIZE))) {\r
-#ifdef SWITCH_SCRIPT_DIR\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s", SWITCH_SCRIPT_DIR);\r
-#else\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s%sscripts", base_dir, SWITCH_PATH_SEPARATOR);\r
-#endif\r
-       }\r
-\r
-       if (!SWITCH_GLOBAL_dirs.htdocs_dir && (SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(BUFSIZE))) {\r
-#ifdef SWITCH_HTDOCS_DIR\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s", SWITCH_HTDOCS_DIR);\r
-#else\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s%shtdocs", base_dir, SWITCH_PATH_SEPARATOR);\r
-#endif\r
-       }\r
-\r
-       if (!SWITCH_GLOBAL_dirs.grammar_dir && (SWITCH_GLOBAL_dirs.grammar_dir = (char *) malloc(BUFSIZE))) {\r
-#ifdef SWITCH_GRAMMAR_DIR\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE, "%s", SWITCH_GRAMMAR_DIR);\r
-#else\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE, "%s%sgrammar", base_dir, SWITCH_PATH_SEPARATOR);\r
-#endif\r
-       }\r
-\r
-       if (!SWITCH_GLOBAL_dirs.temp_dir && (SWITCH_GLOBAL_dirs.temp_dir = (char *) malloc(BUFSIZE))) {\r
-#ifdef SWITCH_TEMP_DIR\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", SWITCH_TEMP_DIR);\r
-#else\r
-#ifdef WIN32\r
-               GetTempPath(dwBufSize, lpPathBuffer);\r
-               lpPathBuffer[strlen(lpPathBuffer)-1] = 0;\r
-               tmp = switch_string_replace(lpPathBuffer, "\\", "/");\r
-               strcpy(lpPathBuffer, tmp);\r
-               free(tmp);\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", lpPathBuffer);\r
-#else\r
-               switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", "/tmp");\r
-#endif\r
-#endif\r
-       }\r
-\r
-       switch_assert(SWITCH_GLOBAL_dirs.base_dir);\r
-       switch_assert(SWITCH_GLOBAL_dirs.mod_dir);\r
-       switch_assert(SWITCH_GLOBAL_dirs.lib_dir);\r
-       switch_assert(SWITCH_GLOBAL_dirs.conf_dir);\r
-       switch_assert(SWITCH_GLOBAL_dirs.log_dir);\r
-       switch_assert(SWITCH_GLOBAL_dirs.run_dir);\r
-       switch_assert(SWITCH_GLOBAL_dirs.db_dir);\r
-       switch_assert(SWITCH_GLOBAL_dirs.script_dir);\r
-       switch_assert(SWITCH_GLOBAL_dirs.htdocs_dir);\r
-       switch_assert(SWITCH_GLOBAL_dirs.grammar_dir);\r
-       switch_assert(SWITCH_GLOBAL_dirs.recordings_dir);\r
-       switch_assert(SWITCH_GLOBAL_dirs.sounds_dir);\r
-       switch_assert(SWITCH_GLOBAL_dirs.temp_dir);\r
-}\r
-\r
-\r
-SWITCH_DECLARE(int32_t) set_low_priority(void)\r
-{\r
-\r
-\r
-#ifdef WIN32\r
-       SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);\r
-#else\r
-#ifdef USE_SCHED_SETSCHEDULER\r
-       /*\r
-        * Try to use a normal scheduler\r
-        */\r
-       struct sched_param sched = { 0 };\r
-       sched.sched_priority = 0;\r
-       if (sched_setscheduler(0, SCHED_OTHER, &sched)) {\r
-               return -1;\r
-       }\r
-#endif\r
-\r
-#ifdef HAVE_SETPRIORITY\r
-       /*\r
-        * setpriority() works on FreeBSD (6.2), nice() doesn't\r
-        */\r
-       if (setpriority(PRIO_PROCESS, getpid(), 19) < 0) {\r
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n");\r
-               return -1;\r
-       }\r
-#else\r
-       if (nice(19) != 19) {\r
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n");\r
-               return -1;\r
-       }\r
-#endif\r
-#endif\r
-\r
-       return 0;\r
-}\r
-\r
-SWITCH_DECLARE(int32_t) set_realtime_priority(void)\r
-{\r
-#ifdef WIN32\r
-       SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);\r
-#else\r
-#ifdef USE_SCHED_SETSCHEDULER\r
-       /*\r
-        * Try to use a round-robin scheduler\r
-        * with a fallback if that does not work\r
-        */\r
-       struct sched_param sched = { 0 };\r
-       sched.sched_priority = SWITCH_PRI_LOW;\r
-       if (sched_setscheduler(0, SCHED_FIFO, &sched)) {\r
-               sched.sched_priority = 0;\r
-               if (sched_setscheduler(0, SCHED_OTHER, &sched)) {\r
-                       return -1;\r
-               }\r
-       }\r
-#endif\r
-\r
-       \r
-\r
-#ifdef HAVE_SETPRIORITY\r
-       /*\r
-        * setpriority() works on FreeBSD (6.2), nice() doesn't\r
-        */\r
-       if (setpriority(PRIO_PROCESS, getpid(), -10) < 0) {\r
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n");\r
-               return -1;\r
-       }\r
-#else\r
-       if (nice(-10) != -10) {\r
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n");\r
-               return -1;\r
-       }\r
-#endif\r
-#endif\r
-       return 0;\r
-}\r
-\r
-SWITCH_DECLARE(uint32_t) switch_core_cpu_count(void)\r
-{\r
-       return runtime.cpu_count;\r
-}\r
-\r
-SWITCH_DECLARE(int32_t) set_normal_priority(void)\r
-{\r
-       return 0;\r
-}\r
-\r
-SWITCH_DECLARE(int32_t) set_auto_priority(void)\r
-{\r
-#ifndef WIN32\r
-       runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN);\r
-#else\r
-       SYSTEM_INFO sysinfo;\r
-       GetSystemInfo( &sysinfo );\r
-       runtime.cpu_count = sysinfo.dwNumberOfProcessors;\r
-#endif\r
-\r
-       if (!runtime.cpu_count) runtime.cpu_count = 1;\r
-\r
-       /* If we have more than 1 cpu, we should use realtime priority so we can have priority threads */\r
-       if (runtime.cpu_count > 1) {\r
-               return set_realtime_priority();\r
-       }\r
-\r
-       return 0;\r
-}\r
-\r
-SWITCH_DECLARE(int32_t) change_user_group(const char *user, const char *group)\r
-{\r
-#ifndef WIN32\r
-       uid_t runas_uid = 0;\r
-       gid_t runas_gid = 0;\r
-       struct passwd *runas_pw = NULL;\r
-\r
-       if (user) {\r
-               /*\r
-                * Lookup user information in the system's db\r
-                */\r
-               runas_pw = getpwnam(user);\r
-               if (!runas_pw) {\r
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unknown user \"%s\"\n", user);\r
-                       return -1;\r
-               }\r
-               runas_uid = runas_pw->pw_uid;\r
-       }\r
-\r
-       if (group) {\r
-               struct group *gr = NULL;\r
-\r
-               /*\r
-                * Lookup group information in the system's db\r
-                */\r
-               gr = getgrnam(group);\r
-               if (!gr) {\r
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unknown group \"%s\"\n", group);\r
-                       return -1;\r
-               }\r
-               runas_gid = gr->gr_gid;\r
-       }\r
-\r
-       if (runas_uid && getuid() == runas_uid && (!runas_gid || runas_gid == getgid())) {\r
-               /* already running as the right user and group, nothing to do! */\r
-               return 0;\r
-       }\r
-\r
-       if (runas_uid) {\r
-#ifdef HAVE_SETGROUPS\r
-               /*\r
-                * Drop all group memberships prior to changing anything\r
-                * or else we're going to inherit the parent's list of groups\r
-                * (which is not what we want...)\r
-                */\r
-               if (setgroups(0, NULL) < 0) {\r
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to drop group access list\n");\r
-                       return -1;\r
-               }\r
-#endif\r
-               if (runas_gid) {\r
-                       /*\r
-                        * A group has been passed, switch to it\r
-                        * (without loading the user's other groups)\r
-                        */\r
-                       if (setgid(runas_gid) < 0) {\r
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change gid!\n");\r
-                               return -1;\r
-                       }\r
-               } else {\r
-                       /*\r
-                        * No group has been passed, use the user's primary group in this case\r
-                        */\r
-                       if (setgid(runas_pw->pw_gid) < 0) {\r
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change gid!\n");\r
-                               return -1;\r
-                       }\r
-#ifdef HAVE_INITGROUPS\r
-                       /*\r
-                        * Set all the other groups the user is a member of\r
-                        * (This can be really useful for fine-grained access control)\r
-                        */\r
-                       if (initgroups(runas_pw->pw_name, runas_pw->pw_gid) < 0) {\r
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to set group access list for user\n");\r
-                               return -1;\r
-                       }\r
-#endif\r
-               }\r
-\r
-               /*\r
-                * Finally drop all privileges by switching to the new userid\r
-                */\r
-               if (setuid(runas_uid) < 0) {\r
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change uid!\n");\r
-                       return -1;\r
-               }\r
-       }\r
-#endif\r
-       return 0;\r
-}\r
-\r
-SWITCH_DECLARE(void) switch_core_runtime_loop(int bg)\r
-{\r
-#ifdef WIN32\r
-       HANDLE shutdown_event;\r
-       char path[256] = "";\r
-#endif\r
-       if (bg) {\r
-               bg = 0;\r
-#ifdef WIN32\r
-               switch_snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid());\r
-               shutdown_event = CreateEvent(NULL, FALSE, FALSE, path);\r
-               if (shutdown_event) {\r
-                       WaitForSingleObject(shutdown_event, INFINITE);\r
-               }\r
-#else\r
-               runtime.running = 1;\r
-               while (runtime.running) {\r
-                       switch_yield(1000000);\r
-               }\r
-#endif\r
-       } else {\r
-               /* wait for console input */\r
-               switch_console_loop();\r
-       }\r
-}\r
-\r
-SWITCH_DECLARE(const char *) switch_core_mime_ext2type(const char *ext)\r
-{\r
-       if (!ext) {\r
-               return NULL;\r
-       }\r
-       return (const char *) switch_core_hash_find(runtime.mime_types, ext);\r
-}\r
-\r
-\r
-SWITCH_DECLARE(switch_hash_index_t *) switch_core_mime_index(void)\r
-{\r
-       return switch_hash_first(NULL, runtime.mime_types);\r
-}\r
-\r
-SWITCH_DECLARE(switch_status_t) switch_core_mime_add_type(const char *type, const char *ext)\r
-{\r
-       const char *check;\r
-       switch_status_t status = SWITCH_STATUS_FALSE;\r
-\r
-       switch_assert(type);\r
-       switch_assert(ext);\r
-\r
-       check = (const char *) switch_core_hash_find(runtime.mime_types, ext);\r
-\r
-       if (!check) {\r
-               char *ptype = switch_core_permanent_strdup(type);\r
-               char *ext_list = strdup(ext);\r
-               int argc = 0;\r
-               char *argv[20] = { 0 };\r
-               int x;\r
-\r
-               switch_assert(ext_list);\r
-\r
-               if ((argc = switch_separate_string(ext_list, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {\r
-\r
-                       for (x = 0; x < argc; x++) {\r
-                               if (argv[x] && ptype) {\r
-                                       switch_core_hash_insert(runtime.mime_types, argv[x], ptype);\r
-                               }\r
-                       }\r
-\r
-                       status = SWITCH_STATUS_SUCCESS;\r
-               }\r
-\r
-               free(ext_list);\r
-       }\r
-\r
-       return status;\r
-}\r
-\r
-static void load_mime_types(void)\r
-{\r
-       char *cf = "mime.types";\r
-       FILE *fd = NULL;\r
-       char *line_buf = NULL;\r
-       switch_size_t llen = 0;\r
-       char *mime_path = NULL;\r
-\r
-       mime_path = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.conf_dir, cf);\r
-       switch_assert(mime_path);\r
-\r
-       fd = fopen(mime_path, "rb");\r
-\r
-       if (fd == NULL) {\r
-               goto end;\r
-       }\r
-\r
-       while ((switch_fp_read_dline(fd, &line_buf, &llen))) {\r
-               char *p;\r
-               char *type = line_buf;\r
-\r
-               if (*line_buf == '#') {\r
-                       continue;\r
-               }\r
-\r
-               if ((p = strchr(line_buf, '\r')) || (p = strchr(line_buf, '\n'))) {\r
-                       *p = '\0';\r
-               }\r
-\r
-               if ((p = strchr(type, '\t')) || (p = strchr(type, ' '))) {\r
-                       *p++ = '\0';\r
-\r
-                       while (*p == ' ' || *p == '\t') {\r
-                               p++;\r
-                       }\r
-\r
-                       switch_core_mime_add_type(type, p);\r
-               }\r
-\r
-       }\r
-\r
-       switch_safe_free(line_buf);\r
-\r
-       if (fd) {\r
-               fclose(fd);\r
-               fd = NULL;\r
-       }\r
-\r
-  end:\r
-\r
-       switch_safe_free(mime_path);\r
-\r
-}\r
-\r
-SWITCH_DECLARE(void) switch_core_setrlimits(void)\r
-{\r
-#ifdef HAVE_SETRLIMIT\r
-       struct rlimit rlp;\r
-\r
-       /* \r
-          Setting the stack size on FreeBSD results in an instant crash.\r
-\r
-          If anyone knows how to fix this,\r
-          feel free to submit a patch to http://jira.freeswitch.org \r
-        */\r
-\r
-#ifndef __FreeBSD__\r
-       memset(&rlp, 0, sizeof(rlp));\r
-       rlp.rlim_cur = SWITCH_THREAD_STACKSIZE;\r
-       rlp.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE;\r
-       setrlimit(RLIMIT_STACK, &rlp);\r
-#endif\r
-\r
-       memset(&rlp, 0, sizeof(rlp));\r
-       rlp.rlim_cur = 999999;\r
-       rlp.rlim_max = 999999;\r
-       setrlimit(RLIMIT_NOFILE, &rlp);\r
-\r
-       memset(&rlp, 0, sizeof(rlp));\r
-       rlp.rlim_cur = RLIM_INFINITY;\r
-       rlp.rlim_max = RLIM_INFINITY;\r
-\r
-       setrlimit(RLIMIT_CPU, &rlp);\r
-       setrlimit(RLIMIT_DATA, &rlp);\r
-       setrlimit(RLIMIT_FSIZE, &rlp);\r
-#ifdef RLIMIT_NPROC\r
-       setrlimit(RLIMIT_NPROC, &rlp);\r
-#endif\r
-#ifdef RLIMIT_RTPRIO\r
-       setrlimit(RLIMIT_RTPRIO, &rlp);\r
-#endif\r
-\r
-#if !defined(__OpenBSD__) && !defined(__NetBSD__)\r
-       setrlimit(RLIMIT_AS, &rlp);\r
-#endif\r
-#endif\r
-       return;\r
-}\r
-\r
-typedef struct {\r
-       switch_memory_pool_t *pool;\r
-       switch_hash_t *hash;\r
-} switch_ip_list_t;\r
-\r
-static switch_ip_list_t IP_LIST = { 0 };\r
-\r
-SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token)\r
-{\r
-       switch_network_list_t *list;\r
-       ip_t  ip, mask, net;\r
-       uint32_t bits;\r
-       char *ipv6 = strchr(ip_str,':');\r
-       switch_bool_t ok = SWITCH_FALSE;\r
-\r
-       switch_mutex_lock(runtime.global_mutex);\r
-       if (ipv6) {\r
-               switch_inet_pton(AF_INET6, ip_str, &ip);\r
-       } else {\r
-               switch_inet_pton(AF_INET, ip_str, &ip);\r
-               ip.v4 = htonl(ip.v4);\r
-       }\r
-\r
-       if ((list = switch_core_hash_find(IP_LIST.hash, list_name))) {\r
-               if (ipv6) {\r
-                       ok = switch_network_list_validate_ip6_token(list, ip, token);\r
-               } else {\r
-                       ok = switch_network_list_validate_ip_token(list, ip.v4, token);\r
-               }\r
-       } else if (strchr(list_name, '/')) {\r
-               if (strchr(list_name, ',')) {\r
-                       char *list_name_dup = strdup(list_name);\r
-                       char *argv[32];\r
-                       int argc;\r
-\r
-                       switch_assert(list_name_dup);\r
-\r
-                       if ((argc = switch_separate_string(list_name_dup, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {\r
-                               int i;\r
-                               for (i = 0; i < argc; i++) {\r
-                                       switch_parse_cidr(argv[i], &net, &mask, &bits);\r
-                                       if (ipv6) {\r
-                                               if ((ok = switch_testv6_subnet(ip, net, mask))){\r
-                                                       break;\r
-                                               }\r
-                                       } else {\r
-                                               if ((ok = switch_test_subnet(ip.v4, net.v4, mask.v4))) {\r
-                                                       break;\r
-                                               }\r
-                                       }\r
-                               }\r
-                       }\r
-                       free(list_name_dup);\r
-               } else {\r
-                       switch_parse_cidr(list_name, &net, &mask, &bits);\r
-                       ok = switch_test_subnet(ip.v4, net.v4, mask.v4);\r
-               }\r
-       }\r
-       switch_mutex_unlock(runtime.global_mutex);\r
-\r
-       return ok;\r
-}\r
-\r
-\r
-SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload)\r
-{\r
-       switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, x_node = NULL, cfg = NULL;\r
-       switch_network_list_t *rfc_list, *list;\r
-       char guess_ip[16] = "";\r
-       int mask = 0;\r
-       char guess_mask[16] = "";\r
-       char *tmp_name;\r
-       struct in_addr in;\r
-\r
-       switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET);\r
-       in.s_addr = mask;\r
-       switch_set_string(guess_mask, inet_ntoa(in));\r
-\r
-       switch_mutex_lock(runtime.global_mutex);\r
-\r
-       if (IP_LIST.hash) {\r
-               switch_core_hash_destroy(&IP_LIST.hash);\r
-       }\r
-\r
-       if (IP_LIST.pool) {\r
-               switch_core_destroy_memory_pool(&IP_LIST.pool);\r
-       }\r
-\r
-       memset(&IP_LIST, 0, sizeof(IP_LIST));\r
-       switch_core_new_memory_pool(&IP_LIST.pool);\r
-       switch_core_hash_init(&IP_LIST.hash, IP_LIST.pool);\r
-\r
-\r
-       tmp_name = "rfc1918.auto";\r
-       switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);\r
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);\r
-       switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE);\r
-       switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE);\r
-       switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE);\r
-       switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);\r
-\r
-       tmp_name = "wan.auto";\r
-       switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool);\r
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name);\r
-       switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_FALSE);\r
-       switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_FALSE);\r
-       switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_FALSE);\r
-       switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);\r
-\r
-       tmp_name = "nat.auto";\r
-       switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);\r
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);\r
-       if (switch_network_list_add_host_mask(rfc_list, guess_ip, guess_mask, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {\r
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (deny) to list %s\n", guess_ip, guess_mask, tmp_name);\r
-       }\r
-       switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE);\r
-       switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE);\r
-       switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE);\r
-       switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);\r
-\r
-       tmp_name = "loopback.auto";\r
-       switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);\r
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);\r
-       switch_network_list_add_cidr(rfc_list, "127.0.0.0/8", SWITCH_TRUE);\r
-       switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);\r
-\r
-       tmp_name = "localnet.auto";\r
-       switch_network_list_create(&list, tmp_name, SWITCH_FALSE, IP_LIST.pool);\r
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);\r
-\r
-       if (switch_network_list_add_host_mask(list, guess_ip, guess_mask, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {\r
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (allow) to list %s\n", guess_ip, guess_mask, tmp_name);\r
-       }\r
-       switch_core_hash_insert(IP_LIST.hash, tmp_name, list);\r
-\r
-\r
-       if ((xml = switch_xml_open_cfg("acl.conf", &cfg, NULL))) {\r
-               if ((x_lists = switch_xml_child(cfg, "network-lists"))) {\r
-                       for (x_list = switch_xml_child(x_lists, "list"); x_list; x_list = x_list->next) {\r
-                               const char *name = switch_xml_attr(x_list, "name");\r
-                               const char *dft = switch_xml_attr(x_list, "default");\r
-                               switch_bool_t default_type = SWITCH_TRUE;\r
-\r
-                               if (zstr(name)) {\r
-                                       continue;\r
-                               }\r
-\r
-                               if (dft) {\r
-                                       default_type = switch_true(dft);\r
-                               }\r
-\r
-                               if (switch_network_list_create(&list, name, default_type, IP_LIST.pool) != SWITCH_STATUS_SUCCESS) {\r
-                                       abort();\r
-                               }\r
-\r
-                               if (reload) {\r
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny");\r
-                               } else {\r
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny");\r
-                               }\r
-\r
-\r
-                               for (x_node = switch_xml_child(x_list, "node"); x_node; x_node = x_node->next) {\r
-                                       const char *cidr = NULL, *host = NULL, *mask = NULL, *domain = NULL;\r
-                                       switch_bool_t ok = default_type;\r
-                                       const char *type = switch_xml_attr(x_node, "type");\r
-\r
-                                       if (type) {\r
-                                               ok = switch_true(type);\r
-                                       }\r
-\r
-                                       cidr = switch_xml_attr(x_node, "cidr");\r
-                                       host = switch_xml_attr(x_node, "host");\r
-                                       mask = switch_xml_attr(x_node, "mask");\r
-                                       domain = switch_xml_attr(x_node, "domain");\r
-\r
-                                       if (domain) {\r
-                                               switch_event_t *my_params = NULL;\r
-                                               switch_xml_t x_domain, xml_root;\r
-                                               switch_xml_t gt, gts, ut, uts;\r
-\r
-                                               switch_event_create(&my_params, SWITCH_EVENT_GENERAL);\r
-                                               switch_assert(my_params);\r
-                                               switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "domain", domain);\r
-                                               switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "purpose", "network-list");\r
-\r
-                                               if (switch_xml_locate_domain(domain, my_params, &xml_root, &x_domain) != SWITCH_STATUS_SUCCESS) {\r
-                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate domain %s\n", domain);\r
-                                                       switch_event_destroy(&my_params);\r
-                                                       continue;\r
-                                               }\r
-\r
-                                               switch_event_destroy(&my_params);\r
-\r
-                                               for (ut = switch_xml_child(x_domain, "user"); ut; ut = ut->next) {\r
-                                                       const char *user_cidr = switch_xml_attr(ut, "cidr");\r
-                                                       const char *id = switch_xml_attr(ut, "id");\r
-\r
-                                                       if (id && user_cidr) {\r
-                                                               char *token = switch_mprintf("%s@%s", id, domain);\r
-                                                               switch_assert(token);\r
-                                                               switch_network_list_add_cidr_token(list, user_cidr, ok, token);\r
-                                                               free(token);\r
-                                                       }\r
-                                               }\r
-\r
-                                               for (gts = switch_xml_child(x_domain, "groups"); gts; gts = gts->next) {\r
-                                                       for (gt = switch_xml_child(gts, "group"); gt; gt = gt->next) {\r
-                                                               for (uts = switch_xml_child(gt, "users"); uts; uts = uts->next) {\r
-                                                                       for (ut = switch_xml_child(uts, "user"); ut; ut = ut->next) {\r
-                                                                               const char *user_cidr = switch_xml_attr(ut, "cidr");\r
-                                                                               const char *id = switch_xml_attr(ut, "id");\r
-\r
-                                                                               if (id && user_cidr) {\r
-                                                                                       char *token = switch_mprintf("%s@%s", id, domain);\r
-                                                                                       switch_assert(token);\r
-                                                                                       switch_network_list_add_cidr_token(list, user_cidr, ok, token);\r
-                                                                                       free(token);\r
-                                                                               }\r
-                                                                       }\r
-                                                               }\r
-                                                       }\r
-                                               }\r
-\r
-                                               switch_xml_free(xml_root);\r
-                                       } else if (cidr) {\r
-                                               if (switch_network_list_add_cidr(list, cidr, ok) == SWITCH_STATUS_SUCCESS) {\r
-                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name);\r
-                                               } else {\r
-                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,\r
-                                                                                         "Error Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name);\r
-                                               }\r
-                                       } else if (host && mask) {\r
-                                               if (switch_network_list_add_host_mask(list, host, mask, ok) == SWITCH_STATUS_SUCCESS) {\r
-                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,\r
-                                                                                         "Adding %s/%s (%s) to list %s\n", host, mask, ok ? "allow" : "deny", name);\r
-                                               }\r
-                                       }\r
-\r
-                                       switch_core_hash_insert(IP_LIST.hash, name, list);\r
-                               }\r
-                       }\r
-               }\r
-\r
-               switch_xml_free(xml);\r
-       }\r
-\r
-       switch_mutex_unlock(runtime.global_mutex);\r
-}\r
-\r
-SWITCH_DECLARE(uint32_t) switch_core_max_dtmf_duration(uint32_t duration)\r
-{\r
-       if (duration) {\r
-               if (duration > SWITCH_MAX_DTMF_DURATION) {\r
-                       duration = SWITCH_MAX_DTMF_DURATION;\r
-               }\r
-               if (duration < SWITCH_MIN_DTMF_DURATION) {\r
-                       duration = SWITCH_MIN_DTMF_DURATION;\r
-               }\r
-               runtime.max_dtmf_duration = duration;\r
-               if (duration < runtime.min_dtmf_duration) {\r
-                       runtime.min_dtmf_duration = duration;\r
-               }\r
-       }\r
-       return runtime.max_dtmf_duration;\r
-}\r
-\r
-SWITCH_DECLARE(uint32_t) switch_core_default_dtmf_duration(uint32_t duration)\r
-{\r
-       if (duration) {\r
-               if (duration < SWITCH_MIN_DTMF_DURATION) {\r
-                       duration = SWITCH_MIN_DTMF_DURATION;\r
-               }\r
-               if (duration > SWITCH_MAX_DTMF_DURATION) {\r
-                       duration = SWITCH_MAX_DTMF_DURATION;\r
-               }\r
-               runtime.default_dtmf_duration = duration;\r
-\r
-               if (duration < runtime.min_dtmf_duration) {\r
-                       runtime.min_dtmf_duration = duration;\r
-               }\r
-\r
-               if (duration > runtime.max_dtmf_duration) {\r
-                       runtime.max_dtmf_duration = duration;\r
-               }\r
-\r
-       }\r
-       return runtime.default_dtmf_duration;\r
-}\r
-\r
-SWITCH_DECLARE(uint32_t) switch_core_min_dtmf_duration(uint32_t duration)\r
-{\r
-       if (duration) {\r
-               if (duration < SWITCH_MIN_DTMF_DURATION) {\r
-                       duration = SWITCH_MIN_DTMF_DURATION;\r
-               }\r
-               if (duration > SWITCH_MAX_DTMF_DURATION) {\r
-                       duration = SWITCH_MAX_DTMF_DURATION;\r
-               }\r
-\r
-               runtime.min_dtmf_duration = duration;\r
-\r
-               if (duration > runtime.max_dtmf_duration) {\r
-                       runtime.max_dtmf_duration = duration;\r
-               }\r
-       }\r
-       return runtime.min_dtmf_duration;\r
-}\r
-\r
-SWITCH_DECLARE(switch_status_t) switch_core_thread_set_cpu_affinity(int cpu)\r
-{\r
-       switch_status_t status = SWITCH_STATUS_FALSE;\r
-\r
-       if (cpu > -1) {\r
-\r
-#ifdef HAVE_CPU_SET_MACROS\r
-               cpu_set_t set;\r
-\r
-               CPU_ZERO(&set);\r
-               CPU_SET(cpu, &set);\r
-\r
-               if (!sched_setaffinity(0, sizeof(set), &set)) {\r
-                       status = SWITCH_STATUS_SUCCESS;\r
-               }\r
-               \r
-#else\r
-#if WIN32\r
-               if (SetThreadAffinityMask(GetCurrentThread(), (DWORD_PTR) cpu)) {\r
-                       status = SWITCH_STATUS_SUCCESS;\r
-               }\r
-#endif\r
-#endif\r
-       }\r
-\r
-       return status;\r
-}\r
-\r
-\r
-static void switch_core_set_serial(void)\r
-{\r
-       char buf[13] = "";\r
-       char path[256];\r
-\r
-       int fd = -1, write_fd = -1;\r
-       switch_ssize_t bytes = 0;\r
-\r
-       switch_snprintf(path, sizeof(path), "%s%sfreeswitch.serial", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR);\r
-\r
-\r
-       if ((fd = open(path, O_RDONLY, 0)) < 0) {\r
-               char *ip = switch_core_get_variable_dup("local_ip_v4");\r
-               uint32_t ipi = 0;\r
-               switch_byte_t *byte;\r
-               int i = 0;\r
-\r
-               if (ip) {\r
-                       switch_inet_pton(AF_INET, ip, &ipi);\r
-                       free(ip);\r
-                       ip = NULL;\r
-               }\r
-\r
-\r
-               byte = (switch_byte_t *) & ipi;\r
-\r
-               for (i = 0; i < 8; i += 2) {\r
-                       switch_snprintf(buf + i, sizeof(buf) - i, "%0.2x", *byte);\r
-                       byte++;\r
-               }\r
-\r
-               switch_stun_random_string(buf + 8, 4, "0123456789abcdef");\r
-\r
-               if ((write_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) >= 0) {\r
-                       bytes = write(write_fd, buf, sizeof(buf));\r
-                       bytes++;\r
-                       close(write_fd);\r
-                       write_fd = -1;\r
-               }\r
-       } else {\r
-               bytes = read(fd, buf, sizeof(buf));\r
-               close(fd);\r
-               fd = -1;\r
-       }\r
-\r
-       switch_core_set_variable("switch_serial", buf);\r
-}\r
-\r
-\r
-SWITCH_DECLARE(int) switch_core_test_flag(int flag)\r
-{\r
-       return switch_test_flag((&runtime), flag);\r
-}\r
-\r
-\r
-SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switch_bool_t console, const char **err)\r
-{\r
-       switch_uuid_t uuid;\r
-       char guess_ip[256];\r
-       int mask = 0;\r
-       struct in_addr in;\r
-\r
-\r
-       if (runtime.runlevel > 0) {\r
-               /* one per customer */\r
-               return SWITCH_STATUS_SUCCESS;\r
-       }\r
-       \r
-       memset(&runtime, 0, sizeof(runtime));\r
-       gethostname(runtime.hostname, sizeof(runtime.hostname));\r
-\r
-       runtime.max_db_handles = 50;\r
-       runtime.db_handle_timeout = 5000000;\r
-       \r
-       runtime.runlevel++;\r
-       runtime.dummy_cng_frame.data = runtime.dummy_data;\r
-       runtime.dummy_cng_frame.datalen = sizeof(runtime.dummy_data);\r
-       runtime.dummy_cng_frame.buflen = sizeof(runtime.dummy_data);\r
-       runtime.dbname = "core";\r
-       switch_set_flag((&runtime.dummy_cng_frame), SFF_CNG);\r
-       switch_set_flag((&runtime), SCF_AUTO_SCHEMAS);\r
-       switch_set_flag((&runtime), SCF_CLEAR_SQL);\r
-       switch_set_flag((&runtime), SCF_API_EXPANSION);\r
-       switch_set_flag((&runtime), SCF_SESSION_THREAD_POOL);\r
-#ifdef WIN32\r
-       switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);\r
-#endif\r
-       switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);\r
-       runtime.hard_log_level = SWITCH_LOG_DEBUG;\r
-       runtime.mailer_app = "sendmail";\r
-       runtime.mailer_app_args = "-t";\r
-       runtime.max_dtmf_duration = SWITCH_MAX_DTMF_DURATION;\r
-       runtime.default_dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION;\r
-       runtime.min_dtmf_duration = SWITCH_MIN_DTMF_DURATION;\r
-       runtime.odbc_dbtype = DBTYPE_DEFAULT;\r
-       runtime.dbname = NULL;\r
-#ifndef WIN32\r
-       runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN);\r
-#else\r
-       {\r
-               SYSTEM_INFO sysinfo;\r
-               GetSystemInfo( &sysinfo );\r
-               runtime.cpu_count = sysinfo.dwNumberOfProcessors;\r
-       }\r
-#endif \r
-\r
-       if (!runtime.cpu_count) runtime.cpu_count = 1;\r
-\r
-\r
-       /* INIT APR and Create the pool context */\r
-       if (apr_initialize() != SWITCH_STATUS_SUCCESS) {\r
-               *err = "FATAL ERROR! Could not initialize APR\n";\r
-               return SWITCH_STATUS_MEMERR;\r
-       }\r
-\r
-       if (!(runtime.memory_pool = switch_core_memory_init())) {\r
-               *err = "FATAL ERROR! Could not allocate memory pool\n";\r
-               return SWITCH_STATUS_MEMERR;\r
-       }\r
-       switch_assert(runtime.memory_pool != NULL);\r
-\r
-       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.base_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);\r
-       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.mod_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);\r
-       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.conf_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);\r
-       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.log_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);\r
-       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.run_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);\r
-       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.db_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);\r
-       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.script_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);\r
-       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.htdocs_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);\r
-       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);\r
-       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.recordings_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);\r
-       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.sounds_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);\r
-       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.temp_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);\r
-\r
-\r
-       switch_mutex_init(&runtime.uuid_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);\r
-\r
-       switch_mutex_init(&runtime.throttle_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);\r
-\r
-       switch_mutex_init(&runtime.session_hash_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);\r
-       switch_mutex_init(&runtime.global_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);\r
-\r
-       switch_thread_rwlock_create(&runtime.global_var_rwlock, runtime.memory_pool);\r
-       switch_core_set_globals();\r
-       switch_core_session_init(runtime.memory_pool);\r
-       switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA);\r
-       switch_core_hash_init(&runtime.mime_types, runtime.memory_pool);\r
-       switch_core_hash_init_case(&runtime.ptimes, runtime.memory_pool, SWITCH_FALSE);\r
-       load_mime_types();\r
-       runtime.flags |= flags;\r
-       runtime.sps_total = 30;\r
-\r
-       *err = NULL;\r
-\r
-       if (console) {\r
-               runtime.console = stdout;\r
-       }\r
-\r
-       switch_ssl_init_ssl_locks();\r
-       switch_curl_init();\r
-\r
-       switch_core_set_variable("hostname", runtime.hostname);\r
-       switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET);\r
-       switch_core_set_variable("local_ip_v4", guess_ip);\r
-       in.s_addr = mask;\r
-       switch_core_set_variable("local_mask_v4", inet_ntoa(in));\r
-\r
-\r
-       switch_find_local_ip(guess_ip, sizeof(guess_ip), NULL, AF_INET6);\r
-       switch_core_set_variable("local_ip_v6", guess_ip);\r
-       switch_core_set_variable("base_dir", SWITCH_GLOBAL_dirs.base_dir);\r
-       switch_core_set_variable("recordings_dir", SWITCH_GLOBAL_dirs.recordings_dir);\r
-       switch_core_set_variable("sound_prefix", SWITCH_GLOBAL_dirs.sounds_dir);\r
-       switch_core_set_variable("sounds_dir", SWITCH_GLOBAL_dirs.sounds_dir);\r
-       switch_core_set_serial();\r
-\r
-       switch_console_init(runtime.memory_pool);\r
-       switch_event_init(runtime.memory_pool);\r
-\r
-       if (switch_xml_init(runtime.memory_pool, err) != SWITCH_STATUS_SUCCESS) {\r
-               apr_terminate();\r
-               return SWITCH_STATUS_MEMERR;\r
-       }\r
-\r
-       if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) {\r
-               switch_nat_init(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_NAT_MAPPING));\r
-       }\r
-\r
-       switch_log_init(runtime.memory_pool, runtime.colorize_console);\r
-\r
-       if (flags & SCF_MINIMAL) return SWITCH_STATUS_SUCCESS;\r
-                       \r
-       runtime.tipping_point = 0;\r
-       runtime.timer_affinity = -1;\r
-       runtime.microseconds_per_tick = 20000;\r
-\r
-       switch_load_core_config("switch.conf");\r
-\r
-       switch_core_state_machine_init(runtime.memory_pool);\r
-\r
-       if (switch_core_sqldb_start(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_SQL) ? SWITCH_TRUE : SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) {\r
-               *err = "Error activating database";\r
-               return SWITCH_STATUS_FALSE;\r
-       }\r
-\r
-       switch_scheduler_task_thread_start();\r
-\r
-       switch_nat_late_init();\r
-\r
-       switch_rtp_init(runtime.memory_pool);\r
-\r
-       runtime.running = 1;\r
-       runtime.initiated = switch_time_now();\r
-       runtime.mono_initiated = switch_mono_micro_time_now();\r
-       \r
-       switch_scheduler_add_task(switch_epoch_time_now(NULL), heartbeat_callback, "heartbeat", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL);\r
-\r
-       switch_scheduler_add_task(switch_epoch_time_now(NULL), check_ip_callback, "check_ip", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL | SSHF_OWN_THREAD);\r
-\r
-       switch_uuid_get(&uuid);\r
-       switch_uuid_format(runtime.uuid_str, &uuid);\r
-       switch_core_set_variable("core_uuid", runtime.uuid_str);\r
-\r
-\r
-       return SWITCH_STATUS_SUCCESS;\r
-}\r
-\r
-\r
-#ifndef WIN32\r
-static void handle_SIGCHLD(int sig)\r
-{\r
-       int status = 0;\r
-\r
-       wait(&status);\r
-       return;\r
-}\r
-#endif\r
-\r
-#ifdef TRAP_BUS\r
-static void handle_SIGBUS(int sig)\r
-{\r
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Sig BUS!\n");\r
-       return;\r
-}\r
-#endif\r
-\r
-static void handle_SIGHUP(int sig)\r
-{\r
-       if (sig) {\r
-               switch_event_t *event;\r
-\r
-               if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {\r
-                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Trapped-Signal", "HUP");\r
-                       switch_event_fire(&event);\r
-               }\r
-       }\r
-       return;\r
-}\r
-\r
-\r
-SWITCH_DECLARE(uint32_t) switch_default_ptime(const char *name, uint32_t number)\r
-{\r
-       uint32_t *p;\r
-\r
-       if ((p = switch_core_hash_find(runtime.ptimes, name))) {\r
-               return *p;\r
-       }\r
-\r
-       return 20;\r
-}\r
-\r
-static uint32_t d_30 = 30;\r
-\r
-static void switch_load_core_config(const char *file)\r
-{\r
-       switch_xml_t xml = NULL, cfg = NULL;\r
-\r
-       switch_core_hash_insert(runtime.ptimes, "ilbc", &d_30);\r
-       switch_core_hash_insert(runtime.ptimes, "G723", &d_30);\r
-\r
-       if ((xml = switch_xml_open_cfg(file, &cfg, NULL))) {\r
-               switch_xml_t settings, param;\r
-\r
-               if ((settings = switch_xml_child(cfg, "default-ptimes"))) {\r
-                       for (param = switch_xml_child(settings, "codec"); param; param = param->next) {\r
-                               const char *var = switch_xml_attr_soft(param, "name");\r
-                               const char *val = switch_xml_attr_soft(param, "ptime");\r
-                               \r
-                               if (!zstr(var) && !zstr(val)) {\r
-                                       uint32_t *p;\r
-                                       uint32_t v = switch_atoul(val);\r
-\r
-                                       if (!strcasecmp(var, "G723") || !strcasecmp(var, "iLBC")) {\r
-                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, defaults cannot be changed\n", var);\r
-                                               continue;\r
-                                       }\r
-                                       \r
-                                       if (v == 0) {\r
-                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, invalid ptime\n", var);\r
-                                               continue;\r
-                                       }\r
-\r
-                                       p = switch_core_alloc(runtime.memory_pool, sizeof(*p));\r
-                                       *p = v;\r
-                                       switch_core_hash_insert(runtime.ptimes, var, p);\r
-                               }\r
-\r
-                       }\r
-               }\r
-\r
-               if ((settings = switch_xml_child(cfg, "settings"))) {\r
-                       for (param = switch_xml_child(settings, "param"); param; param = param->next) {\r
-                               const char *var = switch_xml_attr_soft(param, "name");\r
-                               const char *val = switch_xml_attr_soft(param, "value");\r
-\r
-                               if (!strcasecmp(var, "loglevel")) {\r
-                                       int level;\r
-                                       if (*val > 47 && *val < 58) {\r
-                                               level = atoi(val);\r
-                                       } else {\r
-                                               level = switch_log_str2level(val);\r
-                                       }\r
-\r
-                                       if (level != SWITCH_LOG_INVALID) {\r
-                                               switch_core_session_ctl(SCSC_LOGLEVEL, &level);\r
-                                       }\r
-#ifdef HAVE_SETRLIMIT\r
-                               } else if (!strcasecmp(var, "dump-cores") && switch_true(val)) {\r
-                                       struct rlimit rlp;\r
-                                       memset(&rlp, 0, sizeof(rlp));\r
-                                       rlp.rlim_cur = RLIM_INFINITY;\r
-                                       rlp.rlim_max = RLIM_INFINITY;\r
-                                       setrlimit(RLIMIT_CORE, &rlp);\r
-#endif\r
-                               } else if (!strcasecmp(var, "debug-level")) {\r
-                                       int tmp = atoi(val);\r
-                                       if (tmp > -1 && tmp < 11) {\r
-                                               switch_core_session_ctl(SCSC_DEBUG_LEVEL, &tmp);\r
-                                       }\r
-                               } else if (!strcasecmp(var, "max-db-handles")) {\r
-                                       long tmp = atol(val);\r
-\r
-                                       if (tmp > 4 && tmp < 5001) {\r
-                                               runtime.max_db_handles = (uint32_t) tmp;\r
-                                       } else {\r
-                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "max-db-handles must be between 5 and 5000\n");\r
-                                       }\r
-                               } else if (!strcasecmp(var, "db-handle-timeout")) {\r
-                                       long tmp = atol(val);\r
-                                       \r
-                                       if (tmp > 0 && tmp < 5001) {\r
-                                               runtime.db_handle_timeout = (uint32_t) tmp * 1000000;\r
-                                       } else {\r
-                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "db-handle-timeout must be between 1 and 5000\n");\r
-                                       }\r
-                                       \r
-                               } else if (!strcasecmp(var, "multiple-registrations")) {\r
-                                       runtime.multiple_registrations = switch_true(val);\r
-                               } else if (!strcasecmp(var, "auto-create-schemas")) {\r
-                                       if (switch_true(val)) {\r
-                                               switch_set_flag((&runtime), SCF_AUTO_SCHEMAS);\r
-                                       } else {\r
-                                               switch_clear_flag((&runtime), SCF_AUTO_SCHEMAS);\r
-                                       }\r
-                               } else if (!strcasecmp(var, "session-thread-pool")) {\r
-                                       if (switch_true(val)) {\r
-                                               switch_set_flag((&runtime), SCF_SESSION_THREAD_POOL);\r
-                                       } else {\r
-                                               switch_clear_flag((&runtime), SCF_SESSION_THREAD_POOL);\r
-                                       }\r
-                               } else if (!strcasecmp(var, "auto-clear-sql")) {\r
-                                       if (switch_true(val)) {\r
-                                               switch_set_flag((&runtime), SCF_CLEAR_SQL);\r
-                                       } else {\r
-                                               switch_clear_flag((&runtime), SCF_CLEAR_SQL);\r
-                                       }\r
-                               } else if (!strcasecmp(var, "api-expansion")) {\r
-                                       if (switch_true(val)) {\r
-                                               switch_set_flag((&runtime), SCF_API_EXPANSION);\r
-                                       } else {\r
-                                               switch_clear_flag((&runtime), SCF_API_EXPANSION);\r
-                                       }\r
-                               } else if (!strcasecmp(var, "enable-early-hangup") && switch_true(val)) {\r
-                                       switch_set_flag((&runtime), SCF_EARLY_HANGUP);\r
-                               } else if (!strcasecmp(var, "colorize-console") && switch_true(val)) {\r
-                                       runtime.colorize_console = SWITCH_TRUE;\r
-                               } else if (!strcasecmp(var, "core-db-pre-trans-execute") && !zstr(val)) {\r
-                                       runtime.core_db_pre_trans_execute = switch_core_strdup(runtime.memory_pool, val);\r
-                               } else if (!strcasecmp(var, "core-db-post-trans-execute") && !zstr(val)) {\r
-                                       runtime.core_db_post_trans_execute = switch_core_strdup(runtime.memory_pool, val);\r
-                               } else if (!strcasecmp(var, "core-db-inner-pre-trans-execute") && !zstr(val)) {\r
-                                       runtime.core_db_inner_pre_trans_execute = switch_core_strdup(runtime.memory_pool, val);\r
-                               } else if (!strcasecmp(var, "core-db-inner-post-trans-execute") && !zstr(val)) {\r
-                                       runtime.core_db_inner_post_trans_execute = switch_core_strdup(runtime.memory_pool, val);\r
-                               } else if (!strcasecmp(var, "mailer-app") && !zstr(val)) {\r
-                                       runtime.mailer_app = switch_core_strdup(runtime.memory_pool, val);\r
-                               } else if (!strcasecmp(var, "mailer-app-args") && val) {\r
-                                       runtime.mailer_app_args = switch_core_strdup(runtime.memory_pool, val);\r
-                               } else if (!strcasecmp(var, "sessions-per-second") && !zstr(val)) {\r
-                                       switch_core_sessions_per_second(atoi(val));\r
-                               } else if (!strcasecmp(var, "max-dtmf-duration") && !zstr(val)) {\r
-                                       int tmp = atoi(val);\r
-                                       if (tmp > 0) {\r
-                                               switch_core_max_dtmf_duration((uint32_t) tmp);\r
-                                       }\r
-                               } else if (!strcasecmp(var, "min-dtmf-duration") && !zstr(val)) {\r
-                                       int tmp = atoi(val);\r
-                                       if (tmp > 0) {\r
-                                               switch_core_min_dtmf_duration((uint32_t) tmp);\r
-                                       }\r
-                               } else if (!strcasecmp(var, "default-dtmf-duration") && !zstr(val)) {\r
-                                       int tmp = atoi(val);\r
-                                       if (tmp > 0) {\r
-                                               switch_core_default_dtmf_duration((uint32_t) tmp);\r
-                                       }\r
-                               } else if (!strcasecmp(var, "enable-use-system-time")) {\r
-                                       switch_time_set_use_system_time(switch_true(val));\r
-                               } else if (!strcasecmp(var, "enable-monotonic-timing")) {\r
-                                       switch_time_set_monotonic(switch_true(val));\r
-                               } else if (!strcasecmp(var, "enable-softtimer-timerfd")) {\r
-                                       switch_time_set_timerfd(switch_true(val));\r
-                               } else if (!strcasecmp(var, "enable-clock-nanosleep")) {\r
-                                       switch_time_set_nanosleep(switch_true(val));\r
-                               } else if (!strcasecmp(var, "enable-cond-yield")) {\r
-                                       switch_time_set_cond_yield(switch_true(val));\r
-                               } else if (!strcasecmp(var, "enable-timer-matrix")) {\r
-                                       switch_time_set_matrix(switch_true(val));\r
-                               } else if (!strcasecmp(var, "max-sessions") && !zstr(val)) {\r
-                                       switch_core_session_limit(atoi(val));\r
-                               } else if (!strcasecmp(var, "verbose-channel-events") && !zstr(val)) {\r
-                                       int v = switch_true(val);\r
-                                       if (v) {\r
-                                               switch_set_flag((&runtime), SCF_VERBOSE_EVENTS);\r
-                                       } else {\r
-                                               switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS);\r
-                                       }\r
-                               } else if (!strcasecmp(var, "threaded-system-exec") && !zstr(val)) {\r
-#ifdef WIN32\r
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "threaded-system-exec is not implemented on this platform\n");\r
-#else\r
-                                       int v = switch_true(val);\r
-                                       if (v) {\r
-                                               switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);\r
-                                       } else {\r
-                                               switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);\r
-                                       }\r
-#endif\r
-                               } else if (!strcasecmp(var, "min-idle-cpu") && !zstr(val)) {\r
-                                       switch_core_min_idle_cpu(atof(val));\r
-                               } else if (!strcasecmp(var, "tipping-point") && !zstr(val)) {\r
-                                       runtime.tipping_point = atoi(val);\r
-                               } else if (!strcasecmp(var, "initial-event-threads") && !zstr(val)) {\r
-                                       int tmp = atoi(val);\r
-\r
-\r
-                                       if (tmp > runtime.cpu_count / 2) {\r
-                                               tmp = runtime.cpu_count / 2;\r
-                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be higher than %d so setting it to that value\n", \r
-                                                                                 runtime.cpu_count / 2);\r
-                                       }\r
-\r
-                                       if (tmp < 1) {\r
-                                               tmp = 1;\r
-                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be lower than 1 so setting it to that level\n");\r
-                                       }\r
-\r
-                                       switch_event_launch_dispatch_threads(tmp);\r
-\r
-                               } else if (!strcasecmp(var, "1ms-timer") && switch_true(val)) {\r
-                                       runtime.microseconds_per_tick = 1000;\r
-                               } else if (!strcasecmp(var, "timer-affinity") && !zstr(val)) {\r
-                                       if (!strcasecmp(val, "disabled")) {\r
-                                               runtime.timer_affinity = -1;\r
-                                       } else {\r
-                                               runtime.timer_affinity = atoi(val);\r
-                                       }\r
-                               } else if (!strcasecmp(var, "rtp-start-port") && !zstr(val)) {\r
-                                       switch_rtp_set_start_port((switch_port_t) atoi(val));\r
-                               } else if (!strcasecmp(var, "rtp-end-port") && !zstr(val)) {\r
-                                       switch_rtp_set_end_port((switch_port_t) atoi(val));\r
-                               } else if (!strcasecmp(var, "core-db-name") && !zstr(val)) {\r
-                                       runtime.dbname = switch_core_strdup(runtime.memory_pool, val);\r
-                               } else if (!strcasecmp(var, "core-db-dsn") && !zstr(val)) {\r
-                                       if (switch_odbc_available() || switch_pgsql_available()) {\r
-                                               runtime.odbc_dsn = switch_core_strdup(runtime.memory_pool, val);\r
-                                       } else {\r
-                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC AND PGSQL ARE NOT AVAILABLE!\n");\r
-                                       }\r
-                               } else if (!strcasecmp(var, "core-non-sqlite-db-required") && !zstr(val)) {\r
-                                       switch_set_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ);\r
-                               } else if (!strcasecmp(var, "core-dbtype") && !zstr(val)) {\r
-                                       if (!strcasecmp(val, "MSSQL")) {\r
-                                               runtime.odbc_dbtype = DBTYPE_MSSQL;\r
-                                       } else {\r
-                                               runtime.odbc_dbtype = DBTYPE_DEFAULT;\r
-                                       }\r
-#ifdef ENABLE_ZRTP\r
-                               } else if (!strcasecmp(var, "rtp-enable-zrtp")) {\r
-                                       switch_core_set_variable("zrtp_enabled", val);\r
-#endif\r
-                } else if (!strcasecmp(var, "switchname") && !zstr(val)) {\r
-                                       runtime.switchname = switch_core_strdup(runtime.memory_pool, val);\r
-                    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Set switchname to %s\n", runtime.switchname);\r
-                               }\r
-                       }\r
-               }\r
-\r
-               if ((settings = switch_xml_child(cfg, "variables"))) {\r
-                       for (param = switch_xml_child(settings, "variable"); param; param = param->next) {\r
-                               const char *var = switch_xml_attr_soft(param, "name");\r
-                               const char *val = switch_xml_attr_soft(param, "value");\r
-                               if (var && val) {\r
-                                       switch_core_set_variable(var, val);\r
-                               }\r
-                       }\r
-               }\r
-\r
-               switch_xml_free(xml);\r
-       }\r
-\r
-\r
-}\r
-\r
-SWITCH_DECLARE(const char *) switch_core_banner(void)\r
-{\r
-\r
-       return ("\n"\r
-                       ".=============================================================.\n"\r
-                       "|   _____              ______        _____ _____ ____ _   _   |\n"\r
-                       "|  |  ___| __ ___  ___/ ___\\ \\      / /_ _|_   _/ ___| | | |  |\n"\r
-                       "|  | |_ | '__/ _ \\/ _ \\___ \\\\ \\ /\\ / / | |  | || |   | |_| |  |\n"\r
-                       "|  |  _|| | |  __/  __/___) |\\ V  V /  | |  | || |___|  _  |  |\n"\r
-                       "|  |_|  |_|  \\___|\\___|____/  \\_/\\_/  |___| |_| \\____|_| |_|  |\n"\r
-                       "|                                                             |\n"\r
-                       ".=============================================================."\r
-                       "\n"\r
-\r
-                       "|   Anthony Minessale II, Michael Jerris, Brian West, Others  |\n"\r
-                       "|   FreeSWITCH (http://www.freeswitch.org)                    |\n"\r
-                       "|   Paypal Donations Appreciated: paypal@freeswitch.org       |\n"\r
-                       "|   Brought to you by ClueCon http://www.cluecon.com/         |\n" \r
-                       ".=============================================================.\n" \r
-                       "\n");\r
-}\r
-\r
-\r
-SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t flags, switch_bool_t console, const char **err)\r
-{\r
-       switch_event_t *event;\r
-       char *cmd;\r
-       int x = 0;\r
-       const char *use = NULL;\r
-#include "cc.h"\r
-\r
-\r
-       if (switch_core_init(flags, console, err) != SWITCH_STATUS_SUCCESS) {\r
-               return SWITCH_STATUS_GENERR;\r
-       }\r
-       \r
-       if (runtime.runlevel > 1) {\r
-               /* one per customer */\r
-               return SWITCH_STATUS_SUCCESS;\r
-       }\r
-\r
-       runtime.runlevel++;\r
-\r
-       switch_core_set_signal_handlers();\r
-       switch_load_network_lists(SWITCH_FALSE);\r
-\r
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bringing up environment.\n");\r
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Loading Modules.\n");\r
-       if (switch_loadable_module_init(SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {\r
-               *err = "Cannot load modules";\r
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Error: %s\n", *err);\r
-               return SWITCH_STATUS_GENERR;\r
-       }\r
-\r
-       switch_load_network_lists(SWITCH_FALSE);\r
-\r
-       switch_load_core_config("post_load_switch.conf");\r
-\r
-       switch_core_set_signal_handlers();\r
-\r
-       if (switch_event_create(&event, SWITCH_EVENT_STARTUP) == SWITCH_STATUS_SUCCESS) {\r
-               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready");\r
-               switch_event_fire(&event);\r
-       }\r
-\r
-       switch_core_screen_size(&x, NULL);\r
-\r
-       use = (x > 100) ? cc : cc_s;\r
-\r
-#ifdef WIN32\r
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s\n\n", switch_core_banner(), use);\r
-#else\r
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s%s%s%s%s\n\n", \r
-                                         SWITCH_SEQ_DEFAULT_COLOR,\r
-                                         SWITCH_SEQ_FYELLOW, SWITCH_SEQ_BBLUE,\r
-                                         switch_core_banner(), \r
-                                         use, SWITCH_SEQ_DEFAULT_COLOR);\r
-       \r
-#endif\r
-\r
-\r
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE,\r
-                                         "\nFreeSWITCH Version %s (%s)\n\nFreeSWITCH Started\nMax Sessions [%u]\nSession Rate [%d]\nSQL [%s]\n",\r
-                                         SWITCH_VERSION_FULL, SWITCH_VERSION_REVISION_HUMAN,\r
-                                         switch_core_session_limit(0),\r
-                                         switch_core_sessions_per_second(0), switch_test_flag((&runtime), SCF_USE_SQL) ? "Enabled" : "Disabled");\r
-\r
-\r
-       if (x < 160) {\r
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\n[This app Best viewed at 160x60 or more..]\n");\r
-       }\r
-\r
-       switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS);\r
-\r
-       if ((cmd = switch_core_get_variable_dup("api_on_startup"))) {\r
-               switch_stream_handle_t stream = { 0 };\r
-               SWITCH_STANDARD_STREAM(stream);\r
-               switch_console_execute(cmd, 0, &stream);\r
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Startup command [%s] executed. Output:\n%s\n", cmd, (char *)stream.data);\r
-               free(stream.data);\r
-               free(cmd);\r
-       }\r
-\r
-       return SWITCH_STATUS_SUCCESS;\r
-\r
-}\r
-\r
-SWITCH_DECLARE(void) switch_core_measure_time(switch_time_t total_ms, switch_core_time_duration_t *duration)\r
-{\r
-       switch_time_t temp = total_ms / 1000;\r
-       memset(duration, 0, sizeof(*duration));\r
-       duration->mms = (uint32_t) (total_ms % 1000);\r
-       duration->ms = (uint32_t) (temp % 1000);\r
-       temp = temp / 1000;\r
-       duration->sec = (uint32_t) (temp % 60);\r
-       temp = temp / 60;\r
-       duration->min = (uint32_t) (temp % 60);\r
-       temp = temp / 60;\r
-       duration->hr = (uint32_t) (temp % 24);\r
-       temp = temp / 24;\r
-       duration->day = (uint32_t) (temp % 365);\r
-       duration->yr = (uint32_t) (temp / 365);\r
-}\r
-\r
-SWITCH_DECLARE(switch_time_t) switch_core_uptime(void)\r
-{\r
-       return switch_mono_micro_time_now() - runtime.mono_initiated;\r
-}\r
-\r
-\r
-#ifdef _MSC_VER\r
-static void win_shutdown(void)\r
-{\r
-\r
-       HANDLE shutdown_event;\r
-       char path[512];\r
-       /* for windows we need the event to signal for shutting down a background FreeSWITCH */\r
-       snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid());\r
-\r
-       /* open the event so we can signal it */\r
-       shutdown_event = OpenEvent(EVENT_MODIFY_STATE, FALSE, path);\r
-\r
-       if (shutdown_event) {\r
-               /* signal the event to shutdown */\r
-               SetEvent(shutdown_event);\r
-               /* cleanup */\r
-               CloseHandle(shutdown_event);\r
-       }\r
-}\r
-#endif\r
-\r
-SWITCH_DECLARE(void) switch_core_set_signal_handlers(void)\r
-{\r
-       /* set signal handlers */\r
-       signal(SIGINT, SIG_IGN);\r
-#ifndef WIN32\r
-       if (switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC)) {\r
-               signal(SIGCHLD, SIG_DFL);\r
-       } else {\r
-               signal(SIGCHLD, handle_SIGCHLD);\r
-       }\r
-#endif\r
-#ifdef SIGPIPE\r
-       signal(SIGPIPE, SIG_IGN);\r
-#endif\r
-#ifdef SIGQUIT\r
-       signal(SIGQUIT, SIG_IGN);\r
-#endif\r
-#ifdef SIGPOLL\r
-       signal(SIGPOLL, SIG_IGN);\r
-#endif\r
-#ifdef SIGIO\r
-       signal(SIGIO, SIG_IGN);\r
-#endif\r
-#ifdef TRAP_BUS\r
-       signal(SIGBUS, handle_SIGBUS);\r
-#endif\r
-#ifdef SIGUSR1\r
-       signal(SIGUSR1, handle_SIGHUP);\r
-#endif\r
-       signal(SIGHUP, handle_SIGHUP);\r
-}\r
-\r
-SWITCH_DECLARE(uint32_t) switch_core_debug_level(void)\r
-{\r
-       return runtime.debug_level;\r
-}\r
-\r
-\r
-SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void *val)\r
-{\r
-       int *intval = (int *) val;\r
-       int oldintval = 0, newintval = 0;\r
-       \r
-       if (intval) {\r
-               oldintval = *intval;\r
-       }\r
-\r
-       if (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)) {\r
-               return -1;\r
-       }\r
-\r
-       switch (cmd) {\r
-       case SCSC_RECOVER:\r
-               {\r
-                       char *arg = (char *) val;\r
-                       char *tech = NULL, *prof = NULL;\r
-                       int r, flush = 0;\r
-\r
-                       if (!zstr(arg)) {\r
-                               tech = strdup(arg);\r
-                               \r
-                               if ((prof = strchr(tech, ':'))) {\r
-                                       *prof++ = '\0';\r
-                               }\r
-\r
-                               if (!strcasecmp(tech, "flush")) {\r
-                                       flush++;\r
-\r
-                                       if (prof) {\r
-                                               tech = prof;\r
-                                               if ((prof = strchr(tech, ':'))) {\r
-                                                       *prof++ = '\0';\r
-                                               }\r
-                                       }\r
-                               }\r
-\r
-                       }\r
-\r
-                       if (flush) {\r
-                               switch_core_recovery_flush(tech, prof);\r
-                               r = -1;\r
-                       } else {\r
-                               r = switch_core_recovery_recover(tech, prof);\r
-                       }\r
-\r
-                       switch_safe_free(tech);\r
-                       return r;\r
-\r
-               }\r
-               break;\r
-       case SCSC_DEBUG_SQL:\r
-               {\r
-                       if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) {\r
-                               switch_clear_flag((&runtime), SCF_DEBUG_SQL);\r
-                               newintval = 0;\r
-                       } else {\r
-                               switch_set_flag((&runtime), SCF_DEBUG_SQL);\r
-                               newintval = 1;\r
-                       }\r
-               }\r
-               break;\r
-       case SCSC_VERBOSE_EVENTS:\r
-               if (intval) {\r
-                       if (oldintval > -1) {\r
-                               if (oldintval) {\r
-                                       switch_set_flag((&runtime), SCF_VERBOSE_EVENTS);\r
-                               } else {\r
-                                       switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS);\r
-                               }\r
-                       }\r
-                       newintval = switch_test_flag((&runtime), SCF_VERBOSE_EVENTS);\r
-               }\r
-               break;\r
-       case SCSC_API_EXPANSION:\r
-               if (intval) {\r
-                       if (oldintval > -1) {\r
-                               if (oldintval) {\r
-                                       switch_set_flag((&runtime), SCF_API_EXPANSION);\r
-                               } else {\r
-                                       switch_clear_flag((&runtime), SCF_API_EXPANSION);\r
-                               }\r
-                       }\r
-                       newintval = switch_test_flag((&runtime), SCF_API_EXPANSION);\r
-               }\r
-               break;\r
-       case SCSC_THREADED_SYSTEM_EXEC:\r
-               if (intval) {\r
-                       if (oldintval > -1) {\r
-                               if (oldintval) {\r
-                                       switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);\r
-                               } else {\r
-                                       switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);\r
-                               }\r
-                       }\r
-                       newintval = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);\r
-               }\r
-               break;\r
-       case SCSC_CALIBRATE_CLOCK:\r
-               switch_time_calibrate_clock();\r
-               break;\r
-       case SCSC_FLUSH_DB_HANDLES:\r
-               switch_cache_db_flush_handles();\r
-               break;\r
-       case SCSC_SEND_SIGHUP:\r
-               handle_SIGHUP(1);\r
-               break;\r
-       case SCSC_SYNC_CLOCK:\r
-               switch_time_sync();\r
-               newintval = 0;\r
-               break;\r
-       case SCSC_SYNC_CLOCK_WHEN_IDLE:\r
-               newintval = switch_core_session_sync_clock();\r
-               break;\r
-       case SCSC_SQL:\r
-               if (oldintval) {\r
-                       switch_core_sqldb_resume();\r
-               } else {\r
-                       switch_core_sqldb_pause();\r
-               }\r
-               break;\r
-       case SCSC_PAUSE_ALL:\r
-               if (oldintval) {\r
-                       switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);\r
-               } else {\r
-                       switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS);\r
-               }\r
-               break;\r
-       case SCSC_PAUSE_INBOUND:\r
-               if (oldintval) {\r
-                       switch_set_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS);\r
-               } else {\r
-                       switch_clear_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS);\r
-               }\r
-               break;\r
-       case SCSC_PAUSE_OUTBOUND:\r
-               if (oldintval) {\r
-                       switch_set_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS);\r
-               } else {\r
-                       switch_clear_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS);\r
-               }\r
-               break;\r
-       case SCSC_HUPALL:\r
-               switch_core_session_hupall(SWITCH_CAUSE_MANAGER_REQUEST);\r
-               break;\r
-       case SCSC_CANCEL_SHUTDOWN:\r
-               switch_clear_flag((&runtime), SCF_SHUTDOWN_REQUESTED);\r
-               break;\r
-       case SCSC_SAVE_HISTORY:\r
-               switch_console_save_history();\r
-               break;\r
-       case SCSC_CRASH:\r
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Declinatio Mortuus Obfirmo!\n");\r
-               switch_console_save_history();\r
-               abort();\r
-               break;\r
-       case SCSC_SHUTDOWN_NOW:\r
-               switch_console_save_history();\r
-               exit(0);\r
-               break;\r
-       case SCSC_SHUTDOWN_ELEGANT:\r
-       case SCSC_SHUTDOWN_ASAP:\r
-               {\r
-                       int x = 19;\r
-                       uint32_t count;\r
-\r
-                       switch_set_flag((&runtime), SCF_SHUTDOWN_REQUESTED);\r
-                       if (cmd == SCSC_SHUTDOWN_ASAP) {\r
-                               switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);\r
-                       }\r
-\r
-                       while (runtime.running && switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED) && (count = switch_core_session_count())) {\r
-                               switch_yield(500000);\r
-                               if (++x == 20) {\r
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,\r
-                                                                         "Shutdown in progress, %u session(s) remain.\nShutting down %s\n",\r
-                                                                         count, cmd == SCSC_SHUTDOWN_ASAP ? "ASAP" : "once there are no active calls.");\r
-                                       x = 0;\r
-                               }\r
-                       }\r
-\r
-                       if (switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED)) {\r
-                               switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);\r
-#ifdef _MSC_VER\r
-                               win_shutdown();\r
-#endif\r
-\r
-                               if (oldintval) {\r
-                                       switch_set_flag((&runtime), SCF_RESTART);\r
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n");\r
-                               } else {\r
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n");\r
-#ifdef _MSC_VER\r
-                                       fclose(stdin);\r
-#endif\r
-                               }\r
-                               runtime.running = 0;\r
-                       } else {\r
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutdown Cancelled\n");\r
-                               switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS);\r
-                       }\r
-               }\r
-               break;\r
-       case SCSC_PAUSE_CHECK:\r
-               newintval = !!(switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS);\r
-               break;\r
-       case SCSC_PAUSE_INBOUND_CHECK:\r
-               newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS);\r
-               break;\r
-       case SCSC_PAUSE_OUTBOUND_CHECK:\r
-               newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS);\r
-               break;\r
-       case SCSC_READY_CHECK:\r
-               newintval = switch_core_ready();\r
-               break;\r
-       case SCSC_SHUTDOWN_CHECK:\r
-               newintval = !!switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED);\r
-               break;\r
-       case SCSC_SHUTDOWN:\r
-\r
-#ifdef _MSC_VER\r
-               win_shutdown();\r
-#endif\r
-\r
-               if (oldintval) {\r
-                       switch_set_flag((&runtime), SCF_RESTART);\r
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n");\r
-               } else {\r
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n");\r
-#ifdef _MSC_VER\r
-                       fclose(stdin);\r
-#endif\r
-               }\r
-               runtime.running = 0;\r
-               break;\r
-       case SCSC_CHECK_RUNNING:\r
-               newintval = runtime.running;\r
-               break;\r
-       case SCSC_LOGLEVEL:\r
-               if (oldintval > -1) {\r
-                       runtime.hard_log_level = oldintval;\r
-               }\r
-\r
-               if (runtime.hard_log_level > SWITCH_LOG_DEBUG) {\r
-                       runtime.hard_log_level = SWITCH_LOG_DEBUG;\r
-               }\r
-               newintval = runtime.hard_log_level;\r
-               break;\r
-       case SCSC_DEBUG_LEVEL:\r
-               if (oldintval > -1) {\r
-                       if (oldintval > 10)\r
-                               newintval = 10;\r
-                       runtime.debug_level = oldintval;\r
-               }\r
-               newintval = runtime.debug_level;\r
-               break;\r
-       case SCSC_MIN_IDLE_CPU:\r
-               {\r
-                       double *dval = (double *) val;\r
-                       if (dval) {\r
-                               *dval = switch_core_min_idle_cpu(*dval);\r
-                       }\r
-                       intval = NULL;\r
-               }\r
-               break;\r
-       case SCSC_MAX_SESSIONS:\r
-               newintval = switch_core_session_limit(oldintval);\r
-               break;\r
-       case SCSC_LAST_SPS:\r
-               newintval = runtime.sps_last;\r
-               break;\r
-       case SCSC_MAX_DTMF_DURATION:\r
-               newintval = switch_core_max_dtmf_duration(oldintval);\r
-               break;\r
-       case SCSC_MIN_DTMF_DURATION:\r
-               newintval = switch_core_min_dtmf_duration(oldintval);\r
-               break;\r
-       case SCSC_DEFAULT_DTMF_DURATION:\r
-               newintval = switch_core_default_dtmf_duration(oldintval);\r
-               break;\r
-       case SCSC_SPS:\r
-               switch_mutex_lock(runtime.throttle_mutex);\r
-               if (oldintval > 0) {\r
-                       runtime.sps_total = oldintval;\r
-               }\r
-               newintval = runtime.sps_total;\r
-               switch_mutex_unlock(runtime.throttle_mutex);\r
-               break;\r
-\r
-       case SCSC_RECLAIM:\r
-               switch_core_memory_reclaim_all();\r
-               newintval = 0;\r
-               break;\r
-       }\r
-\r
-       if (intval) {\r
-               *intval = newintval;\r
-       }\r
-\r
-\r
-       return 0;\r
-}\r
-\r
-SWITCH_DECLARE(switch_core_flag_t) switch_core_flags(void)\r
-{\r
-       return runtime.flags;\r
-}\r
-\r
-SWITCH_DECLARE(switch_bool_t) switch_core_ready(void)\r
-{\r
-       return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS) ? SWITCH_FALSE : SWITCH_TRUE;\r
-}\r
-\r
-SWITCH_DECLARE(switch_bool_t) switch_core_ready_inbound(void)\r
-{\r
-       return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE;\r
-}\r
-\r
-SWITCH_DECLARE(switch_bool_t) switch_core_ready_outbound(void)\r
-{\r
-       return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE;\r
-}\r
-\r
-SWITCH_DECLARE(switch_status_t) switch_core_destroy(void)\r
-{\r
-       switch_event_t *event;\r
-\r
-       if (switch_event_create(&event, SWITCH_EVENT_SHUTDOWN) == SWITCH_STATUS_SUCCESS) {\r
-               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Shutting Down");\r
-               switch_event_fire(&event);\r
-       }\r
-\r
-       switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);\r
-       switch_set_flag((&runtime), SCF_SHUTTING_DOWN);\r
-\r
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "End existing sessions\n");\r
-       switch_core_session_hupall(SWITCH_CAUSE_SYSTEM_SHUTDOWN);\r
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clean up modules.\n");\r
-\r
-       switch_loadable_module_shutdown();\r
-\r
-       switch_ssl_destroy_ssl_locks();\r
-\r
-       if (switch_test_flag((&runtime), SCF_USE_SQL)) {\r
-               switch_core_sqldb_stop();\r
-       }\r
-       switch_scheduler_task_thread_stop();\r
-\r
-       switch_rtp_shutdown();\r
-\r
-       if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) {\r
-               switch_nat_shutdown();\r
-       }\r
-       switch_xml_destroy();\r
-       switch_core_session_uninit();\r
-       switch_console_shutdown();\r
-\r
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Closing Event Engine.\n");\r
-       switch_event_shutdown();\r
-\r
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Finalizing Shutdown.\n");\r
-       switch_log_shutdown();\r
-\r
-       switch_core_unset_variables();\r
-       switch_core_memory_stop();\r
-\r
-       if (runtime.console && runtime.console != stdout && runtime.console != stderr) {\r
-               fclose(runtime.console);\r
-               runtime.console = NULL;\r
-       }\r
-\r
-       switch_safe_free(SWITCH_GLOBAL_dirs.base_dir);\r
-       switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir);\r
-       switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir);\r
-       switch_safe_free(SWITCH_GLOBAL_dirs.log_dir);\r
-       switch_safe_free(SWITCH_GLOBAL_dirs.db_dir);\r
-       switch_safe_free(SWITCH_GLOBAL_dirs.script_dir);\r
-       switch_safe_free(SWITCH_GLOBAL_dirs.htdocs_dir);\r
-       switch_safe_free(SWITCH_GLOBAL_dirs.grammar_dir);\r
-       switch_safe_free(SWITCH_GLOBAL_dirs.storage_dir);\r
-       switch_safe_free(SWITCH_GLOBAL_dirs.recordings_dir);\r
-       switch_safe_free(SWITCH_GLOBAL_dirs.sounds_dir);\r
-       switch_safe_free(SWITCH_GLOBAL_dirs.run_dir);\r
-       switch_safe_free(SWITCH_GLOBAL_dirs.temp_dir);\r
-\r
-       switch_event_destroy(&runtime.global_vars);\r
-       switch_core_hash_destroy(&runtime.ptimes);\r
-       switch_core_hash_destroy(&runtime.mime_types);\r
-\r
-       if (IP_LIST.hash) {\r
-               switch_core_hash_destroy(&IP_LIST.hash);\r
-       }\r
-\r
-       if (IP_LIST.pool) {\r
-               switch_core_destroy_memory_pool(&IP_LIST.pool);\r
-       }\r
-\r
-       if (runtime.memory_pool) {\r
-               apr_pool_destroy(runtime.memory_pool);\r
-               apr_terminate();\r
-       }\r
-\r
-       return switch_test_flag((&runtime), SCF_RESTART) ? SWITCH_STATUS_RESTART : SWITCH_STATUS_SUCCESS;\r
-}\r
-\r
-SWITCH_DECLARE(switch_status_t) switch_core_management_exec(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen)\r
-{\r
-       const switch_management_interface_t *ptr;\r
-       switch_status_t status = SWITCH_STATUS_FALSE;\r
-\r
-       if ((ptr = switch_loadable_module_get_management_interface(relative_oid))) {\r
-               status = ptr->management_function(relative_oid, action, data, datalen);\r
-       }\r
-\r
-       return status;\r
-}\r
-\r
-SWITCH_DECLARE(void) switch_core_memory_reclaim_all(void)\r
-{\r
-       switch_core_memory_reclaim_logger();\r
-       switch_core_memory_reclaim_events();\r
-       switch_core_memory_reclaim();\r
-}\r
-\r
-\r
-struct system_thread_handle {\r
-       const char *cmd;\r
-       switch_thread_cond_t *cond;\r
-       switch_mutex_t *mutex;\r
-       switch_memory_pool_t *pool;\r
-       int ret;\r
-       int *fds;\r
-};\r
-\r
-static void *SWITCH_THREAD_FUNC system_thread(switch_thread_t *thread, void *obj)\r
-{\r
-       struct system_thread_handle *sth = (struct system_thread_handle *) obj;\r
-\r
-#if 0                                                  // if we are a luser we can never turn this back down, didn't we already set the stack size?\r
-#if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__)\r
-       struct rlimit rlim;\r
-\r
-       rlim.rlim_cur = SWITCH_SYSTEM_THREAD_STACKSIZE;\r
-       rlim.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE;\r
-       if (setrlimit(RLIMIT_STACK, &rlim) < 0) {\r
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno));\r
-       }\r
-#endif\r
-#endif\r
-\r
-       if (sth->fds) {\r
-               dup2(sth->fds[1], STDOUT_FILENO);\r
-       }\r
-\r
-       sth->ret = system(sth->cmd);\r
-\r
-#if 0\r
-#if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__)\r
-       rlim.rlim_cur = SWITCH_THREAD_STACKSIZE;\r
-       rlim.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE;\r
-       if (setrlimit(RLIMIT_STACK, &rlim) < 0) {\r
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno));\r
-       }\r
-#endif\r
-#endif\r
-\r
-       switch_mutex_lock(sth->mutex);\r
-       switch_thread_cond_signal(sth->cond);\r
-       switch_mutex_unlock(sth->mutex);\r
-\r
-       switch_core_destroy_memory_pool(&sth->pool);\r
-\r
-       return NULL;\r
-}\r
-\r
-\r
-static int switch_system_thread(const char *cmd, switch_bool_t wait)\r
-{\r
-       switch_thread_t *thread;\r
-       switch_threadattr_t *thd_attr;\r
-       int ret = 0;\r
-       struct system_thread_handle *sth;\r
-       switch_memory_pool_t *pool;\r
-\r
-       if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {\r
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n");\r
-               return 1;\r
-       }\r
-\r
-       if (!(sth = switch_core_alloc(pool, sizeof(struct system_thread_handle)))) {\r
-               switch_core_destroy_memory_pool(&pool);\r
-               return 1;\r
-       }\r
-\r
-       sth->pool = pool;\r
-       sth->cmd = switch_core_strdup(pool, cmd);\r
-\r
-       switch_thread_cond_create(&sth->cond, sth->pool);\r
-       switch_mutex_init(&sth->mutex, SWITCH_MUTEX_NESTED, sth->pool);\r
-       switch_mutex_lock(sth->mutex);\r
-\r
-       switch_threadattr_create(&thd_attr, sth->pool);\r
-       switch_threadattr_stacksize_set(thd_attr, SWITCH_SYSTEM_THREAD_STACKSIZE);\r
-       switch_threadattr_detach_set(thd_attr, 1);\r
-       switch_thread_create(&thread, thd_attr, system_thread, sth, sth->pool);\r
-\r
-       if (wait) {\r
-               switch_thread_cond_wait(sth->cond, sth->mutex);\r
-               ret = sth->ret;\r
-       }\r
-       switch_mutex_unlock(sth->mutex);\r
-\r
-       return ret;\r
-}\r
-\r
-SWITCH_DECLARE(int) switch_max_file_desc(void)\r
-{\r
-       int max = 0;\r
-\r
-#ifndef WIN32\r
-#if defined(HAVE_GETDTABLESIZE)\r
-       max = getdtablesize();\r
-#else\r
-       max = sysconf(_SC_OPEN_MAX);\r
-#endif\r
-#endif\r
-\r
-       return max;\r
-\r
-}\r
-\r
-SWITCH_DECLARE(void) switch_close_extra_files(int *keep, int keep_ttl)\r
-{\r
-       int open_max = switch_max_file_desc();\r
-       int i, j;\r
-\r
-       for (i = 3; i < open_max; i++) {\r
-               if (keep) {\r
-                       for (j = 0; j < keep_ttl; j++) {\r
-                               if (i == keep[j]) {\r
-                                       goto skip;\r
-                               }\r
-                       }\r
-               }\r
-\r
-               close(i);\r
-\r
-       skip:\r
-\r
-               continue;\r
-\r
-       }\r
-}\r
-\r
-\r
-#ifdef WIN32\r
-static int switch_system_fork(const char *cmd, switch_bool_t wait)\r
-{\r
-       return switch_system_thread(cmd, wait);\r
-}\r
-\r
-SWITCH_DECLARE(pid_t) switch_fork(void)\r
-{\r
-       return -1;\r
-}\r
-\r
-\r
-#else\r
-\r
-SWITCH_DECLARE(pid_t) switch_fork(void)\r
-{\r
-       int i = fork();\r
-\r
-       if (!i) {\r
-               set_low_priority();\r
-       }\r
-\r
-       return i;\r
-}\r
-\r
-\r
-\r
-static int switch_system_fork(const char *cmd, switch_bool_t wait)\r
-{\r
-       int pid;\r
-       char *dcmd = strdup(cmd);\r
-\r
-       switch_core_set_signal_handlers();\r
-\r
-       pid = switch_fork();\r
-       \r
-       if (pid) {\r
-               if (wait) {\r
-                       waitpid(pid, NULL, 0);\r
-               }\r
-               free(dcmd);\r
-       } else {\r
-               switch_close_extra_files(NULL, 0);\r
-               \r
-               if (system(dcmd) == -1) {\r
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to execute because of a command error : %s\n", dcmd);\r
-               }\r
-               free(dcmd);\r
-               exit(0);\r
-       }\r
-\r
-       return 0;\r
-}\r
-#endif\r
-\r
-\r
-\r
-SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait)\r
-{\r
-       int (*sys_p)(const char *cmd, switch_bool_t wait);\r
-\r
-       sys_p = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC) ? switch_system_thread : switch_system_fork;\r
-\r
-       return sys_p(cmd, wait);\r
-\r
-}\r
-\r
-\r
-\r
-SWITCH_DECLARE(int) switch_stream_system_fork(const char *cmd, switch_stream_handle_t *stream)\r
-{\r
-#ifdef WIN32\r
-       return switch_system(cmd, SWITCH_TRUE);\r
-#else\r
-       int fds[2], pid = 0;\r
-\r
-       if (pipe(fds)) {\r
-               goto end;\r
-       } else {                                        /* good to go */\r
-               pid = switch_fork();\r
-\r
-               if (pid < 0) {                  /* ok maybe not */\r
-                       close(fds[0]);\r
-                       close(fds[1]);\r
-                       goto end;\r
-               } else if (pid) {               /* parent */\r
-                       char buf[1024] = "";\r
-                       int bytes;\r
-                       close(fds[1]);\r
-                       while ((bytes = read(fds[0], buf, sizeof(buf))) > 0) {\r
-                               stream->raw_write_function(stream, (unsigned char *)buf, bytes);\r
-                       }\r
-                       close(fds[0]);\r
-                       waitpid(pid, NULL, 0);\r
-               } else {                                /*  child */\r
-                       switch_close_extra_files(fds, 2);\r
-                       close(fds[0]);\r
-                       dup2(fds[1], STDOUT_FILENO);\r
-                       switch_system(cmd, SWITCH_TRUE);\r
-                       close(fds[1]);\r
-                       exit(0);\r
-               }\r
-       }\r
-\r
- end:\r
-\r
-       return 0;\r
-\r
-#endif\r
-\r
-}\r
-\r
-SWITCH_DECLARE(switch_status_t) switch_core_get_stacksizes(switch_size_t *cur, switch_size_t *max)\r
-{\r
-#ifdef HAVE_SETRLIMIT\r
-       struct rlimit rlp;\r
-\r
-       memset(&rlp, 0, sizeof(rlp));\r
-       getrlimit(RLIMIT_STACK, &rlp);\r
-\r
-       *cur = rlp.rlim_cur;\r
-       *max = rlp.rlim_max;\r
-\r
-       return SWITCH_STATUS_SUCCESS;\r
-\r
-#else\r
-\r
-       return SWITCH_STATUS_FALSE;\r
-\r
-#endif\r
-\r
-\r
-\r
-}\r
-\r
-\r
-SWITCH_DECLARE(int) switch_stream_system(const char *cmd, switch_stream_handle_t *stream)\r
-{\r
-#ifdef WIN32\r
-       stream->write_function(stream, "Capturing output not supported.\n");\r
-       return switch_system(cmd, SWITCH_TRUE);\r
-#else\r
-       return switch_stream_system_fork(cmd, stream);\r
-#endif\r
-\r
-}\r
-\r
-/* For Emacs:\r
- * Local Variables:\r
- * mode:c\r
- * indent-tabs-mode:t\r
- * tab-width:4\r
- * c-basic-offset:4\r
- * End:\r
- * For VIM:\r
- * vim:set softtabstop=4 shiftwidth=4 tabstop=4:\r
- */\r
+/* 
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II <anthm@freeswitch.org>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Anthony Minessale II <anthm@freeswitch.org>
+ * Michael Jerris <mike@jerris.com>
+ * Paul D. Tinsley <pdt at jackhammer.org>
+ * Marcel Barbulescu <marcelbarbulescu@gmail.com>
+ * Joseph Sullivan <jossulli@amazon.com>
+ *
+ *
+ * switch_core.c -- Main Core Library
+ *
+ */
+
+
+
+#include <switch.h>
+#include <switch_ssl.h>
+#include <switch_stun.h>
+#include <switch_nat.h>
+#include <switch_version.h>
+#include "private/switch_core_pvt.h"
+#include <switch_curl.h>
+#ifndef WIN32
+#include <switch_private.h>
+#ifdef HAVE_SETRLIMIT
+#include <sys/resource.h>
+#endif
+#endif
+#include <errno.h>
+
+
+SWITCH_DECLARE_DATA switch_directories SWITCH_GLOBAL_dirs = { 0 };
+
+/* The main runtime obj we keep this hidden for ourselves */
+struct switch_runtime runtime = { 0 };
+static void switch_load_core_config(const char *file);
+
+static void send_heartbeat(void)
+{
+       switch_event_t *event;
+       switch_core_time_duration_t duration;
+
+       switch_core_measure_time(switch_core_uptime(), &duration);
+
+       if (switch_event_create(&event, SWITCH_EVENT_HEARTBEAT) == SWITCH_STATUS_SUCCESS) {
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready");
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Up-Time",
+                                                               "%u year%s, "
+                                                               "%u day%s, "
+                                                               "%u hour%s, "
+                                                               "%u minute%s, "
+                                                               "%u second%s, "
+                                                               "%u millisecond%s, "
+                                                               "%u microsecond%s",
+                                                               duration.yr, duration.yr == 1 ? "" : "s",
+                                                               duration.day, duration.day == 1 ? "" : "s",
+                                                               duration.hr, duration.hr == 1 ? "" : "s",
+                                                               duration.min, duration.min == 1 ? "" : "s",
+                                                               duration.sec, duration.sec == 1 ? "" : "s",
+                                                               duration.ms, duration.ms == 1 ? "" : "s", duration.mms, duration.mms == 1 ? "" : "s");
+
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FreeSWITCH-Version", SWITCH_VERSION_FULL);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Uptime-msec", "%"SWITCH_TIME_T_FMT, switch_core_uptime() / 1000);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Count", "%u", switch_core_session_count());
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Max-Sessions", "%u", switch_core_session_limit(0));
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec", "%u", runtime.sps);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Since-Startup", "%" SWITCH_SIZE_T_FMT, switch_core_session_id() - 1);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Idle-CPU", "%f", switch_core_idle_cpu());
+               switch_event_fire(&event);
+       }
+}
+
+static char main_ip4[256] = "";
+static char main_ip6[256] = "";
+
+static void check_ip(void)
+{
+       char guess_ip4[256] = "";
+       char guess_ip6[256] = "";
+       char old_ip4[256] = "";
+       char old_ip6[256] = "";
+       int ok4 = 1, ok6 = 1;
+       int mask = 0;
+
+       gethostname(runtime.hostname, sizeof(runtime.hostname));
+       switch_core_set_variable("hostname", runtime.hostname);
+
+       switch_find_local_ip(guess_ip4, sizeof(guess_ip4), &mask, AF_INET);
+       switch_find_local_ip(guess_ip6, sizeof(guess_ip6), NULL, AF_INET6);
+
+       if (!*main_ip4) {
+               switch_set_string(main_ip4, guess_ip4);
+       } else {
+               if (!(ok4 = !strcmp(main_ip4, guess_ip4))) {
+                       struct in_addr in;
+
+                       in.s_addr = mask;
+                       switch_set_string(old_ip4, main_ip4);
+                       switch_set_string(main_ip4, guess_ip4);
+                       switch_core_set_variable("local_ip_v4", guess_ip4);
+                       switch_core_set_variable("local_mask_v4", inet_ntoa(in));
+               }
+       }
+
+       if (!*main_ip6) {
+               switch_set_string(main_ip6, guess_ip6);
+       } else {
+               if (!(ok6 = !strcmp(main_ip6, guess_ip6))) {
+                       switch_set_string(old_ip6, main_ip6);
+                       switch_set_string(main_ip6, guess_ip6);
+                       switch_core_set_variable("local_ip_v6", guess_ip6);
+               }
+       }
+
+       if (!ok4 || !ok6) {
+               switch_event_t *event;
+
+               if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "network-address-change");
+                       if (!ok4) {
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v4", old_ip4);
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v4", main_ip4);
+                       }
+                       if (!ok6) {
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v6", old_ip6);
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v6", main_ip6);
+                       }
+                       switch_event_fire(&event);
+               }
+       }
+}
+
+SWITCH_STANDARD_SCHED_FUNC(heartbeat_callback)
+{
+       send_heartbeat();
+
+       /* reschedule this task */
+       task->runtime = switch_epoch_time_now(NULL) + 20;
+}
+
+
+SWITCH_STANDARD_SCHED_FUNC(check_ip_callback)
+{
+       check_ip();
+
+       /* reschedule this task */
+       task->runtime = switch_epoch_time_now(NULL) + 60;
+}
+
+
+SWITCH_DECLARE(switch_status_t) switch_core_set_console(const char *console)
+{
+       if ((runtime.console = fopen(console, "a")) == 0) {
+               fprintf(stderr, "Cannot open output file %s.\n", console);
+               return SWITCH_STATUS_FALSE;
+       }
+
+       return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_DECLARE(FILE *) switch_core_get_console(void)
+{
+       return runtime.console;
+}
+
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+SWITCH_DECLARE(void) switch_core_screen_size(int *x, int *y)
+{
+
+#ifdef WIN32
+       CONSOLE_SCREEN_BUFFER_INFO csbi;
+       int ret;
+
+       if ((ret = GetConsoleScreenBufferInfo(GetStdHandle( STD_OUTPUT_HANDLE ), &csbi))) {
+               if (x) *x = csbi.dwSize.X;
+               if (y) *y = csbi.dwSize.Y;
+       }
+
+#elif defined(TIOCGWINSZ)
+       struct winsize w;
+       ioctl(0, TIOCGWINSZ, &w);
+
+       if (x) *x = w.ws_col;
+       if (y) *y = w.ws_row;
+#else
+       if (x) *x = 80;
+       if (y) *y = 24;
+#endif
+
+}
+
+SWITCH_DECLARE(FILE *) switch_core_data_channel(switch_text_channel_t channel)
+{
+       FILE *handle = stdout;
+
+       switch (channel) {
+       case SWITCH_CHANNEL_ID_LOG:
+       case SWITCH_CHANNEL_ID_LOG_CLEAN:
+               handle = runtime.console;
+               break;
+       default:
+               handle = runtime.console;
+               break;
+       }
+
+       return handle;
+}
+
+
+SWITCH_DECLARE(void) switch_core_remove_state_handler(const switch_state_handler_table_t *state_handler)
+{
+       int index, tmp_index = 0;
+       const switch_state_handler_table_t *tmp[SWITCH_MAX_STATE_HANDLERS + 1] = { 0 };
+
+       switch_mutex_lock(runtime.global_mutex);
+
+       for (index = 0; index < runtime.state_handler_index; index++) {
+               const switch_state_handler_table_t *cur = runtime.state_handlers[index];
+               runtime.state_handlers[index] = NULL;
+               if (cur == state_handler) {
+                       continue;
+               }
+               tmp[tmp_index++] = cur;
+       }
+
+       runtime.state_handler_index = 0;
+
+       for (index = 0; index < tmp_index; index++) {
+               runtime.state_handlers[runtime.state_handler_index++] = tmp[index];
+       }
+       switch_mutex_unlock(runtime.global_mutex);
+}
+
+
+SWITCH_DECLARE(int) switch_core_add_state_handler(const switch_state_handler_table_t *state_handler)
+{
+       int index;
+
+       switch_mutex_lock(runtime.global_mutex);
+       index = runtime.state_handler_index++;
+
+       if (runtime.state_handler_index >= SWITCH_MAX_STATE_HANDLERS) {
+               index = -1;
+       } else {
+               runtime.state_handlers[index] = state_handler;
+       }
+
+       switch_mutex_unlock(runtime.global_mutex);
+       return index;
+}
+
+SWITCH_DECLARE(const switch_state_handler_table_t *) switch_core_get_state_handler(int index)
+{
+
+       if (index >= SWITCH_MAX_STATE_HANDLERS || index > runtime.state_handler_index) {
+               return NULL;
+       }
+
+       return runtime.state_handlers[index];
+}
+
+SWITCH_DECLARE(void) switch_core_dump_variables(switch_stream_handle_t *stream)
+{
+       switch_event_header_t *hi;
+
+       switch_mutex_lock(runtime.global_mutex);
+       for (hi = runtime.global_vars->headers; hi; hi = hi->next) {
+               stream->write_function(stream, "%s=%s\n", hi->name, hi->value);
+       }
+       switch_mutex_unlock(runtime.global_mutex);
+}
+
+SWITCH_DECLARE(const char *) switch_core_get_hostname(void)
+{
+       return runtime.hostname;
+}
+
+SWITCH_DECLARE(const char *) switch_core_get_switchname(void)
+{
+    if (!zstr(runtime.switchname)) return runtime.switchname;
+       return runtime.hostname;
+}
+
+
+SWITCH_DECLARE(char *) switch_core_get_variable(const char *varname)
+{
+       char *val;
+       switch_thread_rwlock_rdlock(runtime.global_var_rwlock);
+       val = (char *) switch_event_get_header(runtime.global_vars, varname);
+       switch_thread_rwlock_unlock(runtime.global_var_rwlock);
+       return val;
+}
+
+SWITCH_DECLARE(char *) switch_core_get_variable_dup(const char *varname)
+{
+       char *val = NULL, *v;
+
+       switch_thread_rwlock_rdlock(runtime.global_var_rwlock);
+       if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) {
+               val = strdup(v);
+       }
+       switch_thread_rwlock_unlock(runtime.global_var_rwlock);
+
+       return val;
+}
+
+SWITCH_DECLARE(char *) switch_core_get_variable_pdup(const char *varname, switch_memory_pool_t *pool)
+{
+       char *val = NULL, *v;
+
+       switch_thread_rwlock_rdlock(runtime.global_var_rwlock);
+       if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) {
+               val = switch_core_strdup(pool, v);
+       }
+       switch_thread_rwlock_unlock(runtime.global_var_rwlock);
+
+       return val;
+}
+
+static void switch_core_unset_variables(void)
+{
+       switch_thread_rwlock_wrlock(runtime.global_var_rwlock);
+       switch_event_destroy(&runtime.global_vars);
+       switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA);
+       switch_thread_rwlock_unlock(runtime.global_var_rwlock);
+}
+
+SWITCH_DECLARE(void) switch_core_set_variable(const char *varname, const char *value)
+{
+       char *val;
+
+       if (varname) {
+               switch_thread_rwlock_wrlock(runtime.global_var_rwlock);
+               val = (char *) switch_event_get_header(runtime.global_vars, varname);
+               if (val) {
+                       switch_event_del_header(runtime.global_vars, varname);
+               }
+               if (value) {
+                       char *v = strdup(value);
+                       switch_string_var_check(v, SWITCH_TRUE);
+                       switch_event_add_header_string(runtime.global_vars, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, varname, v);
+               } else {
+                       switch_event_del_header(runtime.global_vars, varname);
+               }
+               switch_thread_rwlock_unlock(runtime.global_var_rwlock);
+       }
+}
+
+SWITCH_DECLARE(switch_bool_t) switch_core_set_var_conditional(const char *varname, const char *value, const char *val2)
+{
+       char *val;
+
+       if (varname) {
+               switch_thread_rwlock_wrlock(runtime.global_var_rwlock);
+               val = (char *) switch_event_get_header(runtime.global_vars, varname);
+
+               if (val) {
+                       if (!val2 || strcmp(val, val2) != 0) {
+                               switch_thread_rwlock_unlock(runtime.global_var_rwlock);
+                               return SWITCH_FALSE;
+                       }
+                       switch_event_del_header(runtime.global_vars, varname);
+               } else if (!zstr(val2)) {
+                       switch_thread_rwlock_unlock(runtime.global_var_rwlock);
+                       return SWITCH_FALSE;
+               }
+
+               if (value) {
+                       char *v = strdup(value);
+                       switch_string_var_check(v, SWITCH_TRUE);
+                       switch_event_add_header_string(runtime.global_vars, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, varname, v);
+               } else {
+                       switch_event_del_header(runtime.global_vars, varname);
+               }
+               switch_thread_rwlock_unlock(runtime.global_var_rwlock);
+       }
+       return SWITCH_TRUE;
+}
+
+SWITCH_DECLARE(char *) switch_core_get_uuid(void)
+{
+       return runtime.uuid_str;
+}
+
+
+static void *SWITCH_THREAD_FUNC switch_core_service_thread(switch_thread_t *thread, void *obj)
+{
+       switch_core_session_t *session = obj;
+       switch_channel_t *channel;
+       switch_frame_t *read_frame;
+
+//  switch_assert(thread != NULL);
+//  switch_assert(session != NULL);
+
+       if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
+               return NULL;
+       }
+
+       switch_mutex_lock(session->frame_read_mutex);
+
+       channel = switch_core_session_get_channel(session);
+
+       switch_channel_set_flag(channel, CF_SERVICE);
+       while (switch_channel_test_flag(channel, CF_SERVICE)) {
+
+               if (switch_channel_test_flag(channel, CF_SERVICE_AUDIO)) {
+                       switch (switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) {
+                       case SWITCH_STATUS_SUCCESS:
+                       case SWITCH_STATUS_TIMEOUT:
+                       case SWITCH_STATUS_BREAK:
+                               break;
+                       default:
+                               switch_channel_clear_flag(channel, CF_SERVICE);
+                               break;
+                       }
+               }
+
+               if (switch_channel_test_flag(channel, CF_SERVICE_VIDEO) && switch_channel_test_flag(channel, CF_VIDEO)) {
+                       switch (switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) {
+                       case SWITCH_STATUS_SUCCESS:
+                       case SWITCH_STATUS_TIMEOUT:
+                       case SWITCH_STATUS_BREAK:
+                               break;
+                       default:
+                               switch_channel_clear_flag(channel, CF_SERVICE);
+                               break;
+                       }
+               }
+       }
+
+       switch_mutex_unlock(session->frame_read_mutex);
+
+       switch_channel_clear_flag(channel, CF_SERVICE_AUDIO);
+       switch_channel_clear_flag(channel, CF_SERVICE_VIDEO);
+
+       switch_core_session_rwunlock(session);
+
+       return NULL;
+}
+
+/* Either add a timeout here or make damn sure the thread cannot get hung somehow (my preference) */
+SWITCH_DECLARE(void) switch_core_thread_session_end(switch_core_session_t *session)
+{
+       switch_channel_t *channel;
+       switch_assert(session);
+
+       channel = switch_core_session_get_channel(session);
+       switch_assert(channel);
+
+       switch_channel_clear_flag(channel, CF_SERVICE);
+       switch_channel_clear_flag(channel, CF_SERVICE_AUDIO);
+       switch_channel_clear_flag(channel, CF_SERVICE_VIDEO);
+
+       switch_core_session_kill_channel(session, SWITCH_SIG_BREAK);
+       
+}
+
+SWITCH_DECLARE(void) switch_core_service_session_av(switch_core_session_t *session, switch_bool_t audio, switch_bool_t video)
+{
+       switch_channel_t *channel;
+       switch_assert(session);
+
+       channel = switch_core_session_get_channel(session);
+       switch_assert(channel);
+
+       if (audio) switch_channel_set_flag(channel, CF_SERVICE_AUDIO);
+       if (video) switch_channel_set_flag(channel, CF_SERVICE_VIDEO);
+
+       switch_core_session_launch_thread(session, (void *(*)(switch_thread_t *,void *))switch_core_service_thread, session);
+}
+
+/* This function abstracts the thread creation for modules by allowing you to pass a function ptr and
+   a void object and trust that that the function will be run in a thread with arg  This lets
+   you request and activate a thread without giving up any knowledge about what is in the thread
+   neither the core nor the calling module know anything about each other.
+
+   This thread is expected to never exit until the application exits so the func is responsible
+   to make sure that is the case.
+
+   The typical use for this is so switch_loadable_module.c can start up a thread for each module
+   passing the table of module methods as a session obj into the core without actually allowing
+   the core to have any clue and keeping switch_loadable_module.c from needing any thread code.
+
+*/
+
+SWITCH_DECLARE(switch_thread_t *) switch_core_launch_thread(switch_thread_start_t func, void *obj, switch_memory_pool_t *pool)
+{
+       switch_thread_t *thread = NULL;
+       switch_threadattr_t *thd_attr = NULL;
+       switch_core_thread_session_t *ts;
+       int mypool;
+
+       mypool = pool ? 0 : 1;
+
+       if (!pool && switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory pool\n");
+               return NULL;
+       }
+
+       switch_threadattr_create(&thd_attr, pool);
+
+       if ((ts = switch_core_alloc(pool, sizeof(*ts))) == 0) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory\n");
+       } else {
+               if (mypool) {
+                       ts->pool = pool;
+               }
+               ts->objs[0] = obj;
+               ts->objs[1] = thread;
+               switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
+               switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);
+               switch_thread_create(&thread, thd_attr, func, ts, pool);
+       }
+
+       return thread;
+}
+
+SWITCH_DECLARE(void) switch_core_set_globals(void)
+{
+#define BUFSIZE 1024
+#ifdef WIN32
+       char lpPathBuffer[BUFSIZE];
+       DWORD dwBufSize = BUFSIZE;
+       char base_dir[1024];
+       char *lastbacklash;
+       char *tmp;
+
+       GetModuleFileName(NULL, base_dir, BUFSIZE);
+       lastbacklash = strrchr(base_dir, '\\');
+       base_dir[(lastbacklash - base_dir)] = '\0';
+       /* set base_dir as cwd, to be able to use relative paths in scripting languages (e.g. mod_lua) when FS is running as a service or while debugging FS using visual studio */
+       SetCurrentDirectory(base_dir);
+       tmp = switch_string_replace(base_dir, "\\", "/");
+       strcpy(base_dir, tmp);
+       free(tmp);
+
+#else
+       char base_dir[1024] = SWITCH_PREFIX_DIR;
+#endif
+
+       if (!SWITCH_GLOBAL_dirs.base_dir && (SWITCH_GLOBAL_dirs.base_dir = (char *) malloc(BUFSIZE))) {
+               switch_snprintf(SWITCH_GLOBAL_dirs.base_dir, BUFSIZE, "%s", base_dir);
+       }
+
+       if (!SWITCH_GLOBAL_dirs.mod_dir && (SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(BUFSIZE))) {
+#ifdef SWITCH_MOD_DIR
+               switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s", SWITCH_MOD_DIR);
+#else
+               switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s%smod", base_dir, SWITCH_PATH_SEPARATOR);
+#endif
+       }
+
+       if (!SWITCH_GLOBAL_dirs.lib_dir && (SWITCH_GLOBAL_dirs.lib_dir = (char *) malloc(BUFSIZE))) {
+#ifdef SWITCH_LIB_DIR
+               switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s", SWITCH_LIB_DIR);
+#else
+               switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s%slib", base_dir, SWITCH_PATH_SEPARATOR);
+#endif
+       }
+
+       if (!SWITCH_GLOBAL_dirs.conf_dir && (SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(BUFSIZE))) {
+#ifdef SWITCH_CONF_DIR
+               switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s", SWITCH_CONF_DIR);
+#else
+               switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s%sconf", base_dir, SWITCH_PATH_SEPARATOR);
+#endif
+       }
+
+       if (!SWITCH_GLOBAL_dirs.log_dir && (SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(BUFSIZE))) {
+#ifdef SWITCH_LOG_DIR
+               switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s", SWITCH_LOG_DIR);
+#else
+               switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s%slog", base_dir, SWITCH_PATH_SEPARATOR);
+#endif
+       }
+
+       if (!SWITCH_GLOBAL_dirs.run_dir && (SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(BUFSIZE))) {
+#ifdef SWITCH_RUN_DIR
+               switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE, "%s", SWITCH_RUN_DIR);
+#else
+               switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE, "%s%srun", base_dir, SWITCH_PATH_SEPARATOR);
+#endif
+       }
+
+       if (!SWITCH_GLOBAL_dirs.recordings_dir && (SWITCH_GLOBAL_dirs.recordings_dir = (char *) malloc(BUFSIZE))) {
+#ifdef SWITCH_RECORDINGS_DIR
+               switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE, "%s", SWITCH_RECORDINGS_DIR);
+#else
+               switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE, "%s%srecordings", base_dir, SWITCH_PATH_SEPARATOR);
+#endif
+       }
+
+       if (!SWITCH_GLOBAL_dirs.sounds_dir && (SWITCH_GLOBAL_dirs.sounds_dir = (char *) malloc(BUFSIZE))) {
+#ifdef SWITCH_SOUNDS_DIR
+               switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE, "%s", SWITCH_SOUNDS_DIR);
+#else
+               switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE, "%s%ssounds", base_dir, SWITCH_PATH_SEPARATOR);
+#endif
+       }
+
+       if (!SWITCH_GLOBAL_dirs.storage_dir && (SWITCH_GLOBAL_dirs.storage_dir = (char *) malloc(BUFSIZE))) {
+#ifdef SWITCH_STORAGE_DIR
+               switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE, "%s", SWITCH_STORAGE_DIR);
+#else
+               switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE, "%s%sstorage", base_dir, SWITCH_PATH_SEPARATOR);
+#endif
+       }
+
+       if (!SWITCH_GLOBAL_dirs.db_dir && (SWITCH_GLOBAL_dirs.db_dir = (char *) malloc(BUFSIZE))) {
+#ifdef SWITCH_DB_DIR
+               switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s", SWITCH_DB_DIR);
+#else
+               switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s%sdb", base_dir, SWITCH_PATH_SEPARATOR);
+#endif
+       }
+
+       if (!SWITCH_GLOBAL_dirs.script_dir && (SWITCH_GLOBAL_dirs.script_dir = (char *) malloc(BUFSIZE))) {
+#ifdef SWITCH_SCRIPT_DIR
+               switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s", SWITCH_SCRIPT_DIR);
+#else
+               switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s%sscripts", base_dir, SWITCH_PATH_SEPARATOR);
+#endif
+       }
+
+       if (!SWITCH_GLOBAL_dirs.htdocs_dir && (SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(BUFSIZE))) {
+#ifdef SWITCH_HTDOCS_DIR
+               switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s", SWITCH_HTDOCS_DIR);
+#else
+               switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s%shtdocs", base_dir, SWITCH_PATH_SEPARATOR);
+#endif
+       }
+
+       if (!SWITCH_GLOBAL_dirs.grammar_dir && (SWITCH_GLOBAL_dirs.grammar_dir = (char *) malloc(BUFSIZE))) {
+#ifdef SWITCH_GRAMMAR_DIR
+               switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE, "%s", SWITCH_GRAMMAR_DIR);
+#else
+               switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE, "%s%sgrammar", base_dir, SWITCH_PATH_SEPARATOR);
+#endif
+       }
+
+       if (!SWITCH_GLOBAL_dirs.temp_dir && (SWITCH_GLOBAL_dirs.temp_dir = (char *) malloc(BUFSIZE))) {
+#ifdef SWITCH_TEMP_DIR
+               switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", SWITCH_TEMP_DIR);
+#else
+#ifdef WIN32
+               GetTempPath(dwBufSize, lpPathBuffer);
+               lpPathBuffer[strlen(lpPathBuffer)-1] = 0;
+               switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", lpPathBuffer);
+#else
+               switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", "/tmp");
+#endif
+#endif
+       }
+
+       switch_assert(SWITCH_GLOBAL_dirs.base_dir);
+       switch_assert(SWITCH_GLOBAL_dirs.mod_dir);
+       switch_assert(SWITCH_GLOBAL_dirs.lib_dir);
+       switch_assert(SWITCH_GLOBAL_dirs.conf_dir);
+       switch_assert(SWITCH_GLOBAL_dirs.log_dir);
+       switch_assert(SWITCH_GLOBAL_dirs.run_dir);
+       switch_assert(SWITCH_GLOBAL_dirs.db_dir);
+       switch_assert(SWITCH_GLOBAL_dirs.script_dir);
+       switch_assert(SWITCH_GLOBAL_dirs.htdocs_dir);
+       switch_assert(SWITCH_GLOBAL_dirs.grammar_dir);
+       switch_assert(SWITCH_GLOBAL_dirs.recordings_dir);
+       switch_assert(SWITCH_GLOBAL_dirs.sounds_dir);
+       switch_assert(SWITCH_GLOBAL_dirs.temp_dir);
+}
+
+
+SWITCH_DECLARE(int32_t) set_low_priority(void)
+{
+
+
+#ifdef WIN32
+       SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
+#else
+#ifdef USE_SCHED_SETSCHEDULER
+       /*
+        * Try to use a normal scheduler
+        */
+       struct sched_param sched = { 0 };
+       sched.sched_priority = 0;
+       if (sched_setscheduler(0, SCHED_OTHER, &sched)) {
+               return -1;
+       }
+#endif
+
+#ifdef HAVE_SETPRIORITY
+       /*
+        * setpriority() works on FreeBSD (6.2), nice() doesn't
+        */
+       if (setpriority(PRIO_PROCESS, getpid(), 19) < 0) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n");
+               return -1;
+       }
+#else
+       if (nice(19) != 19) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n");
+               return -1;
+       }
+#endif
+#endif
+
+       return 0;
+}
+
+SWITCH_DECLARE(int32_t) set_realtime_priority(void)
+{
+#ifdef WIN32
+       SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
+#else
+#ifdef USE_SCHED_SETSCHEDULER
+       /*
+        * Try to use a round-robin scheduler
+        * with a fallback if that does not work
+        */
+       struct sched_param sched = { 0 };
+       sched.sched_priority = SWITCH_PRI_LOW;
+       if (sched_setscheduler(0, SCHED_FIFO, &sched)) {
+               sched.sched_priority = 0;
+               if (sched_setscheduler(0, SCHED_OTHER, &sched)) {
+                       return -1;
+               }
+       }
+#endif
+
+       
+
+#ifdef HAVE_SETPRIORITY
+       /*
+        * setpriority() works on FreeBSD (6.2), nice() doesn't
+        */
+       if (setpriority(PRIO_PROCESS, getpid(), -10) < 0) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n");
+               return -1;
+       }
+#else
+       if (nice(-10) != -10) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n");
+               return -1;
+       }
+#endif
+#endif
+       return 0;
+}
+
+SWITCH_DECLARE(uint32_t) switch_core_cpu_count(void)
+{
+       return runtime.cpu_count;
+}
+
+SWITCH_DECLARE(int32_t) set_normal_priority(void)
+{
+       return 0;
+}
+
+SWITCH_DECLARE(int32_t) set_auto_priority(void)
+{
+#ifndef WIN32
+       runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN);
+#else
+       SYSTEM_INFO sysinfo;
+       GetSystemInfo( &sysinfo );
+       runtime.cpu_count = sysinfo.dwNumberOfProcessors;
+#endif
+
+       if (!runtime.cpu_count) runtime.cpu_count = 1;
+
+       /* If we have more than 1 cpu, we should use realtime priority so we can have priority threads */
+       if (runtime.cpu_count > 1) {
+               return set_realtime_priority();
+       }
+
+       return 0;
+}
+
+SWITCH_DECLARE(int32_t) change_user_group(const char *user, const char *group)
+{
+#ifndef WIN32
+       uid_t runas_uid = 0;
+       gid_t runas_gid = 0;
+       struct passwd *runas_pw = NULL;
+
+       if (user) {
+               /*
+                * Lookup user information in the system's db
+                */
+               runas_pw = getpwnam(user);
+               if (!runas_pw) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unknown user \"%s\"\n", user);
+                       return -1;
+               }
+               runas_uid = runas_pw->pw_uid;
+       }
+
+       if (group) {
+               struct group *gr = NULL;
+
+               /*
+                * Lookup group information in the system's db
+                */
+               gr = getgrnam(group);
+               if (!gr) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unknown group \"%s\"\n", group);
+                       return -1;
+               }
+               runas_gid = gr->gr_gid;
+       }
+
+       if (runas_uid && getuid() == runas_uid && (!runas_gid || runas_gid == getgid())) {
+               /* already running as the right user and group, nothing to do! */
+               return 0;
+       }
+
+       if (runas_uid) {
+#ifdef HAVE_SETGROUPS
+               /*
+                * Drop all group memberships prior to changing anything
+                * or else we're going to inherit the parent's list of groups
+                * (which is not what we want...)
+                */
+               if (setgroups(0, NULL) < 0) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to drop group access list\n");
+                       return -1;
+               }
+#endif
+               if (runas_gid) {
+                       /*
+                        * A group has been passed, switch to it
+                        * (without loading the user's other groups)
+                        */
+                       if (setgid(runas_gid) < 0) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change gid!\n");
+                               return -1;
+                       }
+               } else {
+                       /*
+                        * No group has been passed, use the user's primary group in this case
+                        */
+                       if (setgid(runas_pw->pw_gid) < 0) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change gid!\n");
+                               return -1;
+                       }
+#ifdef HAVE_INITGROUPS
+                       /*
+                        * Set all the other groups the user is a member of
+                        * (This can be really useful for fine-grained access control)
+                        */
+                       if (initgroups(runas_pw->pw_name, runas_pw->pw_gid) < 0) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to set group access list for user\n");
+                               return -1;
+                       }
+#endif
+               }
+
+               /*
+                * Finally drop all privileges by switching to the new userid
+                */
+               if (setuid(runas_uid) < 0) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change uid!\n");
+                       return -1;
+               }
+       }
+#endif
+       return 0;
+}
+
+SWITCH_DECLARE(void) switch_core_runtime_loop(int bg)
+{
+#ifdef WIN32
+       HANDLE shutdown_event;
+       char path[256] = "";
+#endif
+       if (bg) {
+               bg = 0;
+#ifdef WIN32
+               switch_snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid());
+               shutdown_event = CreateEvent(NULL, FALSE, FALSE, path);
+               if (shutdown_event) {
+                       WaitForSingleObject(shutdown_event, INFINITE);
+               }
+#else
+               runtime.running = 1;
+               while (runtime.running) {
+                       switch_yield(1000000);
+               }
+#endif
+       } else {
+               /* wait for console input */
+               switch_console_loop();
+       }
+}
+
+SWITCH_DECLARE(const char *) switch_core_mime_ext2type(const char *ext)
+{
+       if (!ext) {
+               return NULL;
+       }
+       return (const char *) switch_core_hash_find(runtime.mime_types, ext);
+}
+
+
+SWITCH_DECLARE(switch_hash_index_t *) switch_core_mime_index(void)
+{
+       return switch_hash_first(NULL, runtime.mime_types);
+}
+
+SWITCH_DECLARE(switch_status_t) switch_core_mime_add_type(const char *type, const char *ext)
+{
+       const char *check;
+       switch_status_t status = SWITCH_STATUS_FALSE;
+
+       switch_assert(type);
+       switch_assert(ext);
+
+       check = (const char *) switch_core_hash_find(runtime.mime_types, ext);
+
+       if (!check) {
+               char *ptype = switch_core_permanent_strdup(type);
+               char *ext_list = strdup(ext);
+               int argc = 0;
+               char *argv[20] = { 0 };
+               int x;
+
+               switch_assert(ext_list);
+
+               if ((argc = switch_separate_string(ext_list, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
+
+                       for (x = 0; x < argc; x++) {
+                               if (argv[x] && ptype) {
+                                       switch_core_hash_insert(runtime.mime_types, argv[x], ptype);
+                               }
+                       }
+
+                       status = SWITCH_STATUS_SUCCESS;
+               }
+
+               free(ext_list);
+       }
+
+       return status;
+}
+
+static void load_mime_types(void)
+{
+       char *cf = "mime.types";
+       FILE *fd = NULL;
+       char *line_buf = NULL;
+       switch_size_t llen = 0;
+       char *mime_path = NULL;
+
+       mime_path = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.conf_dir, cf);
+       switch_assert(mime_path);
+
+       fd = fopen(mime_path, "rb");
+
+       if (fd == NULL) {
+               goto end;
+       }
+
+       while ((switch_fp_read_dline(fd, &line_buf, &llen))) {
+               char *p;
+               char *type = line_buf;
+
+               if (*line_buf == '#') {
+                       continue;
+               }
+
+               if ((p = strchr(line_buf, '\r')) || (p = strchr(line_buf, '\n'))) {
+                       *p = '\0';
+               }
+
+               if ((p = strchr(type, '\t')) || (p = strchr(type, ' '))) {
+                       *p++ = '\0';
+
+                       while (*p == ' ' || *p == '\t') {
+                               p++;
+                       }
+
+                       switch_core_mime_add_type(type, p);
+               }
+
+       }
+
+       switch_safe_free(line_buf);
+
+       if (fd) {
+               fclose(fd);
+               fd = NULL;
+       }
+
+  end:
+
+       switch_safe_free(mime_path);
+
+}
+
+SWITCH_DECLARE(void) switch_core_setrlimits(void)
+{
+#ifdef HAVE_SETRLIMIT
+       struct rlimit rlp;
+
+       /* 
+          Setting the stack size on FreeBSD results in an instant crash.
+
+          If anyone knows how to fix this,
+          feel free to submit a patch to http://jira.freeswitch.org 
+        */
+
+#ifndef __FreeBSD__
+       memset(&rlp, 0, sizeof(rlp));
+       rlp.rlim_cur = SWITCH_THREAD_STACKSIZE;
+       rlp.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE;
+       setrlimit(RLIMIT_STACK, &rlp);
+#endif
+
+       memset(&rlp, 0, sizeof(rlp));
+       rlp.rlim_cur = 999999;
+       rlp.rlim_max = 999999;
+       setrlimit(RLIMIT_NOFILE, &rlp);
+
+       memset(&rlp, 0, sizeof(rlp));
+       rlp.rlim_cur = RLIM_INFINITY;
+       rlp.rlim_max = RLIM_INFINITY;
+
+       setrlimit(RLIMIT_CPU, &rlp);
+       setrlimit(RLIMIT_DATA, &rlp);
+       setrlimit(RLIMIT_FSIZE, &rlp);
+#ifdef RLIMIT_NPROC
+       setrlimit(RLIMIT_NPROC, &rlp);
+#endif
+#ifdef RLIMIT_RTPRIO
+       setrlimit(RLIMIT_RTPRIO, &rlp);
+#endif
+
+#if !defined(__OpenBSD__) && !defined(__NetBSD__)
+       setrlimit(RLIMIT_AS, &rlp);
+#endif
+#endif
+       return;
+}
+
+typedef struct {
+       switch_memory_pool_t *pool;
+       switch_hash_t *hash;
+} switch_ip_list_t;
+
+static switch_ip_list_t IP_LIST = { 0 };
+
+SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token)
+{
+       switch_network_list_t *list;
+       ip_t  ip, mask, net;
+       uint32_t bits;
+       char *ipv6 = strchr(ip_str,':');
+       switch_bool_t ok = SWITCH_FALSE;
+
+       switch_mutex_lock(runtime.global_mutex);
+       if (ipv6) {
+               switch_inet_pton(AF_INET6, ip_str, &ip);
+       } else {
+               switch_inet_pton(AF_INET, ip_str, &ip);
+               ip.v4 = htonl(ip.v4);
+       }
+
+       if ((list = switch_core_hash_find(IP_LIST.hash, list_name))) {
+               if (ipv6) {
+                       ok = switch_network_list_validate_ip6_token(list, ip, token);
+               } else {
+                       ok = switch_network_list_validate_ip_token(list, ip.v4, token);
+               }
+       } else if (strchr(list_name, '/')) {
+               if (strchr(list_name, ',')) {
+                       char *list_name_dup = strdup(list_name);
+                       char *argv[32];
+                       int argc;
+
+                       switch_assert(list_name_dup);
+
+                       if ((argc = switch_separate_string(list_name_dup, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
+                               int i;
+                               for (i = 0; i < argc; i++) {
+                                       switch_parse_cidr(argv[i], &net, &mask, &bits);
+                                       if (ipv6) {
+                                               if ((ok = switch_testv6_subnet(ip, net, mask))){
+                                                       break;
+                                               }
+                                       } else {
+                                               if ((ok = switch_test_subnet(ip.v4, net.v4, mask.v4))) {
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+                       free(list_name_dup);
+               } else {
+                       switch_parse_cidr(list_name, &net, &mask, &bits);
+                       ok = switch_test_subnet(ip.v4, net.v4, mask.v4);
+               }
+       }
+       switch_mutex_unlock(runtime.global_mutex);
+
+       return ok;
+}
+
+
+SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload)
+{
+       switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, x_node = NULL, cfg = NULL;
+       switch_network_list_t *rfc_list, *list;
+       char guess_ip[16] = "";
+       int mask = 0;
+       char guess_mask[16] = "";
+       char *tmp_name;
+       struct in_addr in;
+
+       switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET);
+       in.s_addr = mask;
+       switch_set_string(guess_mask, inet_ntoa(in));
+
+       switch_mutex_lock(runtime.global_mutex);
+
+       if (IP_LIST.hash) {
+               switch_core_hash_destroy(&IP_LIST.hash);
+       }
+
+       if (IP_LIST.pool) {
+               switch_core_destroy_memory_pool(&IP_LIST.pool);
+       }
+
+       memset(&IP_LIST, 0, sizeof(IP_LIST));
+       switch_core_new_memory_pool(&IP_LIST.pool);
+       switch_core_hash_init(&IP_LIST.hash, IP_LIST.pool);
+
+
+       tmp_name = "rfc1918.auto";
+       switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
+       switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE);
+       switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE);
+       switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE);
+       switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
+
+       tmp_name = "wan.auto";
+       switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool);
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name);
+       switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_FALSE);
+       switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_FALSE);
+       switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_FALSE);
+       switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
+
+       tmp_name = "nat.auto";
+       switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
+       if (switch_network_list_add_host_mask(rfc_list, guess_ip, guess_mask, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (deny) to list %s\n", guess_ip, guess_mask, tmp_name);
+       }
+       switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE);
+       switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE);
+       switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE);
+       switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
+
+       tmp_name = "loopback.auto";
+       switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
+       switch_network_list_add_cidr(rfc_list, "127.0.0.0/8", SWITCH_TRUE);
+       switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
+
+       tmp_name = "localnet.auto";
+       switch_network_list_create(&list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
+
+       if (switch_network_list_add_host_mask(list, guess_ip, guess_mask, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (allow) to list %s\n", guess_ip, guess_mask, tmp_name);
+       }
+       switch_core_hash_insert(IP_LIST.hash, tmp_name, list);
+
+
+       if ((xml = switch_xml_open_cfg("acl.conf", &cfg, NULL))) {
+               if ((x_lists = switch_xml_child(cfg, "network-lists"))) {
+                       for (x_list = switch_xml_child(x_lists, "list"); x_list; x_list = x_list->next) {
+                               const char *name = switch_xml_attr(x_list, "name");
+                               const char *dft = switch_xml_attr(x_list, "default");
+                               switch_bool_t default_type = SWITCH_TRUE;
+
+                               if (zstr(name)) {
+                                       continue;
+                               }
+
+                               if (dft) {
+                                       default_type = switch_true(dft);
+                               }
+
+                               if (switch_network_list_create(&list, name, default_type, IP_LIST.pool) != SWITCH_STATUS_SUCCESS) {
+                                       abort();
+                               }
+
+                               if (reload) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny");
+                               } else {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny");
+                               }
+
+
+                               for (x_node = switch_xml_child(x_list, "node"); x_node; x_node = x_node->next) {
+                                       const char *cidr = NULL, *host = NULL, *mask = NULL, *domain = NULL;
+                                       switch_bool_t ok = default_type;
+                                       const char *type = switch_xml_attr(x_node, "type");
+
+                                       if (type) {
+                                               ok = switch_true(type);
+                                       }
+
+                                       cidr = switch_xml_attr(x_node, "cidr");
+                                       host = switch_xml_attr(x_node, "host");
+                                       mask = switch_xml_attr(x_node, "mask");
+                                       domain = switch_xml_attr(x_node, "domain");
+
+                                       if (domain) {
+                                               switch_event_t *my_params = NULL;
+                                               switch_xml_t x_domain, xml_root;
+                                               switch_xml_t gt, gts, ut, uts;
+
+                                               switch_event_create(&my_params, SWITCH_EVENT_GENERAL);
+                                               switch_assert(my_params);
+                                               switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "domain", domain);
+                                               switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "purpose", "network-list");
+
+                                               if (switch_xml_locate_domain(domain, my_params, &xml_root, &x_domain) != SWITCH_STATUS_SUCCESS) {
+                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate domain %s\n", domain);
+                                                       switch_event_destroy(&my_params);
+                                                       continue;
+                                               }
+
+                                               switch_event_destroy(&my_params);
+
+                                               for (ut = switch_xml_child(x_domain, "user"); ut; ut = ut->next) {
+                                                       const char *user_cidr = switch_xml_attr(ut, "cidr");
+                                                       const char *id = switch_xml_attr(ut, "id");
+
+                                                       if (id && user_cidr) {
+                                                               char *token = switch_mprintf("%s@%s", id, domain);
+                                                               switch_assert(token);
+                                                               switch_network_list_add_cidr_token(list, user_cidr, ok, token);
+                                                               free(token);
+                                                       }
+                                               }
+
+                                               for (gts = switch_xml_child(x_domain, "groups"); gts; gts = gts->next) {
+                                                       for (gt = switch_xml_child(gts, "group"); gt; gt = gt->next) {
+                                                               for (uts = switch_xml_child(gt, "users"); uts; uts = uts->next) {
+                                                                       for (ut = switch_xml_child(uts, "user"); ut; ut = ut->next) {
+                                                                               const char *user_cidr = switch_xml_attr(ut, "cidr");
+                                                                               const char *id = switch_xml_attr(ut, "id");
+
+                                                                               if (id && user_cidr) {
+                                                                                       char *token = switch_mprintf("%s@%s", id, domain);
+                                                                                       switch_assert(token);
+                                                                                       switch_network_list_add_cidr_token(list, user_cidr, ok, token);
+                                                                                       free(token);
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+
+                                               switch_xml_free(xml_root);
+                                       } else if (cidr) {
+                                               if (switch_network_list_add_cidr(list, cidr, ok) == SWITCH_STATUS_SUCCESS) {
+                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name);
+                                               } else {
+                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
+                                                                                         "Error Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name);
+                                               }
+                                       } else if (host && mask) {
+                                               if (switch_network_list_add_host_mask(list, host, mask, ok) == SWITCH_STATUS_SUCCESS) {
+                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,
+                                                                                         "Adding %s/%s (%s) to list %s\n", host, mask, ok ? "allow" : "deny", name);
+                                               }
+                                       }
+
+                                       switch_core_hash_insert(IP_LIST.hash, name, list);
+                               }
+                       }
+               }
+
+               switch_xml_free(xml);
+       }
+
+       switch_mutex_unlock(runtime.global_mutex);
+}
+
+SWITCH_DECLARE(uint32_t) switch_core_max_dtmf_duration(uint32_t duration)
+{
+       if (duration) {
+               if (duration > SWITCH_MAX_DTMF_DURATION) {
+                       duration = SWITCH_MAX_DTMF_DURATION;
+               }
+               if (duration < SWITCH_MIN_DTMF_DURATION) {
+                       duration = SWITCH_MIN_DTMF_DURATION;
+               }
+               runtime.max_dtmf_duration = duration;
+               if (duration < runtime.min_dtmf_duration) {
+                       runtime.min_dtmf_duration = duration;
+               }
+       }
+       return runtime.max_dtmf_duration;
+}
+
+SWITCH_DECLARE(uint32_t) switch_core_default_dtmf_duration(uint32_t duration)
+{
+       if (duration) {
+               if (duration < SWITCH_MIN_DTMF_DURATION) {
+                       duration = SWITCH_MIN_DTMF_DURATION;
+               }
+               if (duration > SWITCH_MAX_DTMF_DURATION) {
+                       duration = SWITCH_MAX_DTMF_DURATION;
+               }
+               runtime.default_dtmf_duration = duration;
+
+               if (duration < runtime.min_dtmf_duration) {
+                       runtime.min_dtmf_duration = duration;
+               }
+
+               if (duration > runtime.max_dtmf_duration) {
+                       runtime.max_dtmf_duration = duration;
+               }
+
+       }
+       return runtime.default_dtmf_duration;
+}
+
+SWITCH_DECLARE(uint32_t) switch_core_min_dtmf_duration(uint32_t duration)
+{
+       if (duration) {
+               if (duration < SWITCH_MIN_DTMF_DURATION) {
+                       duration = SWITCH_MIN_DTMF_DURATION;
+               }
+               if (duration > SWITCH_MAX_DTMF_DURATION) {
+                       duration = SWITCH_MAX_DTMF_DURATION;
+               }
+
+               runtime.min_dtmf_duration = duration;
+
+               if (duration > runtime.max_dtmf_duration) {
+                       runtime.max_dtmf_duration = duration;
+               }
+       }
+       return runtime.min_dtmf_duration;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_core_thread_set_cpu_affinity(int cpu)
+{
+       switch_status_t status = SWITCH_STATUS_FALSE;
+
+       if (cpu > -1) {
+
+#ifdef HAVE_CPU_SET_MACROS
+               cpu_set_t set;
+
+               CPU_ZERO(&set);
+               CPU_SET(cpu, &set);
+
+               if (!sched_setaffinity(0, sizeof(set), &set)) {
+                       status = SWITCH_STATUS_SUCCESS;
+               }
+               
+#else
+#if WIN32
+               if (SetThreadAffinityMask(GetCurrentThread(), (DWORD_PTR) cpu)) {
+                       status = SWITCH_STATUS_SUCCESS;
+               }
+#endif
+#endif
+       }
+
+       return status;
+}
+
+
+static void switch_core_set_serial(void)
+{
+       char buf[13] = "";
+       char path[256];
+
+       int fd = -1, write_fd = -1;
+       switch_ssize_t bytes = 0;
+
+       switch_snprintf(path, sizeof(path), "%s%sfreeswitch.serial", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR);
+
+
+       if ((fd = open(path, O_RDONLY, 0)) < 0) {
+               char *ip = switch_core_get_variable_dup("local_ip_v4");
+               uint32_t ipi = 0;
+               switch_byte_t *byte;
+               int i = 0;
+
+               if (ip) {
+                       switch_inet_pton(AF_INET, ip, &ipi);
+                       free(ip);
+                       ip = NULL;
+               }
+
+
+               byte = (switch_byte_t *) & ipi;
+
+               for (i = 0; i < 8; i += 2) {
+                       switch_snprintf(buf + i, sizeof(buf) - i, "%0.2x", *byte);
+                       byte++;
+               }
+
+               switch_stun_random_string(buf + 8, 4, "0123456789abcdef");
+
+               if ((write_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) >= 0) {
+                       bytes = write(write_fd, buf, sizeof(buf));
+                       bytes++;
+                       close(write_fd);
+                       write_fd = -1;
+               }
+       } else {
+               bytes = read(fd, buf, sizeof(buf));
+               close(fd);
+               fd = -1;
+       }
+
+       switch_core_set_variable("switch_serial", buf);
+}
+
+
+SWITCH_DECLARE(int) switch_core_test_flag(int flag)
+{
+       return switch_test_flag((&runtime), flag);
+}
+
+
+SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switch_bool_t console, const char **err)
+{
+       switch_uuid_t uuid;
+       char guess_ip[256];
+       int mask = 0;
+       struct in_addr in;
+
+
+       if (runtime.runlevel > 0) {
+               /* one per customer */
+               return SWITCH_STATUS_SUCCESS;
+       }
+       
+       memset(&runtime, 0, sizeof(runtime));
+       gethostname(runtime.hostname, sizeof(runtime.hostname));
+
+       runtime.max_db_handles = 50;
+       runtime.db_handle_timeout = 5000000;
+       
+       runtime.runlevel++;
+       runtime.dummy_cng_frame.data = runtime.dummy_data;
+       runtime.dummy_cng_frame.datalen = sizeof(runtime.dummy_data);
+       runtime.dummy_cng_frame.buflen = sizeof(runtime.dummy_data);
+       runtime.dbname = "core";
+       switch_set_flag((&runtime.dummy_cng_frame), SFF_CNG);
+       switch_set_flag((&runtime), SCF_AUTO_SCHEMAS);
+       switch_set_flag((&runtime), SCF_CLEAR_SQL);
+       switch_set_flag((&runtime), SCF_API_EXPANSION);
+       switch_set_flag((&runtime), SCF_SESSION_THREAD_POOL);
+#ifdef WIN32
+       switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
+#endif
+       switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
+       runtime.hard_log_level = SWITCH_LOG_DEBUG;
+       runtime.mailer_app = "sendmail";
+       runtime.mailer_app_args = "-t";
+       runtime.max_dtmf_duration = SWITCH_MAX_DTMF_DURATION;
+       runtime.default_dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION;
+       runtime.min_dtmf_duration = SWITCH_MIN_DTMF_DURATION;
+       runtime.odbc_dbtype = DBTYPE_DEFAULT;
+       runtime.dbname = NULL;
+#ifndef WIN32
+       runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN);
+#else
+       {
+               SYSTEM_INFO sysinfo;
+               GetSystemInfo( &sysinfo );
+               runtime.cpu_count = sysinfo.dwNumberOfProcessors;
+       }
+#endif 
+
+       if (!runtime.cpu_count) runtime.cpu_count = 1;
+
+
+       /* INIT APR and Create the pool context */
+       if (apr_initialize() != SWITCH_STATUS_SUCCESS) {
+               *err = "FATAL ERROR! Could not initialize APR\n";
+               return SWITCH_STATUS_MEMERR;
+       }
+
+       if (!(runtime.memory_pool = switch_core_memory_init())) {
+               *err = "FATAL ERROR! Could not allocate memory pool\n";
+               return SWITCH_STATUS_MEMERR;
+       }
+       switch_assert(runtime.memory_pool != NULL);
+
+       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.base_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
+       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.mod_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
+       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.conf_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
+       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.log_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
+       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.run_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
+       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.db_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
+       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.script_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
+       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.htdocs_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
+       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
+       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.recordings_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
+       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.sounds_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
+       switch_dir_make_recursive(SWITCH_GLOBAL_dirs.temp_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
+
+
+       switch_mutex_init(&runtime.uuid_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
+
+       switch_mutex_init(&runtime.throttle_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
+
+       switch_mutex_init(&runtime.session_hash_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
+       switch_mutex_init(&runtime.global_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
+
+       switch_thread_rwlock_create(&runtime.global_var_rwlock, runtime.memory_pool);
+       switch_core_set_globals();
+       switch_core_session_init(runtime.memory_pool);
+       switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA);
+       switch_core_hash_init(&runtime.mime_types, runtime.memory_pool);
+       switch_core_hash_init_case(&runtime.ptimes, runtime.memory_pool, SWITCH_FALSE);
+       load_mime_types();
+       runtime.flags |= flags;
+       runtime.sps_total = 30;
+
+       *err = NULL;
+
+       if (console) {
+               runtime.console = stdout;
+       }
+
+       switch_ssl_init_ssl_locks();
+       switch_curl_init();
+
+       switch_core_set_variable("hostname", runtime.hostname);
+       switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET);
+       switch_core_set_variable("local_ip_v4", guess_ip);
+       in.s_addr = mask;
+       switch_core_set_variable("local_mask_v4", inet_ntoa(in));
+
+
+       switch_find_local_ip(guess_ip, sizeof(guess_ip), NULL, AF_INET6);
+       switch_core_set_variable("local_ip_v6", guess_ip);
+       switch_core_set_variable("base_dir", SWITCH_GLOBAL_dirs.base_dir);
+       switch_core_set_variable("recordings_dir", SWITCH_GLOBAL_dirs.recordings_dir);
+       switch_core_set_variable("sound_prefix", SWITCH_GLOBAL_dirs.sounds_dir);
+       switch_core_set_variable("sounds_dir", SWITCH_GLOBAL_dirs.sounds_dir);
+       switch_core_set_serial();
+
+       switch_console_init(runtime.memory_pool);
+       switch_event_init(runtime.memory_pool);
+
+       if (switch_xml_init(runtime.memory_pool, err) != SWITCH_STATUS_SUCCESS) {
+               apr_terminate();
+               return SWITCH_STATUS_MEMERR;
+       }
+
+       if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) {
+               switch_nat_init(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_NAT_MAPPING));
+       }
+
+       switch_log_init(runtime.memory_pool, runtime.colorize_console);
+
+       if (flags & SCF_MINIMAL) return SWITCH_STATUS_SUCCESS;
+                       
+       runtime.tipping_point = 0;
+       runtime.timer_affinity = -1;
+       runtime.microseconds_per_tick = 20000;
+
+       switch_load_core_config("switch.conf");
+
+       switch_core_state_machine_init(runtime.memory_pool);
+
+       if (switch_core_sqldb_start(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_SQL) ? SWITCH_TRUE : SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) {
+               *err = "Error activating database";
+               return SWITCH_STATUS_FALSE;
+       }
+
+       switch_scheduler_task_thread_start();
+
+       switch_nat_late_init();
+
+       switch_rtp_init(runtime.memory_pool);
+
+       runtime.running = 1;
+       runtime.initiated = switch_time_now();
+       runtime.mono_initiated = switch_mono_micro_time_now();
+       
+       switch_scheduler_add_task(switch_epoch_time_now(NULL), heartbeat_callback, "heartbeat", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL);
+
+       switch_scheduler_add_task(switch_epoch_time_now(NULL), check_ip_callback, "check_ip", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL | SSHF_OWN_THREAD);
+
+       switch_uuid_get(&uuid);
+       switch_uuid_format(runtime.uuid_str, &uuid);
+       switch_core_set_variable("core_uuid", runtime.uuid_str);
+
+
+       return SWITCH_STATUS_SUCCESS;
+}
+
+
+#ifndef WIN32
+static void handle_SIGCHLD(int sig)
+{
+       int status = 0;
+
+       wait(&status);
+       return;
+}
+#endif
+
+#ifdef TRAP_BUS
+static void handle_SIGBUS(int sig)
+{
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Sig BUS!\n");
+       return;
+}
+#endif
+
+static void handle_SIGHUP(int sig)
+{
+       if (sig) {
+               switch_event_t *event;
+
+               if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Trapped-Signal", "HUP");
+                       switch_event_fire(&event);
+               }
+       }
+       return;
+}
+
+
+SWITCH_DECLARE(uint32_t) switch_default_ptime(const char *name, uint32_t number)
+{
+       uint32_t *p;
+
+       if ((p = switch_core_hash_find(runtime.ptimes, name))) {
+               return *p;
+       }
+
+       return 20;
+}
+
+static uint32_t d_30 = 30;
+
+static void switch_load_core_config(const char *file)
+{
+       switch_xml_t xml = NULL, cfg = NULL;
+
+       switch_core_hash_insert(runtime.ptimes, "ilbc", &d_30);
+       switch_core_hash_insert(runtime.ptimes, "G723", &d_30);
+
+       if ((xml = switch_xml_open_cfg(file, &cfg, NULL))) {
+               switch_xml_t settings, param;
+
+               if ((settings = switch_xml_child(cfg, "default-ptimes"))) {
+                       for (param = switch_xml_child(settings, "codec"); param; param = param->next) {
+                               const char *var = switch_xml_attr_soft(param, "name");
+                               const char *val = switch_xml_attr_soft(param, "ptime");
+                               
+                               if (!zstr(var) && !zstr(val)) {
+                                       uint32_t *p;
+                                       uint32_t v = switch_atoul(val);
+
+                                       if (!strcasecmp(var, "G723") || !strcasecmp(var, "iLBC")) {
+                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, defaults cannot be changed\n", var);
+                                               continue;
+                                       }
+                                       
+                                       if (v == 0) {
+                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, invalid ptime\n", var);
+                                               continue;
+                                       }
+
+                                       p = switch_core_alloc(runtime.memory_pool, sizeof(*p));
+                                       *p = v;
+                                       switch_core_hash_insert(runtime.ptimes, var, p);
+                               }
+
+                       }
+               }
+
+               if ((settings = switch_xml_child(cfg, "settings"))) {
+                       for (param = switch_xml_child(settings, "param"); param; param = param->next) {
+                               const char *var = switch_xml_attr_soft(param, "name");
+                               const char *val = switch_xml_attr_soft(param, "value");
+
+                               if (!strcasecmp(var, "loglevel")) {
+                                       int level;
+                                       if (*val > 47 && *val < 58) {
+                                               level = atoi(val);
+                                       } else {
+                                               level = switch_log_str2level(val);
+                                       }
+
+                                       if (level != SWITCH_LOG_INVALID) {
+                                               switch_core_session_ctl(SCSC_LOGLEVEL, &level);
+                                       }
+#ifdef HAVE_SETRLIMIT
+                               } else if (!strcasecmp(var, "dump-cores") && switch_true(val)) {
+                                       struct rlimit rlp;
+                                       memset(&rlp, 0, sizeof(rlp));
+                                       rlp.rlim_cur = RLIM_INFINITY;
+                                       rlp.rlim_max = RLIM_INFINITY;
+                                       setrlimit(RLIMIT_CORE, &rlp);
+#endif
+                               } else if (!strcasecmp(var, "debug-level")) {
+                                       int tmp = atoi(val);
+                                       if (tmp > -1 && tmp < 11) {
+                                               switch_core_session_ctl(SCSC_DEBUG_LEVEL, &tmp);
+                                       }
+                               } else if (!strcasecmp(var, "max-db-handles")) {
+                                       long tmp = atol(val);
+
+                                       if (tmp > 4 && tmp < 5001) {
+                                               runtime.max_db_handles = (uint32_t) tmp;
+                                       } else {
+                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "max-db-handles must be between 5 and 5000\n");
+                                       }
+                               } else if (!strcasecmp(var, "db-handle-timeout")) {
+                                       long tmp = atol(val);
+                                       
+                                       if (tmp > 0 && tmp < 5001) {
+                                               runtime.db_handle_timeout = (uint32_t) tmp * 1000000;
+                                       } else {
+                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "db-handle-timeout must be between 1 and 5000\n");
+                                       }
+                                       
+                               } else if (!strcasecmp(var, "multiple-registrations")) {
+                                       runtime.multiple_registrations = switch_true(val);
+                               } else if (!strcasecmp(var, "auto-create-schemas")) {
+                                       if (switch_true(val)) {
+                                               switch_set_flag((&runtime), SCF_AUTO_SCHEMAS);
+                                       } else {
+                                               switch_clear_flag((&runtime), SCF_AUTO_SCHEMAS);
+                                       }
+                               } else if (!strcasecmp(var, "session-thread-pool")) {
+                                       if (switch_true(val)) {
+                                               switch_set_flag((&runtime), SCF_SESSION_THREAD_POOL);
+                                       } else {
+                                               switch_clear_flag((&runtime), SCF_SESSION_THREAD_POOL);
+                                       }
+                               } else if (!strcasecmp(var, "auto-clear-sql")) {
+                                       if (switch_true(val)) {
+                                               switch_set_flag((&runtime), SCF_CLEAR_SQL);
+                                       } else {
+                                               switch_clear_flag((&runtime), SCF_CLEAR_SQL);
+                                       }
+                               } else if (!strcasecmp(var, "api-expansion")) {
+                                       if (switch_true(val)) {
+                                               switch_set_flag((&runtime), SCF_API_EXPANSION);
+                                       } else {
+                                               switch_clear_flag((&runtime), SCF_API_EXPANSION);
+                                       }
+                               } else if (!strcasecmp(var, "enable-early-hangup") && switch_true(val)) {
+                                       switch_set_flag((&runtime), SCF_EARLY_HANGUP);
+                               } else if (!strcasecmp(var, "colorize-console") && switch_true(val)) {
+                                       runtime.colorize_console = SWITCH_TRUE;
+                               } else if (!strcasecmp(var, "core-db-pre-trans-execute") && !zstr(val)) {
+                                       runtime.core_db_pre_trans_execute = switch_core_strdup(runtime.memory_pool, val);
+                               } else if (!strcasecmp(var, "core-db-post-trans-execute") && !zstr(val)) {
+                                       runtime.core_db_post_trans_execute = switch_core_strdup(runtime.memory_pool, val);
+                               } else if (!strcasecmp(var, "core-db-inner-pre-trans-execute") && !zstr(val)) {
+                                       runtime.core_db_inner_pre_trans_execute = switch_core_strdup(runtime.memory_pool, val);
+                               } else if (!strcasecmp(var, "core-db-inner-post-trans-execute") && !zstr(val)) {
+                                       runtime.core_db_inner_post_trans_execute = switch_core_strdup(runtime.memory_pool, val);
+                               } else if (!strcasecmp(var, "mailer-app") && !zstr(val)) {
+                                       runtime.mailer_app = switch_core_strdup(runtime.memory_pool, val);
+                               } else if (!strcasecmp(var, "mailer-app-args") && val) {
+                                       runtime.mailer_app_args = switch_core_strdup(runtime.memory_pool, val);
+                               } else if (!strcasecmp(var, "sessions-per-second") && !zstr(val)) {
+                                       switch_core_sessions_per_second(atoi(val));
+                               } else if (!strcasecmp(var, "max-dtmf-duration") && !zstr(val)) {
+                                       int tmp = atoi(val);
+                                       if (tmp > 0) {
+                                               switch_core_max_dtmf_duration((uint32_t) tmp);
+                                       }
+                               } else if (!strcasecmp(var, "min-dtmf-duration") && !zstr(val)) {
+                                       int tmp = atoi(val);
+                                       if (tmp > 0) {
+                                               switch_core_min_dtmf_duration((uint32_t) tmp);
+                                       }
+                               } else if (!strcasecmp(var, "default-dtmf-duration") && !zstr(val)) {
+                                       int tmp = atoi(val);
+                                       if (tmp > 0) {
+                                               switch_core_default_dtmf_duration((uint32_t) tmp);
+                                       }
+                               } else if (!strcasecmp(var, "enable-use-system-time")) {
+                                       switch_time_set_use_system_time(switch_true(val));
+                               } else if (!strcasecmp(var, "enable-monotonic-timing")) {
+                                       switch_time_set_monotonic(switch_true(val));
+                               } else if (!strcasecmp(var, "enable-softtimer-timerfd")) {
+                                       switch_time_set_timerfd(switch_true(val));
+                               } else if (!strcasecmp(var, "enable-clock-nanosleep")) {
+                                       switch_time_set_nanosleep(switch_true(val));
+                               } else if (!strcasecmp(var, "enable-cond-yield")) {
+                                       switch_time_set_cond_yield(switch_true(val));
+                               } else if (!strcasecmp(var, "enable-timer-matrix")) {
+                                       switch_time_set_matrix(switch_true(val));
+                               } else if (!strcasecmp(var, "max-sessions") && !zstr(val)) {
+                                       switch_core_session_limit(atoi(val));
+                               } else if (!strcasecmp(var, "verbose-channel-events") && !zstr(val)) {
+                                       int v = switch_true(val);
+                                       if (v) {
+                                               switch_set_flag((&runtime), SCF_VERBOSE_EVENTS);
+                                       } else {
+                                               switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS);
+                                       }
+                               } else if (!strcasecmp(var, "threaded-system-exec") && !zstr(val)) {
+#ifdef WIN32
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "threaded-system-exec is not implemented on this platform\n");
+#else
+                                       int v = switch_true(val);
+                                       if (v) {
+                                               switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
+                                       } else {
+                                               switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
+                                       }
+#endif
+                               } else if (!strcasecmp(var, "min-idle-cpu") && !zstr(val)) {
+                                       switch_core_min_idle_cpu(atof(val));
+                               } else if (!strcasecmp(var, "tipping-point") && !zstr(val)) {
+                                       runtime.tipping_point = atoi(val);
+                               } else if (!strcasecmp(var, "initial-event-threads") && !zstr(val)) {
+                                       int tmp = atoi(val);
+
+
+                                       if (tmp > runtime.cpu_count / 2) {
+                                               tmp = runtime.cpu_count / 2;
+                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be higher than %d so setting it to that value\n", 
+                                                                                 runtime.cpu_count / 2);
+                                       }
+
+                                       if (tmp < 1) {
+                                               tmp = 1;
+                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be lower than 1 so setting it to that level\n");
+                                       }
+
+                                       switch_event_launch_dispatch_threads(tmp);
+
+                               } else if (!strcasecmp(var, "1ms-timer") && switch_true(val)) {
+                                       runtime.microseconds_per_tick = 1000;
+                               } else if (!strcasecmp(var, "timer-affinity") && !zstr(val)) {
+                                       if (!strcasecmp(val, "disabled")) {
+                                               runtime.timer_affinity = -1;
+                                       } else {
+                                               runtime.timer_affinity = atoi(val);
+                                       }
+                               } else if (!strcasecmp(var, "rtp-start-port") && !zstr(val)) {
+                                       switch_rtp_set_start_port((switch_port_t) atoi(val));
+                               } else if (!strcasecmp(var, "rtp-end-port") && !zstr(val)) {
+                                       switch_rtp_set_end_port((switch_port_t) atoi(val));
+                               } else if (!strcasecmp(var, "core-db-name") && !zstr(val)) {
+                                       runtime.dbname = switch_core_strdup(runtime.memory_pool, val);
+                               } else if (!strcasecmp(var, "core-db-dsn") && !zstr(val)) {
+                                       if (switch_odbc_available() || switch_pgsql_available()) {
+                                               runtime.odbc_dsn = switch_core_strdup(runtime.memory_pool, val);
+                                       } else {
+                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC AND PGSQL ARE NOT AVAILABLE!\n");
+                                       }
+                               } else if (!strcasecmp(var, "core-non-sqlite-db-required") && !zstr(val)) {
+                                       switch_set_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ);
+                               } else if (!strcasecmp(var, "core-dbtype") && !zstr(val)) {
+                                       if (!strcasecmp(val, "MSSQL")) {
+                                               runtime.odbc_dbtype = DBTYPE_MSSQL;
+                                       } else {
+                                               runtime.odbc_dbtype = DBTYPE_DEFAULT;
+                                       }
+#ifdef ENABLE_ZRTP
+                               } else if (!strcasecmp(var, "rtp-enable-zrtp")) {
+                                       switch_core_set_variable("zrtp_enabled", val);
+#endif
+                } else if (!strcasecmp(var, "switchname") && !zstr(val)) {
+                                       runtime.switchname = switch_core_strdup(runtime.memory_pool, val);
+                    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Set switchname to %s\n", runtime.switchname);
+                               }
+                       }
+               }
+
+               if ((settings = switch_xml_child(cfg, "variables"))) {
+                       for (param = switch_xml_child(settings, "variable"); param; param = param->next) {
+                               const char *var = switch_xml_attr_soft(param, "name");
+                               const char *val = switch_xml_attr_soft(param, "value");
+                               if (var && val) {
+                                       switch_core_set_variable(var, val);
+                               }
+                       }
+               }
+
+               switch_xml_free(xml);
+       }
+
+
+}
+
+SWITCH_DECLARE(const char *) switch_core_banner(void)
+{
+
+       return ("\n"
+                       ".=============================================================.\n"
+                       "|   _____              ______        _____ _____ ____ _   _   |\n"
+                       "|  |  ___| __ ___  ___/ ___\\ \\      / /_ _|_   _/ ___| | | |  |\n"
+                       "|  | |_ | '__/ _ \\/ _ \\___ \\\\ \\ /\\ / / | |  | || |   | |_| |  |\n"
+                       "|  |  _|| | |  __/  __/___) |\\ V  V /  | |  | || |___|  _  |  |\n"
+                       "|  |_|  |_|  \\___|\\___|____/  \\_/\\_/  |___| |_| \\____|_| |_|  |\n"
+                       "|                                                             |\n"
+                       ".=============================================================."
+                       "\n"
+
+                       "|   Anthony Minessale II, Michael Jerris, Brian West, Others  |\n"
+                       "|   FreeSWITCH (http://www.freeswitch.org)                    |\n"
+                       "|   Paypal Donations Appreciated: paypal@freeswitch.org       |\n"
+                       "|   Brought to you by ClueCon http://www.cluecon.com/         |\n" 
+                       ".=============================================================.\n" 
+                       "\n");
+}
+
+
+SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t flags, switch_bool_t console, const char **err)
+{
+       switch_event_t *event;
+       char *cmd;
+       int x = 0;
+       const char *use = NULL;
+#include "cc.h"
+
+
+       if (switch_core_init(flags, console, err) != SWITCH_STATUS_SUCCESS) {
+               return SWITCH_STATUS_GENERR;
+       }
+       
+       if (runtime.runlevel > 1) {
+               /* one per customer */
+               return SWITCH_STATUS_SUCCESS;
+       }
+
+       runtime.runlevel++;
+
+       switch_core_set_signal_handlers();
+       switch_load_network_lists(SWITCH_FALSE);
+
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bringing up environment.\n");
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Loading Modules.\n");
+       if (switch_loadable_module_init(SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
+               *err = "Cannot load modules";
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Error: %s\n", *err);
+               return SWITCH_STATUS_GENERR;
+       }
+
+       switch_load_network_lists(SWITCH_FALSE);
+
+       switch_load_core_config("post_load_switch.conf");
+
+       switch_core_set_signal_handlers();
+
+       if (switch_event_create(&event, SWITCH_EVENT_STARTUP) == SWITCH_STATUS_SUCCESS) {
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready");
+               switch_event_fire(&event);
+       }
+
+       switch_core_screen_size(&x, NULL);
+
+       use = (x > 100) ? cc : cc_s;
+
+#ifdef WIN32
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s\n\n", switch_core_banner(), use);
+#else
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s%s%s%s%s\n\n", 
+                                         SWITCH_SEQ_DEFAULT_COLOR,
+                                         SWITCH_SEQ_FYELLOW, SWITCH_SEQ_BBLUE,
+                                         switch_core_banner(), 
+                                         use, SWITCH_SEQ_DEFAULT_COLOR);
+       
+#endif
+
+
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE,
+                                         "\nFreeSWITCH Version %s (%s)\n\nFreeSWITCH Started\nMax Sessions [%u]\nSession Rate [%d]\nSQL [%s]\n",
+                                         SWITCH_VERSION_FULL, SWITCH_VERSION_REVISION_HUMAN,
+                                         switch_core_session_limit(0),
+                                         switch_core_sessions_per_second(0), switch_test_flag((&runtime), SCF_USE_SQL) ? "Enabled" : "Disabled");
+
+
+       if (x < 160) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\n[This app Best viewed at 160x60 or more..]\n");
+       }
+
+       switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS);
+
+       if ((cmd = switch_core_get_variable_dup("api_on_startup"))) {
+               switch_stream_handle_t stream = { 0 };
+               SWITCH_STANDARD_STREAM(stream);
+               switch_console_execute(cmd, 0, &stream);
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Startup command [%s] executed. Output:\n%s\n", cmd, (char *)stream.data);
+               free(stream.data);
+               free(cmd);
+       }
+
+       return SWITCH_STATUS_SUCCESS;
+
+}
+
+SWITCH_DECLARE(void) switch_core_measure_time(switch_time_t total_ms, switch_core_time_duration_t *duration)
+{
+       switch_time_t temp = total_ms / 1000;
+       memset(duration, 0, sizeof(*duration));
+       duration->mms = (uint32_t) (total_ms % 1000);
+       duration->ms = (uint32_t) (temp % 1000);
+       temp = temp / 1000;
+       duration->sec = (uint32_t) (temp % 60);
+       temp = temp / 60;
+       duration->min = (uint32_t) (temp % 60);
+       temp = temp / 60;
+       duration->hr = (uint32_t) (temp % 24);
+       temp = temp / 24;
+       duration->day = (uint32_t) (temp % 365);
+       duration->yr = (uint32_t) (temp / 365);
+}
+
+SWITCH_DECLARE(switch_time_t) switch_core_uptime(void)
+{
+       return switch_mono_micro_time_now() - runtime.mono_initiated;
+}
+
+
+#ifdef _MSC_VER
+static void win_shutdown(void)
+{
+
+       HANDLE shutdown_event;
+       char path[512];
+       /* for windows we need the event to signal for shutting down a background FreeSWITCH */
+       snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid());
+
+       /* open the event so we can signal it */
+       shutdown_event = OpenEvent(EVENT_MODIFY_STATE, FALSE, path);
+
+       if (shutdown_event) {
+               /* signal the event to shutdown */
+               SetEvent(shutdown_event);
+               /* cleanup */
+               CloseHandle(shutdown_event);
+       }
+}
+#endif
+
+SWITCH_DECLARE(void) switch_core_set_signal_handlers(void)
+{
+       /* set signal handlers */
+       signal(SIGINT, SIG_IGN);
+#ifndef WIN32
+       if (switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC)) {
+               signal(SIGCHLD, SIG_DFL);
+       } else {
+               signal(SIGCHLD, handle_SIGCHLD);
+       }
+#endif
+#ifdef SIGPIPE
+       signal(SIGPIPE, SIG_IGN);
+#endif
+#ifdef SIGQUIT
+       signal(SIGQUIT, SIG_IGN);
+#endif
+#ifdef SIGPOLL
+       signal(SIGPOLL, SIG_IGN);
+#endif
+#ifdef SIGIO
+       signal(SIGIO, SIG_IGN);
+#endif
+#ifdef TRAP_BUS
+       signal(SIGBUS, handle_SIGBUS);
+#endif
+#ifdef SIGUSR1
+       signal(SIGUSR1, handle_SIGHUP);
+#endif
+       signal(SIGHUP, handle_SIGHUP);
+}
+
+SWITCH_DECLARE(uint32_t) switch_core_debug_level(void)
+{
+       return runtime.debug_level;
+}
+
+
+SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void *val)
+{
+       int *intval = (int *) val;
+       int oldintval = 0, newintval = 0;
+       
+       if (intval) {
+               oldintval = *intval;
+       }
+
+       if (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)) {
+               return -1;
+       }
+
+       switch (cmd) {
+       case SCSC_RECOVER:
+               {
+                       char *arg = (char *) val;
+                       char *tech = NULL, *prof = NULL;
+                       int r, flush = 0;
+
+                       if (!zstr(arg)) {
+                               tech = strdup(arg);
+                               
+                               if ((prof = strchr(tech, ':'))) {
+                                       *prof++ = '\0';
+                               }
+
+                               if (!strcasecmp(tech, "flush")) {
+                                       flush++;
+
+                                       if (prof) {
+                                               tech = prof;
+                                               if ((prof = strchr(tech, ':'))) {
+                                                       *prof++ = '\0';
+                                               }
+                                       }
+                               }
+
+                       }
+
+                       if (flush) {
+                               switch_core_recovery_flush(tech, prof);
+                               r = -1;
+                       } else {
+                               r = switch_core_recovery_recover(tech, prof);
+                       }
+
+                       switch_safe_free(tech);
+                       return r;
+
+               }
+               break;
+       case SCSC_DEBUG_SQL:
+               {
+                       if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) {
+                               switch_clear_flag((&runtime), SCF_DEBUG_SQL);
+                               newintval = 0;
+                       } else {
+                               switch_set_flag((&runtime), SCF_DEBUG_SQL);
+                               newintval = 1;
+                       }
+               }
+               break;
+       case SCSC_VERBOSE_EVENTS:
+               if (intval) {
+                       if (oldintval > -1) {
+                               if (oldintval) {
+                                       switch_set_flag((&runtime), SCF_VERBOSE_EVENTS);
+                               } else {
+                                       switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS);
+                               }
+                       }
+                       newintval = switch_test_flag((&runtime), SCF_VERBOSE_EVENTS);
+               }
+               break;
+       case SCSC_API_EXPANSION:
+               if (intval) {
+                       if (oldintval > -1) {
+                               if (oldintval) {
+                                       switch_set_flag((&runtime), SCF_API_EXPANSION);
+                               } else {
+                                       switch_clear_flag((&runtime), SCF_API_EXPANSION);
+                               }
+                       }
+                       newintval = switch_test_flag((&runtime), SCF_API_EXPANSION);
+               }
+               break;
+       case SCSC_THREADED_SYSTEM_EXEC:
+               if (intval) {
+                       if (oldintval > -1) {
+                               if (oldintval) {
+                                       switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
+                               } else {
+                                       switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
+                               }
+                       }
+                       newintval = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
+               }
+               break;
+       case SCSC_CALIBRATE_CLOCK:
+               switch_time_calibrate_clock();
+               break;
+       case SCSC_FLUSH_DB_HANDLES:
+               switch_cache_db_flush_handles();
+               break;
+       case SCSC_SEND_SIGHUP:
+               handle_SIGHUP(1);
+               break;
+       case SCSC_SYNC_CLOCK:
+               switch_time_sync();
+               newintval = 0;
+               break;
+       case SCSC_SYNC_CLOCK_WHEN_IDLE:
+               newintval = switch_core_session_sync_clock();
+               break;
+       case SCSC_SQL:
+               if (oldintval) {
+                       switch_core_sqldb_resume();
+               } else {
+                       switch_core_sqldb_pause();
+               }
+               break;
+       case SCSC_PAUSE_ALL:
+               if (oldintval) {
+                       switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
+               } else {
+                       switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS);
+               }
+               break;
+       case SCSC_PAUSE_INBOUND:
+               if (oldintval) {
+                       switch_set_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS);
+               } else {
+                       switch_clear_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS);
+               }
+               break;
+       case SCSC_PAUSE_OUTBOUND:
+               if (oldintval) {
+                       switch_set_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS);
+               } else {
+                       switch_clear_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS);
+               }
+               break;
+       case SCSC_HUPALL:
+               switch_core_session_hupall(SWITCH_CAUSE_MANAGER_REQUEST);
+               break;
+       case SCSC_CANCEL_SHUTDOWN:
+               switch_clear_flag((&runtime), SCF_SHUTDOWN_REQUESTED);
+               break;
+       case SCSC_SAVE_HISTORY:
+               switch_console_save_history();
+               break;
+       case SCSC_CRASH:
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Declinatio Mortuus Obfirmo!\n");
+               switch_console_save_history();
+               abort();
+               break;
+       case SCSC_SHUTDOWN_NOW:
+               switch_console_save_history();
+               exit(0);
+               break;
+       case SCSC_SHUTDOWN_ELEGANT:
+       case SCSC_SHUTDOWN_ASAP:
+               {
+                       int x = 19;
+                       uint32_t count;
+
+                       switch_set_flag((&runtime), SCF_SHUTDOWN_REQUESTED);
+                       if (cmd == SCSC_SHUTDOWN_ASAP) {
+                               switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
+                       }
+
+                       while (runtime.running && switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED) && (count = switch_core_session_count())) {
+                               switch_yield(500000);
+                               if (++x == 20) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
+                                                                         "Shutdown in progress, %u session(s) remain.\nShutting down %s\n",
+                                                                         count, cmd == SCSC_SHUTDOWN_ASAP ? "ASAP" : "once there are no active calls.");
+                                       x = 0;
+                               }
+                       }
+
+                       if (switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED)) {
+                               switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
+#ifdef _MSC_VER
+                               win_shutdown();
+#endif
+
+                               if (oldintval) {
+                                       switch_set_flag((&runtime), SCF_RESTART);
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n");
+                               } else {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n");
+#ifdef _MSC_VER
+                                       fclose(stdin);
+#endif
+                               }
+                               runtime.running = 0;
+                       } else {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutdown Cancelled\n");
+                               switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS);
+                       }
+               }
+               break;
+       case SCSC_PAUSE_CHECK:
+               newintval = !!(switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS);
+               break;
+       case SCSC_PAUSE_INBOUND_CHECK:
+               newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS);
+               break;
+       case SCSC_PAUSE_OUTBOUND_CHECK:
+               newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS);
+               break;
+       case SCSC_READY_CHECK:
+               newintval = switch_core_ready();
+               break;
+       case SCSC_SHUTDOWN_CHECK:
+               newintval = !!switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED);
+               break;
+       case SCSC_SHUTDOWN:
+
+#ifdef _MSC_VER
+               win_shutdown();
+#endif
+
+               if (oldintval) {
+                       switch_set_flag((&runtime), SCF_RESTART);
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n");
+               } else {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n");
+#ifdef _MSC_VER
+                       fclose(stdin);
+#endif
+               }
+               runtime.running = 0;
+               break;
+       case SCSC_CHECK_RUNNING:
+               newintval = runtime.running;
+               break;
+       case SCSC_LOGLEVEL:
+               if (oldintval > -1) {
+                       runtime.hard_log_level = oldintval;
+               }
+
+               if (runtime.hard_log_level > SWITCH_LOG_DEBUG) {
+                       runtime.hard_log_level = SWITCH_LOG_DEBUG;
+               }
+               newintval = runtime.hard_log_level;
+               break;
+       case SCSC_DEBUG_LEVEL:
+               if (oldintval > -1) {
+                       if (oldintval > 10)
+                               newintval = 10;
+                       runtime.debug_level = oldintval;
+               }
+               newintval = runtime.debug_level;
+               break;
+       case SCSC_MIN_IDLE_CPU:
+               {
+                       double *dval = (double *) val;
+                       if (dval) {
+                               *dval = switch_core_min_idle_cpu(*dval);
+                       }
+                       intval = NULL;
+               }
+               break;
+       case SCSC_MAX_SESSIONS:
+               newintval = switch_core_session_limit(oldintval);
+               break;
+       case SCSC_LAST_SPS:
+               newintval = runtime.sps_last;
+               break;
+       case SCSC_MAX_DTMF_DURATION:
+               newintval = switch_core_max_dtmf_duration(oldintval);
+               break;
+       case SCSC_MIN_DTMF_DURATION:
+               newintval = switch_core_min_dtmf_duration(oldintval);
+               break;
+       case SCSC_DEFAULT_DTMF_DURATION:
+               newintval = switch_core_default_dtmf_duration(oldintval);
+               break;
+       case SCSC_SPS:
+               switch_mutex_lock(runtime.throttle_mutex);
+               if (oldintval > 0) {
+                       runtime.sps_total = oldintval;
+               }
+               newintval = runtime.sps_total;
+               switch_mutex_unlock(runtime.throttle_mutex);
+               break;
+
+       case SCSC_RECLAIM:
+               switch_core_memory_reclaim_all();
+               newintval = 0;
+               break;
+       }
+
+       if (intval) {
+               *intval = newintval;
+       }
+
+
+       return 0;
+}
+
+SWITCH_DECLARE(switch_core_flag_t) switch_core_flags(void)
+{
+       return runtime.flags;
+}
+
+SWITCH_DECLARE(switch_bool_t) switch_core_ready(void)
+{
+       return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS) ? SWITCH_FALSE : SWITCH_TRUE;
+}
+
+SWITCH_DECLARE(switch_bool_t) switch_core_ready_inbound(void)
+{
+       return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE;
+}
+
+SWITCH_DECLARE(switch_bool_t) switch_core_ready_outbound(void)
+{
+       return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_core_destroy(void)
+{
+       switch_event_t *event;
+
+       if (switch_event_create(&event, SWITCH_EVENT_SHUTDOWN) == SWITCH_STATUS_SUCCESS) {
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Shutting Down");
+               switch_event_fire(&event);
+       }
+
+       switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
+       switch_set_flag((&runtime), SCF_SHUTTING_DOWN);
+
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "End existing sessions\n");
+       switch_core_session_hupall(SWITCH_CAUSE_SYSTEM_SHUTDOWN);
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clean up modules.\n");
+
+       switch_loadable_module_shutdown();
+
+       switch_ssl_destroy_ssl_locks();
+
+       if (switch_test_flag((&runtime), SCF_USE_SQL)) {
+               switch_core_sqldb_stop();
+       }
+       switch_scheduler_task_thread_stop();
+
+       switch_rtp_shutdown();
+
+       if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) {
+               switch_nat_shutdown();
+       }
+       switch_xml_destroy();
+       switch_core_session_uninit();
+       switch_console_shutdown();
+
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Closing Event Engine.\n");
+       switch_event_shutdown();
+
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Finalizing Shutdown.\n");
+       switch_log_shutdown();
+
+       switch_core_unset_variables();
+       switch_core_memory_stop();
+
+       if (runtime.console && runtime.console != stdout && runtime.console != stderr) {
+               fclose(runtime.console);
+               runtime.console = NULL;
+       }
+
+       switch_safe_free(SWITCH_GLOBAL_dirs.base_dir);
+       switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir);
+       switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir);
+       switch_safe_free(SWITCH_GLOBAL_dirs.log_dir);
+       switch_safe_free(SWITCH_GLOBAL_dirs.db_dir);
+       switch_safe_free(SWITCH_GLOBAL_dirs.script_dir);
+       switch_safe_free(SWITCH_GLOBAL_dirs.htdocs_dir);
+       switch_safe_free(SWITCH_GLOBAL_dirs.grammar_dir);
+       switch_safe_free(SWITCH_GLOBAL_dirs.storage_dir);
+       switch_safe_free(SWITCH_GLOBAL_dirs.recordings_dir);
+       switch_safe_free(SWITCH_GLOBAL_dirs.sounds_dir);
+       switch_safe_free(SWITCH_GLOBAL_dirs.run_dir);
+       switch_safe_free(SWITCH_GLOBAL_dirs.temp_dir);
+
+       switch_event_destroy(&runtime.global_vars);
+       switch_core_hash_destroy(&runtime.ptimes);
+       switch_core_hash_destroy(&runtime.mime_types);
+
+       if (IP_LIST.hash) {
+               switch_core_hash_destroy(&IP_LIST.hash);
+       }
+
+       if (IP_LIST.pool) {
+               switch_core_destroy_memory_pool(&IP_LIST.pool);
+       }
+
+       if (runtime.memory_pool) {
+               apr_pool_destroy(runtime.memory_pool);
+               apr_terminate();
+       }
+
+       return switch_test_flag((&runtime), SCF_RESTART) ? SWITCH_STATUS_RESTART : SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_core_management_exec(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen)
+{
+       const switch_management_interface_t *ptr;
+       switch_status_t status = SWITCH_STATUS_FALSE;
+
+       if ((ptr = switch_loadable_module_get_management_interface(relative_oid))) {
+               status = ptr->management_function(relative_oid, action, data, datalen);
+       }
+
+       return status;
+}
+
+SWITCH_DECLARE(void) switch_core_memory_reclaim_all(void)
+{
+       switch_core_memory_reclaim_logger();
+       switch_core_memory_reclaim_events();
+       switch_core_memory_reclaim();
+}
+
+
+struct system_thread_handle {
+       const char *cmd;
+       switch_thread_cond_t *cond;
+       switch_mutex_t *mutex;
+       switch_memory_pool_t *pool;
+       int ret;
+       int *fds;
+};
+
+static void *SWITCH_THREAD_FUNC system_thread(switch_thread_t *thread, void *obj)
+{
+       struct system_thread_handle *sth = (struct system_thread_handle *) obj;
+
+#if 0                                                  // if we are a luser we can never turn this back down, didn't we already set the stack size?
+#if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__)
+       struct rlimit rlim;
+
+       rlim.rlim_cur = SWITCH_SYSTEM_THREAD_STACKSIZE;
+       rlim.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE;
+       if (setrlimit(RLIMIT_STACK, &rlim) < 0) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno));
+       }
+#endif
+#endif
+
+       if (sth->fds) {
+               dup2(sth->fds[1], STDOUT_FILENO);
+       }
+
+       sth->ret = system(sth->cmd);
+
+#if 0
+#if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__)
+       rlim.rlim_cur = SWITCH_THREAD_STACKSIZE;
+       rlim.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE;
+       if (setrlimit(RLIMIT_STACK, &rlim) < 0) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno));
+       }
+#endif
+#endif
+
+       switch_mutex_lock(sth->mutex);
+       switch_thread_cond_signal(sth->cond);
+       switch_mutex_unlock(sth->mutex);
+
+       switch_core_destroy_memory_pool(&sth->pool);
+
+       return NULL;
+}
+
+
+static int switch_system_thread(const char *cmd, switch_bool_t wait)
+{
+       switch_thread_t *thread;
+       switch_threadattr_t *thd_attr;
+       int ret = 0;
+       struct system_thread_handle *sth;
+       switch_memory_pool_t *pool;
+
+       if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n");
+               return 1;
+       }
+
+       if (!(sth = switch_core_alloc(pool, sizeof(struct system_thread_handle)))) {
+               switch_core_destroy_memory_pool(&pool);
+               return 1;
+       }
+
+       sth->pool = pool;
+       sth->cmd = switch_core_strdup(pool, cmd);
+
+       switch_thread_cond_create(&sth->cond, sth->pool);
+       switch_mutex_init(&sth->mutex, SWITCH_MUTEX_NESTED, sth->pool);
+       switch_mutex_lock(sth->mutex);
+
+       switch_threadattr_create(&thd_attr, sth->pool);
+       switch_threadattr_stacksize_set(thd_attr, SWITCH_SYSTEM_THREAD_STACKSIZE);
+       switch_threadattr_detach_set(thd_attr, 1);
+       switch_thread_create(&thread, thd_attr, system_thread, sth, sth->pool);
+
+       if (wait) {
+               switch_thread_cond_wait(sth->cond, sth->mutex);
+               ret = sth->ret;
+       }
+       switch_mutex_unlock(sth->mutex);
+
+       return ret;
+}
+
+SWITCH_DECLARE(int) switch_max_file_desc(void)
+{
+       int max = 0;
+
+#ifndef WIN32
+#if defined(HAVE_GETDTABLESIZE)
+       max = getdtablesize();
+#else
+       max = sysconf(_SC_OPEN_MAX);
+#endif
+#endif
+
+       return max;
+
+}
+
+SWITCH_DECLARE(void) switch_close_extra_files(int *keep, int keep_ttl)
+{
+       int open_max = switch_max_file_desc();
+       int i, j;
+
+       for (i = 3; i < open_max; i++) {
+               if (keep) {
+                       for (j = 0; j < keep_ttl; j++) {
+                               if (i == keep[j]) {
+                                       goto skip;
+                               }
+                       }
+               }
+
+               close(i);
+
+       skip:
+
+               continue;
+
+       }
+}
+
+
+#ifdef WIN32
+static int switch_system_fork(const char *cmd, switch_bool_t wait)
+{
+       return switch_system_thread(cmd, wait);
+}
+
+SWITCH_DECLARE(pid_t) switch_fork(void)
+{
+       return -1;
+}
+
+
+#else
+
+SWITCH_DECLARE(pid_t) switch_fork(void)
+{
+       int i = fork();
+
+       if (!i) {
+               set_low_priority();
+       }
+
+       return i;
+}
+
+
+
+static int switch_system_fork(const char *cmd, switch_bool_t wait)
+{
+       int pid;
+       char *dcmd = strdup(cmd);
+
+       switch_core_set_signal_handlers();
+
+       pid = switch_fork();
+       
+       if (pid) {
+               if (wait) {
+                       waitpid(pid, NULL, 0);
+               }
+               free(dcmd);
+       } else {
+               switch_close_extra_files(NULL, 0);
+               
+               if (system(dcmd) == -1) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to execute because of a command error : %s\n", dcmd);
+               }
+               free(dcmd);
+               exit(0);
+       }
+
+       return 0;
+}
+#endif
+
+
+
+SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait)
+{
+       int (*sys_p)(const char *cmd, switch_bool_t wait);
+
+       sys_p = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC) ? switch_system_thread : switch_system_fork;
+
+       return sys_p(cmd, wait);
+
+}
+
+
+
+SWITCH_DECLARE(int) switch_stream_system_fork(const char *cmd, switch_stream_handle_t *stream)
+{
+#ifdef WIN32
+       return switch_system(cmd, SWITCH_TRUE);
+#else
+       int fds[2], pid = 0;
+
+       if (pipe(fds)) {
+               goto end;
+       } else {                                        /* good to go */
+               pid = switch_fork();
+
+               if (pid < 0) {                  /* ok maybe not */
+                       close(fds[0]);
+                       close(fds[1]);
+                       goto end;
+               } else if (pid) {               /* parent */
+                       char buf[1024] = "";
+                       int bytes;
+                       close(fds[1]);
+                       while ((bytes = read(fds[0], buf, sizeof(buf))) > 0) {
+                               stream->raw_write_function(stream, (unsigned char *)buf, bytes);
+                       }
+                       close(fds[0]);
+                       waitpid(pid, NULL, 0);
+               } else {                                /*  child */
+                       switch_close_extra_files(fds, 2);
+                       close(fds[0]);
+                       dup2(fds[1], STDOUT_FILENO);
+                       switch_system(cmd, SWITCH_TRUE);
+                       close(fds[1]);
+                       exit(0);
+               }
+       }
+
+ end:
+
+       return 0;
+
+#endif
+
+}
+
+SWITCH_DECLARE(switch_status_t) switch_core_get_stacksizes(switch_size_t *cur, switch_size_t *max)
+{
+#ifdef HAVE_SETRLIMIT
+       struct rlimit rlp;
+
+       memset(&rlp, 0, sizeof(rlp));
+       getrlimit(RLIMIT_STACK, &rlp);
+
+       *cur = rlp.rlim_cur;
+       *max = rlp.rlim_max;
+
+       return SWITCH_STATUS_SUCCESS;
+
+#else
+
+       return SWITCH_STATUS_FALSE;
+
+#endif
+
+
+
+}
+
+
+SWITCH_DECLARE(int) switch_stream_system(const char *cmd, switch_stream_handle_t *stream)
+{
+#ifdef WIN32
+       stream->write_function(stream, "Capturing output not supported.\n");
+       return switch_system(cmd, SWITCH_TRUE);
+#else
+       return switch_stream_system_fork(cmd, stream);
+#endif
+
+}
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */