ÿØÿà JFIF    ÿÛ „  ( %"1!%)+...383,7(-.+  -+++--++++---+-+-----+---------------+---+-++7-----ÿÀ  ß â" ÿÄ     ÿÄ H    !1AQaq"‘¡2B±ÁÑð#R“Ò Tbr‚²á3csƒ’ÂñDS¢³$CÿÄ   ÿÄ %  !1AQa"23‘ÿÚ   ? ôÿ ¨pŸªáÿ —åYõõ\?àÒü©ŠÄï¨pŸªáÿ —åYõõ\?àÓü©ŠÄá 0Ÿªáÿ Ÿå[úƒ ú®ði~TÁbqÐ8OÕpÿ ƒOò¤Oè`–RÂáœá™êi€ßÉ< FtŸI“öÌ8úDf´°å}“¾œ6  öFá°y¥jñÇh†ˆ¢ã/ÃÐ:ªcÈ "Y¡ðÑl>ÿ ”ÏËte:qž\oäŠe÷󲍷˜HT4&ÿ ÓÐü6ö®¿øþßèô Ÿ•7Ñi’•j|“ñì>b…þS?*Óôÿ ÓÐü*h¥£ír¶ü UãS炟[AÐaè[ûª•õ&õj?†Éö+EzP—WeÒírJFt ‘BŒ†Ï‡%#tE Øz ¥OÛ«!1›üä±Í™%ºÍãö]°î(–:@<‹ŒÊö×òÆt¦ãº+‡¦%ÌÁ²h´OƒJŒtMÜ>ÀÜÊw3Y´•牋4ǍýʏTì>œú=Íwhyë,¾Ôò×õ¿ßÊa»«þˆѪQ|%6ž™A õ%:øj<>É—ÿ Å_ˆCbõ¥š±ý¯Ýƒï…¶|RëócÍf溪“t.СøTÿ *Ä¿-{†çàczůŽ_–^XþŒ±miB[X±d 1,é”zEù»& î9gœf™9Ð'.;—™i}!ôšåîqêÛ٤ёý£½ÆA–àôe"A$˝Úsäÿ ÷Û #°xŸëí(l »ý3—¥5m! rt`†0~'j2(]S¦¦kv,ÚÇ l¦øJA£Šƒ J3E8ÙiŽ:cÉžúeZ°€¯\®kÖ(79«Ž:¯X”¾³Š&¡* ….‰Ž(ÜíŸ2¥ª‡×Hi²TF¤ò[¨íÈRëÉ䢍mgÑ.Ÿ<öäS0í„ǹÁU´f#Vß;Õ–…P@3ío<ä-±»Ž.L|kªÀê›fÂ6@»eu‚|ÓaÞÆŸ…¨ááå>åŠ?cKü6ùTÍÆ”†sĤÚ;H2RÚ†õ\Ö·Ÿn'¾ ñ#ºI¤Å´%çÁ­‚â7›‹qT3Iï¨ÖÚ5I7Ë!ÅOóŸ¶øÝñØôת¦$Tcö‘[«Ö³šÒ';Aþ ¸èíg A2Z"i¸vdÄ÷.iõ®§)¿]¤À†–‡É&ä{V¶iŽ”.Ó×Õÿ û?h¬Mt–íª[ÿ Ñÿ ÌV(í}=ibÔ¡›¥¢±b Lô¥‡piη_Z<‡z§èŒ)iÖwiÇ 2hÙ3·=’d÷8éŽ1¦¸c¤µ€7›7Ø ð\á)} ¹fËí›pAÃL%âc2 í§æQz¿;T8sæ°qø)QFMð‰XŒÂ±N¢aF¨…8¯!U  Z©RÊ ÖPVÄÀÍin™Ì-GˆªÅËŠ›•zË}º±ŽÍFò¹}Uw×#ä5B¤{î}Ð<ÙD é©¤&‡ïDbàÁôMÁ." ¤‡ú*õ'VŽ|¼´Úgllº¼klz[Æüï÷Aób‡Eÿ dÑ»Xx9ÃÜ£ÁT/`¼¸vI±Ýµ·Ë‚“G³þ*Ÿû´r|*}<¨îºœ @¦mÄ’M¹”.œ«Y–|6ÏU¤jç¥ÕÞqO ˜kDÆÁ¨5ÿ š;ÐЦ¦€GÙk \ –Þ=â¼=SͧµªS°ÚÍpÜãQűÀõ¬?ÃÁ1Ñ•õZà?hóœ€ L¦l{Y*K˜Ù›zc˜–ˆâ ø+¾ ­-Ök¥%ùEÜA'}ˆ><ÊIè“bpÍ/qÞâvoX€w,\úªò6Z[XdÒæ­@Ö—€$òJí#é>'°Ú ôª˜<)4ryÙ£|óAÅn5žêŸyÒäMÝ2{"}‰–¤l÷ûWX\l¾Á¸góÉOÔ /óñB¤f¸çñ[.P˜ZsÊË*ßT܈§QN¢’¡¨§V¼(Üù*eÕ“”5T¨‹Âê¥FŒã½Dü[8'Ò¥a…Ú¶k7a *•›¼'Ò·\8¨ª\@\õ¢¦íq+DÙrmÎ…_ªæ»ŠÓœ¡¯’Ré9MÅ×D™lælffc+ŒÑ,ý™ÿ ¯þǤ=Å’Á7µ÷ÚÛ/“Ü€ñýã¼àí¾ÕÑ+ƒ,uµMâÀÄbm:ÒÎPæ{˜Gz[ƒ¯«® KHà`ߨŠéí¯P8Aq.C‰ à€kòpj´kN¶qô€…Õ,ÜNŠª-­{Zö’æû44‰sŽè‰îVíRœÕm" 6?³D9¡ÇTíÅꋇ`4«¸ÝÁô ï’ýorqКÇZ«x4Žâéþuïf¹µö[P ,Q£éaX±`PÉÍZ ¸äYúg üAx ’6Lê‚xÝÓ*äQ  Ï’¨hÍ =²,6ï#rÃ<¯–£»ƒ‹,–ê•€ aÛsñ'%Æ"®ÛüìBᝠHÚ3ß°©$“XnœÖ’î2ËTeûìxîß ¦å¿çÉ ðK§þ{‘t‚Ϋ¬jéîZ[ ”š7L¥4VÚCE×]m¤Øy”ä4-dz£œ§¸x.*ãÊÊ b÷•h:©‡¦s`BTÁRû¾g⻩‹jø sF¢àJøFl‘È•Xᓁà~*j¯ +(ÚÕ6-£¯÷GŠØy‚<Ç’.F‹Hœw(+)ÜÜâÈzÄäT§FߘãÏ;DmVœ3Àu@mÚüXÝü•3B¨òÌÁÛ<·ÃÜ z,Ì@õÅ·d2]ü8s÷IôÞ¯^Ç9¢u„~ëAŸï4«M? K]­ÅàPl@s_ p:°¬ZR”´›JC[CS.h‹ƒïËœ«Æ]–÷ó‚wR×k7X‰k›‘´ù¦=¡«‰¨¨Â')—71ó’c‡Ðúµ `é.{§p¹ój\Ž{1h{o±Ý=áUÊïGÖŒõ–-BÄm+AZX¶¡ ïHðæ¥JmÙ;…䡟ˆ¦ ° äšiÉg«$üMk5¤L“’çÊvïâï ,=f“"íἊ5ô¬x6{ɏžID0e¸vçmi'︧ºð9$ò¹÷*£’9ÿ ²TÔ…×>JV¥}Œ}$p[bÔ®*[jzS*8 ”·T›Í–ñUîƒwo$áè=LT™ç—~ô·¤ÈÚ$榍q‰„+´kFm)ž‹©i–ËqÞŠ‰à¶ü( ‚•§ •°ò·‡#5ª•µÊ﯅¡X¨šÁ*F#TXJÊ ušJVÍ&=iÄs1‚3•'fý§5Ñ<=[íÞ­ PÚ;ѱÌ_~Ä££8rÞ ²w;’hDT°>ÈG¬8Á²ÚzŽ®ò®qZcqJêäÞ-ö[ܘbň±çb“ж31²n×iƒðÕ;1¶þÉ ªX‰,ßqÏ$>•î íZ¥Z 1{ç൵+ƒÕµ¥°T$§K]á»Ûï*·¤tMI’ÂZbŽÕiÒ˜}bÓ0£ª5›¨ [5Ž^ÝœWøÂÝh° ¢OWun£¤5 a2Z.G2³YL]jåtì”ä ÁÓ‘%"©<Ôúʰsº UZvä‡ÄiÆÒM .÷V·™ø#kèýiíÌ–ª)µT[)BˆõÑ xB¾B€ÖT¨.¥~ð@VĶr#¸ü*åZNDŽH;âi ],©£öØpù(šºãö¼T.uCê•4@ÿ GÕÛ)Cx›®0ø#:ÏðFÒbR\(€€Ä®fã4Þ‰Fä¯HXƒÅ,†öEÑÔÜ]Öv²?tLÃvBY£ú6Êu5ÅAQ³1‘’¬x–HŒÐ‡ ^ ¸KwJôÖŽ5×CÚ¨vÜ«/B0$×k°=ðbÇ(Ï)w±A†Á† 11Í=èQšµ626ŒÜ/`G«µ<}—-Ö7KEHÈÉðóȤmݱû±·ø«Snmá=“䫚mݱŸ¡¶~ó·“äUóJæúòB|E LêŽy´jDÔ$G¢þÐñ7óR8ýÒ…Ç› WVe#·Ÿ p·Fx~•ݤF÷0Èÿ K¯æS<6’¡WШ; ´ÿ ¥Êø\Òuî†åÝ–VNœkÒ7oòX¨Á­Ø÷FÎÑä±g÷ÿ M~Çî=p,X´ ÝÌÚÅ‹’ÃjÖ.ØöÏñ qïQ¤ÓZE†° =6·]܈ s¸>v•Ž^Ý\wq9r‰Î\¸¡kURÒ$­*‹Nq?Þª*!sŠÆ:TU_u±T+øX¡ ®¹¡,ÄâÃBTsÜ$Ø›4m椴zÜK]’’›Pƒ @€#â˜`é¹=I‡fiV•Ôî“nRm+µFPOhÍ0B£ €+¬5c v•:P'ÒyÎ ‰V~‚Ó†ÖuókDoh$å\*ö%Ю=£«…aȼ½÷Û.-½VŒŠ¼'lyî±1¬3ó#ÞE¿ÔS¤gV£m›=§\û"—WU¤ÚǼÿ ÂnÁGŒÃ ‚õN D³õNÚíŒÕ;HôyÄÈ©P¹Ä{:?R‘Ô¨âF÷ø£bÅó® JS|‚R÷ivýáâ€Æé¡è³´IئÑT!§˜•ت‚¬â@q€wnïCWÄ@JU€ê¯m6]Ï:£âx'+ÒðXvÓ¦Úm=–´7œ $ì“B£~p%ÕŸUþ« N@¼üï~w˜ñø5®—'Ôe»¤5ã//€ž~‰Tþ›Å7•#¤× Íö pÄ$ùeåì*«ÓŠEØWEÈsßg ¦ûvžSsLpºÊW–âµEWöˬH; ™!CYõZ ÃÄf æ#1W. \uWâ\,\Çf j’<qTbên›Î[vxx£ë 'ö¨1›˜ÀM¼Pÿ H)ƒêêŒA7s,|F“ 꺸k³9Ìö*ç®;Ö!Ö$Eiž•¹ÒÚ†ýóéÝû¾ÕS®ó$’NÝäŸz¤5r¦ãÄÃD÷Üø!°ø‡Ô&@m™Ì^Ãä­d q5Lnÿ N;.6½·N|#ä"1Nƒx“ã<3('&ñßt  ~ªu”1Tb㫨9ê–›–bìd$ߣ=#ÕãÒmU¯eí$EFù5ýYô櫨æì™Ç—±ssM]·á¿0ÕåJRÓªîiƒ+O58ÖñªŠÒx" \µâá¨i’¤i —Ö ” M+M¤ë9‚‰A¦°Qõ¾ßøK~¼Ã‘g…Ö´~÷Ï[3GUœÒ½#…kàÔ®Ò”‰³·dWV‰IP‰Ú8u¹”E ÖqLj¾êÕCBš{A^Âß;–¨`¯¬ìö ˼ ×tìø.tƐm*n¨y4o&Àx¥n¦×î‡aupáÛj8¿m›è¶ã!o½;ß0y^ý×^EÑ¿ÒjzŒ­)vÚÑnÄL …^ªô× ‡—‚3k Îý­hï]içå–îÏ*÷ñþ»Ô CÒjøjÍznˆ´ ¹#b'Fô‹ ‰v¥'’à'T´ƒHýÍ%M‰ ƒ&ÆÇŒï1 ‘ –Þ ‰i¬s žR-Ÿ kЬá¬7:þ 0ŒÅÒÕ/aÙ¬ÃÝ#Úøœ ©aiVc‰. ¹¦ãµ” ›Yg¦›ÆÎýº°f³7ƒhá·¸­}&D9¡ÂsÉÙÞèŠõØàC™¨ñbFC|´Ü(ŸƒÚÒ-%»'a Ì¿)ËÇn¿úÿ ÞŽX…4ÊÅH^ôΑí@ù¹Eh¶“L8Çjù ¼ÎåVªóR©Ï5uà V4lZß®=€xÖŸ–ÑÈ ÷”¨°¾__yM1tÉ?uÆþIkÄgæ@þ[¢†°XÃJ£j·:nkÅ¢u ‘}âGzö­/IµèЬ¼48q¦F°ŽR¼=ûì{´¯RýicS ÕÛ íNtÍÙï£,w4rêì®»~x(©Uñ§#Ñ&œÕ¤>ÎåÍÓ9’Ö{9eV­[Öjâ²ãu]˜å2›qÑšÕJç0€sÄ|Êëè0튔bÁ>“{×_F`Ø©ºê:µä,v¤ðfc1±"«ÔÍän1#=· Âøv~H½ÐßA¾¿Ü€Óš]Õ; I¾÷ç‚Qi†î¹9ywÔKG˜áñ zQY—§ÃÕZ07§X‚ Áh;ÁM)iÌCH-¯T‘ë|A0{Ò½LÚ–TâÖkÜ’dÀ“rmm»”جPF³ÖcbE§T€ÒxKºû’Ó®7±²(\4ŽÃ¸Uu@j™yĵ;³µ!Á¢b.W¤=mõ´êµK k ¸K^ÜÛ#p*Ü14qkZç5ïë †°5Ï%ÍÛ<Õ¤×Ô¥ê†C Õ´¼ú$ƒÖ“”]Ù¬qÞÚ[4©ý!ûÏ—Áb쳐XµA¬â~`›Çr¸8ìùÝ䫦<>ä÷«?xs´ÇÑ /á;¹øüÊÈÙà{"@Žïzâ¬[âß‚ U_<ÇŸ½4èN˜ú61®qŠu ¦þF£»äJ_ˆÙÎ~ ÞAã–݄ϗrŠD;xTž‘ô`É«…suãO`?³à™ô Lý#Íc5öoæØ‚y´´÷«ZR§<&JÇ+éâô´€i!Àˆ0æAoàðLèÖ-2ŸõW.’t^–(KÁmHµV@xÜÇy®Ñø­â^:Ú3w· 7½¹°ñ¸â¹®:',«Mœ—n­Á+Ãbš LÈ‘ÄnRÓÅœ%¦²‰¨ùQ:¤f‚ "PÕtô¸…cæl…&˜Ú˜Ôkv‹ž+vŠ,=¢v­6—Xy*¥t£«<™:“aîϲ=¦6rO]XI¿Œ÷¤zÚ­›¶ 6÷”w\d ü~v®ˆÌk«^m<ÿ ¢‰Õ\)ùºŽ;… lîÙÅEŠ®cѾ@vnMÏ,¼“ñ•ŽBxðÃzãÇç%3ˆ"}Ù•Åî> BÉú;Ò]V+P˜F_´ßé> Øše|ï‡ÄOmFæÇ ãqÞ$/xÐx­z`ï9"œÜij‚!7.\Td…9M‡•iŽ‹¾‘50ÞŽn¥ß4ÉôO ¹*í^QêËÜÇÌ8=ާs‰'ÂëÙ«á%Pú[O †ÅP¯Vsް.‰,kc¶ ¬A9n˜XÎ-ÞšN["¹QÕ‰ƒMýÁߺXJæÍaLj¾×Ãmã¾ãÚ uñÒþåQô¦¥ /ÄUx:‚ÍÜ’ Đ©ØÝ3V¨‰ÕnÐ6ó*óúK­«…c ¯U òhsý­jóÔj#,ímŒRµ«lbïUTŒÑ8†Ä0œÏr`ð¡¬É Ї ë"À² ™ 6¥ f¶ ¢ÚoܱԷ-<Àî)†a¶ž'Ú»¨TXqØæ¶÷YÄHy˜9ÈIW­YÀuMFë ºÏ’AqÌ4·/Ú †ô'i$øä­=Ä Ý|öK×40è|È6p‘0§)o¥ctî§H+CA-“ xØ|ÐXАç l8íºð3Ø:³¤¬KX¯UÿÙ * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /** * base class */ require_once 'PEAR/Command/Common.php'; /** * PEAR commands for registry manipulation * * @category pear * @package PEAR * @author Stig Bakken * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.16 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ class PEAR_Command_Registry extends PEAR_Command_Common { var $commands = array( 'list' => array( 'summary' => 'List Installed Packages In The Default Channel', 'function' => 'doList', 'shortcut' => 'l', 'options' => array( 'channel' => array( 'shortopt' => 'c', 'doc' => 'list installed packages from this channel', 'arg' => 'CHAN', ), 'allchannels' => array( 'shortopt' => 'a', 'doc' => 'list installed packages from all channels', ), 'channelinfo' => array( 'shortopt' => 'i', 'doc' => 'output fully channel-aware data, even on failure', ), ), 'doc' => ' If invoked without parameters, this command lists the PEAR packages installed in your php_dir ({config php_dir}). With a parameter, it lists the files in a package. ', ), 'list-files' => array( 'summary' => 'List Files In Installed Package', 'function' => 'doFileList', 'shortcut' => 'fl', 'options' => array(), 'doc' => ' List the files in an installed package. ' ), 'shell-test' => array( 'summary' => 'Shell Script Test', 'function' => 'doShellTest', 'shortcut' => 'st', 'options' => array(), 'doc' => ' [[relation] version] Tests if a package is installed in the system. Will exit(1) if it is not. The version comparison operator. One of: <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne The version to compare with '), 'info' => array( 'summary' => 'Display information about a package', 'function' => 'doInfo', 'shortcut' => 'in', 'options' => array(), 'doc' => ' Displays information about a package. The package argument may be a local package file, an URL to a package file, or the name of an installed package.' ) ); /** * PEAR_Command_Registry constructor. * * @access public */ function __construct(&$ui, &$config) { parent::__construct($ui, $config); } function _sortinfo($a, $b) { $apackage = isset($a['package']) ? $a['package'] : $a['name']; $bpackage = isset($b['package']) ? $b['package'] : $b['name']; return strcmp($apackage, $bpackage); } function doList($command, $options, $params) { $reg = &$this->config->getRegistry(); $channelinfo = isset($options['channelinfo']); if (isset($options['allchannels']) && !$channelinfo) { return $this->doListAll($command, array(), $params); } if (isset($options['allchannels']) && $channelinfo) { // allchannels with $channelinfo unset($options['allchannels']); $channels = $reg->getChannels(); $errors = array(); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); foreach ($channels as $channel) { $options['channel'] = $channel->getName(); $ret = $this->doList($command, $options, $params); if (PEAR::isError($ret)) { $errors[] = $ret; } } PEAR::staticPopErrorHandling(); if (count($errors)) { // for now, only give first error return PEAR::raiseError($errors[0]); } return true; } if (count($params) === 1) { return $this->doFileList($command, $options, $params); } if (isset($options['channel'])) { if (!$reg->channelExists($options['channel'])) { return $this->raiseError('Channel "' . $options['channel'] .'" does not exist'); } $channel = $reg->channelName($options['channel']); } else { $channel = $this->config->get('default_channel'); } $installed = $reg->packageInfo(null, null, $channel); usort($installed, array(&$this, '_sortinfo')); $data = array( 'caption' => 'Installed packages, channel ' . $channel . ':', 'border' => true, 'headline' => array('Package', 'Version', 'State'), 'channel' => $channel, ); if ($channelinfo) { $data['headline'] = array('Channel', 'Package', 'Version', 'State'); } if (count($installed) && !isset($data['data'])) { $data['data'] = array(); } foreach ($installed as $package) { $pobj = $reg->getPackage(isset($package['package']) ? $package['package'] : $package['name'], $channel); if ($channelinfo) { $packageinfo = array($pobj->getChannel(), $pobj->getPackage(), $pobj->getVersion(), $pobj->getState() ? $pobj->getState() : null); } else { $packageinfo = array($pobj->getPackage(), $pobj->getVersion(), $pobj->getState() ? $pobj->getState() : null); } $data['data'][] = $packageinfo; } if (count($installed) === 0) { if (!$channelinfo) { $data = '(no packages installed from channel ' . $channel . ')'; } else { $data = array( 'caption' => 'Installed packages, channel ' . $channel . ':', 'border' => true, 'channel' => $channel, 'data' => array(array('(no packages installed)')), ); } } $this->ui->outputData($data, $command); return true; } function doListAll($command, $options, $params) { // This duplicate code is deprecated over // list --channelinfo, which gives identical // output for list and list --allchannels. $reg = &$this->config->getRegistry(); $installed = $reg->packageInfo(null, null, null); foreach ($installed as $channel => $packages) { usort($packages, array($this, '_sortinfo')); $data = array( 'caption' => 'Installed packages, channel ' . $channel . ':', 'border' => true, 'headline' => array('Package', 'Version', 'State'), 'channel' => $channel ); foreach ($packages as $package) { $p = isset($package['package']) ? $package['package'] : $package['name']; $pobj = $reg->getPackage($p, $channel); $data['data'][] = array($pobj->getPackage(), $pobj->getVersion(), $pobj->getState() ? $pobj->getState() : null); } // Adds a blank line after each section $data['data'][] = array(); if (count($packages) === 0) { $data = array( 'caption' => 'Installed packages, channel ' . $channel . ':', 'border' => true, 'data' => array(array('(no packages installed)'), array()), 'channel' => $channel ); } $this->ui->outputData($data, $command); } return true; } function doFileList($command, $options, $params) { if (count($params) !== 1) { return $this->raiseError('list-files expects 1 parameter'); } $reg = &$this->config->getRegistry(); $fp = false; if (!is_dir($params[0]) && (file_exists($params[0]) || $fp = @fopen($params[0], 'r'))) { if ($fp) { fclose($fp); } if (!class_exists('PEAR_PackageFile')) { require_once 'PEAR/PackageFile.php'; } $pkg = new PEAR_PackageFile($this->config, $this->_debug); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $info = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL); PEAR::staticPopErrorHandling(); $headings = array('Package File', 'Install Path'); $installed = false; } else { PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel')); PEAR::staticPopErrorHandling(); if (PEAR::isError($parsed)) { return $this->raiseError($parsed); } $info = &$reg->getPackage($parsed['package'], $parsed['channel']); $headings = array('Type', 'Install Path'); $installed = true; } if (PEAR::isError($info)) { return $this->raiseError($info); } if ($info === null) { return $this->raiseError("`$params[0]' not installed"); } $list = ($info->getPackagexmlVersion() == '1.0' || $installed) ? $info->getFilelist() : $info->getContents(); if ($installed) { $caption = 'Installed Files For ' . $params[0]; } else { $caption = 'Contents of ' . basename($params[0]); } $data = array( 'caption' => $caption, 'border' => true, 'headline' => $headings); if ($info->getPackagexmlVersion() == '1.0' || $installed) { foreach ($list as $file => $att) { if ($installed) { if (empty($att['installed_as'])) { continue; } $data['data'][] = array($att['role'], $att['installed_as']); } else { if (isset($att['baseinstalldir']) && !in_array($att['role'], array('test', 'data', 'doc'))) { $dest = $att['baseinstalldir'] . DIRECTORY_SEPARATOR . $file; } else { $dest = $file; } switch ($att['role']) { case 'test': case 'data': case 'doc': $role = $att['role']; if ($role == 'test') { $role .= 's'; } $dest = $this->config->get($role . '_dir') . DIRECTORY_SEPARATOR . $info->getPackage() . DIRECTORY_SEPARATOR . $dest; break; case 'php': default: $dest = $this->config->get('php_dir') . DIRECTORY_SEPARATOR . $dest; } $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; $dest = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"), array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $dest); $file = preg_replace('!/+!', '/', $file); $data['data'][] = array($file, $dest); } } } else { // package.xml 2.0, not installed if (!isset($list['dir']['file'][0])) { $list['dir']['file'] = array($list['dir']['file']); } foreach ($list['dir']['file'] as $att) { $att = $att['attribs']; $file = $att['name']; $role = &PEAR_Installer_Role::factory($info, $att['role'], $this->config); $role->setup($this, $info, $att, $file); if (!$role->isInstallable()) { $dest = '(not installable)'; } else { $dest = $role->processInstallation($info, $att, $file, ''); if (PEAR::isError($dest)) { $dest = '(Unknown role "' . $att['role'] . ')'; } else { list(,, $dest) = $dest; } } $data['data'][] = array($file, $dest); } } $this->ui->outputData($data, $command); return true; } function doShellTest($command, $options, $params) { if (count($params) < 1) { return PEAR::raiseError('ERROR, usage: pear shell-test packagename [[relation] version]'); } PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $reg = &$this->config->getRegistry(); $info = $reg->parsePackageName($params[0], $this->config->get('default_channel')); if (PEAR::isError($info)) { exit(1); // invalid package name } $package = $info['package']; $channel = $info['channel']; // "pear shell-test Foo" if (!$reg->packageExists($package, $channel)) { if ($channel == 'pecl.php.net') { if ($reg->packageExists($package, 'pear.php.net')) { $channel = 'pear.php.net'; // magically change channels for extensions } } } if (count($params) === 1) { if (!$reg->packageExists($package, $channel)) { exit(1); } // "pear shell-test Foo 1.0" } elseif (count($params) === 2) { $v = $reg->packageInfo($package, 'version', $channel); if (!$v || !version_compare("$v", "{$params[1]}", "ge")) { exit(1); } // "pear shell-test Foo ge 1.0" } elseif (count($params) === 3) { $v = $reg->packageInfo($package, 'version', $channel); if (!$v || !version_compare("$v", "{$params[2]}", $params[1])) { exit(1); } } else { PEAR::staticPopErrorHandling(); $this->raiseError("$command: expects 1 to 3 parameters"); exit(1); } } function doInfo($command, $options, $params) { if (count($params) !== 1) { return $this->raiseError('pear info expects 1 parameter'); } $info = $fp = false; $reg = &$this->config->getRegistry(); if (is_file($params[0]) && !is_dir($params[0]) && (file_exists($params[0]) || $fp = @fopen($params[0], 'r')) ) { if ($fp) { fclose($fp); } if (!class_exists('PEAR_PackageFile')) { require_once 'PEAR/PackageFile.php'; } $pkg = new PEAR_PackageFile($this->config, $this->_debug); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $obj = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL); PEAR::staticPopErrorHandling(); if (PEAR::isError($obj)) { $uinfo = $obj->getUserInfo(); if (is_array($uinfo)) { foreach ($uinfo as $message) { if (is_array($message)) { $message = $message['message']; } $this->ui->outputData($message); } } return $this->raiseError($obj); } if ($obj->getPackagexmlVersion() != '1.0') { return $this->_doInfo2($command, $options, $params, $obj, false); } $info = $obj->toArray(); } else { $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel')); if (PEAR::isError($parsed)) { return $this->raiseError($parsed); } $package = $parsed['package']; $channel = $parsed['channel']; $info = $reg->packageInfo($package, null, $channel); if (isset($info['old'])) { $obj = $reg->getPackage($package, $channel); return $this->_doInfo2($command, $options, $params, $obj, true); } } if (PEAR::isError($info)) { return $info; } if (empty($info)) { $this->raiseError("No information found for `$params[0]'"); return; } unset($info['filelist']); unset($info['dirtree']); unset($info['changelog']); if (isset($info['xsdversion'])) { $info['package.xml version'] = $info['xsdversion']; unset($info['xsdversion']); } if (isset($info['packagerversion'])) { $info['packaged with PEAR version'] = $info['packagerversion']; unset($info['packagerversion']); } $keys = array_keys($info); $longtext = array('description', 'summary'); foreach ($keys as $key) { if (is_array($info[$key])) { switch ($key) { case 'maintainers': { $i = 0; $mstr = ''; foreach ($info[$key] as $m) { if ($i++ > 0) { $mstr .= "\n"; } $mstr .= $m['name'] . " <"; if (isset($m['email'])) { $mstr .= $m['email']; } else { $mstr .= $m['handle'] . '@php.net'; } $mstr .= "> ($m[role])"; } $info[$key] = $mstr; break; } case 'release_deps': { $i = 0; $dstr = ''; foreach ($info[$key] as $d) { if (isset($this->_deps_rel_trans[$d['rel']])) { $rel = $this->_deps_rel_trans[$d['rel']]; } else { $rel = $d['rel']; } if (isset($this->_deps_type_trans[$d['type']])) { $type = ucfirst($this->_deps_type_trans[$d['type']]); } else { $type = $d['type']; } if (isset($d['name'])) { $name = $d['name'] . ' '; } else { $name = ''; } if (isset($d['version'])) { $version = $d['version'] . ' '; } else { $version = ''; } if (isset($d['optional']) && $d['optional'] == 'yes') { $optional = ' (optional)'; } else { $optional = ''; } $dstr .= "$type $name$rel $version$optional\n"; } $info[$key] = $dstr; break; } case 'provides' : { $debug = $this->config->get('verbose'); if ($debug < 2) { $pstr = 'Classes: '; } else { $pstr = ''; } $i = 0; foreach ($info[$key] as $p) { if ($debug < 2 && $p['type'] != "class") { continue; } // Only print classes when verbosity mode is < 2 if ($debug < 2) { if ($i++ > 0) { $pstr .= ", "; } $pstr .= $p['name']; } else { if ($i++ > 0) { $pstr .= "\n"; } $pstr .= ucfirst($p['type']) . " " . $p['name']; if (isset($p['explicit']) && $p['explicit'] == 1) { $pstr .= " (explicit)"; } } } $info[$key] = $pstr; break; } case 'configure_options' : { foreach ($info[$key] as $i => $p) { $info[$key][$i] = array_map(null, array_keys($p), array_values($p)); $info[$key][$i] = array_map( function($a) { return join(" = ", $a); }, $info[$key][$i]); $info[$key][$i] = implode(', ', $info[$key][$i]); } $info[$key] = implode("\n", $info[$key]); break; } default: { $info[$key] = implode(", ", $info[$key]); break; } } } if ($key == '_lastmodified') { $hdate = date('Y-m-d', $info[$key]); unset($info[$key]); $info['Last Modified'] = $hdate; } elseif ($key == '_lastversion') { $info['Previous Installed Version'] = $info[$key] ? $info[$key] : '- None -'; unset($info[$key]); } else { $info[$key] = trim($info[$key]); if (in_array($key, $longtext)) { $info[$key] = preg_replace('/ +/', ' ', $info[$key]); } } } $caption = 'About ' . $info['package'] . '-' . $info['version']; $data = array( 'caption' => $caption, 'border' => true); foreach ($info as $key => $value) { $key = ucwords(trim(str_replace('_', ' ', $key))); $data['data'][] = array($key, $value); } $data['raw'] = $info; $this->ui->outputData($data, 'package-info'); } /** * @access private */ function _doInfo2($command, $options, $params, &$obj, $installed) { $reg = &$this->config->getRegistry(); $caption = 'About ' . $obj->getChannel() . '/' .$obj->getPackage() . '-' . $obj->getVersion(); $data = array( 'caption' => $caption, 'border' => true); switch ($obj->getPackageType()) { case 'php' : $release = 'PEAR-style PHP-based Package'; break; case 'extsrc' : $release = 'PECL-style PHP extension (source code)'; break; case 'zendextsrc' : $release = 'PECL-style Zend extension (source code)'; break; case 'extbin' : $release = 'PECL-style PHP extension (binary)'; break; case 'zendextbin' : $release = 'PECL-style Zend extension (binary)'; break; case 'bundle' : $release = 'Package bundle (collection of packages)'; break; } $extends = $obj->getExtends(); $extends = $extends ? $obj->getPackage() . ' (extends ' . $extends . ')' : $obj->getPackage(); if ($src = $obj->getSourcePackage()) { $extends .= ' (source package ' . $src['channel'] . '/' . $src['package'] . ')'; } $info = array( 'Release Type' => $release, 'Name' => $extends, 'Channel' => $obj->getChannel(), 'Summary' => preg_replace('/ +/', ' ', $obj->getSummary()), 'Description' => preg_replace('/ +/', ' ', $obj->getDescription()), ); $info['Maintainers'] = ''; foreach (array('lead', 'developer', 'contributor', 'helper') as $role) { $leads = $obj->{"get{$role}s"}(); if (!$leads) { continue; } if (isset($leads['active'])) { $leads = array($leads); } foreach ($leads as $lead) { if (!empty($info['Maintainers'])) { $info['Maintainers'] .= "\n"; } $active = $lead['active'] == 'no' ? ', inactive' : ''; $info['Maintainers'] .= $lead['name'] . ' <'; $info['Maintainers'] .= $lead['email'] . "> ($role$active)"; } } $info['Release Date'] = $obj->getDate(); if ($time = $obj->getTime()) { $info['Release Date'] .= ' ' . $time; } $info['Release Version'] = $obj->getVersion() . ' (' . $obj->getState() . ')'; $info['API Version'] = $obj->getVersion('api') . ' (' . $obj->getState('api') . ')'; $info['License'] = $obj->getLicense(); $uri = $obj->getLicenseLocation(); if ($uri) { if (isset($uri['uri'])) { $info['License'] .= ' (' . $uri['uri'] . ')'; } else { $extra = $obj->getInstalledLocation($info['filesource']); if ($extra) { $info['License'] .= ' (' . $uri['filesource'] . ')'; } } } $info['Release Notes'] = $obj->getNotes(); if ($compat = $obj->getCompatible()) { if (!isset($compat[0])) { $compat = array($compat); } $info['Compatible with'] = ''; foreach ($compat as $package) { $info['Compatible with'] .= $package['channel'] . '/' . $package['name'] . "\nVersions >= " . $package['min'] . ', <= ' . $package['max']; if (isset($package['exclude'])) { if (is_array($package['exclude'])) { $package['exclude'] = implode(', ', $package['exclude']); } if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } $info['Not Compatible with'] .= $package['channel'] . '/' . $package['name'] . "\nVersions " . $package['exclude']; } } } $usesrole = $obj->getUsesrole(); if ($usesrole) { if (!isset($usesrole[0])) { $usesrole = array($usesrole); } foreach ($usesrole as $roledata) { if (isset($info['Uses Custom Roles'])) { $info['Uses Custom Roles'] .= "\n"; } else { $info['Uses Custom Roles'] = ''; } if (isset($roledata['package'])) { $rolepackage = $reg->parsedPackageNameToString($roledata, true); } else { $rolepackage = $roledata['uri']; } $info['Uses Custom Roles'] .= $roledata['role'] . ' (' . $rolepackage . ')'; } } $usestask = $obj->getUsestask(); if ($usestask) { if (!isset($usestask[0])) { $usestask = array($usestask); } foreach ($usestask as $taskdata) { if (isset($info['Uses Custom Tasks'])) { $info['Uses Custom Tasks'] .= "\n"; } else { $info['Uses Custom Tasks'] = ''; } if (isset($taskdata['package'])) { $taskpackage = $reg->parsedPackageNameToString($taskdata, true); } else { $taskpackage = $taskdata['uri']; } $info['Uses Custom Tasks'] .= $taskdata['task'] . ' (' . $taskpackage . ')'; } } $deps = $obj->getDependencies(); $info['Required Dependencies'] = 'PHP version ' . $deps['required']['php']['min']; if (isset($deps['required']['php']['max'])) { $info['Required Dependencies'] .= '-' . $deps['required']['php']['max'] . "\n"; } else { $info['Required Dependencies'] .= "\n"; } if (isset($deps['required']['php']['exclude'])) { if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } if (is_array($deps['required']['php']['exclude'])) { $deps['required']['php']['exclude'] = implode(', ', $deps['required']['php']['exclude']); } $info['Not Compatible with'] .= "PHP versions\n " . $deps['required']['php']['exclude']; } $info['Required Dependencies'] .= 'PEAR installer version'; if (isset($deps['required']['pearinstaller']['max'])) { $info['Required Dependencies'] .= 's ' . $deps['required']['pearinstaller']['min'] . '-' . $deps['required']['pearinstaller']['max']; } else { $info['Required Dependencies'] .= ' ' . $deps['required']['pearinstaller']['min'] . ' or newer'; } if (isset($deps['required']['pearinstaller']['exclude'])) { if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } if (is_array($deps['required']['pearinstaller']['exclude'])) { $deps['required']['pearinstaller']['exclude'] = implode(', ', $deps['required']['pearinstaller']['exclude']); } $info['Not Compatible with'] .= "PEAR installer\n Versions " . $deps['required']['pearinstaller']['exclude']; } foreach (array('Package', 'Extension') as $type) { $index = strtolower($type); if (isset($deps['required'][$index])) { if (isset($deps['required'][$index]['name'])) { $deps['required'][$index] = array($deps['required'][$index]); } foreach ($deps['required'][$index] as $package) { if (isset($package['conflicts'])) { $infoindex = 'Not Compatible with'; if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } } else { $infoindex = 'Required Dependencies'; $info[$infoindex] .= "\n"; } if ($index == 'extension') { $name = $package['name']; } else { if (isset($package['channel'])) { $name = $package['channel'] . '/' . $package['name']; } else { $name = '__uri/' . $package['name'] . ' (static URI)'; } } $info[$infoindex] .= "$type $name"; if (isset($package['uri'])) { $info[$infoindex] .= "\n Download URI: $package[uri]"; continue; } if (isset($package['max']) && isset($package['min'])) { $info[$infoindex] .= " \n Versions " . $package['min'] . '-' . $package['max']; } elseif (isset($package['min'])) { $info[$infoindex] .= " \n Version " . $package['min'] . ' or newer'; } elseif (isset($package['max'])) { $info[$infoindex] .= " \n Version " . $package['max'] . ' or older'; } if (isset($package['recommended'])) { $info[$infoindex] .= "\n Recommended version: $package[recommended]"; } if (isset($package['exclude'])) { if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } if (is_array($package['exclude'])) { $package['exclude'] = implode(', ', $package['exclude']); } $package['package'] = $package['name']; // for parsedPackageNameToString if (isset($package['conflicts'])) { $info['Not Compatible with'] .= '=> except '; } $info['Not Compatible with'] .= 'Package ' . $reg->parsedPackageNameToString($package, true); $info['Not Compatible with'] .= "\n Versions " . $package['exclude']; } } } } if (isset($deps['required']['os'])) { if (isset($deps['required']['os']['name'])) { $dep['required']['os']['name'] = array($dep['required']['os']['name']); } foreach ($dep['required']['os'] as $os) { if (isset($os['conflicts']) && $os['conflicts'] == 'yes') { if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } $info['Not Compatible with'] .= "$os[name] Operating System"; } else { $info['Required Dependencies'] .= "\n"; $info['Required Dependencies'] .= "$os[name] Operating System"; } } } if (isset($deps['required']['arch'])) { if (isset($deps['required']['arch']['pattern'])) { $dep['required']['arch']['pattern'] = array($dep['required']['os']['pattern']); } foreach ($dep['required']['arch'] as $os) { if (isset($os['conflicts']) && $os['conflicts'] == 'yes') { if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } $info['Not Compatible with'] .= "OS/Arch matching pattern '/$os[pattern]/'"; } else { $info['Required Dependencies'] .= "\n"; $info['Required Dependencies'] .= "OS/Arch matching pattern '/$os[pattern]/'"; } } } if (isset($deps['optional'])) { foreach (array('Package', 'Extension') as $type) { $index = strtolower($type); if (isset($deps['optional'][$index])) { if (isset($deps['optional'][$index]['name'])) { $deps['optional'][$index] = array($deps['optional'][$index]); } foreach ($deps['optional'][$index] as $package) { if (isset($package['conflicts']) && $package['conflicts'] == 'yes') { $infoindex = 'Not Compatible with'; if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } } else { $infoindex = 'Optional Dependencies'; if (!isset($info['Optional Dependencies'])) { $info['Optional Dependencies'] = ''; } else { $info['Optional Dependencies'] .= "\n"; } } if ($index == 'extension') { $name = $package['name']; } else { if (isset($package['channel'])) { $name = $package['channel'] . '/' . $package['name']; } else { $name = '__uri/' . $package['name'] . ' (static URI)'; } } $info[$infoindex] .= "$type $name"; if (isset($package['uri'])) { $info[$infoindex] .= "\n Download URI: $package[uri]"; continue; } if ($infoindex == 'Not Compatible with') { // conflicts is only used to say that all versions conflict continue; } if (isset($package['max']) && isset($package['min'])) { $info[$infoindex] .= " \n Versions " . $package['min'] . '-' . $package['max']; } elseif (isset($package['min'])) { $info[$infoindex] .= " \n Version " . $package['min'] . ' or newer'; } elseif (isset($package['max'])) { $info[$infoindex] .= " \n Version " . $package['min'] . ' or older'; } if (isset($package['recommended'])) { $info[$infoindex] .= "\n Recommended version: $package[recommended]"; } if (isset($package['exclude'])) { if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info['Not Compatible with'] .= "\n"; } if (is_array($package['exclude'])) { $package['exclude'] = implode(', ', $package['exclude']); } $info['Not Compatible with'] .= "Package $package\n Versions " . $package['exclude']; } } } } } if (isset($deps['group'])) { if (!isset($deps['group'][0])) { $deps['group'] = array($deps['group']); } foreach ($deps['group'] as $group) { $info['Dependency Group ' . $group['attribs']['name']] = $group['attribs']['hint']; $groupindex = $group['attribs']['name'] . ' Contents'; $info[$groupindex] = ''; foreach (array('Package', 'Extension') as $type) { $index = strtolower($type); if (isset($group[$index])) { if (isset($group[$index]['name'])) { $group[$index] = array($group[$index]); } foreach ($group[$index] as $package) { if (!empty($info[$groupindex])) { $info[$groupindex] .= "\n"; } if ($index == 'extension') { $name = $package['name']; } else { if (isset($package['channel'])) { $name = $package['channel'] . '/' . $package['name']; } else { $name = '__uri/' . $package['name'] . ' (static URI)'; } } if (isset($package['uri'])) { if (isset($package['conflicts']) && $package['conflicts'] == 'yes') { $info[$groupindex] .= "Not Compatible with $type $name"; } else { $info[$groupindex] .= "$type $name"; } $info[$groupindex] .= "\n Download URI: $package[uri]"; continue; } if (isset($package['conflicts']) && $package['conflicts'] == 'yes') { $info[$groupindex] .= "Not Compatible with $type $name"; continue; } $info[$groupindex] .= "$type $name"; if (isset($package['max']) && isset($package['min'])) { $info[$groupindex] .= " \n Versions " . $package['min'] . '-' . $package['max']; } elseif (isset($package['min'])) { $info[$groupindex] .= " \n Version " . $package['min'] . ' or newer'; } elseif (isset($package['max'])) { $info[$groupindex] .= " \n Version " . $package['min'] . ' or older'; } if (isset($package['recommended'])) { $info[$groupindex] .= "\n Recommended version: $package[recommended]"; } if (isset($package['exclude'])) { if (!isset($info['Not Compatible with'])) { $info['Not Compatible with'] = ''; } else { $info[$groupindex] .= "Not Compatible with\n"; } if (is_array($package['exclude'])) { $package['exclude'] = implode(', ', $package['exclude']); } $info[$groupindex] .= " Package $package\n Versions " . $package['exclude']; } } } } } } if ($obj->getPackageType() == 'bundle') { $info['Bundled Packages'] = ''; foreach ($obj->getBundledPackages() as $package) { if (!empty($info['Bundled Packages'])) { $info['Bundled Packages'] .= "\n"; } if (isset($package['uri'])) { $info['Bundled Packages'] .= '__uri/' . $package['name']; $info['Bundled Packages'] .= "\n (URI: $package[uri]"; } else { $info['Bundled Packages'] .= $package['channel'] . '/' . $package['name']; } } } $info['package.xml version'] = '2.0'; if ($installed) { if ($obj->getLastModified()) { $info['Last Modified'] = date('Y-m-d H:i', $obj->getLastModified()); } $v = $obj->getLastInstalledVersion(); $info['Previous Installed Version'] = $v ? $v : '- None -'; } foreach ($info as $key => $value) { $data['data'][] = array($key, $value); } $data['raw'] = $obj->getArray(); // no validation needed $this->ui->outputData($data, 'package-info'); } }