extconf.c 170 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2006, Digium, Inc.
  5. *
  6. * Steve Murphy <murf@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. /*!
  19. * \file extconf
  20. * A condensation of the pbx_config stuff, to read into exensions.conf, and provide an interface to the data there,
  21. * for operations outside of asterisk. A huge, awful hack.
  22. *
  23. */
  24. /*!
  25. * \li \ref extconf.c uses the configuration file \ref extconfig.conf and \ref extensions.conf and \ref asterisk.conf
  26. * \addtogroup configuration_file Configuration Files
  27. */
  28. /*!
  29. * \page extconfig.conf extconfig.conf
  30. * \verbinclude extconfig.conf.sample
  31. */
  32. /*!
  33. * \page extensions.conf extensions.conf
  34. * \verbinclude extensions.conf.sample
  35. */
  36. /*** MODULEINFO
  37. <support_level>extended</support_level>
  38. ***/
  39. #include "asterisk.h"
  40. #undef DEBUG_THREADS
  41. #include "asterisk/compat.h"
  42. #include "asterisk/paths.h" /* we use AST_CONFIG_DIR */
  43. #include <errno.h>
  44. #include <time.h>
  45. #include <sys/stat.h>
  46. #include <sys/types.h>
  47. #include <sys/time.h>
  48. #include <sys/resource.h>
  49. #include <sys/wait.h>
  50. #include <stdarg.h>
  51. #include <string.h>
  52. #include <locale.h>
  53. #include <ctype.h>
  54. #if !defined(SOLARIS) && !defined(__CYGWIN__)
  55. #include <err.h>
  56. #endif
  57. #include <regex.h>
  58. #include <limits.h>
  59. #include <pthread.h>
  60. #include <netdb.h>
  61. #include <sys/param.h>
  62. #include <signal.h>
  63. static void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) __attribute__((format(printf, 5, 6)));
  64. void ast_verbose(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
  65. #define AST_API_MODULE 1 /* gimme the inline defs! */
  66. struct ast_channel
  67. {
  68. char x; /* basically empty! */
  69. };
  70. #include "asterisk/inline_api.h"
  71. #include "asterisk/endian.h"
  72. #include "asterisk/ast_expr.h"
  73. #include "asterisk/extconf.h"
  74. /* logger.h */
  75. #define EVENTLOG "event_log"
  76. #define QUEUELOG "queue_log"
  77. #define DEBUG_M(a) { \
  78. a; \
  79. }
  80. #define VERBOSE_PREFIX_1 " "
  81. #define VERBOSE_PREFIX_2 " == "
  82. #define VERBOSE_PREFIX_3 " -- "
  83. #define VERBOSE_PREFIX_4 " > "
  84. void ast_log_backtrace(void);
  85. void ast_queue_log(const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt, ...)
  86. __attribute__((format(printf, 5, 6)));
  87. /* IN CONFLICT: void ast_verbose(const char *fmt, ...)
  88. __attribute__((format(printf, 1, 2))); */
  89. int ast_register_verbose(void (*verboser)(const char *string));
  90. int ast_unregister_verbose(void (*verboser)(const char *string));
  91. void ast_console_puts(const char *string);
  92. #define _A_ __FILE__, __LINE__, __PRETTY_FUNCTION__
  93. #ifdef LOG_DEBUG
  94. #undef LOG_DEBUG
  95. #endif
  96. #define __LOG_DEBUG 0
  97. #define LOG_DEBUG __LOG_DEBUG, _A_
  98. #ifdef LOG_EVENT
  99. #undef LOG_EVENT
  100. #endif
  101. #define __LOG_EVENT 1
  102. #define LOG_EVENT __LOG_EVENT, _A_
  103. #ifdef LOG_NOTICE
  104. #undef LOG_NOTICE
  105. #endif
  106. #define __LOG_NOTICE 2
  107. #define LOG_NOTICE __LOG_NOTICE, _A_
  108. #ifdef LOG_WARNING
  109. #undef LOG_WARNING
  110. #endif
  111. #define __LOG_WARNING 3
  112. #define LOG_WARNING __LOG_WARNING, _A_
  113. #ifdef LOG_ERROR
  114. #undef LOG_ERROR
  115. #endif
  116. #define __LOG_ERROR 4
  117. #define LOG_ERROR __LOG_ERROR, _A_
  118. #ifdef LOG_VERBOSE
  119. #undef LOG_VERBOSE
  120. #endif
  121. #define __LOG_VERBOSE 5
  122. #define LOG_VERBOSE __LOG_VERBOSE, _A_
  123. #ifdef LOG_DTMF
  124. #undef LOG_DTMF
  125. #endif
  126. #define __LOG_DTMF 6
  127. #define LOG_DTMF __LOG_DTMF, _A_
  128. /* lock.h */
  129. #define _ASTERISK_LOCK_H /* A small indication that this is horribly wrong. */
  130. #ifndef HAVE_MTX_PROFILE
  131. #define __MTX_PROF(a) return pthread_mutex_lock((a))
  132. #else
  133. int mtx_prof = -1;
  134. #define __MTX_PROF(a) do { \
  135. int i; \
  136. /* profile only non-blocking events */ \
  137. ast_mark(mtx_prof, 1); \
  138. i = pthread_mutex_trylock((a)); \
  139. ast_mark(mtx_prof, 0); \
  140. if (!i) \
  141. return i; \
  142. else \
  143. return pthread_mutex_lock((a)); \
  144. } while (0)
  145. #endif /* HAVE_MTX_PROFILE */
  146. #define AST_PTHREADT_NULL (pthread_t) -1
  147. #define AST_PTHREADT_STOP (pthread_t) -2
  148. #if defined(SOLARIS) || defined(BSD)
  149. #define AST_MUTEX_INIT_W_CONSTRUCTORS
  150. #endif /* SOLARIS || BSD */
  151. /* Asterisk REQUIRES recursive (not error checking) mutexes
  152. and will not run without them. */
  153. #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) && defined(PTHREAD_MUTEX_RECURSIVE_NP)
  154. #define PTHREAD_MUTEX_INIT_VALUE PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
  155. #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE_NP
  156. #else
  157. #define PTHREAD_MUTEX_INIT_VALUE PTHREAD_MUTEX_INITIALIZER
  158. #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE
  159. #endif /* PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
  160. #ifdef DEBUG_THREADS
  161. #define log_mutex_error(canlog, ...) do { if (canlog) ast_log(LOG_ERROR, __VA_ARGS__); else fprintf(stderr, __VA_ARGS__); } while (0)
  162. #ifdef THREAD_CRASH
  163. #define DO_THREAD_CRASH do { *((int *)(0)) = 1; } while(0)
  164. #else
  165. #define DO_THREAD_CRASH do { } while (0)
  166. #endif
  167. #define AST_MUTEX_INIT_VALUE { PTHREAD_MUTEX_INIT_VALUE, { NULL }, { 0 }, 0, { NULL }, { 0 } }
  168. #define AST_MAX_REENTRANCY 10
  169. struct ast_mutex_info {
  170. pthread_mutex_t mutex;
  171. /*! Track which thread holds this lock */
  172. unsigned int track:1;
  173. const char *file[AST_MAX_REENTRANCY];
  174. int lineno[AST_MAX_REENTRANCY];
  175. int reentrancy;
  176. const char *func[AST_MAX_REENTRANCY];
  177. pthread_t thread[AST_MAX_REENTRANCY];
  178. };
  179. typedef struct ast_mutex_info ast_mutex_t;
  180. typedef pthread_cond_t ast_cond_t;
  181. static pthread_mutex_t empty_mutex;
  182. static void __attribute__((constructor)) init_empty_mutex(void)
  183. {
  184. memset(&empty_mutex, 0, sizeof(empty_mutex));
  185. }
  186. static inline int __ast_pthread_mutex_init_attr(const char *filename, int lineno, const char *func,
  187. const char *mutex_name, ast_mutex_t *t,
  188. pthread_mutexattr_t *attr)
  189. {
  190. #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
  191. int canlog = strcmp(filename, "logger.c");
  192. if ((t->mutex) != ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
  193. if ((t->mutex) != (empty_mutex)) {
  194. log_mutex_error(canlog, "%s line %d (%s): Error: mutex '%s' is already initialized.\n",
  195. filename, lineno, func, mutex_name);
  196. log_mutex_error(canlog, "%s line %d (%s): Error: previously initialization of mutex '%s'.\n",
  197. t->file[0], t->lineno[0], t->func[0], mutex_name);
  198. DO_THREAD_CRASH;
  199. return 0;
  200. }
  201. }
  202. #endif
  203. t->file[0] = filename;
  204. t->lineno[0] = lineno;
  205. t->func[0] = func;
  206. t->thread[0] = 0;
  207. t->reentrancy = 0;
  208. return pthread_mutex_init(&t->mutex, attr);
  209. }
  210. static inline int __ast_pthread_mutex_init(const char *filename, int lineno, const char *func,
  211. const char *mutex_name, ast_mutex_t *t)
  212. {
  213. static pthread_mutexattr_t attr;
  214. pthread_mutexattr_init(&attr);
  215. pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
  216. return __ast_pthread_mutex_init_attr(filename, lineno, func, mutex_name, t, &attr);
  217. }
  218. #define ast_mutex_init(pmutex) __ast_pthread_mutex_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex)
  219. static inline int __ast_pthread_mutex_destroy(const char *filename, int lineno, const char *func,
  220. const char *mutex_name, ast_mutex_t *t)
  221. {
  222. int res;
  223. int canlog = strcmp(filename, "logger.c");
  224. #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
  225. if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
  226. log_mutex_error(canlog, "%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
  227. filename, lineno, func, mutex_name);
  228. }
  229. #endif
  230. res = pthread_mutex_trylock(&t->mutex);
  231. switch (res) {
  232. case 0:
  233. pthread_mutex_unlock(&t->mutex);
  234. break;
  235. case EINVAL:
  236. log_mutex_error(canlog, "%s line %d (%s): Error: attempt to destroy invalid mutex '%s'.\n",
  237. filename, lineno, func, mutex_name);
  238. break;
  239. case EBUSY:
  240. log_mutex_error(canlog, "%s line %d (%s): Error: attempt to destroy locked mutex '%s'.\n",
  241. filename, lineno, func, mutex_name);
  242. log_mutex_error(canlog, "%s line %d (%s): Error: '%s' was locked here.\n",
  243. t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
  244. break;
  245. }
  246. if ((res = pthread_mutex_destroy(&t->mutex)))
  247. log_mutex_error(canlog, "%s line %d (%s): Error destroying mutex: %s\n",
  248. filename, lineno, func, strerror(res));
  249. #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
  250. else
  251. t->mutex = PTHREAD_MUTEX_INIT_VALUE;
  252. #endif
  253. t->file[0] = filename;
  254. t->lineno[0] = lineno;
  255. t->func[0] = func;
  256. return res;
  257. }
  258. static inline int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func,
  259. const char* mutex_name, ast_mutex_t *t)
  260. {
  261. int res;
  262. int canlog = strcmp(filename, "logger.c");
  263. #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
  264. if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
  265. log_mutex_error(canlog, "%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
  266. filename, lineno, func, mutex_name);
  267. ast_mutex_init(t);
  268. }
  269. #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
  270. #ifdef DETECT_DEADLOCKS
  271. {
  272. time_t seconds = time(NULL);
  273. time_t current;
  274. do {
  275. #ifdef HAVE_MTX_PROFILE
  276. ast_mark(mtx_prof, 1);
  277. #endif
  278. res = pthread_mutex_trylock(&t->mutex);
  279. #ifdef HAVE_MTX_PROFILE
  280. ast_mark(mtx_prof, 0);
  281. #endif
  282. if (res == EBUSY) {
  283. current = time(NULL);
  284. if ((current - seconds) && (!((current - seconds) % 5))) {
  285. log_mutex_error(canlog, "%s line %d (%s): Deadlock? waited %d sec for mutex '%s'?\n",
  286. filename, lineno, func, (int)(current - seconds), mutex_name);
  287. log_mutex_error(canlog, "%s line %d (%s): '%s' was locked here.\n",
  288. t->file[t->reentrancy-1], t->lineno[t->reentrancy-1],
  289. t->func[t->reentrancy-1], mutex_name);
  290. }
  291. usleep(200);
  292. }
  293. } while (res == EBUSY);
  294. }
  295. #else
  296. #ifdef HAVE_MTX_PROFILE
  297. ast_mark(mtx_prof, 1);
  298. res = pthread_mutex_trylock(&t->mutex);
  299. ast_mark(mtx_prof, 0);
  300. if (res)
  301. #endif
  302. res = pthread_mutex_lock(&t->mutex);
  303. #endif /* DETECT_DEADLOCKS */
  304. if (!res) {
  305. if (t->reentrancy < AST_MAX_REENTRANCY) {
  306. t->file[t->reentrancy] = filename;
  307. t->lineno[t->reentrancy] = lineno;
  308. t->func[t->reentrancy] = func;
  309. t->thread[t->reentrancy] = pthread_self();
  310. t->reentrancy++;
  311. } else {
  312. log_mutex_error(canlog, "%s line %d (%s): '%s' really deep reentrancy!\n",
  313. filename, lineno, func, mutex_name);
  314. }
  315. } else {
  316. log_mutex_error(canlog, "%s line %d (%s): Error obtaining mutex: %s\n",
  317. filename, lineno, func, strerror(errno));
  318. DO_THREAD_CRASH;
  319. }
  320. return res;
  321. }
  322. static inline int __ast_pthread_mutex_trylock(const char *filename, int lineno, const char *func,
  323. const char* mutex_name, ast_mutex_t *t)
  324. {
  325. int res;
  326. int canlog = strcmp(filename, "logger.c");
  327. #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
  328. if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
  329. log_mutex_error(canlog, "%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
  330. filename, lineno, func, mutex_name);
  331. ast_mutex_init(t);
  332. }
  333. #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
  334. if (!(res = pthread_mutex_trylock(&t->mutex))) {
  335. if (t->reentrancy < AST_MAX_REENTRANCY) {
  336. t->file[t->reentrancy] = filename;
  337. t->lineno[t->reentrancy] = lineno;
  338. t->func[t->reentrancy] = func;
  339. t->thread[t->reentrancy] = pthread_self();
  340. t->reentrancy++;
  341. } else {
  342. log_mutex_error(canlog, "%s line %d (%s): '%s' really deep reentrancy!\n",
  343. filename, lineno, func, mutex_name);
  344. }
  345. } else {
  346. log_mutex_error(canlog, "%s line %d (%s): Warning: '%s' was locked here.\n",
  347. t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
  348. }
  349. return res;
  350. }
  351. static inline int __ast_pthread_mutex_unlock(const char *filename, int lineno, const char *func,
  352. const char *mutex_name, ast_mutex_t *t)
  353. {
  354. int res;
  355. int canlog = strcmp(filename, "logger.c");
  356. #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
  357. if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
  358. log_mutex_error(canlog, "%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
  359. filename, lineno, func, mutex_name);
  360. }
  361. #endif
  362. if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
  363. log_mutex_error(canlog, "%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
  364. filename, lineno, func, mutex_name);
  365. log_mutex_error(canlog, "%s line %d (%s): '%s' was locked here.\n",
  366. t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
  367. DO_THREAD_CRASH;
  368. }
  369. if (--t->reentrancy < 0) {
  370. log_mutex_error(canlog, "%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
  371. filename, lineno, func, mutex_name);
  372. t->reentrancy = 0;
  373. }
  374. if (t->reentrancy < AST_MAX_REENTRANCY) {
  375. t->file[t->reentrancy] = NULL;
  376. t->lineno[t->reentrancy] = 0;
  377. t->func[t->reentrancy] = NULL;
  378. t->thread[t->reentrancy] = 0;
  379. }
  380. if ((res = pthread_mutex_unlock(&t->mutex))) {
  381. log_mutex_error(canlog, "%s line %d (%s): Error releasing mutex: %s\n",
  382. filename, lineno, func, strerror(res));
  383. DO_THREAD_CRASH;
  384. }
  385. return res;
  386. }
  387. #else /* !DEBUG_THREADS */
  388. typedef pthread_mutex_t ast_mutex_t;
  389. #define AST_MUTEX_INIT_VALUE ((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE)
  390. static inline int ast_mutex_init(ast_mutex_t *pmutex)
  391. {
  392. pthread_mutexattr_t attr;
  393. pthread_mutexattr_init(&attr);
  394. pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
  395. return pthread_mutex_init(pmutex, &attr);
  396. }
  397. #define ast_pthread_mutex_init(pmutex,a) pthread_mutex_init(pmutex,a)
  398. typedef pthread_cond_t ast_cond_t;
  399. #endif /* !DEBUG_THREADS */
  400. #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
  401. /* If AST_MUTEX_INIT_W_CONSTRUCTORS is defined, use file scope
  402. constructors/destructors to create/destroy mutexes. */
  403. #define __AST_MUTEX_DEFINE(scope, mutex) \
  404. scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE; \
  405. static void __attribute__((constructor)) init_##mutex(void) \
  406. { \
  407. ast_mutex_init(&mutex); \
  408. }
  409. #else /* !AST_MUTEX_INIT_W_CONSTRUCTORS */
  410. /* By default, use static initialization of mutexes. */
  411. #define __AST_MUTEX_DEFINE(scope, mutex) \
  412. scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE
  413. #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
  414. #define pthread_mutex_t use_ast_mutex_t_instead_of_pthread_mutex_t
  415. #define pthread_mutex_init use_ast_mutex_init_instead_of_pthread_mutex_init
  416. #define pthread_cond_t use_ast_cond_t_instead_of_pthread_cond_t
  417. #define AST_MUTEX_DEFINE_STATIC(mutex) __AST_MUTEX_DEFINE(static, mutex)
  418. #define AST_MUTEX_INITIALIZER __use_AST_MUTEX_DEFINE_STATIC_rather_than_AST_MUTEX_INITIALIZER__
  419. #define gethostbyname __gethostbyname__is__not__reentrant__use__ast_gethostbyname__instead__
  420. #ifndef __linux__
  421. #define pthread_create __use_ast_pthread_create_instead__
  422. #endif
  423. typedef pthread_rwlock_t ast_rwlock_t;
  424. static inline int ast_rwlock_init(ast_rwlock_t *prwlock)
  425. {
  426. pthread_rwlockattr_t attr;
  427. pthread_rwlockattr_init(&attr);
  428. #ifdef HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP
  429. pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NP);
  430. #endif
  431. return pthread_rwlock_init(prwlock, &attr);
  432. }
  433. static inline int ast_rwlock_destroy(ast_rwlock_t *prwlock)
  434. {
  435. return pthread_rwlock_destroy(prwlock);
  436. }
  437. static inline int ast_rwlock_unlock(ast_rwlock_t *prwlock)
  438. {
  439. return pthread_rwlock_unlock(prwlock);
  440. }
  441. static inline int ast_rwlock_rdlock(ast_rwlock_t *prwlock)
  442. {
  443. return pthread_rwlock_rdlock(prwlock);
  444. }
  445. static inline int ast_rwlock_wrlock(ast_rwlock_t *prwlock)
  446. {
  447. return pthread_rwlock_wrlock(prwlock);
  448. }
  449. /* Statically declared read/write locks */
  450. #ifndef HAVE_PTHREAD_RWLOCK_INITIALIZER
  451. #define __AST_RWLOCK_DEFINE(scope, rwlock) \
  452. scope ast_rwlock_t rwlock; \
  453. static void __attribute__((constructor)) init_##rwlock(void) \
  454. { \
  455. ast_rwlock_init(&rwlock); \
  456. } \
  457. static void __attribute__((destructor)) fini_##rwlock(void) \
  458. { \
  459. ast_rwlock_destroy(&rwlock); \
  460. }
  461. #else
  462. #define AST_RWLOCK_INIT_VALUE PTHREAD_RWLOCK_INITIALIZER
  463. #define __AST_RWLOCK_DEFINE(scope, rwlock) \
  464. scope ast_rwlock_t rwlock = AST_RWLOCK_INIT_VALUE
  465. #endif
  466. #define AST_RWLOCK_DEFINE_STATIC(rwlock) __AST_RWLOCK_DEFINE(static, rwlock)
  467. /*
  468. * Initial support for atomic instructions.
  469. * For platforms that have it, use the native cpu instruction to
  470. * implement them. For other platforms, resort to a 'slow' version
  471. * (defined in utils.c) that protects the atomic instruction with
  472. * a single lock.
  473. * The slow versions is always available, for testing purposes,
  474. * as ast_atomic_fetchadd_int_slow()
  475. */
  476. #if defined(HAVE_OSX_ATOMICS)
  477. #include "libkern/OSAtomic.h"
  478. #endif
  479. /*! \brief Atomically add v to *p and return * the previous value of *p.
  480. * This can be used to handle reference counts, and the return value
  481. * can be used to generate unique identifiers.
  482. */
  483. #if defined(HAVE_GCC_ATOMICS)
  484. AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
  485. {
  486. return __sync_fetch_and_add(p, v);
  487. })
  488. #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
  489. AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
  490. {
  491. return OSAtomicAdd32(v, (int32_t *) p);
  492. })
  493. #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
  494. AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
  495. {
  496. return OSAtomicAdd64(v, (int64_t *) p);
  497. #elif defined (__i386__) || defined(__x86_64__)
  498. AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
  499. {
  500. __asm __volatile (
  501. " lock xaddl %0, %1 ; "
  502. : "+r" (v), /* 0 (result) */
  503. "=m" (*p) /* 1 */
  504. : "m" (*p)); /* 2 */
  505. return (v);
  506. })
  507. #else
  508. static int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
  509. {
  510. int ret;
  511. ret = *p;
  512. *p += v;
  513. return ret;
  514. }
  515. AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
  516. {
  517. return ast_atomic_fetchadd_int_slow(p, v);
  518. })
  519. #endif
  520. /*! \brief decrement *p by 1 and return true if the variable has reached 0.
  521. * Useful e.g. to check if a refcount has reached 0.
  522. */
  523. #if defined(HAVE_GCC_ATOMICS)
  524. AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
  525. {
  526. return __sync_sub_and_fetch(p, 1) == 0;
  527. })
  528. #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
  529. AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
  530. {
  531. return OSAtomicAdd32( -1, (int32_t *) p) == 0;
  532. })
  533. #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
  534. AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
  535. {
  536. return OSAtomicAdd64( -1, (int64_t *) p) == 0;
  537. #else
  538. AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
  539. {
  540. int a = ast_atomic_fetchadd_int(p, -1);
  541. return a == 1; /* true if the value is 0 now (so it was 1 previously) */
  542. })
  543. #endif
  544. #ifdef DEBUG_CHANNEL_LOCKS
  545. /*! \brief Lock AST channel (and print debugging output)
  546. \note You need to enable DEBUG_CHANNEL_LOCKS for this function */
  547. int ast_channel_lock(struct ast_channel *chan);
  548. /*! \brief Unlock AST channel (and print debugging output)
  549. \note You need to enable DEBUG_CHANNEL_LOCKS for this function
  550. */
  551. int ast_channel_unlock(struct ast_channel *chan);
  552. /*! \brief Lock AST channel (and print debugging output)
  553. \note You need to enable DEBUG_CHANNEL_LOCKS for this function */
  554. int ast_channel_trylock(struct ast_channel *chan);
  555. #endif
  556. #include "asterisk/hashtab.h"
  557. #include "asterisk/ael_structs.h"
  558. #include "asterisk/pval.h"
  559. /* from utils.h */
  560. #define ast_free free
  561. #define ast_free_ptr free
  562. #define MALLOC_FAILURE_MSG \
  563. ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
  564. /*!
  565. * \brief A wrapper for malloc()
  566. *
  567. * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
  568. * message in the case that the allocation fails.
  569. *
  570. * The argument and return value are the same as malloc()
  571. */
  572. #define ast_malloc(len) \
  573. _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
  574. #define ast_calloc(num, len) \
  575. _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
  576. #define ast_calloc_cache(num, len) \
  577. _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
  578. #define ast_realloc(p, len) \
  579. _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
  580. #define ast_strdup(str) \
  581. _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
  582. #define ast_strndup(str, len) \
  583. _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
  584. #define ast_asprintf(ret, fmt, ...) \
  585. _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
  586. #define ast_vasprintf(ret, fmt, ap) \
  587. _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
  588. struct ast_flags { /* stolen from utils.h */
  589. unsigned int flags;
  590. };
  591. #define ast_test_flag(p,flag) ({ \
  592. typeof ((p)->flags) __p = (p)->flags; \
  593. unsigned int __x = 0; \
  594. (void) (&__p == &__x); \
  595. ((p)->flags & (flag)); \
  596. })
  597. #define ast_set2_flag(p,value,flag) do { \
  598. typeof ((p)->flags) __p = (p)->flags; \
  599. unsigned int __x = 0; \
  600. (void) (&__p == &__x); \
  601. if (value) \
  602. (p)->flags |= (flag); \
  603. else \
  604. (p)->flags &= ~(flag); \
  605. } while (0)
  606. #define MALLOC_FAILURE_MSG \
  607. ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
  608. /*!
  609. * \brief A wrapper for malloc()
  610. *
  611. * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
  612. * message in the case that the allocation fails.
  613. *
  614. * The argument and return value are the same as malloc()
  615. */
  616. #define ast_malloc(len) \
  617. _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
  618. AST_INLINE_API(
  619. void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
  620. {
  621. void *p;
  622. if (!(p = malloc(len)))
  623. MALLOC_FAILURE_MSG;
  624. return p;
  625. }
  626. )
  627. /*!
  628. * \brief A wrapper for calloc()
  629. *
  630. * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
  631. * message in the case that the allocation fails.
  632. *
  633. * The arguments and return value are the same as calloc()
  634. */
  635. #define ast_calloc(num, len) \
  636. _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
  637. AST_INLINE_API(
  638. void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
  639. {
  640. void *p;
  641. if (!(p = calloc(num, len)))
  642. MALLOC_FAILURE_MSG;
  643. return p;
  644. }
  645. )
  646. /*!
  647. * \brief A wrapper for calloc() for use in cache pools
  648. *
  649. * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log
  650. * message in the case that the allocation fails. When memory debugging is in use,
  651. * the memory allocated by this function will be marked as 'cache' so it can be
  652. * distinguished from normal memory allocations.
  653. *
  654. * The arguments and return value are the same as calloc()
  655. */
  656. #define ast_calloc_cache(num, len) \
  657. _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
  658. /*!
  659. * \brief A wrapper for realloc()
  660. *
  661. * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
  662. * message in the case that the allocation fails.
  663. *
  664. * The arguments and return value are the same as realloc()
  665. */
  666. #define ast_realloc(p, len) \
  667. _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
  668. AST_INLINE_API(
  669. void *_ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
  670. {
  671. void *newp;
  672. if (!(newp = realloc(p, len)))
  673. MALLOC_FAILURE_MSG;
  674. return newp;
  675. }
  676. )
  677. /*!
  678. * \brief A wrapper for strdup()
  679. *
  680. * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
  681. * message in the case that the allocation fails.
  682. *
  683. * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
  684. * argument is provided, ast_strdup will return NULL without generating any
  685. * kind of error log message.
  686. *
  687. * The argument and return value are the same as strdup()
  688. */
  689. #define ast_strdup(str) \
  690. _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
  691. AST_INLINE_API(
  692. char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
  693. {
  694. char *newstr = NULL;
  695. if (str) {
  696. if (!(newstr = strdup(str)))
  697. MALLOC_FAILURE_MSG;
  698. }
  699. return newstr;
  700. }
  701. )
  702. /*!
  703. * \brief A wrapper for strndup()
  704. *
  705. * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
  706. * message in the case that the allocation fails.
  707. *
  708. * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
  709. * string to duplicate. If a NULL argument is provided, ast_strdup will return
  710. * NULL without generating any kind of error log message.
  711. *
  712. * The arguments and return value are the same as strndup()
  713. */
  714. #define ast_strndup(str, len) \
  715. _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
  716. AST_INLINE_API(
  717. char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
  718. {
  719. char *newstr = NULL;
  720. if (str) {
  721. if (!(newstr = strndup(str, len)))
  722. MALLOC_FAILURE_MSG;
  723. }
  724. return newstr;
  725. }
  726. )
  727. /*!
  728. * \brief A wrapper for asprintf()
  729. *
  730. * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log
  731. * message in the case that the allocation fails.
  732. *
  733. * The arguments and return value are the same as asprintf()
  734. */
  735. #define ast_asprintf(ret, fmt, ...) \
  736. _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
  737. AST_INLINE_API(
  738. __attribute__((format(printf, 5, 6)))
  739. int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...),
  740. {
  741. int res;
  742. va_list ap;
  743. va_start(ap, fmt);
  744. if ((res = vasprintf(ret, fmt, ap)) == -1)
  745. MALLOC_FAILURE_MSG;
  746. va_end(ap);
  747. return res;
  748. }
  749. )
  750. /*!
  751. * \brief A wrapper for vasprintf()
  752. *
  753. * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log
  754. * message in the case that the allocation fails.
  755. *
  756. * The arguments and return value are the same as vasprintf()
  757. */
  758. #define ast_vasprintf(ret, fmt, ap) \
  759. _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
  760. AST_INLINE_API(
  761. __attribute__((format(printf, 5, 0)))
  762. int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
  763. {
  764. int res;
  765. if ((res = vasprintf(ret, fmt, ap)) == -1)
  766. MALLOC_FAILURE_MSG;
  767. return res;
  768. }
  769. )
  770. #if !defined(ast_strdupa) && defined(__GNUC__)
  771. /*!
  772. \brief duplicate a string in memory from the stack
  773. \param s The string to duplicate
  774. This macro will duplicate the given string. It returns a pointer to the stack
  775. allocatted memory for the new string.
  776. */
  777. #define ast_strdupa(s) \
  778. (__extension__ \
  779. ({ \
  780. const char *__old = (s); \
  781. size_t __len = strlen(__old) + 1; \
  782. char *__new = __builtin_alloca(__len); \
  783. memcpy (__new, __old, __len); \
  784. __new; \
  785. }))
  786. #endif
  787. /* from config.c */
  788. #define MAX_NESTED_COMMENTS 128
  789. #define COMMENT_START ";--"
  790. #define COMMENT_END "--;"
  791. #define COMMENT_META ';'
  792. #define COMMENT_TAG '-'
  793. static char *extconfig_conf = "extconfig.conf";
  794. /*! Growable string buffer */
  795. static char *comment_buffer; /*!< this will be a comment collector.*/
  796. static int comment_buffer_size; /*!< the amount of storage so far alloc'd for the comment_buffer */
  797. static char *lline_buffer; /*!< A buffer for stuff behind the ; */
  798. static int lline_buffer_size;
  799. #define CB_INCR 250
  800. struct ast_comment {
  801. struct ast_comment *next;
  802. char cmt[0];
  803. };
  804. static void CB_INIT(void)
  805. {
  806. if (!comment_buffer) {
  807. comment_buffer = ast_malloc(CB_INCR);
  808. if (!comment_buffer)
  809. return;
  810. comment_buffer[0] = 0;
  811. comment_buffer_size = CB_INCR;
  812. lline_buffer = ast_malloc(CB_INCR);
  813. if (!lline_buffer)
  814. return;
  815. lline_buffer[0] = 0;
  816. lline_buffer_size = CB_INCR;
  817. } else {
  818. comment_buffer[0] = 0;
  819. lline_buffer[0] = 0;
  820. }
  821. }
  822. static void CB_ADD(char *str)
  823. {
  824. int rem = comment_buffer_size - strlen(comment_buffer) - 1;
  825. int siz = strlen(str);
  826. if (rem < siz+1) {
  827. comment_buffer = ast_realloc(comment_buffer, comment_buffer_size + CB_INCR + siz + 1);
  828. if (!comment_buffer)
  829. return;
  830. comment_buffer_size += CB_INCR+siz+1;
  831. }
  832. strcat(comment_buffer,str);
  833. }
  834. static void CB_ADD_LEN(char *str, int len)
  835. {
  836. int cbl = strlen(comment_buffer) + 1;
  837. int rem = comment_buffer_size - cbl;
  838. if (rem < len+1) {
  839. comment_buffer = ast_realloc(comment_buffer, comment_buffer_size + CB_INCR + len + 1);
  840. if (!comment_buffer)
  841. return;
  842. comment_buffer_size += CB_INCR+len+1;
  843. }
  844. strncat(comment_buffer,str,len); /* safe */
  845. comment_buffer[cbl+len-1] = 0;
  846. }
  847. static void LLB_ADD(char *str)
  848. {
  849. int rem = lline_buffer_size - strlen(lline_buffer) - 1;
  850. int siz = strlen(str);
  851. if (rem < siz+1) {
  852. lline_buffer = ast_realloc(lline_buffer, lline_buffer_size + CB_INCR + siz + 1);
  853. if (!lline_buffer)
  854. return;
  855. lline_buffer_size += CB_INCR + siz + 1;
  856. }
  857. strcat(lline_buffer,str);
  858. }
  859. static void CB_RESET(void )
  860. {
  861. comment_buffer[0] = 0;
  862. lline_buffer[0] = 0;
  863. }
  864. /*! \brief Keep track of how many threads are currently trying to wait*() on
  865. * a child process */
  866. static unsigned int safe_system_level = 0;
  867. static struct sigaction safe_system_prev_handler;
  868. /*! \brief NULL handler so we can collect the child exit status */
  869. static void _null_sig_handler(int sig)
  870. {
  871. }
  872. static struct sigaction null_sig_handler = {
  873. .sa_handler = _null_sig_handler,
  874. .sa_flags = SA_RESTART,
  875. };
  876. void ast_replace_sigchld(void);
  877. void ast_replace_sigchld(void)
  878. {
  879. unsigned int level;
  880. level = safe_system_level++;
  881. /* only replace the handler if it has not already been done */
  882. if (level == 0) {
  883. sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
  884. }
  885. }
  886. void ast_unreplace_sigchld(void);
  887. void ast_unreplace_sigchld(void)
  888. {
  889. unsigned int level;
  890. level = --safe_system_level;
  891. /* only restore the handler if we are the last one */
  892. if (level == 0) {
  893. sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
  894. }
  895. }
  896. int ast_safe_system(const char *s);
  897. int ast_safe_system(const char *s)
  898. {
  899. pid_t pid;
  900. #ifdef HAVE_WORKING_FORK
  901. int x;
  902. #endif
  903. int res;
  904. int status;
  905. #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
  906. ast_replace_sigchld();
  907. #ifdef HAVE_WORKING_FORK
  908. pid = fork();
  909. #else
  910. pid = vfork();
  911. #endif
  912. if (pid == 0) {
  913. #ifdef HAVE_WORKING_FORK
  914. /* Close file descriptors and launch system command */
  915. for (x = STDERR_FILENO + 1; x < 4096; x++)
  916. close(x);
  917. #endif
  918. execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
  919. _exit(1);
  920. } else if (pid > 0) {
  921. for(;;) {
  922. res = waitpid(pid, &status, 0);
  923. if (res > -1) {
  924. res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
  925. break;
  926. } else if (errno != EINTR)
  927. break;
  928. }
  929. } else {
  930. ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
  931. res = -1;
  932. }
  933. ast_unreplace_sigchld();
  934. #else
  935. res = -1;
  936. #endif
  937. return res;
  938. }
  939. static struct ast_comment *ALLOC_COMMENT(const char *buffer)
  940. {
  941. struct ast_comment *x = ast_calloc(1,sizeof(struct ast_comment)+strlen(buffer)+1);
  942. strcpy(x->cmt, buffer);
  943. return x;
  944. }
  945. static struct ast_config_map {
  946. struct ast_config_map *next;
  947. char *name;
  948. char *driver;
  949. char *database;
  950. char *table;
  951. char stuff[0];
  952. } *config_maps = NULL;
  953. static struct ast_config_engine *config_engine_list;
  954. #define MAX_INCLUDE_LEVEL 10
  955. struct ast_category {
  956. char name[80];
  957. int ignored; /*!< do not let user of the config see this category */
  958. int include_level;
  959. char *file; /*!< the file name from whence this declaration was read */
  960. int lineno;
  961. struct ast_comment *precomments;
  962. struct ast_comment *sameline;
  963. struct ast_variable *root;
  964. struct ast_variable *last;
  965. struct ast_category *next;
  966. };
  967. struct ast_config {
  968. struct ast_category *root;
  969. struct ast_category *last;
  970. struct ast_category *current;
  971. struct ast_category *last_browse; /*!< used to cache the last category supplied via category_browse */
  972. int include_level;
  973. int max_include_level;
  974. struct ast_config_include *includes; /*!< a list of inclusions, which should describe the entire tree */
  975. };
  976. struct ast_config_include {
  977. char *include_location_file; /*!< file name in which the include occurs */
  978. int include_location_lineno; /*!< lineno where include occurred */
  979. int exec; /*!< set to non-zero if itsa #exec statement */
  980. char *exec_file; /*!< if it's an exec, you'll have both the /var/tmp to read, and the original script */
  981. char *included_file; /*!< file name included */
  982. int inclusion_count; /*!< if the file is included more than once, a running count thereof -- but, worry not,
  983. we explode the instances and will include those-- so all entries will be unique */
  984. int output; /*!< a flag to indicate if the inclusion has been output */
  985. struct ast_config_include *next; /*!< ptr to next inclusion in the list */
  986. };
  987. typedef struct ast_config *config_load_func(const char *database, const char *table, const char *configfile, struct ast_config *config, int withcomments, const char *suggested_include_file);
  988. typedef struct ast_variable *realtime_var_get(const char *database, const char *table, va_list ap);
  989. typedef struct ast_config *realtime_multi_get(const char *database, const char *table, va_list ap);
  990. typedef int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
  991. /*! \brief Configuration engine structure, used to define realtime drivers */
  992. struct ast_config_engine {
  993. char *name;
  994. config_load_func *load_func;
  995. realtime_var_get *realtime_func;
  996. realtime_multi_get *realtime_multi_func;
  997. realtime_update *update_func;
  998. struct ast_config_engine *next;
  999. };
  1000. static struct ast_config_engine *config_engine_list;
  1001. /* taken from strings.h */
  1002. static force_inline int ast_strlen_zero(const char *s)
  1003. {
  1004. return (!s || (*s == '\0'));
  1005. }
  1006. #define S_OR(a, b) (!ast_strlen_zero(a) ? (a) : (b))
  1007. AST_INLINE_API(
  1008. void ast_copy_string(char *dst, const char *src, size_t size),
  1009. {
  1010. while (*src && size) {
  1011. *dst++ = *src++;
  1012. size--;
  1013. }
  1014. if (__builtin_expect(!size, 0))
  1015. dst--;
  1016. *dst = '\0';
  1017. }
  1018. )
  1019. AST_INLINE_API(
  1020. char *ast_skip_blanks(const char *str),
  1021. {
  1022. while (*str && *str < 33)
  1023. str++;
  1024. return (char *)str;
  1025. }
  1026. )
  1027. /*!
  1028. \brief Trims trailing whitespace characters from a string.
  1029. \param ast_trim_blanks function being used
  1030. \param str the input string
  1031. \return a pointer to the modified string
  1032. */
  1033. AST_INLINE_API(
  1034. char *ast_trim_blanks(char *str),
  1035. {
  1036. char *work = str;
  1037. if (work) {
  1038. work += strlen(work) - 1;
  1039. /* It's tempting to only want to erase after we exit this loop,
  1040. but since ast_trim_blanks *could* receive a constant string
  1041. (which we presumably wouldn't have to touch), we shouldn't
  1042. actually set anything unless we must, and it's easier just
  1043. to set each position to \0 than to keep track of a variable
  1044. for it */
  1045. while ((work >= str) && *work < 33)
  1046. *(work--) = '\0';
  1047. }
  1048. return str;
  1049. }
  1050. )
  1051. /*!
  1052. \brief Strip leading/trailing whitespace from a string.
  1053. \param s The string to be stripped (will be modified).
  1054. \return The stripped string.
  1055. This functions strips all leading and trailing whitespace
  1056. characters from the input string, and returns a pointer to
  1057. the resulting string. The string is modified in place.
  1058. */
  1059. AST_INLINE_API(
  1060. char *ast_strip(char *s),
  1061. {
  1062. s = ast_skip_blanks(s);
  1063. if (s)
  1064. ast_trim_blanks(s);
  1065. return s;
  1066. }
  1067. )
  1068. /* from config.h */
  1069. struct ast_variable {
  1070. char *name;
  1071. char *value;
  1072. char *file;
  1073. int lineno;
  1074. int object; /*!< 0 for variable, 1 for object */
  1075. int blanklines; /*!< Number of blanklines following entry */
  1076. struct ast_comment *precomments;
  1077. struct ast_comment *sameline;
  1078. struct ast_variable *next;
  1079. char stuff[0];
  1080. };
  1081. static const char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable);
  1082. static struct ast_config *config_text_file_load(const char *database, const char *table, const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_include_file);
  1083. struct ast_config *localized_config_load_with_comments(const char *filename);
  1084. static char *ast_category_browse(struct ast_config *config, const char *prev);
  1085. static struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category);
  1086. static void ast_variables_destroy(struct ast_variable *v);
  1087. static void ast_config_destroy(struct ast_config *cfg);
  1088. static struct ast_config_include *ast_include_new(struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size);
  1089. static struct ast_config_include *ast_include_find(struct ast_config *conf, const char *included_file);
  1090. void localized_ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file);
  1091. static struct ast_variable *ast_variable_new(const char *name, const char *value, const char *filename);
  1092. static struct ast_variable *ast_variable_new(const char *name, const char *value, const char *filename)
  1093. {
  1094. struct ast_variable *variable;
  1095. int name_len = strlen(name) + 1;
  1096. if ((variable = ast_calloc(1, name_len + strlen(value) + 1 + strlen(filename) + 1 + sizeof(*variable)))) {
  1097. variable->name = variable->stuff;
  1098. variable->value = variable->stuff + name_len;
  1099. variable->file = variable->value + strlen(value) + 1;
  1100. strcpy(variable->name,name);
  1101. strcpy(variable->value,value);
  1102. strcpy(variable->file,filename);
  1103. }
  1104. return variable;
  1105. }
  1106. static struct ast_config_include *ast_include_new(struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size)
  1107. {
  1108. /* a file should be included ONCE. Otherwise, if one of the instances is changed,
  1109. then all be changed. -- how do we know to include it? -- Handling modified
  1110. instances is possible, I'd have
  1111. to create a new master for each instance. */
  1112. struct ast_config_include *inc;
  1113. inc = ast_include_find(conf, included_file);
  1114. if (inc)
  1115. {
  1116. inc->inclusion_count++;
  1117. snprintf(real_included_file_name, real_included_file_name_size, "%s~~%d", included_file, inc->inclusion_count);
  1118. ast_log(LOG_WARNING,"'%s', line %d: Same File included more than once! This data will be saved in %s if saved back to disk.\n", from_file, from_lineno, real_included_file_name);
  1119. } else
  1120. *real_included_file_name = 0;
  1121. inc = ast_calloc(1,sizeof(struct ast_config_include));
  1122. inc->include_location_file = ast_strdup(from_file);
  1123. inc->include_location_lineno = from_lineno;
  1124. if (!ast_strlen_zero(real_included_file_name))
  1125. inc->included_file = ast_strdup(real_included_file_name);
  1126. else
  1127. inc->included_file = ast_strdup(included_file);
  1128. inc->exec = is_exec;
  1129. if (is_exec)
  1130. inc->exec_file = ast_strdup(exec_file);
  1131. /* attach this new struct to the conf struct */
  1132. inc->next = conf->includes;
  1133. conf->includes = inc;
  1134. return inc;
  1135. }
  1136. void localized_ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file)
  1137. {
  1138. struct ast_config_include *incl;
  1139. struct ast_category *cat;
  1140. struct ast_variable *v;
  1141. int from_len = strlen(from_file);
  1142. int to_len = strlen(to_file);
  1143. if (strcmp(from_file, to_file) == 0) /* no use wasting time if the name is the same */
  1144. return;
  1145. /* the manager code allows you to read in one config file, then
  1146. write it back out under a different name. But, the new arrangement
  1147. ties output lines to the file name. So, before you try to write
  1148. the config file to disk, better riffle thru the data and make sure
  1149. the file names are changed.
  1150. */
  1151. /* file names are on categories, includes (of course), and on variables. So,
  1152. traverse all this and swap names */
  1153. for (incl = conf->includes; incl; incl=incl->next) {
  1154. if (strcmp(incl->include_location_file,from_file) == 0) {
  1155. if (from_len >= to_len)
  1156. strcpy(incl->include_location_file, to_file);
  1157. else {
  1158. free(incl->include_location_file);
  1159. incl->include_location_file = strdup(to_file);
  1160. }
  1161. }
  1162. }
  1163. for (cat = conf->root; cat; cat = cat->next) {
  1164. if (strcmp(cat->file,from_file) == 0) {
  1165. if (from_len >= to_len)
  1166. strcpy(cat->file, to_file);
  1167. else {
  1168. free(cat->file);
  1169. cat->file = strdup(to_file);
  1170. }
  1171. }
  1172. for (v = cat->root; v; v = v->next) {
  1173. if (strcmp(v->file,from_file) == 0) {
  1174. if (from_len >= to_len)
  1175. strcpy(v->file, to_file);
  1176. else {
  1177. free(v->file);
  1178. v->file = strdup(to_file);
  1179. }
  1180. }
  1181. }
  1182. }
  1183. }
  1184. static struct ast_config_include *ast_include_find(struct ast_config *conf, const char *included_file)
  1185. {
  1186. struct ast_config_include *x;
  1187. for (x=conf->includes;x;x=x->next)
  1188. {
  1189. if (strcmp(x->included_file,included_file) == 0)
  1190. return x;
  1191. }
  1192. return 0;
  1193. }
  1194. static void ast_variable_append(struct ast_category *category, struct ast_variable *variable);
  1195. static void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
  1196. {
  1197. if (!variable)
  1198. return;
  1199. if (category->last)
  1200. category->last->next = variable;
  1201. else
  1202. category->root = variable;
  1203. category->last = variable;
  1204. while (category->last->next)
  1205. category->last = category->last->next;
  1206. }
  1207. static struct ast_category *category_get(const struct ast_config *config, const char *category_name, int ignored);
  1208. static struct ast_category *category_get(const struct ast_config *config, const char *category_name, int ignored)
  1209. {
  1210. struct ast_category *cat;
  1211. /* try exact match first, then case-insensitive match */
  1212. for (cat = config->root; cat; cat = cat->next) {
  1213. if (cat->name == category_name && (ignored || !cat->ignored))
  1214. return cat;
  1215. }
  1216. for (cat = config->root; cat; cat = cat->next) {
  1217. if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored))
  1218. return cat;
  1219. }
  1220. return NULL;
  1221. }
  1222. static struct ast_category *ast_category_get(const struct ast_config *config, const char *category_name)
  1223. {
  1224. return category_get(config, category_name, 0);
  1225. }
  1226. static struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category)
  1227. {
  1228. struct ast_category *cat = NULL;
  1229. if (category && config->last_browse && (config->last_browse->name == category))
  1230. cat = config->last_browse;
  1231. else
  1232. cat = ast_category_get(config, category);
  1233. return (cat) ? cat->root : NULL;
  1234. }
  1235. static const char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
  1236. {
  1237. struct ast_variable *v;
  1238. if (category) {
  1239. for (v = ast_variable_browse(config, category); v; v = v->next) {
  1240. if (!strcasecmp(variable, v->name))
  1241. return v->value;
  1242. }
  1243. } else {
  1244. struct ast_category *cat;
  1245. for (cat = config->root; cat; cat = cat->next)
  1246. for (v = cat->root; v; v = v->next)
  1247. if (!strcasecmp(variable, v->name))
  1248. return v->value;
  1249. }
  1250. return NULL;
  1251. }
  1252. static struct ast_variable *variable_clone(const struct ast_variable *old)
  1253. {
  1254. struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
  1255. if (new) {
  1256. new->lineno = old->lineno;
  1257. new->object = old->object;
  1258. new->blanklines = old->blanklines;
  1259. /* TODO: clone comments? */
  1260. }
  1261. return new;
  1262. }
  1263. static void ast_variables_destroy(struct ast_variable *v)
  1264. {
  1265. struct ast_variable *vn;
  1266. while (v) {
  1267. vn = v;
  1268. v = v->next;
  1269. free(vn);
  1270. }
  1271. }
  1272. static void ast_includes_destroy(struct ast_config_include *incls)
  1273. {
  1274. struct ast_config_include *incl,*inclnext;
  1275. for (incl=incls; incl; incl = inclnext) {
  1276. inclnext = incl->next;
  1277. if (incl->include_location_file)
  1278. free(incl->include_location_file);
  1279. if (incl->exec_file)
  1280. free(incl->exec_file);
  1281. if (incl->included_file)
  1282. free(incl->included_file);
  1283. free(incl);
  1284. }
  1285. }
  1286. static void ast_config_destroy(struct ast_config *cfg)
  1287. {
  1288. struct ast_category *cat, *catn;
  1289. if (!cfg)
  1290. return;
  1291. ast_includes_destroy(cfg->includes);
  1292. cat = cfg->root;
  1293. while (cat) {
  1294. ast_variables_destroy(cat->root);
  1295. catn = cat;
  1296. cat = cat->next;
  1297. free(catn);
  1298. }
  1299. free(cfg);
  1300. }
  1301. enum ast_option_flags {
  1302. /*! Allow \#exec in config files */
  1303. AST_OPT_FLAG_EXEC_INCLUDES = (1 << 0),
  1304. /*! Do not fork() */
  1305. AST_OPT_FLAG_NO_FORK = (1 << 1),
  1306. /*! Keep quiet */
  1307. AST_OPT_FLAG_QUIET = (1 << 2),
  1308. /*! Console mode */
  1309. AST_OPT_FLAG_CONSOLE = (1 << 3),
  1310. /*! Run in realtime Linux priority */
  1311. AST_OPT_FLAG_HIGH_PRIORITY = (1 << 4),
  1312. /*! Initialize keys for RSA authentication */
  1313. AST_OPT_FLAG_INIT_KEYS = (1 << 5),
  1314. /*! Remote console */
  1315. AST_OPT_FLAG_REMOTE = (1 << 6),
  1316. /*! Execute an asterisk CLI command upon startup */
  1317. AST_OPT_FLAG_EXEC = (1 << 7),
  1318. /*! Don't use termcap colors */
  1319. AST_OPT_FLAG_NO_COLOR = (1 << 8),
  1320. /*! Are we fully started yet? */
  1321. AST_OPT_FLAG_FULLY_BOOTED = (1 << 9),
  1322. /*! Trascode via signed linear */
  1323. AST_OPT_FLAG_TRANSCODE_VIA_SLIN = (1 << 10),
  1324. /*! Dump core on a seg fault */
  1325. AST_OPT_FLAG_DUMP_CORE = (1 << 12),
  1326. /*! Cache sound files */
  1327. AST_OPT_FLAG_CACHE_RECORD_FILES = (1 << 13),
  1328. /*! Display timestamp in CLI verbose output */
  1329. AST_OPT_FLAG_TIMESTAMP = (1 << 14),
  1330. /*! Override config */
  1331. AST_OPT_FLAG_OVERRIDE_CONFIG = (1 << 15),
  1332. /*! Reconnect */
  1333. AST_OPT_FLAG_RECONNECT = (1 << 16),
  1334. /*! Transmit Silence during Record() and DTMF Generation */
  1335. AST_OPT_FLAG_TRANSMIT_SILENCE = (1 << 17),
  1336. /*! Suppress some warnings */
  1337. AST_OPT_FLAG_DONT_WARN = (1 << 18),
  1338. /*! End CDRs before the 'h' extension */
  1339. AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN = (1 << 19),
  1340. /*! Always fork, even if verbose or debug settings are non-zero */
  1341. AST_OPT_FLAG_ALWAYS_FORK = (1 << 21),
  1342. /*! Disable log/verbose output to remote consoles */
  1343. AST_OPT_FLAG_MUTE = (1 << 22),
  1344. /*! There is a per-file debug setting */
  1345. AST_OPT_FLAG_DEBUG_FILE = (1 << 23),
  1346. /*! There is a per-file verbose setting */
  1347. AST_OPT_FLAG_VERBOSE_FILE = (1 << 24),
  1348. /*! Terminal colors should be adjusted for a light-colored background */
  1349. AST_OPT_FLAG_LIGHT_BACKGROUND = (1 << 25),
  1350. /*! Count Initiated seconds in CDR's */
  1351. AST_OPT_FLAG_INITIATED_SECONDS = (1 << 26),
  1352. /*! Force black background */
  1353. AST_OPT_FLAG_FORCE_BLACK_BACKGROUND = (1 << 27),
  1354. };
  1355. /* options.h declares ast_options extern; I need it static? */
  1356. #define AST_CACHE_DIR_LEN 512
  1357. #define AST_FILENAME_MAX 80
  1358. /*! These are the options that set by default when Asterisk starts */
  1359. #define AST_DEFAULT_OPTIONS AST_OPT_FLAG_TRANSCODE_VIA_SLIN
  1360. struct ast_flags ast_options = { AST_DEFAULT_OPTIONS };
  1361. #define ast_opt_exec_includes ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES)
  1362. #define ast_opt_no_fork ast_test_flag(&ast_options, AST_OPT_FLAG_NO_FORK)
  1363. #define ast_opt_quiet ast_test_flag(&ast_options, AST_OPT_FLAG_QUIET)
  1364. #define ast_opt_console ast_test_flag(&ast_options, AST_OPT_FLAG_CONSOLE)
  1365. #define ast_opt_high_priority ast_test_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY)
  1366. #define ast_opt_init_keys ast_test_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS)
  1367. #define ast_opt_remote ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)
  1368. #define ast_opt_exec ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC)
  1369. #define ast_opt_no_color ast_test_flag(&ast_options, AST_OPT_FLAG_NO_COLOR)
  1370. #define ast_fully_booted ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)
  1371. #define ast_opt_transcode_via_slin ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN)
  1372. #define ast_opt_priority_jumping ast_test_flag(&ast_options, AST_OPT_FLAG_PRIORITY_JUMPING)
  1373. #define ast_opt_dump_core ast_test_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE)
  1374. #define ast_opt_cache_record_files ast_test_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES)
  1375. #define ast_opt_timestamp ast_test_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP)
  1376. #define ast_opt_override_config ast_test_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG)
  1377. #define ast_opt_reconnect ast_test_flag(&ast_options, AST_OPT_FLAG_RECONNECT)
  1378. #define ast_opt_transmit_silence ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE)
  1379. #define ast_opt_dont_warn ast_test_flag(&ast_options, AST_OPT_FLAG_DONT_WARN)
  1380. #define ast_opt_end_cdr_before_h_exten ast_test_flag(&ast_options, AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN)
  1381. #define ast_opt_always_fork ast_test_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK)
  1382. #define ast_opt_mute ast_test_flag(&ast_options, AST_OPT_FLAG_MUTE)
  1383. extern int option_verbose;
  1384. extern int option_debug; /*!< Debugging */
  1385. extern int ast_option_maxcalls; /*!< Maximum number of simultaneous channels */
  1386. extern double ast_option_maxload;
  1387. extern char ast_defaultlanguage[];
  1388. extern pid_t ast_mainpid;
  1389. extern char record_cache_dir[AST_CACHE_DIR_LEN];
  1390. extern char debug_filename[AST_FILENAME_MAX];
  1391. extern int ast_language_is_prefix;
  1392. /* linkedlists.h */
  1393. /*!
  1394. \brief Write locks a list.
  1395. \param head This is a pointer to the list head structure
  1396. This macro attempts to place an exclusive write lock in the
  1397. list head structure pointed to by head.
  1398. Returns non-zero on success, 0 on failure
  1399. */
  1400. #define AST_RWLIST_WRLOCK(head) \
  1401. ast_rwlock_wrlock(&(head)->lock)
  1402. /*!
  1403. \brief Read locks a list.
  1404. \param head This is a pointer to the list head structure
  1405. This macro attempts to place a read lock in the
  1406. list head structure pointed to by head.
  1407. Returns non-zero on success, 0 on failure
  1408. */
  1409. #define AST_RWLIST_RDLOCK(head) \
  1410. ast_rwlock_rdlock(&(head)->lock)
  1411. /*!
  1412. \brief Attempts to unlock a read/write based list.
  1413. \param head This is a pointer to the list head structure
  1414. This macro attempts to remove a read or write lock from the
  1415. list head structure pointed to by head. If the list
  1416. was not locked by this thread, this macro has no effect.
  1417. */
  1418. #define AST_RWLIST_UNLOCK(head) \
  1419. ast_rwlock_unlock(&(head)->lock)
  1420. /*!
  1421. \brief Defines a structure to be used to hold a list of specified type.
  1422. \param name This will be the name of the defined structure.
  1423. \param type This is the type of each list entry.
  1424. This macro creates a structure definition that can be used
  1425. to hold a list of the entries of type \a type. It does not actually
  1426. declare (allocate) a structure; to do that, either follow this
  1427. macro with the desired name of the instance you wish to declare,
  1428. or use the specified \a name to declare instances elsewhere.
  1429. Example usage:
  1430. \code
  1431. static AST_LIST_HEAD(entry_list, entry) entries;
  1432. \endcode
  1433. This would define \c struct \c entry_list, and declare an instance of it named
  1434. \a entries, all intended to hold a list of type \c struct \c entry.
  1435. */
  1436. #define AST_LIST_HEAD(name, type) \
  1437. struct name { \
  1438. struct type *first; \
  1439. struct type *last; \
  1440. ast_mutex_t lock; \
  1441. }
  1442. /*!
  1443. \brief Defines a structure to be used to hold a read/write list of specified type.
  1444. \param name This will be the name of the defined structure.
  1445. \param type This is the type of each list entry.
  1446. This macro creates a structure definition that can be used
  1447. to hold a list of the entries of type \a type. It does not actually
  1448. declare (allocate) a structure; to do that, either follow this
  1449. macro with the desired name of the instance you wish to declare,
  1450. or use the specified \a name to declare instances elsewhere.
  1451. Example usage:
  1452. \code
  1453. static AST_RWLIST_HEAD(entry_list, entry) entries;
  1454. \endcode
  1455. This would define \c struct \c entry_list, and declare an instance of it named
  1456. \a entries, all intended to hold a list of type \c struct \c entry.
  1457. */
  1458. #define AST_RWLIST_HEAD(name, type) \
  1459. struct name { \
  1460. struct type *first; \
  1461. struct type *last; \
  1462. ast_rwlock_t lock; \
  1463. }
  1464. /*!
  1465. \brief Defines a structure to be used to hold a list of specified type (with no lock).
  1466. \param name This will be the name of the defined structure.
  1467. \param type This is the type of each list entry.
  1468. This macro creates a structure definition that can be used
  1469. to hold a list of the entries of type \a type. It does not actually
  1470. declare (allocate) a structure; to do that, either follow this
  1471. macro with the desired name of the instance you wish to declare,
  1472. or use the specified \a name to declare instances elsewhere.
  1473. Example usage:
  1474. \code
  1475. static AST_LIST_HEAD_NOLOCK(entry_list, entry) entries;
  1476. \endcode
  1477. This would define \c struct \c entry_list, and declare an instance of it named
  1478. \a entries, all intended to hold a list of type \c struct \c entry.
  1479. */
  1480. #define AST_LIST_HEAD_NOLOCK(name, type) \
  1481. struct name { \
  1482. struct type *first; \
  1483. struct type *last; \
  1484. }
  1485. /*!
  1486. \brief Defines initial values for a declaration of AST_LIST_HEAD
  1487. */
  1488. #define AST_LIST_HEAD_INIT_VALUE { \
  1489. .first = NULL, \
  1490. .last = NULL, \
  1491. .lock = AST_MUTEX_INIT_VALUE, \
  1492. }
  1493. /*!
  1494. \brief Defines initial values for a declaration of AST_RWLIST_HEAD
  1495. */
  1496. #define AST_RWLIST_HEAD_INIT_VALUE { \
  1497. .first = NULL, \
  1498. .last = NULL, \
  1499. .lock = AST_RWLOCK_INIT_VALUE, \
  1500. }
  1501. /*!
  1502. \brief Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK
  1503. */
  1504. #define AST_LIST_HEAD_NOLOCK_INIT_VALUE { \
  1505. .first = NULL, \
  1506. .last = NULL, \
  1507. }
  1508. /*!
  1509. \brief Defines a structure to be used to hold a list of specified type, statically initialized.
  1510. \param name This will be the name of the defined structure.
  1511. \param type This is the type of each list entry.
  1512. This macro creates a structure definition that can be used
  1513. to hold a list of the entries of type \a type, and allocates an instance
  1514. of it, initialized to be empty.
  1515. Example usage:
  1516. \code
  1517. static AST_LIST_HEAD_STATIC(entry_list, entry);
  1518. \endcode
  1519. This would define \c struct \c entry_list, intended to hold a list of
  1520. type \c struct \c entry.
  1521. */
  1522. #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
  1523. #define AST_LIST_HEAD_STATIC(name, type) \
  1524. struct name { \
  1525. struct type *first; \
  1526. struct type *last; \
  1527. ast_mutex_t lock; \
  1528. } name; \
  1529. static void __attribute__((constructor)) init_##name(void) \
  1530. { \
  1531. AST_LIST_HEAD_INIT(&name); \
  1532. } \
  1533. static void __attribute__((destructor)) fini_##name(void) \
  1534. { \
  1535. AST_LIST_HEAD_DESTROY(&name); \
  1536. } \
  1537. struct __dummy_##name
  1538. #else
  1539. #define AST_LIST_HEAD_STATIC(name, type) \
  1540. struct name { \
  1541. struct type *first; \
  1542. struct type *last; \
  1543. ast_mutex_t lock; \
  1544. } name = AST_LIST_HEAD_INIT_VALUE
  1545. #endif
  1546. /*!
  1547. \brief Defines a structure to be used to hold a read/write list of specified type, statically initialized.
  1548. \param name This will be the name of the defined structure.
  1549. \param type This is the type of each list entry.
  1550. This macro creates a structure definition that can be used
  1551. to hold a list of the entries of type \a type, and allocates an instance
  1552. of it, initialized to be empty.
  1553. Example usage:
  1554. \code
  1555. static AST_RWLIST_HEAD_STATIC(entry_list, entry);
  1556. \endcode
  1557. This would define \c struct \c entry_list, intended to hold a list of
  1558. type \c struct \c entry.
  1559. */
  1560. #ifndef AST_RWLOCK_INIT_VALUE
  1561. #define AST_RWLIST_HEAD_STATIC(name, type) \
  1562. struct name { \
  1563. struct type *first; \
  1564. struct type *last; \
  1565. ast_rwlock_t lock; \
  1566. } name; \
  1567. static void __attribute__((constructor)) init_##name(void) \
  1568. { \
  1569. AST_RWLIST_HEAD_INIT(&name); \
  1570. } \
  1571. static void __attribute__((destructor)) fini_##name(void) \
  1572. { \
  1573. AST_RWLIST_HEAD_DESTROY(&name); \
  1574. } \
  1575. struct __dummy_##name
  1576. #else
  1577. #define AST_RWLIST_HEAD_STATIC(name, type) \
  1578. struct name { \
  1579. struct type *first; \
  1580. struct type *last; \
  1581. ast_rwlock_t lock; \
  1582. } name = AST_RWLIST_HEAD_INIT_VALUE
  1583. #endif
  1584. /*!
  1585. \brief Defines a structure to be used to hold a list of specified type, statically initialized.
  1586. This is the same as AST_LIST_HEAD_STATIC, except without the lock included.
  1587. */
  1588. #define AST_LIST_HEAD_NOLOCK_STATIC(name, type) \
  1589. struct name { \
  1590. struct type *first; \
  1591. struct type *last; \
  1592. } name = AST_LIST_HEAD_NOLOCK_INIT_VALUE
  1593. /*!
  1594. \brief Initializes a list head structure with a specified first entry.
  1595. \param head This is a pointer to the list head structure
  1596. \param entry pointer to the list entry that will become the head of the list
  1597. This macro initializes a list head structure by setting the head
  1598. entry to the supplied value and recreating the embedded lock.
  1599. */
  1600. #define AST_LIST_HEAD_SET(head, entry) do { \
  1601. (head)->first = (entry); \
  1602. (head)->last = (entry); \
  1603. ast_mutex_init(&(head)->lock); \
  1604. } while (0)
  1605. /*!
  1606. \brief Initializes an rwlist head structure with a specified first entry.
  1607. \param head This is a pointer to the list head structure
  1608. \param entry pointer to the list entry that will become the head of the list
  1609. This macro initializes a list head structure by setting the head
  1610. entry to the supplied value and recreating the embedded lock.
  1611. */
  1612. #define AST_RWLIST_HEAD_SET(head, entry) do { \
  1613. (head)->first = (entry); \
  1614. (head)->last = (entry); \
  1615. ast_rwlock_init(&(head)->lock); \
  1616. } while (0)
  1617. /*!
  1618. \brief Initializes a list head structure with a specified first entry.
  1619. \param head This is a pointer to the list head structure
  1620. \param entry pointer to the list entry that will become the head of the list
  1621. This macro initializes a list head structure by setting the head
  1622. entry to the supplied value.
  1623. */
  1624. #define AST_LIST_HEAD_SET_NOLOCK(head, entry) do { \
  1625. (head)->first = (entry); \
  1626. (head)->last = (entry); \
  1627. } while (0)
  1628. /*!
  1629. \brief Declare a forward link structure inside a list entry.
  1630. \param type This is the type of each list entry.
  1631. This macro declares a structure to be used to link list entries together.
  1632. It must be used inside the definition of the structure named in
  1633. \a type, as follows:
  1634. \code
  1635. struct list_entry {
  1636. ...
  1637. AST_LIST_ENTRY(list_entry) list;
  1638. }
  1639. \endcode
  1640. The field name \a list here is arbitrary, and can be anything you wish.
  1641. */
  1642. #define AST_LIST_ENTRY(type) \
  1643. struct { \
  1644. struct type *next; \
  1645. }
  1646. #define AST_RWLIST_ENTRY AST_LIST_ENTRY
  1647. /*!
  1648. \brief Returns the first entry contained in a list.
  1649. \param head This is a pointer to the list head structure
  1650. */
  1651. #define AST_LIST_FIRST(head) ((head)->first)
  1652. #define AST_RWLIST_FIRST AST_LIST_FIRST
  1653. /*!
  1654. \brief Returns the last entry contained in a list.
  1655. \param head This is a pointer to the list head structure
  1656. */
  1657. #define AST_LIST_LAST(head) ((head)->last)
  1658. #define AST_RWLIST_LAST AST_LIST_LAST
  1659. /*!
  1660. \brief Returns the next entry in the list after the given entry.
  1661. \param elm This is a pointer to the current entry.
  1662. \param field This is the name of the field (declared using AST_LIST_ENTRY())
  1663. used to link entries of this list together.
  1664. */
  1665. #define AST_LIST_NEXT(elm, field) ((elm)->field.next)
  1666. #define AST_RWLIST_NEXT AST_LIST_NEXT
  1667. /*!
  1668. \brief Checks whether the specified list contains any entries.
  1669. \param head This is a pointer to the list head structure
  1670. Returns non-zero if the list has entries, zero if not.
  1671. */
  1672. #define AST_LIST_EMPTY(head) (AST_LIST_FIRST(head) == NULL)
  1673. #define AST_RWLIST_EMPTY AST_LIST_EMPTY
  1674. /*!
  1675. \brief Loops over (traverses) the entries in a list.
  1676. \param head This is a pointer to the list head structure
  1677. \param var This is the name of the variable that will hold a pointer to the
  1678. current list entry on each iteration. It must be declared before calling
  1679. this macro.
  1680. \param field This is the name of the field (declared using AST_LIST_ENTRY())
  1681. used to link entries of this list together.
  1682. This macro is use to loop over (traverse) the entries in a list. It uses a
  1683. \a for loop, and supplies the enclosed code with a pointer to each list
  1684. entry as it loops. It is typically used as follows:
  1685. \code
  1686. static AST_LIST_HEAD(entry_list, list_entry) entries;
  1687. ...
  1688. struct list_entry {
  1689. ...
  1690. AST_LIST_ENTRY(list_entry) list;
  1691. }
  1692. ...
  1693. struct list_entry *current;
  1694. ...
  1695. AST_LIST_TRAVERSE(&entries, current, list) {
  1696. (do something with current here)
  1697. }
  1698. \endcode
  1699. \warning If you modify the forward-link pointer contained in the \a current entry while
  1700. inside the loop, the behavior will be unpredictable. At a minimum, the following
  1701. macros will modify the forward-link pointer, and should not be used inside
  1702. AST_LIST_TRAVERSE() against the entry pointed to by the \a current pointer without
  1703. careful consideration of their consequences:
  1704. \li AST_LIST_NEXT() (when used as an lvalue)
  1705. \li AST_LIST_INSERT_AFTER()
  1706. \li AST_LIST_INSERT_HEAD()
  1707. \li AST_LIST_INSERT_TAIL()
  1708. */
  1709. #define AST_LIST_TRAVERSE(head,var,field) \
  1710. for((var) = (head)->first; (var); (var) = (var)->field.next)
  1711. #define AST_RWLIST_TRAVERSE AST_LIST_TRAVERSE
  1712. /*!
  1713. \brief Loops safely over (traverses) the entries in a list.
  1714. \param head This is a pointer to the list head structure
  1715. \param var This is the name of the variable that will hold a pointer to the
  1716. current list entry on each iteration. It must be declared before calling
  1717. this macro.
  1718. \param field This is the name of the field (declared using AST_LIST_ENTRY())
  1719. used to link entries of this list together.
  1720. This macro is used to safely loop over (traverse) the entries in a list. It
  1721. uses a \a for loop, and supplies the enclosed code with a pointer to each list
  1722. entry as it loops. It is typically used as follows:
  1723. \code
  1724. static AST_LIST_HEAD(entry_list, list_entry) entries;
  1725. ...
  1726. struct list_entry {
  1727. ...
  1728. AST_LIST_ENTRY(list_entry) list;
  1729. }
  1730. ...
  1731. struct list_entry *current;
  1732. ...
  1733. AST_LIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
  1734. (do something with current here)
  1735. }
  1736. AST_LIST_TRAVERSE_SAFE_END;
  1737. \endcode
  1738. It differs from AST_LIST_TRAVERSE() in that the code inside the loop can modify
  1739. (or even free, after calling AST_LIST_REMOVE_CURRENT()) the entry pointed to by
  1740. the \a current pointer without affecting the loop traversal.
  1741. */
  1742. #define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field) { \
  1743. typeof((head)->first) __list_next; \
  1744. typeof((head)->first) __list_prev = NULL; \
  1745. typeof((head)->first) __new_prev = NULL; \
  1746. for ((var) = (head)->first, __new_prev = (var), \
  1747. __list_next = (var) ? (var)->field.next : NULL; \
  1748. (var); \
  1749. __list_prev = __new_prev, (var) = __list_next, \
  1750. __new_prev = (var), \
  1751. __list_next = (var) ? (var)->field.next : NULL \
  1752. )
  1753. #define AST_RWLIST_TRAVERSE_SAFE_BEGIN AST_LIST_TRAVERSE_SAFE_BEGIN
  1754. /*!
  1755. \brief Removes the \a current entry from a list during a traversal.
  1756. \param head This is a pointer to the list head structure
  1757. \param field This is the name of the field (declared using AST_LIST_ENTRY())
  1758. used to link entries of this list together.
  1759. \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
  1760. block; it is used to unlink the current entry from the list without affecting
  1761. the list traversal (and without having to re-traverse the list to modify the
  1762. previous entry, if any).
  1763. */
  1764. #define AST_LIST_REMOVE_CURRENT(head, field) \
  1765. __new_prev->field.next = NULL; \
  1766. __new_prev = __list_prev; \
  1767. if (__list_prev) \
  1768. __list_prev->field.next = __list_next; \
  1769. else \
  1770. (head)->first = __list_next; \
  1771. if (!__list_next) \
  1772. (head)->last = __list_prev;
  1773. #define AST_RWLIST_REMOVE_CURRENT AST_LIST_REMOVE_CURRENT
  1774. /*!
  1775. \brief Inserts a list entry before the current entry during a traversal.
  1776. \param head This is a pointer to the list head structure
  1777. \param elm This is a pointer to the entry to be inserted.
  1778. \param field This is the name of the field (declared using AST_LIST_ENTRY())
  1779. used to link entries of this list together.
  1780. \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
  1781. block.
  1782. */
  1783. #define AST_LIST_INSERT_BEFORE_CURRENT(head, elm, field) do { \
  1784. if (__list_prev) { \
  1785. (elm)->field.next = __list_prev->field.next; \
  1786. __list_prev->field.next = elm; \
  1787. } else { \
  1788. (elm)->field.next = (head)->first; \
  1789. (head)->first = (elm); \
  1790. } \
  1791. __new_prev = (elm); \
  1792. } while (0)
  1793. #define AST_RWLIST_INSERT_BEFORE_CURRENT AST_LIST_INSERT_BEFORE_CURRENT
  1794. /*!
  1795. \brief Closes a safe loop traversal block.
  1796. */
  1797. #define AST_LIST_TRAVERSE_SAFE_END }
  1798. #define AST_RWLIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END
  1799. /*!
  1800. \brief Initializes a list head structure.
  1801. \param head This is a pointer to the list head structure
  1802. This macro initializes a list head structure by setting the head
  1803. entry to \a NULL (empty list) and recreating the embedded lock.
  1804. */
  1805. #define AST_LIST_HEAD_INIT(head) { \
  1806. (head)->first = NULL; \
  1807. (head)->last = NULL; \
  1808. ast_mutex_init(&(head)->lock); \
  1809. }
  1810. /*!
  1811. \brief Initializes an rwlist head structure.
  1812. \param head This is a pointer to the list head structure
  1813. This macro initializes a list head structure by setting the head
  1814. entry to \a NULL (empty list) and recreating the embedded lock.
  1815. */
  1816. #define AST_RWLIST_HEAD_INIT(head) { \
  1817. (head)->first = NULL; \
  1818. (head)->last = NULL; \
  1819. ast_rwlock_init(&(head)->lock); \
  1820. }
  1821. /*!
  1822. \brief Destroys an rwlist head structure.
  1823. \param head This is a pointer to the list head structure
  1824. This macro destroys a list head structure by setting the head
  1825. entry to \a NULL (empty list) and destroying the embedded lock.
  1826. It does not free the structure from memory.
  1827. */
  1828. #define AST_RWLIST_HEAD_DESTROY(head) { \
  1829. (head)->first = NULL; \
  1830. (head)->last = NULL; \
  1831. ast_rwlock_destroy(&(head)->lock); \
  1832. }
  1833. /*!
  1834. \brief Initializes a list head structure.
  1835. \param head This is a pointer to the list head structure
  1836. This macro initializes a list head structure by setting the head
  1837. entry to \a NULL (empty list). There is no embedded lock handling
  1838. with this macro.
  1839. */
  1840. #define AST_LIST_HEAD_INIT_NOLOCK(head) { \
  1841. (head)->first = NULL; \
  1842. (head)->last = NULL; \
  1843. }
  1844. /*!
  1845. \brief Inserts a list entry after a given entry.
  1846. \param head This is a pointer to the list head structure
  1847. \param listelm This is a pointer to the entry after which the new entry should
  1848. be inserted.
  1849. \param elm This is a pointer to the entry to be inserted.
  1850. \param field This is the name of the field (declared using AST_LIST_ENTRY())
  1851. used to link entries of this list together.
  1852. */
  1853. #define AST_LIST_INSERT_AFTER(head, listelm, elm, field) do { \
  1854. (elm)->field.next = (listelm)->field.next; \
  1855. (listelm)->field.next = (elm); \
  1856. if ((head)->last == (listelm)) \
  1857. (head)->last = (elm); \
  1858. } while (0)
  1859. #define AST_RWLIST_INSERT_AFTER AST_LIST_INSERT_AFTER
  1860. /*!
  1861. \brief Inserts a list entry at the head of a list.
  1862. \param head This is a pointer to the list head structure
  1863. \param elm This is a pointer to the entry to be inserted.
  1864. \param field This is the name of the field (declared using AST_LIST_ENTRY())
  1865. used to link entries of this list together.
  1866. */
  1867. #define AST_LIST_INSERT_HEAD(head, elm, field) do { \
  1868. (elm)->field.next = (head)->first; \
  1869. (head)->first = (elm); \
  1870. if (!(head)->last) \
  1871. (head)->last = (elm); \
  1872. } while (0)
  1873. #define AST_RWLIST_INSERT_HEAD AST_LIST_INSERT_HEAD
  1874. /*!
  1875. \brief Appends a list entry to the tail of a list.
  1876. \param head This is a pointer to the list head structure
  1877. \param elm This is a pointer to the entry to be appended.
  1878. \param field This is the name of the field (declared using AST_LIST_ENTRY())
  1879. used to link entries of this list together.
  1880. Note: The link field in the appended entry is \b not modified, so if it is
  1881. actually the head of a list itself, the entire list will be appended
  1882. temporarily (until the next AST_LIST_INSERT_TAIL is performed).
  1883. */
  1884. #define AST_LIST_INSERT_TAIL(head, elm, field) do { \
  1885. if (!(head)->first) { \
  1886. (head)->first = (elm); \
  1887. (head)->last = (elm); \
  1888. } else { \
  1889. (head)->last->field.next = (elm); \
  1890. (head)->last = (elm); \
  1891. } \
  1892. } while (0)
  1893. #define AST_RWLIST_INSERT_TAIL AST_LIST_INSERT_TAIL
  1894. /*!
  1895. \brief Appends a whole list to the tail of a list.
  1896. \param head This is a pointer to the list head structure
  1897. \param list This is a pointer to the list to be appended.
  1898. \param field This is the name of the field (declared using AST_LIST_ENTRY())
  1899. used to link entries of this list together.
  1900. */
  1901. #define AST_LIST_APPEND_LIST(head, list, field) do { \
  1902. if (!(head)->first) { \
  1903. (head)->first = (list)->first; \
  1904. (head)->last = (list)->last; \
  1905. } else { \
  1906. (head)->last->field.next = (list)->first; \
  1907. (head)->last = (list)->last; \
  1908. } \
  1909. } while (0)
  1910. #define AST_RWLIST_APPEND_LIST AST_LIST_APPEND_LIST
  1911. /*!
  1912. \brief Removes and returns the head entry from a list.
  1913. \param head This is a pointer to the list head structure
  1914. \param field This is the name of the field (declared using AST_LIST_ENTRY())
  1915. used to link entries of this list together.
  1916. Removes the head entry from the list, and returns a pointer to it.
  1917. This macro is safe to call on an empty list.
  1918. */
  1919. #define AST_LIST_REMOVE_HEAD(head, field) ({ \
  1920. typeof((head)->first) cur = (head)->first; \
  1921. if (cur) { \
  1922. (head)->first = cur->field.next; \
  1923. cur->field.next = NULL; \
  1924. if ((head)->last == cur) \
  1925. (head)->last = NULL; \
  1926. } \
  1927. cur; \
  1928. })
  1929. #define AST_RWLIST_REMOVE_HEAD AST_LIST_REMOVE_HEAD
  1930. /*!
  1931. \brief Removes a specific entry from a list.
  1932. \param head This is a pointer to the list head structure
  1933. \param elm This is a pointer to the entry to be removed.
  1934. \param field This is the name of the field (declared using AST_LIST_ENTRY())
  1935. used to link entries of this list together.
  1936. \warning The removed entry is \b not freed nor modified in any way.
  1937. */
  1938. #define AST_LIST_REMOVE(head, elm, field) do { \
  1939. if ((head)->first == (elm)) { \
  1940. (head)->first = (elm)->field.next; \
  1941. if ((head)->last == (elm)) \
  1942. (head)->last = NULL; \
  1943. } else { \
  1944. typeof(elm) curelm = (head)->first; \
  1945. while (curelm && (curelm->field.next != (elm))) \
  1946. curelm = curelm->field.next; \
  1947. if (curelm) { \
  1948. curelm->field.next = (elm)->field.next; \
  1949. if ((head)->last == (elm)) \
  1950. (head)->last = curelm; \
  1951. } \
  1952. } \
  1953. (elm)->field.next = NULL; \
  1954. } while (0)
  1955. #define AST_RWLIST_REMOVE AST_LIST_REMOVE
  1956. /* chanvars.h */
  1957. struct ast_var_t {
  1958. AST_LIST_ENTRY(ast_var_t) entries;
  1959. char *value;
  1960. char name[0];
  1961. };
  1962. AST_LIST_HEAD_NOLOCK(varshead, ast_var_t);
  1963. AST_RWLOCK_DEFINE_STATIC(globalslock);
  1964. static struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
  1965. /* IN CONFLICT: struct ast_var_t *ast_var_assign(const char *name, const char *value); */
  1966. static struct ast_var_t *ast_var_assign(const char *name, const char *value);
  1967. static void ast_var_delete(struct ast_var_t *var);
  1968. /*from channel.h */
  1969. #define AST_MAX_EXTENSION 80 /*!< Max length of an extension */
  1970. /* from pbx.h */
  1971. #define PRIORITY_HINT -1 /*!< Special Priority for a hint */
  1972. enum ast_extension_states {
  1973. AST_EXTENSION_REMOVED = -2, /*!< Extension removed */
  1974. AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */
  1975. AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */
  1976. AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */
  1977. AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */
  1978. AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */
  1979. AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */
  1980. AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */
  1981. };
  1982. struct ast_custom_function {
  1983. const char *name; /*!< Name */
  1984. const char *synopsis; /*!< Short description for "show functions" */
  1985. const char *desc; /*!< Help text that explains it all */
  1986. const char *syntax; /*!< Syntax description */
  1987. int (*read)(struct ast_channel *, const char *, char *, char *, size_t); /*!< Read function, if read is supported */
  1988. int (*write)(struct ast_channel *, const char *, char *, const char *); /*!< Write function, if write is supported */
  1989. AST_RWLIST_ENTRY(ast_custom_function) acflist;
  1990. };
  1991. typedef int (ast_switch_f)(struct ast_channel *chan, const char *context,
  1992. const char *exten, int priority, const char *callerid, const char *data);
  1993. struct ast_switch {
  1994. AST_LIST_ENTRY(ast_switch) list;
  1995. const char *name; /*!< Name of the switch */
  1996. const char *description; /*!< Description of the switch */
  1997. ast_switch_f *exists;
  1998. ast_switch_f *canmatch;
  1999. ast_switch_f *exec;
  2000. ast_switch_f *matchmore;
  2001. };
  2002. static char *config_filename = "extensions.conf";
  2003. static char *global_registrar = "conf2ael";
  2004. static char userscontext[AST_MAX_EXTENSION] = "default";
  2005. static int static_config = 0;
  2006. static int write_protect_config = 1;
  2007. static int autofallthrough_config = 0;
  2008. static int clearglobalvars_config = 0;
  2009. static void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count);
  2010. /* stolen from callerid.c */
  2011. /*! \brief Clean up phone string
  2012. * remove '(', ' ', ')', non-trailing '.', and '-' not in square brackets.
  2013. * Basically, remove anything that could be invalid in a pattern.
  2014. */
  2015. static void ast_shrink_phone_number(char *n)
  2016. {
  2017. int x, y=0;
  2018. int bracketed = 0;
  2019. for (x=0; n[x]; x++) {
  2020. switch(n[x]) {
  2021. case '[':
  2022. bracketed++;
  2023. n[y++] = n[x];
  2024. break;
  2025. case ']':
  2026. bracketed--;
  2027. n[y++] = n[x];
  2028. break;
  2029. case '-':
  2030. if (bracketed)
  2031. n[y++] = n[x];
  2032. break;
  2033. case '.':
  2034. if (!n[x+1])
  2035. n[y++] = n[x];
  2036. break;
  2037. default:
  2038. if (!strchr("()", n[x]))
  2039. n[y++] = n[x];
  2040. }
  2041. }
  2042. n[y] = '\0';
  2043. }
  2044. /* stolen from chanvars.c */
  2045. static const char *ast_var_name(const struct ast_var_t *var)
  2046. {
  2047. const char *name;
  2048. if (var == NULL || (name = var->name) == NULL)
  2049. return NULL;
  2050. /* Return the name without the initial underscores */
  2051. if (name[0] == '_') {
  2052. name++;
  2053. if (name[0] == '_')
  2054. name++;
  2055. }
  2056. return name;
  2057. }
  2058. /* experiment 1: see if it's easier just to use existing config code
  2059. * to read in the extensions.conf file. In this scenario,
  2060. I have to rip/copy code from other modules, because they
  2061. are staticly declared as-is. A solution would be to move
  2062. the ripped code to another location and make them available
  2063. to other modules and standalones */
  2064. /* Our own version of ast_log, since the expr parser uses it. -- stolen from utils/check_expr.c */
  2065. static void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
  2066. {
  2067. va_list vars;
  2068. va_start(vars,fmt);
  2069. printf("LOG: lev:%d file:%s line:%d func: %s ",
  2070. level, file, line, function);
  2071. vprintf(fmt, vars);
  2072. fflush(stdout);
  2073. va_end(vars);
  2074. }
  2075. void __attribute__((format(printf, 1, 2))) ast_verbose(const char *fmt, ...)
  2076. {
  2077. va_list vars;
  2078. va_start(vars,fmt);
  2079. printf("VERBOSE: ");
  2080. vprintf(fmt, vars);
  2081. fflush(stdout);
  2082. va_end(vars);
  2083. }
  2084. /* stolen from main/utils.c */
  2085. static char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
  2086. {
  2087. char *dataPut = start;
  2088. int inEscape = 0;
  2089. int inQuotes = 0;
  2090. for (; *start; start++) {
  2091. if (inEscape) {
  2092. *dataPut++ = *start; /* Always goes verbatim */
  2093. inEscape = 0;
  2094. } else {
  2095. if (*start == '\\') {
  2096. inEscape = 1; /* Do not copy \ into the data */
  2097. } else if (*start == '\'') {
  2098. inQuotes = 1 - inQuotes; /* Do not copy ' into the data */
  2099. } else {
  2100. /* Replace , with |, unless in quotes */
  2101. *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
  2102. }
  2103. }
  2104. }
  2105. if (start != dataPut)
  2106. *dataPut = 0;
  2107. return dataPut;
  2108. }
  2109. static int ast_true(const char *s)
  2110. {
  2111. if (ast_strlen_zero(s))
  2112. return 0;
  2113. /* Determine if this is a true value */
  2114. if (!strcasecmp(s, "yes") ||
  2115. !strcasecmp(s, "true") ||
  2116. !strcasecmp(s, "y") ||
  2117. !strcasecmp(s, "t") ||
  2118. !strcasecmp(s, "1") ||
  2119. !strcasecmp(s, "on"))
  2120. return -1;
  2121. return 0;
  2122. }
  2123. #define ONE_MILLION 1000000
  2124. /*
  2125. * put timeval in a valid range. usec is 0..999999
  2126. * negative values are not allowed and truncated.
  2127. */
  2128. static struct timeval tvfix(struct timeval a)
  2129. {
  2130. if (a.tv_usec >= ONE_MILLION) {
  2131. ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
  2132. (long)a.tv_sec, (long int) a.tv_usec);
  2133. a.tv_sec += a.tv_usec / ONE_MILLION;
  2134. a.tv_usec %= ONE_MILLION;
  2135. } else if (a.tv_usec < 0) {
  2136. ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
  2137. (long)a.tv_sec, (long int) a.tv_usec);
  2138. a.tv_usec = 0;
  2139. }
  2140. return a;
  2141. }
  2142. struct timeval ast_tvadd(struct timeval a, struct timeval b);
  2143. struct timeval ast_tvadd(struct timeval a, struct timeval b)
  2144. {
  2145. /* consistency checks to guarantee usec in 0..999999 */
  2146. a = tvfix(a);
  2147. b = tvfix(b);
  2148. a.tv_sec += b.tv_sec;
  2149. a.tv_usec += b.tv_usec;
  2150. if (a.tv_usec >= ONE_MILLION) {
  2151. a.tv_sec++;
  2152. a.tv_usec -= ONE_MILLION;
  2153. }
  2154. return a;
  2155. }
  2156. struct timeval ast_tvsub(struct timeval a, struct timeval b);
  2157. struct timeval ast_tvsub(struct timeval a, struct timeval b)
  2158. {
  2159. /* consistency checks to guarantee usec in 0..999999 */
  2160. a = tvfix(a);
  2161. b = tvfix(b);
  2162. a.tv_sec -= b.tv_sec;
  2163. a.tv_usec -= b.tv_usec;
  2164. if (a.tv_usec < 0) {
  2165. a.tv_sec-- ;
  2166. a.tv_usec += ONE_MILLION;
  2167. }
  2168. return a;
  2169. }
  2170. #undef ONE_MILLION
  2171. void ast_mark_lock_failed(void *lock_addr);
  2172. void ast_mark_lock_failed(void *lock_addr)
  2173. {
  2174. /* Pretend to do something. */
  2175. }
  2176. /* stolen from pbx.c */
  2177. #define VAR_BUF_SIZE 4096
  2178. #define VAR_NORMAL 1
  2179. #define VAR_SOFTTRAN 2
  2180. #define VAR_HARDTRAN 3
  2181. #define BACKGROUND_SKIP (1 << 0)
  2182. #define BACKGROUND_NOANSWER (1 << 1)
  2183. #define BACKGROUND_MATCHEXTEN (1 << 2)
  2184. #define BACKGROUND_PLAYBACK (1 << 3)
  2185. /*!
  2186. \brief ast_exten: An extension
  2187. The dialplan is saved as a linked list with each context
  2188. having it's own linked list of extensions - one item per
  2189. priority.
  2190. */
  2191. struct ast_exten {
  2192. char *exten; /*!< Extension name */
  2193. int matchcid; /*!< Match caller id ? */
  2194. const char *cidmatch; /*!< Caller id to match for this extension */
  2195. int priority; /*!< Priority */
  2196. const char *label; /*!< Label */
  2197. struct ast_context *parent; /*!< The context this extension belongs to */
  2198. const char *app; /*!< Application to execute */
  2199. struct ast_app *cached_app; /*!< Cached location of application */
  2200. void *data; /*!< Data to use (arguments) */
  2201. void (*datad)(void *); /*!< Data destructor */
  2202. struct ast_exten *peer; /*!< Next higher priority with our extension */
  2203. const char *registrar; /*!< Registrar */
  2204. struct ast_exten *next; /*!< Extension with a greater ID */
  2205. char stuff[0];
  2206. };
  2207. /* from pbx.h */
  2208. typedef int (*ast_state_cb_type)(char *context, char* id, enum ast_extension_states state, void *data);
  2209. struct ast_timing {
  2210. int hastime; /*!< If time construct exists */
  2211. unsigned int monthmask; /*!< Mask for month */
  2212. unsigned int daymask; /*!< Mask for date */
  2213. unsigned int dowmask; /*!< Mask for day of week (mon-sun) */
  2214. unsigned int minmask[48]; /*!< Mask for minute */
  2215. char *timezone; /*!< NULL, or zoneinfo style timezone */
  2216. };
  2217. /* end of pbx.h */
  2218. /*! \brief ast_include: include= support in extensions.conf */
  2219. struct ast_include {
  2220. const char *name;
  2221. const char *rname; /*!< Context to include */
  2222. const char *registrar; /*!< Registrar */
  2223. int hastime; /*!< If time construct exists */
  2224. struct ast_timing timing; /*!< time construct */
  2225. struct ast_include *next; /*!< Link them together */
  2226. char stuff[0];
  2227. };
  2228. /*! \brief ast_sw: Switch statement in extensions.conf */
  2229. struct ast_sw {
  2230. char *name;
  2231. const char *registrar; /*!< Registrar */
  2232. char *data; /*!< Data load */
  2233. int eval;
  2234. AST_LIST_ENTRY(ast_sw) list;
  2235. char *tmpdata;
  2236. char stuff[0];
  2237. };
  2238. /*! \brief ast_ignorepat: Ignore patterns in dial plan */
  2239. struct ast_ignorepat {
  2240. const char *registrar;
  2241. struct ast_ignorepat *next;
  2242. char pattern[0];
  2243. };
  2244. /*! \brief ast_context: An extension context */
  2245. struct ast_context {
  2246. ast_rwlock_t lock; /*!< A lock to prevent multiple threads from clobbering the context */
  2247. struct ast_exten *root; /*!< The root of the list of extensions */
  2248. struct ast_context *next; /*!< Link them together */
  2249. struct ast_include *includes; /*!< Include other contexts */
  2250. struct ast_ignorepat *ignorepats; /*!< Patterns for which to continue playing dialtone */
  2251. const char *registrar; /*!< Registrar */
  2252. AST_LIST_HEAD_NOLOCK(, ast_sw) alts; /*!< Alternative switches */
  2253. ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
  2254. char name[0]; /*!< Name of the context */
  2255. };
  2256. /*! \brief ast_app: A registered application */
  2257. struct ast_app {
  2258. int (*execute)(struct ast_channel *chan, void *data);
  2259. const char *synopsis; /*!< Synopsis text for 'show applications' */
  2260. const char *description; /*!< Description (help text) for 'show application &lt;name&gt;' */
  2261. AST_RWLIST_ENTRY(ast_app) list; /*!< Next app in list */
  2262. void *module; /*!< Module this app belongs to */
  2263. char name[0]; /*!< Name of the application */
  2264. };
  2265. /*! \brief ast_state_cb: An extension state notify register item */
  2266. struct ast_state_cb {
  2267. int id;
  2268. void *data;
  2269. ast_state_cb_type callback;
  2270. struct ast_state_cb *next;
  2271. };
  2272. /*! \brief Structure for dial plan hints
  2273. \note Hints are pointers from an extension in the dialplan to one or
  2274. more devices (tech/name)
  2275. - See \ref AstExtState
  2276. */
  2277. struct ast_hint {
  2278. struct ast_exten *exten; /*!< Extension */
  2279. int laststate; /*!< Last known state */
  2280. struct ast_state_cb *callbacks; /*!< Callback list for this extension */
  2281. AST_RWLIST_ENTRY(ast_hint) list;/*!< Pointer to next hint in list */
  2282. };
  2283. struct store_hint {
  2284. char *context;
  2285. char *exten;
  2286. struct ast_state_cb *callbacks;
  2287. int laststate;
  2288. AST_LIST_ENTRY(store_hint) list;
  2289. char data[1];
  2290. };
  2291. AST_LIST_HEAD(store_hints, store_hint);
  2292. #define STATUS_NO_CONTEXT 1
  2293. #define STATUS_NO_EXTENSION 2
  2294. #define STATUS_NO_PRIORITY 3
  2295. #define STATUS_NO_LABEL 4
  2296. #define STATUS_SUCCESS 5
  2297. static struct ast_var_t *ast_var_assign(const char *name, const char *value)
  2298. {
  2299. struct ast_var_t *var;
  2300. int name_len = strlen(name) + 1;
  2301. int value_len = strlen(value) + 1;
  2302. if (!(var = ast_calloc(sizeof(*var) + name_len + value_len, sizeof(char)))) {
  2303. return NULL;
  2304. }
  2305. ast_copy_string(var->name, name, name_len);
  2306. var->value = var->name + name_len;
  2307. ast_copy_string(var->value, value, value_len);
  2308. return var;
  2309. }
  2310. static void ast_var_delete(struct ast_var_t *var)
  2311. {
  2312. free(var);
  2313. }
  2314. /* chopped this one off at the knees! */
  2315. static int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
  2316. {
  2317. /* ast_log(LOG_ERROR, "Function %s not registered\n", function); we are not interested in the details here */
  2318. return -1;
  2319. }
  2320. static unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
  2321. {
  2322. int argc;
  2323. char *scan;
  2324. int paren = 0, quote = 0;
  2325. if (!buf || !array || !arraylen)
  2326. return 0;
  2327. memset(array, 0, arraylen * sizeof(*array));
  2328. scan = buf;
  2329. for (argc = 0; *scan && (argc < arraylen - 1); argc++) {
  2330. array[argc] = scan;
  2331. for (; *scan; scan++) {
  2332. if (*scan == '(')
  2333. paren++;
  2334. else if (*scan == ')') {
  2335. if (paren)
  2336. paren--;
  2337. } else if (*scan == '"' && delim != '"') {
  2338. quote = quote ? 0 : 1;
  2339. /* Remove quote character from argument */
  2340. memmove(scan, scan + 1, strlen(scan));
  2341. scan--;
  2342. } else if (*scan == '\\') {
  2343. /* Literal character, don't parse */
  2344. memmove(scan, scan + 1, strlen(scan));
  2345. } else if ((*scan == delim) && !paren && !quote) {
  2346. *scan++ = '\0';
  2347. break;
  2348. }
  2349. }
  2350. }
  2351. if (*scan)
  2352. array[argc++] = scan;
  2353. return argc;
  2354. }
  2355. static void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
  2356. {
  2357. struct ast_var_t *newvariable;
  2358. struct varshead *headp;
  2359. const char *nametail = name;
  2360. /* XXX may need locking on the channel ? */
  2361. if (name[strlen(name)-1] == ')') {
  2362. char *function = ast_strdupa(name);
  2363. ast_func_write(chan, function, value);
  2364. return;
  2365. }
  2366. headp = &globals;
  2367. /* For comparison purposes, we have to strip leading underscores */
  2368. if (*nametail == '_') {
  2369. nametail++;
  2370. if (*nametail == '_')
  2371. nametail++;
  2372. }
  2373. AST_LIST_TRAVERSE (headp, newvariable, entries) {
  2374. if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
  2375. /* there is already such a variable, delete it */
  2376. AST_LIST_REMOVE(headp, newvariable, entries);
  2377. ast_var_delete(newvariable);
  2378. break;
  2379. }
  2380. }
  2381. if (value && (newvariable = ast_var_assign(name, value))) {
  2382. if ((option_verbose > 1) && (headp == &globals))
  2383. ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
  2384. AST_LIST_INSERT_HEAD(headp, newvariable, entries);
  2385. }
  2386. }
  2387. static int pbx_builtin_setvar(struct ast_channel *chan, const void *data)
  2388. {
  2389. char *name, *value, *mydata;
  2390. int argc;
  2391. char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */
  2392. int global = 0;
  2393. int x;
  2394. if (ast_strlen_zero(data)) {
  2395. ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n");
  2396. return 0;
  2397. }
  2398. mydata = ast_strdupa(data);
  2399. argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
  2400. /* check for a trailing flags argument */
  2401. if ((argc > 1) && !strchr(argv[argc-1], '=')) {
  2402. argc--;
  2403. if (strchr(argv[argc], 'g'))
  2404. global = 1;
  2405. }
  2406. for (x = 0; x < argc; x++) {
  2407. name = argv[x];
  2408. if ((value = strchr(name, '='))) {
  2409. *value++ = '\0';
  2410. pbx_builtin_setvar_helper((global) ? NULL : chan, name, value);
  2411. } else
  2412. ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name);
  2413. }
  2414. return(0);
  2415. }
  2416. int localized_pbx_builtin_setvar(struct ast_channel *chan, const void *data);
  2417. int localized_pbx_builtin_setvar(struct ast_channel *chan, const void *data)
  2418. {
  2419. return pbx_builtin_setvar(chan, data);
  2420. }
  2421. /*! \brief Helper for get_range.
  2422. * return the index of the matching entry, starting from 1.
  2423. * If names is not supplied, try numeric values.
  2424. */
  2425. static int lookup_name(const char *s, char *const names[], int max)
  2426. {
  2427. int i;
  2428. if (names && *s > '9') {
  2429. for (i = 0; names[i]; i++) {
  2430. if (!strcasecmp(s, names[i])) {
  2431. return i;
  2432. }
  2433. }
  2434. }
  2435. /* Allow months and weekdays to be specified as numbers, as well */
  2436. if (sscanf(s, "%2d", &i) == 1 && i >= 1 && i <= max) {
  2437. /* What the array offset would have been: "1" would be at offset 0 */
  2438. return i - 1;
  2439. }
  2440. return -1; /* error return */
  2441. }
  2442. /*! \brief helper function to return a range up to max (7, 12, 31 respectively).
  2443. * names, if supplied, is an array of names that should be mapped to numbers.
  2444. */
  2445. static unsigned get_range(char *src, int max, char *const names[], const char *msg)
  2446. {
  2447. int start, end; /* start and ending position */
  2448. unsigned int mask = 0;
  2449. char *part;
  2450. /* Check for whole range */
  2451. if (ast_strlen_zero(src) || !strcmp(src, "*")) {
  2452. return (1 << max) - 1;
  2453. }
  2454. while ((part = strsep(&src, "&"))) {
  2455. /* Get start and ending position */
  2456. char *endpart = strchr(part, '-');
  2457. if (endpart) {
  2458. *endpart++ = '\0';
  2459. }
  2460. /* Find the start */
  2461. if ((start = lookup_name(part, names, max)) < 0) {
  2462. ast_log(LOG_WARNING, "Invalid %s '%s', skipping element\n", msg, part);
  2463. continue;
  2464. }
  2465. if (endpart) { /* find end of range */
  2466. if ((end = lookup_name(endpart, names, max)) < 0) {
  2467. ast_log(LOG_WARNING, "Invalid end %s '%s', skipping element\n", msg, endpart);
  2468. continue;
  2469. }
  2470. } else {
  2471. end = start;
  2472. }
  2473. /* Fill the mask. Remember that ranges are cyclic */
  2474. mask |= (1 << end); /* initialize with last element */
  2475. while (start != end) {
  2476. if (start >= max) {
  2477. start = 0;
  2478. }
  2479. mask |= (1 << start);
  2480. start++;
  2481. }
  2482. }
  2483. return mask;
  2484. }
  2485. /*! \brief store a bitmask of valid times, one bit each 2 minute */
  2486. static void get_timerange(struct ast_timing *i, char *times)
  2487. {
  2488. char *endpart, *part;
  2489. int x;
  2490. int st_h, st_m;
  2491. int endh, endm;
  2492. int minute_start, minute_end;
  2493. /* start disabling all times, fill the fields with 0's, as they may contain garbage */
  2494. memset(i->minmask, 0, sizeof(i->minmask));
  2495. /* 1-minute per bit */
  2496. /* Star is all times */
  2497. if (ast_strlen_zero(times) || !strcmp(times, "*")) {
  2498. /* 48, because each hour takes 2 integers; 30 bits each */
  2499. for (x = 0; x < 48; x++) {
  2500. i->minmask[x] = 0x3fffffff; /* 30 bits */
  2501. }
  2502. return;
  2503. }
  2504. /* Otherwise expect a range */
  2505. while ((part = strsep(&times, "&"))) {
  2506. if (!(endpart = strchr(part, '-'))) {
  2507. if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
  2508. ast_log(LOG_WARNING, "%s isn't a valid time.\n", part);
  2509. continue;
  2510. }
  2511. i->minmask[st_h * 2 + (st_m >= 30 ? 1 : 0)] |= (1 << (st_m % 30));
  2512. continue;
  2513. }
  2514. *endpart++ = '\0';
  2515. /* why skip non digits? Mostly to skip spaces */
  2516. while (*endpart && !isdigit(*endpart)) {
  2517. endpart++;
  2518. }
  2519. if (!*endpart) {
  2520. ast_log(LOG_WARNING, "Invalid time range starting with '%s-'.\n", part);
  2521. continue;
  2522. }
  2523. if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
  2524. ast_log(LOG_WARNING, "'%s' isn't a valid start time.\n", part);
  2525. continue;
  2526. }
  2527. if (sscanf(endpart, "%2d:%2d", &endh, &endm) != 2 || endh < 0 || endh > 23 || endm < 0 || endm > 59) {
  2528. ast_log(LOG_WARNING, "'%s' isn't a valid end time.\n", endpart);
  2529. continue;
  2530. }
  2531. minute_start = st_h * 60 + st_m;
  2532. minute_end = endh * 60 + endm;
  2533. /* Go through the time and enable each appropriate bit */
  2534. for (x = minute_start; x != minute_end; x = (x + 1) % (24 * 60)) {
  2535. i->minmask[x / 30] |= (1 << (x % 30));
  2536. }
  2537. /* Do the last one */
  2538. i->minmask[x / 30] |= (1 << (x % 30));
  2539. }
  2540. /* All done */
  2541. return;
  2542. }
  2543. static void null_datad(void *foo)
  2544. {
  2545. }
  2546. /*! \brief Find realtime engine for realtime family */
  2547. static struct ast_config_engine *find_engine(const char *family, char *database, int dbsiz, char *table, int tabsiz)
  2548. {
  2549. struct ast_config_engine *eng, *ret = NULL;
  2550. struct ast_config_map *map;
  2551. for (map = config_maps; map; map = map->next) {
  2552. if (!strcasecmp(family, map->name)) {
  2553. if (database)
  2554. ast_copy_string(database, map->database, dbsiz);
  2555. if (table)
  2556. ast_copy_string(table, map->table ? map->table : family, tabsiz);
  2557. break;
  2558. }
  2559. }
  2560. /* Check if the required driver (engine) exist */
  2561. if (map) {
  2562. for (eng = config_engine_list; !ret && eng; eng = eng->next) {
  2563. if (!strcasecmp(eng->name, map->driver))
  2564. ret = eng;
  2565. }
  2566. }
  2567. /* if we found a mapping, but the engine is not available, then issue a warning */
  2568. if (map && !ret)
  2569. ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver);
  2570. return ret;
  2571. }
  2572. struct ast_category *ast_config_get_current_category(const struct ast_config *cfg);
  2573. struct ast_category *ast_config_get_current_category(const struct ast_config *cfg)
  2574. {
  2575. return cfg->current;
  2576. }
  2577. static struct ast_category *ast_category_new(const char *name, const char *in_file, int lineno);
  2578. static struct ast_category *ast_category_new(const char *name, const char *in_file, int lineno)
  2579. {
  2580. struct ast_category *category;
  2581. if ((category = ast_calloc(1, sizeof(*category))))
  2582. ast_copy_string(category->name, name, sizeof(category->name));
  2583. category->file = strdup(in_file);
  2584. category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */
  2585. return category;
  2586. }
  2587. struct ast_category *localized_category_get(const struct ast_config *config, const char *category_name);
  2588. struct ast_category *localized_category_get(const struct ast_config *config, const char *category_name)
  2589. {
  2590. return category_get(config, category_name, 0);
  2591. }
  2592. static void move_variables(struct ast_category *old, struct ast_category *new)
  2593. {
  2594. struct ast_variable *var = old->root;
  2595. old->root = NULL;
  2596. #if 1
  2597. /* we can just move the entire list in a single op */
  2598. ast_variable_append(new, var);
  2599. #else
  2600. while (var) {
  2601. struct ast_variable *next = var->next;
  2602. var->next = NULL;
  2603. ast_variable_append(new, var);
  2604. var = next;
  2605. }
  2606. #endif
  2607. }
  2608. static void inherit_category(struct ast_category *new, const struct ast_category *base)
  2609. {
  2610. struct ast_variable *var;
  2611. for (var = base->root; var; var = var->next)
  2612. ast_variable_append(new, variable_clone(var));
  2613. }
  2614. static void ast_category_append(struct ast_config *config, struct ast_category *category);
  2615. static void ast_category_append(struct ast_config *config, struct ast_category *category)
  2616. {
  2617. if (config->last)
  2618. config->last->next = category;
  2619. else
  2620. config->root = category;
  2621. config->last = category;
  2622. config->current = category;
  2623. }
  2624. static void ast_category_destroy(struct ast_category *cat);
  2625. static void ast_category_destroy(struct ast_category *cat)
  2626. {
  2627. ast_variables_destroy(cat->root);
  2628. if (cat->file)
  2629. free(cat->file);
  2630. free(cat);
  2631. }
  2632. static struct ast_config_engine text_file_engine = {
  2633. .name = "text",
  2634. .load_func = config_text_file_load,
  2635. };
  2636. static struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_incl_file);
  2637. static struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_incl_file)
  2638. {
  2639. char db[256];
  2640. char table[256];
  2641. struct ast_config_engine *loader = &text_file_engine;
  2642. struct ast_config *result;
  2643. if (cfg->include_level == cfg->max_include_level) {
  2644. ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level);
  2645. return NULL;
  2646. }
  2647. cfg->include_level++;
  2648. /* silence is golden!
  2649. ast_log(LOG_WARNING, "internal loading file %s level=%d\n", filename, cfg->include_level);
  2650. */
  2651. if (strcmp(filename, extconfig_conf) && strcmp(filename, "asterisk.conf") && config_engine_list) {
  2652. struct ast_config_engine *eng;
  2653. eng = find_engine(filename, db, sizeof(db), table, sizeof(table));
  2654. if (eng && eng->load_func) {
  2655. loader = eng;
  2656. } else {
  2657. eng = find_engine("global", db, sizeof(db), table, sizeof(table));
  2658. if (eng && eng->load_func)
  2659. loader = eng;
  2660. }
  2661. }
  2662. result = loader->load_func(db, table, filename, cfg, withcomments, suggested_incl_file);
  2663. /* silence is golden
  2664. ast_log(LOG_WARNING, "finished internal loading file %s level=%d\n", filename, cfg->include_level);
  2665. */
  2666. if (result)
  2667. result->include_level--;
  2668. return result;
  2669. }
  2670. static int process_text_line(struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, int withcomments, const char *suggested_include_file)
  2671. {
  2672. char *c;
  2673. char *cur = buf;
  2674. struct ast_variable *v;
  2675. char exec_file[512];
  2676. int object, do_exec, do_include;
  2677. /* Actually parse the entry */
  2678. if (cur[0] == '[') {
  2679. struct ast_category *newcat = NULL;
  2680. char *catname;
  2681. /* A category header */
  2682. c = strchr(cur, ']');
  2683. if (!c) {
  2684. ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile);
  2685. return -1;
  2686. }
  2687. *c++ = '\0';
  2688. cur++;
  2689. if (*c++ != '(')
  2690. c = NULL;
  2691. catname = cur;
  2692. if (!(*cat = newcat = ast_category_new(catname, ast_strlen_zero(suggested_include_file)?configfile:suggested_include_file, lineno))) {
  2693. return -1;
  2694. }
  2695. (*cat)->lineno = lineno;
  2696. /* add comments */
  2697. if (withcomments && comment_buffer && comment_buffer[0] ) {
  2698. newcat->precomments = ALLOC_COMMENT(comment_buffer);
  2699. }
  2700. if (withcomments && lline_buffer && lline_buffer[0] ) {
  2701. newcat->sameline = ALLOC_COMMENT(lline_buffer);
  2702. }
  2703. if( withcomments )
  2704. CB_RESET();
  2705. /* If there are options or categories to inherit from, process them now */
  2706. if (c) {
  2707. if (!(cur = strchr(c, ')'))) {
  2708. ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile);
  2709. return -1;
  2710. }
  2711. *cur = '\0';
  2712. while ((cur = strsep(&c, ","))) {
  2713. if (!strcasecmp(cur, "!")) {
  2714. (*cat)->ignored = 1;
  2715. } else if (!strcasecmp(cur, "+")) {
  2716. *cat = category_get(cfg, catname, 1);
  2717. if (!*cat) {
  2718. ast_config_destroy(cfg);
  2719. if (newcat)
  2720. ast_category_destroy(newcat);
  2721. ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
  2722. return -1;
  2723. }
  2724. if (newcat) {
  2725. move_variables(newcat, *cat);
  2726. ast_category_destroy(newcat);
  2727. newcat = NULL;
  2728. }
  2729. } else {
  2730. struct ast_category *base;
  2731. base = category_get(cfg, cur, 1);
  2732. if (!base) {
  2733. ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
  2734. return -1;
  2735. }
  2736. inherit_category(*cat, base);
  2737. }
  2738. }
  2739. }
  2740. if (newcat)
  2741. ast_category_append(cfg, *cat);
  2742. } else if (cur[0] == '#') {
  2743. /* A directive */
  2744. cur++;
  2745. c = cur;
  2746. while(*c && (*c > 32)) c++;
  2747. if (*c) {
  2748. *c = '\0';
  2749. /* Find real argument */
  2750. c = ast_skip_blanks(c + 1);
  2751. if (!*c)
  2752. c = NULL;
  2753. } else
  2754. c = NULL;
  2755. do_include = !strcasecmp(cur, "include");
  2756. if(!do_include)
  2757. do_exec = !strcasecmp(cur, "exec");
  2758. else
  2759. do_exec = 0;
  2760. if (do_exec && !ast_opt_exec_includes) {
  2761. ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
  2762. do_exec = 0;
  2763. }
  2764. if (do_include || do_exec) {
  2765. if (c) {
  2766. char *cur2;
  2767. char real_inclusion_name[256];
  2768. /* Strip off leading and trailing "'s and <>'s */
  2769. while((*c == '<') || (*c == '>') || (*c == '\"')) c++;
  2770. /* Get rid of leading mess */
  2771. cur = c;
  2772. cur2 = cur;
  2773. while (!ast_strlen_zero(cur)) {
  2774. c = cur + strlen(cur) - 1;
  2775. if ((*c == '>') || (*c == '<') || (*c == '\"'))
  2776. *c = '\0';
  2777. else
  2778. break;
  2779. }
  2780. /* #exec </path/to/executable>
  2781. We create a tmp file, then we #include it, then we delete it. */
  2782. if (do_exec) {
  2783. char cmd[1024];
  2784. snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d.%ld", (int)time(NULL), (long)pthread_self());
  2785. if (snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file) >= sizeof(cmd)) {
  2786. ast_log(LOG_ERROR, "Failed to construct command string to execute %s.\n", cur);
  2787. return -1;
  2788. }
  2789. ast_safe_system(cmd);
  2790. cur = exec_file;
  2791. } else
  2792. exec_file[0] = '\0';
  2793. /* A #include */
  2794. /* ast_log(LOG_WARNING, "Reading in included file %s withcomments=%d\n", cur, withcomments); */
  2795. /* record this inclusion */
  2796. ast_include_new(cfg, configfile, cur, do_exec, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name));
  2797. do_include = ast_config_internal_load(cur, cfg, withcomments, real_inclusion_name) ? 1 : 0;
  2798. if(!ast_strlen_zero(exec_file))
  2799. unlink(exec_file);
  2800. if(!do_include)
  2801. return 0;
  2802. /* ast_log(LOG_WARNING, "Done reading in included file %s withcomments=%d\n", cur, withcomments); */
  2803. } else {
  2804. ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n",
  2805. do_exec ? "exec" : "include",
  2806. do_exec ? "/path/to/executable" : "filename",
  2807. lineno,
  2808. configfile);
  2809. }
  2810. }
  2811. else
  2812. ast_log(LOG_WARNING, "Unknown directive '%s' at line %d of %s\n", cur, lineno, configfile);
  2813. } else {
  2814. /* Just a line (variable = value) */
  2815. if (!*cat) {
  2816. ast_log(LOG_WARNING,
  2817. "parse error: No category context for line %d of %s\n", lineno, configfile);
  2818. return -1;
  2819. }
  2820. c = strchr(cur, '=');
  2821. if (c) {
  2822. *c = 0;
  2823. c++;
  2824. /* Ignore > in => */
  2825. if (*c== '>') {
  2826. object = 1;
  2827. c++;
  2828. } else
  2829. object = 0;
  2830. if ((v = ast_variable_new(ast_strip(cur), ast_strip(c), configfile))) {
  2831. v->lineno = lineno;
  2832. v->object = object;
  2833. /* Put and reset comments */
  2834. v->blanklines = 0;
  2835. ast_variable_append(*cat, v);
  2836. /* add comments */
  2837. if (withcomments && comment_buffer && comment_buffer[0] ) {
  2838. v->precomments = ALLOC_COMMENT(comment_buffer);
  2839. }
  2840. if (withcomments && lline_buffer && lline_buffer[0] ) {
  2841. v->sameline = ALLOC_COMMENT(lline_buffer);
  2842. }
  2843. if( withcomments )
  2844. CB_RESET();
  2845. } else {
  2846. return -1;
  2847. }
  2848. } else {
  2849. ast_log(LOG_WARNING, "EXTENSIONS.CONF: No '=' (equal sign) in line %d of %s\n", lineno, configfile);
  2850. }
  2851. }
  2852. return 0;
  2853. }
  2854. static int use_local_dir = 1;
  2855. void localized_use_local_dir(void);
  2856. void localized_use_conf_dir(void);
  2857. void localized_use_local_dir(void)
  2858. {
  2859. use_local_dir = 1;
  2860. }
  2861. void localized_use_conf_dir(void)
  2862. {
  2863. use_local_dir = 0;
  2864. }
  2865. static struct ast_config *config_text_file_load(const char *database, const char *table, const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_include_file)
  2866. {
  2867. char fn[256];
  2868. char buf[8192];
  2869. char *new_buf, *comment_p, *process_buf;
  2870. FILE *f;
  2871. int lineno=0;
  2872. int comment = 0, nest[MAX_NESTED_COMMENTS];
  2873. struct ast_category *cat = NULL;
  2874. int count = 0;
  2875. struct stat statbuf;
  2876. cat = ast_config_get_current_category(cfg);
  2877. if (filename[0] == '/') {
  2878. ast_copy_string(fn, filename, sizeof(fn));
  2879. } else {
  2880. if (use_local_dir)
  2881. snprintf(fn, sizeof(fn), "./%s", filename);
  2882. else
  2883. snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, filename);
  2884. }
  2885. if (withcomments && cfg && cfg->include_level < 2 ) {
  2886. CB_INIT();
  2887. }
  2888. do {
  2889. if (stat(fn, &statbuf))
  2890. continue;
  2891. if (!S_ISREG(statbuf.st_mode)) {
  2892. ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn);
  2893. continue;
  2894. }
  2895. if (option_verbose > 1) {
  2896. ast_verbose(VERBOSE_PREFIX_2 "Parsing '%s': ", fn);
  2897. fflush(stdout);
  2898. }
  2899. if (!(f = fopen(fn, "r"))) {
  2900. if (option_debug)
  2901. ast_log(LOG_DEBUG, "No file to parse: %s\n", fn);
  2902. if (option_verbose > 1)
  2903. ast_verbose( "Not found (%s)\n", strerror(errno));
  2904. continue;
  2905. }
  2906. count++;
  2907. if (option_debug)
  2908. ast_log(LOG_DEBUG, "Parsing %s\n", fn);
  2909. if (option_verbose > 1)
  2910. ast_verbose("Found\n");
  2911. while(!feof(f)) {
  2912. lineno++;
  2913. if (fgets(buf, sizeof(buf), f)) {
  2914. if ( withcomments ) {
  2915. CB_ADD(lline_buffer); /* add the current lline buffer to the comment buffer */
  2916. lline_buffer[0] = 0; /* erase the lline buffer */
  2917. }
  2918. new_buf = buf;
  2919. if (comment)
  2920. process_buf = NULL;
  2921. else
  2922. process_buf = buf;
  2923. while ((comment_p = strchr(new_buf, COMMENT_META))) {
  2924. if ((comment_p > new_buf) && (*(comment_p-1) == '\\')) {
  2925. /* Yuck, gotta memmove */
  2926. memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
  2927. new_buf = comment_p;
  2928. } else if(comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) {
  2929. /* Meta-Comment start detected ";--" */
  2930. if (comment < MAX_NESTED_COMMENTS) {
  2931. *comment_p = '\0';
  2932. new_buf = comment_p + 3;
  2933. comment++;
  2934. nest[comment-1] = lineno;
  2935. } else {
  2936. ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS);
  2937. }
  2938. } else if ((comment_p >= new_buf + 2) &&
  2939. (*(comment_p - 1) == COMMENT_TAG) &&
  2940. (*(comment_p - 2) == COMMENT_TAG)) {
  2941. /* Meta-Comment end detected */
  2942. comment--;
  2943. new_buf = comment_p + 1;
  2944. if (!comment) {
  2945. /* Back to non-comment now */
  2946. if (process_buf) {
  2947. /* Actually have to move what's left over the top, then continue */
  2948. char *oldptr;
  2949. oldptr = process_buf + strlen(process_buf);
  2950. if ( withcomments ) {
  2951. CB_ADD(";");
  2952. CB_ADD_LEN(oldptr+1,new_buf-oldptr-1);
  2953. }
  2954. memmove(oldptr, new_buf, strlen(new_buf) + 1);
  2955. new_buf = oldptr;
  2956. } else
  2957. process_buf = new_buf;
  2958. }
  2959. } else {
  2960. if (!comment) {
  2961. /* If ; is found, and we are not nested in a comment,
  2962. we immediately stop all comment processing */
  2963. if ( withcomments ) {
  2964. LLB_ADD(comment_p);
  2965. }
  2966. *comment_p = '\0';
  2967. new_buf = comment_p;
  2968. } else
  2969. new_buf = comment_p + 1;
  2970. }
  2971. }
  2972. if( withcomments && comment && !process_buf )
  2973. {
  2974. CB_ADD(buf); /* the whole line is a comment, store it */
  2975. }
  2976. if (process_buf) {
  2977. char *stripped_process_buf = ast_strip(process_buf);
  2978. if (!ast_strlen_zero(stripped_process_buf)) {
  2979. if (process_text_line(cfg, &cat, stripped_process_buf, lineno, filename, withcomments, suggested_include_file)) {
  2980. cfg = NULL;
  2981. break;
  2982. }
  2983. }
  2984. }
  2985. }
  2986. }
  2987. fclose(f);
  2988. } while(0);
  2989. if (comment) {
  2990. ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment]);
  2991. }
  2992. if (cfg && cfg->include_level == 1 && withcomments && comment_buffer) {
  2993. if (comment_buffer) {
  2994. free(comment_buffer);
  2995. free(lline_buffer);
  2996. comment_buffer=0;
  2997. lline_buffer=0;
  2998. comment_buffer_size=0;
  2999. lline_buffer_size=0;
  3000. }
  3001. }
  3002. if (count == 0)
  3003. return NULL;
  3004. return cfg;
  3005. }
  3006. static struct ast_config *ast_config_new(void) ;
  3007. static struct ast_config *ast_config_new(void)
  3008. {
  3009. struct ast_config *config;
  3010. if ((config = ast_calloc(1, sizeof(*config))))
  3011. config->max_include_level = MAX_INCLUDE_LEVEL;
  3012. return config;
  3013. }
  3014. struct ast_config *localized_config_load(const char *filename);
  3015. struct ast_config *localized_config_load(const char *filename)
  3016. {
  3017. struct ast_config *cfg;
  3018. struct ast_config *result;
  3019. cfg = ast_config_new();
  3020. if (!cfg)
  3021. return NULL;
  3022. result = ast_config_internal_load(filename, cfg, 0, "");
  3023. if (!result)
  3024. ast_config_destroy(cfg);
  3025. return result;
  3026. }
  3027. struct ast_config *localized_config_load_with_comments(const char *filename);
  3028. struct ast_config *localized_config_load_with_comments(const char *filename)
  3029. {
  3030. struct ast_config *cfg;
  3031. struct ast_config *result;
  3032. cfg = ast_config_new();
  3033. if (!cfg)
  3034. return NULL;
  3035. result = ast_config_internal_load(filename, cfg, 1, "");
  3036. if (!result)
  3037. ast_config_destroy(cfg);
  3038. return result;
  3039. }
  3040. static struct ast_category *next_available_category(struct ast_category *cat)
  3041. {
  3042. for (; cat && cat->ignored; cat = cat->next);
  3043. return cat;
  3044. }
  3045. static char *ast_category_browse(struct ast_config *config, const char *prev)
  3046. {
  3047. struct ast_category *cat = NULL;
  3048. if (prev && config->last_browse && (config->last_browse->name == prev))
  3049. cat = config->last_browse->next;
  3050. else if (!prev && config->root)
  3051. cat = config->root;
  3052. else if (prev) {
  3053. for (cat = config->root; cat; cat = cat->next) {
  3054. if (cat->name == prev) {
  3055. cat = cat->next;
  3056. break;
  3057. }
  3058. }
  3059. if (!cat) {
  3060. for (cat = config->root; cat; cat = cat->next) {
  3061. if (!strcasecmp(cat->name, prev)) {
  3062. cat = cat->next;
  3063. break;
  3064. }
  3065. }
  3066. }
  3067. }
  3068. if (cat)
  3069. cat = next_available_category(cat);
  3070. config->last_browse = cat;
  3071. return (cat) ? cat->name : NULL;
  3072. }
  3073. void ast_config_set_current_category(struct ast_config *cfg, const struct ast_category *cat);
  3074. void ast_config_set_current_category(struct ast_config *cfg, const struct ast_category *cat)
  3075. {
  3076. /* cast below is just to silence compiler warning about dropping "const" */
  3077. cfg->current = (struct ast_category *) cat;
  3078. }
  3079. /* NOTE: categories and variables each have a file and lineno attribute. On a save operation, these are used to determine
  3080. which file and line number to write out to. Thus, an entire hierarchy of config files (via #include statements) can be
  3081. recreated. BUT, care must be taken to make sure that every cat and var has the proper file name stored, or you may
  3082. be shocked and mystified as to why things are not showing up in the files!
  3083. Also, All #include/#exec statements are recorded in the "includes" LL in the ast_config structure. The file name
  3084. and line number are stored for each include, plus the name of the file included, so that these statements may be
  3085. included in the output files on a file_save operation.
  3086. The lineno's are really just for relative placement in the file. There is no attempt to make sure that blank lines
  3087. are included to keep the lineno's the same between input and output. The lineno fields are used mainly to determine
  3088. the position of the #include and #exec directives. So, blank lines tend to disappear from a read/rewrite operation,
  3089. and a header gets added.
  3090. vars and category heads are output in the order they are stored in the config file. So, if the software
  3091. shuffles these at all, then the placement of #include directives might get a little mixed up, because the
  3092. file/lineno data probably won't get changed.
  3093. */
  3094. static void gen_header(FILE *f1, const char *configfile, const char *fn, const char *generator)
  3095. {
  3096. char date[256]="";
  3097. time_t t;
  3098. time(&t);
  3099. ast_copy_string(date, ctime(&t), sizeof(date));
  3100. fprintf(f1, ";!\n");
  3101. fprintf(f1, ";! Automatically generated configuration file\n");
  3102. if (strcmp(configfile, fn))
  3103. fprintf(f1, ";! Filename: %s (%s)\n", configfile, fn);
  3104. else
  3105. fprintf(f1, ";! Filename: %s\n", configfile);
  3106. fprintf(f1, ";! Generator: %s\n", generator);
  3107. fprintf(f1, ";! Creation Date: %s", date);
  3108. fprintf(f1, ";!\n");
  3109. }
  3110. static void set_fn(char *fn, int fn_size, const char *file, const char *configfile)
  3111. {
  3112. if (!file || file[0] == 0) {
  3113. if (configfile[0] == '/')
  3114. ast_copy_string(fn, configfile, fn_size);
  3115. else
  3116. snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, configfile);
  3117. } else if (file[0] == '/')
  3118. ast_copy_string(fn, file, fn_size);
  3119. else
  3120. snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, file);
  3121. }
  3122. int localized_config_text_file_save(const char *configfile, const struct ast_config *cfg, const char *generator);
  3123. int localized_config_text_file_save(const char *configfile, const struct ast_config *cfg, const char *generator)
  3124. {
  3125. FILE *f;
  3126. char fn[256];
  3127. struct ast_variable *var;
  3128. struct ast_category *cat;
  3129. struct ast_comment *cmt;
  3130. struct ast_config_include *incl;
  3131. int blanklines = 0;
  3132. /* reset all the output flags, in case this isn't our first time saving this data */
  3133. for (incl=cfg->includes; incl; incl = incl->next)
  3134. incl->output = 0;
  3135. /* go thru all the inclusions and make sure all the files involved (configfile plus all its inclusions)
  3136. are all truncated to zero bytes and have that nice header*/
  3137. for (incl=cfg->includes; incl; incl = incl->next)
  3138. {
  3139. if (!incl->exec) { /* leave the execs alone -- we'll write out the #exec directives, but won't zero out the include files or exec files*/
  3140. FILE *f1;
  3141. set_fn(fn, sizeof(fn), incl->included_file, configfile); /* normally, fn is just set to incl->included_file, prepended with config dir if relative */
  3142. f1 = fopen(fn,"w");
  3143. if (f1) {
  3144. gen_header(f1, configfile, fn, generator);
  3145. fclose(f1); /* this should zero out the file */
  3146. } else {
  3147. ast_verbose(VERBOSE_PREFIX_2 "Unable to write %s (%s)", fn, strerror(errno));
  3148. }
  3149. }
  3150. }
  3151. set_fn(fn, sizeof(fn), 0, configfile); /* just set fn to absolute ver of configfile */
  3152. #ifdef __CYGWIN__
  3153. if ((f = fopen(fn, "w+"))) {
  3154. #else
  3155. if ((f = fopen(fn, "w"))) {
  3156. #endif
  3157. if (option_verbose > 1)
  3158. ast_verbose(VERBOSE_PREFIX_2 "Saving '%s': ", fn);
  3159. gen_header(f, configfile, fn, generator);
  3160. cat = cfg->root;
  3161. fclose(f);
  3162. /* from here out, we open each involved file and concat the stuff we need to add to the end and immediately close... */
  3163. /* since each var, cat, and associated comments can come from any file, we have to be
  3164. mobile, and open each file, print, and close it on an entry-by-entry basis */
  3165. while(cat) {
  3166. set_fn(fn, sizeof(fn), cat->file, configfile);
  3167. f = fopen(fn, "a");
  3168. if (!f)
  3169. {
  3170. ast_verbose(VERBOSE_PREFIX_2 "Unable to write %s (%s)", fn, strerror(errno));
  3171. return -1;
  3172. }
  3173. /* dump any includes that happen before this category header */
  3174. for (incl=cfg->includes; incl; incl = incl->next) {
  3175. if (strcmp(incl->include_location_file, cat->file) == 0){
  3176. if (cat->lineno > incl->include_location_lineno && !incl->output) {
  3177. if (incl->exec)
  3178. fprintf(f,"#exec \"%s\"\n", incl->exec_file);
  3179. else
  3180. fprintf(f,"#include \"%s\"\n", incl->included_file);
  3181. incl->output = 1;
  3182. }
  3183. }
  3184. }
  3185. /* Dump section with any appropriate comment */
  3186. for (cmt = cat->precomments; cmt; cmt=cmt->next) {
  3187. if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
  3188. fprintf(f,"%s", cmt->cmt);
  3189. }
  3190. if (!cat->precomments)
  3191. fprintf(f,"\n");
  3192. fprintf(f, "[%s]", cat->name);
  3193. for(cmt = cat->sameline; cmt; cmt=cmt->next) {
  3194. fprintf(f,"%s", cmt->cmt);
  3195. }
  3196. if (!cat->sameline)
  3197. fprintf(f,"\n");
  3198. fclose(f);
  3199. var = cat->root;
  3200. while(var) {
  3201. set_fn(fn, sizeof(fn), var->file, configfile);
  3202. f = fopen(fn, "a");
  3203. if (!f)
  3204. {
  3205. ast_verbose(VERBOSE_PREFIX_2 "Unable to write %s (%s)", fn, strerror(errno));
  3206. return -1;
  3207. }
  3208. /* dump any includes that happen before this category header */
  3209. for (incl=cfg->includes; incl; incl = incl->next) {
  3210. if (strcmp(incl->include_location_file, var->file) == 0){
  3211. if (var->lineno > incl->include_location_lineno && !incl->output) {
  3212. if (incl->exec)
  3213. fprintf(f,"#exec \"%s\"\n", incl->exec_file);
  3214. else
  3215. fprintf(f,"#include \"%s\"\n", incl->included_file);
  3216. incl->output = 1;
  3217. }
  3218. }
  3219. }
  3220. for (cmt = var->precomments; cmt; cmt=cmt->next) {
  3221. if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
  3222. fprintf(f,"%s", cmt->cmt);
  3223. }
  3224. if (var->sameline)
  3225. fprintf(f, "%s %s %s %s", var->name, (var->object ? "=>" : "="), var->value, var->sameline->cmt);
  3226. else
  3227. fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="), var->value);
  3228. if (var->blanklines) {
  3229. blanklines = var->blanklines;
  3230. while (blanklines--)
  3231. fprintf(f, "\n");
  3232. }
  3233. fclose(f);
  3234. var = var->next;
  3235. }
  3236. cat = cat->next;
  3237. }
  3238. if ((option_verbose > 1) && !option_debug)
  3239. ast_verbose("Saved\n");
  3240. } else {
  3241. if (option_debug)
  3242. ast_log(LOG_DEBUG, "Unable to open for writing: %s\n", fn);
  3243. if (option_verbose > 1)
  3244. ast_verbose(VERBOSE_PREFIX_2 "Unable to write (%s)", strerror(errno));
  3245. return -1;
  3246. }
  3247. /* Now, for files with trailing #include/#exec statements,
  3248. we have to make sure every entry is output */
  3249. for (incl=cfg->includes; incl; incl = incl->next) {
  3250. if (!incl->output) {
  3251. /* open the respective file */
  3252. set_fn(fn, sizeof(fn), incl->include_location_file, configfile);
  3253. f = fopen(fn, "a");
  3254. if (!f)
  3255. {
  3256. ast_verbose(VERBOSE_PREFIX_2 "Unable to write %s (%s)", fn, strerror(errno));
  3257. return -1;
  3258. }
  3259. /* output the respective include */
  3260. if (incl->exec)
  3261. fprintf(f,"#exec \"%s\"\n", incl->exec_file);
  3262. else
  3263. fprintf(f,"#include \"%s\"\n", incl->included_file);
  3264. fclose(f);
  3265. incl->output = 1;
  3266. }
  3267. }
  3268. return 0;
  3269. }
  3270. /* ================ the Line ========================================
  3271. above this line, you have what you need to load a config file,
  3272. and below it, you have what you need to process the extensions.conf
  3273. file into the context/exten/prio stuff. They are both in one file
  3274. to make things simpler */
  3275. static struct ast_context *local_contexts = NULL;
  3276. static struct ast_context *contexts = NULL;
  3277. struct ast_context;
  3278. struct ast_app;
  3279. #ifdef LOW_MEMORY
  3280. #define EXT_DATA_SIZE 256
  3281. #else
  3282. #define EXT_DATA_SIZE 8192
  3283. #endif
  3284. #ifdef NOT_ANYMORE
  3285. static AST_RWLIST_HEAD_STATIC(switches, ast_switch);
  3286. #endif
  3287. #define SWITCH_DATA_LENGTH 256
  3288. static const char *ast_get_extension_app(struct ast_exten *e)
  3289. {
  3290. return e ? e->app : NULL;
  3291. }
  3292. static const char *ast_get_extension_name(struct ast_exten *exten)
  3293. {
  3294. return exten ? exten->exten : NULL;
  3295. }
  3296. static AST_RWLIST_HEAD_STATIC(hints, ast_hint);
  3297. /*! \brief ast_change_hint: Change hint for an extension */
  3298. static int ast_change_hint(struct ast_exten *oe, struct ast_exten *ne)
  3299. {
  3300. struct ast_hint *hint;
  3301. int res = -1;
  3302. AST_RWLIST_TRAVERSE(&hints, hint, list) {
  3303. if (hint->exten == oe) {
  3304. hint->exten = ne;
  3305. res = 0;
  3306. break;
  3307. }
  3308. }
  3309. return res;
  3310. }
  3311. /*! \brief ast_add_hint: Add hint to hint list, check initial extension state */
  3312. static int ast_add_hint(struct ast_exten *e)
  3313. {
  3314. struct ast_hint *hint;
  3315. if (!e)
  3316. return -1;
  3317. /* Search if hint exists, do nothing */
  3318. AST_RWLIST_TRAVERSE(&hints, hint, list) {
  3319. if (hint->exten == e) {
  3320. if (option_debug > 1)
  3321. ast_log(LOG_DEBUG, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e));
  3322. return -1;
  3323. }
  3324. }
  3325. if (option_debug > 1)
  3326. ast_log(LOG_DEBUG, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e));
  3327. if (!(hint = ast_calloc(1, sizeof(*hint)))) {
  3328. return -1;
  3329. }
  3330. /* Initialize and insert new item at the top */
  3331. hint->exten = e;
  3332. AST_RWLIST_INSERT_HEAD(&hints, hint, list);
  3333. return 0;
  3334. }
  3335. /*! \brief add the extension in the priority chain.
  3336. * returns 0 on success, -1 on failure
  3337. */
  3338. static int add_pri(struct ast_context *con, struct ast_exten *tmp,
  3339. struct ast_exten *el, struct ast_exten *e, int replace)
  3340. {
  3341. struct ast_exten *ep;
  3342. for (ep = NULL; e ; ep = e, e = e->peer) {
  3343. if (e->priority >= tmp->priority)
  3344. break;
  3345. }
  3346. if (!e) { /* go at the end, and ep is surely set because the list is not empty */
  3347. ep->peer = tmp;
  3348. return 0; /* success */
  3349. }
  3350. if (e->priority == tmp->priority) {
  3351. /* Can't have something exactly the same. Is this a
  3352. replacement? If so, replace, otherwise, bonk. */
  3353. if (!replace) {
  3354. ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name);
  3355. tmp->datad(tmp->data);
  3356. free(tmp);
  3357. return -1;
  3358. }
  3359. /* we are replacing e, so copy the link fields and then update
  3360. * whoever pointed to e to point to us
  3361. */
  3362. tmp->next = e->next; /* not meaningful if we are not first in the peer list */
  3363. tmp->peer = e->peer; /* always meaningful */
  3364. if (ep) /* We're in the peer list, just insert ourselves */
  3365. ep->peer = tmp;
  3366. else if (el) /* We're the first extension. Take over e's functions */
  3367. el->next = tmp;
  3368. else /* We're the very first extension. */
  3369. con->root = tmp;
  3370. if (tmp->priority == PRIORITY_HINT)
  3371. ast_change_hint(e,tmp);
  3372. /* Destroy the old one */
  3373. e->datad(e->data);
  3374. free(e);
  3375. } else { /* Slip ourselves in just before e */
  3376. tmp->peer = e;
  3377. tmp->next = e->next; /* extension chain, or NULL if e is not the first extension */
  3378. if (ep) /* Easy enough, we're just in the peer list */
  3379. ep->peer = tmp;
  3380. else { /* we are the first in some peer list, so link in the ext list */
  3381. if (el)
  3382. el->next = tmp; /* in the middle... */
  3383. else
  3384. con->root = tmp; /* ... or at the head */
  3385. e->next = NULL; /* e is no more at the head, so e->next must be reset */
  3386. }
  3387. /* And immediately return success. */
  3388. if (tmp->priority == PRIORITY_HINT)
  3389. ast_add_hint(tmp);
  3390. }
  3391. return 0;
  3392. }
  3393. /*! \brief ast_remove_hint: Remove hint from extension */
  3394. static int ast_remove_hint(struct ast_exten *e)
  3395. {
  3396. /* Cleanup the Notifys if hint is removed */
  3397. struct ast_hint *hint;
  3398. struct ast_state_cb *cblist, *cbprev;
  3399. int res = -1;
  3400. if (!e)
  3401. return -1;
  3402. AST_RWLIST_TRAVERSE_SAFE_BEGIN(&hints, hint, list) {
  3403. if (hint->exten == e) {
  3404. cbprev = NULL;
  3405. cblist = hint->callbacks;
  3406. while (cblist) {
  3407. /* Notify with -1 and remove all callbacks */
  3408. cbprev = cblist;
  3409. cblist = cblist->next;
  3410. free(cbprev);
  3411. }
  3412. hint->callbacks = NULL;
  3413. AST_RWLIST_REMOVE_CURRENT(&hints, list);
  3414. free(hint);
  3415. res = 0;
  3416. break;
  3417. }
  3418. }
  3419. AST_RWLIST_TRAVERSE_SAFE_END
  3420. return res;
  3421. }
  3422. static void destroy_exten(struct ast_exten *e)
  3423. {
  3424. if (e->priority == PRIORITY_HINT)
  3425. ast_remove_hint(e);
  3426. if (e->datad)
  3427. e->datad(e->data);
  3428. free(e);
  3429. }
  3430. char *days[] =
  3431. {
  3432. "sun",
  3433. "mon",
  3434. "tue",
  3435. "wed",
  3436. "thu",
  3437. "fri",
  3438. "sat",
  3439. NULL,
  3440. };
  3441. char *months[] =
  3442. {
  3443. "jan",
  3444. "feb",
  3445. "mar",
  3446. "apr",
  3447. "may",
  3448. "jun",
  3449. "jul",
  3450. "aug",
  3451. "sep",
  3452. "oct",
  3453. "nov",
  3454. "dec",
  3455. NULL,
  3456. };
  3457. int ast_build_timing(struct ast_timing *i, const char *info_in);
  3458. int ast_build_timing(struct ast_timing *i, const char *info_in)
  3459. {
  3460. char *info;
  3461. int j, num_fields, last_sep = -1;
  3462. i->timezone = NULL;
  3463. /* Check for empty just in case */
  3464. if (ast_strlen_zero(info_in)) {
  3465. return 0;
  3466. }
  3467. /* make a copy just in case we were passed a static string */
  3468. info = ast_strdupa(info_in);
  3469. /* count the number of fields in the timespec */
  3470. for (j = 0, num_fields = 1; info[j] != '\0'; j++) {
  3471. if (info[j] == ',') {
  3472. last_sep = j;
  3473. num_fields++;
  3474. }
  3475. }
  3476. /* save the timezone, if it is specified */
  3477. if (num_fields == 5) {
  3478. i->timezone = ast_strdup(info + last_sep + 1);
  3479. }
  3480. /* Assume everything except time */
  3481. i->monthmask = 0xfff; /* 12 bits */
  3482. i->daymask = 0x7fffffffU; /* 31 bits */
  3483. i->dowmask = 0x7f; /* 7 bits */
  3484. /* on each call, use strsep() to move info to the next argument */
  3485. get_timerange(i, strsep(&info, "|,"));
  3486. if (info)
  3487. i->dowmask = get_range(strsep(&info, "|,"), 7, days, "day of week");
  3488. if (info)
  3489. i->daymask = get_range(strsep(&info, "|,"), 31, NULL, "day");
  3490. if (info)
  3491. i->monthmask = get_range(strsep(&info, "|,"), 12, months, "month");
  3492. return 1;
  3493. }
  3494. /*!
  3495. * \brief helper functions to sort extensions and patterns in the desired way,
  3496. * so that more specific patterns appear first.
  3497. *
  3498. * ext_cmp1 compares individual characters (or sets of), returning
  3499. * an int where bits 0-7 are the ASCII code of the first char in the set,
  3500. * while bit 8-15 are the cardinality of the set minus 1.
  3501. * This way more specific patterns (smaller cardinality) appear first.
  3502. * Wildcards have a special value, so that we can directly compare them to
  3503. * sets by subtracting the two values. In particular:
  3504. * 0x000xx one character, xx
  3505. * 0x0yyxx yy character set starting with xx
  3506. * 0x10000 '.' (one or more of anything)
  3507. * 0x20000 '!' (zero or more of anything)
  3508. * 0x30000 NUL (end of string)
  3509. * 0x40000 error in set.
  3510. * The pointer to the string is advanced according to needs.
  3511. * NOTES:
  3512. * 1. the empty set is equivalent to NUL.
  3513. * 2. given that a full set has always 0 as the first element,
  3514. * we could encode the special cases as 0xffXX where XX
  3515. * is 1, 2, 3, 4 as used above.
  3516. */
  3517. static int ext_cmp1(const char **p)
  3518. {
  3519. uint32_t chars[8];
  3520. int c, cmin = 0xff, count = 0;
  3521. const char *end;
  3522. /* load, sign extend and advance pointer until we find
  3523. * a valid character.
  3524. */
  3525. while ( (c = *(*p)++) && (c == ' ' || c == '-') )
  3526. ; /* ignore some characters */
  3527. /* always return unless we have a set of chars */
  3528. switch (c) {
  3529. default: /* ordinary character */
  3530. return 0x0000 | (c & 0xff);
  3531. case 'N': /* 2..9 */
  3532. return 0x0700 | '2' ;
  3533. case 'X': /* 0..9 */
  3534. return 0x0900 | '0';
  3535. case 'Z': /* 1..9 */
  3536. return 0x0800 | '1';
  3537. case '.': /* wildcard */
  3538. return 0x10000;
  3539. case '!': /* earlymatch */
  3540. return 0x20000; /* less specific than NULL */
  3541. case '\0': /* empty string */
  3542. *p = NULL;
  3543. return 0x30000;
  3544. case '[': /* pattern */
  3545. break;
  3546. }
  3547. /* locate end of set */
  3548. end = strchr(*p, ']');
  3549. if (end == NULL) {
  3550. ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
  3551. return 0x40000; /* XXX make this entry go last... */
  3552. }
  3553. memset(chars, '\0', sizeof(chars)); /* clear all chars in the set */
  3554. for (; *p < end ; (*p)++) {
  3555. unsigned char c1, c2; /* first-last char in range */
  3556. c1 = (unsigned char)((*p)[0]);
  3557. if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */
  3558. c2 = (unsigned char)((*p)[2]);
  3559. *p += 2; /* skip a total of 3 chars */
  3560. } else /* individual character */
  3561. c2 = c1;
  3562. if (c1 < cmin)
  3563. cmin = c1;
  3564. for (; c1 <= c2; c1++) {
  3565. uint32_t mask = 1 << (c1 % 32);
  3566. if ( (chars[ c1 / 32 ] & mask) == 0)
  3567. count += 0x100;
  3568. chars[ c1 / 32 ] |= mask;
  3569. }
  3570. }
  3571. (*p)++;
  3572. return count == 0 ? 0x30000 : (count | cmin);
  3573. }
  3574. /*!
  3575. * \brief the full routine to compare extensions in rules.
  3576. */
  3577. static int ext_cmp(const char *a, const char *b)
  3578. {
  3579. /* make sure non-patterns come first.
  3580. * If a is not a pattern, it either comes first or
  3581. * we use strcmp to compare the strings.
  3582. */
  3583. int ret = 0;
  3584. if (a[0] != '_')
  3585. return (b[0] == '_') ? -1 : strcmp(a, b);
  3586. /* Now we know a is a pattern; if b is not, a comes first */
  3587. if (b[0] != '_')
  3588. return 1;
  3589. #if 0 /* old mode for ext matching */
  3590. return strcmp(a, b);
  3591. #endif
  3592. /* ok we need full pattern sorting routine */
  3593. while (!ret && a && b)
  3594. ret = ext_cmp1(&a) - ext_cmp1(&b);
  3595. if (ret == 0)
  3596. return 0;
  3597. else
  3598. return (ret > 0) ? 1 : -1;
  3599. }
  3600. /*! \brief copy a string skipping whitespace */
  3601. static int ext_strncpy(char *dst, const char *src, int len)
  3602. {
  3603. int count=0;
  3604. while (*src && (count < len - 1)) {
  3605. switch(*src) {
  3606. case ' ':
  3607. /* otherwise exten => [a-b],1,... doesn't work */
  3608. /* case '-': */
  3609. /* Ignore */
  3610. break;
  3611. default:
  3612. *dst = *src;
  3613. dst++;
  3614. }
  3615. src++;
  3616. count++;
  3617. }
  3618. *dst = '\0';
  3619. return count;
  3620. }
  3621. /*
  3622. * Wrapper around _extension_match_core() to do performance measurement
  3623. * using the profiling code.
  3624. */
  3625. int ast_check_timing(const struct ast_timing *i);
  3626. int ast_check_timing(const struct ast_timing *i)
  3627. {
  3628. /* sorry, but this feature will NOT be available
  3629. in the standalone version */
  3630. return 0;
  3631. }
  3632. #ifdef NOT_ANYMORE
  3633. static struct ast_switch *pbx_findswitch(const char *sw)
  3634. {
  3635. struct ast_switch *asw;
  3636. AST_RWLIST_TRAVERSE(&switches, asw, list) {
  3637. if (!strcasecmp(asw->name, sw))
  3638. break;
  3639. }
  3640. return asw;
  3641. }
  3642. #endif
  3643. static struct ast_context *ast_walk_contexts(struct ast_context *con);
  3644. static struct ast_context *ast_walk_contexts(struct ast_context *con)
  3645. {
  3646. return con ? con->next : contexts;
  3647. }
  3648. struct ast_context *localized_walk_contexts(struct ast_context *con);
  3649. struct ast_context *localized_walk_contexts(struct ast_context *con)
  3650. {
  3651. return ast_walk_contexts(con);
  3652. }
  3653. static struct ast_exten *ast_walk_context_extensions(struct ast_context *con,
  3654. struct ast_exten *exten);
  3655. static struct ast_exten *ast_walk_context_extensions(struct ast_context *con,
  3656. struct ast_exten *exten)
  3657. {
  3658. if (!exten)
  3659. return con ? con->root : NULL;
  3660. else
  3661. return exten->next;
  3662. }
  3663. struct ast_exten *localized_walk_context_extensions(struct ast_context *con,
  3664. struct ast_exten *exten);
  3665. struct ast_exten *localized_walk_context_extensions(struct ast_context *con,
  3666. struct ast_exten *exten)
  3667. {
  3668. return ast_walk_context_extensions(con,exten);
  3669. }
  3670. static struct ast_exten *ast_walk_extension_priorities(struct ast_exten *exten,
  3671. struct ast_exten *priority);
  3672. static struct ast_exten *ast_walk_extension_priorities(struct ast_exten *exten,
  3673. struct ast_exten *priority)
  3674. {
  3675. return priority ? priority->peer : exten;
  3676. }
  3677. struct ast_exten *localized_walk_extension_priorities(struct ast_exten *exten,
  3678. struct ast_exten *priority);
  3679. struct ast_exten *localized_walk_extension_priorities(struct ast_exten *exten,
  3680. struct ast_exten *priority)
  3681. {
  3682. return ast_walk_extension_priorities(exten, priority);
  3683. }
  3684. static struct ast_include *ast_walk_context_includes(struct ast_context *con,
  3685. struct ast_include *inc);
  3686. static struct ast_include *ast_walk_context_includes(struct ast_context *con,
  3687. struct ast_include *inc)
  3688. {
  3689. if (!inc)
  3690. return con ? con->includes : NULL;
  3691. else
  3692. return inc->next;
  3693. }
  3694. struct ast_include *localized_walk_context_includes(struct ast_context *con,
  3695. struct ast_include *inc);
  3696. struct ast_include *localized_walk_context_includes(struct ast_context *con,
  3697. struct ast_include *inc)
  3698. {
  3699. return ast_walk_context_includes(con, inc);
  3700. }
  3701. static struct ast_sw *ast_walk_context_switches(struct ast_context *con,
  3702. struct ast_sw *sw);
  3703. static struct ast_sw *ast_walk_context_switches(struct ast_context *con,
  3704. struct ast_sw *sw)
  3705. {
  3706. if (!sw)
  3707. return con ? AST_LIST_FIRST(&con->alts) : NULL;
  3708. else
  3709. return AST_LIST_NEXT(sw, list);
  3710. }
  3711. struct ast_sw *localized_walk_context_switches(struct ast_context *con,
  3712. struct ast_sw *sw);
  3713. struct ast_sw *localized_walk_context_switches(struct ast_context *con,
  3714. struct ast_sw *sw)
  3715. {
  3716. return ast_walk_context_switches(con, sw);
  3717. }
  3718. static struct ast_context *ast_context_find(const char *name);
  3719. static struct ast_context *ast_context_find(const char *name)
  3720. {
  3721. struct ast_context *tmp = NULL;
  3722. while ( (tmp = ast_walk_contexts(tmp)) ) {
  3723. if (!name || !strcasecmp(name, tmp->name))
  3724. break;
  3725. }
  3726. return tmp;
  3727. }
  3728. /*
  3729. * Internal function for ast_extension_{match|close}
  3730. * return 0 on no-match, 1 on match, 2 on early match.
  3731. * mode is as follows:
  3732. * E_MATCH success only on exact match
  3733. * E_MATCHMORE success only on partial match (i.e. leftover digits in pattern)
  3734. * E_CANMATCH either of the above.
  3735. */
  3736. static int _extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
  3737. {
  3738. mode &= E_MATCH_MASK; /* only consider the relevant bits */
  3739. if ( (mode == E_MATCH) && (pattern[0] == '_') && (strcasecmp(pattern,data)==0) ) /* note: if this test is left out, then _x. will not match _x. !!! */
  3740. return 1;
  3741. if (pattern[0] != '_') { /* not a pattern, try exact or partial match */
  3742. int ld = strlen(data), lp = strlen(pattern);
  3743. if (lp < ld) /* pattern too short, cannot match */
  3744. return 0;
  3745. /* depending on the mode, accept full or partial match or both */
  3746. if (mode == E_MATCH)
  3747. return !strcmp(pattern, data); /* 1 on match, 0 on fail */
  3748. if (ld == 0 || !strncasecmp(pattern, data, ld)) /* partial or full match */
  3749. return (mode == E_MATCHMORE) ? lp > ld : 1; /* XXX should consider '!' and '/' ? */
  3750. else
  3751. return 0;
  3752. }
  3753. pattern++; /* skip leading _ */
  3754. /*
  3755. * XXX below we stop at '/' which is a separator for the CID info. However we should
  3756. * not store '/' in the pattern at all. When we insure it, we can remove the checks.
  3757. */
  3758. while (*data && *pattern && *pattern != '/') {
  3759. const char *end;
  3760. if (*data == '-') { /* skip '-' in data (just a separator) */
  3761. data++;
  3762. continue;
  3763. }
  3764. switch (toupper(*pattern)) {
  3765. case '[': /* a range */
  3766. end = strchr(pattern+1, ']'); /* XXX should deal with escapes ? */
  3767. if (end == NULL) {
  3768. ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
  3769. return 0; /* unconditional failure */
  3770. }
  3771. for (pattern++; pattern != end; pattern++) {
  3772. if (pattern+2 < end && pattern[1] == '-') { /* this is a range */
  3773. if (*data >= pattern[0] && *data <= pattern[2])
  3774. break; /* match found */
  3775. else {
  3776. pattern += 2; /* skip a total of 3 chars */
  3777. continue;
  3778. }
  3779. } else if (*data == pattern[0])
  3780. break; /* match found */
  3781. }
  3782. if (pattern == end)
  3783. return 0;
  3784. pattern = end; /* skip and continue */
  3785. break;
  3786. case 'N':
  3787. if (*data < '2' || *data > '9')
  3788. return 0;
  3789. break;
  3790. case 'X':
  3791. if (*data < '0' || *data > '9')
  3792. return 0;
  3793. break;
  3794. case 'Z':
  3795. if (*data < '1' || *data > '9')
  3796. return 0;
  3797. break;
  3798. case '.': /* Must match, even with more digits */
  3799. return 1;
  3800. case '!': /* Early match */
  3801. return 2;
  3802. case ' ':
  3803. case '-': /* Ignore these in patterns */
  3804. data--; /* compensate the final data++ */
  3805. break;
  3806. default:
  3807. if (*data != *pattern)
  3808. return 0;
  3809. }
  3810. data++;
  3811. pattern++;
  3812. }
  3813. if (*data) /* data longer than pattern, no match */
  3814. return 0;
  3815. /*
  3816. * match so far, but ran off the end of the data.
  3817. * Depending on what is next, determine match or not.
  3818. */
  3819. if (*pattern == '\0' || *pattern == '/') /* exact match */
  3820. return (mode == E_MATCHMORE) ? 0 : 1; /* this is a failure for E_MATCHMORE */
  3821. else if (*pattern == '!') /* early match */
  3822. return 2;
  3823. else /* partial match */
  3824. return (mode == E_MATCH) ? 0 : 1; /* this is a failure for E_MATCH */
  3825. }
  3826. static int extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
  3827. {
  3828. int i;
  3829. i = _extension_match_core(pattern, data, mode);
  3830. return i;
  3831. }
  3832. static int ast_extension_match(const char *pattern, const char *data);
  3833. static int ast_extension_match(const char *pattern, const char *data)
  3834. {
  3835. return extension_match_core(pattern, data, E_MATCH);
  3836. }
  3837. static int matchcid(const char *cidpattern, const char *callerid)
  3838. {
  3839. /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so
  3840. failing to get a number should count as a match, otherwise not */
  3841. if (ast_strlen_zero(callerid))
  3842. return ast_strlen_zero(cidpattern) ? 1 : 0;
  3843. return ast_extension_match(cidpattern, callerid);
  3844. }
  3845. static inline int include_valid(struct ast_include *i)
  3846. {
  3847. if (!i->hastime)
  3848. return 1;
  3849. return ast_check_timing(&(i->timing));
  3850. }
  3851. static struct ast_exten *pbx_find_extension(struct ast_channel *chan,
  3852. struct ast_context *bypass,
  3853. struct pbx_find_info *q,
  3854. const char *context,
  3855. const char *exten,
  3856. int priority,
  3857. const char *label,
  3858. const char *callerid,
  3859. enum ext_match_t action);
  3860. static struct ast_exten *pbx_find_extension(struct ast_channel *chan,
  3861. struct ast_context *bypass,
  3862. struct pbx_find_info *q,
  3863. const char *context,
  3864. const char *exten,
  3865. int priority,
  3866. const char *label,
  3867. const char *callerid,
  3868. enum ext_match_t action)
  3869. {
  3870. int x;
  3871. struct ast_context *tmp;
  3872. struct ast_exten *e, *eroot;
  3873. struct ast_include *i;
  3874. if (!context) {
  3875. return NULL;
  3876. }
  3877. /* Initialize status if appropriate */
  3878. if (q->stacklen == 0) {
  3879. q->status = STATUS_NO_CONTEXT;
  3880. q->swo = NULL;
  3881. q->data = NULL;
  3882. q->foundcontext = NULL;
  3883. } else if (q->stacklen >= AST_PBX_MAX_STACK) {
  3884. ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
  3885. return NULL;
  3886. }
  3887. /* Check first to see if we've already been checked */
  3888. for (x = 0; x < q->stacklen; x++) {
  3889. if (!strcasecmp(q->incstack[x], context))
  3890. return NULL;
  3891. }
  3892. if (bypass) /* bypass means we only look there */
  3893. tmp = bypass;
  3894. else { /* look in contexts */
  3895. tmp = NULL;
  3896. while ((tmp = ast_walk_contexts(tmp)) ) {
  3897. if (!strcmp(tmp->name, context))
  3898. break;
  3899. }
  3900. if (!tmp)
  3901. return NULL;
  3902. }
  3903. if (q->status < STATUS_NO_EXTENSION)
  3904. q->status = STATUS_NO_EXTENSION;
  3905. /* scan the list trying to match extension and CID */
  3906. eroot = NULL;
  3907. while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) {
  3908. int match = extension_match_core(eroot->exten, exten, action);
  3909. /* 0 on fail, 1 on match, 2 on earlymatch */
  3910. if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid)))
  3911. continue; /* keep trying */
  3912. if (match == 2 && action == E_MATCHMORE) {
  3913. /* We match an extension ending in '!'.
  3914. * The decision in this case is final and is NULL (no match).
  3915. */
  3916. return NULL;
  3917. }
  3918. /* found entry, now look for the right priority */
  3919. if (q->status < STATUS_NO_PRIORITY)
  3920. q->status = STATUS_NO_PRIORITY;
  3921. e = NULL;
  3922. while ( (e = ast_walk_extension_priorities(eroot, e)) ) {
  3923. /* Match label or priority */
  3924. if (action == E_FINDLABEL) {
  3925. if (q->status < STATUS_NO_LABEL)
  3926. q->status = STATUS_NO_LABEL;
  3927. if (label && e->label && !strcmp(label, e->label))
  3928. break; /* found it */
  3929. } else if (e->priority == priority) {
  3930. break; /* found it */
  3931. } /* else keep searching */
  3932. }
  3933. if (e) { /* found a valid match */
  3934. q->status = STATUS_SUCCESS;
  3935. q->foundcontext = context;
  3936. return e;
  3937. }
  3938. }
  3939. #ifdef NOT_RIGHT_NOW
  3940. /* Check alternative switches??? */
  3941. AST_LIST_TRAVERSE(&tmp->alts, sw, list) {
  3942. struct ast_switch *asw = pbx_findswitch(sw->name);
  3943. ast_switch_f *aswf = NULL;
  3944. char *datap;
  3945. if (!asw) {
  3946. ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name);
  3947. continue;
  3948. }
  3949. /* No need to Substitute variables now; we shouldn't be here if there's any */
  3950. /* equivalent of extension_match_core() at the switch level */
  3951. if (action == E_CANMATCH)
  3952. aswf = asw->canmatch;
  3953. else if (action == E_MATCHMORE)
  3954. aswf = asw->matchmore;
  3955. else /* action == E_MATCH */
  3956. aswf = asw->exists;
  3957. datap = sw->eval ? sw->tmpdata : sw->data;
  3958. res = !aswf ? 0 : aswf(chan, context, exten, priority, callerid, datap);
  3959. if (res) { /* Got a match */
  3960. q->swo = asw;
  3961. q->data = datap;
  3962. q->foundcontext = context;
  3963. /* XXX keep status = STATUS_NO_CONTEXT ? */
  3964. return NULL;
  3965. }
  3966. }
  3967. #endif
  3968. q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */
  3969. /* Now try any includes we have in this context */
  3970. for (i = tmp->includes; i; i = i->next) {
  3971. if (include_valid(i)) {
  3972. if ((e = pbx_find_extension(NULL, bypass, q, i->rname, exten, priority, label, callerid, action)))
  3973. return e;
  3974. if (q->swo)
  3975. return NULL;
  3976. }
  3977. }
  3978. return NULL;
  3979. }
  3980. struct ast_exten *localized_find_extension(struct ast_context *bypass,
  3981. struct pbx_find_info *q,
  3982. const char *context,
  3983. const char *exten,
  3984. int priority,
  3985. const char *label,
  3986. const char *callerid,
  3987. enum ext_match_t action);
  3988. struct ast_exten *localized_find_extension(struct ast_context *bypass,
  3989. struct pbx_find_info *q,
  3990. const char *context,
  3991. const char *exten,
  3992. int priority,
  3993. const char *label,
  3994. const char *callerid,
  3995. enum ext_match_t action)
  3996. {
  3997. return pbx_find_extension(NULL, bypass, q, context, exten, priority, label, callerid, action);
  3998. }
  3999. static struct ast_context *contexts;
  4000. AST_RWLOCK_DEFINE_STATIC(conlock); /*!< Lock for the ast_context list */
  4001. static const char *ast_get_context_name(struct ast_context *con);
  4002. static const char *ast_get_context_name(struct ast_context *con)
  4003. {
  4004. return con ? con->name : NULL;
  4005. }
  4006. /*
  4007. * errno values
  4008. * ENOMEM - out of memory
  4009. * EBUSY - can't lock
  4010. * EEXIST - already included
  4011. * EINVAL - there is no existence of context for inclusion
  4012. */
  4013. static int ast_context_add_include2(struct ast_context *con, const char *value,
  4014. const char *registrar);
  4015. static int ast_context_add_include2(struct ast_context *con, const char *value,
  4016. const char *registrar)
  4017. {
  4018. struct ast_include *new_include;
  4019. char *c;
  4020. struct ast_include *i, *il = NULL; /* include, include_last */
  4021. int length;
  4022. char *p;
  4023. length = sizeof(struct ast_include);
  4024. length += 2 * (strlen(value) + 1);
  4025. /* allocate new include structure ... */
  4026. if (!(new_include = ast_calloc(1, length)))
  4027. return -1;
  4028. /* Fill in this structure. Use 'p' for assignments, as the fields
  4029. * in the structure are 'const char *'
  4030. */
  4031. p = new_include->stuff;
  4032. new_include->name = p;
  4033. strcpy(p, value);
  4034. p += strlen(value) + 1;
  4035. new_include->rname = p;
  4036. strcpy(p, value);
  4037. /* Strip off timing info, and process if it is there */
  4038. if ( (c = strchr(p, '|')) ) {
  4039. *c++ = '\0';
  4040. new_include->hastime = ast_build_timing(&(new_include->timing), c);
  4041. }
  4042. new_include->next = NULL;
  4043. new_include->registrar = registrar;
  4044. /* ... go to last include and check if context is already included too... */
  4045. for (i = con->includes; i; i = i->next) {
  4046. if (!strcasecmp(i->name, new_include->name)) {
  4047. free(new_include);
  4048. errno = EEXIST;
  4049. return -1;
  4050. }
  4051. il = i;
  4052. }
  4053. /* ... include new context into context list, unlock, return */
  4054. if (il)
  4055. il->next = new_include;
  4056. else
  4057. con->includes = new_include;
  4058. if (option_verbose > 2)
  4059. ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
  4060. return 0;
  4061. }
  4062. int localized_context_add_include2(struct ast_context *con, const char *value,
  4063. const char *registrar);
  4064. int localized_context_add_include2(struct ast_context *con, const char *value,
  4065. const char *registrar)
  4066. {
  4067. return ast_context_add_include2(con, value, registrar);
  4068. }
  4069. static int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar);
  4070. static int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar)
  4071. {
  4072. struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
  4073. int length;
  4074. length = sizeof(struct ast_ignorepat);
  4075. length += strlen(value) + 1;
  4076. if (!(ignorepat = ast_calloc(1, length)))
  4077. return -1;
  4078. /* The cast to char * is because we need to write the initial value.
  4079. * The field is not supposed to be modified otherwise
  4080. */
  4081. strcpy((char *)ignorepat->pattern, value);
  4082. ignorepat->next = NULL;
  4083. ignorepat->registrar = registrar;
  4084. for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
  4085. ignorepatl = ignorepatc;
  4086. if (!strcasecmp(ignorepatc->pattern, value)) {
  4087. /* Already there */
  4088. errno = EEXIST;
  4089. return -1;
  4090. }
  4091. }
  4092. if (ignorepatl)
  4093. ignorepatl->next = ignorepat;
  4094. else
  4095. con->ignorepats = ignorepat;
  4096. return 0;
  4097. }
  4098. int localized_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar);
  4099. int localized_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar)
  4100. {
  4101. return ast_context_add_ignorepat2(con, value, registrar);
  4102. }
  4103. /*
  4104. * Lock context list functions ...
  4105. */
  4106. static int ast_wrlock_contexts(void)
  4107. {
  4108. return ast_rwlock_wrlock(&conlock);
  4109. }
  4110. static int ast_unlock_contexts(void)
  4111. {
  4112. return ast_rwlock_unlock(&conlock);
  4113. }
  4114. static int ast_wrlock_context(struct ast_context *con)
  4115. {
  4116. return ast_rwlock_wrlock(&con->lock);
  4117. }
  4118. static int ast_unlock_context(struct ast_context *con)
  4119. {
  4120. return ast_rwlock_unlock(&con->lock);
  4121. }
  4122. /*
  4123. * errno values
  4124. * ENOMEM - out of memory
  4125. * EBUSY - can't lock
  4126. * EEXIST - already included
  4127. * EINVAL - there is no existence of context for inclusion
  4128. */
  4129. static int ast_context_add_switch2(struct ast_context *con, const char *value,
  4130. const char *data, int eval, const char *registrar);
  4131. static int ast_context_add_switch2(struct ast_context *con, const char *value,
  4132. const char *data, int eval, const char *registrar)
  4133. {
  4134. struct ast_sw *new_sw;
  4135. struct ast_sw *i;
  4136. int length;
  4137. char *p;
  4138. length = sizeof(struct ast_sw);
  4139. length += strlen(value) + 1;
  4140. if (data)
  4141. length += strlen(data);
  4142. length++;
  4143. if (eval) {
  4144. /* Create buffer for evaluation of variables */
  4145. length += SWITCH_DATA_LENGTH;
  4146. length++;
  4147. }
  4148. /* allocate new sw structure ... */
  4149. if (!(new_sw = ast_calloc(1, length)))
  4150. return -1;
  4151. /* ... fill in this structure ... */
  4152. p = new_sw->stuff;
  4153. new_sw->name = p;
  4154. strcpy(new_sw->name, value);
  4155. p += strlen(value) + 1;
  4156. new_sw->data = p;
  4157. if (data) {
  4158. strcpy(new_sw->data, data);
  4159. p += strlen(data) + 1;
  4160. } else {
  4161. strcpy(new_sw->data, "");
  4162. p++;
  4163. }
  4164. if (eval)
  4165. new_sw->tmpdata = p;
  4166. new_sw->eval = eval;
  4167. new_sw->registrar = registrar;
  4168. /* ... go to last sw and check if context is already swd too... */
  4169. AST_LIST_TRAVERSE(&con->alts, i, list) {
  4170. if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
  4171. free(new_sw);
  4172. errno = EEXIST;
  4173. return -1;
  4174. }
  4175. }
  4176. /* ... sw new context into context list, unlock, return */
  4177. AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
  4178. if (option_verbose > 2)
  4179. ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
  4180. return 0;
  4181. }
  4182. int localized_context_add_switch2(struct ast_context *con, const char *value,
  4183. const char *data, int eval, const char *registrar);
  4184. int localized_context_add_switch2(struct ast_context *con, const char *value,
  4185. const char *data, int eval, const char *registrar)
  4186. {
  4187. return ast_context_add_switch2(con, value, data, eval, registrar);
  4188. }
  4189. static struct ast_context *__ast_context_create(struct ast_context **extcontexts, const char *name, const char *registrar, int existsokay)
  4190. {
  4191. struct ast_context *tmp, **loc_contexts;
  4192. int length = sizeof(struct ast_context) + strlen(name) + 1;
  4193. if (!extcontexts) {
  4194. ast_wrlock_contexts();
  4195. loc_contexts = &contexts;
  4196. } else
  4197. loc_contexts = extcontexts;
  4198. for (tmp = *loc_contexts; tmp; tmp = tmp->next) {
  4199. if (!strcasecmp(tmp->name, name)) {
  4200. if (!existsokay) {
  4201. ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name);
  4202. tmp = NULL;
  4203. }
  4204. if (!extcontexts)
  4205. ast_unlock_contexts();
  4206. return tmp;
  4207. }
  4208. }
  4209. if ((tmp = ast_calloc(1, length))) {
  4210. ast_rwlock_init(&tmp->lock);
  4211. ast_mutex_init(&tmp->macrolock);
  4212. strcpy(tmp->name, name);
  4213. tmp->root = NULL;
  4214. tmp->registrar = registrar;
  4215. tmp->next = *loc_contexts;
  4216. tmp->includes = NULL;
  4217. tmp->ignorepats = NULL;
  4218. *loc_contexts = tmp;
  4219. if (option_debug)
  4220. ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name);
  4221. if (option_verbose > 2)
  4222. ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name);
  4223. }
  4224. if (!extcontexts)
  4225. ast_unlock_contexts();
  4226. return tmp;
  4227. }
  4228. /*! \brief
  4229. * Main interface to add extensions to the list for out context.
  4230. *
  4231. * We sort extensions in order of matching preference, so that we can
  4232. * stop the search as soon as we find a suitable match.
  4233. * This ordering also takes care of wildcards such as '.' (meaning
  4234. * "one or more of any character") and '!' (which is 'earlymatch',
  4235. * meaning "zero or more of any character" but also impacts the
  4236. * return value from CANMATCH and EARLYMATCH.
  4237. *
  4238. * The extension match rules defined in the devmeeting 2006.05.05 are
  4239. * quite simple: WE SELECT THE LONGEST MATCH.
  4240. * In detail, "longest" means the number of matched characters in
  4241. * the extension. In case of ties (e.g. _XXX and 333) in the length
  4242. * of a pattern, we give priority to entries with the smallest cardinality
  4243. * (e.g, [5-9] comes before [2-8] before the former has only 5 elements,
  4244. * while the latter has 7, etc.
  4245. * In case of same cardinality, the first element in the range counts.
  4246. * If we still have a tie, any final '!' will make this as a possibly
  4247. * less specific pattern.
  4248. *
  4249. * EBUSY - can't lock
  4250. * EEXIST - extension with the same priority exist and no replace is set
  4251. *
  4252. */
  4253. static int ast_add_extension2(struct ast_context *con,
  4254. int replace, const char *extension, int priority, const char *label, const char *callerid,
  4255. const char *application, void *data, void (*datad)(void *),
  4256. const char *registrar)
  4257. {
  4258. /*
  4259. * Sort extensions (or patterns) according to the rules indicated above.
  4260. * These are implemented by the function ext_cmp()).
  4261. * All priorities for the same ext/pattern/cid are kept in a list,
  4262. * using the 'peer' field as a link field..
  4263. */
  4264. struct ast_exten *tmp, *e, *el = NULL;
  4265. int res;
  4266. int length;
  4267. char *p;
  4268. /* if we are adding a hint, and there are global variables, and the hint
  4269. contains variable references, then expand them --- NOT In this situation!!!
  4270. */
  4271. length = sizeof(struct ast_exten);
  4272. length += strlen(extension) + 1;
  4273. length += strlen(application) + 1;
  4274. if (label)
  4275. length += strlen(label) + 1;
  4276. if (callerid)
  4277. length += strlen(callerid) + 1;
  4278. else
  4279. length ++; /* just the '\0' */
  4280. /* Be optimistic: Build the extension structure first */
  4281. if (datad == NULL)
  4282. datad = null_datad;
  4283. if (!(tmp = ast_calloc(1, length)))
  4284. return -1;
  4285. /* use p as dst in assignments, as the fields are const char * */
  4286. p = tmp->stuff;
  4287. if (label) {
  4288. tmp->label = p;
  4289. strcpy(p, label);
  4290. p += strlen(label) + 1;
  4291. }
  4292. tmp->exten = p;
  4293. p += ext_strncpy(p, extension, strlen(extension) + 1) + 1;
  4294. tmp->priority = priority;
  4295. tmp->cidmatch = p; /* but use p for assignments below */
  4296. if (callerid) {
  4297. p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1;
  4298. tmp->matchcid = 1;
  4299. } else {
  4300. *p++ = '\0';
  4301. tmp->matchcid = 0;
  4302. }
  4303. tmp->app = p;
  4304. strcpy(p, application);
  4305. tmp->parent = con;
  4306. tmp->data = data;
  4307. tmp->datad = datad;
  4308. tmp->registrar = registrar;
  4309. res = 0; /* some compilers will think it is uninitialized otherwise */
  4310. for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */
  4311. res = ext_cmp(e->exten, extension);
  4312. if (res == 0) { /* extension match, now look at cidmatch */
  4313. if (!e->matchcid && !tmp->matchcid)
  4314. res = 0;
  4315. else if (tmp->matchcid && !e->matchcid)
  4316. res = 1;
  4317. else if (e->matchcid && !tmp->matchcid)
  4318. res = -1;
  4319. else
  4320. res = strcasecmp(e->cidmatch, tmp->cidmatch);
  4321. }
  4322. if (res >= 0)
  4323. break;
  4324. }
  4325. if (e && res == 0) { /* exact match, insert in the pri chain */
  4326. res = add_pri(con, tmp, el, e, replace);
  4327. if (res < 0) {
  4328. errno = EEXIST; /* XXX do we care ? */
  4329. return 0; /* XXX should we return -1 maybe ? */
  4330. }
  4331. } else {
  4332. /*
  4333. * not an exact match, this is the first entry with this pattern,
  4334. * so insert in the main list right before 'e' (if any)
  4335. */
  4336. tmp->next = e;
  4337. if (el)
  4338. el->next = tmp;
  4339. else
  4340. con->root = tmp;
  4341. if (tmp->priority == PRIORITY_HINT)
  4342. ast_add_hint(tmp);
  4343. }
  4344. if (option_debug) {
  4345. if (tmp->matchcid) {
  4346. ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n",
  4347. tmp->exten, tmp->priority, tmp->cidmatch, con->name);
  4348. } else {
  4349. ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n",
  4350. tmp->exten, tmp->priority, con->name);
  4351. }
  4352. }
  4353. if (option_verbose > 2) {
  4354. if (tmp->matchcid) {
  4355. ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n",
  4356. tmp->exten, tmp->priority, tmp->cidmatch, con->name);
  4357. } else {
  4358. ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n",
  4359. tmp->exten, tmp->priority, con->name);
  4360. }
  4361. }
  4362. return 0;
  4363. }
  4364. int localized_add_extension2(struct ast_context *con,
  4365. int replace, const char *extension, int priority, const char *label, const char *callerid,
  4366. const char *application, void *data, void (*datad)(void *),
  4367. const char *registrar);
  4368. int localized_add_extension2(struct ast_context *con,
  4369. int replace, const char *extension, int priority, const char *label, const char *callerid,
  4370. const char *application, void *data, void (*datad)(void *),
  4371. const char *registrar)
  4372. {
  4373. return ast_add_extension2(con, replace, extension, priority, label, callerid, application, data, datad, registrar);
  4374. }
  4375. /*! \brief The return value depends on the action:
  4376. *
  4377. * E_MATCH, E_CANMATCH, E_MATCHMORE require a real match,
  4378. * and return 0 on failure, -1 on match;
  4379. * E_FINDLABEL maps the label to a priority, and returns
  4380. * the priority on success, ... XXX
  4381. * E_SPAWN, spawn an application,
  4382. * and return 0 on success, -1 on failure.
  4383. */
  4384. static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con,
  4385. const char *context, const char *exten, int priority,
  4386. const char *label, const char *callerid, enum ext_match_t action)
  4387. {
  4388. struct ast_exten *e;
  4389. int res;
  4390. struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
  4391. int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE);
  4392. e = pbx_find_extension(NULL, con, &q, context, exten, priority, label, callerid, action);
  4393. if (e) {
  4394. if (matching_action) {
  4395. return -1; /* success, we found it */
  4396. } else if (action == E_FINDLABEL) { /* map the label to a priority */
  4397. res = e->priority;
  4398. return res; /* the priority we were looking for */
  4399. } else { /* spawn */
  4400. /* NOT!!!!! */
  4401. return 0;
  4402. }
  4403. } else if (q.swo) { /* not found here, but in another switch */
  4404. if (matching_action)
  4405. return -1;
  4406. else {
  4407. if (!q.swo->exec) {
  4408. ast_log(LOG_WARNING, "No execution engine for switch %s\n", q.swo->name);
  4409. res = -1;
  4410. }
  4411. return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data);
  4412. }
  4413. } else { /* not found anywhere, see what happened */
  4414. switch (q.status) {
  4415. case STATUS_NO_CONTEXT:
  4416. if (!matching_action)
  4417. ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context);
  4418. break;
  4419. case STATUS_NO_EXTENSION:
  4420. if (!matching_action)
  4421. ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context);
  4422. break;
  4423. case STATUS_NO_PRIORITY:
  4424. if (!matching_action)
  4425. ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context);
  4426. break;
  4427. case STATUS_NO_LABEL:
  4428. if (context)
  4429. ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, context);
  4430. break;
  4431. default:
  4432. if (option_debug)
  4433. ast_log(LOG_DEBUG, "Shouldn't happen!\n");
  4434. }
  4435. return (matching_action) ? 0 : -1;
  4436. }
  4437. }
  4438. static int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid);
  4439. static int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
  4440. {
  4441. return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL);
  4442. }
  4443. static struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts, void *tab, const char *name, const char *registrar)
  4444. {
  4445. return __ast_context_create(extcontexts, name, registrar, 1);
  4446. }
  4447. struct ast_context *localized_context_find_or_create(struct ast_context **extcontexts, void *tab, const char *name, const char *registrar);
  4448. struct ast_context *localized_context_find_or_create(struct ast_context **extcontexts, void *tab, const char *name, const char *registrar)
  4449. {
  4450. return __ast_context_create(extcontexts, name, registrar, 1);
  4451. }
  4452. /* chopped this one off at the knees */
  4453. static int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
  4454. {
  4455. ast_log(LOG_ERROR, "Function %s not registered\n", function);
  4456. return -1;
  4457. }
  4458. /*! \brief extract offset:length from variable name.
  4459. * Returns 1 if there is a offset:length part, which is
  4460. * trimmed off (values go into variables)
  4461. */
  4462. static int parse_variable_name(char *var, int *offset, int *length, int *isfunc)
  4463. {
  4464. int parens=0;
  4465. *offset = 0;
  4466. *length = INT_MAX;
  4467. *isfunc = 0;
  4468. for (; *var; var++) {
  4469. if (*var == '(') {
  4470. (*isfunc)++;
  4471. parens++;
  4472. } else if (*var == ')') {
  4473. parens--;
  4474. } else if (*var == ':' && parens == 0) {
  4475. *var++ = '\0';
  4476. sscanf(var, "%30d:%30d", offset, length);
  4477. return 1; /* offset:length valid */
  4478. }
  4479. }
  4480. return 0;
  4481. }
  4482. static const char *ast_var_value(const struct ast_var_t *var)
  4483. {
  4484. return (var ? var->value : NULL);
  4485. }
  4486. /*! \brief takes a substring. It is ok to call with value == workspace.
  4487. *
  4488. * offset < 0 means start from the end of the string and set the beginning
  4489. * to be that many characters back.
  4490. * length is the length of the substring. A value less than 0 means to leave
  4491. * that many off the end.
  4492. * Always return a copy in workspace.
  4493. */
  4494. static char *substring(const char *value, int offset, int length, char *workspace, size_t workspace_len)
  4495. {
  4496. char *ret = workspace;
  4497. int lr; /* length of the input string after the copy */
  4498. ast_copy_string(workspace, value, workspace_len); /* always make a copy */
  4499. lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */
  4500. /* Quick check if no need to do anything */
  4501. if (offset == 0 && length >= lr) /* take the whole string */
  4502. return ret;
  4503. if (offset < 0) { /* translate negative offset into positive ones */
  4504. offset = lr + offset;
  4505. if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */
  4506. offset = 0;
  4507. }
  4508. /* too large offset result in empty string so we know what to return */
  4509. if (offset >= lr)
  4510. return ret + lr; /* the final '\0' */
  4511. ret += offset; /* move to the start position */
  4512. if (length >= 0 && length < lr - offset) /* truncate if necessary */
  4513. ret[length] = '\0';
  4514. else if (length < 0) {
  4515. if (lr > offset - length) /* After we remove from the front and from the rear, is there anything left? */
  4516. ret[lr + length - offset] = '\0';
  4517. else
  4518. ret[0] = '\0';
  4519. }
  4520. return ret;
  4521. }
  4522. /*! \brief Support for Asterisk built-in variables in the dialplan
  4523. \note See also
  4524. - \ref AstVar Channel variables
  4525. - \ref AstCauses The HANGUPCAUSE variable
  4526. */
  4527. static void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
  4528. {
  4529. const char not_found = '\0';
  4530. char *tmpvar;
  4531. const char *s; /* the result */
  4532. int offset, length;
  4533. int i, need_substring;
  4534. struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */
  4535. /*
  4536. * Make a copy of var because parse_variable_name() modifies the string.
  4537. * Then if called directly, we might need to run substring() on the result;
  4538. * remember this for later in 'need_substring', 'offset' and 'length'
  4539. */
  4540. tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */
  4541. need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */);
  4542. /*
  4543. * Look first into predefined variables, then into variable lists.
  4544. * Variable 's' points to the result, according to the following rules:
  4545. * s == &not_found (set at the beginning) means that we did not find a
  4546. * matching variable and need to look into more places.
  4547. * If s != &not_found, s is a valid result string as follows:
  4548. * s = NULL if the variable does not have a value;
  4549. * you typically do this when looking for an unset predefined variable.
  4550. * s = workspace if the result has been assembled there;
  4551. * typically done when the result is built e.g. with an snprintf(),
  4552. * so we don't need to do an additional copy.
  4553. * s != workspace in case we have a string, that needs to be copied
  4554. * (the ast_copy_string is done once for all at the end).
  4555. * Typically done when the result is already available in some string.
  4556. */
  4557. s = &not_found; /* default value */
  4558. if (s == &not_found) { /* look for more */
  4559. if (!strcmp(var, "EPOCH")) {
  4560. snprintf(workspace, workspacelen, "%u",(int)time(NULL));
  4561. }
  4562. s = workspace;
  4563. }
  4564. /* if not found, look into chanvars or global vars */
  4565. for (i = 0; s == &not_found && i < (sizeof(places) / sizeof(places[0])); i++) {
  4566. struct ast_var_t *variables;
  4567. if (!places[i])
  4568. continue;
  4569. if (places[i] == &globals)
  4570. ast_rwlock_rdlock(&globalslock);
  4571. AST_LIST_TRAVERSE(places[i], variables, entries) {
  4572. if (strcasecmp(ast_var_name(variables), var)==0) {
  4573. s = ast_var_value(variables);
  4574. break;
  4575. }
  4576. }
  4577. if (places[i] == &globals)
  4578. ast_rwlock_unlock(&globalslock);
  4579. }
  4580. if (s == &not_found || s == NULL)
  4581. *ret = NULL;
  4582. else {
  4583. if (s != workspace)
  4584. ast_copy_string(workspace, s, workspacelen);
  4585. *ret = workspace;
  4586. if (need_substring)
  4587. *ret = substring(*ret, offset, length, workspace, workspacelen);
  4588. }
  4589. }
  4590. static void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count)
  4591. {
  4592. /* Substitutes variables into cp2, based on string cp1, and assuming cp2 to be
  4593. zero-filled */
  4594. char *cp4;
  4595. const char *tmp, *whereweare;
  4596. int length, offset, offset2, isfunction;
  4597. char *workspace = NULL;
  4598. char *ltmp = NULL, *var = NULL;
  4599. char *nextvar, *nextexp, *nextthing;
  4600. char *vars, *vare;
  4601. int pos, brackets, needsub, len;
  4602. *cp2 = 0; /* just in case there's nothing to do */
  4603. whereweare=tmp=cp1;
  4604. while (!ast_strlen_zero(whereweare) && count) {
  4605. /* Assume we're copying the whole remaining string */
  4606. pos = strlen(whereweare);
  4607. nextvar = NULL;
  4608. nextexp = NULL;
  4609. nextthing = strchr(whereweare, '$');
  4610. if (nextthing) {
  4611. switch (nextthing[1]) {
  4612. case '{':
  4613. nextvar = nextthing;
  4614. pos = nextvar - whereweare;
  4615. break;
  4616. case '[':
  4617. nextexp = nextthing;
  4618. pos = nextexp - whereweare;
  4619. break;
  4620. }
  4621. }
  4622. if (pos) {
  4623. /* Can't copy more than 'count' bytes */
  4624. if (pos > count)
  4625. pos = count;
  4626. /* Copy that many bytes */
  4627. memcpy(cp2, whereweare, pos);
  4628. count -= pos;
  4629. cp2 += pos;
  4630. whereweare += pos;
  4631. *cp2 = 0;
  4632. }
  4633. if (nextvar) {
  4634. /* We have a variable. Find the start and end, and determine
  4635. if we are going to have to recursively call ourselves on the
  4636. contents */
  4637. vars = vare = nextvar + 2;
  4638. brackets = 1;
  4639. needsub = 0;
  4640. /* Find the end of it */
  4641. while (brackets && *vare) {
  4642. if ((vare[0] == '$') && (vare[1] == '{')) {
  4643. needsub++;
  4644. } else if (vare[0] == '{') {
  4645. brackets++;
  4646. } else if (vare[0] == '}') {
  4647. brackets--;
  4648. } else if ((vare[0] == '$') && (vare[1] == '['))
  4649. needsub++;
  4650. vare++;
  4651. }
  4652. if (brackets)
  4653. ast_log(LOG_NOTICE, "Error in extension logic (missing '}' in '%s')\n", cp1);
  4654. len = vare - vars - 1;
  4655. /* Skip totally over variable string */
  4656. whereweare += (len + 3);
  4657. if (!var)
  4658. var = alloca(VAR_BUF_SIZE);
  4659. /* Store variable name (and truncate) */
  4660. ast_copy_string(var, vars, len + 1);
  4661. /* Substitute if necessary */
  4662. if (needsub) {
  4663. if (!ltmp)
  4664. ltmp = alloca(VAR_BUF_SIZE);
  4665. memset(ltmp, 0, VAR_BUF_SIZE);
  4666. pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1);
  4667. vars = ltmp;
  4668. } else {
  4669. vars = var;
  4670. }
  4671. if (!workspace)
  4672. workspace = alloca(VAR_BUF_SIZE);
  4673. workspace[0] = '\0';
  4674. parse_variable_name(vars, &offset, &offset2, &isfunction);
  4675. if (isfunction) {
  4676. /* Evaluate function */
  4677. cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
  4678. if (option_debug)
  4679. ast_log(LOG_DEBUG, "Function result is '%s'\n", cp4 ? cp4 : "(null)");
  4680. } else {
  4681. /* Retrieve variable value */
  4682. pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp);
  4683. }
  4684. if (cp4) {
  4685. cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE);
  4686. length = strlen(cp4);
  4687. if (length > count)
  4688. length = count;
  4689. memcpy(cp2, cp4, length);
  4690. count -= length;
  4691. cp2 += length;
  4692. *cp2 = 0;
  4693. }
  4694. } else if (nextexp) {
  4695. /* We have an expression. Find the start and end, and determine
  4696. if we are going to have to recursively call ourselves on the
  4697. contents */
  4698. vars = vare = nextexp + 2;
  4699. brackets = 1;
  4700. needsub = 0;
  4701. /* Find the end of it */
  4702. while (brackets && *vare) {
  4703. if ((vare[0] == '$') && (vare[1] == '[')) {
  4704. needsub++;
  4705. brackets++;
  4706. vare++;
  4707. } else if (vare[0] == '[') {
  4708. brackets++;
  4709. } else if (vare[0] == ']') {
  4710. brackets--;
  4711. } else if ((vare[0] == '$') && (vare[1] == '{')) {
  4712. needsub++;
  4713. vare++;
  4714. }
  4715. vare++;
  4716. }
  4717. if (brackets)
  4718. ast_log(LOG_NOTICE, "Error in extension logic (missing ']')\n");
  4719. len = vare - vars - 1;
  4720. /* Skip totally over expression */
  4721. whereweare += (len + 3);
  4722. if (!var)
  4723. var = alloca(VAR_BUF_SIZE);
  4724. /* Store variable name (and truncate) */
  4725. ast_copy_string(var, vars, len + 1);
  4726. /* Substitute if necessary */
  4727. if (needsub) {
  4728. if (!ltmp)
  4729. ltmp = alloca(VAR_BUF_SIZE);
  4730. memset(ltmp, 0, VAR_BUF_SIZE);
  4731. pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1);
  4732. vars = ltmp;
  4733. } else {
  4734. vars = var;
  4735. }
  4736. length = ast_expr(vars, cp2, count, NULL);
  4737. if (length) {
  4738. if (option_debug)
  4739. ast_log(LOG_DEBUG, "Expression result is '%s'\n", cp2);
  4740. count -= length;
  4741. cp2 += length;
  4742. *cp2 = 0;
  4743. }
  4744. } else
  4745. break;
  4746. }
  4747. }
  4748. static void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
  4749. {
  4750. pbx_substitute_variables_helper_full(c, NULL, cp1, cp2, count);
  4751. }
  4752. static int pbx_load_config(const char *config_file);
  4753. static int pbx_load_config(const char *config_file)
  4754. {
  4755. struct ast_config *cfg;
  4756. char *end;
  4757. char *label;
  4758. char realvalue[256];
  4759. int lastpri = -2;
  4760. struct ast_context *con;
  4761. struct ast_variable *v;
  4762. const char *cxt;
  4763. const char *aft;
  4764. cfg = localized_config_load(config_file);
  4765. if (!cfg)
  4766. return 0;
  4767. /* Use existing config to populate the PBX table */
  4768. static_config = ast_true(ast_variable_retrieve(cfg, "general", "static"));
  4769. write_protect_config = ast_true(ast_variable_retrieve(cfg, "general", "writeprotect"));
  4770. if ((aft = ast_variable_retrieve(cfg, "general", "autofallthrough")))
  4771. autofallthrough_config = ast_true(aft);
  4772. clearglobalvars_config = ast_true(ast_variable_retrieve(cfg, "general", "clearglobalvars"));
  4773. if ((cxt = ast_variable_retrieve(cfg, "general", "userscontext")))
  4774. ast_copy_string(userscontext, cxt, sizeof(userscontext));
  4775. else
  4776. ast_copy_string(userscontext, "default", sizeof(userscontext));
  4777. for (v = ast_variable_browse(cfg, "globals"); v; v = v->next) {
  4778. memset(realvalue, 0, sizeof(realvalue));
  4779. pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
  4780. pbx_builtin_setvar_helper(NULL, v->name, realvalue);
  4781. }
  4782. for (cxt = NULL; (cxt = ast_category_browse(cfg, cxt)); ) {
  4783. /* All categories but "general" or "globals" are considered contexts */
  4784. if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals"))
  4785. continue;
  4786. con=ast_context_find_or_create(&local_contexts,NULL,cxt, global_registrar);
  4787. if (con == NULL)
  4788. continue;
  4789. for (v = ast_variable_browse(cfg, cxt); v; v = v->next) {
  4790. if (!strcasecmp(v->name, "exten")) {
  4791. char *tc = ast_strdup(v->value);
  4792. if (tc) {
  4793. int ipri = -2;
  4794. char realext[256]="";
  4795. char *plus, *firstp, *firstc;
  4796. char *pri, *appl, *data, *cidmatch;
  4797. char *stringp = tc;
  4798. char *ext = strsep(&stringp, ",");
  4799. if (!ext)
  4800. ext="";
  4801. pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1);
  4802. cidmatch = strchr(realext, '/');
  4803. if (cidmatch) {
  4804. *cidmatch++ = '\0';
  4805. ast_shrink_phone_number(cidmatch);
  4806. }
  4807. pri = strsep(&stringp, ",");
  4808. if (!pri)
  4809. pri="";
  4810. label = strchr(pri, '(');
  4811. if (label) {
  4812. *label++ = '\0';
  4813. end = strchr(label, ')');
  4814. if (end)
  4815. *end = '\0';
  4816. else
  4817. ast_log(LOG_WARNING, "Label missing trailing ')' at line %d\n", v->lineno);
  4818. }
  4819. plus = strchr(pri, '+');
  4820. if (plus)
  4821. *plus++ = '\0';
  4822. if (!strcmp(pri,"hint"))
  4823. ipri=PRIORITY_HINT;
  4824. else if (!strcmp(pri, "next") || !strcmp(pri, "n")) {
  4825. if (lastpri > -2)
  4826. ipri = lastpri + 1;
  4827. else
  4828. ast_log(LOG_WARNING, "Can't use 'next' priority on the first entry!\n");
  4829. } else if (!strcmp(pri, "same") || !strcmp(pri, "s")) {
  4830. if (lastpri > -2)
  4831. ipri = lastpri;
  4832. else
  4833. ast_log(LOG_WARNING, "Can't use 'same' priority on the first entry!\n");
  4834. } else if (sscanf(pri, "%30d", &ipri) != 1 &&
  4835. (ipri = ast_findlabel_extension2(NULL, con, realext, pri, cidmatch)) < 1) {
  4836. ast_log(LOG_WARNING, "Invalid priority/label '%s' at line %d\n", pri, v->lineno);
  4837. ipri = 0;
  4838. }
  4839. appl = S_OR(stringp, "");
  4840. /* Find the first occurrence of either '(' or ',' */
  4841. firstc = strchr(appl, ',');
  4842. firstp = strchr(appl, '(');
  4843. if (firstc && (!firstp || firstc < firstp)) {
  4844. /* comma found, no parenthesis */
  4845. /* or both found, but comma found first */
  4846. appl = strsep(&stringp, ",");
  4847. data = stringp;
  4848. } else if (!firstc && !firstp) {
  4849. /* Neither found */
  4850. data = "";
  4851. } else {
  4852. /* Final remaining case is parenthesis found first */
  4853. appl = strsep(&stringp, "(");
  4854. data = stringp;
  4855. end = strrchr(data, ')');
  4856. if ((end = strrchr(data, ')'))) {
  4857. *end = '\0';
  4858. } else {
  4859. ast_log(LOG_WARNING, "No closing parenthesis found? '%s(%s'\n", appl, data);
  4860. }
  4861. ast_process_quotes_and_slashes(data, ',', '|');
  4862. }
  4863. if (!data)
  4864. data="";
  4865. appl = ast_skip_blanks(appl);
  4866. if (ipri) {
  4867. if (plus)
  4868. ipri += atoi(plus);
  4869. lastpri = ipri;
  4870. if (!ast_opt_dont_warn && !strcmp(realext, "_."))
  4871. ast_log(LOG_WARNING, "The use of '_.' for an extension is strongly discouraged and can have unexpected behavior. Please use '_X.' instead at line %d\n", v->lineno);
  4872. if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, strdup(data), ast_free_ptr, global_registrar)) {
  4873. ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno);
  4874. }
  4875. }
  4876. free(tc);
  4877. }
  4878. } else if (!strcasecmp(v->name, "include")) {
  4879. memset(realvalue, 0, sizeof(realvalue));
  4880. pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
  4881. if (ast_context_add_include2(con, realvalue, global_registrar))
  4882. ast_log(LOG_WARNING, "Unable to include context '%s' in context '%s'\n", v->value, cxt);
  4883. } else if (!strcasecmp(v->name, "ignorepat")) {
  4884. memset(realvalue, 0, sizeof(realvalue));
  4885. pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
  4886. if (ast_context_add_ignorepat2(con, realvalue, global_registrar))
  4887. ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s'\n", v->value, cxt);
  4888. } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) {
  4889. char *stringp= realvalue;
  4890. char *appl, *data;
  4891. memset(realvalue, 0, sizeof(realvalue));
  4892. if (!strcasecmp(v->name, "switch"))
  4893. pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
  4894. else
  4895. ast_copy_string(realvalue, v->value, sizeof(realvalue));
  4896. appl = strsep(&stringp, "/");
  4897. data = strsep(&stringp, ""); /* XXX what for ? */
  4898. if (!data)
  4899. data = "";
  4900. if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), global_registrar))
  4901. ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s'\n", v->value, cxt);
  4902. } else {
  4903. ast_log(LOG_WARNING, "==!!== Unknown directive: %s at line %d -- IGNORING!!!\n", v->name, v->lineno);
  4904. }
  4905. }
  4906. }
  4907. ast_config_destroy(cfg);
  4908. return 1;
  4909. }
  4910. static void __ast_context_destroy(struct ast_context *con, const char *registrar)
  4911. {
  4912. struct ast_context *tmp, *tmpl=NULL;
  4913. struct ast_include *tmpi;
  4914. struct ast_sw *sw;
  4915. struct ast_exten *e, *el, *en;
  4916. struct ast_ignorepat *ipi;
  4917. for (tmp = contexts; tmp; ) {
  4918. struct ast_context *next; /* next starting point */
  4919. for (; tmp; tmpl = tmp, tmp = tmp->next) {
  4920. if (option_debug)
  4921. ast_log(LOG_DEBUG, "check ctx %s %s\n", tmp->name, tmp->registrar);
  4922. if ( (!registrar || !strcasecmp(registrar, tmp->registrar)) &&
  4923. (!con || !strcasecmp(tmp->name, con->name)) )
  4924. break; /* found it */
  4925. }
  4926. if (!tmp) /* not found, we are done */
  4927. break;
  4928. ast_wrlock_context(tmp);
  4929. if (option_debug)
  4930. ast_log(LOG_DEBUG, "delete ctx %s %s\n", tmp->name, tmp->registrar);
  4931. next = tmp->next;
  4932. if (tmpl)
  4933. tmpl->next = next;
  4934. else
  4935. contexts = next;
  4936. /* Okay, now we're safe to let it go -- in a sense, we were
  4937. ready to let it go as soon as we locked it. */
  4938. ast_unlock_context(tmp);
  4939. for (tmpi = tmp->includes; tmpi; ) { /* Free includes */
  4940. struct ast_include *tmpil = tmpi;
  4941. tmpi = tmpi->next;
  4942. free(tmpil);
  4943. }
  4944. for (ipi = tmp->ignorepats; ipi; ) { /* Free ignorepats */
  4945. struct ast_ignorepat *ipl = ipi;
  4946. ipi = ipi->next;
  4947. free(ipl);
  4948. }
  4949. while ((sw = AST_LIST_REMOVE_HEAD(&tmp->alts, list)))
  4950. free(sw);
  4951. for (e = tmp->root; e;) {
  4952. for (en = e->peer; en;) {
  4953. el = en;
  4954. en = en->peer;
  4955. destroy_exten(el);
  4956. }
  4957. el = e;
  4958. e = e->next;
  4959. destroy_exten(el);
  4960. }
  4961. ast_rwlock_destroy(&tmp->lock);
  4962. free(tmp);
  4963. /* if we have a specific match, we are done, otherwise continue */
  4964. tmp = con ? NULL : next;
  4965. }
  4966. }
  4967. void localized_context_destroy(struct ast_context *con, const char *registrar);
  4968. void localized_context_destroy(struct ast_context *con, const char *registrar)
  4969. {
  4970. ast_wrlock_contexts();
  4971. __ast_context_destroy(con,registrar);
  4972. ast_unlock_contexts();
  4973. }
  4974. static void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char *registrar)
  4975. {
  4976. struct ast_context *tmp, *lasttmp = NULL;
  4977. /* it is very important that this function hold the hint list lock _and_ the conlock
  4978. during its operation; not only do we need to ensure that the list of contexts
  4979. and extensions does not change, but also that no hint callbacks (watchers) are
  4980. added or removed during the merge/delete process
  4981. in addition, the locks _must_ be taken in this order, because there are already
  4982. other code paths that use this order
  4983. */
  4984. ast_wrlock_contexts();
  4985. tmp = *extcontexts;
  4986. if (registrar) {
  4987. /* XXX remove previous contexts from same registrar */
  4988. if (option_debug)
  4989. ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar);
  4990. __ast_context_destroy(NULL,registrar);
  4991. while (tmp) {
  4992. lasttmp = tmp;
  4993. tmp = tmp->next;
  4994. }
  4995. } else {
  4996. /* XXX remove contexts with the same name */
  4997. while (tmp) {
  4998. ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar);
  4999. __ast_context_destroy(tmp,tmp->registrar);
  5000. lasttmp = tmp;
  5001. tmp = tmp->next;
  5002. }
  5003. }
  5004. if (lasttmp) {
  5005. lasttmp->next = contexts;
  5006. contexts = *extcontexts;
  5007. *extcontexts = NULL;
  5008. } else
  5009. ast_log(LOG_WARNING, "Requested contexts didn't get merged\n");
  5010. ast_unlock_contexts();
  5011. return;
  5012. }
  5013. void localized_merge_contexts_and_delete(struct ast_context **extcontexts, void *tab, const char *registrar)
  5014. {
  5015. ast_merge_contexts_and_delete(extcontexts, registrar);
  5016. }
  5017. static int ast_context_verify_includes(struct ast_context *con)
  5018. {
  5019. struct ast_include *inc = NULL;
  5020. int res = 0;
  5021. while ( (inc = ast_walk_context_includes(con, inc)) )
  5022. if (!ast_context_find(inc->rname)) {
  5023. res = -1;
  5024. if (strcasecmp(inc->rname,"parkedcalls")!=0)
  5025. ast_log(LOG_WARNING, "Context '%s' tries to include the nonexistent context '%s'\n",
  5026. ast_get_context_name(con), inc->rname);
  5027. }
  5028. return res;
  5029. }
  5030. int localized_context_verify_includes(struct ast_context *con);
  5031. int localized_context_verify_includes(struct ast_context *con)
  5032. {
  5033. return ast_context_verify_includes(con);
  5034. }
  5035. int localized_pbx_load_module(void);
  5036. int localized_pbx_load_module(void)
  5037. {
  5038. struct ast_context *con;
  5039. if(!pbx_load_config(config_filename))
  5040. return -1 /* AST_MODULE_LOAD_DECLINE*/;
  5041. /* pbx_load_users(); */ /* does this affect the dialplan? */
  5042. ast_merge_contexts_and_delete(&local_contexts, global_registrar);
  5043. for (con = NULL; (con = ast_walk_contexts(con));)
  5044. ast_context_verify_includes(con);
  5045. printf("=== Loading extensions.conf ===\n");
  5046. con = 0;
  5047. while ((con = ast_walk_contexts(con)) ) {
  5048. printf("Context: %s\n", con->name);
  5049. }
  5050. printf("=========\n");
  5051. return 0;
  5052. }
  5053. /* For platforms which don't have pthread_rwlock_timedrdlock() */
  5054. struct timeval ast_tvnow(void);
  5055. struct timeval ast_tvnow(void)
  5056. {
  5057. struct timeval t;
  5058. gettimeofday(&t, NULL);
  5059. return t;
  5060. }