/*
* PtokaX - hub server for Direct Connect peer to peer network.
* Copyright (C) 2004-2022 Petr Kozelka, PPK at PtokaX dot org
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3
* as published by the Free Software Foundation.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
#include "stdinc.h"
//---------------------------------------------------------------------------
#include "TextFileManager.h"
//---------------------------------------------------------------------------
#include "ServerManager.h"
#include "SettingManager.h"
#include "User.h"
#include "utility.h"
//---------------------------------------------------------------------------
#ifdef _WIN32
#pragma hdrstop
#endif
//---------------------------------------------------------------------------
TextFilesManager * TextFilesManager::m_Ptr = NULL;
//---------------------------------------------------------------------------
TextFilesManager::TextFile::TextFile() : m_pPrev(NULL), m_pNext(NULL), m_sCommand(NULL), m_sText(NULL)
{
// ...
}
//---------------------------------------------------------------------------
TextFilesManager::TextFile::~TextFile()
{
free(m_sCommand);
free(m_sText);
}
//---------------------------------------------------------------------------
TextFilesManager::TextFilesManager() : m_pTextFiles(NULL)
{
// ...
}
//---------------------------------------------------------------------------
TextFilesManager::~TextFilesManager()
{
TextFile * cur = NULL,
* next = m_pTextFiles;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
delete cur;
}
}
//---------------------------------------------------------------------------
bool TextFilesManager::ProcessTextFilesCmd(User * pUser, char * sCommand, const bool bFromPM/* = false*/) const
{
TextFile * cur = NULL,
* next = m_pTextFiles;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if (strcasecmp(cur->m_sCommand, sCommand) == 0)
{
bool bInPM = (SettingManager::m_Ptr->m_bBools[SETBOOL_SEND_TEXT_FILES_AS_PM] == true || bFromPM);
size_t szHubSecLen = (size_t)SettingManager::m_Ptr->m_ui16PreTextsLens[SettingManager::SETPRETXT_HUB_SEC];
size_t szChatLen = 0;
// PPK ... to chat or to PM ???
if (bInPM == true)
{
szChatLen = 18 + pUser->m_ui8NickLen + (2 * szHubSecLen) + strlen(cur->m_sText);
}
else
{
szChatLen = 4 + szHubSecLen + strlen(cur->m_sText);
}
char * sMSG = (char *)malloc(szChatLen);
if (sMSG == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for sMsg in TextFilesManager::ProcessTextFilesCmd\n", szChatLen);
return true;
}
if (bInPM == true)
{
int iRet = snprintf(sMSG, szChatLen, "$To: %s From: %s $<%s> %s", pUser->m_sNick, SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], cur->m_sText);
if (iRet <= 0)
{
free(sMSG);
return true;
}
}
else
{
int iRet = snprintf(sMSG, szChatLen, "<%s> %s", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], cur->m_sText);
if (iRet <= 0)
{
free(sMSG);
return true;
}
}
pUser->SendCharDelayed(sMSG, szChatLen - 1);
free(sMSG);
return true;
}
}
return false;
}
//---------------------------------------------------------------------------
void TextFilesManager::RefreshTextFiles()
{
if (SettingManager::m_Ptr->m_bBools[SETBOOL_ENABLE_TEXT_FILES] == false)
return;
TextFile * cur = NULL,
* next = m_pTextFiles;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
delete cur;
}
m_pTextFiles = NULL;
#ifdef _WIN32
struct _finddata_t textfile;
intptr_t hFile = _findfirst((ServerManager::m_sPath + "\\texts\\*.txt").c_str(), &textfile);
if (hFile != -1)
{
do
{
if ((textfile.attrib & _A_SUBDIR) != 0 ||
stricmp(textfile.name + (strlen(textfile.name) - 4), ".txt") != 0)
{
continue;
}
FILE *f = fopen((ServerManager::m_sPath + "\\texts\\" + textfile.name).c_str(), "rb");
if (f != NULL)
{
if (textfile.size != 0)
{
TextFile * pNewTxtFile = new (std::nothrow) TextFile();
if (pNewTxtFile == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate pNewTxtFile in TextFilesManager::RefreshTextFiles\n");
fclose(f);
_findclose(hFile);
return;
}
pNewTxtFile->m_sText = (char *)malloc(textfile.size + 2);
if (pNewTxtFile->m_sText == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %" PRIu64 " bytes for m_sText in TextFilesManager::RefreshTextFiles\n", (uint64_t)(textfile.size + 2));
fclose(f);
_findclose(hFile);
delete pNewTxtFile;
return;
}
size_t size = fread(pNewTxtFile->m_sText, 1, textfile.size, f);
pNewTxtFile->m_sText[size] = '|';
pNewTxtFile->m_sText[size + 1] = '\0';
size_t szFileName = strlen(textfile.name)-4;
pNewTxtFile->m_sCommand = (char *)malloc(szFileName+1);
if (pNewTxtFile->m_sCommand == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for m_sCommand in TextFilesManager::RefreshTextFiles\n", szFileName+1);
fclose(f);
_findclose(hFile);
delete pNewTxtFile;
return;
}
memcpy(pNewTxtFile->m_sCommand, textfile.name, szFileName);
pNewTxtFile->m_sCommand[szFileName] = '\0';
pNewTxtFile->m_pPrev = NULL;
if (m_pTextFiles == NULL)
{
pNewTxtFile->m_pNext = NULL;
}
else
{
m_pTextFiles->m_pPrev = pNewTxtFile;
pNewTxtFile->m_pNext = m_pTextFiles;
}
m_pTextFiles = pNewTxtFile;
}
fclose(f);
}
}
while (_findnext(hFile, &textfile) == 0);
_findclose(hFile);
}
#else
string txtdir = ServerManager::m_sPath + "/texts/";
DIR * p_txtdir = opendir(txtdir.c_str());
if (p_txtdir == NULL)
{
return;
}
struct dirent * p_dirent;
struct stat s_buf;
while ((p_dirent = readdir(p_txtdir)) != NULL)
{
string txtfile = txtdir + p_dirent->d_name;
if (stat(txtfile.c_str(), &s_buf) != 0 ||
(s_buf.st_mode & S_IFDIR) != 0 ||
strcasecmp(p_dirent->d_name + (strlen(p_dirent->d_name) - 4), ".txt") != 0)
{
continue;
}
FILE *f = fopen(txtfile.c_str(), "rb");
if (f != NULL)
{
if (s_buf.st_size != 0)
{
TextFile * pNewTxtFile = new (std::nothrow) TextFile();
if (pNewTxtFile == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate pNewTxtFile in TextFilesManager::RefreshTextFiles1\n");
fclose(f);
closedir(p_txtdir);
return;
}
pNewTxtFile->m_sText = (char *)malloc(s_buf.st_size + 2);
if (pNewTxtFile->m_sText == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %" PRIu64 " bytes for m_sText in TextFilesManager::RefreshTextFiles\n", (uint64_t)(s_buf.st_size + 2));
fclose(f);
closedir(p_txtdir);
delete pNewTxtFile;
return;
}
size_t size = fread(pNewTxtFile->m_sText, 1, s_buf.st_size, f);
pNewTxtFile->m_sText[size] = '|';
pNewTxtFile->m_sText[size + 1] = '\0';
size_t szFileName = strlen(p_dirent->d_name)-4;
pNewTxtFile->m_sCommand = (char *)malloc(szFileName+1);
if (pNewTxtFile->m_sCommand == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for m_sCommand in TextFilesManager::RefreshTextFiles\n", szFileName+1);
fclose(f);
closedir(p_txtdir);
delete pNewTxtFile;
return;
}
memcpy(pNewTxtFile->m_sCommand, p_dirent->d_name, szFileName);
pNewTxtFile->m_sCommand[szFileName] = '\0';
pNewTxtFile->m_pPrev = NULL;
if (m_pTextFiles == NULL)
{
pNewTxtFile->m_pNext = NULL;
}
else
{
m_pTextFiles->m_pPrev = pNewTxtFile;
pNewTxtFile->m_pNext = m_pTextFiles;
}
m_pTextFiles = pNewTxtFile;
}
fclose(f);
}
}
closedir(p_txtdir);
#endif
}
//---------------------------------------------------------------------------
↑ V1042 This file is marked with copyleft license, which requires you to open the derived source code.