Pipes and NodeSpy

This commit is contained in:
mysticbbs 2012-08-21 12:23:47 -04:00
parent 84e18433f9
commit 1a9939306f
18 changed files with 394 additions and 156 deletions

View File

@ -4689,4 +4689,9 @@
list display to not get redrawn after. list display to not get redrawn after.
! Duplicate IP check in MIS was not working properly. It is now. ! 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.

View File

@ -11,6 +11,7 @@ Uses
{$ENDIF} {$ENDIF}
m_FileIO, m_FileIO,
m_Strings, m_Strings,
m_Pipe_Disk,
m_DateTime, m_DateTime,
BBS_Common, BBS_Common,
BBS_IO, BBS_IO,
@ -26,13 +27,14 @@ Const
Type Type
TBBSCore = Class TBBSCore = Class
{$IFNDEF UNIX} {$IFNDEF UNIX}
Client : TIOBase; Client : TIOBase;
{$ENDIF} {$ENDIF}
User : TBBSUser; User : TBBSUser;
Msgs : TMsgBase; Msgs : TMsgBase;
FileBase : TFileBase; FileBase : TFileBase;
Menu : TMenuEngine; Menu : TMenuEngine;
IO : TBBSIO; IO : TBBSIO;
Pipe : TPipeDisk;
EventFile : File of EventRec; EventFile : File of EventRec;
ThemeFile : File of RecTheme; ThemeFile : File of RecTheme;
VoteFile : File of VoteRec; VoteFile : File of VoteRec;
@ -142,6 +144,7 @@ End;
Destructor TBBSCore.Destroy; Destructor TBBSCore.Destroy;
Begin Begin
Pipe.Free;
Msgs.Free; Msgs.Free;
FileBase.Free; FileBase.Free;
Menu.Free; Menu.Free;
@ -161,7 +164,7 @@ Procedure TBBSCore.UpdateHistory;
Var Var
History : RecHistory; History : RecHistory;
Begin 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'); Assign (HistoryFile, Config.DataPath + 'history.dat');
ioReset (HistoryFile, SizeOf(RecHistory), fmRWDN); ioReset (HistoryFile, SizeOf(RecHistory), fmRWDN);

View File

@ -13,18 +13,9 @@ Uses
bbs_Common, bbs_Common,
bbs_Core; 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); Procedure PrintLn (S: String);
Begin Begin
Print (S + #13#10); Session.io.BufAddStr(S + #13#10);
End; End;
Function AnsiEditor (Var Lines: Integer; WrapPos: Byte; MaxLines: Integer; TEdit, Forced: Boolean; Var Subj: String) : Boolean; Function AnsiEditor (Var Lines: Integer; WrapPos: Byte; MaxLines: Integer; TEdit, Forced: Boolean; Var Subj: String) : Boolean;
@ -70,7 +61,7 @@ Begin
B := CurLine; B := CurLine;
Repeat 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 If B <= TotalLine + 1 Then Begin
Session.io.AnsiClrEOL; Session.io.AnsiClrEOL;
PrintLn(''); PrintLn('');
@ -101,7 +92,7 @@ Begin
A := WinStart; A := WinStart;
Repeat Repeat
If B <= TotalLine Then Print(Session.Msgs.MsgText[B]); If B <= TotalLine Then Session.io.BufAddStr(Session.Msgs.MsgText[B]);
Session.io.AnsiClrEOL; Session.io.AnsiClrEOL;
PrintLn(''); PrintLn('');
Inc (A); Inc (A);
@ -208,7 +199,7 @@ Begin
Repeat Repeat
If (CurY + (A - CurLine) <= WinEnd) and (A <= TotalLine) Then Begin 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; Session.io.AnsiClrEOL;
PrintLn(''); PrintLn('');
End Else End Else
@ -291,7 +282,7 @@ Begin
Delete (Session.Msgs.MsgText[CurLine], CurX, 1); Delete (Session.Msgs.MsgText[CurLine], CurX, 1);
If CurX < Length(Session.Msgs.MsgText[CurLine]) + 1 Then Begin 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; UpdatePosition;
End; End;
End Else End Else
@ -391,13 +382,13 @@ Procedure AddChar (Ch: Char);
Begin Begin
If InsertMode Then Begin If InsertMode Then Begin
Insert (Ch, Session.Msgs.MsgText[Curline], CurX); 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 End Else Begin
If CurX > Length(Session.Msgs.MsgText[CurLine]) Then If CurX > Length(Session.Msgs.MsgText[CurLine]) Then
Inc(Session.Msgs.MsgText[CurLine][0]); Inc(Session.Msgs.MsgText[CurLine][0]);
Session.Msgs.MsgText[CurLine][CurX] := Ch; Session.Msgs.MsgText[CurLine][CurX] := Ch;
Print (Ch); Session.io.BufAddStr (Ch);
End; End;
Inc (CurX); Inc (CurX);
@ -412,7 +403,7 @@ Begin
Session.io.AnsiColor (Session.io.ScreenInfo[3].A); Session.io.AnsiColor (Session.io.ScreenInfo[3].A);
Session.io.AnsiGotoXY (Session.io.ScreenInfo[3].X, Session.io.ScreenInfo[3].Y); 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.AnsiGotoXY (CurX, CurY);
Session.io.AnsiColor (WinText); Session.io.AnsiColor (WinText);
@ -520,7 +511,7 @@ Var
Else Else
Session.io.AnsiColor (Session.io.ScreenInfo[2].A); Session.io.AnsiColor (Session.io.ScreenInfo[2].A);
Print (strPadR(QText[QuoteTopPage + QuoteCurLine], 79, ' ')); Session.io.BufAddStr (strPadR(QText[QuoteTopPage + QuoteCurLine], 79, ' '));
End; End;
Procedure UpdateWindow; Procedure UpdateWindow;
@ -531,7 +522,7 @@ Var
Session.io.AnsiColor (Session.io.ScreenInfo[2].A); Session.io.AnsiColor (Session.io.ScreenInfo[2].A);
For Count := QuoteTopPage to QuoteTopPage + 5 Do Begin 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; Session.io.AnsiClrEOL;
@ -805,7 +796,7 @@ Begin
#82 : ToggleInsert(True); #82 : ToggleInsert(True);
#83 : If CurX <= Length(Session.Msgs.MsgText[CurLine]) Then Begin #83 : If CurX <= Length(Session.Msgs.MsgText[CurLine]) Then Begin
Delete (Session.Msgs.MsgText[CurLine], CurX, 1); 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; UpdatePosition;
End Else End Else
If CurLine < TotalLine Then If CurLine < TotalLine Then

View File

@ -56,11 +56,11 @@ Type
InputPos : Byte; InputPos : Byte;
GetKeyCallBack : TGetKeyCallBack; GetKeyCallBack : TGetKeyCallBack;
LastSecond : LongInt; LastSecond : LongInt;
OutBuffer : Array[0..TBBSIOBufferSize] of Char;
OutBufPos : SmallInt;
{$IFDEF WINDOWS} {$IFDEF WINDOWS}
OutBuffer : Array[0..TBBSIOBufferSize] of Char; SocketEvent : THandle;
OutBufPos : SmallInt;
SocketEvent : THandle;
{$ENDIF} {$ENDIF}
Constructor Create (Var Owner: Pointer); Constructor Create (Var Owner: Pointer);
@ -143,11 +143,11 @@ Begin
LastMCIValue := ''; LastMCIValue := '';
InputPos := 0; InputPos := 0;
FillChar(OutBuffer, SizeOf(OutBuffer), 0);
OutBufPos := 0;
{$IFDEF WINDOWS} {$IFDEF WINDOWS}
FillChar(OutBuffer, SizeOf(OutBuffer), 0);
OutBufPos := 0;
If Not TBBSCore(Core).LocalMode Then If Not TBBSCore(Core).LocalMode Then
SocketEvent := WSACreateEvent; SocketEvent := WSACreateEvent;
{$ENDIF} {$ENDIF}
@ -168,13 +168,11 @@ End;
Procedure TBBSIO.BufAddChar (Ch: Char); Procedure TBBSIO.BufAddChar (Ch: Char);
Begin Begin
{$IFDEF WINDOWS}
OutBuffer[OutBufPos] := Ch; OutBuffer[OutBufPos] := Ch;
Inc (OutBufPos); Inc (OutBufPos);
If OutBufPos = TBBSIOBufferSize Then BufFlush; If OutBufPos = TBBSIOBufferSize Then BufFlush;
{$ENDIF}
Term.Process(Ch); Term.Process(Ch);
End; End;
@ -194,11 +192,19 @@ Begin
If Not TBBSCore(Core).LocalMode Then If Not TBBSCore(Core).LocalMode Then
TBBSCore(Core).Client.WriteBuf(OutBuffer, OutBufPos); TBBSCore(Core).Client.WriteBuf(OutBuffer, OutBufPos);
If Session.Pipe.Connected Then
Session.Pipe.SendToPipe(OutBuffer, OutBufPos);
OutBufPos := 0; OutBufPos := 0;
End; End;
{$ENDIF} {$ENDIF}
{$IFDEF UNIX} {$IFDEF UNIX}
If Session.Pipe.Connected Then
Session.Pipe.SendToPipe(OutBuffer, OutBufPos);
OutBufPos := 0;
Screen.BufFlush; Screen.BufFlush;
{$ENDIF} {$ENDIF}
End; End;

View File

@ -275,7 +275,7 @@ Begin
'C' : Node_Chat; 'C' : Node_Chat;
'P' : PageUserForChat; 'P' : PageUserForChat;
'S' : Send_Node_Message (3, CmdData, 0); 'S' : Send_Node_Message (3, CmdData, 0);
'W' : Show_Whos_Online; 'W' : WhosOnline;
End; End;
'O' : Case Cmd[2] of 'O' : Case Cmd[2] of
'S' : Session.Msgs.ToggleNewScan(True); 'S' : Session.Msgs.ToggleNewScan(True);

View File

@ -450,7 +450,7 @@ Begin
End Else End Else
If Str2 = '/WHO' Then Begin If Str2 = '/WHO' Then Begin
Session.io.AnsiClear; Session.io.AnsiClear;
Show_Whos_Online; WhosOnline;
Chat_Template; Chat_Template;
FullReDraw; FullReDraw;
End Else End Else

View File

@ -9,7 +9,7 @@ Uses
Function GetChatRecord (Node: Byte; Var Chat: ChatRec) : Boolean; Function GetChatRecord (Node: Byte; Var Chat: ChatRec) : Boolean;
Function IsUserOnline (UserName: String) : Word; Function IsUserOnline (UserName: String) : Word;
Procedure Show_Whos_Online; Procedure WhosOnline;
Procedure Send_Node_Message (MsgType: Byte; Data: String; Room: Byte); Procedure Send_Node_Message (MsgType: Byte; Data: String; Room: Byte);
Function CheckNodeMessages : Boolean; Function CheckNodeMessages : Boolean;
Procedure Set_Node_Action (Action: String); Procedure Set_Node_Action (Action: String);
@ -87,7 +87,7 @@ Begin
{$ENDIF} {$ENDIF}
End; End;
Procedure Show_Whos_Online; Procedure WhosOnline;
Var Var
TChat : ChatRec; TChat : ChatRec;
Count : Word; Count : Word;
@ -97,19 +97,12 @@ Begin
For Count := 1 to Config.INetTNNodes Do Begin For Count := 1 to Config.INetTNNodes Do Begin
Session.io.PromptInfo[1] := strI2S(Count); Session.io.PromptInfo[1] := strI2S(Count);
Assign (ChatFile, Config.DataPath + 'chat' + strI2S(Count) + '.dat'); If Not GetChatRecord (Count, TChat) Then Begin
{$I-} Reset(ChatFile); {$I+}
If IoResult <> 0 Then Begin
Session.io.OutFullLn (Session.GetPrompt(268)); Session.io.OutFullLn (Session.GetPrompt(268));
Continue; Continue;
End; End;
Read (ChatFile, TChat);
Close (ChatFile);
If TChat.Active and ((Not TChat.Invisible) or (TChat.Invisible and Session.User.Access(Config.AcsSeeInvis))) Then Begin 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[2] := TChat.Name;
Session.io.PromptInfo[3] := TChat.Action; Session.io.PromptInfo[3] := TChat.Action;
@ -141,7 +134,7 @@ Begin
Repeat Repeat
Session.io.OutFull (Session.GetPrompt(146)); Session.io.OutFull (Session.GetPrompt(146));
Str := Session.io.GetInput(3, 3, 12, ''); Str := Session.io.GetInput(3, 3, 12, '');
If Str = '?' Then Show_Whos_Online Else Break; If Str = '?' Then WhosOnline Else Break;
Until False; Until False;
ToNode := strS2I(Str); ToNode := strS2I(Str);
@ -230,8 +223,7 @@ Var
MsgFile : File of NodeMsgRec; MsgFile : File of NodeMsgRec;
SplitChat : Boolean; SplitChat : Boolean;
Begin Begin
Result := False; Result := False;
FileMode := 66;
Assign (MsgFile, Session.TempPath + 'chat.tmp'); Assign (MsgFile, Session.TempPath + 'chat.tmp');
@ -276,6 +268,12 @@ Begin
OpenUserChat(SplitChat, True, Msg.FromNode); OpenUserChat(SplitChat, True, Msg.FromNode);
End; End;
10: OpenUserChat(SplitChat, False, Msg.FromNode); 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; End;
If Result And (Msg.MsgType = 3) Then If Result And (Msg.MsgType = 3) Then

View File

@ -1081,7 +1081,7 @@ Begin
ThisUser.CallsToday := 0; ThisUser.CallsToday := 0;
ThisUser.DLsToday := 0; ThisUser.DLsToday := 0;
ThisUser.DLkToday := 0; ThisUser.DLkToday := 0;
ThisUser.TimeLeft := Security.Time ThisUser.TimeLeft := Security.Time;
End; End;
If Not Session.LocalMode And (ThisUser.Flags AND UserNoLastCall = 0) Then Begin 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 If (Session.TimeOffset = 0) or (Session.TimeOffset > ThisUser.TimeLeft) Then
Session.SetTimeLeft (ThisUser.TimeLeft); Session.SetTimeLeft (ThisUser.TimeLeft);
// check account expired -- DONE
// check password change -- DONE
// check auto-upgrades posts/calls/downloads/uploads/etc // check auto-upgrades posts/calls/downloads/uploads/etc
If DateValid(Session.User.ThisUser.Expires) Then If DateValid(Session.User.ThisUser.Expires) Then

View File

@ -29,7 +29,7 @@ Begin
Str := Session.io.GetInput(3, 3, 12, ''); 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; If Str = 'Q' Then Exit Else Break;
Until False; Until False;

View File

@ -373,7 +373,7 @@
; &1 = File base name ; &1 = File base name
203 |CR |11|&1 will NOT be scanned in new file scan!|CR 203 |CR |11|&1 will NOT be scanned in new file scan!|CR
; &1 = File base name ; &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. ; Displayed if file already exists when user trys to upload.
205 File already exists. 205 File already exists.
; Displayed before running uploads processor ; Displayed before running uploads processor
@ -938,11 +938,11 @@
; User2User sending chat request &1=User &2=Node ; User2User sending chat request &1=User &2=Node
482 |CR|15Sending chat request to |&1...|DE|DE|CR 482 |CR|15Sending chat request to |&1...|DE|DE|CR
; User2User chat mode starting ; 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 ; 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 ; 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 ; MsgBase quickscan header prompt
486 |CR|12Starting Quick Scan|CR 486 |CR|12Starting Quick Scan|CR
; MsgBase quickscan Scanning prompt ; MsgBase quickscan Scanning prompt

View File

@ -419,6 +419,7 @@ Begin
End; End;
{$IFDEF UNIX} {$IFDEF UNIX}
(*
Procedure Snoop; Procedure Snoop;
Begin Begin
If FocusCurrent <> FocusTelnet Then Exit; If FocusCurrent <> FocusTelnet Then Exit;
@ -453,7 +454,7 @@ Begin
SwitchFocus; SwitchFocus;
End; End;
End; End;
*)
Procedure DaemonEventSignal (Sig : LongInt); cdecl; Procedure DaemonEventSignal (Sig : LongInt); cdecl;
Begin Begin
Case Sig of Case Sig of
@ -592,7 +593,7 @@ Begin
End; End;
End; End;
#09 : SwitchFocus; #09 : SwitchFocus;
#13 : {$IFDEF UNIX}Snoop{$ENDIF}; // #13 : {$IFDEF UNIX}Snoop{$ENDIF};
#27 : Break; #27 : Break;
#32 : LocalLogin; #32 : LocalLogin;
End; End;

View File

@ -31,7 +31,7 @@ Const
#1,'³',#25,'K','³', #8,'°',#24,'°', #1,'³',#25,'K','³', #8,'°',#24, #1,'³',#25,'K','³', #8,'°',#24,'°', #1,'³',#25,'K','³', #8,'°',#24,
'°', #1,'À',#26,'K','Ä','Ù', #8,'°',#24,#26,'O','°',#24,#23,' ', #1, '°', #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', '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','/', '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', 'K','i','l','l',' ','U','s','e','r',#25, #2,'E','S','C','/','S','h',
'u','t','d','o','w','n',' ',#24); 'u','t','d','o','w','n',' ',#24);
@ -39,10 +39,6 @@ Begin
Console.LoadScreenImage(ImageData, ImageData_Length, ImageData_Width, 1, 1); Console.LoadScreenImage(ImageData, ImageData_Length, ImageData_Width, 1, 1);
//Console.WriteXY (25, 1, 113, strPadC(mysVersionText, 30, ' ')); //Console.WriteXY (25, 1, 113, strPadC(mysVersionText, 30, ' '));
{$IFDEF UNIX} Console.WriteXY (1, 25, 113, strPadC('SPACE/Local TELNET TAB/Switch ESC/Shutdown', 79, ' '));
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}
End; End;

View File

@ -28,7 +28,7 @@ Function CreateTelnet (Owner: TServerManager; Config: RecConfig; ND: TNodeData;
Type Type
TTelnetServer = Class(TServerClient) TTelnetServer = Class(TServerClient)
ND : TNodeData; ND : TNodeData;
Snooping : Boolean; // Snooping : Boolean;
Constructor Create (Owner: TServerManager; ND: TNodeData; CliSock: TIOSocket); Constructor Create (Owner: TServerManager; ND: TNodeData; CliSock: TIOSocket);
Procedure Execute; Override; Procedure Execute; Override;
Destructor Destroy; Override; Destructor Destroy; Override;
@ -46,7 +46,7 @@ Begin
Inherited Create(Owner, CliSock); Inherited Create(Owner, CliSock);
Self.ND := ND; Self.ND := ND;
Snooping := False; // Snooping := False;
End; End;
{$IFDEF WINDOWS} {$IFDEF WINDOWS}
@ -84,8 +84,12 @@ Begin
FillChar(SI, SizeOf(SI), 0); FillChar(SI, SizeOf(SI), 0);
FillChar(PI, SizeOf(PI), 0); FillChar(PI, SizeOf(PI), 0);
SI.dwFlags := STARTF_USESHOWWINDOW; SI.dwFlags := STARTF_USESHOWWINDOW;
SI.wShowWindow := SW_SHOWMINNOACTIVE;
If bbsConfig.inetTNHidden Then
SI.wShowWindow := SW_HIDE
Else
SI.wShowWindow := SW_SHOWMINNOACTIVE;
If CreateProcess(NIL, PChar(@Cmd[1]), If CreateProcess(NIL, PChar(@Cmd[1]),
NIL, NIL, True, Create_New_Console + Normal_Priority_Class, NIL, NIL, SI, PI) Then 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); bRead := Proc.Output.Read(Buffer, BufferSize);
Client.WriteBufEscaped (Buffer, bRead); Client.WriteBufEscaped (Buffer, bRead);
If Snooping Then // If Snooping Then
Term.ProcessBuf(Buffer[0], bRead); // Term.ProcessBuf(Buffer[0], bRead);
End; End;
End Else End Else
If Client.DataWaiting Then Begin If Client.DataWaiting Then Begin

View File

@ -40,7 +40,7 @@
Import_FIDONET.NA = false Import_FIDONET.NA = false
Import_FILEBONE.NA = false Import_FILEBONE.NA = false
Import_FILES.BBS = false Import_FILES.BBS = true
MassUpload = false MassUpload = false
GenerateTopLists = false GenerateTopLists = false

View File

@ -40,6 +40,7 @@ Uses
m_DateTime, m_DateTime,
m_Output, m_Output,
m_Input, m_Input,
m_Pipe_Disk,
bbs_Common, bbs_Common,
bbs_Core, bbs_Core,
bbs_NodeInfo, bbs_NodeInfo,
@ -233,6 +234,8 @@ Begin
Session.TempPath := Config.SystemPath + 'temp' + strI2S(Session.NodeNum) + PathChar; Session.TempPath := Config.SystemPath + 'temp' + strI2S(Session.NodeNum) + PathChar;
Session.Pipe := TPipeDisk.Create(Config.DataPath, False, Session.NodeNum);
{$I-} {$I-}
MkDir (Config.SystemPath + 'temp' + strI2S(Session.NodeNum)); MkDir (Config.SystemPath + 'temp' + strI2S(Session.NodeNum));
{$I+} {$I+}

View File

@ -1,5 +1,12 @@
Program NodeSpy; Program NodeSpy;
// page chat
// user editor
// split chat
// auto snoop
// local login
// terminal mode
{$I M_OPS.PAS} {$I M_OPS.PAS}
Uses Uses
@ -22,9 +29,21 @@ Uses
Const Const
HiddenNode = 255; 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 Var
NodeInfo : Array[1..255] of PNodeInfo;
ChatFile : File of ChatRec; ChatFile : File of ChatRec;
Chat : ChatRec; Chat : ChatRec;
ConfigFile : File of RecConfig; ConfigFile : File of RecConfig;
@ -35,6 +54,75 @@ Var
Screen : TOutput; Screen : TOutput;
Keyboard : TInput; 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; Function ShowMsgBox (BoxType: Byte; Str: String) : Boolean;
Var Var
Len : Byte; Len : Byte;
@ -119,6 +207,7 @@ Begin
MsgBox.Free; MsgBox.Free;
Screen.CursorXY (SavedX, SavedY); Screen.CursorXY (SavedX, SavedY);
Screen.TextAttr := SavedA; Screen.TextAttr := SavedA;
End; End;
@ -277,8 +366,8 @@ Begin
Screen.TextAttr := 7; Screen.TextAttr := 7;
Screen.ClearScreen; Screen.ClearScreen;
Screen.WriteXY (1, 1, 31, strRep(' ', 79)); Screen.WriteXY ( 1, 1, 31, strRep(' ', 79));
Screen.WriteXY (2, 1, 31, 'Chat mode engaged'); Screen.WriteXY ( 2, 1, 31, 'Chat mode engaged');
Screen.WriteXY (71, 1, 31, 'ESC/Quit'); Screen.WriteXY (71, 1, 31, 'ESC/Quit');
Screen.CursorXY (1, 3); Screen.CursorXY (1, 3);
@ -355,6 +444,7 @@ Begin
Erase(fIn); Erase(fIn);
Screen.TextAttr := 7; Screen.TextAttr := 7;
Screen.ClearScreen; Screen.ClearScreen;
End; End;
@ -378,43 +468,42 @@ Var
Screen.WriteXY ( 1, 25, Config.StatusColor1, strRep(' ', 79)); Screen.WriteXY ( 1, 25, Config.StatusColor1, strRep(' ', 79));
Screen.WriteXY ( 2, 25, Config.StatusColor1, 'User'); Screen.WriteXY ( 2, 25, Config.StatusColor1, 'User');
Screen.WriteXY ( 7, 25, Config.StatusColor2, Chat.Name); 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.SetWindow ( 1, 1, 80, 24, True);
Screen.CursorXY (SX, SY); Screen.CursorXY (SX, SY);
Screen.TextAttr := SA; Screen.TextAttr := SA;
End; End;
End; End;
Begin Begin
WriteLn; GetChatRecord(Node, Chat);
WriteLn('Requesting snoop session for node ', Node, '...');
WriteLn; 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); SendNodeMessage(Node, 11);
Pipe := TPipeDisk.Create(Config.DataPath, True, Node); Pipe := TPipeDisk.Create(Config.DataPath, True, Node);
If Not Pipe.ConnectPipe(1500) Then Begin If Not Pipe.ConnectPipe(1500) Then Begin
WriteLn('NodeSpy was not able to establish a snoop session. Sessions'); ShowMsgBox (0, 'Unable to establish a session. Try again');
WriteLn('cannot be created if a user is in a door or a file transfer.');
Pipe.Free; Pipe.Free;
Exit; Exit;
End; End;
WriteLn('Connection established'); Term := TTermAnsi.Create(Screen);
Keyboard := TInput.Create; Screen.SetWindowTitle('[NodeSpy] Snooping ' + strI2S(Node));
Screen := TOutput.Create(True);
Term := TTermAnsi.Create(Screen);
Screen.SetWindowTitle('Snooping node ' + strI2S(Node));
DrawStatus; DrawStatus;
Update := TimerSet(UpdateTimer); Update := TimerSet(UpdateNode);
While Pipe.Connected Do Begin While Pipe.Connected Do Begin
Pipe.ReadFromPipe(Buffer, SizeOf(Buffer), BufRead); Pipe.ReadFromPipe(Buffer, SizeOf(Buffer), BufRead);
@ -443,7 +532,7 @@ Begin
DrawStatus; DrawStatus;
Update := TimerSet(UpdateTimer); Update := TimerSet(UpdateNode);
End; End;
End; End;
@ -457,88 +546,219 @@ Begin
Pipe.Disconnect; Pipe.Disconnect;
Pipe.Free; Pipe.Free;
Term.Free; Term.Free;
Screen.Free;
WriteLn;
WriteLn;
WriteLn ('Session closed');
End; End;
Procedure ShowWhosOnline; Procedure UpdateOnlineStatus;
Var Var
Count : Word; Count : LongInt;
Begin Begin
WriteLn; For Count := 1 to Config.inetTNNodes Do
WriteLn('### UserName Action'); If GetChatRecord(Count, Chat) and (Chat.Active) Then Begin
WriteLn(strRep('=', 79)); NodeInfo[Count]^.Node := Count;
NodeInfo[Count]^.User := Chat.Name;
For Count := 1 to Config.INetTNNodes Do Begin NodeInfo[Count]^.Action := Chat.Action;
If GetChatRecord(Count, Chat) Then Begin End Else Begin
WriteLn (strPadL(strI2S(Count), 3, '0') + ' ' + NodeInfo[Count]^.Node := Count;
strPadR(Chat.Name, 25, ' ') + ' ' + NodeInfo[Count]^.User := 'Waiting';
strPadR(Chat.Action, 45, ' ')); NodeInfo[Count]^.Action := 'Waiting';
End Else End;
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');
End; End;
Procedure MainMenu;
Var Var
NodeNum : Byte; StatTotalDays : LongInt = 0;
{$IFDEF UNIX} StatTodayCalls : LongInt = 0;
Info : Stat; StatTotalCalls : LongInt = 0;
{$ENDIF} StatTodayNewUsers : LongInt = 0;
Begin StatTotalNewUsers : LongInt = 0;
{$IFDEF UNIX} StatTodayPosts : LongInt = 0;
If fpStat('nodespy', Info) = 0 Then Begin StatTotalPosts : LongInt = 0;
fpSetGID (Info.st_GID); StatTodayEmail : LongInt = 0;
fpSetUID (Info.st_UID); 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; End;
{$ENDIF}
Assign (ConfigFile, 'mystic.dat'); Procedure UpdateStats;
Reset (ConfigFile); Var
HistFile : File of RecHistory;
Hist : RecHistory;
Begin
FileMode := 66;
If IoResult <> 0 Then Begin Assign (HistFile, Config.DataPath + 'history.dat');
BasePath := GetENV('mysticbbs'); Reset (HistFile);
If BasePath <> '' Then BasePath := DirSlash(BasePath); If IoResult <> 0 Then Exit;
Assign (ConfigFile, BasePath + 'mystic.dat'); StatTotalDays := 0;
Reset (ConfigFile);
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;
End; End;
Read (ConfigFile, Config); Var
Close (ConfigFile); Count : Byte;
Begin
DrawNodeSpyScreen;
UpdateStats;
UpdateOnlineStatus;
If Config.DataChanged <> mysDataChanged Then Begin DrawNodes;
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;
DirCreate(Config.SystemPath + 'temp' + strI2S(HiddenNode)); NodeTimer := TimerSet(UpdateNode);
If ParamCount < 1 Then Repeat
ShowWhosOnline If Keyboard.KeyWait(1000) Then
Else Begin Case Keyboard.ReadKey of
NodeNum := strS2I(ParamStr(1)); #00 : Case Keyboard.ReadKey of
#71 : Begin
TopPage := 1;
CurNode := 1;
If (NodeNum > 0) and (NodeNum <= Config.INetTNNodes) Then DrawNodes;
SnoopNode(NodeNum); End;
End; #72 : If CurNode > 1 Then Begin
End. 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.

View File

@ -11,6 +11,13 @@
{$PACKRECORDS 1} {$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 Const
mysSoftwareID = 'Mystic'; // no idea mysSoftwareID = 'Mystic'; // no idea
mysCopyYear = '1997-2012'; // its been a long time! mysCopyYear = '1997-2012'; // its been a long time!
@ -259,7 +266,8 @@ Type
inetNNTPDupes : Byte; inetNNTPDupes : Byte;
inetNNTPTimeOut : Word; inetNNTPTimeOut : Word;
// UNSORTED // UNSORTED
Reserved : Array[1..846] of Char; inetTNHidden : Boolean;
Reserved : Array[1..845] of Char;
End; End;
Const Const
@ -769,5 +777,8 @@ Type
{ 8 = user 2 user page } { 8 = user 2 user page }
{ 9 = user 2 user forced } { 9 = user 2 user forced }
{ 10 = chat accepted } { 10 = chat accepted }
{ 11 = start pipe session }
{ 12 = end pipe session }
{ 13 = terminte node }
Room : Byte; { Chat room number. 0 = chat broadcast } Room : Byte; { Chat room number. 0 = chat broadcast }
End; End;

View File

@ -19,6 +19,8 @@ BUGS AND POSSIBLE ISSUES
FPC BUG? DirAttr is suspect in MPL is it 1 byte or 4 in size? FPC BUG? DirAttr is suspect in MPL is it 1 byte or 4 in size?
! View archive not working if its external view? [Griffin] ! View archive not working if its external view? [Griffin]
! Test MIS blocking features or just rewrite MIS completely. ! 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 FUTURE / IDEAS / WORK IN PROGRESS / NOTES
========================================= =========================================