// RemoteVMemInit1.bcpl - handles pulling in remote sysout
// Last change November 30, 1981  9:59 PM by Bill van Melle
// Last change September 7, 1981  1:04 PM by Bill van Melle

	get "LispBcpl.decl"
	get "VMem.decl"
	get "FtpProt.decl"
	get "AltoDefs.d"

external [	// procedures defined here
	Retrieve; Wss; FixPassword

		// O.S. procedures
	CallSwat; Puts; PositionPage; WriteBlock; Ws

		// misc procedures used
	IndexedPageIO; LoadIPage; ReadStrng 
		// pup procs
	BSPReadBlock
		// statics used
	LispFmap 
	CtxRunning
	UserName; UserPassword
		// statics from RemoteVMemInit.bcpl
	VMStream; sysoutHost
	]

manifest [
	firstMouseY = 50
	lastMouseY = 800
	]

//----------------------------------------------------------------------------
structure String: [ length byte; char↑1,255 byte ]
//----------------------------------------------------------------------------

let Retrieve (remotePL, localPL) = valof
[		// this two-level action needed to approve the file,
		// then retrieve it
Ws ("*n{")
Ws (sysoutHost)
Ws ("}")
Ws (remotePL>>PL.SFIL)
Ws ("...")	// print filename to show what we're doing
resultis LispRetrieveFile
]

and LispRetrieveFile (remotePL, localPL) = valof
[
 PositionPage (VMStream, FirstVmemBlock)
 let bspStream = CtxRunning>>FtpCtx.bspStream
 let buffer = CtxRunning>>FtpCtx.buffer
 let bufferLength = CtxRunning>>FtpCtx.bufferLength
 for i = 1 to FirstVmemBlock-1
 		// start at page 1--IFS has no leader page
    do BSPReadBlock (bspStream, buffer, 0, WordsPerPage lshift 1)
		// skip over the silly pages before the good stuff
 let nPages = lv remotePL>>FPL.SIZE
 nPages = (nPages!0 lshift 7 + nPages!1 rshift 9) / (bufferLength / WordsPerPage)
		// number of buffers full it will take to retrieve this
 let mouseInc = ((lastMouseY-firstMouseY) lshift 4) / nPages
 let mouseOff = mouseInc
		// thus the mouse crawls down screen as we read.
		// mouseInc is 2↑4 times amount to move per buffer full
		// mouseOff = mouseInc*pgno
 [ let bytesRead = BSPReadBlock (bspStream, buffer, 0, bufferLength lshift 1)
   FlipCursor()	// flip once per buffer full (at same rate as ftp if 6 bufs)
   @mouseY = firstMouseY + (mouseOff rshift 4)
   if bytesRead eq 0
      then break	// done
   if (bytesRead & #777) ne 0
      then CallSwat ("Sysout not integral number of pages")
   WriteBlock (VMStream, buffer, bytesRead rshift 1)
   mouseOff = mouseOff + mouseInc
 ] repeat
 resultis true
]

and FlipCursor () be

[ for i = 0 to 15 do cursorBitMap!i = not cursorBitMap!i ]

and Wss (stream, str) be

[ for i = 1 to str>>String.length
     do Puts(stream, str>>String.char↑i)
]

and FixPassword (host) be

[
Ws ("*n{")
Ws (host)
Ws ("} Login user: ")
let haveDefaultName = UserName>>String.length gr 0
if haveDefaultName
   then Ws (UserName)
unless ReadStrng (UserName, (UserName!-1 lshift 1) - 1, haveDefaultName) loop
Ws (" (password) ")
if ReadStrng (UserPassword, (UserPassword!-1 lshift 1) - 1, false, true) 
   then return
] repeat