Your IP : 172.28.240.42


Current Path : /var/www/html/clients/amz.e-nk.ru/bitrix/modules/main/classes/general/
Upload File :
Current File : /var/www/html/clients/amz.e-nk.ru/bitrix/modules/main/classes/general/update_client.php

<?
/**********************************************************************/
/**    DO NOT MODIFY THIS FILE                                       **/
/**    MODIFICATION OF THIS FILE WILL ENTAIL SITE FAILURE            **/
/**********************************************************************/
define("UPDATE_SYSTEM_VERSION_A", "9.5.6");

if (!defined("BX_DIR_PERMISSIONS"))
	define("BX_DIR_PERMISSIONS", 0777);

//define("DEFAULT_UPDATE_SERVER", "www.bitrixsoft.com");
define("DEFAULT_UPDATE_SERVER", "mysql.smn");

IncludeModuleLangFile(__FILE__);

if (!function_exists("file_get_contents"))
{
	function file_get_contents($filename)
	{
		$fd = fopen("$filename", "rb");
		$content = fread($fd, filesize($filename));
		fclose($fd);
		return $content;
	}
}

if (!function_exists("bx_accelerator_reset"))
{
	function bx_accelerator_reset()
	{
		if(function_exists("accelerator_reset"))
			accelerator_reset();
		elseif(function_exists("wincache_refresh_if_changed"))
			wincache_refresh_if_changed();
	}
}

if (!defined("US_SHARED_KERNEL_PATH"))
	define("US_SHARED_KERNEL_PATH", "/bitrix");

if (!defined("US_CALL_TYPE"))
	define("US_CALL_TYPE", "ALL");

if (!defined("US_BASE_MODULE"))
	define("US_BASE_MODULE", "main");

$GLOBALS["UPDATE_STRONG_UPDATE_CHECK"] = "";
$GLOBALS["CACHE4UPDATESYS_LICENSE_KEY"] = "";

require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/classes/general/update_class.php");

class CUpdateClient
{
	function Repair($type, $stableVersionsOnly, $lang = false)
	{
		if ($type == "include")
		{
			if (CUpdateClient::RegisterVersion($errorMessage, $lang, $stableVersionsOnly))
				CUpdateClient::AddMessage2Log("Include repaired");
			else
				CUpdateClient::AddMessage2Log("Include repair error: ".$errorMessage);
		}
	}

	function IsUpdateAvailable(&$arModulesParam, &$strError)
	{
		$arModulesParam = array();
		$strError = "";

		$stableVersionsOnly = COption::GetOptionString("main", "stable_versions_only", "Y");

		$arUpdateList = CUpdateClient::GetUpdatesList($strError, LANG, $stableVersionsOnly);
		if (!$arUpdateList)
			return false;

		if (isset($arUpdateList["ERROR"]))
		{
			for ($i = 0, $cnt = count($arUpdateList["ERROR"]); $i < $cnt; $i++)
				$strError .= "[".$arUpdateList["ERROR"][$i]["@"]["TYPE"]."] ".$arUpdateList["ERROR"][$i]["#"];

			return false;
		}

		if (isset($arUpdateList["MODULES"]) && is_array($arUpdateList["MODULES"]) && is_array($arUpdateList["MODULES"][0]["#"]["MODULE"]))
		{
			$arModulesParam = $arUpdateList["MODULES"][0]["#"]["MODULE"];
			return true;
		}

		if (isset($arUpdateList["UPDATE_SYSTEM"]))
			return true;

		return false;
	}

	function SubscribeMail($email, &$strError, $lang = false, $stableVersionsOnly = "Y")
	{
		$strError_tmp = "";

		CUpdateClient::AddMessage2Log("exec CUpdateClient::SubscribeMail");

		$updateServerQueryString = CUpdateClient::CollectRequestData($strError_tmp, $lang, $stableVersionsOnly, array(), array(), array());
		if ($updateServerQueryString === False || StrLen($updateServerQueryString) <= 0 || StrLen($strError_tmp) > 0)
		{
			if (StrLen($strError_tmp) <= 0)
				$strError_tmp = "[RV01] ".GetMessage("SUPZ_NO_QSTRING").". ";
		}

		if (StrLen($strError_tmp) <= 0)
		{
			$updateServerQueryString .= "&email=".UrlEncode($email)."&query_type=mail";
			CUpdateClient::AddMessage2Log(preg_replace("/LICENSE_KEY=[^&]*/i", "LICENSE_KEY=X", $updateServerQueryString));

			/*
			foreach ($arFields as $key => $value)
				$updateServerQueryString .= "&".$key."=".urlencode($value);
			*/

			$stime = CUpdateClient::getmicrotime();
			$content = CUpdateClient::GetHTTPPage("ACTIV", $updateServerQueryString, $strError_tmp);
			if (strlen($content) <= 0)
			{
				if (StrLen($strError_tmp) <= 0)
					$strError_tmp = "[GNSU02] ".GetMessage("SUPZ_EMPTY_ANSWER").". ";
			}

			CUpdateClient::AddMessage2Log("TIME SubscribeMail(request) ".Round(CUpdateClient::getmicrotime() - $stime, 3)." sec");
		}

		if (strlen($strError_tmp) <= 0)
		{
			$arRes = Array();
			CUpdateClient::ParseServerData($content, $arRes, $strError_tmp);
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (isset($arRes["DATA"]["#"]["ERROR"]) && is_array($arRes["DATA"]["#"]["ERROR"]) && count($arRes["DATA"]["#"]["ERROR"]) > 0)
			{
				for ($i = 0; $i < count($arRes["DATA"]["#"]["ERROR"]); $i++)
				{
					if (strlen($arRes["DATA"]["#"]["ERROR"][$i]["@"]["TYPE"]) > 0)
						$strError_tmp .= "[".$arRes["DATA"]["#"]["ERROR"][$i]["@"]["TYPE"]."] ";

					$strError_tmp .= $arRes["DATA"]["#"]["ERROR"][$i]["#"].". ";
				}
			}
		}

		if (strlen($strError_tmp) > 0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "SM");
			$strError .= $strError_tmp;
			return False;
		}
		else
			return True;
	}

	function ActivateCoupon($coupon, &$strError, $lang = false, $stableVersionsOnly = "Y")
	{
		$strError_tmp = "";

		CUpdateClient::AddMessage2Log("exec CUpdateClient::ActivateCoupon");

		$updateServerQueryString = CUpdateClient::CollectRequestData($strError_tmp, $lang, $stableVersionsOnly, array(), array(), array());
		if ($updateServerQueryString === False || StrLen($updateServerQueryString) <= 0 || StrLen($strError_tmp) > 0)
		{
			if (StrLen($strError_tmp) <= 0)
				$strError_tmp = "[RV01] ".GetMessage("SUPZ_NO_QSTRING").". ";
		}

		if (StrLen($strError_tmp) <= 0)
		{
			$updateServerQueryString .= "&coupon=".UrlEncode($coupon)."&query_type=coupon";
			CUpdateClient::AddMessage2Log(preg_replace("/LICENSE_KEY=[^&]*/i", "LICENSE_KEY=X", $updateServerQueryString));

			/*
			foreach ($arFields as $key => $value)
				$updateServerQueryString .= "&".$key."=".urlencode($value);
			*/

			$stime = CUpdateClient::getmicrotime();
			$content = CUpdateClient::GetHTTPPage("ACTIV", $updateServerQueryString, $strError_tmp);
			if (strlen($content) <= 0)
			{
				if (StrLen($strError_tmp) <= 0)
					$strError_tmp = "[GNSU02] ".GetMessage("SUPZ_EMPTY_ANSWER").". ";
			}

			CUpdateClient::AddMessage2Log("TIME ActivateCoupon(request) ".Round(CUpdateClient::getmicrotime() - $stime, 3)." sec");
		}

		if (strlen($strError_tmp) <= 0)
		{
			$arRes = Array();
			CUpdateClient::ParseServerData($content, $arRes, $strError_tmp);
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (isset($arRes["DATA"]["#"]["ERROR"]) && is_array($arRes["DATA"]["#"]["ERROR"]) && count($arRes["DATA"]["#"]["ERROR"]) > 0)
			{
				for ($i = 0; $i < count($arRes["DATA"]["#"]["ERROR"]); $i++)
				{
					if (strlen($arRes["DATA"]["#"]["ERROR"][$i]["@"]["TYPE"]) > 0)
						$strError_tmp .= "[".$arRes["DATA"]["#"]["ERROR"][$i]["@"]["TYPE"]."] ";

					$strError_tmp .= $arRes["DATA"]["#"]["ERROR"][$i]["#"].". ";
				}
			}
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (isset($arRes["DATA"]["#"]["RENT"]) && is_array($arRes["DATA"]["#"]["RENT"]))
			{
				COption::SetOptionString('main', '~SAAS_MODE', "Y");
				CUpdateClient::__ApplyLicenseInfo($arRes["DATA"]["#"]["RENT"][0]["@"]);
			}
		}

		if (strlen($strError_tmp) > 0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "AC");
			$strError .= $strError_tmp;
			return False;
		}
		else
			return True;
	}

	function __ApplyLicenseInfo($arData)
	{
		if (array_key_exists("V1", $arData) && array_key_exists("V2", $arData))
		{
			COption::SetOptionString('main', 'admin_passwordh', $arData["V1"]);

			$fp = fopen($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/admin/define.php", 'w');
			fwrite($fp, "<"."?Define(\"TEMPORARY_CACHE\", \"".$arData["V2"]."\");?".">");
			fclose($fp);
		}

		if (array_key_exists("DATE_TO_SOURCE", $arData))
			COption::SetOptionString(US_BASE_MODULE, "~support_finish_date", $arData["DATE_TO_SOURCE"]);
		if (array_key_exists("MAX_SITES", $arData))
			COption::SetOptionString("main", "PARAM_MAX_SITES", IntVal($arData["MAX_SITES"]));
		if (array_key_exists("MAX_USERS", $arData))
			COption::SetOptionString("main", "PARAM_MAX_USERS", IntVal($arData["MAX_USERS"]));

		if (array_key_exists("L", $arData))
		{
			$arSavedValues = array();
			$savedValues = COption::GetOptionString("main", "~cpf_map_value", "");
			if (strlen($savedValues) > 0)
			{
				$savedValues = base64_decode($savedValues);
				$arSavedValues = unserialize($savedValues);
				if (!is_array($arSavedValues))
					$arSavedValues = array();
			}
			if (count($arSavedValues) <= 0)
				$arSavedValues = array("e" => array(), "f" => array());

			$arL = explode(",", $arData["L"]);
			foreach ($arL as $v)
				$arSavedValues["e"][$v] = array("F");

			$keys = array_keys($arSavedValues["e"]);
			foreach ($keys as $key)
			{
				if (in_array($key, $arL) || $key == "Portal")
				{
					$arSavedValues["e"][$key] = array("F");
				}
				else
				{
					if ($arSavedValues["e"][$key][0] != "D")
						$arSavedValues["e"][$key] = array("X");
				}
			}

			$savedValues = serialize($arSavedValues);
			$savedValues = base64_encode($savedValues);
			COption::SetOptionString("main", "~cpf_map_value", $savedValues);
		}
	}

	function UpdateUpdate(&$strError, $lang = false, $stableVersionsOnly = "Y")
	{
		$strError_tmp = "";

		CUpdateClient::AddMessage2Log("exec CUpdateClient::UpdateUpdate");

		$updateServerQueryString = CUpdateClient::CollectRequestData($strError_tmp, $lang, $stableVersionsOnly, array(), array(), array());
		if ($updateServerQueryString === False || StrLen($updateServerQueryString) <= 0 || StrLen($strError_tmp) > 0)
		{
			if (StrLen($strError_tmp) <= 0)
				$strError_tmp = "[RV01] ".GetMessage("SUPZ_NO_QSTRING").". ";
		}

		if (StrLen($strError_tmp) <= 0)
		{
			$updateServerQueryString .= "&query_type=updateupdate";
			CUpdateClient::AddMessage2Log(preg_replace("/LICENSE_KEY=[^&]*/i", "LICENSE_KEY=X", $updateServerQueryString));

			/*
			foreach ($arFields as $key => $value)
				$updateServerQueryString .= "&".$key."=".urlencode($value);
			*/

			$stime = CUpdateClient::getmicrotime();
			$content = CUpdateClient::GetHTTPPage("REG", $updateServerQueryString, $strError_tmp);
			if (strlen($content) <= 0)
			{
				if (StrLen($strError_tmp) <= 0)
					$strError_tmp = "[GNSU02] ".GetMessage("SUPZ_EMPTY_ANSWER").". ";
			}

			CUpdateClient::AddMessage2Log("TIME UpdateUpdate(request) ".Round(CUpdateClient::getmicrotime() - $stime, 3)." sec");
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (!($fp1 = fopen($_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/update_archive.gz", "wb")))
				$strError_tmp .= "[URV02] ".str_replace("#FILE#", $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates", GetMessage("SUPP_RV_ER_TEMP_FILE")).". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (!fwrite($fp1, $content))
				$strError_tmp .= "[URV03] ".str_replace("#FILE#", $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/update_archive.gz", GetMessage("SUPP_RV_WRT_TEMP_FILE")).". ";

			@fclose($fp1);
		}

		if (strlen($strError_tmp) <= 0)
		{
			$updatesDirTmp = "";
			if (!CUpdateClient::UnGzipArchive($updatesDirTmp, $strError_tmp, "Y"))
				$strError_tmp .= "[URV04] ".GetMessage("SUPP_RV_BREAK").". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			$updatesDirFull = $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/".$updatesDirTmp;
			if (!file_exists($updatesDirFull."/update_info.xml") || !is_file($updatesDirFull."/update_info.xml"))
				$strError_tmp .= "[URV05] ".str_replace("#FILE#", $updatesDirFull."/update_info.xml", GetMessage("SUPP_RV_ER_DESCR_FILE")).". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (!is_readable($updatesDirFull."/update_info.xml"))
				$strError_tmp .= "[URV06] ".str_replace("#FILE#", $updatesDirFull."/update_info.xml", GetMessage("SUPP_RV_READ_DESCR_FILE")).". ";
		}

		if (strlen($strError_tmp) <= 0)
			$content = file_get_contents($updatesDirFull."/update_info.xml");

		//echo "!1!".htmlspecialchars($content)."!2!";

		if (strlen($strError_tmp) <= 0)
		{
			$arRes = Array();
			CUpdateClient::ParseServerData($content, $arRes, $strError_tmp);
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (isset($arRes["DATA"]["#"]["ERROR"]) && is_array($arRes["DATA"]["#"]["ERROR"]) && count($arRes["DATA"]["#"]["ERROR"]) > 0)
			{
				for ($i = 0; $i < count($arRes["DATA"]["#"]["ERROR"]); $i++)
				{
					if (strlen($arRes["DATA"]["#"]["ERROR"][$i]["@"]["TYPE"]) > 0)
						$strError_tmp .= "[".$arRes["DATA"]["#"]["ERROR"][$i]["@"]["TYPE"]."] ";

					$strError_tmp .= $arRes["DATA"]["#"]["ERROR"][$i]["#"].". ";
				}
			}
		}

		if (strlen($strError_tmp) <= 0)
		{
			$updateDirTo = $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/main";
			CUpdateClient::CheckDirPath($updateDirTo."/", true);

			if (!file_exists($updateDirTo) || !is_dir($updateDirTo))
				$strError_tmp .= "[UUK04] ".str_replace("#MODULE_DIR#", $updateDirTo, GetMessage("SUPP_UK_NO_MODIR")).". ";

			if (strlen($strError_tmp) <= 0)
				if (!is_writable($updateDirTo))
					$strError_tmp .= "[UUK05] ".str_replace("#MODULE_DIR#", $updateDirTo, GetMessage("SUPP_UK_WR_MODIR")).". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			CUpdateClient::CopyDirFiles($updatesDirFull."/main", $updateDirTo, $strError_tmp);
		}

		if (strlen($strError_tmp) <= 0)
		{
			CUpdateClient::AddMessage2Log("Update updated successfully!", "CURV");
			CUpdateClient::DeleteDirFilesEx($updatesDirFull);
			bx_accelerator_reset();
		}

		if (strlen($strError_tmp) > 0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "UU");
			$strError .= $strError_tmp;
			return False;
		}
		else
			return True;
	}

	function GetPHPSources(&$strError, $lang, $stableVersionsOnly, $arRequestedModules)
	{
		$strError_tmp = "";

		CUpdateClient::AddMessage2Log("exec CUpdateClient::GetPHPSources");

		$updateServerQueryString = CUpdateClient::CollectRequestData($strError_tmp, $lang, $stableVersionsOnly, $arRequestedModules, array(), array());
		if ($updateServerQueryString === False || StrLen($updateServerQueryString) <= 0 || StrLen($strError_tmp) > 0)
		{
			if (StrLen($strError_tmp) <= 0)
				$strError_tmp = "[GNSU01] ".GetMessage("SUPZ_NO_QSTRING").". ";
		}

		if (StrLen($strError_tmp) <= 0)
		{
			CUpdateClient::AddMessage2Log(preg_replace("/LICENSE_KEY=[^&]*/i", "LICENSE_KEY=X", $updateServerQueryString));

			$stime = CUpdateClient::getmicrotime();
			$content = CUpdateClient::GetHTTPPage("SRC", $updateServerQueryString, $strError_tmp);
			if (strlen($content) <= 0)
			{
				if (StrLen($strError_tmp) <= 0)
					$strError_tmp = "[GNSU02] ".GetMessage("SUPZ_EMPTY_ANSWER").". ";
			}

			CUpdateClient::AddMessage2Log("TIME GetPHPSources(request) ".Round(CUpdateClient::getmicrotime() - $stime, 3)." sec");
		}

		if (StrLen($strError_tmp) <= 0)
		{
			if (!($fp1 = fopen($_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/update_archive.gz", "wb")))
				$strError_tmp = "[GNSU03] ".str_replace("#FILE#", $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates", GetMessage("SUPP_RV_ER_TEMP_FILE")).". ";
		}

		if (StrLen($strError_tmp) <= 0)
		{
			fwrite($fp1, $content);
			fclose($fp1);
		}

		if (strlen($strError_tmp) > 0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "GNSU00");
			$strError .= $strError_tmp;
			return False;
		}
		else
			return True;
	}


	function RegisterVersion(&$strError, $lang = false, $stableVersionsOnly = "Y")
	{
		$strError_tmp = "";

		CUpdateClient::AddMessage2Log("exec CUpdateClient::RegisterVersion");

		$updateServerQueryString = CUpdateClient::CollectRequestData($strError_tmp, $lang, $stableVersionsOnly, array(), array(), array());
		if ($updateServerQueryString === False || StrLen($updateServerQueryString) <= 0 || StrLen($strError_tmp) > 0)
		{
			if (StrLen($strError_tmp) <= 0)
				$strError_tmp = "[RV01] ".GetMessage("SUPZ_NO_QSTRING").". ";
		}

		if (StrLen($strError_tmp) <= 0)
		{
			$updateServerQueryString .= "&query_type=register";
			CUpdateClient::AddMessage2Log(preg_replace("/LICENSE_KEY=[^&]*/i", "LICENSE_KEY=X", $updateServerQueryString));

			/*
			foreach ($arFields as $key => $value)
				$updateServerQueryString .= "&".$key."=".urlencode($value);
			*/

			$stime = CUpdateClient::getmicrotime();
			$content = CUpdateClient::GetHTTPPage("REG", $updateServerQueryString, $strError_tmp);
			if (strlen($content) <= 0)
			{
				if (StrLen($strError_tmp) <= 0)
					$strError_tmp = "[GNSU02] ".GetMessage("SUPZ_EMPTY_ANSWER").". ";
			}

			CUpdateClient::AddMessage2Log("TIME RegisterVersion(request) ".Round(CUpdateClient::getmicrotime() - $stime, 3)." sec");
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (!($fp1 = fopen($_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/update_archive.gz", "wb")))
				$strError_tmp .= "[URV02] ".str_replace("#FILE#", $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates", GetMessage("SUPP_RV_ER_TEMP_FILE")).". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (!fwrite($fp1, $content))
				$strError_tmp .= "[URV03] ".str_replace("#FILE#", $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/update_archive.gz", GetMessage("SUPP_RV_WRT_TEMP_FILE")).". ";

			@fclose($fp1);
		}

		if (strlen($strError_tmp) <= 0)
		{
			$updatesDirTmp = "";
			if (!CUpdateClient::UnGzipArchive($updatesDirTmp, $strError_tmp, "Y"))
				$strError_tmp .= "[URV04] ".GetMessage("SUPP_RV_BREAK").". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			$updatesDirFull = $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/".$updatesDirTmp;
			if (!file_exists($updatesDirFull."/update_info.xml") || !is_file($updatesDirFull."/update_info.xml"))
				$strError_tmp .= "[URV05] ".str_replace("#FILE#", $updatesDirFull."/update_info.xml", GetMessage("SUPP_RV_ER_DESCR_FILE")).". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (!is_readable($updatesDirFull."/update_info.xml"))
				$strError_tmp .= "[URV06] ".str_replace("#FILE#", $updatesDirFull."/update_info.xml", GetMessage("SUPP_RV_READ_DESCR_FILE")).". ";
		}

		if (strlen($strError_tmp) <= 0)
			$content = file_get_contents($updatesDirFull."/update_info.xml");

		//echo "!1!".htmlspecialchars($content)."!2!";

		if (strlen($strError_tmp) <= 0)
		{
			$arRes = Array();
			CUpdateClient::ParseServerData($content, $arRes, $strError_tmp);
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (isset($arRes["DATA"]["#"]["ERROR"]) && is_array($arRes["DATA"]["#"]["ERROR"]) && count($arRes["DATA"]["#"]["ERROR"]) > 0)
			{
				for ($i = 0; $i < count($arRes["DATA"]["#"]["ERROR"]); $i++)
				{
					if (strlen($arRes["DATA"]["#"]["ERROR"][$i]["@"]["TYPE"]) > 0)
						$strError_tmp .= "[".$arRes["DATA"]["#"]["ERROR"][$i]["@"]["TYPE"]."] ";

					$strError_tmp .= $arRes["DATA"]["#"]["ERROR"][$i]["#"].". ";
				}
			}
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (!file_exists($updatesDirFull."/include.php") || !is_file($updatesDirFull."/include.php"))
				$strError_tmp .= "[URV07] ".GetMessage("SUPP_RV_NO_FILE").". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			$newfilesize = @filesize($updatesDirFull."/include.php");
			if (IntVal($newfilesize) != IntVal($arRes["DATA"]["#"]["FILE"][0]["@"]["SIZE"]))
				$strError_tmp .= "[URV08] ".GetMessage("SUPP_RV_ER_SIZE").". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (!is_writeable($_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/main/include.php"))
				$strError_tmp .= "[URV09] ".str_replace("#FILE#", $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/main/include.php", GetMessage("SUPP_RV_NO_WRITE")).". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (!copy($updatesDirFull."/include.php", $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/main/include.php"))
				$strError_tmp .= "[URV10] ".GetMessage("SUPP_RV_ERR_COPY").". ";
			@chmod($_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/main/include.php", BX_FILE_PERMISSIONS);
		}

		if (strlen($strError_tmp) <= 0)
		{
			$strongUpdateCheck = COption::GetOptionString("main", "strong_update_check", "Y");

			if ($strongUpdateCheck == "Y")
			{
				$crc32_old = dechex(crc32(file_get_contents($updatesDirFull."/include.php")));
				$crc32_new = dechex(crc32(file_get_contents($_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/main/include.php")));
				if ($crc32_new != $crc32_old)
					$strError_tmp .= "[URV1011] ".str_replace("#FILE#", $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/main/include.php", GetMessage("SUPP_UGA_FILE_CRUSH")).". ";
			}
		}

		if (strlen($strError_tmp) <= 0)
		{
			CUpdateClient::AddMessage2Log("Product registered successfully!", "CURV");
			CUpdateClient::DeleteDirFilesEx($updatesDirFull);
		}

		if (strlen($strError_tmp) > 0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "CURV");
			$strError .= $strError_tmp;
			return False;
		}
		else
			return True;
	}

	/** Àêòèâèðóåò ëèöåíçèîííûé êëþ÷ **/
	function ActivateLicenseKey($arFields, &$strError, $lang = false, $stableVersionsOnly = "Y")
	{
		$strError_tmp = "";

		CUpdateClient::AddMessage2Log("exec CUpdateClient::ActivateLicenseKey");

		$updateServerQueryString = CUpdateClient::CollectRequestData($strError_tmp, $lang, $stableVersionsOnly, array(), array(), array());
		if ($updateServerQueryString === False || StrLen($updateServerQueryString) <= 0 || StrLen($strError_tmp) > 0)
		{
			if (StrLen($strError_tmp) <= 0)
				$strError_tmp = "[GNSU01] ".GetMessage("SUPZ_NO_QSTRING").". ";
		}

		if (StrLen($strError_tmp) <= 0)
		{
			$updateServerQueryString .= "&query_type=activate";
			CUpdateClient::AddMessage2Log(preg_replace("/LICENSE_KEY=[^&]*/i", "LICENSE_KEY=X", $updateServerQueryString));

			foreach ($arFields as $key => $value)
				$updateServerQueryString .= "&".$key."=".urlencode($value);

			$stime = CUpdateClient::getmicrotime();
			$content = CUpdateClient::GetHTTPPage("ACTIV", $updateServerQueryString, $strError_tmp);
			if (strlen($content) <= 0)
			{
				if (StrLen($strError_tmp) <= 0)
					$strError_tmp = "[GNSU02] ".GetMessage("SUPZ_EMPTY_ANSWER").". ";
			}

			CUpdateClient::AddMessage2Log("TIME ActivateLicenseKey(request) ".Round(CUpdateClient::getmicrotime() - $stime, 3)." sec");
		}

		if (strlen($strError_tmp) <= 0)
		{
			$arRes = Array();
			CUpdateClient::ParseServerData($content, $arRes, $strError_tmp);
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (isset($arRes["DATA"]["#"]["ERROR"]) && is_array($arRes["DATA"]["#"]["ERROR"]) && count($arRes["DATA"]["#"]["ERROR"]) > 0)
			{
				for ($i = 0; $i < count($arRes["DATA"]["#"]["ERROR"]); $i++)
				{
					if (strlen($arRes["DATA"]["#"]["ERROR"][$i]["@"]["TYPE"])>0)
						$strError_tmp .= "[".$arRes["DATA"]["#"]["ERROR"][$i]["@"]["TYPE"]."] ";

					$strError_tmp .= $arRes["DATA"]["#"]["ERROR"][$i]["#"].". ";
				}
			}
		}

		if (strlen($strError_tmp) <= 0)
			CUpdateClient::AddMessage2Log("License key activated successfully!", "CUALK");

		if (strlen($strError_tmp) > 0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "CUALK");
			$strError .= $strError_tmp;
			return False;
		}
		else
			return True;
	}

	/* Ïîëó÷èòü îáíîâëåíèÿ ÿçûêîâ ñëåäóþùåãî øàãà */
	function GetNextStepLangUpdates(&$strError, $lang = false, $arRequestedLangs = array())
	{
		$strError_tmp = "";

		CUpdateClient::AddMessage2Log("exec CUpdateClient::GetNextStepLangUpdates");

		$updateServerQueryString = CUpdateClient::CollectRequestData($strError_tmp, $lang, $stableVersionsOnly, array(), $arRequestedLangs, array());
		if ($updateServerQueryString === False || StrLen($updateServerQueryString) <= 0 || StrLen($strError_tmp) > 0)
		{
			if (StrLen($strError_tmp) <= 0)
				$strError_tmp = "[GNSU01] ".GetMessage("SUPZ_NO_QSTRING").". ";
		}

		if (StrLen($strError_tmp) <= 0)
		{
			CUpdateClient::AddMessage2Log(preg_replace("/LICENSE_KEY=[^&]*/i", "LICENSE_KEY=X", $updateServerQueryString));

			$stime = CUpdateClient::getmicrotime();
			$content = CUpdateClient::GetHTTPPage("STEPL", $updateServerQueryString, $strError_tmp);
			if (strlen($content) <= 0)
			{
				if (StrLen($strError_tmp) <= 0)
					$strError_tmp = "[GNSU02] ".GetMessage("SUPZ_EMPTY_ANSWER").". ";
			}

			CUpdateClient::AddMessage2Log("TIME GetNextStepLangUpdates(request) ".Round(CUpdateClient::getmicrotime() - $stime, 3)." sec");
		}

		if (StrLen($strError_tmp) <= 0)
		{
			if (!($fp1 = fopen($_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/update_archive.gz", "wb")))
				$strError_tmp = "[GNSU03] ".str_replace("#FILE#", $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates", GetMessage("SUPP_RV_ER_TEMP_FILE")).". ";
		}

		if (StrLen($strError_tmp) <= 0)
		{
			fwrite($fp1, $content);
			fclose($fp1);
		}

		if (strlen($strError_tmp) > 0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "GNSLU00");
			$strError .= $strError_tmp;
			return False;
		}
		else
			return True;
	}

	/* Ïîëó÷èòü îáíîâëåíèÿ ïîìîùè ñëåäóþùåãî øàãà */
	function GetNextStepHelpUpdates(&$strError, $lang = false, $arRequestedHelps = array())
	{
		$strError_tmp = "";

		CUpdateClient::AddMessage2Log("exec CUpdateClient::GetNextStepHelpUpdates");

		$updateServerQueryString = CUpdateClient::CollectRequestData($strError_tmp, $lang, $stableVersionsOnly, array(), array(), $arRequestedHelps);
		if ($updateServerQueryString === False || StrLen($updateServerQueryString) <= 0 || StrLen($strError_tmp) > 0)
		{
			if (StrLen($strError_tmp) <= 0)
				$strError_tmp = "[GNSU01] ".GetMessage("SUPZ_NO_QSTRING").". ";
		}

		if (StrLen($strError_tmp) <= 0)
		{
			CUpdateClient::AddMessage2Log(preg_replace("/LICENSE_KEY=[^&]*/i", "LICENSE_KEY=X", $updateServerQueryString));

			$stime = CUpdateClient::getmicrotime();
			$content = CUpdateClient::GetHTTPPage("STEPH", $updateServerQueryString, $strError_tmp);
			if (strlen($content) <= 0)
			{
				if (StrLen($strError_tmp) <= 0)
					$strError_tmp = "[GNSU02] ".GetMessage("SUPZ_EMPTY_ANSWER").". ";
			}

			CUpdateClient::AddMessage2Log("TIME GetNextStepHelpUpdates(request) ".Round(CUpdateClient::getmicrotime() - $stime, 3)." sec");
		}

		if (StrLen($strError_tmp) <= 0)
		{
			if (!($fp1 = fopen($_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/update_archive.gz", "wb")))
				$strError_tmp = "[GNSU03] ".str_replace("#FILE#", $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates", GetMessage("SUPP_RV_ER_TEMP_FILE")).". ";
		}

		if (StrLen($strError_tmp) <= 0)
		{
			fwrite($fp1, $content);
			fclose($fp1);
		}

		if (strlen($strError_tmp) > 0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "GNSHU00");
			$strError .= $strError_tmp;
			return False;
		}
		else
			return True;
	}

	function LoadModulesUpdates(&$errorMessage, &$arUpdateDescription, $lang = false, $stableVersionsOnly = "Y", $arRequestedModules = array())
	{
		$arUpdateDescription = array();
		$startTime = CUpdateClient::getmicrotime();
		$strError_tmp = "";

		$filename = $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/update_archive.gz";
		$iTimeOut = COption::GetOptionString("main", "update_load_timeout", "30");
		if ($iTimeOut < 5)
			$iTimeOut = 5;

		CUpdateClient::AddMessage2Log("exec CUpdateClient::LoadModulesUpdates");

		$updateServerQueryString = CUpdateClient::CollectRequestData($strError_tmp, $lang, $stableVersionsOnly, $arRequestedModules, array(), array());
		if ($updateServerQueryString === False || strlen($updateServerQueryString) <= 0 || strlen($strError_tmp) > 0)
		{
			if (StrLen($strError_tmp) <= 0)
				$strError_tmp = "[GNSU01] ".GetMessage("SUPZ_NO_QSTRING").". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (file_exists($filename.".log"))
			{
				$content = file_get_contents($filename.".log");
				CUpdateClient::ParseServerData($content, $arUpdateDescription, $strError_tmp);
			}

			if (count($arUpdateDescription) <= 0 || strlen($strError_tmp) > 0)
			{
				$arUpdateDescription = array();
				if (file_exists($filename.".tmp"))
					@unlink($filename.".tmp");
				if (file_exists($filename.".log"))
					@unlink($filename.".log");
			}
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (count($arUpdateDescription) <= 0)
			{
				if (file_exists($filename.".tmp"))
					@unlink($filename.".tmp");
				if (file_exists($filename.".log"))
					@unlink($filename.".log");

				CUpdateClient::AddMessage2Log(preg_replace("/LICENSE_KEY=[^&]*/i", "LICENSE_KEY=X", $updateServerQueryString));

				$stime = CUpdateClient::getmicrotime();

				$content = CUpdateClient::GetHTTPPage("STEPM", $updateServerQueryString, $strError_tmp);
				if (strlen($content) <= 0)
				{
					if (strlen($strError_tmp) <= 0)
						$strError_tmp = "[GNSU02] ".GetMessage("SUPZ_EMPTY_ANSWER").". ";
				}

				CUpdateClient::AddMessage2Log("TIME LoadModulesUpdates(request) ".Round(CUpdateClient::getmicrotime() - $stime, 3)." sec");

				if (strlen($strError_tmp) <= 0)
					CUpdateClient::ParseServerData($content, $arUpdateDescription, $strError_tmp);

				if (strlen($strError_tmp) <= 0)
				{
					if (isset($arUpdateDescription["DATA"]["#"]["ERROR"]))
					{
						for ($i = 0, $cnt = count($arUpdateDescription["DATA"]["#"]["ERROR"]); $i < $cnt; $i++)
							$strError_tmp .= "[".$arUpdateDescription["DATA"]["#"]["ERROR"][$i]["@"]["TYPE"]."] ".$arUpdateDescription["DATA"]["#"]["ERROR"][$i]["#"];
					}
				}

				if (strlen($strError_tmp) <= 0)
				{
					if (isset($arUpdateDescription["DATA"]["#"]["NOUPDATES"]))
					{
						CUpdateClient::AddMessage2Log("Finish - NOUPDATES", "STEP");
						return "F";
					}
				}

				if (strlen($strError_tmp) <= 0)
				{
					if (!($fp1 = fopen($filename.".log", "wb")))
						$strError_tmp = "[GNSU03] ".str_replace("#FILE#", $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates", GetMessage("SUPP_RV_ER_TEMP_FILE")).". ";

					if (strlen($strError_tmp) <= 0)
					{
						fwrite($fp1, $content);
						fclose($fp1);

						return "S";
					}
				}

				$errorMessage .= $strError_tmp;
				return "E";
			}
		}

		if (strlen($strError_tmp) <= 0)
		{
			$ServerIP = COption::GetOptionString("main", "update_site", DEFAULT_UPDATE_SERVER);
			$ServerPort = 80;

			$proxyAddr = COption::GetOptionString("main", "update_site_proxy_addr", "");
			$proxyPort = COption::GetOptionString("main", "update_site_proxy_port", "");
			$proxyUserName = COption::GetOptionString("main", "update_site_proxy_user", "");
			$proxyPassword = COption::GetOptionString("main", "update_site_proxy_pass", "");

			$bUseProxy = (strlen($proxyAddr) > 0 && strlen($proxyPort) > 0);

			if ($bUseProxy)
			{
				$proxyPort = IntVal($proxyPort);
				if ($proxyPort <= 0)
					$proxyPort = 80;

				$requestIP = $proxyAddr;
				$requestPort = $proxyPort;
			}
			else
			{
				$requestIP = $ServerIP;
				$requestPort = $ServerPort;
			}

			$hUpdateServer = fsockopen($requestIP, $requestPort, $errno, $errstr, 120);

			if (!$hUpdateServer)
			{
				$strError_tmp .= GetMessage("SUPP_GHTTP_ER").": [".$errno."] ".$errstr.". ";
				if (intval($errno) <= 0)
					$strError_tmp .= GetMessage("SUPP_GHTTP_ER_DEF")." ";

				CUpdateClient::AddMessage2Log("Error connecting 2 ".$ServerIP.": [".$errno."] ".$errstr."", "ERRCONN1");
			}
		}

		if (strlen($strError_tmp) <= 0)
		{
			$updateServerRequestString = "";

			if ($bUseProxy)
			{
				$updateServerRequestString .= "POST http://".$ServerIP."/bitrix/updates/us_updater_modules.php HTTP/1.0\r\n";
				if (strlen($proxyUserName) > 0)
					$updateServerRequestString .= "Proxy-Authorization: Basic ".base64_encode($proxyUserName.":".$proxyPassword)."\r\n";
			}
			else
				$updateServerRequestString .= "POST /bitrix/updates/us_updater_modules.php HTTP/1.0\r\n";

			$CRCCode = COption::GetOptionString(US_BASE_MODULE, "crc_code", "");
			$updateServerQueryStringTmp = $updateServerQueryString."&spd=".urlencode($CRCCode);
			$updateServerQueryStringTmp .= "&utf=".urlencode(defined('BX_UTF') ? "Y" : "N");
			$dbv = $GLOBALS["DB"]->GetVersion();
			$updateServerQueryStringTmp .= "&dbv=".urlencode($dbv != false ? $dbv : "");
			$updateServerQueryStringTmp .= "&NS=".COption::GetOptionString("main", "update_site_ns", "");

			$updateServerQueryStringTmp .= "&UFILE=".$arUpdateDescription["DATA"]["#"]["FILE"][0]["@"]["NAME"];
			$currentPosition = (file_exists($filename.".tmp") ? filesize($filename.".tmp") : 0);
			$updateServerQueryStringTmp .= "&USTART=".$currentPosition;

			$updateServerRequestString .= "User-Agent: BitrixSMUpdater\r\n";
			$updateServerRequestString .= "Accept: */*\r\n";
			$updateServerRequestString .= "Host: ".$ServerIP."\r\n";
			$updateServerRequestString .= "Accept-Language: en\r\n";
			$updateServerRequestString .= "Content-type: application/x-www-form-urlencoded\r\n";
			$updateServerRequestString .= "Content-length: ".strlen($updateServerQueryStringTmp)."\r\n\r\n";
			$updateServerRequestString .= $updateServerQueryStringTmp;
			$updateServerRequestString .= "\r\n";

			fputs($hUpdateServer, $updateServerRequestString);

			$responceHeader = "";
			while (($result = fgets($hUpdateServer, 4096)) && $result != "\r\n")
				$responceHeader .= $result;

			$arResponceHeader = preg_split("#\r\n#", $responceHeader);

			$contentLength = 0;
			for ($i = 0, $cnt = count($arResponceHeader); $i < $cnt; $i++)
			{
				if (strpos($arResponceHeader[$i], "Content-Length") !== false)
				{
					$pos = strpos($arResponceHeader[$i], ":");
					$contentLength = intval(trim(substr($arResponceHeader[$i], $pos + 1, strlen($arResponceHeader[$i]) - $pos + 1)));
				}
			}

			if (($contentLength + $currentPosition) != $arUpdateDescription["DATA"]["#"]["FILE"][0]["@"]["SIZE"])
				$strError_tmp .= "[ELVL001] ".GetMessage("ELVL001_SIZE_ERROR").". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			@unlink($filename.".tmp1");

			if (file_exists($filename.".tmp"))
			{
				if (@rename($filename.".tmp", $filename.".tmp1"))
				{
					$hTemporaryUpdateFile = fopen($filename.".tmp", "wb");
					if ($hTemporaryUpdateFile)
					{
						$fh1 = fopen($filename.".tmp1", "rb");
						do
						{
							$data = fread($fh1, 8192);
							if (strlen($data) == 0)
								 break;
							fwrite($hTemporaryUpdateFile, $data);
						}
						while (true);

						fclose($fh1);
						@unlink($filename.".tmp1");
					}
					else
					{
						$strError_tmp .= "[JUHYT002] ".GetMessage("JUHYT002_ERROR_FILE").". ";
					}
				}
				else
				{
					$strError_tmp .= "[JUHYT003] ".GetMessage("JUHYT003_ERROR_FILE").". ";
				}
			}
			else
			{
				$hTemporaryUpdateFile = fopen($filename.".tmp", "wb");
				if (!$hTemporaryUpdateFile)
					$strError_tmp .= "[JUHYT004] ".GetMessage("JUHYT004_ERROR_FILE").". ";
			}
		}

		if (strlen($strError_tmp) <= 0)
		{
			$bFinished = true;
			while (true)
			{
				if ($iTimeOut > 0 && (CUpdateClient::getmicrotime() - $startTime) > $iTimeOut)
				{
					$bFinished = false;
					break;
				}

				$result = fread($hUpdateServer, 40960);
				if ($result == "")
					break;

				fwrite($hTemporaryUpdateFile, $result);
			}

			fclose($hTemporaryUpdateFile);
			fclose($hUpdateServer);
		}

		if (strlen($strError_tmp) <= 0)
		{
			CUpdateClient::AddMessage2Log("Time - ".(CUpdateClient::getmicrotime() - $startTime)." sec", "DOWNLOAD");

			if ($bFinished)
			{
				@unlink($filename);
				if (!@rename($filename.".tmp", $filename))
					$strError_tmp .= "[JUHYT005] ".GetMessage("JUHYT005_ERROR_FILE").". ";
			}
			else
			{
				return "S";
			}
		}

		if (strlen($strError_tmp) <= 0)
		{
			@unlink($filename.".tmp");
			@unlink($filename.".log");
			return "U";
		}

		if (file_exists($filename.".tmp"))
			@unlink($filename.".tmp");
		if (file_exists($filename.".log"))
			@unlink($filename.".log");

		CUpdateClient::AddMessage2Log($strError_tmp, "GNSU001");
		$errorMessage .= $strError_tmp;
		return "E";
	}

	/* Ïîëó÷èòü îáíîâëåíèÿ ñëåäóþùåãî øàãà */
	function GetNextStepUpdates(&$strError, $lang = false, $stableVersionsOnly = "Y", $arRequestedModules = array())
	{
		$strError_tmp = "";

		CUpdateClient::AddMessage2Log("exec CUpdateClient::GetNextStepUpdates");

		$updateServerQueryString = CUpdateClient::CollectRequestData($strError_tmp, $lang, $stableVersionsOnly, $arRequestedModules, array(), array());
		if ($updateServerQueryString === False || StrLen($updateServerQueryString) <= 0 || StrLen($strError_tmp) > 0)
		{
			if (StrLen($strError_tmp) <= 0)
				$strError_tmp = "[GNSU01] ".GetMessage("SUPZ_NO_QSTRING").". ";
		}

		if (StrLen($strError_tmp) <= 0)
		{
			CUpdateClient::AddMessage2Log(preg_replace("/LICENSE_KEY=[^&]*/i", "LICENSE_KEY=X", $updateServerQueryString));

			$stime = CUpdateClient::getmicrotime();
			$content = CUpdateClient::GetHTTPPage("STEPM", $updateServerQueryString, $strError_tmp);
			if (strlen($content) <= 0)
			{
				if (StrLen($strError_tmp) <= 0)
					$strError_tmp = "[GNSU02] ".GetMessage("SUPZ_EMPTY_ANSWER").". ";
			}

			CUpdateClient::AddMessage2Log("TIME GetNextStepUpdates(request) ".Round(CUpdateClient::getmicrotime() - $stime, 3)." sec");
		}

		if (StrLen($strError_tmp) <= 0)
		{
			if (!($fp1 = fopen($_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/update_archive.gz", "wb")))
				$strError_tmp = "[GNSU03] ".str_replace("#FILE#", $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates", GetMessage("SUPP_RV_ER_TEMP_FILE")).". ";
		}

		if (StrLen($strError_tmp) <= 0)
		{
			fwrite($fp1, $content);
			fclose($fp1);
		}

		if (strlen($strError_tmp) > 0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "GNSU00");
			$strError .= $strError_tmp;
			return False;
		}
		else
			return True;
	}

	// Ðàñïàêîâûâàåò àðõèâ ôàéëîâ update_archive.gz â ïàïêy $updatesDir
	function UnGzipArchive(&$updatesDir, &$strError, $bDelArch = true)
	{
		$strError_tmp = "";

		CUpdateClient::AddMessage2Log("exec CUpdateClient::UnGzipArchive");
		$stime = CUpdateClient::getmicrotime();

		$archiveFileName = $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/update_archive.gz";

		if (!file_exists($archiveFileName) || !is_file($archiveFileName))
			$strError_tmp .= "[UUGZA01] ".str_replace("#FILE#", $archiveFileName, GetMessage("SUPP_UGA_NO_TMP_FILE")).". ";

		if (strlen($strError_tmp) <= 0)
		{
			if (!is_readable($archiveFileName))
				$strError_tmp .= "[UUGZA02] ".str_replace("#FILE#", $archiveFileName, GetMessage("SUPP_UGA_NO_READ_FILE")).". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			$updatesDir = "update_m".time();
			$updatesDirFull = $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/".$updatesDir;
			CUpdateClient::CheckDirPath($updatesDirFull."/", true);

			if (!file_exists($updatesDirFull) || !is_dir($updatesDirFull))
				$strError_tmp .= "[UUGZA03] ".str_replace("#FILE#", $updatesDirFull, GetMessage("SUPP_UGA_NO_TMP_CAT")).". ";
			elseif (!is_writable($updatesDirFull))
				$strError_tmp .= "[UUGZA04] ".str_replace("#FILE#", $updatesDirFull, GetMessage("SUPP_UGA_WRT_TMP_CAT")).". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			$bCompressionUsed = True;

			$fd = fopen($archiveFileName, "rb");
			$flabel = fread($fd, strlen("BITRIX"));
			fclose($fd);

			if ($flabel == "BITRIX")
				$bCompressionUsed = False;
		}

		if (strlen($strError_tmp) <= 0)
		{
			if ($bCompressionUsed)
				$zp = gzopen($archiveFileName, "rb9f");
			else
				$zp = fopen($archiveFileName, "rb");

			if (!$zp)
				$strError_tmp .= "[UUGZA05] ".str_replace("#FILE#", $archiveFileName, GetMessage("SUPP_UGA_CANT_OPEN")).". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			if ($bCompressionUsed)
				$flabel = gzread($zp, strlen("BITRIX"));
			else
				$flabel = fread($zp, strlen("BITRIX"));

			if ($flabel != "BITRIX")
			{
				$strError_tmp .= "[UUGZA06] ".str_replace("#FILE#", $archiveFileName, GetMessage("SUPP_UGA_BAD_FORMAT")).". ";

				if ($bCompressionUsed)
					gzclose($zp);
				else
					fclose($zp);
			}
		}

		if (strlen($strError_tmp) <= 0)
		{
			$strongUpdateCheck = COption::GetOptionString("main", "strong_update_check", "Y");

			while (true)
			{
				if ($bCompressionUsed)
					$add_info_size = gzread($zp, 5);
				else
					$add_info_size = fread($zp, 5);

				$add_info_size = trim($add_info_size);
				if (intval($add_info_size) > 0 && intval($add_info_size)."!"==$add_info_size."!")
				{
					$add_info_size = IntVal($add_info_size);
				}
				else
				{
					if ($add_info_size != "RTIBE")
						$strError_tmp .= "[UUGZA071] ".str_replace("#FILE#", $archiveFileName, GetMessage("SUPP_UGA_BAD_FORMAT")).". ";

					break;
				}

				if ($bCompressionUsed)
					$add_info = gzread($zp, $add_info_size);
				else
					$add_info = fread($zp, $add_info_size);

				$add_info_arr = explode("|", $add_info);
				if (count($add_info_arr) != 3)
				{
					$strError_tmp .= "[UUGZA072] ".str_replace("#FILE#", $archiveFileName, GetMessage("SUPP_UGA_BAD_FORMAT")).". ";
					break;
				}

				$size = $add_info_arr[0];
				$curpath = $add_info_arr[1];
				$crc32 = $add_info_arr[2];

				$contents = "";
				if (IntVal($size) > 0)
				{
					if ($bCompressionUsed)
						$contents = gzread($zp, $size);
					else
						$contents = fread($zp, $size);
				}

				$crc32_new = dechex(crc32($contents));

				if ($crc32_new !== $crc32)
				{
					$strError_tmp .= "[UUGZA073] ".str_replace("#FILE#", $curpath, GetMessage("SUPP_UGA_FILE_CRUSH")).". ";
					break;
				}
				else
				{
					CUpdateClient::CheckDirPath($updatesDirFull.$curpath, true);

					if (!($fp1 = fopen($updatesDirFull.$curpath, "wb")))
					{
						$strError_tmp .= "[UUGZA074] ".str_replace("#FILE#", $updatesDirFull.$curpath, GetMessage("SUPP_UGA_CANT_OPEN_WR")).". ";
						break;
					}

					if (strlen($contents) > 0 && !fwrite($fp1, $contents))
					{
						$strError_tmp .= "[UUGZA075] ".str_replace("#FILE#", $updatesDirFull.$curpath, GetMessage("SUPP_UGA_CANT_WRITE_F")).". ";
						@fclose($fp1);
						break;
					}
					fclose($fp1);

					if ($strongUpdateCheck == "Y")
					{
						$crc32_new = dechex(crc32(file_get_contents($updatesDirFull.$curpath)));
						if ($crc32_new !== $crc32)
						{
							$strError_tmp .= "[UUGZA0761] ".str_replace("#FILE#", $curpath, GetMessage("SUPP_UGA_FILE_CRUSH")).". ";
							break;
						}
					}
				}
			}

			if ($bCompressionUsed)
				gzclose($zp);
			else
				fclose($zp);
		}

		if (strlen($strError_tmp) <= 0)
		{
			if ($bDelArch)
				@unlink($archiveFileName);
		}

		CUpdateClient::AddMessage2Log("TIME UnGzipArchive ".Round(CUpdateClient::getmicrotime()-$stime, 3)." sec");

		if (strlen($strError_tmp) > 0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "CUUGZA");
			$strError .= $strError_tmp;
			return False;
		}
		else
			return True;
	}

	// Âîçâðàùàåò èíôîðìàöèþ ïî çàãðóæåííûì â ïàïêó $updatesDir îáíîâëåíèÿì ìîäóëåé
	function CheckUpdatability($updatesDir, &$strError)
	{
		$strError_tmp = "";

		$updatesDirFull = $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/".$updatesDir;
		if (!file_exists($updatesDirFull) || !is_dir($updatesDirFull))
			$strError_tmp .= "[UCU01] ".str_replace("#FILE#", $updatesDirFull, GetMessage("SUPP_CU_NO_TMP_CAT")).". ";

		if (strlen($strError_tmp) <= 0)
			if (!is_readable($updatesDirFull))
				$strError_tmp .= "[UCU02] ".str_replace("#FILE#", $updatesDirFull, GetMessage("SUPP_CU_RD_TMP_CAT")).". ";

		if ($handle = @opendir($updatesDirFull))
		{
			while (($file = readdir($handle)) !== false)
			{
				if ($file == "." || $file == "..")
					continue;

				if (is_dir($updatesDirFull."/".$file))
				{
					CUpdateClient::CheckUpdatability($updatesDir."/".$file, $strError_tmp);
				}
				elseif (is_file($updatesDirFull."/".$file))
				{
					$strRealPath = $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/".substr($updatesDir."/".$file, strpos($updatesDir."/".$file, "/"));
					if (file_exists($strRealPath))
					{
						if (!is_writeable($strRealPath))
							$strError_tmp .= "[UCU03] ".str_replace("#FILE#", $strRealPath, GetMessage("SUPP_CU_MAIN_ERR_FILE")).". ";
					}
					else
					{
						$p = CUpdateClient::bxstrrpos($strRealPath, "/");
						$strRealPath = substr($strRealPath, 0, $p);

						if (strlen($strRealPath) > 1)
							$strRealPath = rtrim($strRealPath, "/");

						$p = CUpdateClient::bxstrrpos($strRealPath, "/");
						while ($p > 0)
						{
							if (file_exists($strRealPath) && is_dir($strRealPath))
							{
								if (!is_writable($strRealPath))
									$strError_tmp .= "[UCU04] ".str_replace("#FILE#", $strRealPath, GetMessage("SUPP_CU_MAIN_ERR_CAT")).". ";

								break;
							}
							$strRealPath = substr($strRealPath, 0, $p);
							$p = CUpdateClient::bxstrrpos($strRealPath, "/");
						}
					}
				}
			}
			@closedir($handle);
		}

		if (strlen($strError_tmp) > 0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "CUCU");
			$strError .= $strError_tmp;
			return False;
		}
		else
			return True;
	}

	// Âîçâðàùàåò èíôîðìàöèþ ïî çàãðóæåííûì â ïàïêó $updatesDir îáíîâëåíèÿì ìîäóëåé
	function GetStepUpdateInfo($updatesDir, &$strError)
	{
		$arResult = array();
		$strError_tmp = "";

		CUpdateClient::AddMessage2Log("exec CUpdateClient::GetStepUpdateInfo");

		$updatesDirFull = $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/".$updatesDir;
		if (!file_exists($updatesDirFull) || !is_dir($updatesDirFull))
			$strError_tmp .= "[UGLMU01] ".str_replace("#FILE#", $updatesDirFull, GetMessage("SUPP_CU_NO_TMP_CAT")).". ";

		if (strlen($strError_tmp) <= 0)
			if (!is_readable($updatesDirFull))
				$strError_tmp .= "[UGLMU02] ".str_replace("#FILE#", $updatesDirFull, GetMessage("SUPP_CU_RD_TMP_CAT")).". ";

		if (strlen($strError_tmp) <= 0)
			if (!file_exists($updatesDirFull."/update_info.xml") || !is_file($updatesDirFull."/update_info.xml"))
				$strError_tmp .= "[UGLMU03] ".str_replace("#FILE#", $updatesDirFull."/update_info.xml", GetMessage("SUPP_RV_ER_DESCR_FILE")).". ";

		if (strlen($strError_tmp) <= 0)
			if (!is_readable($updatesDirFull."/update_info.xml"))
				$strError_tmp .= "[UGLMU04] ".str_replace("#FILE#", $updatesDirFull."/update_info.xml", GetMessage("SUPP_RV_READ_DESCR_FILE")).". ";

		if (strlen($strError_tmp) <= 0)
			$content = file_get_contents($updatesDirFull."/update_info.xml");

		//echo "!1!".htmlspecialchars($content)."!2!";

		if (strlen($strError_tmp) <= 0)
		{
			$arResult = Array();
			CUpdateClient::ParseServerData($content, $arResult, $strError_tmp);
		}

		//echo "!3!".htmlspecialchars($content)."!4!";
		//echo "<pre>";print_r($arRes);echo "</pre>";

		if (strlen($strError_tmp) <= 0)
		{
			if (!isset($arResult["DATA"]) || !is_array($arResult["DATA"]))
				$strError_tmp .= "[UGSMU01] ".GetMessage("SUPP_GAUT_SYSERR").". ";
		}

		if (strlen($strError_tmp) > 0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "CUGLMU");
			$strError .= $strError_tmp;
			return False;
		}
		else
			return $arResult;
	}

	function UpdateStepHelps($updatesDir, &$strError)
	{
		$strError_tmp = "";

		CUpdateClient::AddMessage2Log("exec CUpdateClient::UpdateHelp");
		$stime = CUpdateClient::getmicrotime();

		$updatesDirFull = $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/".$updatesDir;
		$helpDirFull = $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/help";

		$arHelp = array();
		if (StrLen($strError_tmp) <= 0)
		{
			$handle = @opendir($updatesDirFull);
			if ($handle)
			{
				while (false !== ($dir = readdir($handle)))
				{
					if ($dir == "." || $dir == "..")
						continue;
					if (is_dir($updatesDirFull."/".$dir))
						$arHelp[] = $dir;
				}
				closedir($handle);
			}
		}

		if (!is_array($arHelp) || count($arHelp) <= 0)
			$strError_tmp .= "[UUH00] ".GetMessage("SUPP_UH_NO_LANG").". ";

		if (!file_exists($updatesDirFull) || !is_dir($updatesDirFull))
			$strError_tmp .= "[UUH01] ".str_replace("#FILE#", $updatesDirFull, GetMessage("SUPP_CU_NO_TMP_CAT")).". ";

		if (strlen($strError_tmp) <= 0)
			if (!is_readable($updatesDirFull))
				$strError_tmp .= "[UUH03] ".str_replace("#FILE#", $updatesDirFull, GetMessage("SUPP_CU_RD_TMP_CAT")).". ";

		if (strlen($strError_tmp) <= 0)
		{
			CUpdateClient::CheckDirPath($helpDirFull."/", true);

			if (!file_exists($helpDirFull) || !is_dir($helpDirFull))
				$strError_tmp .= "[UUH02] ".str_replace("#FILE#", $helpDirFull, GetMessage("SUPP_UH_NO_HELP_CAT")).". ";
			elseif (!is_writable($helpDirFull))
				$strError_tmp .= "[UUH03] ".str_replace("#FILE#", $helpDirFull, GetMessage("SUPP_UH_NO_WRT_HELP")).". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			for ($i = 0; $i < count($arHelp); $i++)
			{
				$strError_tmp1 = "";

				$updateDirFrom = $updatesDirFull."/".$arHelp[$i];

				if (strlen($strError_tmp1) <= 0)
					if (!file_exists($updateDirFrom) || !is_dir($updateDirFrom))
						$strError_tmp1 .= "[UUH04] ".str_replace("#FILE#", $updateDirFrom, GetMessage("SUPP_UL_NO_TMP_LANG")).". ";

				if (strlen($strError_tmp1) <= 0)
					if (!is_readable($updateDirFrom))
						$strError_tmp1 .= "[UUH05] ".str_replace("#FILE#", $updateDirFrom, GetMessage("SUPP_UL_NO_READ_LANG")).". ";

				if (strlen($strError_tmp1) <= 0)
				{
					if (file_exists($helpDirFull."/".$arHelp[$i]."_tmp"))
						CUpdateClient::DeleteDirFilesEx($helpDirFull."/".$arHelp[$i]."_tmp");
					if (file_exists($helpDirFull."/".$arHelp[$i]."_tmp"))
						$strError_tmp1 .= "[UUH06] ".str_replace("#FILE#", $helpDirFull."/".$arHelp[$i]."_tmp", GetMessage("SUPP_UH_CANT_DEL")).". ";
				}

				if (strlen($strError_tmp1) <= 0)
				{
					if (file_exists($helpDirFull."/".$arHelp[$i]))
						if (!rename($helpDirFull."/".$arHelp[$i], $helpDirFull."/".$arHelp[$i]."_tmp"))
							$strError_tmp1 .= "[UUH07] ".str_replace("#FILE#", $helpDirFull."/".$arHelp[$i], GetMessage("SUPP_UH_CANT_RENAME")).". ";
				}

				if (strlen($strError_tmp1) <= 0)
				{
					CUpdateClient::CheckDirPath($helpDirFull."/".$arHelp[$i]."/", true);

					if (!file_exists($helpDirFull."/".$arHelp[$i]) || !is_dir($helpDirFull."/".$arHelp[$i]))
						$strError_tmp1 .= "[UUH08] ".str_replace("#FILE#", $helpDirFull."/".$arHelp[$i], GetMessage("SUPP_UH_CANT_CREATE")).". ";
					elseif (!is_writable($helpDirFull."/".$arHelp[$i]))
						$strError_tmp1 .= "[UUH09] ".str_replace("#FILE#", $helpDirFull."/".$arHelp[$i], GetMessage("SUPP_UH_CANT_WRITE")).". ";
				}

				if (strlen($strError_tmp1) <= 0)
					CUpdateClient::CopyDirFiles($updateDirFrom, $helpDirFull."/".$arHelp[$i], $strError_tmp1);

				if (strlen($strError_tmp1) > 0)
				{
					$strError_tmp .= $strError_tmp1;
				}
				else
				{
					if (file_exists($helpDirFull."/".$arHelp[$i]."_tmp"))
						CUpdateClient::DeleteDirFilesEx($helpDirFull."/".$arHelp[$i]."_tmp");
				}
			}
			CUpdateClient::ClearUpdateFolder($updatesDirFull);
		}

		CUpdateClient::AddMessage2Log("TIME UpdateHelp ".Round(CUpdateClient::getmicrotime()-$stime, 3)." sec");

		if (strlen($strError_tmp)>0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "USH");
			$strError .= $strError_tmp;
			return False;
		}
		else
			return True;
	}

	function UpdateStepLangs($updatesDir, &$strError)
	{
		global $DB;
		$strError_tmp = "";

		$stime = CUpdateClient::getmicrotime();

		$updatesDirFull = $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/".$updatesDir;
		if (!file_exists($updatesDirFull) || !is_dir($updatesDirFull))
			$strError_tmp .= "[UUL01] ".str_replace("#FILE#", $updatesDirFull, GetMessage("SUPP_CU_NO_TMP_CAT")).". ";

		$arLangs = array();
		if (StrLen($strError_tmp) <= 0)
		{
			$handle = @opendir($updatesDirFull);
			if ($handle)
			{
				while (false !== ($dir = readdir($handle)))
				{
					if ($dir == "." || $dir == "..")
						continue;
					if (is_dir($updatesDirFull."/".$dir))
						$arLangs[] = $dir;
				}
				closedir($handle);
			}
		}

		if (!is_array($arLangs) || count($arLangs) <= 0)
			$strError_tmp .= "[UUL02] ".GetMessage("SUPP_UL_NO_LANGS").". ";

		if (strlen($strError_tmp) <= 0)
			if (!is_readable($updatesDirFull))
				$strError_tmp .= "[UUL03] ".str_replace("#FILE#", $updatesDirFull, GetMessage("SUPP_CU_RD_TMP_CAT")).". ";

		$arCopyLangDirs = array(
			"component" => $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/components/bitrix",
			"activities" => $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/activities/bitrix",
			"gadgets" => $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/gadgets/bitrix",
			"wizards" => $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/wizards/bitrix"
		);
		$arSrcObjectDirs = array(
			"component" => "/install/components/bitrix",
			"activities" => "/install/activities/bitrix",
			"gadgets" => "/install/gadgets/bitrix",
			"wizards" => "/install/wizard/bitrix"
		);

		if (strlen($strError_tmp) <= 0)
		{
			foreach ($arCopyLangDirs as $keyObject => $valuePath)
			{
				CUpdateClient::CheckDirPath($valuePath."/", true);

				if (!file_exists($valuePath) || !is_dir($valuePath))
					$strError_tmp .= "[UUL04] ".str_replace("#FILE#", $valuePath, GetMessage("SUPP_UL_CAT")).". ";
				elseif (!is_writable($valuePath))
					$strError_tmp .= "[UUL05] ".str_replace("#FILE#", $valuePath, GetMessage("SUPP_UL_NO_WRT_CAT")).". ";
			}
		}

		if (strlen($strError_tmp) <= 0)
		{
			$updateDirTo = $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules";

			CUpdateClient::CheckDirPath($updateDirTo."/", true);

			if (!file_exists($updateDirTo) || !is_dir($updateDirTo))
				$strError_tmp .= "[UUL04] ".str_replace("#FILE#", $updateDirTo, GetMessage("SUPP_UL_CAT")).". ";
			elseif (!is_writable($updateDirTo))
				$strError_tmp .= "[UUL05] ".str_replace("#FILE#", $updateDirTo, GetMessage("SUPP_UL_NO_WRT_CAT")).". ";
		}

		$arCopyLangObjects = array();
		if (strlen($strError_tmp) <= 0)
		{
			foreach ($arCopyLangDirs as $keyObject => $valuePath)
			{
				$handle1 = @opendir($valuePath);
				if ($handle1)
				{
					while (false !== ($dir1 = readdir($handle1)))
					{
						if (is_dir($valuePath."/".$dir1) && $dir1 != "." && $dir1 != "..")
						{
							if (!is_writable($valuePath."/".$dir1))
								$strError_tmp .= "[UUL051] ".str_replace("#FILE#", $valuePath."/".$dir1, GetMessage("SUPP_UL_NO_WRT_CAT")).". ";

							if (file_exists($valuePath."/".$dir1."/lang") && !is_writable($valuePath."/".$dir1."/lang"))
								$strError_tmp .= "[UUL052] ".str_replace("#FILE#", $valuePath."/".$dir1."/lang", GetMessage("SUPP_UL_NO_WRT_CAT")).". ";

							$arCopyLangObjects[$keyObject][] = $dir1;
						}
					}
					closedir($handle1);
				}
			}
		}

		if (strlen($strError_tmp) <= 0)
		{
			$arLangModules = array();
			$handle = @opendir($updateDirTo);
			if ($handle)
			{
				while (false !== ($dir = readdir($handle)))
				{
					if (is_dir($updateDirTo."/".$dir) && $dir!="." && $dir!="..")
					{
						if (!is_writable($updateDirTo."/".$dir))
							$strError_tmp .= "[UUL051] ".str_replace("#FILE#", $updateDirTo."/".$dir, GetMessage("SUPP_UL_NO_WRT_CAT")).". ";

						if (file_exists($updateDirTo."/".$dir."/lang") && !is_writable($updateDirTo."/".$dir."/lang"))
							$strError_tmp .= "[UUL052] ".str_replace("#FILE#", $updateDirTo."/".$dir."/lang", GetMessage("SUPP_UL_NO_WRT_CAT")).". ";

						$arLangModules[] = $dir;
					}
				}
				closedir($handle);
			}
		}


		if (strlen($strError_tmp) <= 0)
		{
			for ($i = 0; $i < count($arLangs); $i++)
			{
				$strError_tmp1 = "";

				$updateDirFrom = $updatesDirFull."/".$arLangs[$i];

				if (strlen($strError_tmp1) <= 0)
					if (!file_exists($updateDirFrom) || !is_dir($updateDirFrom))
						$strError_tmp1 .= "[UUL06] ".str_replace("#FILE#", $updateDirFrom, GetMessage("SUPP_UL_NO_TMP_LANG")).". ";

				if (strlen($strError_tmp1) <= 0)
					if (!is_readable($updateDirFrom))
						$strError_tmp1 .= "[UUL07] ".str_replace("#FILE#", $updateDirFrom, GetMessage("SUPP_UL_NO_READ_LANG")).". ";

				if (strlen($strError_tmp1) <= 0)
				{
					$handle1 = @opendir($updateDirFrom);
					if ($handle1)
					{
						while (false !== ($dir1 = readdir($handle1)))
						{
							if (!is_dir($updateDirFrom."/".$dir1) || $dir1 == "." || $dir1 == "..")
								continue;

							foreach ($arSrcObjectDirs as $keyObject => $valuePath)
							{
								if (!file_exists($updateDirFrom."/".$dir1.$valuePath))
									continue;

								$handle2 = @opendir($updateDirFrom."/".$dir1.$valuePath);
								if ($handle2)
								{
									while (false !== ($dir2 = readdir($handle2)))
									{
										if (!is_dir($updateDirFrom."/".$dir1.$valuePath."/".$dir2) || $dir2 == "." || $dir2 == "..")
											continue;

										if (!in_array($dir2, $arCopyLangObjects[$keyObject]))
											continue;

										CUpdateClient::CopyDirFiles($updateDirFrom."/".$dir1.$valuePath."/".$dir2, $arCopyLangDirs[$keyObject]."/".$dir2, $strError_tmp1);
									}
									closedir($handle2);
								}
							}

							if (in_array($dir1, $arLangModules))
								CUpdateClient::CopyDirFiles($updateDirFrom."/".$dir1, $updateDirTo."/".$dir1, $strError_tmp1);
						}
						closedir($handle1);
					}
				}

				if (strlen($strError_tmp1) > 0)
					$strError_tmp .= $strError_tmp1;
			}
		}


		if (strlen($strError_tmp) <= 0)
			CUpdateClient::ClearUpdateFolder($updatesDirFull);
		bx_accelerator_reset();

		CUpdateClient::AddMessage2Log("TIME UpdateLangs ".Round(CUpdateClient::getmicrotime()-$stime, 3)." sec");

		if (strlen($strError_tmp) > 0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "USL");
			$strError .= $strError_tmp;
			return False;
		}
		else
			return True;
	}

	function UpdateStepModules($updatesDir, &$strError, $bSaveUpdaters = False)
	{
		global $DB;
		$strError_tmp = "";

		if (!defined("US_SAVE_UPDATERS_DIR") || StrLen(US_SAVE_UPDATERS_DIR) <= 0)
			$bSaveUpdaters = False;

		$stime = CUpdateClient::getmicrotime();

		$arSkipLangs = array();
		if (!file_exists($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/lang/de"))
			$arSkipLangs[] = "de";
		if (!file_exists($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/lang/en"))
			$arSkipLangs[] = "en";
		if (!file_exists($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/lang/ru"))
			$arSkipLangs[] = "ru";

		$updatesDirFull = $_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/".$updatesDir;

		if (!file_exists($updatesDirFull) || !is_dir($updatesDirFull))
			$strError_tmp .= "[UUK01] ".str_replace("#FILE#", $updatesDirFull, GetMessage("SUPP_CU_NO_TMP_CAT")).". ";

		if (strlen($strError_tmp) <= 0)
			if (!is_readable($updatesDirFull))
				$strError_tmp .= "[UUK03] ".str_replace("#FILE#", $updatesDirFull, GetMessage("SUPP_CU_RD_TMP_CAT")).". ";

		$arModules = array();
		if (StrLen($strError_tmp) <= 0)
		{
			$handle = @opendir($updatesDirFull);
			if ($handle)
			{
				while (false !== ($dir = readdir($handle)))
				{
					if ($dir == "." || $dir == "..")
						continue;
					if (is_dir($updatesDirFull."/".$dir))
						$arModules[] = $dir;
				}
				closedir($handle);
			}
		}

		if (!is_array($arModules) || count($arModules) <= 0)
			$strError_tmp .= "[UUK02] ".GetMessage("SUPP_UK_NO_MODS").". ";

		if (strlen($strError_tmp) <= 0)
		{
			for ($i = 0, $cnt = count($arModules); $i < $cnt; $i++)
			{
				$strError_tmp1 = "";

				$updateDirFrom = $updatesDirFull."/".$arModules[$i];
				$updateDirTo = $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/".$arModules[$i];

				CUpdateClient::CheckDirPath($updateDirTo."/", true);

				if (!file_exists($updateDirTo) || !is_dir($updateDirTo))
					$strError_tmp1 .= "[UUK04] ".str_replace("#MODULE_DIR#", $updateDirTo, GetMessage("SUPP_UK_NO_MODIR")).". ";

				if (strlen($strError_tmp1) <= 0)
					if (!is_writable($updateDirTo))
						$strError_tmp1 .= "[UUK05] ".str_replace("#MODULE_DIR#", $updateDirTo, GetMessage("SUPP_UK_WR_MODIR")).". ";

				if (strlen($strError_tmp1) <= 0)
					if (!file_exists($updateDirFrom) || !is_dir($updateDirFrom))
						$strError_tmp1 .= "[UUK06] ".str_replace("#DIR#", $updateDirFrom, GetMessage("SUPP_UK_NO_FDIR")).". ";

				if (strlen($strError_tmp1) <= 0)
					if (!is_readable($updateDirFrom))
						$strError_tmp1 .= "[UUK07] ".str_replace("#DIR#", $updateDirFrom, GetMessage("SUPP_UK_READ_FDIR")).". ";

				if (strlen($strError_tmp1) <= 0)
				{
					$handle = @opendir($updateDirFrom);
					$arUpdaters = array();
					if ($handle)
					{
						while (false !== ($dir = readdir($handle)))
						{
							if (substr($dir, 0, 7) == "updater")
							{
								$bPostUpdater = "N";
								if (is_file($updateDirFrom."/".$dir))
								{
									$num = substr($dir, 7, strlen($dir) - 11);
									if (substr($dir, strlen($dir) - 9) == "_post.php")
									{
										$bPostUpdater = "Y";
										$num = substr($dir, 7, strlen($dir) - 16);
									}
									$arUpdaters[] = array("/".$dir, Trim($num), $bPostUpdater);
								}
								elseif (file_exists($updateDirFrom."/".$dir."/index.php"))
								{
									$num = substr($dir, 7);
									if (substr($dir, strlen($dir) - 5) == "_post")
									{
										$bPostUpdater = "Y";
										$num = substr($dir, 7, strlen($dir) - 12);
									}
									$arUpdaters[] = array("/".$dir."/index.php", Trim($num), $bPostUpdater);
								}

								if ($bSaveUpdaters)
									CUpdateClient::CopyDirFiles($updateDirFrom."/".$dir, $_SERVER["DOCUMENT_ROOT"].US_SAVE_UPDATERS_DIR."/".$arModules[$i]."/".$dir, $strError_tmp1, False);
							}
						}
						closedir($handle);
					}

					for ($i1 = 0; $i1 < count($arUpdaters) - 1; $i1++)
					{
						for ($j1 = $i1 + 1; $j1 < count($arUpdaters); $j1++)
						{
							if (CUpdateClient::CompareVersions($arUpdaters[$i1][1], $arUpdaters[$j1][1]) > 0)
							{
								$tmp1 = $arUpdaters[$i1];
								$arUpdaters[$i1] = $arUpdaters[$j1];
								$arUpdaters[$j1] = $tmp1;
							}
						}
					}
				}

				if (strlen($strError_tmp1) <= 0)
				{
					if (strtolower($DB->type) == "mysql" && defined("MYSQL_TABLE_TYPE") && strlen(MYSQL_TABLE_TYPE) > 0)
					{
						$DB->Query("SET table_type = '".MYSQL_TABLE_TYPE."'", True);
					}
				}

				if (strlen($strError_tmp1) <= 0)
				{
					for ($i1 = 0; $i1 < count($arUpdaters); $i1++)
					{
						if ($arUpdaters[$i1][2] == "N")
						{
							$strError_tmp2 = "";
							CUpdateClient::RunUpdaterScript($updateDirFrom.$arUpdaters[$i1][0], $strError_tmp2, "/bitrix/updates/".$updatesDir."/".$arModules[$i], $arModules[$i]);
							if (strlen($strError_tmp2) > 0)
							{
								$strError_tmp1 .=
										str_replace("#MODULE#", $arModules[$i], str_replace("#VER#", $arUpdaters[$i1][1], GetMessage("SUPP_UK_UPDN_ERR"))).": ".
										$strError_tmp2.". ";
								$strError_tmp1 .= str_replace("#MODULE#", $arModules[$i], GetMessage("SUPP_UK_UPDN_ERR_BREAK"))." ";
								break;
							}
						}
					}
				}

				if (strlen($strError_tmp1) <= 0)
					CUpdateClient::CopyDirFiles($updateDirFrom, $updateDirTo, $strError_tmp1, True, $arSkipLangs);

				if (strlen($strError_tmp1) <= 0)
				{
					for ($i1 = 0; $i1 < count($arUpdaters); $i1++)
					{
						if ($arUpdaters[$i1][2]=="Y")
						{
							$strError_tmp2 = "";
							CUpdateClient::RunUpdaterScript($updateDirFrom.$arUpdaters[$i1][0], $strError_tmp2, "/bitrix/updates/".$updatesDir."/".$arModules[$i], $arModules[$i]);
							if (strlen($strError_tmp2) > 0)
							{
								$strError_tmp1 .=
										str_replace("#MODULE#", $arModules[$i], str_replace("#VER#", $arUpdaters[$i1][1], GetMessage("SUPP_UK_UPDY_ERR"))).": ".
										$strError_tmp2.". ";
								$strError_tmp1 .= str_replace("#MODULE#", $arModules[$i], GetMessage("SUPP_UK_UPDN_ERR_BREAK"))." ";
								break;
							}
						}
					}
				}

				if (strlen($strError_tmp1) > 0)
					$strError_tmp .= $strError_tmp1;
			}
			CUpdateClient::ClearUpdateFolder($updatesDirFull);
		}

		CUpdateClient::AddMessage2Log("TIME UpdateStepModules ".Round(CUpdateClient::getmicrotime()-$stime, 3)." sec");

		if (strlen($strError_tmp) > 0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "USM");
			$strError .= $strError_tmp;
			return False;
		}
		else
		{
			$events = GetModuleEvents("main", "OnModuleUpdate");
			while ($arEvent = $events->Fetch())
				ExecuteModuleEvent($arEvent, $arModules);

			return True;
		}
	}

	function ClearUpdateFolder($updatesDirFull)
	{
		CUpdateClient::DeleteDirFilesEx($updatesDirFull);
		bx_accelerator_reset();
	}

	/** Çàïóñêàåò updater ìîäóëÿ **/
	function RunUpdaterScript($path, &$strError, $updateDirFrom, $moduleID)
	{
		global $DBType, $DB, $APPLICATION, $USER;

		if (!isset($GLOBALS["UPDATE_STRONG_UPDATE_CHECK"])
			|| ($GLOBALS["UPDATE_STRONG_UPDATE_CHECK"] != "Y" && $GLOBALS["UPDATE_STRONG_UPDATE_CHECK"] != "N"))
		{
			$GLOBALS["UPDATE_STRONG_UPDATE_CHECK"] = ((US_CALL_TYPE != "DB") ? COption::GetOptionString("main", "strong_update_check", "Y") : "Y");
		}
		$strongUpdateCheck = $GLOBALS["UPDATE_STRONG_UPDATE_CHECK"];

		$DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"];

		$path = str_replace("\\", "/", $path);
		$updaterPath = dirname($path);
		$updaterPath = substr($updaterPath, strlen($_SERVER["DOCUMENT_ROOT"]));
		$updaterPath = Trim($updaterPath, " \t\n\r\0\x0B/\\");
		if (strlen($updaterPath) > 0)
			$updaterPath = "/".$updaterPath;

		$updaterName = substr($path, strlen($_SERVER["DOCUMENT_ROOT"]));

		CUpdateClient::AddMessage2Log("Run updater '".$updaterName."'", "CSURUS1");

		$updater = new CUpdater();
		$updater->Init($updaterPath, $DBType, $updaterName, $updateDirFrom, $moduleID, US_CALL_TYPE);

		$errorMessage = "";

		include($path);

		if (strlen($errorMessage) > 0)
			$strError .= $errorMessage;
		if (is_array($updater->errorMessage) && count($updater->errorMessage) > 0)
			$strError .= implode("\n", $updater->errorMessage);

		unset($updater);
	}

	/** Ñðàâíåíèå äâóõ âåðñèé â ôîðìàòå XX.XX.XX  **/
	/** Âîçâðàùàåò 1, åñëè $strVers1 > $strVers2  **/
	/** Âîçâðàùàåò -1, åñëè $strVers1 < $strVers2 **/
	/** Âîçâðàùàåò 0, åñëè $strVers1 == $strVers2 **/
	function CompareVersions($strVers1, $strVers2)
	{
		$strVers1 = Trim($strVers1);
		$strVers2 = Trim($strVers2);

		if ($strVers1 == $strVers2)
			return 0;

		$arVers1 = explode(".", $strVers1);
		$arVers2 = explode(".", $strVers2);

		if (IntVal($arVers1[0]) > IntVal($arVers2[0])
			|| IntVal($arVers1[0]) == IntVal($arVers2[0]) && IntVal($arVers1[1]) > IntVal($arVers2[1])
			|| IntVal($arVers1[0]) == IntVal($arVers2[0]) && IntVal($arVers1[1]) == IntVal($arVers2[1]) && IntVal($arVers1[2]) > IntVal($arVers2[2]))
		{
			return 1;
		}

		if (IntVal($arVers1[0]) == IntVal($arVers2[0]) && IntVal($arVers1[1]) == IntVal($arVers2[1]) && IntVal($arVers1[2]) == IntVal($arVers2[2]))
		{
			return 0;
		}

		return -1;
	}

	/* Ïîëó÷èòü ñïèñîê äîñòóïíûõ îáíîâëåíèé */
	function GetUpdatesList(&$strError, $lang = false, $stableVersionsOnly = "Y")
	{
		$strError_tmp = "";
		$arResult = array();

		CUpdateClient::AddMessage2Log("exec CUpdateClient::GetUpdatesList");

		$updateServerQueryString = CUpdateClient::CollectRequestData($strError_tmp, $lang, $stableVersionsOnly, array(), array(), array());
		if ($updateServerQueryString === False || StrLen($updateServerQueryString) <= 0 || StrLen($strError_tmp) > 0)
		{
			$strError .= $strError_tmp;
			CUpdateClient::AddMessage2Log("Empty query list", "GUL01");
			return False;
		}

		CUpdateClient::AddMessage2Log(preg_replace("/LICENSE_KEY=[^&]*/i", "LICENSE_KEY=X", $updateServerQueryString));

		$stime = CUpdateClient::getmicrotime();
		$content = CUpdateClient::GetHTTPPage("LIST", $updateServerQueryString, $strError_tmp);

		CUpdateClient::AddMessage2Log("TIME GetUpdatesList(request) ".Round(CUpdateClient::getmicrotime() - $stime, 3)." sec");

		$arResult = Array();
		if (strlen($strError_tmp) <= 0)
			CUpdateClient::ParseServerData($content, $arResult, $strError_tmp);

		//echo "<pre>";print_r($arResult);echo "</pre>";

		if (strlen($strError_tmp) <= 0)
		{
			if (!isset($arResult["DATA"]) || !is_array($arResult["DATA"]))
				$strError_tmp .= "[UGAUT01] ".GetMessage("SUPP_GAUT_SYSERR").". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			$arResult = $arResult["DATA"]["#"];
			if (!is_array($arResult["CLIENT"]) && (!isset($arResult["ERROR"]) || !is_array($arResult["ERROR"])))
				$strError_tmp .= "[UGAUT01] ".GetMessage("SUPP_GAUT_SYSERR").". ";
		}

		if (strlen($strError_tmp) > 0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "GUL02");
			$strError .= $strError_tmp;
			return False;
		}
		else
			return $arResult;
	}


	/** Çàïðàøèâàåò ìåòîäîì POST ñòðàíèöó $page ñî ñïèñêîì ïàðàìåòðîâ **/
	/** $strVars è âîçâðàùàåò òåëî îòâåòà. Â ïàðàìåòðå $strError      **/
	/** âîçâðàùàåòñÿ òåêñò îøèáêè, åñëè òàêîâàÿ áûëà.                 **/
	function GetHTTPPage($page, $strVars, &$strError)
	{
		global $SERVER_NAME, $DB;

		CUpdateClient::AddMessage2Log("exec CUpdateClient::GetHTTPPage");

		$ServerIP = COption::GetOptionString("main", "update_site", DEFAULT_UPDATE_SERVER);
		$ServerPort = 80;

		$proxyAddr = COption::GetOptionString("main", "update_site_proxy_addr", "");
		$proxyPort = COption::GetOptionString("main", "update_site_proxy_port", "");
		$proxyUserName = COption::GetOptionString("main", "update_site_proxy_user", "");
		$proxyPassword = COption::GetOptionString("main", "update_site_proxy_pass", "");

		$bUseProxy = (strlen($proxyAddr) > 0 && strlen($proxyPort) > 0);

		if ($page == "LIST")
			$page = "us_updater_list.php";
		elseif ($page == "STEPM")
			$page = "us_updater_modules.php";
		elseif ($page == "STEPL")
			$page = "us_updater_langs.php";
		elseif ($page == "STEPH")
			$page = "us_updater_helps.php";
		elseif ($page == "ACTIV")
			$page = "us_updater_actions.php";
		elseif ($page == "REG")
			$page = "us_updater_register.php";
		elseif ($page == "SRC")
			$page = "us_updater_sources.php";

		if ($bUseProxy)
		{
			$proxyPort = IntVal($proxyPort);
			if ($proxyPort <= 0)
				$proxyPort = 80;

			$requestIP = $proxyAddr;
			$requestPort = $proxyPort;
		}
		else
		{
			$requestIP = $ServerIP;
			$requestPort = $ServerPort;
		}

		$hUpdateServer = fsockopen($requestIP, $requestPort, $errno, $errstr, 120);

		if ($hUpdateServer)
		{
			$strRequest = "";

			if ($bUseProxy)
			{
				$strRequest .= "POST http://".$ServerIP."/bitrix/updates/".$page." HTTP/1.0\r\n";
				if (strlen($proxyUserName) > 0)
					$strRequest .= "Proxy-Authorization: Basic ".base64_encode($proxyUserName.":".$proxyPassword)."\r\n";
			}
			else
				$strRequest .= "POST /bitrix/updates/".$page." HTTP/1.0\r\n";

			$CRCCode = COption::GetOptionString(US_BASE_MODULE, "crc_code", "");
			$strVars .= "&spd=".urlencode($CRCCode);
			if (defined('BX_UTF'))
				$strVars .= "&utf=".urlencode("Y");
			else
				$strVars .= "&utf=".urlencode("N");
			$dbv = $DB->GetVersion();
			$strVars .= "&dbv=".urlencode($dbv != false ? $dbv : "");
			$strVars .= "&NS=".COption::GetOptionString("main", "update_site_ns", "");

			$strRequest .= "User-Agent: BitrixSMUpdater\r\n";
			$strRequest .= "Accept: */*\r\n";
			$strRequest .= "Host: ".$ServerIP."\r\n";
			$strRequest .= "Accept-Language: en\r\n";
			$strRequest .= "Content-type: application/x-www-form-urlencoded\r\n";
			$strRequest .= "Content-length: ".strlen($strVars)."\r\n\r\n";
			$strRequest .= "$strVars";
			$strRequest .= "\r\n";

			fputs($hUpdateServer, $strRequest);


			$bChunked = False;
			while (!feof($hUpdateServer))
			{
				$line = fgets($hUpdateServer, 4096);
				if ($line != "\r\n")
				{
					if (preg_match("/Transfer-Encoding: +chunked/i", $line))
						$bChunked = True;
				}
				else
				{
					break;
				}
			}

			/*
			while (($line = fgets($hUpdateServer, 4096)) && $line != "\r\n")
			{
				if (preg_match("/Transfer-Encoding: +chunked/i", $line))
					$bChunked = True;
			}
			*/

			$content = "";
			if ($bChunked)
			{
				$maxReadSize = 4096;

				$length = 0;
				$line = FGets($hUpdateServer, $maxReadSize);
				$line = StrToLower($line);

				$strChunkSize = "";
				$i = 0;
				while ($i < StrLen($line) && in_array($line[$i], array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f")))
				{
					$strChunkSize .= $line[$i];
					$i++;
				}

				$chunkSize = hexdec($strChunkSize);

				while ($chunkSize > 0)
				{
					$processedSize = 0;
					$readSize = (($chunkSize > $maxReadSize) ? $maxReadSize : $chunkSize);

					while ($readSize > 0 && $line = fread($hUpdateServer, $readSize))
					{
						$content .= $line;
						$processedSize += StrLen($line);
						$newSize = $chunkSize - $processedSize;
						$readSize = (($newSize > $maxReadSize) ? $maxReadSize : $newSize);
					}
					$length += $chunkSize;

					$line = FGets($hUpdateServer, $maxReadSize);

					$line = FGets($hUpdateServer, $maxReadSize);
					$line = StrToLower($line);

					$strChunkSize = "";
					$i = 0;
					while ($i < StrLen($line) && in_array($line[$i], array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f")))
					{
						$strChunkSize .= $line[$i];
						$i++;
					}

					$chunkSize = hexdec($strChunkSize);
				}
			}
			else
			{
				while ($line = fread($hUpdateServer, 4096))
					$content .= $line;
			}

			fclose($hUpdateServer);
		}
		else
		{
			$content = "";
			$strError .= GetMessage("SUPP_GHTTP_ER").": [".$errno."] ".$errstr.". ";
			if (IntVal($errno) <= 0)
				$strError .= GetMessage("SUPP_GHTTP_ER_DEF")." ";

			CUpdateClient::AddMessage2Log("Error connecting 2 ".$ServerIP.": [".$errno."] ".$errstr."", "ERRCONN");
		}
		//echo "content:<br>".$content."<br><br>";
		return $content;
	}


	/** Ïðîâåðÿåò íà îøèáêè îòâåò ñåðâåðà $strServerOutput **/
	/** è ïàðñèò â ìàññèâ $arRes                           **/
	function ParseServerData(&$strServerOutput, &$arRes, &$strError)
	{
		$strError_tmp = "";
		$arRes = array();

		CUpdateClient::AddMessage2Log("exec CUpdateClient::ParseServerData");

		//echo "strServerOutput:<br>".htmlspecialchars($strServerOutput)."<br><br>";

		if (strlen($strServerOutput) <= 0)
			$strError_tmp .= "[UPSD01] ".GetMessage("SUPP_AS_EMPTY_RESP").". ";

		if (strlen($strError_tmp) <= 0)
		{
			if (SubStr($strServerOutput, 0, StrLen("<DATA>")) != "<DATA>" && CUpdateClient::IsGzipInstalled())
				$strServerOutput = @gzuncompress($strServerOutput);
			if (SubStr($strServerOutput, 0, StrLen("<DATA>")) != "<DATA>")
			{
				CUpdateClient::AddMessage2Log(substr($strServerOutput, 0, 100), "UPSD02");
				$strError_tmp .= "[UPSD02] ".GetMessage("SUPP_PSD_BAD_RESPONSE").". ";
			}
		}

		//echo "strServerOutput:<br>".htmlspecialchars($strServerOutput)."<br><br>";

		if (strlen($strError_tmp) <= 0)
		{
//			$arRes = CUpdateClient::xmlize($strServerOutput);

			$objXML = new CUpdatesXML();
			$objXML->LoadString($strServerOutput);
			$arRes = $objXML->GetArray();

			if (!is_array($arRes) || !isset($arRes["DATA"]) || !is_array($arRes["DATA"]))
				$strError_tmp .= "[UPSD03] ".GetMessage("SUPP_PSD_BAD_TRANS").". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			if (isset($arRes["DATA"]["#"]["RESPONSE"]))
			{
				$CRCCode = $arRes["DATA"]["#"]["RESPONSE"][0]["@"]["CRC_CODE"];
				if (StrLen($CRCCode) > 0)
					COption::SetOptionString(US_BASE_MODULE, "crc_code", $CRCCode);
			}
			if (isset($arRes["DATA"]["#"]["CLIENT"]))
				CUpdateClient::__ApplyLicenseInfo($arRes["DATA"]["#"]["CLIENT"][0]["@"]);
			/*if (isset($arRes["DATA"]["#"]["CLIENT"]) && isset($arRes["DATA"]["#"]["CLIENT"][0]["@"]["DATE_TO_SOURCE"]))
				COption::SetOptionString(US_BASE_MODULE, "~support_finish_date", $arRes["DATA"]["#"]["CLIENT"][0]["@"]["DATE_TO_SOURCE"]);
			if (isset($arRes["DATA"]["#"]["CLIENT"]) && isset($arRes["DATA"]["#"]["CLIENT"][0]["@"]["MAX_SITES"]))
				COption::SetOptionString("main", "PARAM_MAX_SITES", IntVal($arRes["DATA"]["#"]["CLIENT"][0]["@"]["MAX_SITES"]));
			if (isset($arRes["DATA"]["#"]["CLIENT"]) && isset($arRes["DATA"]["#"]["CLIENT"][0]["@"]["MAX_USERS"]))
				COption::SetOptionString("main", "PARAM_MAX_USERS", IntVal($arRes["DATA"]["#"]["CLIENT"][0]["@"]["MAX_USERS"]));*/
		}

		if (strlen($strError_tmp) > 0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "CUPSD");
			$strError .= $strError_tmp;
			return False;
		}
		else
			return True;
	}

	function CollectRequestData(&$strError, $lang = false, $stableVersionsOnly = "Y", $arRequestedModules = array(), $arRequestedLangs = array(), $arRequestedHelps = array())
	{
		$strResult = "";
		$strError_tmp = "";

		if ($lang === false)
			$lang = LANGUAGE_ID;

		$stableVersionsOnly = (($stableVersionsOnly == "N") ? "N" : "Y");

		CUpdateClient::AddMessage2Log("exec CUpdateClient::CollectRequestData");

		CUpdateClient::CheckDirPath($_SERVER["DOCUMENT_ROOT"]."/bitrix/updates/", true);

		$arClientModules = CUpdateClient::GetCurrentModules($strError_tmp);
		$arClientLanguages = CUpdateClient::GetCurrentLanguages($strError_tmp);
		$arClientHelps = CUpdateClient::GetCurrentHelps($strError_tmp);

		if (strlen($strError_tmp) <= 0)
		{
			$GLOBALS["DB"]->GetVersion();

			$strResult = "LICENSE_KEY=".urlencode(md5(CUpdateClient::GetLicenseKey())).
				"&lang=".urlencode($lang).
				"&SUPD_VER=".urlencode(UPDATE_SYSTEM_VERSION_A).
				"&VERSION=".urlencode(SM_VERSION).
				"&TYPENC=".((defined("DEMO") && DEMO=="Y") ? "D" : ((defined("ENCODE") && ENCODE=="Y") ? "E" : "F" )).
				"&SUPD_STS=".urlencode(CUpdateClient::__GetFooPath()).
				"&SUPD_URS=".urlencode(CUpdateClient::__GetFooPath1(0)).
				"&SUPD_URSA=".urlencode(CUpdateClient::__GetFooPath1(1)).
				"&SUPD_DBS=".urlencode($GLOBALS["DB"]->type).
				"&XE=".urlencode(($GLOBALS["DB"]->XE) ? "Y" : "N").
				"&CLIENT_SITE=".urlencode($_SERVER["SERVER_NAME"]).
				"&CANGZIP=".urlencode((CUpdateClient::IsGzipInstalled()) ? "Y" : "N").
				"&CLIENT_PHPVER=".urlencode(phpversion()).
				"&stable=".urlencode($stableVersionsOnly).
				"&".CUpdateClient::ModulesArray2Query($arClientModules, "bitm_").
				"&".CUpdateClient::ModulesArray2Query($arClientLanguages, "bitl_").
				"&".CUpdateClient::ModulesArray2Query($arClientHelps, "bith_");

			$strResultTmp = "";
			if (count($arRequestedModules) > 0)
			{
				for ($i = 0, $cnt = count($arRequestedModules); $i < $cnt; $i++)
				{
					if (StrLen($strResultTmp) > 0)
						$strResultTmp .= ",";
					$strResultTmp .= $arRequestedModules[$i];
				}
			}
			if (StrLen($strResultTmp) > 0)
				$strResult .= "&requested_modules=".urlencode($strResultTmp);

			$strResultTmp = "";
			if (count($arRequestedLangs) > 0)
			{
				for ($i = 0, $cnt = count($arRequestedLangs); $i < $cnt; $i++)
				{
					if (StrLen($strResultTmp) > 0)
						$strResultTmp .= ",";
					$strResultTmp .= $arRequestedLangs[$i];
				}
			}
			if (StrLen($strResultTmp) > 0)
				$strResult .= "&requested_langs=".urlencode($strResultTmp);

			$strResultTmp = "";
			if (count($arRequestedHelps) > 0)
			{
				for ($i = 0, $cnt = count($arRequestedHelps); $i < $cnt; $i++)
				{
					if (StrLen($strResultTmp) > 0)
						$strResultTmp .= ",";
					$strResultTmp .= $arRequestedHelps[$i];
				}
			}

			if (StrLen($strResultTmp) > 0)
				$strResult .= "&requested_helps=".urlencode($strResultTmp);

			if (defined("FIRST_EDITION") && constant("FIRST_EDITION") == "Y")
			{
				CModule::IncludeModule("iblock");

				$cnt = 0;
				$dbIBlock = CIBlock::GetList(array(), array("CHECK_PERMISSIONS" => "N"));
				while ($dbIBlock->Fetch())
					$cnt++;

				$strResult .= "&SUPD_PIBC=".$cnt;
				$strResult .= "&SUPD_PUC=".CUser::GetCount();

				$cnt = 0;
				$r = CSite::GetList($o1, $b1, array());
				while($r->Fetch())
					$cnt++;

				$strResult .= "&SUPD_PSC=".$cnt;
			}
			if (defined("INTRANET_EDITION") && constant("INTRANET_EDITION") == "Y")
			{
				$arCorportalFeaturesValues = array();
				$savedValues = COption::GetOptionString("main", "~cpf_map_value", "");
				if (strlen($savedValues) > 0)
				{
					$savedValues = base64_decode($savedValues);
					$arCorportalFeaturesValues = unserialize($savedValues);
					if (!is_array($arCorportalFeaturesValues))
						$arCorportalFeaturesValues = array();
				}
				if (count($arCorportalFeaturesValues) <= 0)
					$arCorportalFeaturesValues = array("e" => array(), "f" => array());

				$s = "";
				foreach ($arCorportalFeaturesValues["e"] as $eId => $arE)
				{
					if ($arE[0] == "F" || $arE[0] == "D")
					{
						if (strlen($s) > 0)
							$s .= ",";
						$s .= $eId.":".$arE[0].":".$arE[1];
					}
				}

				$strResult .= "&SUPD_OFC=".urlencode($s);
			}

			return $strResult;
		}

		CUpdateClient::AddMessage2Log($strError_tmp, "NCRD01");
		$strError .= $strError_tmp;
		return False;
	}

	/** Ñîáèðàåò èç ìàññèâà ìîäóëåé ñòðîêó çàïðîñà **/
	function ModulesArray2Query($arClientModules, $pref = "bitm_")
	{
		$strRes = "";
		if (is_array($arClientModules))
		{
			foreach ($arClientModules as $key => $value)
			{
				if (strlen($strRes) > 0)
					$strRes .= "&";

				$strRes .= $pref.$key."=".urlencode($value);
			}
		}

		return $strRes;
	}

	/** Ïðîâåðêà íà óñòàíîâêó GZip êîìïðåññèè **/
	function IsGzipInstalled()
	{
		if (function_exists("gzcompress"))
			return (COption::GetOptionString("main", "update_is_gzip_installed", "Y") == "Y" ? true : false);

		return False;
	}

	/** Ñîáèðàåò êëèåíòñêèå ìîäóëè ñ âåðñèÿìè **/
	function GetCurrentModules(&$strError, $arSelected = false)
	{
		$arClientModules = array();

		$handle = @opendir($_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules");
		if ($handle)
		{
			if ($arSelected === false || is_array($arSelected) && in_array("main", $arSelected))
			{
				if (file_exists($_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/main/classes/general/version.php")
					&& is_file($_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/main/classes/general/version.php"))
				{
					$p = file_get_contents($_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/main/classes/general/version.php");

					preg_match("/define\s*\(\s*\"SM_VERSION\"\s*,\s*\"(\d+\.\d+\.\d+)\"\s*\)\s*/im", $p, $arVers);
					$arClientModules["main"] = $arVers[1];
				}

				if (StrLen($arClientModules["main"]) <= 0)
				{
					CUpdateClient::AddMessage2Log(GetMessage("SUPP_GM_ERR_DMAIN"), "Ux09");
					$strError .= "[Ux09] ".GetMessage("SUPP_GM_ERR_DMAIN").". ";
				}
			}

			while (false !== ($dir = readdir($handle)))
			{
				if (is_dir($_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/".$dir)
					&& $dir != "." && $dir != ".."
					&& $dir != "main"
					&& strpos($dir, ".") === false)
				{
					if ($arSelected === false || is_array($arSelected) && in_array($dir, $arSelected))
					{
						$module_dir = $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/".$dir;
						if (file_exists($module_dir."/install/index.php"))
						{
							$arInfo = CUpdateClient::GetModuleInfo($module_dir);
							if (!isset($arInfo["VERSION"]) || strlen($arInfo["VERSION"]) <= 0)
							{
								CUpdateClient::AddMessage2Log(str_replace("#MODULE#", $dir, GetMessage("SUPP_GM_ERR_DMOD")), "Ux11");
								$strError .= "[Ux11] ".str_replace("#MODULE#", $dir, GetMessage("SUPP_GM_ERR_DMOD")).". ";
							}
							else
							{
								$arClientModules[$dir] = $arInfo["VERSION"];
							}
						}
						else
						{
							continue;

							CUpdateClient::AddMessage2Log(str_replace("#MODULE#", $dir, GetMessage("SUPP_GM_ERR_DMOD")), "Ux12");
							$strError .= "[Ux12] ".str_replace("#MODULE#", $dir, GetMessage("SUPP_GM_ERR_DMOD")).". ";
						}
					}
				}
			}
			closedir($handle);
		}
		else
		{
			CUpdateClient::AddMessage2Log(GetMessage("SUPP_GM_NO_KERNEL"), "Ux15");
			$strError .= "[Ux15] ".GetMessage("SUPP_GM_NO_KERNEL").". ";
		}

		return $arClientModules;
	}

	function __GetFooPath()
	{
		if (!class_exists("CLang"))
		{
			return "RA";
		}
		else
		{
			$cnt = 0;

			$path = CLang::GetList(($by=""),($order=""),array("ACTIVE"=>"Y"));
			while ($ar_res = $path->Fetch())
				$cnt++;

			return $cnt;
		}
	}

	function GetCurrentNumberOfUsers()
	{
		return CUpdateClient::__GetFooPath1(0);
	}

	/** Ñîáèðàåò êëèåíòñêèå ÿçûêè ñ äàòàìè **/
	function GetCurrentLanguages(&$strError, $arSelected = false)
	{
		/*
		$arClientLangs = array();

		$strLangPath = $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/main/lang";

		$db_res = false;
		if (class_exists("CLanguage"))
			$db_res = CLanguage::GetList(($by="sort"), ($order="asc"), array("ACTIVE"=>"Y"));
		elseif (class_exists("CLang"))
			$db_res = CLang::GetList(($by="sort"), ($order="asc"), array("ACTIVE"=>"Y"));

		if ($db_res === false)
		{
			CUpdateClient::AddMessage2Log(GetMessage("SUPP_GL_WHERE_LANGS"), "UGL00");
			$strError .= "[UGL00] ".GetMessage("SUPP_GL_WHERE_LANGS").". ";
		}
		else
		{
			while ($ar_res = $db_res->Fetch())
			{
				if ($arSelected === false || is_array($arSelected) && in_array($ar_res["LID"], $arSelected))
				{
					$strLangDate = "";
					if (file_exists($strLangPath."/".$ar_res["LID"]) && file_exists($strLangPath."/".$ar_res["LID"]."/supd_lang_date.dat"))
					{
						$strLangDate = file_get_contents($strLangPath."/".$ar_res["LID"]."/supd_lang_date.dat");
						$strLangDate = preg_replace("/[\D]+/", "", $strLangDate);

						if (strlen($strLangDate) != 8)
						{
							CUpdateClient::AddMessage2Log(str_replace("#LANG#", $ar_res["LID"], GetMessage("SUPP_GL_ERR_DLANG")), "UGL01");
							$strError .= "[UGL01] ".str_replace("#LANG#", $ar_res["LID"], GetMessage("SUPP_GL_ERR_DLANG")).". ";
							$strLangDate = "";
						}
					}

					$arClientLangs[$ar_res["LID"]] = $strLangDate;
				}
			}

			if ($arSelected === false && count($arClientLangs) <= 0)
			{
				CUpdateClient::AddMessage2Log(GetMessage("SUPP_GL_NO_SITE_LANGS"), "UGL02");
				$strError .= "[UGL02] ".GetMessage("SUPP_GL_NO_SITE_LANGS").". ";
			}
		}

		return $arClientLangs;
		*/
		$arClientLangs = array();

		$strLangPath = $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/main/lang";

		$handle = @opendir($strLangPath);
		if ($handle)
		{
			while (false !== ($dir = readdir($handle)))
			{
				if (is_dir($strLangPath."/".$dir) && $dir!="." && $dir!="..")
				{
					if ($arSelected===false || is_array($arSelected) && in_array($dir, $arSelected))
					{
						$strLangDate = "";
						if (file_exists($strLangPath."/".$dir."/supd_lang_date.dat"))
						{
							$strLangDate = file_get_contents($strLangPath."/".$dir."/supd_lang_date.dat");
							$strLangDate = preg_replace("/[\D]+/", "", $strLangDate);

							if (strlen($strLangDate) != 8)
							{
								CUpdateClient::AddMessage2Log(str_replace("#LANG#", $dir, GetMessage("SUPP_GL_ERR_DLANG")), "UGL01");
								$strError .= "[UGL01] ".str_replace("#LANG#", $dir, GetMessage("SUPP_GL_ERR_DLANG")).". ";
								$strLangDate = "";
							}
						}

						$arClientLangs[$dir] = $strLangDate;
					}
				}
			}
			closedir($handle);
		}

		$db_res = false;
		if (class_exists("CLanguage"))
			$db_res = CLanguage::GetList(($by="sort"), ($order="asc"), array("ACTIVE"=>"Y"));
		elseif (class_exists("CLang"))
			$db_res = CLang::GetList(($by="sort"), ($order="asc"), array("ACTIVE"=>"Y"));

		if ($db_res===false)
		{
			CUpdateClient::AddMessage2Log(GetMessage("SUPP_GL_WHERE_LANGS"), "UGL00");
			$strError .= "[UGL00] ".GetMessage("SUPP_GL_WHERE_LANGS").". ";
		}
		else
		{
			while ($ar_res = $db_res->Fetch())
			{
				if ($arSelected===false || is_array($arSelected) && in_array($ar_res["LID"], $arSelected))
				{
					if (!array_key_exists($ar_res["LID"], $arClientLangs))
					{
						$arClientLangs[$ar_res["LID"]] = "";
					}
				}
			}

			if ($arSelected===false && count($arClientLangs)<=0)
			{
				CUpdateClient::AddMessage2Log(GetMessage("SUPP_GL_NO_SITE_LANGS"), "UGL02");
				$strError .= "[UGL02] ".GetMessage("SUPP_GL_NO_SITE_LANGS").". ";
			}
		}

		return $arClientLangs;
	}

	function __GetFooPath1($v = 0)
	{
		$q = "SELECT COUNT(ID) as C FROM b_user WHERE ACTIVE = 'Y' AND LAST_LOGIN IS NOT NULL";
		if ($v == 0)
			$q = "SELECT COUNT(U.ID) as C FROM b_user U WHERE U.ACTIVE = 'Y' AND U.LAST_LOGIN IS NOT NULL AND EXISTS(SELECT 'x' FROM b_utm_user UF, b_user_field F WHERE F.ENTITY_ID = 'USER' AND F.FIELD_NAME = 'UF_DEPARTMENT' AND UF.FIELD_ID = F.ID AND UF.VALUE_ID = U.ID AND UF.VALUE_INT IS NOT NULL AND UF.VALUE_INT <> 0)";
		$dbRes = $GLOBALS["DB"]->Query($q, true);
		if ($dbRes && ($arRes = $dbRes->Fetch()))
			return $arRes["C"];
		else
			return 0;
	}

	/** Ñîáèðàåò êëèåíòñêèå help'û ñ äàòàìè **/
	function GetCurrentHelps(&$strError, $arSelected = false)
	{
		$arClientHelps = array();

		$strHelpPath = $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/help";

		$handle = @opendir($strHelpPath);
		if ($handle)
		{
			while (false !== ($dir = readdir($handle)))
			{
				if (is_dir($strHelpPath."/".$dir) && $dir!="." && $dir!="..")
				{
					if ($arSelected===false || is_array($arSelected) && in_array($dir, $arSelected))
					{
						$strHelpDate = "";
						if (file_exists($strHelpPath."/".$dir."/supd_lang_date.dat"))
						{
							$strHelpDate = file_get_contents($strHelpPath."/".$dir."/supd_lang_date.dat");
							$strHelpDate = preg_replace("/[\D]+/", "", $strHelpDate);

							if (strlen($strHelpDate)!=8)
							{
								CUpdateClient::AddMessage2Log(str_replace("#HELP#", $dir, GetMessage("SUPP_GH_ERR_DHELP")), "UGH01");
								$strError .= "[UGH01] ".str_replace("#HELP#", $dir, GetMessage("SUPP_GH_ERR_DHELP")).". ";
								$strHelpDate = "";
							}
						}

						$arClientHelps[$dir] = $strHelpDate;
					}
				}
			}
			closedir($handle);
		}

		$db_res = false;
		if (class_exists("CLanguage"))
			$db_res = CLanguage::GetList(($by="sort"), ($order="asc"), array("ACTIVE"=>"Y"));
		elseif (class_exists("CLang"))
			$db_res = CLang::GetList(($by="sort"), ($order="asc"), array("ACTIVE"=>"Y"));

		if ($db_res===false)
		{
			CUpdateClient::AddMessage2Log(GetMessage("SUPP_GL_WHERE_LANGS"), "UGH00");
			$strError .= "[UGH00] ".GetMessage("SUPP_GL_WHERE_LANGS").". ";
		}
		else
		{
			while ($ar_res = $db_res->Fetch())
			{
				if ($arSelected===false || is_array($arSelected) && in_array($ar_res["LID"], $arSelected))
				{
					if (!array_key_exists($ar_res["LID"], $arClientHelps))
					{
						$arClientHelps[$ar_res["LID"]] = "";
					}
				}
			}

			if ($arSelected===false && count($arClientHelps)<=0)
			{
				CUpdateClient::AddMessage2Log(GetMessage("SUPP_GL_NO_SITE_LANGS"), "UGH02");
				$strError .= "[UGH02] ".GetMessage("SUPP_GL_NO_SITE_LANGS").". ";
			}
		}

		return $arClientHelps;
	}

	/** Ïèøåò ñîîáùåíèÿ â ëîã ôàéë ñèñòåìû îáíîâëåíèé. ×èñòèò ëîã, åñëè íóæíî. **/
	function AddMessage2Log($sText, $sErrorCode = "")
	{
		$MAX_LOG_SIZE = 1000000;
		$READ_PSIZE = 8000;
		$LOG_FILE = $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/updater.log";
		$LOG_FILE_TMP = $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/updater_tmp1.log";

		if (strlen($sText)>0 || strlen($sErrorCode)>0)
		{
			$old_abort_status = ignore_user_abort(true);

			if (file_exists($LOG_FILE))
			{
				$log_size = @filesize($LOG_FILE);
				$log_size = IntVal($log_size);

				if ($log_size > $MAX_LOG_SIZE)
				{
					if (!($fp = @fopen($LOG_FILE, "rb")))
					{
						ignore_user_abort($old_abort_status);
						return False;
					}

					if (!($fp1 = @fopen($LOG_FILE_TMP, "wb")))
					{
						ignore_user_abort($old_abort_status);
						return False;
					}

					$iSeekLen = IntVal($log_size-$MAX_LOG_SIZE/2.0);
					fseek($fp, $iSeekLen);

					do
					{
						$data = fread($fp, $READ_PSIZE);
						if (strlen($data) == 0)
							break;

						@fwrite($fp1, $data);
					}
					while(true);

					@fclose($fp);
					@fclose($fp1);

					@copy($LOG_FILE_TMP, $LOG_FILE);
					@unlink($LOG_FILE_TMP);
				}
				clearstatcache();
			}

			if ($fp = @fopen($LOG_FILE, "ab+"))
			{
				if (flock($fp, LOCK_EX))
				{
					@fwrite($fp, date("Y-m-d H:i:s")." - ".$sErrorCode." - ".$sText."\n");
					@fflush($fp);
					@flock($fp, LOCK_UN);
					@fclose($fp);
				}
			}
			ignore_user_abort($old_abort_status);
		}
	}


	/** Ñîçäàíèå ïóòÿ, åñëè åãî íåò, è óñòàíîâêà ïðàâ ïèñàòü **/
	function CheckDirPath($path, $bPermission = true)
	{
		$badDirs = Array();
		$path = str_replace("\\", "/", $path);
		$path = str_replace("//", "/", $path);

		if ($path[strlen($path)-1] != "/") //îòðåæåì èìÿ ôàéëà
		{
			$p = CUpdateClient::bxstrrpos($path, "/");
			$path = substr($path, 0, $p);
		}

		while (strlen($path)>1 && $path[strlen($path)-1]=="/") //îòðåæåì / â êîíöå, åñëè åñòü
			$path = substr($path, 0, strlen($path)-1);

		$p = CUpdateClient::bxstrrpos($path, "/");
		while ($p > 0)
		{
			if (file_exists($path) && is_dir($path))
			{
				if ($bPermission)
				{
					if (!is_writable($path))
						@chmod($path, BX_DIR_PERMISSIONS);
				}
				break;
			}
			$badDirs[] = substr($path, $p+1);
			$path = substr($path, 0, $p);
			$p = CUpdateClient::bxstrrpos($path, "/");
		}

		for ($i = count($badDirs)-1; $i>=0; $i--)
		{
			$path = $path."/".$badDirs[$i];
			@mkdir($path, BX_DIR_PERMISSIONS);
		}
	}


	/** Ðåêóðñèâíîå êîïèðîâàíèå èç $path_from â $path_to **/
	function CopyDirFiles($path_from, $path_to, &$strError, $bSkipUpdater = True, $arSkipLangs = array())
	{
		$strError_tmp = "";

		while (strlen($path_from) > 1 && $path_from[strlen($path_from)-1] == "/")
			$path_from = substr($path_from, 0, strlen($path_from)-1);

		while (strlen($path_to) > 1 && $path_to[strlen($path_to)-1] == "/")
			$path_to = substr($path_to, 0, strlen($path_to)-1);

		if (strpos($path_to."/", $path_from."/") === 0)
			$strError_tmp .= "[UCDF01] ".GetMessage("SUPP_CDF_SELF_COPY").". ";

		if (strlen($strError_tmp) <= 0)
		{
			if (!file_exists($path_from))
				$strError_tmp .= "[UCDF02] ".str_replace("#FILE#", $path_from, GetMessage("SUPP_CDF_NO_PATH")).". ";
		}

		if (strlen($strError_tmp) <= 0)
		{
			$strongUpdateCheck = COption::GetOptionString("main", "strong_update_check", "Y");

			if (is_dir($path_from))
			{
				CUpdateClient::CheckDirPath($path_to."/");

				if (!file_exists($path_to) || !is_dir($path_to))
					$strError_tmp .= "[UCDF03] ".str_replace("#FILE#", $path_to, GetMessage("SUPP_CDF_CANT_CREATE")).". ";
				elseif (!is_writable($path_to))
					$strError_tmp .= "[UCDF04] ".str_replace("#FILE#", $path_to, GetMessage("SUPP_CDF_CANT_WRITE")).". ";

				if (strlen($strError_tmp) <= 0)
				{
					if ($handle = @opendir($path_from))
					{
						while (($file = readdir($handle)) !== false)
						{
							if ($file == "." || $file == "..")
								continue;

							if ($bSkipUpdater && substr($file, 0, strlen("updater")) == "updater")
								continue;

							if (count($arSkipLangs) > 0)
							{
								$b = false;
								foreach ($arSkipLangs as $l)
								{
									if (strpos($path_from."/".$file."/", "/lang/".$l."/") !== false)
									{
										$b = true;
										break;
									}
								}
								if ($b)
									continue;
							}

							if (is_dir($path_from."/".$file))
							{
								CUpdateClient::CopyDirFiles($path_from."/".$file, $path_to."/".$file, $strError_tmp, $bSkipUpdater, $arSkipLangs);
							}
							elseif (is_file($path_from."/".$file))
							{
								if (file_exists($path_to."/".$file) && !is_writable($path_to."/".$file))
								{
									$strError_tmp .= "[UCDF05] ".str_replace("#FILE#", $path_to."/".$file, GetMessage("SUPP_CDF_CANT_FILE")).". ";
								}
								else
								{
									if ($strongUpdateCheck == "Y")
										$crc32_old = dechex(crc32(file_get_contents($path_from."/".$file)));

									@copy($path_from."/".$file, $path_to."/".$file);
									@chmod($path_to."/".$file, BX_FILE_PERMISSIONS);

									if ($strongUpdateCheck == "Y")
									{
										$crc32_new = dechex(crc32(file_get_contents($path_to."/".$file)));
										if ($crc32_new !== $crc32_old)
										{
											$strError_tmp .= "[UCDF061] ".str_replace("#FILE#", $path_to."/".$file, GetMessage("SUPP_UGA_FILE_CRUSH")).". ";
										}
									}
								}
							}
						}
						@closedir($handle);
					}
				}
			}
			else
			{
				$p = CUpdateClient::bxstrrpos($path_to, "/");
				$path_to_dir = substr($path_to, 0, $p);
				CUpdateClient::CheckDirPath($path_to_dir."/");

				if (!file_exists($path_to_dir) || !is_dir($path_to_dir))
					$strError_tmp .= "[UCDF06] ".str_replace("#FILE#", $path_to_dir, GetMessage("SUPP_CDF_CANT_FOLDER")).". ";
				elseif (!is_writable($path_to_dir))
					$strError_tmp .= "[UCDF07] ".str_replace("#FILE#", $path_to_dir, GetMessage("SUPP_CDF_CANT_FOLDER_WR")).". ";

				if (strlen($strError_tmp) <= 0)
				{
					if ($strongUpdateCheck == "Y")
						$crc32_old = dechex(crc32(file_get_contents($path_from)));

					@copy($path_from, $path_to);
					@chmod($path_to, BX_FILE_PERMISSIONS);

					if ($strongUpdateCheck == "Y")
					{
						$crc32_new = dechex(crc32(file_get_contents($path_to)));
						if ($crc32_new !== $crc32_old)
						{
							$strError_tmp .= "[UCDF0611] ".str_replace("#FILE#", $path_to, GetMessage("SUPP_UGA_FILE_CRUSH")).". ";
						}
					}
				}
			}
		}

		if (strlen($strError_tmp) > 0)
		{
			CUpdateClient::AddMessage2Log($strError_tmp, "CUCDF");
			$strError .= $strError_tmp;
			return False;
		}
		else
			return True;
	}


	/** Ðåêóðñèâíîå óäàëåíèå $path **/
	function DeleteDirFilesEx($path)
	{
		if (!file_exists($path))
			return False;

		if (is_file($path))
		{
			@unlink($path);
			return True;
		}

		if ($handle = @opendir($path))
		{
			while (($file = readdir($handle)) !== false)
			{
				if ($file == "." || $file == "..") continue;

				if (is_dir($path."/".$file))
				{
					CUpdateClient::DeleteDirFilesEx($path."/".$file);
				}
				else
				{
					@unlink($path."/".$file);
				}
			}
		}
		@closedir($handle);
		@rmdir($path);
		return True;
	}

	function bxstrrpos($haystack, $needle)
	{
		$index = strpos(strrev($haystack), strrev($needle));
		if($index === false)
			return false;
		$index = strlen($haystack) - strlen($needle) - $index;
		return $index;
	}

	/** Âîçâðàùàåò ýêçåìïëÿð êëàññà-èíñòàëÿòîðà ìîäóëÿ ïî àáñîëþòíîìó ïóòè $path **/
	function GetModuleInfo($path)
	{
		$arModuleVersion = array();
		include($path."/install/version.php");
		if (is_array($arModuleVersion) && array_key_exists("VERSION", $arModuleVersion))
			return $arModuleVersion;

		include_once($path."/install/index.php");

		$arr = explode("/", $path);
		$i = array_search("modules", $arr);
		$class_name = $arr[$i+1];

		$class_name = str_replace(".", "_", $class_name);
		$cls = new $class_name;

		return array(
			"VERSION" => $cls->MODULE_VERSION,
			"VERSION_DATE" => $cls->MODULE_VERSION_DATE,
		);
	}

	/** Ïîëó÷åíèå ëèöåíçèîííîãî êëþ÷à òåêóùåãî êëèåíòà **/
	function GetLicenseKey()
	{
		if (defined("US_LICENSE_KEY"))
			return US_LICENSE_KEY;
		if (defined("LICENSE_KEY"))
			return LICENSE_KEY;
		if (!isset($GLOBALS["CACHE4UPDATESYS_LICENSE_KEY"])	|| $GLOBALS["CACHE4UPDATESYS_LICENSE_KEY"]=="")
		{
			$LICENSE_KEY = "demo";
			if (file_exists($_SERVER["DOCUMENT_ROOT"]."/bitrix/license_key.php"))
				include($_SERVER["DOCUMENT_ROOT"]."/bitrix/license_key.php");
			$GLOBALS["CACHE4UPDATESYS_LICENSE_KEY"] = $LICENSE_KEY;
		}
		return $GLOBALS["CACHE4UPDATESYS_LICENSE_KEY"];
	}

	function getmicrotime()
	{
		list($usec, $sec) = explode(" ", microtime());
		return ((float)$usec + (float)$sec);
	}
}

/*************************************************************************************/
/*************************************************************************************/
/*************************************************************************************/

class CUpdateControllerSupport
{
	function CheckUpdates()
	{
		$errorMessage = "";
		$stableVersionsOnly = COption::GetOptionString("main", "stable_versions_only", "Y");

		if (!($arUpdateList = CUpdateClient::GetUpdatesList($errorMessage, LANG, $stableVersionsOnly)))
			$errorMessage .= GetMessage("SUPZC_NO_CONNECT").". ";

		if ($arUpdateList)
		{
			if (isset($arUpdateList["ERROR"]))
			{
				for ($i = 0, $cnt = count($arUpdateList["ERROR"]); $i < $cnt; $i++)
					$errorMessage .= "[".$arUpdateList["ERROR"][$i]["@"]["TYPE"]."] ".$arUpdateList["ERROR"][$i]["#"];
			}
		}

		if (StrLen($errorMessage) > 0)
			return array("ERROR", $errorMessage);

		if (isset($arUpdateList["UPDATE_SYSTEM"]))
			return array("UPDSYS", "");

		$countModuleUpdates = 0;
		if (isset($arUpdateList["MODULES"]) && is_array($arUpdateList["MODULES"]) && is_array($arUpdateList["MODULES"][0]["#"]["MODULE"]))
			$countModuleUpdates = count($arUpdateList["MODULES"][0]["#"]["MODULE"]);

		$countLangUpdatesInst = 0;
		if (isset($arUpdateList["LANGS"]) && is_array($arUpdateList["LANGS"]) && is_array($arUpdateList["LANGS"][0]["#"]["INST"]) && is_array($arUpdateList["LANGS"][0]["#"]["INST"][0]["#"]["LANG"]))
			$countLangUpdatesInst = count($arUpdateList["LANGS"][0]["#"]["INST"][0]["#"]["LANG"]);

		if ($countLangUpdatesInst > 0 && $countModuleUpdates > 0)
			return array("UPDATE", "ML");
		elseif ($countLangUpdatesInst <= 0 && $countModuleUpdates > 0)
			return array("UPDATE", "M");
		elseif ($countLangUpdatesInst > 0 && $countModuleUpdates <= 0)
			return array("UPDATE", "L");
		else
			return array("FINISH", "");
	}

	function UpdateModules()
	{
		return CUpdateControllerSupport::__UpdateKernel("M");
	}

	function UpdateLangs()
	{
		return CUpdateControllerSupport::__UpdateKernel("L");
	}

	function __UpdateKernel($query_type)
	{
		define("UPD_INTERNAL_CALL", "Y");
		$_REQUEST["query_type"] = $query_type;
		ob_start();
		include($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/admin/update_system_call.php");
		$result = ob_get_contents();
		ob_end_clean();
		return $result;
	}

	function UpdateUpdate()
	{
		define("UPD_INTERNAL_CALL", "Y");
		$_REQUEST["query_type"] = "updateupdate";
		ob_start();
		include($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/admin/update_system_act.php");
		$result = ob_get_contents();
		ob_end_clean();
		return $result;
	}

	function Finish()
	{
		@unlink($_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/versions.php");
	}

	function Update($data = "")
	{
		@set_time_limit(0);
		ini_set("track_errors", "1");
		ignore_user_abort(true);

		$strResult = "";

		$data = Trim($data);
		if (StrLen($data) <= 0 || $data == "CHK")
		{
			$arResult = CUpdateControllerSupport::CheckUpdates();

			if ($arResult[0] == "ERROR")
			{
				$strResult = "ERR|".$arResult[1];
			}
			elseif ($arResult[0] == "FINISH")
			{
				$strResult = "FIN";
			}
			elseif ($arResult[0] == "UPDSYS")
			{
				$strResult = "UPS";
			}
			elseif ($arResult[0] == "UPDATE")
			{
				$strResult = "STP".$arResult[1];
			}
			else
			{
				$strResult = "ERR|"."UNK1";
			}
		}
		else
		{
			if ($data == "UPS")
			{
				$res = CUpdateControllerSupport::UpdateUpdate();
				if ($res == "Y")
					$strResult = "CHK";
				else
					$strResult = "ERR|".$res;
			}
			elseif (SubStr($data, 0, 3) == "STP")
			{
				$data1 = SubStr($data, 3);
				if ($data1 == "ML")
				{
					$res = CUpdateControllerSupport::UpdateModules();
					if ($res == "FIN")
						$strResult = "STP"."L";
					elseif (SubStr($res, 0, 3) == "ERR")
						$strResult = "ERR|".SubStr($res, 3);
					elseif (SubStr($res, 0, 3) == "STP")
						$strResult = "STP"."ML"."|".SubStr($res, 3);
					else
						$strResult = "ERR|"."UNK01";
				}
				elseif ($data1 == "M")
				{
					$res = CUpdateControllerSupport::UpdateModules();
					if ($res == "FIN")
						$strResult = "FIN";
					elseif (SubStr($res, 0, 3) == "ERR")
						$strResult = "ERR|".SubStr($res, 3);
					elseif (SubStr($res, 0, 3) == "STP")
						$strResult = "STP"."M"."|".SubStr($res, 3);
					else
						$strResult = "ERR|"."UNK02";
				}
				elseif ($data1 == "L")
				{
					$res = CUpdateControllerSupport::UpdateLangs();
					if ($res == "FIN")
						$strResult = "FIN";
					elseif (SubStr($res, 0, 3) == "ERR")
						$strResult = "ERR|".SubStr($res, 3);
					elseif (SubStr($res, 0, 3) == "STP")
						$strResult = "STP"."L"."|".SubStr($res, 3);
					else
						$strResult = "ERR|"."UNK03";
				}
				else
				{
					$strResult = "ERR|"."UNK2";
				}
			}
			else
			{
				$strResult = "ERR|"."UNK3";
			}
		}

		if ($strResult == "FIN")
			CUpdateControllerSupport::Finish();

		return $strResult;
	}

	function CollectVersionsFile()
	{
		$fileName = $_SERVER["DOCUMENT_ROOT"].US_SHARED_KERNEL_PATH."/modules/versions.php";

		@unlink($fileName);

		$errorMessage = "";
		$arDBVersions = CUpdateClient::GetCurrentModules($errorMessage, false);
		if (StrLen($errorMessage) <= 0)
		{
			$f = fopen($fileName, "w");
			fwrite($f, "<"."?\n");
			fwrite($f, "\$arVersions = array(\n");
			foreach ($arDBVersions as $moduleID => $version)
				fwrite($f, "\t\"".htmlspecialchars($moduleID)."\" => \"".htmlspecialchars($version)."\",\n");
			fwrite($f, ");\n");
			fwrite($f, "?".">");
			fclose($f);
		}
	}
}
?>