Код:
//Файл '/home/SendMail.txt' должен выглядеть как-то так:
(*-------------------------------------------------------------------------------------------------------------------
From: fff@ggggg.ru
To: ggggn@hhhhh.ru, hgjhgj@hgjhgjhgj.ru
Subject: Тема письма
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="BOUNDARY"
--BOUNDARY
Content-Type: text/plain; charset=UTF-8
Здесь идёт текстовка самого письма, строка №1
Здесь идёт текстовка самого письма, строка №2
--BOUNDARY
Content-Type: text/plain; charset=UTF-8
Content-Disposition: attachment; filename*=UTF-8''%D1%84%D0%B0%D0%B9%D0%BB.txt
Content-Transfer-Encoding: UTF-8
Здесь идёт текстовка вложенного файла, строка №1
Здесь идёт текстовка вложенного файла, строка №2
Здесь идёт текстовка вложенного файла, строка №3
--BOUNDARY
-------------------------------------------------------------------------------------------------------------------*)
FUNCTION_BLOCK My_CURL_EMAIL (*ФБ отправки электронной почты*)
//Входы-Выходы
VAR_IN_OUT
xExecute : BOOL; //Запуск
Mutex : BOOL; //Mutex для блокировки
END_VAR
//Входы
VAR_INPUT
sMailTo : WSTRING(255); //Список получателей
sTopic : WSTRING(255); //Тема письма
sMessage : WSTRING(131071); //Текстовка письма
sFileName : WSTRING(255); //Имя файла для вложения
sTextForFile : WSTRING(131071); //Содержимое файла для вложения
END_VAR
//Выходы
VAR_OUTPUT
xDone : BOOL; //Признак конца работы
xBusy : BOOL; //Признак занятости
xError : BOOL; //Признак ошибки
END_VAR
//Внутренние параметры
VAR
//R-триггер для фиксации запуска работы ФБ
fbRiseEdge : R_TRIG;
//Тексты для "/home/SendEmail.txt"
sMailFile : WSTRING(131071); //Текст файла для отправки письма "/home/SendEmail.txt"
sMailFile_UTF8 : STRING(131071); //Текст файла для отправки письма "/home/SendEmail.txt" в кодировке UTF8
//ФБ для отправки команд на контроллерную консоль
fbSe5: CmpSysExec.SysExecute5;
//Немножко магии для работы с файлом
pResult : POINTER TO SysFile.SysTypes.RTS_IEC_RESULT;
hFile : POINTER TO SysFile.SysTypes.RTS_IEC_HANDLE;
//Вспомогательный текст
TempText : WSTRING(1023);
//Реальная команда отправки на контроллерную консоль
sCommand_Real: STRING(2047) := '';
//Массив для парсинга списка получателей
MassivParsing : ARRAY[1..255] OF WSTRING(255); //Сам массив
sCommandParsing : WSTRING(255); //Итоговая строка
sCommandParsing_UTF8 : STRING(255); //Итоговая строка в UTF8
//Ненужный ответ от блока отправки на консоль //Но удалять его нельзя, т.к., без него блок не работает
asOutput: STRING(2047);
//Переменная цикла
i : INT; //Сама переменная
i_Max : DINT; //Максимальный индекс массива для парсинга списка получателей
//Определение реального конца работы
Mutex_TON : TON; //Таймер
Mutex_TON_PrVkl : BOOL; //Признак активации таймера
END_VAR
//Константы
VAR CONSTANT
//Команда отправки на контроллерную консоль
sCommand: STRING(2047) := 'curl --mail-from "qqq@qqq.ru" #MAILRCPT# --url "smtp://444.44.4.4:25" -u ggg@hhhh.ru:fdglfdmnjnfdlg --upload-file "/home/SendEmail.txt"';
END_VAR
Код:
//Проверяем признак запуска
fbRiseEdge(CLK := (xExecute AND NOT Mutex));
//Если появился признак запуска...
IF fbRiseEdge.Q THEN
//Парсим список получателей
i_Max := OSU.WSplitStringByToken(ADR(sMailTo), TO_UINT(WLen(sMailTo)), ", ", ADR(MassivParsing), SIZEOF(MassivParsing[1]), 255); //Парсим строку
//Цикл для формирования итоговой строки после парсинга списка получателей
sCommandParsing := "";
FOR i := 1 TO DINT_TO_INT(i_Max) DO
sCommandParsing := WCONCAT04(sCommandParsing, " --mail-rcpt $"", MassivParsing[i], "$"");
END_FOR
//Итоговая строка после парсинга списка получателей в правильной кодировке UTF8
STU.ConvertUTF16toUTF8(ADR(sCommandParsing), ADR(sCommandParsing_UTF8), SIZEOF(sCommandParsing_UTF8), FALSE);
sCommand_Real := OSU.ReplaceSubstring(sCommand, '#MAILRCPT#', sCommandParsing_UTF8);
//Формируем текстовку письма, где будут лежать все его параметры
//Обнуляем
Memutils.MemSet (ADR(sMailFile), 0, SIZEOF(sMailFile));
Memutils.MemSet (ADR(sMailFile_UTF8), 0, SIZEOF(sMailFile_UTF8));
sMailFile := "";
sMailFile_UTF8 := '';
//Пишем строки от кого и кому
TempText := WCONCAT03("From: opa@zaoshr.ru$r$nTo: ", sMailTo, "$r$nSubject: ");
SuperAddWString(ADR(sMailFile), ADR(TempText), TO_DWORD(SIZEOF(sMailFile)));
//Тема письма
SuperAddWString(ADR(sMailFile), ADR(sTopic), TO_DWORD(SIZEOF(sMailFile)));
//Пишем строки
TempText := "$r$nMIME-Version: 1.0$r$nContent-Type: multipart/mixed; boundary=$"BOUNDARY$"$r$n$r$n--BOUNDARY$r$nContent-Type: text/plain; charset=UTF-8$r$n$r$n";
SuperAddWString(ADR(sMailFile), ADR(TempText), TO_DWORD(SIZEOF(sMailFile)));
//Текстовка письма
SuperAddWString(ADR(sMailFile), ADR(sMessage), TO_DWORD(SIZEOF(sMailFile)));
//Пишем строки
TempText := "$r$n$r$n--BOUNDARY$r$nContent-Type: text/plain; charset=UTF-8$r$nContent-Disposition: attachment; filename*=UTF-8''";
SuperAddWString(ADR(sMailFile), ADR(TempText), TO_DWORD(SIZEOF(sMailFile)));
//Имя файла в кодировке "URL Escape Codes"
TempText := Convert_To_URL_Escape_Code(sFileName);
SuperAddWString(ADR(sMailFile), ADR(TempText), TO_DWORD(SIZEOF(sMailFile)));
//Пишем строки
TempText := "$r$nContent-Transfer-Encoding: UTF-8$r$n$r$n";
SuperAddWString(ADR(sMailFile), ADR(TempText), TO_DWORD(SIZEOF(sMailFile)));
//Содержимое файла для вложения
SuperAddWString(ADR(sMailFile), ADR(sTextForFile), TO_DWORD(SIZEOF(sMailFile)));
//Пишем строки
TempText := "$r$n--BOUNDARY";
SuperAddWString(ADR(sMailFile), ADR(TempText), TO_DWORD(SIZEOF(sMailFile)));
//Конвертер в UTF8
STU.ConvertUTF16toUTF8(ADR(sMailFile), ADR(sMailFile_UTF8), TO_DWORD(SIZEOF(sMailFile_UTF8)), FALSE);
//Пишем файл "/home/SendEmail.txt" перед отправкой самого письма
hFile := SysFile.SysFileOpen('/home/SendEmail.txt', SysFile.ACCESS_MODE.AM_WRITE, pResult);
SysFile.SysFileWrite(hFile, ADR(sMailFile_UTF8), TO_UDINT(StrLenA(ADR(sMailFile_UTF8))), pResult); //Пишем
SysFile.SysFileClose(hFile);
//Сброс команды запуска и активация блокировки по Mutex
xExecute := FALSE;
Mutex := TRUE;
Mutex_TON_PrVkl := TRUE;
END_IF
//Блок отправки команды через контроллерную консоль
fbSe5
(
xExecute := fbRiseEdge.Q,
pCommand := ADR(sCommand_Real),
szCommand := TO_DWORD(STU.StrLenA(ADR(sCommand_Real))),
pOutput := ADR(asOutput), //Ненужный ответ //Но удалять его нельзя, т.к., без него блок не работает
szOutput := SIZEOF(asOutput), //Ненужный ответ //Но удалять его нельзя, т.к., без него блок не работает
xDone => xDone,
xBusy => xBusy,
xError => xError
);
//Таймер конца работы, проверка на разблокировку и сама разблокировка
Mutex_TON(IN := Mutex_TON_PrVkl, PT := T#10S);
IF Mutex_TON_PrVkl AND (xDone OR xError OR Mutex_TON.Q) THEN
Mutex_TON_PrVkl := FALSE;
Mutex := FALSE;
END_IF