Bug Summary

File:src/switch_core.c
Location:line 261, column 8
Description:Value stored to 'handle' during its initialization is never read

Annotated Source Code

1
2/*
3 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
4 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
5 *
6 * Version: MPL 1.1
7 *
8 * The contents of this file are subject to the Mozilla Public License Version
9 * 1.1 (the "License"); you may not use this file except in compliance with
10 * the License. You may obtain a copy of the License at
11 * http://www.mozilla.org/MPL/
12 *
13 * Software distributed under the License is distributed on an "AS IS" basis,
14 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
15 * for the specific language governing rights and limitations under the
16 * License.
17 *
18 * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
19 *
20 * The Initial Developer of the Original Code is
21 * Anthony Minessale II <anthm@freeswitch.org>
22 * Portions created by the Initial Developer are Copyright (C)
23 * the Initial Developer. All Rights Reserved.
24 *
25 * Contributor(s):
26 *
27 * Anthony Minessale II <anthm@freeswitch.org>
28 * Michael Jerris <mike@jerris.com>
29 * Paul D. Tinsley <pdt at jackhammer.org>
30 * Marcel Barbulescu <marcelbarbulescu@gmail.com>
31 * Joseph Sullivan <jossulli@amazon.com>
32 * Seven Du <dujinfang@gmail.com>
33 *
34 * switch_core.c -- Main Core Library
35 *
36 */
37
38
39
40#include <switch.h>
41#include <switch_ssl.h>
42#include <switch_stun.h>
43#include <switch_nat.h>
44#include "private/switch_core_pvt.h"
45#include <switch_curl.h>
46#ifndef WIN32
47#include <switch_private.h>
48#ifdef HAVE_SETRLIMIT1
49#include <sys/resource.h>
50#endif
51#endif
52#include <errno(*__errno_location ()).h>
53#include <sqlite3.h>
54
55
56SWITCH_DECLARE_DATA__attribute__((visibility("default"))) switch_directories SWITCH_GLOBAL_dirs = { 0 };
57SWITCH_DECLARE_DATA__attribute__((visibility("default"))) switch_filenames SWITCH_GLOBAL_filenames = { 0 };
58
59/* The main runtime obj we keep this hidden for ourselves */
60struct switch_runtime runtime = { 0 };
61static void switch_load_core_config(const char *file);
62
63static void send_heartbeat(void)
64{
65 switch_event_t *event;
66 switch_core_time_duration_t duration;
67
68 switch_core_measure_time(switch_core_uptime(), &duration);
69
70 if (switch_event_create(&event, SWITCH_EVENT_HEARTBEAT)switch_event_create_subclass_detailed("src/switch_core.c", (const
char * )(const char *)__func__, 70, &event, SWITCH_EVENT_HEARTBEAT
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
71 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready");
72 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Up-Time",
73 "%u year%s, "
74 "%u day%s, "
75 "%u hour%s, "
76 "%u minute%s, "
77 "%u second%s, "
78 "%u millisecond%s, "
79 "%u microsecond%s",
80 duration.yr, duration.yr == 1 ? "" : "s",
81 duration.day, duration.day == 1 ? "" : "s",
82 duration.hr, duration.hr == 1 ? "" : "s",
83 duration.min, duration.min == 1 ? "" : "s",
84 duration.sec, duration.sec == 1 ? "" : "s",
85 duration.ms, duration.ms == 1 ? "" : "s", duration.mms, duration.mms == 1 ? "" : "s");
86
87 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FreeSWITCH-Version", "%s", switch_version_full());
88 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Uptime-msec", "%"SWITCH_TIME_T_FMT"ld", switch_core_uptime() / 1000);
89 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Count", "%u", switch_core_session_count());
90 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Max-Sessions", "%u", switch_core_session_limit(0));
91 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec", "%u", runtime.sps);
92 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec-Max", "%u", runtime.sps_peak);
93 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec-FiveMin", "%u", runtime.sps_peak_fivemin);
94 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Since-Startup", "%" SWITCH_SIZE_T_FMT"ld", switch_core_session_id() - 1);
95 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Peak-Max", "%u", runtime.sessions_peak);
96 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Peak-FiveMin", "%u", runtime.sessions_peak_fivemin);
97 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Idle-CPU", "%f", switch_core_idle_cpu());
98 switch_event_fire(&event)switch_event_fire_detailed("src/switch_core.c", (const char *
)(const char *)__func__, 98, &event, ((void*)0))
;
99 }
100}
101
102static char main_ip4[256] = "";
103static char main_ip6[256] = "";
104
105static void check_ip(void)
106{
107 char guess_ip4[256] = "";
108 char guess_ip6[256] = "";
109 char old_ip4[256] = "";
110 char old_ip6[256] = "";
111 int ok4 = 1, ok6 = 1;
112 int mask = 0;
113 switch_status_t check6, check4;
114 switch_event_t *event;
115 char *hostname = switch_core_get_variable("hostname");
116
117 gethostname(runtime.hostname, sizeof(runtime.hostname));
118
119 if (zstr(hostname)_zstr(hostname)) {
120 switch_core_set_variable("hostname", runtime.hostname);
121 } else if (strcmp(hostname, runtime.hostname)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(hostname) && __builtin_constant_p (runtime.hostname
) && (__s1_len = __builtin_strlen (hostname), __s2_len
= __builtin_strlen (runtime.hostname), (!((size_t)(const void
*)((hostname) + 1) - (size_t)(const void *)(hostname) == 1) ||
__s1_len >= 4) && (!((size_t)(const void *)((runtime
.hostname) + 1) - (size_t)(const void *)(runtime.hostname) ==
1) || __s2_len >= 4)) ? __builtin_strcmp (hostname, runtime
.hostname) : (__builtin_constant_p (hostname) && ((size_t
)(const void *)((hostname) + 1) - (size_t)(const void *)(hostname
) == 1) && (__s1_len = __builtin_strlen (hostname), __s1_len
< 4) ? (__builtin_constant_p (runtime.hostname) &&
((size_t)(const void *)((runtime.hostname) + 1) - (size_t)(const
void *)(runtime.hostname) == 1) ? __builtin_strcmp (hostname
, runtime.hostname) : (__extension__ ({ const unsigned char *
__s2 = (const unsigned char *) (const char *) (runtime.hostname
); int __result = (((const unsigned char *) (const char *) (hostname
))[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (hostname
))[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (hostname
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (hostname
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
runtime.hostname) && ((size_t)(const void *)((runtime
.hostname) + 1) - (size_t)(const void *)(runtime.hostname) ==
1) && (__s2_len = __builtin_strlen (runtime.hostname
), __s2_len < 4) ? (__builtin_constant_p (hostname) &&
((size_t)(const void *)((hostname) + 1) - (size_t)(const void
*)(hostname) == 1) ? __builtin_strcmp (hostname, runtime.hostname
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (hostname); int __result = (((const unsigned
char *) (const char *) (runtime.hostname))[0] - __s2[0]); if
(__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) (runtime.hostname))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (runtime.hostname
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (runtime
.hostname))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(hostname, runtime.hostname)))); })
) {
122 if (switch_event_create(&event, SWITCH_EVENT_TRAP)switch_event_create_subclass_detailed("src/switch_core.c", (const
char * )(const char *)__func__, 122, &event, SWITCH_EVENT_TRAP
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
123 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "hostname-change");
124 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "old-hostname", hostname ? hostname : "nil");
125 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "new-hostname", runtime.hostname);
126 switch_event_fire(&event)switch_event_fire_detailed("src/switch_core.c", (const char *
)(const char *)__func__, 126, &event, ((void*)0))
;
127 }
128
129 switch_core_set_variable("hostname", runtime.hostname);
130 }
131
132 check4 = switch_find_local_ip(guess_ip4, sizeof(guess_ip4), &mask, AF_INET2);
133 check6 = switch_find_local_ip(guess_ip6, sizeof(guess_ip6), NULL((void*)0), AF_INET610);
134
135 if (check6 != SWITCH_STATUS_SUCCESS && (zstr(main_ip6)_zstr(main_ip6) || !strcasecmp(main_ip6, "::1"))) {
136 check6 = SWITCH_STATUS_SUCCESS;
137 }
138
139 if (check4 != SWITCH_STATUS_SUCCESS) {
140 ok4 = 2;
141 } else if (!*main_ip4) {
142 switch_set_string(main_ip4, guess_ip4)switch_copy_string(main_ip4, guess_ip4, sizeof(main_ip4));
143 } else {
144 if (!(ok4 = !strcmp(main_ip4, guess_ip4)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(main_ip4) && __builtin_constant_p (guess_ip4) &&
(__s1_len = __builtin_strlen (main_ip4), __s2_len = __builtin_strlen
(guess_ip4), (!((size_t)(const void *)((main_ip4) + 1) - (size_t
)(const void *)(main_ip4) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((guess_ip4) + 1) - (size_t)(const void
*)(guess_ip4) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(main_ip4, guess_ip4) : (__builtin_constant_p (main_ip4) &&
((size_t)(const void *)((main_ip4) + 1) - (size_t)(const void
*)(main_ip4) == 1) && (__s1_len = __builtin_strlen (
main_ip4), __s1_len < 4) ? (__builtin_constant_p (guess_ip4
) && ((size_t)(const void *)((guess_ip4) + 1) - (size_t
)(const void *)(guess_ip4) == 1) ? __builtin_strcmp (main_ip4
, guess_ip4) : (__extension__ ({ const unsigned char *__s2 = (
const unsigned char *) (const char *) (guess_ip4); int __result
= (((const unsigned char *) (const char *) (main_ip4))[0] - __s2
[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (main_ip4))[1] - __s2
[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (main_ip4))[2] - __s2
[2]); if (__s1_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (main_ip4))[3] - __s2
[3]); } } __result; }))) : (__builtin_constant_p (guess_ip4) &&
((size_t)(const void *)((guess_ip4) + 1) - (size_t)(const void
*)(guess_ip4) == 1) && (__s2_len = __builtin_strlen (
guess_ip4), __s2_len < 4) ? (__builtin_constant_p (main_ip4
) && ((size_t)(const void *)((main_ip4) + 1) - (size_t
)(const void *)(main_ip4) == 1) ? __builtin_strcmp (main_ip4,
guess_ip4) : (- (__extension__ ({ const unsigned char *__s2 =
(const unsigned char *) (const char *) (main_ip4); int __result
= (((const unsigned char *) (const char *) (guess_ip4))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (guess_ip4))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (guess_ip4))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (guess_ip4))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (main_ip4, guess_ip4
)))); })
)) {
145 struct in_addr in;
146
147 in.s_addr = mask;
148 switch_set_string(old_ip4, main_ip4)switch_copy_string(old_ip4, main_ip4, sizeof(old_ip4));
149 switch_set_string(main_ip4, guess_ip4)switch_copy_string(main_ip4, guess_ip4, sizeof(main_ip4));
150 switch_core_set_variable("local_ip_v4", guess_ip4);
151 switch_core_set_variable("local_mask_v4", inet_ntoa(in));
152 }
153 }
154
155 if (check6 != SWITCH_STATUS_SUCCESS) {
156 ok6 = 2;
157 } else if (!*main_ip6) {
158 switch_set_string(main_ip6, guess_ip6)switch_copy_string(main_ip6, guess_ip6, sizeof(main_ip6));
159 } else {
160 if (!(ok6 = !strcmp(main_ip6, guess_ip6)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(main_ip6) && __builtin_constant_p (guess_ip6) &&
(__s1_len = __builtin_strlen (main_ip6), __s2_len = __builtin_strlen
(guess_ip6), (!((size_t)(const void *)((main_ip6) + 1) - (size_t
)(const void *)(main_ip6) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((guess_ip6) + 1) - (size_t)(const void
*)(guess_ip6) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(main_ip6, guess_ip6) : (__builtin_constant_p (main_ip6) &&
((size_t)(const void *)((main_ip6) + 1) - (size_t)(const void
*)(main_ip6) == 1) && (__s1_len = __builtin_strlen (
main_ip6), __s1_len < 4) ? (__builtin_constant_p (guess_ip6
) && ((size_t)(const void *)((guess_ip6) + 1) - (size_t
)(const void *)(guess_ip6) == 1) ? __builtin_strcmp (main_ip6
, guess_ip6) : (__extension__ ({ const unsigned char *__s2 = (
const unsigned char *) (const char *) (guess_ip6); int __result
= (((const unsigned char *) (const char *) (main_ip6))[0] - __s2
[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (main_ip6))[1] - __s2
[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (main_ip6))[2] - __s2
[2]); if (__s1_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (main_ip6))[3] - __s2
[3]); } } __result; }))) : (__builtin_constant_p (guess_ip6) &&
((size_t)(const void *)((guess_ip6) + 1) - (size_t)(const void
*)(guess_ip6) == 1) && (__s2_len = __builtin_strlen (
guess_ip6), __s2_len < 4) ? (__builtin_constant_p (main_ip6
) && ((size_t)(const void *)((main_ip6) + 1) - (size_t
)(const void *)(main_ip6) == 1) ? __builtin_strcmp (main_ip6,
guess_ip6) : (- (__extension__ ({ const unsigned char *__s2 =
(const unsigned char *) (const char *) (main_ip6); int __result
= (((const unsigned char *) (const char *) (guess_ip6))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (guess_ip6))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (guess_ip6))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (guess_ip6))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (main_ip6, guess_ip6
)))); })
)) {
161 switch_set_string(old_ip6, main_ip6)switch_copy_string(old_ip6, main_ip6, sizeof(old_ip6));
162 switch_set_string(main_ip6, guess_ip6)switch_copy_string(main_ip6, guess_ip6, sizeof(main_ip6));
163 switch_core_set_variable("local_ip_v6", guess_ip6);
164 }
165 }
166
167 if (!ok4 || !ok6) {
168 if (switch_event_create(&event, SWITCH_EVENT_TRAP)switch_event_create_subclass_detailed("src/switch_core.c", (const
char * )(const char *)__func__, 168, &event, SWITCH_EVENT_TRAP
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
169 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "network-address-change");
170 if (!ok4) {
171 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v4", old_ip4);
172 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v4", main_ip4);
173 }
174 if (!ok6) {
175 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v6", old_ip6);
176 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v6", main_ip6);
177 }
178 switch_event_fire(&event)switch_event_fire_detailed("src/switch_core.c", (const char *
)(const char *)__func__, 178, &event, ((void*)0))
;
179 }
180 }
181
182 if (ok4 == 2 || ok6 == 2) {
183 if (switch_event_create(&event, SWITCH_EVENT_TRAP)switch_event_create_subclass_detailed("src/switch_core.c", (const
char * )(const char *)__func__, 183, &event, SWITCH_EVENT_TRAP
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
184 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "network-outage");
185
186 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-status-v4", ok4 == 2 ? "disconnected" : "active");
187 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-v4", main_ip4);
188
189 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-status-v6", ok6 == 2 ? "disconnected" : "active");
190 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-v6", main_ip6);
191
192 switch_event_fire(&event)switch_event_fire_detailed("src/switch_core.c", (const char *
)(const char *)__func__, 192, &event, ((void*)0))
;
193 }
194 }
195
196}
197
198SWITCH_STANDARD_SCHED_FUNC(heartbeat_callback)static void heartbeat_callback (switch_scheduler_task_t *task
)
199{
200 send_heartbeat();
201
202 /* reschedule this task */
203 task->runtime = switch_epoch_time_now(NULL((void*)0)) + 20;
204}
205
206
207SWITCH_STANDARD_SCHED_FUNC(check_ip_callback)static void check_ip_callback (switch_scheduler_task_t *task)
208{
209 check_ip();
210
211 /* reschedule this task */
212 task->runtime = switch_epoch_time_now(NULL((void*)0)) + 60;
213}
214
215
216SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_set_console(const char *console)
217{
218 if ((runtime.console = fopen(console, "a")) == 0) {
219 fprintf(stderrstderr, "Cannot open output file %s.\n", console);
220 return SWITCH_STATUS_FALSE;
221 }
222
223 return SWITCH_STATUS_SUCCESS;
224}
225
226SWITCH_DECLARE(FILE *)__attribute__((visibility("default"))) FILE * switch_core_get_console(void)
227{
228 return runtime.console;
229}
230
231#ifdef HAVE_SYS_IOCTL_H1
232#include <sys/ioctl.h>
233#endif
234SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_screen_size(int *x, int *y)
235{
236
237#ifdef WIN32
238 CONSOLE_SCREEN_BUFFER_INFO csbi;
239 int ret;
240
241 if ((ret = GetConsoleScreenBufferInfo(GetStdHandle( STD_OUTPUT_HANDLE ), &csbi))) {
242 if (x) *x = csbi.dwSize.X;
243 if (y) *y = csbi.dwSize.Y;
244 }
245
246#elif defined(TIOCGWINSZ0x5413)
247 struct winsize w;
248 ioctl(0, TIOCGWINSZ0x5413, &w);
249
250 if (x) *x = w.ws_col;
251 if (y) *y = w.ws_row;
252#else
253 if (x) *x = 80;
254 if (y) *y = 24;
255#endif
256
257}
258
259SWITCH_DECLARE(FILE *)__attribute__((visibility("default"))) FILE * switch_core_data_channel(switch_text_channel_t channel)
260{
261 FILE *handle = stdoutstdout;
Value stored to 'handle' during its initialization is never read
262
263 switch (channel) {
264 case SWITCH_CHANNEL_ID_LOG:
265 case SWITCH_CHANNEL_ID_LOG_CLEAN:
266 handle = runtime.console;
267 break;
268 default:
269 handle = runtime.console;
270 break;
271 }
272
273 return handle;
274}
275
276
277SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_remove_state_handler(const switch_state_handler_table_t *state_handler)
278{
279 int index, tmp_index = 0;
280 const switch_state_handler_table_t *tmp[SWITCH_MAX_STATE_HANDLERS30 + 1] = { 0 };
281
282 switch_mutex_lock(runtime.global_mutex);
283
284 for (index = 0; index < runtime.state_handler_index; index++) {
285 const switch_state_handler_table_t *cur = runtime.state_handlers[index];
286 runtime.state_handlers[index] = NULL((void*)0);
287 if (cur == state_handler) {
288 continue;
289 }
290 tmp[tmp_index++] = cur;
291 }
292
293 runtime.state_handler_index = 0;
294
295 for (index = 0; index < tmp_index; index++) {
296 runtime.state_handlers[runtime.state_handler_index++] = tmp[index];
297 }
298 switch_mutex_unlock(runtime.global_mutex);
299}
300
301
302SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_core_add_state_handler(const switch_state_handler_table_t *state_handler)
303{
304 int index;
305
306 switch_mutex_lock(runtime.global_mutex);
307 index = runtime.state_handler_index++;
308
309 if (runtime.state_handler_index >= SWITCH_MAX_STATE_HANDLERS30) {
310 index = -1;
311 } else {
312 runtime.state_handlers[index] = state_handler;
313 }
314
315 switch_mutex_unlock(runtime.global_mutex);
316 return index;
317}
318
319SWITCH_DECLARE(const switch_state_handler_table_t *)__attribute__((visibility("default"))) const switch_state_handler_table_t
*
switch_core_get_state_handler(int index)
320{
321
322 if (index >= SWITCH_MAX_STATE_HANDLERS30 || index > runtime.state_handler_index) {
323 return NULL((void*)0);
324 }
325
326 return runtime.state_handlers[index];
327}
328
329SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_dump_variables(switch_stream_handle_t *stream)
330{
331 switch_event_header_t *hi;
332
333 switch_mutex_lock(runtime.global_mutex);
334 for (hi = runtime.global_vars->headers; hi; hi = hi->next) {
335 stream->write_function(stream, "%s=%s\n", hi->name, hi->value);
336 }
337 switch_mutex_unlock(runtime.global_mutex);
338}
339
340SWITCH_DECLARE(const char *)__attribute__((visibility("default"))) const char * switch_core_get_hostname(void)
341{
342 return runtime.hostname;
343}
344
345SWITCH_DECLARE(const char *)__attribute__((visibility("default"))) const char * switch_core_get_switchname(void)
346{
347 if (!zstr(runtime.switchname)_zstr(runtime.switchname)) return runtime.switchname;
348 return runtime.hostname;
349}
350
351SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_core_get_domain(switch_bool_t dup)
352{
353 char *domain;
354 const char *var;
355
356 switch_thread_rwlock_rdlock(runtime.global_var_rwlock);
357 if (!(var = switch_core_get_variable("domain"))) {
358 var = "freeswitch.local";
359 }
360 if (dup) {
361 domain = strdup(var)(__extension__ (__builtin_constant_p (var) && ((size_t
)(const void *)((var) + 1) - (size_t)(const void *)(var) == 1
) ? (((const char *) (var))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (var) + 1; char *
__retval = (char *) malloc (__len); if (__retval != ((void*)0
)) __retval = (char *) memcpy (__retval, var, __len); __retval
; })) : __strdup (var)))
;
362 } else {
363 domain = (char *) var;
364 }
365 switch_thread_rwlock_unlock(runtime.global_var_rwlock);
366
367 return domain;
368}
369
370SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_get_variables(switch_event_t **event)
371{
372 switch_status_t status;
373 switch_thread_rwlock_rdlock(runtime.global_var_rwlock);
374 status = switch_event_dup(event, runtime.global_vars);
375 switch_thread_rwlock_unlock(runtime.global_var_rwlock);
376 return status;
377}
378
379SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_core_get_variable(const char *varname)
380{
381 char *val;
382 switch_thread_rwlock_rdlock(runtime.global_var_rwlock);
383 val = (char *) switch_event_get_header(runtime.global_vars, varname)switch_event_get_header_idx(runtime.global_vars, varname, -1);
384 switch_thread_rwlock_unlock(runtime.global_var_rwlock);
385 return val;
386}
387
388SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_core_get_variable_dup(const char *varname)
389{
390 char *val = NULL((void*)0), *v;
391
392 switch_thread_rwlock_rdlock(runtime.global_var_rwlock);
393 if ((v = (char *) switch_event_get_header(runtime.global_vars, varname)switch_event_get_header_idx(runtime.global_vars, varname, -1))) {
394 val = strdup(v)(__extension__ (__builtin_constant_p (v) && ((size_t)
(const void *)((v) + 1) - (size_t)(const void *)(v) == 1) ? (
((const char *) (v))[0] == '\0' ? (char *) calloc ((size_t) 1
, (size_t) 1) : ({ size_t __len = strlen (v) + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, v, __len); __retval; })) : __strdup
(v)))
;
395 }
396 switch_thread_rwlock_unlock(runtime.global_var_rwlock);
397
398 return val;
399}
400
401SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_core_get_variable_pdup(const char *varname, switch_memory_pool_t *pool)
402{
403 char *val = NULL((void*)0), *v;
404
405 switch_thread_rwlock_rdlock(runtime.global_var_rwlock);
406 if ((v = (char *) switch_event_get_header(runtime.global_vars, varname)switch_event_get_header_idx(runtime.global_vars, varname, -1))) {
407 val = switch_core_strdup(pool, v)switch_core_perform_strdup(pool, v, "src/switch_core.c", (const
char *)__func__, 407)
;
408 }
409 switch_thread_rwlock_unlock(runtime.global_var_rwlock);
410
411 return val;
412}
413
414static void switch_core_unset_variables(void)
415{
416 switch_thread_rwlock_wrlock(runtime.global_var_rwlock);
417 switch_event_destroy(&runtime.global_vars);
418 switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA);
419 switch_thread_rwlock_unlock(runtime.global_var_rwlock);
420}
421
422SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_set_variable(const char *varname, const char *value)
423{
424 char *val;
425
426 if (varname) {
427 switch_thread_rwlock_wrlock(runtime.global_var_rwlock);
428 val = (char *) switch_event_get_header(runtime.global_vars, varname)switch_event_get_header_idx(runtime.global_vars, varname, -1);
429 if (val) {
430 switch_event_del_header(runtime.global_vars, varname)switch_event_del_header_val(runtime.global_vars, varname, ((void
*)0))
;
431 }
432 if (value) {
433 char *v = strdup(value)(__extension__ (__builtin_constant_p (value) && ((size_t
)(const void *)((value) + 1) - (size_t)(const void *)(value) ==
1) ? (((const char *) (value))[0] == '\0' ? (char *) calloc (
(size_t) 1, (size_t) 1) : ({ size_t __len = strlen (value) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, value, __len
); __retval; })) : __strdup (value)))
;
434 switch_string_var_check(v, SWITCH_TRUE);
435 switch_event_add_header_string(runtime.global_vars, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, varname, v);
436 } else {
437 switch_event_del_header(runtime.global_vars, varname)switch_event_del_header_val(runtime.global_vars, varname, ((void
*)0))
;
438 }
439 switch_thread_rwlock_unlock(runtime.global_var_rwlock);
440 }
441}
442
443SWITCH_DECLARE(switch_bool_t)__attribute__((visibility("default"))) switch_bool_t switch_core_set_var_conditional(const char *varname, const char *value, const char *val2)
444{
445 char *val;
446
447 if (varname) {
448 switch_thread_rwlock_wrlock(runtime.global_var_rwlock);
449 val = (char *) switch_event_get_header(runtime.global_vars, varname)switch_event_get_header_idx(runtime.global_vars, varname, -1);
450
451 if (val) {
452 if (!val2 || strcmp(val, val2)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(val) && __builtin_constant_p (val2) && (__s1_len
= __builtin_strlen (val), __s2_len = __builtin_strlen (val2)
, (!((size_t)(const void *)((val) + 1) - (size_t)(const void *
)(val) == 1) || __s1_len >= 4) && (!((size_t)(const
void *)((val2) + 1) - (size_t)(const void *)(val2) == 1) || __s2_len
>= 4)) ? __builtin_strcmp (val, val2) : (__builtin_constant_p
(val) && ((size_t)(const void *)((val) + 1) - (size_t
)(const void *)(val) == 1) && (__s1_len = __builtin_strlen
(val), __s1_len < 4) ? (__builtin_constant_p (val2) &&
((size_t)(const void *)((val2) + 1) - (size_t)(const void *)
(val2) == 1) ? __builtin_strcmp (val, val2) : (__extension__ (
{ const unsigned char *__s2 = (const unsigned char *) (const char
*) (val2); int __result = (((const unsigned char *) (const char
*) (val))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
val))[1] - __s2[1]); if (__s1_len > 1 && __result ==
0) { __result = (((const unsigned char *) (const char *) (val
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (val))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (val2
) && ((size_t)(const void *)((val2) + 1) - (size_t)(const
void *)(val2) == 1) && (__s2_len = __builtin_strlen (
val2), __s2_len < 4) ? (__builtin_constant_p (val) &&
((size_t)(const void *)((val) + 1) - (size_t)(const void *)(
val) == 1) ? __builtin_strcmp (val, val2) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (val); int __result = (((const unsigned char *) (const
char *) (val2))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (val2))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (val2))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (val2))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(val, val2)))); })
!= 0) {
453 switch_thread_rwlock_unlock(runtime.global_var_rwlock);
454 return SWITCH_FALSE;
455 }
456 switch_event_del_header(runtime.global_vars, varname)switch_event_del_header_val(runtime.global_vars, varname, ((void
*)0))
;
457 } else if (!zstr(val2)_zstr(val2)) {
458 switch_thread_rwlock_unlock(runtime.global_var_rwlock);
459 return SWITCH_FALSE;
460 }
461
462 if (value) {
463 char *v = strdup(value)(__extension__ (__builtin_constant_p (value) && ((size_t
)(const void *)((value) + 1) - (size_t)(const void *)(value) ==
1) ? (((const char *) (value))[0] == '\0' ? (char *) calloc (
(size_t) 1, (size_t) 1) : ({ size_t __len = strlen (value) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, value, __len
); __retval; })) : __strdup (value)))
;
464 switch_string_var_check(v, SWITCH_TRUE);
465 switch_event_add_header_string(runtime.global_vars, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, varname, v);
466 } else {
467 switch_event_del_header(runtime.global_vars, varname)switch_event_del_header_val(runtime.global_vars, varname, ((void
*)0))
;
468 }
469 switch_thread_rwlock_unlock(runtime.global_var_rwlock);
470 }
471 return SWITCH_TRUE;
472}
473
474SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_core_get_uuid(void)
475{
476 return runtime.uuid_str;
477}
478
479
480static void *SWITCH_THREAD_FUNC switch_core_service_thread(switch_thread_t *thread, void *obj)
481{
482 switch_core_session_t *session = obj;
483 switch_channel_t *channel;
484 switch_frame_t *read_frame;
485
486// switch_assert(thread != NULL);
487// switch_assert(session != NULL);
488
489 if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
490 return NULL((void*)0);
491 }
492
493 switch_mutex_lock(session->frame_read_mutex);
494
495 channel = switch_core_session_get_channel(session);
496
497 switch_channel_set_flag(channel, CF_SERVICE)switch_channel_set_flag_value(channel, CF_SERVICE, 1);
498 while (switch_channel_test_flag(channel, CF_SERVICE)) {
499
500 if (switch_channel_test_flag(channel, CF_SERVICE_AUDIO)) {
501 switch (switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) {
502 case SWITCH_STATUS_SUCCESS:
503 case SWITCH_STATUS_TIMEOUT:
504 case SWITCH_STATUS_BREAK:
505 break;
506 default:
507 switch_channel_clear_flag(channel, CF_SERVICE);
508 break;
509 }
510 }
511
512 if (switch_channel_test_flag(channel, CF_SERVICE_VIDEO) && switch_channel_test_flag(channel, CF_VIDEO)) {
513 switch (switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) {
514 case SWITCH_STATUS_SUCCESS:
515 case SWITCH_STATUS_TIMEOUT:
516 case SWITCH_STATUS_BREAK:
517 break;
518 default:
519 switch_channel_clear_flag(channel, CF_SERVICE);
520 break;
521 }
522 }
523 }
524
525 switch_mutex_unlock(session->frame_read_mutex);
526
527 switch_channel_clear_flag(channel, CF_SERVICE_AUDIO);
528 switch_channel_clear_flag(channel, CF_SERVICE_VIDEO);
529
530 switch_core_session_rwunlock(session);
531
532 return NULL((void*)0);
533}
534
535/* Either add a timeout here or make damn sure the thread cannot get hung somehow (my preference) */
536SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_thread_session_end(switch_core_session_t *session)
537{
538 switch_channel_t *channel;
539 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core.c"
, 539, __PRETTY_FUNCTION__))
;
540
541 channel = switch_core_session_get_channel(session);
542 switch_assert(channel)((channel) ? (void) (0) : __assert_fail ("channel", "src/switch_core.c"
, 542, __PRETTY_FUNCTION__))
;
543
544 switch_channel_clear_flag(channel, CF_SERVICE);
545 switch_channel_clear_flag(channel, CF_SERVICE_AUDIO);
546 switch_channel_clear_flag(channel, CF_SERVICE_VIDEO);
547
548 switch_core_session_kill_channel(session, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(session, "src/switch_core.c"
, (const char *)__func__, 548, SWITCH_SIG_BREAK)
;
549
550}
551
552SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_service_session_av(switch_core_session_t *session, switch_bool_t audio, switch_bool_t video)
553{
554 switch_channel_t *channel;
555 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core.c"
, 555, __PRETTY_FUNCTION__))
;
556
557 channel = switch_core_session_get_channel(session);
558 switch_assert(channel)((channel) ? (void) (0) : __assert_fail ("channel", "src/switch_core.c"
, 558, __PRETTY_FUNCTION__))
;
559
560 if (audio) switch_channel_set_flag(channel, CF_SERVICE_AUDIO)switch_channel_set_flag_value(channel, CF_SERVICE_AUDIO, 1);
561 if (video) switch_channel_set_flag(channel, CF_SERVICE_VIDEO)switch_channel_set_flag_value(channel, CF_SERVICE_VIDEO, 1);
562
563 switch_core_session_launch_thread(session, (void *(*)(switch_thread_t *,void *))switch_core_service_thread, session);
564}
565
566/* This function abstracts the thread creation for modules by allowing you to pass a function ptr and
567 a void object and trust that that the function will be run in a thread with arg This lets
568 you request and activate a thread without giving up any knowledge about what is in the thread
569 neither the core nor the calling module know anything about each other.
570
571 This thread is expected to never exit until the application exits so the func is responsible
572 to make sure that is the case.
573
574 The typical use for this is so switch_loadable_module.c can start up a thread for each module
575 passing the table of module methods as a session obj into the core without actually allowing
576 the core to have any clue and keeping switch_loadable_module.c from needing any thread code.
577
578*/
579
580SWITCH_DECLARE(switch_thread_t *)__attribute__((visibility("default"))) switch_thread_t * switch_core_launch_thread(switch_thread_start_t func, void *obj, switch_memory_pool_t *pool)
581{
582 switch_thread_t *thread = NULL((void*)0);
583 switch_threadattr_t *thd_attr = NULL((void*)0);
584 switch_core_thread_session_t *ts;
585 int mypool;
586
587 mypool = pool ? 0 : 1;
588
589 if (!pool && switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_core.c"
, (const char *)__func__, 589)
!= SWITCH_STATUS_SUCCESS) {
590 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 590, ((void*)0)
, SWITCH_LOG_CRIT, "Could not allocate memory pool\n");
591 return NULL((void*)0);
592 }
593
594 switch_threadattr_create(&thd_attr, pool);
595
596 if ((ts = switch_core_alloc(pool, sizeof(*ts))switch_core_perform_alloc(pool, sizeof(*ts), "src/switch_core.c"
, (const char *)__func__, 596)
) == 0) {
597 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 597, ((void*)0)
, SWITCH_LOG_CRIT, "Could not allocate memory\n");
598 } else {
599 if (mypool) {
600 ts->pool = pool;
601 }
602 ts->objs[0] = obj;
603 ts->objs[1] = thread;
604 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
605 switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);
606 switch_thread_create(&thread, thd_attr, func, ts, pool);
607 }
608
609 return thread;
610}
611
612SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_set_globals(void)
613{
614#define BUFSIZE1024 1024
615#ifdef WIN32
616 char lpPathBuffer[BUFSIZE1024];
617 DWORD dwBufSize = BUFSIZE1024;
618 char base_dir[1024];
619 char *lastbacklash;
620 char *tmp;
621
622 GetModuleFileName(NULL((void*)0), base_dir, BUFSIZE1024);
623 lastbacklash = strrchr(base_dir, '\\');
624 base_dir[(lastbacklash - base_dir)] = '\0';
625 /* 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 */
626 SetCurrentDirectory(base_dir);
627 tmp = switch_string_replace(base_dir, "\\", "/");
628 strcpy(base_dir, tmp);
629 free(tmp);
630
631#else
632 char base_dir[1024] = SWITCH_PREFIX_DIR"/usr/local/freeswitch";
633#endif
634
635 /* Order of precedence for, eg, rundir:
636 * -run
637 * -base
638 * --with-rundir
639 * --prefix
640 */
641
642 if (!SWITCH_GLOBAL_dirs.mod_dir && (SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(BUFSIZE1024))) {
643 if (SWITCH_GLOBAL_dirs.base_dir)
644 switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE1024, "%s%smod", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR"/");
645 else
646#ifdef SWITCH_MOD_DIR"/usr/local/freeswitch/mod"
647 switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE1024, "%s", SWITCH_MOD_DIR"/usr/local/freeswitch/mod");
648#else
649 switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE1024, "%s%smod", base_dir, SWITCH_PATH_SEPARATOR"/");
650#endif
651 }
652
653 if (!SWITCH_GLOBAL_dirs.lib_dir && (SWITCH_GLOBAL_dirs.lib_dir = (char *) malloc(BUFSIZE1024))) {
654 if (SWITCH_GLOBAL_dirs.base_dir)
655 switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE1024, "%s%slib", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR"/");
656 else
657#ifdef SWITCH_LIB_DIR
658 switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE1024, "%s", SWITCH_LIB_DIR);
659#else
660 switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE1024, "%s%slib", base_dir, SWITCH_PATH_SEPARATOR"/");
661#endif
662 }
663
664 if (!SWITCH_GLOBAL_dirs.conf_dir && (SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(BUFSIZE1024))) {
665 if (SWITCH_GLOBAL_dirs.base_dir)
666 switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE1024, "%s%sconf", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR"/");
667 else
668#ifdef SWITCH_CONF_DIR"/usr/local/freeswitch/conf"
669 switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE1024, "%s", SWITCH_CONF_DIR"/usr/local/freeswitch/conf");
670#else
671 switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE1024, "%s%sconf", base_dir, SWITCH_PATH_SEPARATOR"/");
672#endif
673 }
674
675 if (!SWITCH_GLOBAL_dirs.log_dir && (SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(BUFSIZE1024))) {
676 if (SWITCH_GLOBAL_dirs.base_dir)
677 switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE1024, "%s%slog", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR"/");
678 else
679#ifdef SWITCH_LOG_DIR"/usr/local/freeswitch/log"
680 switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE1024, "%s", SWITCH_LOG_DIR"/usr/local/freeswitch/log");
681#else
682 switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE1024, "%s%slog", base_dir, SWITCH_PATH_SEPARATOR"/");
683#endif
684 }
685
686 if (!SWITCH_GLOBAL_dirs.run_dir && (SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(BUFSIZE1024))) {
687 if (SWITCH_GLOBAL_dirs.base_dir)
688 switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE1024, "%s%srun", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR"/");
689 else
690#ifdef SWITCH_RUN_DIR"/usr/local/freeswitch/run"
691 switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE1024, "%s", SWITCH_RUN_DIR"/usr/local/freeswitch/run");
692#else
693 switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE1024, "%s%srun", base_dir, SWITCH_PATH_SEPARATOR"/");
694#endif
695 }
696
697 if (!SWITCH_GLOBAL_dirs.recordings_dir && (SWITCH_GLOBAL_dirs.recordings_dir = (char *) malloc(BUFSIZE1024))) {
698 if (SWITCH_GLOBAL_dirs.base_dir)
699 switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE1024, "%s%srecordings", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR"/");
700 else
701#ifdef SWITCH_RECORDINGS_DIR"/usr/local/freeswitch/recordings"
702 switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE1024, "%s", SWITCH_RECORDINGS_DIR"/usr/local/freeswitch/recordings");
703#else
704 switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE1024, "%s%srecordings", base_dir, SWITCH_PATH_SEPARATOR"/");
705#endif
706 }
707
708 if (!SWITCH_GLOBAL_dirs.sounds_dir && (SWITCH_GLOBAL_dirs.sounds_dir = (char *) malloc(BUFSIZE1024))) {
709 if (SWITCH_GLOBAL_dirs.base_dir)
710 switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE1024, "%s%ssounds", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR"/");
711 else
712#ifdef SWITCH_SOUNDS_DIR"/usr/local/freeswitch/sounds"
713 switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE1024, "%s", SWITCH_SOUNDS_DIR"/usr/local/freeswitch/sounds");
714#else
715 switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE1024, "%s%ssounds", base_dir, SWITCH_PATH_SEPARATOR"/");
716#endif
717 }
718
719 if (!SWITCH_GLOBAL_dirs.storage_dir && (SWITCH_GLOBAL_dirs.storage_dir = (char *) malloc(BUFSIZE1024))) {
720 if (SWITCH_GLOBAL_dirs.base_dir)
721 switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE1024, "%s%sstorage", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR"/");
722 else
723#ifdef SWITCH_STORAGE_DIR"/usr/local/freeswitch/storage"
724 switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE1024, "%s", SWITCH_STORAGE_DIR"/usr/local/freeswitch/storage");
725#else
726 switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE1024, "%s%sstorage", base_dir, SWITCH_PATH_SEPARATOR"/");
727#endif
728 }
729
730 if (!SWITCH_GLOBAL_dirs.cache_dir && (SWITCH_GLOBAL_dirs.cache_dir = (char *) malloc(BUFSIZE1024))) {
731 if (SWITCH_GLOBAL_dirs.base_dir)
732 switch_snprintf(SWITCH_GLOBAL_dirs.cache_dir, BUFSIZE1024, "%s%scache", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR"/");
733 else
734#ifdef SWITCH_CACHE_DIR"/usr/local/freeswitch/cache"
735 switch_snprintf(SWITCH_GLOBAL_dirs.cache_dir, BUFSIZE1024, "%s", SWITCH_CACHE_DIR"/usr/local/freeswitch/cache");
736#else
737 switch_snprintf(SWITCH_GLOBAL_dirs.cache_dir, BUFSIZE1024, "%s%scache", base_dir, SWITCH_PATH_SEPARATOR"/");
738#endif
739 }
740
741 if (!SWITCH_GLOBAL_dirs.db_dir && (SWITCH_GLOBAL_dirs.db_dir = (char *) malloc(BUFSIZE1024))) {
742 if (SWITCH_GLOBAL_dirs.base_dir)
743 switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE1024, "%s%sdb", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR"/");
744 else
745#ifdef SWITCH_DB_DIR"/usr/local/freeswitch/db"
746 switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE1024, "%s", SWITCH_DB_DIR"/usr/local/freeswitch/db");
747#else
748 switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE1024, "%s%sdb", base_dir, SWITCH_PATH_SEPARATOR"/");
749#endif
750 }
751
752 if (!SWITCH_GLOBAL_dirs.script_dir && (SWITCH_GLOBAL_dirs.script_dir = (char *) malloc(BUFSIZE1024))) {
753 if (SWITCH_GLOBAL_dirs.base_dir)
754 switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE1024, "%s%sscripts", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR"/");
755 else
756#ifdef SWITCH_SCRIPT_DIR"/usr/local/freeswitch/scripts"
757 switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE1024, "%s", SWITCH_SCRIPT_DIR"/usr/local/freeswitch/scripts");
758#else
759 switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE1024, "%s%sscripts", base_dir, SWITCH_PATH_SEPARATOR"/");
760#endif
761 }
762
763 if (!SWITCH_GLOBAL_dirs.htdocs_dir && (SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(BUFSIZE1024))) {
764 if (SWITCH_GLOBAL_dirs.base_dir)
765 switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE1024, "%s%shtdocs", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR"/");
766 else
767#ifdef SWITCH_HTDOCS_DIR"/usr/local/freeswitch/htdocs"
768 switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE1024, "%s", SWITCH_HTDOCS_DIR"/usr/local/freeswitch/htdocs");
769#else
770 switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE1024, "%s%shtdocs", base_dir, SWITCH_PATH_SEPARATOR"/");
771#endif
772 }
773
774 if (!SWITCH_GLOBAL_dirs.grammar_dir && (SWITCH_GLOBAL_dirs.grammar_dir = (char *) malloc(BUFSIZE1024))) {
775 if (SWITCH_GLOBAL_dirs.base_dir)
776 switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE1024, "%s%sgrammar", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR"/");
777 else
778#ifdef SWITCH_GRAMMAR_DIR"/usr/local/freeswitch/grammar"
779 switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE1024, "%s", SWITCH_GRAMMAR_DIR"/usr/local/freeswitch/grammar");
780#else
781 switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE1024, "%s%sgrammar", base_dir, SWITCH_PATH_SEPARATOR"/");
782#endif
783 }
784
785 if (!SWITCH_GLOBAL_dirs.certs_dir && (SWITCH_GLOBAL_dirs.certs_dir = (char *) malloc(BUFSIZE1024))) {
786 if (SWITCH_GLOBAL_dirs.base_dir)
787 switch_snprintf(SWITCH_GLOBAL_dirs.certs_dir, BUFSIZE1024, "%s%scert", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR"/");
788 else
789#ifdef SWITCH_CERTS_DIR"/usr/local/freeswitch/certs"
790 switch_snprintf(SWITCH_GLOBAL_dirs.certs_dir, BUFSIZE1024, "%s", SWITCH_CERTS_DIR"/usr/local/freeswitch/certs");
791#else
792 switch_snprintf(SWITCH_GLOBAL_dirs.certs_dir, BUFSIZE1024, "%s%scert", base_dir, SWITCH_PATH_SEPARATOR"/");
793#endif
794 }
795
796 if (!SWITCH_GLOBAL_dirs.temp_dir && (SWITCH_GLOBAL_dirs.temp_dir = (char *) malloc(BUFSIZE1024))) {
797#ifdef SWITCH_TEMP_DIR
798 switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE1024, "%s", SWITCH_TEMP_DIR);
799#else
800#ifdef WIN32
801 GetTempPath(dwBufSize, lpPathBuffer);
802 lpPathBuffer[strlen(lpPathBuffer)-1] = 0;
803 tmp = switch_string_replace(lpPathBuffer, "\\", "/");
804 strcpy(lpPathBuffer, tmp);
805 free(tmp);
806 switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE1024, "%s", lpPathBuffer);
807#else
808 switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE1024, "%s", "/tmp");
809#endif
810#endif
811 }
812
813 if (!SWITCH_GLOBAL_filenames.conf_name && (SWITCH_GLOBAL_filenames.conf_name = (char *) malloc(BUFSIZE1024))) {
814 switch_snprintf(SWITCH_GLOBAL_filenames.conf_name, BUFSIZE1024, "%s", "freeswitch.xml");
815 }
816
817 /* Do this last because it being empty is part of the above logic */
818 if (!SWITCH_GLOBAL_dirs.base_dir && (SWITCH_GLOBAL_dirs.base_dir = (char *) malloc(BUFSIZE1024))) {
819 switch_snprintf(SWITCH_GLOBAL_dirs.base_dir, BUFSIZE1024, "%s", base_dir);
820 }
821
822 switch_assert(SWITCH_GLOBAL_dirs.base_dir)((SWITCH_GLOBAL_dirs.base_dir) ? (void) (0) : __assert_fail (
"SWITCH_GLOBAL_dirs.base_dir", "src/switch_core.c", 822, __PRETTY_FUNCTION__
))
;
823 switch_assert(SWITCH_GLOBAL_dirs.mod_dir)((SWITCH_GLOBAL_dirs.mod_dir) ? (void) (0) : __assert_fail ("SWITCH_GLOBAL_dirs.mod_dir"
, "src/switch_core.c", 823, __PRETTY_FUNCTION__))
;
824 switch_assert(SWITCH_GLOBAL_dirs.lib_dir)((SWITCH_GLOBAL_dirs.lib_dir) ? (void) (0) : __assert_fail ("SWITCH_GLOBAL_dirs.lib_dir"
, "src/switch_core.c", 824, __PRETTY_FUNCTION__))
;
825 switch_assert(SWITCH_GLOBAL_dirs.conf_dir)((SWITCH_GLOBAL_dirs.conf_dir) ? (void) (0) : __assert_fail (
"SWITCH_GLOBAL_dirs.conf_dir", "src/switch_core.c", 825, __PRETTY_FUNCTION__
))
;
826 switch_assert(SWITCH_GLOBAL_dirs.log_dir)((SWITCH_GLOBAL_dirs.log_dir) ? (void) (0) : __assert_fail ("SWITCH_GLOBAL_dirs.log_dir"
, "src/switch_core.c", 826, __PRETTY_FUNCTION__))
;
827 switch_assert(SWITCH_GLOBAL_dirs.run_dir)((SWITCH_GLOBAL_dirs.run_dir) ? (void) (0) : __assert_fail ("SWITCH_GLOBAL_dirs.run_dir"
, "src/switch_core.c", 827, __PRETTY_FUNCTION__))
;
828 switch_assert(SWITCH_GLOBAL_dirs.db_dir)((SWITCH_GLOBAL_dirs.db_dir) ? (void) (0) : __assert_fail ("SWITCH_GLOBAL_dirs.db_dir"
, "src/switch_core.c", 828, __PRETTY_FUNCTION__))
;
829 switch_assert(SWITCH_GLOBAL_dirs.script_dir)((SWITCH_GLOBAL_dirs.script_dir) ? (void) (0) : __assert_fail
("SWITCH_GLOBAL_dirs.script_dir", "src/switch_core.c", 829, __PRETTY_FUNCTION__
))
;
830 switch_assert(SWITCH_GLOBAL_dirs.htdocs_dir)((SWITCH_GLOBAL_dirs.htdocs_dir) ? (void) (0) : __assert_fail
("SWITCH_GLOBAL_dirs.htdocs_dir", "src/switch_core.c", 830, __PRETTY_FUNCTION__
))
;
831 switch_assert(SWITCH_GLOBAL_dirs.grammar_dir)((SWITCH_GLOBAL_dirs.grammar_dir) ? (void) (0) : __assert_fail
("SWITCH_GLOBAL_dirs.grammar_dir", "src/switch_core.c", 831,
__PRETTY_FUNCTION__))
;
832 switch_assert(SWITCH_GLOBAL_dirs.recordings_dir)((SWITCH_GLOBAL_dirs.recordings_dir) ? (void) (0) : __assert_fail
("SWITCH_GLOBAL_dirs.recordings_dir", "src/switch_core.c", 832
, __PRETTY_FUNCTION__))
;
833 switch_assert(SWITCH_GLOBAL_dirs.sounds_dir)((SWITCH_GLOBAL_dirs.sounds_dir) ? (void) (0) : __assert_fail
("SWITCH_GLOBAL_dirs.sounds_dir", "src/switch_core.c", 833, __PRETTY_FUNCTION__
))
;
834 switch_assert(SWITCH_GLOBAL_dirs.certs_dir)((SWITCH_GLOBAL_dirs.certs_dir) ? (void) (0) : __assert_fail (
"SWITCH_GLOBAL_dirs.certs_dir", "src/switch_core.c", 834, __PRETTY_FUNCTION__
))
;
835 switch_assert(SWITCH_GLOBAL_dirs.temp_dir)((SWITCH_GLOBAL_dirs.temp_dir) ? (void) (0) : __assert_fail (
"SWITCH_GLOBAL_dirs.temp_dir", "src/switch_core.c", 835, __PRETTY_FUNCTION__
))
;
836
837 switch_assert(SWITCH_GLOBAL_filenames.conf_name)((SWITCH_GLOBAL_filenames.conf_name) ? (void) (0) : __assert_fail
("SWITCH_GLOBAL_filenames.conf_name", "src/switch_core.c", 837
, __PRETTY_FUNCTION__))
;
838}
839
840
841SWITCH_DECLARE(int32_t)__attribute__((visibility("default"))) int32_t set_low_priority(void)
842{
843
844
845#ifdef WIN32
846 SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
847#else
848#ifdef USE_SCHED_SETSCHEDULER1
849 /*
850 * Try to use a normal scheduler
851 */
852 struct sched_param sched = { 0 };
853 sched.sched_priority__sched_priority = 0;
854 if (sched_setscheduler(0, SCHED_OTHER0, &sched)) {
855 return -1;
856 }
857#endif
858
859#ifdef HAVE_SETPRIORITY1
860 /*
861 * setpriority() works on FreeBSD (6.2), nice() doesn't
862 */
863 if (setpriority(PRIO_PROCESSPRIO_PROCESS, getpid(), 19) < 0) {
864 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 864, ((void*)0)
, SWITCH_LOG_CRIT, "Could not set nice level\n");
865 return -1;
866 }
867#else
868 if (nice(19) != 19) {
869 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 869, ((void*)0)
, SWITCH_LOG_CRIT, "Could not set nice level\n");
870 return -1;
871 }
872#endif
873#endif
874
875 return 0;
876}
877
878SWITCH_DECLARE(int32_t)__attribute__((visibility("default"))) int32_t set_realtime_priority(void)
879{
880#ifdef WIN32
881 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
882#else
883#ifdef USE_SCHED_SETSCHEDULER1
884 /*
885 * Try to use a round-robin scheduler
886 * with a fallback if that does not work
887 */
888 struct sched_param sched = { 0 };
889 sched.sched_priority__sched_priority = SWITCH_PRI_LOW;
890 if (sched_setscheduler(0, SCHED_FIFO1, &sched)) {
891 sched.sched_priority__sched_priority = 0;
892 if (sched_setscheduler(0, SCHED_OTHER0, &sched)) {
893 return -1;
894 }
895 }
896#endif
897
898
899
900#ifdef HAVE_SETPRIORITY1
901 /*
902 * setpriority() works on FreeBSD (6.2), nice() doesn't
903 */
904 if (setpriority(PRIO_PROCESSPRIO_PROCESS, getpid(), -10) < 0) {
905 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 905, ((void*)0)
, SWITCH_LOG_CRIT, "Could not set nice level\n");
906 return -1;
907 }
908#else
909 if (nice(-10) != -10) {
910 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 910, ((void*)0)
, SWITCH_LOG_CRIT, "Could not set nice level\n");
911 return -1;
912 }
913#endif
914#endif
915 return 0;
916}
917
918SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_cpu_count(void)
919{
920 return runtime.cpu_count;
921}
922
923SWITCH_DECLARE(int32_t)__attribute__((visibility("default"))) int32_t set_normal_priority(void)
924{
925 return 0;
926}
927
928SWITCH_DECLARE(int32_t)__attribute__((visibility("default"))) int32_t set_auto_priority(void)
929{
930#ifndef WIN32
931 runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN_SC_NPROCESSORS_ONLN);
932#else
933 SYSTEM_INFO sysinfo;
934 GetSystemInfo( &sysinfo );
935 runtime.cpu_count = sysinfo.dwNumberOfProcessors;
936#endif
937
938 if (!runtime.cpu_count) runtime.cpu_count = 1;
939
940 return set_realtime_priority();
941
942
943 // ERROR: code not reachable on Windows Visual Studio Express 2008 return 0;
944}
945
946SWITCH_DECLARE(int32_t)__attribute__((visibility("default"))) int32_t change_user_group(const char *user, const char *group)
947{
948#ifndef WIN32
949 uid_t runas_uid = 0;
950 gid_t runas_gid = 0;
951 struct passwd *runas_pw = NULL((void*)0);
952
953 if (user) {
954 /*
955 * Lookup user information in the system's db
956 */
957 runas_pw = getpwnam(user);
958 if (!runas_pw) {
959 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 959, ((void*)0)
, SWITCH_LOG_CRIT, "Unknown user \"%s\"\n", user);
960 return -1;
961 }
962 runas_uid = runas_pw->pw_uid;
963 }
964
965 if (group) {
966 struct group *gr = NULL((void*)0);
967
968 /*
969 * Lookup group information in the system's db
970 */
971 gr = getgrnam(group);
972 if (!gr) {
973 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 973, ((void*)0)
, SWITCH_LOG_CRIT, "Unknown group \"%s\"\n", group);
974 return -1;
975 }
976 runas_gid = gr->gr_gid;
977 }
978
979 if (runas_uid && getuid() == runas_uid && (!runas_gid || runas_gid == getgid())) {
980 /* already running as the right user and group, nothing to do! */
981 return 0;
982 }
983
984 if (runas_uid) {
985#ifdef HAVE_SETGROUPS1
986 /*
987 * Drop all group memberships prior to changing anything
988 * or else we're going to inherit the parent's list of groups
989 * (which is not what we want...)
990 */
991 if (setgroups(0, NULL((void*)0)) < 0) {
992 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 992, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to drop group access list\n");
993 return -1;
994 }
995#endif
996 if (runas_gid) {
997 /*
998 * A group has been passed, switch to it
999 * (without loading the user's other groups)
1000 */
1001 if (setgid(runas_gid) < 0) {
1002 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1002, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to change gid!\n");
1003 return -1;
1004 }
1005 } else {
1006 /*
1007 * No group has been passed, use the user's primary group in this case
1008 */
1009 if (setgid(runas_pw->pw_gid) < 0) {
1010 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1010, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to change gid!\n");
1011 return -1;
1012 }
1013#ifdef HAVE_INITGROUPS1
1014 /*
1015 * Set all the other groups the user is a member of
1016 * (This can be really useful for fine-grained access control)
1017 */
1018 if (initgroups(runas_pw->pw_name, runas_pw->pw_gid) < 0) {
1019 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1019, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to set group access list for user\n");
1020 return -1;
1021 }
1022#endif
1023 }
1024
1025 /*
1026 * Finally drop all privileges by switching to the new userid
1027 */
1028 if (setuid(runas_uid) < 0) {
1029 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1029, ((void*)0)
, SWITCH_LOG_CRIT, "Failed to change uid!\n");
1030 return -1;
1031 }
1032 }
1033#endif
1034 return 0;
1035}
1036
1037SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_runtime_loop(int bg)
1038{
1039#ifdef WIN32
1040 HANDLE shutdown_event;
1041 char path[256] = "";
1042#endif
1043 if (bg) {
1044#ifdef WIN32
1045 switch_snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid());
1046 shutdown_event = CreateEvent(NULL((void*)0), FALSE0, FALSE0, path);
1047 if (shutdown_event) {
1048 WaitForSingleObject(shutdown_event, INFINITE);
1049 }
1050#else
1051 runtime.running = 1;
1052 while (runtime.running) {
1053 switch_yield(1000000)switch_sleep(1000000);;
1054 }
1055#endif
1056 } else {
1057 /* wait for console input */
1058 switch_console_loop();
1059 }
1060}
1061
1062SWITCH_DECLARE(const char *)__attribute__((visibility("default"))) const char * switch_core_mime_ext2type(const char *ext)
1063{
1064 if (!ext) {
1065 return NULL((void*)0);
1066 }
1067 return (const char *) switch_core_hash_find(runtime.mime_types, ext);
1068}
1069
1070
1071SWITCH_DECLARE(switch_hash_index_t *)__attribute__((visibility("default"))) switch_hash_index_t * switch_core_mime_index(void)
1072{
1073 return switch_core_hash_first(runtime.mime_types)switch_core_hash_first_iter(runtime.mime_types, ((void*)0));
1074}
1075
1076SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_mime_add_type(const char *type, const char *ext)
1077{
1078 const char *check;
1079 switch_status_t status = SWITCH_STATUS_FALSE;
1080
1081 switch_assert(type)((type) ? (void) (0) : __assert_fail ("type", "src/switch_core.c"
, 1081, __PRETTY_FUNCTION__))
;
1082 switch_assert(ext)((ext) ? (void) (0) : __assert_fail ("ext", "src/switch_core.c"
, 1082, __PRETTY_FUNCTION__))
;
1083
1084 check = (const char *) switch_core_hash_find(runtime.mime_types, ext);
1085
1086 if (!check) {
1087 char *ptype = switch_core_permanent_strdup(type)switch_core_perform_permanent_strdup(type, "src/switch_core.c"
, (const char *)__func__, 1087)
;
1088 char *ext_list = strdup(ext)(__extension__ (__builtin_constant_p (ext) && ((size_t
)(const void *)((ext) + 1) - (size_t)(const void *)(ext) == 1
) ? (((const char *) (ext))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (ext) + 1; char *
__retval = (char *) malloc (__len); if (__retval != ((void*)0
)) __retval = (char *) memcpy (__retval, ext, __len); __retval
; })) : __strdup (ext)))
;
1089 int argc = 0;
1090 char *argv[20] = { 0 };
1091 int x;
1092
1093 switch_assert(ext_list)((ext_list) ? (void) (0) : __assert_fail ("ext_list", "src/switch_core.c"
, 1093, __PRETTY_FUNCTION__))
;
1094
1095 if ((argc = switch_separate_string(ext_list, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
1096
1097 for (x = 0; x < argc; x++) {
1098 if (argv[x] && ptype) {
1099 switch_core_hash_insert(runtime.mime_types, argv[x], ptype)switch_core_hash_insert_destructor(runtime.mime_types, argv[x
], ptype, ((void*)0))
;
1100 }
1101 }
1102
1103 status = SWITCH_STATUS_SUCCESS;
1104 }
1105
1106 free(ext_list);
1107 }
1108
1109 return status;
1110}
1111
1112static void load_mime_types(void)
1113{
1114 char *cf = "mime.types";
1115 FILE *fd = NULL((void*)0);
1116 char *line_buf = NULL((void*)0);
1117 switch_size_t llen = 0;
1118 char *mime_path = NULL((void*)0);
1119
1120 mime_path = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.conf_dir, cf);
1121 switch_assert(mime_path)((mime_path) ? (void) (0) : __assert_fail ("mime_path", "src/switch_core.c"
, 1121, __PRETTY_FUNCTION__))
;
1122
1123 fd = fopen(mime_path, "rb");
1124
1125 if (fd == NULL((void*)0)) {
1126 goto end;
1127 }
1128
1129 while ((switch_fp_read_dline(fd, &line_buf, &llen))) {
1130 char *p;
1131 char *type = line_buf;
1132
1133 if (*line_buf == '#') {
1134 continue;
1135 }
1136
1137 if ((p = strchr(line_buf, '\r')(__extension__ (__builtin_constant_p ('\r') && !__builtin_constant_p
(line_buf) && ('\r') == '\0' ? (char *) __rawmemchr (
line_buf, '\r') : __builtin_strchr (line_buf, '\r')))
) || (p = strchr(line_buf, '\n')(__extension__ (__builtin_constant_p ('\n') && !__builtin_constant_p
(line_buf) && ('\n') == '\0' ? (char *) __rawmemchr (
line_buf, '\n') : __builtin_strchr (line_buf, '\n')))
)) {
1138 *p = '\0';
1139 }
1140
1141 if ((p = strchr(type, '\t')(__extension__ (__builtin_constant_p ('\t') && !__builtin_constant_p
(type) && ('\t') == '\0' ? (char *) __rawmemchr (type
, '\t') : __builtin_strchr (type, '\t')))
) || (p = strchr(type, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(type) && (' ') == '\0' ? (char *) __rawmemchr (type
, ' ') : __builtin_strchr (type, ' ')))
)) {
1142 *p++ = '\0';
1143
1144 while (*p == ' ' || *p == '\t') {
1145 p++;
1146 }
1147
1148 switch_core_mime_add_type(type, p);
1149 }
1150
1151 }
1152
1153 switch_safe_free(line_buf)if (line_buf) {free(line_buf);line_buf=((void*)0);};
1154
1155 if (fd) {
1156 fclose(fd);
1157 fd = NULL((void*)0);
1158 }
1159
1160 end:
1161
1162 switch_safe_free(mime_path)if (mime_path) {free(mime_path);mime_path=((void*)0);};
1163
1164}
1165
1166SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_setrlimits(void)
1167{
1168#ifdef HAVE_SETRLIMIT1
1169 struct rlimit rlp;
1170
1171 /*
1172 Setting the stack size on FreeBSD results in an instant crash.
1173
1174 If anyone knows how to fix this,
1175 feel free to submit a patch to http://jira.freeswitch.org
1176 */
1177
1178#ifndef __FreeBSD__
1179 memset(&rlp, 0, sizeof(rlp));
1180 rlp.rlim_cur = SWITCH_THREAD_STACKSIZE240 * 1024;
1181 rlp.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE8192 * 1024;
1182 setrlimit(RLIMIT_STACKRLIMIT_STACK, &rlp);
1183#endif
1184
1185 memset(&rlp, 0, sizeof(rlp));
1186 rlp.rlim_cur = 999999;
1187 rlp.rlim_max = 999999;
1188 setrlimit(RLIMIT_NOFILERLIMIT_NOFILE, &rlp);
1189
1190 memset(&rlp, 0, sizeof(rlp));
1191 rlp.rlim_cur = RLIM_INFINITY((__rlim_t) -1);
1192 rlp.rlim_max = RLIM_INFINITY((__rlim_t) -1);
1193
1194 setrlimit(RLIMIT_CPURLIMIT_CPU, &rlp);
1195 setrlimit(RLIMIT_DATARLIMIT_DATA, &rlp);
1196 setrlimit(RLIMIT_FSIZERLIMIT_FSIZE, &rlp);
1197#ifdef RLIMIT_NPROC__RLIMIT_NPROC
1198 setrlimit(RLIMIT_NPROC__RLIMIT_NPROC, &rlp);
1199#endif
1200#ifdef RLIMIT_RTPRIO__RLIMIT_RTPRIO
1201 setrlimit(RLIMIT_RTPRIO__RLIMIT_RTPRIO, &rlp);
1202#endif
1203
1204#if !defined(__OpenBSD__) && !defined(__NetBSD__)
1205 setrlimit(RLIMIT_ASRLIMIT_AS, &rlp);
1206#endif
1207#endif
1208 return;
1209}
1210
1211typedef struct {
1212 switch_memory_pool_t *pool;
1213 switch_hash_t *hash;
1214} switch_ip_list_t;
1215
1216static switch_ip_list_t IP_LIST = { 0 };
1217
1218SWITCH_DECLARE(switch_bool_t)__attribute__((visibility("default"))) switch_bool_t switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token)
1219{
1220 switch_network_list_t *list;
1221 ip_t ip, mask, net;
1222 uint32_t bits;
1223 char *ipv6 = strchr(ip_str,':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(ip_str) && (':') == '\0' ? (char *) __rawmemchr (ip_str
, ':') : __builtin_strchr (ip_str, ':')))
;
1224 switch_bool_t ok = SWITCH_FALSE;
1225
1226 switch_mutex_lock(runtime.global_mutex);
1227 if (ipv6) {
1228 switch_inet_pton(AF_INET610, ip_str, &ip);
1229 } else {
1230 switch_inet_pton(AF_INET2, ip_str, &ip);
1231 ip.v4 = htonl(ip.v4)(__extension__ ({ unsigned int __v, __x = (ip.v4); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
1232 }
1233
1234 if ((list = switch_core_hash_find(IP_LIST.hash, list_name))) {
1235 if (ipv6) {
1236 ok = switch_network_list_validate_ip6_token(list, ip, token);
1237 } else {
1238 ok = switch_network_list_validate_ip_token(list, ip.v4, token);
1239 }
1240 } else if (strchr(list_name, '/')(__extension__ (__builtin_constant_p ('/') && !__builtin_constant_p
(list_name) && ('/') == '\0' ? (char *) __rawmemchr (
list_name, '/') : __builtin_strchr (list_name, '/')))
) {
1241 if (strchr(list_name, ',')(__extension__ (__builtin_constant_p (',') && !__builtin_constant_p
(list_name) && (',') == '\0' ? (char *) __rawmemchr (
list_name, ',') : __builtin_strchr (list_name, ',')))
) {
1242 char *list_name_dup = strdup(list_name)(__extension__ (__builtin_constant_p (list_name) && (
(size_t)(const void *)((list_name) + 1) - (size_t)(const void
*)(list_name) == 1) ? (((const char *) (list_name))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen (list_name) + 1; char *__retval = (char *) malloc (
__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, list_name, __len); __retval; })) : __strdup (list_name
)))
;
1243 char *argv[32];
1244 int argc;
1245
1246 switch_assert(list_name_dup)((list_name_dup) ? (void) (0) : __assert_fail ("list_name_dup"
, "src/switch_core.c", 1246, __PRETTY_FUNCTION__))
;
1247
1248 if ((argc = switch_separate_string(list_name_dup, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
1249 int i;
1250 for (i = 0; i < argc; i++) {
1251 switch_parse_cidr(argv[i], &net, &mask, &bits);
1252 if (ipv6) {
1253 if ((ok = switch_testv6_subnet(ip, net, mask))){
1254 break;
1255 }
1256 } else {
1257 if ((ok = switch_test_subnet(ip.v4, net.v4, mask.v4)(mask.v4 ? ((net.v4 & mask.v4) == (ip.v4 & mask.v4)) :
net.v4 ? net.v4 == ip.v4 : 1)
)) {
1258 break;
1259 }
1260 }
1261 }
1262 }
1263 free(list_name_dup);
1264 } else {
1265 switch_parse_cidr(list_name, &net, &mask, &bits);
1266 ok = switch_test_subnet(ip.v4, net.v4, mask.v4)(mask.v4 ? ((net.v4 & mask.v4) == (ip.v4 & mask.v4)) :
net.v4 ? net.v4 == ip.v4 : 1)
;
1267 }
1268 }
1269 switch_mutex_unlock(runtime.global_mutex);
1270
1271 return ok;
1272}
1273
1274
1275SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_load_network_lists(switch_bool_t reload)
1276{
1277 switch_xml_t xml = NULL((void*)0), x_lists = NULL((void*)0), x_list = NULL((void*)0), x_node = NULL((void*)0), cfg = NULL((void*)0);
1278 switch_network_list_t *rfc_list, *list;
1279 char guess_ip[16] = "";
1280 int mask = 0;
1281 char guess_mask[16] = "";
1282 char *tmp_name;
1283 struct in_addr in;
1284
1285 switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET2);
1286 in.s_addr = mask;
1287 switch_set_string(guess_mask, inet_ntoa(in))switch_copy_string(guess_mask, inet_ntoa(in), sizeof(guess_mask
))
;
1288
1289 switch_mutex_lock(runtime.global_mutex);
1290
1291 if (IP_LIST.hash) {
1292 switch_core_hash_destroy(&IP_LIST.hash);
1293 }
1294
1295 if (IP_LIST.pool) {
1296 switch_core_destroy_memory_pool(&IP_LIST.pool)switch_core_perform_destroy_memory_pool(&IP_LIST.pool, "src/switch_core.c"
, (const char *)__func__, 1296)
;
1297 }
1298
1299 memset(&IP_LIST, 0, sizeof(IP_LIST));
1300 switch_core_new_memory_pool(&IP_LIST.pool)switch_core_perform_new_memory_pool(&IP_LIST.pool, "src/switch_core.c"
, (const char *)__func__, 1300)
;
1301 switch_core_hash_init(&IP_LIST.hash)switch_core_hash_init_case(&IP_LIST.hash, SWITCH_TRUE);
1302
1303
1304 tmp_name = "rfc6598.auto";
1305 switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
1306 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1306, ((void*)0)
, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
1307 switch_network_list_add_cidr(rfc_list, "100.64.0.0/10", SWITCH_TRUE)switch_network_list_add_cidr_token(rfc_list, "100.64.0.0/10",
SWITCH_TRUE, ((void*)0))
;
1308 switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list)switch_core_hash_insert_destructor(IP_LIST.hash, tmp_name, rfc_list
, ((void*)0))
;
1309
1310 tmp_name = "rfc1918.auto";
1311 switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
1312 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1312, ((void*)0)
, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
1313 switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE)switch_network_list_add_cidr_token(rfc_list, "10.0.0.0/8", SWITCH_TRUE
, ((void*)0))
;
1314 switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE)switch_network_list_add_cidr_token(rfc_list, "172.16.0.0/12",
SWITCH_TRUE, ((void*)0))
;
1315 switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE)switch_network_list_add_cidr_token(rfc_list, "192.168.0.0/16"
, SWITCH_TRUE, ((void*)0))
;
1316 switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list)switch_core_hash_insert_destructor(IP_LIST.hash, tmp_name, rfc_list
, ((void*)0))
;
1317
1318 tmp_name = "wan.auto";
1319 switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool);
1320 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1320, ((void*)0)
, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name);
1321 switch_network_list_add_cidr(rfc_list, "0.0.0.0/8", SWITCH_FALSE)switch_network_list_add_cidr_token(rfc_list, "0.0.0.0/8", SWITCH_FALSE
, ((void*)0))
;
1322 switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_FALSE)switch_network_list_add_cidr_token(rfc_list, "10.0.0.0/8", SWITCH_FALSE
, ((void*)0))
;
1323 switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_FALSE)switch_network_list_add_cidr_token(rfc_list, "172.16.0.0/12",
SWITCH_FALSE, ((void*)0))
;
1324 switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_FALSE)switch_network_list_add_cidr_token(rfc_list, "192.168.0.0/16"
, SWITCH_FALSE, ((void*)0))
;
1325 switch_network_list_add_cidr(rfc_list, "169.254.0.0/16", SWITCH_FALSE)switch_network_list_add_cidr_token(rfc_list, "169.254.0.0/16"
, SWITCH_FALSE, ((void*)0))
;
1326 switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list)switch_core_hash_insert_destructor(IP_LIST.hash, tmp_name, rfc_list
, ((void*)0))
;
1327
1328 tmp_name = "nat.auto";
1329 switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
1330 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1330, ((void*)0)
, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
1331 if (switch_network_list_add_host_mask(rfc_list, guess_ip, guess_mask, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
1332 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1332, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding %s/%s (deny) to list %s\n", guess_ip, guess_mask, tmp_name);
1333 }
1334 switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE)switch_network_list_add_cidr_token(rfc_list, "10.0.0.0/8", SWITCH_TRUE
, ((void*)0))
;
1335 switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE)switch_network_list_add_cidr_token(rfc_list, "172.16.0.0/12",
SWITCH_TRUE, ((void*)0))
;
1336 switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE)switch_network_list_add_cidr_token(rfc_list, "192.168.0.0/16"
, SWITCH_TRUE, ((void*)0))
;
1337 switch_network_list_add_cidr(rfc_list, "100.64.0.0/10", SWITCH_TRUE)switch_network_list_add_cidr_token(rfc_list, "100.64.0.0/10",
SWITCH_TRUE, ((void*)0))
;
1338 switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list)switch_core_hash_insert_destructor(IP_LIST.hash, tmp_name, rfc_list
, ((void*)0))
;
1339
1340 tmp_name = "loopback.auto";
1341 switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
1342 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1342, ((void*)0)
, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
1343 switch_network_list_add_cidr(rfc_list, "127.0.0.0/8", SWITCH_TRUE)switch_network_list_add_cidr_token(rfc_list, "127.0.0.0/8", SWITCH_TRUE
, ((void*)0))
;
1344 switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list)switch_core_hash_insert_destructor(IP_LIST.hash, tmp_name, rfc_list
, ((void*)0))
;
1345
1346 tmp_name = "localnet.auto";
1347 switch_network_list_create(&list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
1348 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1348, ((void*)0)
, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
1349
1350 if (switch_network_list_add_host_mask(list, guess_ip, guess_mask, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
1351 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1351, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding %s/%s (allow) to list %s\n", guess_ip, guess_mask, tmp_name);
1352 }
1353 switch_core_hash_insert(IP_LIST.hash, tmp_name, list)switch_core_hash_insert_destructor(IP_LIST.hash, tmp_name, list
, ((void*)0))
;
1354
1355
1356 if ((xml = switch_xml_open_cfg("acl.conf", &cfg, NULL((void*)0)))) {
1357 if ((x_lists = switch_xml_child(cfg, "network-lists"))) {
1358 for (x_list = switch_xml_child(x_lists, "list"); x_list; x_list = x_list->next) {
1359 const char *name = switch_xml_attr(x_list, "name");
1360 const char *dft = switch_xml_attr(x_list, "default");
1361 switch_bool_t default_type = SWITCH_TRUE;
1362
1363 if (zstr(name)_zstr(name)) {
1364 continue;
1365 }
1366
1367 if (dft) {
1368 default_type = switch_true(dft);
1369 }
1370
1371 if (switch_network_list_create(&list, name, default_type, IP_LIST.pool) != SWITCH_STATUS_SUCCESS) {
1372 abort();
1373 }
1374
1375 if (reload) {
1376 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1376, ((void*)0)
, SWITCH_LOG_NOTICE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny");
1377 } else {
1378 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1378, ((void*)0)
, SWITCH_LOG_CONSOLE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny");
1379 }
1380
1381
1382 for (x_node = switch_xml_child(x_list, "node"); x_node; x_node = x_node->next) {
1383 const char *cidr = NULL((void*)0), *host = NULL((void*)0), *mask = NULL((void*)0), *domain = NULL((void*)0);
1384 switch_bool_t ok = default_type;
1385 const char *type = switch_xml_attr(x_node, "type");
1386
1387 if (type) {
1388 ok = switch_true(type);
1389 }
1390
1391 cidr = switch_xml_attr(x_node, "cidr");
1392 host = switch_xml_attr(x_node, "host");
1393 mask = switch_xml_attr(x_node, "mask");
1394 domain = switch_xml_attr(x_node, "domain");
1395
1396 if (domain) {
1397 switch_event_t *my_params = NULL((void*)0);
1398 switch_xml_t x_domain, xml_root;
1399 switch_xml_t gt, gts, ut, uts;
1400
1401 switch_event_create(&my_params, SWITCH_EVENT_GENERAL)switch_event_create_subclass_detailed("src/switch_core.c", (const
char * )(const char *)__func__, 1401, &my_params, SWITCH_EVENT_GENERAL
, ((void*)0))
;
1402 switch_assert(my_params)((my_params) ? (void) (0) : __assert_fail ("my_params", "src/switch_core.c"
, 1402, __PRETTY_FUNCTION__))
;
1403 switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "domain", domain);
1404 switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "purpose", "network-list");
1405
1406 if (switch_xml_locate_domain(domain, my_params, &xml_root, &x_domain) != SWITCH_STATUS_SUCCESS) {
1407 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1407, ((void*)0)
, SWITCH_LOG_WARNING, "Cannot locate domain %s\n", domain);
1408 switch_event_destroy(&my_params);
1409 continue;
1410 }
1411
1412 switch_event_destroy(&my_params);
1413
1414 if ((ut = switch_xml_child(x_domain, "users"))) {
1415 x_domain = ut;
1416 }
1417
1418 for (ut = switch_xml_child(x_domain, "user"); ut; ut = ut->next) {
1419 const char *user_cidr = switch_xml_attr(ut, "cidr");
1420 const char *id = switch_xml_attr(ut, "id");
1421
1422 if (id && user_cidr) {
1423 char *token = switch_mprintf("%s@%s", id, domain);
1424 switch_assert(token)((token) ? (void) (0) : __assert_fail ("token", "src/switch_core.c"
, 1424, __PRETTY_FUNCTION__))
;
1425 switch_network_list_add_cidr_token(list, user_cidr, ok, token);
1426 free(token);
1427 }
1428 }
1429
1430 for (gts = switch_xml_child(x_domain, "groups"); gts; gts = gts->next) {
1431 for (gt = switch_xml_child(gts, "group"); gt; gt = gt->next) {
1432 for (uts = switch_xml_child(gt, "users"); uts; uts = uts->next) {
1433 for (ut = switch_xml_child(uts, "user"); ut; ut = ut->next) {
1434 const char *user_cidr = switch_xml_attr(ut, "cidr");
1435 const char *id = switch_xml_attr(ut, "id");
1436
1437 if (id && user_cidr) {
1438 char *token = switch_mprintf("%s@%s", id, domain);
1439 switch_assert(token)((token) ? (void) (0) : __assert_fail ("token", "src/switch_core.c"
, 1439, __PRETTY_FUNCTION__))
;
1440 switch_network_list_add_cidr_token(list, user_cidr, ok, token);
1441 free(token);
1442 }
1443 }
1444 }
1445 }
1446 }
1447
1448 switch_xml_free(xml_root);
1449 } else if (cidr) {
1450 if (switch_network_list_add_cidr(list, cidr, ok)switch_network_list_add_cidr_token(list, cidr, ok, ((void*)0)
)
== SWITCH_STATUS_SUCCESS) {
1451 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1451, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name);
1452 } else {
1453 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1453, ((void*)0)
, SWITCH_LOG_ERROR,
1454 "Error Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name);
1455 }
1456 } else if (host && mask) {
1457 if (switch_network_list_add_host_mask(list, host, mask, ok) == SWITCH_STATUS_SUCCESS) {
1458 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1458, ((void*)0)
, SWITCH_LOG_NOTICE,
1459 "Adding %s/%s (%s) to list %s\n", host, mask, ok ? "allow" : "deny", name);
1460 }
1461 }
1462
1463 switch_core_hash_insert(IP_LIST.hash, name, list)switch_core_hash_insert_destructor(IP_LIST.hash, name, list, (
(void*)0))
;
1464 }
1465 }
1466 }
1467
1468 switch_xml_free(xml);
1469 }
1470
1471 switch_mutex_unlock(runtime.global_mutex);
1472}
1473
1474SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_max_dtmf_duration(uint32_t duration)
1475{
1476 if (duration) {
1477 if (duration > SWITCH_MAX_DTMF_DURATION192000) {
1478 duration = SWITCH_MAX_DTMF_DURATION192000;
1479 }
1480 if (duration < SWITCH_MIN_DTMF_DURATION400) {
1481 duration = SWITCH_MIN_DTMF_DURATION400;
1482 }
1483 runtime.max_dtmf_duration = duration;
1484 if (duration < runtime.min_dtmf_duration) {
1485 runtime.min_dtmf_duration = duration;
1486 }
1487 }
1488 return runtime.max_dtmf_duration;
1489}
1490
1491SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_default_dtmf_duration(uint32_t duration)
1492{
1493 if (duration) {
1494 if (duration < SWITCH_MIN_DTMF_DURATION400) {
1495 duration = SWITCH_MIN_DTMF_DURATION400;
1496 }
1497 if (duration > SWITCH_MAX_DTMF_DURATION192000) {
1498 duration = SWITCH_MAX_DTMF_DURATION192000;
1499 }
1500 runtime.default_dtmf_duration = duration;
1501
1502 if (duration < runtime.min_dtmf_duration) {
1503 runtime.min_dtmf_duration = duration;
1504 }
1505
1506 if (duration > runtime.max_dtmf_duration) {
1507 runtime.max_dtmf_duration = duration;
1508 }
1509
1510 }
1511 return runtime.default_dtmf_duration;
1512}
1513
1514SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_min_dtmf_duration(uint32_t duration)
1515{
1516 if (duration) {
1517 if (duration < SWITCH_MIN_DTMF_DURATION400) {
1518 duration = SWITCH_MIN_DTMF_DURATION400;
1519 }
1520 if (duration > SWITCH_MAX_DTMF_DURATION192000) {
1521 duration = SWITCH_MAX_DTMF_DURATION192000;
1522 }
1523
1524 runtime.min_dtmf_duration = duration;
1525
1526 if (duration > runtime.max_dtmf_duration) {
1527 runtime.max_dtmf_duration = duration;
1528 }
1529 }
1530 return runtime.min_dtmf_duration;
1531}
1532
1533SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_thread_set_cpu_affinity(int cpu)
1534{
1535 switch_status_t status = SWITCH_STATUS_FALSE;
1536
1537 if (cpu > -1) {
1538
1539#ifdef HAVE_CPU_SET_MACROS1
1540 cpu_set_t set;
1541
1542 CPU_ZERO(&set)do __builtin_memset (&set, '\0', sizeof (cpu_set_t)); while
(0)
;
1543 CPU_SET(cpu, &set)(__extension__ ({ size_t __cpu = (cpu); __cpu / 8 < (sizeof
(cpu_set_t)) ? (((__cpu_mask *) ((&set)->__bits))[((__cpu
) / (8 * sizeof (__cpu_mask)))] |= ((__cpu_mask) 1 << (
(__cpu) % (8 * sizeof (__cpu_mask))))) : 0; }))
;
1544
1545 if (!sched_setaffinity(0, sizeof(set), &set)) {
1546 status = SWITCH_STATUS_SUCCESS;
1547 }
1548
1549#else
1550#if WIN32
1551 if (SetThreadAffinityMask(GetCurrentThread(), (DWORD_PTR) cpu)) {
1552 status = SWITCH_STATUS_SUCCESS;
1553 }
1554#endif
1555#endif
1556 }
1557
1558 return status;
1559}
1560
1561
1562#ifdef ENABLE_ZRTP
1563static void switch_core_set_serial(void)
1564{
1565 char buf[13] = "";
1566 char path[256];
1567
1568 int fd = -1, write_fd = -1;
1569 switch_ssize_t bytes = 0;
1570
1571 switch_snprintf(path, sizeof(path), "%s%sfreeswitch.serial", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR"/");
1572
1573
1574 if ((fd = open(path, O_RDONLY00, 0)) < 0) {
1575 char *ip = switch_core_get_variable_dup("local_ip_v4");
1576 uint32_t ipi = 0;
1577 switch_byte_t *byte;
1578 int i = 0;
1579
1580 if (ip) {
1581 switch_inet_pton(AF_INET2, ip, &ipi);
1582 free(ip);
1583 ip = NULL((void*)0);
1584 }
1585
1586
1587 byte = (switch_byte_t *) & ipi;
1588
1589 for (i = 0; i < 8; i += 2) {
1590 switch_snprintf(buf + i, sizeof(buf) - i, "%0.2x", *byte);
1591 byte++;
1592 }
1593
1594 switch_stun_random_string(buf + 8, 4, "0123456789abcdef");
1595
1596 if ((write_fd = open(path, O_WRONLY01 | O_CREAT0100 | O_TRUNC01000, S_IRUSR0400 | S_IWUSR0200)) >= 0) {
1597 bytes = write(write_fd, buf, sizeof(buf));
1598 bytes++;
1599 close(write_fd);
1600 }
1601 } else {
1602 bytes = read(fd, buf, sizeof(buf) - 1);
1603 close(fd);
1604 }
1605
1606 switch_core_set_variable("switch_serial", buf);
1607}
1608#endif
1609
1610SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_core_test_flag(int flag)
1611{
1612 return switch_test_flag((&runtime), flag)(((&runtime))->flags & flag);
1613}
1614
1615
1616SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_init(switch_core_flag_t flags, switch_bool_t console, const char **err)
1617{
1618 switch_uuid_t uuid;
1619 char guess_ip[256];
1620 int mask = 0;
1621 struct in_addr in;
1622
1623
1624 if (runtime.runlevel > 0) {
1625 /* one per customer */
1626 return SWITCH_STATUS_SUCCESS;
1627 }
1628
1629 memset(&runtime, 0, sizeof(runtime));
1630 gethostname(runtime.hostname, sizeof(runtime.hostname));
1631
1632 runtime.max_db_handles = 50;
1633 runtime.db_handle_timeout = 5000000;
1634
1635 runtime.runlevel++;
1636 runtime.dummy_cng_frame.data = runtime.dummy_data;
1637 runtime.dummy_cng_frame.datalen = sizeof(runtime.dummy_data);
1638 runtime.dummy_cng_frame.buflen = sizeof(runtime.dummy_data);
1639 runtime.dbname = "core";
1640 switch_set_flag((&runtime.dummy_cng_frame), SFF_CNG)((&runtime.dummy_cng_frame))->flags |= (SFF_CNG);
1641 switch_set_flag((&runtime), SCF_AUTO_SCHEMAS)((&runtime))->flags |= (SCF_AUTO_SCHEMAS);
1642 switch_set_flag((&runtime), SCF_CLEAR_SQL)((&runtime))->flags |= (SCF_CLEAR_SQL);
1643 switch_set_flag((&runtime), SCF_API_EXPANSION)((&runtime))->flags |= (SCF_API_EXPANSION);
1644 switch_set_flag((&runtime), SCF_SESSION_THREAD_POOL)((&runtime))->flags |= (SCF_SESSION_THREAD_POOL);
1645#ifdef WIN32
1646 switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC)((&runtime))->flags |= (SCF_THREADED_SYSTEM_EXEC);
1647#endif
1648 switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS)((&runtime))->flags |= (SCF_NO_NEW_SESSIONS);
1649 runtime.hard_log_level = SWITCH_LOG_DEBUG;
1650 runtime.mailer_app = "sendmail";
1651 runtime.mailer_app_args = "-t";
1652 runtime.max_dtmf_duration = SWITCH_MAX_DTMF_DURATION192000;
1653 runtime.default_dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION2000;
1654 runtime.min_dtmf_duration = SWITCH_MIN_DTMF_DURATION400;
1655 runtime.odbc_dbtype = DBTYPE_DEFAULT;
1656 runtime.dbname = NULL((void*)0);
1657#ifndef WIN32
1658 runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN_SC_NPROCESSORS_ONLN);
1659#else
1660 {
1661 SYSTEM_INFO sysinfo;
1662 GetSystemInfo( &sysinfo );
1663 runtime.cpu_count = sysinfo.dwNumberOfProcessors;
1664 }
1665#endif
1666
1667 if (!runtime.cpu_count) runtime.cpu_count = 1;
1668
1669 if (sqlite3_initialize() != SQLITE_OK0) {
1670 *err = "FATAL ERROR! Could not initialize SQLite\n";
1671 return SWITCH_STATUS_MEMERR;
1672 }
1673
1674 /* INIT APR and Create the pool context */
1675 if (apr_initialize() != SWITCH_STATUS_SUCCESS) {
1676 *err = "FATAL ERROR! Could not initialize APR\n";
1677 return SWITCH_STATUS_MEMERR;
1678 }
1679
1680 if (!(runtime.memory_pool = switch_core_memory_init())) {
1681 *err = "FATAL ERROR! Could not allocate memory pool\n";
1682 return SWITCH_STATUS_MEMERR;
1683 }
1684 switch_assert(runtime.memory_pool != NULL)((runtime.memory_pool != ((void*)0)) ? (void) (0) : __assert_fail
("runtime.memory_pool != ((void*)0)", "src/switch_core.c", 1684
, __PRETTY_FUNCTION__))
;
1685
1686 switch_dir_make_recursive(SWITCH_GLOBAL_dirs.base_dir, SWITCH_DEFAULT_DIR_PERMS0x0400 | 0x0200 | 0x0100 | 0x0040 | 0x0010, runtime.memory_pool);
1687 switch_dir_make_recursive(SWITCH_GLOBAL_dirs.mod_dir, SWITCH_DEFAULT_DIR_PERMS0x0400 | 0x0200 | 0x0100 | 0x0040 | 0x0010, runtime.memory_pool);
1688 switch_dir_make_recursive(SWITCH_GLOBAL_dirs.conf_dir, SWITCH_DEFAULT_DIR_PERMS0x0400 | 0x0200 | 0x0100 | 0x0040 | 0x0010, runtime.memory_pool);
1689 switch_dir_make_recursive(SWITCH_GLOBAL_dirs.log_dir, SWITCH_DEFAULT_DIR_PERMS0x0400 | 0x0200 | 0x0100 | 0x0040 | 0x0010, runtime.memory_pool);
1690 switch_dir_make_recursive(SWITCH_GLOBAL_dirs.run_dir, SWITCH_DEFAULT_DIR_PERMS0x0400 | 0x0200 | 0x0100 | 0x0040 | 0x0010, runtime.memory_pool);
1691 switch_dir_make_recursive(SWITCH_GLOBAL_dirs.db_dir, SWITCH_DEFAULT_DIR_PERMS0x0400 | 0x0200 | 0x0100 | 0x0040 | 0x0010, runtime.memory_pool);
1692 switch_dir_make_recursive(SWITCH_GLOBAL_dirs.script_dir, SWITCH_DEFAULT_DIR_PERMS0x0400 | 0x0200 | 0x0100 | 0x0040 | 0x0010, runtime.memory_pool);
1693 switch_dir_make_recursive(SWITCH_GLOBAL_dirs.htdocs_dir, SWITCH_DEFAULT_DIR_PERMS0x0400 | 0x0200 | 0x0100 | 0x0040 | 0x0010, runtime.memory_pool);
1694 switch_dir_make_recursive(SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_DEFAULT_DIR_PERMS0x0400 | 0x0200 | 0x0100 | 0x0040 | 0x0010, runtime.memory_pool);
1695 switch_dir_make_recursive(SWITCH_GLOBAL_dirs.recordings_dir, SWITCH_DEFAULT_DIR_PERMS0x0400 | 0x0200 | 0x0100 | 0x0040 | 0x0010, runtime.memory_pool);
1696 switch_dir_make_recursive(SWITCH_GLOBAL_dirs.sounds_dir, SWITCH_DEFAULT_DIR_PERMS0x0400 | 0x0200 | 0x0100 | 0x0040 | 0x0010, runtime.memory_pool);
1697 switch_dir_make_recursive(SWITCH_GLOBAL_dirs.temp_dir, SWITCH_DEFAULT_DIR_PERMS0x0400 | 0x0200 | 0x0100 | 0x0040 | 0x0010, runtime.memory_pool);
1698 switch_dir_make_recursive(SWITCH_GLOBAL_dirs.certs_dir, SWITCH_DEFAULT_DIR_PERMS0x0400 | 0x0200 | 0x0100 | 0x0040 | 0x0010, runtime.memory_pool);
1699
1700 switch_mutex_init(&runtime.uuid_mutex, SWITCH_MUTEX_NESTED0x1, runtime.memory_pool);
1701
1702 switch_mutex_init(&runtime.throttle_mutex, SWITCH_MUTEX_NESTED0x1, runtime.memory_pool);
1703
1704 switch_mutex_init(&runtime.session_hash_mutex, SWITCH_MUTEX_NESTED0x1, runtime.memory_pool);
1705 switch_mutex_init(&runtime.global_mutex, SWITCH_MUTEX_NESTED0x1, runtime.memory_pool);
1706
1707 switch_thread_rwlock_create(&runtime.global_var_rwlock, runtime.memory_pool);
1708 switch_core_set_globals();
1709 switch_core_session_init(runtime.memory_pool);
1710 switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA);
1711 switch_core_hash_init(&runtime.mime_types)switch_core_hash_init_case(&runtime.mime_types, SWITCH_TRUE
)
;
1712 switch_core_hash_init_case(&runtime.ptimes, SWITCH_FALSE);
1713 load_mime_types();
1714 runtime.flags |= flags;
1715 runtime.sps_total = 30;
1716
1717 *err = NULL((void*)0);
1718
1719 if (console) {
1720 runtime.console = stdoutstdout;
1721 }
1722
1723 SSL_library_init();
1724 switch_ssl_init_ssl_locks();
1725 switch_curl_init();
1726
1727 switch_core_set_variable("hostname", runtime.hostname);
1728 switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET2);
1729 switch_core_set_variable("local_ip_v4", guess_ip);
1730 in.s_addr = mask;
1731 switch_core_set_variable("local_mask_v4", inet_ntoa(in));
1732
1733
1734 switch_find_local_ip(guess_ip, sizeof(guess_ip), NULL((void*)0), AF_INET610);
1735 switch_core_set_variable("local_ip_v6", guess_ip);
1736 switch_core_set_variable("base_dir", SWITCH_GLOBAL_dirs.base_dir);
1737 switch_core_set_variable("recordings_dir", SWITCH_GLOBAL_dirs.recordings_dir);
1738 switch_core_set_variable("sound_prefix", SWITCH_GLOBAL_dirs.sounds_dir);
1739 switch_core_set_variable("sounds_dir", SWITCH_GLOBAL_dirs.sounds_dir);
1740 switch_core_set_variable("conf_dir", SWITCH_GLOBAL_dirs.conf_dir);
1741 switch_core_set_variable("log_dir", SWITCH_GLOBAL_dirs.log_dir);
1742 switch_core_set_variable("run_dir", SWITCH_GLOBAL_dirs.run_dir);
1743 switch_core_set_variable("db_dir", SWITCH_GLOBAL_dirs.db_dir);
1744 switch_core_set_variable("mod_dir", SWITCH_GLOBAL_dirs.mod_dir);
1745 switch_core_set_variable("htdocs_dir", SWITCH_GLOBAL_dirs.htdocs_dir);
1746 switch_core_set_variable("script_dir", SWITCH_GLOBAL_dirs.script_dir);
1747 switch_core_set_variable("temp_dir", SWITCH_GLOBAL_dirs.temp_dir);
1748 switch_core_set_variable("grammar_dir", SWITCH_GLOBAL_dirs.grammar_dir);
1749 switch_core_set_variable("certs_dir", SWITCH_GLOBAL_dirs.certs_dir);
1750 switch_core_set_variable("storage_dir", SWITCH_GLOBAL_dirs.storage_dir);
1751 switch_core_set_variable("cache_dir", SWITCH_GLOBAL_dirs.cache_dir);
1752#ifdef ENABLE_ZRTP
1753 switch_core_set_serial();
1754#endif
1755 switch_console_init(runtime.memory_pool);
1756 switch_event_init(runtime.memory_pool);
1757 switch_channel_global_init(runtime.memory_pool);
1758
1759 if (switch_xml_init(runtime.memory_pool, err) != SWITCH_STATUS_SUCCESS) {
1760 apr_terminate();
1761 return SWITCH_STATUS_MEMERR;
1762 }
1763
1764 if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)(((&runtime))->flags & SCF_USE_AUTO_NAT)) {
1765 switch_nat_init(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_NAT_MAPPING)(((&runtime))->flags & SCF_USE_NAT_MAPPING));
1766 }
1767
1768 switch_log_init(runtime.memory_pool, runtime.colorize_console);
1769
1770 runtime.tipping_point = 0;
1771 runtime.timer_affinity = -1;
1772 runtime.microseconds_per_tick = 20000;
1773
1774 if (flags & SCF_MINIMAL) return SWITCH_STATUS_SUCCESS;
1775
1776 switch_load_core_config("switch.conf");
1777
1778 switch_core_state_machine_init(runtime.memory_pool);
1779
1780 if (switch_core_sqldb_start(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_SQL)(((&runtime))->flags & SCF_USE_SQL) ? SWITCH_TRUE : SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) {
1781 *err = "Error activating database";
1782 return SWITCH_STATUS_FALSE;
1783 }
1784 switch_core_media_init();
1785 switch_scheduler_task_thread_start();
1786
1787 switch_nat_late_init();
1788
1789 switch_rtp_init(runtime.memory_pool);
1790
1791 runtime.running = 1;
1792 runtime.initiated = switch_mono_micro_time_now();
1793
1794 switch_scheduler_add_task(switch_epoch_time_now(NULL((void*)0)), heartbeat_callback, "heartbeat", "core", 0, NULL((void*)0), SSHF_NONE | SSHF_NO_DEL);
1795
1796 switch_scheduler_add_task(switch_epoch_time_now(NULL((void*)0)), check_ip_callback, "check_ip", "core", 0, NULL((void*)0), SSHF_NONE | SSHF_NO_DEL | SSHF_OWN_THREAD);
1797
1798 switch_uuid_get(&uuid);
1799 switch_uuid_format(runtime.uuid_str, &uuid);
1800 switch_core_set_variable("core_uuid", runtime.uuid_str);
1801
1802
1803 return SWITCH_STATUS_SUCCESS;
1804}
1805
1806
1807#ifndef WIN32
1808static void handle_SIGCHLD(int sig)
1809{
1810 int status = 0;
1811
1812 wait(&status);
1813 return;
1814}
1815#endif
1816
1817#ifdef TRAP_BUS
1818static void handle_SIGBUS(int sig)
1819{
1820 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1820, ((void*)0)
, SWITCH_LOG_DEBUG1, "Sig BUS!\n");
1821 return;
1822}
1823#endif
1824
1825static void handle_SIGHUP(int sig)
1826{
1827 if (sig) {
1828 switch_event_t *event;
1829
1830 if (switch_event_create(&event, SWITCH_EVENT_TRAP)switch_event_create_subclass_detailed("src/switch_core.c", (const
char * )(const char *)__func__, 1830, &event, SWITCH_EVENT_TRAP
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1831 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Trapped-Signal", "HUP");
1832 switch_event_fire(&event)switch_event_fire_detailed("src/switch_core.c", (const char *
)(const char *)__func__, 1832, &event, ((void*)0))
;
1833 }
1834 }
1835 return;
1836}
1837
1838
1839SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_default_ptime(const char *name, uint32_t number)
1840{
1841 uint32_t *p;
1842
1843 if ((p = switch_core_hash_find(runtime.ptimes, name))) {
1844 return *p;
1845 }
1846
1847 return 20;
1848}
1849
1850SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_default_rate(const char *name, uint32_t number)
1851{
1852
1853 if (!strcasecmp(name, "opus")) {
1854 return 48000;
1855 } else if (!strncasecmp(name, "h26", 3)) { // h26x
1856 return 90000;
1857 } else if (!strncasecmp(name, "vp", 2)) { // vp8, vp9
1858 return 90000;
1859 }
1860
1861 return 8000;
1862}
1863
1864static uint32_t d_30 = 30;
1865
1866static void switch_load_core_config(const char *file)
1867{
1868 switch_xml_t xml = NULL((void*)0), cfg = NULL((void*)0);
1869
1870 switch_core_hash_insert(runtime.ptimes, "ilbc", &d_30)switch_core_hash_insert_destructor(runtime.ptimes, "ilbc", &
d_30, ((void*)0))
;
1871 switch_core_hash_insert(runtime.ptimes, "isac", &d_30)switch_core_hash_insert_destructor(runtime.ptimes, "isac", &
d_30, ((void*)0))
;
1872 switch_core_hash_insert(runtime.ptimes, "G723", &d_30)switch_core_hash_insert_destructor(runtime.ptimes, "G723", &
d_30, ((void*)0))
;
1873
1874
1875 if ((xml = switch_xml_open_cfg(file, &cfg, NULL((void*)0)))) {
1876 switch_xml_t settings, param;
1877
1878 if ((settings = switch_xml_child(cfg, "default-ptimes"))) {
1879 for (param = switch_xml_child(settings, "codec"); param; param = param->next) {
1880 const char *var = switch_xml_attr_soft(param, "name");
1881 const char *val = switch_xml_attr_soft(param, "ptime");
1882
1883 if (!zstr(var)_zstr(var) && !zstr(val)_zstr(val)) {
1884 uint32_t *p;
1885 uint32_t v = switch_atoul(val);
1886
1887 if (!strcasecmp(var, "G723") || !strcasecmp(var, "iLBC")) {
1888 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1888, ((void*)0)
, SWITCH_LOG_CRIT, "Error adding %s, defaults cannot be changed\n", var);
1889 continue;
1890 }
1891
1892 if (v == 0) {
1893 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1893, ((void*)0)
, SWITCH_LOG_CRIT, "Error adding %s, invalid ptime\n", var);
1894 continue;
1895 }
1896
1897 p = switch_core_alloc(runtime.memory_pool, sizeof(*p))switch_core_perform_alloc(runtime.memory_pool, sizeof(*p), "src/switch_core.c"
, (const char *)__func__, 1897)
;
1898 *p = v;
1899 switch_core_hash_insert(runtime.ptimes, var, p)switch_core_hash_insert_destructor(runtime.ptimes, var, p, ((
void*)0))
;
1900 }
1901
1902 }
1903 }
1904
1905 if ((settings = switch_xml_child(cfg, "settings"))) {
1906 for (param = switch_xml_child(settings, "param"); param; param = param->next) {
1907 const char *var = switch_xml_attr_soft(param, "name");
1908 const char *val = switch_xml_attr_soft(param, "value");
1909
1910 if (!strcasecmp(var, "loglevel")) {
1911 int level;
1912 if (*val > 47 && *val < 58) {
1913 level = atoi(val);
1914 } else {
1915 level = switch_log_str2level(val);
1916 }
1917
1918 if (level != SWITCH_LOG_INVALID) {
1919 switch_core_session_ctl(SCSC_LOGLEVEL, &level);
1920 }
1921#ifdef HAVE_SETRLIMIT1
1922 } else if (!strcasecmp(var, "dump-cores") && switch_true(val)) {
1923 struct rlimit rlp;
1924 memset(&rlp, 0, sizeof(rlp));
1925 rlp.rlim_cur = RLIM_INFINITY((__rlim_t) -1);
1926 rlp.rlim_max = RLIM_INFINITY((__rlim_t) -1);
1927 setrlimit(RLIMIT_CORERLIMIT_CORE, &rlp);
1928#endif
1929 } else if (!strcasecmp(var, "debug-level")) {
1930 int tmp = atoi(val);
1931 if (tmp > -1 && tmp < 11) {
1932 switch_core_session_ctl(SCSC_DEBUG_LEVEL, &tmp);
1933 }
1934 } else if (!strcasecmp(var, "max-db-handles")) {
1935 long tmp = atol(val);
1936
1937 if (tmp > 4 && tmp < 5001) {
1938 runtime.max_db_handles = (uint32_t) tmp;
1939 } else {
1940 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1940, ((void*)0)
, SWITCH_LOG_ERROR, "max-db-handles must be between 5 and 5000\n");
1941 }
1942 } else if (!strcasecmp(var, "db-handle-timeout")) {
1943 long tmp = atol(val);
1944
1945 if (tmp > 0 && tmp < 5001) {
1946 runtime.db_handle_timeout = (uint32_t) tmp * 1000000;
1947 } else {
1948 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 1948, ((void*)0)
, SWITCH_LOG_ERROR, "db-handle-timeout must be between 1 and 5000\n");
1949 }
1950
1951 } else if (!strcasecmp(var, "multiple-registrations")) {
1952 runtime.multiple_registrations = switch_true(val);
1953 } else if (!strcasecmp(var, "auto-create-schemas")) {
1954 if (switch_true(val)) {
1955 switch_set_flag((&runtime), SCF_AUTO_SCHEMAS)((&runtime))->flags |= (SCF_AUTO_SCHEMAS);
1956 } else {
1957 switch_clear_flag((&runtime), SCF_AUTO_SCHEMAS)((&runtime))->flags &= ~(SCF_AUTO_SCHEMAS);
1958 }
1959 } else if (!strcasecmp(var, "session-thread-pool")) {
1960 if (switch_true(val)) {
1961 switch_set_flag((&runtime), SCF_SESSION_THREAD_POOL)((&runtime))->flags |= (SCF_SESSION_THREAD_POOL);
1962 } else {
1963 switch_clear_flag((&runtime), SCF_SESSION_THREAD_POOL)((&runtime))->flags &= ~(SCF_SESSION_THREAD_POOL);
1964 }
1965 } else if (!strcasecmp(var, "auto-clear-sql")) {
1966 if (switch_true(val)) {
1967 switch_set_flag((&runtime), SCF_CLEAR_SQL)((&runtime))->flags |= (SCF_CLEAR_SQL);
1968 } else {
1969 switch_clear_flag((&runtime), SCF_CLEAR_SQL)((&runtime))->flags &= ~(SCF_CLEAR_SQL);
1970 }
1971 } else if (!strcasecmp(var, "api-expansion")) {
1972 if (switch_true(val)) {
1973 switch_set_flag((&runtime), SCF_API_EXPANSION)((&runtime))->flags |= (SCF_API_EXPANSION);
1974 } else {
1975 switch_clear_flag((&runtime), SCF_API_EXPANSION)((&runtime))->flags &= ~(SCF_API_EXPANSION);
1976 }
1977 } else if (!strcasecmp(var, "enable-early-hangup") && switch_true(val)) {
1978 switch_set_flag((&runtime), SCF_EARLY_HANGUP)((&runtime))->flags |= (SCF_EARLY_HANGUP);
1979 } else if (!strcasecmp(var, "colorize-console") && switch_true(val)) {
1980 runtime.colorize_console = SWITCH_TRUE;
1981 } else if (!strcasecmp(var, "core-db-pre-trans-execute") && !zstr(val)_zstr(val)) {
1982 runtime.core_db_pre_trans_execute = switch_core_strdup(runtime.memory_pool, val)switch_core_perform_strdup(runtime.memory_pool, val, "src/switch_core.c"
, (const char *)__func__, 1982)
;
1983 } else if (!strcasecmp(var, "core-db-post-trans-execute") && !zstr(val)_zstr(val)) {
1984 runtime.core_db_post_trans_execute = switch_core_strdup(runtime.memory_pool, val)switch_core_perform_strdup(runtime.memory_pool, val, "src/switch_core.c"
, (const char *)__func__, 1984)
;
1985 } else if (!strcasecmp(var, "core-db-inner-pre-trans-execute") && !zstr(val)_zstr(val)) {
1986 runtime.core_db_inner_pre_trans_execute = switch_core_strdup(runtime.memory_pool, val)switch_core_perform_strdup(runtime.memory_pool, val, "src/switch_core.c"
, (const char *)__func__, 1986)
;
1987 } else if (!strcasecmp(var, "core-db-inner-post-trans-execute") && !zstr(val)_zstr(val)) {
1988 runtime.core_db_inner_post_trans_execute = switch_core_strdup(runtime.memory_pool, val)switch_core_perform_strdup(runtime.memory_pool, val, "src/switch_core.c"
, (const char *)__func__, 1988)
;
1989 } else if (!strcasecmp(var, "dialplan-timestamps")) {
1990 if (switch_true(val)) {
1991 switch_set_flag((&runtime), SCF_DIALPLAN_TIMESTAMPS)((&runtime))->flags |= (SCF_DIALPLAN_TIMESTAMPS);
1992 } else {
1993 switch_clear_flag((&runtime), SCF_DIALPLAN_TIMESTAMPS)((&runtime))->flags &= ~(SCF_DIALPLAN_TIMESTAMPS);
1994 }
1995 } else if (!strcasecmp(var, "mailer-app") && !zstr(val)_zstr(val)) {
1996 runtime.mailer_app = switch_core_strdup(runtime.memory_pool, val)switch_core_perform_strdup(runtime.memory_pool, val, "src/switch_core.c"
, (const char *)__func__, 1996)
;
1997 } else if (!strcasecmp(var, "mailer-app-args") && val) {
1998 runtime.mailer_app_args = switch_core_strdup(runtime.memory_pool, val)switch_core_perform_strdup(runtime.memory_pool, val, "src/switch_core.c"
, (const char *)__func__, 1998)
;
1999 } else if (!strcasecmp(var, "sessions-per-second") && !zstr(val)_zstr(val)) {
2000 switch_core_sessions_per_second(atoi(val));
2001 } else if (!strcasecmp(var, "max-dtmf-duration") && !zstr(val)_zstr(val)) {
2002 int tmp = atoi(val);
2003 if (tmp > 0) {
2004 switch_core_max_dtmf_duration((uint32_t) tmp);
2005 }
2006 } else if (!strcasecmp(var, "min-dtmf-duration") && !zstr(val)_zstr(val)) {
2007 int tmp = atoi(val);
2008 if (tmp > 0) {
2009 switch_core_min_dtmf_duration((uint32_t) tmp);
2010 }
2011 } else if (!strcasecmp(var, "default-dtmf-duration") && !zstr(val)_zstr(val)) {
2012 int tmp = atoi(val);
2013 if (tmp > 0) {
2014 switch_core_default_dtmf_duration((uint32_t) tmp);
2015 }
2016 } else if (!strcasecmp(var, "enable-use-system-time")) {
2017 switch_time_set_use_system_time(switch_true(val));
2018 } else if (!strcasecmp(var, "enable-monotonic-timing")) {
2019 switch_time_set_monotonic(switch_true(val));
2020 } else if (!strcasecmp(var, "enable-softtimer-timerfd")) {
2021 int ival = 0;
2022 if (val) {
2023 if (switch_true(val)) {
2024 ival = 2;
2025 } else {
2026 if (strcasecmp(val, "broadcast")) {
2027 ival = 1;
2028 } else if (strcasecmp(val, "fd-per-timer")) {
2029 ival = 2;
2030 }
2031 }
2032 }
2033 switch_time_set_timerfd(ival);
2034 } else if (!strcasecmp(var, "enable-clock-nanosleep")) {
2035 switch_time_set_nanosleep(switch_true(val));
2036 } else if (!strcasecmp(var, "enable-cond-yield")) {
2037 switch_time_set_cond_yield(switch_true(val));
2038 } else if (!strcasecmp(var, "enable-timer-matrix")) {
2039 switch_time_set_matrix(switch_true(val));
2040 } else if (!strcasecmp(var, "max-sessions") && !zstr(val)_zstr(val)) {
2041 switch_core_session_limit(atoi(val));
2042 } else if (!strcasecmp(var, "verbose-channel-events") && !zstr(val)_zstr(val)) {
2043 int v = switch_true(val);
2044 if (v) {
2045 switch_set_flag((&runtime), SCF_VERBOSE_EVENTS)((&runtime))->flags |= (SCF_VERBOSE_EVENTS);
2046 } else {
2047 switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS)((&runtime))->flags &= ~(SCF_VERBOSE_EVENTS);
2048 }
2049 } else if (!strcasecmp(var, "threaded-system-exec") && !zstr(val)_zstr(val)) {
2050#ifdef WIN32
2051 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2051, ((void*)0)
, SWITCH_LOG_WARNING, "threaded-system-exec is not implemented on this platform\n");
2052#else
2053 int v = switch_true(val);
2054 if (v) {
2055 switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC)((&runtime))->flags |= (SCF_THREADED_SYSTEM_EXEC);
2056 } else {
2057 switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC)((&runtime))->flags &= ~(SCF_THREADED_SYSTEM_EXEC);
2058 }
2059#endif
2060 } else if (!strcasecmp(var, "min-idle-cpu") && !zstr(val)_zstr(val)) {
2061 switch_core_min_idle_cpu(atof(val));
2062 } else if (!strcasecmp(var, "tipping-point") && !zstr(val)_zstr(val)) {
2063 runtime.tipping_point = atoi(val);
2064 } else if (!strcasecmp(var, "cpu-idle-smoothing-depth") && !zstr(val)_zstr(val)) {
2065 runtime.cpu_idle_smoothing_depth = atoi(val);
2066 } else if (!strcasecmp(var, "events-use-dispatch") && !zstr(val)_zstr(val)) {
2067 runtime.events_use_dispatch = switch_true(val);
2068 } else if (!strcasecmp(var, "initial-event-threads") && !zstr(val)_zstr(val)) {
2069 int tmp;
2070
2071 if (!runtime.events_use_dispatch) {
2072 runtime.events_use_dispatch = 1;
2073 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2073, ((void*)0)
, SWITCH_LOG_WARNING,
2074 "Implicitly setting events-use-dispatch based on usage of this initial-event-threads parameter.\n");
2075 }
2076
2077 tmp = atoi(val);
2078
2079 if (tmp > runtime.cpu_count / 2) {
2080 tmp = runtime.cpu_count / 2;
2081 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2081, ((void*)0)
, SWITCH_LOG_WARNING, "This value cannot be higher than %d so setting it to that value\n",
2082 runtime.cpu_count / 2);
2083 }
2084
2085 if (tmp < 1) {
2086 tmp = 1;
2087 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2087, ((void*)0)
, SWITCH_LOG_WARNING, "This value cannot be lower than 1 so setting it to that level\n");
2088 }
2089
2090 switch_event_launch_dispatch_threads(tmp);
2091
2092 } else if (!strcasecmp(var, "1ms-timer") && switch_true(val)) {
2093 runtime.microseconds_per_tick = 1000;
2094 } else if (!strcasecmp(var, "timer-affinity") && !zstr(val)_zstr(val)) {
2095 if (!strcasecmp(val, "disabled")) {
2096 runtime.timer_affinity = -1;
2097 } else {
2098 runtime.timer_affinity = atoi(val);
2099 }
2100 } else if (!strcasecmp(var, "rtp-start-port") && !zstr(val)_zstr(val)) {
2101 switch_rtp_set_start_port((switch_port_t) atoi(val));
2102 } else if (!strcasecmp(var, "rtp-end-port") && !zstr(val)_zstr(val)) {
2103 switch_rtp_set_end_port((switch_port_t) atoi(val));
2104 } else if (!strcasecmp(var, "rtp-port-usage-robustness") && switch_true(val)) {
2105 runtime.port_alloc_flags |= SPF_ROBUST_UDP;
2106 } else if (!strcasecmp(var, "core-db-name") && !zstr(val)_zstr(val)) {
2107 runtime.dbname = switch_core_strdup(runtime.memory_pool, val)switch_core_perform_strdup(runtime.memory_pool, val, "src/switch_core.c"
, (const char *)__func__, 2107)
;
2108 } else if (!strcasecmp(var, "core-db-dsn") && !zstr(val)_zstr(val)) {
2109 if (switch_odbc_available() || switch_pgsql_available()) {
2110 runtime.odbc_dsn = switch_core_strdup(runtime.memory_pool, val)switch_core_perform_strdup(runtime.memory_pool, val, "src/switch_core.c"
, (const char *)__func__, 2110)
;
2111 } else {
2112 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2112, ((void*)0)
, SWITCH_LOG_ERROR, "ODBC AND PGSQL ARE NOT AVAILABLE!\n");
2113 }
2114 } else if (!strcasecmp(var, "core-non-sqlite-db-required") && !zstr(val)_zstr(val)) {
2115 switch_set_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ)((&runtime))->flags |= (SCF_CORE_NON_SQLITE_DB_REQ);
2116 } else if (!strcasecmp(var, "core-dbtype") && !zstr(val)_zstr(val)) {
2117 if (!strcasecmp(val, "MSSQL")) {
2118 runtime.odbc_dbtype = DBTYPE_MSSQL;
2119 } else {
2120 runtime.odbc_dbtype = DBTYPE_DEFAULT;
2121 }
2122#ifdef ENABLE_ZRTP
2123 } else if (!strcasecmp(var, "rtp-enable-zrtp")) {
2124 switch_core_set_variable("zrtp_enabled", val);
2125#endif
2126 } else if (!strcasecmp(var, "switchname") && !zstr(val)_zstr(val)) {
2127 runtime.switchname = switch_core_strdup(runtime.memory_pool, val)switch_core_perform_strdup(runtime.memory_pool, val, "src/switch_core.c"
, (const char *)__func__, 2127)
;
2128 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2128, ((void*)0)
, SWITCH_LOG_NOTICE, "Set switchname to %s\n", runtime.switchname);
2129 }
2130 }
2131 }
2132
2133 if ((settings = switch_xml_child(cfg, "variables"))) {
2134 for (param = switch_xml_child(settings, "variable"); param; param = param->next) {
2135 const char *var = switch_xml_attr_soft(param, "name");
2136 const char *val = switch_xml_attr_soft(param, "value");
2137 if (var && val) {
2138 switch_core_set_variable(var, val);
2139 }
2140 }
2141 }
2142
2143 switch_xml_free(xml);
2144 }
2145
2146
2147}
2148
2149SWITCH_DECLARE(const char *)__attribute__((visibility("default"))) const char * switch_core_banner(void)
2150{
2151
2152 return ("\n"
2153 ".=============================================================.\n"
2154 "| _____ ______ _____ _____ ____ _ _ |\n"
2155 "| | ___| __ ___ ___/ ___\\ \\ / /_ _|_ _/ ___| | | | |\n"
2156 "| | |_ | '__/ _ \\/ _ \\___ \\\\ \\ /\\ / / | | | || | | |_| | |\n"
2157 "| | _|| | | __/ __/___) |\\ V V / | | | || |___| _ | |\n"
2158 "| |_| |_| \\___|\\___|____/ \\_/\\_/ |___| |_| \\____|_| |_| |\n"
2159 "| |\n"
2160 ".=============================================================."
2161 "\n"
2162
2163 "| Anthony Minessale II, Michael Jerris, Brian West, Others |\n"
2164 "| FreeSWITCH (http://www.freeswitch.org) |\n"
2165 "| Paypal Donations Appreciated: paypal@freeswitch.org |\n"
2166 "| Brought to you by ClueCon http://www.cluecon.com/ |\n"
2167 ".=============================================================.\n"
2168 "\n");
2169}
2170
2171
2172SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_init_and_modload(switch_core_flag_t flags, switch_bool_t console, const char **err)
2173{
2174 switch_event_t *event;
2175 char *cmd;
2176 int x = 0;
2177 const char *use = NULL((void*)0);
2178#include "cc.h"
2179
2180
2181 if (switch_core_init(flags, console, err) != SWITCH_STATUS_SUCCESS) {
2182 return SWITCH_STATUS_GENERR;
2183 }
2184
2185 if (runtime.runlevel > 1) {
2186 /* one per customer */
2187 return SWITCH_STATUS_SUCCESS;
2188 }
2189
2190 runtime.runlevel++;
2191 runtime.events_use_dispatch = 1;
2192
2193 switch_core_set_signal_handlers();
2194 switch_load_network_lists(SWITCH_FALSE);
2195
2196 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2196, ((void*)0)
, SWITCH_LOG_CONSOLE, "Bringing up environment.\n");
2197 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2197, ((void*)0)
, SWITCH_LOG_CONSOLE, "Loading Modules.\n");
2198 if (switch_loadable_module_init(SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
2199 *err = "Cannot load modules";
2200 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2200, ((void*)0)
, SWITCH_LOG_CONSOLE, "Error: %s\n", *err);
2201 return SWITCH_STATUS_GENERR;
2202 }
2203
2204 switch_load_network_lists(SWITCH_FALSE);
2205
2206 switch_load_core_config("post_load_switch.conf");
2207
2208 switch_core_set_signal_handlers();
2209
2210 if (switch_event_create(&event, SWITCH_EVENT_STARTUP)switch_event_create_subclass_detailed("src/switch_core.c", (const
char * )(const char *)__func__, 2210, &event, SWITCH_EVENT_STARTUP
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
2211 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready");
2212 switch_event_fire(&event)switch_event_fire_detailed("src/switch_core.c", (const char *
)(const char *)__func__, 2212, &event, ((void*)0))
;
2213 }
2214
2215 switch_core_screen_size(&x, NULL((void*)0));
2216
2217 use = (x > 100) ? cc : cc_s;
2218
2219#ifdef WIN32
2220 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2220, ((void*)0)
, SWITCH_LOG_CONSOLE, "%s%s\n\n", switch_core_banner(), use);
2221#else
2222 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2222, ((void*)0)
, SWITCH_LOG_CONSOLE, "%s%s%s%s%s%s\n\n",
2223 SWITCH_SEQ_DEFAULT_COLOR"\033[" "m",
2224 SWITCH_SEQ_FYELLOW"\033[" "33" "m", SWITCH_SEQ_BBLUE"\033[" "44" "m",
2225 switch_core_banner(),
2226 use, SWITCH_SEQ_DEFAULT_COLOR"\033[" "m");
2227
2228#endif
2229
2230
2231 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2231, ((void*)0)
, SWITCH_LOG_INFO,
2232 "\nFreeSWITCH Version %s (%s)\n\nFreeSWITCH Started\nMax Sessions [%u]\nSession Rate [%d]\nSQL [%s]\n",
2233 switch_version_full(), switch_version_revision_human(),
2234 switch_core_session_limit(0),
2235 switch_core_sessions_per_second(0), switch_test_flag((&runtime), SCF_USE_SQL)(((&runtime))->flags & SCF_USE_SQL) ? "Enabled" : "Disabled");
2236
2237
2238 if (x < 160) {
2239 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2239, ((void*)0)
, SWITCH_LOG_CONSOLE, "\n[This app Best viewed at 160x60 or more..]\n");
2240 }
2241
2242 switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS)((&runtime))->flags &= ~(SCF_NO_NEW_SESSIONS);
2243
2244 if ((cmd = switch_core_get_variable_dup("api_on_startup"))) {
2245 switch_stream_handle_t stream = { 0 };
2246 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "src/switch_core.c", 2246, __PRETTY_FUNCTION__)); memset(stream
.data, 0, 1024); stream.end = stream.data; stream.data_size =
1024; stream.write_function = switch_console_stream_write; stream
.raw_write_function = switch_console_stream_raw_write; stream
.alloc_len = 1024; stream.alloc_chunk = 1024
;
2247 switch_console_execute(cmd, 0, &stream);
2248 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2248, ((void*)0)
, SWITCH_LOG_CONSOLE, "Startup command [%s] executed. Output:\n%s\n", cmd, (char *)stream.data);
2249 free(stream.data);
2250 free(cmd);
2251 }
2252
2253 return SWITCH_STATUS_SUCCESS;
2254
2255}
2256
2257SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_measure_time(switch_time_t total_ms, switch_core_time_duration_t *duration)
2258{
2259 switch_time_t temp = total_ms / 1000;
2260 memset(duration, 0, sizeof(*duration));
2261 duration->mms = (uint32_t) (total_ms % 1000);
2262 duration->ms = (uint32_t) (temp % 1000);
2263 temp = temp / 1000;
2264 duration->sec = (uint32_t) (temp % 60);
2265 temp = temp / 60;
2266 duration->min = (uint32_t) (temp % 60);
2267 temp = temp / 60;
2268 duration->hr = (uint32_t) (temp % 24);
2269 temp = temp / 24;
2270 duration->day = (uint32_t) (temp % 365);
2271 duration->yr = (uint32_t) (temp / 365);
2272}
2273
2274SWITCH_DECLARE(switch_time_t)__attribute__((visibility("default"))) switch_time_t switch_core_uptime(void)
2275{
2276 return switch_mono_micro_time_now() - runtime.initiated;
2277}
2278
2279
2280#ifdef _MSC_VER
2281static void win_shutdown(void)
2282{
2283
2284 HANDLE shutdown_event;
2285 char path[512];
2286 /* for windows we need the event to signal for shutting down a background FreeSWITCH */
2287 snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid());
2288
2289 /* open the event so we can signal it */
2290 shutdown_event = OpenEvent(EVENT_MODIFY_STATE, FALSE0, path);
2291
2292 if (shutdown_event) {
2293 /* signal the event to shutdown */
2294 SetEvent(shutdown_event);
2295 /* cleanup */
2296 CloseHandle(shutdown_event);
2297 }
2298}
2299#endif
2300
2301SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_set_signal_handlers(void)
2302{
2303 /* set signal handlers */
2304 signal(SIGINT2, SIG_IGN((__sighandler_t) 1));
2305#ifndef WIN32
2306 if (switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC)(((&runtime))->flags & SCF_THREADED_SYSTEM_EXEC)) {
2307 signal(SIGCHLD17, SIG_DFL((__sighandler_t) 0));
2308 } else {
2309 signal(SIGCHLD17, handle_SIGCHLD);
2310 }
2311#endif
2312#ifdef SIGPIPE13
2313 signal(SIGPIPE13, SIG_IGN((__sighandler_t) 1));
2314#endif
2315#ifdef SIGALRM14
2316 signal(SIGALRM14, SIG_IGN((__sighandler_t) 1));
2317#endif
2318#ifdef SIGQUIT3
2319 signal(SIGQUIT3, SIG_IGN((__sighandler_t) 1));
2320#endif
2321#ifdef SIGPOLL29
2322 signal(SIGPOLL29, SIG_IGN((__sighandler_t) 1));
2323#endif
2324#ifdef SIGIO29
2325 signal(SIGIO29, SIG_IGN((__sighandler_t) 1));
2326#endif
2327#ifdef TRAP_BUS
2328 signal(SIGBUS7, handle_SIGBUS);
2329#endif
2330#ifdef SIGUSR110
2331 signal(SIGUSR110, handle_SIGHUP);
2332#endif
2333 signal(SIGHUP1, handle_SIGHUP);
2334}
2335
2336SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_debug_level(void)
2337{
2338 return runtime.debug_level;
2339}
2340
2341
2342SWITCH_DECLARE(int32_t)__attribute__((visibility("default"))) int32_t switch_core_session_ctl(switch_session_ctl_t cmd, void *val)
2343{
2344 int *intval = (int *) val;
2345 int oldintval = 0, newintval = 0;
2346
2347 if (intval) {
2348 oldintval = *intval;
2349 }
2350
2351 if (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)(((&runtime))->flags & SCF_SHUTTING_DOWN)) {
2352 return -1;
2353 }
2354
2355 switch (cmd) {
2356 case SCSC_RECOVER:
2357 {
2358 char *arg = (char *) val;
2359 char *tech = NULL((void*)0), *prof = NULL((void*)0);
2360 int r, flush = 0;
2361
2362 if (!zstr(arg)_zstr(arg)) {
2363 tech = strdup(arg)(__extension__ (__builtin_constant_p (arg) && ((size_t
)(const void *)((arg) + 1) - (size_t)(const void *)(arg) == 1
) ? (((const char *) (arg))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (arg) + 1; char *
__retval = (char *) malloc (__len); if (__retval != ((void*)0
)) __retval = (char *) memcpy (__retval, arg, __len); __retval
; })) : __strdup (arg)))
;
2364
2365 if ((prof = strchr(tech, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(tech) && (':') == '\0' ? (char *) __rawmemchr (tech
, ':') : __builtin_strchr (tech, ':')))
)) {
2366 *prof++ = '\0';
2367 }
2368
2369 if (!strcasecmp(tech, "flush")) {
2370 flush++;
2371
2372 if (prof) {
2373 tech = prof;
2374 if ((prof = strchr(tech, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(tech) && (':') == '\0' ? (char *) __rawmemchr (tech
, ':') : __builtin_strchr (tech, ':')))
)) {
2375 *prof++ = '\0';
2376 }
2377 }
2378 }
2379
2380 }
2381
2382 if (flush) {
2383 switch_core_recovery_flush(tech, prof);
2384 r = -1;
2385 } else {
2386 r = switch_core_recovery_recover(tech, prof);
2387 }
2388
2389 switch_safe_free(tech)if (tech) {free(tech);tech=((void*)0);};
2390 return r;
2391
2392 }
2393 break;
2394 case SCSC_DEBUG_SQL:
2395 {
2396 if (switch_test_flag((&runtime), SCF_DEBUG_SQL)(((&runtime))->flags & SCF_DEBUG_SQL)) {
2397 switch_clear_flag((&runtime), SCF_DEBUG_SQL)((&runtime))->flags &= ~(SCF_DEBUG_SQL);
2398 newintval = 0;
2399 } else {
2400 switch_set_flag((&runtime), SCF_DEBUG_SQL)((&runtime))->flags |= (SCF_DEBUG_SQL);
2401 newintval = 1;
2402 }
2403 }
2404 break;
2405 case SCSC_VERBOSE_EVENTS:
2406 if (intval) {
2407 if (oldintval > -1) {
2408 if (oldintval) {
2409 switch_set_flag((&runtime), SCF_VERBOSE_EVENTS)((&runtime))->flags |= (SCF_VERBOSE_EVENTS);
2410 } else {
2411 switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS)((&runtime))->flags &= ~(SCF_VERBOSE_EVENTS);
2412 }
2413 }
2414 newintval = switch_test_flag((&runtime), SCF_VERBOSE_EVENTS)(((&runtime))->flags & SCF_VERBOSE_EVENTS);
2415 }
2416 break;
2417 case SCSC_API_EXPANSION:
2418 if (intval) {
2419 if (oldintval > -1) {
2420 if (oldintval) {
2421 switch_set_flag((&runtime), SCF_API_EXPANSION)((&runtime))->flags |= (SCF_API_EXPANSION);
2422 } else {
2423 switch_clear_flag((&runtime), SCF_API_EXPANSION)((&runtime))->flags &= ~(SCF_API_EXPANSION);
2424 }
2425 }
2426 newintval = switch_test_flag((&runtime), SCF_API_EXPANSION)(((&runtime))->flags & SCF_API_EXPANSION);
2427 }
2428 break;
2429 case SCSC_THREADED_SYSTEM_EXEC:
2430 if (intval) {
2431 if (oldintval > -1) {
2432 if (oldintval) {
2433 switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC)((&runtime))->flags |= (SCF_THREADED_SYSTEM_EXEC);
2434 } else {
2435 switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC)((&runtime))->flags &= ~(SCF_THREADED_SYSTEM_EXEC);
2436 }
2437 }
2438 newintval = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC)(((&runtime))->flags & SCF_THREADED_SYSTEM_EXEC);
2439 }
2440 break;
2441 case SCSC_CALIBRATE_CLOCK:
2442 switch_time_calibrate_clock();
2443 break;
2444 case SCSC_FLUSH_DB_HANDLES:
2445 switch_cache_db_flush_handles();
2446 break;
2447 case SCSC_SEND_SIGHUP:
2448 handle_SIGHUP(1);
2449 break;
2450 case SCSC_SYNC_CLOCK:
2451 switch_time_sync();
2452 newintval = 0;
2453 break;
2454 case SCSC_SYNC_CLOCK_WHEN_IDLE:
2455 newintval = switch_core_session_sync_clock();
2456 break;
2457 case SCSC_SQL:
2458 if (oldintval) {
2459 switch_core_sqldb_resume();
2460 } else {
2461 switch_core_sqldb_pause();
2462 }
2463 break;
2464 case SCSC_PAUSE_ALL:
2465 if (oldintval) {
2466 switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS)((&runtime))->flags |= (SCF_NO_NEW_SESSIONS);
2467 } else {
2468 switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS)((&runtime))->flags &= ~(SCF_NO_NEW_SESSIONS);
2469 }
2470 break;
2471 case SCSC_PAUSE_INBOUND:
2472 if (oldintval) {
2473 switch_set_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS)((&runtime))->flags |= (SCF_NO_NEW_INBOUND_SESSIONS);
2474 } else {
2475 switch_clear_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS)((&runtime))->flags &= ~(SCF_NO_NEW_INBOUND_SESSIONS
)
;
2476 }
2477 break;
2478 case SCSC_PAUSE_OUTBOUND:
2479 if (oldintval) {
2480 switch_set_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS)((&runtime))->flags |= (SCF_NO_NEW_OUTBOUND_SESSIONS);
2481 } else {
2482 switch_clear_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS)((&runtime))->flags &= ~(SCF_NO_NEW_OUTBOUND_SESSIONS
)
;
2483 }
2484 break;
2485 case SCSC_HUPALL:
2486 switch_core_session_hupall(SWITCH_CAUSE_MANAGER_REQUEST);
2487 break;
2488 case SCSC_CANCEL_SHUTDOWN:
2489 switch_clear_flag((&runtime), SCF_SHUTDOWN_REQUESTED)((&runtime))->flags &= ~(SCF_SHUTDOWN_REQUESTED);
2490 break;
2491 case SCSC_SAVE_HISTORY:
2492 switch_console_save_history();
2493 break;
2494 case SCSC_CRASH:
2495 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2495, ((void*)0)
, SWITCH_LOG_CRIT, "Declinatio Mortuus Obfirmo!\n");
2496 switch_console_save_history();
2497 abort();
2498 break;
2499 case SCSC_SHUTDOWN_NOW:
2500 switch_console_save_history();
2501 exit(0);
2502 break;
2503 case SCSC_REINCARNATE_NOW:
2504 switch_console_save_history();
2505 exit(SWITCH_STATUS_RESTART);
2506 break;
2507 case SCSC_SHUTDOWN_ELEGANT:
2508 case SCSC_SHUTDOWN_ASAP:
2509 {
2510 int x = 19;
2511 uint32_t count;
2512
2513 switch_set_flag((&runtime), SCF_SHUTDOWN_REQUESTED)((&runtime))->flags |= (SCF_SHUTDOWN_REQUESTED);
2514 if (cmd == SCSC_SHUTDOWN_ASAP) {
2515 switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS)((&runtime))->flags |= (SCF_NO_NEW_SESSIONS);
2516 }
2517
2518 while (runtime.running && switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED)(((&runtime))->flags & SCF_SHUTDOWN_REQUESTED) && (count = switch_core_session_count())) {
2519 switch_yield(500000)switch_sleep(500000);;
2520 if (++x == 20) {
2521 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2521, ((void*)0)
, SWITCH_LOG_WARNING,
2522 "Shutdown in progress, %u session(s) remain.\nShutting down %s\n",
2523 count, cmd == SCSC_SHUTDOWN_ASAP ? "ASAP" : "once there are no active calls.");
2524 x = 0;
2525 }
2526 }
2527
2528 if (switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED)(((&runtime))->flags & SCF_SHUTDOWN_REQUESTED)) {
2529 switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS)((&runtime))->flags |= (SCF_NO_NEW_SESSIONS);
2530#ifdef _MSC_VER
2531 win_shutdown();
2532#endif
2533
2534 if (oldintval) {
2535 switch_set_flag((&runtime), SCF_RESTART)((&runtime))->flags |= (SCF_RESTART);
2536 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2536, ((void*)0)
, SWITCH_LOG_INFO, "Restarting\n");
2537 } else {
2538 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2538, ((void*)0)
, SWITCH_LOG_INFO, "Shutting down\n");
2539#ifdef _MSC_VER
2540 fclose(stdinstdin);
2541#endif
2542 }
2543 runtime.running = 0;
2544 } else {
2545 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2545, ((void*)0)
, SWITCH_LOG_INFO, "Shutdown Cancelled\n");
2546 switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS)((&runtime))->flags &= ~(SCF_NO_NEW_SESSIONS);
2547 }
2548 }
2549 break;
2550 case SCSC_PAUSE_CHECK:
2551 newintval = !!(switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS)(((&runtime))->flags & SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS);
2552 break;
2553 case SCSC_PAUSE_INBOUND_CHECK:
2554 newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS)(((&runtime))->flags & SCF_NO_NEW_INBOUND_SESSIONS
)
;
2555 break;
2556 case SCSC_PAUSE_OUTBOUND_CHECK:
2557 newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS)(((&runtime))->flags & SCF_NO_NEW_OUTBOUND_SESSIONS
)
;
2558 break;
2559 case SCSC_READY_CHECK:
2560 newintval = switch_core_ready();
2561 break;
2562 case SCSC_SHUTDOWN_CHECK:
2563 newintval = !!switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED)(((&runtime))->flags & SCF_SHUTDOWN_REQUESTED);
2564 break;
2565 case SCSC_SHUTDOWN:
2566
2567#ifdef _MSC_VER
2568 win_shutdown();
2569#endif
2570
2571 if (oldintval) {
2572 switch_set_flag((&runtime), SCF_RESTART)((&runtime))->flags |= (SCF_RESTART);
2573 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2573, ((void*)0)
, SWITCH_LOG_INFO, "Restarting\n");
2574 } else {
2575 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2575, ((void*)0)
, SWITCH_LOG_INFO, "Shutting down\n");
2576#ifdef _MSC_VER
2577 fclose(stdinstdin);
2578#endif
2579 }
2580 runtime.running = 0;
2581 break;
2582 case SCSC_CHECK_RUNNING:
2583 newintval = runtime.running;
2584 break;
2585 case SCSC_LOGLEVEL:
2586 if (oldintval > -1) {
2587 runtime.hard_log_level = oldintval;
2588 }
2589
2590 if (runtime.hard_log_level > SWITCH_LOG_DEBUG) {
2591 runtime.hard_log_level = SWITCH_LOG_DEBUG;
2592 }
2593 newintval = runtime.hard_log_level;
2594 break;
2595 case SCSC_DEBUG_LEVEL:
2596 if (oldintval > -1) {
2597 if (oldintval > 10)
2598 newintval = 10;
2599 runtime.debug_level = oldintval;
2600 }
2601 newintval = runtime.debug_level;
2602 break;
2603 case SCSC_MIN_IDLE_CPU:
2604 {
2605 double *dval = (double *) val;
2606 if (dval) {
2607 *dval = switch_core_min_idle_cpu(*dval);
2608 }
2609 intval = NULL((void*)0);
2610 }
2611 break;
2612 case SCSC_MAX_SESSIONS:
2613 newintval = switch_core_session_limit(oldintval);
2614 break;
2615 case SCSC_LAST_SPS:
2616 newintval = runtime.sps_last;
2617 break;
2618 case SCSC_SPS_PEAK:
2619 if (oldintval == -1) {
2620 runtime.sps_peak = 0;
2621 }
2622 newintval = runtime.sps_peak;
2623 break;
2624 case SCSC_SPS_PEAK_FIVEMIN:
2625 newintval = runtime.sps_peak_fivemin;
2626 break;
2627 case SCSC_SESSIONS_PEAK:
2628 newintval = runtime.sessions_peak;
2629 break;
2630 case SCSC_SESSIONS_PEAK_FIVEMIN:
2631 newintval = runtime.sessions_peak_fivemin;
2632 break;
2633 case SCSC_MAX_DTMF_DURATION:
2634 newintval = switch_core_max_dtmf_duration(oldintval);
2635 break;
2636 case SCSC_MIN_DTMF_DURATION:
2637 newintval = switch_core_min_dtmf_duration(oldintval);
2638 break;
2639 case SCSC_DEFAULT_DTMF_DURATION:
2640 newintval = switch_core_default_dtmf_duration(oldintval);
2641 break;
2642 case SCSC_SPS:
2643 switch_mutex_lock(runtime.throttle_mutex);
2644 if (oldintval > 0) {
2645 runtime.sps_total = oldintval;
2646 }
2647 newintval = runtime.sps_total;
2648 switch_mutex_unlock(runtime.throttle_mutex);
2649 break;
2650
2651 case SCSC_RECLAIM:
2652 switch_core_memory_reclaim_all();
2653 newintval = 0;
2654 break;
2655 }
2656
2657 if (intval) {
2658 *intval = newintval;
2659 }
2660
2661
2662 return 0;
2663}
2664
2665SWITCH_DECLARE(switch_core_flag_t)__attribute__((visibility("default"))) switch_core_flag_t switch_core_flags(void)
2666{
2667 return runtime.flags;
2668}
2669
2670SWITCH_DECLARE(switch_bool_t)__attribute__((visibility("default"))) switch_bool_t switch_core_running(void)
2671{
2672 return runtime.running ? SWITCH_TRUE : SWITCH_FALSE;
2673}
2674
2675SWITCH_DECLARE(switch_bool_t)__attribute__((visibility("default"))) switch_bool_t switch_core_ready(void)
2676{
2677 return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)(((&runtime))->flags & SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS)(((&runtime))->flags & SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS) ? SWITCH_FALSE : SWITCH_TRUE;
2678}
2679
2680SWITCH_DECLARE(switch_bool_t)__attribute__((visibility("default"))) switch_bool_t switch_core_ready_inbound(void)
2681{
2682 return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)(((&runtime))->flags & SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS)(((&runtime))->flags & SCF_NO_NEW_INBOUND_SESSIONS
)
) ? SWITCH_FALSE : SWITCH_TRUE;
2683}
2684
2685SWITCH_DECLARE(switch_bool_t)__attribute__((visibility("default"))) switch_bool_t switch_core_ready_outbound(void)
2686{
2687 return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)(((&runtime))->flags & SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS)(((&runtime))->flags & SCF_NO_NEW_OUTBOUND_SESSIONS
)
) ? SWITCH_FALSE : SWITCH_TRUE;
2688}
2689
2690SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_destroy(void)
2691{
2692 switch_event_t *event;
2693
2694 if (switch_event_create(&event, SWITCH_EVENT_SHUTDOWN)switch_event_create_subclass_detailed("src/switch_core.c", (const
char * )(const char *)__func__, 2694, &event, SWITCH_EVENT_SHUTDOWN
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
2695 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Shutting Down");
2696 switch_event_fire(&event)switch_event_fire_detailed("src/switch_core.c", (const char *
)(const char *)__func__, 2696, &event, ((void*)0))
;
2697 }
2698
2699 switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS)((&runtime))->flags |= (SCF_NO_NEW_SESSIONS);
2700 switch_set_flag((&runtime), SCF_SHUTTING_DOWN)((&runtime))->flags |= (SCF_SHUTTING_DOWN);
2701
2702 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2702, ((void*)0)
, SWITCH_LOG_CONSOLE, "End existing sessions\n");
2703 switch_core_session_hupall(SWITCH_CAUSE_SYSTEM_SHUTDOWN);
2704 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2704, ((void*)0)
, SWITCH_LOG_CONSOLE, "Clean up modules.\n");
2705
2706 switch_loadable_module_shutdown();
2707
2708 switch_ssl_destroy_ssl_locks();
2709
2710 if (switch_test_flag((&runtime), SCF_USE_SQL)(((&runtime))->flags & SCF_USE_SQL)) {
2711 switch_core_sqldb_stop();
2712 }
2713 switch_scheduler_task_thread_stop();
2714
2715 switch_rtp_shutdown();
2716
2717 if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)(((&runtime))->flags & SCF_USE_AUTO_NAT)) {
2718 switch_nat_shutdown();
2719 }
2720 switch_xml_destroy();
2721 switch_console_shutdown();
2722 switch_channel_global_uninit();
2723
2724 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2724, ((void*)0)
, SWITCH_LOG_CONSOLE, "Closing Event Engine.\n");
2725 switch_event_shutdown();
2726
2727 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2727, ((void*)0)
, SWITCH_LOG_CONSOLE, "Finalizing Shutdown.\n");
2728 switch_log_shutdown();
2729
2730 switch_core_session_uninit();
2731 switch_core_unset_variables();
2732 switch_core_memory_stop();
2733
2734 if (runtime.console && runtime.console != stdoutstdout && runtime.console != stderrstderr) {
2735 fclose(runtime.console);
2736 runtime.console = NULL((void*)0);
2737 }
2738
2739 switch_safe_free(SWITCH_GLOBAL_dirs.base_dir)if (SWITCH_GLOBAL_dirs.base_dir) {free(SWITCH_GLOBAL_dirs.base_dir
);SWITCH_GLOBAL_dirs.base_dir=((void*)0);}
;
2740 switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir)if (SWITCH_GLOBAL_dirs.mod_dir) {free(SWITCH_GLOBAL_dirs.mod_dir
);SWITCH_GLOBAL_dirs.mod_dir=((void*)0);}
;
2741 switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir)if (SWITCH_GLOBAL_dirs.conf_dir) {free(SWITCH_GLOBAL_dirs.conf_dir
);SWITCH_GLOBAL_dirs.conf_dir=((void*)0);}
;
2742 switch_safe_free(SWITCH_GLOBAL_dirs.log_dir)if (SWITCH_GLOBAL_dirs.log_dir) {free(SWITCH_GLOBAL_dirs.log_dir
);SWITCH_GLOBAL_dirs.log_dir=((void*)0);}
;
2743 switch_safe_free(SWITCH_GLOBAL_dirs.db_dir)if (SWITCH_GLOBAL_dirs.db_dir) {free(SWITCH_GLOBAL_dirs.db_dir
);SWITCH_GLOBAL_dirs.db_dir=((void*)0);}
;
2744 switch_safe_free(SWITCH_GLOBAL_dirs.script_dir)if (SWITCH_GLOBAL_dirs.script_dir) {free(SWITCH_GLOBAL_dirs.script_dir
);SWITCH_GLOBAL_dirs.script_dir=((void*)0);}
;
2745 switch_safe_free(SWITCH_GLOBAL_dirs.htdocs_dir)if (SWITCH_GLOBAL_dirs.htdocs_dir) {free(SWITCH_GLOBAL_dirs.htdocs_dir
);SWITCH_GLOBAL_dirs.htdocs_dir=((void*)0);}
;
2746 switch_safe_free(SWITCH_GLOBAL_dirs.grammar_dir)if (SWITCH_GLOBAL_dirs.grammar_dir) {free(SWITCH_GLOBAL_dirs.
grammar_dir);SWITCH_GLOBAL_dirs.grammar_dir=((void*)0);}
;
2747 switch_safe_free(SWITCH_GLOBAL_dirs.storage_dir)if (SWITCH_GLOBAL_dirs.storage_dir) {free(SWITCH_GLOBAL_dirs.
storage_dir);SWITCH_GLOBAL_dirs.storage_dir=((void*)0);}
;
2748 switch_safe_free(SWITCH_GLOBAL_dirs.cache_dir)if (SWITCH_GLOBAL_dirs.cache_dir) {free(SWITCH_GLOBAL_dirs.cache_dir
);SWITCH_GLOBAL_dirs.cache_dir=((void*)0);}
;
2749 switch_safe_free(SWITCH_GLOBAL_dirs.recordings_dir)if (SWITCH_GLOBAL_dirs.recordings_dir) {free(SWITCH_GLOBAL_dirs
.recordings_dir);SWITCH_GLOBAL_dirs.recordings_dir=((void*)0)
;}
;
2750 switch_safe_free(SWITCH_GLOBAL_dirs.sounds_dir)if (SWITCH_GLOBAL_dirs.sounds_dir) {free(SWITCH_GLOBAL_dirs.sounds_dir
);SWITCH_GLOBAL_dirs.sounds_dir=((void*)0);}
;
2751 switch_safe_free(SWITCH_GLOBAL_dirs.run_dir)if (SWITCH_GLOBAL_dirs.run_dir) {free(SWITCH_GLOBAL_dirs.run_dir
);SWITCH_GLOBAL_dirs.run_dir=((void*)0);}
;
2752 switch_safe_free(SWITCH_GLOBAL_dirs.temp_dir)if (SWITCH_GLOBAL_dirs.temp_dir) {free(SWITCH_GLOBAL_dirs.temp_dir
);SWITCH_GLOBAL_dirs.temp_dir=((void*)0);}
;
2753
2754 switch_event_destroy(&runtime.global_vars);
2755 switch_core_hash_destroy(&runtime.ptimes);
2756 switch_core_hash_destroy(&runtime.mime_types);
2757
2758 if (IP_LIST.hash) {
2759 switch_core_hash_destroy(&IP_LIST.hash);
2760 }
2761
2762 if (IP_LIST.pool) {
2763 switch_core_destroy_memory_pool(&IP_LIST.pool)switch_core_perform_destroy_memory_pool(&IP_LIST.pool, "src/switch_core.c"
, (const char *)__func__, 2763)
;
2764 }
2765
2766 switch_core_media_deinit();
2767
2768 if (runtime.memory_pool) {
2769 apr_pool_destroy(runtime.memory_pool);
2770 apr_terminate();
2771 }
2772
2773 sqlite3_shutdown();
2774
2775 return switch_test_flag((&runtime), SCF_RESTART)(((&runtime))->flags & SCF_RESTART) ? SWITCH_STATUS_RESTART : SWITCH_STATUS_SUCCESS;
2776}
2777
2778SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_management_exec(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen)
2779{
2780 const switch_management_interface_t *ptr;
2781 switch_status_t status = SWITCH_STATUS_FALSE;
2782
2783 if ((ptr = switch_loadable_module_get_management_interface(relative_oid))) {
2784 status = ptr->management_function(relative_oid, action, data, datalen);
2785 }
2786
2787 return status;
2788}
2789
2790SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_memory_reclaim_all(void)
2791{
2792 switch_core_memory_reclaim_logger();
2793 switch_core_memory_reclaim_events();
2794 switch_core_memory_reclaim();
2795}
2796
2797
2798struct system_thread_handle {
2799 const char *cmd;
2800 switch_thread_cond_t *cond;
2801 switch_mutex_t *mutex;
2802 switch_memory_pool_t *pool;
2803 int ret;
2804 int *fds;
2805};
2806
2807static void *SWITCH_THREAD_FUNC system_thread(switch_thread_t *thread, void *obj)
2808{
2809 struct system_thread_handle *sth = (struct system_thread_handle *) obj;
2810
2811#if defined(HAVE_SETRLIMIT1) && !defined(__FreeBSD__)
2812 struct rlimit rlim;
2813 struct rlimit rlim_save;
2814
2815 memset(&rlim, 0, sizeof(rlim));
2816 getrlimit(RLIMIT_STACKRLIMIT_STACK, &rlim);
2817
2818 memset(&rlim_save, 0, sizeof(rlim_save));
2819 getrlimit(RLIMIT_STACKRLIMIT_STACK, &rlim_save);
2820
2821 rlim.rlim_cur = rlim.rlim_max;
2822 if (setrlimit(RLIMIT_STACKRLIMIT_STACK, &rlim) < 0) {
2823 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2823, ((void*)0)
, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno(*__errno_location ())));
2824 }
2825#endif
2826
2827 if (sth->fds) {
2828 dup2(sth->fds[1], STDOUT_FILENO1);
2829 }
2830
2831 sth->ret = system(sth->cmd);
2832
2833#if defined(HAVE_SETRLIMIT1) && !defined(__FreeBSD__)
2834 if (setrlimit(RLIMIT_STACKRLIMIT_STACK, &rlim_save) < 0) {
2835 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2835, ((void*)0)
, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno(*__errno_location ())));
2836 }
2837#endif
2838
2839 switch_mutex_lock(sth->mutex);
2840 switch_thread_cond_signal(sth->cond);
2841 switch_mutex_unlock(sth->mutex);
2842
2843 switch_core_destroy_memory_pool(&sth->pool)switch_core_perform_destroy_memory_pool(&sth->pool, "src/switch_core.c"
, (const char *)__func__, 2843)
;
2844
2845 return NULL((void*)0);
2846}
2847
2848
2849static int switch_system_thread(const char *cmd, switch_bool_t wait)
2850{
2851 switch_thread_t *thread;
2852 switch_threadattr_t *thd_attr;
2853 int ret = 0;
2854 struct system_thread_handle *sth;
2855 switch_memory_pool_t *pool;
2856
2857 if (switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_core.c"
, (const char *)__func__, 2857)
!= SWITCH_STATUS_SUCCESS) {
2858 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2858, ((void*)0)
, SWITCH_LOG_CRIT, "Pool Failure\n");
2859 return 1;
2860 }
2861
2862 if (!(sth = switch_core_alloc(pool, sizeof(struct system_thread_handle))switch_core_perform_alloc(pool, sizeof(struct system_thread_handle
), "src/switch_core.c", (const char *)__func__, 2862)
)) {
2863 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_core.c"
, (const char *)__func__, 2863)
;
2864 return 1;
2865 }
2866
2867 sth->pool = pool;
2868 sth->cmd = switch_core_strdup(pool, cmd)switch_core_perform_strdup(pool, cmd, "src/switch_core.c", (const
char *)__func__, 2868)
;
2869
2870 switch_thread_cond_create(&sth->cond, sth->pool);
2871 switch_mutex_init(&sth->mutex, SWITCH_MUTEX_NESTED0x1, sth->pool);
2872 switch_mutex_lock(sth->mutex);
2873
2874 switch_threadattr_create(&thd_attr, sth->pool);
2875 switch_threadattr_stacksize_set(thd_attr, SWITCH_SYSTEM_THREAD_STACKSIZE8192 * 1024);
2876 switch_threadattr_detach_set(thd_attr, 1);
2877 switch_thread_create(&thread, thd_attr, system_thread, sth, sth->pool);
2878
2879 if (wait) {
2880 switch_thread_cond_wait(sth->cond, sth->mutex);
2881 ret = sth->ret;
2882 }
2883 switch_mutex_unlock(sth->mutex);
2884
2885 return ret;
2886}
2887
2888SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_max_file_desc(void)
2889{
2890 int max = 0;
2891
2892#ifndef WIN32
2893#if defined(HAVE_GETDTABLESIZE1)
2894 max = getdtablesize();
2895#else
2896 max = sysconf(_SC_OPEN_MAX_SC_OPEN_MAX);
2897#endif
2898#endif
2899
2900 return max;
2901
2902}
2903
2904SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_close_extra_files(int *keep, int keep_ttl)
2905{
2906 int open_max = switch_max_file_desc();
2907 int i, j;
2908
2909 for (i = 3; i < open_max; i++) {
2910 if (keep) {
2911 for (j = 0; j < keep_ttl; j++) {
2912 if (i == keep[j]) {
2913 goto skip;
2914 }
2915 }
2916 }
2917
2918 close(i);
2919
2920 skip:
2921
2922 continue;
2923
2924 }
2925}
2926
2927
2928#ifdef WIN32
2929static int switch_system_fork(const char *cmd, switch_bool_t wait)
2930{
2931 return switch_system_thread(cmd, wait);
2932}
2933
2934SWITCH_DECLARE(pid_t)__attribute__((visibility("default"))) pid_t switch_fork(void)
2935{
2936 return -1;
2937}
2938
2939
2940#else
2941
2942SWITCH_DECLARE(pid_t)__attribute__((visibility("default"))) pid_t switch_fork(void)
2943{
2944 int i = fork();
2945
2946 if (!i) {
2947 set_low_priority();
2948 }
2949
2950 return i;
2951}
2952
2953
2954
2955static int switch_system_fork(const char *cmd, switch_bool_t wait)
2956{
2957 int pid;
2958 char *dcmd = strdup(cmd)(__extension__ (__builtin_constant_p (cmd) && ((size_t
)(const void *)((cmd) + 1) - (size_t)(const void *)(cmd) == 1
) ? (((const char *) (cmd))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (cmd) + 1; char *
__retval = (char *) malloc (__len); if (__retval != ((void*)0
)) __retval = (char *) memcpy (__retval, cmd, __len); __retval
; })) : __strdup (cmd)))
;
2959#if defined(HAVE_SETRLIMIT1) && !defined(__FreeBSD__)
2960 struct rlimit rlim;
2961 struct rlimit rlim_save;
2962#endif
2963
2964 switch_core_set_signal_handlers();
2965
2966 pid = switch_fork();
2967
2968 if (pid) {
2969 if (wait) {
2970 waitpid(pid, NULL((void*)0), 0);
2971 }
2972 free(dcmd);
2973 } else {
2974 switch_close_extra_files(NULL((void*)0), 0);
2975
2976#if defined(HAVE_SETRLIMIT1) && !defined(__FreeBSD__)
2977 memset(&rlim, 0, sizeof(rlim));
2978 getrlimit(RLIMIT_STACKRLIMIT_STACK, &rlim);
2979
2980 memset(&rlim_save, 0, sizeof(rlim_save));
2981 getrlimit(RLIMIT_STACKRLIMIT_STACK, &rlim_save);
2982
2983 rlim.rlim_cur = rlim.rlim_max;
2984 if (setrlimit(RLIMIT_STACKRLIMIT_STACK, &rlim) < 0) {
2985 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2985, ((void*)0)
, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno(*__errno_location ())));
2986 }
2987#endif
2988
2989 if (system(dcmd) == -1) {
2990 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core.c", (const char *)__func__
, 2990, ((void*)0)
, SWITCH_LOG_ERROR, "Failed to execute because of a command error : %s\n", dcmd);
2991 }
2992 free(dcmd);
2993 exit(0);
2994 }
2995
2996 return 0;
2997}
2998#endif
2999
3000
3001
3002SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_system(const char *cmd, switch_bool_t wait)
3003{
3004 int (*sys_p)(const char *cmd, switch_bool_t wait);
3005
3006 sys_p = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC)(((&runtime))->flags & SCF_THREADED_SYSTEM_EXEC) ? switch_system_thread : switch_system_fork;
3007
3008 return sys_p(cmd, wait);
3009
3010}
3011
3012
3013
3014SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_stream_system_fork(const char *cmd, switch_stream_handle_t *stream)
3015{
3016#ifdef WIN32
3017 return switch_system(cmd, SWITCH_TRUE);
3018#else
3019 int fds[2], pid = 0;
3020
3021 if (pipe(fds)) {
3022 goto end;
3023 } else { /* good to go */
3024 pid = switch_fork();
3025
3026 if (pid < 0) { /* ok maybe not */
3027 close(fds[0]);
3028 close(fds[1]);
3029 goto end;
3030 } else if (pid) { /* parent */
3031 char buf[1024] = "";
3032 int bytes;
3033 close(fds[1]);
3034 while ((bytes = read(fds[0], buf, sizeof(buf))) > 0) {
3035 stream->raw_write_function(stream, (unsigned char *)buf, bytes);
3036 }
3037 close(fds[0]);
3038 waitpid(pid, NULL((void*)0), 0);
3039 } else { /* child */
3040 switch_close_extra_files(fds, 2);
3041 close(fds[0]);
3042 dup2(fds[1], STDOUT_FILENO1);
3043 switch_system(cmd, SWITCH_TRUE);
3044 close(fds[1]);
3045 exit(0);
3046 }
3047 }
3048
3049 end:
3050
3051 return 0;
3052
3053#endif
3054
3055}
3056
3057SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_get_stacksizes(switch_size_t *cur, switch_size_t *max)
3058{
3059#ifdef HAVE_SETRLIMIT1
3060 struct rlimit rlp;
3061
3062 memset(&rlp, 0, sizeof(rlp));
3063 getrlimit(RLIMIT_STACKRLIMIT_STACK, &rlp);
3064
3065 *cur = rlp.rlim_cur;
3066 *max = rlp.rlim_max;
3067
3068 return SWITCH_STATUS_SUCCESS;
3069
3070#else
3071
3072 return SWITCH_STATUS_FALSE;
3073
3074#endif
3075
3076
3077
3078}
3079
3080
3081SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_stream_system(const char *cmd, switch_stream_handle_t *stream)
3082{
3083#ifdef WIN32
3084 stream->write_function(stream, "Capturing output not supported.\n");
3085 return switch_system(cmd, SWITCH_TRUE);
3086#else
3087 return switch_stream_system_fork(cmd, stream);
3088#endif
3089
3090}
3091
3092/* For Emacs:
3093 * Local Variables:
3094 * mode:c
3095 * indent-tabs-mode:t
3096 * tab-width:4
3097 * c-basic-offset:4
3098 * End:
3099 * For VIM:
3100 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
3101 */