Merge branch 'debian/latest' into raspbian/bullseye
This commit is contained in:
commit
ce76bb5d70
|
@ -38,6 +38,7 @@ extern char LTATString[2048];
|
||||||
//static UCHAR BPQDirectory[260];
|
//static UCHAR BPQDirectory[260];
|
||||||
|
|
||||||
extern ConnectionInfo Connections[];
|
extern ConnectionInfo Connections[];
|
||||||
|
|
||||||
extern int NumberofStreams;
|
extern int NumberofStreams;
|
||||||
extern time_t MaintClock; // Time to run housekeeping
|
extern time_t MaintClock; // Time to run housekeeping
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@ extern int MaxChatStreams;
|
||||||
extern char Position[81];
|
extern char Position[81];
|
||||||
extern char PopupText[251];
|
extern char PopupText[251];
|
||||||
extern int PopupMode;
|
extern int PopupMode;
|
||||||
|
extern int reportMailEvents;
|
||||||
|
|
||||||
#define MaxCMS 10 // Numbr of addresses we can keep - currently 4 are used.
|
#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);
|
struct UserInfo * FindBBS(char * Name);
|
||||||
void ReleaseWebMailStruct(WebMailInfo * WebMail);
|
void ReleaseWebMailStruct(WebMailInfo * WebMail);
|
||||||
VOID TidyWelcomeMsg(char ** pPrompt);
|
VOID TidyWelcomeMsg(char ** pPrompt);
|
||||||
|
int MailAPIProcessHTTPMessage(char * response, char * Method, char * URL, char * request, BOOL LOCAL, char * Param);
|
||||||
|
|
||||||
char UNC[] = "";
|
char UNC[] = "";
|
||||||
char CHKD[] = "checked=checked ";
|
char CHKD[] = "checked=checked ";
|
||||||
|
@ -489,6 +492,13 @@ void ProcessMailHTTPMessage(struct HTTPConnectionInfo * Session, char * Method,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_memicmp(URL, "/Mail/API/", 10) == 0)
|
||||||
|
{
|
||||||
|
*RLen = MailAPIProcessHTTPMessage(Reply, Method, URL, input, LOCAL, Context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (strcmp(Method, "POST") == 0)
|
if (strcmp(Method, "POST") == 0)
|
||||||
{
|
{
|
||||||
if (_stricmp(NodeURL, "/Mail/Header") == 0)
|
if (_stricmp(NodeURL, "/Mail/Header") == 0)
|
||||||
|
@ -1633,6 +1643,7 @@ VOID ProcessConfUpdate(struct HTTPConnectionInfo * Session, char * MsgPtr, char
|
||||||
UserCantKillT = !UserCantKillT; // Reverse Logic
|
UserCantKillT = !UserCantKillT; // Reverse Logic
|
||||||
GetCheckBox(input, "FWDtoMe=", &ForwardToMe);
|
GetCheckBox(input, "FWDtoMe=", &ForwardToMe);
|
||||||
GetCheckBox(input, "OnlyKnown=", &OnlyKnown);
|
GetCheckBox(input, "OnlyKnown=", &OnlyKnown);
|
||||||
|
GetCheckBox(input, "Events=", &reportMailEvents);
|
||||||
|
|
||||||
GetParam(input, "POP3Port=", Temp);
|
GetParam(input, "POP3Port=", Temp);
|
||||||
POP3InPort = atoi(Temp);
|
POP3InPort = atoi(Temp);
|
||||||
|
@ -2610,6 +2621,7 @@ VOID SendConfigPage(char * Reply, int * ReplyLen, char * Key)
|
||||||
(UserCantKillT) ? UNC : CHKD, // Reverse logic
|
(UserCantKillT) ? UNC : CHKD, // Reverse logic
|
||||||
(ForwardToMe) ? CHKD : UNC,
|
(ForwardToMe) ? CHKD : UNC,
|
||||||
(OnlyKnown) ? CHKD : UNC,
|
(OnlyKnown) ? CHKD : UNC,
|
||||||
|
(reportMailEvents) ? CHKD : UNC,
|
||||||
POP3InPort, SMTPInPort, NNTPInPort,
|
POP3InPort, SMTPInPort, NNTPInPort,
|
||||||
(RemoteEmail) ? CHKD : UNC,
|
(RemoteEmail) ? CHKD : UNC,
|
||||||
AMPRDomain,
|
AMPRDomain,
|
||||||
|
|
118
BBSUtilities.c
118
BBSUtilities.c
|
@ -43,7 +43,7 @@ RECT ConsoleRect;
|
||||||
BOOL OpenConsole;
|
BOOL OpenConsole;
|
||||||
BOOL OpenMon;
|
BOOL OpenMon;
|
||||||
|
|
||||||
int reportNewMesageEvents = 0;
|
int reportMailEvents = 0;
|
||||||
|
|
||||||
FBBFilter * Filters = NULL;
|
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);
|
int encode_quoted_printable(char *s, char * out, int Len);
|
||||||
int32_t Encode(char * in, char * out, int32_t inlen, BOOL B1Protocol, int Compress);
|
int32_t Encode(char * in, char * out, int32_t inlen, BOOL B1Protocol, int Compress);
|
||||||
int APIENTRY ChangeSessionCallsign(int Stream, unsigned char * AXCall);
|
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_t cfg;
|
||||||
config_setting_t * group;
|
config_setting_t * group;
|
||||||
|
@ -4904,6 +4906,7 @@ sendEOM:
|
||||||
Msg->status = 'Y';
|
Msg->status = 'Y';
|
||||||
Msg->datechanged=time(NULL);
|
Msg->datechanged=time(NULL);
|
||||||
SaveMessageDatabase();
|
SaveMessageDatabase();
|
||||||
|
SendMessageReadEvent(user->Call, Msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6457,30 +6460,9 @@ nextline:
|
||||||
|
|
||||||
// If Event Notifications enabled report a new message event
|
// If Event Notifications enabled report a new message event
|
||||||
|
|
||||||
if (reportNewMesageEvents)
|
user = LookupCall(Msg->to);
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
|
SendNewMessageEvent(user->Call, Msg);
|
||||||
|
|
||||||
if (EnableUI)
|
if (EnableUI)
|
||||||
#ifdef LINBPQ
|
#ifdef LINBPQ
|
||||||
|
@ -6493,8 +6475,6 @@ nextline:
|
||||||
My__except_Routine("SendMsgUI");
|
My__except_Routine("SendMsgUI");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
user = LookupCall(Msg->to);
|
|
||||||
|
|
||||||
if (user && (user->flags & F_APRSMFOR))
|
if (user && (user->flags & F_APRSMFOR))
|
||||||
{
|
{
|
||||||
char APRS[128];
|
char APRS[128];
|
||||||
|
@ -9576,6 +9556,7 @@ VOID SaveConfig(char * ConfigName)
|
||||||
SaveIntValue(group, "EnableUI", EnableUI);
|
SaveIntValue(group, "EnableUI", EnableUI);
|
||||||
SaveIntValue(group, "RefuseBulls", RefuseBulls);
|
SaveIntValue(group, "RefuseBulls", RefuseBulls);
|
||||||
SaveIntValue(group, "OnlyKnown", OnlyKnown);
|
SaveIntValue(group, "OnlyKnown", OnlyKnown);
|
||||||
|
SaveIntValue(group, "reportMailEvents", reportMailEvents);
|
||||||
SaveIntValue(group, "SendSYStoSYSOPCall", SendSYStoSYSOPCall);
|
SaveIntValue(group, "SendSYStoSYSOPCall", SendSYStoSYSOPCall);
|
||||||
SaveIntValue(group, "SendBBStoSYSOPCall", SendBBStoSYSOPCall);
|
SaveIntValue(group, "SendBBStoSYSOPCall", SendBBStoSYSOPCall);
|
||||||
SaveIntValue(group, "DontHoldNewUsers", DontHoldNewUsers);
|
SaveIntValue(group, "DontHoldNewUsers", DontHoldNewUsers);
|
||||||
|
@ -10098,28 +10079,30 @@ BOOL GetConfig(char * ConfigName)
|
||||||
config_destroy(&cfg);
|
config_destroy(&cfg);
|
||||||
return(EXIT_FAILURE);
|
return(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
#if LIBCONFIG_VER_MINOR > 5
|
#if LIBCONFIG_VER_MINOR > 5
|
||||||
config_set_option(&cfg, CONFIG_OPTION_AUTOCONVERT, 1);
|
config_set_option(&cfg, CONFIG_OPTION_AUTOCONVERT, 1);
|
||||||
#else
|
#else
|
||||||
config_set_auto_convert (&cfg, 1);
|
config_set_auto_convert (&cfg, 1);
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
group = config_lookup (&cfg, "main");
|
group = config_lookup (&cfg, "main");
|
||||||
|
|
||||||
if (group == NULL)
|
if (group == NULL)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
SMTPInPort = GetIntValue(group, "SMTPPort");
|
SMTPInPort = GetIntValue(group, "SMTPPort");
|
||||||
POP3InPort = GetIntValue(group, "POP3Port");
|
POP3InPort = GetIntValue(group, "POP3Port");
|
||||||
NNTPInPort = GetIntValue(group, "NNTPPort");
|
NNTPInPort = GetIntValue(group, "NNTPPort");
|
||||||
RemoteEmail = GetIntValue(group, "RemoteEmail");
|
RemoteEmail = GetIntValue(group, "RemoteEmail");
|
||||||
MaxStreams = GetIntValue(group, "Streams");
|
MaxStreams = GetIntValue(group, "Streams");
|
||||||
BBSApplNum = GetIntValue(group, "BBSApplNum");
|
BBSApplNum = GetIntValue(group, "BBSApplNum");
|
||||||
EnableUI = GetIntValue(group, "EnableUI");
|
EnableUI = GetIntValue(group, "EnableUI");
|
||||||
MailForInterval = GetIntValue(group, "MailForInterval");
|
MailForInterval = GetIntValue(group, "MailForInterval");
|
||||||
RefuseBulls = GetIntValue(group, "RefuseBulls");
|
RefuseBulls = GetIntValue(group, "RefuseBulls");
|
||||||
OnlyKnown = GetIntValue(group, "OnlyKnown");
|
OnlyKnown = GetIntValue(group, "OnlyKnown");
|
||||||
|
reportMailEvents = GetIntValue(group, "reportMailEvents");
|
||||||
|
|
||||||
SendSYStoSYSOPCall = GetIntValue(group, "SendSYStoSYSOPCall");
|
SendSYStoSYSOPCall = GetIntValue(group, "SendSYStoSYSOPCall");
|
||||||
SendBBStoSYSOPCall = GetIntValue(group, "SendBBStoSYSOPCall");
|
SendBBStoSYSOPCall = GetIntValue(group, "SendBBStoSYSOPCall");
|
||||||
DontHoldNewUsers = GetIntValue(group, "DontHoldNewUsers");
|
DontHoldNewUsers = GetIntValue(group, "DontHoldNewUsers");
|
||||||
|
@ -15793,3 +15776,62 @@ VOID GetPGConfig()
|
||||||
NUM_SERVERS = n;
|
NUM_SERVERS = n;
|
||||||
fclose(file);
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1123,8 +1123,9 @@
|
||||||
// Add FBB reject.sys style filters (3)
|
// Add FBB reject.sys style filters (3)
|
||||||
// Improve Webmail on 64 bit builds
|
// Improve Webmail on 64 bit builds
|
||||||
// Fix setting status '$' on Bulls sent via WebMail (22)
|
// 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 "bpqmail.h"
|
||||||
#include "winstdint.h"
|
#include "winstdint.h"
|
||||||
|
|
|
@ -316,6 +316,10 @@
|
||||||
RelativePath="..\CommonSource\LzmaLib.c"
|
RelativePath="..\CommonSource\LzmaLib.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\mailapi.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\CommonSource\MailCommands.c"
|
RelativePath="..\CommonSource\MailCommands.c"
|
||||||
>
|
>
|
||||||
|
|
|
@ -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="NOTTSDESKTOP"
|
||||||
|
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="NOTTSDESKTOP"
|
||||||
|
RemoteCommand=""
|
||||||
|
HttpUrl=""
|
||||||
|
PDBPath=""
|
||||||
|
SQLDebugging=""
|
||||||
|
Environment=""
|
||||||
|
EnvironmentMerge="true"
|
||||||
|
DebuggerFlavor=""
|
||||||
|
MPIRunCommand=""
|
||||||
|
MPIRunArguments=""
|
||||||
|
MPIRunWorkingDirectory=""
|
||||||
|
ApplicationCommand=""
|
||||||
|
ApplicationArguments=""
|
||||||
|
ShimCommand=""
|
||||||
|
MPIAcceptMode=""
|
||||||
|
MPIAcceptFilter=""
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
</VisualStudioUserFile>
|
13
Bpq32.c
13
Bpq32.c
|
@ -1086,7 +1086,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
|
||||||
// Add ? and * wildcards to NODES command (74)
|
// Add ? and * wildcards to NODES command (74)
|
||||||
// Add Port RADIO config parameter (74)
|
// Add Port RADIO config parameter (74)
|
||||||
|
|
||||||
// Version 6.0.24.1 August 2023
|
// Version 6.0.24.1 August 2024
|
||||||
|
|
||||||
// Apply NODES command wildcard to alias as well a call (2)
|
// Apply NODES command wildcard to alias as well a call (2)
|
||||||
// Add STOPPORT/STARTPORT to VARA Driver (2)
|
// Add STOPPORT/STARTPORT to VARA Driver (2)
|
||||||
|
@ -1203,6 +1203,11 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
|
||||||
// Improve restart of WinRPR TNC on remote host (21)
|
// Improve restart of WinRPR TNC on remote host (21)
|
||||||
// Fix some Rigcontrol issues with empty timebands (22)
|
// Fix some Rigcontrol issues with empty timebands (22)
|
||||||
// Fix 64 bit bug in processing INP3 Messages (22)
|
// Fix 64 bit bug in processing INP3 Messages (22)
|
||||||
|
// First pass at api (24)
|
||||||
|
// Send OK in response to Rigcontrol CMD (24)
|
||||||
|
// Disable CTS check in WriteComBlock (26)
|
||||||
|
// Improvments to reporting to M0LTE Map (26)
|
||||||
|
// IPGateway fix from github user isavitsky (27)
|
||||||
|
|
||||||
#define CKernel
|
#define CKernel
|
||||||
|
|
||||||
|
@ -2065,7 +2070,7 @@ VOID TimerProcX()
|
||||||
|
|
||||||
GetWindowRect(FrameWnd, &FRect);
|
GetWindowRect(FrameWnd, &FRect);
|
||||||
|
|
||||||
SaveWindowPos(64); // Rigcontrol
|
SaveWindowPos(70); // Rigcontrol
|
||||||
|
|
||||||
for (i=0;i<NUMBEROFPORTS;i++)
|
for (i=0;i<NUMBEROFPORTS;i++)
|
||||||
{
|
{
|
||||||
|
@ -2181,7 +2186,7 @@ VOID TimerProcX()
|
||||||
if(TimerInst == GetCurrentProcessId())
|
if(TimerInst == GetCurrentProcessId())
|
||||||
{
|
{
|
||||||
RigReconfigFlag = FALSE;
|
RigReconfigFlag = FALSE;
|
||||||
CloseDriverWindow(40);
|
CloseDriverWindow(70);
|
||||||
Rig_Close();
|
Rig_Close();
|
||||||
Sleep(6000); // Allow any CATPTT, HAMLIB and FLRIG threads to close
|
Sleep(6000); // Allow any CATPTT, HAMLIB and FLRIG threads to close
|
||||||
RigActive = Rig_Init();
|
RigActive = Rig_Init();
|
||||||
|
@ -6482,7 +6487,7 @@ VOID SaveBPQ32Windows()
|
||||||
PORTVEC=(PEXTPORTDATA)PORTVEC->PORTCONTROL.PORTPOINTER;
|
PORTVEC=(PEXTPORTDATA)PORTVEC->PORTCONTROL.PORTPOINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveWindowPos(40); // Rigcontrol
|
SaveWindowPos(70); // Rigcontrol
|
||||||
|
|
||||||
|
|
||||||
if (hIPResWnd)
|
if (hIPResWnd)
|
||||||
|
|
|
@ -438,6 +438,10 @@
|
||||||
RelativePath="..\CommonSource\MULTIPSK.c"
|
RelativePath="..\CommonSource\MULTIPSK.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\nodeapi.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\png.c"
|
RelativePath=".\png.c"
|
||||||
>
|
>
|
||||||
|
|
|
@ -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="NOTTSDESKTOP"
|
||||||
|
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="NOTTSDESKTOP"
|
||||||
|
RemoteCommand=""
|
||||||
|
HttpUrl=""
|
||||||
|
PDBPath=""
|
||||||
|
SQLDebugging=""
|
||||||
|
Environment=""
|
||||||
|
EnvironmentMerge="true"
|
||||||
|
DebuggerFlavor=""
|
||||||
|
MPIRunCommand=""
|
||||||
|
MPIRunArguments=""
|
||||||
|
MPIRunWorkingDirectory=""
|
||||||
|
ApplicationCommand=""
|
||||||
|
ApplicationArguments=""
|
||||||
|
ShimCommand=""
|
||||||
|
MPIAcceptMode=""
|
||||||
|
MPIAcceptFilter=""
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
</VisualStudioUserFile>
|
|
@ -406,7 +406,7 @@ extern BOOL CloseAllNeeded;
|
||||||
extern int CloseOnError;
|
extern int CloseOnError;
|
||||||
|
|
||||||
extern char * PortConfig[70];
|
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 MaxBPQPortNo 63 // Port 64 reserved for BBS Mon
|
||||||
#define MAXBPQPORTS 63
|
#define MAXBPQPORTS 63
|
||||||
|
|
|
@ -67,6 +67,7 @@ extern int MaxChatStreams;
|
||||||
extern char Position[81];
|
extern char Position[81];
|
||||||
extern char PopupText[251];
|
extern char PopupText[251];
|
||||||
extern int PopupMode;
|
extern int PopupMode;
|
||||||
|
extern int reportChatEvents;
|
||||||
|
|
||||||
#include "httpconnectioninfo.h"
|
#include "httpconnectioninfo.h"
|
||||||
|
|
||||||
|
@ -323,6 +324,8 @@ VOID SaveChatInfo(struct HTTPConnectionInfo * Session, char * MsgPtr, char * Rep
|
||||||
if (chatPaclen < 60)
|
if (chatPaclen < 60)
|
||||||
chatPaclen = 60;
|
chatPaclen = 60;
|
||||||
|
|
||||||
|
GetCheckBox(input, "Events=", &reportChatEvents);
|
||||||
|
|
||||||
GetParam(input, "nodes=", Nodes);
|
GetParam(input, "nodes=", Nodes);
|
||||||
|
|
||||||
ptr1 = Nodes;
|
ptr1 = Nodes;
|
||||||
|
@ -508,7 +511,9 @@ scan:
|
||||||
|
|
||||||
Len = sprintf(Reply, ChatConfigTemplate,
|
Len = sprintf(Reply, ChatConfigTemplate,
|
||||||
OurNode, Key, Key, Key,
|
OurNode, Key, Key, Key,
|
||||||
ChatApplNum, MaxChatStreams, Nodes, chatPaclen, Position,
|
ChatApplNum, MaxChatStreams,
|
||||||
|
(reportChatEvents) ? CHKD : UNC,
|
||||||
|
Nodes, chatPaclen, Position,
|
||||||
(PopupMode) ? UNC : CHKD,
|
(PopupMode) ? UNC : CHKD,
|
||||||
(PopupMode) ? CHKD : UNC, Text, ptr2);
|
(PopupMode) ? CHKD : UNC, Text, ptr2);
|
||||||
|
|
||||||
|
|
146
CommonCode.c
146
CommonCode.c
|
@ -49,7 +49,7 @@ extern struct CONFIGTABLE xxcfg;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct TNCINFO * TNCInfo[70]; // Records are Malloc'd
|
struct TNCINFO * TNCInfo[71]; // Records are Malloc'd
|
||||||
|
|
||||||
extern int ReportTimer;
|
extern int ReportTimer;
|
||||||
|
|
||||||
|
@ -917,8 +917,7 @@ BOOL ProcessIncommingConnectEx(struct TNCINFO * TNC, char * Call, int Stream, BO
|
||||||
PMSGWITHLEN buffptr;
|
PMSGWITHLEN buffptr;
|
||||||
int Totallen = 0;
|
int Totallen = 0;
|
||||||
UCHAR * ptr;
|
UCHAR * ptr;
|
||||||
struct PORTCONTROL * PORT = TNC->PortRecord;
|
struct PORTCONTROL * PORT = (struct PORTCONTROL *)TNC->PortRecord;
|
||||||
|
|
||||||
|
|
||||||
// Stop Scanner
|
// Stop Scanner
|
||||||
|
|
||||||
|
@ -2365,8 +2364,8 @@ BOOL WriteCOMBlock(HANDLE fd, char * Block, int BytesToWrite)
|
||||||
|
|
||||||
Err = GetCommModemStatus(fd, &Mask);
|
Err = GetCommModemStatus(fd, &Mask);
|
||||||
|
|
||||||
if ((Mask & MS_CTS_ON) == 0) // trap com0com other end not open
|
// if ((Mask & MS_CTS_ON) == 0) // trap com0com other end not open
|
||||||
return TRUE;
|
// return TRUE;
|
||||||
|
|
||||||
fWriteStat = WriteFile(fd, Block, BytesToWrite,
|
fWriteStat = WriteFile(fd, Block, BytesToWrite,
|
||||||
&BytesWritten, NULL );
|
&BytesWritten, NULL );
|
||||||
|
@ -3682,7 +3681,7 @@ VOID OpenReportingSockets()
|
||||||
{
|
{
|
||||||
// Enable Node Map Reports
|
// Enable Node Map Reports
|
||||||
|
|
||||||
ReportTimer = 600;
|
ReportTimer = 60;
|
||||||
|
|
||||||
ReportSocket = socket(AF_INET,SOCK_DGRAM,0);
|
ReportSocket = socket(AF_INET,SOCK_DGRAM,0);
|
||||||
|
|
||||||
|
@ -4877,7 +4876,7 @@ static char HeaderTemplate[] = "POST %s HTTP/1.1\r\n"
|
||||||
"Content-Type: application/json\r\n"
|
"Content-Type: application/json\r\n"
|
||||||
"Host: %s:%d\r\n"
|
"Host: %s:%d\r\n"
|
||||||
"Content-Length: %d\r\n"
|
"Content-Length: %d\r\n"
|
||||||
//r\nUser-Agent: BPQ32(G8BPQ)\r\n"
|
"User-Agent: %s%s\r\n"
|
||||||
// "Expect: 100-continue\r\n"
|
// "Expect: 100-continue\r\n"
|
||||||
"\r\n";
|
"\r\n";
|
||||||
|
|
||||||
|
@ -4891,7 +4890,11 @@ VOID SendWebRequest(SOCKET sock, char * Host, char * Request, char * Params, int
|
||||||
char * ptr, * ptr1;
|
char * ptr, * ptr1;
|
||||||
int Sent;
|
int Sent;
|
||||||
|
|
||||||
sprintf(Header, HeaderTemplate, Request, Host, 80, Len, Params);
|
#ifdef LINBPQ
|
||||||
|
sprintf(Header, HeaderTemplate, Request, Host, 80, Len, "linbpq/", VersionString, Params);
|
||||||
|
#else
|
||||||
|
sprintf(Header, HeaderTemplate, Request, Host, 80, Len, "bpq32/", VersionString, Params);
|
||||||
|
#endif
|
||||||
Sent = send(sock, Header, (int)strlen(Header), 0);
|
Sent = send(sock, Header, (int)strlen(Header), 0);
|
||||||
Sent = send(sock, Params, (int)strlen(Params), 0);
|
Sent = send(sock, Params, (int)strlen(Params), 0);
|
||||||
|
|
||||||
|
@ -4986,12 +4989,76 @@ VOID SendWebRequest(SOCKET sock, char * Host, char * Request, char * Params, int
|
||||||
extern char MYALIASLOPPED[10];
|
extern char MYALIASLOPPED[10];
|
||||||
extern int MasterPort[MAXBPQPORTS+1];
|
extern int MasterPort[MAXBPQPORTS+1];
|
||||||
|
|
||||||
|
|
||||||
|
// G7TAJ //
|
||||||
|
/*
|
||||||
|
{"mheard": [
|
||||||
|
{
|
||||||
|
"Callsign": "GB7CIP-7",
|
||||||
|
"Port": "VHF",
|
||||||
|
"Packets": 70369,
|
||||||
|
"LastHeard": "2024-12-29 20:26:32"
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
|
||||||
|
void BuildPortMH(char * MHJSON, struct PORTCONTROL * PORT)
|
||||||
|
{
|
||||||
|
struct tm * TM;
|
||||||
|
static char MHTIME[50];
|
||||||
|
time_t szClock;
|
||||||
|
MHSTRUC * MH = PORT->PORTMHEARD;
|
||||||
|
int count = MHENTRIES;
|
||||||
|
char Normcall[20];
|
||||||
|
int len;
|
||||||
|
char * ptr;
|
||||||
|
char mhstr[400];
|
||||||
|
|
||||||
|
if (MH == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (count--)
|
||||||
|
{
|
||||||
|
if (MH->MHCALL[0] == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
len = ConvFromAX25(MH->MHCALL, Normcall);
|
||||||
|
Normcall[len] = 0;
|
||||||
|
|
||||||
|
ptr = &MH->MHCALL[6]; // End of Address bit
|
||||||
|
|
||||||
|
if ((*ptr & 1) == 0)
|
||||||
|
{
|
||||||
|
// at least one digi - which we are not going to include
|
||||||
|
MH++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Normcall[len++] = 0;
|
||||||
|
|
||||||
|
//format TIME
|
||||||
|
|
||||||
|
szClock = MH->MHTIME;
|
||||||
|
TM = gmtime(&szClock);
|
||||||
|
sprintf(MHTIME, "%d-%d-%d %02d:%02d:%02d",
|
||||||
|
TM->tm_year+1900, TM->tm_mon + 1, TM->tm_mday, TM->tm_hour, TM->tm_min, TM->tm_sec);
|
||||||
|
|
||||||
|
sprintf(mhstr, "{\"callSign\": \"%s\", \"port\": \"%d\", \"packets\": %d, \"lastHeard\": \"%s\" },\r\n" ,
|
||||||
|
Normcall, PORT->PORTNUMBER, MH->MHCOUNT, MHTIME);
|
||||||
|
|
||||||
|
strcat( MHJSON, mhstr );
|
||||||
|
|
||||||
|
MH++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SendDataToPktMap(char *Msg)
|
void SendDataToPktMap(char *Msg)
|
||||||
{
|
{
|
||||||
SOCKET sock;
|
SOCKET sock;
|
||||||
char Return[256];
|
char Return[256];
|
||||||
char Request[64];
|
char Request[64];
|
||||||
char Params[50000];
|
char Params[50000];
|
||||||
|
|
||||||
struct PORTCONTROL * PORT = PORTTABLE;
|
struct PORTCONTROL * PORT = PORTTABLE;
|
||||||
struct PORTCONTROL * SAVEPORT;
|
struct PORTCONTROL * SAVEPORT;
|
||||||
struct ROUTE * Routes = NEIGHBOURS;
|
struct ROUTE * Routes = NEIGHBOURS;
|
||||||
|
@ -5012,10 +5079,19 @@ void SendDataToPktMap(char *Msg)
|
||||||
int Port = 0;
|
int Port = 0;
|
||||||
char Normcall[10];
|
char Normcall[10];
|
||||||
char Copy[20];
|
char Copy[20];
|
||||||
|
char ID[33];
|
||||||
|
|
||||||
char * ptr = Params;
|
char * ptr = Params;
|
||||||
|
|
||||||
printf("Sending to new map\n");
|
// G7TAJ //
|
||||||
|
char MHJSON[50000];
|
||||||
|
char * mhptr;
|
||||||
|
char * b4Routesptr;
|
||||||
|
|
||||||
|
MHJSON[0]=0;
|
||||||
|
// G7TAJ //
|
||||||
|
|
||||||
|
// printf("Sending to new map\n");
|
||||||
|
|
||||||
sprintf(Request, "/api/NodeData/%s", MYNODECALL);
|
sprintf(Request, "/api/NodeData/%s", MYNODECALL);
|
||||||
|
|
||||||
|
@ -5058,6 +5134,11 @@ void SendDataToPktMap(char *Msg)
|
||||||
#endif
|
#endif
|
||||||
ptr += sprintf(ptr, "\"source\": \"ReportedByNode\",\r\n");
|
ptr += sprintf(ptr, "\"source\": \"ReportedByNode\",\r\n");
|
||||||
|
|
||||||
|
// G7TAJ //
|
||||||
|
sprintf(MHJSON, ",\"mheard\": [");
|
||||||
|
// G7TAJ //
|
||||||
|
|
||||||
|
|
||||||
//Ports
|
//Ports
|
||||||
|
|
||||||
ptr += sprintf(ptr, "\"ports\": [");
|
ptr += sprintf(ptr, "\"ports\": [");
|
||||||
|
@ -5232,7 +5313,7 @@ void SendDataToPktMap(char *Msg)
|
||||||
|
|
||||||
// TCP
|
// TCP
|
||||||
|
|
||||||
Mode = Modenames[TNC->Hardware];
|
Mode = Modenames[TNC->Hardware - 1];
|
||||||
|
|
||||||
if (TNC->CONNECTED)
|
if (TNC->CONNECTED)
|
||||||
Active = 1;
|
Active = 1;
|
||||||
|
@ -5258,12 +5339,25 @@ void SendDataToPktMap(char *Msg)
|
||||||
|
|
||||||
if (Active)
|
if (Active)
|
||||||
{
|
{
|
||||||
|
char * ptr2 = &ID[29];
|
||||||
|
strcpy(ID, PORT->PORTDESCRIPTION);
|
||||||
|
while (*(ptr2) == ' ' && ptr2 != ID)
|
||||||
|
*(ptr2--) = 0;
|
||||||
|
|
||||||
ptr += sprintf(ptr, "{\"id\": \"%d\",\"linkType\": \"%s\","
|
ptr += sprintf(ptr, "{\"id\": \"%d\",\"linkType\": \"%s\","
|
||||||
"\"freq\": \"%lld\",\"mode\": \"%s\",\"modulation\": \"%s\","
|
"\"freq\": \"%lld\",\"mode\": \"%s\",\"modulation\": \"%s\","
|
||||||
"\"baud\": \"%d\",\"bitrate\": \"%d\",\"usage\": \"%s\",\"comment\": \"%s\"},\r\n",
|
"\"baud\": \"%d\",\"bitrate\": \"%d\",\"usage\": \"%s\",\"comment\": \"%s\"},\r\n",
|
||||||
PortNo, Type,
|
PortNo, Type,
|
||||||
Freq, Mode, Modulation,
|
Freq, Mode, Modulation,
|
||||||
Baud, Bitrate, "Access", PORT->PORTDESCRIPTION);
|
Baud, Bitrate, "Access", ID);
|
||||||
|
|
||||||
|
// G7TAJ //
|
||||||
|
// make MH list to be added later
|
||||||
|
BuildPortMH(MHJSON, PORT);
|
||||||
|
|
||||||
|
// G7TAJ //
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PORT = PORT->PORTPOINTER;
|
PORT = PORT->PORTPOINTER;
|
||||||
|
@ -5274,6 +5368,10 @@ void SendDataToPktMap(char *Msg)
|
||||||
|
|
||||||
// Neighbours
|
// Neighbours
|
||||||
|
|
||||||
|
// G7TAJ //
|
||||||
|
b4Routesptr = ptr-3;
|
||||||
|
// G7TAJ //
|
||||||
|
|
||||||
ptr += sprintf(ptr, "\"neighbours\": [\r\n");
|
ptr += sprintf(ptr, "\"neighbours\": [\r\n");
|
||||||
|
|
||||||
while (MaxRoutes--)
|
while (MaxRoutes--)
|
||||||
|
@ -5292,8 +5390,30 @@ void SendDataToPktMap(char *Msg)
|
||||||
Routes++;
|
Routes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr -= 3;
|
// G7TAJ //
|
||||||
ptr += sprintf(ptr, "]}");
|
|
||||||
|
// if !strstr quality, then there are none, so remove neighbours portion
|
||||||
|
if ( strstr(Params, "quality") == NULL ) {
|
||||||
|
ptr = b4Routesptr;
|
||||||
|
} else {
|
||||||
|
ptr -= 3;
|
||||||
|
ptr += sprintf(ptr, "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( strlen(MHJSON) > 15 ) {
|
||||||
|
mhptr = MHJSON + strlen(MHJSON);
|
||||||
|
mhptr -= 3;
|
||||||
|
sprintf(mhptr, "]\r\n");
|
||||||
|
ptr += sprintf(ptr, "\r\n%s", MHJSON);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr += sprintf(ptr, "}");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// G7TAJ //
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,13 +11,14 @@ void GetVersionInfo(char * File)
|
||||||
char isDebug[40]="";
|
char isDebug[40]="";
|
||||||
|
|
||||||
#ifdef SPECIALVERSION
|
#ifdef SPECIALVERSION
|
||||||
|
strcat(isDebug, " ");
|
||||||
strcat(isDebug, SPECIALVERSION);
|
strcat(isDebug, SPECIALVERSION);
|
||||||
#endif
|
#endif
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
strcat(isDebug, "Debug Build ");
|
strcat(isDebug, " Debug Build");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sprintf(VersionString,"%d.%d.%d.%d %s", Ver[0], Ver[1], Ver[2], Ver[3], isDebug);
|
sprintf(VersionString,"%d.%d.%d.%d%s", Ver[0], Ver[1], Ver[2], Ver[3], isDebug);
|
||||||
|
|
||||||
sprintf(TextVerstring,"V%d.%d.%d.%d", Ver[0], Ver[1], Ver[2], Ver[3]);
|
sprintf(TextVerstring,"V%d.%d.%d.%d", Ver[0], Ver[1], Ver[2], Ver[3]);
|
||||||
|
|
||||||
|
|
66
HTTPcode.c
66
HTTPcode.c
|
@ -69,6 +69,7 @@ int GetAPRSIcon(unsigned char * _REPLYBUFFER, char * NodeURL);
|
||||||
char * GetStandardPage(char * FN, int * Len);
|
char * GetStandardPage(char * FN, int * Len);
|
||||||
BOOL SHA1PasswordHash(char * String, char * Hash);
|
BOOL SHA1PasswordHash(char * String, char * Hash);
|
||||||
char * byte_base64_encode(char *str, int len);
|
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 struct ROUTE * NEIGHBOURS;
|
||||||
extern int ROUTE_LEN;
|
extern int ROUTE_LEN;
|
||||||
|
@ -1593,7 +1594,7 @@ int InnerProcessHTTPMessage(struct ConnectionInfo * conn)
|
||||||
char * Compressed = 0;
|
char * Compressed = 0;
|
||||||
char * HostPtr = 0;
|
char * HostPtr = 0;
|
||||||
|
|
||||||
char * Context, * Method, * NodeURL, * Key;
|
char * Context, * Method, * NodeURL = 0, * Key;
|
||||||
char _REPLYBUFFER[250000];
|
char _REPLYBUFFER[250000];
|
||||||
char Reply[250000];
|
char Reply[250000];
|
||||||
|
|
||||||
|
@ -1631,7 +1632,7 @@ int InnerProcessHTTPMessage(struct ConnectionInfo * conn)
|
||||||
|
|
||||||
char Encoding[] = "Content-Encoding: deflate\r\n";
|
char Encoding[] = "Content-Encoding: deflate\r\n";
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32xx
|
||||||
|
|
||||||
struct _EXCEPTION_POINTERS exinfo;
|
struct _EXCEPTION_POINTERS exinfo;
|
||||||
strcpy(EXCEPTMSG, "ProcessHTTPMessage");
|
strcpy(EXCEPTMSG, "ProcessHTTPMessage");
|
||||||
|
@ -1772,6 +1773,43 @@ int InnerProcessHTTPMessage(struct ConnectionInfo * conn)
|
||||||
strlop(Mycall, ' ');
|
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
|
// APRS process internally
|
||||||
|
|
||||||
if (_memicmp(Context, "/APRS/", 6) == 0 || _stricmp(Context, "/APRS") == 0)
|
if (_memicmp(Context, "/APRS/", 6) == 0 || _stricmp(Context, "/APRS") == 0)
|
||||||
|
@ -1874,7 +1912,8 @@ int InnerProcessHTTPMessage(struct ConnectionInfo * conn)
|
||||||
|
|
||||||
Session = FindSession(Key);
|
Session = FindSession(Key);
|
||||||
|
|
||||||
if (Session == NULL)
|
|
||||||
|
if (Session == NULL && _memicmp(Context, "/Mail/API/", 10) != 0)
|
||||||
{
|
{
|
||||||
ReplyLen = sprintf(Reply, MailLostSession, Key);
|
ReplyLen = sprintf(Reply, MailLostSession, Key);
|
||||||
RLen = ReplyLen;
|
RLen = ReplyLen;
|
||||||
|
@ -2025,10 +2064,13 @@ Returnit:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add tail
|
if (NodeURL && _memicmp(NodeURL, "/mail/api/", 10) != 0)
|
||||||
|
{
|
||||||
|
// Add tail
|
||||||
|
|
||||||
strcpy(&Reply[ReplyLen], Tail);
|
strcpy(&Reply[ReplyLen], Tail);
|
||||||
ReplyLen += strlen(Tail);
|
ReplyLen += strlen(Tail);
|
||||||
|
}
|
||||||
|
|
||||||
// compress if allowed
|
// compress if allowed
|
||||||
|
|
||||||
|
@ -2037,7 +2079,15 @@ Returnit:
|
||||||
else
|
else
|
||||||
Compressed = Reply;
|
Compressed = Reply;
|
||||||
|
|
||||||
HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n%s\r\n", ReplyLen, Encoding);
|
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, Header, HeaderLen);
|
||||||
sendandcheck(sock, Compressed, ReplyLen);
|
sendandcheck(sock, Compressed, ReplyLen);
|
||||||
|
|
||||||
|
@ -3889,7 +3939,7 @@ SendResp:
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32xx
|
||||||
}
|
}
|
||||||
#include "StdExcept.c"
|
#include "StdExcept.c"
|
||||||
}
|
}
|
||||||
|
|
24
HanksRT.c
24
HanksRT.c
|
@ -77,6 +77,8 @@ char PopupText[260] = "";
|
||||||
int PopupMode = 0;
|
int PopupMode = 0;
|
||||||
int chatPaclen = 236;
|
int chatPaclen = 236;
|
||||||
|
|
||||||
|
int reportChatEvents = 0;
|
||||||
|
|
||||||
char RtKnown[MAX_PATH] = "RTKnown.txt";
|
char RtKnown[MAX_PATH] = "RTKnown.txt";
|
||||||
char RtUsr[MAX_PATH] = "STUsers.txt";
|
char RtUsr[MAX_PATH] = "STUsers.txt";
|
||||||
char RtUsrTemp[MAX_PATH] = "STUsers.tmp";
|
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);
|
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.
|
// Send it to all connected users in the same topic.
|
||||||
// Echo to originator if requested.
|
// Echo to originator if requested.
|
||||||
|
|
||||||
|
@ -2109,14 +2123,6 @@ void text_tellu_Joined(USER * user)
|
||||||
nputc(circuit, 7);
|
nputc(circuit, 7);
|
||||||
|
|
||||||
nputc(circuit, 13);
|
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.
|
// Tell one link circuit about a local user change of topic.
|
||||||
|
@ -4170,6 +4176,7 @@ BOOL GetChatConfig(char * ConfigName)
|
||||||
|
|
||||||
ChatApplNum = GetIntValue(group, "ApplNum");
|
ChatApplNum = GetIntValue(group, "ApplNum");
|
||||||
MaxChatStreams = GetIntValue(group, "MaxStreams");
|
MaxChatStreams = GetIntValue(group, "MaxStreams");
|
||||||
|
reportChatEvents = GetIntValue(group, "reportChatEvents");
|
||||||
chatPaclen = GetIntValue(group, "chatPaclen");
|
chatPaclen = GetIntValue(group, "chatPaclen");
|
||||||
GetStringValue(group, "OtherChatNodes", OtherNodesList);
|
GetStringValue(group, "OtherChatNodes", OtherNodesList);
|
||||||
GetStringValue(group, "ChatWelcomeMsg", ChatWelcomeMsg);
|
GetStringValue(group, "ChatWelcomeMsg", ChatWelcomeMsg);
|
||||||
|
@ -4201,6 +4208,7 @@ VOID SaveChatConfigFile(char * ConfigName)
|
||||||
|
|
||||||
SaveIntValue(group, "ApplNum", ChatApplNum);
|
SaveIntValue(group, "ApplNum", ChatApplNum);
|
||||||
SaveIntValue(group, "MaxStreams", MaxChatStreams);
|
SaveIntValue(group, "MaxStreams", MaxChatStreams);
|
||||||
|
SaveIntValue(group, "reportChatEvents", reportChatEvents);
|
||||||
SaveIntValue(group, "chatPaclen", chatPaclen);
|
SaveIntValue(group, "chatPaclen", chatPaclen);
|
||||||
SaveStringValue(group, "OtherChatNodes", OtherNodesList);
|
SaveStringValue(group, "OtherChatNodes", OtherNodesList);
|
||||||
SaveStringValue(group, "ChatWelcomeMsg", ChatWelcomeMsg);
|
SaveStringValue(group, "ChatWelcomeMsg", ChatWelcomeMsg);
|
||||||
|
|
44
IPCode.c
44
IPCode.c
|
@ -4539,6 +4539,50 @@ void OpenTAP()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fix from github user isavitsky
|
||||||
|
|
||||||
|
/*
|
||||||
|
* After some research I found that on most of my
|
||||||
|
* systems, including Raspberry Pi IV, a slight delay
|
||||||
|
* is needed before considering the TAP device
|
||||||
|
* up and running. Otherwise the interface structures
|
||||||
|
* do not initialise properly and later in the code
|
||||||
|
* around the line 4700 when we initialise our ARP
|
||||||
|
* structure:
|
||||||
|
*
|
||||||
|
* memcpy(Arp->HWADDR, xbuffer.ifr_hwaddr.sa_data, 6);
|
||||||
|
*
|
||||||
|
* the MAC address is getting filled in with random
|
||||||
|
* value which makes the communication via our TAP
|
||||||
|
* device using the configured IPADDR virtually
|
||||||
|
* impossible.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
Debugprintf("Waiting for the TAP to become UP and RUNNING");
|
||||||
|
|
||||||
|
for (int i=10; i>0; i--)
|
||||||
|
{
|
||||||
|
Sleep(10);
|
||||||
|
|
||||||
|
if ((err = ioctl(sockfd, SIOCGIFFLAGS, &ifr)) < 0)
|
||||||
|
{
|
||||||
|
perror("SIOCGIFFLAGS");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((ifr.ifr_flags & IFF_UP) && (ifr.ifr_flags & IFF_RUNNING))
|
||||||
|
{
|
||||||
|
Debugprintf("TAP is UP and RUNNING");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (i == 1)
|
||||||
|
{
|
||||||
|
Debugprintf("TAP is still not UP and RUNNING");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
printf("TAP brought up\n");
|
printf("TAP brought up\n");
|
||||||
|
|
||||||
// Set MTU to 256
|
// Set MTU to 256
|
||||||
|
|
|
@ -23,6 +23,9 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
|
||||||
|
|
||||||
#include "bpqmail.h"
|
#include "bpqmail.h"
|
||||||
|
|
||||||
|
void SendMessageReadEvent(struct UserInfo * user, struct MsgInfo * Msg);
|
||||||
|
|
||||||
|
|
||||||
VOID ProcessMBLLine(CIRCUIT * conn, struct UserInfo * user, UCHAR* Buffer, int len)
|
VOID ProcessMBLLine(CIRCUIT * conn, struct UserInfo * user, UCHAR* Buffer, int len)
|
||||||
{
|
{
|
||||||
Buffer[len] = 0;
|
Buffer[len] = 0;
|
||||||
|
@ -86,6 +89,7 @@ VOID ProcessMBLLine(CIRCUIT * conn, struct UserInfo * user, UCHAR* Buffer, int l
|
||||||
FBBputs(conn, ">\r");
|
FBBputs(conn, ">\r");
|
||||||
Msg->status = 'Y'; // Mark as read
|
Msg->status = 'Y'; // Mark as read
|
||||||
SaveMessageDatabase();
|
SaveMessageDatabase();
|
||||||
|
SendMessageReadEvent(user->Call, Msg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -424,6 +424,10 @@
|
||||||
RelativePath="..\CommonSource\LzmaLib.c"
|
RelativePath="..\CommonSource\LzmaLib.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\mailapi.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\CommonSource\MailCommands.c"
|
RelativePath="..\CommonSource\MailCommands.c"
|
||||||
>
|
>
|
||||||
|
@ -464,6 +468,10 @@
|
||||||
RelativePath="..\CommonSource\NNTPRoutines.c"
|
RelativePath="..\CommonSource\NNTPRoutines.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\nodeapi.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\CommonSource\pibits.c"
|
RelativePath="..\CommonSource\pibits.c"
|
||||||
>
|
>
|
||||||
|
|
240
NNTPRoutines.c
240
NNTPRoutines.c
|
@ -41,6 +41,87 @@ char *day[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
|
||||||
|
|
||||||
VOID ReleaseNNTPSock(SOCKET sock);
|
VOID ReleaseNNTPSock(SOCKET sock);
|
||||||
|
|
||||||
|
int NNTPSendSock(SocketConn * sockptr, char * msg)
|
||||||
|
{
|
||||||
|
int len = (int)strlen(msg);
|
||||||
|
char * newmsg = malloc(len+10);
|
||||||
|
|
||||||
|
WriteLogLine(NULL, '>',msg, len, LOG_TCP);
|
||||||
|
|
||||||
|
strcpy(newmsg, msg);
|
||||||
|
|
||||||
|
strcat(newmsg, "\r\n");
|
||||||
|
|
||||||
|
len+=2;
|
||||||
|
|
||||||
|
// Attempt to fix Thunderbird - Queue all and send at end
|
||||||
|
|
||||||
|
if ((sockptr->SendSize + len) > sockptr->SendBufferSize)
|
||||||
|
{
|
||||||
|
sockptr->SendBufferSize += (10000 + len);
|
||||||
|
sockptr->SendBuffer = realloc(sockptr->SendBuffer, sockptr->SendBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&sockptr->SendBuffer[sockptr->SendSize], newmsg, len);
|
||||||
|
sockptr->SendSize += len;
|
||||||
|
free (newmsg);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NNTPFlush(SocketConn * sockptr)
|
||||||
|
{
|
||||||
|
int sent;
|
||||||
|
|
||||||
|
sent = send(sockptr->socket, sockptr->SendBuffer, sockptr->SendSize, 0);
|
||||||
|
|
||||||
|
if (sent < sockptr->SendSize)
|
||||||
|
{
|
||||||
|
int error, remains;
|
||||||
|
|
||||||
|
// Not all could be sent - queue rest
|
||||||
|
|
||||||
|
if (sent == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
error = WSAGetLastError();
|
||||||
|
if (error == WSAEWOULDBLOCK)
|
||||||
|
sent=0;
|
||||||
|
|
||||||
|
// What else??
|
||||||
|
}
|
||||||
|
|
||||||
|
remains = sockptr->SendSize - sent;
|
||||||
|
|
||||||
|
sockptr->SendBufferSize += (10000 + remains);
|
||||||
|
sockptr->SendBuffer = malloc(sockptr->SendBufferSize);
|
||||||
|
|
||||||
|
memmove(sockptr->SendBuffer, &sockptr->SendBuffer[sent], remains);
|
||||||
|
|
||||||
|
sockptr->SendSize = remains;
|
||||||
|
sockptr->SendPtr = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(sockptr->SendBuffer);
|
||||||
|
sockptr->SendBuffer = NULL;
|
||||||
|
sockptr->SendSize = 0;
|
||||||
|
sockptr->SendBufferSize = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID __cdecl NNTPsockprintf(SocketConn * sockptr, const char * format, ...)
|
||||||
|
{
|
||||||
|
// printf to a socket
|
||||||
|
|
||||||
|
char buff[1000];
|
||||||
|
va_list(arglist);
|
||||||
|
|
||||||
|
va_start(arglist, format);
|
||||||
|
vsprintf(buff, format, arglist);
|
||||||
|
|
||||||
|
NNTPSendSock(sockptr, buff);
|
||||||
|
}
|
||||||
|
|
||||||
struct NNTPRec * LookupNNTP(char * Group)
|
struct NNTPRec * LookupNNTP(char * Group)
|
||||||
{
|
{
|
||||||
struct NNTPRec * ptr = FirstNNTPRec;
|
struct NNTPRec * ptr = FirstNNTPRec;
|
||||||
|
@ -304,7 +385,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
if (ptr2 == NULL)
|
if (ptr2 == NULL)
|
||||||
{
|
{
|
||||||
SendSock(sockptr, "500 Eh");
|
NNTPSendSock(sockptr, "500 Eh");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,7 +509,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
sockptr->Flags &= ~GETTINGMESSAGE;
|
sockptr->Flags &= ~GETTINGMESSAGE;
|
||||||
|
|
||||||
SendSock(sockptr, "240 OK");
|
NNTPSendSock(sockptr, "240 OK");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -459,13 +540,13 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
if (Len > 22) Buffer[22]=0;
|
if (Len > 22) Buffer[22]=0;
|
||||||
strcpy(sockptr->CallSign, &Buffer[14]);
|
strcpy(sockptr->CallSign, &Buffer[14]);
|
||||||
sockptr->State = GettingPass;
|
sockptr->State = GettingPass;
|
||||||
sockprintf(sockptr, "381 More authentication information required");
|
NNTPsockprintf(sockptr, "381 More authentication information required");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sockptr->State == GettingUser)
|
if (sockptr->State == GettingUser)
|
||||||
{
|
{
|
||||||
sockprintf(sockptr, "480 Authentication required");
|
NNTPsockprintf(sockptr, "480 Authentication required");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,19 +562,19 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
{
|
{
|
||||||
if (strcmp(user->pass, &Buffer[14]) == 0)
|
if (strcmp(user->pass, &Buffer[14]) == 0)
|
||||||
{
|
{
|
||||||
sockprintf(sockptr, "281 Authentication accepted");
|
NNTPsockprintf(sockptr, "281 Authentication accepted");
|
||||||
|
|
||||||
sockptr->State = Authenticated;
|
sockptr->State = Authenticated;
|
||||||
sockptr->POP3User = user;
|
sockptr->POP3User = user;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SendSock(sockptr, "482 Authentication rejected");
|
NNTPSendSock(sockptr, "482 Authentication rejected");
|
||||||
sockptr->State = GettingUser;
|
sockptr->State = GettingUser;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sockprintf(sockptr, "480 Authentication required");
|
NNTPsockprintf(sockptr, "480 Authentication required");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,7 +587,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
{
|
{
|
||||||
if (_stricmp(REC->NewsGroup, &Buffer[6]) == 0)
|
if (_stricmp(REC->NewsGroup, &Buffer[6]) == 0)
|
||||||
{
|
{
|
||||||
sockprintf(sockptr, "211 %d %d %d %s", REC->Count, REC->FirstMsg, REC->LastMsg, REC->NewsGroup);
|
NNTPsockprintf(sockptr, "211 %d %d %d %s", REC->Count, REC->FirstMsg, REC->LastMsg, REC->NewsGroup);
|
||||||
sockptr->NNTPNum = 0;
|
sockptr->NNTPNum = 0;
|
||||||
sockptr->NNTPGroup = REC;
|
sockptr->NNTPGroup = REC;
|
||||||
return;
|
return;
|
||||||
|
@ -514,7 +595,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
REC =REC->Next;
|
REC =REC->Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
sockprintf(sockptr, "411 no such news group");
|
NNTPsockprintf(sockptr, "411 no such news group");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,7 +609,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
if (REC == NULL && Buffer[10] == 0)
|
if (REC == NULL && Buffer[10] == 0)
|
||||||
{
|
{
|
||||||
sockprintf(sockptr, "412 No Group Selected");
|
NNTPsockprintf(sockptr, "412 No Group Selected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,7 +624,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
{
|
{
|
||||||
GotGroup:
|
GotGroup:
|
||||||
|
|
||||||
sockprintf(sockptr, "211 Article Numbers Follows");
|
NNTPsockprintf(sockptr, "211 Article Numbers Follows");
|
||||||
sockptr->NNTPNum = 0;
|
sockptr->NNTPNum = 0;
|
||||||
sockptr->NNTPGroup = REC;
|
sockptr->NNTPGroup = REC;
|
||||||
|
|
||||||
|
@ -557,22 +638,22 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
sprintf(FullGroup, "%s.%s", Msg->to, Msg->via );
|
sprintf(FullGroup, "%s.%s", Msg->to, Msg->via );
|
||||||
if (_stricmp(FullGroup, REC->NewsGroup) == 0)
|
if (_stricmp(FullGroup, REC->NewsGroup) == 0)
|
||||||
{
|
{
|
||||||
sockprintf(sockptr, "%d", MsgNo);
|
NNTPsockprintf(sockptr, "%d", MsgNo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SendSock(sockptr,".");
|
NNTPSendSock(sockptr,".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
REC = REC->Next;
|
REC = REC->Next;
|
||||||
}
|
}
|
||||||
sockprintf(sockptr, "411 no such news group");
|
NNTPsockprintf(sockptr, "411 no such news group");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_memicmp(Buffer, "MODE READER", 11) == 0)
|
if(_memicmp(Buffer, "MODE READER", 11) == 0)
|
||||||
{
|
{
|
||||||
SendSock(sockptr, "200 Hello");
|
NNTPSendSock(sockptr, "200 Hello");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,15 +661,15 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
{
|
{
|
||||||
struct NNTPRec * REC = FirstNNTPRec;
|
struct NNTPRec * REC = FirstNNTPRec;
|
||||||
|
|
||||||
SendSock(sockptr, "215 list of newsgroups follows");
|
NNTPSendSock(sockptr, "215 list of newsgroups follows");
|
||||||
|
|
||||||
while (REC)
|
while (REC)
|
||||||
{
|
{
|
||||||
sockprintf(sockptr, "%s %d %d y", REC->NewsGroup, REC->LastMsg, REC->FirstMsg);
|
NNTPsockprintf(sockptr, "%s %d %d y", REC->NewsGroup, REC->LastMsg, REC->FirstMsg);
|
||||||
REC = REC->Next;
|
REC = REC->Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendSock(sockptr,".");
|
NNTPSendSock(sockptr,".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,16 +696,16 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
else
|
else
|
||||||
Time = mktime(&rtime);
|
Time = mktime(&rtime);
|
||||||
|
|
||||||
SendSock(sockptr, "231 list of new newsgroups follows");
|
NNTPSendSock(sockptr, "231 list of new newsgroups follows");
|
||||||
|
|
||||||
while(REC)
|
while(REC)
|
||||||
{
|
{
|
||||||
if (REC->DateCreated > Time)
|
if (REC->DateCreated > Time)
|
||||||
sockprintf(sockptr, "%s %d %d y", REC->NewsGroup, REC->LastMsg, REC->FirstMsg);
|
NNTPsockprintf(sockptr, "%s %d %d y", REC->NewsGroup, REC->LastMsg, REC->FirstMsg);
|
||||||
REC = REC->Next;
|
REC = REC->Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendSock(sockptr,".");
|
NNTPSendSock(sockptr,".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,7 +717,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
if (REC == NULL)
|
if (REC == NULL)
|
||||||
{
|
{
|
||||||
SendSock(sockptr,"412 no newsgroup has been selected");
|
NNTPSendSock(sockptr,"412 no newsgroup has been selected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,7 +727,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
if (MsgNo == 0)
|
if (MsgNo == 0)
|
||||||
{
|
{
|
||||||
SendSock(sockptr,"420 no current article has been selected");
|
NNTPSendSock(sockptr,"420 no current article has been selected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -659,20 +740,20 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
if (Msg)
|
if (Msg)
|
||||||
{
|
{
|
||||||
sockprintf(sockptr, "221 %d <%s>", MsgNo, Msg->bid);
|
NNTPsockprintf(sockptr, "221 %d <%s>", MsgNo, Msg->bid);
|
||||||
|
|
||||||
sockprintf(sockptr, "From: %s", Msg->from);
|
NNTPsockprintf(sockptr, "From: %s", Msg->from);
|
||||||
sockprintf(sockptr, "Date: %s", FormatNNTPDateAndTime((time_t)Msg->datecreated));
|
NNTPsockprintf(sockptr, "Date: %s", FormatNNTPDateAndTime((time_t)Msg->datecreated));
|
||||||
sockprintf(sockptr, "Newsgroups: %s.s", Msg->to, Msg->via);
|
NNTPsockprintf(sockptr, "Newsgroups: %s.s", Msg->to, Msg->via);
|
||||||
sockprintf(sockptr, "Subject: %s", Msg->title);
|
NNTPsockprintf(sockptr, "Subject: %s", Msg->title);
|
||||||
sockprintf(sockptr, "Message-ID: <%s>", Msg->bid);
|
NNTPsockprintf(sockptr, "Message-ID: <%s>", Msg->bid);
|
||||||
sockprintf(sockptr, "Path: %s", BBSName);
|
NNTPsockprintf(sockptr, "Path: %s", BBSName);
|
||||||
|
|
||||||
SendSock(sockptr,".");
|
NNTPSendSock(sockptr,".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendSock(sockptr,"423 No such article in this newsgroup");
|
NNTPSendSock(sockptr,"423 No such article in this newsgroup");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -686,7 +767,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
if (REC == NULL)
|
if (REC == NULL)
|
||||||
{
|
{
|
||||||
SendSock(sockptr,"412 no newsgroup has been selected");
|
NNTPSendSock(sockptr,"412 no newsgroup has been selected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,7 +777,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
if (MsgNo == 0)
|
if (MsgNo == 0)
|
||||||
{
|
{
|
||||||
SendSock(sockptr,"420 no current article has been selected");
|
NNTPSendSock(sockptr,"420 no current article has been selected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -709,25 +790,25 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
if (Msg)
|
if (Msg)
|
||||||
{
|
{
|
||||||
sockprintf(sockptr, "220 %d <%s>", MsgNo, Msg->bid);
|
NNTPsockprintf(sockptr, "220 %d <%s>", MsgNo, Msg->bid);
|
||||||
msgbytes = ReadMessageFile(Msg->number);
|
msgbytes = ReadMessageFile(Msg->number);
|
||||||
|
|
||||||
Path = GetPathFromHeaders(msgbytes);
|
Path = GetPathFromHeaders(msgbytes);
|
||||||
|
|
||||||
sockprintf(sockptr, "From: %s", Msg->from);
|
NNTPsockprintf(sockptr, "From: %s", Msg->from);
|
||||||
sockprintf(sockptr, "Date: %s", FormatNNTPDateAndTime((time_t)Msg->datecreated));
|
NNTPsockprintf(sockptr, "Date: %s", FormatNNTPDateAndTime((time_t)Msg->datecreated));
|
||||||
sockprintf(sockptr, "Newsgroups: %s.%s", Msg->to, Msg->via);
|
NNTPsockprintf(sockptr, "Newsgroups: %s.%s", Msg->to, Msg->via);
|
||||||
sockprintf(sockptr, "Subject: %s", Msg->title);
|
NNTPsockprintf(sockptr, "Subject: %s", Msg->title);
|
||||||
sockprintf(sockptr, "Message-ID: <%s>", Msg->bid);
|
NNTPsockprintf(sockptr, "Message-ID: <%s>", Msg->bid);
|
||||||
sockprintf(sockptr, "Path: %s", &Path[1]);
|
NNTPsockprintf(sockptr, "Path: %s", &Path[1]);
|
||||||
|
|
||||||
SendSock(sockptr,"");
|
NNTPSendSock(sockptr,"");
|
||||||
|
|
||||||
|
|
||||||
SendSock(sockptr,msgbytes);
|
NNTPSendSock(sockptr,msgbytes);
|
||||||
SendSock(sockptr,"");
|
NNTPSendSock(sockptr,"");
|
||||||
|
|
||||||
SendSock(sockptr,".");
|
NNTPSendSock(sockptr,".");
|
||||||
|
|
||||||
free(msgbytes);
|
free(msgbytes);
|
||||||
free(Path);
|
free(Path);
|
||||||
|
@ -735,7 +816,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
SendSock(sockptr,"423 No such article in this newsgroup");
|
NNTPSendSock(sockptr,"423 No such article in this newsgroup");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -749,7 +830,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
if (REC == NULL)
|
if (REC == NULL)
|
||||||
{
|
{
|
||||||
SendSock(sockptr,"412 no newsgroup has been selected");
|
NNTPSendSock(sockptr,"412 no newsgroup has been selected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -759,7 +840,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
if (MsgNo == 0)
|
if (MsgNo == 0)
|
||||||
{
|
{
|
||||||
SendSock(sockptr,"420 no current article has been selected");
|
NNTPSendSock(sockptr,"420 no current article has been selected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -772,15 +853,15 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
if (Msg)
|
if (Msg)
|
||||||
{
|
{
|
||||||
sockprintf(sockptr, "222 %d <%s>", MsgNo, Msg->bid);
|
NNTPsockprintf(sockptr, "222 %d <%s>", MsgNo, Msg->bid);
|
||||||
msgbytes = ReadMessageFile(Msg->number);
|
msgbytes = ReadMessageFile(Msg->number);
|
||||||
|
|
||||||
Path = GetPathFromHeaders(msgbytes);
|
Path = GetPathFromHeaders(msgbytes);
|
||||||
|
|
||||||
SendSock(sockptr,msgbytes);
|
NNTPSendSock(sockptr,msgbytes);
|
||||||
SendSock(sockptr,"");
|
NNTPSendSock(sockptr,"");
|
||||||
|
|
||||||
SendSock(sockptr,".");
|
NNTPSendSock(sockptr,".");
|
||||||
|
|
||||||
free(msgbytes);
|
free(msgbytes);
|
||||||
free(Path);
|
free(Path);
|
||||||
|
@ -788,7 +869,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
SendSock(sockptr,"423 No such article in this newsgroup");
|
NNTPSendSock(sockptr,"423 No such article in this newsgroup");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,7 +882,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
if (REC == NULL)
|
if (REC == NULL)
|
||||||
{
|
{
|
||||||
SendSock(sockptr,"412 no newsgroup has been selected");
|
NNTPSendSock(sockptr,"412 no newsgroup has been selected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -821,7 +902,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
if (MsgStart == 0)
|
if (MsgStart == 0)
|
||||||
{
|
{
|
||||||
SendSock(sockptr,"420 no current article has been selected");
|
NNTPSendSock(sockptr,"420 no current article has been selected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -830,7 +911,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
sockptr->NNTPNum = MsgEnd;
|
sockptr->NNTPNum = MsgEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
sockprintf(sockptr, "221 ");
|
NNTPsockprintf(sockptr, "221 ");
|
||||||
|
|
||||||
for (MsgNo = MsgStart; MsgNo <= MsgEnd; MsgNo++)
|
for (MsgNo = MsgStart; MsgNo <= MsgEnd; MsgNo++)
|
||||||
{
|
{
|
||||||
|
@ -843,20 +924,20 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
if (_stricmp(FullGroup, REC->NewsGroup) == 0)
|
if (_stricmp(FullGroup, REC->NewsGroup) == 0)
|
||||||
{
|
{
|
||||||
if (_stricmp(Header, "subject") == 0)
|
if (_stricmp(Header, "subject") == 0)
|
||||||
sockprintf(sockptr, "%d Subject: %s", MsgNo, Msg->title);
|
NNTPsockprintf(sockptr, "%d Subject: %s", MsgNo, Msg->title);
|
||||||
else if (_stricmp(Header, "from") == 0)
|
else if (_stricmp(Header, "from") == 0)
|
||||||
sockprintf(sockptr, "%d From: %s", MsgNo, Msg->from);
|
NNTPsockprintf(sockptr, "%d From: %s", MsgNo, Msg->from);
|
||||||
else if (_stricmp(Header, "date") == 0)
|
else if (_stricmp(Header, "date") == 0)
|
||||||
sockprintf(sockptr, "%d Date: %s", MsgNo, FormatNNTPDateAndTime((time_t)Msg->datecreated));
|
NNTPsockprintf(sockptr, "%d Date: %s", MsgNo, FormatNNTPDateAndTime((time_t)Msg->datecreated));
|
||||||
else if (_stricmp(Header, "message-id") == 0)
|
else if (_stricmp(Header, "message-id") == 0)
|
||||||
sockprintf(sockptr, "%d Message-ID: <%s>", MsgNo, Msg->bid);
|
NNTPsockprintf(sockptr, "%d Message-ID: <%s>", MsgNo, Msg->bid);
|
||||||
else if (_stricmp(Header, "lines") == 0)
|
else if (_stricmp(Header, "lines") == 0)
|
||||||
sockprintf(sockptr, "%d Lines: %d", MsgNo, Msg->length);
|
NNTPsockprintf(sockptr, "%d Lines: %d", MsgNo, Msg->length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SendSock(sockptr,".");
|
NNTPSendSock(sockptr,".");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -869,7 +950,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
if (REC == NULL)
|
if (REC == NULL)
|
||||||
{
|
{
|
||||||
SendSock(sockptr,"412 no newsgroup has been selected");
|
NNTPSendSock(sockptr,"412 no newsgroup has been selected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -887,7 +968,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
if (MsgStart == 0)
|
if (MsgStart == 0)
|
||||||
{
|
{
|
||||||
SendSock(sockptr,"420 no current article has been selected");
|
NNTPSendSock(sockptr,"420 no current article has been selected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -896,7 +977,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
sockptr->NNTPNum = MsgEnd;
|
sockptr->NNTPNum = MsgEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
sockprintf(sockptr, "224 ");
|
NNTPsockprintf(sockptr, "224 ");
|
||||||
|
|
||||||
for (MsgNo = MsgStart; MsgNo <= MsgEnd; MsgNo++)
|
for (MsgNo = MsgStart; MsgNo <= MsgEnd; MsgNo++)
|
||||||
{
|
{
|
||||||
|
@ -909,14 +990,14 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
if (_stricmp(FullGroup, REC->NewsGroup) == 0)
|
if (_stricmp(FullGroup, REC->NewsGroup) == 0)
|
||||||
{
|
{
|
||||||
// subject, author, date, message-id, references, byte count, and line count.
|
// subject, author, date, message-id, references, byte count, and line count.
|
||||||
sockprintf(sockptr, "%d\t%s\t%s\t%s\t%s\t%s\t%d\t%d",
|
NNTPsockprintf(sockptr, "%d\t%s\t%s\t%s\t%s\t%s\t%d\t%d",
|
||||||
MsgNo, Msg->title, Msg->from, FormatNNTPDateAndTime((time_t)Msg->datecreated), Msg->bid,
|
MsgNo, Msg->title, Msg->from, FormatNNTPDateAndTime((time_t)Msg->datecreated), Msg->bid,
|
||||||
"", Msg->length, Msg->length);
|
"", Msg->length, Msg->length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SendSock(sockptr,".");
|
NNTPSendSock(sockptr,".");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -932,7 +1013,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
{
|
{
|
||||||
if (sockptr->State != Authenticated)
|
if (sockptr->State != Authenticated)
|
||||||
{
|
{
|
||||||
sockprintf(sockptr, "480 Authentication required");
|
NNTPsockprintf(sockptr, "480 Authentication required");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -942,7 +1023,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
if (sockptr->MailBuffer == NULL)
|
if (sockptr->MailBuffer == NULL)
|
||||||
{
|
{
|
||||||
CriticalErrorHandler("Failed to create POP3 Message Buffer");
|
CriticalErrorHandler("Failed to create POP3 Message Buffer");
|
||||||
SendSock(sockptr, "QUIT");
|
NNTPSendSock(sockptr, "QUIT");
|
||||||
sockptr->State = WaitingForQUITResponse;
|
sockptr->State = WaitingForQUITResponse;
|
||||||
shutdown(sock, 0);
|
shutdown(sock, 0);
|
||||||
|
|
||||||
|
@ -951,7 +1032,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
sockptr->Flags |= GETTINGMESSAGE;
|
sockptr->Flags |= GETTINGMESSAGE;
|
||||||
|
|
||||||
SendSock(sockptr, "340 OK");
|
NNTPSendSock(sockptr, "340 OK");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -959,7 +1040,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
if(_memicmp(Buffer, "QUIT", 4) == 0)
|
if(_memicmp(Buffer, "QUIT", 4) == 0)
|
||||||
{
|
{
|
||||||
SendSock(sockptr, "205 OK");
|
NNTPSendSock(sockptr, "205 OK");
|
||||||
Sleep(500);
|
Sleep(500);
|
||||||
shutdown(sock, 0);
|
shutdown(sock, 0);
|
||||||
return;
|
return;
|
||||||
|
@ -967,7 +1048,7 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
|
|
||||||
/* if(memcmp(Buffer, "RSET\r\n", 6) == 0)
|
/* if(memcmp(Buffer, "RSET\r\n", 6) == 0)
|
||||||
{
|
{
|
||||||
SendSock(sockptr, "250 Ok");
|
NNTPSendSock(sockptr, "250 Ok");
|
||||||
sockptr->State = 0;
|
sockptr->State = 0;
|
||||||
sockptr->Recipients;
|
sockptr->Recipients;
|
||||||
return;
|
return;
|
||||||
|
@ -991,15 +1072,15 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
|
||||||
sprintf_s(Date, sizeof(Date), "111 %04d%02d%02d%02d%02d%02d",
|
sprintf_s(Date, sizeof(Date), "111 %04d%02d%02d%02d%02d%02d",
|
||||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||||
|
|
||||||
SendSock(sockptr, Date);
|
NNTPSendSock(sockptr, Date);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SendSock(sockptr, "500 command not recognized");
|
NNTPSendSock(sockptr, "500 command not recognized");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendSock(sockptr, "500 command not recognized");
|
NNTPSendSock(sockptr, "500 command not recognized");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1068,6 +1149,9 @@ loop:
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NNTPFlush(sockptr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1110,9 +1194,11 @@ int NNTP_Accept(SOCKET SocketId)
|
||||||
sockptr->socket = sock;
|
sockptr->socket = sock;
|
||||||
sockptr->State = 0;
|
sockptr->State = 0;
|
||||||
|
|
||||||
SendSock(sockptr, "200 BPQMail NNTP Server ready");
|
NNTPSendSock(sockptr, "200 BPQMail NNTP Server ready");
|
||||||
Logprintf(LOG_TCP, NULL, '|', "Incoming NNTP Connect Socket = %d", sock);
|
Logprintf(LOG_TCP, NULL, '|', "Incoming NNTP Connect Socket = %d", sock);
|
||||||
|
|
||||||
|
NNTPFlush(sockptr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -1144,7 +1230,7 @@ int NNTP_Data(int sock, int error, int eventcode)
|
||||||
SendFromQueue(sockptr);
|
SendFromQueue(sockptr);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SendSock(sockptr, "200 BPQMail NNTP Server ready");
|
NNTPSendSock(sockptr, "200 BPQMail NNTP Server ready");
|
||||||
// sockptr->State = GettingUser;
|
// sockptr->State = GettingUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
RigControl.c
11
RigControl.c
|
@ -1142,7 +1142,6 @@ int Rig_CommandEx(struct RIGPORTINFO * PORT, struct RIGINFO * RIG, TRANSPORTENTR
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Build a ScanEntry in the buffer
|
// Build a ScanEntry in the buffer
|
||||||
|
|
||||||
FreqPtr = (struct ScanEntry *)buffptr->Data;
|
FreqPtr = (struct ScanEntry *)buffptr->Data;
|
||||||
|
@ -1277,8 +1276,6 @@ int Rig_CommandEx(struct RIGPORTINFO * PORT, struct RIGINFO * RIG, TRANSPORTENTR
|
||||||
}
|
}
|
||||||
|
|
||||||
*(CmdPtr++) = 0xFD;
|
*(CmdPtr++) = 0xFD;
|
||||||
|
|
||||||
|
|
||||||
*(CmdPtr) = 0;
|
*(CmdPtr) = 0;
|
||||||
|
|
||||||
Len = (int)(CmdPtr - (char *)&buffptr[30]);
|
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
|
FreqPtr[0].Cmd1Len = Len; // for ICOM
|
||||||
C_Q_ADD(&RIG->BPQtoRADIO_Q, buffptr);
|
C_Q_ADD(&RIG->BPQtoRADIO_Q, buffptr);
|
||||||
return TRUE;
|
|
||||||
|
sprintf(Command, "Ok\r");
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_memicmp(FreqString, "Chan", 4) == 0)
|
if (_memicmp(FreqString, "Chan", 4) == 0)
|
||||||
|
@ -2203,7 +2202,7 @@ DllExport BOOL APIENTRY Rig_Init()
|
||||||
|
|
||||||
memset(&RIGTNC, 0, sizeof(struct TNCINFO));
|
memset(&RIGTNC, 0, sizeof(struct TNCINFO));
|
||||||
|
|
||||||
TNCInfo[40] = TNC;
|
TNCInfo[70] = TNC;
|
||||||
|
|
||||||
// Get config info
|
// Get config info
|
||||||
|
|
||||||
|
@ -2229,7 +2228,7 @@ DllExport BOOL APIENTRY Rig_Init()
|
||||||
|
|
||||||
#ifndef LINBPQ
|
#ifndef LINBPQ
|
||||||
|
|
||||||
TNC->Port = 40;
|
TNC->Port = 70;
|
||||||
CreatePactorWindow(TNC, "RIGCONTROL", "RigControl", 10, PacWndProc, 550, NeedRig * 20 + 60, NULL);
|
CreatePactorWindow(TNC, "RIGCONTROL", "RigControl", 10, PacWndProc, 550, NeedRig * 20 + 60, NULL);
|
||||||
hDlg = TNC->hDlg;
|
hDlg = TNC->hDlg;
|
||||||
|
|
||||||
|
|
33
TelnetV6.c
33
TelnetV6.c
|
@ -534,6 +534,9 @@ int ProcessLine(char * buf, int Port)
|
||||||
else if (_stricmp(param,"HTTPPORT") == 0)
|
else if (_stricmp(param,"HTTPPORT") == 0)
|
||||||
TCP->HTTPPort = atoi(value);
|
TCP->HTTPPort = atoi(value);
|
||||||
|
|
||||||
|
else if (_stricmp(param,"APIPORT") == 0)
|
||||||
|
TCP->APIPort = atoi(value);
|
||||||
|
|
||||||
else if (_stricmp(param,"SYNCPORT") == 0)
|
else if (_stricmp(param,"SYNCPORT") == 0)
|
||||||
TCP->SyncPort = atoi(value);
|
TCP->SyncPort = atoi(value);
|
||||||
|
|
||||||
|
@ -1646,6 +1649,9 @@ BOOL OpenSockets(struct TNCINFO * TNC)
|
||||||
if (TCP->HTTPPort)
|
if (TCP->HTTPPort)
|
||||||
TCP->HTTPsock = OpenSocket4(TNC, TCP->HTTPPort);
|
TCP->HTTPsock = OpenSocket4(TNC, TCP->HTTPPort);
|
||||||
|
|
||||||
|
if (TCP->APIPort)
|
||||||
|
TCP->APIsock = OpenSocket4(TNC, TCP->APIPort);
|
||||||
|
|
||||||
if (TCP->SyncPort)
|
if (TCP->SyncPort)
|
||||||
TCP->Syncsock = OpenSocket4(TNC, TCP->SyncPort);
|
TCP->Syncsock = OpenSocket4(TNC, TCP->SyncPort);
|
||||||
|
|
||||||
|
@ -1755,10 +1761,12 @@ BOOL OpenSockets6(struct TNCINFO * TNC)
|
||||||
if (TCP->RelayPort)
|
if (TCP->RelayPort)
|
||||||
TCP->Relaysock6 = OpenSocket6(TNC, TCP->RelayPort);
|
TCP->Relaysock6 = OpenSocket6(TNC, TCP->RelayPort);
|
||||||
|
|
||||||
|
|
||||||
if (TCP->HTTPPort)
|
if (TCP->HTTPPort)
|
||||||
TCP->HTTPsock6 = OpenSocket6(TNC, TCP->HTTPPort);
|
TCP->HTTPsock6 = OpenSocket6(TNC, TCP->HTTPPort);
|
||||||
|
|
||||||
|
if (TCP->APIPort)
|
||||||
|
TCP->APIsock6 = OpenSocket6(TNC, TCP->APIPort);
|
||||||
|
|
||||||
if (TCP->SyncPort)
|
if (TCP->SyncPort)
|
||||||
TCP->Syncsock6 = OpenSocket6(TNC, TCP->SyncPort);
|
TCP->Syncsock6 = OpenSocket6(TNC, TCP->SyncPort);
|
||||||
|
|
||||||
|
@ -1819,6 +1827,14 @@ static VOID SetupListenSet(struct TNCINFO * TNC)
|
||||||
maxsock = sock;
|
maxsock = sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sock = TCP->APIsock;
|
||||||
|
if (sock)
|
||||||
|
{
|
||||||
|
FD_SET(sock, readfd);
|
||||||
|
if (sock > maxsock)
|
||||||
|
maxsock = sock;
|
||||||
|
}
|
||||||
|
|
||||||
sock = TCP->Syncsock;
|
sock = TCP->Syncsock;
|
||||||
if (sock)
|
if (sock)
|
||||||
{
|
{
|
||||||
|
@ -1886,6 +1902,14 @@ static VOID SetupListenSet(struct TNCINFO * TNC)
|
||||||
maxsock = sock;
|
maxsock = sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sock = TCP->APIsock6;
|
||||||
|
if (sock)
|
||||||
|
{
|
||||||
|
FD_SET(sock, readfd);
|
||||||
|
if (sock > maxsock)
|
||||||
|
maxsock = sock;
|
||||||
|
}
|
||||||
|
|
||||||
sock = TCP->DRATSsock6;
|
sock = TCP->DRATSsock6;
|
||||||
|
|
||||||
if (sock)
|
if (sock)
|
||||||
|
@ -3192,6 +3216,7 @@ int Socket_Accept(struct TNCINFO * TNC, SOCKET SocketId, int Port)
|
||||||
TNC->Streams[n].FramesQueued = 0;
|
TNC->Streams[n].FramesQueued = 0;
|
||||||
|
|
||||||
sockptr->HTTPMode = FALSE;
|
sockptr->HTTPMode = FALSE;
|
||||||
|
sockptr->APIMode = FALSE;
|
||||||
sockptr->SyncMode = FALSE;
|
sockptr->SyncMode = FALSE;
|
||||||
sockptr->DRATSMode = FALSE;
|
sockptr->DRATSMode = FALSE;
|
||||||
sockptr->FBBMode = 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)
|
if (SocketId == TCP->HTTPsock || SocketId == TCP->HTTPsock6)
|
||||||
sockptr->HTTPMode = TRUE;
|
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)
|
else if (SocketId == TCP->Syncsock || SocketId == TCP->Syncsock6)
|
||||||
sockptr->SyncMode = TRUE;
|
sockptr->SyncMode = TRUE;
|
||||||
else if (SocketId == TCP->DRATSsock || SocketId == TCP->DRATSsock6)
|
else if (SocketId == TCP->DRATSsock || SocketId == TCP->DRATSsock6)
|
||||||
|
|
22
Versions.h
22
Versions.h
|
@ -10,16 +10,16 @@
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define KVers 6,0,24,22
|
#define KVers 6,0,24,27
|
||||||
#define KVerstring "6.0.24.22\0"
|
#define KVerstring "6.0.24.27\0"
|
||||||
|
|
||||||
#ifdef CKernel
|
#ifdef CKernel
|
||||||
|
|
||||||
#define Vers KVers
|
#define Vers KVers
|
||||||
#define Verstring KVerstring
|
#define Verstring KVerstring
|
||||||
#define Datestring "November 2023"
|
#define Datestring "January 2024"
|
||||||
#define VerComments "G8BPQ Packet Switch (C Version)" KVerstring
|
#define VerComments "G8BPQ Packet Switch (C Version)" KVerstring
|
||||||
#define VerCopyright "Copyright © 2001-2023 John Wiseman G8BPQ\0"
|
#define VerCopyright "Copyright © 2001-2024 John Wiseman G8BPQ\0"
|
||||||
#define VerDesc "BPQ32 Switch\0"
|
#define VerDesc "BPQ32 Switch\0"
|
||||||
#define VerProduct "BPQ32"
|
#define VerProduct "BPQ32"
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
#define Vers 1,0,16,2
|
#define Vers 1,0,16,2
|
||||||
#define Verstring "1.0.16.2\0"
|
#define Verstring "1.0.16.2\0"
|
||||||
#define VerComments "Internet Terminal for G8BPQ Packet Switch\0"
|
#define VerComments "Internet Terminal for G8BPQ Packet Switch\0"
|
||||||
#define VerCopyright "Copyright © 2011-2023 John Wiseman G8BPQ\0"
|
#define VerCopyright "Copyright © 2011-2024 John Wiseman G8BPQ\0"
|
||||||
#define VerDesc "Simple TCP Terminal Program for G8BPQ Switch\0"
|
#define VerDesc "Simple TCP Terminal Program for G8BPQ Switch\0"
|
||||||
#define VerProduct "BPQTermTCP"
|
#define VerProduct "BPQTermTCP"
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
#define Vers 2,2,5,2
|
#define Vers 2,2,5,2
|
||||||
#define Verstring "2.2.5.2\0"
|
#define Verstring "2.2.5.2\0"
|
||||||
#define VerComments "Simple Terminal for G8BPQ Packet Switch\0"
|
#define VerComments "Simple Terminal for G8BPQ Packet Switch\0"
|
||||||
#define VerCopyright "Copyright © 1999-2023 John Wiseman G8BPQ\0"
|
#define VerCopyright "Copyright © 1999-2024 John Wiseman G8BPQ\0"
|
||||||
#define VerDesc "Simple Terminal Program for G8BPQ Switch\0"
|
#define VerDesc "Simple Terminal Program for G8BPQ Switch\0"
|
||||||
#define VerProduct "BPQTerminal"
|
#define VerProduct "BPQTerminal"
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
#define Vers 2,2,0,3
|
#define Vers 2,2,0,3
|
||||||
#define Verstring "2.2.0.3\0"
|
#define Verstring "2.2.0.3\0"
|
||||||
#define VerComments "MDI Terminal for G8BPQ Packet Switch\0"
|
#define VerComments "MDI Terminal for G8BPQ Packet Switch\0"
|
||||||
#define VerCopyright "Copyright © 1999-2023 John Wiseman G8BPQ\0"
|
#define VerCopyright "Copyright © 1999-2024 John Wiseman G8BPQ\0"
|
||||||
#define VerDesc "MDI Terminal Program for G8BPQ Switch\0"
|
#define VerDesc "MDI Terminal Program for G8BPQ Switch\0"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
#define Vers KVers
|
#define Vers KVers
|
||||||
#define Verstring KVerstring
|
#define Verstring KVerstring
|
||||||
#define VerComments "Mail server for G8BPQ Packet Switch\0"
|
#define VerComments "Mail server for G8BPQ Packet Switch\0"
|
||||||
#define VerCopyright "Copyright © 2009-2023 John Wiseman G8BPQ\0"
|
#define VerCopyright "Copyright © 2009-2024 John Wiseman G8BPQ\0"
|
||||||
#define VerDesc "Mail server for G8BPQ's 32 Bit Switch\0"
|
#define VerDesc "Mail server for G8BPQ's 32 Bit Switch\0"
|
||||||
#define VerProduct "BPQMail"
|
#define VerProduct "BPQMail"
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@
|
||||||
#define Vers 0,1,0,0
|
#define Vers 0,1,0,0
|
||||||
#define Verstring "0.1.0.0\0"
|
#define Verstring "0.1.0.0\0"
|
||||||
#define VerComments "Password Generation Utility for G8BPQ Packet Switch\0"
|
#define VerComments "Password Generation Utility for G8BPQ Packet Switch\0"
|
||||||
#define VerCopyright "Copyright © 2011-2023 John Wiseman G8BPQ\0"
|
#define VerCopyright "Copyright © 2011-2024 John Wiseman G8BPQ\0"
|
||||||
#define VerDesc "Password Generation Utility for G8BPQ Switch\0"
|
#define VerDesc "Password Generation Utility for G8BPQ Switch\0"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
#define Vers KVers
|
#define Vers KVers
|
||||||
#define Verstring KVerstring
|
#define Verstring KVerstring
|
||||||
#define VerComments "APRS Client for G8BPQ Switch\0"
|
#define VerComments "APRS Client for G8BPQ Switch\0"
|
||||||
#define VerCopyright "Copyright © 2012-2023 John Wiseman G8BPQ\0"
|
#define VerCopyright "Copyright © 2012-2024 John Wiseman G8BPQ\0"
|
||||||
#define VerDesc "APRS Client for G8BPQ Switch\0"
|
#define VerDesc "APRS Client for G8BPQ Switch\0"
|
||||||
#define VerProduct "BPQAPRS"
|
#define VerProduct "BPQAPRS"
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@
|
||||||
#define Vers KVers
|
#define Vers KVers
|
||||||
#define Verstring KVerstring
|
#define Verstring KVerstring
|
||||||
#define VerComments "Chat server for G8BPQ Packet Switch\0"
|
#define VerComments "Chat server for G8BPQ Packet Switch\0"
|
||||||
#define VerCopyright "Copyright © 2009-2023 John Wiseman G8BPQ\0"
|
#define VerCopyright "Copyright © 2009-2024 John Wiseman G8BPQ\0"
|
||||||
#define VerDesc "Chat server for G8BPQ's 32 Bit Switch\0"
|
#define VerDesc "Chat server for G8BPQ's 32 Bit Switch\0"
|
||||||
#define VerProduct "BPQChat"
|
#define VerProduct "BPQChat"
|
||||||
|
|
||||||
|
|
92
WebMail.c
92
WebMail.c
|
@ -76,6 +76,8 @@ VOID SendTemplateSelectScreen(struct HTTPConnectionInfo * Session, char *URLPara
|
||||||
BOOL isAMPRMsg(char * Addr);
|
BOOL isAMPRMsg(char * Addr);
|
||||||
char * doXMLTransparency(char * string);
|
char * doXMLTransparency(char * string);
|
||||||
Dll BOOL APIENTRY APISendAPRSMessage(char * Text, char * ToCall);
|
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 NodeTail[];
|
||||||
extern char BBSName[10];
|
extern char BBSName[10];
|
||||||
|
@ -719,26 +721,27 @@ VOID ProcessFormDir(char * FormSet, char * DirName, struct HtmlFormDir *** xxx,
|
||||||
{
|
{
|
||||||
if (entry->d_type == DT_DIR)
|
if (entry->d_type == DT_DIR)
|
||||||
{
|
{
|
||||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
char Dir[MAX_PATH];
|
||||||
|
|
||||||
|
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||||
continue;
|
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;
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
// see if initial html
|
|
||||||
|
|
||||||
// if (stristr(entry->d_name, "initial.html"))
|
// Add to list
|
||||||
{
|
|
||||||
// Add to list
|
|
||||||
|
|
||||||
Form = zalloc(sizeof (struct HtmlForm));
|
Form = zalloc(sizeof (struct HtmlForm));
|
||||||
|
|
||||||
Form->FileName = _strdup(entry->d_name);
|
Form->FileName = _strdup(entry->d_name);
|
||||||
|
|
||||||
FormDir->Forms=realloc(FormDir->Forms, (FormDir->FormCount + 1) * sizeof(void *));
|
FormDir->Forms=realloc(FormDir->Forms, (FormDir->FormCount + 1) * sizeof(void *));
|
||||||
FormDir->Forms[FormDir->FormCount++] = Form;
|
FormDir->Forms[FormDir->FormCount++] = Form;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
#endif
|
#endif
|
||||||
|
@ -808,22 +811,23 @@ int GetHTMLFormSet(char * FormSet)
|
||||||
if (!(dir = opendir(name)))
|
if (!(dir = opendir(name)))
|
||||||
{
|
{
|
||||||
Debugprintf("cant open forms dir %s %d %d", name, errno, dir);
|
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)
|
while ((entry = readdir(dir)) != NULL)
|
||||||
{
|
{
|
||||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
if (entry->d_type == DT_DIR)
|
||||||
continue;
|
{
|
||||||
|
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Add to Directory List
|
// Add to Directory List
|
||||||
|
|
||||||
ProcessFormDir(FormSet, entry->d_name, &HtmlFormDirs, &FormDirCount);
|
ProcessFormDir(FormSet, entry->d_name, &HtmlFormDirs, &FormDirCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// List for testing
|
// List for testing
|
||||||
|
@ -1122,7 +1126,7 @@ int ViewWebMailMessage(struct HTTPConnectionInfo * Session, char * Reply, int Nu
|
||||||
Msg->status = 'Y';
|
Msg->status = 'Y';
|
||||||
Msg->datechanged=time(NULL);
|
Msg->datechanged=time(NULL);
|
||||||
SaveMessageDatabase();
|
SaveMessageDatabase();
|
||||||
|
SendMessageReadEvent(Session->Callsign, Msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1190,6 +1194,7 @@ int ViewWebMailMessage(struct HTTPConnectionInfo * Session, char * Reply, int Nu
|
||||||
Msg->status = 'Y';
|
Msg->status = 'Y';
|
||||||
Msg->datechanged=time(NULL);
|
Msg->datechanged=time(NULL);
|
||||||
SaveMessageDatabase();
|
SaveMessageDatabase();
|
||||||
|
SendMessageReadEvent(Session->Callsign, Msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1303,6 +1308,7 @@ int ViewWebMailMessage(struct HTTPConnectionInfo * Session, char * Reply, int Nu
|
||||||
Msg->status = 'Y';
|
Msg->status = 'Y';
|
||||||
Msg->datechanged=time(NULL);
|
Msg->datechanged=time(NULL);
|
||||||
SaveMessageDatabase();
|
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)
|
if (Msg->status != 'H' && Msg->type == 'B' && memcmp(Msg->fbbs, zeros, NBMASK) != 0)
|
||||||
Msg->status = '$'; // Has forwarding
|
Msg->status = '$'; // Has forwarding
|
||||||
|
|
||||||
|
|
||||||
if (EnableUI)
|
if (EnableUI)
|
||||||
SendMsgUI(Msg);
|
SendMsgUI(Msg);
|
||||||
|
|
||||||
user = LookupCall(Msg->to);
|
user = LookupCall(Msg->to);
|
||||||
|
|
||||||
|
// If Event Notifications enabled report a new message event
|
||||||
|
|
||||||
|
SendNewMessageEvent(user->Call, Msg);
|
||||||
|
|
||||||
if (user && (user->flags & F_APRSMFOR))
|
if (user && (user->flags & F_APRSMFOR))
|
||||||
{
|
{
|
||||||
char APRS[128];
|
char APRS[128];
|
||||||
|
@ -2838,13 +2849,26 @@ char * GetHTMLViewerTemplate(char * FN)
|
||||||
{
|
{
|
||||||
for (l = 0; l < Dir->DirCount; l++)
|
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)
|
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(Dir, Dir->Dirs[l]->Forms[k]->FileName);
|
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;
|
*ptr2++ = 0;
|
||||||
|
|
||||||
ptr3 = strchr(ptr2, '<'); // end of value string
|
ptr3 = strstr(ptr2, "</"); // end of value string
|
||||||
if (ptr3 == NULL)
|
if (ptr3 == NULL)
|
||||||
goto quit;
|
goto quit;
|
||||||
|
|
||||||
|
@ -3236,6 +3260,14 @@ BOOL ParseXML(WebMailInfo * WebMail, char * XMLOrig)
|
||||||
XMLKeys++;
|
XMLKeys++;
|
||||||
|
|
||||||
ptr1 = strchr(ptr3, '<');
|
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
|
#endif
|
||||||
|
|
||||||
|
printf("%s\n", MsgFile);
|
||||||
|
|
||||||
if (stat(MsgFile, &STAT) != -1)
|
if (stat(MsgFile, &STAT) != -1)
|
||||||
{
|
{
|
||||||
hFile = fopen(MsgFile, "rb");
|
hFile = fopen(MsgFile, "rb");
|
||||||
|
@ -5365,6 +5399,8 @@ char * CheckFile(struct HtmlFormDir * Dir, char * FN)
|
||||||
MsgBytes[FileSize] = 0;
|
MsgBytes[FileSize] = 0;
|
||||||
fclose(hFile);
|
fclose(hFile);
|
||||||
|
|
||||||
|
printf("%d %s\n", strlen(MsgBytes), MsgBytes);
|
||||||
|
|
||||||
return MsgBytes;
|
return MsgBytes;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -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="NOTTSDESKTOP"
|
||||||
|
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="NOTTSDESKTOP"
|
||||||
|
RemoteCommand=""
|
||||||
|
HttpUrl=""
|
||||||
|
PDBPath=""
|
||||||
|
SQLDebugging=""
|
||||||
|
Environment=""
|
||||||
|
EnvironmentMerge="true"
|
||||||
|
DebuggerFlavor=""
|
||||||
|
MPIRunCommand=""
|
||||||
|
MPIRunArguments=""
|
||||||
|
MPIRunWorkingDirectory=""
|
||||||
|
ApplicationCommand=""
|
||||||
|
ApplicationArguments=""
|
||||||
|
ShimCommand=""
|
||||||
|
MPIAcceptMode=""
|
||||||
|
MPIAcceptFilter=""
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
</VisualStudioUserFile>
|
|
@ -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="NOTTSDESKTOP"
|
||||||
|
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="NOTTSDESKTOP"
|
||||||
|
RemoteCommand=""
|
||||||
|
HttpUrl=""
|
||||||
|
PDBPath=""
|
||||||
|
SQLDebugging=""
|
||||||
|
Environment=""
|
||||||
|
EnvironmentMerge="true"
|
||||||
|
DebuggerFlavor=""
|
||||||
|
MPIRunCommand=""
|
||||||
|
MPIRunArguments=""
|
||||||
|
MPIRunWorkingDirectory=""
|
||||||
|
ApplicationCommand=""
|
||||||
|
ApplicationArguments=""
|
||||||
|
ShimCommand=""
|
||||||
|
MPIAcceptMode=""
|
||||||
|
MPIAcceptFilter=""
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
</VisualStudioUserFile>
|
|
@ -1,7 +1,24 @@
|
||||||
|
linbpq (6.0.24.27-1~bpo11+1) bullseye; urgency=medium
|
||||||
|
|
||||||
|
* Rebuild for bullseye.
|
||||||
|
|
||||||
|
-- Dave Hibberd <d@vehibberd.com> Tue, 16 Jan 2024 20:55:26 +0000
|
||||||
|
|
||||||
|
linbpq (6.0.24.27-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* New Upstream Release
|
||||||
|
|
||||||
|
-- Dave Hibberd <d@vehibberd.com> Tue, 16 Jan 2024 20:51:43 +0000
|
||||||
|
|
||||||
|
linbpq (6.0.24.25-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* New Upstream Release
|
||||||
|
|
||||||
|
-- Dave Hibberd <d@vehibberd.com> Thu, 28 Dec 2023 10:44:47 +0000
|
||||||
|
|
||||||
linbpq (6.0.24.22-2~bpo11+1) bullseye; urgency=medium
|
linbpq (6.0.24.22-2~bpo11+1) bullseye; urgency=medium
|
||||||
|
|
||||||
* Rebuild for bullseye.
|
* Rebuild for bullseye.
|
||||||
*
|
|
||||||
|
|
||||||
-- Dave Hibberd <d@vehibberd.com> Sat, 16 Dec 2023 14:42:25 +0000
|
-- Dave Hibberd <d@vehibberd.com> Sat, 16 Dec 2023 14:42:25 +0000
|
||||||
|
|
||||||
|
|
|
@ -10,3 +10,5 @@ if [ -L $confile ]; then
|
||||||
cp $node $confile
|
cp $node $confile
|
||||||
mv $node $node.bak
|
mv $node $node.bak
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#DEBHELPER#
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
2
makefile
2
makefile
|
@ -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 \
|
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 \
|
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 \
|
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:
|
# Configuration:
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -36,7 +36,8 @@ struct ConnectionInfo
|
||||||
BOOL RelayMode; // Pure TCP for RMS Relay Emulation forwarding
|
BOOL RelayMode; // Pure TCP for RMS Relay Emulation forwarding
|
||||||
BOOL DRATSMode; // HTML Terminal Emulator
|
BOOL DRATSMode; // HTML Terminal Emulator
|
||||||
BOOL SyncMode; // RMS Relay Sync
|
BOOL SyncMode; // RMS Relay Sync
|
||||||
BOOL HTTPMode; // DRATS Reflector Emulator
|
BOOL HTTPMode; // HTTP Server
|
||||||
|
BOOL APIMode; // REST API Server
|
||||||
BOOL TriMode; // Trimode emulation
|
BOOL TriMode; // Trimode emulation
|
||||||
BOOL TriModeConnected; // Set when remote session is connected - now send data to DataSock
|
BOOL TriModeConnected; // Set when remote session is connected - now send data to DataSock
|
||||||
SOCKET TriModeDataSock; // Data Socket
|
SOCKET TriModeDataSock; // Data Socket
|
||||||
|
|
|
@ -478,7 +478,9 @@ char * MainConfigtxt()
|
||||||
" <input %sname=\"DontCheckFromCall\" type=\"checkbox\"> Dont Check From Call<br>\r\n"
|
" <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=\"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=\"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"
|
||||||
|
|
||||||
" POP3 Port <input value=\"%d\" size=\"3\" name=\"POP3Port\">\r\n"
|
" POP3 Port <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\"> <input %sname=\"EnRemote\" type=\"checkbox\"> Enable Remote Access<br>\r\n"
|
"SMTP Port <input value=\"%d\" size=\"3\" name=\"SMTPPort\"> NTPPort <input value=\"%d\" size=\"3\" name=\"NNTPPort\"> <input %sname=\"EnRemote\" type=\"checkbox\"> Enable Remote Access<br>\r\n"
|
||||||
" AMPR Address <input value=\"%s\" name=\"AMPRDomain\"> <input %sname=\"SendAMPR\" type=\"checkbox\"> Send AMPR Mail to AMPR host\r\n"
|
" 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()
|
||||||
" FBB reject.sys type filters (all fields must match, wildcards allowed)\r\n"
|
" FBB reject.sys type filters (all fields must match, wildcards allowed)\r\n"
|
||||||
"<p></p>"
|
"<p></p>"
|
||||||
"<div style='position: absolute; left: 20px;height: 120px; overflow:auto;'>%s</div>"
|
"<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'>"
|
"<input class='btn' name=\"Save\" value=\"Save\" type=submit class='btn'> <input class='btn' name=\"Cancel\" value=\"Cancel\" type=submit class='btn'>"
|
||||||
"</div>"
|
"</div>"
|
||||||
"</form>\r\n"
|
"</form>\r\n"
|
||||||
|
@ -1428,7 +1430,7 @@ char * ChatConfigtxt()
|
||||||
"<div style=\"text-align: center;\"><font size=\"+1\"><span\r\n"
|
"<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"
|
"style=\"font-family: monospace; font-weight: bold;\">Chat Configuration</span></font></div>\r\n"
|
||||||
"<div id=\"main\"\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"
|
"<form border=\"1\" style=\"font-family: monospace;\" method=\"post\"\r\n"
|
||||||
"action=\"/Chat/ChatConfig?%s\">\r\n"
|
"action=\"/Chat/ChatConfig?%s\">\r\n"
|
||||||
"<h3> Chat Server Params<span style=\"font-family: monospace;\"></span></h3>\r\n"
|
"<h3> 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 \r\n"
|
"<span style=\"font-family: monospace;\"></span>Streams \r\n"
|
||||||
" <input value=\"%d\" size=\"3\" name=\"Streams\"><br>\r\n"
|
" <input value=\"%d\" size=\"3\" name=\"Streams\"><br>\r\n"
|
||||||
" <br>\r\n"
|
" <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 "
|
"<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 "
|
"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 "
|
"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"
|
"<textarea cols=\"80\" rows=\"5\" name=\"welcome\">%s</textarea><br>\r\n"
|
||||||
"<br>\r\n"
|
"<br>\r\n"
|
||||||
"\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=\"Save\" value=\"Save\" type=submit class='btn'> \r\n"
|
||||||
"<input name=\"UpdateMap\" value=\"Update Map\" 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"
|
"<input name=\"Restart\" value=\"Restart Links\" type=submit class='btn'> \r\n"
|
||||||
|
|
|
@ -110,6 +110,7 @@ struct TCPINFO
|
||||||
int FBBPort[100];
|
int FBBPort[100];
|
||||||
int RelayPort;
|
int RelayPort;
|
||||||
int HTTPPort;
|
int HTTPPort;
|
||||||
|
int APIPort;
|
||||||
int TriModePort;
|
int TriModePort;
|
||||||
int SyncPort;
|
int SyncPort;
|
||||||
int DRATSPort;
|
int DRATSPort;
|
||||||
|
@ -159,6 +160,7 @@ struct TCPINFO
|
||||||
SOCKET FBBsock[100];
|
SOCKET FBBsock[100];
|
||||||
SOCKET Relaysock;
|
SOCKET Relaysock;
|
||||||
SOCKET HTTPsock;
|
SOCKET HTTPsock;
|
||||||
|
SOCKET APIsock;
|
||||||
SOCKET TriModeSock;
|
SOCKET TriModeSock;
|
||||||
SOCKET TriModeDataSock;
|
SOCKET TriModeDataSock;
|
||||||
SOCKET Syncsock;
|
SOCKET Syncsock;
|
||||||
|
@ -169,6 +171,7 @@ struct TCPINFO
|
||||||
SOCKET FBBsock6[100];
|
SOCKET FBBsock6[100];
|
||||||
SOCKET Relaysock6;
|
SOCKET Relaysock6;
|
||||||
SOCKET HTTPsock6;
|
SOCKET HTTPsock6;
|
||||||
|
SOCKET APIsock6;
|
||||||
SOCKET Syncsock6;
|
SOCKET Syncsock6;
|
||||||
SOCKET DRATSsock6;
|
SOCKET DRATSsock6;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue