*DECK FFSUCIA 
USETEXT TEXTFFS 
      PROC FFSUCIA ((ADDR$CHAR), ADDR$NUM); 
*CALL COPYRITE
# TITLE FFSUCIA - CONVERT ADDRESS FROM CHARACTER TO NUMERIC FORM.     # 
  
      BEGIN                          # FFSUCIA                        # 
  
# 
**    FFSUCIA - CONVERT IPA ADDRESS FROM CHARACTER TO NUMERIC FORM. 
* 
*     'FFSUCIA' CONVERTS AN INTERNET ADDRESS FROM CHARACTER TO NUMERIC
*     FORM.  VERIFIES THAT A BROADCAST ADDRESS HAS NOT BEEN SPECIFIED.
* 
*     ENTRY (ADDR$CHAR) = ADDRESS IN CHARACTER FORM, AS IN A HOST NAME
*                         TABLE ENTRY.
* 
*     EXIT  (ADDR$NUM)  = ADDRESS IN NUMERIC FORM, AS DEFINED BY THE
*                         RECORD 'I$DADR$REC'.  VALUE OF ZERO FOR HOST
*                         OR NETWORK PART OF ADDRESS INDICATES AN 
*                         INVALID VALUE WAS SPECIFIED.
* 
*     DESCRIPTION.
* 
*     INITIALIZE THE OCTET CHARACTER ARRAY TO BLANKS. 
*     EXTRACT THE 4 OCTETS, AND PLACE THEM INTO THE OCTET CHARACTER 
*       ARRAY.
*     CONVERT EACH OCTET FROM CHARACTER TO NUMBER, PLACING THE NUMBERS
*       INTO THE OCTET NUMBER ARRAY.
*     POINT THE I$DADR$REC BASED ARRAY TO THE ADDR$NUM PARAMETER. 
*     SET THE FIELDS-IN-USE FIELD TO BOTH.
*     IF THE FIRST BIT OF THE FIRST OCTET = 0 
*     THEN (CLASS A ADDRESS)
*       PLACE THE FIRST OCTET INTO THE NETWORK FIELD. 
*       PLACE THE SECOND, THIRD, AND FOURTH OCTETS INTO THE HOST FIELD. 
*       RETURN. 
*     IF THE FIRST 2 BITS OF THE FIRST OCTET = 2
*     THEN (CLASS B ADDRESS)
*       PLACE THE FIRST AND SECOND OCTETS INTO THE NETWORK FIELD. 
*       PLACE THE THIRD AND FOURTH OCTETS INTO THE HOST FIELD.
*       RETURN. 
*     IF THE FIRST 2 BITS OF THE FIRST OCTET = 3
*     THEN (CLASS C ADDRESS)
*       PLACE THE FIRST, SECOND, AND THIRD OCTETS INTO THE NETWORK
*         FIELD.
*       PLACE THE FOURTH OCTET INTO THE HOST FIELD. 
*       RETURN. 
# 
  
      ITEM  ADDR$CHAR C(20);  # ADDRESS IN CHARACTER FORM, AS IN A HOST 
                                NAME TABLE ENTRY.                     # 
      ARRAY ADDR$NUM  [0:0] S(I$DADR$SZ);;  # ADDRESS IN NUMERIC FORM,
                                              AS DEFINED BY THE RECORD
                                              'I$DADR$REC'.           # 
  
      XREF
        BEGIN 
        FUNC FFSULOC I;  # LOCATE CHARACTER                           # 
        PROC XDXB;       # SRVLIB CONVERT DISPLAY CODE TO BINARY      # 
        END 
  
      ARRAY OCTET [1:4] S(2);         # OCTET ARRAY                   # 
        BEGIN 
        ITEM OCTET$WORD C(00,00,10);  # OCTET FULL WORD CHARACTERS    # 
        ITEM OCTET$CHAR C(00,00,03);  # OCTET IN CHARACTER FORM       # 
        ITEM OCTET$NUM  U(01,00,08);  # OCTET IN NUMERIC FORM         # 
        END 
  
      DEF BLANKWORD   #"          "#; # WORD FULL OF BLANKS           # 
  
  
      ITEM  FIRST$POS  I;  # FIRST POSITION OF OCTET                  # 
      ITEM  FROM$POS   I;  # POSITION FROM WHICH TO START COPYING     # 
      ITEM  INDEX      I;  # LOOP INDEX                               # 
      ITEM  LAST$POS   I;  # LAST POSITION OF OCTET                   # 
      ITEM  LOOP       I;  # LOOP INDEX                               # 
      ITEM  NUM$CHARS  I;  # NUMBER OF CHARACTERS TO COPY             # 
      ITEM  OCTET$NUMB U;  # TEMPORARY OCTET IN NUMERIC FORM          # 
      ITEM  TO$POS     I;  # POSITION TO WHICH TO START COPYING       # 
                                              CONTROL EJECT;
# 
*     INITIALIZE THE OCTET CHARACTER ARRAY TO BLANKS. 
# 
  
      CONTROL FASTLOOP; 
      FOR INDEX = 1 STEP 1 UNTIL 4
      DO
        BEGIN 
        OCTET$WORD [INDEX] = BLANKWORD; 
        END 
  
# 
*     EXTRACT THE 4 OCTETS, AND PLACE THEM INTO THE OCTET CHARACTER 
*       ARRAY.
# 
  
# 
*     FIRST, SECOND, AND THIRD OCTETS : EACH ENDS WITH A PERIOD, SO 
*       COPY ALL CHARS UP TO THE NEXT PERIOD. 
# 
  
      LAST$POS = -1;  # INIT SO THAT FIRST$POS WILL BE 0 FIRST TIME # 
      IF C<0,1> ADDR$CHAR EQ "0"
      THEN                    # IF THE FIRST CHAR IS 0, SKIP IT. SET #
        BEGIN                 # LAST$POS TO 0, SO THAT FIRST$POS WILL#
        LAST$POS = 0;         # BE 1, INSTEAD OF 0, THE FIRST TIME.  #
        END 
      CONTROL FASTLOOP; 
      FOR INDEX = 1 STEP 1 UNTIL 3
      DO
        BEGIN 
        FIRST$POS = LAST$POS + 1; 
        LAST$POS = FFSULOC (ADDR$CHAR, ".", FIRST$POS, STR$DIS);
        NUM$CHARS = LAST$POS - FIRST$POS; 
        OCTET$CHAR [INDEX] = C<FIRST$POS, NUM$CHARS> ADDR$CHAR; 
        END 
  
# 
*     FOURTH OCTET : DOES NOT END WITH A PERIOD, SO COPY CHAR-BY-CHAR 
*       UNTIL A NON-DIGIT IS ENCOUNTERED. 
# 
  
      FROM$POS = LAST$POS + 1;
      TO$POS = 0; 
      CONTROL SLOWLOOP; 
      FOR LOOP=LOOP 
        WHILE (C<FROM$POS, 1> ADDR$CHAR GQ "0") AND 
              (C<FROM$POS, 1> ADDR$CHAR LQ "9") 
      DO
        BEGIN 
        C<TO$POS, 1> OCTET$CHAR [4] = C<FROM$POS, 1> ADDR$CHAR; 
        FROM$POS = FROM$POS + 1;
        TO$POS = TO$POS + 1;
        END 
  
# 
*     CONVERT EACH OCTET FROM CHARACTER TO NUMBER, PLACING THE NUMBERS
*       INTO THE OCTET NUMBER ARRAY.
# 
  
      CONTROL FASTLOOP; 
      FOR INDEX = 1 STEP 1 UNTIL 4
      DO
        BEGIN 
        XDXB (OCTET$CHAR [INDEX], 1, OCTET$NUMB); 
        OCTET$NUM [INDEX] = OCTET$NUMB; 
        END 
  
# 
*     POINT THE I$DADR$REC BASED ARRAY TO THE ADDR$NUM PARAMETER. 
*     SET THE FIELDS-IN-USE FIELD TO BOTH.
# 
  
      P<I$DADR$REC> = LOC (ADDR$NUM); 
      I$DADR$FIU = IP$FIUSTAT"BOTH";
  
# 
*     IF THE FIRST BIT OF THE FIRST OCTET = 0 
*     THEN (CLASS A ADDRESS)
*       PLACE THE FIRST OCTET INTO THE NETWORK FIELD. 
*       PLACE THE SECOND, THIRD, AND FOURTH OCTETS INTO THE HOST FIELD. 
*       RETURN. 
# 
  
      IF B<0, 1> OCTET$NUM [1] EQ 0 
      THEN
        BEGIN 
        I$DADR$NET = OCTET$NUM [1]; 
        IF I$DADR$NET EQ X"FF"
        THEN
          BEGIN 
            I$DADR$NET = 0; 
          END 
        B<0, 8> I$DADR$HST = OCTET$NUM [2]; 
        B<8, 8> I$DADR$HST = OCTET$NUM [3]; 
        B<16, 8> I$DADR$HST = OCTET$NUM [4];
        IF I$DADR$HST EQ X"FFFFFF"
        THEN
          BEGIN 
            I$DADR$HST = 0; 
          END 
        GOTO CVTADREND; 
        END  # CLASS A #
  
# 
*     IF THE FIRST 2 BITS OF THE FIRST OCTET = 2
*     THEN (CLASS B ADDRESS)
*       PLACE THE FIRST AND SECOND OCTETS INTO THE NETWORK FIELD. 
*       PLACE THE THIRD AND FOURTH OCTETS INTO THE HOST FIELD.
*       RETURN. 
# 
  
      IF B<0, 2> OCTET$NUM [1] EQ 2 
      THEN
        BEGIN 
        B<8, 8> I$DADR$NET = OCTET$NUM [1]; 
        B<16, 8> I$DADR$NET = OCTET$NUM [2];
        IF I$DADR$NET EQ X"FFFF"
        THEN
          BEGIN 
            I$DADR$NET = 0; 
          END 
        B<8, 8> I$DADR$HST = OCTET$NUM [3]; 
        B<16, 8> I$DADR$HST = OCTET$NUM [4];
        IF I$DADR$HST EQ X"FFFF"
        THEN
          BEGIN 
            I$DADR$HST = 0; 
          END 
        GOTO CVTADREND; 
        END  # CLASS B #
  
# 
*     IF THE FIRST 2 BITS OF THE FIRST OCTET = 3
*     THEN (CLASS C ADDRESS)
*       PLACE THE FIRST, SECOND, AND THIRD OCTETS INTO THE NETWORK
*         FIELD.
*       PLACE THE FOURTH OCTET INTO THE HOST FIELD. 
*       RETURN. 
# 
  
      IF B<0, 2> OCTET$NUM [1] EQ 3 
      THEN
        BEGIN 
        B<0, 8> I$DADR$NET = OCTET$NUM [1]; 
        B<8, 8> I$DADR$NET = OCTET$NUM [2]; 
        B<16, 8> I$DADR$NET = OCTET$NUM [3];
        IF I$DADR$NET EQ X"FFFFFF"
        THEN
          BEGIN 
            I$DADR$NET = 0; 
          END 
        I$DADR$HST = OCTET$NUM [4]; 
        IF I$DADR$HST EQ X"FF"
        THEN
          BEGIN 
            I$DADR$HST = 0; 
          END 
        GOTO CVTADREND; 
        END  # CLASS C #
  
CVTADREND:  
      RETURN;                        # COMMON RETURN                  # 
  
      END                            # FFSUCIA                        # 
  
      TERM
