BEGIN
ENABLE NSExec.Error => IF type = invalidExec THEN GOTO Exit;
tty: TTY.Handle ← NSExec.GetTTY[exec];
outputHandle: XFormat.Handle ← NSExec.OutputHandle[exec];
UserAbort: ERROR = CODE;
SendDataError: ERROR = CODE;
Answer: TYPE = {no, yes, cancel}; -- no: skip and go to next, yes: do it, cancel: abort it.
CommandType:
TYPE = {
nullcommand, closeFile, createFile, loadAll, loadPiece, requestVolume};
Command: TYPE = REF CommandRecord;
CommandRecord:
TYPE =
RECORD [
type: CommandType ← nullcommand, parameter: NSString.String ← NIL];
floppyHandle: Floppy.VolumeHandle ← Floppy.nullVolumeHandle; -- floppy volume handle.
nullFloppyFileHandle: Floppy.FileHandle ← [
Floppy.nullVolumeHandle, Floppy.nullFileID];
null floppy file handle, should be updated when a floppy is opened or closed.
DataType: TYPE = {font, testPattern};
FloppyFileContext: TYPE = LONG POINTER TO FloppyFileContextRecord;
FloppyFileContextRecord: TYPE = RECORD [
id: Floppy.FileHandle ← nullFloppyFileHandle, -- File handle on floppy
attributes: AccessFloppy.Attributes ← NIL, -- Floppy File Attributes
fileName: LONG STRING ← NIL,
nsFileName: NSString.String ← NSString.nullString,
File names indicate destination file in case of multi-floppy fonts and, thus, may not be the name of the file with the given id.
dataType: DataType ← font];
State: TYPE = REF StateRecord;
StateRecord:
TYPE =
RECORD [
nameDest: NSString.String ← NSString.nullString,
nameDest: LONG STRING ← NIL,
sizeDest: File.PageCount ← 0, -- target file size
sizeMapped: File.PageCount ← 0, -- actual size, use to check consistency of the destination file.
create: BOOLEAN ← FALSE, -- set by Create File
close: BOOLEAN ← FALSE, -- set by CloseFile, AnounceEndOfData.
version: Version ← new, -- *MT in case of Error for multi-floppies.
length: CARDINAL ← 0, -- number of source file pieces
piece: SEQUENCE maxlength: [0..LAST[CARDINAL]) OF FilePiece];
FilePiece:
TYPE =
RECORD [
vol: NSString.String ← NIL, base: File.PageNumber ← [0], size: File.PageCount ← 0];
Version: TYPE = {new, newer, same, older};
scriptName: NSString.String = "FontScript.";
nullSinkStream: NSDataStream.SinkStream = [[NIL]];
GLOBAL VARIABLES:
floppyFile: FloppyFileContextRecord ← [];
attributes: AccessFloppy.Attributes ← NIL;
This attributes is used by all floppy file (except script file). Storage is created when confirmation is made to load a floppy first time and the space is freed before exits from LoadFileFromFloppy.
labelString: LONG STRING ← [Floppy.maxCharactersInLabel]; -- floppy label string
nFontsInstalled: CARDINAL ← 0; -- total number of fonts installed.
nTestPatternsInstalled: CARDINAL ← 0; -- total number of test patterns installed.
Used during script interpretation:
state: State ← NIL;
scriptFile: FloppyFileContext ← NIL;
Remember the file context of the script file.
scriptPointer: LONG POINTER ← NIL;
Points to script file in VM.
scriptBuffer: LONG POINTER TO PACKED ARRAY [0..0) OF CHARACTER ← NIL;
For reading characters from script file.
scriptBytesRead: LONG CARDINAL ← 0;
scriptOffset: CARDINAL ← 0; -- Next char to read from script file.
scriptCommand: Command ← NIL; --Points to command just read from script file.
scriptInterpretationMode: BOOLEAN ← FALSE; -- Whether it is in the script - interpretation mode.
firstPieceFile: BOOLEAN ← FALSE; --Whether piece file is first one for given font.
waitChange: CARDINAL ← 3000; -- m sec. to wait for change floppy
systemAbort: BOOLEAN ← FALSE; --Set to true in SendFloppyData if data stream is aborted by receiver; referenced in LoadPiece.
Variables used by mainline code of InstallFromFloppy
continue: TextInput.YesOrNo ← TextInput.nilYesNo;
psState: PSState.StateHandle ← PSCommand.GetPrintServiceStatus[];
Procedures for Processing Script
AbortInstall: PROCEDURE [displayMsg: BOOLEAN ← TRUE, dataSink: NSDataStream.SinkStream ← nullSinkStream] RETURNS [NSDataStream.SinkStream] = BEGIN
IF ~state.close THEN BEGIN
state.close ← TRUE;
IF displayMsg THEN BEGIN
outputHandle.CR[];
outputHandle.NSLine[M[mFloppyCanceled]];
END;
IF dataSink # nullSinkStream THEN BEGIN
NSDataStream.Abort[dataSink ! NSDataStream.Aborted => CONTINUE];
Stream.Delete[dataSink ! NSDataStream.Aborted => CONTINUE];
END;
END;
RETURN [nullSinkStream];
END; -- AbortInstall
AnnounceEndOfData: PROCEDURE [dataSink: NSDataStream.SinkStream] RETURNS [NSDataStream.SinkStream] = BEGIN
IF ~state.close THEN BEGIN
state.close ← TRUE;
IF dataSink # nullSinkStream THEN
Stream.Delete[dataSink ! NSDataStream.Aborted => CONTINUE];
END;
RETURN [nullSinkStream];
END; -- AnnounceEndOfData
BeginInterprete:
PROCEDURE
RETURNS [ok:
BOOLEAN] =
BEGIN
-- Read Script File... map script file into VM
endOfScript: BOOLEAN ← FALSE;
ok ← TRUE;
systemAbort ← FALSE; --global var
scriptPointer ← Space.ScratchMap[scriptFile.attributes.totalSize];
Floppy.Read[scriptFile.id, AccessFloppy.leaderLength,
scriptFile.attributes.totalSize, scriptPointer !
Floppy.Error, Floppy.DataError => {
scriptPointer ← Space.Unmap[scriptPointer]; REJECT}];
scriptBuffer ← scriptPointer;
STATE.CREATE AND STATE.CLOSE:
Initial state: state.create = FALSE, state.close = FALSE.
After LoadPiece has been called to send first floopy's data: state.create = TRUE, state.close = FALSE.
After CloseFile or AnnounceEndOfData is called: state.create = TRUE, state.close = TRUE: This initial state causes NOP.
After EndInterprete has been executed: state.create = FALSE, state.close = TRUE.
state ← NEW[StateRecord[30--10--]]; --*MT
state.nameDest ← NIL;
state.sizeDest ← 0;
state.sizeMapped ← 0;
state.create ← FALSE;
state.close ← FALSE;
state.length ← 0;
Allocate buffer for storing 30 (← 10 *MT) file - piece information.
scriptInterpretationMode ← TRUE;
scriptBytesRead ← 0;
scriptOffset ← 0;
scriptCommand ← NEW[CommandRecord];
scriptCommand.parameter ← NSString.MakeString[AccessFloppy.maxNameLength];
[endOfScript,] ← GetCommand[];
UNTIL endOfScript OR ~ok DO
SELECT scriptCommand.type FROM
createFile => {
ok ← CreateFileName[scriptCommand.parameter]; EXIT};
requestVolume =>
ok ← RequestVolume[scriptCommand.parameter,];
ENDCASE => GOTO Exit;
[endOfScript,] ← GetCommand[];
ENDLOOP;
IF NOT endOfScript AND ok THEN
[endOfScript,] ← GetCommand[];
UNTIL endOfScript OR ~ok DO
SELECT scriptCommand.type FROM
loadPiece => {
ok ← SetPieceFileContext[scriptCommand.parameter,];
firstPieceFile ← TRUE; EXIT};
requestVolume =>
ok ← RequestVolume[scriptCommand.parameter,];
ENDCASE => GOTO Exit;
[endOfScript,] ← GetCommand[];
ENDLOOP;
IF endOfScript THEN GOTO Exit;
EXITS Exit => NULL;
EXITS Exit => {[] ← AbortInstall[]; RETURN [ok ← FALSE]};
END; -- BeginInterprete.
CheckInstalledFont: PSCommand.FontProc =
BEGIN
[type, packageName, sizeInBytes, createDate] RETURNS [continue]--
retries: CARDINAL ← 0;
sizeInPages: LONG CARDINAL ←
(sizeInBytes + PrincOps.bytesPerPage - 1)/PrincOps.bytesPerPage;
IF (state.sizeDest > state.sizeMapped OR state.sizeDest > sizeInPages)
AND state.version # same THEN --ignore the overwritten part if file is the same??
PSCommand.DeleteFont[packageName
! PSCommand.Error => WITH problem SELECT FROM
disallowedInCurrentMode => IF retries = 3
THEN {nFontsInstalled ← nFontsInstalled + 1; CONTINUE}
ELSE {retries ← retries + 1; RETRY};
ENDCASE
]
ELSE nFontsInstalled ← nFontsInstalled + 1;
RETURN [FALSE];
END; --CheckInstalledFont
EnterScriptMode:
PROCEDURE =
BEGIN
continue: BOOLEAN ← TRUE;
fontPackageName: NSString.String ← NSString.nullString;
BEGIN
ENABLE
UNWIND =>
{IF fontPackageName # NSString.nullString THEN
PSCommand.DeleteFont[fontPackageName !PSCommand.Error => CONTINUE];
FreeGlobalSpace[]};
scriptFile ← NEW[FloppyFileContextRecord];
attributes recored of script floppy file.
scriptFile.attributes ← NEW[
AccessFloppy.AttributesRecord[AccessFloppy.maxDataSize]];
scriptFile.nsFileName ← Str[scriptName];
scriptFile.id ← AccessFloppy.LookUp[
scriptFile.nsFileName, scriptFile.attributes];
AccessFloppy.GetAttributes[scriptFile.id, scriptFile.attributes];
IF IsPieceFile[scriptFile.attributes] THEN {
outputHandle.CR[];
outputHandle.NSLine[M[mFloppyIncompleteScript]];
RETURN};
scriptFile.fileName ← scriptName;
Enter Script-interpretation Mode...
continue ← BeginInterprete[];
IF continue
AND state.nameDest #
NIL
THEN BEGIN
fontPackageName ← Str[state.nameDest];
PSCommand.InstallFont[
type: cdFont,
packageName: fontPackageName,
createDate: floppyFile.attributes.createDate,
data: [proc[InterpreteScript]],
packageSizeHintInBytes: floppyFile.attributes.totalSizeInBytes
! PSCommand.Error => {
WITH p: problem SELECT FROM
abortedByClient => NULL;
insufficientSpace => {
outputHandle.Blanks[4];
outputHandle.NSLine[M[mFloppyErrInsufficientVolSpace], 2];
outputHandle.NSLine[M[mFloppyCanceled]]};
disallowedInCurrentMode => BEGIN
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
nsFreeThisString: NSString.String;
stringArray[0] ← M[mInstallFonts];
nsFreeThisString ← XMessage.Compose[M[mConflictingMode], stringArray];
outputHandle.NSLine[nsFreeThisString];
NSString.FreeString[nsFreeThisString];
END;
documentInProgress => BEGIN
We CAN get here since, with the advent of remote administration,
two users may be logged at the same time. One could start printing
before the other finishes installing fonts.
stringArray: REF XMessage.StringArray ← NEW[XMessage.StringArray[2]];
nsFreeThisString: NSString.String;
outputHandle.NSLine[M[mDocInProgress]];
stringArray[0] ← M[mInstallFonts];
nsFreeThisString ← XMessage.Compose[M[mPleaseStopPrinting], stringArray];
outputHandle.NSLine[nsFreeThisString];
NSString.FreeString[nsFreeThisString];
END;
ENDCASE => {
outputHandle.CR[];
outputHandle.NSLine[M[mFloppyCanceled]]};
CONTINUE}];
Exit Script-interpretation Mode...
EndInterprete[fontPackageName];
END; --Enable Clause and code
END; --EnterScriptMode.
EndInterprete:
PROCEDURE [fontPackageName: NSString.String] =
BEGIN
IF state.create
AND fontPackageName # NSString.nullString
THEN
PSCommand.ListFonts[proc: CheckInstalledFont, filter: [packageName: fontPackageName]];
FreeGlobalSpace[];
scriptInterpretationMode ← FALSE;
END; -- EndInterprete.
FreeGlobalSpace:
PROCEDURE =
TRUSTED
BEGIN
IF scriptPointer #
NIL
THEN
scriptPointer ← Space.Unmap[scriptPointer];
scriptBuffer ← NIL;
IF scriptCommand #
NIL
THEN
BEGIN
IF scriptCommand.parameter #
NIL
THEN
NSString.FreeString[scriptCommand.parameter];
FREE[@scriptCommand];
END;
IF state #
NIL
THEN
BEGIN
IF state.nameDest # NIL THEN NSString.FreeString[state.nameDest];
FOR i:
CARDINAL
IN [0..state.length)
DO
IF state.piece[i].vol #
NIL
THEN
NSString.FreeString[state.piece[i].vol];
ENDLOOP;
FREE[@state];
END;
IF scriptFile # NIL THEN BEGIN
IF scriptFile.attributes # NIL THEN FREE[@scriptFile.attributes];
FREE[@scriptFile];
END;
END; --FreeGlobalSpace
GetCommand: PRIVATE PROCEDURE [dataSink: NSDataStream.SinkStream ← nullSinkStream] RETURNS [eof: BOOLEAN, returnDataSink: NSDataStream.SinkStream] = BEGIN
error: BOOLEAN ← FALSE;
node1: NSString.String ← NEW[TEXT[8]];
node2: NSString.String ← NEW[TEXT[8]];
ReadChar: PROC RETURNS [newChar: CHARACTER, end: BOOLEAN] = BEGIN
end ← FALSE;
newChar ← scriptBuffer[scriptOffset];
scriptOffset ← scriptOffset + 1;
IF (scriptBytesRead ← scriptBytesRead + 1) = scriptFile.attributes.totalSizeInBytes THEN
end ← TRUE;
END; -- ReadChar
Token: PROC [string: LONG STRING, parameterToken: BOOLEAN ← FALSE] = BEGIN
"parameterToken" indicates whether the token begin read in is a parameter (e.g. file name), rather than a command. IF so, a space does not indicate the end of the token and double quotes are regarded as token delimiters.
space: CHARACTER = 40C;
cr: CHARACTER = 15C;
semicolon: CHARACTER = 73C;
doubleQuote: CHARACTER = 42C;
i: CARDINAL ← 0;
newChar: CHARACTER ← 40C;
string.length ← 0;
skip delimiting characters
UNTIL eof DO
[newChar, eof] ← ReadChar[];
IF (newChar # cr) AND (newChar # semicolon) AND
(newChar # space) AND ((newChar # doubleQuote) OR NOT parameterToken) THEN
EXIT
ENDLOOP;
FOR i IN [0..string.maxlength) UNTIL eof DO
NSString.AppendCharacter[string, newChar];
[newChar, eof] ← ReadChar[];
IF (newChar # cr) AND (newChar # semicolon) AND
((newChar # space) OR parameterToken) AND
((newChar # doubleQuote) OR NOT parameterToken) THEN
LOOP
ELSE EXIT;
ENDLOOP;
END; --Token
eof ← FALSE;
Token[node1];
IF eof THEN RETURN [eof, dataSink];
Token[node2];
IF eof THEN RETURN [eof, dataSink];
Token[string: scriptCommand.parameter, parameterToken: TRUE]; --Spaces are allowed in file names.
SELECT TRUE FROM
NSString.EqualStrings[node1, "Load"] => {
SELECT TRUE FROM
NSString.EqualStrings[node2, "All"] => scriptCommand.type ← loadAll;
NSString.EqualStrings[node2, "Piece"] => scriptCommand.type ← loadPiece;
ENDCASE => error ← TRUE};
NSString.EqualStrings[node1, "Request"] =>
IF NSString.EqualStrings[node2, "Volume"] THEN
scriptCommand.type ← requestVolume
ELSE error ← TRUE;
NSString.EqualStrings[node1, "Create"] =>
IF NSString.EqualStrings[node2, "File"] THEN scriptCommand.type ← createFile
ELSE error ← TRUE;
NSString.EqualStrings[node1, "Close"L] =>
IF NSString.EqualStrings[node2, "File"] THEN scriptCommand.type ← closeFile
ELSE error ← TRUE;
ENDCASE => error ← TRUE;
IF error THEN {
outputHandle.CR[];
outputHandle.NSLine[M[mFloppyScriptError]];
dataSink ← AbortInstall[,dataSink];
eof ← error};
RETURN [eof, dataSink];
END; -- GetCommand
InterpreteScript: PROCEDURE [dataSink: NSDataStream.SinkStream] = BEGIN
ENABLE BEGIN
UNWIND => {
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];;
outputHandle.CR[];
stringArray[0] ← M[mFloppyErrUnknown];
PSExecInternal.ExpandKeyAndPrint[exec, mFloppyError, stringArray];
outputHandle.CR[];
dataSink ← AbortInstall[,dataSink];
};
AccessFloppy.Error => { --NOTE: add error messages specific to AccessFloppy for next release.
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
outputHandle.CR[];
stringArray[0] ← M[
SELECT type FROM
volumeNotOpen => mFloppyErrVolumeNotOpen,
fileNotFound => mFloppyFileError, --NOTE: add a better message for next release
ENDCASE => mFloppyErrUnknown];
PSExecInternal.ExpandKeyAndPrint[exec, mFloppyError, stringArray];
outputHandle.CR[];
IF type = volumeNotOpen THEN {
floppyHandle ← Floppy.nullVolumeHandle;
nullFloppyFileHandle ← [floppyHandle, Floppy.nullFileID]};
GOTO Abort};
Floppy.Error => {
stringArray: ARRAY [0..1) OF NSString.String;
outputHandle.CR[];
stringArray[0] ← M[
SELECT error FROM
badDisk => mFloppyErrBadDisk,
badSectors => mFloppyErrBadSectors,
hardwareError => mFloppyErrHardware,
invalidVolumeHandle => mFloppyErrInvalidVolumeHandle,
needsScavenging => mFloppyErrNeedsScavenging,
noSuchDrive => mFloppyErrNoSuchDrive,
notReady => mFloppyErrNotReady,
stringTooShort => mFloppyErrStringTooShort,
volumeNotOpen => mFloppyErrVolumeNotOpen,
ENDCASE => mFloppyErrUnknown];
PSExecInternal.ExpandKeyAndPrint[exec, mFloppyError, DESCRIPTOR[stringArray]];
outputHandle.CR[];
floppyHandle ← Floppy.nullVolumeHandle;
nullFloppyFileHandle ← [floppyHandle, Floppy.nullFileID];
GOTO Abort};
END; --Enable Clause
end: BOOLEAN ← FALSE;
ok: BOOLEAN ← TRUE;
IF dataSink = nullSinkStream THEN RETURN;
[ok, dataSink] ← LoadPiece[scriptCommand.parameter, dataSink];
[end, dataSink] ← GetCommand[dataSink];
UNTIL end OR ~ok DO -- end = TRUE if end of file
SELECT scriptCommand.type FROM
loadPiece => [ok, dataSink] ← LoadPiece[scriptCommand.parameter, dataSink];
loadAll => [ok, dataSink] ← LoadAll[scriptCommand.parameter, dataSink]; --not implemented
closeFile => [ok, dataSink] ← CloseFile[scriptCommand.parameter, dataSink];
requestVolume => [ok, dataSink] ← RequestVolume[scriptCommand.parameter, dataSink];
ENDCASE => {
outputHandle.CR[];
outputHandle.NSLine[M[mFloppyScriptError]];
GOTO Abort};
[end, dataSink] ← GetCommand[dataSink];
ENDLOOP;
dataSink ← AnnounceEndOfData[dataSink];
EXITS Abort => dataSink ← AbortInstall[,dataSink];
END; -- InterpreteScript
SetPieceFileContext: PROCEDURE [str: NSString.String, dataSink: NSDataStream.SinkStream ← nullSinkStream] RETURNS [ok: BOOLEAN, returnDataSink: NSDataStream.SinkStream] = BEGIN
floppyFile ← [];
floppyFile.attributes ← attributes;
floppyFile.fileName ← str;
floppyFile.nsFileName ← Str[str];
floppyFile.id ← AccessFloppy.LookUp[
floppyFile.nsFileName, floppyFile.attributes];
IF ~IsPieceFile[floppyFile.attributes] THEN
BEGIN
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
stringArray[0] ← floppyFile.nsFileName;
outputHandle.CR[];
PSExecInternal.ExpandKeyAndPrint[exec, mFloppyNotFilePiece, stringArray];
dataSink ← AbortInstall[,dataSink];
RETURN [ok ← FALSE, dataSink];
END
ELSE RETURN [ok ← TRUE, dataSink];
END; --SetPieceFileContext
command interpreter.
CloseFile:
PRIVATE
PROCEDURE [str: NSString.String]
RETURNS [ok:
BOOLEAN] =
BEGIN
ok ← NSString.EqualStrings[str, state.nameDest];
IF ok THEN dataSink ← AnnounceEndOfData[dataSink]
ELSE dataSink ← AbortInstall[dataSink];
RETURN [ok, dataSink];
CreateFileName:
PROCEDURE [str: NSString.String]
RETURNS [ok:
BOOLEAN] =
BEGIN
ok ← TRUE;
state.nameDest ← NSString.MakeString[str.length];
NSString.AppendString[state.nameDest, str.length];
END; -- CreateFileName
LoadPiece will only load file piece.
LoadPiece: PRIVATE PROCEDURE [str: LONG STRING, dataSink: NSDataStream.SinkStream]
RETURNS [ok: BOOLEAN, returnDataSink: NSDataStream.SinkStream] = BEGIN
ok ← TRUE;
IF ~firstPieceFile THEN BEGIN
[ok, dataSink] ← SetPieceFileContext[str, dataSink];
IF ~ok THEN GOTO Exit;
END;
IF WindowOverlay[] THEN GOTO Exit;
UpdateSourceState[];
IF firstPieceFile THEN BEGIN
floppyFile.fileName ← state.nameDest;
floppyFile.nsFileName ← Str[state.nameDest];
File name now indicates name of destination file rather that floppy file.
SELECT LoadConfirmation[] FROM
no, cancel => {
dataSink ← AbortInstall[displayMsg: FALSE, dataSink: dataSink];
RETURN [ok ← FALSE, dataSink]};
ENDCASE;
END;
SendFloppyData[dataSink ! SendDataError =>
{dataSink ← nullSinkStream; GOTO Exit}];
IF systemAbort THEN RETURN [ok ← FALSE, dataSink ← nullSinkStream];
Stream was aborted by receiver. Error will be raised by PSCommand.InstallFont.
IF firstPieceFile THEN BEGIN
state.sizeDest ← floppyFile.attributes.totalSize;
state.create ← TRUE;
firstPieceFile ← FALSE;
END;
state.sizeMapped ← state.sizeMapped + floppyFile.attributes.size;
RETURN [ok, dataSink];
EXITS Exit => {dataSink ← AbortInstall[,dataSink];
RETURN [ok ← FALSE, dataSink]};
LoadAll: PRIVATE PROCEDURE [str: LONG STRING, dataSink: NSDataStream.SinkStream] RETURNS [ok: BOOLEAN, returnDataSink: NSDataStream.SinkStream] = BEGIN
This procedure implements the merge function of prepress file. This is used to merge multiple font files into a destinateion font file (created by Create File). Note: NOT font PIECES.
RETURN [ok ← TRUE, dataSink];
END; -- LoadAll.
RequestVolume:
PRIVATE
PROCEDURE [str: NSString.String]
RETURNS [ok:
BOOLEAN] =
BEGIN
IF the requested volume is not online then request it, online, and save state otherwise RETURN.
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
maxRetry: CARDINAL = 3;
i: CARDINAL ← 0;
displayMsg: BOOLEAN ← TRUE; --Indicates whether to display canceled msg on abort.
AwaitFloppyChange: PROC = BEGIN OPEN FloppyChannel;
^^^ Copied from PromOpsImpl.mesa if the floppy is ready, wait until it goes notReady first
UNTIL FloppyChannel.Nop[
FloppyChannel.GetHandle[0] !
FloppyChannel.Error => IF type = invalidHandle THEN RETRY] = notReady DO
Process.Pause[Process.MsecToTicks[waitChange]]; ENDLOOP;
UNTIL FloppyChannel.Nop[
FloppyChannel.GetHandle[0] !
FloppyChannel.Error => IF type = invalidHandle THEN RETRY] # notReady DO
Process.Pause[Process.MsecToTicks[waitChange]]; ENDLOOP;
END; -- of AwaitFloppyChange
IF ok ← NSString.EqualStrings[str, labelString] THEN RETURN [ok, dataSink] --##MT
ELSE OfflineFP0[];
FOR i
IN [0..maxRetry)
DO
outputHandle.CR[];
stringArray[0] ← Str[str];
PSExecInternal.ExpandKeyAndPrint[exec,
mFloppyPleaseRemoveAndInsert, stringArray];
AwaitFloppyChange[];
OpenVolume[labelString !
Floppy.Error => {
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
outputHandle.CR[];
stringArray[0] ← M[
SELECT error FROM
hardwareError => mFloppyErrHardware,
invalidVolumeHandle => mFloppyErrInvalidVolumeHandle,
needsScavenging => mFloppyErrNeedsScavenging,
ENDCASE => mFloppyErrUnknown];
PSExecInternal.ExpandKeyAndPrint[exec, mFloppyError, stringArray];
floppyHandle ← Floppy.nullVolumeHandle;
nullFloppyFileHandle ← [floppyHandle, Floppy.nullFileID];
EXIT};
UserAbort => {displayMsg ← FALSE; EXIT}
];
IF NSString.EqualStrings[str, labelString] THEN RETURN [TRUE, dataSink] ELSE OfflineFP0[];
ENDLOOP;
by here, failed!
dataSink ← AbortInstall[displayMsg, dataSink];
RETURN [ok ← FALSE, dataSink];
END; -- RequestVolume
UpdateSourceState:
PROCEDURE =
BEGIN
i: CARDINAL ← state.length;
state.piece[i].vol ← NSString.MakeString[labelString.maxlength];
NSString.CopyString[to: state.piece[i].vol, from: labelString];
state.piece[i].base ← floppyFile.attributes.offset;
state.piece[i].size ← floppyFile.attributes.size;
state.length ← i + 1;
END; -- UpdateSourceState
WindowOverlay:
PROCEDURE
RETURNS [overlay:
BOOLEAN] =
BEGIN
overlay ← FALSE;
FOR i:
CARDINAL
IN [0..state.length)
UNTIL overlay
DO
SELECT TRUE FROM
state.piece[i].base = floppyFile.attributes.offset => overlay ← TRUE;
state.piece[i].base < floppyFile.attributes.offset =>
IF state.piece[i].base + state.piece[i].size <=
floppyFile.attributes.offset THEN LOOP
ELSE overlay ← TRUE;
ENDCASE =>
IF floppyFile.attributes.offset + floppyFile.attributes.size
<= state.piece[i].base THEN LOOP
ELSE overlay ← TRUE;
ENDLOOP;
END; -- WindowOverlay
End of script processing procedures.
DisplayDates:
PROCEDURE
RETURNS [version: Version ← new] =
BEGIN
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
DisplayCurrentDate:
PROCEDURE [createDate: BasicTime.
GMT] =
BEGIN
nsDateAndTime.length ← 0;
XFormat.Date[nsDateTimeObject, createDate]; --appends createDate to nsDataAndTime
stringArray[0] ← nsDateAndTime;
PSExecInternal.ExpandKeyAndPrint[exec, mRDFileCreated, stringArray];
version ←
SELECT TRUE FROM
(createDate < floppyFile.attributes.createDate) => newer,
(createDate = floppyFile.attributes.createDate) => same,
ENDCASE => older;
END; --DisplayCurrentDate
DisplayCurrentFontDate: PSCommand.FontProc =
BEGIN
[type, packageName, sizeInBytes, createDate]--
RETURNS [continue ← TRUE]--
DisplayCurrentDate[createDate];
END; --DisplayCurrentFontDate
DisplayCurrentTestPatternDate: PSCommand.FileProc =
BEGIN
[type, name, sizeInBytes, createDate]
DisplayCurrentDate[createDate];
END; --DisplayCurrentTestPatternDate
outputHandle.Blanks[10];
nsDateAndTime.length ← 0;
XFormat.Date[nsDateTimeObject, floppyFile.attributes.createDate]; --appends date to nsDateAndTime
stringArray[0] ← nsDateAndTime;
PSExecInternal.ExpandKeyAndPrint[exec, mFloppyFileCreated, stringArray];
IF floppyFile.dataType = font THEN
PSCommand.ListFonts[proc: DisplayCurrentFontDate,
filter: [packageName: floppyFile.nsFileName]]
ELSE
PSCommand.ListFiles[proc: DisplayCurrentTestPatternDate,
filter: [type: testPattern, name: floppyFile.nsFileName]];
END; --DisplayDates
Done:
PROCEDURE =
TRUSTED
BEGIN
OfflineFP0[];
FREE[@attributes];
END; -- Done
Install:
PROCEDURE =
BEGIN
ENABLE BEGIN
AccessFloppy.Error => {
IF type = volumeNotOpen THEN {
floppyHandle ← Floppy.nullVolumeHandle;
nullFloppyFileHandle ← [floppyHandle, Floppy.nullFileID]};
GOTO Exit};
May be generated in SendFloppyData (Floppy.Read) among other(?) places:
Floppy.Error => {
stringArray: ARRAY [0..1) OF NSString.String;
outputHandle.CR[];
stringArray[0] ← M[
SELECT error FROM
badDisk => mFloppyErrBadDisk,
badSectors => mFloppyErrBadSectors,
hardwareError => mFloppyErrHardware,
invalidVolumeHandle => mFloppyErrInvalidVolumeHandle,
needsScavenging => mFloppyErrNeedsScavenging,
noSuchDrive => mFloppyErrNoSuchDrive,
notReady => mFloppyErrNotReady,
stringTooShort => mFloppyErrStringTooShort,
volumeNotOpen => mFloppyErrVolumeNotOpen,
ENDCASE => mFloppyErrUnknown];
PSExecInternal.ExpandKeyAndPrint[exec, mFloppyError, DESCRIPTOR[stringArray]];
outputHandle.CR[];
outputHandle.NSLine[M[mFloppyCanceled]];
floppyHandle ← Floppy.nullVolumeHandle;
nullFloppyFileHandle ← [floppyHandle, Floppy.nullFileID];
GOTO Exit};
PSCommand.Error => {
WITH problem SELECT FROM
abortedByClient => NULL;
ENDCASE => {
outputHandle.CR[];
outputHandle.NSLine[M[mFloppyCanceled]]};
GOTO Exit};
END; --Enable Clause
pieceFile: BOOLEAN ← FALSE;
BYTE: TYPE = CARDINAL [0..100];
nsPrompt: NSString.String ← NEW[NSString.StringRep[100]];
nsPrompt: NSString.String ← [bytes: promptBytes, length: 0, maxlength: 100];
promptBytes: PACKED ARRAY [0..100) OF BYTE;
ask for name confirmation
sFileName: LONG STRING ← [AccessFloppy.maxNameLength]M
floppyFile ← [];
nTestPatternsInstalled ← nFontsInstalled ← 0;
OpenVolume[labelString ! UserAbort => GOTO Exit]; -- floppyHandle, labelString, nullFloppyFileHandle will be set.
nsPrompt ← NSString.AppendString[nsPrompt, M[mInstallFromFloppy]];
nsPrompt ← NSString.AppendString[nsPrompt, labelString];
IF TextInput.GetYesNo[
tty, nsPrompt, yes ! TTY.Rubout => GOTO Exit] = no THEN GOTO Exit;
attributes ← NEW[AccessFloppy.AttributesRecord[AccessFloppy.maxDataSize]];
DO
FOR floppyFileHandle: Floppy.FileHandle ← Floppy.GetNextFile[
nullFloppyFileHandle].nextFile, Floppy.GetNextFile[floppyFileHandle].nextFile UNTIL
floppyFileHandle = nullFloppyFileHandle DO
AccessFloppy.GetAttributes[floppyFileHandle, attributes];
AccessFloppyUtil.MesaStringFromAttributes[attributes, sFileName];
IF IsScriptFile[sFileName] THEN LOOP;
pieceFile ← IsPieceFile[attributes];
floppyFile.id ← floppyFileHandle;
floppyFile.attributes ← attributes;
floppyFile.fileName ← sFileName;
floppyFile.nsFileName ← Str[sFileName];
floppyFile.dataType ←
IF floppyFile.attributes.type # PSAssignedTypes.tFont300Rotated0 AND
floppyFile.attributes.type # PSAssignedTypes.tFont300Rotated90 AND
floppyFile.attributes.type # PSAssignedTypes.tFont200Rotated90
THEN testPattern ELSE font;
IF floppyFile.dataType = font THEN
SELECT psState.option FROM
bansheeDl, feps9700, fx3500, raven =>
IF floppyFile.attributes.type # PSAssignedTypes.tFont300Rotated0 THEN
GOTO WrongFontFileType;
d1 =>
d1 fonts can have either type tFont300Rotated0 or tFont300Rotated90,
though we assume they are actually the 90 degree rotated fonts.
IF (floppyFile.attributes.type # PSAssignedTypes.tFont300Rotated0) AND
(floppyFile.attributes.type # PSAssignedTypes.tFont300Rotated90) THEN
GOTO WrongFontFileType;
fax295, fax495 =>
IF floppyFile.attributes.type # PSAssignedTypes.tFont200Rotated90 THEN
GOTO WrongFontFileType;
ENDCASE => ERROR
ELSE BEGIN --file is a test pattern
OPEN T: TestPattern;
This is a bunch of ugly exception code to prevent the user from loading test patterns inappropriate for the printing option being supported. This only matters for the
options that use the 300 spi fonts, since they all share the same Required Fonts floppy. The 200 spi Required Fonts floppy contains only the test patterns used by the fax.
Resuming the NotFound signal below will return the name for the test pattern, even if the TP is not currently installed on the PS....
nsBansheeAlignment: NSString.String ← T.Name[T.bansheeAlignment ! T.NotFound => RESUME];
alignment pattern specific to banshee
nsAlignment: NSString.String ← T.Name[T.alignment ! T.NotFound => RESUME];
alignment pattern for electronic printers
nsDarkDusting: NSString.String ← T.Name[T.darkDusting ! T.NotFound => RESUME];
nsGreyDusting: NSString.String ← T.Name[T.greyDusting ! T.NotFound => RESUME];
SELECT psState.option FROM
d1, fx3500, raven =>
IF NSString.EquivalentStrings[floppyFile.nsFileName, nsBansheeAlignment] THEN LOOP; --skip alignment pattern specific to banshee
bansheeDl => BEGIN
IF NSString.EquivalentStrings[floppyFile.nsFileName, nsAlignment] THEN LOOP; --skip alignment pattern not used for banshee
IF NSString.EquivalentStrings[floppyFile.nsFileName, nsDarkDusting] THEN LOOP; --pattern not used for banshee (bad for engine)
END;
feps9700 => BEGIN
IF NSString.EquivalentStrings[floppyFile.nsFileName, nsBansheeAlignment] THEN LOOP; --don't use any alignment pattern
IF NSString.EquivalentStrings[floppyFile.nsFileName, nsAlignment] THEN LOOP; --don't use any alignment pattern
IF NSString.EquivalentStrings[floppyFile.nsFileName, nsGreyDusting] THEN LOOP; --can't be printed by 9700
END;
fax295, fax495 => NULL; --200 spi Required Fonts floppy contains only Cam.interpress.
ENDCASE => ERROR;
END;
IF pieceFile THEN {EnterScriptMode[]; EXIT};
SELECT LoadConfirmation[]
FROM
no => LOOP;
cancel => EXIT;
ENDCASE;
IF floppyFile.dataType = font THEN BEGIN
PSCommand.InstallFont[
type: cdFont,
packageName: floppyFile.nsFileName,
createDate: floppyFile.attributes.createDate,
data: [proc[SendFloppyData]],
packageSizeHintInBytes: floppyFile.attributes.totalSizeInBytes !
SendDataError => EXIT;
PSCommand.Error => WITH p: problem SELECT FROM
insufficientSpace => BEGIN
outputHandle.Blanks[4];
outputHandle.NSLine[M[mFloppyErrInsufficientVolSpace], 2];
outputHandle.NSLine[M[mFloppyCanceled]];
END;
disallowedInCurrentMode => BEGIN
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
nsFreeThisString: NSString.String;
stringArray[0] ← M[mInstallFonts];
nsFreeThisString ← Message.Expand[M[mConflictingMode], stringArray];
outputHandle.NSLine[nsFreeThisString];
NSString.FreeString[nsFreeThisString];
EXIT;
END;
documentInProgress => BEGIN --We CAN get here since, with the advent of remote administration, two users may be logged at the same time. One could start printing before the other finishes installing fonts.
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
nsFreeThisString: NSString.String;
outputHandle.NSLine[M[mDocInProgress]];
stringArray[0] ← M[mInstallFonts];
nsFreeThisString ← Message.Expand[M[mPleaseStopPrinting], stringArray];
outputHandle.NSLine[nsFreeThisString];
NSString.FreeString[nsFreeThisString];
END;
ENDCASE;
];
nFontsInstalled ← nFontsInstalled + 1;
END
ELSE BEGIN
PSCommand.InstallFile[
type: testPattern, name: floppyFile.nsFileName,
createDate: floppyFile.attributes.createDate,
data: [proc[SendFloppyData]],
fileSizeHintInBytes: floppyFile.attributes.totalSizeInBytes !
SendDataError => EXIT;
PSCommand.Error => WITH problem SELECT FROM
insufficientSpace => BEGIN
outputHandle.Blanks[4];
outputHandle.NSLine[M[mFloppyErrInsufficientVolSpace], 2];
outputHandle.NSLine[M[mFloppyCanceled]];
END;
disallowedInCurrentMode => BEGIN
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
nsFreeThisString: NSString.String;
stringArray[0] ← M[mInstallFonts];
nsFreeThisString ← XMessage.Compose[M[mConflictingMode], stringArray];
outputHandle.NSLine[nsFreeThisString];
NSString.FreeString[nsFreeThisString];
EXIT;
END;
ENDCASE;
];
nTestPatternsInstalled ← nTestPatternsInstalled + 1;
END;
outputHandle.Blanks[10];
outputHandle.NSLine[M[mFloppyDone]];
IF NSExec.CheckForAbort[exec] THEN EXIT;
ENDLOOP;
BEGIN
-- <nFontsInstalled+nTestPatternsInstalled> " files installed from <1>."
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
stringArray[0] ← Str[labelString];
outputHandle.Blanks[2];
outputHandle.Decimal[nFontsInstalled + nTestPatternsInstalled];
PSExecInternal.ExpandKeyAndPrint[exec, mFilesInstalled, stringArray];
END;
Done[];
EXITS
WrongFontFileType => BEGIN
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
stringArray[0] ← floppyFile.nsFileName;
PSExecInternal.ExpandKeyAndPrint[exec, mBadFontFileType, stringArray];
outputHandle.NSLine[M[mFloppyCanceled]];
Done[]; continue ← no
END;
Exit => {Done[]; continue ← no};
END; --Install
IsPieceFile: PRIVATE PROC [attributes: AccessFloppy.Attributes] RETURNS [BOOLEAN] =
BEGIN RETURN [attributes.totalSize > attributes.size];
END; --IsPieceFile
IsScriptFile:
PROC [name: NSString.String]
RETURNS [
BOOLEAN] =
BEGIN
RETURN [NSString.EqualStrings[name, scriptName]];
END; --IsScriptFile
LoadConfirmation:
PROCEDURE
RETURNS [answer: Answer] =
BEGIN
--Get confirmation from user to load file or not.
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
nsFreeThisString: NSString.String;
version: Version;
default: TextInput.YesOrNo ← no;
version ← DisplayDates[];
SELECT version
FROM
new => {
stringArray[0] ← M[mFloppyNew];
default ← yes};
newer => {
stringArray[0] ← M[mFloppyNewer];
default ← yes};
same => stringArray[0] ← M[mFloppySame];
ENDCASE => stringArray[0] ← M[mFloppyOlder];
stringArray[1] ← floppyFile.nsFileName;
nsFreeThisString ← XMessage.Compose[M[mInstallFile], stringArray];
answer ←
IF TextInput.GetYesNo[
tty, nsFreeThisString, default !
TTY.Rubout => {answer ← cancel;
CONTINUE}] =
yes THEN yes ELSE no;
NSString.FreeString[nsFreeThisString];
IF answer = yes
THEN
BEGIN
stringArray[0] ← floppyFile.nsFileName;
outputHandle.Blanks[8];
PSExecInternal.ExpandKeyAndPrint[exec, mInstalling, stringArray];
IF state # NIL THEN state.version ← version; --*MT for multi-floppies error
END;
END; --LoadConfirmation
OfflineFP0:
PROCEDURE =
BEGIN
IF floppyHandle # Floppy.nullVolumeHandle THEN {
AccessFloppy.Close[!Floppy.Error => CONTINUE];
floppyHandle ← Floppy.nullVolumeHandle;
nullFloppyFileHandle ← [floppyHandle, Floppy.nullFileID]};
END; -- OfflineFP0
OpenVolume: PROCEDURE [svName: LONG STRING] = BEGIN
svName.length ← 0;
floppyHandle ← AccessFloppy.Open[
!
Floppy.Error =>
SELECT error FROM
invalidVolumeHandle, notReady => {
outputHandle.CR[];
IF TextInput.GetYesNo[
tty, M[mInsertFloppy], yes ! TTY.Rubout => {GOTO Quit}] = yes
THEN RETRY
ELSE GOTO Quit};
ENDCASE => REJECT];
[] ← Floppy.GetAttributes[floppyHandle, svName];
nullFloppyFileHandle ← [floppyHandle, Floppy.nullFileID];
EXITS Quit => ERROR UserAbort;
END; --OpenVolume
SendFloppyData: PROCEDURE [dataSink: NSDataStream.SinkStream] = BEGIN
bufferSize: VM.PageCount = 30; --one disk track
buffer: VM.Interval ← VM.nullInterval;
bufferBlock: Stream.Block;
pagesRemaining: VM.PageCount ← floppyFile.attributes.size;
base: Floppy.PageNumber ← AccessFloppy.leaderLength;
filePiece: BOOLEAN ← floppyFile.attributes.totalSize # floppyFile.attributes.size;
DeleteBuffer:
PROCEDURE =
BEGIN
IF buffer # VM.nullInterval THEN BEGIN
AccessFloppyUtil.DeleteBuffer[buffer.pointer];
buffer ← Space.nullInterval;
END;
END; --DeleteBuffer
BEGIN ENABLE
BEGIN UNWIND => {
IF dataSink # nullSinkStream THEN {
NSDataStream.Abort[dataSink ! NSDataStream.Aborted => CONTINUE];
Stream.Delete[dataSink ! NSDataStream.Aborted => CONTINUE]};
DeleteBuffer[]};
Floppy.Error => {
stringArray: ARRAY [0..1) OF NSString.String;
stringArray[0] ← M[
SELECT error FROM
invalidVolumeHandle => mFloppyErrInvalidVolumeHandle,
notReady => mFloppyErrNotReady,
volumeNotOpen => mFloppyErrVolumeNotOpen,
hardwareError => mFloppyErrHardware,
ENDCASE => mFloppyErrUnknown];
PSExecInternal.ExpandKeyAndPrint[exec, mFloppyError, DESCRIPTOR[stringArray]];
GOTO dataSendError};
Floppy.DataError => {
outputHandle.Blanks[4];
outputHandle.NSLine[M[mFloppyReadError]];
GOTO dataSendError}
END; --Enable clause
IF dataSink = nullSinkStream THEN RETURN;
buffer ← AccessFloppyUtil.CreateBuffer[bufferSize !
Space.InsufficientSpace, RefText.Error => {
outputHandle.Blanks[4];
outputHandle.NSLine[M[mFloppyCreateFileError]];
GOTO dataSendError};
Volume.InsufficientSpace => {
outputHandle.Blanks[4];
outputHandle.NSLine[M[mFloppyErrInsufficientVolSpace]];
bufferBlock ← [
blockPointer: buffer.pointer, startIndex: 0,
stopIndexPlusOne: CARDINAL[bufferSize * Environment.bytesPerPage]];
Copy as many chunks of the standard buffer size as possible...
UNTIL pagesRemaining < bufferSize DO
Floppy.Read[floppyFile.id, base, bufferSize, buffer.pointer];
Stream.PutBlock[dataSink, bufferBlock !
NSDataStream.Aborted => GOTO aborted];
base ← base + bufferSize;
pagesRemaining ← pagesRemaining - bufferSize;
ENDLOOP;
...and then copy the fraction left over.
IF pagesRemaining # 0 THEN BEGIN
scratchPointer: LONG POINTER ← Space.ScratchMap[pagesRemaining];
scratchBlock: Stream.Block;
bytesRemaining: CARDINAL ← CARDINAL[pagesRemaining * PrincOps.bytesPerPage];
scratchBlock ← [
blockPointer: scratchPointer, startIndex: 0,
stopIndexPlusOne: bytesRemaining];
Floppy.Read[floppyFile.id, base, pagesRemaining, scratchPointer !
Floppy.Error, Floppy.DataError => {
scratchPointer ← Space.Unmap[scratchPointer]; REJECT}];
Stream.PutBlock[dataSink, scratchBlock !
NSDataStream.Aborted => {
scratchPointer ← Space.Unmap[scratchPointer];
GOTO aborted}];
scratchPointer ← Space.Unmap[scratchPointer];
END;
DeleteBuffer[];
IF ~filePiece THEN
Stream.Delete[dataSink ! NSDataStream.Aborted => CONTINUE];
EXITS
aborted => { --PSCommand Install proc will return with raise error.
Stream.Delete[dataSink ! NSDataStream.Aborted => CONTINUE];
DeleteBuffer[];
systemAbort ← TRUE};
dataSendError => {
NSDataStream.Abort[dataSink ! NSDataStream.Aborted => CONTINUE];
Stream.Delete[dataSink ! NSDataStream.Aborted => CONTINUE];
DeleteBuffer[];
ERROR SendDataError};
END; --Enable clause and code
END; --SendFloppyData
IF psState.clientControl.formatterEnabled OR psState.clientControl.markerEnabled
THEN BEGIN
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
stringArray[0] ← M[mInstallFonts];
outputHandle.Blanks[2];
PSExecInternal.ExpandKeyAndPrint[exec, mPleaseStopPrinting, stringArray];
END
ELSE Install[];
EXITS Exit => NULL;