Compare commits

...

No commits in common. "pristine-tar" and "hibbian/latest" have entirely different histories.

292 changed files with 335982 additions and 23 deletions

139
.rej Normal file
View File

@ -0,0 +1,139 @@
--- APRSCode.c
+++ APRSCode.c
@@ -3674,7 +3674,7 @@
if (ptr1)
*ptr1 = 0;
-// Debugprintf("Duplicate Message supressed %s", Msg);
+// Debugprintf("Duplicate Message suppressed %s", Msg);
return TRUE; // Duplicate
}
}
--- BPQChat.rc
+++ BPQChat.rc
@@ -162,7 +162,7 @@
WS_VSCROLL
DEFPUSHBUTTON "Save Welcome Message",SAVEWELCOME,140,296,91,14,
BS_CENTER | BS_VCENTER
- LTEXT " If the node is not directly connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands seperared by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT",
+ LTEXT " If the node is not directly connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands separated by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT",
IDC_STATIC,9,52,355,24
END
--- BPQMail.rc
+++ BPQMail.rc
@@ -1045,7 +1045,7 @@
CONTROL "Delete Log and Message Files to Recycle Bin",
IDC_DELETETORECYCLE,"Button",BS_AUTOCHECKBOX |
BS_LEFTTEXT | BS_MULTILINE | WS_TABSTOP,5,142,115,20
- CONTROL "Supress Mailing of Housekeeping Results",
+ CONTROL "Suppress Mailing of Housekeeping Results",
IDC_MAINTNOMAIL,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT |
BS_MULTILINE | WS_TABSTOP,5,182,115,20
CONTROL "Generate Traffic Report",IDC_MAINTTRAFFIC,"Button",
--- HanksRT.c
+++ HanksRT.c
@@ -1186,7 +1186,7 @@
// Duplicate, so discard, but save time
DupInfo[i].DupTime = Now;
- Logprintf(LOG_CHAT, circuit, '?', "Duplicate Message From %s %s supressed", Call, Msg);
+ Logprintf(LOG_CHAT, circuit, '?', "Duplicate Message From %s %s suppressed", Call, Msg);
return TRUE; // Duplicate
}
--- RigControl.c
+++ RigControl.c
@@ -8385,7 +8385,7 @@
switch (Msg[0])
{
- case 'f': // Get Freqency
+ case 'f': // Get Frequency
HLGetFreq(Sock, RIG, sep);
return 0;
--- UZ7HODrv.c
+++ UZ7HODrv.c
@@ -374,7 +374,7 @@
{
// Read Freq
- buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Modem Freqency %d\r", AGW->CenterFreq);
+ buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Modem Frequency %d\r", AGW->CenterFreq);
return 1;
}
@@ -382,7 +382,7 @@
if (AGW->CenterFreq == 0)
{
- buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Invalid Modem Freqency\r");
+ buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Invalid Modem Frequency\r");
return 1;
}
--- WinRPRHelper.c
+++ WinRPRHelper.c
@@ -111,7 +111,7 @@
if (argc < 3)
{
- printf ("Missing paramters - you need COM port and IP Address and rigctl port of BPQ, eg \r\n"
+ printf ("Missing parameters - you need COM port and IP Address and rigctl port of BPQ, eg \r\n"
" WinRPRHelper com10 192.168.1.64:4532\r\n\r\n"
"Press any key to exit\r\n");
--- config.c
+++ config.c
@@ -649,7 +649,7 @@
if (LOCATOR[0] == 0 && LocSpecified == 0 && RFOnly == 0)
{
Consoleprintf("");
- Consoleprintf("Please enter a LOCATOR statment in your BPQ32.cfg");
+ Consoleprintf("Please enter a LOCATOR statement in your BPQ32.cfg");
Consoleprintf("If you really don't want to be on the Node Map you can enter LOCATOR=NONE");
Consoleprintf("");
--- kiss.c
+++ kiss.c
@@ -1485,7 +1485,7 @@
}
}
else
- Debugprintf("Polled KISS - response from wrong address - Polled %d Reponse %d",
+ Debugprintf("Polled KISS - response from wrong address - Polled %d Response %d",
KISS->POLLPOINTER->OURCTRL, (Port->RXMSG[0] & 0xf0));
goto SeeifMore; // SEE IF ANYTHING ELSE
--- templatedefs.c
+++ templatedefs.c
@@ -1165,7 +1165,7 @@
"Send Non-delivery Notifications<br>\r\n"
"for P and T messages <input %sname=\"SendND\" value=\"SendND\" type=\"checkbox\" /><br>\r\n"
" <br />\r\n"
- "Supress Mailing of<br>\r\n"
+ "Suppress Mailing of<br>\r\n"
"Housekeeping Result <input %sname=\"NoMail\" value=\"Yes\" type=\"checkbox\"><br><br>\r\n"
"Generate Traffic Report<input %sname=\"GenTraffic\" value=\"Yes\" type=\"checkbox\"><br><br>\r\n"
"<div style=\"text-align: center;\"><input class='btn' name=RunNow value=\"Run Housekeeping\" type=submit class='btn'></div>\r\n"
@@ -1454,7 +1454,7 @@
"<div style=\"text-align: left; width: 680px; margin: auto;\">The Nodes to link to box defines which other Chat Nodes should be connected to, or from which "
"connections may be accepted. The format is ALIAS:CALL, eg BPQCHT:G8BPQ-4. If the node is not directly "
"connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands "
- "seperared by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT"
+ "separated by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT"
"<br><br>The Callsign of the Chat Node is not defined here - it is obtained from the bpq32.cfg APPLICATION line corresponding to the Chat Appl Number.<br>\r\n"
"<br></div>\n"
--- WebMail.c
+++ WebMail.c
@@ -2020,7 +2020,7 @@
"document.getElementById('myform').action = '/WebMail/QuoteOriginal' + '?%s';"
" document.getElementById('myform').submit();}</script>"
"<input type=button class='btn' onclick='myfunc()' "
- "value='Include Orignal Msg'>";
+ "value='Include Original Msg'>";
char Temp[1024];
char ReplyAddr[128];

2129
6pack.c Normal file

File diff suppressed because it is too large Load Diff

1628
AEAPactor.c Normal file

File diff suppressed because it is too large Load Diff

750
AFXRES.H Normal file
View File

@ -0,0 +1,750 @@
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1995 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#ifndef __AFXRES_H__
#define __AFXRES_H__
#ifdef REZ // Mac resource compiler (mrc) defines REZ
#define RC_INVOKED
#endif
#ifdef RC_INVOKED
#ifndef _INC_WINDOWS
#define _INC_WINDOWS
#include "..\include\winres.h" // extract from windows header
#endif
#endif
#ifdef _AFX_MINREBUILD
#pragma component(minrebuild, off)
#endif
#ifdef APSTUDIO_INVOKED
#define APSTUDIO_HIDDEN_SYMBOLS
#endif
/////////////////////////////////////////////////////////////////////////////
// MFC resource types (see Technical note TN024 for implementation details)
#ifndef RC_INVOKED
#define RT_DLGINIT MAKEINTRESOURCE(240)
#define RT_TOOLBAR MAKEINTRESOURCE(241)
#endif
/////////////////////////////////////////////////////////////////////////////
#ifdef APSTUDIO_INVOKED
#undef APSTUDIO_HIDDEN_SYMBOLS
#endif
/////////////////////////////////////////////////////////////////////////////
// General style bits etc
// Tab Control styles
#ifndef TCS_MULTILINE // new in later versions of Win32
#define TCS_MULTILINE 0x0200
#endif
// ControlBar styles
#define CBRS_ALIGN_LEFT 0x1000L
#define CBRS_ALIGN_TOP 0x2000L
#define CBRS_ALIGN_RIGHT 0x4000L
#define CBRS_ALIGN_BOTTOM 0x8000L
#define CBRS_ALIGN_ANY 0xF000L
#define CBRS_BORDER_LEFT 0x0100L
#define CBRS_BORDER_TOP 0x0200L
#define CBRS_BORDER_RIGHT 0x0400L
#define CBRS_BORDER_BOTTOM 0x0800L
#define CBRS_BORDER_ANY 0x0F00L
#define CBRS_TOOLTIPS 0x0010L
#define CBRS_FLYBY 0x0020L
#define CBRS_FLOAT_MULTI 0x0040L
#define CBRS_BORDER_3D 0x0080L
#define CBRS_HIDE_INPLACE 0x0008L
#define CBRS_SIZE_DYNAMIC 0x0004L
#define CBRS_SIZE_FIXED 0x0002L
#define CBRS_FLOATING 0x0001L
#define CBRS_ORIENT_HORZ (CBRS_ALIGN_TOP|CBRS_ALIGN_BOTTOM)
#define CBRS_ORIENT_VERT (CBRS_ALIGN_LEFT|CBRS_ALIGN_RIGHT)
#define CBRS_ORIENT_ANY (CBRS_ORIENT_HORZ|CBRS_ORIENT_VERT)
#define CBRS_ALL 0xFFFFL
// the CBRS_ style is made up of an alignment style and a draw border style
// the alignment styles are mutually exclusive
// the draw border styles may be combined
#define CBRS_NOALIGN 0x00000000L
#define CBRS_LEFT (CBRS_ALIGN_LEFT|CBRS_BORDER_RIGHT)
#define CBRS_TOP (CBRS_ALIGN_TOP|CBRS_BORDER_BOTTOM)
#define CBRS_RIGHT (CBRS_ALIGN_RIGHT|CBRS_BORDER_LEFT)
#define CBRS_BOTTOM (CBRS_ALIGN_BOTTOM|CBRS_BORDER_TOP)
/////////////////////////////////////////////////////////////////////////////
// Standard window components
// Mode indicators in status bar - these are routed like commands
#define ID_INDICATOR_EXT 0xE700 // extended selection indicator
#define ID_INDICATOR_CAPS 0xE701 // cap lock indicator
#define ID_INDICATOR_NUM 0xE702 // num lock indicator
#define ID_INDICATOR_SCRL 0xE703 // scroll lock indicator
#define ID_INDICATOR_OVR 0xE704 // overtype mode indicator
#define ID_INDICATOR_REC 0xE705 // record mode indicator
#define ID_INDICATOR_KANA 0xE706 // kana lock indicator
#define ID_SEPARATOR 0 // special separator value
#ifndef RC_INVOKED // code only
// Standard control bars (IDW = window ID)
#define AFX_IDW_CONTROLBAR_FIRST 0xE800
#define AFX_IDW_CONTROLBAR_LAST 0xE8FF
#define AFX_IDW_TOOLBAR 0xE800 // main Toolbar for window
#define AFX_IDW_STATUS_BAR 0xE801 // Status bar window
#define AFX_IDW_PREVIEW_BAR 0xE802 // PrintPreview Dialog Bar
#define AFX_IDW_RESIZE_BAR 0xE803 // OLE in-place resize bar
// Note: If your application supports docking toolbars, you should
// not use the following IDs for your own toolbars. The IDs chosen
// are at the top of the first 32 such that the bars will be hidden
// while in print preview mode, and are not likely to conflict with
// IDs your application may have used succesfully in the past.
#define AFX_IDW_DOCKBAR_TOP 0xE81B
#define AFX_IDW_DOCKBAR_LEFT 0xE81C
#define AFX_IDW_DOCKBAR_RIGHT 0xE81D
#define AFX_IDW_DOCKBAR_BOTTOM 0xE81E
#define AFX_IDW_DOCKBAR_FLOAT 0xE81F
// Macro for mapping standard control bars to bitmask (limit of 32)
#define AFX_CONTROLBAR_MASK(nIDC) (1L << (nIDC - AFX_IDW_CONTROLBAR_FIRST))
// parts of Main Frame
#define AFX_IDW_PANE_FIRST 0xE900 // first pane (256 max)
#define AFX_IDW_PANE_LAST 0xE9ff
#define AFX_IDW_HSCROLL_FIRST 0xEA00 // first Horz scrollbar (16 max)
#define AFX_IDW_VSCROLL_FIRST 0xEA10 // first Vert scrollbar (16 max)
#define AFX_IDW_SIZE_BOX 0xEA20 // size box for splitters
#define AFX_IDW_PANE_SAVE 0xEA21 // to shift AFX_IDW_PANE_FIRST
#endif //!RC_INVOKED
#ifndef APSTUDIO_INVOKED
// common style for form views
#define AFX_WS_DEFAULT_VIEW (WS_CHILD | WS_VISIBLE | WS_BORDER)
#endif //!APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
// Standard app configurable strings
// for application title (defaults to EXE name or name in constructor)
#define AFX_IDS_APP_TITLE 0xE000
// idle message bar line
#define AFX_IDS_IDLEMESSAGE 0xE001
// message bar line when in shift-F1 help mode
#define AFX_IDS_HELPMODEMESSAGE 0xE002
// document title when editing OLE embedding
#define AFX_IDS_APP_TITLE_EMBEDDING 0xE003
// company name
#define AFX_IDS_COMPANY_NAME 0xE004
// object name when server is inplace
#define AFX_IDS_OBJ_TITLE_INPLACE 0xE005
/////////////////////////////////////////////////////////////////////////////
// Standard Commands
// File commands
#define ID_FILE_NEW 0xE100
#define ID_FILE_OPEN 0xE101
#define ID_FILE_CLOSE 0xE102
#define ID_FILE_SAVE 0xE103
#define ID_FILE_SAVE_AS 0xE104
#define ID_FILE_PAGE_SETUP 0xE105
#define ID_FILE_PRINT_SETUP 0xE106
#define ID_FILE_PRINT 0xE107
#define ID_FILE_PRINT_DIRECT 0xE108
#define ID_FILE_PRINT_PREVIEW 0xE109
#define ID_FILE_UPDATE 0xE10A
#define ID_FILE_SAVE_COPY_AS 0xE10B
#define ID_FILE_SEND_MAIL 0xE10C
#define ID_FILE_MRU_FIRST 0xE110
#define ID_FILE_MRU_FILE1 0xE110 // range - 16 max
#define ID_FILE_MRU_FILE2 0xE111
#define ID_FILE_MRU_FILE3 0xE112
#define ID_FILE_MRU_FILE4 0xE113
#define ID_FILE_MRU_FILE5 0xE114
#define ID_FILE_MRU_FILE6 0xE115
#define ID_FILE_MRU_FILE7 0xE116
#define ID_FILE_MRU_FILE8 0xE117
#define ID_FILE_MRU_FILE9 0xE118
#define ID_FILE_MRU_FILE10 0xE119
#define ID_FILE_MRU_FILE11 0xE11A
#define ID_FILE_MRU_FILE12 0xE11B
#define ID_FILE_MRU_FILE13 0xE11C
#define ID_FILE_MRU_FILE14 0xE11D
#define ID_FILE_MRU_FILE15 0xE11E
#define ID_FILE_MRU_FILE16 0xE11F
#define ID_FILE_MRU_LAST 0xE11F
// Edit commands
#define ID_EDIT_CLEAR 0xE120
#define ID_EDIT_CLEAR_ALL 0xE121
#define ID_EDIT_COPY 0xE122
#define ID_EDIT_CUT 0xE123
#define ID_EDIT_FIND 0xE124
#define ID_EDIT_PASTE 0xE125
#define ID_EDIT_PASTE_LINK 0xE126
#define ID_EDIT_PASTE_SPECIAL 0xE127
#define ID_EDIT_REPEAT 0xE128
#define ID_EDIT_REPLACE 0xE129
#define ID_EDIT_SELECT_ALL 0xE12A
#define ID_EDIT_UNDO 0xE12B
#define ID_EDIT_REDO 0xE12C
// Window commands
#define ID_WINDOW_NEW 0xE130
#define ID_WINDOW_ARRANGE 0xE131
#define ID_WINDOW_CASCADE 0xE132
#define ID_WINDOW_TILE_HORZ 0xE133
#define ID_WINDOW_TILE_VERT 0xE134
#define ID_WINDOW_SPLIT 0xE135
#ifndef RC_INVOKED // code only
#define AFX_IDM_WINDOW_FIRST 0xE130
#define AFX_IDM_WINDOW_LAST 0xE13F
#define AFX_IDM_FIRST_MDICHILD 0xFF00 // window list starts here
#endif //!RC_INVOKED
// Help and App commands
#define ID_APP_ABOUT 0xE140
#define ID_APP_EXIT 0xE141
#define ID_HELP_INDEX 0xE142
#define ID_HELP_FINDER 0xE143
#define ID_HELP_USING 0xE144
#define ID_CONTEXT_HELP 0xE145 // shift-F1
// special commands for processing help
#define ID_HELP 0xE146 // first attempt for F1
#define ID_DEFAULT_HELP 0xE147 // last attempt
// Misc
#define ID_NEXT_PANE 0xE150
#define ID_PREV_PANE 0xE151
// Format
#define ID_FORMAT_FONT 0xE160
// OLE commands
#define ID_OLE_INSERT_NEW 0xE200
#define ID_OLE_EDIT_LINKS 0xE201
#define ID_OLE_EDIT_CONVERT 0xE202
#define ID_OLE_EDIT_CHANGE_ICON 0xE203
#define ID_OLE_EDIT_PROPERTIES 0xE204
#define ID_OLE_VERB_FIRST 0xE210 // range - 16 max
#ifndef RC_INVOKED // code only
#define ID_OLE_VERB_LAST 0xE21F
#endif //!RC_INVOKED
// for print preview dialog bar
#define AFX_ID_PREVIEW_CLOSE 0xE300
#define AFX_ID_PREVIEW_NUMPAGE 0xE301 // One/Two Page button
#define AFX_ID_PREVIEW_NEXT 0xE302
#define AFX_ID_PREVIEW_PREV 0xE303
#define AFX_ID_PREVIEW_PRINT 0xE304
#define AFX_ID_PREVIEW_ZOOMIN 0xE305
#define AFX_ID_PREVIEW_ZOOMOUT 0xE306
// View commands (same number used as IDW used for control bar)
#define ID_VIEW_TOOLBAR 0xE800
#define ID_VIEW_STATUS_BAR 0xE801
// -> E8FF reserved for other control bar commands
// RecordForm commands
#define ID_RECORD_FIRST 0xE900
#define ID_RECORD_LAST 0xE901
#define ID_RECORD_NEXT 0xE902
#define ID_RECORD_PREV 0xE903
/////////////////////////////////////////////////////////////////////////////
// Standard control IDs
#ifdef IDC_STATIC
#undef IDC_STATIC
#endif
#define IDC_STATIC (-1) // all static controls
/////////////////////////////////////////////////////////////////////////////
// Standard string error/warnings
#ifndef RC_INVOKED // code only
#define AFX_IDS_SCFIRST 0xEF00
#endif //!RC_INVOKED
#define AFX_IDS_SCSIZE 0xEF00
#define AFX_IDS_SCMOVE 0xEF01
#define AFX_IDS_SCMINIMIZE 0xEF02
#define AFX_IDS_SCMAXIMIZE 0xEF03
#define AFX_IDS_SCNEXTWINDOW 0xEF04
#define AFX_IDS_SCPREVWINDOW 0xEF05
#define AFX_IDS_SCCLOSE 0xEF06
#define AFX_IDS_SCRESTORE 0xEF12
#define AFX_IDS_SCTASKLIST 0xEF13
#define AFX_IDS_MDICHILD 0xEF1F
#define AFX_IDS_DESKACCESSORY 0xEFDA
// General strings
#define AFX_IDS_OPENFILE 0xF000
#define AFX_IDS_SAVEFILE 0xF001
#define AFX_IDS_ALLFILTER 0xF002
#define AFX_IDS_UNTITLED 0xF003
#define AFX_IDS_SAVEFILECOPY 0xF004
#define AFX_IDS_PREVIEW_CLOSE 0xF005
#define AFX_IDS_UNNAMED_FILE 0xF006
#ifdef _MAC
#define AFX_IDS_ABOUT 0xF010
#endif
#define AFX_IDS_HIDE 0xF011
// MFC Standard Exception Error messages
#define AFX_IDP_NO_ERROR_AVAILABLE 0xF020
#define AFX_IDS_NOT_SUPPORTED_EXCEPTION 0xF021
#define AFX_IDS_RESOURCE_EXCEPTION 0xF022
#define AFX_IDS_MEMORY_EXCEPTION 0xF023
#define AFX_IDS_USER_EXCEPTION 0xF024
// Printing and print preview strings
#define AFX_IDS_PRINTONPORT 0xF040
#define AFX_IDS_ONEPAGE 0xF041
#define AFX_IDS_TWOPAGE 0xF042
#define AFX_IDS_PRINTPAGENUM 0xF043
#define AFX_IDS_PREVIEWPAGEDESC 0xF044
#define AFX_IDS_PRINTDEFAULTEXT 0xF045
#define AFX_IDS_PRINTDEFAULT 0xF046
#define AFX_IDS_PRINTFILTER 0xF047
#define AFX_IDS_PRINTCAPTION 0xF048
#define AFX_IDS_PRINTTOFILE 0xF049
// OLE strings
#define AFX_IDS_OBJECT_MENUITEM 0xF080
#define AFX_IDS_EDIT_VERB 0xF081
#define AFX_IDS_ACTIVATE_VERB 0xF082
#define AFX_IDS_CHANGE_LINK 0xF083
#define AFX_IDS_AUTO 0xF084
#define AFX_IDS_MANUAL 0xF085
#define AFX_IDS_FROZEN 0xF086
#define AFX_IDS_ALL_FILES 0xF087
// dynamically changing menu items
#define AFX_IDS_SAVE_MENU 0xF088
#define AFX_IDS_UPDATE_MENU 0xF089
#define AFX_IDS_SAVE_AS_MENU 0xF08A
#define AFX_IDS_SAVE_COPY_AS_MENU 0xF08B
#define AFX_IDS_EXIT_MENU 0xF08C
#define AFX_IDS_UPDATING_ITEMS 0xF08D
// COlePasteSpecialDialog defines
#define AFX_IDS_METAFILE_FORMAT 0xF08E
#define AFX_IDS_DIB_FORMAT 0xF08F
#define AFX_IDS_BITMAP_FORMAT 0xF090
#define AFX_IDS_LINKSOURCE_FORMAT 0xF091
#define AFX_IDS_EMBED_FORMAT 0xF092
// other OLE utility strings
#define AFX_IDS_PASTELINKEDTYPE 0xF094
#define AFX_IDS_UNKNOWNTYPE 0xF095
#define AFX_IDS_RTF_FORMAT 0xF096
#define AFX_IDS_TEXT_FORMAT 0xF097
// OLE datatype format error strings
#define AFX_IDS_INVALID_CURRENCY 0xF098
#define AFX_IDS_INVALID_DATETIME 0xF099
#define AFX_IDS_INVALID_DATETIMESPAN 0xF09A
// General error / prompt strings
#define AFX_IDP_INVALID_FILENAME 0xF100
#define AFX_IDP_FAILED_TO_OPEN_DOC 0xF101
#define AFX_IDP_FAILED_TO_SAVE_DOC 0xF102
#define AFX_IDP_ASK_TO_SAVE 0xF103
#define AFX_IDP_FAILED_TO_CREATE_DOC 0xF104
#define AFX_IDP_FILE_TOO_LARGE 0xF105
#define AFX_IDP_FAILED_TO_START_PRINT 0xF106
#define AFX_IDP_FAILED_TO_LAUNCH_HELP 0xF107
#define AFX_IDP_INTERNAL_FAILURE 0xF108 // general failure
#define AFX_IDP_COMMAND_FAILURE 0xF109 // command failure
#define AFX_IDP_FAILED_MEMORY_ALLOC 0xF10A
// DDV parse errors
#define AFX_IDP_PARSE_INT 0xF110
#define AFX_IDP_PARSE_REAL 0xF111
#define AFX_IDP_PARSE_INT_RANGE 0xF112
#define AFX_IDP_PARSE_REAL_RANGE 0xF113
#define AFX_IDP_PARSE_STRING_SIZE 0xF114
#define AFX_IDP_PARSE_RADIO_BUTTON 0xF115
#define AFX_IDP_PARSE_BYTE 0xF116
#define AFX_IDP_PARSE_UINT 0xF117
#define AFX_IDP_PARSE_DATETIME 0xF118
#define AFX_IDP_PARSE_CURRENCY 0xF119
// CFile/CArchive error strings for user failure
#define AFX_IDP_FAILED_INVALID_FORMAT 0xF120
#define AFX_IDP_FAILED_INVALID_PATH 0xF121
#define AFX_IDP_FAILED_DISK_FULL 0xF122
#define AFX_IDP_FAILED_ACCESS_READ 0xF123
#define AFX_IDP_FAILED_ACCESS_WRITE 0xF124
#define AFX_IDP_FAILED_IO_ERROR_READ 0xF125
#define AFX_IDP_FAILED_IO_ERROR_WRITE 0xF126
// OLE errors / prompt strings
#define AFX_IDP_STATIC_OBJECT 0xF180
#define AFX_IDP_FAILED_TO_CONNECT 0xF181
#define AFX_IDP_SERVER_BUSY 0xF182
#define AFX_IDP_BAD_VERB 0xF183
#define AFX_IDP_FAILED_TO_NOTIFY 0xF185
#define AFX_IDP_FAILED_TO_LAUNCH 0xF186
#define AFX_IDP_ASK_TO_UPDATE 0xF187
#define AFX_IDP_FAILED_TO_UPDATE 0xF188
#define AFX_IDP_FAILED_TO_REGISTER 0xF189
#define AFX_IDP_FAILED_TO_AUTO_REGISTER 0xF18A
#define AFX_IDP_FAILED_TO_CONVERT 0xF18B
#define AFX_IDP_GET_NOT_SUPPORTED 0xF18C
#define AFX_IDP_SET_NOT_SUPPORTED 0xF18D
#define AFX_IDP_ASK_TO_DISCARD 0xF18E
#define AFX_IDP_FAILED_TO_CREATE 0xF18F
// MAPI errors / prompt strings
#define AFX_IDP_FAILED_MAPI_LOAD 0xF190
#define AFX_IDP_INVALID_MAPI_DLL 0xF191
#define AFX_IDP_FAILED_MAPI_SEND 0xF192
#define AFX_IDP_FILE_NONE 0xF1A0
#define AFX_IDP_FILE_GENERIC 0xF1A1
#define AFX_IDP_FILE_NOT_FOUND 0xF1A2
#define AFX_IDP_FILE_BAD_PATH 0xF1A3
#define AFX_IDP_FILE_TOO_MANY_OPEN 0xF1A4
#define AFX_IDP_FILE_ACCESS_DENIED 0xF1A5
#define AFX_IDP_FILE_INVALID_FILE 0xF1A6
#define AFX_IDP_FILE_REMOVE_CURRENT 0xF1A7
#define AFX_IDP_FILE_DIR_FULL 0xF1A8
#define AFX_IDP_FILE_BAD_SEEK 0xF1A9
#define AFX_IDP_FILE_HARD_IO 0xF1AA
#define AFX_IDP_FILE_SHARING 0xF1AB
#define AFX_IDP_FILE_LOCKING 0xF1AC
#define AFX_IDP_FILE_DISKFULL 0xF1AD
#define AFX_IDP_FILE_EOF 0xF1AE
#define AFX_IDP_ARCH_NONE 0xF1B0
#define AFX_IDP_ARCH_GENERIC 0xF1B1
#define AFX_IDP_ARCH_READONLY 0xF1B2
#define AFX_IDP_ARCH_ENDOFFILE 0xF1B3
#define AFX_IDP_ARCH_WRITEONLY 0xF1B4
#define AFX_IDP_ARCH_BADINDEX 0xF1B5
#define AFX_IDP_ARCH_BADCLASS 0xF1B6
#define AFX_IDP_ARCH_BADSCHEMA 0xF1B7
#define AFX_IDS_OCC_SCALEUNITS_PIXELS 0xF1C0
// 0xf200-0xf20f reserved
// font names and point sizes
#define AFX_IDS_STATUS_FONT 0xF230
#define AFX_IDS_TOOLTIP_FONT 0xF231
#define AFX_IDS_UNICODE_FONT 0xF232
#define AFX_IDS_MINI_FONT 0xF233
// ODBC Database errors / prompt strings
#ifndef RC_INVOKED // code only
#define AFX_IDP_SQL_FIRST 0xF280
#endif //!RC_INVOKED
#define AFX_IDP_SQL_CONNECT_FAIL 0xF281
#define AFX_IDP_SQL_RECORDSET_FORWARD_ONLY 0xF282
#define AFX_IDP_SQL_EMPTY_COLUMN_LIST 0xF283
#define AFX_IDP_SQL_FIELD_SCHEMA_MISMATCH 0xF284
#define AFX_IDP_SQL_ILLEGAL_MODE 0xF285
#define AFX_IDP_SQL_MULTIPLE_ROWS_AFFECTED 0xF286
#define AFX_IDP_SQL_NO_CURRENT_RECORD 0xF287
#define AFX_IDP_SQL_NO_ROWS_AFFECTED 0xF288
#define AFX_IDP_SQL_RECORDSET_READONLY 0xF289
#define AFX_IDP_SQL_SQL_NO_TOTAL 0xF28A
#define AFX_IDP_SQL_ODBC_LOAD_FAILED 0xF28B
#define AFX_IDP_SQL_DYNASET_NOT_SUPPORTED 0xF28C
#define AFX_IDP_SQL_SNAPSHOT_NOT_SUPPORTED 0xF28D
#define AFX_IDP_SQL_API_CONFORMANCE 0xF28E
#define AFX_IDP_SQL_SQL_CONFORMANCE 0xF28F
#define AFX_IDP_SQL_NO_DATA_FOUND 0xF290
#define AFX_IDP_SQL_ROW_UPDATE_NOT_SUPPORTED 0xF291
#define AFX_IDP_SQL_ODBC_V2_REQUIRED 0xF292
#define AFX_IDP_SQL_NO_POSITIONED_UPDATES 0xF293
#define AFX_IDP_SQL_LOCK_MODE_NOT_SUPPORTED 0xF294
#define AFX_IDP_SQL_DATA_TRUNCATED 0xF295
#define AFX_IDP_SQL_ROW_FETCH 0xF296
#define AFX_IDP_SQL_INCORRECT_ODBC 0xF297
#define AFX_IDP_SQL_UPDATE_DELETE_FAILED 0xF298
#define AFX_IDP_SQL_DYNAMIC_CURSOR_NOT_SUPPORTED 0xF299
// DAO Database errors / prompt strings
#ifndef RC_INVOKED // code only
#define AFX_IDP_DAO_FIRST 0xF2A0
#endif //!RC_INVOKED
#define AFX_IDP_DAO_ENGINE_INITIALIZATION 0xF2A0
#define AFX_IDP_DAO_DFX_BIND 0xF2A1
#define AFX_IDP_DAO_OBJECT_NOT_OPEN 0xF2A2
// ICDAORecordset::GetRows Errors
// These are not placed in DAO Errors collection
// and must be handled directly by MFC.
#define AFX_IDP_DAO_ROWTOOSHORT 0xF2A3
#define AFX_IDP_DAO_BADBINDINFO 0xF2A4
#define AFX_IDP_DAO_COLUMNUNAVAILABLE 0xF2A5
/////////////////////////////////////////////////////////////////////////////
// AFX implementation - control IDs (AFX_IDC)
// Parts of dialogs
#define AFX_IDC_LISTBOX 100
#define AFX_IDC_CHANGE 101
// for print dialog
#define AFX_IDC_PRINT_DOCNAME 201
#define AFX_IDC_PRINT_PRINTERNAME 202
#define AFX_IDC_PRINT_PORTNAME 203
#define AFX_IDC_PRINT_PAGENUM 204
// Property Sheet control id's (determined with Spy++)
#define ID_APPLY_NOW 0x3021
#define ID_WIZBACK 0x3023
#define ID_WIZNEXT 0x3024
#define ID_WIZFINISH 0x3025
#define AFX_IDC_TAB_CONTROL 0x3020
/////////////////////////////////////////////////////////////////////////////
// IDRs for standard components
#ifndef RC_INVOKED // code only
// These are really COMMDLG dialogs, so there usually isn't a resource
// for them, but these IDs are used as help IDs.
#define AFX_IDD_FILEOPEN 28676
#define AFX_IDD_FILESAVE 28677
#define AFX_IDD_FONT 28678
#define AFX_IDD_COLOR 28679
#define AFX_IDD_PRINT 28680
#define AFX_IDD_PRINTSETUP 28681
#define AFX_IDD_FIND 28682
#define AFX_IDD_REPLACE 28683
#endif //!RC_INVOKED
// Standard dialogs app should leave alone (0x7801->)
#define AFX_IDD_NEWTYPEDLG 30721
#define AFX_IDD_PRINTDLG 30722
#define AFX_IDD_PREVIEW_TOOLBAR 30723
#ifdef _MAC
#define AFX_IDD_PREVIEW_SHORTTOOLBAR 30731
#endif
// Dialogs defined for OLE2UI library
#define AFX_IDD_INSERTOBJECT 30724
#define AFX_IDD_CHANGEICON 30725
#define AFX_IDD_CONVERT 30726
#define AFX_IDD_PASTESPECIAL 30727
#define AFX_IDD_EDITLINKS 30728
#define AFX_IDD_FILEBROWSE 30729
#define AFX_IDD_BUSY 30730
#define AFX_IDD_OBJECTPROPERTIES 30732
#define AFX_IDD_CHANGESOURCE 30733
// Standard cursors (0x7901->)
// AFX_IDC = Cursor resources
#define AFX_IDC_CONTEXTHELP 30977 // context sensitive help
#define AFX_IDC_MAGNIFY 30978 // print preview zoom
#define AFX_IDC_SMALLARROWS 30979 // splitter
#define AFX_IDC_HSPLITBAR 30980 // splitter
#define AFX_IDC_VSPLITBAR 30981 // splitter
#define AFX_IDC_NODROPCRSR 30982 // No Drop Cursor
#define AFX_IDC_TRACKNWSE 30983 // tracker
#define AFX_IDC_TRACKNESW 30984 // tracker
#define AFX_IDC_TRACKNS 30985 // tracker
#define AFX_IDC_TRACKWE 30986 // tracker
#define AFX_IDC_TRACK4WAY 30987 // tracker
#define AFX_IDC_MOVE4WAY 30988 // resize bar (server only)
// Mini frame window bitmap ID
#define AFX_IDB_MINIFRAME_MENU 30994
// CheckListBox checks bitmap ID
#define AFX_IDB_CHECKLISTBOX_NT 30995
#define AFX_IDB_CHECKLISTBOX_95 30996
// AFX standard accelerator resources
#define AFX_IDR_PREVIEW_ACCEL 30997
// AFX standard ICON IDs (for MFC V1 apps) (0x7A01->)
#define AFX_IDI_STD_MDIFRAME 31233
#define AFX_IDI_STD_FRAME 31234
/////////////////////////////////////////////////////////////////////////////
// AFX OLE control implementation - control IDs (AFX_IDC)
// Font property page
#define AFX_IDC_FONTPROP 1000
#define AFX_IDC_FONTNAMES 1001
#define AFX_IDC_FONTSTYLES 1002
#define AFX_IDC_FONTSIZES 1003
#define AFX_IDC_STRIKEOUT 1004
#define AFX_IDC_UNDERLINE 1005
#define AFX_IDC_SAMPLEBOX 1006
// Color property page
#define AFX_IDC_COLOR_BLACK 1100
#define AFX_IDC_COLOR_WHITE 1101
#define AFX_IDC_COLOR_RED 1102
#define AFX_IDC_COLOR_GREEN 1103
#define AFX_IDC_COLOR_BLUE 1104
#define AFX_IDC_COLOR_YELLOW 1105
#define AFX_IDC_COLOR_MAGENTA 1106
#define AFX_IDC_COLOR_CYAN 1107
#define AFX_IDC_COLOR_GRAY 1108
#define AFX_IDC_COLOR_LIGHTGRAY 1109
#define AFX_IDC_COLOR_DARKRED 1110
#define AFX_IDC_COLOR_DARKGREEN 1111
#define AFX_IDC_COLOR_DARKBLUE 1112
#define AFX_IDC_COLOR_LIGHTBROWN 1113
#define AFX_IDC_COLOR_DARKMAGENTA 1114
#define AFX_IDC_COLOR_DARKCYAN 1115
#define AFX_IDC_COLORPROP 1116
#define AFX_IDC_SYSTEMCOLORS 1117
// Picture porperty page
#define AFX_IDC_PROPNAME 1201
#define AFX_IDC_PICTURE 1202
#define AFX_IDC_BROWSE 1203
#define AFX_IDC_CLEAR 1204
/////////////////////////////////////////////////////////////////////////////
// IDRs for OLE control standard components
// Standard propery page dialogs app should leave alone (0x7E01->)
#define AFX_IDD_PROPPAGE_COLOR 32257
#define AFX_IDD_PROPPAGE_FONT 32258
#define AFX_IDD_PROPPAGE_PICTURE 32259
#define AFX_IDB_TRUETYPE 32384
/////////////////////////////////////////////////////////////////////////////
// Standard OLE control strings
// OLE Control page strings
#define AFX_IDS_PROPPAGE_UNKNOWN 0xFE01
#define AFX_IDS_COLOR_DESKTOP 0xFE04
#define AFX_IDS_COLOR_APPWORKSPACE 0xFE05
#define AFX_IDS_COLOR_WNDBACKGND 0xFE06
#define AFX_IDS_COLOR_WNDTEXT 0xFE07
#define AFX_IDS_COLOR_MENUBAR 0xFE08
#define AFX_IDS_COLOR_MENUTEXT 0xFE09
#define AFX_IDS_COLOR_ACTIVEBAR 0xFE0A
#define AFX_IDS_COLOR_INACTIVEBAR 0xFE0B
#define AFX_IDS_COLOR_ACTIVETEXT 0xFE0C
#define AFX_IDS_COLOR_INACTIVETEXT 0xFE0D
#define AFX_IDS_COLOR_ACTIVEBORDER 0xFE0E
#define AFX_IDS_COLOR_INACTIVEBORDER 0xFE0F
#define AFX_IDS_COLOR_WNDFRAME 0xFE10
#define AFX_IDS_COLOR_SCROLLBARS 0xFE11
#define AFX_IDS_COLOR_BTNFACE 0xFE12
#define AFX_IDS_COLOR_BTNSHADOW 0xFE13
#define AFX_IDS_COLOR_BTNTEXT 0xFE14
#define AFX_IDS_COLOR_BTNHIGHLIGHT 0xFE15
#define AFX_IDS_COLOR_DISABLEDTEXT 0xFE16
#define AFX_IDS_COLOR_HIGHLIGHT 0xFE17
#define AFX_IDS_COLOR_HIGHLIGHTTEXT 0xFE18
#define AFX_IDS_REGULAR 0xFE19
#define AFX_IDS_BOLD 0xFE1A
#define AFX_IDS_ITALIC 0xFE1B
#define AFX_IDS_BOLDITALIC 0xFE1C
#define AFX_IDS_SAMPLETEXT 0xFE1D
#define AFX_IDS_DISPLAYSTRING_FONT 0xFE1E
#define AFX_IDS_DISPLAYSTRING_COLOR 0xFE1F
#define AFX_IDS_DISPLAYSTRING_PICTURE 0xFE20
#define AFX_IDS_PICTUREFILTER 0xFE21
#define AFX_IDS_PICTYPE_UNKNOWN 0xFE22
#define AFX_IDS_PICTYPE_NONE 0xFE23
#define AFX_IDS_PICTYPE_BITMAP 0xFE24
#define AFX_IDS_PICTYPE_METAFILE 0xFE25
#define AFX_IDS_PICTYPE_ICON 0xFE26
#define AFX_IDS_COLOR_PPG 0xFE28
#define AFX_IDS_COLOR_PPG_CAPTION 0xFE29
#define AFX_IDS_FONT_PPG 0xFE2A
#define AFX_IDS_FONT_PPG_CAPTION 0xFE2B
#define AFX_IDS_PICTURE_PPG 0xFE2C
#define AFX_IDS_PICTURE_PPG_CAPTION 0xFE2D
#define AFX_IDS_PICTUREBROWSETITLE 0xFE30
#define AFX_IDS_BORDERSTYLE_0 0xFE31
#define AFX_IDS_BORDERSTYLE_1 0xFE32
// OLE Control verb names
#define AFX_IDS_VERB_EDIT 0xFE40
#define AFX_IDS_VERB_PROPERTIES 0xFE41
// OLE Control internal error messages
#define AFX_IDP_PICTURECANTOPEN 0xFE83
#define AFX_IDP_PICTURECANTLOAD 0xFE84
#define AFX_IDP_PICTURETOOLARGE 0xFE85
#define AFX_IDP_PICTUREREADFAILED 0xFE86
// Standard OLE Control error strings
#define AFX_IDP_E_ILLEGALFUNCTIONCALL 0xFEA0
#define AFX_IDP_E_OVERFLOW 0xFEA1
#define AFX_IDP_E_OUTOFMEMORY 0xFEA2
#define AFX_IDP_E_DIVISIONBYZERO 0xFEA3
#define AFX_IDP_E_OUTOFSTRINGSPACE 0xFEA4
#define AFX_IDP_E_OUTOFSTACKSPACE 0xFEA5
#define AFX_IDP_E_BADFILENAMEORNUMBER 0xFEA6
#define AFX_IDP_E_FILENOTFOUND 0xFEA7
#define AFX_IDP_E_BADFILEMODE 0xFEA8
#define AFX_IDP_E_FILEALREADYOPEN 0xFEA9
#define AFX_IDP_E_DEVICEIOERROR 0xFEAA
#define AFX_IDP_E_FILEALREADYEXISTS 0xFEAB
#define AFX_IDP_E_BADRECORDLENGTH 0xFEAC
#define AFX_IDP_E_DISKFULL 0xFEAD
#define AFX_IDP_E_BADRECORDNUMBER 0xFEAE
#define AFX_IDP_E_BADFILENAME 0xFEAF
#define AFX_IDP_E_TOOMANYFILES 0xFEB0
#define AFX_IDP_E_DEVICEUNAVAILABLE 0xFEB1
#define AFX_IDP_E_PERMISSIONDENIED 0xFEB2
#define AFX_IDP_E_DISKNOTREADY 0xFEB3
#define AFX_IDP_E_PATHFILEACCESSERROR 0xFEB4
#define AFX_IDP_E_PATHNOTFOUND 0xFEB5
#define AFX_IDP_E_INVALIDPATTERNSTRING 0xFEB6
#define AFX_IDP_E_INVALIDUSEOFNULL 0xFEB7
#define AFX_IDP_E_INVALIDFILEFORMAT 0xFEB8
#define AFX_IDP_E_INVALIDPROPERTYVALUE 0xFEB9
#define AFX_IDP_E_INVALIDPROPERTYARRAYINDEX 0xFEBA
#define AFX_IDP_E_SETNOTSUPPORTEDATRUNTIME 0xFEBB
#define AFX_IDP_E_SETNOTSUPPORTED 0xFEBC
#define AFX_IDP_E_NEEDPROPERTYARRAYINDEX 0xFEBD
#define AFX_IDP_E_SETNOTPERMITTED 0xFEBE
#define AFX_IDP_E_GETNOTSUPPORTEDATRUNTIME 0xFEBF
#define AFX_IDP_E_GETNOTSUPPORTED 0xFEC0
#define AFX_IDP_E_PROPERTYNOTFOUND 0xFEC1
#define AFX_IDP_E_INVALIDCLIPBOARDFORMAT 0xFEC2
#define AFX_IDP_E_INVALIDPICTURE 0xFEC3
#define AFX_IDP_E_PRINTERERROR 0xFEC4
#define AFX_IDP_E_CANTSAVEFILETOTEMP 0xFEC5
#define AFX_IDP_E_SEARCHTEXTNOTFOUND 0xFEC6
#define AFX_IDP_E_REPLACEMENTSTOOLONG 0xFEC7
#ifdef _AFX_MINREBUILD
#pragma component(minrebuild, on)
#endif
#endif //__AFXRES_H__
/////////////////////////////////////////////////////////////////////////////

1720
AGWAPI.c Normal file

File diff suppressed because it is too large Load Diff

654
AGWMoncode.c Normal file
View File

@ -0,0 +1,654 @@
/*
Copyright 2001-2022 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
*/
// Monitor Code - from moncode.asm
// Modified for AGW form monitor
#pragma data_seg("_BPQDATA")
#define _CRT_SECURE_NO_DEPRECATE
#include <stdlib.h>
#include <string.h>
#include <time.h>
#pragma data_seg("_BPQDATA")
#include "CHeaders.h"
#include "tncinfo.h"
// MSGFLAG contains CMD/RESPONSE BITS
#define CMDBIT 4 // CURRENT MESSAGE IS A COMMAND
#define RESP 2 // CURRENT MSG IS RESPONSE
#define VER1 1 // CURRENT MSG IS VERSION 1
#define UI 3
#define SABM 0x2F
#define DISC 0x43
#define DM 0x0F
#define UA 0x63
#define FRMR 0x87
#define RR 1
#define RNR 5
#define REJ 9
#define PFBIT 0x10 // POLL/FINAL BIT IN CONTROL BYTE
#define NETROM_PID 0xCF
#define IP_PID 0xCC
#define ARP_PID 0xCD
#define NODES_SIG 0xFF
UCHAR * DisplayINP3RIF(UCHAR * ptr1, UCHAR * ptr2, int msglen);
static UCHAR * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen, int DoNodes);
static UCHAR * DISPLAYIPDATAGRAM(IPMSG * IP, UCHAR * Output, int MsgLen);
static UCHAR * DISPLAYARPDATAGRAM(UCHAR * Datagram, UCHAR * Output);
int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * FrameType, int useLocalTime, int DoNodes)
{
UCHAR * ptr;
int n;
MESSAGE * ADJBUFFER;
ptrdiff_t Work;
UCHAR CTL;
BOOL PF = 0;
char CRCHAR[3] = " ";
char PFCHAR[3] = " ";
int MSGFLAG = 0; //CR and V1 flags
char * Output = buffer;
char From[10], To[10];
BOOL Info = 0;
BOOL FRMRFLAG = 0;
BOOL XIDFLAG = 0;
BOOL TESTFLAG = 0;
size_t MsgLen = msg->LENGTH;
struct tm * TM;
if (useLocalTime)
TM = localtime(&Stamp);
else
TM = gmtime(&Stamp);
// GET THE CONTROL BYTE, TO SEE IF THIS FRAME IS TO BE DISPLAYED
n = 8; // MAX DIGIS
ptr = &msg->ORIGIN[6]; // End of Address bit
while ((*ptr & 1) == 0)
{
// MORE TO COME
ptr += 7;
n--;
if (n == 0)
{
return 0; // Corrupt - no end of address bit
}
}
// Reached End of digis
Work = ptr - &msg->ORIGIN[6]; // Work is length of digis
MsgLen -= Work;
ADJBUFFER = (MESSAGE *)((UCHAR *)msg + Work); // ADJBUFFER points to CTL, etc. allowing for digis
CTL = ADJBUFFER->CTL;
if (CTL & PFBIT)
PF = TRUE;
CTL &= ~PFBIT;
*FrameType = CTL;
Output += sprintf((char *)Output, " %d:Fm ", msg->PORT & 0x7f); // Mask TX bit
From[ConvFromAX25(msg->ORIGIN, From)] = 0;
To[ConvFromAX25(msg->DEST, To)] = 0;
Output += sprintf((char *)Output, "%s To %s", From, To);
// Display any Digi-Peaters
n = 8; // Max number of digi-peaters
ptr = &msg->ORIGIN[6]; // End of Address bit
while ((*ptr & 1) == 0)
{
// MORE TO COME
From[ConvFromAX25(ptr + 1, From)] = 0;
if (n == 8)
Output += sprintf((char *)Output, " Via %s", From); // Send via on first
else
Output += sprintf((char *)Output, ",%s", From);
ptr += 7;
n--;
if (n == 0)
break;
// See if digi actioned - put a * on last actioned
if (*ptr & 0x80)
{
if (*ptr & 1) // if last address, must need *
*(Output++) = '*';
else
if ((ptr[7] & 0x80) == 0) // Repeased by next?
*(Output++) = '*'; // No, so need *
}
}
*(Output++) = ' ';
// Set up CR and PF
CRCHAR[0] = 0;
PFCHAR[0] = 0;
if (msg->DEST[6] & 0x80)
{
if (msg->ORIGIN[6] & 0x80) // Both set, assume V1
MSGFLAG |= VER1;
else
{
MSGFLAG |= CMDBIT;
CRCHAR[0] = ' ';
CRCHAR[1] = 'C';
if (PF) // If FP set
{
PFCHAR[0] = ' ';
PFCHAR[1] = 'P';
}
}
}
else
{
if (msg->ORIGIN[6] & 0x80) // Only Origin Set
{
MSGFLAG |= RESP;
CRCHAR[0] = ' ';
CRCHAR[1] = 'R';
if (PF) // If FP set
{
PFCHAR[0] = ' ';
PFCHAR[1] = 'F';
}
}
else
MSGFLAG |= VER1; // Neither, assume V1
}
if ((CTL & 1) == 0) // I frame
{
int NS = (CTL >> 1) & 7; // ISOLATE RECEIVED N(S)
int NR = (CTL >> 5) & 7;
Info = 1;
Output += sprintf((char *)Output, "<I%s%s S%d R%d>", CRCHAR, PFCHAR, NS, NR);
}
else if (CTL == 3)
{
// Un-numbered Information Frame
//UI pid=F0 Len=20 >
Output += sprintf((char *)Output, "<UI pid=%02X Len=%d>", ADJBUFFER->PID, (int)MsgLen - 23);
Info = 1;
}
else if (CTL & 2)
{
// UN Numbered
char SUP[5] = "??";
switch (CTL)
{
case SABM:
strcpy(SUP, "C");
break;
case DISC:
strcpy(SUP, "D");
break;
case DM:
strcpy(SUP, "DM");
break;
case UA:
strcpy(SUP, "UA");
break;
case FRMR:
strcpy(SUP, "FRMR");
FRMRFLAG = 1;
break;
}
Output += sprintf((char *)Output, "<%s%s%s>", SUP, CRCHAR, PFCHAR);
}
else
{
// Super
int NR = (CTL >> 5) & 7;
char SUP[4] = "??";
switch (CTL & 0x0F)
{
case RR:
strcpy(SUP, "RR");
break;
case RNR:
strcpy(SUP, "RNR");
break;
case REJ:
strcpy(SUP, "REJ");
break;
}
Output += sprintf((char *)Output, "<%s%s%s R%d>", SUP, CRCHAR, PFCHAR, NR);
}
Output += sprintf((char *)Output, "[%02d:%02d:%02d]", TM->tm_hour, TM->tm_min, TM->tm_sec);
if (FRMRFLAG)
Output += sprintf((char *)Output, "%02X %02X %02X", ADJBUFFER->PID, ADJBUFFER->L2DATA[0], ADJBUFFER->L2DATA[1]);
if (Info)
{
// We have an info frame
switch (ADJBUFFER->PID)
{
case 0xF0: // Normal Data
{
char Infofield[257];
char * ptr1 = Infofield;
char * ptr2 = ADJBUFFER->L2DATA;
UCHAR C;
size_t len;
MsgLen = MsgLen - 23;
if (MsgLen < 0 || MsgLen > 257)
return 0; // Duff
while (MsgLen--)
{
C = *(ptr2++);
// Convert to printable
C &= 0x7F;
if (C == 13 || C == 10 || C > 31)
*(ptr1++) = C;
}
len = ptr1 - Infofield;
// Output[0] = ':';
Output[0] = 13;
memcpy(&Output[1], Infofield, len);
Output += (len + 1);
break;
}
case NETROM_PID:
Output = DISPLAY_NETROM(ADJBUFFER, Output,(int) MsgLen, DoNodes);
break;
case IP_PID:
Output += sprintf((char *)Output, " <IP>\r");
Output = DISPLAYIPDATAGRAM((IPMSG *)&ADJBUFFER->L2DATA[0], Output, (int)MsgLen);
break;
case ARP_PID:
Output = DISPLAYARPDATAGRAM(&ADJBUFFER->L2DATA[0], Output);
break;
case 8: // Fragmented IP
Output += sprintf((char *)Output, "<Fragmented IP>");
break;
}
}
if (Output == NULL)
return 0;
if (Output[-1] != 13)
Output += sprintf((char *)Output, "\r");
return (int)(Output - buffer);
}
// Display NET/ROM data
UCHAR * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen, int DoNodes)
{
char Alias[7]= "";
char Dest[10];
char Node[10];
UCHAR TTL, Index, ID, TXNO, RXNO, OpCode, Flags, Window;
UCHAR * ptr = &ADJBUFFER->L2DATA[0];
if (ADJBUFFER->L2DATA[0] == NODES_SIG)
{
// Display NODES
if (DoNodes == 0)
return NULL;
// If an INP3 RIF (type <> UI) decode as such
if (ADJBUFFER->CTL != 3) // UI
return DisplayINP3RIF(&ADJBUFFER->L2DATA[1], Output, MsgLen - 24);
memcpy(Alias, ++ptr, 6);
ptr += 6;
Output += sprintf((char *)Output, "\rFF %s (NetRom Routing)\r", Alias);
MsgLen -= 30; //Header, mnemonic and signature length
while(MsgLen > 20) // Entries are 21 bytes
{
Dest[ConvFromAX25(ptr, Dest)] = 0;
ptr +=7;
memcpy(Alias, ptr, 6);
ptr +=6;
strlop(Alias, ' ');
Node[ConvFromAX25(ptr, Node)] = 0;
ptr +=7;
Output += sprintf((char *)Output, " %s:%s via %s qlty=%d\r", Alias, Dest, Node, ptr[0]);
ptr++;
MsgLen -= 21;
}
return Output;
}
// Display normal NET/ROM transmissions
Output += sprintf((char *)Output, " NET/ROM\r ");
Dest[ConvFromAX25(ptr, Dest)] = 0;
ptr +=7;
Node[ConvFromAX25(ptr, Node)] = 0;
ptr +=7;
TTL = *(ptr++);
Index = *(ptr++);
ID = *(ptr++);
TXNO = *(ptr++);
RXNO = *(ptr++);
OpCode = Flags = *(ptr++);
OpCode &= 15; // Remove Flags
Output += sprintf((char *)Output, "%s to %s ttl %d cct=%02X%02X ", Dest, Node, TTL, Index, ID );
MsgLen -= 20;
switch (OpCode)
{
case L4CREQ:
Window = *(ptr++);
Dest[ConvFromAX25(ptr, Dest)] = 0;
ptr +=7;
Node[ConvFromAX25(ptr, Node)] = 0;
ptr +=7;
Output += sprintf((char *)Output, "<CON REQ> w=%d %s at %s", Window, Dest, Node);
if (MsgLen > 38) // BPQ Extended Params
{
short Timeout = (SHORT)*ptr;
Output += sprintf((char *)Output, " t/o %d", Timeout);
}
return Output;
case L4CACK:
if (Flags & L4BUSY) // BUSY RETURNED
return Output + sprintf((char *)Output, " <CON NAK> - BUSY");
return Output + sprintf((char *)Output, " <CON ACK> w=%d my cct=%02X%02X", ptr[1], TXNO, RXNO);
case L4DREQ:
return Output + sprintf((char *)Output, " <DISC REQ>");
case L4DACK:
return Output + sprintf((char *)Output, " <DISC ACK>");
case L4INFO:
{
char Infofield[257];
char * ptr1 = Infofield;
UCHAR C;
size_t len;
Output += sprintf((char *)Output, " <INFO S%d R%d>", TXNO, RXNO);
if (Flags & L4BUSY)
*(Output++) = 'B';
if (Flags & L4NAK)
*(Output++) = 'N';
if (Flags & L4MORE)
*(Output++) = 'M';
MsgLen = MsgLen - 23;
if (MsgLen < 0 || MsgLen > 257)
return Output; // Duff
while (MsgLen--)
{
C = *(ptr++);
// Convert to printable
C &= 0x7F;
if (C == 13 || C == 10 || C > 31)
*(ptr1++) = C;
}
len = ptr1 - Infofield;
Output[0] = ':';
Output[1] = 13;
memcpy(&Output[2], Infofield, len);
Output += (len + 2);
}
return Output;
case L4IACK:
Output += sprintf((char *)Output, " <INFO ACK R%d> ", RXNO);
if (Flags & L4BUSY)
*(Output++) = 'B';
if (Flags & L4NAK)
*(Output++) = 'N';
if (Flags & L4MORE)
*(Output++) = 'M';
return Output;
case 0:
// OPcode zero is used for several things
if (Index == 0x0c && ID == 0x0c) // IP
{
// Output = L3IP(Output);
return Output;
}
if (Index == 0 && ID == 1) // NRR
{
Output += sprintf((char *)Output, " <Record Route>\r");
MsgLen -= 23;
while (MsgLen > 6)
{
Dest[ConvFromAX25(ptr, Dest)] = 0;
if (ptr[7] & 0x80)
Output += sprintf((char *)Output, "%s* ", Dest);
else
Output += sprintf((char *)Output, "%s ", Dest);
ptr +=8;
MsgLen -= 8;
}
return Output;
}
}
Output += sprintf((char *)Output, " <???\?>");
return Output;
}
/*
PUBLIC L3IP
L3IP:
;
; TCP/IP DATAGRAM
;
mov EBX,OFFSET IP_MSG
call NORMSTR
;
INC ESI ; NOW POINTING TO IP HEADER
*/
UCHAR * DISPLAYIPDATAGRAM(IPMSG * IP, UCHAR * Output, int MsgLen)
{
UCHAR * ptr;
ptr = (UCHAR *)&IP->IPSOURCE;
Output += sprintf((char *)Output, "%d.%d.%d.%d>", ptr[0], ptr[1], ptr[2], ptr[3]);
ptr = (UCHAR *)&IP->IPDEST;
Output += sprintf((char *)Output, "%d.%d.%d.%d LEN:%d ", ptr[0], ptr[1], ptr[2], ptr[3], htons(IP->IPLENGTH));
/*
MOV AL,IPPROTOCOL[ESI]
CMP AL,6
JNE @F
MOV EBX, OFFSET TCP
CALL NORMSTR
JMP ADD_CR
@@:
CMP AL,1
JNE @F
MOV EBX, OFFSET ICMP
CALL NORMSTR
JMP ADD_CR
@@:
CALL DISPLAY_BYTE_1 ; DISPLAY PROTOCOL TYPE
; mov AL,CR
; call PUTCHAR
;
; MOV ECX,39 ; TESTING
;IPLOOP:
; lodsb
; CALL BYTE_TO_HEX
;
; LOOP IPLOOP
JMP ADD_CR
*/
return Output;
}
UCHAR * DISPLAYARPDATAGRAM(UCHAR * Datagram, UCHAR * Output)
{
UCHAR * ptr = Datagram;
UCHAR Dest[10];
if (ptr[7] == 1) // Request
return Output + sprintf((char *)Output, " < ARP Request who has %d.%d.%d.%d? Tell %d.%d.%d.%d",
ptr[26], ptr[27], ptr[28], ptr[29], ptr[15], ptr[16], ptr[17], ptr[18]);
// Response
Dest[ConvFromAX25(&ptr[8], Dest)] = 0;
return Output + sprintf((char *)Output, " < ARP Rreply %d.%d.%d.%d? is at %s",
ptr[15], ptr[16], ptr[17], ptr[18], "??");
}

3307
AISCommon.c Normal file

File diff suppressed because it is too large Load Diff

9222
APRSCode.c Normal file

File diff suppressed because it is too large Load Diff

9223
APRSCode.c.orig Normal file

File diff suppressed because it is too large Load Diff

139
APRSCode.c.rej Normal file
View File

@ -0,0 +1,139 @@
--- APRSCode.c
+++ APRSCode.c
@@ -3674,7 +3674,7 @@
if (ptr1)
*ptr1 = 0;
-// Debugprintf("Duplicate Message supressed %s", Msg);
+// Debugprintf("Duplicate Message suppressed %s", Msg);
return TRUE; // Duplicate
}
}
--- BPQChat.rc
+++ BPQChat.rc
@@ -162,7 +162,7 @@
WS_VSCROLL
DEFPUSHBUTTON "Save Welcome Message",SAVEWELCOME,140,296,91,14,
BS_CENTER | BS_VCENTER
- LTEXT " If the node is not directly connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands seperared by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT",
+ LTEXT " If the node is not directly connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands separated by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT",
IDC_STATIC,9,52,355,24
END
--- BPQMail.rc
+++ BPQMail.rc
@@ -1045,7 +1045,7 @@
CONTROL "Delete Log and Message Files to Recycle Bin",
IDC_DELETETORECYCLE,"Button",BS_AUTOCHECKBOX |
BS_LEFTTEXT | BS_MULTILINE | WS_TABSTOP,5,142,115,20
- CONTROL "Supress Mailing of Housekeeping Results",
+ CONTROL "Suppress Mailing of Housekeeping Results",
IDC_MAINTNOMAIL,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT |
BS_MULTILINE | WS_TABSTOP,5,182,115,20
CONTROL "Generate Traffic Report",IDC_MAINTTRAFFIC,"Button",
--- HanksRT.c
+++ HanksRT.c
@@ -1186,7 +1186,7 @@
// Duplicate, so discard, but save time
DupInfo[i].DupTime = Now;
- Logprintf(LOG_CHAT, circuit, '?', "Duplicate Message From %s %s supressed", Call, Msg);
+ Logprintf(LOG_CHAT, circuit, '?', "Duplicate Message From %s %s suppressed", Call, Msg);
return TRUE; // Duplicate
}
--- RigControl.c
+++ RigControl.c
@@ -8385,7 +8385,7 @@
switch (Msg[0])
{
- case 'f': // Get Freqency
+ case 'f': // Get Frequency
HLGetFreq(Sock, RIG, sep);
return 0;
--- UZ7HODrv.c
+++ UZ7HODrv.c
@@ -374,7 +374,7 @@
{
// Read Freq
- buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Modem Freqency %d\r", AGW->CenterFreq);
+ buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Modem Frequency %d\r", AGW->CenterFreq);
return 1;
}
@@ -382,7 +382,7 @@
if (AGW->CenterFreq == 0)
{
- buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Invalid Modem Freqency\r");
+ buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Invalid Modem Frequency\r");
return 1;
}
--- WinRPRHelper.c
+++ WinRPRHelper.c
@@ -111,7 +111,7 @@
if (argc < 3)
{
- printf ("Missing paramters - you need COM port and IP Address and rigctl port of BPQ, eg \r\n"
+ printf ("Missing parameters - you need COM port and IP Address and rigctl port of BPQ, eg \r\n"
" WinRPRHelper com10 192.168.1.64:4532\r\n\r\n"
"Press any key to exit\r\n");
--- config.c
+++ config.c
@@ -649,7 +649,7 @@
if (LOCATOR[0] == 0 && LocSpecified == 0 && RFOnly == 0)
{
Consoleprintf("");
- Consoleprintf("Please enter a LOCATOR statment in your BPQ32.cfg");
+ Consoleprintf("Please enter a LOCATOR statement in your BPQ32.cfg");
Consoleprintf("If you really don't want to be on the Node Map you can enter LOCATOR=NONE");
Consoleprintf("");
--- kiss.c
+++ kiss.c
@@ -1485,7 +1485,7 @@
}
}
else
- Debugprintf("Polled KISS - response from wrong address - Polled %d Reponse %d",
+ Debugprintf("Polled KISS - response from wrong address - Polled %d Response %d",
KISS->POLLPOINTER->OURCTRL, (Port->RXMSG[0] & 0xf0));
goto SeeifMore; // SEE IF ANYTHING ELSE
--- templatedefs.c
+++ templatedefs.c
@@ -1165,7 +1165,7 @@
"Send Non-delivery Notifications<br>\r\n"
"for P and T messages <input %sname=\"SendND\" value=\"SendND\" type=\"checkbox\" /><br>\r\n"
" <br />\r\n"
- "Supress Mailing of<br>\r\n"
+ "Suppress Mailing of<br>\r\n"
"Housekeeping Result <input %sname=\"NoMail\" value=\"Yes\" type=\"checkbox\"><br><br>\r\n"
"Generate Traffic Report<input %sname=\"GenTraffic\" value=\"Yes\" type=\"checkbox\"><br><br>\r\n"
"<div style=\"text-align: center;\"><input class='btn' name=RunNow value=\"Run Housekeeping\" type=submit class='btn'></div>\r\n"
@@ -1454,7 +1454,7 @@
"<div style=\"text-align: left; width: 680px; margin: auto;\">The Nodes to link to box defines which other Chat Nodes should be connected to, or from which "
"connections may be accepted. The format is ALIAS:CALL, eg BPQCHT:G8BPQ-4. If the node is not directly "
"connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands "
- "seperared by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT"
+ "separated by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT"
"<br><br>The Callsign of the Chat Node is not defined here - it is obtained from the bpq32.cfg APPLICATION line corresponding to the Chat Appl Number.<br>\r\n"
"<br></div>\n"
--- WebMail.c
+++ WebMail.c
@@ -2020,7 +2020,7 @@
"document.getElementById('myform').action = '/WebMail/QuoteOriginal' + '?%s';"
" document.getElementById('myform').submit();}</script>"
"<input type=button class='btn' onclick='myfunc()' "
- "value='Include Orignal Msg'>";
+ "value='Include Original Msg'>";
char Temp[1024];
char ReplyAddr[128];

428
APRSIconData.c Normal file
View File

@ -0,0 +1,428 @@
int IconDataLen = 11434;
unsigned long long IconData[] = {
0xa1a0a0d474e5089, 0x524448490d000000, 0xff00000051010000, 0x15c97f0000000308,
0x4d4167040000005a, 0x8a0537c8af000041, 0x58457419000000e9, 0x72617774666f5374,
0x2065626f64410065, 0x6165526567616d49, 0x3c65c9717964, 0xffff45544c500003,
0xfffffff7f7ffffff, 0xfff7f7ffffeffff7, 0xf7effff7eff7f7f7, 0xdeffeff79cfffff7,
0xefefeff7efeffff7, 0xefdeefefe6f7efe6, 0xe6efe6e6f7e6efff, 0xefe6def7e6dee6e6,
0xfffff7e6d6e6e6de, 0xe6f7dedeffff9c00, 0xdededee6dededede, 0xe6bde6ded6efded6,
0xc5e6d6dededed6ff, 0xefd6cef7d6cef7de, 0xd6cef7d6c5d6d6d6, 0xd6d6d6ceefd6c5de,
0xdeced6e6d6c5e6ce, 0xced6d6d6c5ded6c5, 0xced6cececed6c5ce, 0xe6ceb5cecec5cece,
0xc5b5cebdcec5c5c5, 0xbddec5b5f7ce9ce6, 0xdec5adf7c5a5c5c5, 0xbdbdbdc5b5c5bdc5,
0xb5debdadbdbdbdc5, 0xbdb5bddebda5c5bd, 0xadb5c5b5b5f7b5a5, 0xa5f7b59cb5b5b5e6,
0xdeb59ce6adaddeb5, 0xb5a5d6b59cefada5, 0x94efb58ce6ada5bd, 0xadadad319cffd6b5,
0xad8cd6ad94adada5, 0xceada5a5b5a5a5d6, 0xa9a59ca5a5a59494, 0x9c9ccea584cea58c,
0x7ba594a5949c9c9c, 0x94949cde9484ce9c, 0x9494e6947ba59494, 0x73d68c84de8c8494,
0x9c8c8cc59473ce94, 0x8c8c948c8cc5946b, 0x52f79452ffbd008c, 0x63ffc58c6bef94,
0x8484c58c6384848c, 0x848c8484bd8c6394, 0xde737bc584638484, 0x7373ce737bd6737b,
0x737b8473848473e2, 0xbd845a7b7b84d673, 0x8442847b7b8c846b, 0x738473847b7b7bef,
0x7b7b7300ce00da6b, 0x7b52737b73ff9c00, 0x778473737b7377bd, 0x7b6b7b6b73737373,
0xbd006b736b777367, 0x4a736b7331639c00, 0x736b6b6b6b73b573, 0x6b6bde6b42b57342,
0x63736b63636b6b6b, 0xb56b42ff00ff6b6b, 0x6b3a6b63676b6b5a, 0x73636363ce5a52b5,
0x5a635a635a6b635a, 0xff635a636b5a63, 0xad63315a5a639c, 0x635a5a6b5a5a009c,
0x4a4aad63295a5a5a, 0x3a5a5a52ce4a4ad6, 0x525a4aad5a29d64a, 0x52524a5a4a4a525a,
0x52ad5a21524e5a5a, 0x4a5252a55a215252, 0x3a4a52524ac53a52, 0x52d63a42008400ce,
0xce3a42bd3a4a524a, 0x4a52a552210000ff, 0x3ad63a3a424a524a, 0xc53a3aa55219ce3a,
0x4a194242520000ef, 0x4242424a4a424aa5, 0x4242420000de4a42, 0x423a2100c542423a,
0x42423a420000ce3a, 0x3163423a3a3a3a, 0x3a3a3a3a3a006300, 0x293a313a423a3131,
0x3131313a3131313a, 0x31213129313a3129, 0x2931292929293131, 0x2921292929212929,
0x9c0031212121, 0x19ce0000de0000ff, 0x1910109c0000210c, 0x147b000000840000,
0x4449302900005c89, 0x980b9decda785441, 0x8a6766ab80555724, 0x2f20ac1bba2264c4,
0x14616a09fa3442f9, 0xe0a020be3e11a404, 0xc621e50458166a22, 0xcf8bf5a421a11e,
0x544051198a2896da, 0x5f0420c1318f891e, 0x8aacb222611647c4, 0x6fb4ac2ef48ec63d,
0xcf7df78f64cd27b7, 0xe86ceecf7755567d, 0xf8f5d5b5bd55d3db, 0x53def73dce7b9cfb,
0xe24092d7328b0249, 0xac9029e663796729, 0x1f177f262f8b81c, 0x12cf7e2f27b7ee59,
0x3be9f958b64c104d, 0xe5a271edfbc6f2ad, 0x271bc11c8e01eea4, 0xb76367803afca956,
0x5140515efa2898b, 0xdf7949479df17a21, 0xf3b94547ddfebf93, 0x744e78a40689e8e2,
0x4e88b7850d44be6c, 0x92ca94495a371526, 0xb113ae84969a7a20, 0xff65138d23540d04,
0xaf8a3288cba1745b, 0xb1d8f444cee7b2cd, 0xd9bff537369cd563, 0xe5106a1d569ee0e7,
0x48d11c8e9e4755e2, 0x110cca4c9cacd131, 0x5130ce7faa23ed3d, 0x2df464c0383392f7,
0x442e607a22b57659, 0x31a06a6e89c624c1, 0x4b6e24ad68e2e2a2, 0x11c8f44d5b1a9513,
0x68922b174a20d484, 0xf2a0602b0ca42996, 0x91f3bd1394640db0, 0xabbaef443a7026df,
0xbe31d8ec79652882, 0xf8a90a9b7d828832, 0xb44c15fb2aca2510, 0x5588f44c32c1eb34,
0x2510f3344d33443c, 0xa88750b79149cd67, 0x295cb8bfd13947a8, 0x6663d128aef44bbd,
0x49490488adc14441, 0x415290a809944636, 0xaeef24bb90404bb4, 0x27f48e328ca0d390,
0x89a21ea3d66a7291, 0x2908e79e3d5550a8, 0xa3760b4498b49e28, 0x7a4fe5e8cb49db05,
0x4fd6af41fadf5beb, 0x44a96311157c144b, 0xa21c741833a89d55, 0xae2f15109eb4a97a,
0xf1aecdcddd00eaf8, 0x9bf142fbeca051e3, 0xbb31e52e41406511, 0x5f89b73005a268a8,
0x7ee43c17eefa248a, 0xde89f83fd57d25c4, 0xb48a228ab0344fc5, 0x58ac9b44556a25de,
0xcd1063ae1e875e35, 0x528cb947a8ccd124, 0x60e6dfba5d00eaa2, 0x944a54755dd749b0,
0xb6d7ad6d49a8b4de, 0x9ca2fe49c615125e, 0x23299c9e0dc7aea8, 0xa22a90a94477005a,
0x37adf21f63d17dbf, 0x85de8c9087f37cdf, 0xa63fbb696351254b, 0x2536c9ee5aa02238,
0xa895993274415f9, 0x85128fb5728875a0, 0x23d0fd13402d1382, 0xa5cda3f7e5e7719e,
0x2875c1445e6fbc47, 0xd1344e8935074463, 0x536812a1b99eb469, 0xc8e882972eaa17ad,
0xddecd6ff87b8f474, 0xe0715e522af8df47, 0xdfac3e1c0289235, 0xb613de17b7dca211,
0x13f5a8e7daa8b9f5, 0x44cb536ea65b9441, 0xd932ca9d014cd0fd, 0x408820e97a073eb6,
0xff3349e78df465ce, 0x5302cd87a24ac7e4, 0x4ce88b19d339a3f8, 0xd3dec329ef566996,
0xe89296713de2e64, 0x565be8f3b92f96e8, 0xf79c57a87dca3e6e, 0x99ce688dce77a3c1,
0xf0f47364ad3de4ce, 0x12c27c3c5ce80333, 0x3a1ff5a16ba4f04, 0xf81d27fcfa22e22f,
0x63fbf5a7c8bfc7ae, 0x9b44c35417959544, 0x15a19a66d399f87b, 0xe450ad74e818959a,
0x2a023460147ab28e, 0x62bc9488890d74a4, 0x1719f9bd15c445e9, 0x8c2df93d17c9eabe,
0x3ba64cdb44ab7ee8, 0x259d0ad2e69ef61a, 0x7eb4438910f19252, 0x92465dbbf0f6c4a4,
0xbfcfa3d1244eb216, 0xf11e8bc6ff8f21e8, 0x4da3cef9be6f4723, 0x448cf465c47b3289,
0xcaf7fb0f3466ce4a, 0xc4cb535f289ee51f, 0xfb9e3be8bcb7d09c, 0xd193392910cdf79a,
0x9b81fa5fc31e3dbc, 0x533f8622caf572ad, 0xda3d9255917248af, 0xe7773d079f28b22b,
0x443a215d9205c6f6, 0xec6f98cb56bed45, 0x43d8da8a8e636a2a, 0x371b1027d346d45,
0x51df1e2a34f1b515, 0x2abd6e27eff6b935, 0x2d05242d7ac70f56, 0x2b23746f05aaf223,
0x58290b438744a2a7, 0x8290b1d3a1b05540, 0xa43280b05219405, 0x161b1b8d8968ed89,
0x96181726ea80b052, 0x216d61d10885138a, 0x5660f13cf62b48d3, 0x9966512a2315ba5e,
0x5036037e27890a44, 0x40d82914a06c148a, 0x2361b1bae790d229, 0xfc6580206ca81b05,
0x93289cd84232a21d, 0x9582bc6f3d8d51be, 0xf25e5fd44ba222e, 0x2a20de2f2a21ccd1,
0x98dece7b894459b6, 0x88346c5449bafca8, 0x451351be51166d8a, 0x907303b594813dad,
0xacb0e5a32983f738, 0xf46e083a3b1a8a22, 0xc3e07fad6a8804c9, 0xe5c97baeebecffee,
0xc1e5aa21ccd136cb, 0xa89b5668929b3443, 0x288aa603aa20d3dc, 0x46d194d5d859fb2f,
0x2ae804351d401344, 0x1fb7e0bdbaaeaeac, 0x5e0bc6e5dbf6e562, 0x3e47c4ff1f65e07e,
0xa25e6688b72f9efe, 0x60ca22deb4b2b503, 0x9600028f5a3d44ba, 0x54cd1112f544bbd6,
0x4e549b2348df23df, 0x3c3e3d008c853721, 0xe1d944182887a5e, 0xfb0b44e500418eb5,
0x67d192a8f5176feb, 0x87c771ddb771fd3d, 0x7ad6aa5e2fe3eaff, 0xd2ba24a65744fc5e,
0xca208ae8804ae890, 0xb44381f35c069ed4, 0x950e03b94459ec37, 0x4aa02d1190b8a144,
0xe8fcaf99f27e9746, 0x5d7a3e8fe3bb6ffb, 0x37bd0a8f5da89356, 0x9efad1e44bdd51ea,
0x3d456802a25deb4f, 0x797d7252133d68ea, 0xa2138f2fad4dcc3e, 0x2dd1156ce8cd4852,
0xb4d5ba6fda04a43b, 0xedbe1fb4fb3f2bf5, 0xb1fb6ff5edb98f31, 0xd68859cf05445a95,
0x347a9ccd13eb47a8, 0x28870f9174a0501f, 0x152242c316804ce2, 0xe426ace93bb327b6,
0x7416c293e823bf26, 0x73ca40deb7af8b9d, 0x7b6fa3f2bf5b4cb6, 0x3ad9fb4fc3fa253d,
0x2759547aaacf1544, 0xa89c65ea88727bd7, 0x5c544d72f1951eb7, 0x7b4027c31453931f,
0x5deb029027b761dd, 0xa221ac5de06f2d95, 0x86f0ca97da24a59c, 0xf75df744590e526d,
0xfa3ffbdb71dff789, 0x69ef2d4ae4fe67ca, 0xa512d3a04a88a670, 0xaf6794a20a88885,
0xebeca671e8a9962, 0x8289c53f4e73099, 0xbf92f4ba251d749e, 0x8f6dc771df0fabfb,
0x9d339eb67cb3fa7b, 0x3ef5a46d11f27bc6, 0x72027ad5c9ef1ea2, 0x642060dfe80e1838,
0xf94425d9cf4bbd74, 0x214fc8d0c2a32907, 0xa5215016d6eb64a2, 0xbf972689f952e96b,
0x765fc7c4f91f13e7, 0x9b53b448cc17e5e0, 0xd689aa4fe1e7cf68, 0xbb4874415009f0f4,
0x32884e38a15474f9, 0xd58998eea8f5d521, 0xab590b492336eda3, 0x7d6eb74bcb45b86a,
0xe5fc3da55d5715e9, 0xffbecf75dd7c5fcb, 0xfd86ea8569e81ec3, 0x856ad6887a856859,
0x32ed1110e912a272, 0x3d3e1ebd44d5da2, 0x64fb8a3fb479fa81, 0x452b0379cf13c6d8,
0xa258a9c853fcda97, 0xc564a46ce74b38bd, 0x2681ef151908948a, 0x231a42a51294444a,
0xf083364ad28922ba, 0xd0f7637eca606f9e, 0x28f3460fbb77d88d, 0x5bae8822f2955a51,
0x6770ce16a999da25, 0xba8edcbc5b53cf63, 0xdcff0c45e711173d, 0x4595f7bdb628ba24,
0x4b445befeb42ddcf, 0xed8bc7da54ebccab, 0x28f4976e649563b9, 0x27fd58d447054780,
0x1e628b1f5f411fdc, 0x6671651b063728b3, 0x4b688a5ace63da88, 0x44f6944529bc346e,
0x191129b7a89845a2, 0xe8bf0a3046a06f1, 0xe3c744d9ed1262a2, 0x95765481333c232c,
0xd7ab4bcbd06f7994, 0x66cb3f2fa50e9cd4, 0x279896830f8f6a22, 0x38b6347b6f8342d4,
0x579df2e4b4e3d135, 0x107a129a88b4ca8d, 0x34e2944e647eb513, 0x814bce7125a01289,
0x3c499445ab3c1f54, 0x6afed3c0587e7b17, 0xf835a57dd7a3b88c, 0x5a6cbb2ecbe0f7b6,
0xafe6f247094844a2, 0x8bb3d70680ae71aa, 0x64f17289c742c637, 0x1a0b250498fac750,
0xbe3eadb513a3592, 0x43fd09162f622513, 0x2f2570a325a80a0d, 0x22a8cbd365e8c860,
0x89bc0a20ad19339a, 0x9ed13075aca89803, 0x31f5f35ca2211755, 0x121a6ea5a83284a9,
0x5448686d96186da0, 0x775ab1d11d7d601c, 0x9a8691a0a0713dd6, 0x5e68c95594cb7ea6,
0x6e7d51258bc71441, 0xa8a89fa922bed44d, 0x5add4b2795706e63, 0x8fba646e18334026,
0x1ac0eba26bd696af, 0x23a79ad97b4e0ca, 0xc7ea887df4a46828, 0xd12f5197e27c3321,
0x9cf0401471e7c944, 0xf67251394815011d, 0x24876a229fc8f41e, 0xc5728871901e5134,
0x1a6dda0cd00944d7, 0xcae64a38a2236c00, 0x264b9e1a40d441a8, 0x146e21e37ca40a81,
0xcef19213d44f4d0e, 0xbe94415239404364, 0x214f7c3f02b51300, 0xb06e892a43279c9b,
0x5647ae0a2686cf18, 0xe4130612eaa26887, 0xe9b805195e4f7232, 0x4a21d52dc89bc1e0,
0x982894d6515c44af, 0x34474e994a20c144, 0x182db11299b08b19, 0xd0f75b8607b9ef0e,
0x6fb0ae8f53af5c32, 0xc53da90c09e5518f, 0xd5053e8f593bd6cb, 0x3209e673c967c4a3,
0x375bcf9441543d71, 0xd6b8a75c223f1e89, 0x5b59271c5b93ff43, 0xd68cb21dbd686a32,
0x1cc7650247690ca3, 0x5099ee7bd1281a7e, 0x8ed68723d6dcd0a4, 0x94dc2888f5b0d611,
0x6e5193e4cb5104df, 0xadfd8bb11a35549b, 0x7a910d74f5353ead, 0x40ea51eb75130934,
0x9b2600aa8d029d15, 0xcb1e94455292a940, 0xa951fc8da45d47f2, 0x4da8f5ba8459c2f5,
0xedeb63d44b4f8f4, 0xa3aa876a93de1b77, 0x441430d5a8a671eb, 0xd57a1c9336ea6b61,
0x7ea329932d24cdb0, 0x4a26af3465b146a2, 0xd1fcf932d8a230a, 0xd62a274511231d12,
0x9ea15b9760ac608b, 0x439ebfe89ef0bd76, 0x75c2268cb9a73c3e, 0xb81336a288a993ca,
0xd9be6b942b66351d, 0xe6dc6eb86486a7ae, 0x4948c5debd4c9316, 0xe8efaea22353d8ed,
0x9bd2a606897bb3d, 0x108a64d5324a4514, 0x459b1b7abcd1a33d, 0x726738fe9d4442f3,
0xb3a8f347f4ebc361, 0x45fc31179c445dd6, 0x5a16ee7a2ca2ddcf, 0x3444cc51636767f,
0xedd49267aefd0209, 0x8dd2aed8f979ab11, 0x4a2576da7271eee9, 0xdf5f3b6ed9ec62d0,
0xd0288061dec12566, 0xabed98046e74fc61, 0x7b44ab740a0c0d04, 0xbe3e63c7ec5a92c4,
0xd1bbc09c02fe71c9, 0x579dd58afde326cd, 0xd155b744626f495a, 0x833955cf05440294,
0x7888c289b1f44f07, 0x89b8e623d5a823be, 0x875c6c663d63f65e, 0xfc9e236e413539a8,
0x116a7449e9ebb60d, 0x3cecbe86586940a5, 0x3d29136dedd13642, 0x17278b8144bc177b,
0xa24ca12990c2d554, 0x23de34c4a675c46c, 0x7861e31fb3f12166, 0x93149a005b6a1ae3,
0xb86e1ba36da3eb89, 0x21e77557ac3b3cc1, 0x6e88b104a56965a0, 0x22a91b5119485b6f,
0x6688885eac2682a, 0x4b48e54418273722, 0x41ced1345112f44d, 0x947d9c7eeb25c711,
0xe1ff28830ac847a8, 0x445a932744b81833, 0x6781d5da0a564903, 0xd36cad9901196631,
0x76bb7548c895cb35, 0x2e51eb2a22e01e2a, 0xc98934461f44c6a4, 0x4e4a91490f496128,
0xb9ef42ed5f23acfd, 0xb20ab7fb65bf3079, 0x5938606cc73da9f, 0x76b0d4543bb7935d,
0x191d42eca32da804, 0xfac927d64c9f5f5d, 0x1111ba13b06a11ba, 0x32892d62bed4d09d,
0x344e6df9aec8bc9c, 0xa4bd2ed115b74413, 0xd144c0522aaa26c2, 0xe70a21c8e8835414,
0x4eaf572768880293, 0x447d87a26dc9d3bb, 0x3488823b517bb0d9, 0x60145f5761206291,
0xceba22255e9f68cb, 0xbc8cd128b0cef288, 0x8ab6da20b5b3ca88, 0x8daa6bb44416944d,
0x4d5033c512600a26, 0xc94827ce144d99a2, 0x56d3a69e31a8c902, 0xc4899d3d120fcf44,
0xb376e945c764ec70, 0x7e5544d85d8a28e3, 0x2133491c81ee7bda, 0x3ac8dcf0411a89c9,
0x4e4a2217ca28d2a8, 0x1cc7e0b151361623, 0x8c4d116a8aeaa471, 0x35485cf9e88057d8,
0xda9f24e047400ed1, 0xd290a0a26ccd1971, 0x2d1242af9cae3e0b, 0x5faa139da5192c0,
0x8c4a25ea3d4f5218, 0xc4c4cb5ea26b7b3c, 0x6a27ebb485ca21d3, 0x8fc528835946bd6b,
0x8d447c5147287689, 0x5e157ad63bab947a, 0x41a802a24b8f44a6, 0xbac4cb9443a8ca54,
0x5a182a012ae70de1, 0x437757288868c96f, 0x7ef509961ad235eb, 0x2f6eb4a3d46b4458,
0x9a328ca8922cd194, 0x8e74f051eb7265b6, 0x9f3d6a6eed946587, 0xb2b344da0ed3ace5,
0x73dc44cb2378a882, 0xb547f693de421481, 0xb0a86036792c6c87, 0xa5209447d47f7ef5,
0xf8fe8e3a7bc7a8f5, 0x4a5195103521e275, 0x5c8bed52248c413, 0x8fed9d4522b48951,
0x485027bcb6df8532, 0x585fe1e142ff0f6d, 0x455a3f9544cb9445, 0x21693ad2a3f8ea14,
0x6d08009d19628133, 0x1e265b12cc43ffe6, 0x785526dca22d79a2, 0x324342b58d2360f8,
0x44bcc47b46ac67aa, 0x58b27a8568367bbd, 0x8356076db8bf84eb, 0x9a4aac7036874415,
0xa5d9f5f134448055, 0x804a078a856f14e3, 0x5e49ee84948e1a42, 0xda1ebec65b681e56,
0x259c6cc5c4a469b3, 0x77aa22b484737674, 0x30948f1a2fb544c2, 0x79b48e4f6668cd21,
0x2d9b3beeacb38f34, 0xb61af4f511bb79a, 0x279a2867812b512, 0x188bce222d7e0ea9,
0x10b773d16ee7a2fe, 0xe6bd44d39fd685b2, 0x1c0695cb3623d432, 0x1e89d1a3af37dcef,
0xf79e17f2fe273ff5, 0xfd9fbc78e3724b55, 0x721cce1e3f7fb291, 0x363511f9c2ba787e,
0x9e0bfcb1e77462dc, 0x1b492ca51279a13e, 0x7e888d082ce397aa, 0xfcfebbe77c6e07ff,
0x1398bf87bdf1ffaf, 0xb8fb5bd5fb5f4fdd, 0x60c1a3e839632822, 0x73f944c16f446bb4,
0x1dac7b75b95d3c40, 0xbd4242a65ec132a2, 0xde45938f0e504e5e, 0xf75f448693ee44cb,
0xf03f27d7fd4ea7e7, 0x2a2314ff07f1bf2b, 0xa46a8125c8285ca3, 0xbb6d593d8a21dd60,
0x2b13e544c16f447a, 0xd6d2346d5f68cb6a, 0xb24387ccd15289c7, 0x689eedb31f6ffa26,
0xff5f2e5dd2b7dfa3, 0xf67e7fdbfecfa327, 0xee88287f75f7ffbf, 0x51505c1cfd1510f7,
0x144954736fc47abb, 0x544c16f44daaa665, 0xf2708c13da25523f, 0x435498e9d3b4463f,
0xaca2109a811e9344, 0xcdf46d9fb441a802, 0xeffa7fcbf45fc679, 0xfaffd3e2713eef27,
0xd28f5da888e3f13, 0x522540c079c11b20, 0x7e694452210b8c9c, 0x401801b87442e827,
0x453dac0c17945115, 0x54a52fbbe4b4532, 0xdfc944235418ed1, 0xb40df7f16db5d687,
0xf177186feb344d8, 0x753e5fe67fdff37a, 0x11ef8efedc4f9fe2, 0xed1160d10f3da069,
0xbea1132a17ce0cae, 0xc04c39697c8e91cd, 0x82d86401bab2ca20, 0x144c16e54c0f719b,
0x10e85e0ca81b5a27, 0x755f7e972aac3a2a, 0xf2962542f4500f39, 0xb740bb4a21c56513,
0xfc679e2904a201da, 0x6a7c4f67edfc77c8, 0x1be9bf6f53e9feb, 0x65a05288b4dcdd13,
0xe291ca04c03bfaa9, 0xcd944394188909a7, 0x88f40d496e48821f, 0x338ca33ca9701a22,
0x8bf41fd9f726ad11, 0xa95b83a74baa9c24, 0x27d6c375b5b5ba26, 0x9f637cdbc483a06f,
0x49ffbf416c9fbf1e, 0x9e6bd4febf23b9f2, 0x7cffedd37cefa8f0, 0x89c85fbbf53f33e2,
0xa21d360c1d01803e, 0x3997991d1119c7b4, 0xb5703118f9630142, 0xa5a9904f5e50cb3e,
0x79a88aa12c344e50, 0x36374420a24e082a, 0x12fbf45f1c1d1fe8, 0x47ad61190a4f48c9,
0x2217b4e944a2f629, 0xe206ca26816e74a6, 0x7f37d0f9ef9f778b, 0xe9bf87abf9df0bdf,
0x67e97f37f6bcae6b, 0xca4128875a32412, 0x34cd0d5847bd80d2, 0x4c90c87a21e93c69,
0xa4b7281ff2645678, 0xe0a0cd7525115401, 0xa2502069d447c2cb, 0x1953d2ad7251bc85,
0x1f59deb3a4d1ebc5, 0xb36851ea83b2e90e, 0x67ca269dc728df99, 0xfb5febfedf8db1de,
0xadd9fd9fe3743f85, 0xa7aefe1e13e17f6f, 0xaafe5019eb5cd26, 0x3188f467ce9eaa2,
0x89aa00d25b91805d, 0xed4a81af10addf92, 0x9d166fbd144e05, 0x63bd744c3424847d,
0x7f2da01b7388acbe, 0x4f908b262be13eba, 0x5fc1efbab63e92fc, 0xfe3ffdfa6fc3c4f3,
0xd4d259edcb7ef7d8, 0xba66668ca6a22132, 0xa22ae9de0d544e49, 0xa00d25b99824a33c,
0x6f4e28cb6074648, 0x4fb2c0a6a0fb464a, 0x16a261a12d673c8, 0xdcdb93e836ee48d,
0xfb783f25bd512671, 0x1f2beb56c4fa1f0b, 0x317e6fe03de7d2fd, 0xa3fb1fb4f3b944c1,
0xf5544fdeb4c4f7ae, 0x574136e1267ee9c0, 0x4c6803496e6f779b, 0x285a2336f279c146,
0x9342c74d6253e4a2, 0x967468134b44bc87, 0x8dd13ea5af9f16d0, 0xcbe2beaf5b7bfd5f,
0x4e77e03d97d97c1e, 0xd799047ad449817e, 0xd375a0fa28c88fc3, 0x882a5bfc3d84e268,
0x3495fbe173511616, 0x9d949d1289dc64d1, 0x349cbd72f5efe4b2, 0x6bf1ff03fa3e856f,
0x7dcff9fa0fa5fcdf, 0x5f3750f9a8cb6245, 0x5937a1a28f50342b, 0x6bd44bc5b8115ef3,
0xc9cfc6c4f62177eb, 0xffef7baf929174d7, 0x44924a7b9f73fadd, 0x6d7ad809291bd465,
0x8bcd1b4ddce79c28, 0x2c479bcd1ce6f885, 0x8deb77ef70bf01f3, 0x783f63ba32251fdc,
0xc445fc3cf87409d0, 0xca2ddcf45fc31179, 0x3d12ee7f5a174642, 0x3a8f843e29655fc4,
0x8cd45d1a67a9db1e, 0x102f77d73d05175f, 0x403d95643af00df5, 0xf67a26e639cbd414,
0xed3497bda343c574, 0xeb6c6a0017c6629e, 0xa8c81a113460d8d1, 0x6b79d334494e638c,
0x809c6f7bb01eda78, 0x6fd3d96b9e4c7db5, 0xfd57d75f0089e9e8, 0xd7c86ca01c6771ae,
0xd116a4e349293a24, 0x2944fc5935d10eac, 0x4c44dc618b4eb1cf, 0x8f1445b3eafa6546,
0xa1ad1185e5130bc9, 0xdeb2eb6ac7271cb6, 0xad659d8d7f1c8d73, 0x3c066fa373ba288a,
0xa5a891cf8233aa37, 0x8a9d656760a22125, 0x875490a88a5175a8, 0x61a44a89a4994aa8,
0x46c4e0bac0ebbaa2, 0x88f1a88dcfac9382, 0x39ea891985196ac6, 0xec744fd8f1d1167b,
0x6cbfc1a565481510, 0xac044369d4d04d10, 0xd0a5893eb799b6e6, 0x152285fe9375120c,
0x8a3215f5b3d663de, 0xf2897b1e3a20d46e, 0xc954caf16cba6b8d, 0x575f1cc544985b28,
0xa488028fdbb38d19, 0x11f4db27f512f4d0, 0xa3215f271ad31c0d, 0x8ab71def128a2525,
0xb47fa630a26a8f53, 0xd5052cd38c78da80, 0x850077510f7ad4d2, 0x6a2073a32bc1b33b,
0x72d1084e88dcce88, 0x9d66cc7bcca89b52, 0x755e30ab27798801, 0xbc305118fc585464,
0xb3bd6a6ef3426728, 0x4ac9cb4486cf6473, 0x18986d45eb6da884, 0x35d6e9d7a8a73d,
0x399a20d5ba7c9349, 0x30b1a65f27bdc996, 0x4654414d3de033d1, 0x4cb2a89713447dcb,
0xa5004d36a35a8bde, 0x3f71f0f0ccd1309f, 0x3ecf6553d93de98d, 0x6959f5a151d1bb51,
0xf7adb123348be8a5, 0x54c47aabe29a145f, 0x4502360081a34512, 0x32bd444bdaf44d94,
0x1b2b34044f5b21a, 0x86aca2e068fed51, 0x31a8e4e5cdaaa221, 0x2ef76533d73cbddd,
0x27d49f9d8801e0d1, 0x21cc4a46334cdb8a, 0x34c948fddd12d399, 0x79a2267f5afa9344,
0x466bcd1833a7bd35, 0x1b0bdfc31171b174, 0xd685bb9e8b6d7d17, 0x391d93efad12de7f,
0x1d2e34cba23c6d62, 0xaf8672a7bd664b77, 0xed6a1f4fd7c6467b, 0x289b351d7afae159,
0xf8f15a4097929943, 0xfbb9d6ea724ff039, 0x7cdd7e8d035eb850, 0xf3b9cc5680781ece,
0xa42634539ef64f78, 0x69022d281c8dca28, 0x8c96bedf816961fc, 0xe4b2fae19aa1a7f2,
0xeaef7d774fc6b2cb, 0x45a264bf3cfbc9eb, 0xa9ece815a79dce60, 0x2a689a992026946f,
0x6d28b1909d44955e, 0x89957e0ae28b4ae3, 0xa688adea9b0201d5, 0x42a25d1356592614,
0x3140d5aaaf3bd6ba, 0xa91bcee7358b45dd, 0x362ac47a24369130, 0x12c1c324f5196ad1,
0xb3174b8091520e9a, 0xa4311e6e9fe4094b, 0x5def6530bd555965, 0x89add823d1e95cf,
0x5125316c9a313823, 0xd890b1d15ca58960, 0xd03464850d129b40, 0x5548c5d164947a81,
0x48a4e0d197b01d27, 0x7ae9fe197e2992d3, 0xd62b5ef757981357, 0x64c2802a8c120366,
0xaca6836eaa4296a7, 0x9d4455a44d3dcc4b, 0xa8f517598f11f590, 0x41d195cc47bc6887,
0xb7754c488dd289aa, 0xa4f29e1356e79e67, 0x63d9c328987fa985, 0x33d0bcf6bdefaf48,
0x3a9d80f43b446325, 0xab748fbd2bceb944, 0xffd445ae0914098, 0x9da272ee868f0b4b,
0x535cf02898f5a381, 0x5268c94c3fb8d8ec, 0x690f5aea0c6ba321, 0x47cbbd1250b735bd,
0xe9d344abb88499d4, 0x741d225483060e88, 0x961f8ad44bca8c84, 0x7443bd6db5338651,
0x2f75796cf0a17af9, 0x2a26a6bbd1149962, 0xa9eb429d225cf87e, 0x94f4d53d68d3a68c,
0x1a44a88b50094d01, 0x2a265a8f954d47a9, 0xe14bf7a24b602f9f, 0xeb4a9d0389c940de,
0xbcf523a65b6b4483, 0x652094422658f27, 0x6db5130fada54d34, 0x5e894536dc4830bd,
0x1bd232e4f64946bf, 0x94a0132c69d00608, 0x9aa7bd8601e7d172, 0x40d039071bd53d44,
0x2a3f98eb15da3fb1, 0x3569744034857cbc, 0xb14d0eb4d5e975e5, 0x33513e6367bb2a3f,
0xe1ed33cb951389ef, 0xbb76374a02899473, 0xdac6ed7182d93844, 0x8c90d225ef70894c,
0xc94667af43f329a6, 0x5443af79e12f7a24, 0xead54442a2537d2b, 0x284b3e522942b74c,
0x6cba8d1a3bb176d5, 0x6ca5f5daab76ea39, 0x3f3bc28810075689, 0x4dd283946589e332,
0x5a48f23050ada6a6, 0x42e4684a47aecd4e, 0x4782298c5112bb4c, 0x6a4bd1523fa36fa5,
0xdcd278d252319d10, 0xb4434cab4379a35c, 0xec0bdef709c0299c, 0x79f79a3f53a22b5d,
0x622f7b15f526321c, 0xc5bb9e8b77398bf8, 0x38df36882fd685c6, 0xa895ef8ec3acb9c1,
0xe8cdf227ba8bed18, 0xe9be91bd5d8cfc1, 0xaf73d75ea21d2a2f, 0x34cf5c8c911e346d,
0xaa90b4af2bcf5c35, 0x7c89ce3539fe898c, 0x52154d263c587a33, 0x2e3557e4f29fcc9e,
0x9938db1ef2ef4eb, 0x354066f1cf599a6d, 0x5148a0adb140a052, 0x3d19be941d3aca0e,
0xc451d236ca46a802, 0x5124e7c72c98e694, 0x429a376745c35251, 0xee89c6a93cfea23d,
0x40e7aed15ef40d05, 0xf51fcc7b5c3e42e5, 0x74d195dcf2efe630, 0x5702918a6981db82,
0x2028ca9b2e524a7a, 0x1e257c960a89a0a2, 0xbb9ea12c7e74c8e5, 0x150148f0744e9a32,
0xc90c4dcceb44e348, 0x193a22513c744ba8, 0xc6daf65033bd44db, 0xfd63b74d139b64c9,
0x7ad95435f2512002, 0x447a1b547a9e44e7, 0x3dbc72cb8e88c274, 0xf694bb7a892ac2a1,
0x53df3469a32446e0, 0x289ff5d44ee3f630, 0x65289ca3d70d7442, 0x54454e882d7ea74c,
0x44d1344d4b449500, 0x5eb4fa8877ad25cf, 0x4cde4c9d14ff3d2b, 0xd6858e8f595025eb,
0xea324265b2e7a233, 0x347f1d688cd4cb5, 0x79f5110fba559544, 0xc86894da43281a4f,
0x4cb8d3ae9511f51f, 0x1eba8f57d47f4dce, 0xe451a8fe03448cfe, 0xb97393444ac7c5a3,
0xb80a15a7265964cd, 0x57574815191f3f59, 0x5528068b1d0adc4b, 0xa44a442e7f5da778,
0x589a40a8fed13a3f, 0x252332d9c0969291, 0x303a99bc89f6a201, 0xf19261e1dfd8d551,
0x6be79a2e73d1171a, 0x37913dd5e68a3533, 0xe57923279a3f8c9b, 0xee7a2f3888bce222,
0xfd685b210b773d16, 0x22acb42b8dea255e, 0x8d4a9f54a8ab00e, 0xd4281d754c7624d0,
0x4bc5e45b4d2b4291, 0xe7a7c4924966098d, 0xd33e47d03f483c1f, 0x2ce79cf014d7fd35,
0x3f914a510d32a0ed, 0x2ddba9cc23fc494e, 0x2acba5dda8eedd46, 0x64b405e87fae09a2,
0x1c35ad70897c92d3, 0xa743949473ce3c69, 0x10f878a116bf9030, 0x1b7080e556e9ca43,
0xd39deffcc2b82d1d, 0x514d10548169e682, 0x92d7f22d5b29a951, 0x574ce4f25571b62b,
0x918bc19c777c9ef5, 0x7fd915c350e6cf64, 0x2dcc6747cdd7d8b, 0x2ab4b4a6262d4d7a,
0xca510579a2319827, 0x9be6c5ab57f612f4, 0xd8e4629bff35da37, 0x928c4052884694a4,
0x64f7aa248a83b441, 0xf252a469b20e80bf, 0x95389a7b5237fa5a, 0x226510eb4a6be3d6,
0xd1960f06a8c7138a, 0xa27674647a0f07c3, 0x1060a26968513569, 0xa20b489144d97ba5,
0x32d0b77d187248e4, 0x9b38dca9ed19e42a, 0x7fa75445ca243428, 0xe89fa8f5950a2254,
0xe94657597aa24d66, 0x4658a472812a271f, 0x2993cdaa269f0941, 0xfe8aeb9acb7d02a3,
0xf595f7ae52042fc1, 0x4529a84a288918e8, 0x86b44e0b872f5714, 0x499444cf19327a8c,
0xaae90ca02a8f5d93, 0xb43ca3c476bacd23, 0x5697f4315f5a51bd, 0x4c7eb6155bf35a9f,
0x52d0b80945025365, 0xf041edea21ec3d13, 0x7b2ed7a8859e3265, 0x4f77a88fb82dfa89,
0x96aebc822841a7bf, 0x6e4e9711ef50fad0, 0x34c0991d90f413e8, 0xdad13eb2059c344a,
0x7aca8ca8e55628f5, 0xe9edf5197eb8d511, 0xef0d5254642a7b3d, 0xe90fd5015cd02a29,
0x510331688b428d13, 0x6913eb63aab00f90, 0xeb65884cca3d5403, 0x33d4caa3d504d135,
0x2a064f6fbd6a8e6d, 0x398e09194cc49851, 0xb963150104cf7a51, 0x409f3ba4ab4bd288,
0x9a1c99d11eb4db64, 0xd3d110d633d5eb41, 0xe030a8ca574fdf42, 0x565fe5265af7ad96,
0x5eeeafce89eef512, 0x593d9ef5b0c09635, 0xf14aa2631b332a2d, 0xb0ae1e8ca987a20d,
0x8774421df53d44c, 0xba3694fa4c741dd1, 0x5b6a888d3ba3d5f0, 0xd465c726b49ef21f,
0x4cf113400bea7b7, 0x18b6ea2264f7869a, 0x2764bd13570f44c3, 0x1ba71d92bd44b9d9,
0xe1efd47afea22a7b, 0xa9eef51eaaa8872b, 0x340988f6e52ba140, 0xba88b93de15b4bad,
0x53539cdca995706d, 0xee5bf120212f464b, 0x9bece9de793bc9d9, 0x9d0ad7deb6bd4652,
0xb16ccbd8502bd6d1, 0x9d42b701423793da, 0x46435a22ad111d3d, 0xa9fe2e225c979e4d,
0x1d6cdd52937ccd9d, 0x4a45eec958cd4442, 0xfd93854cbdb5119a, 0x204d111d47f31c4,
0xc1cfb28ca45275ab, 0x554f8be63b25c948, 0xdafc84dcf2913d6d, 0x25ce80b1291d5d43,
0xa6889496a217379a, 0x3dadf0f4df34ca52, 0x75c5281ab60d111d, 0xaf4f735136eba32e,
0x3a01ccdd20977d6, 0xd72478f6f34656d7, 0x2ce2b53d7d6b2872, 0xa2fe188b7da4bc73,
0x98db5f7773d16ee7, 0x4f442e6ee7a2ca7a, 0x79f4771da8899c9e, 0x72d8d337b6e0c15a,
0x4e49fb27b8d5fc47, 0xc48f86a71332ada7, 0x134fb59513c2d395, 0xd7ddae38cc566dd,
0x492c3fb488770912, 0xdcc648805944d5a6, 0x772fae93a0be5d91, 0xd9e63c7eef2a9796,
0xfeb4463c1b3f40e, 0x2bafa3498b3c1344, 0x4a955b7445b6eda2, 0x650c64294c9da0a2,
0x3aa69a2515723ba, 0x4a5e593967688ac4, 0xb1a271d27c940253, 0x2b18906751bd4a12,
0x4b07f5a25d1af2a2, 0x41ebf2b449859e72, 0xe05108d226dbdba2, 0x1054d1141505c9e2,
0x80f5f56c67d96b65, 0xf883c3e8ff4b0f1e, 0xa493de593a444b9e, 0x7ded32a46a8a0173,
0x20d48e5030307b2a, 0x7465b4f29442ce9a, 0x944a5216dbdba26a, 0x34151302e54d144d,
0xd17f38a94b9443c1, 0x182a2629277eb84e, 0x5cf6a4a2336c67d3, 0xca5d799664a9165a,
0xca9268027be4e0da, 0x26994709a27e0ad1, 0x44bbbdb9f26513d3, 0x3d6530a513195c75,
0xc0a4ebb4423485ca, 0x90a882264c7fd31a, 0xebc3ceca893a0bd1, 0x962aa5273927ba52,
0x92b1ae526658d9e2, 0x8b3c65196a744e51, 0xa268529368beb5e9, 0x5214d4465236dbdb,
0x8a289b50a455544d, 0xb1631fb13c618cfe, 0xa27138cc2688a4bc, 0x3cdeb4474f5f281c,
0x3afead12e2724e1d, 0x144f4c52f270c2e5, 0x7aac4f3bc3ba20c0, 0x3d6748307dd44fd4,
0x12b1d1043fc944d5, 0xa996ba89c6935a53, 0x9ad1369f2e325cf6, 0x31d72980aed34f5f,
0x271dca2014cb5ea2, 0x236ca22a9377d6cb, 0x2ac6497eb5af231, 0x4d164a24d65d3cab,
0x1459a26511331689, 0xa159680b54415162, 0xfb631d51bea27ef5, 0x228f547bdcc0ab71,
0xd6a553de529249ef, 0x5a9c925eb50d4fd3, 0xacb465aa9963deb, 0xbee394f8a89f54cb,
0xbbc529124b05ceb3, 0x69e89c7d9b799dac, 0xf13923132d0da62e, 0x212a8907d6da9d12,
0xc7214486a7bc2b2d, 0xb517c5d44b4b91bd, 0x3c61ff1a32d2f2e8, 0x959448ce8fe6383b,
0x1a3b864f780d1239, 0x903211ad4403f0f7, 0x4a5bcf5b31d74678, 0x314f783a0bfd5c4,
0xfad2d47f6a892a06, 0x833eba5519b7449a, 0xda89fa856d1968fe, 0x967fe8ed2330514d,
0x25a5d0eb43a9ab69, 0x2a856a1a21c9463c, 0x9dcf5a66a65949e7, 0xd5aa4da944d4c9d1,
0x71291e6cb2d52d0a, 0xa9236a497b802852, 0xdfad41ab2553d74b, 0x553c064cc4c94885,
0xa52523f54e3b84a4, 0x722703cd19aa7b19, 0x629c93444156c914, 0x995626f3442cf969,
0x79a369d1fd279a22, 0x8987bf8622f3888b, 0x2ef7af6ee7a2ca2e, 0xff4dcdd11aec902f,
0xeddb2a6d00fb2c60, 0x75472af3bab3bdb8, 0x7a0f952adf57ced8, 0xabc9fc67dd491199,
0x5a5b20fb97123631, 0xce3fbc11a9ad3744, 0x53f3ca9d4e013d71, 0xdbbbb43e4f58d0a7,
0x9fe93ceee1233d15, 0x7bcc0e89816e38f1, 0xf4cf09a9d3b44e6a, 0x3113126990f35347,
0x89b2f61d98f83d7c, 0x41fbe501a483da6e, 0xa7a45281453b800f, 0xd4d1300e816478d4,
0x7d0924e3a7279dd7, 0x204328a260524070, 0x1d2882b4bfea9a23, 0x6c7047133681a829,
0x4a2587494528987a, 0xea222acb542520a4, 0xb4f40069f9d584a4, 0x510e053d12540a35,
0xc4646aa9e77708b6, 0x51352c595512624a, 0x25f4622688ab4af6, 0xd7551054a863fbba,
0xe4f196958490174d, 0x4444f6795239bbe3, 0xb18872d375190c84, 0x484aa22906b8d6c4,
0x52a249e7766a3243, 0x29464b05191e4746, 0x4c42a321ad3574c9, 0x5a5fd8c7dbe4a20d,
0xa89c45f122841441, 0xa8aad3d288a3279e, 0x55c0c7530417fd25, 0xbb819be7f9e955e9,
0xa3d71b54f44c29f6, 0x8658bc9e776f5126, 0xb465a4cb2d47aed4, 0xca0d119bed435106,
0xe73cd139f60d5da8, 0x52928b2a5d25f944, 0xaf56abd21e023e08, 0x52a22c2b54f01f3a,
0xeb647061a7ad9548, 0xf9d73dde7a79ddbd, 0x52d4d294426fad98, 0x2c3fb458b1fd6b6a,
0xa5c9d3b406512ea3, 0x5ad725d52f3dd290, 0x4aba32652369b9bf, 0xa213b2878055e95e,
0x23bc66ffb7a88723, 0x27465d520ee0ee50, 0x6a42a59cf5b37347, 0x4b8a0f835062dd11,
0x65863a8c96267884, 0x952280fe9de68940, 0x8d7a5e973a75f744, 0x83bcf442242eca40,
0x4e00fcf548241de7, 0x9dd3d44e27243f54, 0xfad88922d2150a87, 0x6a1669aa8844a32d,
0x866d8ec7a323807e, 0x882fb443bd6c8689, 0x5f9e5f74c25131f6, 0x9bd698d305c3e97b,
0x623dbd44624c280f, 0x3522b4dca53ceebe, 0x13546575f5b1deb5, 0x3af058f443df3695,
0x9eb52baa6ba8fe43, 0xdae975e4cb317d94, 0xdfaa65849c93f0a7, 0x3f98d09080bf50ec,
0xa26d4e085f45145a, 0x9f27b54b6489eb58, 0x265a8900f1490e9a, 0x94b5409ef31f8a5,
0x88f4d12563678caf, 0x8b550d2aa9979a89, 0x25d68f53a856ec8e, 0x5b98fadfa5381f4a,
0x513b34fb1c3896c5, 0xd4690b52efb4f79f, 0xa7a20c06df997c3, 0x336cd2a430511895,
0x44bafada8a75c225, 0xe88a5ba24a21879d, 0xe1e3d06adea26356, 0x82ce3a8876afa26b,
0xe7f1a44d70d02b12, 0x41b45d85b2094a60, 0xb3689bcc9f5dab0b, 0xada856bea21d48a0,
0x90a32c129122fbf5, 0x328c542782b159e0, 0xc88e947a8a8caf06, 0xbeb48532c75a26ae,
0x78fcebd44bc4a466, 0x9af384435ed72523, 0x3458eaf35e84856b, 0xf3476b3a1a9cb00f,
0x90aa88a2550846fc, 0xa25124515d3ce252, 0xed79a230379a367b, 0x6beddbbbeefbba1f,
0xc466cfb757eef2c8, 0xe36c6744e8670479, 0xd16ee7317f0c45be, 0x773d177d3ac7b773,
0xe4dd71cceea241f7, 0xa4a44cbda5479919, 0x29eeea89ee79ddd5, 0x307bb51262c8a3b3,
0xa2559d7916fde4e8, 0x3ea0906ec9e6a396, 0xba8886940a547c0d, 0x5018bc039a899ce9,
0x46bb78c1a409595e, 0xeceb5271a75ce2d9, 0x4faf70dc80c7e3a9, 0x624e893bca179e16,
0x3272948449e804a2, 0x44b8b26b4e08f9e7, 0x6a2107301765f13, 0x2e45291dbb06912a,
0xfaeb6109151fe2a6, 0x2a27194621a6fea3, 0x2c91e718c6a48b66, 0x69438a32596e8c86,
0xd6b1ad08691ae88a, 0x9b6289b5193d5ae2, 0xcddf9c0941ba888a, 0x206601442bb1214c,
0x80ca3d5548191a3a, 0x225445a90ca688fa, 0x4e6cb94918d74465, 0xf8356c37d33813d4,
0xb4e993cfb5144ee6, 0x116a224160944bde, 0xca252902a26d4865, 0x40c7ad5197a2131e,
0x40b758a3b75f5125, 0xcb56cc7235139b2c, 0x62996dc15a887828, 0x4c8d18df16730e4f,
0x44034854e581eaa4, 0xe8d5492cd44e5229, 0xbaa455074c526b59, 0x240260ea3b76f51e,
0xe8e4a77512f265a6, 0x1de4ef04019967e7, 0x435134603afbd6d7, 0x1fd95110d34483eb,
0x137d4483483a3749, 0xc93b07d8db1d3ab7, 0x7a88c495b4494628, 0x902ca13243798da7,
0x89aa77443a847cd6, 0x93e9ba261bb48ab2, 0x8c98d0247688e9d1, 0x9c67567ca968abb2,
0x728947de85eb5468, 0x35d6f464ab4d09, 0xafad1a75ba7c9349, 0xb6aad5b46425b44d,
0xae62b78d232eb64c, 0x9dfad9f5120fad1e, 0x3cd0527a24aa4954, 0x8829e2a8fe251069,
0x585469464c675d5a, 0x8eb96dd1309fa500, 0x7cd6d1156902a3fb, 0xb0d8f75813803d6c,
0x1544ae3d68eb44a6, 0x7804d1042d1142d1, 0x8ad635bac4fe85bf, 0xa807ccdec6b15ac9,
0xf119fd6956812a20, 0x7511eecd966b1347, 0x49b4a1cf3012ceba, 0x680aa22aaf54e14c,
0xd12eed6a68d5a884, 0xbb440347f1ea3206, 0x468a286c1a6fbdda, 0xa9a316d108d03544,
0x4948ad688b67f79a, 0x94474d32d4a532c8, 0xd1291bbd680c35ce, 0xdce3144fc4a4653c,
0x9e68bd68944948cd, 0xb4474c3dad44cdbf, 0xf5afcf3450b8fcee, 0x888ba21d495be14a,
0x51744579ff8622f3, 0x7ba20b28b773dde6, 0xb8c9000300bffcbb, 0x816dca717973,
0x42ae444e45490000, 0x8260, 0x0, 0x0,
};
int DummyDataLen = 2032;
unsigned long long DummyData[254] = {
0x464a1000e0ffd8ff, 0x6400000201004649, 0x1100ecff00006400, 0x100796b637544,
0xff00001e00000004, 0x65626f64410e00ee, 0xff01000000c06400, 0xb0b0b10008400db,
0xf17100c0c100b0c, 0x141010141b170f0d, 0x1f17171717171f1b, 0x1e171a1a1a1a171e,
0x2f1e23252725231e, 0x4040402f2f33332f, 0x4040404040404040, 0xf0f110140404040,
0x1415121215111311, 0x1616141a14111411, 0x1a1a1c1a1a261a14, 0x231e1e1e1e233026,
0x2b2e2727272e2b30, 0x4040353530303535, 0x404040404040403f, 0xc0ff4040404040,
0x103000100010811, 0x111030111020022, 0x30001008000c4ff, 0x10101,
0x504000000000000, 0x101010101030206, 0x1, 0x201000000000000,
0x401020200011004, 0xf0004060101, 0x1104030201000000, 0x5141063105131221,
0x1523427114322261, 0x834333a26252a181, 0x113616456434b3a3, 0x1050100010101,
0x0, 0x815141f012110100, 0x1030c00daff2102, 0x3f001103110200,
0x8073e800d8, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x6387ad181b0c3ee3, 0x56f2d81db762731d,
0x9f6e6b8e79e2592d, 0x785ca6e0f3c5ed20, 0x8ec5bb9bcbb5926f, 0xaced36c7f66b116d,
0x7ad67386e7239ef5, 0xe91bde7da87f57af, 0x9c63f1b43f2cb6e0, 0x6bbbcd14bbd39a54,
0xbbbe159e9f39e235, 0x577ab735fd3a066f, 0x3eae972cfb3a065b, 0xef98366da59556fb,
0xba3ccbfc1c3fefb5, 0x1f390337bd1ed7f6, 0x3adbfc2db6a66255, 0x4d3295262fbe2c7e,
0xe86e2dd624d730b6, 0x1d4f6d9e48939c99, 0x9fd6bf373fbdde7e, 0xd7d8f9affbefcefc,
0xc12b4ff633e15b66, 0xec3f7db119fbf790, 0x8bb13afbe6e546bd, 0xd7fa7c6fbdd71c26,
0xea9e15f1bc63acd8, 0xdc33afe7637edbf1, 0x346a9bbdb9bfc5bc, 0x797b9d66e9700d27,
0x7a6dad946cb6f662, 0xeede9e89289e1df3, 0x98c5b43a1dcfcf2f, 0xa03eedb96beffacb,
0xebcfd414b1adcdd7, 0xcc4aedadf6da9eeb, 0x248ff41dafe5f166, 0xcff2c76f2723265a,
0xdb5c4d4db3b747cb, 0x78cb760c1e672259, 0x9ee36913694d5baf, 0xcf8c7accd225f43a,
0x7698da7c166379d3, 0xbc656f04779fb1ab, 0xd9ed99dc636a0e5b, 0x716a733cabbd468b,
0x6d7f0d2bf1c4131f, 0xd915718cab17679f, 0x8c93c596ee7e9bdc, 0x5e3371cc465bc175,
0xfff6d31d295eaec9, 0xf85cc6d962293100, 0xd1921f57b279f630, 0xe9b7d7bda27d1f8f,
0xfdd994fb99f979a5, 0x9bb7adad611f7dde, 0xb0f505d772ee3757, 0xe638f1f2bdc6c64c,
0x697b26fbf43daf7b, 0x9992cba7d8474cf6, 0xb1d46f1757713b3b, 0xedf963bea74d765b,
0xbfc88c39f756bdf, 0x2ff84c71b4e5b3f4, 0xede1b2ad641a2697, 0xcdd19dda448be3f2,
0x4de5f898631dab7b, 0xc63e6f517fde3dee, 0x2646db448b625b6d, 0x63328ed3da706a63,
0xf676f3e76911afb5, 0xd3f0e94e77c77c44, 0x7ca92bef4d7ddb8d, 0xd9d632f926e9bf58,
0xfef8568a15cfd83f, 0x1a3d4f7c9ceefe7e, 0x9b670f83cf65d098, 0xdaf7f1182df97125,
0x999f579a7e7bdd2b, 0xecafecbf27dbb99f, 0x53678f919a6ffd35, 0xe7384f8ad9d561dd,
0xdbeb9963ebee2e2e, 0xcfa4f8d9afe7f43c, 0xce0e7f97adaf58d5, 0x937ca5c797178b9f,
0xbadb8a36c7d58c5d, 0xc7d39a23de1c2766, 0x350ee5ca5fafb36f, 0x3d06638bcf601ca3,
0x8ec9b59ac5ee368c, 0x896775475b734cdc, 0x50edf0eb, 0x7510000000000000,
0xb000ff9ebded673d, 0x3efdc300fffe77f2, 0x67ae7e9a343c3bde, 0x9ef4af5da1fb799e,
0x6cfe6cbe763d782c, 0x4f93bd92c7da155a, 0xe61773b4d5227735, 0xc8c42ff01fbf459c,
0x87e9f477343550bb, 0xd28ae0e93bd60e5b, 0x235ec79b6d86cbb5, 0xd2f19c8ecb6372b6,
0xebbe9f9f79fcc727, 0x937fbd99f5767fd6, 0x1d7f6fa7feece6c3, 0xff354f00ffad97,
0x57756fec0c4eef27, 0x538cd6bb17871ed4, 0x792d53cc69f9da9a, 0xcde9a5d6d6b4ed98,
0x1331e1cf4a33d162, 0x3d9bc3e6b6bf7dfc, 0x2e4fde1e5f2376f4, 0xa5b5e6c56f1527c5,
0xf3766bdb6b6286af, 0xcf3c1fafe778f13d, 0x96a6a0bf4ed5860c, 0x7d5dc55886ceaee6,
0xe28beff48ec9d368, 0xb78f2d4db459c68b, 0x4cf875acdb3ccf24, 0x5a7b5dc1bf3f5af6,
0x9ede6a268bcb8bb1, 0x779c26b95e31bd48, 0xa7e79923d6744744, 0x3f9abba80d1994d8,
0x7499564bb1a7cfb8, 0x4b33dfa9b548cef2, 0x5eb3ba2752f2d8d2, 0x13251df1fd3cb7e8,
0xd888edbd2da6a10f, 0xb59582a9addb15cb, 0x4db13d9bdfbc75a2, 0xe9e9bf38f9e668ad,
0x9c7e15d5860cb530, 0x38debed5aebffdd8, 0xb0988ecd6273ebc1, 0x39279fe7e224e378,
0xcc331fc7f7adf96f, 0xf75feb00ff3e4e4f, 0xffea9fee4ff93f, 0xcbcc4bff4bffee0,
0x3d19fbd22f7bd686, 0xd97c5dd11b557f5e, 0x5ef2d93d9ce52c27, 0x527f7292cf397972,
0x1caf233d2b62ce7e, 0xf7ecc3dba8afccc4, 0x14df6d69dda68e7d, 0x5331564a3e4c0e5b,
0x58773fd35272f9b3, 0x43865a4c7a629e8f, 0x5787add8d32fa76a, 0xb0c7ee6b5bd33c16,
0xeb4e36dfacd496cb, 0xdc3d731c3fdedd5e, 0xfaea1d8e8848c773, 0xce667d35865dafad,
0xe2b3985a9b957a3c, 0xde5af3a67da7d69c, 0x9fb93bbd5e7e7199, 0x54006dc830ebbef3,
0x0, 0x0, 0x0, 0x0,
0x0, 0x3e00000000000000, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0xd9ff070000000000};

3889
APRSStdPages.c Normal file

File diff suppressed because it is too large Load Diff

6410
ARDOP.c Normal file

File diff suppressed because it is too large Load Diff

2377
ARDOPAX25.c Normal file

File diff suppressed because it is too large Load Diff

129
Alloc.c Normal file
View File

@ -0,0 +1,129 @@
/* Alloc.c -- Memory allocation functions
2008-09-24
Igor Pavlov
Public domain */
#ifdef _WIN32
#include <windows.h>
#endif
#include <stdlib.h>
#include "Alloc.h"
/* #define _SZ_ALLOC_DEBUG */
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
#ifdef _SZ_ALLOC_DEBUG
#include <stdio.h>
int g_allocCount = 0;
int g_allocCountMid = 0;
int g_allocCountBig = 0;
#endif
void *MyAlloc(size_t size)
{
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
{
void *p = malloc(size);
fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p);
return p;
}
#else
return malloc(size);
#endif
}
void MyFree(void *address)
{
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address);
#endif
free(address);
}
#ifdef _WIN32
void *MidAlloc(size_t size)
{
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
#endif
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
}
void MidFree(void *address)
{
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
#endif
if (address == 0)
return;
VirtualFree(address, 0, MEM_RELEASE);
}
#ifndef MEM_LARGE_PAGES
#undef _7ZIP_LARGE_PAGES
#endif
#ifdef _7ZIP_LARGE_PAGES
SIZE_T g_LargePageSize = 0;
typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
#endif
void SetLargePageSize()
{
#ifdef _7ZIP_LARGE_PAGES
SIZE_T size = 0;
GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
if (largePageMinimum == 0)
return;
size = largePageMinimum();
if (size == 0 || (size & (size - 1)) != 0)
return;
g_LargePageSize = size;
#endif
}
void *BigAlloc(size_t size)
{
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
#endif
#ifdef _7ZIP_LARGE_PAGES
if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
{
void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
if (res != 0)
return res;
}
#endif
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
}
void BigFree(void *address)
{
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
#endif
if (address == 0)
return;
VirtualFree(address, 0, MEM_RELEASE);
}
#endif

32
Alloc.h Normal file
View File

@ -0,0 +1,32 @@
/* Alloc.h -- Memory allocation functions
2008-03-13
Igor Pavlov
Public domain */
#ifndef __COMMON_ALLOC_H
#define __COMMON_ALLOC_H
#include <stddef.h>
void *MyAlloc(size_t size);
void MyFree(void *address);
#ifdef _WIN32
void SetLargePageSize();
void *MidAlloc(size_t size);
void MidFree(void *address);
void *BigAlloc(size_t size);
void BigFree(void *address);
#else
#define MidAlloc(size) MyAlloc(size)
#define MidFree(address) MyFree(address)
#define BigAlloc(size) MyAlloc(size)
#define BigFree(address) MyFree(address)
#endif
#endif

3175
BBSHTMLConfig.c Normal file

File diff suppressed because it is too large Load Diff

15928
BBSUtilities.c Normal file

File diff suppressed because it is too large Load Diff

451
BPQChat.rc Normal file
View File

@ -0,0 +1,451 @@
//Microsoft Developer Studio generated resource script.
//
#include "chatrc.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
#define CHAT
#define IDC_STATIC -1
#include "..\CommonSource\Versions.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_PROPPAGE_LARGE DIALOG DISCARDABLE 0, 0, 235, 156
STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
CAPTION "Property Page"
FONT 8, "MS Sans Serif"
BEGIN
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO MOVEABLE PURE
BEGIN
IDD_PROPPAGE_LARGE, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 228
TOPMARGIN, 7
BOTTOMMARGIN, 149
END
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.K.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
BPQMAILCHAT DIALOG DISCARDABLE 120, 50, 294, 165
STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU |
WS_THICKFRAME
CAPTION "G8BPQ Chat Server 1.0.0.10 Beta July 2009"
CLASS "BPQMailChat"
FONT 8, "FixedSys"
BEGIN
LTEXT " User Callsign Stream Conf Queue RTT",101,3,4,
184,10
LTEXT "UTC",IDC_STATIC,197,5,15,10
LTEXT "Local",IDC_STATIC,241,5,21,10
LTEXT "",IDC_UTC,215,5,25,10
LTEXT "",IDC_LOCAL,269,5,25,10
LISTBOX 100,2,16,190,130,WS_VSCROLL
LTEXT "Chat Nodes",IDC_STATIC,197,25,40,10
LTEXT "",IDC_NODES,243,25,20,10
LTEXT "Chat Users",IDC_STATIC,197,35,40,10
LTEXT "0",IDC_CHATSEM,274,126,20,10
LTEXT "Chat Links",IDC_STATIC,197,45,40,10
LTEXT "",IDC_LINKS,243,45,20,10
LTEXT "Chat SEM Clashes",IDC_STATIC,197,126,68,10
LTEXT "",IDC_USERS,243,35,20,10
LTEXT "Con SEM Clashes",IDC_STATIC,197,135,68,10
LTEXT "0",IDC_CONSEM,274,135,20,10
END
CONSOLEWINDOW DIALOG DISCARDABLE 17, 25, 400, 301
STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU |
WS_THICKFRAME
CAPTION "Chat Console"
MENU CONSOLEMENU
CLASS "CONSOLEWINDOW"
FONT 8, "FixedSys"
BEGIN
EDITTEXT 118,24,228,348,15,ES_AUTOHSCROLL | ES_NOHIDESEL
END
BPQMONWINDOW DIALOG DISCARDABLE 17, 25, 400, 300
STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU |
WS_THICKFRAME
CAPTION "Chat Monitor"
MENU MENU_2
CLASS "BPQMONWINDOW"
FONT 8, "FixedSys"
BEGIN
LISTBOX 121,6,25,290,109,LBS_MULTIPLESEL | LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_HSCROLL
END
BPQDEBUGWINDOW DIALOG DISCARDABLE 17, 25, 400, 300
STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU |
WS_THICKFRAME
CAPTION "Chat Debug Window"
MENU MENU_3
CLASS "BPQDEBUGWINDOW"
FONT 8, "FixedSys"
BEGIN
LISTBOX 122,5,156,290,109,LBS_MULTIPLESEL | LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_HSCROLL
END
CHAT_CONFIG DIALOG DISCARDABLE 0, 0, 372, 318
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Configuration"
FONT 8, "System"
BEGIN
LTEXT "Chat Appl Number",IDC_STATIC,91,110,61,8
EDITTEXT ID_CHATAPPL,159,108,29,14
LTEXT "Nodes to link to",IDC_STATIC,159,126,53,8
EDITTEXT ID_CHATNODES,29,141,313,60,ES_MULTILINE | ES_UPPERCASE |
ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL
DEFPUSHBUTTON "Save",SAVENODES,160,204,50,14,BS_CENTER | BS_VCENTER
LTEXT "The Application Number defines which BPQ32 Application gives access to the Chat Server. Note this is the APPLNumber (1-32) not an Application Mask, as uses in many BPQ32 programs.",
IDC_STATIC,10,10,353,18
LTEXT "The Nodes to link to box defines which other Chat Nodes should be connected to, or from which connections may be accepted. The format is ALIAS:CALL, eg BPQCHT:G8BPQ-4.",
IDC_STATIC,10,31,355,22
LTEXT "The Callsign of the Chat Node is not defined here - it is obtained from the BPQ32 APPLCALL parameter corresponding to the Chat Appl Number.",
IDC_STATIC,10,76,360,21
LTEXT "Streams",IDC_STATIC,199,110,34,8
EDITTEXT ID_STREAMS,236,108,29,14
LTEXT "Chat Welcome Message",IDC_STATIC,142,222,82,8
EDITTEXT IDM_CHATUSERMSG,15,235,340,54,ES_MULTILINE |
ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN |
WS_VSCROLL
DEFPUSHBUTTON "Save Welcome Message",SAVEWELCOME,140,296,91,14,
BS_CENTER | BS_VCENTER
LTEXT " If the node is not directly connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands separared by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT",
IDC_STATIC,9,52,355,24
END
IDD_USERADDED_BOX DIALOG DISCARDABLE 176, 132, 129, 68
STYLE DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_THICKFRAME
FONT 8, "System"
BEGIN
DEFPUSHBUTTON "Ok",0,47,48,36,17,BS_CENTER | BS_VCENTER
LTEXT "Label0",5050,5,10,117,32
END
WELCOMEMSG DIALOG DISCARDABLE 26, 5, 381, 266
STYLE WS_CHILD | WS_VISIBLE
FONT 8, "System"
BEGIN
LTEXT "Normal User Welcome Message",IDC_STATIC,5,7,130,8
EDITTEXT IDM_USERMSG,5,20,340,45,ES_MULTILINE | ES_AUTOVSCROLL |
ES_AUTOHSCROLL | ES_WANTRETURN
LTEXT "Chat Welcome Message",IDC_STATIC,5,67,130,8
EDITTEXT IDM_CHATUSERMSG,5,80,340,45,ES_MULTILINE |
ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
LTEXT "New User Welcome Message",IDC_STATIC,5,127,130,8
EDITTEXT IDM_NEWUSERMSG,5,140,340,45,ES_MULTILINE |
ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
LTEXT "Expert User Welcome Message",IDC_STATIC,5,187,130,8
EDITTEXT IDM_EXPERTUSERMSG,5,200,340,25,ES_MULTILINE |
ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
DEFPUSHBUTTON "Save",IDM_MSGSAVE,166,250,50,14,BS_CENTER | BS_VCENTER
LTEXT "$U : Callsign of the user $I : First name of the user $X Messages for user $x Unread messages",
IDC_STATIC,5,228,369,8
LTEXT "$L : Number of the latest message $N : Number of active messages. $Z : Last message read by user",
IDC_STATIC,5,238,365,10
END
IDD_CHATCOLCONFIG DIALOG DISCARDABLE 0, 0, 224, 120
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Chat Colour Configuration"
FONT 8, "System"
BEGIN
DEFPUSHBUTTON "Save",IDOK,50,95,50,14
PUSHBUTTON "Close",IDCANCEL,120,95,50,14
COMBOBOX IDC_CHATCALLS,10,5,100,60,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_CHATCOLOURS,115,5,100,60,CBS_DROPDOWNLIST |
CBS_OWNERDRAWFIXED | WS_VSCROLL | WS_TABSTOP
END
IDD_UPDATECHATMAP DIALOG DISCARDABLE 0, 0, 274, 146
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Update Chat Map"
FONT 8, "System"
BEGIN
LTEXT "Click Help for full information about the Chat Network Map",
IDC_STATIC,5,10,195,15
DEFPUSHBUTTON "? Help",IDC_MAPHELP,220,10,33,11,BS_CENTER | BS_VCENTER
LTEXT "Position",IDC_STATIC,5,30,35,10
EDITTEXT IDC_MAPPOSITION,5,45,145,15,ES_AUTOHSCROLL
LTEXT "Popup Box Text. ",IDC_STATIC,5,65,70,9
EDITTEXT IDC_POPUPTEXT,5,80,200,35,ES_MULTILINE | ES_AUTOHSCROLL |
WS_HSCROLL
LTEXT "Popup Mode",IDC_STATIC,215,80,49,10
CONTROL "Hover",IDC_HOVER,"Button",BS_AUTORADIOBUTTON,219,92,45,
10
CONTROL "Click",IDC_CLICK,"Button",BS_AUTORADIOBUTTON,219,104,45,
10
DEFPUSHBUTTON "Send to Map System",IDSENDTOMAP,5,125,90,14
DEFPUSHBUTTON "Save",IDOK,100,125,35,14
PUSHBUTTON "Cancel",IDCANCEL,140,125,40,14
END
IDD_HRHELP DIALOG DISCARDABLE 0, 0, 415, 182
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Hierarchical Forwarding Help"
FONT 8, "System"
BEGIN
DEFPUSHBUTTON "OK",IDOK,182,158,50,14
EDITTEXT IDC_HRTEXT,4,4,405,150,ES_MULTILINE | ES_AUTOVSCROLL |
ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO MOVEABLE PURE
BEGIN
"BPQMAILCHAT", DIALOG
BEGIN
BOTTOMMARGIN, 155
END
CHAT_CONFIG, DIALOG
BEGIN
RIGHTMARGIN, 371
BOTTOMMARGIN, 296
END
"IDD_USERADDED_BOX", DIALOG
BEGIN
BOTTOMMARGIN, 65
END
IDD_HRHELP, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 408
TOPMARGIN, 7
BOTTOMMARGIN, 175
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDC_BPQMailChat MENU DISCARDABLE
BEGIN
POPUP "Actions"
BEGIN
POPUP "Logging Options"
BEGIN
MENUITEM "Log Chat Traffic", IDM_LOGCHAT
END
POPUP "Disconnect User"
BEGIN
MENUITEM ".", IDM_DISCONNECT
END
MENUITEM "Update Chat Map Info", ID_ACTIONS_UPDATECHATMAPINFO
MENUITEM "Edit Chat Console Colours", IDM_EDITCHATCOLOURS
END
MENUITEM "&Configuration", IDM_CONFIG
POPUP "Windows"
BEGIN
MENUITEM "Chat Console (F3)", IDM_CHATCONSOLE
MENUITEM "Monitor (F4)", IDM_MONITOR
MENUITEM "Debug Chat (F5)", IDM_DEBUG
END
POPUP "&Help"
BEGIN
MENUITEM "&About ...", IDM_ABOUT
MENUITEM "Online Documentation", ID_HELP_ONLINEHELP
END
END
CONSOLEMENU MENU DISCARDABLE
BEGIN
POPUP "Options"
BEGIN
MENUITEM "Enable Bells", BPQBELLS
MENUITEM "Flash insstead of Beep on Bell", BPQFLASHONBELL
MENUITEM "Strip Linefeeds", BPQStripLF
MENUITEM "Wrap Input ", IDM_WRAPTEXT
MENUITEM "Beep if Input too long", IDM_WARNINPUT
MENUITEM "Flash on Chat User Connect", IDM_Flash
MENUITEM "Close Window on exit", IDM_CLOSEWINDOW
END
POPUP "Edit"
BEGIN
MENUITEM "Copy Output Window", BPQCOPYOUT
MENUITEM "Clear Output Window", BPQCLEAROUT
MENUITEM "Edit Chat Console Colours", IDM_EDITCHATCOLOURS
END
END
MENU_2 MENU DISCARDABLE
BEGIN
POPUP "Monitor"
BEGIN
MENUITEM "Monitor CHAT", MONCHAT
END
POPUP "Edit"
BEGIN
MENUITEM "Copy Monitor Window", BPQCOPYOUT
MENUITEM "Clear Monitor Window", BPQCLEAROUT
END
END
MENU_3 MENU DISCARDABLE
BEGIN
POPUP "Edit"
BEGIN
MENUITEM "Copy Monitor Window", BPQCOPYOUT
MENUITEM "Clear Monitor Window", BPQCLEAROUT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDC_TELNETSERVER ACCELERATORS MOVEABLE PURE
BEGIN
"?", IDM_ABOUT, ASCII, ALT
"/", IDM_ABOUT, ASCII, ALT
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE MOVEABLE PURE
BEGIN
"chatrc.h\0"
END
2 TEXTINCLUDE MOVEABLE PURE
BEGIN
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#define CHAT\r\n"
"#define IDC_STATIC -1\r\n"
"#include ""..\\CommonSource\\Versions.h""\r\n"
"\r\n"
"\0"
END
3 TEXTINCLUDE MOVEABLE PURE
BEGIN
"#include ""..\\StdVer.inc""\r\n"
"\0"
END
1 TEXTINCLUDE MOVEABLE PURE
BEGIN
"resource.h\0"
END
3 TEXTINCLUDE MOVEABLE PURE
BEGIN
"#include ""..\\StdVer.inc""\r\n"
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
CHAT_CONFIG AFX_DIALOG_LAYOUT MOVEABLE PURE
BEGIN
0x0000
END
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_APP_TITLE "BPQMailChat"
IDC_BPQMailChat "BPQMailChat"
END
#endif // English (U.K.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "..\StdVer.inc"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

1387
BPQINP3.c Normal file

File diff suppressed because it is too large Load Diff

3723
BPQMail.c Normal file

File diff suppressed because it is too large Load Diff

1490
BPQMail.rc Normal file

File diff suppressed because it is too large Load Diff

3823
BPQMailConfig.c Normal file

File diff suppressed because it is too large Load Diff

333
BPQMailrc.h Normal file
View File

@ -0,0 +1,333 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by BPQMail.rc
//
#define IDC_MYICON 2
#define IDSENDTOMAP 3
#define IDSelectFiles 3
#define IDI_ICON1 101
#define IDD_CONFIG 102
#define IDS_APP_TITLE 103
#define IDD_ABOUTBOX 103
#define IDM_ABOUT 104
#define IDM_EXIT 105
#define IDD_PROPPAGE_LARGE 107
#define IDC_BPQMailChat 109
#define IDM_CONFIG 110
#define IDM_CONSOLE 120
#define IDM_MONITOR 121
#define IDR_MAINFRAME 128
#define IDD_USEREDIT 200
#define IDD_FORWARDING 201
#define IDD_MSGEDIT 202
#define IDC_NODES 501
#define IDC_USERS 502
#define IDC_LINKS 503
#define IDC_SYSOPMSGS 504
#define IDC_NODES2 505
#define IDC_FWDINT 505
#define IDC_MAXSEND 506
#define IDC_UTC 506
#define IDC_MAXRECV 507
#define IDC_LOCAL 507
#define IDC_MAXBLOCK 508
#define IDC_MSGS 508
#define IDC_BBSHA 509
#define IDC_HELD 509
#define IDC_SMTP 510
#define IDC_REVFWDINT 510
#define IDC_MAXAGE 511
#define IDC_FWDINT2 512
#define IDC_CONTIMEOUT 512
#define IDC_USERS2 513
#define IDC_MSGSEM 514
#define IDC_ALLOCSEM 515
#define IDC_CONSEM 517
#define COPYFROMCALL 518
#define IDC_BBSCall 1001
#define IDC_BaseDir 1002
#define IDC_BBSAppl 1003
#define IDC_BBSStreams 1004
#define IDC_POP3Port 1005
#define IDC_REMOVED 1006
#define IDC_SMTPPort 1006
#define IDC_KILLED 1007
#define IDC_HRoute 1007
#define IDC_LIVE 1008
#define IDC_SYSOPCALL 1008
#define IDC_TOTAL 1009
#define IDC_REMOTEEMAIL 1009
#define IDC_BIDSREMOVED 1010
#define IDC_UIPORTS 1010
#define IDC_NNTPPort 1010
#define IDC_BIDSLEFT 1011
#define IDC_AMPR 1011
#define IDC_ENABLEUI 1012
#define IDC_USEB2 1013
#define IDC_REFUSEBULLS 1013
#define IDC_CHATSEM 1014
#define IDC_PERSONALONLY 1014
#define MAILFOR_MINS 1014
#define IDC_SENDNEW 1015
#define IDC_FORWARDAMPR 1015
#define IDC_UICONFIG 1016
#define IDC_USELOCALTIME 1016
#define IDC_DELETETORECYCLE 1017
#define IDC_CTRLZ 1017
#define IDC_KNOWNUSERS 1017
#define IDC_MAINTNOMAIL 1018
#define IDC_EDIT1 1019
#define IDC_MSGTO 1020
#define IDC_WPVIA 1020
#define IDC_MSGTITLE 1021
#define IDC_MAINTSAVEREG 1021
#define IDC_MAINTTRAFFIC 1021
#define IDC_MSGBID 1022
#define IDC_MAINTNONDELIVERY 1022
#define IDSEND 1023
#define IDC_MAINTSAVEREG2 1023
#define IDCANCELMSG 1024
#define BPQBASE 1024
#define IDC_ATTACHMENTS 1024
#define IDC_ALIAS 1025
#define IDC_HRTEXT 1027
#define IDC_HROUTESP 1029
#define IDC_LASTLISTED 1030
#define IDC_MESSAGE 1031
#define IDSAVE 1032
#define IDM_USERMSG 1034
#define IDM_CHATUSERMSG 1035
#define IDM_NEWUSERMSG 1036
#define IDM_MSGSAVE 1037
#define IDM_EXPERTUSERMSG 1038
#define IDC_MAPPOSITION 1039
#define IDM_SIGNOFF 1039
#define IDC_HOVER 1040
#define BPQMTX 1040
#define IDC_CLICK 1041
#define BPQMCOM 1041
#define IDC_MAPHELP 1042
#define BPQCOPYMON 1042
#define IDC_POPUPTEXT 1043
#define BPQCOPYOUT 1043
#define IDC_SAVEATTACHMENTS 1044
#define BPQCLEARMON 1044
#define CONN_OUT 1045
#define BPQCLEAROUT 1045
#define MSGS_OUT 1046
#define BPQBELLS 1046
#define MSGS_IN 1047
#define BPQCHAT 1047
#define REJECTS_IN 1048
#define BPQHELP 1048
#define REJECTS_OUT 1049
#define BPQStripLF 1049
#define BYTES_OUT 1050
#define BPQLogOutput 1050
#define BYTES_IN 1051
#define BPQLogMonitor 1051
#define LASTCONNECT 1052
#define BPQSendDisconnected 1052
#define CONN_IN 1053
#define BPQFLASHONBELL 1053
#define MONBBS 1060
#define MONCHAT 1061
#define MONTCP 1062
#define IDC_CHATCALLS 1064
#define IDC_CHATCOLOURS 1065
#define RMS_EXPRESS_USER 1066
#define NO_WINLINKdotORG 1067
#define ALLOW_BULLS 1068
#define RMS_SSID1 1070
#define RMS_SSID2 1071
#define RMS_SSID3 1072
#define IDC_SYSTOSYSOPCALL 1073
#define IDC_DONTHOLDNEW 1074
#define IDC_FORWARDTOBBS 1075
#define IDC_BBSTOSYSOPCALL 1076
#define IDC_NOHOMEBBS 1077
#define IDC_NONAME 1078
#define IDC_USERRKILLT 1079
#define IDC_FILTERSAVE 1080
#define IDC_OVERRIDEUNSENT 1081
#define IDC_REJBID 1081
#define IDC_MAILFOR 1082
#define IDC_HOLDBID 1082
#define IDC_SENDWP 1083
#define IDC_FILTERWPB 1084
#define IDC_WPTYPE 1085
#define IDC_WPTO 1086
#define IDC_WPSAVE 1087
#define IDC_PRINTMSG 1088
#define IDC_EXPORT 1089
#define IDM_PROMPTSAVE 1090
#define IDC_RMSBULL 1090
#define BBSUSERCHAT 1091
#define IDC_BBSSAVE 1500
#define ENDUSERCHAT 1501
#define IDM_DISCONNECT 2000
#define IDC_ChatAppl 2001
#define IDC_ChatNodes 2002
#define IDC_DONTCHECKFROM 2010
#define IDM_LOGGING 2100
#define IDC_CHATSAVE 2100
#define IDC_ISP_Gateway_Enabled 3000
#define IDC_MyMailDomain 3001
#define IDC_ISPSMTPName 3002
#define IDC_ISPSMTPPort 3003
#define IDC_ISPPOP3Name 3004
#define IDC_ISPPOP3Port 3005
#define IDC_ISPAccountName 3006
#define IDC_ISPAccountPass 3007
#define IDC_POP3Timer 3008
#define ISP_SMTP_AUTH 3009
#define SMTP_EHELO 3010
#define IDC_ISPSAVE 3100
#define IDC_FWDENABLE 4000
#define IDC_BBS 4001
#define IDC_CALL 4002
#define IDC_TOCALLS 4003
#define IDC_ATCALLS 4004
#define IDC_TOCALLS2 4004
#define IDC_HROUTES 4005
#define IDC_TOCALLS3 4005
#define IDC_REVERSE 4006
#define IDC_TOCALLS4 4006
#define IDC_FWDTIMES 4008
#define IDC_FWDSAVE 4100
#define IDC_HRHELP 4101
#define COPYCONFIG 4102
#define IDC_WP 5000
#define IDC_USER 5000
#define IDC_WPNAME 5001
#define IDC_NAME 5001
#define IDC_ZIP1 5002
#define IDC_PASSWORD 5002
#define IDC_QTH1 5003
#define IDC_ZIP 5003
#define IDC_QTH 5003
#define IDC_HOMEBBS1 5004
#define IDC_HOMEBBS 5004
#define IDC_HOMEBBS2 5005
#define IDC_BBSFLAG 5005
#define IDC_QTH2 5006
#define IDC_PMSFLAG 5006
#define IDC_ZIP2 5007
#define IDC_SYSOP 5007
#define IDC_LASTSEEN 5008
#define IDC_EXPERT 5008
#define IDC_LASTMODIFIED 5009
#define IDC_EXCLUDED 5009
#define IDC_TYPE 5010
#define IDC_EMAIL 5010
#define IDC_CHANGED 5011
#define IDC_HOLDMAIL 5011
#define IDC_SEEN 5012
#define IDC_POLLRMS 5012
#define IDC_SYSOP_IN_LM 5013
#define IDC_UZIP 5014
#define IDC_SYSOP_IN_LMx 5015
#define IDC_UZIP2 5015
#define IDC_CMSPASS 5015
#define IDC_APRSSSID 5016
#define IDD_USERADDED_BOX 5051
#define IDD_UserEditInfo 5051
#define IDC_NTSMPS 5060
#define IDC_APRSMFOR 5061
#define IDC_RMSREDIRECT 5062
#define IDC_ADDUSER 5100
#define IDC_DELETEUSER 5101
#define IDC_SAVEUSER 5102
#define FILTER_FROM 6006
#define FILTER_TO 6007
#define FILTER_VIA 6008
#define EMAILFROM 6009
#define FILTER_BID 6010
#define IDC_MSGTYPE 6101
#define IDC_MSGSTATUS 6102
#define IDC_SAVEMSG 6103
#define IDC_EDITTEXT 6104
#define IDC_SAVETOFILE 6105
#define IDM_FORWARD_ALL 7000
#define IDC_HOLDFROM 7074
#define IDC_HOLDTO 7075
#define IDC_HOLDAT 7076
#define IDC_REJFROM 7077
#define IDC_REJTO 7078
#define IDC_REJAT 7079
#define IDC_HOLDFROM2 7080
#define IDC_REJSYS 7080
#define IDM_HOUSEKEEPING 9000
#define IDM_PR 9001
#define IDM_PUR 9002
#define IDM_PF 9003
#define IDM_PNF 9004
#define IDM_BF 9005
#define IDM_BNF 9006
#define IDM_NTSF 9007
#define IDM_NTSU 9008
#define IDM_LTFROM 9009
#define IDM_LTTO 9010
#define IDM_LTAT 9011
#define IDM_MAINTSAVE 9012
#define IDM_NTSD 9013
#define IDC_MAXMSG 9021
#define IDC_BIDLIFETIME 9022
#define IDC_MAINTINTERVAL 9023
#define IDC_MAINTTIME 9024
#define IDC_LOGLIFETIME 9025
#define IDC_USERLIFETIME 9026
#define IDC_USEB1 9876
#define IDC_READDRESSLOCAL 9877
#define IDC_READDRESSRXED 9878
#define IDC_ALLOWCOMP 9879
#define IDC_BLOCKED 9880
#define IDC_WARNNOROUTE 9881
#define IDD_MAINTRESULTS 30001
#define IDD_EDITWP 30002
#define IDD_UICONFIG 30003
#define IDD_MSGFROMCLIPBOARD 30004
#define IDD_HRHELP 30005
#define IDD_EDITMSGTEXT 30006
#define IDD_UPDATECHATMAP 30007
#define IDD_CHATCOLCONFIG 30008
#define IDR_MENU1 30010
#define IDD_RMSBULLDLG 30011
#define IDM_USERS 40001
#define IDM_FWD 40002
#define IDM_MESSAGES 40003
#define IDM_WRAPTEXT 40004
#define IDM_WARNINPUT 40005
#define IDM_Flash 40006
#define IDM_CLOSEWINDOW 40007
#define IDM_WP 40008
#define IDC_SAVEWP 40009
#define IDC_DELETEWP 40010
#define IDM_DEBUG 40011
#define IDM_LOGBBS 40012
#define IDM_LOGTCP 40013
#define IDM_LOGCHAT 40014
#define ID_ACTIONS_SENDMSGFROMCLIPBOARD 40015
#define IDM_MCMONITOR 40016
#define ID_ACTIONS_UPDATECHATMAPINFO 40017
#define IDM_EDITCHATCOLOURS 40018
#define BPQSAVEREG 40019
#define RESCANMSGS 40020
#define ID_HELP_ONLINEHELP 40021
#define ID_ACTIONS_SENDMESSAGE 40022
#define IDM_IMPORT 40023
#define ID_MULTICAST 40024
#define IDC_DEFAULTNOWINLINK 41001
#define IDC_MULTIP 41002
#define IDC_FOURCHARCONTINENT 41003
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 30013
#define _APS_NEXT_COMMAND_VALUE 40027
#define _APS_NEXT_CONTROL_VALUE 1093
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

6
BPQMailrc.hm Normal file
View File

@ -0,0 +1,6 @@
// Microsoft Developer Studio generated Help ID include file.
// Used by BPQMail.rc
//
#define HFILTER_BID 0x80ca177a
#define HFILTER_VIA 0x80ca1778
#define HIDC_POLLRMS 0x80c81394

193
BPQNRR.c Normal file
View File

@ -0,0 +1,193 @@
/*
Copyright 2001-2022 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
*/
//
// Netrom Record ROute Suport Code for BPQ32 Switch
//
// All code runs from the BPQ32 Received or Timer Routines under Semaphore.
// As most data areas are dynamically allocated, they will not survive a Timer Process Swap.
// Shared data can be used for Config Info.
#define _CRT_SECURE_NO_DEPRECATE
#pragma data_seg("_BPQDATA")
#include "time.h"
#include "stdio.h"
#include <fcntl.h>
//#include "vmm.h"
#include "CHeaders.h"
extern int SENDNETFRAME();
extern VOID Q_ADD();
VOID __cdecl Debugprintf(const char * format, ...);
TRANSPORTENTRY * NRRSession;
/*
datagrams (and other things) to be transported in Netrom L3 frames.
When the frametype is 0x00, the "circuit index" and "circuit id" (first 2
bytes of the transport header) take on a different meaning, something like
"protocol family" and "protocol id". IP over netrom uses 0x0C for both
bytes, TheNet uses 0x00 for both bytes when making L3RTT measurements, and
Xnet uses family 0x00, protocol id 0x01 for Netrom Record Route. I believe
there are authors using other values too. Unfortunately there is no
co-ordinating authority for these numbers, so authors just pick an unused
one.
*/
VOID NRRecordRoute(UCHAR * Buff, int Len)
{
// NRR frame for us. If We originated it, report outcome, else put our call on end, and send back
L3MESSAGEBUFFER * Msg = (L3MESSAGEBUFFER *)Buff;
struct DEST_LIST * DEST;
char Temp[7];
int NRRLen = Len - (21 + MSGHDDRLEN);
UCHAR Flags;
char call[10];
int calllen;
char * Save = Buff;
if (memcmp(&Msg->L4DATA, MYCALL, 7) == 0)
{
UCHAR * BUFFER = GetBuff();
UCHAR * ptr1;
struct _MESSAGE * Msg;
if (BUFFER == NULL)
return;
ptr1 = &BUFFER[MSGHDDRLEN];
*ptr1++ = 0xf0; // PID
ptr1 += sprintf(ptr1, "NRR Response:");
Buff += 21 + MSGHDDRLEN;
Len -= (21 + MSGHDDRLEN);
while (Len > 0)
{
calllen = ConvFromAX25(Buff, call);
call[calllen] = 0;
ptr1 += sprintf(ptr1, " %s", call);
if ((Buff[7] & 0x80) == 0x80) // Check turnround bit
*ptr1++ = '*';
Buff+=8;
Len -= 8;
}
// Add ours on end for neatness
calllen = ConvFromAX25(MYCALL, call);
call[calllen] = 0;
ptr1 += sprintf(ptr1, " %s", call);
*ptr1++ = 0x0d; // CR
Len = (int)(ptr1 - BUFFER);
Msg = (struct _MESSAGE *)BUFFER;
Msg->LENGTH = Len;
Msg->CHAIN = NULL;
C_Q_ADD(&NRRSession->L4TX_Q, (UINT *)BUFFER);
PostDataAvailable(NRRSession);
ReleaseBuffer(Save);
return;
}
// Add our call on end, and increase count
Flags = Buff[Len - 1];
Flags--;
if (Flags && NRRLen < 228) // Dont update if full
{
Flags |= 0x80; // Set End of route bit
Msg->L3PID = NRPID;
memcpy(&Msg->L4DATA[NRRLen], MYCALL, 7);
Msg->L4DATA[NRRLen+7] = Flags;
NRRLen += 8;
}
// We should send it back via our bast route, or recorded route could be wrong
memcpy(Temp, Msg->L3DEST, 7);
memcpy(Msg->L3DEST, Msg->L3SRCE, 7);
memcpy(Msg->L3SRCE, Temp, 7);
if (FindDestination(Msg->L3DEST, &DEST) == 0)
{
ReleaseBuffer(Msg); // CANT FIND DESTINATION
return;
}
Msg->LENGTH = NRRLen + 21 + MSGHDDRLEN;
Debugprintf("NRR TX Len %d Flags %d NRRLen %d", Msg->LENGTH, Flags, NRRLen);
C_Q_ADD(&DEST->DEST_Q, Msg);
}
VOID SendNRRecordRoute(struct DEST_LIST * DEST, TRANSPORTENTRY * Session)
{
L3MESSAGEBUFFER * Msg = GetBuff();
int Stream = 1;
if (Msg == NULL)
return;
NRRSession = Session; // Save Session Pointer for reply
Msg->Port = 0;
Msg->L3PID = NRPID;
memcpy(Msg->L3DEST, DEST->DEST_CALL, 7);
memcpy(Msg->L3SRCE, MYCALL, 7);
Msg->L3TTL = L3LIVES;
Msg->L4ID = 1;
Msg->L4INDEX = 0;
Msg->L4FLAGS = 0;
memcpy(Msg->L4DATA, MYCALL, 7);
Msg->L4DATA[7] = Stream + 28;
Msg->LENGTH = 8 + 21 + MSGHDDRLEN;
C_Q_ADD(&DEST->DEST_Q, Msg);
}

988
BPQRemotePTT.c Normal file
View File

@ -0,0 +1,988 @@
// Program to Convert RTS changes on Virtual COM Port to hamlib PTT commands
// Version 1. 0. 0. 1 December 2020
// Version 1. 0. 2. 1 April 2018
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <Psapi.h>
#define LIBCONFIG_STATIC
#include "libconfig.h"
#include "BPQRemotePTTRes.h"
#define BPQICON 400
WSADATA WsaData; // receives data from WSAStartup
#define WSA_READ WM_USER + 1
HINSTANCE hInst;
char AppName[] = "BPQRemotePTT";
char Title[80] = "BPQRemotePTT";
TCHAR szTitle[]="GPSMuxPC"; // The title bar text
TCHAR szWindowClass[]="GPSMAINWINDOW"; // the main window class name
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
VOID WINAPI CompletedReadRoutine(DWORD dwErr, DWORD cbBytesRead, LPOVERLAPPED lpOverLap);
VOID WINAPI txCompletedReadRoutine(DWORD dwErr, DWORD cbBytesRead, LPOVERLAPPED lpOverLap);
VOID CATThread();
VOID runTimer();
int TimerHandle = 0;
LOGFONT LFTTYFONT ;
HFONT hFont;
struct sockaddr_in sinx;
struct sockaddr rx;
int addrlen = sizeof(struct sockaddr_in);
int HAMLIBPORT; // Port Number for HAMLIB (rigctld) Emulator
char * HAMLIBHOST[128];
BOOL MinimizetoTray=FALSE;
VOID __cdecl Debugprintf(const char * format, ...)
{
char Mess[255];
va_list(arglist);
va_start(arglist, format);
vsprintf(Mess, format, arglist);
strcat(Mess, "\r\n");
OutputDebugString(Mess);
return;
}
char * strlop(char * buf, char delim)
{
// Terminate buf at delim, and return rest of string
char * ptr = strchr(buf, delim);
if (ptr == NULL) return NULL;
*(ptr)++=0;
return ptr;
}
char * RigPort = NULL;
char * RigSpeed = NULL;
HANDLE RigHandle = 0;
int RigType = 0; // Flag for possible RTS/DTR
char BPQHostIP[128];
char PTTCATPort[4][16];
HANDLE PTTCATHandle[4];
short HamLibPort[4];
SOCKET HamLibSock[4]; // rigctld socket
HWND comWnd[4];
HWND portWnd[4];
HWND stateWnd[4];
int stateCtl[4];
struct sockaddr_in remoteDest[4];
int RealMux[4]; // BPQ Virtual or Real
int EndPTTCATThread = 0;
char ConfigName[256] = "BPQRemotePTT.cfg";
BOOL GetStringValue(config_setting_t * group, char * name, char * value)
{
const char * str;
config_setting_t *setting;
setting = config_setting_get_member (group, name);
if (setting)
{
str = config_setting_get_string (setting);
strcpy(value, str);
return TRUE;
}
return FALSE;
}
int GetIntValue(config_setting_t * group, char * name)
{
config_setting_t *setting;
setting = config_setting_get_member (group, name);
if (setting)
return config_setting_get_int (setting);
return 0;
}
VOID SaveStringValue(config_setting_t * group, char * name, char * value)
{
config_setting_t *setting;
setting = config_setting_add(group, name, CONFIG_TYPE_STRING);
if (setting)
config_setting_set_string(setting, value);
}
VOID SaveIntValue(config_setting_t * group, char * name, int value)
{
config_setting_t *setting;
setting = config_setting_add(group, name, CONFIG_TYPE_INT);
if(setting)
config_setting_set_int(setting, value);
}
VOID GetConfig()
{
config_setting_t *group;
config_t cfg;
memset((void *)&cfg, 0, sizeof(config_t));
config_init(&cfg);
if(!config_read_file(&cfg, ConfigName))
{
fprintf(stderr, "Config read error line %d - %s\n", config_error_line(&cfg), config_error_text(&cfg));
config_destroy(&cfg);
return;
}
group = config_lookup(&cfg, "main");
if (group == NULL)
{
config_destroy(&cfg);
return;
}
GetStringValue(group, "BPQHostIP", BPQHostIP);
GetStringValue(group, "COM1", PTTCATPort[0]);
GetStringValue(group, "COM2", PTTCATPort[1]);
GetStringValue(group, "COM3", PTTCATPort[2]);
GetStringValue(group, "COM4", PTTCATPort[3]);
HamLibPort[0] = GetIntValue(group, "HamLibPort1");
HamLibPort[1] = GetIntValue(group, "HamLibPort2");
HamLibPort[2] = GetIntValue(group, "HamLibPort3");
HamLibPort[3] = GetIntValue(group, "HamLibPort4");
config_destroy(&cfg);
}
VOID SaveConfig()
{
config_setting_t *root, *group;
config_t cfg;
// Get rid of old config before saving
config_init(&cfg);
root = config_root_setting(&cfg);
group = config_setting_add(root, "main", CONFIG_TYPE_GROUP);
SaveStringValue(group, "BPQHostIP", BPQHostIP);
SaveStringValue(group, "COM1", PTTCATPort[0]);
SaveStringValue(group, "COM2", PTTCATPort[1]);
SaveStringValue(group, "COM3", PTTCATPort[2]);
SaveStringValue(group, "COM4", PTTCATPort[3]);
SaveIntValue(group, "HamLibPort1", HamLibPort[0]);
SaveIntValue(group, "HamLibPort2", HamLibPort[1]);
SaveIntValue(group, "HamLibPort3", HamLibPort[2]);
SaveIntValue(group, "HamLibPort4", HamLibPort[3]);
if(!config_write_file(&cfg, ConfigName))
{
fprintf(stderr, "Error while writing file.\n");
config_destroy(&cfg);
return;
}
config_destroy(&cfg);
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
if (lpCmdLine[0])
{
// Port Name and Speed for Remote CAT
RigPort = _strdup(lpCmdLine);
RigSpeed = strlop(RigPort, ':');
}
MyRegisterClass(hInstance);
GetConfig();
if (!InitInstance(hInstance, nCmdShow))
return (FALSE);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
KillTimer(NULL, TimerHandle);
return (msg.wParam);
}
//
//
// FUNCTION: InitApplication(HANDLE)
//
// PURPOSE: Initializes window data and registers window class
//
// COMMENTS:
//
// In this function, we initialize a window class by filling out a data
// structure of type WNDCLASS and calling either RegisterClass or
// the internal MyRegisterClass.
//
#define BGCOLOUR RGB(236,233,216)
HBRUSH bgBrush;
HBRUSH RedBrush;
HBRUSH GreenBrush;
HWND hWnd;
BOOL InitApplication(HINSTANCE hInstance)
{
return TRUE;
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
HFONT FAR PASCAL MyCreateFont( void )
{
CHOOSEFONT cf;
LOGFONT lf;
HFONT hfont;
// Initialize members of the CHOOSEFONT structure.
cf.lStructSize = sizeof(CHOOSEFONT);
cf.hwndOwner = (HWND)NULL;
cf.hDC = (HDC)NULL;
cf.lpLogFont = &lf;
cf.iPointSize = 0;
cf.Flags = CF_SCREENFONTS | CF_FIXEDPITCHONLY;
cf.rgbColors = RGB(0,0,0);
cf.lCustData = 0L;
cf.lpfnHook = (LPCFHOOKPROC)NULL;
cf.lpTemplateName = (LPSTR)NULL;
cf.hInstance = (HINSTANCE) NULL;
cf.lpszStyle = (LPSTR)NULL;
cf.nFontType = SCREEN_FONTTYPE;
cf.nSizeMin = 0;
cf.nSizeMax = 0;
// Display the CHOOSEFONT common-dialog box.
ChooseFont(&cf);
// Create a logical font based on the user's
// selection and return a handle identifying
// that font.
hfont = CreateFontIndirect(cf.lpLogFont);
return (hfont);
}
VOID Rig_PTT(int n, BOOL PTTState)
{
char Msg[16];
int Len = sprintf(Msg, "T %d\n", PTTState);
if (HamLibSock[n])
{
send(HamLibSock[n], Msg, Len, 0);
if (PTTState)
SetDlgItemText(hWnd, stateCtl[n], "PTT");
else
SetDlgItemText(hWnd, stateCtl[n], "");
}
}
VOID PTTCATThread()
{
DWORD dwLength = 0;
int Length, ret, i;
UCHAR * ptr1;
UCHAR * ptr2;
UCHAR c;
UCHAR Block[4][80];
UCHAR CurrentState[4] = {0};
#define RTS 2
#define DTR 4
HANDLE Event;
DWORD EvtMask[4];
OVERLAPPED Overlapped[4];
char Port[32];
int PIndex = 0;
int HIndex = 0;
int rc;
EndPTTCATThread = FALSE;
while (PIndex < 4 && PTTCATPort[PIndex][0])
{
RealMux[HIndex] = 0;
sprintf(Port, "\\\\.\\pipe\\BPQ%s", PTTCATPort[PIndex]);
PTTCATHandle[HIndex] = CreateFile(Port, GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
if (PTTCATHandle[HIndex] == INVALID_HANDLE_VALUE)
{
int Err = GetLastError();
// Consoleprintf("PTTMUX port BPQCOM%s Open failed code %d", RIG->PTTCATPort[PIndex], Err);
// See if real com port
sprintf(Port, "\\\\.\\\\%s", PTTCATPort[PIndex]);
PTTCATHandle[HIndex] = CreateFile(Port, GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
RealMux[HIndex] = 1;
if (PTTCATHandle[HIndex] == INVALID_HANDLE_VALUE)
{
int Err = GetLastError();
PTTCATHandle[HIndex] = 0;
Debugprintf("PTTMUX port COM%s Open failed code %d", PTTCATPort[PIndex], Err);
}
else
{
rc = SetCommMask(PTTCATHandle[HIndex], EV_CTS | EV_DSR); // Request notifications
HIndex++;
}
}
else
HIndex++;
PIndex++;
}
if (PIndex == 0)
return; // No ports
Event = CreateEvent(NULL, TRUE, FALSE, NULL);
for (i = 0; i < HIndex; i ++)
{
memset(&Overlapped[i], 0, sizeof(OVERLAPPED));
Overlapped[i].hEvent = Event;
if (RealMux[i])
{
// Request Interface change notifications
rc = WaitCommEvent(PTTCATHandle[i], &EvtMask[i], &Overlapped[i]);
rc = GetLastError();
}
else
{
// Prime a read on each PTTCATHandle
ReadFile(PTTCATHandle[i], Block[i], 80, &Length, &Overlapped[i]);
}
}
while (EndPTTCATThread == FALSE)
{
WaitAgain:
ret = WaitForSingleObject(Event, 1000);
if (ret == WAIT_TIMEOUT)
{
if (EndPTTCATThread)
{
for (i = 0; i < HIndex; i ++)
{
CancelIo(PTTCATHandle[i]);
CloseHandle(PTTCATHandle[i]);
PTTCATHandle[i] = INVALID_HANDLE_VALUE;
}
CloseHandle(Event);
return;
}
goto WaitAgain;
}
ResetEvent(Event);
// See which request(s) have completed
for (i = 0; i < HIndex; i ++)
{
ret = GetOverlappedResult(PTTCATHandle[i], &Overlapped[i], &Length, FALSE);
if (ret)
{
if (RealMux[i])
{
// Request Interface change notifications
DWORD Mask;
GetCommModemStatus(PTTCATHandle[i], &Mask);
if (Mask & MS_CTS_ON)
Rig_PTT(i, TRUE);
else
Rig_PTT(i, FALSE);
memset(&Overlapped[i], 0, sizeof(OVERLAPPED));
Overlapped[i].hEvent = Event;
WaitCommEvent(PTTCATHandle[i], &EvtMask[i], &Overlapped[i]);
}
else
{
ptr1 = Block[i];
ptr2 = Block[i];
while (Length > 0)
{
c = *(ptr1++);
Length--;
if (c == 0xff)
{
c = *(ptr1++);
Length--;
if (c == 0xff) // ff ff means ff
{
Length--;
}
else
{
// This is connection / RTS/DTR statua from other end
// Convert to CAT Command
if (c == CurrentState[i])
continue;
if (c & RTS)
Rig_PTT(i, TRUE);
else
Rig_PTT(i, FALSE);
CurrentState[i] = c;
continue;
}
}
}
memset(&Overlapped[i], 0, sizeof(OVERLAPPED));
Overlapped[i].hEvent = Event;
ReadFile(PTTCATHandle[i], Block[i], 80, &Length, &Overlapped[i]);
}
}
}
}
EndPTTCATThread = FALSE;
}
char ClassName[]="BPQMAIL";
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASS wc;
bgBrush = CreateSolidBrush(BGCOLOUR);
RedBrush = CreateSolidBrush(RGB(255,0,0));
GreenBrush = CreateSolidBrush(RGB(0,255,0));
// BlueBrush = CreateSolidBrush(RGB(0,0,255));
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInstance;
wc.hIcon = NULL; //LoadIcon( hInstance, MAKEINTRESOURCE(IDI_GPSMUXPC));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = bgBrush;
wc.lpszMenuName = NULL;//"MENU_1";
wc.lpszClassName = szWindowClass;
// RegisterClass(&wc);
// wc.lpfnWndProc = TraceWndProc;
// wc.lpszClassName = TraceClassName;
// RegisterClass(&wc);
// wc.lpfnWndProc = ConfigWndProc;
// wc.lpszClassName = ConfigClassName;
return (RegisterClass(&wc));
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
u_long param=1;
BOOL bcopt=TRUE;
int ret;
WNDCLASS wc = {0};
int n = 0;
hInst = hInstance; // Store instance handle in our global variable
WSAStartup(MAKEWORD(2, 0), &WsaData);
hWnd=CreateDialog(hInst,szWindowClass,0,NULL);
if (!hWnd)
{
ret=GetLastError();
return FALSE;
}
// setup default font information
LFTTYFONT.lfHeight = 12;
LFTTYFONT.lfWidth = 8 ;
LFTTYFONT.lfEscapement = 0 ;
LFTTYFONT.lfOrientation = 0 ;
LFTTYFONT.lfWeight = 0 ;
LFTTYFONT.lfItalic = 0 ;
LFTTYFONT.lfUnderline = 0 ;
LFTTYFONT.lfStrikeOut = 0 ;
LFTTYFONT.lfCharSet = OEM_CHARSET ;
LFTTYFONT.lfOutPrecision = OUT_DEFAULT_PRECIS ;
LFTTYFONT.lfClipPrecision = CLIP_DEFAULT_PRECIS ;
LFTTYFONT.lfQuality = DEFAULT_QUALITY ;
LFTTYFONT.lfPitchAndFamily = FIXED_PITCH | FF_MODERN ;
lstrcpy( LFTTYFONT.lfFaceName, "Fixedsys" ) ;
hFont = CreateFontIndirect(&LFTTYFONT) ;
// hFont = MyCreateFont();
SetWindowText(hWnd,Title);
comWnd[0] = GetDlgItem(hWnd, IDC_COM1);
comWnd[1] = GetDlgItem(hWnd, IDC_COM2);
comWnd[2] = GetDlgItem(hWnd, IDC_COM3);
comWnd[3] = GetDlgItem(hWnd, IDC_COM4);
portWnd[0] = GetDlgItem(hWnd, IDC_HAMLIBPORT1);
portWnd[1] = GetDlgItem(hWnd, IDC_HAMLIBPORT2);
portWnd[2] = GetDlgItem(hWnd, IDC_HAMLIBPORT3);
portWnd[3] = GetDlgItem(hWnd, IDC_HAMLIBPORT4);
stateWnd[0] = GetDlgItem(hWnd, IDC_STATE1);
stateWnd[1] = GetDlgItem(hWnd, IDC_STATE2);
stateWnd[2] = GetDlgItem(hWnd, IDC_STATE3);
stateWnd[3] = GetDlgItem(hWnd, IDC_STATE4);
stateCtl[0] = IDC_STATE1;
stateCtl[1] = IDC_STATE2;
stateCtl[2] = IDC_STATE3;
stateCtl[3] = IDC_STATE4;
ShowWindow(hWnd, nCmdShow);
SetDlgItemText(hWnd, IDC_BPQHOST, BPQHostIP);
SetDlgItemText(hWnd, IDC_COM1, PTTCATPort[0]);
SetDlgItemText(hWnd, IDC_COM2, PTTCATPort[1]);
SetDlgItemText(hWnd, IDC_COM3, PTTCATPort[2]);
SetDlgItemText(hWnd, IDC_COM4, PTTCATPort[3]);
SetDlgItemInt(hWnd, IDC_HAMLIBPORT1, HamLibPort[0], 0);
SetDlgItemInt(hWnd, IDC_HAMLIBPORT2, HamLibPort[1], 0);
SetDlgItemInt(hWnd, IDC_HAMLIBPORT3, HamLibPort[2], 0);
SetDlgItemInt(hWnd, IDC_HAMLIBPORT4, HamLibPort[3], 0);
// ioctlsocket (sock, FIONBIO, &param);
if (RigPort)
{
int Speed = 9600;
if (RigSpeed)
Speed = atoi(RigSpeed);
}
TimerHandle = SetTimer(hWnd, 1, 10000, NULL);
runTimer(); // Open Hamlib connections
_beginthread(PTTCATThread, 0);
return TRUE;
}
VOID ConnecttoHAMLIB(int n);
VOID runTimer()
{
int n;
for (n = 0; n < 4; n++)
{
if (HamLibPort[n] && HamLibSock[n] == 0)
{
// try to connect
ConnecttoHAMLIB(n);
}
}
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_TIMER:
runTimer();
break;
case WM_CTLCOLOREDIT:
{
HDC hdc = (HDC) wParam; // handle to display context
HWND hwnd = (HWND) lParam; // handle to control window
int n;
for (n = 0; n < 4; n++)
{
if (hwnd == comWnd[n] && PTTCATPort[n][0])
if (PTTCATHandle[n])
return (INT_PTR)GreenBrush;
else
return (INT_PTR)RedBrush;
if (hwnd == portWnd[n] && HamLibPort[n])
if (HamLibSock[n])
return (INT_PTR)GreenBrush;
else
return (INT_PTR)RedBrush;
}
//return (INT_PTR)RedBrush;
return (DefWindowProc(hWnd, message, wParam, lParam));
}
case WM_SYSCOMMAND:
wmId = LOWORD(wParam); // Remember, these are...
wmEvent = HIWORD(wParam); // ...different for Win32!
switch (wmId)
{
case SC_MINIMIZE:
if (MinimizetoTray)
return ShowWindow(hWnd, SW_HIDE);
else
return (DefWindowProc(hWnd, message, wParam, lParam));
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
int OK;
case IDC_TEST1:
Rig_PTT(0, 1);
Sleep(1500);
Rig_PTT(0, 0);
break;
case IDC_TEST2:
Rig_PTT(1, 1);
Sleep(1500);
Rig_PTT(1, 0);
break;
case IDC_TEST3:
Rig_PTT(2, 1);
Sleep(1500);
Rig_PTT(2, 0);
break;
case IDC_TEST4:
Rig_PTT(3, 1);
Sleep(1500);
Rig_PTT(3, 0);
break;
case IDOK:
GetDlgItemText(hWnd, IDC_BPQHOST, BPQHostIP, 127);
GetDlgItemText(hWnd, IDC_COM1, PTTCATPort[0], 15);
GetDlgItemText(hWnd, IDC_COM2, PTTCATPort[1], 15);
GetDlgItemText(hWnd, IDC_COM3, PTTCATPort[2], 15);
GetDlgItemText(hWnd, IDC_COM4, PTTCATPort[3], 15);
HamLibPort[0] = GetDlgItemInt(hWnd, IDC_HAMLIBPORT1, &OK, 0);
HamLibPort[1] = GetDlgItemInt(hWnd, IDC_HAMLIBPORT2, &OK, 0);
HamLibPort[2] = GetDlgItemInt(hWnd, IDC_HAMLIBPORT3, &OK, 0);
HamLibPort[3] = GetDlgItemInt(hWnd, IDC_HAMLIBPORT4, &OK, 0);
SaveConfig();
// EndPTTCATThread = 1;
// Sleep(1100);
// _beginthread(PTTCATThread, 0);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
}
return (DefWindowProc(hWnd, message, wParam, lParam));
}
void HAMLIBProcessMessage(int n)
{
char RXBuffer[256];
int InputLen = recv(HamLibSock[n], RXBuffer, 256, 0);
if (InputLen == 0 || InputLen == SOCKET_ERROR)
{
if (HamLibSock[n])
closesocket(HamLibSock[n]);
HamLibSock[n] = 0;
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE);
return;
}
}
VOID HAMLIBThread(int n);
VOID ConnecttoHAMLIB(int n)
{
_beginthread(HAMLIBThread, 0, n);
return ;
}
VOID HAMLIBThread(int n)
{
// Opens sockets and looks for data
char Msg[255];
int err, i, ret;
u_long param=1;
BOOL bcopt=TRUE;
fd_set readfs;
fd_set errorfs;
struct timeval timeout;
if (HamLibSock[n])
closesocket(HamLibSock[n]);
// Param is IPADDR:PORT. Only Allow numeric addresses
if (HamLibPort[n] == 0)
return;
remoteDest[n].sin_family = AF_INET;
remoteDest[n].sin_addr.s_addr = inet_addr(BPQHostIP);
remoteDest[n].sin_port = htons(HamLibPort[n]);
HamLibSock[n] = 0;
HamLibSock[n] = socket(AF_INET,SOCK_STREAM,0);
if (HamLibSock[n] == INVALID_SOCKET)
{
i=sprintf(Msg, "Socket Failed for HAMLIB socket - error code = %d\r\n", WSAGetLastError());
Debugprintf(Msg);
return;
}
setsockopt(HamLibSock[n], SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt, 4);
setsockopt(HamLibSock[n], IPPROTO_TCP, TCP_NODELAY, (const char FAR *)&bcopt, 4);
if (connect(HamLibSock[n],(LPSOCKADDR)&remoteDest[n],sizeof(remoteDest[n])) == 0)
{
//
// Connected successful
//
}
else
{
err=WSAGetLastError();
i=sprintf(Msg, "Connect Failed for HAMLIB socket %d - error code = %d\r\n", n, err);
Debugprintf(Msg);
closesocket(HamLibSock[n]);
HamLibSock[n] = 0;
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE);
return;
}
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE);
ret = GetLastError();
while (HamLibSock[n])
{
FD_ZERO(&readfs);
FD_ZERO(&errorfs);
FD_SET(HamLibSock[n],&readfs);
FD_SET(HamLibSock[n],&errorfs);
timeout.tv_sec = 60;
timeout.tv_usec = 0;
ret = select((int)HamLibSock[n] + 1, &readfs, NULL, &errorfs, &timeout);
if (ret == SOCKET_ERROR)
{
Debugprintf("HAMLIB Select failed %d ", WSAGetLastError());
goto Lost;
}
if (ret > 0)
{
// See what happened
if (FD_ISSET(HamLibSock[n], &readfs))
{
HAMLIBProcessMessage(n);
}
if (FD_ISSET(HamLibSock[n], &errorfs))
{
Lost:
sprintf(Msg, "HAMLIB Connection lost for Port %d\r\n", n);
Debugprintf(Msg);
closesocket(HamLibSock[n]);
HamLibSock[n] = 0;
RedrawWindow(hWnd, NULL, NULL, 0);
return;
}
continue;
}
else
{
}
}
sprintf(Msg, "HAMLIB Thread Terminated Port %d\r\n", n);
Debugprintf(Msg);
}

12
BPQRemotePTT.cfg Normal file
View File

@ -0,0 +1,12 @@
main :
{
BPQHostIP = "192.168.1.64";
COM1 = "COM43";
COM2 = "";
COM3 = "";
COM4 = "";
HamLibPort1 = 4534;
HamLibPort2 = 0;
HamLibPort3 = 0;
HamLibPort4 = 0;
};

173
BPQRemotePTT.rc Normal file
View File

@ -0,0 +1,173 @@
//Microsoft Developer Studio generated resource script.
//
#include "BPQRemotePTTRes.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.K.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
BPQICON ICON DISCARDABLE "..\\BPQIcon.ICO"
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,3,2
PRODUCTVERSION 1,0,3,2
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080904b0"
BEGIN
VALUE "Comments", "Program to Convert RTS changes on Virtual COM Port to hamlib PTT commands\0"
VALUE "CompanyName", " \0"
VALUE "FileDescription", "BPQRemotePTT\0"
VALUE "FileVersion", "1. 0. 3. 2\0"
VALUE "InternalName", "bpq32\0"
VALUE "LegalCopyright", "Copyright © 2020 G8BPQ\0"
VALUE "OriginalFilename", "\\BPQRemotePTT.exe\0"
VALUE "ProductName", "BPQRemotePTT\0"
VALUE "ProductVersion", "1. 0. 1. 1\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x809, 1200
END
END
#endif // !_MAC
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"BPQRemotePTTRes.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
GPSMAINWINDOW DIALOG FIXED IMPURE 100, 100, 335, 162
STYLE DS_MODALFRAME | DS_3DLOOK | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "GPS Mux Version 1.0.0"
CLASS "GPSMAINWINDOW"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,150,116,50,14
EDITTEXT IDC_BPQHOST,71,7,72,14,ES_AUTOHSCROLL
LTEXT "BPQ Host IP",IDC_STATIC,9,7,55,11
EDITTEXT IDC_COM1,71,27,46,14,ES_AUTOHSCROLL
LTEXT "COM Port",IDC_STATIC,9,29,55,14
EDITTEXT IDC_HAMLIBPORT1,186,27,46,14,ES_AUTOHSCROLL
LTEXT "HAMLIB Port",IDC_STATIC,124,28,55,14
LTEXT "",IDC_STATE1,243,28,24,14
PUSHBUTTON "Test",IDC_TEST1,277,27,50,14
EDITTEXT IDC_COM2,71,47,46,14,ES_AUTOHSCROLL
LTEXT "COM Port",IDC_STATIC,9,48,55,14
EDITTEXT IDC_HAMLIBPORT2,185,47,46,14,ES_AUTOHSCROLL
LTEXT "HAMLIB Port",IDC_STATIC,123,47,55,14
LTEXT "",IDC_STATE2,243,47,24,14
PUSHBUTTON "Test",IDC_TEST2,277,47,50,14
EDITTEXT IDC_COM3,71,66,46,14,ES_AUTOHSCROLL
LTEXT "COM Port",IDC_STATIC,9,69,55,14
EDITTEXT IDC_HAMLIBPORT3,186,66,46,14,ES_AUTOHSCROLL
LTEXT "HAMLIB Port",IDC_STATIC,124,67,55,14
LTEXT "",IDC_STATE3,244,66,24,14
PUSHBUTTON "Test",IDC_TEST3,277,66,50,14
EDITTEXT IDC_COM4,71,86,46,14,ES_AUTOHSCROLL
LTEXT "COM Port",IDC_STATIC,9,88,55,14
EDITTEXT IDC_HAMLIBPORT4,186,86,46,14,ES_AUTOHSCROLL
LTEXT "HAMLIB Port",IDC_STATIC,124,87,55,14
LTEXT "",IDC_STATE4,243,87,24,14
PUSHBUTTON "Test",IDC_TEST4,277,86,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
"GPSMAINWINDOW", DIALOG
BEGIN
BOTTOMMARGIN, 144
END
END
#endif // APSTUDIO_INVOKED
#endif // English (U.K.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

32
BPQRemotePTTRes.h Normal file
View File

@ -0,0 +1,32 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by BPQRemotePTT.rc
//
#define IDC_BPQHOST 1000
#define IDC_COM1 1001
#define IDC_HAMLIBPORT1 1002
#define IDC_COM2 1003
#define IDC_STATE1 1004
#define IDC_TEST1 1005
#define IDC_HAMLIBPORT2 1006
#define IDC_STATE2 1007
#define IDC_TEST2 1008
#define IDC_COM3 1009
#define IDC_HAMLIBPORT3 1010
#define IDC_STATE3 1011
#define IDC_TEST3 1012
#define IDC_COM4 1013
#define IDC_HAMLIBPORT4 1014
#define IDC_STATE4 1015
#define IDC_TEST4 1016
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1006
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

4854
BPQTermMDI.c Normal file

File diff suppressed because it is too large Load Diff

246
BPQWinAPP.c Normal file
View File

@ -0,0 +1,246 @@
// Version 1. 0. 2. 1 October 2010
// Add Delay on start option, and dynamically load bpq32
// Version 1. 0. 3. 1 October 2011
// Call CloseBPQ32 on exit
// Version 2.0.1.1 July 2002
// Add try/except round main loop
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <time.h>
#include "DbgHelp.h"
//#define DYNLOADBPQ // Dynamically Load BPQ32.dll
#include "..\Include\bpq32.h"
VOID APIENTRY SetFrameWnd(HWND hWnd);
#define BPQICON 400
HINSTANCE hInst;
char AppName[] = "BPQ32";
char Title[80] = "Program to hold BPQ32.dll in memory";
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(CONST WNDCLASS*);
BOOL InitApplication(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK FrameWndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
HWND FrameWnd;
int TimerHandle = 0;
VOID __cdecl Debugprintf(const char * format, ...)
{
char Mess[8192];
va_list(arglist);int Len;
va_start(arglist, format);
Len = vsprintf_s(Mess, sizeof(Mess), format, arglist);
strcat_s(Mess, 999, "\r\n");
OutputDebugString(Mess);
return;
}
VOID WriteMiniDump()
{
#ifdef WIN32
HANDLE hFile;
BOOL ret;
char FN[256];
sprintf(FN, "%s/Logs/MiniDump%x.dmp", GetBPQDirectory(), time(NULL));
hFile = CreateFile(FN, GENERIC_READ | GENERIC_WRITE,
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
{
// Create the minidump
ret = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
hFile, MiniDumpNormal, 0, 0, 0 );
if(!ret)
Debugprintf("MiniDumpWriteDump failed. Error: %u", GetLastError());
else
Debugprintf("Minidump %s created.", FN);
CloseHandle(hFile);
}
#endif
}
//
// FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
//
// PURPOSE: Entry point for the application.
//
// COMMENTS:
//
// This function initializes the application and processes the
// message loop.
//
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
BOOL bRet;
struct _EXCEPTION_POINTERS exinfo;
Debugprintf("BPQ32.exe %s Entered", lpCmdLine);
if (_stricmp(lpCmdLine, "Wait") == 0) // If AutoRestart then Delay 5 Secs
Sleep(5000);
// GetAPI();
if (!InitInstance(hInstance, nCmdShow))
return (FALSE);
// Main message loop:
__try
{
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
Debugprintf("GetMessage Returned -1 %d", GetLastError());
break;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
#define EXCEPTMSG "BPQ32.exe Main Loop"
#include "StdExcept.c"
}
Debugprintf("BPQ32.exe exiting %d", msg.message);
KillTimer(NULL,TimerHandle);
CloseBPQ32(); // Close Ext Drivers if last bpq32 process
return (msg.wParam);
}
//
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
WNDCLASSEX wndclassMainFrame;
hInst = hInstance; // Store instance handle in our global variable
wndclassMainFrame.cbSize = sizeof(WNDCLASSEX);
wndclassMainFrame.style = CS_HREDRAW | CS_VREDRAW;
wndclassMainFrame.lpfnWndProc = FrameWndProc;
wndclassMainFrame.cbClsExtra = 0;
wndclassMainFrame.cbWndExtra = 0;
wndclassMainFrame.hInstance = hInstance;
wndclassMainFrame.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(BPQICON));
wndclassMainFrame.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclassMainFrame.hbrBackground = (HBRUSH) GetStockObject(GRAY_BRUSH);
wndclassMainFrame.lpszMenuName = NULL;
wndclassMainFrame.lpszClassName = AppName;
wndclassMainFrame.hIconSm = NULL;
if(!RegisterClassEx(&wndclassMainFrame))
{
Debugprintf("BPQ32.exe RC failed %d", GetLastError());
return 0;
}
FrameWnd = CreateWindow(AppName,
"BPQ32",
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
CW_USEDEFAULT, // allows system choose an x position
CW_USEDEFAULT, // allows system choose a y position
CW_USEDEFAULT, // width, CW_USEDEFAULT allows system to choose height and width
CW_USEDEFAULT, // height, CW_USEDEFAULT ignores heights as this is set by setting
// CW_USEDEFAULT in width above.
HWND_MESSAGE, // Message only Window
NULL, // handle to menu
hInstance, // handle to the instance of module
NULL); // Long pointer to a value to be passed to the window through the
// CREATESTRUCT structure passed in the lParam parameter the WM_CREATE message
TimerHandle=SetTimer(FrameWnd,WM_TIMER,5000,NULL);
CheckTimer();
return (TRUE);
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_TIMER:
CheckTimer();
return 0;
case WM_CLOSE:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}

71
BPQWinAPP.rc Normal file
View File

@ -0,0 +1,71 @@
//Microsoft Developer Studio generated resource script.
//
//#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "windows.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.K.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
#pragma code_page(1252)
#endif //_WIN32
#define BPQICON 400
BPQICON ICON DISCARDABLE "..\\bpqicon.ico"
//
// Version
//
#define TEXTVER "2. 0. 1. 1\0"
#define BINVER 2, 0, 1, 1
VS_VERSION_INFO VERSIONINFO
FILEVERSION BINVER
PRODUCTVERSION BINVER
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080904b0"
BEGIN
VALUE "Comments", "Program to hold BPQ32.dll in memory\0"
VALUE "CompanyName", " \0"
VALUE "FileDescription", "bpq32\0"
VALUE "FileVersion", TEXTVER
VALUE "InternalName", "bpq32\0"
VALUE "LegalCopyright", "Copyright © 2006-2011 G8BPQ\0"
VALUE "OriginalFilename", "bpq32.exe\0"
VALUE "ProductName", " bpq32\0"
VALUE "ProductVersion", TEXTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x809, 1200
END
END
#endif // not APSTUDIO_INVOKED

760
BPQtoAGW.c Normal file
View File

@ -0,0 +1,760 @@
/*
Copyright 2001-2022 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
*/
//
// DLL to provide interface to allow G8BPQ switch to use AGWPE as a Port Driver
// 32bit environment,
//
// Uses BPQ EXTERNAL interface
//
// Version 1.0 January 2005 - Initial Version
//
// Version 1.1 August 2005
//
// Treat NULL string in Registry as use current directory
// Version 1.2 January 2006
// Support multiple commections (not quire yet!)
// Fix memory leak when AGEPE not running
// Version 1.3 March 2006
// Support multiple connections
// Version 1.4 October 1006
// Write diagmnostics to BPQ console window instead of STDOUT
// Version 1.5 February 2008
// Changes for dynamic unload of bpq32.dll
// Version 1.5.1 September 2010
// Add option to get config from BPQ32.cfg
#define _CRT_SECURE_NO_DEPRECATE
#include "CHeaders.h"
#ifndef WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#include "bpq32.h"
#ifndef LINBPQ
#include "kernelresource.h"
#include <process.h>
#endif
#include <time.h>
#define VERSION_MAJOR 2
#define VERSION_MINOR 0
//uintptr_t _beginthread(void( *start_address )( int ), unsigned stack_size, int arglist);
//int ResetExtDriver(int num);
void ConnecttoAGWThread(void * portptr);
VOID __cdecl Consoleprintf(const char * format, ...);
void CreateMHWindow();
int Update_MH_List(struct in_addr ipad, char * call, char proto);
static BOOL ReadConfigFile(int Port);
int ConnecttoAGW(int port);
int ProcessReceivedData(int bpqport);
static int ProcessLine(char * buf, int Port, BOOL CheckPort);
extern UCHAR BPQDirectory[];
#pragma pack(1)
static struct AGWHEADER
{
byte Port;
byte filler1[3];
char DataKind;
byte filler2;
unsigned char PID;
byte filler3;
unsigned char callfrom[10];
unsigned char callto[10];
int DataLength;
int reserved;
} AGWHeader;
static struct AGWHEADER RXHeader;
#pragma pack()
#define MAXAGWPORTS 16
//LOGFONT LFTTYFONT ;
//HFONT hFont ;
static int AGWChannel[MAXBPQPORTS+1]; // BPQ Port to AGW Port
static int BPQPort[MAXAGWPORTS][MAXBPQPORTS+1]; // AGW Port and Connection to BPQ Port
static void * AGWtoBPQ_Q[MAXBPQPORTS+1]; // Frames for BPQ, indexed by BPQ Port
static void * BPQtoAGW_Q[MAXBPQPORTS+1]; // Frames for AGW. indexed by AGW port. Only used it TCP session is blocked
// Each port may be on a different machine. We only open one connection to each AGW instance
static SOCKET AGWSock[MAXBPQPORTS+1]; // Socket, indexed by BPQ Port
BOOL Alerted[MAXBPQPORTS+1]; // Error msg sent
static int MasterPort[MAXBPQPORTS+1]; // Pointer to first BPQ port for a specific AGW host
static char * AGWSignon[MAXBPQPORTS+1]; // Pointer to message for secure signin
static char * AGWHostName[MAXBPQPORTS+1]; // AGW Host - may be dotted decimal or DNS Name
static unsigned int AGWInst = 0;
static int AttachedProcesses=0;
static HWND hResWnd,hMHWnd;
static BOOL GotMsg;
static HANDLE STDOUT=0;
//SOCKET sock;
static SOCKADDR_IN sinx;
static SOCKADDR_IN rxaddr;
static SOCKADDR_IN destaddr[MAXBPQPORTS+1];
static int addrlen=sizeof(sinx);
//static short AGWPort=0;
static time_t ltime,lasttime[MAXBPQPORTS+1];
static BOOL CONNECTED[MAXBPQPORTS+1];
static BOOL CONNECTING[MAXBPQPORTS+1];
//HANDLE hInstance;
static fd_set readfs;
static fd_set writefs;
static fd_set errorfs;
static struct timeval timeout;
static size_t ExtProc(int fn, int port, PMESSAGE buff)
{
int i,winerr;
int datalen;
PMSGWITHLEN buffptr;
char txbuff[500];
unsigned int bytes,txlen=0;
char ErrMsg[255];
switch (fn)
{
case 1: // poll
if (MasterPort[port] == port)
{
SOCKET sock = AGWSock[port];
// Only on first port using a host
if (CONNECTED[port] == FALSE && CONNECTING[port] == FALSE)
{
// See if time to reconnect
time( &ltime );
if (ltime-lasttime[port] > 9 )
{
ConnecttoAGW(port);
lasttime[port]=ltime;
}
}
FD_ZERO(&readfs);
if (CONNECTED[port]) FD_SET(sock,&readfs);
FD_ZERO(&writefs);
if (BPQtoAGW_Q[port]) FD_SET(sock,&writefs); // Need notification of busy clearing
FD_ZERO(&errorfs);
if (CONNECTED[port]) FD_SET(sock,&errorfs);
if (select((int)sock+1, &readfs, &writefs, &errorfs, &timeout) > 0)
{
// See what happened
if (FD_ISSET(sock, &readfs))
{
// data available
ProcessReceivedData(port);
}
if (FD_ISSET(sock, &writefs))
{
if (BPQtoAGW_Q[port] == 0)
{
}
else
{
// Write block has cleared. Send rest of packet
buffptr = Q_REM(&BPQtoAGW_Q[port]);
txlen = buffptr->Len;
memcpy(txbuff, buffptr->Data, txlen);
bytes = send(AGWSock[port], (const char FAR *)&txbuff, txlen, 0);
ReleaseBuffer(buffptr);
}
}
if (FD_ISSET(sock, &errorfs))
{
sprintf(ErrMsg, "AGW Connection lost for BPQ Port %d\n", port);
Alerted[port] = FALSE;
WritetoConsole(ErrMsg);
CONNECTED[port]=FALSE;
}
}
}
// See if any frames for this port
if (AGWtoBPQ_Q[port] !=0)
{
buffptr=Q_REM(&AGWtoBPQ_Q[port]);
datalen = buffptr->Len - 1;
memcpy(buff->DEST, &buffptr->Data[1] , datalen); // Data goes to +7, but we have an extra byte
datalen += MSGHDDRLEN;
buff->LENGTH = datalen;
ReleaseBuffer(buffptr);
return (1);
}
return (0);
case 2: // send
if (!CONNECTED[MasterPort[port]]) return 0; // Don't try if not connected
if (BPQtoAGW_Q[MasterPort[port]]) return 0; // Socket is blocked - just drop packets
// till it clears
// AGW has a control byte on front, so only subtract 6 from BPQ length
txlen = GetLengthfromBuffer((PDATAMESSAGE)buff);
txlen -= (MSGHDDRLEN - 1);
AGWHeader.Port=AGWChannel[port];
AGWHeader.DataKind='K'; // raw send
#ifdef __BIG_ENDIAN__
AGWHeader.DataLength = reverse(txlen);
#else
AGWHeader.DataLength = txlen;
#endif
memcpy(&txbuff,&AGWHeader,sizeof(AGWHeader));
memcpy(&txbuff[sizeof(AGWHeader) + 1], &buff->DEST, txlen);
txbuff[sizeof(AGWHeader)]=0;
txlen+=sizeof(AGWHeader);
bytes=send(AGWSock[MasterPort[port]],(const char FAR *)&txbuff, txlen, 0);
if (bytes != txlen)
{
// AGW doesn't seem to recover from a blocked write. For now just reset
winerr = WSAGetLastError();
i = sprintf(ErrMsg, "AGW Write Failed for port %d - error code = %d\n", port, winerr);
WritetoConsole(ErrMsg);
closesocket(AGWSock[MasterPort[port]]);
CONNECTED[MasterPort[port]] = FALSE;
return (0);
}
return (0);
case 3: // CHECK IF OK TO SEND
return (0); // OK
break;
case 4: // reinit
// return(ReadConfigFile("BPQAXIP.CFG"));
return (0);
}
return 0;
}
void * AGWExtInit(struct PORTCONTROL * PortEntry)
{
int i, port;
char Msg[255];
//
// Will be called once for each AGW port to be mapped to a BPQ Port
// The AGW port number is in CHANNEL - A=0, B=1 etc
//
// The Socket to connect to is in IOBASE
//
port=PortEntry->PORTNUMBER;
ReadConfigFile(port);
AGWChannel[port]=PortEntry->CHANNELNUM-65;
if (destaddr[port].sin_family == 0)
{
// not defined in config file
destaddr[port].sin_family = AF_INET;
destaddr[port].sin_port = htons(PortEntry->IOBASE);
AGWHostName[port]=malloc(10);
if (AGWHostName[port] != NULL)
strcpy(AGWHostName[port],"127.0.0.1");
}
i=sprintf(Msg,"AGW Port %d Host %s %d\n",AGWChannel[port]+1,AGWHostName[port],htons(destaddr[port].sin_port));
WritetoConsole(Msg);
// See if we already have a port for this host
MasterPort[port]=port;
for (i=1;i<port;i++)
{
if (i == port) continue;
if (destaddr[i].sin_port == destaddr[port].sin_port &&
_stricmp(AGWHostName[i],AGWHostName[port]) == 0)
{
MasterPort[port]=i;
break;
}
}
Alerted[port] = FALSE;
BPQPort[PortEntry->CHANNELNUM-65][MasterPort[port]]=PortEntry->PORTNUMBER;
if (MasterPort[port] == port)
ConnecttoAGW(port);
time(&lasttime[port]); // Get initial time value
return ExtProc;
}
/*
# Config file for BPQtoAGW
#
# For each AGW port defined in BPQCFG.TXT, Add a line here
# Format is BPQ Port, Host/IP Address, Port
#
# Any unspecified Ports will use 127.0.0.1 and port for BPQCFG.TXT IOADDR field
#
1 127.0.0.1 8000
2 127.0.0.1 8001
*/
BOOL ReadConfigFile(int Port)
{
char buf[256],errbuf[256];
char * Config;
Config = PortConfig[Port];
if (Config)
{
// Using config from bpq32.cfg
char * ptr1 = Config, * ptr2;
ptr2 = strchr(ptr1, 13);
while(ptr2)
{
memcpy(buf, ptr1, ptr2 - ptr1);
buf[ptr2 - ptr1] = 0;
ptr1 = ptr2 + 2;
ptr2 = strchr(ptr1, 13);
strcpy(errbuf,buf); // save in case of error
if (!ProcessLine(buf, Port, FALSE))
{
WritetoConsole("BPQtoAGW - Bad config record ");
Consoleprintf(errbuf);
}
}
return (TRUE);
}
return (TRUE);
}
static int ProcessLine(char * buf, int Port, BOOL CheckPort)
{
char * ptr,* p_user,* p_password;
char * p_ipad;
char * p_udpport;
unsigned short AGWport;
int BPQport;
int len=510;
ptr = strtok(buf, " \t\n\r");
if(ptr == NULL) return (TRUE);
if(*ptr =='#') return (TRUE); // comment
if(*ptr ==';') return (TRUE); // comment
if (CheckPort)
{
p_ipad = strtok(NULL, " \t\n\r");
if (p_ipad == NULL) return (FALSE);
BPQport = atoi(ptr);
if (Port != BPQport) return TRUE; // Not for us
}
else
{
BPQport = Port;
p_ipad = ptr;
}
if(BPQport > 0 && BPQport < MAXBPQPORTS)
{
p_udpport = strtok(NULL, " \t\n\r");
if (p_udpport == NULL) return (FALSE);
AGWport = atoi(p_udpport);
destaddr[BPQport].sin_family = AF_INET;
destaddr[BPQport].sin_port = htons(AGWport);
AGWHostName[BPQport]=malloc(strlen(p_ipad)+1);
if (AGWHostName[BPQport] == NULL) return TRUE;
strcpy(AGWHostName[BPQport],p_ipad);
p_user = strtok(NULL, " \t\n\r");
if (p_user == NULL) return (TRUE);
p_password = strtok(NULL, " \t\n\r");
if (p_password == NULL) return (TRUE);
// Allocate buffer for signon message
AGWSignon[BPQport]=malloc(546);
if (AGWSignon[BPQport] == NULL) return TRUE;
memset(AGWSignon[BPQport],0,546);
AGWSignon[BPQport][4]='P';
memcpy(&AGWSignon[BPQport][28],&len,4);
strcpy(&AGWSignon[BPQport][36],p_user);
strcpy(&AGWSignon[BPQport][291],p_password);
return (TRUE);
}
//
// Bad line
//
return (FALSE);
}
int ConnecttoAGW(int port)
{
_beginthread(ConnecttoAGWThread, 0, (void *)(size_t)port);
return 0;
}
VOID ConnecttoAGWThread(void * portptr)
{
int port = (int)(size_t)portptr;
char Msg[255];
int err,i;
u_long param=1;
BOOL bcopt=TRUE;
struct hostent * HostEnt;
// Only called for the first BPQ port for a particular host/port combination
destaddr[port].sin_addr.s_addr = inet_addr(AGWHostName[port]);
if (destaddr[port].sin_addr.s_addr == INADDR_NONE)
{
// Resolve name to address
HostEnt = gethostbyname (AGWHostName[port]);
if (!HostEnt) return; // Resolve failed
memcpy(&destaddr[port].sin_addr.s_addr,HostEnt->h_addr,4);
}
AGWSock[port]=socket(AF_INET,SOCK_STREAM,0);
if (AGWSock[port] == INVALID_SOCKET)
{
i=sprintf(Msg, "Socket Failed for AGW socket - error code = %d\r\n", WSAGetLastError());
WritetoConsole(Msg);
return;
}
setsockopt (AGWSock[port],SOL_SOCKET,SO_REUSEADDR,(const char FAR *)&bcopt,4);
sinx.sin_family = AF_INET;
sinx.sin_addr.s_addr = INADDR_ANY;
sinx.sin_port = 0;
if (bind(AGWSock[port], (LPSOCKADDR) &sinx, addrlen) != 0 )
{
//
// Bind Failed
//
i=sprintf(Msg, "Bind Failed for AGW socket - error code = %d\r\n", WSAGetLastError());
WritetoConsole(Msg);
closesocket(AGWSock[port]);
return;
}
CONNECTING[port] = TRUE;
if (connect(AGWSock[port],(LPSOCKADDR) &destaddr[port],sizeof(destaddr[port])) == 0)
{
//
// Connected successful
//
CONNECTED[port] = TRUE;
CONNECTING[port] = FALSE;
ioctlsocket (AGWSock[port],FIONBIO,&param);
// If required, send signon
if (AGWSignon[port])
send(AGWSock[port],AGWSignon[port],546,0);
// Request Raw Frames
AGWHeader.Port=0;
AGWHeader.DataKind='k';
AGWHeader.DataLength=0;
send(AGWSock[port],(const char FAR *)&AGWHeader,sizeof(AGWHeader),0);
return;
}
else
{
err=WSAGetLastError();
//
// Connect failed
//
if (Alerted[port] == FALSE)
{
sprintf(Msg, "Connect Failed for AGW Port %d - error code = %d\n", port, err);
WritetoConsole(Msg);
Alerted[port] = TRUE;
}
closesocket(AGWSock[port]);
CONNECTING[port] = FALSE;
return;
}
}
int ProcessReceivedData(int port)
{
unsigned int bytes;
int datalen,i;
char ErrMsg[255];
char Message[500];
PMSGWITHLEN buffptr;
// Need to extract messages from byte stream
// Use MSG_PEEK to ensure whole message is available
bytes = recv(AGWSock[port],(char *)&RXHeader,sizeof(RXHeader),MSG_PEEK);
if (bytes == SOCKET_ERROR)
{
i=sprintf(ErrMsg, "Read Failed for AGW socket - error code = %d\r\n", WSAGetLastError());
WritetoConsole(ErrMsg);
closesocket(AGWSock[port]);
CONNECTED[port]=FALSE;
return (0);
}
if (bytes == 0)
{
// zero bytes means connection closed
i=sprintf(ErrMsg, "AGW Connection closed for BPQ Port %d\r\n", port);
WritetoConsole(ErrMsg);
CONNECTED[port]=FALSE;
return (0);
}
// Have some data
if (bytes == sizeof(RXHeader))
{
// Have a header - see if we have any associated data
datalen=RXHeader.DataLength;
#ifdef __BIG_ENDIAN__
datalen = reverse(datalen);
#endif
if (datalen > 0)
{
// Need data - See if enough there
bytes = recv(AGWSock[port],(char *)&Message,sizeof(RXHeader)+datalen,MSG_PEEK);
}
if (bytes == sizeof(RXHeader)+datalen)
{
bytes = recv(AGWSock[port],(char *)&RXHeader,sizeof(RXHeader),0);
if (datalen > 0)
{
bytes = recv(AGWSock[port],(char *)&Message,datalen,0);
}
// Have header, and data if needed
// Only use frame type K
if (RXHeader.DataKind == 'K') // raw data
{
// Make sure it is for a port we want - we may not be using all AGW ports
if (BPQPort[RXHeader.Port][MasterPort[port]] == 0)
return (0);
// Get a buffer
buffptr = GetBuff();
if (buffptr == 0) return (0); // No buffers, so ignore
buffptr->Len = datalen;
memcpy(buffptr->Data, &Message, datalen);
C_Q_ADD(&AGWtoBPQ_Q[BPQPort[RXHeader.Port][MasterPort[port]]], buffptr);
}
return (0);
}
// Have header, but not sufficient data
return (0);
}
// Dont have at least header bytes
return (0);
}

6732
Bpq32.c Normal file

File diff suppressed because it is too large Load Diff

147
BpqTermMDI.h Normal file
View File

@ -0,0 +1,147 @@
#define MAXSTACK 20
#define INPUTLEN 512
#define MAXLINES 1000
#define LINELEN 200
#define BPQICON 2
#define IDR_MENU1 101
#define BPQMENU 101
#define BPQCONNECT 102
#define BPQDISCONNECT 103
#define IDD_FONT 105
#define ID_WARNWRAP 415
#define ID_WRAP 416
#define ID_FLASHONBELL 417
#define IDC_FONTWIDTH 1008
#define IDC_FONTNAME 1009
#define IDC_CODEPAGE 1010
#define IDC_CHARSET 1011
#define IDC_FONTSIZE 1012
#define BPQMTX 1164
#define BPQMCOM 1165
#define BPQCOPYMON 1166
#define BPQCOPYOUT 1167
#define BPQCLEARMON 1168
#define BPQCLEAROUT 1169
#define BPQBELLS 1170
#define BPQCHAT 1171
#define BPQHELP 1172
#define BPQStripLF 1173
#define BPQLogOutput 1174
#define BPQLogMonitor 1175
#define BPQSendDisconnected 1176
#define BPQMNODES 1177
#define MONCOLOUR 1178
#define CHATTERM 1179
#define IDM_CLOSEWINDOW 1180
#define MONITORAPRS 1181
#define MONLOCALTIME 1182
#define MON_UI_ONLY 40006
#define StopALLMon 40007
#define IDR_MAINFRAME_MENU 191
#define TERM_MENU 192
#define MON_MENU 193
#define IDI_SIGMA_MAIN_ICON 104
#define IDI_SYSTEM_INFO 106
#define RTFCOPY 30000
#define ID_INFORMATION_SYSTEMINFORMATION 30001
#define ID_HELP_ABOUT 30002
#define ID_WINDOWS_CASCADE 30003
#define ID_FILE_EXIT 30004
#define ID_WINDOWS_TILE 30005
#define ID_NEWWINDOW 30006
#define ID_WINDOWS_RESTORE 30007
#define ID_SETUP_FONT 30008
#define ID_ACTION_RESETWINDOWSPLIT 30009
#define BPQBASE 40100
#define IDM_FIRSTCHILD 50000 // used in structure when creating mdi client area for the main frame
// Port monitoring flags use BPQBASE -> BPQBASE+100
struct ConsoleInfo
{
struct ConsoleInfo * next;
int BPQStream;
BOOL Active;
int Incoming;
WNDPROC wpOrigInputProc;
HWND hConsole;
HWND hwndInput;
HWND hwndOutput;
HMENU hMenu; // handle of menu
RECT ConsoleRect;
RECT OutputRect;
int CharWidth;
int Height, Width, Top, Left;
int ClientHeight, ClientWidth;
char kbbuf[INPUTLEN];
int kbptr;
int readbufflen; // Current Length
char * readbuff; // Malloc'ed
char * KbdStack[MAXSTACK];
int StackIndex;
// BOOL Bells;
// BOOL FlashOnBell; // Flash instead of Beep
BOOL StripLF;
// BOOL WarnWrap;
// BOOL FlashOnConnect;
// BOOL WrapInput;
// BOOL CloseWindowOnBye;
unsigned int WrapLen;
int WarnLen;
int maxlinelen;
int PartLinePtr;
int PartLineIndex; // Listbox index of (last) incomplete line
DWORD dwCharX; // average width of characters
DWORD dwCharY; // height of characters
DWORD dwClientX; // width of client area
DWORD dwClientY; // height of client area
DWORD dwLineLen; // line length
int nCaretPosX; // horizontal position of caret
int nCaretPosY; // vertical position of caret
COLORREF FGColour; // Text Colour
COLORREF BGColour; // Background Colour
COLORREF DefaultColour; // Default Text Colour
int CurrentLine; // Line we are writing to in circular buffer.
int Index;
BOOL SendHeader;
BOOL Finished;
char OutputScreen[MAXLINES][LINELEN];
int Colourvalue[MAXLINES];
int LineLen[MAXLINES];
int CurrentColour;
int Thumb;
int FirstTime;
BOOL Scrolled; // Set if scrolled back
int RTFHeight; // Height of RTF control in pixels
BOOL CONNECTED;
int SlowTimer;
BOOL Minimized;
BOOL NeedRefresh;
};

448
CHeaders.h Normal file
View File

@ -0,0 +1,448 @@
//
// Prototypes for BPQ32 Node Functions
//
#define DllImport
#define EXCLUDEBITS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include "compatbits.h"
#include "asmstrucs.h"
BOOL CheckExcludeList(UCHAR * Call);
Dll int ConvFromAX25(unsigned char * incall,unsigned char * outcall);
Dll BOOL ConvToAX25(unsigned char * callsign, unsigned char * ax25call);
DllExport BOOL ConvToAX25Ex(unsigned char * callsign, unsigned char * ax25call);
int WritetoConsoleLocal(char * buff);
VOID Consoleprintf(const char * format, ...);
VOID FreeConfig();
int GetListeningPortsPID(int Port);
void * InitializeExtDriver(PEXTPORTDATA PORTVEC);
VOID PutLengthinBuffer(PDATAMESSAGE buff, USHORT datalen); // Needed for arm5 portability
int GetLengthfromBuffer(PDATAMESSAGE buff);
int IntDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, uint64_t Mask, BOOL APRS, BOOL MCTL);
int IntSetTraceOptionsEx(uint64_t mask, int mtxparam, int mcomparam, int monUIOnly);
int CountBits64(uint64_t in);
#define GetBuff() _GetBuff(__FILE__, __LINE__)
#define ReleaseBuffer(s) _ReleaseBuffer(s, __FILE__, __LINE__)
#define CheckGuardZone() _CheckGuardZone(__FILE__, __LINE__)
#define Q_REM(s) _Q_REM(s, __FILE__, __LINE__)
#define Q_REM_NP(s) _Q_REM_NP(s, __FILE__, __LINE__)
#define C_Q_ADD(s, b) _C_Q_ADD(s, b, __FILE__, __LINE__)
void _CheckGuardZone(char * File, int Line);
VOID * _Q_REM(VOID **Q, char * File, int Line);
VOID * _Q_REM_NP(VOID *Q, char * File, int Line);
int _C_Q_ADD(VOID *Q, VOID *BUFF, char * File, int Line);
UINT _ReleaseBuffer(VOID *BUFF, char * File, int Line);
VOID * _GetBuff(char * File, int Line);
int _C_Q_ADD(VOID *PQ, VOID *PBUFF, char * File, int Line);
int C_Q_COUNT(VOID *Q);
DllExport char * APIENTRY GetApplCall(int Appl);
DllExport char * APIENTRY GetApplAlias(int Appl);
DllExport int APIENTRY FindFreeStream();
DllExport int APIENTRY DeallocateStream(int stream);
DllExport int APIENTRY SessionState(int stream, int * state, int * change);
DllExport int APIENTRY SetAppl(int stream, int flags, int mask);
DllExport int APIENTRY GetMsg(int stream, char * msg, int * len, int * count );
DllExport int APIENTRY GetConnectionInfo(int stream, char * callsign,
int * port, int * sesstype, int * paclen,
int * maxframe, int * l4window);
struct config_setting_t;
int GetIntValue(struct config_setting_t * group, char * name);
BOOL GetStringValue(struct config_setting_t * group, char * name, char * value);
VOID SaveIntValue(struct config_setting_t * group, char * name, int value);
VOID SaveStringValue(struct config_setting_t * group, char * name, char * value);
int EncryptPass(char * Pass, char * Encrypt);
VOID DecryptPass(char * Encrypt, unsigned char * Pass, unsigned int len);
Dll VOID APIENTRY CreateOneTimePassword(char * Password, char * KeyPhrase, int TimeOffset);
Dll BOOL APIENTRY CheckOneTimePassword(char * Password, char * KeyPhrase);
DllExport int APIENTRY TXCount(int stream);
DllExport int APIENTRY RXCount(int stream);
DllExport int APIENTRY MONCount(int stream);
VOID ReadNodes();
int BPQTRACE(MESSAGE * Msg, BOOL APRS);
VOID CommandHandler(TRANSPORTENTRY * Session, struct DATAMESSAGE * Buffer);
VOID PostStateChange(TRANSPORTENTRY * Session);
VOID InnerCommandHandler(TRANSPORTENTRY * Session, struct DATAMESSAGE * Buffer);
VOID DoTheCommand(TRANSPORTENTRY * Session);
char * MOVEANDCHECK(TRANSPORTENTRY * Session, char * Bufferptr, char * Source, int Len);
VOID DISPLAYCIRCUIT(TRANSPORTENTRY * L4, char * Buffer);
char * FormatUptime(int Uptime);
char * strlop(const char * buf, char delim);
BOOL CompareCalls(UCHAR * c1, UCHAR * c2);
VOID PostDataAvailable(TRANSPORTENTRY * Session);
int WritetoConsoleLocal(char * buff);
char * CHECKBUFFER(TRANSPORTENTRY * Session, char * Bufferptr);
VOID CLOSECURRENTSESSION(TRANSPORTENTRY * Session);
VOID SendCommandReply(TRANSPORTENTRY * Session, struct DATAMESSAGE * Buffer, int Len);
struct PORTCONTROL * APIENTRY GetPortTableEntryFromPortNum(int portnum);
int cCOUNT_AT_L2(struct _LINKTABLE * LINK);
VOID SENDL4CONNECT(TRANSPORTENTRY * Session);
VOID CloseSessionPartner(TRANSPORTENTRY * Session);
int COUNTNODES(struct ROUTE * ROUTE);
int DecodeNodeName(char * NodeName, char * ptr);;
VOID DISPLAYCIRCUIT(TRANSPORTENTRY * L4, char * Buffer);
int cCOUNT_AT_L2(struct _LINKTABLE * LINK);
void * zalloc(int len);
BOOL FindDestination(UCHAR * Call, struct DEST_LIST ** REQDEST);
BOOL ProcessConfig();
VOID PUT_ON_PORT_Q(struct PORTCONTROL * PORT, MESSAGE * Buffer);
VOID CLEAROUTLINK(struct _LINKTABLE * LINK);
VOID TellINP3LinkGone(struct ROUTE * Route);
VOID CLEARACTIVEROUTE(struct ROUTE * ROUTE, int Reason);
// Reason Equates
#define NORMALCLOSE 0
#define RETRIEDOUT 1
#define SETUPFAILED 2
#define LINKLOST 3
#define LINKSTUCK 4
int COUNT_AT_L2(struct _LINKTABLE * LINK);
VOID SENDIDMSG();
VOID SENDBTMSG();
VOID INP3TIMER();
VOID REMOVENODE(dest_list * DEST);
BOOL ACTIVATE_DEST(struct DEST_LIST * DEST);
VOID TellINP3LinkSetupFailed(struct ROUTE * Route);
BOOL FindNeighbour(UCHAR * Call, int Port, struct ROUTE ** REQROUTE);
VOID PROCROUTES(struct DEST_LIST * DEST, struct ROUTE * ROUTE, int Qual);
BOOL L2SETUPCROSSLINK(PROUTE ROUTE);
VOID REMOVENODE(dest_list * DEST);
char * SetupNodeHeader(struct DATAMESSAGE * Buffer);
VOID L4CONNECTFAILED(TRANSPORTENTRY * L4);
int CountFramesQueuedOnSession(TRANSPORTENTRY * Session);
VOID CLEARSESSIONENTRY(TRANSPORTENTRY * Session);
VOID __cdecl Debugprintf(const char * format, ...);
int APIENTRY Restart();
int APIENTRY Reboot();
int APIENTRY Reconfig();
Dll int APIENTRY SaveNodes ();
struct SEM;
void GetSemaphore(struct SEM * Semaphore, int ID);
void FreeSemaphore(struct SEM * Semaphore);
void MySetWindowText(HWND hWnd, char * Msg);
Dll int APIENTRY SessionControl(int stream, int command, int Mask);
HANDLE OpenCOMPort(VOID * pPort, int speed, BOOL SetDTR, BOOL SetRTS, BOOL Quiet, int Stopbits);
int ReadCOMBlock(HANDLE fd, char * Block, int MaxLength);
BOOL WriteCOMBlock(HANDLE fd, char * Block, int BytesToWrite);
VOID CloseCOMPort(HANDLE fd);
VOID initUTF8();
int Is8Bit(unsigned char *cpt, int len);
int WebIsUTF8(unsigned char *ptr, int len);
int IsUTF8(unsigned char *ptr, int len);
int Convert437toUTF8(unsigned char * MsgPtr, int len, unsigned char * UTF);
int Convert1251toUTF8(unsigned char * MsgPtr, int len, unsigned char * UTF);
int Convert1252toUTF8(unsigned char * MsgPtr, int len, unsigned char * UTF);
int TrytoGuessCode(unsigned char * Char, int Len);
#define CMD_TO_APPL 1 // PASS COMMAND TO APPLICATION
#define MSG_TO_USER 2 // SEND 'CONNECTED' TO USER
#define MSG_TO_APPL 4 // SEND 'CONECTED' TO APPL
#define CHECK_FOR_ESC 8 // Look for ^d (^D) to disconnect session)
#define UI 3
#define SABM 0x2F
#define DISC 0x43
#define DM 0x0F
#define UA 0x63
#define FRMR 0x87
#define RR 1
#define RNR 5
#define REJ 9
// V2.2 Types
#define SREJ 0x0D
#define SABME 0x6F
#define XID 0xAF
#define TEST 0xE3
#define SUPPORT2point2 1
// XID Optional Functions
#define OPMustHave 0x02A080 // Sync TEST 16 bit FCS Extended Address
#define OPSREJ 4
#define OPSREJMult 0x200000
#define OPREJ 2
#define OPMod8 0x400
#define OPMod128 0x800
#define BPQHOSTSTREAMS 64
extern TRANSPORTENTRY * L4TABLE;
extern unsigned char NEXTID;
extern int MAXCIRCUITS;
extern int L4DEFAULTWINDOW;
extern int L4T1;
extern APPLCALLS APPLCALLTABLE[];
extern char * APPLS;
extern int NEEDMH;
extern int RFOnly;
extern char SESSIONHDDR[];
extern UCHAR NEXTID;
extern struct ROUTE * NEIGHBOURS;
extern int MAXNEIGHBOURS;
extern struct ROUTE * NEIGHBOURS;
extern int ROUTE_LEN;
extern int MAXNEIGHBOURS;
extern struct DEST_LIST * DESTS; // NODE LIST
extern struct DEST_LIST * ENDDESTLIST;
extern int DEST_LIST_LEN;
extern int MAXDESTS; // MAX NODES IN SYSTEM
extern struct _LINKTABLE * LINKS;
extern int LINK_TABLE_LEN;
extern int MAXLINKS;
extern char MYCALL[]; // DB 7 DUP (0) ; NODE CALLSIGN (BIT SHIFTED)
extern char MYALIASTEXT[]; // {" " ; NODE ALIAS (KEEP TOGETHER)
extern UCHAR MYCALLWITHALIAS[13];
extern APPLCALLS APPLCALLTABLE[NumberofAppls];
extern UCHAR MYNODECALL[]; // NODE CALLSIGN (ASCII)
extern char NODECALLLOPPED[]; // NODE CALLSIGN (ASCII). Null terminated
extern UCHAR MYNETROMCALL[]; // NETROM CALLSIGN (ASCII)
extern UCHAR NETROMCALL[]; // NETORM CALL (AX25)
extern VOID * FREE_Q;
extern struct PORTCONTROL * PORTTABLE;
extern int NUMBEROFPORTS;
extern int OBSINIT; // INITIAL OBSOLESCENCE VALUE
extern int OBSMIN; // MINIMUM TO BROADCAST
extern int L3INTERVAL; // "NODES" INTERVAL IN MINS
extern int IDINTERVAL; // "ID" BROADCAST INTERVAL
extern int BTINTERVAL; // "BT" BROADCAST INTERVAL
extern int MINQUAL; // MIN QUALITY FOR AUTOUPDATES
extern int HIDENODES; // N * COMMAND SWITCH
extern int BBSQUAL; // QUALITY OF BBS RELATIVE TO NODE
extern int NUMBEROFBUFFERS; // PACKET BUFFERS
extern int PACLEN; //MAX PACKET SIZE
// L2 SYSTEM TIMER RUNS AT 3 HZ
extern int T3; // LINK VALIDATION TIMER (3 MINS) (+ a bit to reduce RR collisions)
extern int L2KILLTIME; // IDLE LINK TIMER (16 MINS)
extern int L3LIVES; // MAX L3 HOPS
extern int L4N2; // LEVEL 4 RETRY COUNT
extern int L4LIMIT; // IDLE SESSION LIMIT - 15 MINS
extern int L4DELAY; // L4 DELAYED ACK TIMER
extern int BBS; // INCLUDE BBS SUPPORT
extern int NODE; // INCLUDE SWITCH SUPPORT
extern int FULL_CTEXT; // CTEXT ON ALL CONNECTS IF NZ
// Although externally streams are numbered 1 to 64, internally offsets are 0 - 63
extern BPQVECSTRUC DUMMYVEC; // Needed to force correct order of following
extern BPQVECSTRUC BPQHOSTVECTOR[BPQHOSTSTREAMS + 5];
extern int NODEORDER;
extern UCHAR LINKEDFLAG;
extern UCHAR UNPROTOCALL[80];
extern char * INFOMSG;
extern char * CTEXTMSG;
extern int CTEXTLEN;
extern UCHAR MYALIAS[7]; // ALIAS IN AX25 FORM
extern UCHAR BBSALIAS[7];
extern VOID * TRACE_Q; // TRANSMITTED FRAMES TO BE TRACED
extern char HEADERCHAR; // CHAR FOR _NODE HEADER MSGS
extern int AUTOSAVE; // AUTO SAVE NODES ON EXIT FLAG
extern int L4APPL; // Application for BBSCALL/ALIAS connects
extern int CFLAG; // C =HOST Command
extern VOID * IDMSG_Q; // ID/BEACONS WAITING TO BE SENT
extern struct DATAMESSAGE BTHDDR;
extern struct _MESSAGE IDHDDR;
extern VOID * IDMSG;
extern int L3TIMER; // TIMER FOR 'NODES' MESSAGE
extern int IDTIMER; // TIMER FOR ID MESSAGE
extern int BTTIMER; // TIMER FOR BT MESSAGE
extern int STATSTIME;
extern BOOL IPRequired;
extern int MaxHops;
extern int MAXRTT;
extern USHORT CWTABLE[];
extern TRANSPORTENTRY * L4TABLE;
extern UCHAR ROUTEQUAL;
extern UINT BPQMsg;
extern UCHAR ExcludeList[];
extern APPLCALLS APPLCALLTABLE[];
extern char VersionStringWithBuild[];
extern char VersionString[];
extern int MAXHEARDENTRIES;
extern int MHLEN;
extern int APPL1;
extern int PASSCMD;
extern int NUMBEROFCOMMANDS;
extern char * ConfigBuffer;
extern char * WL2KReportLine[];
extern struct CMDX COMMANDS[];
extern int QCOUNT, MAXBUFFS, MAXCIRCUITS, L4DEFAULTWINDOW, L4T1, CMDXLEN;
extern char CMDALIAS[ALIASLEN][NumberofAppls];
extern int SEMGETS;
extern int SEMRELEASES;
extern int SEMCLASHES;
extern int MINBUFFCOUNT;
extern UCHAR BPQDirectory[];
extern UCHAR BPQProgramDirectory[];
extern UCHAR WINMOR[];
extern UCHAR PACTORCALL[];
extern UCHAR MCOM;
extern UCHAR MUIONLY;
extern UCHAR MTX;
extern uint64_t MMASK;
extern UCHAR NODECALL[]; // NODES in ax.25
extern int L4CONNECTSOUT;
extern int L4CONNECTSIN;
extern int L4FRAMESTX;
extern int L4FRAMESRX;
extern int L4FRAMESRETRIED;
extern int OLDFRAMES;
extern int L3FRAMES;
extern char * PortConfig[];
extern struct SEM Semaphore;
extern UCHAR AuthorisedProgram; // Local Variable. Set if Program is on secure list
extern int REALTIMETICKS;
extern time_t CurrentSecs;
extern time_t lastSlowSecs;
extern time_t lastSaveSecs;
// SNMP Variables
extern int InOctets[64];
extern int OutOctets[64];
extern BOOL CloseAllNeeded;
extern int CloseOnError;
extern char * PortConfig[70];
extern struct TNCINFO * TNCInfo[71]; // Records are Malloc'd
#define MaxBPQPortNo 63 // Port 64 reserved for BBS Mon
#define MAXBPQPORTS 63
// IP, APRS use port ocnfig slots above the real port range
#define IPConfigSlot MaxBPQPortNo + 1
#define PortMapConfigSlot MaxBPQPortNo + 2
#define APRSConfigSlot MaxBPQPortNo + 3
extern char * UIUIDigi[MaxBPQPortNo + 1];
extern char UIUIDEST[MaxBPQPortNo + 1][11]; // Dest for Beacons
extern UCHAR FN[MaxBPQPortNo + 1][256]; // Filename
extern int Interval[MaxBPQPortNo + 1]; // Beacon Interval (Mins)
extern char Message[MaxBPQPortNo + 1][1000]; // Beacon Text
extern int MinCounter[MaxBPQPortNo + 1]; // Interval Countdown
extern BOOL SendFromFile[MaxBPQPortNo + 1];
extern BOOL MQTT;
extern char MQTT_HOST[80];
extern int MQTT_PORT;
extern char MQTT_USER[80];
extern char MQTT_PASS[80];
DllExport uint64_t APIENTRY GetPortFrequency(int PortNo, char * FreqStringMhz);
void hookL2SessionAccepted(int Port, char * remotecall, char * ourcall, struct _LINKTABLE * LINK);
void hookL2SessionDeleted(struct _LINKTABLE * LINK);
void hookL2SessionAttempt(int Port, char * ourcall, char * remotecall, struct _LINKTABLE * LINK);
void hookL4SessionAttempt(void * STREAM, char * remotecall, char * ourcall);
void hookL4SessionAccepted(void * STREAM, char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);

73
CMSAuth.c Normal file
View File

@ -0,0 +1,73 @@
/*
Copyright 2001-2022 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
*/
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _CRT_SECURE_NO_DEPRECATE
#ifdef LINBPQ
#include "compatbits.h"
char * strlop(const char * buf, char delim);
#define APIENTRY
#define VOID void
#else
#include <windows.h>
#endif
VOID APIENTRY md5 (char *arg, unsigned char * checksum);
// Implementation of the WinLink password challenge/response protocol
unsigned char seed [] = {77, 197, 101, 206, 190, 249,
93, 200, 51, 243, 93, 237,
71, 94, 239, 138, 68, 108,
70, 185, 225, 137, 217, 16,
51, 122, 193, 48, 194, 195,
198, 175, 172, 169, 70, 84,
61, 62, 104, 186, 114, 52,
61, 168, 66, 129, 192, 208,
187, 249, 232, 193, 41, 113,
41, 45, 240, 16, 29, 228,
208, 228, 61, 20, 0};
/*
Calculate the challenge password response as follows:
- Concatenate the challenge phrase, password, and supplied secret value (i.e. the salt)
- Generate an MD5 hash of the result
- Convert the first 4 bytes of the hash to an integer (big endian) and return it
*/
int GetCMSHash(char * Challenge, char * Password)
{
unsigned char Hash[16];
unsigned char Phrase[256];
strlop(Challenge, 13);
strlop(Password, 13);
strcpy(Phrase, Challenge);
strcat(Phrase, Password);
strcat(Phrase, seed);
md5(Phrase, Hash);
return ((Hash[3] & 0x3f) << 24) + (Hash[2] << 16) + (Hash[1] << 8) + Hash[0];
}

432
ChatDebug.c Normal file
View File

@ -0,0 +1,432 @@
// Mail and Chat Server for BPQ32 Packet Switch
//
// Debug Window(s) Module
#include "BPQChat.h"
static char ClassName[]="BPQDEBUGWINDOW";
static WNDPROC wpOrigInputProc;
static WNDPROC wpOrigOutputProc;
HWND hDebug;
static HWND hwndInput;
static HWND hwndOutput;
static HMENU hMenu; // handle of menu
#define InputBoxHeight 25
RECT DebugRect;
int Height, Width, LastY;
static char readbuff[1024];
static BOOL Bells = TRUE;
static BOOL StripLF = TRUE;
static BOOL MonBBS = TRUE;
static BOOL MonCHAT = TRUE;
static BOOL MonTCP = TRUE;
static int PartLinePtr=0;
static int PartLineIndex=0; // Listbox index of (last) incomplete line
static LRESULT CALLBACK MonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static LRESULT APIENTRY InputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static LRESULT APIENTRY OutputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static LRESULT APIENTRY MonProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static LRESULT APIENTRY SplitProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static void MoveWindows();
#define BGCOLOUR RGB(236,233,216)
extern char DebugSize[32];
BOOL CreateDebugWindow()
{
WNDCLASS wc;
HBRUSH bgBrush;
char Text[80];
if (hDebug)
{
ShowWindow(hDebug, SW_SHOWNORMAL);
SetForegroundWindow(hDebug);
return FALSE; // Alreaqy open
}
bgBrush = CreateSolidBrush(BGCOLOUR);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MonWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInst;
wc.hIcon = LoadIcon( hInst, MAKEINTRESOURCE(BPQICON) );
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = bgBrush;
wc.lpszMenuName = NULL;
wc.lpszClassName = ClassName;
RegisterClass(&wc);
hDebug=CreateDialog(hInst,ClassName,0,NULL);
if (!hDebug)
return (FALSE);
wsprintf(Text, "Chat %s Debug", Session);
SetWindowText(hDebug, Text);
hMenu=GetMenu(hDebug);
if (Bells & 1)
CheckMenuItem(hMenu,BPQBELLS, MF_CHECKED);
else
CheckMenuItem(hMenu,BPQBELLS, MF_UNCHECKED);
if (StripLF & 1)
CheckMenuItem(hMenu,BPQStripLF, MF_CHECKED);
else
CheckMenuItem(hMenu,BPQStripLF, MF_UNCHECKED);
CheckMenuItem(hMenu,MONBBS, MonBBS ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hMenu,MONCHAT, MonCHAT ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hMenu,MONTCP, MonTCP ? MF_CHECKED : MF_UNCHECKED);
DrawMenuBar(hWnd);
// Retrieve the handlse to the edit controls.
hwndOutput = GetDlgItem(hDebug, 122);
// Set our own WndProcs for the controls.
wpOrigOutputProc = (WNDPROC)SetWindowLong(hwndOutput, GWL_WNDPROC, (LONG)OutputProc);
if (cfgMinToTray)
{
AddTrayMenuItem(hDebug, Text);
}
ShowWindow(hDebug, SW_SHOWNORMAL);
if (DebugRect.right < 100 || DebugRect.bottom < 100)
{
GetWindowRect(hDebug, &DebugRect);
}
MoveWindow(hDebug,DebugRect.left,DebugRect.top, DebugRect.right-DebugRect.left, DebugRect.bottom-DebugRect.top, TRUE);
MoveWindows();
return TRUE;
}
static void MoveWindows()
{
RECT rcMain, rcClient;
int ClientHeight, ClientWidth;
GetWindowRect(hDebug, &rcMain);
GetClientRect(hDebug, &rcClient);
ClientHeight = rcClient.bottom;
ClientWidth = rcClient.right;
// MoveWindow(hwndMon,2, 0, ClientWidth-4, SplitPos, TRUE);
MoveWindow(hwndOutput,2, 2, ClientWidth-4, ClientHeight-4, TRUE);
// MoveWindow(hwndSplit,0, SplitPos, ClientWidth, SplitBarHeight, TRUE);
}
static LRESULT CALLBACK MonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
LPRECT lprc;
switch (message) {
case WM_ACTIVATE:
SetFocus(hwndInput);
break;
case WM_COMMAND:
wmId = LOWORD(wParam); // Remember, these are...
wmEvent = HIWORD(wParam); // ...different for Win32!
switch (wmId) {
case MONBBS:
ToggleParam(hMenu, hWnd, &MonBBS, MONBBS);
break;
case MONCHAT:
ToggleParam(hMenu, hWnd, &MonCHAT, MONCHAT);
break;
case MONTCP:
ToggleParam(hMenu, hWnd, &MonTCP, MONTCP);
break;
case BPQCLEAROUT:
SendMessage(hwndOutput,LB_RESETCONTENT, 0, 0);
break;
case BPQCOPYOUT:
CopyToClipboard(hwndOutput);
break;
//case BPQHELP:
// HtmlHelp(hWnd,"BPQTerminal.chm",HH_HELP_FINDER,0);
// break;
default:
return 0;
}
case WM_SYSCOMMAND:
wmId = LOWORD(wParam); // Remember, these are...
wmEvent = HIWORD(wParam); // ...different for Win32!
switch (wmId) {
case SC_MINIMIZE:
if (cfgMinToTray)
return ShowWindow(hWnd, SW_HIDE);
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
case WM_SIZING:
lprc = (LPRECT) lParam;
Height = lprc->bottom-lprc->top;
Width = lprc->right-lprc->left;
MoveWindows();
return TRUE;
case WM_DESTROY:
// Remove the subclass from the edit control.
GetWindowRect(hWnd, &DebugRect); // For save soutine
SetWindowLong(hwndInput, GWL_WNDPROC,
(LONG) wpOrigInputProc);
if (cfgMinToTray)
DeleteTrayMenuItem(hWnd);
hDebug = NULL;
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}
LRESULT APIENTRY OutputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// Trap mouse messages, so we cant select stuff in output and mon windows,
// otherwise scrolling doesnt work.
if (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST)
return TRUE;
return CallWindowProc(wpOrigOutputProc, hwnd, uMsg, wParam, lParam);
}
VOID ClearDebugWindow()
{
SendMessage(hwndOutput,LB_RESETCONTENT, 0, 0);
}
VOID WritetoDebugWindow(char * Msg, int len)
{
char * ptr1, * ptr2;
int index;
if (len ==0)
return;
if (PartLinePtr != 0)
SendMessage(hwndOutput,LB_DELETESTRING,PartLineIndex,(LPARAM)(LPCTSTR) 0 );
memcpy(&readbuff[PartLinePtr], Msg, len);
len=len+PartLinePtr;
ptr1=&readbuff[0];
readbuff[len]=0;
if (Bells)
{
do {
ptr2=memchr(ptr1,7,len);
if (ptr2)
{
*(ptr2)=32;
Beep(440,250);
}
} while (ptr2);
}
lineloop:
if (PartLinePtr > 300)
PartLinePtr = 0;
if (len > 0)
{
// copy text to control a line at a time
ptr2=memchr(ptr1,13,len);
if (ptr2 == 0)
{
// no newline. Move data to start of buffer and Save pointer
PartLinePtr=len;
memmove(readbuff,ptr1,len);
PartLineIndex=SendMessage(hwndOutput,LB_ADDSTRING,0,(LPARAM)(LPCTSTR) ptr1 );
SendMessage(hwndOutput,LB_SETCARETINDEX,(WPARAM) PartLineIndex, MAKELPARAM(FALSE, 0));
return;
}
*(ptr2++)=0;
index=SendMessage(hwndOutput,LB_ADDSTRING,0,(LPARAM)(LPCTSTR) ptr1 );
// if (LogOutput) WriteMonitorLine(ptr1, ptr2 - ptr1);
PartLinePtr=0;
len-=(ptr2-ptr1);
ptr1=ptr2;
if ((len > 0) && StripLF)
{
if (*ptr1 == 0x0a) // Line Feed
{
ptr1++;
len--;
}
}
if (index > 1200)
do{
index=SendMessage(hwndOutput,LB_DELETESTRING, 0, 0);
} while (index > 1000);
SendMessage(hwndOutput,LB_SETCARETINDEX,(WPARAM) index, MAKELPARAM(FALSE, 0));
goto lineloop;
}
return;
}
/*static int ToggleParam(HMENU hMenu, HWND hWnd, BOOL * Param, int Item)
{
*Param = !(*Param);
CheckMenuItem(hMenu,Item, (*Param) ? MF_CHECKED : MF_UNCHECKED);
return (0);
}
*/
static void CopyToClipboard(HWND hWnd)
{
int i,n, len=0;
HGLOBAL hMem;
char * ptr;
//
// Copy List Box to clipboard
//
n = SendMessage(hWnd, LB_GETCOUNT, 0, 0);
for (i=0; i<n; i++)
{
len+=SendMessage(hWnd, LB_GETTEXTLEN, i, 0);
}
hMem=GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, len+n+n+1);
if (hMem != 0)
{
ptr=GlobalLock(hMem);
if (OpenClipboard(MainWnd))
{
// CopyScreentoBuffer(GlobalLock(hMem));
for (i=0; i<n; i++)
{
ptr+=SendMessage(hWnd, LB_GETTEXT, i, (LPARAM) ptr);
*(ptr++)=13;
*(ptr++)=10;
}
*(ptr)=0; // end of data
GlobalUnlock(hMem);
EmptyClipboard();
SetClipboardData(CF_TEXT,hMem);
CloseClipboard();
}
else
GlobalFree(hMem);
}
}

825
ChatHTMLConfig.c Normal file
View File

@ -0,0 +1,825 @@
/*
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
*/
#include "bpqchat.h"
extern char OurNode[10];
// Flags Equates
#define GETTINGUSER 1
#define GETTINGBBS 2
#define CHATMODE 4
#define GETTINGTITLE 8
#define GETTINGMESSAGE 16
#define CHATLINK 32 // Link to another Chat Node
#define SENDTITLE 64
#define SENDBODY 128
#define WAITPROMPT 256 // Waiting for prompt after message
extern char PassError[];
extern char BusyError[];
extern int chatPaclen;
extern char NodeTail[];
extern BOOL APRSApplConnected;
extern char ChatConfigName[250];
extern char OtherNodesList[1000];
extern char ChatWelcomeMsg[1000];
extern USER *user_hd;
extern LINK *link_hd;
extern UCHAR BPQDirectory[260];
#define MaxSockets 64
extern ChatCIRCUIT ChatConnections[MaxSockets+1];
extern int NumberofChatStreams;
extern int SMTPMsgs;
extern int ChatApplNum;
extern int MaxChatStreams;
extern char Position[81];
extern char PopupText[251];
extern int PopupMode;
extern int reportChatEvents;
#include "httpconnectioninfo.h"
static struct HTTPConnectionInfo * SessionList; // active bbs config sessions
static struct HTTPConnectionInfo * AllocateSession(char Appl);
static struct HTTPConnectionInfo * FindSession(char * Key);
VOID ProcessUserUpdate(struct HTTPConnectionInfo * Session, char * MsgPtr, char * Reply, int * RLen, char * Rest);
VOID ProcessMsgFwdUpdate(struct HTTPConnectionInfo * Session, char * MsgPtr, char * Reply, int * RLen, char * Rest);
VOID SendConfigPage(char * Reply, int * ReplyLen, char * Key);
VOID ProcessConfUpdate(struct HTTPConnectionInfo * Session, char * MsgPtr, char * Reply, int * RLen, char * Rest);
VOID ProcessUIUpdate(struct HTTPConnectionInfo * Session, char * MsgPtr, char * Reply, int * RLen, char * Rest);
VOID SendUserSelectPage(char * Reply, int * ReplyLen, char * Key);
VOID SendFWDSelectPage(char * Reply, int * ReplyLen, char * Key);
int EncryptPass(char * Pass, char * Encrypt);
VOID ProcessFWDUpdate(struct HTTPConnectionInfo * Session, char * MsgPtr, char * Reply, int * RLen, char * Rest);
VOID SendStatusPage(char * Reply, int * ReplyLen, char * Key);
VOID SendChatStatusPage(char * Reply, int * ReplyLen, char * Key);
VOID SendUIPage(char * Reply, int * ReplyLen, char * Key);
static VOID GetParam(char * input, char * key, char * value);
BOOL GetConfig(char * ConfigName);
VOID ProcessChatDisUser(struct HTTPConnectionInfo * Session, char * MsgPtr, char * Reply, int * RLen, char * Rest);
int APIENTRY SessionControl(int stream, int command, int param);
int APIENTRY GetNumberofPorts();
int APIENTRY GetPortNumber(int portslot);
UCHAR * APIENTRY GetPortDescription(int portslot, char * Desc);
struct PORTCONTROL * APIENTRY GetPortTableEntryFromSlot(int portslot);
VOID SendHouseKeeping(char * Reply, int * ReplyLen, char * Key);
VOID SendWelcomePage(char * Reply, int * ReplyLen, char * Key);
VOID SaveWelcome(struct HTTPConnectionInfo * Session, char * MsgPtr, char * Reply, int * RLen, char * Key);
VOID GetMallocedParam(char * input, char * key, char ** value);
VOID SaveMessageText(struct HTTPConnectionInfo * Session, char * MsgPtr, char * Reply, int * RLen, char * Rest);
VOID SaveHousekeeping(struct HTTPConnectionInfo * Session, char * MsgPtr, char * Reply, int * RLen, char * Key);
VOID SaveWP(struct HTTPConnectionInfo * Session, char * MsgPtr, char * Reply, int * RLen, char * Key);
int SetupNodeMenu(char * Buff);
VOID SendFwdSelectPage(char * Reply, int * ReplyLen, char * Key);
VOID SendFwdDetails(struct HTTPConnectionInfo * Session, char * Reply, int * ReplyLen, char * Key);
VOID SendFwdMainPage(char * Reply, int * ReplyLen, char * Key);
VOID SaveFwdCommon(struct HTTPConnectionInfo * Session, char * MsgPtr, char * Reply, int * RLen, char * Rest);
VOID SaveFwdDetails(struct HTTPConnectionInfo * Session, char * MsgPtr, char * Reply, int * RLen, char * Rest);
char ** SeparateMultiString(char * MultiString);
VOID SendChatConfigPage(char * Reply, int * ReplyLen, char * Key);
VOID SaveChatInfo(struct HTTPConnectionInfo * Session, char * MsgPtr, char * Reply, int * RLen, char * Key);
int rtlink (char * Call);
char * APIENTRY GetBPQDirectory();
VOID SaveChatConfigFile(char * Config);
BOOL GetChatConfig(char * Config);
char * GetTemplateFromFile(int Version, char * FN);
static char UNC[] = "";
static char CHKD[] = "checked=checked ";
static char sel[] = "selected";
char ChatSignon[] = "<html><head><title>BPQ32 Chat Server Access</title></head><body background=\"/background.jpg\">"
"<h3 align=center>BPQ32 Chat Server %s Access</h3>"
"<h3 align=center>Please enter Callsign and Password to access the Chat Server</h3>"
"<form method=post action=/Chat/Signon?Chat>"
"<table align=center bgcolor=white>"
"<tr><td>User</td><td><input type=text name=user tabindex=1 size=20 maxlength=50 /></td></tr>"
"<tr><td>Password</td><td><input type=password name=password tabindex=2 size=20 maxlength=50 /></td></tr></table>"
"<p align=center><input type=submit value=Submit /><input type=submit value=Cancel name=Cancel /></form>";
char ChatPage[] = "<html><head><title>%s's Chat Server</title></head>"
"<body background=\"/background.jpg\"><h3 align=center>BPQ32 Chat Node %s</h3><P>"
"<P align=center><table border=1 cellpadding=2 bgcolor=white><tr>"
"<td><a href=/Chat/ChatStatus?%s>Status</a></td>"
"<td><a href=/Chat/ChatConf?%s>Configuration</a></td>"
"<td><a href=/>Node Menu</a></td>"
"</tr></table>";
static char LostSession[] = "<html><body>"
"<form style=\"font-family: monospace; text-align: center;\" method=post action=/Chat/Lost?%s>"
"Sorry, Session had been lost<br><br>&nbsp;&nbsp;&nbsp;&nbsp;"
"<input name=Submit value=Restart type=submit> <input type=submit value=Exit name=Cancel><br></form>";
char * ChatConfigTemplate = NULL;
char * ChatStatusTemplate = NULL;
static int compare(const void *arg1, const void *arg2)
{
// Compare Calls. Fortunately call is at start of stuct
return _stricmp(*(char**)arg1 , *(char**)arg2);
}
int SendChatHeader(char * Reply, char * Key)
{
return sprintf(Reply, ChatPage, OurNode, OurNode, Key, Key);
}
void ProcessChatHTTPMessage(struct HTTPConnectionInfo * Session, char * Method, char * URL, char * input, char * Reply, int * RLen)
{
char * Conxtext = 0, * NodeURL;
int ReplyLen;
char * Key;
char Appl = 'M';
NodeURL = strtok_s(URL, "?", &Conxtext);
Key = Session->Key;
if (strcmp(Method, "POST") == 0)
{
if (_stricmp(NodeURL, "/Chat/Header") == 0)
{
*RLen = SendChatHeader(Reply, Session->Key);
return;
}
if (_stricmp(NodeURL, "/Chat/ChatConfig") == 0)
{
if (ChatConfigTemplate)
free(ChatConfigTemplate);
ChatConfigTemplate = GetTemplateFromFile(2, "ChatConfig.txt");
NodeURL[strlen(NodeURL)] = ' '; // Undo strtok
SaveChatInfo(Session, input, Reply, RLen, Key);
return ;
}
if (_stricmp(NodeURL, "/Chat/ChatDisSession") == 0)
{
ProcessChatDisUser(Session, input, Reply, RLen, Key);
return ;
}
// End of POST section
}
if ((_stricmp(NodeURL, "/chat/Chat.html") == 0) || (_stricmp(NodeURL, "/chat/Header") == 0))
{
*RLen = SendChatHeader(Reply, Session->Key);
return;
}
if ((_stricmp(NodeURL, "/Chat/ChatStatus") == 0) || (_stricmp(NodeURL, "/Chat/ChatDisSession") == 0))
{
if (ChatStatusTemplate)
free(ChatStatusTemplate);
ChatStatusTemplate = GetTemplateFromFile(1, "ChatStatus.txt");
SendChatStatusPage(Reply, RLen, Key);
return;
}
if (_stricmp(NodeURL, "/Chat/ChatConf") == 0)
{
if (ChatConfigTemplate)
free(ChatConfigTemplate);
ChatConfigTemplate = GetTemplateFromFile(2, "ChatConfig.txt");
SendChatConfigPage(Reply, RLen, Key);
return;
}
ReplyLen = sprintf(Reply, ChatSignon, OurNode, OurNode);
*RLen = ReplyLen;
}
static VOID GetParam(char * input, char * key, char * value)
{
char * ptr = strstr(input, key);
char Param[2048];
char * ptr1, * ptr2;
char c;
if (ptr)
{
ptr2 = strchr(ptr, '&');
if (ptr2) *ptr2 = 0;
strcpy(Param, ptr + strlen(key));
if (ptr2) *ptr2 = '&'; // Restore string
// Undo any % transparency
ptr1 = Param;
ptr2 = Param;
c = *(ptr1++);
while (c)
{
if (c == '%')
{
int n;
int m = *(ptr1++) - '0';
if (m > 9) m = m - 7;
n = *(ptr1++) - '0';
if (n > 9) n = n - 7;
*(ptr2++) = m * 16 + n;
}
else if (c == '+')
*(ptr2++) = ' ';
else
*(ptr2++) = c;
c = *(ptr1++);
}
*(ptr2++) = 0;
strcpy(value, Param);
}
}
static VOID GetCheckBox(char * input, char * key, int * value)
{
char * ptr = strstr(input, key);
if (ptr)
*value = 1;
else
*value = 0;
}
VOID SaveChatInfo(struct HTTPConnectionInfo * Session, char * MsgPtr, char * Reply, int * RLen, char * Key)
{
int ReplyLen = 0;
char * input;
struct UserInfo * USER = NULL;
char Temp[80];
char Nodes[10000] = "";
char * ptr1, * ptr2;
input = strstr(MsgPtr, "\r\n\r\n"); // End of headers
if (input)
{
if (strstr(input, "Cancel=Cancel"))
{
*RLen = SendChatHeader(Reply, Session->Key);
return;
}
GetParam(input, "ApplNum=", Temp);
ChatApplNum = atoi(Temp);
GetParam(input, "Streams=", Temp);
MaxChatStreams = atoi(Temp);
GetParam(input, "Paclen=", Temp);
chatPaclen = atoi(Temp);
if (chatPaclen < 60)
chatPaclen = 60;
GetCheckBox(input, "Events=", &reportChatEvents);
GetParam(input, "nodes=", Nodes);
ptr1 = Nodes;
ptr2 = OtherNodesList;
// Now we just save with crlf in place
strcpy(OtherNodesList, Nodes);
/*
while (*ptr1)
{
if ((*ptr1) == 13)
{
*(ptr2++) = ' ';
ptr1 += 2;
}
else
*(ptr2++) = *(ptr1++);
}
*ptr2 = 0;
*/
GetParam(input, "Posn=", Position);
GetParam(input, "MapText=", PopupText);
GetParam(input, "welcome=", ChatWelcomeMsg);
// Replace cr lf in string with $W
ptr1 = ChatWelcomeMsg;
scan2:
ptr1 = strstr(ptr1, "\r\n");
if (ptr1)
{
*(ptr1++)='$'; // put in cr
*(ptr1++)='W'; // put in lf
goto scan2;
}
GetCheckBox(input, "PopType=Click", &PopupMode);
if (strstr(input, "Restart=Restart+Links"))
{
char * ptr1, * ptr2, * Context;
node_close();
Sleep(2);
// Dont call removelinks - they may still be attached to a circuit. Just clear header
link_hd = NULL;
// Set up other nodes list. rtlink messes with the string so pass copy
ptr2 = ptr1 = strtok_s(_strdup(OtherNodesList), "\r\n", &Context);
while (ptr1)
{
rtlink(ptr1);
ptr1 = strtok_s(NULL, "\r\n", &Context);
}
free(ptr2);
if (user_hd) // Any Users?
makelinks(); // Bring up links
}
if (strstr(input, "UpdateMap=Update+Map"))
{
char Msg[500];
int len;
len = sprintf(Msg, "INFO %s|%s|%d|\r", Position, PopupText, PopupMode);
if (len < 256)
Send_MON_Datagram(Msg, len);
}
SaveChatConfigFile(ChatConfigName);
GetChatConfig(ChatConfigName);
}
SendChatConfigPage(Reply, RLen, Key);
return;
}
VOID ProcessChatDisUser(struct HTTPConnectionInfo * Session, char * MsgPtr, char * Reply, int * RLen, char * Rest)
{
char * input;
char * ptr;
input = strstr(MsgPtr, "\r\n\r\n"); // End of headers
if (input)
{
ptr = strstr(input, "Stream=");
if (ptr)
{
int Stream = atoi(ptr + 7);
SessionControl(Stream, 2, 0);
}
}
SendChatStatusPage(Reply, RLen, Rest);
}
VOID SendChatConfigPage(char * Reply, int * ReplyLen, char * Key)
{
int Len;
char Nodes[10000];
char Text[1000];
char * ptr1, * ptr2;
// Replace spaces in Node List with CR/LF
ptr1 = OtherNodesList;
ptr2 = Nodes;
if (strchr(OtherNodesList, 13)) // New format maybe with connect scripts
{
// OtherNodesList alresdy has crlf
strcpy(Nodes, OtherNodesList);
}
else
{
while (*ptr1)
{
if ((*ptr1) == ' ')
{
*(ptr2++) = 13;
*(ptr2++) = 10;
ptr1++ ;
}
else
*(ptr2++) = *(ptr1++);
}
*ptr2 = 0;
}
// Replace " in Text with &quot;
ptr1 = PopupText;
ptr2 = Text;
while (*ptr1)
{
if ((*ptr1) == '"')
{
*(ptr2++) = '&';
*(ptr2++) = 'q';
*(ptr2++) = 'u';
*(ptr2++) = 'o';
*(ptr2++) = 't';
*(ptr2++) = ';';
ptr1++ ;
}
else
*(ptr2++) = *(ptr1++);
}
*ptr2 = 0;
// Replace $W in Welcome Message with cr lf
ptr2 = ptr1 = _strdup(ChatWelcomeMsg);
scan:
ptr1 = strstr(ptr1, "$W");
if (ptr1)
{
*(ptr1++)=13; // put in cr
*(ptr1++)=10; // put in lf
goto scan;
}
Len = sprintf(Reply, ChatConfigTemplate,
OurNode, Key, Key, Key,
ChatApplNum, MaxChatStreams,
(reportChatEvents) ? CHKD : UNC,
Nodes, chatPaclen, Position,
(PopupMode) ? UNC : CHKD,
(PopupMode) ? CHKD : UNC, Text, ptr2);
free(ptr2);
*ReplyLen = Len;
}
VOID SendChatStatusPage(char * Reply, int * ReplyLen, char * Key)
{
int Len = 0;
USER *user;
char * Alias;
char * Topic;
LINK *link;
char Streams[65536];
char Users[65536];
char Links[65536];
ChatCIRCUIT * conn;
int i = 0, n;
Users[0] = 0;
for (user = user_hd; user; user = user->next)
{
if ((user->node == 0) || (user->node->alias == 0))
Alias = "(Corrupt Alias)";
else
Alias = user->node->alias;
if ((user->topic == 0) || (user->topic->name == 0))
Topic = "(Corrupt Topic)";
else
Topic = user->topic->name;
Len += sprintf(&Users[Len], "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%s</td></tr>",
user->call, Alias, user->name, Topic, (int)(time(NULL) - user->lastrealmsgtime), user->qth);
}
Links[0] = 0;
Len = 0;
for (link = link_hd; link; link = link->next)
{
if (link->flags & p_linked )
if (link->supportsPolls)
Len += sprintf(&Links[Len], "<tr><td>%s</td><td>Open &nbsp RTT %d</td></tr>", link->call, link->RTT);
else
Len += sprintf(&Links[Len], "<tr><td>%s</td><td>Open</td></tr>", link->call);
else if (link->flags & (p_linked | p_linkini))
Len += sprintf(&Links[Len], "<tr><td>%s</td><td>Connecting</td></tr>", link->call);
else if (link->flags & p_linkfailed)
Len += sprintf(&Links[Len], "<tr><td>%s</td><td>Connect failed</td></tr>", link->call);
else
Len += sprintf(&Links[Len], "<tr><td>%s</td><td>Idle</td></tr>", link->call);
}
Len = 0;
Streams[0] = 0;
for (n = 0; n < NumberofChatStreams; n++)
{
conn=&ChatConnections[n];
i = conn->BPQStream;
if (!conn->Active)
{
Len += sprintf(&Streams[Len], "<tr><td onclick= SelectRow(%d) id=cell_%d>Idle</td><td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td></tr>", i, i);
}
else
{
if (conn->Flags & CHATLINK)
{
if (conn->BPQStream > 64 || conn->u.link == 0)
Len += sprintf(&Streams[Len], "<tr><td onclick= SelectRow(%d) id=cell_%d>** Corrupt ChatLink **</td>"
"<td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td><td>&nbsp;&nbsp;</td></tr>", i, i);
else
Len += sprintf(&Streams[Len], "<tr><td onclick='SelectRow(%d)' id='cell_%d'>"
"%s</td><td>%s</td><td>%d</td><td>%s</td><td>%d</td></tr>",
i, i, "Chat Link", conn->u.link->alias, conn->BPQStream,
"", conn->OutputQueueLength - conn->OutputGetPointer);
}
else
if ((conn->Flags & CHATMODE) && conn->topic)
{
Len += sprintf(&Streams[Len], "<tr><td onclick='SelectRow(%d)' id='cell_%d'>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%d</td></tr>",
i, i, conn->u.user->name, conn->u.user->call, conn->BPQStream,
conn->topic->topic->name, conn->OutputQueueLength - conn->OutputGetPointer);
}
else
{
if (conn->UserPointer == 0)
Len += sprintf(&Streams[Len], "Logging in");
else
{
Len += sprintf(&Streams[Len], "<tr><td onclick='SelectRow(%d)' id='cell_%d'>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%d</td></tr>",
i, i, conn->UserPointer->Name, conn->UserPointer->Call, conn->BPQStream,
"CHAT", conn->OutputQueueLength - conn->OutputGetPointer);
}
}
}
}
Len = sprintf(Reply, ChatStatusTemplate, OurNode, OurNode, Key, Key, Key, Streams, Users, Links);
*ReplyLen = Len;
}
static struct HTTPConnectionInfo * AllocateSession(char Appl)
{
int KeyVal;
struct HTTPConnectionInfo * Session = zalloc(sizeof(struct HTTPConnectionInfo));
if (Session == NULL)
return NULL;
KeyVal = (int)time(NULL);
sprintf(Session->Key, "%c%012X", Appl, KeyVal);
if (SessionList)
Session->Next = SessionList;
SessionList = Session;
return Session;
}
static struct HTTPConnectionInfo * FindSession(char * Key)
{
struct HTTPConnectionInfo * Session = SessionList;
while (Session)
{
if (strcmp(Session->Key, Key) == 0)
return Session;
Session = Session->Next;
}
return NULL;
}
#ifdef WIN32
static char PipeFileName[] = "\\\\.\\pipe\\BPQChatWebPipe";
static DWORD WINAPI InstanceThread(LPVOID lpvParam)
// This routine is a thread processing function to read from and reply to a client
// via the open pipe connection passed from the main loop. Note this allows
// the main loop to continue executing, potentially creating more threads of
// 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[4096];
char OutBuffer[100000];
char * MsgPtr;
int InputLen = 0;
int OutputLen = 0;
struct HTTPConnectionInfo Session;
char URL[4096];
char * Context, * Method;
int n;
char * ptr;
// Debugprintf("InstanceThread created, receiving and processing messages.");
// The thread's parameter is a handle to a pipe object instance.
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, 4096, &InputLen, NULL);
if (!fSuccess || InputLen == 0)
{
if (GetLastError() == ERROR_BROKEN_PIPE)
Debugprintf("InstanceThread: client disconnected.", GetLastError());
else
Debugprintf("InstanceThread ReadFile failed, GLE=%d.", GetLastError());
}
else
{
Buffer[InputLen] = 0;
MsgPtr = &Buffer[0];
strcpy(URL, MsgPtr);
ptr = strstr(URL, " HTTP");
if (ptr)
*ptr = 0;
Method = strtok_s(URL, " ", &Context);
ProcessChatHTTPMessage(&Session, Method, Context, MsgPtr, OutBuffer, &OutputLen);
WriteFile(hPipe, &Session, sizeof (struct HTTPConnectionInfo), &n, NULL);
WriteFile(hPipe, OutBuffer, OutputLen, &cbWritten, NULL);
FlushFileBuffers(hPipe);
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);
}
return 1;
}
static DWORD WINAPI PipeThreadProc(LPVOID lpvParam)
{
BOOL fConnected = FALSE;
DWORD dwThreadId = 0;
HANDLE hPipe = INVALID_HANDLE_VALUE, hThread = NULL;
// The main loop creates an instance of the named pipe and
// then waits for a client to connect to it. When the client
// connects, a thread is created to handle communications
// with that client, and this loop is free to wait for the
// next client connect request. It is an infinite loop.
for (;;)
{
hPipe = CreateNamedPipe(
PipeFileName, // pipe name
PIPE_ACCESS_DUPLEX, // read/write access
PIPE_TYPE_BYTE | // message type pipe
PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // max. instances
4096, // output buffer size
4096, // input buffer size
0, // client time-out
NULL); // default security attribute
if (hPipe == INVALID_HANDLE_VALUE)
{
Debugprintf("CreateNamedPipe failed, GLE=%d.\n", GetLastError());
return -1;
}
// Wait for the client to connect; if it succeeds,
// the function returns a nonzero value. If the function
// returns zero, GetLastError returns ERROR_PIPE_CONNECTED.
fConnected = ConnectNamedPipe(hPipe, NULL) ?
TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
if (fConnected)
{
// Create a thread for this client.
hThread = CreateThread(
NULL, // no security attribute
0, // default stack size
InstanceThread, // thread proc
(LPVOID) hPipe, // thread parameter
0, // not suspended
&dwThreadId); // returns thread ID
if (hThread == NULL)
{
Debugprintf("CreateThread failed, GLE=%d.\n", GetLastError());
return -1;
}
else CloseHandle(hThread);
}
else
// The client could not connect, so close the pipe.
CloseHandle(hPipe);
}
return 0;
}
BOOL CreateChatPipeThread()
{
DWORD ThreadId;
CreateThread(NULL, 0, PipeThreadProc, 0, 0, &ThreadId);
return TRUE;
}
static char *month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
static char *dat[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
static VOID FormatTime(char * Time, time_t cTime)
{
struct tm * TM;
TM = gmtime(&cTime);
sprintf(Time, "%s, %02d %s %3d %02d:%02d:%02d GMT", dat[TM->tm_wday], TM->tm_mday, month[TM->tm_mon],
TM->tm_year + 1900, TM->tm_hour, TM->tm_min, TM->tm_sec);
}
#endif

455
ChatMonitor.c Normal file
View File

@ -0,0 +1,455 @@
// Mail and Chat Server for BPQ32 Packet Switch
//
// Monitor Window(s) Module
#include "BPQChat.h"
static char ClassName[]="BPQMONWINDOW";
static WNDPROC wpOrigInputProc;
static WNDPROC wpOrigOutputProc;
HWND hMonitor;
static HWND hwndInput;
static HWND hwndOutput;
static HMENU hMenu; // handle of menu
#define InputBoxHeight 25
RECT MonitorRect;
RECT OutputRect;
int Height, Width, LastY;
static char kbbuf[160];
static int kbptr=0;
static char * readbuff;
static int readbufflen;
static BOOL StripLF = TRUE;
static BOOL MonBBS = TRUE;
static BOOL MonCHAT = TRUE;
static BOOL MonTCP = TRUE;
BOOL LogBBS = TRUE;
BOOL LogCHAT = TRUE;
BOOL LogTCP = TRUE;
static int PartLinePtr=0;
static int PartLineIndex=0; // Listbox index of (last) incomplete line
static LRESULT CALLBACK MonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static LRESULT APIENTRY InputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static LRESULT APIENTRY OutputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static LRESULT APIENTRY MonProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static void MoveWindows();
#define BGCOLOUR RGB(236,233,216)
extern char MonitorSize[32];
BOOL CreateMonitor()
{
WNDCLASS wc;
HBRUSH bgBrush;
char Text[80];
if (hMonitor)
{
ShowWindow(hMonitor, SW_SHOWNORMAL);
SetForegroundWindow(hMonitor);
return FALSE; // Alreaqy open
}
bgBrush = CreateSolidBrush(BGCOLOUR);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MonWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInst;
wc.hIcon = LoadIcon( hInst, MAKEINTRESOURCE(BPQICON) );
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = bgBrush;
wc.lpszMenuName = NULL;
wc.lpszClassName = ClassName;
RegisterClass(&wc);
hMonitor=CreateDialog(hInst,ClassName,0,NULL);
if (!hMonitor)
return (FALSE);
wsprintf(Text, "Chat %s Monitor", Session);
SetWindowText(hMonitor, Text);
readbuff = zalloc(1000);
readbufflen = 1000;
hMenu=GetMenu(hMonitor);
CheckMenuItem(hMenu,MONBBS, MonBBS ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hMenu,MONCHAT, MonCHAT ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hMenu,MONTCP, MonTCP ? MF_CHECKED : MF_UNCHECKED);
DrawMenuBar(hWnd);
// Retrieve the handlse to the edit controls.
hwndOutput = GetDlgItem(hMonitor, 121);
// Set our own WndProcs for the controls.
wpOrigOutputProc = (WNDPROC)SetWindowLong(hwndOutput, GWL_WNDPROC, (LONG)OutputProc);
if (cfgMinToTray)
{
AddTrayMenuItem(hMonitor, Text);
}
ShowWindow(hMonitor, SW_SHOWNORMAL);
if (MonitorRect.right < 100 || MonitorRect.bottom < 100)
{
GetWindowRect(hMonitor, &MonitorRect);
}
MoveWindow(hMonitor,MonitorRect.left,MonitorRect.top, MonitorRect.right-MonitorRect.left, MonitorRect.bottom-MonitorRect.top, TRUE);
MoveWindows();
return TRUE;
}
static void MoveWindows()
{
RECT rcMain, rcClient;
int ClientHeight, ClientWidth;
GetWindowRect(hMonitor, &rcMain);
GetClientRect(hMonitor, &rcClient);
ClientHeight = rcClient.bottom;
ClientWidth = rcClient.right;
// MoveWindow(hwndMon,2, 0, ClientWidth-4, SplitPos, TRUE);
MoveWindow(hwndOutput,2, 2, ClientWidth-4, ClientHeight-4, TRUE);
// MoveWindow(hwndSplit,0, SplitPos, ClientWidth, SplitBarHeight, TRUE);
}
static LRESULT CALLBACK MonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
LPRECT lprc;
switch (message) {
case WM_ACTIVATE:
SetFocus(hwndInput);
break;
case WM_COMMAND:
wmId = LOWORD(wParam); // Remember, these are...
wmEvent = HIWORD(wParam); // ...different for Win32!
switch (wmId) {
case MONBBS:
ToggleParam(hMenu, hWnd, &MonBBS, MONBBS);
break;
case MONCHAT:
ToggleParam(hMenu, hWnd, &MonCHAT, MONCHAT);
break;
case MONTCP:
ToggleParam(hMenu, hWnd, &MonTCP, MONTCP);
break;
case BPQCLEAROUT:
SendMessage(hwndOutput,LB_RESETCONTENT, 0, 0);
break;
case BPQCOPYOUT:
CopyToClipboard(hwndOutput);
break;
//case BPQHELP:
// HtmlHelp(hWnd,"BPQTerminal.chm",HH_HELP_FINDER,0);
// break;
default:
return 0;
}
case WM_SYSCOMMAND:
wmId = LOWORD(wParam); // Remember, these are...
wmEvent = HIWORD(wParam); // ...different for Win32!
switch (wmId) {
case SC_MINIMIZE:
if (cfgMinToTray)
return ShowWindow(hWnd, SW_HIDE);
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
case WM_SIZING:
lprc = (LPRECT) lParam;
Height = lprc->bottom-lprc->top;
Width = lprc->right-lprc->left;
MoveWindows();
return TRUE;
case WM_DESTROY:
// Remove the subclass from the edit control.
GetWindowRect(hWnd, &MonitorRect); // For save soutine
SetWindowLong(hwndInput, GWL_WNDPROC,
(LONG) wpOrigInputProc);
if (cfgMinToTray)
DeleteTrayMenuItem(hWnd);
hMonitor = NULL;
free(readbuff);
readbufflen = 0;
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}
LRESULT APIENTRY OutputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// Trap mouse messages, so we cant select stuff in output and mon windows,
// otherwise scrolling doesnt work.
if (uMsg >= WM_MOUSEFIRST && uMsg <= WM_LBUTTONDBLCLK)
return TRUE;
return CallWindowProc(wpOrigOutputProc, hwnd, uMsg, wParam, lParam);
}
int WritetoMonitorWindow(char * Msg, int len)
{
char * ptr1, * ptr2;
int index;
if (len+PartLinePtr > readbufflen)
{
readbufflen += len+PartLinePtr;
readbuff = realloc(readbuff, readbufflen);
}
if (PartLinePtr != 0)
SendMessage(hwndOutput,LB_DELETESTRING,PartLineIndex,(LPARAM)(LPCTSTR) 0 );
memcpy(&readbuff[PartLinePtr], Msg, len);
len=len+PartLinePtr;
ptr1=&readbuff[0];
readbuff[len]=0;
do {
ptr2=memchr(ptr1,7,len);
if (ptr2)
*(ptr2)=32;
} while (ptr2);
lineloop:
// if (PartLinePtr > 300)
// PartLinePtr = 0;
if (len > 0)
{
// copy text to control a line at a time
ptr2=memchr(ptr1,13,len);
if (ptr2 == 0)
{
// no newline. Move data to start of buffer and Save pointer
PartLinePtr=len;
memmove(readbuff,ptr1,len);
PartLineIndex=SendMessage(hwndOutput,LB_ADDSTRING,0,(LPARAM)(LPCTSTR) ptr1 );
SendMessage(hwndOutput,LB_SETCARETINDEX,(WPARAM) PartLineIndex, MAKELPARAM(FALSE, 0));
return (0);
}
*(ptr2++)=0;
index=SendMessage(hwndOutput,LB_ADDSTRING,0,(LPARAM)(LPCTSTR) ptr1 );
// if (LogOutput) WriteMonitorLine(ptr1, ptr2 - ptr1);
PartLinePtr=0;
len-=(ptr2-ptr1);
ptr1=ptr2;
if ((len > 0) && StripLF)
{
if (*ptr1 == 0x0a) // Line Feed
{
ptr1++;
len--;
}
}
if (index > 1200)
do{
index=SendMessage(hwndOutput,LB_DELETESTRING, 0, 0);
} while (index > 1000);
SendMessage(hwndOutput,LB_SETCARETINDEX,(WPARAM) index, MAKELPARAM(FALSE, 0));
goto lineloop;
}
return (0);
}
static int ToggleParam(HMENU hMenu, HWND hWnd, BOOL * Param, int Item)
{
*Param = !(*Param);
CheckMenuItem(hMenu,Item, (*Param) ? MF_CHECKED : MF_UNCHECKED);
return (0);
}
static void CopyToClipboard(HWND hWnd)
{
int i,n, len=0;
HGLOBAL hMem;
char * ptr;
//
// Copy List Box to clipboard
//
n = SendMessage(hWnd, LB_GETCOUNT, 0, 0);
for (i=0; i<n; i++)
{
len+=SendMessage(hWnd, LB_GETTEXTLEN, i, 0);
}
hMem=GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, len+n+n+1);
if (hMem != 0)
{
ptr=GlobalLock(hMem);
if (OpenClipboard(MainWnd))
{
// CopyScreentoBuffer(GlobalLock(hMem));
for (i=0; i<n; i++)
{
ptr+=SendMessage(hWnd, LB_GETTEXT, i, (LPARAM) ptr);
*(ptr++)=13;
*(ptr++)=10;
}
*(ptr)=0; // end of data
GlobalUnlock(hMem);
EmptyClipboard();
SetClipboardData(CF_TEXT,hMem);
CloseClipboard();
}
else
GlobalFree(hMem);
}
}
HANDLE LogHandle[4] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE};
char * Logs[4] = {"BBS", "CHAT", "TCP", "DEBUG"};
BOOL OpenLogfile(int Flags)
{
UCHAR FN[MAX_PATH];
time_t T;
struct tm * tm;
T = time(NULL);
tm = gmtime(&T);
sprintf(FN,"%s/logs/log_%02d%02d%02d_%s.txt", GetLogDirectory(), tm->tm_year-100, tm->tm_mon+1, tm->tm_mday, Logs[Flags]);
LogHandle[Flags] = CreateFile(FN,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
SetFilePointer(LogHandle[Flags], 0, 0, FILE_END);
return (LogHandle[Flags] != INVALID_HANDLE_VALUE);
}

1731
ChatMultiConsole.c Normal file

File diff suppressed because it is too large Load Diff

369
ChatUtilities.c Normal file
View File

@ -0,0 +1,369 @@
// Mail and Chat Server for BPQ32 Packet Switch
//
// Utility Routines
#include "BPQChat.h"
#include "Winspool.h"
int LogAge = 7;
int SEMCLASHES = 0;
VOID __cdecl Debugprintf(const char * format, ...)
{
char Mess[65536];
va_list(arglist);int Len;
va_start(arglist, format);
Len = vsprintf_s(Mess, sizeof(Mess), format, arglist);
ChatWriteLogLine(NULL, '!',Mess, Len, LOG_DEBUGx);
// #ifdef _DEBUG
strcat(Mess, "\r\n");
OutputDebugString(Mess);
// #endif
return;
}
VOID __cdecl Logprintf(int LogMode, ChatCIRCUIT * conn, int InOut, const char * format, ...)
{
char Mess[65536];
va_list(arglist);int Len;
va_start(arglist, format);
Len = vsprintf_s(Mess, sizeof(Mess), format, arglist);
ChatWriteLogLine(conn, InOut, Mess, Len, LogMode);
return;
}
void GetSemaphore(struct SEM * Semaphore, int ID)
{
//
// Wait for it to be free
//
if (Semaphore->Flag != 0)
{
Semaphore->Clashes++;
// Debugprintf("MailChat Semaphore Clash");
}
loop1:
while (Semaphore->Flag != 0)
{
Sleep(10);
}
//
// try to get semaphore
//
_asm{
mov eax,1
mov ebx, Semaphore
xchg [ebx],eax // this instruction is locked
cmp eax,0
jne loop1 // someone else got it - try again
;
; ok, we've got the semaphore
;
}
return;
}
void FreeSemaphore(struct SEM * Semaphore)
{
Semaphore->Flag=0;
return;
}
VOID __cdecl nodeprintf(ChatCIRCUIT * conn, const char * format, ...)
{
char Mess[65536];
int len;
va_list(arglist);
va_start(arglist, format);
len = vsprintf_s(Mess, sizeof(Mess), format, arglist);
ChatQueueMsg(conn, Mess, len);
ChatWriteLogLine(conn, '>',Mess, len-1, LOG_CHAT);
return;
}
// Costimised message handling routines.
/*
Variables - a subset of those used by FBB
$C : Number of the next message.
$I : First name of the connected user.
$L : Number of the latest message.
$N : Number of active messages.
$U : Callsign of the connected user.
$W : Inserts a carriage return.
$Z : Last message read by the user (L command).
%X : Number of messages for the user.
%x : Number of new messages for the user.
*/
VOID ExpandAndSendMessage(ChatCIRCUIT * conn, char * Msg, int LOG)
{
char NewMessage[10000];
char * OldP = Msg;
char * NewP = NewMessage;
char * ptr, * pptr;
int len;
char Dollar[] = "$";
char CR[] = "\r";
ptr = strchr(OldP, '$');
while (ptr)
{
len = ptr - OldP; // Chars before $
memcpy(NewP, OldP, len);
NewP += len;
switch (*++ptr)
{
case 'I': // First name of the connected user.
pptr = conn->UserPointer->Name;
break;
case 'W': // Inserts a carriage return.
pptr = CR;
break;
default:
pptr = Dollar; // Just Copy $
}
len = strlen(pptr);
memcpy(NewP, pptr, len);
NewP += len;
OldP = ++ptr;
ptr = strchr(OldP, '$');
}
strcpy(NewP, OldP);
len = RemoveLF(NewMessage, strlen(NewMessage));
ChatWriteLogLine(conn, '>', NewMessage, len, LOG);
ChatQueueMsg(conn, NewMessage, len);
}
BOOL isdigits(char * string)
{
// Returns TRUE id sting is decimal digits
int i, n = strlen(string);
for (i = 0; i < n; i++)
{
if (isdigit(string[i]) == FALSE) return FALSE;
}
return TRUE;
}
BOOL wildcardcompare(char * Target, char * Match)
{
// Do a compare with string *string string* *string*
// Strings should all be UC
char Pattern[100];
char * firststar;
strcpy(Pattern, Match);
firststar = strchr(Pattern,'*');
if (firststar)
{
int Len = strlen(Pattern);
if (Pattern[0] == '*' && Pattern[Len - 1] == '*') // * at start and end
{
Pattern[Len - 1] = 0;
return (BOOL)(strstr(Target, &Pattern[1]));
}
if (Pattern[0] == '*') // * at start
{
// Compare the last len - 1 chars of Target
int Targlen = strlen(Target);
int Comparelen = Targlen - (Len - 1);
if (Len == 1) // Just *
return TRUE;
if (Comparelen < 0) // Too Short
return FALSE;
return (memcmp(&Target[Comparelen], &Pattern[1], Len - 1) == 0);
}
// Must be * at end - compare first Len-1 char
return (memcmp(Target, Pattern, Len - 1) == 0);
}
// No WildCards - straight strcmp
return (strcmp(Target, Pattern) == 0);
}
int DeleteLogFiles()
{
WIN32_FIND_DATA ffd;
char szDir[MAX_PATH];
char File[MAX_PATH];
HANDLE hFind = INVALID_HANDLE_VALUE;
DWORD dwError=0;
LARGE_INTEGER ft;
time_t now = time(NULL);
int Age;
// Prepare string for use with FindFile functions. First, copy the
// string to a buffer, then append '\*' to the directory name.
strcpy(szDir, GetLogDirectory());
strcat(szDir, "\\logs\\Log_*.txt");
// Find the first file in the directory.
hFind = FindFirstFile(szDir, &ffd);
if (INVALID_HANDLE_VALUE == hFind)
{
return dwError;
}
// List all the files in the directory with some info about them.
do
{
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
OutputDebugString(ffd.cFileName);
}
else
{
ft.HighPart = ffd.ftCreationTime.dwHighDateTime;
ft.LowPart = ffd.ftCreationTime.dwLowDateTime;
ft.QuadPart -= 116444736000000000;
ft.QuadPart /= 10000000;
Age = (now - ft.LowPart) / 86400;
if (Age > LogAge)
{
sprintf(File, "%s/logs/%s%c", GetLogDirectory(), ffd.cFileName, 0);
DeleteFile(File);
}
}
}
while (FindNextFile(hFind, &ffd) != 0);
dwError = GetLastError();
FindClose(hFind);
return dwError;
}
int RemoveLF(char * Message, int len)
{
// Remove lf chars
char * ptr1, * ptr2;
ptr1 = ptr2 = Message;
while (len-- > 0)
{
*ptr2 = *ptr1;
if (*ptr1 == '\r')
if (*(ptr1+1) == '\n')
{
ptr1++;
len--;
}
ptr1++;
ptr2++;
}
return (ptr2 - Message);
}
char * ReadInfoFile(char * File)
{
int FileSize;
char MsgFile[MAX_PATH];
FILE * hFile;
char * MsgBytes;
struct stat STAT;
char * ptr1 = 0, * ptr2;
sprintf_s(MsgFile, sizeof(MsgFile), "%s/%s", GetBPQDirectory(), File);
if (stat(MsgFile, &STAT) == -1)
return NULL;
FileSize = STAT.st_size;
hFile = fopen(MsgFile, "rb");
if (hFile == NULL)
return NULL;
MsgBytes=malloc(FileSize+1);
fread(MsgBytes, 1, FileSize, hFile);
fclose(hFile);
MsgBytes[FileSize]=0;
// Replace LF or CRLF with CR
// First remove cr from crlf
ptr1 = MsgBytes;
while(ptr2 = strstr(ptr1, "\r\n"))
{
memmove(ptr2, ptr2 + 1, strlen(ptr2));
}
// Now replace lf with cr
ptr1 = MsgBytes;
while (*ptr1)
{
if (*ptr1 == '\n')
*(ptr1) = '\r';
ptr1++;
}
return MsgBytes;
}

758
ChatUtils.c Normal file
View File

@ -0,0 +1,758 @@
// Chat Server for BPQ32 Packet Switch
//
//
// Based on MailChat Version 1.4.48.1
#define _CRT_SECURE_NO_DEPRECATE
#include "BPQChat.h"
#include <new.h>
#define MaxSockets 64
extern ChatCIRCUIT ChatConnections[MaxSockets+1];
extern int NumberofChatStreams;
extern char ChatConfigName[MAX_PATH];
extern char Session[20];
extern int chatPaclen;
extern struct SEM ChatSemaphore;
extern struct SEM AllocSemaphore;
extern struct SEM ConSemaphore;
extern struct SEM OutputSEM;
extern char OtherNodesList[1000];
extern int MaxChatStreams;
extern char Position[81];
extern char PopupText[260];
extern int PopupMode;
extern int Bells, FlashOnBell, StripLF, WarnWrap, WrapInput, FlashOnConnect, CloseWindowOnBye;
extern char Version[32];
extern char ConsoleSize[32];
extern char MonitorSize[32];
extern char DebugSize[32];
extern char WindowSize[32];
extern int RunningConnectScript;
INT_PTR CALLBACK InfoDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
int GetMultiLineDialog(HWND hDialog, int DLGItem);
BOOL ProcessChatConnectScript(ChatCIRCUIT * conn, char * Buffer, int len);
VOID WriteMiniDump();
int Connected(int Stream)
{
int n;
ChatCIRCUIT * conn;
struct UserInfo * user = NULL;
char callsign[10];
int port, paclen, maxframe, l4window;
char ConnectedMsg[] = "*** CONNECTED ";
char Msg[100];
LINK *link;
KNOWNNODE *node;
for (n = 0; n < NumberofChatStreams; n++)
{
conn = &ChatConnections[n];
if (Stream == conn->BPQStream)
{
if (conn->Active)
{
// Probably an outgoing connect
if (conn->rtcflags == p_linkini)
{
conn->paclen = chatPaclen;
// Run first line of connect script
ProcessChatConnectScript(conn, ConnectedMsg, 15);
return 0;
// nprintf(conn, "c %s\r", conn->u.link->call);
}
return 0;
}
memset(conn, 0, sizeof(ChatCIRCUIT)); // Clear everything
conn->Active = TRUE;
conn->BPQStream = Stream;
conn->Secure_Session = GetConnectionInfo(Stream, callsign,
&port, &conn->SessType, &paclen, &maxframe, &l4window);
if (paclen > chatPaclen || paclen == 0)
paclen = chatPaclen;
conn->paclen = paclen;
strlop(callsign, ' '); // Remove trailing spaces
memcpy(conn->Callsign, callsign, 10);
strlop(callsign, '-'); // Remove any SSID
user = zalloc(sizeof(struct UserInfo));
strcpy(user->Call, callsign);
conn->UserPointer = user;
n=sprintf_s(Msg, sizeof(Msg), "Incoming Connect from %s", user->Call);
// Send SID and Prompt
ChatWriteLogLine(conn, '|',Msg, n, LOG_CHAT);
conn->Flags |= CHATMODE;
nodeprintf(conn, ChatSID, Ver[0], Ver[1], Ver[2], Ver[3]);
// See if from a defined node
for (link = link_hd; link; link = link->next)
{
if (matchi(conn->Callsign, link->call))
{
conn->rtcflags = p_linkwait;
return 0; // Wait for *RTL
}
}
// See if from a previously known node
// I'm not sure this is safe. If it really is from a node the *RTL will be rejected
// Actually this protects against repeated attempts from a node that isn't configured. Maybe leave as is
node = knownnode_find(conn->Callsign);
if (node)
{
// A node is trying to link, but we don't have it defined - close
Logprintf(LOG_CHAT, conn, '!', "Node %s connected, but is not defined as a Node - closing",
conn->Callsign);
nodeprintf(conn, "Node %s does not have %s defined as a node to link to - closing.\r",
OurNode, conn->Callsign);
ChatFlush(conn);
Sleep(500);
conn->rtcflags = p_nil;
Disconnect(conn->BPQStream);
return 0;
}
if (user->Name[0] == 0)
{
char * Name = lookupuser(user->Call);
if (Name)
{
if (strlen(Name) > 17)
Name[17] = 0;
strcpy(user->Name, Name);
free(Name);
}
else
{
conn->Flags |= GETTINGUSER;
nputs(conn, NewUserPrompt);
return TRUE;
}
}
SendWelcomeMsg(Stream, conn, user);
RefreshMainWindow();
ChatFlush(conn);
return 0;
}
}
return 0;
}
int Disconnected (int Stream)
{
struct UserInfo * user = NULL;
ChatCIRCUIT * conn;
int n;
char Msg[255];
int len;
struct _EXCEPTION_POINTERS exinfo;
for (n = 0; n <= NumberofChatStreams-1; n++)
{
conn=&ChatConnections[n];
if (Stream == conn->BPQStream)
{
if (conn->Active == FALSE)
{
return 0;
}
ChatClearQueue(conn);
conn->Active = FALSE;
if (conn->Flags & CHATMODE)
{
if (conn->Flags & CHATLINK && conn->u.link)
{
// if running connect script, clear script active
if (conn->u.link->flags & p_linkini)
{
RunningConnectScript = 0;
conn->u.link->scriptRunning = 0;
}
len = sprintf_s(Msg, sizeof(Msg), "Chat Node %s Disconnected", conn->u.link->call);
ChatWriteLogLine(conn, '|',Msg, len, LOG_CHAT);
__try {link_drop(conn);} My__except_Routine("link_drop");
}
else
{
len=sprintf_s(Msg, sizeof(Msg), "Chat User %s Disconnected", conn->Callsign);
ChatWriteLogLine(conn, '|',Msg, len, LOG_CHAT);
__try
{
logout(conn);
}
#define EXCEPTMSG "logout"
#include "StdExcept.c"
}
}
conn->Flags = 0;
conn->u.link = NULL;
conn->UserPointer = NULL;
}
// RefreshMainWindow();
return 0;
}
}
return 0;
}
int DoReceivedData(int Stream)
{
int count, InputLen;
UINT MsgLen;
int n;
ChatCIRCUIT * conn;
struct UserInfo * user;
char * ptr, * ptr2;
char Buffer[10000];
int Written;
for (n = 0; n < NumberofChatStreams; n++)
{
conn = &ChatConnections[n];
if (Stream == conn->BPQStream)
{
do
{
// May have several messages per packet, or message split over packets
if (conn->InputLen + 1000 > 10000) // Shouldnt have lines longer than this in text mode
conn->InputLen = 0; // discard
GetMsg(Stream, &conn->InputBuffer[conn->InputLen], &InputLen, &count);
if (InputLen == 0) return 0;
if (conn->DebugHandle) // Receiving a Compressed Message
WriteFile(conn->DebugHandle, &conn->InputBuffer[conn->InputLen],
InputLen, &Written, NULL);
conn->Watchdog = 900; // 15 Minutes
conn->InputLen += InputLen;
{
loop:
if (conn->InputLen == 1 && conn->InputBuffer[0] == 0) // Single Null
{
conn->InputLen = 0;
if (conn->u.user->circuit && conn->u.user->circuit->rtcflags & p_user) // Local User
conn->u.user->lastmsgtime = time(NULL);
return 0;
}
ptr = memchr(conn->InputBuffer, '\r', conn->InputLen);
if (ptr) // CR in buffer
{
user = conn->UserPointer;
ptr2 = &conn->InputBuffer[conn->InputLen];
if (++ptr == ptr2)
{
// Usual Case - single meg in buffer
__try
{
if (conn->rtcflags == p_linkini) // Chat Connect
ProcessChatConnectScript(conn, conn->InputBuffer, conn->InputLen);
else
ProcessLine(conn, user, conn->InputBuffer, conn->InputLen);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
conn->InputBuffer[conn->InputLen] = 0;
Debugprintf("CHAT *** Program Error Processing input %s ", conn->InputBuffer);
Disconnect(conn->BPQStream);
conn->InputLen=0;
CheckProgramErrors();
return 0;
}
conn->InputLen=0;
}
else
{
// buffer contains more that 1 message
MsgLen = conn->InputLen - (ptr2-ptr);
memcpy(Buffer, conn->InputBuffer, MsgLen);
__try
{
if (conn->rtcflags == p_linkini)
ProcessChatConnectScript(conn, Buffer, MsgLen);
else
ProcessLine(conn, user, Buffer, MsgLen);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
Buffer[MsgLen] = 0;
Debugprintf("CHAT *** Program Error Processing input %s ", Buffer);
Disconnect(conn->BPQStream);
conn->InputLen=0;
CheckProgramErrors();
return 0;
}
if (*ptr == 0 || *ptr == '\n')
{
/// CR LF or CR Null
ptr++;
conn->InputLen--;
}
memmove(conn->InputBuffer, ptr, conn->InputLen-MsgLen);
conn->InputLen -= MsgLen;
goto loop;
}
}
else
{
// no cr - testing..
// Debugprintf("Test");
}
}
} while (count > 0);
return 0;
}
}
// Socket not found
return 0;
}
int ConnectState(Stream)
{
int state;
SessionStateNoAck(Stream, &state);
return state;
}
UCHAR * EncodeCall(UCHAR * Call)
{
static char axcall[10];
ConvToAX25(Call, axcall);
return &axcall[0];
}
VOID SendWelcomeMsg(int Stream, ChatCIRCUIT * conn, struct UserInfo * user)
{
if (!rtloginu (conn, TRUE))
{
// Already connected - close
ChatFlush(conn);
Sleep(1000);
Disconnect(conn->BPQStream);
}
return;
}
VOID SendPrompt(ChatCIRCUIT * conn, struct UserInfo * user)
{
nodeprintf(conn, "de %s>\r", OurNode);
}
VOID ProcessLine(ChatCIRCUIT * conn, struct UserInfo * user, char* Buffer, int len)
{
char seps[] = " \t\r";
struct _EXCEPTION_POINTERS exinfo;
{
GetSemaphore(&ChatSemaphore, 0);
__try
{
ProcessChatLine(conn, user, Buffer, len);
}
#define EXCEPTMSG "ProcessChatLine"
#include "StdExcept.c"
FreeSemaphore(&ChatSemaphore);
if (conn->BPQStream < 0)
CloseConsole(conn->BPQStream);
else
Disconnect(conn->BPQStream);
return;
}
FreeSemaphore(&ChatSemaphore);
return;
}
// Send if possible
ChatFlush(conn);
}
VOID SendUnbuffered(int stream, char * msg, int len)
{
if (stream < 0)
WritetoConsoleWindow(stream, msg, len);
else
SendMsg(stream, msg, len);
}
void TrytoSend()
{
// call Flush on any connected streams with queued data
ChatCIRCUIT * conn;
struct ConsoleInfo * Cons;
int n;
for (n = 0; n < NumberofChatStreams; n++)
{
conn = &ChatConnections[n];
if (conn->Active == TRUE)
ChatFlush(conn);
}
for (Cons = ConsHeader[0]; Cons; Cons = Cons->next)
{
if (Cons->Console)
ChatFlush(Cons->Console);
}
}
/*
char * FormatDateAndTime(time_t Datim, BOOL DateOnly)
{
struct tm *tm;
static char Date[]="xx-xxx hh:mmZ";
tm = gmtime(&Datim);
if (tm)
sprintf_s(Date, sizeof(Date), "%02d-%3s %02d:%02dZ",
tm->tm_mday, month[tm->tm_mon], tm->tm_hour, tm->tm_min);
if (DateOnly)
{
Date[6]=0;
return Date;
}
return Date;
}
*/
VOID FreeList(char ** Hddr)
{
VOID ** Save;
if (Hddr)
{
Save = Hddr;
while(Hddr[0])
{
free(Hddr[0]);
Hddr++;
}
free(Save);
}
}
#define LIBCONFIG_STATIC
#include "libconfig.h"
static config_t cfg;
static config_setting_t * group;
extern char ChatWelcomeMsg[1000];
VOID SaveIntValue(config_setting_t * group, char * name, int value)
{
config_setting_t *setting;
setting = config_setting_add(group, name, CONFIG_TYPE_INT);
if(setting)
config_setting_set_int(setting, value);
}
VOID SaveStringValue(config_setting_t * group, char * name, char * value)
{
config_setting_t *setting;
setting = config_setting_add(group, name, CONFIG_TYPE_STRING);
if (setting)
config_setting_set_string(setting, value);
}
int GetIntValue(config_setting_t * group, char * name, int Default)
{
config_setting_t *setting;
setting = config_setting_get_member (group, name);
if (setting)
return config_setting_get_int (setting);
return Default;
}
BOOL GetStringValue(config_setting_t * group, char * name, char * value)
{
const char * str;
config_setting_t *setting;
setting = config_setting_get_member (group, name);
if (setting)
{
str = config_setting_get_string (setting);
strcpy(value, str);
return TRUE;
}
return FALSE;
}
BOOL GetChatConfig(char * ConfigName)
{
config_init(&cfg);
/* Read the file. If there is an error, report it and exit. */
if(! config_read_file(&cfg, ConfigName))
{
fprintf(stderr, "%d - %s\n",
config_error_line(&cfg), config_error_text(&cfg));
config_destroy(&cfg);
return(EXIT_FAILURE);
}
group = config_lookup (&cfg, "Chat");
if (group == NULL)
return EXIT_FAILURE;
ChatApplNum = GetIntValue(group, "ApplNum", 0);
MaxChatStreams = GetIntValue(group, "MaxStreams", 0);
GetStringValue(group, "OtherChatNodes", OtherNodesList);
GetStringValue(group, "ChatWelcomeMsg", ChatWelcomeMsg);
GetStringValue(group, "MapPosition", Position);
GetStringValue(group, "MapPopup", PopupText);
PopupMode = GetIntValue(group, "PopupMode", 0);
Bells = GetIntValue(group, "Bells", 0);
FlashOnBell = GetIntValue(group, "FlashOnBell",0 );
StripLF = GetIntValue(group, "StripLF", 0);
WarnWrap = GetIntValue(group, "WarnWrap", 0);
WrapInput = GetIntValue(group, "WrapInput",0 );
FlashOnConnect = GetIntValue(group, "FlashOnConnect", 0);
CloseWindowOnBye = GetIntValue(group, "CloseWindowOnBye", 0);
GetStringValue(group, "ConsoleSize", ConsoleSize);
GetStringValue(group, "MonitorSize", MonitorSize);
GetStringValue(group, "DebugSize", DebugSize);
GetStringValue(group, "WindowSize", WindowSize);
GetStringValue(group, "Version", Version);
return EXIT_SUCCESS;
}
VOID SaveChatConfigFile(char * File)
{
config_setting_t *root, *group;
// Get rid of old config before saving
config_init(&cfg);
root = config_root_setting(&cfg);
group = config_setting_add(root, "Chat", CONFIG_TYPE_GROUP);
SaveIntValue(group, "ApplNum", ChatApplNum);
SaveIntValue(group, "MaxStreams", MaxChatStreams);
SaveStringValue(group, "OtherChatNodes", OtherNodesList);
SaveStringValue(group, "ChatWelcomeMsg", ChatWelcomeMsg);
SaveStringValue(group, "MapPosition", Position);
SaveStringValue(group, "MapPopup", PopupText);
SaveIntValue(group, "PopupMode", PopupMode);
SaveIntValue(group, "Bells", Bells);
SaveIntValue(group, "FlashOnBell", FlashOnBell);
SaveIntValue(group, "StripLF", StripLF);
SaveIntValue(group, "WarnWrap", WarnWrap);
SaveIntValue(group, "WrapInput", WrapInput);
SaveIntValue(group, "FlashOnConnect", FlashOnConnect);
SaveIntValue(group, "CloseWindowOnBye", CloseWindowOnBye);
SaveStringValue(group, "ConsoleSize", ConsoleSize);
SaveStringValue(group, "MonitorSize", MonitorSize);
SaveStringValue(group, "DebugSize", DebugSize);
SaveStringValue(group, "WindowSize",WindowSize );
SaveStringValue(group, "Version",Version );
if(! config_write_file(&cfg, File))
{
fprintf(stderr, "Error while writing file.\n");
config_destroy(&cfg);
return;
}
config_destroy(&cfg);
}
VOID SaveChatConfig(HWND hDlg)
{
BOOL OK1;
HKEY hKey=0;
int OldChatAppl;
char * ptr1;
char * Save, * Context;
OldChatAppl = ChatApplNum;
ChatApplNum = GetDlgItemInt(hDlg, ID_CHATAPPL, &OK1, FALSE);
MaxChatStreams = GetDlgItemInt(hDlg, ID_STREAMS, &OK1, FALSE);
if (ChatApplNum)
{
ptr1=GetApplCall(ChatApplNum);
if (ptr1 && (*ptr1 < 0x21))
{
MessageBox(NULL, "WARNING - There is no APPLCALL in BPQCFG matching the confgured ChatApplNum. Chat will not work",
"BPQMailChat", MB_ICONINFORMATION);
}
}
GetMultiLineDialog(hDlg, IDC_ChatNodes);
// Show dialog box now - gives time for links to close
// reinitialise other nodes list. rtlink messes with the string so pass copy
node_close();
if (ChatApplNum == OldChatAppl)
wsprintf(InfoBoxText, "Configuration Changes Saved and Applied");
else
wsprintf(InfoBoxText, "Warning Program must be restarted to change Chat Appl Num");
DialogBox(hInst, MAKEINTRESOURCE(IDD_USERADDED_BOX), hWnd, InfoDialogProc);
Sleep(2);
// Dont call removelinks - they may still be attached to a circuit. Just clear header
link_hd = NULL;
// Set up other nodes list. rtlink messes with the string so pass copy
Save = ptr1 = strtok_s(_strdup(OtherNodesList), "\r\n", &Context);
while (ptr1 && ptr1[0])
{
rtlink(ptr1);
ptr1 = strtok_s(NULL, "\r\n", &Context);
}
// if (strchr(ptr1, '|') == 0) // No script
// while (*ptr1)
// {
// if (*ptr1 == '\r')
// {
// while (*(ptr1+2) == '\r') // Blank line
// ptr1+=2;
// *++ptr1 = 32;
// }
// *ptr2++=*ptr1++;
// }
// *ptr2++ = 0;
free(Save);
if (user_hd) // Any Users?
makelinks(); // Bring up links
SaveChatConfigFile(ChatConfigName); // Commit to file
GetChatConfig(ChatConfigName);
}

5988
Cmd.c Normal file

File diff suppressed because it is too large Load Diff

62
CmdLineAuth.c Normal file
View File

@ -0,0 +1,62 @@
// CmdLineAuth.cpp : Defines the entry point for the console application.
//
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _CRT_SECURE_NO_DEPRECATE
#define _USE_32BIT_TIME_T
#include <stdio.h>
#include <time.h>
#include <stdio.h>
#include "md5.c"
VOID CreateOneTimePassword(char * KeyPhrase)
{
// Create a time dependent One Time Password from the KeyPhrase
time_t NOW = time(NULL);
unsigned char Hash[16];
char Password[20];
char Key[1000];
int i, chr;
long long Val;
int PassCode;
NOW = NOW/30; // Only Change every 30 secs
sprintf(Key, "%s%x", KeyPhrase, NOW);
md5(Key, Hash);
for (i=0; i<16; i++)
{
chr = (Hash[i] & 31);
if (chr > 9) chr += 7;
Password[i] = chr + 48;
}
Password[16] = 0;
memcpy(&Val, Password, 8);
PassCode = Val % 1000000;
printf("Passcode is %06d\n", PassCode);
return;
}
int main(int argc, char * argv[])
{
if (argc < 2)
{
printf ("Need to supply KeyPhrase\n");
return 0;
}
CreateOneTimePassword(argv[1]);
return 0;
}

68
CmdLineAuth.cpp Normal file
View File

@ -0,0 +1,68 @@
// CmdLineAuth.cpp : Defines the entry point for the console application.
//
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _CRT_SECURE_NO_DEPRECATE
#define _USE_32BIT_TIME_T
#include <stdio.h>
#include <time.h>
#include <stdio.h>
#include "MD5.c"
int LastNow;
int PassCode;
VOID CreateOneTimePassword(char * KeyPhrase)
{
// Create a time dependent One Time Password from the KeyPhrase
time_t NOW = time(NULL);
unsigned char Hash[16];
char Password[20];
char Key[1000];
int i, chr;
long long Val;
NOW = NOW/30; // Only Change every 30 secs
if (NOW == LastNow)
return;
LastNow = NOW;
sprintf(Key, "%s%x", KeyPhrase, NOW);
md5(Key, Hash);
for (i=0; i<16; i++)
{
chr = (Hash[i] & 31);
if (chr > 9) chr += 7;
Password[i] = chr + 48;
}
Password[16] = 0;
memcpy(&Val, Password, 8);
PassCode = Val %= 1000000;
printf("Passcode is %d\n", PassCode);
return;
}
int main(int argc, char * argv[])
{
if (argc < 2)
{
printf ("Need to supply KeyPhrase\n");
return 0;
}
CreateOneTimePassword(argv[1]);
return 0;
}

5624
CommonCode.c Normal file

File diff suppressed because it is too large Load Diff

131
ConfigDirewolf.c Normal file
View File

@ -0,0 +1,131 @@
//
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _CRT_SECURE_NO_DEPRECATE
#include <Windows.h>
#include <mmsystem.h>
#include <stdio.h>
#include <malloc.h>
#pragma comment(lib, "winmm.lib")
WAVEFORMATEX wfx = { WAVE_FORMAT_PCM, 1, 12000, 24000, 2, 16, 0 };
WAVEOUTCAPS pwoc;
WAVEINCAPS pwic;
char * CaptureDevices = NULL;
char * PlaybackDevices = NULL;
int CaptureCount = 0;
int PlaybackCount = 0;
int CaptureIndex = -1; // Card number
int PlayBackIndex = -1;
HWAVEOUT hWaveOut = 0;
HWAVEIN hWaveIn = 0;
char CaptureNames[16][MAXPNAMELEN + 2] = { "" };
char PlaybackNames[16][MAXPNAMELEN + 2] = { "" };
void main(int argc, char * argv[])
{
int i;
FILE *file;
if (argc < 3)
return;
_strupr(argv[1]);
_strupr(argv[2]);
CaptureCount = waveInGetNumDevs();
CaptureDevices = malloc((MAXPNAMELEN + 2) * CaptureCount);
CaptureDevices[0] = 0;
printf("Capture Devices\r\n");
for (i = 0; i < CaptureCount; i++)
{
waveInOpen(&hWaveIn, i, &wfx, 0, 0, CALLBACK_NULL); //WAVE_MAPPER
waveInGetDevCaps((UINT_PTR)hWaveIn, &pwic, sizeof(WAVEINCAPS));
if (CaptureDevices)
strcat(CaptureDevices, ",");
strcat(CaptureDevices, pwic.szPname);
printf("%d %s\r\n", i, pwic.szPname);
memcpy(&CaptureNames[i][0], pwic.szPname, MAXPNAMELEN);
_strupr(&CaptureNames[i][0]);
}
printf("\r\n");
PlaybackCount = waveOutGetNumDevs();
PlaybackDevices = malloc((MAXPNAMELEN + 2) * PlaybackCount);
PlaybackDevices[0] = 0;
printf("Playback Devices\r\n");
for (i = 0; i < PlaybackCount; i++)
{
waveOutOpen(&hWaveOut, i, &wfx, 0, 0, CALLBACK_NULL); //WAVE_MAPPER
waveOutGetDevCaps((UINT_PTR)hWaveOut, &pwoc, sizeof(WAVEOUTCAPS));
if (PlaybackDevices[0])
strcat(PlaybackDevices, ",");
strcat(PlaybackDevices, pwoc.szPname);
printf("%i %s\r\n", i, pwoc.szPname);
memcpy(&PlaybackNames[i][0], pwoc.szPname, MAXPNAMELEN);
_strupr(&PlaybackNames[i][0]);
waveOutClose(hWaveOut);
}
for (i = 0; i < CaptureCount; i++)
{
if (strstr(&CaptureNames[i][0], argv[1]))
{
CaptureIndex = i;
break;
}
}
for (i = 0; i < PlaybackCount; i++)
{
if (strstr(&PlaybackNames[i][0], argv[2]))
{
PlayBackIndex = i;
break;
}
}
CopyFile("direwolf.in", "direwolf.conf", 0);
if ((file = fopen("direwolf.conf", "ab")) == NULL)
return;
printf("ADEVICE %d %d\r\n", CaptureIndex, PlayBackIndex);
fprintf(file, "ADEVICE %d %d\r\n", CaptureIndex, PlayBackIndex);
fclose(file);
printf("File updated");
}

197
ConfigSDR.c Normal file
View File

@ -0,0 +1,197 @@
//
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _CRT_SECURE_NO_DEPRECATE
#include <Windows.h>
#include <mmsystem.h>
#include <stdio.h>
#include <malloc.h>
#pragma comment(lib, "winmm.lib")
WAVEFORMATEX wfx = { WAVE_FORMAT_PCM, 1, 12000, 24000, 2, 16, 0 };
WAVEOUTCAPS pwoc;
WAVEINCAPS pwic;
char * CaptureDevices = NULL;
char * PlaybackDevices = NULL;
int CaptureCount = 0;
int PlaybackCount = 0;
int IndexA = -1; // Card number
int IndexB = -1; // Card number
int IndexC = -1; // Card number
int IndexD = -1; // Card number
int SPEAKERS = -1; // Card number
int Device = 0;
HWAVEOUT hWaveOut = 0;
HWAVEIN hWaveIn = 0;
char CaptureNames[16][MAXPNAMELEN + 2] = { "" };
char PlaybackNames[16][MAXPNAMELEN + 2] = { "" };
char * strlop(char * buf, char delim)
{
// Terminate buf at delim, and return rest of string
char * ptr;
if (buf == NULL) return NULL; // Protect
ptr = strchr(buf, delim);
if (ptr == NULL) return NULL;
*(ptr)++ = 0;
return ptr;
}
void main(int argc, char * argv[])
{
int i;
FILE *infile;
FILE *file;
char line[1024] = "";
char index[64];
char * ptr;
PlaybackCount = waveOutGetNumDevs();
PlaybackDevices = malloc((MAXPNAMELEN + 2) * PlaybackCount);
PlaybackDevices[0] = 0;
printf("Playback Devices\r\n");
for (i = 0; i < PlaybackCount; i++)
{
waveOutOpen(&hWaveOut, i, &wfx, 0, 0, CALLBACK_NULL); //WAVE_MAPPER
waveOutGetDevCaps((UINT_PTR)hWaveOut, &pwoc, sizeof(WAVEOUTCAPS));
if (PlaybackDevices[0])
strcat(PlaybackDevices, ",");
strcat(PlaybackDevices, pwoc.szPname);
printf("%i %s\r\n", i, pwoc.szPname);
memcpy(&PlaybackNames[i][0], pwoc.szPname, MAXPNAMELEN);
_strupr(&PlaybackNames[i][0]);
waveOutClose(hWaveOut);
}
printf("\r\n");
for (i = 0; i < PlaybackCount; i++)
{
if (strstr(&PlaybackNames[i][0], "CABLE-A"))
IndexA = i;
else if(strstr(&PlaybackNames[i][0], "CABLE-B"))
IndexB = i;
else if (strstr(&PlaybackNames[i][0], "CABLE-C"))
IndexC = i;
else if (strstr(&PlaybackNames[i][0], "CABLE-D"))
IndexD = i;
else if (strstr(&PlaybackNames[i][0], "SPEAKERS"))
SPEAKERS = i;
}
if ((infile = fopen("C:\\Users\\johnw\\AppData\\Roaming\\SDRplay\\SDRuno.ini", "rb")) == NULL)
return;
if ((file = fopen("C:\\Users\\johnw\\AppData\\Roaming\\SDRplay\\SDRuno.in.new", "wb")) == NULL)
return;
while ((fgets(line, 1023, infile)))
{
if (ptr = strstr(line, "iOutputAudioDeviceID"))
{
char * ptr2 = strchr(ptr, '=');
*ptr2 = 0;
Device = atoi(ptr2 + 1);
sprintf(index, "=%s", &PlaybackNames[Device][0]);
strlop(index, ' ');
strcat(index, "\r\n");
strcat(line, index);
}
fprintf(file, line);
}
fclose(file);
fclose(infile);
if ((infile = fopen("C:\\Users\\johnw\\AppData\\Roaming\\SDRplay\\SDRuno.in", "rb")) == NULL)
return;
if ((file = fopen("C:\\Users\\johnw\\AppData\\Roaming\\SDRplay\\SDRuno.ini", "wb")) == NULL)
return;
while ((fgets(line, 1023, infile)))
{
if (ptr = strstr(line, "CABLE-A"))
{
printf(line);
*ptr = 0;
sprintf(index, "%d\r\n", IndexA);
strcat(line, index);
printf(line);
}
if (ptr = strstr(line, "CABLE-B"))
{
printf(line);
*ptr = 0;
sprintf(index, "%d\r\n", IndexB);
strcat(line, index);
printf(line);
}
if (ptr = strstr(line, "CABLE-C"))
{
printf(line);
*ptr = 0;
sprintf(index, "%d\r\n", IndexC);
strcat(line, index);
printf(line);
}
if (ptr = strstr(line, "CABLE-D"))
{
printf(line);
*ptr = 0;
sprintf(index, "%d\r\n", IndexD);
strcat(line, index);
printf(line);
}
if (ptr = strstr(line, "SPEAKERS"))
{
printf(line);
*ptr = 0;
sprintf(index, "%d\r\n", SPEAKERS);
strcat(line, index);
printf(line);
}
fprintf(file, line);
}
fclose(file);
fclose(infile);
printf("File updated");
}

137
ConfigWinRPR.c Normal file
View File

@ -0,0 +1,137 @@
//
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _CRT_SECURE_NO_DEPRECATE
#include <Windows.h>
#include <mmsystem.h>
#include <stdio.h>
#include <malloc.h>
#pragma comment(lib, "winmm.lib")
WAVEFORMATEX wfx = { WAVE_FORMAT_PCM, 1, 12000, 24000, 2, 16, 0 };
WAVEOUTCAPS pwoc;
WAVEINCAPS pwic;
char * CaptureDevices = NULL;
char * PlaybackDevices = NULL;
int CaptureCount = 0;
int PlaybackCount = 0;
int CaptureIndex = -1; // Card number
int PlayBackIndex = -1;
HWAVEOUT hWaveOut = 0;
HWAVEIN hWaveIn = 0;
char CaptureNames[16][MAXPNAMELEN + 2] = { "" };
char PlaybackNames[16][MAXPNAMELEN + 2] = { "" };
void main(int argc, char * argv[])
{
int i;
FILE *file;
if (argc < 3)
return;
_strupr(argv[1]);
_strupr(argv[2]);
CaptureCount = waveInGetNumDevs();
CaptureDevices = malloc((MAXPNAMELEN + 2) * CaptureCount);
CaptureDevices[0] = 0;
printf("Capture Devices\r\n");
for (i = 0; i < CaptureCount; i++)
{
waveInOpen(&hWaveIn, i, &wfx, 0, 0, CALLBACK_NULL); //WAVE_MAPPER
waveInGetDevCaps((UINT_PTR)hWaveIn, &pwic, sizeof(WAVEINCAPS));
if (CaptureDevices)
strcat(CaptureDevices, ",");
strcat(CaptureDevices, pwic.szPname);
printf("%d %s\r\n", i + 1, pwic.szPname);
memcpy(&CaptureNames[i][0], pwic.szPname, MAXPNAMELEN);
_strupr(&CaptureNames[i][0]);
}
printf("\r\n");
PlaybackCount = waveOutGetNumDevs();
PlaybackDevices = malloc((MAXPNAMELEN + 2) * PlaybackCount);
PlaybackDevices[0] = 0;
printf("Playback Devices\r\n");
for (i = 0; i < PlaybackCount; i++)
{
waveOutOpen(&hWaveOut, i, &wfx, 0, 0, CALLBACK_NULL); //WAVE_MAPPER
waveOutGetDevCaps((UINT_PTR)hWaveOut, &pwoc, sizeof(WAVEOUTCAPS));
if (PlaybackDevices[0])
strcat(PlaybackDevices, ",");
strcat(PlaybackDevices, pwoc.szPname);
printf("%i %s\r\n", i + 1, pwoc.szPname);
memcpy(&PlaybackNames[i][0], pwoc.szPname, MAXPNAMELEN);
_strupr(&PlaybackNames[i][0]);
waveOutClose(hWaveOut);
}
for (i = 0; i < CaptureCount; i++)
{
if (strstr(&CaptureNames[i][0], argv[1]))
{
CaptureIndex = i;
break;
}
}
for (i = 0; i < PlaybackCount; i++)
{
if (strstr(&PlaybackNames[i][0], argv[2]))
{
PlayBackIndex = i;
break;
}
}
printf("RX:%d\r\nTX:%d\r\n", CaptureIndex + 1, PlayBackIndex + 1);
CopyFile("WinRPR_Config.in", "WinRPR_Config.txt", 0);
if ((file = fopen("WinRPR_Config.txt", "ab")) == NULL)
return;
fprintf(file, "[AUDIO]\r\n");
fprintf(file, "RX:%d\r\nTX:%d\r\n", CaptureIndex + 1, PlayBackIndex + 1);
fprintf(file, "[END]\r\n");
fclose(file);
printf("File updated");
}

406
DOSAPI.c Normal file
View File

@ -0,0 +1,406 @@
/*
Copyright 2001-2015 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
*/
//
// Implements the DOS register based API.
// Called via an assmbler glue that puts registers into C variables.
#define _CRT_SECURE_NO_DEPRECATE
#pragma data_seg("_BPQDATA")
#include "time.h"
#include "stdio.h"
#include <fcntl.h>
#include "compatbits.h"
#include "CHeaders.h"
extern QCOUNT;
extern BPQVECSTRUC BPQHOSTVECTOR[];
extern int MAJORVERSION;
extern int MINORVERSION;
extern char pgm[256]; // Uninitialised so per process
VOID PostDataAvailable(TRANSPORTENTRY * Session);
DllExport int APIENTRY SendMsg(int stream, char * msg, int len);
DllExport int APIENTRY AllocateStream(int stream);
DllExport int APIENTRY SendRaw(int port, char * msg, int len);
DllExport time_t APIENTRY GetRaw(int stream, char * msg, int * len, int * count);
VOID SENDNODESMSG();
int BTLENGTH;
char BTEXTFLD[256];
int REALTIMETICKS;
VOID CHOSTAPI(ULONG * pEAX, ULONG * pEBX, ULONG * pECX, ULONG * pEDX, VOID ** pESI, VOID ** pEDI)
{
ULONG EAX = *pEAX;
ULONG EBX = *pEBX;
ULONG ECX = *pECX;
ULONG EDX = *pEDX;
VOID * ESI = *pESI;
VOID * EDI = *pEDI;
int Command;
int Stream;
int n;
int Temp;
PBPQVECSTRUC HostVec;
TRANSPORTENTRY * Session;
/*
; COMMANDS SUPPORTED ARE
;
; AH = 0 Get node/switch version number and description. On return
; AH = major version number and AL = minor version number,
; and user's buffer pointed to by ES:ESI is set to the text
; string normally output by the USERS command, eg:
; "G8BPQ Packet Switch Version 4.01 Dev". CX is set to the
; length of the text string.
;
;
; AH = 1 Set application mask to value in DL (or even DX if 16
; applications are ever to be supported).
;
; Set application flag(s) to value in CL (or CX).
; whether user gets connected/disconnected messages issued
; by the node etc.
;
;
; AH = 2 Send frame in ES:ESI (length CX)
;
;
; AH = 3 Receive frame into buffer at ES:ESI, length of frame returned
; in CX. BX returns the number of outstanding frames still to
; be received (ie. after this one) or zero if no more frames
; (ie. this is last one).
;
;
;
; AH = 4 Get stream status. Returns:
;
; CX = 0 if stream disconnected or CX = 1 if stream connected
; DX = 0 if no change of state since last read, or DX = 1 if
; the connected/disconnected state has changed since
; last read (ie. delta-stream status).
;
;
;
; AH = 6 Session control.
;
; CX = 0 Conneect - _APPLMASK in DL
; CX = 1 connect
; CX = 2 disconnect
; CX = 3 return user to node
;
;
; AH = 7 Get buffer counts for stream. Returns:
;
; AX = number of status change messages to be received
; BX = number of frames queued for receive
; CX = number of un-acked frames to be sent
; DX = number of buffers left in node
; SI = number of trace frames queued for receive
;
;AH = 8 Port control/information. Called with a stream number
; in AL returns:
;
; AL = Radio port on which channel is connected (or zero)
; AH = SESSION TYPE BITS
; BX = L2 paclen for the radio port
; CX = L2 maxframe for the radio port
; DX = L4 window size (if L4 circuit, or zero)
; ES:EDI = CALLSIGN
;AH = 9 Fetch node/application callsign & alias. AL = application
; number:
;
; 0 = node
; 1 = BBS
; 2 = HOST
; 3 = SYSOP etc. etc.
;
; Returns string with alias & callsign or application name in
; user's buffer pointed to by ES:ESI length CX. For example:
;
; "WORCS:G8TIC" or "TICPMS:G8TIC-10".
;
;
; AH = 10 Unproto transmit frame. Data pointed to by ES:ESI, of
; length CX, is transmitted as a HDLC frame on the radio
; port (not stream) in AL.
;
;
; AH = 11 Get Trace (RAW Data) Frame into ES:EDI,
; Length to CX, Timestamp to AX
;
;
; AH = 12 Update Switch. At the moment only Beacon Text may be updated
; DX = Function
; 1=update BT. ES:ESI, Len CX = Text
; 2=kick off nodes broadcast
;
; AH = 14 Internal Interface for IP Router
;
; Send frame - to NETROM L3 if DL=0
; to L2 Session if DL<>0
;
;
; AH = 15 Get interval timer
;
*/
Command = (EAX & 0xFFFF) >> 8;
Stream = (EAX & 0xFF);
n = Stream - 1; // API Numbers Streams 1-64
if (n < 0 || n > 63)
n = 64;
HostVec = &BPQHOSTVECTOR[n];
Session = HostVec->HOSTSESSION;
switch (Command)
{
case 0: // Check Loaded/Get Version
EAX = ('P' << 8) | 'B';
EBX = ('Q' << 8) | ' ';
EDX = (MAJORVERSION << 8) | MINORVERSION;
break;
case 1: // Set Appl mAsk
HostVec->HOSTAPPLMASK = EDX; // APPL MASK
HostVec->HOSTAPPLFLAGS = (UCHAR)ECX; // APPL FLAGS
// If either is non-zero, set allocated and Process. This gets round problem with
// stations that don't call allocate stream
if (ECX || EBX)
{
HostVec->HOSTFLAGS |= 0x80; // SET ALLOCATED BIT
HostVec->STREAMOWNER = GetCurrentProcessId();
// Set Program Name
memcpy(&HostVec->PgmName, pgm, 31);
}
break;
case 2: // Send Frame
// ES:ESI = MESSAGE, CX = LENGTH, BX = VECTOR
EAX = SendMsg(Stream, ESI, ECX);
break;
case 3:
// AH = 3 Receive frame into buffer at ES:EDI, length of frame returned
// in CX. BX returns the number of outstanding frames still to
// be received (ie. after this one) or zero if no more frames
// (ie. this is last one).
EAX = GetMsg(Stream, EDI, &ECX, &EBX);
break;
case 4:
// AH = 4 Get stream status. Returns:
// CX = 0 if stream disconnected or CX = 1 if stream connected
// DX = 0 if no change of state since last read, or DX = 1 if
// the connected/disconnected state has changed since
// last read (ie. delta-stream status).
ECX = EDX = 0;
if (HostVec->HOSTFLAGS & 3) //STATE CHANGE BITS
EDX = 1;
if (Session)
ECX = 1;
break;
case 5:
// AH = 5 Ack stream status change
HostVec->HOSTFLAGS &= 0xFC; // Clear Chnage Bits
break;
case 6:
// AH = 6 Session control.
// CX = 0 Conneect - APPLMASK in DL
// CX = 1 connect
// CX = 2 disconnect
// CX = 3 return user to node
SessionControl(Stream, ECX, EDX);
break;
case 7:
// AH = 7 Get buffer counts for stream. Returns:
// AX = number of status change messages to be received
// BX = number of frames queued for receive
// CX = number of un-acked frames to be sent
// DX = number of buffers left in node
// SI = number of trace frames queued for receive
ECX = 0; // unacked frames
EDX = QCOUNT;
ESI = (void *)MONCount(Stream);
EBX = RXCount(Stream);
ECX = TXCount(Stream);
EAX = 0; // Is this right ???
break;
case 8:
// AH = 8 Port control/information. Called with a stream number
// in AL returns:
//
// AL = Radio port on which channel is connected (or zero)
// AH = SESSION TYPE BITS
// BX = L2 paclen for the radio port
// CX = L2 maxframe for the radio port
// DX = L4 window size (if L4 circuit, or zero)
// ES:EDI = CALLSIGN
GetConnectionInfo(Stream, EDI, &EAX, &Temp, &EBX, &ECX, &EDX); // Return the Secure Session Flag rather than not connected
EAX |= Temp <<8;
break;
case 9:
// Not Implemented
break;
case 10:
// AH = 10 Unproto transmit frame. Data pointed to by ES:ESI, of
// length CX, is transmitted as a HDLC frame on the radio
// port (not stream) in AL.
EAX = SendRaw(EAX, ESI, ECX);
return;
case 11:
// AH = 11 Get Trace (RAW Data) Frame into ES:EDI,
// Length to CX, Timestamp to AX
EAX = GetRaw(Stream, EDI, &ECX, &EBX);
break;
case 12:
// Update Switch
if (EDX == 2)
{
SENDNODESMSG();
break;
}
if (EDX == 2)
{
// UPDATE BT
BTLENGTH = ECX;
memcpy(BTEXTFLD, ESI, ECX + 7);
}
break;
case 13:
// BPQALLOC
// AL = 0 = Find Free
// AL != 0 Alloc or Release
if (EAX == 0)
{
EAX = FindFreeStream();
break;
}
if (ECX == 1) // Allocate
{
EAX = AllocateStream(Stream);
break;
}
DeallocateStream(Stream);
break;
case 14:
// AH = 14 Internal Interface for IP Router
// Send frame - to NETROM L3 if DL=0
// to L2 Session if DL<>0
break; // Shouldn't be needed
case 15:
// GETTIME
EAX = REALTIMETICKS;
EBX = 0;
#ifdef EXCLUDEBITS
EBX = (ULONG)ExcludeList;
#endif
break;
}
*pEAX = EAX;
*pEBX = EBX;
*pECX = ECX;
*pEDX = EDX;
*pESI = ESI;
*pEDI = EDI;
return;
}

673
DRATS.c Normal file
View File

@ -0,0 +1,673 @@
/*
Copyright 2001-2022 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
*/
// DRATS support code
#define _CRT_SECURE_NO_DEPRECATE
#include "CHeaders.h"
#include "bpq32.h"
#include "telnetserver.h"
/*
The header is the first 23 bytes of of the frame. The payload is the rest of the frame.
Byte 1 is a "magic" number. It is 0xDD if the payload is zlib compressed before being yencoded.
Bytes 2 and 3 is a 16 bit sequence number.
Byte 4 is a session number.
Byte 5 is a type. Still don't know the types.
Bytes 6 and 7, 16 bits, is the checksum of the data after any compression.
Bytes 8 and 9, 16 bits, is the length of the data.
bytes 10-18, 8 bits, are the source call sign.
bytes 19-25, 8 bits, are the destination call sign.
If a call sign is less than 8 characters, it is padded to fill the space with the "~" tilde character.
Frame types: (Some from sessions/chat.py)
0 - T_DEF
1 - T_PING_REQ - Ping request (Used in Test frame)
2 - T_PING_RSP - Ping response
3 - T_PING_ERS - Ping error status?
4 - T_STATUS - Status frame
5 - File Transfer
8 - Used in Test frame
254 - Apparently a warm up frame.
T_DEF = 0
T_PNG_REQ = 1
T_PNG_RSP = 2
T_PNG_ERQ = 3
T_PNG_ERS = 4
T_STATUS = 5
For a station status frame, the first byte of the message is an ASCII station status value.
'0' - Unknown
'1' - Online
'2' - Unattended
'9' - Offline
*/
#define T_DEF 0
#define T_PNG_REQ 1
#define T_PNG_RSP 2
#define T_PNG_ERQ 3
#define T_PNG_ERS 4
#define T_STATUS 5
#pragma pack(1)
// shorts are big-endian
struct DRATSHeader
{
unsigned char Magic;
unsigned short Seq;
unsigned char Sessno;
unsigned char Type;
unsigned short CheckSum;
unsigned short Length;
char CallFrom[8];
char CallTo[8];
unsigned char Message[2048];
};
#pragma pack()
struct DRATSSession
{
struct ConnectionInfo * sockptr;
unsigned int Seq;
unsigned int Sessno;
char CallFrom[8];
char CallTo[8];
int Stream; // BPQ Stream
int StreamState;
struct DRATSQueue * Queue;
struct DRATSSession * Next;
};
struct DRATSQueue
{
// Queue of messages to be sent to node from background (ie not under semaphore)
int Stream;
int Len;
unsigned char * Msg;
struct DRATSQueue * Next;
};
struct DRATSSession * DRATSSessions = NULL;
char peer0_2[] = { /* Packet 17 */
0x5b, 0x53, 0x4f, 0x42, 0x5d, 0xdd, 0x3d, 0x40,
0x3d, 0x40, 0x01, 0x05, 0x45, 0x78, 0x3d, 0x40,
0x18, 0x47, 0x38, 0x42, 0x50, 0x51, 0x7e, 0x7e,
0x7e, 0x43, 0x51, 0x43, 0x51, 0x43, 0x51, 0x7e,
0x7e, 0x78, 0xda, 0x33, 0xf4, 0xcf, 0xcb, 0xc9,
0xcc, 0x4b, 0x55, 0xd0, 0x70, 0xd1, 0x0d, 0x72,
0x0c, 0x09, 0xd6, 0x04, 0x3d, 0x40, 0x2a, 0x8c,
0x04, 0xb3, 0x5b, 0x45, 0x4f, 0x42, 0x5d };
void processDRATSFrame(unsigned char * Message, int Len, struct ConnectionInfo * sockptr);
int testDRATS()
{
// processDRATSFrame(peer0_1, sizeof(peer0_1), 0);
// processDRATSFrame(peer0_2, sizeof(peer0_2), 0);
// processDRATSFrame(peer1_1, sizeof(peer1_1), 0);
// processDRATSFrame(peer1_20, sizeof(peer1_20));
// processDRATSFrame(peer0_20, sizeof(peer0_20));
// processDRATSFrame(peer1_21, sizeof(peer1_21));
return 0;
}
extern char pgm[256];
extern char TextVerstring[50];
int HeaderLen = offsetof(struct DRATSHeader, Message);
int doinflate(unsigned char * source, unsigned char * dest, int Len, int destlen, int * outLen);
int dratscrc(unsigned char *ptr, int count);
int FindFreeStreamNoSem();
void sendDRATSFrame(struct ConnectionInfo * sockptr, struct DRATSHeader * Header);
int yEncode(unsigned char * in, unsigned char * out, int len, unsigned char * Banned);
int AllocateDRATSStream(struct DRATSSession * Sess)
{
int Stream;
strcpy(pgm, "DRATS");
Stream = FindFreeStreamNoSem();
strcpy(pgm, "bpq32.exe");
if (Stream == 255) return 0;
if (memcmp(Sess->CallTo, "NODE", 4) == 0)
{
// Just connect to command level on switch
}
return Stream;
}
void ProcessDRATSPayload(struct DRATSHeader * Header, struct DRATSSession * Sess)
{
struct DRATSQueue * QEntry;
BPQVECSTRUC * HOST;
if (Sess->Stream == 0)
{
Sess->Stream = AllocateDRATSStream(Sess);
}
if (Sess->StreamState == 0)
{
unsigned char AXCall[10];
Connect(Sess->Stream); // Connect
ConvToAX25(Sess->CallFrom, AXCall);
ChangeSessionCallsign(Sess->Stream, AXCall); // Prevent triggering incoming connect code
// Clear State Changed bits (cant use SessionState under semaphore)
HOST = &BPQHOSTVECTOR[Sess->Stream -1]; // API counts from 1
HOST->HOSTFLAGS &= 0xFC; // Clear Change Bits
Sess->StreamState = 1;
}
strcat(Header->Message, "\r");
// Need to Queue to Background as we can't use SendMsg under semaphore
QEntry = zalloc(sizeof(struct DRATSQueue));
QEntry->Len = strlen(Header->Message);
QEntry->Msg = malloc(QEntry->Len);
memcpy(QEntry->Msg, Header->Message, QEntry->Len);
// Add to queue
if (Sess->Queue)
{
struct DRATSQueue * End = Sess->Queue;
// Add on end
while (End->Next)
End = End->Next;
End->Next = QEntry;
}
else
Sess->Queue = QEntry;
}
// Called under semaphore
void processDRATSFrame(unsigned char * Message, int Len, struct ConnectionInfo * sockptr)
{
unsigned char * Payload;
unsigned char * ptr;
unsigned char dest[2048];
struct DRATSHeader * Header;
int outLen;
struct DRATSSession * Sess = DRATSSessions;
unsigned short crc, savecrc;
char CallFrom[10] = "";
char CallTo[10] = "";
Message[Len] = 0;
Debugprintf(Message);
Payload = strstr(Message, "[SOB]");
if (Payload == 0)
return;
ptr = strstr(Message, "[EOB]");
if (ptr == 0)
return;
ptr[0] = 0;
Payload += 5;
Header = (struct DRATSHeader *)Payload;
// Undo = transparency
ptr = Payload;
while (ptr = strchr(ptr, '='))
{
memmove(ptr, ptr + 1, Len);
ptr[0] -= 64;
ptr++;
}
// Check CRC
savecrc = htons(Header->CheckSum);
Header->CheckSum = 0;
crc = dratscrc(Payload, htons(Header->Length) + HeaderLen);
if (crc != savecrc)
{
Debugprintf(" DRARS CRC Error %x %x", crc, savecrc); // Good CRC
return;
}
Header->Length = htons(Header->Length); // convert to machine order
if (Header->Magic == 0xdd) // Zlib compressed
{
doinflate(Header->Message, dest, Header->Length, 2048, &outLen);
memcpy(Header->Message, dest, outLen + 1);
Header->Length = outLen;
}
Debugprintf(Header->Message);
// Look for a matching From/To/Session
memcpy(CallFrom, Header->CallFrom, 8);
memcpy(CallTo, Header->CallTo, 8);
strlop(CallFrom, '~');
strlop(CallTo, '~');
if (Header->Type == T_STATUS)
{
// Status frame ?? What to do with it ??
return;
}
if (Header->Type == T_PNG_REQ)
{
// "Ping Request"
// if to "NODE" reply to it
if (strcmp(CallTo, "NODE") == 0)
{
// Reuse incoming message
strcpy(Header->CallFrom, CallTo);
strcpy(Header->CallTo, CallFrom);
Header->Type = T_PNG_RSP;
Header->Length = sprintf(Header->Message, "Running BPQ32 Version %s", TextVerstring);
sendDRATSFrame(sockptr, Header);
return;
}
// Not to us - do we route it ??
return;
}
if (Header->Type == T_PNG_RSP)
{
// Reponse is PNG_RSP then Status - 1Online (D-RATS)
// "Running D-RATS 0.3.9 (Windows 8->10 (6, 2, 9200, 2, ''))"
// "Running D-RATS 0.3.10 beta 4 (Linux - Raspbian GNU/Linux 9)"
return;
}
if (Header->Type != T_DEF)
{
return;
}
// ?? Normal Data
if (strcmp(CallTo, "NODE") != 0)
{
// Not not Node - should we route it ??
return;
}
while (Sess)
{
if (Sess->Sessno == Header->Sessno && memcmp(Sess->CallFrom, CallFrom, 8) == 0
&& memcmp(Sess->CallTo, CallTo, 8) == 0 && Sess->sockptr == sockptr)
{
ProcessDRATSPayload(Header, Sess);
return;
}
Sess = Sess->Next;
}
// Allocate a new one
Sess = zalloc(sizeof(struct DRATSSession));
Sess->Sessno = Header->Sessno;
memcpy(Sess->CallFrom, CallFrom, 8);
memcpy(Sess->CallTo, CallTo, 8);
Sess->sockptr = sockptr;
if (DRATSSessions)
{
// Add to front of Chain
Sess->Next = DRATSSessions;
}
DRATSSessions = Sess;
ProcessDRATSPayload(Header, Sess);
return;
}
void DRATSPoll()
{
struct DRATSSession * Sess = DRATSSessions;
int Stream, state, change;
int count;
struct DRATSHeader Header;
struct DRATSQueue * QEntry;
struct DRATSQueue * Save;
while (Sess)
{
Stream = Sess->Stream;
SessionState(Stream, &state, &change);
if (change == 1)
{
if (state == 1)
{
// Connected - do we need anything ??
}
else
{
// Send a disconnected message
char From[10] = "~~~~~~~~~";
char To[10] = "~~~~~~~~~";
Sess->StreamState = 0;
Header.Length = sprintf(Header.Message, "*** Disconnected from Node");
memcpy(To, Sess->CallFrom, strlen(Sess->CallFrom));
memcpy(From, Sess->CallTo, strlen(Sess->CallTo));
memcpy(Header.CallFrom, From, 8);
memcpy(Header.CallTo, To, 8);
Header.Magic = 0x22;
Header.Type = 0;
Header.Seq = 0;
Header.Sessno = Sess->Sessno;
sendDRATSFrame(Sess->sockptr, &Header);
}
}
do
{
int Len;
GetMsg(Stream, (char *)Header.Message, &Len, &count);
Header.Length = Len;
if (Header.Length)
{
char From[10] = "~~~~~~~~~";
char To[10] = "~~~~~~~~~";
memcpy(To, Sess->CallFrom, strlen(Sess->CallFrom));
memcpy(From, Sess->CallTo, strlen(Sess->CallTo));
memcpy(Header.CallFrom, From, 8);
memcpy(Header.CallTo, To, 8);
Header.Magic = 0x22;
Header.Type = 0;
Header.Seq = 0;
Header.Sessno = Sess->Sessno;
sendDRATSFrame(Sess->sockptr, &Header);
}
}
while (count > 0);
// See if anything to send to node
QEntry = Sess->Queue;
while (QEntry)
{
SendMsg(Sess->Stream, QEntry->Msg, QEntry->Len);
Save = QEntry;
QEntry = QEntry->Next;
free(Save->Msg);
free(Save);
}
Sess->Queue = 0;
Sess = Sess->Next;
}
}
unsigned char BANNED[] = {'=', 0x11, 0x13, 0x1A, 0xFD, 0xFE, 0xFF, 0};
void sendDRATSFrame(struct ConnectionInfo * sockptr, struct DRATSHeader * Header)
{
unsigned short crc;
int len;
unsigned char out[2048] = "[SOB]";
int packetLen = Header->Length + HeaderLen;
// Length is in host order
Header->Length = htons(Header->Length);
Header->CheckSum = 0;
crc = dratscrc((unsigned char *)Header, packetLen);
Header->CheckSum = htons(crc);
len = yEncode((unsigned char *)Header, out + 5, packetLen, BANNED);
memcpy(&out[len + 5], "[EOB]", 5);
Debugprintf(out);
send(sockptr->socket, out, len + 10, 0);
}
void DRATSConnectionLost(struct ConnectionInfo * sockptr)
{
// Disconnect any sessions, then free Stream and Sess record
struct DRATSSession * Sess = DRATSSessions;
struct DRATSSession * Save = 0;
BPQVECSTRUC * HOST;
while (Sess)
{
if (Sess->sockptr == sockptr)
{
if (Sess->StreamState == 1) // COnnected
{
Disconnect(Sess->Stream);
HOST = &BPQHOSTVECTOR[Sess->Stream -1]; // API counts from 1
HOST->HOSTFLAGS &= 0xFC; // Clear Change Bits
}
DeallocateStream(Sess->Stream);
// We must unhook from chain
if (Save)
Save->Next = Sess->Next;
else
DRATSSessions = Sess->Next;
// Should really Free any Queue, but unlikely to be any
free(Sess);
if (Save)
Sess = Save->Next;
else
Sess = DRATSSessions;
}
else
{
Save = Sess;
Sess = Sess->Next;
}
}
}
#ifdef WIN32
#define ZEXPORT __stdcall
#endif
#include <zlib.h>
int doinflate(unsigned char * source, unsigned char * dest, int Len, int destlen, int * outLen)
{
int ret;
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
strm.avail_in = Len;
strm.next_in = source;
strm.avail_out = destlen;
strm.next_out = dest;
ret = inflate(&strm, Z_NO_FLUSH);
inflateEnd(&strm);
dest[strm.total_out] = 0;
*outLen = strm.total_out;
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
// No idea what this CRC is, but it works! (converted from DRATS python code)
int update_crc(int c, int crc)
{
int i;
int v;
for (i = 0; i < 8; i++)
{
if ((c & 0x80))
v = 1;
else
v = 0;
if (crc & 0x8000)
{
crc <<= 1;
crc += v;
crc ^= 0x1021;
}
else
{
crc <<= 1;
crc += v;
}
c <<= 1;
}
crc &= 0xFFFF;
return crc;
}
int dratscrc(unsigned char *ptr, int count)
{
int i;
int checksum = 0;
for (i = 0; i < count; i++)
checksum = update_crc(ptr[i], checksum);
checksum = update_crc(0, checksum);
checksum = update_crc(0, checksum);
return checksum;
}
#define OFFSET 64
int yEncode(unsigned char * in, unsigned char * out, int len, unsigned char * Banned)
{
unsigned char * ptr = out;
unsigned char c;
while (len--)
{
c = *(in++);
if (strchr(&Banned[0], c))
{
*(out++) = '=';
*(out++) = (c + OFFSET) & 0xFF;
}
else
*(out++) = c;
}
return (out - ptr);
}

2257
Dragon.c Normal file

File diff suppressed because it is too large Load Diff

238
Events.c Normal file
View File

@ -0,0 +1,238 @@
/*
Copyright 2001-2022 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
*/
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _CRT_SECURE_NO_DEPRECATE
#include "compatbits.h"
#include <string.h>
#include "asmstrucs.h"
#include "tncinfo.h"
VOID __cdecl Debugprintf(const char * format, ...);
#ifndef WIN32
#define APIENTRY
#define DllExport
#define VOID void
#else
#include <windows.h>
#endif
extern BOOL EventsEnabled;
void MQTTReportSession(char * Msg);
extern int MQTT;
extern char Modenames[19][10];
// Runs use specified routine on certain event
#ifndef WIN32
void RunEventProgram(char * Program, char * Param)
{
char * arg_list[] = {Program, NULL, NULL};
pid_t child_pid;
if (EventsEnabled == 0)
return;
signal(SIGCHLD, SIG_IGN); // Silently (and portably) reap children.
if (Param && Param[0])
arg_list[1] = Param;
// Fork and Exec Specified program
// Duplicate this process.
child_pid = fork ();
if (child_pid == -1)
{
printf ("Event fork() Failed\n");
return;
}
if (child_pid == 0)
{
execvp (arg_list[0], arg_list);
// The execvp function returns only if an error occurs.
printf ("Failed to run %s\n", arg_list[0]);
exit(0); // Kill the new process
}
#else
DllExport void APIENTRY RunEventProgram(char * Program, char * Param)
{
int n = 0;
char cmdLine[256];
STARTUPINFO SInfo; // pointer to STARTUPINFO
PROCESS_INFORMATION PInfo; // pointer to PROCESS_INFORMATION
if (EventsEnabled == 0)
return;
SInfo.cb=sizeof(SInfo);
SInfo.lpReserved=NULL;
SInfo.lpDesktop=NULL;
SInfo.lpTitle=NULL;
SInfo.dwFlags=0;
SInfo.cbReserved2=0;
SInfo.lpReserved2=NULL;
sprintf(cmdLine, "%s %s", Program, Param);
if (!CreateProcess(NULL, cmdLine, NULL, NULL, FALSE,0 ,NULL ,NULL, &SInfo, &PInfo))
Debugprintf("Failed to Start %s Error %d ", Program, GetLastError());
#endif
return;
}
void hookL2SessionAccepted(int Port, char * remotecall, char * ourcall, struct _LINKTABLE * LINK)
{
// Incoming SABM
LINK->ConnectTime = time(NULL);
LINK->bytesTXed = LINK->bytesRXed = 0;
strcpy(LINK->callingCall, remotecall);
strcpy(LINK->receivingCall, ourcall);
strcpy(LINK->Direction, "In");
}
void hookL2SessionDeleted(struct _LINKTABLE * LINK)
{
// calculate session time and av bytes/min in and out
if (LINK->ConnectTime)
{
if (LINK->bytesTXed == 0 && LINK->bytesRXed == 0)
{
// assume failed connect and ignore for now - maybe log later
}
else
{
char Msg[256];
char timestamp[16];
time_t sessionTime = time(NULL) - LINK->ConnectTime;
double avBytesSent = LINK->bytesTXed / (sessionTime / 60.0);
double avBytesRXed = LINK->bytesRXed / (sessionTime / 60.0);
time_t Now = time(NULL);
struct tm * TM = localtime(&Now);
sprintf(timestamp, "%02d:%02d:%02d", TM->tm_hour, TM->tm_min, TM->tm_sec);
if (sessionTime == 0)
sessionTime = 1; // Or will get divide by zero error
Debugprintf("KISS Session Stats Port %d %s %s %d secs Bytes Sent %d BPM %4.2f Bytes Received %d %4.2f BPM ",
LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall, sessionTime, LINK->bytesTXed, avBytesSent, LINK->bytesRXed, avBytesRXed, timestamp);
sprintf(Msg, "{\"mode\": \"%s\", \"direction\": \"%s\", \"port\": %d, \"callfrom\": \"%s\", \"callto\": \"%s\", \"time\": %d, \"bytesSent\": %d,"
"\"BPMSent\": %4.2f, \"BytesReceived\": %d, \"BPMReceived\": %4.2f, \"timestamp\": \"%s\"}",
"KISS", LINK->Direction, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall, sessionTime,
LINK->bytesTXed, avBytesSent, LINK->bytesRXed, avBytesRXed, timestamp);
if (MQTT)
MQTTReportSession(Msg);
}
LINK->ConnectTime = 0;
}
}
void hookL2SessionAttempt(int Port, char * ourcall, char * remotecall, struct _LINKTABLE * LINK)
{
LINK->ConnectTime = time(NULL);
LINK->bytesTXed = LINK->bytesRXed = 0;
strcpy(LINK->callingCall, ourcall);
strcpy(LINK->receivingCall, remotecall);
strcpy(LINK->Direction, "Out");
}
void hookL4SessionAttempt(struct STREAMINFO * STREAM, char * remotecall, char * ourcall)
{
// Outgoing Connect
STREAM->ConnectTime = time(NULL);
STREAM->bytesTXed = STREAM->bytesRXed = 0;
strcpy(STREAM->callingCall, ourcall);
strcpy(STREAM->receivingCall, remotecall);
strcpy(STREAM->Direction, "Out");
}
void hookL4SessionAccepted(struct STREAMINFO * STREAM, char * remotecall, char * ourcall)
{
// Incoming Connect
STREAM->ConnectTime = time(NULL);
STREAM->bytesTXed = STREAM->bytesRXed = 0;
strcpy(STREAM->callingCall, remotecall);
strcpy(STREAM->receivingCall, ourcall);
strcpy(STREAM->Direction, "In");
}
void hookL4SessionDeleted(struct TNCINFO * TNC, struct STREAMINFO * STREAM)
{
char Msg[256];
char timestamp[16];
if (STREAM->ConnectTime)
{
time_t sessionTime = time(NULL) - STREAM->ConnectTime;
double avBytesRXed = STREAM->bytesRXed / (sessionTime / 60.0);
double avBytesSent = STREAM->bytesTXed / (sessionTime / 60.0);
time_t Now = time(NULL);
struct tm * TM = localtime(&Now);
sprintf(timestamp, "%02d:%02d:%02d", TM->tm_hour, TM->tm_min, TM->tm_sec);
if (sessionTime == 0)
sessionTime = 1; // Or will get divide by zero error
sprintf(Msg, "{\"mode\": \"%s\", \"direction\": \"%s\", \"port\": %d, \"callfrom\": \"%s\", \"callto\": \"%s\", \"time\": %d, \"bytesSent\": %d,"
"\"BPMSent\": %4.2f, \"BytesReceived\": %d, \"BPMReceived\": %4.2f, \"timestamp\": \"%s\"}",
Modenames[TNC->Hardware - 1], STREAM->Direction, TNC->Port, STREAM->callingCall, STREAM->receivingCall, sessionTime,
STREAM->bytesTXed, avBytesSent, STREAM->bytesRXed, avBytesRXed, timestamp);
if (MQTT)
MQTTReportSession(Msg);
STREAM->ConnectTime = 0;
}
}

2012
FBBRoutines.c Normal file

File diff suppressed because it is too large Load Diff

3966
FLDigi.c Normal file

File diff suppressed because it is too large Load Diff

3860
FLDigi64.c Normal file

File diff suppressed because it is too large Load Diff

60
FormatHTML.cpp Normal file
View File

@ -0,0 +1,60 @@
// FormatHTML.cpp : Defines the entry point for the console application.
//
#include <stdio.h>
int main () {
FILE *fp, *fp2;
char str[256];
char newstr[256];
char * ptr, * inptr;
/* opening file for reading */
fp = fopen("D:/AtomProject/test.html" , "r");
fp2 = fopen("D:/AtomProject/test.html.c" , "w");
if(fp == NULL) {
perror("Error opening file");
return(-1);
}
while(fgets (str, 256, fp) != NULL)
{
// Replace any " with \" and add " on front and \r\n" on end
char c;
ptr = newstr;
inptr = str;
c = *(inptr++);
*(ptr++) = '"';
while (c && c != 10)
{
if (c == '"')
*(ptr++) = '\\';
*(ptr++) = c;
c = *(inptr++);
}
*(ptr++) = '\\';
*(ptr++) = 'r';
*(ptr++) = '\\';
*(ptr++) = 'n';
*(ptr++) = '"';
*(ptr++) = 10;
*(ptr++) = 0;
puts(newstr);
fputs(newstr, fp2);
}
fclose(fp);
fclose(fp2);
return(0);
}

4369
FreeDATA.c Normal file

File diff suppressed because it is too large Load Diff

29
GetVersion.h Normal file
View File

@ -0,0 +1,29 @@
char VersionString[50]="";
char VersionStringWithBuild[50]="";
int Ver[4] = {Vers};
char TextVerstring[50] = "";
void GetVersionInfo(char * File)
{
#ifndef LINBPQ
char isDebug[40]="";
#ifdef SPECIALVERSION
strcat(isDebug, " ");
strcat(isDebug, SPECIALVERSION);
#endif
#ifdef _DEBUG
strcat(isDebug, " Debug Build");
#endif
sprintf(VersionString,"%d.%d.%d.%d%s", Ver[0], Ver[1], Ver[2], Ver[3], isDebug);
sprintf(TextVerstring,"V%d.%d.%d.%d", Ver[0], Ver[1], Ver[2], Ver[3]);
sprintf(VersionStringWithBuild,"%d.%d.%d Build %d %s", Ver[0], Ver[1], Ver[2], Ver[3], isDebug);
return;
#endif
}

1905
HALDriver.c Normal file

File diff suppressed because it is too large Load Diff

1907
HALDriver64.c Normal file

File diff suppressed because it is too large Load Diff

2200
HFCommon.c Normal file

File diff suppressed because it is too large Load Diff

1845
HSMODEM.c Normal file

File diff suppressed because it is too large Load Diff

124
HTMLCommonCode.c Normal file
View File

@ -0,0 +1,124 @@
/*
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
*/
// General C Routines common to bpq32 and linbpq.mainly moved from BPQ32.c
#pragma data_seg("_BPQDATA")
#define _CRT_SECURE_NO_DEPRECATE
#pragma data_seg("_BPQDATA")
#include "CHeaders.h"
#include "templatedefs.c" // Inline definitions from HTLMPages
char * GetTemplateFromFile(int Version, char * FN)
{
int FileSize;
char * MsgBytes;
char MsgFile[265];
FILE * hFile;
size_t ReadLen;
BOOL Special = FALSE;
struct stat STAT;
if (strcmp(FN, "WebMailMsg.txt") == 0)
return WebMailMsgtxt();
if (strcmp(FN, "FwdPage.txt") == 0)
return FwdPagetxt();
if (strcmp(FN, "FwdDetail.txt") == 0)
return FwdDetailtxt();
if (strcmp(FN, "webscript.js") == 0)
return webscriptjs();
if (strcmp(FN, "WebMailPage.txt") == 0)
return WebMailPagetxt();
if (strcmp(FN, "MainConfig.txt") == 0)
return MainConfigtxt();
if (strcmp(FN, "MsgPage.txt") == 0)
return MsgPagetxt();
if (strcmp(FN, "UserDetail.txt") == 0)
return UserDetailtxt();
if (strcmp(FN, "UserPage.txt") == 0)
return UserPagetxt();
if (strcmp(FN, "Housekeeping.txt") == 0)
return Housekeepingtxt();
if (strcmp(FN, "WP.txt") == 0)
return WPtxt();
if (strcmp(FN, "ChatConfig.txt") == 0)
return ChatConfigtxt();
if (strcmp(FN, "ChatStatus.txt") == 0)
return ChatStatustxt();
sprintf(MsgFile, "%s/HTML/%s", BPQDirectory, FN);
if (stat(MsgFile, &STAT) == -1)
{
MsgBytes = _strdup("File is missing");
return MsgBytes;
}
hFile = fopen(MsgFile, "rb");
if (hFile == 0)
{
MsgBytes = _strdup("File is missing");
return MsgBytes;
}
FileSize = STAT.st_size;
MsgBytes = malloc(FileSize + 1);
ReadLen = fread(MsgBytes, 1, FileSize, hFile);
MsgBytes[FileSize] = 0;
fclose(hFile);
// Check Version
if (Version)
{
int PageVersion = 0;
if (memcmp(MsgBytes, "<!-- Version", 12) == 0)
PageVersion = atoi(&MsgBytes[13]);
if (Version != PageVersion)
{
free(MsgBytes);
MsgBytes = malloc(256);
sprintf(MsgBytes, "Wrong Version of HTML Page %s - is %d should be %d. Please update", FN, PageVersion, Version);
}
}
return MsgBytes;
}

5140
HTTPcode.c Normal file

File diff suppressed because it is too large Load Diff

4551
HanksRT.c Normal file

File diff suppressed because it is too large Load Diff

1184
Housekeeping.c Normal file

File diff suppressed because it is too large Load Diff

5459
IPCode.c Normal file

File diff suppressed because it is too large Load Diff

2086
KAMPactor.c Normal file

File diff suppressed because it is too large Load Diff

1609
KISSHF.c Normal file

File diff suppressed because it is too large Load Diff

340
KernelScript1.rc Normal file
View File

@ -0,0 +1,340 @@
//Microsoft Developer Studio generated resource script.
//
#include "kernelresource.h"
#define CKernel
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
#include "BpqTermMDI.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.K.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
BPQMAINWINDOW DIALOG DISCARDABLE 17, 25, 382, 300
STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU |
WS_THICKFRAME
CAPTION "BPQ32 Console"
CLASS "BPQMAINWINDOW"
FONT 8, "Fixedsys"
BEGIN
LTEXT "",IDC_BACKGROUND,22,20,337,273
CONTROL "",IDC_ENIGATE,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT |
WS_TABSTOP,57,0,8,12
LTEXT "IGate State - Disconnected",IGATESTATE,69,0,110,12,
SS_CENTERIMAGE
LTEXT "IGATE Stats - Msgs 0 Local Stns 0",IGATESTATS,180,0,
152,12,SS_CENTERIMAGE
LISTBOX BPQCONSOLE,1,17,359,262,LBS_NOINTEGRALHEIGHT |
LBS_DISABLENOSCROLL | LBS_NOSEL | WS_VSCROLL |
WS_HSCROLL
LTEXT "GPS Off",IDC_GPS,332,0,40,12,SS_CENTERIMAGE
LTEXT "Enable IGate",IDC_STATIC,5,2,49,10
END
CONFIG DIALOGEX 249, 200, 160, 118
STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION
EXSTYLE WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE
CAPTION "Configuration"
CLASS "CONFIG"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
EDITTEXT 1001,50,5,43,14,ES_AUTOHSCROLL | NOT WS_BORDER,
WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
EDITTEXT 1002,50,25,100,14,ES_AUTOHSCROLL | NOT WS_BORDER,
WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
EDITTEXT 1003,50,65,43,14,ES_AUTOHSCROLL | NOT WS_BORDER,
WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
LTEXT "Call",1,10,5,21,18,0,WS_EX_NOPARENTNOTIFY
LTEXT "Host",2,10,25,30,20,0,WS_EX_NOPARENTNOTIFY
LTEXT "UDP Port",3,10,65,32,15,0,WS_EX_NOPARENTNOTIFY
PUSHBUTTON "Cancel",ID_CANCEL,15,95,35,14,0,WS_EX_NOPARENTNOTIFY
PUSHBUTTON "Apply",ID_SAVE,55,95,35,14,0,WS_EX_NOPARENTNOTIFY
CONTROL "UDP Flag ",1004,"Button",BS_AUTOCHECKBOX | BS_LEFT |
WS_TABSTOP,8,45,50,14,WS_EX_RIGHT
CONTROL "Broadcast Flag ",1005,"Button",BS_AUTOCHECKBOX |
BS_LEFT | WS_TABSTOP,68,45,70,14,WS_EX_RIGHT
END
IDD_WL2KSYSOP DIALOGEX 0, 0, 277, 355
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "WL2K Sysop Record Update"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Name",3,5,31,28,10,0,WS_EX_NOPARENTNOTIFY
EDITTEXT NAME,60,30,64,12,ES_AUTOHSCROLL | NOT WS_BORDER,
WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
LTEXT "Address Line 1",6,5,72,50,9,0,WS_EX_NOPARENTNOTIFY
EDITTEXT ADDR1,60,71,133,14,ES_AUTOHSCROLL | NOT WS_BORDER,
WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
LTEXT "Address Line 2",7,5,92,50,9,0,WS_EX_NOPARENTNOTIFY
EDITTEXT ADDR2,60,91,133,14,ES_AUTOHSCROLL | NOT WS_BORDER,
WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
LTEXT "City",4,5,112,40,9,0,WS_EX_NOPARENTNOTIFY
EDITTEXT CITY,60,111,133,14,ES_AUTOHSCROLL | NOT WS_BORDER,
WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
LTEXT "State",8,5,132,40,9,0,WS_EX_NOPARENTNOTIFY
EDITTEXT STATE,60,131,133,14,ES_AUTOHSCROLL | NOT WS_BORDER,
WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
LTEXT "Country",9,5,152,40,9,0,WS_EX_NOPARENTNOTIFY
EDITTEXT COUNTRY,60,151,133,14,ES_AUTOHSCROLL | NOT WS_BORDER,
WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
PUSHBUTTON "Cancel",ID_CANCEL,115,311,47,17,0,WS_EX_NOPARENTNOTIFY
PUSHBUTTON "Apply",ID_SAVE,55,311,47,17,0,WS_EX_NOPARENTNOTIFY
LTEXT "PostCode",10,5,172,40,9,0,WS_EX_NOPARENTNOTIFY
EDITTEXT POSTCODE,60,171,133,14,ES_AUTOHSCROLL | NOT WS_BORDER,
WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
LTEXT "Email",11,5,192,40,9,0,WS_EX_NOPARENTNOTIFY
EDITTEXT EMAIL,60,191,133,14,ES_AUTOHSCROLL | NOT WS_BORDER,
WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
LTEXT "Website",12,5,212,40,9,0,WS_EX_NOPARENTNOTIFY
EDITTEXT WEBSITE,60,209,133,14,ES_AUTOHSCROLL | NOT WS_BORDER,
WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
LTEXT "Phone",13,6,232,40,9,0,WS_EX_NOPARENTNOTIFY
EDITTEXT PHONE,60,231,133,14,ES_AUTOHSCROLL | NOT WS_BORDER,
WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
LTEXT "Addiitional Data",14,5,252,50,9,0,WS_EX_NOPARENTNOTIFY
EDITTEXT ADDITIONALDATA,60,251,205,14,ES_AUTOHSCROLL | NOT
WS_BORDER,WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
LTEXT "Password",15,5,13,50,9,0,WS_EX_NOPARENTNOTIFY
EDITTEXT IDC_Password,60,12,133,14,ES_AUTOHSCROLL | NOT WS_BORDER,
WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
LTEXT "Locator",16,5,49,50,9,0,WS_EX_NOPARENTNOTIFY
EDITTEXT IDC_Locator,60,48,133,14,ES_AUTOHSCROLL | NOT WS_BORDER,
WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
END
UIMAINWINDOW DIALOG DISCARDABLE 100, 100, 323, 304
STYLE WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "BPQ32 UI Utility"
CLASS "UIMAINWINDOW"
FONT 8, "FixedSys"
BEGIN
END
PORTPAGE DIALOG DISCARDABLE 26, 5, 366, 186
STYLE WS_CHILD | WS_VISIBLE
FONT 8, "FixedSys"
BEGIN
LTEXT "Send Beacon Every",IDC_STATIC,17,25,68,14,
SS_CENTERIMAGE
EDITTEXT IDC_INTERVAL,90,26,20,12,ES_AUTOHSCROLL
LTEXT "Minutes to ",IDC_STATIC,117,25,55,14,SS_CENTERIMAGE
EDITTEXT IDC_UIDEST,175,26,59,12,ES_UPPERCASE | ES_AUTOHSCROLL
CONTROL "Send From File",IDC_FROMFILE,"Button",BS_AUTOCHECKBOX |
BS_VCENTER | WS_TABSTOP,17,59,68,13
EDITTEXT IDC_FILENAME,89,58,223,12,ES_AUTOHSCROLL
PUSHBUTTON "Find File",IDC_FILE,316,58,40,12
DEFPUSHBUTTON "Save",IDOK,122,142,40,12
DEFPUSHBUTTON "Test",ID_TEST,205,142,40,12
EDITTEXT IDC_MESSAGE,20,84,294,52,ES_MULTILINE | ES_AUTOVSCROLL |
ES_AUTOHSCROLL | ES_WANTRETURN
LTEXT "",IDC_PORTNAME,12,9,139,14,SS_CENTERIMAGE
LTEXT "Path",IDC_STATIC,17,42,57,14,SS_CENTERIMAGE
EDITTEXT IDC_UIDIGIS,90,42,223,12,ES_UPPERCASE | ES_AUTOHSCROLL
END
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MAINFRAME_MENU MENU DISCARDABLE
BEGIN
POPUP "Window"
BEGIN
MENUITEM "New Terminal Window", ID_NEWWINDOW
MENUITEM "Cascade", ID_WINDOWS_CASCADE
MENUITEM "Tile", ID_WINDOWS_TILE
MENUITEM "Beacon Config", BPQUICONFIG
MENUITEM "Close all BPQ32 Programs", BPQCLOSEALL
END
END
CONS_MENU MENU DISCARDABLE
BEGIN
POPUP "Window"
BEGIN
MENUITEM "New Terminal Window", ID_NEWWINDOW
MENUITEM "Cascade", ID_WINDOWS_CASCADE
MENUITEM "Tile", ID_WINDOWS_TILE
MENUITEM "Beacon Config", BPQUICONFIG
MENUITEM "Close all BPQ32 Programs", BPQCLOSEALL
END
POPUP "Actions"
BEGIN
MENUITEM "Save Nodes to file BPQNODES.DAT", BPQSAVENODES
MENUITEM "Save Registry Configuration", BPQSAVEREG
MENUITEM "Diagnostic Dump to file BPQDUMP", BPQDUMP
MENUITEM "Re-read Rigcontrol Config", SCANRECONFIG
MENUITEM "Re-read APRS Config", APRSRECONFIG
MENUITEM "Start Minimized", BPQSTARTMIN
MENUITEM "Minimize to Notification Area (System Tray)", BPQMINTOTRAY
MENUITEM "Update WL2K Sysop Record", IDD_WL2KSYSOP
END
END
TERM_MENU MENU DISCARDABLE
BEGIN
POPUP "Window"
BEGIN
MENUITEM "New Terminal Window", ID_NEWWINDOW
MENUITEM "Cascade", ID_WINDOWS_CASCADE
MENUITEM "Tile", ID_WINDOWS_TILE
MENUITEM "Beacon Config", BPQUICONFIG
MENUITEM "Close all BPQ32 Programs", BPQCLOSEALL
END
POPUP "Action"
BEGIN
MENUITEM "Connect", BPQCONNECT
MENUITEM "Disconnect", BPQDISCONNECT, GRAYED
END
POPUP "Config"
BEGIN
MENUITEM "Font", ID_SETUP_FONT
MENUITEM "Enable Bells", BPQBELLS
MENUITEM "Strip Linefeeds", BPQStripLF
MENUITEM "Log Output", BPQLogOutput
MENUITEM "Send Disconnected", BPQSendDisconnected
MENUITEM "Chat Terminal Mode (Send Keppalives)", CHATTERM
MENUITEM "Restore Windows on load", ID_WINDOWS_RESTORE
MENUITEM "Beep if input too long", ID_WARNWRAP
MENUITEM "Wrap Input", ID_WRAP
MENUITEM "Flash instead of Beep on Bell", ID_FLASHONBELL
END
POPUP "Edit"
BEGIN
MENUITEM "Copy Output Window", BPQCOPYOUT
MENUITEM "Clear Output Window", BPQCLEAROUT
END
MENUITEM "Help", BPQHELP
END
MON_MENU MENU DISCARDABLE
BEGIN
POPUP "Window"
BEGIN
MENUITEM "New Window", ID_NEWWINDOW
MENUITEM "Cascade", ID_WINDOWS_CASCADE
MENUITEM "Tile", ID_WINDOWS_TILE
MENUITEM "Beacon Config", BPQUICONFIG
MENUITEM "Close all BPQ32 Programs", BPQCLOSEALL
END
POPUP "Monitor"
BEGIN
MENUITEM "Use Local Time", MONLOCALTIME
MENUITEM "Monitor TX", BPQMTX
MENUITEM "Monitor Supervisory", BPQMCOM
MENUITEM "Monitor UI Only", MON_UI_ONLY
MENUITEM "Monitor NODES", BPQMNODES
MENUITEM "Enable Colour", MONCOLOUR
MENUITEM "Log Monitor", BPQLogMonitor
MENUITEM "Trace APRS-IS", MONITORAPRS
MENUITEM "Clear all port flags", StopALLMon
END
POPUP "Edit"
BEGIN
MENUITEM "Copy Monitor Window", BPQCOPYMON
MENUITEM "Clear Monitor Window", BPQCLEARMON
END
MENUITEM "Help", BPQHELP
END
/////////////////////////////////////////////////////////////////////////////
//
// WAVE
//
INCOMINGCALL WAVE MOVEABLE PURE "Ring.wav"
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"kernelresource.h\0"
"""\r\n"
"BpqTermMDI.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"#include ""BpqTermMDI.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""..\\CommonSource\\Versions.h""\r\n"
"#include ""..\\CommonSource\\StdVer.inc""\r\n"
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
"BPQMAINWINDOW", DIALOG
BEGIN
RIGHTMARGIN, 360
END
IDD_WL2KSYSOP, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 270
TOPMARGIN, 7
BOTTOMMARGIN, 348
END
END
#endif // APSTUDIO_INVOKED
#endif // English (U.K.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "..\CommonSource\Versions.h"
#include "..\StdVer.inc"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

4145
L2Code.c Normal file

File diff suppressed because it is too large Load Diff

1514
L3Code.c Normal file

File diff suppressed because it is too large Load Diff

2419
L4Code.c Normal file

File diff suppressed because it is too large Load Diff

2099
LinBPQ.c Normal file

File diff suppressed because it is too large Load Diff

751
LzFind.c Normal file
View File

@ -0,0 +1,751 @@
/* LzFind.c -- Match finder for LZ algorithms
2008-10-04 : Igor Pavlov : Public domain */
#include <string.h>
#include "LzFind.h"
#include "LzHash.h"
#define kEmptyHashValue 0
#define kMaxValForNormalize ((LZ_UInt32)0xFFFFFFFF)
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
#define kNormalizeMask (~(kNormalizeStepMin - 1))
#define kMaxHistorySize ((LZ_UInt32)3 << 30)
#define kStartMaxLen 3
static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
{
if (!p->directInput)
{
alloc->Free(alloc, p->bufferBase);
p->bufferBase = 0;
}
}
/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
static int LzInWindow_Create(CMatchFinder *p, LZ_UInt32 keepSizeReserv, ISzAlloc *alloc)
{
LZ_UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
if (p->directInput)
{
p->blockSize = blockSize;
return 1;
}
if (p->bufferBase == 0 || p->blockSize != blockSize)
{
LzInWindow_Free(p, alloc);
p->blockSize = blockSize;
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
}
return (p->bufferBase != 0);
}
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
Byte MatchFinder_GetIndexByte(CMatchFinder *p, LZ_Int32 index) { return p->buffer[index]; }
LZ_UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
void MatchFinder_ReduceOffsets(CMatchFinder *p, LZ_UInt32 subValue)
{
p->posLimit -= subValue;
p->pos -= subValue;
p->streamPos -= subValue;
}
static void MatchFinder_ReadBlock(CMatchFinder *p)
{
if (p->streamEndWasReached || p->result != SZ_OK)
return;
for (;;)
{
Byte *dest = p->buffer + (p->streamPos - p->pos);
size_t size = (p->bufferBase + p->blockSize - dest);
if (size == 0)
return;
p->result = p->stream->Read(p->stream, dest, &size);
if (p->result != SZ_OK)
return;
if (size == 0)
{
p->streamEndWasReached = 1;
return;
}
p->streamPos += (LZ_UInt32)size;
if (p->streamPos - p->pos > p->keepSizeAfter)
return;
}
}
void MatchFinder_MoveBlock(CMatchFinder *p)
{
memmove(p->bufferBase,
p->buffer - p->keepSizeBefore,
(size_t)(p->streamPos - p->pos + p->keepSizeBefore));
p->buffer = p->bufferBase + p->keepSizeBefore;
}
int MatchFinder_NeedMove(CMatchFinder *p)
{
/* if (p->streamEndWasReached) return 0; */
return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
}
void MatchFinder_ReadIfRequired(CMatchFinder *p)
{
if (p->streamEndWasReached)
return;
if (p->keepSizeAfter >= p->streamPos - p->pos)
MatchFinder_ReadBlock(p);
}
static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
{
if (MatchFinder_NeedMove(p))
MatchFinder_MoveBlock(p);
MatchFinder_ReadBlock(p);
}
static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
{
p->cutValue = 32;
p->btMode = 1;
p->numHashBytes = 4;
/* p->skipModeBits = 0; */
p->directInput = 0;
p->bigHash = 0;
}
#define kCrcPoly 0xEDB88320
void MatchFinder_Construct(CMatchFinder *p)
{
LZ_UInt32 i;
p->bufferBase = 0;
p->directInput = 0;
p->hash = 0;
MatchFinder_SetDefaultSettings(p);
for (i = 0; i < 256; i++)
{
LZ_UInt32 r = i;
int j;
for (j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
p->crc[i] = r;
}
}
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->hash);
p->hash = 0;
}
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
{
MatchFinder_FreeThisClassMemory(p, alloc);
LzInWindow_Free(p, alloc);
}
static CLzRef* AllocRefs(LZ_UInt32 num, ISzAlloc *alloc)
{
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
if (sizeInBytes / sizeof(CLzRef) != num)
return 0;
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
}
int MatchFinder_Create(CMatchFinder *p, LZ_UInt32 historySize,
LZ_UInt32 keepAddBufferBefore, LZ_UInt32 matchMaxLen, LZ_UInt32 keepAddBufferAfter,
ISzAlloc *alloc)
{
LZ_UInt32 sizeReserv;
if (historySize > kMaxHistorySize)
{
MatchFinder_Free(p, alloc);
return 0;
}
sizeReserv = historySize >> 1;
if (historySize > ((LZ_UInt32)2 << 30))
sizeReserv = historySize >> 2;
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
if (LzInWindow_Create(p, sizeReserv, alloc))
{
LZ_UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1;
LZ_UInt32 hs;
p->matchMaxLen = matchMaxLen;
{
p->fixedHashSize = 0;
if (p->numHashBytes == 2)
hs = (1 << 16) - 1;
else
{
hs = historySize - 1;
hs |= (hs >> 1);
hs |= (hs >> 2);
hs |= (hs >> 4);
hs |= (hs >> 8);
hs >>= 1;
/* hs >>= p->skipModeBits; */
hs |= 0xFFFF; /* don't change it! It's required for Deflate */
if (hs > (1 << 24))
{
if (p->numHashBytes == 3)
hs = (1 << 24) - 1;
else
hs >>= 1;
}
}
p->hashMask = hs;
hs++;
if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
hs += p->fixedHashSize;
}
{
LZ_UInt32 prevSize = p->hashSizeSum + p->numSons;
LZ_UInt32 newSize;
p->historySize = historySize;
p->hashSizeSum = hs;
p->cyclicBufferSize = newCyclicBufferSize;
p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
newSize = p->hashSizeSum + p->numSons;
if (p->hash != 0 && prevSize == newSize)
return 1;
MatchFinder_FreeThisClassMemory(p, alloc);
p->hash = AllocRefs(newSize, alloc);
if (p->hash != 0)
{
p->son = p->hash + p->hashSizeSum;
return 1;
}
}
}
MatchFinder_Free(p, alloc);
return 0;
}
static void MatchFinder_SetLimits(CMatchFinder *p)
{
LZ_UInt32 limit = kMaxValForNormalize - p->pos;
LZ_UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
if (limit2 < limit)
limit = limit2;
limit2 = p->streamPos - p->pos;
if (limit2 <= p->keepSizeAfter)
{
if (limit2 > 0)
limit2 = 1;
}
else
limit2 -= p->keepSizeAfter;
if (limit2 < limit)
limit = limit2;
{
LZ_UInt32 lenLimit = p->streamPos - p->pos;
if (lenLimit > p->matchMaxLen)
lenLimit = p->matchMaxLen;
p->lenLimit = lenLimit;
}
p->posLimit = p->pos + limit;
}
void MatchFinder_Init(CMatchFinder *p)
{
LZ_UInt32 i;
for (i = 0; i < p->hashSizeSum; i++)
p->hash[i] = kEmptyHashValue;
p->cyclicBufferPos = 0;
p->buffer = p->bufferBase;
p->pos = p->streamPos = p->cyclicBufferSize;
p->result = SZ_OK;
p->streamEndWasReached = 0;
MatchFinder_ReadBlock(p);
MatchFinder_SetLimits(p);
}
static LZ_UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
{
return (p->pos - p->historySize - 1) & kNormalizeMask;
}
void MatchFinder_Normalize3(LZ_UInt32 subValue, CLzRef *items, LZ_UInt32 numItems)
{
LZ_UInt32 i;
for (i = 0; i < numItems; i++)
{
LZ_UInt32 value = items[i];
if (value <= subValue)
value = kEmptyHashValue;
else
value -= subValue;
items[i] = value;
}
}
static void MatchFinder_Normalize(CMatchFinder *p)
{
LZ_UInt32 subValue = MatchFinder_GetSubValue(p);
MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
MatchFinder_ReduceOffsets(p, subValue);
}
static void MatchFinder_CheckLimits(CMatchFinder *p)
{
if (p->pos == kMaxValForNormalize)
MatchFinder_Normalize(p);
if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
MatchFinder_CheckAndMoveAndRead(p);
if (p->cyclicBufferPos == p->cyclicBufferSize)
p->cyclicBufferPos = 0;
MatchFinder_SetLimits(p);
}
static LZ_UInt32 * Hc_GetMatchesSpec(LZ_UInt32 lenLimit, LZ_UInt32 curMatch, LZ_UInt32 pos, const Byte *cur, CLzRef *son,
LZ_UInt32 _cyclicBufferPos, LZ_UInt32 _cyclicBufferSize, LZ_UInt32 cutValue,
LZ_UInt32 *distances, LZ_UInt32 maxLen)
{
son[_cyclicBufferPos] = curMatch;
for (;;)
{
LZ_UInt32 delta = pos - curMatch;
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
return distances;
{
const Byte *pb = cur - delta;
curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
if (pb[maxLen] == cur[maxLen] && *pb == *cur)
{
LZ_UInt32 len = 0;
while (++len != lenLimit)
if (pb[len] != cur[len])
break;
if (maxLen < len)
{
*distances++ = maxLen = len;
*distances++ = delta - 1;
if (len == lenLimit)
return distances;
}
}
}
}
}
LZ_UInt32 * GetMatchesSpec1(LZ_UInt32 lenLimit, LZ_UInt32 curMatch, LZ_UInt32 pos, const Byte *cur, CLzRef *son,
LZ_UInt32 _cyclicBufferPos, LZ_UInt32 _cyclicBufferSize, LZ_UInt32 cutValue,
LZ_UInt32 *distances, LZ_UInt32 maxLen)
{
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
LZ_UInt32 len0 = 0, len1 = 0;
for (;;)
{
LZ_UInt32 delta = pos - curMatch;
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
{
*ptr0 = *ptr1 = kEmptyHashValue;
return distances;
}
{
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
const Byte *pb = cur - delta;
LZ_UInt32 len = (len0 < len1 ? len0 : len1);
if (pb[len] == cur[len])
{
if (++len != lenLimit && pb[len] == cur[len])
while (++len != lenLimit)
if (pb[len] != cur[len])
break;
if (maxLen < len)
{
*distances++ = maxLen = len;
*distances++ = delta - 1;
if (len == lenLimit)
{
*ptr1 = pair[0];
*ptr0 = pair[1];
return distances;
}
}
}
if (pb[len] < cur[len])
{
*ptr1 = curMatch;
ptr1 = pair + 1;
curMatch = *ptr1;
len1 = len;
}
else
{
*ptr0 = curMatch;
ptr0 = pair;
curMatch = *ptr0;
len0 = len;
}
}
}
}
static void SkipMatchesSpec(LZ_UInt32 lenLimit, LZ_UInt32 curMatch, LZ_UInt32 pos, const Byte *cur, CLzRef *son,
LZ_UInt32 _cyclicBufferPos, LZ_UInt32 _cyclicBufferSize, LZ_UInt32 cutValue)
{
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
LZ_UInt32 len0 = 0, len1 = 0;
for (;;)
{
LZ_UInt32 delta = pos - curMatch;
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
{
*ptr0 = *ptr1 = kEmptyHashValue;
return;
}
{
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
const Byte *pb = cur - delta;
LZ_UInt32 len = (len0 < len1 ? len0 : len1);
if (pb[len] == cur[len])
{
while (++len != lenLimit)
if (pb[len] != cur[len])
break;
{
if (len == lenLimit)
{
*ptr1 = pair[0];
*ptr0 = pair[1];
return;
}
}
}
if (pb[len] < cur[len])
{
*ptr1 = curMatch;
ptr1 = pair + 1;
curMatch = *ptr1;
len1 = len;
}
else
{
*ptr0 = curMatch;
ptr0 = pair;
curMatch = *ptr0;
len0 = len;
}
}
}
}
#define MOVE_POS \
++p->cyclicBufferPos; \
p->buffer++; \
if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
#define MOVE_POS_RET MOVE_POS return offset;
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
#define GET_MATCHES_HEADER2(minLen, ret_op) \
LZ_UInt32 lenLimit; LZ_UInt32 hashValue; const Byte *cur; LZ_UInt32 curMatch; \
lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
cur = p->buffer;
#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)
#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
#define GET_MATCHES_FOOTER(offset, maxLen) \
offset = (LZ_UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
distances + offset, maxLen) - distances); MOVE_POS_RET;
#define SKIP_FOOTER \
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
static LZ_UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, LZ_UInt32 *distances)
{
LZ_UInt32 offset;
GET_MATCHES_HEADER(2)
HASH2_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
offset = 0;
GET_MATCHES_FOOTER(offset, 1)
}
LZ_UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, LZ_UInt32 *distances)
{
LZ_UInt32 offset;
GET_MATCHES_HEADER(3)
HASH_ZIP_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
offset = 0;
GET_MATCHES_FOOTER(offset, 2)
}
static LZ_UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, LZ_UInt32 *distances)
{
LZ_UInt32 hash2Value, delta2, maxLen, offset;
GET_MATCHES_HEADER(3)
HASH3_CALC;
delta2 = p->pos - p->hash[hash2Value];
curMatch = p->hash[kFix3HashSize + hashValue];
p->hash[hash2Value] =
p->hash[kFix3HashSize + hashValue] = p->pos;
maxLen = 2;
offset = 0;
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
{
for (; maxLen != lenLimit; maxLen++)
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
break;
distances[0] = maxLen;
distances[1] = delta2 - 1;
offset = 2;
if (maxLen == lenLimit)
{
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
MOVE_POS_RET;
}
}
GET_MATCHES_FOOTER(offset, maxLen)
}
static LZ_UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, LZ_UInt32 *distances)
{
LZ_UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
GET_MATCHES_HEADER(4)
HASH4_CALC;
delta2 = p->pos - p->hash[ hash2Value];
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
curMatch = p->hash[kFix4HashSize + hashValue];
p->hash[ hash2Value] =
p->hash[kFix3HashSize + hash3Value] =
p->hash[kFix4HashSize + hashValue] = p->pos;
maxLen = 1;
offset = 0;
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
{
distances[0] = maxLen = 2;
distances[1] = delta2 - 1;
offset = 2;
}
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
{
maxLen = 3;
distances[offset + 1] = delta3 - 1;
offset += 2;
delta2 = delta3;
}
if (offset != 0)
{
for (; maxLen != lenLimit; maxLen++)
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
break;
distances[offset - 2] = maxLen;
if (maxLen == lenLimit)
{
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
MOVE_POS_RET;
}
}
if (maxLen < 3)
maxLen = 3;
GET_MATCHES_FOOTER(offset, maxLen)
}
static LZ_UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, LZ_UInt32 *distances)
{
LZ_UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
GET_MATCHES_HEADER(4)
HASH4_CALC;
delta2 = p->pos - p->hash[ hash2Value];
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
curMatch = p->hash[kFix4HashSize + hashValue];
p->hash[ hash2Value] =
p->hash[kFix3HashSize + hash3Value] =
p->hash[kFix4HashSize + hashValue] = p->pos;
maxLen = 1;
offset = 0;
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
{
distances[0] = maxLen = 2;
distances[1] = delta2 - 1;
offset = 2;
}
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
{
maxLen = 3;
distances[offset + 1] = delta3 - 1;
offset += 2;
delta2 = delta3;
}
if (offset != 0)
{
for (; maxLen != lenLimit; maxLen++)
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
break;
distances[offset - 2] = maxLen;
if (maxLen == lenLimit)
{
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS_RET;
}
}
if (maxLen < 3)
maxLen = 3;
offset = (LZ_UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
distances + offset, maxLen) - (distances));
MOVE_POS_RET
}
LZ_UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, LZ_UInt32 *distances)
{
LZ_UInt32 offset;
GET_MATCHES_HEADER(3)
HASH_ZIP_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
offset = (LZ_UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
distances, 2) - (distances));
MOVE_POS_RET
}
static void Bt2_MatchFinder_Skip(CMatchFinder *p, LZ_UInt32 num)
{
do
{
SKIP_HEADER(2)
HASH2_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
}
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, LZ_UInt32 num)
{
do
{
SKIP_HEADER(3)
HASH_ZIP_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
}
static void Bt3_MatchFinder_Skip(CMatchFinder *p, LZ_UInt32 num)
{
do
{
LZ_UInt32 hash2Value;
SKIP_HEADER(3)
HASH3_CALC;
curMatch = p->hash[kFix3HashSize + hashValue];
p->hash[hash2Value] =
p->hash[kFix3HashSize + hashValue] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
}
static void Bt4_MatchFinder_Skip(CMatchFinder *p, LZ_UInt32 num)
{
do
{
LZ_UInt32 hash2Value, hash3Value;
SKIP_HEADER(4)
HASH4_CALC;
curMatch = p->hash[kFix4HashSize + hashValue];
p->hash[ hash2Value] =
p->hash[kFix3HashSize + hash3Value] = p->pos;
p->hash[kFix4HashSize + hashValue] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
}
static void Hc4_MatchFinder_Skip(CMatchFinder *p, LZ_UInt32 num)
{
do
{
LZ_UInt32 hash2Value, hash3Value;
SKIP_HEADER(4)
HASH4_CALC;
curMatch = p->hash[kFix4HashSize + hashValue];
p->hash[ hash2Value] =
p->hash[kFix3HashSize + hash3Value] =
p->hash[kFix4HashSize + hashValue] = p->pos;
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS
}
while (--num != 0);
}
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, LZ_UInt32 num)
{
do
{
SKIP_HEADER(3)
HASH_ZIP_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS
}
while (--num != 0);
}
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
{
vTable->Init = (Mf_Init_Func)MatchFinder_Init;
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
if (!p->btMode)
{
vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
}
else if (p->numHashBytes == 2)
{
vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
}
else if (p->numHashBytes == 3)
{
vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
}
else
{
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
}
}

107
LzFind.h Normal file
View File

@ -0,0 +1,107 @@
/* LzFind.h -- Match finder for LZ algorithms
2008-10-04 : Igor Pavlov : Public domain */
#ifndef __LZFIND_H
#define __LZFIND_H
#include "types.h"
typedef LZ_UInt32 CLzRef;
typedef struct _CMatchFinder
{
Byte *buffer;
LZ_UInt32 pos;
LZ_UInt32 posLimit;
LZ_UInt32 streamPos;
LZ_UInt32 lenLimit;
LZ_UInt32 cyclicBufferPos;
LZ_UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
LZ_UInt32 matchMaxLen;
CLzRef *hash;
CLzRef *son;
LZ_UInt32 hashMask;
LZ_UInt32 cutValue;
Byte *bufferBase;
ISeqInStream *stream;
int streamEndWasReached;
LZ_UInt32 blockSize;
LZ_UInt32 keepSizeBefore;
LZ_UInt32 keepSizeAfter;
LZ_UInt32 numHashBytes;
int directInput;
int btMode;
/* int skipModeBits; */
int bigHash;
LZ_UInt32 historySize;
LZ_UInt32 fixedHashSize;
LZ_UInt32 hashSizeSum;
LZ_UInt32 numSons;
SRes result;
LZ_UInt32 crc[256];
} CMatchFinder;
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(LZ_Int32)(index)])
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
int MatchFinder_NeedMove(CMatchFinder *p);
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
void MatchFinder_MoveBlock(CMatchFinder *p);
void MatchFinder_ReadIfRequired(CMatchFinder *p);
void MatchFinder_Construct(CMatchFinder *p);
/* Conditions:
historySize <= 3 GB
keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
*/
int MatchFinder_Create(CMatchFinder *p, LZ_UInt32 historySize,
LZ_UInt32 keepAddBufferBefore, LZ_UInt32 matchMaxLen, LZ_UInt32 keepAddBufferAfter,
ISzAlloc *alloc);
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
void MatchFinder_Normalize3(LZ_UInt32 subValue, CLzRef *items, LZ_UInt32 numItems);
void MatchFinder_ReduceOffsets(CMatchFinder *p, LZ_UInt32 subValue);
LZ_UInt32 * GetMatchesSpec1(LZ_UInt32 lenLimit, LZ_UInt32 curMatch, LZ_UInt32 pos, const Byte *buffer, CLzRef *son,
LZ_UInt32 _cyclicBufferPos, LZ_UInt32 _cyclicBufferSize, LZ_UInt32 _cutValue,
LZ_UInt32 *distances, LZ_UInt32 maxLen);
/*
Conditions:
Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
*/
typedef void (*Mf_Init_Func)(void *object);
typedef Byte (*Mf_GetIndexByte_Func)(void *object, LZ_Int32 index);
typedef LZ_UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
typedef LZ_UInt32 (*Mf_GetMatches_Func)(void *object, LZ_UInt32 *distances);
typedef void (*Mf_Skip_Func)(void *object, LZ_UInt32);
typedef struct _IMatchFinder
{
Mf_Init_Func Init;
Mf_GetIndexByte_Func GetIndexByte;
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
Mf_GetMatches_Func GetMatches;
Mf_Skip_Func Skip;
} IMatchFinder;
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
void MatchFinder_Init(CMatchFinder *p);
LZ_UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, LZ_UInt32 *distances);
LZ_UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, LZ_UInt32 *distances);
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, LZ_UInt32 num);
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, LZ_UInt32 num);
#endif

54
LzHash.h Normal file
View File

@ -0,0 +1,54 @@
/* LzHash.h -- HASH functions for LZ algorithms
2008-10-04 : Igor Pavlov : Public domain */
#ifndef __LZHASH_H
#define __LZHASH_H
#define kHash2Size (1 << 10)
#define kHash3Size (1 << 16)
#define kHash4Size (1 << 20)
#define kFix3HashSize (kHash2Size)
#define kFix4HashSize (kHash2Size + kHash3Size)
#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
#define HASH2_CALC hashValue = cur[0] | ((LZ_UInt32)cur[1] << 8);
#define HASH3_CALC { \
LZ_UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hashValue = (temp ^ ((LZ_UInt32)cur[2] << 8)) & p->hashMask; }
#define HASH4_CALC { \
LZ_UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((LZ_UInt32)cur[2] << 8)) & (kHash3Size - 1); \
hashValue = (temp ^ ((LZ_UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
#define HASH5_CALC { \
LZ_UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((LZ_UInt32)cur[2] << 8)) & (kHash3Size - 1); \
hash4Value = (temp ^ ((LZ_UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
hash4Value &= (kHash4Size - 1); }
/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((LZ_UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
#define HASH_ZIP_CALC hashValue = ((cur[2] | ((LZ_UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
#define MT_HASH2_CALC \
hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
#define MT_HASH3_CALC { \
LZ_UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((LZ_UInt32)cur[2] << 8)) & (kHash3Size - 1); }
#define MT_HASH4_CALC { \
LZ_UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((LZ_UInt32)cur[2] << 8)) & (kHash3Size - 1); \
hash4Value = (temp ^ ((LZ_UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
#endif

1025
LzmaDec.c Normal file

File diff suppressed because it is too large Load Diff

223
LzmaDec.h Normal file
View File

@ -0,0 +1,223 @@
/* LzmaDec.h -- LZMA Decoder
2008-10-04 : Igor Pavlov : Public domain */
#ifndef __LZMADEC_H
#define __LZMADEC_H
#include "types.h"
/* #define _LZMA_PROB32 */
/* _LZMA_PROB32 can increase the speed on some CPUs,
but memory usage for CLzmaDec::probs will be doubled in that case */
#ifdef _LZMA_PROB32
#define CLzmaProb LZ_UInt32
#else
#define CLzmaProb UInt16
#endif
/* ---------- LZMA Properties ---------- */
#define LZMA_PROPS_SIZE 5
typedef struct _CLzmaProps
{
unsigned lc, lp, pb;
LZ_UInt32 dicSize;
} CLzmaProps;
/* LzmaProps_Decode - decodes properties
Returns:
SZ_OK
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
/* ---------- LZMA Decoder state ---------- */
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
#define LZMA_REQUIRED_INPUT_MAX 20
typedef struct
{
CLzmaProps prop;
CLzmaProb *probs;
Byte *dic;
const Byte *buf;
LZ_UInt32 range, code;
SizeT dicPos;
SizeT dicBufSize;
LZ_UInt32 processedPos;
LZ_UInt32 checkDicSize;
unsigned state;
LZ_UInt32 reps[4];
unsigned remainLen;
int needFlush;
int needInitState;
LZ_UInt32 numProbs;
unsigned tempBufSize;
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
} CLzmaDec;
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
void LzmaDec_Init(CLzmaDec *p);
/* There are two types of LZMA streams:
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
typedef enum
{
LZMA_FINISH_ANY, /* finish at any point */
LZMA_FINISH_END /* block must be finished at the end */
} ELzmaFinishMode;
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
You must use LZMA_FINISH_END, when you know that current output buffer
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
and output value of destLen will be less than output buffer size limit.
You can check status result also.
You can use multiple checks to test data integrity after full decompression:
1) Check Result and "status" variable.
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
You must use correct finish mode in that case. */
typedef enum
{
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
} ELzmaStatus;
/* ELzmaStatus is used only as output value for function call */
/* ---------- Interfaces ---------- */
/* There are 3 levels of interfaces:
1) Dictionary Interface
2) Buffer Interface
3) One Call Interface
You can select any of these interfaces, but don't mix functions from different
groups for same object. */
/* There are two variants to allocate state for Dictionary Interface:
1) LzmaDec_Allocate / LzmaDec_Free
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
You can use variant 2, if you set dictionary buffer manually.
For Buffer Interface you must always use variant 1.
LzmaDec_Allocate* can return:
SZ_OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
/* ---------- Dictionary Interface ---------- */
/* You can use it, if you want to eliminate the overhead for data copying from
dictionary to some other external buffer.
You must work with CLzmaDec variables directly in this interface.
STEPS:
LzmaDec_Constr()
LzmaDec_Allocate()
for (each new stream)
{
LzmaDec_Init()
while (it needs more decompression)
{
LzmaDec_DecodeToDic()
use data from CLzmaDec::dic and update CLzmaDec::dicPos
}
}
LzmaDec_Free()
*/
/* LzmaDec_DecodeToDic
The decoding to internal dictionary buffer (CLzmaDec::dic).
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
finishMode:
It has meaning only if the decoding reaches output limit (dicLimit).
LZMA_FINISH_ANY - Decode just dicLimit bytes.
LZMA_FINISH_END - Stream must be finished after dicLimit.
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_NEEDS_MORE_INPUT
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
*/
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- Buffer Interface ---------- */
/* It's zlib-like interface.
See LzmaDec_DecodeToDic description for information about STEPS and return results,
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
to work with CLzmaDec variables manually.
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
*/
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- One Call Interface ---------- */
/* LzmaDecode
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
*/
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc);
#endif

2281
LzmaEnc.c Normal file

File diff suppressed because it is too large Load Diff

72
LzmaEnc.h Normal file
View File

@ -0,0 +1,72 @@
/* LzmaEnc.h -- LZMA Encoder
2008-10-04 : Igor Pavlov : Public domain */
#ifndef __LZMAENC_H
#define __LZMAENC_H
#include "types.h"
#define LZMA_PROPS_SIZE 5
typedef struct _CLzmaEncProps
{
int level; /* 0 <= level <= 9 */
LZ_UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version
default = (1 << 24) */
int lc; /* 0 <= lc <= 8, default = 3 */
int lp; /* 0 <= lp <= 4, default = 0 */
int pb; /* 0 <= pb <= 4, default = 2 */
int algo; /* 0 - fast, 1 - normal, default = 1 */
int fb; /* 5 <= fb <= 273, default = 32 */
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
int numHashBytes; /* 2, 3 or 4, default = 4 */
LZ_UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
int numThreads; /* 1 or 2, default = 2 */
} CLzmaEncProps;
void LzmaEncProps_Init(CLzmaEncProps *p);
void LzmaEncProps_Normalize(CLzmaEncProps *p);
LZ_UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
/* ---------- CLzmaEncHandle Interface ---------- */
/* LzmaEnc_* functions can return the following exit codes:
Returns:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater in props
SZ_ERROR_WRITE - Write callback error.
SZ_ERROR_PROGRESS - some break from progress callback
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
*/
typedef void * CLzmaEncHandle;
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
/* ---------- One Call Interface ---------- */
/* LzmaEncode
Return code:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater
SZ_ERROR_OUTPUT_EOF - output buffer overflow
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
*/
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
#endif

46
LzmaLib.c Normal file
View File

@ -0,0 +1,46 @@
/* LzmaLib.c -- LZMA library wrapper
2008-08-05
Igor Pavlov
Public domain */
#include "LzmaEnc.h"
#include "LzmaDec.h"
#include "Alloc.h"
#include "LzmaLib.h"
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
unsigned char *outProps, size_t *outPropsSize,
int level, /* 0 <= level <= 9, default = 5 */
unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */
int lc, /* 0 <= lc <= 8, default = 3 */
int lp, /* 0 <= lp <= 4, default = 0 */
int pb, /* 0 <= pb <= 4, default = 2 */
int fb, /* 5 <= fb <= 273, default = 32 */
int numThreads /* 1 or 2, default = 2 */
)
{
CLzmaEncProps props;
LzmaEncProps_Init(&props);
props.level = level;
props.dictSize = dictSize;
props.lc = lc;
props.lp = lp;
props.pb = pb;
props.fb = fb;
props.numThreads = numThreads;
return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0,
NULL, &g_Alloc, &g_Alloc);
}
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen,
const unsigned char *props, size_t propsSize)
{
ELzmaStatus status;
return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc);
}

135
LzmaLib.h Normal file
View File

@ -0,0 +1,135 @@
/* LzmaLib.h -- LZMA library interface
2008-08-05
Igor Pavlov
Public domain */
#ifndef __LZMALIB_H
#define __LZMALIB_H
#include "types.h"
#ifdef __cplusplus
#define MY_EXTERN_C extern "C"
#else
#define MY_EXTERN_C extern
#endif
#define MY_STDAPI MY_EXTERN_C int MY_STD_CALL
#define LZMA_PROPS_SIZE 5
/*
RAM requirements for LZMA:
for compression: (dictSize * 11.5 + 6 MB) + state_size
for decompression: dictSize + state_size
state_size = (4 + (1.5 << (lc + lp))) KB
by default (lc=3, lp=0), state_size = 16 KB.
LZMA properties (5 bytes) format
Offset Size Description
0 1 lc, lp and pb in encoded form.
1 4 dictSize (little endian).
*/
/*
LzmaCompress
------------
outPropsSize -
In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
LZMA Encoder will use defult values for any parameter, if it is
-1 for any from: level, loc, lp, pb, fb, numThreads
0 for dictSize
level - compression level: 0 <= level <= 9;
level dictSize algo fb
0: 16 KB 0 32
1: 64 KB 0 32
2: 256 KB 0 32
3: 1 MB 0 32
4: 4 MB 0 32
5: 16 MB 1 32
6: 32 MB 1 32
7+: 64 MB 1 64
The default value for "level" is 5.
algo = 0 means fast method
algo = 1 means normal method
dictSize - The dictionary size in bytes. The maximum value is
128 MB = (1 << 27) bytes for 32-bit version
1 GB = (1 << 30) bytes for 64-bit version
The default value is 16 MB = (1 << 24) bytes.
It's recommended to use the dictionary that is larger than 4 KB and
that can be calculated as (1 << N) or (3 << N) sizes.
lc - The number of literal context bits (high bits of previous literal).
It can be in the range from 0 to 8. The default value is 3.
Sometimes lc=4 gives the gain for big files.
lp - The number of literal pos bits (low bits of current position for literals).
It can be in the range from 0 to 4. The default value is 0.
The lp switch is intended for periodical data when the period is equal to 2^lp.
For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's
better to set lc=0, if you change lp switch.
pb - The number of pos bits (low bits of current position).
It can be in the range from 0 to 4. The default value is 2.
The pb switch is intended for periodical data when the period is equal 2^pb.
fb - Word size (the number of fast bytes).
It can be in the range from 5 to 273. The default value is 32.
Usually, a big number gives a little bit better compression ratio and
slower compression process.
numThreads - The number of thereads. 1 or 2. The default value is 2.
Fast mode (algo = 0) can use only 1 thread.
Out:
destLen - processed output size
Returns:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater
SZ_ERROR_OUTPUT_EOF - output buffer overflow
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
*/
MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */
int level, /* 0 <= level <= 9, default = 5 */
unsigned dictSize, /* default = (1 << 24) */
int lc, /* 0 <= lc <= 8, default = 3 */
int lp, /* 0 <= lp <= 4, default = 0 */
int pb, /* 0 <= pb <= 4, default = 2 */
int fb, /* 5 <= fb <= 273, default = 32 */
int numThreads /* 1 or 2, default = 2 */
);
/*
LzmaUncompress
--------------
In:
dest - output data
destLen - output data size
src - input data
srcLen - input data size
Out:
destLen - processed output size
srcLen - processed input size
Returns:
SZ_OK - OK
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation arror
SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src)
*/
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
const unsigned char *props, size_t propsSize);
#endif

433
MBLRoutines.c Normal file
View File

@ -0,0 +1,433 @@
/*
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
*/
// Mail and Chat Server for BPQ32 Packet Switch
//
// MBL-Style Forwarding Routines
#include "bpqmail.h"
void SendMessageReadEvent(char * call, struct MsgInfo * Msg);
void MQTTMessageEvent(void* message);
VOID ProcessMBLLine(CIRCUIT * conn, struct UserInfo * user, UCHAR* Buffer, int len)
{
Buffer[len] = 0;
// Winpack can send a second SID to switch to upload mode
if (Buffer[0] == '[' && Buffer[len-2] == ']') // SID
{
if (user->flags & (F_PMS))
{
Parse_SID(conn, &Buffer[1], len-4);
if (conn->BBSFlags & FBBForwarding)
{
conn->FBBIndex = 0; // ready for first block;
conn->FBBChecksum = 0;
memset(&conn->FBBHeaders[0], 0, 5 * sizeof(struct FBBHeaderLine));
}
else
FBBputs(conn, ">\r");
}
return;
}
if (Buffer[0] == 6 && Buffer[1] == 5)
{
// ?? Sally send these after a failed tranfer
memmove(Buffer, &Buffer[2], len);
len-=2;
}
if (_memicmp(Buffer, "F< ", 3) == 0)
{
// FBB Compressed request from system using UI Messages
int Number = atoi(&Buffer[3]);
struct MsgInfo * Msg = FindMessageByNumber(Number);
char ErrMsg[80];
int ErrLen;
if (Msg == 0)
{
ErrLen = sprintf(&ErrMsg[2], "Msg $%d does not exist!\r>", Number);
ErrMsg[0] = 0x18;
ErrMsg[1] = ErrLen;
BBSputs(conn, ErrMsg);
FBBputs(conn, ">\r");
return;
}
Msg = FindMessage(user->Call, Number, conn->sysop);
if (Msg)
{
conn->BBSFlags |= FBBCompressed; // Needs compression
SendCompressed(conn, Msg);
FBBputs(conn, ">\r");
Msg->status = 'Y'; // Mark as read
SaveMessageDatabase();
SendMessageReadEvent(user->Call, Msg);
}
else
{
ErrLen = sprintf(&ErrMsg[2], "Msg $%d not available to you!\r>", Number);
ErrMsg[0] = 0x18;
ErrMsg[1] = ErrLen;
BBSputs(conn, ErrMsg);
FBBputs(conn, ">\r");
}
return;
}
if (Buffer[0] == 'S') //Send
{
// SB WANT @ ALLCAN < N6ZFJ $4567_N0ARY
char * Cmd;
char * To = NULL;
char * From = NULL;
char * BID = NULL;
char * ATBBS = NULL;
char * ptr, * Context;
char seps[] = " \t\r";
Cmd = strtok_s(Buffer, seps, &Context);
if (Cmd[1] == 0) Cmd[1] = 'P';
if (RefuseBulls && Cmd[1] == 'B')
{
nodeprintfEx(conn, "NO - BULLS NOT ACCEPTED\r");
if (conn->BBSFlags & OUTWARDCONNECT)
nodeprintfEx(conn, "F>\r"); // if Outward connect must be reverse forward
else
nodeprintfEx(conn, ">\r");
return;
}
To = strtok_s(NULL, seps, &Context);
ptr = strtok_s(NULL, seps, &Context);
while (ptr)
{
if (strcmp(ptr, "@") == 0)
{
ATBBS = _strupr(strtok_s(NULL, seps, &Context));
}
else if(strcmp(ptr, "<") == 0)
{
From = strtok_s(NULL, seps, &Context);
}
else if (ptr[0] == '$')
BID = &ptr[1];
else
{
nodeprintfEx(conn, "*** Error: Invalid Format\r");
return;
}
ptr = strtok_s(NULL, seps, &Context);
}
if (!From)
{
nodeprintfEx(conn, "*** Error: Invalid Format\r");
return;
}
if (BID && LookupTempBID(BID))
{
// Being received from another BBS
nodeprintfEx(conn, "NO - BID\r");
if (conn->BBSFlags & OUTWARDCONNECT)
nodeprintfEx(conn, "F>\r"); // if Outward connect must be reverse forward
else
nodeprintfEx(conn, ">\r");
return;
}
CreateMessage(conn, From, To, ATBBS, toupper(Cmd[1]), BID, NULL);
return;
}
if (Buffer[0] == 'N') // Not wanted
{
if (conn->FwdMsg)
{
// Zap the entry
clear_fwd_bit(conn->FwdMsg->fbbs, user->BBSNumber);
set_fwd_bit(conn->FwdMsg->forw, user->BBSNumber);
conn->UserPointer->ForwardingInfo->MsgCount--;
// Only mark as forwarded if sent to all BBSs that should have it
if (memcmp(conn->FwdMsg->fbbs, zeros, NBMASK) == 0)
{
conn->FwdMsg->status = 'F'; // Mark as forwarded
conn->FwdMsg->datechanged=time(NULL);
}
conn->FwdMsg->Locked = 0; // Unlock
#ifndef NOMQTT
if (MQTT)
MQTTMessageEvent(conn->FwdMsg);
#endif
}
return;
}
if (Buffer[0] == 'O') // Need it (OK)
{
struct tm * tm;
time_t now;
char * MsgBytes;
char * MsgPtr; // In case updated for B2
int MsgLen;
if (!conn->FwdMsg)
return;
nodeprintfEx(conn, "%s\r", conn->FwdMsg->title);
MsgBytes = ReadMessageFile(conn->FwdMsg->number);
if (MsgBytes == 0)
{
MsgBytes = _strdup("Message file not found\r");
conn->FwdMsg->length = (int)strlen(MsgBytes);
}
MsgPtr = MsgBytes;
MsgLen = conn->FwdMsg->length;
// If a B2 Message, remove B2 Header
if (conn->FwdMsg->B2Flags & B2Msg)
{
// Remove all B2 Headers, and all but the first part.
MsgPtr = strstr(MsgBytes, "Body:");
if (MsgPtr)
{
MsgLen = atoi(&MsgPtr[5]);
MsgPtr= strstr(MsgBytes, "\r\n\r\n"); // Blank Line after headers
if (MsgPtr)
MsgPtr +=4;
else
MsgPtr = MsgBytes;
}
else
MsgPtr = MsgBytes;
}
MsgLen = RemoveLF(MsgPtr, MsgLen);
now = time(NULL);
tm = gmtime(&now);
nodeprintf(conn, "R:%02d%02d%02d/%02d%02dZ %d@%s.%s %s\r",
tm->tm_year-100, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min,
conn->FwdMsg->number, BBSName, HRoute, RlineVer);
if (memcmp(MsgPtr, "R:", 2) != 0) // No R line, so must be our message
BBSputs(conn, "\r");
QueueMsg(conn, MsgPtr, MsgLen);
if (user->ForwardingInfo->SendCTRLZ)
nodeprintf(conn, "\rx1a");
else
nodeprintf(conn, "\r/ex\r");
free(MsgBytes);
conn->FBBMsgsSent = TRUE;
return;
}
if (_stricmp(Buffer, "F>\r") == 0)
{
// Reverse forward request
// If we have just sent a message, Flag it as sent
if (conn->FBBMsgsSent)
{
conn->FBBMsgsSent = FALSE;
clear_fwd_bit(conn->FwdMsg->fbbs, user->BBSNumber);
set_fwd_bit(conn->FwdMsg->forw, user->BBSNumber);
// Only mark as forwarded if sent to all BBSs that should have it
if (memcmp(conn->FwdMsg->fbbs, zeros, NBMASK) == 0)
{
conn->FwdMsg->status = 'F'; // Mark as forwarded
conn->FwdMsg->datechanged=time(NULL);
}
conn->FwdMsg->Locked = 0; // Unlock
#ifndef NOMQTT
if (MQTT)
MQTTMessageEvent(conn->FwdMsg);
#endif
conn->UserPointer->ForwardingInfo->MsgCount--;
}
// Send Message or Disconnect
if (FindMessagestoForward(conn))
{
struct MsgInfo * Msg;
// Send S line and wait for response - SB WANT @ USA < W8AAA $1029_N0XYZ
Msg = conn->FwdMsg;
if (conn->BBSFlags & MFJMODE)
{
// No @ BBS to MFJ TNC
nodeprintfEx(conn, "S%c %s < %s $%s\r", Msg->type, Msg->to, Msg->from, Msg->bid);
}
else
nodeprintfEx(conn, "S%c %s @ %s < %s $%s\r", Msg->type, Msg->to,
(Msg->via[0]) ? Msg->via : conn->UserPointer->Call,
Msg->from, Msg->bid);
conn->BBSFlags |= MBLFORWARDING;
return;
}
BBSputs(conn, "*** DONE\r");
Flush(conn);
Sleep(400);
Disconnect(conn->BPQStream);
return;
}
if (Buffer[len-2] == '>')
{
// If we have just sent a message, Flag it as sent
if (conn->FBBMsgsSent)
{
conn->FBBMsgsSent = FALSE;
clear_fwd_bit(conn->FwdMsg->fbbs, user->BBSNumber);
set_fwd_bit(conn->FwdMsg->forw, user->BBSNumber);
// Only mark as forwarded if sent to all BBSs that should have it
if (memcmp(conn->FwdMsg->fbbs, zeros, NBMASK) == 0)
{
conn->FwdMsg->status = 'F'; // Mark as forwarded
conn->FwdMsg->datechanged=time(NULL);
}
#ifndef NOMQTT
if (MQTT)
MQTTMessageEvent(conn->FwdMsg);
#endif
conn->UserPointer->ForwardingInfo->MsgCount--;
}
// Send Message or request reverse using MBL-style forwarding
if (FindMessagestoForward(conn))
{
struct MsgInfo * Msg;
// Send S line and wait for response - SB WANT @ USA < W8AAA $1029_N0XYZ
Msg = conn->FwdMsg;
nodeprintfEx(conn, "S%c %s @ %s < %s $%s\r", Msg->type, Msg->to,
(Msg->via[0]) ? Msg->via : conn->UserPointer->Call,
Msg->from, Msg->bid);
return;
}
else
{
FBBputs(conn, "F>\r");
return;
}
}
// Winpack after doing ocmpressed downloads sends KM or B
if (_stricmp(Buffer, "*** DONE\r") == 0 || _stricmp(Buffer, "*** What?\r") == 0
|| _stricmp(Buffer, "B\r") == 0)
{
Disconnect(conn->BPQStream);
return;
}
if (_stricmp(Buffer, "KM\r") == 0)
{
int i;
struct MsgInfo * Msg;
for (i = NumberofMessages; i > 0; i--)
{
Msg = MsgHddrPtr[i];
if ((_stricmp(Msg->to, user->Call) == 0))
{
if (Msg->type == 'P' && Msg->status == 'Y')
{
FlagAsKilled(Msg, TRUE);
nodeprintfEx(conn, "Message #%d Killed\r", Msg->number);
}
}
}
SendPrompt(conn, user);
return;
}
}

427
MCP2221.c Normal file
View File

@ -0,0 +1,427 @@
// MCP2221.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include "time.h"
#include "winstdint.h"
#include "hidapi.h"
void DecodeCM108(int Port, char * ptr);
#ifdef WIN32
/* Simple Raw HID functions for Windows - for use with Teensy RawHID example
* http://www.pjrc.com/teensy/rawhid.html
* Copyright (c) 2009 PJRC.COM, LLC
*
* rawhid_open - open 1 or more devices
* rawhid_recv - receive a packet
* rawhid_send - send a packet
* rawhid_close - close a device
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above description, website URL and copyright notice and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* Version 1.0: Initial Release
*/
#include <stdio.h>
#include <stdlib.h>
//#include <stdint.h>
#include <windows.h>
#include <setupapi.h>
//#include <ddk/hidsdi.h>
//#include <ddk/hidclass.h>
typedef USHORT USAGE;
typedef struct _HIDD_CONFIGURATION {
PVOID cookie;
ULONG size;
ULONG RingBufferSize;
} HIDD_CONFIGURATION, *PHIDD_CONFIGURATION;
typedef struct _HIDD_ATTRIBUTES {
ULONG Size;
USHORT VendorID;
USHORT ProductID;
USHORT VersionNumber;
} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
typedef struct _HIDP_CAPS {
USAGE Usage;
USAGE UsagePage;
USHORT InputReportByteLength;
USHORT OutputReportByteLength;
USHORT FeatureReportByteLength;
USHORT Reserved[17];
USHORT NumberLinkCollectionNodes;
USHORT NumberInputButtonCaps;
USHORT NumberInputValueCaps;
USHORT NumberInputDataIndices;
USHORT NumberOutputButtonCaps;
USHORT NumberOutputValueCaps;
USHORT NumberOutputDataIndices;
USHORT NumberFeatureButtonCaps;
USHORT NumberFeatureValueCaps;
USHORT NumberFeatureDataIndices;
} HIDP_CAPS, *PHIDP_CAPS;
typedef struct _HIDP_PREPARSED_DATA * PHIDP_PREPARSED_DATA;
// a list of all opened HID devices, so the caller can
// simply refer to them by number
typedef struct hid_struct hid_t;
static hid_t *first_hid = NULL;
static hid_t *last_hid = NULL;
struct hid_struct {
HANDLE handle;
int open;
struct hid_struct *prev;
struct hid_struct *next;
};
static HANDLE rx_event=NULL;
static HANDLE tx_event=NULL;
static CRITICAL_SECTION rx_mutex;
static CRITICAL_SECTION tx_mutex;
// private functions, not intended to be used from outside this file
static void add_hid(hid_t *h);
static hid_t * get_hid(int num);
static void free_all_hid(void);
void print_win32_err(void);
// rawhid_recv - receive a packet
// Inputs:
// num = device to receive from (zero based)
// buf = buffer to receive packet
// len = buffer's size
// timeout = time to wait, in milliseconds
// Output:
// number of bytes received, or -1 on error
//
int rawhid_recv(int num, void *buf, int len, int timeout)
{
hid_t *hid;
unsigned char tmpbuf[516];
OVERLAPPED ov;
DWORD r;
int n;
if (sizeof(tmpbuf) < len + 1) return -1;
hid = get_hid(num);
if (!hid || !hid->open) return -1;
EnterCriticalSection(&rx_mutex);
ResetEvent(&rx_event);
memset(&ov, 0, sizeof(ov));
ov.hEvent = rx_event;
if (!ReadFile(hid->handle, tmpbuf, len + 1, NULL, &ov)) {
if (GetLastError() != ERROR_IO_PENDING) goto return_error;
r = WaitForSingleObject(rx_event, timeout);
if (r == WAIT_TIMEOUT) goto return_timeout;
if (r != WAIT_OBJECT_0) goto return_error;
}
if (!GetOverlappedResult(hid->handle, &ov, &n, FALSE)) goto return_error;
LeaveCriticalSection(&rx_mutex);
if (n <= 0) return -1;
n--;
if (n > len) n = len;
memcpy(buf, tmpbuf + 1, n);
return n;
return_timeout:
CancelIo(hid->handle);
LeaveCriticalSection(&rx_mutex);
return 0;
return_error:
print_win32_err();
LeaveCriticalSection(&rx_mutex);
return -1;
}
// rawhid_send - send a packet
// Inputs:
// num = device to transmit to (zero based)
// buf = buffer containing packet to send
// len = number of bytes to transmit
// timeout = time to wait, in milliseconds
// Output:
// number of bytes sent, or -1 on error
//
int rawhid_send(int num, void *buf, int len, int timeout)
{
hid_t *hid;
unsigned char tmpbuf[516];
OVERLAPPED ov;
DWORD n, r;
if (sizeof(tmpbuf) < len + 1) return -1;
hid = get_hid(num);
if (!hid || !hid->open) return -1;
EnterCriticalSection(&tx_mutex);
ResetEvent(&tx_event);
memset(&ov, 0, sizeof(ov));
ov.hEvent = tx_event;
tmpbuf[0] = 0;
memcpy(tmpbuf + 1, buf, len);
if (!WriteFile(hid->handle, tmpbuf, len + 1, NULL, &ov)) {
if (GetLastError() != ERROR_IO_PENDING) goto return_error;
r = WaitForSingleObject(tx_event, timeout);
if (r == WAIT_TIMEOUT) goto return_timeout;
if (r != WAIT_OBJECT_0) goto return_error;
}
if (!GetOverlappedResult(hid->handle, &ov, &n, FALSE)) goto return_error;
LeaveCriticalSection(&tx_mutex);
if (n <= 0) return -1;
return n - 1;
return_timeout:
CancelIo(hid->handle);
LeaveCriticalSection(&tx_mutex);
return 0;
return_error:
print_win32_err();
LeaveCriticalSection(&tx_mutex);
return -1;
}
HANDLE rawhid_open(char * Device)
{
DWORD index=0;
HANDLE h;
hid_t *hid;
int count=0;
if (first_hid) free_all_hid();
if (!rx_event)
{
rx_event = CreateEvent(NULL, TRUE, TRUE, NULL);
tx_event = CreateEvent(NULL, TRUE, TRUE, NULL);
InitializeCriticalSection(&rx_mutex);
InitializeCriticalSection(&tx_mutex);
}
h = CreateFile(Device, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (h == INVALID_HANDLE_VALUE)
return 0;
hid = (struct hid_struct *)malloc(sizeof(struct hid_struct));
if (!hid)
{
CloseHandle(h);
return 0;
}
hid->handle = h;
hid->open = 1;
add_hid(hid);
return h;
}
// rawhid_close - close a device
//
// Inputs:
// num = device to close (zero based)
// Output
// (nothing)
//
void rawhid_close(int num)
{
hid_t *hid;
hid = get_hid(num);
if (!hid || !hid->open) return;
CloseHandle(hid->handle);
hid->handle = NULL;
hid->open = FALSE;
}
static void add_hid(hid_t *h)
{
if (!first_hid || !last_hid) {
first_hid = last_hid = h;
h->next = h->prev = NULL;
return;
}
last_hid->next = h;
h->prev = last_hid;
h->next = NULL;
last_hid = h;
}
static hid_t * get_hid(int num)
{
hid_t *p;
for (p = first_hid; p && num > 0; p = p->next, num--) ;
return p;
}
static void free_all_hid(void)
{
hid_t *p, *q;
for (p = first_hid; p; p = p->next)
{
CloseHandle(p->handle);
p->handle = NULL;
p->open = FALSE;
}
p = first_hid;
while (p) {
q = p;
p = p->next;
free(q);
}
first_hid = last_hid = NULL;
}
void print_win32_err(void)
{
char buf[256];
DWORD err;
err = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
0, buf, sizeof(buf), NULL);
printf("err %ld: %s\n", err, buf);
}
#endif
HANDLE hDevice;
char * HIDDevice;
int main()
{
int Len;
unsigned char Msg[65] = "";
DecodeCM108(0, "0x4D8:0xDD");
hDevice = rawhid_open(HIDDevice);
if (hDevice)
printf("Rigcontrol HID Device %s opened\n", HIDDevice);
Msg[0] = 0x51;
Msg[0] = 0xB0;
Msg[1] = 0x1;
Len = rawhid_send(0, Msg, 64, 100);
Msg[0] = 0;
#ifdef WIN32
Len = rawhid_recv(0, Msg, 64, 100);
#else
Len = read(PORT->hDevice, Msg, 64);
#endif
return 0;
}
char * CM108Device = NULL;
void DecodeCM108(int Port, char * ptr)
{
// Called if Device Name or PTT = Param is CM108
#ifdef WIN32
// Next Param is VID and PID - 0xd8c:0x8 or Full device name
// On Windows device name is very long and difficult to find, so
// easier to use VID/PID, but allow device in case more than one needed
char * next;
int32_t VID = 0, PID = 0;
char product[256];
char sernum[256] = "NULL";
struct hid_device_info *devs, *cur_dev;
const char *path_to_open = NULL;
hid_device *handle = NULL;
if (strlen(ptr) > 16)
CM108Device = _strdup(ptr);
else
{
VID = strtol(ptr, &next, 0);
if (next)
PID = strtol(++next, &next, 0);
// Look for Device
devs = hid_enumerate(0, 0); // so we list devices(USHORT)VID, (USHORT)PID);
cur_dev = devs;
while (cur_dev)
{
wcstombs(product, cur_dev->product_string, 255);
if (cur_dev->serial_number)
wcstombs(sernum, cur_dev->serial_number, 255);
if (product)
printf("HID Device %s VID %X PID %X Ser %s %s\n", product, cur_dev->vendor_id, cur_dev->product_id, sernum, cur_dev->path);
else
printf("HID Device %s VID %X PID %X Ser %s %s", "Missing Product\n", cur_dev->vendor_id, cur_dev->product_id, sernum, cur_dev->path);
if (cur_dev->vendor_id == VID && cur_dev->product_id == PID)
path_to_open = cur_dev->path;
cur_dev = cur_dev->next;
}
if (path_to_open)
{
HIDDevice = _strdup(path_to_open);
}
hid_free_enumeration(devs);
}
#else
// Linux - Next Param HID Device, eg /dev/hidraw0
CM108Device = _strdup(ptr);
#endif
}

0
MHSave.txt Normal file
View File

1554
MULTIPSK.c Normal file

File diff suppressed because it is too large Load Diff

1543
MULTIPSK64.c Normal file

File diff suppressed because it is too large Load Diff

696
MailCommands.c Normal file
View File

@ -0,0 +1,696 @@
/*
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
*/
#include "bpqmail.h"
int APIENTRY ChangeSessionIdletime(int Stream, int idletime);
struct MsgInfo * GetMsgFromNumber(int msgno);
BOOL ForwardMessagetoFile(struct MsgInfo * Msg, FILE * Handle);
struct UserInfo * FindBBS(char * Name);
int ListMessagestoForward(CIRCUIT * conn, struct UserInfo * user);
static char seps[] = " \t\r";
VOID DoAuthCmd(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
int AuthInt = 0;
if (!(user->flags & F_SYSOP))
{
nodeprintf(conn, "AUTH can only be used by SYSOPs\r");
SendPrompt(conn, user);
return;
}
if (Arg1)
AuthInt = atoi(Arg1);
else
{
nodeprintf(conn, "AUTH Code missing\r");
SendPrompt(conn, user);
return;
}
if (user->Temp->LastAuthCode == AuthInt)
{
nodeprintf(conn, "AUTH Code already used\r");
SendPrompt(conn, user);
return;
}
if (Arg1 && CheckOneTimePassword(Arg1, user->pass))
{
conn->sysop = TRUE;
nodeprintf(conn, "Ok\r");
user->Temp->LastAuthCode = atoi(Arg1);
}
else
nodeprintf(conn, "AUTH Failed\r");
SendPrompt(conn, user);
return;
}
VOID DoEditUserCmd(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
char Line[200] = "User Flags:";
struct UserInfo * EUser = user;
if (conn->sysop == 0)
{
nodeprintf(conn, "Edit User needs SYSOP status\r");
SendPrompt(conn, user);
return;
}
if (Arg1 == 0 || _stricmp(Arg1, "HELP") == 0)
{
nodeprintf(conn, "EDITUSER CALLSIGN to Display\r");
nodeprintf(conn, "EDITUSER CALLSIGN FLAG1 FLAG2 ... to set, -FLAG1 -FLAG2 ... to clear\r");
nodeprintf(conn, "EDITUSER: Flags are: EXC(luded) EXP(ert) SYSOP BBS PMS EMAIL HOLD RMS(Express User) APRS(Mail For)\r");
SendPrompt(conn, user);
return;
}
EUser = LookupCall(Arg1);
if (EUser == 0)
{
nodeprintf(conn, "User %s not found\r", Arg1);
SendPrompt(conn, user);
return;
}
Arg1 = strtok_s(NULL, seps, &Context);
if (Arg1 == NULL)
goto UDisplay;
// A set of flags to change +Flag or -Flag
while(Arg1 && strlen(Arg1) > 2)
{
_strupr(Arg1);
if (strstr(Arg1, "EXC"))
if (Arg1[0] != '-') EUser->flags |= F_Excluded; else EUser->flags &= ~F_Excluded;
if (strstr(Arg1, "EXP"))
if (Arg1[0] != '-') EUser->flags |= F_Expert; else EUser->flags &= ~F_Expert;
if (strstr(Arg1, "SYS"))
if (Arg1[0] != '-') EUser->flags |= F_SYSOP; else EUser->flags &= ~F_SYSOP;
if (strstr(Arg1, "BBS"))
if (Arg1[0] != '-') EUser->flags |= F_BBS; else EUser->flags &= ~F_BBS;
if (strstr(Arg1, "PMS"))
if (Arg1[0] != '-') EUser->flags |= F_PMS; else EUser->flags &= ~F_PMS;
if (strstr(Arg1, "EMAIL"))
if (Arg1[0] != '-') EUser->flags |= F_EMAIL; else EUser->flags &= ~F_EMAIL;
if (strstr(Arg1, "HOLD"))
if (Arg1[0] != '-') EUser->flags |= F_HOLDMAIL; else EUser->flags &= ~F_HOLDMAIL;
if (strstr(Arg1, "RMS"))
if (Arg1[0] != '-') EUser->flags |= F_Temp_B2_BBS; else EUser->flags &= ~F_Temp_B2_BBS;
if (strstr(Arg1, "APRS"))
if (Arg1[0] != '-') EUser->flags |= F_APRSMFOR; else EUser->flags &= ~F_APRSMFOR;
Arg1 = strtok_s(NULL, seps, &Context);
}
SaveUserDatabase();
// Drop through to display
UDisplay:
if (EUser->flags & F_Excluded)
strcat(Line, " EXC");
if (EUser->flags & F_Expert)
strcat(Line, " EXP");
if (EUser->flags & F_SYSOP)
strcat(Line, " SYSOP");
if (EUser->flags & F_BBS)
strcat(Line, " BBS");
if (EUser->flags & F_PMS)
strcat(Line, " PMS");
if (EUser->flags & F_EMAIL)
strcat(Line, " EMAIL");
if (EUser->flags & F_HOLDMAIL)
strcat(Line, " HOLD");
if (EUser->flags & F_Temp_B2_BBS)
strcat(Line, " RMS");
if (EUser->flags & F_APRSMFOR)
strcat(Line, " APRS");
strcat(Line, "\r");
nodeprintf(conn, Line);
SendPrompt(conn, user);
return;
}
VOID DoShowRMSCmd(CIRCUIT * conn, struct UserInfo * inuser, char * Arg1, char * Context)
{
int i, s;
char FWLine[10000] = "";
struct UserInfo * user;
char RMSCall[20];
if (conn->sysop == 0)
{
nodeprintf(conn, "Command needs SYSOP status\r");
SendPrompt(conn, inuser);
return;
}
for (i = 0; i <= NumberofUsers; i++)
{
user = UserRecPtr[i];
if (user->flags & F_POLLRMS)
{
if (user->RMSSSIDBits == 0) user->RMSSSIDBits = 1;
for (s = 0; s < 16; s++)
{
if (user->RMSSSIDBits & (1 << s))
{
strcat(FWLine, " ");
if (s)
{
sprintf(RMSCall, "%s-%d", user->Call, s);
strcat(FWLine, RMSCall);
}
else
strcat(FWLine, user->Call);
}
}
}
}
strcat(FWLine, "\r");
nodeprintf(conn, FWLine);
}
VOID DoPollRMSCmd(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
char RMSLine[200];
char RMSCall[10];
struct UserInfo * RMSUser = user;
int s;
Loop:
if (Arg1)
{
// Update
if (_stricmp(Arg1, "Enable") == 0)
{
RMSUser->flags |= F_POLLRMS;
Arg1 = strtok_s(NULL, seps, &Context);
goto Display;
}
else if (_stricmp(Arg1, "Disable") == 0)
{
RMSUser->flags &= ~F_POLLRMS;
Arg1 = strtok_s(NULL, seps, &Context);
goto Display;
}
else if (strlen(Arg1) > 2)
{
// Callsign - if SYSOP, following commands apply to selected user
if (conn->sysop == 0)
{
nodeprintf(conn, "Changing RMS Poll params for another user needs SYSOP status\r");
SendPrompt(conn, user);
return;
}
RMSUser = LookupCall(Arg1);
if (RMSUser == NULL)
{
nodeprintf(conn, "User %s not found\r", Arg1);
SendPrompt(conn, user);
return;
}
Arg1 = strtok_s(NULL, seps, &Context);
if (Arg1 == NULL)
goto Display;
if (_stricmp(Arg1, "Enable") == 0 || _stricmp(Arg1, "Disable") == 0 || (strlen(Arg1) < 3))
goto Loop;
goto Display;
}
// A list of SSID's to poll
RMSUser->RMSSSIDBits = 0;
while(Arg1 && strlen(Arg1) < 3)
{
s = atoi(Arg1);
if (s < 16)
RMSUser->RMSSSIDBits |= (1 << (s));
Arg1 = strtok_s(NULL, seps, &Context);
}
}
// Drop through to display
Display:
strcpy(RMSLine, "Polling for calls");
if (RMSUser->flags & F_POLLRMS)
{
if (RMSUser->RMSSSIDBits == 0) RMSUser->RMSSSIDBits = 1;
{
for (s = 0; s < 16; s++)
{
if (RMSUser->RMSSSIDBits & (1 << s))
{
strcat(RMSLine, " ");
if (s)
{
sprintf(RMSCall, "%s-%d", RMSUser->Call, s);
strcat(RMSLine, RMSCall);
}
else
strcat(RMSLine, RMSUser->Call);
}
}
}
strcat(RMSLine, "\r");
nodeprintf(conn, RMSLine);
}
else
nodeprintf(conn, "RMS Polling for %s disabled\r", RMSUser->Call);
if (Arg1)
goto Loop;
SaveUserDatabase();
SendPrompt(conn, user);
}
VOID DoSetIdleTime(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
int IdleTime;
if (Arg1)
IdleTime = atoi(Arg1);
else
{
nodeprintf(conn, "Format is IDLETIME nnn\r");
SendPrompt(conn, user);
return;
}
if (IdleTime < 60 || IdleTime > 900)
{
nodeprintf(conn, "Time out of range (60 to 900 seconds)\r");
SendPrompt(conn, user);
return;
}
if (conn->BPQStream >= 0)
ChangeSessionIdletime(conn->BPQStream, IdleTime);
else
{
nodeprintf(conn, "Can't set Idle Time on Console)\r");
SendPrompt(conn, user);
return;
}
nodeprintf(conn, "Idle Time set to %d\r", IdleTime);
SendPrompt(conn, user);
return;
}
VOID DoSetMsgNo(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
int newNumber;
if (conn->sysop == 0)
{
nodeprintf(conn, "Command needs SYSOP status\r");
SendPrompt(conn, user);
return;
}
if (Arg1)
newNumber = atoi(Arg1);
else
{
nodeprintf(conn, "New Number not specified\r");
SendPrompt(conn, user);
return;
}
if (newNumber < LatestMsg)
{
nodeprintf(conn, "New Number less tham current (%d)\r", LatestMsg);
SendPrompt(conn, user);
return;
}
if (newNumber > (MaxMsgno - 1000))
{
nodeprintf(conn, "New Number too close to Max Message Number\r");
SendPrompt(conn, user);
return;
}
nodeprintf(conn, "Next message number was %d, now %d\r", LatestMsg, newNumber);
SendPrompt(conn, user);
LatestMsg = newNumber;
SaveMessageDatabase();
}
VOID DoExportCmd(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
int msgno;
char * FN;
FILE * Handle = NULL;
struct MsgInfo * Msg;
if (conn->sysop == 0)
{
nodeprintf(conn, "EXPORT command needs SYSOP status\r");
SendPrompt(conn, user);
return;
}
if (Arg1 == 0 || _stricmp(Arg1, "HELP") == 0)
{
nodeprintf(conn, "EXPORT nnn FILENAME - Export Message nnn to file FILENAME\r");
SendPrompt(conn, user);
return;
}
msgno = atoi(Arg1);
FN = strtok_s(NULL, " \r", &Context);
if (FN == NULL)
{
nodeprintf(conn, "Missong Filename");
SendPrompt(conn, user);
return;
}
Msg = GetMsgFromNumber(msgno);
if (Msg == NULL)
{
nodeprintf(conn, "Message %d not found\r", msgno);
SendPrompt(conn, user);
return;
}
conn->BBSFlags |= BBS;
Handle = fopen(FN, "ab");
if (Handle == NULL)
{
nodeprintf(conn, "File %s could not be opened\r", FN);
SendPrompt(conn, user);
return;
}
// SetFilePointer(Handle, 0, 0, FILE_END);
ForwardMessagetoFile(Msg, Handle);
fclose(Handle);
nodeprintf(conn, "%Message %d Exported\r", msgno);
SendPrompt(conn, user);
return;
}
VOID DoImportCmd(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
int count;
if (conn->sysop == 0)
{
nodeprintf(conn, "IMPORT command needs SYSOP status\r");
SendPrompt(conn, user);
return;
}
if (Arg1 == 0 || _stricmp(Arg1, "HELP") == 0)
{
nodeprintf(conn, "IMPORT FILENAME - Import Messages from file FILENAME\r");
SendPrompt(conn, user);
return;
}
conn->BBSFlags |= BBS;
count = ImportMessages(conn, Arg1, TRUE);
conn->BBSFlags &= ~BBS;
conn->Flags = 0;
nodeprintf(conn, "%d Messages Processed\r", count);
SendPrompt(conn, user);
return;
}
VOID DoFwdCmd(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
char Line[200];
struct UserInfo * FwdBBS;
struct BBSForwardingInfo * ForwardingInfo;
if (conn->sysop == 0)
{
nodeprintf(conn, "FWD command needs SYSOP status\r");
SendPrompt(conn, user);
return;
}
if (Arg1 == 0 || _stricmp(Arg1, "HELP") == 0)
{
nodeprintf(conn, "FWD BBSCALL - Display settings\r");
nodeprintf(conn, "FWD BBSCALL interval - Set forwarding interval\r");
nodeprintf(conn, "FWD BBSCALL REV interval - Set reverse forwarding interval\r");
nodeprintf(conn, "FWD BBSCALL +- Flags (Flags are EN(able) RE(verse Poll) SE(Send Immediately)\r");
nodeprintf(conn, "FWD BBSCALL NOW - Start a forwarding cycle now\r");
nodeprintf(conn, "FWD QUEUE - List BBS's with queued messages\r");
nodeprintf(conn, "FWD NOW can specify a Connect Script to use, overriding the configured script.\r");
nodeprintf(conn, "Elements are separated by | chars. eg FWD RMS NOW ATT 7|C GM8BPQ-10\r");
SendPrompt(conn, user);
return;
}
if (_stricmp(Arg1, "QUEUE") == 0)
{
struct UserInfo * xuser;
int Msgs;
if (Context && Context[0])
{
// a bbs name - list all messages queued to it
strlop(Context, '\r');
xuser = FindBBS(_strupr(Context));
if (xuser)
{
ListMessagestoForward(conn, xuser);
SendPrompt(conn, user);
return;
}
}
for (xuser = BBSChain; xuser; xuser = xuser->BBSNext)
{
Msgs = CountMessagestoForward(xuser);
if (Msgs)
nodeprintf(conn, "%s %d Msgs\r", xuser->Call, Msgs);
}
SendPrompt(conn, user);
return;
}
FwdBBS = LookupCall(Arg1);
if (FwdBBS == 0 || (FwdBBS->flags & F_BBS) == 0)
{
nodeprintf(conn, "BBS %s not found\r", Arg1);
SendPrompt(conn, user);
return;
}
ForwardingInfo = FwdBBS->ForwardingInfo;
Arg1 = strtok_s(NULL, seps, &Context);
if (Arg1 == NULL)
goto FDisplay;
if (_stricmp(Arg1, "NOW") == 0)
{
char ** Value = NULL;
if (ForwardingInfo->Forwarding)
{
BBSputs(conn, "Already Connected\r");
SendPrompt(conn, user);
return;
}
while (Context[0] == ' ')
Context++;
if (Context)
strlop(Context, 13);
if (Context && Context[0])
{
// Temp Connect Script to use
char * ptr1;
char * MultiString = NULL;
const char * ptr;
int Count = 0;
Value = zalloc(sizeof(void *)); // always NULL entry on end even if no values
Value[0] = NULL;
ptr = Context;
while (ptr && strlen(ptr))
{
ptr1 = strchr(ptr, '|');
if (ptr1)
*(ptr1++) = 0;
Value = realloc(Value, (Count+2) * sizeof(void *));
Value[Count++] = _strdup(ptr);
ptr = ptr1;
}
Value[Count] = NULL;
}
StartForwarding(FwdBBS->BBSNumber, Value);
if (ForwardingInfo->Forwarding)
nodeprintf(conn, "Forwarding Started\r");
else
nodeprintf(conn, "Start Forwarding failed\r");
SendPrompt(conn, user);
return;
}
if (_stricmp(Arg1, "REV") == 0)
{
Arg1 = strtok_s(NULL, seps, &Context);
ForwardingInfo->RevFwdInterval = atoi(Arg1);
}
else
{
while(Arg1)
{
_strupr(Arg1);
if (isdigits(Arg1))
ForwardingInfo->FwdInterval = atoi(Arg1);
else if (strstr(Arg1, "EN"))
if (Arg1[0] == '-') ForwardingInfo->Enabled = FALSE; else ForwardingInfo->Enabled = TRUE;
else if (strstr(Arg1, "RE"))
if (Arg1[0] == '-') ForwardingInfo->ReverseFlag = FALSE; else ForwardingInfo->ReverseFlag = TRUE;
else if (strstr(Arg1, "SE"))
if (Arg1[0] == '-') ForwardingInfo->SendNew = FALSE; else ForwardingInfo->SendNew = TRUE;
Arg1 = strtok_s(NULL, seps, &Context);
}
}
SaveConfig(ConfigName);
GetConfig(ConfigName);
FDisplay:
sprintf(Line, "%s Fwd Interval %d Rev Interval %d Fwd %s, Reverse Poll %s, Send Immediately %s\r",
FwdBBS->Call, ForwardingInfo->FwdInterval, ForwardingInfo->RevFwdInterval,
(ForwardingInfo->Enabled)? "Enabled" : "Disabled", (ForwardingInfo->ReverseFlag) ? "Enabled": "Disabled",
(ForwardingInfo->SendNew) ? "Enabled": "Disabled");
nodeprintf(conn, Line);
SendPrompt(conn, user);
return;
}
void DoHousekeepingCmd(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
if (conn->sysop == 0)
{
nodeprintf(conn, "DOHOUSEKEEPING command needs SYSOP status\r");
SendPrompt(conn, user);
return;
}
DoHouseKeeping(FALSE);
nodeprintf(conn, "Ok\r", Arg1);
SendPrompt(conn, user);
}

224
MailDataDefs.c Normal file
View File

@ -0,0 +1,224 @@
/*
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
*/
#include "bpqmail.h"
int LastVer[4] = {0, 0, 0, 0}; // In case we need to do somthing the first time a version is run
HWND MainWnd;
HWND hWndSess;
RECT MainRect;
HMENU hActionMenu;
static HMENU hMenu;
HMENU hDisMenu; // Disconnect Menu Handle
HMENU hFWDMenu; // Forward Menu Handle
int SessX, SessY, SessWidth; // Params for Session Window
char szBuff[80];
#define MaxSockets 64
ConnectionInfo Connections[MaxSockets+1];
struct SEM ChatSemaphore = {0, 0};
struct SEM AllocSemaphore = {0, 0};
struct SEM ConSemaphore = {0, 0};
struct SEM Semaphore = {0, 0};
struct SEM OutputSEM = {0, 0};
struct SEM ConfigSEM = {0, 0};
struct UserInfo ** UserRecPtr=NULL;
int NumberofUsers=0;
struct UserInfo * BBSChain = NULL; // Chain of users that are BBSes
struct MsgInfo ** MsgHddrPtr=NULL;
int NumberofMessages=0;
int FirstMessageIndextoForward = 0; // Lowest Message with a forward bit set - limits search
BIDRec ** BIDRecPtr=NULL;
int NumberofBIDs=0;
BIDRec ** TempBIDRecPtr=NULL;
int NumberofTempBIDs=0;
WPRec ** WPRecPtr=NULL;
int NumberofWPrecs=0;
char ** BadWords=NULL;
int NumberofBadWords=0;
char * BadFile = NULL;
int LatestMsg = 0;
struct SEM MsgNoSemaphore = {0, 0}; // For locking updates to LatestMsg
int HighestBBSNumber = 0;
int MaxMsgno = 60000;
int BidLifetime = 60;
int MaxAge = 30;
int MaintInterval = 24;
int MaintTime = 0;
int UserLifetime = 0;
BOOL cfgMinToTray;
BOOL DisconnectOnClose=FALSE;
char PasswordMsg[100]="Password:";
char cfgHOSTPROMPT[100];
char cfgCTEXT[100];
char cfgLOCALECHO[100];
char AttemptsMsg[] = "Too many attempts - Disconnected\r\r";
char disMsg[] = "Disconnected by SYSOP\r\r";
char LoginMsg[]="user:";
char BlankCall[]=" ";
ULONG BBSApplMask;
ULONG ChatApplMask;
int BBSApplNum=0;
int ChatApplNum=0;
//int StartStream=0;
int NumberofStreams=0;
int MaxStreams=0;
char BBSSID[]="[%s%d.%d.%d.%d-%s%s%s%sIH%sM$]\r";
char ChatSID[]="[BPQChatServer-%d.%d.%d.%d]\r";
char NewUserPrompt[100]="Please enter your Name\r>\r";
char * WelcomeMsg = NULL;
char * NewWelcomeMsg = NULL;
char * ExpertWelcomeMsg = NULL;
char * Prompt = NULL;
char * NewPrompt = NULL;
char * ExpertPrompt = NULL;
char BBSName[100] = "NOCALL";
char SYSOPCall[50];
char MailForText[100];
char HRoute[100];
char AMPRDomain[100];
BOOL SendAMPRDirect = 0;
char SignoffMsg[100];
char AbortedMsg[100]="\rOutput aborted\r";
char UserDatabaseName[MAX_PATH] = "BPQBBSUsers.dat";
char UserDatabasePath[MAX_PATH];
char MsgDatabasePath[MAX_PATH];
char MsgDatabaseName[MAX_PATH] = "DIRMES.SYS";
char BIDDatabasePath[MAX_PATH];
char BIDDatabaseName[MAX_PATH] = "WFBID.SYS";
char WPDatabasePath[MAX_PATH];
char WPDatabaseName[MAX_PATH] = "WP.SYS";
char BadWordsPath[MAX_PATH];
char BadWordsName[MAX_PATH] = "BADWORDS.SYS";
char NTSAliasesPath[MAX_PATH];
char NTSAliasesName[MAX_PATH] = "INTRCPT.APS";
char ConfigName[250];
char ChatConfigName[250];
BOOL UsingingRegConfig = FALSE;
BOOL MulticastRX = FALSE;
char BaseDir[MAX_PATH];
char BaseDirRaw[MAX_PATH]; // As set in registry - may contain %NAME%
char ProperBaseDir[MAX_PATH]; // BPQ Directory/BPQMailChat
char MailDir[MAX_PATH];
char RlineVer[50];
BOOL KISSOnly = FALSE;
BOOL EnableUI = FALSE;
BOOL RefuseBulls = FALSE;
BOOL SendSYStoSYSOPCall = FALSE;
BOOL SendBBStoSYSOPCall = FALSE;
BOOL DontHoldNewUsers = FALSE;
BOOL DefaultNoWINLINK = FALSE;
BOOL ForwardToMe = FALSE;
BOOL OnlyKnown = FALSE;
BOOL DontNeedHomeBBS = FALSE;
BOOL DontCheckFromCall = FALSE;
// Send WP Params
BOOL SendWP;
BOOL FilterWPBulls;
BOOL NoWPGuesses;
char SendWPVIA[81];
char SendWPTO[11];
char ** SendWPAddrs; // Replaces WP To and VIA
int SendWPType;
int SMTPMsgs;
int MailForInterval = 0;
char zeros[NBMASK]; // For forward bitmask tests
time_t MaintClock; // Time to run housekeeping
time_t APIClock; // Time to sent to MOLTE's Database
struct MsgInfo * MsgnotoMsg[100000]; // Message Number to Message Slot List.
// Filter Params
char ** RejFrom; // Reject on FROM Call
char ** RejTo; // Reject on TO Call
char ** RejAt; // Reject on AT Call
char ** RejBID; // Reject on BID
char ** HoldFrom; // Hold on FROM Call
char ** HoldTo; // Hold on TO Call
char ** HoldAt; // Hold on AT Call
char ** HoldBID; // Hold on BID
struct ConsoleInfo * ConsHeader[2];

2099
MailRouting.c Normal file

File diff suppressed because it is too large Load Diff

4139
MailTCP.c Normal file

File diff suppressed because it is too large Load Diff

961
Moncode.c Normal file
View File

@ -0,0 +1,961 @@
/*
Copyright 2001-2022 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
*/
// Monitor Code - from moncode.asm
#pragma data_seg("_BPQDATA")
#define _CRT_SECURE_NO_DEPRECATE
#include <stdlib.h>
#include <string.h>
#include <time.h>
#pragma data_seg("_BPQDATA")
#include "CHeaders.h"
#include "tncinfo.h"
// MSGFLAG contains CMD/RESPONSE BITS
#define CMDBIT 4 // CURRENT MESSAGE IS A COMMAND
#define RESP 2 // CURRENT MSG IS RESPONSE
#define VER1 1 // CURRENT MSG IS VERSION 1
#define UI 3
#define SABM 0x2F
#define DISC 0x43
#define DM 0x0F
#define UA 0x63
#define FRMR 0x87
#define RR 1
#define RNR 5
#define REJ 9
#define PFBIT 0x10 // POLL/FINAL BIT IN CONTROL BYTE
#define NETROM_PID 0xCF
#define IP_PID 0xCC
#define ARP_PID 0xCD
#define NODES_SIG 0xFF
UCHAR * DisplayINP3RIF(UCHAR * ptr1, UCHAR * ptr2, unsigned int msglen);
char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen);
UCHAR * DISPLAYIPDATAGRAM(IPMSG * IP, UCHAR * Output, int MsgLen);
char * DISPLAYARPDATAGRAM(UCHAR * Datagram, UCHAR * Output);
DllExport int APIENTRY SetTraceOptions(int mask, int mtxparam, int mcomparam)
{
// Sets the tracing options for DecodeFrame. Mask is a bit
// mask of ports to monitor (ie 101 binary will monitor ports
// 1 and 3). MTX enables monitoring on transmitted frames. MCOM
// enables monitoring of protocol control frames (eg SABM, UA, RR),
// as well as info frames.
// *** For external use only, supports portnum up to 31 ***
MMASK = mask;
MTX = mtxparam;
MCOM = mcomparam;
return (0);
}
DllExport int APIENTRY SetTraceOptions64(uint64_t mask, int mtxparam, int mcomparam, int monUIOnly)
{
// Sets the tracing options for DecodeFrame. Mask is a bit
// mask of ports to monitor (ie 101 binary will monitor ports
// 1 and 3). MTX enables monitoring on transmitted frames. MCOM
// enables monitoring of protocol control frames (eg SABM, UA, RR),
// as well as info frames.
// *** For external use only, supports portnum up to 63 ***
MMASK = mask;
MTX = mtxparam;
MCOM = mcomparam;
MUIONLY = monUIOnly;
return (0);
}
DllExport int APIENTRY SetTraceOptionsEx(int mask, int mtxparam, int mcomparam, int monUIOnly)
{
// *** For external use only, supports portnum up to 31 ***
// Sets the tracing options for DecodeFrame. Mask is a bit
// mask of ports to monitor (ie 101 binary will monitor ports
// 1 and 3). MTX enables monitoring on transmitted frames. MCOM
// enables monitoring of protocol control frames (eg SABM, UA, RR),
// as well as info frames.
MMASK = mask;
MTX = mtxparam;
MCOM = mcomparam;
MUIONLY = monUIOnly;
return 0;
}
int IntSetTraceOptionsEx(uint64_t mask, int mtxparam, int mcomparam, int monUIOnly)
{
// Sets the tracing options for DecodeFrame. Mask is a bit
// mask of ports to monitor (ie 101 binary will monitor ports
// 1 and 3). MTX enables monitoring on transmitted frames. MCOM
// enables monitoring of protocol control frames (eg SABM, UA, RR),
// as well as info frames.
MMASK = mask;
MTX = mtxparam;
MCOM = mcomparam;
MUIONLY = monUIOnly;
return 0;
}
int APRSDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, uint64_t Mask)
{
return IntDecodeFrame(msg, buffer, Stamp, Mask, TRUE, FALSE);
}
DllExport int APIENTRY DecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp)
{
return IntDecodeFrame(msg, buffer, Stamp, MMASK, FALSE, FALSE);
}
int IntDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, uint64_t Mask, BOOL APRS, BOOL MINI)
{
UCHAR * ptr;
int n;
MESSAGE * ADJBUFFER;
ptrdiff_t Work;
UCHAR CTL;
BOOL PF = 0;
char CRCHAR[3] = " ";
char PFCHAR[3] = " ";
int Port;
int MSGFLAG = 0; //CR and V1 flags
char * Output = buffer;
char TR = 'R';
char From[10], To[10];
BOOL Info = 0;
BOOL FRMRFLAG = 0;
BOOL XIDFLAG = 0;
BOOL TESTFLAG = 0;
size_t MsgLen = msg->LENGTH;
// Use gmtime so we can also display in local time
struct tm * TM;
if (MTX & 0x80)
TM = localtime(&Stamp);
else
TM = gmtime(&Stamp);
// MINI mode is for Node Listen (remote monitor) Mode. Keep info to minimum
/*
KO6IZ*>K7TMG-1:
/ex
KO6IZ*>K7TMG-1:
b
KO6IZ*>K7TMG-1 (UA)
W0TX*>KC6OAR>KB9KC>ID:
W0TX/R DRC/D W0TX-2/G W0TX-1/B W0TX-7/N
KC6OAR*>ID:
*/
// Check Port
Port = msg->PORT;
if (Port == 40)
Port = Port;
if (Port & 0x80)
{
if ((MTX & 1) == 0)
return 0; // TRANSMITTED FRAME - SEE IF MTX ON
TR = 'T';
}
Port &= 0x7F;
if ((((uint64_t)1 << (Port - 1)) & Mask) == 0) // Check MMASK
{
if (msg->Padding[0] == '[')
msg->Padding[0] = 0;
return 0;
}
// We now pass Text format monitoring from non-ax25 drivers through this code
// As a valid ax.25 address must have bottom bit set flag plain text messages
// with hex 01.
// GET THE CONTROL BYTE, TO SEE IF THIS FRAME IS TO BE DISPLAYED
if (msg->DEST[0] == 1)
{
// Just copy text (Null Terminated) to output
// Need Timestamp and T/R
// Add Port: unless Mail Mon (port 64)
Output += sprintf((char *)Output, "%02d:%02d:%02d%c ", TM->tm_hour, TM->tm_min, TM->tm_sec, TR);
strcpy(Output, &msg->DEST[1]);
Output += strlen(Output);
if (buffer[strlen(buffer) -1] == '\r')
Output--;
if (Port == 64)
Output += sprintf((char *)Output, " \r");
else
Output += sprintf((char *)Output, " Port=%d\r", Port);
return (int)strlen(buffer);
}
n = 8; // MAX DIGIS
ptr = &msg->ORIGIN[6]; // End of Address bit
while ((*ptr & 1) == 0)
{
// MORE TO COME
ptr += 7;
n--;
if (n < 0)
return 0; // Corrupt - no end of address bit
}
// Reached End of digis
Work = ptr - &msg->ORIGIN[6]; // Work is length of digis
MsgLen -= Work;
ADJBUFFER = (MESSAGE *)((UCHAR *)msg + Work); // ADJBUFFER points to CTL, etc. allowing for digis
CTL = ADJBUFFER->CTL;
if (CTL & PFBIT)
PF = TRUE;
CTL &= ~PFBIT;
if (MUIONLY)
if (CTL != 3)
return 0;
if ((CTL & 1) == 0 || CTL == FRMR || CTL == 3)
{
}
else
{
if (((CTL & 2) && MINI) == 0) // Want Control (but not super unless MCOM
if (MCOM == 0)
return 0; // Dont do control
}
// Add Port: if MINI mode and monitoring more than one port
if (MINI == 0)
Output += sprintf((char *)Output, "%02d:%02d:%02d%c ", TM->tm_hour, TM->tm_min, TM->tm_sec, TR);
else
if (CountBits64(Mask) > 1)
Output += sprintf((char *)Output, "%d:", Port);
From[ConvFromAX25(msg->ORIGIN, From)] = 0;
To[ConvFromAX25(msg->DEST, To)] = 0;
Output += sprintf((char *)Output, "%s>%s", From, To);
// Display any Digi-Peaters
n = 8; // Max number of digi-peaters
ptr = &msg->ORIGIN[6]; // End of Address bit
while ((*ptr & 1) == 0)
{
// MORE TO COME
From[ConvFromAX25(ptr + 1, From)] = 0;
Output += sprintf((char *)Output, ",%s", From);
ptr += 7;
n--;
if (n == 0)
break;
// See if digi actioned - put a * on last actioned
if (*ptr & 0x80)
{
if (*ptr & 1) // if last address, must need *
*(Output++) = '*';
else
if ((ptr[7] & 0x80) == 0) // Repeased by next?
*(Output++) = '*'; // No, so need *
}
}
if (MINI == 0)
Output += sprintf((char *)Output, " Port=%d ", Port);
// Set up CR and PF
CRCHAR[0] = 0;
PFCHAR[0] = 0;
if (msg->DEST[6] & 0x80)
{
if (msg->ORIGIN[6] & 0x80) // Both set, assume V1
MSGFLAG |= VER1;
else
{
MSGFLAG |= CMDBIT;
CRCHAR[0] = ' ';
CRCHAR[1] = 'C';
if (PF) // If FP set
{
PFCHAR[0] = ' ';
PFCHAR[1] = 'P';
}
}
}
else
{
if (msg->ORIGIN[6] & 0x80) // Only Origin Set
{
MSGFLAG |= RESP;
CRCHAR[0] = ' ';
CRCHAR[1] = 'R';
if (PF) // If FP set
{
PFCHAR[0] = ' ';
PFCHAR[1] = 'F';
}
}
else
MSGFLAG |= VER1; // Neither, assume V1
}
if ((CTL & 1) == 0) // I frame
{
int NS = (CTL >> 1) & 7; // ISOLATE RECEIVED N(S)
int NR = (CTL >> 5) & 7;
Info = 1;
if (MINI == 0)
Output += sprintf((char *)Output, "<I%s%s S%d R%d>", CRCHAR, PFCHAR, NS, NR);
}
else if (CTL == 3)
{
// Un-numbered Information Frame
Output += sprintf((char *)Output, "<UI%s>", CRCHAR);
Info = 1;
}
else if (CTL & 2)
{
// UN Numbered
char SUP[6] = "??";
switch (CTL)
{
case SABM:
strcpy(SUP, "C");
break;
case SABME:
strcpy(SUP, "SABME");
break;
case XID:
strcpy(SUP, "XID");
XIDFLAG = 1;
break;
case TEST:
strcpy(SUP, "TEST");
TESTFLAG = 1;
break;
case DISC:
strcpy(SUP, "D");
break;
case DM:
strcpy(SUP, "DM");
break;
case UA:
strcpy(SUP, "UA");
break;
case FRMR:
strcpy(SUP, "FRMR");
FRMRFLAG = 1;
break;
}
if (MINI)
Output += sprintf((char *)Output, "<%s>", SUP);
else
Output += sprintf((char *)Output, "<%s%s%s>", SUP, CRCHAR, PFCHAR);
}
else
{
// Super
int NR = (CTL >> 5) & 7;
char SUP[5] = "??";
switch (CTL & 0x0F)
{
case RR:
strcpy(SUP, "RR");
break;
case RNR:
strcpy(SUP, "RNR");
break;
case REJ:
strcpy(SUP, "REJ");
break;
case SREJ:
strcpy(SUP, "SREJ");
break;
}
Output += sprintf((char *)Output, "<%s%s%s R%d>", SUP, CRCHAR, PFCHAR, NR);
}
if (FRMRFLAG)
Output += sprintf((char *)Output, " %02X %02X %02X", ADJBUFFER->PID, ADJBUFFER->L2DATA[0], ADJBUFFER->L2DATA[1]);
if (XIDFLAG)
{
// Decode and display XID
UCHAR * ptr = &ADJBUFFER->PID;
if (*ptr++ == 0x82 && *ptr++ == 0x80)
{
int Type;
int Len;
unsigned int value;
int xidlen = *(ptr++) << 8;
xidlen += *ptr++;
// XID is set of Type, Len, Value n-tuples
// G8BPQ-2>G8BPQ:(XID cmd, p=1) Half-Duplex SREJ modulo-128 I-Field-Length-Rx=256 Window-Size-Rx=32 Ack-Timer=3000 Retries=10
while (xidlen > 0)
{
Type = *ptr++;
Len = *ptr++;
value = 0;
xidlen -= (Len + 2);
while (Len--)
{
value <<=8;
value += *ptr++;
}
switch(Type)
{
case 2: //Bin fields
case 3:
Output += sprintf((char *)Output, " %d=%x", Type, value);
break;
case 6: //RX Size
Output += sprintf((char *)Output, " RX Paclen=%d", value / 8);
break;
case 8: //RX Window
Output += sprintf((char *)Output, " RX Window=%d", value);
break;
}
}
}
}
if (msg->Padding[0] == '[')
Output += sprintf((char *)Output, " %s", msg->Padding);
msg->Padding[0] = 0;
if (Info)
{
// We have an info frame
switch (ADJBUFFER->PID)
{
case 0xF0: // Normal Data
{
char Infofield[257];
char * ptr1 = Infofield;
char * ptr2 = ADJBUFFER->L2DATA;
UCHAR C;
size_t len;
MsgLen = MsgLen - (19 + sizeof(void *));
if (MsgLen < 0 || MsgLen > 257)
return 0; // Duff
while (MsgLen--)
{
C = *(ptr2++);
if (APRS)
*(ptr1++) = C; // MIC-E needs all chars
else
{
// Convert to printable
C &= 0x7F;
if (C == 13 || C == 10 || C > 31)
*(ptr1++) = C;
}
}
len = ptr1 - Infofield;
Output[0] = ':';
Output[1] = 13;
memcpy(&Output[2], Infofield, len);
Output += (len + 2);
break;
}
case NETROM_PID:
Output = DISPLAY_NETROM(ADJBUFFER, Output, (int)MsgLen);
break;
case IP_PID:
Output += sprintf((char *)Output, " <IP>\r");
Output = DISPLAYIPDATAGRAM((IPMSG *)&ADJBUFFER->L2DATA[0], Output, (int)MsgLen);
break;
case ARP_PID:
Output = DISPLAYARPDATAGRAM(&ADJBUFFER->L2DATA[0], Output);
break;
case 8: // Fragmented IP
n = ADJBUFFER->L2DATA[0]; // Frag Count
Output += sprintf((char *)Output, "<Fragmented IP %02x>\r", n);
if (ADJBUFFER->L2DATA[0] & 0x80) // First Frag - Display Header
{
Output = DISPLAYIPDATAGRAM((IPMSG *)&ADJBUFFER->L2DATA[2], Output, (int)MsgLen - 1);
}
break;
}
}
if (Output[-1] != 13)
Output += sprintf((char *)Output, "\r");
return (int)(Output - buffer);
}
// Display NET/ROM data
char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen)
{
char Alias[7]= "";
char Dest[10];
char Node[10];
UCHAR TTL, Index, ID, TXNO, RXNO, OpCode, Flags, Window;
UCHAR * ptr = &ADJBUFFER->L2DATA[0];
if (ADJBUFFER->L2DATA[0] == NODES_SIG)
{
// Display NODES
// If an INP3 RIF (type <> UI) decode as such
if (ADJBUFFER->CTL != 3) // UI
return DisplayINP3RIF(&ADJBUFFER->L2DATA[1], Output, MsgLen - (MSGHDDRLEN + 14 + 3));
memcpy(Alias, ++ptr, 6);
ptr += 6;
Output += sprintf((char *)Output, " NODES broadcast from %s\r", Alias);
MsgLen -= 30; //Header, mnemonic and signature length
while(MsgLen > 20) // Entries are 21 bytes
{
Dest[ConvFromAX25(ptr, Dest)] = 0;
ptr +=7;
memcpy(Alias, ptr, 6);
ptr +=6;
strlop(Alias, ' ');
Node[ConvFromAX25(ptr, Node)] = 0;
ptr +=7;
Output += sprintf((char *)Output, " %s:%s via %s qlty=%d\r", Alias, Dest, Node, ptr[0]);
ptr++;
MsgLen -= 21;
}
return Output;
}
// Display normal NET/ROM transmissions
Output += sprintf((char *)Output, " NET/ROM\r ");
Dest[ConvFromAX25(ptr, Dest)] = 0;
ptr +=7;
Node[ConvFromAX25(ptr, Node)] = 0;
ptr +=7;
TTL = *(ptr++);
Index = *(ptr++);
ID = *(ptr++);
TXNO = *(ptr++);
RXNO = *(ptr++);
OpCode = Flags = *(ptr++);
OpCode &= 15; // Remove Flags
Output += sprintf((char *)Output, "%s to %s ttl %d cct=%02X%02X ", Dest, Node, TTL, Index, ID );
MsgLen -= 20;
switch (OpCode)
{
case L4CREQ:
Window = *(ptr++);
Dest[ConvFromAX25(ptr, Dest)] = 0;
ptr +=7;
Node[ConvFromAX25(ptr, Node)] = 0;
ptr +=7;
Output += sprintf((char *)Output, "<CON REQ> w=%d %s at %s", Window, Dest, Node);
if (MsgLen > 38) // BPQ Extended Params
{
short Timeout = (SHORT)*ptr;
Output += sprintf((char *)Output, " t/o %d", Timeout);
}
return Output;
case L4CACK:
if (Flags & L4BUSY) // BUSY RETURNED
return Output + sprintf((char *)Output, " <CON NAK> - BUSY");
return Output + sprintf((char *)Output, " <CON ACK> w=%d my cct=%02X%02X", ptr[1], TXNO, RXNO);
case L4DREQ:
return Output + sprintf((char *)Output, " <DISC REQ>");
case L4DACK:
return Output + sprintf((char *)Output, " <DISC ACK>");
case L4INFO:
{
char Infofield[257];
char * ptr1 = Infofield;
UCHAR C;
size_t len;
Output += sprintf((char *)Output, " <INFO S%d R%d>", TXNO, RXNO);
if (Flags & L4BUSY)
*(Output++) = 'B';
if (Flags & L4NAK)
*(Output++) = 'N';
if (Flags & L4MORE)
*(Output++) = 'M';
MsgLen = MsgLen - (19 + sizeof(void *));
if (MsgLen < 0 || MsgLen > 257)
return Output; // Duff
while (MsgLen--)
{
C = *(ptr++);
// Convert to printable
C &= 0x7F;
if (C == 13 || C == 10 || C > 31)
*(ptr1++) = C;
}
len = ptr1 - Infofield;
Output[0] = ':';
Output[1] = 13;
memcpy(&Output[2], Infofield, len);
Output += (len + 2);
}
return Output;
case L4IACK:
Output += sprintf((char *)Output, " <INFO ACK R%d> ", RXNO);
if (Flags & L4BUSY)
*(Output++) = 'B';
if (Flags & L4NAK)
*(Output++) = 'N';
if (Flags & L4MORE)
*(Output++) = 'M';
return Output;
case 0:
// OPcode zero is used for several things
if (Index == 0x0c && ID == 0x0c) // IP
{
*(Output++) = 13;
*(Output++) = ' ';
Output = DISPLAYIPDATAGRAM((IPMSG *)ptr, Output, MsgLen);
return Output;
}
if (Index == 0 && ID == 1) // NRR
{
Output += sprintf((char *)Output, " <Record Route>\r");
MsgLen -= 23;
while (MsgLen > 6)
{
Dest[ConvFromAX25(ptr, Dest)] = 0;
if (ptr[7] & 0x80)
Output += sprintf((char *)Output, "%s* ", Dest);
else
Output += sprintf((char *)Output, "%s ", Dest);
ptr +=8;
MsgLen -= 8;
}
return Output;
}
}
Output += sprintf((char *)Output, " <???\?>");
return Output;
}
/*
PUBLIC L3IP
L3IP:
;
; TCP/IP DATAGRAM
;
mov EBX,OFFSET IP_MSG
call NORMSTR
;
INC ESI ; NOW POINTING TO IP HEADER
*/
UCHAR * DISPLAYIPDATAGRAM(IPMSG * IP, UCHAR * Output, int MsgLen)
{
UCHAR * ptr;
USHORT FRAGWORD;
ptr = (UCHAR *)&IP->IPSOURCE;
Output += sprintf((char *)Output, "%d.%d.%d.%d>", ptr[0], ptr[1], ptr[2], ptr[3]);
ptr = (UCHAR *)&IP->IPDEST;
Output += sprintf((char *)Output, "%d.%d.%d.%d LEN:%d ", ptr[0], ptr[1], ptr[2], ptr[3], htons(IP->IPLENGTH));
FRAGWORD = ntohs(IP->FRAGWORD);
if (FRAGWORD)
{
// If nonzero, check which bits are set
//Bit 0: reserved, must be zero
//Bit 1: (DF) 0 = May Fragment, 1 = Don't Fragment.
//Bit 2: (MF) 0 = Last Fragment, 1 = More Fragments.
//Fragment Offset: 13 bits
if (FRAGWORD & (1 << 14))
Output += sprintf((char *)Output, "DF ");
if (FRAGWORD & (1 << 13))
Output += sprintf((char *)Output, "MF ");
FRAGWORD &= 0xfff;
if (FRAGWORD)
{
Output += sprintf((char *)Output, "Offset %d ", FRAGWORD * 8);
return Output; // Cant display proto fields
}
}
if (IP->IPPROTOCOL == 6)
{
PTCPMSG TCP = (PTCPMSG)&IP->Data;
Output += sprintf((char *)Output, "TCP Src %d Dest %d ", ntohs(TCP->SOURCEPORT), ntohs(TCP->DESTPORT));
return Output;
}
if (IP->IPPROTOCOL == 1)
{
PICMPMSG ICMPptr = (PICMPMSG)&IP->Data;
Output += sprintf((char *)Output, "ICMP ");
if (ICMPptr->ICMPTYPE == 8)
Output += sprintf((char *)Output, "Echo Request ");
else
if (ICMPptr->ICMPTYPE == 0)
Output += sprintf((char *)Output, "Echo Reply ");
else
Output += sprintf((char *)Output, "Code %d", ICMPptr->ICMPTYPE);
return Output;
}
/*
MOV AL,IPPROTOCOL[ESI]
CMP AL,6
JNE @F
MOV EBX, OFFSET TCP
CALL NORMSTR
JMP ADD_CR
@@:
CMP AL,1
JNE @F
MOV EBX, OFFSET ICMP
CALL NORMSTR
JMP ADD_CR
@@:
CALL DISPLAY_BYTE_1 ; DISPLAY PROTOCOL TYPE
; mov AL,CR
; call PUTCHAR
;
; MOV ECX,39 ; TESTING
;IPLOOP:
; lodsb
; CALL BYTE_TO_HEX
;
; LOOP IPLOOP
JMP ADD_CR
*/
return Output;
}
char * DISPLAYARPDATAGRAM(UCHAR * Datagram, UCHAR * Output)
{
UCHAR * ptr = Datagram;
char Dest[10];
if (ptr[7] == 1) // Request
return Output + sprintf((char *)Output, " ARP Request who has %d.%d.%d.%d? Tell %d.%d.%d.%d",
ptr[26], ptr[27], ptr[28], ptr[29], ptr[15], ptr[16], ptr[17], ptr[18]);
// Response
Dest[ConvFromAX25(&ptr[8], Dest)] = 0;
return Output + sprintf((char *)Output, " ARP Reply %d.%d.%d.%d is at %s Tell %d.%d.%d.%d",
ptr[15], ptr[16], ptr[17], ptr[18], Dest, ptr[26], ptr[27], ptr[28], ptr[29]);
}

424
Monitor.c Normal file
View File

@ -0,0 +1,424 @@
// Mail and Chat Server for BPQ32 Packet Switch
//
// Monitor Window(s) Module
#include "bpqmail.h"
static char ClassName[]="BPQMONWINDOW";
char SYSOPCall[50];
static WNDPROC wpOrigInputProc;
static WNDPROC wpOrigOutputProc;
HWND hMonitor;
static HWND hwndInput;
static HWND hwndOutput;
static HMENU hMenu; // handle of menu
#define InputBoxHeight 25
RECT MonitorRect;
RECT OutputRect;
int Height, Width, LastY;
static char kbbuf[160];
static int kbptr=0;
static char * readbuff;
static int readbufflen;
static BOOL StripLF = TRUE;
BOOL MonBBS = TRUE;
BOOL MonCHAT = TRUE;
BOOL MonTCP = TRUE;
BOOL LogBBS = TRUE;
BOOL LogCHAT = TRUE;
BOOL LogTCP = TRUE;
static int PartLinePtr=0;
static int PartLineIndex=0; // Listbox index of (last) incomplete line
static LRESULT CALLBACK MonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static LRESULT APIENTRY InputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static LRESULT APIENTRY OutputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static LRESULT APIENTRY MonProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static void MoveWindows();
static void MoveMCWindows();
#define BGCOLOUR RGB(236,233,216)
BOOL CreateMonitor()
{
WNDCLASS wc;
HBRUSH bgBrush;
if (hMonitor)
{
ShowWindow(hMonitor, SW_SHOWNORMAL);
SetForegroundWindow(hMonitor);
return FALSE; // Alreaqy open
}
bgBrush = CreateSolidBrush(BGCOLOUR);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MonWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInst;
wc.hIcon = LoadIcon( hInst, MAKEINTRESOURCE(BPQICON) );
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = bgBrush;
wc.lpszMenuName = NULL;
wc.lpszClassName = ClassName;
RegisterClass(&wc);
hMonitor=CreateDialog(hInst,ClassName,0,NULL);
if (!hMonitor)
return (FALSE);
readbuff = zalloc(1000);
readbufflen = 1000;
hMenu=GetMenu(hMonitor);
CheckMenuItem(hMenu,MONBBS, MonBBS ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hMenu,MONCHAT, MonCHAT ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hMenu,MONTCP, MonTCP ? MF_CHECKED : MF_UNCHECKED);
DrawMenuBar(hWnd);
// Retrieve the handlse to the edit controls.
hwndOutput = GetDlgItem(hMonitor, 121);
// Set our own WndProcs for the controls.
wpOrigOutputProc = (WNDPROC)SetWindowLong(hwndOutput, GWL_WNDPROC, (LONG)OutputProc);
if (cfgMinToTray)
AddTrayMenuItem(hMonitor, "Mail Monitor");
ShowWindow(hMonitor, SW_SHOWNORMAL);
if (MonitorRect.right < 100 || MonitorRect.bottom < 100)
{
GetWindowRect(hMonitor, &MonitorRect);
}
MoveWindow(hMonitor,MonitorRect.left,MonitorRect.top, MonitorRect.right-MonitorRect.left, MonitorRect.bottom-MonitorRect.top, TRUE);
MoveWindows();
return TRUE;
}
static void MoveWindows()
{
RECT rcMain, rcClient;
int ClientHeight, ClientWidth;
GetWindowRect(hMonitor, &rcMain);
GetClientRect(hMonitor, &rcClient);
ClientHeight = rcClient.bottom;
ClientWidth = rcClient.right;
// MoveWindow(hwndMon,2, 0, ClientWidth-4, SplitPos, TRUE);
MoveWindow(hwndOutput,2, 2, ClientWidth-4, ClientHeight-4, TRUE);
// MoveWindow(hwndSplit,0, SplitPos, ClientWidth, SplitBarHeight, TRUE);
}
static LRESULT CALLBACK MonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
LPRECT lprc;
switch (message)
{
case WM_ACTIVATE:
SetFocus(hwndInput);
break;
case WM_CLOSE:
if (wParam) // Used by Close All Programs.
return 0;
return (DefWindowProc(hWnd, message, wParam, lParam));
case WM_COMMAND:
wmId = LOWORD(wParam); // Remember, these are...
wmEvent = HIWORD(wParam); // ...different for Win32!
switch (wmId) {
case MONBBS:
ToggleParam(hMenu, hWnd, &MonBBS, MONBBS);
break;
case MONCHAT:
ToggleParam(hMenu, hWnd, &MonCHAT, MONCHAT);
break;
case MONTCP:
ToggleParam(hMenu, hWnd, &MonTCP, MONTCP);
break;
case BPQCLEAROUT:
SendMessage(hwndOutput,LB_RESETCONTENT, 0, 0);
break;
case BPQCOPYOUT:
CopyToClipboard(hwndOutput);
break;
//case BPQHELP:
// HtmlHelp(hWnd,"BPQTerminal.chm",HH_HELP_FINDER,0);
// break;
default:
return 0;
}
case WM_SYSCOMMAND:
wmId = LOWORD(wParam); // Remember, these are...
wmEvent = HIWORD(wParam); // ...different for Win32!
switch (wmId) {
case SC_MINIMIZE:
if (cfgMinToTray)
return ShowWindow(hWnd, SW_HIDE);
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
case WM_SIZING:
lprc = (LPRECT) lParam;
Height = lprc->bottom-lprc->top;
Width = lprc->right-lprc->left;
MoveWindows();
return TRUE;
case WM_DESTROY:
// Remove the subclass from the edit control.
GetWindowRect(hWnd, &MonitorRect); // For save soutine
SetWindowLong(hwndInput, GWL_WNDPROC,
(LONG) wpOrigInputProc);
if (cfgMinToTray)
DeleteTrayMenuItem(hWnd);
hMonitor = NULL;
free(readbuff);
readbufflen = 0;
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}
LRESULT APIENTRY OutputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// Trap mouse messages, so we cant select stuff in output and mon windows,
// otherwise scrolling doesnt work.
if (uMsg >= WM_MOUSEFIRST && uMsg <= WM_LBUTTONDBLCLK)
return TRUE;
return CallWindowProc(wpOrigOutputProc, hwnd, uMsg, wParam, lParam);
}
int WritetoMonitorWindow(char * Msg, int len)
{
char * ptr1, * ptr2;
int index;
if (len+PartLinePtr > readbufflen)
{
readbufflen += len+PartLinePtr;
readbuff = realloc(readbuff, readbufflen);
}
if (PartLinePtr != 0)
SendMessage(hwndOutput,LB_DELETESTRING,PartLineIndex,(LPARAM)(LPCTSTR) 0 );
memcpy(&readbuff[PartLinePtr], Msg, len);
len=len+PartLinePtr;
ptr1=&readbuff[0];
readbuff[len]=0;
do {
ptr2=memchr(ptr1,7,len);
if (ptr2)
*(ptr2)=32;
} while (ptr2);
lineloop:
// if (PartLinePtr > 300)
// PartLinePtr = 0;
if (len > 0)
{
// copy text to control a line at a time
ptr2=memchr(ptr1,13,len);
if (ptr2 == 0)
{
// no newline. Move data to start of buffer and Save pointer
PartLinePtr=len;
memmove(readbuff,ptr1,len);
PartLineIndex=SendMessage(hwndOutput,LB_ADDSTRING,0,(LPARAM)(LPCTSTR) ptr1 );
SendMessage(hwndOutput,LB_SETCARETINDEX,(WPARAM) PartLineIndex, MAKELPARAM(FALSE, 0));
return (0);
}
*(ptr2++)=0;
index=SendMessage(hwndOutput,LB_ADDSTRING,0,(LPARAM)(LPCTSTR) ptr1 );
// if (LogOutput) WriteMonitorLine(ptr1, ptr2 - ptr1);
PartLinePtr=0;
len-=(ptr2-ptr1);
ptr1=ptr2;
if ((len > 0) && StripLF)
{
if (*ptr1 == 0x0a) // Line Feed
{
ptr1++;
len--;
}
}
if (index > 1200)
do{
index=SendMessage(hwndOutput,LB_DELETESTRING, 0, 0);
} while (index > 1000);
SendMessage(hwndOutput,LB_SETCARETINDEX,(WPARAM) index, MAKELPARAM(FALSE, 0));
goto lineloop;
}
return (0);
}
static int ToggleParam(HMENU hMenu, HWND hWnd, BOOL * Param, int Item)
{
*Param = !(*Param);
CheckMenuItem(hMenu,Item, (*Param) ? MF_CHECKED : MF_UNCHECKED);
return (0);
}
static void CopyToClipboard(HWND hWnd)
{
int i,n, len=0;
HGLOBAL hMem;
char * ptr;
//
// Copy List Box to clipboard
//
n = SendMessage(hWnd, LB_GETCOUNT, 0, 0);
for (i=0; i<n; i++)
{
len+=SendMessage(hWnd, LB_GETTEXTLEN, i, 0);
}
hMem=GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, len+n+n+1);
if (hMem != 0)
{
ptr=GlobalLock(hMem);
if (OpenClipboard(MainWnd))
{
// CopyScreentoBuffer(GlobalLock(hMem));
for (i=0; i<n; i++)
{
ptr+=SendMessage(hWnd, LB_GETTEXT, i, (LPARAM) ptr);
*(ptr++)=13;
*(ptr++)=10;
}
*(ptr)=0; // end of data
GlobalUnlock(hMem);
EmptyClipboard();
SetClipboardData(CF_TEXT,hMem);
CloseClipboard();
}
else
GlobalFree(hMem);
}
}

1666
MultiConsole.c Normal file

File diff suppressed because it is too large Load Diff

1676
Multicast.c Normal file

File diff suppressed because it is too large Load Diff

1326
NNTPRoutines.c Normal file

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More