DIRECTORY Atom, CardTab, IO, FS, FSExtras, PrincOps, Process, RefText, Rope, SoftcardDataExch, SoftcardFSAccess, SoftcardTool, SparcSoftcardLoaderOps; SoftcardFSAccessImpl: CEDAR PROGRAM IMPORTS Atom, CardTab, IO, FS, FSExtras, Process, RefText, Rope, SoftcardDataExch, SoftcardTool, SparcSoftcardLoaderOps EXPORTS SoftcardFSAccess ~ BEGIN OPEN SoftcardFSAccess; QUIT: CARD32 _ SoftcardDataExch.QUIT; -- 0 is the type which stops the watch procedure of the SPARC logActive: BOOLEAN _ FALSE; log: IO.STREAM _ NIL; logName: Rope.ROPE; StartLog: PROC [fName: Rope.ROPE _ NIL] ~ { IF logActive THEN StopLog[]; logName _ IF fName#NIL THEN fName ELSE "///Temp/Softcard/SoftcardFSAccess.log"; log _ FS.StreamOpen[fileName: logName, accessOptions: create, keep: 3]; logActive _ TRUE; }; StartViewerLog: PROC ~ { IF logActive THEN StopLog[]; log _ GetStream[1]; logActive _ TRUE; }; StopLog: PROC ~ { logActive _ FALSE; IO.Close[log]; }; FlushLog: PROC ~ { StopLog[]; StartLog[logName]; }; LogC: PROC [what: CARD32] ~ { IO.PutF[log, "%08x\t", IO.card[what]]; }; LogR: PROC [what: Rope.ROPE] ~ { IO.PutRope[log, what]; IO.PutChar[log, '\n]; }; maxMsgSize: NAT = 80; --limited on the Sparc side SendFSError: PROC [error: FS.ErrorDesc] ~ { DoPutError: SoftcardDataExch.PutProc ~ TRUSTED { s: IO.STREAM _ IO.TIS[text: r]; nBytes _ IO.UnsafeGetBlock[self: s, block: ub]; }; groupVal: CARD32; codeName: Rope.ROPE _ Atom.GetPName[error.code]; r: REF TEXT _ RefText.ObtainScratch[Rope.Length[codeName]+Rope.Length[error.explanation]+3]; groupVal _ SELECT error.group FROM ok => 1, bug => 2, environment=> 3, lock => 4, client => 5, user => 6, ENDCASE => 7; -- will never happen, right ? r _ RefText.AppendRope[r, IO.PutFR["%g %d %g", [rope[codeName]], [cardinal[groupVal]], [rope[error.explanation]] ]]; IF r.length>maxMsgSize THEN { r.length _ maxMsgSize; r[maxMsgSize-1] _ '.; r[maxMsgSize-2] _ '.; r[maxMsgSize-3] _ '.; }; SoftcardDataExch.PutPacket[SOPEN, groupVal, 0, r.length, DoPutError]; RefText.ReleaseScratch[r]; SoftcardDataExch.PutPacket[QUIT]; IF logActive THEN LogR[error.explanation]; }; blkSize: NAT _ 8*1024; ReadIt: PROC [s: IO.STREAM, data1, len: CARD32] ~ { stillToDo: NAT _ MAX[len, MIN[blkSize, IO.CharsAvail[s]]]; -- get at least a buffer index: CARD32 _ 0; UNTIL IO.EndOf[s] DO DoPutBlock: SoftcardDataExch.PutProc ~ TRUSTED { nBytes _ IO.UnsafeGetBlock[self: s, block: ub]; n _ n+nBytes; }; n: NAT _ 0; count: NAT _ MIN[blkSize, stillToDo]; SoftcardDataExch.PutPacket[SREAD, data1, index, count, DoPutBlock]; stillToDo _ stillToDo-n; index _ index+n; IF stillToDo=0 THEN EXIT; ENDLOOP; SoftcardDataExch.PutPacket[QUIT]; IF logActive AND data1>0ffh THEN {LogC[data1]; LogC[len]; LogC[index]; LogC[IO.GetIndex[s ! IO.Error => CONTINUE]]; LogR["Read Block"];} }; UnknownStream: PUBLIC SIGNAL ~ CODE; GetStream: PROC [streamNo: CARD32] RETURNS [s: IO.STREAM] ~ { s _ NARROW[CardTab.Fetch[streams, streamNo].val]; IF s=NIL THEN SIGNAL UnknownStream; }; RegisterConsoleStreams: PUBLIC PROC [in, out, err: IO.STREAM] ~ { [] _ CardTab.Store[streams, STDIN, in]; [] _ CardTab.Store[streams, STDOUT, out]; [] _ CardTab.Store[streams, STDERR, out]; --err }; ActionClose: SoftcardDataExch.ActionProc ~ { IF data1>specialStreams THEN { --do not close the console stream: IO.STREAM _ GetStream[data1]; IO.Close[stream]; [] _ CardTab.Delete[streams, data1]; }; IF logActive THEN {LogC[data1]; LogR["Close"];} }; ActionWrite: SoftcardDataExch.ActionProc ~ { stream: IO.STREAM _ GetStream[data1]; IO.UnsafePutBlock[self: stream, block: ub]; IF logActive THEN {LogC[data1]; LogC[ub.count]; LogR["Write"];} }; ActionRead: SoftcardDataExch.ActionProc ~ { stream: IO.STREAM _ GetStream[data1]; ReadIt[stream, data1, data2]; }; ActionSetIndex: SoftcardDataExch.ActionProc ~ { stream: IO.STREAM _ GetStream[data1]; IO.SetIndex[stream, data2]; IF logActive THEN {LogC[data1]; LogC[data2]; LogR["SetIndex"];} }; ActionGetIndex: SoftcardDataExch.ActionProc ~ { stream: IO.STREAM _ GetStream[data1]; index: INT _ IO.GetIndex[stream ! IO.Error => IF ec=NotImplementedForThisStream THEN GOTO Exit]; --do not ask the console IF data2=0 THEN { SoftcardDataExch.PutPacket[SGETINDEX, data1, index]; SoftcardDataExch.PutPacket[QUIT]; } ELSE IO.SetIndex[stream, index-data2]; IF logActive THEN {LogC[data1]; LogC[data2]; LogR["GetIndex"];} EXITS Exit => NULL; }; ActionSetLength: SoftcardDataExch.ActionProc ~ { stream: IO.STREAM _ GetStream[data1]; IO.SetLength[stream, data2]; IF logActive THEN {LogC[data1]; LogC[data2]; LogR["SetLength"];} }; ActionGetLength: SoftcardDataExch.ActionProc ~ { stream: IO.STREAM _ GetStream[data1]; index: INT _ IO.GetLength[stream]; SoftcardDataExch.PutPacket[SGETLENGTH, data1, index]; SoftcardDataExch.PutPacket[QUIT]; IF logActive THEN {LogC[data1]; LogC[data2]; LogR["GetLength"];} }; ActionOpen: SoftcardDataExch.ActionProc ~ { fsError: FS.ErrorDesc; { name: Rope.ROPE; accessOptions: FS.AccessOptions; stream: IO.STREAM; IF data1<=specialStreams THEN RETURN; -- do not perturbate console streams IF ub.count=0 THEN name _ "NoFileNameSpecified.data" ELSE { ros: IO.STREAM _ IO.ROS[]; IO.UnsafePutBlock[ros, ub]; name _ IO.RopeFromROS[ros]; }; IF data2=TSCREATE THEN { in, out, err: IO.STREAM; [in, out, err] _ SoftcardTool.CreateCmdStreams[name]; -- to hide viewers from this [] _ CardTab.Store[streams, data1, in]; [] _ CardTab.Store[streams, data1+1, out]; [] _ CardTab.Store[streams, data1+2, err]; } ELSE { accessOptions _ SELECT data2 FROM FSCREATE => create, FSAPPEND => append, FSWRITE => write, ENDCASE => read; stream _ FS.StreamOpen[ fileName: name, accessOptions: accessOptions, streamBufferParms: [vmPagesPerBuffer: blkSize/PrincOps.bytesPerPage, nBuffers: 4], wDir: defaultDir ! FS.Error => {fsError _ error; GOTO NoSuchFile}]; IF stream#NIL THEN [] _ CardTab.Store[streams, data1, stream]; }; SoftcardDataExch.PutPacket[QUIT]; IF logActive THEN {LogC[data1]; LogC[data2]; LogR[name];} EXITS NoSuchFile => TRUSTED {Process.Detach[FORK SendFSError[fsError]]}; }; }; Reset: PUBLIC PROC[fileInput: IO.STREAM] ~ { GetRidOfOne: CardTab.EachPairAction ~ { s: IO.STREAM _ NARROW[val]; IF key>2 AND s#NIL THEN IO.Close[s ! FS.Error => CONTINUE]; }; s0: IO.STREAM _ GetStream[0]; s1: IO.STREAM _ GetStream[1]; s2: IO.STREAM _ GetStream[2]; [] _ CardTab.Pairs[x: streams, action: GetRidOfOne]; streams _ CardTab.Create[]; IO.Reset[s0]; [] _ CardTab.Store[streams, 0, s0]; IO.Reset[s1]; [] _ CardTab.Store[streams, 1, s1]; IO.Reset[s2]; [] _ CardTab.Store[streams, 2, s2]; SoftcardDataExch.Restart[]; }; streams: CardTab.Ref _ CardTab.Create[]; defaultDir: Rope.ROPE _ FSExtras.GetWDir[]; SoftcardDataExch.Register[SCLOSE, ActionClose]; SoftcardDataExch.Register[SWRITE, ActionWrite]; SoftcardDataExch.Register[SREAD, ActionRead]; SoftcardDataExch.Register[SSETINDEX, ActionSetIndex]; SoftcardDataExch.Register[SGETINDEX, ActionGetIndex]; SoftcardDataExch.Register[SSETLENGTH, ActionSetLength]; SoftcardDataExch.Register[SGETLENGTH, ActionGetLength]; SoftcardDataExch.Register[SOPEN, ActionOpen]; SparcSoftcardLoaderOps.RegisterStartProc[$SparcFSAccess, Reset]; END. *SoftcardFSAccessImpl.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. written by Ch. Le Cocq, August 4, 1988 Christian Le Cocq November 22, 1988 10:49:44 am PST Christophe Cuenod September 12, 1988 5:59:56 pm PDT Description of what this module does. Log: We are going unmonitored for now, we'll fix that if it causes too many problems. TRUSTED { Process.Detach[ FORK ReadIt[stream, data1, data2]];} if data2=0 means get & send index info, else means get index and correct it by -data2 (cache thrown away in the softcard); Κ˜code•Mark outsideHeaderšœ™Kšœ<™Kšœ˜K˜K˜—š œ!˜/Kšœœœ˜%Jšœ˜Kšœ œ.˜?K˜K˜—š œ!˜/K™zKšœœœ˜%šœœœ˜"Jš œ œ œœŸ˜W—šœ œ˜Jšœ œ˜4Kšœœ˜!K˜—Kšœœ˜&Kšœ œ.˜?š˜Kšœœ˜ —K˜K˜—š œ!˜0Kšœœœ˜%Jšœ˜Kšœ œ/˜@K˜K˜—š œ!˜0Kšœœœ˜%Jšœœœ˜"Jšœ œ˜5Kšœœ˜!Kšœ œ/˜@K˜K˜—š  œ!˜+Kšœ œ ˜˜Kšœ œ˜K–Κ[fileName: ROPE, accessOptions: FS.AccessOptions _ read, streamOptions: FS.StreamOptions _ (3)[TRUE, TRUE, TRUE], keep: CARDINAL _ 1B (1), createByteCount: FS.ByteCount _ 2560, streamBufferParms: FS.StreamBufferParms _ [vmPagesPerBuffer: 8, nBuffers: 2], extendFileProc: FS.ExtendFileProc, wantedCreatedTime: GMT _ nullGMT, remoteCheck: BOOL _ TRUE, wDir: ROPE _ NIL, checkFileType: BOOL _ FALSE, fileType: FS.FileType _ [0B (0)]]šœœ˜ Kšœœœ˜KšœœœŸ$˜J–Κ[fileName: ROPE, accessOptions: FS.AccessOptions _ read, streamOptions: FS.StreamOptions _ (3)[TRUE, TRUE, TRUE], keep: CARDINAL _ 1B (1), createByteCount: FS.ByteCount _ 2560, streamBufferParms: FS.StreamBufferParms _ [vmPagesPerBuffer: 8, nBuffers: 2], extendFileProc: FS.ExtendFileProc, wantedCreatedTime: GMT _ nullGMT, remoteCheck: BOOL _ TRUE, wDir: ROPE _ NIL, checkFileType: BOOL _ FALSE, fileType: FS.FileType _ [0B (0)]]šœ œ#œ˜;Kš œœœœœ˜Kšœ˜Jšœœ˜Kšœ˜—šœœœ˜Kšœœœ˜Kšœ6Ÿ˜RKšœ'˜'Kšœ*˜*Kšœ*˜*K˜—šœ˜šœœ˜!Kšœ ˜Kšœ ˜Kšœ ˜Kšœ ˜—šœ œ ˜Kšœ˜Kšœ˜KšœR˜RKšœ˜Kšœœœ˜2—Kšœœœ,˜>K˜—Kšœœ˜!Kšœ œ(˜9š˜K– [PROCESS]šœœœ˜B—K˜—K˜K™—š  œœœ œœ˜,–4[x: CardTab.Ref, action: CardTab.EachPairAction]š  œ˜'Kšœœœœ˜Kšœœœœœ œ œ˜;K˜—Kšœœœ˜Kšœœœ˜Kšœœœ˜Kšœ4˜4Kšœ˜K–[self: STREAM]šœ ˜ Kšœ#˜#K–[self: STREAM]šœ ˜ Kšœ#˜#K–[self: STREAM]šœ ˜ Kšœ#˜#Kšœ˜K˜K˜—Kšœœ ˜(Kšœœ˜+Kšœœ˜/Kšœœ˜/Kšœœ˜-Kšœ œ˜5Kšœ œ˜5Kšœ œ˜7Kšœ œ˜7Kšœœ˜-Kšœ@˜@—K˜Kšœ˜—…—Δ-ρ