Too much to document

This commit is contained in:
mysticbbs 2013-03-22 23:17:33 -04:00
parent a0fa3890db
commit 6dca0ead56
19 changed files with 806 additions and 302 deletions

View File

@ -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 ('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 ('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.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.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 ('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'); 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; GBox : TAnsiMenuBox;
Form : TAnsiMenuForm; Form : TAnsiMenuForm;
Active : Array[1..26] of Boolean; Active : Array[1..26] of Boolean;
ActCnt : Byte;
Count : LongInt; Count : LongInt;
Topic : String; Topic : String;
Begin Begin
@ -246,45 +247,52 @@ Var
Case Form.Execute of Case Form.Execute of
'D' : Global.NetAddr := Configuration_EchoMailAddress(False); 'D' : Global.NetAddr := Configuration_EchoMailAddress(False);
#21 : If ShowMsgBox(1, 'Update with these settings?') Then Begin #21 : Begin
For Count := 1 to List.ListMax Do ActCnt := 0;
If List.List[Count]^.Tagged = 1 Then Begin
Seek (MBaseFile, Count - 1);
Read (MBaseFile, MBase);
If Active[01] Then MBase.Path := Global.Path; For Count := 1 to 26 Do
If Active[02] Then MBase.ListACS := Global.ListACS; If Active[Count] Then Inc(ActCnt);
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;
If Active[14] Then MBase.ColQuote := Global.ColQuote; If ShowMsgBox(1, 'Update ' + strI2S(ActCnt) + ' settings per base?') Then Begin
If Active[15] Then MBase.ColText := Global.ColText; For Count := 1 to List.ListMax Do
If Active[16] Then MBase.ColTear := Global.ColTear; If List.List[Count]^.Tagged = 1 Then Begin
If Active[17] Then MBase.ColOrigin := Global.ColOrigin; Seek (MBaseFile, Count - 1);
If Active[18] Then MBase.ColKludge := Global.ColKludge; Read (MBaseFile, MBase);
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); If Active[01] Then MBase.Path := Global.Path;
Write (MBaseFile, MBase); If Active[02] Then MBase.ListACS := Global.ListACS;
End; 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; End;
#27 : Break; #27 : Break;
End; End;

View File

@ -2,38 +2,42 @@ Unit bbs_Edit_Ansi;
{$I M_OPS.PAS} {$I M_OPS.PAS}
// modes
// viewer
// msgedit
// ansiedit
Interface Interface
Uses Uses
m_FileIO,
bbs_MsgBase_ANSI; bbs_MsgBase_ANSI;
Type Type
TEditorANSI = Class TEditorANSI = Class
Owner : Pointer; Owner : Pointer;
ANSI : TMsgBaseANSI; ANSI : TMsgBaseANSI;
WinY1 : Byte; WinY1 : Byte;
WinY2 : Byte; WinY2 : Byte;
WinX1 : Byte; WinX1 : Byte;
WinX2 : Byte; WinX2 : Byte;
WinSize : Byte; WinSize : Byte;
RowSize : Byte; RowSize : Byte;
CurX : Byte; CurX : Byte;
CurY : SmallInt; CurY : SmallInt;
CurAttr : Byte; CurAttr : Byte;
CurLength : Byte; CurLength : Byte;
TopLine : LongInt; TopLine : LongInt;
CurLine : LongInt; CurLine : LongInt;
InsertMode : Boolean; InsertMode : Boolean;
DrawMode : Boolean; DrawMode : Boolean;
GlyphMode : Boolean; GlyphMode : Boolean;
WrapMode : Boolean; WrapMode : Boolean;
ClearEOL : Boolean; ClearEOL : Boolean;
LastLine : LongInt; 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); Constructor Create (Var O: Pointer);
Destructor Destroy; Override; Destructor Destroy; Override;
@ -42,7 +46,7 @@ Type
Function IsBlankLine (Var Line; LineSize: Byte) : Boolean; Function IsBlankLine (Var Line; LineSize: Byte) : Boolean;
Function GetLineLength (Var Line; LineSize: Byte) : Byte; Function GetLineLength (Var Line; LineSize: Byte) : Byte;
Function GetWrapPos (Var Line; LineSize, WrapPos: 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 DeleteLine (Line: LongInt);
Procedure InsertLine (Line: LongInt); Procedure InsertLine (Line: LongInt);
Function GetLineText (Line: Word) : String; Function GetLineText (Line: Word) : String;
@ -50,10 +54,11 @@ Type
Procedure FindLastLine; Procedure FindLastLine;
Procedure Reformat; Procedure Reformat;
Procedure LocateCursor; Procedure LocateCursor;
Procedure ReDrawTemplate; Procedure ToggleInsert (Toggle: Boolean);
Procedure ReDrawTemplate (Reset: Boolean);
Procedure DrawPage (StartY, EndY: Byte; ExitEOF: Boolean); Procedure DrawPage (StartY, EndY: Byte; ExitEOF: Boolean);
Procedure ScrollUp; Procedure ScrollUp;
Procedure ScrollDown; Procedure ScrollDown (Draw: Boolean);
Function LineUp : Boolean; Function LineUp : Boolean;
Function LineDown (Reset: Boolean) : Boolean; Function LineDown (Reset: Boolean) : Boolean;
Procedure PageUp; Procedure PageUp;
@ -64,7 +69,11 @@ Type
Procedure DoDelete; Procedure DoDelete;
Procedure DoChar (Ch: Char); Procedure DoChar (Ch: Char);
Function Edit : Boolean; Function Edit : Boolean;
Procedure LoadANSI;
procedure quote;
procedure quotewindow;
procedure commands;
procedure messageupload;
End; End;
Implementation Implementation
@ -130,8 +139,6 @@ Begin
End; End;
Procedure TEditorANSI.FindLastLine; Procedure TEditorANSI.FindLastLine;
Var
Count : LongInt;
Begin Begin
LastLine := mysMaxMsgLines; LastLine := mysMaxMsgLines;
@ -172,7 +179,7 @@ Begin
Result := EndPos = 0; Result := EndPos = 0;
End; End;
Procedure TEditorANSI.TrimLine (Var Line; LineSize: Byte); Procedure TEditorANSI.TrimLeft (Var Line; LineSize: Byte);
Var Var
Data : Array[1..255] of RecAnsiBufferChar absolute Line; Data : Array[1..255] of RecAnsiBufferChar absolute Line;
EndPos : Byte; EndPos : Byte;
@ -186,14 +193,6 @@ Begin
Inc (EndPos); Inc (EndPos);
End; 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; End;
Procedure TEditorANSI.DeleteLine (Line: LongInt); Procedure TEditorANSI.DeleteLine (Line: LongInt);
@ -267,7 +266,7 @@ Var
If NewY > WinSize Then NewY := WinSize; If NewY > WinSize Then NewY := WinSize;
If CurY > WinSize Then If CurY > WinSize Then
ScrollDown ScrollDown(True)
Else Else
DrawPage (StartY, NewY, True); DrawPage (StartY, NewY, True);
End; End;
@ -321,7 +320,7 @@ Begin
Move (TempStr[LineSize], WrapData, (GetLineLength(TempStr, 255) - LineSize + 1) * SizeOf(RecAnsiBufferChar)); Move (TempStr[LineSize], WrapData, (GetLineLength(TempStr, 255) - LineSize + 1) * SizeOf(RecAnsiBufferChar));
FillChar (TempStr[LineSize], (255 - LineSize) * SizeOf(RecAnsiBufferChar), #0); FillChar (TempStr[LineSize], (255 - LineSize) * SizeOf(RecAnsiBufferChar), #0);
TrimLine (WrapData, 255); TrimLeft (WrapData, 255);
If First Then Begin If First Then Begin
If CurX > LineSize Then Begin If CurX > LineSize Then Begin
@ -339,17 +338,7 @@ Begin
Move (TempStr, ANSI.Data[Count], RowSize * SizeOf(RecAnsiBufferChar)); Move (TempStr, ANSI.Data[Count], RowSize * SizeOf(RecAnsiBufferChar));
If LineSize = 0 Then Begin If LineSize = 0 Then Begin
If First Then Begin EndLine := Count;
CurX := 1;
Inc (CurLine);
Inc (CurY);
If CurLine > LastLine Then LastLine := CurLine;
EndLine := Count + 1;
End Else
EndLine := Count;
Update; Update;
@ -358,49 +347,46 @@ Begin
Inc (Count); Inc (Count);
End; End;
// Update;
End; End;
Procedure TEditorANSI.ReDrawTemplate; Procedure TEditorANSI.ToggleInsert (Toggle: Boolean);
// temp stuff to be replaced by real template Begin
Var If Toggle Then InsertMode := Not InsertMode;
B : TAnsiMenuBox;
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 Begin
TBBSCore(Owner).io.AllowArrow := True; TBBSCore(Owner).io.AllowArrow := True;
TBBSCore(Owner).io.AnsiColor(7); Session.io.PromptInfo[2] := Subj;
TBBSCore(Owner).io.AnsiClear;
(* Session.io.OutFile ('ansiedit', True, 0);
B := TAnsiMenuBox.Create;
B.FrameType := 1;
B.Open (5, 2, 75, 23);
B.Free;
WinX1 := 6;
WinX2 := 74;
WinY1 := 3;
WinY2 := 22;
*)
WinX1 := 1; WinX1 := 1;
WinX2 := 79; WinX2 := 79;
WinY1 := 2; WinY1 := Session.io.ScreenInfo[1].Y;
WinY2 := 23; WinY2 := Session.io.ScreenInfo[2].Y;
WinSize := WinY2 - WinY1 + 1; WinSize := WinY2 - WinY1 + 1;
RowSize := WinX2 - WinX1 + 1; RowSize := WinX2 - WinX1 + 1;
CurX := 1;
CurY := 1;
ClearEOL := RowSize >= 79; ClearEOL := RowSize >= 79;
//LoadANSI; If Reset Then Begin
FindLastLine; CurX := 1;
CurY := 1;
CurAttr := Session.io.ScreenInfo[1].A;
FindLastLine;
End;
DrawPage(1, WinSize, False); DrawPage(1, WinSize, False);
ToggleInsert (False);
End; End;
Procedure TEditorANSI.LocateCursor; Procedure TEditorANSI.LocateCursor;
@ -424,10 +410,6 @@ Begin
End; End;
With TBBSCore(Owner).io Do Begin 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); AnsiGotoXY (WinX1 + CurX - 1, WinY1 + CurY - 1);
AnsiColor (CurAttr); AnsiColor (CurAttr);
@ -438,7 +420,6 @@ End;
Procedure TEditorANSI.DrawPage (StartY, EndY: Byte; ExitEOF: Boolean); Procedure TEditorANSI.DrawPage (StartY, EndY: Byte; ExitEOF: Boolean);
Var Var
CountY : LongInt; CountY : LongInt;
CountX : Byte;
Begin Begin
For CountY := StartY to EndY Do Begin For CountY := StartY to EndY Do Begin
If TopLine + CountY - 1 > LastLine + 1 Then Begin If TopLine + CountY - 1 > LastLine + 1 Then Begin
@ -452,8 +433,8 @@ Begin
End Else End Else
If TopLine + CountY - 1 = LastLine + 1 Then Begin If TopLine + CountY - 1 = LastLine + 1 Then Begin
TBBSCore(Owner).io.AnsiGotoXY (WinX1, WinY1 + CountY - 1); TBBSCore(Owner).io.AnsiGotoXY (WinX1, WinY1 + CountY - 1);
TBBSCore(Owner).io.AnsiColor (12); TBBSCore(Owner).io.AnsiColor (8);
TBBSCore(Owner).io.BufAddStr (strPadC('-----END-----', RowSize, ' ')); TBBSCore(Owner).io.BufAddStr (strPadC('(END)', RowSize, ' '));
If ExitEOF Then Break; If ExitEOF Then Break;
End Else End Else
@ -475,7 +456,7 @@ Begin
DrawPage(1, WinSize, False); DrawPage(1, WinSize, False);
End; End;
Procedure TEditorANSI.ScrollDown; Procedure TEditorANSI.ScrollDown (Draw: Boolean);
Var Var
NewTop : LongInt; NewTop : LongInt;
Begin Begin
@ -487,7 +468,8 @@ Begin
CurY := CurLine - NewTop + 1; CurY := CurLine - NewTop + 1;
TopLine := NewTop; TopLine := NewTop;
DrawPage(1, WinSize, False); If Draw Then
DrawPage(1, WinSize, False);
End; End;
Function TEditorANSI.LineUp : Boolean; Function TEditorANSI.LineUp : Boolean;
@ -524,27 +506,9 @@ Begin
If CurY > WinSize Then Begin If CurY > WinSize Then Begin
Result := True; Result := True;
ScrollDown; ScrollDown(True);
End; End;
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); Procedure TEditorANSI.DrawLine (Line: LongInt; XP, YP: Byte);
Var Var
@ -758,34 +722,6 @@ Begin
DrawPage(1, WinSize, False); DrawPage(1, WinSize, False);
End; 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; Procedure TEditorANSI.DoEnter;
Var Var
TempLine : RecAnsiBufferLine; TempLine : RecAnsiBufferLine;
@ -810,16 +746,437 @@ Begin
LineDown(True); LineDown(True);
End; 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; Function TEditorANSI.Edit : Boolean;
Var Var
Ch : Char; Ch : Char;
Attr : Byte;
Begin Begin
Result := False; Result := False;
QuoteCurLine := 0;
QuoteTopPage := 1;
ReDrawTemplate; ReDrawTemplate(True);
While Not TBBSCore(Owner).ShutDown Do Begin Repeat
LocateCursor; LocateCursor;
Ch := TBBSCore(Owner).io.GetKey; Ch := TBBSCore(Owner).io.GetKey;
@ -827,19 +1184,27 @@ Begin
If Session.io.IsArrow Then Begin If Session.io.IsArrow Then Begin
Case Ch of Case Ch of
#71 : CurX := 1; #71 : CurX := 1;
#79 : CurX := CurLength + 1;
#72 : LineUp; #72 : LineUp;
#80 : If CurLine < LastLine Then LineDown(False); #73 : PageUp;
#75 : If CurX > 1 Then Dec(CurX); #75 : If CurX > 1 Then Dec(CurX);
#77 : If CurX <= RowSize Then Inc(CurX); #77 : If CurX <= RowSize Then Inc(CurX);
#73 : PageUp; #79 : CurX := CurLength + 1;
#80 : If CurLine < LastLine Then LineDown(False);
#81 : PageDown; #81 : PageDown;
#83 : DoDelete; #83 : DoDelete;
End; End;
End Else End Else
Case Ch of Case Ch of
^V : InsertMode := Not InsertMode; //update on screen ^Q : Begin
^Y : 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); DeleteLine (CurLine);
If CurLine > LastLine Then If CurLine > LastLine Then
@ -847,20 +1212,38 @@ Begin
DrawPage (CurY, WinSize, False); DrawPage (CurY, WinSize, False);
End; End;
^Z : Break; ^Z,
^[ : Begin
Commands;
If (Not Save) and (Not Done) Then ReDrawTemplate(False);
Session.io.AllowArrow := True;
End;
#08 : DoBackSpace; #08 : DoBackSpace;
#13 : DoEnter; #13 : DoEnter;
#32.. #32..
#254 : If (CurLength >= RowSize) and (GetWrapPos(ANSI.Data[CurLine], RowSize, RowSize) = 0) Then Begin #254 : If (CurLength >= RowSize) and (GetWrapPos(ANSI.Data[CurLine], RowSize, RowSize) = 0) Then Begin
If CurX = CurLength + 1 Then Begin // dont do anything
LineDown(True); End Else
End; If (CurX = 1) and (Ch = '/') Then Begin
Commands;
If (Not Save) and (Not Done) Then ReDrawTemplate(False);
Session.io.AllowArrow := True;
End Else End Else
DoChar(Ch); DoChar(Ch);
End; 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;
End. End.

View File

@ -155,6 +155,7 @@ Begin
If CurX > WrapPos Then Begin If CurX > WrapPos Then Begin
Inc (NewLine); Inc (NewLine);
Inc (NewY); Inc (NewY);
CurX := 1; CurX := 1;
End; End;
@ -169,7 +170,7 @@ Begin
End Else Begin End Else Begin
Session.io.BufFlush; 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 If (A > 0) And (Not Moved) And (CurX > Length(OldStr) + 1) Then Begin
CurX := CurX - A; 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 If (Session.Msgs.MsgText[Line] = '') or ((Pos(' ', Session.Msgs.MsgText[Line]) = 0) And (Length(Session.Msgs.MsgText[Line]) >= WrapPos)) Then Begin
InsertLine(Line); InsertLine(Line);
OldStr := NewStr; OldStr := NewStr;
End Else End Else
OldStr := NewStr + ' ' + Session.Msgs.MsgText[Line]; OldStr := NewStr + ' ' + Session.Msgs.MsgText[Line];
@ -192,6 +194,16 @@ Begin
Session.Msgs.MsgText[Line] := OldStr; 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 If NewY <= WinEnd Then Begin
Session.io.AnsiGotoXY(1, CurY); Session.io.AnsiGotoXY(1, CurY);
@ -215,6 +227,7 @@ Begin
CurLine := NewLine; CurLine := NewLine;
If CurY > WinEnd Then TextRefreshFull Else UpdatePosition; If CurY > WinEnd Then TextRefreshFull Else UpdatePosition;
*)
End; End;
Procedure keyEnter; Procedure keyEnter;
@ -977,7 +990,7 @@ Begin
Lines := TotalLine; Lines := TotalLine;
End; End;
Result := (Save = True); Result := Save;
Session.io.AnsiGotoXY (1, Session.User.ThisUser.ScreenSize); Session.io.AnsiGotoXY (1, Session.User.ThisUser.ScreenSize);

View File

@ -11,6 +11,7 @@ Implementation
Uses Uses
m_Strings, m_Strings,
m_FileIO,
bbs_Common, bbs_Common,
bbs_Core, bbs_Core,
bbs_FileBase, bbs_FileBase,
@ -21,6 +22,57 @@ Var
Done, Done,
Save : Boolean; 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; Procedure Quote;
Var Var
InFile : Text; InFile : Text;
@ -111,7 +163,7 @@ Function LineEditor (Var Lines : Integer; MaxLen: Byte; MaxLine: Integer; TEdit,
Done := True; Done := True;
End; End;
'U' : Begin 'U' : Begin
Session.Msgs.MessageUpload(CurLine); MessageUpload(CurLine);
Exit; Exit;
End; End;
End; End;

View File

@ -75,7 +75,6 @@ Type
Procedure SetFileScan; Procedure SetFileScan;
Procedure GetFileScan; Procedure GetFileScan;
Function SelectProtocol (UseDefault, Batch: Boolean) : Char; Function SelectProtocol (UseDefault, Batch: Boolean) : Char;
Function WildcardMatch (Wildcard, FName: String) : Boolean;
Procedure CheckFileNameLength (FPath : String; Var FName: String); Procedure CheckFileNameLength (FPath : String; Var FName: String);
Procedure GetFileDescription (FN: String); Procedure GetFileDescription (FN: String);
Function CheckFileLimits (DL: Byte; DLK: Integer) : Byte; Function CheckFileLimits (DL: Byte; DLK: Integer) : Byte;
@ -933,32 +932,6 @@ Begin
If Not Result Then Session.io.OutFullLn(Session.GetPrompt(425)); If Not Result Then Session.io.OutFullLn(Session.GetPrompt(425));
End; 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; Function TFileBase.ArchiveList (FName : String) : Boolean;
Var Var
Arc : PArchive; Arc : PArchive;
@ -2036,7 +2009,7 @@ Var
Case Mode of Case Mode of
1 : If Data <> '' Then 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; 2 : If FDir.DateTime < FScan.LastNew Then Exit;
3 : Begin 3 : Begin
T2 := Bool_Search(Data, FDir.FileName); T2 := Bool_Search(Data, FDir.FileName);
@ -3629,7 +3602,7 @@ Begin
End; End;
If Back Then Seek (FDirFile, FilePos(FDirFile) - 2); If Back Then Seek (FDirFile, FilePos(FDirFile) - 2);
Read (FDirFile, FDir); 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; Break;
Until False; Until False;
End; End;
@ -3770,7 +3743,9 @@ Begin
Session.User.IgnoreGroup := True; Session.User.IgnoreGroup := True;
Repeat Repeat
Session.io.OutFull ('|CR|09Move to which base (?/List): '); Session.io.OutFull ('|CR|09Move to which base (?/List): ');
Temp := Session.io.GetInput(4, 4, 12, ''); Temp := Session.io.GetInput(4, 4, 12, '');
If Temp = '?' Then Begin If Temp = '?' Then Begin
Old := FBase; Old := FBase;
ListFileAreas(False); ListFileAreas(False);
@ -3785,7 +3760,7 @@ Begin
Seek (FBaseFile, B - 1); Seek (FBaseFile, B - 1);
Read (FBaseFile, FBase); 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'); Session.io.OutFull ('ERROR|CR|CR|PA');
FBase := Old; FBase := Old;

View File

@ -67,8 +67,12 @@ Begin
For Count := 1 to Lines Do For Count := 1 to Lines Do
Editor.SetLineText (Count, Session.Msgs.MsgText[Count]); Editor.SetLineText (Count, Session.Msgs.MsgText[Count]);
Editor.Subj := Subj;
Result := Editor.Edit; Result := Editor.Edit;
Subj := Editor.Subj;
If Result Then Begin If Result Then Begin
For Count := 1 to Editor.LastLine Do For Count := 1 to Editor.LastLine Do
Session.Msgs.MsgText[Count] := Editor.GetLineText(Count); Session.Msgs.MsgText[Count] := Editor.GetLineText(Count);

View File

@ -11,7 +11,8 @@ Uses
bbs_General, bbs_General,
bbs_MsgBase_ABS, bbs_MsgBase_ABS,
bbs_MsgBase_JAM, bbs_MsgBase_JAM,
bbs_MsgBase_Squish; bbs_MsgBase_Squish,
bbs_Edit_ANSI;
Type Type
TMsgBase = Class TMsgBase = Class
@ -40,6 +41,7 @@ Type
Function GetBaseCompressed (Num: LongInt; Var TempBase: RecMessageBase) : Boolean; Function GetBaseCompressed (Num: LongInt; Var TempBase: RecMessageBase) : Boolean;
Function GetBaseByIndex (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); 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 GetTotalBases (Compressed: Boolean) : LongInt;
Function GetTotalMessages (Var TempBase: RecMessageBase) : LongInt; Function GetTotalMessages (Var TempBase: RecMessageBase) : LongInt;
Procedure PostTextFile (Data: String; AllowCodes: Boolean); Procedure PostTextFile (Data: String; AllowCodes: Boolean);
@ -50,7 +52,6 @@ Type
Procedure SetMessageScan; Procedure SetMessageScan;
Procedure GetMessageScan; Procedure GetMessageScan;
Procedure SendMassEmail; Procedure SendMassEmail;
Procedure MessageUpload (Var CurLine: SmallInt);
Procedure ReplyMessage (Email: Boolean; ListMode: Byte; ReplyID: String); Procedure ReplyMessage (Email: Boolean; ListMode: Byte; ReplyID: String);
Procedure EditMessage; Procedure EditMessage;
Function ReadMessages (Mode: Char; CmdData, SearchStr: String) : Boolean; Function ReadMessages (Mode: Char; CmdData, SearchStr: String) : Boolean;
@ -127,6 +128,21 @@ Begin
Inherited Destroy; Inherited Destroy;
End; 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; Function TMsgBase.NetmailLookup (FromMenu: Boolean; MsgTo, DefAddr: String) : String;
Procedure ShowNode (ShowType: Byte; NodeData: RecNodeSearch; Ext: Boolean); Procedure ShowNode (ShowType: Byte; NodeData: RecNodeSearch; Ext: Boolean);
@ -563,13 +579,12 @@ Begin
If MBase.NetType > 0 Then Begin If MBase.NetType > 0 Then Begin
Msg^.DoStringLn (#13 + '--- ' + mysSoftwareID + ' BBS v' + mysVersion + ' (' + OSID + ')'); 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;
End; End;
Procedure TMsgBase.AssignMessageData (Var Msg: PMsgBaseABS; Var TempBase: RecMessageBase); Procedure TMsgBase.AssignMessageData (Var Msg: PMsgBaseABS; Var TempBase: RecMessageBase);
Var Var
Addr : RecEchoMailAddr;
SemFile : Text; SemFile : Text;
Begin Begin
Msg^.StartNewMsg; Msg^.StartNewMsg;
@ -587,9 +602,7 @@ Begin
Else Else
Msg^.SetMailType(mmtEchoMail); Msg^.SetMailType(mmtEchoMail);
Addr := Config.NetAddress[TempBase.NetAddr]; Msg^.SetOrig(Config.NetAddress[TempBase.NetAddr]);
Msg^.SetOrig(Addr);
Case TempBase.NetType of Case TempBase.NetType of
1 : Begin 1 : Begin
@ -1152,8 +1165,8 @@ Begin
If DoWrap Then Begin If DoWrap Then Begin
If WrapData <> '' Then Begin If WrapData <> '' Then Begin
If TempStr = '' Then Begin If TempStr = '' Then Begin
WriteLn (QuoteFile, Initials + strStripB(WrapData, ' ')); WriteLn (QuoteFile, ' ' + Initials + strStripB(WrapData, ' '));
WriteLn (QuoteFile, Initials); WriteLn (QuoteFile, ' ' + Initials);
WrapData := ''; WrapData := '';
@ -1163,11 +1176,11 @@ Begin
TempStr := strStripB(WrapData, ' ') + ' ' + strStripL(TempStr, ' '); TempStr := strStripB(WrapData, ' ') + ' ' + strStripL(TempStr, ' ');
End; 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 End Else
WriteLn (QuoteFile, Initials + Copy(TempStr, 1, 75)); WriteLn (QuoteFile, ' ' + Initials + Copy(TempStr, 1, 75));
End; End;
Close (QuoteFile); Close (QuoteFile);
@ -1188,13 +1201,11 @@ Begin
2 : MsgNew^.SetTo('All'); 2 : MsgNew^.SetTo('All');
3 : Begin 3 : Begin
MsgNew^.SetDest (Addr); MsgNew^.SetDest (Addr);
MsgNew^.SetOrig (GetMatchedAddress(Config.NetAddress[MBase.NetAddr], Addr));
MsgNew^.SetCrash (Config.netCrash); MsgNew^.SetCrash (Config.netCrash);
MsgNew^.SetHold (Config.netHold); MsgNew^.SetHold (Config.netHold);
MsgNew^.SetKillSent (Config.netKillSent); MsgNew^.SetKillSent (Config.netKillSent);
MsgNew^.SetTo (ToWho); MsgNew^.SetTo (ToWho);
Addr := Config.NetAddress[MBase.NetAddr];
MsgNew^.SetOrig (Addr);
End; End;
Else Else
MsgNew^.SetTo (ToWho); MsgNew^.SetTo (ToWho);
@ -1326,6 +1337,7 @@ Begin
Until False; Until False;
End; End;
(*
Procedure TMsgBase.MessageUpload (Var CurLine: SmallInt); Procedure TMsgBase.MessageUpload (Var CurLine: SmallInt);
Var Var
FN : String[100]; FN : String[100];
@ -1376,6 +1388,7 @@ Begin
Session.io.PromptInfo[1] := T1; Session.io.PromptInfo[1] := T1;
Session.io.PromptInfo[2] := T2; Session.io.PromptInfo[2] := T2;
End; End;
*)
Function TMsgBase.ReadMessages (Mode: Char; CmdData, SearchStr: String) : Boolean; Function TMsgBase.ReadMessages (Mode: Char; CmdData, SearchStr: String) : Boolean;
Var Var
@ -2900,10 +2913,7 @@ Begin
MsgBase^.SetCrash (Config.netCrash); MsgBase^.SetCrash (Config.netCrash);
MsgBase^.SetHold (Config.netHold); MsgBase^.SetHold (Config.netHold);
MsgBase^.SetKillSent (Config.netKillSent); MsgBase^.SetKillSent (Config.netKillSent);
MsgBase^.SetOrig (GetMatchedAddress(Config.NetAddress[MBase.NetAddr], DestAddr));
DestAddr := Config.NetAddress[MBase.NetAddr];
MsgBase^.SetOrig (DestAddr);
End; End;
AppendMessageText (MsgBase, Lines, ''); AppendMessageText (MsgBase, Lines, '');
@ -3556,7 +3566,7 @@ Begin
Msg^.SetLocal (True); Msg^.SetLocal (True);
If mArea.NetType > 0 Then Begin If mArea.NetType > 0 Then Begin
If mArea.NetType = 2 Then Begin If mArea.NetType = 3 Then Begin
Msg^.SetMailType (mmtNetMail); Msg^.SetMailType (mmtNetMail);
Msg^.SetCrash (Config.netCrash); Msg^.SetCrash (Config.netCrash);
Msg^.SetHold (Config.netHold); Msg^.SetHold (Config.netHold);
@ -3590,7 +3600,7 @@ Begin
If mArea.NetType > 0 Then Begin If mArea.NetType > 0 Then Begin
Msg^.DoStringLn (#13 + '--- ' + mysSoftwareID + ' BBS v' + mysVersion + ' (' + OSID + ')'); 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; End;
Msg^.WriteMsg; Msg^.WriteMsg;
@ -4341,7 +4351,7 @@ Begin
If TempBase.NetType > 0 Then Begin If TempBase.NetType > 0 Then Begin
MsgBase^.DoStringLn (#13 + '--- ' + mysSoftwareID + '/QWK v' + mysVersion + ' (' + OSID + ')'); 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; End;
If Not IsControl Then Begin If Not IsControl Then Begin

View File

@ -221,10 +221,10 @@ Begin
Case FocusCurrent of Case FocusCurrent of
FocusTelnet : If TelnetServer <> NIL Then Break; FocusTelnet : If TelnetServer <> NIL Then Break;
FocusSMTP : If SmtpServer <> NIL Then Break; FocusSMTP : If SmtpServer <> NIL Then Break;
FocusPOP3 : If Pop3Server <> NIL Then Break; FocusPOP3 : If Pop3Server <> NIL Then Break;
FocusFTP : If FtpServer <> NIL Then Break; FocusFTP : If FtpServer <> NIL Then Break;
FocusNNTP : If NNTPServer <> NIL Then Break; FocusNNTP : If NNTPServer <> NIL Then Break;
End; End;
Until False; Until False;

View File

@ -505,7 +505,7 @@ Begin
If (Dir.Flags And FDirInvalid <> 0) And (Not CheckAccess(User, True, bbsConfig.AcsSeeUnvalid)) Then Continue; 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 (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); DataSocket.WriteLine(Dir.FileName);
End; End;
End; End;
@ -548,7 +548,7 @@ Begin
While Not FBaseFile.EOF Do Begin While Not FBaseFile.EOF Do Begin
FBaseFile.Read(TempBase); 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) DataSocket.WriteLine('drwxr-xr-x 1 ftp ftp 0 Jul 11 23:35 ' + TempBase.FtpName)
End; End;
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 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 (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) DataSocket.WriteLine('-rw-r--r-- 1 ftp ftp ' + strPadL(strI2S(Dir.Size), 13, ' ') + ' Jul 11 23:35 ' + Dir.FileName)
End; End;
End; End;
@ -612,7 +612,7 @@ Begin
While Not DirFile.EOF Do Begin While Not DirFile.EOF Do Begin
DirFile.Read(Dir); DirFile.Read(Dir);
If WildcardMatch(FileMask, Dir.FileName) Then Begin If WildMatch(FileMask, Dir.FileName, False) Then Begin
Found := DirFile.FilePos; Found := DirFile.FilePos;
Break; Break;
End; End;

View File

@ -18,7 +18,6 @@ Var
Function SearchForUser (UN: String; Var Rec: RecUser; Var RecPos: LongInt) : Boolean; Function SearchForUser (UN: String; Var Rec: RecUser; Var RecPos: LongInt) : Boolean;
Function CheckAccess (User: RecUser; IgnoreGroup: Boolean; Str: String) : Boolean; Function CheckAccess (User: RecUser; IgnoreGroup: Boolean; Str: String) : Boolean;
Function WildcardMatch (Wildcard, FName: String) : Boolean;
Function GetSecurityLevel (Level: Byte; SecLevel: RecSecurity) : Boolean; Function GetSecurityLevel (Level: Byte; SecLevel: RecSecurity) : Boolean;
Implementation Implementation
@ -198,32 +197,6 @@ Begin
Result := Pos('%', Out) = 0; Result := Pos('%', Out) = 0;
End; 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; Function GetSecurityLevel (Level: Byte; SecLevel: RecSecurity) : Boolean;
Var Var
SecLevelFile : File of RecSecurity; SecLevelFile : File of RecSecurity;

View File

@ -13,7 +13,7 @@ Interface
Uses Uses
DOS; DOS;
Function ToUnixDate (FDate: LongInt): LongInt; Function ToUnixDate (DosDate: LongInt): LongInt;
Function DTToUnixDate (DT: DateTime): LongInt; Function DTToUnixDate (DT: DateTime): LongInt;
Procedure UnixToDT (SecsPast: LongInt; Var Dt: DateTime); Procedure UnixToDT (SecsPast: LongInt; Var Dt: DateTime);
Procedure Str2Az (Str: String; MaxLen: Byte; Var AZStr); {Convert string to asciiz} Procedure Str2Az (Str: String; MaxLen: Byte; Var AZStr); {Convert string to asciiz}
@ -48,11 +48,11 @@ Begin
DTToUnixDate := SecsPast; DTToUnixDate := SecsPast;
End; End;
Function ToUnixDate (FDate: LongInt): LongInt; Function ToUnixDate (DosDate: LongInt): LongInt;
Var Var
DT: DateTime; DT: DateTime;
Begin Begin
UnpackTime(Fdate, DT); UnpackTime(DosDate, DT);
ToUnixDate := DTToUnixDate(DT); ToUnixDate := DTToUnixDate(DT);
End; End;

View File

@ -63,7 +63,7 @@
Import_MessageBase = false Import_MessageBase = false
Import_FILEBONE.NA = false Import_FILEBONE.NA = false
Import_FILES.BBS = false Import_FILES.BBS = false
MassUpload = false MassUpload = true
GenerateTopLists = false GenerateTopLists = false
GenerateAllFiles = false GenerateAllFiles = false
PurgeMessageBases = false PurgeMessageBases = false
@ -205,6 +205,11 @@
no_description = No Description no_description = No Description
; Ignore list one file mask per line (allows * and ? wildcards)
ignore = files.bbs
;ignore = *.readme
; ========================================================================== ; ==========================================================================
; ========================================================================== ; ==========================================================================
; ========================================================================== ; ==========================================================================

View File

@ -202,7 +202,7 @@ Begin
If ProcessTotal = 0 Then Begin If ProcessTotal = 0 Then Begin
ProcessName ('Load configuration', False); ProcessName ('Load configuration', False);
ProcessStatus ('No processes configured!', True); ProcessStatus ('No processes configured', True);
ProcessResult (rFATAL, False); ProcessResult (rFATAL, False);
Halt(1); Halt(1);

View File

@ -353,8 +353,11 @@ Begin
End; End;
Function GetMBaseByNetZone (Zone: Word; Var TempBase: RecMessageBase) : Boolean; Function GetMBaseByNetZone (Zone: Word; Var TempBase: RecMessageBase) : Boolean;
// get netmail base with matching zone, or at least A netmail base if no match
Var Var
F : File; F : File;
One : RecMessageBase;
GotOne : Boolean;
Begin Begin
Result := False; Result := False;
@ -365,13 +368,24 @@ Begin
While Not Eof(F) Do Begin While Not Eof(F) Do Begin
ioRead(F, TempBase); ioRead(F, TempBase);
If (Zone = bbsConfig.NetAddress[TempBase.NetAddr].Zone) and (TempBase.NetType = 3) Then Begin If (TempBase.NetType = 3) Then Begin
Result := True; One := TempBase;
Break; GotOne := True;
If Zone = bbsConfig.NetAddress[TempBase.NetAddr].Zone Then Begin
Result := True;
Break;
End;
End; End;
End; End;
Close (F); Close (F);
If Not Result And GotOne Then Begin
Result := True;
TempBase := One;
End;
End; End;
Function MessageBaseOpen (Var Msg: PMsgBaseABS; Var Area: RecMessageBase) : Boolean; Function MessageBaseOpen (Var Msg: PMsgBaseABS; Var Area: RecMessageBase) : Boolean;

View File

@ -29,22 +29,13 @@ Var
Begin Begin
FileMode := 66; FileMode := 66;
log(3, '+', 'flo add: ' + floname + ' ' + packetfn);
Assign (T, FloName); Assign (T, FloName);
{$I-} Reset (T); {$I+} {$I-} Reset (T); {$I+}
If IoResult <> 0 Then Begin If IoResult <> 0 Then Begin
log(3, '+', 'flo reset failed');
{$I-} ReWrite(T); {$I+} {$I-} ReWrite(T); {$I+}
If IoResult <> 0 Then Begin
log(3, '+', 'unable to rewrite flo');
end;
Reset(T); Reset(T);
end; End;
While Not Eof(T) Do Begin While Not Eof(T) Do Begin
ReadLn (T, Str); ReadLn (T, Str);
@ -55,9 +46,6 @@ Begin
End; End;
End; End;
log(3, '+', 'flo close and append');
// Close (T);
Append (T); Append (T);
WriteLn (T, '^' + PacketFN); WriteLn (T, '^' + PacketFN);
Close (T); Close (T);
@ -101,6 +89,8 @@ Begin
FLOName := bbsConfig.OutboundPath + GetFTNFlowName(EchoNode.Address) + '.flo'; FLOName := bbsConfig.OutboundPath + GetFTNFlowName(EchoNode.Address) + '.flo';
BundleName := bbsConfig.OutboundPath + GetFTNArchiveName(OrigAddr, EchoNode.Address) + '.' + DayString[DayOfWeek(CurDateDos)]; 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'; BundleName[Length(BundleName)] := '0';
ExecuteArchive (BundleName, EchoNode.ArcType, TempPath + PKTName, 1); ExecuteArchive (BundleName, EchoNode.ArcType, TempPath + PKTName, 1);
@ -167,6 +157,8 @@ Var
TempStr2 := bbsConfig.OutboundPath + GetFTNFlowName(EchoNode.Address) + '.flo'; TempStr2 := bbsConfig.OutboundPath + GetFTNFlowName(EchoNode.Address) + '.flo';
// change extensions based on crash etc from echonode // change extensions based on crash etc from echonode
// need to add aka matching somewhere in here and also incorporate
// routing?
Assign (F, TempStr1); Assign (F, TempStr1);
@ -231,7 +223,9 @@ Var
If MBase.NetType <> 3 Then If MBase.NetType <> 3 Then
WriteStr ('AREA:' + MBase.EchoTag, #13); 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); WriteStr (#1 + 'TID: Mystic BBS ' + mysVersion, #13);
MsgBase^.MsgTxtStartUp; MsgBase^.MsgTxtStartUp;
@ -239,6 +233,9 @@ Var
While Not MsgBase^.EOM Do While Not MsgBase^.EOM Do
WriteStr (MsgBase^.GetString(79), #13); 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) + ' '; 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 If bbsConfig.NetAddress[MBase.NetAddr].Net <> EchoNode.Address.Net Then
@ -295,6 +292,9 @@ Begin
While MsgBase^.SeekFound Do Begin While MsgBase^.SeekFound Do Begin
MsgBase^.MsgStartUp; MsgBase^.MsgStartUp;
// uncomment islocal if/when we build downlinks on import instead
// of export
If {MsgBase^.IsLocal And } Not MsgBase^.IsSent Then Begin If {MsgBase^.IsLocal And } Not MsgBase^.IsSent Then Begin
Assign (ExportFile, MBase.Path + MBase.FileName + '.lnk'); Assign (ExportFile, MBase.Path + MBase.FileName + '.lnk');

View File

@ -267,4 +267,4 @@ Begin
ProcessResult (rDONE, True); ProcessResult (rDONE, True);
End; End;
End. End.

View File

@ -29,6 +29,8 @@ Var
Desc : Array[1..99] of String[50]; Desc : Array[1..99] of String[50];
Count : Integer; Count : Integer;
FilesAdded : LongInt = 0; FilesAdded : LongInt = 0;
IgnoreList : Array[1..100] of String[80];
IgnoreSize : Byte = 0;
Procedure RemoveDesc (Num: Byte); Procedure RemoveDesc (Num: Byte);
Var Var
@ -46,6 +48,26 @@ Begin
ProcessName ('Mass Upload Files', True); ProcessName ('Mass Upload Files', True);
ProcessResult (rWORKING, False); 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'); Assign (BaseFile, bbsConfig.DataPath + 'fbases.dat');
{$I-} Reset (BaseFile); {$I+} {$I-} Reset (BaseFile); {$I+}
@ -90,6 +112,13 @@ Begin
{$ENDIF} {$ENDIF}
End; 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 If Not Found Then Begin
Log (1, '+', ' Add: ' + DirInfo.Name + ' To: ' + strStripPipe(Base.Name)); Log (1, '+', ' Add: ' + DirInfo.Name + ' To: ' + strStripPipe(Base.Name));

View File

@ -29,7 +29,11 @@ BUGS AND POSSIBLE ISSUES
FUTURE / IDEAS / WORK IN PROGRESS / NOTES 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) - 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 - New files list to MUTIL based X number of days
- All/new file list template files like TOP XX - All/new file list template files like TOP XX
- MUTIL create FILES.BBS in the file base directory - MUTIL create FILES.BBS in the file base directory

View File

@ -2912,3 +2912,37 @@
+ The echomail node editor now has an editor where message bases can be + The echomail node editor now has an editor where message bases can be
list, linked, and unlinked from each configured node. 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