DIRECTORY FS, --???New--STP, IO, RemoteFiles, Rope, Stream, UserCredentials; RemoteFilesImpl: CEDAR PROGRAM IMPORTS --AlpineInterimDirectory, AlpFile, AlpTransaction, FileIOAlpine,-- IO, --New--STP, Stream, --UnsafeSTP,-- UserCredentials EXPORTS RemoteFiles = BEGIN STPStreamDataRef: TYPE = REF STPStreamData; STPStreamData: TYPE = RECORD [ handle: NewSTP.Handle, stream: Stream.Handle]; OpenSTP: PUBLIC PROC [ fileName: Rope.ROPE, accessOptions: FS.AccessOptions _ read, host, connect, directory: Rope.ROPE _ NIL ] RETURNS [ self: IO.STREAM, greetings: Rope.ROPE ] = BEGIN -- simplified for output to Oliver servers like [vice] stpHandle: NewSTP.Handle; streamHandle: Stream.Handle; SELECT accessOptions FROM write -- , read -- => NULL; ENDCASE => ERROR IO.Error[NotImplementedForThisStream, NIL]; stpHandle _ NewSTP.Create[]; IF host=NIL THEN host _ "indigo"; greetings _ stpHandle.Open[host]; stpHandle.Login[name: UserCredentials.GetUserCredentials[].name, password: UserCredentials.GetUserCredentials[].password]; IF connect#NIL THEN stpHandle.Connect[name: connect, password: NIL]; IF directory#NIL THEN stpHandle.SetDirectory[directory: directory]; streamHandle _ stpHandle.CreateRemoteStream[ file: fileName, access: (SELECT accessOptions FROM read => read, ENDCASE => write), fileType: binary]; self _ IO.CreateProcsStream[ streamProcs: IO.CreateRefStreamProcs[ putChar: SendSTPChar, unsafePutBlock: SendSTPBlock, close: CloseSTP], streamData: NEW[STPStreamData _ [ handle: stpHandle, stream: streamHandle]]]; END; SendSTPChar: PROC [ self: IO.STREAM, char: CHAR ] = BEGIN sd: STPStreamDataRef = NARROW[self.streamData]; TRUSTED {sd.stream.PutChar[char: char]}; END; SendSTPBlock: PROC [ self: IO.STREAM, block: IO.UnsafeBlock ] = BEGIN sd: STPStreamDataRef = NARROW[self.streamData]; TRUSTED {sd.stream.PutBlock[block: [blockPointer: block.base, startIndex: block.startIndex, stopIndexPlusOne: block.stopIndexPlusOne]]}; END; CloseSTP: PROC [ self: IO.STREAM, abort: BOOL _ FALSE ] = BEGIN BEGIN ENABLE UnsafeSTP.Error => IF abort THEN CONTINUE ELSE REJECT; sd: STPStreamDataRef = NARROW[self.streamData]; TRUSTED {sd.stream.Delete[]}; sd.stream _ NIL; sd.handle.Close[]; sd.handle _ NIL; END; END; END. -- of RemoteFilesImpl  RemoteFilesImpl.mesa A package for producing IO streams on Alpine and FTP remote files, suited for ChipNDale I/O. written by E. McCreight, November 9, 1983 12:42 pm Last Edited by: Mccreight, November 9, 1983 2:47 pm AlpineEnvironment, AlpineInterimDirectory, AlpInstance, AlpFile, AlpTransaction, FileIOAlpine, ???UnsafeSTP, OpenAlpineForWrite: PUBLIC PROC [ fileName: Rope.ROPE, expectedLength: INT _ 6D6 ] RETURNS [ self: IO.STREAM ] = BEGIN server: AlpInstance.Handle; trans: AlpTransaction.Handle; file: AlpFile.Handle; refUniversalFile: REF AlpineEnvironment.UniversalFile; retryCount: INT _ 0; DO { ENABLE AlpineInterimDirectory.Error => IF retryCount < 2 THEN LOOP; retryCount _ retryCount + 1; [instHandle: server, refUniversalFile: refUniversalFile] _ AlpineInterimDirectory.Open[fileName: fileName, initialByteAllocation: expectedLength]; trans _ AlpTransaction.Create[server]; file _ AlpFile.Open[ transHandle: trans, universalFile: refUniversalFile^, access: $readWrite, referencePattern: $sequential].handle; file.SetSize[expectedLength/512]; file.WriteProperties[LIST[ [highWaterMark[highWaterMark: 0]]]]; IF trans.Finish[$commit].outcome # $commit THEN LOOP; trans _ AlpTransaction.Create[server]; file _ AlpFile.Open[ transHandle: trans, universalFile: refUniversalFile^, access: $readWrite, referencePattern: $sequential, lock: [mode: write, ifConflict: wait]].handle; self _ FileIOAlpine.StreamFromAlpineOpenFile[ fileHandle: file, fileName: fileName, accessOptions: $write]; EXIT; } ENDLOOP; END; Module START code... Ê‘˜Jšœ™J˜Jšœ\™\J˜Jšœ2™2J™3J˜šÏk ˜ Jšœ™Jšœ™Jšœ ™ Jšœ™J™Jšœ˜Jšœ ™ Jšœ˜Jšœ˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ ™ Jšœ˜J˜—šœœ˜JšœDœ4˜Jšœ˜Jš˜J˜Jšœœœ˜+šœœœ˜Jšœ˜Jšœ˜—J˜šÏnœœœœIœœœ œœœ˜³JšœÏc6˜