Update upstream source from tag 'upstream/6.0.24.25'

Update to upstream version '6.0.24.25'
with Debian dir c5f88a7af8
This commit is contained in:
Dave Hibberd 2023-12-28 10:31:16 +00:00
commit ce4f1b11b0
39 changed files with 5557 additions and 387 deletions

View File

@ -38,6 +38,7 @@ extern char LTATString[2048];
//static UCHAR BPQDirectory[260];
extern ConnectionInfo Connections[];
extern int NumberofStreams;
extern time_t MaintClock; // Time to run housekeeping
@ -49,6 +50,7 @@ extern int MaxChatStreams;
extern char Position[81];
extern char PopupText[251];
extern int PopupMode;
extern int reportMailEvents;
#define MaxCMS 10 // Numbr of addresses we can keep - currently 4 are used.
@ -114,6 +116,7 @@ int SendWebMailHeader(char * Reply, char * Key, struct HTTPConnectionInfo * Sess
struct UserInfo * FindBBS(char * Name);
void ReleaseWebMailStruct(WebMailInfo * WebMail);
VOID TidyWelcomeMsg(char ** pPrompt);
int MailAPIProcessHTTPMessage(char * response, char * Method, char * URL, char * request, BOOL LOCAL, char * Param);
char UNC[] = "";
char CHKD[] = "checked=checked ";
@ -489,6 +492,13 @@ void ProcessMailHTTPMessage(struct HTTPConnectionInfo * Session, char * Method,
return;
}
if (_memicmp(URL, "/Mail/API/", 10) == 0)
{
*RLen = MailAPIProcessHTTPMessage(Reply, Method, URL, input, LOCAL, Context);
return;
}
if (strcmp(Method, "POST") == 0)
{
if (_stricmp(NodeURL, "/Mail/Header") == 0)
@ -1633,6 +1643,7 @@ VOID ProcessConfUpdate(struct HTTPConnectionInfo * Session, char * MsgPtr, char
UserCantKillT = !UserCantKillT; // Reverse Logic
GetCheckBox(input, "FWDtoMe=", &ForwardToMe);
GetCheckBox(input, "OnlyKnown=", &OnlyKnown);
GetCheckBox(input, "Events=", &reportMailEvents);
GetParam(input, "POP3Port=", Temp);
POP3InPort = atoi(Temp);
@ -2610,6 +2621,7 @@ VOID SendConfigPage(char * Reply, int * ReplyLen, char * Key)
(UserCantKillT) ? UNC : CHKD, // Reverse logic
(ForwardToMe) ? CHKD : UNC,
(OnlyKnown) ? CHKD : UNC,
(reportMailEvents) ? CHKD : UNC,
POP3InPort, SMTPInPort, NNTPInPort,
(RemoteEmail) ? CHKD : UNC,
AMPRDomain,

View File

@ -43,7 +43,7 @@ RECT ConsoleRect;
BOOL OpenConsole;
BOOL OpenMon;
int reportNewMesageEvents = 0;
int reportMailEvents = 0;
FBBFilter * Filters = NULL;
@ -124,6 +124,8 @@ void decodeblock( unsigned char in[4], unsigned char out[3]);
int encode_quoted_printable(char *s, char * out, int Len);
int32_t Encode(char * in, char * out, int32_t inlen, BOOL B1Protocol, int Compress);
int APIENTRY ChangeSessionCallsign(int Stream, unsigned char * AXCall);
void SendMessageReadEvent(char * user, struct MsgInfo * Msg);
void SendNewMessageEvent(char * call, struct MsgInfo * Msg);
config_t cfg;
config_setting_t * group;
@ -4904,6 +4906,7 @@ sendEOM:
Msg->status = 'Y';
Msg->datechanged=time(NULL);
SaveMessageDatabase();
SendMessageReadEvent(user->Call, Msg);
}
}
}
@ -6457,30 +6460,9 @@ nextline:
// If Event Notifications enabled report a new message event
if (reportNewMesageEvents)
{
char msg[200];
//12345 B 2053 TEST@ALL F6FBB 920325 This is the subject
struct tm *tm = gmtime((time_t *)&Msg->datecreated);
sprintf_s(msg, sizeof(msg),"%-6d %c %6d %-13s %-6s %02d%02d%02d %s\r",
Msg->number, Msg->type, Msg->length, Msg->to,
Msg->from, tm->tm_year-100, tm->tm_mon+1, tm->tm_mday, Msg->title);
#ifdef WIN32
if (pRunEventProgram)
pRunEventProgram("MailNewMsg.exe", msg);
#else
{
char prog[256];
sprintf(prog, "%s/%s", BPQDirectory, "MailNewMsg");
RunEventProgram(prog, msg);
}
#endif
}
user = LookupCall(Msg->to);
SendNewMessageEvent(user->Call, Msg);
if (EnableUI)
#ifdef LINBPQ
@ -6493,8 +6475,6 @@ nextline:
My__except_Routine("SendMsgUI");
#endif
user = LookupCall(Msg->to);
if (user && (user->flags & F_APRSMFOR))
{
char APRS[128];
@ -9576,6 +9556,7 @@ VOID SaveConfig(char * ConfigName)
SaveIntValue(group, "EnableUI", EnableUI);
SaveIntValue(group, "RefuseBulls", RefuseBulls);
SaveIntValue(group, "OnlyKnown", OnlyKnown);
SaveIntValue(group, "reportMailEvents", reportMailEvents);
SaveIntValue(group, "SendSYStoSYSOPCall", SendSYStoSYSOPCall);
SaveIntValue(group, "SendBBStoSYSOPCall", SendBBStoSYSOPCall);
SaveIntValue(group, "DontHoldNewUsers", DontHoldNewUsers);
@ -10098,13 +10079,13 @@ BOOL GetConfig(char * ConfigName)
config_destroy(&cfg);
return(EXIT_FAILURE);
}
/*
#if LIBCONFIG_VER_MINOR > 5
config_set_option(&cfg, CONFIG_OPTION_AUTOCONVERT, 1);
#else
config_set_auto_convert (&cfg, 1);
#endif
*/
group = config_lookup (&cfg, "main");
if (group == NULL)
@ -10120,6 +10101,8 @@ BOOL GetConfig(char * ConfigName)
MailForInterval = GetIntValue(group, "MailForInterval");
RefuseBulls = GetIntValue(group, "RefuseBulls");
OnlyKnown = GetIntValue(group, "OnlyKnown");
reportMailEvents = GetIntValue(group, "reportMailEvents");
SendSYStoSYSOPCall = GetIntValue(group, "SendSYStoSYSOPCall");
SendBBStoSYSOPCall = GetIntValue(group, "SendBBStoSYSOPCall");
DontHoldNewUsers = GetIntValue(group, "DontHoldNewUsers");
@ -15793,3 +15776,62 @@ VOID GetPGConfig()
NUM_SERVERS = n;
fclose(file);
}
void SendMessageReadEvent(char * call, struct MsgInfo * Msg)
{
if (reportMailEvents)
{
char msg[512];
//12345 B 2053 TEST@ALL F6FBB 920325 This is the subject
struct tm *tm = gmtime((time_t *)&Msg->datecreated);
sprintf_s(msg, sizeof(msg),"%-6d %c %c %6d %-13s %-6s %02d%02d%02d %s\r",
Msg->number, Msg->type, Msg->status, Msg->length, Msg->to,
Msg->from, tm->tm_year-100, tm->tm_mon+1, tm->tm_mday, Msg->title);
// sprintf(msg, "%s Read %d\r", user->Call, Msg->number);
#ifdef WIN32
if (pRunEventProgram)
pRunEventProgram("MailMsgRead.exe", msg);
#else
{
char prog[256];
sprintf(prog, "%s/%s", BPQDirectory, "MailMsgRead");
RunEventProgram(prog, msg);
}
#endif
}
}
void SendNewMessageEvent(char * call, struct MsgInfo * Msg)
{
if (reportMailEvents)
{
char msg[512];
//12345 B 2053 TEST@ALL F6FBB 920325 This is the subject
struct tm *tm = gmtime((time_t *)&Msg->datecreated);
sprintf_s(msg, sizeof(msg),"%-6d %c %c %6d %-13s %-6s %02d%02d%02d %s\r",
Msg->number, Msg->type, Msg->status, Msg->length, Msg->to,
Msg->from, tm->tm_year-100, tm->tm_mon+1, tm->tm_mday, Msg->title);
#ifdef WIN32
if (pRunEventProgram)
pRunEventProgram("MailNewMsg.exe", msg);
#else
{
char prog[256];
sprintf(prog, "%s/%s", BPQDirectory, "MailNewMsg");
RunEventProgram(prog, msg);
}
#endif
}
}

View File

@ -1123,8 +1123,9 @@
// Add FBB reject.sys style filters (3)
// Improve Webmail on 64 bit builds
// Fix setting status '$' on Bulls sent via WebMail (22)
// Implement New Message and Message Read Events (23)
// Start adding json api (25)
// Fix reading nested directories when loading Standard Templates and other template bugs (25)
#include "bpqmail.h"
#include "winstdint.h"

View File

@ -316,6 +316,10 @@
RelativePath="..\CommonSource\LzmaLib.c"
>
</File>
<File
RelativePath=".\mailapi.c"
>
</File>
<File
RelativePath="..\CommonSource\MailCommands.c"
>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="DESKTOP-TGEL8RC"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="DESKTOP-TGEL8RC"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="DESKTOP-TGEL8RC"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="DESKTOP-TGEL8RC"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="LAPTOP-Q6S4RP5Q"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="LAPTOP-Q6S4RP5Q"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -1203,6 +1203,9 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
// Improve restart of WinRPR TNC on remote host (21)
// Fix some Rigcontrol issues with empty timebands (22)
// Fix 64 bit bug in processing INP3 Messages (22)
// First pass at api (24)
// Send OK in response to Rigcontrol CMD (24);
#define CKernel
@ -2065,7 +2068,7 @@ VOID TimerProcX()
GetWindowRect(FrameWnd, &FRect);
SaveWindowPos(64); // Rigcontrol
SaveWindowPos(70); // Rigcontrol
for (i=0;i<NUMBEROFPORTS;i++)
{
@ -2181,7 +2184,7 @@ VOID TimerProcX()
if(TimerInst == GetCurrentProcessId())
{
RigReconfigFlag = FALSE;
CloseDriverWindow(40);
CloseDriverWindow(70);
Rig_Close();
Sleep(6000); // Allow any CATPTT, HAMLIB and FLRIG threads to close
RigActive = Rig_Init();
@ -6482,7 +6485,7 @@ VOID SaveBPQ32Windows()
PORTVEC=(PEXTPORTDATA)PORTVEC->PORTCONTROL.PORTPOINTER;
}
SaveWindowPos(40); // Rigcontrol
SaveWindowPos(70); // Rigcontrol
if (hIPResWnd)

View File

@ -438,6 +438,10 @@
RelativePath="..\CommonSource\MULTIPSK.c"
>
</File>
<File
RelativePath=".\nodeapi.c"
>
</File>
<File
RelativePath=".\png.c"
>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="C:\Devprogs\BPQ32\bpq32.exe"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="DESKTOP-TGEL8RC"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command=""
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="DESKTOP-TGEL8RC"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="C:\Devprogs\BPQ32\bpq32.exe"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="DESKTOP-TGEL8RC"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command=""
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="DESKTOP-TGEL8RC"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="C:\Devprogs\BPQ32\bpq32.exe"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="LAPTOP-Q6S4RP5Q"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command=""
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="LAPTOP-Q6S4RP5Q"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="C:\Devprogs\BPQ32\bpq32.exe"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="LAPTOP-Q6S4RP5Q"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command=""
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="LAPTOP-Q6S4RP5Q"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -406,7 +406,7 @@ extern BOOL CloseAllNeeded;
extern int CloseOnError;
extern char * PortConfig[70];
extern struct TNCINFO * TNCInfo[70]; // Records are Malloc'd
extern struct TNCINFO * TNCInfo[71]; // Records are Malloc'd
#define MaxBPQPortNo 63 // Port 64 reserved for BBS Mon
#define MAXBPQPORTS 63

View File

@ -67,6 +67,7 @@ extern int MaxChatStreams;
extern char Position[81];
extern char PopupText[251];
extern int PopupMode;
extern int reportChatEvents;
#include "httpconnectioninfo.h"
@ -323,6 +324,8 @@ VOID SaveChatInfo(struct HTTPConnectionInfo * Session, char * MsgPtr, char * Rep
if (chatPaclen < 60)
chatPaclen = 60;
GetCheckBox(input, "Events=", &reportChatEvents);
GetParam(input, "nodes=", Nodes);
ptr1 = Nodes;
@ -508,7 +511,9 @@ scan:
Len = sprintf(Reply, ChatConfigTemplate,
OurNode, Key, Key, Key,
ChatApplNum, MaxChatStreams, Nodes, chatPaclen, Position,
ChatApplNum, MaxChatStreams,
(reportChatEvents) ? CHKD : UNC,
Nodes, chatPaclen, Position,
(PopupMode) ? UNC : CHKD,
(PopupMode) ? CHKD : UNC, Text, ptr2);

View File

@ -49,7 +49,7 @@ extern struct CONFIGTABLE xxcfg;
#endif
struct TNCINFO * TNCInfo[70]; // Records are Malloc'd
struct TNCINFO * TNCInfo[71]; // Records are Malloc'd
extern int ReportTimer;
@ -3516,8 +3516,6 @@ int __sync_lock_test_and_set(int * ptr, int val)
#endif // __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
#endif // MACBPQ
void GetSemaphore(struct SEM * Semaphore, int ID)
{
//
@ -5232,7 +5230,7 @@ void SendDataToPktMap(char *Msg)
// TCP
Mode = Modenames[TNC->Hardware];
Mode = Modenames[TNC->Hardware - 1];
if (TNC->CONNECTED)
Active = 1;

View File

@ -69,6 +69,7 @@ int GetAPRSIcon(unsigned char * _REPLYBUFFER, char * NodeURL);
char * GetStandardPage(char * FN, int * Len);
BOOL SHA1PasswordHash(char * String, char * Hash);
char * byte_base64_encode(char *str, int len);
int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * request, BOOL LOCAL, BOOL COOKIE);
extern struct ROUTE * NEIGHBOURS;
extern int ROUTE_LEN;
@ -1593,7 +1594,7 @@ int InnerProcessHTTPMessage(struct ConnectionInfo * conn)
char * Compressed = 0;
char * HostPtr = 0;
char * Context, * Method, * NodeURL, * Key;
char * Context, * Method, * NodeURL = 0, * Key;
char _REPLYBUFFER[250000];
char Reply[250000];
@ -1631,7 +1632,7 @@ int InnerProcessHTTPMessage(struct ConnectionInfo * conn)
char Encoding[] = "Content-Encoding: deflate\r\n";
#ifdef WIN32
#ifdef WIN32xx
struct _EXCEPTION_POINTERS exinfo;
strcpy(EXCEPTMSG, "ProcessHTTPMessage");
@ -1772,6 +1773,43 @@ int InnerProcessHTTPMessage(struct ConnectionInfo * conn)
strlop(Mycall, ' ');
// Look for API messages
if (_memicmp(Context, "/api/", 5) == 0 || _stricmp(Context, "/api") == 0)
{
char * Compressed;
ReplyLen = APIProcessHTTPMessage(_REPLYBUFFER, Method, Context, MsgPtr, LOCAL, COOKIE);
if (memcmp(_REPLYBUFFER, "HTTP", 4) == 0)
{
// Full Message - just send it
sendandcheck(sock, _REPLYBUFFER, ReplyLen);
return 0;
}
if (allowDeflate)
Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen);
else
Compressed = _REPLYBUFFER;
HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\n"
"Content-Length: %d\r\n"
"Content-Type: application/json\r\n"
"Connection: close\r\n"
"%s\r\n", ReplyLen, Encoding);
sendandcheck(sock, Header, HeaderLen);
sendandcheck(sock, Compressed, ReplyLen);
if (allowDeflate)
free (Compressed);
return 0;
}
// APRS process internally
if (_memicmp(Context, "/APRS/", 6) == 0 || _stricmp(Context, "/APRS") == 0)
@ -1874,7 +1912,8 @@ int InnerProcessHTTPMessage(struct ConnectionInfo * conn)
Session = FindSession(Key);
if (Session == NULL)
if (Session == NULL && _memicmp(Context, "/Mail/API/", 10) != 0)
{
ReplyLen = sprintf(Reply, MailLostSession, Key);
RLen = ReplyLen;
@ -2025,10 +2064,13 @@ Returnit:
return 0;
}
if (NodeURL && _memicmp(NodeURL, "/mail/api/", 10) != 0)
{
// Add tail
strcpy(&Reply[ReplyLen], Tail);
ReplyLen += strlen(Tail);
}
// compress if allowed
@ -2037,7 +2079,15 @@ Returnit:
else
Compressed = Reply;
if (NodeURL && _memicmp(NodeURL, "/mail/api/", 10) == 0)
HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\n"
"Content-Length: %d\r\n"
"Content-Type: application/json\r\n"
"Connection: close\r\n"
"%s\r\n", ReplyLen, Encoding);
else
HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n%s\r\n", ReplyLen, Encoding);
sendandcheck(sock, Header, HeaderLen);
sendandcheck(sock, Compressed, ReplyLen);
@ -3889,7 +3939,7 @@ SendResp:
}
return 0;
#ifdef WIN32
#ifdef WIN32xx
}
#include "StdExcept.c"
}

View File

@ -77,6 +77,8 @@ char PopupText[260] = "";
int PopupMode = 0;
int chatPaclen = 236;
int reportChatEvents = 0;
char RtKnown[MAX_PATH] = "RTKnown.txt";
char RtUsr[MAX_PATH] = "STUsers.txt";
char RtUsrTemp[MAX_PATH] = "STUsers.tmp";
@ -2079,6 +2081,18 @@ void text_tellu_Joined(USER * user)
sprintf(buf, "%s%-6.6s : %s *** Joined Chat, Topic %s", Stamp, user->call, user->name, user->topic->name);
if (reportChatEvents)
{
#ifdef WIN32
if (pRunEventProgram)
pRunEventProgram("ChatNewUser.exe", user->call);
#else
sprintf(prog, "%s/%s", BPQDirectory, "ChatNewUser");
RunEventProgram(prog, user->call);
#endif
}
// Send it to all connected users in the same topic.
// Echo to originator if requested.
@ -2109,14 +2123,6 @@ void text_tellu_Joined(USER * user)
nputc(circuit, 7);
nputc(circuit, 13);
#ifdef WIN32
if (pRunEventProgram)
pRunEventProgram("ChatNewUser.exe", user->call);
#else
sprintf(prog, "%s/%s", BPQDirectory, "ChatNewUser");
RunEventProgram(prog, user->call);
#endif
}
}
// Tell one link circuit about a local user change of topic.
@ -4170,6 +4176,7 @@ BOOL GetChatConfig(char * ConfigName)
ChatApplNum = GetIntValue(group, "ApplNum");
MaxChatStreams = GetIntValue(group, "MaxStreams");
reportChatEvents = GetIntValue(group, "reportChatEvents");
chatPaclen = GetIntValue(group, "chatPaclen");
GetStringValue(group, "OtherChatNodes", OtherNodesList);
GetStringValue(group, "ChatWelcomeMsg", ChatWelcomeMsg);
@ -4201,6 +4208,7 @@ VOID SaveChatConfigFile(char * ConfigName)
SaveIntValue(group, "ApplNum", ChatApplNum);
SaveIntValue(group, "MaxStreams", MaxChatStreams);
SaveIntValue(group, "reportChatEvents", reportChatEvents);
SaveIntValue(group, "chatPaclen", chatPaclen);
SaveStringValue(group, "OtherChatNodes", OtherNodesList);
SaveStringValue(group, "ChatWelcomeMsg", ChatWelcomeMsg);

View File

@ -23,6 +23,9 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
#include "bpqmail.h"
void SendMessageReadEvent(struct UserInfo * user, struct MsgInfo * Msg);
VOID ProcessMBLLine(CIRCUIT * conn, struct UserInfo * user, UCHAR* Buffer, int len)
{
Buffer[len] = 0;
@ -86,6 +89,7 @@ VOID ProcessMBLLine(CIRCUIT * conn, struct UserInfo * user, UCHAR* Buffer, int l
FBBputs(conn, ">\r");
Msg->status = 'Y'; // Mark as read
SaveMessageDatabase();
SendMessageReadEvent(user->Call, Msg);
}
else
{

View File

@ -424,6 +424,10 @@
RelativePath="..\CommonSource\LzmaLib.c"
>
</File>
<File
RelativePath=".\mailapi.c"
>
</File>
<File
RelativePath="..\CommonSource\MailCommands.c"
>
@ -464,6 +468,10 @@
RelativePath="..\CommonSource\NNTPRoutines.c"
>
</File>
<File
RelativePath=".\nodeapi.c"
>
</File>
<File
RelativePath="..\CommonSource\pibits.c"
>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="DESKTOP-TGEL8RC"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="DESKTOP-TGEL8RC"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -1142,7 +1142,6 @@ int Rig_CommandEx(struct RIGPORTINFO * PORT, struct RIGINFO * RIG, TRANSPORTENTR
return FALSE;
}
// Build a ScanEntry in the buffer
FreqPtr = (struct ScanEntry *)buffptr->Data;
@ -1277,8 +1276,6 @@ int Rig_CommandEx(struct RIGPORTINFO * PORT, struct RIGINFO * RIG, TRANSPORTENTR
}
*(CmdPtr++) = 0xFD;
*(CmdPtr) = 0;
Len = (int)(CmdPtr - (char *)&buffptr[30]);
@ -1325,7 +1322,9 @@ int Rig_CommandEx(struct RIGPORTINFO * PORT, struct RIGINFO * RIG, TRANSPORTENTR
FreqPtr[0].Cmd1Len = Len; // for ICOM
C_Q_ADD(&RIG->BPQtoRADIO_Q, buffptr);
return TRUE;
sprintf(Command, "Ok\r");
return FALSE;
}
if (_memicmp(FreqString, "Chan", 4) == 0)
@ -2203,7 +2202,7 @@ DllExport BOOL APIENTRY Rig_Init()
memset(&RIGTNC, 0, sizeof(struct TNCINFO));
TNCInfo[40] = TNC;
TNCInfo[70] = TNC;
// Get config info
@ -2229,7 +2228,7 @@ DllExport BOOL APIENTRY Rig_Init()
#ifndef LINBPQ
TNC->Port = 40;
TNC->Port = 70;
CreatePactorWindow(TNC, "RIGCONTROL", "RigControl", 10, PacWndProc, 550, NeedRig * 20 + 60, NULL);
hDlg = TNC->hDlg;

View File

@ -534,6 +534,9 @@ int ProcessLine(char * buf, int Port)
else if (_stricmp(param,"HTTPPORT") == 0)
TCP->HTTPPort = atoi(value);
else if (_stricmp(param,"APIPORT") == 0)
TCP->APIPort = atoi(value);
else if (_stricmp(param,"SYNCPORT") == 0)
TCP->SyncPort = atoi(value);
@ -1646,6 +1649,9 @@ BOOL OpenSockets(struct TNCINFO * TNC)
if (TCP->HTTPPort)
TCP->HTTPsock = OpenSocket4(TNC, TCP->HTTPPort);
if (TCP->APIPort)
TCP->APIsock = OpenSocket4(TNC, TCP->APIPort);
if (TCP->SyncPort)
TCP->Syncsock = OpenSocket4(TNC, TCP->SyncPort);
@ -1755,10 +1761,12 @@ BOOL OpenSockets6(struct TNCINFO * TNC)
if (TCP->RelayPort)
TCP->Relaysock6 = OpenSocket6(TNC, TCP->RelayPort);
if (TCP->HTTPPort)
TCP->HTTPsock6 = OpenSocket6(TNC, TCP->HTTPPort);
if (TCP->APIPort)
TCP->APIsock6 = OpenSocket6(TNC, TCP->APIPort);
if (TCP->SyncPort)
TCP->Syncsock6 = OpenSocket6(TNC, TCP->SyncPort);
@ -1819,6 +1827,14 @@ static VOID SetupListenSet(struct TNCINFO * TNC)
maxsock = sock;
}
sock = TCP->APIsock;
if (sock)
{
FD_SET(sock, readfd);
if (sock > maxsock)
maxsock = sock;
}
sock = TCP->Syncsock;
if (sock)
{
@ -1886,6 +1902,14 @@ static VOID SetupListenSet(struct TNCINFO * TNC)
maxsock = sock;
}
sock = TCP->APIsock6;
if (sock)
{
FD_SET(sock, readfd);
if (sock > maxsock)
maxsock = sock;
}
sock = TCP->DRATSsock6;
if (sock)
@ -3192,6 +3216,7 @@ int Socket_Accept(struct TNCINFO * TNC, SOCKET SocketId, int Port)
TNC->Streams[n].FramesQueued = 0;
sockptr->HTTPMode = FALSE;
sockptr->APIMode = FALSE;
sockptr->SyncMode = FALSE;
sockptr->DRATSMode = FALSE;
sockptr->FBBMode = FALSE;
@ -3208,6 +3233,12 @@ int Socket_Accept(struct TNCINFO * TNC, SOCKET SocketId, int Port)
if (SocketId == TCP->HTTPsock || SocketId == TCP->HTTPsock6)
sockptr->HTTPMode = TRUE;
if (SocketId == TCP->APIsock || SocketId == TCP->APIsock6)
{
sockptr->HTTPMode = TRUE; // API is a type of HTTP socket
sockptr->APIMode = TRUE;
}
else if (SocketId == TCP->Syncsock || SocketId == TCP->Syncsock6)
sockptr->SyncMode = TRUE;
else if (SocketId == TCP->DRATSsock || SocketId == TCP->DRATSsock6)

View File

@ -10,14 +10,14 @@
#endif
#define KVers 6,0,24,22
#define KVerstring "6.0.24.22\0"
#define KVers 6,0,24,25
#define KVerstring "6.0.24.25\0"
#ifdef CKernel
#define Vers KVers
#define Verstring KVerstring
#define Datestring "November 2023"
#define Datestring "December 2023"
#define VerComments "G8BPQ Packet Switch (C Version)" KVerstring
#define VerCopyright "Copyright © 2001-2023 John Wiseman G8BPQ\0"
#define VerDesc "BPQ32 Switch\0"

View File

@ -76,6 +76,8 @@ VOID SendTemplateSelectScreen(struct HTTPConnectionInfo * Session, char *URLPara
BOOL isAMPRMsg(char * Addr);
char * doXMLTransparency(char * string);
Dll BOOL APIENTRY APISendAPRSMessage(char * Text, char * ToCall);
void SendMessageReadEvent(char * Call, struct MsgInfo * Msg);
void SendNewMessageEvent(char * call, struct MsgInfo * Msg);
extern char NodeTail[];
extern char BBSName[10];
@ -719,17 +721,19 @@ VOID ProcessFormDir(char * FormSet, char * DirName, struct HtmlFormDir *** xxx,
{
if (entry->d_type == DT_DIR)
{
char Dir[MAX_PATH];
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
Debugprintf("Recurse %s/%s/%s", FormSet, DirName, entry->d_name);
// Recurse in subdir
sprintf(Dir, "%s/%s", DirName, entry->d_name);
ProcessFormDir(FormSet, Dir, &FormDir->Dirs, &FormDir->DirCount);
continue;
}
// see if initial html
// if (stristr(entry->d_name, "initial.html"))
{
// Add to list
Form = zalloc(sizeof (struct HtmlForm));
@ -739,7 +743,6 @@ VOID ProcessFormDir(char * FormSet, char * DirName, struct HtmlFormDir *** xxx,
FormDir->Forms=realloc(FormDir->Forms, (FormDir->FormCount + 1) * sizeof(void *));
FormDir->Forms[FormDir->FormCount++] = Form;
}
}
closedir(dir);
#endif
return;
@ -808,9 +811,9 @@ int GetHTMLFormSet(char * FormSet)
if (!(dir = opendir(name)))
{
Debugprintf("cant open forms dir %s %d %d", name, errno, dir);
return 0;
}
else
{
while ((entry = readdir(dir)) != NULL)
{
if (entry->d_type == DT_DIR)
@ -824,6 +827,7 @@ int GetHTMLFormSet(char * FormSet)
}
}
closedir(dir);
}
#endif
// List for testing
@ -1122,7 +1126,7 @@ int ViewWebMailMessage(struct HTTPConnectionInfo * Session, char * Reply, int Nu
Msg->status = 'Y';
Msg->datechanged=time(NULL);
SaveMessageDatabase();
SendMessageReadEvent(Session->Callsign, Msg);
}
}
}
@ -1190,6 +1194,7 @@ int ViewWebMailMessage(struct HTTPConnectionInfo * Session, char * Reply, int Nu
Msg->status = 'Y';
Msg->datechanged=time(NULL);
SaveMessageDatabase();
SendMessageReadEvent(Session->Callsign, Msg);
}
}
}
@ -1303,6 +1308,7 @@ int ViewWebMailMessage(struct HTTPConnectionInfo * Session, char * Reply, int Nu
Msg->status = 'Y';
Msg->datechanged=time(NULL);
SaveMessageDatabase();
SendMessageReadEvent(Session->Callsign, Msg);
}
}
}
@ -2776,11 +2782,16 @@ VOID SaveNewMessage(struct HTTPConnectionInfo * Session, char * MsgPtr, char * R
if (Msg->status != 'H' && Msg->type == 'B' && memcmp(Msg->fbbs, zeros, NBMASK) != 0)
Msg->status = '$'; // Has forwarding
if (EnableUI)
SendMsgUI(Msg);
user = LookupCall(Msg->to);
// If Event Notifications enabled report a new message event
SendNewMessageEvent(user->Call, Msg);
if (user && (user->flags & F_APRSMFOR))
{
char APRS[128];
@ -2838,12 +2849,25 @@ char * GetHTMLViewerTemplate(char * FN)
{
for (l = 0; l < Dir->DirCount; l++)
{
for (k = 0; k < Dir->Dirs[l]->FormCount; k++)
struct HtmlFormDir * SDir = Dir->Dirs[l];
if (SDir->DirCount)
{
if (strcmp(FN, Dir->Dirs[l]->Forms[k]->FileName) == 0)
{
return CheckFile(Dir, Dir->Dirs[l]->Forms[k]->FileName);
struct HtmlFormDir * SSDir = SDir->Dirs[0];
int x = 1;
}
for (k = 0; k < SDir->FormCount; k++)
{
if (_stricmp(FN, SDir->Forms[k]->FileName) == 0)
{
return CheckFile(SDir, SDir->Forms[k]->FileName);
}
}
if (SDir->DirCount)
{
struct HtmlFormDir * SSDir = SDir->Dirs[0];
int x = 1;
}
}
}
@ -3224,7 +3248,7 @@ BOOL ParseXML(WebMailInfo * WebMail, char * XMLOrig)
*ptr2++ = 0;
ptr3 = strchr(ptr2, '<'); // end of value string
ptr3 = strstr(ptr2, "</"); // end of value string
if (ptr3 == NULL)
goto quit;
@ -3236,6 +3260,14 @@ BOOL ParseXML(WebMailInfo * WebMail, char * XMLOrig)
XMLKeys++;
ptr1 = strchr(ptr3, '<');
if (_memicmp(ptr1, "</", 2) == 0)
{
// end of a parameter block. Find start of next block
ptr1 = strchr(++ptr1, '<');
ptr1 = strchr(++ptr1, '<'); // Skip start of next block
}
}
@ -5349,6 +5381,8 @@ char * CheckFile(struct HtmlFormDir * Dir, char * FN)
#endif
printf("%s\n", MsgFile);
if (stat(MsgFile, &STAT) != -1)
{
hFile = fopen(MsgFile, "rb");
@ -5365,6 +5399,8 @@ char * CheckFile(struct HtmlFormDir * Dir, char * FN)
MsgBytes[FileSize] = 0;
fclose(hFile);
printf("%d %s\n", strlen(MsgBytes), MsgBytes);
return MsgBytes;
}
return NULL;

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="DESKTOP-TGEL8RC"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="DESKTOP-TGEL8RC"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="DESKTOP-TGEL8RC"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="DESKTOP-TGEL8RC"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="DESKTOP-TGEL8RC"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="DESKTOP-TGEL8RC"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="LAPTOP-Q6S4RP5Q"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="LAPTOP-Q6S4RP5Q"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

3161
bbshtmlconfig.c~ Normal file

File diff suppressed because it is too large Load Diff

196
mailapi.c Normal file
View File

@ -0,0 +1,196 @@
// basic JASON API to BPQ Node
// Authentication is via Telnet USER records.
#define _CRT_SECURE_NO_DEPRECATE
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
//#include <windows.h>
#include "CHeaders.h"
#include <stdlib.h>
#include "bpqmail.h"
// Constants
#define TOKEN_SIZE 32 // Length of the authentication token
#define TOKEN_EXPIRATION 7200 // Token expiration time in seconds (2 hours)
// Token data structure
typedef struct MailToken {
char token[TOKEN_SIZE + 1];
time_t expiration_time;
struct UserInfo * User;
char Call[10];
struct MailToken* next;
} MailToken;
static MailToken * token_list = NULL;
static int verify_token(const char* token);
static void remove_expired_tokens();
static int request_token(char * response);
static void add_token_to_list(MailToken* token);
static MailToken * find_token(const char* token);
static MailToken * generate_token()
{
// Generate a random authentication token
int i;
MailToken * token = malloc(sizeof(MailToken));
srand(time(NULL));
for (i = 0; i < TOKEN_SIZE; i++)
{
token->token[i] = 'A' + rand() % 26; // Random uppercase alphabet character
}
token->token[TOKEN_SIZE] = '\0'; // Null-terminate the token
token->expiration_time = time(NULL) + TOKEN_EXPIRATION; // Set token expiration time
add_token_to_list(token);
return token;
}
// Function to add the token to the token_list
static void add_token_to_list(MailToken * token)
{
if (token_list == NULL)
{
token_list = token;
token->next = NULL;
}
else
{
MailToken * current = token_list;
while (current->next != NULL)
current = current->next;
current->next = token;
token->next = NULL;
}
}
static int verify_token(const char* token)
{
// Find the token in the token list
MailToken * existing_token = find_token(token);
if (existing_token != NULL)
{
// Check if the token has expired
time_t current_time = time(NULL);
if (current_time > existing_token->expiration_time)
{
// Token has expired, remove it from the token list
remove_expired_tokens();
return 0;
}
// Token is valid
return 1;
}
// Token doesn't exist in the token list
return 0;
}
static void remove_expired_tokens()
{
time_t current_time = time(NULL);
MailToken* current_token = token_list;
MailToken* prev_token = NULL;
MailToken* next_token;
while (current_token != NULL)
{
if (current_time > current_token->expiration_time)
{
// Token has expired, remove it from the token list
if (prev_token == NULL)
{
token_list = current_token->next;
} else {
prev_token->next = current_token->next;
}
next_token = current_token->next;
free(current_token);
current_token = next_token;
} else {
prev_token = current_token;
current_token = current_token->next;
}
}
}
static MailToken * find_token(const char* token)
{
MailToken * current_token = token_list;
while (current_token != NULL)
{
if (strcmp(current_token->token, token) == 0)
{
return current_token;
}
current_token = current_token->next;
}
return NULL;
}
static int send_http_response(char * response, const char* msg)
{
return sprintf(response, "HTTP/1.1 %s\r\nContent-Length: 0\r\nConnection: close\r\n\r\n", msg);
}
int MailAPIProcessHTTPMessage(char * response, char * Method, char * URL, char * request, BOOL LOCAL, char *Params)
{
char * pass = strlop(Params, '&');
int Flags = 0;
MailToken * Token;
// Check if the request is for token generation
if (strcmp(Method, "GET") != 0)
return send_http_response(response, "403 (Bad Method)");
if (_stricmp(URL, "/mail/api/login") == 0)
{
// user is in Params and Password in pass
struct UserInfo * User;
char Msg[256];
int n;
User = LookupCall(Params);
if (User)
{
// Check Password
if (pass[0] == 0 || strcmp(User->pass, pass) != 0 || User->flags & F_Excluded)
return send_http_response(response, "403 (Login Failed)");
n=sprintf_s(Msg, sizeof(Msg), "API Connect from %s", _strupr(Params));
WriteLogLine(NULL, '|',Msg, n, LOG_BBS);
Token = generate_token();
add_token_to_list(Token);
Token->User = User;
strcpy(Token->Call, Params);
// Return Token
sprintf(response, "{\"access_token\":\"%s\", \"expires_in\":%d, \"scope\":\"create\"}\r\n",
Token->token, TOKEN_EXPIRATION);
return strlen(response);
}
}
return 0;
}

View File

@ -13,7 +13,7 @@ OBJS = pngwtran.o pngrtran.o pngset.o pngrio.o pngwio.o pngtrans.o pngrutil.o pn
MailCommands.o MailDataDefs.o LinBPQ.o MailRouting.o MailTCP.o MBLRoutines.o md5.o Moncode.o \
NNTPRoutines.o RigControl.o TelnetV6.o WINMOR.o TNCCode.o UZ7HODrv.o WPRoutines.o \
SCSTrackeMulti.o SCSPactor.o SCSTracker.o HanksRT.o UIRoutines.o AGWAPI.o AGWMoncode.o \
DRATS.o FreeDATA.o base64.o Events.o
DRATS.o FreeDATA.o base64.o Events.o nodeapi.o mailapi.o
# Configuration:

633
nodeapi.c Normal file
View File

@ -0,0 +1,633 @@
// basic JASON API to BPQ Node
// Authentication is via Telnet USER records.
#define _CRT_SECURE_NO_DEPRECATE
#include "CHeaders.h"
#include <stdlib.h>
#include "tncinfo.h"
#include "asmstrucs.h"
#include "kiss.h"
// Constants
#define TOKEN_SIZE 32 // Length of the authentication token
#define TOKEN_EXPIRATION 7200 // Token expiration time in seconds (2 hours)
// Token data structure
typedef struct Token {
char token[TOKEN_SIZE + 1];
time_t expiration_time;
struct Token* next;
} Token;
// Function prototypes
void handle_request(SOCKET client_socket, char * request, char * response);
int verify_token(const char* token);
void remove_expired_tokens();
char* fetch_data(const char* endpoint);
int request_token(char * response);
int send_http_response(char * response, const char* msg);
int create_json_response(char * response, char* access_token, int expires_in, char* scope);
void add_token_to_list(Token* token);
Token* find_token(const char* token);
Token* generate_token();
int sendPortList(char * response, char * token,int Flags);
int sendNodeList(char * response, char * token,int Flags);
int sendUserList(char * response, char * token,int Flags);
int sendInfo(char * response, char * token, int Flags);
DllExport struct PORTCONTROL * APIENTRY GetPortTableEntryFromSlot(int portslot);
// Token list
Token* token_list = NULL;
int xx()
{
while (1)
{
// Remove expired tokens
remove_expired_tokens();
// Handle the client request
// handle_request();
}
return 0;
}
int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * request, BOOL LOCAL, BOOL COOKIE)
{
const char * auth_header = "Authorization: Bearer ";
char * token_begin = strstr(request, auth_header);
char token[TOKEN_SIZE + 1]= "";
char * param = strlop(URL, '?');
int Flags = 0;
if (param && strlen(param) == TOKEN_SIZE)
{
// assume auth token
strcpy(token, param);
}
remove_expired_tokens(); // Tidy up
// Check if the request is for token generation
if (strcmp(Method, "GET") != 0)
return send_http_response(response, "403 (Bad Method)");
if (_stricmp(URL, "/api/request_token") == 0)
return request_token(response);
if (token[0] == 0)
{
// Extract the token from the request (assuming it's present in the request headers)
if (token_begin == NULL)
{
Debugprintf("Invalid request: No authentication token provided.\n");
return send_http_response(response, "403 (Forbidden)");
}
token_begin += strlen(auth_header); // Move to the beginning of the token
strncpy(token, token_begin, TOKEN_SIZE);
token[TOKEN_SIZE] = '\0'; // Null-terminate the token
}
// Verify the token
if (!verify_token(token))
{
Debugprintf("Invalid authentication token.\n");
return send_http_response(response, "401 Unauthorized");
}
// Determine the requested API endpoint
if (_stricmp(URL, "/api/getports") == 0)
return sendPortList(response, token, Flags);
else if (_stricmp(URL, "/api/getnodes") == 0)
return sendNodeList(response, token, Flags);
else if (_stricmp(URL, "/api/getusers") == 0)
return sendUserList(response, token, Flags);
else if (_stricmp(URL, "/api/getinfo") == 0)
return sendInfo(response, token, Flags);
return send_http_response(response, "401 Invalid API Call");
}
int request_token(char * response)
{
Token * token = generate_token();
int expires_in = 3600;
char scope[] = "create";
printf("Token generated: %s\n", token->token);
sprintf(response, "{\"access_token\":\"%s\", \"expires_in\":%d, \"scope\":\"create\"}\r\n",
token->token, expires_in);
return strlen(response);
}
Token * generate_token()
{
// Generate a random authentication token
int i;
Token * token = malloc(sizeof(Token));
for (i = 0; i < TOKEN_SIZE; i++)
{
token->token[i] = 'A' + rand() % 26; // Random uppercase alphabet character
}
token->token[TOKEN_SIZE] = '\0'; // Null-terminate the token
token->expiration_time = time(NULL) + TOKEN_EXPIRATION; // Set token expiration time
add_token_to_list(token);
return token;
}
// Function to add the token to the token_list
void add_token_to_list(Token* token)
{
if (token_list == NULL)
{
token_list = token;
token->next = NULL;
}
else
{
Token* current = token_list;
while (current->next != NULL)
current = current->next;
current->next = token;
token->next = NULL;
}
}
int verify_token(const char* token)
{
// Find the token in the token list
Token * existing_token = find_token(token);
if (existing_token != NULL)
{
// Check if the token has expired
time_t current_time = time(NULL);
if (current_time > existing_token->expiration_time)
{
// Token has expired, remove it from the token list
remove_expired_tokens();
return 0;
}
// Token is valid
return 1;
}
// Token doesn't exist in the token list
return 0;
}
void remove_expired_tokens()
{
time_t current_time = time(NULL);
Token* current_token = token_list;
Token* prev_token = NULL;
Token* next_token;
while (current_token != NULL)
{
if (current_time > current_token->expiration_time)
{
// Token has expired, remove it from the token list
if (prev_token == NULL)
{
token_list = current_token->next;
} else {
prev_token->next = current_token->next;
}
next_token = current_token->next;
free(current_token);
current_token = next_token;
} else {
prev_token = current_token;
current_token = current_token->next;
}
}
}
Token * find_token(const char* token)
{
Token* current_token = token_list;
while (current_token != NULL)
{
if (strcmp(current_token->token, token) == 0)
{
return current_token;
}
current_token = current_token->next;
}
return NULL;
}
int send_http_response(char * response, const char* msg)
{
return sprintf(response, "HTTP/1.1 %s\r\nContent-Length: 0\r\nConnection: close\r\n\r\n", msg);
}
/*
{
"access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
"expires_in":3600,
"scope":"create"
}
*/
/*
{"ports":[
{"ID":"My Port", "Driver":"KISS", "Number":2, "State":"Active"),
{ ...},
{...}
]}
*/
extern int MasterPort[MAXBPQPORTS+1]; // Pointer to first BPQ port for a specific MPSK or UZ7HO host
int sendPortList(char * response, char * token, int Flags)
{
char * Array = 0;
int ArrayLen = 0;
int ArrayPtr = 0;
struct _EXTPORTDATA * ExtPort;
struct PORTCONTROL * Port;
struct PORTCONTROL * SAVEPORT;
int PortNo;
int count;
char DLL[20];
char Status[32]="Unknown";
char ID[33];
char * ptr;
ArrayPtr += sprintf(&response[ArrayPtr], "{\"ports\":[\r\n");
for (count = 1; count <= NUMBEROFPORTS; count++)
{
Port = GetPortTableEntryFromSlot(count);
ExtPort = (struct _EXTPORTDATA *)Port;
PortNo = Port->PORTNUMBER;
if (Port->PORTTYPE == 0x10)
{
strcpy(DLL, ExtPort->PORT_DLL_NAME);
strlop(DLL, '.');
strlop(DLL, ' ');
}
else if (Port->PORTTYPE == 0)
strcpy(DLL, "ASYNC");
else if (Port->PORTTYPE == 22)
strcpy(DLL, "I2C");
else if (Port->PORTTYPE == 14)
strcpy(DLL, "INTERNAL");
else if (Port->PORTTYPE > 0 && Port->PORTTYPE < 14)
strcpy(DLL, "HDLC");
if (Port->PortStopped)
{
strcpy(Status, "Stopped");
}
else
{
if (Port->PORTTYPE == 0)
{
struct KISSINFO * KISS = (struct KISSINFO *)Port;
NPASYINFO KPort;
SAVEPORT = Port;
if (KISS->FIRSTPORT && KISS->FIRSTPORT != KISS)
{
// Not first port on device
Port = (struct PORTCONTROL *)KISS->FIRSTPORT;
KPort = KISSInfo[PortNo];
}
KPort = KISSInfo[PortNo];
if (KPort)
{
// KISS like - see if connected
if (Port->PORTIPADDR.s_addr || Port->KISSSLAVE)
{
// KISS over UDP or TCP
if (Port->KISSTCP)
{
if (KPort->Connected)
strcpy(Status, "Open ");
else
if (Port->KISSSLAVE)
strcpy(Status, "Listen");
else
strcpy(Status, "Closed");
}
else
strcpy(Status, "UDP");
}
else
if (KPort->idComDev) // Serial port Open
strcpy(Status, "Open ");
else
strcpy(Status, "Closed");
Port = SAVEPORT;
}
}
if (Port->PORTTYPE == 14) // Loopback
strcpy(Status, "Open ");
else if (Port->PORTTYPE == 16) // External
{
if (Port->PROTOCOL == 10) // 'HF' Port
{
struct TNCINFO * TNC = TNCInfo[PortNo];
if (TNC)
{
switch (TNC->Hardware) // Hardware Type
{
case H_SCS:
case H_KAM:
case H_AEA:
case H_HAL:
case H_TRK:
case H_SERIAL:
// Serial
if (TNC->hDevice)
strcpy(Status, "Open ");
else
strcpy(Status, "Closed");
break;
case H_UZ7HO:
if (TNCInfo[MasterPort[PortNo]]->CONNECTED)
strcpy(Status, "Open ");
else
strcpy(Status, "Closed");
break;
case H_WINMOR:
case H_V4:
case H_MPSK:
case H_FLDIGI:
case H_UIARQ:
case H_ARDOP:
case H_VARA:
case H_KISSHF:
case H_WINRPR:
case H_FREEDATA:
// TCP
if (TNC->CONNECTED)
{
if (TNC->Streams[0].Attached)
strcpy(Status, "In Use");
else
strcpy(Status, "Open ");
}
else
strcpy(Status, "Closed");
break;
case H_TELNET:
strcpy(Status, "Open ");
}
}
}
else
{
// External but not HF - AXIP, BPQETHER VKISS, ??
struct _EXTPORTDATA * EXTPORT = (struct _EXTPORTDATA *)Port;
strcpy(Status, "Open ");
}
}
}
strlop(Status, ' ');
strcpy(ID, Port->PORTDESCRIPTION);
ptr = &ID[29];
while (*(ptr) == ' ')
{
*(ptr--) = 0;
}
ArrayPtr += sprintf(&response[ArrayPtr], " {\"ID\":\"%s\", \"Driver\":\"%s\", \"Number\":%d,\"State\":\"%s\"},\r\n",
ID, DLL, Port->PORTNUMBER, Status);
}
ArrayPtr -= 3; // remove trailing comma
ArrayPtr += sprintf(&response[ArrayPtr], "\r\n]}\r\n");
return ArrayPtr;
}
/*
{"Nodes":[
{"Call":"xx", "Alias":"xx", "Nbour1 ":"xx", "Quality":192),
{ ...},
{...}
]}
*/
extern int MaxNodes;
extern struct DEST_LIST * DESTS; // NODE LIST
extern int DEST_LIST_LEN;
int sendNodeList(char * response, char * token, int Flags)
{
int ArrayPtr = 0;
int count, len, i;
char Normcall[10], Portcall[10];
char Alias[7];
struct DEST_LIST * Dests = DESTS ;
// struct ROUTE * Routes;
Dests = DESTS;
MaxNodes = MAXDESTS;
ArrayPtr += sprintf(&response[ArrayPtr], "{\"nodes\":[\r\n");
Dests-=1;
for (count = 0; count < MaxNodes; count++)
{
Dests+=1;
if (Dests->DEST_CALL[0] == 0)
continue;
len = ConvFromAX25(Dests->DEST_CALL, Normcall);
Normcall[len] = 0;
memcpy(Alias, Dests->DEST_ALIAS, 6);
Alias[6]=0;
for (i=0;i<6;i++)
{
if (Alias[i] == ' ')
Alias[i] = 0;
}
ArrayPtr += sprintf(&response[ArrayPtr], " {\"Call\":\"%s\", \"Alias\":\"%s\", \"Routes\":[", Normcall, Alias);
// Add an array with up to 6 objects (3 NR + 3 INP3 Neighbours
if (Dests->NRROUTE[0].ROUT_NEIGHBOUR != 0 && Dests->NRROUTE[0].ROUT_NEIGHBOUR->INP3Node == 0)
{
len = ConvFromAX25(Dests->NRROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL,Portcall);
Portcall[len] = 0;
ArrayPtr += sprintf(&response[ArrayPtr], "{\"Call\":\"%s\", \"Port\":%d, \"Quality\":%d},",
Portcall, Dests->NRROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_PORT, Dests->NRROUTE[0].ROUT_QUALITY);
// if (Dests->NRROUTE[0].ROUT_OBSCOUNT > 127)
// {
// len=sprintf(&line[cursor],"! ");
// cursor+=len;
// }
if (Dests->NRROUTE[1].ROUT_NEIGHBOUR != 0 && Dests->NRROUTE[1].ROUT_NEIGHBOUR->INP3Node == 0)
{
len=ConvFromAX25(Dests->NRROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL,Portcall);
Portcall[len]=0;
ArrayPtr += sprintf(&response[ArrayPtr], " {\"Call\":\"%s\", \"Port\":%d, \"Quality\":%d},",
Portcall, Dests->NRROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_PORT, Dests->NRROUTE[1].ROUT_QUALITY);
//if (Dests->NRROUTE[1].ROUT_OBSCOUNT > 127)
//{
//len=sprintf(&line[cursor],"! ");
//cursor+=len;
//}
}
if (Dests->NRROUTE[2].ROUT_NEIGHBOUR != 0 && Dests->NRROUTE[2].ROUT_NEIGHBOUR->INP3Node == 0)
{
len=ConvFromAX25(Dests->NRROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL,Portcall);
Portcall[len]=0;
ArrayPtr += sprintf(&response[ArrayPtr], " {\"Call\":\"%s\", \"Port\":%d, \"Quality\":%d},",
Portcall, Dests->NRROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_PORT, Dests->NRROUTE[1].ROUT_QUALITY);
//if (Dests->NRROUTE[2].ROUT_OBSCOUNT > 127)
//{
//len=sprintf(&line[cursor],"! ");
//cursor+=len;
}
ArrayPtr -= 1; // remove comma
}
ArrayPtr += sprintf(&response[ArrayPtr], "]},\r\n");
}
ArrayPtr -= 3; // remove comma
ArrayPtr += sprintf(&response[ArrayPtr], "\r\n]}");
return ArrayPtr;
}
int sendUserList(char * response, char * token, int Flags)
{
int ArrayPtr = 0;
int n = MAXCIRCUITS;
TRANSPORTENTRY * L4 = L4TABLE;
TRANSPORTENTRY * Partner;
int MaxLinks = MAXLINKS;
char State[12] = "", Type[12] = "Uplink";
char LHS[50] = "", MID[10] = "", RHS[50] = "";
char Line[100];
char Normcall[10];
int len;
ArrayPtr += sprintf(&response[ArrayPtr], "{\"users\":[\r\n");
while (n--)
{
if (L4->L4USER[0])
{
RHS[0] = MID[0] = 0;
len = ConvFromAX25(L4->L4USER, Normcall);
Normcall[len] = 0;
ArrayPtr += sprintf(&response[ArrayPtr], " {\"Call\", \"%s\"},\r\n", Normcall);
L4++;
}
}
if (ArrayPtr == 12) //empty list
{
ArrayPtr -=2;
ArrayPtr += sprintf(&response[ArrayPtr], "]}\r\n");
}
else
{
ArrayPtr -= 3; // remove trailing comma
ArrayPtr += sprintf(&response[ArrayPtr], "\r\n]}\r\n");
}
return ArrayPtr;
}
extern char MYALIASLOPPED[];
extern char TextVerstring[];
extern char LOCATOR[];
int sendInfo(char * response, char * token, int Flags)
{
char call[10];
memcpy(call, MYNODECALL, 10);
strlop(call, ' ');
sprintf(response, "{\"info\":{\"NodeCall\":\"%s\", \"Alias\":\"%s\", \"Locator\":\"%s\", \"Version\":\"%s\"}}\r\n",
call, MYALIASLOPPED, LOCATOR, TextVerstring);
return strlen(response);
}

View File

@ -36,7 +36,8 @@ struct ConnectionInfo
BOOL RelayMode; // Pure TCP for RMS Relay Emulation forwarding
BOOL DRATSMode; // HTML Terminal Emulator
BOOL SyncMode; // RMS Relay Sync
BOOL HTTPMode; // DRATS Reflector Emulator
BOOL HTTPMode; // HTTP Server
BOOL APIMode; // REST API Server
BOOL TriMode; // Trimode emulation
BOOL TriModeConnected; // Set when remote session is connected - now send data to DataSock
SOCKET TriModeDataSock; // Data Socket

View File

@ -478,7 +478,9 @@ char * MainConfigtxt()
" <input %sname=\"DontCheckFromCall\" type=\"checkbox\"> Dont Check From Call<br>\r\n"
" <input %sname=\"UserCantKillT\" type=\"checkbox\"> Allow users to kill T messages<br>\r\n"
" <input %sname=\"FWDtoMe\" type=\"checkbox\"> Forward Messages to BBS Call<br>\r\n"
" <input %sname=\"OnlyKnown\" type=\"checkbox\"> Don't allow unknown users<br><br>\r\n"
" <input %sname=\"OnlyKnown\" type=\"checkbox\"> Don't allow unknown users<br>\r\n"
" <input %sname=\"Events\" type=\"checkbox\"> Enable Event Reporting<br><br>\r\n"
"&nbsp;POP3 Port&nbsp;&nbsp; <input value=\"%d\" size=\"3\" name=\"POP3Port\">\r\n"
"SMTP Port <input value=\"%d\" size=\"3\" name=\"SMTPPort\"> NTPPort <input value=\"%d\" size=\"3\" name=\"NNTPPort\">&nbsp;<input %sname=\"EnRemote\" type=\"checkbox\"> Enable Remote Access<br>\r\n"
"&nbsp;AMPR Address <input value=\"%s\" name=\"AMPRDomain\"> <input %sname=\"SendAMPR\" type=\"checkbox\"> Send AMPR Mail to AMPR host\r\n"
@ -515,7 +517,7 @@ char * MainConfigtxt()
"&nbsp;FBB reject.sys type filters (all fields must match, wildcards allowed)\r\n"
"<p></p>"
"<div style='position: absolute; left: 20px;height: 120px; overflow:auto;'>%s</div>"
"<div style='position: absolute; top: 1100px;left: 300px; overflow:auto;'>"
"<div style='position: absolute; top: 1120px;left: 300px; overflow:auto;'>"
"<input class='btn' name=\"Save\" value=\"Save\" type=submit class='btn'> <input class='btn' name=\"Cancel\" value=\"Cancel\" type=submit class='btn'>"
"</div>"
"</form>\r\n"
@ -1428,7 +1430,7 @@ char * ChatConfigtxt()
"<div style=\"text-align: center;\"><font size=\"+1\"><span\r\n"
"style=\"font-family: monospace; font-weight: bold;\">Chat Configuration</span></font></div>\r\n"
"<div id=\"main\"\r\n"
"style=\"align: center; border: 2px solid ; overflow: auto; text-align: center; position: relative; top: 10px; height: 600px; width: 700px; left: 96.5px;\">\r\n"
"style=\"align: center; border: 2px solid ; overflow: auto; text-align: center; position: relative; top: 10px; height: 650px; width: 700px; left: 96.5px;\">\r\n"
"<form border=\"1\" style=\"font-family: monospace;\" method=\"post\"\r\n"
"action=\"/Chat/ChatConfig?%s\">\r\n"
"<h3>&nbsp;Chat Server Params<span style=\"font-family: monospace;\"></span></h3>\r\n"
@ -1437,6 +1439,8 @@ char * ChatConfigtxt()
"<span style=\"font-family: monospace;\"></span>Streams &nbsp; &nbsp;\r\n"
"&nbsp;&nbsp; <input value=\"%d\" size=\"3\" name=\"Streams\"><br>\r\n"
"&nbsp; <br>\r\n"
"<input %sname=\"Events\" type=\"checkbox\"> Enable Event Reporting<br><br>\r\n"
"<div style=\"text-align: left; width: 680px; margin: auto;\">The Nodes to link to box defines which other Chat Nodes should be connected to, or from which "
"connections may be accepted. The format is ALIAS:CALL, eg BPQCHT:G8BPQ-4. If the node is not directly "
"connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands "
@ -1460,7 +1464,7 @@ char * ChatConfigtxt()
"<textarea cols=\"80\" rows=\"5\" name=\"welcome\">%s</textarea><br>\r\n"
"<br>\r\n"
"\r\n"
"<div style=\"position: absolute; left: 150px; top: 600px;\">\r\n"
"<div style=\"position: absolute; left: 150px; top: 620px;\">\r\n"
"<input name=\"Save\" value=\"Save\" type=submit class='btn'> \r\n"
"<input name=\"UpdateMap\" value=\"Update Map\" type=submit class='btn'> \r\n"
"<input name=\"Restart\" value=\"Restart Links\" type=submit class='btn'> \r\n"

View File

@ -110,6 +110,7 @@ struct TCPINFO
int FBBPort[100];
int RelayPort;
int HTTPPort;
int APIPort;
int TriModePort;
int SyncPort;
int DRATSPort;
@ -159,6 +160,7 @@ struct TCPINFO
SOCKET FBBsock[100];
SOCKET Relaysock;
SOCKET HTTPsock;
SOCKET APIsock;
SOCKET TriModeSock;
SOCKET TriModeDataSock;
SOCKET Syncsock;
@ -169,6 +171,7 @@ struct TCPINFO
SOCKET FBBsock6[100];
SOCKET Relaysock6;
SOCKET HTTPsock6;
SOCKET APIsock6;
SOCKET Syncsock6;
SOCKET DRATSsock6;

187
upnp.c.bak Normal file
View File

@ -0,0 +1,187 @@
// Includes code from MiniUPnPc, used subject to the following conditions:
/*
MiniUPnPc
Copyright (c) 2005-2020, Thomas BERNARD
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#define MINIUPNP_STATICLIB
#include <stdio.h>
#ifdef _WIN32
#include "upnpcommands.h"
#include "miniupnpc.h"
#include "upnperrors.h"
#include <winsock2.h>
#else
#include <miniupnpc/upnpcommands.h>
#include <miniupnpc/miniupnpc.h>
#include <miniupnpc/upnperrors.h>
#include <stdio.h>
#endif
int AddMap(char * controlURL, char * eport, char * iport, char * proto);
int DeleteMap(char * controlURL, char * eport, char * iport, char * proto);
void Consoleprintf(const char * format, ...);
struct UPNP
{
struct UPNP * Next;
char * Protocol;
char * LANport;
char * WANPort;
};
extern struct UPNP * UPNPConfig;
char * controlURL = 0;
char * servicetype = 0;
char iaddr[] = "IP";
char * inClient = NULL;
#ifdef LINBPQ
char desc[] = "LinBPQ ";
#else
char desc[] = "BPQ32 ";
#endif
char * remoteHost = NULL;
char * leaseDuration = NULL;
struct UPNPDev * devlist = 0;
char lanaddr[64] = "unset"; /* my ip address on the LAN */
struct UPNPUrls urls;
struct IGDdatas data;
int i;
const char * rootdescurl = 0;
const char * multicastif = 0;
const char * minissdpdpath = 0;
int localport = UPNP_LOCAL_PORT_ANY;
int retcode = 0;
int error = 0;
int ipv6 = 0;
int ignore = 0;
unsigned char ttl = 2;
int upnpInit()
{
struct UPNP * Config = UPNPConfig;
int i;
#ifdef WIN32
WSADATA wsaData;
int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if(nResult != NO_ERROR)
{
fprintf(stderr, "WSAStartup() failed.\n");
return -1;
}
#endif
while (Config)
{
if (devlist == NULL)
{
devlist = upnpDiscover(2000, multicastif, minissdpdpath, localport, ipv6, ttl, &error);
if (devlist == NULL)
{
Consoleprintf("Failed to find a UPNP device");
return 0;
}
i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
}
AddMap(devlist->descURL, Config->LANport, Config->WANPort, Config->Protocol);
Config = Config->Next;
}
return 0;
}
int upnpClose()
{
struct UPNP * Config = UPNPConfig;
int i;
while (Config)
{
if (devlist == NULL)
{
devlist = upnpDiscover(2000, multicastif, minissdpdpath, localport, ipv6, ttl, &error);
if (devlist == NULL)
{
Consoleprintf("Failed to find a UPNP device");
return 0;
}
i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
}
DeleteMap(devlist->descURL, Config->LANport, Config->WANPort, Config->Protocol);
Config = Config->Next;
}
return 0;
}
int AddMap(char * controlURL, char * eport, char * iport, char * proto)
{
int r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
eport, iport, lanaddr, desc,
proto, remoteHost, leaseDuration);
if (r != UPNPCOMMAND_SUCCESS)
{
Consoleprintf("UPNP AddPortMapping(%s, %s, %s) failed with code %d (%s)", eport, iport, lanaddr, r, strupnperror(r));
return -2;
}
Consoleprintf("UPNP AddPortMapping(%s, %s, %s) Succeeded", eport, iport, lanaddr, r);
return 0;
}
int DeleteMap(char * controlURL, char * eport, char * iport, char * proto)
{
int r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, eport, proto, remoteHost);
if(r != UPNPCOMMAND_SUCCESS)
{
Consoleprintf("UPNP DeletePortMapping(%s, %s, %s) failed with code %d (%s)", eport, iport, lanaddr, r, strupnperror(r));
return -2;
}
Consoleprintf("UPNP DeletePortMapping(%s, %s, %s) Succeeded", eport, iport, lanaddr, r);
return 0;
}