-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRUP.PAS
569 lines (497 loc) · 14.7 KB
/
RUP.PAS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
{
05/13/2022 - Added /L parameter TO list index AND data file records
first param is RGDir
use truncate on file???
InsertIndex should update old rec instead of deleting old and adding new
}
PROGRAM RenegadeUserPacker;
USES
CRT,
DOS,
{WinDOS,}
Strings,
RUPTPU,
Runtime;
CONST
Check = '|10'#251; { Square root symbol, kind of looks like a check mark -- for successful operation }
VAR
RGDir : String; { Paths }
CurDir : String; { ^ }
DatDir : String; { ^ }
Path2SCN : String;
{Path2SCNPChar : Array [0..255] OF Char;}
RenegadeDatIn : GeneralRec;
UsersDatIn : UserRec;
UsersIDXIn : UserIDXRec;
NewUsersDatIn : UserRec;
NewUsersIDXIn : UserIDXRec;
SCNIn,
NewSCNIn : ScanRec;
SCN_FName : String;
TookOut : Array [0..6500] OF Integer;
TookOutCountUser,
TookOutCountScanRec,
TookOutCountScanRecTot,
ScanFilesCount: Integer;
FileErr : Boolean;
OldBackupOne,
OldBackupTwo : File;
Skip : Boolean;
RecCount,
NewRecCount,
C1,
C2 : LongInt;
PROCEDURE Pipe(InStr: String; CRLF: Boolean);
VAR
S: String;
I,
Err: Integer;
Col: Byte;
BEGIN
S := InStr;
I := 1;
REPEAT
IF (S[I] = '|') THEN
BEGIN
Val(Copy(S,I+1,2),Col,Err);
IF (Err = 0) AND (Col IN [0..22]) THEN
IF Col IN [0..15] THEN
TextColor(Col)
ELSE IF Col IN [16..22] THEN
TextBackground(Col - 16);
Inc(I,3);
END
ELSE
BEGIN
Write(S[I]);
Inc(I);
END;
UNTIL (I > Length(S));
IF (CRLF) THEN
WriteLn;
Delay(50); { LeeW: Remove this -- FOR testing }
END;
PROCEDURE Error(InStr: String);
BEGIN
WriteLn;
Pipe('|12[ERROR]',FALSE);
Pipe(InStr,TRUE); { Single line? }
Window(1,1,80,25);
GoToXY(1,23);
Halt(IOResult);
END;
PROCEDURE Intro;
VAR
Loop: Byte;
BEGIN
ClrScr;
Pipe('|07 Renegade BBS User Packer Ä Version 1.0',TRUE);
Pipe('|07 Copyright (c) 2022 The Renegade BBS Development Team',TRUE);
GoToXY(1,3);
Pipe('|08 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ',TRUE);
FOR Loop := 1 TO 18 DO
Pipe('',TRUE);
Pipe('|08 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ',TRUE);
Window(2,4,78,21);
END;
FUNCTION DirExist(InDir: DirStr): Boolean;
VAR
Attr : Word;
TempFile : File;
BEGIN
Assign(TempFile,(InDir+'.'));
GetFAttr(TempFile,Attr);
IF (DOSError <> 0) THEN
DirExist := FALSE
ELSE
DirExist := ((Attr AND Directory) <> 0)
END;
FUNCTION FileExist(InFile: String): Boolean;
VAR
F: File;
BEGIN
Assign(F,InFile);
{$I-}Reset(F);{$I+}
IF IOResult = 0 THEN
FileExist := TRUE
ELSE
FileExist := FALSE;
END;
FUNCTION IntToStr(InInt: LongInt): String;
VAR
S: String;
BEGIN
S := '';
Str(InInt,S);
IntToStr := S;
END;
PROCEDURE GetRGDir;
BEGIN
GetDir(0,CurDir);
IF ParamStr(1) <> '' THEN
RGDir := ParamStr(1);
IF (ParamStr(1) = '') OR (RGDir[2] <> ':') THEN
RGDir := GetEnv('RENEGADE');
IF RGDir = '' THEN
RGDir := GetEnv('RG');
IF RGDir = '' THEN
RGDir := GetEnv('BBS');
IF RGDir = '' THEN
BEGIN
RGDir := FSearch('RENEGADE.DAT',GetEnv('PATH'));
IF RGDir <> '' THEN
RGDir := CurDir;
END;
IF RGDir = '' THEN
BEGIN
RGDir := FSearch('RENEGADE.DAT',CurDir);
IF RGDir <> '' THEN
RGDir := CurDir;
END;
IF (RGDir <> '') AND (RGDir[Length(RGDir)] <> '\') THEN
RGDir := RGDir + '\';
IF (RGDir = '') OR (NOT DirExist(RGDir)) THEN
Error(' þ RENEGADE.DAT not found!');
END;
FUNCTION AllCaps(InString: STRING): STRING;
VAR
Counter: Byte;
BEGIN
FOR Counter := 1 TO Length(InString) DO
IF (InString[Counter] IN ['a'..'z']) THEN
InString[Counter] := Chr(Ord(InString[Counter]) - Ord('a')+Ord('A'));
AllCaps := InString;
END;
FUNCTION SearchUser(UName: Str36; RealNameOK: Boolean): Integer;
VAR
UserIDX: UserIDXRec;
UserIDXFile: FILE OF UserIDXRec; { USER.IDX }
Current: Integer;
Done: Boolean;
BEGIN
SearchUser := 0;
Assign(UserIDXFile,+DatDir+'\USERS.IDX');
Reset(UserIDXFile);
IF (IOResult <> 0) THEN
BEGIN
{SysOpLog}Error('Error opening USERS.IDX.');
Exit;
END;
WHILE (Uname[Length(Uname)] = ' ') DO
Dec(Uname[0]);
UName := AllCaps(UName);
Current := 0;
Done := FALSE;
IF (FileSize(UserIDXFile) > 0) THEN
REPEAT
Seek(UserIDXFile,Current);
Read(UserIDXFile,UserIDX);
IF (Uname < UserIDX.Name) THEN
Current := UserIDX.Left
ELSE IF (Uname > UserIDX.Name) THEN
Current := UserIDX.Right
ELSE
Done := TRUE;
UNTIL (Current = -1) OR (Done);
Close(UserIDXFile);
IF (Done) AND (RealNameOK OR NOT UserIDX.RealName) AND (NOT UserIDX.Deleted) THEN
SearchUser := UserIDX.Number;
{LastError := IOResult;}
END;
FUNCTION Plural(InString: STRING; Number: Integer): STRING;
BEGIN
IF (Number <> 1) THEN
Plural := InString + 's'
ELSE
Plural := InString;
END;
FUNCTION IsUpdate: Boolean; { Was user deleted, or just changed username or realname? }
BEGIN
IsUpdate := FALSE;
ReadFromUsersDat(UsersDatIn,UsersIdxIn.Number);
IF ((UsersIdxIn.RealName) AND (SearchUser(UsersDatIn.Name,FALSE) > 0)) OR
((NOT UsersIdxIn.RealName) AND (SearchUser(UsersDatIn.RealName,TRUE) > 0)) THEN
IsUpdate := TRUE;
END;
BEGIN { User/SCN Packer }
Intro;
GetRGDir;
OpenRenegadeDat(RGDir,FileErr);
IF FileErr THEN
Error(' þ RENEGADE.DAT not found!'); { I think this is redundant because of GetRGDir }
ReadFromRenegadeDat(RenegadeDatIn);
CloseRenegadeDat;
DatDir := AddSlash(RenegadeDatIn.DataPath);
OpenUsersIDX(DatDir,FileErr);
IF FileErr THEN
Error(' þ USERS.IDX not found!');
OpenUsersDat(DatDir,FileErr);
IF FileErr THEN
Error(' þ USERS.DAT not found!');
{ Assign and ReWrite new IDX and DAT files }
OpenNewUsersIDX(DatDir,FileErr);
IF FileErr THEN
Error(' þ USER_IDX.NEW not found!');
OpenNewUsersDat(DatDir,FileErr);
IF FileErr THEN
Error(' þ USER_DAT.NEW not found!');
{ --- }
(* TEST CODE
IF (ParamCount <> 0) AND (AllCaps(ParamStr(1))='/L') THEN
BEGIN
{Writeln (ParamStr(0),' : Got ',ParamCount,' command-line parameters: ');
FOR i:=1 TO ParamCount DO
Writeln (ParamStr (i));}
{pipe(inttostr(filesize(usersidx)),true);
pipe(inttostr(filesize(usersdat)),true);}
Pipe('IDX',TRUE);
FOR RecCount := 0 TO (FileSize(UsersIdx)-1) DO
BEGIN
ReadFromUsersIdx(UsersIdxIn,RecCount);
Pipe('REC: '+IntToStr(RecCount)+' IDX#: '+IntToStr(UsersIdxIn.Number)+' NAME: '+UsersIdxIn.Name,TRUE);
IF usersidxin.deleted THEN
pipe('deleted',TRUE);
IF usersidxin.realname THEN
pipe('realname',TRUE);
END;
Pipe('DAT',TRUE);
FOR RecCount := 0 TO (FileSize(UsersDat)-1) DO
BEGIN
ReadFromUsersDat(UsersDatIn,RecCount);
Pipe('REC: '+IntToStr(RecCount)+' NAME: '+UsersDatIn.Name,TRUE);
END;
EXIT;
END;
IF (ParamCount <> 0) AND (AllCaps(ParamStr(1))='/M') THEN
BEGIN
OpenSCN('c:\renegade\msgs\NEWBB.SCN',FileErr);
FOR RecCount := 0 TO FileSize(SCN)-1 DO
BEGIN
ReadFromSCN(SCNIn,RecCount);
pipe(inttostr(SCNIn.lastread),FALSE);
if SCNIn.newscan then
pipe('true',FALSE)
else
pipe('false',FALSE)
END;
EXIT;
END;
*)
{ -- END of IF parameter -- }
{ -- UPDATE USER IDX/DAT RECORDS -- }
{ Generate TEMPORARY new user index }
FillChar(TookOut,SizeOf(TookOut),' ');
TookOutCountUser := 0;
Pipe('|08þ |07Scanning for deleted users ... ',FALSE);
FOR RecCount := 0 TO (FileSize(UsersIdx)-1) DO
BEGIN
ReadFromUsersIdx(UsersIdxIn,RecCount);
{---}
(*
ReadFromUsersDat(UsersDatIn,usersidxin.number);
if usersidxin.realname then
begin
if SearchUser(usersdatin.name,false) > 0 then
pipe('match',true);
end
else
begin
if SearchUser(usersdatin.realname,true) > 0 then
pipe('match',true);
end;
*)
{---}
IF NOT UsersIdxIn.Deleted THEN
WriteToNewUsersIdx(UsersIdxIn,UsersIdxIn.Number)
ELSE
BEGIN { If deleted }
IF NOT IsUpdate THEN
TookOut[TookOutCountUser] := {RecCount}UsersIdxIn.Number-1 {LeeW: Changed}
ELSE
TookOut[TookOutCountUser] := -1;
Inc(TookOutCountUser);
END;
END;
IF (TookOutCountUser = 0) THEN
BEGIN
CloseUsersIdx;
CloseNewUsersIdx;
CloseUsersDat;
CloseNewUsersDat;
Erase(NewUsersIdx);
Erase(NewUsersDat);
Pipe('None found!',TRUE);
Window(1,1,80,25);
GoToXY(1,23);
Halt;
END
ELSE
Pipe('|07'+IntToStr(TookOutCountUser)+' deleted records found!',TRUE);
{ Generate new user data file }
Pipe('|08þ |07Writing new user data file ... ',FALSE);
NewRecCount := 0;
ReadFromUsersDat(UsersDatIn,0); { Add default new user configuration account }
WriteToNewUsersDat(UsersDatIn,0); { ^ }
FOR RecCount := 0 TO (FileSize(NewUsersIdx)-1) DO
BEGIN
ReadFromNewUsersIdx(NewUsersIdxIn,RecCount);
ReadFromUsersDat(UsersDatIn,NewUsersIdxIn.Number); { Read from old USERS.DAT using new index }
IF NewUsersIdxIn.Number <> 0 THEN
BEGIN
Inc(NewRecCount);
WriteToNewUsersDat(UsersDatIn,NewRecCount);
END;
END;
IF (IOResult <> 0) THEN
Error('Unable to write new user data file!')
ELSE
Pipe(Check,TRUE);
{ Close all records }
CloseUsersIdx;
CloseNewUsersIdx;
CloseUsersDat;
CloseNewUsersDat;
Pipe('|08þ |07Deleting previous backups ... ',true);
IF FileExist(DatDir+'USER_IDX.BAK') THEN
BEGIN
Assign(OldBackupOne,DatDir+'USER_IDX.BAK');
Pipe(' |08- |07USER_IDX.BAK ',false);
{Pipe('Deleting ... ',False);}
Erase(OldBackupOne);
IF IOresult <> 0 THEN
Error('Unable to erase USER_IDX.BAK!')
ELSE
Pipe(Check,FALSE);
END;
Assign(OldBackupTwo,DatDir+'USER_DAT.BAK');
IF FileExist(DatDir+'USER_DAT.BAK') THEN
BEGIN
Assign(OldBackupTwo,DatDir+'USER_DAT.BAK');
Pipe(' |07USER_DAT.BAK ',FALSE);
{Pipe('Deleting ... ',False);}
Erase(OldBackupTwo);
IF IOresult <> 0 THEN
Error('Unable to erase USER_DAT.BAK!')
ELSE
Pipe(Check,TRUE);
END;
Pipe('|08þ |07Backing up user index and data files ... ',true);
Pipe(' |08- |07USER.IDX ',FALSE);
Rename(UsersIdx,DatDir+'USER_IDX.BAK');
IF IOresult <> 0 THEN
Error('Unable to rename USER.IDX to USER_IDX.BAK!')
ELSE
Pipe(Check,FALSE);
Pipe(' |07USER.DAT ',FALSE);
Rename(UsersDat,DatDir+'USER_DAT.BAK');
IF IOresult <> 0 THEN
Error('Unable to rename USER.DAT to USER_DAT.BAK!')
ELSE
Pipe(Check,TRUE);
Pipe('|08þ |07Updating user index and data files ... ',TRUE);
Pipe(' |08- |07USER.IDX ',FALSE);
Rename(NewUsersIdx,DatDir+'USERS.IDX');
IF IOresult <> 0 THEN
Error('Unable to rename USER_IDX.NEW to USERS.IDX!')
ELSE
Pipe(Check,FALSE);
Pipe(' |07USER.DAT ',FALSE);
Rename(NewUsersDat,DatDir+'USERS.DAT');
IF IOresult <> 0 THEN
Error('Unable to rename USER_DAT.NEW to USERS.DAT!')
ELSE
Pipe(Check,TRUE);
Erase(NewUsersIdx); { This new index is not compatible with current RG version;
so we'll just delete it and have RG regenerate it on next boot }
{ -- END OF USER IDX/DAT RECORDS -- }
{ -- UPDATE MSG SCAN RECORDS -- } (* MORE EFFECIENT FIND CODE *)
{ Find the first scan record }
Pipe('|08þ |07Scanning for message scan record files ... ',TRUE);
Path2SCN := AddSlash(RenegadeDatIn.MsgPath)+'*.SCN';
{StrPCopy(Path2SCNPChar,Path2SCN);}
tookoutcountscanrectot := 0;
scanfilescount := 0;
{$I-}FindFirst(Path2SCN{PChar},{fa}AnyFile,DirInfo);{$I+}
WHILE (DOSError = 0) DO
BEGIN
{ Initialize }
Skip := False;
C1 := 0;
TookOutCountScanRec := 0; { LeeW: Added }
Inc(ScanFilesCount);
Pipe(' |08- |07'+DirInfo.Name+' :',TRUE); { Found scan file }
Path2SCN := AddSlash(RenegadeDatIn.MsgPath);
OpenSCN(Path2SCN+DirInfo.Name,FileErr);
IF FileErr THEN
Error('|08þ |07Unable to open message scan file '+DirInfo.Name+'!');
OpenNewSCN(Path2SCN+'SCN.NEW',FileErr);
IF FileErr THEN
Error('|08þ |07Unable to open message scan file SCN.NEW!');
{ Generate new scan record file }
{Pipe('|07þ Startting TO Synch Msgs Scan Records with User Records',TRUE);}
Pipe(' |08- |07GENERATE ',FALSE);
FOR RecCount := 0 TO FileSize(SCN)-1 DO
BEGIN
{ If record was deleted, then skip ... }
(*FOR C2 := 0 TO TookOutCount DO*)
BEGIN
IF RecCount = TookOut[RecCount] THEN
Skip := TRUE
ELSE
Skip := FALSE;
{IF Skip THEN
Break;}
END;
{ ... else write it to new record }
IF NOT Skip THEN
BEGIN
{Pipe('|08þ |07Kept record #'+IntToStr(C1),TRUE);}
ReadFromSCN(SCNIn,RecCount);
WriteToNewSCN(SCNIn,C1);
Inc(C1);
(*Inc(SCNUpdateCount); { LeeW: Added }*)
END
ELSE
Inc(TookOutCountScanRec);
{Pipe('Removed record #'+IntToStr(C1),TRUE);}
END;
Pipe(Check,FALSE); { Successful generation }
IF (FileSize(SCN) > FileSize(NewSCN)) THEN
BEGIN { Records were removed }
{ Delete old record and replace with new record }
Pipe(' |07DELETE ',FALSE); {}
Erase(SCN);
Pipe(Check,FALSE); {}
CloseSCN;
CloseNewSCN;
Assign(NewSCN,Path2SCN+'SCN.NEW');
Pipe(' |07RENAME ',FALSE);
Rename(NewSCN,Path2SCN+DirInfo.Name);
IF (IOResult <> 0) THEN
Error('Unable to rename SCN.NEW to '+DirInfo.Name+'!')
ELSE
Pipe(Check+' |07... ('+IntToStr(TookOutCountScanRec)+' '+Plural('record',TookOutCountScanRec)+' removed)',TRUE);
END
ELSE
BEGIN { No records were removed }
Pipe('',TRUE);
Pipe(' |08- |07No update required! ',TRUE);
{Pipe(Check,TRUE);}
{ Close all records }
CloseSCN;
Erase(NewSCN);
CloseNewSCN;
END;
Inc(tookoutcountscanrectot,tookoutcountscanrec);
{$I-}FindNext(DirInfo);{$I+}
END;
IF (DOSError <> 0) AND (ScanFilesCount = 0) THEN
Error('|08þ |07Unable to locate any .SCN files!');
{ -- END OF MSG SCAN RECORDS -- }
Pipe('|08þ |07Finished!',TRUE);
Pipe(' |08- |07'+IntToStr(TookOutCountUser)+' user records removed|08',TRUE);
Pipe(' |08- |07'+IntToStr(TookOutCountScanRecTot)+' scan records removed (from '
+IntToStr(ScanFilesCount)+' scan files)',FALSE);
Window(1,1,80,25);
GoToXY(1,23);
END.