DIRECTORY
BasicTime USING [Unpacked],
CHEntries USING [PrimaryData],
CHPIDs USING [ps],
CHNameP2V0 USING [Name],
IO USING [STREAM],
NSExec USING [BroadcastAsyncMessage, CheckForAbort, ClientID, Error, ExecProc, GetTTY, Handle, OutputHandle, UserName],
NSString USING [AppendCharacter, AppendDecimal, CopyString, LogicalLength, MakeString, nullString, String, TruncateString],
NSTTY USING [SetLinePosition],
PrintingTypes USING [Option],
PSAssignedTypes USING [tSelfRegStableData],
PSCommand USING [allDocuments, CancelDocument, DocumentFilter, DocumentProc, DocumentStatus, Error, FaxLocalPrintStatus, FaxTransmitStatus, GetPrintServiceStatus, ListDocuments, noDocuments, ResetStatistics, ShutDownEngine, SpecificDocStatus, StartDiagnosticMode, StartPrinting, StartQueuing, StopPrinting, StopQueuing, WakeUpEngine],
PSExec USING [GetClientID],
PSExecInternal USING [ChoiceList, KeyList, KeyListRep, RegCode],
PSExecMessages USING [Key],
PSKMessages USING [GetHandle],
PSState USING [maxStopReasonLength, StateHandle],
Rope USING [ROPE, Substr, ToRefText],
SelfReg USING [Register, RegisterCode, UnRegister, UnRegisterCode],
TextInput USING [GetChoice, GetText, GetYesNo],
TTY USING [Handle],
XFormat USING [Blanks, CR, Handle, NSLine, NSString],
XMessage USING [Get, GetList, Handle, MsgKey, MsgKeyList, Compose, StringArray];
XNSAuth USING [Key];
**********************************
Command Processing Routines:
**********************************
DisplayDocuments:
PUBLIC NSExec.ExecProc =
BEGIN
ENABLE NSExec.Error => IF type = invalidExec THEN GOTO Exit;
tty: TTY.Handle ← NSExec.GetTTY[exec];
outputHandle: XFormat.Handle ← NSExec.OutputHandle[exec];
choices: CARDINAL = 4;
truncatedSenderLength: CARDINAL = 22;
truncatedStatusLength: CARDINAL = 23;
truncatedDocLength: CARDINAL = 27;
truncatedXmitStatusLength: CARDINAL = 31;
truncatedDestLength: CARDINAL = 22;
statusPosition: CARDINAL = 23;
docNamePosition: CARDINAL = 47;
pagesPosition: CARDINAL = 75;
xMitStatusPosition: CARDINAL = 2;
destPosition: CARDINAL = 34;
dateTimePosition: CARDINAL = 57;
phoneTimePosition: CARDINAL = 72;
printingOption: PrintingTypes.Option ← PSCommand.GetPrintServiceStatus[].option;
docsDisplayed: CARDINAL ← 0;
msgKeys: PSExecInternal.KeyList ← NEW[PSExecInternal.KeyListRep[choices]];
queueChoices: choiceSeq ← NEW[XMessage.StringArray[choices]];
filter: PSCommand.DocumentFilter ← PSCommand.noDocuments;
specificStatusFilter: BOOLEAN ← FALSE;
allowSpecificStatus: PACKED ARRAY PSCommand.SpecificDocStatus OF BOOLEAN ← ALL[FALSE];
senderName: CHName.Name;
msgKeys.keys[0] ← mInProgDocs; msgKeys.keys[1] ← mUnCompDocs;
msgKeys.keys[2] ← mCompDocs; msgKeys.keys[3] ← mAllDocs;
BEGIN
ENABLE
UNWIND =>
NULL;
CheckFilter: PSCommand.DocumentProc =
BEGIN
[document: DocumentAttributes] RETURNS [continue: BOOLEAN ← TRUE]--
status: PSCommand.SpecificDocStatus ← GetSpecificDocStatus[document.status];
IF allowSpecificStatus[status]
THEN
[] ← DisplayDocument[document];
END; --CheckFilter
DisplayDocument: PSCommand.DocumentProc =
BEGIN
[document: DocumentAttributes] RETURNS [continue: BOOLEAN ← TRUE]--
freeThisString: NSString.String;
***Display sender name:
BEGIN
senderName ← CHName.NameFieldsFromString[document.sender
! CHName.Error => GOTO NoSenderName];
senderName.object ← Rope.Substr[senderName.object, truncatedSenderLength];
XFormat.NSString[outputHandle, Rope.ToRefText[senderName.object]];
EXITS NoSenderName => XFormat.NSString[outputHandle, M[mUnreadableName]];
END;
***Display document status:
NSTTY.SetLinePosition[tty, statusPosition];
Message file string is copied so it can be truncated...
freeThisString ← StringForDocStatus[document.status, printingOption];
freeThisString ← NSString.TruncateString[freeThisString, truncatedStatusLength];
XFormat.NSString[outputHandle, freeThisString];
***Display document name:
NSTTY.SetLinePosition[tty, docNamePosition];
IF NSString.LogicalLength[document.name] # 0
THEN
BEGIN
document.name ← NSString.TruncateString[document.name, truncatedDocLength];
XFormat.NSString[outputHandle, document.name];
END
ELSE XFormat.NSString[outputHandle, M[mAnonymous]];
***Display page count:
IF document.pagesDecomposed > 0
THEN
BEGIN
NSTTY.SetLinePosition[tty, pagesPosition];
XFormat.NSString[outputHandle, NSString.AppendDecimal[NIL, document.pagesDecomposed]];
END;
XFormat.CR[outputHandle];
IF printingOption = fax495 THEN NULL;
<<There could be data for documents printed on a fax, even though the printing option has been changed to something else. Only print the fax-specific status, if the printing option is a fax.>>
<<THIS PROCEDURE DEALS WITH FAX WHICH IS NOT IN CEDAR>>
WITH d: document SELECT FROM
fax495 => BEGIN OPEN d.faxStatus;
unpackedTime: Time.Unpacked;
sUnpackedTime: LONG STRING ← [20];
sMinutes: LONG STRING ← [8];
sSeconds: LONG STRING ← [8];
stringArray: REF [0..2) OF NSString.String;
minutes, seconds: CARDINAL ← 0;
IF localPrint # null THEN BEGIN
***Display local print status:
NSTTY.SetLinePosition[tty, xMitStatusPosition];
Message file string is copied so it can be truncated...
freeThisString ← NSString.CopyString[
PSExecInternal.execHeap, StringForFaxLocalPrintStatus[d.status, localPrint]];
freeThisString ← NSString.TruncateString[
freeThisString, truncatedXmitStatusLength];
XFormat.NSString[outputHandle, freeThisString];
NSString.FreeString[z: PSExecInternal.execHeap, s: freeThisString];
***Display destination "Local":
NSTTY.SetLinePosition[tty, destPosition];
XFormat.NSString[outputHandle, M[mLocal]];
***Display completion date:
IF localPrint IN [printed..localFaxFailure] AND
localPrintCompletionDate # BasicTime.nullGMT THEN BEGIN --display completion time
NSTTY.SetLinePosition[tty, dateTimePosition];
unpackedTime ← BasicTime.Unpack[localPrintCompletionDate];
sUnpackedTime.length ← 0;
Time.Append[sUnpackedTime, unpackedTime];
sUnpackedTime ← ShortenDateString[sUnpackedTime];
XFormat.NSString[outputHandle, Str[sUnpackedTime]];
END;
IO.PutChar[outputHandle, '\n];
END;
FOR i: CARDINAL IN [0..phoneNumberCount) DO
***Display transmit status:
NSTTY.SetLinePosition[tty, xMitStatusPosition];
Put "will retry" on the end of status if applicable...
IF transmitData[i].willRetry THEN BEGIN
freeThisStringToo: NSString.String ← NSString.nullString;
SELECT transmitData[i].transmit FROM
transmitError => BEGIN
stringArray[0] ← transmitData[i].errorCode;
freeThisStringToo ← XMessage.Compose[
M[mShortXmitError], DESCRIPTOR[BASE[stringArray], 1], PSExecInternal.execHeap];
stringArray[0] ← freeThisStringToo;
END;
localFaxFailure => BEGIN
stringArray[0] ← transmitData[i].errorCode;
freeThisStringToo ← XMessage.Compose[
M[mShortFaxFailure], DESCRIPTOR[BASE[stringArray], 1], PSExecInternal.execHeap];
stringArray[0] ← freeThisStringToo;
END;
ENDCASE => stringArray[0] ← StringForFaxTransmitStatus[
status: d.status, faxStatus: transmitData[i].transmit, willRetry: TRUE];
freeThisString ← XMessage.Compose[
M[mWillRetry], DESCRIPTOR[BASE[stringArray], 1], PSExecInternal.execHeap];
NSString.FreeString[z: PSExecInternal.execHeap, s: freeThisStringToo];
END
ELSE
SELECT transmitData[i].transmit FROM
transmitError => BEGIN
stringArray[0] ← transmitData[i].errorCode;
freeThisString ← XMessage.Compose[
M[mTransmitError], DESCRIPTOR[BASE[stringArray], 1], PSExecInternal.execHeap];
END;
localFaxFailure => BEGIN
stringArray[0] ← transmitData[i].errorCode;
freeThisString ← XMessage.Compose[
M[mFaxFailure], DESCRIPTOR[BASE[stringArray], 1], PSExecInternal.execHeap];
END;
ENDCASE => freeThisString ← NSString.CopyString[
z: PSExecInternal.execHeap, s: StringForFaxTransmitStatus[
status: d.status, faxStatus: transmitData[i].transmit, willRetry: FALSE]];
freeThisString ← NSString.TruncateString[
s: freeThisString, bytes: truncatedXmitStatusLength];
XFormat.NSString[outputHandle, freeThisString];
NSString.FreeString[z: PSExecInternal.execHeap, s: freeThisString];
***Display destination phone number:
NSTTY.SetLinePosition[tty, destPosition];
transmitData[i].phoneNumber ← NSString.TruncateString[
s: transmitData[i].phoneNumber, bytes: truncatedDestLength];
XFormat.NSString[outputHandle, transmitData[i].phoneNumber];
***Display completion date:
IF transmitData[i].transmit IN [transmitted..localFaxFailure]
AND transmitData[i].completionDate # BasicTime.nullGMT THEN BEGIN
***Display completion time:
NSTTY.SetLinePosition[tty, dateTimePosition];
unpackedTime ← BasicTime.Unpack[transmitData[i].completionDate];
sUnpackedTime.length ← 0;
Time.Append[sUnpackedTime, unpackedTime];
sUnpackedTime ← ShortenDateString[sUnpackedTime];
XFormat.NSString[outputHandle, Str[sUnpackedTime]];
***Display phone call elapsed time:
IF transmitData[i].phoneCallElapsedTime # 0 THEN BEGIN
NSTTY.SetLinePosition[tty, phoneTimePosition];
minutes ← CARDINAL[transmitData[i].phoneCallElapsedTime / 60];
seconds ← CARDINAL[transmitData[i].phoneCallElapsedTime MOD 60];
sMinutes.length ← 0;
sSeconds.length ← 0;
String.AppendDecimal[sMinutes, minutes];
IF seconds < 10 THEN String.AppendChar[s: sSeconds, c: '0];
String.AppendDecimal[sSeconds, seconds];
stringArray[0] ← Str[sMinutes];
stringArray[1] ← Str[sSeconds];
freeThisString ← XMessage.Compose[
M[mPhoneTime], DESCRIPTOR[stringArray], PSExecInternal.execHeap];
XFormat.NSString[outputHandle, freeThisString];
NSString.FreeString[z: PSExecInternal.execHeap, s: freeThisString];
END
END;
IO.PutChar[outputHandle, '\n];
ENDCASE;
ENDLOOP;
END;
docsDisplayed ← docsDisplayed + 1;
IF docsDisplayed
MOD 4 = 0
THEN
--Check for user abort every 4 documents.
IF NSExec.CheckForAbort[exec] = TRUE THEN continue ← FALSE;
END; --DisplayDocument
GetList[choices, msgKeys, queueChoices];
SELECT TextInput.GetChoice[tty: tty, prompt: nsNil, choices: queueChoices, default: 1]
FROM
0 => filter.status[inProgress] ← TRUE;
1 => filter.status[pending] ← filter.status[inProgress] ← filter.status[held] ← TRUE;
2 =>
BEGIN
filter ← PSCommand.allDocuments;
filter.status[pending] ← filter.status[inProgress] ← filter.status[held] ← FALSE;
END;
3 => filter ← PSCommand.allDocuments;
ENDCASE => {outputHandle.NSLine[M[mInvalidChoice]]; GOTO Exit};
outputHandle.NSLine[M[mDocList]];
IF printingOption = fax495 THEN outputHandle.NSLine[M[mFaxDocList]];
XFormat.CR[outputHandle];
IF specificStatusFilter
THEN PSCommand.ListDocuments[CheckFilter, filter]
ELSE PSCommand.ListDocuments[DisplayDocument, filter];
XFormat.CR[outputHandle];
DisplayCount[exec, docsDisplayed, mDocsListed];
END; --Enable clause and code.
EXITS Exit => NULL;
END; --DisplayDocuments
CancelDocuments:
PUBLIC NSExec.ExecProc =
BEGIN
The current implementation puts up a menu of particular groups of documents to cancel. If we allow the users to cancel individual documents in the future, be sure to catch the signal PSCommand.Error[documentNotFound].
ENABLE NSExec.Error => IF type = invalidExec THEN GOTO Exit;
tty: TTY.Handle ← NSExec.GetTTY[exec];
outputHandle: XFormat.Handle ← NSExec.OutputHandle[exec];
printingOption: PrintingTypes.Option ← PSCommand.GetPrintServiceStatus[].option;
docsCanceled: CARDINAL ← 0;
choices: CARDINAL = 5;
msgKeys: PSExecInternal.KeyList ← NEW[PSExecInternal.KeyListRep[choices]];
queueChoices: PSExecInternal.ChoiceList ← NEW[XMessage.StringArray[choices]];
filter: PSCommand.DocumentFilter ← PSCommand.noDocuments;
specificStatusFilter: BOOLEAN ← FALSE; --If true check specific status filter (allowSpecificStatus) before cancelling doc.
faxFilter: BOOLEAN ← FALSE; --If true check fax status filters (allowFaxLocalStatus and allowFaxTransmitStatus) before cancelling doc.
allowSpecificStatus: PACKED ARRAY PSCommand.SpecificDocStatus OF BOOLEAN ← ALL[FALSE];
allowFaxLocalStatus: PACKED ARRAY PSCommand.FaxLocalPrintStatus OF BOOLEAN ← ALL[FALSE];
allowFaxTransmitStatus:
PACKED
ARRAY PSCommand.FaxTransmitStatus
OF
BOOLEAN ←
ALL[
FALSE];
CheckFilter: PSCommand.DocumentProc =
[document: DocumentAttributes] RETURNS [continue: BOOLEAN ← TRUE]--
BEGIN
intStatus: PSCommand.SpecificDocStatus ←
GetSpecificDocStatus[document.status];
IF specificStatusFilter AND NOT allowSpecificStatus[intStatus] THEN RETURN;
IF faxFilter
THEN
TRUSTED
BEGIN
WITH d: document
SELECT
FROM
fax495 =>
BEGIN
IF allowFaxLocalStatus[d.faxStatus.localPrint] THEN GOTO allowed;
FOR p:
CARDINAL
IN [0..d.faxStatus.phoneNumberCount)
DO
IF allowFaxTransmitStatus[d.faxStatus.transmitData[p].transmit]
THEN
GOTO allowed;
ENDLOOP;
RETURN; --none of the "allowed" statuses found
END;
ENDCASE => NULL; --not a fax document
EXITS allowed => NULL;
END;
continue ← CancelDocument[document];
CancelDocument: PSCommand.DocumentProc =
[document: DocumentAttributes] RETURNS [continue: BOOLEAN ← TRUE]--
TRUSTED BEGIN
stringArray: REF XMessage.StringArray ← NEW[XMessage.StringArray[2]];
newStatus: PSCommand.DocumentStatus;
IF NSExec.CheckForAbort[exec] THEN RETURN [continue: FALSE];
newStatus ← PSCommand.CancelDocument[document.id];
IF newStatus.simple = canceled
THEN
BEGIN
stringArray[0] ←
IF document.name.length = 0 THEN M[mAnonymous]
ELSE document.name;
stringArray[1] ← StringForDocStatus[newStatus, printingOption];
ExpandKeyAndPrint[exec, mDocListTerse, stringArray];
docsCanceled ← docsCanceled + 1;
END;
END; --CancelDocument
For feps9700 mMarkingDoc becomes mForwardingDoc...
IF printingOption = feps9700
THEN {msgKeys.keys[0] ← mFormatDoc; msgKeys.keys[1] ← mForwardingDoc; msgKeys.keys[2] ← mInProgDocs; msgKeys.keys[3] ← mQdDocs;
msgKeys.keys[4] ← mAllDocs}
ELSE {msgKeys.keys[0] ← mFormatDoc; msgKeys.keys[1] ← mMarkingDoc;
msgKeys.keys[2] ← mInProgDocs; msgKeys.keys[3] ← mQdDocs;
msgKeys.keys[4] ← mAllDocs};
GetList[choices, msgKeys, queueChoices];
SELECT TextInput.GetChoice[tty: tty, prompt: nsNil, choices: queueChoices]
FROM
0 => BEGIN
filter.status[inProgress] ← TRUE;
specificStatusFilter ← TRUE;
allowSpecificStatus[decomposing] ← TRUE;
IF printingOption = feps9700
THEN
allowSpecificStatus[decomposed] ←
allowSpecificStatus[merging] ← TRUE;
END;
1 =>
BEGIN
filter.status[inProgress] ← TRUE;
specificStatusFilter ← faxFilter ← TRUE;
allowSpecificStatus[marking] ←
allowSpecificStatus[forwarding] ←
allowSpecificStatus[faxStatus] ← TRUE;
allowFaxLocalStatus[marking] ←
allowFaxTransmitStatus[transmitting] ← TRUE;
END;
2 => filter.status[inProgress] ← TRUE;
3 => filter.status[pending] ← TRUE;
4 =>
BEGIN
filter.status[pending] ← TRUE;
filter.status[inProgress] ← TRUE;
END;
ENDCASE => {outputHandle.NSLine[M[mInvalidChoice]]; GOTO Exit;};
IF Confirm[exec]
THEN
BEGIN
IF specificStatusFilter
OR faxFilter
THEN
PSCommand.ListDocuments[CheckFilter, filter]
ELSE
PSCommand.ListDocuments[CancelDocument, filter];
DisplayCount[exec, docsCanceled, mDocsCanceled];
END;
EXITS Exit => NULL;
END; --CancelDocuments
StartQueuingAndPrinting:
PUBLIC NSExec.ExecProc =
BEGIN
ENABLE NSExec.Error => IF type = invalidExec THEN GOTO Exit;
name: CHName.Name ← NSExec.UserName[
exec ! NSExec.Error => GOTO Exit];
state: PSState.StateHandle ← PSCommand.GetPrintServiceStatus[];
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
stringArray: ARRAY [0..2) OF NSString.String ← ALL[nsNil];
freeThisString: NSString.String;
stopReasonDisplayed: BOOLEAN ← FALSE;
Display stop queuing reason, if any:
IF state.lastUserToStopQueuing.length > 0
AND
state.lastStopQueuingReason.length > 0 THEN BEGIN
stringArray.data[0] ← state.lastStopQueuingReason;
freeThisString ← XMessage.Compose[M[mReason], stringArray];
stringArray.data[0] ← state.lastUserToStopQueuing;
stringArray.data[1] ← freeThisString;
ExpandKeyAndPrint[exec, mQueuingStoppedBy, stringArray];
stopReasonDisplayed ← TRUE;
END;
Display stop printing reason, if any:
IF state.lastUserToStopPrinting.length > 0
AND
state.lastStopPrintingReason.length > 0 THEN BEGIN
stringArray[0] ← state.lastStopPrintingReason;
freeThisString ← XMessage.Compose[M[mReason], stringArray];
stringArray[0] ← state.lastUserToStopPrinting;
stringArray[1] ← freeThisString;
ExpandKeyAndPrint[exec, mPrintingStoppedBy, stringArray];
NSString.FreeString[z: PSExecInternal.execHeap, s: freeThisString];
stopReasonDisplayed ← TRUE;
END;
IF stopReasonDisplayed
THEN
IF NOT ConfirmExpanded[exec, mStart] THEN RETURN;
StartQueuingInternal[exec, name];
StartPrintingInternal[exec, name];
EXITS Exit => NULL;
END; --StartQueuingAndPrinting
StopQueuingAndPrinting:
PUBLIC NSExec.ExecProc =
BEGIN
ENABLE NSExec.Error => IF type = invalidExec THEN GOTO Exit;
tty: TTY.Handle ← NSExec.GetTTY[exec];
name: CHName.Name ← NSExec.UserName[
exec ! NSExec.Error => GOTO Exit];
stopReason: NSString.String ← NSString.MakeString[
bytes: PSState.maxStopReasonLength];
stopReason ← TextInput.GetText[tty: tty,
prompt: M[mEnterReason], text: stopReason,
minLength: 0, maxLength: PSState.maxStopReasonLength];
StopQueuingInternal[exec, name, stopReason];
StopPrintingInternal[exec, name, stopReason];
NSString.FreeString[z: PSExecInternal.execHeap, s: stopReason];
EXITS Exit => NULL;
END;
--StopQueuingAndPrinting
StartPrinting:
PUBLIC NSExec.ExecProc =
BEGIN
ENABLE NSExec.Error => IF type = invalidExec THEN GOTO Exit;
name: CHName.Name ← NSExec.UserName[
exec ! NSExec.Error => GOTO Exit];
state: PSState.StateHandle ← PSCommand.GetPrintServiceStatus[];
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
freeThisString: NSString.String;
Display stop printing reason, if any:
IF state.lastUserToStopPrinting.length > 0
AND
state.lastStopPrintingReason.length > 0 THEN BEGIN
stringArray[0] ← state.lastStopPrintingReason;
freeThisString ← XMessage.Compose[M[mReason], stringArray];
stringArray[0] ← state.lastUserToStopPrinting;
stringArray[1] ← freeThisString;
ExpandKeyAndPrint[exec, mPrintingStoppedBy, stringArray];
NSString.FreeString[z: PSExecInternal.execHeap, s: freeThisString];
IF NOT ConfirmExpanded[exec, mStartPrinting] THEN RETURN;
END;
StartPrintingInternal[exec, name];
EXITS Exit => NULL;
END; --StartPrinting
StopPrinting:
PUBLIC NSExec.ExecProc =
BEGIN
ENABLE NSExec.Error => IF type = invalidExec THEN GOTO Exit;
tty: TTY.Handle ← NSExec.GetTTY[exec];
name: CHName.Name ← NSExec.UserName[
exec ! NSExec.Error => GOTO Exit];
stopReason: NSString.String ← NSString.MakeString[bytes: PSState.maxStopReasonLength];
BEGIN
ENABLE
UNWIND =>
NSString.FreeString[z: PSExecInternal.execHeap, s: stopReason];
stopReason ← TextInput.GetText[tty: tty, prompt: M[mEnterReason], text: stopReason,
minLength: 0, maxLength: PSState.maxStopReasonLength];
StopPrintingInternal[exec, name, stopReason];
NSString.FreeString[z: PSExecInternal.execHeap, s: stopReason];
END; --Enable clause and code
EXITS Exit => NULL;
END; --StopPrinting
StartQueuing:
PUBLIC NSExec.ExecProc =
BEGIN
ENABLE NSExec.Error => IF type = invalidExec THEN GOTO Exit;
name: CHName.Name ← NSExec.UserName[exec ! NSExec.Error => GOTO Exit];
state: PSState.StateHandle ← PSCommand.GetPrintServiceStatus[];
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
freeThisString: NSString.String;
Display stop queuing reason, if any:
IF state.lastUserToStopQueuing.length > 0
AND
state.lastStopQueuingReason.length > 0 THEN BEGIN
stringArray[0] ← state.lastStopQueuingReason;
freeThisString ← XMessage.Compose[M[mReason], stringArray];
stringArray[0] ← state.lastUserToStopQueuing;
stringArray[1] ← freeThisString;
ExpandKeyAndPrint[exec, mQueuingStoppedBy, stringArray];
NSString.FreeString[PSExecInternal.execHeap, expandedString];
IF NOT ConfirmExpanded[exec, mStartSpooling] THEN RETURN;
END;
StartQueuingInternal[exec, name];
EXITS Exit => NULL;
END; --StartQueuing
StopQueuing:
PUBLIC NSExec.ExecProc =
BEGIN
ENABLE NSExec.Error => IF type = invalidExec THEN GOTO Exit;
tty: TTY.Handle ← NSExec.GetTTY[exec];
name: CHName.Name ← NSExec.UserName[
exec ! NSExec.Error => GOTO Exit];
stopReason: NSString.String ← NSString.MakeString[bytes: PSState.maxStopReasonLength];
BEGIN
ENABLE
UNWIND =>
NSString.FreeString[z: PSExecInternal.execHeap, s: stopReason];
stopReason ← TextInput.GetText[tty: tty,
prompt: M[mEnterReason], text: stopReason,
minLength: 0, maxLength: PSState.maxStopReasonLength];
StopQueuingInternal[exec, name, stopReason];
END; --Enable clause and code
EXITS Exit => NULL;
END; --StopQueuing
StartDiagnostic:
PUBLIC NSExec.ExecProc =
BEGIN
ENABLE NSExec.Error => IF type = invalidExec THEN GOTO Exit;
outputHandle: XFormat.Handle ← NSExec.OutputHandle[exec];
IF Confirm[exec]
THEN
BEGIN
PSCommand.StartDiagnosticMode[];
outputHandle.Blanks[2];
outputHandle.NSLine[M[mDone]];
END;
EXITS Exit => NULL;
END; --StartDiagnostic
ShutDownPrinter:
PUBLIC NSExec.ExecProc =
BEGIN
ENABLE NSExec.Error => IF type = invalidExec THEN GOTO Exit;
IF Confirm[exec] THEN PSCommand.ShutDownEngine[];
EXITS Exit => NULL;
END; --ShutDownPrinter
WakeUpPrinter:
PUBLIC NSExec.ExecProc =
BEGIN
ENABLE NSExec.Error => IF type = invalidExec THEN GOTO Exit;
PSCommand.WakeUpEngine[];
EXITS Exit => NULL;
END; --WakeUpPrinter
ResetStatistics:
PUBLIC NSExec.ExecProc =
BEGIN
ENABLE NSExec.Error => IF type = invalidExec THEN GOTO Exit;
IF Confirm[exec] THEN PSCommand.ResetStatistics[];
EXITS Exit => NULL;
END; --ResetStatistics
RenamePrintService: PUBLIC NSExec.ExecProc = BEGIN
Rename the Print Service with the Clearinghouse.
ENABLE NSExec.Error => IF type = invalidExec THEN GOTO Exit;
outputHandle: XFormat.Handle ← NSExec.OutputHandle[exec];
BEGIN --Another nested block added so that Aborted EXIT may reference outputHandle.
IF Confirm[exec]
THEN
BEGIN
registerCode, unRegisterCode: PSExecInternal.RegCode;
Delete old service name from Clearinghouse:
XFormat.CR[outputHandle];
outputHandle.Blanks[4];
outputHandle.NSLine[M[mDeleteOldName]];
SELECT unRegisterCode ← DeleteServiceFromClearinghouse[exec]
FROM
aborted => GOTO Aborted;
checkClearinghouse =>
BEGIN
outputHandle.Blanks[8];
outputHandle.NSLine[M[mCheckClearinghouse]];
END;
ENDCASE => NULL;
Proceed to register new name with Clearinghouse:
XFormat.CR[outputHandle];
outputHandle.Blanks[4];
outputHandle.NSLine[M[mAddNewName]];
[registerCode,] ← RegisterServiceAtClearinghouse[exec];
SELECT registerCode
FROM
aborted => GOTO Aborted;
checkClearinghouse =>
BEGIN
outputHandle.Blanks[8];
outputHandle.NSLine[M[mCheckClearinghouse]];
END;
ENDCASE => NULL;
XFormat.CR[outputHandle];
outputHandle.Blanks[4];
outputHandle.NSLine[M[mBootForNameOnBanner]];
END;
EXITS
Aborted =>
BEGIN
XFormat.CR[outputHandle];
outputHandle.Blanks[4];
outputHandle.NSLine[M[mProblems]];
outputHandle.Blanks[4];
outputHandle.NSLine[M[mTryAgainLater]];
outputHandle.Blanks[4];
outputHandle.NSLine[M[mCheckClearinghouse]];
END;
END; --Extra nested block.
EXITS Exit => NULL;
END; --RenamePrintService
***************************
The 'internal' procs below were created rather than having Start and Stop call the StartPrinting, etc., ExecProcs so that if the user cancels the command in the middle of Start or Stop, they will not try to continue. (I.e. NSCommand.Error should be caught in only one place for each command processor.
StartPrintingInternal:
PROCEDURE [exec: NSExec.Handle, user: CHName.Name] =
BEGIN
outputHandle: XFormat.Handle ← NSExec.OutputHandle[exec];
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
outputHandle.NSLine[M[mStartingPrinting]];
PSCommand.StartPrinting[user
! PSCommand.Error =>
IF problem.errorType = documentInProgress
THEN {
Couldn't catalog fonts because a document (presumably a test
pattern) was in progress. So printing wasn't started.
outputHandle.NSLine[M[mUnableToCatalogFonts]];
GOTO Exit}];
IF
NOT PSCommand.GetPrintServiceStatus[].internalControl.markerEnabled
THEN
stringArray[0] ← M[mCurrentlyPreempted];
outputHandle.Blanks[2];
ExpandKeyAndPrint[exec, mDoneExpanded, stringArray];
EXITS Exit => NULL;
END; --StartPrintingInternal
StartQueuingInternal:
PROCEDURE [ exec: NSExec.Handle, user: CHName.Name] =
BEGIN
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
PSCommand.StartQueuing[user];
IF PSCommand.GetPrintServiceStatus[].internalControl.spooler # enabled
THEN
stringArray[0] ← M[mCurrentlyPreempted];
ExpandKeyAndPrint[exec, mQueuingStarted, stringArray];
END; --StartQueuingInternal
StopPrintingInternal:
PROCEDURE [ exec: NSExec.Handle, user: CHName.Name, reason: NSString.String ← NSString.nullString] =
BEGIN
outputHandle: XFormat.Handle ← NSExec.OutputHandle[exec];
outputHandle.NSLine[M[mStoppingPrinting]];
PSCommand.StopPrinting[user, reason];
outputHandle.Blanks[2];
outputHandle.NSLine[M[mDone]];
END; --StopPrintingInternal
StopQueuingInternal:
PROCEDURE [ exec: NSExec.Handle, user: CHName.Name, reason: NSString.String ← NSString.nullString] =
BEGIN
outputHandle: XFormat.Handle ← NSExec.OutputHandle[exec];
outputHandle.NSLine[M[mStoppingQueuing]];
PSCommand.StopQueuing[user, reason];
outputHandle.Blanks[2];
outputHandle.NSLine[M[mDone]];
END; --StopQueuingInternal
*********************
Support routines:
Confirm:
PROCEDURE [exec: NSExec.Handle]
RETURNS [response:
BOOLEAN] =
BEGIN
tty: TTY.Handle ← NSExec.GetTTY[exec];
response ← TextInput.GetYesNo[tty, M[mConfirm], yes] = yes;
END; --Confirm
ConfirmExpanded:
PROCEDURE [exec: NSExec.Handle, insertKey: PSExecMessages.Key]
RETURNS [response:
BOOLEAN] =
BEGIN
tty: TTY.Handle ← NSExec.GetTTY[exec];
stringArray: REF XMessage.StringArray ← NEW[XMessage.StringArray[1]];
freeThisString: NSString.String;
stringArray.data[0] ← M[insertKey];
freeThisString ← XMessage.Compose[M[mConfirmExpanded], stringArray];
response ← TextInput.GetYesNo[tty, freeThisString, yes] = yes;
NSString.FreeString[PSExecInternal.execHeap, freeThisString];
END; --ConfirmExpanded
DeleteServiceFromClearinghouse:
PUBLIC
PROCEDURE [exec: NSExec.Handle]
RETURNS [code: PSExecInternal.RegCode] =
BEGIN
UnRegister uses self-registration to remove stable data and CH entry for the Print Service. NOTE: Per Larry Kluger 7/9/84, authProblem should be treated as non-fatal (stable data is updated) because it usually means we couldn't reach the auth service.
<<THESE ARE FILE TYPES FROM INTERFACE PSAssignedTypes>>
unRegCode: SelfReg.UnRegisterCode;
unRegCode ← SelfReg.UnRegister[
primary: CHPIDs.ps, stableType: PSAssignedTypes.tSelfRegStableData,
exec: exec, clientID: psClientID, asyncMessage: FALSE];
printServiceName ← [NIL, NIL, NIL]; --Clear global variable.
SELECT unRegCode FROM
accessProblem, userAbort, other => code ← aborted;
authProblem, noClearinghouse, alreadyAlias, inUse, noStableData => code ← checkClearinghouse;
ENDCASE => code ← ok;
END; --DeleteServiceFromClearinghouse
DisplayCount:
PUBLIC
PROCEDURE [exec: NSExec.Handle, count:
CARDINAL, msg: PSExecMessages.Key] =
BEGIN
stringArray: REF XMessage.StringArray ← NEW [XMessage.StringArray[2]];
stringArray[0] ← NEW[TEXT[10]];
ExpandKeyAndPrint[exec, msg, stringArray];
END; -- DisplayCount
ExpandKeyAndPrint:
PUBLIC
PROCEDURE [exec: NSExec.Handle, template: PSExecMessages.Key, stringArray: PSExecInternal.ChoiceList] =
BEGIN
ExpandArrayAndPrint[exec, M[template], stringArray];
END; -- ExpandKeyAndPrint
ExpandArrayAndPrint:
PUBLIC
PROCEDURE [exec: NSExec.Handle, template: NSString.String, stringArray: PSExecInternal.ChoiceList] =
BEGIN
outputHandle: XFormat.Handle ← NSExec.OutputHandle[exec];
expandedString: NSString.String ← XMessage.Compose[template, stringArray];
outputHandle.NSLine[expandedString];
END; -- ExpandArrayAndPrint
ExpandArrayAndPrintAsync:
PUBLIC
PROCEDURE [template: NSString.String,
stringArray: PSExecInternal.ChoiceList] =
BEGIN
--Asynchronous messages are sent to all active execs.
expandedString: NSString.String ← XMessage.Compose[template, stringArray];
NSExec.BroadcastAsyncMessage[expandedString, psClientID]; --send async message to all active execs
NSString.FreeString[PSExecInternal.execHeap, expandedString];
END; -- ExpandArrayAndPrintAsync
Proc for getting a list of messages via XMessage and converting them to NSStrings
GetList:
PUBLIC
PROCEDURE [length:
CARDINAL, keys: PSExecInternal.KeyList,
stringArray: PSExecInternal.ChoiceList] =
BEGIN
maxStrings: CARDINAL = 10;
xs: REF XMessage.StringArray ← NEW[XMessage.StringArray[maxStrings]];
xKeys: REF XMessage.MsgKeyList ← NEW[XMessage.MsgKeyList[maxStrings]];
IF length > maxStrings THEN ERROR;
FOR i:
CARDINAL
IN [0..length)
DO
xKeys.data[i] ← ORD[keys.keys[i]];
ENDLOOP;
XMessage.GetList[execMsgs, xKeys, xs];
FOR i:
CARDINAL
IN [0..length)
DO
stringArray[i] ← xs.data[i];
ENDLOOP;
END;
GetSpecificDocStatus:
PROCEDURE [status: PSCommand.DocumentStatus]
RETURNS [specificStatus: PSCommand.SpecificDocStatus] =
BEGIN
WITH s: status
SELECT
FROM
pending => specificStatus ← s.specific;
inProgress => specificStatus ← s.specific;
rejected => specificStatus ← s.specific;
aborted => specificStatus ← s.specific;
canceled => specificStatus ← s.specific;
ENDCASE => specificStatus ← null;
END; --GetSpecificDocStatus
RegisterServiceAtClearinghouse: PUBLIC PROCEDURE [exec: NSExec.Handle] RETURNS [code: PSExecInternal.RegCode, serviceName: CHName.Name ← [NIL, NIL, NIL]] =
Register uses self registratin to prompt operator for new service name, creates new CH entry and stores name in stable data.
NOTE: Per Larry Kluger 7/9/84, authProblem should be treated as non-fatal (stable data is updated), because it usually means we couldn't reach the auth service.
BEGIN --Exported by PSExecInternal.
<<COMMENTED OUT BECAUSE THIS IMPLEMENTATION IS NOT CURRENTLY
SUPPORTED IN CEDAR>>
regCode: SelfReg.RegisterCode;
chDesc: CHEntries.PrimaryData ← NSString.nullString;
authKey: XNSAuth.Key;
[regCode, serviceName, chDesc, authKey] ← SelfReg.Register[
primary: CHPIDs.ps, stableType: PSAssignedTypes.tSelfRegStableData,
exec: exec, clientID: psClientID, operator: TRUE,
asyncMessage: FALSE, z: PSExecInternal.execHeap];
printServiceName ← serviceName; --Save name in global variable.
SELECT regCode FROM
alreadyAlias, inUse, badServiceName, noOperator, accessProblem, userAbort, other => code ← aborted;
authProblem, noClearinghouse => code ← checkClearinghouse;
ENDCASE => code ← ok;
END; --RegisterServiceAtClearinghouse
ShortenDateString:
PROCEDURE [sDate: NSString.String]
RETURNS [sShortDate: NSString.String] =
Returns date string with only day, month, hour and minutes stored in place of old string.
BEGIN
sOldDate: NSString.String ← NSString.CopyString[s: sDate];
onceAround: BOOLEAN ← FALSE;
i: CARDINAL ← 0;
hyphen: CHARACTER = '-;
colon: CHARACTER = ':;
blank: CHARACTER = ' ;
sDate.length ← 0;
sShortDate ← sDate;
Copy day and month, but skip year:
UNTIL sOldDate.text[i] = hyphen
AND onceAround
DO
sShortDate ← NSString.AppendCharacter[sShortDate, [0, LOOPHOLE[sOldDate.text[i]]]];
IF sOldDate.text[i] = hyphen THEN onceAround ← TRUE;
i ← i + 1;
ENDLOOP;
onceAround ← FALSE;
UNTIL sOldDate.text[i] = blank DO i ← i + 1; ENDLOOP;
Copy hours and minutes, but skip seconds:
UNTIL sOldDate.text[i] = colon
AND onceAround
DO
sShortDate ← NSString.AppendCharacter[sShortDate, [0, LOOPHOLE[sOldDate.text[i]]]];
IF sOldDate.text[i] = colon THEN onceAround ← TRUE;
i ← i + 1;
ENDLOOP;
NSString.FreeString[z: PSExecInternal.execHeap, s: sOldDate];
END; --ShortenDateString
19-Oct-84 16:00:45 - Jacks - Rename ttyHeap to execHeap; added feps9700 statuses to StringForDocStatus.
19-Nov-84 14:21:43 - Jacks - Added feps9700 specific stuff to CancelDocuments.
13-Dec-84 11:37:22 - Jacks - Removed ControlMessagesExtras.
16-Jan-85 15:34:38 - Jacks - Added "ps" prefix to all new msg keys for 9.0.
28-Feb-85 15:27:03 - Jacks - Raise error to turn off public error catching during development in certain exec procs.
28-Jun-85 15:02:54 - Jacks - Removed SetCatching calls.
26-Aug-85 10:45:01 - Jacks - Made arrays of booleans in DisplayDocuments and CancelDocuments PACKED ARRAYs to reduce local frame size.
10-Sep-85 13:45:50 - Jacks - Switched to PSCommandExtras.DocumentFilter because it requires less frame space.
24-Sep-85 14:24:20 - Jacks - PSCommandExtras folded into PSCommand.
13-Dec-85 16:42:23 - Jacks - ExecMessages renamed to PSExecMessages.