-- Copyright (C) 1983 by Xerox Corporation. All rights reserved. -- SloshRecv.mesa, HGM, 24-Sep-83 17:39:42 DIRECTORY Ascii USING [CR], Environment USING [Byte, bytesPerPage], Inline USING [LowHalf], Put USING [Text], Stream USING [Delete, Handle, PutBlock], String USING [AppendChar, AppendString, AppendLongDecimal], System USING [GetClockPulses], Time USING [AppendCurrent], Volume USING [GetAttributes, InsufficientSpace, SystemID], Window USING [Handle], Slosh USING [RecvStatus], EFTPDefs USING [ EFTPOpenForReceiving, EFTPAbortReceiving, EFTPGetBlock, EFTPFinishReceiving, EFTPEndReceiving, EFTPTimeOut, EFTPTroubleReceiving, EFTPSetRecvTimeout], PupTypes USING [PupAddress]; SloshRecv: MONITOR IMPORTS Inline, Put, Stream, String, System, Time, Volume, EFTPDefs EXPORTS Slosh = BEGIN verbose: BOOLEAN = TRUE; RecvFile: PUBLIC ENTRY PROCEDURE [ who: Window.Handle, fileName: LONG STRING, file: Stream.Handle, me: PupTypes.PupAddress, ask: PROCEDURE] RETURNS [status: Slosh.RecvStatus] = BEGIN OPEN EFTPDefs; FixThingsUp: PROCEDURE [e: LONG STRING, why: Slosh.RecvStatus] = BEGIN message ← e; EFTPAbortReceiving[message]; status ← why; END; buffer: PACKED ARRAY [0..Environment.bytesPerPage) OF Environment.Byte; total: LONG CARDINAL ← 0; message: LONG STRING ← NIL; trouble: STRING = [100]; EFTPSetRecvTimeout[1000]; BEGIN ENABLE BEGIN EFTPTroubleReceiving => BEGIN String.AppendString[trouble, s]; GOTO EFTPTrouble; END; EFTPTimeOut => GOTO EFTPTimeout; END; pokes: CARDINAL ← 0; bytes: CARDINAL; [] ← EFTPOpenForReceiving[ me ! EFTPTimeOut => BEGIN -- We expect to get here once since we haven't asked yet IF (pokes ← pokes + 1) > 3 THEN GOTO OpenFailed; ask[]; RESUME ; END]; EFTPSetRecvTimeout[60000]; -- This is a silly place to check, but it simplifies recovery DO bytes ← EFTPGetBlock[ @buffer, Environment.bytesPerPage ! EFTPEndReceiving => EXIT]; Stream.PutBlock[ file, [@buffer, 0, bytes] ! Volume.InsufficientSpace => GOTO TempFull]; total ← total + bytes; ENDLOOP; EFTPFinishReceiving[]; status ← statusStoreOk; EXITS OpenFailed => FixThingsUp["EFTP Open Failed"L, statusEFTPFailed]; EFTPTrouble => FixThingsUp["EFTP Trouble"L, statusEFTPFailed]; EFTPTimeout => FixThingsUp["EFTP Timeout"L, statusEFTPFailed]; TempFull => FixThingsUp[ "Disk Full while buffering into buffer file"L, statusDiskFull]; END; Stream.Delete[file]; IF verbose THEN BEGIN text: STRING = [200]; pagesLeft: LONG CARDINAL ← Volume.GetAttributes[ Volume.SystemID[]].freePageCount; Time.AppendCurrent[text]; IF message = NIL THEN BEGIN String.AppendString[text, " Got "L]; String.AppendString[text, fileName]; String.AppendString[text, " ok. Length="L]; String.AppendLongDecimal[text, total/Environment.bytesPerPage]; String.AppendChar[text, '.]; String.AppendLongDecimal[text, total MOD Environment.bytesPerPage]; END ELSE BEGIN String.AppendString[text, " Recv aborted because: "L]; String.AppendString[text, message]; IF trouble.length # 0 THEN BEGIN String.AppendString[text, "("L]; String.AppendString[text, trouble]; String.AppendString[text, ") "L]; END; String.AppendString[text, " after page "L]; String.AppendLongDecimal[text, total/Environment.bytesPerPage]; END; String.AppendString[text, ", pages left="L]; String.AppendLongDecimal[text, pagesLeft]; LogString[who, text]; END; END; LogString: PROCEDURE [msg: Window.Handle, text: LONG STRING] = BEGIN String.AppendChar[text, '.]; String.AppendChar[text, Ascii.CR]; Put.Text[NIL, text]; IF msg # NIL THEN Put.Text[msg, text]; END; RetransmissionInterval: PUBLIC PROCEDURE RETURNS [seconds: CARDINAL] = BEGIN RETURN[Inline.LowHalf[System.GetClockPulses[]] MOD 5*60]; -- 5 min END; END.