mysticbbs/mystic/mystic.pas

515 lines
14 KiB
ObjectPascal
Raw Normal View History

2012-02-13 16:03:45 -08:00
// ====================================================================
2013-02-26 04:45:01 -08:00
// Mystic BBS Software Copyright 1997-2013 By James Coyle
2012-02-13 16:03:45 -08:00
// ====================================================================
//
// This file is part of Mystic BBS.
//
// Mystic BBS is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mystic BBS is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mystic BBS. If not, see <http://www.gnu.org/licenses/>.
//
// ====================================================================
Program Mystic;
{$I M_OPS.PAS}
Uses
{$IFDEF DEBUG}
HeapTrc,
LineInfo,
{$ENDIF}
{$IFDEF WINDOWS}
m_io_Base,
m_io_Sockets,
{$ENDIF}
2012-02-13 16:03:45 -08:00
{$IFDEF UNIX}
BaseUnix,
{$ENDIF}
m_FileIO,
m_Strings,
m_DateTime,
m_Output,
m_Input,
2012-09-06 01:33:15 -07:00
m_Pipe,
2013-08-29 03:04:20 -07:00
BBS_Records,
2012-02-13 16:03:45 -08:00
bbs_Common,
bbs_DataBase,
2012-02-13 16:03:45 -08:00
bbs_Core,
bbs_NodeInfo,
{$IFDEF TESTEDITOR}
BBS_Edit_Ansi,
{$ENDIF}
2012-02-13 16:03:45 -08:00
bbs_Cfg_Main;
{$IFDEF TESTEDITOR}
2013-03-04 07:53:06 -08:00
Procedure TestEditor;
Var
T : TEditorANSI;
Begin
T := TEditorANSI.Create(Pointer(Session), 'ansiedit');
2013-03-04 07:53:06 -08:00
T.Edit;
T.Free;
End;
{$ENDIF}
2013-03-04 07:53:06 -08:00
2012-02-13 16:03:45 -08:00
Procedure InitClasses;
Begin
2013-09-16 13:31:39 -07:00
Case BBSCfgStatus of
CfgNotFound : Begin
WriteLn('ERROR: Unable to read mystic.dat');
Halt(1);
End;
CfgMisMatch : Begin
WriteLn('ERROR: Data files are not current and must be upgraded');
Halt(1);
End;
2012-02-13 16:03:45 -08:00
End;
2013-09-16 13:31:39 -07:00
Console := TOutput.Create(True);
Keyboard := TInput.Create;
Session := TBBSCore.Create;
2012-02-13 16:03:45 -08:00
2013-09-16 13:31:39 -07:00
Assign (Session.ConfigFile, bbsCfgPath + 'mystic.dat');
2012-02-13 16:03:45 -08:00
End;
Procedure DisposeClasses;
Begin
Session.Free;
2013-09-16 13:31:39 -07:00
Keyboard.Free;
Console.Free;
2012-02-13 16:03:45 -08:00
End;
Var
ExitSave : Pointer;
Procedure ExitHandle;
Begin
Set_Node_Action('');
Session.UpdateHistory;
ExitProc := ExitSave;
If ErrorAddr <> NIL Then ExitCode := 1;
2012-02-13 16:03:45 -08:00
If Session.User.UserNum <> -1 Then Begin
Session.User.ThisUser.LastOn := CurDateDos;
Session.User.ThisUser.PeerIP := Session.UserIPInfo;
Session.User.ThisUser.PeerHost := Session.UserHostInfo;
2012-02-13 16:03:45 -08:00
If Session.TimerOn Then
If (Session.TimeOffset > 0) and (Session.TimeSaved > Session.TimeOffset) Then
Session.User.ThisUser.TimeLeft := Session.TimeSaved - (Session.TimeOffset - Session.TimeLeft)
Else
Session.User.ThisUser.TimeLeft := Session.TimeLeft;
Reset (Session.User.UserFile);
Seek (Session.User.UserFile, Session.User.UserNum - 1);
Write (Session.User.UserFile, Session.User.ThisUser);
Close (Session.User.UserFile);
End;
If Session.EventExit or Session.EventRunAfter Then Begin
Reset (Session.EventFile);
2012-02-26 12:44:07 -08:00
2012-02-13 16:03:45 -08:00
While Not Eof(Session.EventFile) Do Begin
Read (Session.EventFile, Session.Event);
2012-02-26 04:45:21 -08:00
2012-02-13 16:03:45 -08:00
If Session.Event.Name = Session.NextEvent.Name Then Begin
Session.Event.LastRan := CurDateDos;
Seek (Session.EventFile, FilePos(Session.EventFile) - 1);
Write (Session.EventFile, Session.Event);
End;
End;
2012-02-26 04:45:21 -08:00
2012-02-13 16:03:45 -08:00
Close (Session.EventFile);
End;
If Session.ExitLevel <> 0 Then ExitCode := Session.ExitLevel;
If Session.EventRunAfter Then ExitCode := Session.NextEvent.ExecLevel;
2012-02-13 16:03:45 -08:00
2013-05-20 02:35:04 -07:00
// would be nice flush if not local and still conected: Session.io.BufFlush;
FileMode := 66;
DirClean (Session.TempPath, '');
FileErase (bbsCfg.DataPath + 'chat' + strI2S(Session.NodeNum) + '.dat');
2012-02-13 16:03:45 -08:00
{$IFNDEF LOGGING}
{$IFNDEF UNIX}
2013-09-16 13:31:39 -07:00
Console.TextAttr := 14;
2013-09-16 13:31:39 -07:00
Console.SetWindow (1, 1, 80, 25, False);
Console.ClearScreen;
Console.WriteLine ('Exiting with Errorlevel ' + strI2S(ExitCode));
{$ENDIF}
2012-02-13 16:03:45 -08:00
{$ENDIF}
DisposeClasses;
Halt (ExitCode);
End;
Procedure CheckDIR (Dir: String);
Begin
2012-03-03 19:08:30 -08:00
If Not DirExists(Dir) Then Begin
2013-09-16 13:31:39 -07:00
Console.WriteLine ('ERROR: ' + Dir + ' does not exist.');
2012-02-13 16:03:45 -08:00
DisposeClasses;
2012-02-13 16:03:45 -08:00
Halt(1);
End;
End;
Procedure CalculateNodeNumber;
Var
Count : Word;
TChat : ChatRec;
Begin
Session.NodeNum := 0;
For Count := 1 to bbsCfg.INetTNNodes Do Begin
2013-09-16 13:31:39 -07:00
Assign (Session.ChatFile, bbsCfg.DataPath + 'chat' + strI2S(Count) + '.dat');
2013-09-16 13:31:39 -07:00
If Not ioReset (Session.ChatFile, Sizeof(ChatRec), fmRWDN) Then Begin
Session.NodeNum := Count;
Break;
End Else Begin
2013-09-16 13:31:39 -07:00
ioRead (Session.ChatFile, TChat);
Close (Session.ChatFile);
If Not TChat.Active Then Begin
Session.NodeNum := Count;
Break;
End;
End;
End;
End;
2012-02-13 16:03:45 -08:00
{$IFDEF UNIX}
Procedure LinuxEventSignal (Sig : LongInt); cdecl;
Begin
FileMode := 66;
2013-08-24 22:39:24 -07:00
Session.SystemLog('DEBUG: Signal received: ' + strI2S(Sig));
2012-02-13 16:03:45 -08:00
Case Sig of
// SIGHUP : Halt;
// SIGTERM : Halt;
SIGHUP : Begin
FileErase (bbsCfg.DataPath + 'chat' + strI2S(Session.NodeNum) + '.dat');
Halt;
End;
SIGTERM : Begin
FileErase (bbsCfg.DataPath + 'chat' + strI2S(Session.NodeNum) + '.dat');
Halt;
End;
2012-02-13 16:03:45 -08:00
SIGUSR1 : Session.CheckTimeOut := False;
SIGUSR2 : Begin
Session.CheckTimeOut := True;
Session.TimeOut := TimerSeconds;
End;
End;
End;
Procedure InitializeUnix;
2012-02-13 16:03:45 -08:00
Var
Info : Stat;
2012-02-13 16:03:45 -08:00
Begin
If fpStat('mystic', Info) = 0 Then Begin
fpSetGID (Info.st_GID);
fpSetUID (Info.st_UID);
End;
2012-02-13 16:03:45 -08:00
fpSignal (SIGTERM, LinuxEventSignal);
fpSignal (SIGHUP, LinuxEventSignal);
Write (#27 + '(U');
End;
{$ENDIF}
Procedure CheckPathsAndDataFiles;
Var
Count : Byte;
Begin
Randomize;
2012-08-24 14:41:05 -07:00
FileMode := 66;
Session.TempPath := bbsCfg.SystemPath + 'temp' + strI2S(Session.NodeNum) + PathChar;
Session.Pipe := TPipe.Create(bbsCfg.DataPath, False, Session.NodeNum);
2012-08-21 09:23:47 -07:00
2013-09-13 20:08:58 -07:00
(*
2012-02-13 16:03:45 -08:00
{$I-}
MkDir (bbsCfg.SystemPath + 'temp' + strI2S(Session.NodeNum));
2012-02-13 16:03:45 -08:00
{$I+}
2012-03-03 01:49:58 -08:00
If IoResult <> 0 Then;
2013-09-13 20:08:58 -07:00
*)
DirCreate (Session.TempPath);
DirClean (Session.TempPath, '');
2012-02-13 16:03:45 -08:00
Assign (Session.User.UserFile, bbsCfg.DataPath + 'users.dat');
2012-02-26 12:44:07 -08:00
{$I-} Reset (Session.User.UserFile); {$I+}
If IoResult <> 0 Then Begin
If FileExist(bbsCfg.DataPath + 'users.dat') Then Begin
2013-09-16 13:31:39 -07:00
Console.WriteLine ('ERROR: Unable to access USERS.DAT');
2012-02-26 12:44:07 -08:00
DisposeClasses;
Halt(1);
End;
ReWrite(Session.User.UserFile);
End;
Close (Session.User.UserFile);
Assign (Session.VoteFile, bbsCfg.DataPath + 'votes.dat');
2012-06-30 17:23:39 -07:00
{$I-} Reset (Session.VoteFile); {$I+}
If IoResult <> 0 Then ReWrite (Session.VoteFile);
Close (Session.VoteFile);
Assign (Session.ThemeFile, bbsCfg.DataPath + 'theme.dat');
2012-06-30 17:23:39 -07:00
{$I-} Reset (Session.ThemeFile); {$I+}
If IoResult <> 0 Then Begin
2013-09-21 22:32:42 -07:00
Console.WriteLine ('ERROR: No theme configuration');
DisposeClasses;
Halt(1);
End;
2012-06-30 17:23:39 -07:00
Close (Session.ThemeFile);
If Not Session.LoadThemeData(bbsCfg.DefThemeFile) Then Begin
If Not Session.ConfigMode Then Begin
2013-09-16 13:31:39 -07:00
Console.WriteLine ('ERROR: Default theme prompts not found: ' + bbsCfg.DefThemeFile + '.txt');
DisposeClasses;
Halt(1);
End;
End;
If Session.ConfigMode Then Exit;
CheckDIR (bbsCfg.SystemPath);
CheckDIR (bbsCfg.AttachPath);
CheckDIR (bbsCfg.DataPath);
CheckDIR (bbsCfg.MsgsPath);
CheckDIR (bbsCfg.SemaPath);
CheckDIR (bbsCfg.QwkPath);
CheckDIR (bbsCfg.ScriptPath);
CheckDIR (bbsCfg.LogsPath);
2013-09-16 13:31:39 -07:00
Assign (Session.RoomFile, bbsCfg.DataPath + 'chatroom.dat');
{$I-} Reset (Session.RoomFile); {$I+}
If IoResult <> 0 Then Begin
2013-09-16 13:31:39 -07:00
ReWrite (Session.RoomFile);
Session.Room.Name := 'None';
For Count := 1 to 99 Do
2013-09-16 13:31:39 -07:00
Write (Session.RoomFile, Session.Room);
End;
2013-09-16 13:31:39 -07:00
Close (Session.RoomFile);
Assign (Session.FileBase.FBaseFile, bbsCfg.DataPath + 'fbases.dat');
2012-02-13 16:03:45 -08:00
{$I-} Reset(Session.FileBase.FBaseFile); {$I+}
If IoResult <> 0 Then ReWrite(Session.FileBase.FBaseFile);
Close (Session.FileBase.FBaseFile);
Assign (Session.Msgs.MBaseFile, bbsCfg.DataPath + 'mbases.dat');
2012-02-13 16:03:45 -08:00
{$I-} Reset(Session.Msgs.MBaseFile); {$I+}
If IoResult <> 0 Then Begin
2013-09-16 13:31:39 -07:00
Console.WriteLine ('ERROR: No message base configuration. Use MYSTIC -CFG');
DisposeClasses;
Halt(1);
2012-02-13 16:03:45 -08:00
End;
Close (Session.Msgs.MBaseFile);
Assign (Session.Msgs.GroupFile, bbsCfg.DataPath + 'groups_g.dat');
2012-02-13 16:03:45 -08:00
{$I-} Reset (Session.Msgs.GroupFile); {$I-}
If IoResult <> 0 Then ReWrite(Session.Msgs.GroupFile);
Close (Session.Msgs.GroupFile);
Assign (Session.FileBase.FGroupFile, bbsCfg.DataPath + 'groups_f.dat');
2012-02-13 16:03:45 -08:00
{$I-} Reset (Session.FileBase.FGroupFile); {$I+}
If IoResult <> 0 Then ReWrite (Session.FileBase.FGroupFile);
Close (Session.FileBase.FGroupFile);
Assign (Session.User.SecurityFile, bbsCfg.DataPath + 'security.dat');
2012-02-13 16:03:45 -08:00
{$I-} Reset (Session.User.SecurityFile); {$I+}
If IoResult <> 0 Then Begin
ReWrite(Session.User.SecurityFile);
2012-02-13 16:03:45 -08:00
For Count := 1 to 255 Do
Write (Session.User.SecurityFile, Session.User.Security);
End;
Close (Session.User.SecurityFile);
2013-09-16 13:31:39 -07:00
Assign (Session.LastOnFile, bbsCfg.DataPath + 'callers.dat');
{$I-} Reset(Session.LastOnFile); {$I+}
If IoResult <> 0 Then ReWrite(Session.LastOnFile);
Close (Session.LastOnFile);
2012-02-13 16:03:45 -08:00
Assign (Session.FileBase.ArcFile, bbsCfg.DataPath + 'archive.dat');
2012-02-13 16:03:45 -08:00
{$I-} Reset(Session.FileBase.ArcFile); {$I+}
If IoResult <> 0 Then ReWrite(Session.FileBase.ArcFile);
Close (Session.FileBase.ArcFile);
Assign (Session.FileBase.ProtocolFile, bbsCfg.DataPath + 'protocol.dat');
2012-02-13 16:03:45 -08:00
{$I-} Reset (Session.FileBase.ProtocolFile); {$I+}
If IoResult <> 0 Then ReWrite (Session.FileBase.ProtocolFile);
Close (Session.FileBase.ProtocolFile);
End;
Var
2013-03-13 20:56:42 -07:00
Count : Byte;
Temp : String[120];
Script : String[120];
2012-02-13 16:03:45 -08:00
Begin
{$IFDEF DEBUG}
SetHeapTraceOutput('mystic.mem');
{$ENDIF}
2012-02-24 06:04:34 -08:00
DirChange(JustPath(ParamStr(0)));
2012-02-13 16:03:45 -08:00
2013-03-04 07:53:06 -08:00
//FileMode := 66;
2012-02-13 16:03:45 -08:00
InitClasses;
2013-09-16 13:31:39 -07:00
Console.TextAttr := 7;
Console.WriteLine('');
2012-02-13 16:03:45 -08:00
For Count := 1 to ParamCount Do Begin
Temp := strUpper(ParamStr(Count));
If Copy(Temp, 1, 4) = '-TID' Then
Session.CommHandle := strS2I(Copy(Temp, 5, Length(Temp)))
Else
If Copy(Temp, 1, 2) = '-B' Then
Session.Baud := strS2I(Copy(Temp, 3, Length(Temp)))
Else
2012-08-16 05:31:19 -07:00
If Copy(Temp, 1, 2) = '-T' Then
2012-02-13 16:03:45 -08:00
Session.TimeOffset := strS2I(Copy(Temp, 3, Length(Temp)))
Else
2012-08-16 05:31:19 -07:00
If Copy(Temp, 1, 2) = '-N' Then
2012-02-13 16:03:45 -08:00
Session.NodeNum := strS2I(Copy(Temp, 3, Length(Temp)))
Else
2012-08-16 05:31:19 -07:00
If Copy(Temp, 1, 4) = '-CFG' Then Begin
2012-02-13 16:03:45 -08:00
Session.ConfigMode := True;
Session.LocalMode := True;
Session.NodeNum := 0;
End Else
2012-08-16 05:31:19 -07:00
If Copy(Temp, 1, 3) = '-IP' Then
2012-02-13 16:03:45 -08:00
Session.UserIPInfo := Copy(Temp, 4, Length(Temp))
Else
2012-08-16 05:31:19 -07:00
If Copy(Temp, 1, 4) = '-UID' Then
2012-02-13 16:03:45 -08:00
Session.UserHostInfo := Copy(Temp, 5, Length(Temp))
Else
2012-08-16 05:31:19 -07:00
If Copy(Temp, 1, 5) = '-HOST' Then
Session.UserHostInfo := Copy(ParamStr(Count), 6, Length(Temp))
2012-02-13 16:03:45 -08:00
Else
2012-08-16 05:31:19 -07:00
If Copy(Temp, 1, 2) = '-U' Then
2013-03-13 20:56:42 -07:00
Session.UserLoginName := strReplace(Copy(Temp, 3, Length(Temp)), '_', ' ')
2012-02-13 16:03:45 -08:00
Else
2012-08-16 05:31:19 -07:00
If Copy(Temp, 1, 2) = '-P' Then
2013-03-13 20:56:42 -07:00
Session.UserLoginPW := Copy(Temp, 3, Length(Temp))
2012-02-13 16:03:45 -08:00
Else
2012-08-16 05:31:19 -07:00
If Copy(Temp, 1, 2) = '-X' Then
Script := strReplace(Copy(ParamStr(Count), 3, Length(Temp)), '_', ' ')
2012-02-13 16:03:45 -08:00
Else
If Temp = '-L' Then Session.LocalMode := True;
End;
{$IFDEF UNIX}
InitializeUnix;
2012-02-13 16:03:45 -08:00
{$ENDIF}
If Session.NodeNum = 0 Then CalculateNodeNumber;
If Session.NodeNum = 0 Then Begin
WriteLn ('BUSY');
DisposeClasses;
Halt;
End;
2012-02-13 16:03:45 -08:00
CheckPathsAndDataFiles;
{$IFNDEF UNIX}
2012-06-30 20:59:38 -07:00
Session.LocalMode := Session.CommHandle = -1;
2012-02-13 16:03:45 -08:00
2012-06-30 20:59:38 -07:00
If Not Session.LocalMode Then Begin
TIOSocket(Session.Client).FSocketHandle := Session.CommHandle;
TIOSocket(Session.Client).FTelnetServer := True;
2012-02-13 16:03:45 -08:00
2012-06-30 20:59:38 -07:00
Session.io.LocalScreenDisable;
End;
2012-02-13 16:03:45 -08:00
{$ENDIF}
ExitSave := ExitProc;
ExitProc := @ExitHandle;
If Session.ConfigMode Then Begin
Session.NodeNum := 0;
2013-09-16 13:31:39 -07:00
Console.SetWindowTitle ('Mystic Configuration');
2012-02-13 16:03:45 -08:00
Configuration_MainMenu;
2013-09-16 13:31:39 -07:00
Console.TextAttr := 7;
Console.ClearScreen;
Console.BufFlush;
2012-02-13 16:03:45 -08:00
Halt(0);
End;
Session.FindNextEvent;
2012-02-13 16:03:45 -08:00
If Session.TimeOffset > 0 Then
Session.SetTimeLeft(Session.TimeOffset)
Else
Session.SetTimeLeft(bbsCfg.LoginTime);
2012-02-13 16:03:45 -08:00
2013-09-13 20:08:58 -07:00
(*
2012-02-13 16:03:45 -08:00
{$IFNDEF UNIX}
2012-06-30 20:59:38 -07:00
Screen.TextAttr := 7;
Screen.ClearScreen;
2012-02-13 16:03:45 -08:00
{$ENDIF}
2013-09-13 20:08:58 -07:00
*)
2012-02-13 16:03:45 -08:00
{$IFNDEF UNIX}
2012-06-30 20:59:38 -07:00
UpdateStatusLine(0, '');
2012-02-13 16:03:45 -08:00
{$ENDIF}
Set_Node_Action (Session.GetPrompt(345));
{$IFDEF TESTEDITOR}
TestEditor;
Halt(0);
{$ENDIF}
2013-03-04 07:53:06 -08:00
2013-03-13 20:56:42 -07:00
Session.User.UserLogon1 (Script);
2012-02-13 16:03:45 -08:00
If Session.TimeOffset > 0 Then
Session.TimeSaved := Session.User.ThisUser.TimeLeft;
If (Session.User.ThisUser.Flags AND UserQWKNetwork <> 0) and (bbsCfg.QwkNetMenu <> '') Then
Session.Menu.MenuName := bbsCfg.QwkNetMenu
Else
2012-02-13 16:03:45 -08:00
If Session.User.ThisUser.StartMenu <> '' Then
Session.Menu.MenuName := Session.User.ThisUser.StartMenu
Else
Session.Menu.MenuName := bbsCfg.DefStartMenu;
2012-02-13 16:03:45 -08:00
Repeat
Session.Menu.ExecuteMenu (True, True, False, True);
2012-02-13 16:03:45 -08:00
Until False;
End.