int handle_identity(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request = NULL; oid subid; const char *version = switch_version_full(); char uuid[40] = ""; switch(reqinfo->mode) { case MODE_GET: subid = requests->requestvb->name[reginfo->rootoid_len - 2]; switch (subid) { case ID_VERSION_STR: snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &version, strlen(version)); break; case ID_UUID: strncpy(uuid, switch_core_get_uuid(), sizeof(uuid)); snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &uuid, strlen(uuid)); break; default: snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid); netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); } break; default: /* we should never get here, so this is a really bad error */ snmp_log(LOG_ERR, "Unknown mode (%d) in handle_identity\n", reqinfo->mode ); return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; }
/* 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; switch_bool_t reincarnate = SWITCH_FALSE, reincarnate_reexec = SWITCH_FALSE; int fds[2] = { 0, 0 }; #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, alt_base = 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 #ifndef FS_64BIT switch_bool_t waste = SWITCH_FALSE; #endif #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++) { 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 && !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); } 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); } 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 (%u).\n", GetLastError()); 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); if (!hService) { fprintf(stderr, "Error creating freeswitch service (%u).\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 (%u).\n", GetLastError()); } CloseServiceHandle(hService); CloseServiceHandle(hSCManager); exit(EXIT_SUCCESS); } 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 (%u).\n", GetLastError()); exit(EXIT_FAILURE); } hService = OpenService(hSCManager, service_name, DELETE); if (!hService) { fprintf(stderr, "Error opening service (%u).\n", GetLastError()); CloseServiceHandle(hSCManager); exit(EXIT_FAILURE); } /* remove the service! */ deleted = DeleteService(hService); if (!deleted) { fprintf(stderr, "Error deleting service (%u).\n", GetLastError()); } CloseServiceHandle(hService); CloseServiceHandle(hSCManager); exit(deleted ? EXIT_SUCCESS : EXIT_FAILURE); } else if (!strcmp(local_argv[x], "-monotonic-clock")) { flags |= SCF_USE_WIN32_MONOTONIC; } #else else if (!strcmp(local_argv[x], "-u")) { 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]; } else if (!strcmp(local_argv[x], "-g")) { 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]; } else if (!strcmp(local_argv[x], "-nf")) { nf = SWITCH_TRUE; } else if (!strcmp(local_argv[x], "-reincarnate")) { reincarnate = SWITCH_TRUE; } else if (!strcmp(local_argv[x], "-reincarnate-reexec")) { reincarnate = SWITCH_TRUE; reincarnate_reexec = SWITCH_TRUE; } else if (!strcmp(local_argv[x], "-version")) { fprintf(stdout, "FreeSWITCH version: %s (%s)\n", switch_version_full(), switch_version_revision_human()); exit(EXIT_SUCCESS); } #endif #ifdef HAVE_SETRLIMIT 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); } else if (!strcmp(local_argv[x], "-waste")) { #ifndef FS_64BIT fprintf(stderr, "WARNING: Wasting up to 8 megs of memory per thread.\n"); sleep(2); waste = SWITCH_TRUE; #endif } else if (!strcmp(local_argv[x], "-no-auto-stack")) { #ifndef FS_64BIT waste = SWITCH_TRUE; #endif } #endif else if (!strcmp(local_argv[x], "-hp") || !strcmp(local_argv[x], "-rp")) { priority = 2; } else if (!strcmp(local_argv[x], "-lp")) { priority = -1; } else if (!strcmp(local_argv[x], "-np")) { priority = 1; } else if (!strcmp(local_argv[x], "-nosql")) { flags &= ~SCF_USE_SQL; } else if (!strcmp(local_argv[x], "-nonat")) { flags &= ~SCF_USE_AUTO_NAT; } else if (!strcmp(local_argv[x], "-nonatmap")) { flags &= ~SCF_USE_NAT_MAPPING; } else if (!strcmp(local_argv[x], "-heavy-timer")) { flags |= SCF_USE_HEAVY_TIMING; } else if (!strcmp(local_argv[x], "-nort")) { flags &= ~SCF_USE_CLOCK_RT; } else if (!strcmp(local_argv[x], "-nocal")) { flags &= ~SCF_CALIBRATE_CLOCK; } else if (!strcmp(local_argv[x], "-vg")) { flags |= SCF_VG; } else if (!strcmp(local_argv[x], "-stop")) { do_kill = SWITCH_TRUE; } else if (!strcmp(local_argv[x], "-nc")) { nc = SWITCH_TRUE; } #ifndef WIN32 else if (!strcmp(local_argv[x], "-ncwait")) { nc = SWITCH_TRUE; do_wait = SWITCH_TRUE; } #endif else if (!strcmp(local_argv[x], "-c")) { nc = SWITCH_FALSE; } else if (!strcmp(local_argv[x], "-conf")) { 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"); return 255; } strcpy(SWITCH_GLOBAL_dirs.conf_dir, local_argv[x]); alt_dirs++; } else if (!strcmp(local_argv[x], "-mod")) { 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 if (!strcmp(local_argv[x], "-log")) { 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"); return 255; } strcpy(SWITCH_GLOBAL_dirs.log_dir, local_argv[x]); alt_dirs++; log_set = SWITCH_TRUE; } else if (!strcmp(local_argv[x], "-run")) { 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 = SWITCH_TRUE; } else if (!strcmp(local_argv[x], "-db")) { 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"); return 255; } strcpy(SWITCH_GLOBAL_dirs.db_dir, local_argv[x]); alt_dirs++; } else if (!strcmp(local_argv[x], "-scripts")) { 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 if (!strcmp(local_argv[x], "-htdocs")) { 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 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]); alt_base = 1; } 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.storage_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], "-cache")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "When using -cache you must specify a cache directory\n"); return 255; } SWITCH_GLOBAL_dirs.cache_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.cache_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.cache_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], "-certs")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "When using -certs you must specify a certificates directory\n"); return 255; } SWITCH_GLOBAL_dirs.certs_dir = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_dirs.certs_dir) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_dirs.certs_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]); } else if (!strcmp(local_argv[x], "-cfgname")) { x++; if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) { fprintf(stderr, "When using -cfgname you must specify a filename\n"); return 255; } SWITCH_GLOBAL_filenames.conf_name = (char *) malloc(strlen(local_argv[x]) + 1); if (!SWITCH_GLOBAL_filenames.conf_name) { fprintf(stderr, "Allocation error\n"); return 255; } strcpy(SWITCH_GLOBAL_filenames.conf_name, 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); } } if (log_set && !run_set) { 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; } strcpy(SWITCH_GLOBAL_dirs.run_dir, SWITCH_GLOBAL_dirs.log_dir); } if (do_kill) { return freeswitch_kill_background(); } if (apr_initialize() != SWITCH_STATUS_SUCCESS) { fprintf(stderr, "FATAL ERROR! Could not initialize APR\n"); return 255; } if (alt_dirs && alt_dirs != 3 && !alt_base) { fprintf(stderr, "You must specify all or none of -conf, -log, and -db\n"); return 255; } #ifndef FS_64BIT #if defined(HAVE_SETRLIMIT) && !defined(__sun) if (!waste && !(flags & SCF_VG)) { struct rlimit rlp; memset(&rlp, 0, sizeof(rlp)); getrlimit(RLIMIT_STACK, &rlp); if (rlp.rlim_cur != SWITCH_THREAD_STACKSIZE) { char buf[1024] = ""; int i = 0; memset(&rlp, 0, sizeof(rlp)); rlp.rlim_cur = SWITCH_THREAD_STACKSIZE; rlp.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE; setrlimit(RLIMIT_STACK, &rlp); apr_terminate(); if (argv) ret = (int) execv(argv[0], argv); for (i = 0; i < argc; i++) { switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s ", argv[i]); } return system(buf); } } #endif #endif signal(SIGILL, handle_SIGILL); signal(SIGTERM, handle_SIGILL); #ifndef WIN32 if (do_wait) { if (pipe(fds)) { fprintf(stderr, "System Error!\n"); exit(-1); } } #endif if (nc) { #ifdef WIN32 FreeConsole(); #else if (!nf) { daemonize(do_wait ? fds : NULL); } #endif } #ifndef WIN32 if (reincarnate) reincarnate_protect(reincarnate_reexec ? argv : NULL); #endif switch (priority) { case 2: set_realtime_priority(); break; case 1: set_normal_priority(); break; case -1: set_low_priority(); break; default: set_auto_priority(); break; } switch_core_setrlimits(); #ifndef WIN32 if (runas_user || runas_group) { if (change_user_group(runas_user, runas_group) < 0) { 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 */ 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); } #endif switch_core_set_globals(); pid = getpid(); memset(pid_buffer, 0, sizeof(pid_buffer)); switch_snprintf(pid_path, sizeof(pid_path), "%s%s%s", SWITCH_GLOBAL_dirs.run_dir, SWITCH_PATH_SEPARATOR, pfile); switch_snprintf(pid_buffer, sizeof(pid_buffer), "%d", pid); pid_len = strlen(pid_buffer); apr_pool_create(&pool, NULL); switch_dir_make_recursive(SWITCH_GLOBAL_dirs.run_dir, SWITCH_DEFAULT_DIR_PERMS, pool); if (switch_file_open(&fd, pid_path, SWITCH_FOPEN_READ, SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE, pool) == SWITCH_STATUS_SUCCESS) { old_pid_len = sizeof(old_pid_buffer) -1; switch_file_read(fd, old_pid_buffer, &old_pid_len); switch_file_close(fd); } if (switch_file_open(&fd, pid_path, SWITCH_FOPEN_WRITE | SWITCH_FOPEN_CREATE | SWITCH_FOPEN_TRUNCATE, SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE, pool) != SWITCH_STATUS_SUCCESS) { fprintf(stderr, "Cannot open pid file %s.\n", pid_path); return 255; } if (switch_file_lock(fd, SWITCH_FLOCK_EXCLUSIVE | SWITCH_FLOCK_NONBLOCK) != SWITCH_STATUS_SUCCESS) { fprintf(stderr, "Cannot lock pid file %s.\n", pid_path); old_pid_len = strlen(old_pid_buffer); if (strlen(old_pid_buffer)) { switch_file_write(fd, old_pid_buffer, &old_pid_len); } 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) { fprintf(stderr, "Cannot Initialize [%s]\n", err); return 255; } #ifndef WIN32 if (do_wait) { if (fds[1] > -1) { int i, v = 1; if ((i = write(fds[1], &v, sizeof(v))) < 0) { fprintf(stderr, "System Error [%s]\n", strerror(errno)); } else { (void)read(fds[1], &v, sizeof(v)); } shutdown(fds[1], 2); close(fds[1]); fds[1] = -1; } } #endif switch_core_runtime_loop(nc); destroy_status = switch_core_destroy(); switch_file_close(fd); apr_pool_destroy(pool); if (unlink(pid_path) != 0) { fprintf(stderr, "Failed to delete pid file [%s]\n", pid_path); } if (destroy_status == SWITCH_STATUS_RESTART) { char buf[1024] = ""; int j = 0; switch_sleep(1000000); if (!argv || execv(argv[0], argv) == -1) { fprintf(stderr, "Restart Failed [%s] resorting to plan b\n", strerror(errno)); for (j = 0; j < argc; j++) { switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s ", argv[j]); } ret = system(buf); } } return ret; }
static switch_status_t webm_file_open(switch_file_handle_t *handle, const char *path) { webm_file_context_t *context; char *ext; unsigned int flags = 0; const char *tmp = NULL; char *fmtp; if ((ext = strrchr((char *)path, '.')) == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Format\n"); return SWITCH_STATUS_GENERR; } ext++; if ((context = (webm_file_context_t *)switch_core_alloc(handle->memory_pool, sizeof(webm_file_context_t))) == 0) { return SWITCH_STATUS_MEMERR; } memset(context, 0, sizeof(webm_file_context_t)); context->offset = -100; if (handle->params && (tmp = switch_event_get_header(handle->params, "webmv2_video_offset"))) { context->offset = atoi(tmp); } switch_mutex_init(&context->mutex, SWITCH_MUTEX_NESTED, handle->memory_pool); switch_core_timer_init(&context->timer, "soft", 1, 1000, context->pool); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "init timer\n"); if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { flags |= SWITCH_FOPEN_WRITE | SWITCH_FOPEN_CREATE; if (switch_test_flag(handle, SWITCH_FILE_WRITE_APPEND) || switch_test_flag(handle, SWITCH_FILE_WRITE_OVER)) { flags |= SWITCH_FOPEN_READ; } else { flags |= SWITCH_FOPEN_TRUNCATE; } } if (switch_test_flag(handle, SWITCH_FILE_FLAG_READ)) { flags |= SWITCH_FOPEN_READ; } context->writer = new mkvmuxer::MkvWriter(); if (!context->writer->Open(path)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error opening file %s\n", path); return SWITCH_STATUS_GENERR; } context->segment = new mkvmuxer::Segment(); if (!context->segment || !context->segment->Init(context->writer)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error init segment\n"); return SWITCH_STATUS_GENERR; } // context->segment.set_mode(mkvmuxer::Segment::kLive); context->segment->set_mode(mkvmuxer::Segment::kFile); context->segment->OutputCues(true); mkvmuxer::SegmentInfo* const info = context->segment->GetSegmentInfo(); info->set_timecode_scale(1000000); info->set_muxing_app("FreeSWITCH"); info->set_writing_app(switch_version_full()); context->audio_track_id = context->segment->AddAudioTrack(handle->samplerate, handle->channels, 0); if (!context->audio_track_id) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error add audio track!\n"); goto end; } context->audio = static_cast<mkvmuxer::AudioTrack*>(context->segment->GetTrackByNumber(context->audio_track_id)); context->audio->set_codec_id("A_" AUDIO_CODEC); switch_buffer_create_dynamic(&context->audio_buffer, 512, 512, 0); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sample rate: %d, channels: %d\n", handle->samplerate, handle->channels); handle->format = 0; handle->sections = 0; handle->seekable = 0; handle->speed = 0; handle->pos = 0; handle->private_info = context; context->pool = handle->memory_pool; // handle->flags |= SWITCH_FILE_NATIVE; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening File [%s] %dhz %s\n", path, handle->samplerate, switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO) ? " with VIDEO" : ""); fmtp = switch_core_sprintf(context->pool, "useinbandfec=1;minptime=20;ptime=20;samplerate=%d%s", handle->samplerate, handle->channels == 2 ? ",stereo=1" : ""); if (switch_core_codec_init(&context->audio_codec, AUDIO_CODEC, NULL, fmtp, handle->samplerate, 20,//ms handle->channels, SWITCH_CODEC_FLAG_ENCODE, NULL, handle->memory_pool) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Audio Codec Activation Success\n"); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Audio Codec Activation Fail\n"); goto end; } if (switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO)) { if (switch_core_codec_init(&context->video_codec, "VP8", NULL, NULL, 90000, 0,//ms 1, SWITCH_CODEC_FLAG_ENCODE, NULL, handle->memory_pool) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Video Codec H264 Activation Success\n"); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Video Codec H264 Activation Fail\n"); goto end; } } if (!strcmp(AUDIO_CODEC, "VORBIS")) { uint16_t size = 0; uint8_t *codec_private_data = NULL; switch_core_codec_control(&context->audio_codec, SCC_GET_CODEC_PRIVATE, SCCT_INT, (void *)&size, NULL, (void **)&codec_private_data); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "======codec_private_data size: %d data: %p\n", size, codec_private_data); context->audio->SetCodecPrivate(codec_private_data, size); } if (1) { // for better quality? int bw = 4096; switch_core_codec_control(&context->video_codec, SCC_VIDEO_BANDWIDTH, SCCT_INT, (void *)&bw, NULL, NULL); } switch_buffer_create_dynamic(&context->buf, 512, 512, 1024000); return SWITCH_STATUS_SUCCESS; end: if (context->segment) delete context->segment; if (context->writer) delete context->writer; return SWITCH_STATUS_GENERR; }