<<>> <> <> <> <> DIRECTORY Basics USING [FFromInt32, HFromInt16], BasicTime USING [GMT, Now, nullGMT], Commander USING [CommandProc, Register], CrRPC USING [BulkDataCheckAbortProc], IO, PFS, PFSNames, Rope, TrickleChargeP9813V411 USING [AnyBodyHomeType, EnumerateForInfoType, ErrorType, FileInfoType, FileNotFoundType, RetrieveType]; TrickleChargeP9813V411Impl: CEDAR PROGRAM IMPORTS Basics, BasicTime, Commander, IO, PFS, Rope EXPORTS TrickleChargeP9813V411 ~ BEGIN <> GMT: TYPE = BasicTime.GMT; ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; <> tempName: PFSNames.PATH ~ PFS.PathFromRope["/tmp/Enumerate.txt"]; <> startTime: BasicTime.GMT ¬ BasicTime.Now[]; anybodyHomeCount: CARD ¬ 0; enumForInfoCount: CARD ¬ 0; fileInfoCount: CARD ¬ 0; retrieveCount: CARD ¬ 0; anybodyHomeTime: GMT ¬ BasicTime.nullGMT; enumForInfoStart: GMT ¬ BasicTime.nullGMT; enumForInfoEnd: GMT ¬ BasicTime.nullGMT; fileInfoStart: GMT ¬ BasicTime.nullGMT; fileInfoEnd: GMT ¬ BasicTime.nullGMT; fileInfoName: ROPE; retrieveStart: GMT ¬ BasicTime.nullGMT; retrieveEnd: GMT ¬ BasicTime.nullGMT; retrieveInProgress: BOOL ¬ FALSE; retrieveName: ROPE; <> AnyBodyHome: PUBLIC TrickleChargeP9813V411.AnyBodyHomeType = { <<[h: CrRPC.Handle] RETURNS [mayBe: TrickleChargeP9813V411.INT16]>> anybodyHomeCount ¬ anybodyHomeCount.SUCC; anybodyHomeTime ¬ BasicTime.Now[]; RETURN[301]; -- 311 from dmachine }; EnumerateForInfo: PUBLIC TrickleChargeP9813V411.EnumerateForInfoType = { <<[h: CrRPC.Handle, pattern: ROPE, info: CrRPC.BulkDataSink]>> <> ENABLE PFS.Error => { IF error.code = $unknownFile THEN ERROR FileNotFound[pattern] ELSE ERROR Error[error.explanation]; }; Enumerate: PFS.InfoProc = { <<[fullFName: PATH, attachedTo: PATH, uniqueID: UniqueID, bytes: INT, mutability: Mutability, fileType: PFS.FileType] RETURNS [continue: BOOL]>> <> <> <> <> <> <<];>> fullNameRope: ROPE ~ PFS.RopeFromPath[fullFName]; length: INT16 ~ Rope.Length[fullNameRope]; createdInt: INT ~ LOOPHOLE[uniqueID.egmt.gmt]; IO.PutHWord[self: s, hword: Basics.HFromInt16[length]]; IO.PutFWord[self: s, fword: Basics.FFromInt32[createdInt]]; IO.PutFWord[self: s, fword: Basics.FFromInt32[bytes]]; IO.PutRope[self: s, r: fullNameRope]; RETURN[TRUE]; }; Abort: CrRPC.BulkDataCheckAbortProc = { <<[h: CrRPC.Handle] RETURNS [abort: BOOL]>> IF abortProcess THEN RETURN [TRUE] ELSE RETURN[FALSE]; }; abortProcess: BOOL ¬ FALSE; s: STREAM ¬ PFS.StreamOpen[fileName: tempName, accessOptions: create]; enumForInfoCount ¬ enumForInfoCount.SUCC; enumForInfoStart ¬ BasicTime.Now[]; PFS.EnumerateForInfo[pattern: PFS.PathFromRope[pattern], proc: Enumerate]; IO.Close[self: s, abort: FALSE]; s ¬ PFS.StreamOpen[fileName: tempName, accessOptions: read]; abortProcess ¬ info[h: h, s: s, checkAbort: Abort]; IO.Close[self: s, abort: FALSE]; PFS.Delete[name: tempName]; enumForInfoEnd ¬ BasicTime.Now[]; }; FileInfo: PUBLIC TrickleChargeP9813V411.FileInfoType = { <<[h: CrRPC.Handle, name: ROPE, wantedCreatedTime: TrickleChargeP9813V411.INT32] RETURNS [fullFName: ROPE, bytes: TrickleChargeP9813V411.INT32, created: TrickleChargeP9813V411.INT32]>> ENABLE PFS.Error => { IF error.code = $unknownFile THEN ERROR FileNotFound[name] ELSE ERROR Error[error.explanation]; }; createdUID: PFS.UniqueID; wantedUID: PFS.UniqueID; wantedGMT: GMT ~ LOOPHOLE[wantedCreatedTime]; fullFNamePath: PFSNames.PATH; wantedUID.egmt.gmt ¬ wantedGMT; fileInfoCount ¬ fileInfoCount.SUCC; fileInfoStart ¬ BasicTime.Now[]; fileInfoName ¬ name; [fullFName: fullFNamePath, bytes: bytes, uniqueID: createdUID] ¬ PFS.FileInfo[name: PFS.PathFromRope[name], wantedUniqueID: wantedUID]; created ¬ LOOPHOLE[createdUID.egmt.gmt]; fullFName ¬ PFS.RopeFromPath[fullFNamePath]; fileInfoEnd ¬ BasicTime.Now[]; }; Retrieve: PUBLIC TrickleChargeP9813V411.RetrieveType = { <<[h: CrRPC.Handle, name: ROPE, wantedCreatedTime: TrickleChargeP9813V411.INT32, data: CrRPC.BulkDataSink]>> ENABLE PFS.Error => { IF error.code = $unknownFile THEN ERROR FileNotFound[name] ELSE ERROR Error[error.explanation]; }; Abort: CrRPC.BulkDataCheckAbortProc = { <<[h: CrRPC.Handle] RETURNS [abort: BOOL]>> IF abortThis THEN RETURN [TRUE] ELSE RETURN[FALSE]; }; abortThis: BOOL ¬ FALSE; s: STREAM; wantedGMT: GMT ~ LOOPHOLE[wantedCreatedTime]; wantedUID: PFS.UniqueID; retrieveStreamOptions: PFS.StreamOptions; retrieveStreamOptions[includeFormatting] ¬ TRUE; wantedUID.egmt.gmt ¬ wantedGMT; retrieveCount ¬ retrieveCount.SUCC; retrieveStart ¬ BasicTime.Now[]; retrieveInProgress ¬ TRUE; retrieveName ¬ name; s ¬ PFS.StreamOpen[fileName: PFS.PathFromRope[name], accessOptions: read, streamOptions: retrieveStreamOptions, wantedUniqueID: wantedUID]; abortThis ¬ data[h: h, s: s, checkAbort: Abort]; IO.Close[self: s, abort: FALSE]; retrieveInProgress ¬ FALSE; retrieveEnd ¬ BasicTime.Now[]; }; <> FileNotFound: PUBLIC TrickleChargeP9813V411.FileNotFoundType = CODE; <<[file: ROPE]>> Error: PUBLIC TrickleChargeP9813V411.ErrorType = CODE; <<[description: ROPE]>> <> nullGMTRope: ROPE ~ "nullGMT"; TCStats: Commander.CommandProc = { cmd.out.PutF1["***** Server started at %g\n", [time[startTime]] ]; cmd.out.PutF["anybodyHomeCount: %g (%g)\n", [cardinal[anybodyHomeCount]], IF anybodyHomeTime = BasicTime.nullGMT THEN [rope[nullGMTRope]] ELSE [time[anybodyHomeTime]] ]; cmd.out.PutF["enumForInfoCount: %g (%g, %g)\n", [cardinal[enumForInfoCount]], IF enumForInfoStart = BasicTime.nullGMT THEN [rope[nullGMTRope]] ELSE [time[enumForInfoStart]], IF enumForInfoEnd = BasicTime.nullGMT THEN [rope[nullGMTRope]] ELSE [time[enumForInfoEnd]] ]; cmd.out.PutFL["fileInfoCount: %g (%g, %g) (%g)\n", LIST[ [cardinal[fileInfoCount]], IF fileInfoStart = BasicTime.nullGMT THEN [rope[nullGMTRope]] ELSE [time[fileInfoStart]], IF fileInfoEnd = BasicTime.nullGMT THEN [rope[nullGMTRope]] ELSE [time[fileInfoEnd]], [rope[fileInfoName]]] ]; cmd.out.PutFL["retrieveCount: %g (%g, %g) (%g%g)\n", LIST[ [cardinal[retrieveCount]], IF retrieveStart = BasicTime.nullGMT THEN [rope[nullGMTRope]] ELSE [time[retrieveStart]], IF retrieveEnd = BasicTime.nullGMT THEN [rope[nullGMTRope]] ELSE [time[retrieveEnd]], [rope[retrieveName]], [rope[IF retrieveInProgress THEN " - in progress" ELSE NIL]]] ]; }; Commander.Register["TCStats", TCStats, "Statistics for TrickleChargeServer"]; END.