asterisk.c 119 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2014, Digium, Inc.
  5. *
  6. * Mark Spencer <markster@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /* Doxygenified Copyright Header */
  19. /*!
  20. * \mainpage Asterisk -- The Open Source Telephony Project
  21. *
  22. * \par Welcome
  23. *
  24. * This documentation created by the Doxygen project clearly explains the
  25. * internals of the Asterisk software. This documentation contains basic
  26. * examples, developer documentation, support information, and information
  27. * for upgrading.
  28. *
  29. * \section community Community
  30. * Asterisk is a big project and has a busy community. Look at the
  31. * resources for questions and stick around to help answer questions.
  32. * \li \ref asterisk_community_resources
  33. *
  34. * \par Developer Documentation for Asterisk
  35. *
  36. * This is the main developer documentation for Asterisk. It is
  37. * generated by running "make progdocs" from the Asterisk source tree.
  38. *
  39. * In addition to the information available on the Asterisk source code,
  40. * please see the appendices for information on coding guidelines,
  41. * release management, commit policies, and more.
  42. *
  43. * \arg \ref AsteriskArchitecture
  44. *
  45. * \par Additional documentation
  46. * \arg \ref Licensing
  47. * \arg \ref DevDoc
  48. * \arg \ref configuration_file
  49. * \arg \ref channel_drivers
  50. * \arg \ref applications
  51. *
  52. * \section copyright Copyright and Author
  53. *
  54. * Copyright (C) 1999 - 2014, Digium, Inc.
  55. * Asterisk is a <a href="http://www.digium.com/en/company/view-policy.php?id=Trademark-Policy">registered trademark</a>
  56. * of <a rel="nofollow" href="http://www.digium.com">Digium, Inc</a>.
  57. *
  58. * \author Mark Spencer <markster@digium.com>
  59. *
  60. * See http://www.asterisk.org for more information about
  61. * the Asterisk project. Please do not directly contact
  62. * any of the maintainers of this project for assistance;
  63. * the project provides a web site, mailing lists, and IRC
  64. * channels for your use.
  65. *
  66. */
  67. /*!
  68. * \page asterisk_community_resources Asterisk Community Resources
  69. * \par Websites
  70. * \li http://www.asterisk.org Asterisk Homepage
  71. * \li http://wiki.asterisk.org Asterisk Wiki
  72. *
  73. * \par Mailing Lists
  74. * \par
  75. * All lists: http://lists.digium.com/mailman/listinfo
  76. * \li aadk-commits SVN commits to the AADK repository
  77. * \li asterisk-addons-commits SVN commits to the Asterisk addons project
  78. * \li asterisk-announce [no description available]
  79. * \li asterisk-biz Commercial and Business-Oriented Asterisk Discussion
  80. * \li Asterisk-BSD Asterisk on BSD discussion
  81. * \li asterisk-bugs [no description available]
  82. * \li asterisk-commits SVN commits to the Asterisk project
  83. * \li asterisk-dev Asterisk Developers Mailing List
  84. * \li asterisk-doc Discussions regarding The Asterisk Documentation Project
  85. * \li asterisk-embedded Asterisk Embedded Development
  86. * \li asterisk-gui Asterisk GUI project discussion
  87. * \li asterisk-gui-commits SVN commits to the Asterisk-GUI project
  88. * \li asterisk-ha-clustering Asterisk High Availability and Clustering List - Non-Commercial Discussion
  89. * \li Asterisk-i18n Discussion of Asterisk internationalization
  90. * \li asterisk-r2 [no description available]
  91. * \li asterisk-scf-commits Commits to the Asterisk SCF project code repositories
  92. * \li asterisk-scf-committee Asterisk SCF Steering Committee discussions
  93. * \li asterisk-scf-dev Asterisk SCF Developers Mailing List
  94. * \li asterisk-scf-wiki-changes Changes to the Asterisk SCF space on wiki.asterisk.org
  95. * \li asterisk-security Asterisk Security Discussion
  96. * \li asterisk-speech-rec Use of speech recognition in Asterisk
  97. * \li asterisk-ss7 [no description available]
  98. * \li asterisk-users Asterisk Users Mailing List - Non-Commercial Discussion
  99. * \li asterisk-video Development discussion of video media support in Asterisk
  100. * \li asterisk-wiki-changes Changes to the Asterisk space on wiki.asterisk.org
  101. * \li asterisknow AsteriskNOW Discussion
  102. * \li dahdi-commits SVN commits to the DAHDI project
  103. * \li digium-announce Digium Product Announcements
  104. * \li Dundi Distributed Universal Number Discovery
  105. * \li libiax2-commits SVN commits to the libiax2 project
  106. * \li libpri-commits SVN commits to the libpri project
  107. * \li libss7-commits SVN commits to the libss7 project
  108. * \li svn-commits SVN commits to the Digium repositories
  109. * \li Test-results Results from automated testing
  110. * \li thirdparty-commits SVN commits to the Digium third-party software repository
  111. * \li zaptel-commits SVN commits to the Zaptel project
  112. *
  113. * \par Forums
  114. * \li Forums are located at http://forums.asterisk.org/
  115. *
  116. * \par IRC
  117. * \par
  118. * Use http://www.freenode.net IRC server to connect with Asterisk
  119. * developers and users in realtime.
  120. *
  121. * \li \verbatim #asterisk \endverbatim Asterisk Users Room
  122. * \li \verbatim #asterisk-dev \endverbatim Asterisk Developers Room
  123. *
  124. * \par More
  125. * \par
  126. * If you would like to add a resource to this list please create an issue
  127. * on the issue tracker with a patch.
  128. */
  129. /*! \file
  130. * \brief Top level source file for Asterisk - the Open Source PBX.
  131. * Implementation of PBX core functions and CLI interface.
  132. */
  133. /*! \li \ref asterisk.c uses the configuration file \ref asterisk.conf
  134. * \addtogroup configuration_file
  135. */
  136. /*! \page asterisk.conf asterisk.conf
  137. * \verbinclude asterisk.conf.sample
  138. */
  139. /*** MODULEINFO
  140. <support_level>core</support_level>
  141. ***/
  142. #include "asterisk.h"
  143. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  144. #include "asterisk/_private.h"
  145. #undef sched_setscheduler
  146. #undef setpriority
  147. #include <sys/time.h>
  148. #include <fcntl.h>
  149. #include <signal.h>
  150. #include <sched.h>
  151. #include <sys/un.h>
  152. #include <sys/wait.h>
  153. #include <ctype.h>
  154. #include <sys/resource.h>
  155. #include <grp.h>
  156. #include <pwd.h>
  157. #include <sys/stat.h>
  158. #if defined(HAVE_SYSINFO)
  159. #include <sys/sysinfo.h>
  160. #elif defined(HAVE_SYSCTL)
  161. #include <sys/param.h>
  162. #include <sys/sysctl.h>
  163. #include <sys/vmmeter.h>
  164. #if defined(__FreeBSD__) || defined(__DragonFly__)
  165. #include <vm/vm_param.h>
  166. #endif
  167. #if defined(HAVE_SWAPCTL)
  168. #include <sys/swap.h>
  169. #endif
  170. #endif
  171. #include <regex.h>
  172. #include <histedit.h>
  173. #if defined(SOLARIS)
  174. int daemon(int, int); /* defined in libresolv of all places */
  175. #include <sys/loadavg.h>
  176. #endif
  177. #ifdef linux
  178. #include <sys/prctl.h>
  179. #ifdef HAVE_CAP
  180. #include <sys/capability.h>
  181. #endif /* HAVE_CAP */
  182. #endif /* linux */
  183. /* we define here the variables so to better agree on the prototype */
  184. #include "asterisk/paths.h"
  185. #include "asterisk/network.h"
  186. #include "asterisk/cli.h"
  187. #include "asterisk/channel.h"
  188. #include "asterisk/translate.h"
  189. #include "asterisk/pickup.h"
  190. #include "asterisk/features.h"
  191. #include "asterisk/acl.h"
  192. #include "asterisk/ulaw.h"
  193. #include "asterisk/alaw.h"
  194. #include "asterisk/callerid.h"
  195. #include "asterisk/image.h"
  196. #include "asterisk/tdd.h"
  197. #include "asterisk/term.h"
  198. #include "asterisk/manager.h"
  199. #include "asterisk/cdr.h"
  200. #include "asterisk/cel.h"
  201. #include "asterisk/pbx.h"
  202. #include "asterisk/enum.h"
  203. #include "asterisk/http.h"
  204. #include "asterisk/udptl.h"
  205. #include "asterisk/app.h"
  206. #include "asterisk/lock.h"
  207. #include "asterisk/utils.h"
  208. #include "asterisk/file.h"
  209. #include "asterisk/io.h"
  210. #include "editline/histedit.h"
  211. #include "asterisk/config.h"
  212. #include "asterisk/ast_version.h"
  213. #include "asterisk/linkedlists.h"
  214. #include "asterisk/devicestate.h"
  215. #include "asterisk/presencestate.h"
  216. #include "asterisk/module.h"
  217. #include "asterisk/dsp.h"
  218. #include "asterisk/buildinfo.h"
  219. #include "asterisk/xmldoc.h"
  220. #include "asterisk/poll-compat.h"
  221. #include "asterisk/ccss.h"
  222. #include "asterisk/test.h"
  223. #include "asterisk/rtp_engine.h"
  224. #include "asterisk/format.h"
  225. #include "asterisk/aoc.h"
  226. #include "asterisk/uuid.h"
  227. #include "asterisk/sorcery.h"
  228. #include "asterisk/bucket.h"
  229. #include "asterisk/stasis.h"
  230. #include "asterisk/json.h"
  231. #include "asterisk/stasis_endpoints.h"
  232. #include "asterisk/stasis_system.h"
  233. #include "asterisk/security_events.h"
  234. #include "asterisk/endpoints.h"
  235. #include "asterisk/codec.h"
  236. #include "asterisk/format_cache.h"
  237. #include "asterisk/astdb.h"
  238. #include "asterisk/options.h"
  239. #include "../defaults.h"
  240. /*** DOCUMENTATION
  241. <managerEvent language="en_US" name="FullyBooted">
  242. <managerEventInstance class="EVENT_FLAG_SYSTEM">
  243. <synopsis>Raised when all Asterisk initialization procedures have finished.</synopsis>
  244. <syntax>
  245. <parameter name="Status">
  246. <para>Informational message</para>
  247. </parameter>
  248. </syntax>
  249. </managerEventInstance>
  250. </managerEvent>
  251. <managerEvent language="en_US" name="Shutdown">
  252. <managerEventInstance class="EVENT_FLAG_SYSTEM">
  253. <synopsis>Raised when Asterisk is shutdown or restarted.</synopsis>
  254. <syntax>
  255. <parameter name="Shutdown">
  256. <para>Whether the shutdown is proceeding cleanly (all channels
  257. were hungup successfully) or uncleanly (channels will be
  258. terminated)</para>
  259. <enumlist>
  260. <enum name="Uncleanly"/>
  261. <enum name="Cleanly"/>
  262. </enumlist>
  263. </parameter>
  264. <parameter name="Restart">
  265. <para>Whether or not a restart will occur.</para>
  266. <enumlist>
  267. <enum name="True"/>
  268. <enum name="False"/>
  269. </enumlist>
  270. </parameter>
  271. </syntax>
  272. </managerEventInstance>
  273. </managerEvent>
  274. ***/
  275. #ifndef AF_LOCAL
  276. #define AF_LOCAL AF_UNIX
  277. #define PF_LOCAL PF_UNIX
  278. #endif
  279. #define AST_MAX_CONNECTS 128
  280. #define NUM_MSGS 64
  281. /*! \brief Welcome message when starting a CLI interface */
  282. #define WELCOME_MESSAGE \
  283. ast_verbose("Asterisk %s, Copyright (C) 1999 - 2014, Digium, Inc. and others.\n" \
  284. "Created by Mark Spencer <markster@digium.com>\n" \
  285. "Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.\n" \
  286. "This is free software, with components licensed under the GNU General Public\n" \
  287. "License version 2 and other licenses; you are welcome to redistribute it under\n" \
  288. "certain conditions. Type 'core show license' for details.\n" \
  289. "=========================================================================\n", ast_get_version()) \
  290. static int ast_socket = -1; /*!< UNIX Socket for allowing remote control */
  291. static int ast_consock = -1; /*!< UNIX Socket for controlling another asterisk */
  292. pid_t ast_mainpid;
  293. struct console {
  294. int fd; /*!< File descriptor */
  295. int p[2]; /*!< Pipe */
  296. pthread_t t; /*!< Thread of handler */
  297. int mute; /*!< Is the console muted for logs */
  298. int uid; /*!< Remote user ID. */
  299. int gid; /*!< Remote group ID. */
  300. int levels[NUMLOGLEVELS]; /*!< Which log levels are enabled for the console */
  301. /*! Verbosity level of this console. */
  302. int option_verbose;
  303. };
  304. struct ast_atexit {
  305. void (*func)(void);
  306. int is_cleanup;
  307. AST_LIST_ENTRY(ast_atexit) list;
  308. };
  309. static AST_LIST_HEAD_STATIC(atexits, ast_atexit);
  310. struct timeval ast_startuptime;
  311. struct timeval ast_lastreloadtime;
  312. static History *el_hist;
  313. static EditLine *el;
  314. static char *remotehostname;
  315. struct console consoles[AST_MAX_CONNECTS];
  316. static int ast_el_add_history(const char *);
  317. static int ast_el_read_history(const char *);
  318. static int ast_el_write_history(const char *);
  319. static void ast_el_read_default_histfile(void);
  320. static void ast_el_write_default_histfile(void);
  321. static void asterisk_daemon(int isroot, const char *runuser, const char *rungroup);
  322. static char *_argv[256];
  323. typedef enum {
  324. /*! Normal operation */
  325. NOT_SHUTTING_DOWN,
  326. /*! Committed to shutting down. Final phase */
  327. SHUTTING_DOWN_FINAL,
  328. /*! Committed to shutting down. Initial phase */
  329. SHUTTING_DOWN,
  330. /*!
  331. * Valid values for quit_handler() niceness below.
  332. * These shutdown/restart levels can be cancelled.
  333. *
  334. * Remote console exit right now
  335. */
  336. SHUTDOWN_FAST,
  337. /*! core stop/restart now */
  338. SHUTDOWN_NORMAL,
  339. /*! core stop/restart gracefully */
  340. SHUTDOWN_NICE,
  341. /*! core stop/restart when convenient */
  342. SHUTDOWN_REALLY_NICE
  343. } shutdown_nice_t;
  344. static shutdown_nice_t shuttingdown = NOT_SHUTTING_DOWN;
  345. /*! Prevent new channel allocation for shutdown. */
  346. static int shutdown_pending;
  347. static int restartnow;
  348. static pthread_t consolethread = AST_PTHREADT_NULL;
  349. static pthread_t mon_sig_flags;
  350. static int canary_pid = 0;
  351. static char canary_filename[128];
  352. static int multi_thread_safe;
  353. static char randompool[256];
  354. static int sig_alert_pipe[2] = { -1, -1 };
  355. static struct {
  356. unsigned int need_reload:1;
  357. unsigned int need_quit:1;
  358. unsigned int need_quit_handler:1;
  359. unsigned int need_el_end:1;
  360. } sig_flags;
  361. #if !defined(LOW_MEMORY)
  362. struct registered_file {
  363. AST_RWLIST_ENTRY(registered_file) list;
  364. const char *file;
  365. };
  366. static AST_RWLIST_HEAD_STATIC(registered_files, registered_file);
  367. void ast_register_file_version(const char *file, const char *version)
  368. {
  369. struct registered_file *reg;
  370. reg = ast_calloc(1, sizeof(*reg));
  371. if (!reg) {
  372. return;
  373. }
  374. reg->file = file;
  375. AST_RWLIST_WRLOCK(&registered_files);
  376. AST_RWLIST_INSERT_HEAD(&registered_files, reg, list);
  377. AST_RWLIST_UNLOCK(&registered_files);
  378. }
  379. void ast_unregister_file_version(const char *file)
  380. {
  381. struct registered_file *find;
  382. AST_RWLIST_WRLOCK(&registered_files);
  383. AST_RWLIST_TRAVERSE_SAFE_BEGIN(&registered_files, find, list) {
  384. if (!strcasecmp(find->file, file)) {
  385. AST_RWLIST_REMOVE_CURRENT(list);
  386. break;
  387. }
  388. }
  389. AST_RWLIST_TRAVERSE_SAFE_END;
  390. AST_RWLIST_UNLOCK(&registered_files);
  391. if (find) {
  392. ast_free(find);
  393. }
  394. }
  395. char *ast_complete_source_filename(const char *partial, int n)
  396. {
  397. struct registered_file *find;
  398. size_t len = strlen(partial);
  399. int count = 0;
  400. char *res = NULL;
  401. AST_RWLIST_RDLOCK(&registered_files);
  402. AST_RWLIST_TRAVERSE(&registered_files, find, list) {
  403. if (!strncasecmp(find->file, partial, len) && ++count > n) {
  404. res = ast_strdup(find->file);
  405. break;
  406. }
  407. }
  408. AST_RWLIST_UNLOCK(&registered_files);
  409. return res;
  410. }
  411. const char *ast_file_version_find(const char *file)
  412. {
  413. struct registered_file *iterator;
  414. AST_RWLIST_RDLOCK(&registered_files);
  415. AST_RWLIST_TRAVERSE(&registered_files, iterator, list) {
  416. if (!strcasecmp(iterator->file, file)) {
  417. break;
  418. }
  419. }
  420. AST_RWLIST_UNLOCK(&registered_files);
  421. if (iterator) {
  422. return ast_get_version();
  423. }
  424. return NULL;
  425. }
  426. struct thread_list_t {
  427. AST_RWLIST_ENTRY(thread_list_t) list;
  428. char *name;
  429. pthread_t id;
  430. int lwp;
  431. };
  432. static AST_RWLIST_HEAD_STATIC(thread_list, thread_list_t);
  433. void ast_register_thread(char *name)
  434. {
  435. struct thread_list_t *new = ast_calloc(1, sizeof(*new));
  436. if (!new)
  437. return;
  438. ast_assert(multi_thread_safe);
  439. new->id = pthread_self();
  440. new->lwp = ast_get_tid();
  441. new->name = name; /* steal the allocated memory for the thread name */
  442. AST_RWLIST_WRLOCK(&thread_list);
  443. AST_RWLIST_INSERT_HEAD(&thread_list, new, list);
  444. AST_RWLIST_UNLOCK(&thread_list);
  445. }
  446. void ast_unregister_thread(void *id)
  447. {
  448. struct thread_list_t *x;
  449. AST_RWLIST_WRLOCK(&thread_list);
  450. AST_RWLIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) {
  451. if ((void *) x->id == id) {
  452. AST_RWLIST_REMOVE_CURRENT(list);
  453. break;
  454. }
  455. }
  456. AST_RWLIST_TRAVERSE_SAFE_END;
  457. AST_RWLIST_UNLOCK(&thread_list);
  458. if (x) {
  459. ast_free(x->name);
  460. ast_free(x);
  461. }
  462. }
  463. /*! \brief Give an overview of core settings */
  464. static char *handle_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  465. {
  466. char buf[BUFSIZ];
  467. struct ast_tm tm;
  468. char eid_str[128];
  469. struct rlimit limits;
  470. char pbx_uuid[AST_UUID_STR_LEN];
  471. switch (cmd) {
  472. case CLI_INIT:
  473. e->command = "core show settings";
  474. e->usage = "Usage: core show settings\n"
  475. " Show core misc settings";
  476. return NULL;
  477. case CLI_GENERATE:
  478. return NULL;
  479. }
  480. ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
  481. ast_pbx_uuid_get(pbx_uuid, sizeof(pbx_uuid));
  482. ast_cli(a->fd, "\nPBX Core settings\n");
  483. ast_cli(a->fd, "-----------------\n");
  484. ast_cli(a->fd, " Version: %s\n", ast_get_version());
  485. ast_cli(a->fd, " Build Options: %s\n", S_OR(ast_get_build_opts(), "(none)"));
  486. if (ast_option_maxcalls)
  487. ast_cli(a->fd, " Maximum calls: %d (Current %d)\n", ast_option_maxcalls, ast_active_channels());
  488. else
  489. ast_cli(a->fd, " Maximum calls: Not set\n");
  490. if (getrlimit(RLIMIT_NOFILE, &limits)) {
  491. ast_cli(a->fd, " Maximum open file handles: Error because of %s\n", strerror(errno));
  492. } else if (limits.rlim_cur == RLIM_INFINITY) {
  493. ast_cli(a->fd, " Maximum open file handles: Unlimited\n");
  494. } else if (limits.rlim_cur < ast_option_maxfiles) {
  495. ast_cli(a->fd, " Maximum open file handles: %d (is) %d (requested)\n", (int) limits.rlim_cur, ast_option_maxfiles);
  496. } else {
  497. ast_cli(a->fd, " Maximum open file handles: %d\n", (int) limits.rlim_cur);
  498. }
  499. ast_cli(a->fd, " Root console verbosity: %d\n", option_verbose);
  500. ast_cli(a->fd, " Current console verbosity: %d\n", ast_verb_console_get());
  501. ast_cli(a->fd, " Debug level: %d\n", option_debug);
  502. ast_cli(a->fd, " Maximum load average: %lf\n", ast_option_maxload);
  503. #if defined(HAVE_SYSINFO)
  504. ast_cli(a->fd, " Minimum free memory: %ld MB\n", option_minmemfree);
  505. #endif
  506. if (ast_localtime(&ast_startuptime, &tm, NULL)) {
  507. ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
  508. ast_cli(a->fd, " Startup time: %s\n", buf);
  509. }
  510. if (ast_localtime(&ast_lastreloadtime, &tm, NULL)) {
  511. ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
  512. ast_cli(a->fd, " Last reload time: %s\n", buf);
  513. }
  514. ast_cli(a->fd, " System: %s/%s built by %s on %s %s\n", ast_build_os, ast_build_kernel, ast_build_user, ast_build_machine, ast_build_date);
  515. ast_cli(a->fd, " System name: %s\n", ast_config_AST_SYSTEM_NAME);
  516. ast_cli(a->fd, " Entity ID: %s\n", eid_str);
  517. ast_cli(a->fd, " PBX UUID: %s\n", pbx_uuid);
  518. ast_cli(a->fd, " Default language: %s\n", ast_defaultlanguage);
  519. ast_cli(a->fd, " Language prefix: %s\n", ast_language_is_prefix ? "Enabled" : "Disabled");
  520. ast_cli(a->fd, " User name and group: %s/%s\n", ast_config_AST_RUN_USER, ast_config_AST_RUN_GROUP);
  521. ast_cli(a->fd, " Executable includes: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) ? "Enabled" : "Disabled");
  522. ast_cli(a->fd, " Transcode via SLIN: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN) ? "Enabled" : "Disabled");
  523. ast_cli(a->fd, " Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE) ? "Enabled" : "Disabled");
  524. ast_cli(a->fd, " Generic PLC: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC) ? "Enabled" : "Disabled");
  525. ast_cli(a->fd, " Generic PLC on equal codecs: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC_ON_EQUAL_CODECS) ? "Enabled" : "Disabled");
  526. ast_cli(a->fd, " Min DTMF duration:: %u\n", option_dtmfminduration);
  527. #if !defined(LOW_MEMORY)
  528. ast_cli(a->fd, " Cache media frames: %s\n", ast_opt_cache_media_frames ? "Enabled" : "Disabled");
  529. #endif
  530. if (ast_option_rtpptdynamic == AST_RTP_PT_LAST_REASSIGN) {
  531. ast_cli(a->fd, " RTP dynamic payload types: %u,%u-%u\n",
  532. ast_option_rtpptdynamic,
  533. AST_RTP_PT_FIRST_DYNAMIC, AST_RTP_MAX_PT - 1);
  534. } else if (ast_option_rtpptdynamic < AST_RTP_PT_LAST_REASSIGN) {
  535. ast_cli(a->fd, " RTP dynamic payload types: %u-%u,%u-%u\n",
  536. ast_option_rtpptdynamic, AST_RTP_PT_LAST_REASSIGN,
  537. AST_RTP_PT_FIRST_DYNAMIC, AST_RTP_MAX_PT - 1);
  538. } else {
  539. ast_cli(a->fd, " RTP dynamic payload types: %u-%u\n",
  540. AST_RTP_PT_FIRST_DYNAMIC, AST_RTP_MAX_PT - 1);
  541. }
  542. ast_cli(a->fd, "\n* Subsystems\n");
  543. ast_cli(a->fd, " -------------\n");
  544. ast_cli(a->fd, " Manager (AMI): %s\n", check_manager_enabled() ? "Enabled" : "Disabled");
  545. ast_cli(a->fd, " Web Manager (AMI/HTTP): %s\n", check_webmanager_enabled() ? "Enabled" : "Disabled");
  546. ast_cli(a->fd, " Call data records: %s\n", ast_cdr_is_enabled() ? "Enabled" : "Disabled");
  547. ast_cli(a->fd, " Realtime Architecture (ARA): %s\n", ast_realtime_enabled() ? "Enabled" : "Disabled");
  548. /*! \todo we could check musiconhold, voicemail, smdi, adsi, queues */
  549. ast_cli(a->fd, "\n* Directories\n");
  550. ast_cli(a->fd, " -------------\n");
  551. ast_cli(a->fd, " Configuration file: %s\n", ast_config_AST_CONFIG_FILE);
  552. ast_cli(a->fd, " Configuration directory: %s\n", ast_config_AST_CONFIG_DIR);
  553. ast_cli(a->fd, " Module directory: %s\n", ast_config_AST_MODULE_DIR);
  554. ast_cli(a->fd, " Spool directory: %s\n", ast_config_AST_SPOOL_DIR);
  555. ast_cli(a->fd, " Log directory: %s\n", ast_config_AST_LOG_DIR);
  556. ast_cli(a->fd, " Run/Sockets directory: %s\n", ast_config_AST_RUN_DIR);
  557. ast_cli(a->fd, " PID file: %s\n", ast_config_AST_PID);
  558. ast_cli(a->fd, " VarLib directory: %s\n", ast_config_AST_VAR_DIR);
  559. ast_cli(a->fd, " Data directory: %s\n", ast_config_AST_DATA_DIR);
  560. ast_cli(a->fd, " ASTDB: %s\n", ast_config_AST_DB);
  561. ast_cli(a->fd, " IAX2 Keys directory: %s\n", ast_config_AST_KEY_DIR);
  562. ast_cli(a->fd, " AGI Scripts directory: %s\n", ast_config_AST_AGI_DIR);
  563. ast_cli(a->fd, "\n\n");
  564. return CLI_SUCCESS;
  565. }
  566. static char *handle_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  567. {
  568. int count = 0;
  569. struct thread_list_t *cur;
  570. switch (cmd) {
  571. case CLI_INIT:
  572. e->command = "core show threads";
  573. e->usage =
  574. "Usage: core show threads\n"
  575. " List threads currently active in the system.\n";
  576. return NULL;
  577. case CLI_GENERATE:
  578. return NULL;
  579. }
  580. AST_RWLIST_RDLOCK(&thread_list);
  581. AST_RWLIST_TRAVERSE(&thread_list, cur, list) {
  582. ast_cli(a->fd, "%p %d %s\n", (void *)cur->id, cur->lwp, cur->name);
  583. count++;
  584. }
  585. AST_RWLIST_UNLOCK(&thread_list);
  586. ast_cli(a->fd, "%d threads listed.\n", count);
  587. return CLI_SUCCESS;
  588. }
  589. #if defined (HAVE_SYSCTL) && defined(HAVE_SWAPCTL)
  590. /*
  591. * swapmode is rewritten by Tobias Weingartner <weingart@openbsd.org>
  592. * to be based on the new swapctl(2) system call.
  593. */
  594. static int swapmode(int *used, int *total)
  595. {
  596. struct swapent *swdev;
  597. int nswap, rnswap, i;
  598. nswap = swapctl(SWAP_NSWAP, 0, 0);
  599. if (nswap == 0)
  600. return 0;
  601. swdev = ast_calloc(nswap, sizeof(*swdev));
  602. if (swdev == NULL)
  603. return 0;
  604. rnswap = swapctl(SWAP_STATS, swdev, nswap);
  605. if (rnswap == -1) {
  606. ast_free(swdev);
  607. return 0;
  608. }
  609. /* if rnswap != nswap, then what? */
  610. /* Total things up */
  611. *total = *used = 0;
  612. for (i = 0; i < nswap; i++) {
  613. if (swdev[i].se_flags & SWF_ENABLE) {
  614. *used += (swdev[i].se_inuse / (1024 / DEV_BSIZE));
  615. *total += (swdev[i].se_nblks / (1024 / DEV_BSIZE));
  616. }
  617. }
  618. ast_free(swdev);
  619. return 1;
  620. }
  621. #endif
  622. #if defined(HAVE_SYSINFO) || defined(HAVE_SYSCTL)
  623. /*! \brief Give an overview of system statistics */
  624. static char *handle_show_sysinfo(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  625. {
  626. uint64_t physmem, freeram;
  627. #if defined(HAVE_SYSINFO) || defined(HAVE_SWAPCTL)
  628. int totalswap = 0;
  629. uint64_t freeswap = 0;
  630. #endif
  631. int nprocs = 0;
  632. long uptime = 0;
  633. #if defined(HAVE_SYSINFO)
  634. struct sysinfo sys_info;
  635. #elif defined(HAVE_SYSCTL)
  636. static int pageshift;
  637. struct vmtotal vmtotal;
  638. struct timeval boottime;
  639. time_t now;
  640. int mib[2], pagesize;
  641. #if defined(HAVE_SWAPCTL)
  642. int usedswap = 0;
  643. #endif
  644. size_t len;
  645. #endif
  646. switch (cmd) {
  647. case CLI_INIT:
  648. e->command = "core show sysinfo";
  649. e->usage =
  650. "Usage: core show sysinfo\n"
  651. " List current system information.\n";
  652. return NULL;
  653. case CLI_GENERATE:
  654. return NULL;
  655. }
  656. #if defined(HAVE_SYSINFO)
  657. sysinfo(&sys_info);
  658. uptime = sys_info.uptime / 3600;
  659. physmem = sys_info.totalram * sys_info.mem_unit;
  660. freeram = (sys_info.freeram * sys_info.mem_unit) / 1024;
  661. totalswap = (sys_info.totalswap * sys_info.mem_unit) / 1024;
  662. freeswap = (sys_info.freeswap * sys_info.mem_unit) / 1024;
  663. nprocs = sys_info.procs;
  664. #elif defined(HAVE_SYSCTL)
  665. /* calculate the uptime by looking at boottime */
  666. time(&now);
  667. mib[0] = CTL_KERN;
  668. mib[1] = KERN_BOOTTIME;
  669. len = sizeof(boottime);
  670. if (sysctl(mib, 2, &boottime, &len, NULL, 0) != -1) {
  671. uptime = now - boottime.tv_sec;
  672. }
  673. uptime = uptime/3600;
  674. /* grab total physical memory */
  675. mib[0] = CTL_HW;
  676. #if defined(HW_PHYSMEM64)
  677. mib[1] = HW_PHYSMEM64;
  678. #else
  679. mib[1] = HW_PHYSMEM;
  680. #endif
  681. len = sizeof(physmem);
  682. sysctl(mib, 2, &physmem, &len, NULL, 0);
  683. pagesize = getpagesize();
  684. pageshift = 0;
  685. while (pagesize > 1) {
  686. pageshift++;
  687. pagesize >>= 1;
  688. }
  689. /* we only need the amount of log(2)1024 for our conversion */
  690. pageshift -= 10;
  691. /* grab vm totals */
  692. mib[0] = CTL_VM;
  693. mib[1] = VM_METER;
  694. len = sizeof(vmtotal);
  695. sysctl(mib, 2, &vmtotal, &len, NULL, 0);
  696. freeram = (vmtotal.t_free << pageshift);
  697. /* generate swap usage and totals */
  698. #if defined(HAVE_SWAPCTL)
  699. swapmode(&usedswap, &totalswap);
  700. freeswap = (totalswap - usedswap);
  701. #endif
  702. /* grab number of processes */
  703. #if defined(__OpenBSD__)
  704. mib[0] = CTL_KERN;
  705. mib[1] = KERN_NPROCS;
  706. len = sizeof(nprocs);
  707. sysctl(mib, 2, &nprocs, &len, NULL, 0);
  708. #endif
  709. #endif
  710. ast_cli(a->fd, "\nSystem Statistics\n");
  711. ast_cli(a->fd, "-----------------\n");
  712. ast_cli(a->fd, " System Uptime: %ld hours\n", uptime);
  713. ast_cli(a->fd, " Total RAM: %" PRIu64 " KiB\n", physmem / 1024);
  714. ast_cli(a->fd, " Free RAM: %" PRIu64 " KiB\n", freeram);
  715. #if defined(HAVE_SYSINFO)
  716. ast_cli(a->fd, " Buffer RAM: %" PRIu64 " KiB\n", ((uint64_t) sys_info.bufferram * sys_info.mem_unit) / 1024);
  717. #endif
  718. #if defined(HAVE_SYSINFO) || defined(HAVE_SWAPCTL)
  719. ast_cli(a->fd, " Total Swap Space: %d KiB\n", totalswap);
  720. ast_cli(a->fd, " Free Swap Space: %" PRIu64 " KiB\n\n", freeswap);
  721. #endif
  722. ast_cli(a->fd, " Number of Processes: %d \n\n", nprocs);
  723. return CLI_SUCCESS;
  724. }
  725. #endif
  726. struct profile_entry {
  727. const char *name;
  728. uint64_t scale; /* if non-zero, values are scaled by this */
  729. int64_t mark;
  730. int64_t value;
  731. int64_t events;
  732. };
  733. struct profile_data {
  734. int entries;
  735. int max_size;
  736. struct profile_entry e[0];
  737. };
  738. static struct profile_data *prof_data;
  739. /*! \brief allocates a counter with a given name and scale.
  740. * \return Returns the identifier of the counter.
  741. */
  742. int ast_add_profile(const char *name, uint64_t scale)
  743. {
  744. int l = sizeof(struct profile_data);
  745. int n = 10; /* default entries */
  746. if (prof_data == NULL) {
  747. prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
  748. if (prof_data == NULL)
  749. return -1;
  750. prof_data->entries = 0;
  751. prof_data->max_size = n;
  752. }
  753. if (prof_data->entries >= prof_data->max_size) {
  754. void *p;
  755. n = prof_data->max_size + 20;
  756. p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
  757. if (p == NULL)
  758. return -1;
  759. prof_data = p;
  760. prof_data->max_size = n;
  761. }
  762. n = prof_data->entries++;
  763. prof_data->e[n].name = ast_strdup(name);
  764. prof_data->e[n].value = 0;
  765. prof_data->e[n].events = 0;
  766. prof_data->e[n].mark = 0;
  767. prof_data->e[n].scale = scale;
  768. return n;
  769. }
  770. int64_t ast_profile(int i, int64_t delta)
  771. {
  772. if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
  773. return 0;
  774. if (prof_data->e[i].scale > 1)
  775. delta /= prof_data->e[i].scale;
  776. prof_data->e[i].value += delta;
  777. prof_data->e[i].events++;
  778. return prof_data->e[i].value;
  779. }
  780. /* The RDTSC instruction was introduced on the Pentium processor and is not
  781. * implemented on certain clones, like the Cyrix 586. Hence, the previous
  782. * expectation of __i386__ was in error. */
  783. #if defined ( __i686__) && (defined(__FreeBSD__) || defined(linux))
  784. #if defined(__FreeBSD__)
  785. #include <machine/cpufunc.h>
  786. #elif defined(linux)
  787. static __inline uint64_t
  788. rdtsc(void)
  789. {
  790. uint64_t rv;
  791. __asm __volatile(".byte 0x0f, 0x31" : "=A" (rv));
  792. return (rv);
  793. }
  794. #endif
  795. #else /* supply a dummy function on other platforms */
  796. static __inline uint64_t
  797. rdtsc(void)
  798. {
  799. return 0;
  800. }
  801. #endif
  802. int64_t ast_mark(int i, int startstop)
  803. {
  804. if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
  805. return 0;
  806. if (startstop == 1)
  807. prof_data->e[i].mark = rdtsc();
  808. else {
  809. prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
  810. if (prof_data->e[i].scale > 1)
  811. prof_data->e[i].mark /= prof_data->e[i].scale;
  812. prof_data->e[i].value += prof_data->e[i].mark;
  813. prof_data->e[i].events++;
  814. }
  815. return prof_data->e[i].mark;
  816. }
  817. #define DEFINE_PROFILE_MIN_MAX_VALUES min = 0; \
  818. max = prof_data->entries;\
  819. if (a->argc > 3) { /* specific entries */ \
  820. if (isdigit(a->argv[3][0])) { \
  821. min = atoi(a->argv[3]); \
  822. if (a->argc == 5 && strcmp(a->argv[4], "-")) \
  823. max = atoi(a->argv[4]); \
  824. } else \
  825. search = a->argv[3]; \
  826. } \
  827. if (max > prof_data->entries) \
  828. max = prof_data->entries;
  829. static char *handle_show_profile(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  830. {
  831. int i, min, max;
  832. const char *search = NULL;
  833. switch (cmd) {
  834. case CLI_INIT:
  835. e->command = "core show profile";
  836. e->usage = "Usage: core show profile\n"
  837. " show profile information";
  838. return NULL;
  839. case CLI_GENERATE:
  840. return NULL;
  841. }
  842. if (prof_data == NULL)
  843. return 0;
  844. DEFINE_PROFILE_MIN_MAX_VALUES;
  845. ast_cli(a->fd, "profile values (%d, allocated %d)\n-------------------\n",
  846. prof_data->entries, prof_data->max_size);
  847. ast_cli(a->fd, "%6s %8s %10s %12s %12s %s\n", "ID", "Scale", "Events",
  848. "Value", "Average", "Name");
  849. for (i = min; i < max; i++) {
  850. struct profile_entry *entry = &prof_data->e[i];
  851. if (!search || strstr(entry->name, search))
  852. ast_cli(a->fd, "%6d: [%8ld] %10ld %12lld %12lld %s\n",
  853. i,
  854. (long)entry->scale,
  855. (long)entry->events, (long long)entry->value,
  856. (long long)(entry->events ? entry->value / entry->events : entry->value),
  857. entry->name);
  858. }
  859. return CLI_SUCCESS;
  860. }
  861. static char *handle_clear_profile(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  862. {
  863. int i, min, max;
  864. const char *search = NULL;
  865. switch (cmd) {
  866. case CLI_INIT:
  867. e->command = "core clear profile";
  868. e->usage = "Usage: core clear profile\n"
  869. " clear profile information";
  870. return NULL;
  871. case CLI_GENERATE:
  872. return NULL;
  873. }
  874. if (prof_data == NULL)
  875. return 0;
  876. DEFINE_PROFILE_MIN_MAX_VALUES;
  877. for (i= min; i < max; i++) {
  878. if (!search || strstr(prof_data->e[i].name, search)) {
  879. prof_data->e[i].value = 0;
  880. prof_data->e[i].events = 0;
  881. }
  882. }
  883. return CLI_SUCCESS;
  884. }
  885. #undef DEFINE_PROFILE_MIN_MAX_VALUES
  886. /*! \brief CLI command to list module versions */
  887. static char *handle_show_version_files(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  888. {
  889. #define FORMAT "%-25.25s %-40.40s\n"
  890. static const char * const completions[] = { "like", NULL };
  891. struct registered_file *iterator;
  892. regex_t regexbuf;
  893. int havepattern = 0;
  894. int havename = 0;
  895. int count_files = 0;
  896. char *ret = NULL;
  897. switch (cmd) {
  898. case CLI_INIT:
  899. e->command = "core show file version";
  900. e->usage =
  901. "Usage: core show file version [<filename>|like <pattern>]\n"
  902. " Lists the files along with the Asterisk version.\n"
  903. " Optional regular expression pattern is used to filter the file list.\n";
  904. return NULL;
  905. case CLI_GENERATE:
  906. if (a->pos != 4) {
  907. return NULL;
  908. }
  909. ret = ast_cli_complete(a->word, completions, a->n);
  910. if (!ret) {
  911. ret = ast_complete_source_filename(a->word, a->n - 1);
  912. }
  913. return ret;
  914. }
  915. switch (a->argc) {
  916. case 6:
  917. if (!strcasecmp(a->argv[4], "like")) {
  918. if (regcomp(&regexbuf, a->argv[5], REG_EXTENDED | REG_NOSUB))
  919. return CLI_SHOWUSAGE;
  920. havepattern = 1;
  921. } else
  922. return CLI_SHOWUSAGE;
  923. break;
  924. case 5:
  925. if (!strcasecmp(a->argv[4], "like")) {
  926. return CLI_SHOWUSAGE;
  927. }
  928. havename = 1;
  929. break;
  930. case 4:
  931. break;
  932. default:
  933. return CLI_SHOWUSAGE;
  934. }
  935. ast_cli(a->fd, FORMAT, "File", "Revision");
  936. ast_cli(a->fd, FORMAT, "----", "--------");
  937. AST_RWLIST_RDLOCK(&registered_files);
  938. AST_RWLIST_TRAVERSE(&registered_files, iterator, list) {
  939. if (havename && strcasecmp(iterator->file, a->argv[4]))
  940. continue;
  941. if (havepattern && regexec(&regexbuf, iterator->file, 0, NULL, 0))
  942. continue;
  943. ast_cli(a->fd, FORMAT, iterator->file, ast_get_version());
  944. count_files++;
  945. if (havename)
  946. break;
  947. }
  948. AST_RWLIST_UNLOCK(&registered_files);
  949. if (!havename) {
  950. ast_cli(a->fd, "%d files listed.\n", count_files);
  951. }
  952. if (havepattern)
  953. regfree(&regexbuf);
  954. return CLI_SUCCESS;
  955. #undef FORMAT
  956. }
  957. #endif /* ! LOW_MEMORY */
  958. int ast_pbx_uuid_get(char *pbx_uuid, int length)
  959. {
  960. return ast_db_get("pbx", "UUID", pbx_uuid, length);
  961. }
  962. static void publish_fully_booted(void)
  963. {
  964. struct ast_json *json_object;
  965. json_object = ast_json_pack("{s: s}",
  966. "Status", "Fully Booted");
  967. ast_manager_publish_event("FullyBooted", EVENT_FLAG_SYSTEM, json_object);
  968. ast_json_unref(json_object);
  969. }
  970. static void ast_run_atexits(int run_cleanups)
  971. {
  972. struct ast_atexit *ae;
  973. AST_LIST_LOCK(&atexits);
  974. while ((ae = AST_LIST_REMOVE_HEAD(&atexits, list))) {
  975. if (ae->func && (!ae->is_cleanup || run_cleanups)) {
  976. ae->func();
  977. }
  978. ast_free(ae);
  979. }
  980. AST_LIST_UNLOCK(&atexits);
  981. }
  982. static void __ast_unregister_atexit(void (*func)(void))
  983. {
  984. struct ast_atexit *ae;
  985. AST_LIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
  986. if (ae->func == func) {
  987. AST_LIST_REMOVE_CURRENT(list);
  988. ast_free(ae);
  989. break;
  990. }
  991. }
  992. AST_LIST_TRAVERSE_SAFE_END;
  993. }
  994. static int register_atexit(void (*func)(void), int is_cleanup)
  995. {
  996. struct ast_atexit *ae;
  997. ae = ast_calloc(1, sizeof(*ae));
  998. if (!ae) {
  999. return -1;
  1000. }
  1001. ae->func = func;
  1002. ae->is_cleanup = is_cleanup;
  1003. AST_LIST_LOCK(&atexits);
  1004. __ast_unregister_atexit(func);
  1005. AST_LIST_INSERT_HEAD(&atexits, ae, list);
  1006. AST_LIST_UNLOCK(&atexits);
  1007. return 0;
  1008. }
  1009. int ast_register_atexit(void (*func)(void))
  1010. {
  1011. return register_atexit(func, 0);
  1012. }
  1013. int ast_register_cleanup(void (*func)(void))
  1014. {
  1015. return register_atexit(func, 1);
  1016. }
  1017. void ast_unregister_atexit(void (*func)(void))
  1018. {
  1019. AST_LIST_LOCK(&atexits);
  1020. __ast_unregister_atexit(func);
  1021. AST_LIST_UNLOCK(&atexits);
  1022. }
  1023. /* Sending commands from consoles back to the daemon requires a terminating NULL */
  1024. static int fdsend(int fd, const char *s)
  1025. {
  1026. return write(fd, s, strlen(s) + 1);
  1027. }
  1028. /* Sending messages from the daemon back to the display requires _excluding_ the terminating NULL */
  1029. static int fdprint(int fd, const char *s)
  1030. {
  1031. return write(fd, s, strlen(s));
  1032. }
  1033. /*! \brief NULL handler so we can collect the child exit status */
  1034. static void _null_sig_handler(int sig)
  1035. {
  1036. }
  1037. static struct sigaction null_sig_handler = {
  1038. .sa_handler = _null_sig_handler,
  1039. .sa_flags = SA_RESTART,
  1040. };
  1041. static struct sigaction ignore_sig_handler = {
  1042. .sa_handler = SIG_IGN,
  1043. };
  1044. AST_MUTEX_DEFINE_STATIC(safe_system_lock);
  1045. /*! \brief Keep track of how many threads are currently trying to wait*() on
  1046. * a child process
  1047. */
  1048. static unsigned int safe_system_level = 0;
  1049. static struct sigaction safe_system_prev_handler;
  1050. void ast_replace_sigchld(void)
  1051. {
  1052. unsigned int level;
  1053. ast_mutex_lock(&safe_system_lock);
  1054. level = safe_system_level++;
  1055. /* only replace the handler if it has not already been done */
  1056. if (level == 0) {
  1057. sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
  1058. }
  1059. ast_mutex_unlock(&safe_system_lock);
  1060. }
  1061. void ast_unreplace_sigchld(void)
  1062. {
  1063. unsigned int level;
  1064. ast_mutex_lock(&safe_system_lock);
  1065. level = --safe_system_level;
  1066. /* only restore the handler if we are the last one */
  1067. if (level == 0) {
  1068. sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
  1069. }
  1070. ast_mutex_unlock(&safe_system_lock);
  1071. }
  1072. /*! \brief fork and perform other preparations for spawning applications */
  1073. static pid_t safe_exec_prep(int dualfork)
  1074. {
  1075. pid_t pid;
  1076. #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
  1077. ast_replace_sigchld();
  1078. #ifdef HAVE_WORKING_FORK
  1079. pid = fork();
  1080. #else
  1081. pid = vfork();
  1082. #endif
  1083. if (pid == 0) {
  1084. #ifdef HAVE_CAP
  1085. cap_t cap = cap_from_text("cap_net_admin-eip");
  1086. if (cap_set_proc(cap)) {
  1087. /* Careful with order! Logging cannot happen after we close FDs */
  1088. ast_log(LOG_WARNING, "Unable to remove capabilities.\n");
  1089. }
  1090. cap_free(cap);
  1091. #endif
  1092. #ifdef HAVE_WORKING_FORK
  1093. if (ast_opt_high_priority) {
  1094. ast_set_priority(0);
  1095. }
  1096. /* Close file descriptors and launch system command */
  1097. ast_close_fds_above_n(STDERR_FILENO);
  1098. #endif
  1099. if (dualfork) {
  1100. #ifdef HAVE_WORKING_FORK
  1101. pid = fork();
  1102. #else
  1103. pid = vfork();
  1104. #endif
  1105. if (pid < 0) {
  1106. /* Second fork failed. */
  1107. /* No logger available. */
  1108. _exit(1);
  1109. }
  1110. if (pid > 0) {
  1111. /* This is the first fork, exit so the reaper finishes right away. */
  1112. _exit(0);
  1113. }
  1114. /* This is the second fork. The first fork will exit immediately so
  1115. * Asterisk doesn't have to wait for completion.
  1116. * ast_safe_system("cmd &") would run in the background, but the '&'
  1117. * cannot be added with ast_safe_execvp, so we have to double fork.
  1118. */
  1119. }
  1120. }
  1121. if (pid < 0) {
  1122. ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
  1123. }
  1124. #else
  1125. ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(ENOTSUP));
  1126. pid = -1;
  1127. #endif
  1128. return pid;
  1129. }
  1130. /*! \brief wait for spawned application to complete and unreplace sigchld */
  1131. static int safe_exec_wait(pid_t pid)
  1132. {
  1133. int res = -1;
  1134. #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
  1135. if (pid > 0) {
  1136. for (;;) {
  1137. int status;
  1138. res = waitpid(pid, &status, 0);
  1139. if (res > -1) {
  1140. res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
  1141. break;
  1142. }
  1143. if (errno != EINTR) {
  1144. break;
  1145. }
  1146. }
  1147. }
  1148. ast_unreplace_sigchld();
  1149. #endif
  1150. return res;
  1151. }
  1152. int ast_safe_execvp(int dualfork, const char *file, char *const argv[])
  1153. {
  1154. pid_t pid = safe_exec_prep(dualfork);
  1155. if (pid == 0) {
  1156. execvp(file, argv);
  1157. _exit(1);
  1158. /* noreturn from _exit */
  1159. }
  1160. return safe_exec_wait(pid);
  1161. }
  1162. int ast_safe_system(const char *s)
  1163. {
  1164. pid_t pid = safe_exec_prep(0);
  1165. if (pid == 0) {
  1166. execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
  1167. _exit(1);
  1168. /* noreturn from _exit */
  1169. }
  1170. return safe_exec_wait(pid);
  1171. }
  1172. /*!
  1173. * \brief enable or disable a logging level to a specified console
  1174. */
  1175. void ast_console_toggle_loglevel(int fd, int level, int state)
  1176. {
  1177. int x;
  1178. if (level >= NUMLOGLEVELS) {
  1179. level = NUMLOGLEVELS - 1;
  1180. }
  1181. for (x = 0;x < AST_MAX_CONNECTS; x++) {
  1182. if (fd == consoles[x].fd) {
  1183. /*
  1184. * Since the logging occurs when levels are false, set to
  1185. * flipped iinput because this function accepts 0 as off and 1 as on
  1186. */
  1187. consoles[x].levels[level] = state ? 0 : 1;
  1188. return;
  1189. }
  1190. }
  1191. }
  1192. /*!
  1193. * \brief mute or unmute a console from logging
  1194. */
  1195. void ast_console_toggle_mute(int fd, int silent)
  1196. {
  1197. int x;
  1198. for (x = 0;x < AST_MAX_CONNECTS; x++) {
  1199. if (fd == consoles[x].fd) {
  1200. if (consoles[x].mute) {
  1201. consoles[x].mute = 0;
  1202. if (!silent)
  1203. ast_cli(fd, "Console is not muted anymore.\n");
  1204. } else {
  1205. consoles[x].mute = 1;
  1206. if (!silent)
  1207. ast_cli(fd, "Console is muted.\n");
  1208. }
  1209. return;
  1210. }
  1211. }
  1212. ast_cli(fd, "Couldn't find remote console.\n");
  1213. }
  1214. /*!
  1215. * \brief log the string to all attached network console clients
  1216. */
  1217. static void ast_network_puts_mutable(const char *string, int level)
  1218. {
  1219. int x;
  1220. for (x = 0; x < AST_MAX_CONNECTS; ++x) {
  1221. if (consoles[x].fd < 0
  1222. || consoles[x].mute
  1223. || consoles[x].levels[level]) {
  1224. continue;
  1225. }
  1226. fdprint(consoles[x].p[1], string);
  1227. }
  1228. }
  1229. /*!
  1230. * \brief log the string to the root console, and all attached
  1231. * network console clients
  1232. */
  1233. void ast_console_puts_mutable(const char *string, int level)
  1234. {
  1235. /* Send to the root console */
  1236. fputs(string, stdout);
  1237. fflush(stdout);
  1238. /* Send to any network console clients */
  1239. ast_network_puts_mutable(string, level);
  1240. }
  1241. /*!
  1242. * \brief write the string to all attached console clients
  1243. */
  1244. static void ast_network_puts(const char *string)
  1245. {
  1246. int x;
  1247. for (x = 0; x < AST_MAX_CONNECTS; ++x) {
  1248. if (consoles[x].fd < 0) {
  1249. continue;
  1250. }
  1251. fdprint(consoles[x].p[1], string);
  1252. }
  1253. }
  1254. /*!
  1255. * \brief write the string to the root console, and all attached
  1256. * network console clients
  1257. */
  1258. void ast_console_puts(const char *string)
  1259. {
  1260. /* Send to the root console */
  1261. fputs(string, stdout);
  1262. fflush(stdout);
  1263. /* Send to any network console clients */
  1264. ast_network_puts(string);
  1265. }
  1266. static void network_verboser(const char *string)
  1267. {
  1268. int x;
  1269. int verb_level;
  1270. /* Send to any network console clients if client verbocity allows. */
  1271. verb_level = VERBOSE_MAGIC2LEVEL(string);
  1272. for (x = 0; x < AST_MAX_CONNECTS; ++x) {
  1273. if (consoles[x].fd < 0
  1274. || consoles[x].mute
  1275. || consoles[x].levels[__LOG_VERBOSE]
  1276. || consoles[x].option_verbose < verb_level) {
  1277. continue;
  1278. }
  1279. fdprint(consoles[x].p[1], string);
  1280. }
  1281. }
  1282. static pthread_t lthread;
  1283. /*!
  1284. * \brief read() function supporting the reception of user credentials.
  1285. *
  1286. * \param fd Socket file descriptor.
  1287. * \param buffer Receive buffer.
  1288. * \param size 'buffer' size.
  1289. * \param con Console structure to set received credentials
  1290. * \retval -1 on error
  1291. * \retval the number of bytes received on success.
  1292. */
  1293. static int read_credentials(int fd, char *buffer, size_t size, struct console *con)
  1294. {
  1295. #if defined(SO_PEERCRED)
  1296. #ifdef HAVE_STRUCT_SOCKPEERCRED_UID
  1297. #define HAVE_STRUCT_UCRED_UID
  1298. struct sockpeercred cred;
  1299. #else
  1300. struct ucred cred;
  1301. #endif
  1302. socklen_t len = sizeof(cred);
  1303. #endif
  1304. #if defined(HAVE_GETPEEREID)
  1305. uid_t uid;
  1306. gid_t gid;
  1307. #else
  1308. int uid, gid;
  1309. #endif
  1310. int result;
  1311. result = read(fd, buffer, size);
  1312. if (result < 0) {
  1313. return result;
  1314. }
  1315. #if defined(SO_PEERCRED) && (defined(HAVE_STRUCT_UCRED_UID) || defined(HAVE_STRUCT_UCRED_CR_UID))
  1316. if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len)) {
  1317. return result;
  1318. }
  1319. #if defined(HAVE_STRUCT_UCRED_UID)
  1320. uid = cred.uid;
  1321. gid = cred.gid;
  1322. #else /* defined(HAVE_STRUCT_UCRED_CR_UID) */
  1323. uid = cred.cr_uid;
  1324. gid = cred.cr_gid;
  1325. #endif /* defined(HAVE_STRUCT_UCRED_UID) */
  1326. #elif defined(HAVE_GETPEEREID)
  1327. if (getpeereid(fd, &uid, &gid)) {
  1328. return result;
  1329. }
  1330. #else
  1331. return result;
  1332. #endif
  1333. con->uid = uid;
  1334. con->gid = gid;
  1335. return result;
  1336. }
  1337. /* This is the thread running the remote console on the main process. */
  1338. static void *netconsole(void *vconsole)
  1339. {
  1340. struct console *con = vconsole;
  1341. char hostname[MAXHOSTNAMELEN] = "";
  1342. char inbuf[512];
  1343. char outbuf[512];
  1344. const char * const end_buf = inbuf + sizeof(inbuf);
  1345. char *start_read = inbuf;
  1346. int res;
  1347. struct pollfd fds[2];
  1348. if (gethostname(hostname, sizeof(hostname)-1))
  1349. ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
  1350. snprintf(outbuf, sizeof(outbuf), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version());
  1351. fdprint(con->fd, outbuf);
  1352. ast_verb_console_register(&con->option_verbose);
  1353. for (;;) {
  1354. fds[0].fd = con->fd;
  1355. fds[0].events = POLLIN;
  1356. fds[0].revents = 0;
  1357. fds[1].fd = con->p[0];
  1358. fds[1].events = POLLIN;
  1359. fds[1].revents = 0;
  1360. res = ast_poll(fds, 2, -1);
  1361. if (res < 0) {
  1362. if (errno != EINTR)
  1363. ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
  1364. continue;
  1365. }
  1366. if (fds[0].revents) {
  1367. int cmds_read, bytes_read;
  1368. if ((bytes_read = read_credentials(con->fd, start_read, end_buf - start_read, con)) < 1) {
  1369. break;
  1370. }
  1371. /* XXX This will only work if it is the first command, and I'm not sure fixing it is worth the effort. */
  1372. if (strncmp(inbuf, "cli quit after ", 15) == 0) {
  1373. ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read - 15, inbuf + 15);
  1374. break;
  1375. }
  1376. /* ast_cli_command_multiple_full will only process individual commands terminated by a
  1377. * NULL and not trailing partial commands. */
  1378. if (!(cmds_read = ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read + start_read - inbuf, inbuf))) {
  1379. /* No commands were read. We either have a short read on the first command
  1380. * with space left, or a command that is too long */
  1381. if (start_read + bytes_read < end_buf) {
  1382. start_read += bytes_read;
  1383. } else {
  1384. ast_log(LOG_ERROR, "Command too long! Skipping\n");
  1385. start_read = inbuf;
  1386. }
  1387. continue;
  1388. }
  1389. if (start_read[bytes_read - 1] == '\0') {
  1390. /* The read ended on a command boundary, start reading again at the head of inbuf */
  1391. start_read = inbuf;
  1392. continue;
  1393. }
  1394. /* If we get this far, we have left over characters that have not been processed.
  1395. * Advance to the character after the last command read by ast_cli_command_multiple_full.
  1396. * We are guaranteed to have at least cmds_read NULLs */
  1397. while (cmds_read-- && (start_read = strchr(start_read, '\0'))) {
  1398. start_read++;
  1399. }
  1400. memmove(inbuf, start_read, end_buf - start_read);
  1401. start_read = end_buf - start_read + inbuf;
  1402. }
  1403. if (fds[1].revents) {
  1404. res = read_credentials(con->p[0], outbuf, sizeof(outbuf), con);
  1405. if (res < 1) {
  1406. ast_log(LOG_ERROR, "read returned %d\n", res);
  1407. break;
  1408. }
  1409. res = write(con->fd, outbuf, res);
  1410. if (res < 1)
  1411. break;
  1412. }
  1413. }
  1414. ast_verb_console_unregister();
  1415. if (!ast_opt_hide_connect) {
  1416. ast_verb(3, "Remote UNIX connection disconnected\n");
  1417. }
  1418. close(con->fd);
  1419. close(con->p[0]);
  1420. close(con->p[1]);
  1421. con->fd = -1;
  1422. return NULL;
  1423. }
  1424. static void *listener(void *unused)
  1425. {
  1426. struct sockaddr_un sunaddr;
  1427. int s;
  1428. socklen_t len;
  1429. int x;
  1430. int poll_result;
  1431. struct pollfd fds[1];
  1432. for (;;) {
  1433. if (ast_socket < 0) {
  1434. return NULL;
  1435. }
  1436. fds[0].fd = ast_socket;
  1437. fds[0].events = POLLIN;
  1438. poll_result = ast_poll(fds, 1, -1);
  1439. pthread_testcancel();
  1440. if (poll_result < 0) {
  1441. if (errno != EINTR) {
  1442. ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
  1443. }
  1444. continue;
  1445. }
  1446. len = sizeof(sunaddr);
  1447. s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
  1448. if (s < 0) {
  1449. if (errno != EINTR)
  1450. ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
  1451. } else {
  1452. #if defined(SO_PASSCRED)
  1453. int sckopt = 1;
  1454. /* turn on socket credentials passing. */
  1455. if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt, sizeof(sckopt)) < 0) {
  1456. ast_log(LOG_WARNING, "Unable to turn on socket credentials passing\n");
  1457. close(s);
  1458. } else
  1459. #endif
  1460. {
  1461. for (x = 0; x < AST_MAX_CONNECTS; x++) {
  1462. if (consoles[x].fd >= 0) {
  1463. continue;
  1464. }
  1465. if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
  1466. ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
  1467. fdprint(s, "Server failed to create pipe\n");
  1468. close(s);
  1469. break;
  1470. }
  1471. ast_fd_set_flags(consoles[x].p[1], O_NONBLOCK);
  1472. consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
  1473. /* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able
  1474. to know if the user didn't send the credentials. */
  1475. consoles[x].uid = -2;
  1476. consoles[x].gid = -2;
  1477. /* Server default of remote console verbosity level is OFF. */
  1478. consoles[x].option_verbose = 0;
  1479. consoles[x].fd = s;
  1480. if (ast_pthread_create_detached_background(&consoles[x].t, NULL, netconsole, &consoles[x])) {
  1481. consoles[x].fd = -1;
  1482. ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
  1483. close(consoles[x].p[0]);
  1484. close(consoles[x].p[1]);
  1485. fdprint(s, "Server failed to spawn thread\n");
  1486. close(s);
  1487. }
  1488. break;
  1489. }
  1490. if (x >= AST_MAX_CONNECTS) {
  1491. fdprint(s, "No more connections allowed\n");
  1492. ast_log(LOG_WARNING, "No more connections allowed\n");
  1493. close(s);
  1494. } else if ((consoles[x].fd > -1) && (!ast_opt_hide_connect)) {
  1495. ast_verb(3, "Remote UNIX connection\n");
  1496. }
  1497. }
  1498. }
  1499. }
  1500. return NULL;
  1501. }
  1502. static int ast_makesocket(void)
  1503. {
  1504. struct sockaddr_un sunaddr;
  1505. int res;
  1506. int x;
  1507. uid_t uid = -1;
  1508. gid_t gid = -1;
  1509. for (x = 0; x < AST_MAX_CONNECTS; x++)
  1510. consoles[x].fd = -1;
  1511. unlink(ast_config_AST_SOCKET);
  1512. ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
  1513. if (ast_socket < 0) {
  1514. ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
  1515. return -1;
  1516. }
  1517. memset(&sunaddr, 0, sizeof(sunaddr));
  1518. sunaddr.sun_family = AF_LOCAL;
  1519. ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
  1520. res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
  1521. if (res) {
  1522. ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
  1523. close(ast_socket);
  1524. ast_socket = -1;
  1525. return -1;
  1526. }
  1527. res = listen(ast_socket, 2);
  1528. if (res < 0) {
  1529. ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
  1530. close(ast_socket);
  1531. ast_socket = -1;
  1532. return -1;
  1533. }
  1534. if (ast_register_verbose(network_verboser)) {
  1535. ast_log(LOG_WARNING, "Unable to register network verboser?\n");
  1536. }
  1537. if (ast_pthread_create_background(&lthread, NULL, listener, NULL)) {
  1538. ast_log(LOG_WARNING, "Unable to create listener thread.\n");
  1539. close(ast_socket);
  1540. return -1;
  1541. }
  1542. if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
  1543. struct passwd *pw;
  1544. if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL)
  1545. ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
  1546. else
  1547. uid = pw->pw_uid;
  1548. }
  1549. if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) {
  1550. struct group *grp;
  1551. if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL)
  1552. ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
  1553. else
  1554. gid = grp->gr_gid;
  1555. }
  1556. if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
  1557. ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
  1558. if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) {
  1559. unsigned int p1;
  1560. mode_t p;
  1561. sscanf(ast_config_AST_CTL_PERMISSIONS, "%30o", &p1);
  1562. p = p1;
  1563. if ((chmod(ast_config_AST_SOCKET, p)) < 0)
  1564. ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
  1565. }
  1566. return 0;
  1567. }
  1568. static int ast_tryconnect(void)
  1569. {
  1570. struct sockaddr_un sunaddr;
  1571. int res;
  1572. ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
  1573. if (ast_consock < 0) {
  1574. fprintf(stderr, "Unable to create socket: %s\n", strerror(errno));
  1575. return 0;
  1576. }
  1577. memset(&sunaddr, 0, sizeof(sunaddr));
  1578. sunaddr.sun_family = AF_LOCAL;
  1579. ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
  1580. res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
  1581. if (res) {
  1582. close(ast_consock);
  1583. ast_consock = -1;
  1584. return 0;
  1585. } else
  1586. return 1;
  1587. }
  1588. /*! \brief Urgent handler
  1589. *
  1590. * Called by soft_hangup to interrupt the poll, read, or other
  1591. * system call. We don't actually need to do anything though.
  1592. * Remember: Cannot EVER ast_log from within a signal handler
  1593. */
  1594. static void _urg_handler(int num)
  1595. {
  1596. return;
  1597. }
  1598. static struct sigaction urg_handler = {
  1599. .sa_handler = _urg_handler,
  1600. };
  1601. static void _hup_handler(int num)
  1602. {
  1603. int a = 0;
  1604. int save_errno = errno;
  1605. if (restartnow) {
  1606. if (el) {
  1607. el_end(el);
  1608. }
  1609. execvp(_argv[0], _argv);
  1610. }
  1611. printf("Received HUP signal -- Reloading configs\n");
  1612. sig_flags.need_reload = 1;
  1613. if (sig_alert_pipe[1] != -1) {
  1614. if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
  1615. fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
  1616. }
  1617. }
  1618. errno = save_errno;
  1619. }
  1620. static struct sigaction hup_handler = {
  1621. .sa_handler = _hup_handler,
  1622. .sa_flags = SA_RESTART,
  1623. };
  1624. static void _child_handler(int sig)
  1625. {
  1626. /* Must not ever ast_log or ast_verbose within signal handler */
  1627. int n, status, save_errno = errno;
  1628. /*
  1629. * Reap all dead children -- not just one
  1630. */
  1631. for (n = 0; waitpid(-1, &status, WNOHANG) > 0; n++)
  1632. ;
  1633. if (n == 0 && option_debug)
  1634. printf("Huh? Child handler, but nobody there?\n");
  1635. errno = save_errno;
  1636. }
  1637. static struct sigaction child_handler = {
  1638. .sa_handler = _child_handler,
  1639. .sa_flags = SA_RESTART,
  1640. };
  1641. /*! \brief Set an X-term or screen title */
  1642. static void set_title(char *text)
  1643. {
  1644. if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
  1645. fprintf(stdout, "\033]2;%s\007", text);
  1646. }
  1647. static void set_icon(char *text)
  1648. {
  1649. if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
  1650. fprintf(stdout, "\033]1;%s\007", text);
  1651. }
  1652. /*! \brief Check whether we were set to high(er) priority. */
  1653. static int has_priority(void)
  1654. {
  1655. /* Neither of these calls should fail with these arguments. */
  1656. #ifdef __linux__
  1657. /* For SCHED_OTHER, SCHED_BATCH and SCHED_IDLE, this will return
  1658. * 0. For the realtime priorities SCHED_RR and SCHED_FIFO, it
  1659. * will return something >= 1. */
  1660. return sched_getscheduler(0);
  1661. #else
  1662. /* getpriority() can return a value in -20..19 (or even -INF..20)
  1663. * where negative numbers are high priority. We don't bother
  1664. * checking errno. If the query fails and it returns -1, we'll
  1665. * assume that we're running at high prio; a safe assumption
  1666. * that will enable the resource starvation monitor (canary)
  1667. * just in case. */
  1668. return (getpriority(PRIO_PROCESS, 0) < 0);
  1669. #endif
  1670. }
  1671. /*! \brief Set priority on all known threads. */
  1672. static int set_priority_all(int pri)
  1673. {
  1674. #if !defined(__linux__)
  1675. /* The non-linux version updates the entire process prio. */
  1676. return ast_set_priority(pri);
  1677. #elif defined(LOW_MEMORY)
  1678. ast_log(LOG_WARNING, "Unable to enumerate all threads to update priority\n");
  1679. return ast_set_priority(pri);
  1680. #else
  1681. struct thread_list_t *cur;
  1682. struct sched_param sched;
  1683. char const *policy_str;
  1684. int policy;
  1685. memset(&sched, 0, sizeof(sched));
  1686. if (pri) {
  1687. policy = SCHED_RR;
  1688. policy_str = "realtime";
  1689. sched.sched_priority = 10;
  1690. } else {
  1691. policy = SCHED_OTHER;
  1692. policy_str = "regular";
  1693. sched.sched_priority = 0;
  1694. }
  1695. if (sched_setscheduler(getpid(), policy, &sched)) {
  1696. ast_log(LOG_WARNING, "Unable to set %s thread priority on main thread\n", policy_str);
  1697. return -1;
  1698. }
  1699. ast_verb(1, "Setting %s thread priority on all threads\n", policy_str);
  1700. AST_RWLIST_RDLOCK(&thread_list);
  1701. AST_RWLIST_TRAVERSE(&thread_list, cur, list) {
  1702. /* Don't care about the return value. It should work. */
  1703. sched_setscheduler(cur->lwp, policy, &sched);
  1704. }
  1705. AST_RWLIST_UNLOCK(&thread_list);
  1706. return 0;
  1707. #endif
  1708. }
  1709. /*! \brief We set ourselves to a high priority, that we might pre-empt
  1710. * everything else. If your PBX has heavy activity on it, this is a
  1711. * good thing.
  1712. */
  1713. int ast_set_priority(int pri)
  1714. {
  1715. struct sched_param sched;
  1716. memset(&sched, 0, sizeof(sched));
  1717. #ifdef __linux__
  1718. if (pri) {
  1719. sched.sched_priority = 10;
  1720. if (sched_setscheduler(0, SCHED_RR, &sched)) {
  1721. ast_log(LOG_WARNING, "Unable to set high priority\n");
  1722. return -1;
  1723. } else
  1724. ast_verb(1, "Set to realtime thread\n");
  1725. } else {
  1726. sched.sched_priority = 0;
  1727. /* According to the manpage, these parameters can never fail. */
  1728. sched_setscheduler(0, SCHED_OTHER, &sched);
  1729. }
  1730. #else
  1731. if (pri) {
  1732. if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
  1733. ast_log(LOG_WARNING, "Unable to set high priority\n");
  1734. return -1;
  1735. } else
  1736. ast_verb(1, "Set to high priority\n");
  1737. } else {
  1738. /* According to the manpage, these parameters can never fail. */
  1739. setpriority(PRIO_PROCESS, 0, 0);
  1740. }
  1741. #endif
  1742. return 0;
  1743. }
  1744. int ast_shutdown_final(void)
  1745. {
  1746. return shuttingdown == SHUTTING_DOWN_FINAL;
  1747. }
  1748. int ast_shutting_down(void)
  1749. {
  1750. return shutdown_pending;
  1751. }
  1752. int ast_cancel_shutdown(void)
  1753. {
  1754. int shutdown_aborted = 0;
  1755. ast_mutex_lock(&safe_system_lock);
  1756. if (shuttingdown >= SHUTDOWN_FAST) {
  1757. shuttingdown = NOT_SHUTTING_DOWN;
  1758. shutdown_pending = 0;
  1759. shutdown_aborted = 1;
  1760. }
  1761. ast_mutex_unlock(&safe_system_lock);
  1762. return shutdown_aborted;
  1763. }
  1764. /*!
  1765. * \internal
  1766. * \brief Initiate system shutdown -- prevents new channels from being allocated.
  1767. */
  1768. static void ast_begin_shutdown(void)
  1769. {
  1770. ast_mutex_lock(&safe_system_lock);
  1771. if (shuttingdown != NOT_SHUTTING_DOWN) {
  1772. shutdown_pending = 1;
  1773. }
  1774. ast_mutex_unlock(&safe_system_lock);
  1775. }
  1776. static int can_safely_quit(shutdown_nice_t niceness, int restart);
  1777. static void really_quit(int num, shutdown_nice_t niceness, int restart);
  1778. static void quit_handler(int num, shutdown_nice_t niceness, int restart)
  1779. {
  1780. if (can_safely_quit(niceness, restart)) {
  1781. really_quit(num, niceness, restart);
  1782. /* No one gets here. */
  1783. }
  1784. /* It wasn't our time. */
  1785. }
  1786. #define SHUTDOWN_TIMEOUT 15 /* Seconds */
  1787. /*!
  1788. * \internal
  1789. * \brief Wait for all channels to die, a timeout, or shutdown cancelled.
  1790. * \since 13.3.0
  1791. *
  1792. * \param niceness Shutdown niceness in effect
  1793. * \param seconds Number of seconds to wait or less than zero if indefinitely.
  1794. *
  1795. * \retval zero if waiting wasn't necessary. We were idle.
  1796. * \retval non-zero if we had to wait.
  1797. */
  1798. static int wait_for_channels_to_die(shutdown_nice_t niceness, int seconds)
  1799. {
  1800. time_t start;
  1801. time_t now;
  1802. int waited = 0;
  1803. time(&start);
  1804. for (;;) {
  1805. if (!ast_undestroyed_channels() || shuttingdown != niceness) {
  1806. break;
  1807. }
  1808. if (seconds < 0) {
  1809. /* No timeout so just poll every second */
  1810. sleep(1);
  1811. } else {
  1812. time(&now);
  1813. /* Wait up to the given seconds for all channels to go away */
  1814. if (seconds < (now - start)) {
  1815. break;
  1816. }
  1817. /* Sleep 1/10 of a second */
  1818. usleep(100000);
  1819. }
  1820. waited = 1;
  1821. }
  1822. return waited;
  1823. }
  1824. static int can_safely_quit(shutdown_nice_t niceness, int restart)
  1825. {
  1826. int waited = 0;
  1827. /* Check if someone else isn't already doing this. */
  1828. ast_mutex_lock(&safe_system_lock);
  1829. if (shuttingdown != NOT_SHUTTING_DOWN && niceness >= shuttingdown) {
  1830. /* Already in progress and other request was less nice. */
  1831. ast_mutex_unlock(&safe_system_lock);
  1832. ast_verbose("Ignoring asterisk %s request, already in progress.\n", restart ? "restart" : "shutdown");
  1833. return 0;
  1834. }
  1835. shuttingdown = niceness;
  1836. ast_mutex_unlock(&safe_system_lock);
  1837. /* Try to get as many CDRs as possible submitted to the backend engines
  1838. * (if in batch mode). really_quit happens to call it again when running
  1839. * the atexit handlers, otherwise this would be a bit early. */
  1840. ast_cdr_engine_term();
  1841. /*
  1842. * Shutdown the message queue for the technology agnostic message channel.
  1843. * This has to occur before we pause shutdown pending ast_undestroyed_channels.
  1844. *
  1845. * XXX This is not reversed on shutdown cancel.
  1846. */
  1847. ast_msg_shutdown();
  1848. if (niceness == SHUTDOWN_NORMAL) {
  1849. /* Begin shutdown routine, hanging up active channels */
  1850. ast_begin_shutdown();
  1851. if (ast_opt_console) {
  1852. ast_verb(0, "Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
  1853. }
  1854. ast_softhangup_all();
  1855. waited |= wait_for_channels_to_die(niceness, SHUTDOWN_TIMEOUT);
  1856. } else if (niceness >= SHUTDOWN_NICE) {
  1857. if (niceness != SHUTDOWN_REALLY_NICE) {
  1858. ast_begin_shutdown();
  1859. }
  1860. if (ast_opt_console) {
  1861. ast_verb(0, "Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
  1862. }
  1863. waited |= wait_for_channels_to_die(niceness, -1);
  1864. }
  1865. /* Re-acquire lock and check if someone changed the niceness, in which
  1866. * case someone else has taken over the shutdown.
  1867. */
  1868. ast_mutex_lock(&safe_system_lock);
  1869. if (shuttingdown != niceness) {
  1870. if (shuttingdown == NOT_SHUTTING_DOWN && ast_opt_console) {
  1871. ast_verb(0, "Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
  1872. }
  1873. ast_mutex_unlock(&safe_system_lock);
  1874. return 0;
  1875. }
  1876. if (niceness >= SHUTDOWN_REALLY_NICE) {
  1877. shuttingdown = SHUTTING_DOWN;
  1878. ast_mutex_unlock(&safe_system_lock);
  1879. /* No more Mr. Nice guy. We are committed to shutting down now. */
  1880. ast_begin_shutdown();
  1881. ast_softhangup_all();
  1882. waited |= wait_for_channels_to_die(SHUTTING_DOWN, SHUTDOWN_TIMEOUT);
  1883. ast_mutex_lock(&safe_system_lock);
  1884. }
  1885. shuttingdown = SHUTTING_DOWN_FINAL;
  1886. ast_mutex_unlock(&safe_system_lock);
  1887. if (niceness >= SHUTDOWN_NORMAL && waited) {
  1888. /*
  1889. * We were not idle. Give things in progress a chance to
  1890. * recognize the final shutdown phase.
  1891. */
  1892. sleep(1);
  1893. }
  1894. return 1;
  1895. }
  1896. /*! Called when exiting is certain. */
  1897. static void really_quit(int num, shutdown_nice_t niceness, int restart)
  1898. {
  1899. int active_channels;
  1900. struct ast_json *json_object = NULL;
  1901. int run_cleanups = niceness >= SHUTDOWN_NICE;
  1902. if (run_cleanups && modules_shutdown()) {
  1903. ast_verb(0, "Some modules could not be unloaded, switching to fast shutdown\n");
  1904. run_cleanups = 0;
  1905. }
  1906. if (!restart) {
  1907. ast_sd_notify("STOPPING=1");
  1908. }
  1909. if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) {
  1910. ast_el_write_default_histfile();
  1911. if (consolethread == AST_PTHREADT_NULL || consolethread == pthread_self()) {
  1912. /* Only end if we are the consolethread, otherwise there's a race with that thread. */
  1913. if (el != NULL) {
  1914. el_end(el);
  1915. }
  1916. if (el_hist != NULL) {
  1917. history_end(el_hist);
  1918. }
  1919. } else if (!restart) {
  1920. sig_flags.need_el_end = 1;
  1921. pthread_kill(consolethread, SIGURG);
  1922. }
  1923. }
  1924. active_channels = ast_active_channels();
  1925. /* Don't publish messages if we're a remote console - we won't have all of the Stasis
  1926. * topics or message types
  1927. */
  1928. if (!ast_opt_remote) {
  1929. json_object = ast_json_pack("{s: s, s: s}",
  1930. "Shutdown", active_channels ? "Uncleanly" : "Cleanly",
  1931. "Restart", restart ? "True" : "False");
  1932. ast_manager_publish_event("Shutdown", EVENT_FLAG_SYSTEM, json_object);
  1933. ast_json_unref(json_object);
  1934. json_object = NULL;
  1935. }
  1936. ast_verb(0, "Asterisk %s ending (%d).\n",
  1937. active_channels ? "uncleanly" : "cleanly", num);
  1938. ast_verb(0, "Executing last minute cleanups\n");
  1939. ast_run_atexits(run_cleanups);
  1940. ast_debug(1, "Asterisk ending (%d).\n", num);
  1941. if (ast_socket > -1) {
  1942. pthread_cancel(lthread);
  1943. close(ast_socket);
  1944. ast_socket = -1;
  1945. unlink(ast_config_AST_SOCKET);
  1946. pthread_kill(lthread, SIGURG);
  1947. pthread_join(lthread, NULL);
  1948. }
  1949. if (ast_consock > -1)
  1950. close(ast_consock);
  1951. if (!ast_opt_remote)
  1952. unlink(ast_config_AST_PID);
  1953. if (sig_alert_pipe[0])
  1954. close(sig_alert_pipe[0]);
  1955. if (sig_alert_pipe[1])
  1956. close(sig_alert_pipe[1]);
  1957. printf("%s", term_quit());
  1958. if (restart) {
  1959. int i;
  1960. ast_verb(0, "Preparing for Asterisk restart...\n");
  1961. /* Mark all FD's for closing on exec */
  1962. for (i = 3; i < 32768; i++) {
  1963. fcntl(i, F_SETFD, FD_CLOEXEC);
  1964. }
  1965. ast_verb(0, "Asterisk is now restarting...\n");
  1966. restartnow = 1;
  1967. /* close logger */
  1968. close_logger();
  1969. clean_time_zones();
  1970. /* If there is a consolethread running send it a SIGHUP
  1971. so it can execvp, otherwise we can do it ourselves */
  1972. if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
  1973. pthread_kill(consolethread, SIGHUP);
  1974. /* Give the signal handler some time to complete */
  1975. sleep(2);
  1976. } else
  1977. execvp(_argv[0], _argv);
  1978. } else {
  1979. /* close logger */
  1980. close_logger();
  1981. clean_time_zones();
  1982. }
  1983. exit(0);
  1984. }
  1985. static void __quit_handler(int num)
  1986. {
  1987. int a = 0;
  1988. sig_flags.need_quit = 1;
  1989. if (sig_alert_pipe[1] != -1) {
  1990. if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
  1991. fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
  1992. }
  1993. }
  1994. /* There is no need to restore the signal handler here, since the app
  1995. * is going to exit */
  1996. }
  1997. static void __remote_quit_handler(int num)
  1998. {
  1999. sig_flags.need_quit = 1;
  2000. }
  2001. static void set_header(char *outbuf, int maxout, char level)
  2002. {
  2003. const char *cmp;
  2004. char date[40];
  2005. switch (level) {
  2006. case 0: cmp = NULL;
  2007. break;
  2008. case 1: cmp = VERBOSE_PREFIX_1;
  2009. break;
  2010. case 2: cmp = VERBOSE_PREFIX_2;
  2011. break;
  2012. case 3: cmp = VERBOSE_PREFIX_3;
  2013. break;
  2014. default: cmp = VERBOSE_PREFIX_4;
  2015. break;
  2016. }
  2017. if (ast_opt_timestamp) {
  2018. struct ast_tm tm;
  2019. struct timeval now = ast_tvnow();
  2020. ast_localtime(&now, &tm, NULL);
  2021. ast_strftime(date, sizeof(date), ast_logger_get_dateformat(), &tm);
  2022. }
  2023. snprintf(outbuf, maxout, "%s%s%s%s%s%s",
  2024. ast_opt_timestamp ? "[" : "",
  2025. ast_opt_timestamp ? date : "",
  2026. ast_opt_timestamp ? "] " : "",
  2027. cmp ? ast_term_color(COLOR_GRAY, 0) : "",
  2028. cmp ? cmp : "",
  2029. cmp ? ast_term_reset() : "");
  2030. }
  2031. struct console_state_data {
  2032. char verbose_line_level;
  2033. };
  2034. static int console_state_init(void *ptr)
  2035. {
  2036. struct console_state_data *state = ptr;
  2037. state->verbose_line_level = 0;
  2038. return 0;
  2039. }
  2040. AST_THREADSTORAGE_CUSTOM(console_state, console_state_init, ast_free_ptr);
  2041. static int console_print(const char *s, int local)
  2042. {
  2043. struct console_state_data *state =
  2044. ast_threadstorage_get(&console_state, sizeof(*state));
  2045. char prefix[80];
  2046. const char *c;
  2047. int num, res = 0;
  2048. unsigned int newline;
  2049. do {
  2050. if (VERBOSE_HASMAGIC(s)) {
  2051. /* always use the given line's level, otherwise
  2052. we'll use the last line's level */
  2053. state->verbose_line_level = VERBOSE_MAGIC2LEVEL(s);
  2054. /* move past magic */
  2055. s++;
  2056. set_header(prefix, sizeof(prefix), state->verbose_line_level);
  2057. } else {
  2058. *prefix = '\0';
  2059. }
  2060. c = s;
  2061. /* for a given line separate on verbose magic, newline, and eol */
  2062. if ((s = strchr(c, '\n'))) {
  2063. ++s;
  2064. newline = 1;
  2065. } else {
  2066. s = strchr(c, '\0');
  2067. newline = 0;
  2068. }
  2069. /* check if we should write this line after calculating begin/end
  2070. so we process the case of a higher level line embedded within
  2071. two lower level lines */
  2072. if (state->verbose_line_level > option_verbose) {
  2073. continue;
  2074. }
  2075. if (!ast_strlen_zero(prefix)) {
  2076. fputs(prefix, stdout);
  2077. }
  2078. num = s - c;
  2079. if (fwrite(c, sizeof(char), num, stdout) < num) {
  2080. break;
  2081. }
  2082. if (!res) {
  2083. /* if at least some info has been written
  2084. we'll want to return true */
  2085. res = 1;
  2086. }
  2087. } while (*s);
  2088. if (newline) {
  2089. /* if ending on a newline then reset last level to zero
  2090. since what follows may be not be logging output */
  2091. state->verbose_line_level = 0;
  2092. }
  2093. if (res) {
  2094. fflush(stdout);
  2095. }
  2096. return res;
  2097. }
  2098. static void console_verboser(const char *s)
  2099. {
  2100. if (!console_print(s, 1)) {
  2101. return;
  2102. }
  2103. /* Wake up a poll()ing console */
  2104. if (ast_opt_console && consolethread != AST_PTHREADT_NULL) {
  2105. pthread_kill(consolethread, SIGURG);
  2106. }
  2107. }
  2108. static int ast_all_zeros(const char *s)
  2109. {
  2110. while (*s) {
  2111. if (*s > 32)
  2112. return 0;
  2113. s++;
  2114. }
  2115. return 1;
  2116. }
  2117. /* This is the main console CLI command handler. Run by the main() thread. */
  2118. static void consolehandler(const char *s)
  2119. {
  2120. printf("%s", term_end());
  2121. fflush(stdout);
  2122. /* Called when readline data is available */
  2123. if (!ast_all_zeros(s))
  2124. ast_el_add_history(s);
  2125. /* The real handler for bang */
  2126. if (s[0] == '!') {
  2127. if (s[1])
  2128. ast_safe_system(s+1);
  2129. else
  2130. ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
  2131. } else
  2132. ast_cli_command(STDOUT_FILENO, s);
  2133. }
  2134. static int remoteconsolehandler(const char *s)
  2135. {
  2136. int ret = 0;
  2137. /* Called when readline data is available */
  2138. if (!ast_all_zeros(s))
  2139. ast_el_add_history(s);
  2140. while (isspace(*s)) {
  2141. s++;
  2142. }
  2143. /* The real handler for bang */
  2144. if (s[0] == '!') {
  2145. if (s[1])
  2146. ast_safe_system(s+1);
  2147. else
  2148. ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
  2149. ret = 1;
  2150. } else if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
  2151. (s[4] == '\0' || isspace(s[4]))) {
  2152. quit_handler(0, SHUTDOWN_FAST, 0);
  2153. ret = 1;
  2154. }
  2155. return ret;
  2156. }
  2157. static char *handle_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  2158. {
  2159. switch (cmd) {
  2160. case CLI_INIT:
  2161. e->command = "core show version";
  2162. e->usage =
  2163. "Usage: core show version\n"
  2164. " Shows Asterisk version information.\n";
  2165. return NULL;
  2166. case CLI_GENERATE:
  2167. return NULL;
  2168. }
  2169. if (a->argc != 3)
  2170. return CLI_SHOWUSAGE;
  2171. ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
  2172. ast_get_version(), ast_build_user, ast_build_hostname,
  2173. ast_build_machine, ast_build_os, ast_build_date);
  2174. return CLI_SUCCESS;
  2175. }
  2176. static char *handle_stop_now(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  2177. {
  2178. switch (cmd) {
  2179. case CLI_INIT:
  2180. e->command = "core stop now";
  2181. e->usage =
  2182. "Usage: core stop now\n"
  2183. " Shuts down a running Asterisk immediately, hanging up all active calls .\n";
  2184. ast_cli_allow_at_shutdown(e);
  2185. return NULL;
  2186. case CLI_GENERATE:
  2187. return NULL;
  2188. }
  2189. if (a->argc != e->args)
  2190. return CLI_SHOWUSAGE;
  2191. quit_handler(0, SHUTDOWN_NORMAL, 0 /* not restart */);
  2192. return CLI_SUCCESS;
  2193. }
  2194. static char *handle_stop_gracefully(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  2195. {
  2196. switch (cmd) {
  2197. case CLI_INIT:
  2198. e->command = "core stop gracefully";
  2199. e->usage =
  2200. "Usage: core stop gracefully\n"
  2201. " Causes Asterisk to not accept new calls, and exit when all\n"
  2202. " active calls have terminated normally.\n";
  2203. ast_cli_allow_at_shutdown(e);
  2204. return NULL;
  2205. case CLI_GENERATE:
  2206. return NULL;
  2207. }
  2208. if (a->argc != e->args)
  2209. return CLI_SHOWUSAGE;
  2210. quit_handler(0, SHUTDOWN_NICE, 0 /* no restart */);
  2211. return CLI_SUCCESS;
  2212. }
  2213. static char *handle_stop_when_convenient(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  2214. {
  2215. switch (cmd) {
  2216. case CLI_INIT:
  2217. e->command = "core stop when convenient";
  2218. e->usage =
  2219. "Usage: core stop when convenient\n"
  2220. " Causes Asterisk to perform a shutdown when all active calls have ended.\n";
  2221. ast_cli_allow_at_shutdown(e);
  2222. return NULL;
  2223. case CLI_GENERATE:
  2224. return NULL;
  2225. }
  2226. if (a->argc != e->args)
  2227. return CLI_SHOWUSAGE;
  2228. ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
  2229. quit_handler(0, SHUTDOWN_REALLY_NICE, 0 /* don't restart */);
  2230. return CLI_SUCCESS;
  2231. }
  2232. static char *handle_restart_now(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  2233. {
  2234. switch (cmd) {
  2235. case CLI_INIT:
  2236. e->command = "core restart now";
  2237. e->usage =
  2238. "Usage: core restart now\n"
  2239. " Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
  2240. " restart.\n";
  2241. ast_cli_allow_at_shutdown(e);
  2242. return NULL;
  2243. case CLI_GENERATE:
  2244. return NULL;
  2245. }
  2246. if (a->argc != e->args)
  2247. return CLI_SHOWUSAGE;
  2248. quit_handler(0, SHUTDOWN_NORMAL, 1 /* restart */);
  2249. return CLI_SUCCESS;
  2250. }
  2251. static char *handle_restart_gracefully(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  2252. {
  2253. switch (cmd) {
  2254. case CLI_INIT:
  2255. e->command = "core restart gracefully";
  2256. e->usage =
  2257. "Usage: core restart gracefully\n"
  2258. " Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
  2259. " restart when all active calls have ended.\n";
  2260. ast_cli_allow_at_shutdown(e);
  2261. return NULL;
  2262. case CLI_GENERATE:
  2263. return NULL;
  2264. }
  2265. if (a->argc != e->args)
  2266. return CLI_SHOWUSAGE;
  2267. quit_handler(0, SHUTDOWN_NICE, 1 /* restart */);
  2268. return CLI_SUCCESS;
  2269. }
  2270. static char *handle_restart_when_convenient(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  2271. {
  2272. switch (cmd) {
  2273. case CLI_INIT:
  2274. e->command = "core restart when convenient";
  2275. e->usage =
  2276. "Usage: core restart when convenient\n"
  2277. " Causes Asterisk to perform a cold restart when all active calls have ended.\n";
  2278. ast_cli_allow_at_shutdown(e);
  2279. return NULL;
  2280. case CLI_GENERATE:
  2281. return NULL;
  2282. }
  2283. if (a->argc != e->args)
  2284. return CLI_SHOWUSAGE;
  2285. ast_cli(a->fd, "Waiting for inactivity to perform restart\n");
  2286. quit_handler(0, SHUTDOWN_REALLY_NICE, 1 /* restart */);
  2287. return CLI_SUCCESS;
  2288. }
  2289. static char *handle_abort_shutdown(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  2290. {
  2291. switch (cmd) {
  2292. case CLI_INIT:
  2293. e->command = "core abort shutdown";
  2294. e->usage =
  2295. "Usage: core abort shutdown\n"
  2296. " Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
  2297. " call operations.\n";
  2298. ast_cli_allow_at_shutdown(e);
  2299. return NULL;
  2300. case CLI_GENERATE:
  2301. return NULL;
  2302. }
  2303. if (a->argc != e->args)
  2304. return CLI_SHOWUSAGE;
  2305. ast_cancel_shutdown();
  2306. return CLI_SUCCESS;
  2307. }
  2308. static char *handle_bang(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  2309. {
  2310. switch (cmd) {
  2311. case CLI_INIT:
  2312. e->command = "!";
  2313. e->usage =
  2314. "Usage: !<command>\n"
  2315. " Executes a given shell command\n";
  2316. return NULL;
  2317. case CLI_GENERATE:
  2318. return NULL;
  2319. }
  2320. return CLI_SUCCESS;
  2321. }
  2322. static const char warranty_lines[] = {
  2323. "\n"
  2324. " NO WARRANTY\n"
  2325. "\n"
  2326. "BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n"
  2327. "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n"
  2328. "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n"
  2329. "PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n"
  2330. "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
  2331. "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n"
  2332. "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n"
  2333. "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n"
  2334. "REPAIR OR CORRECTION.\n"
  2335. "\n"
  2336. "IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n"
  2337. "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n"
  2338. "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n"
  2339. "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n"
  2340. "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n"
  2341. "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n"
  2342. "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n"
  2343. "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n"
  2344. "POSSIBILITY OF SUCH DAMAGES.\n"
  2345. };
  2346. static char *show_warranty(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  2347. {
  2348. switch (cmd) {
  2349. case CLI_INIT:
  2350. e->command = "core show warranty";
  2351. e->usage =
  2352. "Usage: core show warranty\n"
  2353. " Shows the warranty (if any) for this copy of Asterisk.\n";
  2354. return NULL;
  2355. case CLI_GENERATE:
  2356. return NULL;
  2357. }
  2358. ast_cli(a->fd, "%s", warranty_lines);
  2359. return CLI_SUCCESS;
  2360. }
  2361. static const char license_lines[] = {
  2362. "\n"
  2363. "This program is free software; you can redistribute it and/or modify\n"
  2364. "it under the terms of the GNU General Public License version 2 as\n"
  2365. "published by the Free Software Foundation.\n"
  2366. "\n"
  2367. "This program also contains components licensed under other licenses.\n"
  2368. "They include:\n"
  2369. "\n"
  2370. "This program is distributed in the hope that it will be useful,\n"
  2371. "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
  2372. "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
  2373. "GNU General Public License for more details.\n"
  2374. "\n"
  2375. "You should have received a copy of the GNU General Public License\n"
  2376. "along with this program; if not, write to the Free Software\n"
  2377. "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n"
  2378. };
  2379. static char *show_license(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  2380. {
  2381. switch (cmd) {
  2382. case CLI_INIT:
  2383. e->command = "core show license";
  2384. e->usage =
  2385. "Usage: core show license\n"
  2386. " Shows the license(s) for this copy of Asterisk.\n";
  2387. return NULL;
  2388. case CLI_GENERATE:
  2389. return NULL;
  2390. }
  2391. ast_cli(a->fd, "%s", license_lines);
  2392. return CLI_SUCCESS;
  2393. }
  2394. #define ASTERISK_PROMPT "*CLI> "
  2395. /*!
  2396. * \brief Shutdown Asterisk CLI commands.
  2397. *
  2398. * \note These CLI commands cannot be unregistered at shutdown
  2399. * because one of them is likely the reason for the shutdown.
  2400. * The CLI generates a warning if a command is in-use when it is
  2401. * unregistered.
  2402. */
  2403. static struct ast_cli_entry cli_asterisk_shutdown[] = {
  2404. AST_CLI_DEFINE(handle_stop_now, "Shut down Asterisk immediately"),
  2405. AST_CLI_DEFINE(handle_stop_gracefully, "Gracefully shut down Asterisk"),
  2406. AST_CLI_DEFINE(handle_stop_when_convenient, "Shut down Asterisk at empty call volume"),
  2407. AST_CLI_DEFINE(handle_restart_now, "Restart Asterisk immediately"),
  2408. AST_CLI_DEFINE(handle_restart_gracefully, "Restart Asterisk gracefully"),
  2409. AST_CLI_DEFINE(handle_restart_when_convenient, "Restart Asterisk at empty call volume"),
  2410. };
  2411. static struct ast_cli_entry cli_asterisk[] = {
  2412. AST_CLI_DEFINE(handle_abort_shutdown, "Cancel a running shutdown"),
  2413. AST_CLI_DEFINE(show_warranty, "Show the warranty (if any) for this copy of Asterisk"),
  2414. AST_CLI_DEFINE(show_license, "Show the license(s) for this copy of Asterisk"),
  2415. AST_CLI_DEFINE(handle_version, "Display version info"),
  2416. AST_CLI_DEFINE(handle_bang, "Execute a shell command"),
  2417. #if !defined(LOW_MEMORY)
  2418. AST_CLI_DEFINE(handle_show_version_files, "List versions of files used to build Asterisk"),
  2419. AST_CLI_DEFINE(handle_show_threads, "Show running threads"),
  2420. #if defined(HAVE_SYSINFO) || defined(HAVE_SYSCTL)
  2421. AST_CLI_DEFINE(handle_show_sysinfo, "Show System Information"),
  2422. #endif
  2423. AST_CLI_DEFINE(handle_show_profile, "Display profiling info"),
  2424. AST_CLI_DEFINE(handle_show_settings, "Show some core settings"),
  2425. AST_CLI_DEFINE(handle_clear_profile, "Clear profiling info"),
  2426. #endif /* ! LOW_MEMORY */
  2427. };
  2428. static void send_rasterisk_connect_commands(void)
  2429. {
  2430. char buf[80];
  2431. /*
  2432. * Tell the server asterisk instance about the verbose level
  2433. * initially desired.
  2434. */
  2435. if (option_verbose) {
  2436. snprintf(buf, sizeof(buf), "core set verbose atleast %d silent", option_verbose);
  2437. fdsend(ast_consock, buf);
  2438. }
  2439. if (option_debug) {
  2440. snprintf(buf, sizeof(buf), "core set debug atleast %d", option_debug);
  2441. fdsend(ast_consock, buf);
  2442. }
  2443. /* Leave verbose filtering to the server. */
  2444. option_verbose = INT_MAX;
  2445. if (!ast_opt_mute) {
  2446. fdsend(ast_consock, "logger mute silent");
  2447. } else {
  2448. printf("log and verbose output currently muted ('logger mute' to unmute)\n");
  2449. }
  2450. }
  2451. #ifdef HAVE_LIBEDIT_IS_UNICODE
  2452. #define CHAR_T_LIBEDIT wchar_t
  2453. #define CHAR_TO_LIBEDIT(c) btowc(c)
  2454. #else
  2455. #define CHAR_T_LIBEDIT char
  2456. #define CHAR_TO_LIBEDIT(c) c
  2457. #endif
  2458. static int ast_el_read_char(EditLine *editline, CHAR_T_LIBEDIT *cp)
  2459. {
  2460. int num_read = 0;
  2461. int lastpos = 0;
  2462. struct pollfd fds[2];
  2463. int res;
  2464. int max;
  2465. #define EL_BUF_SIZE 512
  2466. char buf[EL_BUF_SIZE];
  2467. for (;;) {
  2468. max = 1;
  2469. fds[0].fd = ast_consock;
  2470. fds[0].events = POLLIN;
  2471. if (!ast_opt_exec) {
  2472. fds[1].fd = STDIN_FILENO;
  2473. fds[1].events = POLLIN;
  2474. max++;
  2475. }
  2476. res = ast_poll(fds, max, -1);
  2477. if (res < 0) {
  2478. if (sig_flags.need_quit || sig_flags.need_quit_handler || sig_flags.need_el_end) {
  2479. break;
  2480. }
  2481. if (errno == EINTR) {
  2482. continue;
  2483. }
  2484. fprintf(stderr, "poll failed: %s\n", strerror(errno));
  2485. break;
  2486. }
  2487. if (!ast_opt_exec && fds[1].revents) {
  2488. char c = '\0';
  2489. num_read = read(STDIN_FILENO, &c, 1);
  2490. if (num_read < 1) {
  2491. break;
  2492. }
  2493. *cp = CHAR_TO_LIBEDIT(c);
  2494. return num_read;
  2495. }
  2496. if (fds[0].revents) {
  2497. res = read(ast_consock, buf, sizeof(buf) - 1);
  2498. /* if the remote side disappears exit */
  2499. if (res < 1) {
  2500. fprintf(stderr, "\nDisconnected from Asterisk server\n");
  2501. if (!ast_opt_reconnect) {
  2502. quit_handler(0, SHUTDOWN_FAST, 0);
  2503. } else {
  2504. int tries;
  2505. int reconnects_per_second = 20;
  2506. fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
  2507. for (tries = 0; tries < 30 * reconnects_per_second; tries++) {
  2508. if (ast_tryconnect()) {
  2509. fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
  2510. printf("%s", term_quit());
  2511. WELCOME_MESSAGE;
  2512. send_rasterisk_connect_commands();
  2513. break;
  2514. }
  2515. usleep(1000000 / reconnects_per_second);
  2516. }
  2517. if (tries >= 30 * reconnects_per_second) {
  2518. fprintf(stderr, "Failed to reconnect for 30 seconds. Quitting.\n");
  2519. quit_handler(0, SHUTDOWN_FAST, 0);
  2520. }
  2521. }
  2522. continue;
  2523. }
  2524. buf[res] = '\0';
  2525. /* Write over the CLI prompt */
  2526. if (!ast_opt_exec && !lastpos) {
  2527. if (write(STDOUT_FILENO, "\r", 5) < 0) {
  2528. }
  2529. }
  2530. console_print(buf, 0);
  2531. if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (res >= 2 && buf[res-2] == '\n'))) {
  2532. *cp = CHAR_TO_LIBEDIT(CC_REFRESH);
  2533. return 1;
  2534. }
  2535. lastpos = 1;
  2536. }
  2537. }
  2538. *cp = CHAR_TO_LIBEDIT('\0');
  2539. return 0;
  2540. }
  2541. static struct ast_str *prompt = NULL;
  2542. static char *cli_prompt(EditLine *editline)
  2543. {
  2544. char tmp[100];
  2545. char *pfmt;
  2546. int color_used = 0;
  2547. static int cli_prompt_changes = 0;
  2548. struct passwd *pw;
  2549. struct group *gr;
  2550. if (prompt == NULL) {
  2551. prompt = ast_str_create(100);
  2552. } else if (!cli_prompt_changes) {
  2553. return ast_str_buffer(prompt);
  2554. } else {
  2555. ast_str_reset(prompt);
  2556. }
  2557. if ((pfmt = getenv("ASTERISK_PROMPT"))) {
  2558. char *t = pfmt;
  2559. struct timeval ts = ast_tvnow();
  2560. while (*t != '\0') {
  2561. if (*t == '%') {
  2562. char hostname[MAXHOSTNAMELEN] = "";
  2563. int i, which;
  2564. struct ast_tm tm = { 0, };
  2565. int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
  2566. t++;
  2567. switch (*t) {
  2568. case 'C': /* color */
  2569. t++;
  2570. if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
  2571. ast_term_color_code(&prompt, fgcolor, bgcolor);
  2572. t += i - 1;
  2573. } else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) {
  2574. ast_term_color_code(&prompt, fgcolor, 0);
  2575. t += i - 1;
  2576. }
  2577. /* If the color has been reset correctly, then there's no need to reset it later */
  2578. color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1;
  2579. break;
  2580. case 'd': /* date */
  2581. if (ast_localtime(&ts, &tm, NULL)) {
  2582. ast_strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm);
  2583. ast_str_append(&prompt, 0, "%s", tmp);
  2584. cli_prompt_changes++;
  2585. }
  2586. break;
  2587. case 'g': /* group */
  2588. if ((gr = getgrgid(getgid()))) {
  2589. ast_str_append(&prompt, 0, "%s", gr->gr_name);
  2590. }
  2591. break;
  2592. case 'h': /* hostname */
  2593. if (!gethostname(hostname, sizeof(hostname) - 1)) {
  2594. ast_str_append(&prompt, 0, "%s", hostname);
  2595. } else {
  2596. ast_str_append(&prompt, 0, "%s", "localhost");
  2597. }
  2598. break;
  2599. case 'H': /* short hostname */
  2600. if (!gethostname(hostname, sizeof(hostname) - 1)) {
  2601. char *dotptr;
  2602. if ((dotptr = strchr(hostname, '.'))) {
  2603. *dotptr = '\0';
  2604. }
  2605. ast_str_append(&prompt, 0, "%s", hostname);
  2606. } else {
  2607. ast_str_append(&prompt, 0, "%s", "localhost");
  2608. }
  2609. break;
  2610. #ifdef HAVE_GETLOADAVG
  2611. case 'l': /* load avg */
  2612. t++;
  2613. if (sscanf(t, "%30d", &which) == 1 && which > 0 && which <= 3) {
  2614. double list[3];
  2615. getloadavg(list, 3);
  2616. ast_str_append(&prompt, 0, "%.2f", list[which - 1]);
  2617. cli_prompt_changes++;
  2618. }
  2619. break;
  2620. #endif
  2621. case 's': /* Asterisk system name (from asterisk.conf) */
  2622. ast_str_append(&prompt, 0, "%s", ast_config_AST_SYSTEM_NAME);
  2623. break;
  2624. case 't': /* time */
  2625. if (ast_localtime(&ts, &tm, NULL)) {
  2626. ast_strftime(tmp, sizeof(tmp), "%H:%M:%S", &tm);
  2627. ast_str_append(&prompt, 0, "%s", tmp);
  2628. cli_prompt_changes++;
  2629. }
  2630. break;
  2631. case 'u': /* username */
  2632. if ((pw = getpwuid(getuid()))) {
  2633. ast_str_append(&prompt, 0, "%s", pw->pw_name);
  2634. }
  2635. break;
  2636. case '#': /* process console or remote? */
  2637. ast_str_append(&prompt, 0, "%c", ast_opt_remote ? '>' : '#');
  2638. break;
  2639. case '%': /* literal % */
  2640. ast_str_append(&prompt, 0, "%c", '%');
  2641. break;
  2642. case '\0': /* % is last character - prevent bug */
  2643. t--;
  2644. break;
  2645. }
  2646. } else {
  2647. ast_str_append(&prompt, 0, "%c", *t);
  2648. }
  2649. t++;
  2650. }
  2651. if (color_used) {
  2652. /* Force colors back to normal at end */
  2653. ast_term_color_code(&prompt, 0, 0);
  2654. }
  2655. } else {
  2656. ast_str_set(&prompt, 0, "%s%s",
  2657. remotehostname ? remotehostname : "",
  2658. ASTERISK_PROMPT);
  2659. }
  2660. return ast_str_buffer(prompt);
  2661. }
  2662. static struct ast_vector_string *ast_el_strtoarr(char *buf)
  2663. {
  2664. char *retstr;
  2665. char *bestmatch;
  2666. struct ast_vector_string *vec = ast_calloc(1, sizeof(*vec));
  2667. if (!vec) {
  2668. return NULL;
  2669. }
  2670. /* bestmatch must not be deduplicated */
  2671. bestmatch = strsep(&buf, " ");
  2672. if (!bestmatch || !strcmp(bestmatch, AST_CLI_COMPLETE_EOF)) {
  2673. goto vector_cleanup;
  2674. }
  2675. while ((retstr = strsep(&buf, " "))) {
  2676. if (!strcmp(retstr, AST_CLI_COMPLETE_EOF)) {
  2677. break;
  2678. }
  2679. /* Older daemons sent duplicates. */
  2680. if (AST_VECTOR_GET_CMP(vec, retstr, !strcasecmp)) {
  2681. continue;
  2682. }
  2683. retstr = ast_strdup(retstr);
  2684. /* Older daemons sent unsorted. */
  2685. if (!retstr || AST_VECTOR_ADD_SORTED(vec, retstr, strcasecmp)) {
  2686. ast_free(retstr);
  2687. goto vector_cleanup;
  2688. }
  2689. }
  2690. bestmatch = ast_strdup(bestmatch);
  2691. if (!bestmatch || AST_VECTOR_INSERT_AT(vec, 0, bestmatch)) {
  2692. ast_free(bestmatch);
  2693. goto vector_cleanup;
  2694. }
  2695. return vec;
  2696. vector_cleanup:
  2697. AST_VECTOR_CALLBACK_VOID(vec, ast_free);
  2698. AST_VECTOR_PTR_FREE(vec);
  2699. return NULL;
  2700. }
  2701. static void ast_cli_display_match_list(struct ast_vector_string *matches, int max)
  2702. {
  2703. int idx = 1;
  2704. /* find out how many entries can be put on one line, with two spaces between strings */
  2705. int limit = ast_get_termcols(STDOUT_FILENO) / (max + 2);
  2706. if (limit == 0) {
  2707. limit = 1;
  2708. }
  2709. for (;;) {
  2710. int numoutputline;
  2711. for (numoutputline = 0; numoutputline < limit && idx < AST_VECTOR_SIZE(matches); idx++) {
  2712. numoutputline++;
  2713. fprintf(stdout, "%-*s ", max, AST_VECTOR_GET(matches, idx));
  2714. }
  2715. if (!numoutputline) {
  2716. break;
  2717. }
  2718. fprintf(stdout, "\n");
  2719. }
  2720. }
  2721. static char *cli_complete(EditLine *editline, int ch)
  2722. {
  2723. int len = 0;
  2724. char *ptr;
  2725. struct ast_vector_string *matches;
  2726. int retval = CC_ERROR;
  2727. char savechr;
  2728. int res;
  2729. LineInfo *lf = (LineInfo *)el_line(editline);
  2730. savechr = *(char *)lf->cursor;
  2731. *(char *)lf->cursor = '\0';
  2732. ptr = (char *)lf->cursor;
  2733. if (ptr) {
  2734. while (ptr > lf->buffer) {
  2735. if (isspace(*ptr)) {
  2736. ptr++;
  2737. break;
  2738. }
  2739. ptr--;
  2740. }
  2741. }
  2742. len = lf->cursor - ptr;
  2743. if (ast_opt_remote) {
  2744. #define CMD_MATCHESARRAY "_COMMAND MATCHESARRAY \"%s\" \"%s\""
  2745. char *mbuf;
  2746. char *new_mbuf;
  2747. int mlen = 0;
  2748. int maxmbuf = ast_asprintf(&mbuf, CMD_MATCHESARRAY, lf->buffer, ptr);
  2749. if (maxmbuf == -1) {
  2750. *((char *) lf->cursor) = savechr;
  2751. return (char *)(CC_ERROR);
  2752. }
  2753. fdsend(ast_consock, mbuf);
  2754. res = 0;
  2755. mlen = 0;
  2756. mbuf[0] = '\0';
  2757. while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
  2758. if (mlen + 1024 > maxmbuf) {
  2759. /* Expand buffer to the next 1024 byte increment plus a NULL terminator. */
  2760. maxmbuf = mlen + 1024;
  2761. new_mbuf = ast_realloc(mbuf, maxmbuf + 1);
  2762. if (!new_mbuf) {
  2763. ast_free(mbuf);
  2764. *((char *) lf->cursor) = savechr;
  2765. return (char *)(CC_ERROR);
  2766. }
  2767. mbuf = new_mbuf;
  2768. }
  2769. /* Only read 1024 bytes at a time */
  2770. res = read(ast_consock, mbuf + mlen, 1024);
  2771. if (res > 0) {
  2772. mlen += res;
  2773. mbuf[mlen] = '\0';
  2774. }
  2775. }
  2776. mbuf[mlen] = '\0';
  2777. matches = ast_el_strtoarr(mbuf);
  2778. ast_free(mbuf);
  2779. } else {
  2780. matches = ast_cli_completion_vector((char *)lf->buffer, ptr);
  2781. }
  2782. if (matches) {
  2783. int i;
  2784. int maxlen, match_len;
  2785. const char *best_match = AST_VECTOR_GET(matches, 0);
  2786. if (!ast_strlen_zero(best_match)) {
  2787. el_deletestr(editline, (int) len);
  2788. el_insertstr(editline, best_match);
  2789. retval = CC_REFRESH;
  2790. }
  2791. if (AST_VECTOR_SIZE(matches) == 2) {
  2792. /* Found an exact match */
  2793. el_insertstr(editline, " ");
  2794. retval = CC_REFRESH;
  2795. } else {
  2796. /* Must be more than one match */
  2797. for (i = 1, maxlen = 0; i < AST_VECTOR_SIZE(matches); i++) {
  2798. match_len = strlen(AST_VECTOR_GET(matches, i));
  2799. if (match_len > maxlen) {
  2800. maxlen = match_len;
  2801. }
  2802. }
  2803. fprintf(stdout, "\n");
  2804. ast_cli_display_match_list(matches, maxlen);
  2805. retval = CC_REDISPLAY;
  2806. }
  2807. AST_VECTOR_CALLBACK_VOID(matches, ast_free);
  2808. AST_VECTOR_PTR_FREE(matches);
  2809. }
  2810. *((char *) lf->cursor) = savechr;
  2811. return (char *)(long)retval;
  2812. }
  2813. static int ast_el_initialize(void)
  2814. {
  2815. HistEvent ev;
  2816. char *editor, *editrc = getenv("EDITRC");
  2817. if (!(editor = getenv("AST_EDITMODE"))) {
  2818. if (!(editor = getenv("AST_EDITOR"))) {
  2819. editor = "emacs";
  2820. }
  2821. }
  2822. if (el != NULL)
  2823. el_end(el);
  2824. if (el_hist != NULL)
  2825. history_end(el_hist);
  2826. el = el_init("asterisk", stdin, stdout, stderr);
  2827. el_set(el, EL_PROMPT, cli_prompt);
  2828. el_set(el, EL_EDITMODE, 1);
  2829. el_set(el, EL_EDITOR, editor);
  2830. el_hist = history_init();
  2831. if (!el || !el_hist)
  2832. return -1;
  2833. /* setup history with 100 entries */
  2834. history(el_hist, &ev, H_SETSIZE, 100);
  2835. el_set(el, EL_HIST, history, el_hist);
  2836. el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
  2837. /* Bind <tab> to command completion */
  2838. el_set(el, EL_BIND, "^I", "ed-complete", NULL);
  2839. /* Bind ? to command completion */
  2840. el_set(el, EL_BIND, "?", "ed-complete", NULL);
  2841. /* Bind ^D to redisplay */
  2842. el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
  2843. /* Bind Delete to delete char left */
  2844. el_set(el, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL);
  2845. /* Bind Home and End to move to line start and end */
  2846. el_set(el, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL);
  2847. el_set(el, EL_BIND, "\\e[4~", "ed-move-to-end", NULL);
  2848. /* Bind C-left and C-right to move by word (not all terminals) */
  2849. el_set(el, EL_BIND, "\\eOC", "vi-next-word", NULL);
  2850. el_set(el, EL_BIND, "\\eOD", "vi-prev-word", NULL);
  2851. if (editrc) {
  2852. el_source(el, editrc);
  2853. }
  2854. return 0;
  2855. }
  2856. #define MAX_HISTORY_COMMAND_LENGTH 256
  2857. static int ast_el_add_history(const char *buf)
  2858. {
  2859. HistEvent ev;
  2860. char *stripped_buf;
  2861. if (el_hist == NULL || el == NULL) {
  2862. ast_el_initialize();
  2863. }
  2864. if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1)) {
  2865. return 0;
  2866. }
  2867. stripped_buf = ast_strip(ast_strdupa(buf));
  2868. /* HISTCONTROL=ignoredups */
  2869. if (!history(el_hist, &ev, H_FIRST) && strcmp(ev.str, stripped_buf) == 0) {
  2870. return 0;
  2871. }
  2872. return history(el_hist, &ev, H_ENTER, stripped_buf);
  2873. }
  2874. static int ast_el_write_history(const char *filename)
  2875. {
  2876. HistEvent ev;
  2877. if (el_hist == NULL || el == NULL)
  2878. ast_el_initialize();
  2879. return (history(el_hist, &ev, H_SAVE, filename));
  2880. }
  2881. static int ast_el_read_history(const char *filename)
  2882. {
  2883. HistEvent ev;
  2884. if (el_hist == NULL || el == NULL) {
  2885. ast_el_initialize();
  2886. }
  2887. return history(el_hist, &ev, H_LOAD, filename);
  2888. }
  2889. static void ast_el_read_default_histfile(void)
  2890. {
  2891. char histfile[80] = "";
  2892. const char *home = getenv("HOME");
  2893. if (!ast_strlen_zero(home)) {
  2894. snprintf(histfile, sizeof(histfile), "%s/.asterisk_history", home);
  2895. ast_el_read_history(histfile);
  2896. }
  2897. }
  2898. static void ast_el_write_default_histfile(void)
  2899. {
  2900. char histfile[80] = "";
  2901. const char *home = getenv("HOME");
  2902. if (!ast_strlen_zero(home)) {
  2903. snprintf(histfile, sizeof(histfile), "%s/.asterisk_history", home);
  2904. ast_el_write_history(histfile);
  2905. }
  2906. }
  2907. static void ast_remotecontrol(char *data)
  2908. {
  2909. char buf[256] = "";
  2910. int res;
  2911. char *hostname;
  2912. char *cpid;
  2913. char *version;
  2914. int pid;
  2915. char *stringp = NULL;
  2916. char *ebuf;
  2917. int num = 0;
  2918. ast_term_init();
  2919. printf("%s", term_end());
  2920. fflush(stdout);
  2921. memset(&sig_flags, 0, sizeof(sig_flags));
  2922. signal(SIGINT, __remote_quit_handler);
  2923. signal(SIGTERM, __remote_quit_handler);
  2924. signal(SIGHUP, __remote_quit_handler);
  2925. if (read(ast_consock, buf, sizeof(buf) - 1) < 0) {
  2926. ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
  2927. return;
  2928. }
  2929. if (data) {
  2930. char prefix[] = "cli quit after ";
  2931. char *tmp = ast_alloca(strlen(data) + strlen(prefix) + 1);
  2932. sprintf(tmp, "%s%s", prefix, data);
  2933. if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) {
  2934. ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
  2935. if (sig_flags.need_quit || sig_flags.need_quit_handler || sig_flags.need_el_end) {
  2936. return;
  2937. }
  2938. }
  2939. }
  2940. stringp = buf;
  2941. hostname = strsep(&stringp, "/");
  2942. cpid = strsep(&stringp, "/");
  2943. version = strsep(&stringp, "\n");
  2944. if (!version)
  2945. version = "<Version Unknown>";
  2946. stringp = hostname;
  2947. strsep(&stringp, ".");
  2948. if (cpid)
  2949. pid = atoi(cpid);
  2950. else
  2951. pid = -1;
  2952. if (!data) {
  2953. send_rasterisk_connect_commands();
  2954. }
  2955. if (ast_opt_exec && data) { /* hack to print output then exit if asterisk -rx is used */
  2956. int linefull = 1, prev_linefull = 1, prev_line_verbose = 0;
  2957. struct pollfd fds;
  2958. fds.fd = ast_consock;
  2959. fds.events = POLLIN;
  2960. fds.revents = 0;
  2961. while (ast_poll(&fds, 1, 60000) > 0) {
  2962. char buffer[512] = "", *curline = buffer, *nextline;
  2963. int not_written = 1;
  2964. if (sig_flags.need_quit || sig_flags.need_quit_handler || sig_flags.need_el_end) {
  2965. break;
  2966. }
  2967. if (read(ast_consock, buffer, sizeof(buffer) - 1) <= 0) {
  2968. break;
  2969. }
  2970. do {
  2971. prev_linefull = linefull;
  2972. if ((nextline = strchr(curline, '\n'))) {
  2973. linefull = 1;
  2974. nextline++;
  2975. } else {
  2976. linefull = 0;
  2977. nextline = strchr(curline, '\0');
  2978. }
  2979. /* Skip verbose lines */
  2980. /* Prev line full? | Line is verbose | Last line verbose? | Print
  2981. * TRUE | TRUE* | TRUE | FALSE
  2982. * TRUE | TRUE* | FALSE | FALSE
  2983. * TRUE | FALSE* | TRUE | TRUE
  2984. * TRUE | FALSE* | FALSE | TRUE
  2985. * FALSE | TRUE | TRUE* | FALSE
  2986. * FALSE | TRUE | FALSE* | TRUE
  2987. * FALSE | FALSE | TRUE* | FALSE
  2988. * FALSE | FALSE | FALSE* | TRUE
  2989. */
  2990. if ((!prev_linefull && !prev_line_verbose) || (prev_linefull && *curline > 0)) {
  2991. prev_line_verbose = 0;
  2992. not_written = 0;
  2993. if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
  2994. ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
  2995. }
  2996. } else {
  2997. prev_line_verbose = 1;
  2998. }
  2999. curline = nextline;
  3000. } while (!ast_strlen_zero(curline));
  3001. /* No non-verbose output in 60 seconds. */
  3002. if (not_written) {
  3003. break;
  3004. }
  3005. }
  3006. return;
  3007. }
  3008. ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
  3009. remotehostname = hostname;
  3010. if (el_hist == NULL || el == NULL)
  3011. ast_el_initialize();
  3012. ast_el_read_default_histfile();
  3013. el_set(el, EL_GETCFN, ast_el_read_char);
  3014. for (;;) {
  3015. ebuf = (char *)el_gets(el, &num);
  3016. if (sig_flags.need_quit || sig_flags.need_quit_handler || sig_flags.need_el_end) {
  3017. break;
  3018. }
  3019. if (!ebuf && write(1, "", 1) < 0)
  3020. break;
  3021. if (!ast_strlen_zero(ebuf)) {
  3022. if (ebuf[strlen(ebuf)-1] == '\n')
  3023. ebuf[strlen(ebuf)-1] = '\0';
  3024. if (!remoteconsolehandler(ebuf)) {
  3025. res = write(ast_consock, ebuf, strlen(ebuf) + 1);
  3026. if (res < 1) {
  3027. ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
  3028. break;
  3029. }
  3030. }
  3031. }
  3032. }
  3033. printf("\nDisconnected from Asterisk server\n");
  3034. }
  3035. static int show_version(void)
  3036. {
  3037. printf("Asterisk %s\n", ast_get_version());
  3038. return 0;
  3039. }
  3040. static int show_cli_help(void)
  3041. {
  3042. printf("Asterisk %s, Copyright (C) 1999 - 2014, Digium, Inc. and others.\n", ast_get_version());
  3043. printf("Usage: asterisk [OPTIONS]\n");
  3044. printf("Valid Options:\n");
  3045. printf(" -V Display version number and exit\n");
  3046. printf(" -C <configfile> Use an alternate configuration file\n");
  3047. printf(" -G <group> Run as a group other than the caller\n");
  3048. printf(" -U <user> Run as a user other than the caller\n");
  3049. printf(" -c Provide console CLI\n");
  3050. printf(" -d Enable extra debugging\n");
  3051. #if HAVE_WORKING_FORK
  3052. printf(" -f Do not fork\n");
  3053. printf(" -F Always fork\n");
  3054. #endif
  3055. printf(" -g Dump core in case of a crash\n");
  3056. printf(" -h This help screen\n");
  3057. printf(" -i Initialize crypto keys at startup\n");
  3058. printf(" -L <load> Limit the maximum load average before rejecting new calls\n");
  3059. printf(" -M <value> Limit the maximum number of calls to the specified value\n");
  3060. printf(" -m Mute debugging and console output on the console\n");
  3061. printf(" -n Disable console colorization\n");
  3062. printf(" -p Run as pseudo-realtime thread\n");
  3063. printf(" -q Quiet mode (suppress output)\n");
  3064. printf(" -r Connect to Asterisk on this machine\n");
  3065. printf(" -R Same as -r, except attempt to reconnect if disconnected\n");
  3066. printf(" -s <socket> Connect to Asterisk via socket <socket> (only valid with -r)\n");
  3067. printf(" -t Record soundfiles in /var/tmp and move them where they\n");
  3068. printf(" belong after they are done\n");
  3069. printf(" -T Display the time in [Mmm dd hh:mm:ss] format for each line\n");
  3070. printf(" of output to the CLI\n");
  3071. printf(" -v Increase verbosity (multiple v's = more verbose)\n");
  3072. printf(" -x <cmd> Execute command <cmd> (implies -r)\n");
  3073. printf(" -X Execute includes by default (allows #exec in asterisk.conf)\n");
  3074. printf(" -W Adjust terminal colors to compensate for a light background\n");
  3075. printf("\n");
  3076. return 0;
  3077. }
  3078. static void read_pjproject_startup_options(void)
  3079. {
  3080. struct ast_config *cfg;
  3081. struct ast_variable *v;
  3082. struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE | CONFIG_FLAG_NOREALTIME };
  3083. ast_option_pjproject_log_level = DEFAULT_PJ_LOG_MAX_LEVEL;
  3084. ast_option_pjproject_cache_pools = DEFAULT_PJPROJECT_CACHE_POOLS;
  3085. cfg = ast_config_load2("pjproject.conf", "" /* core, can't reload */, config_flags);
  3086. if (!cfg
  3087. || cfg == CONFIG_STATUS_FILEUNCHANGED
  3088. || cfg == CONFIG_STATUS_FILEINVALID) {
  3089. /* We'll have to use defaults */
  3090. return;
  3091. }
  3092. for (v = ast_variable_browse(cfg, "startup"); v; v = v->next) {
  3093. if (!strcasecmp(v->name, "log_level")) {
  3094. if (sscanf(v->value, "%30d", &ast_option_pjproject_log_level) != 1) {
  3095. ast_option_pjproject_log_level = DEFAULT_PJ_LOG_MAX_LEVEL;
  3096. } else if (ast_option_pjproject_log_level < 0) {
  3097. ast_option_pjproject_log_level = 0;
  3098. } else if (MAX_PJ_LOG_MAX_LEVEL < ast_option_pjproject_log_level) {
  3099. ast_option_pjproject_log_level = MAX_PJ_LOG_MAX_LEVEL;
  3100. }
  3101. } else if (!strcasecmp(v->name, "cache_pools")) {
  3102. ast_option_pjproject_cache_pools = !ast_false(v->value);
  3103. }
  3104. }
  3105. ast_config_destroy(cfg);
  3106. }
  3107. static void *monitor_sig_flags(void *unused)
  3108. {
  3109. for (;;) {
  3110. struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
  3111. int a;
  3112. ast_poll(&p, 1, -1);
  3113. if (sig_flags.need_reload) {
  3114. sig_flags.need_reload = 0;
  3115. ast_module_reload(NULL);
  3116. }
  3117. if (sig_flags.need_quit) {
  3118. sig_flags.need_quit = 0;
  3119. if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
  3120. sig_flags.need_quit_handler = 1;
  3121. pthread_kill(consolethread, SIGURG);
  3122. } else {
  3123. quit_handler(0, SHUTDOWN_NORMAL, 0);
  3124. }
  3125. }
  3126. if (read(sig_alert_pipe[0], &a, sizeof(a)) != sizeof(a)) {
  3127. }
  3128. }
  3129. return NULL;
  3130. }
  3131. static void *canary_thread(void *unused)
  3132. {
  3133. struct stat canary_stat;
  3134. struct timeval now;
  3135. /* Give the canary time to sing */
  3136. sleep(120);
  3137. for (;;) {
  3138. now = ast_tvnow();
  3139. if (stat(canary_filename, &canary_stat) || now.tv_sec > canary_stat.st_mtime + 60) {
  3140. ast_log(LOG_WARNING,
  3141. "The canary is no more. He has ceased to be! "
  3142. "He's expired and gone to meet his maker! "
  3143. "He's a stiff! Bereft of life, he rests in peace. "
  3144. "His metabolic processes are now history! He's off the twig! "
  3145. "He's kicked the bucket. He's shuffled off his mortal coil, "
  3146. "run down the curtain, and joined the bleeding choir invisible!! "
  3147. "THIS is an EX-CANARY. (Reducing priority)\n");
  3148. set_priority_all(0);
  3149. pthread_exit(NULL);
  3150. }
  3151. /* Check the canary once a minute */
  3152. sleep(60);
  3153. }
  3154. }
  3155. /* Used by libc's atexit(3) function */
  3156. static void canary_exit(void)
  3157. {
  3158. if (canary_pid > 0) {
  3159. int status;
  3160. kill(canary_pid, SIGKILL);
  3161. waitpid(canary_pid, &status, 0);
  3162. }
  3163. }
  3164. /* Execute CLI commands on startup. Run by main() thread. */
  3165. static void run_startup_commands(void)
  3166. {
  3167. int fd;
  3168. struct ast_config *cfg;
  3169. struct ast_flags cfg_flags = { 0 };
  3170. struct ast_variable *v;
  3171. if (!(cfg = ast_config_load2("cli.conf", "" /* core, can't reload */, cfg_flags)))
  3172. return;
  3173. if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
  3174. return;
  3175. }
  3176. fd = open("/dev/null", O_RDWR);
  3177. if (fd < 0) {
  3178. ast_config_destroy(cfg);
  3179. return;
  3180. }
  3181. for (v = ast_variable_browse(cfg, "startup_commands"); v; v = v->next) {
  3182. if (ast_true(v->value))
  3183. ast_cli_command(fd, v->name);
  3184. }
  3185. close(fd);
  3186. ast_config_destroy(cfg);
  3187. }
  3188. static void env_init(void)
  3189. {
  3190. setenv("AST_SYSTEMNAME", ast_config_AST_SYSTEM_NAME, 1);
  3191. setenv("AST_BUILD_HOST", ast_build_hostname, 1);
  3192. setenv("AST_BUILD_DATE", ast_build_date, 1);
  3193. setenv("AST_BUILD_KERNEL", ast_build_kernel, 1);
  3194. setenv("AST_BUILD_MACHINE", ast_build_machine, 1);
  3195. setenv("AST_BUILD_OS", ast_build_os, 1);
  3196. setenv("AST_BUILD_USER", ast_build_user, 1);
  3197. setenv("AST_VERSION", ast_get_version(), 1);
  3198. }
  3199. static void print_intro_message(const char *runuser, const char *rungroup)
  3200. {
  3201. if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) {
  3202. if (ast_register_verbose(console_verboser)) {
  3203. fprintf(stderr, "Unable to register console verboser?\n");
  3204. return;
  3205. }
  3206. WELCOME_MESSAGE;
  3207. if (runuser) {
  3208. ast_verbose("Running as user '%s'\n", runuser);
  3209. }
  3210. if (rungroup) {
  3211. ast_verbose("Running under group '%s'\n", rungroup);
  3212. }
  3213. }
  3214. }
  3215. static void main_atexit(void)
  3216. {
  3217. ast_cli_unregister_multiple(cli_asterisk, ARRAY_LEN(cli_asterisk));
  3218. }
  3219. int main(int argc, char *argv[])
  3220. {
  3221. int c;
  3222. char * xarg = NULL;
  3223. int x;
  3224. int isroot = 1, rundir_exists = 0;
  3225. const char *runuser = NULL, *rungroup = NULL;
  3226. char *remotesock = NULL;
  3227. struct rlimit l;
  3228. /* Remember original args for restart */
  3229. if (argc > ARRAY_LEN(_argv) - 1) {
  3230. fprintf(stderr, "Truncating argument size to %d\n", (int)ARRAY_LEN(_argv) - 1);
  3231. argc = ARRAY_LEN(_argv) - 1;
  3232. }
  3233. for (x = 0; x < argc; x++)
  3234. _argv[x] = argv[x];
  3235. _argv[x] = NULL;
  3236. if (geteuid() != 0)
  3237. isroot = 0;
  3238. /* if the progname is rasterisk consider it a remote console */
  3239. if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) {
  3240. ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
  3241. }
  3242. ast_mainpid = getpid();
  3243. /*! \brief Check for options
  3244. *
  3245. * \todo Document these options
  3246. */
  3247. while ((c = getopt(argc, argv, "BC:cde:FfG:ghIiL:M:mnpqRrs:TtU:VvWXx:")) != -1) {
  3248. /*!\note Please keep the ordering here to alphabetical, capital letters
  3249. * first. This will make it easier in the future to select unused
  3250. * option flags for new features. */
  3251. switch (c) {
  3252. case 'B': /* Force black background */
  3253. ast_set_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
  3254. ast_clear_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND);
  3255. break;
  3256. case 'X':
  3257. ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES);
  3258. break;
  3259. case 'C':
  3260. set_asterisk_conf_path(optarg);
  3261. ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG);
  3262. break;
  3263. case 'c':
  3264. ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
  3265. break;
  3266. case 'd':
  3267. option_debug++;
  3268. ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
  3269. break;
  3270. #if defined(HAVE_SYSINFO)
  3271. case 'e':
  3272. if ((sscanf(&optarg[1], "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
  3273. option_minmemfree = 0;
  3274. }
  3275. break;
  3276. #endif
  3277. #if HAVE_WORKING_FORK
  3278. case 'F':
  3279. ast_set_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
  3280. break;
  3281. case 'f':
  3282. ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
  3283. break;
  3284. #endif
  3285. case 'G':
  3286. rungroup = ast_strdupa(optarg);
  3287. break;
  3288. case 'g':
  3289. ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE);
  3290. break;
  3291. case 'h':
  3292. show_cli_help();
  3293. exit(0);
  3294. case 'I':
  3295. fprintf(stderr,
  3296. "NOTICE: The -I option is no longer needed.\n"
  3297. " It will always be enabled if you have a timing module loaded.\n");
  3298. break;
  3299. case 'i':
  3300. ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS);
  3301. break;
  3302. case 'L':
  3303. if ((sscanf(optarg, "%30lf", &ast_option_maxload) != 1) || (ast_option_maxload < 0.0)) {
  3304. ast_option_maxload = 0.0;
  3305. }
  3306. break;
  3307. case 'M':
  3308. if ((sscanf(optarg, "%30d", &ast_option_maxcalls) != 1) || (ast_option_maxcalls < 0)) {
  3309. ast_option_maxcalls = 0;
  3310. }
  3311. break;
  3312. case 'm':
  3313. ast_set_flag(&ast_options, AST_OPT_FLAG_MUTE);
  3314. break;
  3315. case 'n':
  3316. ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR);
  3317. break;
  3318. case 'p':
  3319. ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
  3320. break;
  3321. case 'q':
  3322. ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET);
  3323. break;
  3324. case 'R':
  3325. ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT);
  3326. break;
  3327. case 'r':
  3328. ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
  3329. break;
  3330. case 's':
  3331. remotesock = ast_strdupa(optarg);
  3332. break;
  3333. case 'T':
  3334. ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP);
  3335. break;
  3336. case 't':
  3337. ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES);
  3338. break;
  3339. case 'U':
  3340. runuser = ast_strdupa(optarg);
  3341. break;
  3342. case 'V':
  3343. show_version();
  3344. exit(0);
  3345. case 'v':
  3346. option_verbose++;
  3347. ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
  3348. break;
  3349. case 'W': /* White background */
  3350. ast_set_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND);
  3351. ast_clear_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
  3352. break;
  3353. case 'x':
  3354. /* -r is implied by -x so set the flags -r sets as well. */
  3355. ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
  3356. ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC | AST_OPT_FLAG_NO_COLOR);
  3357. xarg = ast_strdupa(optarg);
  3358. break;
  3359. case '?':
  3360. exit(1);
  3361. }
  3362. }
  3363. /* For remote connections, change the name of the remote connection.
  3364. * We do this for the benefit of init scripts (which need to know if/when
  3365. * the main asterisk process has died yet). */
  3366. if (ast_opt_remote) {
  3367. strcpy(argv[0], "rasterisk");
  3368. for (x = 1; x < argc; x++) {
  3369. argv[x] = argv[0] + 10;
  3370. }
  3371. }
  3372. load_asterisk_conf();
  3373. env_init();
  3374. if (ast_opt_remote && remotesock != NULL) {
  3375. set_socket_path(remotesock);
  3376. }
  3377. if (!ast_language_is_prefix && !ast_opt_remote) {
  3378. fprintf(stderr, "The 'languageprefix' option in asterisk.conf is deprecated; in a future release it will be removed, and your sound files will need to be organized in the 'new style' language layout.\n");
  3379. }
  3380. if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) {
  3381. fprintf(stderr, "'alwaysfork' is not compatible with console or remote console mode; ignored\n");
  3382. ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
  3383. }
  3384. if (ast_opt_dump_core) {
  3385. memset(&l, 0, sizeof(l));
  3386. l.rlim_cur = RLIM_INFINITY;
  3387. l.rlim_max = RLIM_INFINITY;
  3388. if (setrlimit(RLIMIT_CORE, &l)) {
  3389. fprintf(stderr, "Unable to disable core size resource limit: %s\n", strerror(errno));
  3390. }
  3391. }
  3392. if (getrlimit(RLIMIT_NOFILE, &l)) {
  3393. fprintf(stderr, "Unable to check file descriptor limit: %s\n", strerror(errno));
  3394. }
  3395. #if !defined(CONFIGURE_RAN_AS_ROOT)
  3396. /* Check if select(2) will run with more file descriptors */
  3397. do {
  3398. int fd, fd2;
  3399. ast_fdset readers;
  3400. struct timeval tv = { 0, };
  3401. if (l.rlim_cur <= FD_SETSIZE) {
  3402. /* The limit of select()able FDs is irrelevant, because we'll never
  3403. * open one that high. */
  3404. break;
  3405. }
  3406. if (!(fd = open("/dev/null", O_RDONLY))) {
  3407. fprintf(stderr, "Cannot open a file descriptor at boot? %s\n", strerror(errno));
  3408. break; /* XXX Should we exit() here? XXX */
  3409. }
  3410. fd2 = ((l.rlim_cur > sizeof(readers) * 8) ? sizeof(readers) * 8 : l.rlim_cur) - 1;
  3411. if (dup2(fd, fd2) < 0) {
  3412. fprintf(stderr, "Cannot open maximum file descriptor %d at boot? %s\n", fd2, strerror(errno));
  3413. close(fd);
  3414. break;
  3415. }
  3416. FD_ZERO(&readers);
  3417. FD_SET(fd2, &readers);
  3418. if (ast_select(fd2 + 1, &readers, NULL, NULL, &tv) < 0) {
  3419. fprintf(stderr, "Maximum select()able file descriptor is %d\n", FD_SETSIZE);
  3420. }
  3421. ast_FD_SETSIZE = l.rlim_cur > ast_FDMAX ? ast_FDMAX : l.rlim_cur;
  3422. close(fd);
  3423. close(fd2);
  3424. } while (0);
  3425. #elif defined(HAVE_VARIABLE_FDSET)
  3426. ast_FD_SETSIZE = l.rlim_cur > ast_FDMAX ? ast_FDMAX : l.rlim_cur;
  3427. #endif /* !defined(CONFIGURE_RAN_AS_ROOT) */
  3428. if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP))
  3429. rungroup = ast_config_AST_RUN_GROUP;
  3430. if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER))
  3431. runuser = ast_config_AST_RUN_USER;
  3432. /* Must install this signal handler up here to ensure that if the canary
  3433. * fails to execute that it doesn't kill the Asterisk process.
  3434. */
  3435. sigaction(SIGCHLD, &child_handler, NULL);
  3436. /* It's common on some platforms to clear /var/run at boot. Create the
  3437. * socket file directory before we drop privileges. */
  3438. if (mkdir(ast_config_AST_RUN_DIR, 0755)) {
  3439. if (errno == EEXIST) {
  3440. rundir_exists = 1;
  3441. } else {
  3442. fprintf(stderr, "Unable to create socket file directory. Remote consoles will not be able to connect! (%s)\n", strerror(x));
  3443. }
  3444. }
  3445. #ifndef __CYGWIN__
  3446. if (isroot) {
  3447. ast_set_priority(ast_opt_high_priority);
  3448. }
  3449. if (isroot && rungroup) {
  3450. struct group *gr;
  3451. gr = getgrnam(rungroup);
  3452. if (!gr) {
  3453. fprintf(stderr, "No such group '%s'!\n", rungroup);
  3454. exit(1);
  3455. }
  3456. if (!rundir_exists && chown(ast_config_AST_RUN_DIR, -1, gr->gr_gid)) {
  3457. fprintf(stderr, "Unable to chgrp run directory to %d (%s)\n", (int) gr->gr_gid, rungroup);
  3458. }
  3459. if (setgid(gr->gr_gid)) {
  3460. fprintf(stderr, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup);
  3461. exit(1);
  3462. }
  3463. if (setgroups(0, NULL)) {
  3464. fprintf(stderr, "Unable to drop unneeded groups\n");
  3465. exit(1);
  3466. }
  3467. }
  3468. if (runuser && !ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)) {
  3469. #ifdef HAVE_CAP
  3470. int has_cap = 1;
  3471. #endif /* HAVE_CAP */
  3472. struct passwd *pw;
  3473. pw = getpwnam(runuser);
  3474. if (!pw) {
  3475. fprintf(stderr, "No such user '%s'!\n", runuser);
  3476. exit(1);
  3477. }
  3478. if (chown(ast_config_AST_RUN_DIR, pw->pw_uid, -1)) {
  3479. fprintf(stderr, "Unable to chown run directory to %d (%s)\n", (int) pw->pw_uid, runuser);
  3480. }
  3481. #ifdef HAVE_CAP
  3482. if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
  3483. ast_log(LOG_WARNING, "Unable to keep capabilities.\n");
  3484. has_cap = 0;
  3485. }
  3486. #endif /* HAVE_CAP */
  3487. if (!isroot && pw->pw_uid != geteuid()) {
  3488. fprintf(stderr, "Asterisk started as nonroot, but runuser '%s' requested.\n", runuser);
  3489. exit(1);
  3490. }
  3491. if (!rungroup) {
  3492. if (setgid(pw->pw_gid)) {
  3493. fprintf(stderr, "Unable to setgid to %d!\n", (int)pw->pw_gid);
  3494. exit(1);
  3495. }
  3496. if (isroot && initgroups(pw->pw_name, pw->pw_gid)) {
  3497. fprintf(stderr, "Unable to init groups for '%s'\n", runuser);
  3498. exit(1);
  3499. }
  3500. }
  3501. if (setuid(pw->pw_uid)) {
  3502. fprintf(stderr, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser);
  3503. exit(1);
  3504. }
  3505. #ifdef HAVE_CAP
  3506. if (has_cap) {
  3507. cap_t cap;
  3508. cap = cap_from_text("cap_net_admin=eip");
  3509. if (cap_set_proc(cap)) {
  3510. fprintf(stderr, "Unable to install capabilities.\n");
  3511. }
  3512. if (cap_free(cap)) {
  3513. fprintf(stderr, "Unable to drop capabilities.\n");
  3514. }
  3515. }
  3516. #endif /* HAVE_CAP */
  3517. }
  3518. #endif /* __CYGWIN__ */
  3519. #ifdef linux
  3520. if (geteuid() && ast_opt_dump_core) {
  3521. if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
  3522. fprintf(stderr, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno));
  3523. }
  3524. }
  3525. #endif
  3526. {
  3527. #if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS)
  3528. #if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS)
  3529. #define eaccess euidaccess
  3530. #endif
  3531. char dir[PATH_MAX];
  3532. if (!getcwd(dir, sizeof(dir)) || eaccess(dir, R_OK | X_OK | F_OK)) {
  3533. fprintf(stderr, "Unable to access the running directory (%s). Changing to '/' for compatibility.\n", strerror(errno));
  3534. /* If we cannot access the CWD, then we couldn't dump core anyway,
  3535. * so chdir("/") won't break anything. */
  3536. if (chdir("/")) {
  3537. /* chdir(/) should never fail, so this ends up being a no-op */
  3538. fprintf(stderr, "chdir(\"/\") failed?!! %s\n", strerror(errno));
  3539. }
  3540. } else
  3541. #endif /* defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS) */
  3542. if (!ast_opt_no_fork && !ast_opt_dump_core) {
  3543. /* Backgrounding, but no cores, so chdir won't break anything. */
  3544. if (chdir("/")) {
  3545. fprintf(stderr, "Unable to chdir(\"/\") ?!! %s\n", strerror(errno));
  3546. }
  3547. }
  3548. }
  3549. /* Initial value of the maximum active system verbosity level. */
  3550. ast_verb_sys_level = option_verbose;
  3551. if (ast_tryconnect()) {
  3552. /* One is already running */
  3553. if (ast_opt_remote) {
  3554. multi_thread_safe = 1;
  3555. if (ast_opt_exec) {
  3556. ast_remotecontrol(xarg);
  3557. quit_handler(0, SHUTDOWN_FAST, 0);
  3558. exit(0);
  3559. }
  3560. ast_term_init();
  3561. printf("%s", term_end());
  3562. fflush(stdout);
  3563. print_intro_message(runuser, rungroup);
  3564. printf("%s", term_quit());
  3565. ast_remotecontrol(NULL);
  3566. quit_handler(0, SHUTDOWN_FAST, 0);
  3567. exit(0);
  3568. } else {
  3569. fprintf(stderr, "Asterisk already running on %s. Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET);
  3570. printf("%s", term_quit());
  3571. exit(1);
  3572. }
  3573. } else if (ast_opt_remote || ast_opt_exec) {
  3574. fprintf(stderr, "Unable to connect to remote asterisk (does %s exist?)\n", ast_config_AST_SOCKET);
  3575. printf("%s", term_quit());
  3576. exit(1);
  3577. }
  3578. /* Not a remote console? Start the daemon. */
  3579. asterisk_daemon(isroot, runuser, rungroup);
  3580. return 0;
  3581. }
  3582. static inline void check_init(int init_result, const char *name)
  3583. {
  3584. if (init_result) {
  3585. if (ast_is_logger_initialized()) {
  3586. ast_log(LOG_ERROR, "%s initialization failed. ASTERISK EXITING!\n%s", name, term_quit());
  3587. } else {
  3588. fprintf(stderr, "%s initialization failed. ASTERISK EXITING!\n%s", name, term_quit());
  3589. }
  3590. ast_run_atexits(0);
  3591. exit(init_result == -2 ? 2 : 1);
  3592. }
  3593. }
  3594. static void asterisk_daemon(int isroot, const char *runuser, const char *rungroup)
  3595. {
  3596. FILE *f;
  3597. sigset_t sigs;
  3598. int num;
  3599. char *buf;
  3600. char pbx_uuid[AST_UUID_STR_LEN];
  3601. /* This needs to remain as high up in the initial start up as possible.
  3602. * daemon causes a fork to occur, which has all sorts of unintended
  3603. * consequences for things that interact with threads. This call *must*
  3604. * occur before anything in Asterisk spawns or manipulates thread related
  3605. * primitives. */
  3606. #if HAVE_WORKING_FORK
  3607. if (ast_opt_always_fork || !ast_opt_no_fork) {
  3608. #ifndef HAVE_SBIN_LAUNCHD
  3609. if (daemon(1, 0) < 0) {
  3610. fprintf(stderr, "daemon() failed: %s\n", strerror(errno));
  3611. } else {
  3612. ast_mainpid = getpid();
  3613. }
  3614. #else
  3615. fprintf(stderr, "Mac OS X detected. Use 'launchctl load /Library/LaunchDaemon/org.asterisk.asterisk.plist'.\n");
  3616. #endif
  3617. }
  3618. #endif
  3619. /* At this point everything has been forked successfully,
  3620. * we have determined that we aren't attempting to connect to
  3621. * an Asterisk instance, and that there isn't one already running. */
  3622. multi_thread_safe = 1;
  3623. #if defined(__AST_DEBUG_MALLOC)
  3624. __ast_mm_init_phase_1();
  3625. #endif /* defined(__AST_DEBUG_MALLOC) */
  3626. /* Check whether high prio was succesfully set by us or some
  3627. * other incantation. */
  3628. if (has_priority()) {
  3629. ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
  3630. } else {
  3631. ast_clear_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
  3632. }
  3633. /* Spawning of astcanary must happen AFTER the call to daemon(3) */
  3634. if (ast_opt_high_priority) {
  3635. snprintf(canary_filename, sizeof(canary_filename), "%s/alt.asterisk.canary.tweet.tweet.tweet", ast_config_AST_RUN_DIR);
  3636. /* Don't let the canary child kill Asterisk, if it dies immediately */
  3637. sigaction(SIGPIPE, &ignore_sig_handler, NULL);
  3638. canary_pid = fork();
  3639. if (canary_pid == 0) {
  3640. char canary_binary[PATH_MAX], ppid[12];
  3641. /* Reset signal handler */
  3642. signal(SIGCHLD, SIG_DFL);
  3643. signal(SIGPIPE, SIG_DFL);
  3644. ast_close_fds_above_n(0);
  3645. ast_set_priority(0);
  3646. snprintf(ppid, sizeof(ppid), "%d", (int) ast_mainpid);
  3647. /* Use the astcanary binary that we installed */
  3648. snprintf(canary_binary, sizeof(canary_binary), "%s/astcanary", ast_config_AST_SBIN_DIR);
  3649. execl(canary_binary, "astcanary", canary_filename, ppid, (char *)NULL);
  3650. /* Should never happen */
  3651. _exit(1);
  3652. } else if (canary_pid > 0) {
  3653. pthread_t dont_care;
  3654. ast_pthread_create_detached(&dont_care, NULL, canary_thread, NULL);
  3655. }
  3656. /* Kill the canary when we exit */
  3657. ast_register_atexit(canary_exit);
  3658. }
  3659. /* Blindly write the PID file. */
  3660. unlink(ast_config_AST_PID);
  3661. f = fopen(ast_config_AST_PID, "w");
  3662. if (f) {
  3663. fprintf(f, "%ld\n", (long)ast_mainpid);
  3664. fclose(f);
  3665. } else {
  3666. fprintf(stderr, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
  3667. }
  3668. /* Initialize the terminal. Since all processes have been forked,
  3669. * we can now start using the standard log messages.
  3670. */
  3671. ast_term_init();
  3672. printf("%s", term_end());
  3673. fflush(stdout);
  3674. print_intro_message(runuser, rungroup);
  3675. if (ast_opt_console) {
  3676. ast_verb(0, "[ Initializing Custom Configuration Options ]\n");
  3677. }
  3678. /* custom config setup */
  3679. register_config_cli();
  3680. read_config_maps();
  3681. check_init(astobj2_init(), "AO2");
  3682. check_init(ast_named_locks_init(), "Named Locks");
  3683. if (ast_opt_console) {
  3684. if (el_hist == NULL || el == NULL)
  3685. ast_el_initialize();
  3686. ast_el_read_default_histfile();
  3687. }
  3688. #ifdef AST_XML_DOCS
  3689. /* Load XML documentation. */
  3690. ast_xmldoc_load_documentation();
  3691. #endif
  3692. check_init(astdb_init(), "ASTdb");
  3693. ast_uuid_init();
  3694. if (ast_pbx_uuid_get(pbx_uuid, sizeof(pbx_uuid))) {
  3695. ast_uuid_generate_str(pbx_uuid, sizeof(pbx_uuid));
  3696. ast_db_put("pbx", "UUID", pbx_uuid);
  3697. }
  3698. ast_verb(0, "PBX UUID: %s\n", pbx_uuid);
  3699. ast_json_init();
  3700. ast_ulaw_init();
  3701. ast_alaw_init();
  3702. tdd_init();
  3703. callerid_init();
  3704. ast_builtins_init();
  3705. check_init(ast_utils_init(), "Utilities");
  3706. check_init(ast_tps_init(), "Task Processor Core");
  3707. check_init(ast_fd_init(), "File Descriptor Debugging");
  3708. check_init(ast_pbx_init(), "ast_pbx_init");
  3709. check_init(aco_init(), "Configuration Option Framework");
  3710. check_init(stasis_init(), "Stasis");
  3711. #ifdef TEST_FRAMEWORK
  3712. check_init(ast_test_init(), "Test Framework");
  3713. #endif
  3714. check_init(ast_translate_init(), "Translator Core");
  3715. ast_aoc_cli_init();
  3716. check_init(ast_sorcery_init(), "Sorcery");
  3717. check_init(ast_codec_init(), "Codecs");
  3718. check_init(ast_format_init(), "Formats");
  3719. check_init(ast_format_cache_init(), "Format Cache");
  3720. check_init(ast_codec_builtin_init(), "Built-in Codecs");
  3721. check_init(ast_bucket_init(), "Bucket API");
  3722. check_init(ast_stasis_system_init(), "Stasis system-level information");
  3723. check_init(ast_endpoint_stasis_init(), "Stasis Endpoint");
  3724. ast_makesocket();
  3725. /* GCC 4.9 gives a bogus "right-hand operand of comma expression has
  3726. * no effect" warning */
  3727. (void) sigemptyset(&sigs);
  3728. (void) sigaddset(&sigs, SIGHUP);
  3729. (void) sigaddset(&sigs, SIGTERM);
  3730. (void) sigaddset(&sigs, SIGINT);
  3731. (void) sigaddset(&sigs, SIGPIPE);
  3732. (void) sigaddset(&sigs, SIGWINCH);
  3733. pthread_sigmask(SIG_BLOCK, &sigs, NULL);
  3734. sigaction(SIGURG, &urg_handler, NULL);
  3735. signal(SIGINT, __quit_handler);
  3736. signal(SIGTERM, __quit_handler);
  3737. sigaction(SIGHUP, &hup_handler, NULL);
  3738. sigaction(SIGPIPE, &ignore_sig_handler, NULL);
  3739. /* ensure that the random number generators are seeded with a different value every time
  3740. Asterisk is started
  3741. */
  3742. srand((unsigned int) getpid() + (unsigned int) time(NULL));
  3743. initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool));
  3744. check_init(init_logger(), "Logger");
  3745. threadstorage_init();
  3746. check_init(ast_rtp_engine_init(), "RTP Engine");
  3747. ast_autoservice_init();
  3748. check_init(ast_timing_init(), "Timing");
  3749. check_init(ast_ssl_init(), "SSL");
  3750. read_pjproject_startup_options();
  3751. check_init(ast_pj_init(), "Embedded PJProject");
  3752. check_init(app_init(), "App Core");
  3753. check_init(devstate_init(), "Device State Core");
  3754. check_init(ast_msg_init(), "Messaging API");
  3755. check_init(ast_data_init(), "Data Retrieval API");
  3756. check_init(ast_channels_init(), "Channel");
  3757. check_init(ast_endpoint_init(), "Endpoints");
  3758. check_init(ast_pickup_init(), "Call Pickup");
  3759. check_init(ast_bridging_init(), "Bridging");
  3760. check_init(ast_parking_stasis_init(), "Parking Core");
  3761. check_init(ast_device_state_engine_init(), "Device State Engine");
  3762. check_init(ast_presence_state_engine_init(), "Presence State Engine");
  3763. check_init(load_modules(1), "Module Preload");
  3764. check_init(ast_features_init(), "Call Features");
  3765. check_init(dnsmgr_init(), "DNS manager");
  3766. check_init(ast_security_stasis_init(), "Security Stasis Topic and Events");
  3767. check_init(ast_named_acl_init(), "Named ACL system");
  3768. ast_http_init(); /* Start the HTTP server, if needed */
  3769. check_init(ast_indications_init(), "Indication Tone Handling");
  3770. check_init(ast_cdr_engine_init(), "CDR Engine");
  3771. ast_dsp_init();
  3772. ast_udptl_init();
  3773. check_init(ast_image_init(), "Image");
  3774. check_init(ast_file_init(), "Generic File Format Support");
  3775. check_init(load_pbx(), "load_pbx");
  3776. check_init(load_pbx_builtins(), "Builtin PBX Applications");
  3777. check_init(load_pbx_functions_cli(), "PBX Functions Support");
  3778. check_init(load_pbx_variables(), "PBX Variables Support");
  3779. check_init(load_pbx_switch(), "PBX Switch Support");
  3780. check_init(load_pbx_app(), "PBX Application Support");
  3781. check_init(load_pbx_hangup_handler(), "PBX Hangup Handler Support");
  3782. check_init(ast_local_init(), "Local Proxy Channel Driver");
  3783. check_init(ast_cel_engine_init(), "CEL Engine");
  3784. check_init(init_manager(), "Asterisk Manager Interface");
  3785. check_init(ast_enum_init(), "ENUM Support");
  3786. check_init(ast_cc_init(), "Call Completion Supplementary Services");
  3787. check_init(load_modules(0), "Module");
  3788. /*
  3789. * This is initialized after the dynamic modules load to avoid repeatedly
  3790. * reindexing sounds for every format module load.
  3791. */
  3792. check_init(ast_sounds_index_init(), "Sounds Indexer");
  3793. /* loads the cli_permissoins.conf file needed to implement cli restrictions. */
  3794. ast_cli_perms_init(0);
  3795. ast_stun_init();
  3796. dnsmgr_start_refresh();
  3797. if (ast_opt_no_fork) {
  3798. consolethread = pthread_self();
  3799. }
  3800. if (pipe(sig_alert_pipe)) {
  3801. sig_alert_pipe[0] = sig_alert_pipe[1] = -1;
  3802. }
  3803. ast_process_pending_reloads();
  3804. ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED);
  3805. publish_fully_booted();
  3806. pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
  3807. #if defined(__AST_DEBUG_MALLOC)
  3808. __ast_mm_init_phase_2();
  3809. #endif /* defined(__AST_DEBUG_MALLOC) */
  3810. ast_lastreloadtime = ast_startuptime = ast_tvnow();
  3811. ast_cli_register_multiple(cli_asterisk_shutdown, ARRAY_LEN(cli_asterisk_shutdown));
  3812. ast_cli_register_multiple(cli_asterisk, ARRAY_LEN(cli_asterisk));
  3813. ast_register_cleanup(main_atexit);
  3814. run_startup_commands();
  3815. ast_sd_notify("READY=1");
  3816. ast_verb(0, COLORIZE_FMT "\n", COLORIZE(COLOR_BRGREEN, 0, "Asterisk Ready."));
  3817. logger_queue_start();
  3818. if (ast_opt_console) {
  3819. /* Console stuff now... */
  3820. /* Register our quit function */
  3821. char title[256];
  3822. char hostname[MAXHOSTNAMELEN] = "";
  3823. if (gethostname(hostname, sizeof(hostname) - 1)) {
  3824. ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
  3825. }
  3826. ast_pthread_create_detached(&mon_sig_flags, NULL, monitor_sig_flags, NULL);
  3827. set_icon("Asterisk");
  3828. snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid);
  3829. set_title(title);
  3830. el_set(el, EL_GETCFN, ast_el_read_char);
  3831. for (;;) {
  3832. if (sig_flags.need_el_end) {
  3833. el_end(el);
  3834. return;
  3835. }
  3836. if (sig_flags.need_quit || sig_flags.need_quit_handler) {
  3837. quit_handler(0, SHUTDOWN_FAST, 0);
  3838. break;
  3839. }
  3840. buf = (char *) el_gets(el, &num);
  3841. if (!buf && write(1, "", 1) < 0)
  3842. return; /* quit */
  3843. if (buf) {
  3844. if (buf[strlen(buf)-1] == '\n')
  3845. buf[strlen(buf)-1] = '\0';
  3846. consolehandler(buf);
  3847. }
  3848. }
  3849. }
  3850. /* Stall until a quit signal is given */
  3851. monitor_sig_flags(NULL);
  3852. }