From ed81fc5267a230d12a2519e61707025087ec6234 Mon Sep 17 00:00:00 2001
From: g8bpq <john.wiseman@cantab.net>
Date: Thu, 29 Jun 2023 18:13:31 +0100
Subject: [PATCH] 6.0.23.77

---
 AEAPactor.c      |    1 -
 Bpq32.c          |   17 +
 Cmd.c            |  166 +++-
 HALDriver.c      |    1 -
 KAMPactor.c      |    3 -
 LinBPQ.c         |    1 -
 LinBPQ.c~        | 1975 ++++++++++++++++++++++++++++++++++++++++++++++
 MULTIPSK.c       |    2 +-
 RigControl.c     |    2 -
 SCSPactor.c      |    3 +-
 SCSTrackeMulti.c |    4 +-
 SCSTracker.c     |    3 -
 TelnetV6.c       |    1 -
 UZ7HODrv.c       |    2 +-
 Versions.h       |    4 +-
 WinRPR.c         |    5 -
 cMain.c          |    4 +-
 kiss.c           |   33 +-
 kiss.h           |    9 +-
 rigcontrol.h     |    1 -
 20 files changed, 2179 insertions(+), 58 deletions(-)
 create mode 100644 LinBPQ.c~

diff --git a/AEAPactor.c b/AEAPactor.c
index 62f9cfa..56686ee 100644
--- a/AEAPactor.c
+++ b/AEAPactor.c
@@ -71,7 +71,6 @@ static RECT Rect;
 static char status[8][8] = {"STANDBY",  "PHASING", "CHGOVER", "IDLE", "TRAFFIC", "ERROR", "RQ", "XXXX"};
 
 struct TNCINFO * CreateTTYInfo(int port, int speed);
-BOOL OpenConnection(int);
 BOOL SetupConnection(int);
 BOOL CloseConnection(struct TNCINFO * conn);
 static BOOL WriteCommBlock(struct TNCINFO * TNC);
diff --git a/Bpq32.c b/Bpq32.c
index a4d19f6..228dabf 100644
--- a/Bpq32.c
+++ b/Bpq32.c
@@ -1173,6 +1173,7 @@ along with LinBPQ/BPQ32.  If not, see http://www.gnu.org/licenses
 //	Detect loss of DED application (76)
 //	Fix connects to Application Alias with UZ7HO Driver (76)
 //	Fix Interlock of ports on same UZ7HO modem. (76)
+//	Add extended Ports command 
 
 #define CKernel
 
@@ -2576,6 +2577,22 @@ BOOL APIENTRY DllMain(HANDLE hInst, DWORD ul_reason_being_called, LPVOID lpReser
 			return 0;
 		}
 			  
+		if (sizeof(struct KISSINFO) > PORTENTRYLEN + 200)	// 200 bytes of Hardwaredata
+		{
+			// Catastrophic - Refuse to load
+			
+			MessageBox(NULL,"BPQ32 Too much KISS data - Recompile","BPQ32", MB_OK);
+			return 0;
+		}
+
+		if (sizeof(struct _EXTPORTDATA) > PORTENTRYLEN + 200)	// 200 bytes of Hardwaredata
+		{
+			// Catastrophic - Refuse to load
+			
+			MessageBox(NULL,"BPQ32 Too much _EXTPORTDATA data - Recompile","BPQ32", MB_OK);
+			return 0;
+		}
+		  
 		if (sizeof(LINKTABLE) != LINK_TABLE_LEN)
 		{
 			// Catastrophic - Refuse to load
diff --git a/Cmd.c b/Cmd.c
index 617d6e9..44bf503 100644
--- a/Cmd.c
+++ b/Cmd.c
@@ -37,6 +37,7 @@ along with LinBPQ/BPQ32.  If not, see http://www.gnu.org/licenses
 
 #include "CHeaders.h"
 #include "bpqaprs.h"
+#include "kiss.h"
 
 #pragma pack()
 
@@ -1313,19 +1314,182 @@ CMDS60:
 	SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
 }
 
+extern int MasterPort[MAXBPQPORTS+1];	// Pointer to first BPQ port for a specific MPSK or UZ7HO host
+
 VOID CMDP00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD)
 {
 	// Process PORTS Message
 
+	// If extended show state of TNC (Open, Active, etc)
+
 	struct PORTCONTROL * PORT = PORTTABLE;
+	char Extended = CmdTail[0];
+	struct PORTCONTROL * SAVEPORT;
 
 	Bufferptr = Cmdprintf(Session, Bufferptr, "Ports\r");
 
 	while (PORT)
 	{
-		if (PORT->Hide == 0) 
+		char Status[32] = "???????";
+		int Portno = PORT->PORTNUMBER;
+
+		if (PORT->Hide) 
+		{
+			PORT = PORT->PORTPOINTER;
+			continue;
+		}
+
+		if (Extended != 'E')
+		{
 			Bufferptr = Cmdprintf(Session, Bufferptr, " %2d %s\r", PORT->PORTNUMBER, PORT->PORTDESCRIPTION);
 
+			PORT = PORT->PORTPOINTER;
+			continue;
+		}
+
+		// Try to get port status - may not be possible with some
+
+		if (PORT->PortStopped)
+		{
+			strcpy(Status, "Stopped");
+			Bufferptr = Cmdprintf(Session, Bufferptr, " %2d %-7s %s\r", PORT->PORTNUMBER, Status, PORT->PORTDESCRIPTION);
+
+			PORT = PORT->PORTPOINTER;
+			continue;
+		}
+
+		if (PORT->PORTTYPE == 0)
+		{
+			struct KISSINFO * KISS = (struct KISSINFO *)PORT;
+			NPASYINFO Port;
+
+			SAVEPORT = PORT;
+
+			if (KISS->FIRSTPORT && KISS->FIRSTPORT != KISS)
+			{
+				// Not first port on device
+
+				PORT = (struct PORTCONTROL *)KISS->FIRSTPORT;
+				Port = KISSInfo[Portno];
+			}
+
+			Port = KISSInfo[PORT->PORTNUMBER];
+
+			if (Port)
+			{
+				// KISS like - see if connected 
+
+				if (PORT->PORTIPADDR.s_addr || PORT->KISSSLAVE)
+				{
+					// KISS over UDP or TCP
+
+					if (PORT->KISSTCP)
+					{
+						if (Port->Connected)
+							strcpy(Status, "Open  ");
+						else
+							if (PORT->KISSSLAVE)
+								strcpy(Status, "Listen");
+							else
+								strcpy(Status, "Closed");
+					}
+					else
+						strcpy(Status, "UDP");
+				}
+				else
+					if (Port->idComDev)			// Serial port Open
+						strcpy(Status, "Open  ");
+					else
+						strcpy(Status, "Closed");
+
+				PORT = SAVEPORT;
+			}		
+		}
+		else if (PORT->PORTTYPE == 14)		// Loopback 
+			strcpy(Status, "Open  ");
+
+		else if (PORT->PORTTYPE == 16)		// External
+		{
+			if (PORT->PROTOCOL == 10)		// 'HF' Port
+			{
+				struct TNCINFO * TNC = TNCInfo[Portno];
+
+				if (TNC == NULL)
+				{
+					PORT = PORT->PORTPOINTER;
+					continue;
+				}
+
+				switch (TNC->Hardware)				// Hardware Type
+				{
+				case H_SCS:
+				case H_KAM:
+				case H_AEA:
+				case H_HAL:
+				case H_TRK:
+				case H_SERIAL:
+
+					// Serial
+
+					if (TNC->hDevice)
+						strcpy(Status, "Open  ");
+					else
+						strcpy(Status, "Closed");
+
+					break;
+
+				case H_UZ7HO:
+
+					if (TNCInfo[MasterPort[Portno]]->CONNECTED)
+						strcpy(Status, "Open  ");
+					else
+						strcpy(Status, "Closed");
+
+					break;
+
+				case H_WINMOR:
+				case H_V4:
+
+				case H_MPSK:
+				case H_FLDIGI:
+				case H_UIARQ:
+				case H_ARDOP:
+				case H_VARA:
+				case H_KISSHF:
+				case H_WINRPR:
+				case H_FREEDATA:
+
+					// TCP
+
+					if (TNC->CONNECTED)
+					{
+						if (TNC->Streams[0].Attached)
+							strcpy(Status, "In Use");
+						else
+							strcpy(Status, "Open  ");
+					}
+					else
+						strcpy(Status, "Closed");
+
+					break;
+
+				case H_TELNET:
+
+					strcpy(Status, "Open  ");
+				}
+			}
+			else
+			{
+				// External but not HF - AXIP, BPQETHER VKISS, ??
+
+				struct _EXTPORTDATA * EXTPORT = (struct _EXTPORTDATA *)PORT;
+
+				strcpy(Status, "Open  ");
+			}
+		}
+
+			Bufferptr = Cmdprintf(Session, Bufferptr, " %2d %-7s %s\r", PORT->PORTNUMBER, Status, PORT->PORTDESCRIPTION);
+
 		PORT = PORT->PORTPOINTER;
 	}
 
diff --git a/HALDriver.c b/HALDriver.c
index f7231e7..31e03cf 100644
--- a/HALDriver.c
+++ b/HALDriver.c
@@ -64,7 +64,6 @@ static char status[23][50] = {"IDLE", "TFC", "RQ", "ERR", "PHS", "OVER", "FSK TX
 		"FREE SIGNAL TX (AMTOR)", "FREE SIGNAL TX TIMED OUT (AMTOR)"};
 
 struct TNCINFO * CreateTTYInfo(int port, int speed);
-BOOL OpenConnection(int);
 BOOL SetupConnection(int);
 static BOOL WriteCommBlock(struct TNCINFO * TNC);
 static void CheckRX(struct TNCINFO * TNC);
diff --git a/KAMPactor.c b/KAMPactor.c
index f214f04..0b1a125 100644
--- a/KAMPactor.c
+++ b/KAMPactor.c
@@ -252,9 +252,6 @@ ConfigLine:
 
 static int MaxStreams = 26;
 
-struct TNCINFO * CreateTTYInfo(int port, int speed);
-BOOL OpenConnection(int);
-BOOL SetupConnection(int);
 BOOL CloseConnection(struct TNCINFO * conn);
 static BOOL WriteCommBlock(struct TNCINFO * TNC);
 BOOL DestroyTTYInfo(int port);
diff --git a/LinBPQ.c b/LinBPQ.c
index 514c131..0ca3dc5 100644
--- a/LinBPQ.c
+++ b/LinBPQ.c
@@ -552,7 +552,6 @@ extern int POP3Timer;
 #include <stdio.h>
 #include <sys/select.h>
 #include <termios.h>
-#include <stropts.h>
 
 int _kbhit() {
     static const int STDIN = 0;
diff --git a/LinBPQ.c~ b/LinBPQ.c~
new file mode 100644
index 0000000..6cb346e
--- /dev/null
+++ b/LinBPQ.c~
@@ -0,0 +1,1975 @@
+/*
+Copyright 2001-2018 John Wiseman G8BPQ
+
+This file is part of LinBPQ/BPQ32.
+ 
+LinBPQ/BPQ32 is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+LinBPQ/BPQ32 is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with LinBPQ/BPQ32.  If not, see http://www.gnu.org/licenses
+*/	
+
+// Control Routine for LinBPQ 
+
+#define _CRT_SECURE_NO_DEPRECATE
+
+#include "CHeaders.h"
+#include "bpqmail.h"
+#ifdef WIN32
+#include <Iphlpapi.h>
+//#include "C:\Program Files (x86)\GnuWin32\include\iconv.h"
+#else
+#include <iconv.h>
+#ifndef MACBPQ
+#ifndef FREEBSD
+#include <sys/prctl.h>
+#endif
+#endif
+#endif
+
+#include "time.h"
+
+#define Connect(stream) SessionControl(stream,1,0)
+#define Disconnect(stream) SessionControl(stream,2,0)
+#define ReturntoNode(stream) SessionControl(stream,3,0)
+#define ConnectUsingAppl(stream, appl) SessionControl(stream, 0, appl)
+
+BOOL APIENTRY Rig_Init();
+
+void GetSemaphore(struct SEM * Semaphore, int ID);
+void FreeSemaphore(struct SEM * Semaphore);
+VOID CopyConfigFile(char * ConfigName);
+VOID SendMailForThread(VOID * Param);
+VOID GetUIConfig();
+Dll BOOL APIENTRY Init_IP();
+VOID OpenReportingSockets();
+VOID SetupNTSAliases(char * FN);
+int DeleteRedundantMessages();
+BOOL InitializeTNCEmulator();
+VOID FindLostBuffers();
+VOID IPClose();
+DllExport BOOL APIENTRY Rig_Close();
+Dll BOOL APIENTRY Poll_IP();
+BOOL Rig_Poll();
+BOOL Rig_Poll();
+VOID CheckWL2KReportTimer();
+VOID TNCTimer();
+VOID SendLocation();
+int ChatPollStreams();
+void ChatTrytoSend();
+VOID BBSSlowTimer();
+int GetHTMLForms();
+char * AddUser(char * Call, char * password, BOOL BBSFlag);
+VOID SaveChatConfigFile(char * ConfigName);
+VOID SaveMH();
+int upnpClose();
+void SaveAIS();
+void initAIS();
+void DRATSPoll();
+
+BOOL IncludesMail = FALSE;
+BOOL IncludesChat = FALSE;
+
+BOOL RunMail = FALSE;
+BOOL RunChat = FALSE;
+BOOL needAIS= FALSE;
+BOOL needADSB = FALSE;
+
+int CloseOnError = 0;
+
+VOID Poll_AGW();
+BOOL AGWAPIInit();
+int AGWAPITerminate();
+
+BOOL AGWActive = FALSE;
+
+extern int AGWPort;
+
+BOOL RigActive = FALSE;
+
+extern ULONG ChatApplMask;
+extern char Verstring[];
+
+extern char SignoffMsg[];
+extern char AbortedMsg[];
+extern char InfoBoxText[];			// Text to display in Config Info Popup
+
+extern int LastVer[4];				// In case we need to do somthing the first time a version is run
+
+extern HWND MainWnd;
+extern char BaseDir[];
+extern char BaseDirRaw[];
+extern char MailDir[];
+extern char WPDatabasePath[];
+extern char RlineVer[50];
+
+extern BOOL LogBBS;
+extern BOOL LogCHAT;
+extern BOOL LogTCP;
+extern BOOL ForwardToMe;
+
+extern int LatestMsg;
+extern char BBSName[];
+extern char SYSOPCall[];
+extern char BBSSID[];
+extern char NewUserPrompt[];
+
+extern int	NumberofStreams;
+extern int MaxStreams;
+extern ULONG BBSApplMask;
+extern int BBSApplNum;
+extern int ChatApplNum;
+extern int MaxChatStreams;
+
+extern int NUMBEROFTNCPORTS;
+
+extern int EnableUI;
+
+extern  BOOL AUTOSAVEMH;
+
+extern FILE * LogHandle[4];
+
+#define MaxSockets 64
+
+extern ConnectionInfo Connections[MaxSockets+1];
+
+time_t LastTrafficTime;
+extern int MaintTime;
+
+#define LOG_BBS 0
+#define LOG_CHAT 1
+#define LOG_TCP 2
+#define LOG_DEBUG_X 3
+
+int _MYTIMEZONE = 0;
+
+// flags equates
+
+#define F_Excluded   0x0001
+#define F_LOC        0x0002
+#define F_Expert     0x0004
+#define F_SYSOP      0x0008
+#define F_BBS        0x0010
+#define F_PAG        0x0020
+#define F_GST        0x0040
+#define F_MOD        0x0080
+#define F_PRV        0x0100
+#define F_UNP        0x0200
+#define F_NEW        0x0400
+#define F_PMS        0x0800
+#define F_EMAIL      0x1000
+#define F_HOLDMAIL   0x2000
+#define F_POLLRMS	 0x4000
+#define F_SYSOP_IN_LM 0x8000
+#define F_Temp_B2_BBS 0x00010000
+
+/* #define F_PWD        0x1000 */
+
+
+UCHAR BPQDirectory[260];
+UCHAR LogDirectory[260];
+
+BOOL GetConfig(char * ConfigName);
+VOID DecryptPass(char * Encrypt, unsigned char * Pass, unsigned int len);
+int EncryptPass(char * Pass, char * Encrypt);
+int APIENTRY FindFreeStream();
+int PollStreams();
+int APIENTRY SetAppl(int stream, int flags, int mask);
+int APIENTRY SessionState(int stream, int * state, int * change);
+int APIENTRY SessionControl(int stream, int command, int Mask);
+
+BOOL ChatInit();
+VOID CloseChat();
+VOID CloseTNCEmulator();
+
+static config_t cfg;
+static config_setting_t * group;
+
+BOOL MonBBS = TRUE;
+BOOL MonCHAT = TRUE;
+BOOL MonTCP = TRUE;
+
+BOOL LogBBS = TRUE;
+BOOL LogCHAT = TRUE;
+BOOL LogTCP = TRUE;
+
+extern BOOL LogAPRSIS;
+
+BOOL UIEnabled[33];
+BOOL UINull[33];
+char * UIDigi[33];
+
+extern struct UserInfo ** UserRecPtr;
+extern int NumberofUsers;
+
+extern struct UserInfo * BBSChain;					// Chain of users that are BBSes
+
+extern struct MsgInfo ** MsgHddrPtr;
+extern int NumberofMessages;
+
+extern int FirstMessageIndextoForward;					// Lowest Message wirh a forward bit set - limits search
+
+extern char UserDatabaseName[MAX_PATH];
+extern char UserDatabasePath[MAX_PATH];
+
+extern char MsgDatabasePath[MAX_PATH];
+extern char MsgDatabaseName[MAX_PATH];
+
+extern char BIDDatabasePath[MAX_PATH];
+extern char BIDDatabaseName[MAX_PATH];
+
+extern char WPDatabasePath[MAX_PATH];
+extern char WPDatabaseName[MAX_PATH];
+
+extern char BadWordsPath[MAX_PATH];
+extern char BadWordsName[MAX_PATH];
+
+extern char NTSAliasesPath[MAX_PATH];
+extern char NTSAliasesName[MAX_PATH];
+
+extern char BaseDir[MAX_PATH];
+extern char BaseDirRaw[MAX_PATH];			// As set in registry - may contain %NAME%
+extern char ProperBaseDir[MAX_PATH];		// BPQ Directory/BPQMailChat
+
+extern char MailDir[MAX_PATH];
+
+extern time_t MaintClock;						// Time to run housekeeping
+
+#ifdef WIN32
+BOOL KEEPGOING = 30;					// 5 secs to shut down
+#else
+BOOL KEEPGOING = 50;					// 5 secs to shut down
+#endif
+BOOL Restarting = FALSE;
+BOOL CLOSING = FALSE;
+
+int ProgramErrors;
+int Slowtimer = 0;
+
+#define REPORTINTERVAL 15 * 549;	// Magic Ticks Per Minute for PC's nominal 100 ms timer
+int ReportTimer = 0;
+
+// Console Terminal Support
+
+struct ConTermS 
+{
+	int BPQStream;
+	BOOL Active;
+	int Incoming;
+
+	char kbbuf[INPUTLEN];
+	int kbptr;
+
+	char * KbdStack[MAXSTACK];
+	int StackIndex;
+
+	BOOL CONNECTED;
+	int SlowTimer;
+};
+
+struct ConTermS ConTerm = {0, 0};
+
+
+VOID CheckProgramErrors()
+{
+	if (Restarting)
+		exit(0);				// Make sure can't loop in restarting
+
+	ProgramErrors++;
+
+	if (ProgramErrors > 25)
+	{
+		Restarting = TRUE;
+
+		Logprintf(LOG_DEBUG_X, NULL, '!', "Too Many Program Errors - Closing");
+
+/*
+		SInfo.cb=sizeof(SInfo);
+		SInfo.lpReserved=NULL;
+		SInfo.lpDesktop=NULL;
+		SInfo.lpTitle=NULL;
+		SInfo.dwFlags=0;
+		SInfo.cbReserved2=0;
+  		SInfo.lpReserved2=NULL;
+
+		GetModuleFileName(NULL, ProgName, 256);
+
+		Debugprintf("Attempting to Restart %s", ProgName);
+
+		CreateProcess(ProgName, "MailChat.exe WAIT", NULL, NULL, FALSE, 0, NULL, NULL, &SInfo, &PInfo);
+*/
+		exit(0);
+	}
+}
+
+#ifdef WIN32
+
+BOOL CtrlHandler(DWORD fdwCtrlType)
+{
+  switch( fdwCtrlType )
+  {
+    // Handle the CTRL-C signal.
+    case CTRL_C_EVENT:
+      printf( "Ctrl-C event\n\n" );
+	  CLOSING = TRUE;
+      Beep( 750, 300 );
+      return( TRUE );
+
+    // CTRL-CLOSE: confirm that the user wants to exit.
+    case CTRL_CLOSE_EVENT:
+
+	  CLOSING = TRUE;
+     printf( "Ctrl-Close event\n\n" );
+	 Sleep(20000);
+       Beep( 750, 300 );
+	   return( TRUE );
+
+    // Pass other signals to the next handler.
+    case CTRL_BREAK_EVENT:
+      Beep( 900, 200 );
+      printf( "Ctrl-Break event\n\n" );
+	  CLOSING = TRUE;
+      Beep( 750, 300 );
+     return FALSE;
+
+    case CTRL_LOGOFF_EVENT:
+      Beep( 1000, 200 );
+      printf( "Ctrl-Logoff event\n\n" );
+      return FALSE;
+
+    case CTRL_SHUTDOWN_EVENT:
+      Beep( 750, 500 );
+      printf( "Ctrl-Shutdown event\n\n" );
+	  CLOSING = TRUE;
+      Beep( 750, 300 );
+    return FALSE;
+
+    default:
+      return FALSE;
+  }
+}
+
+#else
+
+// Linux Signal Handlers
+
+static void sigterm_handler(int sig)
+{
+	syslog(LOG_INFO, "terminating on SIGTERM\n");
+	CLOSING = TRUE;
+}
+
+static void sigint_handler(int sig)
+{
+	printf("terminating on SIGINT\n");
+	CLOSING = TRUE;
+}
+
+
+static void sigusr1_handler(int sig)
+{
+	signal(SIGUSR1, sigusr1_handler);
+}
+
+#endif
+
+
+#ifndef WIN32
+
+BOOL CopyFile(char * In, char * Out, BOOL Failifexists)
+{
+	FILE * Handle;
+	DWORD FileSize;
+	char * Buffer;
+	struct stat STAT;
+
+	if (stat(In, &STAT) == -1)
+		return FALSE;
+
+	FileSize = STAT.st_size;
+
+	Handle = fopen(In, "rb");
+
+	if (Handle == NULL)
+		return FALSE;
+
+	Buffer = malloc(FileSize+1);
+
+	FileSize = fread(Buffer, 1, STAT.st_size, Handle);
+
+	fclose(Handle);
+
+	if (FileSize != STAT.st_size)
+	{
+		free(Buffer);
+		return FALSE;
+	}
+
+	Handle = fopen(Out, "wb");
+
+	if (Handle == NULL)
+	{
+		free(Buffer);
+		return FALSE;
+	}
+
+	FileSize = fwrite(Buffer, 1, STAT.st_size, Handle);
+
+	fclose(Handle);
+	free(Buffer);
+
+	return TRUE;
+}
+#endif
+
+int RefreshMainWindow()
+{
+	return 0;
+}
+
+int LastSemGets = 0;
+
+extern int SemHeldByAPI;
+
+VOID MonitorThread(void * x)
+{
+	// Thread to detect stuck semaphore
+
+	do
+	{
+		if ((Semaphore.Gets == LastSemGets) && Semaphore.Flag)
+		{
+			// It is stuck - try to release
+
+			Debugprintf ("Semaphore locked - Process ID = %d, Held By %d",
+				Semaphore.SemProcessID, SemHeldByAPI);
+
+			Semaphore.Flag = 0;
+		}
+
+		LastSemGets = Semaphore.Gets;
+
+		Sleep(30000);
+//		Debugprintf("Monitor Thread Still going %d %d %d %x %d", LastSemGets, Semaphore.Gets, Semaphore.Flag, Semaphore.SemThreadID, SemHeldByAPI);
+
+	} 
+	while (TRUE);
+}
+
+
+
+
+VOID TIMERINTERRUPT();
+
+BOOL Start();
+VOID INITIALISEPORTS();
+Dll BOOL APIENTRY Init_APRS();
+VOID APRSClose();
+Dll VOID APIENTRY Poll_APRS();
+VOID HTTPTimer();
+
+
+#define CKernel
+#include "Versions.h"
+
+extern struct SEM Semaphore;
+
+int SemHeldByAPI = 0;
+BOOL IGateEnabled = TRUE;
+BOOL APRSActive = FALSE;
+BOOL ReconfigFlag = FALSE;
+BOOL APRSReconfigFlag = FALSE;
+BOOL RigReconfigFlag = FALSE;
+
+BOOL IPActive = FALSE;
+extern BOOL IPRequired;
+
+extern struct WL2KInfo * WL2KReports;
+
+int InitDone;
+char pgm[256] = "LINBPQ";
+
+char SESSIONHDDR[80] = "";
+int SESSHDDRLEN = 0;
+
+
+// Next 3 should be uninitialised so they are local to each process
+
+UCHAR MCOM;
+UCHAR MUIONLY;
+UCHAR MTX;
+uint64_t MMASK;
+
+
+UCHAR AuthorisedProgram;			// Local Variable. Set if Program is on secure list
+
+int SAVEPORT = 0;
+
+VOID SetApplPorts();
+
+char VersionString[50] = Verstring;
+char VersionStringWithBuild[50]=Verstring;
+int Ver[4] = {Vers};
+char TextVerstring[50] = Verstring;
+
+extern UCHAR PWLen;
+extern char PWTEXT[];
+extern int ISPort;
+
+extern char ChatConfigName[250];
+
+BOOL EventsEnabled = 0;
+
+UCHAR * GetBPQDirectory()
+{
+	return BPQDirectory;
+}
+UCHAR * GetLogDirectory()
+{
+	return LogDirectory;
+}
+extern int POP3Timer;
+
+// Console Terminal Stuff
+
+#ifndef WIN32
+
+#define _getch getchar
+
+/**
+ Linux (POSIX) implementation of _kbhit().
+ Morgan McGuire, morgan@cs.brown.edu
+ */
+
+#include <stdio.h>
+#include <sys/select.h>
+#include <termios.h>
+//#include <stropts.h>
+
+int _kbhit() {
+    static const int STDIN = 0;
+    static int initialized = 0;
+
+    if (! initialized) {
+        // Use termios to turn off line buffering
+        struct termios term;
+        tcgetattr(STDIN, &term);
+        term.c_lflag &= ~ICANON;
+ 
+        tcsetattr(STDIN, TCSANOW, &term);
+        setbuf(stdin, NULL);
+        initialized = 1;
+    }
+
+    int bytesWaiting;
+    ioctl(STDIN, FIONREAD, &bytesWaiting);
+    return bytesWaiting;
+}
+
+#endif
+
+void ConTermInput(char * Msg)
+{
+	int i;
+
+	if (ConTerm.BPQStream == 0)
+	{
+		ConTerm.BPQStream = FindFreeStream();
+
+		if (ConTerm.BPQStream == 255)
+		{
+			ConTerm.BPQStream = 0;
+			printf("No Free Streams\n");
+			return;
+		}
+	}
+	
+	if (!ConTerm.CONNECTED)
+		SessionControl(ConTerm.BPQStream, 1, 0);
+
+	ConTerm.StackIndex = 0;
+
+	// Stack it
+
+	if (ConTerm.KbdStack[19])
+		free(ConTerm.KbdStack[19]);
+
+	for (i = 18; i >= 0; i--)
+	{
+		ConTerm.KbdStack[i+1] = ConTerm.KbdStack[i];
+	}
+
+	ConTerm.KbdStack[0] = _strdup(ConTerm.kbbuf);
+
+	ConTerm.kbbuf[ConTerm.kbptr]=13;
+
+	SendMsg(ConTerm.BPQStream, ConTerm.kbbuf, ConTerm.kbptr+1);
+}
+
+void ConTermPoll()
+{
+	int port, sesstype, paclen, maxframe, l4window, len;
+	int state, change, InputLen, count;
+	char callsign[11] = "";
+	char Msg[300];
+
+	//	Get current Session State. Any state changed is ACK'ed
+	//	automatically. See BPQHOST functions 4 and 5.
+	
+	SessionState(ConTerm.BPQStream, &state, &change);
+		
+	if (change == 1)
+	{
+		if (state == 1)
+		{
+			// Connected
+
+			ConTerm.CONNECTED = TRUE;
+			ConTerm.SlowTimer = 0;
+		}
+		else
+		{
+			ConTerm.CONNECTED = FALSE;
+			printf("*** Disconnected\n");		
+		}
+	}
+
+	GetMsg(ConTerm.BPQStream, Msg, &InputLen, &count);
+
+	if (InputLen)
+	{
+		char * ptr = Msg;
+		char * ptr2 = ptr;
+		Msg[InputLen] = 0;
+		
+		while (ptr)
+		{
+			ptr2 = strlop(ptr, 13);
+
+		// Replace CR with CRLF
+
+			printf(ptr);
+
+			if (ptr2)
+				printf("\r\n");
+
+			ptr = ptr2;
+		}
+	}
+
+	if (_kbhit())
+	{
+        unsigned char c = _getch();
+
+		if (c == 0xe0)
+		{
+			// Cursor control 
+
+			c = _getch();
+
+			if (c == 75)		// cursor left
+				c = 8;
+		}
+
+#ifdef WIN32
+		printf("%c", c);
+#endif
+		if (c == 8)
+		{
+			if (ConTerm.kbptr)
+				ConTerm.kbptr--;
+			printf(" \b");		// Already echoed bs - clear typed char from screen
+			return;
+		}
+
+		if (c == 13  || c == 10)
+		{
+			 ConTermInput(ConTerm.kbbuf);
+			 ConTerm.kbptr = 0;
+			 return;
+		}
+
+		ConTerm.kbbuf[ConTerm.kbptr++] = c;
+		fflush(NULL);
+
+	}
+
+	return;
+
+}
+		
+
+int Redirected = 0;
+
+int main(int argc, char * argv[])
+{
+	int i;
+	struct UserInfo * user = NULL;
+	ConnectionInfo * conn;
+	struct stat STAT;
+	PEXTPORTDATA PORTVEC;
+	UCHAR LogDir[260];
+
+#ifdef WIN32
+
+	WSADATA       WsaData;            // receives data from WSAStartup
+	HWND hWnd = GetForegroundWindow();
+
+	WSAStartup(MAKEWORD(2, 0), &WsaData);
+	SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE);
+
+	// disable the [x] button.
+
+	if (hWnd != NULL)
+	{
+		HMENU hMenu = GetSystemMenu(hWnd, 0);
+		if (hMenu != NULL)
+		{
+			DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
+			DrawMenuBar(hWnd);
+		}
+	}
+
+#else
+	setlinebuf(stdout);
+	struct sigaction act;
+ 	openlog("LINBPQ", LOG_PID, LOG_DAEMON);
+#ifndef MACBPQ
+#ifndef FREEBSD
+	prctl(PR_SET_DUMPABLE, 1);					// Enable Core Dumps even with setcap
+#endif
+#endif
+
+	// Disable Console Terminal if stdout redirected
+
+	if (!isatty(STDOUT_FILENO))
+		Redirected = 1;
+
+#endif
+
+	printf("G8BPQ AX25 Packet Switch System Version %s %s\n", TextVerstring, Datestring);
+	printf("%s\n", VerCopyright);
+
+	if (argc > 1 && _stricmp(argv[1], "-v") == 0)
+		return 0;
+
+	sprintf(RlineVer, "LinBPQ%d.%d.%d", Ver[0], Ver[1], Ver[2]);
+
+
+	Debugprintf("G8BPQ AX25 Packet Switch System Version %s %s", TextVerstring, Datestring);
+
+#ifndef MACBPQ
+	_MYTIMEZONE = _timezone;
+#endif
+
+	if (_MYTIMEZONE < -86400 || _MYTIMEZONE > 86400)
+		_MYTIMEZONE = 0;
+
+#ifdef WIN32
+	GetCurrentDirectory(256, BPQDirectory);
+	GetCurrentDirectory(256, LogDirectory);
+#else
+	getcwd(BPQDirectory, 256);
+	getcwd(LogDirectory, 256);
+#endif
+	Consoleprintf("Current Directory is %s\n", BPQDirectory);
+
+	for (i = 1; i < argc; i++)
+	{
+		if (_memicmp(argv[i], "logdir=", 7) == 0)
+		{
+			strcpy(LogDirectory, &argv[i][7]);
+			break;
+		}
+	}
+
+
+	// Make sure logs directory exists
+
+	sprintf(LogDir, "%s/logs", LogDirectory);
+
+#ifdef WIN32
+	CreateDirectory(LogDir, NULL);
+#else
+	mkdir(LogDir, S_IRWXU | S_IRWXG | S_IRWXO);
+	chmod(LogDir, S_IRWXU | S_IRWXG | S_IRWXO);
+#endif
+
+	if (!ProcessConfig())
+	{
+			WritetoConsoleLocal("Configuration File Error\n");
+			return (0);
+	}
+
+	SESSHDDRLEN = sprintf(SESSIONHDDR, "G8BPQ Network System %s for Linux (", TextVerstring);
+
+#ifdef MACBPQ
+	SESSHDDRLEN = sprintf(SESSIONHDDR, "G8BPQ Network System %s for MAC (", TextVerstring);
+#endif
+#ifdef FREEBSD
+	SESSHDDRLEN = sprintf(SESSIONHDDR, "G8BPQ Network System %s for FreeBSD (", TextVerstring);
+#endif
+
+
+	GetSemaphore(&Semaphore, 0);
+
+	if (Start() != 0)
+	{
+		FreeSemaphore(&Semaphore);
+		return (0);
+	}
+
+	for (i=0;PWTEXT[i] > 0x20;i++); //Scan for cr or null
+
+	PWLen=i;
+
+	SetApplPorts();
+
+	GetUIConfig();
+
+	INITIALISEPORTS();
+
+	if (IPRequired)	IPActive = Init_IP();
+
+	APRSActive = Init_APRS();
+
+	if (ISPort == 0)
+		IGateEnabled = 0;
+
+	if (needAIS)
+		initAIS();
+
+	RigActive = Rig_Init();
+
+	FreeSemaphore(&Semaphore);
+
+	OpenReportingSockets();
+
+	initUTF8();
+
+	InitDone = TRUE;
+
+	Debugprintf("Monitor Thread ID %x", _beginthread(MonitorThread, 0, 0));
+
+
+#ifdef WIN32
+#else
+	openlog("LINBPQ", LOG_PID, LOG_DAEMON);
+ 
+	memset (&act, '\0', sizeof(act));
+ 
+	act.sa_handler = &sigint_handler; 
+	if (sigaction(SIGINT, &act, NULL) < 0) 
+		perror ("SIGINT");
+
+	act.sa_handler = &sigterm_handler; 
+	if (sigaction(SIGTERM, &act, NULL) < 0) 
+		perror ("sigaction");
+
+	act.sa_handler = SIG_IGN; 
+	if (sigaction(SIGHUP, &act, NULL) < 0) 
+		perror ("SIGHUP");
+
+	if (sigaction(SIGPIPE, &act, NULL) < 0) 
+		perror ("SIGPIPE");
+
+#endif
+
+	for (i = 1; i < argc; i++)
+	{
+		if (_stricmp(argv[i], "chat") == 0)
+			IncludesChat = TRUE;
+	}
+
+	if (IncludesChat) 
+	{
+		RunChat = TRUE;
+
+		printf("Starting Chat\n");
+
+		sprintf (ChatConfigName, "%s/chatconfig.cfg", BPQDirectory);
+		printf("Config File is %s\n", ChatConfigName);
+
+		if (stat(ChatConfigName, &STAT) == -1)
+		{
+			printf("Chat Config File not found - creating a default config\n");
+			ChatApplNum = 2;
+			MaxChatStreams = 10;
+			SaveChatConfigFile(ChatConfigName);
+		}
+
+		if (GetChatConfig(ChatConfigName) == EXIT_FAILURE)
+		{
+			printf("Chat Config File seems corrupt - check before continuing\n");
+			return -1;
+		}
+
+		if (ChatApplNum)
+		{
+			if (ChatInit() == 0)
+			{
+				printf("Chat Init Failed\n");
+				RunChat = 0;
+			}
+			else
+			{
+				printf("Chat Started\n");
+			}
+		}
+		else
+		{
+			printf("Chat APPLNUM not defined\n");
+			RunChat = 0;
+		}
+		CopyConfigFile(ChatConfigName);
+	}
+
+	// Start Mail if requested by command line or config
+
+	for (i = 1; i < argc; i++)
+	{
+		if (_stricmp(argv[i], "mail") == 0)
+			IncludesMail = TRUE;
+	}
+
+
+	if (IncludesMail)
+	{
+		RunMail = TRUE;
+
+		printf("Starting Mail\n");
+
+		sprintf (ConfigName, "%s/linmail.cfg", BPQDirectory);
+		printf("Config File is %s\n", ConfigName);
+
+		if (stat(ConfigName, &STAT) == -1)
+		{
+			printf("Config File not found - creating a default config\n");
+			strcpy(BBSName, MYNODECALL);
+			strlop(BBSName, '-');
+			strlop(BBSName, ' ');
+			BBSApplNum = 1;
+			MaxStreams = 10;
+			SaveConfig(ConfigName);
+		}
+
+		if (GetConfig(ConfigName) == EXIT_FAILURE)
+		{
+			printf("BBS Config File seems corrupt - check before continuing\n");
+			return -1;
+		}
+
+		printf("Config Processed\n");
+
+		BBSApplMask = 1<<(BBSApplNum-1);
+
+	// See if we need to warn of possible problem with BaseDir moved by installer
+
+	sprintf(BaseDir, "%s", BPQDirectory);
+
+
+	// Set up file and directory names
+
+	strcpy(UserDatabasePath, BaseDir);
+	strcat(UserDatabasePath, "/");
+	strcat(UserDatabasePath, UserDatabaseName);
+
+	strcpy(MsgDatabasePath, BaseDir);
+	strcat(MsgDatabasePath, "/");
+	strcat(MsgDatabasePath, MsgDatabaseName);
+
+	strcpy(BIDDatabasePath, BaseDir);
+	strcat(BIDDatabasePath, "/");
+	strcat(BIDDatabasePath, BIDDatabaseName);
+
+	strcpy(WPDatabasePath, BaseDir);
+	strcat(WPDatabasePath, "/");
+	strcat(WPDatabasePath, WPDatabaseName);
+
+	strcpy(BadWordsPath, BaseDir);
+	strcat(BadWordsPath, "/");
+	strcat(BadWordsPath, BadWordsName);
+
+	strcpy(NTSAliasesPath, BaseDir);
+	strcat(NTSAliasesPath, "/");
+	strcat(NTSAliasesPath, NTSAliasesName);
+
+	strcpy(MailDir, BaseDir);
+	strcat(MailDir, "/");
+	strcat(MailDir, "Mail");
+
+#ifdef WIN32
+	CreateDirectory(MailDir, NULL);		// Just in case
+#else
+	mkdir(MailDir, S_IRWXU | S_IRWXG | S_IRWXO);
+	chmod(MailDir, S_IRWXU | S_IRWXG | S_IRWXO);
+#endif
+
+	// Make backup copies of Databases
+
+//	CopyConfigFile(ConfigName);
+
+	CopyBIDDatabase();
+	CopyMessageDatabase();
+	CopyUserDatabase();
+	CopyWPDatabase();
+
+	SetupMyHA();
+	SetupFwdAliases();
+	SetupNTSAliases(NTSAliasesPath);
+
+	GetWPDatabase();
+
+	GetMessageDatabase();
+	GetUserDatabase();
+	GetBIDDatabase();
+	GetBadWordFile();
+	GetHTMLForms();
+
+	// Make sure there is a user record for the BBS, with BBS bit set.
+
+	user = LookupCall(BBSName);
+
+	if (user == NULL)
+	{
+		user = AllocateUserRecord(BBSName);
+		user->Temp = zalloc(sizeof (struct TempUserInfo));
+	}
+
+	if ((user->flags & F_BBS) == 0)
+	{
+		// Not Defined as a BBS
+
+		if(SetupNewBBS(user))
+			user->flags |= F_BBS;
+	}
+
+	// if forwarding AMPR mail make sure User/BBS AMPR exists
+
+	if (SendAMPRDirect)
+	{
+		BOOL NeedSave = FALSE;
+		
+		user = LookupCall("AMPR");
+		
+		if (user == NULL)
+		{
+			user = AllocateUserRecord("AMPR");
+			user->Temp = zalloc(sizeof (struct TempUserInfo));
+			NeedSave = TRUE;
+		}
+
+		if ((user->flags & F_BBS) == 0)
+		{
+			// Not Defined as a BBS
+
+			if (SetupNewBBS(user))
+				user->flags |= F_BBS;
+			NeedSave = TRUE;
+		}
+
+		if (NeedSave)
+			SaveUserDatabase();
+	}
+
+
+	// Make sure SYSOPCALL is set
+
+	if (SYSOPCall[0] == 0)
+		strcpy(SYSOPCall, BBSName);
+
+	// See if just want to add user (mainly for setup scripts)
+
+	if (argc == 5 && _stricmp(argv[1], "--adduser") == 0)
+	{
+		BOOL isBBS = FALSE;
+		char * response;
+
+		if (_stricmp(argv[4], "TRUE") == 0)
+			isBBS = TRUE;
+
+		printf("Adding User %s\r\n", argv[2]);
+		response = AddUser(argv[2], argv[3], isBBS);
+		printf("%s", response);
+		exit(0);
+	}
+	// Allocate Streams
+
+	strcpy(pgm, "BBS");
+
+	for (i=0; i < MaxStreams; i++)
+	{
+		conn = &Connections[i];
+		conn->BPQStream = FindFreeStream();
+
+		if (conn->BPQStream == 255) break;
+
+		NumberofStreams++;
+
+//		BPQSetHandle(conn->BPQStream, hWnd);
+
+		SetAppl(conn->BPQStream, (i == 0 && EnableUI) ? 0x82 : 2, BBSApplMask);
+		Disconnect(conn->BPQStream);
+	}
+
+	strcpy(pgm, "LINBPQ");
+
+	Debugprintf("POP3 Debug Before Init TCP Timer = %d", POP3Timer);
+
+	InitialiseTCP();
+	Debugprintf("POP3 Debug Before Init NNTP Timer = %d", POP3Timer);
+	InitialiseNNTP();
+
+	SetupListenSet();		// Master set of listening sockets
+
+	if (EnableUI || MailForInterval)
+		SetupUIInterface();
+
+	if (MailForInterval)
+		_beginthread(SendMailForThread, 0, 0);
+
+
+	// Calulate time to run Housekeeping
+	{
+		struct tm *tm;
+		time_t now;
+
+		now = time(NULL);
+
+		tm = gmtime(&now);
+
+		tm->tm_hour = MaintTime / 100;
+		tm->tm_min = MaintTime % 100;
+		tm->tm_sec = 0;
+
+		MaintClock = mktime(tm) - (time_t)_MYTIMEZONE;
+
+		while (MaintClock < now)
+			MaintClock += MaintInterval * 3600;
+
+		Debugprintf("Maint Clock %lld NOW %lld Time to HouseKeeping %lld", (long long)MaintClock, (long long)now, (long long)(MaintClock - now));
+
+		if (LastHouseKeepingTime)
+		{
+			if ((now - LastHouseKeepingTime) > MaintInterval * 3600)
+			{
+				DoHouseKeeping(FALSE);
+			}
+		}
+		for (i = 1; i < argc; i++)
+		{
+			if (_stricmp(argv[i], "tidymail") == 0)
+				DeleteRedundantMessages();
+
+			if (_stricmp(argv[i], "nohomebbs") == 0)
+				DontNeedHomeBBS = TRUE;
+		}
+
+		printf("Mail Started\n");
+		Logprintf(LOG_BBS, NULL, '!', "Mail Starting");
+
+	}
+	}
+
+	Debugprintf("POP3 Debug After Mail Init Timer = %d", POP3Timer);
+
+	if (NUMBEROFTNCPORTS)
+		InitializeTNCEmulator();
+
+	AGWActive = AGWAPIInit();
+
+#ifndef WIN32
+
+	for (i = 1; i < argc; i++)
+	{
+		if (_stricmp(argv[i], "daemon") == 0)
+		{
+	
+			// Convert to daemon
+	
+			pid_t pid, sid;
+
+		    /* Fork off the parent process */
+			pid = fork();
+
+			if (pid < 0)
+				exit(EXIT_FAILURE);
+
+			if (pid > 0)
+				exit(EXIT_SUCCESS);
+
+			/* Change the file mode mask */
+
+			umask(0);
+
+			/* Create a new SID for the child process */
+
+			sid = setsid();
+
+			if (sid < 0)
+				exit(EXIT_FAILURE);
+
+			 /* Change the current working directory */
+
+			if ((chdir("/")) < 0)
+				exit(EXIT_FAILURE);
+
+			/* Close out the standard file descriptors */
+
+			printf("Entering daemon mode\n");
+
+			close(STDIN_FILENO);
+			close(STDOUT_FILENO);
+			close(STDERR_FILENO);
+			break;
+		}
+	}
+#endif
+
+	while (KEEPGOING)
+	{
+		Sleep(100);
+		GetSemaphore(&Semaphore, 2);
+
+		if (QCOUNT < 10)
+		{
+			if (CLOSING == FALSE)
+				FindLostBuffers();
+			CLOSING = TRUE;
+		}
+
+		if (CLOSING)
+		{
+			if (RunChat)
+			{
+				CloseChat();
+				RunChat = FALSE;
+			}
+
+			if (RunMail)
+			{
+				int BPQStream, n;
+
+				RunMail = FALSE;
+
+				for (n = 0; n < NumberofStreams; n++)
+				{
+					BPQStream = Connections[n].BPQStream;
+
+					if (BPQStream)
+					{
+						SetAppl(BPQStream, 0, 0);
+						Disconnect(BPQStream);
+						DeallocateStream(BPQStream);
+					}
+				}
+
+//				SaveUserDatabase();
+				SaveMessageDatabase();
+				SaveBIDDatabase();
+				SaveConfig(ConfigName);
+			}
+
+			KEEPGOING--;					// Give time for links to close
+			setbuf(stdout, NULL);
+			printf("Closing... %d  \r", KEEPGOING);
+		}
+
+
+		if (RigReconfigFlag)
+		{
+			RigReconfigFlag = FALSE;
+			Rig_Close();
+			Sleep(2000);				// Allow CATPTT threads to close
+			RigActive = Rig_Init();
+
+			Consoleprintf("Rigcontrol Reconfiguration Complete");	
+		}
+
+		if (APRSReconfigFlag)
+		{
+			APRSReconfigFlag = FALSE;
+			APRSClose();				
+			APRSActive = Init_APRS();
+
+			Consoleprintf("APRS Reconfiguration Complete");	
+		}
+
+		if (ReconfigFlag)
+		{
+			int i;
+			BPQVECSTRUC * HOSTVEC;
+			PEXTPORTDATA PORTVEC=(PEXTPORTDATA)PORTTABLE;
+
+			ReconfigFlag = FALSE;
+
+//			SetupBPQDirectory();
+
+			WritetoConsoleLocal("Reconfiguring ...\n\n");
+			OutputDebugString("BPQ32 Reconfiguring ...\n");
+
+
+			for (i=0;i<NUMBEROFPORTS;i++)
+			{
+				if (PORTVEC->PORTCONTROL.PORTTYPE == 0x10)			// External
+				{
+					if (PORTVEC->PORT_EXT_ADDR)
+					{
+//						SaveWindowPos(PORTVEC->PORTCONTROL.PORTNUMBER);
+//						SaveAXIPWindowPos(PORTVEC->PORTCONTROL.PORTNUMBER);
+//						CloseDriverWindow(PORTVEC->PORTCONTROL.PORTNUMBER);
+						PORTVEC->PORT_EXT_ADDR(5,PORTVEC->PORTCONTROL.PORTNUMBER, NULL);	// Close External Ports
+					}
+				}
+				PORTVEC->PORTCONTROL.PORTCLOSECODE(&PORTVEC->PORTCONTROL);
+				PORTVEC=(PEXTPORTDATA)PORTVEC->PORTCONTROL.PORTPOINTER;
+			}
+
+			IPClose();
+			APRSClose();
+			Rig_Close();
+			CloseTNCEmulator();
+
+			if (AGWActive)
+				AGWAPITerminate();
+
+			WL2KReports = NULL;
+
+//			Sleep(2000);
+
+			Consoleprintf("G8BPQ AX25 Packet Switch System Version %s %s", TextVerstring, Datestring);
+			Consoleprintf(VerCopyright);
+
+			Start();
+
+			INITIALISEPORTS();
+
+			SetApplPorts();
+
+			GetUIConfig();
+
+			FreeConfig();
+
+			for (i=1; i<68; i++)			// Include Telnet, APRS, IP Vec
+			{
+				HOSTVEC=&BPQHOSTVECTOR[i-1];
+
+				HOSTVEC->HOSTTRACEQ=0;
+
+				if (HOSTVEC->HOSTSESSION !=0)
+				{
+					// Had a connection
+
+					HOSTVEC->HOSTSESSION=0;
+					HOSTVEC->HOSTFLAGS |=3;	// Disconnected
+
+//					PostMessage(HOSTVEC->HOSTHANDLE, BPQMsg, i, 4);
+				}
+			}
+
+			OpenReportingSockets();
+
+			WritetoConsoleLocal("\n\nReconfiguration Complete\n");
+
+			if (IPRequired)	IPActive = Init_IP();
+
+			APRSActive = Init_APRS();
+
+			if (ISPort == 0)
+				IGateEnabled = 0;
+
+			RigActive = Rig_Init();
+
+			if (NUMBEROFTNCPORTS)
+			{
+				FreeSemaphore(&Semaphore);
+				InitializeTNCEmulator();
+				GetSemaphore(&Semaphore, 2);
+			}
+
+			FreeSemaphore(&Semaphore);
+			AGWActive = AGWAPIInit();
+			GetSemaphore(&Semaphore, 2);
+
+			OutputDebugString("BPQ32 Reconfiguration Complete\n");
+		}
+
+		if (IPActive) Poll_IP();
+		if (RigActive) Rig_Poll();
+		if (APRSActive) Poll_APRS();
+		CheckWL2KReportTimer();
+
+		TIMERINTERRUPT();
+
+		FreeSemaphore(&Semaphore);
+
+		if (Redirected == 0)
+			ConTermPoll();
+
+		if (NUMBEROFTNCPORTS)
+			TNCTimer();
+
+		if (AGWActive)
+			Poll_AGW();
+
+		DRATSPoll();
+
+		HTTPTimer();
+
+		if (ReportTimer)
+		{
+			ReportTimer--;
+
+			if (ReportTimer == 0)
+			{
+				ReportTimer = REPORTINTERVAL;
+				SendLocation();
+			}
+		}
+
+		Slowtimer++;
+
+		if (RunChat)
+		{
+			ChatPollStreams();
+			ChatTrytoSend();
+
+			if (Slowtimer > 100)		// 10 secs
+			{
+				ChatTimer();
+			}
+		}
+
+		if (RunMail)
+		{
+			PollStreams();
+
+			if (Slowtimer > 100)		// 10 secs
+			{
+				time_t NOW = time(NULL);
+				struct tm * tm;
+
+				TCPTimer();
+				FWDTimerProc();
+				BBSSlowTimer();
+
+				if (MaintClock < NOW)
+				{
+					while (MaintClock < NOW)		// in case large time step
+						MaintClock += MaintInterval * 3600;
+
+					Debugprintf("|Enter HouseKeeping");
+					DoHouseKeeping(FALSE);
+				}
+
+				tm = gmtime(&NOW);
+
+				if (tm->tm_wday == 0)		// Sunday
+				{
+					if (GenerateTrafficReport && (LastTrafficTime + 86400) < NOW)
+					{
+						LastTrafficTime = NOW;
+						CreateBBSTrafficReport();
+					}
+				}
+			}
+			TCPFastTimer();
+			TrytoSend();
+		}
+
+		if (Slowtimer > 100)
+			Slowtimer = 0;
+	}
+
+	printf("Closing Ports\n");
+
+	CloseTNCEmulator();
+
+	if (AGWActive)
+		AGWAPITerminate();
+
+	if (needAIS)
+		SaveAIS();
+
+	// Close Ports
+
+	PORTVEC=(PEXTPORTDATA)PORTTABLE;
+
+	for (i=0;i<NUMBEROFPORTS;i++)
+	{
+		if (PORTVEC->PORTCONTROL.PORTTYPE == 0x10)			// External
+		{
+			if (PORTVEC->PORT_EXT_ADDR)
+			{
+				PORTVEC->PORT_EXT_ADDR(5, PORTVEC->PORTCONTROL.PORTNUMBER, NULL);
+			}
+		}
+		PORTVEC=(PEXTPORTDATA)PORTVEC->PORTCONTROL.PORTPOINTER;
+	}
+
+	if (AUTOSAVE)
+		SaveNodes();
+
+	if (AUTOSAVEMH)
+		SaveMH();
+
+	if (IPActive)
+		IPClose();
+
+	if (RunMail)
+		FreeWebMailMallocs();
+
+	upnpClose();
+
+	// Close any open logs
+
+	for (i = 0; i < 4; i++)
+	{
+		if (LogHandle[i])
+			fclose(LogHandle[i]);
+	}
+
+	return 0;
+}
+
+int APIENTRY WritetoConsole(char * buff)
+{
+	return WritetoConsoleLocal(buff);
+}
+
+int WritetoConsoleLocal(char * buff)
+{
+	return printf("%s", buff);
+}
+
+#ifdef WIN32
+void * VCOMExtInit(struct PORTCONTROL *  PortEntry);
+void * V4ExtInit(EXTPORTDATA * PortEntry);
+#endif
+//UINT SoundModemExtInit(EXTPORTDATA * PortEntry);
+//UINT BaycomExtInit(EXTPORTDATA * PortEntry);
+
+void * AEAExtInit(struct PORTCONTROL *  PortEntry);
+void * MPSKExtInit(EXTPORTDATA * PortEntry);
+void * HALExtInit(struct PORTCONTROL *  PortEntry);
+
+void * AGWExtInit(struct PORTCONTROL *  PortEntry);
+void * KAMExtInit(struct PORTCONTROL *  PortEntry);
+void * WinmorExtInit(EXTPORTDATA * PortEntry);
+void * SCSExtInit(struct PORTCONTROL *  PortEntry);
+void * TrackerExtInit(EXTPORTDATA * PortEntry);
+void * TrackerMExtInit(EXTPORTDATA * PortEntry);
+
+void * TelnetExtInit(EXTPORTDATA * PortEntry);
+void * UZ7HOExtInit(EXTPORTDATA * PortEntry);
+void * FLDigiExtInit(EXTPORTDATA * PortEntry);
+void * ETHERExtInit(struct PORTCONTROL *  PortEntry);
+void * AXIPExtInit(struct PORTCONTROL *  PortEntry);
+void * ARDOPExtInit(EXTPORTDATA * PortEntry);
+void * VARAExtInit(EXTPORTDATA * PortEntry);
+void * SerialExtInit(EXTPORTDATA * PortEntry);
+void * WinRPRExtInit(EXTPORTDATA * PortEntry);
+void * HSMODEMExtInit(EXTPORTDATA * PortEntry);
+void * FreeDataExtInit(EXTPORTDATA * PortEntry);
+void * KISSHFExtInit(EXTPORTDATA * PortEntry);
+
+void * InitializeExtDriver(PEXTPORTDATA PORTVEC)
+{
+	// Only works with built in drivers
+
+	UCHAR Value[20];
+
+	strcpy(Value,PORTVEC->PORT_DLL_NAME);
+
+	_strupr(Value);
+
+#ifndef FREEBSD
+#ifndef MACBPQ
+	if (strstr(Value, "BPQETHER"))
+		return ETHERExtInit;
+#endif
+#endif
+	if (strstr(Value, "BPQAXIP"))
+		return AXIPExtInit;
+
+	if (strstr(Value, "BPQTOAGW"))
+		return AGWExtInit;
+
+	if (strstr(Value, "AEAPACTOR"))
+		return AEAExtInit;
+
+	if (strstr(Value, "HALDRIVER"))
+		return HALExtInit;
+
+#ifdef WIN32
+
+	if (strstr(Value, "BPQVKISS"))
+		return VCOMExtInit;
+
+	if (strstr(Value, "V4"))
+		return V4ExtInit;
+
+#endif
+/*
+	if (strstr(Value, "SOUNDMODEM"))
+		return (UINT) SoundModemExtInit;
+
+	if (strstr(Value, "BAYCOM"))
+		return (UINT) BaycomExtInit;
+*/
+	if (strstr(Value, "MULTIPSK"))
+		return MPSKExtInit;
+
+	if (strstr(Value, "KAMPACTOR"))
+		return KAMExtInit;
+
+	if (strstr(Value, "WINMOR"))
+		return WinmorExtInit;
+
+	if (strstr(Value, "SCSPACTOR"))
+		return SCSExtInit;
+
+	if (strstr(Value, "SCSTRACKER"))
+		return TrackerExtInit;
+
+	if (strstr(Value, "TRKMULTI"))
+		return TrackerMExtInit;
+
+	if (strstr(Value, "UZ7HO"))
+		return UZ7HOExtInit;
+
+	if (strstr(Value, "FLDIGI"))
+		return FLDigiExtInit;
+
+	if (strstr(Value, "TELNET"))
+		return TelnetExtInit;
+
+	if (strstr(Value, "ARDOP"))
+		return ARDOPExtInit;
+
+	if (strstr(Value, "VARA"))
+		return VARAExtInit;
+
+	if (strstr(Value, "KISSHF"))
+		return KISSHFExtInit;
+
+	if (strstr(Value, "SERIAL"))
+		return SerialExtInit;
+
+	if (strstr(Value, "WINRPR"))
+		return WinRPRExtInit;
+
+	if (strstr(Value, "HSMODEM"))
+		return HSMODEMExtInit;
+
+	if (strstr(Value, "FREEDATA"))
+		return FreeDataExtInit;
+
+	return(0);
+}
+
+int APIENTRY Restart()
+{
+	CLOSING = TRUE;
+	return TRUE;
+}
+
+int APIENTRY Reboot()
+{
+	// Run sudo shutdown -r -f
+#ifdef WIN32
+	STARTUPINFO  SInfo;
+    PROCESS_INFORMATION PInfo;
+	char Cmd[] = "shutdown -r -f";
+
+
+	SInfo.cb=sizeof(SInfo);
+	SInfo.lpReserved=NULL;
+	SInfo.lpDesktop=NULL;
+	SInfo.lpTitle=NULL;
+	SInfo.dwFlags=0;
+	SInfo.cbReserved2=0;
+  	SInfo.lpReserved2=NULL;
+
+	return CreateProcess(NULL, Cmd, NULL, NULL, FALSE,0 ,NULL ,NULL, &SInfo, &PInfo);
+	return 0;
+#else
+	
+	char * arg_list[] = {NULL, NULL, NULL, NULL, NULL};
+	pid_t child_pid;
+	char * Context;
+	signal(SIGCHLD, SIG_IGN); // Silently (and portably) reap children. 
+
+	arg_list[0] = "sudo";
+	arg_list[1] = "shutdown";
+	arg_list[2] = "now";
+	arg_list[3] = "-r";
+
+	//	Fork and Exec shutdown
+
+	// Duplicate this process.  
+
+	child_pid = fork(); 
+
+	if (child_pid == -1) 
+	{    				
+		printf ("Reboot fork() Failed\n"); 
+		return 0;
+	}
+
+	if (child_pid == 0) 
+ 	{    				
+		execvp (arg_list[0], arg_list); 
+        
+		/* The execvp  function returns only if an error occurs.  */ 
+
+		printf ("Failed to run shutdown\n"); 
+		exit(0);			// Kill the new process
+	}
+	return TRUE;								 
+#endif
+
+}
+
+int APIENTRY Reconfig()
+{
+	if (!ProcessConfig())
+	{
+		return (0);
+	}
+	SaveNodes();
+	WritetoConsoleLocal("Nodes Saved\n");
+	ReconfigFlag=TRUE;
+	WritetoConsoleLocal("Reconfig requested ... Waiting for Timer Poll\n");
+	return 1;
+}
+
+int APRSWriteLog(char * msg);
+
+VOID MonitorAPRSIS(char * Msg, size_t MsgLen, BOOL TX)
+{
+	char Line[300];
+	char Copy[300];
+	int Len;
+	struct tm * TM;
+	time_t NOW;
+
+	if (LogAPRSIS == 0)
+		return;
+
+	if (MsgLen > 250)
+		return;
+
+	// Mustn't change Msg
+
+	memcpy(Copy, Msg, MsgLen);
+	Copy[MsgLen] = 0;
+
+	NOW = time(NULL);
+	TM = gmtime(&NOW);
+
+	Len = sprintf_s(Line, 299, "%02d:%02d:%02d%c %s", TM->tm_hour, TM->tm_min, TM->tm_sec, (TX)? 'T': 'R', Copy);
+
+	APRSWriteLog(Line);
+
+}
+
+struct TNCINFO * TNC;
+
+#ifndef WIN32
+
+#include <time.h>
+#include <sys/time.h>
+
+#ifndef MACBPQ
+#ifdef __MACH__
+
+#include <mach/mach_time.h>
+
+#define CLOCK_REALTIME 0
+#define CLOCK_MONOTONIC 0
+
+int clock_gettime(int clk_id, struct timespec *t){
+    mach_timebase_info_data_t timebase;
+    mach_timebase_info(&timebase);
+    uint64_t time;
+    time = mach_absolute_time();
+    double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
+    double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
+    t->tv_sec = seconds;
+    t->tv_nsec = nseconds;
+    return 0;
+}
+#endif
+#endif
+
+int GetTickCount()
+{
+	struct timespec ts;
+	clock_gettime(CLOCK_REALTIME, &ts);
+	return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
+}
+
+
+
+void SetWindowText(HWND hWnd, char * lpString)
+{
+	return;
+};
+
+BOOL SetDlgItemText(HWND hWnd, int item, char * lpString)
+{
+	return 0;
+};
+
+#endif
+
+int GetListeningPortsPID(int Port)
+{
+#ifdef WIN32
+
+	MIB_TCPTABLE_OWNER_PID * TcpTable = NULL;
+	PMIB_TCPROW_OWNER_PID Row;
+	int dwSize = 0;
+	unsigned int n;
+
+	// Get PID of process for this TCP Port
+
+	// Get Length of table
+	
+	GetExtendedTcpTable(TcpTable, &dwSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0);
+
+	TcpTable = malloc(dwSize);
+	GetExtendedTcpTable(TcpTable, &dwSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0);
+
+	for (n = 0; n < TcpTable->dwNumEntries; n++)
+	{
+		Row = &TcpTable->table[n];
+		
+		if (Row->dwLocalPort == Port && Row->dwState == MIB_TCP_STATE_LISTEN)
+		{
+			return Row->dwOwningPid;
+			break;
+		}
+	}
+#endif
+	return 0;			// Not found
+}
+
+
+
+VOID Check_Timer()
+{
+}
+
+VOID POSTDATAAVAIL(){};
+
+COLORREF Colours[256] = {0,
+		RGB(0,0,0), RGB(0,0,128), RGB(0,0,192), RGB(0,0,255),				// 1 - 4
+		RGB(0,64,0), RGB(0,64,128), RGB(0,64,192), RGB(0,64,255),			// 5 - 8
+		RGB(0,128,0), RGB(0,128,128), RGB(0,128,192), RGB(0,128,255),		// 9 - 12
+		RGB(0,192,0), RGB(0,192,128), RGB(0,192,192), RGB(0,192,255),		// 13 - 16
+		RGB(0,255,0), RGB(0,255,128), RGB(0,255,192), RGB(0,255,255),		// 17 - 20
+
+		RGB(6425,0,0), RGB(64,0,128), RGB(64,0,192), RGB(0,0,255),				// 21
+		RGB(64,64,0), RGB(64,64,128), RGB(64,64,192), RGB(64,64,255),
+		RGB(64,128,0), RGB(64,128,128), RGB(64,128,192), RGB(64,128,255),
+		RGB(64,192,0), RGB(64,192,128), RGB(64,192,192), RGB(64,192,255),
+		RGB(64,255,0), RGB(64,255,128), RGB(64,255,192), RGB(64,255,255),
+
+		RGB(128,0,0), RGB(128,0,128), RGB(128,0,192), RGB(128,0,255),				// 41
+		RGB(128,64,0), RGB(128,64,128), RGB(128,64,192), RGB(128,64,255),
+		RGB(128,128,0), RGB(128,128,128), RGB(128,128,192), RGB(128,128,255),
+		RGB(128,192,0), RGB(128,192,128), RGB(128,192,192), RGB(128,192,255),
+		RGB(128,255,0), RGB(128,255,128), RGB(128,255,192), RGB(128,255,255),
+
+		RGB(192,0,0), RGB(192,0,128), RGB(192,0,192), RGB(192,0,255),				// 61
+		RGB(192,64,0), RGB(192,64,128), RGB(192,64,192), RGB(192,64,255),
+		RGB(192,128,0), RGB(192,128,128), RGB(192,128,192), RGB(192,128,255),
+		RGB(192,192,0), RGB(192,192,128), RGB(192,192,192), RGB(192,192,255),
+		RGB(192,255,0), RGB(192,255,128), RGB(192,255,192), RGB(192,255,255),
+
+		RGB(255,0,0), RGB(255,0,128), RGB(255,0,192), RGB(255,0,255),				// 81
+		RGB(255,64,0), RGB(255,64,128), RGB(255,64,192), RGB(255,64,255),
+		RGB(255,128,0), RGB(255,128,128), RGB(255,128,192), RGB(255,128,255),
+		RGB(255,192,0), RGB(255,192,128), RGB(255,192,192), RGB(255,192,255),
+		RGB(255,255,0), RGB(255,255,128), RGB(255,255,192), RGB(255,255,255)
+};
+
+
+//VOID SendRPBeacon(struct TNCINFO * TNC)
+//{
+//}
+
+int PollStreams()
+{
+	int state,change;
+	ConnectionInfo * conn;
+	int n;
+	struct UserInfo * user = NULL;
+	char ConnectedMsg[] = "*** CONNECTED    ";
+
+	for (n = 0; n < NumberofStreams; n++)
+	{
+  		conn = &Connections[n];
+
+		DoReceivedData(conn->BPQStream);
+		DoBBSMonitorData(conn->BPQStream);
+
+		SessionState(conn->BPQStream, &state, &change);
+
+		if (change == 1)
+		{
+			if (state == 1) // Connected
+			{
+				GetSemaphore(&ConSemaphore, 0);
+				Connected(conn->BPQStream);
+				FreeSemaphore(&ConSemaphore);
+			}
+			else
+			{
+				GetSemaphore(&ConSemaphore, 0);
+				Disconnected(conn->BPQStream);
+				FreeSemaphore(&ConSemaphore);
+			}
+		}
+	}
+
+	return 0;
+}
+
+
+VOID CloseConsole(int Stream)
+{
+}
+
+#ifndef WIN32
+
+int V4ProcessReceivedData(struct TNCINFO * TNC)
+{
+	return 0;
+}
+#endif
+
+#ifdef FREEBSD
+
+char * gcvt(double _Val, int _NumOfDigits, char * _DstBuf)
+{
+	sprintf(_DstBuf, "%f", _Val);
+	return _DstBuf;
+}
+
+#endif
+
+
+
+
+
diff --git a/MULTIPSK.c b/MULTIPSK.c
index 91ba1a0..a20b964 100644
--- a/MULTIPSK.c
+++ b/MULTIPSK.c
@@ -84,7 +84,7 @@ extern UCHAR BPQDirectory[];
 static int MPSKChannel[MAXBPQPORTS+1];			// BPQ Port to MPSK Port
 static int BPQPort[MAXMPSKPORTS][MAXBPQPORTS+1];	// MPSK Port and Connection to BPQ Port
 
-static int MasterPort[MAXBPQPORTS+1];			// Pointer to first BPQ port for a specific MPSK host
+extern int MasterPort[MAXBPQPORTS+1];			// Pointer to first BPQ port for a specific MPSK host
 
 //	Each port may be on a different machine. We only open one connection to each MPSK instance
 
diff --git a/RigControl.c b/RigControl.c
index 9b33f57..6a7d026 100644
--- a/RigControl.c
+++ b/RigControl.c
@@ -70,8 +70,6 @@ VOID __cdecl Debugprintf(const char * format, ...);
 
 struct RIGINFO * RigConfig(struct TNCINFO * TNC, char * buf, int Port);
 struct RIGPORTINFO * CreateTTYInfo(int port, int speed);
-BOOL OpenConnection(int);
-BOOL SetupConnection(int);
 BOOL RigCloseConnection(struct RIGPORTINFO * PORT);
 BOOL RigWriteCommBlock(struct RIGPORTINFO * PORT);
 BOOL DestroyTTYInfo(int port);
diff --git a/SCSPactor.c b/SCSPactor.c
index 61568fa..244a62c 100644
--- a/SCSPactor.c
+++ b/SCSPactor.c
@@ -355,8 +355,7 @@ ConfigLine:
 }
 
 struct TNCINFO * CreateTTYInfo(int port, int speed);
-BOOL OpenConnection(int);
-BOOL SetupConnection(int);
+
 BOOL CloseConnection(struct TNCINFO * conn);
 BOOL WriteCommBlock(struct TNCINFO * TNC);
 BOOL DestroyTTYInfo(int port);
diff --git a/SCSTrackeMulti.c b/SCSTrackeMulti.c
index fd96d6a..f8459dd 100644
--- a/SCSTrackeMulti.c
+++ b/SCSTrackeMulti.c
@@ -140,9 +140,7 @@ ConfigLine:
 
 }
 
-struct TNCINFO * CreateTTYInfo(int port, int speed);
-BOOL OpenConnection(int);
-BOOL SetupConnection(int);
+
 BOOL CloseConnection(struct TNCINFO * conn);
 static BOOL WriteCommBlock(struct TNCINFO * TNC);
 BOOL DestroyTTYInfo(int port);
diff --git a/SCSTracker.c b/SCSTracker.c
index caa6b0e..c7d9f93 100644
--- a/SCSTracker.c
+++ b/SCSTracker.c
@@ -56,9 +56,6 @@ char * strlop(char * buf, char delim);
 
 char NodeCall[11];		// Nodecall, Null Terminated
 
-struct TNCINFO * CreateTTYInfo(int port, int speed);
-BOOL OpenConnection(int);
-BOOL SetupConnection(int);
 BOOL CloseConnection(struct TNCINFO * conn);
 BOOL TrkWriteCommBlock(struct TNCINFO * TNC);
 BOOL DestroyTTYInfo(int port);
diff --git a/TelnetV6.c b/TelnetV6.c
index 4a76bc2..c67516c 100644
--- a/TelnetV6.c
+++ b/TelnetV6.c
@@ -37,7 +37,6 @@ along with LinBPQ/BPQ32.  If not, see http://www.gnu.org/licenses
 #define IDM_DISCONNECT			2000
 #define IDM_LOGGING				2100
 
-#define MAXBLOCK 4096
 #include "CHeaders.h"
 #include "tncinfo.h"
 
diff --git a/UZ7HODrv.c b/UZ7HODrv.c
index 90732a2..7ec055b 100644
--- a/UZ7HODrv.c
+++ b/UZ7HODrv.c
@@ -96,7 +96,7 @@ static int BPQPort[MAXUZ7HOPORTS][MAXBPQPORTS+1];	// UZ7HO Port and Connection t
 static void * UZ7HOtoBPQ_Q[MAXBPQPORTS+1];			// Frames for BPQ, indexed by BPQ Port
 static void * BPQtoUZ7HO_Q[MAXBPQPORTS+1];			// Frames for UZ7HO. indexed by UZ7HO port. Only used it TCP session is blocked
 
-static int MasterPort[MAXBPQPORTS+1];			// Pointer to first BPQ port for a specific UZ7HO host
+int MasterPort[MAXBPQPORTS+1];						// Pointer to first BPQ port for a specific UZ7HO host
 static struct TNCINFO * SlaveTNC[MAXBPQPORTS+1];// TNC Record Slave if present
 
 //	Each port may be on a different machine. We only open one connection to each UZ7HO instance
diff --git a/Versions.h b/Versions.h
index fe9fcb6..f3bfe9d 100644
--- a/Versions.h
+++ b/Versions.h
@@ -10,8 +10,8 @@
 
 #endif
 
-#define KVers 6,0,23,76
-#define KVerstring "6.0.23.76\0"
+#define KVers 6,0,23,77
+#define KVerstring "6.0.23.77\0"
 
 #ifdef CKernel
 
diff --git a/WinRPR.c b/WinRPR.c
index f12971e..51c6983 100644
--- a/WinRPR.c
+++ b/WinRPR.c
@@ -67,12 +67,7 @@ char * strlop(char * buf, char delim);
 
 char NodeCall[11];		// Nodecall, Null Terminated
 
-struct TNCINFO * CreateTTYInfo(int port, int speed);
-BOOL OpenConnection(int);
-BOOL SetupConnection(int);
-BOOL CloseConnection(struct TNCINFO * conn);
 static BOOL WriteCommBlock(struct TNCINFO * TNC);
-BOOL DestroyTTYInfo(int port);
 static void DEDCheckRX(struct TNCINFO * TNC);
 VOID DEDPoll(int Port);
 VOID StuffAndSend(struct TNCINFO * TNC, UCHAR * Msg, int Len);
diff --git a/cMain.c b/cMain.c
index 1624f80..e6c1d88 100644
--- a/cMain.c
+++ b/cMain.c
@@ -1071,10 +1071,10 @@ BOOL Start()
 			KISS->KISSCMD = malloc(256);
 
 			KISS->KISSCMDLEN = KissEncode(KissString, KISS->KISSCMD, KissLen);
-			realloc(KISS->KISSCMD, KISS->KISSCMDLEN);
+			KISS->KISSCMD = realloc(KISS->KISSCMD, KISS->KISSCMDLEN);
 		}
 
-		if (PortRec->BBSFLAG)						// Appl 1 no permitted - BBSFLAG=NOBBS
+		if (PortRec->BBSFLAG)						// Appl 1 not permitted - BBSFLAG=NOBBS
 			PORT->PERMITTEDAPPLS &= 0xfffffffe;		// Clear bottom bit
 
 			
diff --git a/kiss.c b/kiss.c
index 0de9ae9..1f52345 100644
--- a/kiss.c
+++ b/kiss.c
@@ -34,17 +34,13 @@ along with LinBPQ/BPQ32.  If not, see http://www.gnu.org/licenses
 #include <time.h>
 #include <sys/types.h>
 #include <unistd.h>
-#ifndef RP2040
 #include <sys/ioctl.h>
 #include <termios.h>
 #include <syslog.h>
-#endif
 #include <fcntl.h>
 #include <signal.h>
 #include <ctype.h>
 
-
-
 //#include <netax25/ttyutils.h>
 //#include <netax25/daemon.h>
 
@@ -131,6 +127,9 @@ int lastcount;
 
 UCHAR ENCBUFF[600];
 
+NPASYINFO KISSInfo[MAXBPQPORTS] = {0};
+
+
 int ASYSEND(struct PORTCONTROL * PortVector, char * buffer, int count)
 {
 	NPASYINFO Port = KISSInfo[PortVector->PORTNUMBER];
@@ -160,7 +159,7 @@ int ASYSEND(struct PORTCONTROL * PortVector, char * buffer, int count)
 			if (ret == -1)
 			{
 				Debugprintf ("i2c Write Error\r");
-				Sleep(1);
+				usleep(1000);
 				ret = i2c_smbus_write_byte(Port->idComDev, *(ptr));
 			}		
 			ptr++;
@@ -309,15 +308,11 @@ int	ASYINIT(int comport, int speed, struct PORTCONTROL * PortVector, char Channe
 	}
 	else if (PortVector->PORTIPADDR.s_addr || PortVector->KISSSLAVE)
 	{
-
-#ifndef RP2040
-
 		SOCKET sock;
 		u_long param=1;
 		BOOL bcopt=TRUE;
 		struct sockaddr_in sinx;
 
-
 		// KISS over UDP or TCP
 
 		if (PortVector->ListenPort == 0)
@@ -431,7 +426,6 @@ int	ASYINIT(int comport, int speed, struct PORTCONTROL * PortVector, char Channe
 		npKISSINFO->RXMPTR=&npKISSINFO->RXMSG[0];
 
 		OpenConnection(PortVector);
-#endif
 	}
 
 	npKISSINFO->Portvector = PortVector; 
@@ -621,7 +615,7 @@ static void CheckReceivedData(struct PORTCONTROL * PORT, NPASYINFO npKISSINFO)
 				struct sockaddr_in rxaddr;
 				int addrlen = sizeof(struct sockaddr_in);
 
-				nLength = recvfrom(npKISSINFO->sock, &npKISSINFO->RXBUFFER[0], MAXBLOCK - 1, 0, (struct sockaddr *)&rxaddr, &addrlen);
+				nLength = recvfrom(npKISSINFO->sock, &npKISSINFO->RXBUFFER[0], KISSMAXBLOCK - 1, 0, (struct sockaddr *)&rxaddr, &addrlen);
 	
 				if (nLength < 0)
 				{
@@ -633,7 +627,7 @@ static void CheckReceivedData(struct PORTCONTROL * PORT, NPASYINFO npKISSINFO)
 			}
 		}
 		else
-			nLength = ReadCommBlock(npKISSINFO, (char *) &npKISSINFO->RXBUFFER, MAXBLOCK - 1);;
+			nLength = ReadCommBlock(npKISSINFO, (char *) &npKISSINFO->RXBUFFER, KISSMAXBLOCK - 1);;
 	
 		npKISSINFO->RXBCOUNT = nLength;
 		npKISSINFO->RXBPTR = (UCHAR *)&npKISSINFO->RXBUFFER; 
@@ -1359,7 +1353,7 @@ int KISSRX(struct KISSINFO * KISS)
 	PMESSAGE Buffer;
 	int len;
 	NPASYINFO Port = KISSInfo[PORT->PORTNUMBER];
-	struct KISSINFO * SAVEKISS = KISS;		// Save so we can restore at SeeifMode
+	struct KISSINFO * SAVEKISS = KISS;		// Save so we can restore at SeeifMore
 
 	if (Port == NULL)
 		return 0;
@@ -1596,13 +1590,13 @@ SeeifMore:
 	}
 
 	//	checksum if necessary
-#ifndef RP2040
+
 	if (KISS->PORT.KISSFLAGS & DRATS)
 	{
 		processDRATSFrame(&Port->RXMSG[1], len - 2, 0);
 		return 0;
 	}
-#endif
+
 	if (len < 15)
 		return 0;					// too short for AX25
 
@@ -1829,7 +1823,6 @@ int ConnecttoTCP(NPASYINFO ASY)
 
 VOID ConnecttoTCPThread(NPASYINFO ASY)
 {
-#ifndef RP2040
 	char Msg[255];
 	int err,i;
 	u_long param=1;
@@ -1926,13 +1919,10 @@ VOID ConnecttoTCPThread(NPASYINFO ASY)
 		}
 		Sleep (57000/2);						// 1/2 Mins
 	}
-#endif
 }
 
 int KISSGetTCPMessage(NPASYINFO ASY)
 {
-#ifndef RP2040
-
 	int index=0;
 	ULONG param = 1;
 
@@ -1973,7 +1963,7 @@ int KISSGetTCPMessage(NPASYINFO ASY)
 
 		// May have several messages per packet, or message split over packets
 
-		InputLen = recv(ASY->sock, ASY->RXBUFFER, MAXBLOCK - 1, 0);
+		InputLen = recv(ASY->sock, ASY->RXBUFFER, KISSMAXBLOCK - 1, 0);
 
 		if (InputLen < 0)
 		{
@@ -2008,8 +1998,6 @@ int KISSGetTCPMessage(NPASYINFO ASY)
 	{
 		// Reopen Listening Socket
 
-
-
 		SOCKET sock;
 		u_long param=1;
 		BOOL bcopt=TRUE;
@@ -2042,6 +2030,5 @@ int KISSGetTCPMessage(NPASYINFO ASY)
 				ASY->Listening = TRUE;	
 		}
 	}
-#endif
 	return 0;
 }
diff --git a/kiss.h b/kiss.h
index b45df2d..46e670f 100644
--- a/kiss.h
+++ b/kiss.h
@@ -1,6 +1,6 @@
 
 
-#define MAXBLOCK        512
+#define KISSMAXBLOCK        512
 
 // KISS over TCP Slave now allows multiple connections
 // so need a struct to keep track of them
@@ -9,7 +9,7 @@ typedef struct _KISSTCPSess
 {
 	struct _KISSTCPSesssion * Next;
 	SOCKET Socket;
-	UCHAR RXBuffer[MAXBLOCK];
+	UCHAR RXBuffer[KISSMAXBLOCK];
 	int RXLen;
 
 	time_t Timeout;
@@ -30,7 +30,7 @@ typedef struct tagASYINFO
 	struct sockaddr_in destaddr;
 	struct PORTCONTROL * Portvector;
 	UCHAR	RXMSG[512];				// Msg being built
-	UCHAR	RXBUFFER[MAXBLOCK];		// Raw chars from Comms
+	UCHAR	RXBUFFER[KISSMAXBLOCK];	// Raw chars from Comms
 	int		RXBCOUNT;				// chars in RXBUFFER
 	UCHAR * RXBPTR;					// get pointer for RXBUFFER (put ptr is RXBCOUNT) 
 	UCHAR * RXMPTR;					// put pointer for RXMSG
@@ -45,8 +45,7 @@ typedef struct tagASYINFO
 
 } ASYINFO, *NPASYINFO ;
 
-NPASYINFO KISSInfo[MAXBPQPORTS] = {0};
-
+extern NPASYINFO KISSInfo[MAXBPQPORTS];
 
 #define _fmemset   memset
 #define _fmemmove  memmove
diff --git a/rigcontrol.h b/rigcontrol.h
index bd3c942..e762ea4 100644
--- a/rigcontrol.h
+++ b/rigcontrol.h
@@ -7,7 +7,6 @@
 
 #define IDI_ICON2 2
 
-#define MAXBLOCK 4096
 
 struct TimeScan
 {