<> <> <> DIRECTORY BasicTime USING [GMT, nullGMT], File USING [Reason], FS USING [ErrorGroup, ErrorDesc], FSBackdoor USING [ErrorCode, EventOp, MakeFName, noVersion, Version], FSExtras USING [CreateOp, CreateEvent, RemoteOp, RemoteEvent], FSName USING [BangVersionFile], FSReport USING [], IO USING [PutFR, rope, time], Rope USING [Cat, ROPE]; FSReportImpl: CEDAR MONITOR IMPORTS BasicTime, FSBackdoor, FSName, IO, Rope EXPORTS FS, FSBackdoor, FSExtras, FSReport = BEGIN <> Error: PUBLIC ERROR [error: FS.ErrorDesc] = CODE; <> remoteEventListTail: REF FSExtras.RemoteEvent _ NIL; anotherRemoteEvent: CONDITION; watchingRemote: BOOLEAN _ FALSE; NextRemoteEvent: PUBLIC ENTRY PROC [last: REF READONLY FSExtras.RemoteEvent] RETURNS [REF FSExtras.RemoteEvent] = BEGIN IF last = NIL THEN BEGIN -- first call for this client IF remoteEventListTail = NIL THEN BEGIN -- no events in list yet watchingRemote _ TRUE; UNTIL remoteEventListTail # NIL DO WAIT anotherRemoteEvent ENDLOOP; RETURN [remoteEventListTail]; END ELSE last _ remoteEventListTail; END; UNTIL last.chain # NIL DO WAIT anotherRemoteEvent ENDLOOP; -- wait for next event RETURN [last.chain]; END; creationEventListTail: REF FSExtras.CreateEvent _ NIL; anotherCreationEvent: CONDITION; watchingCreation: BOOLEAN _ FALSE; NextCreationEvent: PUBLIC ENTRY PROC [last: REF READONLY FSExtras.CreateEvent] RETURNS [REF FSExtras.CreateEvent] = BEGIN IF last = NIL THEN BEGIN -- first call for this client IF creationEventListTail = NIL THEN BEGIN -- no events in list yet watchingCreation _ TRUE; UNTIL creationEventListTail # NIL DO WAIT anotherCreationEvent ENDLOOP; RETURN [creationEventListTail]; END ELSE last _ creationEventListTail; END; UNTIL last.chain # NIL DO WAIT anotherCreationEvent ENDLOOP; -- wait for next event RETURN [last.chain]; END; <> EventObject: PUBLIC TYPE = FSExtras.RemoteEvent; NextEvent: PUBLIC PROC [last: REF EventObject] RETURNS [fName: Rope.ROPE, event: FSBackdoor.EventOp, this: REF EventObject] = BEGIN DO nextEvent: REF FSExtras.RemoteEvent = NextRemoteEvent[last]; SELECT nextEvent.op FROM startRetrieving => event _ startRetrieving; endRetrieving => event _ endRetrieving; startStoring => event _ startStoring; endStoring => event _ endStoring; startFlushing => event _ startFlushing; endFlushing => event _ endFlushing; ENDCASE => {last _ nextEvent; LOOP}; fName _ nextEvent.fName; this _ nextEvent; EXIT; ENDLOOP; END; group: PACKED ARRAY FSBackdoor.ErrorCode OF FS.ErrorGroup = [ -- 4-- bug, bug, bug, bug, --13-- environment, environment, environment, environment, environment, environment, environment, environment, environment, environment, environment, environment, environment, -- 2-- lock, lock, -- 8-- client, client, client, client, client, client, client, client, --12-- user, user, user, user, user, user, user, user, user, user, user, user ]; codeAtom: ARRAY FSBackdoor.ErrorCode OF ATOM = [ $ok, $inconsistent, $software, $badFP, $wentOffline, $hardware, $volumeFull, $fragmented, $noMoreVersions, $serverInaccessible, $connectionRejected, $connectionTimedOut, $badCredentials, $accessDenied, $quotaExceeded, $invalidPropertyPage, $badBTree, $lockConflict, $fileBusy, $noCache, $wrongLock, $globalWriteLock, $zeroKeep, $badByteCount, $unknownPage, $invalidOpenFile, $notImplemented, $nonCedarVolume, $unknownServer, $unknownVolume, $unknownFile, $unknownCreatedTime, $illegalName, $patternNotAllowed, $versionSpecified, $globalCreation, $badWorkingDir, $noKeeps, $cantUpdateTiogaFile ]; ProduceError: PUBLIC PROC [code: FSBackdoor.ErrorCode, explanation: Rope.ROPE] = { ERROR Error [ [group[code], codeAtom[code], explanation] ] }; <> ReportRemote: PUBLIC ENTRY PROC [op: FSExtras.RemoteOp, fName: Rope.ROPE] = BEGIN IF watchingRemote THEN BEGIN eventREF: REF FSExtras.RemoteEvent = NEW [ FSExtras.RemoteEvent _ [op, fName, NIL] ]; IF remoteEventListTail # NIL THEN remoteEventListTail.chain _ eventREF; remoteEventListTail _ eventREF; BROADCAST anotherRemoteEvent; END; END; ReportCreation: PUBLIC ENTRY PROC [op: FSExtras.CreateOp, fName: Rope.ROPE] = BEGIN IF watchingCreation THEN BEGIN eventREF: REF FSExtras.CreateEvent = NEW [ FSExtras.CreateEvent _ [op, fName, NIL] ]; IF creationEventListTail # NIL THEN creationEventListTail.chain _ eventREF; creationEventListTail _ eventREF; BROADCAST anotherCreationEvent; END; END; FileError: PUBLIC PROC [reason: File.Reason] = BEGIN code: FSBackdoor.ErrorCode; e: Rope.ROPE; SELECT reason FROM wentOffline => { code _ wentOffline; e _ "Local volume is no longer accessible." }; nonCedarVolume => { code _ nonCedarVolume; e _ "Not a cedar volume." }; inconsistent => { code _ inconsistent; e _ "Local volume's permanent data structures are inconsistent." }; software => { code _ software; e _ "Label check encountered while reading or writing local volume pages." }; hardware => { code _ hardware; e _ "Hard error encountered while reading or writing local volume pages." }; unknownFile => { code _ badFP; e _ "File.FP from directory/cache doesn't correspond to a local volume file." }; unknownPage => { code _ unknownPage; e _ "Tried to read or write a page that is beyond end of the file." }; volumeFull => { code _ volumeFull; e _ "No more free pages on a local volume." }; fragmented => { code _ fragmented; e _ "File required too many non-contiguous areas on a local volume." }; ENDCASE => ERROR; ProduceError[code, e]; END; LockConflict: PUBLIC PROC [prefix, nameBody: Rope.ROPE, version: FSBackdoor.Version] = BEGIN ProduceError[lockConflict, Rope.Cat["FS lock conflict on \"", FSBackdoor.MakeFName[nameBody, version, prefix], "\"."]]; END; UnknownFile: PUBLIC PROC [name: Rope.ROPE, createdTime: BasicTime.GMT] = BEGIN IF createdTime = BasicTime.nullGMT THEN ProduceError[unknownFile, Rope.Cat["Couldn't find a file named \"", name, "\"."]] ELSE BEGIN name _ FSName.BangVersionFile[name, FSBackdoor.noVersion]; ProduceError[unknownCreatedTime, IO.PutFR["Couldn't find a version of \"%g\" created at %t.", IO.rope[name], IO.time[createdTime]]]; END; END; UnknownVolumeLName: PUBLIC PROC [name: Rope.ROPE] = BEGIN ProduceError[unknownVolume, Rope.Cat["There's no system volume, so can't access the LName \"", name, "\"."]]; END; UnknownVolume: PUBLIC PROC [vName: Rope.ROPE] = BEGIN IF vName = NIL THEN ProduceError[unknownVolume, "There is no system volume for this Cedar instance."] ELSE ProduceError[unknownVolume, Rope.Cat["Couldn't find a local volume named \"", vName, "\"."]]; END; NoCache: PUBLIC PROC [name: Rope.ROPE] = BEGIN ProduceError[noCache, Rope.Cat["There's no system volume, so can't cache the GName \"", name, "\"."]]; END; VersionSpecified: PUBLIC PROC [name: Rope.ROPE] = BEGIN ProduceError[versionSpecified, Rope.Cat[ "\"", name, "\" includes a version part, but none is allowed when generating a new FName."]]; END; END.