/*
* PtokaX - hub server for Direct Connect peer to peer network.
* Copyright (C) 2002-2005 Ptaczek, Ptaczek at PtokaX dot org
* 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 "utility.h"
//---------------------------------------------------------------------------
#include "hashBanManager.h"
#include "LanguageManager.h"
#include "ServerManager.h"
#include "SettingManager.h"
#include "UdpDebug.h"
#include "GlobalDataQueue.h"
//---------------------------------------------------------------------------
#ifdef _WIN32
#pragma hdrstop
#endif
//---------------------------------------------------------------------------
#ifdef _BUILD_GUI
#include "../gui.win/GuiUtil.h"
#include "../gui.win/MainWindowPageUsersChat.h"
#endif
//---------------------------------------------------------------------------
#ifndef _WITHOUT_SKEIN
#include <skein.h>
#endif
//---------------------------------------------------------------------------
/*
static const int MAX_PAT_SIZE = 64;
static const int MAX_ALPHABET_SIZE = 255;
*/
//---------------------------------------------------------------------------
extern bool g_isUseSyslog;
void AppendSyslog(const char* sType, const char * sData)
{
#ifndef _WIN32
if (g_isUseSyslog)
{
syslog(LOG_NOTICE, "[%s] %s", sType, sData);
}
#else
(void)sType;
(void)sData;
#endif
}
#ifdef _WIN32
void Cout(const string & sMsg)
{
if (ServerManager::m_hConsole != NULL)
{
WriteConsole(ServerManager::m_hConsole, (sMsg + "\n").c_str(), (DWORD)sMsg.size() + 1, 0, 0);
}
}
#else
void Cout(const string &/*sMsg*/)
{
return;
}
#endif
//---------------------------------------------------------------------------
/*
#ifdef _WIN32
// Boyer-Moore string matching algo.
// returns :
// offset in bytes or -1 if no match
int BMFind(char *text, int N, char *pat, int M) {
int i, j, DD[MAX_PAT_SIZE], D[MAX_ALPHABET_SIZE];
// Predzpracovani
preDD(pat, M, DD);
preD(pat, M, D);
// Vyhledavani
// Searching
i = 0;
while (i <= N-M) {
for(j = M-1; j >= 0 && pat[j] == text[j+i]; --j);
if (j < 0) {
return i;
//i += DD[0];
}
else
i += DD[j] > (D[text[j + i]] - M + 1 + j) ? DD[j] : (D[text[j + i]] - M + 1 + j);
}
return -1;
}
//---------------------------------------------------------------------------
void preD(char *pat, int M, int D[]) {
int i;
for(i = 0; i < MAX_ALPHABET_SIZE; ++i)
D[i] = M;
for(i = 0; i < M - 1; ++i)
D[pat[i]] = M - i - 1;
}
//---------------------------------------------------------------------------
// Funkce ulozi do suff[i] delku nejdelsiho podretezce,
// ktery konci na pozici pat[i]
// a soucasne je priponou pat
//
void suffixes(char *pat, int M, int *suff) {
int f = 0, g, i;
suff[M - 1] = M;
g = M - 1;
for(i = M - 2; i >= 0; --i) {
if (i > g && suff[i + M - 1 - f] < i - g)
suff[i] = suff[i + M - 1 - f];
else {
if (i < g)
g = i;
f = i;
while (g >= 0 && pat[g] == pat[g + M - 1 - f])
--g;
suff[i] = f - g;
}
}
}
//---------------------------------------------------------------------------
void preDD(char *pat, int M, int DD[]) {
int i, j, suff[MAX_PAT_SIZE];
suffixes(pat, M, suff);
for(i = 0; i < M; ++i)
DD[i] = M;
j = 0;
for(i = M - 1; i >= -1; --i)
if (suff[i] == i+1 || i == -1) // TODO FlylinkDC++ cppcheck! suff[-1] ??
for( ; j < M-1-i; ++j)
if (DD[j] == M)
DD[j] = M-1-i;
for(i = 0; i <= M-2; ++i)
DD[M - 1 - suff[i]] = M-1-i;
}
#endif
*/
//---------------------------------------------------------------------------
char * Lock2Key(char * sLock)
{
static const uint8_t ui8LockSize = 46;
static char cKey[128];
cKey[0] = '\0';
// $Lock EXTENDEDPROTOCOL33MTL6@h5AIad^P2UoPv?fZU]ivM6 Pk=PtokaX|
sLock = sLock + 6; // set begin after $Lock_
sLock[ui8LockSize] = '\0'; // set end before Pk
uint8_t v;
// first make the crypting stuff
for (uint8_t ui8i = 0; ui8i < ui8LockSize; ui8i++)
{
if (ui8i == 0)
{
v = (uint8_t)(sLock[0] ^ sLock[45] ^ sLock[44] ^ 5);
}
else
{
v = sLock[ui8i] ^ sLock[ui8i - 1];
}
// swap nibbles (0xF0 = 11110000, 0x0F = 00001111)
v = (uint8_t)(((v << 4) & 0xF0) | ((v >> 4) & 0x0F));
switch (v)
{
case 0:
strcat(cKey, "/%DCN000%/");
break;
case 5:
strcat(cKey, "/%DCN005%/");
break;
case 36:
strcat(cKey, "/%DCN036%/");
break;
case 96:
strcat(cKey, "/%DCN096%/");
break;
case 124:
strcat(cKey, "/%DCN124%/");
break;
case 126:
strcat(cKey, "/%DCN126%/");
break;
default:
strncat(cKey, (char *)&v, 1);
break;
}
}
return cKey;
}
//---------------------------------------------------------------------------
#ifdef _WIN32
char * WSErrorStr(const uint32_t ui32Error)
{
static char errStrings[][64] =
{
{"0"}, {"1"}, {"2"}, {"3"},
{"WSAEINTR"},
{"5"}, {"6"}, {"7"}, {"8"},
{"WSAEBADF"},
{"10"}, {"11"}, {"12"},
{"WSAEACCES"},
{"WSAEFAULT"},
{"15"}, {"16"}, {"17"}, {"18"}, {"19"}, {"20"}, {"21"},
{"WSAEINVAL"},
{"23"},
{"WSAEMFILE"},
{"25"}, {"26"}, {"27"}, {"28"}, {"29"}, {"30"}, {"31"}, {"32"}, {"33"}, {"34"},
{"WSAEWOULDBLOCK"},
{"WSAEINPROGRESS"}, // This error is returned if any Windows Sockets API function is called while a blocking function is in progress.
{"WSAEALREADY"},
{"WSAENOTSOCK"},
{"WSAEDESTADDRREQ"},
{"WSAEMSGSIZE"},
{"WSAEPROTOTYPE"},
{"WSAENOPROTOOPT"},
{"WSAEPROTONOSUPPORT"},
{"WSAESOCKTNOSUPPORT"},
{"WSAEOPNOTSUPP"},
{"WSAEPFNOSUPPORT"},
{"WSAEAFNOSUPPORT"},
{"WSAEADDRINUSE"},
{"WSAEADDRNOTAVAIL"},
{"WSAENETDOWN"}, // This error may be reported at any time if the Windows Sockets implementation detects an underlying failure.
{"WSAENETUNREACH"},
{"WSAENETRESET"},
{"WSAECONNABORTED"},
{"WSAECONNRESET"},
{"WSAENOBUFS"},
{"WSAEISCONN"},
{"WSAENOTCONN"},
{"WSAESHUTDOWN"},
{"WSAETOOMANYREFS"},
{"WSAETIMEDOUT"},
{"WSAECONNREFUSED"},
{"WSAELOOP"},
{"WSAENAMETOOLONG"},
{"WSAEHOSTDOWN"},
{"WSAEHOSTUNREACH"}, // 10065
{"WSASYSNOTREADY"}, // 10091
{"WSAVERNOTSUPPORTED"}, // 10092
{"WSANOTINITIALISED"}, // 10093
{"WSAHOST_NOT_FOUND"}, // 11001
{"WSATRY_AGAIN"}, // 11002
{"WSANO_RECOVERY"}, // 11003
{"WSANO_DATA"} // 11004
};
switch (ui32Error)
{
case 10091 :
return errStrings[66]; // WSASYSNOTREADY
case 10092 :
return errStrings[67]; // WSAVERNOTSUPPORTED
case 10093 :
return errStrings[68]; // WSANOTINITIALISED
case 11001 :
return errStrings[69]; // WSAHOST
case 11002 :
return errStrings[70]; // WSATRY
case 11003 :
return errStrings[71]; // WSANO
case 11004 :
return errStrings[72]; // WSANO
default :
return errStrings[ui32Error - 10000];
}
}
#else
const char * ErrnoStr(const uint32_t ui32Error)
{
static const char *errStrings[] =
{
"UNDEFINED",
"EADDRINUSE",
"EADDRNOTAVAIL",
"ECONNRESET",
"ETIMEDOUT",
"ECONNREFUSED",
"EHOSTUNREACH",
};
switch(ui32Error)
{
case 98:
return errStrings[1];
case 99:
return errStrings[2];
case 104:
return errStrings[3];
case 110:
return errStrings[4];
case 111:
return errStrings[5];
case 113:
return errStrings[6];
default :
return errStrings[0];
}
}
#endif
//---------------------------------------------------------------------------
const char * formatBytes(const uint64_t ui64Bytes)
{
static const char *unit[] = {"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", " ", " ", " ", " ", " ", " ", " "};
static char sBytes[128];
if (ui64Bytes < 1024)
{
int iLen = snprintf(sBytes, 128, "%" PRIu64 " %s", ui64Bytes & 0xffffffff, unit[0]);
if (iLen <= 0)
{
sBytes[0] = '\0';
}
}
else
{
long double ldBytes = (long double)ui64Bytes;
uint8_t iter = 0;
for (; ldBytes > 1024; iter++)
ldBytes /= 1024;
int iLen = snprintf(sBytes, 128, "%0.2Lf %s", ldBytes, unit[iter]);
if (iLen <= 0)
{
sBytes[0] = '\0';
}
}
return sBytes;
}
//---------------------------------------------------------------------------
const char * formatBytesPerSecond(const uint64_t ui64Bytes)
{
static const char *secondunit[] = {"B/s", "kB/s", "MB/s", "GB/s", "TB/s", "PB/s", "EB/s", "ZB/s", "YB/s", " ", " ", " ", " ", " ", " ", " "};
static char sBytes[128];
if (ui64Bytes < 1024)
{
int iLen = snprintf(sBytes, 128, "%" PRIu64 " %s", ui64Bytes & 0xffffffff, secondunit[0]);
if (iLen <= 0)
{
sBytes[0] = '\0';
}
}
else
{
long double ldBytes = (long double)ui64Bytes;
uint8_t iter = 0;
for (; ldBytes > 1024; iter++)
ldBytes /= 1024;
int iLen = snprintf(sBytes, 128, "%0.2Lf %s", ldBytes, secondunit[iter]);
if (iLen <= 0)
{
sBytes[0] = '\0';
}
}
return sBytes;
}
//---------------------------------------------------------------------------
const char * formatTime(uint64_t ui64Rest)
{
static char time[256];
time[0] = '\0';
char buf[128];
uint8_t i = 0;
uint64_t n = ui64Rest / 525600;
ui64Rest -= n * 525600;
if (n != 0)
{
int iLen = snprintf(buf, 128, "%" PRIu64 " %s", n, n > 1 ? LanguageManager::m_Ptr->m_sTexts[LAN_YEARS_LWR] : LanguageManager::m_Ptr->m_sTexts[LAN_YEAR_LWR]);
if (iLen <= 0)
{
return time;
}
strcat(time, buf);
i++;
}
n = ui64Rest / 43200;
ui64Rest -= n * 43200;
if (n != 0)
{
int iLen = snprintf(buf, 128, "%s%" PRIu64 " %s", i > 0 ? " " : "", n, n > 1 ? LanguageManager::m_Ptr->m_sTexts[LAN_MONTHS_LWR] : LanguageManager::m_Ptr->m_sTexts[LAN_MONTH_LWR]);
if (iLen <= 0)
{
time[0] = '\0';
return time;
}
strcat(time, buf);
i++;
}
n = ui64Rest / 1440;
ui64Rest -= n * 1440;
if (n != 0)
{
int iLen = snprintf(buf, 128, "%s%" PRIu64 " %s", i > 0 ? " " : "", n, n > 1 ? LanguageManager::m_Ptr->m_sTexts[LAN_DAYS_LWR] : LanguageManager::m_Ptr->m_sTexts[LAN_DAY_LWR]);
if (iLen <= 0)
{
time[0] = '\0';
return time;
}
strcat(time, buf);
i++;
}
n = ui64Rest / 60;
ui64Rest -= n * 60;
if (n != 0)
{
int iLen = snprintf(buf, 128, "%s%" PRIu64 " %s", i > 0 ? " " : "", n, n > 1 ? LanguageManager::m_Ptr->m_sTexts[LAN_HOURS_LWR] : LanguageManager::m_Ptr->m_sTexts[LAN_HOUR_LWR]);
if (iLen <= 0)
{
time[0] = '\0';
return time;
}
strcat(time, buf);
i++;
}
if (ui64Rest != 0)
{
int iLen = snprintf(buf, 128, "%s%" PRIu64 " %s", i > 0 ? " " : "", ui64Rest, LanguageManager::m_Ptr->m_sTexts[LAN_MIN_LWR]);
if (iLen <= 0)
{
time[0] = '\0';
return time;
}
strcat(time, buf);
}
return time;
}
//---------------------------------------------------------------------------
const char * formatSecTime(uint64_t ui64Rest)
{
static char time[256];
time[0] = '\0';
char buf[128];
uint8_t i = 0;
uint64_t n = ui64Rest / 31536000;
ui64Rest -= n * 31536000;
if (n != 0)
{
int iLen = snprintf(buf, 128, "%" PRIu64 " %s", n, n > 1 ? LanguageManager::m_Ptr->m_sTexts[LAN_YEARS_LWR] : LanguageManager::m_Ptr->m_sTexts[LAN_YEAR_LWR]);
if (iLen <= 0)
{
return time;
}
strcat(time, buf);
i++;
}
n = ui64Rest / 2592000;
ui64Rest -= n * 2592000;
if (n != 0)
{
int iLen = snprintf(buf, 128, "%s%" PRIu64 " %s", i > 0 ? " " : "", n, n > 1 ? LanguageManager::m_Ptr->m_sTexts[LAN_MONTHS_LWR] : LanguageManager::m_Ptr->m_sTexts[LAN_MONTH_LWR]);
if (iLen <= 0)
{
time[0] = '\0';
return time;
}
strcat(time, buf);
i++;
}
n = ui64Rest / 86400;
ui64Rest -= n * 86400;
if (n != 0)
{
int iLen = snprintf(buf, 128, "%s%" PRIu64 " %s", i > 0 ? " " : "", n, n > 1 ? LanguageManager::m_Ptr->m_sTexts[LAN_DAYS_LWR] : LanguageManager::m_Ptr->m_sTexts[LAN_DAY_LWR]);
if (iLen <= 0)
{
time[0] = '\0';
return time;
}
strcat(time, buf);
i++;
}
n = ui64Rest / 3600;
ui64Rest -= n * 3600;
if (n != 0)
{
int iLen = snprintf(buf, 128, "%s%" PRIu64 " %s", i > 0 ? " " : "", n, n > 1 ? LanguageManager::m_Ptr->m_sTexts[LAN_HOURS_LWR] : LanguageManager::m_Ptr->m_sTexts[LAN_HOUR_LWR]);
if (iLen <= 0)
{
time[0] = '\0';
return time;
}
strcat(time, buf);
i++;
}
n = ui64Rest / 60;
ui64Rest -= n * 60;
if (n != 0)
{
int iLen = snprintf(buf, 128, "%s%" PRIu64 " %s", i > 0 ? " " : "", n, LanguageManager::m_Ptr->m_sTexts[LAN_MIN_LWR]);
if (iLen <= 0)
{
time[0] = '\0';
return time;
}
strcat(time, buf);
i++;
}
if (ui64Rest != 0)
{
int iLen = snprintf(buf, 128, "%s%" PRIu64 " %s", i > 0 ? " " : "", ui64Rest, LanguageManager::m_Ptr->m_sTexts[LAN_SEC_LWR]);
if (iLen <= 0)
{
time[0] = '\0';
return time;
}
strcat(time, buf);
}
return time;
}
//---------------------------------------------------------------------------
char* stristr(const char *str1, const char *str2)
{
char *cp = (char *)str1;
if (*str2 == 0)
return (char *)str1;
while (*cp != 0)
{
char *s1 = cp;
char *s2 = (char *) str2;
while (*s1 != 0 && *s2 != 0 && ((*s1 - *s2) == 0 ||
(*s1 - tolower(*s2)) == 0 || (*s1 - toupper(*s2)) == 0))
s1++, s2++;
if (*s2 == 0)
{
return cp;
}
cp++;
}
return NULL;
}
//---------------------------------------------------------------------------
char* stristr2(const char *str1, const char *str2)
{
char *cp = (char *)str1;
if (*str2 == 0)
return (char *)str1;
while (*cp != 0)
{
char *s1 = cp;
char *s2 = (char *) str2;
while (*s1 != 0 && *s2 != 0 && ((*s1 - *s2) == 0 ||
(tolower(*s1) - *s2) == 0))
s1++, s2++;
if (*s2 == 0)
{
return cp;
}
cp++;
}
return NULL;
}
//---------------------------------------------------------------------------
// check IP string.
// false - no ip
// true - valid ip
bool isIP(const char * sIP)
{
if (ServerManager::m_bUseIPv6 == true && strchr(sIP, '.') == NULL)
{
if (strlen(sIP) > 39)
{
return false;
}
uint8_t ui128IpHash[16];
#if defined(_WIN32) && !defined(_WIN64) && !defined(_WIN_IOT)
if (win_inet_pton(sIP, ui128IpHash) != 1)
{
#else
if (inet_pton(AF_INET6, sIP, ui128IpHash) != 1)
{
#endif
return false;
}
}
else
{
if (strlen(sIP) > 15)
{
return false;
}
uint32_t ui32IpHash = inet_addr(sIP);
if (ui32IpHash == INADDR_NONE)
{
return false;
}
}
return true;
}
//---------------------------------------------------------------------------
uint32_t HashNick(const char * sNick, const size_t szNickLen)
{
unsigned char c = 0;
uint32_t h = 5381;
for (size_t szi = 0; szi < szNickLen; szi++)
{
c = (unsigned char)tolower(sNick[szi]);
h += (h << 5);
h ^= c;
}
return (h + 1);
}
//---------------------------------------------------------------------------
bool HashIP(const char * sIP, uint8_t * ui128IpHash)
{
if (ServerManager::m_bUseIPv6 == true && strchr(sIP, '.') == NULL)
{
if (strlen(sIP) > 39)
{
return false;
}
#if defined(_WIN32) && !defined(_WIN64) && !defined(_WIN_IOT)
if (win_inet_pton(sIP, ui128IpHash) != 1)
{
#else
if (inet_pton(AF_INET6, sIP, ui128IpHash) != 1)
{
#endif
return false;
}
}
else
{
if (strlen(sIP) > 15)
{
return false;
}
uint32_t ui32IpHash = inet_addr(sIP);
if (ui32IpHash == INADDR_NONE)
{
return false;
}
memset(ui128IpHash, 0, 16);
ui128IpHash[10] = 255;
ui128IpHash[11] = 255;
memcpy(ui128IpHash + 12, &ui32IpHash, 4);
}
return true;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
uint16_t GetIpTableIdx(const uint8_t * ui128IpHash)
{
unsigned char c = 0;
uint32_t h = 5381;
for (uint8_t ui8i = 0; ui8i < 16; ui8i++)
{
c = (unsigned char)ui128IpHash[ui8i];
h += (h << 5);
h ^= c;
}
h += 1;
uint16_t ui16Idx = 0;
memcpy(&ui16Idx, &h, sizeof(uint16_t));
return ui16Idx;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
int GenerateBanMessage(BanItem * pBan, const time_t &tAccTime)
{
int iMsgLen = 0;
if (((pBan->m_ui8Bits & BanManager::PERM) == BanManager::PERM) == true)
{
iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "<%s> %s.", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_SORRY_PERM_BANNED]);
}
else
{
iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "<%s> %s: %s.", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_SORRY_TEMP_BANNED], formatSecTime(pBan->m_tTempBanExpire - tAccTime));
}
if (iMsgLen <= 0)
{
AppendDebugLogFormat("[ERR] snprintf wrong value %d in GenerateBanMessage1\n", iMsgLen);
return 0;
}
if (SettingManager::m_Ptr->m_bBools[SETBOOL_BAN_MSG_SHOW_IP] == true && pBan->m_sIp[0] != '\0')
{
int iLen = snprintf(ServerManager::m_pGlobalBuffer + iMsgLen, ServerManager::m_szGlobalBufferSize - iMsgLen, "\n%s: %s", LanguageManager::m_Ptr->m_sTexts[LAN_IP], pBan->m_sIp);
if (iLen <= 0)
{
AppendDebugLogFormat("[ERR] snprintf wrong value %d in GenerateBanMessage2\n", iLen);
return 0;
}
iMsgLen += iLen;
}
if (SettingManager::m_Ptr->m_bBools[SETBOOL_BAN_MSG_SHOW_NICK] == true && pBan->m_sNick != NULL)
{
int iLen = snprintf(ServerManager::m_pGlobalBuffer + iMsgLen, ServerManager::m_szGlobalBufferSize - iMsgLen, "\n%s: %s", LanguageManager::m_Ptr->m_sTexts[LAN_NICK], pBan->m_sNick);
if (iLen <= 0)
{
AppendDebugLogFormat("[ERR] snprintf wrong value %d in GenerateBanMessage3\n", iLen);
return 0;
}
iMsgLen += iLen;
}
if (SettingManager::m_Ptr->m_bBools[SETBOOL_BAN_MSG_SHOW_REASON] == true && pBan->m_sReason != NULL)
{
int iLen = snprintf(ServerManager::m_pGlobalBuffer + iMsgLen, ServerManager::m_szGlobalBufferSize - iMsgLen, "\n%s: %s", LanguageManager::m_Ptr->m_sTexts[LAN_REASON], pBan->m_sReason);
if (iLen <= 0)
{
AppendDebugLogFormat("[ERR] snprintf wrong value %d in GenerateBanMessage4\n", iLen);
return 0;
}
iMsgLen += iLen;
}
if (SettingManager::m_Ptr->m_bBools[SETBOOL_BAN_MSG_SHOW_BY] == true && pBan->m_sBy != NULL)
{
int iLen = snprintf(ServerManager::m_pGlobalBuffer + iMsgLen, ServerManager::m_szGlobalBufferSize - iMsgLen, "\n%s: %s", LanguageManager::m_Ptr->m_sTexts[LAN_BANNED_BY], pBan->m_sBy);
if (iLen <= 0)
{
AppendDebugLogFormat("[ERR] snprintf wrong value %d in GenerateBanMessage5\n", iLen);
return 0;
}
iMsgLen += iLen;
}
if (SettingManager::m_Ptr->m_sTexts[SETTXT_MSG_TO_ADD_TO_BAN_MSG] != NULL)
{
int iLen = snprintf(ServerManager::m_pGlobalBuffer + iMsgLen, ServerManager::m_szGlobalBufferSize - iMsgLen, "\n%s|", SettingManager::m_Ptr->m_sTexts[SETTXT_MSG_TO_ADD_TO_BAN_MSG]);
if (iLen <= 0)
{
AppendDebugLogFormat("[ERR] snprintf wrong value %d in GenerateBanMessage6\n", iLen);
return 0;
}
iMsgLen += iLen;
}
else
{
ServerManager::m_pGlobalBuffer[iMsgLen] = '|';
iMsgLen++;
ServerManager::m_pGlobalBuffer[iMsgLen] = '\0';
}
#ifdef FLYLINKDC_USE_REDIR
if (((pBan->m_ui8Bits & BanManager::PERM) == BanManager::PERM) == true)
{
if (SettingManager::m_Ptr->m_bBools[SETBOOL_PERM_BAN_REDIR] == true && SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_PERM_BAN_REDIR_ADDRESS] != NULL)
{
strcpy(ServerManager::m_pGlobalBuffer + iMsgLen, SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_PERM_BAN_REDIR_ADDRESS]);
iMsgLen += (int)SettingManager::m_Ptr->m_ui16PreTextsLens[SettingManager::SETPRETXT_PERM_BAN_REDIR_ADDRESS];
}
}
else
{
if (SettingManager::m_Ptr->m_bBools[SETBOOL_TEMP_BAN_REDIR] == true && SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_TEMP_BAN_REDIR_ADDRESS] != NULL)
{
strcpy(ServerManager::m_pGlobalBuffer + iMsgLen, SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_TEMP_BAN_REDIR_ADDRESS]);
iMsgLen += (int)SettingManager::m_Ptr->m_ui16PreTextsLens[SettingManager::SETPRETXT_TEMP_BAN_REDIR_ADDRESS];
}
}
#endif
return iMsgLen;
}
//---------------------------------------------------------------------------
int GenerateRangeBanMessage(RangeBanItem * pRangeBan, const time_t &tAccTime)
{
int iMsgLen = 0;
if (((pRangeBan->m_ui8Bits & BanManager::PERM) == BanManager::PERM) == true)
{
iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "<%s> %s.", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_SORRY_PERM_BANNED]);
}
else
{
iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "<%s> %s: %s", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_SORRY_TEMP_BANNED], formatSecTime(pRangeBan->m_tTempBanExpire - tAccTime));
}
if (iMsgLen <= 0)
{
AppendDebugLogFormat("[ERR] snprintf wrong value %d in GenerateRangeBanMessage1\n", iMsgLen);
return 0;
}
if (SettingManager::m_Ptr->m_bBools[SETBOOL_BAN_MSG_SHOW_RANGE] == true)
{
int iLen = snprintf(ServerManager::m_pGlobalBuffer + iMsgLen, ServerManager::m_szGlobalBufferSize - iMsgLen, "\n%s: %s-%s", LanguageManager::m_Ptr->m_sTexts[LAN_RANGE], pRangeBan->m_sIpFrom, pRangeBan->m_sIpTo);
if (iLen <= 0)
{
AppendDebugLogFormat("[ERR] snprintf wrong value %d in GenerateRangeBanMessage2\n", iLen);
return 0;
}
iMsgLen += iLen;
}
if (SettingManager::m_Ptr->m_bBools[SETBOOL_BAN_MSG_SHOW_REASON] == true && pRangeBan->m_sReason != NULL)
{
int iLen = snprintf(ServerManager::m_pGlobalBuffer + iMsgLen, ServerManager::m_szGlobalBufferSize - iMsgLen, "\n%s: %s", LanguageManager::m_Ptr->m_sTexts[LAN_REASON], pRangeBan->m_sReason);
if (iLen <= 0)
{
AppendDebugLogFormat("[ERR] snprintf wrong value %d in GenerateRangeBanMessage3\n", iLen);
return 0;
}
iMsgLen += iLen;
}
if (SettingManager::m_Ptr->m_bBools[SETBOOL_BAN_MSG_SHOW_BY] == true && pRangeBan->m_sBy != NULL)
{
int iLen = snprintf(ServerManager::m_pGlobalBuffer + iMsgLen, ServerManager::m_szGlobalBufferSize - iMsgLen, "\n%s: %s", LanguageManager::m_Ptr->m_sTexts[LAN_BANNED_BY], pRangeBan->m_sBy);
if (iLen <= 0)
{
AppendDebugLogFormat("[ERR] snprintf wrong value %d in GenerateRangeBanMessage4\n", iLen);
return 0;
}
iMsgLen += iLen;
}
if (SettingManager::m_Ptr->m_sTexts[SETTXT_MSG_TO_ADD_TO_BAN_MSG] != NULL)
{
int iLen = snprintf(ServerManager::m_pGlobalBuffer + iMsgLen, ServerManager::m_szGlobalBufferSize - iMsgLen, "\n%s|", SettingManager::m_Ptr->m_sTexts[SETTXT_MSG_TO_ADD_TO_BAN_MSG]);
if (iLen <= 0)
{
AppendDebugLogFormat("[ERR] snprintf wrong value %d in GenerateRangeBanMessage5\n", iLen);
return 0;
}
iMsgLen += iLen;
}
else
{
ServerManager::m_pGlobalBuffer[iMsgLen] = '|';
iMsgLen++;
ServerManager::m_pGlobalBuffer[iMsgLen] = '\0';
}
#ifdef FLYLINKDC_USE_REDIR
if (((pRangeBan->m_ui8Bits & BanManager::PERM) == BanManager::PERM) == true)
{
if (SettingManager::m_Ptr->m_bBools[SETBOOL_PERM_BAN_REDIR] == true && SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_PERM_BAN_REDIR_ADDRESS] != NULL)
{
strcpy(ServerManager::m_pGlobalBuffer + iMsgLen, SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_PERM_BAN_REDIR_ADDRESS]);
iMsgLen += (int)SettingManager::m_Ptr->m_ui16PreTextsLens[SettingManager::SETPRETXT_PERM_BAN_REDIR_ADDRESS];
}
}
else
{
if (SettingManager::m_Ptr->m_bBools[SETBOOL_TEMP_BAN_REDIR] == true && SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_TEMP_BAN_REDIR_ADDRESS] != NULL)
{
strcpy(ServerManager::m_pGlobalBuffer + iMsgLen, SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_TEMP_BAN_REDIR_ADDRESS]);
iMsgLen += (int)SettingManager::m_Ptr->m_ui16PreTextsLens[SettingManager::SETPRETXT_TEMP_BAN_REDIR_ADDRESS];
}
}
#endif
return iMsgLen;
}
//---------------------------------------------------------------------------
bool GenerateTempBanTime(const uint8_t ui8Multiplyer, const uint32_t ui32Time, time_t &tAccTime, time_t &tBanTime)
{
time(&tAccTime);
struct tm *tm = localtime(&tAccTime);
switch (ui8Multiplyer)
{
case 'm':
tm->tm_min += ui32Time;
break;
case 'h':
tm->tm_hour += ui32Time;
break;
case 'd':
tm->tm_mday += ui32Time;
break;
case 'w':
tm->tm_mday += ui32Time * 7;
break;
case 'M':
tm->tm_mon += ui32Time;
break;
case 'Y':
tm->tm_year += ui32Time;
break;
default:
return false;
}
tm->tm_isdst = -1;
tBanTime = mktime(tm);
if(tBanTime == (time_t)-1)
{
return false;
}
return true;
}
//---------------------------------------------------------------------------
// + alex82 ... from MOD
bool CheckSprintf(const int iRetVal, const size_t szMax, const char * sMsg)
{
if (iRetVal > 0)
{
if (szMax != 0 && iRetVal >= (int)szMax)
{
const std::string sDbgstr = "%s - [ERR] sprintf high value " + std::to_string(iRetVal) + "/" + std::to_string((uint64_t)szMax) + " in " + std::to_string(sMsg) + "\n";
AppendDebugLog(sDbgstr.c_str()/*, 0*/);
return false;
}
}
else
{
const std::string sDbgstr = "%s - [ERR] sprintf low value " + std::to_string(iRetVal) + " in " + std::to_string(sMsg) + "\n";
AppendDebugLog(sDbgstr.c_str()/*, 0*/);
return false;
}
return true;
}
//---------------------------------------------------------------------------
bool CheckSprintf1(const int iRetVal, const size_t szLenVal, const size_t szMax, const char * sMsg)
{
if (iRetVal > 0)
{
if (szMax != 0 && szLenVal >= szMax)
{
const std::string sDbgstr = "%s - [ERR] sprintf high value " + std::to_string((uint64_t)szLenVal) + "/" + std::to_string((uint64_t)szMax) + " in " + std::to_string(sMsg) + "\n";
AppendDebugLog(sDbgstr.c_str()/*, 0*/);
return false;
}
}
else
{
const std::string sDbgstr = "%s - [ERR] sprintf low value " + std::to_string(iRetVal) + " in " + std::to_string(sMsg) + "\n";
AppendDebugLog(sDbgstr.c_str()/*, 0*/);
return false;
}
return true;
}
//---------------------------------------------------------------------------
void AppendLog(const char* sData, const bool bScript/* == false*/)
{
FILE * fw;
AppendSyslog("AppendLog", sData); // [+]FlylinkDC++
if (bScript == false)
{
#ifdef _WIN32
fw = fopen((ServerManager::m_sPath + "\\logs\\system.log").c_str(), "a");
#else
fw = fopen((ServerManager::m_sPath + "/logs/system.log").c_str(), "a");
#endif
}
else
{
#ifdef _WIN32
fw = fopen((ServerManager::m_sPath + "\\logs\\script.log").c_str(), "a");
#else
fw = fopen((ServerManager::m_sPath + "/logs/script.log").c_str(), "a");
#endif
}
if (fw != NULL)
{
time_t acc_time;
time(&acc_time);
struct tm * acc_tm;
acc_tm = localtime(&acc_time);
char sBuf[64];
strftime(sBuf, sizeof(sBuf), "%c", acc_tm);
fprintf(fw, "%s - %s\n", sBuf, sData);
printf("[log] %s - %s\n", sBuf, sData);
fclose(fw);
}
if(GlobalDataQueue::m_Ptr)
GlobalDataQueue::m_Ptr->PrometheusLogBytes("logs",strlen(sData));
if (UdpDebug::m_Ptr != NULL && bScript == false)
{
UdpDebug::m_Ptr->BroadcastFormat("[LOG] %s", sData);
}
}
//---------------------------------------------------------------------------
void AppendDebugLog(const char * sData)
{
AppendSyslog("AppendDebugLog", sData); // [+]FlylinkDC++
#ifdef _WIN32
FILE * fw = fopen((ServerManager::m_sPath + "\\logs\\debug.log").c_str(), "a");
#else
FILE * fw = fopen((ServerManager::m_sPath + "/logs/debug.log").c_str(), "a");
#endif
if (fw == NULL)
{
return;
}
time_t acc_time;
time(&acc_time);
struct tm * acc_tm;
acc_tm = localtime(&acc_time);
char sBuf[64];
strftime(sBuf, 64, "%c", acc_tm);
fprintf(fw, sData, sBuf); // "%s - xxx\n"
printf("[debug-log] %s - %s\n", sBuf, sData);
fclose(fw);
if(GlobalDataQueue::m_Ptr)
GlobalDataQueue::m_Ptr->PrometheusLogBytes("logsd",strlen(sData));
}
//---------------------------------------------------------------------------
void AppendDebugLogFormat(const char * sFormatMsg, ...)
{
#ifndef _WIN32 // [+]FlylinkDC++
if (g_isUseSyslog)
{
std::string l_str;
l_str.resize(65535);
va_list vlArgs;
va_start(vlArgs, sFormatMsg);
vsnprintf(&l_str[0], l_str.size(), sFormatMsg, vlArgs);
va_end(vlArgs);
syslog(LOG_NOTICE, "[AppendDebugLogFormat] %s", l_str.c_str());
}
#endif
#ifdef _WIN32
FILE * fw = fopen((ServerManager::m_sPath + "\\logs\\debug.log").c_str(), "a");
#else
FILE * fw = fopen((ServerManager::m_sPath + "/logs/debug.log").c_str(), "a");
#endif
if (fw == NULL)
{
return;
}
time_t tmAccTime;
time(&tmAccTime);
size_t szLen = strftime(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "%c - ", localtime(&tmAccTime));
if (szLen != 0)
{
fwrite(ServerManager::m_pGlobalBuffer, 1, szLen, fw);
}
va_list vlArgs;
va_start(vlArgs, sFormatMsg);
vfprintf(fw, sFormatMsg, vlArgs);
va_end(vlArgs);
fclose(fw);
if(GlobalDataQueue::m_Ptr)
GlobalDataQueue::m_Ptr->PrometheusLogBytes("logf",szLen);
}
//---------------------------------------------------------------------------
#ifdef _WIN32
void GetHeapStats(void * pHeap, DWORD &dwCommitted, DWORD &dwUnCommitted)
{
PROCESS_HEAP_ENTRY *lpEntry;
lpEntry = (PROCESS_HEAP_ENTRY *)calloc(1, sizeof(PROCESS_HEAP_ENTRY));
if (lpEntry == NULL)
{
return;
}
lpEntry->lpData = NULL;
while (HeapWalk((HANDLE)pHeap, (PROCESS_HEAP_ENTRY *)lpEntry) != 0)
{
if ((lpEntry->wFlags & PROCESS_HEAP_REGION))
{
dwCommitted += lpEntry->Region.dwCommittedSize;
dwUnCommitted += lpEntry->Region.dwUnCommittedSize;
}
}
free(lpEntry);
}
//---------------------------------------------------------------------------
const char * ExtractFileName(const char * sPath)
{
const char * sName = strrchr(sPath, '\\');
if (sName != NULL)
{
return sName;
}
else
{
return sPath;
}
}
#endif
//---------------------------------------------------------------------------
#ifdef _BUILD_GUI
void Memo(const string &sMessage)
{
RichEditAppendText(MainWindowPageUsersChat::m_Ptr->m_hWndPageItems[MainWindowPageUsersChat::REDT_CHAT], sMessage.c_str());
}
#else
void Memo(const string &/*sMessage*/)
{
// ...
}
#endif
//---------------------------------------------------------------------------
bool FileExist(const char * sPath)
{
#ifdef _WIN32
const DWORD code = GetFileAttributes(sPath);
if (code != INVALID_FILE_ATTRIBUTES && code != FILE_ATTRIBUTE_DIRECTORY)
{
#else
struct stat st;
if (stat(sPath, &st) == 0 && S_ISDIR(st.st_mode) == 0)
{
#endif
return true;
}
return false;
}
//---------------------------------------------------------------------------
bool DirExist(const char * sPath)
{
#ifdef _WIN32
const DWORD code = GetFileAttributes(sPath);
if (code == FILE_ATTRIBUTE_DIRECTORY)
{
#else
struct stat st;
if (stat(sPath, &st) == 0 && S_ISDIR(st.st_mode))
{
#endif
return true;
}
return false;
}
//---------------------------------------------------------------------------
#ifdef _WIN32
void SetupOsVersion()
{
OSVERSIONINFOEX ver;
memset(&ver, 0, sizeof(OSVERSIONINFOEX));
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if (::GetVersionEx((OSVERSIONINFO*)&ver) == 0)
{
ServerManager::m_sOS = "Windows (unknown version)";
return;
}
if (ver.dwMajorVersion == 10)
{
if (ver.dwMinorVersion == 0)
{
if(ver.dwBuildNumber >= 22000)
{
ServerManager::m_sOS = "Windows 11 (Build " + std::to_string((uint32_t)ver.dwBuildNumber) + ")";
}
else
{
ServerManager::m_sOS = "Windows 10 (Build " + std::to_string((uint32_t)ver.dwBuildNumber) + ")";
}
return;
}
}
else if (ver.dwMajorVersion == 6)
{
if (ver.dwMinorVersion == 3)
{
ServerManager::m_sOS = "Windows 8.1";
return;
}
else if (ver.dwMinorVersion == 2)
{
ServerManager::m_sOS = "Windows 8";
return;
}
else if (ver.dwMinorVersion == 1)
{
if (ver.wProductType == VER_NT_WORKSTATION)
{
ServerManager::m_sOS = "Windows 7";
return;
}
else
{
ServerManager::m_sOS = "Windows 2008 R2";
return;
}
}
else
{
if (ver.wProductType == VER_NT_WORKSTATION)
{
ServerManager::m_sOS = "Windows Vista";
return;
}
else
{
ServerManager::m_sOS = "Windows 2008";
return;
}
}
}
else if (ver.dwMajorVersion == 5)
{
if (ver.dwMinorVersion == 2)
{
if (ver.wProductType != VER_NT_WORKSTATION)
{
ServerManager::m_sOS = "Windows 2003";
return;
}
else
{
SYSTEM_INFO si;
memset(&si, 0, sizeof(SYSTEM_INFO));
::GetNativeSystemInfo(&si);
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
{
ServerManager::m_sOS = "Windows XP x64";
return;
}
}
// should not happen, but for sure...
ServerManager::m_sOS = "Windows 2003/XP64";
return;
}
else if (ver.dwMinorVersion == 1)
{
ServerManager::m_sOS = "Windows XP";
return;
}
}
ServerManager::m_sOS = "Windows (unknown version)";
}
//---------------------------------------------------------------------------
void * LuaAlocator(void * /*pOld*/, void * pData, const size_t /*szOldSize*/, const size_t szNewSize)
{
if (szNewSize == 0)
{
if (pData)
{
free(pData);
}
return NULL;
}
else
{
if (pData)
{
return realloc(pData, szNewSize);
}
else
{
return malloc(szNewSize);
}
}
}
#endif
//---------------------------------------------------------------------------
#if defined(_WIN32) && !defined(_WIN64) && !defined(_WIN_IOT)
typedef INT (WSAAPI * pInetPton)(INT, PCTSTR, PVOID);
pInetPton MyInetPton = NULL;
typedef PCTSTR(WSAAPI *pInetNtop)(INT, PVOID, PTSTR, size_t);
pInetNtop MyInetNtop = NULL;
#endif
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void CheckForIPv4()
{
#ifdef _WIN32
SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == INVALID_SOCKET)
{
int iError = WSAGetLastError();
if (iError == WSAEAFNOSUPPORT)
{
#else
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == -1)
{
if (errno == EAFNOSUPPORT)
{
#endif
ServerManager::m_bUseIPv4 = false;
return;
}
}
safe_closesocket(sock);
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void CheckForIPv6()
{
#ifdef _WIN32
SOCKET sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (sock == INVALID_SOCKET)
{
int iError = WSAGetLastError();
if (iError == WSAEAFNOSUPPORT)
{
#else
int sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (sock == -1)
{
if (errno == EAFNOSUPPORT)
{
#endif
ServerManager::m_bUseIPv6 = false;
return;
}
}
#ifdef _WIN32
DWORD dwIPv6 = 0;
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&dwIPv6, sizeof(dwIPv6)) != SOCKET_ERROR)
{
#else
int iIPv6 = 0;
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &iIPv6, sizeof(iIPv6)) != -1)
{
#endif
ServerManager::m_bIPv6DualStack = true;
}
safe_closesocket(sock);
#if defined(_WIN32) && !defined(_WIN64) && !defined(_WIN_IOT)
HINSTANCE hWs2_32 = ::LoadLibrary("Ws2_32.dll");
MyInetPton = (pInetPton)::GetProcAddress(hWs2_32, "inet_pton");
MyInetNtop = (pInetNtop)::GetProcAddress(hWs2_32, "inet_ntop");
::FreeLibrary(hWs2_32);
#endif
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#if defined(_WIN32) && !defined(_WIN64) && !defined(_WIN_IOT)
INT win_inet_pton(PCTSTR pAddrString, PVOID pAddrBuf)
{
if (MyInetPton != NULL)
{
return MyInetPton(AF_INET6, pAddrString, pAddrBuf);
}
else
{
sockaddr_storage sas_addr;
socklen_t sas_len = sizeof(sockaddr_storage);
memset(&sas_addr, 0, sas_len);
if (::WSAStringToAddressA((LPSTR)pAddrString, AF_INET6, NULL, (struct sockaddr *)&sas_addr, &sas_len) == 0)
{
memcpy(pAddrBuf, &((struct sockaddr_in6 *)&sas_addr)->sin6_addr.s6_addr, 16);
return 1;
}
else
{
return 0;
}
}
}
//---------------------------------------------------------------------------
void win_inet_ntop(PVOID pAddr, PTSTR pStringBuf, size_t szStringBufSize)
{
if (MyInetNtop != NULL)
{
MyInetNtop(AF_INET6, pAddr, pStringBuf, szStringBufSize);
}
else
{
struct sockaddr_in6 sin6;
socklen_t sin6_len = sizeof(sockaddr_in6);
memset(&sin6, 0, sin6_len);
sin6.sin6_family = AF_INET6;
memcpy(&sin6.sin6_addr, pAddr, 16);
::WSAAddressToStringA((struct sockaddr *)&sin6, sin6_len, NULL, pStringBuf, (LPDWORD)&szStringBufSize);
}
}
//---------------------------------------------------------------------------
#endif
bool GetMacAddress(const char * sIP, char * sMac)
{
#ifdef FLYLINKDC_USE_MAC
#ifdef _WIN32
uint32_t uiIP = ::inet_addr(sIP);
MIB_IPNETTABLE * pINT = (MIB_IPNETTABLE *)new (std::nothrow) char[PTOKAX_GLOBAL_BUFF_SIZE]; // TODO
if (pINT == NULL)
{
return false;
}
ULONG ulSize = PTOKAX_GLOBAL_BUFF_SIZE;
DWORD dwRes = ::GetIpNetTable(pINT, &ulSize, TRUE);
if (dwRes == NO_ERROR)
{
for (DWORD dwi = 0; dwi < pINT->dwNumEntries; dwi++)
{
if (pINT->table[dwi].dwAddr == uiIP && pINT->table[dwi].dwType != MIB_IPNET_TYPE_INVALID)
{
snprintf(sMac, 18, "%02x:%02x:%02x:%02x:%02x:%02x", pINT->table[dwi].bPhysAddr[0], pINT->table[dwi].bPhysAddr[1], pINT->table[dwi].bPhysAddr[2],
pINT->table[dwi].bPhysAddr[3], pINT->table[dwi].bPhysAddr[4], pINT->table[dwi].bPhysAddr[5]);
delete []pINT;
return true;
}
}
}
delete []pINT;
#else
FILE *fp = fopen("/proc/net/arp", "r");
if (fp != NULL)
{
bool bLastCharSpace = true;
uint8_t ui8NonSpaces = 0;
uint16_t ui16IpLen = (uint16_t)strlen(sIP);
char buf[1024];
while (fgets(buf, 1024, fp) != NULL)
{
if (strncmp(buf, sIP, ui16IpLen) == 0 && buf[ui16IpLen] == ' ')
{
bLastCharSpace = true;
ui8NonSpaces = 0;
while (buf[ui16IpLen] != '\0')
{
if (buf[ui16IpLen] == ' ')
{
bLastCharSpace = true;
}
else
{
if (bLastCharSpace == true)
{
bLastCharSpace = false;
ui8NonSpaces++;
}
}
if (ui8NonSpaces == 3)
{
strncpy(sMac, buf + ui16IpLen, 17);
sMac[17] = '\0';
fclose(fp);
return true;
}
ui16IpLen++;
}
}
}
fclose(fp);
}
#endif
#else
(void)sIP;
(void)sMac;
#endif // FLYLINKDC_USE_MAC
return false;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void CreateGlobalBuffer()
{
ServerManager::m_szGlobalBufferSize = PTOKAX_GLOBAL_BUFF_SIZE;
ServerManager::m_pGlobalBuffer = (char *)calloc(ServerManager::m_szGlobalBufferSize, 1);
if (ServerManager::m_pGlobalBuffer == NULL)
{
AppendDebugLog("%s - [MEM] Cannot create ServerManager::m_pGlobalBuffer\n");
exit(EXIT_FAILURE);
}
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void DeleteGlobalBuffer()
{
safe_free(ServerManager::m_pGlobalBuffer);
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
bool CheckAndResizeGlobalBuffer(const size_t szWantedSize)
{
if (ServerManager::m_szGlobalBufferSize >= szWantedSize)
{
return true;
}
size_t szOldSize = ServerManager::m_szGlobalBufferSize;
char * sOldBuf = ServerManager::m_pGlobalBuffer;
ServerManager::m_szGlobalBufferSize = Allign(szWantedSize);
ServerManager::m_pGlobalBuffer = (char *)realloc(sOldBuf, ServerManager::m_szGlobalBufferSize);
if (ServerManager::m_pGlobalBuffer == NULL)
{
ServerManager::m_pGlobalBuffer = sOldBuf;
AppendDebugLogFormat("[MEM] Cannot reallocate %zu bytes in CheckAndResizeGlobalBuffer for ServerManager::m_pGlobalBuffer\n", ServerManager::m_szGlobalBufferSize);
ServerManager::m_szGlobalBufferSize = szOldSize;
return false;
}
return true;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void ReduceGlobalBuffer()
{
if (ServerManager::m_szGlobalBufferSize == PTOKAX_GLOBAL_BUFF_SIZE)
{
return;
}
size_t szOldSize = ServerManager::m_szGlobalBufferSize;
char * sOldBuf = ServerManager::m_pGlobalBuffer;
ServerManager::m_szGlobalBufferSize = PTOKAX_GLOBAL_BUFF_SIZE;
ServerManager::m_pGlobalBuffer = (char *)realloc(sOldBuf, ServerManager::m_szGlobalBufferSize);
if (ServerManager::m_pGlobalBuffer == NULL)
{
ServerManager::m_pGlobalBuffer = sOldBuf;
AppendDebugLogFormat("[MEM] Cannot reallocate %zu bytes in ReduceGlobalBuffer for ServerManager::m_pGlobalBuffer\n", ServerManager::m_szGlobalBufferSize);
ServerManager::m_szGlobalBufferSize = szOldSize;
return;
}
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
bool HashPassword(const char * sPassword, const size_t szPassLen, uint8_t * ui8PassHash)
{
#ifndef _WITHOUT_SKEIN
Skein1024_Ctxt_t ctx1024;
if (Skein1024_Init(&ctx1024, 512) == SKEIN_SUCCESS)
{
if (Skein1024_Update(&ctx1024, (const u08b_t *)sPassword, szPassLen) == SKEIN_SUCCESS)
{
if (Skein1024_Final(&ctx1024, ui8PassHash) == SKEIN_SUCCESS)
{
return true;
}
}
}
#endif
return false;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#ifdef _WIN32
static const uint16_t ui16Num = 42; // Answer to the Ultimate Question
static const uint8_t ui8Num = 42; // of Life, The Universe, and Everything
uint64_t htobe64(const uint64_t & ui64Value)
{
if (*(uint8_t *)&ui16Num == ui8Num) // LE
{
return _byteswap_uint64(ui64Value);
}
else // BE
{
return ui64Value;
}
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
uint64_t be64toh(const uint64_t & ui64Value)
{
if (*(uint8_t *)&ui16Num == ui8Num) // LE
{
return _byteswap_uint64(ui64Value);
}
else // BE
{
return ui64Value;
}
}
#endif
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
bool WantAgain()
{
printf("Do you want to try it again (Y/n) ? ");
int iChar = getchar();
while (getchar() != '\n')
{
// boredom...
};
if (toupper(iChar) == 'Y')
{
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
bool IsPrivateIP(const char * sIP)
{
if (ServerManager::m_bUseIPv6 == true && strchr(sIP, '.') == NULL)
{
Hash128 ui128IpHash;
#if defined(_WIN32) && !defined(_WIN64) && !defined(_WIN_IOT)
if (win_inet_pton(sIP, ui128IpHash) != 1)
{
#else
if (inet_pton(AF_INET6, sIP, ui128IpHash) != 1)
{
#endif
return false;
}
if (IN6_IS_ADDR_LOOPBACK((in6_addr *)ui128IpHash.data()) || IN6_IS_ADDR_LINKLOCAL((in6_addr *)ui128IpHash.data()) || IN6_IS_ADDR_SITELOCAL((in6_addr *)ui128IpHash.data()))
{
return true;
}
}
else
{
uint32_t ui32IpHash = inet_addr(sIP);
if (ui32IpHash == INADDR_NONE)
{
return false;
}
uint8_t ui32IP[4];
memcpy(ui32IP, &ui32IpHash, 4);
if (ui32IP[0] == 10 || ui32IP[0] == 127 || (ui32IP[0] == 169 && ui32IP[1] == 254) || (ui32IP[0] == 172 && ui32IP[1] == 16) || (ui32IP[0] == 192 && ui32IP[1] == 168))
{
return true;
}
}
return false;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
↑ V1042 This file is marked with copyleft license, which requires you to open the derived source code.