diff --git a/mystic/bbs_cfg_msgbase.pas b/mystic/bbs_cfg_msgbase.pas index 4b3d471..df2044b 100644 --- a/mystic/bbs_cfg_msgbase.pas +++ b/mystic/bbs_cfg_msgbase.pas @@ -121,7 +121,7 @@ Begin Form.AddStr ('R', ' Read ACS' , 7, 13, 19, 13, 10, 30, 30, @MBase.ReadACS, Topic + 'Access required to read messages'); Form.AddStr ('C', ' Post ACS' , 7, 14, 19, 14, 10, 30, 30, @MBase.PostACS, Topic + 'Access required to post messages'); Form.AddStr ('Y', ' Sysop ACS' , 6, 15, 19, 15, 11, 30, 30, @MBase.SysopACS, Topic + 'Access required for Sysop access'); - Form.AddNone ('D', ' Net Address' , 4, 16, 19, 16, 13, Topic + 'NetMail Address'); + Form.AddNone ('D', ' Net Address' , 4, 16, 19, 16, 13, Topic + 'Net/EchoMail Address'); Form.AddNone ('7', ' Export To' , 6, 17, 19, 17, 11, Topic + 'Export messages to these nodes'); Form.AddStr ('I', ' Origin' , 9, 18, 19, 18, 8, 30, 50, @MBase.Origin, Topic + 'Message base origin line'); Form.AddStr ('S', ' Sponsor' , 8, 19, 19, 19, 9, 30, 30, @MBase.Sponsor, Topic + 'User name of base''s sponser'); @@ -189,6 +189,7 @@ Var GBox : TAnsiMenuBox; Form : TAnsiMenuForm; Active : Array[1..26] of Boolean; + ActCnt : Byte; Count : LongInt; Topic : String; Begin @@ -246,45 +247,52 @@ Var Case Form.Execute of 'D' : Global.NetAddr := Configuration_EchoMailAddress(False); - #21 : If ShowMsgBox(1, 'Update with these settings?') Then Begin - For Count := 1 to List.ListMax Do - If List.List[Count]^.Tagged = 1 Then Begin - Seek (MBaseFile, Count - 1); - Read (MBaseFile, MBase); + #21 : Begin + ActCnt := 0; - If Active[01] Then MBase.Path := Global.Path; - If Active[02] Then MBase.ListACS := Global.ListACS; - If Active[03] Then MBase.ReadACS := Global.ReadACS; - If Active[04] Then MBase.PostACS := Global.PostACS; - If Active[05] Then MBase.SysopACS := Global.SysopACS; - If Active[06] Then MBase.NetAddr := Global.NetAddr; - If Active[07] Then MBase.Origin := Global.Origin; - If Active[08] Then MBase.Sponsor := Global.Sponsor; - If Active[09] Then MBase.Header := Global.Header; - If Active[10] Then MBase.RTemplate := Global.RTemplate; - If Active[11] Then MBase.ITemplate := Global.ITemplate; - If Active[12] Then MBase.NetType := Global.NetType; - If Active[13] Then MBase.BaseType := Global.BaseType; + For Count := 1 to 26 Do + If Active[Count] Then Inc(ActCnt); - If Active[14] Then MBase.ColQuote := Global.ColQuote; - If Active[15] Then MBase.ColText := Global.ColText; - If Active[16] Then MBase.ColTear := Global.ColTear; - If Active[17] Then MBase.ColOrigin := Global.ColOrigin; - If Active[18] Then MBase.ColKludge := Global.ColKludge; - If Active[19] Then MBase.MaxMsgs := Global.MaxMsgs; - If Active[20] Then MBase.MaxAge := Global.MaxAge; - If Active[21] Then MBase.DefNScan := Global.DefNScan; - If Active[22] Then MBase.DefQScan := Global.DefQScan; - If Active[23] Then BitSet(1, 4, MBase.Flags, (Global.Flags AND MBRealNames <> 0)); - If Active[24] Then BitSet(3, 4, MBase.Flags, (Global.Flags AND MBAutoSigs <> 0)); - If Active[25] Then BitSet(2, 4, MBase.Flags, (Global.Flags AND MBKillKludge <> 0)); - If Active[26] Then BitSet(5, 4, MBase.Flags, (Global.Flags AND MBPrivate <> 0)); + If ShowMsgBox(1, 'Update ' + strI2S(ActCnt) + ' settings per base?') Then Begin + For Count := 1 to List.ListMax Do + If List.List[Count]^.Tagged = 1 Then Begin + Seek (MBaseFile, Count - 1); + Read (MBaseFile, MBase); - Seek (MBaseFile, Count - 1); - Write (MBaseFile, MBase); - End; + If Active[01] Then MBase.Path := Global.Path; + If Active[02] Then MBase.ListACS := Global.ListACS; + If Active[03] Then MBase.ReadACS := Global.ReadACS; + If Active[04] Then MBase.PostACS := Global.PostACS; + If Active[05] Then MBase.SysopACS := Global.SysopACS; + If Active[06] Then MBase.NetAddr := Global.NetAddr; + If Active[07] Then MBase.Origin := Global.Origin; + If Active[08] Then MBase.Sponsor := Global.Sponsor; + If Active[09] Then MBase.Header := Global.Header; + If Active[10] Then MBase.RTemplate := Global.RTemplate; + If Active[11] Then MBase.ITemplate := Global.ITemplate; + If Active[12] Then MBase.NetType := Global.NetType; + If Active[13] Then MBase.BaseType := Global.BaseType; - Break; + If Active[14] Then MBase.ColQuote := Global.ColQuote; + If Active[15] Then MBase.ColText := Global.ColText; + If Active[16] Then MBase.ColTear := Global.ColTear; + If Active[17] Then MBase.ColOrigin := Global.ColOrigin; + If Active[18] Then MBase.ColKludge := Global.ColKludge; + If Active[19] Then MBase.MaxMsgs := Global.MaxMsgs; + If Active[20] Then MBase.MaxAge := Global.MaxAge; + If Active[21] Then MBase.DefNScan := Global.DefNScan; + If Active[22] Then MBase.DefQScan := Global.DefQScan; + If Active[23] Then BitSet(1, 4, MBase.Flags, (Global.Flags AND MBRealNames <> 0)); + If Active[24] Then BitSet(3, 4, MBase.Flags, (Global.Flags AND MBAutoSigs <> 0)); + If Active[25] Then BitSet(2, 4, MBase.Flags, (Global.Flags AND MBKillKludge <> 0)); + If Active[26] Then BitSet(5, 4, MBase.Flags, (Global.Flags AND MBPrivate <> 0)); + + Seek (MBaseFile, Count - 1); + Write (MBaseFile, MBase); + End; + + Break; + End; End; #27 : Break; End; diff --git a/mystic/bbs_edit_ansi.pas b/mystic/bbs_edit_ansi.pas index 263fcc1..c200db8 100644 --- a/mystic/bbs_edit_ansi.pas +++ b/mystic/bbs_edit_ansi.pas @@ -2,38 +2,42 @@ Unit bbs_Edit_Ansi; {$I M_OPS.PAS} -// modes -// viewer -// msgedit -// ansiedit - Interface Uses + m_FileIO, bbs_MsgBase_ANSI; Type TEditorANSI = Class - Owner : Pointer; - ANSI : TMsgBaseANSI; - WinY1 : Byte; - WinY2 : Byte; - WinX1 : Byte; - WinX2 : Byte; - WinSize : Byte; - RowSize : Byte; - CurX : Byte; - CurY : SmallInt; - CurAttr : Byte; - CurLength : Byte; - TopLine : LongInt; - CurLine : LongInt; - InsertMode : Boolean; - DrawMode : Boolean; - GlyphMode : Boolean; - WrapMode : Boolean; - ClearEOL : Boolean; - LastLine : LongInt; + Owner : Pointer; + ANSI : TMsgBaseANSI; + WinY1 : Byte; + WinY2 : Byte; + WinX1 : Byte; + WinX2 : Byte; + WinSize : Byte; + RowSize : Byte; + CurX : Byte; + CurY : SmallInt; + CurAttr : Byte; + CurLength : Byte; + TopLine : LongInt; + CurLine : LongInt; + InsertMode : Boolean; + DrawMode : Boolean; + GlyphMode : Boolean; + WrapMode : Boolean; + ClearEOL : Boolean; + LastLine : LongInt; + QuoteTopPage : SmallInt; + QuoteCurLine : SmallInt; + + // old shit from copy over of quote/command functions + save : boolean; + forced : boolean; + done : boolean; + subj : string; Constructor Create (Var O: Pointer); Destructor Destroy; Override; @@ -42,7 +46,7 @@ Type Function IsBlankLine (Var Line; LineSize: Byte) : Boolean; Function GetLineLength (Var Line; LineSize: Byte) : Byte; Function GetWrapPos (Var Line; LineSize, WrapPos: Byte) : Byte; - Procedure TrimLine (Var Line; LineSize: Byte); + Procedure TrimLeft (Var Line; LineSize: Byte); Procedure DeleteLine (Line: LongInt); Procedure InsertLine (Line: LongInt); Function GetLineText (Line: Word) : String; @@ -50,10 +54,11 @@ Type Procedure FindLastLine; Procedure Reformat; Procedure LocateCursor; - Procedure ReDrawTemplate; + Procedure ToggleInsert (Toggle: Boolean); + Procedure ReDrawTemplate (Reset: Boolean); Procedure DrawPage (StartY, EndY: Byte; ExitEOF: Boolean); Procedure ScrollUp; - Procedure ScrollDown; + Procedure ScrollDown (Draw: Boolean); Function LineUp : Boolean; Function LineDown (Reset: Boolean) : Boolean; Procedure PageUp; @@ -64,7 +69,11 @@ Type Procedure DoDelete; Procedure DoChar (Ch: Char); Function Edit : Boolean; - Procedure LoadANSI; + + procedure quote; + procedure quotewindow; + procedure commands; + procedure messageupload; End; Implementation @@ -130,8 +139,6 @@ Begin End; Procedure TEditorANSI.FindLastLine; -Var - Count : LongInt; Begin LastLine := mysMaxMsgLines; @@ -172,7 +179,7 @@ Begin Result := EndPos = 0; End; -Procedure TEditorANSI.TrimLine (Var Line; LineSize: Byte); +Procedure TEditorANSI.TrimLeft (Var Line; LineSize: Byte); Var Data : Array[1..255] of RecAnsiBufferChar absolute Line; EndPos : Byte; @@ -186,14 +193,6 @@ Begin Inc (EndPos); End; - - EndPos := LineSize; - - While (EndPos > 0) and ((Data[EndPos].Ch = ' ') or (Data[EndPos].Ch = #0)) Do Begin - Data[EndPos].Ch := #0; - - Dec (EndPos); - End; End; Procedure TEditorANSI.DeleteLine (Line: LongInt); @@ -267,7 +266,7 @@ Var If NewY > WinSize Then NewY := WinSize; If CurY > WinSize Then - ScrollDown + ScrollDown(True) Else DrawPage (StartY, NewY, True); End; @@ -321,7 +320,7 @@ Begin Move (TempStr[LineSize], WrapData, (GetLineLength(TempStr, 255) - LineSize + 1) * SizeOf(RecAnsiBufferChar)); FillChar (TempStr[LineSize], (255 - LineSize) * SizeOf(RecAnsiBufferChar), #0); - TrimLine (WrapData, 255); + TrimLeft (WrapData, 255); If First Then Begin If CurX > LineSize Then Begin @@ -339,17 +338,7 @@ Begin Move (TempStr, ANSI.Data[Count], RowSize * SizeOf(RecAnsiBufferChar)); If LineSize = 0 Then Begin - If First Then Begin - CurX := 1; - - Inc (CurLine); - Inc (CurY); - - If CurLine > LastLine Then LastLine := CurLine; - - EndLine := Count + 1; - End Else - EndLine := Count; + EndLine := Count; Update; @@ -358,49 +347,46 @@ Begin Inc (Count); End; - -// Update; End; -Procedure TEditorANSI.ReDrawTemplate; -// temp stuff to be replaced by real template -Var - B : TAnsiMenuBox; +Procedure TEditorANSI.ToggleInsert (Toggle: Boolean); +Begin + If Toggle Then InsertMode := Not InsertMode; + + Session.io.AnsiColor (Session.io.ScreenInfo[3].A); + Session.io.AnsiGotoXY (Session.io.ScreenInfo[3].X, Session.io.ScreenInfo[3].Y); + + If InsertMode Then Session.io.BufAddStr('INS') else Session.io.BufAddStr('OVR'); { ++lang } +End; + +Procedure TEditorANSI.ReDrawTemplate (Reset: Boolean); Begin TBBSCore(Owner).io.AllowArrow := True; - TBBSCore(Owner).io.AnsiColor(7); - TBBSCore(Owner).io.AnsiClear; + Session.io.PromptInfo[2] := Subj; -(* - B := TAnsiMenuBox.Create; - - B.FrameType := 1; - - B.Open (5, 2, 75, 23); - B.Free; - - WinX1 := 6; - WinX2 := 74; - WinY1 := 3; - WinY2 := 22; -*) + Session.io.OutFile ('ansiedit', True, 0); WinX1 := 1; WinX2 := 79; - WinY1 := 2; - WinY2 := 23; + WinY1 := Session.io.ScreenInfo[1].Y; + WinY2 := Session.io.ScreenInfo[2].Y; WinSize := WinY2 - WinY1 + 1; RowSize := WinX2 - WinX1 + 1; - CurX := 1; - CurY := 1; ClearEOL := RowSize >= 79; - //LoadANSI; - FindLastLine; + If Reset Then Begin + CurX := 1; + CurY := 1; + CurAttr := Session.io.ScreenInfo[1].A; + + FindLastLine; + End; DrawPage(1, WinSize, False); + + ToggleInsert (False); End; Procedure TEditorANSI.LocateCursor; @@ -424,10 +410,6 @@ Begin End; With TBBSCore(Owner).io Do Begin - - //AnsiGotoXY (1, 1); - //BufAddStr ('X:' + strI2S(CurX) + ' Y:' + strI2S(CurY) + ' CL:' + strI2S(CurLine) + ' TL:' + strI2S(TopLine) + ' Last:' + strI2S(LastLine) + ' Len:' + strI2S(GetLineLength(ANSI.Data[CurLine], 80)) + ' Row:' + strI2S(RowSize) + ' '); - AnsiGotoXY (WinX1 + CurX - 1, WinY1 + CurY - 1); AnsiColor (CurAttr); @@ -438,7 +420,6 @@ End; Procedure TEditorANSI.DrawPage (StartY, EndY: Byte; ExitEOF: Boolean); Var CountY : LongInt; - CountX : Byte; Begin For CountY := StartY to EndY Do Begin If TopLine + CountY - 1 > LastLine + 1 Then Begin @@ -452,8 +433,8 @@ Begin End Else If TopLine + CountY - 1 = LastLine + 1 Then Begin TBBSCore(Owner).io.AnsiGotoXY (WinX1, WinY1 + CountY - 1); - TBBSCore(Owner).io.AnsiColor (12); - TBBSCore(Owner).io.BufAddStr (strPadC('-----END-----', RowSize, ' ')); + TBBSCore(Owner).io.AnsiColor (8); + TBBSCore(Owner).io.BufAddStr (strPadC('(END)', RowSize, ' ')); If ExitEOF Then Break; End Else @@ -475,7 +456,7 @@ Begin DrawPage(1, WinSize, False); End; -Procedure TEditorANSI.ScrollDown; +Procedure TEditorANSI.ScrollDown (Draw: Boolean); Var NewTop : LongInt; Begin @@ -487,7 +468,8 @@ Begin CurY := CurLine - NewTop + 1; TopLine := NewTop; - DrawPage(1, WinSize, False); + If Draw Then + DrawPage(1, WinSize, False); End; Function TEditorANSI.LineUp : Boolean; @@ -524,27 +506,9 @@ Begin If CurY > WinSize Then Begin Result := True; - ScrollDown; + ScrollDown(True); End; End; -(* -Procedure TEditorANSI.DrawLine (Line: LongInt; XP, YP: Byte); -Var - Count : Byte; -Begin - TBBSCore(Owner).io.AnsiGotoXY (WinX1 + XP - 1, WinY1 + YP - 1); - - For Count := XP to RowSize Do Begin - If ANSI.Data[Line][Count].Ch = #0 Then Begin - TBBSCore(Owner).io.AnsiColor (7); - TBBSCore(Owner).io.BufAddChar (' '); - End Else Begin - TBBSCore(Owner).io.AnsiColor (ANSI.Data[Line][Count].Attr); - TBBSCore(Owner).io.BufAddChar (ANSI.Data[Line][Count].Ch); - End; - End; -End; -*) Procedure TEditorANSI.DrawLine (Line: LongInt; XP, YP: Byte); Var @@ -758,34 +722,6 @@ Begin DrawPage(1, WinSize, False); End; -Procedure TEditorANSI.LoadANSI; -Var - F : File; - B : Array[1..1024] of Char; - BR : LongInt; - A : LongInt; - C : LongINt; -Begin - Assign (F, '\code\mystic1\text\gj-glue1.ans'); - Reset (F, 1); - - While Not Eof(F) Do Begin - BlockRead (F, B, SizeOf(B), BR); - - If BR = 0 Then Break; - - ANSI.ProcessBuf(B, BR); - End; - - Close(F); - - For A := 1 to ANSI.Lines Do - For C := RowSize + 1 to 80 Do Begin - ANSI.Data[A][C].Ch := #0; - ANSI.Data[A][C].Attr := 0; - End; -End; - Procedure TEditorANSI.DoEnter; Var TempLine : RecAnsiBufferLine; @@ -810,16 +746,437 @@ Begin LineDown(True); End; +Procedure TEditorANSI.Quote; +Var + InFile : Text; + Start : Integer; + Finish : Integer; + NumLines : Integer; + Text : Array[1..mysMaxMsgLines] of String[80]; + PI1 : String; + PI2 : String; +Begin + Assign (InFile, Session.TempPath + 'msgtmp'); + {$I-} Reset (InFile); {$I+} + If IoResult <> 0 Then Begin + Session.io.OutFullLn (Session.GetPrompt(158)); + Exit; + End; + + NumLines := 0; + Session.io.AllowPause := True; + + While Not Eof(InFile) Do Begin + Inc (NumLines); + ReadLn (InFile, Text[NumLines]); + End; + + Close (InFile); + + PI1 := Session.io.PromptInfo[1]; + PI2 := Session.io.PromptInfo[2]; + + Session.io.OutFullLn('|CL' + Session.GetPrompt(452)); + + For Start := 1 to NumLines Do Begin + Session.io.PromptInfo[1] := strI2S(Start); + Session.io.PromptInfo[2] := Text[Start]; + + Session.io.OutFullLn (Session.GetPrompt(341)); + + If (Session.io.PausePtr >= Session.User.ThisUser.ScreenSize) and (Session.io.AllowPause) Then + Case Session.io.MorePrompt of + 'N' : Break; + 'C' : Session.io.AllowPause := False; + End; + End; + + Session.io.AllowPause := True; + + Session.io.OutFull (Session.GetPrompt(159)); + Start := strS2I(Session.io.GetInput(3, 3, 11, '')); + + Session.io.OutFull (Session.GetPrompt(160)); + + Finish := strS2I(Session.io.GetInput(3, 3, 11, '')); + + If (Start > 0) and (Start <= NumLines) and (Finish <= NumLines) Then Begin + If Finish = 0 Then Finish := Start; + + For NumLines := Start to Finish Do Begin + If LastLine = mysMaxMsgLines Then Break; + + If Not IsBlankLine(Ansi.Data[CurLine], 80) Then Begin + Inc (CurLine); + Inc (CurY); + + InsertLine (CurLine); + End; + + SetLineText (CurLine, Text[NumLines]); + + If CurY > WinSize Then + ScrollDown(False); + End; + End; + + If CurLine < mysMaxMsgLines Then Begin + Inc (CurLine); + Inc (CurY); + + InsertLine(CurLine); + + If CurY > WinSize Then + ScrollDown(False); + End; + + Session.io.PromptInfo[1] := PI1; + Session.io.PromptInfo[2] := PI2; +End; + +Procedure TEditorANSI.QuoteWindow; +Var + QText : Array[1..mysMaxMsgLines] of String[79]; + InFile : Text; + QuoteLines : Integer; + NoMore : Boolean; + + Procedure UpdateBar (On: Boolean); + Begin + Session.io.AnsiGotoXY (1, QuoteCurLine + Session.io.ScreenInfo[2].Y); + + If On Then + Session.io.AnsiColor (Session.Theme.QuoteColor) + Else + Session.io.AnsiColor (Session.io.ScreenInfo[2].A); + + Session.io.BufAddStr (strPadR(QText[QuoteTopPage + QuoteCurLine], 79, ' ')); + End; + + Procedure UpdateWindow; + Var + Count : Integer; + Begin + Session.io.AnsiGotoXY (1, Session.io.ScreenInfo[2].Y); + Session.io.AnsiColor (Session.io.ScreenInfo[2].A); + + For Count := QuoteTopPage to QuoteTopPage + 5 Do Begin + If Count <= QuoteLines Then Session.io.BufAddStr (QText[Count]); + + Session.io.AnsiClrEOL; + + If Count <= QuoteLines Then Session.io.BufAddStr(#13#10); + End; + + UpdateBar(True); + End; + +Var + Ch : Char; + Added : Boolean; + QWinSize : Byte; + QWinDataPos : Byte; + QWinData : Array[1..15] of String[79]; + + Procedure AddQuoteWin (S: String); + Var + Count : Byte; + Begin + If QWinDataPos < QWinSize Then Begin + Inc (QWinDataPos); + End Else Begin + For Count := 2 to QWinSize Do + QWinData[Count - 1] := QWinData[Count] + End; + + QWinData[QWinDataPos] := S; + End; + + Procedure DrawQWin; + Var + Count : Byte; + Begin + Session.io.AnsiColor(11); // quote text color + + For Count := 1 to QWinSize Do Begin + Session.io.AnsiGotoXY (WinX1, WinY1 + Count - 1); + Session.io.BufAddStr(QWinData[Count]); + Session.io.AnsiClrEOL; + End; + End; + +Begin + Added := False; + + Assign (InFile, Session.TempPath + 'msgtmp'); + {$I-} Reset(InFile); {$I+} + + If IoResult <> 0 Then Exit; + + QuoteLines := 0; + NoMore := False; + QWinDataPos := 0; + + While Not Eof(InFile) Do Begin + Inc (QuoteLines); + ReadLn (InFile, QText[QuoteLines]); + End; + + Close (InFile); + + Session.io.OutFile ('ansiquot', True, 0); + + FillChar(QWinData, SizeOf(QWinData), 0); + + QWinSize := Session.io.ScreenInfo[1].Y - WinY1 + 1; + + DrawQWin; + UpdateWindow; + + Repeat + Ch := Session.io.GetKey; + + If Session.io.IsArrow Then Begin + Case Ch of + #71 : If QuoteCurLine > 0 Then Begin + QuoteTopPage := 1; + QuoteCurLine := 0; + + UpdateWindow; + End; + #72 : Begin + If QuoteCurLine > 0 Then Begin + UpdateBar(False); + + Dec(QuoteCurLine); + + UpdateBar(True); + End Else + If QuoteTopPage > 1 Then Begin + Dec (QuoteTopPage); + + UpdateWindow; + End; + + NoMore := False; + End; + #73, + #75 : Begin + If QuoteTopPage > 6 Then + Dec (QuoteTopPage, 6) + Else Begin + QuoteTopPage := 1; + QuoteCurLine := 0; + End; + + NoMore := False; + + UpdateWindow; + End; + #79 : Begin + If QuoteLines <= 6 Then + QuoteCurLine := QuoteLines - QuoteTopPage + Else Begin + QuoteTopPage := QuoteLines - 5; + QuoteCurLine := 5; + End; + + UpdateWindow; + End; + #80 : If QuoteTopPage + QuoteCurLine < QuoteLines Then Begin + If QuoteCurLine = 5 Then Begin + Inc (QuoteTopPage); + + UpdateWindow; + End Else Begin + UpdateBar(False); + + Inc (QuoteCurLine); + + UpdateBar(True); + End; + End; + #77, + #81 : Begin + If QuoteLines <= 6 Then + QuoteCurLine := QuoteLines - QuoteTopPage + Else + If QuoteTopPage + 6 < QuoteLines - 6 Then + Inc (QuoteTopPage, 6) + Else Begin + QuoteTopPage := QuoteLines - 5; + QuoteCurLine := 5; + End; + + UpdateWindow; + End; + End; + End Else + Case Ch of + #27 : Break; + #13 : If (LastLine < mysMaxMsgLines) and (Not NoMore) Then Begin + Added := True; + + If QuoteTopPage + QuoteCurLine = QuoteLines Then NoMore := True; + + InsertLine (CurLine); + SetLineText (CurLine, QText[QuoteTopPage + QuoteCurLine]); + + ANSI.SetLineColor (11, CurLine); + + Inc (CurLine); + Inc (CurY); + + If CurY > WinSize Then + ScrollDown(False); + + AddQuoteWin(QText[QuoteTopPage + QuoteCurLine]); + DrawQWin; + + If QuoteTopPage + QuoteCurLine < QuoteLines Then + If QuoteCurLine = 5 Then Begin + Inc (QuoteTopPage); + + UpdateWindow; + End Else Begin + UpdateBar(False); + + Inc (QuoteCurLine); + + UpdateBar(True); + End; + End; + End; + Until False; + + Session.io.OutFull('|16'); + +// If (CurLine < mysMaxMsgLines) And Added Then Inc(CurLine); +End; + +Procedure TEditorANSI.Commands; +Var + Ch : Char; + Str : String; +Begin + Done := False; + Save := False; + + Repeat + Session.io.OutFull (Session.GetPrompt(354)); + + Ch := Session.io.OneKey ('?ACHQRSTU', True); + + Case Ch of + '?' : Session.io.OutFullLn (Session.GetPrompt(355)); + 'A' : If Forced Then Begin + Session.io.OutFull (Session.GetPrompt(307)); + Exit; + End Else Begin + Done := Session.io.GetYN(Session.GetPrompt(356), False); + Exit; + End; + 'C' : Exit; + 'H' : Begin + Session.io.OutFile ('fshelp', True, 0); + Exit; + End; + 'Q' : Begin + If Session.User.ThisUser.UseLBQuote Then + QuoteWindow + Else + Quote; + Exit; + End; + 'R' : Exit; + 'S' : Begin + Save := True; + Done := True; + End; + 'T' : Begin + Session.io.OutFull(Session.GetPrompt(463)); + Str := Session.io.GetInput(60, 60, 11, Subj); + If Str <> '' Then Subj := Str; + Session.io.PromptInfo[2] := Subj; + Exit; + End; + 'U' : Begin + MessageUpload; + Exit; + End; + End; + Until Done; +End; + +Procedure TEditorANSI.MessageUpload; +Var + FN : String[100]; + T1 : String[30]; + T2 : String[60]; + OK : Boolean; + F : File; + B : Array[1..2048] of Char; + BR : LongInt; +Begin + OK := False; + + T1 := Session.io.PromptInfo[1]; + T2 := Session.io.PromptInfo[2]; + + Session.io.OutFull (Session.GetPrompt(352)); + + If Session.LocalMode Then Begin + FN := Session.io.GetInput(70, 70, 11, ''); + + If FN = '' Then Exit; + + OK := FileExist(FN); + End Else Begin + FN := Session.TempPath + Session.io.GetInput(70, 70, 11, ''); + + If Session.FileBase.SelectProtocol(True, False) = 'Q' Then Exit; + + Session.FileBase.ExecuteProtocol(1, FN); + + OK := Session.FileBase.dszSearch(JustFile(FN)); + End; + + If OK Then Begin + Assign (F, FN); + Reset (F, 1); + + While Not Eof(F) Do Begin + BlockRead (F, B, SizeOf(B), BR); + + If BR = 0 Then Break; + + ANSI.ProcessBuf(B, BR); + End; + + Close(F); + End; + + If Not Session.LocalMode Then FileErase(FN); + + DirClean (Session.TempPath, 'msgtmp'); + + Session.io.PromptInfo[1] := T1; + Session.io.PromptInfo[2] := T2; + + FindLastLine; +End; + Function TEditorANSI.Edit : Boolean; Var - Ch : Char; - Attr : Byte; + Ch : Char; Begin - Result := False; + Result := False; + QuoteCurLine := 0; + QuoteTopPage := 1; - ReDrawTemplate; + ReDrawTemplate(True); - While Not TBBSCore(Owner).ShutDown Do Begin + Repeat LocateCursor; Ch := TBBSCore(Owner).io.GetKey; @@ -827,19 +1184,27 @@ Begin If Session.io.IsArrow Then Begin Case Ch of #71 : CurX := 1; - #79 : CurX := CurLength + 1; #72 : LineUp; - #80 : If CurLine < LastLine Then LineDown(False); + #73 : PageUp; #75 : If CurX > 1 Then Dec(CurX); #77 : If CurX <= RowSize Then Inc(CurX); - #73 : PageUp; + #79 : CurX := CurLength + 1; + #80 : If CurLine < LastLine Then LineDown(False); #81 : PageDown; #83 : DoDelete; End; End Else Case Ch of - ^V : InsertMode := Not InsertMode; //update on screen - ^Y : Begin + ^Q : Begin + If Session.User.ThisUser.UseLBQuote Then + QuoteWindow + Else + Quote; + + ReDrawTemplate(False); + End; + ^V : ToggleInsert(True); + ^Y : If (CurLine < LastLine) or ((CurLine = LastLine) And Not IsBlankLine(ANSI.Data[CurLine], 80)) Then Begin DeleteLine (CurLine); If CurLine > LastLine Then @@ -847,20 +1212,38 @@ Begin DrawPage (CurY, WinSize, False); End; - ^Z : Break; + ^Z, + ^[ : Begin + Commands; + + If (Not Save) and (Not Done) Then ReDrawTemplate(False); + + Session.io.AllowArrow := True; + End; #08 : DoBackSpace; #13 : DoEnter; #32.. #254 : If (CurLength >= RowSize) and (GetWrapPos(ANSI.Data[CurLine], RowSize, RowSize) = 0) Then Begin - If CurX = CurLength + 1 Then Begin - LineDown(True); - End; + // dont do anything + End Else + If (CurX = 1) and (Ch = '/') Then Begin + Commands; + + If (Not Save) and (Not Done) Then ReDrawTemplate(False); + + Session.io.AllowArrow := True; End Else DoChar(Ch); End; - End; + Until Done; - Result := True; + Session.io.AllowArrow := False; + + If Save Then FindLastLine; + + Result := Save; + + Session.io.AnsiGotoXY (1, Session.User.ThisUser.ScreenSize); End; End. diff --git a/mystic/bbs_edit_full.pas b/mystic/bbs_edit_full.pas index 45c20ee..bbab362 100644 --- a/mystic/bbs_edit_full.pas +++ b/mystic/bbs_edit_full.pas @@ -155,6 +155,7 @@ Begin If CurX > WrapPos Then Begin Inc (NewLine); Inc (NewY); + CurX := 1; End; @@ -169,7 +170,7 @@ Begin End Else Begin Session.io.BufFlush; - A := strWrap (OldStr, NewStr, WrapPos); + A := strWrap (OldStr, NewStr, WrapPos + 1); If (A > 0) And (Not Moved) And (CurX > Length(OldStr) + 1) Then Begin CurX := CurX - A; @@ -184,6 +185,7 @@ Begin If (Session.Msgs.MsgText[Line] = '') or ((Pos(' ', Session.Msgs.MsgText[Line]) = 0) And (Length(Session.Msgs.MsgText[Line]) >= WrapPos)) Then Begin InsertLine(Line); + OldStr := NewStr; End Else OldStr := NewStr + ' ' + Session.Msgs.MsgText[Line]; @@ -192,6 +194,16 @@ Begin Session.Msgs.MsgText[Line] := OldStr; + + + If NewY <= WinEnd Then TextRefreshPart; + + CurY := NewY; + CurLine := NewLine; + + If CurY > WinEnd Then TextRefreshFull Else UpdatePosition; + +(* If NewY <= WinEnd Then Begin Session.io.AnsiGotoXY(1, CurY); @@ -215,6 +227,7 @@ Begin CurLine := NewLine; If CurY > WinEnd Then TextRefreshFull Else UpdatePosition; +*) End; Procedure keyEnter; @@ -977,7 +990,7 @@ Begin Lines := TotalLine; End; - Result := (Save = True); + Result := Save; Session.io.AnsiGotoXY (1, Session.User.ThisUser.ScreenSize); diff --git a/mystic/bbs_edit_line.pas b/mystic/bbs_edit_line.pas index 151476f..8c691de 100644 --- a/mystic/bbs_edit_line.pas +++ b/mystic/bbs_edit_line.pas @@ -11,6 +11,7 @@ Implementation Uses m_Strings, + m_FileIO, bbs_Common, bbs_Core, bbs_FileBase, @@ -21,6 +22,57 @@ Var Done, Save : Boolean; +Procedure MessageUpload (Var CurLine: SmallInt); +Var + FN : String[100]; + TF : Text; + T1 : String[30]; + T2 : String[60]; + OK : Boolean; +Begin + OK := False; + + T1 := Session.io.PromptInfo[1]; + T2 := Session.io.PromptInfo[2]; + + Session.io.OutFull (Session.GetPrompt(352)); + + If Session.LocalMode Then Begin + FN := Session.io.GetInput(70, 70, 11, ''); + + If FN = '' Then Exit; + + OK := FileExist(FN); + End Else Begin + FN := Session.TempPath + Session.io.GetInput(70, 70, 11, ''); + + If Session.FileBase.SelectProtocol(True, False) = 'Q' Then Exit; + + Session.FileBase.ExecuteProtocol(1, FN); + + OK := Session.FileBase.dszSearch(JustFile(FN)); + End; + + If OK Then Begin + Assign (TF, FN); + Reset (TF); + + While Not Eof(TF) and (CurLine < mysMaxMsgLines) Do Begin + ReadLn (TF, Session.Msgs.MsgText[CurLine]); + Inc (CurLine); + End; + + Close (TF); + End; + + If Not Session.LocalMode Then FileErase(FN); + + DirClean (Session.TempPath, 'msgtmp'); + + Session.io.PromptInfo[1] := T1; + Session.io.PromptInfo[2] := T2; +End; + Procedure Quote; Var InFile : Text; @@ -111,7 +163,7 @@ Function LineEditor (Var Lines : Integer; MaxLen: Byte; MaxLine: Integer; TEdit, Done := True; End; 'U' : Begin - Session.Msgs.MessageUpload(CurLine); + MessageUpload(CurLine); Exit; End; End; diff --git a/mystic/bbs_filebase.pas b/mystic/bbs_filebase.pas index f319653..6b97472 100644 --- a/mystic/bbs_filebase.pas +++ b/mystic/bbs_filebase.pas @@ -75,7 +75,6 @@ Type Procedure SetFileScan; Procedure GetFileScan; Function SelectProtocol (UseDefault, Batch: Boolean) : Char; - Function WildcardMatch (Wildcard, FName: String) : Boolean; Procedure CheckFileNameLength (FPath : String; Var FName: String); Procedure GetFileDescription (FN: String); Function CheckFileLimits (DL: Byte; DLK: Integer) : Byte; @@ -933,32 +932,6 @@ Begin If Not Result Then Session.io.OutFullLn(Session.GetPrompt(425)); End; -Function TFileBase.WildcardMatch (Wildcard, FName: String) : Boolean; -Begin - Result := False; - - If FName = '' Then Exit; - - Case Wildcard[1] of - '*' : Begin - If FName[1] = '.' Then Exit; - If Length(Wildcard) = 1 Then Result := True; - If (Length(Wildcard) > 1) and (Wildcard[2] = '.') and (Length(FName) > 0) Then - Result := WildCardMatch(Copy(Wildcard, 3, Length(Wildcard) - 2), Copy(FName, Pos('.', FName) + 1, Length(FName)-Pos('.', FName))); - End; - '?' : If Ord(Wildcard[0]) = 1 Then - Result := True - Else - Result := WildCardMatch(Copy(Wildcard, 2, Length(Wildcard) - 1), Copy(FName, 2, Length(FName) - 1)); - Else - If FName[1] = Wildcard[1] Then - If Length(wildcard) > 1 Then - Result := WildCardMatch(Copy(Wildcard, 2, Length(Wildcard) - 1), Copy(FName, 2, Length(FName) - 1)) - Else - Result := (Length(FName) = 1) And (Length(Wildcard) = 1); - End; -End; - Function TFileBase.ArchiveList (FName : String) : Boolean; Var Arc : PArchive; @@ -2036,7 +2009,7 @@ Var Case Mode of 1 : If Data <> '' Then - If Not WildCardMatch (Data, FDir.FileName) Then Exit; + If Not WildMatch (Data, FDir.FileName, False) Then Exit; 2 : If FDir.DateTime < FScan.LastNew Then Exit; 3 : Begin T2 := Bool_Search(Data, FDir.FileName); @@ -3629,7 +3602,7 @@ Begin End; If Back Then Seek (FDirFile, FilePos(FDirFile) - 2); Read (FDirFile, FDir); - If (FDir.Flags And FDirDeleted = 0) and WildCardMatch(Mask, FDir.FileName) Then + If (FDir.Flags And FDirDeleted = 0) and WildMatch(Mask, FDir.FileName, False) Then Break; Until False; End; @@ -3770,7 +3743,9 @@ Begin Session.User.IgnoreGroup := True; Repeat Session.io.OutFull ('|CR|09Move to which base (?/List): '); + Temp := Session.io.GetInput(4, 4, 12, ''); + If Temp = '?' Then Begin Old := FBase; ListFileAreas(False); @@ -3785,7 +3760,7 @@ Begin Seek (FBaseFile, B - 1); Read (FBaseFile, FBase); - If Not FileCopy (Old.Path + FDir.FileName, FBase.Path + FDir.FileName) Then Begin + If FileExist(FBase.Path + FDir.FileName) or (Not FileCopy(Old.Path + FDir.FileName, FBase.Path + FDir.FileName)) Then Begin Session.io.OutFull ('ERROR|CR|CR|PA'); FBase := Old; diff --git a/mystic/bbs_general.pas b/mystic/bbs_general.pas index 850143c..c243342 100644 --- a/mystic/bbs_general.pas +++ b/mystic/bbs_general.pas @@ -67,8 +67,12 @@ Begin For Count := 1 to Lines Do Editor.SetLineText (Count, Session.Msgs.MsgText[Count]); + Editor.Subj := Subj; + Result := Editor.Edit; + Subj := Editor.Subj; + If Result Then Begin For Count := 1 to Editor.LastLine Do Session.Msgs.MsgText[Count] := Editor.GetLineText(Count); diff --git a/mystic/bbs_msgbase.pas b/mystic/bbs_msgbase.pas index 5e871d9..aa59277 100644 --- a/mystic/bbs_msgbase.pas +++ b/mystic/bbs_msgbase.pas @@ -11,7 +11,8 @@ Uses bbs_General, bbs_MsgBase_ABS, bbs_MsgBase_JAM, - bbs_MsgBase_Squish; + bbs_MsgBase_Squish, + bbs_Edit_ANSI; Type TMsgBase = Class @@ -40,6 +41,7 @@ Type Function GetBaseCompressed (Num: LongInt; Var TempBase: RecMessageBase) : Boolean; Function GetBaseByIndex (Num: LongInt; Var TempBase: RecMessageBase) : Boolean; Procedure GetMessageStats (List, ShowPrompt, ShowYou: Boolean; Var ListPtr: LongInt; Var TempBase: RecMessageBase; NoFrom, NoRead: Boolean; Var Total, New, Yours: LongInt); + Function GetMatchedAddress (Orig, Dest: RecEchoMailAddr) : RecEchoMailAddr; Function GetTotalBases (Compressed: Boolean) : LongInt; Function GetTotalMessages (Var TempBase: RecMessageBase) : LongInt; Procedure PostTextFile (Data: String; AllowCodes: Boolean); @@ -50,7 +52,6 @@ Type Procedure SetMessageScan; Procedure GetMessageScan; Procedure SendMassEmail; - Procedure MessageUpload (Var CurLine: SmallInt); Procedure ReplyMessage (Email: Boolean; ListMode: Byte; ReplyID: String); Procedure EditMessage; Function ReadMessages (Mode: Char; CmdData, SearchStr: String) : Boolean; @@ -127,6 +128,21 @@ Begin Inherited Destroy; End; +Function TMsgBase.GetMatchedAddress (Orig, Dest: RecEchoMailAddr) : RecEchoMailAddr; +Var + Count : Byte; +Begin + Result := Orig; + + If Orig.Zone = Dest.Zone Then Exit; + + For Count := 1 to 30 Do + If Config.NetAddress[Count].Zone = Dest.Zone Then Begin + Result := Config.NetAddress[Count]; + Exit; + End; +End; + Function TMsgBase.NetmailLookup (FromMenu: Boolean; MsgTo, DefAddr: String) : String; Procedure ShowNode (ShowType: Byte; NodeData: RecNodeSearch; Ext: Boolean); @@ -563,13 +579,12 @@ Begin If MBase.NetType > 0 Then Begin Msg^.DoStringLn (#13 + '--- ' + mysSoftwareID + ' BBS v' + mysVersion + ' (' + OSID + ')'); - Msg^.DoStringLn (' * Origin: ' + ResolveOrigin(MBase) + ' (' + strAddr2Str(Config.NetAddress[MBase.NetAddr]) + ')'); + Msg^.DoStringLn (' * Origin: ' + ResolveOrigin(MBase) + ' (' + strAddr2Str(Msg^.GetOrigAddr) + ')'); End; End; Procedure TMsgBase.AssignMessageData (Var Msg: PMsgBaseABS; Var TempBase: RecMessageBase); Var - Addr : RecEchoMailAddr; SemFile : Text; Begin Msg^.StartNewMsg; @@ -587,9 +602,7 @@ Begin Else Msg^.SetMailType(mmtEchoMail); - Addr := Config.NetAddress[TempBase.NetAddr]; - - Msg^.SetOrig(Addr); + Msg^.SetOrig(Config.NetAddress[TempBase.NetAddr]); Case TempBase.NetType of 1 : Begin @@ -1152,8 +1165,8 @@ Begin If DoWrap Then Begin If WrapData <> '' Then Begin If TempStr = '' Then Begin - WriteLn (QuoteFile, Initials + strStripB(WrapData, ' ')); - WriteLn (QuoteFile, Initials); + WriteLn (QuoteFile, ' ' + Initials + strStripB(WrapData, ' ')); + WriteLn (QuoteFile, ' ' + Initials); WrapData := ''; @@ -1163,11 +1176,11 @@ Begin TempStr := strStripB(WrapData, ' ') + ' ' + strStripL(TempStr, ' '); End; - strWrap (TempStr, WrapData, 75); + strWrap (TempStr, WrapData, 74); - WriteLn (QuoteFile, Initials + Copy(TempStr, 1, 75)); + WriteLn (QuoteFile, ' ' + Initials + Copy(TempStr, 1, 75)); End Else - WriteLn (QuoteFile, Initials + Copy(TempStr, 1, 75)); + WriteLn (QuoteFile, ' ' + Initials + Copy(TempStr, 1, 75)); End; Close (QuoteFile); @@ -1188,13 +1201,11 @@ Begin 2 : MsgNew^.SetTo('All'); 3 : Begin MsgNew^.SetDest (Addr); + MsgNew^.SetOrig (GetMatchedAddress(Config.NetAddress[MBase.NetAddr], Addr)); MsgNew^.SetCrash (Config.netCrash); MsgNew^.SetHold (Config.netHold); MsgNew^.SetKillSent (Config.netKillSent); MsgNew^.SetTo (ToWho); - - Addr := Config.NetAddress[MBase.NetAddr]; - MsgNew^.SetOrig (Addr); End; Else MsgNew^.SetTo (ToWho); @@ -1326,6 +1337,7 @@ Begin Until False; End; +(* Procedure TMsgBase.MessageUpload (Var CurLine: SmallInt); Var FN : String[100]; @@ -1376,6 +1388,7 @@ Begin Session.io.PromptInfo[1] := T1; Session.io.PromptInfo[2] := T2; End; +*) Function TMsgBase.ReadMessages (Mode: Char; CmdData, SearchStr: String) : Boolean; Var @@ -2900,10 +2913,7 @@ Begin MsgBase^.SetCrash (Config.netCrash); MsgBase^.SetHold (Config.netHold); MsgBase^.SetKillSent (Config.netKillSent); - - DestAddr := Config.NetAddress[MBase.NetAddr]; - - MsgBase^.SetOrig (DestAddr); + MsgBase^.SetOrig (GetMatchedAddress(Config.NetAddress[MBase.NetAddr], DestAddr)); End; AppendMessageText (MsgBase, Lines, ''); @@ -3556,7 +3566,7 @@ Begin Msg^.SetLocal (True); If mArea.NetType > 0 Then Begin - If mArea.NetType = 2 Then Begin + If mArea.NetType = 3 Then Begin Msg^.SetMailType (mmtNetMail); Msg^.SetCrash (Config.netCrash); Msg^.SetHold (Config.netHold); @@ -3590,7 +3600,7 @@ Begin If mArea.NetType > 0 Then Begin Msg^.DoStringLn (#13 + '--- ' + mysSoftwareID + ' BBS v' + mysVersion + ' (' + OSID + ')'); - Msg^.DoStringLn (' * Origin: ' + ResolveOrigin(mArea) + ' (' + strAddr2Str(Config.NetAddress[mArea.NetAddr]) + ')'); + Msg^.DoStringLn (' * Origin: ' + ResolveOrigin(mArea) + ' (' + strAddr2Str(Msg^.GetOrigAddr) + ')'); End; Msg^.WriteMsg; @@ -4341,7 +4351,7 @@ Begin If TempBase.NetType > 0 Then Begin MsgBase^.DoStringLn (#13 + '--- ' + mysSoftwareID + '/QWK v' + mysVersion + ' (' + OSID + ')'); - MsgBase^.DoStringLn (' * Origin: ' + ResolveOrigin(TempBase) + ' (' + strAddr2Str(Config.NetAddress[TempBase.NetAddr]) + ')'); + MsgBase^.DoStringLn (' * Origin: ' + ResolveOrigin(TempBase) + ' (' + strAddr2Str(MsgBase^.GetOrigAddr) + ')'); End; If Not IsControl Then Begin diff --git a/mystic/mis.pas b/mystic/mis.pas index 49e3164..f052a6f 100644 --- a/mystic/mis.pas +++ b/mystic/mis.pas @@ -221,10 +221,10 @@ Begin Case FocusCurrent of FocusTelnet : If TelnetServer <> NIL Then Break; - FocusSMTP : If SmtpServer <> NIL Then Break; - FocusPOP3 : If Pop3Server <> NIL Then Break; - FocusFTP : If FtpServer <> NIL Then Break; - FocusNNTP : If NNTPServer <> NIL Then Break; + FocusSMTP : If SmtpServer <> NIL Then Break; + FocusPOP3 : If Pop3Server <> NIL Then Break; + FocusFTP : If FtpServer <> NIL Then Break; + FocusNNTP : If NNTPServer <> NIL Then Break; End; Until False; diff --git a/mystic/mis_client_ftp.pas b/mystic/mis_client_ftp.pas index cdc8e78..0f50597 100644 --- a/mystic/mis_client_ftp.pas +++ b/mystic/mis_client_ftp.pas @@ -505,7 +505,7 @@ Begin If (Dir.Flags And FDirInvalid <> 0) And (Not CheckAccess(User, True, bbsConfig.AcsSeeUnvalid)) Then Continue; If (Dir.Flags And FDirFailed <> 0) And (Not CheckAccess(User, True, bbsConfig.AcsSeeFailed)) Then Continue; - If WildcardMatch(FileMask, Dir.FileName) Then + If WildMatch(FileMask, Dir.FileName, False) Then DataSocket.WriteLine(Dir.FileName); End; End; @@ -548,7 +548,7 @@ Begin While Not FBaseFile.EOF Do Begin FBaseFile.Read(TempBase); - If ValidDirectory(TempBase) and WildcardMatch(FileMask, TempBase.FtpName) Then + If ValidDirectory(TempBase) and WildMatch(FileMask, TempBase.FtpName, False) Then DataSocket.WriteLine('drwxr-xr-x 1 ftp ftp 0 Jul 11 23:35 ' + TempBase.FtpName) End; End; @@ -573,7 +573,7 @@ Begin If (Dir.Flags And FDirInvalid <> 0) And (Not CheckAccess(User, True, bbsConfig.AcsSeeUnvalid)) Then Continue; If (Dir.Flags And FDirFailed <> 0) And (Not CheckAccess(User, True, bbsConfig.AcsSeeFailed)) Then Continue; - If WildcardMatch(FileMask, Dir.FileName) Then + If WildMatch(FileMask, Dir.FileName, False) Then DataSocket.WriteLine('-rw-r--r-- 1 ftp ftp ' + strPadL(strI2S(Dir.Size), 13, ' ') + ' Jul 11 23:35 ' + Dir.FileName) End; End; @@ -612,7 +612,7 @@ Begin While Not DirFile.EOF Do Begin DirFile.Read(Dir); - If WildcardMatch(FileMask, Dir.FileName) Then Begin + If WildMatch(FileMask, Dir.FileName, False) Then Begin Found := DirFile.FilePos; Break; End; diff --git a/mystic/mis_common.pas b/mystic/mis_common.pas index 2520948..9b94d73 100644 --- a/mystic/mis_common.pas +++ b/mystic/mis_common.pas @@ -18,7 +18,6 @@ Var Function SearchForUser (UN: String; Var Rec: RecUser; Var RecPos: LongInt) : Boolean; Function CheckAccess (User: RecUser; IgnoreGroup: Boolean; Str: String) : Boolean; -Function WildcardMatch (Wildcard, FName: String) : Boolean; Function GetSecurityLevel (Level: Byte; SecLevel: RecSecurity) : Boolean; Implementation @@ -198,32 +197,6 @@ Begin Result := Pos('%', Out) = 0; End; -Function WildcardMatch (Wildcard, FName: String) : Boolean; -Begin - Result := False; - - If FName = '' Then Exit; - - Case Wildcard[1] of - '*' : Begin - If FName[1] = '.' Then Exit; - If Length(Wildcard) = 1 Then Result := True; - If (Length(Wildcard) > 1) and (Wildcard[2] = '.') and (Length(FName) > 0) Then - Result := WildCardMatch(Copy(Wildcard, 3, Length(Wildcard) - 2), Copy(FName, Pos('.', FName) + 1, Length(FName)-Pos('.', FName))); - End; - '?' : If Ord(Wildcard[0]) = 1 Then - Result := True - Else - Result := WildCardMatch(Copy(Wildcard, 2, Length(Wildcard) - 1), Copy(FName, 2, Length(FName) - 1)); - Else - If FName[1] = Wildcard[1] Then - If Length(wildcard) > 1 Then - Result := WildCardMatch(Copy(Wildcard, 2, Length(Wildcard) - 1), Copy(FName, 2, Length(FName) - 1)) - Else - Result := (Length(FName) = 1) And (Length(Wildcard) = 1); - End; -End; - Function GetSecurityLevel (Level: Byte; SecLevel: RecSecurity) : Boolean; Var SecLevelFile : File of RecSecurity; diff --git a/mystic/mkcrap.pas b/mystic/mkcrap.pas index 05aa196..f95b80e 100644 --- a/mystic/mkcrap.pas +++ b/mystic/mkcrap.pas @@ -13,7 +13,7 @@ Interface Uses DOS; -Function ToUnixDate (FDate: LongInt): LongInt; +Function ToUnixDate (DosDate: LongInt): LongInt; Function DTToUnixDate (DT: DateTime): LongInt; Procedure UnixToDT (SecsPast: LongInt; Var Dt: DateTime); Procedure Str2Az (Str: String; MaxLen: Byte; Var AZStr); {Convert string to asciiz} @@ -48,11 +48,11 @@ Begin DTToUnixDate := SecsPast; End; -Function ToUnixDate (FDate: LongInt): LongInt; +Function ToUnixDate (DosDate: LongInt): LongInt; Var DT: DateTime; Begin - UnpackTime(Fdate, DT); + UnpackTime(DosDate, DT); ToUnixDate := DTToUnixDate(DT); End; diff --git a/mystic/mutil.ini b/mystic/mutil.ini index 066500d..cd820c1 100644 --- a/mystic/mutil.ini +++ b/mystic/mutil.ini @@ -63,7 +63,7 @@ Import_MessageBase = false Import_FILEBONE.NA = false Import_FILES.BBS = false - MassUpload = false + MassUpload = true GenerateTopLists = false GenerateAllFiles = false PurgeMessageBases = false @@ -205,6 +205,11 @@ no_description = No Description + ; Ignore list one file mask per line (allows * and ? wildcards) + + ignore = files.bbs + ;ignore = *.readme + ; ========================================================================== ; ========================================================================== ; ========================================================================== diff --git a/mystic/mutil.pas b/mystic/mutil.pas index c3e397a..3280a76 100644 --- a/mystic/mutil.pas +++ b/mystic/mutil.pas @@ -202,7 +202,7 @@ Begin If ProcessTotal = 0 Then Begin ProcessName ('Load configuration', False); - ProcessStatus ('No processes configured!', True); + ProcessStatus ('No processes configured', True); ProcessResult (rFATAL, False); Halt(1); diff --git a/mystic/mutil_common.pas b/mystic/mutil_common.pas index 9686876..01585ca 100644 --- a/mystic/mutil_common.pas +++ b/mystic/mutil_common.pas @@ -353,8 +353,11 @@ Begin End; Function GetMBaseByNetZone (Zone: Word; Var TempBase: RecMessageBase) : Boolean; +// get netmail base with matching zone, or at least A netmail base if no match Var - F : File; + F : File; + One : RecMessageBase; + GotOne : Boolean; Begin Result := False; @@ -365,13 +368,24 @@ Begin While Not Eof(F) Do Begin ioRead(F, TempBase); - If (Zone = bbsConfig.NetAddress[TempBase.NetAddr].Zone) and (TempBase.NetType = 3) Then Begin - Result := True; - Break; + If (TempBase.NetType = 3) Then Begin + One := TempBase; + GotOne := True; + + If Zone = bbsConfig.NetAddress[TempBase.NetAddr].Zone Then Begin + Result := True; + + Break; + End; End; End; Close (F); + + If Not Result And GotOne Then Begin + Result := True; + TempBase := One; + End; End; Function MessageBaseOpen (Var Msg: PMsgBaseABS; Var Area: RecMessageBase) : Boolean; diff --git a/mystic/mutil_echoexport.pas b/mystic/mutil_echoexport.pas index 68d79a9..a88e88b 100644 --- a/mystic/mutil_echoexport.pas +++ b/mystic/mutil_echoexport.pas @@ -29,22 +29,13 @@ Var Begin FileMode := 66; - log(3, '+', 'flo add: ' + floname + ' ' + packetfn); - Assign (T, FloName); {$I-} Reset (T); {$I+} If IoResult <> 0 Then Begin - log(3, '+', 'flo reset failed'); - {$I-} ReWrite(T); {$I+} - - If IoResult <> 0 Then Begin - log(3, '+', 'unable to rewrite flo'); - end; - Reset(T); - end; + End; While Not Eof(T) Do Begin ReadLn (T, Str); @@ -55,9 +46,6 @@ Begin End; End; - log(3, '+', 'flo close and append'); - -// Close (T); Append (T); WriteLn (T, '^' + PacketFN); Close (T); @@ -101,6 +89,8 @@ Begin FLOName := bbsConfig.OutboundPath + GetFTNFlowName(EchoNode.Address) + '.flo'; BundleName := bbsConfig.OutboundPath + GetFTNArchiveName(OrigAddr, EchoNode.Address) + '.' + DayString[DayOfWeek(CurDateDos)]; + // check for existance, packet size limitations, etc and increment + // from 0-9 A-Z BundleName[Length(BundleName)] := '0'; ExecuteArchive (BundleName, EchoNode.ArcType, TempPath + PKTName, 1); @@ -167,6 +157,8 @@ Var TempStr2 := bbsConfig.OutboundPath + GetFTNFlowName(EchoNode.Address) + '.flo'; // change extensions based on crash etc from echonode + // need to add aka matching somewhere in here and also incorporate + // routing? Assign (F, TempStr1); @@ -231,7 +223,9 @@ Var If MBase.NetType <> 3 Then WriteStr ('AREA:' + MBase.EchoTag, #13); - WriteStr (#1 + 'INTL ' + strAddr2Str(EchoNode.Address) + ' ' + strAddr2Str(bbsConfig.NetAddress[MBase.NetAddr]), #13); + If MBase.NetType = 3 Then + WriteStr (#1 + 'INTL ' + strAddr2Str(EchoNode.Address) + ' ' + strAddr2Str(bbsConfig.NetAddress[MBase.NetAddr]), #13); + WriteStr (#1 + 'TID: Mystic BBS ' + mysVersion, #13); MsgBase^.MsgTxtStartUp; @@ -239,6 +233,9 @@ Var While Not MsgBase^.EOM Do WriteStr (MsgBase^.GetString(79), #13); + // SEEN-BY needs to include yourself and ANYTHING it is sent to (downlinks) + // so we need to cycle through nodes for this mbase and add ALL of them + TempStr1 := 'SEEN-BY: ' + strI2S(bbsConfig.NetAddress[MBase.NetAddr].Net) + '/' + strI2S(bbsConfig.NetAddress[MBase.NetAddr].Node) + ' '; If bbsConfig.NetAddress[MBase.NetAddr].Net <> EchoNode.Address.Net Then @@ -295,6 +292,9 @@ Begin While MsgBase^.SeekFound Do Begin MsgBase^.MsgStartUp; + // uncomment islocal if/when we build downlinks on import instead + // of export + If {MsgBase^.IsLocal And } Not MsgBase^.IsSent Then Begin Assign (ExportFile, MBase.Path + MBase.FileName + '.lnk'); diff --git a/mystic/mutil_msgpack.pas b/mystic/mutil_msgpack.pas index 893714b..223104d 100644 --- a/mystic/mutil_msgpack.pas +++ b/mystic/mutil_msgpack.pas @@ -267,4 +267,4 @@ Begin ProcessResult (rDONE, True); End; -End. \ No newline at end of file +End. diff --git a/mystic/mutil_upload.pas b/mystic/mutil_upload.pas index 1bfbf6a..4030432 100644 --- a/mystic/mutil_upload.pas +++ b/mystic/mutil_upload.pas @@ -29,6 +29,8 @@ Var Desc : Array[1..99] of String[50]; Count : Integer; FilesAdded : LongInt = 0; + IgnoreList : Array[1..100] of String[80]; + IgnoreSize : Byte = 0; Procedure RemoveDesc (Num: Byte); Var @@ -46,6 +48,26 @@ Begin ProcessName ('Mass Upload Files', True); ProcessResult (rWORKING, False); + // Read in ignore list + + FillChar (Ignorelist, SizeOf(IgnoreList), #0); + + Ini.SetSequential(True); + + Repeat + DizName := INI.ReadString(Header_UPLOAD, 'ignore', ''); + + If DizName = '' Then Break; + + Inc (IgnoreSize); + + IgnoreList[IgnoreSize] := DizName; + Until IgnoreSize = 100; + + INI.SetSequential(False); + + // get the show on the road + Assign (BaseFile, bbsConfig.DataPath + 'fbases.dat'); {$I-} Reset (BaseFile); {$I+} @@ -90,6 +112,13 @@ Begin {$ENDIF} End; + For Count := 1 to IgnoreSize Do + If WildMatch (IgnoreList[Count], DirInfo.Name, True) Then Begin + Found := True; + + Break; + End; + If Not Found Then Begin Log (1, '+', ' Add: ' + DirInfo.Name + ' To: ' + strStripPipe(Base.Name)); diff --git a/mystic/todo.pas b/mystic/todo.pas index 824f297..80f8681 100644 --- a/mystic/todo.pas +++ b/mystic/todo.pas @@ -29,7 +29,11 @@ BUGS AND POSSIBLE ISSUES FUTURE / IDEAS / WORK IN PROGRESS / NOTES ========================================= +- Reply to echomail via netmail. +- Msgbase flag for AKA matching or just rewrite netmail all together. - Amiga .readme and .TIC processing (similar) +- ^^ or utility to find .readme in the smae dir and add to file_id.diz if + it does not exist. - New files list to MUTIL based X number of days - All/new file list template files like TOP XX - MUTIL create FILES.BBS in the file base directory diff --git a/mystic/whatsnew.txt b/mystic/whatsnew.txt index 5dd953e..336886b 100644 --- a/mystic/whatsnew.txt +++ b/mystic/whatsnew.txt @@ -2912,3 +2912,37 @@ + The echomail node editor now has an editor where message bases can be list, linked, and unlinked from each configured node. + + ! Fixed a bug which would cause the file to be deleted if you tried to + move it to the new file base. Mystic should check now and give an + error. + + + Message base global editor now confirms the number of different settings + you will be updating before it does. This will help prevent people from + claiming its buggy because they forgot to select "Yes" on a setting! :) + + + The MUTIL mass upload function now has the ability to ignore files when + performating the mass upload. The list can contain up to 100 ignore + masks (supporting ? and * wildcards). For example under your header + for [MassUpload] you can add them: + + [MassUpload] + + ignore = files.bbs + ignore = *.readme + + ! Fixed a bug with sending Netmail using the text file post menu command + + + Mystic will now attempt to perform AKA matching on the origin address + of netmail messages. If you have a netmail base configured as the address + of 1:111/111 but you send a Netmail to 911:111/111, Mystic will switch the + origin address to your 911 AKA if you have one configured in Network + addresses. Translation: Use one netmail base for many networks with + tossers like FastEcho. + + + Message quoting will now indent itself by a single character to better + facilitate separation from regular text. The text will wrap and + reformat itself so no text should be lost. + + + NEW FSE/BSO FTN TOSSER AND BINKP MAILER need to type up the changes + when done