Unit MIS_Common; {$I M_OPS.PAS} Interface {$I RECORDS.PAS} Var bbsConfig : RecConfig; Function SearchForUser (UN: String; Var Rec: RecUser; Var RecPos: LongInt) : Boolean; Function CheckAccess (User: RecUser; IgnoreGroup: Boolean; Str: String) : Boolean; Function WildcardMatch (Wildcard, FName: String) : Boolean; Function GetSecurityLevel (Level: Byte; SecLevel: RecSecurity) : Boolean; Implementation Uses m_FileIO, m_DateTime, m_Strings; Function SearchForUser (UN: String; Var Rec: RecUser; Var RecPos: LongInt) : Boolean; Var UserFile : TBufFile; Begin Result := False; UN := strUpper(UN); If UN = '' Then Exit; UserFile := TBufFile.Create(4096); If UserFile.Open(bbsConfig.DataPath + 'users.dat', fmOpen, fmRWDN, SizeOf(RecUser)) Then While Not UserFile.EOF Do Begin UserFile.Read(Rec); If Rec.Flags AND UserDeleted <> 0 Then Continue; If (UN = strUpper(Rec.RealName)) or (UN = strUpper(Rec.Handle)) Then Begin RecPos := UserFile.FilePos; Result := True; Break; End; End; UserFile.Free; End; Function CheckAccess (User: RecUser; IgnoreGroup: Boolean; Str: String) : Boolean; Const OpCmds = ['%', '^', '(', ')', '&', '!', '|']; AcsCmds = ['A', 'D', 'E', 'F', 'G', 'H', 'M', 'N', 'O', 'S', 'T', 'U', 'W', 'Z']; Var Key : Char; Data : String; Check : Boolean; Out : String; First : Boolean; Procedure CheckCommand; Var Res : Boolean; Begin Res := False; Case Key of 'A' : Res := True; 'D' : Res := (Ord(Data[1]) - 64) in User.AF2; 'E' : Case Data[1] of '1' : Res := True; '0' : Res := True; End; 'F' : Res := (Ord(Data[1]) - 64) in User.AF1; 'G' : If IgnoreGroup Then Begin First := True; Check := False; Data := ''; Exit; End Else Res := User.LastMGroup = strS2I(Data); 'H' : Res := strS2I(Data) < strS2I(Copy(TimeDos2Str(CurDateDos, False), 1, 2)); 'M' : Res := strS2I(Data) < strS2I(Copy(TimeDos2Str(CurDateDos, False), 4, 2)); 'N' : Res := True; 'O' : Case Data[1] of 'A' : Res := True; 'I' : Res := True; 'K' : Res := True; 'P' : If (User.Calls > 0) And (User.Flags AND UserNoRatio = 0) Then Begin //Temp1 := Round(Security.PCRatio / 100 * 100); //Temp2 := Round(User.ThisUser.Posts / User.ThisUser.Calls * 100); //Res := (Temp2 >= Temp1); Res := True; End Else Res := True; End; 'S' : Res := User.Security >= strS2I(Data); 'T' : Res := True; 'U' : Res := User.PermIdx = strS2I(Data); 'W' : Res := strS2I(Data) = m_DateTime.DayOfWeek; 'Z' : If IgnoreGroup Then Begin Check := False; First := True; Data := ''; Exit; End Else Res := strS2I(Data) = User.LastFGroup; End; If Res Then Out := Out + '^' Else Out := Out + '%'; Check := False; First := True; Data := ''; End; Var A : Byte; Paran1 : Byte; Paran2 : Byte; Ch1 : Char; Ch2 : Char; S1 : String; Begin Data := ''; Out := ''; Check := False; Str := strUpper(Str); First := True; For A := 1 to Length(Str) Do If Str[A] in OpCmds Then Begin If Check Then CheckCommand; Out := Out + Str[A]; End Else If (Str[A] in AcsCmds) and (First or Check) Then Begin If Check Then CheckCommand; Key := Str[A]; If First Then First := False; End Else Begin Data := Data + Str[A]; Check := True; If A = Length(Str) Then CheckCommand; End; Out := '(' + Out + ')'; While Pos('&', Out) <> 0 Do Delete (Out, Pos('&', Out), 1); While Pos('(', Out) <> 0 Do Begin Paran2 := 1; While ((Out[Paran2] <> ')') And (Paran2 <= Length(Out))) Do Begin If (Out[Paran2] = '(') Then Paran1 := Paran2; Inc (Paran2); End; S1 := Copy(Out, Paran1 + 1, (Paran2 - Paran1) - 1); While Pos('!', S1) <> 0 Do Begin A := Pos('!', S1) + 1; If S1[A] = '^' Then S1[A] := '%' Else If S1[A] = '%' Then S1[A] := '^'; Delete (S1, A - 1, 1); End; While Pos('|', S1) <> 0 Do Begin A := Pos('|', S1) - 1; Ch1 := S1[A]; Ch2 := S1[A + 2]; If (Ch1 in ['%', '^']) and (Ch2 in ['%', '^']) Then Begin Delete (S1, A, 3); If (Ch1 = '^') or (Ch2 = '^') Then Insert ('^', S1, A) Else Insert ('%', S1, A) End Else Delete (S1, A + 1, 1); End; While Pos('%%', S1) <> 0 Do Delete (S1, Pos('%%', S1), 1); While Pos('^^', S1) <> 0 Do Delete (S1, Pos('^^', S1), 1); While Pos('%^', S1) <> 0 Do Delete (S1, Pos('%^', S1) + 1, 1); While Pos('^%', S1) <> 0 Do Delete (S1, Pos('^%', S1), 1); Delete (Out, Paran1, (Paran2 - Paran1) + 1); Insert (S1, Out, Paran1); End; Result := Pos('%', Out) = 0; End; Function WildcardMatch (Wildcard, FName: String) : Boolean; Begin Result := False; If FName = '' Then Exit; Case Wildcard[1] of '*' : Begin If FName[1] = '.' Then Exit; If Length(Wildcard) = 1 Then Result := True; If (Length(Wildcard) > 1) and (Wildcard[2] = '.') and (Length(FName) > 0) Then Result := WildCardMatch(Copy(Wildcard, 3, Length(Wildcard) - 2), Copy(FName, Pos('.', FName) + 1, Length(FName)-Pos('.', FName))); End; '?' : If Ord(Wildcard[0]) = 1 Then Result := True Else Result := WildCardMatch(Copy(Wildcard, 2, Length(Wildcard) - 1), Copy(FName, 2, Length(FName) - 1)); Else If FName[1] = Wildcard[1] Then If Length(wildcard) > 1 Then Result := WildCardMatch(Copy(Wildcard, 2, Length(Wildcard) - 1), Copy(FName, 2, Length(FName) - 1)) Else Result := (Length(FName) = 1) And (Length(Wildcard) = 1); End; End; Function GetSecurityLevel (Level: Byte; SecLevel: RecSecurity) : Boolean; Var SecLevelFile : File of RecSecurity; Begin Result := False; Assign (SecLevelFile, bbsConfig.DataPath + 'security.dat'); If Not ioReset (SecLevelFile, SizeOf(SecLevel), fmRWDN) Then Exit; ioSeek (SecLevelFile, Level - 1); ioRead (SecLevelFile, SecLevel); Close (SecLevelFile); Result := True; End; End.