Trailing-Edge
-
PDP-10 Archives
-
BB-X117B-SB_1986
-
10,7/nml/ncpcex.b36
There is 1 other file named ncpcex.b36 in the archive. Click here to see a list.
! UPD ID= 323, SNARK:<6.1.NML>NCPCEX.B36.15, 8-May-85 21:36:50 by GLINDELL
! Allow dashes in ETHERNET addresses (HI and H formats). Add REMOVE_DASHES.
!
! UPD ID= 313, SNARK:<6.1.NML>NCPCEX.B36.10, 6-May-85 21:47:09 by GLINDELL
! Reinstate $KNSIG since SIGNIFICANT is back, but invisible in NCPTAB.
!
! UPD ID= 309, SNARK:<6.1.NML>NCPCEX.B36.9, 30-Apr-85 15:57:03 by GLINDELL
! Comment out $KNSIG since SIGNIFICANT is no longer part of NCPTAB
!
! UPD ID= 303, SNARK:<6.1.NML>NCPCEX.B36.8, 29-Apr-85 18:01:07 by GLINDELL
! NCP$SEND_RESPONSE has an extra argument - add that to all calls
!
! UPD ID= 262, SNARK:<6.1.NML>NCPCEX.B36.7, 1-Mar-85 09:59:54 by GLINDELL
! 1. TELL area.node used the area # for node number and ignored node #!
! - dot bugs in NCP$TELL.
! 2. Fixes for area typeout in SHOW QUEUE code.
!
! UPD ID= 199, SNARK:<6.1.NML>NCPCEX.B36.6, 10-Dec-84 15:05:57 by HALPIN
! Get MONSYM Library file out of default directory, not BLI:
!
! UPD ID= 168, SNARK:<6.1.NML>NCPCEX.B36.5, 15-Nov-84 13:40:35 by HALPIN
! Add Area.Node_Nmuber support in NCP$TELL.
!
! UPD ID= 79, SLICE:<6.1.NML>NCPCEX.B36.4, 18-Sep-84 14:48:33 by GUNN
! WORK:<GUNN.NML>NCPCEX.B36.2 21-Aug-84 12:00:54, Edit by GUNN
!
! Change to accomodate new LIBRARY conventions. MONSYM.L36 and JLNKG.L36
! are now explicity declared here rather than in NMULIB.
!
! UPD ID= 52, SNARK:<6.1.NML>NCPCEX.B36.3, 6-Jun-84 11:31:07 by HALPIN
! Undeclared $TOPS10, $TOPS20, $MCB, and $X25 preceding the Require GALAXY
! statement, because GALAXY.R36, requires SYSTYP.REQ, which has already
! been invoked.
!
! UPD ID= 22, SNARK:<6.1.NML>NCPCEX.B36.2, 24-May-84 14:00:34 by GLINDELL
! DSKT:NCPCEX.B36[10,6026,NML702] 10-Feb-84 11:33:44, Edit by DAVENPORT
!
! Change NCPTAB keyword names from $DNxxx to $KNxxx to avoid conflicts
! with DNET. UUO definitions in UUOSYM.R36.
!
! PH4:<HALPIN>NCPCEX.B36.3 26-Jan-84 14:55:59, Edit by HALPIN
!
! Ident 57.
! Fix call to NML$INFORMATION in ASSEMBLER. Was calling
! with the contents of DATA in the PARAMETER field, causing
! a failure return. This resulted in the incorrect assembly
! of the NICE message for a SHOW LOGGING FILE EVENTS KNOWN SINKS
! command.
!
! DSKT:NCPCEX.B36[10,6026,NML54] 18-Jan-84 15:19:33, Edit by DAVENPORT
!
! Add back code to convert userid, account, and password to upper case
! that was lost by Edit 42. This is a short term fix until the MCB
! is changed to do this conversion on incoming account information.
!
! DSKC:NCPCEX.B36[10,5665,SOURCE,TOPS10] 22-Nov-83 15:40:08, Edit by GROSSMAN
!
! Disable the routine QUOTE_FIELD for TOPS-10 in order to prevent quoting
! characters from ending up in DECnet CI messages.
!
! PH4:<HALPIN>NCPCEX.B36.2 7-Dec-83 16:44:15, Edit by HALPIN
!
! Ident 56.
! Fix the formatting of HI-n NICE parameter value. Create a new routine
! CVATHI similar to CVATH to do it but not reversing the value string.
! From PVC:<VOBA.NML.DEVELOPMENT>NCPCEX.B36.7
!
! PH4:<GLINDELL>NCPCEX.B36.2 17-Nov-83 09:44:48, Edit by GLINDELL
!
! Ident 55.
! Make CVLTU (Convert lower to upper case) global for the use of
! other modules. In future, move this and other similar routines
! to some 'general' module.
!
!<MCINTEE.WORK>NCPCEX.B36.8, 9-Sep-83 12:10:21, Edit by MCINTEE
!
! Ident 54.
! x.y node number format support
!
!<MCINTEE.WORK>NCPCEX.B36.2, 5-Aug-83 13:13:41, Edit by MCINTEE
!
! Ident 53.
! AREA entity bug fix
!
!<MCINTEE.WORK>NCPCEX.B36.2, 26-Jul-83 14:55:45, Edit by MCINTEE
!
! Ident 52.
! Add in references to subentity type. Subentity type is needed at this
! level.
!
!<MCINTEE.WORK>NCPCEX.B36.2, 13-Jul-83 08:31:36, Edit by MCINTEE
!
! Ident 51.
! Remove all references to subentity type. All that is now
! handled in NMLNIC.
!
!<MCINTEE.WORK>NCPCEX.B36.4, 7-Jul-83 10:51:05, Edit by MCINTEE
!
! Ident 50.
! Add new module entities for phase IV
!
!<MCINTEE.WORK>NCPCEX.B36.18, 14-Jun-83 11:23:32, Edit by MCINTEE
!
! Ident 49.
! Add in AREA entity, ADJACENT_ and SIGNIFICANT_ selectors
! Change ENTITY type constant names to new style.
!
! PH4:<PECKHAM>NCPCEX.B36.13 17-May-83 13:36:20, Edit by PECKHAM
!
! Ident 48.
! Fix ASSEMBLER to use NML$DATA_TYPE to determine how to format
! the data. This also required a change in the calling sequence
! from the routine NICE_PARM to include the entity type and
! parameter number.
!
! <BRANDT.DEVELOPMENT>NCPCEX.B36.1 6-Dec-82 15:15:21, Edit by BRANDT
!
! Ident 47.
! Fix NICE_PARM and NM_PARMS so that qualifiers for EVENTS are
! included in NICE messages.
!
! <BRANDT.DEVELOPMENT>NCPCEX.B36.1 6-Dec-82 12:51:12, Edit by BRANDT
!
! Ident 46.
! In QUOTE_FIELD return the length of the new string with embedded
! ^V chars.
!
! <BRANDT.DEVELOPMENT>NCPCEX.B36.1 28-Sep-82 14:01:12, Edit by BRANDT
!
! Ident 45.
! In NICE_INITIALIZE also set RB_NICE_FUNCTION in the request
! block.
!
! <BRANDT.DEVELOPMENT>NCPCEX.B36.1 16-Sep-82 17:34:21, Edit by BRANDT
!
! Ident 44.
! In NM_PARMS special case a PARM_TYPE of P$ALL (377777) since it
! has bit 16 set and now looks like a qualifier keyword.
!
! <BRANDT.DEVELOPMENT>NCPCEX.B36.1 27-Aug-82 11:54:12, Edit by BRANDT
!
! Ident 43.
! In NICE_TEST update RB_NICE_POINTER when access control info is
! supplied.
!
! NET:<PECKHAM.DEVELOPMENT>NCPCEX.B36.2 26-Jun-82 15:55:11, Edit by PECKHAM
!
! Ident 42.
! QUOTE_FIELD was moving one-too-many characters. This caused it to quote
! all trailing nulls (caused by a second bug), thus overwriting memory.
! Both bugs fixed.
! NOTE: this indicates a data-base bug in the XCTR data base. It does not
! have enough room allocated for poossible quoted characters.
! Double length of buffers in NCP$LOOP and XCTR_BLOCK (NCPCOM).
!
! NET:<PECKHAM.DEVELOPMENT>NCPCEX.B36.4 23-Jun-82 12:24:51, Edit by PECKHAM
!
! Ident 41.
! Set privledged bits in request block (user has at least operator privledges).
!
! NET:<PLATUKIS>NCPCEX.B36.2 14-Jun-82 14:59:10, Edit by PLATUKIS
!
! ident 40
! change algorithm of known qualifier keywords.
!
! NET:<PECKHAM.DEVELOPMENT>NCPCEX.B36.2 28-May-82 21:06:15, Edit by PECKHAM
!
! Ident 39.
! Fix CVATH to insert HEX strings with low order byte first.
! This showed up first a screwy SERVICE PASSWORDS.
! Also make fixes to ASSEMBLER cases HI and HX8.
!
! NET:<BRANDT.DEVELOP>NCPCEX.B36.1 28-Apr-82 11:15:47, Edit by BRANDT
!
! Ident 38.
! Change error message on DEFINE / PURGE EXECUTOR commands.
!
! NET:<VOBA.NML.DEVELOPMENT>NCPCEX.B36.7 9-Apr-82 14:39:42, Edit by VOBA
!
! Ident 37.
! Fix CVATH to use -1 as the invalid character in the HEX conversion table
! instead of 0.
!
! NET:<VOBA.NML.DEVELOPMENT>NCPCEX.B36.8 26-Mar-82 18:26:46, Edit by VOBA
!
! Ident 36.
! Fix to code to use PUTW to write parameter number in NICE message
! construction.
!
! NET:<VOBA.NML.DEVELOPMENT>NCPCEX.B36.5 25-Mar-82 20:34:26, Edit by VOBA
!
! Ident 35.
! Debug in NICE_PARM routine.
!
! NET:<VOBA.NML.DEVELOPMENT>NCPCEX.B36.2 25-Mar-82 19:02:28, Edit by VOBA
!
! Ident 34.
! Fix code to raise case of CIRCUIT entity id string.
!
! NET:<VOBA.NML.DEVELOPMENT>NCPCEX.B36.25 25-Mar-82 17:05:26, Edit by VOBA
!
! Ident 33.
! Remove default qualifiers for MODULE entity from routine DEFAULT_QUALIFIER.
! Fix NICE_PARM to build NICE parameter data for MODULE clear request to
! accomodate qualifier data.
! Fix NM_PARMS to parse parameters of CLEAR commands as value keywords.
! These should be defined in the NCP parsing table NCPTAB as value keywords.
! Qualified parameters of CLEAR commands are parsed as regular parameters.
!
! NET:<VOBA.NML.DEVELOPMENT>NCPCEX.B36.4 16-Mar-82 13:16:57, Edit by VOBA
!
! Ident 32.
! Fix NM_PARMS to calculate X25-PROTOCOL KNOWN qualifier parameter
! numbers correctly.
!
! NET:<VOBA.NML.DEVELOPMENT>NCPCEX.B36.3 15-Mar-82 17:35:34, Edit by VOBA
!
! Ident 31.
! Fix DEFAULT_QUALIFIER to format SINK EXECUTOR NODE correctly.
!
! NET:<VOBA.NML.DEVELOPMENT>NCPCEX.B36.18 15-Mar-82 16:01:01, Edit by VOBA
!
! Ident 30.
! Add code to recognize all qualifiers of the SHOW commands.
! Fix ASSEMBLER to assemble only non-zero mask bytes of the EVENTS parameter.
!
! NET:<VOBA.NML.DEVELOPMENT>NCPCEX.B36.4 15-Mar-82 10:21:47, Edit by VOBA
!
! Ident 29.
! Fix READ_OPTION to recognize EVENTS option of the SHOW LOGGING command.
!
! <VOBA.NML.DEVELOPMENT>NCPCEX.B36.13 12-Mar-82 13:35:33, Edit by VOBA
!
! Ident 28.
! Fix NCP_READ to process qualifier parameters of SHOW MODULE commands.
! Fix READ_OPTION not to bother with the TO parameter.
! Remove TOPS-10 file handling code (not needed any more).
!
! NET:<GROSSMAN.NML-SOURCES>NCPCEX.B36.3 8-Mar-82 11:26:07, Edit by GROSSMAN
!
! Ident 27.
! Add some calls to NMU$MEMORY_RELEASE at the end of the SHOW_QUEUE routine.
! These calls will deallocate the REQuest blocks and associated data bases that
! would normally be deallocated by the completion routine for a command. Since
! there is no completion routine for SHOW QUEUE, these weren't getting
! released.
!
! NET:<VOBA.NML.DEVELOPMENT>NCPCEX.B36.4 1-Mar-82 14:44:02, Edit by VOBA
!
! Ident 26.
! Assign HI a distinct value different from AI.
! Fix CVATH to recognize hexadecimal digits in lower case also.
!
! NET:<PECKHAM.DEVELOPMENT>NCPCEX.B36.5 26-Feb-82 13:38:34, Edit by PECKHAM
! NET:<VOBA.NML.DEVELOPMENT>NCPCEX.B36.11 26-Feb-82 10:50:48, Edit by VOBA
!
! Ident 25.
! Fix NICE_PARM to reference local data structure, instead of the one defined
! in NMLPRM.
! Surround response texts by $NML$TEXT and convert to lower case;
! $NML$TEXT in NMARCH can be made to raise case if necessary.
!
! NET:<PECKHAM.DEVELOPMENT>NCPCEX.B36.2 24-Feb-82 08:40:54, Edit by PECKHAM
!
! Ident 24.
! Undo last fix, as bug was in inconsistency in NCPTAB.
!
! NET:<PECKHAM.DEVELOPMENT>NCPCEX.B36.2 24-Feb-82 08:02:07, Edit by PECKHAM
!
! Ident 23.
! Fix NM_ENTITY to set the proper FORMAT for logging sinks.
!
! <VOBA.NML.DEVELOPMENT>NCPCEX.B36.16 22-Feb-82 10:28:46, Edit by VOBA
!
! Ident 22.
! Remove NICE parameter definition tables and use the ones already defined
! in NMLPRM. Replaced NP_xxx routines by a single NICE message assembly
! routine, ASSEMBLER.
!
! Fix the checking of the request message type in NCP$QUEUE_REQUEST from
! GETB to ch$rchar in order not to clobber data buffer.
!
! NET:<VOBA.NML>NCPCEX.B36.176 25-Jan-82 16:13:41, Edit by VOBA
!
! Ident 21.
! Remove code from NM_PARMS to create new routines NM_REMOTE (to parse
! remote file name) and NM_NUMBER, NM_EVENT (to parse numeric range and
! event list) for better management and debugging.
!
! Rewrite NP_EVENT to build NICE message for LOGGING parameter correctly.
!
! Adjust pointer in NCP$TELL not to overwrite node number in TELL command.
!
! Remove reference to NCP$ABORT routine. The routine is kept for future
! possible reuse.
!
! NET:<BRANDT.DEVELOP>NCPCEX.B36.1 21-Jan-82 12:45:47, Edit by BRANDT
!
! Ident 20.
! Terminate text for SHOW QUEUE command with a carriage return.
!
! NET:<PECKHAM.DEVELOPMENT>NCPCEX.B36.3 21-Jan-82 09:51:18, Edit by PECKHAM
!
! Ident 19.
! Add DMP parameters and clean up for NM V3.0.0
!
! NET:<BRANDT.DEVELOPMENT>NCPCEX.B36.7 12-Jan-82 16:55:47, Edit by BRANDT
!
! Ident 18.
! Terminate text for SHOW QUEUE command with a null byte.
!
! NET:<BRANDT.DEVELOPMENT>NCPCEX.B36.7 11-Jan-82 11:55:47, Edit by GUNN
!
! Ident 17.
! Update copyright date to 1982.
! Fix calls to NCP$SEND_RESPONSE to pass proper 'MORE' flag.
! Fix code to use NMU debug facility rather than location 135.
!
! NET:<VOBA.NML>NCPCEX.B36.133 11-Jan-82 10:00:05, Edit by VOBA
!
! Ident 16.
! Update NM_PARMS to recognize full NCP command syntax.
! Add parsing routines and parsing look up tables for all NCP commands.
!
! NET:<BRANDT.DEVELOP>NCPCEX.B36.1 17-Dec-81 16:28:57, Edit by BRANDT
!
! Ident 15.
! Fix routine NM_PARMS so that no parameters are included in the
! NICE message for commands like "CLEAR CIRCUIT foo ALL".
!
! NET:<DECNET20-V3P1.NCP.SOURCES>NCPCEX.B36.3 2-Jun-81 16:37:23, Edit by GUNN
!
! Ident 14.
! Fix text of SHOW QUEUE output to print node address as decimal.
! Output ACCEPTED message if command is LOAD, DUMP or LOOP.
!
! NET:<DECNET20-V3P1.NCP.SOURCES>NCPCEX.B36.2 27-May-81 17:17:52, Edit by GUNN
!
! Ident 13.
! Change NICE_TEST to allow CIRCUIT entity and be more defensive about
! other entity types.
!
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NCPCEX.B36.44 21-May-81 09:51:58, Edit by JENNESS
!
! Change debugging code in NCP$QUEUE_REQUEST to use a page buffer instead
! of the text buffer. It was overrunning the end when interpreting the
! NICE message.
!
! ***** Note that the same problem still exists in the SHOW QUEUE processing.
!
! NET:<DECNET20-V3P1.NCP.SOURCES>NCPCEX.B36.2 13-Apr-81 17:29:20, Edit by GUNN
!
! Always pass entity type of NODE when calling NM_PARMS from NCP_BOOT.
! All parameters are associated with NODE although NCP command entity
! may be circuit.
!
! NET:<DECNET20-V3P1.NCP.SOURCES>NCPCEX.B36.11 9-Apr-81 14:17:21, Edit by GUNN
!
! Add code to handle SERVICE PASSWORD in NICE_PARM routine. Add routine
! CVATH to convert an ASCII string containing only the characters
! 0-9 & A-F to an 8 bit hexadecimal string.
!
! NET:<DECNET20-V3P1.NCP.SOURCES>NCPCEX.B36.2 7-Apr-81 10:46:11, Edit by GUNN
!
! Fix NCP_BOOT to write option byte in the NICE request message.
!
! NET:<DECNET20-V3P1.NCP.SOURCES>NCPCEX.B36.4 3-Apr-81 17:21:00, Edit by GUNN
!
! Fix NCP$TELL to build executor node id in internal format.
!
! NET:<DECNET20-V3P1.NCP.SOURCES>NCPCEX.B36.3 9-Mar-81 09:59:40, Edit by GUNN
!
! Fix NICE_TEST to prefix access control strings with I-field length byte
! in NICE message. Use individual CH$MOVE rather than CH$COPY for each
! field.
!
! NET:<DECNET20-V3P1.NCP.SOURCES>NCPCEX.B36.2 6-Mar-81 21:23:36, Edit by GUNN
!
! Fix NCP$LOOP to handle all combinations of access control and parameters.
!
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NCPCEX.B36.39 13-Feb-81 16:09:28, Edit by GUNN
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NCPCEX.B36.38 9-Feb-81 16:40:10, Edit by GUNN
!
! Fix test for presence of access control arguments in NICE_TEST routine to
! be based on lengths rather than pointers. In call from NCP$LOOP add dot
! operator to pass length values rather than address of values.
!
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NCPCEX.B36.37 9-Feb-81 15:00:05, Edit by GUNN
!
! Make ACCESS_CONTROL routine return parsed item type when it is other
! than keyword.
! Backup parse of keywords in NPC$LOOP after access control only if it is
! a keyword.
!
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NCPCEX.B36.34 5-Feb-81 17:00:22, Edit by GUNN
!
! Miscellaneous source code cleanup.
!***** NOTE: Still to be done is to go through and make sure all references
! to the NICE option byte use the structures defined in NMARCH.REQ
!
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NCPCEX.B36.33 4-Feb-81 19:37:04, Edit by GUNN
!
! Move call to NML$REQUEST_ENTER back to before formatting of accepted
! message in routine NCP$QUEUE_REQUEST to fix print out of garbage
! request number.
!
! Update copyright date to 1981.
!
%title 'NCPCEX -- NCP Command EXecutor'
module NCPCEX (
ident ='X03.57'
) =
begin
!
! COPYRIGHT (c) 1980, 1981, 1982 BY
! DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
!
! THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
! ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
! INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
! COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
! OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
! TRANSFERRED.
!
! THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
! AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
! CORPORATION.
!
! DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
! SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
!
!++
! FACILITY: DECnet-10/20 V3.0 Network Control Program (NCP)
!
! ABSTRACT:
!
! Executes commands, parsed by OPR and transmitted to NCP via ORION, in
! GALAXY IPCF messages. The blocks are formatted as GALAXY MS blocks as
! described in the Final Functional Specification for the New Operator
! Interface, MLB-78-004-S, 6-Jul-79. The received MS command blocks are
! transformed to NICE messages and passed to NML for execution.
!
! ENVIRONMENT: TOPS-10/20 User mode under NML
!
! AUTHOR: Dale C. Gunn , CREATION DATE: 28-Aug-80
!
! MODIFIED BY:
!
! , : VERSION
! 01 -
!--
!
! INCLUDE FILES:
!
library 'NCPLIB'; ! All required definitions
%if $TOPS20
%then
library 'MONSYM'; ! Monitor symbols
library 'JLNKG'; ! JSYS linkage definitions
%fi
! gets SYSTYP.REQ also
library 'GALAXY'; ! GALAXY interface definitions
require 'NCPEXT'; ! NCP External Names
!
! TABLE OF CONTENTS
!
forward routine
NCP$COMMAND_INITIALIZE, ! Initialize data base for NCPCEX
NCP$COMMAND, ! Process NCP IPCF command message
NCP$DISPATCH_COMMAND, ! Route to command specific routine
NCP$ABORT, ! Process ABORT command
NCP$CANCEL, ! Process CANCEL command
NCP$CLEAR, ! Process CLEAR command
NCP$DEFINE, ! Process DEFINE command
NCP$DUMP, ! Process DUMP command
NCP$LIST, ! Process LIST command
NCP$LOAD, ! Process LOAD command
NCP$LOOP, ! Process LOOP command
NCP$PURGE, ! Process PURGE command
NCP$SET, ! Process SET command
NCP$SHOW, ! Process SHOW command
NCP$TELL, ! Process TELL prefix
NCP$TRIGGER, ! Process TRIGGER command
NCP$ZERO, ! Process ZERO command
NCP$REQUEST_INITIALIZE : novalue, ! Initialize NML request
NCP$QUEUE_REQUEST : novalue, ! Queue NICE request message to NML
NM_ENTITY, ! Process entity in IPCF format
NM_PARMS, ! Process parameters in IPCF format
NCP_READ, ! Common SHOW/LIST processing
DEFAULT_QUALIFIER : novalue, ! Process SHOW qualifiers
SHOW_QUEUE : novalue, ! Perform SHOW QUEUE command
NCP_CHANGE, ! Common SET/CLEAR/DEFINE/PURGE process
NCP_BOOT, ! Common LOAD/DUMP/TRIGGER processing
CVSTA : novalue, ! Convert SIXBIT node name to ASCII
CVLTU : novalue, ! Convert string to upper case
CVATH, ! Convert ASCII string to 8 bit HEX
CVATHI, ! Convert ASCII string to HEX image
REMOVE_DASHES, ! Remove dashes from an ETHERNET addr
SET_XCTR, ! Perform SET EXECUTOR command
CLEAR_XCTR, ! Perform CLEAR EXECUTOR command
ACCESS_CONTROL, ! Process access control fields
QUOTE_FIELD, ! Quote string with ^V character
SCAN_XCTR_Q, ! Search EXECUTOR data base
READ_OPTION, ! Build READ option byte
NICE_INITIALIZE : novalue, ! Initialize NICE message
NICE_OPTION : novalue, ! Store option byte in NICE message
NICE_TEST : novalue, ! Store NICE test message fields
NICE_ENTITY : novalue, ! Store entity id in NICE message
NICE_PARM, ! Store a parameter in NICE message
ASSEMBLER : novalue, ! Assemble parameters in NICE message
PUTBUF: novalue; ! Format a NICE message for display
!
! MACROS:
!
macro
CH$EXPLODE [] =
CH$CHTAB (%quote %explode (%remaining)) %;
macro
CH$CHTAB [CH] =
%quote %c CH %;
!
! EQUATED SYMBOLS:
!
literal
NICE_BUFFER_LENGTH = 1000, ! NICE buffer size in bytes
NICE_BUFFER_SIZE = ch$allocation (NICE_BUFFER_LENGTH,8), ! In fullwords
NICE_BUFFER_ALLOCATION = NICE_BUFFER_SIZE * %upval; ! In units
!
! OWN STORAGE:
!
own
REQ: ref REQUEST_BLOCK; ! Address of NML request block
own
CMD_PTR, ! Pointer to command text string
ACK_COD, ! Operator ACK code (PID of OPR)
XCTR_NOD_Q: Q_HEADER; ! Head of EXECUTOR node queue
own
TELL_BLOCK_ADDR, ! Address of dynamic TELL block
TELL_BLOCK: ref block [XCTR_SZ] field (XCTR_FIELDS); ! Address of TELL block
bind ! SIXBIT to ASCII translation table
SIXTAB = ch$transtable (CH$EXPLODE (' !"#$%&'), %c'''',
CH$EXPLODE ('()*+,-./0123456789:'),
CH$EXPLODE (';<=>?@ABCDEFGHIJKLM'),
CH$EXPLODE ('NOPQRSTUVWXYZ[\]^_'));
bind ! ASCII to HEX translation table
HEXTAB = ch$transtable (rep 48 of (-1), ! Invalid HEX digits
0,1,2,3,4,5,6,7,8,9,
rep 7 of (-1),
10,11,12,13,14,15, ! HEX digits (upper case)
rep 26 of (-1),
10,11,12,13,14,15, ! HEX digits (lower case)
rep 25 of (-1));
own
TEXT_PTR; ! @@@@@ Temporary for debug @@@@@
!
! EXTERNAL REFERENCES:
!
external routine
NCP$GET_COMMAND, ! Read Next Command Message
NCP$SEND_TO_OPERATOR, ! Send Unsolicited Message to Operator
NCP$SEND_RESPONSE, ! Send Command Response to Operator
NCP$DEQUEUE_RESPONSE, ! NICE Response Processing Routine
NML$DATA_TYPE, ! Return data type/format
NML$UPPER_CASE, ! Check if text must be upper case
NML$INFORMATION, ! Check information type applicability
NMU$NETWORK_LOCAL; ! Get local node name
external routine ! GALAXY routines
P$SETUP: GALXYS, ! OPRPAR semantic setup
P$NFLD: GALXYO, ! OPRPAR semantic routines
P$NARG: GALXYO,
P$PREV: GALXYO,
P$CFM: GALXYO,
P$KEYW: GALXYO,
P$SWIT: GALXYO,
P$USER: GALXYO,
P$NUM: GALXYO,
P$FILE: GALXYO,
P$IFIL: GALXYO,
P$OFIL: GALXYO,
P$FLD: GALXYO,
P$TOK: GALXYO,
P$NODE: GALXYO,
P$SIXF: GALXYO,
P$RNGE: GALXYO,
P$TEXT: GALXYO,
P$DIR: GALXYO,
P$FLOT: GALXYO,
P$TIME: GALXYO,
P$DEV: GALXYO,
P$QSTR: GALXYO,
P$COMMA:GALXYO,
P$UQSTR:GALXYO,
P$ACCT: GALXYO;
external %debug_data_base;
%global_routine ('NCP$COMMAND_INITIALIZE') =
!++
! FUNCTIONAL DESCRIPTION:
!
! Initializes data base for NCPCEX module.
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! True, always.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
NMU$QUEUE_RESET (XCTR_NOD_Q); ! Initialize the EXECUTOR node queue
return 1 ! Always succeeds
end; ! End of NCP$COMMAND_INITIALIZE
%global_routine ('NCP$COMMAND', MS) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Provides the top level NCP command proccessing. Processes a
! GALAXY command message (type .OMCMD), in standard MS block
! format as defined in GLXMAC.MAC, which represents an NCP
! command parsed by OPR. Calls NCP$DISPATCH_COMMAND, with the
! command keyword code, to dispatch to the appropriate NCP
! command specific processing routine.
!
! FORMAL PARAMETERS
!
! MS - Address of the received MS block.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! True if first argument of command message is a keyword,
! false otherwise.
!
! SIDE EFFECTS:
!
! (1) The current position within the PB portion of the MS block
! is initialized to the first PB argument.
!
! (2) A NICE protocol message is created which represents the NCP
! command.
!
!--
begin
local
TEMP; ! local work variable
bind
COM = MS; ! Make MS and COM overlay
map
MS: ref MS_BLOCK (PAGE_SIZE), ! Structure for MS block
COM: ref COM_BLOCK (PAGE_SIZE); ! Structure for COM block
NCP$REQUEST_INITIALIZE (.MS[CODMS$],.CMD_PTR); ! Initialize the request
ACK_COD = .MS[CODMS$]; ! Get and save ACK code of operator
CMD_PTR = ch$ptr(.MS + .COM[CM$COM] + 1); ! Save pointer to command text
if not P_SETUP (.MS + .COM[PB$COM]) ! Initial address of PB (Parse Block)
then $INTERNAL_ERROR$ ('OPRPAR Failure'); ! But this should never fail
if P_NARG (TEMP)
then if .TEMP eql $CMKEY
then begin
P_KEYW (TEMP);
NCP$DISPATCH_COMMAND (.TEMP)
end
else $INTERNAL_ERROR$ ('Invalidly formatted command message block')
else $INTERNAL_ERROR$ ('No fields in message block')
end; ! End of NCP$COMMAND
%routine ('NCP$DISPATCH_COMMAND', KEY_CODE) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Dispatches to the appropriate NCP command processing routine
! based on the command keyword code.
!
! FORMAL PARAMETERS
!
! Value of command keyword code.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! Value of command specific routine,
! if the command keyword code is valid;
! false otherwise.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
case .KEY_CODE from $KNCAN to $KNZRO of
set
[$KNCAN]:
NCP$CANCEL ();
[$KNCLR]:
NCP$CLEAR ();
[$KNDEF]:
NCP$DEFINE ();
[$KNDMP]:
NCP$DUMP ();
[$KNLST]:
NCP$LIST ();
[$KNLOD]:
NCP$LOAD ();
[$KNLOP]:
NCP$LOOP ();
[$KNPUR]:
NCP$PURGE ();
[$KNSET]:
NCP$SET ();
[$KNSHW]:
NCP$SHOW ();
[$KNTEL]:
NCP$TELL ();
[$KNTRG]:
NCP$TRIGGER ();
[$KNZRO]:
NCP$ZERO ();
[inrange,
outrange]:
$INTERNAL_ERROR$ ('Invalid command keyword code')
tes
end; ! End of NCP$DISPATCH_COMMAND
%routine ('NCP$ABORT') =
!++
! FUNCTIONAL DESCRIPTION:
!
! Performs semantic analysis and processing for ABORT command.
! Scans NML Request Queue for entry with a request number which
! matches the one given in the command. If found it is removed
! from the queue. NCP$SEND_RESPONSE is called to provide an
! appropriate indication of action taken.
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! Current position within the PB portion of the MS block.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
literal
TEXT_BUFFER_LENGTH = 80, ! Length of text buffer in characters
TEXT_BUFFER_SIZE = ! Size in fullwords
ch$allocation (TEXT_BUFFER_LENGTH),
TEXT_BUFFER_ALLOCATION = ! Size of allocation in units
TEXT_BUFFER_SIZE * %upval,
TXT_BFR_SZ = 80; ! A screenful
local
TXT_BFR, ! Text buffer address for response text
TEMP; ! Local work variable
if (P_KEYW(TEMP) and .TEMP eql $KNQUE)
then if (P_KEYW(TEMP) and .TEMP eql $KNREQ)
then if (P_NUM(TEMP))
then begin
TXT_BFR = NMU$MEMORY_GET (TXT_BFR_SZ); ! Get text buffer
TEXT_PTR = ch$ptr(.TXT_BFR);
if NML$REQUEST_ABORT (.TEMP) ! Try to abort this request #
then $NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
$NML$TEXT ('Request # %D Aborted'),
.TEMP)
else $NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
$NML$TEXT ('Request # %D Does not exist'),
.TEMP);
TEMP = NCP$SEND_RESPONSE (0,ch$ptr(.TXT_BFR),.ACK_COD, 0);
NMU$MEMORY_RELEASE (.TXT_BFR,TXT_BFR_SZ); ! Release buffer
return .TEMP
end
else $INTERNAL_ERROR$ ('Request number not present')
else $INTERNAL_ERROR$ ('REQUEST keyword not present')
else $INTERNAL_ERROR$ ('QUEUE keyword not present')
end; ! End of NCP$ABORT
%routine ('NCP$CANCEL') =
!++
! FUNCTIONAL DESCRIPTION:
!
! Performs semantic analysis and processing for CANCEL command.
! Scans NML Request Queue for entry with a request number which
! matches the one given in the command. If found it is removed
! from the queue. NCP$SEND_RESPONSE is called to provide an
! appropriate indication of action taken.
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! Current position within the PB portion of the MS block.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
literal
TEXT_BUFFER_LENGTH = 80, ! Length of text buffer in characters
TEXT_BUFFER_SIZE = ! Size in fullwords
ch$allocation (TEXT_BUFFER_LENGTH),
TEXT_BUFFER_ALLOCATION = ! Size of allocation in units
TEXT_BUFFER_SIZE * %upval,
TXT_BFR_SZ = 80; ! A screenful
local
TXT_BFR, ! Text buffer address for response text
TEMP; ! Local work variable
if (P_KEYW(TEMP) and .TEMP eql $KNQUE)
then if (P_KEYW(TEMP) and .TEMP eql $KNREQ)
then if (P_NUM(TEMP))
then begin
TXT_BFR = NMU$MEMORY_GET (TXT_BFR_SZ); ! Get text buffer
TEXT_PTR = ch$ptr(.TXT_BFR);
selectone NML$REQUEST_CANCEL (.TEMP) of
set
[0]: $NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
$NML$TEXT ('Request # %D cancelled'),
.TEMP) ;
[1]: $NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
$NML$TEXT ('Request # %D does not exist'),
.TEMP);
[2]: $NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
$NML$TEXT ('Request # %D is active. It cannot be cancelled'),
.TEMP);
tes;
TEMP = NCP$SEND_RESPONSE (0,ch$ptr(.TXT_BFR),.ACK_COD, 0);
NMU$MEMORY_RELEASE (.TXT_BFR,TXT_BFR_SZ); ! Release buffer
return .TEMP
end
else $INTERNAL_ERROR$ ('Request number not present')
else $INTERNAL_ERROR$ ('REQUEST keyword not present')
else $INTERNAL_ERROR$ ('QUEUE keyword not present')
end; ! End of NCP$CANCEL
%routine ('NCP$CLEAR') =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
literal
VOLATILE_ = 0, ! Change volatile parameters
CLEAR_PURGE = 1; ! Perform CLEAR_PURGE
NICE_INITIALIZE (CLEAR_); ! Initialize NICE message
if NCP_CHANGE (VOLATILE_,CLEAR_PURGE)
then $TRUE
else $INTERNAL_ERROR$ ('Invalid syntax in CLEAR command')
end; ! End of NCP$CLEAR
%routine ('NCP$DEFINE') =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
literal
PERMANENT_ = 1, ! Change permanent parameters
SET_DEFINE = 0; ! Perform SET/DEFINE
NICE_INITIALIZE (DEFINE_); ! Initialize NICE message
if NCP_CHANGE (PERMANENT_,SET_DEFINE)
then $TRUE
else $INTERNAL_ERROR$ ('Invalid syntax in DEFINE command')
end; ! End of NCP$DEFINE
%routine ('NCP$DUMP') =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
NICE_INITIALIZE (DUMP_); ! Initialize NICE message
NCP_BOOT () ! Do the common boot processing
end; ! End of NCP$DUMP
%routine ('NCP$LIST') =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
literal
PERMANENT = 1; ! Read permanent parameters
NICE_INITIALIZE (LIST_); ! Initialize NICE message
if NCP_READ (PERMANENT)
then $TRUE
else $INTERNAL_ERROR$ ('Invalid syntax in LIST command')
end; ! End of NCP$LIST
%routine ('NCP$LOAD') =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
NICE_INITIALIZE (LOAD_); ! Initialize NICE message
NCP_BOOT () ! Do the common boot processing
end; ! End of NCP$LOAD
%routine ('NCP$LOOP') =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! Current position within the PB portion of the MS block.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
local
TEMP,
OPTION_BYTE,
ENTITY_TYPE : FULL_ENTITY,
FORMAT,
LENGTH,
ENTITY_POINTER,
USR_LEN,
ACT_LEN,
PWD_LEN,
USR_STRING: ch$sequence (2*16),
PWD_STRING: ch$sequence (2*16),
ACT_STRING: ch$sequence (2*16);
NICE_INITIALIZE (LOOP_); ! Initialize NICE message
if (TEMP = NM_ENTITY (ENTITY_TYPE, ! Get entity field from command
FORMAT,
LENGTH,
ENTITY_POINTER))
then (case .ENTITY_TYPE[ENTITY_MAIN] from ENTITY_LO to ENTITY_HI of
set
[ENTITY_NODE]: ! NODE
begin ! Special case for NODE id
local
NODE_STRING: CH$SEQUENCE(6,8); ! Storage for node name
CVSTA (.FORMAT, ! Convert node id to string
.LENGTH,
.ENTITY_POINTER,
ch$ptr(NODE_STRING,,8));
!
! Get access control fields, returning next keyword code
!
TEMP = ACCESS_CONTROL (ch$ptr(USR_STRING),USR_LEN,
ch$ptr(ACT_STRING),ACT_LEN,
ch$ptr(PWD_STRING),PWD_LEN);
if .TEMP neq N$XACT ! If next item was keyword
then P_PREV (); ! Back up to make NM_PARMS work
NICE_TEST (ch$ptr(USR_STRING),.USR_LEN,
ch$ptr(PWD_STRING),.PWD_LEN,
ch$ptr(ACT_STRING),.ACT_LEN,
.ENTITY_TYPE,
.FORMAT,
.LENGTH,
ch$ptr(NODE_STRING,,8));
end;
[ENTITY_LINE, ! LINE & CIRCUIT
ENTITY_CIRCUIT]:
begin
NICE_TEST (.ENTITY_TYPE,
.FORMAT,
.LENGTH,
.ENTITY_POINTER);
end;
[inrange,outrange]:
$INTERNAL_ERROR$ ('Invalid entity keyword for LOOP');
tes)
else return .TEMP;
! Force NM_PARMS to interpret all parameters as NODE
! entity parameters.
NM_PARMS (ENTITY_NODE, 0) ! Process any node parameters supplied
end; ! End of NCP$LOOP
%routine ('NCP$PURGE') =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
literal
PERMANENT_ = 1, ! Change permanent parameters
CLEAR_PURGE = 1; ! Perform CLEAR_PURGE
NICE_INITIALIZE (PURGE_); ! Initialize NICE message
if NCP_CHANGE (PERMANENT_,CLEAR_PURGE)
then $TRUE
else $INTERNAL_ERROR$ ('Invalid syntax in PURGE command')
end; ! End of NCP$PURGE
%routine ('NCP$SET') =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
literal
VOLATILE_ = 0, ! Change volatile parameters
SET_DEFINE = 0; ! Perform SET/DEFINE
NICE_INITIALIZE (SET_); ! Initialize NICE message
if NCP_CHANGE (VOLATILE_,SET_DEFINE)
then $TRUE
else $INTERNAL_ERROR$ ('Invalid syntax in SET command')
end; ! End of NCP$SET
%routine ('NCP$SHOW') =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
literal
VOLATILE_ = 0; ! Read volatile parameters
NICE_INITIALIZE (SHOW_); ! Initialize NICE message
if NCP_READ (VOLATILE_)
then $TRUE
else $INTERNAL_ERROR$ ('Invalid syntax in SHOW command')
end; ! End of NCP$SHOW
%routine ('NCP$TELL') =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! Current position within the PB portion of the MS block.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
local
REQ_DATA: ref XCTR_BLOCK, ! Address of Request data
FORMAT,
LENGTH,
NOD_PTR,
USR_LEN,
ACT_LEN,
PWD_LEN,
TEMP; ! Local work variable
REQ_DATA = .REQ[RB_DATA]; ! Get address of source data block
NOD_PTR = ch$ptr(REQ_DATA[NOD_ID],,8); ! Initialize pointer to node id
if P_NODE (TEMP) ! Node name
then begin
FORMAT = 0; ! Store node address of zero
PUTW (FORMAT, NOD_PTR);
FORMAT = ! Length & format are
LENGTH = CH$MIN(ch$ptr(TEMP,,6), 6); ! less than six
PUTB (.FORMAT, NOD_PTR); ! Write node entity format
CVSTA (.FORMAT, ! Convert node id to string
.LENGTH,
.TEMP,
.NOD_PTR);
end
else if P_NUM (TEMP)
then begin ! Node address
local TMP,LEN;
FORMAT = 0; ! Node address format
LENGTH = 2; ! 2 byte node address
P_NARG (TMP,LEN); ! Peek at next
if .TMP eql $CMTOK
then begin ! Possibly x.y node address format
P_TOK (TMP);
TMP = ch$ptr(.TMP+1); ! Get pointer to token
LEN = ch$len(.TMP); ! Get length
if ch$eql(.LEN,.TMP,1,ch$asciz('.'))
then begin ! It is a .
P_TOK (TMP); ! Eat up the .
if not P_NUM (TMP) then ! Get the rest of the node address
$INTERNAL_ERROR$ ('Invalidly formatted message block');
if (.temp lss 0 or .temp gtr 63) or (.tmp lss 0 or .tmp gtr 1023) then ! Node value in range?
$INTERNAL_ERROR$ ('Invalid node or area number specified');
TEMP = .TEMP * 1024 + .TMP; ! Compute the whole node address
end
else begin
if (.temp lss 0 or .temp gtr 1023) then
$INTERNAL_ERROR$ ('Invalid node number specified');
P_PREV (TMP); ! Not a ., backup parsing pointer
end
end;
if .TEMP eql 0 ! Valid node address?
then $INTERNAL_ERROR$ ('Zero is an invalid node number');
CVSTA (.FORMAT, ! Convert node id to string
.LENGTH,
.TEMP,
.NOD_PTR);
NOD_PTR = ch$plus(.NOD_PTR,2);
PUTB (.FORMAT,NOD_PTR); ! Null node name string
end
else $INTERNAL_ERROR$ ('node name not present in TELL syntax');
REQ[RB_EXECUTOR] = REQ_DATA[NOD_ID]; ! Store address of EXECUTOR node id
!
! Get access control fields, returning next keyword code
!
TEMP = ACCESS_CONTROL (ch$ptr(REQ_DATA[USR_ID],1),USR_LEN,
ch$ptr(REQ_DATA[ACTSTR],1),ACT_LEN,
ch$ptr(REQ_DATA[PWDSTR],1),PWD_LEN);
ch$wchar(.USR_LEN,ch$ptr(REQ_DATA[USR_ID])); ! Write length byte
ch$wchar(.ACT_LEN,ch$ptr(REQ_DATA[ACTSTR])); ! Write length byte
ch$wchar(.PWD_LEN,ch$ptr(REQ_DATA[PWDSTR])); ! Write length byte
!
! Update Request Block to point to access control fields
!
REQ[RB_USER_LENGTH] = .USR_LEN;
if .USR_LEN gtr 0
then REQ[RB_USER] = ch$ptr (REQ_DATA[USR_ID],1);
REQ[RB_ACCOUNT_LENGTH] = .ACT_LEN;
if .ACT_LEN gtr 0
then REQ[RB_ACCOUNT] = ch$ptr (REQ_DATA[ACTSTR],1);
REQ[RB_PASSWORD_LENGTH] = .PWD_LEN;
if .PWD_LEN gtr 0
then REQ[RB_PASSWORD] = ch$ptr (REQ_DATA[PWDSTR],1);
!
! Dispatch to perform command
!
NCP$DISPATCH_COMMAND (.TEMP)
end; ! End of NCP$TELL
%routine ('NCP$TRIGGER') =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
NICE_INITIALIZE (TRIGGER_); ! Initialize NICE message
NCP_BOOT () ! Do the common boot processing
end; ! End of NCP$TRIGGER
%routine ('NCP$ZERO') =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
literal
ZERO_ONLY = 0,
READ_AND_ZERO = 1;
local
TEMP,
ENTITY_TYPE : FULL_ENTITY,
FORMAT,
LENGTH,
ENTITY_POINTER,
OPTION_BYTE: block [1] field (ZERO_OPTIONS);
NICE_INITIALIZE (ZERO_); ! Initialize NICE message
if (TEMP = NM_ENTITY (ENTITY_TYPE, ! Get entity field from command
FORMAT,
LENGTH,
ENTITY_POINTER))
then begin
OPTION_BYTE[ZO_ENTITY_TYPE] = .ENTITY_TYPE;
OPTION_BYTE[ZO_READ_AND_ZERO] = ZERO_ONLY;
NICE_OPTION (.OPTION_BYTE); ! Write option byte
if .ENTITY_TYPE[ENTITY_MAIN] eql ENTITY_NODE ! Special case for NODE id
then begin
local NODE_STRING: CH$SEQUENCE(6,8); ! Storage for node name
CVSTA (.FORMAT, ! Convert node id to string
.LENGTH,
.ENTITY_POINTER,
ch$ptr(NODE_STRING,,8));
NICE_ENTITY (.FORMAT, ! Write entity id field
.LENGTH,
ch$ptr(NODE_STRING,,8));
end
else NICE_ENTITY (.FORMAT, ! Write entity field
.LENGTH,
.ENTITY_POINTER);
end
else return .TEMP;
if .ENTITY_TYPE[ENTITY_MAIN] eql ENTITY_MODULE
then NM_PARMS (.ENTITY_TYPE, 0) ! Only MODULE has parameters
else begin
NCP$QUEUE_REQUEST (0);
return .TEMP
end
end; ! End of NCP$ZERO
%routine ('NCP$REQUEST_INITIALIZE', OPERATOR_ID, CMD_PTR) : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
! Performs initialization processing for a NICE request. Allocates
! storage required for performing the request and initializes
! various fields within the request block.
!
! FORMAL PARAMETERS
!
! OPERATOR_ID - A value which distinguishes the operator from whence this
! request has come.
!
! CMD_PTR - A character sequence pointer to the command text string.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
local
REQ_DATA: ref XCTR_BLOCK, ! Address of Request data
LENGTH, ! Length of command text
TEMP;
REQ = NMU$MEMORY_GET (REQUEST_BLOCK_ALLOCATION); ! Allocate Request Block
REQ[RB_NICE] = NMU$MEMORY_GET (NICE_BUFFER_ALLOCATION);
REQ[RB_NICE_ALLOCATION] = NICE_BUFFER_ALLOCATION ; ! Units allocated
REQ[RB_NICE_LENGTH] = 0; ! Initially no NICE message
REQ[RB_NICE_POINTER] = ch$ptr (.REQ[RB_NICE], ! Point to NICE message
0, ! No offset
8); ! DECnet byte size
REQ[RB_EXECUTOR] = 0; ! Initialize to process locally
REQ[RB_PRV_SYSTEM] = $true; ! Set privledges.
REQ[RB_PRV_SERVICE] = $true;
REQ[RB_PRV_TEST] = $true;
REQ[RB_PRV_CHANGE] = $true;
REQ[RB_PRV_READ] = $true;
!
! Allocate block for additional data used by NCP
!
REQ_DATA = NMU$MEMORY_GET (EXECUTOR_BLOCK_ALLOCATION);
REQ[RB_DATA] = .REQ_DATA; ! Save address of data block
REQ[RB_DATA_ALLOCATION] = EXECUTOR_BLOCK_ALLOCATION; ! Units allocated
REQ_DATA[OPR_ID] = .OPERATOR_ID; ! Set Operator Id
%( N.B. - This code will save the command typein string from the IPCF message
for use during response processing. It is turned off now because the
NML request handler code does not return this info in the RB on the
call to NML$REQUEST_SHOW. Also needs a variable to hold size of
command buffer.
LENGTH = CH$LEN (.CMD_PTR); ! Get length of command string
TEMP = ch$allocation (.LENGTH + 1); ! Size of block in words
REQ_DATA[CMD_ADR] = NMU$MEMORY_GET (.TEMP); ! Use this temporarily
ch$move (.LENGTH,.CMD_PTR,ch$ptr(.REQ_DATA[CMD_ADR])); ! Copy string
)%
REQ[RB_COMPLETION] = NCP$DEQUEUE_RESPONSE; ! Completion routine
end; ! End of NCP$REQUEST_INITIALIZE
%routine ('NCP$QUEUE_REQUEST', TO_FIL) : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
! Places a request on the NICE request queue for processing.
!
! FORMAL PARAMETERS
!
! TO_FIL - File handle of file in which output may be directed
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
literal
TEXT_BUFFER_LENGTH = 80, ! Length of text buffer in characters
TEXT_BUFFER_SIZE = ! Size in fullwords
ch$allocation (TEXT_BUFFER_LENGTH),
TEXT_BUFFER_ALLOCATION = ! Size of allocation in units
TEXT_BUFFER_SIZE * %upval,
TXT_BFR_SZ = 80; ! A screenful
local
TXT_BFR; ! Text buffer address for response
local
REQ_DATA: ref XCTR_BLOCK, ! Address of Request data
REQ_NO, ! NML Request number
NICE_ADDR, ! Address of NICE request buffer
NICE_LENGTH, ! Length of NICE request in bytes
TEMP;
REQ_DATA = .REQ[RB_DATA]; ! Get address of source data block
REQ_DATA[TO_FILE] = .TO_FIL; ! Output goes to file named
%( Determine if there is a TELL_BLOCK created for this command.
If so, use executor node from it. If it also contains access
control info use it, otherwise look for an XCTR_BLOCK on the
queue for this OPR ID and this node, if it contains access control
info use that. If access control info is not available in either
TELL_BLOCK or XCTR_BLOCK then use null.
If there is no TELL_BLOCK for this command, search for
the first XCTR_BLOCK for this OPR ID and use all info from it. )%
if .REQ[RB_EXECUTOR] eql 0 ! Check if TELL prefix used
then begin ! If not then look for SET EXECUTOR
local
SPTR,
DPTR,
LENGTH,
XCTR: ref block[XCTR_SZ] field(XCTR_FIELDS);
if (XCTR = NMU$QUEUE_SCAN (XCTR_NOD_Q,
.REQ_DATA[OPR_ID],
SCAN_XCTR_Q)) neq 0
then begin ! An EXECUTOR has been set
SPTR = ch$ptr (XCTR[NOD_ID],,8); ! Point to EXECUTOR node id
DPTR = ch$ptr (REQ_DATA[NOD_ID],,8);
ch$wchar_a (ch$rchar_a(SPTR),DPTR); ! Copy node address
ch$wchar_a (ch$rchar_a(SPTR),DPTR);
ch$wchar_a ((LENGTH = ch$rchar_a(SPTR)) ! Write length byte
,DPTR);
ch$move (.LENGTH,.SPTR,.DPTR); ! Move id string
REQ[RB_EXECUTOR] = REQ_DATA[NOD_ID]; ! Address of executor id
SPTR = ch$ptr (XCTR[USR_ID]); ! Point to user id
DPTR = ch$ptr (REQ_DATA[USR_ID]);
ch$wchar_a ((LENGTH = ch$rchar_a(SPTR)) ! Write length byte
,DPTR);
ch$move (.LENGTH,.SPTR,.DPTR); ! Move id string
REQ[RB_USER_LENGTH] = .LENGTH;
if .LENGTH gtr 0
then REQ[RB_USER] = .DPTR; ! Make request use USER id
SPTR = ch$ptr (XCTR[ACTSTR]); ! Point to account string
DPTR = ch$ptr (REQ_DATA[ACTSTR]);
ch$wchar_a ((LENGTH = ch$rchar_a(SPTR)) ! Write length byte
,DPTR);
ch$move (.LENGTH,.SPTR,.DPTR); ! Move id string
REQ[RB_ACCOUNT_LENGTH] = .LENGTH;
if .LENGTH gtr 0
then REQ[RB_ACCOUNT] = .DPTR; ! Make request use ACCOUNT
SPTR = ch$ptr (XCTR[PWDSTR]); ! Point to password string
DPTR = ch$ptr (REQ_DATA[PWDSTR]);
ch$wchar_a ((LENGTH = ch$rchar_a(SPTR)) ! Write length byte
,DPTR);
ch$move (.LENGTH,.SPTR,.DPTR); ! Move id string
REQ[RB_PASSWORD_LENGTH] = .LENGTH;
if .LENGTH gtr 0
then REQ[RB_PASSWORD] = .DPTR; ! Make request use PASSWORD
end;
end;
NICE_ADDR =.REQ[RB_NICE]; ! Save address of NICE request buffer
NICE_LENGTH = .REQ[RB_NICE_LENGTH]; ! And message length
REQ_NO = NML$REQUEST_ENTER (.REQ); ! Enter request in queue
TXT_BFR = NMU$MEMORY_GET (TXT_BFR_SZ); ! Get text buffer
!
! Return a response message now indicating we've accepted the command
! for any command which may take a significant amount of time to perform.
!
if (.REQ[RB_EXECUTOR] neq 0) ! Was an executor set?
or ((TEMP = ch$rchar (ch$ptr(.NICE_ADDR,,8))) eql LOAD_) ! Or LOAD command
or (.TEMP eql DUMP_) ! Or DUMP command
or (.TEMP eql LOOP_) ! Or LOOP command
then begin ! Yes, then print accepted message
TEXT_PTR = ch$ptr(.TXT_BFR); ! Set up pointer to text
$NMU$TEXT (TEXT_PTR, ! Build an acceptance message
TXT_BFR_SZ,
$NML$TEXT ('Request # %D Accepted'),
.REQ_NO);
NCP$SEND_RESPONSE (0,ch$ptr(.TXT_BFR), ! Send it back to operator
.REQ_DATA[OPR_ID], 0);
end;
%debug (NCP_NICE_VALIDATION, ! Print the content of the NICE
(begin ! message buffer as an ASCII text
builtin LSH;
local PAGE, PTR, TMP;
PAGE = NMU$PAGE_GET ();
PTR = TMP = ch$ptr (LSH (.PAGE,9));
$NMU$TEXT (TMP, TEXT_BUFFER_LENGTH,
'%/[NICE Request Message]%/%N');
PUTBUF (TMP, 0, .NICE_ADDR, .NICE_LENGTH);
NCP$SEND_RESPONSE (0, .PTR, .REQ_DATA[OPR_ID], 0);
NMU$PAGE_RELEASE (.PAGE);
end));
NMU$MEMORY_RELEASE (.TXT_BFR,TXT_BFR_SZ); ! Release buffer
end; ! End of NCP$QUEUE_REQUEST
%routine ('NM_ENTITY', ENTITY_TYPE, FORMAT, LENGTH, ENTITY_POINTER) =
!++
! FUNCTIONAL DESCRIPTION:
!
! The entity portion of an NCP command parsed by OPR is
! converted into the primitive fields required to build
! a NICE message.
!
! FORMAL PARAMETERS
!
! ENTITY_TYPE - The address of a variable which is to receive
! the full entity type representing the entity.
!
! FORMAT - The address of a variable which will contain
! the entity format/length field.
!
! LENGTH - The address of a variable which will contain the
! length of the entity id string. This length
! represents the length of the complete entity id
! field and will not necessarily be the same as
! the length encoded in the format field of
! the NICE message. If zero the contents of
! ENTITY_POINTER should be ignored.
!
! ENTITY_POINTER - The address of a variable which will contain
! a character sequence pointer to the entity id
! string,
! or, in the case of ENTITY_AREA, or ENTITY_NODE
! the address of a variable which will contain
! the entity id value. (a number or 6 SIXBIT chars)
!
! IMPLICIT INPUTS
!
! Current position within the PB portion of the MS block.
!
! ROUTINE VALUE: True or False.
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
map
ENTITY_TYPE : ref FULL_ENTITY;
local
T_ADDR, ! Address temporary variable
T_LTH, ! Length temporary variable
TEMP; ! Local work variable
!
! Find out what entity keyword was parsed
!
if not P_NARG (TEMP)
then $INTERNAL_ERROR$ ('Message block terminated prematurely')
else if .TEMP nequ $CMKEY
then $INTERNAL_ERROR$ ('Invalidly formatted message block')
else P_KEYW (TEMP); ! Get entity keyword value
!
! Interpretation of entity id field is dependent on entity keyword
!
selectone .TEMP of
set
!************
!* EXECUTOR *
!************
[$KNXTR]: ! EXECUTOR
begin
.ENTITY_TYPE = ENTITY_NODE; ! Return node entity value
.FORMAT = 0; ! Indicate node address format
.LENGTH = 2; ! 2 byte node address
.ENTITY_POINTER = 0; ! Zero is EXECUTOR
return $TRUE
end;
!***********
!* CIRCUIT *
!* or *
!* VIA *
!***********
[$KNCKT, ! CIRCUIT
$KNVIA]: ! VIA ... a pseudonym
begin
if not P_FLD (T_ADDR,T_LTH)
then $INTERNAL_ERROR$ ('Invalidly formatted message block');
.ENTITY_TYPE = ENTITY_CIRCUIT; ! Return circuit entity value
.FORMAT = .LENGTH = CH$LEN (ch$ptr(.T_ADDR+1));
.ENTITY_POINTER = ch$ptr(.T_ADDR+1);
CVLTU (..ENTITY_POINTER, ..LENGTH); ! Upper case circuit id
return $TRUE
end;
!****************************************************
!* SELECTORS - KNOWN, ACTIVE, ADJACENT, SIGNIFICANT *
!****************************************************
[$KNKNW, ! KNOWN
$KNATV, ! ACTIVE
$KNADJ, ! ADJACENT
$KNSIG ! SIGNIFICANT
]:
begin
selectone .TEMP of
set
[$KNKNW]:
.FORMAT = KNOWN_; ! Class format
[$KNATV]:
.FORMAT = ACTIVE_; ! Class format
[$KNADJ]:
.FORMAT = ADJACENT_; ! Class format
[$KNSIG]:
.FORMAT = SIGNIFICANT_; ! Class format
tes;
if not P_KEYW (TEMP) ! Get entity keyword value
then $INTERNAL_ERROR$ ('Invalidly formatted message block');
.LENGTH = 0; ! Only format byte
.ENTITY_POINTER = 0; ! Null pointer
selectone .TEMP of
set
[$KNCKT]:
.ENTITY_TYPE = ENTITY_CIRCUIT;
[$KNLGG]:
.ENTITY_TYPE = ENTITY_LOGGING;
[$KNLIN]:
.ENTITY_TYPE = ENTITY_LINE;
[$KNNOD]:
.ENTITY_TYPE = ENTITY_NODE;
[$KNMDL]:
.ENTITY_TYPE = ENTITY_MODULE;
[$KNARE]:
.ENTITY_TYPE = ENTITY_AREA;
[otherwise]:
$INTERNAL_ERROR$ ('Invalid entity type keyword');
tes;
return $TRUE
end;
!***********
!* LOGGING *
!***********
[$KNLGG]: ! LOGGING
begin
if not P_KEYW (TEMP)
then $INTERNAL_ERROR$ ('Invalidly formatted message block');
.LENGTH = 0; ! Only format byte
.ENTITY_POINTER = 0; ! Null pointer
.FORMAT = .TEMP; ! Logging id
.ENTITY_TYPE = ENTITY_LOGGING;
return $TRUE
end;
!********
!* NODE *
!********
[$KNNOD]: ! NODE
begin
if P_NODE (TEMP)
then begin ! Node name
.FORMAT = ! Length & format are
.LENGTH = CH$MIN(ch$ptr(TEMP,,6), 6); ! less than six
%( N.B. - This is a special case use of the ENTITY_POINTER parameter due
to the fact that the node name from OPR is in SIXBIT and is
passed back as a value and not a string. The caller will have to
be prepared to handle this. Problem is we have no way to allocate
memory for the string here and can't leave it in a local variable. )%
.ENTITY_POINTER = .TEMP;
end
else if P_NUM (TEMP)
then begin ! Node address
local TMP,LEN;
.FORMAT = 0; ! Node address format
.LENGTH = 2; ! 2 byte node address
P_NARG (TMP,LEN); ! Peek at next
if .TMP eql $CMTOK
then begin ! Possibly x.y node address format
P_TOK (TMP);
TMP = ch$ptr(.TMP+1); ! Get pointer to token
LEN = ch$len(.TMP); ! Get length
if ch$eql(.LEN,.TMP,1,ch$asciz('.'))
then begin ! It is a .
P_TOK (TMP); ! Eat up the .
if not P_NUM (TMP) then ! Get the rest of the node address
$INTERNAL_ERROR$ ('Invalidly formatted message block');
TEMP = .TEMP * 1024 + .TMP; ! Compute the whole node address
end
else
P_PREV (TMP); ! Not a ., backup parsing pointer
end;
if .TEMP eql 0 ! Valid node address?
then $INTERNAL_ERROR$ ('Zero is an invalid node number');
%( N.B. - Special case as above. )%
.ENTITY_POINTER = .TEMP;
end
else $INTERNAL_ERROR$ ('Invalidly formatted message block');
.ENTITY_TYPE = ENTITY_NODE; ! Return node entity value
return $TRUE
end;
!********
!* AREA * $$UNDER DEVELOPMENT$$
!********
[$KNARE]: ! AREA
begin
%( N.B. - This is another special case use of the ENTITY_POINTER parameter due
to the fact that the area name from OPR is a number and is
passed back as a value and not a string. The caller will have to
be prepared to handle this. Problem is we have no way to allocate
memory for the string here and can't leave it in a local variable. )%
if not P_NUM (TEMP)
then $INTERNAL_ERROR$ ('Invalidly formatted message block');
.ENTITY_TYPE = ENTITY_AREA; ! Return area entity value
.FORMAT = 0; ! Area address format.
.LENGTH = 1; ! Area address is one byte.
.ENTITY_POINTER = .TEMP; ! The entity id value.
return $TRUE
end;
!********
!* LINE *
!********
[$KNLIN]: ! LINE
begin
if not P_FLD (T_ADDR)
then $INTERNAL_ERROR$ ('Invalidly formatted message block');
.ENTITY_TYPE = ENTITY_LINE; ! Return line entity value
.FORMAT = .LENGTH = CH$LEN (ch$ptr(.T_ADDR+1));
.ENTITY_POINTER = ch$ptr(.T_ADDR+1);
CVLTU (..ENTITY_POINTER, ..LENGTH); ! Upper case line id
return $TRUE
end;
!********
!* LOOP *
!********
[$KNLOP]: ! LOOP class
begin
if not P_KEYW (TEMP)
then $INTERNAL_ERROR$ ('Invalidly formatted message block');
.FORMAT = LOOPED_; ! Class format
.LENGTH = 0; ! Only format byte
.ENTITY_POINTER = 0; ! Null pointer
selectone .TEMP of
set
[$KNNOD]:
.ENTITY_TYPE = ENTITY_NODE; ! Return node entity type value
[otherwise]:
$INTERNAL_ERROR$ ('Invalid LOOP class entity keyword')
tes;
return $TRUE
end;
!**********
!* MODULE *
!**********
[$KNMDL]: ! MODULE
begin
if not P_KEYW (TEMP)
then $INTERNAL_ERROR$ ('Invalidly formatted message block');
case .TEMP from $KNCFG to $KNXSV of
set
[$KNXSV]:
begin
.ENTITY_TYPE = ENTITY_MODULE_X25_SERVER;
.ENTITY_POINTER = CH$ASCIZ ('X25-SERVER');
end;
[$KNXAC]:
begin
.ENTITY_TYPE = ENTITY_MODULE_X25_ACCESS;
.ENTITY_POINTER = CH$ASCIZ ('X25-ACCESS');
end;
[$KNXPR]:
begin
.ENTITY_TYPE = ENTITY_MODULE_X25_PROTOCOL;
.ENTITY_POINTER = CH$ASCIZ ('X25-PROTOCOL');
end;
[$KNCFG]:
begin
.ENTITY_TYPE = ENTITY_MODULE_CONFIGURATOR;
.ENTITY_POINTER = CH$ASCIZ ('CONFIGURATOR');
end;
[$KNCSL]:
begin
.ENTITY_TYPE = ENTITY_MODULE_CONSOLE;
.ENTITY_POINTER = CH$ASCIZ ('CONSOLE');
end;
[$KNLDR]:
begin
.ENTITY_TYPE = ENTITY_MODULE_LOADER;
.ENTITY_POINTER = CH$ASCIZ ('LOADER');
end;
[$KNLPR]:
begin
.ENTITY_TYPE = ENTITY_MODULE_LOOPER;
.ENTITY_POINTER = CH$ASCIZ ('LOOPER');
end;
[inrange,
outrange]:
$INTERNAL_ERROR$ ('Invalid module entity keyword');
tes;
.FORMAT = .LENGTH = CH$LEN (..ENTITY_POINTER);
return $TRUE;
end;
!*********
!* QUEUE *
!*********
[$KNQUE]: ! QUEUE
begin
macro Q_NAME = 'QUEUE' %;
.ENTITY_TYPE = 8; ! Dummy up a system specific entity #
.FORMAT = .LENGTH = %charcount(Q_NAME); ! Make it complete
.ENTITY_POINTER = CH$ASCII (Q_NAME);
return $TRUE
end;
!***********
!* INVALID *
!* ENTITY *
!***********
[otherwise]: ! Error case
$INTERNAL_ERROR$ ('Invalid entity type keyword');
tes
end; ! End of NM_ENTITY
%routine ('NM_EVENT', NUMBER, BUFFER) =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! Current position within the PB portion of the MS block.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
local
TMP,
NUM1,
NUM2;
bind
E_CLASS = (.NUMBER+0),
E_MASK1 = (.NUMBER+1),
E_MASK2 = (.NUMBER+2),
E_ETYPE = (.NUMBER+3),
E_ELEN = (.NUMBER+4),
E_ENAME = (.NUMBER+5);
P_NARG (TMP);
! If the routine is called to process KNOWN EVENTS, then the following
! section of code will not be executed. Following the KNOWN EVENTS keywords,
! there will be neither a token "*" nor a number, but an entity keyword.
! Otherwise, this section is entered with the assumption that the event
! class was parsed and put in the first element of the data vector. The
! parsing pointer now should point to the first event type in the list.
if .TMP eql $CMTOK ! Next field is a token
then begin
P_TOK (TMP); ! Parse "*"
E_CLASS = .E_CLASS or (2^14); ! Set flag bit to indicate all events
P_NARG (TMP); ! Peek at next field
end
else begin ! Otherwise, it should be a number
while (.TMP eql $CMNUM) or (.TMP eql $CMNUX)
do begin
P_NUM (NUM1); ! Parse number
P_NARG (TMP); ! Peek at next field
NUM2 = .NUM1; ! Assume that this is single event type
if .TMP eql $CMTOK ! If next field is a token
then begin ! This is a range
P_TOK (TMP); ! Parse "-"
P_NUM (NUM2); ! Parse ending range
P_NARG (TMP); ! Peek at next field
end;
if .TMP eql $CMCMA ! If it is a comma
then begin
P_COMMA (TMP); ! Parse it
P_NARG (TMP); ! Peek at next field
end;
if .NUM2 lss .NUM1 ! Make sure range is in order
then $INTERNAL_ERROR$ ('Range should be lo-hi');
if .NUM2 gtr 63
then $INTERNAL_ERROR$ ('Upper bound should not exceed 63');
incr I from .NUM1 to .NUM2
do begin
if .I geq 32 ! Set up binary event mask
then E_MASK1<.I-32,1> = 1
else E_MASK2<.I,1> = 1;
end;
end;
end;
! At this point we have to peek at the next field to determine whether
! an entity keyword follows the event list (or the keywords KNOWN EVENTS, if
! the routine is invoked to process KNOWN EVENTS). If there is an entity
! keyword that we expect, then parse it and also parse the entity id field.
! Otherwise, backup parsing pointer, so that NM_PARMS code can parse the
! remaining of the command normally.
if .TMP eql $CMKEY ! Is the next field a keyword
then begin
P_KEYW (TMP); ! Get keyword
selectone .TMP of ! Check if the keyword is a
set
[E$QNOD]: ! NODE entity
begin
E_ETYPE = .TMP; ! Set value for node entity type
if P_NODE (TMP)
then begin
E_ELEN = CH$MIN (ch$ptr(TMP,,6),6);
E_ENAME = ch$ptr(.BUFFER,,8);
CVSTA (.E_ELEN, ! Convert node name to ASCII string
.E_ELEN,
.TMP,
.E_ENAME);
end
else begin
if P_NUM (TMP)
then begin
E_ELEN = 0;
E_ENAME = .TMP;
end;
end;
end;
[E$QCKT, ! LINE entity
E$QLIN]: ! CIRCUIT entity
begin
E_ETYPE = .TMP; ! Set value for line and circuit entity
P_FLD (TMP);
E_ENAME = ch$ptr(.TMP+1);
E_ELEN = CH$LEN (.E_ENAME);
end;
[E$QMDL]: ! MODULE entity
begin
E_ETYPE = .TMP; ! Set value for module entity type
E_ENAME = ch$ptr(.BUFFER,,8);
P_KEYW (TMP); ! Parse module name
case .TMP from $KNCFG to $KNXSV of
set
[$KNXAC]: ! X25-ACCESS
begin
E_ELEN = %charcount('X25-ACCESS');
ch$move (.E_ELEN, CH$ASCII('X25-ACCESS'), .E_ENAME);
end;
[$KNXPR]: ! X25-PROTOCOL
begin
E_ELEN = %charcount('X25-PROTOCOL');
ch$move (.E_ELEN, CH$ASCII('X25-PROTOCOL'), .E_ENAME);
end;
[$KNXSV]: ! X25-SERVER
begin
E_ELEN = %charcount('X25-SERVER');
ch$move (.E_ELEN, CH$ASCII('X25-SERVER'), .E_ENAME);
end;
[$KNCFG]: ! CONFIGURATOR
begin
E_ELEN = %charcount('CONFIGURATOR');
ch$move (.E_ELEN, CH$ASCII('CONFIGURATOR'), .E_ENAME);
end;
[$KNLDR]:
begin
E_ELEN = %charcount('LOADER');
ch$move (.E_ELEN, CH$ASCII('LOADER'), .E_ENAME);
end;
[$KNLPR]:
begin
E_ELEN = %charcount('LOOPER');
ch$move (.E_ELEN, CH$ASCII('LOOPER'), .E_ENAME);
end;
[$KNCSL]:
begin
E_ELEN = %charcount('CONSOLE');
ch$move (.E_ELEN, CH$ASCII('CONSOLE'), .E_ENAME);
end;
[inrange,
outrange]:
E_ETYPE = -1; ! No entity
tes;
end;
[otherwise]: ! If it is not the entity keyword we
begin ! expect, then
E_ETYPE = -1; ! Set value to indicate no entity
P_PREV (TMP); ! Readjust parsing pointer
end;
tes;
end
else E_ETYPE = -1; ! Set value to indicate no entity
return $TRUE;
end; ! End of NM_EVENT
%routine ('NM_NUMBER', NUMBER, BUFFER) =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! Current position within the PB portion of the MS block.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
local
LEN,
TMP;
if P_NARG (TMP) and ((.TMP eql $CMTOK) or (.TMP eql $CMCMA))
then begin
if .TMP eql $CMTOK ! Identify token
then begin
P_TOK (TMP); ! Get token
TMP = ch$ptr(.TMP+1); ! Get pointer to token
LEN = CH$LEN(.TMP); ! Get length
if ch$eql(.LEN,.TMP,1,CH$ASCIZ('-'))
then P_NUM (.NUMBER+1) ! Get numeric range
else begin
if ch$eql(.LEN,.TMP,1,CH$ASCIZ('.'))
then NM_EVENT (.NUMBER, .BUFFER)
else P_PREV (TMP); ! Backup parsing pointer
end;
P_NARG (TMP);
end;
if .TMP eql $CMCMA ! If followed by a comma
then P_COMMA (TMP); ! then parse it
end;
return $TRUE;
end; ! End of NM_NUMBER
%routine ('NM_REMOTE', POINTER, LENGTH, BUFFER) =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! Current position within the PB portion of the MS block.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
local
LEN,
TMP,
TMP1,
TMP2,
FILEN,
FIPTR;
label X;
if P_NARG (TMP) and ((.TMP eql $CMQST) or (.TMP eql $CMTOK))
then begin
FILEN = MIN(..LENGTH,6);
FIPTR = ch$ptr(.BUFFER,,8);
TMP1 = ch$move (.FILEN,..POINTER,.FIPTR);
if .TMP eql $CMQST ! Field is followed by an optional
then begin ! quoted accounting field
P_QSTR (TMP); ! Parse the optional data field
TMP2 = ch$ptr(.TMP+1); ! Get pointer
LEN = CH$LEN(.TMP2); ! Get length
ch$wchar_a (%C'"',TMP1); ! Recreate quoted accounting string
TMP1 = ch$move (.LEN,.TMP2,.TMP1);
ch$wchar_a (%C'"',TMP1);
P_NARG (TMP); ! Check next argument
if .TMP neq $CMTOK ! If it is not a token, then error
then $INTERNAL_ERROR$ ('Illegal remote file name');
FILEN = .FILEN + .LEN + 2; ! New node name length
end;
if .TMP eql $CMTOK ! Field is followed by a token
then begin
P_TOK (TMP); ! Parse the token
TMP2 = ch$ptr(.TMP+1); ! Get pointer
LEN = CH$LEN(.TMP2); ! Get length
if not ch$eql(.LEN,.TMP2,2,CH$ASCIZ('::'))
then $INTERNAL_ERROR$ ('Illegal remote file name')
else begin ! If it is "::", then everything is OK
TMP1 = ch$move (2,.TMP2,.TMP1); ! Append colons
FILEN = .FILEN + 2; ! New node name length
end;
if P_NARG (TMP)
then
X: begin
case .TMP from $CMOFI to $CMFLD of
set
[$CMOFI]: P_OFIL (TMP);
[$CMFIL]: P_FILE (TMP);
[$CMFLD]: P_FLD (TMP);
[OUTRANGE]: leave X;
tes;
TMP2 = ch$ptr(.TMP+1);
LEN = CH$MIN(.TMP2,(80-.FILEN));
ch$move (.LEN,.TMP2,.TMP1); ! Append file
FILEN = .FILEN + .LEN;
CVLTU (.FIPTR, .FILEN); ! Convert file name to upper case
end;
end;
.POINTER = .FIPTR; ! Update new file name pointer
.LENGTH = .FILEN; ! Update new file name length
end;
return $TRUE;
end; ! End of NM_REMOTE
%routine ('NM_PARMS', ENTITY_TYPE, CLEAR_PURGE) =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! Current position within the PB portion of the MS block.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
literal
MAX_TEMP = 6;
map
ENTITY_TYPE : FULL_ENTITY;
local
PARM_NO, ! Parameter number
PARM_TYPE, ! Parsed parameter type
EBUF: CH$SEQUENCE (25,8),
TEMP: vector[MAX_TEMP];
! Process any parameters supplied
while not P_CFM (PARM_TYPE) ! Get type of next parsed item
do begin ! As long as not at end of command
incr I from 0 to (MAX_TEMP-1)
do TEMP[.I] = 0; ! Reset data vector
case .PARM_TYPE from $CMKEY to $CMNOD of
set
[$CMKEY]: ! %O'00' Keyword
begin
local VALKEY;
! Special case for keywords - Could be either second part of
! parameter keyword or value
PARM_NO = 0; ! Initialize parameter number
VALKEY = $FALSE; ! Reset recording flag
while (P_KEYW (PARM_TYPE)) ! Get the keyword code
do begin
if (.PARM_TYPE<16,1> and ! Known qualifier keyword ?
(.PARM_TYPE neq P$ALL))! but not ALL
then begin ! Yes,
VALKEY = $TRUE; ! Record this parameter now
selectone .PARM_NO of
set ! Process KNOWN qualifiers
[E$PKNW]: ! Special case for KNOWN EVENTS
begin
TEMP = 3^14; ! Indicate known events
NM_EVENT (TEMP, EBUF); ! Parse event list
exitloop;
end;
[otherwise]: ! Other KNOWN qualifiers
begin ! Adjust qualifier parameter number
PARM_TYPE<16,1> = 0; ! Clear known keyword bit
PARM_NO = .PARM_NO + .PARM_TYPE;
TEMP = KNOWN_; ! Set KNOWN indicator
end;
tes;
end
else begin
if .PARM_TYPE<17,1> ! Value keyword ?
then begin ! Yes,
VALKEY = $TRUE; ! Record this parameter now
! If function is CLEAR/PURGE, then this is
! actually a parameter keyword, not a value
! keyword. Clear value keyword and use it
! to update parameter number
if not .CLEAR_PURGE
then TEMP = .PARM_TYPE
else begin
PARM_TYPE<17,1> = 0;
PARM_NO = .PARM_NO + .PARM_TYPE;
TEMP = 0;
end;
exitloop;
end
else begin ! Add parameter values
PARM_NO = .PARM_NO + .PARM_TYPE;
if .PARM_TYPE eql P$ALL
then begin
VALKEY = $TRUE;
exitloop;
end;
end;
end;
end;
if .VALKEY
then NICE_PARM (%O'0', ! Assemble value keyword parameters
TEMP,
.CLEAR_PURGE,
.PARM_NO,
.ENTITY_TYPE);
end;
[$CMNUM, ! %O'01' Number parsed by $NUMBER
$CMNUX]: ! %O'24' Number parsed by $DIGIT
begin
local TMP, LEN;
P_NUM (TEMP); ! Get the first numeric value
NM_NUMBER (TEMP, EBUF); ! Parse possible range or list
NICE_PARM (%O'0',
TEMP,
.CLEAR_PURGE,
.PARM_NO,
.ENTITY_TYPE);
end;
[$CMIFI, ! %O'04' Input file specification
$CMOFI, ! %O'05' Output file specification
$CMFIL]: ! %O'06' File specification
begin
local FDB;
case .PARM_TYPE from $CMIFI to $CMFIL of
set ! Get file specification address
[$CMIFI]: P_IFIL (FDB);
[$CMOFI]: P_OFIL (FDB);
[$CMFIL]: P_FILE (FDB);
tes;
! The value returned is the address of a GALAXY formatted file
! descriptor block. The first word contains the number of words
! in the block in the left half.
TEMP = ch$ptr (.FDB+1);
NICE_PARM (CH$LEN(.TEMP), ! Length of ASCIZ string
TEMP,
.CLEAR_PURGE,
.PARM_NO,
.ENTITY_TYPE);
end;
[$CMFLD]: ! %O'07' Field
begin
local TMP, LENGTH,
FILE: CH$SEQUENCE (80,8);
P_FLD (TEMP); ! Get address of string
TEMP = ch$ptr (.TEMP+1); ! Make pointer to it
LENGTH = CH$LEN (.TEMP); ! Length of field
NM_REMOTE (TEMP, LENGTH, FILE);
NICE_PARM (.LENGTH, ! Write NICE message
TEMP,
.CLEAR_PURGE,
.PARM_NO,
.ENTITY_TYPE);
end;
[$CMDEV]: ! %O'16' Device
begin
P_DEV (TEMP); ! Get address of string
TEMP = ch$ptr(.TEMP+1); ! Make pointer to it
NICE_PARM (CH$LEN(.TEMP), ! Length of ASCIZ string
TEMP,
.CLEAR_PURGE,
.PARM_NO,
.ENTITY_TYPE);
end;
[$CMQST]: ! %O'21' Quoted string
begin
P_QSTR (TEMP); ! Get address of string
TEMP = ch$ptr(.TEMP+1); ! Make pointer to it
NICE_PARM (CH$LEN(.TEMP), ! Length of ASCIZ string
TEMP,
.CLEAR_PURGE,
.PARM_NO,
.ENTITY_TYPE);
end;
[$CMNOD]: ! %O'26' Node name
begin
literal FILE_NAME_LENGTH = 80; ! Length of node name storage
local LENGTH, TMP,
NODE: CH$SEQUENCE (FILE_NAME_LENGTH,8);
P_NODE (TEMP); ! Get node name
LENGTH = CH$MIN (ch$ptr (TEMP,,6), 6); ! Maximum length
CVSTA (.LENGTH, ! Convert node name to ASCII
.LENGTH,
.TEMP,
ch$ptr (NODE,,8));
if P_NARG (TMP)
then begin
selectone .TMP of
set ! Remote file name: if followed by
[$CMFIL, ! a file name, then it is a TOPS-20
$CMFLD]: ! a field, then it is a foreign
begin
local LEN, FP, NP;
if .TMP eql $CMFLD ! Get file name
then P_FLD (TMP)
else P_FILE (TMP);
FP = ch$ptr (.TMP+1);
NP = ch$ptr (NODE,.LENGTH,8); ! Pointer to node name
LEN = CH$MIN (.FP,FILE_NAME_LENGTH-(.LENGTH+2));
NP = ch$move (2, ! Append colons to node
CH$ASCIZ('::'),
.NP);
ch$move (.LEN,.FP,.NP); ! Append file name to node
LENGTH = .LENGTH + .LEN + 2; ! File name length
end;
[otherwise]: ! Otherwise, it is just another node
tes;
end;
TEMP = ch$ptr (NODE,,8);
NICE_PARM (.LENGTH, ! Write NICE node name parameter
TEMP,
.CLEAR_PURGE,
.PARM_NO,
.ENTITY_TYPE);
end;
[inrange,
outrange]:
$INTERNAL_ERROR$ ('Unexpected COMND jsys function code');
tes;
end;
NCP$QUEUE_REQUEST (0); ! Queue the NICE request message
return $TRUE;
end; ! End of NM_PARMS
%routine ('NCP_READ', TYPE) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Performs common semantic processing for NCP SHOW and LIST command.
!
! FORMAL PARAMETERS
!
! TYPE - Type of parameters to be read; PERMANENT or VOLATILE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
local
TEMP,
PARAMETER,
OPTION_BYTE,
ENTITY_TYPE : FULL_ENTITY,
FORMAT,
LENGTH,
ENTITY_POINTER;
TEMP = NM_ENTITY (ENTITY_TYPE, ! Get entity field from command
FORMAT,
LENGTH,
ENTITY_POINTER);
if .TEMP
then begin
if .ENTITY_TYPE eql 8 ! Is it QUEUE entity ?
then SHOW_QUEUE () ! Process a SHOW QUEUE
else begin
if (TEMP = READ_OPTION (.TYPE, .ENTITY_TYPE, OPTION_BYTE))
then begin
NICE_OPTION (.OPTION_BYTE); ! Write option byte
! Build NICE read information message
selectone .ENTITY_TYPE[ENTITY_MAIN] of
set
[ENTITY_NODE]:
begin ! Special case for NODE id
local NODE_STRING: ch$sequence (6,8);
CVSTA (.FORMAT, ! Convert node id to string
.LENGTH,
.ENTITY_POINTER,
ch$ptr (NODE_STRING,,8));
NICE_ENTITY (.FORMAT, ! Write entity id field
.LENGTH,
ch$ptr (NODE_STRING,,8));
end;
[ENTITY_AREA]:
begin
local AREA_STRING: ch$sequence (2);
ch$wchar (.ENTITY_POINTER, ch$ptr (AREA_STRING,,8)); ! Put the area id into a string
NICE_ENTITY (.FORMAT, ! Write the entity id field
.LENGTH,
ch$ptr (AREA_STRING,,8));
end;
[otherwise]:
NICE_ENTITY (.FORMAT, ! Write entity id field
.LENGTH,
.ENTITY_POINTER);
tes;
if not P_CFM (PARAMETER) ! Parse remaining parameters
then NM_PARMS (.ENTITY_TYPE, 0)
else begin
DEFAULT_QUALIFIER (.ENTITY_TYPE, ! Set up default
.ENTITY_POINTER, ! qualifiers
.LENGTH);
NCP$QUEUE_REQUEST (0); ! Queue NICE request message
end;
end;
end;
end;
return .TEMP;
end; ! End of NCP_READ
%routine ('DEFAULT_QUALIFIER', ENTITY, POINTER, LENGTH) : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! ENTITY Entity type code
! POINTER Pointer to entity id string
! LENGTH Length of the entity id string
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
local
PARAMETER;
selectone .ENTITY of
set
[ENTITY_LOGGING]: ! LOGGING entity
begin
PARAMETER = 200; ! SINK NODE
PUTW (PARAMETER, REQ[RB_NICE_POINTER]);
incr I from 1 to 3 ! Make it EXECUTOR node
do ch$wchar_a (0, REQ[RB_NICE_POINTER]);
REQ[RB_NICE_LENGTH] = .REQ[RB_NICE_LENGTH] + 5;
end;
[otherwise]: ! No default qualifiers for others
0;
tes;
return;
end; ! End of DEFAULT_QUALIFIER
%routine ('SHOW_QUEUE') : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
literal
TEXT_BUFFER_LENGTH = 24*80, ! Length of text buffer in characters
TEXT_BUFFER_SIZE = ! Size in fullwords
ch$allocation (TEXT_BUFFER_LENGTH),
TEXT_BUFFER_ALLOCATION = ! Size of allocation in units
TEXT_BUFFER_SIZE * %upval,
TXT_BFR_SZ = 24*80; ! A screenful
local
TXT_BFR, ! Text buffer address for response
HDR, ! Flags whether first response header
REQ_BLOCK_ADDR, ! Address of NML request block
REQ_DATA, ! Address of Request data
REQ_NO; ! NML Request number
map
REQ_BLOCK_ADDR: ref REQUEST_BLOCK; ! Make fields addressable
map
REQ_DATA: ref XCTR_BLOCK; ! Make fields available
TXT_BFR = NMU$MEMORY_GET (TXT_BFR_SZ); ! Get text buffer
REQ_NO = 0; ! Initialize to start of queues
HDR = 0; ! Initially no header sent
if NML$REQUEST_SHOW (REQ_NO,REQ_BLOCK_ADDR)
then begin
do begin
TEXT_PTR = ch$ptr(.TXT_BFR); ! Set up pointer to text
REQ_DATA = .REQ_BLOCK_ADDR[RB_DATA]; ! Special data
if .REQ_BLOCK_ADDR[RB_STATE] eql RB$WAITING
then $NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
$NML$TEXT ('Request # %D Queued%N'),
.REQ_BLOCK_ADDR[RB_NUMBER])
else if .REQ_BLOCK_ADDR[RB_STATE] eql RB$ACTIVE
or .REQ_BLOCK_ADDR[RB_STATE] eql RB$MORE
then $NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
$NML$TEXT ('Request # %D Active%N'),
.REQ_BLOCK_ADDR[RB_NUMBER])
else if .REQ_BLOCK_ADDR[RB_STATE] eql RB$DONE
then $NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
$NML$TEXT ('Request # %D Complete%N'),
.REQ_BLOCK_ADDR[RB_NUMBER])
%( N.B - The following situation should be changed
to an internal error after testing is
completed. )%
else $NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
$NML$TEXT ('Request # %D Unknown State%N'),
.REQ_BLOCK_ADDR[RB_NUMBER]);
if .REQ_BLOCK_ADDR[RB_TYPE] eql RT$LOCAL
then $NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
$NML$TEXT (', Local%N'))
else if .REQ_BLOCK_ADDR[RB_TYPE] eql RT$REMOTE
then $NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
$NML$TEXT (', Remote%N'))
%( N.B - The following situation should be changed
to an internal error after testing is
completed. )%
else $NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
$NML$TEXT (', Unknown Type%N'));
if .REQ_BLOCK_ADDR[RB_EXECUTOR] neq 0
then begin
local
LEN,
ADR,
PTR,
PAT;
PTR = ch$ptr(.REQ_BLOCK_ADDR[RB_EXECUTOR],,8);
ADR = GETW (PTR); ! Get node address
if .ADR neq 0
then begin ! Node address
local
AREA,
NODE;
if (AREA = .ADR<10,6>) eql 0
then begin
local TEMP;
TEMP = NMU$NETWORK_LOCAL();
TEMP = GETW (TEMP);
AREA = .TEMP<10,6>;
end;
NODE = .ADR<0,10>;
LEN = GETB (PTR); ! Get I-length
if .LEN eql 0
then begin
PAT = CH$ASCIZ(
$NML$TEXT (', Executor = %D.%D %N'));
$NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
.PAT,
.AREA,
.NODE);
end
else begin
PAT = CH$ASCIZ(
$NML$TEXT (', Executor = %D.%D (%#A) %N'));
$NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
.PAT,
.AREA,
.NODE,
.LEN,
.PTR);
end;
end
else begin ! Node name
PAT = CH$ASCIZ($NML$TEXT (', Executor = (%#A) %N'));
LEN = GETB (PTR); ! Get I-length
$NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
.PAT,
.LEN,
.PTR);
end;
end;
if .REQ_BLOCK_ADDR[RB_SOURCE] neq 0
then begin
local
LEN,
PTR,
PAT;
PTR = ch$ptr(.REQ_BLOCK_ADDR[RB_SOURCE],,8);
if (LEN = GETB (PTR)) eql 0
then begin ! Node address
PAT = CH$ASCIZ($NML$TEXT (', Source = %D %N'));
! removed at edit 20 PAT = CH$ASCIZ($NML$TEXT (', Source = %D %/%/%N'));
PTR = GETW (PTR);
$NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
.PAT,
.PTR);
end
else begin ! Node name
PAT = CH$ASCIZ($NML$TEXT (', Source = (%#A) %N'));
! removed at edit 20 PAT = CH$ASCIZ($NML$TEXT (', Source = (%#A) %/%/%N'));
$NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
.PAT,
.LEN,
.PTR);
end;
end;
%debug (NCP_NICE_VALIDATION,
(begin
$NMU$TEXT (TEXT_PTR, TXT_BFR_SZ,
'%/[NICE Request Message]%/%N');
PUTBUF (TEXT_PTR, 0,
.REQ_BLOCK_ADDR[RB_NICE],
.REQ_BLOCK_ADDR[RB_NICE_LENGTH]);
end));
$NMU$TEXT (TEXT_PTR, ! Terminate with CR/LF and a
TXT_BFR_SZ, ! null byte
'%/') ;
if .REQ_BLOCK_ADDR[RB_DATA_ALLOCATION] neq 0 ! Release data block
then NMU$MEMORY_RELEASE (.REQ_BLOCK_ADDR[RB_DATA],
.REQ_BLOCK_ADDR[RB_DATA_ALLOCATION]);
NMU$MEMORY_RELEASE (.REQ_BLOCK_ADDR, ! Release the copy of request
REQUEST_BLOCK_ALLOCATION);
end
while begin
if NML$REQUEST_SHOW (REQ_NO,REQ_BLOCK_ADDR)
then begin ! Send first or later partial response
NCP$SEND_RESPONSE ((if not .HDR
then (HDR = 1; 1)
else 2),
ch$ptr(.TXT_BFR),
.ACK_COD,
0);
$TRUE
end
else $FALSE
end;
NCP$SEND_RESPONSE ((if .HDR ! Final or only response
then 3
else 0),
ch$ptr(.TXT_BFR),
.ACK_COD,
0);
end
else begin
TEXT_PTR = ch$ptr(.TXT_BFR);
$NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
$NML$TEXT ('[The queue is empty]'));
NCP$SEND_RESPONSE (0,ch$ptr(.TXT_BFR),.ACK_COD, 0);
end;
NMU$MEMORY_RELEASE (.TXT_BFR,TXT_BFR_SZ); ! Release buffer
!
! Now we have to clean up and release the REQuest block, because this
! command never calls its completion routine
!
NMU$MEMORY_RELEASE (.REQ [RB_NICE], NICE_BUFFER_ALLOCATION);
NMU$MEMORY_RELEASE (.REQ [RB_DATA], EXECUTOR_BLOCK_ALLOCATION);
NMU$MEMORY_RELEASE (.REQ, REQUEST_BLOCK_ALLOCATION);
end; ! End of SHOW_QUEUE
%routine ('NCP_CHANGE', TYPE, OP) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Performs common semantic processing for NCP SET, DEFINE,
! CLEAR, or PURGE commands.
!
! FORMAL PARAMETERS
!
! TYPE - The type of parameters to change.
! 0 = VOLATILE
! 1 = PERMANENT
!
! OP - The operation to be performed.
! 0 = SET/DEFINE
! 1 = CLEAR/PURGE
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
local
TEMP,
OPTION_BYTE,
ENTITY_TYPE : FULL_ENTITY,
FORMAT,
LENGTH,
ENTITY_POINTER,
NODE_STRING: CH$SEQUENCE(6,8); ! Storage for node name
if not (TEMP = NM_ENTITY (ENTITY_TYPE, ! Get entity field from command
FORMAT,
LENGTH,
ENTITY_POINTER))
then return .TEMP; ! Failed
OPTION_BYTE = ((.TYPE ^ 7) or ! Change volatile/permanent parameters
(.OP ^ 6) or ! Set/Define parameters
(.ENTITY_TYPE[ENTITY_MAIN]));
NICE_OPTION (.OPTION_BYTE); ! Write option byte
if .ENTITY_TYPE[ENTITY_MAIN] eqlu ENTITY_NODE
then begin
if (.LENGTH eql 2) and ! Changing an EXECUTOR ?
(.ENTITY_POINTER eql 0)
then begin
literal
TEXT_BUFFER_LENGTH = 24*80, ! Length of text buffer in characters
TEXT_BUFFER_SIZE = ! Size in fullwords
ch$allocation (TEXT_BUFFER_LENGTH),
TEXT_BUFFER_ALLOCATION = ! Size of allocation in units
TEXT_BUFFER_SIZE * %upval,
TXT_BFR_SZ = 24*80; ! A screenful
local
TXT_BFR; ! Text buffer address for response
P_KEYW (TEMP); ! Get the next keyword
if .TEMP eql N$XNOD ! Check for 'NODE'
then begin ! Perform CHANGE EXECUTOR function
if (if P_NODE (ENTITY_POINTER)
then begin ! Node name
FORMAT = ! Length & format are less than six
LENGTH = CH$MIN(ch$ptr(ENTITY_POINTER,,6), 6);
$TRUE
end
else if P_NUM (ENTITY_POINTER)
then begin ! Node number
FORMAT = 0;
LENGTH = 2;
$TRUE
end
else $FALSE)
then CVSTA (.FORMAT, ! Convert executor node id to string
.LENGTH,
.ENTITY_POINTER,
ch$ptr(NODE_STRING,,8));
TXT_BFR = NMU$MEMORY_GET (TXT_BFR_SZ); ! Get text buffer
TEXT_PTR = ch$ptr(.TXT_BFR); ! Set up pointer to text
case (.TYPE ^ 1 or .OP) from %B'00' to %B'11' of
set
[%B'00']: ! Perform SET EXECUTOR
begin
SET_XCTR (.FORMAT,
ch$ptr(NODE_STRING,,8));
$NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
$NML$TEXT ('Set Executor Complete'));
end;
[%B'01']: ! Perform CLEAR EXECUTOR
begin
CLEAR_XCTR ();
$NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
$NML$TEXT ('Clear Executor Complete'));
end;
%( N.B. - The other cases, DEFINE EXECUTOR and
PURGE EXECUTOR will have to be handled eventually. )%
[%B'10']: ! Perform DEFINE EXECUTOR
begin
$NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
$NML$TEXT ('Define Executor is not implemented'));
end;
[%B'11']: ! Perform PURGE EXECUTOR
begin
$NMU$TEXT (TEXT_PTR,
TXT_BFR_SZ,
$NML$TEXT ('Purge Executor is not implemented'));
end;
tes;
%( N.B. - ***** Format and send a confirmation
message back to the operator. )%
NCP$SEND_RESPONSE (0,ch$ptr(.TXT_BFR),.ACK_COD, 0);
NMU$MEMORY_RELEASE (.TXT_BFR,TXT_BFR_SZ); ! Release buffer
return $TRUE
end ! ------End of EXECUTOR NODE block
else begin ! Dummy up an entity id for EXECUTOR
P_PREV (); ! Back up past current keyword
CVSTA (0, ! Convert node name to ASCII string
2,
0,
ch$ptr(NODE_STRING,,8)) ;
NICE_ENTITY (.FORMAT, ! Write entity id field
.LENGTH,
ch$ptr(NODE_STRING,,8));
end;
end
else begin
CVSTA (.FORMAT, ! Convert node id to string
.LENGTH,
.ENTITY_POINTER,
ch$ptr(NODE_STRING,,8));
NICE_ENTITY (.FORMAT, ! Write entity id field
.LENGTH,
ch$ptr(NODE_STRING,,8));
end;
end
else NICE_ENTITY (.FORMAT, ! Write entity field
.LENGTH,
.ENTITY_POINTER);
NM_PARMS (.ENTITY_TYPE,.OP) ! Process parameters
end; ! End of NCP_CHANGE
%routine ('NCP_BOOT') =
!++
! FUNCTIONAL DESCRIPTION:
!
! Performs semantic processing for the boot class commands,
! LOAD, DUMP, and TRIGGER.
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
local
RTN_COD,
OPTION_BYTE: block [1] field (BOOT_OPTIONS),
ENTITY_TYPE : FULL_ENTITY,
FORMAT,
LENGTH,
ENTITY_POINTER;
!
! Process the entity portion of the NCP command.
!
RTN_COD = NM_ENTITY (ENTITY_TYPE, ! Get entity field from command
FORMAT,
LENGTH,
ENTITY_POINTER);
if not .RTN_COD ! Error return if invalid entity
then return .RTN_COD;
!
! Format the option byte and entity id portion of the NICE request.
!
case .ENTITY_TYPE[ENTITY_MAIN] from ENTITY_LO to ENTITY_HI of
set
[ENTITY_NODE]:
begin
local
NODE_STRING: CH$SEQUENCE(6,8); ! Storage for node name
OPTION_BYTE[BO_ENTITY_TYPE] = ENTITY_NODE; ! Node id option
CVSTA (.FORMAT, ! Convert node id to string
.LENGTH,
.ENTITY_POINTER,
ch$ptr(NODE_STRING,,8));
ENTITY_POINTER = ch$ptr(NODE_STRING,,8);
NICE_OPTION (.OPTION_BYTE); ! Write option byte
NICE_ENTITY (.FORMAT, ! Write entity id field
.LENGTH,
.ENTITY_POINTER);
RTN_COD = $TRUE;
end;
[ENTITY_CIRCUIT]:
begin
OPTION_BYTE[BO_ENTITY_TYPE] = ENTITY_CIRCUIT; ! Circuit id option
NICE_OPTION (.OPTION_BYTE); ! Write option byte
NICE_ENTITY (.FORMAT, ! Write entity id field
.LENGTH,
.ENTITY_POINTER);
RTN_COD = $TRUE;
end;
[inrange,outrange]:
$INTERNAL_ERROR$ ('Invalid entity keyword for BOOT');
tes;
if not .RTN_COD
then return .RTN_COD;
! Force NM_PARMS to interpret all parameters as NODE
! entity parameters.
RTN_COD = NM_PARMS (ENTITY_NODE,0); ! Process any parameters
return .RTN_COD
end; ! End of NCP_BOOT
%routine ('CVSTA', FORMAT, LENGTH, NODE_ID, NOD_PTR) : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
! Converts parsed node id to usable format.
!
! FORMAL PARAMETERS
!
! FORMAT - A value which represents the NODE entity format type.
!
! LENGTH - A value which represents the length of the node id.
!
! NODE_ID - A value which represents either a SIXBIT node name or
! a node number, depending on the contents of FORMAT.
!
! NOD_PTR - A character sequence pointer to the destination where
! the node id string will be written.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
if .FORMAT eql 0 ! NODE in address format, so just
then PUTW (NODE_ID,NOD_PTR) ! copy it as is
else if .FORMAT gtr 0 ! NODE in name format, so convert
then ch$translate (SIXTAB,
.LENGTH,
ch$ptr(NODE_ID,,6), ! Source SIXBIT string
0,
.LENGTH,
.NOD_PTR); ! Destination ASCII string
end; ! End of CVSTA
%global_routine ('CVLTU', POINTER, LENGTH) : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
! Converts an ASCII character string from mixed (lower and upper) case
! text to all upper case text.
!
! FORMAL PARAMETERS
!
! POINTER - A character sequence pointer to the source ASCII string.
! LENGTH - The length of the ASCII string.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
bind ! Lower to upper case translation table
UPCASE = ch$transtable (rep 32 of (0),
CH$EXPLODE (' !"#$%&'), %c'''',
CH$EXPLODE ('()*+,-./0123456789'),
CH$EXPLODE (':;<=>?@ABCDEFGHIJK'),
CH$EXPLODE ('LMNOPQRSTUVWXYZ[\]'),
CH$EXPLODE ('^_`ABCDEFGHIJKLMNO'),
CH$EXPLODE ('PQRSTUVWXYZ{|}~'),
%O'177');
ch$translate (UPCASE, ! Translation table
.LENGTH, ! String length
.POINTER, ! Source string
0, ! Fill with nulls
.LENGTH,
.POINTER); ! Destination string
end; ! End of CVLTU
%routine ('CVATH', ASC_PTR, ASC_LTH, BP8_ADR) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Converts an ASCII character string, representing a hexadecimal
! number, to a string of 8 bit bytes. The ASCII string may be of
! arbitrary length, with two ASCII characters, in the range
! 0-9 and A-F only, being converted to one 8 bit byte in the
! output string. If the length of the ASCII string is an odd
! number then the first 8 bit byte written will have the first
! 4 bits set to zero. The pointer to the output string buffer
! will be point to the next available byte on return.
!
! FORMAL PARAMETERS
!
! ASC_PTR - A character sequence pointer to an ASCII hex string.
! ASC_LTH - The length of the ASCII string.
! 8BP_PTR - The address of a pointer to an 8 bit character sequence
! buffer where the output will be written.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! $TRUE, if the input ASCII string was a valid hex string.
! $FALSE, if a character other than 0-9 or A-F was encountered.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
local
SRC_LEN, ! Length of source string
SRC_PTR, ! Pointer to tail of source string
HEX_VAL; ! 8 bit HEX value
! Translate the ASCII string to HEX values. Invalid characters are
! replaced by -1. The ASCII characters which represent HEX digits
! are replaced by the HEX digit value.
SRC_LEN = .ASC_LTH;
SRC_PTR = ch$translate (HEXTAB, .SRC_LEN, .ASC_PTR, -1, .SRC_LEN, .ASC_PTR);
if not ch$fail (ch$find_ch (.SRC_LEN, .ASC_PTR, -1))
then return $FALSE;
HEX_VAL = 0; ! Initialize to zero
while (SRC_LEN = .SRC_LEN - 2) geq 0
do begin
SRC_PTR = ch$plus (.SRC_PTR, -2);
HEX_VAL<4,4> = ch$rchar_a (SRC_PTR); ! Get hi order HEX bits
HEX_VAL<0,4> = ch$rchar_a (SRC_PTR); ! Get lo order HEX bits
SRC_PTR = ch$plus (.SRC_PTR, -2);
ch$wchar_a (.HEX_VAL,.BP8_ADR); ! Write a HEX byte
end;
if .SRC_LEN ! Is it an odd length ASCII string?
then begin ! Assume hi order 4 bits zero
SRC_PTR = ch$plus (.SRC_PTR, -1);
HEX_VAL = ch$rchar_a (SRC_PTR);
ch$wchar_a (.HEX_VAL,.BP8_ADR); ! Write first HEX byte
end;
return $TRUE
end; ! End of CVATH
%routine ('CVATHI', ASC_PTR, ASC_LTH, BP8_ADR) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Converts an ASCII character string, representing a hexadecimal
! numeric string, to a string of 8 bit bytes. The ASCII string may
! be of arbitrary length, with two ASCII characters, in the range
! 0-9 and A-F only, being converted to one 8 bit byte in the
! output string. If the length of the ASCII string is an odd
! number then the first 8 bit byte written will have the first
! 4 bits set to zero. The pointer to the output string buffer
! will be point to the next available byte on return.
!
! FORMAL PARAMETERS
!
! ASC_PTR - A character sequence pointer to an ASCII hex string.
! ASC_LTH - The length of the ASCII string.
! 8BP_PTR - The address of a pointer to an 8 bit character sequence
! buffer where the output will be written.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! $TRUE, if the input ASCII string was a valid hex string.
! $FALSE, if a character other than 0-9 or A-F was encountered.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
local
SRC_LEN, ! Length of source string
SRC_PTR, ! Pointer to tail of source string
HEX_VAL; ! 8 bit HEX value
! Translate the ASCII string to HEX values. Invalid characters are
! replaced by -1. The ASCII characters which represent HEX digits
! are replaced by the HEX digit value.
SRC_LEN = .ASC_LTH;
ch$translate (HEXTAB, .SRC_LEN, .ASC_PTR, -1, .SRC_LEN, .ASC_PTR);
if not ch$fail (ch$find_ch (.SRC_LEN, .ASC_PTR, -1))
then return $FALSE;
HEX_VAL = 0; ! Initialize to zero
SRC_PTR = .ASC_PTR;
if .SRC_LEN ! Is it an odd length ASCII string?
and (.SRC_LEN gtr 0) ! Make sure it is not negative length
then begin ! Assume hi order 4 bits zero
HEX_VAL<0,4> = ch$rchar_a (SRC_PTR);
ch$wchar_a (.HEX_VAL,.BP8_ADR); ! Write first HEX byte
SRC_LEN = .SRC_LEN - 1;
end;
while (SRC_LEN = .SRC_LEN - 2) geq 0
do begin
HEX_VAL<4,4> = ch$rchar_a (SRC_PTR); ! Get hi order HEX bits
HEX_VAL<0,4> = ch$rchar_a (SRC_PTR); ! Get lo order HEX bits
ch$wchar_a (.HEX_VAL,.BP8_ADR); ! Write a HEX byte
end;
return $TRUE
end; ! End of CVATHI
%routine ('REMOVE_DASHES', INPUT_PTR, INPUT_LENGTH, OUTPUT_PTR) =
!++
!
! Functional description:
!
! This function removes all dashes from a string. It takes an ETHERNET
! address as input with dashes and outputs a string with the dashes
! removed. No syntax checks are made.
!
! Formal parameters:
!
! INPUT_PTR Character pointer to input string
! INPUT_LENGTH Length of input string
! OUTPUT_PTR Character pointer to output string
!
! Routine value:
!
! Returns length of output string
!
!--
begin
local
OUTPUT_LENGTH, ! Output length
COUNT, ! Input count
CHR; ! Current character
COUNT = .INPUT_LENGTH; ! Set up count of chars to do
OUTPUT_LENGTH = 0; ! No output chars yet
! Loop over input string
while (COUNT = .COUNT - 1) geq 0
do begin
CHR = ch$rchar_a (INPUT_PTR); ! Read next char
if .CHR neq %C'-'
then begin
ch$wchar_a (.CHR, OUTPUT_PTR);
OUTPUT_LENGTH = .OUTPUT_LENGTH + 1;
end;
end;
return .OUTPUT_LENGTH; ! Return the output string length
end; ! End of REMOVE_DASHES
%routine ('SET_XCTR', FORMAT, NODE_PTR) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Performs the SET EXECUTOR NODE node-id command.
!
! FORMAL PARAMETERS
!
! FORMAT - The node entity format byte.
! 0 = NODE address
! >0 = NODE name
!
! NODE_PTR - Pointer to node entity id.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
local
USR_LEN,
ACT_LEN,
PWD_LEN,
TEMP,
XCTR: ref block[XCTR_SZ] field(XCTR_FIELDS);
!
! Check to see if this OPERATOR has previously specified an EXECUTOR.
! If so, reuse that block else allocate a new executor block and place
! in the data base.
!
if (XCTR = NMU$QUEUE_SCAN (XCTR_NOD_Q,.ACK_COD,SCAN_XCTR_Q)) eql 0
then begin ! Entry not in queue
XCTR = NMU$MEMORY_GET (XCTR_SZ); ! Allocate storage for EXECUTOR
XCTR[OPR_ID] = .ACK_COD; ! Copy operator identifier
NMU$QUEUE_INSERT (XCTR_NOD_Q,.XCTR) ! Insert it
end;
!
! Copy the new EXECUTOR node id into the block in the data base.
!
TEMP = ch$ptr(XCTR[NOD_ID],,8); ! Pointer to node id
if .FORMAT eql 0 ! Node address format ?
then begin
TEMP = ch$move(2, ! Copy node address
.NODE_PTR,
.TEMP);
PUTB (0,TEMP); ! Write I-length of zero
end
else begin
ch$wchar_a (0,TEMP); ! Write node address of zero
ch$wchar_a (0,TEMP);
ch$wchar_a (.FORMAT,TEMP); ! Write I-field length
ch$move (.FORMAT, ! Copy node name string
.NODE_PTR,
.TEMP);
end;
!
! Process any access control info specified in the command and copy it into
! the EXECUTOR block. If an EXECUTOR had been previously specified and access
! control info was specified then default to any access control previously
! specified in the absence of any new access control.
!
ACCESS_CONTROL (ch$ptr(XCTR[USR_ID],1),USR_LEN, ! Get access control info
ch$ptr(XCTR[ACTSTR],1),ACT_LEN,
ch$ptr(XCTR[PWDSTR],1),PWD_LEN);
ch$wchar(.USR_LEN,ch$ptr(XCTR[USR_ID])); ! Write length byte
ch$wchar(.ACT_LEN,ch$ptr(XCTR[ACTSTR])); ! Write length byte
ch$wchar(.PWD_LEN,ch$ptr(XCTR[PWDSTR])); ! Write length byte
return 1;
end; ! End of SET_XCTR
%routine ('CLEAR_XCTR') =
!++
! FUNCTIONAL DESCRIPTION:
!
! Performs the CLEAR EXECUTOR NODE command.
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
local
XCTR: ref block[XCTR_SZ] field(XCTR_FIELDS);
if (XCTR = NMU$QUEUE_SCAN (XCTR_NOD_Q,.ACK_COD,SCAN_XCTR_Q)) neq 0
then begin ! An EXECUTOR was previously set
if not NMU$QUEUE_EXTRACT (XCTR_NOD_Q,.XCTR) ! Delete from data base
then $INTERNAL_ERROR$ ('EXECUTOR was on queue but could not be extracted');
end;
return 1;
end; ! End of CLEAR_XCTR
%routine ('ACCESS_CONTROL', USR_PTR, USR_LEN, ACT_PTR, ACT_LEN, PWD_PTR, PWD_LEN) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Performs semantic processing of access control fields in
! SET EXECUTOR and LOOP NODE commands, and TELL prefix.
!
! FORMAL PARAMETERS
!
!
!
! IMPLICIT INPUTS
!
! Current position within the PB portion of the MS block.
!
! ROUTINE VALUE: Returns keyword code of next keyword, if exists.
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
local
TEMP; ! Local work variable
.USR_LEN = .PWD_LEN = .ACT_LEN = 0; ! Initialize to indicate no access ctl
while (P_KEYW (TEMP))
do begin
case .TEMP from N$XACT to N$XUSR of
set
[N$XACT]: ! ACCOUNT
begin
if P_FLD (TEMP)
then begin
.ACT_LEN = CH$MIN(ch$ptr(.TEMP+1), 16);
CVLTU (ch$ptr(.TEMP+1), ..ACT_LEN); ! Convert to upper case
QUOTE_FIELD (..ACT_LEN,
ch$ptr(.TEMP+1),
.ACT_PTR);
end
else $INTERNAL_ERROR$ ('Access control field syntax error');
end;
[N$XPWD]: ! PASSWORD
begin
%( N.B. - Note that over the network the password provided
on a connection to a remote server is 8 bit binary. As
implemented here and in the NCP3TB syntax tables only
7 bit ASCII strings are provided. If the full 8 bit
functionality is desired then NCP3TB must be changed
to accept octal triplets, ala, NETPRO; and this code
changed accordingly. )%
if P_FLD (TEMP)
then begin
.PWD_LEN = CH$MIN(ch$ptr(.TEMP+1), 16);
CVLTU (ch$ptr(.TEMP+1), ..PWD_LEN); ! Convert to upper case
QUOTE_FIELD (..PWD_LEN,
ch$ptr(.TEMP+1),
.PWD_PTR);
end
else $INTERNAL_ERROR$ ('Access control field syntax error');
end;
[N$XUSR]: ! USER
begin
if P_FLD (TEMP)
then begin
.USR_LEN = CH$MIN(ch$ptr(.TEMP+1), 16);
CVLTU (ch$ptr(.TEMP+1), ..USR_LEN); ! Convert to upper case
QUOTE_FIELD (..USR_LEN,
ch$ptr(.TEMP+1),
.USR_PTR);
end
else $INTERNAL_ERROR$ ('Access control field syntax error');
end;
[inrange,
outrange]: ! Keyword other than access control
begin
return .TEMP; ! Return keyword code, probably command
end;
tes;
end;
return N$XACT ! Return ridiculous keyword code
end; ! End of ACCESS_CONTROL
%routine ('QUOTE_FIELD', N, SPTR, DPTR) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Inserts the TOPS-20 file name quote character (^V) preceding
! any characters other than alphanumerics and dash ('-').
!
! FORMAL PARAMETERS
!
! N - Count of characters to move.
! SPTR - Pointer to source string.
! DPTR - Pointer to destination string.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! The length of the string with embedded control chars.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
local
CH, ! Single character value
LEN;
LEN = .N; ! Initial value
decr REMAINING from .N to 1 ! Loop for each character in string
do begin
CH = ch$rchar_a (SPTR); ! Fetch a character
! If not an alpha, numeric, or hyphen then quote with ^V
%if $TOPS20 %then
if (.CH lss %C'0' and .CH neq %C'-')
or (.CH gtr %C'9' and .CH lss %C'A')
or (.CH gtr %C'Z' and .CH lss %C'a')
or (.CH gtr %C'z')
then begin
ch$wchar_a ((%C'V' - %O'100'),DPTR);
LEN = .LEN + 1;
end;
%fi ! End of %if $TOPS20
ch$wchar_a (.CH,DPTR); ! Write the character
end;
.LEN ! Return adjusted length
end; ! End of QUOTE_FIELD
%routine ('SCAN_XCTR_Q', Q_ADDR, DATA) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Called by NMU$QUEUE_SCAN as an exit routine to determine if a
! particular EXECUTOR block in the EXECUTOR data base list matches
! the operator id being searched for.
!
! FORMAL PARAMETERS
!
! Q_ADDR - Address of the EXECUTOR block in the data base list.
!
! DATA - The operator id being searched for.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! Q_ADDR, if the entry in the data base matches the operator id being
! searched for.
! Zero, otherwise.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
map
Q_ADDR: ref block[XCTR_SZ] field(XCTR_FIELDS);
if .Q_ADDR[OPR_ID] eql .DATA
then return .Q_ADDR ! Found entry being scanned for
else return 0 ! Not found, return zero
end; ! End of SCAN_XCTR_Q
%routine ('READ_OPTION', TYPE, ENTITY_TYPE, ADDRESS) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Builds the option byte for the NICE read information message
! based on the keywords entered on a SHOW or LIST command.
!
! FORMAL PARAMETERS
!
! TYPE A value which represents whether the permanent or
! volatile parameters are to be read.
! 0 = Volatile
! 1 = Permanent.
!
! ENTITY_TYPE The value of the entity type field.
!
! ADDRESS The address of the location where the option byte
! is to be stored.
!
! IMPLICIT INPUTS
!
! Current position within the PB portion of the MS block.
!
! ROUTINE VALUE: True or False.
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
map
ENTITY_TYPE : FULL_ENTITY,
ADDRESS: ref block [1] field (READ_OPTIONS);
local
INFO_TYPE;
!
! The PB is assumed to be pointing past the entity id and at the
! beginning of the parameter keyword.
!
if P_KEYW (INFO_TYPE) ! Get information class
then begin
.ADDRESS = 0; ! Clear the option byte
ADDRESS[RO_PERMANENT] = .TYPE; ! Set the type of parameters to read
ADDRESS[RO_ENTITY_TYPE] = .ENTITY_TYPE[ENTITY_MAIN]; ! Set entity type number
selectone .INFO_TYPE of ! Set information type
set
[$KNCHR]:
ADDRESS[RO_INFO_TYPE] = CHARACTERISTICS_;
[$KNCTR]:
ADDRESS[RO_INFO_TYPE] = COUNTERS_;
[$KNEVT]:
ADDRESS[RO_INFO_TYPE] = EVENTS_;
[$KNSTS]:
ADDRESS[RO_INFO_TYPE] = STATUS_;
[$KNSUM]:
ADDRESS[RO_INFO_TYPE] = SUMMARY_;
[otherwise]: ! Error case
$INTERNAL_ERROR$ ('Invalid parameter keyword');
tes;
return $TRUE; ! Success return
end
else $INTERNAL_ERROR$ ('Invalid message format, expected keyword')
end; ! End of READ_OPTION
%routine ('NICE_INITIALIZE', FUNC_CODE) : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
! Initializes NICE message buffer and stores the NICE function
! code, passed as an argument, in the first byte of the NICE
! message.
!
! FORMAL PARAMETERS
!
! Value of the NICE function code as described in NM Functional
! Specification.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE: NONE.
!
! NONE.
!
! SIDE EFFECTS:
!
! REQ[RB_NICE] is set to the address of a dynamically allocated NICE
! message buffer.
!
! REQ[RB_NICE_POINTER] is updated to point to first byte after the NICE
! function code.
!
! REQ[RB_NICE_LENGTH] is updated to reflect message length of 1.
!
! REQ[RB_NICE_FUNCTION] is set to the function code.
!
!--
begin
REQ[RB_NICE_POINTER] = ch$ptr (.REQ[RB_NICE],,8);
REQ[RB_NICE_LENGTH] = 0; ! Point at beginning of NICE buffer
ch$wchar_a (.FUNC_CODE,REQ[RB_NICE_POINTER]); ! Store NICE function code
REQ[RB_NICE_FUNCTION] = .FUNC_CODE; ! Store NICE function code
REQ[RB_NICE_LENGTH] = .REQ[RB_NICE_LENGTH] + 1; ! Bump length count
end; ! End of NICE_INITIALIZE
%routine ('NICE_OPTION', OPTION_BYTE) : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
ch$wchar_a(.OPTION_BYTE,REQ[RB_NICE_POINTER]); ! Write option byte
REQ[RB_NICE_LENGTH] = .REQ[RB_NICE_LENGTH] + 1; ! Bump length
end; ! End of NICE_OPTION
%routine ('NICE_TEST', USER, USR_LEN, PWD, PWD_LEN, ACCT, ACT_LEN, TYPE, FORMAT, LENGTH, ENTITY_POINTER) : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
! Builds NICE test message for LOOP command.
!
! FORMAL PARAMETERS
!
! USER - A character pointer to a user id string
! if entity is node.
! USR_LEN - The length of the user id string.
!
! PWD - A character pointer to a password string
! if entity is node.
! PWD_LEN - The length of the password string.
!
! ACCT - A character pointer to an account string
! if entity is node.
! ACT_LEN - The length of the account string.
!
! TYPE - The type of loop test to perform. Corresponds to
! the entity type.
! 0 = NODE.
! 1 = LINE.
!
! FORMAT - A value which represents the entity format byte.
!
! LENGTH - A value for the length of the entity id string.
!
! ENTITY_POINTER - A character pointer to the entity id string.
!
!
! IMPLICIT INPUTS
!
! NICE buffer.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
local
OPTION;
case .TYPE from ENTITY_LO to ENTITY_HI of
set
[ENTITY_NODE]: ! Node loop test
if .USR_LEN gtr 0
or .PWD_LEN gtr 0
or .ACT_LEN gtr 0
then begin
OPTION = ((1 ^ 7) or (0 ^ 0)); ! Access control supplied
PUTB (.OPTION,REQ[RB_NICE_POINTER]); ! Write option byte
REQ[RB_NICE_LENGTH] = .REQ[RB_NICE_LENGTH] + 1; ! Bump length
NICE_ENTITY (.FORMAT, ! Build entity id
.LENGTH,
.ENTITY_POINTER);
PUTB (.USR_LEN,REQ[RB_NICE_POINTER]); ! Copy user id length
if .USR_LEN gtr 0 ! And string if any
then REQ[RB_NICE_POINTER] =
ch$move (.USR_LEN,
.USER,
.REQ[RB_NICE_POINTER]);
PUTB (.PWD_LEN,REQ[RB_NICE_POINTER]); ! Copy password length
if .PWD_LEN gtr 0 ! And string if any
then REQ[RB_NICE_POINTER] =
ch$move (.PWD_LEN,
.PWD,
.REQ[RB_NICE_POINTER]);
PUTB (.ACT_LEN,REQ[RB_NICE_POINTER]); ! Copy account length
if .ACT_LEN gtr 0 ! And string if any
then REQ[RB_NICE_POINTER] =
ch$move (.ACT_LEN,
.ACCT,
.REQ[RB_NICE_POINTER]);
REQ[RB_NICE_LENGTH] = .REQ[RB_NICE_LENGTH] + 3 +
.USR_LEN +
.PWD_LEN +
.ACT_LEN;
end
else begin
OPTION = ((0 ^ 7) or (0 ^ 0)); ! Default access control
ch$wchar_a(.OPTION,REQ[RB_NICE_POINTER]); ! Write option byte
REQ[RB_NICE_LENGTH] = .REQ[RB_NICE_LENGTH] + 1; ! Bump length
NICE_ENTITY (.FORMAT, ! Build entity id
.LENGTH,
.ENTITY_POINTER);
end;
[ENTITY_LINE, ! Data link test
ENTITY_CIRCUIT]:
begin
OPTION = ((0 ^ 7) or (.TYPE ^ 0)); ! Line loop test
ch$wchar_a(.OPTION,REQ[RB_NICE_POINTER]); ! Write option byte
REQ[RB_NICE_LENGTH] = .REQ[RB_NICE_LENGTH] + 1; ! Bump length
NICE_ENTITY (.FORMAT, ! Build entity id
.LENGTH,
.ENTITY_POINTER);
end;
[inrange, ! Invalid entity
outrange]:
;
tes
end; ! End of NICE_TEST
%routine ('NICE_ENTITY', FORMAT, LENGTH, ENTITY_POINTER) : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
ch$wchar_a (.FORMAT, REQ[RB_NICE_POINTER]); ! Write entity format byte
if .LENGTH gtr 0
then begin
REQ[RB_NICE_POINTER] = ch$move (.LENGTH,
.ENTITY_POINTER,
.REQ[RB_NICE_POINTER]);
REQ[RB_NICE_LENGTH] = .REQ[RB_NICE_LENGTH] + .LENGTH + 1;
end
else REQ[RB_NICE_LENGTH] = .REQ[RB_NICE_LENGTH] + 1;
end; ! End of NICE_ENTITY
%global_routine ('PUTBUF', PTR, BIAS, ADR, LNG) : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
!
!
!
! FORMAL PARAMETERS:
!
! PTR -> The address of a character sequence pointer to the
! resultant text buffer.
!
! BIAS -> A BLISS value which represents a byte offset into the
! beginning of the buffer to be displayed.
!
! ADR -> The address of the buffer to be displayed
!
! LNG -> A BLISS value which represents the number of bytes
! to be displayed.
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS
!
! NONE
!
!--
begin
local
ADDRESS, !Current dump address.
BASE_ADR,
CHR_PTR, !Pointer to bytes string.
BYTES_LEFT, !Number of bytes left to process.
COUNT; !Number of bytes for this line.
literal
TEXT_BUFFER_LENGTH = 80, ! Length of text buffer in characters
TEXT_BUFFER_SIZE = ! Size in fullwords
ch$allocation (TEXT_BUFFER_LENGTH),
TEXT_BUFFER_ALLOCATION = ! Size of allocation in units
TEXT_BUFFER_SIZE * %upval,
TXT_BFR_SZ = 80; ! A Line's worth
ADDRESS = .ADR + .BIAS; ! Buffer address
BASE_ADR = .BIAS; ! Offset from start of buffer
BYTES_LEFT = .LNG; ! Length of buffer
CHR_PTR = ch$ptr(.ADDRESS,0,8); ! Pointer to bytes string.
while (COUNT = min (.BYTES_LEFT, 8)) gtr 0 do
begin
$NMU$TEXT (.PTR,
TXT_BFR_SZ,
'%(6)P %#(32L)B%2- *%#(8L)E*%/%N',
.BASE_ADR,
.COUNT,
.CHR_PTR);
CHR_PTR = ch$plus(.CHR_PTR,.COUNT); ! Bump pointer
BASE_ADR = .BASE_ADR + .COUNT;
BYTES_LEFT = .BYTES_LEFT - .COUNT;
end;
$NMU$TEXT (.PTR, ! Terminate string with null byte
TXT_BFR_SZ,
'%/');
end; ! End of PUTBUF
%routine ('ASSEMBLER', ENTITY_TYPE, PARAMETER, DATA, LENGTH) : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
! Assemble data into the NICE message buffer, according to the
! specified format, and bump message counter by given length.
!
! FORMAL PARAMETERS
!
! If FORMAT is
!
! DU1,2,4 DATA - Address of location contains 1 to 4
! C1, O4 bytes of data.
!
!
! AI, HI DATA - Address of location contains pointer to
! the ASCII string for AI, and pointer to
! the field of 8-bit binary bytes for HI.
! LENGTH - Actual length of the string.
!
!
! CM2 DATA - Address of data vector, where
! +0: first 2-byte
! +1: second 2-byte
!
!
! CMN DATA - Address of location contains
! - a pointer to the node name ASCII
! string, or
! - 2 bytes of binary node address.
! LENGTH - Contains the length of the node name
! ASCII string, or 0 for node address.
!
!
! CMO DATA - Address of location contains
! - a pointer to the object name ASCII
! string, or
! - 1 byte of binary object number.
! LENGTH - Contains the length of the object name
! ASCII string, or 0 for object number.
!
!
! CME DATA - Address of data vector, where
! +0: Event class
! +1: Event mask (high order 8 bytes)
! +2: Event mask (low order 8 bytes)
! +3: Entity type
! +4: Entity id length
! +5: Entity id
!
!
! HX8 DATA - Address of location contains pointer
! to an HEX numeric string.
! LENGTH - Number of HEX digits in the string.
!
! IMPLICIT INPUTS
!
! NICE buffer.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
map
ENTITY_TYPE : FULL_ENTITY;
local
DATA_TYPE: block [1] field (DATA_TYPE_FIELDS),
NEWLEN;
DATA_TYPE = NML$DATA_TYPE (.ENTITY_TYPE, .PARAMETER);
if .DATA_TYPE[DT_CODED] eql 0
then begin
if .DATA_TYPE[DT_FTYPE] eql 0
then begin
selectone (NEWLEN = .DATA_TYPE[DT_LENGTH]) of
set
[0] : ! HI
begin
local
TEMP_STR : block [ch$allocation(32,8)],
TEMP_PTR,
TEMP;
TEMP_PTR = ch$ptr (TEMP_STR,,8);
TEMP = REMOVE_DASHES (..DATA, .LENGTH, .TEMP_PTR);
NEWLEN = (.TEMP+1)/2; ! Calculate number of bytes
PUTB (.NEWLEN,REQ[RB_NICE_POINTER]); ! Write count byte
CVATHI (.TEMP_PTR, .TEMP, REQ[RB_NICE_POINTER]);
NEWLEN = .NEWLEN + 1; ! Update length of message
end;
[1] : ! DU1
PUTB (..DATA,REQ[RB_NICE_POINTER]);
[2] : ! DU2, O2
PUTW ((.DATA),REQ[RB_NICE_POINTER]);
[4] : ! DU4, O4
begin
incr I from 0 to .NEWLEN-1
do PUTB (.(.DATA)<.I*8,8,0>,REQ[RB_NICE_POINTER]);
end;
[8] : ! HX8
begin
local
TEMP_STR : block [ch$allocation(32,8)],
TEMP_PTR,
TEMP;
TEMP_PTR = ch$ptr (TEMP_STR,,8);
TEMP = REMOVE_DASHES (..DATA, .LENGTH, .TEMP_PTR);
CVATH (.TEMP_PTR, .TEMP, REQ[RB_NICE_POINTER]);
REQ[RB_NICE_POINTER] =
ch$fill (0,
.NEWLEN - min((.TEMP+1)/2,.NEWLEN),
.REQ[RB_NICE_POINTER]);
end;
[otherwise] :
$INTERNAL_ERROR$ ('Unable to assemble parameter code');
tes;
end
else begin ! AI
if .LENGTH gtr 0
then begin ! Regular ASCII parameter
PUTB (.LENGTH,REQ[RB_NICE_POINTER]);
REQ[RB_NICE_POINTER] = ch$move (.LENGTH,
..DATA,
.REQ[RB_NICE_POINTER]);
NEWLEN = .LENGTH + 1;
end
else begin
if NML$INFORMATION (.ENTITY_TYPE, .PARAMETER, QUALIFIER_)
then begin ! This must be the KNOWN Qualifier.
PUTB (KNOWN_, REQ[RB_NICE_POINTER]);
NEWLEN = 1;
end
else return;
end;
end;
end
else if .DATA_TYPE[DT_FIELDS] eql 0
then begin
selectone (NEWLEN = .DATA_TYPE[DT_NUMBER]) of
set
[1]: ! C1
PUTB (..DATA,REQ[RB_NICE_POINTER]);
[otherwise]:
$INTERNAL_ERROR$ ('Unable to assemble parameter code');
tes;
end
else NEWLEN = 0;
if .NEWLEN neq 0
then begin
REQ[RB_NICE_LENGTH] = .REQ[RB_NICE_LENGTH] + .NEWLEN;
return
end;
selectone .DATA_TYPE[DT_NUMBER] of
set
[CMN, ! Coded node field
CMO] : ! Coded object field
begin
if .LENGTH gtr 0
then begin ! Write node name or object name
PUTB (.LENGTH,REQ[RB_NICE_POINTER]);
REQ[RB_NICE_POINTER] = ch$move (.LENGTH,
..DATA,
.REQ[RB_NICE_POINTER]);
NEWLEN = .LENGTH + 1; ! Bump length
end
else begin
if NML$INFORMATION (.ENTITY_TYPE, .PARAMETER, EVENTS_)
and (.DATA_TYPE[DT_NUMBER] eql CMN)
and (..DATA eql -1)
then begin ! KNOWN SINKS parameter
PUTB (-1,REQ[RB_NICE_POINTER]);
NEWLEN = 1;
end
else begin ! Regular NODE number
PUTB (%O'0',REQ[RB_NICE_POINTER]);
NEWLEN = (if .DATA_TYPE[DT_NUMBER] eql CMN
then begin ! Write 2 bytes of node address
PUTW ((.DATA),REQ[RB_NICE_POINTER]);
3 ! Bump length
end
else begin ! Write 1 byte of object number
PUTB (..DATA,REQ[RB_NICE_POINTER]);
2 ! Bump length
end);
end;
end;
end;
[CM2] : ! Coded 2 fields
begin
if .(.DATA+1) eql 0 ! Set null range end to same as begin
then (.DATA+1) = ..DATA;
PUTW ((.DATA),REQ[RB_NICE_POINTER]);
PUTW ((.DATA+1),REQ[RB_NICE_POINTER]);
NEWLEN = 4;
end;
[CME] : ! Coded event fields
begin
local LEN;
bind
CLASS = (.DATA+0),
EMASK = (.DATA+2),
ETYPE = (.DATA+3),
IDLEN = (.DATA+4),
IDVAL = (.DATA+5);
PUTB (.ETYPE,REQ[RB_NICE_POINTER]); ! Write entity type
NEWLEN = 1;
if .ETYPE gtr -1 ! Write entity type and id
then begin
if (LEN = .IDLEN) gtr 0
then begin ! NODE, LINE, CIRCUIT and MODULE id
LEN = min(.LEN,(if .ETYPE eql $KNNOD then 6 else 16));
PUTB (.LEN,REQ[RB_NICE_POINTER]);
REQ[RB_NICE_POINTER] = ch$move (.LEN,
.IDVAL,
.REQ[RB_NICE_POINTER]);
NEWLEN = .NEWLEN + .LEN + 1;
end
else begin ! NODE number
PUTB (%O'0',REQ[RB_NICE_POINTER]);
PUTW (IDVAL,REQ[RB_NICE_POINTER]);
NEWLEN = .NEWLEN + 3;
end;
end;
PUTW (CLASS,REQ[RB_NICE_POINTER]); ! Write event class
NEWLEN = .NEWLEN + 2;
if (.EMASK neq 0) or (.(EMASK-1) neq 0)
then begin ! Write event mask
local MSKCNT, SCANNING;
SCANNING = $TRUE;
MSKCNT = 8; ! Assume there are 8 bytes to write
decr J from 1 to 0 ! Verify that and remove hi order
do begin ! zero bytes
decr I from 24 to 0 by 8
do begin
if .(EMASK-.J)<.I,8,0> eql 0
then MSKCNT = .MSKCNT - 1
else begin
SCANNING = $FALSE;
exitloop;
end;
end;
if not .SCANNING
then exitloop;
end;
if .MSKCNT gtr 0
then begin
PUTB (.MSKCNT,REQ[RB_NICE_POINTER]); ! Write count byte
NEWLEN = .NEWLEN + .MSKCNT + 1; ! Update length
incr J from 0 to 1
do incr I from 0 to 24 by 8
do begin ! Write mask, lo order bytes first
if .MSKCNT gtr 0
then PUTB (.(EMASK-.J)<.I,8,0>,REQ[RB_NICE_POINTER])
else exitloop;
MSKCNT = .MSKCNT - 1;
end;
end;
end;
end;
[otherwise] :
$INTERNAL_ERROR$ ('Unable to assemble parameter code');
tes;
REQ[RB_NICE_LENGTH] = .REQ[RB_NICE_LENGTH] + .NEWLEN;
end; ! End of ASSEMBLER
%routine ('NICE_PARM', LENGTH, DATA, CLEAR_PURGE, PARAMETER, ENTITY_TYPE) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Builds a single parameter field in a NICE message.
! A single parameter is written into the NICE buffer and current
! NICE message length is updated accordingly. The NICE request message
! pointer is updated to point to the next available in the buffer.
!
! FORMAL PARAMETERS
!
! LENGTH - An optional parameter which provides the length in
! bytes of parameter data which is of variable length.
!
! DATA - The vector contains addresses of the data, to be
! interpreted according to the entity type.
!
! CLEAR_PURGE - A flag to indicate whether data is to be written along
! with the DATA ID field, i.e., whether we are doing a
! SET/DEFINE or a CLEAR/PURGE.
!
! PARAMETER - A value to be placed in the parameter type number field
! (bits 0 to 11) in the data id field of a parameter.
!
! ENTITY_TYPE - The entity type with which the parameter is associated.
!
! IMPLICIT INPUTS
!
! NICE buffer.
!
! ROUTINE VALUE:
!
! $TRUE, If the parameter number is valid and the data has been
! written into the NICE request message buffer;
! $FALSE, otherwise.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
map
ENTITY_TYPE : FULL_ENTITY;
local
NUMBER;
if .PARAMETER eql P$ALL ! ALL Parameter ?
then return $TRUE; ! Requires no processing
NUMBER = .PARAMETER and %O'7777'; ! Mask data id to be exactly 12 bits
PUTW (NUMBER, REQ[RB_NICE_POINTER]);
REQ[RB_NICE_LENGTH] = .REQ[RB_NICE_LENGTH] + 2; ! Bump length
! If CLEAR_PURGE flag is set, but DATA vector contain non-zero data,
! and the entity is MODULE, then it may be qualifier identification
! string, so write it; otherwise, there should not be any data following
! parameter numbers when the CLEAR_PURGE flag is set.
if .CLEAR_PURGE ! Need to write the data ?
and not (NML$INFORMATION (.ENTITY_TYPE, .PARAMETER, QUALIFIER_) or
NML$INFORMATION (.ENTITY_TYPE, .PARAMETER, EVENTS_))
then return $TRUE; ! No, all done
if NML$UPPER_CASE (.ENTITY_TYPE, .PARAMETER)
then CVLTU (..DATA, .LENGTH); ! Convert text to upper case
ASSEMBLER (.ENTITY_TYPE, ! Entity type
.PARAMETER, ! Parameter Number
.DATA, ! Address of the data vector
.LENGTH); ! Actual length of data item
return $TRUE;
end; ! End of NICE_PARM
end ! End of Module NCPCEX
eludom
! Local Modes:
! Mode:BLISS
! Auto Save Mode:0
! Comment Column:40
! Comment Rounding:+1
! End: