diff --git a/mystic/bbs_cfg_menuedit.pas b/mystic/bbs_cfg_menuedit.pas index 09c742b..7cd1c0c 100644 --- a/mystic/bbs_cfg_menuedit.pas +++ b/mystic/bbs_cfg_menuedit.pas @@ -30,7 +30,7 @@ Type End; Const - Num_Cmds = 100; + Num_Cmds = 101; MenuCmds : Array[1..Num_Cmds] of CmdRec = ( // AUTOSIG MENU COMMANDS ( Name: 'AE'; Desc: 'Autosig editor' ), @@ -89,6 +89,7 @@ Const ( Name: 'MC'; Desc: 'Check e-mail' ), ( Name: 'MD'; Desc: 'Set msg newscan date' ), ( Name: 'MG'; Desc: 'Message group change' ), + ( Name: 'ML'; Desc: 'Nodelist browser' ), ( Name: 'MM'; Desc: 'Send mass e-mail' ), ( Name: 'MN'; Desc: 'Message new scan' ), ( Name: 'MP'; Desc: 'Post a message' ), diff --git a/mystic/bbs_edit_ansi.pas b/mystic/bbs_edit_ansi.pas index f8bf340..1a89fd9 100644 --- a/mystic/bbs_edit_ansi.pas +++ b/mystic/bbs_edit_ansi.pas @@ -2,17 +2,16 @@ Unit bbs_Edit_Ansi; {$I M_OPS.PAS} -Interface +// modes +// viewer +// msgedit +// ansiedit -// Future online pipe/ansi editor and new full screen editor. -// Will be the most badass editor to ever exist. +Interface Uses bbs_MsgBase_ANSI; -Const - MaxLines = 1000; - Type TEditorANSI = Class Owner : Pointer; @@ -46,6 +45,8 @@ Type Procedure TrimLine (Var Line; LineSize: Byte); Procedure DeleteLine (Line: LongInt); Procedure InsertLine (Line: LongInt); + Function GetLineText (Line: Word) : String; + Procedure SetLineText (Line: LongInt; Str: String); Procedure FindLastLine; Procedure Reformat; Procedure LocateCursor; @@ -71,6 +72,7 @@ Implementation Uses m_Strings, bbs_Core, + bbs_Common, bbs_Ansi_MenuBox; Constructor TEditorANSI.Create (Var O: Pointer); @@ -105,11 +107,33 @@ Begin ANSI.Free; End; +Function TEditorANSI.GetLineText (Line: Word) : String; +Var + Count : Word; +Begin + Result := ''; + + For Count := 1 to GetLineLength(ANSI.Data[Line], RowSize) Do + Result := Result + ANSI.Data[Line][Count].Ch; +End; + +Procedure TEditorANSI.SetLineText (Line: LongInt; Str: String); +Var + Count : Byte; +Begin + FillChar (ANSI.Data[Line], SizeOf(ANSI.Data[Line]), 0); + + For Count := 1 to Length(Str) Do Begin + ANSI.Data[Line][Count].Ch := Str[Count]; + ANSI.Data[Line][Count].Attr := CurAttr; + End; +End; + Procedure TEditorANSI.FindLastLine; Var Count : LongInt; Begin - LastLine := MaxLines; + LastLine := mysMaxMsgLines; While (LastLine > 1) And IsBlankLine(ANSI.Data[LastLine], 80) Do Dec(LastLine); @@ -176,10 +200,10 @@ Procedure TEditorANSI.DeleteLine (Line: LongInt); Var Count : LongInt; Begin - For Count := Line to MaxLines - 1 Do + For Count := Line to mysMaxMsgLines - 1 Do ANSI.Data[Count] := ANSI.Data[Count + 1]; - FillChar (ANSI.Data[MaxLines], SizeOf(RecAnsiBufferLine), #0); + FillChar (ANSI.Data[mysMaxMsgLines], SizeOf(RecAnsiBufferLine), #0); If LastLine > 1 Then Dec(LastLine); End; @@ -188,12 +212,12 @@ Procedure TEditorANSI.InsertLine (Line: LongInt); Var Count : LongInt; Begin - For Count := MaxLines DownTo Line + 1 Do + For Count := mysMaxMsgLines DownTo Line + 1 Do ANSI.Data[Count] := ANSI.Data[Count - 1]; FillChar(ANSI.Data[Line], SizeOf(RecAnsiBufferLine), #0); - If LastLine < MaxLines Then Inc(LastLine); + If LastLine < mysMaxMsgLines Then Inc(LastLine); End; Function TEditorANSI.GetWrapPos (Var Line; LineSize: Byte; WrapPos: Byte) : Byte; @@ -255,7 +279,7 @@ Begin StartY := CurY; StartLine := Count; - While Count <= MaxLines Do Begin + While Count <= mysMaxMsgLines Do Begin If Count > LastLine Then LastLine := Count; FillChar (TempStr, SizeOf(TempStr), #0); @@ -265,7 +289,7 @@ Begin If IsBlankLine(TempStr, 255) Then Begin If Count < LastLine Then Begin InsertLine(Count); - EndLine := MaxLines; + EndLine := mysMaxMsgLines; End Else EndLine := Count; @@ -373,7 +397,7 @@ Begin CurY := 1; ClearEOL := RowSize >= 79; - LoadANSI; + //LoadANSI; FindLastLine; DrawPage(1, WinSize, False); @@ -457,7 +481,7 @@ Var Begin NewTop := TopLine + (WinSize DIV 2) + 1; - While NewTop >= MaxLines Do + While NewTop >= mysMaxMsgLines Do Dec (NewTop, 2); CurY := CurLine - NewTop + 1; @@ -488,7 +512,7 @@ Function TEditorANSI.LineDown (Reset: Boolean) : Boolean; Begin Result := False; - If CurLine >= MaxLines Then Exit; + If CurLine >= mysMaxMsgLines Then Exit; Inc (CurLine); Inc (CurY); @@ -766,7 +790,7 @@ Procedure TEditorANSI.DoEnter; Var TempLine : RecAnsiBufferLine; Begin - If InsertMode and IsBlankLine(ANSI.Data[MaxLines], 80) Then Begin + If InsertMode and IsBlankLine(ANSI.Data[mysMaxMsgLines], 80) Then Begin If CurX > CurLength Then Begin InsertLine (CurLine + 1); @@ -835,6 +859,8 @@ Begin DoChar(Ch); End; End; + + Result := True; End; End. diff --git a/mystic/bbs_edit_full.pas b/mystic/bbs_edit_full.pas index 70e0538..7ee31b7 100644 --- a/mystic/bbs_edit_full.pas +++ b/mystic/bbs_edit_full.pas @@ -4,7 +4,7 @@ Unit bbs_Edit_Full; Interface -Function AnsiEditor (Var Lines: SmallInt; WrapPos: Byte; MaxLines: SmallInt; Forced: Boolean; Template: String; Var Subj: String) : Boolean; +Function FullEditor (Var Lines: SmallInt; WrapPos: Byte; MaxLines: SmallInt; Forced: Boolean; Template: String; Var Subj: String) : Boolean; Implementation @@ -18,7 +18,7 @@ Begin Session.io.BufAddStr(S + #13#10); End; -Function AnsiEditor (Var Lines: Integer; WrapPos: Byte; MaxLines: Integer; Forced: Boolean; Template: String; Var Subj: String) : Boolean; +Function FullEditor (Var Lines: Integer; WrapPos: Byte; MaxLines: Integer; Forced: Boolean; Template: String; Var Subj: String) : Boolean; Const MaxCutText = 100; Type @@ -984,4 +984,4 @@ Begin Dispose (CutText[A]); End; -End. \ No newline at end of file +End. diff --git a/mystic/bbs_general.pas b/mystic/bbs_general.pas index 2b4ca8e..fcb8d47 100644 --- a/mystic/bbs_general.pas +++ b/mystic/bbs_general.pas @@ -12,7 +12,11 @@ Uses bbs_SysopChat, {$ENDIF} bbs_Common, + {$IFDEF NEWEDITOR} + bbs_Edit_ANSI, + {$ELSE} bbs_Edit_Full, + {$ENDIF} bbs_Edit_Line; Function Editor (Var Lines: SmallInt; MaxLen, MaxLine: SmallInt; Forced: Boolean; Template: String; Var Subj: String) : Boolean; @@ -52,10 +56,38 @@ Uses bbs_MsgBase_Ansi, bbs_NodeInfo; +{$IFDEF NEWEDITOR} +Function AnsiEditor (Var Lines: SmallInt; WrapPos: Byte; MaxLines: SmallInt; Forced: Boolean; Template: String; Var Subj: String) : Boolean; +Var + Editor : TEditorANSI; + Count : LongInt; +Begin + Editor := TEditorANSI.Create(Pointer(Session)); + + For Count := 1 to Lines Do + Editor.SetLineText (Count, Session.Msgs.MsgText[Count]); + + Result := Editor.Edit; + + If Result Then Begin + For Count := 1 to Editor.LastLine Do + Session.Msgs.MsgText[Count] := Editor.GetLineText(Count); + + Lines := Editor.LastLine; + End; + + Editor.Free; +End; +{$ENDIF} + Function Editor (Var Lines: SmallInt; MaxLen, MaxLine: SmallInt; Forced: Boolean; Template: String; Var Subj: String) : Boolean; Begin If (Session.io.Graphics > 0) and ((Session.User.ThisUser.EditType = 1) or ((Session.User.ThisUser.EditType = 2) and Session.io.GetYN(Session.GetPrompt(106), True))) Then + {$IFDEF NEWEDITOR} Editor := AnsiEditor(Lines, MaxLen, MaxLine, Forced, Template, Subj) + {$ELSE} + Editor := FullEditor(Lines, MaxLen, MaxLine, Forced, Template, Subj) + {$ENDIF} Else Editor := LineEditor(Lines, MaxLen, MaxLine, False, Forced, Subj); End; diff --git a/mystic/bbs_menus.pas b/mystic/bbs_menus.pas index cb0bf07..6adf64b 100644 --- a/mystic/bbs_menus.pas +++ b/mystic/bbs_menus.pas @@ -258,6 +258,7 @@ Begin 'C' : Session.Msgs.CheckEMail; 'D' : Session.Msgs.SetMessagePointers; 'G' : Session.Msgs.MessageGroupChange (CmdData, True, True); + 'L' : Session.Msgs.NetMailLookup (True, '', ''); 'M' : Session.Msgs.SendMassEmail; 'N' : Session.Msgs.MessageNewScan (strUpper(CmdData)); 'P' : Session.Msgs.PostMessage (False, CmdData); diff --git a/mystic/bbs_msgbase_ansi.pas b/mystic/bbs_msgbase_ansi.pas index bf0274c..dd42ab4 100644 --- a/mystic/bbs_msgbase_ansi.pas +++ b/mystic/bbs_msgbase_ansi.pas @@ -55,7 +55,6 @@ Type Procedure WriteLine (Line: Word; Flush: Boolean); Procedure DrawLine (Y, Line: Word; Flush: Boolean); Procedure DrawPage (pStart, pEnd, pLine: Word); - Function GetLineText (Line: Word) : String; Procedure SetLineColor (Attr, Line: Word); Procedure RemoveLine (Line: Word); End; @@ -241,9 +240,7 @@ Begin If Offset = 0 Then Offset := 1; If CurX + Offset > 80 Then Begin - NewPos := 80; -// NewPos := (CurX + Offset) - 80; -// Inc (CurY); + NewPos := 80; End Else NewPos := CurX + Offset; @@ -459,18 +456,6 @@ Begin Session.io.BufFlush; End; -Function TMsgBaseAnsi.GetLineText (Line: Word) : String; -Var - Count : Word; -Begin - Result := ''; - - If Line > Lines Then Exit; - - For Count := 1 to 80 Do - Result := Result + Data[Line][Count].Ch; -End; - Procedure TMsgBaseAnsi.SetLineColor (Attr, Line: Word); Var Count : Word; @@ -489,4 +474,4 @@ Begin Dec (Lines); End; -End. \ No newline at end of file +End. diff --git a/mystic/bbs_nodelist.pas b/mystic/bbs_nodelist.pas index d04872f..3809166 100644 --- a/mystic/bbs_nodelist.pas +++ b/mystic/bbs_nodelist.pas @@ -74,10 +74,9 @@ Begin A := Pos(':', SearchStr); B := Pos('/', SearchStr); - If (A = 0) or (B <= A) Then - AddrSearch := False - Else Begin - AddrSearch := True; + AddrSearch := Not (A = 0) or (B <= A); + + If AddrSearch Then Begin SearchZone := Copy(SearchStr, 1, A - 1); SearchNet := Copy(SearchStr, A + 1, B - 1 - A); SearchNode := Copy(SearchStr, B + 1, 255); diff --git a/mystic/default.txt b/mystic/default.txt index 2a0dedb..a3d12ce 100644 --- a/mystic/default.txt +++ b/mystic/default.txt @@ -102,7 +102,7 @@ 041 |CL|09Ú|$D77Ä¿|CR³|17 ± |15File Listing|$L61|FB |16|01³|CR|09À|01|$D77ÄÙ ; Standard file list: #/filename: ; &1 = filenum, &2 = filename, &3 = tag char &4 = size &5 = date &6 = DLs -042 |07|&1|12|&3|15|$R58|&2 |09|$L06|&4 |&5 +042 |07|&1|12|&3|15|$R57|&2 |09|$L07|&4 |&5 ; Standard file list: description/info ; &1 = size, &2 = date, &3 = DLs, &4 = desc, &5 = uploader 043 |07|$D29 |&4 @@ -823,7 +823,7 @@ 430 ; Lightbar file list: #/filename: ; &1 = filenum, &2 = filename, &3 = tag char &4 = size &5 = date &6 = DLs -431 |07|&1|12|&3|15|$R58|&2 |09|$L06|&4 |&5 +431 |07|&1|12|&3|15|$R57|&2 |09|$L07|&4 |&5 ; Lightbar file list: highlight on: &1 = #, &2 = filename, &3 = tag char 432 |16 |01|23|&1|16|12|&3 ; Lightbar file list: highlight off: &1 = #, &2 = filename, &3 = tag char diff --git a/mystic/mis.pas b/mystic/mis.pas index 507524a..d4136c2 100644 --- a/mystic/mis.pas +++ b/mystic/mis.pas @@ -70,9 +70,7 @@ Var TopPage : Integer; BarPos : Integer; NodeData : TNodeData; - {$IFDEF UNIX} DaemonMode : Boolean = False; - {$ENDIF} {$I MIS_ANSIWFC.PAS} @@ -89,9 +87,13 @@ Begin If DatLoc <> '' Then DatLoc := DirSlash(DatLoc); If Not FileConfig.Open(DatLoc + 'mystic.dat', fmOpen, fmReadWrite + fmDenyNone, SizeOf(RecConfig)) Then Begin - WriteLn; - WriteLn ('ERROR: Unable to read MYSTIC.DAT. This file must exist in the same'); - WriteLn ('directory as MIS'); + If Not DaemonMode Then Begin + Console.WriteLine (#13#10 + 'ERROR: Unable to read MYSTIC.DAT. This file must exist in the same'); + Console.WriteLine ('directory as MIS'); + + Keyboard.Free; + Console.Free; + End; FileConfig.Free; diff --git a/mystic/mis_client_telnet.pas b/mystic/mis_client_telnet.pas index 48de631..e1c31c0 100644 --- a/mystic/mis_client_telnet.pas +++ b/mystic/mis_client_telnet.pas @@ -1,16 +1,26 @@ -{$I M_OPS.PAS} - Unit MIS_Client_Telnet; +{$I M_OPS.PAS} + Interface +{$IFDEF LINUX} + {$IFDEF CPU32} + {$LinkLib libutil.a} + {$ENDIF} + {$IFDEF CPU64} + {$LinkLib libutil_64.a} + {$ENDIF} +{$ENDIF} + Uses - {$IFDEF UNIX} - Unix, - Classes, + {$IFDEF DARWIN} Process, - SysUtils, - m_FileIO, + m_DateTime, + {$ENDIF} + {$IFDEF UNIX} + BaseUnix, + Unix, {$ENDIF} {$IFDEF WINDOWS} Windows, @@ -23,13 +33,16 @@ Uses MIS_NodeData, MIS_Server; +{$IFDEF LINUX} + function forkpty(__amaster:Plongint; __name:Pchar; __termp:Pointer; __winp:Pointer):longint;cdecl;external 'c' name 'forkpty'; +{$ENDIF} + Function CreateTelnet (Owner: TServerManager; Config: RecConfig; ND: TNodeData; CliSock: TIOSocket) : TServerClient; -{ must match server create or there will be access violations } Type TTelnetServer = Class(TServerClient) - ND : TNodeData; -// Snooping : Boolean; + ND : TNodeData; + Constructor Create (Owner: TServerManager; ND: TNodeData; CliSock: TIOSocket); Procedure Execute; Override; Destructor Destroy; Override; @@ -46,8 +59,7 @@ Constructor TTelnetServer.Create (Owner: TServerManager; ND: TNodeData; CliSock: Begin Inherited Create(Owner, CliSock); - Self.ND := ND; -// Snooping := False; + Self.ND := ND; End; {$IFDEF WINDOWS} @@ -107,7 +119,87 @@ Begin End; {$ENDIF} -{$IFDEF UNIX} +{$IFDEF LINUX} +Procedure TTelnetServer.Execute; +Var + Num : LongInt; + NI : TNodeInfoRec; + PID : LongInt; + PTYFD : LongInt; + RDFDSET : TFDSet; + Count : LongInt; + Buffer : Array[1..8 * 1024] of Char; + MaxFD : LongInt; +Begin + Client.FTelnetServer := True; + + Num := ND.GetFreeNode; + + PID := ForkPTY (@PTYFD, NIL, NIL, NIL); + + If PID = 0 Then Begin + fpSetSID; + //tcSetPGrp (0, fpGetPID); + + fpExecLP ('./mystic', ['-n' + strI2S(Num), '-TID' + strI2S(Client.FSocketHandle), '-IP' + Client.FPeerIP, '-HOST' + Client.FPeerName]); + + Exit; + End Else + If PID = -1 Then + Exit; + + FillChar (NI, SizeOf(NI), 0); + + NI.Num := Num; + NI.Busy := True; + NI.IP := Client.FPeerIP; + NI.User := 'Unknown'; + NI.Action := 'Logging In'; + + ND.SetNodeInfo(Num, NI); + + MaxFD := Client.FSocketHandle; + + If PTYFD > Client.FSocketHandle Then MaxFD := PTYFD; + + Repeat + fpFD_ZERO (RDFDSET); + fpFD_SET (PTYFD, RDFDSET); + fpFD_SET (Client.FSocketHandle, RDFDSET); + + If fpSelect (MaxFD + 1, @RDFDSET, NIL, NIL, 3000) < 0 Then Break; + + If fpFD_ISSET(PTYFD, RDFDSET) = 1 Then Begin + Count := fpRead (PTYFD, Buffer, SizeOf(Buffer)); + + If Count <= 0 Then Break; + + Client.WriteBuf (Buffer, Count); + End; + + If fpFD_ISSET(Client.FSocketHandle, RDFDSET) = 1 Then Begin + Count := Client.ReadBuf (Buffer, SizeOf(Buffer)); + + If Count < 0 Then Break; + + If fpWrite (PTYFD, Buffer, Count) <> Count Then Break; + End; + Until False; + + fpClose (PTYFD); + + NI.Busy := False; + NI.IP := ''; + NI.User := ''; + NI.Action := ''; + + ND.SetNodeInfo(Num, NI); + + FileErase (bbsConfig.DataPath + 'chat' + strI2S(NI.Num) + '.dat'); +End; +{$ENDIF} + +{$IFDEF DARWIN} Procedure TTelnetServer.Execute; Var Cmd : String; @@ -152,7 +244,7 @@ Begin Proc.Input.Write(Buffer, bWrite); End; End Else - Sleep(10); + WaitMS(10); End; Proc.Free; diff --git a/mystic/mystic.pas b/mystic/mystic.pas index 457e41d..49d203a 100644 --- a/mystic/mystic.pas +++ b/mystic/mystic.pas @@ -23,8 +23,6 @@ Program Mystic; {$I M_OPS.PAS} -{.$DEFINE EDITWORK} - Uses {$IFDEF DEBUG} HeapTrc, @@ -46,12 +44,12 @@ Uses bbs_Common, bbs_Core, bbs_NodeInfo, - {$IFDEF EDITWORK} + {$IFDEF NEWEDITOR} bbs_edit_ansi, {$ENDIF} bbs_Cfg_Main; -{$IFDEF EDITWORK} +{$IFDEF NEWEDITOR} Procedure TestEditor; Var T : TEditorANSI; @@ -486,9 +484,9 @@ Begin Set_Node_Action (Session.GetPrompt(345)); - {$IFDEF EDITWORK} - TestEditor; - Halt(0); + {$IFDEF NEWEDITOR} + //TestEditor; + //Halt(0); {$ENDIF} Session.User.UserLogon1 (UserName, Password, Script); diff --git a/mystic/todo.pas b/mystic/todo.pas index 2ec4826..efd1443 100644 --- a/mystic/todo.pas +++ b/mystic/todo.pas @@ -27,6 +27,12 @@ BUGS AND POSSIBLE ISSUES FUTURE / IDEAS / WORK IN PROGRESS / NOTES ========================================= +- Option for QuickScan that only prints a base if it has new messages. +- QWK via email +- Either add Public/Private fusion type message base or allow reply via + email or netmail option. +- mUTIL scans MSGS directory and auto-creates anything that has data files + not related to a BBS message base - Blind upload for single file upload (also message upload) - Email validation - Recode FCHECK into MUTIL, but also add the option to phsyically delete the diff --git a/mystic/whatsnew.txt b/mystic/whatsnew.txt index 4ca188b..ee1a42e 100644 --- a/mystic/whatsnew.txt +++ b/mystic/whatsnew.txt @@ -2584,7 +2584,7 @@ - ! WordGet will now trim spaces off the beginning of the string, but only + ! MPL WordGet will now trim spaces off the beginning of the string, but only when space is used as a word separator. When something other than a space is used, it will not trim anything. This fixes a problem that could cause the result to be incorrect when using non-space separators. @@ -2596,9 +2596,10 @@ than just nodes themselves. To enable this feature, simply copy a raw FTN-style nodelist into the - data directory and name it "nodelist.txt". Mystic is using a raw - uncompiled nodelist, because of lack of compilers and advancement in CPU - speed makes it much more feasible these days. + data directory and name it "nodelist.txt". Mystic is using raw uncompiled + nodelists. The reason for this is due to a lack of nodelist compilers, + standards that are behind the times, and when combined with faster CPUs + and shrinking nodelist size it seems to make the most sense. A new display file called "nodesearch.xxx" will be displayed if it exists before the netmail address prompt, and when the user selects ?/help at the @@ -2641,4 +2642,19 @@ ; &1=msgs imported &2=msgs failed &3=bases added to scan &4=bases removed 503 |10SUCCESS|01.|CR|CR|11- |03Posted |11|&1 |03new messages (|11|&2 |03failed)|CR|11- |03Added |11|&3 |03bases to new scan (|11|&4 |03removed).|CR|CR|PA + + Added new menu command ML (Nodelist Browser). This kicks off the new + nodelist browser, just in case someone would like to use it outside of + sending a netmail. + + + Complete rewrote the MIS telnet server for Unix platforms. It should be + much faster now. There is no reason not to use MIS now at all and you + should switch to it as soon as possible - at least if you want to take + advantage of future features that will require MIS (new event system, FTN + mailer and tosser, etc). + + ! Fixed all known issues with MIS and STDIO redirection. DOSEMU works + great now, and is pretty easy to setup. Check the new section in the + Linux installation document for a tutorial on how to set up a DOS door + in DOSEMU with Mystic! +