FSPropertiesImpl.mesa
Last Edited by: Schroeder, November 15, 1983 1:36 pm
Last Edited by: Levin, September 22, 1983 1:04 pm
DIRECTORY
BasicTime USING [GMT, nullGMT],
File USING [Error, FP, GetProperties, Handle, PropertyStorage, RC, WriteProperties],
FSBackdoor USING [ProduceError, Version],
FSFileOps,
FSReport USING [FileError],
GVBasics USING [MakeKey, Password],
PrincOps USING [ByteBltBlock],
PrincOpsUtils USING [ByteBlt],
Rope USING [Length, NewText, ROPE, Text];
FSPropertiesImpl: CEDAR MONITOR
IMPORTS File, FSBackdoor, FSReport, GVBasics, PrincOpsUtils, Rope
EXPORTS FSFileOps
= BEGIN
PropertiesObject: TYPE = RECORD [
validation: GVBasics.Password,
bytes: INT,
keep: CARDINAL,
created: BasicTime.GMT,
version: FSBackdoor.Version,
nameBody: TextRep];
TextRep: TYPE = RECORD[length: CARDINAL, chars: PACKED ARRAY [0 .. 0) OF CHARACTER];
Properties: TYPE = LONG POINTER TO PropertiesObject;
Exported to FSFileOps
GetProps: PUBLIC PROC [f: File.Handle] RETURNS [bytes: INT, keep: CARDINAL, created: BasicTime.GMT] =
BEGIN
InnerGet: ENTRY PROC = TRUSTED
BEGIN ENABLE UNWIND => NULL;
pPtr: Properties = LOOPHOLE[File.GetProperties[f], Properties];
IF pPtr.validation = validation
THEN BEGIN
bytes ← pPtr.bytes;
keep ← pPtr.keep;
created ← pPtr.created;
END
ELSE invalidPP ← TRUE; -- invalid property page
END;
fileRC: File.RC ← ok;
invalidPP: BOOLEANFALSE;
InnerGet[ ! File.Error => {fileRC ← why; CONTINUE} ];
IF invalidPP THEN InvalidPropertyPage[];
IF fileRC # ok THEN FSReport.FileError[fileRC];
END;
GetNameBodyAndVersion: PUBLIC PROC [f: File.Handle] RETURNS [nameBody: Rope.Text, version: FSBackdoor.Version] =
BEGIN
InnerGetNameBodyAndVersion: ENTRY PROC = TRUSTED
BEGIN ENABLE UNWIND => NULL;
pPtr: Properties = LOOPHOLE[File.GetProperties[f], Properties];
IF pPtr.validation = validation
THEN BEGIN
nameBody ← GetText[@pPtr.nameBody];
version ← pPtr.version;
END
ELSE invalidPP ← TRUE; -- invalid property page
END;
fileRC: File.RC ← ok;
invalidPP: BOOLEANFALSE;
InnerGetNameBodyAndVersion[
! File.Error => {fileRC ← why; CONTINUE} ];
IF invalidPP THEN InvalidPropertyPage[];
IF fileRC # ok THEN FSReport.FileError[fileRC];
END;
InitializePropertyStorage: PUBLIC PROC [fp: File.FP, propStorage: File.PropertyStorage] = TRUSTED
{ LOOPHOLE[propStorage, Properties].validation ← validation };
SetProps: PUBLIC PROC [f: File.Handle, bytes: INT, keep: CARDINAL, created: BasicTime.GMT, nameBody: Rope.Text, version: FSBackdoor.Version] =
BEGIN
InnerSet: ENTRY PROC = TRUSTED
BEGIN ENABLE UNWIND => NULL;
pPtr: Properties = LOOPHOLE[File.GetProperties[f], Properties];
IF pPtr.validation = validation
THEN BEGIN
IF bytes # -1 THEN pPtr.bytes ← bytes;
pPtr.keep ← keep;
IF created # BasicTime.nullGMT THEN pPtr.created ← created;
pPtr.version ← version;
PutText[nameBody, @(pPtr.nameBody)];
File.WriteProperties[f];
END
ELSE invalidPP ← TRUE; -- invalid property page here is a bug
END;
fileRC: File.RC ← ok;
invalidPP: BOOLEANFALSE;
InnerSet[ ! File.Error => {fileRC ← why; CONTINUE} ];
IF invalidPP THEN ERROR;
IF fileRC # ok THEN FSReport.FileError[fileRC];
END;
SetBytesAndCreated: PUBLIC PROC [f: File.Handle, bytes: INT, created: BasicTime.GMT] =
BEGIN
InnerSetBytesAndCreated: ENTRY PROC = TRUSTED
BEGIN ENABLE UNWIND => NULL;
pPtr: Properties = LOOPHOLE[File.GetProperties[f], Properties];
IF pPtr.validation = validation
THEN BEGIN
IF bytes # -1 THEN pPtr.bytes ← bytes;
IF created # BasicTime.nullGMT THEN pPtr.created ← created;
File.WriteProperties[f];
END
ELSE invalidPP ← TRUE; -- invalid property page
END;
fileRC: File.RC ← ok;
invalidPP: BOOLEANFALSE;
InnerSetBytesAndCreated[ ! File.Error => {fileRC ← why; CONTINUE} ];
IF invalidPP THEN InvalidPropertyPage[];
IF fileRC # ok THEN FSReport.FileError[fileRC];
END;
SetKeep: PUBLIC PROC [f: File.Handle, keep: CARDINAL] =
BEGIN
InnerSetKeep: ENTRY PROC = TRUSTED
BEGIN ENABLE UNWIND => NULL;
pPtr: Properties = LOOPHOLE[File.GetProperties[f], Properties];
IF pPtr.validation = validation
THEN BEGIN
pPtr.keep ← keep;
File.WriteProperties[f];
END
ELSE invalidPP ← TRUE; -- invalid property page
END;
fileRC: File.RC ← ok;
invalidPP: BOOLEANFALSE;
InnerSetKeep[ ! File.Error => {fileRC ← why; CONTINUE} ];
IF invalidPP THEN InvalidPropertyPage[];
IF fileRC # ok THEN FSReport.FileError[fileRC];
END;
Internal procedures
InvalidPropertyPage: PROC =
{ FSBackdoor.ProduceError[invalidPropertyPage, "The property page of a file on the local volume has an unrecognizable property page format."] };
GetText: PROC [tR: LONG POINTER TO TextRep] RETURNS [t: Rope.Text] = TRUSTED
BEGIN
IF tR.length = 0
THEN t ← NIL
ELSE BEGIN
t ← Rope.NewText[tR.length];
LOOPHOLE[t, LONG POINTER TO CARDINAL]^ ← tR.length; -- sets t.length
[] ← PrincOpsUtils.ByteBlt[
to: [BASE[DESCRIPTOR[t]], 0, tR.length],
from: [@tR.chars, 0, tR.length]
];
END;
END;
PutText: PROC [t: Rope.Text, tR: LONG POINTER TO TextRep] = TRUSTED
BEGIN
tR.length ← Rope.Length[t];
[] ← PrincOpsUtils.ByteBlt[
to: [@tR.chars, 0, tR.length],
from: [BASE[DESCRIPTOR[t]], 0, tR.length]
];
END;
Validation stuff for leader pages; changing the stamp will require all nucleus volumes to be erased.
validation: GVBasics.Password ← ALL[0];
ComputeValidation: PROC =
BEGIN
stamp: Rope.ROPE = "August 19, 1983 1:16 pm"; -- DON'T CHANGE THIS!!! --
validation ← GVBasics.MakeKey[stamp];
END;
Start code.
ComputeValidation[];
END.