diff --git a/BBSHTMLConfig.c b/BBSHTMLConfig.c index d327367..a69cab5 100644 --- a/BBSHTMLConfig.c +++ b/BBSHTMLConfig.c @@ -445,7 +445,7 @@ void ProcessMailHTTPMessage(struct HTTPConnectionInfo * Session, char * Method, if (strstr(input, "Host: 127.0.0.1")) LOCAL = TRUE; - if (Session->TNC == 1) + if (Session->TNC == (void *)1) // Re-using an address as a flag LOCAL = TRUE; NodeURL = strtok_s(URL, "?", &Context); @@ -2842,6 +2842,8 @@ int SendUserDetails(struct HTTPConnectionInfo * Session, char * Reply, char * Ke #ifdef WIN32 +int ProcessWebmailWebSock(char * MsgPtr, char * OutBuffer); + static char PipeFileName[] = "\\\\.\\pipe\\BPQMailWebPipe"; static DWORD WINAPI InstanceThread(LPVOID lpvParam) @@ -2852,14 +2854,14 @@ static DWORD WINAPI InstanceThread(LPVOID lpvParam) // of this procedure to run concurrently, depending on the number of incoming // client connections. { - DWORD cbBytesRead = 0, cbReplyBytes = 0, cbWritten = 0; - BOOL fSuccess = FALSE; - HANDLE hPipe = NULL; - char Buffer[250000]; - char OutBuffer[250000]; - char * MsgPtr; - int InputLen = 0; - int OutputLen = 0; + DWORD cbBytesRead = 0, cbReplyBytes = 0, cbWritten = 0; + BOOL fSuccess = FALSE; + HANDLE hPipe = NULL; + char Buffer[250000]; + char OutBuffer[250000]; + char * MsgPtr; + int InputLen = 0; + int OutputLen = 0; struct HTTPConnectionInfo Session; char URL[100001]; char * Context, * Method; @@ -2867,17 +2869,17 @@ static DWORD WINAPI InstanceThread(LPVOID lpvParam) char * ptr; -// Debugprintf("InstanceThread created, receiving and processing messages."); + // The thread's parameter is a handle to a pipe object instance. -// The thread's parameter is a handle to a pipe object instance. - - hPipe = (HANDLE) lpvParam; + hPipe = (HANDLE) lpvParam; - // Read client requests from the pipe. This simplistic code only allows messages - // up to BUFSIZE characters in length. - - n = ReadFile(hPipe, &Session, sizeof (struct HTTPConnectionInfo), &n, NULL); - fSuccess = ReadFile(hPipe, Buffer, 250000, &InputLen, NULL); + // First block is the HTTPConnectionInfo record, rest is request + + n = ReadFile(hPipe, &Session, sizeof (struct HTTPConnectionInfo), &n, NULL); + + // Get the data + + fSuccess = ReadFile(hPipe, Buffer, 250000, &InputLen, NULL); if (!fSuccess || InputLen == 0) { @@ -2885,13 +2887,20 @@ static DWORD WINAPI InstanceThread(LPVOID lpvParam) Debugprintf("InstanceThread: client disconnected.", GetLastError()); else Debugprintf("InstanceThread ReadFile failed, GLE=%d.", GetLastError()); + + return 1; + } + + Buffer[InputLen] = 0; + + MsgPtr = &Buffer[0]; + + if (memcmp(MsgPtr, "WMRefresh", 9) == 0) + { + OutputLen = ProcessWebmailWebSock(MsgPtr, OutBuffer); } else { - Buffer[InputLen] = 0; - - MsgPtr = &Buffer[0]; - strcpy(URL, MsgPtr); ptr = strstr(URL, " HTTP"); @@ -2902,14 +2911,15 @@ static DWORD WINAPI InstanceThread(LPVOID lpvParam) Method = strtok_s(URL, " ", &Context); ProcessMailHTTPMessage(&Session, Method, Context, MsgPtr, OutBuffer, &OutputLen, InputLen); - - WriteFile(hPipe, &Session, sizeof (struct HTTPConnectionInfo), &n, NULL); - WriteFile(hPipe, OutBuffer, OutputLen, &cbWritten, NULL); - - FlushFileBuffers(hPipe); - DisconnectNamedPipe(hPipe); - CloseHandle(hPipe); } + + WriteFile(hPipe, &Session, sizeof (struct HTTPConnectionInfo), &n, NULL); + WriteFile(hPipe, OutBuffer, OutputLen, &cbWritten, NULL); + + FlushFileBuffers(hPipe); + DisconnectNamedPipe(hPipe); + CloseHandle(hPipe); + return 1; } diff --git a/BBSUtilities.c b/BBSUtilities.c index e8adc81..4d04579 100644 --- a/BBSUtilities.c +++ b/BBSUtilities.c @@ -58,10 +58,13 @@ extern char LOC[7]; extern BPQVECSTRUC ** BPQHOSTVECPTR; UCHAR * GetLogDirectory(); DllExport int APIENTRY SessionStateNoAck(int stream, int * state); +int RefreshWebMailIndex(); #else __declspec(dllimport) BPQVECSTRUC ** BPQHOSTVECPTR; typedef char * (WINAPI FAR *FARPROCZ)(); +typedef int (WINAPI FAR *FARPROCX)(); FARPROCZ pGetLOC; +FARPROCX pRefreshWebMailIndex; #endif @@ -1507,6 +1510,13 @@ VOID SaveMessageDatabase() // SaveConfig(ConfigName); // Message Headers now in main config // return; +#ifdef LINBPQ + RefreshWebMailIndex(); +#else + if (pRefreshWebMailIndex) + pRefreshWebMailIndex(); +#endif + Handle = fopen(MsgDatabasePath, "wb"); if (Handle == NULL) diff --git a/BPQChat.vcproj.DESKTOP-TGEL8RC.John.user b/BPQChat.vcproj.DESKTOP-TGEL8RC.John.user new file mode 100644 index 0000000..32abbfd --- /dev/null +++ b/BPQChat.vcproj.DESKTOP-TGEL8RC.John.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/BPQMail.c b/BPQMail.c index 73d06ac..b72e751 100644 --- a/BPQMail.c +++ b/BPQMail.c @@ -1101,7 +1101,7 @@ // Fix ' in Webmail subject (8) // Change web buttons to white on black when pressed (10) - +// Add auto-refresh option to Webmail index page (25) #include "bpqmail.h" #define MAIL @@ -1116,6 +1116,7 @@ typedef int (WINAPI FAR *FARPROCZ)(); FARPROCX pDllBPQTRACE; FARPROCZ pGetLOC; +FARPROCX pRefreshWebMailIndex; BOOL WINE = FALSE; @@ -1879,6 +1880,7 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { pDllBPQTRACE = GetProcAddress(ExtDriver,"_DllBPQTRACE@8"); pGetLOC = GetProcAddress(ExtDriver,"_GetLOC@0"); + pRefreshWebMailIndex = GetProcAddress(ExtDriver,"_RefreshWebMailIndex@0"); if (pGetLOC) { diff --git a/BPQMail.vcproj.DESKTOP-TGEL8RC.John.user b/BPQMail.vcproj.DESKTOP-TGEL8RC.John.user new file mode 100644 index 0000000..32abbfd --- /dev/null +++ b/BPQMail.vcproj.DESKTOP-TGEL8RC.John.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/BPQMail.vcproj.SKIGACER.johnw.user b/BPQMail.vcproj.SKIGACER.johnw.user new file mode 100644 index 0000000..bbece07 --- /dev/null +++ b/BPQMail.vcproj.SKIGACER.johnw.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/BPQRemotePTT.vcproj.DESKTOP-TGEL8RC.John.user b/BPQRemotePTT.vcproj.DESKTOP-TGEL8RC.John.user new file mode 100644 index 0000000..32abbfd --- /dev/null +++ b/BPQRemotePTT.vcproj.DESKTOP-TGEL8RC.John.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/BPQWinAPP.vcproj.DESKTOP-TGEL8RC.John.user b/BPQWinAPP.vcproj.DESKTOP-TGEL8RC.John.user new file mode 100644 index 0000000..32abbfd --- /dev/null +++ b/BPQWinAPP.vcproj.DESKTOP-TGEL8RC.John.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/BPQWinAPP.vcproj.SKIGACER.johnw.user b/BPQWinAPP.vcproj.SKIGACER.johnw.user new file mode 100644 index 0000000..bbece07 --- /dev/null +++ b/BPQWinAPP.vcproj.SKIGACER.johnw.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/Bpq32.c b/Bpq32.c index c0da5ed..167d254 100644 --- a/Bpq32.c +++ b/Bpq32.c @@ -1117,6 +1117,9 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses // Fix using FLARQ chat mode with FLDIGI ddriover (22) // Fixed to KISSHF driver (23) // Fix for application buffer loss (24) +// Add Web Sockets auto-refresh option for Webmail index page (25) +// Fix FREEDATA driver for compatibility with FreeData TNC version 0.6.4-alpha.3 (25) + #define CKernel @@ -1350,6 +1353,7 @@ DllExport int APIENTRY CloseBPQ32(); DllExport char * APIENTRY GetLOC(); DllExport int APIENTRY SessionControl(int stream, int command, int param); +int DoRefreshWebMailIndex(); BOOL APIENTRY Init_IP(); BOOL APIENTRY Poll_IP(); @@ -1508,6 +1512,7 @@ BOOL ReconfigFlag = FALSE; BOOL RigReconfigFlag = FALSE; BOOL APRSReconfigFlag = FALSE; BOOL CloseAllNeeded = FALSE; +BOOL NeedWebMailRefresh = FALSE; int AttachedPIDList[100] = {0}; @@ -2127,6 +2132,9 @@ VOID TimerProcX() if (PMActive) Poll_PM(); if (RigActive) Rig_Poll(); + if (NeedWebMailRefresh) + DoRefreshWebMailIndex(); + CheckGuardZone(); if (APRSActive) diff --git a/CBPQ32.vcproj b/CBPQ32.vcproj index ce65cb9..3e6fff8 100644 --- a/CBPQ32.vcproj +++ b/CBPQ32.vcproj @@ -74,7 +74,7 @@ + + + + + + + + + + diff --git a/CBPQ32.vcproj.SKIGACER.johnw.user b/CBPQ32.vcproj.SKIGACER.johnw.user new file mode 100644 index 0000000..6aa33d1 --- /dev/null +++ b/CBPQ32.vcproj.SKIGACER.johnw.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/FreeDATA.c b/FreeDATA.c index 95ef527..7cea9dd 100644 --- a/FreeDATA.c +++ b/FreeDATA.c @@ -2978,7 +2978,11 @@ void ProcessDAEMONJSON(struct TNCINFO * TNC, char * Msg, int Len) "\"tuning_range_fmax\":\"%3.1f\"," // 50.0 "\"tx_audio_level\":\"125\"," "\"respond_to_cq\":\"True\"," - "\"rx_buffer_size\":\"16\"}]}\n"; + "\"rx_buffer_size\":\"16\"," + "\"rx_buffer_size\":\"16\"," + "\"enable_explorer\": \"False\"" + + "}]}\n"; char Command[2048]; diff --git a/HTTPcode.c b/HTTPcode.c index 6267e60..cfca56e 100644 --- a/HTTPcode.c +++ b/HTTPcode.c @@ -2068,7 +2068,7 @@ doHeader: if (Session == 0) Session = &Dummy; - Session->TNC = LOCAL; // TNC only used for Web Terminal Sessions + Session->TNC = (void *)LOCAL; // TNC only used for Web Terminal Sessions ProcessMailHTTPMessage(Session, Method, Context, MsgPtr, _REPLYBUFFER, &ReplyLen, MsgLen); @@ -2195,7 +2195,7 @@ doHeader: if (Session == 0) Session = &Dummy; - Session->TNC = LOCAL; // TNC is only used on Web Terminal Sessions + Session->TNC = LOCAL; // TNC is only used on Web Terminal Sessions so can reuse as LOCAL flag WriteFile(hPipe, Session, sizeof (struct HTTPConnectionInfo), &InputLen, NULL); WriteFile(hPipe, MsgPtr, MsgLen, &InputLen, NULL); @@ -4325,7 +4325,100 @@ void SendRigWebPage() } } +// Webmail web socket code + +int ProcessWebmailWebSock(char * MsgPtr, char * OutBuffer); + +void ProcessWebmailWebSockThread(void * conn) +{ + // conn is a malloc'ed copy to handle reused connections, so need to free it + + struct ConnectionInfo * sockptr = (struct ConnectionInfo *)conn; + char * URL = sockptr->WebURL; + int Loops = 0; + int Sent; + int InputLen; + struct HTTPConnectionInfo Dummy = {0}; + int ReplyLen = 0; + +#ifdef LINBPQ + + char _REPLYBUFFER[250000]; + + ReplyLen = ProcessWebmailWebSock(URL, _REPLYBUFFER); + + // Send may block + + Sent = send(sockptr->socket, _REPLYBUFFER, ReplyLen, 0); + + while (Sent != ReplyLen && Loops++ < 3000) // 100 secs max + { + if (Sent > 0) // something sent + { + InputLen -= Sent; + memmove(_REPLYBUFFER, &_REPLYBUFFER[Sent], ReplyLen); + } + + Sleep(30); + Sent = send(sockptr->socket, _REPLYBUFFER, ReplyLen, 0); + } + +#else + // Send URL to BPQMail via Pipe. Just need a dummy session, as URL contains session key + + HANDLE hPipe; + char Reply[250000]; + + + + hPipe = CreateFile(MAILPipeFileName, GENERIC_READ | GENERIC_WRITE, + 0, // exclusive access + NULL, // no security attrs + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL ); + + if (hPipe == (HANDLE)-1) + { + free(conn); + return; + } + + WriteFile(hPipe, &Dummy, sizeof (struct HTTPConnectionInfo), &InputLen, NULL); + WriteFile(hPipe, URL, strlen(URL), &InputLen, NULL); + + ReadFile(hPipe, &Dummy, sizeof (struct HTTPConnectionInfo), &InputLen, NULL); + ReadFile(hPipe, Reply, 250000, &ReplyLen, NULL); + + if (ReplyLen <= 0) + { + InputLen = GetLastError(); + } + + CloseHandle(hPipe); + + // ?? do we need a thread to handle write which may block + + Sent = send(sockptr->socket, Reply, ReplyLen, 0); + + while (Sent != ReplyLen && Loops++ < 3000) // 100 secs max + { + // Debugprintf("%d out of %d sent %d Loops", Sent, InputLen, Loops); + + if (Sent > 0) // something sent + { + InputLen -= Sent; + memmove(Reply, &Reply[Sent], ReplyLen); + } + + Sleep(30); + Sent = send(sockptr->socket, Reply, ReplyLen, 0); + } +#endif + free(conn); + return; +} + - diff --git a/MBLRoutines.c b/MBLRoutines.c index b279729..d116893 100644 --- a/MBLRoutines.c +++ b/MBLRoutines.c @@ -85,6 +85,7 @@ VOID ProcessMBLLine(CIRCUIT * conn, struct UserInfo * user, UCHAR* Buffer, int l SendCompressed(conn, Msg); FBBputs(conn, ">\r"); Msg->status = 'Y'; // Mark as read + SaveMessageDatabase(); } else { diff --git a/MailNode.vcproj.DESKTOP-TGEL8RC.John.user b/MailNode.vcproj.DESKTOP-TGEL8RC.John.user new file mode 100644 index 0000000..32abbfd --- /dev/null +++ b/MailNode.vcproj.DESKTOP-TGEL8RC.John.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/MailNode.vcproj.SKIGACER.johnw.user b/MailNode.vcproj.SKIGACER.johnw.user new file mode 100644 index 0000000..8da606c --- /dev/null +++ b/MailNode.vcproj.SKIGACER.johnw.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/MailRouting.c b/MailRouting.c index 6692d69..27dc162 100644 --- a/MailRouting.c +++ b/MailRouting.c @@ -1467,6 +1467,7 @@ NOHA: } // We should choose the BBS with most matching elements (ie match on #23.GBR better that GBR) + // If SendPtoMultiple is set I think we send to any with same mtch level for (bbs = BBSChain; bbs; bbs = bbs->BBSNext) { diff --git a/TelnetV6.c b/TelnetV6.c index b03cbb0..886a26c 100644 --- a/TelnetV6.c +++ b/TelnetV6.c @@ -88,6 +88,7 @@ int DataSocket_ReadDRATS(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, void processDRATSFrame(unsigned char * Message, int Len, struct ConnectionInfo * sockptr); void DRATSConnectionLost(struct ConnectionInfo * sockptr); int BuildRigCtlPage(char * _REPLYBUFFER); +void ProcessWebmailWebSockThread(void * conn); #ifndef LINBPQ extern HKEY REGTREE; @@ -915,7 +916,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff) { case 7: - // 100 mS Timer. Now needed, as Poll can be called more ferquently in some circimstances + // 100 mS Timer. Now needed, as Poll can be called more frequently in some circuymstances while (TNC->PortRecord->UI_Q) // Release anything accidentally put on UI_Q { @@ -1317,7 +1318,10 @@ static int WebProc(struct TNCINFO * TNC, char * Buff, BOOL LOCAL) { char Addr[100]; Tel_Format_Addr(sockptr, Addr); - sprintf(msg,"HTTP<%s  ", Addr); + if (sockptr->WebSocks) + sprintf(msg,"Websock<%s  ", Addr); + else + sprintf(msg,"HTTP<%s  ", Addr); } else if (sockptr->DRATSMode) { @@ -4953,10 +4957,20 @@ int DataSocket_ReadHTTP(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, S sprintf(RigCMD, "%s PTT", &MsgPtr[6]); Rig_Command(-1, RigCMD); } - else - Debugprintf("WebSock Opcode %d Msg %s", Opcode, &MsgPtr[6]); + else if (memcmp(sockptr->WebURL, "WMRefresh", 9) == 0) + { + sockcopy = malloc(sizeof(struct ConnectionInfo)); + sockptr->TNC = TNC; + sockptr->LastSendTime = REALTIMETICKS; + memcpy(sockcopy, sockptr, sizeof(struct ConnectionInfo)); + + _beginthread(ProcessWebmailWebSockThread, 2048000, (VOID *)sockcopy); // Needs big stack + return 0; + } } + else + Debugprintf("WebSock Opcode %d Msg %s", Opcode, &MsgPtr[6]); sockptr->InputLen = 0; return 0; @@ -4989,59 +5003,60 @@ int DataSocket_ReadHTTP(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, S if(strstr(MsgPtr, "Upgrade: websocket")) { - if(RigWebPage[0]) - { - int LOCAL = 0, COOKIE = 0; - char * HostPtr; - char * ptr; + int LOCAL = 0, COOKIE = 0; + char * HostPtr; + char * ptr; - sockptr->WebSocks = 1; - memcpy(sockptr->WebURL, &MsgPtr[5], 15); - strlop(sockptr->WebURL, ' '); + sockptr->WebSocks = 1; + ShowConnections(TNC); + + memcpy(sockptr->WebURL, &MsgPtr[5], 31); + strlop(sockptr->WebURL, ' '); + if (RigWebPage) RigWebPage[0] = 0; - HostPtr = strstr(MsgPtr, "Host: "); + HostPtr = strstr(MsgPtr, "Host: "); - if (HostPtr) + if (HostPtr) + { + uint32_t Host; + char Hostname[32]= ""; + struct LOCALNET * LocalNet = sockptr->TNC->TCPInfo->LocalNets; + + HostPtr += 6; + memcpy(Hostname, HostPtr, 31); + strlop(Hostname, ':'); + Host = inet_addr(Hostname); + + if (strcmp(Hostname, "127.0.0.1") == 0) + LOCAL = TRUE; + else { - uint32_t Host; - char Hostname[32]= ""; - struct LOCALNET * LocalNet = sockptr->TNC->TCPInfo->LocalNets; - - HostPtr += 6; - memcpy(Hostname, HostPtr, 31); - strlop(Hostname, ':'); - Host = inet_addr(Hostname); - - if (strcmp(Hostname, "127.0.0.1") == 0) - LOCAL = TRUE; - else + if (sockptr->sin.sin_family != AF_INET6) { - if (sockptr->sin.sin_family != AF_INET6) + while(LocalNet) { - while(LocalNet) - { - uint32_t MaskedHost = sockptr->sin.sin_addr.s_addr & LocalNet->Mask; - if (MaskedHost == LocalNet->Network) - { - LOCAL = 1; - break; - } - LocalNet = LocalNet->Next; + uint32_t MaskedHost = sockptr->sin.sin_addr.s_addr & LocalNet->Mask; + if (MaskedHost == LocalNet->Network) + { + LOCAL = 1; + break; } + LocalNet = LocalNet->Next; } - - ptr = strstr(MsgPtr, "BPQSessionCookie=N"); - - if (ptr) - COOKIE = TRUE; } - sockptr->WebSecure = LOCAL | COOKIE; + + ptr = strstr(MsgPtr, "BPQSessionCookie=N"); + + if (ptr) + COOKIE = TRUE; } + sockptr->WebSecure = LOCAL | COOKIE; } } - _beginthread(ProcessHTTPMessage, 2048000, (VOID *)sockcopy); + + _beginthread(ProcessHTTPMessage, 2048000, (VOID *)sockcopy); // Needs big stack sockptr->InputLen = 0; return 0; @@ -5103,7 +5118,7 @@ int ShowConnections(struct TNCINFO * TNC) SendMessage(TNC->hMonitor,LB_RESETCONTENT,0,0); - for (n = 0; n <= TNC->TCPInfo->CurrentSockets; n++) + for (n = 1; n <= TNC->TCPInfo->CurrentSockets; n++) { sockptr=TNC->Streams[n].ConnectionInfo; @@ -5119,7 +5134,11 @@ int ShowConnections(struct TNCINFO * TNC) { char Addr[100]; Tel_Format_Addr(sockptr, Addr); - sprintf(msg, "HTTP From %s", Addr); + + if (sockptr->WebSocks) + sprintf(msg, "Websock From %s", Addr); + else + sprintf(msg, "HTTP From %s", Addr); } else if (sockptr->DRATSMode) { @@ -6873,7 +6892,12 @@ VOID SHOWTELNET(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX { char Addr[100]; Tel_Format_Addr(sockptr, Addr); - sprintf(msg, "HTTP From %s", Addr); + + if (sockptr->WebSocks) + sprintf(msg, "Websock From %s", Addr); + else + sprintf(msg, "HTTP From %s", Addr); + } else if (sockptr->DRATSMode) { @@ -6895,3 +6919,83 @@ VOID SHOWTELNET(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); } + + +// Refresh any Web Socket Webmail index display +// Called whenever message database is changed + +#ifdef LINBPQ + +int DoRefreshWebMailIndex(); + +int RefreshWebMailIndex() +{ + DoRefreshWebMailIndex(); +} + +#else + +// Have to pass request from BPQMail to DLL as socket can only be accessed in calling process +// Pass request back to WebMail via pipe + +// Code must run in bpq32 process, so set flag here and call code from Timer Routine + +extern BOOL NeedWebMailRefresh; + + +DllExport int APIENTRY RefreshWebMailIndex() +{ + NeedWebMailRefresh = 1; + return 0; +} + +#endif + +int DoRefreshWebMailIndex() +{ + // Loop through all sockets and pick out WebMail Index Connections + + int i, n; + struct ConnectionInfo * sockptr; + struct ConnectionInfo * sockcopy; + struct TNCINFO * TNC; + struct TCPINFO * TCP; + +#ifndef LINBPQ + NeedWebMailRefresh = 0; +#endif + + for (i = 0; i < 33; i++) + { + TNC = TNCInfo[i]; + + if (TNC && TNC->Hardware == H_TELNET) + { + TCP = TNC->TCPInfo; + + if (TCP) + { + for (n = 0; n <= TCP->MaxSessions; n++) + { + sockptr = TNC->Streams[n].ConnectionInfo; + + if (sockptr->SocketActive) + { + if (sockptr->HTTPMode && sockptr->WebSocks && memcmp(sockptr->WebURL, "WMRefresh", 9) == 0) + { + sockcopy = malloc(sizeof(struct ConnectionInfo)); + sockptr->TNC = TNC; + sockptr->LastSendTime = REALTIMETICKS; + + memcpy(sockcopy, sockptr, sizeof(struct ConnectionInfo)); + + _beginthread(ProcessWebmailWebSockThread, 2048000, (VOID *)sockcopy); // Needs big stack + } + } + } + } + } + } + return 0; +} + diff --git a/VARA.c b/VARA.c index 878d78c..4636579 100644 --- a/VARA.c +++ b/VARA.c @@ -1162,7 +1162,7 @@ void * VARAExtInit(EXTPORTDATA * PortEntry) if (TNC->TXFreq) { - CreatePactorWindow(TNC, ClassName, WindowTitle, RigControlRow + 22, PacWndProc, 500, 450, ForcedClose); + CreatePactorWindow(TNC, ClassName, WindowTitle, RigControlRow + 22, PacWndProc, 550, 450, ForcedClose); InitCommonControls(); // loads common control's DLL diff --git a/Versions.h b/Versions.h index 11cbe15..3dd5a17 100644 --- a/Versions.h +++ b/Versions.h @@ -10,8 +10,8 @@ #endif -#define KVers 6,0,23,24 -#define KVerstring "6.0.23.24\0" +#define KVers 6,0,23,25 +#define KVerstring "6.0.23.25\0" #ifdef CKernel diff --git a/WebMail.c b/WebMail.c index aeddc40..f76584b 100644 --- a/WebMail.c +++ b/WebMail.c @@ -954,7 +954,7 @@ int SendWebMailHeaderEx(char * Reply, char * Key, struct HTTPConnectionInfo * Se if (WebMailTemplate == NULL) WebMailTemplate = GetTemplateFromFile(6, "WebMailPage.txt"); - return sprintf(Reply, WebMailTemplate, BBSName, User->Call, Key, Key, Key, Key, Key, Key, Key, Messages); + return sprintf(Reply, WebMailTemplate, BBSName, User->Call, Key, Key, Key, Key, Key, Key, Key, Key, Messages); } int ViewWebMailMessage(struct HTTPConnectionInfo * Session, char * Reply, int Number, BOOL DisplayHTML) @@ -1119,6 +1119,8 @@ int ViewWebMailMessage(struct HTTPConnectionInfo * Session, char * Reply, int Nu { Msg->status = 'Y'; Msg->datechanged=time(NULL); + SaveMessageDatabase(); + } } } @@ -1185,6 +1187,7 @@ int ViewWebMailMessage(struct HTTPConnectionInfo * Session, char * Reply, int Nu { Msg->status = 'Y'; Msg->datechanged=time(NULL); + SaveMessageDatabase(); } } } @@ -1281,6 +1284,7 @@ int ViewWebMailMessage(struct HTTPConnectionInfo * Session, char * Reply, int Nu { Msg->status = 'Y'; Msg->datechanged=time(NULL); + SaveMessageDatabase(); } } } @@ -1791,6 +1795,98 @@ void ProcessWebMailMessage(struct HTTPConnectionInfo * Session, char * Key, BOOL return; } + if (_stricmp(NodeURL, "/WebMail/WMAuto") == 0) + { + // Auto Refresh Version of index page. Uses Web Sockets + + char Page[4096]; + + char WebSockPage[] = + "\r\n" + " \r\n" + " \r\n" + " \r\n" + " \r\n" + "\r\n" + "\r\n" + + "\r\n" + "WebMail \r\n" + "\r\n" + + "\r\n" + "

%s Webmail Interface - User %s - Message List

\r\n" + "\r\n" + "\r\n" + "\r\n" + "\r\n" + "\r\n" + "\r\n" + "\r\n" + "\r\n" + "\r\n" + "\r\n" + "
BullsPersonalNTSAll TypesMineAuto RefreshSend MessageLogoutNode Menu
\r\n" + "
\r\n" + + "
Waiting for data...
\r\n" + "\r\n"; + + sprintf(Page, WebSockPage, Key, Key ,BBSName, Session->User->Call, Key, Key, Key, Key, Key, Key, Key, Key); + + *RLen = sprintf(Reply, "%s", Page); + return; + } + + if (memcmp(NodeURL, "/WebMail/QuoteOriginal/", 15) == 0) { // Reply to Message @@ -2657,7 +2753,6 @@ VOID SaveNewMessage(struct HTTPConnectionInfo * Session, char * MsgPtr, char * R BuildNNTPList(Msg); // Build NNTP Groups list - if (EnableUI) SendMsgUI(Msg); @@ -5959,5 +6054,118 @@ char * WebFindPart(char ** Msg, char * Boundary, int * PartLen, char * End) } +int ProcessWebmailWebSock(char * MsgPtr, char * OutBuffer) +{ + int Len = 129; + char * Key = strlop(MsgPtr, '&'); + + struct HTTPConnectionInfo * Session; + struct UserInfo * User; + int m; + struct MsgInfo * Msg; + char * ptr = &OutBuffer[4]; + + int n = NumberofMessages; + char Via[64]; + int Count = 0; + + if (Key == 0) + return 0; + + Session = FindWMSession(Key); + + if (Session == NULL) + return 0; + + User = Session->User; + + // Outbuffer is 250000 + +// ptr += sprintf(ptr, "
\r\n" + ptr += sprintf(ptr, "
");
+
+	ptr += sprintf(ptr, "%s", "     #  Date  XX   Len To      @       From    Subject\r\n\r\n");
+
+	for (m = LatestMsg; m >= 1; m--)
+	{
+		if (ptr > &OutBuffer[244000])
+			break;						// protect buffer
+
+		Msg = GetMsgFromNumber(m);
+
+		if (Msg == 0 || Msg->type == 0 || Msg->status == 0)
+			continue;					// Protect against corrupt messages
+		
+		if (Msg && CheckUserMsg(Msg, User->Call, User->flags & F_SYSOP))
+		{
+			char UTF8Title[128];
+			char  * EncodedTitle;
+			
+			// List if it is the right type and in the page range we want
+
+			if (Session->WebMailTypes[0] && strchr(Session->WebMailTypes, Msg->type) == 0) 
+				continue;
+
+			// All Types or right Type. Check Mine Flag
+
+			if (Session->WebMailMine)
+			{
+				// Only list if to or from me
+
+				if (strcmp(User->Call, Msg->to) != 0 && strcmp(User->Call, Msg->from) != 0)
+					continue;
+			}
+
+			if (Count++ < Session->WebMailSkip)
+				continue;
+
+			strcpy(Via, Msg->via);
+			strlop(Via, '.');
+
+			// make sure title is HTML safe (no < > etc) and UTF 8 encoded
+
+			EncodedTitle = doXMLTransparency(Msg->title);
+
+			ConvertTitletoUTF8(EncodedTitle, UTF8Title);
+
+			free(EncodedTitle);
+			
+			ptr += sprintf(ptr, "%6d %s %c%c %5d %-8s%-8s%-8s%s\r\n",
+				Key, Msg->number, Msg->number,
+				FormatDateAndTime((time_t)Msg->datecreated, TRUE), Msg->type,
+				Msg->status, Msg->length, Msg->to, Via,
+				Msg->from, UTF8Title);
+
+			n--;
+
+			if (n == 0)
+				break;
+		}
+	}
+
+	ptr += sprintf(ptr, "%s
\r\n", ptr); + + Len = ptr - &OutBuffer[4]; + + OutBuffer[0] = 0x81; // Fin, Data + + if (Len < 126) + { + OutBuffer[1] = Len; + memmove(&OutBuffer[2], &OutBuffer[4], Len); + return Len + 2; + } + else + { + OutBuffer[1] = 126; // Unmasked, Extended Len + OutBuffer[2] = Len >> 8; + OutBuffer[3] = Len & 0xff; + + return Len + 4; + } + +} + + diff --git a/WinmorControl.vcproj.SKIGACER.johnw.user b/WinmorControl.vcproj.SKIGACER.johnw.user new file mode 100644 index 0000000..bbece07 --- /dev/null +++ b/WinmorControl.vcproj.SKIGACER.johnw.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/configure.scan b/configure.scan deleted file mode 100644 index e3b787d..0000000 --- a/configure.scan +++ /dev/null @@ -1,53 +0,0 @@ -# -*- Autoconf -*- -# Process this file with autoconf to produce a configure script. - -AC_PREREQ([2.69]) -AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS]) -AC_CONFIG_SRCDIR([AEAPactor.c]) -AC_CONFIG_HEADERS([config.h]) - -# Checks for programs. -AC_PROG_CXX -AC_PROG_CC - -# Checks for libraries. -# FIXME: Replace `main' with a function in `-lconfig': -AC_CHECK_LIB([config], [main]) -# FIXME: Replace `main' with a function in `-lm': -AC_CHECK_LIB([m], [main]) -# FIXME: Replace `main' with a function in `-lpcap': -AC_CHECK_LIB([pcap], [main]) -# FIXME: Replace `main' with a function in `-lpthread': -AC_CHECK_LIB([pthread], [main]) -# FIXME: Replace `main' with a function in `-lrt': -AC_CHECK_LIB([rt], [main]) - -# Checks for header files. -AC_PATH_X -AC_CHECK_HEADERS([arpa/inet.h fcntl.h malloc.h netdb.h netinet/in.h stddef.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h syslog.h termios.h unistd.h wchar.h]) - -# Checks for typedefs, structures, and compiler characteristics. -AC_CHECK_HEADER_STDBOOL -AC_C_INLINE -AC_TYPE_INT16_T -AC_TYPE_INT32_T -AC_TYPE_INT64_T -AC_TYPE_INT8_T -AC_TYPE_PID_T -AC_TYPE_SIZE_T -AC_TYPE_UINT16_T -AC_TYPE_UINT32_T -AC_TYPE_UINT64_T -AC_TYPE_UINT8_T -AC_CHECK_TYPES([ptrdiff_t]) - -# Checks for library functions. -AC_FUNC_FORK -AC_FUNC_MALLOC -AC_FUNC_MKTIME -AC_FUNC_MMAP -AC_FUNC_REALLOC -AC_CHECK_FUNCS([bzero clock_gettime floor ftruncate getcwd gethostbyaddr gethostbyname gethostname inet_ntoa memchr memmove memset mkdir munmap pow select socket strchr strrchr strstr strtol]) - -AC_CONFIG_FILES([makefile]) -AC_OUTPUT diff --git a/httpconnectioninfo.h b/httpconnectioninfo.h index 081a855..8ad1b37 100644 --- a/httpconnectioninfo.h +++ b/httpconnectioninfo.h @@ -2,7 +2,7 @@ // HTTP Session Control. Used In Kernel HTTPCode, BBSHTMLConfig // and ChatHTMLConfig -// On Windows ghanges to layout or length of this struct require rebuilding BPQ32.dll, BPQMail and BPQChat +// On Windows changes to layout or length of this struct require rebuilding BPQ32.dll, BPQMail and BPQChat struct HTTPConnectionInfo // Used for Web Server for thread-specific stuff { diff --git a/telnetserver.h b/telnetserver.h index a665298..072f14c 100644 --- a/telnetserver.h +++ b/telnetserver.h @@ -68,7 +68,7 @@ struct ConnectionInfo struct ADIF * ADIF; // ADIF Logging info int WebSocks; - char WebURL[16]; // URL for WebSocket Connection + char WebURL[32]; // URL for WebSocket Connection int WebSecure; // Set if secure session }; diff --git a/templatedefs.c b/templatedefs.c index 14dfe64..14061f6 100644 --- a/templatedefs.c +++ b/templatedefs.c @@ -394,6 +394,7 @@ char * WebMailPagetxt() "NTS\r\n" "All Types\r\n" "Mine\r\n" + "Auto Refresh\r\n" "Send Message\r\n" "Logout\r\n" "Node Menu\r\n"