2012-07-10 22:12:57 +00:00
/*
2005-11-19 20:07:43 +00:00
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
2012-04-18 16:51:48 +00:00
* Copyright ( C ) 2005 - 2012 , Anthony Minessale II < anthm @ freeswitch . org >
2005-11-19 20:07:43 +00:00
*
* Version : MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
*
* The Initial Developer of the Original Code is
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2005-11-19 20:07:43 +00:00
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
2012-07-10 22:12:57 +00:00
*
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2006-09-18 05:08:55 +00:00
* Michael Jerris < mike @ jerris . com >
2007-01-19 12:59:49 +00:00
* Pawel Pierscionek < pawel @ voiceworks . pl >
2007-02-06 17:05:14 +00:00
* Bret McDanel < trixter AT 0xdecafbad . com >
2005-11-19 20:07:43 +00:00
*
*
* switch . c - - Main
*
*/
2006-02-28 21:21:48 +00:00
2007-03-11 04:02:10 +00:00
# ifndef _XOPEN_SOURCE
2007-03-19 00:33:54 +00:00
# define _XOPEN_SOURCE 600
2007-03-11 04:02:10 +00:00
# endif
2009-03-07 02:20:29 +00:00
# ifndef WIN32
# ifdef HAVE_SETRLIMIT
# include <sys/resource.h>
# endif
# endif
2005-11-19 20:07:43 +00:00
# include <switch.h>
2010-01-23 18:37:11 +00:00
# include <switch_version.h>
2007-12-08 03:41:00 +00:00
# include "private/switch_core_pvt.h"
2006-08-18 21:57:47 +00:00
2007-03-02 05:53:45 +00:00
/* pid filename: Stores the process id of the freeswitch process */
2006-08-18 21:57:47 +00:00
# define PIDFILE "freeswitch.pid"
2006-10-30 01:36:51 +00:00
static char * pfile = PIDFILE ;
2010-10-29 17:43:55 +00:00
static int system_ready = 0 ;
2006-08-18 21:57:47 +00:00
2007-03-02 05:53:45 +00:00
/* Picky compiler */
2006-08-18 21:57:47 +00:00
# ifdef __ICC
# pragma warning (disable:167)
# endif
2006-02-23 22:41:08 +00:00
2006-08-19 18:51:22 +00:00
# ifdef WIN32
2008-05-12 19:05:02 +00:00
/* If we are a windows service, what should we be called */
# define SERVICENAME_DEFAULT "FreeSWITCH"
# define SERVICENAME_MAXLEN 256
static char service_name [ SERVICENAME_MAXLEN ] ;
2010-07-29 01:44:45 +00:00
static switch_core_flag_t service_flags = SCF_NONE ;
2006-08-20 03:04:55 +00:00
# include <winsock2.h>
# include <windows.h>
2006-10-30 01:36:51 +00:00
2007-03-02 05:53:45 +00:00
/* event to signal shutdown (for you unix people, this is like a pthread_cond) */
2006-08-19 18:51:22 +00:00
static HANDLE shutdown_event ;
2012-07-11 12:52:20 +00:00
# ifndef PATH_MAX
# define PATH_MAX 256
# endif
2006-08-19 18:51:22 +00:00
# endif
2006-02-26 03:13:01 +00:00
2007-03-02 05:53:45 +00:00
/* signal handler for when freeswitch is running in background mode.
* signal triggers the shutdown of freeswitch
2008-05-12 19:05:02 +00:00
# * /
2008-09-23 22:09:40 +00:00
static void handle_SIGILL ( int sig )
2006-02-23 22:41:08 +00:00
{
2007-10-03 23:43:01 +00:00
int32_t arg = 0 ;
2011-12-14 15:27:31 +00:00
if ( sig ) { } ;
2007-03-02 05:53:45 +00:00
/* send shutdown signal to the freeswitch core */
2006-09-20 20:25:26 +00:00
switch_core_session_ctl ( SCSC_SHUTDOWN , & arg ) ;
2006-10-02 16:48:00 +00:00
return ;
2006-02-23 22:41:08 +00:00
}
2010-10-29 18:00:14 +00:00
# ifndef WIN32
2010-10-29 17:43:55 +00:00
static void handle_SIGUSR2 ( int sig )
{
2012-01-08 20:19:16 +00:00
if ( sig ) { } ;
2010-10-29 17:43:55 +00:00
system_ready = 1 ;
return ;
}
static void handle_SIGCHLD ( int sig )
{
int status = 0 ;
int pid = 0 ;
2012-01-08 20:19:16 +00:00
if ( sig ) { } ;
2010-10-29 17:43:55 +00:00
pid = wait ( & status ) ;
if ( pid > 0 ) {
system_ready = - 1 ;
}
return ;
}
2010-10-29 18:00:14 +00:00
# endif
2010-10-29 17:43:55 +00:00
2007-03-02 05:53:45 +00:00
/* kill a freeswitch process running in background mode */
2006-08-18 21:57:47 +00:00
static int freeswitch_kill_background ( )
{
2007-03-29 22:31:56 +00:00
FILE * f ; /* FILE handle to open the pid file */
2012-07-10 21:32:42 +00:00
char path [ PATH_MAX ] = " " ; /* full path of the PID file */
2007-03-29 22:31:56 +00:00
pid_t pid = 0 ; /* pid from the pid file */
2006-10-30 01:36:51 +00:00
2007-03-02 05:53:45 +00:00
/* set the globals so we can use the global paths. */
2006-08-20 03:04:55 +00:00
switch_core_set_globals ( ) ;
2009-01-15 23:32:19 +00:00
2007-03-02 05:53:45 +00:00
/* get the full path of the pid file. */
2009-09-04 18:26:15 +00:00
switch_snprintf ( path , sizeof ( path ) , " %s%s%s " , SWITCH_GLOBAL_dirs . run_dir , SWITCH_PATH_SEPARATOR , pfile ) ;
2006-10-30 01:36:51 +00:00
2007-03-02 05:53:45 +00:00
/* open the pid file */
2006-08-18 21:57:47 +00:00
if ( ( f = fopen ( path , " r " ) ) = = 0 ) {
2007-03-02 05:53:45 +00:00
/* pid file does not exist */
2006-08-18 21:57:47 +00:00
fprintf ( stderr , " Cannot open pid file %s. \n " , path ) ;
2006-03-01 17:06:10 +00:00
return 255 ;
}
2006-10-30 01:36:51 +00:00
2007-03-02 05:53:45 +00:00
/* pull the pid from the file */
2010-02-06 03:38:24 +00:00
if ( fscanf ( f , " %d " , ( int * ) ( intptr_t ) & pid ) ! = 1 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Unable to get the pid! \n " ) ;
2007-08-03 21:29:01 +00:00
}
2006-10-30 01:36:51 +00:00
2007-03-02 05:53:45 +00:00
/* if we have a valid pid */
2006-08-18 21:57:47 +00:00
if ( pid > 0 ) {
2006-10-30 01:36:51 +00:00
2007-03-02 05:53:45 +00:00
/* kill the freeswitch running at the pid we found */
2006-08-19 18:51:22 +00:00
fprintf ( stderr , " Killing: %d \n " , ( int ) pid ) ;
# ifdef WIN32
2008-10-06 23:05:55 +00:00
/* for windows we need the event to signal for shutting down a background FreeSWITCH */
2006-08-19 18:51:22 +00:00
snprintf ( path , sizeof ( path ) , " Global \\ Freeswitch.%d " , pid ) ;
2006-10-30 01:36:51 +00:00
2007-03-02 05:53:45 +00:00
/* open the event so we can signal it */
2006-08-19 19:00:35 +00:00
shutdown_event = OpenEvent ( EVENT_MODIFY_STATE , FALSE , path ) ;
2006-10-30 01:36:51 +00:00
2008-10-06 23:05:55 +00:00
/* did we successfully open the event */
2006-08-19 19:00:35 +00:00
if ( ! shutdown_event ) {
/* we can't get the event, so we can't signal the process to shutdown */
2006-08-19 18:51:22 +00:00
fprintf ( stderr , " ERROR: Can't Shutdown: %d \n " , ( int ) pid ) ;
2006-08-19 19:00:35 +00:00
} else {
2007-03-02 05:53:45 +00:00
/* signal the event to shutdown */
2006-08-19 19:00:35 +00:00
SetEvent ( shutdown_event ) ;
2007-12-15 20:04:49 +00:00
/* cleanup */
CloseHandle ( shutdown_event ) ;
2006-08-19 19:00:35 +00:00
}
2006-08-19 18:51:22 +00:00
# else
2007-03-02 05:53:45 +00:00
/* for unix, send the signal to kill. */
2008-11-11 19:27:49 +00:00
kill ( pid , SIGTERM ) ;
2006-03-30 23:02:50 +00:00
# endif
2006-08-18 21:57:47 +00:00
}
2006-03-01 17:06:10 +00:00
2007-03-02 05:53:45 +00:00
/* be nice and close the file handle to the pid file */
2006-08-19 18:51:22 +00:00
fclose ( f ) ;
2006-10-30 01:36:51 +00:00
2006-08-18 21:57:47 +00:00
return 0 ;
}
2006-08-11 23:27:08 +00:00
2006-08-20 03:04:55 +00:00
# ifdef WIN32
2006-10-30 01:36:51 +00:00
2007-03-02 05:53:45 +00:00
/* we need these vars to handle the service */
2006-08-20 03:36:14 +00:00
SERVICE_STATUS_HANDLE hStatus ;
SERVICE_STATUS status ;
2007-03-02 05:53:45 +00:00
/* Handler function for service start/stop from the service */
2007-03-29 22:31:56 +00:00
void WINAPI ServiceCtrlHandler ( DWORD control )
2006-08-20 03:36:14 +00:00
{
2007-03-29 22:31:56 +00:00
switch ( control ) {
2006-10-30 01:36:51 +00:00
case SERVICE_CONTROL_SHUTDOWN :
case SERVICE_CONTROL_STOP :
2007-03-02 05:53:45 +00:00
/* Shutdown freeswitch */
2007-03-02 09:22:34 +00:00
switch_core_destroy ( ) ;
2008-10-06 23:05:55 +00:00
/* set service status values */
2006-10-30 01:36:51 +00:00
status . dwCurrentState = SERVICE_STOPPED ;
status . dwWin32ExitCode = 0 ;
status . dwCheckPoint = 0 ;
status . dwWaitHint = 0 ;
break ;
case SERVICE_CONTROL_INTERROGATE :
2007-03-02 05:53:45 +00:00
/* we already set the service status every time it changes. */
/* if there are other times we change it and don't update, we should do so here */
2006-10-30 01:36:51 +00:00
break ;
}
2007-03-29 22:31:56 +00:00
SetServiceStatus ( hStatus , & status ) ;
2006-08-20 03:36:14 +00:00
}
2007-03-02 05:53:45 +00:00
/* the main service entry point */
2007-03-29 22:31:56 +00:00
void WINAPI service_main ( DWORD numArgs , char * * args )
2006-08-20 03:36:14 +00:00
{
2011-04-01 17:30:24 +00:00
switch_core_flag_t flags = SCF_USE_SQL | SCF_USE_AUTO_NAT | SCF_USE_NAT_MAPPING | SCF_CALIBRATE_CLOCK | SCF_USE_CLOCK_RT ;
2007-03-02 05:53:45 +00:00
const char * err = NULL ; /* error value for return from freeswitch initialization */
2010-07-29 01:44:45 +00:00
/* Override flags if they have been set earlier */
if ( service_flags ! = SCF_NONE )
flags = service_flags ;
2007-03-02 05:53:45 +00:00
/* we have to initialize the service-specific stuff */
2007-03-29 22:31:56 +00:00
memset ( & status , 0 , sizeof ( SERVICE_STATUS ) ) ;
2006-10-30 01:36:51 +00:00
status . dwServiceType = SERVICE_WIN32 ;
status . dwCurrentState = SERVICE_START_PENDING ;
2012-04-18 14:17:52 +00:00
status . dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN ;
2006-08-20 03:36:14 +00:00
2007-03-02 05:53:45 +00:00
/* register our handler for service control messages */
2008-05-12 19:05:02 +00:00
hStatus = RegisterServiceCtrlHandler ( service_name , & ServiceCtrlHandler ) ;
2006-08-20 03:36:14 +00:00
2007-03-02 05:53:45 +00:00
/* update the service status */
2007-03-29 22:31:56 +00:00
SetServiceStatus ( hStatus , & status ) ;
2006-11-05 19:41:03 +00:00
2008-07-21 05:05:36 +00:00
switch_core_set_globals ( ) ;
2007-03-02 05:53:45 +00:00
/* attempt to initialize freeswitch and load modules */
2007-12-06 13:40:00 +00:00
if ( switch_core_init_and_modload ( flags , SWITCH_FALSE , & err ) ! = SWITCH_STATUS_SUCCESS ) {
2008-10-06 23:05:55 +00:00
/* freeswitch did not start successfully */
2006-10-30 01:36:51 +00:00
status . dwCurrentState = SERVICE_STOPPED ;
2006-08-20 03:04:55 +00:00
} else {
2007-03-02 05:53:45 +00:00
/* freeswitch started */
2006-08-20 03:04:55 +00:00
status . dwCurrentState = SERVICE_RUNNING ;
}
2006-08-20 03:36:14 +00:00
2007-03-02 05:53:45 +00:00
/* update the service status */
2007-03-29 22:31:56 +00:00
SetServiceStatus ( hStatus , & status ) ;
2006-08-20 03:36:14 +00:00
}
2008-09-17 02:09:58 +00:00
# else
2012-07-10 22:11:59 +00:00
static void daemonize ( int do_wait )
2010-02-06 03:38:24 +00:00
{
2008-09-17 02:09:58 +00:00
int fd ;
pid_t pid ;
2010-10-29 17:43:55 +00:00
if ( ! do_wait ) {
switch ( fork ( ) ) {
2012-07-10 22:11:59 +00:00
case 0 : /* child process */
2010-10-29 17:43:55 +00:00
break ;
case - 1 :
fprintf ( stderr , " Error Backgrounding (fork)! %d - %s \n " , errno , strerror ( errno ) ) ;
2012-07-10 22:11:59 +00:00
exit ( EXIT_SUCCESS ) ;
2010-10-29 17:43:55 +00:00
break ;
2012-07-10 22:11:59 +00:00
default : /* parent process */
exit ( EXIT_SUCCESS ) ;
2010-10-29 17:43:55 +00:00
}
2008-09-17 02:09:58 +00:00
2010-10-29 17:43:55 +00:00
if ( setsid ( ) < 0 ) {
fprintf ( stderr , " Error Backgrounding (setsid)! %d - %s \n " , errno , strerror ( errno ) ) ;
2012-07-10 22:11:59 +00:00
exit ( EXIT_SUCCESS ) ;
2010-10-29 17:43:55 +00:00
}
2008-09-17 02:09:58 +00:00
}
2010-10-29 17:43:55 +00:00
2008-09-17 02:09:58 +00:00
pid = fork ( ) ;
2010-10-29 17:43:55 +00:00
2008-09-17 02:09:58 +00:00
switch ( pid ) {
2012-07-10 22:11:59 +00:00
case 0 : /* child process */
2010-02-06 03:38:24 +00:00
break ;
case - 1 :
fprintf ( stderr , " Error Backgrounding (fork2)! %d - %s \n " , errno , strerror ( errno ) ) ;
2012-07-10 22:11:59 +00:00
exit ( EXIT_SUCCESS ) ;
2010-02-06 03:38:24 +00:00
break ;
2012-07-10 22:11:59 +00:00
default : /* parent process */
fprintf ( stderr , " %d Backgrounding. \n " , ( int ) pid ) ;
2010-10-29 17:43:55 +00:00
2012-07-10 22:11:59 +00:00
if ( do_wait ) {
unsigned int sanity = 60 ;
char * o ;
2010-10-29 17:43:55 +00:00
2012-07-10 22:11:59 +00:00
if ( ( o = getenv ( " FREESWITCH_BG_TIMEOUT " ) ) ) {
int tmp = atoi ( o ) ;
if ( tmp > 0 ) {
sanity = tmp ;
2010-10-29 18:00:14 +00:00
}
2012-07-10 22:11:59 +00:00
}
2010-10-29 18:00:14 +00:00
2012-07-10 22:11:59 +00:00
while ( - - sanity & & ! system_ready ) {
2010-10-29 17:43:55 +00:00
2012-07-10 22:11:59 +00:00
if ( sanity % 2 = = 0 ) {
printf ( " FreeSWITCH[%d] Waiting for background process pid:%d to be ready..... \n " , ( int ) getpid ( ) , ( int ) pid ) ;
2010-10-29 17:43:55 +00:00
}
2012-07-10 22:11:59 +00:00
sleep ( 1 ) ;
}
if ( ! system_ready ) {
printf ( " FreeSWITCH[%d] Error starting system! pid:%d \n " , ( int ) getpid ( ) , ( int ) pid ) ;
kill ( pid , 9 ) ;
exit ( EXIT_FAILURE ) ;
2010-10-29 17:43:55 +00:00
}
2012-07-10 22:11:59 +00:00
printf ( " FreeSWITCH[%d] System Ready pid:%d \n " , ( int ) getpid ( ) , ( int ) pid ) ;
2010-10-29 17:43:55 +00:00
}
2012-07-10 22:11:59 +00:00
exit ( EXIT_SUCCESS ) ;
2008-09-17 02:09:58 +00:00
}
2010-10-29 17:43:55 +00:00
if ( do_wait ) {
setsid ( ) ;
}
2008-09-17 02:09:58 +00:00
/* redirect std* to null */
fd = open ( " /dev/null " , O_RDONLY ) ;
if ( fd ! = 0 ) {
dup2 ( fd , 0 ) ;
close ( fd ) ;
}
2012-07-10 22:11:59 +00:00
2008-09-17 02:09:58 +00:00
fd = open ( " /dev/null " , O_WRONLY ) ;
if ( fd ! = 1 ) {
dup2 ( fd , 1 ) ;
close ( fd ) ;
}
2012-07-10 22:11:59 +00:00
2008-09-17 02:09:58 +00:00
fd = open ( " /dev/null " , O_WRONLY ) ;
if ( fd ! = 2 ) {
dup2 ( fd , 2 ) ;
close ( fd ) ;
}
}
2006-08-20 03:04:55 +00:00
# endif
2012-07-11 12:52:20 +00:00
static const char usage [ ] =
2012-07-10 13:08:59 +00:00
" 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 "
" \t -uninstall -- remove freeswitch as a service \n "
" \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 "
# endif
# 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 "
" \t -vg -- run under valgrind \n "
" \t -nosql -- disable internal sql scoreboard \n "
" \t -heavy-timer -- Heavy Timer, possibly more accurate but at a cost \n "
" \t -nonat -- disable auto nat detection \n "
" \t -nonatmap -- disable auto nat port mapping \n "
" \t -nocal -- disable clock calibration \n "
" \t -nort -- disable clock clock_realtime \n "
" \t -stop -- stop freeswitch \n "
" \t -nc -- do not output to a console and background \n "
# ifndef WIN32
" \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 "
2012-07-10 22:50:46 +00:00
" \n \t Options to control locations of files: \n "
2012-07-12 17:52:00 +00:00
" \t -base [basedir] -- alternate prefix directory \n "
2012-07-10 22:50:46 +00:00
" \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 " ;
2012-07-10 13:08:59 +00:00
2012-07-10 21:32:42 +00:00
/**
* 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 ] = = ' - ' ) ;
}
2007-03-02 05:53:45 +00:00
/* the main application entry point */
2006-08-18 21:57:47 +00:00
int main ( int argc , char * argv [ ] )
{
2012-07-10 21:32:42 +00:00
char pid_path [ PATH_MAX ] = " " ; /* full path to the pid file */
2007-12-08 03:41:00 +00:00
char pid_buffer [ 32 ] = " " ; /* pid string */
2008-11-21 15:52:22 +00:00
char old_pid_buffer [ 32 ] = " " ; /* pid string */
switch_size_t pid_len , old_pid_len ;
2007-03-02 05:53:45 +00:00
const char * err = NULL ; /* error value for return from freeswitch initialization */
2007-01-19 22:47:23 +00:00
# ifndef WIN32
2012-07-10 21:32:42 +00:00
switch_bool_t nf = SWITCH_FALSE ; /* TRUE if we are running in nofork mode */
switch_bool_t do_wait = SWITCH_FALSE ;
2007-10-23 15:56:23 +00:00
char * runas_user = NULL ;
char * runas_group = NULL ;
2010-02-02 22:53:36 +00:00
# else
2012-07-10 21:32:42 +00:00
switch_bool_t win32_service = SWITCH_FALSE ;
2007-01-19 22:47:23 +00:00
# endif
2012-07-10 21:32:42 +00:00
switch_bool_t nc = SWITCH_FALSE ; /* TRUE if we are running in noconsole mode */
2007-03-29 22:31:56 +00:00
pid_t pid = 0 ;
2010-02-06 03:38:24 +00:00
int i , x ;
2009-07-24 18:20:37 +00:00
char * opts ;
char opts_str [ 1024 ] = " " ;
char * local_argv [ 1024 ] = { 0 } ;
2009-10-15 15:25:06 +00:00
int local_argc = argc ;
2009-07-24 18:20:37 +00:00
char * arg_argv [ 128 ] = { 0 } ;
2010-10-29 17:43:55 +00:00
int alt_dirs = 0 , log_set = 0 , run_set = 0 , do_kill = 0 ;
2011-09-12 21:13:19 +00:00
int priority = 0 ;
2009-08-01 05:53:28 +00:00
# ifdef __sun
switch_core_flag_t flags = SCF_USE_SQL ;
# else
2011-04-01 17:30:24 +00:00
switch_core_flag_t flags = SCF_USE_SQL | SCF_USE_AUTO_NAT | SCF_USE_NAT_MAPPING | SCF_CALIBRATE_CLOCK | SCF_USE_CLOCK_RT ;
2009-08-01 05:53:28 +00:00
# endif
2008-10-02 17:40:41 +00:00
int ret = 0 ;
2008-10-02 16:46:20 +00:00
switch_status_t destroy_status ;
2008-05-27 04:34:23 +00:00
switch_file_t * fd ;
2007-12-08 03:41:00 +00:00
switch_memory_pool_t * pool = NULL ;
2009-03-07 02:20:29 +00:00
# ifdef HAVE_SETRLIMIT
2012-07-10 21:32:42 +00:00
switch_bool_t waste = SWITCH_FALSE ;
2009-03-07 02:20:29 +00:00
# endif
2007-12-08 03:41:00 +00:00
2009-07-24 18:20:37 +00:00
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 + + ) {
2009-10-15 15:25:06 +00:00
local_argv [ local_argc + + ] = arg_argv [ x ] ;
2009-07-24 18:20:37 +00:00
}
}
if ( local_argv [ 0 ] & & strstr ( local_argv [ 0 ] , " freeswitchd " ) ) {
2012-07-10 21:32:42 +00:00
nc = SWITCH_TRUE ;
2009-01-29 00:17:33 +00:00
}
2009-10-15 15:25:06 +00:00
for ( x = 1 ; x < local_argc ; x + + ) {
2012-07-10 13:08:59 +00:00
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 ) ;
}
2006-09-20 20:25:26 +00:00
# ifdef WIN32
2012-07-10 21:32:42 +00:00
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 ( ! 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 ) ;
2006-09-20 20:25:26 +00:00
}
2012-07-10 21:32:42 +00:00
win32_service = SWITCH_TRUE ;
continue ;
}
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 ( ! 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 ) ;
2006-09-20 20:25:26 +00:00
}
2009-03-07 02:20:29 +00:00
2012-07-10 21:32:42 +00:00
GetModuleFileName ( NULL , exePath , sizeof ( exePath ) ) ;
snprintf ( servicePath , sizeof ( servicePath ) , " %s -service %s " , exePath , service_name ) ;
/* Perform service installation */
hSCManager = OpenSCManager ( NULL , NULL , SC_MANAGER_ALL_ACCESS ) ;
if ( ! hSCManager ) {
fprintf ( stderr , " Could not open service manager (%d). \n " , GetLastError ( ) ) ;
exit ( EXIT_FAILURE ) ;
2006-09-20 20:25:26 +00:00
}
2012-07-10 21:32:42 +00:00
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 ( ) ) ;
CloseServiceHandle ( hSCManager ) ;
exit ( EXIT_FAILURE ) ;
}
/* Set desc, and don't care if it succeeds */
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 ( EXIT_SUCCESS ) ;
2006-08-20 03:36:14 +00:00
}
2010-07-29 01:44:45 +00:00
2012-07-10 21:32:42 +00:00
else if ( x = = 1 & & ! strcmp ( local_argv [ x ] , " -uninstall " ) ) {
SC_HANDLE hService ;
SC_HANDLE hSCManager ;
BOOL deleted ;
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 */
hSCManager = OpenSCManager ( NULL , NULL , SC_MANAGER_ALL_ACCESS ) ;
if ( ! hSCManager ) {
fprintf ( stderr , " Could not open service manager (%d). \n " , GetLastError ( ) ) ;
exit ( EXIT_FAILURE ) ;
}
hService = OpenService ( hSCManager , service_name , DELETE ) ;
if ( ! hService ) {
fprintf ( stderr , " Error opening service (%d). \n " , GetLastError ( ) ) ;
CloseServiceHandle ( hSCManager ) ;
exit ( EXIT_FAILURE ) ;
}
/* remove the service! */
deleted = DeleteService ( hService ) ;
if ( ! deleted ) {
fprintf ( stderr , " Error deleting service (%d). \n " , GetLastError ( ) ) ;
}
CloseServiceHandle ( hService ) ;
CloseServiceHandle ( hSCManager ) ;
exit ( deleted ? EXIT_SUCCESS : EXIT_FAILURE ) ;
}
else if ( ! strcmp ( local_argv [ x ] , " -monotonic-clock " ) ) {
2010-07-29 01:44:45 +00:00
flags | = SCF_USE_WIN32_MONOTONIC ;
}
2007-01-19 12:59:49 +00:00
# else
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -u " ) ) {
2007-10-23 15:56:23 +00:00
x + + ;
2012-07-10 21:32:42 +00:00
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 ) ;
2007-10-23 15:56:23 +00:00
}
2012-07-10 21:32:42 +00:00
runas_user = local_argv [ x ] ;
2007-10-23 15:56:23 +00:00
}
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -g " ) ) {
2007-10-23 15:56:23 +00:00
x + + ;
2012-07-10 21:32:42 +00:00
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 ) ;
2007-10-23 15:56:23 +00:00
}
2012-07-10 21:32:42 +00:00
runas_group = local_argv [ x ] ;
2007-10-23 15:56:23 +00:00
}
2007-01-19 22:47:23 +00:00
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -nf " ) ) {
nf = SWITCH_TRUE ;
2007-01-19 12:59:49 +00:00
}
2010-01-23 18:37:11 +00:00
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -version " ) ) {
2012-07-20 07:33:40 +00:00
fprintf ( stdout , " FreeSWITCH version: %s (%s) \n " , SWITCH_VERSION_FULL , SWITCH_VERSION_FULL_HUMAN ) ;
2012-07-10 21:32:42 +00:00
exit ( EXIT_SUCCESS ) ;
2010-01-23 18:37:11 +00:00
}
2006-08-20 03:04:55 +00:00
# endif
2007-12-18 16:55:39 +00:00
# ifdef HAVE_SETRLIMIT
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -core " ) ) {
2012-07-10 22:14:01 +00:00
struct rlimit rlp ;
2007-12-18 16:55:39 +00:00
memset ( & rlp , 0 , sizeof ( rlp ) ) ;
rlp . rlim_cur = RLIM_INFINITY ;
rlp . rlim_max = RLIM_INFINITY ;
setrlimit ( RLIMIT_CORE , & rlp ) ;
}
2009-03-07 02:20:29 +00:00
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -waste " ) ) {
2011-02-28 17:25:42 +00:00
fprintf ( stderr , " WARNING: Wasting up to 8 megs of memory per thread. \n " ) ;
sleep ( 2 ) ;
2012-07-10 21:32:42 +00:00
waste = SWITCH_TRUE ;
2011-02-28 17:25:42 +00:00
}
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -no-auto-stack " ) ) {
waste = SWITCH_TRUE ;
2009-03-07 02:20:29 +00:00
}
2007-12-18 16:55:39 +00:00
# endif
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -hp " ) | | ! strcmp ( local_argv [ x ] , " -rp " ) ) {
2011-09-12 21:13:19 +00:00
priority = 2 ;
}
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -lp " ) ) {
2011-09-12 21:13:19 +00:00
priority = - 1 ;
}
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -np " ) ) {
2011-09-12 21:13:19 +00:00
priority = 1 ;
2006-09-20 20:25:26 +00:00
}
2006-10-30 01:36:51 +00:00
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -nosql " ) ) {
2007-09-29 01:06:08 +00:00
flags & = ~ SCF_USE_SQL ;
}
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -nonat " ) ) {
2009-06-02 16:55:10 +00:00
flags & = ~ SCF_USE_AUTO_NAT ;
}
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -nonatmap " ) ) {
2011-04-01 17:30:24 +00:00
flags & = ~ SCF_USE_NAT_MAPPING ;
}
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -heavy-timer " ) ) {
2010-03-01 19:25:27 +00:00
flags | = SCF_USE_HEAVY_TIMING ;
2010-01-15 21:09:51 +00:00
}
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -nort " ) ) {
2010-01-15 21:09:51 +00:00
flags & = ~ SCF_USE_CLOCK_RT ;
}
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -nocal " ) ) {
2010-01-15 21:09:51 +00:00
flags & = ~ SCF_CALIBRATE_CLOCK ;
}
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -vg " ) ) {
2008-08-22 19:00:56 +00:00
flags | = SCF_VG ;
}
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -stop " ) ) {
do_kill = SWITCH_TRUE ;
2006-09-20 20:25:26 +00:00
}
2006-08-20 03:04:55 +00:00
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -nc " ) ) {
nc = SWITCH_TRUE ;
2007-01-19 22:47:23 +00:00
}
2010-10-29 17:43:55 +00:00
# ifndef WIN32
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -ncwait " ) ) {
nc = SWITCH_TRUE ;
do_wait = SWITCH_TRUE ;
2010-10-29 17:43:55 +00:00
}
# endif
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -c " ) ) {
nc = SWITCH_FALSE ;
2008-01-25 14:08:53 +00:00
}
2007-02-06 17:05:14 +00:00
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -conf " ) ) {
2007-03-29 22:31:56 +00:00
x + + ;
2012-07-10 21:32:42 +00:00
if ( switch_strlen_zero ( local_argv [ x ] ) | | is_option ( local_argv [ x ] ) ) {
2007-03-29 22:31:56 +00:00
fprintf ( stderr , " When using -conf you must specify a config directory \n " ) ;
return 255 ;
}
2012-07-10 21:32:42 +00:00
SWITCH_GLOBAL_dirs . conf_dir = ( char * ) malloc ( strlen ( local_argv [ x ] ) + 1 ) ;
if ( ! SWITCH_GLOBAL_dirs . conf_dir ) {
fprintf ( stderr , " Allocation error \n " ) ;
return 255 ;
}
strcpy ( SWITCH_GLOBAL_dirs . conf_dir , local_argv [ x ] ) ;
alt_dirs + + ;
2007-03-29 22:31:56 +00:00
}
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -mod " ) ) {
2008-10-09 16:05:35 +00:00
x + + ;
2012-07-10 21:32:42 +00:00
if ( switch_strlen_zero ( local_argv [ x ] ) | | is_option ( local_argv [ x ] ) ) {
2008-10-09 16:05:35 +00:00
fprintf ( stderr , " When using -mod you must specify a module directory \n " ) ;
return 255 ;
}
2012-07-10 21:32:42 +00:00
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 ] ) ;
2008-10-09 16:05:35 +00:00
}
2010-02-06 03:38:24 +00:00
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -log " ) ) {
2007-03-29 22:31:56 +00:00
x + + ;
2012-07-10 21:32:42 +00:00
if ( switch_strlen_zero ( local_argv [ x ] ) | | is_option ( local_argv [ x ] ) ) {
2007-03-29 22:31:56 +00:00
fprintf ( stderr , " When using -log you must specify a log directory \n " ) ;
return 255 ;
}
2012-07-10 21:32:42 +00:00
SWITCH_GLOBAL_dirs . log_dir = ( char * ) malloc ( strlen ( local_argv [ x ] ) + 1 ) ;
if ( ! SWITCH_GLOBAL_dirs . log_dir ) {
fprintf ( stderr , " Allocation error \n " ) ;
return 255 ;
}
strcpy ( SWITCH_GLOBAL_dirs . log_dir , local_argv [ x ] ) ;
alt_dirs + + ;
log_set = SWITCH_TRUE ;
2007-03-29 22:31:56 +00:00
}
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -run " ) ) {
2009-09-04 18:26:15 +00:00
x + + ;
2012-07-10 21:32:42 +00:00
if ( switch_strlen_zero ( local_argv [ x ] ) | | is_option ( local_argv [ x ] ) ) {
2009-09-04 18:26:15 +00:00
fprintf ( stderr , " When using -run you must specify a pid directory \n " ) ;
return 255 ;
}
2012-07-10 21:32:42 +00:00
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 = SWITCH_TRUE ;
2009-09-04 18:26:15 +00:00
}
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -db " ) ) {
2007-03-29 22:31:56 +00:00
x + + ;
2012-07-10 21:32:42 +00:00
if ( switch_strlen_zero ( local_argv [ x ] ) | | is_option ( local_argv [ x ] ) ) {
2007-03-29 22:31:56 +00:00
fprintf ( stderr , " When using -db you must specify a db directory \n " ) ;
return 255 ;
}
2012-07-10 21:32:42 +00:00
SWITCH_GLOBAL_dirs . db_dir = ( char * ) malloc ( strlen ( local_argv [ x ] ) + 1 ) ;
if ( ! SWITCH_GLOBAL_dirs . db_dir ) {
fprintf ( stderr , " Allocation error \n " ) ;
return 255 ;
}
strcpy ( SWITCH_GLOBAL_dirs . db_dir , local_argv [ x ] ) ;
alt_dirs + + ;
2007-04-21 16:58:35 +00:00
}
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -scripts " ) ) {
2007-10-20 06:46:16 +00:00
x + + ;
2012-07-10 21:32:42 +00:00
if ( switch_strlen_zero ( local_argv [ x ] ) | | is_option ( local_argv [ x ] ) ) {
2007-10-20 06:46:16 +00:00
fprintf ( stderr , " When using -scripts you must specify a scripts directory \n " ) ;
return 255 ;
}
2012-07-10 21:32:42 +00:00
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 ] ) ;
2007-10-20 06:46:16 +00:00
}
2012-07-10 21:32:42 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -htdocs " ) ) {
2009-02-03 19:37:58 +00:00
x + + ;
2012-07-10 21:32:42 +00:00
if ( switch_strlen_zero ( local_argv [ x ] ) | | is_option ( local_argv [ x ] ) ) {
2009-02-03 19:37:58 +00:00
fprintf ( stderr , " When using -htdocs you must specify a htdocs directory \n " ) ;
return 255 ;
}
2012-07-10 21:32:42 +00:00
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 ] ) ;
}
2012-07-10 22:50:46 +00:00
2012-07-12 17:52:00 +00:00
else if ( ! strcmp ( local_argv [ x ] , " -base " ) ) {
x + + ;
if ( switch_strlen_zero ( local_argv [ x ] ) | | is_option ( local_argv [ x ] ) ) {
fprintf ( stderr , " When using -base you must specify a base directory \n " ) ;
return 255 ;
}
SWITCH_GLOBAL_dirs . base_dir = ( char * ) malloc ( strlen ( local_argv [ x ] ) + 1 ) ;
if ( ! SWITCH_GLOBAL_dirs . base_dir ) {
fprintf ( stderr , " Allocation error \n " ) ;
return 255 ;
}
strcpy ( SWITCH_GLOBAL_dirs . base_dir , local_argv [ x ] ) ;
}
2012-07-10 22:50:46 +00:00
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 ;
}
2012-07-12 08:02:09 +00:00
SWITCH_GLOBAL_dirs . storage_dir = ( char * ) malloc ( strlen ( local_argv [ x ] ) + 1 ) ;
2012-07-10 22:50:46 +00:00
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 ] ) ;
}
2012-07-10 21:32:42 +00:00
/* Unknown option (always last!) */
else {
2012-07-10 13:08:59 +00:00
fprintf ( stderr , " Unknown option '%s', see '%s -help' for a list of valid options \n " ,
local_argv [ x ] , local_argv [ 0 ] ) ;
exit ( EXIT_FAILURE ) ;
2007-03-29 22:31:56 +00:00
}
2007-12-15 20:04:49 +00:00
}
2010-02-06 03:38:24 +00:00
2009-10-26 21:46:21 +00:00
if ( log_set & & ! run_set ) {
2009-10-27 14:01:13 +00:00
SWITCH_GLOBAL_dirs . run_dir = ( char * ) malloc ( strlen ( SWITCH_GLOBAL_dirs . log_dir ) + 1 ) ;
if ( ! SWITCH_GLOBAL_dirs . run_dir ) {
fprintf ( stderr , " Allocation error \n " ) ;
return 255 ;
}
2009-10-26 21:46:21 +00:00
strcpy ( SWITCH_GLOBAL_dirs . run_dir , SWITCH_GLOBAL_dirs . log_dir ) ;
}
2010-10-29 17:43:55 +00:00
if ( do_kill ) {
2009-10-26 21:46:21 +00:00
return freeswitch_kill_background ( ) ;
}
2007-03-29 22:31:56 +00:00
2007-12-15 20:04:49 +00:00
if ( apr_initialize ( ) ! = SWITCH_STATUS_SUCCESS ) {
2008-01-07 10:45:06 +00:00
fprintf ( stderr , " FATAL ERROR! Could not initialize APR \n " ) ;
2007-12-15 20:04:49 +00:00
return 255 ;
2006-08-18 21:57:47 +00:00
}
2007-03-29 22:31:56 +00:00
if ( alt_dirs & & alt_dirs ! = 3 ) {
2007-10-20 06:46:16 +00:00
fprintf ( stderr , " You must specify all or none of -conf, -log, and -db \n " ) ;
2007-02-06 17:05:14 +00:00
return 255 ;
}
2006-08-18 21:57:47 +00:00
2009-03-16 20:14:36 +00:00
# if defined(HAVE_SETRLIMIT) && !defined(__sun)
2009-03-20 01:22:40 +00:00
if ( ! waste & & ! ( flags & SCF_VG ) ) {
2012-07-10 22:14:01 +00:00
struct rlimit rlp ;
2010-10-29 17:43:55 +00:00
2009-03-07 02:20:29 +00:00
memset ( & rlp , 0 , sizeof ( rlp ) ) ;
2011-04-22 21:43:29 +00:00
getrlimit ( RLIMIT_STACK , & rlp ) ;
2010-10-29 17:43:55 +00:00
2012-07-02 16:20:05 +00:00
if ( rlp . rlim_cur ! = SWITCH_THREAD_STACKSIZE ) {
2009-03-07 14:07:48 +00:00
char buf [ 1024 ] = " " ;
int i = 0 ;
2012-07-10 22:12:57 +00:00
2012-07-02 16:20:05 +00:00
fprintf ( stderr , " Error: stacksize %d is not optimal: run ulimit -s %d from your shell before starting the application. \n auto-adjusting stack size for optimal performance... \n " ,
( int ) ( rlp . rlim_cur / 1024 ) , SWITCH_THREAD_STACKSIZE / 1024 ) ;
2012-07-10 22:12:57 +00:00
2009-03-07 02:20:29 +00:00
memset ( & rlp , 0 , sizeof ( rlp ) ) ;
rlp . rlim_cur = SWITCH_THREAD_STACKSIZE ;
rlp . rlim_max = SWITCH_THREAD_STACKSIZE ;
setrlimit ( RLIMIT_STACK , & rlp ) ;
2012-07-10 22:12:57 +00:00
2009-03-07 14:07:48 +00:00
apr_terminate ( ) ;
2010-02-06 03:38:24 +00:00
ret = ( int ) execv ( argv [ 0 ] , argv ) ;
2012-07-10 22:12:57 +00:00
2010-02-06 03:38:24 +00:00
for ( i = 0 ; i < argc ; i + + ) {
2009-10-15 15:25:06 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " %s " , argv [ i ] ) ;
2009-03-07 14:07:48 +00:00
}
2010-02-06 03:38:24 +00:00
2012-07-10 22:12:57 +00:00
return system ( buf ) ;
2009-03-07 02:20:29 +00:00
}
}
# endif
2010-10-29 17:43:55 +00:00
signal ( SIGILL , handle_SIGILL ) ;
signal ( SIGTERM , handle_SIGILL ) ;
# ifndef WIN32
if ( do_wait ) {
signal ( SIGUSR2 , handle_SIGUSR2 ) ;
signal ( SIGCHLD , handle_SIGCHLD ) ;
}
# endif
2012-07-10 22:12:57 +00:00
2010-10-29 17:43:55 +00:00
if ( nc ) {
# ifdef WIN32
FreeConsole ( ) ;
# else
if ( ! nf ) {
daemonize ( do_wait ) ;
}
# endif
}
2012-07-10 22:12:57 +00:00
switch ( priority ) {
2011-09-12 21:13:19 +00:00
case 2 :
set_realtime_priority ( ) ;
break ;
case 1 :
2011-03-22 18:27:37 +00:00
set_normal_priority ( ) ;
2011-09-12 21:13:19 +00:00
break ;
case - 1 :
set_low_priority ( ) ;
break ;
default :
set_auto_priority ( ) ;
break ;
2007-10-23 15:56:23 +00:00
}
2011-09-12 21:13:19 +00:00
2008-01-07 20:40:59 +00:00
switch_core_setrlimits ( ) ;
2008-05-27 04:34:23 +00:00
2009-03-07 02:20:29 +00:00
2007-10-23 15:56:23 +00:00
# ifndef WIN32
if ( runas_user | | runas_group ) {
2008-02-15 23:16:01 +00:00
if ( change_user_group ( runas_user , runas_group ) < 0 ) {
2012-07-10 22:16:21 +00:00
fprintf ( stderr , " Failed to switch user [%s] / group [%s] \n " ,
switch_strlen_zero ( runas_user ) ? " - " : runas_user ,
switch_strlen_zero ( runas_group ) ? " - " : runas_group ) ;
2007-10-23 15:56:23 +00:00
return 255 ;
}
}
2010-02-02 22:53:36 +00:00
# else
if ( win32_service ) {
2012-07-10 21:32:42 +00:00
/* Attempt to start service */
SERVICE_TABLE_ENTRY dispatchTable [ ] = {
{ service_name , & service_main }
,
{ NULL , NULL }
} ;
service_flags = flags ; /* copy parsed flags for service startup */
if ( StartServiceCtrlDispatcher ( dispatchTable ) = = 0 ) {
/* Not loaded as a service */
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 ( EXIT_SUCCESS ) ;
2010-02-02 22:53:36 +00:00
}
2007-10-23 15:56:23 +00:00
# endif
2007-12-08 03:41:00 +00:00
switch_core_set_globals ( ) ;
pid = getpid ( ) ;
2007-12-25 03:00:29 +00:00
memset ( pid_buffer , 0 , sizeof ( pid_buffer ) ) ;
2009-09-04 18:26:15 +00:00
switch_snprintf ( pid_path , sizeof ( pid_path ) , " %s%s%s " , SWITCH_GLOBAL_dirs . run_dir , SWITCH_PATH_SEPARATOR , pfile ) ;
2007-12-15 20:04:49 +00:00
switch_snprintf ( pid_buffer , sizeof ( pid_buffer ) , " %d " , pid ) ;
2008-09-17 02:09:58 +00:00
pid_len = strlen ( pid_buffer ) ;
2007-12-08 03:41:00 +00:00
apr_pool_create ( & pool , NULL ) ;
2010-02-06 03:38:24 +00:00
2010-01-12 17:20:16 +00:00
switch_dir_make_recursive ( SWITCH_GLOBAL_dirs . run_dir , SWITCH_DEFAULT_DIR_PERMS , pool ) ;
2008-11-21 15:52:22 +00:00
2010-02-06 03:38:24 +00:00
if ( switch_file_open ( & fd , pid_path , SWITCH_FOPEN_READ , SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE , pool ) = = SWITCH_STATUS_SUCCESS ) {
2008-11-21 15:55:17 +00:00
old_pid_len = sizeof ( old_pid_buffer ) ;
switch_file_read ( fd , old_pid_buffer , & old_pid_len ) ;
switch_file_close ( fd ) ;
2008-11-21 15:52:22 +00:00
}
if ( switch_file_open ( & fd ,
pid_path ,
SWITCH_FOPEN_WRITE | SWITCH_FOPEN_CREATE | SWITCH_FOPEN_TRUNCATE ,
2010-02-06 03:38:24 +00:00
SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE , pool ) ! = SWITCH_STATUS_SUCCESS ) {
2008-11-21 15:52:22 +00:00
fprintf ( stderr , " Cannot open pid file %s. \n " , pid_path ) ;
return 255 ;
2006-08-20 03:04:55 +00:00
}
2007-12-08 03:41:00 +00:00
if ( switch_file_lock ( fd , SWITCH_FLOCK_EXCLUSIVE | SWITCH_FLOCK_NONBLOCK ) ! = SWITCH_STATUS_SUCCESS ) {
fprintf ( stderr , " Cannot lock pid file %s. \n " , pid_path ) ;
2008-11-21 15:52:22 +00:00
old_pid_len = strlen ( old_pid_buffer ) ;
2008-11-21 15:55:17 +00:00
if ( strlen ( old_pid_buffer ) ) {
switch_file_write ( fd , old_pid_buffer , & old_pid_len ) ;
}
2007-12-08 03:41:00 +00:00
return 255 ;
}
switch_file_write ( fd , pid_buffer , & pid_len ) ;
if ( switch_core_init_and_modload ( flags , nc ? SWITCH_FALSE : SWITCH_TRUE , & err ) ! = SWITCH_STATUS_SUCCESS ) {
2008-01-07 10:45:06 +00:00
fprintf ( stderr , " Cannot Initialize [%s] \n " , err ) ;
2007-12-08 03:41:00 +00:00
return 255 ;
}
2006-08-20 03:04:55 +00:00
2010-10-29 17:43:55 +00:00
# ifndef WIN32
if ( do_wait ) {
kill ( getppid ( ) , SIGUSR2 ) ;
}
# endif
2007-01-19 12:59:49 +00:00
switch_core_runtime_loop ( nc ) ;
2006-08-18 21:57:47 +00:00
2008-10-02 16:46:20 +00:00
destroy_status = switch_core_destroy ( ) ;
2010-02-06 03:38:24 +00:00
2007-12-08 03:41:00 +00:00
switch_file_close ( fd ) ;
2010-04-21 15:11:13 +00:00
apr_pool_destroy ( pool ) ;
2007-12-07 02:03:55 +00:00
2007-12-15 20:04:49 +00:00
if ( unlink ( pid_path ) ! = 0 ) {
fprintf ( stderr , " Failed to delete pid file [%s] \n " , pid_path ) ;
}
2008-10-02 16:46:20 +00:00
if ( destroy_status = = SWITCH_STATUS_RESTART ) {
2009-01-20 18:35:07 +00:00
char buf [ 1024 ] = " " ;
2009-07-29 22:33:44 +00:00
int j = 0 ;
2010-02-06 03:38:24 +00:00
2009-01-20 18:35:07 +00:00
switch_sleep ( 1000000 ) ;
2010-02-06 03:38:24 +00:00
ret = ( int ) execv ( argv [ 0 ] , argv ) ;
2009-01-20 18:35:07 +00:00
fprintf ( stderr , " Restart Failed [%s] resorting to plan b \n " , strerror ( errno ) ) ;
2010-02-06 03:38:24 +00:00
for ( j = 0 ; j < argc ; j + + ) {
2009-10-15 15:25:06 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " %s " , argv [ j ] ) ;
2009-01-20 18:35:07 +00:00
}
ret = system ( buf ) ;
2008-10-02 16:46:20 +00:00
}
2007-12-15 20:04:49 +00:00
return ret ;
2005-11-19 20:07:43 +00:00
}
2006-11-27 22:30:48 +00:00
/* For Emacs:
* Local Variables :
* mode : c
2008-02-03 22:14:57 +00:00
* indent - tabs - mode : t
2006-11-27 22:30:48 +00:00
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
2008-07-03 19:12:26 +00:00
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 :
2006-11-27 22:30:48 +00:00
*/