home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1990-03-25 | 28.2 KB | 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.
-