1566 lines
42 KiB
Plaintext
1566 lines
42 KiB
Plaintext
{$M 35500,0,131072}
|
|
PROGRAM RGMAINT;
|
|
|
|
USES
|
|
Crt,
|
|
Dos,
|
|
TimeFunc;
|
|
|
|
{$I RECORDS.PAS}
|
|
|
|
TYPE
|
|
StorageType =
|
|
(
|
|
Disk,
|
|
CD,
|
|
Copied
|
|
);
|
|
|
|
TransferFlagType =
|
|
(IsAddDLBatch,
|
|
IsFileAttach,
|
|
IsUnlisted,
|
|
IsTempArc,
|
|
IsQWK,
|
|
IsNoFilePoints,
|
|
IsNoRatio,
|
|
IsCheckRatio,
|
|
IsCDRom,
|
|
IsPaused,
|
|
IsAutoLogOff,
|
|
IsKeyboardAbort,
|
|
IsTransferOk);
|
|
|
|
TransferFlagSet = SET OF TransferFlagType;
|
|
|
|
BatchDLRecordType = RECORD
|
|
BDLFileName: STRING[52];
|
|
BDLStorage: StorageType;
|
|
BDLUserNum,
|
|
BDLSection,
|
|
BDLPoints,
|
|
BDLUploader: Integer;
|
|
BDLFSize,
|
|
BDLTime,
|
|
BDLOwnerCRC: LongInt;
|
|
BDLFlags: TransferFlagSet;
|
|
END;
|
|
|
|
DirF = FILE OF FileInfoRecordType;
|
|
SF = FILE OF UserIDXRec;
|
|
|
|
CONST
|
|
DYNY: BOOLEAN = FALSE;
|
|
|
|
FUNCTION AllCaps(S: STRING): STRING;
|
|
VAR
|
|
Counter: Byte;
|
|
BEGIN
|
|
FOR Counter := 1 TO Length(S) DO
|
|
IF (S[Counter] IN ['a'..'z']) THEN
|
|
S[Counter] := Chr(Ord(S[Counter]) - Ord('a')+Ord('A'));
|
|
AllCaps := S;
|
|
END;
|
|
|
|
FUNCTION IntToStr(L: LongInt): STRING;
|
|
VAR
|
|
S: STRING[11];
|
|
BEGIN
|
|
Str(L,S);
|
|
IntToStr := s;
|
|
END;
|
|
|
|
FUNCTION SQOutSp(S: STRING): STRING;
|
|
BEGIN
|
|
WHILE (Pos(' ',S) > 0) DO
|
|
Delete(S,Pos(' ',S),1);
|
|
SQOutSp := S;
|
|
END;
|
|
|
|
FUNCTION Exist(fn: AStr): Boolean;
|
|
VAR
|
|
DirInfo: SearchRec;
|
|
BEGIN
|
|
FindFirst(SQOutSp(fn),AnyFile,DirInfo);
|
|
Exist := (DOSError = 0);
|
|
END;
|
|
|
|
FUNCTION SYN(B: BOOLEAN): STRING;
|
|
BEGIN
|
|
IF (B) THEN
|
|
SYN := 'Yes'
|
|
ELSE
|
|
SYN := 'No ';
|
|
END;
|
|
|
|
FUNCTION YN: BOOLEAN;
|
|
VAR
|
|
C: CHAR;
|
|
BEGIN
|
|
Write(SQOutSp(SYN(DYNY)));
|
|
REPEAT
|
|
C := UpCase(Char(ReadKey));
|
|
UNTIL (C IN ['Y','N',^M]);
|
|
IF (DYNY) AND (C <> 'N') THEN
|
|
C := 'Y';
|
|
IF (DYNY) AND (C = 'N') THEN
|
|
Write(#8#8#8'No ')
|
|
ELSE IF (NOT DYNY) AND (C = 'Y') THEN
|
|
Write(#8#8'Yes');
|
|
WriteLn;
|
|
YN := (C = 'Y');
|
|
DYNY := FALSE;
|
|
END;
|
|
|
|
FUNCTION PYNQ(CONST S: AStr): BOOLEAN;
|
|
BEGIN
|
|
Write(S);
|
|
PYNQ := YN;
|
|
END;
|
|
|
|
FUNCTION StrToInt(S: STRING): LongInt;
|
|
VAR
|
|
I: Integer;
|
|
L: LongInt;
|
|
BEGIN
|
|
Val(S,L,I);
|
|
IF (I > 0) THEN
|
|
BEGIN
|
|
S[0] := Chr(I - 1);
|
|
Val(S,L,I)
|
|
END;
|
|
IF (S = '') THEN
|
|
StrToInt := 0
|
|
ELSE
|
|
StrToInt := L;
|
|
END;
|
|
|
|
FUNCTION GetFileSize(FileName: AStr): LongInt;
|
|
VAR
|
|
F: FILE OF Byte;
|
|
FSize: LongInt;
|
|
BEGIN
|
|
FSize := 0;
|
|
IF (Exist(SQOutSp(FileName))) THEN
|
|
BEGIN
|
|
Assign(F,SQOutSp(FileName));
|
|
Reset(F);
|
|
FSize := FileSize(F);
|
|
Close(F);
|
|
END;
|
|
GetFileSize := FSize;
|
|
END;
|
|
|
|
PROCEDURE KillUserVotes(DataPath: STRING; VAR User: UserRecordType);
|
|
VAR
|
|
VotingFile: FILE OF VotingRecordType;
|
|
Topic: VotingRecordType;
|
|
Counter: Integer;
|
|
BEGIN
|
|
IF (Exist(DataPath+'VOTING.DAT')) THEN
|
|
BEGIN
|
|
Assign(VotingFile,DataPath+'VOTING.DAT');
|
|
Reset(VotingFile);
|
|
FOR Counter := 1 TO FileSize(VotingFile) DO
|
|
IF (User.Vote[Counter] > 0) THEN
|
|
BEGIN
|
|
Seek(VotingFile,(Counter - 1));
|
|
Read(VotingFile,Topic);
|
|
IF (Topic.NumVotedQuestion > 0) THEN
|
|
Dec(Topic.NumVotedQuestion);
|
|
IF (Topic.Answers[User.Vote[Counter]].NumVotedAnswer > 0) THEN
|
|
Dec(Topic.Answers[User.Vote[Counter]].NumVotedAnswer);
|
|
Seek(VotingFile,(Counter - 1));
|
|
Write(VotingFile,Topic);
|
|
User.Vote[Counter] := 0;
|
|
END;
|
|
Close(VotingFile);
|
|
END;
|
|
END;
|
|
|
|
PROCEDURE ResetVotes(DataPath: STRING);
|
|
VAR
|
|
VotingFile: FILE OF VotingRecordType;
|
|
Topic: VotingRecordType;
|
|
Counter,
|
|
Counter1: Integer;
|
|
BEGIN
|
|
IF (Exist(DataPath+'VOTING.DAT')) THEN
|
|
BEGIN
|
|
Assign(VotingFile,DataPath+'VOTING.DAT');
|
|
Reset(VotingFile);
|
|
FOR Counter := 1 TO FileSize(VotingFile) DO
|
|
BEGIN
|
|
Seek(VotingFile,(Counter - 1));
|
|
Read(VotingFile,Topic);
|
|
Topic.NumVotedQuestion := 0;;
|
|
FOR Counter1 := 1 TO 25 DO
|
|
Topic.Answers[Counter1].NumVotedAnswer := 0;
|
|
Seek(VotingFile,(Counter - 1));
|
|
Write(VotingFile,Topic);
|
|
END;
|
|
Close(VotingFile);
|
|
END;
|
|
END;
|
|
|
|
PROCEDURE ReScanUserVotes(DataPath: STRING; VAR User: UserRecordType);
|
|
VAR
|
|
VotingFile: FILE OF VotingRecordType;
|
|
Topic: VotingRecordType;
|
|
Counter: Integer;
|
|
BEGIN
|
|
IF (Exist(DataPath+'VOTING.DAT')) THEN
|
|
BEGIN
|
|
Assign(VotingFile,DataPath+'VOTING.DAT');
|
|
Reset(VotingFile);
|
|
FOR Counter := 1 TO FileSize(VotingFile) DO
|
|
IF (User.Vote[Counter] > 0) THEN
|
|
BEGIN
|
|
Seek(VotingFile,(Counter - 1));
|
|
Read(VotingFile,Topic);
|
|
Inc(Topic.NumVotedQuestion);
|
|
Inc(Topic.Answers[User.Vote[Counter]].NumVotedAnswer);
|
|
Seek(VotingFile,(Counter - 1));
|
|
Write(VotingFile,Topic);
|
|
END;
|
|
Close(VotingFile);
|
|
END;
|
|
END;
|
|
|
|
PROCEDURE KillShortMsgs(DataPath: STRING; VAR User: UserRecordType);
|
|
VAR
|
|
ShortMsgFile: FILE OF ShortMessageRecordType;
|
|
ShortMsg: ShortMessageRecordType;
|
|
Counter: Integer;
|
|
BEGIN
|
|
IF (Exist(DataPath+'SHORTMSG.DAT')) THEN
|
|
BEGIN
|
|
Assign(ShortMsgFile,DataPath+'SHORTMSG.DAT');
|
|
Reset(ShortMsgFile);
|
|
FOR Counter := 1 TO FileSize(ShortMsgFile) DO
|
|
BEGIN
|
|
Seek(ShortMsgFile,(Counter - 1));
|
|
Read(ShortMsgFile,ShortMsg);
|
|
IF (ShortMsg.Destin = User.UserID) THEN
|
|
ShortMsg.Destin := -1;
|
|
Seek(ShortMsgFile,(Counter - 1));
|
|
Write(ShortMsgFile,ShortMsg);
|
|
END;
|
|
Close(ShortMsgFile);
|
|
END;
|
|
END;
|
|
|
|
PROCEDURE UpdateShortMsgs(DataPath: STRING; VAR User: UserRecordType; NewUserNumber: Integer);
|
|
VAR
|
|
ShortMsgFile: FILE OF ShortMessageRecordType;
|
|
ShortMsg: ShortMessageRecordType;
|
|
Counter: Integer;
|
|
BEGIN
|
|
IF Exist(DataPath+'SHORTMSG.DAT') THEN
|
|
BEGIN
|
|
Assign(ShortMsgFile,DataPath+'SHORTMSG.DAT');
|
|
Reset(ShortMsgFile);
|
|
FOR Counter := 1 TO FileSize(ShortMsgFile) DO
|
|
BEGIN
|
|
Seek(ShortMsgFile,(Counter - 1));
|
|
Read(ShortMsgFile,ShortMsg);
|
|
IF (ShortMsg.Destin = User.UserID) THEN
|
|
ShortMsg.Destin := NewUserNumber;
|
|
Seek(ShortMsgFile,(Counter - 1));
|
|
Write(ShortMsgFile,ShortMsg);
|
|
END;
|
|
Close(ShortMsgFile);
|
|
END;
|
|
END;
|
|
|
|
PROCEDURE PurgingShortMsgs(DataPath: STRING);
|
|
VAR
|
|
ShortMsgFile: FILE OF ShortMessageRecordType;
|
|
ShortMsgFile1: FILE OF ShortMessageRecordType;
|
|
ShortMsg: ShortMessageRecordType;
|
|
Counter: Integer;
|
|
BEGIN
|
|
IF Exist(DataPath+'SHORTMSG.DAT') THEN
|
|
BEGIN
|
|
Assign(ShortMsgFile,DataPath+'SHORTMSG.DAT');
|
|
Reset(ShortMsgFile);
|
|
Assign(ShortMsgFile1,DataPath+'SHORTMSG.BAK');
|
|
ReWrite(ShortMsgFile1);
|
|
FOR Counter := 1 TO FileSize(ShortMsgFile) DO
|
|
BEGIN
|
|
Seek(ShortMsgFile,(Counter - 1));
|
|
Read(ShortMsgFile,ShortMsg);
|
|
IF (ShortMsg.Destin <> -1) THEN
|
|
BEGIN
|
|
Seek(ShortMsgFile1,FileSize(ShortMsgFile1));
|
|
Write(ShortMsgFile1,ShortMsg);
|
|
END;
|
|
END;
|
|
Close(ShortMsgFile);
|
|
Erase(ShortMsgFile);
|
|
Close(ShortMsgFile1);
|
|
ReName(ShortMsgFile1,DataPath+'SHORTMSG.DAT');
|
|
END;
|
|
END;
|
|
|
|
PROCEDURE KillBatchQueue(DataPath: STRING; VAR User: UserRecordType);
|
|
VAR
|
|
BatchDLFile: FILE OF BatchDlRecordType;
|
|
BatchDL: BatchDlRecordType;
|
|
Counter: Integer;
|
|
BEGIN
|
|
IF Exist(DataPath+'BATCHDL.DAT') THEN
|
|
BEGIN
|
|
Assign(BatchDLFile,DataPath+'BATCHDL.DAT');
|
|
Reset(BatchDLFile);
|
|
FOR Counter := 1 TO FileSize(BatchDLFile) DO
|
|
BEGIN
|
|
Seek(BatchDLFile,(Counter - 1));
|
|
Read(BatchDLFile,BatchDL);
|
|
IF (BatchDL.BDLUserNum = User.UserID) THEN
|
|
BatchDL.BDLUserNum := -1;
|
|
Seek(BatchDLFile,(Counter - 1));
|
|
Write(BatchDLFile,BatchDL);
|
|
END;
|
|
Close(BatchDLFile);
|
|
END;
|
|
END;
|
|
|
|
PROCEDURE UpdateBatchQueue(DataPath: STRING; VAR User: UserRecordType; NewUserNumber: Integer);
|
|
VAR
|
|
BatchDLFile: FILE OF BatchDLRecordType;
|
|
BatchDL: BatchDlRecordType;
|
|
Counter: Integer;
|
|
BEGIN
|
|
IF Exist(DataPath+'BATCHDL.DAT') THEN
|
|
BEGIN
|
|
Assign(BatchDLFile,DataPath+'BATCHDL.DAT');
|
|
Reset(BatchDLFile);
|
|
FOR Counter := 1 TO FileSize(BatchDLFile) DO
|
|
BEGIN
|
|
Seek(BatchDLFile,(Counter - 1));
|
|
Read(BatchDLFile,BatchDL);
|
|
IF (BatchDL.BDLUserNum = User.UserID) THEN
|
|
BatchDL.BDLUserNum := NewUserNumber;
|
|
Seek(BatchDLFile,(Counter - 1));
|
|
Write(BatchDLFile,BatchDL);
|
|
END;
|
|
Close(BatchDLFile);
|
|
END;
|
|
END;
|
|
|
|
PROCEDURE PurgingBatchQueue(DataPath: STRING);
|
|
VAR
|
|
BatchDLFile: FILE OF BatchDLRecordType;
|
|
BatchDLFile1: FILE OF BatchDLRecordType;
|
|
BatchDL: BatchDLRecordType;
|
|
Counter: Integer;
|
|
BEGIN
|
|
IF Exist(DataPath+'BATCHDL.DAT') THEN
|
|
BEGIN
|
|
Assign(BatchDLFile,DataPath+'BATCHDL.DAT');
|
|
Reset(BatchDLFile);
|
|
Assign(BatchDLFile1,DataPath+'BATCHDL.BAK');
|
|
ReWrite(BatchDLFile1);
|
|
FOR Counter := 1 TO FileSize(BatchDLFile) DO
|
|
BEGIN
|
|
Seek(BatchDLFile,(Counter - 1));
|
|
Read(BatchDLFile,BatchDL);
|
|
IF (BatchDL.BDLUserNum <> -1) THEN
|
|
BEGIN
|
|
Seek(BatchDLFile1,FileSize(BatchDLFile1));
|
|
Write(BatchDLFile1,BatchDL);
|
|
END;
|
|
END;
|
|
Close(BatchDLFile);
|
|
Erase(BatchDLFile);
|
|
Close(BatchDLFile1);
|
|
ReName(BatchDLFile1,DataPath+'BATCHDL.DAT');
|
|
END;
|
|
END;
|
|
|
|
PROCEDURE KillUserEMail(DataPath,MsgPath: STRING; VAR User: UserRecordType);
|
|
VAR
|
|
MsgHdrF: FILE OF MHeaderRec;
|
|
MHeader: MHeaderRec;
|
|
MsgNum: Word;
|
|
BEGIN
|
|
IF (Exist(MsgPath+'EMAIL.HDR')) THEN
|
|
BEGIN
|
|
Assign(MsgHdrF,MsgPath+'EMAIL.HDR');
|
|
Reset(MsgHdrF);
|
|
FOR MsgNum := 1 TO FileSize(MsgHdrF) DO
|
|
BEGIN
|
|
Seek(MsgHdrF,(MsgNum - 1));
|
|
Read(MsgHdrF,MHeader);
|
|
IF ((MHeader.MTO.UserNum = User.UserID) OR (MHeader.From.UserNum = User.UserID)) THEN
|
|
Include(MHeader.Status,MDeleted);
|
|
IF (MHeader.MTO.UserNum = User.UserID) THEN
|
|
MHeader.MTO.UserNum := 0;
|
|
IF (MHeader.FROM.UserNum = User.UserID) THEN
|
|
MHeader.FROM.UserNum := 0;
|
|
Seek(MsgHdrF,(MsgNum - 1));
|
|
Write(MsgHdrF,MHeader);
|
|
END;
|
|
Close(MsgHdrF);
|
|
User.Waiting := 0;
|
|
END;
|
|
END;
|
|
|
|
PROCEDURE UpdateUserEMail(MsgPath: STRING; VAR User: UserRecordType; NewUserNum: Integer);
|
|
VAR
|
|
MsgHdrF: FILE OF MHeaderRec;
|
|
MHeader: MHeaderRec;
|
|
MsgNum: Word;
|
|
BEGIN
|
|
IF (Exist(MsgPath+'EMAIL.HDR')) THEN
|
|
BEGIN
|
|
Assign(MsgHdrF,MsgPath+'EMAIL.HDR');
|
|
Reset(MsgHdrF);
|
|
FOR MsgNum := 1 TO FileSize(MsgHdrF) DO
|
|
BEGIN
|
|
Seek(MsgHdrF,(MsgNum - 1));
|
|
Read(MsgHdrF,MHeader);
|
|
IF (MHeader.MTO.UserNum = User.UserID) THEN
|
|
MHeader.MTO.UserNum := NewUserNum;
|
|
IF (MHeader.From.UserNum = User.UserID) THEN
|
|
MHeader.From.UserNum := NewUserNum;
|
|
Seek(MsgHdrF,(MsgNum - 1));
|
|
Write(MsgHdrF,MHeader);
|
|
END;
|
|
Close(MsgHdrF);
|
|
END;
|
|
END;
|
|
|
|
PROCEDURE ReScanUserEMail(MsgPath: STRING; VAR User: UserRecordType; UserNum: Integer);
|
|
VAR
|
|
MsgHdrF: FILE OF MHeaderRec;
|
|
MHeader: MHeaderRec;
|
|
MsgNum: Word;
|
|
BEGIN
|
|
IF (Exist(MsgPath+'EMAIL.HDR')) THEN
|
|
BEGIN
|
|
User.Waiting := 0;
|
|
Assign(MsgHdrF,MsgPath+'EMAIL.HDR');
|
|
Reset(MsgHdrF);
|
|
FOR MsgNum := 1 TO FileSize(MsgHdrF) DO
|
|
BEGIN
|
|
Seek(MsgHdrF,(MsgNum - 1));
|
|
Read(MsgHdrF,MHeader);
|
|
IF (MHeader.MTO.UserNum = UserNum) THEN
|
|
IF (NOT (MDeleted IN MHeader.Status)) THEN
|
|
Inc(User.Waiting);
|
|
END;
|
|
Close(MsgHdrF);
|
|
END;
|
|
END;
|
|
|
|
PROCEDURE UpdateDIRFilesDeletedUsers(DataPath: STRING; User,SysOpUser: UserRecordType);
|
|
VAR
|
|
FileAreaFile: FILE OF FileAreaRecordType;
|
|
DirFile: FILE OF FileInfoRecordType;
|
|
FileArea: FileAreaRecordType;
|
|
VerbF: FILE;
|
|
F: FileInfoRecordType;
|
|
Counter,
|
|
Counter1: Integer;
|
|
BEGIN
|
|
Assign(FileAreaFile,DataPath+'FBASES.DAT');
|
|
Reset(FileAreaFile);
|
|
FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO
|
|
BEGIN
|
|
Seek(FileAreaFile,Counter);
|
|
Read(FileAreaFile,FileArea);
|
|
IF (FADirDLPath IN FileArea.FAFlags) THEN
|
|
Assign(Dirfile,FileArea.Dlpath+FileArea.FileName+'.DIR')
|
|
ELSE
|
|
Assign(Dirfile,Datapath+FileArea.FileName+'.DIR');
|
|
Reset(Dirfile);
|
|
IF (IOResult = 2) THEN
|
|
ReWrite(Dirfile);
|
|
IF (FADirDLPath IN FileArea.FAFlags) THEN
|
|
Assign(VerbF,FileArea.DLPath+FileArea.FileName+'.EXT')
|
|
ELSE
|
|
Assign(VerbF,Datapath+FileArea.FileName+'.EXT');
|
|
Reset(VerbF,1);
|
|
IF (IOResult = 2) THEN
|
|
ReWrite(VerbF,1);
|
|
FOR Counter1 := 0 TO (FileSize(DirFile) - 1) DO
|
|
BEGIN
|
|
Seek(DirFile,Counter1);
|
|
Read(DirFile,F);
|
|
IF (F.OwnerNum = User.UserID) THEN
|
|
BEGIN
|
|
F.OwnerNum := SysOpUser.UserID;
|
|
F.OwnerName := AllCaps(SysOpUser.Name);
|
|
END;
|
|
Seek(DirFile,Counter1);
|
|
Write(DirFile,F);
|
|
END;
|
|
Close(DirFile);
|
|
Close(VerbF);
|
|
END;
|
|
Close(FileAreaFile);
|
|
END;
|
|
|
|
PROCEDURE UpdateDIRFilesExistingUsers(DataPath: STRING; User: UserRecordType; NewUserNum: Integer);
|
|
VAR
|
|
FileAreaFile: FILE OF FileAreaRecordType;
|
|
DirFile: FILE OF FileInfoRecordType;
|
|
VerbF: FILE;
|
|
FileArea: FileAreaRecordType;
|
|
F: FileInfoRecordType;
|
|
Counter,
|
|
Counter1: Integer;
|
|
BEGIN
|
|
Assign(FileAreaFile,DataPath+'FBASES.DAT');
|
|
Reset(FileAreaFile);
|
|
FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO
|
|
BEGIN
|
|
Seek(FileAreaFile,Counter);
|
|
Read(FileAreaFile,FileArea);
|
|
IF (FADirDLPath IN FileArea.FAFlags) THEN
|
|
Assign(Dirfile,FileArea.Dlpath+FileArea.FileName+'.DIR')
|
|
ELSE
|
|
Assign(Dirfile,Datapath+FileArea.FileName+'.DIR');
|
|
Reset(Dirfile);
|
|
IF (IOResult = 2) THEN
|
|
ReWrite(Dirfile);
|
|
IF (FADirDLPath IN FileArea.FAFlags) THEN
|
|
Assign(VerbF,FileArea.Dlpath+FileArea.FileName+'.EXT')
|
|
ELSE
|
|
Assign(VerbF,Datapath+FileArea.FileName+'.EXT');
|
|
Reset(VerbF,1);
|
|
IF (IOResult = 2) THEN
|
|
ReWrite(VerbF,1);
|
|
FOR Counter1 := 0 TO (FileSize(DirFile) - 1) DO
|
|
BEGIN
|
|
Seek(DirFile,Counter1);
|
|
Read(DirFile,F);
|
|
IF (F.OwnerNum = User.UserID) THEN
|
|
F.OwnerNum := NewUserNum;
|
|
Seek(DirFile,Counter1);
|
|
Write(DirFile,F);
|
|
END;
|
|
Close(DirFile);
|
|
Close(VerbF);
|
|
END;
|
|
Close(FileAreaFile);
|
|
END;
|
|
|
|
PROCEDURE UpdateDIRFileSize(DataPath: STRING);
|
|
VAR
|
|
FileAreaFile: FILE OF FileAreaRecordType;
|
|
DirFile: FILE OF FileInfoRecordType;
|
|
FileArea: FileAreaRecordType;
|
|
VerbF: FILE;
|
|
F: FileInfoRecordType;
|
|
Counter,
|
|
Counter1: Integer;
|
|
FSize: Longint;
|
|
BEGIN
|
|
Assign(FileAreaFile,DataPath+'FBASES.DAT');
|
|
Reset(FileAreaFile);
|
|
FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO
|
|
BEGIN
|
|
Seek(FileAreaFile,Counter);
|
|
Read(FileAreaFile,FileArea);
|
|
IF (FADirDLPath IN FileArea.FAFlags) THEN
|
|
Assign(Dirfile,FileArea.Dlpath+FileArea.FileName+'.DIR')
|
|
ELSE
|
|
Assign(Dirfile,Datapath+FileArea.FileName+'.DIR');
|
|
Reset(Dirfile);
|
|
IF (IOResult = 2) THEN
|
|
ReWrite(Dirfile);
|
|
IF (FADirDLPath IN FileArea.FAFlags) THEN
|
|
Assign(VerbF,FileArea.Dlpath+FileArea.FileName+'.EXT')
|
|
ELSE
|
|
Assign(VerbF,Datapath+FileArea.FileName+'.EXT');
|
|
Reset(VerbF,1);
|
|
IF (IOResult = 2) THEN
|
|
ReWrite(VerbF,1);
|
|
FOR Counter1 := 0 TO (FileSize(DirFile) - 1) DO
|
|
BEGIN
|
|
Seek(DirFile,Counter1);
|
|
Read(DirFile,F);
|
|
FSize := GetFileSize(FileArea.DLPath+F.FileName);
|
|
IF (FSize = 0) THEN
|
|
BEGIN
|
|
F.FileSize := 0;
|
|
Include(F.FIFlags,FIIsRequest);
|
|
END
|
|
ELSE
|
|
F.FileSize := FSize;
|
|
Seek(DirFile,Counter1);
|
|
Write(DirFile,F);
|
|
END;
|
|
Close(DirFile);
|
|
Close(VerbF);
|
|
END;
|
|
Close(FileAreaFile);
|
|
END;
|
|
|
|
PROCEDURE UpdateFileSCNFilesExistingUsers(DataPath: STRING);
|
|
VAR
|
|
FileAreaFile: FILE OF FileAreaRecordType;
|
|
UserFile: FILE OF UserRecordType;
|
|
UserFile2: FILE OF UserRecordType;
|
|
ScnFile: FILE OF Boolean;
|
|
ScnFile1: FILE OF Boolean;
|
|
FileArea: FileAreaRecordType;
|
|
User: UserRecordType;
|
|
Path: STRING;
|
|
Counter,
|
|
Counter1,
|
|
NumUsers: Integer;
|
|
NewScanFBase: Boolean;
|
|
BEGIN
|
|
Assign(UserFile,DataPath+'USERS.DAT');
|
|
Reset(UserFile);
|
|
Assign(UserFile2,DataPath+'USERS.BAK');
|
|
Reset(UserFile2);
|
|
Assign(FileAreaFile,DataPath+'FBASES.DAT');
|
|
Reset(FileAreaFile);
|
|
FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO
|
|
BEGIN
|
|
Seek(FileAreaFile,Counter);
|
|
Read(FileAreaFile,FileArea);
|
|
IF (FADirDLPath IN FileArea.FAFlags) THEN
|
|
Path := FileArea.Dlpath+FileArea.FileName
|
|
ELSE
|
|
Path := Datapath+FileArea.FileName;
|
|
Assign(ScnFile,Path+'.SCN');
|
|
Reset(ScnFile);
|
|
IF (IOResult = 2) THEN
|
|
ReWrite(ScnFile);
|
|
Assign(ScnFile1,Path+'.SCB');
|
|
ReWrite(ScnFile1);
|
|
NumUsers := (FileSize(UserFile) - 1);
|
|
IF (NumUsers > FileSize(ScnFile)) THEN
|
|
BEGIN
|
|
Seek(ScnFile,FileSize(ScnFile));
|
|
NewScanFBase := TRUE;
|
|
FOR Counter1 := FileSize(ScnFile) TO (NumUsers - 1) DO
|
|
Write(ScnFile,NewScanFBase);
|
|
END;
|
|
FOR Counter1 := 1 TO (FileSize(UserFile2) - 1) DO
|
|
BEGIN
|
|
Seek(ScnFile1,FileSize(ScnFile1));
|
|
NewScanFBase := TRUE;
|
|
Write(ScnFile1,NewScanFBase);
|
|
END;
|
|
FOR Counter1 := 1 TO (FileSize(UserFile2) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile2,Counter1);
|
|
Read(UserFile2,User);
|
|
Seek(ScnFile,(User.UserID - 1));
|
|
Read(ScnFile,NewScanFBase);
|
|
Seek(ScnFile1,(Counter1 - 1));
|
|
Write(ScnFile1,NewScanFBase);
|
|
END;
|
|
Close(ScnFile);
|
|
Erase(ScnFile);
|
|
Close(ScnFile1);
|
|
ReName(ScnFile1,Path+'.SCN');
|
|
END;
|
|
Close(FileAreaFile);
|
|
Close(UserFile);
|
|
Close(UserFile2);
|
|
END;
|
|
|
|
PROCEDURE UpdateMsgFilesDeletedUsers(DataPath,MsgPath: STRING; User: UserRecordType);
|
|
VAR
|
|
MsgAreaFile: FILE OF MessageAreaRecordType;
|
|
MsgHdrF: FILE OF MHeaderRec;
|
|
MsgTxtF: FILE;
|
|
MsgArea: MessageAreaRecordType;
|
|
MHeader: MHeaderRec;
|
|
Counter: Integer;
|
|
MsgNum: Word;
|
|
BEGIN
|
|
Assign(MsgAreaFile,DataPath+'MBASES.DAT');
|
|
Reset(MsgAreaFile);
|
|
FOR Counter := 0 TO (FileSize(MsgAreaFile) - 1) DO
|
|
BEGIN
|
|
Seek(MsgAreaFile,Counter);
|
|
Read(MsgAreaFile,MsgArea);
|
|
Assign(MsgHdrF,MsgPath+MsgArea.FileName+'.HDR');
|
|
Reset(MsgHdrF);
|
|
IF (IOResult = 2) THEN
|
|
ReWrite(MsgHdrF);
|
|
Assign(MsgTxtF,MsgPath+MsgArea.FileName+'.DAT');
|
|
Reset(MsgTxtF,1);
|
|
IF (IOResult = 2) THEN
|
|
ReWrite(MsgTxtF,1);
|
|
FOR MsgNum := 1 TO FileSize(MsgHdrF) DO
|
|
BEGIN
|
|
Seek(MsgHdrF,(MsgNum - 1));
|
|
Read(MsgHdrF,MHeader);
|
|
IF (MHeader.MTO.UserNum = User.UserID) THEN
|
|
MHeader.MTO.UserNum := 0;
|
|
IF (MHeader.From.UserNum = User.UserID) THEN
|
|
MHeader.From.UserNum := 0;
|
|
Seek(MsgHdrF,(MsgNum - 1));
|
|
Write(MsgHdrF,MHeader);
|
|
END;
|
|
Close(MsgHdrF);
|
|
Close(MsgTxtF);
|
|
END;
|
|
Close(MsgAreaFile);
|
|
END;
|
|
|
|
PROCEDURE UpdateMsgFilesExistingUsers(DataPath,MsgPath: STRING; User: UserRecordType; NewUserNum: Integer);
|
|
VAR
|
|
MsgAreaFile: FILE OF MessageAreaRecordType;
|
|
MsgHdrF: FILE OF MHeaderRec;
|
|
MsgTxtF: FILE;
|
|
MsgArea: MessageAreaRecordType;
|
|
MHeader: MHeaderRec;
|
|
Counter: Integer;
|
|
MsgNum: Word;
|
|
BEGIN
|
|
Assign(MsgAreaFile,DataPath+'MBASES.DAT');
|
|
Reset(MsgAreaFile);
|
|
FOR Counter := 0 TO (FileSize(MsgAreaFile) - 1) DO
|
|
BEGIN
|
|
Seek(MsgAreaFile,Counter);
|
|
Read(MsgAreaFile,MsgArea);
|
|
Assign(MsgHdrF,MsgPath+MsgArea.FileName+'.HDR');
|
|
Reset(MsgHdrF);
|
|
IF (IOResult = 2) THEN
|
|
ReWrite(MsgHdrF);
|
|
Assign(MsgTxtF,MsgPath+MsgArea.FileName+'.DAT');
|
|
Reset(MsgTxtF,1);
|
|
IF (IOResult = 2) THEN
|
|
ReWrite(MsgTxtF,1);
|
|
FOR MsgNum := 1 TO FileSize(MsgHdrF) DO
|
|
BEGIN
|
|
Seek(MsgHdrF,(MsgNum - 1));
|
|
Read(MsgHdrF,MHeader);
|
|
IF (MHeader.MTO.UserNum = User.UserID) THEN
|
|
MHeader.MTO.UserNum := NewUserNum;
|
|
IF (MHeader.From.UserNum = User.UserID) THEN
|
|
MHeader.From.UserNum := NewUserNum;
|
|
Seek(MsgHdrF,(MsgNum - 1));
|
|
Write(MsgHdrF,MHeader);
|
|
END;
|
|
Close(MsgHdrF);
|
|
Close(MsgTxtF);
|
|
END;
|
|
Close(MsgAreaFile);
|
|
END;
|
|
|
|
PROCEDURE UpdateMsgSCNFilesExistingUsers(DataPath,MsgPath: STRING);
|
|
VAR
|
|
MessageFile: FILE OF MessageAreaRecordType;
|
|
UserFile: FILE OF UserRecordType;
|
|
UserFile2: FILE OF UserRecordType;
|
|
MsgScanFile: FILE OF ScanRec;
|
|
MsgScanFile1: FILE OF ScanRec;
|
|
MsgArea: MessageAreaRecordType;
|
|
User: UserRecordType;
|
|
LastReadRecord: ScanRec;
|
|
Path: STRING;
|
|
Counter,
|
|
Counter1,
|
|
NumUsers: Integer;
|
|
BEGIN
|
|
Assign(UserFile,DataPath+'USERS.DAT');
|
|
Reset(UserFile);
|
|
Assign(UserFile2,DataPath+'USERS.BAK');
|
|
Reset(UserFile2);
|
|
Assign(MessageFile,DataPath+'MBASES.DAT');
|
|
Reset(MessageFile);
|
|
FOR Counter := 0 TO (FileSize(MessageFile) - 1) DO
|
|
BEGIN
|
|
Seek(MessageFile,Counter);
|
|
Read(MessageFile,MsgArea);
|
|
Path := MsgPath+MsgArea.FileName;
|
|
Assign(MsgScanFile,Path+'.SCN');
|
|
Reset(MsgScanFile);
|
|
IF (IOResult = 2) THEN
|
|
ReWrite(MsgScanFile);
|
|
Assign(MsgScanFile1,Path+'.SCB');
|
|
ReWrite(MsgScanFile1);
|
|
NumUsers := (FileSize(UserFile) - 1);
|
|
IF (NumUsers > FileSize(MsgScanFile)) THEN
|
|
BEGIN
|
|
WITH LastReadRecord DO
|
|
BEGIN
|
|
LastRead := 0;
|
|
NewScan := TRUE;
|
|
END;
|
|
Seek(MsgScanFile,FileSize(MsgScanFile));
|
|
FOR Counter1 := FileSize(MSGScanFile) TO (NumUsers - 1) DO
|
|
Write(MsgScanFile,LastReadRecord);
|
|
END;
|
|
FOR Counter1 := 1 TO (FileSize(UserFile2) - 1) DO
|
|
BEGIN
|
|
WITH LastReadRecord DO
|
|
BEGIN
|
|
LastRead := 0;
|
|
NewScan := TRUE;
|
|
END;
|
|
Seek(MsgScanFile1,FileSize(MsgScanFile1));
|
|
Write(MsgScanFile1,LastReadRecord);
|
|
END;
|
|
FOR Counter1 := 1 TO (FileSize(UserFile2) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile2,Counter1);
|
|
Read(UserFile2,User);
|
|
Seek(MsgScanFile,(User.UserID - 1));
|
|
Read(MsgScanFile,LastReadRecord);
|
|
Seek(MsgScanFile1,(Counter1 - 1));
|
|
Write(MsgScanFile1,LastReadRecord);
|
|
END;
|
|
Close(MsgScanFile);
|
|
Erase(MsgScanFile);
|
|
Close(MsgScanFile1);
|
|
ReName(MsgScanFile1,Path+'.SCN');
|
|
END;
|
|
Close(MessageFile);
|
|
Close(UserFile);
|
|
Close(UserFile2);
|
|
END;
|
|
|
|
PROCEDURE PackMessageArea(MsgPath,FN: STRING; MaxM: LongInt);
|
|
VAR
|
|
Buffer: ARRAY [1..4096] OF Char;
|
|
MsgHdrF1,
|
|
MsgHdrF2: FILE OF MheaderRec;
|
|
BrdF1,
|
|
BrdF2: FILE;
|
|
MHeader: MheaderRec;
|
|
Numm,
|
|
i,
|
|
IDX,
|
|
TotLoad,
|
|
Buffered: Word;
|
|
NeedPack: Boolean;
|
|
|
|
PROCEDURE ErrMsg;
|
|
BEGIN
|
|
Writeln('Error renaming temp files while packing.');
|
|
END;
|
|
|
|
PROCEDURE Kill(CONST FN: AStr);
|
|
VAR
|
|
F: FILE;
|
|
BEGIN
|
|
IF Exist(FN) THEN
|
|
BEGIN
|
|
Assign(F,FN);
|
|
Erase(F);
|
|
END;
|
|
END;
|
|
|
|
BEGIN
|
|
NeedPack := FALSE;
|
|
FN := AllCaps(FN);
|
|
FN := MsgPath + FN;
|
|
|
|
Assign(BrdF1,FN+'.DAT');
|
|
Reset(BrdF1,1);
|
|
IF (IOResult <> 0) THEN
|
|
Exit;
|
|
|
|
Assign(MsgHdrF1,FN+'.HDR');
|
|
Reset(MsgHdrF1);
|
|
|
|
IF (IOResult <> 0) THEN
|
|
BEGIN
|
|
Close(BrdF1);
|
|
Exit
|
|
END;
|
|
|
|
IF (MaxM <> 0) AND (FileSize(MsgHdrF1) > MaxM) THEN
|
|
BEGIN
|
|
Numm := 0;
|
|
IDX := FileSize(MsgHdrF1);
|
|
WHILE (IDX > 0) DO
|
|
BEGIN
|
|
Seek(MsgHdrF1,(IDX - 1));
|
|
Read(MsgHdrF1,MHeader);
|
|
IF NOT (MDeleted IN MHeader.Status) THEN
|
|
Inc(Numm);
|
|
IF (Numm > MaxM) AND NOT (Permanent IN MHeader.Status) THEN
|
|
BEGIN
|
|
MHeader.Status := [MDeleted];
|
|
Seek(MsgHdrF1,(IDX - 1));
|
|
Write(MsgHdrF1,MHeader);
|
|
END;
|
|
Dec(IDX);
|
|
END;
|
|
END
|
|
ELSE
|
|
BEGIN
|
|
|
|
WHILE (FilePos(MsgHdrF1) < FileSize(MsgHdrF1)) AND (NOT NeedPack) DO
|
|
BEGIN
|
|
Read(MsgHdrF1,MHeader);
|
|
IF (MDeleted IN MHeader.Status) THEN
|
|
NeedPack := TRUE;
|
|
END;
|
|
|
|
IF (NOT NeedPack) THEN
|
|
BEGIN
|
|
Close(MsgHdrF1);
|
|
Close(BrdF1);
|
|
Exit;
|
|
END;
|
|
END;
|
|
|
|
Assign(BrdF2,FN+'.DA1');
|
|
ReWrite(BrdF2,1);
|
|
|
|
Assign(MsgHdrF2,FN+'.HD2');
|
|
ReWrite(MsgHdrF2);
|
|
|
|
Kill(FN+'.HD3');
|
|
Kill(FN+'.DA3');
|
|
|
|
IDX := 1;
|
|
i := 0;
|
|
|
|
WHILE (i <= FileSize(MsgHdrF1) - 1) DO
|
|
BEGIN
|
|
Seek(MsgHdrF1,i);
|
|
Read(MsgHdrF1,MHeader);
|
|
|
|
IF (MHeader.Pointer - 1 + MHeader.TextSize > FileSize(BrdF1)) OR
|
|
(MHeader.Pointer < 1) THEN
|
|
MHeader.Status := [MDeleted];
|
|
|
|
IF NOT (MDeleted IN MHeader.Status) THEN
|
|
BEGIN
|
|
Inc(IDX);
|
|
Seek(BrdF1,MHeader.Pointer - 1);
|
|
MHeader.Pointer := (FileSize(BrdF2) + 1);
|
|
Write(MsgHdrF2,MHeader);
|
|
|
|
TotLoad := 0;
|
|
IF (MHeader.TextSize > 0) THEN
|
|
WHILE (MHeader.TextSize > 0) DO
|
|
BEGIN
|
|
Buffered := MHeader.TextSize;
|
|
IF (Buffered > 4096) THEN
|
|
Buffered := 4096;
|
|
Dec(MHeader.TextSize,Buffered);
|
|
BlockRead(BrdF1,Buffer[1],Buffered);
|
|
BlockWrite(BrdF2,Buffer[1],Buffered);
|
|
END;
|
|
END;
|
|
Inc(i);
|
|
END;
|
|
|
|
Close(BrdF1);
|
|
Close(BrdF2);
|
|
Close(MsgHdrF1);
|
|
Close(MsgHdrF2);
|
|
|
|
ReName(BrdF1,FN+'.DA3'); { ReName .DAT to .DA3 }
|
|
|
|
IF (IOResult <> 0) THEN { Didn't work, abort }
|
|
BEGIN
|
|
ErrMsg;
|
|
Exit;
|
|
END;
|
|
|
|
ReName(BrdF2,FN+'.DAT'); { ReName .DA2 to .DAT }
|
|
|
|
IF (IOResult <> 0) THEN { Didn't work, abort }
|
|
BEGIN
|
|
ErrMsg;
|
|
ReName(BrdF1,FN+'.DAT'); { ReName .DA3 to .DAT }
|
|
Exit;
|
|
END;
|
|
|
|
ReName(MsgHdrF1,FN+'.HD3'); { ReName .HDR to .HD3 }
|
|
|
|
IF (IOResult <> 0) THEN { Didn't work, abort }
|
|
BEGIN
|
|
ErrMsg;
|
|
Erase(BrdF2); { Erase .DA2 }
|
|
ReName(BrdF1,FN+'.DAT'); { ReName .DA3 to .DAT }
|
|
Exit;
|
|
END;
|
|
|
|
ReName(MsgHdrF2,FN+'.HDR'); { ReName .HD2 to .HDR }
|
|
|
|
IF (IOResult <> 0) THEN { Didn't work, abort }
|
|
BEGIN
|
|
ErrMsg;
|
|
Erase(BrdF2); { Erase .DAT (new) }
|
|
Erase(MsgHdrF2); { Erase .HD2 (new) }
|
|
ReName(BrdF1,FN+'.DAT'); { ReName .DA3 to .DAT }
|
|
ReName(MsgHdrF1,FN+'.HDR'); { ReName .HD3 to .HDR }
|
|
Exit;
|
|
END;
|
|
|
|
Erase(MsgHdrF1);
|
|
Erase(BrdF1);
|
|
END;
|
|
|
|
PROCEDURE PackMessageAreas(DataPath,MsgPath: STRING);
|
|
VAR
|
|
MsgAreaFile: FILE OF MessageAreaRecordType;
|
|
MsgArea: MessageAreaRecordType;
|
|
MArea: Integer;
|
|
BEGIN
|
|
PackMessageArea(MsgPath,'EMAIL',0);
|
|
Assign(MsgAreaFile,DataPath+'MBASES.DAT');
|
|
Reset(MsgAreaFile);
|
|
FOR MArea := 0 TO (FileSize(MsgAreaFile) - 1) DO
|
|
BEGIN
|
|
Seek(MsgAreaFile,MArea);
|
|
Read(MsgAreaFile,MsgArea);
|
|
PackMessageArea(MsgPath,MsgArea.FileName,MsgArea.MaxMsgs);
|
|
END;
|
|
Close(MsgAreaFile);
|
|
END;
|
|
|
|
PROCEDURE SortFileArea(VAR DirFile1: DirF; NumFiles: Integer);
|
|
VAR
|
|
F1,
|
|
F2: FileInfoRecordType;
|
|
NumSorted,
|
|
RecNum,
|
|
RecNum1,
|
|
Gap: Integer;
|
|
BEGIN
|
|
Gap := NumFiles;
|
|
REPEAT;
|
|
Gap := (Gap DIV 2);
|
|
IF (Gap = 0) THEN
|
|
Gap := 1;
|
|
NumSorted := 0;
|
|
FOR RecNum := 1 TO (NumFiles - Gap) DO
|
|
BEGIN
|
|
RecNum1 := (RecNum + Gap);
|
|
Seek(DirFile1,(RecNum - 1));
|
|
Read(DirFile1,F1);
|
|
Seek(DirFile1,(RecNum1 - 1));
|
|
Read(DirFile1,F2);
|
|
IF (F1.FileName > F2.FileName) THEN
|
|
BEGIN
|
|
Seek(DirFile1,(RecNum - 1));
|
|
Write(DirFile1,F2);
|
|
Seek(DirFile1,(RecNum1 - 1));
|
|
Write(DirFile1,F1);
|
|
Inc(NumSorted);
|
|
END;
|
|
END;
|
|
UNTIL (NumSorted = 0) AND (Gap = 1);
|
|
END;
|
|
|
|
PROCEDURE SortAllFileAreas(DataPath: STRING);
|
|
VAR
|
|
FileAreaFile: FILE OF FileAreaRecordType;
|
|
DirFile: DirF;
|
|
FileArea: FileAreaRecordType;
|
|
F: FileInfoRecordType;
|
|
NumFiles,
|
|
Counter: Integer;
|
|
BEGIN
|
|
Assign(FileAreaFile,DataPath+'FBASES.DAT');
|
|
Reset(FileAreaFile);
|
|
FOR Counter := 0 TO (FileSize(FileAreaFile) - 1) DO
|
|
BEGIN
|
|
Seek(FileAreaFile,Counter);
|
|
Read(FileAreaFile,FileArea);
|
|
IF (FADirDLPath IN FileArea.FAFlags) THEN
|
|
Assign(Dirfile,FileArea.Dlpath+FileArea.FileName+'.DIR')
|
|
ELSE
|
|
Assign(Dirfile,Datapath+FileArea.FileName+'.DIR');
|
|
Reset(Dirfile);
|
|
IF (IOResult = 2) THEN
|
|
ReWrite(Dirfile);
|
|
NumFiles := FileSize(DirFile);
|
|
IF (NumFiles <> 0) THEN
|
|
SortFileArea(DirFile,NumFiles);
|
|
Close(DirFile);
|
|
END;
|
|
Close(FileAreaFile);
|
|
END;
|
|
|
|
PROCEDURE InsertIndex(VAR UserIndexFile1: SF; Uname: AStr; UserNum: Integer; IsReal,IsDeleted: Boolean);
|
|
VAR
|
|
IndexR: UserIDXRec;
|
|
Current,
|
|
InsertAt: Integer;
|
|
Done: Boolean;
|
|
|
|
PROCEDURE WriteIndex;
|
|
BEGIN
|
|
FillChar(IndexR,SizeOf(IndexR),0);
|
|
WITH IndexR DO
|
|
BEGIN
|
|
Name := Uname;
|
|
Number := UserNum;
|
|
RealName := IsReal;
|
|
Deleted := IsDeleted;
|
|
Left := -1;
|
|
Right := -1;
|
|
Write(UserIndexFile1,IndexR);
|
|
END
|
|
END;
|
|
|
|
BEGIN
|
|
Done := FALSE;
|
|
Uname := Allcaps(Uname);
|
|
Current := 0;
|
|
Reset(UserIndexFile1);
|
|
IF (FileSize(UserIndexFile1) = 0) THEN
|
|
WriteIndex
|
|
ELSE
|
|
REPEAT
|
|
Seek(UserIndexFile1,Current);
|
|
InsertAt := Current;
|
|
Read(UserIndexFile1,IndexR);
|
|
IF (Uname < IndexR.Name) THEN
|
|
Current := IndexR.Left
|
|
ELSE IF (Uname > IndexR.Name) THEN
|
|
Current := IndexR.Right
|
|
ELSE IF (IndexR.Deleted <> IsDeleted) THEN
|
|
BEGIN
|
|
Done := TRUE;
|
|
IndexR.Deleted := IsDeleted;
|
|
IndexR.RealName := IsReal;
|
|
IndexR.Number := UserNum;
|
|
Seek(UserIndexFile1,Current);
|
|
Write(UserIndexFile1,IndexR);
|
|
END
|
|
ELSE
|
|
BEGIN
|
|
IF (UserNum <> IndexR.Number) THEN
|
|
WriteLn('Note: Duplicate user '+UName+' #'+IntToStr(IndexR.Number)+' and '+UName+' #'+IntToStr(UserNum))
|
|
ELSE
|
|
BEGIN
|
|
IndexR.RealName := FALSE;
|
|
Seek(UserIndexFile1,Current); { Make it be his handle IF it's BOTH }
|
|
Write(UserIndexFile1,IndexR);
|
|
END;
|
|
Done := TRUE;
|
|
END;
|
|
UNTIL (Current = -1) OR (Done);
|
|
IF (Current = -1) THEN
|
|
BEGIN
|
|
IF (Uname < IndexR.Name) THEN
|
|
IndexR.Left := FileSize(UserIndexFile1)
|
|
ELSE
|
|
IndexR.Right := FileSize(UserIndexFile1);
|
|
Seek(UserIndexFile1,InsertAt);
|
|
Write(UserIndexFile1,IndexR);
|
|
Seek(UserIndexFile1,FileSize(UserIndexFile1));
|
|
WriteIndex;
|
|
END;
|
|
Close(UserIndexFile1);
|
|
END;
|
|
|
|
PROCEDURE PackUsers;
|
|
VAR
|
|
GeneralFile: FILE OF GeneralRecordType;
|
|
UserFile: FILE OF UserRecordType;
|
|
UserFile1: FILE OF UserRecordType;
|
|
UserFile2: FILE OF UserRecordType;
|
|
UserIndexFile: SF;
|
|
F: FILE;
|
|
General: GeneralRecordType;
|
|
User,
|
|
SysOpUser: UserRecordType;
|
|
DeleteDateStr: STRING;
|
|
TotalUsers,
|
|
Counter: Integer;
|
|
Year: Word;
|
|
PackedDeleteDate: LongInt;
|
|
UsersToDelete,
|
|
DeleteByDate,
|
|
InvalidDate: Boolean;
|
|
BEGIN
|
|
DeleteByDate := FALSE;
|
|
|
|
IF (ParamCount > 0) THEN
|
|
FOR Counter := 1 TO ParamCount DO
|
|
IF (AllCaps(Copy(ParamStr(Counter),1,2)) = AllCaps('-D')) THEN
|
|
BEGIN
|
|
DeleteDateStr := Copy(ParamStr(Counter),3,Length(ParamStr(Counter)));
|
|
InvalidDate := FALSE;
|
|
IF (Length(DeleteDateStr) <> 10) THEN
|
|
InvalidDate := TRUE;
|
|
IF (StrToInt(Copy(DeleteDateStr,1,2)) = 0) THEN
|
|
InvalidDate := TRUE;
|
|
IF (StrToInt(Copy(DeleteDateStr,1,2)) > 12) THEN
|
|
InvalidDate := TRUE;
|
|
IF (StrToInt(Copy(DeleteDateStr,4,2)) = 0) THEN
|
|
InvalidDate := TRUE;
|
|
IF (StrToInt(Copy(DeleteDateStr,1,2)) IN [1,3,5,7,8,10,12]) THEN
|
|
IF (StrToInt(Copy(DeleteDateStr,4,2)) > 31) THEN
|
|
InvalidDate := TRUE;
|
|
IF (StrToInt(Copy(DeleteDateStr,1,2)) IN [4,6,9,11]) THEN
|
|
IF (StrToInt(Copy(DeleteDateStr,4,2)) > 30) THEN
|
|
InvalidDate := TRUE;
|
|
IF (StrToInt(Copy(DeleteDateStr,1,2)) = 2) AND ((StrToInt(Copy(DeleteDateStr,7,4)) MOD 4) <> 0) THEN
|
|
IF (StrToInt(Copy(DeleteDateStr,4,2)) > 28) THEN
|
|
InvalidDate := TRUE;
|
|
IF (StrToInt(Copy(DeleteDateStr,1,2)) = 2) AND ((StrToInt(Copy(DeleteDateStr,7,4)) MOD 4) = 0) THEN
|
|
IF (StrToInt(Copy(DeleteDateStr,4,2)) > 29) THEN
|
|
InvalidDate := TRUE;
|
|
GetYear(Year);
|
|
IF (StrToInt(Copy(DeleteDateStr,7,4)) > Year) THEN
|
|
InvalidDate := TRUE;
|
|
|
|
IF (InvalidDate) THEN
|
|
BEGIN
|
|
WriteLn;
|
|
WriteLn(^G^G^G'Invalid date or format, valid format is "00/00/0000');
|
|
Exit;
|
|
END
|
|
ELSE
|
|
BEGIN
|
|
PackedDeleteDate := Date2PD(DeleteDateStr);
|
|
DeleteByDate := TRUE;
|
|
END;
|
|
END;
|
|
|
|
ClrScr;
|
|
WriteLn('Renegade User Packer Version 2.0');
|
|
Writeln('Copyright 2009 - The Renegade Developement Team');
|
|
WriteLn;
|
|
Writeln('This utility will pack your Renegade BBS Version 1.0');
|
|
WriteLn('USERS.DAT file and update all required data files.');
|
|
WriteLn;
|
|
WriteLn('User''s to be packed:');
|
|
WriteLn(' - All user''s currently marked for deletion');
|
|
IF (DeleteByDate) THEN
|
|
WriteLn(' - All user''s that have not logged on since '+DeleteDateStr);
|
|
WriteLn;
|
|
WriteLn('This process could take awhile depending on the total number');
|
|
WriteLn('of files on your BBS that require update.');
|
|
WriteLn;
|
|
IF PYNQ('Do you wish to continue? ') THEN
|
|
BEGIN
|
|
WriteLn;
|
|
IF (NOT Exist('RENEGADE.DAT')) THEN
|
|
WriteLn('This utility must be executed in the same directory as RENEGADE.DAT!')
|
|
ELSE
|
|
BEGIN
|
|
Write('Reading RENEGADE.DAT ... ');
|
|
Assign(GeneralFile,'RENEGADE.DAT');
|
|
Reset(GeneralFile);
|
|
Read(GeneralFile,General);
|
|
Close(GeneralFile);
|
|
WriteLn('Done!');
|
|
|
|
WriteLn;
|
|
Write('Checking USERS.DAT for user''s to pack ... ');
|
|
Assign(UserFile,General.DataPath+'USERS.DAT');
|
|
Reset(UserFile);
|
|
UsersToDelete := FALSE;
|
|
Counter := 2;
|
|
WHILE (Counter <= (FileSize(UserFile) - 1)) AND (NOT UsersToDelete) DO
|
|
BEGIN
|
|
Seek(UserFile,Counter);
|
|
Read(UserFile,User);
|
|
IF (Deleted IN User.SFlags) OR (DeleteByDate) AND (NOT (FNoDeletion IN User.Flags))
|
|
AND (User.LastOn < PackedDeleteDate) THEN
|
|
UsersToDelete := TRUE;
|
|
Inc(Counter);
|
|
END;
|
|
WriteLn('Done!');
|
|
|
|
IF (NOT UsersToDelete) THEN
|
|
BEGIN
|
|
WriteLn;
|
|
WriteLn(^G^G^G'No deleted user''s found to pack!');
|
|
END
|
|
ELSE
|
|
BEGIN
|
|
|
|
Write('Updating USERS.DAT "UserID" with record number for all user''s ... ');
|
|
FOR Counter := 0 TO (FileSize(UserFile) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile,Counter);
|
|
Read(UserFile,User);
|
|
User.UserID := Counter;
|
|
Seek(UserFile,Counter);
|
|
Write(UserFile,User);
|
|
END;
|
|
WriteLn('Done!');
|
|
|
|
Write('Locating deleted user''s and creating USERS.DEL and USERS.BAK ... ');
|
|
Assign(UserFile1,General.DataPath+'USERS.DEL');
|
|
ReWrite(UserFile1);
|
|
Assign(UserFile2,General.DataPath+'USERS.BAK');
|
|
ReWrite(UserFile2);
|
|
Seek(UserFile,0);
|
|
Read(UserFile,User);
|
|
User.UserID := 0;
|
|
Seek(UserFile2,FileSize(UserFile2));
|
|
Write(UserFile2,User);
|
|
Seek(UserFile,1);
|
|
Read(UserFile,User);
|
|
User.UserID := 1;
|
|
Seek(UserFile2,FileSize(UserFile2));
|
|
Write(UserFile2,User);
|
|
FOR Counter := 2 TO (FileSize(UserFile) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile,Counter);
|
|
Read(UserFile,User);
|
|
IF (Deleted IN User.SFlags) OR (DeleteByDate) AND (NOT (FNoDeletion IN User.Flags))
|
|
AND (User.LastOn < PackedDeleteDate) THEN
|
|
BEGIN
|
|
Seek(UserFile1,FileSize(UserFile1));
|
|
Write(UserFile1,User);
|
|
END
|
|
ELSE
|
|
BEGIN
|
|
Seek(UserFile2,FileSize(UserFile2));
|
|
Write(UserFile2,User);
|
|
END;
|
|
END;
|
|
Close(UserFile);
|
|
Close(UserFile2);
|
|
WriteLn('Done!');
|
|
|
|
Write('Removing voting records for deleted user''s ... ');
|
|
FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile1,Counter);
|
|
Read(UserFile1,User);
|
|
KillUserVotes(General.DataPath,User);
|
|
Seek(UserFile1,Counter);
|
|
Write(UserFile1,User);
|
|
END;
|
|
WriteLn('Done!');
|
|
|
|
Write('Setting SHORTMSG.DAT "Destin" to -1 for deleted user''s ... ');
|
|
FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile1,Counter);
|
|
Read(UserFile1,User);
|
|
KillShortMsgs(General.DataPath,User);
|
|
END;
|
|
WriteLn('Done!');
|
|
|
|
Write('Updating SHORTMSG.DAT "Destin" with new user number ... ');
|
|
Reset(UserFile2);
|
|
FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile2,Counter);
|
|
Read(UserFile2,User);
|
|
UpdateShortMsgs(General.DataPath,User,Counter);
|
|
END;
|
|
Close(UserFile2);
|
|
WriteLn('Done!');
|
|
|
|
(*
|
|
Write('Setting BATCHDL.DAT "BDLUserNum" to -1 for all deleted user''s ... ');
|
|
FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile1,Counter);
|
|
Read(UserFile1,User);
|
|
KillBatchQueue(General.DataPath,User);
|
|
END;
|
|
WriteLn('Done!');
|
|
|
|
Write('Updating BATCHDL.DAT "BDLUserNum" with new user number ... ');
|
|
Reset(UserFile2);
|
|
FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile2,Counter);
|
|
Read(UserFile2,User);
|
|
UpdateBatchQueue(General.DataPath,User,Counter);
|
|
END;
|
|
Close(UserFile2);
|
|
WriteLn('Done!');
|
|
|
|
Write('Setting EMAIL.HDR "MDeleted" for email to/from deleted user''s ... ');
|
|
FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile1,Counter);
|
|
Read(UserFile1,User);
|
|
KillUserEMail(General.DataPath,General.MsgPath,User);
|
|
Seek(UserFile1,Counter);
|
|
Write(UserFile1,User);
|
|
END;
|
|
WriteLn('Done!');
|
|
|
|
Write('Updating EMAIL.HDR "MTO/FROM" with new user number ... ');
|
|
Reset(UserFile2);
|
|
FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile2,Counter);
|
|
Read(UserFile2,User);
|
|
UpdateUserEMail(General.MsgPath,User,Counter);
|
|
Seek(UserFile2,Counter);
|
|
Write(UserFile2,User);
|
|
END;
|
|
Close(UserFile2);
|
|
WriteLn('Done!');
|
|
|
|
Write('Updating *.DIR files with sysop name/number for all deleted user''s ... ');
|
|
Assign(UserFile2,General.DataPath+'USERS.BAK');
|
|
Reset(UserFile2);
|
|
Seek(UserFile2,1);
|
|
Read(UserFile2,SysOpUser);
|
|
Close(UserFile2);
|
|
Reset(UserFile1);
|
|
FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile1,Counter);
|
|
Read(UserFile1,User);
|
|
UpdateDIRFilesDeletedUsers(General.DataPath,User,SysOpUser);
|
|
END;
|
|
WriteLn('Done!');
|
|
|
|
Write('Updating *.DIR files with new user number ... ');
|
|
Reset(UserFile2);
|
|
FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile2,Counter);
|
|
Read(UserFile2,User);
|
|
UpdateDIRFilesExistingUsers(General.DataPath,User,Counter);
|
|
END;
|
|
Close(UserFile2);
|
|
WriteLn('Done!');
|
|
|
|
Write('Setting *.HDR files "MTO/FROM" to 0 for all deleted user''s ... ');
|
|
Reset(UserFile1);
|
|
FOR Counter := 0 TO (FileSize(UserFile1) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile1,Counter);
|
|
Read(UserFile1,User);
|
|
UpdateMsgFilesDeletedUsers(General.DataPath,General.MsgPath,User);
|
|
END;
|
|
WriteLn('Done!');
|
|
|
|
Write('Updating *.HDR files with new user number for existing user''s ... ');
|
|
Reset(UserFile2);
|
|
FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile2,Counter);
|
|
Read(UserFile2,User);
|
|
UpdateMsgFilesExistingUsers(General.DataPath,General.MsgPath,User,Counter);
|
|
END;
|
|
Close(UserFile2);
|
|
WriteLn('Done!');
|
|
|
|
Write('Updating file area scan flags for existing user''s ... ');
|
|
UpdateFileSCNFilesExistingUsers(General.DataPath);
|
|
WriteLn('Done!');
|
|
|
|
Write('Updating message area scan flags for existing user''s ... ');
|
|
UpdateMsgSCNFilesExistingUsers(General.DataPath,General.MsgPath);
|
|
WriteLn('Done!');
|
|
|
|
Write('Re-Scaning email waiting for existing user''s ... ');
|
|
Reset(UserFile2);
|
|
FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile2,Counter);
|
|
Read(UserFile2,User);
|
|
ReScanUserEMail(General.MsgPath,User,Counter);
|
|
Seek(UserFile2,Counter);
|
|
Write(UserFile2,User);
|
|
END;
|
|
WriteLn('Done!');
|
|
|
|
Write('Re-Scaning voting for existing user''s ... ');
|
|
ResetVotes(General.DataPath);
|
|
FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile2,Counter);
|
|
Read(UserFile2,User);
|
|
ReScanUserVotes(General.DataPath,User);
|
|
Seek(UserFile2,Counter);
|
|
Write(UserFile2,User);
|
|
END;
|
|
WriteLn('Done!');
|
|
|
|
Write('Updating UserID with record number for existing user''s ... ');
|
|
FOR Counter := 0 TO (FileSize(UserFile2) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile2,Counter);
|
|
Read(UserFile2,User);
|
|
User.UserID := Counter;
|
|
Seek(UserFile2,Counter);
|
|
Write(UserFile2,User);
|
|
END;
|
|
WriteLn('Done!');
|
|
|
|
Write('Purging SHORTMSG.DAT of deleted records ... ');
|
|
PurgingShortMsgs(General.DataPath);
|
|
WriteLn('Done!');
|
|
|
|
Write('Purging BATCHDL.DAT of deleted records ... ');
|
|
PurgingBatchQueue(General.DataPath);
|
|
WriteLn('Done!');
|
|
|
|
Write('Updating all File Area file size ... ');
|
|
UpdateDIRFileSize(General.DataPath);
|
|
WriteLn('Done!');
|
|
|
|
Write('Sorting all file areas ... ');
|
|
SortAllFileAreas(General.DataPath);
|
|
WriteLn('Done!');
|
|
|
|
Write('Packing all message areas ... ');
|
|
PackMessageAreas(General.DataPath,General.MsgPath);
|
|
WriteLn('Done!');
|
|
|
|
Write('Deleting USERS.DEL ... ');
|
|
Close(UserFile1);
|
|
Erase(UserFile1);
|
|
WriteLn('Done!');
|
|
|
|
Write('Deleting USERS.DAT ... ');
|
|
Erase(UserFile);
|
|
WriteLn('Done!');
|
|
|
|
Write('Re-Naming USERS.BAK to USERS.DAT ... ');
|
|
ReName(UserFile2,General.DataPath+'USERS.DAT');
|
|
WriteLn('Done!');
|
|
|
|
Write('Deleting USERS.IDX ... ');
|
|
Assign(F,General.DataPath+'USERS.IDX');
|
|
Erase(F);
|
|
WriteLn('Done!');
|
|
|
|
Write('Creating and re-indexing USERS.IDX ... ');
|
|
TotalUsers := 0;
|
|
Assign(UserIndexFile,General.DataPath+'USERS.IDX');
|
|
ReWrite(UserIndexFile);
|
|
Reset(UserFile2);
|
|
FOR Counter := 1 TO (FileSize(UserFile2) - 1) DO
|
|
BEGIN
|
|
Seek(UserFile2,Counter);
|
|
Read(UserFile2,User);
|
|
IF NOT (Deleted IN User.SFLags) THEN
|
|
Inc(TotalUsers);
|
|
InsertIndex(UserIndexFile,User.Name,Counter,FALSE,(Deleted IN User.SFLags));
|
|
InsertIndex(UserIndexFile,User.RealName,Counter,TRUE,(Deleted IN User.SFLags));
|
|
END;
|
|
Close(UserFile2);
|
|
WriteLn('Done!');
|
|
|
|
Write('Updating RENEGADE.DAT "NumUsers" ... ');
|
|
Assign(GeneralFile,'RENEGADE.DAT');
|
|
Reset(GeneralFile);
|
|
Read(GeneralFile,General);
|
|
General.NumUsers := TotalUsers;
|
|
Seek(GeneralFile,0);
|
|
Write(GeneralFile,General);
|
|
Close(GeneralFile);
|
|
WriteLn('Done!');
|
|
*)
|
|
|
|
WriteLn;
|
|
WriteLn(^G^G^G'Your USERS.DAT file has been packed and associated files have been updated.');
|
|
END;
|
|
END;
|
|
END;
|
|
END;
|
|
|
|
BEGIN
|
|
PackUsers;
|
|
END. |