1
0
mirror of https://github.com/Bayselonarrend/OpenIntegrations.git synced 2025-11-25 22:12:29 +02:00
Files
OpenIntegrations/XML/CommonModules/OPI_SFTP/Ext/Module.bsl
Vitaly the Alpaca (bot) cdef2d02ab Main build (Jenkins)
2025-10-21 21:43:05 +03:00

741 lines
36 KiB
Plaintext

// OneScript: ./OInt/core/Modules/OPI_SFTP.os
// Lib: SFTP
// CLI: sftp
// Keywords: sftp
// MIT License
// Copyright (c) 2023-2025 Anton Tsitavets
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// https://github.com/Bayselonarrend/OpenIntegrations
// BSLLS:Typo-off
// BSLLS:LatinAndCyrillicSymbolInWord-off
// BSLLS:IncorrectLineBreak-off
// BSLLS:NumberOfOptionalParams-off
// BSLLS:UsingServiceTag-off
// BSLLS:LineLength-off
// BSLLS:UsingSynchronousCalls-off
//@skip-check module-structure-top-region
//@skip-check module-structure-method-in-regions
//@skip-check wrong-string-literal-content
//@skip-check method-too-many-params
//@skip-check constructor-function-return-section
#Область ПрограммныйИнтерфейс
#Область ОсновныеМетоды
// Открыть соединение !NOCLI
// Создает новый сеанс SFTP
//
// Примечание:
// Получить конфигурацию соединения можно при помощи функций `ПолучитьНастройкиЛогинПароль`,^^
// `ПолучитьНастройкиПриватныйКлюч`, `ПолучитьНастройкиЧерезАгента`
//
// Параметры:
// НастройкиSSH - Структура Из КлючИЗначение - Структура настроек соединения - set
// Прокси - Структура Из КлючИЗначение - Структура настроек прокси, если необходимо - proxy
//
// Возвращаемое значение:
// Произвольный, Соответствие Из КлючИЗначение - Открыть соединение
Функция ОткрытьСоединение(Знач НастройкиSSH, Знач Прокси = "") Экспорт
СоединениеSSH = OPI_ЗапросыSSH.ОткрытьСоединение(НастройкиSSH, Прокси);
Если ЭтоКоннектор(СоединениеSSH) Тогда
Результат = СоединениеSSH.ToSFTP();
Результат = OPI_Инструменты.JsonВСтруктуру(Результат);
Иначе
Возврат СоединениеSSH;
КонецЕсли;
Возврат ?(Результат["result"], СоединениеSSH, Результат);
КонецФункции
// Получить конфигурацию соединения
// Формирует полную структуру настроек соединения, которая может быть использована вместо самого соединения при вызове других функций
//
// Примечание:
// Может быть передана в качестве параметра `Соединение` в других функциях вместо настоящего соединения из функции `ОткрытьСоединение`.^^
// При этом новое соединение будет открыто и закрыто в рамках вызываемой функции
// Не рекомендуется использовать конфигурацию соединения при множественных обращениях к серверу SSH.^^
// Данный функционал предназначен, в первую очередь для CLI версии ОПИ, где хранение соединения между вызовами невозможно
//
// Параметры:
// НастройкиSSH - Структура Из КлючИЗначение - Настройки SSH - set
// Прокси - Структура Из КлючИЗначение - Настройки прокси, если необходимо. См. ПолучитьНастройкиПрокси - proxy
//
// Возвращаемое значение:
// Структура Из КлючИЗначение - Структура настроек соединения
Функция ПолучитьКонфигурациюСоединения(Знач НастройкиSSH, Знач Прокси = Неопределено) Экспорт
Возврат OPI_ЗапросыSSH.ПолучитьКонфигурациюСоединения(НастройкиSSH, Прокси);
КонецФункции
// Закрыть соединение !NOCLI
// Явно закрывает переданное соединение
//
// Параметры:
// Соединение - Произвольный - Объект компоненты с открытым соединением - conn
//
// Возвращаемое значение:
// Структура Из КлючИЗначение - Результат закрытия соединения
Функция ЗакрытьСоединение(Знач Соединение) Экспорт
Возврат OPI_ЗапросыSSH.ЗакрытьСоединение(Соединение);
КонецФункции
// Изменить путь
// Изменяет путь объекта на указанный
//
// Параметры:
// Соединение - Произвольный - Существующее соединение или конфигурация соединения - conn
// Путь - Строка - Текущий путь к объекту - old
// НовыйПуть - Строка - Новый путь к объекту - new
// Перезаписывать - Булево - Перезаписывать, если объект по целевому пути уже существует - rw
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - Результат обработки
Функция ИзменитьПуть(Знач Соединение, Знач Путь, Знач НовыйПуть, Знач Перезаписывать = Ложь) Экспорт
ЗакрыватьСоединение = ПроверитьСоздатьСоединение(Соединение);
Если Не ЭтоКоннектор(Соединение) Тогда
Возврат Соединение;
Иначе
OPI_ПреобразованиеТипов.ПолучитьСтроку(Путь);
OPI_ПреобразованиеТипов.ПолучитьСтроку(НовыйПуть);
OPI_ПреобразованиеТипов.ПолучитьБулево(Перезаписывать);
Результат = Соединение.RenameObject(Путь, НовыйПуть, Перезаписывать);
Результат = OPI_Инструменты.JsonВСтруктуру(Результат);
КонецЕсли;
Если ЗакрыватьСоединение Тогда
Результат.Вставить("close_connection", ЗакрытьСоединение(Соединение));
КонецЕсли;
Возврат Результат;
КонецФункции
// Это коннектор !NOCLI
// Проверяет, что значение является объектом внешней компоненты для работы с SFTP
//
// Параметры:
// Значение - Произвольный - Значение для проверки - value
//
// Возвращаемое значение:
// Булево - Это коннектор
Функция ЭтоКоннектор(Знач Значение) Экспорт
Возврат OPI_ЗапросыSSH.ЭтоКоннектор(Значение);
КонецФункции
// Получить настройки (логин/пароль)
// Получает настройки соединения с авторизацией через логин и пароль
//
// Параметры:
// Хост - Строка - Хост SSH - host
// Порт - Число - Порт SSH - port
// Логин - Строка - Имя пользователя SSH - user
// Пароль - Строка - Пароль пользователя SSH - pass
//
// Возвращаемое значение:
// Структура Из КлючИЗначение - Конфигурация соединения
Функция ПолучитьНастройкиЛогинПароль(Знач Хост, Знач Порт, Знач Логин, Знач Пароль = "") Экспорт
Возврат OPI_ЗапросыSSH.ПолучитьНастройкиЛогинПароль(Хост, Порт, Логин, Пароль);
КонецФункции
// Получить настройки (приватный ключ)
// Получает настройки соединения с авторизацией через приватный ключ
//
// Параметры:
// Хост - Строка - Хост SSH - host
// Порт - Число - Порт SSH - port
// Логин - Строка - Имя пользователя SSH - user
// Приватный - Строка - Путь к файлу приватного ключа - key
// Публичный - Строка - Путь к файлу публичного ключ - pub
// Пароль - Строка - Пароль (passphrase) приватного ключа - pass
//
// Возвращаемое значение:
// Структура Из КлючИЗначение - Конфигурация соединения
Функция ПолучитьНастройкиПриватныйКлюч(Знач Хост
, Знач Порт
, Знач Логин
, Знач Приватный
, Знач Публичный = ""
, Знач Пароль = "") Экспорт
Возврат OPI_ЗапросыSSH.ПолучитьНастройкиПриватныйКлюч(Хост, Порт, Логин, Приватный, Публичный, Пароль);
КонецФункции
// Получить настройки (через агента)
// Получает настройки соединения с авторизацией через SSH Agent
//
// Параметры:
// Хост - Строка - Хост SSH - host
// Порт - Число - Порт SSH - port
// Логин - Строка - Имя пользователя SSH - user
//
// Возвращаемое значение:
// Структура Из КлючИЗначение - Конфигурация соединения
Функция ПолучитьНастройкиЧерезАгента(Знач Хост, Знач Порт, Знач Логин) Экспорт
Возврат OPI_ЗапросыSSH.ПолучитьНастройкиЧерезАгента(Хост, Порт, Логин);
КонецФункции
// Получить настройки прокси
// Формирует структуру настроек прокси-сервера для соединения
//
// Параметры:
// Адрес - Строка - Адрес прокси - addr
// Порт - Число - Порт прокси - port
// Вид - Строка - Вид прокси: socks5, socks4, http - type
// Логин - Строка, Неопределено - Логин авторизации, если необходимо - login
// Пароль - Строка, Неопределено - Пароль для авторизации, если необходимо - pass
//
// Возвращаемое значение:
// Структура Из КлючИЗначение - Структура настроек прокси
Функция ПолучитьНастройкиПрокси(Знач Адрес
, Знач Порт
, Знач Вид = "socks5"
, Знач Логин = Неопределено
, Знач Пароль = Неопределено) Экспорт
//@skip-check constructor-function-return-section
Возврат OPI_Компоненты.ПолучитьНастройкиПрокси(Адрес, Порт, Вид, Логин, Пароль);
КонецФункции
#КонецОбласти
#Область РаботаСДиректориями
// Получить список объектов
// Получает информацию о содержимом директории по выбранному пути
//
// Примечание:
// Команда FTP: `LIST`
//
// Параметры:
// Соединение - Произвольный - Существующее соединение или конфигурация соединения - conn
// Путь - Строка - Путь к директории поиска - path
// Рекурсивно - Булево - Получать информацию об объектах во вложенных директориях - rcv
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - Результат обработки
Функция ПолучитьСписокОбъектов(Знач Соединение, Знач Путь = "", Знач Рекурсивно = Ложь) Экспорт
ЗакрыватьСоединение = ПроверитьСоздатьСоединение(Соединение);
Если Не ЭтоКоннектор(Соединение) Тогда
Возврат Соединение;
Иначе
OPI_ПреобразованиеТипов.ПолучитьБулево(Рекурсивно);
OPI_ПреобразованиеТипов.ПолучитьСтроку(Путь);
Результат = Соединение.ListDirectory(Путь);
Результат = OPI_Инструменты.JsonВСтруктуру(Результат);
ОбработатьРезультатПолученияСписка(Результат, Соединение, Рекурсивно);
КонецЕсли;
Если ЗакрыватьСоединение Тогда
Результат.Вставить("close_connection", ЗакрытьСоединение(Соединение));
КонецЕсли;
Возврат Результат;
КонецФункции
// BSLLS:MagicNumber-off
// Создать новую директорию
// Создает директорию по указанному пути
//
// Параметры:
// Соединение - Произвольный - Существующее соединение или конфигурация соединения - conn
// Путь - Строка - Путь к новой директории - path
// Права - Строка - Режим доступа к каталогу в числовом формате POSIX (как в chmod) - mode
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - Результат обработки
Функция СоздатьНовуюДиректорию(Знач Соединение, Знач Путь, Знач Права = 700) Экспорт
ЗакрыватьСоединение = ПроверитьСоздатьСоединение(Соединение);
Если Не ЭтоКоннектор(Соединение) Тогда
Возврат Соединение;
Иначе
OPI_ПреобразованиеТипов.ПолучитьСтроку(Путь);
Результат = Соединение.MakeDirectory(Путь, Права);
Результат = OPI_Инструменты.JsonВСтруктуру(Результат);
КонецЕсли;
Если ЗакрыватьСоединение Тогда
Результат.Вставить("close_connection", ЗакрытьСоединение(Соединение));
КонецЕсли;
Возврат Результат;
КонецФункции
// BSLLS:MagicNumber-on
// Удалить директорию
// Удаляет существующую директорию
//
// Параметры:
// Соединение - Произвольный - Существующее соединение или конфигурация соединения - conn
// Путь - Строка - Путь к удаляемой директории - path
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - Результат обработки
Функция УдалитьДиректорию(Знач Соединение, Знач Путь) Экспорт
ЗакрыватьСоединение = ПроверитьСоздатьСоединение(Соединение);
Если Не ЭтоКоннектор(Соединение) Тогда
Возврат Соединение;
Иначе
OPI_ПреобразованиеТипов.ПолучитьСтроку(Путь);
Результат = Соединение.RemoveDirectory(Путь);
Результат = OPI_Инструменты.JsonВСтруктуру(Результат);
КонецЕсли;
Если ЗакрыватьСоединение Тогда
Результат.Вставить("close_connection", ЗакрытьСоединение(Соединение));
КонецЕсли;
Возврат Результат;
КонецФункции
// Получить текущий каталог
// Получает текущий каталог, от которого вычисляются относительные пути
//
//
// Параметры:
// Соединение - Произвольный - Существующее соединение или конфигурация соединения - conn
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - Результат обработки
Функция ПолучитьТекущийКаталог(Знач Соединение) Экспорт
ЗакрыватьСоединение = ПроверитьСоздатьСоединение(Соединение);
Если Не ЭтоКоннектор(Соединение) Тогда
Возврат Соединение;
Иначе
Результат = OPI_ЗапросыSSH.ВыполнитьКоманду(Соединение, "pwd");
ОбработатьВыполнениеКомандыSSH(Результат, "path");
КонецЕсли;
Если ЗакрыватьСоединение Тогда
Результат.Вставить("close_connection", ЗакрытьСоединение(Соединение));
КонецЕсли;
Возврат Результат;
КонецФункции
#КонецОбласти
#Область РаботаСФайлами
// Загрузить файл
// Загружает файл с диска или двоичные данные на сервер
//
//
// Параметры:
// Соединение - Произвольный - Существующее соединение или конфигурация соединения - conn
// Файл - Строка, ДвоичныеДанные - Файл на диске или данные файла - file
// Путь - Строка - Путь сохранения файла на сервере - path
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - Результат обработки
Функция ЗагрузитьФайл(Знач Соединение, Знач Файл, Знач Путь) Экспорт
ЗакрыватьСоединение = ПроверитьСоздатьСоединение(Соединение);
Если Не ЭтоКоннектор(Соединение) Тогда
Возврат Соединение;
Иначе
Если ТипЗнч(Файл) = Тип("Строка") Тогда
ФайлНаДиске = Новый Файл(Файл);
ЭтоФайлНаДиске = ФайлНаДиске.Существует();
Иначе
ЭтоФайлНаДиске = Ложь;
КонецЕсли;
Если Не ЭтоФайлНаДиске Тогда
OPI_ПреобразованиеТипов.ПолучитьДвоичныеДанные(Файл);
Если OPI_Компоненты.ТребуетсяПередачаЧерезФайл() Тогда
// BSLLS:MissingTemporaryFileDeletion-off
//@skip-check missing-temporary-file-deletion
ИВФ = ПолучитьИмяВременногоФайла();
// BSLLS:MissingTemporaryFileDeletion-on
Файл.Записать(ИВФ);
Результат = Соединение.UploadFile(ИВФ, Путь);
OPI_Инструменты.УдалитьФайлВПопытке(ИВФ, "Не удалось удалить временный файл после загрузки");
Иначе
Результат = Соединение.UploadData(Файл, Путь);
КонецЕсли;
Иначе
Результат = Соединение.UploadFile(Файл, Путь);
КонецЕсли;
Результат = OPI_Инструменты.JsonВСтруктуру(Результат);
КонецЕсли;
Если ЗакрыватьСоединение Тогда
Результат.Вставить("close_connection", ЗакрытьСоединение(Соединение));
КонецЕсли;
Возврат Результат;
КонецФункции
// Удалить файл
// Удаляет файл с сервера
//
// Параметры:
// Соединение - Произвольный - Существующее соединение или конфигурация соединения - conn
// Путь - Строка - Путь файла на сервере - path
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - Результат обработки
Функция УдалитьФайл(Знач Соединение, Знач Путь) Экспорт
ЗакрыватьСоединение = ПроверитьСоздатьСоединение(Соединение);
Если Не ЭтоКоннектор(Соединение) Тогда
Возврат Соединение;
Иначе
OPI_ПреобразованиеТипов.ПолучитьСтроку(Путь);
Результат = Соединение.RemoveFile(Путь);
Результат = OPI_Инструменты.JsonВСтруктуру(Результат);
КонецЕсли;
Если ЗакрыватьСоединение Тогда
Результат.Вставить("close_connection", ЗакрытьСоединение(Соединение));
КонецЕсли;
Возврат Результат;
КонецФункции
// Сохранить файл
// Сохраняет файл с сервера по указанному пути
//
// Параметры:
// Соединение - Произвольный - Существующее соединение или конфигурация соединения - conn
// Путь - Строка - Путь файла на сервере - path
// ИмяФайла - Строка - Путь для сохранения файла на диске - file
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - Результат обработки
Функция СохранитьФайл(Знач Соединение, Знач Путь, Знач ИмяФайла) Экспорт
ЗакрыватьСоединение = ПроверитьСоздатьСоединение(Соединение);
Если Не ЭтоКоннектор(Соединение) Тогда
Возврат Соединение;
Иначе
OPI_ПреобразованиеТипов.ПолучитьСтроку(Путь);
OPI_ПреобразованиеТипов.ПолучитьСтроку(ИмяФайла);
OPI_Инструменты.ВернутьУправляющиеПоследовательности(ИмяФайла);
Результат = Соединение.DownloadToFile(Путь, ИмяФайла);
Результат = OPI_Инструменты.JsonВСтруктуру(Результат);
КонецЕсли;
Если ЗакрыватьСоединение Тогда
Результат.Вставить("close_connection", ЗакрытьСоединение(Соединение));
КонецЕсли;
Возврат Результат;
КонецФункции
// Получить данные файла !NOCLI
// Получает файл с сервера как двоичные данные
//
// Параметры:
// Соединение - Произвольный - Существующее соединение или конфигурация соединения - conn
// Путь - Строка - Путь файла на сервере - path
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение, ДвоичныеДанные - Данные файла или информация об ошибке
Функция ПолучитьДанныеФайла(Знач Соединение, Знач Путь) Экспорт
ЗакрыватьСоединение = ПроверитьСоздатьСоединение(Соединение);
Если Не ЭтоКоннектор(Соединение) Тогда
Возврат Соединение;
Иначе
OPI_ПреобразованиеТипов.ПолучитьСтроку(Путь);
Если OPI_Компоненты.ТребуетсяПередачаЧерезФайл() Тогда
// BSLLS:MissingTemporaryFileDeletion-off
//@skip-check missing-temporary-file-deletion
ИВФ = ПолучитьИмяВременногоФайла();
// BSLLS:MissingTemporaryFileDeletion-on
Результат = Соединение.DownloadToFile(Путь, ИВФ);
Результат = OPI_Инструменты.JsonВСтруктуру(Результат);
Если Результат["result"] Тогда
Данные = Новый ДвоичныеДанные(ИВФ);
OPI_Инструменты.УдалитьФайлВПопытке(ИВФ, "Не удалось удалить временный файл после загрузки");
Возврат Данные;
КонецЕсли;
Иначе
Данные = Соединение.DownloadToBuffer(Путь);
Если ТипЗнч(Данные) = Тип("Строка") Тогда
Результат = OPI_Инструменты.JsonВСтруктуру(Данные);
Иначе
Возврат Данные;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЗакрыватьСоединение Тогда
Результат.Вставить("close_connection", ЗакрытьСоединение(Соединение));
КонецЕсли;
Возврат Результат;
КонецФункции
// Получить информацию о файле
// Получает информацию о файле по указанному пути
//
// Параметры:
// Соединение - Произвольный - Существующее соединение или конфигурация соединения - conn
// Путь - Строка - Путь файла на сервере - path
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - Результат обработки
Функция ПолучитьИнформациюОФайле(Знач Соединение, Знач Путь) Экспорт
ЗакрыватьСоединение = ПроверитьСоздатьСоединение(Соединение);
Если Не ЭтоКоннектор(Соединение) Тогда
Возврат Соединение;
Иначе
OPI_ПреобразованиеТипов.ПолучитьСтроку(Путь);
Результат = Соединение.GetFileInfo(Путь);
Результат = OPI_Инструменты.JsonВСтруктуру(Результат);
КонецЕсли;
Если ЗакрыватьСоединение Тогда
Результат.Вставить("close_connection", ЗакрытьСоединение(Соединение));
КонецЕсли;
Возврат Результат;
КонецФункции
#КонецОбласти
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Функция ПроверитьСоздатьСоединение(Соединение)
Если Не ЭтоКоннектор(Соединение) Тогда
ЗакрыватьСоединение = Истина;
Соединение = ОткрытьСоединениеПоКонфигурации(Соединение);
Иначе
ЗакрыватьСоединение = Ложь;
КонецЕсли;
Если Не ЭтоКоннектор(Соединение) Тогда
Возврат Соединение;
КонецЕсли;
ЭтоSFTP = Соединение.IsSFTP();
Если Не ЭтоSFTP Тогда
Результат = Соединение.ToSFTP();
Результат = OPI_Инструменты.JsonВСтруктуру(Результат);
Соединение = ?(Результат["result"], Соединение, Результат);
КонецЕсли;
Возврат ЗакрыватьСоединение;
КонецФункции
Функция ОткрытьСоединениеПоКонфигурации(Знач СтруктураКонфигурации)
Если ЭтоКоннектор(СтруктураКонфигурации) Тогда
Возврат СтруктураКонфигурации;
КонецЕсли;
ШаблонОшибки = "Передана некорректная конфигурация соединения: %1";
Попытка
OPI_ПреобразованиеТипов.ПолучитьКоллекциюКлючИЗначение(СтруктураКонфигурации);
Исключение
Результат = Новый Соответствие;
Результат.Вставить("result", Ложь);
Результат.Вставить("error" , СтрШаблон(ШаблонОшибки, ОписаниеОшибки()));
Возврат Результат;
КонецПопытки;
Если Не OPI_Инструменты.ПолеКоллекцииСуществует(СтруктураКонфигурации, "set") Тогда
Результат = Новый Соответствие;
Результат.Вставить("result", Ложь);
Результат.Вставить("error" , СтрШаблон(ШаблонОшибки, "отсутствуют основные параметры соединения"));
Возврат Результат;
КонецЕсли;
НастройкиSSH = СтруктураКонфигурации["set"];
Прокси = OPI_Инструменты.ПолучитьИли(СтруктураКонфигурации, "proxy", Неопределено);
Возврат ОткрытьСоединение(НастройкиSSH, Прокси);
КонецФункции
Процедура ОбработатьВыполнениеКомандыSSH(Результат, ПолеРезультата = "data")
Result_ = "result";
Если Результат[Result_] Тогда
РезультатОбработки = Новый Соответствие;
Если Не ЗначениеЗаполнено(Результат["stderr"]) Тогда
РезультатОбработки.Вставить(Result_, Истина);
StdOut = Результат["stdout"];
Если ЗначениеЗаполнено(StdOut) Тогда
РезультатОбработки.Вставить(ПолеРезультата, StdOut);
КонецЕсли;
Иначе
РезультатОбработки.Вставить(Result_, Ложь);
РезультатОбработки.Вставить("error", Результат["stderr"]);
КонецЕсли;
Результат = РезультатОбработки;
КонецЕсли;
КонецПроцедуры
Процедура ОбработатьРезультатПолученияСписка(Результат, Соединение, Знач Рекурсивно)
Если Результат["result"] И Рекурсивно Тогда
Для Каждого ОбъектКаталога Из Результат["data"] Цикл
Если Не ОбъектКаталога["is_directory"] Тогда
Продолжить;
КонецЕсли;
Дочерние = ПолучитьСписокОбъектов(Соединение, ОбъектКаталога["path"], Истина);
Если Дочерние["result"] Тогда
ОбъектКаталога.Вставить("objects", Дочерние["data"]);
Иначе
ОбъектКаталога.Вставить("objects", Дочерние["error"]);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
#КонецОбласти