#!/usr/bin/env php
<?php

$web = 'index.php';

if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) {
Phar::interceptFileFuncs();
set_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path());
Phar::webPhar(null, $web);
include 'phar://' . __FILE__ . '/' . Extract_Phar::START;
return;
}

if (@(isset($_SERVER['REQUEST_URI']) && isset($_SERVER['REQUEST_METHOD']) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'POST'))) {
Extract_Phar::go(true);
$mimes = array(
'phps' => 2,
'c' => 'text/plain',
'cc' => 'text/plain',
'cpp' => 'text/plain',
'c++' => 'text/plain',
'dtd' => 'text/plain',
'h' => 'text/plain',
'log' => 'text/plain',
'rng' => 'text/plain',
'txt' => 'text/plain',
'xsd' => 'text/plain',
'php' => 1,
'inc' => 1,
'avi' => 'video/avi',
'bmp' => 'image/bmp',
'css' => 'text/css',
'gif' => 'image/gif',
'htm' => 'text/html',
'html' => 'text/html',
'htmls' => 'text/html',
'ico' => 'image/x-ico',
'jpe' => 'image/jpeg',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'js' => 'application/x-javascript',
'midi' => 'audio/midi',
'mid' => 'audio/midi',
'mod' => 'audio/mod',
'mov' => 'movie/quicktime',
'mp3' => 'audio/mp3',
'mpg' => 'video/mpeg',
'mpeg' => 'video/mpeg',
'pdf' => 'application/pdf',
'png' => 'image/png',
'swf' => 'application/shockwave-flash',
'tif' => 'image/tiff',
'tiff' => 'image/tiff',
'wav' => 'audio/wav',
'xbm' => 'image/xbm',
'xml' => 'text/xml',
);

header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");

$basename = basename(__FILE__);
if (!strpos($_SERVER['REQUEST_URI'], $basename)) {
chdir(Extract_Phar::$temp);
include $web;
return;
}
$pt = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $basename) + strlen($basename));
if (!$pt || $pt == '/') {
$pt = $web;
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $_SERVER['REQUEST_URI'] . '/' . $pt);
exit;
}
$a = realpath(Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt);
if (!$a || strlen(dirname($a)) < strlen(Extract_Phar::$temp)) {
header('HTTP/1.0 404 Not Found');
echo "<html>\n <head>\n  <title>File Not Found<title>\n </head>\n <body>\n  <h1>404 - File Not Found</h1>\n </body>\n</html>";
exit;
}
$b = pathinfo($a);
if (!isset($b['extension'])) {
header('Content-Type: text/plain');
header('Content-Length: ' . filesize($a));
readfile($a);
exit;
}
if (isset($mimes[$b['extension']])) {
if ($mimes[$b['extension']] === 1) {
include $a;
exit;
}
if ($mimes[$b['extension']] === 2) {
highlight_file($a);
exit;
}
header('Content-Type: ' .$mimes[$b['extension']]);
header('Content-Length: ' . filesize($a));
readfile($a);
exit;
}
}

class Extract_Phar
{
static $temp;
static $origdir;
const GZ = 0x1000;
const BZ2 = 0x2000;
const MASK = 0x3000;
const START = 'index.php';
const LEN = 6643;

static function go($return = false)
{
$fp = fopen(__FILE__, 'rb');
fseek($fp, self::LEN);
$L = unpack('V', $a = fread($fp, 4));
$m = '';

do {
$read = 8192;
if ($L[1] - strlen($m) < 8192) {
$read = $L[1] - strlen($m);
}
$last = fread($fp, $read);
$m .= $last;
} while (strlen($last) && strlen($m) < $L[1]);

if (strlen($m) < $L[1]) {
die('ERROR: manifest length read was "' .
strlen($m) .'" should be "' .
$L[1] . '"');
}

$info = self::_unpack($m);
$f = $info['c'];

if ($f & self::GZ) {
if (!function_exists('gzinflate')) {
die('Error: zlib extension is not enabled -' .
' gzinflate() function needed for zlib-compressed .phars');
}
}

if ($f & self::BZ2) {
if (!function_exists('bzdecompress')) {
die('Error: bzip2 extension is not enabled -' .
' bzdecompress() function needed for bz2-compressed .phars');
}
}

$temp = self::tmpdir();

if (!$temp || !is_writable($temp)) {
$sessionpath = session_save_path();
if (strpos ($sessionpath, ";") !== false)
$sessionpath = substr ($sessionpath, strpos ($sessionpath, ";")+1);
if (!file_exists($sessionpath) || !is_dir($sessionpath)) {
die('Could not locate temporary directory to extract phar');
}
$temp = $sessionpath;
}

$temp .= '/pharextract/'.basename(__FILE__, '.phar');
self::$temp = $temp;
self::$origdir = getcwd();
@mkdir($temp, 0777, true);
$temp = realpath($temp);

if (!file_exists($temp . DIRECTORY_SEPARATOR . md5_file(__FILE__))) {
self::_removeTmpFiles($temp, getcwd());
@mkdir($temp, 0777, true);
@file_put_contents($temp . '/' . md5_file(__FILE__), '');

foreach ($info['m'] as $path => $file) {
$a = !file_exists(dirname($temp . '/' . $path));
@mkdir(dirname($temp . '/' . $path), 0777, true);
clearstatcache();

if ($path[strlen($path) - 1] == '/') {
@mkdir($temp . '/' . $path, 0777);
} else {
file_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp));
@chmod($temp . '/' . $path, 0666);
}
}
}

chdir($temp);

if (!$return) {
include self::START;
}
}

static function tmpdir()
{
if (strpos(PHP_OS, 'WIN') !== false) {
if ($var = getenv('TMP') ? getenv('TMP') : getenv('TEMP')) {
return $var;
}
if (is_dir('/temp') || mkdir('/temp')) {
return realpath('/temp');
}
return false;
}
if ($var = getenv('TMPDIR')) {
return $var;
}
return realpath('/tmp');
}

static function _unpack($m)
{
$info = unpack('V', substr($m, 0, 4));
 $l = unpack('V', substr($m, 10, 4));
$m = substr($m, 14 + $l[1]);
$s = unpack('V', substr($m, 0, 4));
$o = 0;
$start = 4 + $s[1];
$ret['c'] = 0;

for ($i = 0; $i < $info[1]; $i++) {
 $len = unpack('V', substr($m, $start, 4));
$start += 4;
 $savepath = substr($m, $start, $len[1]);
$start += $len[1];
   $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24)));
$ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3]
& 0xffffffff);
$ret['m'][$savepath][7] = $o;
$o += $ret['m'][$savepath][2];
$start += 24 + $ret['m'][$savepath][5];
$ret['c'] |= $ret['m'][$savepath][4] & self::MASK;
}
return $ret;
}

static function extractFile($path, $entry, $fp)
{
$data = '';
$c = $entry[2];

while ($c) {
if ($c < 8192) {
$data .= @fread($fp, $c);
$c = 0;
} else {
$c -= 8192;
$data .= @fread($fp, 8192);
}
}

if ($entry[4] & self::GZ) {
$data = gzinflate($data);
} elseif ($entry[4] & self::BZ2) {
$data = bzdecompress($data);
}

if (strlen($data) != $entry[0]) {
die("Invalid internal .phar file (size error " . strlen($data) . " != " .
$stat[7] . ")");
}

if ($entry[3] != sprintf("%u", crc32($data) & 0xffffffff)) {
die("Invalid internal .phar file (checksum error)");
}

return $data;
}

static function _removeTmpFiles($temp, $origdir)
{
chdir($temp);

foreach (glob('*') as $f) {
if (file_exists($f)) {
is_dir($f) ? @rmdir($f) : @unlink($f);
if (file_exists($f) && is_dir($f)) {
self::_removeTmpFiles($f, getcwd());
}
}
}

@rmdir($temp);
clearstatcache();
chdir($origdir);
}
}

Extract_Phar::go();
__HALT_COMPILER(); ?>
          
   eecms.phar    	   index.php  Z  ʨw         upgrade.php  Z  J         helpers.php  Z        <?php

if (strpos(__DIR__, '/ee/eecms') === FALSE)
{
	exit('The eecms utility must be kept in your /system/ee directory.');
}

if (version_compare(phpversion(), '5.4', '<'))
{
	exit('The command line version of PHP is less than the required version of 5.4.');
}

// In case a default isn't set on the server
date_default_timezone_set('UTC');

require_once __DIR__.'/helpers.php';

$project_base = realpath(str_replace('phar://', '', dirname(__DIR__)).'/../').'/';

$args = parseArguments();

// Path constants
define('SELF', basename(__FILE__));
define('SYSPATH', $project_base);
define('SYSDIR', basename($project_base));
define('FCPATH', dirname(SELF));
define('DEBUG', 1);
define('REQ', 'CLI');
define('CLI_VERBOSE', isset($args['v']) OR isset($args['verbose']));

// Load up ExpressionEngine
if ( ! isset($args['no-bootstrap']) && !
	(in_array('upgrade', $args) && isset($args['rollback'])))
{
	$bootstrap = SYSPATH.'ee/EllisLab/ExpressionEngine/Boot/boot.php';
	if (file_exists($bootstrap))
	{
		define('BOOT_ONLY', TRUE);
		require_once $bootstrap;
	}
}

$supported_commands = ['upgrade'];

// Load up the file for this command
if (isset($args[0]) && in_array($args[0], $supported_commands))
{
	$command = array_shift($args);

	try
	{
		require_once 'phar://eecms.phar/'.$command.'.php';
		new Command($args);
	}
	catch (\Exception $e)
	{
		echo $e->getMessage();
		exit;
	}
}
else
{
	exit('Available commands:

upgrade               Upgrade this installation of ExpressionEngine
upgrade --rollback    Rollback the install if an upgrade failed');
}
<?php

$updater_boot = SYSPATH.'/ee/updater/boot.php';
if (file_exists($updater_boot))
{
	require_once $updater_boot;
}

class Command {

	/**
	 * Constructor
	 *
	 * @param array $params CLI arguments as parsed by parseArguments()
	 */
	public function __construct($params = [])
	{
		set_error_handler(array($this, 'showError'));

		try
		{
			if (isset($params['microapp']))
			{
				$step = (isset($params['step'])) ? $params['step'] : NULL;
				return $this->updaterMicroapp($step);
			}

			if (isset($params['rollback']))
			{
				return $this->updaterMicroapp('rollback');
			}

			$this->start( ! isset($params['y']));
		}
		catch (\Exception $e)
		{
			$this->showError($e->getCode(), $e->getMessage());
			exit;
		}
	}

	/**
	 * Kicks off a new upgrade
	 */
	public function start($interactive = TRUE)
	{
		ee()->load->library('el_pings');
		$version_file = ee()->el_pings->get_version_info(TRUE);
		$to_version = $version_file['latest_version'];
		$core_to_pro = (IS_CORE && $version_file['license_type'] == 'pro');

		if (version_compare(ee()->config->item('app_version'), $to_version, '>=') && ! $core_to_pro)
		{
			exit('ExpressionEngine '.APP_VER.' is already up-to-date!');
		}

		echo "There is a new version of ExpressionEngine available: " . $to_version . "\n";

		if ($interactive)
		{
			echo "Would you like to upgrade? (y/n): ";
			$stdin = trim(fgets(STDIN));
			if ( ! in_array($stdin, ['yes', 'y']))
			{
				exit;
			}
		}

		// Preflight checks, download and unpack update
		ee('Updater/Runner')->run();

		// Launch into microapp
		runCommandExternally('upgrade --microapp --no-bootstrap');
	}

	/**
	 * Runs a step through the updater microapp
	 *
	 * @param string $step The name of the step to run
	 */
	public function updaterMicroapp($step = NULL)
	{
		if ( ! class_exists('EllisLab\ExpressionEngine\Updater\Service\Updater\Runner'))
		{
			exit('Cannot rollback, updater microapp not found.');
		}

		$runner = new EllisLab\ExpressionEngine\Updater\Service\Updater\Runner();

		if ( ! $step)
		{
			$step = $runner->getFirstStep();
		}

		$runner->runStep($step);

		// Perform each step as its own command so we can control the scope of
		// files loaded into the app's memory
		if (($next_step = $runner->getNextStep()) !== FALSE)
		{
			if ($next_step == 'rollback')
			{
				return runCommandExternally('upgrade --rollback');
			}

			$cmd = 'upgrade --microapp --step="'.$next_step.'"';

			// We can't rely on loading EE during these steps
			if ($next_step == 'updateFiles')
			{
				$cmd .= ' --no-bootstrap';
			}

			runCommandExternally($cmd);
		}
	}

	/**
	 * Custom PHP error handler
	 */
	public function showError($code, $error, $file = NULL, $line = NULL)
	{
		if (error_reporting() === 0)
		{
			return;
		}

		$message = "We could not complete the update because an error has occured:\n\033[0m";
		$message .= strip_tags($error);

		if ($file && $line)
		{
			$message .= "\n\n".$file.':'.$line;
		}

		stdout($message, CLI_STDOUT_FAILURE);
		exit;
	}
}

// EOF
<?php

/**
 * Helper function to parse the global $argv into something useful; we cannot
 * use getopt() as we want to support subcommands
 *
 * @return array
 */
function parseArguments()
{
	global $argv;
	array_shift($argv);
	$out = array();
	foreach ($argv as $arg)
	{
		if (substr($arg, 0, 2) == '--')
		{
			$eqPos = strpos($arg, '=');
			if ($eqPos === false)
			{
				$key = substr($arg, 2);
				$out[$key] = isset($out[$key]) ? $out[$key] : true;
			}
			else
			{
				$key = substr($arg, 2, $eqPos - 2);
				$out[$key] = substr($arg, $eqPos + 1);
			}
		}
		else if (substr($arg, 0, 1) == '-')
		{
			if (substr($arg, 2, 1) == '=')
			{
				$key = substr($arg, 1, 1);
				$out[$key] = substr($arg, 3);
			}
			else
			{
				$chars = str_split(substr($arg, 1));
				foreach ($chars as $char)
				{
					$key = $char;
					$out[$key] = isset($out[$key]) ? $out[$key] : true;
				}
			}
		}
		else
		{
			$out[] = $arg;
		}
	}
	return $out;
}

/**
 * Runs a an eecms.phar command externally from the current process/scope
 *
 * @param	string	$command	Command to run, string that normally follows
 *   "eecms.phar" on the command line
 */
function runCommandExternally($command)
{
	if (CLI_VERBOSE)
	{
		$command .= ' -v';
	}

	system('php '.SYSPATH.'ee/eecms ' . $command);
}


define('CLI_STDOUT_NORMAL', 1);
define('CLI_STDOUT_BOLD', 2);
define('CLI_STDOUT_SUCCESS', 3);
define('CLI_STDOUT_FAILURE', 4);

/**
 * Sends a message to stdout if we're in the CLI
 *
 * @param	string	$message	Message to display
 * @param	const	$status		Status of message, affects appearance
 */
function stdout($message, $status = CLI_STDOUT_NORMAL)
{
	$text_color = '[1;37m';

	switch ($status) {
		case CLI_STDOUT_BOLD:
			$arrow_color = '[0;34m';
			$text_color = '[1;37m';
			break;
		case CLI_STDOUT_SUCCESS:
			$arrow_color = '[0;32m';
			break;
		case CLI_STDOUT_FAILURE:
			$arrow_color = '[0;31m';
			break;
		default:
			$arrow_color = $text_color = '[0m';
			break;
	}

	if (REQ == 'CLI' && ! empty($message))
	{
		$message = "\033".$arrow_color."==> \033" . $text_color . strip_tags($message) . "\033[0m\n";

		$stdout = fopen('php://stdout', 'w');
		fwrite($stdout, $message);
		fclose($stdout);
	}
}

// EOF
(X?$*q   GBMB