 Rem File: Dndsub9 for Dndbbs Version v5.0a Release r2.0
 Rem $Include: 'dndbbs.inc'
Sub Read.Config(Var)
 On Local Error Goto Error.Trap1
 ' store state of log files.
 Var1=Disk.Log
 Var2=Print.Log
 ' reset state of log files.
 Disk.Log=False
 Print.Log=False
 ' call config settings.
 Call Init.Drivers
 Call Get.Command
 Call Open.Arrays
 Call Increase.Files
 Call Get.Config
 Call Make.FileNames
 Call Open.Files
 Call Read.MonClasses
 Call Read.Door
 Call Init.Port
 Call Read.Guest
 Call Valid.Port
 Call Read.Options
 ' restore state of log files.
 Disk.Log=Var1
 Print.Log=Var2
 ' init config settings.
 If Var Then
    ' reset state of log files.
    Disk.Log=Config2(115)
    Print.Log=Config2(116)
    ' init node settings.
    Call Init.Node
    Call Valid.Node
    Call Zero.Node(-1)
    ' init default terminal settings.
    User.Echo=Config2(86)
    User.Linefeeds=Config2(87)
    User.Wordwrap=Config2(90)
    ' check old linelength settings.
    VarX=Config2(88)
    If VarX=40 Or VarX=80 Then
       Eat$ = Nul
    Else
       VarX = 80
    Endif
    User.Linelength = VarX
    ' check old pagelength settings.
    VarY=Config2(89)
    If VarY=25 Or VarY=43 Or VarY=50 Then
       Eat$ = Nul
    Else
       VarY = 25
    Endif
    User.Pagelength = VarY
 Endif
 ' open log files.
 Call Open.Session.Files
Error.Resume1:
 Exit Sub
Error.Trap1:
 Resume Error.Resume1
End Sub

' Assign PSP file handles.
Sub Increase.Files
 On Local Error Goto Error.Trap2
 Close
 Call StdinInt(62,0)
 PSP.Segment=OutregsX.BX
 Def Seg=PSP.Segment
 Command.Line=&H80
 Command.Tail=Command.Line+60
 For Var=1 To 54 ' 50 file handles
    Poke Command.Tail+Var-1,&HFF
 Next
 For Var=1 To 4 ' DOS handles
    File.Handle=Peek(&H18+Var-1)
    Poke Command.Tail+Var-1,File.Handle
 Next
 Poke &H32,54
 Poke &H34,Command.Tail
 Def Seg
 Close
Error.Resume2:
 Exit Sub
Error.Trap2:
 Resume Error.Resume2
End Sub

' Release PSP handles.
Sub Decrease.Files
 On Local Error Goto Error.trap3
 Close
 Call StdinInt(62,0)
 PSP.Segment=OutregsX.BX
 Def Seg=PSP.Segment
 Poke &H32,20
 Poke &H34,&H18
 Def Seg
 Close
Error.Resume3:
 Exit Sub
Error.Trap3:
 Resume Error.Resume3
End Sub

Sub Open.Arrays
 On Local Error Goto Array.Error
 Redim Alignment.Name1(1 To MaxAlignment) As String*7,_
 Alignment.Name2(1 To MaxAlignment) As String*7,_
 Class.Name(1 To MaxClassNames) As String*15,_
 Direction(1 To MaxDirections) As String*9,_
 High.Class.Name(1 To MaxClassNames) As String*15,_
 InventoryNames(1 To MaxItems) As String*8,_
 Menu1(1 To MaxMenus) As String*25,_
 Menu2(1 To MaxMenus,1 To MaxMenuChoices) As Integer,_
 Modem.Allow(1 To MaxModemBauds) As Integer,_
 Modem.Connect(1 To MaxModemBauds) As Single,_
 Modem.String(1 To MaxModemBauds) As String*20,_
 Node.Work.Array1(0 To MaxNodes) As String*80,_
 Node.Work.Array2(0 To MaxNodes) As Integer,_
 Numeral(1 To MaxNumerals) As String*5,_
 Race(1 To MaxRaces) As String*8,_
 Room.Array(1 To MaxRoomArrays) As String*40,_
 Stat(1 To MaxStats) As String*12,_
 Training.Stats(1 To MaxClassNames,1 To MaxTrainStats) As Integer,_
 Weapon.Type.Name(1 To MaxWeapons) As String*9
Array.Exit:
 Exit Sub
Array.Error:
 Var2=Err
 If Var2=0 Then Var2=53
 Call Error.Message(Var2,Strng2)
 Out2="opening arrays."
 Out3="Free RAM and restart."
 Call Terminal.Error
 Resume Array.Exit
End Sub

Sub Get.Config
 On Local Error Goto Config.Error
 DND.Path=Environ$("DNDBBS")
 If DND.Path<>Nul Then
    If Right$(DND.Path,1)<>"\" Then
       DND.Path=DND.Path+"\"
    Endif
 Endif
 ' open the config file for input.
 FileName=DND.Path+"DND"+NodeX+".CFG"
 Close #TempFile1
 Open FileName For Input Shared As #TempFile1
 ' read the temp directory.
 Line Input #TempFile1,Var$
 If Drive.Override Then
    Var$=Chr$(Drive.Override)+":\"
 Endif
 ' open the workfile for config array storage.
 Close #MessWorkFile9
 UserConfigLen=Len(UserConfigRecord)
 FileName2$=Var$+"TMPWRK"+NodeX+".DAT" ' workfile d:\tmpwrk??.dat
 Open FileName2$ For Random Shared As #MessWorkFile9 Len=UserConfigLen
 For Temp1=1 To MaxConfigArray1
    Input #TempFile1,Temp!
    UserConfigRecord.UserConfig1=Temp!
    VarX=Temp1
    Call Write.Message.Record(MessWorkFile9,VarX)
 Next
 For Temp1=1 To MaxConfigArray2
    Input #TempFile1,TempZ
    UserConfigRecord.UserConfig2=TempZ
    VarX=Temp1+MaxConfigArray1
    Call Write.Message.Record(MessWorkFile9,VarX)
 Next
 For Temp1=1 To MaxConfigArray3
    Line Input #TempFile1,OutZ
    UserConfigRecord.UserConfig3=OutZ
    VarX=Temp1+MaxConfigArray1+MaxConfigArray2
    Call Write.Message.Record(MessWorkFile9,VarX)
 Next
 ' read the following arrays.
 For Temp1=1 To 10
    For Temp2=1 To 4
       Input #TempFile1,Var%
       Training.Stats(Temp1,Temp2)=Var%
    Next
 Next
 For Temp1=1 To 20
    Line Input #TempFile1,Var$
    Room.Array(Temp1)=Var$
 Next
 For Temp1=1 To 10
    Line Input #TempFile1,Var$
    High.Class.Name(Temp1)=Var$
 Next
 For Temp1=1 To 8
    Line Input #TempFile1,Var$
    Race(Temp1)=Var$
 Next
 For Temp1=1 To 10
    Line Input #TempFile1,Var$
    Class.Name(Temp1)=Var$
 Next
 For Temp1=1 To 7
    Line Input #TempFile1,Var$
    Stat(Temp1)=Var$
 Next
 For Temp1=1 To 12
    Line Input #TempFile1,Var$
    Direction(Temp1)=Var$
 Next
 For Temp1=1 To 10
    Line Input #TempFile1,Var$
    Numeral(Temp1)=Var$
 Next
 For Temp1=1 To 4
    Line Input #TempFile1,Var$
    Weapon.Type.Name(Temp1)=Var$
 Next
 For Temp1=1 To 3
    Line Input #TempFile1,Var$
    Alignment.Name1(Temp1)=Var$
 Next
 For Temp1=1 To 3
    Line Input #TempFile1,Var$
    Alignment.Name2(Temp1)=Var$
 Next
 Call Get.Environment
 ' open the workfile for command list storage.
 Close #MessWorkFile8
 UserCommandLen=Len(UserCommandRecord)
 ' d:\altwrk??.dat
 If Drive.Override Then
    FileName=Chr$(Drive.Override)+":\"+Config3(69)+NodeX+Config3(15)
 Else
    FileName=Config3(53)+Config3(69)+NodeX+Config3(15)
 Endif
 Open FileName For Random Shared As #MessWorkFile8 Len=UserCommandLen
 For Temp1=1 To MaxUserCommands
    Line Input #TempFile1,UserCommandRecord.CommandAbbr
    For Temp2=1 To 3
       Line Input #TempFile1,Var$
       UserCommandRecord.CommandSet(Temp2)=Var$
    Next
    Input #TempFile1,UserCommandRecord.CommandParam
    For Temp2=1 To 8
       Input #TempFile1,Var%
       UserCommandRecord.CommandClass(Temp2)=Var%
    Next
    For Temp2=1 To 4
       Input #TempFile1,Var%
       UserCommandRecord.CommandTime(Temp2)=Var%
    Next
    Input #TempFile1,UserCommandRecord.CommandLimit
    Input #TempFile1,UserCommandRecord.AttackCommand
    VarX=Temp1
    Call Write.Message.Record(MessWorkFile8,VarX)
 Next
 For Temp1=1 To MaxDMcommands
    Line Input #TempFile1,Var$
    UserCommandRecord.CommandSet(1)=Var$
    Input #TempFile1,UserCommandRecord.CommandParam
    For Temp2=1 To 3
       Input #TempFile1,Var%
       UserCommandRecord.CommandClass(Temp2)=Var%
    Next
    Temp2=Temp1+MaxUserCommands
    Call Write.Message.Record(MessWorkFile8,Temp2)
 Next
 For Temp1=1 To MaxSysopCommands
    Line Input #TempFile1,Var$
    UserCommandRecord.CommandSet(1)=Var$
    Input #TempFile1,Var%
    UserCommandRecord.CommandClass(1)=Var%
    Temp2=Temp1+MaxUserCommands+MaxDMcommands
    Call Write.Message.Record(MessWorkFile8,Temp2)
 Next
 For Temp1=1 To MaxNodeCommands
    Line Input #TempFile1,Var$
    UserCommandRecord.CommandSet(1)=Var$
    For Temp2=1 To 8
       Input #TempFile1,UserCommandRecord.CommandClass(Temp2)
    Next
    Temp2=Temp1+MaxUserCommands+MaxDMcommands+MaxSysopCommands
    Call Write.Message.Record(MessWorkFile8,Temp2)
 Next
 For Temp1=1 To MaxLetters
    Input #TempFile1,Var%
    UserCommandRecord.CommandParam=Var%
    Temp2=Temp1+MaxUserCommands+MaxDMcommands+MaxSysopCommands+MaxNodeCommands
    Call Write.Message.Record(MessWorkFile8,Temp2)
 Next
 For Temp1=1 To MaxStrips
    Line Input #TempFile1,Var$
    UserCommandRecord.CommandSet(1)=Var$
    Temp2=Temp1+MaxUserCommands+MaxDMcommands+MaxSysopCommands+MaxNodeCommands+MaxLetters
    Call Write.Message.Record(MessWorkFile8,Temp2)
 Next
 ' read the remaining arrays.
 For Temp1=1 To 10
    Line Input #TempFile1,Var$
    Menu1(Temp1)=Var$
    Input #TempFile1,Var%
    Menu2(Temp1,1)=Var%
    Input #TempFile1,Var%
    Menu2(Temp1,2)=Var%
 Next
 For Temp1=1 To 10
    Line Input #TempFile1,Var$
    InventoryNames(Temp1)=Var$
 Next
 For Temp1=1 To MaxModemBauds
    Input #TempFile1,Var!
    Modem.Connect(Temp1)=Var!
    Line Input #TempFile1,Var$
    Modem.String(Temp1)=Var$
    Input #TempFile1,Var%
    Modem.Allow(Temp1)=Var%
 Next
 ANSIPrefixChar=Config3(85)
Config.Exit:
 Exit Sub
Config.Error:
 Var2=Err
 If Var2=0 Then Var2=53
 Call Error.Message(Var2,Strng2)
 Out2="reading config processing "+Lcase$(FileName)
 Out3="Increase files= in config.sys or config.nt file, or run Dndcnfg."
 Call Terminal.Error
 Resume Config.Exit
End Sub

Sub Get.Environment
 On Local Error Goto Error.Trap4
 Out2=Environ$("DNDDAT")
 If Out2<>Nul Then
    If Right$(Out2,1)<>"\" Then
       Out2=Out2+"\"
    Endif
    UserConfigRecord.UserConfig3=Out2
    Temp2=MaxConfigArray1+MaxConfigArray2+11
    Call Write.Message.Record(MessWorkFile9,Temp2)
 Endif
 Out2=Environ$("DNDDOC")
 If Out2<>Nul Then
    If Right$(Out2,1)<>"\" Then
       Out2=Out2+"\"
    Endif
    UserConfigRecord.UserConfig3=Out2
    Temp2=MaxConfigArray1+MaxConfigArray2+52
    Call Write.Message.Record(MessWorkFile9,Temp2)
 Endif
 Out2=Environ$("DNDTEMP")
 If Out2<>Nul Then
    If Right$(Out2,1)<>"\" Then
       Out2=Out2+"\"
    Endif
    UserConfigRecord.UserConfig3=Out2
    Temp2=MaxConfigArray1+MaxConfigArray2+53
    Call Write.Message.Record(MessWorkFile9,Temp2)
 Endif
 Out2=Environ$("DNDMESS")
 If Out2<>Nul Then
    If Right$(Out2,1)<>"\" Then
       Out2=Out2+"\"
    Endif
    UserConfigRecord.UserConfig3=Out2
    Temp2=MaxConfigArray1+MaxConfigArray2+54
    Call Write.Message.Record(MessWorkFile9,Temp2)
 Endif
 Out2=Environ$("DNDDOOR")
 If Out2<>Nul Then
    If Right$(Out2,1)<>"\" Then
       Out2=Out2+"\"
    Endif
    UserConfigRecord.UserConfig3=Out2
    Temp2=MaxConfigArray1+MaxConfigArray2+84
    Call Write.Message.Record(MessWorkFile9,Temp2)
 Endif
Error.Resume4:
 Exit Sub
Error.Trap4:
 Resume Error.Resume4
End Sub

Sub Make.FileNames
 On Local Error Goto Error.Trap5
 Data.Path1=Config3(11) ' \dnddat
 Data.Path2=Config3(52) ' \dnddoc
 ' \dndtemp (ram drive)
 If Drive.Override Then
    Data.Path3=Chr$(Drive.Override)+":\"
 Else
    Data.Path3=Config3(53)
 Endif
 Data.Path4=Config3(54) ' \dndmess
 File.Extension1=Config3(15) ' .dat
 File.Extension2=Config3(62) ' .doc
 Log.Extension=Config3(100) ' .log
 Public.Filename=Config3(58)
 Private.Filename=Config3(60)
 DOS.Exit=DND.Path+Config3(70)+NodeX+".BAT"
 Catalog.FileName=Data.Path2+Config3(65)+File.Extension2
 Hint.FileName=Data.Path2+Config3(64)+File.Extension2
 Summary.FileName=Data.Path2+Config3(50)+File.Extension2
 Day.File.FileName=Data.Path1+Config3(72)
 Day.Log.FileName=Data.Path1+Config3(67)
 DMhelp.FileName=Data.Path1+Config3(63)+File.Extension1
 Help.FileName1=Data.Path1+Config3(55)+File.Extension1
 Help.FileName2=Data.Path1+Config3(56)+File.Extension1
 Help.FileName3=Data.Path1+Config3(61)+File.Extension1
 Help.FileName4=Data.Path1+Config3(76)+File.Extension1
 MessWork.FileName=Data.Path3+Config3(68)
 Message.Base.FileName=Data.Path4+Config3(59)+File.Extension1
 LastUser.FileName=Data.Path1+Config3(49)+File.Extension1
 Log.FileName=Data.Path1+Config3(73)+File.Extension1
 Logoff.FileName=Data.Path1+Config3(28)+File.Extension1
 Logon.Help.FileName=Data.Path1+Config3(61)+File.Extension1
 Logoff.Help.FileName=Data.Path1+Config3(38)+File.Extension1
 Notice.FileName=Data.Path1+Config3(4)+File.Extension1
 Prelog.FileName=Data.Path1+Config3(1)+File.Extension1
 Team.FileName=Data.Path1+Config3(57)+File.Extension1
 Welcome.FileName=Data.Path1+Config3(3)+File.Extension1
 Action.FileName=Data.Path1+Config3(71)+File.Extension1
 Container.FileName=Data.Path1+Config3(80)+File.Extension1
 MonClass.FileName=Data.Path1+Config3(12)+File.Extension1
 MonTalk.FileName=Data.Path1+Config3(13)+File.Extension1
 Monster.FileName=Data.Path1+Config3(18)+File.Extension1
 NonPlayer.FileName=Data.Path1+Config3(22)+File.Extension1
 Object.FileName=Data.Path1+Config3(17)+File.Extension1
 Room.FileName=Data.Path1+Config3(16)+File.Extension1
 Room.Desc.Filename=Data.Path1+Config3(93)+File.Extension1
 Spell.FileName=Data.Path1+Config3(20)+File.Extension1
 Treasure.FileName=Data.Path1+Config3(19)+File.Extension1
 MonInv.FileName=Data.Path1+Config3(90)+File.Extension1
 RoomInv.FileName=Data.Path1+Config3(89)+File.Extension1
 TeamInv.FileName=Data.Path1+Config3(88)+File.Extension1
 User.FileName=Data.Path1+Config3(21)+File.Extension1
 CtnInv.FileName=Data.Path1+Config3(87)+File.Extension1
 UserInv.FileName=Data.Path1+Config3(86)+File.Extension1
 Usage.FileName=Data.Path1+Config3(51)+File.Extension1
 ActionRecLen=Len(ActionRecord)
 BufferRecLen=Len(BufferRecord)
 ContainerRecLen=Len(ContainerRecord)
 DayFileRecLen=Len(BufferRecord)
 LogRecLen=Len(LogRecord)
 HelpRecLen1=Len(HelpRecord1)
 HelpRecLen2=Len(HelpRecord2)
 HelpRecLen3=Len(HelpRecord3)
 HelpRecLen4=Len(HelpRecord3)
 MessWorkRecLen1=Len(MessWorkRecord1)
 MessWorkRecLen2=Len(MessWorkRecord2)
 MessWorkRecLen3=Len(MessWorkRecord3)
 MessWorkRecLen4=Len(MessWorkRecord4)
 MessWorkRecLen5=Len(MessWorkRecord5)
 MessWorkRecLen6=Len(MessWorkRecord6)
 MessWorkRecLen7=Len(MessWorkRecord7)
 MessageRecLen=Len(BufferRecord)
 NewMessRecLen=Len(NewMessages)
 TableRecLen=Len(TableRecord)
 UserRecLen=Len(UserRecord)
 NonPlayerRecLen=Len(MonsterRecord)
 RoomDescLen=Len(BufferRecord)
 RoomRecLen=Len(RoomRecord)
 ObjectRecLen=Len(ObjectRecord)
 MonsterRecLen=Len(MonsterRecord)
 MonTalkRecLen=Len(BufferRecord)
 MessBaseRecLen=Len(MessageBaseRecord)
 MonClassRecLen=Len(MonClassRecord)
 SpellRecLen=Len(SpellRecord)
 TeamRecLen=Len(TeamRecord)
 TreasureRecLen=Len(TreasureRecord)

 Allow.High.Class=Config2(48)
 Allow.Remote.Edit=Config2(81)
 Base.Address=Config2(114)

 Bank.FileName=Config3(96)
 Bank.Log.FileName=Config3(99)
 BankRecLen=Len(BankRecord)
 Disable.Nodes=Config2(111)
 Disable.DM=Config2(112)
 Disable.Sysop=Config2(113)
 Inline.FileName1=Ucase$(Config3(92)) ' EDIT.COM
 Inline.FileName2=Ucase$(Config3(91)) ' QBASIC.EXE
 InterestRate1=Config1(10)/100
 InterestRate2=Config1(30)/100
 InterestRate3=Csng(Val(Config3(98)))

 ' reset usage file
 Close #TempFile1
 Open Usage.FileName For Random Shared As #TempFile1 Len=26
 If Lof(TempFile1)=0 Then
    Field #TempFile1,26 As S$
    Lset S$="DND Usage File v"+Version$+Chr$(13)+Chr$(10)+Chr$(26)
    Put #TempFile1,1
 Endif
 Field #TempFile1,10 As D$, 8 As T$, 8 As X$
 If Lof(TempFile1)/26<2 Then
    Lset D$=DateS$
    Lset T$=Format$(Now,"hh:mm:ss")
    Lset X$=Mkd$(0#)
    Put #TempFile1,2
 Endif
 If Lof(TempFile1)/26<3 Then
    Lset D$="01-01-1980"
    Lset T$=Format$(Now,"hh:mm:ss")
    Lset X$=Mkd$(0#)
    Put #TempFile1,3
 Endif
Error.Resume5:
 Exit Sub
Error.Trap5:
 Resume Error.Resume5
End Sub

Sub Close.Files
 On Local Error Goto Error.Trap6
 Close #ActionFile, #ContainerFile, #MessBaseFile, #MonsterFile, #MonClassFile,_
 #MonTalkFile, #NonPlayerFile, #ObjectFile, #RoomFile, #RoomDescFile, #SpellFile, #TeamFile,_
 #TreasureFile, #UserFile, #UserFile2, #UserInvFile, #CtnInvFile, #TeamInvFile, #RoomInvFile, #MonInvFile
Error.Resume6:
 Exit Sub
Error.Trap6:
 Resume Error.Resume6
End Sub

Sub Close.Nodes
 On Local Error Goto Error.Trap7
 Close #MessWorkFile1, #MessWorkFile2, #MessWorkFile3, #MessWorkFile4,_
 #MessWorkFile5, #MessWorkFile6, #MessWorkFile7, #MessWorkFile8
Error.Resume7:
 Exit Sub
Error.Trap7:
 Resume Error.Resume7
End Sub

Sub Close.Temp
 On Local Error Goto Error.Trap8
 Close #MessageFile, #NewFile, #TableFile, #LogFile, #DayFile1, #TempFile1,_
 #TempFile2, #HelpFile1, #HelpFile2, #HelpFile3, #SicFile,_
 #DiskFile, #PrintFile
Error.Resume8:
 Exit Sub
Error.Trap8:
 Resume Error.Resume8
End Sub

Sub Open.Files
 On Local Error Goto Error.Trap9
 Call Close.Files
 Call Open.Shell.Files
 Call Close.Nodes
 Call Open.Node.Files
 Call Close.Temp
 Call Open.Temp.Files
Error.Resume9:
 Exit Sub
Error.Trap9:
 Resume Error.Resume9
End Sub

Sub Open.Shell.Files
 On Local Error Goto Open.Error1
 FileName=Action.Filename
 Open FileName For Random Shared As #ActionFile Len=ActionRecLen
 FileName=Container.FileName
 Open FileName For Random Shared As #ContainerFile Len=ContainerRecLen
 FileName=Message.Base.FileName
 Open FileName For Random Shared As #MessBaseFile Len=MessBaseRecLen
 FileName=Monster.FileName
 Open FileName For Random Shared As #MonsterFile Len=MonsterRecLen
 FileName=MonClass.FileName
 Open FileName For Random Shared As #MonClassFile Len=MonClassRecLen
 FileName=MonTalk.FileName
 Open FileName For Random Shared As #MonTalkFile Len=MonTalkRecLen
 FileName=NonPlayer.FileName
 Open FileName For Random Shared As #NonPlayerFile Len=NonPlayerRecLen
 FileName=Object.FileName
 Open FileName For Random Shared As #ObjectFile Len=ObjectRecLen
 FileName=Room.FileName
 Open FileName For Random Shared As #RoomFile Len=RoomRecLen
 FileName=Room.Desc.FileName
 Open FileName For Random Shared As #RoomDescFile Len=RoomDescLen
 FileName=Spell.FileName
 Open FileName For Random Shared As #SpellFile Len=SpellRecLen
 FileName=Team.FileName
 Open FileName For Random Shared As #TeamFile Len=TeamRecLen
 FileName=Treasure.FileName
 Open FileName For Random Shared As #TreasureFile Len=TreasureRecLen

 FileName=User.FileName
 Open FileName For Random Shared As #UserFile Len=UserRecLen
 Open FileName For Random Shared As #UserFile2 Len=UserRecLen

 FileName=UserInv.FileName
 Open FileName For Random Shared As #UserInvFile Len=MessWorkRecLen6
 FileName=CtnInv.FileName
 Open FileName For Random Shared As #CtnInvFile Len=MessWorkRecLen6
 FileName=TeamInv.FileName
 Open FileName For Random Shared As #TeamInvFile Len=MessWorkRecLen6
 FileName=RoomInv.FileName
 Open FileName For Random Shared As #RoomInvFile Len=MessWorkRecLen6
 FileName=MonInv.FileName
 Open FileName For Random Shared As #MonInvFile Len=MessWorkRecLen6
Open.Exit1:
 Exit Sub
Open.Error1:
 Var2=Err
 If Var2=0 Then Var2=53
 Call Error.Message(Var2,Strng2)
 Out2="opening shell files processing "+Lcase$(FileName)
 Out3="Increase files= in config.sys or config.nt file, or run Dndcnfg."
 Call Terminal.Error
 Resume Open.Exit1
End Sub

Sub Open.Node.Files
 On Local Error Goto Open.Error2
 FileName=MessWork.FileName+"1"+File.Extension1
 Open FileName For Random Shared As #MessWorkFile1 Len=MessWorkRecLen1
 FileName=MessWork.FileName+"2"+File.Extension1
 Open FileName For Random Shared As #MessWorkFile2 Len=MessWorkRecLen2
 FileName=MessWork.FileName+"3"+File.Extension1
 Open FileName For Random Shared As #MessWorkFile3 Len=MessWorkRecLen3
 FileName=MessWork.FileName+"4"+File.Extension1
 Open FileName For Random Shared As #MessWorkFile4 Len=MessWorkRecLen4
 FileName=MessWork.FileName+"5"+File.Extension1
 Open FileName For Random Shared As #MessWorkFile5 Len=MessWorkRecLen5
 FileName=MessWork.FileName+"6"+File.Extension1
 Open FileName For Random Shared As #MessWorkFile6 Len=MessWorkRecLen6
 FileName=MessWork.FileName+"7"+File.Extension1
 Open FileName For Random Shared As #MessWorkFile7 Len=MessWorkRecLen7
 FileName=Data.Path3+Config3(69)+NodeX+File.Extension1
 Open FileName For Random Shared As #MessWorkFile8 Len=UserCommandLen
OPen.Exit2:
 Exit Sub
Open.Error2:
 Var2=Err
 If Var2=0 Then Var2=53
 Call Error.Message(Var2,Strng2)
 Out2="opening node files processing "+Lcase$(FileName)
 Out3="Increase files= in config.sys or config.nt file, or run Dndcnfg."
 Call Terminal.Error
 Resume Open.Exit2
End Sub

Sub Open.Temp.Files
 On Local Error Goto Open.Error3
 FileName=Data.Path3+Config3(69)+NodeX+File.Extension1
 Open FileName For Random Shared As #MessageFile
 Open FileName For Random Shared As #NewFile
 Open FileName For Random Shared As #TableFile
 Open FileName For Random Shared As #LogFile
 Open FileName For Random Shared As #DayFile1
 Open FileName For Random Shared As #TempFile1
 Open FileName For Random Shared As #TempFile2
 Open FileName For Random Shared As #HelpFile1
 Open FileName For Random Shared As #HelpFile2
 Open FileName For Random Shared As #HelpFile3
 Open FileName For Random Shared As #SicFile
 Open FileName For Random Shared As #DiskFile
 Open FileName For Random Shared As #PrintFile
Open.Exit3:
 Exit Sub
Open.Error3:
 Var2=Err
 If Var2=0 Then Var2=53
 Call Error.Message(Var2,Strng2)
 Out2="opening temp files processing "+Lcase$(FileName)
 Out3="Increase files= in config.sys or config.nt file, or run Dndcnfg."
 Call Terminal.Error
 Resume Open.Exit3
End Sub

Sub Read.MonClasses
 On Local Error Goto Monclass.Error
 MonClass.Max=Lof(MonClassFile)/MonClassRecLen
 If MonClass.Max<>Int(MonClass.Max) Then
    MonClass.Max=False
 Endif
 If Config1(39)>SFalse Then
    If MonClass.Max>Config1(39) Then
       MonClass.Max=Config1(39)
    Endif
 Endif
 If MonClass.Max=SFalse Then
    MonClass.Max=1!
    For Temp=1 To 10
       MonClassRecord.Monsters(Temp)=SFalse
    Next
    Call Write.Record(MonClassFile,1!)
 Endif
 NonPlayer.Max=Lof(NonPlayerFile)/NonPlayerRecLen
 If NonPlayer.Max<>Int(NonPlayer.Max) Then
    NonPlayer.Max=False
 Endif
 If Config1(39)>SFalse Then
    If NonPlayer.Max>Config1(39) Then
       NonPlayer.Max=Config1(39)
    Endif
 Endif
 If NonPlayer.Max=SFalse Then
    NonPlayer.Max=1!
    MonsterRecord.PluralName=Nul
    Call Write.Record(NonPlayerFile,1!)
 Endif
 If Low.Mem.Use Then
    Goto Monclass.Exit
 Endif
 Temp!=SFalse
 Temp1!=SFalse
 Redim Monster.Class(1! To MonClass.Max,1 To MaxMonClass) As Single,_
 Monster.Percent(1! To MonClass.Max,1 To MaxMonClass) As Integer,_
 Monster.Rate(1! To MonClass.Max,1 To MaxMonClass) As Integer,_
 NonPlayer.Rooms(1! To NonPlayer.Max) As String*30
 For Temp!=1! To MonClass.Max
    Call Read.Record(MonClassFile,Temp!)
    For Temp1=1 To 10
       Temp2!=MonClassRecord.Monsters(Temp1)
       Monster.Class(Temp!,Temp1)=Temp2!
       If Temp2!>SFalse And Temp2!<=Lof(MonsterFile)/MonsterRecLen Then
          Call Read.Record(MonsterFile,Temp2!)
          Monster.Rate(Temp!,Temp1)=MonsterRecord.Rate
          Monster.Percent(Temp!,Temp1)=MonsterRecord.RatePercent
       Endif
    Next
 Next
 For Temp1!=1! To NonPlayer.Max
    Call Read.Record(NonPlayerFile,Temp1!)
    NonPlayer.Rooms(Temp1!)=MonsterRecord.PluralName
 Next
 Exit Sub
Monclass.Exit:
 Redim Monster.Class(1! To 1!,1 To MaxMonClass) As Single,_
 Monster.Percent(1! To 1!,1 To MaxMonClass) As Integer,_
 Monster.Rate(1! To 1!,1 To MaxMonClass) As Integer,_
 NonPlayer.Rooms(1! To 1!) As String*30
Monclass.Exit2:
 Exit Sub
Monclass.Error:
 ' Out of memory/Subscript out of range/Out of string space.
 If Err=7 Or Err=9 Or Err=14 Then
    Low.Mem.Use=True
    Resume Monclass.Exit
 Endif
 Var2=Err
 If Var2=0 Then Var2=53
 Call Error.Message(Var2,Strng2)
 Out2="opening arrays"
 Out3="Free RAM and restart, or use /D:4"
 Call Terminal.Error
 Resume Monclass.Exit2
End Sub

Sub Open.Session.Files
 On Local Error Goto Error.Trap11
 Close #DiskFile
 If Disk.Log Then ' dsklog??.dat
    Filename=DND.Path+Config3(81)+NodeX+File.Extension1
    Open Filename For Append Shared As #DiskFile
 Else ' altwrk??.dat
    FileName=Data.Path3+Config3(69)+NodeX+File.Extension1
    Open Filename For Random Shared As #DiskFile
 Endif
 Close #PrintFile
 If Print.Log Then
    Filename=Config3(82) ' lpt?:
    Open Filename For Output As #PrintFile
 Else ' altwrk??.dat
    FileName=Data.Path3+Config3(69)+NodeX+File.Extension1
    Open Filename For Random Shared As #PrintFile
 Endif
Error.Resume11:
 Exit Sub
Error.Trap11:
 Resume Error.Resume11
End Sub

Sub Read.Guest
 On Local Error Goto Error.Trap12
 Redim GuestLines(1 To 127) As String
 Redim SpecialUserName(1) As String*30
 Redim SpecialUserTime(1) As String*11
 Redim Temp.Array1(127) As Integer
 Special=1
 GuestRecord.OpenSystem=True
 GuestRecord.OpenSystemTime1=Nul
 GuestRecord.OpenSystemTime2=Nul
 GuestRecord.GuestAllowed=True
 GuestRecord.GuestStartsAtLevel=1
 GuestRecord.GuestStartsInRoom=1!
 GuestRecord.GuestTimeLeft=False
 GuestRecord.GuestClass=False
 GuestRecord.GuestRace=False
 GuestRecord.GuestAlign1=False
 GuestRecord.GuestAlign2=False
 GuestRecord.GuestProf=False
 GuestRecord.GuestStats=Nul
 GuestRecord.GuestCanTeleport=False
 GuestRecord.GuestRoomExit=Nul
 GuestRecord.GuestRoomResurrect=SFalse
 GuestRecord.GuestAllowMail=False
 GuestRecord.GuestAllowCasino=False
 GuestRecord.GuestAllowBank=False
 GuestRecord.GuestAllowTeam=False
 GuestRecord.DualPassword=False
 GuestRecord.PasswordQuestion=False
 GuestRecord.AllowDMLogon=False
 GuestRecord.AllowLocalSysopLogon=False
 GuestRecord.AllowLocalMaxLogon=False
 For Var=1 To 127
    GuestLines(Var)=Nul
 Next
 GuestRecord.SysopName=Nul
 GuestRecord.SysopEmail=Nul
 GuestRecord.BBSname=Nul
 GuestRecord.BBSdesc=Nul
 GuestRecord.TownMayorTime=Nul
 GuestRecord.GovernorTime=Nul
 GuestRecord.GuildMasterTime=Nul
 GuestRecord.SysopTime=Nul
 GuestRecord.DMTime=Nul
 GuestRecord.AsstDMTime=Nul
 GuestRecord.PageTimes=Nul
 Special.Names=False
 GuestRecord.NodeBitMask=Nul
 ' read guest config file
 VarX=1
 FileName=Data.Path1+"GUEST"+NodeX+".CFG"
 Close #TempFile1
 Close #TempFile2
 ' check guest.cfg exists
 If Dir$(Filename)=Nul Then
    Filename2$=Data.Path1+"GUEST.CFG"
    If Dir$(Filename2$)<>Nul Then
       Open Filename$ For Output As #TempFile1
       Open Filename2$ For Input As #TempFile2
       Do While Eof(TempFile2)=0
          Line Input #TempFile2,Var$
          Print #TempFile1,Var$
       Loop
    Endif
 Endif
 Close #TempFile1
 ' recheck config file
 If Dir$(Filename)=Nul Then
    Error 53
 Endif
 If Dir$(FileName)<>Nul Then
    Open Filename For Input Shared As #TempFile1
    Line1=False
    Do
       If Eof(TempFile1) Then
          Exit Do
       Endif
       Line Input #TempFile1,Var$
       Line1=Line1+1
       Var$=Ltrim$(Rtrim$(Var$))
       If Var$<>Nul Then
          If Left$(Var$,1)<>";" Then
             Var=Instr(Var$,"=")
             If Var Then
                Var1$=Left$(Var$,Var-1)
                Var2$=Mid$(Var$,Var+1)
                Var1$=Ltrim$(Rtrim$(Var1$))
                Var2$=Ltrim$(Rtrim$(Var2$))
                Var1$=Ucase$(Var1$)
                Var3$=Var2$
                Var2$=Ucase$(Var2$)
                If Len(Var1$) Then
                   If Len(Var2$) Then
                      ' scan special user time slots
                      If Var1$="USER" Then
                         VarQ=Instr(Var2$,",")
                         If VarQ Then
                            VarX$=Left$(Var2$,VarQ-1)
                            VarX$=Ltrim$(Rtrim$(VarX$))
                            VarY$=Mid$(Var2$,VarQ+1)
                            VarY$=Ltrim$(Rtrim$(VarY$))
                            Gosub Check.Time
                            Special.Names=Special.Names+1
                            If Special.Names>Special Then
                               Special=Special.Names
                               Redim Preserve SpecialUserName(Special) As String*30
                               Redim Preserve SpecialUserTime(Special) As String*11
                            Endif
                            SpecialUserName(Special.Names)=VarX$
                            SpecialUserTime(Special.Names)=VarY$
                         Endif
                      Endif
                      ' store guest line
                      If Left$(Var1$,10)="GUESTLINE#" Then
                         VarZ=Val(Mid$(Var1$,11))
                         If VarZ>=1 And VarZ<=127 Then
                            If Rtrim$(GuestLines(VarZ))<>"" Then
                               Goto Error.Trap12x0
                            Endif
                            GuestLines(VarZ)=Var2$
                         Else
                            Goto Error.Trap12x0
                         Endif
                      Endif
                      ' check open system time
                      If Left$(Var1$,11)="OPENSYSTEM#" Then
                         VarZ=Val(Mid$(Var1$,12))
                         If VarZ>=1 And VarZ<=127 Then
                            If Temp.Array1(VarZ) Then
                               Goto Error.Trap12x0
                            Endif
                            Temp.Array1(VarZ)=-1
                            VarY$=Var2$
                            Gosub Check.Time
                         Else
                            Goto Error.Trap12x0
                         Endif
                      Endif
                      ' parse remaining parameters
                      Select Case Var1$
                      Case "OPENSYSTEM"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            GuestRecord.OpenSystem=False
                         Case "-1", "ON", "TRUE"
                            GuestRecord.OpenSystem=True
                         End Select
                      Case "OPENSYSTEMTIME1"
                         VarY$=Var2$
                         Gosub Check.Time
                         GuestRecord.OpenSystemTime1=Var2$
                      Case "OPENSYSTEMTIME2"
                         VarY$=Var2$
                         Gosub Check.Time
                         GuestRecord.OpenSystemTime2=Var2$
                      Case "TOWNMAYORTIME"
                         VarY$=Var2$
                         Gosub Check.Time
                         GuestRecord.TownMayorTime=Var2$
                      Case "GOVERNORTIME"
                         VarY$=Var2$
                         Gosub Check.Time
                         GuestRecord.GovernorTime=Var2$
                      Case "GUILDMASTERTIME"
                         VarY$=Var2$
                         Gosub Check.Time
                         GuestRecord.GuildMasterTime=Var2$
                      Case "SYSOPTIME"
                         VarY$=Var2$
                         Gosub Check.Time
                         GuestRecord.SysopTime=Var2$
                      Case "DMTIME"
                         VarY$=Var2$
                         Gosub Check.Time
                         GuestRecord.DMTime=Var2$
                      Case "ASSTDMTIME"
                         VarY$=Var2$
                         Gosub Check.Time
                         GuestRecord.AsstDMTime=Var2$
                      Case "PAGETIMES"
                         GuestRecord.PageTimes=Var2$
                      Case "NODEBITMASK"
                         GuestRecord.NodeBitMask=Var2$
                      Case "GUESTALLOWED"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            GuestRecord.GuestAllowed=False
                         Case "-1", "ON", "TRUE"
                            GuestRecord.GuestAllowed=True
                         End Select
                      Case "GUESTCANTELEPORT"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            GuestRecord.GuestCanTeleport=False
                         Case "-1", "ON", "TRUE"
                            GuestRecord.GuestCanTeleport=True
                         End Select
                      Case "GUESTSTARTSATLEVEL"
                         GuestRecord.GuestStartsAtLevel=Int(Val(Var2$))
                      Case "GUESTSTARTSINROOM"
                         GuestRecord.GuestStartsInRoom=Csng(Int(Val(Var2$)))
                      Case "GUESTTIMELEFT"
                         GuestRecord.GuestTimeLeft=Int(Val(Var2$))
                      Case "GUESTCLASS"
                         GuestRecord.GuestClass=Int(Val(Var2$))
                      Case "GUESTRACE"
                         GuestRecord.GuestRace=Int(Val(Var2$))
                      Case "GUESTALIGN1"
                         GuestRecord.GuestAlign1=Int(Val(Var2$))
                      Case "GUESTALIGN2"
                         GuestRecord.GuestAlign2=Int(Val(Var2$))
                      Case "GUESTPROF"
                         GuestRecord.GuestProf=Int(Val(Var2$))
                      Case "GUESTSTATS"
                         GuestRecord.GuestStats=Var2$
                      Case "GUESTROOMEXIT"
                         GuestRecord.GuestRoomExit=Var2$
                      Case "GUESTROOMRESURRECT"
                         GuestRecord.GuestRoomResurrect=Int(Val(Var2$))
                      Case "SYSOPNAME"
                         GuestRecord.SysopName=Var3$
                      Case "SYSOPEMAIL"
                         GuestRecord.SysopEmail=Var3$
                      Case "BBSNAME"
                         GuestRecord.BBSname=Var3$
                      Case "BBSDESC"
                         GuestRecord.BBSdesc=Var3$
                      Case "GUESTALLOWMAIL"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            GuestRecord.GuestAllowMail=False
                         Case "-1", "ON", "TRUE"
                            GuestRecord.GuestAllowMail=True
                         End Select
                      Case "GUESTALLOWCASINO"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            GuestRecord.GuestAllowCasino=False
                         Case "-1", "ON", "TRUE"
                            GuestRecord.GuestAllowCasino=True
                         End Select
                      Case "GUESTALLOWBANK"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            GuestRecord.GuestAllowBank=False
                         Case "-1", "ON", "TRUE"
                            GuestRecord.GuestAllowBank=True
                         End Select
                      Case "GUESTALLOWTEAM"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            GuestRecord.GuestAllowTeam=False
                         Case "-1", "ON", "TRUE"
                            GuestRecord.GuestAllowTeam=True
                         End Select
                      Case "DUALPASSWORD"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            GuestRecord.DualPassword=False
                         Case "-1", "ON", "TRUE"
                            GuestRecord.DualPassword=True
                         End Select
                      Case "NOPASSWORDREQUIRED"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            GuestRecord.DualPassword=False
                         Case "-1", "ON", "TRUE"
                            GuestRecord.DualPassword=-2
                         End Select
                      Case "PASSWORDQUESTION"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            GuestRecord.PasswordQuestion=False
                         Case "-1", "ON", "TRUE"
                            GuestRecord.PassWordQuestion=True
                         End Select
                      CASE "ALLOWDMLOGON"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            GuestRecord.AllowDMLogon=False
                         Case "-1", "ON", "TRUE"
                            GuestRecord.AllowDMLogon=True
                         End Select
                      CASE "ALLOWLOCALSYSOPLOGON"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            GuestRecord.AllowLocalSysopLogon=False
                         Case "-1", "ON", "TRUE"
                            GuestRecord.AllowLocalSysopLogon=True
                         End Select
                      CASE "ALLOWLOCALMAXLOGON"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            GuestRecord.AllowLocalMaxLogon=False
                         Case "-1", "ON", "TRUE"
                            GuestRecord.AllowLocalMaxLogon=True
                         End Select
                      End Select
                   Endif
                Endif
             Endif
          Endif
       Endif
    Loop
 Endif
 Erase Temp.Array1
 ' sort special usernames
 For Var1=1 To Special.Names
    For Var2=Var1+1 To Special.Names
       If SpecialUserName(Var1)>SpecialUserName(Var2) Then
          Swap SpecialUserName(Var1),SpecialUserName(Var2)
          Swap SpecialUserTime(Var1),SpecialUserTime(Var2)
       Endif
    Next
 Next
 ' read start config file
 Low.Mem.Use=True
 Check.Machine.Name=True
 FileName=Data.Path1+"START"+NodeX+".CFG"
 Close #TempFile1
 Close #TempFile2
 ' check start.cfg exists
 VarX=2
 If Dir$(Filename)=Nul Then
    Filename2$=Data.Path1+"START.CFG"
    If Dir$(Filename2$)<>Nul Then
       Open Filename$ For Output As #TempFile1
       Open Filename2$ For Input As #TempFile2
       Do While Eof(TempFile2)=0
          Line Input #TempFile2,Var$
          Print #TempFile1,Var$
       Loop
    Endif
 Endif
 Close #TempFile1
 ' recheck config file
 If Dir$(Filename)=Nul Then
    Error 53
 Endif
 If Dir$(FileName)<>Nul Then
    Open Filename For Input Shared As #TempFile1
    Line1=False
    Do
       If Eof(TempFile1) Then
          Exit Do
       Endif
       Line Input #TempFile1,Var$
       Line1=Line1+1
       Var$=Ltrim$(Rtrim$(Var$))
       If Var$<>Nul Then
          If Left$(Var$,1)<>";" Then
             Var=Instr(Var$,"=")
             If Var Then
                Var1$=Left$(Var$,Var-1)
                Var2$=Mid$(Var$,Var+1)
                Var1$=Ltrim$(Rtrim$(Var1$))
                Var2$=Ltrim$(Rtrim$(Var2$))
                Var1$=Ucase$(Var1$)
                Var2$=Ucase$(Var2$)
                If Len(Var1$) Then
                   If Len(Var2$) Then
                      Select Case Var1$
                      Case "BYPASSSWITCH"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            Bypass.Splash=Bypass.Splash And Not 1
                         Case "-1", "ON", "TRUE"
                            Bypass.Splash=Bypass.Splash Or 1
                         End Select
                      Case "BYPASSAUTHOR"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            Bypass.Splash=Bypass.Splash And Not 2
                         Case "-1", "ON", "TRUE"
                            Bypass.Splash=Bypass.Splash Or 2
                         End Select
                      Case "DEBUGPACK"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            Debug.Pack=False
                         Case "-1", "ON", "TRUE"
                            Debug.Pack=True
                         End Select
                      Case "LOADWINDOWS"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            Windows.Detected=False
                         Case "-1", "ON", "TRUE"
                            Windows.Detected=True
                         End Select
                      Case "LOWMEMUSE"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            Low.Mem.Use=False
                         Case "-1", "ON", "TRUE"
                            Low.Mem.Use=True
                         End Select
                      Case "DISABLESHARE"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            Disable.Share=False
                         Case "-1", "ON", "TRUE"
                            Disable.Share=True
                         End Select
                      Case "FORCESHARE"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            Disable.Share=False
                         Case "-1", "ON", "TRUE"
                            Disable.Share=-2
                         End Select
                      Case "DISABLEANSI"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            Disable.Ansi=False
                         Case "-1", "ON", "TRUE"
                            Disable.Ansi=True
                         End Select
                      Case "FORCEANSI"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            Disable.Ansi=False
                         Case "-1", "ON", "TRUE"
                            Disable.Ansi=-2
                         End Select
                      Case "DISABLEAVATAR"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            Disable.Avatar=False
                         Case "-1", "ON", "TRUE"
                            Disable.Avatar=True
                         End Select
                      Case "FORCEAVATAR"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            Disable.Avatar=False
                         Case "-1", "ON", "TRUE"
                            Disable.Avatar=-2
                         End Select
                      Case "DEBUGMODE"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            Debug.Mode=False
                         Case "-1", "ON", "TRUE"
                            Debug.Mode=True
                         End Select
                      Case "DISABLEBREAK"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            Disable.Break=False
                         Case "-1", "ON", "TRUE"
                            Disable.Break=True
                         End Select
                      Case "CHECKMACHINENAME"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            Check.Machine.Name=False
                         Case "-1", "ON", "TRUE"
                            Check.Machine.Name=True
                         End Select
                      Case "EQUATEDEBUG"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            Equate.Debug=False
                         Case "-1", "ON", "TRUE"
                            Equate.Debug=True
                         End Select
                      Case "DISABLESTRING"
                         Select Case Var2$
                         Case "0", "OFF", "FALSE"
                            Disable.String=False
                         Case "-1", "ON", "TRUE"
                            Disable.String=True
                         End Select
                      End Select
                   Endif
                Endif
             Endif
          Endif
       Endif
    Loop
 Endif
Error.Resume12:
 Exit Sub

' check time string
Check.Time:
' check 00:00-23:59 format
 If Len(VarY$)<>11 Then
    Goto Error.Trap12x1
 Endif
 For VarZ2=1 To 11
    VarZ$=Mid$(VarY$,VarZ2,1)
    Select Case VarZ2
    Case 1, 2, 4, 5, 7, 8, 10, 11
       If VarZ$>="0" And VarZ$<="9" Then
          Eat$ = Nul
       Else
          Goto Error.Trap12x1
       Endif
    Case 3, 9
       If VarZ$<>":" Then
          Goto Error.Trap12x1
       Endif
    Case 6
       If VarZ$<>"-" Then
          Goto Error.Trap12x1
       Endif
    End Select
 Next
 ' check hh:mm-hh:mm ranges
 HH=Val(Mid$(VarY$,1,2))
 If HH>=0 And HH<=23 Then
    Eat$=Nul
 Else
    Goto Error.Trap12x1
 Endif
 HH=Val(Mid$(VarY$,7,2))
 If HH>=0 And HH<=23 Then
    Eat$=Nul
 Else
    Goto Error.Trap12x1
 Endif
 MM=Val(Mid$(VarY$,4,2))
 If MM>=0 And MM<=59 Then
    Eat$=Nul
 Else
    Goto Error.Trap12x1
 Endif
 MM=Val(Mid$(VarY$,10,2))
 If MM>=0 And MM<=59 Then
    Eat$=Nul
 Else
    Goto Error.Trap12x1
 Endif
 Return
Error.Trap12x0:
 Strng2=" Bad value in line"+Str$(Line1)
 Var2=0
 VarX=0
 Goto Error.Trap12x2
Error.Trap12x1:
 Strng2=" Bad time in line"+Str$(Line1)
 Var2=0
 VarX=0
 Goto Error.Trap12x2
Error.Trap12:
 Var2=Err
 If Var2=0 Then Var2=53
 Call Error.Message(Var2,Strng2)
Error.Trap12x2:
 Strng3="Edit file and restart"
 If VarX=1 Then
    Strng3=Strng3+", or run Dndutil /W7"
 Else
    If VarX=2 Then
       Strng3=Strng3+", or run Dndutil /W8"
    Else
       Strng3=Strng3+"."
    Endif
 Endif
 ' Out of memory/Subscript out of range/Out of string space.
 If Var2=7 Or Var2=9 Or Var2=14 Then
    Strng3="Free RAM and restart."
 Endif
 Out2="reading "+FileName
 Out3=Strng3
 Call Terminal.Error
 Resume Error.Resume12
End Sub

Sub Read.Options
 On Local Error Goto Error.Trap13
 Redim Options.Array(1 To 128) As String
 Options.Lines=128
 Var=0
 Close #TempFile1
 Close #TempFile2
 Filename=DND.Path+"OPTION"+NodeX+".CFG"

 ' check option.cfg exists
 VarZ=0
 If Dir$(Filename)=Nul Then
    Filename2$=DND.Path+"OPTION.CFG"
    If Dir$(Filename2$)<>Nul Then
       Open Filename$ For Output As #TempFile1
       Open Filename2$ For Input As #TempFile2
       Do While Eof(TempFile2)=0
          Line Input #TempFile2,Var$
          ' check line 1
          If VarZ=0 Then
             VarZ=-1
             If Left$(Var$,1)=";" Then
                If Right$(Var$,5)="<nul>" Then
                   Var$=Left$(Var$,Len(Var$)-5)
                   Var$=Var$+NodeX
                Endif
             Endif
          Endif
          Print #TempFile1,Var$
       Loop
    Endif
 Endif

 ' recheck options
 If Dir$(Filename)=Nul Then
    Error 53
 Endif

 ' read options
 If Dir$(Filename)<>Nul Then
    Close #TempFile1
    Open Filename For Input As #TempFile1
    Do
       If Eof(TempFile1) Then
          Exit Do
       Endif
       Line Input #TempFile1,Var$
       Var$=Ltrim$(Rtrim$(Var$))
       If Len(Var$) Then
          If Left$(Var$,1)<>";" Then
             Var=Var+1
             If Var>Options.Lines Then
                Options.Lines=Options.Lines+16
                Redim Preserve Options.Array(1 To Options.Lines) As String
             Endif
             Options.Array(Var)=Var$
          Endif
       Endif
    Loop
 Endif
 Options.Lines=Var
 VarX=0
 Do
    VarX=VarX+1
    If VarX>Options.Lines Then
       Exit Do
    Endif
    Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
    If Ucase$(Var$)="[DNDBBS]" Then
       Do
          VarX=VarX+1
          If VarX>Options.Lines Then
             Exit Do
          Endif
          Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
          If Ucase$(Var$)="[END]" Then
             Exit Do
          Endif
          Var=Instr(Var$,"=")
          If Var Then
             Var2$=Lcase$(Ltrim$(Rtrim$(Left$(Var$,Var-1))))
             Var3$=Lcase$(Ltrim$(Rtrim$(Mid$(Var$,Var+1))))
             If Left$(Var2$,4)="menu" Then
                VarQ=Val(Mid$(Var2$,5))
                If VarQ>=1 And VarQ<=10 Then
                   Select Case Var3$
                   Case "0", "false", "off"
                      If Menu1(VarQ)="" Then
                         Menu1(VarQ)="*"
                      Else
                         Mid$(Menu1(VarQ),1,1)="*"
                      Endif
                   End Select
                Endif
             Endif
          Endif
       Loop
    Endif
 Loop
 For VarX=1 To MaxMenus
    If Len(Rtrim$(Menu1(VarX)))=0 Then
       Menu1(VarX)="*"
    Endif
 Next
 If Dir$(DND.Path+"edit.exe")=Nul Then
    Mid$(Menu1(4),1,1)="*"
 Endif
 If Dir$(DND.Path+"dndcnfg.exe")=Nul Then
    Mid$(Menu1(8),1,1)="*"
 Endif
 If Dir$(DND.Path+"dndedit.exe")=Nul Then
    Mid$(Menu1(9),1,1)="*"
 Endif
Error.Resume13:
 Exit Sub
Error.Trap13:
 Var2=Err
 If Var2=0 Then Var2=53
 Call Error.Message(Var2,Strng2)
 Strng3="Edit file and restart, or run Dndutil /W9"
 ' Out of memory/Subscript out of range/Out of string space.
 If Var2=7 Or Var2=9 Or Var2=14 Then
    Strng3="Free RAM and restart."
 Endif
 Out2="reading "+FileName
 Out3=Strng3
 Call Terminal.Error
 Resume Error.Resume13
End Sub

Sub Error.Message(VarX,VarX$)
 On Local Error Goto Error.Trap14
 VarX$=Nul
 Select Case VarX
 Case 5
    VarX$="Syntax Error"
 Case 7
    VarX$="Out of memory"
 Case 9
    VarX$="Subscript out of range"
 Case 14
    VarX$="Out of string space"
 Case 53
    VarX$="File not found"
 Case 55
    VarX$="File already open"
 Case 57
    VarX$="Media error"
 Case 61
    VarX$="Disk full"
 Case 62
    VarX$="Input past eof"
 Case 64
    VarX$="Bad filename"
 Case 67
    VarX$="Not enough file handles"
 Case 68
    VarX$="Device unavailable"
 Case 70
    VarX$="Permission denied"
 Case 71
    VarX$="Disk not ready"
 Case 75
    VarX$="Path/file access error"
 Case 76
    VarX$="Path not found"
 Case Else
    VarX$=Str$(VarX)
    Exit Sub
 End Select
 VarX$=" "+Quote+VarX$+Quote
Error.Resume14:
 Exit Sub
Error.Trap14:
 Resume Error.Resume14
End Sub

Sub Terminal.Error
 Lost.Carrier=-1
 Print
 Strng="Dndbbs main menu:"
 Call Scroll.Row(1)
 Print
 Out2="Error:"+Strng2+" "+Out2+"."
 Call Terminate.Program
 End 1
End Sub
