--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