<> <> <> <> <> <> <<>> DIRECTORY BasicTime USING [GMT, nullGMT], File USING [Error, FP, GetProperties, Handle, PageCount, PropertyStorage, RC, WriteProperties], FSBackdoor USING [ProduceError, Version], FSFileOps, FSReport USING [FileError], GVBasics USING [MakeKey, Password], PrincOpsUtils USING [LongCopy], Rope USING [Length, NewText, ROPE, Text]; FSPropertiesImpl: CEDAR MONITOR IMPORTS File, FSBackdoor, FSReport, GVBasics, PrincOpsUtils, Rope EXPORTS FSFileOps = { PropertiesObject: TYPE = RECORD [ validation: GVBasics.Password, bytes: INT, keep: CARDINAL, created: BasicTime.GMT, version: FSBackdoor.Version, nameBody: TextRep]; TextRep: TYPE = RECORD[PACKED SEQUENCE length: CARDINAL OF CHAR]; Properties: TYPE = LONG POINTER TO PropertiesObject; <> GetProps: PUBLIC PROC [f: File.Handle] RETURNS [bytes: INT, keep: CARDINAL, created: BasicTime.GMT] = { InnerGet: ENTRY PROC = TRUSTED { ENABLE UNWIND => NULL; pPtr: Properties = LOOPHOLE[File.GetProperties[f].prop, Properties]; IF pPtr.validation = validation THEN { bytes _ pPtr.bytes; keep _ pPtr.keep; created _ pPtr.created; } ELSE invalidPP _ TRUE; -- invalid property page }; fileRC: File.RC _ ok; invalidPP: BOOLEAN _ FALSE; InnerGet[ ! File.Error => {fileRC _ why; CONTINUE} ]; IF invalidPP THEN InvalidPropertyPage[]; IF fileRC # ok THEN FSReport.FileError[fileRC]; }; GetNameBodyAndVersion: PUBLIC PROC [f: File.Handle] RETURNS [nameBody: Rope.Text, version: FSBackdoor.Version] = { InnerGetNameBodyAndVersion: ENTRY PROC = TRUSTED { ENABLE UNWIND => NULL; pPtr: Properties = LOOPHOLE[File.GetProperties[f].prop, Properties]; IF pPtr.validation = validation THEN { nameBody _ GetText[@pPtr.nameBody]; version _ pPtr.version; } ELSE invalidPP _ TRUE; -- invalid property page }; fileRC: File.RC _ ok; invalidPP: BOOLEAN _ FALSE; InnerGetNameBodyAndVersion[ ! File.Error => {fileRC _ why; CONTINUE} ]; IF invalidPP THEN InvalidPropertyPage[]; IF fileRC # ok THEN FSReport.FileError[fileRC]; }; InitializePropertyStorage: PUBLIC PROC [fp: File.FP, propStorage: File.PropertyStorage, nPages: File.PageCount] = 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] = { InnerSet: ENTRY PROC = TRUSTED { ENABLE UNWIND => NULL; pPtr: Properties = LOOPHOLE[File.GetProperties[f].prop, Properties]; IF pPtr.validation = validation THEN { 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]; } ELSE invalidPP _ TRUE; -- invalid property page here is a bug }; fileRC: File.RC _ ok; invalidPP: BOOLEAN _ FALSE; InnerSet[ ! File.Error => {fileRC _ why; CONTINUE} ]; IF invalidPP THEN ERROR; IF fileRC # ok THEN FSReport.FileError[fileRC]; }; SetBytesAndCreated: PUBLIC PROC [f: File.Handle, bytes: INT, created: BasicTime.GMT] = { InnerSetBytesAndCreated: ENTRY PROC = TRUSTED { ENABLE UNWIND => NULL; pPtr: Properties = LOOPHOLE[File.GetProperties[f].prop, Properties]; IF pPtr.validation = validation THEN { IF bytes # -1 THEN pPtr.bytes _ bytes; IF created # BasicTime.nullGMT THEN pPtr.created _ created; File.WriteProperties[f]; } ELSE invalidPP _ TRUE; -- invalid property page }; fileRC: File.RC _ ok; invalidPP: BOOLEAN _ FALSE; InnerSetBytesAndCreated[ ! File.Error => {fileRC _ why; CONTINUE} ]; IF invalidPP THEN InvalidPropertyPage[]; IF fileRC # ok THEN FSReport.FileError[fileRC]; }; SetKeep: PUBLIC PROC [f: File.Handle, keep: CARDINAL] = { InnerSetKeep: ENTRY PROC = TRUSTED { ENABLE UNWIND => NULL; pPtr: Properties = LOOPHOLE[File.GetProperties[f].prop, Properties]; IF pPtr.validation = validation THEN { pPtr.keep _ keep; File.WriteProperties[f]; } ELSE invalidPP _ TRUE; -- invalid property page }; fileRC: File.RC _ ok; invalidPP: BOOLEAN _ FALSE; InnerSetKeep[ ! File.Error => {fileRC _ why; CONTINUE} ]; IF invalidPP THEN InvalidPropertyPage[]; IF fileRC # ok THEN FSReport.FileError[fileRC]; }; <> InvalidPropertyPage: PROC = { FSBackdoor.ProduceError[invalidPropertyPage, "Property page of a local file has a bad property page"]; }; GetText: PROC [tR: LONG POINTER TO TextRep] RETURNS [t: Rope.Text] = TRUSTED { chars: NAT _ tR.length; IF chars = 0 THEN t _ NIL ELSE { t _ Rope.NewText[chars]; PrincOpsUtils.LongCopy[ from: tR + SIZE[TextRep[0]], nwords: SIZE[TEXT[chars]] - SIZE[TEXT[0]], to: LOOPHOLE[t, LONG POINTER] + SIZE[TEXT[0]] ]; }; }; PutText: PROC [t: Rope.Text, tR: LONG POINTER TO TextRep] = TRUSTED { chars: NAT _ Rope.Length[t]; bogus: LONG POINTER TO NAT _ LOOPHOLE[tR]; bogus^ _ chars; <> IF chars # 0 THEN PrincOpsUtils.LongCopy[ to: tR + SIZE[TextRep[0]], nwords: SIZE[TEXT[chars]] - SIZE[TEXT[0]], from: LOOPHOLE[t, LONG POINTER] + SIZE[TEXT[0]] ]; }; validation: GVBasics.Password _ ALL[0]; ComputeValidation: PROC = { <> stamp: Rope.ROPE = "August 19, 1983 1:16 pm"; -- DON'T CHANGE THIS!!! -- validation _ GVBasics.MakeKey[stamp]; }; <> ComputeValidation[]; }. <<>> <> <> <> <<>> <<>>