diff --git a/mystic/bbs_cfg_echomail.pas b/mystic/bbs_cfg_echomail.pas index 1d50866..7727077 100644 --- a/mystic/bbs_cfg_echomail.pas +++ b/mystic/bbs_cfg_echomail.pas @@ -8,6 +8,10 @@ Uses BBS_Core, BBS_Common; +Function GetNodeByIndex (Num: LongInt; Var TempNode: RecEchoMailNode) : Boolean; +Procedure AddExportByBase (Var MBase: RecMessageBase; Idx: LongInt); +Procedure RemoveExportFromBase (Var MBase: RecMessageBase; Idx: LongInt); + Function Configuration_EchoMailNodes (Edit: Boolean) : LongInt; Function Configuration_EchomailAddress (Edit: Boolean) : Byte; Procedure Configuration_NodeExport (Var MBase: RecMessageBase); @@ -140,12 +144,12 @@ Begin Box.Open (3, 5, 76, 21); - VerticalLine (19, 7, 12); - VerticalLine (19, 15, 19); + VerticalLine (19, 7, 13); + VerticalLine (19, 16, 20); VerticalLine (53, 7, 11); // VerticalLine (53, 14, 19); - WriteXY (13, 14, 112, 'BINKP'); + WriteXY (13, 15, 112, 'BINKP'); // WriteXY (49, 13, 112, 'FTP'); Form.AddStr ('D', ' Description' , 6, 7, 21, 7, 13, 23, 35, @Node.Description, Topic + 'Node description'); @@ -154,12 +158,13 @@ Begin Form.AddTog ('E', ' Network Type' , 5, 10, 21, 10, 14, 7, 0, 1, 'FidoNet QWK', @Node.NetType, Topic); Form.AddTog ('L', ' Session Type' , 5, 11, 21, 11, 14, 5, 0, 1, 'BinkP FTP', @Node.ProtType, Topic); Form.AddTog ('Y', ' Export Type' , 6, 12, 21, 12, 13, 6, 0, 3, 'Normal Crash Direct Hold', @Node.MailType, Topic); + Form.AddStr ('U', ' Route Info' , 7, 13, 21, 13, 12, 54, 128, @Node.RouteInfo, Topic + 'Route info (ie "2:* 3:*")'); - Form.AddStr ('H', ' Host' , 13, 15, 21, 15, 6, 20, 60, @Node.binkHost, Topic + ':'); - Form.AddMask ('S', ' Password' , 9, 16, 21, 16, 10, 20, 20, @Node.binkPass, Topic); - Form.AddWord ('T', ' TimeOut' , 10, 17, 21, 17, 9, 4, 10, 9999, @Node.binkTimeOut, Topic + 'Inactive session timeout (seconds)'); - Form.AddWord ('B', ' BlockSize' , 8, 18, 21, 18, 11, 5, 4096, 30720, @Node.binkBlock, Topic + 'Blocksize in bytes'); - Form.AddTog ('M', ' CRAM-MD5' , 9, 19, 21, 19, 10, 6, 0, 2, 'No Yes Forced', @Node.binkMD5, Topic); + Form.AddStr ('H', ' Host' , 13, 16, 21, 16, 6, 20, 60, @Node.binkHost, Topic + ':'); + Form.AddMask ('S', ' Password' , 9, 17, 21, 17, 10, 20, 20, @Node.binkPass, Topic); + Form.AddWord ('T', ' TimeOut' , 10, 18, 21, 18, 9, 4, 10, 9999, @Node.binkTimeOut, Topic + 'Inactive session timeout (seconds)'); + Form.AddWord ('B', ' BlockSize' , 8, 19, 21, 19, 11, 5, 4096, 30720, @Node.binkBlock, Topic + 'Blocksize in bytes'); + Form.AddTog ('M', ' CRAM-MD5' , 9, 20, 21, 20, 10, 6, 0, 2, 'No Yes Forced', @Node.binkMD5, Topic); Form.AddWord ('Z', ' Zone' , 47, 7, 55, 7, 6, 5, 0, 65535, @Node.Address.Zone, Topic + 'Network Zone'); Form.AddWord ('N', ' Net' , 48, 8, 55, 8, 5, 5, 0, 65535, @Node.Address.Net, Topic + 'Network Net'); @@ -393,7 +398,7 @@ Begin Break; End; - EditNode(EchoNode); + EditNode (EchoNode); Seek (EchoFile, List.Picked - 1); Write (EchoFile, EchoNode); @@ -412,12 +417,16 @@ End; Function Configuration_EchomailAddress (Edit: Boolean) : Byte; Procedure EditAddress (Num: Byte); + Label + Start; Var Box : TAnsiMenuBox; Form : TAnsiMenuForm; Topic : String; Count : Byte; Begin + Start: + Topic := '|03(|09Echomail Network|03) |01-|09> |15'; Box := TAnsiMenuBox.Create; Form := TAnsiMenuForm.Create; @@ -448,6 +457,11 @@ Function Configuration_EchomailAddress (Edit: Boolean) : Byte; Box.Close; Form.Free; Box.Free; + + If Config.NetDomain[Num] = '' Then Begin + ShowMsgBox(0, 'You must supply a domain'); + Goto Start; + End; End; Var diff --git a/mystic/bbs_cfg_msgbase.pas b/mystic/bbs_cfg_msgbase.pas index 88ee5d7..1f722f0 100644 --- a/mystic/bbs_cfg_msgbase.pas +++ b/mystic/bbs_cfg_msgbase.pas @@ -215,10 +215,15 @@ Var Var GBox : TAnsiMenuBox; Form : TAnsiMenuForm; - Active : Array[1..26] of Boolean; + Active : Array[1..28] of Boolean; ActCnt : Byte; Count : LongInt; Topic : String; + DelIdx : LongInt = -1; + DelStr : String = ''; + AddIdx : LongInt = -1; + AddStr : String = ''; + EN : RecEchoMailNode; Begin FillChar (Active, SizeOf(Active), 0); @@ -230,10 +235,10 @@ Var GBox.Open (6, 5, 75, 21); - VerticalLine (26, 7, 19); - VerticalLine (64, 7, 19); + VerticalLine (26, 7, 20); + VerticalLine (64, 7, 20); - For Count := 1 to 13 Do + For Count := 1 to 14 Do Form.AddBol ('!', '> ', 8, 6 + Count, 10, 6 + Count, 2, 3, @Active[Count], Topic + ChangeStr); Form.AddPath ('P', ' Path' , 20, 7, 28, 7, 6, 16, 80, @Global.Path, Topic + 'Message base storage path'); @@ -249,9 +254,10 @@ Var Form.AddStr ('M', ' L Template' , 14, 17, 28, 17, 12, 16, 20, @Global.ITemplate, Topic + 'Template for lightbar message list'); Form.AddTog ('A', ' Base Type' , 15, 18, 28, 18, 11, 9, 0, 3, 'Local EchoMail Newsgroup Netmail', @Global.NetType, Topic + 'Message base type'); Form.AddTog ('B', ' Base Format' , 13, 19, 28, 19, 13, 6, 0, 1, 'JAM Squish', @Global.BaseType, Topic + 'Message base storage format'); + Form.AddNone ('7', ' Export Add' , 14, 20, 28, 20, 12, Topic + 'Add EchoNode Export'); - For Count := 1 to 13 Do - Form.AddBol ('!', '> ', 45, 6 + Count, 47, 6 + Count, 2, 3, @Active[Count + 13], Topic + ChangeStr); + For Count := 1 to 14 Do + Form.AddBol ('!', '> ', 45, 6 + Count, 47, 6 + Count, 2, 3, @Active[Count + 14], Topic + ChangeStr); Form.AddAttr ('Q', ' Quote Color' , 51, 7, 66, 7, 13, @Global.ColQuote, Topic + 'Color for quoted text'); Form.AddAttr ('X', ' Text Color' , 52, 8, 66, 8, 12, @Global.ColText, Topic + 'Color for message text'); @@ -266,18 +272,37 @@ Var Form.AddBits ('5', ' Autosigs' , 54, 17, 66, 17, 10, MBAutoSigs, @Global.Flags, Topic + 'Allow auto signatures in this base?'); Form.AddBits ('6', ' Kill Kludge' , 51, 18, 66, 18, 13, MBKillKludge, @Global.Flags, Topic + 'Filter out kludge lines'); Form.AddBits ('V', ' Private' , 55, 19, 66, 19, 9, MBPrivate, @Global.Flags, Topic + 'Is this a private base?'); + Form.AddNone ('8', ' Export Kill' , 51, 20, 66, 20, 13, Topic + 'Remove EchoNode Export'); Form.LoExitChars := #21#27; Repeat WriteXY (28, 12, 113, strPadR(strAddr2Str(Config.NetAddress[Global.NetAddr]), 19, ' ')); + If AddStr <> '' Then + WriteXY (28, 20, 113, strPadR(AddStr, 12, ' ')); + + If DelStr <> '' Then + WriteXY (66, 20, 113, strPadR(DelStr, 8, ' ')); + Case Form.Execute of + '7' : Begin + AddIdx := Configuration_EchoMailNodes(False); + + If GetNodeByIndex(AddIdx, EN) Then + AddStr := strAddr2Str(EN.Address); + End; + '8' : Begin + DelIdx := Configuration_EchoMailNodes(False); + + If GetNodeByIndex(DelIdx, EN) Then + DelStr := strAddr2Str(EN.Address); + End; 'D' : Global.NetAddr := Configuration_EchoMailAddress(False); #21 : Begin ActCnt := 0; - For Count := 1 to 26 Do + For Count := 1 to 28 Do If Active[Count] Then Inc(ActCnt); If ShowMsgBox(1, 'Update ' + strI2S(ActCnt) + ' settings per base?') Then Begin @@ -300,22 +325,28 @@ Var 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 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 Active[15] Then MBase.ColQuote := Global.ColQuote; + If Active[16] Then MBase.ColText := Global.ColText; + If Active[17] Then MBase.ColTear := Global.ColTear; + If Active[18] Then MBase.ColOrigin := Global.ColOrigin; + If Active[19] Then MBase.ColKludge := Global.ColKludge; + If Active[20] Then MBase.MaxMsgs := Global.MaxMsgs; + If Active[21] Then MBase.MaxAge := Global.MaxAge; + If Active[22] Then MBase.DefNScan := Global.DefNScan; + If Active[23] Then MBase.DefQScan := Global.DefQScan; + If Active[24] Then BitSet(1, 4, MBase.Flags, (Global.Flags AND MBRealNames <> 0)); + If Active[25] Then BitSet(3, 4, MBase.Flags, (Global.Flags AND MBAutoSigs <> 0)); + If Active[26] Then BitSet(2, 4, MBase.Flags, (Global.Flags AND MBKillKludge <> 0)); + If Active[27] Then BitSet(5, 4, MBase.Flags, (Global.Flags AND MBPrivate <> 0)); Seek (MBaseFile, Count - 1); Write (MBaseFile, MBase); + + If Active[14] And (AddIdx <> -1) Then + AddExportByBase (MBase, AddIdx); + + If Active[28] And (DelIdx <> -1) Then + RemoveExportFromBase (MBase, DelIdx); End; Break; @@ -418,9 +449,24 @@ Var End; End; - Write(MBaseFile, MBase); + Write (MBaseFile, MBase); End; + Procedure EraseData; + Begin + FileErase (MBase.Path + MBase.FileName + '.jhr'); + FileErase (MBase.Path + MBase.FileName + '.jlr'); + FileErase (MBase.Path + MBase.FileName + '.jdt'); + FileErase (MBase.Path + MBase.FileName + '.jdx'); + FileErase (MBase.Path + MBase.FileName + '.sqd'); + FileErase (MBase.Path + MBase.FileName + '.sqi'); + FileErase (MBase.Path + MBase.FileName + '.sql'); + FileErase (MBase.Path + MBase.FileName + '.scn'); + End; + +Var + KillData : Boolean; + Count : LongInt; Begin Result := -1; @@ -459,24 +505,34 @@ Begin AssignRecord(False); MakeList; End; - 'D' : If (List.Picked > 1) and (List.Picked < List.ListMax) Then + 'D' : If List.Marked > 0 Then Begin + If ShowMsgBox(1, 'Delete ' + strI2S(List.Marked) + ' bases?') Then Begin + KillData := ShowMsgBox(1, 'Delete data files for ' + strI2S(List.Marked) + ' bases?'); + + For Count := List.ListMax DownTo 1 Do + If List.List[Count].Tagged = 1 Then Begin + Seek (MBaseFile, Count - 1); + Read (MBaseFile, MBase); + + KillRecord (MBaseFile, Count, SizeOf(MBase)); + FileErase (MBase.Path + MBase.FileName + '.lnk'); + + If KillData Then EraseData; + End; + + MakeList; + End; + End Else + If (List.Picked > 1) and (List.Picked < List.ListMax) Then If ShowMsgBox(1, 'Delete this entry?') Then Begin Seek (MBaseFile, List.Picked - 1); Read (MBaseFile, MBase); KillRecord (MBaseFile, List.Picked, SizeOf(MBase)); + FileErase (MBase.Path + MBase.FileName + '.lnk'); - If ShowMsgBox(1, 'Delete data files?') Then Begin - FileErase (MBase.Path + MBase.FileName + '.jhr'); - FileErase (MBase.Path + MBase.FileName + '.jlr'); - FileErase (MBase.Path + MBase.FileName + '.jdt'); - FileErase (MBase.Path + MBase.FileName + '.jdx'); - FileErase (MBase.Path + MBase.FileName + '.sqd'); - FileErase (MBase.Path + MBase.FileName + '.sqi'); - FileErase (MBase.Path + MBase.FileName + '.sql'); - FileErase (MBase.Path + MBase.FileName + '.scn'); - FileErase (MBase.Path + MBase.FileName + '.lnk'); - End; + If ShowMsgBox(1, 'Delete data: ' + strStripPipe(MBase.Name)) Then + EraseData; MakeList; End; diff --git a/mystic/bbs_msgbase.pas b/mystic/bbs_msgbase.pas index 45d6e41..57dc4f6 100644 --- a/mystic/bbs_msgbase.pas +++ b/mystic/bbs_msgbase.pas @@ -139,6 +139,7 @@ Begin For Count := 1 to 30 Do If Config.NetAddress[Count].Zone = Dest.Zone Then Begin Result := Config.NetAddress[Count]; + Exit; End; End; @@ -276,7 +277,7 @@ Begin Session.io.PromptInfo[7] := MsgTo; If Session.io.GetYN(Session.GetPrompt(502), True) Then Begin - Result := strAddr2Str(NodeData.Address); + Result := strAddr2Str(Addr); Break; End; @@ -295,7 +296,8 @@ Function TMsgBase.IsQuotedText (Str: String) : Boolean; Var Temp : Byte; Begin - Temp := Pos('>', strStripL(Str, ' ')); + Temp := Pos('>', Str); +// Temp := Pos('>', strStripL(Str, ' ')); Result := (Temp > 0) and (Temp < 5); End; @@ -1127,30 +1129,56 @@ Var DoWrap : Boolean = True; QuoteFile : Text; Lines : SmallInt; + Total : LongInt; ReplyBase : RecMessageBase; Begin ReplyBase := MBase; -(* - Session.io.OutFull('|CR|09Reply |01[|10ENTER|01] |09Current Base, |01[|10B|01]|09ase, |01[|10N|01]|09etmail, |01[|10E|01]|09mail, |01[|10ESC|01] |09Abort: |11'); + If Not Email Then Begin + Session.io.PromptInfo[1] := MBase.Name; + Session.io.PromptInfo[2] := MsgBase^.GetFrom; + Session.io.PromptInfo[3] := MsgBase^.GetSubj; - Case Session.io.OneKey (#13#27 + 'BNE', True) of - #27 : Exit; - 'B' : Begin - //Total := ListAreas(Config.MCompress); - //NEW something like: (and use it in other areas too) - //PromptMessageBase (Var Base: RMB, IgnoreGroups): LongInt; -1 is abort, otherwise = physical area - End; - 'E' : Begin - Reset (MBaseFile); - Read (MBaseFile, ReplyBase); - Close (MBaseFile); + If ListMode = 0 Then + Session.io.OutFull(Session.GetPrompt(509)) + Else + Session.io.OutFull(Session.GetPrompt(510)); - Email := True; - End; // load email area set email := true - 'N' : ; // load netmail area + Case Session.io.OneKey (#13#27 + 'QBNE', True) of + 'Q', + #27 : Exit; + 'B' : Begin + Total := ListAreas(Config.MCompress); + + Repeat + Session.io.OutFull(Session.GetPrompt(511)); + + Case Session.io.OneKeyRange(#13 + '?Q', 1, Total) of + #13, + 'Q': Exit; + '?': Total := ListAreas(Config.MCompress); + Else + Break; + End; + Until False; + + If Not GetBaseCompressed(Session.io.RangeValue, ReplyBase) Then + Exit; + End; + 'E' : Begin + Reset (MBaseFile); + Read (MBaseFile, ReplyBase); + Close (MBaseFile); + + Email := True; + End; + End; End; -*) + + Session.io.PromptInfo[1] := ReplyBase.Name; + + Session.io.OutFullLn(Session.GetPrompt(512)); + If Not Session.User.Access(ReplyBase.PostACS) Then Begin Session.io.OutFullLn (Session.GetPrompt(105)); Exit; @@ -1812,7 +1840,6 @@ Var Var Ch : Char; - A : LongInt; CurMsg : LongInt; Begin Result := False; @@ -1971,15 +1998,15 @@ Var Session.io.OutFull (Session.GetPrompt(403)); - A := strS2I(Session.io.GetInput(9, 9, 12, '')); + If Session.io.OneKeyRange(#13 + 'Q', 1, MsgBase^.GetHighMsgNum) = #0 Then Begin + MsgBase^.SeekFirst(Session.io.RangeValue); - If (A > 0) and (A <= MsgBase^.GetHighMsgNum) Then Begin - MsgBase^.SeekFirst(A); If Not SeekNextMsg(True, False) Then Begin MsgBase^.SeekFirst(CurMsg); SeekNextMsg(True, False); End; End; + Break; End; 'L' : Exit; @@ -2554,10 +2581,8 @@ Var Session.io.OutFull (Session.GetPrompt(334)); - A := strS2I(Session.io.GetInput(9, 9, 12, '')); - - If (A > 0) and (A <= MsgBase^.GetHighMsgNum) Then Begin - MsgBase^.SeekFirst(A); + If Session.io.OneKeyRange(#13 + 'Q', 1, MsgBase^.GetHighMsgNum) = #0 Then Begin + MsgBase^.SeekFirst(Session.io.RangeValue); If Not SeekNextMsg(True, False) Then Begin MsgBase^.SeekFirst(B); @@ -2623,6 +2648,7 @@ Var End; 'R' : Begin ReplyMessage (Mode = 'E', ListMode, ReplyID); + Break; End; 'T' : Begin diff --git a/mystic/default.txt b/mystic/default.txt index 65b7e85..0e437d1 100644 --- a/mystic/default.txt +++ b/mystic/default.txt @@ -1004,3 +1004,13 @@ 507 |10|$R15|&3 |09|$R20|&2 |11|$R42|&5 ; QuicScan message list footer 508 |09|$D79=|CR +; Message reply options (standard) +; &1=base name &2=reply to name &3=msg subject +509 |16|CL|09|17 ° |15Message Reply |$X79 |16|CR|CR|03 Area: |11|&1|CR |03To: |11|&2|CR|03 Subject: |11|$R65|&3|CR|CR|09Reply area (|11ENTER|09) Current, |09(|11B|09)ase, |09(|11E|09)mail, |09(|11Q|09)uit? |14 +; Message reply options (lightbar) +; &1=base name &2=reply to name &3=msg subject +510 |16|CL|09|17 ° |15Message Reply |$X79 |16|CR|CR|03 Area: |11|&1|CR |03To: |11|&2|CR|03 Subject: |11|$R65|&3|CR|CR|09Reply area (|11ENTER|09) Current, |09(|11B|09)ase, |09(|11E|09)mail, |09(|11Q|09)uit? |14 +; Message reply select base prompt +511 |CR|09Select message base for reply [|10?|09/|10List|09]: |11 +; Message "replying to X base" prompt &1=base name +512 |CR|03Posting reply message to base |11|&1|03. diff --git a/mystic/mpl_common.pas b/mystic/mpl_common.pas index 179e0b6..120bb47 100644 --- a/mystic/mpl_common.pas +++ b/mystic/mpl_common.pas @@ -381,6 +381,7 @@ Begin AddStr ({$IFDEF MPLPARSER} 'fbasename', {$ENDIF} iString, 40); AddStr ({$IFDEF MPLPARSER} 'fbaseacs', {$ENDIF} iString, 30); + AddStr ({$IFDEF MPLPARSER} 'fbasefn', {$ENDIF} iString, 40); End; 6 : Begin {$IFNDEF MPLPARSER} TInterpEngine(S).IdxVarFGroup := X + 1; {$ENDIF} diff --git a/mystic/mpl_execute.pas b/mystic/mpl_execute.pas index d28c5d7..904f44e 100644 --- a/mystic/mpl_execute.pas +++ b/mystic/mpl_execute.pas @@ -292,6 +292,7 @@ Procedure TInterpEngine.GetFBaseVars (Var F: RecFileBase); Begin Move (F.Name, VarData[IdxVarFBase ]^.Data^, SizeOf(F.Name)); Move (F.ListACS, VarData[IdxVarFBase + 1 ]^.Data^, SizeOf(F.ListACS)); + Move (F.FileName, VarData[IdxVarFBase + 2 ]^.Data^, SizeOf(F.FileName)); End; Function TInterpEngine.GetFBaseRecord (Num: LongInt) : Boolean; diff --git a/mystic/mutil.ini b/mystic/mutil.ini index 9cb8af4..700e7a2 100644 --- a/mystic/mutil.ini +++ b/mystic/mutil.ini @@ -417,6 +417,12 @@ dupe_db_size = 32000 + ; If you want to forward netmail from one user name to another, you can + ; define up to 50 remapped names below using the format ; + ; + ; forward = sysop;g00r00 + ; forward = system operator;g00r00 + ; If you want MUTIL to auto create message bases when it finds an ; echomail message for a non-existing base, set this value to true ; and use the options below to define the default values @@ -451,4 +457,5 @@ [ExportEchoMail] - ; no options for this area yet + ; no options + diff --git a/mystic/mutil_common.pas b/mystic/mutil_common.pas index 91e5e15..0ff61dc 100644 --- a/mystic/mutil_common.pas +++ b/mystic/mutil_common.pas @@ -93,6 +93,7 @@ Function GetFTNArchiveName (Orig, Dest: RecEchoMailAddr) : String; Function GetFTNFlowName (Dest: RecEchoMailAddr) : String; Function GetFTNOutPath (EchoNode: RecEchoMailNode) : String; Function GetNodeByIndex (Num: LongInt; Var TempNode: RecEchoMailNode) : Boolean; +Function GetNodeByRoute (Dest: RecEchoMailAddr; Var TempNode: RecEchoMailNode) : Boolean; Function IsValidAKA (Zone, Net, Node: Word) : Boolean; Implementation @@ -582,6 +583,111 @@ Begin Close (F); End; +Function GetNodeByRoute (Dest: RecEchoMailAddr; Var TempNode: RecEchoMailNode) : Boolean; + + Function IsMatch (Str: String) : Boolean; + + Function IsOneMatch (Mask: String) : Boolean; + Var + Zone : String; + Net : String; + Node : String; + A : Byte; + B : Byte; + Count : Byte; + Begin + Result := False; + Zone := ''; + Net := ''; + Node := ''; + A := Pos(':', Mask); + B := Pos('/', Mask); + + If A <> 0 Then Begin + Zone := Copy(Mask, 1, A - 1); + + If B = 0 Then B := 255; + + Net := Copy(Mask, A + 1, B - 1 - A); + Node := Copy(Mask, B + 1, 255); + End; + + If Zone = '' Then Zone := '*'; + If Net = '' Then Net := '*'; + If Node = '' Then Node := '*'; + + If (Zone <> '*') and (Dest.Zone <> strS2I(Zone)) Then Exit; + If (Net <> '*') and (Dest.Net <> strS2I(Net)) Then Exit; + If (Node <> '*') and (Dest.Node <> strS2I(Node)) Then Exit; + + Result := True; + End; + + Var + Mask : String = ''; + IsNot : Boolean; + OneRes : Boolean; + + Procedure GetNextAddress; + Begin + If Pos('!', Str) > 0 Then Begin + Mask := Copy(Str, 1, Pos('!', Str) - 1); + + Delete (Str, 1, Pos('!', Str) - 1); + End Else + If Pos(' ', Str) > 0 Then Begin + Mask := Copy(Str, 1, Pos(' ', Str) - 1); + + Delete (Str, 1, Pos(' ', Str)); + End Else Begin + Mask := Str; + Str := ''; + End; + End; + + Begin + Result := False; + Str := strStripB(Str, ' '); + + If Str = '' Then Exit; + + Repeat + GetNextAddress; + + If Mask = '' Then Break; + + OneRes := IsOneMatch(Mask); + + While (Str[1] = '!') and (Mask <> '') Do Begin + Delete (Str, 1, 1); + + GetNextAddress; + + OneRes := OneRes AND (NOT IsOneMatch(Mask)); + End; + + Result := Result OR OneRes; + Until Str = ''; + End; + +Var + F : File; +Begin + Result := False; + + Assign (F, bbsConfig.DataPath + 'echonode.dat'); + + If Not ioReset(F, SizeOf(RecEchoMailNode), fmRWDN) Then Exit; + + While Not Eof(F) And Not Result Do Begin + ioRead(F, TempNode); + + Result := IsMatch(TempNode.RouteInfo); + End; + + Close (F); +End; + Function IsValidAKA (Zone, Net, Node: Word) : Boolean; Var Count : Byte; diff --git a/mystic/mutil_echoexport.pas b/mystic/mutil_echoexport.pas index 5ded667..5ddea61 100644 --- a/mystic/mutil_echoexport.pas +++ b/mystic/mutil_echoexport.pas @@ -154,25 +154,18 @@ Var TempStr2 : String; TempStr3 : String; Begin + // if msg originated from this echomail address then do not export + If (EchoNode.Address.Zone = MsgBase^.GetOrigAddr.Zone) and (EchoNode.Address.Net = MsgBase^.GetOrigAddr.Net) and (EchoNode.Address.Node = MsgBase^.GetOrigAddr.Node) Then Exit; - Log (2, '+', ' Export Msg #' + strI2S(MsgBase^.GetMsgNum) + ' to ' + strAddr2Str(EchoNode.Address)); + Log (2, '+', ' Export #' + strI2S(MsgBase^.GetMsgNum) + ' to ' + strAddr2Str(EchoNode.Address)); GetDate (DT.Year, DT.Month, DT.Day, Temp); GetTime (DT.Hour, DT.Min, DT.Sec, Temp); If MBase.NetType = 3 Then Begin - // if is NOT a msg originated from ourself, skip it unless - // both orig and dest are not ourself? hmmm.... - - // need to incorporate routing here... this all needs reworked - // ALWAYS send directly if the message is directed to one of our - // uplinks, else, perform routing to figure it out? - // add configuration for routing somewhere... hmm need to research - // and think all of this through - TempStr3 := GetFTNOutPath(EchoNode); DirCreate (TempStr3); @@ -342,13 +335,13 @@ Begin While Not Eof(ExportFile) Do Begin Read (ExportFile, ExportIndex); - // check base type and export network or echo? or - // do it from exportmessage? - If MBase.NetType = 3 Then Begin - If GetNodeByIndex(ExportIndex, EchoNode) Then - If EchoNode.Active and (EchoNode.Address.Zone = MsgBase^.GetDestAddr.Zone) Then + If GetNodeByRoute(MsgBase^.GetDestAddr, EchoNode) Then + If EchoNode.Active Then Begin ExportMessage; + + Break; + End; End Else If GetNodeByIndex(ExportIndex, EchoNode) Then If EchoNode.Active Then diff --git a/mystic/mutil_echoimport.pas b/mystic/mutil_echoimport.pas index 3001545..f2f3c5e 100644 --- a/mystic/mutil_echoimport.pas +++ b/mystic/mutil_echoimport.pas @@ -65,16 +65,18 @@ End; Procedure uEchoImport; Var - TotalEcho : LongInt; - TotalNet : LongInt; - TotalDupes : LongInt; - EchoNode : RecEchoMailNode; - DupeIndex : LongInt; - DupeMBase : RecMessageBase; - CreateBases : Boolean; - PKT : TPKTReader; - Dupes : TPKTDupe; - Status : LongInt; + TotalEcho : LongInt; + TotalNet : LongInt; + TotalDupes : LongInt; + EchoNode : RecEchoMailNode; + DupeIndex : LongInt; + DupeMBase : RecMessageBase; + CreateBases : Boolean; + PKT : TPKTReader; + Dupes : TPKTDupe; + Status : LongInt; + ForwardList : Array[1..50] of String[35]; + ForwardSize : Byte = 0; Procedure ImportPacketFile (PktFN: String); Var @@ -101,9 +103,6 @@ Var BarOne.Reset; - // set status for PKT name - // do percentage bar init - CurTag := ''; MsgBase := NIL; Status := 20; @@ -118,6 +117,10 @@ Var // areafix etc here If GetMBaseByNetZone (PKT.PKTHeader.DestZone, MBase) Then Begin + For Count := 1 to 50 Do + If strUpper(strWordGet(1, ForwardList[Count], ';')) = strUpper(PKT.MsgTo) Then + PKT.MsgTo := strWordGet(2, ForwardList[Count], ';'); + CurTag := ''; If MsgBase <> NIL Then Begin @@ -357,6 +360,24 @@ Begin DupeIndex := INI.ReadInteger(Header_ECHOIMPORT, 'dupe_msg_index', -1); Count := INI.ReadInteger(Header_ECHOIMPORT, 'dupe_db_size', 32000); + // Read in forward list from INI + + FillChar (ForwardList, SizeOf(ForwardList), #0); + + Ini.SetSequential(True); + + Repeat + FileExt := INI.ReadString(Header_ECHOIMPORT, 'forward', ''); + + If FileExt = '' Then Break; + + Inc (ForwardSize); + + ForwardList[ForwardSize] := FileExt; + Until ForwardSize = 50; + + INI.SetSequential(False); + Dupes := TPKTDupe.Create(Count); PKT := TPKTReader.Create; @@ -397,4 +418,4 @@ Begin ProcessResult (rDONE, True); End; -End. +End. \ No newline at end of file diff --git a/mystic/records.pas b/mystic/records.pas index 5a9dc6f..e938061 100644 --- a/mystic/records.pas +++ b/mystic/records.pas @@ -59,7 +59,7 @@ Const mysMaxMenuCmds = 25; // Max menu commands per item mysMaxMenuInput = 12; mysMaxMenuStack = 8; - mysMaxThemeText = 508; + mysMaxThemeText = 512; fn_SemFileEcho = 'echomail.now'; fn_SemFileNews = 'newsmail.now'; @@ -116,7 +116,8 @@ Type OutFiles : Cardinal; OutSize : Cardinal; binkPass : String[20]; - Res : Array[1..491] of Byte; + RouteInfo : String[128]; + Res : Array[1..362] of Byte; End; RecSauceInfo = Packed Record diff --git a/mystic/whatsnew.txt b/mystic/whatsnew.txt index ea685ba..a60e818 100644 --- a/mystic/whatsnew.txt +++ b/mystic/whatsnew.txt @@ -3129,3 +3129,87 @@ netmail to match an address found in the nodelist. If it is set to false Mystic will still allow a user to search the nodelist, but if it does not find a match they will still have the option to send the netmail. + + + When replying to a message, Mystic now gives the option to reply in the + current message base, BBS email base, or by selecting a new message base. + Four new prompts have been added for this: + + ; Message reply options (standard) + ; &1=base name &2=reply to name &3=msg subject + 509 |16|CL|09|17 ° |15Message Reply |$X79 |16|CR|CR|03 Area: |11|&1|CR |03To: |11|&2|CR|03 Subject: |11|$R65|&3|CR|CR|09Reply area (|11ENTER|09) Current, |09(|11B|09)ase, |09(|11E|09)mail, |09(|11Q|09)uit? |14 + + ; Message reply options (lightbar) + ; &1=base name &2=reply to name &3=msg subject + 510 |16|CL|09|17 ° |15Message Reply |$X79 |16|CR|CR|03 Area: |11|&1|CR |03To: |11|&2|CR|03 Subject: |11|$R65|&3|CR|CR|09Reply area (|11ENTER|09) Current, |09(|11B|09)ase, |09(|11E|09)mail, |09(|11Q|09)uit? |14 + + ; Message reply select base prompt + 511 |CR|09Select message base for reply [|10?|09/|10List|09]: |11 + + ; Message "replying to X base" prompt &1=base name + 512 |CR|03Posting reply message to base |11|&1|03. + + + The message jump command in both lightbar and standard message readers + now use intelligent input for the message number. + + + MUTIL can now optionally remap incoming netmail messages by defining up to + 50 sets of mappings under [EchoImport] address. For example: + + [EchoImport] + forward = sysop;g00r00 + forward = system operator;g00r00 + + + Netmail exporting has been rewritten and now requires routing information + configured for each Echomail node. The first requirement is that any + netmail base must first be linked for export if you want it to be checked + for routing of netmail posted in that base. + + Once linked, it must match the "Routing Info" defined for that node. In + general if you only have one uplink for that zone/network, you can use the + first example below. But if you have many uplinks for a single network it + will of course become more complicated. + + Routing info is defined in the format of addresses separated by spaces and + uses an asterisk (*) as a wildcard. In addition to an address, a "NOT" can + be applied to each address by appending a ! and another address mask to it + which will then be excluded. + + For example if you have are a FidoNet node in zone 1 and you want to route + all netmail posted to zones 1 through 5 to a specific downlink, you'd + configure the following Routing Info for that echomail node: + + Routing Info | 1:* 2:* 3:* 4:* 5:* + + For most cases that will do. For networks that only have one zone you'd + simply route just that zone. IE RandomNet zone 66 would just have 66:* + and you are done. But... + + If for example, you had two FidoNet uplinks one at (1:123/1) and you + wanted to route all Netmail to your first uplink EXCEPT for Netmail + specifically addressed to your second uplink's NET you'd do this for your + primary uplink: + + Routing Info | 1:*!1:123/* 2:* 3:* 4:* 5:* + + This will cause ALL zone 1-5 netmail to be routed to that uplink EXCEPT + for netmail with a destination to 1:123/*. And then you'd configure your + second uplink to route ONLY net 123: + + Routing Info | 1:123/* + + Remember, only exported echomail nodes are eligible for routing, so in the + above example you'd link both FidoNet bases to your export and Mystic. + + As usual with routing it can be confusing when you have very specific + routing needs but if you have only single uplinks then it can be pretty + straight forward. EXISTING echomail users need to go in and add their + routing information. + + + Message bases can now be tagged and deleted in bulk, along with their + message base data files. + + + Message base global editor can now add and/or remove an echomail link to + a selected list of bases. + + + New MPL filebase variable: "fbasefn" returns the file base's filename. + +