diff --git a/BBSUtilities.c b/BBSUtilities.c index 2cb6ee5..833d3f9 100644 --- a/BBSUtilities.c +++ b/BBSUtilities.c @@ -10823,6 +10823,15 @@ int Disconnected (int Stream) } } + user = conn->UserPointer; + + if (user && (conn->lastmsg > user->lastmsg)) + { + user->lastmsg = conn->lastmsg; + SaveUserDatabase(); + } + + // if sysop was chatting to user clear link #ifndef LINBPQ if (conn->BBSFlags & SYSOPCHAT) diff --git a/BPQChat.vcproj.SKIGACER.johnw.user b/BPQChat.vcproj.SKIGACER.johnw.user deleted file mode 100644 index b5b0536..0000000 --- a/BPQChat.vcproj.SKIGACER.johnw.user +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - diff --git a/BPQMail.c b/BPQMail.c index 91b66ba..bbc9ece 100644 --- a/BPQMail.c +++ b/BPQMail.c @@ -1129,6 +1129,8 @@ // Add TO and AT to "Message has nowhere to go" message (28) // Add My Sent and My Received filter options to Webmail (30) // Add Send P to multiple BBS's when routing on HR (30) +// Fix Traffic stats for T messages received via B2 forwarding (31) +// Fix possible failure to update last listed count when user disconnects without using B command #include "bpqmail.h" #include "winstdint.h" diff --git a/BPQMail.vcproj.NOTTSDESKTOP.John.user b/BPQMail.vcproj.NOTTSDESKTOP.John.user deleted file mode 100644 index fa82c00..0000000 --- a/BPQMail.vcproj.NOTTSDESKTOP.John.user +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - diff --git a/BPQWinAPP.vcproj.NOTTSDESKTOP.John.user b/BPQWinAPP.vcproj.NOTTSDESKTOP.John.user deleted file mode 100644 index fa82c00..0000000 --- a/BPQWinAPP.vcproj.NOTTSDESKTOP.John.user +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - diff --git a/Bpq32.c b/Bpq32.c index d826062..c7b939c 100644 --- a/Bpq32.c +++ b/Bpq32.c @@ -1209,6 +1209,8 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses // Improvments to reporting to M0LTE Map (26) // IPGateway fix from github user isavitsky (27) // Fix possible crash in SCSPactor PTCPORT code (29) +// Add NodeAPI call sendLinks and remove get from other calls (32) +// Improve validation of Web Beacon Config (33) #define CKernel @@ -6518,6 +6520,7 @@ VOID GetParam(char * input, char * key, char * value) char * ptr1, * ptr2; char c; + if (ptr) { ptr2 = strchr(ptr, '&'); diff --git a/CBPQ32.vcproj.NOTTSDESKTOP.John.user b/CBPQ32.vcproj.NOTTSDESKTOP.John.user deleted file mode 100644 index 270b67b..0000000 --- a/CBPQ32.vcproj.NOTTSDESKTOP.John.user +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - diff --git a/CBPQ32.vcproj.SKIGACER.johnw.user b/CBPQ32.vcproj.SKIGACER.johnw.user deleted file mode 100644 index f8a6101..0000000 --- a/CBPQ32.vcproj.SKIGACER.johnw.user +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - diff --git a/CommonCode.c b/CommonCode.c index abcbee1..da9b2d7 100644 --- a/CommonCode.c +++ b/CommonCode.c @@ -5003,20 +5003,20 @@ extern int MasterPort[MAXBPQPORTS+1]; 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]; + 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; + if (MH == NULL) + return; - while (count--) + while (count--) { if (MH->MHCALL[0] == 0) break; @@ -5028,22 +5028,22 @@ void BuildPortMH(char * MHJSON, struct PORTCONTROL * PORT) if ((*ptr & 1) == 0) { - // at least one digi - which we are not going to include - MH++; - continue; + // 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); + 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); + Normcall, PORT->PORTNUMBER, MH->MHCOUNT, MHTIME); strcat( MHJSON, mhstr ); diff --git a/HTTPcode.c b/HTTPcode.c index 049fce3..0e62928 100644 --- a/HTTPcode.c +++ b/HTTPcode.c @@ -2462,29 +2462,29 @@ doHeader: return 1; } - GetParam(input, "Port", &Param[0]); - Port = atoi(&Param[1]); + GetParam(input, "Port=", &Param[0]); + Port = atoi(&Param[0]); PORT = GetPortTableEntryFromPortNum(Port); // Need slot not number if (PORT) Slot = PORT->PortSlot; - GetParam(input, "Every", &Param[0]); - Interval[Slot] = atoi(&Param[1]); + GetParam(input, "Every=", &Param[0]); + Interval[Slot] = atoi(&Param[0]); - GetParam(input, "Dest", &Param[0]); + GetParam(input, "Dest=", &Param[0]); _strupr(Param); - strcpy(UIUIDEST[Slot], &Param[1]); + strcpy(UIUIDEST[Slot], &Param[0]); - GetParam(input, "Path", &Param[0]); + GetParam(input, "Path=", &Param[0]); _strupr(Param); if (UIUIDigi[Slot]) free(UIUIDigi[Slot]); - UIUIDigi[Slot] = _strdup(&Param[1]); + UIUIDigi[Slot] = _strdup(&Param[0]); - GetParam(input, "File", &Param[0]); + GetParam(input, "File=", &Param[0]); strcpy(FN[Slot], &Param[1]); - GetParam(input, "Text", &Param[0]); - strcpy(Message[Slot], &Param[1]); + GetParam(input, "Text=", &Param[0]); + strcpy(Message[Slot], &Param[0]); MinCounter[Slot] = Interval[Slot]; diff --git a/MailNode.vcproj.NOTTSDESKTOP.John.user b/MailNode.vcproj.NOTTSDESKTOP.John.user deleted file mode 100644 index fa82c00..0000000 --- a/MailNode.vcproj.NOTTSDESKTOP.John.user +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - diff --git a/RTKnown.txt b/RTKnown.txt new file mode 100644 index 0000000..e69de29 diff --git a/Versions.h b/Versions.h index 0c9ebab..b83cbbe 100644 --- a/Versions.h +++ b/Versions.h @@ -10,8 +10,8 @@ #endif -#define KVers 6,0,24,30 -#define KVerstring "6.0.24.30\0" +#define KVers 6,0,24,33 +#define KVerstring "6.0.24.33\0" #ifdef CKernel diff --git a/WebMail.c b/WebMail.c index f493c06..569796f 100644 --- a/WebMail.c +++ b/WebMail.c @@ -3715,7 +3715,6 @@ char * BuildB2Header(WebMailInfo * WebMail, struct MsgInfo * Msg, char ** ToCall for (i = 0; i < Calls; i++) NewMsg += sprintf(NewMsg, "To: %s\r\n", ToCalls[i]); - } else { diff --git a/WinRPRHelper.vcproj.NOTTSDESKTOP.John.user b/WinRPRHelper.vcproj.NOTTSDESKTOP.John.user deleted file mode 100644 index fa82c00..0000000 --- a/WinRPRHelper.vcproj.NOTTSDESKTOP.John.user +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - diff --git a/WinmorControl.vcproj.NOTTSDESKTOP.John.user b/WinmorControl.vcproj.NOTTSDESKTOP.John.user deleted file mode 100644 index fa82c00..0000000 --- a/WinmorControl.vcproj.NOTTSDESKTOP.John.user +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - diff --git a/bpqmail.h b/bpqmail.h index 9081e19..0071261 100644 --- a/bpqmail.h +++ b/bpqmail.h @@ -620,7 +620,7 @@ struct MsgInfo char title[61]; int nntpnum; // Number within topic (ie Bull TO Addr) - used for nntp - UCHAR B2Flags; + UCHAR B2Flags; // Not all flags specific to B2 #define B2Msg 1 // Set if Message File is a formatted B2 message #define Attachments 2 // Set if B2 message has attachments @@ -629,6 +629,7 @@ struct MsgInfo #define FromRMSExpress 16 #define RadioOnlyMsg 32 // Received using call-T #define RadioOnlyFwd 64 // Received using call-R + #define WarnNotForwardedSent 128 int xdatecreated; int xdatechanged; diff --git a/chatconfig.cfg b/chatconfig.cfg index 1533ced..49e3f4e 100644 --- a/chatconfig.cfg +++ b/chatconfig.cfg @@ -18,5 +18,5 @@ Chat : MonitorSize = "828,1644,148,770"; DebugSize = "0,0,0,0"; WindowSize = "231,835,254,602"; - Version = "6,0,23,59"; + Version = "6,0,24,32"; }; diff --git a/lzhuf32.c b/lzhuf32.c index 7289086..3482b30 100644 --- a/lzhuf32.c +++ b/lzhuf32.c @@ -933,15 +933,21 @@ void Decode(CIRCUIT * conn, int FromSync) FBBHeader->MsgType = 'P'; } - if (FBBHeader->MsgType == 'P') - Index = PMSG; - else if (FBBHeader->MsgType == 'B') - Index = BMSG; - else if (FBBHeader->MsgType == 'T') - Index = TMSG; + if (!FBBHeader->B2Message) + { + // With B2 the Type is specified in the body, so can't update stats now + + if (FBBHeader->MsgType == 'P') + Index = PMSG; + else if (FBBHeader->MsgType == 'B') + Index = BMSG; + else if (FBBHeader->MsgType == 'T') + Index = TMSG; + + conn->UserPointer->Total.MsgsReceived[Index]++; + conn->UserPointer->Total.BytesForwardedIn[Index] += count; + } - conn->UserPointer->Total.MsgsReceived[Index]++; - conn->UserPointer->Total.BytesForwardedIn[Index] += count; if (FBBHeader->B2Message) { @@ -1497,6 +1503,7 @@ File: 5566 NEWBOAT.HOMEPORT.JPG // Processed all headers + // If multiple recipents, create one copy for each BBS address, and one for all others (via RMS) if (Recipients == 0 || HddrTo == NULL) @@ -1702,9 +1709,9 @@ File: 5566 NEWBOAT.HOMEPORT.JPG ptr += 7; - // This handles a message arriving with bull/ or nts/ oerrides + // This handles a message arriving with bull/ or nts/ overrides - if (_memicmp(ptr, "Private", 7) == 0 && Msg->type != 'P') + if (_memicmp(ptr, "Private", 7) == 0 && Msg->type != 'P') { if (Msg->type == 'T') memcpy(ptr, "Traffic", 7); @@ -1744,6 +1751,18 @@ File: 5566 NEWBOAT.HOMEPORT.JPG if (i > 0 && Msg->type != 'B') // Must Change the BID Msg->bid[0] = 0; + // Update Stats + + if (Msg->type == 'P') + Index = PMSG; + else if (Msg->type == 'B') + Index = BMSG; + else if (Msg->type == 'T') + Index = TMSG; + + conn->UserPointer->Total.MsgsReceived[Index]++; + conn->UserPointer->Total.BytesForwardedIn[Index] += MsgLen; + CreateMessageFromBuffer(conn); } } // End not from RMS @@ -1759,33 +1778,7 @@ File: 5566 NEWBOAT.HOMEPORT.JPG SetupNextFBBMessage(conn); return; } -/* - else - { - // Single Destination - Need to put to: line back in message - char * ptr = HddrTo[0]; - __int32 ToLen; - char toCopy[80]; - - - ptr = HddrTo[0]; - - if (_memicmp(&ptr[4], "nts:", 4) == 0) - memmove(ptr + 4, ptr + 8, strlen(ptr + 7)); - - ToLen = strlen(ptr); - - memmove(&conn->MailBuffer[B2To + ToLen], &conn->MailBuffer[B2To], count); - memcpy(&conn->MailBuffer[B2To], HddrTo[0], ToLen); - conn->TempMsg->length += ToLen; - Msg->type = Type[i]; - - CreateMessageFromBuffer(conn); - SetupNextFBBMessage(conn); - return; - } -*/ #ifndef LINBPQ } #define EXCEPTMSG "Error Decoding B2 Message" @@ -1800,8 +1793,6 @@ File: 5566 NEWBOAT.HOMEPORT.JPG #endif } // end if B2Msg - // Look for - CreateMessageFromBuffer(conn); SetupNextFBBMessage(conn); } \ No newline at end of file diff --git a/nodeapi.c b/nodeapi.c index 8a5a814..eef71e8 100644 --- a/nodeapi.c +++ b/nodeapi.c @@ -40,6 +40,8 @@ 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); +int sendLinks(char * response, char * token, int Flags); +int sendPortMHList(char * response, char * token, int Flags); DllExport struct PORTCONTROL * APIENTRY GetPortTableEntryFromSlot(int portslot); @@ -64,14 +66,18 @@ int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * req 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; + char * Tok = strlop(URL, '?'); + char * param = strlop(Tok, '&'); - if (param && strlen(param) == TOKEN_SIZE) + if (param) + Flags = atoi(param); + + if (Tok && strlen(Tok) == TOKEN_SIZE) { // assume auth token - strcpy(token, param); + strcpy(token, Tok); } remove_expired_tokens(); // Tidy up @@ -106,17 +112,20 @@ int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * req // Determine the requested API endpoint - if (_stricmp(URL, "/api/getports") == 0) + if (_stricmp(URL, "/api/ports") == 0) return sendPortList(response, token, Flags); - else if (_stricmp(URL, "/api/getnodes") == 0) + else if (_stricmp(URL, "/api/nodes") == 0) return sendNodeList(response, token, Flags); - else if (_stricmp(URL, "/api/getusers") == 0) + else if (_stricmp(URL, "/api/users") == 0) return sendUserList(response, token, Flags); - else if (_stricmp(URL, "/api/getinfo") == 0) + else if (_stricmp(URL, "/api/info") == 0) return sendInfo(response, token, Flags); + else if (_stricmp(URL, "/api/links") == 0) + return sendLinks(response, token, Flags); + else if (strstr(URL, "/api/mheardport") != 0) + return sendPortMHList(response, token, Flags); return send_http_response(response, "401 Invalid API Call"); - } int request_token(char * response) @@ -631,3 +640,87 @@ int sendInfo(char * response, char * token, int Flags) return strlen(response); } + +int sendLinks(char * response, char * token, int Flags) +{ + struct _LINKTABLE * Links = LINKS; + int MaxLinks = MAXLINKS; + int count; + char Normcall1[10]; + char Normcall2[10]; + char State[12] = "", Type[12] = "Uplink"; + int axState; + int cctType; + int ReplyLen = 0; + ReplyLen += sprintf(&response[ReplyLen],"{\"links\":[\r\n"); + + for (count=0; countLINKCALL[0] != 0) + { + int len = ConvFromAX25(Links->LINKCALL, Normcall1); + Normcall1[len] = 0; + + len = ConvFromAX25(Links->OURCALL, Normcall2); + Normcall2[len] = 0; + + + axState = Links->L2STATE; + + if (axState == 2) + strcpy(State, "Connecting"); + else if (axState == 3) + strcpy(State, "FRMR"); + else if (axState == 4) + strcpy(State, "Closing"); + else if (axState == 5) + strcpy(State, "Active"); + else if (axState == 6) + strcpy(State, "REJ Sent"); + + cctType = Links->LINKTYPE; + + if (cctType == 1) + strcpy(Type, "Uplink"); + else if (cctType == 2) + strcpy(Type, "Downlink"); + else if (cctType == 3) + strcpy(Type, "Node-Node"); + + + + ReplyLen += sprintf(&response[ReplyLen], "{\"farCall\": \"%s\",\"ourCall\": \"%s\", \"port\": \"%d\", \"state\": \"%s\", \"linkType\": \"%s\", \"ax25Version\": \"%d\"},\r\n", + Normcall1, Normcall2, Links->LINKPORT->PORTNUMBER, + State, Type, 2 - Links->VER1FLAG ); + Links+=1; + } + } + + if (ReplyLen < 13) + ReplyLen -= 2; // no links + else + ReplyLen -= 3; // remove trailing comma + + ReplyLen+= sprintf(&response[ReplyLen], "\r\n]}\r\n"); + + return ReplyLen; +} + +int sendPortMHList(char * response, char * token, int Flags) +{ + struct PORTCONTROL * PORTVEC = GetPortTableEntryFromPortNum(Flags); + + response[0] = 0; + + if (PORTVEC == 0) + return send_http_response(response, "401 Invalid API Call"); + + BuildPortMH( response, PORTVEC ); + response[ strlen(response)-3 ] = '\0'; // remove ,\r\n +// printf("MH for port %d:\r\n%s\r\n", PORTVEC->PORTNUMBER, response); + return strlen(response); +} + + + +