Pipes and NodeSpy
This commit is contained in:
parent
84e18433f9
commit
1a9939306f
|
@ -4689,4 +4689,9 @@
|
|||
list display to not get redrawn after.
|
||||
|
||||
! Duplicate IP check in MIS was not working properly. It is now.
|
||||
|
||||
|
||||
+ MIS telnet in Windows now has an option to hide node windows.
|
||||
|
||||
+ Added a new utility called NodeSpy. This utility will allow you to see
|
||||
who is online from the command line. It will also allow you to snoop/spy
|
||||
on a node, kick people from a node, and engage in chat with the user.
|
||||
|
|
|
@ -11,6 +11,7 @@ Uses
|
|||
{$ENDIF}
|
||||
m_FileIO,
|
||||
m_Strings,
|
||||
m_Pipe_Disk,
|
||||
m_DateTime,
|
||||
BBS_Common,
|
||||
BBS_IO,
|
||||
|
@ -26,13 +27,14 @@ Const
|
|||
Type
|
||||
TBBSCore = Class
|
||||
{$IFNDEF UNIX}
|
||||
Client : TIOBase;
|
||||
Client : TIOBase;
|
||||
{$ENDIF}
|
||||
User : TBBSUser;
|
||||
Msgs : TMsgBase;
|
||||
FileBase : TFileBase;
|
||||
Menu : TMenuEngine;
|
||||
IO : TBBSIO;
|
||||
Pipe : TPipeDisk;
|
||||
EventFile : File of EventRec;
|
||||
ThemeFile : File of RecTheme;
|
||||
VoteFile : File of VoteRec;
|
||||
|
@ -142,6 +144,7 @@ End;
|
|||
|
||||
Destructor TBBSCore.Destroy;
|
||||
Begin
|
||||
Pipe.Free;
|
||||
Msgs.Free;
|
||||
FileBase.Free;
|
||||
Menu.Free;
|
||||
|
@ -161,7 +164,7 @@ Procedure TBBSCore.UpdateHistory;
|
|||
Var
|
||||
History : RecHistory;
|
||||
Begin
|
||||
If User.ThisUser.Flags AND UserNoHistory = 0 Then Exit;
|
||||
If User.ThisUser.Flags AND UserNoHistory <> 0 Then Exit;
|
||||
|
||||
Assign (HistoryFile, Config.DataPath + 'history.dat');
|
||||
ioReset (HistoryFile, SizeOf(RecHistory), fmRWDN);
|
||||
|
|
|
@ -13,18 +13,9 @@ Uses
|
|||
bbs_Common,
|
||||
bbs_Core;
|
||||
|
||||
Procedure Print (S: String);
|
||||
Begin
|
||||
{$IFNDEF UNIX}
|
||||
If Not Session.LocalMode Then Session.io.BufAddStr(S);
|
||||
{$ENDIF}
|
||||
|
||||
Screen.WriteStr(S);
|
||||
End;
|
||||
|
||||
Procedure PrintLn (S: String);
|
||||
Begin
|
||||
Print (S + #13#10);
|
||||
Session.io.BufAddStr(S + #13#10);
|
||||
End;
|
||||
|
||||
Function AnsiEditor (Var Lines: Integer; WrapPos: Byte; MaxLines: Integer; TEdit, Forced: Boolean; Var Subj: String) : Boolean;
|
||||
|
@ -70,7 +61,7 @@ Begin
|
|||
B := CurLine;
|
||||
|
||||
Repeat
|
||||
If B <= TotalLine Then Print(Session.Msgs.MsgText[B]);
|
||||
If B <= TotalLine Then Session.io.BufAddStr(Session.Msgs.MsgText[B]);
|
||||
If B <= TotalLine + 1 Then Begin
|
||||
Session.io.AnsiClrEOL;
|
||||
PrintLn('');
|
||||
|
@ -101,7 +92,7 @@ Begin
|
|||
A := WinStart;
|
||||
|
||||
Repeat
|
||||
If B <= TotalLine Then Print(Session.Msgs.MsgText[B]);
|
||||
If B <= TotalLine Then Session.io.BufAddStr(Session.Msgs.MsgText[B]);
|
||||
Session.io.AnsiClrEOL;
|
||||
PrintLn('');
|
||||
Inc (A);
|
||||
|
@ -208,7 +199,7 @@ Begin
|
|||
|
||||
Repeat
|
||||
If (CurY + (A - CurLine) <= WinEnd) and (A <= TotalLine) Then Begin
|
||||
Print(Session.Msgs.MsgText[A]);
|
||||
Session.io.BufAddStr(Session.Msgs.MsgText[A]);
|
||||
Session.io.AnsiClrEOL;
|
||||
PrintLn('');
|
||||
End Else
|
||||
|
@ -291,7 +282,7 @@ Begin
|
|||
Delete (Session.Msgs.MsgText[CurLine], CurX, 1);
|
||||
|
||||
If CurX < Length(Session.Msgs.MsgText[CurLine]) + 1 Then Begin
|
||||
Print (Copy(Session.Msgs.MsgText[CurLine], CurX, Length(Session.Msgs.MsgText[CurLine])) + ' ');
|
||||
Session.io.BufAddStr (Copy(Session.Msgs.MsgText[CurLine], CurX, Length(Session.Msgs.MsgText[CurLine])) + ' ');
|
||||
UpdatePosition;
|
||||
End;
|
||||
End Else
|
||||
|
@ -391,13 +382,13 @@ Procedure AddChar (Ch: Char);
|
|||
Begin
|
||||
If InsertMode Then Begin
|
||||
Insert (Ch, Session.Msgs.MsgText[Curline], CurX);
|
||||
Print (Copy(Session.Msgs.MsgText[CurLine], CurX, Length(Session.Msgs.MsgText[CurLine])));
|
||||
Session.io.BufAddStr (Copy(Session.Msgs.MsgText[CurLine], CurX, Length(Session.Msgs.MsgText[CurLine])));
|
||||
End Else Begin
|
||||
If CurX > Length(Session.Msgs.MsgText[CurLine]) Then
|
||||
Inc(Session.Msgs.MsgText[CurLine][0]);
|
||||
|
||||
Session.Msgs.MsgText[CurLine][CurX] := Ch;
|
||||
Print (Ch);
|
||||
Session.io.BufAddStr (Ch);
|
||||
End;
|
||||
|
||||
Inc (CurX);
|
||||
|
@ -412,7 +403,7 @@ Begin
|
|||
Session.io.AnsiColor (Session.io.ScreenInfo[3].A);
|
||||
Session.io.AnsiGotoXY (Session.io.ScreenInfo[3].X, Session.io.ScreenInfo[3].Y);
|
||||
|
||||
If InsertMode Then Print('INS') else Print('OVR'); { ++lang }
|
||||
If InsertMode Then Session.io.BufAddStr('INS') else Session.io.BufAddStr('OVR'); { ++lang }
|
||||
|
||||
Session.io.AnsiGotoXY (CurX, CurY);
|
||||
Session.io.AnsiColor (WinText);
|
||||
|
@ -520,7 +511,7 @@ Var
|
|||
Else
|
||||
Session.io.AnsiColor (Session.io.ScreenInfo[2].A);
|
||||
|
||||
Print (strPadR(QText[QuoteTopPage + QuoteCurLine], 79, ' '));
|
||||
Session.io.BufAddStr (strPadR(QText[QuoteTopPage + QuoteCurLine], 79, ' '));
|
||||
End;
|
||||
|
||||
Procedure UpdateWindow;
|
||||
|
@ -531,7 +522,7 @@ Var
|
|||
Session.io.AnsiColor (Session.io.ScreenInfo[2].A);
|
||||
|
||||
For Count := QuoteTopPage to QuoteTopPage + 5 Do Begin
|
||||
If Count <= QuoteLines Then Print (QText[Count]);
|
||||
If Count <= QuoteLines Then Session.io.BufAddStr (QText[Count]);
|
||||
|
||||
Session.io.AnsiClrEOL;
|
||||
|
||||
|
@ -805,7 +796,7 @@ Begin
|
|||
#82 : ToggleInsert(True);
|
||||
#83 : If CurX <= Length(Session.Msgs.MsgText[CurLine]) Then Begin
|
||||
Delete (Session.Msgs.MsgText[CurLine], CurX, 1);
|
||||
Print (Copy(Session.Msgs.MsgText[CurLine], CurX, Length(Session.Msgs.MsgText[CurLine])) + ' ');
|
||||
Session.io.BufAddStr (Copy(Session.Msgs.MsgText[CurLine], CurX, Length(Session.Msgs.MsgText[CurLine])) + ' ');
|
||||
UpdatePosition;
|
||||
End Else
|
||||
If CurLine < TotalLine Then
|
||||
|
|
|
@ -56,11 +56,11 @@ Type
|
|||
InputPos : Byte;
|
||||
GetKeyCallBack : TGetKeyCallBack;
|
||||
LastSecond : LongInt;
|
||||
OutBuffer : Array[0..TBBSIOBufferSize] of Char;
|
||||
OutBufPos : SmallInt;
|
||||
|
||||
{$IFDEF WINDOWS}
|
||||
OutBuffer : Array[0..TBBSIOBufferSize] of Char;
|
||||
OutBufPos : SmallInt;
|
||||
SocketEvent : THandle;
|
||||
SocketEvent : THandle;
|
||||
{$ENDIF}
|
||||
|
||||
Constructor Create (Var Owner: Pointer);
|
||||
|
@ -143,11 +143,11 @@ Begin
|
|||
LastMCIValue := '';
|
||||
InputPos := 0;
|
||||
|
||||
FillChar(OutBuffer, SizeOf(OutBuffer), 0);
|
||||
|
||||
OutBufPos := 0;
|
||||
|
||||
{$IFDEF WINDOWS}
|
||||
FillChar(OutBuffer, SizeOf(OutBuffer), 0);
|
||||
|
||||
OutBufPos := 0;
|
||||
|
||||
If Not TBBSCore(Core).LocalMode Then
|
||||
SocketEvent := WSACreateEvent;
|
||||
{$ENDIF}
|
||||
|
@ -168,13 +168,11 @@ End;
|
|||
|
||||
Procedure TBBSIO.BufAddChar (Ch: Char);
|
||||
Begin
|
||||
{$IFDEF WINDOWS}
|
||||
OutBuffer[OutBufPos] := Ch;
|
||||
|
||||
Inc (OutBufPos);
|
||||
|
||||
If OutBufPos = TBBSIOBufferSize Then BufFlush;
|
||||
{$ENDIF}
|
||||
|
||||
Term.Process(Ch);
|
||||
End;
|
||||
|
@ -194,11 +192,19 @@ Begin
|
|||
If Not TBBSCore(Core).LocalMode Then
|
||||
TBBSCore(Core).Client.WriteBuf(OutBuffer, OutBufPos);
|
||||
|
||||
If Session.Pipe.Connected Then
|
||||
Session.Pipe.SendToPipe(OutBuffer, OutBufPos);
|
||||
|
||||
OutBufPos := 0;
|
||||
End;
|
||||
{$ENDIF}
|
||||
|
||||
{$IFDEF UNIX}
|
||||
If Session.Pipe.Connected Then
|
||||
Session.Pipe.SendToPipe(OutBuffer, OutBufPos);
|
||||
|
||||
OutBufPos := 0;
|
||||
|
||||
Screen.BufFlush;
|
||||
{$ENDIF}
|
||||
End;
|
||||
|
|
|
@ -275,7 +275,7 @@ Begin
|
|||
'C' : Node_Chat;
|
||||
'P' : PageUserForChat;
|
||||
'S' : Send_Node_Message (3, CmdData, 0);
|
||||
'W' : Show_Whos_Online;
|
||||
'W' : WhosOnline;
|
||||
End;
|
||||
'O' : Case Cmd[2] of
|
||||
'S' : Session.Msgs.ToggleNewScan(True);
|
||||
|
|
|
@ -450,7 +450,7 @@ Begin
|
|||
End Else
|
||||
If Str2 = '/WHO' Then Begin
|
||||
Session.io.AnsiClear;
|
||||
Show_Whos_Online;
|
||||
WhosOnline;
|
||||
Chat_Template;
|
||||
FullReDraw;
|
||||
End Else
|
||||
|
|
|
@ -9,7 +9,7 @@ Uses
|
|||
|
||||
Function GetChatRecord (Node: Byte; Var Chat: ChatRec) : Boolean;
|
||||
Function IsUserOnline (UserName: String) : Word;
|
||||
Procedure Show_Whos_Online;
|
||||
Procedure WhosOnline;
|
||||
Procedure Send_Node_Message (MsgType: Byte; Data: String; Room: Byte);
|
||||
Function CheckNodeMessages : Boolean;
|
||||
Procedure Set_Node_Action (Action: String);
|
||||
|
@ -87,7 +87,7 @@ Begin
|
|||
{$ENDIF}
|
||||
End;
|
||||
|
||||
Procedure Show_Whos_Online;
|
||||
Procedure WhosOnline;
|
||||
Var
|
||||
TChat : ChatRec;
|
||||
Count : Word;
|
||||
|
@ -97,19 +97,12 @@ Begin
|
|||
For Count := 1 to Config.INetTNNodes Do Begin
|
||||
Session.io.PromptInfo[1] := strI2S(Count);
|
||||
|
||||
Assign (ChatFile, Config.DataPath + 'chat' + strI2S(Count) + '.dat');
|
||||
|
||||
{$I-} Reset(ChatFile); {$I+}
|
||||
|
||||
If IoResult <> 0 Then Begin
|
||||
If Not GetChatRecord (Count, TChat) Then Begin
|
||||
Session.io.OutFullLn (Session.GetPrompt(268));
|
||||
|
||||
Continue;
|
||||
End;
|
||||
|
||||
Read (ChatFile, TChat);
|
||||
Close (ChatFile);
|
||||
|
||||
If TChat.Active and ((Not TChat.Invisible) or (TChat.Invisible and Session.User.Access(Config.AcsSeeInvis))) Then Begin
|
||||
Session.io.PromptInfo[2] := TChat.Name;
|
||||
Session.io.PromptInfo[3] := TChat.Action;
|
||||
|
@ -141,7 +134,7 @@ Begin
|
|||
Repeat
|
||||
Session.io.OutFull (Session.GetPrompt(146));
|
||||
Str := Session.io.GetInput(3, 3, 12, '');
|
||||
If Str = '?' Then Show_Whos_Online Else Break;
|
||||
If Str = '?' Then WhosOnline Else Break;
|
||||
Until False;
|
||||
|
||||
ToNode := strS2I(Str);
|
||||
|
@ -230,8 +223,7 @@ Var
|
|||
MsgFile : File of NodeMsgRec;
|
||||
SplitChat : Boolean;
|
||||
Begin
|
||||
Result := False;
|
||||
FileMode := 66;
|
||||
Result := False;
|
||||
|
||||
Assign (MsgFile, Session.TempPath + 'chat.tmp');
|
||||
|
||||
|
@ -276,6 +268,12 @@ Begin
|
|||
OpenUserChat(SplitChat, True, Msg.FromNode);
|
||||
End;
|
||||
10: OpenUserChat(SplitChat, False, Msg.FromNode);
|
||||
11: Begin
|
||||
Session.Pipe.CreatePipe;
|
||||
Session.Pipe.WaitForPipe(300);
|
||||
End;
|
||||
12: If Session.Pipe.Connected Then Session.Pipe.Disconnect;
|
||||
13: Halt(0);
|
||||
End;
|
||||
|
||||
If Result And (Msg.MsgType = 3) Then
|
||||
|
|
|
@ -1081,7 +1081,7 @@ Begin
|
|||
ThisUser.CallsToday := 0;
|
||||
ThisUser.DLsToday := 0;
|
||||
ThisUser.DLkToday := 0;
|
||||
ThisUser.TimeLeft := Security.Time
|
||||
ThisUser.TimeLeft := Security.Time;
|
||||
End;
|
||||
|
||||
If Not Session.LocalMode And (ThisUser.Flags AND UserNoLastCall = 0) Then Begin
|
||||
|
@ -1138,8 +1138,6 @@ Begin
|
|||
If (Session.TimeOffset = 0) or (Session.TimeOffset > ThisUser.TimeLeft) Then
|
||||
Session.SetTimeLeft (ThisUser.TimeLeft);
|
||||
|
||||
// check account expired -- DONE
|
||||
// check password change -- DONE
|
||||
// check auto-upgrades posts/calls/downloads/uploads/etc
|
||||
|
||||
If DateValid(Session.User.ThisUser.Expires) Then
|
||||
|
|
|
@ -29,7 +29,7 @@ Begin
|
|||
|
||||
Str := Session.io.GetInput(3, 3, 12, '');
|
||||
|
||||
If Str = '?' Then Show_Whos_Online Else
|
||||
If Str = '?' Then WhosOnline Else
|
||||
If Str = 'Q' Then Exit Else Break;
|
||||
Until False;
|
||||
|
||||
|
|
|
@ -373,7 +373,7 @@
|
|||
; &1 = File base name
|
||||
203 |CR |11|&1 will NOT be scanned in new file scan!|CR
|
||||
; &1 = File base name
|
||||
204 |CR| 11|&1 will be scanned in new file scan!|CR
|
||||
204 |CR |11|&1 will be scanned in new file scan!|CR
|
||||
; Displayed if file already exists when user trys to upload.
|
||||
205 File already exists.
|
||||
; Displayed before running uploads processor
|
||||
|
@ -938,11 +938,11 @@
|
|||
; User2User sending chat request &1=User &2=Node
|
||||
482 |CR|15Sending chat request to |&1...|DE|DE|CR
|
||||
; User2User chat mode starting
|
||||
483 |CL|09|17 ° |15Chat mode engaged.|$X70 ESC/Quit |16|CR
|
||||
483 |16|CL|09|17 ° |15Chat mode engaged.|$X70 ESC/Quit |16|CR
|
||||
; User2User chat mode ended
|
||||
484 |CL|09|17 ° |15Chat mode end.|$X79 |16|DE|DE
|
||||
484 |16|CL|09|17 ° |15Chat mode end.|$X79 |16|DE|DE
|
||||
; User2User accept chat page request? &1=user &2=Node
|
||||
485 |CL|15|&1 is requesting private user chat. Accept? |11
|
||||
485 |16|CL|15|&1 is requesting private user chat. Accept? |11
|
||||
; MsgBase quickscan header prompt
|
||||
486 |CR|12Starting Quick Scan|CR
|
||||
; MsgBase quickscan Scanning prompt
|
||||
|
|
|
@ -419,6 +419,7 @@ Begin
|
|||
End;
|
||||
|
||||
{$IFDEF UNIX}
|
||||
(*
|
||||
Procedure Snoop;
|
||||
Begin
|
||||
If FocusCurrent <> FocusTelnet Then Exit;
|
||||
|
@ -453,7 +454,7 @@ Begin
|
|||
SwitchFocus;
|
||||
End;
|
||||
End;
|
||||
|
||||
*)
|
||||
Procedure DaemonEventSignal (Sig : LongInt); cdecl;
|
||||
Begin
|
||||
Case Sig of
|
||||
|
@ -592,7 +593,7 @@ Begin
|
|||
End;
|
||||
End;
|
||||
#09 : SwitchFocus;
|
||||
#13 : {$IFDEF UNIX}Snoop{$ENDIF};
|
||||
// #13 : {$IFDEF UNIX}Snoop{$ENDIF};
|
||||
#27 : Break;
|
||||
#32 : LocalLogin;
|
||||
End;
|
||||
|
|
|
@ -31,7 +31,7 @@ Const
|
|||
#1,'³',#25,'K','³', #8,'°',#24,'°', #1,'³',#25,'K','³', #8,'°',#24,
|
||||
'°', #1,'À',#26,'K','Ä','Ù', #8,'°',#24,#26,'O','°',#24,#23,' ', #1,
|
||||
'T','A','B','/','S','w','i','t','c','h',' ','W','i','n','d','o','w',
|
||||
#25, #2,'E','N','T','E','R','/','S','n','o','o','p',#25, #2,'S','P',
|
||||
#25, #2,' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',#25, #2,'S','P',
|
||||
'A','C','E','/','L','o','c','a','l',#25, #2,'A','L','T','-','K','/',
|
||||
'K','i','l','l',' ','U','s','e','r',#25, #2,'E','S','C','/','S','h',
|
||||
'u','t','d','o','w','n',' ',#24);
|
||||
|
@ -39,10 +39,6 @@ Begin
|
|||
Console.LoadScreenImage(ImageData, ImageData_Length, ImageData_Width, 1, 1);
|
||||
|
||||
//Console.WriteXY (25, 1, 113, strPadC(mysVersionText, 30, ' '));
|
||||
|
||||
{$IFDEF UNIX}
|
||||
Console.WriteXY (1, 25, 113, strPadC('ENTER/Snoop SPACE/Local TELNET TAB/Switch ESC/Shutdown', 79, ' '));
|
||||
{$ELSE}
|
||||
Console.WriteXY (1, 25, 113, strPadC('SPACE/Local TELNET TAB/Switch ESC/Shutdown', 79, ' '));
|
||||
{$ENDIF}
|
||||
|
||||
Console.WriteXY (1, 25, 113, strPadC('SPACE/Local TELNET TAB/Switch ESC/Shutdown', 79, ' '));
|
||||
End;
|
||||
|
|
|
@ -28,7 +28,7 @@ Function CreateTelnet (Owner: TServerManager; Config: RecConfig; ND: TNodeData;
|
|||
Type
|
||||
TTelnetServer = Class(TServerClient)
|
||||
ND : TNodeData;
|
||||
Snooping : Boolean;
|
||||
// Snooping : Boolean;
|
||||
Constructor Create (Owner: TServerManager; ND: TNodeData; CliSock: TIOSocket);
|
||||
Procedure Execute; Override;
|
||||
Destructor Destroy; Override;
|
||||
|
@ -46,7 +46,7 @@ Begin
|
|||
Inherited Create(Owner, CliSock);
|
||||
|
||||
Self.ND := ND;
|
||||
Snooping := False;
|
||||
// Snooping := False;
|
||||
End;
|
||||
|
||||
{$IFDEF WINDOWS}
|
||||
|
@ -84,8 +84,12 @@ Begin
|
|||
FillChar(SI, SizeOf(SI), 0);
|
||||
FillChar(PI, SizeOf(PI), 0);
|
||||
|
||||
SI.dwFlags := STARTF_USESHOWWINDOW;
|
||||
SI.wShowWindow := SW_SHOWMINNOACTIVE;
|
||||
SI.dwFlags := STARTF_USESHOWWINDOW;
|
||||
|
||||
If bbsConfig.inetTNHidden Then
|
||||
SI.wShowWindow := SW_HIDE
|
||||
Else
|
||||
SI.wShowWindow := SW_SHOWMINNOACTIVE;
|
||||
|
||||
If CreateProcess(NIL, PChar(@Cmd[1]),
|
||||
NIL, NIL, True, Create_New_Console + Normal_Priority_Class, NIL, NIL, SI, PI) Then
|
||||
|
@ -140,8 +144,8 @@ Begin
|
|||
bRead := Proc.Output.Read(Buffer, BufferSize);
|
||||
Client.WriteBufEscaped (Buffer, bRead);
|
||||
|
||||
If Snooping Then
|
||||
Term.ProcessBuf(Buffer[0], bRead);
|
||||
// If Snooping Then
|
||||
// Term.ProcessBuf(Buffer[0], bRead);
|
||||
End;
|
||||
End Else
|
||||
If Client.DataWaiting Then Begin
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
Import_FIDONET.NA = false
|
||||
Import_FILEBONE.NA = false
|
||||
Import_FILES.BBS = false
|
||||
Import_FILES.BBS = true
|
||||
MassUpload = false
|
||||
GenerateTopLists = false
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ Uses
|
|||
m_DateTime,
|
||||
m_Output,
|
||||
m_Input,
|
||||
m_Pipe_Disk,
|
||||
bbs_Common,
|
||||
bbs_Core,
|
||||
bbs_NodeInfo,
|
||||
|
@ -233,6 +234,8 @@ Begin
|
|||
|
||||
Session.TempPath := Config.SystemPath + 'temp' + strI2S(Session.NodeNum) + PathChar;
|
||||
|
||||
Session.Pipe := TPipeDisk.Create(Config.DataPath, False, Session.NodeNum);
|
||||
|
||||
{$I-}
|
||||
MkDir (Config.SystemPath + 'temp' + strI2S(Session.NodeNum));
|
||||
{$I+}
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
Program NodeSpy;
|
||||
|
||||
// page chat
|
||||
// user editor
|
||||
// split chat
|
||||
// auto snoop
|
||||
// local login
|
||||
// terminal mode
|
||||
|
||||
{$I M_OPS.PAS}
|
||||
|
||||
Uses
|
||||
|
@ -22,9 +29,21 @@ Uses
|
|||
|
||||
Const
|
||||
HiddenNode = 255;
|
||||
UpdateTimer = 500;
|
||||
UpdateNode = 500;
|
||||
UpdateStats = 6000 * 10;
|
||||
|
||||
AutoSnoop : Boolean = True;
|
||||
|
||||
Type
|
||||
PNodeInfo = ^TNodeInfo;
|
||||
TNodeInfo = Record
|
||||
Node : Byte;
|
||||
User : String[30];
|
||||
Action : String[50];
|
||||
End;
|
||||
|
||||
Var
|
||||
NodeInfo : Array[1..255] of PNodeInfo;
|
||||
ChatFile : File of ChatRec;
|
||||
Chat : ChatRec;
|
||||
ConfigFile : File of RecConfig;
|
||||
|
@ -35,6 +54,75 @@ Var
|
|||
Screen : TOutput;
|
||||
Keyboard : TInput;
|
||||
|
||||
{$I NODESPY_ANSI.PAS}
|
||||
|
||||
Procedure ApplicationShutdown;
|
||||
Var
|
||||
Count : Byte;
|
||||
Begin
|
||||
For Count := Config.inetTNNodes DownTo 1 Do
|
||||
If Assigned(NodeInfo[Count]) Then
|
||||
Dispose(NodeInfo[Count]);
|
||||
|
||||
Keyboard.Free;
|
||||
Screen.Free;
|
||||
End;
|
||||
|
||||
Procedure ApplicationInit;
|
||||
Var
|
||||
{$IFDEF UNIX}
|
||||
Info : Stat;
|
||||
{$ENDIF}
|
||||
Count : Byte;
|
||||
Begin
|
||||
{$IFDEF UNIX}
|
||||
If fpStat('nodespy', Info) = 0 Then Begin
|
||||
fpSetGID (Info.st_GID);
|
||||
fpSetUID (Info.st_UID);
|
||||
End;
|
||||
{$ENDIF}
|
||||
|
||||
ExitProc := @ApplicationShutdown;
|
||||
Screen := TOutput.Create(True);
|
||||
Keyboard := TInput.Create;
|
||||
|
||||
Assign (ConfigFile, 'mystic.dat');
|
||||
Reset (ConfigFile);
|
||||
|
||||
If IoResult <> 0 Then Begin
|
||||
BasePath := GetENV('mysticbbs');
|
||||
|
||||
If BasePath <> '' Then BasePath := DirSlash(BasePath);
|
||||
|
||||
Assign (ConfigFile, BasePath + 'mystic.dat');
|
||||
Reset (ConfigFile);
|
||||
|
||||
If IoResult <> 0 Then Begin
|
||||
Screen.WriteLine ('ERROR: Unable to read MYSTIC.DAT' + #13#10);
|
||||
Screen.WriteLine ('MYSTIC.DAT must exist in the same directory as NodeSpy, or in the');
|
||||
Screen.WriteLine ('path defined by the MYSTICBBS environment variable.');
|
||||
|
||||
Halt (1);
|
||||
End;
|
||||
End;
|
||||
|
||||
Read (ConfigFile, Config);
|
||||
Close (ConfigFile);
|
||||
|
||||
If Config.DataChanged <> mysDataChanged Then Begin
|
||||
Screen.WriteLine ('ERROR: NodeSpy has detected a version mismatch' + #13#10);
|
||||
Screen.WriteLine ('NodeSpy or another BBS utility is an older incompatible version. Make');
|
||||
Screen.WriteLine ('sure you have upgraded properly!');
|
||||
|
||||
Halt (1);
|
||||
End;
|
||||
|
||||
DirCreate(Config.SystemPath + 'temp' + strI2S(HiddenNode));
|
||||
|
||||
For Count := 1 to Config.inetTNNodes Do
|
||||
New (NodeInfo[Count]);
|
||||
End;
|
||||
|
||||
Function ShowMsgBox (BoxType: Byte; Str: String) : Boolean;
|
||||
Var
|
||||
Len : Byte;
|
||||
|
@ -119,6 +207,7 @@ Begin
|
|||
MsgBox.Free;
|
||||
|
||||
Screen.CursorXY (SavedX, SavedY);
|
||||
|
||||
Screen.TextAttr := SavedA;
|
||||
End;
|
||||
|
||||
|
@ -277,8 +366,8 @@ Begin
|
|||
Screen.TextAttr := 7;
|
||||
Screen.ClearScreen;
|
||||
|
||||
Screen.WriteXY (1, 1, 31, strRep(' ', 79));
|
||||
Screen.WriteXY (2, 1, 31, 'Chat mode engaged');
|
||||
Screen.WriteXY ( 1, 1, 31, strRep(' ', 79));
|
||||
Screen.WriteXY ( 2, 1, 31, 'Chat mode engaged');
|
||||
Screen.WriteXY (71, 1, 31, 'ESC/Quit');
|
||||
Screen.CursorXY (1, 3);
|
||||
|
||||
|
@ -355,6 +444,7 @@ Begin
|
|||
Erase(fIn);
|
||||
|
||||
Screen.TextAttr := 7;
|
||||
|
||||
Screen.ClearScreen;
|
||||
End;
|
||||
|
||||
|
@ -378,43 +468,42 @@ Var
|
|||
Screen.WriteXY ( 1, 25, Config.StatusColor1, strRep(' ', 79));
|
||||
Screen.WriteXY ( 2, 25, Config.StatusColor1, 'User');
|
||||
Screen.WriteXY ( 7, 25, Config.StatusColor2, Chat.Name);
|
||||
Screen.WriteXY (56, 25, Config.StatusColor3, 'ALT: C)hat K)ick e(X)it');
|
||||
Screen.WriteXY (54, 25, Config.StatusColor3, 'ALT (C)hat (K)ick e(X)it');
|
||||
Screen.SetWindow ( 1, 1, 80, 24, True);
|
||||
|
||||
Screen.CursorXY (SX, SY);
|
||||
|
||||
Screen.TextAttr := SA;
|
||||
End;
|
||||
End;
|
||||
|
||||
Begin
|
||||
WriteLn;
|
||||
WriteLn('Requesting snoop session for node ', Node, '...');
|
||||
WriteLn;
|
||||
GetChatRecord(Node, Chat);
|
||||
|
||||
If Not Chat.Active Then Begin
|
||||
ShowMsgBox(0, 'Node ' + strI2S(Node) + ' is not in use');
|
||||
Exit;
|
||||
End;
|
||||
|
||||
ShowMsgBox (3, 'Requesting snoop session for node ' + strI2S(Node));
|
||||
|
||||
SendNodeMessage(Node, 11);
|
||||
|
||||
Pipe := TPipeDisk.Create(Config.DataPath, True, Node);
|
||||
|
||||
If Not Pipe.ConnectPipe(1500) Then Begin
|
||||
WriteLn('NodeSpy was not able to establish a snoop session. Sessions');
|
||||
WriteLn('cannot be created if a user is in a door or a file transfer.');
|
||||
|
||||
ShowMsgBox (0, 'Unable to establish a session. Try again');
|
||||
Pipe.Free;
|
||||
|
||||
Exit;
|
||||
End;
|
||||
|
||||
WriteLn('Connection established');
|
||||
Term := TTermAnsi.Create(Screen);
|
||||
|
||||
Keyboard := TInput.Create;
|
||||
Screen := TOutput.Create(True);
|
||||
Term := TTermAnsi.Create(Screen);
|
||||
|
||||
Screen.SetWindowTitle('Snooping node ' + strI2S(Node));
|
||||
Screen.SetWindowTitle('[NodeSpy] Snooping ' + strI2S(Node));
|
||||
|
||||
DrawStatus;
|
||||
|
||||
Update := TimerSet(UpdateTimer);
|
||||
Update := TimerSet(UpdateNode);
|
||||
|
||||
While Pipe.Connected Do Begin
|
||||
Pipe.ReadFromPipe(Buffer, SizeOf(Buffer), BufRead);
|
||||
|
@ -443,7 +532,7 @@ Begin
|
|||
|
||||
DrawStatus;
|
||||
|
||||
Update := TimerSet(UpdateTimer);
|
||||
Update := TimerSet(UpdateNode);
|
||||
End;
|
||||
End;
|
||||
|
||||
|
@ -457,88 +546,219 @@ Begin
|
|||
Pipe.Disconnect;
|
||||
Pipe.Free;
|
||||
Term.Free;
|
||||
Screen.Free;
|
||||
|
||||
WriteLn;
|
||||
WriteLn;
|
||||
WriteLn ('Session closed');
|
||||
End;
|
||||
|
||||
Procedure ShowWhosOnline;
|
||||
Procedure UpdateOnlineStatus;
|
||||
Var
|
||||
Count : Word;
|
||||
Count : LongInt;
|
||||
Begin
|
||||
WriteLn;
|
||||
WriteLn('### UserName Action');
|
||||
WriteLn(strRep('=', 79));
|
||||
|
||||
For Count := 1 to Config.INetTNNodes Do Begin
|
||||
If GetChatRecord(Count, Chat) Then Begin
|
||||
WriteLn (strPadL(strI2S(Count), 3, '0') + ' ' +
|
||||
strPadR(Chat.Name, 25, ' ') + ' ' +
|
||||
strPadR(Chat.Action, 45, ' '));
|
||||
End Else
|
||||
WriteLn (strPadL(strI2S(Count), 3, '0') + ' ' +
|
||||
strPadR('Waiting', 25, ' ') + ' ' +
|
||||
strPadR('Waiting', 45, ' '));
|
||||
End;
|
||||
|
||||
WriteLn (strRep('=', 79));
|
||||
WriteLn ('Execute NodeSpy [node number] to spy on a node');
|
||||
For Count := 1 to Config.inetTNNodes Do
|
||||
If GetChatRecord(Count, Chat) and (Chat.Active) Then Begin
|
||||
NodeInfo[Count]^.Node := Count;
|
||||
NodeInfo[Count]^.User := Chat.Name;
|
||||
NodeInfo[Count]^.Action := Chat.Action;
|
||||
End Else Begin
|
||||
NodeInfo[Count]^.Node := Count;
|
||||
NodeInfo[Count]^.User := 'Waiting';
|
||||
NodeInfo[Count]^.Action := 'Waiting';
|
||||
End;
|
||||
End;
|
||||
|
||||
Procedure MainMenu;
|
||||
Var
|
||||
NodeNum : Byte;
|
||||
{$IFDEF UNIX}
|
||||
Info : Stat;
|
||||
{$ENDIF}
|
||||
Begin
|
||||
{$IFDEF UNIX}
|
||||
If fpStat('nodespy', Info) = 0 Then Begin
|
||||
fpSetGID (Info.st_GID);
|
||||
fpSetUID (Info.st_UID);
|
||||
StatTotalDays : LongInt = 0;
|
||||
StatTodayCalls : LongInt = 0;
|
||||
StatTotalCalls : LongInt = 0;
|
||||
StatTodayNewUsers : LongInt = 0;
|
||||
StatTotalNewUsers : LongInt = 0;
|
||||
StatTodayPosts : LongInt = 0;
|
||||
StatTotalPosts : LongInt = 0;
|
||||
StatTodayEmail : LongInt = 0;
|
||||
StatTotalEmail : LongInt = 0;
|
||||
StatTodayDownloads : LongInt = 0;
|
||||
StatTotalDownloads : LongInt = 0;
|
||||
StatTodayUploads : LongInt = 0;
|
||||
StatTotalUploads : LongInt = 0;
|
||||
|
||||
NodeTimer : LongInt;
|
||||
TopPage : SmallInt = 1;
|
||||
CurNode : SmallInt = 1;
|
||||
|
||||
Procedure DrawStats;
|
||||
Begin
|
||||
Screen.WriteXY (12, 18, 9, strPadL(strI2S(StatTodayCalls), 6, ' '));
|
||||
Screen.WriteXY (12, 19, 9, strPadL(strI2S(StatTodayNewUsers), 6, ' '));
|
||||
Screen.WriteXY (12, 20, 9, strPadL(strI2S(StatTodayPosts), 6, ' '));
|
||||
Screen.WriteXY (12, 21, 9, strPadL(strI2S(StatTodayEmail), 6, ' '));
|
||||
Screen.WriteXY (12, 22, 9, strPadL(strI2S(StatTodayDownloads), 6, ' '));
|
||||
Screen.WriteXY (12, 23, 9, strPadL(strI2S(StatTodayUploads), 6, ' '));
|
||||
|
||||
Screen.WriteXY (19, 18, 9, strPadL(strComma(StatTotalCalls), 12, ' '));
|
||||
Screen.WriteXY (19, 19, 9, strPadL(strComma(StatTotalNewUsers), 12, ' '));
|
||||
Screen.WriteXY (19, 20, 9, strPadL(strComma(StatTotalPosts), 12, ' '));
|
||||
Screen.WriteXY (19, 21, 9, strPadL(strComma(StatTotalEmail), 12, ' '));
|
||||
Screen.WriteXY (19, 22, 9, strPadL(strComma(StatTotalDownloads), 12, ' '));
|
||||
Screen.WriteXY (19, 23, 9, strPadL(strComma(StatTotalUploads), 12, ' '));
|
||||
End;
|
||||
{$ENDIF}
|
||||
|
||||
Assign (ConfigFile, 'mystic.dat');
|
||||
Reset (ConfigFile);
|
||||
Procedure UpdateStats;
|
||||
Var
|
||||
HistFile : File of RecHistory;
|
||||
Hist : RecHistory;
|
||||
Begin
|
||||
FileMode := 66;
|
||||
|
||||
If IoResult <> 0 Then Begin
|
||||
BasePath := GetENV('mysticbbs');
|
||||
Assign (HistFile, Config.DataPath + 'history.dat');
|
||||
Reset (HistFile);
|
||||
|
||||
If BasePath <> '' Then BasePath := DirSlash(BasePath);
|
||||
If IoResult <> 0 Then Exit;
|
||||
|
||||
Assign (ConfigFile, BasePath + 'mystic.dat');
|
||||
Reset (ConfigFile);
|
||||
StatTotalDays := 0;
|
||||
|
||||
While Not Eof(HistFile) Do Begin
|
||||
Read (HistFile, Hist);
|
||||
|
||||
Inc (StatTotalDays);
|
||||
|
||||
Inc (StatTotalCalls, Hist.Calls);
|
||||
Inc (StatTotalNewUsers, Hist.NewUsers);
|
||||
Inc (StatTotalDownloads, Hist.Downloads);
|
||||
Inc (StatTotalPosts, Hist.Posts);
|
||||
Inc (StatTotalEmail, Hist.Emails);
|
||||
Inc (StatTotalUploads, Hist.Uploads);
|
||||
|
||||
If DateDos2Str(Hist.Date, 1) = DateDos2Str(CurDateDos, 1) Then Begin
|
||||
Inc (StatTodayCalls, Hist.Calls);
|
||||
Inc (StatTodayNewUsers, Hist.NewUsers);
|
||||
Inc (StatTodayDownloads, Hist.Downloads);
|
||||
Inc (StatTodayPosts, Hist.Posts);
|
||||
Inc (StatTodayEmail, Hist.Emails);
|
||||
Inc (StatTodayUploads, Hist.Uploads);
|
||||
End;
|
||||
End;
|
||||
|
||||
Close (HistFile);
|
||||
|
||||
DrawStats;
|
||||
End;
|
||||
|
||||
Procedure DrawNodes;
|
||||
Var
|
||||
CN : Byte;
|
||||
Count : Byte;
|
||||
Attr : Byte;
|
||||
Begin
|
||||
For Count := 1 to 5 Do Begin
|
||||
CN := Count + TopPage - 1;
|
||||
|
||||
If CN > Config.inetTNNodes Then Break;
|
||||
|
||||
If CurNode = CN Then Attr := 31 Else Attr := 7;
|
||||
|
||||
Screen.WriteXY (1, 10 + Count, Attr,
|
||||
' ' +
|
||||
strPadL(strI2S(NodeInfo[CN]^.Node), 3, ' ') + ' ' +
|
||||
strPadR(NodeInfo[CN]^.User, 25, ' ') + ' ' +
|
||||
strPadR(NodeInfo[CN]^.Action, 43, ' ') + ' '
|
||||
);
|
||||
|
||||
If IoResult <> 0 Then Begin
|
||||
WriteLn ('ERROR: Unable to read MYSTIC.DAT');
|
||||
WriteLn;
|
||||
WriteLn ('MYSTIC.DAT must exist in the same directory as NodeSpy, or in the');
|
||||
WriteLn ('path defined by the MYSTICBBS environment variable.');
|
||||
Halt (1);
|
||||
End;
|
||||
End;
|
||||
|
||||
Read (ConfigFile, Config);
|
||||
Close (ConfigFile);
|
||||
Var
|
||||
Count : Byte;
|
||||
Begin
|
||||
DrawNodeSpyScreen;
|
||||
UpdateStats;
|
||||
UpdateOnlineStatus;
|
||||
|
||||
If Config.DataChanged <> mysDataChanged Then Begin
|
||||
WriteLn ('ERROR: NodeSpy has detected a version mismatch');
|
||||
WriteLn;
|
||||
WriteLn ('NodeSpy or another BBS utility is an older incompatible version. Make');
|
||||
WriteLn ('sure you have upgraded properly!');
|
||||
Halt (1);
|
||||
End;
|
||||
DrawNodes;
|
||||
|
||||
DirCreate(Config.SystemPath + 'temp' + strI2S(HiddenNode));
|
||||
NodeTimer := TimerSet(UpdateNode);
|
||||
|
||||
If ParamCount < 1 Then
|
||||
ShowWhosOnline
|
||||
Else Begin
|
||||
NodeNum := strS2I(ParamStr(1));
|
||||
Repeat
|
||||
If Keyboard.KeyWait(1000) Then
|
||||
Case Keyboard.ReadKey of
|
||||
#00 : Case Keyboard.ReadKey of
|
||||
#71 : Begin
|
||||
TopPage := 1;
|
||||
CurNode := 1;
|
||||
|
||||
If (NodeNum > 0) and (NodeNum <= Config.INetTNNodes) Then
|
||||
SnoopNode(NodeNum);
|
||||
End;
|
||||
End.
|
||||
DrawNodes;
|
||||
End;
|
||||
#72 : If CurNode > 1 Then Begin
|
||||
Dec (CurNode);
|
||||
|
||||
If CurNode < TopPage Then Dec(TopPage);
|
||||
|
||||
DrawNodes;
|
||||
End;
|
||||
#73,
|
||||
#75 : Begin
|
||||
Dec (TopPage, 5);
|
||||
Dec (CurNode, 5);
|
||||
|
||||
If TopPage < 1 Then TopPage := 1;
|
||||
If CurNode < 1 Then CurNode := 1;
|
||||
|
||||
DrawNodes;
|
||||
End;
|
||||
#77,
|
||||
#81 : Begin
|
||||
Inc (TopPage, 5);
|
||||
Inc (CurNode, 5);
|
||||
|
||||
If TopPage + 4 > Config.inetTNNodes Then TopPage := Config.inetTNNodes - 4;
|
||||
If CurNode > Config.inetTNNodes Then CurNode := Config.inetTNNodes;
|
||||
|
||||
If TopPage < 1 Then TopPage := 1;
|
||||
|
||||
DrawNodes;
|
||||
End;
|
||||
#79 : Begin
|
||||
TopPage := Config.inetTNNodes - 4;
|
||||
CurNode := Config.inetTNNodes;
|
||||
|
||||
If Toppage < 1 Then TopPage := 1;
|
||||
|
||||
DrawNodes;
|
||||
End;
|
||||
#80 : If CurNode < Config.inetTNNodes Then Begin
|
||||
Inc (CurNode);
|
||||
If TopPage + 4 < CurNode Then Inc(TopPage);
|
||||
DrawNodes;
|
||||
End;
|
||||
End;
|
||||
#13 : Begin
|
||||
SnoopNode(NodeInfo[CurNode]^.Node);
|
||||
DrawNodeSpyScreen;
|
||||
UpdateOnlineStatus;
|
||||
DrawNodes;
|
||||
DrawStats;
|
||||
End;
|
||||
#27 : Break;
|
||||
End;
|
||||
|
||||
If TimerUp(NodeTimer) Then Begin
|
||||
UpdateOnlineStatus;
|
||||
DrawNodes;
|
||||
|
||||
NodeTimer := TimerSet(UpdateNode);
|
||||
|
||||
For Count := 1 to Config.inetTNNodes Do
|
||||
If NodeInfo[Count]^.User <> 'Waiting' Then Begin
|
||||
SnoopNode(NodeInfo[Count]^.Node);
|
||||
DrawNodeSpyScreen;
|
||||
UpdateOnlineStatus;
|
||||
DrawNodes;
|
||||
DrawStats;
|
||||
End;
|
||||
End;
|
||||
Until False;
|
||||
End;
|
||||
|
||||
Begin
|
||||
ApplicationInit;
|
||||
|
||||
MainMenu;
|
||||
End.
|
|
@ -11,6 +11,13 @@
|
|||
|
||||
{$PACKRECORDS 1}
|
||||
|
||||
// Add minutes to history
|
||||
// Change file listing size to Int64
|
||||
// Extend msg and file base names to 70 chars?
|
||||
// local qwk download/upload?
|
||||
// rewrite event system...
|
||||
// event types, exec commands, weekly/monthly option?
|
||||
|
||||
Const
|
||||
mysSoftwareID = 'Mystic'; // no idea
|
||||
mysCopyYear = '1997-2012'; // its been a long time!
|
||||
|
@ -259,7 +266,8 @@ Type
|
|||
inetNNTPDupes : Byte;
|
||||
inetNNTPTimeOut : Word;
|
||||
// UNSORTED
|
||||
Reserved : Array[1..846] of Char;
|
||||
inetTNHidden : Boolean;
|
||||
Reserved : Array[1..845] of Char;
|
||||
End;
|
||||
|
||||
Const
|
||||
|
@ -769,5 +777,8 @@ Type
|
|||
{ 8 = user 2 user page }
|
||||
{ 9 = user 2 user forced }
|
||||
{ 10 = chat accepted }
|
||||
{ 11 = start pipe session }
|
||||
{ 12 = end pipe session }
|
||||
{ 13 = terminte node }
|
||||
Room : Byte; { Chat room number. 0 = chat broadcast }
|
||||
End;
|
||||
|
|
|
@ -19,6 +19,8 @@ BUGS AND POSSIBLE ISSUES
|
|||
FPC BUG? DirAttr is suspect in MPL is it 1 byte or 4 in size?
|
||||
! View archive not working if its external view? [Griffin]
|
||||
! Test MIS blocking features or just rewrite MIS completely.
|
||||
! Test midnight rollovers for time (flag for user to be immune to timecheck)
|
||||
! Elasped time will need to be recalculated based on flag above ^^
|
||||
|
||||
FUTURE / IDEAS / WORK IN PROGRESS / NOTES
|
||||
=========================================
|
||||
|
|
Loading…
Reference in New Issue