6.0.23.46

This commit is contained in:
g8bpq 2023-02-05 11:01:05 +00:00
parent c15de2c7f7
commit c32ef4ee1e
19 changed files with 706 additions and 55 deletions

View File

@ -179,7 +179,7 @@ char LON[] = "00000.00W"; //in standard APRS Format
char HostName[80]; // for BlueNMEA
int HostPort = 4352;
char GPSDHost[80]; // for BlueNMEA
char GPSDHost[80];
int GPSDPort = 2947;
@ -248,6 +248,8 @@ char CFGSYMSET = 'B';
char SYMBOL = '='; // Unknown Locaton
char SYMSET = '/';
char * PHG = 0; // Optional PHG (Power-Height-Gain) string for beacon
BOOL TraceDigi = FALSE; // Add Trace to packets relayed on Digi Calls
BOOL SATGate = FALSE; // Delay Gating to IS directly heard packets
BOOL RXOnly = FALSE; // Run as RX only IGATE, ie don't gate anything to RF
@ -2413,6 +2415,12 @@ static int APRSProcessLine(char * buf)
return TRUE;
}
if (_stricmp(ptr, "PHG") == 0)
{
PHG = _strdup(p_value);
return TRUE;
}
if (_stricmp(ptr, "MaxTraceHops") == 0)
{
MaxTraceHops = atoi(p_value);
@ -2652,8 +2660,12 @@ VOID SendBeacon(int toPort, char * BeaconText, BOOL SendStatus, BOOL SendSOGCOG)
if (SendSOGCOG | (COG != 0.0))
sprintf(SOGCOG, "%03.0f/%03.0f", COG, SOG);
Len = sprintf(ISMsg, "%s>%s,TCPIP*:%c%s%c%s%c%s%s\r\n", APRSCall, APRSDest,
(APRSApplConnected) ? '=' : '!', LAT, SYMSET, LON, SYMBOL, SOGCOG, BeaconText);
if (PHG) // Send PHG instead of SOG COG
Len = sprintf(ISMsg, "%s>%s,TCPIP*:%c%s%c%s%c%s%s\r\n", APRSCall, APRSDest,
(APRSApplConnected) ? '=' : '!', LAT, SYMSET, LON, SYMBOL, PHG, BeaconText);
else
Len = sprintf(ISMsg, "%s>%s,TCPIP*:%c%s%c%s%c%s%s\r\n", APRSCall, APRSDest,
(APRSApplConnected) ? '=' : '!', LAT, SYMSET, LON, SYMBOL, SOGCOG, BeaconText);
ISSend(sock, ISMsg, Len, 0);
Debugprintf(">%s", ISMsg);
@ -2683,15 +2695,18 @@ void SendBeaconThread(void * Param)
int Port;
DIGIMESSAGE Msg;
int Len;
char SOGCOG[10] = "";
char SOGCOG[256] = "";
struct STATIONRECORD * Station;
struct PORTCONTROL * PORT;
if (PosnSet == FALSE)
return;
if (SendSOGCOG | (COG != 0.0))
sprintf(SOGCOG, "%03.0f/%03.0f", COG, SOG);
if (PHG) // Send PHG instead of SOG COG
strcpy(SOGCOG, PHG);
else
if (SendSOGCOG | (COG != 0.0))
sprintf(SOGCOG, "%03.0f/%03.0f", COG, SOG);
BeaconCounter = BeaconInterval * 60;

View File

@ -3325,6 +3325,10 @@ VOID ARDOPProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
STREAM->BytesRXed, (int)(STREAM->BytesRXed/Duration), (int)Duration);
Debugprintf(logmsg);
STREAM->ConnectTime = 0; // Prevent retrigger
}

View File

@ -117,6 +117,11 @@ long long GetInt64Value(config_setting_t * group, char * name);
void ProcessSyncModeMessage(CIRCUIT * conn, struct UserInfo * user, char* Buffer, int len);
int ReformatSyncMessage(CIRCUIT * conn);
char * initMultipartUnpack(char ** Input);
char * FormatSYNCMessage(CIRCUIT * conn, struct MsgInfo * Msg);
int decode_quoted_printable(char *ptr, int len);
void decodeblock( unsigned char in[4], unsigned char out[3]);
int encode_quoted_printable(char *s, char * out, int Len);
config_t cfg;
config_setting_t * group;
@ -5984,6 +5989,9 @@ VOID CreateMessageFromBuffer(CIRCUIT * conn)
FreeSemaphore(&MsgNoSemaphore);
MsgnotoMsg[Msg->number] = Msg;
if (Msg->status == 0)
Msg->status = 'N';
// Create BID if non supplied
if (Msg->bid[0] == 0)
@ -8267,6 +8275,12 @@ InBand:
goto CheckForEnd;
}
if (_memicmp(Cmd, "SYNC", 4) == 0)
{
conn->BBSFlags |= SYNCMODE;
goto CheckForEnd;
}
if (_memicmp(Cmd, "NEEDLF", 6) == 0)
{
conn->BBSFlags |= NEEDLF;
@ -8467,7 +8481,7 @@ InBand:
CheckForSID:
if (strstr(Buffer, "POSYNCHELLO")) // URONODE
if (strstr(Buffer, "POSYNCHELLO")) // RMS RELAY Sync process
{
conn->BBSFlags &= ~RunningConnectScript; // so it doesn't get reentered
ProcessLine(conn, 0, Buffer, len);
@ -11371,6 +11385,9 @@ VOID ProcessLine(CIRCUIT * conn, struct UserInfo * user, char* Buffer, int len)
if (_memicmp(Buffer, "POSYNCHELLO", 11) == 0)
{
// This is first message received after connecting to SYNC
// Save Callsign
char Reply[32];
conn->BBSFlags |= SYNCMODE;
conn->FBBHeaders = zalloc(5 * sizeof(struct FBBHeaderLine));
@ -13544,11 +13561,151 @@ void ProcessSyncModeMessage(CIRCUIT * conn, struct UserInfo * user, char* Buffer
{
Buffer[len] = 0;
if (conn->Flags & PROPOSINGSYNCMSG)
{
// Waiting for response to TR AddMessage
if (strcmp(Buffer, "OK\r") == 0)
{
char Msg[256];
int n;
WriteLogLine(conn, '<', Buffer, len-1, LOG_BBS);
// Send the message, it has already been built
conn->Flags &= !PROPOSINGSYNCMSG;
conn->Flags |= SENDINGSYNCMSG;
n = sprintf_s(Msg, sizeof(Msg), "Sending SYNC message %s", conn->FwdMsg->bid);
WriteLogLine(conn, '|',Msg, n, LOG_BBS);
QueueMsg(conn, conn->SyncMessage, conn->SyncCompressedLen);
return;
}
if (strcmp(Buffer, "NO\r") == 0)
{
WriteLogLine(conn, '<', Buffer, len-1, LOG_BBS);
// Message Rejected - ? duplicate
if (conn->FwdMsg)
{
// Zap the entry
clear_fwd_bit(conn->FwdMsg->fbbs, user->BBSNumber);
set_fwd_bit(conn->FwdMsg->forw, user->BBSNumber);
conn->UserPointer->ForwardingInfo->MsgCount--;
// Only mark as forwarded if sent to all BBSs that should have it
if (memcmp(conn->FwdMsg->fbbs, zeros, NBMASK) == 0)
{
conn->FwdMsg->status = 'F'; // Mark as forwarded
conn->FwdMsg->datechanged=time(NULL);
}
conn->FwdMsg->Locked = 0; // Unlock
}
}
BBSputs(conn, "BYE\r");
conn->CloseAfterFlush = 20; // 2 Secs
conn->Flags &= !PROPOSINGSYNCMSG;
conn->BBSFlags &= ~SYNCMODE;
return;
}
if (conn->Flags & SENDINGSYNCMSG)
{
if (strcmp(Buffer, "OK\r") == 0)
{
// Message Sent
conn->Flags &= !SENDINGSYNCMSG;
free(conn->SyncMessage);
if (conn->FwdMsg)
{
char Msg[256];
int n;
n = sprintf_s(Msg, sizeof(Msg), "SYNC message %s Sent", conn->FwdMsg->bid);
WriteLogLine(conn, '|',Msg, n, LOG_BBS);
clear_fwd_bit(conn->FwdMsg->fbbs, user->BBSNumber);
set_fwd_bit(conn->FwdMsg->forw, user->BBSNumber);
conn->UserPointer->ForwardingInfo->MsgCount--;
// Only mark as forwarded if sent to all BBSs that should have it
if (memcmp(conn->FwdMsg->fbbs, zeros, NBMASK) == 0)
{
conn->FwdMsg->status = 'F'; // Mark as forwarded
conn->FwdMsg->datechanged=time(NULL);
}
conn->FwdMsg->Locked = 0; // Unlock
}
// drop through to send any more
}
else
{
WriteLogLine(conn, '<', Buffer, len-1, LOG_BBS);
conn->Flags &= !SENDINGSYNCMSG;
free(conn->SyncMessage);
BBSputs(conn, "BYE\r");
conn->CloseAfterFlush = 20; // 2 Secs
conn->BBSFlags &= ~SYNCMODE;
return;
}
}
if (strcmp(Buffer, "OK\r") == 0)
{
WriteLogLine(conn, '<', Buffer, len-1, LOG_BBS);
// Propose any waiting files
// Send Message(?s) to RMS Relay SYNC
/*
<POSYNCLOGON G8BPQ
>OK
>TR AddMessage_V5JLSGH591JR 786 1219 522 True
<OK
.. message
<OK
?? repeat
>BYE*/
if (FindMessagestoForward(conn) && conn->FwdMsg)
{
struct MsgInfo * Msg = conn->FwdMsg;
char Buffer[128];
char * Message;
Message = FormatSYNCMessage(conn, Msg);
// Need to compress it
conn->SyncMessage = malloc(conn->SyncXMLLen + conn->SyncMsgLen + 4096);
conn->SyncCompressedLen = Encode(Message, conn->SyncMessage, conn->SyncXMLLen + conn->SyncMsgLen, 0, 1);
sprintf(Buffer, "TR AddMessage_%s %d %d %d True\r",
Msg->bid, conn->SyncCompressedLen, conn->SyncXMLLen, conn->SyncMsgLen);
free(Message);
conn->Flags |= PROPOSINGSYNCMSG;
BBSputs(conn, Buffer);
return;
}
BBSputs(conn, "BYE\r");
conn->CloseAfterFlush = 20; // 2 Secs
@ -13556,6 +13713,46 @@ void ProcessSyncModeMessage(CIRCUIT * conn, struct UserInfo * user, char* Buffer
return;
}
if (memcmp(Buffer, "TR RMS_Location_", 16) == 0)
{
// I think this is an xml message giving location of station
BIDRec * BID;
char *ptr1, *ptr2, *context;
// TR RMS_Location_OH6IJ3_YIBB50HCCQUS 200 367 0 True
WriteLogLine(conn, '<', Buffer, len-1, LOG_BBS);
ptr1 = strtok_s(&Buffer[16], " ", &context); // MID
// What to do with call bit??
ptr1 = strlop(ptr1, '_');
ptr2 = strtok_s(NULL, " ", &context);
conn->SyncCompressedLen = atoi(ptr2);
ptr2 = strtok_s(NULL, " ", &context);
conn->SyncXMLLen = atoi(ptr2);
ptr2 = strtok_s(NULL, " ", &context);
conn->SyncMsgLen = atoi(ptr2);
ptr2 = strtok_s(NULL, " ", &context);
BID = LookupBID(ptr1);
if (BID)
{
BBSputs(conn, "Rejected - Duplicate BID\r");
return;
}
conn->TempMsg = zalloc(sizeof(struct MsgInfo));
BBSputs(conn, "OK\r");
return;
}
if (memcmp(Buffer, "TR AddMessage_", 14) == 0)
{
BIDRec * BID;
@ -13590,7 +13787,8 @@ void ProcessSyncModeMessage(CIRCUIT * conn, struct UserInfo * user, char* Buffer
{
char *ptr1, *ptr2, *context;
// TR RequestSync_G8BPQ_14 224 417 0 True
// TR RequestSync_G8BPQ_14 224 417 0 True
WriteLogLine(conn, '<', Buffer, len-1, LOG_BBS);
ptr1 = strtok_s(&Buffer[15], " ", &context); // MID
@ -13863,7 +14061,7 @@ VOID SendServerReply(char * Title, char * MailBuffer, int Length, char * To)
int ReformatSyncMessage(CIRCUIT * conn)
{
// Message has been decompressed - reformat to look lime a WLE message
// Message has been decompressed - reformat to look like a WLE message
char * MsgBit;
char *ptr1, *ptr2;
@ -13883,10 +14081,16 @@ int ReformatSyncMessage(CIRCUIT * conn)
char DateString[80];
struct tm * tm;
char Type[16] = "Private";
char * part[100];
char * part[100] = {""};
char * partname[100];
int partLen[100];
char xml[4096];
// Message has an XML header then the message
// The XML may have control info, so examine it.
// Message has an XML header which I don't think we need, then the message
/*
Date: Mon, 25 Oct 2021 10:22:00 -0000
From: GM8BPQ
@ -13913,9 +14117,20 @@ int ReformatSyncMessage(CIRCUIT * conn)
// WriteLogLine(conn, '<', conn->MailBuffer, conn->TempMsg->length, LOG_BBS);
if (conn->SyncMsgLen == 0)
return 0;
// display the xml for testing
memcpy(xml, conn->MailBuffer, conn->SyncXMLLen);
xml[conn->SyncXMLLen] = 0;
Debugprintf(xml);
if (conn->SyncMsgLen == 0)
{
// No message, Just xml. Looks like a status report
return 0;
}
MsgBit = &conn->MailBuffer[conn->SyncXMLLen];
conn->TempMsg->length -= conn->SyncXMLLen;
@ -13988,8 +14203,14 @@ Loop:
// Unpack Body - seems to be multipart even if only one
Input = MsgBit;
// Can't we just send the whole body through ??
// No, Attachment format is different
// Mbo: GM8BPQ
// Body: 17
// File: 1471 leadercoeffs.txt
Input = MsgBit;
Boundary = initMultipartUnpack(&Input);
i = 0;
@ -14015,6 +14236,12 @@ Loop:
{
// Found Boundary
char * p1, *p2, *ptr3, *ptr4;
int llen;
int Base64 = 0;
int QuotedP = 0;
char * BoundaryStart = ptr;
Partlen = ptr - Msgptr;
ptr += (BLen + 2); // End of Boundary
@ -14026,21 +14253,106 @@ Loop:
// Part Starts with header (content-type, etc), but skip for now
part[i] = strstr(Msgptr, "\r\n\r\n"); // Over separator
// Will check for quoted printable
p1 = Msgptr;
Loop2:
p2 = strchr(p1, '\r');
llen = (int)(p2 - p1);
if (llen)
{
if (_memicmp(p1, "Content-Transfer-Encoding:", 26) == 0)
{
if (_memicmp(&p1[27], "base64", 6) == 0)
Base64 = TRUE;
else if (_memicmp(&p1[27], "quoted", 6) == 0)
QuotedP = TRUE;
}
else if (_memicmp(p1, "Content-Disposition: ", 21) == 0)
{
ptr3 = strstr(&p1[21], "name");
if (ptr3)
{
ptr3 += 5;
if (*ptr3 == '"') ptr3++;
ptr4 = strchr(ptr3, '"');
if (ptr4) *ptr4 = 0;
partname[i] = ptr3;
}
}
if (llen) // Not Null line
{
p1 = p2 + 2; // Skip crlf
goto Loop2;
}
}
part[i] = strstr(p2, "\r\n"); // Over separator
if (part[i])
{
part[i] += 4;
partLen[i] = Partlen - (part[i] - Msgptr) - 2;
part[i] += 2;
partLen[i] = BoundaryStart - part[i] - 2;
if (QuotedP)
partLen[i] = decode_quoted_printable(part[i], partLen[i]);
else if (Base64)
{
int Len = partLen[i], NewLen;
char * ptr = part[i];
char * ptr2 = part[i];
// WLE sends base64 with embedded crlf, so remove them
while (Len-- > 0)
{
if ((*ptr) != 10 && (*ptr) != 13)
*(ptr2++) = *(ptr++);
else
ptr ++;
}
Len = ptr2 - part[i];
ptr = part[i];
ptr2 = part[i];
while (Len > 0)
{
decodeblock(ptr, ptr2);
ptr += 4;
ptr2 += 3;
Len -= 4;
}
NewLen = (int)(ptr2 - part[i]);
if (*(ptr-1) == '=')
NewLen--;
if (*(ptr-2) == '=')
NewLen--;
partLen[i] = NewLen;
}
}
Msgptr = ptr = Input;
i++;
}
// See if more parts
}
else
ptr++;
}
}
// Build the message
tm = gmtime(&Date);
@ -14080,22 +14392,29 @@ Loop:
NewMsg += sprintf(NewMsg, "Body: %d\r\n", partLen[0]);
/*
i == 1;
i = 1;
while (part[i])
{
Msg->B2Flags |= Attachments;
NewMsg += sprintf(NewMsg, "File: %d %s\r\n",
partn[i], partName[i]);
partLen[i], partname[i]);
i++;
}
*/
NewMsg += sprintf(NewMsg, "\r\n"); // Blank Line to end header
// Now add parts
memmove(NewMsg, part[0], partLen[0]);
NewMsg += partLen[0];
i = 0;
while (part[i])
{
memmove(NewMsg, part[i], partLen[i]);
NewMsg += partLen[i];
i++;
NewMsg += sprintf(NewMsg, "\r\n"); // Blank Line between attachments
}
conn->TempMsg->length = NewMsg - SaveMsg;
conn->TempMsg->datereceived = conn->TempMsg->datechanged = time(NULL);
@ -14110,8 +14429,250 @@ Loop:
return TRUE;
}
char * FormatSYNCMessage(CIRCUIT * conn, struct MsgInfo * Msg)
{
// First an XML Header
char * Buffer = malloc(4096 + Msg->length);
int Len = 0;
struct tm *tm;
char Date[32];
char MsgTime[32];
char Separator[33]="";
time_t Time = time(NULL);
char * MailBuffer;
int BodyLen;
char * Encoded;
// Get the message - may need length in header
MailBuffer = ReadMessageFile(Msg->number);
BodyLen = Msg->length;
// Remove any B2 Header
if (Msg->B2Flags & B2Msg)
{
// Remove B2 Headers (up to the File: Line)
char * ptr;
ptr = strstr(MailBuffer, "Body:");
if (ptr)
{
BodyLen = atoi(ptr + 5);
ptr = strstr(ptr, "\r\n\r\n");
}
if (ptr)
{
memcpy(MailBuffer, ptr + 4, BodyLen);
MailBuffer[BodyLen] = 0;
}
}
// encode body as quoted printable;
Encoded = malloc(Msg->length * 3);
BodyLen = encode_quoted_printable(MailBuffer, Encoded, BodyLen);
// Create multipart Boundary
CreateOneTimePassword(&Separator[0], "Key", 0);
CreateOneTimePassword(&Separator[16], "Key", 1);
tm = gmtime(&Time);
sprintf_s(Date, sizeof(Date), "%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 = gmtime(&Msg->datecreated);
sprintf_s(MsgTime, sizeof(Date), "%04d/%02d/%02d %02d:%02d",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min);
Len += sprintf(&Buffer[Len], "<?xml version=\"1.0\"?>\r\n");
Len += sprintf(&Buffer[Len], "<sync_record>\r\n");
Len += sprintf(&Buffer[Len], " <po_sync>\r\n");
Len += sprintf(&Buffer[Len], " <transaction_type>add_message</transaction_type>\r\n");
Len += sprintf(&Buffer[Len], " <timestamp>%s</timestamp>\r\n", Date);
Len += sprintf(&Buffer[Len], " <originating_station>%s</originating_station>\r\n", Msg->from);
Len += sprintf(&Buffer[Len], " </po_sync>\r\n");
Len += sprintf(&Buffer[Len], " <add_message>\r\n");
Len += sprintf(&Buffer[Len], " <register_entry>\r\n");
Len += sprintf(&Buffer[Len], " <MessageId>%s</MessageId>\r\n", Msg->bid);
Len += sprintf(&Buffer[Len], " <Time>%s</Time>\r\n", MsgTime);
Len += sprintf(&Buffer[Len], " <Sender>%s</Sender>\r\n", Msg->from);
Len += sprintf(&Buffer[Len], " <Source>%s</Source>\r\n", Msg->from);
Len += sprintf(&Buffer[Len], " <Precedence>2</Precedence>\r\n");
Len += sprintf(&Buffer[Len], " <Attachment>%s</Attachment>\r\n", (Msg->B2Flags & Attachments) ? "true" : "false");
Len += sprintf(&Buffer[Len], " <CSize>%d</CSize>\r\n", BodyLen);
Len += sprintf(&Buffer[Len], " <Subject>%s</Subject>\r\n", Msg->title);
Len += sprintf(&Buffer[Len], " <RMSOriginator></RMSOriginator>\r\n");
Len += sprintf(&Buffer[Len], " <RMSDestination></RMSDestination>\r\n");
Len += sprintf(&Buffer[Len], " </register_entry>\r\n");
Len += sprintf(&Buffer[Len], " <destinations>\r\n");
Len += sprintf(&Buffer[Len], " <destination>\r\n");
Len += sprintf(&Buffer[Len], " <MessageId>%s</MessageId>\r\n", Msg->bid);
Len += sprintf(&Buffer[Len], " <Priority>450443</Priority>\r\n");
Len += sprintf(&Buffer[Len], " <Destination>%s</Destination>\r\n", Msg->to);
Len += sprintf(&Buffer[Len], " <ForwardedTo></ForwardedTo>\r\n");
Len += sprintf(&Buffer[Len], " <DeliveredVia>0</DeliveredVia>\r\n");
Len += sprintf(&Buffer[Len], " <SentToCMS>False</SentToCMS>\r\n");
Len += sprintf(&Buffer[Len], " <SentViaRadio>False</SentViaRadio>\r\n");
Len += sprintf(&Buffer[Len], " <SentViaTelnet>False</SentViaTelnet>\r\n");
Len += sprintf(&Buffer[Len], " <LocalOnly>False</LocalOnly>\r\n");
Len += sprintf(&Buffer[Len], " </destination>\r\n");
Len += sprintf(&Buffer[Len], " </destinations>\r\n");
Len += sprintf(&Buffer[Len], " <misc>\r\n");
Len += sprintf(&Buffer[Len], " <Local>True</Local>\r\n");
Len += sprintf(&Buffer[Len], " <LocalOnly>False</LocalOnly>\r\n");
Len += sprintf(&Buffer[Len], " </misc>\r\n");
Len += sprintf(&Buffer[Len], " </add_message>\r\n");
Len += sprintf(&Buffer[Len], "</sync_record>\r\n");
// Debugprintf(Buffer);
conn->SyncXMLLen = Len;
Len += sprintf(&Buffer[Len], "Date: Sat, 04 Feb 2023 11:19:00 +0000\r\n");
Len += sprintf(&Buffer[Len], "From: %s\r\n", Msg->from);
Len += sprintf(&Buffer[Len], "Subject: %s\r\n", Msg->title);
Len += sprintf(&Buffer[Len], "To: %s\r\n", Msg->to);
Len += sprintf(&Buffer[Len], "Message-ID: %s\r\n", Msg->bid);
// Len += sprintf(&Buffer[Len], "X-Source: G8BPQ\r\n");
// Len += sprintf(&Buffer[Len], "X-Location: 52.979167N, 1.125000W (GRID SQUARE)\r\n");
// Len += sprintf(&Buffer[Len], "X-RMS-Originator: G8BPQ\r\n");
// Len += sprintf(&Buffer[Len], "X-RMS-Path: G8BPQ@2023-02-04-11:19:29\r\n");
Len += sprintf(&Buffer[Len], "X-Relay: %s\r\n", BBSName);
Len += sprintf(&Buffer[Len], "MIME-Version: 1.0\r\n");
Len += sprintf(&Buffer[Len], "Content-Type: multipart/mixed; boundary=\"%s\"\r\n", Separator);
Len += sprintf(&Buffer[Len], "\r\n"); // Blank line before separator
Len += sprintf(&Buffer[Len], "--%s\r\n", Separator);
Len += sprintf(&Buffer[Len], "Content-Type: text/plain; charset=\"iso-8859-1\"\r\n");
Len += sprintf(&Buffer[Len], "Content-Transfer-Encoding: quoted-printable\r\n");
Len += sprintf(&Buffer[Len], "\r\n"); // Blank line before body
Len += sprintf(&Buffer[Len], "%s\r\n", Encoded);
Len += sprintf(&Buffer[Len], "--%s--\r\n", Separator);
conn->SyncMsgLen = Len - conn->SyncXMLLen;
free(Encoded);
free(MailBuffer);
/*
Date: Sat, 04 Feb 2023 11:19:00 +0000
From: G8BPQ
Subject: Sync Test 5
To: GM8BPQ
Message-ID: E4P6YIYGQ347
X-Source: G8BPQ
X-Location: 52.979167N, 1.125000W (GRID SQUARE)
X-RMS-Originator: G8BPQ
X-RMS-Path: G8BPQ@2023-02-04-11:19:29
X-Relay: G8BPQ
MIME-Version: 1.0
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="boundaryHjgswg=="
--boundaryHjgswg==
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Message 5 with attachments
--boundaryHjgswg==
Content-Disposition: attachment; name="new1.html";
filename="new1.html"
Content-Type: attachment; name="new1.html"
Content-Transfer-Encoding: base64
PCFET0NUWVBFIGh0bWw+DQo8aHRtbD4NCg0KDQogIDxoZWFkPg0KICAgIDx0aXRsZT4NCiAgICAg
IENvbnNwaXJhY3kgVGhlb3JpZXMNCiAgICA8L3RpdGxlPg0KICA8L2hlYWQ+DQogIDxib2R5Pg0K
ICAgIDxkaXYgc3R5bGU9J3RleHQtYWxpZ246IGNlbnRlcjsnPjxkaXYgc3R5bGU9J2Rpc3BsYXk6
IGlubGluZS1ibG9jazsnPjxzcGFuIHN0eWxlPSdkaXNwbGF5OmJsb2NrOyB0ZXh0LWFsaWduOiBs
ZWZ0Oyc+DQoJICBhYWFhYWE8YnI+DQogICAgICBiYjxicj4NCiAgICAgIGNjY2NjY2NjYyBjY2Nj
Y2NjY2NjY2NjPGJyPg0KCSAgPC9zcGFuPg0KICAgICAgPC9kaXY+DQogICAgPC9kaXY+DQogIDwv
Ym9keT4NCjwvaHRtbD4=
--boundaryHjgswg==--
*/
return Buffer;
}
int encode_quoted_printable(char *s, char * out, int Len)
{
int n = 0;
char * start = out;
while(Len--)
{
if (n >= 73 && *s != 10 && *s != 13)
{strcpy(out, "=\r\n"); n = 0; out +=3;}
if (*s == 10 || *s == 13) {putchar(*s); n = 0;}
else if (*s<32 || *s==61 || *s>126)
out += sprintf(out, "=%02x", (unsigned char)*s);
else if (*s != 32 || (*(s+1) != 10 && *(s+1) != 13))
{*(out++) = *s; n++;}
else n += printf("=20");
s++;
}
*out = 0;
return out - start;
}
int decode_quoted_printable(char *ptr, int len)
{
// overwrite input with decoded version
char * ptr2 = ptr;
char * End = ptr + len;
char * Start = ptr;
while (ptr < End)
{
if ((*ptr) == '=')
{
char c = *(++ptr);
char d;
c = c - 48;
if (c < 0)
{
// = CRLF as a soft break
ptr += 2;
continue;
}
if (c > 9) c -= 7;
d = *(++ptr);
d = d - 48;
if (d > 9) d -= 7;
*(ptr2) = c << 4 | d;
ptr2++;
ptr++;
}
else
*ptr2++ = *ptr++;
}
return ptr2 - Start;
}

View File

@ -1103,8 +1103,9 @@
// Change web buttons to white on black when pressed (10)
// Add auto-refresh option to Webmail index page (25)
// Fix displaying help and info files with crlf line endings on Linux (28)
// Impotove validation of extended FC message (32)
// Improve validation of extended FC message (32)
// Improve WP check for SYSTEM as a callsihn (33)
// Improvements to RMS Relay SYNC mode (
#include "bpqmail.h"

View File

@ -1139,7 +1139,11 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
// Fix Interlock of incoming UZ7HO connections (41)
// Disable VARA Actions menu if not sysop (41)
// Fix Port CTEXT on UZ7HO B C or D channels (42)
// Fix repeated trigger of SessionTimeLimit (43)
// Fix posible memory corruption in UpateMH (44)
// Add PHG to APRS beacons (45)
// Dont send DM to stations in exclude list(45)
// Improvements to RMS Relay SYNC Mode (46)
#define CKernel

View File

@ -728,7 +728,7 @@ VOID CheckForDetach(struct TNCINFO * TNC, int Stream, struct STREAMINFO * STREAM
// Create a traffic record
if (STREAM->Connected)
if (STREAM->Connected && STREAM->ConnectTime)
{
Duration = time(NULL) - STREAM->ConnectTime;
@ -741,6 +741,8 @@ VOID CheckForDetach(struct TNCINFO * TNC, int Stream, struct STREAMINFO * STREAM
STREAM->BytesRXed, (int)(STREAM->BytesRXed/Duration), (int)Duration);
Debugprintf(logmsg);
STREAM->ConnectTime = 0;
}
if (STREAM->BPQtoPACTOR_Q) // Still data to send?
@ -897,7 +899,9 @@ BOOL ProcessIncommingConnectEx(struct TNCINFO * TNC, char * Call, int Stream, BO
PMSGWITHLEN buffptr;
int Totallen = 0;
UCHAR * ptr;
struct PORTCONTROL * PORT = &TNC->PortRecord->PORTCONTROL;
struct PORTCONTROL * PORT;
PORT = &TNC->PortRecord->PORTCONTROL;
// Stop Scanner
@ -908,6 +912,7 @@ BOOL ProcessIncommingConnectEx(struct TNCINFO * TNC, char * Call, int Stream, BO
sprintf(Msg, "%d SCANSTOP", TNC->Port);
Rig_Command(-1, Msg);
UpdateMH(TNC, Call, '+', 'I');
}
@ -967,7 +972,7 @@ BOOL ProcessIncommingConnectEx(struct TNCINFO * TNC, char * Call, int Stream, BO
return TRUE;
// if Port CTEXT defined, use it
if (PORT->CTEXT)
{
Totallen = strlen(PORT->CTEXT);

View File

@ -1358,7 +1358,6 @@ VOID UpdateMHSupport(struct TNCINFO * TNC, UCHAR * Call, char Mode, char Directi
int OldCount = 0;
char ReportCall[16];
if (MH == 0) return;
if (Digis)
@ -1445,7 +1444,6 @@ VOID UpdateMHSupport(struct TNCINFO * TNC, UCHAR * Call, char Mode, char Directi
goto NOLOC;
}
LOC = memchr(Call, '(', 20);
if (LOC)
@ -1500,6 +1498,7 @@ NOLOC:
// Move others down and add at front
DoMove:
if (i != 0) // First
memmove(MHBASE + 1, MHBASE, i * sizeof(MHSTRUC));

View File

@ -730,6 +730,14 @@ VOID ProcessChatLine(ChatCIRCUIT * conn, struct UserInfo * user, char* OrigBuffe
{
// Process Command
int cmdLen = 0;
char * param = strchr(&Buffer[1], ' ');
if (param)
cmdLen = param - &Buffer[1];
else
cmdLen = strlen(&Buffer[1]);
if (_memicmp(&Buffer[1], "Bye", 1) == 0)
{
SendUnbuffered(conn->BPQStream, ChatSignoffMsg, (int)strlen(ChatSignoffMsg));
@ -767,15 +775,20 @@ VOID ProcessChatLine(ChatCIRCUIT * conn, struct UserInfo * user, char* OrigBuffe
return;
}
if (_memicmp(&Buffer[1], "History", 7) == 0)
if (_memicmp(&Buffer[1], "History", cmdLen) == 0)
{
// Param is number of minutes to go back (max 24 hours)
struct HistoryRec * ptr = History;
int interval = atoi(&Buffer[9]) * 60;
time_t start = time(NULL) - interval;
int interval = 0;
time_t start;
int n = HistoryCount;
if (param)
interval = atoi(param) * 60;
start = time(NULL) - interval;
if (interval < 1)
{
nprintf(conn, "Format is /history n, where n is history time in minutes\r");

View File

@ -1538,6 +1538,12 @@ VOID L2SENDUA(struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER)
VOID L2SENDDM(struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER)
{
if (CheckExcludeList(Buffer->ORIGIN) == 0) // if in exclude, don't send DM
{
ReleaseBuffer(Buffer); // not sure that this is the right place for releasing?
return;
}
L2SENDRESP(PORT, Buffer, ADJBUFFER, DM);
}

View File

@ -2768,7 +2768,7 @@ void encodeblock( unsigned char in[3], unsigned char out[4], int len )
out[3] = (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '=');
}
void decodeblock( unsigned char in[4], unsigned char out[3] )
void decodeblock( unsigned char in[4], unsigned char out[3])
{
char Block[5];

View File

@ -973,7 +973,32 @@ VOID ProcessNNTPServerMessage(SocketConn * sockptr, char * Buffer, int Len)
return;
}
*/
if(memcmp(Buffer, "DATE", 4) == 0)
{
//This command returns a one-line response code of 111 followed by the
//GMT date and time on the server in the form YYYYMMDDhhmmss.
// 111 YYYYMMDDhhmmss
struct tm *tm;
char Date[32];
time_t Time = time(NULL);
tm = gmtime(&Time);
if (tm)
{
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);
SendSock(sockptr, Date);
}
else
SendSock(sockptr, "500 command not recognized");
return;
}
SendSock(sockptr, "500 command not recognized");
return;

View File

@ -4259,16 +4259,26 @@ int DataSocket_ReadSync(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, S
if (sockptr->LoginState == 0) // Initial connection
{
// if (TNC->Streams[Stream].Connected == 0)
// First Message should be POSYNCLOGON CALL
strcpy(sockptr->Callsign, "SYNC");
// Extract the callsign
char * call = strlop(MsgPtr, ' ');
if (call == NULL || strcmp(MsgPtr, "POSYNCLOGON") !=0)
{
DataSocket_Disconnect(TNC, sockptr); //' Tidy up
return 0;
}
strcpy(sockptr->Callsign, call);
sockptr->UserPointer = &SyncUser;
SendtoNode(TNC, sockptr->Number, TCP->SyncAPPL, (int)strlen(TCP->SyncAPPL));
BuffertoNode(sockptr, MsgPtr, InputLen);
STREAM->RelaySyncStream = 1;
sockptr->LoginState = 1;
sockptr->LoginState = 2;
ShowConnections(TNC);
return 0;

20
VARA.c
View File

@ -349,8 +349,10 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
{
if (TNC->SessionTimeLimit && STREAM->ConnectTime && time(NULL) > (TNC->SessionTimeLimit + STREAM->ConnectTime))
{
VARASendCommand(TNC, "ABORT\r", TRUE);
VARASendCommand(TNC, "CLEANTXBUFFER\r", TRUE);
VARASendCommand(TNC, "DISCONNECT\r", TRUE);
STREAM->Disconnecting = TRUE;
TNC->SessionTimeLimit += 120; // Don't retrigger unless things have gone horribly wrong
}
}
@ -2127,7 +2129,7 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
return; // No buffers, so ignore
}
buffptr->Len = sprintf(buffptr->Data, "VARA} Failure with %s\r", TNC->Streams[0].RemoteCall);
buffptr->Len = sprintf(buffptr->Data, "VARA} Failure with %s\r", STREAM->RemoteCall);
C_Q_ADD(&TNC->WINMORtoBPQ_Q, buffptr);
@ -2147,7 +2149,7 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
// Release Session
if (TNC->Streams[0].Connected)
if (STREAM->Connected && STREAM->ConnectTime)
{
// Create a traffic record
@ -2165,17 +2167,19 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
STREAM->BytesRXed, (int)(STREAM->BytesRXed/Duration), (int)Duration);
Debugprintf(logmsg);
STREAM->ConnectTime= 0; //Prevent retrigger
}
TNC->Streams[0].Connecting = FALSE;
TNC->Streams[0].Connected = FALSE; // Back to Command Mode
TNC->Streams[0].ReportDISC = TRUE; // Tell Node
STREAM->Connecting = FALSE;
STREAM->Connected = FALSE; // Back to Command Mode
STREAM->ReportDISC = TRUE; // Tell Node
if (TNC->Streams[0].Disconnecting) //
if (STREAM->Disconnecting) //
VARAReleaseTNC(TNC);
TNC->Streams[0].Disconnecting = FALSE;
STREAM->Disconnecting = FALSE;
return;
}

View File

@ -10,8 +10,8 @@
#endif
#define KVers 6,0,23,42
#define KVerstring "6.0.23.42\0"
#define KVers 6,0,23,46
#define KVerstring "6.0.23.46\0"
#ifdef CKernel

View File

@ -78,6 +78,9 @@ int BadCall(char * Call)
if (_memicmp(Call, "MCAST", 5) == 0)
return 1;
if (_memicmp(Call, "SYNC", 5) == 0)
return 1;
return 0;
}

View File

@ -66,7 +66,8 @@
// Add History (28)
// Add connect scripts to config page text (31)
// Fix History (31)
// Stop buffer overflow in History (
// Stop buffer overflow in History
// Allow /History to be shortened to /Hi (45)
#include "BPQChat.h"
#include "Dbghelp.h"

View File

@ -274,6 +274,7 @@ typedef struct ConnectionInfo_S
int SyncCompressedLen;
int SyncXMLLen;
int SyncMsgLen;
UCHAR * SyncMessage; // Compressed SYNC message to send
// These are used to detect CRLF split over a packet boundary
int usingCR; // Session is (normally) using CR as terminator
@ -294,6 +295,8 @@ typedef struct ConnectionInfo_S
#define SENDTITLE 64
#define SENDBODY 128
#define WAITPROMPT 256 // Waiting for prompt after message
#define PROPOSINGSYNCMSG 512 // Sent proposal to SYNC, waiting response
#define SENDINGSYNCMSG 1024 // Sent messagr to SYNC, waiting response
// BBSFlags Equates

View File

@ -1108,7 +1108,7 @@ BOOL Start()
ptr3 = (char *)PORT->PORTPOINTER; // Permitted Calls follows Port Info
PORT->PORTMHEARD = (PMHSTRUC)ptr3;
ptr3 += MHENTRIES * sizeof(MHSTRUC);
ptr3 += (MHENTRIES + 1)* sizeof(MHSTRUC);
// Round to word boundsaty (for ARM5 etc)

View File

@ -927,10 +927,7 @@ void Decode(CIRCUIT * conn, int FromSync)
// Refomat Sync message as if from WLE
if (ReformatSyncMessage(conn) == 0)
{
BBSputs(conn, "OK\r"); // only xml - don't need it (i think)
return;
}
FBBHeader->B2Message = TRUE;
FBBHeader->MsgType = 'P';