Trailing-Edge
-
PDP-10 Archives
-
TOPS-20_V6.1_DECnetSrc_7-23-85
-
mcb/sc/sc1.bli
There is 1 other file named sc1.bli in the archive. Click here to see a list.
module SC1 ( ! Network Management stuff
ident = 'X01260'
) =
begin
!
! COPYRIGHT (c) 1980, 1981, 1982
! DIGITAL EQUIPMENT CORPORATION
! Maynard, Massachusetts
!
! 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: Session Control
!
! ABSTRACT: This is the Network Management module for the MCB
! implementation of Session Control.
!
! ENVIRONMENT: MCB
!
! AUTHOR: Buren Hoffman CREATION DATE: 20-Nov-80
!
! MODIFIED BY:
! X01010 Made this module an extension process.
! X01020 Use new Comm/Exec to process linkage (.CRDAT for database)
! X01030 Added event logging module NM_SIG
! X01040 Added new entry (NM_NOD) to allow outside modules to
! ascertain node name to number mappings.
! X01050 Updated to use library calls, instead of requires.
! X01060 Fix in node location code.
! X01070 Changed SC state representations to same as NM usage.
! X01080 Fixed state checking bug.
! X01090 Modified node search to default to local node when null
! node spec is given.
! X01100 Fixed error reporting in "show-node-characteristics"
! X01110 Mapping bug in SHOW_NODE_ITEMS fixed.
! X01120 Fixed reporting in show_nodes stuff
! X01130 Repaired mapping bug in RETURN_NODE_LIST.
! X01140 Utilize "paranoid" conditional for some checking, and
! fixed case-shift bug in node-name selection.
! X01150 Optimization work
! X01160 Fixed mapping bug in SHOW_NODE_ITEMS
! X01170 Added Host-Node-ID processing, and put in
! abbreviated reporting on Return-Nodes function
! x01180 Ron Platukis 17-nov-81
! -fix code for parmeter 400 and 501 support.
! x01190 Ron Platukis 8-dec-81
! -allow setting of a node name if it already exists.
! x01200 Alan Peckham 14-apr-82
! -Optimize code.
! -Change RETURN_NODE_LIST functionality for new NMX.
! This fixes the duplicate node names and makes sure
! that the entries are in order.
! -Fix Loop node support.
! -Support change in NMT data base (SCPRM changed).
! x01210 Alan Peckham 14-apr-82
! -Fix bug which displays invalid EXECUTOR STATE.
! x01220 Alan Peckham 2-may-82
! -Change buffer overflow code to $NM$ERR_REE
! in RETURN_NODE_LIST
! x01230 Alan Peckham 22-may-82
! -Fix to not display CLEARed parameters.
! -Do some range checking on received parameter values.
! x01240 Alan Peckham 26-may-82
! -Fix INSERT_NODE bug which did not maintain space left
! x01250 Alan Peckham 1-oct-82
! -Fix CLEAR_NODE_PARMS to handle CLEAR ALL case.
! -Fix SET_NODE_PARMS to respond to SET ALL with $NM$ERR_OPF.
! x01260 Alan Peckham 12-oct-82
! -Fix mapping bug introduced by edit #25.
!--
!
! REQUIRED FILES
!
library 'SCPRM'; ! Our parameter and macro definitions
library 'MCB:MCBLIB';
library 'MCB:NMXLIB';
library 'MCB:XPORTX';
require 'NSP:NSINFO';
!
! TABLE OF CONTENTS:
!
linkage
SC_LKG_CCB = jsr (register = 4),
SC_LKG_CCB_PTR_LNG = jsr (register = 4, register = 1, register = 0),
SC_LKG_LEN_PTR = jsr (register = 1, register = 2),
SC_LKG_NMT_CCB = jsr (register = 1, register = 4),
SC_LKG_PTR = jsr (register = 3),
SC_LKG_SCDB_NMT_CCB = jsr (register = 5, register = 1, register = 4);
forward routine
NM_EXT: call$ novalue,
NM_NOD: call$ novalue,
NM_SIG: call$ novalue,
CLEAR_NODE_PARMS : SC_LKG_CCB,
CLEAR_EXECUTOR_INCOMING_TIMER : SC_LKG_SCDB_NMT_CCB,
CLEAR_EXECUTOR_OUTGOING_TIMER : SC_LKG_SCDB_NMT_CCB,
CLEAR_NODE_CIRCUIT : SC_LKG_SCDB_NMT_CCB,
CLEAR_NODE_NAME : SC_LKG_SCDB_NMT_CCB,
SET_NODE_PARMS : SC_LKG_CCB,
SHOW_NODE_ITEMS : SC_LKG_CCB,
RETURN_NODE_LIST : SC_LKG_CCB,
SHOW_CIRCUIT_ITEMS : SC_LKG_CCB,
CASE_SHIFT : SC_LKG_LEN_PTR novalue,
GET_NODE : SC_LKG_PTR,
INSERT_NODE : SC_LKG_NMT_CCB novalue,
MAKE_ROOM : SC_LKG_CCB_PTR_LNG novalue;
!
! MACROS:
!
macro
RAD50 (STR) =
%if %bliss (bliss36) %then %rad50_10 STR %else %rad50_11 STR %fi %;
!
! EQUATED SYMBOLS:
!
!
! OWN STORAGE:
!
$MCB_PROCESS (NAME = SC1);
!
! EXTERNAL REFERENCES:
!
%sbttl 'Network Management'
global routine NM_EXT (CCB): call$ novalue =
!++
! FUNCTIONAL DESCRIPTION:
! This routine is activated by a control request from
! Network Management.
!
! FORMAL PARAMETERS:
! CCB CCB to pass to handler routine
!
! IMPLICIT INPUTS:
! CCB Contents
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map CCB: ref block field (C_NM_FIELDS);
local
STATUS;
STATUS =
begin
if .CCB [C_MOD] neq FM_NM
then $NM$ERR_MPE
else
begin
case .CCB [C_NM_ENTITY] from NMX$ENT_lo to NMX$ENT_hi of
set
[NMX$ENT_nod]: ! NM fnc for node parameter
begin
case .CCB [C_NM_FUNC] from NMX$FNC_lo to NMX$FNC_hi of
set ! *** NODE ***
[NMX$FNC_set]:
SET_NODE_PARMS (.CCB); ! Set parameters
[NMX$FNC_clr]:
CLEAR_NODE_PARMS (.CCB); ! Clear parameters
[NMX$FNC_sho]:
SHOW_NODE_ITEMS (.CCB); ! Show selected items
[NMX$FNC_ret]:
RETURN_NODE_LIST (.CCB); ! Return selected items
[inrange, outrange]:
$NM$ERR_MPE;
tes
end;
[NMX$ENT_ckt]: ! NM function for circuit parameter
begin
case .CCB [C_NM_FUNC] from NMX$FNC_lo to NMX$FNC_hi of
set ! *** CIRCUIT ***
[NMX$FNC_sho]:
SHOW_CIRCUIT_ITEMS (.CCB); ! Show selected items
[inrange, outrange]:
$NM$ERR_MPE;
tes
end;
[inrange, outrange]:
$NM$ERR_MPE;
tes
end
end;
if .STATUS neq 0 then $SC_DO_CCP (.CCB, .STATUS)
end;
global routine NM_NOD (NODE_ID_PTR): call$ novalue =
!++
! FUNCTIONAL DESCRIPTION:
! Map from node address to node name, or vice versa.
!
! FORMAL PARAMETERS:
! NODE_ID_PTR
! Node ID block pointer. The block is to
! contain space for:
! Node address (2 bytes)
! Node name (I-6)
! specifying either one of the parameters.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! The missing field in the node ID block will be filled in.
! If the node is unknown, a -1 node address is returned.
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
$sc_get_data_base (SCDB);
local
SAVE_MAP,
PTR,
NMT: ref block field (NMT_FIELDS);
SMAP$ (SAVE_MAP);
PTR = .NODE_ID_PTR;
if (NMT = GET_NODE (.PTR)) neqa 0
then
begin
local
NAML;
byt$short_string (NMT [NMT_ADDR], PTR);
NAML = .NMT [NMT_NAML];
ch$wchar_a (.NAML, PTR);
ch$move (.NAML, byt$ptr (NMT [NMT_NAME]), .PTR);
end
else
begin
ch$wchar_a (-1, PTR);
ch$wchar_a (-1, PTR);
end;
MAP$ (.SAVE_MAP)
end;
global routine NM_SIG (SIG_TYPE, PRM1, PRM2): call$ novalue =
!++
! FUNCTIONAL DESCRIPTION:
! This routine is activated by call from another SC routine
! to effect event logging - via Network Management (NMX).
!
! FORMAL PARAMETERS:
! SIG_TYPE Signal type identifier
! PRM1 Type-dependent parameter #1
! PRM2 Type-dependent parameter #2
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! NMX is signaled concerning the event
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
$sc_get_data_base (SCDB);
selectone .SIG_TYPE of
set
[0]: ! Node state change
! PRM1 = Reason for state change
! PRM2 = Old state
begin
local NEW_STATE;
$NM_LOG_BEGIN ();
PARAMETER_C_1 (0, PRM1); ! Reason
PARAMETER_C_1 (1, PRM2); ! Old-State
NEW_STATE = .SCDB [SCF_STAT];
PARAMETER_C_1 (2, NEW_STATE); ! New-State
$NM_LOG_END ((2^6 + 0), 0);
end;
[otherwise]:
return;
tes;
end;
routine CLEAR_NODE_PARMS (CCB) : SC_LKG_CCB =
!++
! FUNCTIONAL DESCRIPTION:
! Perform clearing of specified node parameter.
!
! FORMAL PARAMETERS:
! CCB CCB address
!
! IMPLICIT INPUTS:
! PARBLK & NMPAR inputs, as pointed at by CCB.
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! Operation status code
!
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
$sc_get_data_base (SCDB);
map CCB: ref block field (C_NM_FIELDS);
bind
NMPAR = CCB [C_NM_NMPAR]: ref block field (NMX_NMPAR_FIELDS);
local
NMT : ref block field (NMT_FIELDS);
if (NMT = GET_NODE (byt$ptr (NMPAR [NMX_NMPAR_ENTITY]))) eqla 0
then return $NM$ERR_URC;
if .CCB [C_CNT] neq 0
then
begin
selectone
begin
local SAVE_MAP,BUF_PTR;
stacklocal PARM_NUM;
SMAP$(SAVE_MAP);
MAP$ (.CCB [C_BIAS]);
BUF_PTR = .CCB [C_ADDR];
byt$string_short (BUF_PTR, PARM_NUM);
MAP$(.SAVE_MAP);
.PARM_NUM
end
of
set
[500]:
CLEAR_NODE_NAME (SCDB [SC_TICK], NMT [NMT_BASE], .CCB);
[501]:
CLEAR_NODE_CIRCUIT (SCDB [SC_TICK], NMT [NMT_BASE], .CCB);
[510]:
CLEAR_EXECUTOR_INCOMING_TIMER (SCDB [SC_TICK], NMT [NMT_BASE], .CCB);
[511]:
CLEAR_EXECUTOR_OUTGOING_TIMER (SCDB [SC_TICK], NMT [NMT_BASE], .CCB);
[otherwise]:
$NM$ERR_UPT;
tes
end
else
begin
CLEAR_NODE_NAME (SCDB [SC_TICK], NMT [NMT_BASE], .CCB);
CLEAR_NODE_CIRCUIT (SCDB [SC_TICK], NMT [NMT_BASE], .CCB);
CLEAR_EXECUTOR_INCOMING_TIMER (SCDB [SC_TICK], NMT [NMT_BASE], .CCB);
CLEAR_EXECUTOR_OUTGOING_TIMER (SCDB [SC_TICK], NMT [NMT_BASE], .CCB);
NM$SUC
end
end;
routine CLEAR_EXECUTOR_INCOMING_TIMER (SCDB, NMT, CCB) : SC_LKG_SCDB_NMT_CCB =
!++
! FUNCTIONAL DESCRIPTION:
! Clear the incoming timer
!
! FORMAL PARAMETERS:
! SCDB SC data base
! NMT NMT address
! CCB CCB address (not needed)
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! Operation status code
!
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
$sc_get_data_base (SCDB);
map CCB: ref block field (C_NM_FIELDS),
NMT: ref block field (NMT_FIELDS);
if .NMT [NMT_ADDR] neq .SCDB [SC_LADDR] then return $NM$ERR_PNA;
SCDB [SC_ITIME] = 0;
return NM$SUC
end;
routine CLEAR_EXECUTOR_OUTGOING_TIMER (SCDB, NMT, CCB) : SC_LKG_SCDB_NMT_CCB =
!++
! FUNCTIONAL DESCRIPTION:
! Clear the outgoing timer
!
! FORMAL PARAMETERS:
! SCDB SC data base
! NMT NMT address
! CCB CCB address (not needed)
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! Operation status code
!
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
$sc_get_data_base (SCDB);
map CCB: ref block field (C_NM_FIELDS),
NMT: ref block field (NMT_FIELDS);
if .NMT [NMT_ADDR] neq .SCDB [SC_LADDR] then return $NM$ERR_PNA;
SCDB [SC_OTIME] = 0;
return NM$SUC
end;
routine CLEAR_NODE_CIRCUIT (SCDB, NMT, CCB) : SC_LKG_SCDB_NMT_CCB =
!++
! FUNCTIONAL DESCRIPTION:
! Clear a loop node
!
! FORMAL PARAMETERS:
! SCDB SC data base
! NMT NMT address
! CCB CCB address (not needed)
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! Operation status code
!
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
$sc_get_data_base (SCDB);
map CCB: ref block field (C_NM_FIELDS),
NMT: ref block field (NMT_FIELDS);
if .NMT [NMT_ADDR] neq 0 then return $NM$ERR_CWS;
NMT [NMT_NAML] = 0;
return NM$SUC
end;
routine CLEAR_NODE_NAME (SCDB, NMT, CCB) : SC_LKG_SCDB_NMT_CCB =
!++
! FUNCTIONAL DESCRIPTION:
! Clear a node name mapping
!
! FORMAL PARAMETERS:
! SCDB SC data base
! NMT NMT address
! CCB CCB address (not needed)
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! Operation status code
!
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
$sc_get_data_base (SCDB);
map CCB: ref block field (C_NM_FIELDS),
NMT: ref block field (NMT_FIELDS);
NMT [NMT_NAML] = 0; ! No name anymore
return NM$SUC
end;
routine SET_NODE_PARMS (CCB) : SC_LKG_CCB =
!++
! FUNCTIONAL DESCRIPTION:
! Perform setting of specified node parameter.
!
! FORMAL PARAMETERS:
! CCB CCB address
!
! IMPLICIT INPUTS:
! PARBLK & NMPAR inputs, as pointed at by CCB.
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! Operation status code
!
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
$sc_get_data_base (SCDB);
map CCB: ref block field (C_NM_FIELDS);
bind
NMPAR = CCB [C_NM_NMPAR]: ref block field (NMX_NMPAR_FIELDS);
local
BUF_PTR,
PARM_NUM;
if .CCB [C_CNT] eql 0
then
return $NM$ERR_OPF;
BUF_PTR = .CCB [C_ADDR];
MAP$ (.CCB [C_BIAS]);
byt$string_short (BUF_PTR, PARM_NUM);
selectone .PARM_NUM of
set
[0]: ! Set node state
begin
local
STATE,
LCCB: ref block field (C_FIELDS);
STATE = ch$rchar_a (BUF_PTR);
selectone .STATE of
set
[S_ST_ON] :
0;
[S_ST_OFF, S_ST_SHUT, S_ST_RST] :
return $NM$ERR_OPF;
[otherwise] :
return $NM$ERR_IPV;
tes;
if .SCDB [SCF_STAT] eql S_ST_ON then return NM$SUC;
if not PDVID$ (RAD50 ('NMX'), SCDB [SC_NMPIX]) then SIGNAL_STOP (SC$_NNM);
if not PDVID$ (RAD50 ('NSP'), SCDB [SC_NSPIX]) then SIGNAL_STOP (SC$_NNS);
SCDB [SC_LLINK] = 0;
if not CCBGT$ (LCCB) then return $NM$ERR_REE;
LCCB [C_STK] = .CCB;
LCCB [C_PIX] = .SCDB [SC_NSPIX];
LCCB [C_FNC] = FC_XME; ! Initialize
LCCB [C_MOD] = N_XINI; ! NSP
$MCB_SCHEDULE_CCB (.LCCB);
return 0 ! Special hack so no ccb completion
end;
[141]: ! Define Host Node Address
begin
local
HOST_ADDR;
BUF_PTR = byt$ptr (NMPAR [NMX_NMPAR_NODE_ADDRESS]);
byt$string_short (BUF_PTR, HOST_ADDR);
SCDB [SC_HADDR] = .HOST_ADDR
end;
[500]: ! Set a node name
begin
local
NEW_NAME : vector [byt$allocation(6)],
NEW_NAML,
NMT : ref block field (NMT_FIELDS);
byt$string_tiny (BUF_PTR, NEW_NAML);
selectone .NEW_NAML of
set
[1 to 6]:
; ! Valid range
[otherwise]:
return $NM$ERR_IPV;
tes;
ch$move (.NEW_NAML, .BUF_PTR, byt$ptr (NEW_NAME));
if (NMT = GET_NODE (byt$ptr (NMPAR [NMX_NMPAR_ENTITY]))) eqla 0
then return $NM$ERR_URC;
if .NMT [NMT_ADDR] eql 0 then return $NM$ERR_CWS;
NMT [NMT_NAML] = .NEW_NAML;
ch$move (.NEW_NAML, byt$ptr (NEW_NAME), byt$ptr (NMT [NMT_NAME]))
end;
[501]: ! Set circuit for node name
begin
local
CHAN,
NMXID,
NMT: ref block field (NMT_FIELDS);
if GET_NODE (byt$ptr (NMPAR [NMX_NMPAR_ENTITY])) neqa 0
then return $NM$ERR_CWS;
MAP$ (.CCB [C_BIAS]);
NMX$OBTAIN_CIRCUIT_OWNER (.SCDB [SC_NMPIX], .buf_ptr, CHAN, NMXID);
MAP$ (.SCDB [SC_NMT_BIAS]);
NMT = blockvector [.SCDB [SC_NMT_ADDR], .SCDB [SC_NODES], NMT_BASE; 0, NMT_SIZE];
decru I from .SCDB [SC_LOOPS] to 1 do
begin
if .NMT [NMT_NAML] eql 0 ! Find available slot
then
begin
local PTR;
PTR = byt$ptr (NMPAR [NMX_NMPAR_NODE_NAME_LENGTH]);
NMT [NMT_NAML] = ch$rchar_a (PTR);
ch$move (.NMT [NMT_NAML], .PTR, byt$ptr (NMT [NMT_NAME]));
NMT [NMT_CHAN] = .CHAN;
NMT [NMT_NMXID] = .NMXID;
return NM$SUC
end;
NMT = vector [.NMT, NMT_SIZE];
end;
return $NM$ERR_NRE
end;
[510]: ! Set incoming connect timer
begin
local VALUE;
byt$string_short (BUF_PTR, VALUE);
selectoneu .VALUE of
set
[1 to 65535]:
SCDB [SC_ITIME] = .VALUE;
[otherwise]:
return $NM$ERR_IPV;
tes;
end;
[511]: ! Set outgoing connect timer
begin
local VALUE;
byt$string_short (BUF_PTR, VALUE);
selectoneu .VALUE of
set
[1 to 65535]:
SCDB [SC_OTIME] = .VALUE;
[otherwise]:
return $NM$ERR_IPV;
tes;
end;
[otherwise]:
return $NM$ERR_UPT;
tes;
return NM$SUC
end;
routine SHOW_NODE_ITEMS (CCB) : SC_LKG_CCB =
!++
! FUNCTIONAL DESCRIPTION:
! Show specified items
!
! FORMAL PARAMETERS:
! CCB CCB address
!
! IMPLICIT INPUTS:
! PARBLK & NMPAR inputs, as pointed at by CCB.
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! Operation status code
!
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
$sc_get_data_base (SCDB);
map CCB: ref block field (C_NM_FIELDS);
local
NMT : ref block field (NMT_FIELDS);
bind
NMPAR = CCB [C_NM_NMPAR]: ref block field (NMX_NMPAR_FIELDS);
$NM_RESPONSE_BEGIN( .CCB);
if (NMT = GET_NODE (byt$ptr (NMPAR [NMX_NMPAR_ENTITY]))) neqa 0
then
selectone .CCB [C_NM_SELECT] of
set
[NMX$SEL_sum, NMX$SEL_sta]:
begin
local NEW_STATE;
if .NMT [NMT_ADDR] eql .SCDB [SC_LADDR]
then
begin
NEW_STATE = .SCDB[SCF_STAT];
PARAMETER_C_1 (0, NEW_STATE);
end;
if .NMT [NMT_ADDR] eql 0
then
NMX$PARAMETER_CIRCUIT (.SCDB[SC_NMPIX], .NMT [NMT_NMXID], 501);
end;
[NMX$SEL_cha]:
begin
if .NMT [NMT_ADDR] eql 0
then
NMX$PARAMETER_CIRCUIT (.SCDB[SC_NMPIX], .NMT [NMT_NMXID], 501);
if .NMT [NMT_ADDR] eql .SCDB [SC_LADDR]
then
begin
if .SCDB [SC_ITIME] neq 0
then PARAMETER_DU_2 (510, SCDB [SC_ITIME]);
if .SCDB [SC_OTIME] neq 0
then PARAMETER_DU_2 (511, SCDB [SC_OTIME]);
end;
end;
tes;
$NM_RESPONSE_END( .CCB);
return .CCB[C_STS]
end;
routine RETURN_NODE_LIST (CCB) : SC_LKG_CCB =
!++
! FUNCTIONAL DESCRIPTION:
! Return list of named nodes.
!
! FORMAL PARAMETERS:
! CCB CCB address
!
! IMPLICIT INPUTS:
! PARBLK & NMPAR inputs, as pointed at by CCB.
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! Operation status code
!
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
$sc_get_data_base (SCDB);
map CCB: ref block field (C_NM_FIELDS);
bind NMPAR = .CCB [C_NM_NMPAR] : block field (NMX_NMPAR_FIELDS);
local
BUF_SIZ,
LEN,
PTR,
NMT: ref block [NMT_SIZE] field (NMT_FIELDS);
MAP$ (.SCDB [SC_NMT_BIAS]);
CCB [C_STS] = .CCB [C_CNT];
CCB [C_CNT] = .NMPAR [NMX_NMPAR_RETURN_CNT];
CCB [C_STS] = .CCB [C_STS] - .CCB [C_CNT];
select .CCB [C_NM_SELECT] of
set
[NMX$SEL_kno] :
begin
NMT = .SCDB [SC_NMT_ADDR];
decru I from .SCDB [SC_NODES] to 1 do
begin
local NAM_LEN;
if (NAM_LEN = .NMT [NMT_NAML]) neq 0
then INSERT_NODE (NMT [NMT_BASE], .CCB);
NMT = vector [.NMT, NMT_SIZE];
end;
end;
[NMX$SEL_kno, NMX$SEL_lop] :
begin
NMT = blockvector [.SCDB [SC_NMT_ADDR], .SCDB [SC_NODES], 0, 0, 0, 0; 0, NMT_SIZE];
decru I from .SCDB [SC_LOOPS] to 1 do
begin
local NAM_LEN;
if (NAM_LEN = .NMT [NMT_NAML]) neq 0
then INSERT_NODE (NMT [NMT_BASE], .CCB);
NMT = vector [.NMT, NMT_SIZE];
end;
end;
tes;
if .CCB [C_STS] geq 0
then
return NM$SUC
else
return $NM$ERR_REE
end;
routine SHOW_CIRCUIT_ITEMS (CCB) : SC_LKG_CCB =
!++
! FUNCTIONAL DESCRIPTION:
! Show selected circuit items.
!
! FORMAL PARAMETERS:
! CCB CCB address
!
! IMPLICIT INPUTS:
! PARBLK & NMPAR inputs, as pointed at by CCB.
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! Operation status code
!
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
$sc_get_data_base (SCDB);
map CCB: ref block field (C_NM_FIELDS);
bind
NMPAR = CCB [C_NM_NMPAR]: ref block field (NMX_NMPAR_FIELDS);
$NM_RESPONSE_BEGIN (.CCB);
case .CCB [C_NM_SELECT] from NMX$SEL_lo to NMX$SEL_hi of
set
[NMX$SEL_sta, NMX$SEL_sum] :
begin
local
CHAN,
NMXID,
NMT : ref block field (NMT_FIELDS);
NMX$OBTAIN_CIRCUIT_OWNER( .SCDB[SC_NMPIX], byt$ptr (NMPAR [NMX_NMPAR_OTHER_LENGTH]), CHAN, NMXID);
MAP$ (.SCDB [SC_NMT_BIAS]);
NMT = blockvector [.SCDB [SC_NMT_ADDR], .SCDB [SC_NODES], NMT_BASE; 0, NMT_SIZE];
decru I from .SCDB [SC_LOOPS] to 1 do
begin
if (.NMT [NMT_NAML] neq 0) and
(.NMT [NMT_CHAN] eqlu .CHAN<0, 8>)
then
begin
PARAMETER_AI (400, .NMT [NMT_NAML], byt$ptr (NMT [NMT_NAME]));
exitloop;
end;
NMT = vector [.NMT, NMT_SIZE];
end;
end;
[inrange] :
0;
tes;
$NM_RESPONSE_END (.CCB);
return .CCB [C_STS]
end;
routine CASE_SHIFT (LEN, PTR) : SC_LKG_LEN_PTR novalue =
!++
! FUNCTIONAL DESCRIPTION:
! Shift string pointed to by PTR to uppercase
!
! FORMAL PARAMETERS:
! LEN Length of string
! PTR Pointer to string to shift
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
local
CH,
TMP_PTR;
TMP_PTR = .PTR;
if .LEN neq 0
then
decru I from .LEN to 1 do
begin
if (CH = ch$rchar (.TMP_PTR)) geq %c'a' and .CH leq %c'z'
then CH = .CH - (%c'a' - %c'A');
ch$wchar_a (.CH, TMP_PTR);
end;
end;
routine GET_NODE (PARBLK) : SC_LKG_PTR =
!++
! FUNCTIONAL DESCRIPTION:
! Determine whether name is in NMT
!
! FORMAL PARAMETERS:
! PARBLK Pointer to NM parameter block specifying node,
! starting at NMX_NMPAR_ENTITY
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! Mapped to NMT
!
! ROUTINE VALUE:
!
! NMT address if name found, else 0
!
! SIDE EFFECTS:
! None
!--
begin
$sc_get_data_base (SCDB);
local
PARPTR,
NODE_ADDR,
NAME_LEN,
NMT : ref block field (NMT_FIELDS);
MAP$ (.SCDB [SC_NMT_BIAS]); ! Set map to node mapping table
NMT = .SCDB [SC_NMT_ADDR];
PARPTR = .PARBLK;
byt$string_short (PARPTR, NODE_ADDR); ! Get the node address
byt$string_tiny (PARPTR, NAME_LEN); ! and name length
selectone .NAME_LEN of ! If a name is specified,
set
[1 to 6]:
begin ! then search for the entry
CASE_SHIFT (.NAME_LEN, .PARPTR);
decru I from (.SCDB [SC_NODES] + .SCDB [SC_LOOPS]) to 1 do
begin
if (.NMT [NMT_NAML] neq 0) and
ch$eql (.NAME_LEN, .PARPTR,
.NMT [NMT_NAML], byt$ptr (NMT [NMT_NAME]),
0)
then return NMT [NMT_BASE];
NMT = vector [.NMT, NMT_SIZE];
end
end;
[0]: ! Node spec via address
begin
if .NODE_ADDR eql 0 then NODE_ADDR = .SCDB [SC_LADDR]; ! Default to local
if .NODE_ADDR lequ .SCDB [SC_NODES]
then
begin
NODE_ADDR = .NODE_ADDR - 1;
NMT = blockvector [NMT [NMT_BASE], .NODE_ADDR, NMT_BASE; 0, NMT_SIZE];
return NMT [NMT_BASE];
end;
end;
[otherwise]:
;
tes;
return 0
end;
routine INSERT_NODE (NMT, CCB) : SC_LKG_NMT_CCB novalue =
!++
! FUNCTIONAL DESCRIPTION:
! Make room for LNG bytes at PTR in the CCB buffer.
!
! FORMAL PARAMETERS:
! NMT NMT for node
! CCB CCB address
!
! IMPLICIT INPUTS:
! Mapped to CCB buffer
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_NM_FIELDS),
NMT : ref block field (NMT_FIELDS);
label
FIND_NODE;
local
ADDR,
LEN,
NODE_ID : vector [byt$allocation (9)];
ADDR = .NMT [NMT_ADDR];
LEN = .NMT [NMT_NAML];
begin
local
PTR;
PTR = byt$ptr (NODE_ID);
byt$short_string (NMT [NMT_ADDR], PTR);
byt$tiny_string (LEN, PTR);
ch$move (.LEN, byt$ptr (NMT [NMT_NAME]), .PTR);
end;
LEN = .LEN + 3;
if .ADDR eql 0 then ADDR = .ADDR - 1;
FIND_NODE:
begin ! FIND_NODE
local
CNT,
PTR,
SAVE_MAP;
SMAP$ (SAVE_MAP);
MAP$ (.CCB [C_BIAS]);
PTR = .CCB [C_ADDR];
CNT = .CCB [C_CNT];
if .CNT neq 0
then
while true do
begin
local TCNT, TEST, TPTR;
TPTR = .PTR;
byt$string_short (TPTR, TEST);
if .TEST gtru .ADDR then exitloop CNT = 0;
TCNT = 3 + ch$rchar_a (TPTR);
if .TEST eqlu .ADDR then exitloop CNT = .TCNT;
PTR = ch$plus (.PTR, .TCNT);
if (CNT = .CNT - .TCNT) leq 0 then exitloop CNT = 0;
end;
begin
local
DIFFERENCE;
DIFFERENCE = .LEN - .CNT;
if (CCB [C_STS] = .CCB [C_STS] - .DIFFERENCE) lss 0
then
leave FIND_NODE;
MAKE_ROOM (.CCB, .PTR, .DIFFERENCE);
end;
ch$move (.LEN, byt$ptr (NODE_ID), .PTR);
MAP$ (.SAVE_MAP);
end; ! FIND_NODE
end;
routine MAKE_ROOM (CCB, PTR, LNG) : SC_LKG_CCB_PTR_LNG novalue =
!++
! FUNCTIONAL DESCRIPTION:
! Make room for LNG bytes at PTR in the CCB buffer.
!
! FORMAL PARAMETERS:
! CCB CCB address
! PTR Pointer within CCB buffer
! LNG Number of bytes needed
!
! IMPLICIT INPUTS:
! Mapped to CCB buffer
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! None
!
! SIDE EFFECTS:
! None
!--
begin
map CCB: ref block field (C_NM_FIELDS);
macro
ch$r_rchar (PTR) =
begin
PTR = .PTR - 1;
ch$rchar (.PTR)
end %,
ch$r_wchar (BYT, PTR) =
begin
PTR = .PTR - 1;
ch$wchar (BYT, .PTR);
end %;
local
CNT,
TOP_FROM,
TOP_TO;
TOP_FROM = .CCB [C_ADDR];
TOP_FROM = ch$plus (.TOP_FROM, .CCB [C_CNT]);
CCB [C_CNT] = .CCB [C_CNT] + .LNG;
CNT = .TOP_FROM;
CNT = ch$diff (.CNT, .PTR);
if .CNT eql 0 then return;
TOP_TO = .TOP_FROM;
TOP_TO = ch$plus (.TOP_TO, .LNG);
do ch$r_wchar (ch$r_rchar (TOP_FROM), TOP_TO) while (CNT = .CNT - 1) neq 0;
end;
end
eludom