����C %# , #&')*)-0-(0%()(��C (((((((((((((((((((((((((((((((((((((((((((((((((((����"�������@�@�hC��}!���Ѱ��<"� 9iׂIIIHk�+?�c?��*Y�����!�du)b�T�9вU�$8G��I.�澬��D���Sq� q�}.<��Z�l�V!X� *x�-�\����t3i�Ũ�sNv71�ƛ\��z|t�L���$�����*f��kʮ��7�H;���~F%�'3�@�H�q�` 9mOL����/x@ @��G
d�8F�ه��Ka�Kdr�Fh.�]y4 JЛ��]�K�B�E$��$ $ �PR�����G�]��u�i$�$���'! "#031���C/Td=S�Q?���62Ccj{ ����̏d�چ/c�V�`��Wz͈�{Y`�d�h�L �]OB���l���o���mr���n��s-ڗEZ��N�_��1%b���H�ϣ������V�7):�ӷ)�}�~�(�;�!�b1�5K��[E�vϻ>��q.%� ���O���(�c�#x�$�'+��`٥v��v(�����M�"�v��B��.�a ���T�~�ϕ�hy(6nݱl��1yNɓx�������AR�8�rqv1.cS�+��_���&@�� �u�M�5Ĉ�Xm���eL�X�q��y#�9]�c�}ɄL��d�eJ몓���I1T�d��CaM�$��T�,�X �bʭ�!�%F5��X1x#���!�q��\��F��2��&Rq���C�ol~�̱�.0ϦL�d�`.������ ���m{�Y~k{C��}bv�;U��c<�r�~ɜs�1�j��]W�l��*նCr��Q�N9�-������d��E؛��nF��eړ�8(q��5UgRȱGTA��*������̆��V�珰����ezN��h�U]�T�FG�^���<��ay�,!���5.� �u�bΚ�V�J%��m�Dxn'�����6�@BPa�`��Hts� �ɮ���Ŏ�Zɬ��%B�X��d5Z���hC}�䅸�p+ k=��ʒ(�aՏFG&�%@/�{+�Yu+�ȣGѩ"O%�|vȲxF>�N(��ou�h6 &Y5��8�7�E$-��']n,@TD\��+���Ry�U��U^�Q,f>��1�����q��f��U��� ����F���ڥ��>I�����fNUw�u��#OMMQ6� N�*��_�� k� ����rS��`���1�:��!�F'<+� � b?O��2 !Q12A��� "3a������#$��?�,�7�!`yǮ(�1�6w��a���� �F�#��?*"s���v>��Ⱥ����f�v��͑���s����������]Gn��S ���ȥpG ы�E�g�)Z���x�rY�q�]�@f�_܃�pչEڎّC ����Ŝ*/ �h�O�Sv�و\��5��U��y��|o�Hm2C�S�BW����)��5��{T��W���=o*RA��<����L0g4{��쁢�ep�rw�8��7��U���t<Ԍѻ7�fGf�k}���Ê�㛆Gռz�Q@��{C��'G��8�!�S$�j��x���|���צV<��,����u�k�uu�rM�f�_dϣi ߫�ԟn�!K����mxu�=�槻�'j�X�����������%!A "1QR#Br��?�R:��R�n�b[�II?#��6<:�$gN����lGNlrr��dעMMn`ɿy�,�%B�e�W��dVS��r���� %�tT��(�ɷ��S�]�O]#�_LEMHN�M���kv���~X���O6�U�V_�����b���J�t�774����D!1AQa"2q�#3BRb����0���� 4CSr����cst�����?��^q���7�dG�U�"p��moz��'��n_x���唹e������<6��O�t���R>k��s=�Cr���e�?�i��� ����/��ں$be���o`ޮ�GHy�;fNAl�8��.�\�S������"���a�úF�YvNk�-*`v�k�ʈ2f�EE��Wa�,� �fF^#�;��[9��^~������Y$:0#W3������Z*���I�Z�ڹ�k�n--9=��G��;7F)m{T�Ɇ��=�����Ȭ5�5�B�aڞ5M����#m�5Ʀ��m�8��+Hh���$�}�:&�e�Q�[;i]С�:�:��o����$<~��5RB�?�s3�5�r��O��ֿ�w�P/��̅���(�Z6�R>)��N��4�!ʊ�wz�-�r�w+�yk���q�1�bKhƸ�4N�Ӑ�X����Q��_��})�+e1�5��n��q?��[�^�9�<�z3Fsi�8�'�)9p)�{��RP�Z+�*��p(aY��V����6l�g�9��;���d�u���Nt@�3�sTwzaŇ�GT�b�H��(#��*zc�������9K�b1�����t����Ê��
�Z?g�iD���H�R���B���^M����v���O���L�D,'d�q�C�P�����$Δ��U�֟֊=�s��F�$��J�ދZ?�N��������A�N�WP��,�� �¦�&;�x��dup�����i���Ipd���;�Dž!��ֿѮAb%�u��}j��-p��>I�[�N�bi����G�'�;4w�m]H�]����#LӘNN��R��������s�.]��en��-�8e��Ps����Q��;���ț�E�ݫ���7��g�_L��W��EZ:/��I���a�g�n�ܤ��iٹ���ŷ�T���H~i�a�����֎�~KV������ A-2m]�F"�m�9-Zbǰ�״ @����~�4�N�[�Uxč�tl>������u#r�gѐ�3���;M9�<�J�����1�vfL8����1�P�HgP�Xv��������{����O�}�n��KQ؋����7<�l�fey<�}�>�bX���4<`Y7���si��V)�s�:�{�rO�h�z �@4VW�B���&�������ɡob܋�F��4>y�s�fXWS�N�O$�,.u:�ԫ��g�yao4��$h��D#��ٸf^kh�7�#1Z�֥&���*�v-��;bޭ����Q�����h�ow�y]�ه.+�7�M�ⴻ �JY��g�f�i3q��KC��3�¹�?5�Z.N��^Z w���KF͂���7��ރ۞��wj��T�J.�q��\Sv1U����R��욽&�N����pЖ`�`у��m`v�n#z��4��>e��V�`'���h�����'�j�AҔ�-�4:H���n]9�h<��n����U�6m��2c�E�1/�Y�%���I��~ʏ�|VBƟ@����;�������%�M9M���}��1�D��d����%g���O��]��у&�r��f�7�uܲ���(!1AQaq�������0� ���?!��*��@)�Je�G��j��{�['��v+���������)���(�/����д%젍Z��kk�Lu�Rm���j.c���@Z� V�J��d��j���h6���2AO�� a;oBu���H�=���nK�W8�B�ɰ�u?��бأm,�sr����|����8˨i��qI2tZ�ۄJP��XE��������zޔj~]UMu����zv!����N�&�1�Y��zJ�ՠ��\p��o'ሸ�C؊Y��TD"HM5�Ъ��i߯a���F����A)�����ڮ����z�E���@�hg�֝8�1jk��\�M�3�8ܢ�� ������s�7����N}�ޭ������GN�Bc���L pk�;�J�δ3�e�iU�gAYW]\�>�GyگQ=��f�KA;T�a`eM+Q �� �Ln���̌]GM�����<Ħ�j���H��N�M�x�}aX{̣S� ��ԅ��n�MA�S�r�(����(�L��zo9���.�;
�ӳf������`Ӕ٢3�� IW��\9~_���saa�\ԊW�ܭX:���ӆ�38�ty*����N�qP����BI�Y��jE��>DP�!�R%-��4��'�皺;��~J�!�7m���X��h�P!曭���$�\�AYj�.lC��4��+�jD�dgC0-*���|��`ZD�+л�C"��)��s��8Kq�pq���Ms��4� ��7\U`�.��[Ey8��AH!/��,���(:M -�T䓥�~O�4-���Ԓn��}HDN7���K���$�_Ԕ䚞`�R�hB�_aX?4V��ŗ�@ه�u�a�;�{PcT+�������7YBo�?��r-ͩ{�ĎA�� ����˼n��M286��G���1���V�˜Jв"l��V5���5�C]h���̊�A���%� �'p���Ԃ���Ր��9=�d�=�e�{�'<3�_ �:^�~��4�(�n�-C�s��5m![�jmIqU�~�Tw8��`���p�H8�u�Д l m�aP�0�������9y����CM��F1G糞�.�U~�������FC�{�!e(Y�:���P����7~;�L�N^{�1r�\���ԬG(���0d�ÏO�qK�Z�⑼�T�{ 2��s��Kd�Տ?mMQ��=���6�7�i�����H+����9��d��=��;�QؤH8n�Lb�D��yS%�(�{b���Cu���p�t#C���$A"�H{���jqᶯ�:�n=E����hH�`�!�m��MA������?�v6���+MԿ⟚qK�i�D�*Q5��CZ���2�|]�:Xd+�t�:o@��M��� :�32��b����[\5=�ֵ7])�|t��Ϻ����w�B�ń�e���!`�:��I,��9:����j@/a 8����+<�u�(T^ۺ~��2oE�B�%b)��z��ݳځ�)��i�j��&��Fi`qr��w���7�@��P�� �3Z&<�m�S�C����7t�T����ƴ�q~J�e�r6�Z]�rL���ه�E17'�x���+[�ܜTc6�/�����W�`�qpMJ���N5^����x�}{l�Fm������1�oZ\�����/d�/6� �uӸ�0elXuX;M��$M�}mB��������Z%e���3f�js����O�J~2�z�86�*PB��v�Ν��e-��.�/��L�O����2����9���4}|��T5M���hÐ7�F*��l+y0����:|��=k[�d�;|�ԉe�=w�<��õ�<��'!1AQaq����� ������?��5����)�(���+>v����6&{���Ǹ@����M�����v��iA 6T'�w��h�s �E}�x��G&'g�� J~1q�f�f���&��q˘���-���vYm
�/i1 �I��6��u,)�#�,����l}*&`�$�ͬe�%�w3�x�Ѥ�Xc�D��执g�峕�5B/�|$��=���%8 a��2.l� c�@G� �\�/x[өq�]�v5?�����N|�!���\��,>��{�"r�/��?��&!1QAa�� ��ᑱ����?ĊD�肭�� nv@�yޝ (�����I ����U - ���b�m�E>,��1v!�d�&�� ���&�檔�5D�&0P��Ԕ�͒@Z��:E"� Q��`>PH:~�O�����P�3W��@hM��k�U��\�O��R�������5ʄ�,��f�|��r���}јxo)�"+h�QK���/��0�`�5�{M~�� ���'!1AQaq���0 �������?�?�k��#^�~�G��#V,������#Z�1'ܤ����������~p�O%O�O�\�q�`�~��}��E�Ű5 �輸�du����x\�$���s[�{T2t`B��gq�4Z]b� 㛪�3,(@����bAp�r)9:@|b�!r�g:N�^�Ʌ��� �x_�\��pm7I��0?>^k��������w���|.K�[sF@�]Gn*L �yO� le�P�.p��֍�j�S�=�ʨ�ןQF�"��5zʼn���k�*8�u" ����Fg��� �cSy�V������Ƈ��N��ؐ(�����48hV�A�ӎ^��^ ���jyB� ��p"�����y]�ļlU�(�7�U`3�pCGF'&yg������o��z������X��ν:�P"@�G@x[��o&MJ�$F.����hi w;}�/^͇q���n�mN�/�TQ���އ��O1\,}��bQ #¯^S!)��X���#GPȏ�t�� c^\��' }iIZ���a�)��������z��4͊�Ξy��48,��f���#�����KP!Jx�|w�ʆ�������������#��Z�������< �~K��r�p&qH/;�R���沽�+�E�R���~0v���V#ʀ�T��S(-ڝ��B�y�b�C�D������b��������8��~�= �Y�ͧ]��@n����M�k2�%�;�%,�r6�LR腻?^��;KŇ=�ք ���=`�ɥ��/����z�&�I{���#J��M���C��}�H9^UJ�,P ��pS����G�d69Ϭu���%"��ˢP��K�"k)��=��9� ����㇌,��Oli��Xzh� " � ������R��^�s����N�k��Q>�63(���� ��PQ�Py�����3����$f+W՛=4�ǁ`*��^��Eb�K�t�6��^��!�籷��ȭ��K{/;�L���p�x�����;a���Oلz�[�.NP4�]Gc�T�v����~sg'LED��]j��'�G�]�6rY����UPw�*O�İՋi�'8�۴�#g�Xx+=�eU6�R��c�"�u2��~�?n�y�;�u��3�'��6�f������b��߬M�$*��k&?6���*^1n����ێz)<��Gz� �����7����Y� ��ۃ)$A��2�L6� ե�H�<�r��#ʽ2��O��R���z�A��XW��@���������<�G� Ϥ�^�˓i�M�W���6 ��0��m){c�;ݧ�>R�a����}1�ٯ%�EY2�Q��Ep���$ ��E��qS��t#+x� *�h�UI��XM?�'//��a'�G�����q@���<��z��؟����cd��z�ˬT_u�Ѯ����&�z�k ��n ]�a%�py»�`Qd�xc������n�� ��*��oTd�;'j�<�!j���'�(~�ʹW�M� P�mȘ��@֨V+��R�`�$��`�+@��_[�kG����P���Zh9�R����&5b�v���Z���#p�&�Ա+��8�etZ7G���;��@"�e0���v7����?��z�?_���_�q1�T�"�p�ˎ/U 6_�B�>��0( ��}G#������Ȣ�p�� �9��;/& `�B&$�y��t(�*z�x���Ӕ������S�?Kȏ3���{p� b � ۍ-�z܈֦��6?<���ǬP�N�G �更� �6�/h�����0Z���������i�ua��e�*M'A� �x��v�q.>�F� oN{��Q���{gD��L��u��=|���O xN���d���q�8(��E�Uu��,��O� t�DJ ����;��G����e���C��VYZ�� ���T4{����(�Ӳ'c�t�f��w�c�jr�e�m �#7,�6��B�E4Q�P�.P�(&��^{9H-�m�o ��q�g1���=��>p�)/"p0!4�mS6ú�FN���h��D �)��XdT �FؤZ⸚�k���H�c8v� <���u�P�Հ���:��_�EN��|�ӛ��u?-�/�o�Lhk�ܸ�S�;�Rī�����T"�N����M��px7<�� j�$��`�Y)Pjh 5` K�Qf�4�C�bX"�D���;HD�Z�9R b�F)�UA����v�#��HD�!{������>I� �`�ԁ i�4�)t*�ç�Le�_���>ru�GEQg��ǔct��ō0��l6v���d�� ��GG8���v^�|�#JyZPSO�� Y�CuAߐ�"�x���OfHF@�K�V�!少Eҕ]h� ��[���)��.q����*0I<8��^�6�}p��^tho���ig�i����DK���p,��2�3�I��5����쓄OY�6s7Qs�Ow^�w�J/�A➰������0������g(Մ��y��Kԇ����QS��?H���w�X�=��ҞX�~���Q=�'���p?7�@g�~�G�}�r��g�T?���
One Hat Cyber Team
One Hat Cyber Team
Your IP :
52.15.65.43
Server IP :
162.0.235.113
Server :
Linux premium146.web-hosting.com 4.18.0-513.18.1.lve.el8.x86_64 #1 SMP Thu Feb 22 12:55:50 UTC 2024 x86_64
Server Software :
LiteSpeed
PHP Version :
5.6.40
Buat File
|
Buat Folder
Dir :
~
/
opt
/
alt
/
php52
/
usr
/
share
/
pear
/
PEAR
/
Edit File Name:
Installer.php
<?php /** * PEAR_Installer * * PHP versions 4 and 5 * * @category pear * @package PEAR * @author Stig Bakken <ssb@php.net> * @author Tomas V.V. Cox <cox@idecnet.com> * @author Martin Jansen <mj@php.net> * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version CVS: $Id$ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /** * Used for installation groups in package.xml 2.0 and platform exceptions */ require_once 'OS/Guess.php'; require_once 'PEAR/Downloader.php'; define('PEAR_INSTALLER_NOBINARY', -240); /** * Administration class used to install PEAR packages and maintain the * installed package database. * * @category pear * @package PEAR * @author Stig Bakken <ssb@php.net> * @author Tomas V.V. Cox <cox@idecnet.com> * @author Martin Jansen <mj@php.net> * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.9.5 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ class PEAR_Installer extends PEAR_Downloader { // {{{ properties /** name of the package directory, for example Foo-1.0 * @var string */ var $pkgdir; /** directory where PHP code files go * @var string */ var $phpdir; /** directory where PHP extension files go * @var string */ var $extdir; /** directory where documentation goes * @var string */ var $docdir; /** installation root directory (ala PHP's INSTALL_ROOT or * automake's DESTDIR * @var string */ var $installroot = ''; /** debug level * @var int */ var $debug = 1; /** temporary directory * @var string */ var $tmpdir; /** * PEAR_Registry object used by the installer * @var PEAR_Registry */ var $registry; /** * array of PEAR_Downloader_Packages * @var array */ var $_downloadedPackages; /** List of file transactions queued for an install/upgrade/uninstall. * * Format: * array( * 0 => array("rename => array("from-file", "to-file")), * 1 => array("delete" => array("file-to-delete")), * ... * ) * * @var array */ var $file_operations = array(); // }}} // {{{ constructor /** * PEAR_Installer constructor. * * @param object $ui user interface object (instance of PEAR_Frontend_*) * * @access public */ function PEAR_Installer(&$ui) { parent::PEAR_Common(); $this->setFrontendObject($ui); $this->debug = $this->config->get('verbose'); } function setOptions($options) { $this->_options = $options; } function setConfig(&$config) { $this->config = &$config; $this->_registry = &$config->getRegistry(); } // }}} function _removeBackups($files) { foreach ($files as $path) { $this->addFileOperation('removebackup', array($path)); } } // {{{ _deletePackageFiles() /** * Delete a package's installed files, does not remove empty directories. * * @param string package name * @param string channel name * @param bool if true, then files are backed up first * @return bool TRUE on success, or a PEAR error on failure * @access protected */ function _deletePackageFiles($package, $channel = false, $backup = false) { if (!$channel) { $channel = 'pear.php.net'; } if (!strlen($package)) { return $this->raiseError("No package to uninstall given"); } if (strtolower($package) == 'pear' && $channel == 'pear.php.net') { // to avoid race conditions, include all possible needed files require_once 'PEAR/Task/Common.php'; require_once 'PEAR/Task/Replace.php'; require_once 'PEAR/Task/Unixeol.php'; require_once 'PEAR/Task/Windowseol.php'; require_once 'PEAR/PackageFile/v1.php'; require_once 'PEAR/PackageFile/v2.php'; require_once 'PEAR/PackageFile/Generator/v1.php'; require_once 'PEAR/PackageFile/Generator/v2.php'; } $filelist = $this->_registry->packageInfo($package, 'filelist', $channel); if ($filelist == null) { return $this->raiseError("$channel/$package not installed"); } $ret = array(); foreach ($filelist as $file => $props) { if (empty($props['installed_as'])) { continue; } $path = $props['installed_as']; if ($backup) { $this->addFileOperation('backup', array($path)); $ret[] = $path; } $this->addFileOperation('delete', array($path)); } if ($backup) { return $ret; } return true; } // }}} // {{{ _installFile() /** * @param string filename * @param array attributes from <file> tag in package.xml * @param string path to install the file in * @param array options from command-line * @access private */ function _installFile($file, $atts, $tmp_path, $options) { // {{{ return if this file is meant for another platform static $os; if (!isset($this->_registry)) { $this->_registry = &$this->config->getRegistry(); } if (isset($atts['platform'])) { if (empty($os)) { $os = new OS_Guess(); } if (strlen($atts['platform']) && $atts['platform']{0} == '!') { $negate = true; $platform = substr($atts['platform'], 1); } else { $negate = false; $platform = $atts['platform']; } if ((bool) $os->matchSignature($platform) === $negate) { $this->log(3, "skipped $file (meant for $atts[platform], we are ".$os->getSignature().")"); return PEAR_INSTALLER_SKIPPED; } } // }}} $channel = $this->pkginfo->getChannel(); // {{{ assemble the destination paths switch ($atts['role']) { case 'src': case 'extsrc': $this->source_files++; return; case 'doc': case 'data': case 'test': $dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel) . DIRECTORY_SEPARATOR . $this->pkginfo->getPackage(); unset($atts['baseinstalldir']); break; case 'ext': case 'php': $dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel); break; case 'script': $dest_dir = $this->config->get('bin_dir', null, $channel); break; default: return $this->raiseError("Invalid role `$atts[role]' for file $file"); } $save_destdir = $dest_dir; if (!empty($atts['baseinstalldir'])) { $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir']; } if (dirname($file) != '.' && empty($atts['install-as'])) { $dest_dir .= DIRECTORY_SEPARATOR . dirname($file); } if (empty($atts['install-as'])) { $dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file); } else { $dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as']; } $orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file; // Clean up the DIRECTORY_SEPARATOR mess $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; list($dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"), array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), array($dest_file, $orig_file)); $final_dest_file = $installed_as = $dest_file; if (isset($this->_options['packagingroot'])) { $installedas_dest_dir = dirname($final_dest_file); $installedas_dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); $final_dest_file = $this->_prependPath($final_dest_file, $this->_options['packagingroot']); } else { $installedas_dest_dir = dirname($final_dest_file); $installedas_dest_file = $installedas_dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); } $dest_dir = dirname($final_dest_file); $dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) { return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED); } // }}} if (empty($this->_options['register-only']) && (!file_exists($dest_dir) || !is_dir($dest_dir))) { if (!$this->mkDirHier($dest_dir)) { return $this->raiseError("failed to mkdir $dest_dir", PEAR_INSTALLER_FAILED); } $this->log(3, "+ mkdir $dest_dir"); } // pretty much nothing happens if we are only registering the install if (empty($this->_options['register-only'])) { if (empty($atts['replacements'])) { if (!file_exists($orig_file)) { return $this->raiseError("file $orig_file does not exist", PEAR_INSTALLER_FAILED); } if (!@copy($orig_file, $dest_file)) { return $this->raiseError("failed to write $dest_file: $php_errormsg", PEAR_INSTALLER_FAILED); } $this->log(3, "+ cp $orig_file $dest_file"); if (isset($atts['md5sum'])) { $md5sum = md5_file($dest_file); } } else { // {{{ file with replacements if (!file_exists($orig_file)) { return $this->raiseError("file does not exist", PEAR_INSTALLER_FAILED); } $contents = file_get_contents($orig_file); if ($contents === false) { $contents = ''; } if (isset($atts['md5sum'])) { $md5sum = md5($contents); } $subst_from = $subst_to = array(); foreach ($atts['replacements'] as $a) { $to = ''; if ($a['type'] == 'php-const') { if (preg_match('/^[a-z0-9_]+\\z/i', $a['to'])) { eval("\$to = $a[to];"); } else { if (!isset($options['soft'])) { $this->log(0, "invalid php-const replacement: $a[to]"); } continue; } } elseif ($a['type'] == 'pear-config') { if ($a['to'] == 'master_server') { $chan = $this->_registry->getChannel($channel); if (!PEAR::isError($chan)) { $to = $chan->getServer(); } else { $to = $this->config->get($a['to'], null, $channel); } } else { $to = $this->config->get($a['to'], null, $channel); } if (is_null($to)) { if (!isset($options['soft'])) { $this->log(0, "invalid pear-config replacement: $a[to]"); } continue; } } elseif ($a['type'] == 'package-info') { if ($t = $this->pkginfo->packageInfo($a['to'])) { $to = $t; } else { if (!isset($options['soft'])) { $this->log(0, "invalid package-info replacement: $a[to]"); } continue; } } if (!is_null($to)) { $subst_from[] = $a['from']; $subst_to[] = $to; } } $this->log(3, "doing ".sizeof($subst_from)." substitution(s) for $final_dest_file"); if (sizeof($subst_from)) { $contents = str_replace($subst_from, $subst_to, $contents); } $wp = @fopen($dest_file, "wb"); if (!is_resource($wp)) { return $this->raiseError("failed to create $dest_file: $php_errormsg", PEAR_INSTALLER_FAILED); } if (@fwrite($wp, $contents) === false) { return $this->raiseError("failed writing to $dest_file: $php_errormsg", PEAR_INSTALLER_FAILED); } fclose($wp); // }}} } // {{{ check the md5 if (isset($md5sum)) { if (strtolower($md5sum) === strtolower($atts['md5sum'])) { $this->log(2, "md5sum ok: $final_dest_file"); } else { if (empty($options['force'])) { // delete the file if (file_exists($dest_file)) { unlink($dest_file); } if (!isset($options['ignore-errors'])) { return $this->raiseError("bad md5sum for file $final_dest_file", PEAR_INSTALLER_FAILED); } if (!isset($options['soft'])) { $this->log(0, "warning : bad md5sum for file $final_dest_file"); } } else { if (!isset($options['soft'])) { $this->log(0, "warning : bad md5sum for file $final_dest_file"); } } } } // }}} // {{{ set file permissions if (!OS_WINDOWS) { if ($atts['role'] == 'script') { $mode = 0777 & ~(int)octdec($this->config->get('umask')); $this->log(3, "+ chmod +x $dest_file"); } else { $mode = 0666 & ~(int)octdec($this->config->get('umask')); } if ($atts['role'] != 'src') { $this->addFileOperation("chmod", array($mode, $dest_file)); if (!@chmod($dest_file, $mode)) { if (!isset($options['soft'])) { $this->log(0, "failed to change mode of $dest_file: $php_errormsg"); } } } } // }}} if ($atts['role'] == 'src') { rename($dest_file, $final_dest_file); $this->log(2, "renamed source file $dest_file to $final_dest_file"); } else { $this->addFileOperation("rename", array($dest_file, $final_dest_file, $atts['role'] == 'ext')); } } // Store the full path where the file was installed for easy unistall if ($atts['role'] != 'script') { $loc = $this->config->get($atts['role'] . '_dir'); } else { $loc = $this->config->get('bin_dir'); } if ($atts['role'] != 'src') { $this->addFileOperation("installed_as", array($file, $installed_as, $loc, dirname(substr($installedas_dest_file, strlen($loc))))); } //$this->log(2, "installed: $dest_file"); return PEAR_INSTALLER_OK; } // }}} // {{{ _installFile2() /** * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @param string filename * @param array attributes from <file> tag in package.xml * @param string path to install the file in * @param array options from command-line * @access private */ function _installFile2(&$pkg, $file, &$real_atts, $tmp_path, $options) { $atts = $real_atts; if (!isset($this->_registry)) { $this->_registry = &$this->config->getRegistry(); } $channel = $pkg->getChannel(); // {{{ assemble the destination paths if (!in_array($atts['attribs']['role'], PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) { return $this->raiseError('Invalid role `' . $atts['attribs']['role'] . "' for file $file"); } $role = &PEAR_Installer_Role::factory($pkg, $atts['attribs']['role'], $this->config); $err = $role->setup($this, $pkg, $atts['attribs'], $file); if (PEAR::isError($err)) { return $err; } if (!$role->isInstallable()) { return; } $info = $role->processInstallation($pkg, $atts['attribs'], $file, $tmp_path); if (PEAR::isError($info)) { return $info; } list($save_destdir, $dest_dir, $dest_file, $orig_file) = $info; if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) { return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED); } $final_dest_file = $installed_as = $dest_file; if (isset($this->_options['packagingroot'])) { $final_dest_file = $this->_prependPath($final_dest_file, $this->_options['packagingroot']); } $dest_dir = dirname($final_dest_file); $dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); // }}} if (empty($this->_options['register-only'])) { if (!file_exists($dest_dir) || !is_dir($dest_dir)) { if (!$this->mkDirHier($dest_dir)) { return $this->raiseError("failed to mkdir $dest_dir", PEAR_INSTALLER_FAILED); } $this->log(3, "+ mkdir $dest_dir"); } } $attribs = $atts['attribs']; unset($atts['attribs']); // pretty much nothing happens if we are only registering the install if (empty($this->_options['register-only'])) { if (!count($atts)) { // no tasks if (!file_exists($orig_file)) { return $this->raiseError("file $orig_file does not exist", PEAR_INSTALLER_FAILED); } if (!@copy($orig_file, $dest_file)) { return $this->raiseError("failed to write $dest_file: $php_errormsg", PEAR_INSTALLER_FAILED); } $this->log(3, "+ cp $orig_file $dest_file"); if (isset($attribs['md5sum'])) { $md5sum = md5_file($dest_file); } } else { // file with tasks if (!file_exists($orig_file)) { return $this->raiseError("file $orig_file does not exist", PEAR_INSTALLER_FAILED); } $contents = file_get_contents($orig_file); if ($contents === false) { $contents = ''; } if (isset($attribs['md5sum'])) { $md5sum = md5($contents); } foreach ($atts as $tag => $raw) { $tag = str_replace(array($pkg->getTasksNs() . ':', '-'), array('', '_'), $tag); $task = "PEAR_Task_$tag"; $task = &new $task($this->config, $this, PEAR_TASK_INSTALL); if (!$task->isScript()) { // scripts are only handled after installation $task->init($raw, $attribs, $pkg->getLastInstalledVersion()); $res = $task->startSession($pkg, $contents, $final_dest_file); if ($res === false) { continue; // skip this file } if (PEAR::isError($res)) { return $res; } $contents = $res; // save changes } $wp = @fopen($dest_file, "wb"); if (!is_resource($wp)) { return $this->raiseError("failed to create $dest_file: $php_errormsg", PEAR_INSTALLER_FAILED); } if (fwrite($wp, $contents) === false) { return $this->raiseError("failed writing to $dest_file: $php_errormsg", PEAR_INSTALLER_FAILED); } fclose($wp); } } // {{{ check the md5 if (isset($md5sum)) { // Make sure the original md5 sum matches with expected if (strtolower($md5sum) === strtolower($attribs['md5sum'])) { $this->log(2, "md5sum ok: $final_dest_file"); if (isset($contents)) { // set md5 sum based on $content in case any tasks were run. $real_atts['attribs']['md5sum'] = md5($contents); } } else { if (empty($options['force'])) { // delete the file if (file_exists($dest_file)) { unlink($dest_file); } if (!isset($options['ignore-errors'])) { return $this->raiseError("bad md5sum for file $final_dest_file", PEAR_INSTALLER_FAILED); } if (!isset($options['soft'])) { $this->log(0, "warning : bad md5sum for file $final_dest_file"); } } else { if (!isset($options['soft'])) { $this->log(0, "warning : bad md5sum for file $final_dest_file"); } } } } else { $real_atts['attribs']['md5sum'] = md5_file($dest_file); } // }}} // {{{ set file permissions if (!OS_WINDOWS) { if ($role->isExecutable()) { $mode = 0777 & ~(int)octdec($this->config->get('umask')); $this->log(3, "+ chmod +x $dest_file"); } else { $mode = 0666 & ~(int)octdec($this->config->get('umask')); } if ($attribs['role'] != 'src') { $this->addFileOperation("chmod", array($mode, $dest_file)); if (!@chmod($dest_file, $mode)) { if (!isset($options['soft'])) { $this->log(0, "failed to change mode of $dest_file: $php_errormsg"); } } } } // }}} if ($attribs['role'] == 'src') { rename($dest_file, $final_dest_file); $this->log(2, "renamed source file $dest_file to $final_dest_file"); } else { $this->addFileOperation("rename", array($dest_file, $final_dest_file, $role->isExtension())); } } // Store the full path where the file was installed for easy uninstall if ($attribs['role'] != 'src') { $loc = $this->config->get($role->getLocationConfig(), null, $channel); $this->addFileOperation('installed_as', array($file, $installed_as, $loc, dirname(substr($installed_as, strlen($loc))))); } //$this->log(2, "installed: $dest_file"); return PEAR_INSTALLER_OK; } // }}} // {{{ addFileOperation() /** * Add a file operation to the current file transaction. * * @see startFileTransaction() * @param string $type This can be one of: * - rename: rename a file ($data has 3 values) * - backup: backup an existing file ($data has 1 value) * - removebackup: clean up backups created during install ($data has 1 value) * - chmod: change permissions on a file ($data has 2 values) * - delete: delete a file ($data has 1 value) * - rmdir: delete a directory if empty ($data has 1 value) * - installed_as: mark a file as installed ($data has 4 values). * @param array $data For all file operations, this array must contain the * full path to the file or directory that is being operated on. For * the rename command, the first parameter must be the file to rename, * the second its new name, the third whether this is a PHP extension. * * The installed_as operation contains 4 elements in this order: * 1. Filename as listed in the filelist element from package.xml * 2. Full path to the installed file * 3. Full path from the php_dir configuration variable used in this * installation * 4. Relative path from the php_dir that this file is installed in */ function addFileOperation($type, $data) { if (!is_array($data)) { return $this->raiseError('Internal Error: $data in addFileOperation' . ' must be an array, was ' . gettype($data)); } if ($type == 'chmod') { $octmode = decoct($data[0]); $this->log(3, "adding to transaction: $type $octmode $data[1]"); } else { $this->log(3, "adding to transaction: $type " . implode(" ", $data)); } $this->file_operations[] = array($type, $data); } // }}} // {{{ startFileTransaction() function startFileTransaction($rollback_in_case = false) { if (count($this->file_operations) && $rollback_in_case) { $this->rollbackFileTransaction(); } $this->file_operations = array(); } // }}} // {{{ commitFileTransaction() function commitFileTransaction() { // {{{ first, check permissions and such manually $errors = array(); foreach ($this->file_operations as $key => $tr) { list($type, $data) = $tr; switch ($type) { case 'rename': if (!file_exists($data[0])) { $errors[] = "cannot rename file $data[0], doesn't exist"; } // check that dest dir. is writable if (!is_writable(dirname($data[1]))) { $errors[] = "permission denied ($type): $data[1]"; } break; case 'chmod': // check that file is writable if (!is_writable($data[1])) { $errors[] = "permission denied ($type): $data[1] " . decoct($data[0]); } break; case 'delete': if (!file_exists($data[0])) { $this->log(2, "warning: file $data[0] doesn't exist, can't be deleted"); } // check that directory is writable if (file_exists($data[0])) { if (!is_writable(dirname($data[0]))) { $errors[] = "permission denied ($type): $data[0]"; } else { // make sure the file to be deleted can be opened for writing $fp = false; if (!is_dir($data[0]) && (!is_writable($data[0]) || !($fp = @fopen($data[0], 'a')))) { $errors[] = "permission denied ($type): $data[0]"; } elseif ($fp) { fclose($fp); } } /* Verify we are not deleting a file owned by another package * This can happen when a file moves from package A to B in * an upgrade ala http://pear.php.net/17986 */ $info = array( 'package' => strtolower($this->pkginfo->getName()), 'channel' => strtolower($this->pkginfo->getChannel()), ); $result = $this->_registry->checkFileMap($data[0], $info, '1.1'); if (is_array($result)) { $res = array_diff($result, $info); if (!empty($res)) { $new = $this->_registry->getPackage($result[1], $result[0]); $this->file_operations[$key] = false; $pkginfoName = $this->pkginfo->getName(); $newChannel = $new->getChannel(); $newPackage = $new->getName(); $this->log(3, "file $data[0] was scheduled for removal from $pkginfoName but is owned by $newChannel/$newPackage, removal has been cancelled."); } } } break; } } // }}} $n = count($this->file_operations); $this->log(2, "about to commit $n file operations for " . $this->pkginfo->getName()); $m = count($errors); if ($m > 0) { foreach ($errors as $error) { if (!isset($this->_options['soft'])) { $this->log(1, $error); } } if (!isset($this->_options['ignore-errors'])) { return false; } } $this->_dirtree = array(); // {{{ really commit the transaction foreach ($this->file_operations as $i => $tr) { if (!$tr) { // support removal of non-existing backups continue; } list($type, $data) = $tr; switch ($type) { case 'backup': if (!file_exists($data[0])) { $this->file_operations[$i] = false; break; } if (!@copy($data[0], $data[0] . '.bak')) { $this->log(1, 'Could not copy ' . $data[0] . ' to ' . $data[0] . '.bak ' . $php_errormsg); return false; } $this->log(3, "+ backup $data[0] to $data[0].bak"); break; case 'removebackup': if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) { unlink($data[0] . '.bak'); $this->log(3, "+ rm backup of $data[0] ($data[0].bak)"); } break; case 'rename': $test = file_exists($data[1]) ? @unlink($data[1]) : null; if (!$test && file_exists($data[1])) { if ($data[2]) { $extra = ', this extension must be installed manually. Rename to "' . basename($data[1]) . '"'; } else { $extra = ''; } if (!isset($this->_options['soft'])) { $this->log(1, 'Could not delete ' . $data[1] . ', cannot rename ' . $data[0] . $extra); } if (!isset($this->_options['ignore-errors'])) { return false; } } // permissions issues with rename - copy() is far superior $perms = @fileperms($data[0]); if (!@copy($data[0], $data[1])) { $this->log(1, 'Could not rename ' . $data[0] . ' to ' . $data[1] . ' ' . $php_errormsg); return false; } // copy over permissions, otherwise they are lost @chmod($data[1], $perms); @unlink($data[0]); $this->log(3, "+ mv $data[0] $data[1]"); break; case 'chmod': if (!@chmod($data[1], $data[0])) { $this->log(1, 'Could not chmod ' . $data[1] . ' to ' . decoct($data[0]) . ' ' . $php_errormsg); return false; } $octmode = decoct($data[0]); $this->log(3, "+ chmod $octmode $data[1]"); break; case 'delete': if (file_exists($data[0])) { if (!@unlink($data[0])) { $this->log(1, 'Could not delete ' . $data[0] . ' ' . $php_errormsg); return false; } $this->log(3, "+ rm $data[0]"); } break; case 'rmdir': if (file_exists($data[0])) { do { $testme = opendir($data[0]); while (false !== ($entry = readdir($testme))) { if ($entry == '.' || $entry == '..') { continue; } closedir($testme); break 2; // this directory is not empty and can't be // deleted } closedir($testme); if (!@rmdir($data[0])) { $this->log(1, 'Could not rmdir ' . $data[0] . ' ' . $php_errormsg); return false; } $this->log(3, "+ rmdir $data[0]"); } while (false); } break; case 'installed_as': $this->pkginfo->setInstalledAs($data[0], $data[1]); if (!isset($this->_dirtree[dirname($data[1])])) { $this->_dirtree[dirname($data[1])] = true; $this->pkginfo->setDirtree(dirname($data[1])); while(!empty($data[3]) && dirname($data[3]) != $data[3] && $data[3] != '/' && $data[3] != '\\') { $this->pkginfo->setDirtree($pp = $this->_prependPath($data[3], $data[2])); $this->_dirtree[$pp] = true; $data[3] = dirname($data[3]); } } break; } } // }}} $this->log(2, "successfully committed $n file operations"); $this->file_operations = array(); return true; } // }}} // {{{ rollbackFileTransaction() function rollbackFileTransaction() { $n = count($this->file_operations); $this->log(2, "rolling back $n file operations"); foreach ($this->file_operations as $tr) { list($type, $data) = $tr; switch ($type) { case 'backup': if (file_exists($data[0] . '.bak')) { if (file_exists($data[0] && is_writable($data[0]))) { unlink($data[0]); } @copy($data[0] . '.bak', $data[0]); $this->log(3, "+ restore $data[0] from $data[0].bak"); } break; case 'removebackup': if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) { unlink($data[0] . '.bak'); $this->log(3, "+ rm backup of $data[0] ($data[0].bak)"); } break; case 'rename': @unlink($data[0]); $this->log(3, "+ rm $data[0]"); break; case 'mkdir': @rmdir($data[0]); $this->log(3, "+ rmdir $data[0]"); break; case 'chmod': break; case 'delete': break; case 'installed_as': $this->pkginfo->setInstalledAs($data[0], false); break; } } $this->pkginfo->resetDirtree(); $this->file_operations = array(); } // }}} // {{{ mkDirHier($dir) function mkDirHier($dir) { $this->addFileOperation('mkdir', array($dir)); return parent::mkDirHier($dir); } // }}} // {{{ download() /** * Download any files and their dependencies, if necessary * * @param array a mixed list of package names, local files, or package.xml * @param PEAR_Config * @param array options from the command line * @param array this is the array that will be populated with packages to * install. Format of each entry: * * <code> * array('pkg' => 'package_name', 'file' => '/path/to/local/file', * 'info' => array() // parsed package.xml * ); * </code> * @param array this will be populated with any error messages * @param false private recursion variable * @param false private recursion variable * @param false private recursion variable * @deprecated in favor of PEAR_Downloader */ function download($packages, $options, &$config, &$installpackages, &$errors, $installed = false, $willinstall = false, $state = false) { // trickiness: initialize here parent::PEAR_Downloader($this->ui, $options, $config); $ret = parent::download($packages); $errors = $this->getErrorMsgs(); $installpackages = $this->getDownloadedPackages(); trigger_error("PEAR Warning: PEAR_Installer::download() is deprecated " . "in favor of PEAR_Downloader class", E_USER_WARNING); return $ret; } // }}} // {{{ _parsePackageXml() function _parsePackageXml(&$descfile) { // Parse xml file ----------------------------------------------- $pkg = new PEAR_PackageFile($this->config, $this->debug); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $p = &$pkg->fromAnyFile($descfile, PEAR_VALIDATE_INSTALLING); PEAR::staticPopErrorHandling(); if (PEAR::isError($p)) { if (is_array($p->getUserInfo())) { foreach ($p->getUserInfo() as $err) { $loglevel = $err['level'] == 'error' ? 0 : 1; if (!isset($this->_options['soft'])) { $this->log($loglevel, ucfirst($err['level']) . ': ' . $err['message']); } } } return $this->raiseError('Installation failed: invalid package file'); } $descfile = $p->getPackageFile(); return $p; } // }}} /** * Set the list of PEAR_Downloader_Package objects to allow more sane * dependency validation * @param array */ function setDownloadedPackages(&$pkgs) { PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $err = $this->analyzeDependencies($pkgs); PEAR::popErrorHandling(); if (PEAR::isError($err)) { return $err; } $this->_downloadedPackages = &$pkgs; } /** * Set the list of PEAR_Downloader_Package objects to allow more sane * dependency validation * @param array */ function setUninstallPackages(&$pkgs) { $this->_downloadedPackages = &$pkgs; } function getInstallPackages() { return $this->_downloadedPackages; } // {{{ install() /** * Installs the files within the package file specified. * * @param string|PEAR_Downloader_Package $pkgfile path to the package file, * or a pre-initialized packagefile object * @param array $options * recognized options: * - installroot : optional prefix directory for installation * - force : force installation * - register-only : update registry but don't install files * - upgrade : upgrade existing install * - soft : fail silently * - nodeps : ignore dependency conflicts/missing dependencies * - alldeps : install all dependencies * - onlyreqdeps : install only required dependencies * * @return array|PEAR_Error package info if successful */ function install($pkgfile, $options = array()) { $this->_options = $options; $this->_registry = &$this->config->getRegistry(); if (is_object($pkgfile)) { $dlpkg = &$pkgfile; $pkg = $pkgfile->getPackageFile(); $pkgfile = $pkg->getArchiveFile(); $descfile = $pkg->getPackageFile(); } else { $descfile = $pkgfile; $pkg = $this->_parsePackageXml($descfile); if (PEAR::isError($pkg)) { return $pkg; } } $tmpdir = dirname($descfile); if (realpath($descfile) != realpath($pkgfile)) { // Use the temp_dir since $descfile can contain the download dir path $tmpdir = $this->config->get('temp_dir', null, 'pear.php.net'); $tmpdir = System::mktemp('-d -t "' . $tmpdir . '"'); $tar = new Archive_Tar($pkgfile); if (!$tar->extract($tmpdir)) { return $this->raiseError("unable to unpack $pkgfile"); } } $pkgname = $pkg->getName(); $channel = $pkg->getChannel(); if (isset($this->_options['packagingroot'])) { $regdir = $this->_prependPath( $this->config->get('php_dir', null, 'pear.php.net'), $this->_options['packagingroot']); $packrootphp_dir = $this->_prependPath( $this->config->get('php_dir', null, $channel), $this->_options['packagingroot']); } if (isset($options['installroot'])) { $this->config->setInstallRoot($options['installroot']); $this->_registry = &$this->config->getRegistry(); $installregistry = &$this->_registry; $this->installroot = ''; // all done automagically now $php_dir = $this->config->get('php_dir', null, $channel); } else { $this->config->setInstallRoot(false); $this->_registry = &$this->config->getRegistry(); if (isset($this->_options['packagingroot'])) { $installregistry = &new PEAR_Registry($regdir); if (!$installregistry->channelExists($channel, true)) { // we need to fake a channel-discover of this channel $chanobj = $this->_registry->getChannel($channel, true); $installregistry->addChannel($chanobj); } $php_dir = $packrootphp_dir; } else { $installregistry = &$this->_registry; $php_dir = $this->config->get('php_dir', null, $channel); } $this->installroot = ''; } // {{{ checks to do when not in "force" mode if (empty($options['force']) && (file_exists($this->config->get('php_dir')) && is_dir($this->config->get('php_dir')))) { $testp = $channel == 'pear.php.net' ? $pkgname : array($channel, $pkgname); $instfilelist = $pkg->getInstallationFileList(true); if (PEAR::isError($instfilelist)) { return $instfilelist; } // ensure we have the most accurate registry $installregistry->flushFileMap(); $test = $installregistry->checkFileMap($instfilelist, $testp, '1.1'); if (PEAR::isError($test)) { return $test; } if (sizeof($test)) { $pkgs = $this->getInstallPackages(); $found = false; foreach ($pkgs as $param) { if ($pkg->isSubpackageOf($param)) { $found = true; break; } } if ($found) { // subpackages can conflict with earlier versions of parent packages $parentreg = $installregistry->packageInfo($param->getPackage(), null, $param->getChannel()); $tmp = $test; foreach ($tmp as $file => $info) { if (is_array($info)) { if (strtolower($info[1]) == strtolower($param->getPackage()) && strtolower($info[0]) == strtolower($param->getChannel()) ) { if (isset($parentreg['filelist'][$file])) { unset($parentreg['filelist'][$file]); } else{ $pos = strpos($file, '/'); $basedir = substr($file, 0, $pos); $file2 = substr($file, $pos + 1); if (isset($parentreg['filelist'][$file2]['baseinstalldir']) && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir ) { unset($parentreg['filelist'][$file2]); } } unset($test[$file]); } } else { if (strtolower($param->getChannel()) != 'pear.php.net') { continue; } if (strtolower($info) == strtolower($param->getPackage())) { if (isset($parentreg['filelist'][$file])) { unset($parentreg['filelist'][$file]); } else{ $pos = strpos($file, '/'); $basedir = substr($file, 0, $pos); $file2 = substr($file, $pos + 1); if (isset($parentreg['filelist'][$file2]['baseinstalldir']) && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir ) { unset($parentreg['filelist'][$file2]); } } unset($test[$file]); } } } $pfk = &new PEAR_PackageFile($this->config); $parentpkg = &$pfk->fromArray($parentreg); $installregistry->updatePackage2($parentpkg); } if ($param->getChannel() == 'pecl.php.net' && isset($options['upgrade'])) { $tmp = $test; foreach ($tmp as $file => $info) { if (is_string($info)) { // pear.php.net packages are always stored as strings if (strtolower($info) == strtolower($param->getPackage())) { // upgrading existing package unset($test[$file]); } } } } if (count($test)) { $msg = "$channel/$pkgname: conflicting files found:\n"; $longest = max(array_map("strlen", array_keys($test))); $fmt = "%${longest}s (%s)\n"; foreach ($test as $file => $info) { if (!is_array($info)) { $info = array('pear.php.net', $info); } $info = $info[0] . '/' . $info[1]; $msg .= sprintf($fmt, $file, $info); } if (!isset($options['ignore-errors'])) { return $this->raiseError($msg); } if (!isset($options['soft'])) { $this->log(0, "WARNING: $msg"); } } } } // }}} $this->startFileTransaction(); $usechannel = $channel; if ($channel == 'pecl.php.net') { $test = $installregistry->packageExists($pkgname, $channel); if (!$test) { $test = $installregistry->packageExists($pkgname, 'pear.php.net'); $usechannel = 'pear.php.net'; } } else { $test = $installregistry->packageExists($pkgname, $channel); } if (empty($options['upgrade']) && empty($options['soft'])) { // checks to do only when installing new packages if (empty($options['force']) && $test) { return $this->raiseError("$channel/$pkgname is already installed"); } } else { // Upgrade if ($test) { $v1 = $installregistry->packageInfo($pkgname, 'version', $usechannel); $v2 = $pkg->getVersion(); $cmp = version_compare("$v1", "$v2", 'gt'); if (empty($options['force']) && !version_compare("$v2", "$v1", 'gt')) { return $this->raiseError("upgrade to a newer version ($v2 is not newer than $v1)"); } } } // Do cleanups for upgrade and install, remove old release's files first if ($test && empty($options['register-only'])) { // when upgrading, remove old release's files first: if (PEAR::isError($err = $this->_deletePackageFiles($pkgname, $usechannel, true))) { if (!isset($options['ignore-errors'])) { return $this->raiseError($err); } if (!isset($options['soft'])) { $this->log(0, 'WARNING: ' . $err->getMessage()); } } else { $backedup = $err; } } // {{{ Copy files to dest dir --------------------------------------- // info from the package it self we want to access from _installFile $this->pkginfo = &$pkg; // used to determine whether we should build any C code $this->source_files = 0; $savechannel = $this->config->get('default_channel'); if (empty($options['register-only']) && !is_dir($php_dir)) { if (PEAR::isError(System::mkdir(array('-p'), $php_dir))) { return $this->raiseError("no installation destination directory '$php_dir'\n"); } } if (substr($pkgfile, -4) != '.xml') { $tmpdir .= DIRECTORY_SEPARATOR . $pkgname . '-' . $pkg->getVersion(); } $this->configSet('default_channel', $channel); // {{{ install files $ver = $pkg->getPackagexmlVersion(); if (version_compare($ver, '2.0', '>=')) { $filelist = $pkg->getInstallationFilelist(); } else { $filelist = $pkg->getFileList(); } if (PEAR::isError($filelist)) { return $filelist; } $p = &$installregistry->getPackage($pkgname, $channel); $dirtree = (empty($options['register-only']) && $p) ? $p->getDirTree() : false; $pkg->resetFilelist(); $pkg->setLastInstalledVersion($installregistry->packageInfo($pkg->getPackage(), 'version', $pkg->getChannel())); foreach ($filelist as $file => $atts) { $this->expectError(PEAR_INSTALLER_FAILED); if ($pkg->getPackagexmlVersion() == '1.0') { $res = $this->_installFile($file, $atts, $tmpdir, $options); } else { $res = $this->_installFile2($pkg, $file, $atts, $tmpdir, $options); } $this->popExpect(); if (PEAR::isError($res)) { if (empty($options['ignore-errors'])) { $this->rollbackFileTransaction(); if ($res->getMessage() == "file does not exist") { $this->raiseError("file $file in package.xml does not exist"); } return $this->raiseError($res); } if (!isset($options['soft'])) { $this->log(0, "Warning: " . $res->getMessage()); } } $real = isset($atts['attribs']) ? $atts['attribs'] : $atts; if ($res == PEAR_INSTALLER_OK && $real['role'] != 'src') { // Register files that were installed $pkg->installedFile($file, $atts); } } // }}} // {{{ compile and install source files if ($this->source_files > 0 && empty($options['nobuild'])) { if (PEAR::isError($err = $this->_compileSourceFiles($savechannel, $pkg))) { return $err; } } // }}} if (isset($backedup)) { $this->_removeBackups($backedup); } if (!$this->commitFileTransaction()) { $this->rollbackFileTransaction(); $this->configSet('default_channel', $savechannel); return $this->raiseError("commit failed", PEAR_INSTALLER_FAILED); } // }}} $ret = false; $installphase = 'install'; $oldversion = false; // {{{ Register that the package is installed ----------------------- if (empty($options['upgrade'])) { // if 'force' is used, replace the info in registry $usechannel = $channel; if ($channel == 'pecl.php.net') { $test = $installregistry->packageExists($pkgname, $channel); if (!$test) { $test = $installregistry->packageExists($pkgname, 'pear.php.net'); $usechannel = 'pear.php.net'; } } else { $test = $installregistry->packageExists($pkgname, $channel); } if (!empty($options['force']) && $test) { $oldversion = $installregistry->packageInfo($pkgname, 'version', $usechannel); $installregistry->deletePackage($pkgname, $usechannel); } $ret = $installregistry->addPackage2($pkg); } else { if ($dirtree) { $this->startFileTransaction(); // attempt to delete empty directories uksort($dirtree, array($this, '_sortDirs')); foreach($dirtree as $dir => $notused) { $this->addFileOperation('rmdir', array($dir)); } $this->commitFileTransaction(); } $usechannel = $channel; if ($channel == 'pecl.php.net') { $test = $installregistry->packageExists($pkgname, $channel); if (!$test) { $test = $installregistry->packageExists($pkgname, 'pear.php.net'); $usechannel = 'pear.php.net'; } } else { $test = $installregistry->packageExists($pkgname, $channel); } // new: upgrade installs a package if it isn't installed if (!$test) { $ret = $installregistry->addPackage2($pkg); } else { if ($usechannel != $channel) { $installregistry->deletePackage($pkgname, $usechannel); $ret = $installregistry->addPackage2($pkg); } else { $ret = $installregistry->updatePackage2($pkg); } $installphase = 'upgrade'; } } if (!$ret) { $this->configSet('default_channel', $savechannel); return $this->raiseError("Adding package $channel/$pkgname to registry failed"); } // }}} $this->configSet('default_channel', $savechannel); if (class_exists('PEAR_Task_Common')) { // this is auto-included if any tasks exist if (PEAR_Task_Common::hasPostinstallTasks()) { PEAR_Task_Common::runPostinstallTasks($installphase); } } return $pkg->toArray(true); } // }}} // {{{ _compileSourceFiles() /** * @param string * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 */ function _compileSourceFiles($savechannel, &$filelist) { require_once 'PEAR/Builder.php'; $this->log(1, "$this->source_files source files, building"); $bob = &new PEAR_Builder($this->ui); $bob->debug = $this->debug; $built = $bob->build($filelist, array(&$this, '_buildCallback')); if (PEAR::isError($built)) { $this->rollbackFileTransaction(); $this->configSet('default_channel', $savechannel); return $built; } $this->log(1, "\nBuild process completed successfully"); foreach ($built as $ext) { $bn = basename($ext['file']); list($_ext_name, $_ext_suff) = explode('.', $bn); if ($_ext_suff == '.so' || $_ext_suff == '.dll') { if (extension_loaded($_ext_name)) { $this->raiseError("Extension '$_ext_name' already loaded. " . 'Please unload it in your php.ini file ' . 'prior to install or upgrade'); } $role = 'ext'; } else { $role = 'src'; } $dest = $ext['dest']; $packagingroot = ''; if (isset($this->_options['packagingroot'])) { $packagingroot = $this->_options['packagingroot']; } $copyto = $this->_prependPath($dest, $packagingroot); $extra = $copyto != $dest ? " as '$copyto'" : ''; $this->log(1, "Installing '$dest'$extra"); $copydir = dirname($copyto); // pretty much nothing happens if we are only registering the install if (empty($this->_options['register-only'])) { if (!file_exists($copydir) || !is_dir($copydir)) { if (!$this->mkDirHier($copydir)) { return $this->raiseError("failed to mkdir $copydir", PEAR_INSTALLER_FAILED); } $this->log(3, "+ mkdir $copydir"); } if (!@copy($ext['file'], $copyto)) { return $this->raiseError("failed to write $copyto ($php_errormsg)", PEAR_INSTALLER_FAILED); } $this->log(3, "+ cp $ext[file] $copyto"); $this->addFileOperation('rename', array($ext['file'], $copyto)); if (!OS_WINDOWS) { $mode = 0666 & ~(int)octdec($this->config->get('umask')); $this->addFileOperation('chmod', array($mode, $copyto)); if (!@chmod($copyto, $mode)) { $this->log(0, "failed to change mode of $copyto ($php_errormsg)"); } } } $data = array( 'role' => $role, 'name' => $bn, 'installed_as' => $dest, 'php_api' => $ext['php_api'], 'zend_mod_api' => $ext['zend_mod_api'], 'zend_ext_api' => $ext['zend_ext_api'], ); if ($filelist->getPackageXmlVersion() == '1.0') { $filelist->installedFile($bn, $data); } else { $filelist->installedFile($bn, array('attribs' => $data)); } } } // }}} function &getUninstallPackages() { return $this->_downloadedPackages; } // {{{ uninstall() /** * Uninstall a package * * This method removes all files installed by the application, and then * removes any empty directories. * @param string package name * @param array Command-line options. Possibilities include: * * - installroot: base installation dir, if not the default * - register-only : update registry but don't remove files * - nodeps: do not process dependencies of other packages to ensure * uninstallation does not break things */ function uninstall($package, $options = array()) { $installRoot = isset($options['installroot']) ? $options['installroot'] : ''; $this->config->setInstallRoot($installRoot); $this->installroot = ''; $this->_registry = &$this->config->getRegistry(); if (is_object($package)) { $channel = $package->getChannel(); $pkg = $package; $package = $pkg->getPackage(); } else { $pkg = false; $info = $this->_registry->parsePackageName($package, $this->config->get('default_channel')); $channel = $info['channel']; $package = $info['package']; } $savechannel = $this->config->get('default_channel'); $this->configSet('default_channel', $channel); if (!is_object($pkg)) { $pkg = $this->_registry->getPackage($package, $channel); } if (!$pkg) { $this->configSet('default_channel', $savechannel); return $this->raiseError($this->_registry->parsedPackageNameToString( array( 'channel' => $channel, 'package' => $package ), true) . ' not installed'); } if ($pkg->getInstalledBinary()) { // this is just an alias for a binary package return $this->_registry->deletePackage($package, $channel); } $filelist = $pkg->getFilelist(); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); if (!class_exists('PEAR_Dependency2')) { require_once 'PEAR/Dependency2.php'; } $depchecker = &new PEAR_Dependency2($this->config, $options, array('channel' => $channel, 'package' => $package), PEAR_VALIDATE_UNINSTALLING); $e = $depchecker->validatePackageUninstall($this); PEAR::staticPopErrorHandling(); if (PEAR::isError($e)) { if (!isset($options['ignore-errors'])) { return $this->raiseError($e); } if (!isset($options['soft'])) { $this->log(0, 'WARNING: ' . $e->getMessage()); } } elseif (is_array($e)) { if (!isset($options['soft'])) { $this->log(0, $e[0]); } } $this->pkginfo = &$pkg; // pretty much nothing happens if we are only registering the uninstall if (empty($options['register-only'])) { // {{{ Delete the files $this->startFileTransaction(); PEAR::pushErrorHandling(PEAR_ERROR_RETURN); if (PEAR::isError($err = $this->_deletePackageFiles($package, $channel))) { PEAR::popErrorHandling(); $this->rollbackFileTransaction(); $this->configSet('default_channel', $savechannel); if (!isset($options['ignore-errors'])) { return $this->raiseError($err); } if (!isset($options['soft'])) { $this->log(0, 'WARNING: ' . $err->getMessage()); } } else { PEAR::popErrorHandling(); } if (!$this->commitFileTransaction()) { $this->rollbackFileTransaction(); if (!isset($options['ignore-errors'])) { return $this->raiseError("uninstall failed"); } if (!isset($options['soft'])) { $this->log(0, 'WARNING: uninstall failed'); } } else { $this->startFileTransaction(); $dirtree = $pkg->getDirTree(); if ($dirtree === false) { $this->configSet('default_channel', $savechannel); return $this->_registry->deletePackage($package, $channel); } // attempt to delete empty directories uksort($dirtree, array($this, '_sortDirs')); foreach($dirtree as $dir => $notused) { $this->addFileOperation('rmdir', array($dir)); } if (!$this->commitFileTransaction()) { $this->rollbackFileTransaction(); if (!isset($options['ignore-errors'])) { return $this->raiseError("uninstall failed"); } if (!isset($options['soft'])) { $this->log(0, 'WARNING: uninstall failed'); } } } // }}} } $this->configSet('default_channel', $savechannel); // Register that the package is no longer installed return $this->_registry->deletePackage($package, $channel); } /** * Sort a list of arrays of array(downloaded packagefilename) by dependency. * * It also removes duplicate dependencies * @param array an array of PEAR_PackageFile_v[1/2] objects * @return array|PEAR_Error array of array(packagefilename, package.xml contents) */ function sortPackagesForUninstall(&$packages) { $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->config); if (PEAR::isError($this->_dependencyDB)) { return $this->_dependencyDB; } usort($packages, array(&$this, '_sortUninstall')); } function _sortUninstall($a, $b) { if (!$a->getDeps() && !$b->getDeps()) { return 0; // neither package has dependencies, order is insignificant } if ($a->getDeps() && !$b->getDeps()) { return -1; // $a must be installed after $b because $a has dependencies } if (!$a->getDeps() && $b->getDeps()) { return 1; // $b must be installed after $a because $b has dependencies } // both packages have dependencies if ($this->_dependencyDB->dependsOn($a, $b)) { return -1; } if ($this->_dependencyDB->dependsOn($b, $a)) { return 1; } return 0; } // }}} // {{{ _sortDirs() function _sortDirs($a, $b) { if (strnatcmp($a, $b) == -1) return 1; if (strnatcmp($a, $b) == 1) return -1; return 0; } // }}} // {{{ _buildCallback() function _buildCallback($what, $data) { if (($what == 'cmdoutput' && $this->debug > 1) || ($what == 'output' && $this->debug > 0)) { $this->ui->outputData(rtrim($data), 'build'); } } // }}} }
Save