diff --git a/APRSCode.c b/APRSCode.c index 76b0140..a54371b 100644 --- a/APRSCode.c +++ b/APRSCode.c @@ -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; diff --git a/ARDOP.c b/ARDOP.c index 1e1c9be..36c344a 100644 --- a/ARDOP.c +++ b/ARDOP.c @@ -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 + + } diff --git a/BBSUtilities.c b/BBSUtilities.c index a90fb2d..c161cb6 100644 --- a/BBSUtilities.c +++ b/BBSUtilities.c @@ -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 + +/* +OK +>TR AddMessage_V5JLSGH591JR 786 1219 522 True +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], "\r\n"); + + Len += sprintf(&Buffer[Len], "\r\n"); + Len += sprintf(&Buffer[Len], " \r\n"); + Len += sprintf(&Buffer[Len], " add_message\r\n"); + Len += sprintf(&Buffer[Len], " %s\r\n", Date); + Len += sprintf(&Buffer[Len], " %s\r\n", Msg->from); + Len += sprintf(&Buffer[Len], " \r\n"); + Len += sprintf(&Buffer[Len], " \r\n"); + Len += sprintf(&Buffer[Len], " \r\n"); + Len += sprintf(&Buffer[Len], " %s\r\n", Msg->bid); + Len += sprintf(&Buffer[Len], " \r\n", MsgTime); + Len += sprintf(&Buffer[Len], " %s\r\n", Msg->from); + Len += sprintf(&Buffer[Len], " %s\r\n", Msg->from); + Len += sprintf(&Buffer[Len], " 2\r\n"); + Len += sprintf(&Buffer[Len], " %s\r\n", (Msg->B2Flags & Attachments) ? "true" : "false"); + Len += sprintf(&Buffer[Len], " %d\r\n", BodyLen); + Len += sprintf(&Buffer[Len], " %s\r\n", Msg->title); + Len += sprintf(&Buffer[Len], " \r\n"); + Len += sprintf(&Buffer[Len], " \r\n"); + Len += sprintf(&Buffer[Len], " \r\n"); + Len += sprintf(&Buffer[Len], " \r\n"); + Len += sprintf(&Buffer[Len], " \r\n"); + Len += sprintf(&Buffer[Len], " %s\r\n", Msg->bid); + Len += sprintf(&Buffer[Len], " 450443\r\n"); + Len += sprintf(&Buffer[Len], " %s\r\n", Msg->to); + Len += sprintf(&Buffer[Len], " \r\n"); + Len += sprintf(&Buffer[Len], " 0\r\n"); + Len += sprintf(&Buffer[Len], " False\r\n"); + Len += sprintf(&Buffer[Len], " False\r\n"); + Len += sprintf(&Buffer[Len], " False\r\n"); + Len += sprintf(&Buffer[Len], " False\r\n"); + Len += sprintf(&Buffer[Len], " \r\n"); + Len += sprintf(&Buffer[Len], " \r\n"); + Len += sprintf(&Buffer[Len], " \r\n"); + Len += sprintf(&Buffer[Len], " True\r\n"); + Len += sprintf(&Buffer[Len], " False\r\n"); + Len += sprintf(&Buffer[Len], " \r\n"); + Len += sprintf(&Buffer[Len], " \r\n"); + Len += sprintf(&Buffer[Len], "\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; +} diff --git a/BPQMail.c b/BPQMail.c index fa2b149..402e25c 100644 --- a/BPQMail.c +++ b/BPQMail.c @@ -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" diff --git a/Bpq32.c b/Bpq32.c index 63903d4..8a3c3b9 100644 --- a/Bpq32.c +++ b/Bpq32.c @@ -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 diff --git a/CommonCode.c b/CommonCode.c index c2f6e75..2abf722 100644 --- a/CommonCode.c +++ b/CommonCode.c @@ -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); diff --git a/HFCommon.c b/HFCommon.c index 723d33d..efe1e9e 100644 --- a/HFCommon.c +++ b/HFCommon.c @@ -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)); diff --git a/HanksRT.c b/HanksRT.c index a65b38e..ab34b66 100644 --- a/HanksRT.c +++ b/HanksRT.c @@ -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"); diff --git a/L2Code.c b/L2Code.c index 86c01f4..78c58c7 100644 --- a/L2Code.c +++ b/L2Code.c @@ -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); } diff --git a/MailTCP.c b/MailTCP.c index ebdaf77..b67b839 100644 --- a/MailTCP.c +++ b/MailTCP.c @@ -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]; diff --git a/NNTPRoutines.c b/NNTPRoutines.c index 385f6a7..2875a06 100644 --- a/NNTPRoutines.c +++ b/NNTPRoutines.c @@ -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; diff --git a/TelnetV6.c b/TelnetV6.c index 0e765f2..67c4f68 100644 --- a/TelnetV6.c +++ b/TelnetV6.c @@ -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; diff --git a/VARA.c b/VARA.c index 5dddeca..40a02c2 100644 --- a/VARA.c +++ b/VARA.c @@ -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; } diff --git a/Versions.h b/Versions.h index abe445f..6a4d343 100644 --- a/Versions.h +++ b/Versions.h @@ -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 diff --git a/WPRoutines.c b/WPRoutines.c index 856c0ec..4a065b5 100644 --- a/WPRoutines.c +++ b/WPRoutines.c @@ -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; } diff --git a/bpqchat.c b/bpqchat.c index f2be464..a090d38 100644 --- a/bpqchat.c +++ b/bpqchat.c @@ -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" diff --git a/bpqmail.h b/bpqmail.h index 603d850..d868bf8 100644 --- a/bpqmail.h +++ b/bpqmail.h @@ -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 diff --git a/cMain.c b/cMain.c index e4e57cf..7758eac 100644 --- a/cMain.c +++ b/cMain.c @@ -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) diff --git a/lzhuf32.c b/lzhuf32.c index 17d9bee..7289086 100644 --- a/lzhuf32.c +++ b/lzhuf32.c @@ -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';