mirror of https://github.com/nostar/urfd.git
parent
9465842bf3
commit
1ed0ab2971
@ -1,14 +1,17 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# URFD interlink file
|
# URFD interlink file
|
||||||
#
|
#
|
||||||
# one line per entry
|
# One line per entry.
|
||||||
# each entry specifies a remote XLX or XRF to peer with
|
# Each entry specifies a remote URF to peer with.
|
||||||
|
# If no Port is specified, 17000 will be used.
|
||||||
|
# If DHT is enabled and the target is also DHT-enabled, then you only
|
||||||
|
# need to specify the URF-Callsign and the Shared-Modules
|
||||||
# format:
|
# format:
|
||||||
# <URF callsign> <ip> <list of modules shared>
|
# <URF-Callsign> <IP-Address> <Shared-Mdoules> <Port>
|
||||||
# example:
|
# examples:
|
||||||
# URF270 158.64.26.132 ACD
|
# URF270 158.64.26.132 EF
|
||||||
#
|
# URF280 ABC
|
||||||
# note: the remote URFD must list this in its interlink file
|
|
||||||
# for the link to be established
|
|
||||||
#
|
#
|
||||||
|
# note: The remote URFD must list this in its interlink file
|
||||||
|
# for the link to be established.
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|||||||
@ -0,0 +1,193 @@
|
|||||||
|
//
|
||||||
|
// ccallsignlist.cpp
|
||||||
|
// m17ref
|
||||||
|
//
|
||||||
|
// Created by Jean-Luc Deltombe (LX3JL) on 30/12/2015.
|
||||||
|
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||||
|
// Copyright © 2020 Thomas A. Early, N7TAE
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// This file is part of m17ref.
|
||||||
|
//
|
||||||
|
// m17ref is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// m17ref 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
|
||||||
|
// with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include "BlackWhiteSet.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// file io
|
||||||
|
|
||||||
|
bool CBlackWhiteSet::LoadFromFile(const std::string &filename)
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
char sz[256];
|
||||||
|
|
||||||
|
// and load
|
||||||
|
std::ifstream file(filename);
|
||||||
|
if ( file.is_open() )
|
||||||
|
{
|
||||||
|
Lock();
|
||||||
|
|
||||||
|
// empty list
|
||||||
|
m_Callsigns.clear();
|
||||||
|
// fill with file content
|
||||||
|
while ( file.getline(sz, sizeof(sz)).good() )
|
||||||
|
{
|
||||||
|
// remove leading & trailing spaces
|
||||||
|
char *szt = TrimWhiteSpaces(sz);
|
||||||
|
|
||||||
|
// crack it
|
||||||
|
if ( (strlen(szt) > 0) && (szt[0] != '#') )
|
||||||
|
{
|
||||||
|
// 1st token is callsign
|
||||||
|
if ( (szt = strtok(szt, " ,\t")) != nullptr )
|
||||||
|
{
|
||||||
|
std::string cs(ToUpper(szt));
|
||||||
|
if (m_Callsigns.end() == m_Callsigns.find(cs))
|
||||||
|
{
|
||||||
|
m_Callsigns.insert(cs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "Duplicate ," << cs << " in " << filename << " will be ignored." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// close file
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
// keep file path
|
||||||
|
m_Filename = filename;
|
||||||
|
|
||||||
|
// update time
|
||||||
|
GetLastModTime(&m_LastModTime);
|
||||||
|
|
||||||
|
// and done
|
||||||
|
Unlock();
|
||||||
|
ok = true;
|
||||||
|
std::cout << "Gatekeeper loaded " << m_Callsigns.size() << " lines from " << filename << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Gatekeeper cannot find " << filename << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBlackWhiteSet::ReloadFromFile(void)
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
|
||||||
|
if ( m_Filename.empty() )
|
||||||
|
{
|
||||||
|
ok = LoadFromFile(m_Filename);
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBlackWhiteSet::NeedReload(void)
|
||||||
|
{
|
||||||
|
bool needReload = false;
|
||||||
|
|
||||||
|
time_t time;
|
||||||
|
if ( GetLastModTime(&time) )
|
||||||
|
{
|
||||||
|
needReload = time != m_LastModTime;
|
||||||
|
}
|
||||||
|
return needReload;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// compare
|
||||||
|
|
||||||
|
bool CBlackWhiteSet::IsMatched(const std::string &cs) const
|
||||||
|
{
|
||||||
|
for ( const auto &item : m_Callsigns )
|
||||||
|
{
|
||||||
|
auto pos = item.find('*');
|
||||||
|
switch (pos)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return true;
|
||||||
|
case std::string::npos:
|
||||||
|
if (0 == item.compare(cs))
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (0 == item.compare(0, pos, cs, 0, pos))
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// helpers
|
||||||
|
|
||||||
|
char *CBlackWhiteSet::TrimWhiteSpaces(char *str)
|
||||||
|
{
|
||||||
|
char *end;
|
||||||
|
|
||||||
|
// Trim leading space & tabs
|
||||||
|
while((*str == ' ') || (*str == '\t')) str++;
|
||||||
|
|
||||||
|
// All spaces?
|
||||||
|
if(*str == 0)
|
||||||
|
return str;
|
||||||
|
|
||||||
|
// Trim trailing space, tab or lf
|
||||||
|
end = str + ::strlen(str) - 1;
|
||||||
|
while((end > str) && ((*end == ' ') || (*end == '\t') || (*end == '\r'))) end--;
|
||||||
|
|
||||||
|
// Write new null terminator
|
||||||
|
*(end+1) = 0;
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBlackWhiteSet::GetLastModTime(time_t *time)
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
|
||||||
|
if ( !m_Filename.empty() )
|
||||||
|
{
|
||||||
|
struct stat fileStat;
|
||||||
|
if( ::stat(m_Filename.c_str(), &fileStat) != -1 )
|
||||||
|
{
|
||||||
|
*time = fileStat.st_mtime;
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *CBlackWhiteSet::ToUpper(char *str)
|
||||||
|
{
|
||||||
|
constexpr auto diff = 'a' - 'A';
|
||||||
|
for (char *p=str; *p; p++)
|
||||||
|
{
|
||||||
|
if (*p >= 'a' && *p <= 'z')
|
||||||
|
*p -= diff;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
//
|
||||||
|
// Copyright © 2020 Thomas A. Early, N7TAE
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// This file is part of m17ref.
|
||||||
|
//
|
||||||
|
// m17ref is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// m17ref 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
|
||||||
|
// with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class
|
||||||
|
|
||||||
|
class CBlackWhiteSet
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
CBlackWhiteSet() : m_Filename(nullptr), m_LastModTime(0) {}
|
||||||
|
|
||||||
|
// locks
|
||||||
|
void Lock(void) const { m_Mutex.lock(); }
|
||||||
|
void Unlock(void) const { m_Mutex.unlock(); }
|
||||||
|
|
||||||
|
// file io
|
||||||
|
bool LoadFromFile(const std::string &filename);
|
||||||
|
bool ReloadFromFile(void);
|
||||||
|
bool NeedReload(void);
|
||||||
|
|
||||||
|
// pass-thru
|
||||||
|
bool empty() const { return m_Callsigns.empty(); }
|
||||||
|
|
||||||
|
// compare
|
||||||
|
bool IsMatched(const std::string &) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool GetLastModTime(time_t *);
|
||||||
|
char *TrimWhiteSpaces(char *);
|
||||||
|
char *ToUpper(char *str);
|
||||||
|
|
||||||
|
// data
|
||||||
|
mutable std::mutex m_Mutex;
|
||||||
|
std::string m_Filename;
|
||||||
|
time_t m_LastModTime;
|
||||||
|
std::set<std::string> m_Callsigns;
|
||||||
|
};
|
||||||
@ -1,223 +0,0 @@
|
|||||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
|
||||||
|
|
||||||
// urfd -- The universal reflector
|
|
||||||
// Copyright © 2021 Thomas A. Early N7TAE
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <string.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include "CallsignList.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// constructor
|
|
||||||
|
|
||||||
CCallsignList::CCallsignList()
|
|
||||||
{
|
|
||||||
memset(&m_LastModTime, 0, sizeof(time_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// file io
|
|
||||||
|
|
||||||
bool CCallsignList::LoadFromFile(const std::string &filename)
|
|
||||||
{
|
|
||||||
bool ok = false;
|
|
||||||
char sz[256];
|
|
||||||
char szStar[2] = "*";
|
|
||||||
|
|
||||||
// and load
|
|
||||||
std::ifstream file (filename);
|
|
||||||
if ( file.is_open() )
|
|
||||||
{
|
|
||||||
Lock();
|
|
||||||
|
|
||||||
// empty list
|
|
||||||
m_Callsigns.clear();
|
|
||||||
// fill with file content
|
|
||||||
while ( file.getline(sz, sizeof(sz)).good() )
|
|
||||||
{
|
|
||||||
// remove leading & trailing spaces
|
|
||||||
char *szt = TrimWhiteSpaces(sz);
|
|
||||||
|
|
||||||
// crack it
|
|
||||||
if ( (::strlen(szt) > 0) && (szt[0] != '#') )
|
|
||||||
{
|
|
||||||
// 1st token is callsign
|
|
||||||
if ( (szt = ::strtok(szt, " ,\t")) != nullptr )
|
|
||||||
{
|
|
||||||
CCallsign callsign(szt);
|
|
||||||
// 2nd token is modules list
|
|
||||||
szt = ::strtok(nullptr, " ,\t");
|
|
||||||
// if token absent, use wildcard
|
|
||||||
if ( szt == nullptr )
|
|
||||||
{
|
|
||||||
szt = szStar;
|
|
||||||
}
|
|
||||||
// and add to list
|
|
||||||
m_Callsigns.push_back(CCallsignListItem(callsign, CIp(), szt));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// close file
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
// keep file path
|
|
||||||
m_Filename.assign(filename);
|
|
||||||
|
|
||||||
// update time
|
|
||||||
GetLastModTime(&m_LastModTime);
|
|
||||||
|
|
||||||
// and done
|
|
||||||
Unlock();
|
|
||||||
ok = true;
|
|
||||||
std::cout << "Gatekeeper loaded " << m_Callsigns.size() << " lines from " << filename << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "Gatekeeper cannot find " << filename << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCallsignList::ReloadFromFile(void)
|
|
||||||
{
|
|
||||||
bool ok = false;
|
|
||||||
|
|
||||||
if (! m_Filename.empty())
|
|
||||||
{
|
|
||||||
ok = LoadFromFile(m_Filename);
|
|
||||||
}
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCallsignList::NeedReload(void)
|
|
||||||
{
|
|
||||||
bool needReload = false;
|
|
||||||
|
|
||||||
time_t time;
|
|
||||||
if ( GetLastModTime(&time) )
|
|
||||||
{
|
|
||||||
needReload = time != m_LastModTime;
|
|
||||||
}
|
|
||||||
return needReload;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// compare
|
|
||||||
|
|
||||||
bool CCallsignList::IsCallsignListedWithWildcard(const CCallsign &callsign) const
|
|
||||||
{
|
|
||||||
for ( const auto &item : m_Callsigns )
|
|
||||||
{
|
|
||||||
if (item.HasSameCallsignWithWildcard(callsign))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCallsignList::IsCallsignListedWithWildcard(const CCallsign &callsign, char module) const
|
|
||||||
{
|
|
||||||
for ( const auto &item : m_Callsigns )
|
|
||||||
{
|
|
||||||
if (item.HasSameCallsignWithWildcard(callsign) && ((module == ' ') || item.HasModuleListed(module)) )
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCallsignList::IsCallsignListed(const CCallsign &callsign, char module) const
|
|
||||||
{
|
|
||||||
for ( const auto &item : m_Callsigns )
|
|
||||||
{
|
|
||||||
if (item.HasSameCallsign(callsign) && item.HasModuleListed(module))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCallsignList::IsCallsignListed(const CCallsign &callsign, char *modules) const
|
|
||||||
{
|
|
||||||
for ( const auto &item : m_Callsigns )
|
|
||||||
{
|
|
||||||
if (item.HasSameCallsign(callsign) && item.CheckListedModules(modules))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// find
|
|
||||||
|
|
||||||
CCallsignListItem *CCallsignList::FindListItem(const CCallsign &Callsign)
|
|
||||||
{
|
|
||||||
for ( auto &item : m_Callsigns )
|
|
||||||
{
|
|
||||||
if ( item.GetCallsign().HasSameCallsign(Callsign) )
|
|
||||||
{
|
|
||||||
return &item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// helpers
|
|
||||||
|
|
||||||
char *CCallsignList::TrimWhiteSpaces(char *str)
|
|
||||||
{
|
|
||||||
char *end;
|
|
||||||
|
|
||||||
// Trim leading space & tabs
|
|
||||||
while((*str == ' ') || (*str == '\t')) str++;
|
|
||||||
|
|
||||||
// All spaces?
|
|
||||||
if(*str == 0)
|
|
||||||
return str;
|
|
||||||
|
|
||||||
// Trim trailing space, tab or lf
|
|
||||||
end = str + ::strlen(str) - 1;
|
|
||||||
while((end > str) && ((*end == ' ') || (*end == '\t') || (*end == '\r'))) end--;
|
|
||||||
|
|
||||||
// Write new null terminator
|
|
||||||
*(end+1) = 0;
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCallsignList::GetLastModTime(time_t *time)
|
|
||||||
{
|
|
||||||
bool ok = false;
|
|
||||||
|
|
||||||
if (! m_Filename.empty())
|
|
||||||
{
|
|
||||||
struct stat fileStat;
|
|
||||||
if( ::stat(m_Filename.c_str(), &fileStat) != -1 )
|
|
||||||
{
|
|
||||||
*time = fileStat.st_mtime;
|
|
||||||
ok = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
|
||||||
|
|
||||||
// urfd -- The universal reflector
|
|
||||||
// Copyright © 2021 Thomas A. Early N7TAE
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <list>
|
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
#include "CallsignListItem.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// class
|
|
||||||
|
|
||||||
class CCallsignList
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// constructor
|
|
||||||
CCallsignList();
|
|
||||||
|
|
||||||
// locks
|
|
||||||
void Lock(void) const { m_Mutex.lock(); }
|
|
||||||
void Unlock(void) const { m_Mutex.unlock(); }
|
|
||||||
|
|
||||||
// file io
|
|
||||||
virtual bool LoadFromFile(const std::string &str);
|
|
||||||
bool ReloadFromFile(void);
|
|
||||||
bool NeedReload(void);
|
|
||||||
|
|
||||||
// compare
|
|
||||||
bool IsCallsignListedWithWildcard(const CCallsign &) const;
|
|
||||||
bool IsCallsignListedWithWildcard(const CCallsign &, char) const;
|
|
||||||
bool IsCallsignListed(const CCallsign &, char) const;
|
|
||||||
bool IsCallsignListed(const CCallsign &, char*) const;
|
|
||||||
|
|
||||||
// pass-thru
|
|
||||||
bool empty() const { return m_Callsigns.empty(); }
|
|
||||||
std::list<CCallsignListItem>::iterator begin() { return m_Callsigns.begin(); }
|
|
||||||
std::list<CCallsignListItem>::iterator end() { return m_Callsigns.end(); }
|
|
||||||
|
|
||||||
// find
|
|
||||||
CCallsignListItem *FindListItem(const CCallsign &);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool GetLastModTime(time_t *);
|
|
||||||
char *TrimWhiteSpaces(char *);
|
|
||||||
|
|
||||||
// data
|
|
||||||
mutable std::mutex m_Mutex;
|
|
||||||
std::string m_Filename;
|
|
||||||
time_t m_LastModTime;
|
|
||||||
std::list<CCallsignListItem> m_Callsigns;
|
|
||||||
};
|
|
||||||
@ -1,136 +0,0 @@
|
|||||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
|
||||||
|
|
||||||
// urfd -- The universal reflector
|
|
||||||
// Copyright © 2021 Thomas A. Early N7TAE
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "Global.h"
|
|
||||||
|
|
||||||
#include "CallsignListItem.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// constructor
|
|
||||||
|
|
||||||
CCallsignListItem::CCallsignListItem()
|
|
||||||
{
|
|
||||||
memset(m_Modules, 0, sizeof(m_Modules));
|
|
||||||
memset(m_szUrl, 0, sizeof(m_szUrl));
|
|
||||||
}
|
|
||||||
|
|
||||||
CCallsignListItem::CCallsignListItem(const CCallsign &callsign, const CIp &ip, const char *modules)
|
|
||||||
{
|
|
||||||
const std::string mods(g_Configure.GetString(g_Keys.modules.modules));
|
|
||||||
m_Callsign = callsign;
|
|
||||||
memset(m_szUrl, 0, sizeof(m_szUrl));
|
|
||||||
m_Ip = ip;
|
|
||||||
if ( modules != nullptr )
|
|
||||||
{
|
|
||||||
memset(m_Modules, 0, sizeof(m_Modules));
|
|
||||||
if ( modules[0] == '*' )
|
|
||||||
{
|
|
||||||
memcpy(m_Modules, mods.c_str(), mods.size());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int n = MIN(::strlen(modules), sizeof(m_Modules)-1);
|
|
||||||
for (int i=0, j=0; i<n; i++)
|
|
||||||
{
|
|
||||||
if (std::string::npos != mods.find(modules[i]))
|
|
||||||
{
|
|
||||||
m_Modules[j++] = modules[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CCallsignListItem::CCallsignListItem(const CCallsign &callsign, const char *url, const char *modules)
|
|
||||||
{
|
|
||||||
const std::string mods(g_Configure.GetString(g_Keys.modules.modules));
|
|
||||||
m_Callsign = callsign;
|
|
||||||
::strncpy(m_szUrl, url, URL_MAXLEN);
|
|
||||||
m_Ip = CIp(m_szUrl);
|
|
||||||
if ( modules != nullptr )
|
|
||||||
{
|
|
||||||
memset(m_Modules, 0, sizeof(m_Modules));
|
|
||||||
if ( modules[0] == '*' )
|
|
||||||
{
|
|
||||||
memcpy(m_Modules, mods.c_str(), mods.size());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int n = MIN(::strlen(modules), sizeof(m_Modules)-1);
|
|
||||||
for (int i=0, j=0; i<n; i++)
|
|
||||||
{
|
|
||||||
if (std::string::npos != mods.find(modules[i]))
|
|
||||||
{
|
|
||||||
m_Modules[j++] = modules[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CCallsignListItem::CCallsignListItem(const CCallsignListItem &item)
|
|
||||||
{
|
|
||||||
m_Callsign = item.m_Callsign;
|
|
||||||
memcpy(m_szUrl, item.m_szUrl, sizeof(m_szUrl));
|
|
||||||
m_Ip = item.m_Ip;
|
|
||||||
memcpy(m_Modules, item.m_Modules, sizeof(m_Modules));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// compare
|
|
||||||
|
|
||||||
bool CCallsignListItem::HasSameCallsign(const CCallsign &callsign) const
|
|
||||||
{
|
|
||||||
return m_Callsign.HasSameCallsign(callsign);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCallsignListItem::HasSameCallsignWithWildcard(const CCallsign &callsign) const
|
|
||||||
{
|
|
||||||
return m_Callsign.HasSameCallsignWithWildcard(callsign);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCallsignListItem::HasModuleListed(char module) const
|
|
||||||
{
|
|
||||||
return (::strchr(m_Modules, (int)module) != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCallsignListItem::CheckListedModules(char *Modules) const
|
|
||||||
{
|
|
||||||
bool listed = false;
|
|
||||||
|
|
||||||
if ( Modules != nullptr )
|
|
||||||
{
|
|
||||||
// build a list of common modules
|
|
||||||
char list[27];
|
|
||||||
list[0] = 0;
|
|
||||||
//
|
|
||||||
for ( unsigned i = 0; i < ::strlen(Modules); i++ )
|
|
||||||
{
|
|
||||||
if ( HasModuleListed(Modules[i]) )
|
|
||||||
{
|
|
||||||
::strncat(list, &(Modules[i]), 1);
|
|
||||||
listed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
::strcpy(Modules, list);
|
|
||||||
}
|
|
||||||
return listed;
|
|
||||||
}
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
|
||||||
|
|
||||||
// urfd -- The universal reflector
|
|
||||||
// Copyright © 2021 Thomas A. Early N7TAE
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
|
|
||||||
#include "Callsign.h"
|
|
||||||
#include "IP.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// define
|
|
||||||
|
|
||||||
#define URL_MAXLEN 256
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// class
|
|
||||||
|
|
||||||
class CCallsignListItem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// constructor
|
|
||||||
CCallsignListItem();
|
|
||||||
CCallsignListItem(const CCallsign &, const CIp &, const char *);
|
|
||||||
CCallsignListItem(const CCallsign &, const char *, const char *);
|
|
||||||
CCallsignListItem(const CCallsignListItem &);
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
virtual ~CCallsignListItem() {}
|
|
||||||
|
|
||||||
// compare
|
|
||||||
bool HasSameCallsign(const CCallsign &) const;
|
|
||||||
bool HasSameCallsignWithWildcard(const CCallsign &) const;
|
|
||||||
bool HasModuleListed(char) const;
|
|
||||||
bool CheckListedModules(char*) const;
|
|
||||||
|
|
||||||
// get
|
|
||||||
const CCallsign &GetCallsign(void) const { return m_Callsign; }
|
|
||||||
const CIp &GetIp(void) const { return m_Ip; }
|
|
||||||
const char *GetModules(void) { return m_Modules; }
|
|
||||||
|
|
||||||
// update
|
|
||||||
void ResolveIp(void) { m_Ip = CIp(m_szUrl); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// data
|
|
||||||
CCallsign m_Callsign;
|
|
||||||
char m_szUrl[URL_MAXLEN+1];
|
|
||||||
CIp m_Ip;
|
|
||||||
char m_Modules[27];
|
|
||||||
};
|
|
||||||
@ -0,0 +1,258 @@
|
|||||||
|
//
|
||||||
|
// ccallsignlist.cpp
|
||||||
|
// m17ref
|
||||||
|
//
|
||||||
|
// Created by Jean-Luc Deltombe (LX3JL) on 30/12/2015.
|
||||||
|
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||||
|
// Copyright © 2020,2022 Thomas A. Early, N7TAE
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// This file is part of m17ref.
|
||||||
|
//
|
||||||
|
// m17ref is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// m17ref 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
|
||||||
|
// with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include "Global.h"
|
||||||
|
#include "InterlinkMap.h"
|
||||||
|
|
||||||
|
CInterlinkMap::CInterlinkMap()
|
||||||
|
{
|
||||||
|
m_Filename = nullptr;
|
||||||
|
::memset(&m_LastModTime, 0, sizeof(time_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CInterlinkMap::LoadFromFile(const std::string &filename)
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
char line[256];
|
||||||
|
|
||||||
|
// and load
|
||||||
|
std::ifstream file(filename);
|
||||||
|
if ( file.is_open() )
|
||||||
|
{
|
||||||
|
Lock();
|
||||||
|
|
||||||
|
// empty list
|
||||||
|
m_InterlinkMap.clear();
|
||||||
|
// fill with file content
|
||||||
|
while ( file.getline(line, sizeof(line)).good() )
|
||||||
|
{
|
||||||
|
char *token[4];
|
||||||
|
// remove leading & trailing spaces
|
||||||
|
token[0] = ToUpper(TrimWhiteSpaces(line));
|
||||||
|
// crack it
|
||||||
|
if ( (strlen(token[0]) > 0) && (token[0][0] != '#') )
|
||||||
|
{
|
||||||
|
const char *delim = " \t\r";
|
||||||
|
// 1st token is callsign
|
||||||
|
if ( (token[0] = strtok(token[0], delim)) != nullptr )
|
||||||
|
{
|
||||||
|
if (strcmp(token[0], g_Configure.GetString(g_Keys.names.callsign).c_str()))
|
||||||
|
{
|
||||||
|
if (m_InterlinkMap.end() == m_InterlinkMap.find(token[0]))
|
||||||
|
{
|
||||||
|
CCallsign callsign(token[0]);
|
||||||
|
// read remaining tokens
|
||||||
|
for (int i=1; i<4; i++)
|
||||||
|
{
|
||||||
|
token[i] = strtok(nullptr, delim);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token[2])
|
||||||
|
{
|
||||||
|
int port = 17000;
|
||||||
|
if (token[3])
|
||||||
|
{
|
||||||
|
port = std::atoi(token[2]);
|
||||||
|
if (port < 1024 || port > 49000)
|
||||||
|
{
|
||||||
|
std::cout << token[0] << " Port " << port << " is out of range, resetting to 17000." << std::endl;
|
||||||
|
port = 17000;
|
||||||
|
}
|
||||||
|
m_InterlinkMap[token[0]] = CInterlinkMapItem(token[1], token[3], (uint16_t)port);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_InterlinkMap[token[0]] = CInterlinkMapItem(token[1], token[2], (uint16_t)port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifndef NO_DHT
|
||||||
|
else if (token[1])
|
||||||
|
{
|
||||||
|
m_InterlinkMap[token[0]] = CInterlinkMapItem(token[1]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << token[0] << " has insufficient parameters!" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "Duplicate found: " << token[0] << " in " << filename << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "Self linking is not allowed! You cannot use " << token[0] << " in " << filename << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// close file
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
// keep file path
|
||||||
|
m_Filename = filename;
|
||||||
|
|
||||||
|
// update time
|
||||||
|
GetLastModTime(&m_LastModTime);
|
||||||
|
|
||||||
|
// and done
|
||||||
|
Unlock();
|
||||||
|
ok = true;
|
||||||
|
std::cout << "Gatekeeper loaded " << m_InterlinkMap.size() << " lines from " << filename << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Gatekeeper cannot find " << filename << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CInterlinkMap::ReloadFromFile(void)
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
|
||||||
|
if ( ! m_Filename.empty() )
|
||||||
|
{
|
||||||
|
ok = LoadFromFile(m_Filename);
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CInterlinkMap::NeedReload(void)
|
||||||
|
{
|
||||||
|
bool needReload = false;
|
||||||
|
|
||||||
|
time_t time;
|
||||||
|
if ( GetLastModTime(&time) )
|
||||||
|
{
|
||||||
|
needReload = time != m_LastModTime;
|
||||||
|
}
|
||||||
|
return needReload;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CInterlinkMap::IsCallsignListed(const std::string &callsign, char module) const
|
||||||
|
{
|
||||||
|
const auto item = m_InterlinkMap.find(callsign);
|
||||||
|
if (m_InterlinkMap.cend() == item)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return item->second.HasModuleListed(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CInterlinkMap::IsCallsignListed(const std::string &callsign, const CIp &ip, const char *modules) const
|
||||||
|
{
|
||||||
|
const auto item = m_InterlinkMap.find(callsign);
|
||||||
|
if (m_InterlinkMap.cend() != item)
|
||||||
|
{
|
||||||
|
if ( item->second.CheckListedModules(modules) )
|
||||||
|
{
|
||||||
|
if ( ip == item->second.GetIp() )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CInterlinkMapItem *CInterlinkMap::FindMapItem(const std::string &cs)
|
||||||
|
{
|
||||||
|
auto it = m_InterlinkMap.find(cs);
|
||||||
|
if (m_InterlinkMap.end() == it)
|
||||||
|
return nullptr;
|
||||||
|
return &it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *CInterlinkMap::TrimWhiteSpaces(char *str)
|
||||||
|
{
|
||||||
|
char *end;
|
||||||
|
|
||||||
|
// Trim leading space & tabs
|
||||||
|
while((*str == ' ') || (*str == '\t')) str++;
|
||||||
|
|
||||||
|
// All spaces?
|
||||||
|
if(*str == 0)
|
||||||
|
return str;
|
||||||
|
|
||||||
|
// Trim trailing space, tab or lf
|
||||||
|
end = str + ::strlen(str) - 1;
|
||||||
|
while((end > str) && ((*end == ' ') || (*end == '\t') || (*end == '\r'))) end--;
|
||||||
|
|
||||||
|
// Write new null terminator
|
||||||
|
*(end+1) = 0;
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CInterlinkMap::GetLastModTime(time_t *time)
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
|
||||||
|
if ( ! m_Filename.empty() )
|
||||||
|
{
|
||||||
|
struct stat fileStat;
|
||||||
|
if( ::stat(m_Filename.c_str(), &fileStat) != -1 )
|
||||||
|
{
|
||||||
|
*time = fileStat.st_mtime;
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *CInterlinkMap::ToUpper(char *str)
|
||||||
|
{
|
||||||
|
constexpr auto diff = 'a' - 'A';
|
||||||
|
for (char *p=str; *p; p++)
|
||||||
|
{
|
||||||
|
if (*p >= 'a' && *p <= 'z')
|
||||||
|
*p -= diff;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NO_DHT
|
||||||
|
void CInterlinkMap::Update(const std::string &cs, const std::string &cmods, const std::string &ipv4, const std::string &ipv6, uint16_t port, const std::string &emods)
|
||||||
|
{
|
||||||
|
auto it = m_InterlinkMap.find(cs);
|
||||||
|
if (m_InterlinkMap.end() == it)
|
||||||
|
{
|
||||||
|
std::cerr << "Can't Update CInterlinkMap item '" << cs << "' because it doesn't exist!";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it->second.UpdateItem(cmods, ipv4, ipv6, port, emods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
//
|
||||||
|
// Created by Jean-Luc Deltombe (LX3JL) on 30/12/2015.
|
||||||
|
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||||
|
// Copyright © 2020 Thomas A. Early, N7TAE
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// This file is part of m17ref.
|
||||||
|
//
|
||||||
|
// m17ref is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// m17ref 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
|
||||||
|
// with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "InterlinkMapItem.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class
|
||||||
|
|
||||||
|
class CInterlinkMap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
CInterlinkMap();
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
virtual ~CInterlinkMap() {}
|
||||||
|
|
||||||
|
// locks
|
||||||
|
void Lock(void) const { m_Mutex.lock(); }
|
||||||
|
void Unlock(void) const { m_Mutex.unlock(); }
|
||||||
|
|
||||||
|
// file io
|
||||||
|
virtual bool LoadFromFile(const std::string &filename);
|
||||||
|
bool ReloadFromFile(void);
|
||||||
|
bool NeedReload(void);
|
||||||
|
|
||||||
|
#ifndef NO_DHT
|
||||||
|
void Update(const std::string &cs, const std::string &mods, const std::string &ipv4, const std::string &ipv6, uint16_t port, const std::string &tcmods);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// compare
|
||||||
|
bool IsCallsignListed(const std::string &, const char) const;
|
||||||
|
bool IsCallsignListed(const std::string &, const CIp &ip, const char*) const;
|
||||||
|
|
||||||
|
// pass-thru
|
||||||
|
bool empty() const { return m_InterlinkMap.empty(); }
|
||||||
|
std::map<std::string, CInterlinkMapItem>::iterator begin() { return m_InterlinkMap.begin(); }
|
||||||
|
std::map<std::string, CInterlinkMapItem>::iterator end() { return m_InterlinkMap.end(); }
|
||||||
|
std::map<std::string, CInterlinkMapItem>::const_iterator cbegin() { return m_InterlinkMap.cbegin(); }
|
||||||
|
std::map<std::string, CInterlinkMapItem>::const_iterator cend() { return m_InterlinkMap.cend(); }
|
||||||
|
|
||||||
|
// find
|
||||||
|
CInterlinkMapItem *FindMapItem(const std::string &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool GetLastModTime(time_t *);
|
||||||
|
char *TrimWhiteSpaces(char *);
|
||||||
|
char *ToUpper(char *str);
|
||||||
|
|
||||||
|
// data
|
||||||
|
mutable std::mutex m_Mutex;
|
||||||
|
std::string m_Filename;
|
||||||
|
time_t m_LastModTime;
|
||||||
|
std::map<std::string, CInterlinkMapItem> m_InterlinkMap;
|
||||||
|
};
|
||||||
@ -0,0 +1,143 @@
|
|||||||
|
//
|
||||||
|
// ccallsignlistitem.cpp
|
||||||
|
// m17ref
|
||||||
|
//
|
||||||
|
// Created by Jean-Luc Deltombe (LX3JL) on 31/01/2016.
|
||||||
|
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||||
|
// Copyright © 2020,2022 Thomas A. Early N7TAE
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// This file is part of m17ref.
|
||||||
|
//
|
||||||
|
// m17ref is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// m17ref 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
|
||||||
|
// with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "Configure.h"
|
||||||
|
#include "InterlinkMapItem.h"
|
||||||
|
#include "Reflector.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// constructor
|
||||||
|
#ifdef NO_DHT
|
||||||
|
CInterlinkMapItem::CInterlinkMapItem()
|
||||||
|
{
|
||||||
|
m_UsesDHT = false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
CInterlinkMapItem::CInterlinkMapItem()
|
||||||
|
{
|
||||||
|
m_UsesDHT = false;
|
||||||
|
m_Updated = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NO_DHT
|
||||||
|
CInterlinkMapItem::CInterlinkMapItem(const char *mods)
|
||||||
|
{
|
||||||
|
m_UsesDHT = true;
|
||||||
|
m_Updated = false;
|
||||||
|
m_Mods.assign(mods);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CInterlinkMapItem::CInterlinkMapItem(const char *addr, const char *mods, uint16_t port) : CInterlinkMapItem()
|
||||||
|
{
|
||||||
|
m_Mods.assign(mods);
|
||||||
|
m_Ip.Initialize(strchr(addr, ':') ? AF_INET6 : AF_INET, port, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// compare
|
||||||
|
|
||||||
|
bool CInterlinkMapItem::HasModuleListed(char module) const
|
||||||
|
{
|
||||||
|
return m_Mods.npos != m_Mods.find(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CInterlinkMapItem::HasSameIp(const CIp &ip)
|
||||||
|
{
|
||||||
|
return ip == m_Ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CInterlinkMapItem::CheckListedModules(const char *mods) const
|
||||||
|
{
|
||||||
|
if (mods == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// make sure every mods character is matched in m_Mods
|
||||||
|
const auto count = m_Mods.size();
|
||||||
|
bool found[count];
|
||||||
|
for (unsigned i=0; i<count; i++)
|
||||||
|
found[i] = false;
|
||||||
|
for (auto p=mods; *p; p++)
|
||||||
|
{
|
||||||
|
auto pos = m_Mods.find(*p);
|
||||||
|
if (pos == m_Mods.npos)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
found[pos] = true;
|
||||||
|
}
|
||||||
|
for (unsigned i=0; i<count; i++)
|
||||||
|
{
|
||||||
|
if (! found[i])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NO_DHT
|
||||||
|
void CInterlinkMapItem::UpdateItem(const std::string &cmods, const std::string &ipv4, const std::string &ipv6, uint16_t port, const std::string &tcmods)
|
||||||
|
{
|
||||||
|
if (m_CMods.compare(cmods))
|
||||||
|
{
|
||||||
|
m_CMods.assign(cmods);
|
||||||
|
m_Updated = true;
|
||||||
|
}
|
||||||
|
if (m_IPv4.compare(ipv4))
|
||||||
|
{
|
||||||
|
m_IPv4.assign(ipv4);
|
||||||
|
m_Updated = true;
|
||||||
|
}
|
||||||
|
if (m_IPv6.compare(ipv6))
|
||||||
|
{
|
||||||
|
m_IPv6.assign(ipv6);
|
||||||
|
m_Updated = true;
|
||||||
|
}
|
||||||
|
if (m_Port != port)
|
||||||
|
{
|
||||||
|
m_Port = port;
|
||||||
|
m_Updated = true;
|
||||||
|
}
|
||||||
|
if (m_TCMods.compare(tcmods))
|
||||||
|
{
|
||||||
|
m_TCMods.assign(tcmods);
|
||||||
|
m_Updated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInterlinkMapItem::UpdateIP(bool IPv6NotConfigured)
|
||||||
|
{
|
||||||
|
if (m_Updated)
|
||||||
|
{
|
||||||
|
if (IPv6NotConfigured || m_IPv6.empty())
|
||||||
|
m_Ip.Initialize(AF_INET, m_Port, m_IPv4.c_str());
|
||||||
|
else
|
||||||
|
m_Ip.Initialize(AF_INET6, m_Port, m_IPv6.c_str());
|
||||||
|
|
||||||
|
m_Updated = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
//
|
||||||
|
// Created by Jean-Luc Deltombe (LX3JL) on 31/01/2016.
|
||||||
|
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||||
|
// Copyright © 2020 Thomas A. Early N7TAE
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// This file is part of m17ref.
|
||||||
|
//
|
||||||
|
// m17ref is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// m17ref 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
|
||||||
|
// with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Callsign.h"
|
||||||
|
#include "IP.h"
|
||||||
|
|
||||||
|
class CInterlinkMapItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
CInterlinkMapItem();
|
||||||
|
#ifndef NO_DHT
|
||||||
|
CInterlinkMapItem(const char *mods);
|
||||||
|
#endif
|
||||||
|
CInterlinkMapItem(const char *addr, const char *mods, uint16_t port);
|
||||||
|
|
||||||
|
// Update things
|
||||||
|
void UpdateIP(bool IPv6NotConfigured);
|
||||||
|
#ifndef NO_DHT
|
||||||
|
void UpdateItem(const std::string &cmods, const std::string &ipv4, const std::string &ipv6, uint16_t port, const std::string &tcmods);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// compare
|
||||||
|
bool HasSameIp(const CIp &ip);
|
||||||
|
bool HasModuleListed(char) const;
|
||||||
|
bool CheckListedModules(const char*) const;
|
||||||
|
|
||||||
|
// get
|
||||||
|
const CIp &GetIp(void) const { return m_Ip; }
|
||||||
|
const std::string &GetModules(void) const { return m_Mods; }
|
||||||
|
bool UsesDHT(void) const { return m_UsesDHT; }
|
||||||
|
uint16_t GetPort(void) const { return m_Port; }
|
||||||
|
#ifndef NO_DHT
|
||||||
|
const std::string &GetIPv4(void) const { return m_IPv4; }
|
||||||
|
const std::string &GetIPv6(void) const { return m_IPv6; }
|
||||||
|
const std::string &GetTCMods(void) const { return m_TCMods; }
|
||||||
|
const std::string &GetCMods(void) const { return m_CMods; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
// data
|
||||||
|
CIp m_Ip;
|
||||||
|
std::string m_Mods;
|
||||||
|
uint16_t m_Port;
|
||||||
|
bool m_UsesDHT;
|
||||||
|
|
||||||
|
#ifndef NO_DHT
|
||||||
|
bool m_Updated;
|
||||||
|
std::string m_CMods, m_IPv4, m_IPv6, m_TCMods;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
@ -1,84 +0,0 @@
|
|||||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
|
||||||
|
|
||||||
// urfd -- The universal reflector
|
|
||||||
// Copyright © 2021 Thomas A. Early N7TAE
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "PeerCallsignList.h"
|
|
||||||
|
|
||||||
bool CPeerCallsignList::LoadFromFile(const std::string &filename)
|
|
||||||
{
|
|
||||||
bool ok = false;
|
|
||||||
char sz[256];
|
|
||||||
|
|
||||||
// and load
|
|
||||||
std::ifstream file (filename);
|
|
||||||
if ( file.is_open() )
|
|
||||||
{
|
|
||||||
Lock();
|
|
||||||
|
|
||||||
// empty list
|
|
||||||
m_Callsigns.clear();
|
|
||||||
// fill with file content
|
|
||||||
while ( file.getline(sz, sizeof(sz)).good() )
|
|
||||||
{
|
|
||||||
// remove leading & trailing spaces
|
|
||||||
char *szt = TrimWhiteSpaces(sz);
|
|
||||||
|
|
||||||
// crack it
|
|
||||||
if ( (::strlen(szt) > 0) && (szt[0] != '#') )
|
|
||||||
{
|
|
||||||
// 1st token is callsign
|
|
||||||
if ( (szt = ::strtok(szt, " ,\t")) != nullptr )
|
|
||||||
{
|
|
||||||
CCallsign callsign(szt);
|
|
||||||
// 2nd token is ip
|
|
||||||
char *szip;
|
|
||||||
if ( (szip = ::strtok(nullptr, " ,\t")) != nullptr )
|
|
||||||
{
|
|
||||||
// 3rd token is modules list
|
|
||||||
if ( (szt = ::strtok(nullptr, " ,\t")) != nullptr )
|
|
||||||
{
|
|
||||||
// and load
|
|
||||||
m_Callsigns.push_back(CCallsignListItem(callsign, szip, szt));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// close file
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
// keep file path
|
|
||||||
m_Filename = filename;
|
|
||||||
|
|
||||||
// update time
|
|
||||||
GetLastModTime(&m_LastModTime);
|
|
||||||
|
|
||||||
// and done
|
|
||||||
Unlock();
|
|
||||||
ok = true;
|
|
||||||
std::cout << "Gatekeeper loaded " << m_Callsigns.size() << " lines from " << filename << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "Gatekeeper cannot find " << filename << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
|
||||||
|
|
||||||
// urfd -- The universal reflector
|
|
||||||
// Copyright © 2021 Thomas A. Early N7TAE
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
|
|
||||||
#include "CallsignList.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// class
|
|
||||||
|
|
||||||
class CPeerCallsignList : public CCallsignList
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// constructor
|
|
||||||
CPeerCallsignList() {}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
virtual ~CPeerCallsignList() {}
|
|
||||||
|
|
||||||
// file io
|
|
||||||
bool LoadFromFile(const std::string &filename);
|
|
||||||
};
|
|
||||||
Loading…
Reference in new issue