RFC 119

Network Fortran Subprograms

πŸ“… published April 1971, from ietf

NETWORK FORTRAN SUBPROGRAMS πŸŽ€

Okay bestie, this is RFC 119 and it's a whole vintage moment 🌸 Here's the header tea β˜•

  • RFC number: 119
  • Title: NETWORK FORTRAN SUBPROGRAMS
  • Author: M. Krilanovich, UCSB
  • Working group: Network Working Group
  • NIC number: 5831
  • Date: April 21, 1971
  • Obsoletes / updates: the header doesn't list anything it obsoletes or updates, and it doesn't name a category either πŸ€·β€β™€οΈ

Preface ✨

Okay so these subroutines were built at UCSB and they hook the Network (through the NCP) up to Fortran programs running on the 360/75 πŸ’… You can call them from any Fortran main program or subroutine compiled at UCSB, iconic πŸ¦‹

There's also a set of assembly-language subprograms that make the Network easier for Fortran programmers to use. They sit between you and the Network Control Program (NCP), which runs all the Network operations at this site 🫢

The big concept here is the completion code variable πŸ”₯ Every socket that isn't closed gets its own unique completion code variable. It does two jobs: it tells you which local socket you're talking about, and once an operation finishes, it holds a completion code that says how things went. You're free to use it for anything else when you're not doing network stuff. Its starting value doesn't matter, because the variable itself is the important part πŸ’–

For every Network operation that asks for a completion code variable, the only type that works is INTERGER*4 πŸ‘‘

Most of these subprograms start an operation, then go into the WAIT state (no CPU time used) until the NCP says the operation is done ⭐ You give them a time limit of type INTERGER*4, measured in tenths of a second, for the longest they should wait. If that limit runs out, a completion code tells you there was an error, and control goes back to your calling program with the operation still pending 😭

When an operation needs a socket identified by its socket identifier, the format is this: the identifier is an INTERGER*4 array with at least two elements, or a single element from one of those arrays. The first element is the site number, and the next one is the socket number. A socket number can be any value, positive, negative, or zero 🌈 Negative numbers are stored internally in two's complement form. For a socket's gender, the socket number counts as even or odd depending on whether its absolute value is even or odd, respectively πŸ™ˆ

Here's each subprogram, its job, and how to call it πŸ’œ


(1) OPEN πŸ¦‹

Calling OPEN asks for the local socket to leave the closed state, so it's ready to move data. There are three different operations it can do, covered below πŸ‘‘

(A) CONNECT πŸ”₯

Using CONNECT means you want your local socket logically connected to a foreign socket, with data transfer enabled between the two. The subprogram waits until the foreign socket either accepts or rejects the attempt. This only works when the local socket is closed ✨

The calling sequence:

CALL OPEN (cmpcd, time, lclsck, fgnsck, ws)

Where:

  • cmpcd is the completion code variable linked to the local socket.
  • time is how long the subprogram waits for the operation to finish.
  • lclsck is the socket identifier of the local socket.
  • fgnsck is the socket identifier of the foreign socket.
  • ws is a workspace with the same attributes as a socket identifier. If the operation works, it becomes linked to the local socket for the whole life of the connection πŸ’– Later operations might send information back to you in this workspace.

These completion codes are possible for CONNECT:

0, The operation was successful and the connection
   has been established

4, The specified completion code variable is
   already assigned to a socket; the operation was
   suppressed

8, The specified local socket is not in the closed
   state; the operation was suppressed

12, All communication paths to the specified foreign
    site are in use; the operation was suppressed

16, Local resources are insufficient to support
    another connection; the operation was suppressed

20, The connection attempt was rejected by the
    foreign process

24, The specified local socket is not local to UCSB;
    the operation was suppressed

28, The specified foreign site is invalid; the
    operation was suppressed

32, An addressing or protection exception was
    encountered with respect to the specified
    workspace; the operation was suppressed

36, Either hardware at the foreign site is
    inoperative or the NCP's counterpart at the
    foreign site does not exist or has failed

40, Local and foreign sockets are both either send
    or receive sockets; the operation was suppressed

44, By operator command, all Network operations were
    terminated; the socket will be closed

60, An NCP control transmission error occurred; the
    operation was suppressed

252, The specified time limit was exceeded; the
     operation was initiated but not completed

(B) LISTEN πŸŽ€

LISTEN is you asking to be notified about any connection attempt aimed at your local socket. The subprogram waits until one comes in, and then gives you the calling process's socket identifier. This only works when the local socket is closed 🌸

The calling sequence:

CALL OPEN (cmpcd, time, lclsck, ws)

Where:

  • cmpcd is the completion code variable linked to the local socket.
  • time is how long the subprogram waits for the operation to finish.
  • lclsck is the socket identifier of the local socket.
  • ws is a workspace. If the operation works, it holds the socket identifier of the calling socket and becomes linked to the local socket for the life of the connection πŸ¦‹ It has the same attributes as a socket identifier.

These completion codes are possible for LISTEN:

0, The operation was successful and a call has been
   received

4, The specified completion code variable is
   already assigned to a socket; the operation was
   suppressed

8, The specified local socket is not in the closed
   state; the operation was suppressed

12, Local resources are insufficient to support
    another connection; the operation was suppressed

16, The specified local socket is not local to UCSB;
    the operation was suppressed

20, An addressing or protection exception was
    encountered with respect to the specified
    workspace; the operation was suppressed

44, By operator command, all Network operations were
    terminated; the socket will be closed

252, The specified time limit was exceeded; the
     operation was initiated but not completed

(C) ACCEPT πŸ’…

ACCEPT takes the connection from the foreign socket whose call made an earlier LISTEN succeed on the local socket. Once it finishes, data can move to or from the local socket, depending on its gender 🫢 This only works when the last operation on the local socket was a LISTEN. The subprogram waits until it's done ✨

The calling sequence:

CALL OPEN (cmpcd, time)

Where:

  • cmpcd is the completion code variable linked to the local socket by an earlier LISTEN.
  • time is how long the subprogram waits for the operation to finish.

These completion codes are possible for ACCEPT:

0, The operation was successful, and the connection
   is established

4, The specified local socket is in the closed
   state 9The NCP may have received an abort
   notification from the foreign process); the
   operation was suppressed

8, the previous operation specifying the designated
   local socket was not a LISTEN; the operation was
   suppressed

12, All communication paths to the specified foreign
    site are in use; the socket has been returned to
    the closed state

252, the specified time limit was exceeded; the
     operation was initiated but not completed

(2) CLOSE 🌈

CLOSE is you asking for the local socket to go back to the closed state πŸ’€ If the last thing you did on this socket was a LISTEN, CLOSE turns down the foreign process's connection attempt. If the last thing was a CONNECT, the attempt gets aborted 😭 If a connection is up, any data still on its way out from the local socket is allowed to reach the foreign socket, where it can be either received or flushed, before the local socket closes. The subprogram waits until the socket is back in the closed state ⭐

The calling sequence:

CALL CLOSE (cmpcd, time)

Where:

  • cmpcd is the completion code variable linked to the local socket.

Okay so time is basically how long the subprogram is gonna wait for the operation to finish ⏳

Here are the completion codes that can pop up for this one πŸŽ€

  • 0, the operation worked and the socket is back in the closed state ✨
  • 8, the completion code variable isn't assigned to a socket, so the operation got suppressed πŸ™ˆ
  • 12, the local socket is already in the middle of closing. The operation was suppressed, but the local socket will still close πŸ’…
  • 36, either the hardware at the foreign site is inoperative, or the NCP's counterpart there doesn't exist or has failed πŸ’€
  • 44, an operator command terminated all Network operations, so the socket will be closed 😭
  • 60, an NCP control transmission error happened and the operation was aborted 🫢
  • 64, a transmission error happened and the operation was aborted, but the socket will be closed 🌸
  • 252, the time limit got exceeded. The operation was started but never finished 🧚

3) SEND πŸ¦‹

Okay this one is the main event πŸ’– It causes data to be sent to the foreign socket. The subprogram waits until the foreign socket has received the data, or until the NCP has queued it locally. Either way, you're good 🫢

The calling sequence is as follows:

CALL WRITE (cmpcd, bfr, len, time [,offset])

Where

  • 'cmpcd' is the completion code variable associated with the local socket.
  • 'bfr' is the data to be sent. It can be of any type and any length 🌈
  • 'len' is the number of bits of data to be sent. If 'len' is non-positive, no operation is performed. 'len' is of type INTEGER*4.
  • 'time' is the length of time the subprogram is to wait for the completion of the operation.
  • 'offset' is the bit offset from the first bit of 'bfr' at which data transmission is to begin. It is of type INTEGER*4. If it isn't specified, 'offset' defaults to zero πŸ“

The following completion codes are possible for this operation:

  • 0, the operation was successful and the data has been sent ✨
  • 4, the specified local socket isn't a send socket, so the operation was suppressed πŸ™…β€β™€οΈ
  • 8, the specified completion code variable isn't assigned to a socket, so the operation was suppressed πŸ™ˆ
  • 12, a previous send operation is still in progress, so this one was suppressed 😀
  • 16, the connection isn't fully open, so the operation was suppressed πŸ₯Ί
  • 20, the foreign socket terminated the connection before the send finished. Not all the data was transmitted πŸ’”
  • 36, either the hardware at the foreign site is inoperative, or the NCP's counterpart there doesn't exist or has failed πŸ’€
  • 44, an operator command terminated all Network operations, so the socket will be closed 😭
  • 52, one or more interrupts were received from the foreign socket, so the operation was suppressed ⚑
  • 56, an addressing exception came up with respect to the data buffer, so the operation was suppressed 🚫
  • 60, an NCP control transmission error happened. The operation was aborted and the socket will be closed 🫠
  • 64, a transmission error happened. The operation was aborted and the socket will be closed 🌸
  • 252, the time limit got exceeded. The operation was started but never finished 🧚

4) RECEIVE πŸ’œ

This one's the mirror of SEND πŸͺž It causes data to be received from the foreign socket. The subprogram waits until the reception of the data is complete.

The calling sequence is as follows:

CALL READ (cmpcd, bfr, len, time [,offset])

Where

  • 'cmpcd' is the completion code variable associated with the local socket.
  • 'bfr' is the variable where the data is going to be placed. It can be of any type and any length πŸ’…
  • 'len' is the number of bits of data to be received. If 'len' is non-positive, no operation is performed. 'len' is of type INTEGER*4.
  • 'time' is the length of time the subprogram is to wait for the completion of the operation.
  • 'offset' is the bit offset from the first bit of 'bfr' at which the first bit of data is to be placed. It is of type INTEGER*4. If it isn't specified, 'offset' defaults to zero πŸŽ€

The following completion codes are possible for this operation:

  • 0, the operation was successful and the data has been received ✨
  • 4, the specified local socket isn't a receive socket, so the operation was suppressed πŸ™…β€β™€οΈ
  • 8, the specified completion code variable isn't assigned to a socket, so the operation was suppressed πŸ™ˆ
  • 12, a previous receive operation is still in process, so this one was suppressed 😀
  • 16, the connection isn't fully open, so the operation was suppressed πŸ₯Ί
  • 20, the foreign socket terminated the connection before the receive finished. The data is unpredictable πŸ˜΅β€πŸ’«
  • 24, an addressing or protection exception came up with respect to the data buffer, so the operation was suppressed 🚫
  • 36, either the hardware at the foreign site is inoperative, or the NCP's counterpart there doesn't exist or has failed πŸ’€
  • 44, an operator command terminated all network operations, so the socket will be closed 😭
  • 52, one or more interrupts were received from the foreign socket, so the operation was suppressed ⚑
  • 60, an NCP control transmission error happened. The operation was suppressed and the socket will be closed 🫠
  • 252, the time limit got exceeded. The operation was started but never finished 🧚

5) CHECK πŸ”₯

This operation returns the status of the specified local socket πŸ‘€ There's no completion code variable tied to it, because it's always successful and the socket is identified by its socket number. It's valid at any time and always finishes immediately ⚑

The calling sequence is as follows:

CALL CHECK (lclsck, stat, menu, fgnsck, deficit)

Where

  • 'lclsck' is the socket identifier of the local socket.
  • 'stat' is a code for the status, and is of type INTEGER*4.
  • 'mnem' is a mnemonic for the status. It can be of any type, of any length greater than or equal to eight bytes 🧚
  • 'fgnsck' is the socket identifier of the foreign socket, or zero.
  • 'deficit' is the send/receive deficit in bits, or zero, and is to type INTEGER*4.
  • 'lclsck' is the only argument the programmer needs to define. The others are output from the subprogram πŸ’–

Here's the status table. Each row tells you what the socket is up to πŸ’Œ

   'STAT'    'MNEM'         MEANING
   ------    ------         ---------
     0        OPEN         A connection is fully established. No
                           SEND/RECEIVE operation is in progress.
                          'fgnsck' is the socket identifier of the
                           connected socket.  'deficit' is the number of
                           bites queued locally at the socket by the NCP
                           and available to satisfy a future RECEIVE
                           operation, or awaiting output ads the results
                           of a previous SEND operation.

     1       LISTEN        A LISTEN has been issued.

     2       CONNECT       A CONNECT has been issued. 'fgnsck' is the
                           socket identifier of the foreign socket.

     3       DECISION      A LISTEN has been completed.  'fgnsck' is
                           the socket identifier of the calling socket.

     4       CALL(S)       One or more calls have been received for the
                           local socket. No LISTEN or CONNECT has been
                           issued.

     5       I/O           A connection is fully established. A
                           SEND/RECEIVE operation is in progress.
                          'fgnsck' is the socket identifier of the
                           connected socket.  'deficit' is the number
                           of bits yet to be sent or received.

     6       CLOSED        The socket is in the closed state.

     7      <--DRAIN       The foreign socket is attempting to close the
                           connection.  The NCP has data yet to be ready
                           by the local socket.  'fgnsck' is the socket
                           identifier of the connected socket.
                          'deficit' is the number of bits yet to be
                           received.

     8       DRAINED       The foreign socket is attempting to close the
                           connection.  The NCP is awaiting arrival at
                           the foreign site of data currently in
                           transit.  'fgnsck' is the socket identifier
                           of the connected socket.

     9       CLOSING       The local socket has issued a CLOSE. The NCP
                           is in the process of returning the local
                           socket to the closed state. 'fgnsck' is the
                           socket identifier of the connected socket.

    10       DRAIN-->      The local socket has issued a CLOSE.  The NCP
                           is completing the last SEND operation before
                           returning the local socket to the closed
                           state.  'fgnsck' is the socket identifier
                           of the connected socket. 'deficit' is the
                           number of bits the NCP has yet to transmit.

(6) IDENTIFY πŸ‘‘

okay so this one is the ID operation, bestie πŸͺͺ it's how you look up a local socket using its completion code variable. It's valid at any time and always finishes immediately, no waiting around ⚑ Since it literally can't fail, there are no completion codes for it, and the completion code variable doesn't get changed at all ✨

CALL ID (cmpcd, lclsck)

Where

  • cmpcd is the completion code variable associated with the local socket.
  • lclsck gets set to the socket identifier of the local socket if the completion code variable is associated with a socket, or to zero otherwise.

(7) SIGNAL πŸ“£

okay this one is giving secret message to the other process 🀫 It sends a signal to the foreign process, and what the signal means is totally up to the user πŸ’… The tea is that the next time the foreign socket tries to start a RECEIVE or SEND, that operation gets suppressed and it gets a completion code saying a signal was received 🚫 The subprogram waits until the signal has actually been sent to the foreign NCP. This is only valid when the socket is fully open πŸ”“

CALL SIGNAL (cmpcd, time)

Where

  • cmpcd is the completion code variable associated with the local socket.
  • time is the length of time the subprogram is to wait for completion of the operation.

The following completion codes are possible for this operation:

  • 0, the operation was successful, and the signal has been sent βœ…
  • 4, the specified completion code variable is not assigned to a socket; the operation was suppressed πŸ™ˆ
  • 8, the connection is not fully open; the operation was suppressed πŸ’€

Certain of the Network subprograms are meant for, though not restricted to, use with the Online System Network operators. Here's the general vibe of those operators πŸ–₯️

In all Network operations involving the Online System Network operators, there are certain conventions about how the data sent and received is formatted. The data is grouped into 'messages' made of three fields, in this order: op code, length, and text. The op code is one byte long and tells you how to interpret the text field. The length field is two bytes long and gives the length, in bits, of the text field, which holds the actual data. (The op code and length fields together are called a header πŸŽ€)

The following op codes are currently defined:

Op Code   Meaning

  0       This op code is a NOP. No text field exists, and the
          contents of the length field are unpredictable. (This
          op code is used mainly as a delimiter.)

  1       The text field contains EBCDIC characters, one
          character per byte.  The Online System operators
          consider the characters as intended for display as soon
          as the text field has been received.

  2       The text contains codes for keypushes, one byte per
          key.  The Online operators consider the keys as
          intended for execution as soon as the text field has
          been received.

  3       The same as for an op code of 2, except that the Online
          operators consider that the execution of the keys will
          be delayed until all data for that receive operations
          has been received.

The standard format for data sent or received by the Online System operators is a string of messages, with the last message marked by a header with a NOP op code, called a trailer 🧚 These conventions are the default, but any of them can be overridden by appropriate programming ✨

Here are the subprograms meant for use with the Online System operators πŸ’»

(8) WRITE TO ONLINE CONSOLE πŸ–ŠοΈ

This subprogram sends data, assumed to be characters represented by their EBCDIC codes, from the specified local socket πŸ“€ The characters go out in a standard message, with a header in front and optionally a trailer after. The subprogram waits for the data to be received by the foreign socket, or to be queued locally by the NCP. This is only valid when the local socket is a send socket and is fully open πŸ”“

CALL WTOLC (cmpcd, bfr, len, level, across, down, time)

Where

  • cmpcd is the completion code variable associated with the local socket.
  • bfr is the character string to be sent, and can be of any type, any length.
  • len, in absolute value, is the number of characters to be sent. If len is positive or zero, the end of the data is marked by a trailer; if len is negative, no trailer is sent. len is of type INTEGER*4.
  • level indicates the mode of typing. The absolute value of level, if non-zero, is the shift level to type on, and must be less than or equal to nine. If greater than nine, one is used. If level is positive, across and down are relative to the current typing location. If level is negative, the carriage is moved to the upper left-hand corner before typing begins, which makes across and down absolute coordinates. If level is zero, the typing is in case one characters, and a carriage return comes before the positioning for across and down. If the characters to be displayed are case one characters, the header sent will have an op code that says the characters should be displayed as soon as they're received; otherwise, the op code will say the buttons should be executed as soon as they're received. level is of type INTEGER*4.
  • across is the number of spaces to be moved horizontally across the display tube before typing begins. across can be any value, positive, negative, or zero, and is of type INTEGER*4.
  • time is the length of time the subprogram is to wait for completion of the operation.

The completion codes for this operation are the same as for SEND.

(9) READ FROM ONLINE CONSOLE πŸ“₯

This subprogram receives data, assumed to be characters represented by their EBCDIC codes, from the foreign socket in one or more standard messages. The subprogram waits for the data, optionally followed by a trailer, to be received by the local socket. This is only valid when the local socket is a receive socket and is fully open πŸ”“

CALL RFOLC (cmpcd, bfr, len, time)

Where

  • cmpcd is the completion code variable associated with the local socket.
  • bfr is the variable the data is to be placed into, and can be of any type, any length.
  • len, in absolute value, is the maximum number of characters to be placed in bfr. If the length fields of the header(s) received total more data than len, the excess data will still be received, but it won't be placed into bfr and won't be accessible to the program πŸ™… If len is positive or zero, data will be received until a trailer is encountered. If len is negative, a single message, not including the trailer, will be received. len is of type INTEGER*4.
  • time is the length of time the subprogram is to wait for completion of the operation.

The completion codes for this operation are the same as for RECEIVE.

(10) WRITE TO ONLINE CONSOLE WITH REPLY πŸ”

This subprogram combines the jobs of 'WRITE TO ONLINE CONSOLE' and 'READ FROM ONLINE CONSOLE' 🫢 It first sends a string of data to the foreign socket from the specified send socket, waits for it to be received by the foreign socket (or queued locally by the NCP), and then waits for a reply directed toward the specified receive socket. This is only valid when the sockets have the correct gender and both are fully open πŸ”“

CALL WTOLCR (cmpcd, bfr, len, level, across, down, time,
cmpcd2, bfr2, len2)

Where

  • cmpcd is the completion code variable associated with the local send socket.
  • bfr is as in 'WRITE TO ONLINE CONSOLE'.
  • len is as in 'WRITE TO ONLINE CONSOLE'.
  • level is as in 'WRITE TO ONLINE CONSOLE'.
  • across is as in 'WRITE TO ONLINE CONSOLE'.
  • down is as in 'WRITE TO ONLINE CONSOLE'.
  • time is the length of time the subprogram is to wait for completion, individually, of the transmission and reception of data.
  • cmpcd2 is the completion code variable associated with the local receive socket.
  • bfr2 is as bfr in 'READ FROM ONLINE CONSOLE'.
  • len2 is as len in 'READ FROM ONLINE CONSOLE'.

The completion codes for the send socket are the same as for the SEND operation, and the completion codes for the receive socket are the same as for the RECEIVE operation.

(11) ERASE 🧹

This subprogram causes data constituting an Online System command to erase the display tube to be sent from the specified local socket ✨ The data goes out in a single standard message, including an op code that says characters should be displayed as they're received, and optionally including a trailer. The subprogram waits for the data to be received by the foreign socket, or to be queued locally by the NCP. This is only valid when the local socket is a send socket and is fully open πŸ”“

CALL ERASE ('cmpcd', 'delay1', 'delay2', 'time')

Where

  • cmpcd is the completion code variable associated with the local socket.

Okay bestie, so the next bit is all about the knobs you can twist for the erase step. πŸŽ€βœ¨

  • delay1 πŸ’… is the pause, in tenths of a second, that the subprogram takes while it's chilling in the WAIT state before it sends the erase. Here's the twist: we look at its absolute value for the length. If delay1 is positive or zero, a trailer gets sent after the erase. If it's negative, no trailer. Lowkey genius, right? 🧚 It's an INTEGER*4.
  • delay2 πŸ¦‹ is the pause after the erase goes out and before control gets handed back to the calling program. It's also measured in tenths of a second, and it's an INTEGER*4 too. πŸ’œ
  • time ⏰ is how long the subprogram will wait for the operation to finish. 🌸

And the completion codes? Same as SEND. No new codes to memorize, periodt! πŸ‘‘πŸ«Ά

πŸ“¦ where this page comes from