home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
programs
/
disk
/
backup_utils
/
kwikbackup
/
source.lha
/
source
/
BackUp.mod
< prev
next >
Wrap
Text File
|
1989-09-24
|
29KB
|
959 lines
IMPLEMENTATION MODULE BackUp;
FROM SYSTEM IMPORT ADR, ADDRESS, LONGSET;
FROM Arts IMPORT Assert;
FROM Dos IMPORT FileLockPtr, UnLock, Lock, Examine, ExNext,
FileInfoBlockPtr, sharedLock, IoErr, CurrentDir,
noMoreEntries, DateStamp, DatePtr, Read,
FileHandlePtr, Open, Close, oldFile, archive,
SetProtection, CreateDir, newFile, Write,
SetComment, DeleteFile;
FROM Exec IMPORT Byte, CopyMem, GetMsg, ReplyMsg;
FROM Graphics IMPORT SetAPen, SetBPen, SetDrMd, jam1, jam2, RectFill;
FROM Heap IMPORT AllocMem, Deallocate;
FROM Intuition IMPORT GadgetFlags, GadgetFlagSet, IntuiMessagePtr,
IDCMPFlags, IDCMPFlagSet, RefreshGadgets;
FROM Strings IMPORT first, last, Insert, Length, Copy;
FROM TrackDisk IMPORT notSpecified, noSecHdr, badSecPreamble,
badSecId, badHdrSum, badSecSum, tooFewSecs,
badSecHdr, writeProt, diskChanged, seekError,
noMem, badUnitNum, badDriveType, driveInUse,
postReset;
FROM TrackDiskSupport IMPORT OpenTrackDisk, FormatTrack, ReadBlock, Motor,
GetNumTracks, CloseTrackDisk, GetDiskChange,
ChangeState, ReadCycSec;
FROM HDDisplay IMPORT gadgets, ReqResults, Gadgets, RP, HDName, Type,
HDRequest, Window;
(*------ CONTs: ------*)
CONST
TrackSize = 512*22;
Gorks = "Gorks!?!";
EndeID = "BkUpEnde";
(*------ TYPEs: ------*)
TYPE
Res = (ok,continue,cancel);
String = ARRAY[0..255] OF CHAR;
MyFileType = RECORD
gorks: ARRAY[0..7] OF CHAR; (* 0 = 0 *)
byte: LONGCARD; (* 8 = 8 *)
prot: LONGSET; (* 12 = C *)
name: ARRAY[0..107] OF CHAR; (* 16 = 10 *)
comm: ARRAY[0..115] OF CHAR; (* 124 = 7C *)
Size: LONGCARD; (* 240 = F0 *)
path: String; (* 244 = F4 *)
END; (* 500 = 1F4 *)
(* Danach MyFileType.size Bytes data und bis zu 3 pad-Bytes *)
EndeType = RECORD
endeID: ARRAY[0..7] OF CHAR;
byte: LONGCARD;
END;
(* hinter letztem File *)
(* BackUp - Format:
Am Anfang jeder Diskkette :
Byte 0..3 : "BkUp"
4..5 : Identifier der BackUp-Reihe
6 : Disketten Nummer
7 : Version (0)
Der Rest aller Disketten wird als ein großer Block angesehen.
Er enthält für jedes File einen `MyFileType' gefolgt von dem
Fileinhalt und bis zu 3 Pad-Bytes. Hinter dem letzen File ist ein
`EndeID'. *)
(*------ VARs: ------*)
VAR
TrackBuffer: POINTER TO ARRAY[0..TrackSize-1] OF CHAR;
ActTrack: CARDINAL;
TrackBufferCnt: CARDINAL;
DiskChange: LONGCARD;
DiskNum: CARDINAL;
Datum: DatePtr;
ReqStr: ARRAY[0..39] OF CHAR;
bool: BOOLEAN;
MyFileInfo: MyFileType;
MyLock: FileLockPtr;
File: FileHandlePtr;
(*------ Fast Val to String: ------*)
PROCEDURE Make2Digits(x: INTEGER; at: CARDINAL);
(* macht aus x eine 2 - Ziffer Zahl an der Stelle at in ReqStr *)
BEGIN
ReqStr[at ] := CHAR(ORD("0") + x DIV 10);
ReqStr[at+1] := CHAR(ORD("0") + x - (x DIV 10) * 10);
END Make2Digits;
(*------ Type Pathname: ------*)
PROCEDURE TypePath(Path: ARRAY OF CHAR);
BEGIN
SetAPen(RP,0); SetBPen(RP,0); SetDrMd(RP,jam2);
RectFill(RP,100,144,612,151);
SetAPen(RP,1);
IF Length(Path)<64 THEN
Type(100,150,Path);
ELSE
Path[64] := 0C;
Type(100,150,Path);
END;
END TypePath;
PROCEDURE TypeName(Name: ARRAY OF CHAR);
BEGIN
SetAPen(RP,0); SetBPen(RP,0); SetDrMd(RP,jam2);
RectFill(RP,100,164,612,171);
SetAPen(RP,1);
IF Length(Name)<64 THEN
Type(100,170,Name);
ELSE
Name[64] := 0C;
Type(100,150,Name);
END;
END TypeName;
(*------ Error Request: ------*)
PROCEDURE Error(Drive: CARDINAL; err: Byte; Read: BOOLEAN): ReqResults;
VAR
res: ReqResults;
BEGIN
CASE err OF
notSpecified: ReqStr := "???"; |
noSecHdr: ReqStr := "No Sector Header"; |
badSecPreamble:ReqStr := "Bad Sector Preamble"; |
badSecId: ReqStr := "Bad Sector Identifier"; |
badHdrSum: ReqStr := "Header-Checksum Error"; |
badSecSum: ReqStr := "Sector-Checksum Error"; |
tooFewSecs: ReqStr := "Too few Sectors"; |
badSecHdr: ReqStr := "Bad Sector Header"; |
writeProt: ReqStr := "Disk is Write-Protected"; |
diskChanged: ReqStr := "Disk Changed"; |
seekError: ReqStr := "Seek Error"; |
noMem: ReqStr := "Not enough Memory"; |
badUnitNum: ReqStr := "Drive not connected"; |
badDriveType: ReqStr := "Bad Drive-Type"; |
driveInUse: ReqStr := "Drive in Use"; |
postReset: ReqStr := "User Reset"; |
ELSE
ReqStr := "00"; Make2Digits(ORD(err),0);
END;
IF Read THEN
Insert(ReqStr,first,"Read-Error: ");
ELSE
Insert(ReqStr,first,"Write-Error: ");
END;
res := HDRequest(ADR(ReqStr),3,2,TRUE);
DiskChange := GetDiskChange(Drive);
RETURN res;
END Error;
(*----------------------- Create BackUp: --------------------------------*)
PROCEDURE BackUp(Drive: CARDINAL);
VAR
ID1,ID2: CHAR;
NumTracks: LONGCARD;
Count: LONGCARD;
err: BOOLEAN;
(*------ Move to next Track: ------*)
PROCEDURE NextTrack(): Res;
(* Res can be ok or cancel *)
BEGIN
IF ActTrack>=(NumTracks-1) THEN
INC(DiskNum);
IF Motor(Drive,FALSE) THEN END;
ReqStr := "Insert Disk Number 00 !";
Make2Digits(DiskNum,19);
IF HDRequest(ADR(ReqStr),0,1,FALSE)=Cancel THEN RETURN cancel END;
LOOP
WHILE NOT(ChangeState(Drive)) DO
IF HDRequest(ADR("No Disk in Drive !"),0,1,TRUE)=Cancel THEN
RETURN cancel;
END;
END;
IF DiskNum=1 THEN EXIT END;
IF ReadBlock(Drive,0,TrackBuffer,1,GetDiskChange(Drive))#0 THEN EXIT END;
IF (TrackBuffer^[0]="B") AND (TrackBuffer^[1]="k") AND
(TrackBuffer^[2]="U") AND (TrackBuffer^[3]="p") AND
(TrackBuffer^[4]=ID1) AND (TrackBuffer^[5]=ID2) AND
(TrackBuffer^[6]<CHAR(DiskNum)) THEN
IF Motor(Drive,FALSE) THEN END;
ReqStr := "This is Disk # 00! Insert # 00!";
Make2Digits(ORD(TrackBuffer^[6]),15);
Make2Digits(DiskNum,28);
CASE HDRequest(ADR(ReqStr),3,2,TRUE) OF
Continue: EXIT; |
Cancel: RETURN cancel;
ELSE
END;
ELSE
EXIT;
END;
END;
ActTrack := 0;
TrackBuffer^ := "BkUp"; (* Disk ID *)
TrackBuffer^[4] := ID1; TrackBuffer^[5] := ID2; (* Backup ID *)
TrackBuffer^[6] := CHAR(DiskNum); (* Disk # *)
TrackBuffer^[7] := 0C; (* BackUp Version *)
TrackBufferCnt := 8; (* 8 Bytes in Buffer *)
ReqStr := "00"; Make2Digits(DiskNum,0);
Type(560,45,ReqStr);
DiskChange := GetDiskChange(Drive);
ELSE
INC(ActTrack);
END;
ReqStr := "00"; Make2Digits(ActTrack,0);
Type(560,61,ReqStr);
RETURN ok;
END NextTrack;
(*------ Write to TrackDisk: ------*)
PROCEDURE WriteTrack(Buffer: ADDRESS; Size: LONGCARD): Res;
VAR
err: Byte;
BEGIN
WHILE Size>=(TrackSize-TrackBufferCnt) DO
CopyMem(Buffer,ADDRESS(LONGCARD(TrackBuffer)+TrackBufferCnt),
TrackSize-TrackBufferCnt);
INC(Buffer,TrackSize-TrackBufferCnt);
DEC(Size,TrackSize-TrackBufferCnt);
TrackBufferCnt := 0;
LOOP
Type(500,77," writing ");
err := FormatTrack(Drive,ActTrack,TrackBuffer,1,DiskChange);
IF err=0 THEN
Type(500,77,"verifying");
err := ReadCycSec(Drive,ActTrack,0,0,TrackBuffer,22,DiskChange);
IF err=0 THEN EXIT END;
END;
CASE Error(Drive,err,FALSE) OF
Retry:
DiskChange := GetDiskChange(Drive); |
Continue:
IF NextTrack()=cancel THEN RETURN cancel END;
RETURN continue; |
Cancel:
RETURN cancel; |
ELSE
END;
END;
IF NextTrack()=cancel THEN RETURN cancel END;
END;
IF Size#0 THEN
CopyMem(Buffer,ADDRESS(LONGCARD(TrackBuffer)+TrackBufferCnt),Size);
INC(TrackBufferCnt,Size);
END;
RETURN ok;
END WriteTrack;
(*------ Write last Track: ------*)
PROCEDURE WriteLast(): Res;
VAR err: Byte;
Ende: EndeType;
BEGIN
LOOP
Ende.endeID := EndeID;
Ende.byte := TrackBufferCnt + 11264 * LONGCARD(ActTrack);
IF WriteTrack(ADR(Ende),SIZE(Ende))=cancel THEN RETURN cancel END;
IF (TrackBufferCnt#0) OR (ActTrack#0) THEN
err := FormatTrack(Drive,ActTrack,TrackBuffer,1,DiskChange);
IF err=0 THEN EXIT END;
CASE Error(Drive,err,FALSE) OF
Continue: RETURN continue; |
Cancel: RETURN cancel; |
ELSE
END;
ELSE
EXIT;
END;
END;
IF Motor(Drive,FALSE) THEN END;
RETURN ok;
END WriteLast;
(*------ Write File to Tracks: ------*)
PROCEDURE WriteFile(File: FileHandlePtr; Size: LONGCARD): Res;
VAR
err: Byte;
len: LONGINT;
BEGIN
Size := ((Size+3) DIV 4) * 4; (* add Pad bytes *)
WHILE Size>=(TrackSize-TrackBufferCnt) DO
len := Read(File,ADDRESS(LONGCARD(TrackBuffer)+TrackBufferCnt),
TrackSize-TrackBufferCnt);
DEC(Size,TrackSize-TrackBufferCnt);
TrackBufferCnt := 0;
LOOP
Type(500,77," writing ");
err := FormatTrack(Drive,ActTrack,TrackBuffer,1,DiskChange);
IF err=0 THEN
Type(500,77,"verifying");
err := ReadCycSec(Drive,ActTrack,0,0,TrackBuffer,22,DiskChange);
IF err=0 THEN EXIT END;
END;
CASE Error(Drive,err,FALSE) OF
Retry:
DiskChange := GetDiskChange(Drive); |
Continue:
IF NextTrack()=cancel THEN RETURN cancel END;
RETURN continue; |
Cancel:
RETURN cancel; |
ELSE
END;
END;
IF NextTrack()=cancel THEN RETURN cancel END;
END;
IF Size#0 THEN
len := Read(File,ADDRESS(LONGCARD(TrackBuffer)+TrackBufferCnt),Size);
INC(TrackBufferCnt,Size);
END;
RETURN ok;
END WriteFile;
(*------ Rekursiv backup procedure: ------*)
PROCEDURE DoBackUp(lock: FileLockPtr): Res;
VAR
FileInfo: FileInfoBlockPtr;
DosErr: LONGINT;
res: Res;
Lock2,old: FileLockPtr;
l: INTEGER;
c: CHAR;
MyMsgPtr: IntuiMessagePtr;
BEGIN
res := ok;
TypePath(MyFileInfo.path);
LOOP
AllocMem(FileInfo,SIZE(FileInfo^),FALSE);
IF FileInfo#NIL THEN EXIT END;
IF HDRequest(ADR("Out of memory"),3,2,TRUE)#Retry THEN EXIT END;
END;
IF Examine(lock,FileInfo)#0 THEN
IF FileInfo^.dirEntryType>0 THEN
old := CurrentDir(lock);
WITH FileInfo^ DO
WITH MyFileInfo DO
WHILE (ExNext(lock,FileInfo)#0) AND (res#cancel) DO
IF dirEntryType>0 THEN
(*------ Directory: ------*)
LOOP
Lock2 := Lock(ADR(fileName),sharedLock);
IF Lock2#NIL THEN EXIT END;
ReqStr := "Can't Lock ";
Insert(ReqStr,last,fileName);
IF HDRequest(ADR(ReqStr),3,2,TRUE)=Cancel THEN
res:= cancel;
EXIT;
END;
END;
IF Lock2#0 THEN
l := Length(path);
IF l>253 THEN
WHILE HDRequest(ADR("Path tooo looong!!!"),3,2,TRUE)#Cancel DO END;
res := cancel;
ELSE
IF l#0 THEN path[l] := "/"; path[l+1] := 0C END;
Insert(path,last,fileName);
res := DoBackUp(Lock2);
path[l] := 0C;
TypePath(path);
END;
UnLock(Lock2);
END;
ELSE
(*------ File: ------*)
IF NOT(archive IN protection) OR
NOT(selected IN Gadgets[RegardArchivedGadg].flags) THEN
TypeName(fileName);
byte := TrackBufferCnt + 11264*LONGCARD(ActTrack);
prot := protection;
Copy(name,fileName,first,Length(fileName));
Copy(comm,comment ,first,Length(comment));
Size := size;
LOOP
File := Open(ADR(fileName),oldFile);
IF File#NIL THEN EXIT END;
Copy(ReqStr,"Can't Open ",first,11);
Insert(ReqStr,last,fileName);
Insert(ReqStr,last,"!");
CASE HDRequest(ADR(ReqStr),3,2,TRUE) OF
Cancel: res := cancel; EXIT; |
Continue: EXIT; |
ELSE
END;
END;
IF File#NIL THEN
CASE WriteTrack(ADR(MyFileInfo),SIZE(MyFileType)) OF
ok: res := WriteFile(File,size);
Close(File);
IF (res=ok) AND (selected IN Gadgets[SetArchivedGadg].flags) THEN
IF SetProtection(ADR(fileName),protection +
LONGSET{archive})=0 THEN END;
END; |
cancel: Close(File); res := cancel; |
ELSE
Close(File);
END;
END;
END; (* IF archived IN protection AND RegardArchived THEN *)
END; (* IF direntryType>0 THEN ELSE *)
MyMsgPtr := GetMsg(Window^.userPort);
IF MyMsgPtr#NIL THEN
IF MyMsgPtr^.class=IDCMPFlagSet{gadgetDown} THEN
ReplyMsg(MyMsgPtr);
IF HDRequest(ADR("Do you wish to abort BackUp?"),0,1,FALSE)=Cancel THEN
res := ok;
ELSE
res := cancel;
END;
ELSE
ReplyMsg(MyMsgPtr);
END;
END;
END; (* WHILE ExNext()#0 DO *)
END; (* WITH MyFileInfo DO *)
END; (* WITH FileInfo^ DO *)
old := CurrentDir(old);
END; (* IF FileInfo^.dirEntryType>0 THEN *)
END; (* IF Examine()=0 THEN *)
Deallocate(FileInfo);
RETURN res;
END DoBackUp;
(*------ Start: ------*)
BEGIN
(*------ Init: ------*)
MyFileInfo.gorks := Gorks;
LOOP (* this loop is just to be able to jump to the end easily *)
SetAPen(RP,1); SetBPen(RP,0); SetDrMd(RP,jam2);
LOOP
err := OpenTrackDisk(Drive,TRUE)#0;
IF NOT(err) THEN EXIT END;
IF HDRequest(ADR("Can't open TrackDisk"),3,2,TRUE)=Cancel THEN EXIT END;
END;
IF err THEN EXIT END;
NumTracks := GetNumTracks(Drive) DIV 2;
DiskNum := 0; (* start disk #0 *)
ActTrack := NumTracks;
DateStamp(Datum); (* take ticks as ID for this BackUp *)
WITH Datum^ DO
ID1 := CHAR(tick - (tick DIV 256) * 256);
ID2 := CHAR((tick - (tick DIV 65536) * 65536) DIV 256);
END;
LOOP
MyLock := Lock(ADR(HDName),sharedLock);
IF MyLock#NIL THEN EXIT END;
ReqStr := "Can't Lock ";
Insert(ReqStr,last,HDName);
IF HDRequest(ADR(ReqStr),3,2,TRUE)=Cancel THEN EXIT END;
END;
(*------ Start: ------*)
IF MyLock#NIL THEN
IF NextTrack()#cancel THEN (* insert first Disk *)
MyFileInfo.path := "";
IF DoBackUp(MyLock)#cancel THEN (* Back it up *)
IF WriteLast()=cancel THEN END; (* Write last track *)
END;
END;
UnLock(MyLock);
END;
(*------ Done: ------*)
EXIT;
END;
IF NOT(err) THEN
IF Motor(Drive,FALSE) THEN END;
CloseTrackDisk(Drive);
END;
TypeName(" -------- Done --------");
END BackUp;
(*---------------------------- Restore: ---------------------------------*)
PROCEDURE Restore(Drive: CARDINAL);
VAR
DiskID: ARRAY[0..7] OF CHAR;
ID1,ID2: CHAR;
res: Res;
err: BOOLEAN;
NumTracks: LONGCARD;
old: FileLockPtr;
MyMsgPtr: IntuiMessagePtr;
(*------ Move to next Track: ------*)
PROCEDURE NextReadTrack(): Res;
(* Res can be ok or cancel *)
VAR
err: Byte;
BEGIN
Type(500,77," reading ");
MyMsgPtr := GetMsg(Window^.userPort);
IF MyMsgPtr#NIL THEN
IF MyMsgPtr^.class=IDCMPFlagSet{gadgetDown} THEN
ReplyMsg(MyMsgPtr);
IF HDRequest(ADR("Do you wish to abort BackUp?"),0,1,FALSE)=Retry THEN
RETURN cancel;
END;
ELSE
ReplyMsg(MyMsgPtr);
END;
END;
IF ActTrack>=(NumTracks-1) THEN
ActTrack := 0;
INC(DiskNum);
IF Motor(Drive,FALSE) THEN END;
ReqStr := "Insert Disk Number 00 !";
Make2Digits(DiskNum,19);
IF HDRequest(ADR(ReqStr),0,1,FALSE)=Cancel THEN RETURN cancel END;
LOOP
WHILE NOT(ChangeState(Drive)) DO
IF HDRequest(ADR("No Disk in Drive !"),0,1,TRUE)=Cancel THEN
RETURN cancel;
END;
END;
err := ReadBlock(Drive,0,TrackBuffer,22,GetDiskChange(Drive));
IF err#0 THEN
CASE Error(Drive,err,TRUE) OF
Cancel: RETURN cancel; |
Continue: RETURN continue; |
ELSE
END;
ELSIF (TrackBuffer^[0]#"B") OR (TrackBuffer^[1]#"k") OR
(TrackBuffer^[2]#"U") OR (TrackBuffer^[3]#"p") THEN
CASE HDRequest(ADR("That's no Backup-Disk"),3,2,TRUE) OF
Cancel: RETURN cancel; |
Continue: RETURN continue; |
ELSE
END;
ELSIF TrackBuffer^[6]#CHAR(DiskNum) THEN
IF Motor(Drive,FALSE) THEN END;
ReqStr := "This is Disk # 00! Insert # 00!";
Make2Digits(ORD(TrackBuffer^[6]),15);
Make2Digits(DiskNum,28);
CASE HDRequest(ADR(ReqStr),3,2,TRUE) OF
Continue: RETURN continue; |
Cancel: RETURN cancel;
ELSE
END;
ELSIF TrackBuffer^[7]#0C THEN
IF Motor(Drive,FALSE) THEN END;
ReqStr := "Wrong Backup Version!";
CASE HDRequest(ADR(ReqStr),3,2,TRUE) OF
Continue: RETURN continue; |
Cancel: RETURN cancel;
ELSE
END;
ELSIF DiskNum=1 THEN
ID1 := TrackBuffer^[4]; ID2 := TrackBuffer^[5]; EXIT;
ELSIF (TrackBuffer^[4]#ID1) OR (TrackBuffer^[5]#ID2) THEN
IF Motor(Drive,FALSE) THEN END;
ReqStr := "Wrong BackUp-Identifier!";
CASE HDRequest(ADR(ReqStr),3,2,TRUE) OF
Continue: RETURN continue; |
Cancel: RETURN cancel;
ELSE
END;
ELSE
EXIT;
END;
END; (* LOOP *)
ReqStr := "00"; Make2Digits(DiskNum,0);
Type(560,45,ReqStr);
DiskChange := GetDiskChange(Drive);
TrackBufferCnt := 8;
ELSE
INC(ActTrack);
err := ReadBlock(Drive,22*ActTrack,TrackBuffer,22,DiskChange);
IF err#0 THEN
CASE Error(Drive,err,FALSE) OF
Cancel: RETURN cancel; |
Continue: RETURN continue; |
ELSE
END;
END;
TrackBufferCnt := 0;
END;
ReqStr := "00"; Make2Digits(ActTrack,0);
Type(560,61,ReqStr);
RETURN ok;
END NextReadTrack;
(*------ Read Bytes from TrackDisk: ------*)
PROCEDURE ReadTrack(Buffer: ADDRESS; Size: LONGCARD): Res;
BEGIN
WHILE Size>0 DO
IF Size>=TrackSize-TrackBufferCnt THEN
CopyMem(ADDRESS(LONGCARD(TrackBuffer)+TrackBufferCnt),Buffer,
TrackSize-TrackBufferCnt);
DEC(Size,TrackSize-TrackBufferCnt);
INC(Buffer,TrackSize-TrackBufferCnt);
CASE NextReadTrack() OF
cancel: RETURN cancel; |
continue: RETURN continue; |
ELSE
END;
ELSE
CopyMem(ADDRESS(LONGCARD(TrackBuffer)+TrackBufferCnt),Buffer,
Size);
INC(TrackBufferCnt,Size);
Size := 0;
END;
END;
RETURN ok;
END ReadTrack;
(*------ Make Directory: ------*)
PROCEDURE GetDir(VAR name: ARRAY OF CHAR; VAR lock: FileLockPtr): BOOLEAN;
(* Returns TRUE if error occured *)
VAR
lck: FileLockPtr;
len: INTEGER;
c: CHAR;
BEGIN
lock := Lock(ADR(name),sharedLock);
IF lock#NIL THEN
RETURN FALSE;
ELSE
lock := CreateDir(ADR(name));
IF lock#NIL THEN
RETURN FALSE;
ELSE
len := Length(name) - 1;
WHILE (len>0) AND (name[len]#"/") DO DEC(len) END;
IF len=0 THEN RETURN TRUE END;
c := name[len];
name[len] := 0C;
IF GetDir(name,lck) THEN
name[len] := c;
RETURN TRUE; (* Error *)
ELSE
UnLock(lck);
name[len] := c;
lock := Lock(ADR(name),sharedLock);
IF lock#NIL THEN
RETURN FALSE;
ELSE
lock := CreateDir(ADR(name));
RETURN lock=NIL;
END;
END;
END;
END;
END GetDir;
(*------ Read File from TrackDisk: ------*)
PROCEDURE ReadFile(seek: BOOLEAN): Res;
VAR
err: Byte;
adr: LONGCARD;
len: LONGINT;
lock,old: FileLockPtr;
file: FileHandlePtr;
res: Res;
BEGIN
res := ok;
adr := TrackBufferCnt + LONGCARD(ActTrack) * 11264;
IF seek THEN
CASE ReadTrack(ADR(MyFileInfo.prot),SIZE(MyFileInfo)-12) OF
cancel: RETURN cancel; |
continue: RETURN continue; |
ELSE
END;
MyFileInfo.gorks := Gorks;
MyFileInfo.byte := adr;
ELSE
CASE ReadTrack(ADR(MyFileInfo),SIZE(MyFileInfo)) OF
cancel: RETURN cancel; |
continue: RETURN continue; |
ELSE
END;
END;
WITH MyFileInfo DO
IF (gorks[0]="G") AND (gorks[1]="o") AND (gorks[2]="r") AND
(gorks[3]="k") AND (gorks[4]="s") AND (gorks[5]="!") AND
(gorks[6]="?") AND (gorks[7]="!") AND (byte=adr) THEN
TypeName(name);
IF Length(path)=0 THEN
lock := NIL;
ELSE
TypePath(path);
LOOP
IF GetDir(path,lock) THEN
CASE HDRequest(ADR("Can't create Directory!"),3,2,TRUE) OF
Cancel: res := cancel; EXIT; |
Continue: res := continue; EXIT; |
ELSE
END;
ELSE
EXIT;
END;
END;
END;
IF res=ok THEN
IF lock#NIL THEN old := CurrentDir(lock) END;
LOOP
file := Open(ADR(name),newFile);
IF file#NIL THEN EXIT END;
ReqStr := "Can't open ";
Insert(ReqStr,last,name);
CASE HDRequest(ADR(ReqStr),3,2,TRUE) OF
Cancel: res := cancel; EXIT; |
Continue: res := continue; EXIT; |
ELSE
END;
END;
IF file#NIL THEN
WHILE (Size#0) AND (res=ok) DO
IF Size>=TrackSize-TrackBufferCnt THEN
len := Write(file,ADDRESS(LONGCARD(TrackBuffer)+TrackBufferCnt),
TrackSize-TrackBufferCnt);
DEC(Size,TrackSize-TrackBufferCnt);
CASE NextReadTrack() OF
cancel: res := cancel; |
continue: res := continue; |
ELSE
END;
ELSE
len := Write(file,ADDRESS(LONGCARD(TrackBuffer)+TrackBufferCnt),
Size);
INC(TrackBufferCnt,Size);
Size := 0;
END;
END;
TrackBufferCnt := ((TrackBufferCnt + 3) DIV 4) * 4;
IF TrackBufferCnt>TrackSize THEN
CASE NextReadTrack() OF
cancel: res := cancel; |
continue: res := continue; |
ELSE
END;
END;
Close(file);
IF res#ok THEN
IF DeleteFile(ADR(name))=0 THEN END;
ELSE
IF SetProtection(ADR(name),prot)=0 THEN END;
IF SetComment(ADR(name),ADR(comm))=0 THEN END;
END;
END;
IF lock#NIL THEN
old := CurrentDir(old);
UnLock(lock);
END;
RETURN res;
END;
ELSIF (gorks[0]="B") AND (gorks[1]="k") AND
(gorks[2]="U") AND (gorks[3]="p") AND
(gorks[4]="E") AND (gorks[5]="n") AND
(gorks[6]="d") AND (gorks[7]="e") AND
(byte=adr) THEN
RETURN cancel;
ELSE
IF HDRequest(ADR("Wrong data found! Continue?"),3,2,FALSE)=Cancel THEN
RETURN cancel;
ELSE
RETURN continue;
END;
END;
END;
RETURN res;
END ReadFile;
(*------ Seek: ------*)
PROCEDURE Seek(): Res;
VAR ID: RECORD
go: ARRAY[0..7] OF CHAR;
by: LONGCARD;
END;
adr: LONGCARD;
err: Byte;
BEGIN
TypeName(" ------ Searching ------");
LOOP
DiskChange := GetDiskChange(Drive);
err := ReadBlock(Drive,0,TrackBuffer,22,DiskChange);
IF err#0 THEN
CASE Error(Drive,err,TRUE) OF
Cancel: RETURN cancel; |
Continue: EXIT; |
ELSE END;
ELSE
ID1 := TrackBuffer^[4];
ID2 := TrackBuffer^[5];
DiskNum := ORD(TrackBuffer^[6]);
ReqStr := "00"; Make2Digits(DiskNum,0);
Type(560,45,ReqStr);
EXIT;
END;
END;
IF TrackBufferCnt>TrackSize THEN TrackBufferCnt := TrackSize END;
IF ActTrack>NumTracks THEN ActTrack := NumTracks END;
adr := TrackBufferCnt + LONGCARD(ActTrack) * 11264;
LOOP
IF TrackBufferCnt>=TrackSize THEN
LOOP
CASE NextReadTrack() OF
cancel: RETURN cancel; |
ok: EXIT; |
ELSE END;
END;
IF ActTrack=0 THEN
ID1 := TrackBuffer^[4];
ID2 := TrackBuffer^[5];
DiskNum := ORD(TrackBuffer^[6]);
ReqStr := "00"; Make2Digits(DiskNum,0);
Type(560,45,ReqStr);
END;
adr := TrackBufferCnt + LONGCARD(ActTrack) * 11264;
END;
IF (TrackBuffer^[TrackBufferCnt]="G") THEN
IF (TrackBuffer^[TrackBufferCnt+1]="o") AND
(TrackBuffer^[TrackBufferCnt+2]="r") AND
(TrackBuffer^[TrackBufferCnt+3]="k") THEN
CASE ReadTrack(ADR(ID),12) OF
cancel: RETURN cancel; |
ELSE
IF (ID.go[4]="s") AND (ID.go[5]="!") AND
(ID.go[6]="?") AND (ID.go[7]="!") AND
(ID.by = adr) THEN
RETURN ReadFile(TRUE);
END;
END;
END;
END;
INC(TrackBufferCnt,4);
INC(adr,4);
END;
END Seek;
BEGIN
(*------ Init: ------*)
LOOP (* this loop is just to be able to jump to the end easily *)
SetAPen(RP,1); SetBPen(RP,0); SetDrMd(RP,jam2);
LOOP
err := OpenTrackDisk(Drive,TRUE)#0;
IF NOT(err) THEN EXIT END;
IF HDRequest(ADR("Can't open TrackDisk"),3,2,TRUE)=Cancel THEN EXIT END;
END;
IF err THEN EXIT END;
NumTracks := GetNumTracks(Drive) DIV 2;
DiskNum := 0; (* start disk #0 *)
ActTrack := NumTracks;
LOOP
MyLock := Lock(ADR(HDName),sharedLock);
IF MyLock#NIL THEN EXIT END;
ReqStr := "Can't Lock ";
Insert(ReqStr,last,HDName);
IF HDRequest(ADR(ReqStr),3,2,TRUE)=Cancel THEN EXIT END;
END;
(*------ Start: ------*)
IF MyLock#NIL THEN
old := CurrentDir(MyLock);
res := NextReadTrack(); (* insert first Disk *)
IF res=continue THEN res := Seek() END;
IF res=ok THEN
LOOP
CASE ReadFile(FALSE) OF
continue: IF Seek()=cancel THEN EXIT END; |
cancel: EXIT; |
ELSE
END;
END;
END;
old := CurrentDir(old);
UnLock(MyLock);
END;
(*------ Done: ------*)
EXIT;
END;
IF NOT(err) THEN
IF Motor(Drive,FALSE) THEN END;
CloseTrackDisk(Drive);
END;
TypeName(" -------- Done --------");
END Restore;
(*------ Initialization: ------*)
BEGIN
AllocMem(TrackBuffer,SIZE(TrackBuffer^),TRUE);
AllocMem(Datum,SIZE(Datum^),FALSE);
Assert((TrackBuffer#NIL) AND (Datum#NIL),ADR("Not enough memory!!!"));
END BackUp.