12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605 |
- /*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
- *
- * 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
- * Anthony Minessale II <anthm@freeswitch.org>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthm@freeswitch.org>
- * Michael Jerris <mike@jerris.com>
- * Paul D. Tinsley <pdt at jackhammer.org>
- * Marcel Barbulescu <marcelbarbulescu@gmail.com>
- * Joseph Sullivan <jossulli@amazon.com>
- * Seven Du <dujinfang@gmail.com>
- * Andrey Volk <andywolk@gmail.com>
- *
- * switch_core.c -- Main Core Library
- *
- */
- #include <switch.h>
- #include <switch_ssl.h>
- #include <switch_stun.h>
- #include <switch_nat.h>
- #include "private/switch_apr_pvt.h"
- #include "private/switch_core_pvt.h"
- #include <switch_curl.h>
- #include <switch_msrp.h>
- #ifndef WIN32
- #include <switch_private.h>
- #ifdef HAVE_SETRLIMIT
- #include <sys/resource.h>
- #endif
- #endif
- #include <errno.h>
- #include <sqlite3.h>
- #ifdef HAVE_SYS_PRCTL_H
- #include <sys/prctl.h>
- #endif
- #ifdef SOLARIS_PRIVILEGES
- #include <priv.h>
- #endif
- #ifdef __linux__
- #include <sys/wait.h>
- #ifndef _GNU_SOURCE
- #define _GNU_SOURCE /* Required for POSIX_SPAWN_USEVFORK */
- #endif
- #include <spawn.h>
- #include <poll.h>
- #endif
- #ifdef WIN32
- #define popen _popen
- #define pclose _pclose
- #endif
- #ifdef HAVE_SYSTEMD
- #include <systemd/sd-daemon.h>
- #endif
- SWITCH_DECLARE_DATA switch_directories SWITCH_GLOBAL_dirs = { 0 };
- SWITCH_DECLARE_DATA switch_filenames SWITCH_GLOBAL_filenames = { 0 };
- /* The main runtime obj we keep this hidden for ourselves */
- struct switch_runtime runtime = { 0 };
- static void switch_load_core_config(const char *file);
- static void send_heartbeat(void)
- {
- switch_event_t *event;
- switch_core_time_duration_t duration;
- switch_core_measure_time(switch_core_uptime(), &duration);
- if (switch_event_create(&event, SWITCH_EVENT_HEARTBEAT) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready");
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Up-Time",
- "%u year%s, "
- "%u day%s, "
- "%u hour%s, "
- "%u minute%s, "
- "%u second%s, "
- "%u millisecond%s, "
- "%u microsecond%s",
- duration.yr, duration.yr == 1 ? "" : "s",
- duration.day, duration.day == 1 ? "" : "s",
- duration.hr, duration.hr == 1 ? "" : "s",
- duration.min, duration.min == 1 ? "" : "s",
- duration.sec, duration.sec == 1 ? "" : "s",
- duration.ms, duration.ms == 1 ? "" : "s", duration.mms, duration.mms == 1 ? "" : "s");
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FreeSWITCH-Version", "%s", switch_version_full());
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Uptime-msec", "%"SWITCH_TIME_T_FMT, switch_core_uptime() / 1000);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Count", "%u", switch_core_session_count());
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Max-Sessions", "%u", switch_core_session_limit(0));
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec", "%u", runtime.sps);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec-Last", "%u", runtime.sps_last);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec-Max", "%u", runtime.sps_peak);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec-FiveMin", "%u", runtime.sps_peak_fivemin);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Since-Startup", "%" SWITCH_SIZE_T_FMT, switch_core_session_id() - 1);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Peak-Max", "%u", runtime.sessions_peak);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Peak-FiveMin", "%u", runtime.sessions_peak_fivemin);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Idle-CPU", "%f", switch_core_idle_cpu());
- switch_event_fire(&event);
- }
- }
- static char main_ip4[256] = "";
- static char main_ip6[256] = "";
- static void check_ip(void)
- {
- char guess_ip4[256] = "";
- char guess_ip6[256] = "";
- char old_ip4[256] = "";
- char old_ip6[256] = "";
- int ok4 = 1, ok6 = 1;
- int mask = 0;
- switch_status_t check6, check4;
- switch_event_t *event;
- char *hostname = switch_core_get_variable("hostname");
- gethostname(runtime.hostname, sizeof(runtime.hostname));
- if (zstr(hostname)) {
- switch_core_set_variable("hostname", runtime.hostname);
- } else if (strcmp(hostname, runtime.hostname)) {
- if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "hostname-change");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "old-hostname", hostname);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "new-hostname", runtime.hostname);
- switch_event_fire(&event);
- }
- switch_core_set_variable("hostname", runtime.hostname);
- }
- check4 = switch_find_local_ip(guess_ip4, sizeof(guess_ip4), &mask, AF_INET);
- check6 = switch_find_local_ip(guess_ip6, sizeof(guess_ip6), NULL, AF_INET6);
- if (check6 != SWITCH_STATUS_SUCCESS && (zstr(main_ip6) || !strcasecmp(main_ip6, "::1"))) {
- check6 = SWITCH_STATUS_SUCCESS;
- }
- if (check4 != SWITCH_STATUS_SUCCESS) {
- ok4 = 2;
- } else if (!*main_ip4) {
- switch_set_string(main_ip4, guess_ip4);
- } else {
- if (!(ok4 = !strcmp(main_ip4, guess_ip4))) {
- struct in_addr in;
- in.s_addr = mask;
- switch_set_string(old_ip4, main_ip4);
- switch_set_string(main_ip4, guess_ip4);
- switch_core_set_variable("local_ip_v4", guess_ip4);
- switch_core_set_variable("local_mask_v4", inet_ntoa(in));
- }
- }
- if (check6 != SWITCH_STATUS_SUCCESS) {
- ok6 = 2;
- } else if (!*main_ip6) {
- switch_set_string(main_ip6, guess_ip6);
- } else {
- if (!(ok6 = !strcmp(main_ip6, guess_ip6))) {
- switch_set_string(old_ip6, main_ip6);
- switch_set_string(main_ip6, guess_ip6);
- switch_core_set_variable("local_ip_v6", guess_ip6);
- }
- }
- if (!ok4 || !ok6) {
- if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "network-address-change");
- if (!ok4) {
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v4", old_ip4);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v4", main_ip4);
- }
- if (!ok6) {
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v6", old_ip6);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v6", main_ip6);
- }
- switch_event_fire(&event);
- }
- }
- if (ok4 == 2 || ok6 == 2) {
- if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "network-outage");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-status-v4", ok4 == 2 ? "disconnected" : "active");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-v4", main_ip4);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-status-v6", ok6 == 2 ? "disconnected" : "active");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-v6", main_ip6);
- switch_event_fire(&event);
- }
- }
- }
- SWITCH_STANDARD_SCHED_FUNC(heartbeat_callback)
- {
- send_heartbeat();
- /* reschedule this task */
- task->runtime = switch_epoch_time_now(NULL) + runtime.event_heartbeat_interval;
- }
- SWITCH_STANDARD_SCHED_FUNC(check_ip_callback)
- {
- check_ip();
- /* reschedule this task */
- task->runtime = switch_epoch_time_now(NULL) + 60;
- }
- SWITCH_DECLARE(switch_status_t) switch_core_set_console(const char *console)
- {
- if ((runtime.console = fopen(console, "a")) == 0) {
- fprintf(stderr, "Cannot open output file %s.\n", console);
- return SWITCH_STATUS_FALSE;
- }
- return SWITCH_STATUS_SUCCESS;
- }
- SWITCH_DECLARE(FILE *) switch_core_get_console(void)
- {
- return runtime.console;
- }
- #ifdef HAVE_SYS_IOCTL_H
- #include <sys/ioctl.h>
- #endif
- SWITCH_DECLARE(void) switch_core_screen_size(int *x, int *y)
- {
- #ifdef WIN32
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- int ret;
- if ((ret = GetConsoleScreenBufferInfo(GetStdHandle( STD_OUTPUT_HANDLE ), &csbi))) {
- if (x) *x = csbi.dwSize.X;
- if (y) *y = csbi.dwSize.Y;
- }
- #elif defined(TIOCGWINSZ)
- struct winsize w;
- ioctl(0, TIOCGWINSZ, &w);
- if (x) *x = w.ws_col;
- if (y) *y = w.ws_row;
- #else
- if (x) *x = 80;
- if (y) *y = 24;
- #endif
- }
- SWITCH_DECLARE(FILE *) switch_core_data_channel(switch_text_channel_t channel)
- {
- return runtime.console;
- }
- SWITCH_DECLARE(void) switch_core_remove_state_handler(const switch_state_handler_table_t *state_handler)
- {
- int index, tmp_index = 0;
- const switch_state_handler_table_t *tmp[SWITCH_MAX_STATE_HANDLERS + 1] = { 0 };
- switch_mutex_lock(runtime.global_mutex);
- for (index = 0; index < runtime.state_handler_index; index++) {
- const switch_state_handler_table_t *cur = runtime.state_handlers[index];
- runtime.state_handlers[index] = NULL;
- if (cur == state_handler) {
- continue;
- }
- tmp[tmp_index++] = cur;
- }
- runtime.state_handler_index = 0;
- for (index = 0; index < tmp_index; index++) {
- runtime.state_handlers[runtime.state_handler_index++] = tmp[index];
- }
- switch_mutex_unlock(runtime.global_mutex);
- }
- SWITCH_DECLARE(int) switch_core_add_state_handler(const switch_state_handler_table_t *state_handler)
- {
- int index;
- switch_mutex_lock(runtime.global_mutex);
- index = runtime.state_handler_index;
- if (index > (SWITCH_MAX_STATE_HANDLERS - 1)) {
- index = -1;
- } else {
- runtime.state_handlers[index] = state_handler;
- runtime.state_handler_index++;
- }
- switch_mutex_unlock(runtime.global_mutex);
- return index;
- }
- SWITCH_DECLARE(const switch_state_handler_table_t *) switch_core_get_state_handler(int index)
- {
- if (index >= SWITCH_MAX_STATE_HANDLERS || index > runtime.state_handler_index) {
- return NULL;
- }
- return runtime.state_handlers[index];
- }
- SWITCH_DECLARE(void) switch_core_dump_variables(switch_stream_handle_t *stream)
- {
- switch_event_header_t *hi;
- switch_mutex_lock(runtime.global_mutex);
- for (hi = runtime.global_vars->headers; hi; hi = hi->next) {
- stream->write_function(stream, "%s=%s\n", hi->name, hi->value);
- }
- switch_mutex_unlock(runtime.global_mutex);
- }
- SWITCH_DECLARE(const char *) switch_core_get_hostname(void)
- {
- return runtime.hostname;
- }
- SWITCH_DECLARE(const char *) switch_core_get_switchname(void)
- {
- if (!zstr(runtime.switchname)) return runtime.switchname;
- return runtime.hostname;
- }
- SWITCH_DECLARE(char *) switch_core_get_domain(switch_bool_t dup)
- {
- char *domain;
- const char *var;
- switch_thread_rwlock_rdlock(runtime.global_var_rwlock);
- if (!(var = switch_core_get_variable("domain"))) {
- var = "freeswitch.local";
- }
- if (dup) {
- domain = strdup(var);
- } else {
- domain = (char *) var;
- }
- switch_thread_rwlock_unlock(runtime.global_var_rwlock);
- return domain;
- }
- SWITCH_DECLARE(switch_status_t) switch_core_get_variables(switch_event_t **event)
- {
- switch_status_t status;
- switch_thread_rwlock_rdlock(runtime.global_var_rwlock);
- status = switch_event_dup(event, runtime.global_vars);
- switch_thread_rwlock_unlock(runtime.global_var_rwlock);
- return status;
- }
- SWITCH_DECLARE(char *) switch_core_get_variable(const char *varname)
- {
- char *val;
- switch_thread_rwlock_rdlock(runtime.global_var_rwlock);
- val = (char *) switch_event_get_header(runtime.global_vars, varname);
- switch_thread_rwlock_unlock(runtime.global_var_rwlock);
- return val;
- }
- SWITCH_DECLARE(char *) switch_core_get_variable_dup(const char *varname)
- {
- char *val = NULL, *v;
- if (varname) {
- switch_thread_rwlock_rdlock(runtime.global_var_rwlock);
- if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) {
- val = strdup(v);
- }
- switch_thread_rwlock_unlock(runtime.global_var_rwlock);
- }
- return val;
- }
- SWITCH_DECLARE(char *) switch_core_get_variable_pdup(const char *varname, switch_memory_pool_t *pool)
- {
- char *val = NULL, *v;
- if (varname) {
- switch_thread_rwlock_rdlock(runtime.global_var_rwlock);
- if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) {
- val = switch_core_strdup(pool, v);
- }
- switch_thread_rwlock_unlock(runtime.global_var_rwlock);
- }
- return val;
- }
- static void switch_core_unset_variables(void)
- {
- switch_thread_rwlock_wrlock(runtime.global_var_rwlock);
- switch_event_destroy(&runtime.global_vars);
- switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA);
- switch_thread_rwlock_unlock(runtime.global_var_rwlock);
- }
- SWITCH_DECLARE(void) switch_core_set_variable(const char *varname, const char *value)
- {
- char *val;
- if (varname) {
- switch_thread_rwlock_wrlock(runtime.global_var_rwlock);
- val = (char *) switch_event_get_header(runtime.global_vars, varname);
- if (val) {
- switch_event_del_header(runtime.global_vars, varname);
- }
- if (value) {
- char *v = strdup(value);
- switch_string_var_check(v, SWITCH_TRUE);
- switch_event_add_header_string(runtime.global_vars, SWITCH_STACK_BOTTOM, varname, v);
- free(v);
- } else {
- switch_event_del_header(runtime.global_vars, varname);
- }
- switch_thread_rwlock_unlock(runtime.global_var_rwlock);
- }
- }
- SWITCH_DECLARE(switch_bool_t) switch_core_set_var_conditional(const char *varname, const char *value, const char *val2)
- {
- char *val;
- if (varname) {
- switch_thread_rwlock_wrlock(runtime.global_var_rwlock);
- val = (char *) switch_event_get_header(runtime.global_vars, varname);
- if (val) {
- if (!val2 || strcmp(val, val2) != 0) {
- switch_thread_rwlock_unlock(runtime.global_var_rwlock);
- return SWITCH_FALSE;
- }
- switch_event_del_header(runtime.global_vars, varname);
- } else if (!zstr(val2)) {
- switch_thread_rwlock_unlock(runtime.global_var_rwlock);
- return SWITCH_FALSE;
- }
- if (value) {
- char *v = strdup(value);
- switch_string_var_check(v, SWITCH_TRUE);
- switch_event_add_header_string_nodup(runtime.global_vars, SWITCH_STACK_BOTTOM, varname, v);
- } else {
- switch_event_del_header(runtime.global_vars, varname);
- }
- switch_thread_rwlock_unlock(runtime.global_var_rwlock);
- }
- return SWITCH_TRUE;
- }
- SWITCH_DECLARE(char *) switch_core_get_uuid(void)
- {
- return runtime.uuid_str;
- }
- static void *SWITCH_THREAD_FUNC switch_core_service_thread(switch_thread_t *thread, void *obj)
- {
- switch_core_session_t *session = obj;
- switch_channel_t *channel;
- switch_frame_t *read_frame = NULL;
- // switch_assert(thread != NULL);
- // switch_assert(session != NULL);
- if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
- return NULL;
- }
- switch_mutex_lock(session->frame_read_mutex);
- channel = switch_core_session_get_channel(session);
- switch_channel_set_flag(channel, CF_SERVICE);
- while (switch_channel_test_flag(channel, CF_SERVICE)) {
- if (switch_channel_test_flag(channel, CF_SERVICE_AUDIO)) {
- switch (switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) {
- case SWITCH_STATUS_SUCCESS:
- case SWITCH_STATUS_TIMEOUT:
- case SWITCH_STATUS_BREAK:
- break;
- default:
- switch_channel_clear_flag(channel, CF_SERVICE);
- break;
- }
- }
- if (switch_channel_test_flag(channel, CF_SERVICE_VIDEO) && switch_channel_test_flag(channel, CF_VIDEO)) {
- switch (switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) {
- case SWITCH_STATUS_SUCCESS:
- case SWITCH_STATUS_TIMEOUT:
- case SWITCH_STATUS_BREAK:
- break;
- default:
- switch_channel_clear_flag(channel, CF_SERVICE);
- break;
- }
- }
- }
- switch_mutex_unlock(session->frame_read_mutex);
- switch_channel_clear_flag(channel, CF_SERVICE_AUDIO);
- switch_channel_clear_flag(channel, CF_SERVICE_VIDEO);
- switch_core_session_rwunlock(session);
- return NULL;
- }
- /* Either add a timeout here or make damn sure the thread cannot get hung somehow (my preference) */
- SWITCH_DECLARE(void) switch_core_thread_session_end(switch_core_session_t *session)
- {
- switch_channel_t *channel;
- switch_assert(session);
- channel = switch_core_session_get_channel(session);
- switch_assert(channel);
- switch_channel_clear_flag(channel, CF_SERVICE);
- switch_channel_clear_flag(channel, CF_SERVICE_AUDIO);
- switch_channel_clear_flag(channel, CF_SERVICE_VIDEO);
- switch_core_session_kill_channel(session, SWITCH_SIG_BREAK);
- }
- SWITCH_DECLARE(void) switch_core_service_session_av(switch_core_session_t *session, switch_bool_t audio, switch_bool_t video)
- {
- switch_channel_t *channel;
- switch_assert(session);
- channel = switch_core_session_get_channel(session);
- switch_assert(channel);
- if (audio) switch_channel_set_flag(channel, CF_SERVICE_AUDIO);
- if (video) switch_channel_set_flag(channel, CF_SERVICE_VIDEO);
- switch_core_session_launch_thread(session, (void *(*)(switch_thread_t *,void *))switch_core_service_thread, session);
- }
- /* This function abstracts the thread creation for modules by allowing you to pass a function ptr and
- a void object and trust that that the function will be run in a thread with arg This lets
- you request and activate a thread without giving up any knowledge about what is in the thread
- neither the core nor the calling module know anything about each other.
- This thread is expected to never exit until the application exits so the func is responsible
- to make sure that is the case.
- The typical use for this is so switch_loadable_module.c can start up a thread for each module
- passing the table of module methods as a session obj into the core without actually allowing
- the core to have any clue and keeping switch_loadable_module.c from needing any thread code.
- */
- SWITCH_DECLARE(switch_thread_t *) switch_core_launch_thread(switch_thread_start_t func, void *obj, switch_memory_pool_t *pool)
- {
- switch_thread_t *thread = NULL;
- switch_threadattr_t *thd_attr = NULL;
- switch_core_thread_session_t *ts;
- int mypool;
- mypool = pool ? 0 : 1;
- if (!pool && switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory pool\n");
- return NULL;
- }
- switch_threadattr_create(&thd_attr, pool);
- if ((ts = switch_core_alloc(pool, sizeof(*ts))) == 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory\n");
- } else {
- if (mypool) {
- ts->pool = pool;
- }
- ts->objs[0] = obj;
- ts->objs[1] = thread;
- switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
- switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);
- switch_thread_create(&thread, thd_attr, func, ts, pool);
- }
- return thread;
- }
- SWITCH_DECLARE(void) switch_core_set_globals(void)
- {
- #define BUFSIZE 1024
- #ifdef WIN32
- char lpPathBuffer[BUFSIZE];
- DWORD dwBufSize = BUFSIZE;
- char base_dir[1024];
- char *lastbacklash;
- char *tmp;
- GetModuleFileName(NULL, base_dir, BUFSIZE);
- lastbacklash = strrchr(base_dir, '\\');
- base_dir[(lastbacklash - base_dir)] = '\0';
- /* set base_dir as cwd, to be able to use relative paths in scripting languages (e.g. mod_lua) when FS is running as a service or while debugging FS using visual studio */
- SetCurrentDirectory(base_dir);
- tmp = switch_string_replace(base_dir, "\\", "/");
- strcpy(base_dir, tmp);
- free(tmp);
- #else
- char base_dir[1024] = SWITCH_PREFIX_DIR;
- #endif
- /* Order of precedence for, eg, rundir:
- * -run
- * -base
- * --with-rundir
- * --prefix
- */
- if (!SWITCH_GLOBAL_dirs.mod_dir && (SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s%smod", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR);
- else
- #ifdef SWITCH_MOD_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s", SWITCH_MOD_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s%smod", base_dir, SWITCH_PATH_SEPARATOR);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.lib_dir && (SWITCH_GLOBAL_dirs.lib_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s%slib", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR);
- else
- #ifdef SWITCH_LIB_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s", SWITCH_LIB_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s%slib", base_dir, SWITCH_PATH_SEPARATOR);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.conf_dir && (SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s%sconf", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR);
- else
- #ifdef SWITCH_CONF_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s", SWITCH_CONF_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s%sconf", base_dir, SWITCH_PATH_SEPARATOR);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.log_dir && (SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s%slog", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR);
- else
- #ifdef SWITCH_LOG_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s", SWITCH_LOG_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s%slog", base_dir, SWITCH_PATH_SEPARATOR);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.run_dir && (SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE, "%s%srun", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR);
- else
- #ifdef SWITCH_RUN_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE, "%s", SWITCH_RUN_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE, "%s%srun", base_dir, SWITCH_PATH_SEPARATOR);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.recordings_dir && (SWITCH_GLOBAL_dirs.recordings_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE, "%s%srecordings", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR);
- else
- #ifdef SWITCH_RECORDINGS_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE, "%s", SWITCH_RECORDINGS_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE, "%s%srecordings", base_dir, SWITCH_PATH_SEPARATOR);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.sounds_dir && (SWITCH_GLOBAL_dirs.sounds_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE, "%s%ssounds", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR);
- else
- #ifdef SWITCH_SOUNDS_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE, "%s", SWITCH_SOUNDS_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE, "%s%ssounds", base_dir, SWITCH_PATH_SEPARATOR);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.storage_dir && (SWITCH_GLOBAL_dirs.storage_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE, "%s%sstorage", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR);
- else
- #ifdef SWITCH_STORAGE_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE, "%s", SWITCH_STORAGE_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE, "%s%sstorage", base_dir, SWITCH_PATH_SEPARATOR);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.cache_dir && (SWITCH_GLOBAL_dirs.cache_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.cache_dir, BUFSIZE, "%s%scache", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR);
- else
- #ifdef SWITCH_CACHE_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.cache_dir, BUFSIZE, "%s", SWITCH_CACHE_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.cache_dir, BUFSIZE, "%s%scache", base_dir, SWITCH_PATH_SEPARATOR);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.db_dir && (SWITCH_GLOBAL_dirs.db_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s%sdb", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR);
- else
- #ifdef SWITCH_DB_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s", SWITCH_DB_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s%sdb", base_dir, SWITCH_PATH_SEPARATOR);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.script_dir && (SWITCH_GLOBAL_dirs.script_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s%sscripts", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR);
- else
- #ifdef SWITCH_SCRIPT_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s", SWITCH_SCRIPT_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s%sscripts", base_dir, SWITCH_PATH_SEPARATOR);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.htdocs_dir && (SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s%shtdocs", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR);
- else
- #ifdef SWITCH_HTDOCS_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s", SWITCH_HTDOCS_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s%shtdocs", base_dir, SWITCH_PATH_SEPARATOR);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.grammar_dir && (SWITCH_GLOBAL_dirs.grammar_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE, "%s%sgrammar", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR);
- else
- #ifdef SWITCH_GRAMMAR_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE, "%s", SWITCH_GRAMMAR_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE, "%s%sgrammar", base_dir, SWITCH_PATH_SEPARATOR);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.fonts_dir && (SWITCH_GLOBAL_dirs.fonts_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.fonts_dir, BUFSIZE, "%s%sfonts", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR);
- else
- #ifdef SWITCH_FONTS_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.fonts_dir, BUFSIZE, "%s", SWITCH_FONTS_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.fonts_dir, BUFSIZE, "%s%sfonts", base_dir, SWITCH_PATH_SEPARATOR);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.images_dir && (SWITCH_GLOBAL_dirs.images_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.images_dir, BUFSIZE, "%s%simages", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR);
- else
- #ifdef SWITCH_IMAGES_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.images_dir, BUFSIZE, "%s", SWITCH_IMAGES_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.images_dir, BUFSIZE, "%s%simages", base_dir, SWITCH_PATH_SEPARATOR);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.data_dir && (SWITCH_GLOBAL_dirs.data_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.data_dir, BUFSIZE, "%s", SWITCH_GLOBAL_dirs.base_dir);
- else
- #ifdef SWITCH_DATA_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.data_dir, BUFSIZE, "%s", SWITCH_DATA_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.data_dir, BUFSIZE, "%s", base_dir);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.localstate_dir && (SWITCH_GLOBAL_dirs.localstate_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.localstate_dir, BUFSIZE, "%s", SWITCH_GLOBAL_dirs.base_dir);
- else
- #ifdef SWITCH_LOCALSTATE_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.localstate_dir, BUFSIZE, "%s", SWITCH_LOCALSTATE_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.localstate_dir, BUFSIZE, "%s", base_dir);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.certs_dir && (SWITCH_GLOBAL_dirs.certs_dir = (char *) malloc(BUFSIZE))) {
- if (SWITCH_GLOBAL_dirs.base_dir)
- switch_snprintf(SWITCH_GLOBAL_dirs.certs_dir, BUFSIZE, "%s%scert", SWITCH_GLOBAL_dirs.base_dir, SWITCH_PATH_SEPARATOR);
- else
- #ifdef SWITCH_CERTS_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.certs_dir, BUFSIZE, "%s", SWITCH_CERTS_DIR);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.certs_dir, BUFSIZE, "%s%scert", base_dir, SWITCH_PATH_SEPARATOR);
- #endif
- }
- if (!SWITCH_GLOBAL_dirs.temp_dir && (SWITCH_GLOBAL_dirs.temp_dir = (char *) malloc(BUFSIZE))) {
- #ifdef SWITCH_TEMP_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", SWITCH_TEMP_DIR);
- #else
- #ifdef WIN32
- GetTempPath(dwBufSize, lpPathBuffer);
- lpPathBuffer[strlen(lpPathBuffer)-1] = 0;
- tmp = switch_string_replace(lpPathBuffer, "\\", "/");
- strcpy(lpPathBuffer, tmp);
- free(tmp);
- switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", lpPathBuffer);
- #else
- switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", "/tmp");
- #endif
- #endif
- }
- if (!SWITCH_GLOBAL_filenames.conf_name && (SWITCH_GLOBAL_filenames.conf_name = (char *) malloc(BUFSIZE))) {
- switch_snprintf(SWITCH_GLOBAL_filenames.conf_name, BUFSIZE, "%s", "freeswitch.xml");
- }
- /* Do this last because it being empty is part of the above logic */
- if (!SWITCH_GLOBAL_dirs.base_dir && (SWITCH_GLOBAL_dirs.base_dir = (char *) malloc(BUFSIZE))) {
- switch_snprintf(SWITCH_GLOBAL_dirs.base_dir, BUFSIZE, "%s", base_dir);
- }
- switch_assert(SWITCH_GLOBAL_dirs.base_dir);
- switch_assert(SWITCH_GLOBAL_dirs.mod_dir);
- switch_assert(SWITCH_GLOBAL_dirs.lib_dir);
- switch_assert(SWITCH_GLOBAL_dirs.conf_dir);
- switch_assert(SWITCH_GLOBAL_dirs.log_dir);
- switch_assert(SWITCH_GLOBAL_dirs.run_dir);
- switch_assert(SWITCH_GLOBAL_dirs.db_dir);
- switch_assert(SWITCH_GLOBAL_dirs.script_dir);
- switch_assert(SWITCH_GLOBAL_dirs.htdocs_dir);
- switch_assert(SWITCH_GLOBAL_dirs.grammar_dir);
- switch_assert(SWITCH_GLOBAL_dirs.fonts_dir);
- switch_assert(SWITCH_GLOBAL_dirs.images_dir);
- switch_assert(SWITCH_GLOBAL_dirs.recordings_dir);
- switch_assert(SWITCH_GLOBAL_dirs.sounds_dir);
- switch_assert(SWITCH_GLOBAL_dirs.certs_dir);
- switch_assert(SWITCH_GLOBAL_dirs.temp_dir);
- switch_assert(SWITCH_GLOBAL_dirs.data_dir);
- switch_assert(SWITCH_GLOBAL_dirs.localstate_dir);
- switch_assert(SWITCH_GLOBAL_filenames.conf_name);
- }
- SWITCH_DECLARE(int32_t) switch_core_set_process_privileges(void)
- {
- #ifdef SOLARIS_PRIVILEGES
- priv_set_t *basicset;
- /* make the process privilege-aware */
- setpflags(PRIV_AWARE, 1);
- /* reset the privileges to basic */
- basicset = priv_str_to_set("basic", ",", NULL);
- if (setppriv(PRIV_SET, PRIV_EFFECTIVE, basicset) != 0) {
- fprintf(stderr, "ERROR: Failed to acquire basic privileges (%s)\n", strerror(errno));
- }
- /* we need high-resolution clock, and this requires a non-basic privilege */
- if (priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_CLOCK_HIGHRES, NULL) < 0) {
- fprintf(stderr, "ERROR: Failed to acquire proc_clock_highres privilege (%s)\n", strerror(errno));
- return -1;
- }
- /* need this for setrlimit */
- if (priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_RESOURCE, NULL) < 0) {
- fprintf(stderr, "ERROR: Failed to acquire sys_resource privilege (%s)\n", strerror(errno));
- return -1;
- }
- /* we need to read directories belonging to other uid */
- if (priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_FILE_DAC_SEARCH, NULL) < 0) {
- fprintf(stderr, "ERROR: Failed to acquire file_dac_search privilege (%s)\n", strerror(errno));
- return -1;
- }
- #endif
- return 0;
- }
- SWITCH_DECLARE(int32_t) set_low_priority(void)
- {
- #ifdef WIN32
- return SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
- #else
- #if defined(USE_SCHED_SETSCHEDULER) && ! defined(SOLARIS_PRIVILEGES)
- /*
- * Try to use a normal scheduler
- */
- struct sched_param sched = { 0 };
- sched.sched_priority = 0;
- if (sched_setscheduler(0, SCHED_OTHER, &sched) < 0) {
- fprintf(stderr, "ERROR: Failed to set SCHED_OTHER scheduler (%s)\n", strerror(errno));
- return -1;
- }
- #endif
- #ifdef HAVE_SETPRIORITY
- /*
- * setpriority() works on FreeBSD (6.2), nice() doesn't
- */
- if (setpriority(PRIO_PROCESS, getpid(), 19) < 0) {
- fprintf(stderr, "ERROR: Could not set nice level\n");
- return -1;
- }
- #else
- if (nice(19) != 19) {
- fprintf(stderr, "ERROR: Could not set nice level\n");
- return -1;
- }
- #endif
- return 0;
- #endif
- }
- SWITCH_DECLARE(int32_t) set_realtime_priority(void)
- {
- #ifdef WIN32
- return SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
- #else
- #ifdef USE_SCHED_SETSCHEDULER
- /*
- * Try to use a round-robin scheduler
- * with a fallback if that does not work
- */
- struct sched_param sched = { 0 };
- sched.sched_priority = SWITCH_PRI_LOW;
- #endif
- #ifdef SOLARIS_PRIVILEGES
- /* request the privileges to elevate the priority */
- if (priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_PRIOCNTL, NULL) < 0) {
- #ifdef PRIV_PROC_PRIOUP
- /* fallback to PRIV_PROC_PRIOUP on SmartOS */
- fprintf(stderr, "WARN: Failed to acquire proc_priocntl privilege (%s)\n", strerror(errno));
- if (priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_PRIOUP, NULL) < 0) {
- fprintf(stderr, "ERROR: Failed to acquire proc_prioup privilege (%s)\n", strerror(errno));
- return -1;
- }
- #else
- fprintf(stderr, "ERROR: Failed to acquire proc_priocntl privilege (%s)\n", strerror(errno));
- return -1;
- #endif
- }
- if (sched_setscheduler(0, SCHED_FIFO, &sched) < 0) {
- fprintf(stderr, "WARN: Failed to set SCHED_FIFO scheduler (%s)\n", strerror(errno));
- } else {
- return 0;
- }
- if (setpriority(PRIO_PROCESS, 0, -10) < 0) {
- fprintf(stderr, "ERROR: Could not set nice level\n");
- return -1;
- }
- return 0;
- #else
- #ifdef USE_SCHED_SETSCHEDULER
- if (sched_setscheduler(0, SCHED_FIFO, &sched) < 0) {
- fprintf(stderr, "ERROR: Failed to set SCHED_FIFO scheduler (%s)\n", strerror(errno));
- sched.sched_priority = 0;
- if (sched_setscheduler(0, SCHED_OTHER, &sched) < 0 ) {
- fprintf(stderr, "ERROR: Failed to set SCHED_OTHER scheduler (%s)\n", strerror(errno));
- return -1;
- }
- }
- #endif
- #ifdef HAVE_SETPRIORITY
- /*
- * setpriority() works on FreeBSD (6.2), nice() doesn't
- */
- if (setpriority(PRIO_PROCESS, getpid(), -10) < 0) {
- fprintf(stderr, "ERROR: Could not set nice level\n");
- return -1;
- }
- #else
- if (nice(-10) != -10) {
- fprintf(stderr, "ERROR: Could not set nice level\n");
- return -1;
- }
- #endif
- #endif
- return 0;
- #endif
- }
- SWITCH_DECLARE(uint32_t) switch_core_cpu_count(void)
- {
- return runtime.cpu_count;
- }
- SWITCH_DECLARE(int32_t) set_normal_priority(void)
- {
- return 0;
- }
- SWITCH_DECLARE(int32_t) set_auto_priority(void)
- {
- #ifndef WIN32
- runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN);
- #else
- SYSTEM_INFO sysinfo;
- GetSystemInfo( &sysinfo );
- runtime.cpu_count = sysinfo.dwNumberOfProcessors;
- #endif
- if (!runtime.cpu_count) runtime.cpu_count = 1;
- return set_realtime_priority();
- // ERROR: code not reachable on Windows Visual Studio Express 2008 return 0;
- }
- SWITCH_DECLARE(int32_t) change_user_group(const char *user, const char *group)
- {
- #ifndef WIN32
- uid_t runas_uid = 0;
- gid_t runas_gid = 0;
- struct passwd *runas_pw = NULL;
- if (user) {
- /*
- * Lookup user information in the system's db
- */
- runas_pw = getpwnam(user);
- if (!runas_pw) {
- fprintf(stderr, "ERROR: Unknown user \"%s\"\n", user);
- return -1;
- }
- runas_uid = runas_pw->pw_uid;
- }
- if (group) {
- struct group *gr = NULL;
- /*
- * Lookup group information in the system's db
- */
- gr = getgrnam(group);
- if (!gr) {
- fprintf(stderr, "ERROR: Unknown group \"%s\"\n", group);
- return -1;
- }
- runas_gid = gr->gr_gid;
- }
- if (runas_uid && getuid() == runas_uid && (!runas_gid || runas_gid == getgid())) {
- /* already running as the right user and group, nothing to do! */
- return 0;
- }
- if (runas_uid) {
- #ifdef SOLARIS_PRIVILEGES
- /* request the privilege to set the UID */
- if (priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_SETID, NULL) < 0) {
- fprintf(stderr, "ERROR: Failed to acquire proc_setid privilege (%s)\n", strerror(errno));
- return -1;
- }
- #endif
- #ifdef HAVE_SETGROUPS
- /*
- * Drop all group memberships prior to changing anything
- * or else we're going to inherit the parent's list of groups
- * (which is not what we want...)
- */
- if (setgroups(0, NULL) < 0) {
- fprintf(stderr, "ERROR: Failed to drop group access list\n");
- return -1;
- }
- #endif
- if (runas_gid) {
- /*
- * A group has been passed, switch to it
- * (without loading the user's other groups)
- */
- if (setgid(runas_gid) < 0) {
- fprintf(stderr, "ERROR: Failed to change gid!\n");
- return -1;
- }
- } else {
- /*
- * No group has been passed, use the user's primary group in this case
- */
- if (setgid(runas_pw->pw_gid) < 0) {
- fprintf(stderr, "ERROR: Failed to change gid!\n");
- return -1;
- }
- #ifdef HAVE_INITGROUPS
- /*
- * Set all the other groups the user is a member of
- * (This can be really useful for fine-grained access control)
- */
- if (initgroups(runas_pw->pw_name, runas_pw->pw_gid) < 0) {
- fprintf(stderr, "ERROR: Failed to set group access list for user\n");
- return -1;
- }
- #endif
- }
- /*
- * Finally drop all privileges by switching to the new userid
- */
- if (setuid(runas_uid) < 0) {
- fprintf(stderr, "ERROR: Failed to change uid!\n");
- return -1;
- }
- #ifdef HAVE_SYS_PRCTL_H
- if (prctl(PR_SET_DUMPABLE, 1) < 0) {
- fprintf(stderr, "ERROR: Failed to enable core dumps!\n");
- return -1;
- }
- #endif
- }
- #endif
- return 0;
- }
- SWITCH_DECLARE(void) switch_core_runtime_loop(int bg)
- {
- #ifdef WIN32
- HANDLE shutdown_event;
- char path[256] = "";
- #endif
- if (bg) {
- #ifdef WIN32
- switch_snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid());
- shutdown_event = CreateEvent(NULL, FALSE, FALSE, path);
- if (shutdown_event) {
- WaitForSingleObject(shutdown_event, INFINITE);
- }
- #else
- while (runtime.running) {
- switch_yield(1000000);
- }
- #endif
- } else {
- /* wait for console input */
- switch_console_loop();
- }
- }
- SWITCH_DECLARE(const char *) switch_core_mime_ext2type(const char *ext)
- {
- if (!ext) {
- return NULL;
- }
- return (const char *) switch_core_hash_find(runtime.mime_types, ext);
- }
- SWITCH_DECLARE(const char *) switch_core_mime_type2ext(const char *mime)
- {
- if (!mime) {
- return NULL;
- }
- return (const char *) switch_core_hash_find(runtime.mime_type_exts, mime);
- }
- SWITCH_DECLARE(switch_hash_index_t *) switch_core_mime_index(void)
- {
- return switch_core_hash_first(runtime.mime_types);
- }
- SWITCH_DECLARE(switch_status_t) switch_core_mime_add_type(const char *type, const char *ext)
- {
- char *ptype = NULL;
- char *ext_list = NULL;
- int argc = 0;
- char *argv[20] = { 0 };
- int x;
- switch_status_t status = SWITCH_STATUS_FALSE;
- switch_assert(type);
- switch_assert(ext);
- ptype = switch_core_permanent_strdup(type);
- ext_list = strdup(ext);
- switch_assert(ext_list);
- /* Map each file extension to this MIME type if not already mapped. Map the MIME type to the first file extension in the list if not already mapped. */
- if ((argc = switch_separate_string(ext_list, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
- int is_mapped_type = switch_core_hash_find(runtime.mime_type_exts, ptype) != NULL;
- for (x = 0; x < argc; x++) {
- if (argv[x] && ptype) {
- if (!switch_core_hash_find(runtime.mime_types, ext)) {
- switch_core_hash_insert(runtime.mime_types, argv[x], ptype);
- }
- if (!is_mapped_type) {
- switch_core_hash_insert(runtime.mime_type_exts, ptype, switch_core_permanent_strdup(argv[x]));
- is_mapped_type = 1;
- }
- }
- }
- status = SWITCH_STATUS_SUCCESS;
- }
- free(ext_list);
- return status;
- }
- static void load_mime_types(void)
- {
- char *cf = "mime.types";
- FILE *fd = NULL;
- char *line_buf = NULL;
- switch_size_t llen = 0;
- char *mime_path = NULL;
- mime_path = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.conf_dir, cf);
- switch_assert(mime_path);
- fd = fopen(mime_path, "rb");
- if (fd == NULL) {
- goto end;
- }
- while ((switch_fp_read_dline(fd, &line_buf, &llen))) {
- char *p;
- char *type = line_buf;
- if (*line_buf == '#') {
- continue;
- }
- if ((p = strchr(line_buf, '\r')) || (p = strchr(line_buf, '\n'))) {
- *p = '\0';
- }
- if ((p = strchr(type, '\t')) || (p = strchr(type, ' '))) {
- *p++ = '\0';
- while (*p == ' ' || *p == '\t') {
- p++;
- }
- switch_core_mime_add_type(type, p);
- }
- }
- switch_safe_free(line_buf);
- fclose(fd);
- end:
- switch_safe_free(mime_path);
- }
- SWITCH_DECLARE(void) switch_core_setrlimits(void)
- {
- #ifdef HAVE_SETRLIMIT
- struct rlimit rlp;
- /*
- Setting the stack size on FreeBSD results in an instant crash.
- If anyone knows how to fix this,
- feel free to submit a patch to https://github.com/signalwire/freeswitch
- */
- #ifndef __FreeBSD__
- memset(&rlp, 0, sizeof(rlp));
- rlp.rlim_cur = SWITCH_THREAD_STACKSIZE;
- rlp.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE;
- setrlimit(RLIMIT_STACK, &rlp);
- #endif
- memset(&rlp, 0, sizeof(rlp));
- rlp.rlim_cur = 999999;
- rlp.rlim_max = 999999;
- setrlimit(RLIMIT_NOFILE, &rlp);
- memset(&rlp, 0, sizeof(rlp));
- rlp.rlim_cur = RLIM_INFINITY;
- rlp.rlim_max = RLIM_INFINITY;
- setrlimit(RLIMIT_CPU, &rlp);
- setrlimit(RLIMIT_DATA, &rlp);
- setrlimit(RLIMIT_FSIZE, &rlp);
- #ifdef RLIMIT_NPROC
- setrlimit(RLIMIT_NPROC, &rlp);
- #endif
- #ifdef RLIMIT_RTPRIO
- setrlimit(RLIMIT_RTPRIO, &rlp);
- #endif
- #if !defined(__OpenBSD__) && !defined(__NetBSD__)
- setrlimit(RLIMIT_AS, &rlp);
- #endif
- #endif
- return;
- }
- typedef struct {
- switch_memory_pool_t *pool;
- switch_hash_t *hash;
- } switch_ip_list_t;
- static switch_ip_list_t IP_LIST = { 0 };
- SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_port_token(const char *ip_str, int port, const char *list_name, const char **token)
- {
- switch_network_list_t *list;
- ip_t ip, mask, net;
- uint32_t bits;
- char *ipv6 = strchr(ip_str,':');
- switch_bool_t ok = SWITCH_FALSE;
- char *ipv4 = NULL;
- if (!list_name) {
- return SWITCH_FALSE;
- }
- if ((ipv4 = switch_network_ipv4_mapped_ipv6_addr(ip_str))) {
- ip_str = ipv4;
- ipv6 = NULL;
- }
- switch_mutex_lock(runtime.global_mutex);
- if (ipv6) {
- switch_inet_pton(AF_INET6, ip_str, &ip);
- } else {
- switch_inet_pton(AF_INET, ip_str, &ip);
- ip.v4 = htonl(ip.v4);
- }
- if ((list = switch_core_hash_find(IP_LIST.hash, list_name))) {
- if (ipv6) {
- ok = switch_network_list_validate_ip6_port_token(list, ip, port, token);
- } else {
- ok = switch_network_list_validate_ip_port_token(list, ip.v4, port, token);
- }
- } else if (strchr(list_name, '/')) {
- if (strchr(list_name, ',')) {
- char *list_name_dup = strdup(list_name);
- char *argv[100]; /* MAX ACL */
- int argc;
- switch_assert(list_name_dup);
- if ((argc = switch_separate_string(list_name_dup, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
- int i;
- for (i = 0; i < argc; i++) {
- switch_parse_cidr(argv[i], &net, &mask, &bits);
- if (ipv6) {
- if ((ok = switch_testv6_subnet(ip, net, mask))){
- break;
- }
- } else {
- if ((ok = switch_test_subnet(ip.v4, net.v4, mask.v4))) {
- break;
- }
- }
- }
- }
- free(list_name_dup);
- } else {
- switch_parse_cidr(list_name, &net, &mask, &bits);
- if (ipv6) {
- ok = switch_testv6_subnet(ip, net, mask);
- } else {
- ok = switch_test_subnet(ip.v4, net.v4, mask.v4);
- }
- }
- }
- switch_safe_free(ipv4);
- switch_mutex_unlock(runtime.global_mutex);
- return ok;
- }
- SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token)
- {
- return switch_check_network_list_ip_port_token(ip_str, 0, list_name, token);
- }
- SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload)
- {
- switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, x_node = NULL, cfg = NULL;
- switch_network_list_t *rfc_list, *list;
- char guess_ip[16] = "";
- int mask = 0;
- char guess_mask[16] = "";
- char *tmp_name;
- struct in_addr in;
- switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET);
- in.s_addr = mask;
- switch_set_string(guess_mask, inet_ntoa(in));
- switch_mutex_lock(runtime.global_mutex);
- if (IP_LIST.hash) {
- switch_core_hash_destroy(&IP_LIST.hash);
- }
- if (IP_LIST.pool) {
- switch_core_destroy_memory_pool(&IP_LIST.pool);
- }
- memset(&IP_LIST, 0, sizeof(IP_LIST));
- switch_core_new_memory_pool(&IP_LIST.pool);
- switch_core_hash_init(&IP_LIST.hash);
- tmp_name = "rfc6598.auto";
- switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
- switch_network_list_add_cidr(rfc_list, "100.64.0.0/10", SWITCH_TRUE);
- switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
- tmp_name = "rfc1918.auto";
- switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
- switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE);
- switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE);
- switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE);
- switch_network_list_add_cidr(rfc_list, "fe80::/10", SWITCH_TRUE);
- switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
- tmp_name = "wan.auto";
- switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name);
- switch_network_list_add_cidr(rfc_list, "0.0.0.0/8", SWITCH_FALSE);
- switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_FALSE);
- switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_FALSE);
- switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_FALSE);
- switch_network_list_add_cidr(rfc_list, "169.254.0.0/16", SWITCH_FALSE);
- switch_network_list_add_cidr(rfc_list, "100.64.0.0/10", SWITCH_FALSE);
- switch_network_list_add_cidr(rfc_list, "fe80::/10", SWITCH_FALSE);
- switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
- tmp_name = "wan_v6.auto";
- switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name);
- switch_network_list_add_cidr(rfc_list, "0.0.0.0/0", SWITCH_FALSE);
- switch_network_list_add_cidr(rfc_list, "fe80::/10", SWITCH_FALSE);
- switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
- tmp_name = "wan_v4.auto";
- switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name);
- switch_network_list_add_cidr(rfc_list, "0.0.0.0/8", SWITCH_FALSE);
- switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_FALSE);
- switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_FALSE);
- switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_FALSE);
- switch_network_list_add_cidr(rfc_list, "169.254.0.0/16", SWITCH_FALSE);
- switch_network_list_add_cidr(rfc_list, "100.64.0.0/10", SWITCH_FALSE);
- switch_network_list_add_cidr(rfc_list, "::/0", SWITCH_FALSE);
- switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
- tmp_name = "any_v6.auto";
- switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name);
- switch_network_list_add_cidr(rfc_list, "0.0.0.0/0", SWITCH_FALSE);
- switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
- tmp_name = "any_v4.auto";
- switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name);
- switch_network_list_add_cidr(rfc_list, "::/0", SWITCH_FALSE);
- switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
- tmp_name = "nat.auto";
- switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
- if (switch_network_list_add_host_mask(rfc_list, guess_ip, guess_mask, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (deny) to list %s\n", guess_ip, guess_mask, tmp_name);
- }
- switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE);
- switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE);
- switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE);
- switch_network_list_add_cidr(rfc_list, "100.64.0.0/10", SWITCH_TRUE);
- switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
- tmp_name = "loopback.auto";
- switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
- switch_network_list_add_cidr(rfc_list, "127.0.0.0/8", SWITCH_TRUE);
- switch_network_list_add_cidr(rfc_list, "::1/128", SWITCH_TRUE);
- switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
- tmp_name = "localnet.auto";
- switch_network_list_create(&list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
- if (switch_network_list_add_host_mask(list, guess_ip, guess_mask, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (allow) to list %s\n", guess_ip, guess_mask, tmp_name);
- }
- switch_core_hash_insert(IP_LIST.hash, tmp_name, list);
- if ((xml = switch_xml_open_cfg("acl.conf", &cfg, NULL))) {
- if ((x_lists = switch_xml_child(cfg, "network-lists"))) {
- for (x_list = switch_xml_child(x_lists, "list"); x_list; x_list = x_list->next) {
- const char *name = switch_xml_attr(x_list, "name");
- const char *dft = switch_xml_attr(x_list, "default");
- switch_bool_t default_type = SWITCH_TRUE;
- if (zstr(name)) {
- continue;
- }
- if (dft) {
- default_type = switch_true(dft);
- }
- if (switch_network_list_create(&list, name, default_type, IP_LIST.pool) != SWITCH_STATUS_SUCCESS) {
- abort();
- }
- if (reload) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny");
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny");
- }
- for (x_node = switch_xml_child(x_list, "node"); x_node; x_node = x_node->next) {
- const char *cidr = NULL, *host = NULL, *mask = NULL, *domain = NULL, *port = NULL;
- switch_bool_t ok = default_type;
- const char *type = switch_xml_attr(x_node, "type");
- switch_network_port_range_t port_range;
- char *argv[MAX_NETWORK_PORTS] = { 0 };
- int argc = 0, i;
- if (type) {
- ok = switch_true(type);
- }
- cidr = switch_xml_attr(x_node, "cidr");
- host = switch_xml_attr(x_node, "host");
- mask = switch_xml_attr(x_node, "mask");
- domain = switch_xml_attr(x_node, "domain");
- memset(&port_range, 0, sizeof(switch_network_port_range_t));
- if( (port = switch_xml_attr(x_node, "port")) != NULL) {
- port_range.port = atoi(port);
- }
- if( (port = switch_xml_attr(x_node, "ports")) != NULL) {
- argc = switch_separate_string((char*)port, ',', argv, (sizeof(argv) / sizeof(argv[0])));
- for(i=0; i < argc; i++) {
- port_range.ports[i] = atoi(argv[i]);
- }
- }
- if( (port = switch_xml_attr(x_node, "port-min")) != NULL) {
- port_range.min_port = atoi(port);
- }
- if( (port = switch_xml_attr(x_node, "port-max")) != NULL) {
- port_range.max_port = atoi(port);
- }
- if (domain) {
- switch_event_t *my_params = NULL;
- switch_xml_t x_domain, xml_root;
- switch_xml_t gt, gts, ut, uts;
- switch_event_create(&my_params, SWITCH_EVENT_GENERAL);
- switch_assert(my_params);
- switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "domain", domain);
- switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "purpose", "network-list");
- if (switch_xml_locate_domain(domain, my_params, &xml_root, &x_domain) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate domain %s\n", domain);
- switch_event_destroy(&my_params);
- continue;
- }
- switch_event_destroy(&my_params);
- if ((ut = switch_xml_child(x_domain, "users"))) {
- x_domain = ut;
- }
- for (ut = switch_xml_child(x_domain, "user"); ut; ut = ut->next) {
- const char *user_cidr = switch_xml_attr(ut, "cidr");
- const char *id = switch_xml_attr(ut, "id");
- if (id && user_cidr) {
- char *token = switch_mprintf("%s@%s", id, domain);
- switch_assert(token);
- switch_network_list_add_cidr_token(list, user_cidr, ok, token);
- free(token);
- }
- }
- for (gts = switch_xml_child(x_domain, "groups"); gts; gts = gts->next) {
- for (gt = switch_xml_child(gts, "group"); gt; gt = gt->next) {
- for (uts = switch_xml_child(gt, "users"); uts; uts = uts->next) {
- for (ut = switch_xml_child(uts, "user"); ut; ut = ut->next) {
- const char *user_cidr = switch_xml_attr(ut, "cidr");
- const char *id = switch_xml_attr(ut, "id");
- if (id && user_cidr) {
- char *token = switch_mprintf("%s@%s", id, domain);
- switch_assert(token);
- switch_network_list_add_cidr_port_token(list, user_cidr, ok, token, &port_range);
- free(token);
- }
- }
- }
- }
- }
- switch_xml_free(xml_root);
- } else if (cidr) {
- switch_network_list_add_cidr_port_token(list, cidr, ok, NULL, &port_range);
- } else if (host && mask) {
- switch_network_list_add_host_port_mask(list, host, mask, ok, &port_range);
- }
- }
- switch_core_hash_insert(IP_LIST.hash, name, list);
- }
- }
- switch_xml_free(xml);
- }
- switch_mutex_unlock(runtime.global_mutex);
- }
- SWITCH_DECLARE(uint32_t) switch_core_max_dtmf_duration(uint32_t duration)
- {
- if (duration) {
- if (duration > SWITCH_MAX_DTMF_DURATION) {
- duration = SWITCH_MAX_DTMF_DURATION;
- }
- if (duration < SWITCH_MIN_DTMF_DURATION) {
- duration = SWITCH_MIN_DTMF_DURATION;
- }
- runtime.max_dtmf_duration = duration;
- if (duration < runtime.min_dtmf_duration) {
- runtime.min_dtmf_duration = duration;
- }
- }
- return runtime.max_dtmf_duration;
- }
- SWITCH_DECLARE(uint32_t) switch_core_default_dtmf_duration(uint32_t duration)
- {
- if (duration) {
- if (duration < SWITCH_MIN_DTMF_DURATION) {
- duration = SWITCH_MIN_DTMF_DURATION;
- }
- if (duration > SWITCH_MAX_DTMF_DURATION) {
- duration = SWITCH_MAX_DTMF_DURATION;
- }
- runtime.default_dtmf_duration = duration;
- if (duration < runtime.min_dtmf_duration) {
- runtime.min_dtmf_duration = duration;
- }
- if (duration > runtime.max_dtmf_duration) {
- runtime.max_dtmf_duration = duration;
- }
- }
- return runtime.default_dtmf_duration;
- }
- SWITCH_DECLARE(uint32_t) switch_core_min_dtmf_duration(uint32_t duration)
- {
- if (duration) {
- if (duration < SWITCH_MIN_DTMF_DURATION) {
- duration = SWITCH_MIN_DTMF_DURATION;
- }
- if (duration > SWITCH_MAX_DTMF_DURATION) {
- duration = SWITCH_MAX_DTMF_DURATION;
- }
- runtime.min_dtmf_duration = duration;
- if (duration > runtime.max_dtmf_duration) {
- runtime.max_dtmf_duration = duration;
- }
- }
- return runtime.min_dtmf_duration;
- }
- SWITCH_DECLARE(switch_status_t) switch_core_thread_set_cpu_affinity(int cpu)
- {
- switch_status_t status = SWITCH_STATUS_FALSE;
- if (cpu > -1) {
- #ifdef HAVE_CPU_SET_MACROS
- cpu_set_t set;
- CPU_ZERO(&set);
- CPU_SET(cpu, &set);
- if (!sched_setaffinity(0, sizeof(set), &set)) {
- status = SWITCH_STATUS_SUCCESS;
- }
- #else
- #if WIN32
- if (SetThreadAffinityMask(GetCurrentThread(), (DWORD_PTR) cpu)) {
- status = SWITCH_STATUS_SUCCESS;
- }
- #endif
- #endif
- }
- return status;
- }
- SWITCH_DECLARE(int) switch_core_test_flag(int flag)
- {
- return switch_test_flag((&runtime), flag);
- }
- SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switch_bool_t console, const char **err)
- {
- switch_uuid_t uuid;
- char guess_ip[256];
- int mask = 0;
- struct in_addr in;
- if (runtime.runlevel > 0) {
- /* one per customer */
- return SWITCH_STATUS_SUCCESS;
- }
- memset(&runtime, 0, sizeof(runtime));
- gethostname(runtime.hostname, sizeof(runtime.hostname));
- runtime.shutdown_cause = SWITCH_CAUSE_SYSTEM_SHUTDOWN;
- runtime.max_db_handles = 50;
- runtime.db_handle_timeout = 5000000;
- runtime.event_heartbeat_interval = 20;
- runtime.runlevel++;
- runtime.dummy_cng_frame.data = runtime.dummy_data;
- runtime.dummy_cng_frame.datalen = sizeof(runtime.dummy_data);
- runtime.dummy_cng_frame.buflen = sizeof(runtime.dummy_data);
- runtime.dbname = "core";
- switch_set_flag((&runtime.dummy_cng_frame), SFF_CNG);
- switch_set_flag((&runtime), SCF_AUTO_SCHEMAS);
- switch_set_flag((&runtime), SCF_CLEAR_SQL);
- switch_set_flag((&runtime), SCF_API_EXPANSION);
- switch_set_flag((&runtime), SCF_SESSION_THREAD_POOL);
- #ifdef WIN32
- switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
- #endif
- switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
- if (flags & SCF_LOG_DISABLE) {
- runtime.hard_log_level = SWITCH_LOG_DISABLE;
- flags &= ~SCF_LOG_DISABLE;
- } else {
- runtime.hard_log_level = SWITCH_LOG_DEBUG;
- }
- runtime.mailer_app = "sendmail";
- runtime.mailer_app_args = "-t";
- runtime.max_dtmf_duration = SWITCH_MAX_DTMF_DURATION;
- runtime.default_dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION;
- runtime.min_dtmf_duration = SWITCH_MIN_DTMF_DURATION;
- runtime.odbc_dbtype = DBTYPE_DEFAULT;
- runtime.dbname = NULL;
- #ifndef WIN32
- runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN);
- #else
- {
- SYSTEM_INFO sysinfo;
- GetSystemInfo( &sysinfo );
- runtime.cpu_count = sysinfo.dwNumberOfProcessors;
- }
- #endif
- if (!runtime.cpu_count) runtime.cpu_count = 1;
- if (sqlite3_initialize() != SQLITE_OK) {
- *err = "FATAL ERROR! Could not initialize SQLite\n";
- return SWITCH_STATUS_MEMERR;
- }
- /* INIT APR and Create the pool context */
- if (fspr_initialize() != SWITCH_STATUS_SUCCESS) {
- *err = "FATAL ERROR! Could not initialize APR\n";
- return SWITCH_STATUS_MEMERR;
- }
- if (!(runtime.memory_pool = switch_core_memory_init())) {
- *err = "FATAL ERROR! Could not allocate memory pool\n";
- return SWITCH_STATUS_MEMERR;
- }
- switch_assert(runtime.memory_pool != NULL);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.base_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.mod_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.conf_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.log_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.run_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.db_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.script_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.htdocs_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.fonts_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.images_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.recordings_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.sounds_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.temp_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.certs_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_mutex_init(&runtime.uuid_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
- switch_mutex_init(&runtime.throttle_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
- switch_mutex_init(&runtime.session_hash_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
- switch_mutex_init(&runtime.global_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
- switch_thread_rwlock_create(&runtime.global_var_rwlock, runtime.memory_pool);
- switch_core_set_globals();
- switch_core_session_init(runtime.memory_pool);
- switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA);
- switch_core_hash_init_case(&runtime.mime_types, SWITCH_FALSE);
- switch_core_hash_init_case(&runtime.mime_type_exts, SWITCH_FALSE);
- switch_core_hash_init_case(&runtime.ptimes, SWITCH_FALSE);
- load_mime_types();
- runtime.flags |= flags;
- runtime.sps_total = 30;
- *err = NULL;
- if (console) {
- runtime.console = stdout;
- }
- SSL_library_init();
- switch_ssl_init_ssl_locks();
- OpenSSL_add_all_algorithms();
- switch_curl_init();
- switch_core_set_variable("hostname", runtime.hostname);
- switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET);
- switch_core_set_variable("local_ip_v4", guess_ip);
- in.s_addr = mask;
- switch_core_set_variable("local_mask_v4", inet_ntoa(in));
- switch_find_local_ip(guess_ip, sizeof(guess_ip), NULL, AF_INET6);
- switch_core_set_variable("local_ip_v6", guess_ip);
- switch_core_set_variable("base_dir", SWITCH_GLOBAL_dirs.base_dir);
- switch_core_set_variable("recordings_dir", SWITCH_GLOBAL_dirs.recordings_dir);
- switch_core_set_variable("sound_prefix", SWITCH_GLOBAL_dirs.sounds_dir);
- switch_core_set_variable("sounds_dir", SWITCH_GLOBAL_dirs.sounds_dir);
- switch_core_set_variable("conf_dir", SWITCH_GLOBAL_dirs.conf_dir);
- switch_core_set_variable("log_dir", SWITCH_GLOBAL_dirs.log_dir);
- switch_core_set_variable("run_dir", SWITCH_GLOBAL_dirs.run_dir);
- switch_core_set_variable("db_dir", SWITCH_GLOBAL_dirs.db_dir);
- switch_core_set_variable("mod_dir", SWITCH_GLOBAL_dirs.mod_dir);
- switch_core_set_variable("htdocs_dir", SWITCH_GLOBAL_dirs.htdocs_dir);
- switch_core_set_variable("script_dir", SWITCH_GLOBAL_dirs.script_dir);
- switch_core_set_variable("temp_dir", SWITCH_GLOBAL_dirs.temp_dir);
- switch_core_set_variable("grammar_dir", SWITCH_GLOBAL_dirs.grammar_dir);
- switch_core_set_variable("fonts_dir", SWITCH_GLOBAL_dirs.fonts_dir);
- switch_core_set_variable("images_dir", SWITCH_GLOBAL_dirs.images_dir);
- switch_core_set_variable("certs_dir", SWITCH_GLOBAL_dirs.certs_dir);
- switch_core_set_variable("storage_dir", SWITCH_GLOBAL_dirs.storage_dir);
- switch_core_set_variable("cache_dir", SWITCH_GLOBAL_dirs.cache_dir);
- switch_core_set_variable("data_dir", SWITCH_GLOBAL_dirs.data_dir);
- switch_core_set_variable("localstate_dir", SWITCH_GLOBAL_dirs.localstate_dir);
- switch_console_init(runtime.memory_pool);
- switch_event_init(runtime.memory_pool);
- switch_channel_global_init(runtime.memory_pool);
- if (switch_xml_init(runtime.memory_pool, err) != SWITCH_STATUS_SUCCESS) {
- /* allow missing configuration if MINIMAL */
- if (!(flags & SCF_MINIMAL)) {
- fspr_terminate();
- return SWITCH_STATUS_MEMERR;
- }
- }
- if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) {
- switch_nat_init(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_NAT_MAPPING));
- }
- switch_log_init(runtime.memory_pool, runtime.colorize_console);
- runtime.tipping_point = 0;
- runtime.timer_affinity = -1;
- runtime.microseconds_per_tick = 20000;
- if (flags & SCF_MINIMAL) return SWITCH_STATUS_SUCCESS;
- switch_load_core_config("switch.conf");
- switch_core_state_machine_init(runtime.memory_pool);
- switch_core_media_init();
- switch_scheduler_task_thread_start();
- switch_nat_late_init();
- switch_rtp_init(runtime.memory_pool);
- runtime.running = 1;
- runtime.initiated = switch_mono_micro_time_now();
- switch_scheduler_add_task(switch_epoch_time_now(NULL), heartbeat_callback, "heartbeat", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL);
- switch_scheduler_add_task(switch_epoch_time_now(NULL), check_ip_callback, "check_ip", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL | SSHF_OWN_THREAD);
- switch_uuid_get(&uuid);
- switch_uuid_format(runtime.uuid_str, &uuid);
- switch_core_set_variable("core_uuid", runtime.uuid_str);
- return SWITCH_STATUS_SUCCESS;
- }
- #ifdef TRAP_BUS
- static void handle_SIGBUS(int sig)
- {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Sig BUS!\n");
- return;
- }
- #endif
- static void handle_SIGHUP(int sig)
- {
- if (sig) {
- switch_event_t *event;
- if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Trapped-Signal", "HUP");
- switch_event_fire(&event);
- }
- }
- return;
- }
- SWITCH_DECLARE(uint32_t) switch_default_ptime(const char *name, uint32_t number)
- {
- uint32_t *p;
- if ((p = switch_core_hash_find(runtime.ptimes, name))) {
- return *p;
- }
- return 20;
- }
- SWITCH_DECLARE(uint32_t) switch_default_rate(const char *name, uint32_t number)
- {
- if (!strcasecmp(name, "opus")) {
- return 48000;
- } else if (!strncasecmp(name, "h26", 3)) { // h26x
- return 90000;
- } else if (!strncasecmp(name, "vp", 2)) { // vp8, vp9
- return 90000;
- }
- return 8000;
- }
- static uint32_t d_30 = 30;
- static void switch_load_core_config(const char *file)
- {
- switch_xml_t xml = NULL, cfg = NULL;
- switch_core_hash_insert(runtime.ptimes, "ilbc", &d_30);
- switch_core_hash_insert(runtime.ptimes, "isac", &d_30);
- switch_core_hash_insert(runtime.ptimes, "G723", &d_30);
- if ((xml = switch_xml_open_cfg(file, &cfg, NULL))) {
- switch_xml_t settings, param;
- if ((settings = switch_xml_child(cfg, "default-ptimes"))) {
- for (param = switch_xml_child(settings, "codec"); param; param = param->next) {
- const char *var = switch_xml_attr_soft(param, "name");
- const char *val = switch_xml_attr_soft(param, "ptime");
- if (!zstr(var) && !zstr(val)) {
- uint32_t *p;
- uint32_t v = switch_atoul(val);
- if (!strcasecmp(var, "G723") || !strcasecmp(var, "iLBC")) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, defaults cannot be changed\n", var);
- continue;
- }
- if (v == 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, invalid ptime\n", var);
- continue;
- }
- p = switch_core_alloc(runtime.memory_pool, sizeof(*p));
- *p = v;
- switch_core_hash_insert(runtime.ptimes, var, p);
- }
- }
- }
- if ((settings = switch_xml_child(cfg, "settings"))) {
- for (param = switch_xml_child(settings, "param"); param; param = param->next) {
- const char *var = switch_xml_attr_soft(param, "name");
- const char *val = switch_xml_attr_soft(param, "value");
- if (!strcasecmp(var, "loglevel")) {
- int level;
- if (*val > 47 && *val < 58) {
- level = atoi(val);
- } else {
- level = switch_log_str2level(val);
- }
- if (level != SWITCH_LOG_INVALID) {
- switch_core_session_ctl(SCSC_LOGLEVEL, &level);
- }
- #ifdef HAVE_SETRLIMIT
- } else if (!strcasecmp(var, "dump-cores") && switch_true(val)) {
- struct rlimit rlp;
- memset(&rlp, 0, sizeof(rlp));
- rlp.rlim_cur = RLIM_INFINITY;
- rlp.rlim_max = RLIM_INFINITY;
- setrlimit(RLIMIT_CORE, &rlp);
- #endif
- } else if (!strcasecmp(var, "debug-level")) {
- int tmp = atoi(val);
- if (tmp > -1 && tmp < 11) {
- switch_core_session_ctl(SCSC_DEBUG_LEVEL, &tmp);
- }
- } else if (!strcasecmp(var, "max-db-handles")) {
- long tmp = atol(val);
- if (tmp > 4 && tmp < 5001) {
- runtime.max_db_handles = (uint32_t) tmp;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "max-db-handles must be between 5 and 5000\n");
- }
- } else if (!strcasecmp(var, "odbc-skip-autocommit-flip")) {
- if (switch_true(val)) {
- switch_odbc_skip_autocommit_flip();
- }
- } else if (!strcasecmp(var, "db-handle-timeout")) {
- long tmp = atol(val);
- if (tmp > 0 && tmp < 5001) {
- runtime.db_handle_timeout = (uint32_t) tmp * 1000000;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "db-handle-timeout must be between 1 and 5000\n");
- }
- } else if (!strcasecmp(var, "event-heartbeat-interval")) {
- long tmp = atol(val);
- if (tmp > 0) {
- runtime.event_heartbeat_interval = (uint32_t) tmp;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "heartbeat-interval must be a greater than 0\n");
- }
- } else if (!strcasecmp(var, "multiple-registrations")) {
- runtime.multiple_registrations = switch_true(val);
- } else if (!strcasecmp(var, "auto-create-schemas")) {
- if (switch_true(val)) {
- switch_set_flag((&runtime), SCF_AUTO_SCHEMAS);
- } else {
- switch_clear_flag((&runtime), SCF_AUTO_SCHEMAS);
- }
- } else if (!strcasecmp(var, "session-thread-pool")) {
- if (switch_true(val)) {
- switch_set_flag((&runtime), SCF_SESSION_THREAD_POOL);
- } else {
- switch_clear_flag((&runtime), SCF_SESSION_THREAD_POOL);
- }
- } else if (!strcasecmp(var, "auto-clear-sql")) {
- if (switch_true(val)) {
- switch_set_flag((&runtime), SCF_CLEAR_SQL);
- } else {
- switch_clear_flag((&runtime), SCF_CLEAR_SQL);
- }
- } else if (!strcasecmp(var, "api-expansion")) {
- if (switch_true(val)) {
- switch_set_flag((&runtime), SCF_API_EXPANSION);
- } else {
- switch_clear_flag((&runtime), SCF_API_EXPANSION);
- }
- } else if (!strcasecmp(var, "enable-early-hangup") && switch_true(val)) {
- switch_set_flag((&runtime), SCF_EARLY_HANGUP);
- } else if (!strcasecmp(var, "colorize-console") && switch_true(val)) {
- runtime.colorize_console = SWITCH_TRUE;
- } else if (!strcasecmp(var, "core-db-pre-trans-execute") && !zstr(val)) {
- runtime.core_db_pre_trans_execute = switch_core_strdup(runtime.memory_pool, val);
- } else if (!strcasecmp(var, "core-db-post-trans-execute") && !zstr(val)) {
- runtime.core_db_post_trans_execute = switch_core_strdup(runtime.memory_pool, val);
- } else if (!strcasecmp(var, "core-db-inner-pre-trans-execute") && !zstr(val)) {
- runtime.core_db_inner_pre_trans_execute = switch_core_strdup(runtime.memory_pool, val);
- } else if (!strcasecmp(var, "core-db-inner-post-trans-execute") && !zstr(val)) {
- runtime.core_db_inner_post_trans_execute = switch_core_strdup(runtime.memory_pool, val);
- } else if (!strcasecmp(var, "dialplan-timestamps")) {
- if (switch_true(val)) {
- switch_set_flag((&runtime), SCF_DIALPLAN_TIMESTAMPS);
- } else {
- switch_clear_flag((&runtime), SCF_DIALPLAN_TIMESTAMPS);
- }
- } else if (!strcasecmp(var, "mailer-app") && !zstr(val)) {
- runtime.mailer_app = switch_core_strdup(runtime.memory_pool, val);
- } else if (!strcasecmp(var, "mailer-app-args") && val) {
- runtime.mailer_app_args = switch_core_strdup(runtime.memory_pool, val);
- } else if (!strcasecmp(var, "sessions-per-second") && !zstr(val)) {
- switch_core_sessions_per_second(atoi(val));
- } else if (!strcasecmp(var, "max-dtmf-duration") && !zstr(val)) {
- int tmp = atoi(val);
- if (tmp > 0) {
- switch_core_max_dtmf_duration((uint32_t) tmp);
- }
- } else if (!strcasecmp(var, "min-dtmf-duration") && !zstr(val)) {
- int tmp = atoi(val);
- if (tmp > 0) {
- switch_core_min_dtmf_duration((uint32_t) tmp);
- }
- } else if (!strcasecmp(var, "default-dtmf-duration") && !zstr(val)) {
- int tmp = atoi(val);
- if (tmp > 0) {
- switch_core_default_dtmf_duration((uint32_t) tmp);
- }
- } else if (!strcasecmp(var, "enable-use-system-time")) {
- switch_time_set_use_system_time(switch_true(val));
- } else if (!strcasecmp(var, "enable-monotonic-timing")) {
- switch_time_set_monotonic(switch_true(val));
- } else if (!strcasecmp(var, "enable-softtimer-timerfd")) {
- int ival = 0;
- if (val) {
- if (switch_true(val)) {
- ival = 2;
- } else {
- if (strcasecmp(val, "broadcast")) {
- ival = 1;
- } else if (strcasecmp(val, "fd-per-timer")) {
- ival = 2;
- }
- }
- }
- switch_time_set_timerfd(ival);
- } else if (!strcasecmp(var, "enable-clock-nanosleep")) {
- switch_time_set_nanosleep(switch_true(val));
- } else if (!strcasecmp(var, "enable-cond-yield")) {
- switch_time_set_cond_yield(switch_true(val));
- } else if (!strcasecmp(var, "enable-timer-matrix")) {
- switch_time_set_matrix(switch_true(val));
- } else if (!strcasecmp(var, "max-sessions") && !zstr(val)) {
- switch_core_session_limit(atoi(val));
- } else if (!strcasecmp(var, "verbose-channel-events") && !zstr(val)) {
- int v = switch_true(val);
- if (v) {
- switch_set_flag((&runtime), SCF_VERBOSE_EVENTS);
- } else {
- switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS);
- }
- } else if (!strcasecmp(var, "threaded-system-exec") && !zstr(val)) {
- #ifdef WIN32
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "threaded-system-exec is not implemented on this platform\n");
- #else
- int v = switch_true(val);
- if (v) {
- switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
- } else {
- switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
- }
- #endif
- } else if (!strcasecmp(var, "spawn-instead-of-system") && !zstr(val)) {
- #ifdef WIN32
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "spawn-instead-of-system is not implemented on this platform\n");
- #else
- int v = switch_true(val);
- if (v) {
- switch_core_set_variable("spawn_instead_of_system", "true");
- } else {
- switch_core_set_variable("spawn_instead_of_system", "false");
- }
- #endif
- } else if (!strcasecmp(var, "exclude-error-log-from-xml-cdr") && !zstr(val)) {
- int v = switch_true(val);
- if (v) {
- switch_core_set_variable("exclude_error_log_from_xml_cdr", "true");
- } else {
- switch_core_set_variable("exclude_error_log_from_xml_cdr", "false");
- }
- } else if (!strcasecmp(var, "min-idle-cpu") && !zstr(val)) {
- switch_core_min_idle_cpu(atof(val));
- } else if (!strcasecmp(var, "tipping-point") && !zstr(val)) {
- runtime.tipping_point = atoi(val);
- } else if (!strcasecmp(var, "cpu-idle-smoothing-depth") && !zstr(val)) {
- runtime.cpu_idle_smoothing_depth = atoi(val);
- } else if (!strcasecmp(var, "events-use-dispatch") && !zstr(val)) {
- runtime.events_use_dispatch = switch_true(val);
- } else if (!strcasecmp(var, "initial-event-threads") && !zstr(val)) {
- int tmp;
- if (!runtime.events_use_dispatch) {
- runtime.events_use_dispatch = 1;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
- "Implicitly setting events-use-dispatch based on usage of this initial-event-threads parameter.\n");
- }
- tmp = atoi(val);
- if (tmp > runtime.cpu_count / 2) {
- tmp = runtime.cpu_count / 2;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be higher than %d so setting it to that value\n",
- runtime.cpu_count / 2);
- }
- if (tmp < 1) {
- tmp = 1;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be lower than 1 so setting it to that level\n");
- }
- switch_event_launch_dispatch_threads(tmp);
- } else if (!strcasecmp(var, "1ms-timer") && switch_true(val)) {
- runtime.microseconds_per_tick = 1000;
- } else if (!strcasecmp(var, "timer-affinity") && !zstr(val)) {
- if (!strcasecmp(val, "disabled")) {
- runtime.timer_affinity = -1;
- } else {
- runtime.timer_affinity = atoi(val);
- }
- } else if (!strcasecmp(var, "ice-resolve-candidate")) {
- switch_core_media_set_resolveice(switch_true(val));
- } else if (!strcasecmp(var, "rtp-start-port") && !zstr(val)) {
- switch_rtp_set_start_port((switch_port_t) atoi(val));
- } else if (!strcasecmp(var, "rtp-end-port") && !zstr(val)) {
- switch_rtp_set_end_port((switch_port_t) atoi(val));
- } else if (!strcasecmp(var, "rtp-port-usage-robustness") && switch_true(val)) {
- runtime.port_alloc_flags |= SPF_ROBUST_UDP;
- } else if (!strcasecmp(var, "core-db-name") && !zstr(val)) {
- runtime.dbname = switch_core_strdup(runtime.memory_pool, val);
- } else if (!strcasecmp(var, "core-db-dsn") && !zstr(val)) {
- runtime.odbc_dsn = switch_core_strdup(runtime.memory_pool, val);
- } else if (!strcasecmp(var, "core-non-sqlite-db-required") && !zstr(val)) {
- switch_set_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ);
- } else if (!strcasecmp(var, "core-dbtype") && !zstr(val)) {
- if (!strcasecmp(val, "MSSQL")) {
- runtime.odbc_dbtype = DBTYPE_MSSQL;
- } else {
- runtime.odbc_dbtype = DBTYPE_DEFAULT;
- }
- } else if (!strcasecmp(var, "switchname") && !zstr(val)) {
- runtime.switchname = switch_core_strdup(runtime.memory_pool, val);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Set switchname to %s\n", runtime.switchname);
- } else if (!strcasecmp(var, "rtp-retain-crypto-keys")) {
- if (switch_true(val)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
- "rtp-retain-crypto-keys enabled. Could be used to decrypt secure media.\n");
- }
- switch_core_set_variable("rtp_retain_crypto_keys", val);
- } else if (!strcasecmp(var, "caller-profile-soft-variables-uses-prefix") && !zstr(val)) {
- int v = switch_true(val);
- if (v) {
- switch_set_flag((&runtime), SCF_CPF_SOFT_PREFIX);
- } else {
- switch_clear_flag((&runtime), SCF_CPF_SOFT_PREFIX);
- }
- } else if (!strcasecmp(var, "caller-profile-soft-lookup-values") && !zstr(val)) {
- int v = switch_true(val);
- if (v) {
- switch_set_flag((&runtime), SCF_CPF_SOFT_LOOKUP);
- } else {
- switch_clear_flag((&runtime), SCF_CPF_SOFT_LOOKUP);
- }
- } else if (!strcasecmp(var, "event-channel-key-separator") && !zstr(val)) {
- runtime.event_channel_key_separator = switch_core_strdup(runtime.memory_pool, val);
- } else if (!strcasecmp(var, "event-channel-enable-hierarchy-deliver") && !zstr(val)) {
- int v = switch_true(val);
- if (v) {
- switch_set_flag((&runtime), SCF_EVENT_CHANNEL_ENABLE_HIERARCHY_DELIVERY);
- } else {
- switch_clear_flag((&runtime), SCF_EVENT_CHANNEL_ENABLE_HIERARCHY_DELIVERY);
- }
- } else if (!strcasecmp(var, "event-channel-hierarchy-deliver-once") && !zstr(val)) {
- int v = switch_true(val);
- if (v) {
- switch_set_flag((&runtime), SCF_EVENT_CHANNEL_HIERARCHY_DELIVERY_ONCE);
- } else {
- switch_clear_flag((&runtime), SCF_EVENT_CHANNEL_HIERARCHY_DELIVERY_ONCE);
- }
- } else if (!strcasecmp(var, "event-channel-log-undeliverable-json") && !zstr(val)) {
- int v = switch_true(val);
- if (v) {
- switch_set_flag((&runtime), SCF_EVENT_CHANNEL_LOG_UNDELIVERABLE_JSON);
- } else {
- switch_clear_flag((&runtime), SCF_EVENT_CHANNEL_LOG_UNDELIVERABLE_JSON);
- }
- } else if (!strcasecmp(var, "max-audio-channels") && !zstr(val)) {
- switch_core_max_audio_channels(atoi(val));
- }
- }
- }
- if (runtime.event_channel_key_separator == NULL) {
- runtime.event_channel_key_separator = switch_core_strdup(runtime.memory_pool, ".");
- }
- if ((settings = switch_xml_child(cfg, "variables"))) {
- for (param = switch_xml_child(settings, "variable"); param; param = param->next) {
- const char *var = switch_xml_attr_soft(param, "name");
- const char *val = switch_xml_attr_soft(param, "value");
- if (var && val) {
- switch_core_set_variable(var, val);
- }
- }
- }
- switch_xml_free(xml);
- }
- }
- SWITCH_DECLARE(const char *) switch_core_banner(void)
- {
- return ("\n"
- ".=============================================================.\n"
- "| _____ ______ _____ _____ ____ _ _ |\n"
- "| | ___| __ ___ ___/ ___\\ \\ / /_ _|_ _/ ___| | | | |\n"
- "| | |_ | '__/ _ \\/ _ \\___ \\\\ \\ /\\ / / | | | || | | |_| | |\n"
- "| | _|| | | __/ __/___) |\\ V V / | | | || |___| _ | |\n"
- "| |_| |_| \\___|\\___|____/ \\_/\\_/ |___| |_| \\____|_| |_| |\n"
- "| |\n"
- ".=============================================================."
- "\n"
- "| Anthony Minessale II, Michael Jerris, Brian West, Others |\n"
- "| FreeSWITCH (http://www.freeswitch.org) |\n"
- "| Paypal Donations Appreciated: paypal@freeswitch.org |\n"
- "| Brought to you by ClueCon http://www.cluecon.com/ |\n"
- ".=============================================================.\n"
- "\n");
- }
- switch_status_t switch_core_sqldb_init(const char **err)
- {
- if (switch_core_check_core_db_dsn() != SWITCH_STATUS_SUCCESS) {
- *err = "NO SUITABLE DATABASE INTERFACE IS AVAILABLE TO SERVE 'core-db-dsn'!\n";
- return SWITCH_STATUS_GENERR;
- }
- if (switch_core_sqldb_start(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_SQL) ? SWITCH_TRUE : SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) {
- *err = "Error activating database";
- return SWITCH_STATUS_GENERR;
- }
- return SWITCH_STATUS_SUCCESS;
- }
- SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t flags, switch_bool_t console, const char **err)
- {
- switch_event_t *event;
- char *cmd;
- int x = 0;
- const char *use = NULL;
- #include "cc.h"
- if (switch_core_init(flags, console, err) != SWITCH_STATUS_SUCCESS) {
- return SWITCH_STATUS_GENERR;
- }
- if (runtime.runlevel > 1) {
- /* one per customer */
- return SWITCH_STATUS_SUCCESS;
- }
- runtime.runlevel++;
- runtime.events_use_dispatch = 1;
- switch_core_set_signal_handlers();
- switch_load_network_lists(SWITCH_FALSE);
- switch_msrp_init();
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bringing up environment.\n");
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Loading Modules.\n");
- if (switch_loadable_module_init(SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
- *err = "Cannot load modules";
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Error: %s\n", *err);
- return SWITCH_STATUS_GENERR;
- }
- switch_load_network_lists(SWITCH_FALSE);
- switch_load_core_config("post_load_switch.conf");
- switch_core_set_signal_handlers();
- if (switch_event_create(&event, SWITCH_EVENT_STARTUP) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready");
- switch_event_fire(&event);
- }
- switch_core_screen_size(&x, NULL);
- use = (x > 100) ? cc : cc_s;
- #ifdef WIN32
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s\n\n", switch_core_banner(), use);
- #else
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s%s%s%s%s\n\n",
- SWITCH_SEQ_DEFAULT_COLOR,
- SWITCH_SEQ_FYELLOW, SWITCH_SEQ_BBLUE,
- switch_core_banner(),
- use, SWITCH_SEQ_DEFAULT_COLOR);
- #endif
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
- "\nFreeSWITCH Version %s (%s)\n\nFreeSWITCH Started\nMax Sessions [%u]\nSession Rate [%d]\nSQL [%s]\n",
- switch_version_full(), switch_version_revision_human(),
- switch_core_session_limit(0),
- switch_core_sessions_per_second(0), switch_test_flag((&runtime), SCF_USE_SQL) ? "Enabled" : "Disabled");
- if (x < 160) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\n[This app Best viewed at 160x60 or more..]\n");
- }
- switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS);
- if ((cmd = switch_core_get_variable_dup("api_on_startup"))) {
- switch_stream_handle_t stream = { 0 };
- SWITCH_STANDARD_STREAM(stream);
- switch_console_execute(cmd, 0, &stream);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Startup command [%s] executed. Output:\n%s\n", cmd, (char *)stream.data);
- free(stream.data);
- free(cmd);
- }
- #ifdef HAVE_SYSTEMD
- sd_notifyf(0, "READY=1\n"
- "MAINPID=%lu\n", (unsigned long) getpid());
- #endif
- return SWITCH_STATUS_SUCCESS;
- }
- SWITCH_DECLARE(void) switch_core_measure_time(switch_time_t total_ms, switch_core_time_duration_t *duration)
- {
- switch_time_t temp = total_ms / 1000;
- memset(duration, 0, sizeof(*duration));
- duration->mms = (uint32_t) (total_ms % 1000);
- duration->ms = (uint32_t) (temp % 1000);
- temp = temp / 1000;
- duration->sec = (uint32_t) (temp % 60);
- temp = temp / 60;
- duration->min = (uint32_t) (temp % 60);
- temp = temp / 60;
- duration->hr = (uint32_t) (temp % 24);
- temp = temp / 24;
- duration->day = (uint32_t) (temp % 365);
- duration->yr = (uint32_t) (temp / 365);
- }
- SWITCH_DECLARE(switch_time_t) switch_core_uptime(void)
- {
- return switch_mono_micro_time_now() - runtime.initiated;
- }
- #ifdef _MSC_VER
- static void win_shutdown(void)
- {
- HANDLE shutdown_event;
- char path[512];
- /* for windows we need the event to signal for shutting down a background FreeSWITCH */
- snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid());
- /* open the event so we can signal it */
- shutdown_event = OpenEvent(EVENT_MODIFY_STATE, FALSE, path);
- if (shutdown_event) {
- /* signal the event to shutdown */
- SetEvent(shutdown_event);
- /* cleanup */
- CloseHandle(shutdown_event);
- }
- }
- #endif
- SWITCH_DECLARE(void) switch_core_set_signal_handlers(void)
- {
- /* set signal handlers */
- signal(SIGINT, SIG_IGN);
- #ifdef SIGPIPE
- signal(SIGPIPE, SIG_IGN);
- #endif
- #ifdef SIGALRM
- signal(SIGALRM, SIG_IGN);
- #endif
- #ifdef SIGQUIT
- signal(SIGQUIT, SIG_IGN);
- #endif
- #ifdef SIGPOLL
- signal(SIGPOLL, SIG_IGN);
- #endif
- #ifdef SIGIO
- signal(SIGIO, SIG_IGN);
- #endif
- #ifdef TRAP_BUS
- signal(SIGBUS, handle_SIGBUS);
- #endif
- #ifdef SIGUSR1
- signal(SIGUSR1, handle_SIGHUP);
- #endif
- signal(SIGHUP, handle_SIGHUP);
- }
- SWITCH_DECLARE(uint32_t) switch_core_debug_level(void)
- {
- return runtime.debug_level;
- }
- SWITCH_DECLARE(int32_t) switch_core_sps(void)
- {
- return runtime.sps;
- }
- SWITCH_DECLARE(int32_t) switch_core_sps_last(void)
- {
- return runtime.sps_last;
- }
- SWITCH_DECLARE(int32_t) switch_core_sps_peak(void)
- {
- return runtime.sps_peak;
- }
- SWITCH_DECLARE(int32_t) switch_core_sps_peak_fivemin(void)
- {
- return runtime.sps_peak_fivemin;
- }
- SWITCH_DECLARE(int32_t) switch_core_sessions_peak(void)
- {
- return runtime.sessions_peak;
- }
- SWITCH_DECLARE(int32_t) switch_core_sessions_peak_fivemin(void)
- {
- return runtime.sessions_peak_fivemin;
- }
- SWITCH_DECLARE(uint32_t) switch_core_max_audio_channels(uint32_t limit)
- {
- if (limit) {
- runtime.max_audio_channels = limit;
- }
- return runtime.max_audio_channels;
- }
- SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void *val)
- {
- int *intval = (int *) val;
- int oldintval = 0, newintval = 0;
- if (intval) {
- oldintval = *intval;
- }
- if (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)) {
- return -1;
- }
- switch (cmd) {
- case SCSC_RECOVER:
- {
- char *arg = (char *) val;
- char *tech = NULL, *prof = NULL;
- int r, flush = 0;
- if (!zstr(arg)) {
- tech = strdup(arg);
- switch_assert(tech);
- if ((prof = strchr(tech, ':'))) {
- *prof++ = '\0';
- }
- if (!strcasecmp(tech, "flush")) {
- flush++;
- if (prof) {
- char *tech = prof;
- if ((prof = strchr(tech, ':'))) {
- *prof++ = '\0';
- }
- }
- }
- }
- if (flush) {
- switch_core_recovery_flush(tech, prof);
- r = -1;
- } else {
- r = switch_core_recovery_recover(tech, prof);
- }
- switch_safe_free(tech);
- return r;
- }
- break;
- case SCSC_DEBUG_SQL:
- {
- if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) {
- switch_clear_flag((&runtime), SCF_DEBUG_SQL);
- newintval = 0;
- } else {
- switch_set_flag((&runtime), SCF_DEBUG_SQL);
- newintval = 1;
- }
- }
- break;
- case SCSC_VERBOSE_EVENTS:
- if (intval) {
- if (oldintval > -1) {
- if (oldintval) {
- switch_set_flag((&runtime), SCF_VERBOSE_EVENTS);
- } else {
- switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS);
- }
- }
- newintval = switch_test_flag((&runtime), SCF_VERBOSE_EVENTS);
- }
- break;
- case SCSC_API_EXPANSION:
- if (intval) {
- if (oldintval > -1) {
- if (oldintval) {
- switch_set_flag((&runtime), SCF_API_EXPANSION);
- } else {
- switch_clear_flag((&runtime), SCF_API_EXPANSION);
- }
- }
- newintval = switch_test_flag((&runtime), SCF_API_EXPANSION);
- }
- break;
- case SCSC_THREADED_SYSTEM_EXEC:
- if (intval) {
- if (oldintval > -1) {
- if (oldintval) {
- switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
- } else {
- switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
- }
- }
- newintval = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
- }
- break;
- case SCSC_CALIBRATE_CLOCK:
- switch_time_calibrate_clock();
- break;
- case SCSC_FLUSH_DB_HANDLES:
- switch_cache_db_flush_handles();
- break;
- case SCSC_SEND_SIGHUP:
- handle_SIGHUP(1);
- break;
- case SCSC_SYNC_CLOCK:
- switch_time_sync();
- newintval = 0;
- break;
- case SCSC_SYNC_CLOCK_WHEN_IDLE:
- newintval = switch_core_session_sync_clock();
- break;
- case SCSC_SQL:
- if (oldintval) {
- switch_core_sqldb_resume();
- } else {
- switch_core_sqldb_pause();
- }
- break;
- case SCSC_PAUSE_ALL:
- if (oldintval) {
- switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
- } else {
- switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS);
- }
- break;
- case SCSC_PAUSE_INBOUND:
- if (oldintval) {
- switch_set_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS);
- } else {
- switch_clear_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS);
- }
- break;
- case SCSC_PAUSE_OUTBOUND:
- if (oldintval) {
- switch_set_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS);
- } else {
- switch_clear_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS);
- }
- break;
- case SCSC_HUPALL:
- switch_core_session_hupall(SWITCH_CAUSE_MANAGER_REQUEST);
- break;
- case SCSC_CANCEL_SHUTDOWN:
- switch_clear_flag((&runtime), SCF_SHUTDOWN_REQUESTED);
- break;
- case SCSC_SAVE_HISTORY:
- switch_console_save_history();
- break;
- case SCSC_CRASH:
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Declinatio Mortuus Obfirmo!\n");
- switch_console_save_history();
- abort();
- break;
- case SCSC_SHUTDOWN_NOW:
- switch_console_save_history();
- exit(0);
- break;
- case SCSC_REINCARNATE_NOW:
- switch_console_save_history();
- exit(SWITCH_STATUS_RESTART);
- break;
- case SCSC_SHUTDOWN_ELEGANT:
- case SCSC_SHUTDOWN_ASAP:
- {
- int x = 19;
- uint32_t count;
- switch_event_t *shutdown_requested_event = NULL;
- if (switch_event_create(&shutdown_requested_event, SWITCH_EVENT_SHUTDOWN_REQUESTED) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(shutdown_requested_event, SWITCH_STACK_BOTTOM, "Event-Info", "%s", cmd == SCSC_SHUTDOWN_ASAP ? "ASAP" : "elegant");
- switch_event_fire(&shutdown_requested_event);
- }
- switch_set_flag((&runtime), SCF_SHUTDOWN_REQUESTED);
- if (cmd == SCSC_SHUTDOWN_ASAP) {
- switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
- }
- while (runtime.running && switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED) && (count = switch_core_session_count())) {
- switch_yield(500000);
- if (++x == 20) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
- "Shutdown in progress, %u session(s) remain.\nShutting down %s\n",
- count, cmd == SCSC_SHUTDOWN_ASAP ? "ASAP" : "once there are no active calls.");
- x = 0;
- }
- }
- if (switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED)) {
- switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
- #ifdef _MSC_VER
- win_shutdown();
- #endif
- if (oldintval) {
- switch_set_flag((&runtime), SCF_RESTART);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n");
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n");
- #ifdef HAVE_SYSTEMD
- sd_notifyf(0, "STOPPING=1\n");
- #endif
- #ifdef _MSC_VER
- fclose(stdin);
- #endif
- }
- runtime.running = 0;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutdown Cancelled\n");
- switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS);
- }
- }
- break;
- case SCSC_PAUSE_CHECK:
- newintval = !!(switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS);
- break;
- case SCSC_PAUSE_INBOUND_CHECK:
- newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS);
- break;
- case SCSC_PAUSE_OUTBOUND_CHECK:
- newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS);
- break;
- case SCSC_READY_CHECK:
- newintval = switch_core_ready();
- break;
- case SCSC_SHUTDOWN_CHECK:
- newintval = !!switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED);
- break;
- case SCSC_SHUTDOWN:
- #ifdef _MSC_VER
- win_shutdown();
- #endif
- if (oldintval) {
- switch_set_flag((&runtime), SCF_RESTART);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n");
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n");
- #ifdef _MSC_VER
- fclose(stdin);
- #endif
- }
- runtime.running = 0;
- break;
- case SCSC_CHECK_RUNNING:
- newintval = runtime.running;
- break;
- case SCSC_LOGLEVEL:
- if (oldintval >= SWITCH_LOG_DISABLE) {
- runtime.hard_log_level = oldintval;
- }
- if (runtime.hard_log_level > SWITCH_LOG_DEBUG) {
- runtime.hard_log_level = SWITCH_LOG_DEBUG;
- }
- newintval = runtime.hard_log_level;
- break;
- case SCSC_DEBUG_LEVEL:
- if (oldintval > -1) {
- if (oldintval > 10)
- oldintval = 10;
- runtime.debug_level = oldintval;
- }
- newintval = runtime.debug_level;
- break;
- case SCSC_MIN_IDLE_CPU:
- {
- double *dval = (double *) val;
- if (dval) {
- *dval = switch_core_min_idle_cpu(*dval);
- }
- intval = NULL;
- }
- break;
- case SCSC_MAX_SESSIONS:
- newintval = switch_core_session_limit(oldintval);
- break;
- case SCSC_LAST_SPS:
- newintval = runtime.sps_last;
- break;
- case SCSC_SPS_PEAK:
- if (oldintval == -1) {
- runtime.sps_peak = 0;
- }
- newintval = runtime.sps_peak;
- break;
- case SCSC_SPS_PEAK_FIVEMIN:
- newintval = runtime.sps_peak_fivemin;
- break;
- case SCSC_SESSIONS_PEAK:
- newintval = runtime.sessions_peak;
- break;
- case SCSC_SESSIONS_PEAK_FIVEMIN:
- newintval = runtime.sessions_peak_fivemin;
- break;
- case SCSC_MAX_DTMF_DURATION:
- newintval = switch_core_max_dtmf_duration(oldintval);
- break;
- case SCSC_MIN_DTMF_DURATION:
- newintval = switch_core_min_dtmf_duration(oldintval);
- break;
- case SCSC_DEFAULT_DTMF_DURATION:
- newintval = switch_core_default_dtmf_duration(oldintval);
- break;
- case SCSC_SPS:
- switch_mutex_lock(runtime.throttle_mutex);
- if (oldintval > 0) {
- runtime.sps_total = oldintval;
- }
- newintval = runtime.sps_total;
- switch_mutex_unlock(runtime.throttle_mutex);
- break;
- case SCSC_RECLAIM:
- switch_core_memory_reclaim_all();
- newintval = 0;
- break;
- case SCSC_MDNS_RESOLVE:
- switch_core_media_set_resolveice(!!oldintval);
- break;
- case SCSC_SHUTDOWN_CAUSE:
- runtime.shutdown_cause = oldintval;
- break;
- }
- if (intval) {
- *intval = newintval;
- }
- return 0;
- }
- SWITCH_DECLARE(switch_core_flag_t) switch_core_flags(void)
- {
- return runtime.flags;
- }
- SWITCH_DECLARE(switch_bool_t) switch_core_running(void)
- {
- return runtime.running ? SWITCH_TRUE : SWITCH_FALSE;
- }
- SWITCH_DECLARE(switch_bool_t) switch_core_ready(void)
- {
- return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS) ? SWITCH_FALSE : SWITCH_TRUE;
- }
- SWITCH_DECLARE(switch_bool_t) switch_core_ready_inbound(void)
- {
- return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE;
- }
- SWITCH_DECLARE(switch_bool_t) switch_core_ready_outbound(void)
- {
- return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE;
- }
- void switch_core_sqldb_destroy(void)
- {
- if (switch_test_flag((&runtime), SCF_USE_SQL)) {
- switch_core_sqldb_stop();
- }
- }
- SWITCH_DECLARE(switch_status_t) switch_core_destroy(void)
- {
- switch_event_t *event;
- if (switch_event_create(&event, SWITCH_EVENT_SHUTDOWN) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Shutting Down");
- switch_event_fire(&event);
- }
- switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
- switch_set_flag((&runtime), SCF_SHUTTING_DOWN);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "End existing sessions\n");
- switch_core_session_hupall(runtime.shutdown_cause);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clean up modules.\n");
- switch_loadable_module_shutdown();
- switch_curl_destroy();
- switch_ssl_destroy_ssl_locks();
- EVP_cleanup();
- switch_scheduler_task_thread_stop();
- switch_rtp_shutdown();
- switch_msrp_destroy();
- if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) {
- switch_nat_shutdown();
- }
- switch_xml_destroy();
- switch_console_shutdown();
- switch_channel_global_uninit();
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Closing Event Engine.\n");
- switch_event_shutdown();
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Finalizing Shutdown.\n");
- switch_log_shutdown();
- switch_core_session_uninit();
- switch_core_unset_variables();
- switch_core_memory_stop();
- if (runtime.console && runtime.console != stdout && runtime.console != stderr) {
- fclose(runtime.console);
- runtime.console = NULL;
- }
- switch_safe_free(SWITCH_GLOBAL_dirs.base_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.log_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.db_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.script_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.htdocs_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.grammar_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.fonts_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.images_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.storage_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.cache_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.recordings_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.sounds_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.run_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.temp_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.data_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.localstate_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.certs_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.lib_dir);
- switch_safe_free(SWITCH_GLOBAL_filenames.conf_name);
- switch_event_destroy(&runtime.global_vars);
- switch_core_hash_destroy(&runtime.ptimes);
- switch_core_hash_destroy(&runtime.mime_types);
- switch_core_hash_destroy(&runtime.mime_type_exts);
- if (IP_LIST.hash) {
- switch_core_hash_destroy(&IP_LIST.hash);
- }
- if (IP_LIST.pool) {
- switch_core_destroy_memory_pool(&IP_LIST.pool);
- }
- switch_core_media_deinit();
- if (runtime.memory_pool) {
- fspr_pool_destroy(runtime.memory_pool);
- fspr_terminate();
- }
- sqlite3_shutdown();
- return switch_test_flag((&runtime), SCF_RESTART) ? SWITCH_STATUS_RESTART : SWITCH_STATUS_SUCCESS;
- }
- SWITCH_DECLARE(switch_status_t) switch_core_management_exec(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen)
- {
- const switch_management_interface_t *ptr;
- switch_status_t status = SWITCH_STATUS_FALSE;
- if ((ptr = switch_loadable_module_get_management_interface(relative_oid))) {
- status = ptr->management_function(relative_oid, action, data, datalen);
- }
- return status;
- }
- SWITCH_DECLARE(void) switch_core_memory_reclaim_all(void)
- {
- switch_core_memory_reclaim_logger();
- switch_core_memory_reclaim_events();
- switch_core_memory_reclaim();
- }
- struct system_thread_handle {
- const char *cmd;
- switch_thread_cond_t *cond;
- switch_mutex_t *mutex;
- switch_memory_pool_t *pool;
- int ret;
- int *fds;
- };
- static void *SWITCH_THREAD_FUNC system_thread(switch_thread_t *thread, void *obj)
- {
- struct system_thread_handle *sth = (struct system_thread_handle *) obj;
- #if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__)
- struct rlimit rlim;
- struct rlimit rlim_save;
- memset(&rlim, 0, sizeof(rlim));
- getrlimit(RLIMIT_STACK, &rlim);
- memset(&rlim_save, 0, sizeof(rlim_save));
- getrlimit(RLIMIT_STACK, &rlim_save);
- rlim.rlim_cur = rlim.rlim_max;
- if (setrlimit(RLIMIT_STACK, &rlim) < 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno));
- }
- #endif
- if (sth->fds) {
- dup2(sth->fds[1], STDOUT_FILENO);
- }
- sth->ret = system(sth->cmd);
- #if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__)
- if (setrlimit(RLIMIT_STACK, &rlim_save) < 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno));
- }
- #endif
- switch_mutex_lock(sth->mutex);
- switch_thread_cond_signal(sth->cond);
- switch_mutex_unlock(sth->mutex);
- switch_core_destroy_memory_pool(&sth->pool);
- return NULL;
- }
- static int switch_system_thread(const char *cmd, switch_bool_t wait)
- {
- switch_thread_t *thread;
- switch_threadattr_t *thd_attr;
- int ret = 0;
- struct system_thread_handle *sth;
- switch_memory_pool_t *pool;
- if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n");
- return 1;
- }
- if (!(sth = switch_core_alloc(pool, sizeof(struct system_thread_handle)))) {
- switch_core_destroy_memory_pool(&pool);
- return 1;
- }
- sth->pool = pool;
- sth->cmd = switch_core_strdup(pool, cmd);
- switch_thread_cond_create(&sth->cond, sth->pool);
- switch_mutex_init(&sth->mutex, SWITCH_MUTEX_NESTED, sth->pool);
- switch_mutex_lock(sth->mutex);
- switch_threadattr_create(&thd_attr, sth->pool);
- switch_threadattr_stacksize_set(thd_attr, SWITCH_SYSTEM_THREAD_STACKSIZE);
- switch_threadattr_detach_set(thd_attr, 1);
- switch_thread_create(&thread, thd_attr, system_thread, sth, sth->pool);
- if (wait) {
- switch_thread_cond_wait(sth->cond, sth->mutex);
- ret = sth->ret;
- }
- switch_mutex_unlock(sth->mutex);
- return ret;
- }
- SWITCH_DECLARE(int) switch_max_file_desc(void)
- {
- int max = 0;
- #ifndef WIN32
- #if defined(HAVE_GETDTABLESIZE)
- max = getdtablesize();
- #else
- max = sysconf(_SC_OPEN_MAX);
- #endif
- #endif
- return max;
- }
- SWITCH_DECLARE(void) switch_close_extra_files(int *keep, int keep_ttl)
- {
- int open_max = switch_max_file_desc();
- int i, j;
- for (i = 3; i < open_max; i++) {
- if (keep) {
- for (j = 0; j < keep_ttl; j++) {
- if (i == keep[j]) {
- goto skip;
- }
- }
- }
- close(i);
- skip:
- continue;
- }
- }
- #ifdef WIN32
- static int switch_system_fork(const char *cmd, switch_bool_t wait)
- {
- return switch_system_thread(cmd, wait);
- }
- SWITCH_DECLARE(pid_t) switch_fork(void)
- {
- return -1;
- }
- #else
- SWITCH_DECLARE(pid_t) switch_fork(void)
- {
- int i = fork();
- if (!i) {
- set_low_priority();
- }
- return i;
- }
- static int switch_system_fork(const char *cmd, switch_bool_t wait)
- {
- int pid;
- char *dcmd = strdup(cmd);
- #if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__)
- struct rlimit rlim;
- struct rlimit rlim_save;
- #endif
- switch_core_set_signal_handlers();
- pid = switch_fork();
- if (pid) {
- if (wait) {
- waitpid(pid, NULL, 0);
- }
- free(dcmd);
- } else {
- switch_close_extra_files(NULL, 0);
- #if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__)
- memset(&rlim, 0, sizeof(rlim));
- getrlimit(RLIMIT_STACK, &rlim);
- memset(&rlim_save, 0, sizeof(rlim_save));
- getrlimit(RLIMIT_STACK, &rlim_save);
- rlim.rlim_cur = rlim.rlim_max;
- if (setrlimit(RLIMIT_STACK, &rlim) < 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno));
- }
- #endif
- if (system(dcmd) == -1) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to execute because of a command error : %s\n", dcmd);
- }
- free(dcmd);
- exit(0);
- }
- return 0;
- }
- #endif
- SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait)
- {
- int retval = 0;
- #ifdef __linux__
- switch_bool_t spawn_instead_of_system = switch_true(switch_core_get_variable("spawn_instead_of_system"));
- #else
- switch_bool_t spawn_instead_of_system = SWITCH_FALSE;
- #endif
-
- if (spawn_instead_of_system) {
- retval = switch_stream_spawn(cmd, SWITCH_TRUE, wait, NULL);
- } else if (switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC)) {
- retval = switch_system_thread(cmd, wait);
- } else {
- retval = switch_system_fork(cmd, wait);
- }
- return retval;
- }
- SWITCH_DECLARE(int) switch_stream_system_fork(const char *cmd, switch_stream_handle_t *stream)
- {
- return switch_stream_system(cmd, stream);
- }
- #ifdef __linux__
- extern char **environ;
- #endif
- SWITCH_DECLARE(int) switch_stream_spawn(const char *cmd, switch_bool_t shell, switch_bool_t wait, switch_stream_handle_t *stream)
- {
- #ifndef __linux__
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "posix_spawn is unsupported on current platform\n");
- return 1;
- #else
- int status = 0;
- char buffer[1024];
- pid_t pid;
- char *pdata = NULL, *argv[64];
- posix_spawn_file_actions_t action;
- posix_spawnattr_t *attr;
- int cout_pipe[2];
- int cerr_pipe[2];
- struct pollfd pfds[2] = { {0} };
- if (zstr(cmd)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to execute switch_spawn_stream because of empty command\n");
- return 1;
- }
- if (shell) {
- argv[0] = switch_core_get_variable("spawn_system_shell");
- argv[1] = "-c";
- argv[2] = (char *)cmd;
- argv[3] = NULL;
- if (zstr(argv[0])) {
- argv[0] = "/bin/sh";
- }
- } else {
- if (!(pdata = strdup(cmd))) {
- return 1;
- }
- if (!switch_separate_string(pdata, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) {
- free(pdata);
- return 1;
- }
- }
- if (!(attr = malloc(sizeof(posix_spawnattr_t)))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to execute switch_spawn_stream because of a memory error: %s\n", cmd);
- switch_safe_free(pdata);
- return 1;
- }
- if (stream) {
- if (pipe(cout_pipe)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to execute switch_spawn_stream because of a pipe error: %s\n", cmd);
- free(attr);
- switch_safe_free(pdata);
- return 1;
- }
- if (pipe(cerr_pipe)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to execute switch_spawn_stream because of a pipe error: %s\n", cmd);
- close(cout_pipe[0]);
- close(cout_pipe[1]);
- free(attr);
- switch_safe_free(pdata);
- return 1;
- }
- }
- memset(attr, 0, sizeof(posix_spawnattr_t));
- posix_spawnattr_init(attr);
- posix_spawnattr_setflags(attr, POSIX_SPAWN_USEVFORK);
- posix_spawn_file_actions_init(&action);
- if (stream) {
- posix_spawn_file_actions_addclose(&action, cout_pipe[0]);
- posix_spawn_file_actions_addclose(&action, cerr_pipe[0]);
- posix_spawn_file_actions_adddup2(&action, cout_pipe[1], 1);
- posix_spawn_file_actions_adddup2(&action, cerr_pipe[1], 2);
- posix_spawn_file_actions_addclose(&action, cout_pipe[1]);
- posix_spawn_file_actions_addclose(&action, cerr_pipe[1]);
- }
- if (posix_spawnp(&pid, argv[0], &action, attr, argv, environ) != 0) {
- status = 1;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to execute posix_spawnp: %s\n", cmd);
- if (stream) {
- close(cout_pipe[0]), close(cerr_pipe[0]);
- close(cout_pipe[1]), close(cerr_pipe[1]);
- }
- } else {
- if (stream) {
- close(cout_pipe[1]), close(cerr_pipe[1]); /* close child-side of pipes */
- pfds[0] = (struct pollfd) {
- .fd = cout_pipe[0],
- .events = POLLIN,
- .revents = 0
- };
- pfds[1] = (struct pollfd) {
- .fd = cerr_pipe[0],
- .events = POLLIN,
- .revents = 0
- };
- while (poll(pfds, 2, /*timeout*/-1) > 0) {
- if (pfds[0].revents & POLLIN) {
- int bytes_read = read(cout_pipe[0], buffer, sizeof(buffer));
- stream->raw_write_function(stream, (unsigned char *)buffer, bytes_read);
- } else if (pfds[1].revents & POLLIN) {
- int bytes_read = read(cerr_pipe[0], buffer, sizeof(buffer));
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "STDERR of cmd (%s): %.*s\n", cmd, bytes_read, buffer);
- } else {
- break; /* nothing left to read */
- }
- }
- close(cout_pipe[0]), close(cerr_pipe[0]);
- }
- if (wait) {
- if (waitpid(pid, &status, 0) != pid) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "waitpid failed: %s\n", cmd);
- } else if (status != 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Exit status (%d): %s\n", status, cmd);
- }
- }
- }
- posix_spawnattr_destroy(attr);
- free(attr);
- posix_spawn_file_actions_destroy(&action);
- switch_safe_free(pdata);
- return status;
- #endif
- }
- SWITCH_DECLARE(int) switch_spawn(const char *cmd, switch_bool_t wait)
- {
- return switch_stream_spawn(cmd, SWITCH_FALSE, wait, NULL);
- }
- SWITCH_DECLARE(switch_status_t) switch_core_get_stacksizes(switch_size_t *cur, switch_size_t *max)
- {
- #ifdef HAVE_SETRLIMIT
- struct rlimit rlp;
- memset(&rlp, 0, sizeof(rlp));
- getrlimit(RLIMIT_STACK, &rlp);
- *cur = rlp.rlim_cur;
- *max = rlp.rlim_max;
- return SWITCH_STATUS_SUCCESS;
- #else
- return SWITCH_STATUS_FALSE;
- #endif
- }
- SWITCH_DECLARE(int) switch_stream_system(const char *cmd, switch_stream_handle_t *stream)
- {
- #ifdef __linux__
- switch_bool_t spawn_instead_of_system = switch_true(switch_core_get_variable("spawn_instead_of_system"));
- #else
- switch_bool_t spawn_instead_of_system = SWITCH_FALSE;
- #endif
- if (spawn_instead_of_system){
- return switch_stream_spawn(cmd, SWITCH_TRUE, SWITCH_TRUE, stream);
- } else {
- char buffer[128];
- size_t bytes;
- FILE* pipe = popen(cmd, "r");
- if (!pipe) return 1;
- while (!feof(pipe)) {
- while ((bytes = fread(buffer, 1, 128, pipe)) > 0) {
- if (stream != NULL) {
- stream->raw_write_function(stream, (unsigned char *)buffer, bytes);
- }
- }
- }
- if (ferror(pipe)) {
- pclose(pipe);
- return 1;
- }
- pclose(pipe);
- return 0;
- }
- }
- SWITCH_DECLARE(uint16_t) switch_core_get_rtp_port_range_start_port(void)
- {
- uint16_t start_port = 0;
- /* By default pass rtp port range start value as zero in order to get actual
- * RTP port range start value as configured */
- start_port = (uint16_t)switch_rtp_set_start_port((switch_port_t)start_port);
- return start_port;
- }
- SWITCH_DECLARE(uint16_t) switch_core_get_rtp_port_range_end_port(void)
- {
- uint16_t end_port = 0;
- /* By default pass rtp port range end value as zero in order to get actual
- * RTP port range end value as configured */
- end_port = (uint16_t)switch_rtp_set_end_port((switch_port_t)end_port);
- return end_port;
- }
- SWITCH_DECLARE(const char *) switch_core_get_event_channel_key_separator(void)
- {
- return runtime.event_channel_key_separator;
- }
- /* For Emacs:
- * Local Variables:
- * mode:c
- * indent-tabs-mode:t
- * tab-width:4
- * c-basic-offset:4
- * End:
- * For VIM:
- * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
- */
|