--File: ILTInstallImpl.mesa --Created by -- JFung.PASA 22-Sep-83 10:21:23 -- This is a modified version taken from InstallMuImpl.mesa --last edited by -- JFung.PASA 29-Nov-83 11:14:31 DIRECTORY Ascii, Display, Environment USING [bytesPerPage, PageCount, PageOffset], File USING [ Capability, Create, Delete, DeleteImmutable, GetAttributes, GetSize, MakePermanent, nullCapability, PageCount, PageNumber, SetSize, Unknown], FileName: TYPE USING [AllocVFN, FreeVFN, VFN], FileTransfer, FileTypes USING [tUntypedFile], Inline USING [LowHalf], LispToolOps, NSName USING [maxFullNameLength], OthelloOps USING [ GetPhysicalVolumeBootFile, GetVolumeBootFile, MakeBootable, MakeUnbootable, SetPhysicalVolumeBootFile, SetVolumeBootFile, VoidPhysicalVolumeBootFile, VoidVolumeBootFile], PhysicalVolume USING [GetContainingPhysicalVolume, ID], Process USING [Pause, SecondsToTicks], PrincOps USING [Port], Put, Space USING [ CopyOut, Create, CreateUniformSwapUnits, Delete, Handle, InsufficientSpace, LongPointer, Map, nullHandle, PageCount, PageOffset, virtualMemory], Stream USING [Delete, GetBlock, Handle], TemporaryBooting USING [InvalidParameters], ToolWindow, UserInput, Volume USING [ Close, GetAttributes, ID, InsufficientSpace, maxNameLength, nullID, PageCount], Window; ILTInstallImpl: PROGRAM IMPORTS Display, File, FileName, FileTransfer, Inline, LispToolOps, OthelloOps, PhysicalVolume, Process, Put, Space, Stream, TemporaryBooting, UserInput, Volume, Window EXPORTS LispToolOps = BEGIN OPEN FileName, ILT: LispToolOps; PortRep: TYPE = PrincOps.Port; byteCount: LONG INTEGER _ 0; conn: FileTransfer.Connection; debug : BOOLEAN _ FALSE; defaultVMemSize: File.PageCount; fileName: LONG STRING _ NIL; indicatorBox: Window.Box = [[10, 10], [16, 16]]; readStream: Stream.Handle _ NIL; space: Space.Handle _ Space.nullHandle; vfn: VFN _ NIL; volumeID: Volume.ID _ Volume.nullID; volumeOpen: BOOLEAN _ FALSE; CheckForAbort: FileTransfer.CheckAbortProc = BEGIN IF UserInput.UserAbort[ILT.windowHandle] THEN BEGIN ILT.toolData.busy _ FALSE; Put.Line[ILT.toolData.msgSW, "Aborted.. "L]; Cleanup[]; ILT.DisplayCommandSubwindow; --Process.Pause[Process.SecondsToTicks[10]]; Put.Line[ILT.toolData.fileSW, "Aborted.. "L]; DisplayOldVMemSize; RETURN[TRUE]; END ELSE RETURN[FALSE]; END; Cleanup: PROC = BEGIN IF debug THEN { Put.Line[ILT.toolData.fileSW, "Enter Cleanup....."L]; Process.Pause[Process.SecondsToTicks[5]]; }; IF readStream # NIL THEN BEGIN readStream.Delete[]; readStream _ NIL; END; IF space # Space.nullHandle THEN BEGIN IF debug THEN { Put.Line[ILT.toolData.fileSW, "space # null handle..."L]; Process.Pause[Process.SecondsToTicks[5]]; }; Space.Delete[space]; space _ Space.nullHandle; END; IF vfn # NIL THEN {FreeVFN[vfn]; vfn _ NIL}; IF conn # NIL THEN {conn.Destroy[]; conn _ NIL}; --CloseVolume[]; END; --Cleanup CloseVolume: PROC = BEGIN IF volumeOpen THEN {Volume.Close[volumeID]; volumeOpen _ FALSE} END; DisplayOldVMemSize: PROC = BEGIN size: File.PageCount; size _ ILT.GetFileSize[]; ILT.DisplayFileSize[size]; END; GetFile: PORT [ file: File.Capability _ File.nullCapability, name: LONG STRING _ NIL] RETURNS [BOOLEAN]; InstallProc: PUBLIC PROCEDURE [volName: LONG STRING] = BEGIN byteCount _ 0; fileName _ ILT.toolData.filePathName; volumeID _ Volume.nullID; volumeOpen _ FALSE; IF debug THEN { Put.Line[ILT.toolData.fileSW, "Enter Install Proc "L]; Put.LongString[ILT.toolData.fileSW, volName]; --Process.Pause[Process.SecondsToTicks[5]]; }; IF ValidateString[fileName] THEN InstallFileOnVolume[volName ! UNWIND => CloseVolume[]]; END; InstallFileOnVolume: PROC [volName: LONG STRING] = BEGIN OPEN OthelloOps; cap: File.Capability; created: BOOLEAN _ FALSE; currentSize: File.PageCount; firstPage: File.PageNumber; freePages: Volume.PageCount; maxSize: Volume.PageCount; volSize: Volume.PageCount; -- clean the PORT up from last time LOOPHOLE[GetFile, PortRep].in _ 0; -- CONNECT GetFile.out TO Retrieve; LOOPHOLE[GetFile, PortRep].out _ Retrieve; [volumeID, volumeOpen] _ ILT.GetVolumeID[volName]; IF volumeID = Volume.nullID THEN RETURN; IF debug THEN { Put.Text[ILT.toolData.fileSW, "File name ="L]; Put.LongString[ILT.toolData.fileSW, fileName]; Put.Line[ILT.toolData.fileSW, " ...."L]; Process.Pause[Process.SecondsToTicks[5]]; }; conn _ FileTransfer.Create[]; FileTransfer.SetProcs[ conn: conn, clientData: NIL, messages: PostComment, login: NIL, checkAbort: CheckForAbort]; IF debug THEN { Put.Line[ILT.toolData.fileSW, "GetVolumeBootFile....."L]; Process.Pause[Process.SecondsToTicks[5]]; }; [cap, firstPage] _ GetVolumeBootFile[volumeID, hardMicrocode]; [volSize, freePages] _ Volume.GetAttributes[volumeID]; -- set up default size to whatever pages (here aim at 14000-2000=12000) defaultVMemSize _ volSize - 2000; IF cap # File.nullCapability THEN BEGIN ENABLE File.Unknown => {cap _ File.nullCapability; CONTINUE}; IF debug THEN { Put.Line[ILT.toolData.fileSW, " not nullCapability...."L]; Process.Pause[Process.SecondsToTicks[5]]; }; << IF File.GetAttributes[cap].immutable THEN BEGIN pvID: PhysicalVolume.ID = PhysicalVolume.GetContainingPhysicalVolume[volumeID]; IF debug THEN { Put.Line[ILT.toolData.fileSW, "file immutable....."L]; Process.Pause[Process.SecondsToTicks[5]]; }; File.DeleteImmutable[cap, volumeID]; VoidVolumeBootFile[volumeID, hardMicrocode]; IF GetPhysicalVolumeBootFile[pvID, hardMicrocode].cap = cap THEN VoidPhysicalVolumeBootFile[pvID, hardMicrocode]; cap _ File.nullCapability END; >> END; IF (created _ cap = File.nullCapability) THEN BEGIN IF debug THEN { Put.Line[ILT.toolData.fileSW, " = nullCapability...."L]; Process.Pause[Process.SecondsToTicks[5]]; }; cap _ File.Create[volumeID, 0, FileTypes.tUntypedFile]; --set default vMem size --dont overwrite user's selection IF ILT.toolData.vMemSize = 0 THEN BEGIN ILT.toolData.vMemSize _ defaultVMemSize; ILT.DisplayFileSize[ILT.toolData.vMemSize]; END; END ELSE BEGIN IF debug THEN { Put.Line[ILT.toolData.fileSW, " MakeUnbootable.."L]; Process.Pause[Process.SecondsToTicks[5]]; }; MakeUnbootable[ cap, hardMicrocode, firstPage ! TemporaryBooting.InvalidParameters => BEGIN Put.Text[ ILT.toolData.msgSW, "Warning: trouble making unbootable"L]; CONTINUE; END]; END; [volSize, freePages] _ Volume.GetAttributes[volumeID]; IF cap = File.nullCapability THEN currentSize _ 0 ELSE currentSize _ File.GetSize[cap]; IF debug THEN { Put.LongDecimal[ILT.toolData.fileSW, currentSize]; Put.CR[ILT.toolData.fileSW]; }; IF debug THEN { Put.Line[ILT.toolData.fileSW, "GetFile...."L]; Process.Pause[Process.SecondsToTicks[5]]; }; IF ~GetFile[name: fileName] THEN BEGIN CloseVolume[]; Put.Line[ ILT.toolData.msgSW, "File not found or Incorrect user/password or Connection timed out(2 mins)"L]; Put.Line[ILT.toolData.fileSW, " Install failed."L]; DisplayOldVMemSize; ILT.toolData.busy _ FALSE; RETURN; END; Put.Text[ILT.toolData.fileSW, " \n Volume size = "L]; Put.LongDecimal[ILT.toolData.fileSW, volSize]; Put.Line[ILT.toolData.fileSW, " pages"L]; Put.Text[ILT.toolData.fileSW, " Default VMem size = "L]; Put.LongDecimal[ILT.toolData.fileSW, defaultVMemSize]; Put.Line[ILT.toolData.fileSW, " pages"L]; Put.Text[ILT.toolData.fileSW, " Free pages on volume = "L]; Put.LongDecimal[ILT.toolData.fileSW, freePages]; Put.CR[ILT.toolData.fileSW]; << -- calculate maximum vmem size maxSize _ currentSize + freePages; File.SetSize[ cap, maxSize ! Volume.InsufficientSpace => {maxSize _ maxSize - 100; RETRY}]; Put.Text[ILT.toolData.fileSW, " Approximate maximum VMem size = "L]; Put.LongDecimal[ILT.toolData.fileSW, maxSize]; Put.Line[ILT.toolData.fileSW, " pages"L]; -- restore original size File.SetSize[cap, currentSize]; >> Put.Text[ILT.toolData.fileSW, " Fetching... "L]; IF ~GetFile[ file: cap ! UNWIND => { IF created THEN File.Delete[cap]; --Put.Line[ILT.toolData.fileSW, " UNWIND ~GetFile"L]; CloseVolume[]}] THEN BEGIN IF created THEN File.Delete[cap]; CloseVolume[]; Put.Line[ILT.toolData.msgSW, "cannot fetch file "L]; DisplayOldVMemSize; RETURN; END; IF debug THEN { Put.Text[ILT.toolData.fileSW, "SetVolumeBootFile..."L]; Process.Pause[Process.SecondsToTicks[5]]; }; SetVolumeBootFile[cap, hardMicrocode, 0]; IF debug THEN { Put.Text[ILT.toolData.fileSW, "MakePermanent..."L]; Process.Pause[Process.SecondsToTicks[5]]; }; File.MakePermanent[cap]; IF debug THEN { Put.Text[ILT.toolData.fileSW, "MakeBootable..."L]; Process.Pause[Process.SecondsToTicks[5]]; }; MakeBootable[ cap, hardMicrocode, 0 ! TemporaryBooting.InvalidParameters => BEGIN Put.Text[ ILT.toolData.msgSW, "Warning: trouble making bootable"L]; CONTINUE; END]; Put.Line[ILT.toolData.fileSW, " installed."L]; IF debug THEN { Put.Text[ILT.toolData.fileSW, "SetPhysicalVolumeBootFile..."L]; Process.Pause[Process.SecondsToTicks[5]]; }; SetPhysicalVolumeBootFile[cap, hardMicrocode, 0]; CloseVolume[]; END; PostComment: FileTransfer.MessageProc = BEGIN IF ~ILT.toolData.busy THEN RETURN; IF level > terse THEN Post[ILT.toolData.msgSW, s1, s2, s3, s4]; Post[ILT.toolData.fileSW, s1, s2, s3, s4]; END; --PostComment Post: PROCEDURE [w: Window.Handle, s1, s2, s3, s4: LONG STRING] = BEGIN IF s1 # NIL THEN Put.LongString[w, s1]; IF s2 # NIL THEN Put.LongString[w, s2]; IF s3 # NIL THEN Put.LongString[w, s3]; IF s4 # NIL THEN Put.LongString[w, s4]; END; --Post Retrieve: PROC [file: File.Capability, name: LONG STRING] RETURNS [gotIt: BOOLEAN _ TRUE] = BEGIN OPEN FileTransfer; ResumeSetup: PORT [BOOLEAN] RETURNS [file: File.Capability, name: LONG STRING]; --original source --bufferPages: Space.PageCount = 64; bufferPages: Space.PageCount = 100; bufferBytes: CARDINAL; base: LONG POINTER _ NIL; --conn: Connection _ FileTransfer.Create[]; --conn: Connection _ ILT.toolData.connection; fileSize: File.PageCount _ ILT.toolData.vMemSize; size: File.PageCount; sysoutSize: File.PageCount; -- CONNECT ResumeSetup.out TO GetFile LOOPHOLE[ResumeSetup, PortRep].out _ @GetFile; -- CONNECT GetFile.out TO ResumeSetup LOOPHOLE[GetFile, PortRep].out _ @ResumeSetup; bufferBytes _ bufferPages*Environment.bytesPerPage; IF debug THEN { Put.Line[ILT.toolData.fileSW, "Enter Retrieve"L]; Process.Pause[Process.SecondsToTicks[5]]; }; << FileTransfer.SetProcs[ conn: conn, clientData: NIL, messages: PostComment, login: NIL, checkAbort: CheckForAbort]; >> IF debug THEN { Put.Line[ILT.toolData.fileSW, "AllocVFN..."L]; Process.Pause[Process.SecondsToTicks[5]]; }; vfn _ AllocVFN[name]; IF debug THEN { Put.Line[ILT.toolData.fileSW, "ReadStream...."L]; Process.Pause[Process.SecondsToTicks[5]]; }; readStream _ conn.ReadStream[ files: vfn ! Error => {gotIt _ FALSE; CONTINUE}]; IF ~gotIt THEN {Cleanup[]; GOTO noGood}; -- FileTransfer has ML bug! IF debug THEN { Put.Line[ILT.toolData.fileSW, "ResumeSetup...."L]; Process.Pause[Process.SecondsToTicks[5]]; }; [file, ] _ ResumeSetup[gotIt]; IF debug THEN { Put.Line[ILT.toolData.fileSW, "sysoutSize...."L]; Process.Pause[Process.SecondsToTicks[5]]; }; sysoutSize _ (FileTransfer.GetStreamInfo[readStream].size + Environment.bytesPerPage - 1)/Environment.bytesPerPage; Put.Text[ILT.toolData.fileSW, "Sysout size = "]; Put.LongDecimal[ILT.toolData.fileSW, sysoutSize]; Put.Text[ILT.toolData.fileSW, " pages; "]; Put.LongDecimal[ILT.toolData.fileSW, sysoutSize*512]; Put.Line[ILT.toolData.fileSW, " bytes."]; -- set up initial default size << IF LOOPHOLE[ILT.GetFileSize, CARDINAL] = 0 THEN ILT.toolData.vMemSize _ defaultVMemSize; >> IF (ILT.toolData.vMemSize < sysoutSize) AND (ILT.toolData.vMemSize > 0) THEN BEGIN Put.Line[ ILT.toolData.msgSW, "Virtual memory smaller than Sysout size, please respecify."L]; --size _ ILT.GetFileSize[]; --ILT.DisplayFileSize[size]; --CloseVolume[]; RETURN[FALSE]; END; IF debug THEN { Put.Line[ILT.toolData.fileSW, "SetSize...."L]; Process.Pause[Process.SecondsToTicks[5]]; }; IF ILT.toolData.vMemSize = 0 THEN fileSize _ defaultVMemSize; File.SetSize[ file, fileSize ! Volume.InsufficientSpace => { Put.Line[ILT.toolData.fileSW, " Not enough room for file!"L]; Cleanup[]; GOTO noGood}]; IF debug THEN { Put.Line[ILT.toolData.fileSW, "Create...."L]; Process.Pause[Process.SecondsToTicks[5]]; }; space _ Space.Create[ bufferPages, Space.virtualMemory ! Space.InsufficientSpace => { Put.Line[ILT.toolData.fileSW, " Insufficient Disk Space!"L]; Process.Pause[Process.SecondsToTicks[10]]; Cleanup[]; GOTO noGood}; ]; IF debug THEN { Put.Line[ILT.toolData.fileSW, "Map...."L]; Process.Pause[Process.SecondsToTicks[5]]; }; Space.Map[ space ! Volume.InsufficientSpace => { Put.Line[ILT.toolData.fileSW, " Insufficient disk space!"L]; Process.Pause[Process.SecondsToTicks[10]]; Cleanup[]; GOTO noGood}; ]; Space.CreateUniformSwapUnits[size: 16, parent: space]; --original source --Space.CreateUniformSwapUnits[size: 4, parent: space]; base _ Space.LongPointer[space]; FOR windowPage: Space.PageOffset _ 0, windowPage + bufferPages WHILE windowPage < Inline.LowHalf[sysoutSize] DO bytesTransferred: LONG INTEGER; bytesTransferred _ readStream.GetBlock[ [base, 0, bufferBytes]].bytesTransferred; Space.CopyOut[space, [file, windowPage]]; byteCount _ byteCount + bytesTransferred; Put.Text[ILT.toolData.msgSW, "Bytes transfered: "]; Put.LongDecimal[ILT.toolData.msgSW, byteCount]; Put.CR[ILT.toolData.msgSW]; ILT.InvertIndicator[]; ENDLOOP; Cleanup[]; RETURN[TRUE]; EXITS noGood => RETURN[FALSE] END; --Retrieve SetVolumeProc: PUBLIC PROCEDURE [vName: LONG STRING] RETURNS [BOOLEAN] = BEGIN OPEN OthelloOps; cap: File.Capability; firstPage: File.PageNumber; created: BOOLEAN _ FALSE; IF debug THEN { Put.Line[ILT.toolData.fileSW, "Enter SetVolume Proc "L]; Put.LongString[ILT.toolData.fileSW, vName]; --Process.Pause[Process.SecondsToTicks[5]]; }; [volumeID, volumeOpen] _ ILT.GetVolumeID[vName]; IF volumeID = Volume.nullID THEN RETURN[FALSE]; IF debug THEN { Put.Line[ILT.toolData.fileSW, "GetVolumeBootFile....."L]; Process.Pause[Process.SecondsToTicks[5]]; }; [cap, firstPage] _ GetVolumeBootFile[volumeID, hardMicrocode]; IF cap # File.nullCapability THEN BEGIN ENABLE File.Unknown => {cap _ File.nullCapability; CONTINUE}; IF File.GetAttributes[cap].immutable THEN BEGIN pvID: PhysicalVolume.ID = PhysicalVolume.GetContainingPhysicalVolume[volumeID]; IF debug THEN { Put.Line[ILT.toolData.fileSW, "file immutable....."L]; Process.Pause[Process.SecondsToTicks[5]]; }; File.DeleteImmutable[cap, volumeID]; VoidVolumeBootFile[volumeID, hardMicrocode]; IF GetPhysicalVolumeBootFile[pvID, hardMicrocode].cap = cap THEN VoidPhysicalVolumeBootFile[pvID, hardMicrocode]; cap _ File.nullCapability END END; IF (created _ cap = File.nullCapability) THEN BEGIN Put.Line[ILT.toolData.msgSW, " No Sysout file installed."L]; RETURN[FALSE]; --cap _ File.Create[volumeID, 0, FileTypes.tUntypedFile]; END ELSE MakeUnbootable[ cap, hardMicrocode, firstPage ! TemporaryBooting.InvalidParameters => BEGIN Put.Text[ ILT.toolData.msgSW, "Warning: trouble making unbootable"L]; CONTINUE; END]; IF debug THEN { Put.Text[ILT.toolData.fileSW, "SetVolumeBootFile..."L]; Process.Pause[Process.SecondsToTicks[5]]; }; SetVolumeBootFile[cap, hardMicrocode, 0]; File.MakePermanent[cap]; MakeBootable[ cap, hardMicrocode, 0 ! TemporaryBooting.InvalidParameters => BEGIN Put.Text[ ILT.toolData.msgSW, "Warning: trouble making bootable"L]; CONTINUE; END]; IF debug THEN { Put.Text[ILT.toolData.fileSW, "SetPhysicalVolumeBootFile..."L]; Process.Pause[Process.SecondsToTicks[5]]; }; SetPhysicalVolumeBootFile[cap, hardMicrocode, 0]; CloseVolume[]; RETURN[TRUE]; END; --SetVolumeProc -- This procedure validates the syntax for the file name used by NS file server . -- Allowable string is an -- alpha-numeric string beginning with a capital or small letter ['A .. 'Z] -- followed by any number (up to maxStringSize) of letters or numbers. ValidateString: PROC [sName: LONG STRING] RETURNS [BOOLEAN] = BEGIN currentString: STRING = [maxStringSize]; currentChar: CARDINAL _ 0; c: CHARACTER; maxStringSize: CARDINAL = NSName.maxFullNameLength; -- bytes CheckChar: PROC[] RETURNS [BOOLEAN] = BEGIN IF currentString.length >= maxStringSize THEN BEGIN Put.Line[ILT.toolData.msgSW, "Scan Error: string length too long"L]; Put.LongString[ILT.toolData.msgSW, sName]; Put.CR[ILT.toolData.msgSW]; RETURN[FALSE]; END; currentString.text[currentString.length] _ c; currentString.length _ currentString.length + 1; currentChar _ currentChar + 1; RETURN[TRUE]; END; --CheckChar IF debug THEN { Put.Line[ILT.toolData.fileSW, "ValidateString"L]; Put.Text[ILT.toolData.fileSW, sName]; Put.CR[ILT.toolData.fileSW]; Process.Pause[Process.SecondsToTicks[5]]; }; WHILE (currentChar < sName.length) DO c _ sName.text[currentChar]; --Put.Char[ILT.toolData.fileSW, c]; --Process.Pause[Process.SecondsToTicks[5]]; SELECT ILT.toolData.fileServer FROM NS => BEGIN IF (c = '- OR c = '* OR c = '@ OR c = ': OR c = Ascii.SP OR c = '[ OR c = '] OR c = '< OR c = '> OR c IN ['a..'z] OR c IN ['A..'Z] OR c IN ['0..'9]) THEN RETURN[CheckChar[]] ELSE BEGIN Put.Text[ILT.toolData.msgSW, "Scan Error on: "L]; Put.LongString[ILT.toolData.msgSW, sName]; Put.Text[ILT.toolData.fileSW, " Bad character detected: "]; Put.Char[ILT.toolData.fileSW, c]; RETURN[FALSE]; END; END; IFS => BEGIN IF (c = '- OR c = '* OR c = '@ OR c = Ascii.SP OR c = '[ OR c = '] OR c = '< OR c = '> OR c IN ['a..'z] OR c IN ['A..'Z] OR c IN ['0..'9]) THEN RETURN[CheckChar[]] ELSE BEGIN Put.Line[ILT.toolData.fileSW, "Scan Error"L]; Put.LongString[ILT.toolData.fileSW, sName]; RETURN[FALSE]; END; END; ENDCASE; ENDLOOP; RETURN[TRUE]; END; --ValidateString END. --ILTInstallImpl