481 char pid_path[PATH_MAX] =
"";
482 char pid_buffer[32] =
"";
483 char old_pid_buffer[32] = { 0 };
485 const char *err = NULL;
489 char *runas_user = NULL;
490 char *runas_group = NULL;
492 int fds[2] = { 0, 0 };
501 char opts_str[1024] =
"";
502 char *local_argv[1024] = { 0 };
503 int local_argc = argc;
504 char *arg_argv[128] = { 0 };
505 int alt_dirs = 0, alt_base = 0, log_set = 0, run_set = 0, do_kill = 0;
516 #ifdef HAVE_SETRLIMIT
522 for (x = 0; x < argc; x++) {
523 local_argv[x] = argv[x];
526 if ((opts = getenv(
"FREESWITCH_OPTS"))) {
527 strncpy(opts_str, opts,
sizeof(opts_str) - 1);
529 for (x = 0; x < i; x++) {
530 local_argv[local_argc++] = arg_argv[x];
534 if (local_argv[0] && strstr(local_argv[0],
"freeswitchd")) {
538 for (x = 1; x < local_argc; x++) {
543 if (!strcmp(local_argv[x],
"-help") || !strcmp(local_argv[x],
"-h") || !strcmp(local_argv[x],
"-?")) {
544 printf(
"%s\n",
usage);
548 if (x == 1 && !strcmp(local_argv[x],
"-service")) {
561 else if (x == 1 && !strcmp(local_argv[x],
"-install")) {
562 char servicePath[PATH_MAX];
563 char exePath[PATH_MAX];
565 SC_HANDLE hSCManager;
566 SERVICE_DESCRIPTION desc;
567 desc.lpDescription =
"The FreeSWITCH service.";
576 GetModuleFileName(NULL, exePath,
sizeof(exePath));
577 snprintf(servicePath,
sizeof(servicePath),
"%s -service %s", exePath, service_name);
581 hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
583 fprintf(stderr,
"Could not open service manager (%u).\n", GetLastError());
587 hService = CreateService(hSCManager, service_name, service_name, GENERIC_READ | GENERIC_EXECUTE | SERVICE_CHANGE_CONFIG, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE,
588 servicePath, NULL, NULL, NULL, NULL, NULL);
590 fprintf(stderr,
"Error creating freeswitch service (%u).\n", GetLastError());
591 CloseServiceHandle(hSCManager);
596 if (!ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &desc)) {
597 fprintf(stderr,
"FreeSWITCH installed, but could not set the service description (%u).\n", GetLastError());
600 CloseServiceHandle(hService);
601 CloseServiceHandle(hSCManager);
605 else if (x == 1 && !strcmp(local_argv[x],
"-uninstall")) {
607 SC_HANDLE hSCManager;
618 hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
620 fprintf(stderr,
"Could not open service manager (%u).\n", GetLastError());
624 hService = OpenService(hSCManager, service_name, DELETE);
626 fprintf(stderr,
"Error opening service (%u).\n", GetLastError());
627 CloseServiceHandle(hSCManager);
632 deleted = DeleteService(hService);
634 fprintf(stderr,
"Error deleting service (%u).\n", GetLastError());
637 CloseServiceHandle(hService);
638 CloseServiceHandle(hSCManager);
639 exit(deleted ? EXIT_SUCCESS : EXIT_FAILURE);
642 else if (!strcmp(local_argv[x],
"-monotonic-clock")) {
646 else if (!strcmp(local_argv[x],
"-u")) {
649 fprintf(stderr,
"Option '%s' requires an argument!\n", local_argv[x - 1]);
652 runas_user = local_argv[x];
655 else if (!strcmp(local_argv[x],
"-g")) {
658 fprintf(stderr,
"Option '%s' requires an argument!\n", local_argv[x - 1]);
661 runas_group = local_argv[x];
664 else if (!strcmp(local_argv[x],
"-nf")) {
668 else if (!strcmp(local_argv[x],
"-reincarnate")) {
671 else if (!strcmp(local_argv[x],
"-reincarnate-reexec")) {
676 else if (!strcmp(local_argv[x],
"-version")) {
681 #ifdef HAVE_SETRLIMIT
682 else if (!strcmp(local_argv[x],
"-core")) {
684 memset(&rlp, 0,
sizeof(rlp));
685 rlp.rlim_cur = RLIM_INFINITY;
686 rlp.rlim_max = RLIM_INFINITY;
687 setrlimit(RLIMIT_CORE, &rlp);
690 else if (!strcmp(local_argv[x],
"-waste")) {
692 fprintf(stderr,
"WARNING: Wasting up to 8 megs of memory per thread.\n");
698 else if (!strcmp(local_argv[x],
"-no-auto-stack")) {
704 else if (!strcmp(local_argv[x],
"-hp") || !strcmp(local_argv[x],
"-rp")) {
708 else if (!strcmp(local_argv[x],
"-lp")) {
712 else if (!strcmp(local_argv[x],
"-np")) {
716 else if (!strcmp(local_argv[x],
"-nosql")) {
720 else if (!strcmp(local_argv[x],
"-nonat")) {
724 else if (!strcmp(local_argv[x],
"-nonatmap")) {
728 else if (!strcmp(local_argv[x],
"-heavy-timer")) {
732 else if (!strcmp(local_argv[x],
"-nort")) {
736 else if (!strcmp(local_argv[x],
"-nocal")) {
740 else if (!strcmp(local_argv[x],
"-vg")) {
744 else if (!strcmp(local_argv[x],
"-stop")) {
748 else if (!strcmp(local_argv[x],
"-nc")) {
752 else if (!strcmp(local_argv[x],
"-ncwait")) {
757 else if (!strcmp(local_argv[x],
"-c")) {
761 else if (!strcmp(local_argv[x],
"-conf")) {
764 fprintf(stderr,
"When using -conf you must specify a config directory\n");
770 fprintf(stderr,
"Allocation error\n");
777 else if (!strcmp(local_argv[x],
"-mod")) {
780 fprintf(stderr,
"When using -mod you must specify a module directory\n");
786 fprintf(stderr,
"Allocation error\n");
792 else if (!strcmp(local_argv[x],
"-log")) {
795 fprintf(stderr,
"When using -log you must specify a log directory\n");
801 fprintf(stderr,
"Allocation error\n");
809 else if (!strcmp(local_argv[x],
"-run")) {
812 fprintf(stderr,
"When using -run you must specify a pid directory\n");
818 fprintf(stderr,
"Allocation error\n");
825 else if (!strcmp(local_argv[x],
"-db")) {
828 fprintf(stderr,
"When using -db you must specify a db directory\n");
834 fprintf(stderr,
"Allocation error\n");
841 else if (!strcmp(local_argv[x],
"-scripts")) {
844 fprintf(stderr,
"When using -scripts you must specify a scripts directory\n");
850 fprintf(stderr,
"Allocation error\n");
856 else if (!strcmp(local_argv[x],
"-htdocs")) {
859 fprintf(stderr,
"When using -htdocs you must specify a htdocs directory\n");
865 fprintf(stderr,
"Allocation error\n");
871 else if (!strcmp(local_argv[x],
"-base")) {
874 fprintf(stderr,
"When using -base you must specify a base directory\n");
880 fprintf(stderr,
"Allocation error\n");
887 else if (!strcmp(local_argv[x],
"-temp")) {
890 fprintf(stderr,
"When using -temp you must specify a temp directory\n");
896 fprintf(stderr,
"Allocation error\n");
902 else if (!strcmp(local_argv[x],
"-storage")) {
905 fprintf(stderr,
"When using -storage you must specify a storage directory\n");
911 fprintf(stderr,
"Allocation error\n");
917 else if (!strcmp(local_argv[x],
"-cache")) {
920 fprintf(stderr,
"When using -cache you must specify a cache directory\n");
926 fprintf(stderr,
"Allocation error\n");
932 else if (!strcmp(local_argv[x],
"-recordings")) {
935 fprintf(stderr,
"When using -recordings you must specify a recording directory\n");
941 fprintf(stderr,
"Allocation error\n");
947 else if (!strcmp(local_argv[x],
"-grammar")) {
950 fprintf(stderr,
"When using -grammar you must specify a grammar directory\n");
956 fprintf(stderr,
"Allocation error\n");
962 else if (!strcmp(local_argv[x],
"-certs")) {
965 fprintf(stderr,
"When using -certs you must specify a certificates directory\n");
971 fprintf(stderr,
"Allocation error\n");
977 else if (!strcmp(local_argv[x],
"-sounds")) {
980 fprintf(stderr,
"When using -sounds you must specify a sounds directory\n");
986 fprintf(stderr,
"Allocation error\n");
992 else if (!strcmp(local_argv[x],
"-cfgname")) {
995 fprintf(stderr,
"When using -cfgname you must specify a filename\n");
1001 fprintf(stderr,
"Allocation error\n");
1009 fprintf(stderr,
"Unknown option '%s', see '%s -help' for a list of valid options\n",
1010 local_argv[x], local_argv[0]);
1015 if (log_set && !run_set) {
1018 fprintf(stderr,
"Allocation error\n");
1029 fprintf(stderr,
"FATAL ERROR! Could not initialize APR\n");
1033 if (alt_dirs && alt_dirs != 3 && !alt_base) {
1034 fprintf(stderr,
"You must specify all or none of -conf, -log, and -db\n");
1039 #if defined(HAVE_SETRLIMIT) && !defined(__sun)
1040 if (!waste && !(flags &
SCF_VG)) {
1043 memset(&rlp, 0,
sizeof(rlp));
1044 getrlimit(RLIMIT_STACK, &rlp);
1047 char buf[1024] =
"";
1050 memset(&rlp, 0,
sizeof(rlp));
1053 setrlimit(RLIMIT_STACK, &rlp);
1056 if (argv) ret = (int) execv(argv[0], argv);
1058 for (i = 0; i < argc; i++) {
1059 switch_snprintf(buf + strlen(buf),
sizeof(buf) - strlen(buf),
"%s ", argv[i]);
1072 fprintf(stderr,
"System Error!\n");
1115 if (runas_user || runas_group) {
1117 fprintf(stderr,
"Failed to switch user [%s] / group [%s]\n",
1124 if (win32_service) {
1126 SERVICE_TABLE_ENTRY dispatchTable[] = {
1127 {service_name, &service_main}
1131 service_flags = flags;
1133 if (StartServiceCtrlDispatcher(dispatchTable) == 0) {
1135 fprintf(stderr,
"Error Freeswitch loaded as a console app with -service option\n");
1136 fprintf(stderr,
"To install the service load freeswitch with -install\n");
1146 memset(pid_buffer, 0,
sizeof(pid_buffer));
1149 pid_len = strlen(pid_buffer);
1151 apr_pool_create(&pool, NULL);
1157 old_pid_len =
sizeof(old_pid_buffer) -1;
1166 fprintf(stderr,
"Cannot open pid file %s.\n", pid_path);
1171 fprintf(stderr,
"Cannot lock pid file %s.\n", pid_path);
1172 old_pid_len = strlen(old_pid_buffer);
1173 if (strlen(old_pid_buffer)) {
1182 fprintf(stderr,
"Cannot Initialize [%s]\n", err);
1191 if ((i = write(fds[1], &v,
sizeof(v))) < 0) {
1192 fprintf(stderr,
"System Error [%s]\n", strerror(errno));
1194 (void)read(fds[1], &v,
sizeof(v));
1197 shutdown(fds[1], 2);
1213 apr_pool_destroy(pool);
1215 if (unlink(pid_path) != 0) {
1216 fprintf(stderr,
"Failed to delete pid file [%s]\n", pid_path);
1220 char buf[1024] = { 0 };
1224 if (!argv || execv(argv[0], argv) == -1) {
1225 fprintf(stderr,
"Restart Failed [%s] resorting to plan b\n", strerror(errno));
1226 for (j = 0; j < argc; j++) {
1227 switch_snprintf(buf + strlen(buf),
sizeof(buf) - strlen(buf),
"%s ", argv[j]);
int32_t change_user_group(const char *user, const char *group)
Change user and/or group of the running process.
#define SWITCH_FOPEN_TRUNCATE
switch_status_t switch_file_write(switch_file_t *thefile, const void *buf, switch_size_t *nbytes)
static void handle_SIGILL(int sig)
const char * switch_version_full(void)
#define SWITCH_FOPEN_READ
void switch_sleep(switch_interval_time_t t)
int32_t set_low_priority(void)
#define SWITCH_FLOCK_EXCLUSIVE
switch_memory_pool_t * pool
static void reincarnate_protect(char **argv)
void switch_core_set_globals(void)
Initiate Globals.
switch_status_t switch_core_destroy(void)
Destroy the core.
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
uint32_t switch_core_flag_t
static switch_bool_t is_option(const char *p)
static const char usage[]
int32_t set_auto_priority(void)
static void daemonize(int *fds)
#define SWITCH_PATH_SEPARATOR
switch_byte_t switch_byte_t * buf
unsigned int switch_separate_string(_In_ char *buf, char delim, _Post_count_(return) char **array, unsigned int arraylen)
Separate a string into an array based on a character delimiter.
switch_status_t switch_core_init_and_modload(_In_ switch_core_flag_t flags, _In_ switch_bool_t console, _Out_ const char **err)
Initilize the core and load modules.
#define switch_strlen_zero(x)
void switch_core_setrlimits(void)
#define SWITCH_THREAD_STACKSIZE
#define SWITCH_SYSTEM_THREAD_STACKSIZE
int32_t set_normal_priority(void)
Set the maximum priority the process can obtain.
#define SWITCH_FPROT_UWRITE
switch_filenames SWITCH_GLOBAL_filenames
void switch_core_runtime_loop(int bg)
Run endlessly until the system is shutdown.
struct apr_file_t switch_file_t
char * switch_copy_string(_Out_z_cap_(dst_size) char *dst, _In_z_ const char *src, _In_ switch_size_t dst_size)
#define SWITCH_FPROT_UREAD
switch_status_t switch_file_read(switch_file_t *thefile, void *buf, switch_size_t *nbytes)
switch_directories SWITCH_GLOBAL_dirs
int32_t set_realtime_priority(void)
static int freeswitch_kill_background()
#define SWITCH_DEFAULT_DIR_PERMS
switch_status_t
Common return values.
switch_status_t switch_dir_make_recursive(const char *path, switch_fileperms_t perm, switch_memory_pool_t *pool)
#define SWITCH_FLOCK_NONBLOCK
switch_status_t switch_file_lock(switch_file_t *thefile, int type)
struct apr_pool_t switch_memory_pool_t
switch_status_t switch_file_open(switch_file_t **newf, const char *fname, int32_t flag, switch_fileperms_t perm, switch_memory_pool_t *pool)
int32_t switch_core_set_process_privileges(void)
Switch on the privilege awareness for the process and request required privileges.
#define SWITCH_FOPEN_CREATE
const char * switch_version_revision_human(void)
switch_status_t switch_file_close(switch_file_t *thefile)
#define SWITCH_FOPEN_WRITE