*DECK SCANPTH 
USETEXT COMCBEG 
USETEXT COMRAPL 
USETEXT COMRNET 
USETEXT COMRQUE 
USETEXT COMRRTN 
PROC SCANPTH((REQUEST),RETURNCODE,ACTSEL);
# TITLE SCANPTH - SCAN FOR BEST PATH TO REQUESTED LID/PID # 
  
      BEGIN  # SCANPTH #
  
# 
**    SCANPTH - SCAN FOR BEST PATH TO REQUESTED LID-PID.
* 
*     THIS PROCEDURE WILL SCAN ALL AVAILABLE PATHS TO THE REQUESTED 
*     LID/PID AND CHOOSE THE BEST ONE. THE SELECTION IS BASED PRIMARILY 
*     ON FINDING THE PATH WITH THE LOWEST LOCAL AND REMOTE CONNECTION 
*     COUNTS.  IF THERE ARE SEVERAL PATHS WITH EQUALLY LOW COUNTS THEN
*     THE SELECTION IS BASED ON THE PATH ACTIVITY BIT.
* 
*     PROC SCANPTH(REQUEST,RETURNCODE,ACTSEL).
* 
*     EWNTRY  -  QU$ADDRESS IS BASED ARRAY CONTAINING CON/ACRQ/R. 
*                REQUEST - BEST$   -FIND BEST PATH. 
*                          BEST$REJ-FIND BEST REJECTED PATH.
* 
*     EXIT    -  RETURNCODE - SCAN$OK   - PATH FOUND. 
*                             SCAN$DIS  - ALL PATHS DISABLED. 
*                             SCAN$REJ  - ALL ENABLED PATHS REJECTED. 
*                             SCAN$NOID - LID OR PID NOT FOUND. 
*                IF PATH FOUND -
*                  ACTSEL   - TRUE IF PATH ACTIVITY USED AS SELECTION 
*                               CRITERIA. 
*                  NET$HEADER-BASED ARRAY CONTAINING BEST PATH PID. 
*                  PTH$ENTRY -BASED ARRAY FOR BEST PATH ENTRY.
*                  NAD$ENTRY -BASED ARRAY FOR BEST PATH NAD ENTRY.
*                  RMT$ENTRY -BASED ARRAY FOR BEST PATH REMOTE NAD. 
* 
*     PROCESS -  INITIALIZE VARIABLES 
*                FOR EACH MAINFRAME HEADER (PID): 
*                  SEARCH ASSOCIATED LIDS FOR MATCHING ENABLED LID
*                  IF LID FOUND MATCHING REQUEST
*                    AND THIS PID MATCHES REQUEST AND IS ENABLED
*                  THEN:  
*                    FOR EACH ENABLED PATH ENTRY: 
*                      IF PATH REJECT BIT NOT SET 
*                        OR REQUEST WAS FOR BEST REJECT 
*                      THEN:  
*                        COMPUTE WEIGHTED CONNECTION COUNT
*                        IF THIS WEIGHTED COUNT LT BEST COUNT 
*                          OR THIS IS FIRST AVAILABLE PATH
*                        THEN:  
*                          SAVE THIS COUNT AS BEST COUNT
*                        SAVE THIS PATH AS BEST PATH
*                        SAVE PATH ACTIVITY FLAG. 
*                        ELSE:  
*                          IF THIS WEIGHTED COUNT EQ BEST COUNT 
*                          THEN:  
*                            SET ACTSEL TRUE  "ACTIVITY USED IN 
*                                       SELECTING BEST PATH"
*                            IF THIS PATH ACTIVITY BIT DIFFERS FROM 
*                              SAVED ACTIVITY BIT 
*                            THEN:  
*                              SAVE THIS PATH AS BEST PATH....... 
*                IF PID NOT FOUND OR LID NOT FOUND
*                THEN:  
*                  RETURN CODE SCAN$NOID. 
*                ELSE:  
*                  IF PATH NOT FOUND
*                  THEN:  
*                    IF ALL PATHS HAD PATH REJECT SET 
*                    THEN:  
*                      RETURN CODE SCAN$REJ.
*                    ELSE:  "ALL PATHS DISABLED"
*                      RETURN CODE SCAN$DIS.. 
*                  ELSE:  "PATH FOUND"
*                    RETURN CODE SCAN$OD
*                    SET UP ALL APPROPRIATE BASED ARRAYS. 
*                RETURN.
* 
*     NOTES   -  MEANING AND USE OF PATH ACTIVITY FLAG: 
*                THE ACTIVITY FLAG IS SIMPLY USED TO HELP EVENLY
*                DISTRIBUTE PATH SELECTION AMONG PATHS HAVING THE 
*                SAME CONNECTION COUNTS.
* 
*                THE VALUE OF THE PATH ACTIVITY BIT IS COMPLEMENTED 
*                WHEN A NEW PATH IS ASSIGNED BUT ONLY IF THE ACTIVITY 
*                BIT WAS EXAMINED TO ASSIST IN PATH SELECTION.
* 
*                WHEN CHOOSING THE BEST PATH AMONG PATHS HAVING EQUAL 
*                CONNECTION COUNTS, THE FOLLOWING ALGORITHM IS USED:  
* 
*                   IF THE VALUES OF THE AVTIVITY BITS ARE EQUAL
*                   THEN: 
*                     CHOOSE THE FIRST PATH 
*                   ELSE: 
*                     CHOOSE THE FIRST SUCCESSIVE PATH TO HAVE A
*                       DIFFERENT ACTIVITY BIT VALUE THAN THE FIRST 
*                       PATH. 
* 
* 
# 
  
      ITEM REQUEST    I;             # REQUEST CODE # 
      ITEM RETURNCODE I;             # RETURN CODE #
      ITEM ACTSEL     B;             # IF TRUE, ACTIVITY BITS USED #
  
# 
*     PROC SCANPTH - XREF LIST BEGIN. 
# 
  
      XREF
        BEGIN 
        PROC FINDPIDS;               # FIND PIDS ASSOCIATED WITH LID  # 
        ITEM NADTBL  I;              # LOCAL NAD TABLE ADDRESS #
        ITEM NDTADDR  I;             # NETWORK DEFINITION TABLE ADDR #
        END 
  
# 
*     PROC SCANPTH - XREF LIST END. 
# 
  
  
      ITEM BESTCOUNT  I;             # LOWEST CONNECTION COUNT SO FAR # 
      ITEM BESTPATH   I;             # PATH ADDRESS OF BEST COUNT PATH# 
      ITEM BSTPTHACT  B;             # BEST PATH WITH THIS COUNT HAS  # 
                                     # ALREADY BEEN SELECTED          # 
    CONTROL IFEQ OS$NOS;
      ITEM FIRSTCALL  B;             #  FIRST CALL FLAG FOR FINDPIDS  # 
    CONTROL ENDIF;
      ITEM LIDFOUND B;               # FOUND LEGAL MATCHING LID # 
      ITEM PATHREJECT B;             # AN ENABLE PATH HAD REJECT SET #
      ITEM PIDENABLD  B;             # PID ENABLED FLAG  #
      ITEM PIDFOUND   B;             # FOUND LEGAL MATCHING PID # 
      ITEM PTHACTBIT  B;             # VALUE OF BESTCOUNT PATH ACTIVITY#
      ITEM THISCOUNT  I;             # CONNECTION COUNT OF CURRENT PATH#
      ITEM THISPIDOK  B;             # CURRENT PID MAY BE USED #
      ITEM PTHINDX    I;             # INDEX FOR PATH SEARCH #
      ITEM INDX       I;             # INDEX FOR LID SEARCH # 
  
      ARRAY [0:0] S(1); 
        BEGIN  # LID TABLE SEARCH INDEX # 
        ITEM LIDINDX    I(00,00,60); # LID SEARCH INDEX # 
        ITEM LIDINDXODD B(00,59,01); # LID ORDINAL ODD FLAG # 
        END 
  
CONTROL EJECT;
  
      BSTPTHACT = FALSE;
      ACTSEL    = FALSE;
      PIDFOUND  = FALSE;
      LIDFOUND  = FALSE;
      PATHREJECT= FALSE;
      BESTPATH  = 0;
      BESTCOUNT = 0;
  
      P<NET$HEADER> = NDTADDR;
  
    CONTROL IFEQ OS$NOS;
      PIDENABLD = FALSE;
      THISPIDOK = FALSE;
      FIRSTCALL = TRUE; 
      FINDPIDS(THISPIDOK,FIRSTCALL);
      FIRSTCALL = FALSE;
    CONTROL ENDIF;
  
      ASLONGAS P<NET$HEADER> NE 0 
      DO
        BEGIN  # LOOK AT NEXT PID HEADER #
  
        IF QU$PIDI EQ 0  OR QU$PID EQ NET$PID 
        THEN
          BEGIN  # MATCHING PID FOUND # 
          PIDFOUND = TRUE;
          THISPIDOK= FALSE; 
        CONTROL IFEQ OS$NOS;
          FINDPIDS(THISPIDOK,FIRSTCALL);
          IF THISPIDOK
          THEN
            BEGIN 
            PIDENABLD = TRUE; 
            LIDFOUND = TRUE;
            END 
        CONTROL ENDIF;
  
        CONTROL IFEQ OS$NOSBE;
          P<LID$ENTRY> = NET$LIDADR;
          SLOWFOR INDX  = 1 STEP 1 UNTIL NET$NUMLID 
          DO
            BEGIN  # SEARCH FOR ENABLED MATCHING LID #
            LIDINDX = INDX; 
  
            IF LIDINDXODD 
            THEN
              BEGIN  # 1ST OF TWO LIDS PER WORD # 
              IF QU$LIDI EQ 0 OR QU$LID EQ LID$1
              THEN
                BEGIN  # MATCHING LID # 
                LIDFOUND = TRUE;
  
                IF LID$ENAB1
                THEN
                  BEGIN  # LID ENABLED #
                  THISPIDOK = TRUE; 
                  EXIT LIDSRCH; 
                  END 
  
                END 
  
              END 
  
            ELSE
              BEGIN  # 2ND OF TWO LIDS PER WORD # 
              IF QU$LIDI EQ 0 OR QU$LID EQ LID$2
              THEN
                BEGIN  # MATCHING LID # 
                LIDFOUND = TRUE;
  
                IF LID$ENAB2
                THEN
                  BEGIN  # LID ENABLED #
                  THISPIDOK = TRUE; 
                  EXIT LIDSRCH; 
                  END 
  
                END 
  
              P<LID$ENTRY> = P<LID$ENTRY> + 1;
              END 
  
            END  LIDSRCH: 
          PIDENABLD = NET$ENABLE; 
        CONTROL ENDIF;
  
      IF THISPIDOK
        AND PIDENABLD 
          THEN
            BEGIN  # MATCHING PID AND LID # 
            P<PTH$ENTRY>= NET$PATHAD; 
  
            SLOWFOR PTHINDX = 1 STEP 1 UNTIL NET$NMPATH 
            DO
              BEGIN  # LOOK FOR AVAILABLE PATH #
            P<NAD$ENTRY> = NADTBL + PTH$NADORD * NAD$LENGTH;
  
              IF NOT NAD$ESTOFF AND PTH$ENABLE
                AND NOT NAD$PREVOF
              THEN
                BEGIN  # PATH IS ENABLED #
  
                IF PTH$REJ
                THEN
                  BEGIN  # LAST CONNECTION REQUEST REJECTED # 
                  PATHREJECT = TRUE;
                  END 
  
                IF NOT PTH$REJ OR REQUEST EQ BEST$REJ 
                THEN
                  BEGIN  # THIS PATH MAY BE USED #
                  P<RMT$ENTRY> = PTH$RMTNAD;
                  THISCOUNT = 3 * NAD$CCOUNT + RMT$CCOUNT;
  
                  IF BESTPATH EQ 0 OR BESTCOUNT GT THISCOUNT
                  THEN
                    BEGIN  # BEST PATH SO FAR # 
                    BESTPATH = P<PTH$ENTRY>;
                    BESTCOUNT= THISCOUNT; 
                    ACTSEL   = FALSE; 
                    BSTPTHACT= FALSE; 
                    PTHACTBIT= PTH$ACTIV; 
                    END 
  
                  ELSE
                    BEGIN  # CHECK FOR EQUAL COUNTS # 
                    IF BESTCOUNT EQ THISCOUNT AND NOT BSTPTHACT 
                    THEN
                      BEGIN  # EQUAL COUNTS - USE ACTIVITY BIT #
                      ACTSEL = TRUE;
  
                      IF PTHACTBIT AND NOT PTH$ACTIV
                        OR NOT PTHACTBIT AND PTH$ACTIV
                      THEN
                        BEGIN  # BEST PATH USING ACTIVITY SELECTION # 
                        BSTPTHACT = TRUE; 
                        BESTPATH  = P<PTH$ENTRY>; 
                        END 
  
                      END 
  
                    END  # CHECK FOR EQUAL COUNTS # 
  
                  END  # THIS PATH MAY BE USED #
  
                END  # PATH IS ENABLED #
  
              P<PTH$ENTRY> = P<PTH$ENTRY>+ PTH$LENGTH;
              END  # LOOK FOR AVAILABLE PATH #
  
            END  # MATCHING PID AND LID # 
  
          END  # MATCHING PID FOUND # 
  
        P<NET$HEADER> = NET$NXTPID; 
        END  # LOOK AT NEXT PID HEADER #
  
      IF NOT PIDFOUND OR NOT LIDFOUND 
      THEN
        BEGIN  # INVALID LID OR PID # 
        RETURNCODE = SCAN$NOID; 
        END 
  
      ELSE
        BEGIN  # LID AND PID FOUND #
        IF BESTPATH EQ 0
        THEN
          BEGIN  # NO PATH FOUND #
          IF PATHREJECT 
          THEN
            BEGIN  # ALL ENABLED PATHS HAD PATH REJECT SET #
            RETURNCODE = SCAN$REJ;
            END 
  
          ELSE
            BEGIN  # NO ENABLED PATHS # 
            RETURNCODE = SCAN$DIS;
            END 
  
          END 
  
        ELSE
          BEGIN  # PATH FOUND # 
          P<PTH$ENTRY>= BESTPATH; 
          P<NET$HEADER> = PTH$PIDADR; 
          P<NAD$ENTRY> = NADTBL + PTH$NADORD * NAD$LENGTH;
          P<RMT$ENTRY>  = PTH$RMTNAD; 
          RETURNCODE = SCAN$OK; 
          END 
  
        END 
  
      RETURN; 
      END  # SCANPTH #
  
      TERM
