diff --git a/mystic/bbs_common.pas b/mystic/bbs_common.pas index 3b437e9..41e003c 100644 --- a/mystic/bbs_common.pas +++ b/mystic/bbs_common.pas @@ -142,7 +142,7 @@ Begin B := Pos('/', S); C := Pos('.', S); - If (A = 0) or (B = 0) Then Exit; + If (A = 0) or (B <= A) Then Exit; If C = 0 Then Begin Point := False; diff --git a/mystic/bbs_filebase.pas b/mystic/bbs_filebase.pas index 57aa37b..4e1601a 100644 --- a/mystic/bbs_filebase.pas +++ b/mystic/bbs_filebase.pas @@ -314,7 +314,10 @@ Var Case Mode of 0 : Protocol^.SetDestinationDirectory(JustPath(FName)); - 1 : Protocol^.AddFileToList(FileList, FName); + 1 : Begin + Protocol^.SetDestinationDirectory(JustPath(FName)); + Protocol^.AddFileToList(FileList, FName); + End; 2 : Protocol^.AddFileToList(FileList, FName); 3 : Begin Assign (T, Session.TempPath + 'file.lst'); diff --git a/mystic/bbs_msgbase.pas b/mystic/bbs_msgbase.pas index a5cf03a..5045b23 100644 --- a/mystic/bbs_msgbase.pas +++ b/mystic/bbs_msgbase.pas @@ -44,6 +44,7 @@ Type Function GetTotalMessages (Var TempBase: RecMessageBase) : LongInt; Procedure PostTextFile (Data: String; AllowCodes: Boolean); Function SaveMessage (mArea: RecMessageBase; mFrom, mTo, mSubj: String; mAddr: RecEchoMailAddr; mLines: Integer) : Boolean; + Function NetmailLookup (FromMenu: Boolean; MsgTo, DefAddr: String) : String; Function ListAreas (Compress: Boolean) : Integer; Procedure ChangeArea (Data: String); Procedure SetMessageScan; @@ -79,6 +80,7 @@ Uses bbs_Core, bbs_User, bbs_NodeInfo, + bbs_NodeList, bbs_cfg_UserEdit; Const @@ -125,6 +127,142 @@ Begin Inherited Destroy; End; +Function TMsgBase.NetmailLookup (FromMenu: Boolean; MsgTo, DefAddr: String) : String; + + Procedure ShowNode (ShowType: Byte; NodeData: RecNodeSearch; Ext: Boolean); + Var + Str : String; + Begin + Case ShowType of + 0 : Str := strAddr2Str(NodeData.Address); + 1, + 2 : If NodeData.Keyword = 'ZONE' Then + Str := 'ZONE' + strPadL(strI2S(NodeData.Address.Zone), 8, ' ') + Else + If NodeData.Keyword = 'REGION' Then + Str := 'REGION' + strPadL(strI2S(NodeData.Address.Net), 6, ' ') + Else + If NodeData.Keyword = 'HOST' Then + Str := 'NET' + strPadL(strI2S(NodeData.Address.Net), 9, ' '); + End; + + Session.io.PromptInfo[1] := Str; + Session.io.PromptInfo[2] := NodeData.BBSName; + Session.io.PromptInfo[3] := NodeData.Location; + Session.io.PromptInfo[4] := NodeData.SysopName; + Session.io.PromptInfo[5] := NodeData.Phone; + Session.io.PromptInfo[6] := NodeData.Internet; + + If Ext Then + Session.io.OutFullLn(Session.GetPrompt(500)) + Else + Session.io.OutFullLn(Session.GetPrompt(499)); + End; + +Var + NodeList : TNodeListSearch; + FirstNode : RecNodeSearch; + NodeData : RecNodeSearch; + Listed : LongInt; + ListType : Byte; + HasList : Boolean; +Begin + HasList := FileExist(Config.DataPath + 'nodelist.txt'); + NodeList := TNodeListSearch.Create; + + If HasList Then + Session.io.OutFile ('nodesearch', False, 0); + + Repeat + If FromMenu Then + Session.io.OutFull (Session.GetPrompt(497)) + Else + If HasList Then + Session.io.OutFull (Session.GetPrompt(496)) + Else + Session.io.OutFull (Session.GetPrompt(342)); + + Result := strUpper(Session.io.GetInput(25, 25, 11, DefAddr)); + + If Result = '' Then Break; + + If (Result = '?') and HasList Then Begin + Session.io.OutFile('nodesearch', False, 0); + + Continue; + End; + + If Not HasList Then Break; + + ListType := 0; + + If Pos('LIST ZONE', Result) > 0 Then Begin + ListType := 1; + Result := '?:?/?'; + End; + + If Pos('LIST NET', Result) > 0 Then Begin + ListType := 2; + Result := strWordGet(3, Result, ' ') + ':?/?'; + End; + + Listed := 0; + + Session.io.PausePtr := 1; + Session.io.AllowPause := True; + + NodeList.ResetSearch(Config.DataPath + 'nodelist.txt', Result); + + While NodeList.FindNext(NodeData) Do Begin + Case ListType of + 0 : If NodeData.Keyword <> '' Then Continue; + 1 : If NodeData.Keyword <> 'ZONE' Then Continue; + 2 : If (NodeData.Keyword <> 'ZONE') and (NodeData.Keyword <> 'REGION') and (NodeData.Keyword <> 'HOST') Then Continue; + End; + + Inc (Listed); + + If Listed = 1 Then + FirstNode := NodeData + Else Begin + If Listed = 2 Then Begin + Session.io.OutFullLn (Session.GetPrompt(498)); + + ShowNode (ListType, FirstNode, False); + End; + + ShowNode (ListType, NodeData, False); + End; + + 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; + + If (Listed = 1) and (ListType = 0) Then Begin + ShowNode(ListType, FirstNode, True); + + If FromMenu Then Continue; + + Session.io.PromptInfo[7] := MsgTo; + + If Session.io.GetYN(Session.GetPrompt(502), True) Then Begin + Result := strAddr2Str(NodeData.Address); + + Break; + End; + End Else Begin + Session.io.PromptInfo[1] := strComma(Listed); + + Session.io.OutFullLn(Session.GetPrompt(501)); + End; + Until False; + + NodeList.Free; +End; + Function TMsgBase.IsQuotedText (Str: String) : Boolean; Var Temp : Byte; @@ -926,11 +1064,9 @@ Begin Until False; If MBase.NetType = 3 Then Begin - Session.io.OutFull (Session.GetPrompt(342)); - MsgBase^.GetOrig(Addr); - TempStr := Session.io.GetInput(20, 20, 12, strAddr2Str(Addr)); + TempStr := NetmailLookup(False, ToWho, strAddr2Str(Addr)); If Not strStr2Addr (TempStr, Addr) Then Exit; End; @@ -2582,13 +2718,12 @@ Begin MsgTo := Session.io.GetInput (30, 30, 18, ''); End; - If MsgAddr = '' Then Begin - Session.io.OutFull (Session.GetPrompt(342)); + If MsgTo <> '' Then + If MsgAddr = '' Then Begin + MsgAddr := NetmailLookup(False, MsgTo, ''); - MsgAddr := Session.io.GetInput (20, 20, 12, ''); - - If Not strStr2Addr(MsgAddr, DestAddr) Then MsgTo := ''; - End; + If Not strStr2Addr(MsgAddr, DestAddr) Then MsgTo := ''; + End; End Else If MBase.Flags and MBPrivate <> 0 Then Begin If MsgTo = '' Then Begin @@ -3896,19 +4031,23 @@ End; Procedure TMsgBase.UploadREP; Var - DataFile : File; - TempBase : RecMessageBase; - OldBase : RecMessageBase; - QwkHeader : QwkDATHdr; - QwkBlock : String[128]; - Line : String; - A : SmallInt; - B : SmallInt; - Chunks : SmallInt; - LineCount : SmallInt; - IsControl : Boolean; - GotControl : Boolean; - ExtFile : Text; + DataFile : File; + TempBase : RecMessageBase; + OldBase : RecMessageBase; + QwkHeader : QwkDATHdr; + QwkBlock : String[128]; + Line : String; + A : SmallInt; + B : SmallInt; + Chunks : SmallInt; + LineCount : SmallInt; + IsControl : Boolean; + GotControl : Boolean; + ExtFile : Text; + StatOK : LongInt = 0; + StatFailed : LongInt = 0; + StatBaseAdd : LongInt = 0; + StatBaseDel : LongInt = 0; Procedure QwkControl (Idx: LongInt; Mode: Byte); Begin @@ -3919,6 +4058,9 @@ Var MScan.QwkScan := Mode; + If Mode = 0 Then Inc (StatBaseDel); + If Mode = 1 Then Inc (StatBaseAdd); + SetMessageScan; End; @@ -3945,9 +4087,8 @@ Begin End; Assign (DataFile, FileFind(Session.TempPath + Config.qwkBBSID + '.msg')); - {$I-} Reset (DataFile, 1); {$I+} - If IoResult <> 0 Then Begin + If Not ioReset(DataFile, 1, fmRWDN) Then Begin Session.io.OutFull (Session.GetPrompt(238)); DirClean (Session.TempPath, ''); Exit; @@ -3963,11 +4104,12 @@ Begin Exit; End; - Session.io.OutFullLn (Session.GetPrompt(240)); + Session.io.OutFull (Session.GetPrompt(240)); While Not Eof(DataFile) Do Begin BlockRead (DataFile, QwkHeader, SizeOf(QwkHeader)); - Move (QwkHeader.MsgNum, QwkBlock[1], 7); + Move (QwkHeader.MsgNum, QwkBlock[1], 7); + QwkBlock[0] := #7; If GetBaseByIndex(strS2I(QwkBlock), TempBase) Then Begin @@ -4041,18 +4183,21 @@ Begin MsgBase^.DoStringLn (' * Origin: ' + ResolveOrigin(TempBase) + ' (' + strAddr2Str(Config.NetAddress[TempBase.NetAddr]) + ')'); End; - If Not IsControl Then MsgBase^.WriteMsg; - - MsgBase^.CloseMsgBase; - If Not IsControl Then Begin + MsgBase^.WriteMsg; + + Inc (StatOK); Inc (Session.User.ThisUser.Posts); Inc (Session.HistoryPosts); End; + MsgBase^.CloseMsgBase; + Dispose (MsgBase, Done); - End; - End; + End Else + Inc (StatFailed); + End Else + Inc (StatFailed); End; Close (DataFile); @@ -4076,6 +4221,13 @@ Begin End; DirClean (Session.TempPath, ''); + + Session.io.PromptInfo[1] := strI2S(StatOK); + Session.io.PromptInfo[2] := strI2S(StatFailed); + Session.io.PromptInfo[3] := strI2S(StatBaseAdd); + Session.io.PromptInfo[4] := strI2S(StatBaseDel); + + Session.io.OutFullLn(Session.GetPrompt(503)); End; End. diff --git a/mystic/default.txt b/mystic/default.txt index 4ac3475..2a0dedb 100644 --- a/mystic/default.txt +++ b/mystic/default.txt @@ -452,8 +452,8 @@ 238 |CR|12Your .REP packet was not found.|CR|CR|PA ; Displayed if the wrong QWK packet is uploaded 239 |CR|12Your .REP packet is not for this BBS.|CR|PA -; Processing reply packet -240 |CR|01[|10þ|01] |09Processing reply packet|01... +; Processing QWK reply packet +240 |CR|01[|10þ|01] |09Processing QWK reply packet|01: |XX ; Voting booth header 241 |CL|08|$D79Ä|CR|14Voting Booth |12(* = New Question)|CR|08|$D79Ä ; Voting booth question list format @@ -539,7 +539,7 @@ ; Save this question? 281 |CR|12Save this voting question? |11 ; Move message to where? -282 |CR|09Move to which base (?/List): |XX +282 |CR|09Move to which base (|10?|09/|10List|09): |XX ; Add BBS list: enter phone number 283 |03Enter BBS phone number: |XX ; Add BBS list: enter BBS name @@ -646,7 +646,8 @@ 340 |$D34 |07+ Uploader: |&1 ; Line editor quote mode: &1 = line number &2 = line text 341 |10|&1|02: |11|$R74|&2 -342 |CR|09Enter destination address: |XX +; Netmail destination address (if no nodelist data) +342 |CR|09Enter destination netmail address: |XX ; Upload file name prompt 343 |CR|09File Name|CR: ; Download file name prompt @@ -971,4 +972,23 @@ ; Normal msg reader: Remove from newscan? (after I command) 494 |CR|12Remove |15|MB |12from message newscan? |XX ; Lightbar msg reader: Remove from newscan (after I command) -495 |CR|12Remove |15|MB |12from message newscan? |XX \ No newline at end of file +495 |CR|12Remove |15|MB |12from message newscan? |XX +; Netmail send address prompt with active nodelist searching +496 |CR|09Enter netmail address or search criteria (|10?|09/|10Help|09): |11 +; Nodelist browser prompt +497 |CR|09Enter nodelist search criteria (|10?|09/|10Help|09): |11 +; Nodelist search results header +498 |CR|15Node System Name Location SysOp |CR|09============ ========================== ================== ==================== +; Node list search results +; &1=addr &2=bbsname &3=location &4=sysop &5=phone &6=internet +499 |10|$R12|&1 |15|$R26|&2 |11|$R18|&3 |09|$R20|&4 +; Node list single result +500 |CR|03 Address: |14|&1|CR|03System Name: |11|&2|CR|03 Location: |11|&3|CR|03 Operator: |11|&4|CR|03 Phone: |11|&5|CR|03 Internet: |11|&6 +; Node list search "found X matches" &1=# of matches +501 |CR|03Found |11|&1 |03matches. +; Netmail send confirmation +; &1=addr &2=bbsname &3=location &4=sysop &5=phone &6=internet &7=to +502 |CR|12Send netmail to |15|&7|07 at |15|&1|12? |11 +; QWK .REP complete/results prompt +; &1=msgs imported &2=msgs failed &3=bases added to scan &4=bases removed +503 |10SUCCESS|01.|CR|CR|11- |03Posted |11|&1 |03new messages (|11|&2 |03failed)|CR|11- |03Added |11|&3 |03bases to new scan (|11|&4 |03removed).|CR|CR|PA diff --git a/mystic/records.pas b/mystic/records.pas index 7d3778d..2a2eb4e 100644 --- a/mystic/records.pas +++ b/mystic/records.pas @@ -23,7 +23,7 @@ Const mysSoftwareID = 'Mystic'; // no idea mysCopyYear = '1997-2013'; // its been a long time! - mysVersion = '1.10 A26'; // current version + mysVersion = '1.10 A27'; // current version mysDataChanged = '1.10 A11'; // version of last records change {$IFDEF WIN32} @@ -59,7 +59,7 @@ Const mysMaxMenuCmds = 25; // Max menu commands per item mysMaxMenuInput = 12; mysMaxMenuStack = 8; - mysMaxThemeText = 495; // Total prompts in theme file + mysMaxThemeText = 503; // Total prompts in theme file fn_SemFileEcho = 'echomail.now'; fn_SemFileNews = 'newsmail.now'; diff --git a/mystic/todo.pas b/mystic/todo.pas index 9650a35..2ec4826 100644 --- a/mystic/todo.pas +++ b/mystic/todo.pas @@ -27,6 +27,8 @@ BUGS AND POSSIBLE ISSUES FUTURE / IDEAS / WORK IN PROGRESS / NOTES ========================================= +- Blind upload for single file upload (also message upload) +- Email validation - Recode FCHECK into MUTIL, but also add the option to phsyically delete the file record instead of marking it offline. - Add ability to ignore files from a files.bbs import diff --git a/mystic/whatsnew.txt b/mystic/whatsnew.txt index 0e77e6e..4ca188b 100644 --- a/mystic/whatsnew.txt +++ b/mystic/whatsnew.txt @@ -2583,3 +2583,62 @@ mbbsutil -fcheck kill + + ! WordGet will now trim spaces off the beginning of the string, but only + when space is used as a word separator. When something other than a + space is used, it will not trim anything. This fixes a problem that + could cause the result to be incorrect when using non-space separators. + + + Mystic now has a node address lookup option when sending NetMail. This + search allows wildcard search by address, or text seaching of the BBS + name, SysOp name, location, phone and Internet address. In addition, it + also has functions to list zones and specific nets within a zone, rather + than just nodes themselves. + + To enable this feature, simply copy a raw FTN-style nodelist into the + data directory and name it "nodelist.txt". Mystic is using a raw + uncompiled nodelist, because of lack of compilers and advancement in CPU + speed makes it much more feasible these days. + + A new display file called "nodesearch.xxx" will be displayed if it exists + before the netmail address prompt, and when the user selects ?/help at the + prompt. A nodesearch.asc file has been included in the new default + install. + + The following new prompts must be added: + + ; Netmail send address prompt with active nodelist searching + 496 |CR|09Enter netmail address or search criteria (|10?|09/|10Help|09): |11 + + ; Nodelist browser prompt + 497 |CR|09Enter nodelist search criteria (|10?|09/|10Help|09): |11 + + ; Nodelist search results header + 498 |CR|15Node System Name Location SysOp |CR|09============ ========================== ================== ==================== + + ; Node list search results + ; &1=addr &2=bbsname &3=location &4=sysop &5=phone &6=internet + 499 |10|$R12|&1 |15|$R26|&2 |11|$R18|&3 |09|$R20|&4 + + ; Node list single result + 500 |CR|03 Address: |14|&1|CR|03System Name: |11|&2|CR|03 Location: |11|&3|CR|03 Operator: |11|&4|CR|03 Phone: |11|&5|CR|03 Internet: |11|&6 + + ; Node list search "found X matches" &1=# of matches + 501 |CR|03Found |11|&1 |03matches. + + ; Netmail send confirmation + ; &1=addr &2=bbsname &3=location &4=sysop &5=phone &6=internet &7=to + 502 |CR|12Send netmail to |15|&7|07 at |15|&1|12? |11 + + ! Fixed a bug with internal Zmodem uploads which would cause the upload to + not be detected by Mystic. + + + After uploading a QWK .REP reply packet, Mystic will now display some + basic statistics of messages posted, or of failed imports. A new prompt + must be added to go with this: + + ; QWK .REP complete/results prompt + ; &1=msgs imported &2=msgs failed &3=bases added to scan &4=bases removed + 503 |10SUCCESS|01.|CR|CR|11- |03Posted |11|&1 |03new messages (|11|&2 |03failed)|CR|11- |03Added |11|&3 |03bases to new scan (|11|&4 |03removed).|CR|CR|PA + +