Merge branch 'master' of ssh://git.freeswitch.org:222/freeswitch

This commit is contained in:
Michael S Collins 2012-07-11 11:10:33 -07:00
commit eb7e640b59
16 changed files with 679 additions and 386 deletions

View File

@ -916,15 +916,18 @@ static const char *banner =
"* Paypal Donations Appreciated: paypal@freeswitch.org *\n"
"* Brought to you by ClueCon http://www.cluecon.com/ *\n"
"*******************************************************\n"
"\n"
"Type /help <enter> to see a list of commands\n\n\n";
"\n";
static const char *inf = "Type /help <enter> to see a list of commands\n\n\n";
static void print_banner(FILE *stream)
{
#include <cc.h>
#ifndef WIN32
fprintf(stream, "%s%s", output_text_color, banner);
fprintf(stream, "%s%s%s\n%s", output_text_color, banner, cc, inf);
#else
fprintf(stream, "%s", banner);
fprintf(stream, "%s%s\n%s", banner, cc, inf);
#endif
}

View File

@ -35,6 +35,15 @@
#include <stdlib.h>
#include <esl.h>
#include <errno.h>
#include <sys/wait.h>
static void handle_SIGCHLD(int sig)
{
int status = 0;
wait(&status);
return;
}
static void my_forking_callback(esl_socket_t server_sock, esl_socket_t client_sock, struct sockaddr_in *addr)
{
@ -43,6 +52,8 @@ static void my_forking_callback(esl_socket_t server_sock, esl_socket_t client_so
const char *path;
char arg[64] = { 0 };
signal(SIGCHLD, handle_SIGCHLD);
if (fork()) {
close(client_sock);
return;

View File

@ -0,0 +1,3 @@
const char *cc = "\n.========================================================================================================.\n| ____ _____ ____ _ ____ _ _ ____ |\n| / ___|___ _ __ ___ ___ |_ _|__ / ___| |_ _ ___ / ___|___ _ __ ( ) |___ \\ |\n| | | / _ \\| '_ ` _ \\ / _ \\ | |/ _ \\ | | | | | | |/ _ \\ | / _ \\| '_ \\ |/| | __) | |\n| | |__| (_) | | | | | | __/ | | (_) | | |___| | |_| | __/ |__| (_) | | | | | |/ __/ |\n| \\____\\___/|_| |_| |_|\\___| |_|\\___/ \\____|_|\\__,_|\\___|\\____\\___/|_| |_| |_|_____| |\n| |\n| ____ _ _ _ _ ____ _ |\n| / ___| |__ (_) ___ __ _ __ _ ___ | | | / ___| / \\ |\n| | | | '_ \\| |/ __/ _` |/ _` |/ _ \\ | | | \\___ \\ / _ \\ |\n| | |___| | | | | (_| (_| | (_| | (_) | _ | |_| |___) / ___ \\ |\n| \\____|_| |_|_|\\___\\__,_|\\__, |\\___/ ( ) \\___/|____/_/ \\_\\ |\n| |___/ |/ |\n| _ _ _____ _ _ ___ _ _ ____ ___ _ ____ |\n| / \\ _ _ __ _ _ _ ___| |_ |___ | |_| |__ / _ \\| |_| |__ |___ \\ / _ \\/ |___ \\ |\n| / _ \\| | | |/ _` | | | / __| __| / /| __| '_ \\ _____ | (_) | __| '_ \\ __) | | | | | __) | |\n| / ___ \\ |_| | (_| | |_| \\__ \\ |_ / / | |_| | | | |_____| \\__, | |_| | | | / __/| |_| | |/ __/ |\n| /_/ \\_\\__,_|\\__, |\\__,_|___/\\__| /_/ \\__|_| |_| /_/ \\__|_| |_| |_____|\\___/|_|_____| |\n| |___/ |\n| _ |\n| __ ____ ____ __ ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| \\ \\ /\\ / /\\ \\ /\\ / /\\ \\ /\\ / / / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| \\ V V / \\ V V / \\ V V / _ | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\_/\\_/ \\_/\\_/ \\_/\\_/ (_) \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.========================================================================================================.\n\n";

View File

@ -79,7 +79,8 @@ libfreetdm_la_SOURCES = \
$(SRC)/ftdm_buffer.c \
$(SRC)/ftdm_threadmutex.c \
$(SRC)/ftdm_dso.c \
$(SRC)/ftdm_cpu_monitor.c
$(SRC)/ftdm_cpu_monitor.c \
$(SRC)/ftdm_backtrace.c
library_include_HEADERS = \
$(SRC)/include/freetdm.h \

View File

@ -136,7 +136,7 @@ AC_CHECK_LIB([dl], [dlopen])
AC_CHECK_LIB([pthread], [pthread_create])
AC_CHECK_LIB([m], [cos])
AC_CHECK_HEADERS([netdb.h sys/select.h])
AC_CHECK_HEADERS([netdb.h sys/select.h execinfo.h])
AC_CHECK_FUNC([gethostbyname_r],
[], [AC_CHECK_LIB([nsl], [gethostbyname_r])]

View File

@ -35,13 +35,6 @@
#include "freetdm.h"
//#define CUDATEL_DEBUG
#ifdef CUDATEL_DEBUG
#ifndef _BSD_SOURCE
#define _BSD_SOURCE
#endif
#include <execinfo.h>
#include <syscall.h>
#endif
#ifndef __FUNCTION__
#define __FUNCTION__ __SWITCH_FUNC__
@ -499,6 +492,21 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session)
return SWITCH_STATUS_SUCCESS;
}
#ifdef CUDATEL_DEBUG
struct cudatel_trace_priv {
const char *name;
int span_id;
int chan_id;
};
static void cudatel_trace(const int tid, const void *addr, const char *symbol, void *priv)
{
struct cudatel_trace_priv *data = priv;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%d:%d][tid:%d] %s -> %s\n",
data->span_id, data->chan_id, tid, data->name, symbol);
}
#endif
static switch_status_t channel_on_hangup(switch_core_session_t *session)
{
switch_channel_t *channel = NULL;
@ -558,19 +566,11 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
#ifdef CUDATEL_DEBUG
{
pid_t tid = 0;
size_t size = 0;
char **symbols = NULL;
void *stacktrace[50];
int si = 0;
size = backtrace(stacktrace, ftdm_array_len(stacktrace));
symbols = backtrace_symbols(stacktrace, size);
tid = syscall(SYS_gettid);
for (si = 0; si < size; si++) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%d:%d][tid:%d] %s -> %s\n",
span_id, chan_id, tid, name, symbols[si]);
}
free(symbols);
struct cudatel_trace_priv trace_data;
trace_data.name = name;
trace_data.span_id = span_id;
trace_data.chan_id = chan_id;
ftdm_backtrace_walk(&cudatel_trace, &trace_data);
}
#endif

View File

@ -0,0 +1,75 @@
/*
*
*
*/
#define _BSD_SOURCE
#include "private/ftdm_core.h"
#ifdef HAVE_EXECINFO_H
#include <stdlib.h>
#include <unistd.h>
#include <execinfo.h>
#include <syscall.h>
#define FTDM_BACKTRACE_MAX 50
FT_DECLARE(ftdm_status_t) ftdm_backtrace_walk(void (* callback)(const int tid, const void *addr, const char *symbol, void *priv), void *priv)
{
void *stacktrace[FTDM_BACKTRACE_MAX];
char **symbols = NULL;
size_t size = 0;
pid_t tid = 0;
int si = 0;
if (!callback) {
return FTDM_EINVAL;
}
tid = syscall(SYS_gettid);
size = backtrace(stacktrace, ftdm_array_len(stacktrace));
symbols = backtrace_symbols(stacktrace, size);
for (si = 0; si < size; si++) {
callback(tid, stacktrace[si], symbols[si], priv);
}
free(symbols);
return FTDM_SUCCESS;
}
#else /* !HAVE_EXECINFO_H */
FT_DECLARE(ftdm_status_t) ftdm_backtrace_walk(void (* callback)(const int tid, const void *addr, const char *symbol, void *priv), void *priv)
{
ftdm_log(FTDM_LOG_DEBUG, "Stack traces are not available on this platform!\n");
return FTDM_NOTIMPL;
}
#endif
static void span_backtrace(const int tid, const void *addr, const char *symbol, void *priv)
{
ftdm_span_t *span = priv;
ftdm_log(FTDM_LOG_DEBUG, "[%d][tid:%d] %p -> %s\n",
ftdm_span_get_id(span), tid, addr, symbol);
}
FT_DECLARE(ftdm_status_t) ftdm_backtrace_span(ftdm_span_t *span)
{
return ftdm_backtrace_walk(&span_backtrace, span);
}
static void chan_backtrace(const int tid, const void *addr, const char *symbol, void *priv)
{
ftdm_channel_t *chan = priv;
ftdm_log(FTDM_LOG_DEBUG, "[%d:%d][tid:%d] %p -> %s\n",
ftdm_channel_get_span_id(chan), ftdm_channel_get_id(chan), tid, addr, symbol);
}
FT_DECLARE(ftdm_status_t) ftdm_backtrace_chan(ftdm_channel_t *chan)
{
return ftdm_backtrace_walk(&chan_backtrace, chan);
}

View File

@ -262,9 +262,12 @@ FTDM_STR2ENUM(ftdm_str2ftdm_tonemap, ftdm_tonemap2str, ftdm_tonemap_t, TONEMAP_N
FTDM_ENUM_NAMES(OOB_NAMES, OOB_STRINGS)
FTDM_STR2ENUM(ftdm_str2ftdm_oob_event, ftdm_oob_event2str, ftdm_oob_event_t, OOB_NAMES, FTDM_OOB_INVALID)
FTDM_ENUM_NAMES(TRUNK_TYPE_NAMES, TRUNK_STRINGS)
FTDM_ENUM_NAMES(TRUNK_TYPE_NAMES, TRUNK_TYPE_STRINGS)
FTDM_STR2ENUM(ftdm_str2ftdm_trunk_type, ftdm_trunk_type2str, ftdm_trunk_type_t, TRUNK_TYPE_NAMES, FTDM_TRUNK_NONE)
FTDM_ENUM_NAMES(TRUNK_MODE_NAMES, TRUNK_MODE_STRINGS)
FTDM_STR2ENUM(ftdm_str2ftdm_trunk_mode, ftdm_trunk_mode2str, ftdm_trunk_mode_t, TRUNK_MODE_NAMES, FTDM_TRUNK_MODE_INVALID)
FTDM_ENUM_NAMES(START_TYPE_NAMES, START_TYPE_STRINGS)
FTDM_STR2ENUM(ftdm_str2ftdm_analog_start_type, ftdm_analog_start_type2str, ftdm_analog_start_type_t, START_TYPE_NAMES, FTDM_ANALOG_START_NA)
@ -816,6 +819,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_create(const char *iotype, const char *name,
ftdm_copy_string(new_span->tone_map[FTDM_TONEMAP_BUSY], "%(500,500,480,620)", FTDM_TONEMAP_LEN);
ftdm_copy_string(new_span->tone_map[FTDM_TONEMAP_ATTN], "%(100,100,1400,2060,2450,2600)", FTDM_TONEMAP_LEN);
new_span->trunk_type = FTDM_TRUNK_NONE;
new_span->trunk_mode = FTDM_TRUNK_MODE_CPE;
new_span->data_type = FTDM_TYPE_SPAN;
ftdm_mutex_lock(globals.span_mutex);
@ -1994,6 +1998,21 @@ FT_DECLARE(const char *) ftdm_span_get_trunk_type_str(const ftdm_span_t *span)
return ftdm_trunk_type2str(span->trunk_type);
}
FT_DECLARE(void) ftdm_span_set_trunk_mode(ftdm_span_t *span, ftdm_trunk_mode_t mode)
{
span->trunk_mode = mode;
}
FT_DECLARE(ftdm_trunk_mode_t) ftdm_span_get_trunk_mode(const ftdm_span_t *span)
{
return span->trunk_mode;
}
FT_DECLARE(const char *) ftdm_span_get_trunk_mode_str(const ftdm_span_t *span)
{
return ftdm_trunk_mode2str(span->trunk_mode);
}
FT_DECLARE(uint32_t) ftdm_span_get_id(const ftdm_span_t *span)
{
return span->span_id;
@ -4706,6 +4725,10 @@ static ftdm_status_t load_config(void)
ftdm_trunk_type_t trtype = ftdm_str2ftdm_trunk_type(val);
ftdm_span_set_trunk_type(span, trtype);
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s'\n", ftdm_trunk_type2str(trtype));
} else if (!strcasecmp(var, "trunk_mode")) {
ftdm_trunk_mode_t trmode = ftdm_str2ftdm_trunk_mode(val);
ftdm_span_set_trunk_mode(span, trmode);
ftdm_log(FTDM_LOG_DEBUG, "setting trunk mode to '%s'\n", ftdm_trunk_mode2str(trmode));
} else if (!strcasecmp(var, "name")) {
if (!strcasecmp(val, "undef")) {
chan_config.name[0] = '\0';
@ -4730,8 +4753,9 @@ static ftdm_status_t load_config(void)
} else if (!strcasecmp(var, "fxo-channel")) {
if (span->trunk_type == FTDM_TRUNK_NONE) {
span->trunk_type = FTDM_TRUNK_FXO;
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s)\n", ftdm_trunk_type2str(span->trunk_type),
ftdm_analog_start_type2str(span->start_type));
span->trunk_mode = FTDM_TRUNK_MODE_CPE;
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s), mode(%s)\n", ftdm_trunk_type2str(span->trunk_type),
ftdm_analog_start_type2str(span->start_type), ftdm_trunk_mode2str(span->trunk_mode));
}
if (span->trunk_type == FTDM_TRUNK_FXO) {
unsigned chans_configured = 0;
@ -4745,8 +4769,9 @@ static ftdm_status_t load_config(void)
} else if (!strcasecmp(var, "fxs-channel")) {
if (span->trunk_type == FTDM_TRUNK_NONE) {
span->trunk_type = FTDM_TRUNK_FXS;
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s)\n", ftdm_trunk_type2str(span->trunk_type),
ftdm_analog_start_type2str(span->start_type));
span->trunk_mode = FTDM_TRUNK_MODE_NET;
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s), mode(%s)\n", ftdm_trunk_type2str(span->trunk_type),
ftdm_analog_start_type2str(span->start_type), ftdm_trunk_mode2str(span->trunk_mode));
}
if (span->trunk_type == FTDM_TRUNK_FXS) {
unsigned chans_configured = 0;
@ -4760,8 +4785,9 @@ static ftdm_status_t load_config(void)
} else if (!strcasecmp(var, "em-channel")) {
if (span->trunk_type == FTDM_TRUNK_NONE) {
span->trunk_type = FTDM_TRUNK_EM;
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s)\n", ftdm_trunk_type2str(span->trunk_type),
ftdm_analog_start_type2str(span->start_type));
span->trunk_mode = FTDM_TRUNK_MODE_CPE;
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s), mode(%s)\n", ftdm_trunk_type2str(span->trunk_type),
ftdm_analog_start_type2str(span->start_type), ftdm_trunk_mode2str(span->trunk_mode));
}
if (span->trunk_type == FTDM_TRUNK_EM) {
unsigned chans_configured = 0;

View File

@ -2462,9 +2462,15 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span)
memset(isdn_data, 0, sizeof(*isdn_data));
/* set some default values */
isdn_data->mode = PRI_CPE;
isdn_data->ton = PRI_UNKNOWN;
/* Use span's trunk_mode as a reference for the default libpri mode */
if (ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_NET) {
isdn_data->mode = PRI_NETWORK;
} else {
isdn_data->mode = PRI_CPE;
}
switch (ftdm_span_get_trunk_type(span)) {
case FTDM_TRUNK_BRI:
case FTDM_TRUNK_BRI_PTMP:
@ -2516,8 +2522,8 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span)
if (!strcasecmp(var, "node") || !strcasecmp(var, "mode")) {
if ((isdn_data->mode = parse_mode(val)) == -1) {
ftdm_log(FTDM_LOG_ERROR, "Unknown node type '%s', defaulting to CPE mode\n", val);
isdn_data->mode = PRI_CPE;
ftdm_log(FTDM_LOG_ERROR, "Unknown node type '%s'\n", val);
goto error;
}
}
else if (!strcasecmp(var, "switch") || !strcasecmp(var, "dialect")) {
@ -2563,6 +2569,16 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span)
}
}
/* Check if modes match and log a message if they do not. Just to be on the safe side. */
if (isdn_data->mode == PRI_CPE && ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_NET) {
ftdm_log(FTDM_LOG_WARNING, "Span '%s' signalling set up for TE/CPE/USER mode, while port is running in NT/NET mode. You may want to check your 'trunk_mode' settings.\n",
ftdm_span_get_name(span));
}
else if (isdn_data->mode == PRI_NETWORK && ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_CPE) {
ftdm_log(FTDM_LOG_WARNING, "Span '%s' signalling set up for NT/NET mode, while port is running in TE/CPE/USER mode. You may want to check your 'trunk_mode' settings.\n",
ftdm_span_get_name(span));
}
span->start = ftdm_libpri_start;
span->stop = ftdm_libpri_stop;
span->signal_cb = sig_cb;

View File

@ -1432,12 +1432,12 @@ static ftdm_status_t misdn_open_range(ftdm_span_t *span, ftdm_chan_type_t type,
switch (ftdm_span_get_trunk_type(span)) {
case FTDM_TRUNK_E1:
d_protocol = ISDN_P_TE_E1;
d_protocol = ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_NET ? ISDN_P_NT_E1 : ISDN_P_TE_E1;
d_channel = 16;
break;
case FTDM_TRUNK_BRI:
case FTDM_TRUNK_BRI_PTMP:
d_protocol = ISDN_P_TE_S0;
d_protocol = ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_NET ? ISDN_P_NT_S0 : ISDN_P_TE_S0;
d_channel = 0;
break;
default:

View File

@ -484,11 +484,23 @@ typedef enum {
FTDM_TRUNK_GSM,
FTDM_TRUNK_NONE
} ftdm_trunk_type_t;
#define TRUNK_STRINGS "E1", "T1", "J1", "BRI", "BRI_PTMP", "FXO", "FXS", "EM", "GSM", "NONE"
#define TRUNK_TYPE_STRINGS "E1", "T1", "J1", "BRI", "BRI_PTMP", "FXO", "FXS", "EM", "GSM", "NONE"
/*! \brief Move from string to ftdm_trunk_type_t and viceversa */
FTDM_STR2ENUM_P(ftdm_str2ftdm_trunk_type, ftdm_trunk_type2str, ftdm_trunk_type_t)
/*! \brief Span trunk modes */
typedef enum {
FTDM_TRUNK_MODE_CPE,
FTDM_TRUNK_MODE_NET,
FTDM_TRUNK_MODE_INVALID
} ftdm_trunk_mode_t;
#define TRUNK_MODE_STRINGS "CPE", "NET", "INVALID"
/*! \brief Move from string to ftdm_trunk_mode_t and viceversa */
FTDM_STR2ENUM_P(ftdm_str2ftdm_trunk_mode, ftdm_trunk_mode2str, ftdm_trunk_mode_t)
/*! \brief Basic channel configuration provided to ftdm_configure_span_channels */
typedef struct ftdm_channel_config {
char name[FTDM_MAX_NAME_STR_SZ];
@ -1744,6 +1756,28 @@ FT_DECLARE(ftdm_trunk_type_t) ftdm_span_get_trunk_type(const ftdm_span_t *span);
/*! \brief For display debugging purposes you can display this string which describes the trunk type of a span */
FT_DECLARE(const char *) ftdm_span_get_trunk_type_str(const ftdm_span_t *span);
/*!
* Set the trunk mode for a span
* \note This must be called before configuring any channels within the span!
* \param[in] span The span
* \param[in] type The trunk mode
*/
FT_DECLARE(void) ftdm_span_set_trunk_mode(ftdm_span_t *span, ftdm_trunk_mode_t mode);
/*!
* Get the trunk mode for a span
* \param[in] span The span
* \return Span trunk mode
*/
FT_DECLARE(ftdm_trunk_mode_t) ftdm_span_get_trunk_mode(const ftdm_span_t *span);
/*!
* Get the trunk mode of a span in textual form
* \param[in] span The span
* \return Span mode name as a string
*/
FT_DECLARE(const char *) ftdm_span_get_trunk_mode_str(const ftdm_span_t *span);
/*!
* \brief Return the channel identified by the provided id
*
@ -1814,6 +1848,40 @@ FT_DECLARE(void) ftdm_global_set_config_directory(const char *path);
/*! \brief Check if the FTDM library is initialized and running */
FT_DECLARE(ftdm_bool_t) ftdm_running(void);
/**
* Generate a stack trace and invoke a callback function for each entry
* \param[in] callback Callback function, that is invoked for each stack symbol
* \param[in] priv (User-)Private data passed to the callback
* \retval
* FTDM_SUCCESS On success
* FTDM_NOTIMPL Backtraces are not available
* FTDM_EINVAL Invalid arguments (callback was NULL)
*/
FT_DECLARE(ftdm_status_t) ftdm_backtrace_walk(void (* callback)(const int tid, const void *addr, const char *symbol, void *priv), void *priv);
/**
* Convenience function to print a backtrace for a span.
* \note The backtrace is generated with FTDM_LOG_DEBUG log level.
* \param[in] span Span object
* \retval
* FTDM_SUCCESS On success
* FTDM_NOTIMPL Backtraces are not available
* FTDM_EINVAL Invalid arguments (e.g. span was NULL)
*/
FT_DECLARE(ftdm_status_t) ftdm_backtrace_span(ftdm_span_t *span);
/**
* Convenience function to print a backtrace for a channel.
* \note The backtrace is generated with FTDM_LOG_DEBUG log level.
* \param[in] chan Channel object
* \retval
* FTDM_SUCCESS On success
* FTDM_NOTIMPL Backtraces are not available
* FTDM_EINVAL Invalid arguments (e.g. chan was NULL)
*/
FT_DECLARE(ftdm_status_t) ftdm_backtrace_chan(ftdm_channel_t *chan);
FT_DECLARE_DATA extern ftdm_logger_t ftdm_log;
/*! \brief Basic transcoding function prototype */

View File

@ -104,10 +104,6 @@
#include <sys/time.h>
#endif
#ifdef __linux__
#include <execinfo.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -489,6 +485,7 @@ struct ftdm_span {
fio_event_cb_t event_callback;
ftdm_mutex_t *mutex;
ftdm_trunk_type_t trunk_type;
ftdm_trunk_mode_t trunk_mode;
ftdm_analog_start_type_t start_type;
ftdm_signal_type_t signal_type;
uint32_t last_used_index;

View File

@ -1074,15 +1074,17 @@ static void our_sofia_event_callback(nua_event_t event,
case nua_i_cancel:
if (sip && channel) {
switch_channel_set_variable(channel, "sip_hangup_disposition", "recv_cancel");
if (sip && channel && sip->sip_reason) {
if (sip->sip_reason) {
char *reason_header = sip_header_as_string(nh->nh_home, (void *) sip->sip_reason);
if (!zstr(reason_header)) {
switch_channel_set_variable_partner(channel, "sip_reason", reason_header);
}
}
}
break;
@ -5039,11 +5041,13 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu
} else if (sofia_test_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL) && (status != 200 && status != 486) && sip && sip->sip_to) {
char *sql;
time_t now = switch_epoch_time_now(NULL);
const char *call_id = sip->sip_call_id->i_id;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Expire registration '%s@%s' due to options failure\n",
sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
sql = switch_mprintf("update sip_registrations set expires=%ld where sip_user='%s' and sip_host='%s'",
(long) now, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
sql = switch_mprintf("update sip_registrations set expires=%ld where sip_user='%s' and sip_host='%s' and call_id='%q'",
(long) now, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
}
}

View File

@ -551,15 +551,16 @@ int sofia_reg_nat_callback(void *pArg, int argc, char **argv, char **columnNames
{
sofia_profile_t *profile = (sofia_profile_t *) pArg;
nua_handle_t *nh;
char to[128] = "";
char to[512] = "";
sofia_destination_t *dst = NULL;
switch_snprintf(to, sizeof(to), "sip:%s@%s", argv[1], argv[2]);
dst = sofia_glue_get_destination(argv[3]);
switch_assert(dst);
nh = nua_handle(profile->nua, NULL, SIPTAG_FROM_STR(profile->url), SIPTAG_TO_STR(to), NUTAG_URL(dst->contact), SIPTAG_CONTACT_STR(profile->url),
TAG_END());
SIPTAG_CALL_ID_STR(argv[0]), TAG_END());
nua_handle_bind(nh, &mod_sofia_globals.destroy_private);
nua_options(nh,
NTATAG_SIP_T2(5000),

View File

@ -68,6 +68,10 @@ static switch_core_flag_t service_flags = SCF_NONE;
/* event to signal shutdown (for you unix people, this is like a pthread_cond) */
static HANDLE shutdown_event;
#ifndef PATH_MAX
#define PATH_MAX 256
#endif
#endif
/* signal handler for when freeswitch is running in background mode.
@ -100,7 +104,6 @@ static void handle_SIGCHLD(int sig)
if (sig) {};
pid = wait(&status);
if (pid > 0) {
system_ready = -1;
}
@ -113,7 +116,7 @@ static void handle_SIGCHLD(int sig)
static int freeswitch_kill_background()
{
FILE *f; /* FILE handle to open the pid file */
char path[256] = ""; /* full path of the PID file */
char path[PATH_MAX] = ""; /* full path of the PID file */
pid_t pid = 0; /* pid from the pid file */
/* set the globals so we can use the global paths. */
@ -236,43 +239,41 @@ void WINAPI service_main(DWORD numArgs, char **args)
#else
void daemonize(int do_wait)
static void daemonize(int do_wait)
{
int fd;
pid_t pid;
if (!do_wait) {
switch (fork()) {
case 0:
case 0: /* child process */
break;
case -1:
fprintf(stderr, "Error Backgrounding (fork)! %d - %s\n", errno, strerror(errno));
exit(0);
exit(EXIT_SUCCESS);
break;
default:
exit(0);
default: /* parent process */
exit(EXIT_SUCCESS);
}
if (setsid() < 0) {
fprintf(stderr, "Error Backgrounding (setsid)! %d - %s\n", errno, strerror(errno));
exit(0);
exit(EXIT_SUCCESS);
}
}
pid = fork();
switch (pid) {
case 0:
case 0: /* child process */
break;
case -1:
fprintf(stderr, "Error Backgrounding (fork2)! %d - %s\n", errno, strerror(errno));
exit(0);
exit(EXIT_SUCCESS);
break;
default:
{
default: /* parent process */
fprintf(stderr, "%d Backgrounding.\n", (int) pid);
if (do_wait) {
unsigned int sanity = 60;
char *o;
@ -284,27 +285,22 @@ void daemonize(int do_wait)
}
}
while(--sanity && !system_ready) {
while (--sanity && !system_ready) {
if (sanity % 2 == 0) {
printf("FreeSWITCH[%d] Waiting for background process pid:%d to be ready.....\n", (int)getpid(), (int) pid);
}
sleep(1);
}
if (system_ready == 1) {
printf("FreeSWITCH[%d] System Ready pid:%d\n", (int) getpid(), (int) pid);
} else {
if (!system_ready) {
printf("FreeSWITCH[%d] Error starting system! pid:%d\n", (int)getpid(), (int) pid);
kill(pid, 9);
exit(-1);
exit(EXIT_FAILURE);
}
printf("FreeSWITCH[%d] System Ready pid:%d\n", (int) getpid(), (int) pid);
}
}
exit(0);
exit(EXIT_SUCCESS);
}
if (do_wait) {
@ -317,11 +313,13 @@ void daemonize(int do_wait)
dup2(fd, 0);
close(fd);
}
fd = open("/dev/null", O_WRONLY);
if (fd != 1) {
dup2(fd, 1);
close(fd);
}
fd = open("/dev/null", O_WRONLY);
if (fd != 2) {
dup2(fd, 2);
@ -331,68 +329,9 @@ void daemonize(int do_wait)
#endif
/* the main application entry point */
int main(int argc, char *argv[])
{
char pid_path[256] = ""; /* full path to the pid file */
char pid_buffer[32] = ""; /* pid string */
char old_pid_buffer[32] = ""; /* pid string */
switch_size_t pid_len, old_pid_len;
const char *err = NULL; /* error value for return from freeswitch initialization */
#ifndef WIN32
int nf = 0; /* TRUE if we are running in nofork mode */
char *runas_user = NULL;
char *runas_group = NULL;
#else
int win32_service = 0;
#endif
int nc = 0; /* TRUE if we are running in noconsole mode */
pid_t pid = 0;
int i, x;
char *opts;
char opts_str[1024] = "";
char *local_argv[1024] = { 0 };
int local_argc = argc;
char *arg_argv[128] = { 0 };
char *usageDesc;
int alt_dirs = 0, log_set = 0, run_set = 0, do_kill = 0;
int known_opt;
int priority = 0;
#ifndef WIN32
int do_wait = 0;
#endif
#ifdef __sun
switch_core_flag_t flags = SCF_USE_SQL;
#else
switch_core_flag_t flags = SCF_USE_SQL | SCF_USE_AUTO_NAT | SCF_USE_NAT_MAPPING | SCF_CALIBRATE_CLOCK | SCF_USE_CLOCK_RT;
#endif
int ret = 0;
switch_status_t destroy_status;
switch_file_t *fd;
switch_memory_pool_t *pool = NULL;
#ifdef HAVE_SETRLIMIT
struct rlimit rlp;
int waste = 0;
#endif
for (x = 0; x < argc; x++) {
local_argv[x] = argv[x];
}
if ((opts = getenv("FREESWITCH_OPTS"))) {
strncpy(opts_str, opts, sizeof(opts_str) - 1);
i = switch_separate_string(opts_str, ' ', arg_argv, (sizeof(arg_argv) / sizeof(arg_argv[0])));
for (x = 0; x < i; x++) {
local_argv[local_argc++] = arg_argv[x];
}
}
if (local_argv[0] && strstr(local_argv[0], "freeswitchd")) {
nc++;
}
usageDesc = "these are the optional arguments you can pass to freeswitch\n"
static const char usage[] =
"Usage: freeswitch [OPTIONS]\n\n"
"These are the optional arguments you can pass to freeswitch:\n"
#ifdef WIN32
"\t-service [name] -- start freeswitch as a service, cannot be used if loaded as a console app\n"
"\t-install [name] -- install freeswitch as a service, with optional service name\n"
@ -400,13 +339,15 @@ int main(int argc, char *argv[])
"\t-monotonic-clock -- use monotonic clock as timer source\n"
#else
"\t-nf -- no forking\n"
"\t-u [user] -- specify user to switch to\n" "\t-g [group] -- specify group to switch to\n"
"\t-u [user] -- specify user to switch to\n"
"\t-g [group] -- specify group to switch to\n"
#endif
"\t-help -- this message\n" "\t-version -- print the version and exit\n"
#ifdef HAVE_SETRLIMIT
"\t-waste -- allow memory waste\n"
"\t-core -- dump cores\n"
#endif
"\t-help -- this message\n"
"\t-version -- print the version and exit\n"
"\t-rp -- enable high(realtime) priority settings\n"
"\t-lp -- enable low priority settings\n"
"\t-np -- enable normal priority settings (system defaults)\n"
@ -423,225 +364,305 @@ int main(int argc, char *argv[])
"\t-ncwait -- do not output to a console and background but wait until the system is ready before exiting (implies -nc)\n"
#endif
"\t-c -- output to a console and stay in the foreground\n"
"\t-conf [confdir] -- specify an alternate config dir\n"
"\t-log [logdir] -- specify an alternate log dir\n"
"\t-run [rundir] -- specify an alternate run dir\n"
"\t-db [dbdir] -- specify an alternate db dir\n"
"\t-mod [moddir] -- specify an alternate mod dir\n"
"\t-htdocs [htdocsdir] -- specify an alternate htdocs dir\n" "\t-scripts [scriptsdir] -- specify an alternate scripts dir\n";
"\n\tOptions to control locations of files:\n"
"\t-conf [confdir] -- alternate directory for FreeSWITCH configuration files\n"
"\t-log [logdir] -- alternate directory for logfiles\n"
"\t-run [rundir] -- alternate directory for runtime files\n"
"\t-db [dbdir] -- alternate directory for the internal database\n"
"\t-mod [moddir] -- alternate directory for modules\n"
"\t-htdocs [htdocsdir] -- alternate directory for htdocs\n"
"\t-scripts [scriptsdir] -- alternate directory for scripts\n"
"\t-temp [directory] -- alternate directory for temporary files\n"
"\t-grammar [directory] -- alternate directory for grammar files\n"
"\t-recordings [directory] -- alternate directory for recordings\n"
"\t-storage [directory] -- alternate directory for voicemail storage\n"
"\t-sounds [directory] -- alternate directory for sound files\n";
/**
* Check if value string starts with "-"
*/
static switch_bool_t is_option(const char *p)
{
/* skip whitespaces */
while ((*p == 13) || (*p == 10) || (*p == 9) || (*p == 32) || (*p == 11)) p++;
return (p[0] == '-');
}
/* the main application entry point */
int main(int argc, char *argv[])
{
char pid_path[PATH_MAX] = ""; /* full path to the pid file */
char pid_buffer[32] = ""; /* pid string */
char old_pid_buffer[32] = ""; /* pid string */
switch_size_t pid_len, old_pid_len;
const char *err = NULL; /* error value for return from freeswitch initialization */
#ifndef WIN32
switch_bool_t nf = SWITCH_FALSE; /* TRUE if we are running in nofork mode */
switch_bool_t do_wait = SWITCH_FALSE;
char *runas_user = NULL;
char *runas_group = NULL;
#else
switch_bool_t win32_service = SWITCH_FALSE;
#endif
switch_bool_t nc = SWITCH_FALSE; /* TRUE if we are running in noconsole mode */
pid_t pid = 0;
int i, x;
char *opts;
char opts_str[1024] = "";
char *local_argv[1024] = { 0 };
int local_argc = argc;
char *arg_argv[128] = { 0 };
int alt_dirs = 0, log_set = 0, run_set = 0, do_kill = 0;
int priority = 0;
#ifdef __sun
switch_core_flag_t flags = SCF_USE_SQL;
#else
switch_core_flag_t flags = SCF_USE_SQL | SCF_USE_AUTO_NAT | SCF_USE_NAT_MAPPING | SCF_CALIBRATE_CLOCK | SCF_USE_CLOCK_RT;
#endif
int ret = 0;
switch_status_t destroy_status;
switch_file_t *fd;
switch_memory_pool_t *pool = NULL;
#ifdef HAVE_SETRLIMIT
switch_bool_t waste = SWITCH_FALSE;
#endif
for (x = 0; x < argc; x++) {
local_argv[x] = argv[x];
}
if ((opts = getenv("FREESWITCH_OPTS"))) {
strncpy(opts_str, opts, sizeof(opts_str) - 1);
i = switch_separate_string(opts_str, ' ', arg_argv, (sizeof(arg_argv) / sizeof(arg_argv[0])));
for (x = 0; x < i; x++) {
local_argv[local_argc++] = arg_argv[x];
}
}
if (local_argv[0] && strstr(local_argv[0], "freeswitchd")) {
nc = SWITCH_TRUE;
}
for (x = 1; x < local_argc; x++) {
known_opt = 0;
if (switch_strlen_zero(local_argv[x]))
continue;
if (!strcmp(local_argv[x], "-help") || !strcmp(local_argv[x], "-h") || !strcmp(local_argv[x], "-?")) {
printf("%s\n", usage);
exit(EXIT_SUCCESS);
}
#ifdef WIN32
if (x == 1) {
if (local_argv[x] && !strcmp(local_argv[x], "-service")) {
if (x == 1 && !strcmp(local_argv[x], "-service")) {
/* New installs will always have the service name specified, but keep a default for compat */
x++;
if (local_argv[x] && strlen(local_argv[x])) {
if (!switch_strlen_zero(local_argv[x])) {
switch_copy_string(service_name, local_argv[x], SERVICENAME_MAXLEN);
} else {
switch_copy_string(service_name, SERVICENAME_DEFAULT, SERVICENAME_MAXLEN);
}
known_opt++;
win32_service++;
win32_service = SWITCH_TRUE;
continue;
}
if (local_argv[x] && !strcmp(local_argv[x], "-install")) {
char exePath[1024];
char servicePath[1024];
else if (x == 1 && !strcmp(local_argv[x], "-install")) {
char servicePath[PATH_MAX];
char exePath[PATH_MAX];
SC_HANDLE hService;
SC_HANDLE hSCManager;
SERVICE_DESCRIPTION desc;
desc.lpDescription = "The FreeSWITCH service.";
x++;
if (local_argv[x] && strlen(local_argv[x])) {
if (!switch_strlen_zero(local_argv[x])) {
switch_copy_string(service_name, local_argv[x], SERVICENAME_MAXLEN);
} else {
switch_copy_string(service_name, SERVICENAME_DEFAULT, SERVICENAME_MAXLEN);
}
known_opt++;
GetModuleFileName(NULL, exePath, 1024);
GetModuleFileName(NULL, exePath, sizeof(exePath));
snprintf(servicePath, sizeof(servicePath), "%s -service %s", exePath, service_name);
{ /* Perform service installation */
SC_HANDLE hService;
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
/* Perform service installation */
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!hSCManager) {
fprintf(stderr, "Could not open service manager (%d).\n", GetLastError());
exit(1);
exit(EXIT_FAILURE);
}
hService = CreateService(hSCManager, service_name, service_name, GENERIC_READ | GENERIC_EXECUTE | SERVICE_CHANGE_CONFIG, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, servicePath, NULL, NULL, NULL, NULL, /* Service start name */
NULL);
hService = CreateService(hSCManager, service_name, service_name, GENERIC_READ | GENERIC_EXECUTE | SERVICE_CHANGE_CONFIG, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE,
servicePath, NULL, NULL, NULL, NULL, /* Service start name */ NULL);
if (!hService) {
fprintf(stderr, "Error creating freeswitch service (%d).\n", GetLastError());
} else {
CloseServiceHandle(hSCManager);
exit(EXIT_FAILURE);
}
/* Set desc, and don't care if it succeeds */
SERVICE_DESCRIPTION desc;
desc.lpDescription = "The FreeSWITCH service.";
if (!ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &desc)) {
fprintf(stderr, "FreeSWITCH installed, but could not set the service description (%d).\n", GetLastError());
}
CloseServiceHandle(hService);
}
CloseServiceHandle(hSCManager);
exit(0);
}
exit(EXIT_SUCCESS);
}
if (local_argv[x] && !strcmp(local_argv[x], "-uninstall")) {
else if (x == 1 && !strcmp(local_argv[x], "-uninstall")) {
SC_HANDLE hService;
SC_HANDLE hSCManager;
BOOL deleted;
x++;
if (local_argv[x] && strlen(local_argv[x])) {
if (!switch_strlen_zero(local_argv[x])) {
switch_copy_string(service_name, local_argv[x], SERVICENAME_MAXLEN);
} else {
switch_copy_string(service_name, SERVICENAME_DEFAULT, SERVICENAME_MAXLEN);
}
{ /* Do the uninstallation */
SC_HANDLE hService;
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
/* Do the uninstallation */
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!hSCManager) {
fprintf(stderr, "Could not open service manager (%d).\n", GetLastError());
exit(1);
exit(EXIT_FAILURE);
}
hService = OpenService(hSCManager, service_name, DELETE);
known_opt++;
if (hService != NULL) {
if (!hService) {
fprintf(stderr, "Error opening service (%d).\n", GetLastError());
CloseServiceHandle(hSCManager);
exit(EXIT_FAILURE);
}
/* remove the service! */
if (!DeleteService(hService)) {
deleted = DeleteService(hService);
if (!deleted) {
fprintf(stderr, "Error deleting service (%d).\n", GetLastError());
}
CloseServiceHandle(hService);
} else {
fprintf(stderr, "Error opening service (%d).\n", GetLastError());
}
CloseServiceHandle(hSCManager);
exit(0);
}
}
exit(deleted ? EXIT_SUCCESS : EXIT_FAILURE);
}
if (local_argv[x] && !strcmp(local_argv[x], "-monotonic-clock")) {
else if (!strcmp(local_argv[x], "-monotonic-clock")) {
flags |= SCF_USE_WIN32_MONOTONIC;
known_opt++;
}
#else
if (local_argv[x] && !strcmp(local_argv[x], "-u")) {
else if (!strcmp(local_argv[x], "-u")) {
x++;
if (local_argv[x] && strlen(local_argv[x])) {
if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
fprintf(stderr, "Option '%s' requires an argument!\n", local_argv[x - 1]);
exit(EXIT_FAILURE);
}
runas_user = local_argv[x];
}
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-g")) {
else if (!strcmp(local_argv[x], "-g")) {
x++;
if (local_argv[x] && strlen(local_argv[x])) {
if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
fprintf(stderr, "Option '%s' requires an argument!\n", local_argv[x - 1]);
exit(EXIT_FAILURE);
}
runas_group = local_argv[x];
}
known_opt++;
else if (!strcmp(local_argv[x], "-nf")) {
nf = SWITCH_TRUE;
}
if (local_argv[x] && !strcmp(local_argv[x], "-nf")) {
nf++;
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-version")) {
else if (!strcmp(local_argv[x], "-version")) {
fprintf(stdout, "FreeSWITCH version: %s\n", SWITCH_VERSION_FULL);
return 0;
known_opt++;
exit(EXIT_SUCCESS);
}
#endif
#ifdef HAVE_SETRLIMIT
if (local_argv[x] && !strcmp(local_argv[x], "-core")) {
else if (!strcmp(local_argv[x], "-core")) {
struct rlimit rlp;
memset(&rlp, 0, sizeof(rlp));
rlp.rlim_cur = RLIM_INFINITY;
rlp.rlim_max = RLIM_INFINITY;
setrlimit(RLIMIT_CORE, &rlp);
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-waste")) {
else if (!strcmp(local_argv[x], "-waste")) {
fprintf(stderr, "WARNING: Wasting up to 8 megs of memory per thread.\n");
sleep(2);
waste++;
known_opt++;
waste = SWITCH_TRUE;
}
if (local_argv[x] && !strcmp(local_argv[x], "-no-auto-stack")) {
waste++;
known_opt++;
else if (!strcmp(local_argv[x], "-no-auto-stack")) {
waste = SWITCH_TRUE;
}
#endif
if (local_argv[x] && (!strcmp(local_argv[x], "-hp") || !strcmp(local_argv[x], "-rp"))) {
else if (!strcmp(local_argv[x], "-hp") || !strcmp(local_argv[x], "-rp")) {
priority = 2;
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-lp")) {
else if (!strcmp(local_argv[x], "-lp")) {
priority = -1;
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-np")) {
else if (!strcmp(local_argv[x], "-np")) {
priority = 1;
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-nosql")) {
else if (!strcmp(local_argv[x], "-nosql")) {
flags &= ~SCF_USE_SQL;
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-nonat")) {
else if (!strcmp(local_argv[x], "-nonat")) {
flags &= ~SCF_USE_AUTO_NAT;
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-nonatmap")) {
else if (!strcmp(local_argv[x], "-nonatmap")) {
flags &= ~SCF_USE_NAT_MAPPING;
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-heavy-timer")) {
else if (!strcmp(local_argv[x], "-heavy-timer")) {
flags |= SCF_USE_HEAVY_TIMING;
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-nort")) {
else if (!strcmp(local_argv[x], "-nort")) {
flags &= ~SCF_USE_CLOCK_RT;
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-nocal")) {
else if (!strcmp(local_argv[x], "-nocal")) {
flags &= ~SCF_CALIBRATE_CLOCK;
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-vg")) {
else if (!strcmp(local_argv[x], "-vg")) {
flags |= SCF_VG;
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-stop")) {
do_kill++;
known_opt++;
else if (!strcmp(local_argv[x], "-stop")) {
do_kill = SWITCH_TRUE;
}
if (local_argv[x] && !strcmp(local_argv[x], "-nc")) {
nc++;
known_opt++;
else if (!strcmp(local_argv[x], "-nc")) {
nc = SWITCH_TRUE;
}
#ifndef WIN32
if (local_argv[x] && !strcmp(local_argv[x], "-ncwait")) {
nc++;
do_wait++;
known_opt++;
else if (!strcmp(local_argv[x], "-ncwait")) {
nc = SWITCH_TRUE;
do_wait = SWITCH_TRUE;
}
#endif
if (local_argv[x] && !strcmp(local_argv[x], "-c")) {
nc = 0;
known_opt++;
else if (!strcmp(local_argv[x], "-c")) {
nc = SWITCH_FALSE;
}
if (local_argv[x] && !strcmp(local_argv[x], "-conf")) {
else if (!strcmp(local_argv[x], "-conf")) {
x++;
if (local_argv[x] && strlen(local_argv[x])) {
if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
fprintf(stderr, "When using -conf you must specify a config directory\n");
return 255;
}
SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(strlen(local_argv[x]) + 1);
if (!SWITCH_GLOBAL_dirs.conf_dir) {
fprintf(stderr, "Allocation error\n");
@ -649,32 +670,30 @@ int main(int argc, char *argv[])
}
strcpy(SWITCH_GLOBAL_dirs.conf_dir, local_argv[x]);
alt_dirs++;
} else {
fprintf(stderr, "When using -conf you must specify a config directory\n");
return 255;
}
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-mod")) {
else if (!strcmp(local_argv[x], "-mod")) {
x++;
if (local_argv[x] && strlen(local_argv[x])) {
if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
fprintf(stderr, "When using -mod you must specify a module directory\n");
return 255;
}
SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(strlen(local_argv[x]) + 1);
if (!SWITCH_GLOBAL_dirs.mod_dir) {
fprintf(stderr, "Allocation error\n");
return 255;
}
strcpy(SWITCH_GLOBAL_dirs.mod_dir, local_argv[x]);
} else {
fprintf(stderr, "When using -mod you must specify a module directory\n");
return 255;
}
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-log")) {
else if (!strcmp(local_argv[x], "-log")) {
x++;
if (local_argv[x] && strlen(local_argv[x])) {
if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
fprintf(stderr, "When using -log you must specify a log directory\n");
return 255;
}
SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(strlen(local_argv[x]) + 1);
if (!SWITCH_GLOBAL_dirs.log_dir) {
fprintf(stderr, "Allocation error\n");
@ -682,34 +701,32 @@ int main(int argc, char *argv[])
}
strcpy(SWITCH_GLOBAL_dirs.log_dir, local_argv[x]);
alt_dirs++;
log_set++;
} else {
fprintf(stderr, "When using -log you must specify a log directory\n");
return 255;
}
known_opt++;
log_set = SWITCH_TRUE;
}
if (local_argv[x] && !strcmp(local_argv[x], "-run")) {
else if (!strcmp(local_argv[x], "-run")) {
x++;
if (local_argv[x] && strlen(local_argv[x])) {
if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
fprintf(stderr, "When using -run you must specify a pid directory\n");
return 255;
}
SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(strlen(local_argv[x]) + 1);
if (!SWITCH_GLOBAL_dirs.run_dir) {
fprintf(stderr, "Allocation error\n");
return 255;
}
strcpy(SWITCH_GLOBAL_dirs.run_dir, local_argv[x]);
run_set++;
} else {
fprintf(stderr, "When using -run you must specify a pid directory\n");
return 255;
}
known_opt++;
run_set = SWITCH_TRUE;
}
if (local_argv[x] && !strcmp(local_argv[x], "-db")) {
else if (!strcmp(local_argv[x], "-db")) {
x++;
if (local_argv[x] && strlen(local_argv[x])) {
if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
fprintf(stderr, "When using -db you must specify a db directory\n");
return 255;
}
SWITCH_GLOBAL_dirs.db_dir = (char *) malloc(strlen(local_argv[x]) + 1);
if (!SWITCH_GLOBAL_dirs.db_dir) {
fprintf(stderr, "Allocation error\n");
@ -717,48 +734,118 @@ int main(int argc, char *argv[])
}
strcpy(SWITCH_GLOBAL_dirs.db_dir, local_argv[x]);
alt_dirs++;
} else {
fprintf(stderr, "When using -db you must specify a db directory\n");
return 255;
}
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-scripts")) {
else if (!strcmp(local_argv[x], "-scripts")) {
x++;
if (local_argv[x] && strlen(local_argv[x])) {
if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
fprintf(stderr, "When using -scripts you must specify a scripts directory\n");
return 255;
}
SWITCH_GLOBAL_dirs.script_dir = (char *) malloc(strlen(local_argv[x]) + 1);
if (!SWITCH_GLOBAL_dirs.script_dir) {
fprintf(stderr, "Allocation error\n");
return 255;
}
strcpy(SWITCH_GLOBAL_dirs.script_dir, local_argv[x]);
} else {
fprintf(stderr, "When using -scripts you must specify a scripts directory\n");
return 255;
}
known_opt++;
}
if (local_argv[x] && !strcmp(local_argv[x], "-htdocs")) {
else if (!strcmp(local_argv[x], "-htdocs")) {
x++;
if (local_argv[x] && strlen(local_argv[x])) {
if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
fprintf(stderr, "When using -htdocs you must specify a htdocs directory\n");
return 255;
}
SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(strlen(local_argv[x]) + 1);
if (!SWITCH_GLOBAL_dirs.htdocs_dir) {
fprintf(stderr, "Allocation error\n");
return 255;
}
strcpy(SWITCH_GLOBAL_dirs.htdocs_dir, local_argv[x]);
} else {
fprintf(stderr, "When using -htdocs you must specify a htdocs directory\n");
return 255;
}
known_opt++;
}
if (!known_opt || (local_argv[x] && (!strcmp(local_argv[x], "-help") || !strcmp(local_argv[x], "-h") || !strcmp(local_argv[x], "-?")))) {
printf("%s\n", usageDesc);
exit(0);
else if (!strcmp(local_argv[x], "-temp")) {
x++;
if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
fprintf(stderr, "When using -temp you must specify a temp directory\n");
return 255;
}
SWITCH_GLOBAL_dirs.temp_dir = (char *) malloc(strlen(local_argv[x]) + 1);
if (!SWITCH_GLOBAL_dirs.temp_dir) {
fprintf(stderr, "Allocation error\n");
return 255;
}
strcpy(SWITCH_GLOBAL_dirs.temp_dir, local_argv[x]);
}
else if (!strcmp(local_argv[x], "-storage")) {
x++;
if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
fprintf(stderr, "When using -storage you must specify a storage directory\n");
return 255;
}
SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(strlen(local_argv[x]) + 1);
if (!SWITCH_GLOBAL_dirs.storage_dir) {
fprintf(stderr, "Allocation error\n");
return 255;
}
strcpy(SWITCH_GLOBAL_dirs.storage_dir, local_argv[x]);
}
else if (!strcmp(local_argv[x], "-recordings")) {
x++;
if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
fprintf(stderr, "When using -recordings you must specify a recording directory\n");
return 255;
}
SWITCH_GLOBAL_dirs.recordings_dir = (char *) malloc(strlen(local_argv[x]) + 1);
if (!SWITCH_GLOBAL_dirs.recordings_dir) {
fprintf(stderr, "Allocation error\n");
return 255;
}
strcpy(SWITCH_GLOBAL_dirs.recordings_dir, local_argv[x]);
}
else if (!strcmp(local_argv[x], "-grammar")) {
x++;
if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
fprintf(stderr, "When using -grammar you must specify a grammar directory\n");
return 255;
}
SWITCH_GLOBAL_dirs.grammar_dir = (char *) malloc(strlen(local_argv[x]) + 1);
if (!SWITCH_GLOBAL_dirs.grammar_dir) {
fprintf(stderr, "Allocation error\n");
return 255;
}
strcpy(SWITCH_GLOBAL_dirs.grammar_dir, local_argv[x]);
}
else if (!strcmp(local_argv[x], "-sounds")) {
x++;
if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
fprintf(stderr, "When using -sounds you must specify a sounds directory\n");
return 255;
}
SWITCH_GLOBAL_dirs.sounds_dir = (char *) malloc(strlen(local_argv[x]) + 1);
if (!SWITCH_GLOBAL_dirs.sounds_dir) {
fprintf(stderr, "Allocation error\n");
return 255;
}
strcpy(SWITCH_GLOBAL_dirs.sounds_dir, local_argv[x]);
}
/* Unknown option (always last!) */
else {
fprintf(stderr, "Unknown option '%s', see '%s -help' for a list of valid options\n",
local_argv[x], local_argv[0]);
exit(EXIT_FAILURE);
}
}
@ -788,7 +875,7 @@ int main(int argc, char *argv[])
#if defined(HAVE_SETRLIMIT) && !defined(__sun)
if (!waste && !(flags & SCF_VG)) {
//int x;
struct rlimit rlp;
memset(&rlp, 0, sizeof(rlp));
getrlimit(RLIMIT_STACK, &rlp);
@ -796,6 +883,7 @@ int main(int argc, char *argv[])
if (rlp.rlim_cur != SWITCH_THREAD_STACKSIZE) {
char buf[1024] = "";
int i = 0;
fprintf(stderr, "Error: stacksize %d is not optimal: run ulimit -s %d from your shell before starting the application.\nauto-adjusting stack size for optimal performance...\n",
(int) (rlp.rlim_cur / 1024), SWITCH_THREAD_STACKSIZE / 1024);
@ -812,12 +900,10 @@ int main(int argc, char *argv[])
}
return system(buf);
}
}
#endif
signal(SIGILL, handle_SIGILL);
signal(SIGTERM, handle_SIGILL);
#ifndef WIN32
@ -837,8 +923,7 @@ int main(int argc, char *argv[])
#endif
}
switch(priority) {
switch (priority) {
case 2:
set_realtime_priority();
break;
@ -859,13 +944,15 @@ int main(int argc, char *argv[])
#ifndef WIN32
if (runas_user || runas_group) {
if (change_user_group(runas_user, runas_group) < 0) {
fprintf(stderr, "Failed to switch user / group\n");
fprintf(stderr, "Failed to switch user [%s] / group [%s]\n",
switch_strlen_zero(runas_user) ? "-" : runas_user,
switch_strlen_zero(runas_group) ? "-" : runas_group);
return 255;
}
}
#else
if (win32_service) {
{ /* Attempt to start service */
/* Attempt to start service */
SERVICE_TABLE_ENTRY dispatchTable[] = {
{service_name, &service_main}
,
@ -878,8 +965,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "Error Freeswitch loaded as a console app with -service option\n");
fprintf(stderr, "To install the service load freeswitch with -install\n");
}
exit(0);
}
exit(EXIT_SUCCESS);
}
#endif

View File

@ -3577,7 +3577,9 @@ SWITCH_DECLARE(char *) switch_channel_expand_variables_check(switch_channel_t *c
idx = atoi(ptr);
}
if (vtype == 3 || (sub_val = (char *) switch_channel_get_variable_dup(channel, vname, SWITCH_TRUE, idx))) {
if (!sub_val) sub_val = vname;
if ((sub_val = (char *) switch_channel_get_variable_dup(channel, vname, SWITCH_TRUE, idx))) {
if (var_list && !switch_event_check_permission_list(var_list, vname)) {
sub_val = "INVALID";
}