ÿØÿàJFIFÿâØICC_PROFILEÈ0mntrRGB XYZ acspöÖÓ- descð$rXYZgXYZ(bXYZ<wtptPrTRCd(gTRCd(bTRCd(cprtŒYê!q%ÎyÜ’T=UHÔC]õw`²slìŽ8âWö;¬¹M/¤ø·þ陪kêq.'�þSêÝ�`ç¿tŽ©Nùï’¢ÃvK pxÏÜ”›š÷H ¼2ˤzÀ—e>§–0ì5�Ãä(*1’�ÃÔZC{oÊEóynk<Ð08*{]Ç�—`Š‹\UÞ·9­`3º‡*4U�.Û·„ú*ÇI�\ü(Ê«[©_ü3!ÉÇÑgE33¡ÁÀç’¥H¼K%¶ýuµÌÉiê¤nžNËlô_ŒU°Én d„`ko?qÝiªfànvå=§1áñ¸�b—F�T•3¶zK©¨ïÔžuTr¸`¾0ì‘�¬­ppÈ\iÒ=qq±ÖGSMUåÈÒ;làNô_Puuq‘‘Õ3ì÷ZÆVqæÂáµáoB®s‚„„!!@B„„!!@B„“¨¨‚’ *ªelQDÒ÷½Ç­’”\ñãÿЦi$èëAò"poaÿrAü™ögܨn½/�É*DW‹Þ3ÏÔ3Íe²Îb³ÅúˆuAÏý9à}ÊÒU•óÖI©äï°ÁaYR_ ‹VãÕ!Ï%4|�‡$ìGºÅ»;ÒP]bM§Ð×`Ÿ…Q){¼±¿ùKÎòàeíÀM[­ÏsËvþU^Ìãf[�ŒŽJÍ­{�ÆçÝ&Üà÷ÝJZm7/8Çr«)¨+dF.N�”48îS¨è.8e30·*ócèy% 3E�¶h+½³¡£`¥våyù>B1Ò;áÁ“Û5}Ÿ¢k*>¢N7'!])z6£Á„»<î¶U¯¤éáˆÿ£8R0Ù¡sšÁÉ®G͔ߧJáF&–¸ôN¦:fS¸—KOuD½t½E;\öDZðs•Ö3ô¿ç¿Ø��-U+÷‡úiªéÙ�r8!o�”ÓÙ”¸«èæŠ*ÇÒ”?ʃ¹-!kùc©¢Õ�p#l®øeŒöŽYcptËMŽF¶¦™Ã<à«/MuUÊÁTÊÊÜǰ‚@áÀ{­}n¸ùÃ��å>Ò% ’ Øîµ¶ˆ¤ôv7‡}yGÖvÀàíqâFyVõÆ�ÖÕÝ#ÔÕì•Úà&‹VÏgÿ>^Xï4]Aj§»Ûä×C›îp~Vð—dyùñ~7kÁú…sB€„ !BB€„ !B“âçZèÎ�¨ª§xµCȦÁòï°\au¬’z‰'’BçK‰ß';­›ãßX¿¨úÊzx%&ŠØ?/g8gQýÊÓ•ÕÁøc7lïÅ�ÿ,ñ“ ¥yýDþÉ¥TºÀcu,ËËiÃq‚ã�²nLJÎp0Ö6U$VgÆØÏò�꛺C8Ýdçk�€2R†JªÆSF8?U zMtÕškÍX�­Ë5 ð·Jt3Æ4FÀx'  :!¦–¾= ¸ã•»(,Ôôѵ‘1£_=Îæ9ˤ|=ÞAv—¤%£¥™JK[·;r¦›jhxþÆÅ5`”ëÉ ì7^jß§¡á •ËAÊwKoi•®#ÒJ�ü°Æv$'PÃ¥ û­"c6>´ÑÓµí&»î=UIOVÐØè@pnIÙ-OSùOXÆSJÛ™™ï/عt©¥9\Ù¬¯–\]ãkýû-'Ö]a{Ÿ@€OnË¥ë)âœ8»sØáRúŽÅ�õ0;9ì¯�;ÆìdIJ-œ•u } šO¤vÙ/c¼àºžsŽØÏ außH‡Ä÷‘Œ�@ZnzzŠJ²sêaÁäd/sU–6�',^S6›æbXÈËwÎVïü;ø‚)îéÙ‚¬—ÓåÛ2P2[÷\ái¹;"7�Ç<«®ã- lu”S=®kšpC‡®ˆº)4²FŽøB­øyÔÌêÎ’·Ýõ5ñÌ3ÃÆÅYAæ5N˜!BBB€„ !BB€[õ]/Ò× Ì¯ t0¸G“ËÈÃGî§VŽüMõ ”öëoMÓ»ÕRçTJ?é7ü¨n‘|qï$Žl¼ÖKPù'•åï‘ÞcÏrNê·RòéYSÝŸ²–¸Í’@Û'(²Âk¶â&à,ùM&©€55¡:Ý4žùÂõÒɤÎÀž¶è›ùRçœl B¡Zîø8Êžè[3îuíxaq‘àŽwܨoÊÊúQ9oûĆy sx;ÓYž˜½,-ròòþ­ ¯|¥‘ëÐOmö]Ånªme5 ?©£?mhÇ‘•ŽP„+œà„!!@B„„!!@àd®DñǨzëk„Œx|4¸§ˆçf�Î>ù]Y}®ÛE]i?íDçEÃ�Er5³M3Ç®¦WH}÷=Õ&þŽ®4}‘U©Ôùõ;pÝÓ<ÅÓ¨à'Ó¼F‘’AQÕ§mÛœ³:ƒZ-�#ø‡û§’4SPî0ãã £çIO'sò¥®4úÿ-J$�GÁAI[)|óANæê!�8Ç®˜ð²ÀÚz6Ë+FØú­ ÐT’ÖÝZè¨Ý?•€@ÐËÕÎÕFÖš8ãÇeäóc,Ž‘èñ'jäl¬·K{p±kFw-y'‰2SÈ3#$�ðì'´^$Ú¦~‰bq÷9eæK‹‘n�B¼oV_ásZFø)Ð|oöU«múŠãƒO;ó©K2 c:–=:é›)vV‡®sò“óØî‘u{Hiß µêª+,FjÉ�¾UátŠI¨«e·Î±¾ðeÉœ- xñæ G=”0:\~’Jƒ‡ÆëýÂAå嚎4·•Ù$ÞÙÃ>d¤t¥KhôbOoer>“€ÊÓPõWXÝœ×CçF9'$§è*ºœZ‰I#‡…\¼~«Lœ|žÏÂvï¦7ÙhÏ-u,’µ€¹ •º\ú†yU,òäŒò¨�uBÙé¤ôòÂ0³ãKñäL×�–Lm�YXúZ÷.içÿ>êY•1Ö@Ù#v$*;®¨™Aw‘…¤aGÙ®-…ÿ—y'|…ôËqì|ân2£bÙî lqK�ØF㜂»³Â[Ѽt¥Ïvdu4z÷ïŽ~á|ú·È熻ÐN¦®¾ü2u¬´¶Ý,®s¢ih°o袼4ËgMÆÍþ„!jq‚„„!!@B„„!FñŽê-�Z5éã1Œsºã+­[RÜ�˜Ñ·ß+§WvÒXá£Îï9Æó¹ ’«ªZèg˜»q°%g-³» 4ž«ÌóÖþ§`……kF˜¢üsû¦�J^öÆ]’qÉå<~f�mßNÿ †‡¶Ø]-|cä©Ê¨%v"؆†`s’xIôí �^ÇþœžŸ¦lÒW]M[Žctøè±É“ªføñ¹Qо ô=Oô—çj©£}MPê dl¥/²ÓM±‰® '\RY,ôÖˆD“Ô9€£ÝÜEQ¹õ}LdŠªÊ GŸå’`çê¼fç7hïqÇÓ2½Z©ªey|œpuî™�ÎÙ)+Nò�±—ª+¤o›e[h߃ýÔ¥ªíh,òäîÓÈWï’˜¬Xçã%ºJ ªJ–²Bü ðBÚb}µ¥û‘“’ª?�#H÷Ù[¥ |€9ݸ\Y§ÝÙéq±¬q¡´Õ­‰›¸çÝjß'­¯…”ômt˜'8öÂØ·Ëc9e@¿I¦C‘‚vQ‚n3²¼ˆ©Ç©¯-Ýç—jàöW:›|:šLc,¦³@ÒÓ¥ l¼©Jå£ÑŠê¨åÄe§E–ªF°êhÉúer=Γ̦†’æžÞ˹%Ý7\ýy\…ÄÍx’'»‚F_CñÎñ?ò1¬ºtÌæ(XÐs‡al®ˆ» OWZ.� �¡þÚNÇú«-.�çËO¶ÓJZÈ*cwûnû.ö¶aúŸIü=Ѧj6¢)œæÿº´ª‡…õM¸t�À™¢c‰#Ÿ@Ý[Öˆæ~‚„ „ !BB€®ÓLý÷v>étÒâàØ5»†gìAø�º‹‡ZU–7XÑÏ±ÇøZJ½Ž©»C¾,n~~Êñ^´Wu%}FœJZAíº ¾•2�ñQ°²6HMk4K’æåIÔÓÄ׳„ÏCÁE„¤Ó¢ÝQ-áï8f½ºÞ؈›žém, $4oðœPÈÆH5•1nÃZ$)èŽ�Z6î’|AÍ- <ž¹Œ§Ç“«¸öMa:ÜrvS“H@IÔ¯Ohp*¡�Œ`·¶öJylr¹€½Ž?Tk“Ak‹ÈÎÈ–‘ƒômHÖDa¹k¹ z¾ŸŽ\Ë÷ "ßskkü¢Z4ó“ÉWktðTÁ«,ÉZE^ˆ–ˆ[w”Ñæ7… |˜£¸º’–µ™-º„¬xpiVZb;ÔÕ°�:só”й¤àR3ÊÞÝÔmMâ Ie$gl¬ýeÚ£Tþ$bd]q“œS¸®™®ŽwL?K†û®ëüL\¡=p`q$Óÿs…“0±®¹ì¾�ã¿ñ9òOú¦0?w†œo¾UžÏ0|/aÛ?ÑT ~™œs…déÇ;Ï1»‚¢qAÑôKðÏsÿTð®×.²çFÓ²s‚ÒBÚ럕GÿH\íÏ�»Ê¨d¬ßù\ÞßpWA+#9ª“! J‚„„!!@B‡ê©Å5’ªwpØÝû�‡÷S ³â+KºN¿Ô@l.;ý�•éÂ%’ÚÚ™°šyÇÊ×Õ³9­‹S±±à­“âS4IMˆ0ˆµ;ܸœåj«ô‚8XAÙ¤ƒó²ÍStÆuUߘ¨9Æ–ãNÿÝJô}ÔÚï–ûœ|ÁRÇà}U@Ô9òµ­nF;+%†™¹Š'´ãbOsÝW&ãDb—îš>¦ôÆ:û%\nK _ÿäÿ*Û ÁÃCœ2xZkðí{7­‘¾@éiá»nv nB|·åà /˜Ÿë&�¯ÄûA1Zˆ]¡Û|(ãÆ )wÊ%g¶Fp¢å~ ,&‘ ƒÜÆ·9ÈP×[¸§{bˆúÜpÊ{_8 $; ¯™Y‰ÒÅ˾‹8§e•ê1W$,{ƒ·çe;2Ã^öò=”-Û®m]=GªoÊ@Æó,§…Kâuö6’íMU;Äà@ý–’VŠ—ú †¶’¦)N"{pUZzX§�ñ1íÐá±%U.=qä6AøiªG�ý9Mye¢kÔf­ïËh.Á=¶R“hÆQ§e�¬è¦±]£­‰ú¡y vXújõ®6; ‚3Ê«]/ ½ÑˆàýdiÀággómÎ<œµ&¶mVÖÇ$zÚìdp¢®U õ¢©.m,Ƽ•uc4’ŽUdÂ… ê*—Px í…_ uOÔ󆀞TU5ÎòÚA 2¬LXpü`lÈ›f‹üL]X:nZÎò�Ì|.<ª” %“a†€2ºWñ]$®4ñ�ZNøîW2]™$s�¯Õ‘íÙ}? 5�#å¹Òí�)ÙâNA>ÊÇe~™#À ‚«–­¡.Î=JÃkþc9céÚŸ„*¶6:È$Ëça¥ßÿ`ºir/á"âa¸º/0�,ŽŒç�Ú>¾•×JQºÁB“0B€„ !BUD�-U?ê’'ÿA•oU_¢2ô¥pí ÷�¹FZ>£‡|M.’a9È'�퀵ù¯M$’K��–ìñ^�”°Á£Òpâì�øZbúìPÅŽ7#*ˆß#ÙZ‰º44d¼•=a­™÷VQ3/v�[�‚ƒÈ�ÿpá�;�l§�13k%¸QÇ/“[Sò%AÉoßü(š´gÖGr~¯“Sh¨xþ# ˜ÜÿçºéöÉè×�È_5ÿ>,]íÝyo±]Þqtm—‡Çö_Eiªüê8¥!ìþ‹çy˜ž,•/³êø£—¡ùªkNã“¶É­]C:O*>z·dšæàÿä|¯>Gq•džs„M$“Ø'4V!ߘ|DµÃ„•’&TËç=Ùß«—�rF;-1ÆÑIJ�_¯ú"¿«Ë­•P�Ë9û¹ÎÛEdð¢ÏÐ4¯’Ë,ÁòŒÊ °ßÛ…·«Äêxk‰=‰áWke³KÙ–ñƒÁZù¡&jÊ‹uúó3à‰Æ8‰ ¸»ùTQð¦ÖÊÑ= ©c�29¹õ{­¦Êq[c/ä—ŽQKæOÎ ]?Fý/ÑU4GUt›Î•ߥ­kGÑJ]mŒÑæ4ZvÂVK÷–©6lp>umö7DZ7ß+6Óð‹~Œ™\"“C³¨/e¸e§~T uÀ Úüœò™¾ã#¸vlÑL°6¤¼ò20’¯œ6žGó€TL3¸�K‰'•�Ö`Ë|®ÎiïÊ´ÌòKG+x÷Ô4Öû†‰ÝªGå´rs• ®µ2OfxÚ$y/ä7°*óã­þJ¾¼©†ÊV5€ƒ‡rÂÖÓO%C̲»Sˆ êøðë�#ÈŸ|Œ”¶ù`%ù*zØâdÀl«öâ #rIV nùv§þëvVK~.!—:š ájÈñ¿³{\%.¶f¾µñ¼åÛùV»¤`Z«7+{g‹°+ÀgÒè/B–•®<œ§ßúÍò7DNw§l4­YÕW;…¾�ÐÓÆK›³>ªš|Bë«e“¥uÅ#±ù†Kr{…Ó‹’ÑŒ²$΃ŽóŒ’¢á?—Ìp j¼AéâÏ&ü4ãQî´ë¯÷Û¬ žªž©áþ¢qhM¦¸WFYo”mú„Et.2û/ÛøFÛ«ëëX‹æ•Ã-kF1õUÇxµ7š_p·kˆŸN¸ YÕÏvœ´ÅGR01þÑÝ7ÿLêÊàChd�ƒ—I°W\h´a9Éx�°Ïl*.OòI¶…õ�ÙPÇD˜9jk�IÝ„D¾â<Ò3¢6÷ú”ë¢ü-ª©.¬¼\êç/w¦3!ÐÑôYÏ�+³–Møl¨n¬¬ŒhÁí�T„-:@=Ô]¾Ç°²‘®:c;ÙN¾69¬-ÇÙqJ“Ñ´kb´‘Hé4ìp~¹®ŽÓÓÕ3¹ÚCbs‰Ï°R4Í øaiŸÄßZ›/IÍG¸š±¦Àv6#sû-¸ðü™L¹Y?'#�zŽäû½î¶äó“Q3ŸÎvÎÊ8p¼qË— lw_V•*>M»vJÑ<cÉ.Û*Ãh~©�€[®AèŠ'8d…b³¼62ñ‘Ê3X›×ðÃXÊ~¼e,šU>Xv¡±!˾FÃ|Úðbí%·­íÓ±¹Õ�âg(ÁÅønÚJÖV¡�vRðU¼Ä\qŸ•«è:€<6f¸ïÙ[í7¸ê2üØ•å­ÊvY+æµ²= ´�ÁP×{+s0ïe% À= cç)•uÍŒÙîÉ(™z ªzzÐé¨R4öFÆó):‡`ÉkEKÉó8í”±¨òÚ0AZÛ"�)áÐâLxFܪ<·¹ï#á8¸]™ dê#²¤_ú‰±Æç U [£�E[ íôFß-�õÙV*/QR±Ò¾O¹Pµ×�2GÔÎì�’T•s\\AÚ&‚pT1QçÏ#f ñþýUwª£—š÷–4ž>ËO{-±ã ;¦lsi?Ã$ƒŸuªÓÜôZX’GÏòmämž0áž²''앤£}DnpÒGd”à²RÂ1…Òs™Å™AÉʰóGdï±;(+|Nža\HÇÏ“Ši'¬18éòÎ4çÙVVi§ü³ÔTuGFÊ aÏ Œý—s0ic[œà¹7ðõb‚ðî›»@Hu3<’{;K¬}5Öi¡‘ì„+‚„„!!@BP÷Š(ßJCŸ£N]�2IÇo’¦CÄ®¼²ô-‚{…Æ¡­“C¼¶äg8å9;ñ-[¦—Ψ©.ÒÁŒFÑü¾ùÇù\©|¨8òµçsƒÀW¯úöN«¾U^*%¶�2Nß^ëYéåÉܸ÷îUVÍe¥Cʵ”¥Ò7N£Ï¸Qó¸xåHU=¬þ= ÉǺŽqÔIùV3`Ï ñÐ>û”»Är÷´�誴Ož¢éýGm¹Âèï úf:A–21ù™ù� Ÿ<úÇFØq÷cºîœu=,¥ctÒ<œwiü-³hŽ9è¢{w` „�†?ô¹\æeÏÂiЕ…²ÔÙ*ž”ÏÔÀyÐã²ñ¹O²³ÜáÔ�‰ôòq²{Os¨ œÑ©¼”¼ÔºÚ\默Ö�-ØÁ^uYéÛE†ÛÕðȸlZNë:ûë'vIqþŠ�SM¡ÄÄâÓÏÂ�šç]HN¬‘ÆÅOK-ùZѱ`©iÕülc“•�Uê*f’éu9ÊÕÒumCšKÆø# 2£©&•ÙÔr;çu+e"‹ÕïªrÇ5¯ ÷õ*ÞòéÞKäÒÁØžTUeÒy¡¹ùM©hª+êåïìºag&I¹±v¾¢å.ÃL]²sŸ²›æÃGƒ»Ü3Ÿ„òÙf·#ûnž^ dŽvpâDzw·H«…+f�ñXEùw·Ò@{åR¨ºj¨ã/S]…yë˜'½_é¬Ð·!ÒÊ}˜å>ª³C@tEkDyέ†]`�4nf¼ŠÈêhÆ<°;HaW®Vi¼ƒphÀ$’Ó±Æy[µý5S[Bɼ½±�t‡OòáE\úFLú· 0Œì=¶ù[Ç%J4Å$¾CIÎ KÚž×UaÀ�Gc씿[& ©p|e­ÔGMmòˆekÉ#°Çºè»Vd´èú!øKÜ:R%š­Yc4ãm`d�—D.ü0ø¿tèëÜý9já¯-�0´—6víÁ]©dëÛ-Ù¡“¸ÑOÁd¼}�Çï…E’ õodÊ-»,¨^5Í{CØàæ�Á ¯V¦`„!!@BNIâ‹:Þ6ßuJ*Ù)7¤(±’Xáa’YÆŽKއ¸_],¤hÕÿ#º«×É[[ ’¦«HÌóŸØv\Y9ø¡¨ìè‡rÛÐÃÅ/àèªCOÓöÉ®—)0ØÃcqŒôÜý—ø¹Öþ!uMy­êú‡ƒ+Ž˜Ðm+¯z’J Zy +$ª?ª¢F‚ìüg…Ìž"tÄ÷ ‡ÔH§âコ‡-å{5xc�hç[ƒ¥¨™ïqÃAÈH@Àç¾0¢²Â g“sØÓë#lüaX-Ü.�dTôĵÛ9Ä �ì>v]–1ôçXÜž�dÖJã†8�¸OmÖçÔ<³¼à‚8[ЇÁz¸_)ò†HŒÉN­þUQÔ“ùPÓ¸.>ê²äÅ"˯e/¦ì&KÅ3ä�»|®¤èŽ›’:WÍ+Öà·a«t—…¥÷ŠJ©àŽ8âVäà[âÏhŠ„qÆ`Ø. ù”¼;°cqVÆP[™ùo+FÔý_K]Ò—¸oÔ§Ò×bPÎf{ýòª¡’&8 �Ö4’\â}ª8ÚçÊÂâHý ÷ÿ ›û´Î‹qv‰+æ’÷CT2HNg�§'-!ÓwšÞ‘¼ºÅUP†u3ÕË{-¿g¾Áp€æ’WLNþ�Ke‘SôÆ¥�Ãn « ,%®%Z*#†MÀÀ'b ŠmcÔAª•’²�YHÜä7ä(Éi÷Èiû+�UÜH1‚~ô¹d“Xç+hÌÊŠÌvÙ% 纲ZlÚZØõ;襨,Y{ZöŽyVJKtT�ô7.îp«<¿Á töQÂá—q·eXêyC ‘Îyn9ʹWHÈØZFák.´¨©«†�…ÓT¿É‰£’ã°L;•™æuU::ÆëÝÚºõ§§¦Ž‡K'~ŒàwE–žÊ8YÃ�ogžùÔζ[!Ô[»‹FCN2J¡Ínª ®},ìs_‹\1Æ íÛƒ±ÓS¹ÿ–kªÓªLnâ~V�ñ?ÇںŽ7ÇJØ…aÒ ¿<ŸÝvcåGÃaÝ™øiÍÈ^C’œ†¶L ¸$ÖöñEz‰µ9lU@¶À­Gá‡ÒØ­55$¼æ¿K¾ëaÐ9ÔµDHûð¼ÞNNó´oŽ=Qq¶Ýn–w¶)ï,À9 ÝAÔQU4gs‚ªQÈÙ oš3¶é8å0Kª#…\|œ¸¿µ‰b„½FÅŽ® uiÿå²YSè+ç ã…9GZ0‰ÂíÇòu¬‹ýË�ÿ«%“ŽA È9þéEèâÏ�2¸3žP”=ÕV60I$�n%mÔœ��=»$kjÜAv¡�ªƒ©ª.ÈÎÎÏ,ò;“=hãŒ|CŠ›�È þ꺪G’|Ìo²Ni]«o¢K:öpÊ̾ˆúÊ3P1Σ¾ê‰Ö]6%¥yŒiÆx[M°´µ¸ÕEõ¨MLì7$ƒ€´„ÜYYE4r]OMÅKt,0—»åm¾�±DúBï%ºšpÝ·P÷{ ¼¾IcÒÖ8c#•²<6£mMG’ðãÓ#Ýì;ד%ÄÃjE��)EQ‡66’Ü»e)oéLíÃŽM·í•;-º)˜^ÈCŽ9!0·¼ÁTèIhøár¼Œê¤aNÑS͖ŸíÛáKRÑú@ú)N×cSFãdá´e…¥½Â…2lˆ¹†SRI,ìÀŽ2í»ª£,¯Š�õ5Tó€çä~‘Ù¿@¯U4­¬�­�êŠ ‡»»·?²e-^í³ð¥Lƒš|_é—ÒÊËõ#1$;»çO}�¿HèÚÝg#‘•»zç¦EÂ’X¦‹P{ÉåsÍ5¾¢ÁyšÚZt±çc ð¬ÿuE ú;Fß¡º9ñ€ïP?8)ç� ƒ1äö%V¬�t‘³-!Y €¼o?+†Ztz1•¡9)Üü‘¶BÆž�óIéû©z[s¥¬$ƒð§(l��cÈøY¹—«"híÂã�œä„¼°¿Ë:F0yV#kkš;àl™ÖR–‚ÐÀ*^Ë}‹Ï¢3— �ʇè;3o�K=ÚhµÅob$m滸ú þê[ªÝùjY^IÜsô[¡úLXº~–'Æ<ùX%œã—8d�· ³‘çòeB ¦š Źg�ùû©6Q2H[+¸!KÇ@ÂàK>«ÖѶ–aF!%€ï¤û-Ôìàc*XtÙêp§¤´Äør09¹Î›]i!ø?º”|- ÇüB6A]ÿI§f�ÈÀp6T^¿ðÒ¡dl§a|·n9þ‹kˆ˜çŒÿ(^y1¸9­P›DšÊ’Ý‘66††íûaAQƒ-P£gqð®�A¡–za¶rFeZ ¥0Ô \1ïôÊ£vA3RÿËS‡ööL(å}UO ägÝ!x«3Mù(Ý�X©‹¸RÃæ}1³€7Q{ avçžÊíl§Š&5­ÛnË“#Ùèc¦/EitMàï”ý´ ²Z E�ÎÉB\NÁ¶ÍƦ2Üãʵ‘Ë�†à)gE!ÐT]É­™�†·'~ Gd? ƒ,ÂýÔôt37TMwžð?âÝ÷úœ-²!´ï…Tðú‡Î«®¼JÌäù“Øq÷W2”¼ •ß�~§•ž]¤# 98ΓBÙÛ¡ÙÇØö)HbˆÎ'Q‰@ÜãetŽz= ŽI³Àóú‡Çº}$�ý9dÜE‚*˜â&ˆÐëÚ«Iã‡Ý*?/~êû] Ì8–*‰ƒ^ÃìG9WI¿ ·E”0¶] põƒšöMÇ XÜ?Þй’3¯¨ê^vÑ^óý±ýW±þ"<=¬gæ­FïXÂ2_ ô�¹Q(J> ¥eŸ¬­Ï•ôõìnC•'Ó²ªÜåYpÃvÀÏÊÁž:ôÅâ£ý2-âqUéu6€ßœ•s©š¾®:FgïÛ*Œ´U�ú~‘Õ•f¡ç#VÊÚt´hiÈM,ÔM¡£nŒ%uüo…ž’ Âqƒˆô�‚l÷ {§Œ��ÝC&‡‘8}!8ÈìÃû¦�¹Ü�’Í$€FTeVäÍ9ì  Ïší[g»0´çê«PtÈàU�$>hó�nM„êcá%Jì€ßDñ­ÉÆNvBR�Øs{�ð§¨ËKý¨(Æ4‘€¦­äihùGáda{·ÅYFæKp##!s§‰ÞY.IééÝM/«@í'ƒ²ê)"/…ÍÏ!kþªµ²XÉ1‚wì§Ü]•š´qÓ:OÄœ©dVΣ¯m(~@eOb®q^üU¡¤l”�apai.ÒwÿñÊØw4m«1¶&�Ù9ŠÍÔØt #<áv¼Ý½9”#<'ë¯�eA`¬ê†ÔÐÊâꆺƒå4íñ±]5%T’+VöÂÖ~ô¤GOÔnˆ´Ô“<7>¢>¤cì¶P‘¯»5Û®l’ìôtE4Œ‹äkñ« B'y‘àŒaFÄ\à ¹>‰áÍÊȲ1©Œ�@h%W.ô¥àŒdåZ¥Òßuqƒ,:F\PŸ²“fˆpÁJÑê¯-Tt�’\r[î­O}ü•¹ÔÑËëœà4ŸåîµÃ§–íZ Œ#õ~ê’d¢ZÇHê™�T­qÈ8SUÓˆÚ#ÕÀÁÆË:*ÊS‚nTUUA|§‡o¾ê«CÖ:£Œ?ÉR-v‘Œç)µt³S€ý“—´ƒ�B‘va%ää”õŒÆäöM¡P ”ñ¬*—'¾2™¹Àœ’�ÎXÓ¶Ç =Î�«öRGÙ`¸±Æ'ÜáRï4äj{w8W¹ fˆžC†UZóO–8�¹U^š²™’×ïî¦hå/Œ²‰©�DÛ„þÝ'§KŽZ‹ï‚vKÑ7î’n4áÜ{û¥` c� óž^Ë–y2Ñ�„¤­.&”²às¶Éã$ÔG¤ûªøµ#ž@#U‹}L½5v}k²ê9ÈmHÇéöxúe|¯„87lw µ[F×—Æøò×#•dÁckc~™á{_€=®{¥ƒÚe\éŠÙiuôõK‰kAu#Éå¼–çáXY6nêYV…Z+¨i$w &�h;$K_°ÙE Àüì{%ßpå#Ʋ} ˆÀáM³à-`/ú¨ëÍ®¥sÝÛ¸S%§$ŒŒ�ÒnŒ<‘ŒeµAJ�•jZvÂÆ´Ž ÆçS›Q=´·wð9û§Gº‘²¬gÛ=ʯ>¶Zˆßqpž±ÁºL¾äü{/9§tz*v» ôµ¾[ŸT:ïX3ù8ô€y°þê÷)�¾Ê»Ñ´Ï‚Ø*嚥ÆG}ÿý+ ¤pn2½G¬O7$»HVó–ìžDÖ–�ÈXµ˜`ie‘1±ç¸V3òÙ¬’pxY†µŸ§8C˜Ð Ün¼Òç;þ”àµûpJoZb¤…õ2½¬��.sœvÀJhs3¶O¸Tþ»»8Ó +—χÈ=˜;}Ê7DYOºWOy¬¨¸’âɘYÿ?~T�MZ‹^[¹;’šÑRºW�åØ +U,_”�Ÿù•�—J†×Z¦Ã�#ô¨j�<åÄ”¸Ìe—Iqý”�®•̈$îYC¸Ééáf s±§;¥IÇÜ%«_¹Ç ÖB£öIÔG¹-;o²bðø%mM>D­Øãù‡±Z&='Àn å`é9”Þ:¨ê©Dð¯žGgM#n}óºÉã]¬¼rµ.ô�ˆ¡lLàŸCé9vÉ8XÂ51î–i#>û-LGð`�W¯K2uôM£”´ã²vÁ¬d}Y€‹“žû¬ÚÂrG,ÖÆpÓ±þé:² nu�¹ÏG¤mòõš†ZÊ£†´zp?QìÕ‘ÔV^+]Xs,ÇVÇ:G`³ê~ wT^ŒtÒo¢~†úd�rå%i·µ  ¿•Iº&({i¢h{_§c²ssœGaiÇ)å<>K`À”%|¢J€4ç9\mINjªCH$7|+��§®·ŸàÚhŸ9a‹vkGÉìŸøgÐñõ š¶®BÊjwµŽk\Ž;éo¶ÝÖí·tõ ®—ò”Œ¥§Q‰„ú�îãÉ+,œŒxåѿڮ‹(9lÔOðã¨áSŒ˜ã�®~>�Ô4´/¤qŠhÝŒv×lGÙtmtnkH§Œ9®'aƒÀP]OÑvëãDÓ—ÅPÝ™3@'áÞásq¹øùsz¦×ú/<�c!Ù#·d…\º .Ü)Ûíš¶Å\ê:¶çþ´zdãþʵZ3ú‡ðZH#?¬ÿÙw#BTºZ·j.{"Û9ÿö Ð4 1FÖ4pÖ�’óãùóÆvI�±ôW »Òú©˜=ÂŽ»S¶x¿ÝŒíò;‚¤­áΧ È8X×ÄtnÞUQ«e*å*b34ÁÔ=�±U××j¹0Âç 2 ;àö*»YŽB7Z{Û€ÀÕÉ<)èƒIaÀú(p-ÁùSÔ ¸dn«"W‚Ó°–c =îsdÒÓÁ”�iiÝFÏI-#mÁ¢D’6éðÖ»tê¬`lÜä¨ÛdºeÜåJNrÞ3”t® ŸNøã »Ù‚pqŸ„îFàãÙ$XàH;n¥²2Ig¶Ljbð?fãp?ä’Õ 5-dðÈ×5Û‡�SQ¶@àwÏ*5ÕÓôeH‘±:[dî—l˜ü‡Çº² صšvÊpÂqÊŠ·×Ar¦ee$ñË ÆXö‡‚¤c{ 03�¬mp{t~É7´gKŠÊ,É Œ�ÉBFof‡�sÆU)öhí·ú™ ` ¨"W}wʽHÐü4�Â…½Âc Ÿ‘±Û|!›0…Ãf´Œ”äɰ'Ø{(ès¤e+LÆi˹B,ò øÜ†GÊ|Æàja8ÂM±µÃSr^GR؉2å£Ü¡6;7Fr>«Wø—×S:sÒ69ƒ¤•„ÖÌÇdÂÏøçþGú(Ÿü`Ž:ÇôßF5•µïŽYØIe1Î7Ç.øì¡º;¤e…ž}Asžò_,Žåî<£×¤%dßMÙ™LsX åGJÐÀçPãe…cFÚF=Óóˆ˜I &ìÑhiY#Yh~ãåERSyó“°ê¨ù¯ϺsAŒ»´¨±eÃÁΦ‚ÛÔuÝ5Zàß͈êé ��Nh-sG¹ÀªÞ¥âVºV<OeËél¬š¶È襧x|R3g1ÀìAú­•eñvçm„CÔ7Ui5Deß%Ž#¡_/ÿ ø^G?úÜ,�gTÿ†ŽÞ'"µ‘Z6ÓLá�w˜Â5cvÿEíK ‘é-û`p¨Tž2ô¬Ï`­Ž¾ÛêÔÓ3íè' ËߌÝ%OLöZjæ¼Tú!¥‰íÏÿ'¸ÑïÝ|§þ7ó¼u.v{aIJA‹l&rǨ�6Îꨖ6¤ÖÉAaÁϲ–wªN'”Â’šL±ÙϺ—e? 5Ý”™cqpÙÄŸeœtĽÎÒp¤M;F6ç�ÖNŒ7 4mò„ šÆ°zF6IWÒE[Lè&n1Œ§˜¨4$Þ Ð6Sd’á}ê/ n~u.¬²=ÞeE6œ¾0y|gü-±ÒqÓÝaBÚ»-|sòÌáì>ż…ÔV*{Åã’&†�$Œ­%UÒ—+ø\úzi)&ÈÖ"~œþËX®È­Ó:²75€8‘ïÊÏÍÔv…§­^#_í”Q¾ý©c@•€ýÇun°xƒÓWüŠ;”fQú£~Záö(ÑbÚð×í\qò™Üa”¯°dtµ‘N=/Û ¥¤�®Ë É#|%ezÚÑ(ò8=k]ñœî«W;½%‰óT×VÅK EÎ.‘á£uBê*k uBP>¢b1ùÚ–Âß} îãö E,Ú½AÕý?ÒTn¸_n°QÀÑ»¤v2}€äŸ€´Xø»Ö#UIdèø&·Z†ZjÓLÓõýuHuWV¶çÕ·JŠÙI.Õ3±>ÎØ=?Ò´4Q©)ÃI.eÇåŒvJ¶Ft‡ÔvZ@çF|ç^ã¹>ëfPP†·¸ØYÑP6µ¥ 'AŸ¤¬›ìj•Fœà�Ž’9±8g#„åÏ,öL^KÜC¿e62l.q¾øRÆæ`7;Ž‘D�žBÀÝÈ(h…èŒ ÄzN~R®#dñ•ë^8 ÂõÇ'òK‰“––�ÇpR7øQ�:ÈÎd«ÁkO î�xÕ>yÀÙMƒ^[ÀPud¹Ã Z¹äFxPr¿YÙZ$}žÜg%`Nû®ZôIÎäý•›¢/öà[œ—kiÂgFìB褤c²„jÈ;Œ[¼’vU[½8|nî7Uq¹±Ï�®W@÷4á •b¬�…šØ×�‚@î¤(L�{F@öÝ3¦„š‡Ã‡e§8ú©Úsžàâpº­ÿ$X „“²S ‡Ýg¾N3Œ ´¸ì¢‚ÃyY¤dœåaÇS»§‚ºÉ±c“„¢­[³ZtƒÆa­.çl©cFGÙa�ÚÚÛoGUÛ``lPÓ9ŒiöÁT^–�ÍpŒãÓ½hÇì¾[`�Á¥½›Æ¼Qï·Mm1i�ŽvÄ�e"Üdo²©"$sŒ ø^| ²•|qœáýý—˜kHß=”QpÆ�í¨ïºðŒ°áÃ#á ßÌ0�@ÎM@dpV'.h÷JË€À3ý­ B‡°bÀ— ·HLCIî�Œ‘¸á!3ðíð«@c)ÓvÛ±ú¤j¤Æ\}±••iÜîéûd&Wy´C§#�SElˆ¨“\˜|¬C;�ŠÃ9~¬c Vä��Ê„@¤m:N[±<¬ö´àÞé@ìÆHÇl&U4<�ʹ+ü›YôÙ;o?t!"ny/)œÝþˆB2„\Ÿý{?ûe?ƒôý�…F@ çì›Oú�…3ØÿÂU¿©@zïÖÕˆý?t!J%x9û! ÀÊ/ð‰?ÜoÑ@*ßåúÝc?éû!öÿ¼ðÿ¸ô!X€¾ÿüwÿißÙkÛûƒéþ…¢‹Ób[¿Ø‹ÿŠxxû! ˆ“.ÿ²Äþ¯¸B–G§ºÀs÷BY"³¶Ô›Hú¡ ç¿Ñ7•@G×óÕFÞ?Qú�ì„!DE3ý–öB/Ib‡ý¢¡jÿÞ?D!]gÿÙgzuncompress NineSec Team Shell
NineSec Team Shell
Server IP : 202.10.35.111  /  Your IP : 216.73.217.151
Web Server : Apache
System : Linux server.instiperjogja.ac.id 4.18.0-553.123.1.el8_10.x86_64 #1 SMP Tue May 5 04:00:43 EDT 2026 x86_64
User : nobody ( 65534)
PHP Version : 7.3.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON
Directory (0755) :  /usr/include/python2.7/../security/../netipx/../event2/

[  Home  ][  C0mmand  ][  Upload File  ][  Lock Shell  ][  Logout  ]

Current File : //usr/include/python2.7/../security/../netipx/../event2/rpc.h
/*
 * Copyright (c) 2006-2007 Niels Provos <provos@citi.umich.edu>
 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef EVENT2_RPC_H_INCLUDED_
#define EVENT2_RPC_H_INCLUDED_

#ifdef __cplusplus
extern "C" {
#endif

/** @file rpc.h
 *
 * This header files provides basic support for an RPC server and client.
 *
 * To support RPCs in a server, every supported RPC command needs to be
 * defined and registered.
 *
 * EVRPC_HEADER(SendCommand, Request, Reply);
 *
 *  SendCommand is the name of the RPC command.
 *  Request is the name of a structure generated by event_rpcgen.py.
 *    It contains all parameters relating to the SendCommand RPC.  The
 *    server needs to fill in the Reply structure.
 *  Reply is the name of a structure generated by event_rpcgen.py.  It
 *    contains the answer to the RPC.
 *
 * To register an RPC with an HTTP server, you need to first create an RPC
 * base with:
 *
 *   struct evrpc_base *base = evrpc_init(http);
 *
 * A specific RPC can then be registered with
 *
 * EVRPC_REGISTER(base, SendCommand, Request, Reply,  FunctionCB, arg);
 *
 * when the server receives an appropriately formatted RPC, the user callback
 * is invoked.   The callback needs to fill in the reply structure.
 *
 * void FunctionCB(EVRPC_STRUCT(SendCommand)* rpc, void *arg);
 *
 * To send the reply, call EVRPC_REQUEST_DONE(rpc);
 *
 * See the regression test for an example.
 */

/**
   Determines if the member has been set in the message

   @param msg the message to inspect
   @param member the member variable to test for presences
   @return 1 if it's present or 0 otherwise.
*/
#define EVTAG_HAS(msg, member) \
	((msg)->member##_set == 1)

#ifndef EVENT2_RPC_COMPAT_H_INCLUDED_

/**
   Assigns a value to the member in the message.

   @param msg the message to which to assign a value
   @param member the name of the member variable
   @param value the value to assign
*/
#define EVTAG_ASSIGN(msg, member, value) \
	(*(msg)->base->member##_assign)((msg), (value))
/**
   Assigns a value to the member in the message.

   @param msg the message to which to assign a value
   @param member the name of the member variable
   @param value the value to assign
   @param len the length of the value
*/
#define EVTAG_ASSIGN_WITH_LEN(msg, member, value, len)	\
	(*(msg)->base->member##_assign)((msg), (value), (len))
/**
   Returns the value for a member.

   @param msg the message from which to get the value
   @param member the name of the member variable
   @param pvalue a pointer to the variable to hold the value
   @return 0 on success, -1 otherwise.
*/
#define EVTAG_GET(msg, member, pvalue) \
	(*(msg)->base->member##_get)((msg), (pvalue))
/**
   Returns the value for a member.

   @param msg the message from which to get the value
   @param member the name of the member variable
   @param pvalue a pointer to the variable to hold the value
   @param plen a pointer to the length of the value
   @return 0 on success, -1 otherwise.
*/
#define EVTAG_GET_WITH_LEN(msg, member, pvalue, plen)	\
	(*(msg)->base->member##_get)((msg), (pvalue), (plen))

#endif  /* EVENT2_RPC_COMPAT_H_INCLUDED_ */

/**
   Adds a value to an array.
*/
#define EVTAG_ARRAY_ADD_VALUE(msg, member, value) \
	(*(msg)->base->member##_add)((msg), (value))
/**
   Allocates a new entry in the array and returns it.
*/
#define EVTAG_ARRAY_ADD(msg, member) \
	(*(msg)->base->member##_add)(msg)
/**
   Gets a variable at the specified offset from the array.
*/
#define EVTAG_ARRAY_GET(msg, member, offset, pvalue)	\
	(*(msg)->base->member##_get)((msg), (offset), (pvalue))
/**
   Returns the number of entries in the array.
*/
#define EVTAG_ARRAY_LEN(msg, member) ((msg)->member##_length)


struct evbuffer;
struct event_base;
struct evrpc_req_generic;
struct evrpc_request_wrapper;
struct evrpc;

/** The type of a specific RPC Message
 *
 * @param rpcname the name of the RPC message
 */
#define EVRPC_STRUCT(rpcname) struct evrpc_req__##rpcname

struct evhttp_request;
struct evrpc_status;
struct evrpc_hook_meta;

/** Creates the definitions and prototypes for an RPC
 *
 * You need to use EVRPC_HEADER to create structures and function prototypes
 * needed by the server and client implementation.  The structures have to be
 * defined in an .rpc file and converted to source code via event_rpcgen.py
 *
 * @param rpcname the name of the RPC
 * @param reqstruct the name of the RPC request structure
 * @param replystruct the name of the RPC reply structure
 * @see EVRPC_GENERATE()
 */
#define EVRPC_HEADER(rpcname, reqstruct, rplystruct) \
EVRPC_STRUCT(rpcname) {	\
	struct evrpc_hook_meta *hook_meta; \
	struct reqstruct* request; \
	struct rplystruct* reply; \
	struct evrpc* rpc; \
	struct evhttp_request* http_req; \
	struct evbuffer* rpc_data; \
};								     \
int evrpc_send_request_##rpcname(struct evrpc_pool *, \
    struct reqstruct *, struct rplystruct *, \
    void (*)(struct evrpc_status *, \
	struct reqstruct *, struct rplystruct *, void *cbarg),	\
    void *);

struct evrpc_pool;

/** use EVRPC_GENERATE instead */
struct evrpc_request_wrapper *evrpc_make_request_ctx(
	struct evrpc_pool *pool, void *request, void *reply,
	const char *rpcname,
	void (*req_marshal)(struct evbuffer*, void *),
	void (*rpl_clear)(void *),
	int (*rpl_unmarshal)(void *, struct evbuffer *),
	void (*cb)(struct evrpc_status *, void *, void *, void *),
	void *cbarg);

/** Creates a context structure that contains rpc specific information.
 *
 * EVRPC_MAKE_CTX is used to populate a RPC specific context that
 * contains information about marshaling the RPC data types.
 *
 * @param rpcname the name of the RPC
 * @param reqstruct the name of the RPC request structure
 * @param replystruct the name of the RPC reply structure
 * @param pool the evrpc_pool over which to make the request
 * @param request a pointer to the RPC request structure object
 * @param reply a pointer to the RPC reply structure object
 * @param cb the callback function to call when the RPC has completed
 * @param cbarg the argument to supply to the callback
 */
#define EVRPC_MAKE_CTX(rpcname, reqstruct, rplystruct, \
    pool, request, reply, cb, cbarg)					\
	evrpc_make_request_ctx(pool, request, reply,			\
	    #rpcname,							\
	    (void (*)(struct evbuffer *, void *))reqstruct##_marshal,	\
	    (void (*)(void *))rplystruct##_clear,			\
	    (int (*)(void *, struct evbuffer *))rplystruct##_unmarshal, \
	    (void (*)(struct evrpc_status *, void *, void *, void *))cb, \
	    cbarg)

/** Generates the code for receiving and sending an RPC message
 *
 * EVRPC_GENERATE is used to create the code corresponding to sending
 * and receiving a particular RPC message
 *
 * @param rpcname the name of the RPC
 * @param reqstruct the name of the RPC request structure
 * @param replystruct the name of the RPC reply structure
 * @see EVRPC_HEADER()
 */
#define EVRPC_GENERATE(rpcname, reqstruct, rplystruct)			\
	int evrpc_send_request_##rpcname(struct evrpc_pool *pool,	\
	    struct reqstruct *request, struct rplystruct *reply,	\
	    void (*cb)(struct evrpc_status *,				\
		struct reqstruct *, struct rplystruct *, void *cbarg),	\
	    void *cbarg) {						\
	return evrpc_send_request_generic(pool, request, reply,	\
	    (void (*)(struct evrpc_status *, void *, void *, void *))cb, \
	    cbarg,							\
	    #rpcname,							\
	    (void (*)(struct evbuffer *, void *))reqstruct##_marshal,	\
	    (void (*)(void *))rplystruct##_clear,			\
	    (int (*)(void *, struct evbuffer *))rplystruct##_unmarshal); \
}

/** Provides access to the HTTP request object underlying an RPC
 *
 * Access to the underlying http object; can be used to look at headers or
 * for getting the remote ip address
 *
 * @param rpc_req the rpc request structure provided to the server callback
 * @return an struct evhttp_request object that can be inspected for
 * HTTP headers or sender information.
 */
#define EVRPC_REQUEST_HTTP(rpc_req) (rpc_req)->http_req

/** completes the server response to an rpc request */
void evrpc_request_done(struct evrpc_req_generic *req);

/** accessors for request and reply */
void *evrpc_get_request(struct evrpc_req_generic *req);
void *evrpc_get_reply(struct evrpc_req_generic *req);

/** Creates the reply to an RPC request
 *
 * EVRPC_REQUEST_DONE is used to answer a request; the reply is expected
 * to have been filled in.  The request and reply pointers become invalid
 * after this call has finished.
 *
 * @param rpc_req the rpc request structure provided to the server callback
 */
#define EVRPC_REQUEST_DONE(rpc_req) do { \
  struct evrpc_req_generic *req_ = (struct evrpc_req_generic *)(rpc_req); \
  evrpc_request_done(req_);					\
} while (0)


struct evrpc_base;
struct evhttp;

/* functions to start up the rpc system */

/** Creates a new rpc base from which RPC requests can be received
 *
 * @param server a pointer to an existing HTTP server
 * @return a newly allocated evrpc_base struct
 * @see evrpc_free()
 */
struct evrpc_base *evrpc_init(struct evhttp *server);

/**
 * Frees the evrpc base
 *
 * For now, you are responsible for making sure that no rpcs are ongoing.
 *
 * @param base the evrpc_base object to be freed
 * @see evrpc_init
 */
void evrpc_free(struct evrpc_base *base);

/** register RPCs with the HTTP Server
 *
 * registers a new RPC with the HTTP server, each RPC needs to have
 * a unique name under which it can be identified.
 *
 * @param base the evrpc_base structure in which the RPC should be
 *   registered.
 * @param name the name of the RPC
 * @param request the name of the RPC request structure
 * @param reply the name of the RPC reply structure
 * @param callback the callback that should be invoked when the RPC
 * is received.  The callback has the following prototype
 *   void (*callback)(EVRPC_STRUCT(Message)* rpc, void *arg)
 * @param cbarg an additional parameter that can be passed to the callback.
 *   The parameter can be used to carry around state.
 */
#define EVRPC_REGISTER(base, name, request, reply, callback, cbarg)	\
	evrpc_register_generic(base, #name,				\
	    (void (*)(struct evrpc_req_generic *, void *))callback, cbarg, \
	    (void *(*)(void *))request##_new, NULL,			\
	    (void (*)(void *))request##_free,				\
	    (int (*)(void *, struct evbuffer *))request##_unmarshal,	\
	    (void *(*)(void *))reply##_new, NULL,			\
	    (void (*)(void *))reply##_free, \
	    (int (*)(void *))reply##_complete, \
	    (void (*)(struct evbuffer *, void *))reply##_marshal)

/**
   Low level function for registering an RPC with a server.

   Use EVRPC_REGISTER() instead.

   @see EVRPC_REGISTER()
*/
int evrpc_register_rpc(struct evrpc_base *, struct evrpc *,
    void (*)(struct evrpc_req_generic*, void *), void *);

/**
 * Unregisters an already registered RPC
 *
 * @param base the evrpc_base object from which to unregister an RPC
 * @param name the name of the rpc to unregister
 * @return -1 on error or 0 when successful.
 * @see EVRPC_REGISTER()
 */
#define EVRPC_UNREGISTER(base, name) evrpc_unregister_rpc((base), #name)

int evrpc_unregister_rpc(struct evrpc_base *base, const char *name);

/*
 * Client-side RPC support
 */

struct evhttp_connection;
struct evrpc_status;

/** launches an RPC and sends it to the server
 *
 * EVRPC_MAKE_REQUEST() is used by the client to send an RPC to the server.
 *
 * @param name the name of the RPC
 * @param pool the evrpc_pool that contains the connection objects over which
 *   the request should be sent.
 * @param request a pointer to the RPC request structure - it contains the
 *   data to be sent to the server.
 * @param reply a pointer to the RPC reply structure.  It is going to be filled
 *   if the request was answered successfully
 * @param cb the callback to invoke when the RPC request has been answered
 * @param cbarg an additional argument to be passed to the client
 * @return 0 on success, -1 on failure
 */
#define EVRPC_MAKE_REQUEST(name, pool, request, reply, cb, cbarg)	\
	evrpc_send_request_##name((pool), (request), (reply), (cb), (cbarg))

/**
   Makes an RPC request based on the provided context.

   This is a low-level function and should not be used directly
   unless a custom context object is provided.  Use EVRPC_MAKE_REQUEST()
   instead.

   @param ctx a context from EVRPC_MAKE_CTX()
   @returns 0 on success, -1 otherwise.
   @see EVRPC_MAKE_REQUEST(), EVRPC_MAKE_CTX()
*/
int evrpc_make_request(struct evrpc_request_wrapper *ctx);

/** creates an rpc connection pool
 *
 * a pool has a number of connections associated with it.
 * rpc requests are always made via a pool.
 *
 * @param base a pointer to an struct event_based object; can be left NULL
 *   in singled-threaded applications
 * @return a newly allocated struct evrpc_pool object
 * @see evrpc_pool_free()
 */
struct evrpc_pool *evrpc_pool_new(struct event_base *base);
/** frees an rpc connection pool
 *
 * @param pool a pointer to an evrpc_pool allocated via evrpc_pool_new()
 * @see evrpc_pool_new()
 */
void evrpc_pool_free(struct evrpc_pool *pool);

/**
 * Adds a connection over which rpc can be dispatched to the pool.
 *
 * The connection object must have been newly created.
 *
 * @param pool the pool to which to add the connection
 * @param evcon the connection to add to the pool.
 */
void evrpc_pool_add_connection(struct evrpc_pool *pool,
    struct evhttp_connection *evcon);

/**
 * Removes a connection from the pool.
 *
 * The connection object must have been newly created.
 *
 * @param pool the pool from which to remove the connection
 * @param evcon the connection to remove from the pool.
 */
void evrpc_pool_remove_connection(struct evrpc_pool *pool,
    struct evhttp_connection *evcon);

/**
 * Sets the timeout in secs after which a request has to complete.  The
 * RPC is completely aborted if it does not complete by then.  Setting
 * the timeout to 0 means that it never timeouts and can be used to
 * implement callback type RPCs.
 *
 * Any connection already in the pool will be updated with the new
 * timeout.  Connections added to the pool after set_timeout has be
 * called receive the pool timeout only if no timeout has been set
 * for the connection itself.
 *
 * @param pool a pointer to a struct evrpc_pool object
 * @param timeout_in_secs the number of seconds after which a request should
 *   timeout and a failure be returned to the callback.
 */
void evrpc_pool_set_timeout(struct evrpc_pool *pool, int timeout_in_secs);

/**
 * Hooks for changing the input and output of RPCs; this can be used to
 * implement compression, authentication, encryption, ...
 */

enum EVRPC_HOOK_TYPE {
	EVRPC_INPUT,		/**< apply the function to an input hook */
	EVRPC_OUTPUT		/**< apply the function to an output hook */
};

#ifndef _WIN32
/** Deprecated alias for EVRPC_INPUT.  Not available on windows, where it
 * conflicts with platform headers. */
#define INPUT EVRPC_INPUT
/** Deprecated alias for EVRPC_OUTPUT.  Not available on windows, where it
 * conflicts with platform headers. */
#define OUTPUT EVRPC_OUTPUT
#endif

/**
 * Return value from hook processing functions
 */

enum EVRPC_HOOK_RESULT {
	EVRPC_TERMINATE = -1,	/**< indicates the rpc should be terminated */
	EVRPC_CONTINUE = 0,	/**< continue processing the rpc */
	EVRPC_PAUSE = 1		/**< pause processing request until resumed */
};

/** adds a processing hook to either an rpc base or rpc pool
 *
 * If a hook returns TERMINATE, the processing is aborted. On CONTINUE,
 * the request is immediately processed after the hook returns.  If the
 * hook returns PAUSE, request processing stops until evrpc_resume_request()
 * has been called.
 *
 * The add functions return handles that can be used for removing hooks.
 *
 * @param vbase a pointer to either struct evrpc_base or struct evrpc_pool
 * @param hook_type either INPUT or OUTPUT
 * @param cb the callback to call when the hook is activated
 * @param cb_arg an additional argument for the callback
 * @return a handle to the hook so it can be removed later
 * @see evrpc_remove_hook()
 */
void *evrpc_add_hook(void *vbase,
    enum EVRPC_HOOK_TYPE hook_type,
    int (*cb)(void *, struct evhttp_request *, struct evbuffer *, void *),
    void *cb_arg);

/** removes a previously added hook
 *
 * @param vbase a pointer to either struct evrpc_base or struct evrpc_pool
 * @param hook_type either INPUT or OUTPUT
 * @param handle a handle returned by evrpc_add_hook()
 * @return 1 on success or 0 on failure
 * @see evrpc_add_hook()
 */
int evrpc_remove_hook(void *vbase,
    enum EVRPC_HOOK_TYPE hook_type,
    void *handle);

/** resume a paused request
 *
 * @param vbase a pointer to either struct evrpc_base or struct evrpc_pool
 * @param ctx the context pointer provided to the original hook call
 */
int
evrpc_resume_request(void *vbase, void *ctx, enum EVRPC_HOOK_RESULT res);

/** adds meta data to request
 *
 * evrpc_hook_add_meta() allows hooks to add meta data to a request. for
 * a client request, the meta data can be inserted by an outgoing request hook
 * and retrieved by the incoming request hook.
 *
 * @param ctx the context provided to the hook call
 * @param key a NUL-terminated c-string
 * @param data the data to be associated with the key
 * @param data_size the size of the data
 */
void evrpc_hook_add_meta(void *ctx, const char *key,
    const void *data, size_t data_size);

/** retrieves meta data previously associated
 *
 * evrpc_hook_find_meta() can be used to retrieve meta data associated to a
 * request by a previous hook.
 * @param ctx the context provided to the hook call
 * @param key a NUL-terminated c-string
 * @param data pointer to a data pointer that will contain the retrieved data
 * @param data_size pointer to the size of the data
 * @return 0 on success or -1 on failure
 */
int evrpc_hook_find_meta(void *ctx, const char *key,
    void **data, size_t *data_size);

/**
 * returns the connection object associated with the request
 *
 * @param ctx the context provided to the hook call
 * @return a pointer to the evhttp_connection object
 */
struct evhttp_connection *evrpc_hook_get_connection(void *ctx);

/**
   Function for sending a generic RPC request.

   Do not call this function directly, use EVRPC_MAKE_REQUEST() instead.

   @see EVRPC_MAKE_REQUEST()
 */
int evrpc_send_request_generic(struct evrpc_pool *pool,
    void *request, void *reply,
    void (*cb)(struct evrpc_status *, void *, void *, void *),
    void *cb_arg,
    const char *rpcname,
    void (*req_marshal)(struct evbuffer *, void *),
    void (*rpl_clear)(void *),
    int (*rpl_unmarshal)(void *, struct evbuffer *));

/**
   Function for registering a generic RPC with the RPC base.

   Do not call this function directly, use EVRPC_REGISTER() instead.

   @see EVRPC_REGISTER()
 */
int
evrpc_register_generic(struct evrpc_base *base, const char *name,
    void (*callback)(struct evrpc_req_generic *, void *), void *cbarg,
    void *(*req_new)(void *), void *req_new_arg, void (*req_free)(void *),
    int (*req_unmarshal)(void *, struct evbuffer *),
    void *(*rpl_new)(void *), void *rpl_new_arg, void (*rpl_free)(void *),
    int (*rpl_complete)(void *),
    void (*rpl_marshal)(struct evbuffer *, void *));

/** accessors for obscure and undocumented functionality */
struct evrpc_pool* evrpc_request_get_pool(struct evrpc_request_wrapper *ctx);
void evrpc_request_set_pool(struct evrpc_request_wrapper *ctx,
    struct evrpc_pool *pool);
void evrpc_request_set_cb(struct evrpc_request_wrapper *ctx,
    void (*cb)(struct evrpc_status*, void *request, void *reply, void *arg),
    void *cb_arg);

#ifdef __cplusplus
}
#endif

#endif /* EVENT2_RPC_H_INCLUDED_ */

NineSec Team - 2022