From 1ef9422955883a3d0eb64f44ad6a98f700d99644 Mon Sep 17 00:00:00 2001 From: Anton Laktionov Date: Wed, 24 Jun 2026 17:30:17 +0300 Subject: [PATCH] add restore.php --- src/public/restore.php | 4748 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 4748 insertions(+) create mode 100644 src/public/restore.php diff --git a/src/public/restore.php b/src/public/restore.php new file mode 100644 index 0000000..2a97a3a --- /dev/null +++ b/src/public/restore.php @@ -0,0 +1,4748 @@ + " +

+

+ Документация +

+ ", + "ARC_DOWN" => "Скачать резервную копию с другого сайта", + "ARC_DOWN_BITRIXCLOUD" => "Развернуть резервную копию из облака "1С-Битрикс"", + "BITRIXCLOUD_KEYS" => "Обновление ключей доступа к файлам в облаке", + "LICENSE_KEY" => "Ваш лицензионный ключ:", + "ARC_LOCAL_NAME" => "Имя архива:", + "DB_SELECT" => "Выберите дамп БД:", + "DB_SETTINGS" => "Параметры подключения к базе данных", + "DB_SKIP" => "Пропустить восстановление базы", + "SKIP" => "Пропустить", + "DELETE_FILES" => "Удалить локальную резервную копию и служебные скрипты", + "ARC_DOWN_URL" => "Ссылка на архив:", + "TITLE0" => "Подготовка архива", + "TITLE1" => "Загрузка резервной копии", + "TITLE_PROCESS1" => "Распаковка архива", + "FILE_IS_ENC" => "Архив зашифрован, для продолжения распаковки необходимо ввести пароль (с учетом регистра и пробелов): ", + "WRONG_PASS" => "Введенный пароль неверен", + "ENC_KEY" => "Пароль: ", + "TITLE_PROCESS2" => "Выполняется восстановление базы данных", + "TITLE2" => "Восстановление базы данных", + "TITLE3" => "Загрузка файлов из облака", + "ARC_SKIP" => "Архив уже распакован", + "ARC_SKIP_DESC" => "переход к восстановлению базы данных", + "ARC_NAME" => "Архив загружен в корневую папку сервера", + "ARC_DOWN_PROCESS" => "Загружается:", + "ERR_LOAD_FILE_LIST" => "Ошибочный ответ от сервиса 1С-Битрикс", + "ARC_LOCAL" => "Загрузить с локального диска", + "ARC_LOCAL_WARN" => "Загрузите все части многотомного архива", + "ERR_NO_PARTS" => "Доступны не все части многотомного архива.
Общее число частей: ", + "BUT_TEXT1" => "Далее", + "BUT_TEXT_BACK" => "Назад", + "DUMP_RETRY" => "Попробовать снова", + "USER_NAME" => "Имя пользователя", + "USER_PASS" => "Пароль", + "SEARCHING_UNUSED" => "Поиск посторонних файлов в ядре...", + "BASE_NAME" => "Имя базы данных", + "BASE_HOST" => "Сервер баз данных", + "BASE_RESTORE" => "Восстановить", + "ERR_EXTRACT" => "Ошибка", + "ERR_MSG" => "Ошибка!", + "LICENSE_NOT_FOUND" => "Лицензионный ключ не найден", + "SELECT_ARC" => "Выберите архив", + "CNT_PARTS" => "частей", + "ARC_LIST_EMPTY" => "Нет резервных копий, связанных с этим ключом", + "ERR_UNKNOWN" => "Неизвестный ответ сервера", + "ERR_UPLOAD" => "Не удалось загрузить файл на сервер", + "ERR_DUMP_RESTORE" => "Ошибка восстановления базы данных", + "ERR_CREATE_DB" => "Ошибка создания базы", + "ERR_TAR_TAR" => "Присутствуют файлы с расширением tar.tar. Вместо них должны быть архивы с номерами: tar.1, tar.2 и т.д.", + "FINISH" => "Операция выполнена успешно", + "FINISH_MSG" => "Операция восстановления системы завершена.", + "FINISH_BTN" => "Перейти на сайт", + "BASE_CREATE_DB" => "Создать базу данных если не существует", + "BASE_CLOUDS" => "Файлы из облачных хранилищ:", + "BASE_CLOUDS_Y" => "сохранить локально", + "BASE_CLOUDS_N" => "оставить в облаке", + "FINISH_ERR_DELL" => "Не удалось удалить все временные файлы! Обязательно удалите их вручную.", + "FINISH_ERR_DELL_TITLE" => "Ошибка удаления файлов", + "NO_READ_PERMS" => "Нет прав на чтение корневой папки сайта", + "UTF8_ERROR1" => "Сайт работал в кодировке UTF-8. Конфигурация сервера не соответствует требованиям.
Для продолжения установите настройки PHP: mbstring.func_overload=2 и mbstring.internal_encoding=UTF-8.", + "UTF8_ERROR2" => "Сайт работал в однобайтовой кодировке, а конфигурация сервера рассчитана на кодировку UTF-8.
Для продолжения установите настройки PHP: mbstring.func_overload=0 или mbstring.internal_encoding=ISO-8859-1.", + "FUNC_OVERLOAD_ERROR" => "Версия вашего продукта не поддерживает настройку PHP mbstring.func_overload, отличную от нуля. Для продолжения установите mbstring.func_overload = 0", + "DOC_ROOT_WARN" => "Во избежание проблем с доступом был переписан путь к корню сайта в настройках сайтов. Проверьте настройки сайтов.", + "CDN_WARN" => "Ускорение CDN было отключено т.к. текущий домен не соответствует домену из настроек CDN.", + "HOSTS_WARN" => "Было отключено ограничение по доменам в модуле проактивной защиты т.к. текущий домен попадает под ограничения.", + "WARN_CLEARED" => "При распаковке ядра были обнаружены файлы, которых не было в архиве. Эти файлы перенесены в /bitrix/tmp/restore.removed", + "WARN_SITES" => "Вы распаковали многосайтовый архив, файлы дополнительных сайтов следует скопировать вручную из папки /bitrix/backup/sites", + "WARNING" => "Внимание!", + "DBCONN_WARN" => "Данные подключения взяты из .settings.php. Если их не изменить, будет переписана база данных текущего сайта.", + "HTACCESS_RENAMED_WARN" => "Файл .htaccess из архива был сохранен в корне сайта под именем .htaccess.restore, т.к. он может содержать директивы, недопустимые на данном сервере.", + "HTACCESS_WARN" => "Файл .htaccess из архива был сохранен в корне сайта под именем .htaccess.restore, т.к. он может содержать директивы, недопустимые на данном сервере. В корне сайта создан .htaccess по умолчанию. Измените его вручную через FTP.", + "HTACCESS_ERR_WARN" => "Файл .htaccess из архива был сохранен в корне сайта под именем .htaccess.restore, т.к. он может содержать директивы, недопустимые на данном сервере.
Не удалось создать корне сайта .htaccess по умолчанию. Переименуйте файл .htaccess.restore в .htaccess через FTP.", + "ERR_CANT_DECODE" => "Невозможно восстановить архив т.к. он содержит файлы, имена которых нужно перекодировать, а модуль mbstring недоступен.", + "ERR_CANT_DETECT_ENC" => "Невозможно восстановить архив т.к. он содержит файлы с именами в неизвестной кодировке:", + 'TAR_ERR_FILE_OPEN' => 'Не удалось открыть файл: ', + "ARC_DOWN_OK" => "Все части архива загружены", + "LOADER_SUBTITLE1" => "Загрузка резервной копии", + "LOADER_SUBTITLE1_ERR" => "Ошибка загрузки", + "LOADER_LOAD_QUERY_DISTR" => "Запрашиваю файл #DISTR#", + "LOADER_LOAD_CONN2HOST" => "Подключение к серверу #HOST#", + "LOADER_LOAD_NO_CONN2HOST" => "Не могу соединиться с #HOST#:", + "LOADER_LOAD_SERVER_ANSWER" => "Ошибка загрузки. Сервер ответил: #ANS#", + "LOADER_LOAD_SERVER_ANSWER1" => "Ошибка загрузки. У вас нет прав на доступ к этому файлу. Сервер ответил: #ANS#", + "LOADER_LOAD_LOAD_DISTR" => "Загружаю файл #DISTR#", + "LOADER_LOAD_ERR_RENAME" => "Не могу переименовать файл #FILE1# в файл #FILE2#", + "ERROR_CANT_WRITE" => "Не могу записать файл #FILE#. Место на диске: #SPACE#", + "ERROR_IP_CHANGED" => "IP адрес клиента изменился, продолжение невозможно.", + "ERROR_INIT_TIMESTAMP" => "Время работы скрипта восстановления истекло. Загрузите новую версию.", + "LOADER_LOAD_CANT_REDIRECT" => "Ошибочное перенаправление на адрес #URL#. Проверьте адрес для скачивания.", + "LOADER_LOAD_CANT_OPEN_READ" => "Не могу открыть файл #FILE# на чтение", + "LOADER_LOAD_LOADING" => "Загружаю файл, дождитесь окончания загрузки...", + "LOADER_LOAD_FILE_SAVED" => "Файл сохранен: #FILE# [#SIZE# байт]", + "UPDATE_SUCCESS" => "Обновлено успешно. Открыть.", + "LOADER_NEW_VERSION" => "Доступна новая версия скрипта восстановления, но загрузить её не удалось", + ]; +} +elseif (LANG == 'de') +{ + $MESS = [ + "BACK" => "Zurück", + "BEGIN" => " +

+

+ Dokumentation: Trainingskurs +

+ ", + "ARC_DOWN" => "Von Remote-Server herunterladen", + "ARC_DOWN_BITRIXCLOUD" => "Backup aus der Bitrix Cloud wiederherstellen", + "BITRIXCLOUD_KEYS" => "Refreshing Bitrix Cloud access keys", + "LICENSE_KEY" => "Ihr Lizenzschlüssel:", + "ARC_LOCAL_NAME" => "Archivname:", + "DB_SELECT" => "Datenbank-Dump auswählen:", + "DB_SETTINGS" => "Datenbank-Einstellungen", + "DB_SKIP" => "Überspringen", + "SKIP" => "Überspringen", + "DELETE_FILES" => "Archiv und temporäre Scripts löschen", + "ARC_DOWN_URL" => "Archiv-URL:", + "TITLE0" => "Archiv erstellen", + "TITLE1" => "Archiv herunterladen", + "TITLE_PROCESS1" => "Archiv wird entpackt", + "TITLE_PROCESS2" => "Datenbank wird wiederhergestellt...", + "FILE_IS_ENC" => "Archiv ist verschlüsselt. Passwort eingeben: ", + "WRONG_PASS" => "Passwort ist falsch", + "ENC_KEY" => "Passwort: ", + "TITLE2" => "Datenbank wiederherstellen", + "TITLE3" => "Herunterladen von cloud-Dateien", + "ARC_SKIP" => "Archiv wurde bereits entpackt", + "ARC_SKIP_DESC" => "Wiederherstellung der Datenbank starten", + "ARC_NAME" => "Archiv ist im Dokumenten-Root abgespeichert", + "ARC_DOWN_PROCESS" => "Wird herunterladen:", + "ERR_LOAD_FILE_LIST" => "Falsche Antwort vom Bitrixsoft Server", + "ARC_LOCAL" => "Vom lokalen Speicher hochladen", + "ARC_LOCAL_WARN" => "Vergessen Sie nicht, alle Teile eines mehrbändigen Archivs hochzuladen.", + "ERR_NO_PARTS" => "Einige Teile des mehrbändigen Archivs fehlen.
Teile gesamt: ", + "BUT_TEXT1" => "Fortfahren", + "BUT_TEXT_BACK" => "Zurück", + "DUMP_RETRY" => "Wiederholen", + "USER_NAME" => "Name des datenbank-Nutzers", + "USER_PASS" => "Passwort", + "BASE_NAME" => "Datenbankname", + "SEARCHING_UNUSED" => "Ungenutzte Kernel-Dateien werden gesucht...", + "BASE_HOST" => "Datenbank-Host", + "BASE_RESTORE" => "Wiederherstellen", + "ERR_EXTRACT" => "Fehler", + "ERR_MSG" => "Fehler!", + "LICENSE_NOT_FOUND" => "Lizenz wurde nicht gefunden", + "SELECT_ARC" => "Backup auswählen", + "CNT_PARTS" => "Teile", + "ARC_LIST_EMPTY" => "Backup-Liste ist leer für den aktuellen Lizenzschlüssel", + "ERR_UNKNOWN" => "Unbekannte Server-Antwort", + "ERR_UPLOAD" => "Datei kann nicht hochgeladen werden", + "ERR_DUMP_RESTORE" => "Fehler bei Wiederherstellung der Datenbank:", + "ERR_CREATE_DB" => "Fehler bei Erstellung der Datenbank", + "ERR_TAR_TAR" => "Es gibt Dateien mit Erweiterung tar.tar. Es müssten tar.1, tar.2 und so weiter sein", + "FINISH" => "Erfolgreich abgeschlossen", + "FINISH_MSG" => "Wiederherstellung des Systems wurde abgeschlossen.", + "FINISH_BTN" => "Website öffnen", + "BASE_CREATE_DB" => "Datenbank erstellen", + "BASE_CLOUDS" => "Cloud-Dateien:", + "BASE_CLOUDS_Y" => "lokal speichern", + "BASE_CLOUDS_N" => "in der Cloud lassen", + "FINISH_ERR_DELL" => "Löschen von temporären Dateien ist fehlgeschlagen. Sie sollten diese manuell löschen", + "FINISH_ERR_DELL_TITLE" => "Fehler beim Löschen von dateien", + "NO_READ_PERMS" => "Sie haben nicht genügend Rechte, um Web-Server Root zu lesen", + "UTF8_ERROR1" => "Ihr Server ist für die Codierung UTF-8 nicht konfiguriert. Definieren Sie bitte mbstring.func_overload=2 und mbstring.internal_encoding=UTF-8 um fortzufahren.", + "UTF8_ERROR2" => "Ihr Server ist für die Codierung UTF-8 konfiguriert. Definieren Sie bitte mbstring.func_overload=0 oder mbstring.internal_encoding=ISO-8859-1 um fortzufahren.", + "FUNC_OVERLOAD_ERROR" => "Ihre Produktversion unterstützt keine andere PHP-Einstellung mbstring.func_overload als Null. Um fortzufahren, setzen Sie mbstring.func_overload = 0", + "DOC_ROOT_WARN" => "Um Probleme mit Zugriffsrechten zu vermeiden, wurde das Dokumenten-Root in den Einstellungen der Website aufgeräumt.", + "CDN_WARN" => "CDN Web-Accelerator wurde deaktiviert, weil die aktuelle Domain sich von der unterscheidet, die in den CDN-Einstellungen gespeichrt ist.", + "HOSTS_WARN" => "Domain-Einschränkung wurde deaktiviert (Sicherheitsmodul), weil die aktuelle Domain den Einstellungen nicht entspricht.", + "WARN_CLEARED" => "Einige Dateien wurden in /bitrix gefunden, sie sind in der Backup nicht enthalten. Sie wurden nach /bitrix/tmp/restore.removed verschoben", + "WARN_SITES" => "Sie haben das Multisite-Archiv entpackt, kopieren Sie bitte die Dateien zusätzlicher Websites von /bitrix/backup/sites in einen entsprechenden Ort", + "WARNING" => "Warnung!", + "DBCONN_WARN" => "Die Verbindungseinstellungen werden von .settings.php gelesen. Wenn Sie sie nicht ändern, wird aktuelle Datenbank überschrieben.", + "HTACCESS_RENAMED_WARN" => "Die Datei .htaccess wurde unter .htaccess.restore gespeichert, weil sie Anweisungen enthalten kann, die auf diesem Server nicht erlaubt sind.", + "HTACCESS_WARN" => "Die Datei .htaccess wurde unter .htaccess.restore gespeichert, weil sie die Anweisungen enthalten kann, die auf diesem Server nicht erlaubt sind. Standarddatei .htaccess wurde im Dokumenten-Root erstellt. Sie sollten sie manuell via FTP aktualisieren.", + "HTACCESS_ERR_WARN" => "Die Datei .htaccess wurde unter .htaccess.restore gespeichert, weil sie Anweisungen enthalten kann, die auf diesem Server nicht erlaubt sind. Es gab einen Fehler beim Erstellen der Standarddatei .htaccess. Sie sollten .htaccess.restore in .htaccess via FTP umbenennen.", + "ERR_CANT_DECODE" => "Unmöglich fortzufahren, weil das Modul MBString nicht verfügbar ist.", + "ERR_CANT_DETECT_ENC" => "Unmöglich fortzufahren wegen eines Fehlers in der Erkennung der Codierung des Dateinamen: ", + 'TAR_ERR_FILE_OPEN' => 'Datei kann nicht geöffnet werden: ', + "ARC_DOWN_OK" => "Alle Archivteile wurden heruntergeladen", + "LOADER_SUBTITLE1" => "Wird geladen", + "LOADER_SUBTITLE1_ERR" => "Fehler beim Laden", + "LOADER_LOAD_QUERY_DISTR" => "Paket #DISTR# wird angefragt", + "LOADER_LOAD_CONN2HOST" => "Verbindung mit #HOST#", + "LOADER_LOAD_NO_CONN2HOST" => "Keine Verbindung mit #HOST#:", + "LOADER_LOAD_SERVER_ANSWER" => "Fehler beim Herunterladen. Die Antwort vom Server war: #ANS#", + "LOADER_LOAD_SERVER_ANSWER1" => "Fehler beim Herunterladen. Sie können dieses Paket nicht herunterladen. Die Antwort vom Server war: #ANS#", + "LOADER_LOAD_LOAD_DISTR" => "Das Paket #DISTR# wird heruntergeladen", + "LOADER_LOAD_ERR_RENAME" => "Die Datei #FILE1# kann nicht in #FILE2# umbenannt werden", + "ERROR_CANT_WRITE" => "In der Datei #FILE# kann nicht geschrieben werden. Freier Speicherplatz: #SPACE#", + "ERROR_IP_CHANGED" => "IP address has changed. Permission denied.", + "ERROR_INIT_TIMESTAMP" => "This script is outdated. Please upload the new version.", + "LOADER_LOAD_CANT_REDIRECT" => "Inkorrekte Weiterleitung an #URL#. Überprüfen Sie die Download-URL.", + "LOADER_LOAD_CANT_OPEN_READ" => "Die Datei #FILE# kann nicht zum Lesen geöffnet werden", + "LOADER_LOAD_LOADING" => "Es wird nun heruntergeladen. Bitte warten...", + "LOADER_LOAD_FILE_SAVED" => "Datei gespeichert: #FILE# [#SIZE# bytes]", + "UPDATE_SUCCESS" => "Aktualisierung war erfolgreich. Öffnen.", + "LOADER_NEW_VERSION" => "Beim Aktualisieren des Scripts restore.php ist ein Fehler aufgetreten.", + ]; +} +else +{ + $MESS = [ + "BEGIN" => " +

+

+ Documentation: learning course +

+ ", + "ARC_DOWN" => "Download from remote server", + "ARC_DOWN_BITRIXCLOUD" => "Restore the backup from the Bitrix Cloud", + "BITRIXCLOUD_KEYS" => "Refreshing Bitrix Cloud access keys", + "LICENSE_KEY" => "Your license key:", + "ARC_LOCAL_NAME" => "Archive name:", + "DB_SELECT" => "Select Database Dump:", + "DB_SETTINGS" => "Database settings", + "DB_SKIP" => "Skip", + "SKIP" => "Skip", + "DELETE_FILES" => "Delete archive and temporary scripts", + "ARC_DOWN_URL" => "Archive URL:", + "TITLE0" => "Archive Creation", + "TITLE1" => "Archive download", + "TITLE_PROCESS1" => "Extracting an archive", + "TITLE_PROCESS2" => "Restoring database...", + "FILE_IS_ENC" => "Archive is encrypted. Enter password: ", + "WRONG_PASS" => "Wrong password", + "ENC_KEY" => "Password: ", + "TITLE2" => "Database restore", + "TITLE3" => "Downloading cloud files", + "ARC_SKIP" => "Archive is already extracted", + "ARC_SKIP_DESC" => "Starting database restore", + "ARC_NAME" => "Archive is stored in document root folder", + "ARC_DOWN_PROCESS" => "Downloading:", + "ERR_LOAD_FILE_LIST" => "Wrong Bitrixsoft server response", + "ARC_LOCAL" => "Upload from local disk", + "ARC_LOCAL_WARN" => "Don't forget to upload all the parts of multi-volume archive.", + "ERR_NO_PARTS" => "Some parts of the multivolume archive are missed.
Total number of parts: ", + "BUT_TEXT1" => "Continue", + "BUT_TEXT_BACK" => "Back", + "DUMP_RETRY" => "Retry", + "USER_NAME" => "Database User Name", + "USER_PASS" => "Password", + "BASE_NAME" => "Database Name", + "SEARCHING_UNUSED" => "Searching for unused kernel files...", + "BASE_HOST" => "Database Host", + "BASE_RESTORE" => "Restore", + "ERR_EXTRACT" => "Error", + "ERR_MSG" => "Error!", + "LICENSE_NOT_FOUND" => "License not found", + "SELECT_ARC" => "Select backup", + "CNT_PARTS" => "parts", + "ARC_LIST_EMPTY" => "Backup list is empty for current license key", + "ERR_UNKNOWN" => "Unknown server response", + "ERR_UPLOAD" => "Unable to upload file", + "ERR_DUMP_RESTORE" => "Error restoring the database:", + "ERR_CREATE_DB" => "Error creating the database", + "ERR_TAR_TAR" => "There are files with tar.tar extension presents. Should be tar.1, tar.2 and so on", + "FINISH" => "Successfully completed", + "FINISH_MSG" => "Restoring of the system was completed.", + "FINISH_BTN" => "Open site", + "BASE_CREATE_DB" => "Create database", + "BASE_CLOUDS" => "Cloud files:", + "BASE_CLOUDS_Y" => "store locally", + "BASE_CLOUDS_N" => "leave in the cloud", + "FINISH_ERR_DELL" => "Failed to delete temporary files! You should delete them manually", + "FINISH_ERR_DELL_TITLE" => "Error deleting the files", + "NO_READ_PERMS" => "No permissions for reading Web Server root", + "UTF8_ERROR1" => "Your server is not configured for UTF-8 encoding. Please set mbstring.func_overload=2 and mbstring.internal_encoding=UTF-8 to continue.", + "UTF8_ERROR2" => "Your server is configured for UTF-8 encoding. Please set mbstring.func_overload=0 or mbstring.internal_encoding=ISO-8859-1 to continue.", + "FUNC_OVERLOAD_ERROR" => "Invalid PHP value for mbstring.func_overload. Please set mbstring.func_overload = 0 to continue installation", + "DOC_ROOT_WARN" => "To prevent access problems the document root has been cleared in the site settings.", + "CDN_WARN" => "CDN Web Accelerator has been disabled because current domain differs from the one stored in CDN settings.", + "HOSTS_WARN" => "Domain restriction has beed disabled (security module) because current domain doesn't correspond settings.", + "WARN_CLEARED" => "Some files were found in /bitrix which don't present in the backup. They were moved to /bitrix/tmp/restore.removed", + "WARN_SITES" => "You have extracted the multisite archive, please copy files of additional sites from /bitrix/backup/sites to an appropriate place", + "WARNING" => "Warning!", + "DBCONN_WARN" => "The connection settings are read from .settings.php. If you don't change them, current database will be overwriten.", + "HTACCESS_RENAMED_WARN" => "The file .htaccess was saved as .htaccess.restore, because it may contain directives which are not permitted on this server.", + "HTACCESS_WARN" => "The file .htaccess was saved as .htaccess.restore, because it may contain directives which are not permitted on this server. Default .htaccess file has been created at the document root. Please modify it manually using FTP.", + "HTACCESS_ERR_WARN" => "The file .htaccess was saved as .htaccess.restore, because it may contain directives which are not permitted on this server. There was an error in creating default .htaccess file. Please rename .htaccess.restore to .htaccess using FTP.", + "ERR_CANT_DECODE" => "Unable to continue because the module MBString is not available.", + "ERR_CANT_DETECT_ENC" => "Unable to continue due to error in encoding detection of file name: ", + 'TAR_ERR_FILE_OPEN' => 'Can\'t open file: ', + "ARC_DOWN_OK" => "All archive parts have been downloaded", + "LOADER_SUBTITLE1" => "Loading", + "LOADER_SUBTITLE1_ERR" => "Loading Error", + "LOADER_MENU_UNPACK" => "Unpack file", + "LOADER_LOAD_QUERY_DISTR" => "Requesting package #DISTR#", + "LOADER_LOAD_CONN2HOST" => "Connection to #HOST#...", + "LOADER_LOAD_NO_CONN2HOST" => "Cannot connect to #HOST#:", + "LOADER_LOAD_SERVER_ANSWER" => "Error while downloading. Server reply was: #ANS#", + "LOADER_LOAD_SERVER_ANSWER1" => "Error while downloading. Your can not download this package. Server reply was: #ANS#", + "LOADER_LOAD_LOAD_DISTR" => "Downloading package #DISTR#", + "LOADER_LOAD_ERR_RENAME" => "Cannot rename file #FILE1# to #FILE2#", + "ERROR_CANT_WRITE" => "Cannot write to file #FILE#. Free disk space: #SPACE#", + "ERROR_IP_CHANGED" => "IP address has changed. Permission denied.", + "ERROR_INIT_TIMESTAMP" => "This script is outdated. Please upload the new version.", + "LOADER_LOAD_CANT_REDIRECT" => "Wrong redirect to #URL#. Check download url.", + "LOADER_LOAD_CANT_OPEN_READ" => "Cannot open file #FILE# for reading", + "LOADER_LOAD_LOADING" => "Download in progress. Please wait...", + "LOADER_LOAD_FILE_SAVED" => "File saved: #FILE# [#SIZE# bytes]", + "UPDATE_SUCCESS" => "Successful update. Open.", + "LOADER_NEW_VERSION" => "Error occured while updating restore.php script!", + ]; +} + +$bClearUnusedStep = (bool)($_REQUEST['clear'] ?? false); +$bSelectDumpStep = (($_REQUEST['source'] ?? '') == 'dump'); +$bCloudDownloadStep = ($_REQUEST['cloud_download'] ?? ''); + +$Step = intval($_REQUEST["Step"] ?? 0); + +if (LANG == 'ru') +{ + $bx_host = 'www.1c-bitrix.ru'; + $util_host = 'util.1c-bitrix.ru'; +} +elseif (LANG == 'de') +{ + $bx_host = 'www.bitrix.de'; + $util_host = 'util.bitrixsoft.com'; +} +else +{ + $bx_host = 'www.bitrixsoft.com'; + $util_host = 'util.bitrixsoft.com'; +} + +$strErrMsg = ''; +if (!DEBUG && !$Step && $_SERVER['REQUEST_METHOD'] == 'GET') +{ + $this_script_name = basename(__FILE__); + + $bx_url = '/download/files/scripts/' . $this_script_name; + $form = ''; + + // Check for updates + $res = fsockopen('ssl://' . $bx_host, 443, $errno, $errstr, 3); + + if ($res) + { + $strRequest = "HEAD " . $bx_url . " HTTP/1.1\r\n"; + $strRequest .= "Host: " . $bx_host . "\r\n"; + $strRequest .= "\r\n"; + + fputs($res, $strRequest); + + while ($line = fgets($res, 4096)) + { + if (preg_match("/Content-Length: *([0-9]+)/i", $line, $regs)) + { + if (filesize(__FILE__) != trim($regs[1])) + { + $tmp_name = $this_script_name . '.tmp'; + if (LoadFile('https://' . $bx_host . $bx_url, $tmp_name)) + { + if (rename($_SERVER['DOCUMENT_ROOT'] . '/' . $tmp_name, __FILE__)) + { + bx_accelerator_reset(); + echo '' . getMsg('UPDATE_SUCCESS'); + die(); + } + else + { + $strErrMsg = getMsg("ERROR_CANT_WRITE", ["#FILE#" => $this_script_name, '#SPACE#' => freeSpace()]); + } + } + else + { + $strErrMsg = getMsg('LOADER_NEW_VERSION'); + } + } + break; + } + } + fclose($res); + } +} + +if (!DEBUG) +{ + if (IP_LIMIT == IP_LIMIT_DEFAULT) + { + ($str = file_get_contents(__FILE__)) || die(getMsg("LOADER_LOAD_CANT_OPEN_READ", ["#FILE#" => __FILE__])); + $size = mb_strlen($str); + $str = str_replace(IP_LIMIT, $_SERVER['REMOTE_ADDR'], $str); + $str = str_replace(INIT_TIMESTAMP, time(), $str); + $str = str_pad($str, $size, ' '); + file_put_contents(__FILE__, $str) || die(getMsg("ERROR_CANT_WRITE", ["#FILE#" => __FILE__, '#SPACE#' => freeSpace()])); + bx_accelerator_reset(); + header('Location: ' . $_SERVER['REQUEST_URI']); + die(); + } + elseif ($_SERVER['REMOTE_ADDR'] != IP_LIMIT) + { + $strErrMsg = getMsg('ERROR_IP_CHANGED'); + } + elseif (time() - INIT_TIMESTAMP > 86400 * 7) + { + $strErrMsg = getMsg('ERROR_INIT_TIMESTAMP'); + } + + if ($strErrMsg) + { + echo '
' . getMsg('ERR_MSG') . ' ' . $strErrMsg . '
'; + die(); + } +} + +if (!empty($_REQUEST['LoadFileList'])) +{ + $strLog = ''; + if (LoadFile("https://" . $util_host . "/backup.php?license=" . md5(trim($_REQUEST['license_key'])) . "&lang=" . LANG . "&action=get_info&is_restore=y", $file = $_SERVER['DOCUMENT_ROOT'] . '/file_list.xml') && ($str = file_get_contents($file))) + { + if (preg_match_all('//', $str, $regs)) + { + $arFiles = []; + $arParts = []; + foreach ($regs[0] as $i => $wholeMatch) + { + $name = CTar::getFirstName($regs[1][$i]); + if (!isset($arFiles[$name])) + { + $arFiles[$name] = 0; + $arParts[$name] = 0; + } + $arFiles[$name] += (int)$regs[2][$i]; + $arParts[$name]++; + } + krsort($arFiles); + + echo getMsg('SELECT_ARC') . ': 
'; + echo getMsg('ENC_KEY') . ' '; + } + else + { + if (mb_strpos($str, '') !== false) // valid answer + { + $strErrMsg = getMsg('ARC_LIST_EMPTY'); + } + elseif (preg_match('#error#i', $str)) + { + $code = strip_tags($str); + $strErrMsg = ($code == 'LICENSE_NOT_FOUND' ? getMsg('LICENSE_NOT_FOUND') : $code); + } + else + { + $strErrMsg = getMsg('ERR_UNKNOWN'); + } + echo '
' . getMsg('ERR_MSG') . ' ' . $strErrMsg . '
'; + } + bx_unlink($file); + } + else + { + echo '
' . getMsg('ERR_LOAD_FILE_LIST') . '
' . nl2br($strLog) . '
'; + } + die(); +} + +if ($Step == 2 && !$bSelectDumpStep) +{ + if (isset($_REQUEST['arHeaders']) && is_array($_REQUEST['arHeaders'])) + { + $arHeaders = $_REQUEST['arHeaders']; + } + else + { + $arHeaders = []; + } + + $source = $_REQUEST['source'] ?? ''; + if ($source == 'bitrixcloud' && empty($_REQUEST['arc_down_url'])) + { + $strLog = ''; + $downloadUrl = 'https://' . $util_host . '/backup.php?license=' . md5(trim($_REQUEST['license_key'])) . '&lang=' . LANG . '&action=read_file&file_name=' . urlencode($_REQUEST['bitrixcloud_backup']) . '&check_word=' . CTar::getCheckword($_REQUEST['EncryptKey']).'&is_restore=y'; + $file = $_SERVER['DOCUMENT_ROOT'] . '/file_info.xml'; + if (LoadFile($downloadUrl, $file) && ($str = file_get_contents($file))) + { + bx_unlink($file); + + $host = preg_match('#([^<]+)#i', $str, $regs) ? $regs[1] : false; + $path = preg_match('#([^<]+)#i', $str, $regs) ? $regs[1] : false; + + if (preg_match_all('/
/', $str, $regs)) + { + foreach ($regs[0] as $i => $wholeMatch) + { + $arHeaders[$regs[1][$i]] = $regs[2][$i]; + } + } + + if ($host && $path) + { + $_REQUEST['arc_down_url'] = $host . $path; + } + elseif (mb_strpos($str, 'WRONG_FILE_NAME_OR_CHECKWORD') !== false) + { + $strErrMsg = '
' . getMsg('WRONG_PASS') . '
'; + } + else + { + $strErrMsg = '
' . getMsg('ERR_LOAD_FILE_LIST') . '
'; + } + } + else + { + $strErrMsg = '
' . getMsg('ERR_LOAD_FILE_LIST') . '
' . nl2br($strLog) . '
'; + } + + if (empty($_REQUEST['try_next']) && $strErrMsg) + { + $text = $strErrMsg . + getMsg('ENC_KEY') . '' . + '' . + '' . + '' . + ''; + $bottom = ' + ' . getMsg('BUT_TEXT_BACK') . ' + '; + showMsg(getMsg('TITLE1'), $text, $bottom); + die(); + } + } + + if ($source == 'download' || $source == 'bitrixcloud') + { + $strUrl = $_REQUEST['arc_down_url'] ?? ''; + $res = false; + if ($strUrl) + { + if (!preg_match('#https?://#', $strUrl)) + { + $strUrl = 'http://' . $strUrl; + } + + $arc_name = trim(basename($strUrl)); + + if ($arc_name == CTar::getFirstName($arc_name)) + { + $full = false; + $tar = new CTar(); + $n = CTar::getLastNum($_SERVER['DOCUMENT_ROOT'] . '/' . $arc_name); + $arc_name1 = $arc_name; + while (file_exists($_SERVER['DOCUMENT_ROOT'] . '/' . $arc_name1)) + { + if ($n && $arc_name1 == $arc_name . '.' . $n) + { + $full = true; + break; + } + $arc_name1 = $tar->getNextName($arc_name1); + } + + if (!$full) + { + $strUrl = str_replace($arc_name, $arc_name1, $strUrl); + $_REQUEST['bitrixcloud_backup'] = $arc_name = $arc_name1; + } + } + + $strLog = ''; + $status = ''; + + if (!empty($_REQUEST['continue'])) + { + $res = LoadFile($strUrl, $_SERVER['DOCUMENT_ROOT'] . '/' . $arc_name, $arHeaders); + if (file_exists($file = $_SERVER['DOCUMENT_ROOT'] . '/' . $arc_name)) + { + if ($res == 1) + { + $f = fopen($_SERVER['DOCUMENT_ROOT'] . '/' . $arc_name, 'rb'); + $id = fread($f, 2); + fclose($f); + + if ($id != chr(31) . chr(139)) // not gzip + { + $s = filesize($_SERVER['DOCUMENT_ROOT'] . '/' . $arc_name); + if ($s == 0 || $s % 512 > 0) // not tar + { + bx_unlink($_SERVER['DOCUMENT_ROOT'] . '/' . $arc_name); + $res = false; + } + } + } + } + } + else + { + $res = 2; + SetCurrentProgress(0); + } + } + + if ($res) + { + $text = getMsg('ARC_DOWN_PROCESS') . ' ' . htmlspecialcharsbx($arc_name) . '' . $status . + '' . + '' . + '' . + ''; + + if ($res == 2) + { + $text .= ''; + $text .= ''; + $text .= ''; + } + else + { + $tar = new CTar(); + $text .= ''; + if (!empty($arHeaders)) // bitrixcloud + { + $text .= ''; + $text .= ''; + } + else + { + $text .= ''; + $text .= ''; + } + } + if (!empty($arHeaders)) + { + foreach ($arHeaders as $k => $v) + { + $text .= ''; + } + } + } + elseif (!empty($_REQUEST['try_next'])) + { + $text = getMsg('ARC_DOWN_OK') . + '' . + '' . + ''; + + if (!empty($_REQUEST['bitrixcloud_backup'])) + { + $text .= ''; + } + else + { + $text .= ''; + } + } + else + { + if (!empty($_REQUEST['bitrixcloud_backup']) && isset($replycode) && $replycode == 403 && !empty($arHeaders) && (empty($_REQUEST['timestamp']) || time() - $_REQUEST['timestamp'] > 10)) // Retry for bitrixcloud + { + $status = '
' . getMsg('BITRIXCLOUD_KEYS') . '
'; + $text = getMsg('ARC_DOWN_PROCESS') . ' ' . htmlspecialcharsbx($arc_name) . '' . $status . + '' . + '' . + '' . + '' . + ''; + $text .= ''; + $text .= ''; + } + else + { + $ar = [ + 'TITLE' => getMsg('LOADER_SUBTITLE1_ERR'), + 'TEXT' => nl2br($strLog), + 'BOTTOM' => '' . getMsg('BUT_TEXT_BACK') . '', + ]; + html($ar); + die(); + } + } + $bottom = '' . getMsg('BUT_TEXT_BACK') . ''; + showMsg(getMsg('LOADER_SUBTITLE1'), $text, $bottom); + ?> + getMsg('ERR_EXTRACT'), + 'TEXT' => getMsg('ERR_UPLOAD'), + 'BOTTOM' => '' . getMsg('BUT_TEXT_BACK') . '', + ]; + html($ar); + die(); + } + + foreach ($_FILES['archive']['tmp_name'] as $k => $v) + { + if (!$v) + { + continue; + } + $arc_name = $_FILES['archive']['name'][$k]; + if (!@move_uploaded_file($v, $_SERVER['DOCUMENT_ROOT'] . '/' . $arc_name)) + { + $ar = [ + 'TITLE' => getMsg('ERR_EXTRACT'), + 'TEXT' => getMsg('ERR_UPLOAD'), + 'BOTTOM' => '' . getMsg('BUT_TEXT_BACK') . '', + ]; + html($ar); + die(); + } + } + $text = + '' . + ''; + showMsg(getMsg('LOADER_SUBTITLE1'), $text); + ?> + LocalCloud = $_REQUEST['LocalCloud'] ?? ''; + + if (!$oDB->Connect()) + { + $strErrMsg = $oDB->getError(); + $Step = 2; + $bSelectDumpStep = true; + } +} + +if (!$Step) +{ + $ar = [ + 'TITLE' => getMsg("TITLE0"), + 'TEXT' => + ($strErrMsg ? '
' . $strErrMsg . '
' : '') . + getMsg('BEGIN'), + 'BOTTOM' => + (defined('VMBITRIX') ? '' . getMsg('BUT_TEXT_BACK') . ' ' : '') . + '', + ]; + html($ar); +} +elseif ($Step == 1) +{ + $arc_down_url = $_REQUEST['arc_down_url'] ?? ''; + $local_arc_name = htmlspecialcharsbx(ltrim(($_REQUEST['local_arc_name'] ?? ''), '/')); + $license_key = ''; + if (!empty($_REQUEST['bitrixcloud_backup'])) + { + @include($_SERVER['DOCUMENT_ROOT'] . '/bitrix/license_key.php'); + $license_key = $LICENSE_KEY; + } + + $option = getArcList(); + $ar = [ + 'TITLE' => getMsg("TITLE1"), + 'TEXT' => + $local_arc_name + ? + '
' . getMsg("ARC_LOCAL_NAME") . ' ' . $local_arc_name . '
' + : + ($strErrMsg ? '
' . $strErrMsg . '
' : '') . + '' . + '
+ + +
+
+ + +
+
+ + +
+ ' + . (mb_strlen($option) ? + '
+ + ' . + '
' + : '') + . ($option === false ? '
' . getMsg('NO_READ_PERMS') . '
' : '') + . (count(getDumpList()) ? + '
' . + ' + +
' : '') + , + 'BOTTOM' => + '' . getMsg('BUT_TEXT_BACK') . ' ' . + '', + ]; + html($ar); +} +elseif ($Step == 2) +{ + if (!$bSelectDumpStep && !$bClearUnusedStep && !$bCloudDownloadStep) + { + $tar = new CTarRestore; + $tar->path = $_SERVER['DOCUMENT_ROOT']; + $tar->ReadBlockCurrent = intval($_REQUEST['ReadBlockCurrent'] ?? 0); + $tar->EncryptKey = $_REQUEST['EncryptKey'] ?? ''; + + $bottom = '' . getMsg('BUT_TEXT_BACK') . ' '; + + if ($rs = $tar->openRead($file1 = $file = $_SERVER['DOCUMENT_ROOT'] . '/' . $arc_name)) + { + $DataSize = intval($_REQUEST['DataSize'] ?? 0); + $skip = ''; + + if (!$DataSize) // first step + { + bx_unlink(RESTORE_FILE_LIST); + DeleteDirRec(RESTORE_FILE_DIR); + + $Block = $tar->Block; + if (!$ArchiveSize = $tar->getDataSize($file)) + { + $ArchiveSize = filesize($file) * 2; // for standard gzip files + } + $DataSize = $ArchiveSize; + + while (file_exists($file1 = $tar->getNextName($file1))) + { + $DataSize += $ArchiveSize; + } + + $r = true; + SetCurrentProgress(0); + + if ($n = CTar::getLastNum($file)) + { + for ($i = 1; $i <= $n; $i++) + { + if (!file_exists($file . '.' . $i)) + { + $strErrMsg = getMsg('ERR_NO_PARTS') . ' ' . ($n + 1) . ''; + $r = false; + break; + } + } + } + } + else + { + $Block = intval($_REQUEST['Block']); + $skip = ' '; + if ($r = $tar->SkipTo($Block)) + { + if ($_REQUEST['skip']) + { + while ($tar->readHeader() === false) + { + ; + } + $tar->SkipFile(); + } + while (($r = $tar->extractFile()) && haveTime()) + { + ; + } + } + $strErrMsg = implode('
', $tar->err); + } + + if ($r === 0) // Finish + { + $bClearUnusedStep = true; + } + else + { + SetCurrentProgress(($tar->BlockHeader + $tar->ReadBlockCurrent) * 512, $DataSize); + + $hidden = '' . + '' . + '' . + '' . + ''; + + if ($r === false) // Error + { + showMsg(getMsg("ERR_EXTRACT"), $status . $hidden . '
' . $strErrMsg . '
', $bottom . $skip); + } + else + { + showMsg(getMsg('TITLE_PROCESS1'), $status . $hidden, $bottom); + ?> + close(); + } + elseif ($tar->LastErrCode == 'ENC_KEY') + { + $text = ($tar->EncryptKey ? '
' . getMsg('WRONG_PASS') . '
' : '') . + getMsg('FILE_IS_ENC') . + '' . + '' . + ''; + $bottom .= ' '; + showMsg(getMsg('TITLE_PROCESS1'), $text, $bottom); + die(); + } + else + { + showMsg(getMsg("ERR_EXTRACT"), getMsg('TAR_ERR_FILE_OPEN') . ' ' . implode('
', $tar->err), $bottom); + die(); + } + } + + if ($bClearUnusedStep) + { + if (file_exists(RESTORE_FILE_LIST) && $f = fopen(RESTORE_FILE_LIST, 'rb')) + { + $modules = $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules'; + $components = $_SERVER['DOCUMENT_ROOT'] . '/bitrix/components/bitrix'; + fgets($f); // "die" line + $a = []; + while (($l = fgets($f)) !== false) + { + $a[trim($l)] = 1; + } + fclose($f); + + $ds = new CDirRealScan; + $ds->startPath = $_REQUEST['nextPath'] ?? ''; + if (mb_strpos($ds->startPath, $components) === 0) + { + $init_path = $components; + } + else + { + $init_path = $modules; + } + $res = $ds->Scan($init_path); + + if ($res === true && $init_path == $modules) + { + $ds->nextPath = $components; + $res = 'BREAK'; + } + + if ($res === 'BREAK') + { + $status = getMsg("SEARCHING_UNUSED"); + $hidden = '' . + '' . GetHidden(['dump_name', 'arc_name']); + $bottom = '' . getMsg('BUT_TEXT_BACK') . ' '; + showMsg(getMsg('TITLE_PROCESS1'), $status . $hidden, $bottom); + ?> + ' . getMsg('WARN_CLEARED'); + } + if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/bitrix/backup/sites')) + { + $strWarning .= '
  • ' . getMsg('WARN_SITES'); + } + $bSelectDumpStep = true; + } + + if ($strWarning) + { + $status = '
    ' . getMsg('WARNING') . '
      ' . $strWarning . '
    '; + $hidden = '' . GetHidden(['dump_name', 'arc_name']); + $bottom = '' . getMsg('BUT_TEXT_BACK') . ' ' . + ''; + showMsg(getMsg('TITLE_PROCESS1'), $status . $hidden, $bottom); + die(); + } + + if (file_exists(RESTORE_CLOUD_FILE_LIST)) + { + $skip = $_REQUEST['skip']; + if (!$skip && ($rsFile = fopen(RESTORE_CLOUD_FILE_LIST, 'rb'))) + { + if ($start_position = intval($_REQUEST['position'])) + { + fseek($rsFile, $start_position); + } + + if (is_array($_REQUEST['mirror_list']) && time() - intval($_REQUEST['init_time']) < 600) // раз в 10 минут снова измеряем зеркала + { + $mirror_list = $_REQUEST['mirror_list']; + arsort($mirror_list); // выбираем самое быстрое зеркало + } + else + { + $mirror_list = [ + 'cdn.bitrix24.ru' => 999999, + 'cdn.bitrix24.com' => 999999, + 'cdn.bitrix24.de' => 999999, + 'cdn-ru.bitrix24.ru' => 999999, + 'cdn-ru.bitrix24.de' => 999999, + ]; + $_REQUEST['init_time'] = $init_time = time(); + } + $mirror = key($mirror_list); + if (DEBUG) + { + echo time() - intval($_REQUEST['init_time']); + echo '
    ';
    +				print_r($mirror_list);
    +				echo '
    '; + } + + $file_list = []; + if (is_array($_REQUEST['file_list'])) + { + foreach ($_REQUEST['file_list'] as $file => $str) + { + if (!$f = unserialize($str)) + { + $strErrMsg = 'Unserialize failure: ' . $str; + break; + } + $file_list[$file] = $f; + $url = 'https://' . $mirror . '/' . $f['path']; + CMultiGet::startLoad($url, $file); + } + } + + $concurrency = 20; + $num = 0; + $bFirst = true; + while (!$strErrMsg) + { + while (haveTime() && count(CMultiGet::$connections) < $concurrency && (false !== $line = fgets($rsFile))) + { + $num++; + if (mb_strpos($line, '<' . '?php') === 0) + { + continue; + } + if (!preg_match('#^(\d{4}-\d{2}-\d{2} [\d:]{8})[ \t]+(\d+)[ \t]+(.+)$#', trim($line), $regs)) + { + $strErrMsg = 'File parse error ' . RESTORE_CLOUD_FILE_LIST . ' for line ' . $num . ': ' . $line; + break; + } + + $date = $regs[1]; + $size = $regs[2]; + $path = str_replace(' ', '%20', $regs[3]); + $save_path = preg_replace('#^[^/]+/#', '', $regs[3]); + + if (preg_match('#^[^/]*(cache/|tmp/|test.txt)#', $save_path)) + { + continue; + } + + $url = 'https://' . $mirror . '/' . $path; + $file = $_SERVER['DOCUMENT_ROOT'] . '/upload/' . $save_path; + + if (file_exists($file)) + { + if (filesize($file) == $size) + { + continue; + } + if (filesize($file) > $size) + { + bx_unlink($file); + } + } + + if (!CMultiGet::startLoad($url, $file)) + { + $strErrMsg = nl2br(htmlspecialcharsbx(CMultiGet::$error)); + break; + } + + $file_list[$file] = [ + 'date' => $date, + 'size' => $size, + 'path' => $path, + 'mirror' => $mirror, + ]; + } + + if (!CMultiGet::getPart()) + { + debug(CMultiGet::$error); + + $connection = CMultiGet::$connections[CMultiGet::$current]; + $url = $connection['url']; + CMultiGet::dropConnection(CMultiGet::$current); + + unset($file_list[$connection['file']]); // файла нет + + if ($bFirst) + { + $mirror_list_orig = $mirror_list; + $bFirst = false; + } + + foreach ($mirror_list as $mirror => $speed) + { + if (mb_strpos($url, 'https://' . $mirror) === 0) + { + unset($mirror_list[$mirror]); + CMultiGet::$bytes = 0; + break; + } + } + + if (count($mirror_list)) + { + $mirror = key($mirror_list); + foreach ($file_list as $file => $f) + { + $file_list[$file]['mirror'] = $mirror; + } + continue; + } + + if (!file_exists(RESTORE_CLOUD_FILE_LIST_404)) + { + file_put_contents(RESTORE_CLOUD_FILE_LIST_404, '<' . '?php die(); ?' . '>' . "\n"); + } + file_put_contents(RESTORE_CLOUD_FILE_LIST_404, nl2br(htmlspecialcharsbx(CMultiGet::$error)) . "\n", FILE_APPEND); + } + + if (!haveTime()) + { + break; + } + } + // для следующего хита обновим список зеркал + if ($bFirst === false) + { + $mirror_list = $mirror_list_orig; + } + + if (!$strErrMsg && (!feof($rsFile) || count(CMultiGet::$connections))) + { + $position = ftell($rsFile); + $size = filesize(RESTORE_CLOUD_FILE_LIST); + SetCurrentProgress($position, $size); + if (mb_strlen($file) > 80) + { + $file = '...' . mb_substr($file, -80); + } + $text = getMsg('ARC_DOWN_PROCESS') . ' ' . htmlspecialcharsbx($file) . '' . + $status . + GetHidden(['source', 'dump_name', 'arc_name', 'init_time']) . ' + + '; + + foreach ($file_list as $file => $f) + { + if (!file_exists($file) || filesize($file) < $f['size']) + { + $text .= ''; + } + } + + $mirror_list[$mirror] = round(CMultiGet::$bytes * 8 / 1024 / 1024 / STEP_TIME, 2); // Mbit/s + foreach ($mirror_list as $mirror => $speed) + { + $text .= ''; + } + + $bottom = '' . getMsg('BUT_TEXT_BACK') . '' . + ' '; + showMsg(getMsg('TITLE3'), $text, $bottom); + ?> + RESTORE_CLOUD_FILE_LIST]); + } + + if (!$strErrMsg) + { + bx_unlink(RESTORE_CLOUD_FILE_LIST) || $strErrMsg = getMsg('FINISH_ERR_DELL_TITLE') . ': ' . RESTORE_CLOUD_FILE_LIST; + $bSelectDumpStep = true; + } + + if ($strErrMsg) + { + $ar = [ + 'TITLE' => getMsg("TITLE3"), + 'TEXT' => '
    ' . $strErrMsg . '
    ', + 'BOTTOM' => + '' . + GetHidden(['source', 'dump_name', 'arc_name']) . + '' . getMsg('BUT_TEXT_BACK') . ' ' . + ' ', + ]; + html($ar); + ?> + = 0) + { + $mbstringVersion = true; + if ($mb_overload_value > 0) + { + $strErrMsg = getMsg('FUNC_OVERLOAD_ERROR') . '

    ' . $strErrMsg; + } + } + } + if (!$mbstringVersion) + { + if ($bUTF_conf && !$bUTF_serv) + { + $strErrMsg = getMsg('UTF8_ERROR1') . '

    ' . $strErrMsg; + } + elseif (!$bUTF_conf && $bUTF_serv) + { + $strErrMsg = getMsg('UTF8_ERROR2') . '

    ' . $strErrMsg; + } + } + } + + if ($strErrMsg) + { + $ar = [ + 'TITLE' => getMsg("TITLE2"), + 'TEXT' => '
    ' . $strErrMsg . '
    ', + 'BOTTOM' => + '' . GetHidden(['dump_name', 'arc_name']) . + '' . getMsg('BUT_TEXT_BACK') . ' ' . + ' ', + ]; + html($ar); + } + else + { + if (empty($_REQUEST['DBName'])) + { + $DBName = ''; + + $config = $_SERVER['DOCUMENT_ROOT'] . "/bitrix/.settings.php"; + if (file_exists($config)) + { + $ar = include($config); + + if (is_array($ar)) + { + if (is_array($ar['connections']['value']['default'])) + { + $DBHost = $ar['connections']['value']['default']['host'] ?? ''; + $DBName = $ar['connections']['value']['default']['database'] ?? ''; + $DBLogin = $ar['connections']['value']['default']['login'] ?? ''; + $DBPassword = $ar['connections']['value']['default']['password'] ?? ''; + } + } + } + + if ($DBName && !preg_match('#^\*+$#', $DBName)) + { + $strWarning .= '
  • ' . getMsg('DBCONN_WARN'); + $create_db = false; + } + else + { + $DBHost = 'localhost'; + $DBLogin = 'root'; + $DBPassword = ''; + $DBName = 'bitrix_' . (rand(11, 99)); + $create_db = "Y"; + } + } + else + { + $DBHost = $_REQUEST["DBHost"]; + $DBLogin = $_REQUEST["DBLogin"]; + $DBPassword = $_REQUEST["DBPassword"]; + $DBName = $_REQUEST["DBName"]; + $create_db = ($_REQUEST["create_db"] ?? '') == "Y"; + } + + $arDName = getDumpList(); + $strDName = ''; + foreach ($arDName as $db) + { + $strDName .= ''; + } + + if (!empty($arDName)) + { + $ar = [ + 'TITLE' => getMsg("TITLE2"), + 'TEXT' => + ($strWarning ? '
    ' . getMsg('WARNING') . '
      ' . $strWarning . '
    ' : '') . + '' . + (count($arDName) > 1 ? getMsg("DB_SELECT") . ' ' : '') . + '
    +
    ' . getMsg("DB_SETTINGS") . '
    + + + + + + +
    ' . getMsg("BASE_HOST") . ':
    ' . getMsg("USER_NAME") . ':
    ' . getMsg("USER_PASS") . ':
    ' . getMsg("BASE_NAME") . ':
    ' . getMsg("BASE_CREATE_DB") . '
    +
    ' . + ( + file_exists($_SERVER['DOCUMENT_ROOT'] . '/bitrix/backup/clouds') ? + '
    ' . getMsg("BASE_CLOUDS") . ' + +
    ' + : + '' + ) + , + 'BOTTOM' => + '' . getMsg('BUT_TEXT_BACK') . ' ' . + ' ' . + '', + ]; + html($ar); + } + else + { + showMsg(getMsg('FINISH'), GetHidden(['dump_name', 'arc_name']) . ''); + } + } + } +} +elseif ($Step == 3) +{ + $d_pos = (double)($_REQUEST["d_pos"] ?? 0); + if ($d_pos < 0) + { + $d_pos = 0; + } + + if (!isset($_REQUEST['d_pos'])) // start + { + $dbconnRestore = $_SERVER['DOCUMENT_ROOT'] . "/bitrix/php_interface/dbconn.restore.php"; + if (file_exists($dbconnRestore)) + { + bx_unlink($dbconn); + rename($dbconnRestore, $dbconn); + } + + if (file_exists($dbconn)) + { + if (($mainVersion = getMainVersion()) !== null && version_compare($mainVersion, '20.900.0') < 0) + { + // DB password should be in dbconn.php for older versions + $strFile = ''; + $arFile = file($dbconn); + foreach ($arFile as $line) + { + $line = str_replace("\r\n", "\n", $line); + if (preg_match('#^[ \t]*\$(DBHost|DBLogin|DBPassword|DBName)#', $line, $regs)) + { + $key = $regs[1]; + $line = '$' . $key . ' = "' . str_replace('$', '\$', addslashes($_REQUEST[$key])) . '";' . "\n"; + } + $strFile .= $line; + } + file_put_contents($dbconn, $strFile); + } + } + + $configRestore = $_SERVER['DOCUMENT_ROOT'] . "/bitrix/.settings.restore.php"; + if (file_exists($configRestore)) + { + $ar = include($configRestore); + + if (is_array($ar)) + { + if (is_array($ar['connections']['value']['default'])) + { + $ar['connections']['value']['default']['host'] = $_REQUEST['DBHost']; + $ar['connections']['value']['default']['database'] = $_REQUEST['DBName']; + $ar['connections']['value']['default']['login'] = $_REQUEST['DBLogin']; + $ar['connections']['value']['default']['password'] = $_REQUEST['DBPassword']; + $data = var_export($ar, true); + file_put_contents($configRestore, "<" . "?php\nreturn " . $data . ";\n"); + + $config = $_SERVER['DOCUMENT_ROOT'] . "/bitrix/.settings.php"; + bx_unlink($config); + rename($configRestore, $config); + } + } + bx_unlink($configRestore); + } + + SetCurrentProgress(0); + $r = true; + } + else + { + $r = $oDB->restore(); + } + + $bottom = '' . getMsg('BUT_TEXT_BACK') . ' '; + if ($r && !$oDB->is_end()) + { + $d_pos = $oDB->getPos(); + $oDB->close(); + $arc_name = $_REQUEST["arc_name"] ?? ''; + $dump_name = preg_replace('#\.[0-9]+$#', '', $_SERVER['DOCUMENT_ROOT'] . '/bitrix/backup/' . $_REQUEST['dump_name']); + $dump_size = 0; + while (file_exists($dump_name)) + { + $dump_size += filesize($dump_name); + $dump_name = CDBRestore::getNextName($dump_name); + } + SetCurrentProgress($d_pos, $dump_size); + $text = + $status . ' + + + + + + 0 ? htmlspecialcharsbx($_REQUEST["DBPassword"]) : '') . '"> + + + + '; + showMsg(getMsg('TITLE_PROCESS2'), $text, $bottom); + ?> + getError() != '') + { + showMsg(getMsg("ERR_DUMP_RESTORE"), '
    ' . $oDB->getError() . '
    ', $bottom); + } + else + { + if (!$oDB->ft_index) + { + $oDB->Query('UPDATE b_option SET VALUE="' . $oDB->escapeString(serialize([])) . '" WHERE MODULE_ID="main" AND NAME LIKE "~ft_%"'); + } + showMsg(getMsg('FINISH'), GetHidden(['DBLogin', 'DBPassword', 'DBHost', 'DBName', 'dump_name', 'arc_name', 'check_site_path']) . ''); + } + } +} +elseif ($Step == 4) +{ + $strWarning .= CheckHtaccessAndWarn(); + + if (!empty($_REQUEST['check_site_path'])) + { + $oDB = new CDBRestore($_REQUEST["DBHost"], $_REQUEST["DBName"], $_REQUEST["DBLogin"], $_REQUEST["DBPassword"], $_REQUEST["dump_name"], 0); + if ($oDB->Connect()) + { + if ($rs = $oDB->Query("SELECT * FROM b_lang WHERE DOC_ROOT != '" . $oDB->escapeString($_SERVER['DOCUMENT_ROOT']) . "' AND DOC_ROOT IS NOT NULL AND DOC_ROOT != ''")) + { + if ($oDB->Fetch($rs)) + { + $oDB->Query("UPDATE b_lang SET DOC_ROOT = '' "); + $strWarning .= '
  • ' . getMsg('DOC_ROOT_WARN'); + } + } + + $rs = $oDB->Query('SHOW TABLES LIKE "b_bitrixcloud_option"'); + if ($oDB->Fetch($rs)) + { + $rs = $oDB->Query('SELECT * FROM b_bitrixcloud_option WHERE NAME="cdn_config_active" AND PARAM_VALUE=1'); + if ($oDB->Fetch($rs)) + { + $rs = $oDB->Query('SELECT * FROM b_bitrixcloud_option WHERE NAME="cdn_config_domain"'); + if (($f = $oDB->Fetch($rs)) && $f['PARAM_VALUE'] != $_SERVER['HTTP_HOST']) + { + $oDB->Query('UPDATE b_bitrixcloud_option SET PARAM_VALUE=0 WHERE NAME="cdn_config_active"'); + $oDB->Query('UPDATE b_bitrixcloud_option SET PARAM_VALUE=' . (time() + 86400 * 3650) . ' WHERE NAME="cdn_config_expire_time"'); + $strWarning .= '
  • ' . getMsg('CDN_WARN'); + } + } + } + + if ($rs = $oDB->Query('SELECT * FROM b_module_to_module WHERE FROM_MODULE_ID="main" AND MESSAGE_ID="OnPageStart" AND TO_CLASS="Bitrix\\\\Security\\\\HostRestriction"')) + { + if ($f = $oDB->Fetch($rs)) // host restriction is turned on + { + $rs0 = $oDB->Query('SELECT * FROM b_option WHERE MODULE_ID="security" AND NAME="restriction_hosts_hosts"'); + if ($f0 = $oDB->Fetch($rs0)) + { + if (mb_strpos($f0['VALUE'], $_SERVER['HTTP_HOST']) === false) + { + $oDB->Query('DELETE FROM b_module_to_module WHERE ID=' . $f['ID']); + $strWarning .= '
  • ' . getMsg('HOSTS_WARN'); + } + } + } + } + } + else + { + $strWarning .= '
  • ' . $oDB->getError(); + } + } + + $text = + ($strWarning ? '
    ' . getMsg('WARNING') . '
      ' . $strWarning . '
    ' : '') . + getMsg("FINISH_MSG") . GetHidden(['dump_name', 'arc_name']); + $bottom = '' . getMsg('BUT_TEXT_BACK') . ' ' . + ''; + showMsg(getMsg("FINISH"), $text, $bottom); +} +elseif ($Step == 5) +{ + $ok = true; + $ok = bx_unlink($_SERVER['DOCUMENT_ROOT'] . '/bitrixsetup.php') && $ok; + + if (isset($_REQUEST['dump_name'])) + { + $ok = bx_unlink($_SERVER["DOCUMENT_ROOT"] . "/bitrix/backup/" . $_REQUEST["dump_name"]) && $ok; + $ok = bx_unlink($_SERVER["DOCUMENT_ROOT"] . "/bitrix/backup/" . str_replace('.sql', '_after_connect.sql', $_REQUEST["dump_name"])) && $ok; + } + + if (isset($_REQUEST['arc_name']) && mb_strpos($_REQUEST['arc_name'], 'bitrix/') === false) + { + $ok = bx_unlink($_SERVER["DOCUMENT_ROOT"] . "/" . $_REQUEST["arc_name"]) && $ok; + $i = 0; + while (file_exists($_SERVER['DOCUMENT_ROOT'] . '/' . $_REQUEST['arc_name'] . '.' . ++$i)) + { + $ok = bx_unlink($_SERVER['DOCUMENT_ROOT'] . '/' . $_REQUEST['arc_name'] . '.' . $i) && $ok; + } + } + + foreach (['cache', 'stack_cache', 'managed_cache', 'resize_cache', 'tmp'] as $dir) + { + $ok = DeleteDirRec($_SERVER['DOCUMENT_ROOT'] . '/bitrix/' . $dir) && $ok; + } + + $ok = bx_unlink($_SERVER["DOCUMENT_ROOT"] . "/restore.php") && $ok; + if (!$ok) + { + showMsg(getMsg("FINISH_ERR_DELL_TITLE"), '' . getMsg("FINISH_ERR_DELL") . ''); + } + else + { + showMsg(getMsg("FINISH"), getMsg("FINISH_MSG"), ''); + ?> + DBHost = $DBHost; + $this->DBLogin = $DBLogin; + $this->DBPassword = $DBPassword; + $this->DBName = $DBName; + $this->DBdump = $_SERVER["DOCUMENT_ROOT"] . "/bitrix/backup/" . $DBdump; + $this->d_pos = $d_pos; + $this->ft_index = null; + } + + function Query($sql, $ignoreError = false) + { + if ($this->ft_index === false && preg_match("#^CREATE TABLE.*FULLTEXT KEY#ms", $sql)) + { + $sql = preg_replace("#[\r\n\s]*FULLTEXT KEY[^\r\n]*[\r\n]*#m", '', $sql); + $sql = str_replace("),)", "))", $sql); + } + + $rs = mysqli_query($this->db_Conn, $sql); + if ($this->ft_index === null) + { + if (preg_match("#^CREATE TABLE.*FULLTEXT KEY#ms", $sql)) + { + $this->ft_index = (bool)$rs; + return $rs ? $rs : $this->Query($sql); + } + } + + if (!$rs && !$ignoreError) + { + $this->db_Error = "MySQL query error!
    " . mysqli_error($this->db_Conn) . '

    ' . htmlspecialcharsbx($sql); + return false; + } + return $rs; + } + + function Connect() + { + mysqli_report(MYSQLI_REPORT_OFF); + + $this->db_Conn = @mysqli_connect($this->DBHost, $this->DBLogin, $this->DBPassword); + if (!$this->db_Conn) + { + $this->db_Error = "MySQL connect error!
    " . mysqli_connect_error() . '
    '; + return false; + } + + $this->Query('SET FOREIGN_KEY_CHECKS = 0'); + + $dbExists = @mysqli_select_db($this->db_Conn, $this->DBName); + if (!$dbExists) + { + if (@$_REQUEST["create_db"] == "Y") + { + if (!@$this->Query("CREATE DATABASE `" . $this->escapeString($this->DBName) . "`")) + { + $this->db_Error = getMsg("ERR_CREATE_DB") . ': ' . mysqli_error($this->db_Conn); + return false; + } + $dbExists = @mysqli_select_db($this->db_Conn, $this->DBName); + } + + if (!$dbExists) + { + $this->db_Error = "Error! mysqli_select_db(" . htmlspecialcharsbx($this->DBName) . ")
    " . mysqli_error($this->db_Conn) . "
    "; + return false; + } + } + + $this->Query("SET SQL_MODE=''"); + $this->Query("SET innodb_strict_mode=0", true); + + $after_file = str_replace('.sql', '_after_connect.sql', $this->DBdump); + if (file_exists($after_file)) + { + $arSql = explode(';', file_get_contents($after_file)); + foreach ($arSql as $sql) + { + $sql = str_replace('', $this->DBName, $sql); + if (trim($sql)) + { + $this->Query($sql); + } + } + } + + return true; + } + + function Fetch($rs) + { + return mysqli_fetch_assoc($rs); + } + + function escapeString($str) + { + return mysqli_real_escape_string($this->db_Conn, $str); + } + + function readSql() + { + $cache = ''; + + while (CTar::substr($cache, -2, 1) != ";") + { + $line = fgets($this->_dFile); + if (feof($this->_dFile) || $line === false) + { + fclose($this->_dFile); + if (file_exists($next_part = self::getNextName($this->DBdump))) + { + $this->DBdump = $next_part; + if (!$this->_dFile = fopen($this->DBdump, 'rb')) + { + $this->db_Error = "Can't open file: " . $this->DBdump; + return false; + } + } + else + { + $this->f_end = true; + break; + } + } + + $cache .= $line; + } + + if ($this->f_end) + { + return false; + } + return $cache; + } + + function restore() + { + clearstatcache(); + while ($this->d_pos > ($s = filesize($this->DBdump)) && file_exists($this->DBdump)) + { + $this->d_pos -= $s; + $this->DBdump = self::getNextName($this->DBdump); + } + + if (!$this->_dFile = fopen($this->DBdump, 'rb')) + { + $this->db_Error = "Can't open file: " . $this->DBdump; + return false; + } + + if ($this->d_pos > 0) + { + fseek($this->_dFile, $this->d_pos); + } + + while (haveTime() && ($sql = $this->readSql())) + { + if (defined('VMBITRIX')) + { + if (preg_match('#^CREATE TABLE#i', $sql)) + { + $sql = preg_replace('#ENGINE=MyISAM#i', '', $sql); + $sql = preg_replace('#TYPE=MyISAM#i', '', $sql); + } + } + + $rs = $this->Query($sql); + + if (!$rs) + { + if ($this->getErrorNum() != 1062) // Duplicate entry + { + return false; + } + + if (preg_match('#^(INSERT[^(]+VALUES[^(]+)\((.+)\);?$#mis', $sql, $regs)) + { + $insert = $regs[1]; + foreach (preg_split('#\),[^(]\(#', $regs[2]) as $values) + { + $rs = $this->Query($insert . '(' . $values . ')'); + if (!$rs && $this->getErrorNum() != 1062) + { + return false; + } + } + return true; + } + } + } + $this->Query('SET FOREIGN_KEY_CHECKS = 1'); + + if ($this->LocalCloud && $this->f_end) + { + $i = ''; + while (file_exists($_SERVER['DOCUMENT_ROOT'] . '/upload/' . ($name = 'clouds' . $i))) + { + $i++; + } + if (!file_exists($f = $_SERVER['DOCUMENT_ROOT'] . '/upload')) + { + mkdir($f); + } + if (rename($_SERVER['DOCUMENT_ROOT'] . '/bitrix/backup/clouds', $_SERVER['DOCUMENT_ROOT'] . '/upload/' . $name)) + { + $arFiles = scandir($_SERVER['DOCUMENT_ROOT'] . '/upload/' . $name); + foreach ($arFiles as $file) + { + if ($id = intval($file)) + { + $this->Query('UPDATE b_file SET SUBDIR = CONCAT("' . $name . '/' . $id . '/", SUBDIR), HANDLER_ID=NULL WHERE HANDLER_ID =' . $id); + } + } + } + } + return true; + } + + function getError() + { + return $this->db_Error; + } + + function getErrorNum() + { + return mysqli_errno($this->db_Conn); + } + + function getPos() + { + if (is_resource($this->_dFile)) + { + $res = ftell($this->_dFile); + $prev = preg_replace('#\.[0-9]+$#', '', $this->DBdump); + clearstatcache(); + while ($this->DBdump != $prev) + { + if (!file_exists($prev)) + { + return false; + } + $res += filesize($prev); + $prev = self::getNextName($prev); + } + return $res; + } + return false; + } + + function close() + { + $this->_dFile = null; + return true; + } + + function is_end() + { + return $this->f_end; + } + + public static function getNextName($file) + { + static $CACHE; + $c = &$CACHE[$file]; + + if (!$c) + { + $l = mb_strrpos($file, '.'); + $num = CTar::substr($file, $l + 1); + if (is_numeric($num)) + { + $file = CTar::substr($file, 0, $l + 1) . ++$num; + } + else + { + $file .= '.1'; + } + $c = $file; + } + return $c; + } +} + +function getDumpList() +{ + $arDump = []; + if (is_dir($back_dir = $_SERVER["DOCUMENT_ROOT"] . "/bitrix/backup")) + { + $handle = opendir($back_dir); + while (false !== ($file = readdir($handle))) + { + if ($file == "." || $file == "..") + { + continue; + } + + if (is_dir($back_dir . '/' . $file)) + { + continue; + } + + if (mb_strpos($file, '_after_connect.sql')) + { + continue; + } + + if (mb_substr($file, mb_strlen($file) - 3, 3) == "sql") + { + $arDump[] = $file; + } + } + } + + return $arDump; +} + +function getMsg($index, $ar = []) +{ + global $MESS; + $str = $MESS[$index]; + foreach ($ar as $k => $v) + { + $str = str_replace($k, $v, $str); + } + return $str; +} + +function getArcList() +{ + $arc = ''; + global $strErrMsg; + + $handle = @opendir($_SERVER["DOCUMENT_ROOT"]); + if (!$handle) + { + return false; + } + + while (false !== ($file = @readdir($handle))) + { + if ($file == "." || $file == "..") + { + continue; + } + + if (is_dir($_SERVER["DOCUMENT_ROOT"] . "/" . $file)) + { + continue; + } + + if (preg_match('#\.(tar|enc)(\.gz)?$#', $file)) + { + $arc .= "
  • ' . getMsg('HTACCESS_RENAMED_WARN'); + } + } + else + { + if (file_put_contents($tmp, + 'Options -Indexes +ErrorDocument 404 /404.php + + + Options +FollowSymLinks + RewriteEngine On + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-l + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !/bitrix/urlrewrite.php$ + RewriteRule ^(.*)$ /bitrix/urlrewrite.php [L] + RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}] + + + + DirectoryIndex index.php index.html + + + + ExpiresActive on + ExpiresByType image/jpeg "access plus 3 day" + ExpiresByType image/gif "access plus 3 day" +')) + { + return '
  • ' . getMsg('HTACCESS_WARN'); + } + else + { + return '
  • ' . getMsg('HTACCESS_ERR_WARN'); + } + } +} + +function GetHidden($ar) +{ + $str = ''; + foreach ($ar as $k) + { + if (isset($_REQUEST[$k]) && is_array($_REQUEST[$k])) + { + foreach ($_REQUEST[$k] as $k0 => $v) + { + $str .= ''; + } + } + else + { + $str .= ''; + } + } + return $str; +} + +class CDirScan +{ + public $DirCount = 0; + public $FileCount = 0; + public $err = []; + public $bFound = false; + public $nextPath = ''; + public $startPath = ''; + public $arIncludeDir = false; + + public function __construct() + { + } + + function ProcessDirBefore($f) + { + return true; + } + + function ProcessDirAfter($f) + { + return true; + } + + function ProcessFile($f) + { + return true; + } + + function Skip($f) + { + if ($this->startPath) + { + if (mb_strpos($this->startPath . '/', $f . '/') === 0) + { + if ($this->startPath == $f) + { + $this->startPath = ''; + } + return false; + } + return true; + } + return false; + } + + function Scan($dir) + { + $dir = str_replace('\\', '/', $dir); + + if ($this->Skip($dir)) + { + return; + } + + $this->nextPath = $dir; + + if (is_dir($dir)) + { + if (!$this->startPath) + { + $r = $this->ProcessDirBefore($dir); + if ($r === false) + { + return false; + } + } + + if (!($handle = opendir($dir))) + { + $this->err[] = 'Error opening dir: ' . $dir; + return false; + } + + while (($item = readdir($handle)) !== false) + { + if ($item == '.' || $item == '..' || CTar::strpos($item, '\\') !== false) + { + continue; + } + + $f = $dir . "/" . $item; + $r = $this->Scan($f); + if ($r === false || $r === 'BREAK') + { + closedir($handle); + return $r; + } + } + closedir($handle); + + if (!$this->startPath) + { + if ($this->ProcessDirAfter($dir) === false) + { + return false; + } + $this->DirCount++; + } + } + else + { + $r = $this->ProcessFile($dir); + if ($r === false) + { + return false; + } + elseif ($r === 'BREAK') + { + return $r; + } + $this->FileCount++; + } + return true; + } +} + +class CDirRealScan extends CDirScan +{ + protected $cut; + + function Scan($dir) + { + if (!$this->cut) + { + $this->cut = CTar::strlen($_SERVER['DOCUMENT_ROOT'] . '/bitrix/'); + } + return parent::Scan($dir); + } + + function ProcessFile($f) + { + if (!haveTime()) + { + return 'BREAK'; + } + global $a; + if (!$a) + { + return null; + } + $k = CTar::substr($f, $this->cut); + if (!isset($a[$k])) + { + $to = RESTORE_FILE_DIR . '/' . $k; + CTar::xmkdir(dirname($to)); + rename($f, $to); + } + return true; + } +} + +class CMultiGet +{ + static $error = ''; + static $free_connections = []; + static $connections = []; + static $current; + static $bytes = 0; + + static function getConnection($connect_string) + { + $new_connection = null; + foreach (self::$free_connections as $key => $connection) + { + if ($connection['connect_string'] == $connect_string) + { + if (!self::isAlive($connection['socket'])) // сервер закрыл соединение + { + unset(self::$free_connections[$key]); + continue; + } + + $new_connection = self::$free_connections[$key]; + unset(self::$free_connections[$key]); + break; + } + } + + if (!$new_connection) + { + if ($sock = stream_socket_client($connect_string, $errno, $errstr, 5)) + { + stream_set_blocking($sock, false); + } + else + { + self::$error = 'Can\'t connect to ' . $connect_string . ' [' . $errno . '] ' . $errstr; + return false; + } + + $new_connection = [ + 'connect_string' => $connect_string, + 'socket' => $sock, + 'code' => 0, + 'length' => 0, + 'saved_length' => 0, + 'microtime' => microtime(1), + ]; + } + return $new_connection; + } + + static function startLoad($url, $file) + { + $u = parse_url($url); + if (!isset($u['port'])) + { + $u['port'] = $u['scheme'] == 'https' ? 443 : 80; + } + $connect_string = ($u['scheme'] == 'https' ? 'ssl://' : 'tcp://') . $u['host'] . ':' . $u['port']; + + if (!$connection = self::getConnection($connect_string)) + { + return false; + } + + $connection['state'] = 0; + $connection['url'] = $url; + $connection['file'] = $file; + + $strReq = + 'GET ' . $u['path'] . (isset($u['query']) ? '?' . $u['query'] : '') . ' HTTP/1.0' . "\r\n" . + 'Connection: keep-alive' . "\r\n" . + 'Host: ' . $u['host'] . "\r\n"; + if (file_exists($file)) + { + $strReq .= 'Range: bytes=' . filesize($file) . '-' . "\r\n"; + } + $strReq .= "\r\n"; + + if (!fwrite($connection['socket'], $strReq)) + { + self::$error = 'Can\'t write to ' . $connect_string; + return false; + } + + self::$connections[] = $connection; + end(self::$connections); + + debug('Connection #' . key(self::$connections) . ' request' . "\n" . $strReq); + + return true; + } + + static function getPart() + { + if (!count(self::$connections)) + { + return true; + } + + $arReadSock = []; + foreach (self::$connections as $key => $connection) + { + if (self::isAlive($connection['socket'])) + { + $arReadSock[] = $connection['socket']; + } + } + + $w = null; + $e = null; + + $n = stream_select($arReadSock, $w, $e, 1); + if ($n === 0) + { + return true; + } + + foreach ($arReadSock as $sock) + { + $key = null; + foreach (self::$connections as $key => $connection) + { + if ($connection['socket'] == $sock) + { + break; + } + } + self::$current = $key; + + $file = self::$connections[$key]['file']; + $state = &self::$connections[$key]['state']; + $header = ''; + + if ($state == 0) // начало загрузки, читаем заголовки + { + if (($line = fgets($sock)) === false) + { + continue; + } + + if (!preg_match('#^HTTP/1.. ([0-9]+)#', trim($line), $regs)) + { + self::$error = 'Invalid reply header: ' . trim($line) . "\n" . 'File: ' . $file; + return false; + } + + $header .= $line; + $state = $regs[1]; + + if ($state != 416 && !preg_match('#^2\d{2}$#', $state)) + { + self::$error = 'Wrong reply code: ' . trim($line) . "\n" . 'File: ' . $file; + return false; + } + + do + { + $line = fgets($sock); + if (preg_match('#Content-length: (\d+)#i', $line, $regs)) + { + self::$connections[$key]['length'] = $regs[1]; + } + $header .= $line; + } + while ($line != "\r\n"); + + debug('Connection #' . $key . ' response' . "\n" . $header); + } + + if (feof($sock) || $state == 416) + { + self::freeConnection($key); + } + else + { + $str = fread($sock, 1024 * 1024); + $dir = dirname($file); + if (!file_exists($dir)) + { + mkdir($dir, 0777, true); + } + $bytes = file_put_contents($file, $str, 8); + if ($bytes === false) + { + self::$error = getMsg('ERROR_CANT_WRITE', ['#FILE#' => $file, '#SPACE#' => freeSpace()]); + return false; + } + self::$bytes += $bytes; + self::$connections[$key]['saved_length'] += $bytes; + + if (self::$connections[$key]['saved_length'] >= self::$connections[$key]['length']) + { + self::freeConnection($key); + } + } + } + return true; + } + + static function isAlive($sock) + { + return is_resource($sock) && get_resource_type($sock) == 'stream'; + } + + static function freeConnection($key) + { + $sock = self::$connections[$key]['socket']; + if (self::isAlive($sock)) + { + self::$free_connections[] = [ + 'connect_string' => self::$connections[$key]['connect_string'], + 'microtime' => self::$connections[$key]['microtime'], + 'socket' => $sock, + ]; + unset(self::$connections[$key]); + } + } + + static function dropConnection($key) + { + $sock = self::$connections[$key]['socket']; + if (self::isAlive($sock)) + { + fclose($sock); + } + unset(self::$connections[$key]); + } +} + +function bx_unlink($file) +{ + if (!file_exists($file)) + { + return true; + } + if (DEBUG) + { + return rename($file, $file . '.debug'); + } + return unlink($file); +} + +function debug($str) +{ + if (!DEBUG) + { + return; + } + if (is_array($str)) + { + $str = print_r($str, 1); + } + file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/log.txt', date('[Y-m-d H:i:s] ') . $str . "\n", 8); +} + +function freeSpace() +{ + $d = disk_free_space(__FILE__); + if ($d === false) + { + return 'N/A'; + } + return HumanSize($d); +} + +function HumanSize($s) +{ + $i = 0; + $ar = ['b', 'kb', 'Mb', 'Gb']; + while ($s > 1024) + { + $s /= 1024; + $i++; + } + return round($s, 2) . '' . $ar[$i]; +} + +function getMainVersion() +{ + $versionFile = $_SERVER['DOCUMENT_ROOT'] . "/bitrix/modules/main/classes/general/version.php"; + if (file_exists($versionFile)) + { + include_once($versionFile); + return SM_VERSION; + } + + return null; +}