home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / defdata / telnet.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  267.0 KB  |  6,841 lines

  1. --::::::::::::::
  2. --debugio_.ada
  3. --::::::::::::::
  4. -----------------------------------------------------------------------
  5. --
  6. --         DoD Protocols    NA-00004-200       80-01053-100(-)
  7. --         E-Systems, Inc.  August 07, 1985
  8. --
  9. --         DEBUGIO_.ADA       Author : Mike Thomas 
  10. --
  11. -----------------------------------------------------------------------
  12.  
  13. -- File : debugio    Author : Mike Thomas
  14.  
  15. --   5/4/85  2:09 PM : MODIFY FOR DEC ADA 
  16. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  17.  
  18. --  5/21/85  1:40 PM : MODIFIED TO RECOMPILE UNDER TELESOFT ADA
  19. --                     OLD CODE (DEC) MARKED AS --&MT 
  20.  
  21. --  5/22/85  8:10 AM : MODIFY FOR DEC ADA 
  22. --                     OLD CODE (TELESOFT) MARKED AS --&MT
  23. WITH SYSTEM ;
  24. USE  SYSTEM ;
  25. PACKAGE debug_io IS
  26.  
  27. -- ****************************************************************************
  28. -- 
  29. -- This package has routines which do output to the CRT or a debug disk file
  30. -- or both (or neither).  The interface is indended to look similer to 
  31. -- text_io for string, character and integer output.  NOTE : The Wicat
  32. -- must close a disk file for it to exist.
  33. --
  34. -- ****************************************************************************
  35.  
  36.  
  37.   --&MT  SUBTYPE bit_count_32_type IS LONG_INTEGER ; 
  38.   SUBTYPE bit_count_32_type IS INTEGER ;
  39.  
  40.   --&MT   SUBTYPE bit_count_16_type IS INTEGER ; 
  41.   SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  42.  
  43.   --&MT   SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  44.   SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  45.  
  46.   
  47.   PROCEDURE put (item : IN CHARACTER) ;
  48.  
  49.   PROCEDURE put (item : IN STRING) ;
  50.  
  51.   PROCEDURE put (item : IN bit_count_16_type) ;
  52.  
  53. --&MT--PROCEDURE put (item : IN SYSTEM.BYTE) ;      -- TeleLie-ADA flags this as an 
  54. --&MT                                               -- illegel redeclaration!
  55. --&MT  PROCEDURE put_byte (item : IN SYSTEM.BYTE) ; -- so... use this
  56.   PROCEDURE put_byte (item : IN bit_count_8_type) ;
  57.  
  58.   PROCEDURE put_line (item : IN CHARACTER) ;
  59.  
  60.   PROCEDURE put_line (item : IN STRING) ;
  61.  
  62.   PROCEDURE put_line (item : IN bit_count_16_type) ;
  63.  
  64. --&MT--PROCEDURE put_line (item : IN SYSTEM.BYTE) ; -- as above...
  65.  
  66.   PROCEDURE put_line_byte (item : IN bit_count_8_type) ; 
  67.  
  68.   PROCEDURE open_debug_disk_file ;
  69.  
  70.   PROCEDURE close_debug_disk_file ;
  71.  
  72.   FUNCTION debug_disk_file_is_open RETURN BOOLEAN ;
  73.  
  74. -- user could store existing destination, set his own temporary one, and
  75. -- restore the origional destination at any point to redirect debug info.
  76. -- NOTE : ATTEMPTING TO WRITE TO THE DISK FILE WHEN IT IS NOT OPEN IS ERRONEOUS.
  77.  
  78.   TYPE debug_destination_type IS 
  79.    (none, crt_only, debug_disk_file_only, crt_and_disk) ;
  80.   destination : debug_destination_type := none ;
  81.   
  82. END debug_io ;
  83.  
  84. --::::::::::::::
  85. --debugio.ada
  86. --::::::::::::::
  87. -----------------------------------------------------------------------
  88. --
  89. --         DoD Protocols    NA-00004-200       80-01054-100(-)
  90. --         E-Systems, Inc.  August 07, 1985
  91. --
  92. --         DEBUGIO.ADA       Author : Mike Thomas 
  93. --
  94. -----------------------------------------------------------------------
  95.  
  96. -- File : debugio    Author : Mike Thomas
  97.  
  98. --   5/4/85  2:09 PM : MODIFY FOR DEC ADA 
  99. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  100.  
  101. --  5/21/85  1:40 PM : MODIFIED TO RECOMPILE UNDER TELESOFT ADA
  102. --                     OLD CODE (DEC) MARKED AS --&MT 
  103.  
  104. --  5/22/85  8:10 AM : MODIFY FOR DEC ADA 
  105. --                     OLD CODE (TELESOFT) MARKED AS --&MT
  106.  
  107. WITH TEXT_IO ;
  108. USE  TEXT_IO ;
  109.  
  110. PACKAGE BODY debug_io IS
  111.  
  112. -- ****************************************************************************
  113. -- 
  114. -- It would be nice to revamp this package and use generics when they are 
  115. -- supported by the compiler.  Also could add enumerated type I/O routines.  
  116. -- If input routines are needed, they could be added.
  117. -- ****************************************************************************
  118.  
  119.   debug_filename              : CONSTANT STRING(1..13) := "DEBUGFILE.TXT" ;
  120.   debug_output_file           : TEXT_IO.FILE_TYPE ;
  121.   output_file                 : TEXT_IO.FILE_MODE := TEXT_IO.OUT_FILE ;
  122.   the_debug_disk_file_is_open : BOOLEAN := FALSE ;
  123. --&MT  next line not used for TeleSoft
  124.   PACKAGE integer_io IS NEW TEXT_IO.INTEGER_IO(bit_count_16_type) ;
  125.  
  126.   PROCEDURE screening_put (item : IN CHARACTER) IS
  127.             -------------
  128.   BEGIN
  129.     IF item = ASCII.CR THEN 
  130.       TEXT_IO.PUT("<CR>") ; -- display logical cr so won't mess up printer
  131.     ELSE
  132.       TEXT_IO.PUT(item) ;
  133.     END IF ;
  134.   EXCEPTION
  135.     WHEN OTHERS =>
  136.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.SCR_PUT(C)") ;
  137.       RAISE ;
  138.   END screening_put ;
  139.  
  140.  
  141.   PROCEDURE screening_put 
  142.             -------------
  143.    (debug_file : IN TEXT_IO.FILE_TYPE ;
  144.     item       : IN CHARACTER) IS
  145.   BEGIN
  146.     IF item = ASCII.CR THEN 
  147.       TEXT_IO.PUT(debug_file, "<CR>") ; -- display logical cr so won't 
  148.     ELSE
  149.       TEXT_IO.PUT(debug_file, item) ;
  150.     END IF ;
  151.   EXCEPTION
  152.     WHEN OTHERS =>
  153.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.SCR_PUT(F,C)") ;
  154.       RAISE ;
  155.   END screening_put ;
  156.  
  157.  
  158.   PROCEDURE put (item : IN CHARACTER) IS 
  159.   BEGIN
  160.     CASE destination IS
  161.       WHEN crt_only =>
  162.         screening_put(item) ;
  163.       WHEN debug_disk_file_only =>
  164.         screening_put(debug_output_file, item) ;
  165.       WHEN crt_and_disk =>
  166.         screening_put(item) ;
  167.         screening_put(debug_output_file, item) ;
  168.       WHEN none =>
  169.         NULL ;
  170.     END CASE ;       
  171.   EXCEPTION
  172.     WHEN OTHERS =>
  173.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.PUT(C)") ;
  174.       RAISE ;
  175.   END put ;
  176.  
  177.  
  178.   PROCEDURE put (item : IN STRING) IS
  179.     buf : STRING (1..4*item'length) ;-- arbitrary length(allow for "expansion")
  180.  
  181.     buf_ptr : bit_count_32_type RANGE 0..4*item'length := 0 ;
  182. --&MT    buf_ptr : bit_count_16_type RANGE 0..4*item'length := 0 ;
  183.  
  184.   BEGIN
  185.   -- Calls to text_io are expensive, do processing here to reduce calls
  186.   -- by printing strings and not individual characters.
  187.     IF destination = none THEN RETURN ; END IF ;
  188.     FOR index IN item'RANGE LOOP -- check for printer control char
  189.       IF item(index) = ASCII.CR THEN -- replace ASCII.CR with "<CR>"
  190.         buf((buf_ptr + 1)..(buf_ptr + 4)) := "<CR>" ;
  191.         buf_ptr := buf_ptr + 4 ;
  192.       ELSE
  193.         buf_ptr := buf_ptr + 1 ;
  194.         buf(buf_ptr) := item(index) ;
  195.       END IF ;
  196.     END LOOP ;
  197.     IF buf_ptr > 0 THEN
  198.       DECLARE -- handle strings > 132 so text_io does not get constraint error
  199.  
  200.         start : bit_count_32_type := 1 ;
  201.         stop  : bit_count_32_type := 79 ;
  202.         --&MT       start : bit_count_16_type := 1 ;
  203.         --&MT       stop  : bit_count_16_type := 79 ;
  204.       BEGIN
  205.         LOOP
  206.           IF stop > buf_ptr THEN
  207.             CASE destination IS
  208.               WHEN crt_only =>
  209.                 TEXT_IO.PUT(buf(start..buf_ptr)) ;
  210.               WHEN debug_disk_file_only =>
  211.                 TEXT_IO.PUT(debug_output_file, buf(start..buf_ptr)) ;
  212.               WHEN crt_and_disk =>
  213.                 TEXT_IO.PUT(buf(start..buf_ptr)) ;
  214.                 TEXT_IO.PUT(debug_output_file, buf(start..buf_ptr)) ;
  215.               WHEN none =>
  216.                 NULL ;
  217.               END CASE ; 
  218.               EXIT ;
  219.           ELSE
  220.             CASE destination IS
  221.               WHEN crt_only =>
  222.                 TEXT_IO.PUT_LINE(buf(start..stop)) ;
  223.               WHEN debug_disk_file_only =>
  224.                 TEXT_IO.PUT_LINE(debug_output_file, buf(start..stop)) ;
  225.               WHEN crt_and_disk =>
  226.                 TEXT_IO.PUT_LINE(buf(start..stop)) ;
  227.                 TEXT_IO.PUT_LINE(debug_output_file, buf(start..stop)) ;
  228.               WHEN none =>
  229.                 NULL ;
  230.               END CASE ; 
  231.               start := start + 79;
  232.               stop := stop + 79 ;
  233.           END IF ; -- < 79 characters ?
  234.         END LOOP ;
  235.       END ; -- declare
  236.     END IF ; -- buf_ptr > 0 
  237.   EXCEPTION
  238.     WHEN OTHERS =>
  239.       TEXT_IO.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.PUT(S)") ;
  240.       RAISE ;
  241.   END put ;
  242.  
  243.  
  244.   PROCEDURE put (item : IN bit_count_16_type) IS 
  245.   BEGIN
  246.     CASE destination IS
  247.       WHEN crt_only =>
  248.         INTEGER_IO.PUT(item) ;
  249.       WHEN debug_disk_file_only =>
  250.         INTEGER_IO.PUT(debug_output_file, item) ;
  251.       WHEN crt_and_disk =>
  252.         INTEGER_IO.PUT(item) ;
  253.         INTEGER_IO.PUT(debug_output_file, item) ;
  254.       WHEN none =>
  255.         NULL ;
  256.     END CASE ;       
  257.   EXCEPTION
  258.     WHEN OTHERS =>
  259.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.PUT(I)") ;
  260.       RAISE ;
  261.   END put ;
  262.  
  263.  
  264.   PROCEDURE put_byte (item : IN bit_count_8_type) IS
  265.   BEGIN
  266.     debug_io.put('<') ;
  267.     debug_io.put(bit_count_16_type(item)) ;
  268.     debug_io.put('>') ;
  269.   EXCEPTION
  270.     WHEN OTHERS =>
  271.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.PUT(B)") ;
  272.       RAISE ;
  273.   END put_byte ;
  274.  
  275.   
  276.   PROCEDURE put_line (item : IN CHARACTER) IS
  277.   BEGIN
  278.     debug_io.put(item) ;
  279.     CASE destination IS
  280.       WHEN crt_only =>
  281.         TEXT_IO.NEW_LINE ;
  282.       WHEN debug_disk_file_only =>
  283.         TEXT_IO.NEW_LINE(debug_output_file) ;
  284.       WHEN crt_and_disk =>
  285.         TEXT_IO.NEW_LINE ;
  286.         TEXT_IO.NEW_LINE(debug_output_file) ;
  287.       WHEN none =>
  288.         NULL ;
  289.      END CASE ; 
  290.   EXCEPTION
  291.     WHEN OTHERS =>
  292.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.PUT_LINE(C)") ;
  293.       RAISE ;
  294.   END put_line ;
  295.  
  296.  
  297.   PROCEDURE put_line (item : IN STRING) IS
  298.   BEGIN
  299.     IF destination = none THEN RETURN ; END IF ;
  300.     debug_io.put(item) ;
  301.     CASE destination IS
  302.       WHEN crt_only =>
  303.         TEXT_IO.NEW_LINE ;
  304.       WHEN debug_disk_file_only =>
  305.         TEXT_IO.NEW_LINE(debug_output_file) ;
  306.       WHEN crt_and_disk =>
  307.         TEXT_IO.NEW_LINE ;
  308.         TEXT_IO.NEW_LINE(debug_output_file) ;
  309.       WHEN none =>
  310.         NULL ;
  311.      END CASE ; 
  312.   EXCEPTION
  313.     WHEN OTHERS =>
  314.       TEXT_IO.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.PUT_LINE(S)") ;
  315.       RAISE ;
  316.   END put_line ;
  317.  
  318.  
  319.   PROCEDURE put_line (item : IN bit_count_16_type) IS 
  320.   BEGIN
  321.     CASE destination IS
  322.       WHEN crt_only =>
  323.         INTEGER_IO.PUT(item) ;
  324.         TEXT_IO.NEW_LINE ;
  325.       WHEN debug_disk_file_only =>
  326.         INTEGER_IO.PUT(debug_output_file, item) ;
  327.         TEXT_IO.NEW_LINE(debug_output_file) ;
  328.       WHEN crt_and_disk =>
  329.         INTEGER_IO.PUT(item) ;
  330.         INTEGER_IO.PUT(debug_output_file, item) ;
  331.         TEXT_IO.NEW_LINE ;
  332.         TEXT_IO.NEW_LINE(debug_output_file) ;
  333.       WHEN none =>
  334.         NULL ;
  335.     END CASE ;
  336.   EXCEPTION
  337.     WHEN OTHERS =>
  338.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.PUT_LINE(I)") ;
  339.       RAISE ;
  340.   END put_line ;
  341.  
  342.  
  343.   PROCEDURE put_line_byte (item : IN bit_count_8_type) IS
  344.   BEGIN
  345.     debug_io.put('<') ;
  346.     debug_io.put(bit_count_16_type(item)) ;
  347.     debug_io.put_line('>') ;
  348.   EXCEPTION
  349.     WHEN OTHERS =>
  350.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.PUT_LINE(B)") ;
  351.       RAISE ;
  352.   END put_line_byte ;
  353.  
  354.  
  355.   PROCEDURE open_debug_disk_file IS
  356.   BEGIN
  357.     TEXT_IO.CREATE (debug_output_file, output_file, debug_filename) ;
  358.     the_debug_disk_file_is_open := TRUE ;
  359.   EXCEPTION
  360.     WHEN OTHERS =>
  361.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.OPEN_DDF") ;
  362.       RAISE ;
  363.   END open_debug_disk_file ;
  364.  
  365.  
  366.   PROCEDURE close_debug_disk_file IS
  367.   BEGIN
  368.     TEXT_IO.CLOSE(debug_output_file) ;
  369.     the_debug_disk_file_is_open := FALSE ;
  370.   EXCEPTION
  371.     WHEN OTHERS =>
  372.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.CLOSE_DDF") ;
  373.       RAISE ;
  374.   END close_debug_disk_file ;
  375.  
  376.  
  377.   FUNCTION debug_disk_file_is_open RETURN BOOLEAN IS
  378.   BEGIN
  379.     RETURN the_debug_disk_file_is_open ;
  380.   END debug_disk_file_is_open ;
  381.  
  382.  
  383. BEGIN -- package body
  384.   NULL ;
  385. EXCEPTION
  386.   WHEN OTHERS =>
  387.     debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN debugio instantiation") ;
  388.     RAISE ;
  389. END debug_io ;
  390. --::::::::::::::
  391. --pvirtmpac_.ada
  392. --::::::::::::::
  393. -----------------------------------------------------------------------
  394. --
  395. --         DoD Protocols    NA-00004-200       80-01063-100(-)
  396. --         E-Systems, Inc.  August 07, 1985
  397. --
  398. --         PVIRTMPAC_.ADA       Author : Mike Thomas 
  399. --
  400. -----------------------------------------------------------------------
  401.  
  402. -- File pvirtmpac     AUTHOR : Paul Higgins
  403.  
  404. --   5/4/85  2:09 PM : MODIFY FOR DEC ADA 
  405. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  406.  
  407. WITH SYSTEM ; -- to access system.byte
  408.  
  409. PACKAGE virtual_terminal -- specification
  410.         ----------------
  411.  IS
  412.  
  413. --**********************  USER SPECIFICATION  *******************************
  414. --
  415. -- This package implements the interface between telnet and the process
  416. --  using telnet. The interface is on a character by character basis and
  417. --  is buffered. The "user process" is referred to as the NVT (network
  418. --  virtual terminal) and could be an applications process (FTP,SMTP,etc)
  419. --  or a terminal-handler.
  420. --
  421. -------------------------  data specifications  -----------------------------
  422.   
  423.  
  424. --&MT SUBTYPE bit_count_32_type IS LONG_INTEGER ; 
  425.   SUBTYPE bit_count_32_type IS INTEGER ;
  426.  
  427. --&MT SUBTYPE bit_count_16_type IS INTEGER ; 
  428.   SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  429.  
  430. --&MT SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  431.   SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  432.  
  433.   SUBTYPE port_number IS bit_count_16_type ;
  434.  
  435.   ---------------------  procedure specifications  ----------------------------
  436.  
  437. --- telnet's side of the interface:
  438.   
  439.   FUNCTION there_are_characters_in_keyboard_buffer (I : port_number)
  440.            ---------------------------------------
  441.    RETURN BOOLEAN ;
  442.  
  443.   -- ***********************  USER SPECIFICATION  *************************
  444.   --
  445.   -- This function returns true if there are unprocessed characters in the
  446.   -- NVT keyboard buffer.
  447.   -------------------------------------------------------------------------
  448.  
  449.  
  450.     
  451.   PROCEDURE get_next_character_from_keyboard_buffer 
  452.             ---------------------------------------
  453.    (I   : IN  port_number;
  454.    char : OUT bit_count_8_type) ;
  455.  
  456.   -- ***********************  USER SPECIFICATION  *************************
  457.   --
  458.   -- This procedure will return the next unprocessed character from the
  459.   -- NVT keyboard buffer.
  460.   -------------------------------------------------------------------------
  461.      
  462.      
  463.      
  464.   FUNCTION there_is_room_in_the_printer_buffer (I : port_number) 
  465.            -----------------------------------
  466.    RETURN BOOLEAN ;
  467.  
  468.   -- ***********************  USER SPECIFICATION  *************************
  469.   --
  470.   -- This function returns true if there is room for a character in the
  471.   -- NVT printer buffer.
  472.   -------------------------------------------------------------------------
  473.  
  474.  
  475.  
  476.   PROCEDURE output_character_to_NVT_printer  
  477.             -------------------------------
  478.    (I   : IN port_number;
  479.    char : IN bit_count_8_type);
  480.  
  481.   -- ***********************  USER SPECIFICATION  *************************
  482.   --
  483.   -- This procedure will output a character to the NVT printer buffer.
  484.   -- If there is no room in the buffer the character will be lost.
  485.   -- It is the caller's responsibility to make sure there is room in the 
  486.   -- buffer.
  487.   -------------------------------------------------------------------------
  488.     
  489.     
  490.   --- nvt's side of the interface
  491.  
  492.   FUNCTION there_are_characters_in_printer_buffer (I : port_number) 
  493.            ---------------------------------------
  494.    RETURN BOOLEAN ;
  495.  
  496.   -- ***********************  USER SPECIFICATION  *************************
  497.   --
  498.   -- This function returns true if there are unprocessed characters in the
  499.   -- NVT printer buffer.
  500.   -------------------------------------------------------------------------
  501.  
  502.  
  503.     
  504.   PROCEDURE get_next_character_from_telnet 
  505.             ------------------------------
  506.    (I : port_number;
  507.    char : OUT bit_count_8_type) ;
  508.  
  509.   -- ***********************  USER SPECIFICATION  *************************
  510.   --
  511.   -- This procedure will return the next unprocessed character from the
  512.   -- NVT printer buffer.
  513.   -------------------------------------------------------------------------
  514.      
  515.      
  516.      
  517.   FUNCTION there_is_room_in_the_keyboard_buffer (I : port_number)
  518.            -----------------------------------
  519.    RETURN BOOLEAN ;
  520.  
  521.   -- ***********************  USER SPECIFICATION  *************************
  522.   --
  523.   -- This function returns true if there is room for a character in the
  524.   -- NVT keyboard buffer.
  525.   -------------------------------------------------------------------------
  526.  
  527.  
  528.  
  529.   PROCEDURE send_char_to_telnet 
  530.             -------------------
  531.    (I :   IN port_number;
  532.    char : IN bit_count_8_type);
  533.  
  534.   -- ***********************  USER SPECIFICATION  *************************
  535.   --
  536.   -- If there is no room in the buffer the character will be lost.
  537.   -- It is the caller's responsibility to make sure there is room in the 
  538.   -- buffer.
  539.   -------------------------------------------------------------------------
  540.     
  541.     
  542. END virtual_terminal ;
  543. --::::::::::::::
  544. --pvirtmpac.ada
  545. --::::::::::::::
  546. -----------------------------------------------------------------------
  547. --
  548. --         DoD Protocols    NA-00004-200       80-01064-100(-)
  549. --         E-Systems, Inc.  August 07, 1985
  550. --
  551. --         PVIRTMPAC.ADA       Author : Mike Thomas 
  552. --
  553. -----------------------------------------------------------------------
  554.  
  555. -- File pvirtmpac    AUTHOR : Paul Higgins
  556.  
  557. --   5/4/85  2:09 PM : MODIFY FOR DEC ADA 
  558. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  559.  
  560. with text_io; use text_io ;
  561.   
  562. PACKAGE BODY virtual_terminal IS 
  563.              ----------------
  564.  
  565. -- *************************  BODY SPECIFICATION  *****************************
  566. --
  567. -- This package manages buffers which are tied to the process/user terminal
  568. -- "I/O" device.  For example, keyboard input is stored in the keyboard_
  569. -- input_buffer.  Then, the Presentation Protocol Layer can retrieve
  570. -- characters from that buffer and pass them back to the Application Protocol 
  571. -- Layer when that layer asks for the characters.  Similar processing
  572. -- occurs for the printer_output_buffer.  The APL could ask the PPL to send
  573. -- a character out to the NVT_printer; the PPL would put the character into
  574. -- the printer_output_buffer and this character would eventually be 
  575. -- "printed" on the nvt printer.  Also procedures exist to store and retrieve
  576. -- these buffers in their entirety.  
  577. -- 
  578. -- ****************************************************************************
  579.  
  580.   -- the buffers 
  581.  
  582.   buffer_length : CONSTANT bit_count_16_type := 256 ; -- arbitrary
  583.   SUBTYPE buf_ptr IS bit_count_16_type RANGE 0..buffer_length ;
  584.   TYPE buffer_type IS ARRAY (0..buffer_length-1) OF bit_count_8_type ;
  585.  
  586.   -- keyboard input buffer
  587.  
  588.   TYPE keyboard_input_buffer_record IS 
  589.     RECORD
  590.       buffer  : buffer_type ;
  591.       in_ptr  : buf_ptr := 0 ;
  592.       out_ptr  : buf_ptr := 0 ;
  593.     END RECORD ;
  594.     
  595.  
  596.   -- printer output buffer
  597.  
  598.   TYPE printer_output_buffer_record IS 
  599.     RECORD
  600.       buffer   : buffer_type ;
  601.       in_ptr   : buf_ptr := 0 ;
  602.       out_ptr  : buf_ptr := 0 ;
  603.     END RECORD ;
  604.  
  605.  
  606.   TYPE nvt_ppl_buffers_type IS
  607.     RECORD  
  608.       keyboard_buffer : keyboard_input_buffer_record ;
  609.       printer_buffer : printer_output_buffer_record ;
  610.     END RECORD ;
  611.  
  612.  
  613.  number_of_devices : CONSTANT port_number := 1 ;
  614.  
  615.  io_buffer : ARRAY (1..number_of_devices) OF nvt_ppl_buffers_type ;
  616.  
  617.  
  618. -- Note that only one task is implemented. This should be a task type,
  619. -- and an array of them should be defined (one for each device).
  620. -- This could not be done by TS for now...
  621.  
  622. TASK inbuf IS
  623.   ENTRY kbd_char_rdy     (device : IN port_number; rdy : OUT BOOLEAN ) ;
  624.   ENTRY get_kbd_char     (device : IN port_number; ch  : OUT bit_count_8_type) ;
  625.   ENTRY put_kbd_char     (device : IN port_number; ch  : IN  bit_count_8_type) ;
  626.   ENTRY get_printer_char (device : IN port_number; ch  : OUT bit_count_8_type) ;
  627.   ENTRY put_printer_char (device : IN port_number; ch  : IN  bit_count_8_type) ;
  628.   ENTRY printer_char_rdy (device : IN port_number; rdy : OUT BOOLEAN ) ;
  629. END ;
  630.  
  631.  
  632. TASK BODY inbuf IS
  633.   BEGIN
  634.   LOOP
  635.   SELECT
  636.     ACCEPT kbd_char_rdy     (device : IN port_number; rdy : OUT BOOLEAN )
  637.       DO
  638.         rdy := io_buffer(device).keyboard_buffer.in_ptr 
  639.               /= io_buffer(device).keyboard_buffer.out_ptr ;
  640.       END ;
  641.   OR
  642.     WHEN io_buffer(1).keyboard_buffer.in_ptr 
  643.               /= io_buffer(1).keyboard_buffer.out_ptr =>
  644.       ACCEPT get_kbd_char (device : IN port_number; ch  : OUT bit_count_8_type) 
  645.         DO
  646.           ch := io_buffer(device).keyboard_buffer.buffer
  647.                 (io_buffer(device).keyboard_buffer.out_ptr) ;
  648.           io_buffer(device).keyboard_buffer.out_ptr :=
  649.            (io_buffer(device).keyboard_buffer.out_ptr + 1) mod buffer_length ;
  650.         END ;
  651.   OR
  652.     ACCEPT put_kbd_char (device : IN port_number; ch  : IN  bit_count_8_type) 
  653.       DO
  654.         IF io_buffer(device).keyboard_buffer.out_ptr 
  655.               /= (io_buffer(device).keyboard_buffer.in_ptr + 1)
  656.                 mod buffer_length THEN
  657.         io_buffer(device).keyboard_buffer.buffer
  658.                (io_buffer(device).keyboard_buffer.in_ptr) := ch ;
  659.         io_buffer(device).keyboard_buffer.in_ptr :=
  660.              (io_buffer(device).keyboard_buffer.in_ptr + 1) mod buffer_length ;
  661.         END IF ;
  662.      END ;
  663.   OR
  664.     WHEN io_buffer(1).printer_buffer.in_ptr 
  665.               /= io_buffer(1).printer_buffer.out_ptr =>
  666.       ACCEPT get_printer_char(device : IN port_number; ch : OUT bit_count_8_type)
  667.         DO
  668.           ch := io_buffer(device).printer_buffer.buffer
  669.                 (io_buffer(device).printer_buffer.out_ptr) ;
  670.           io_buffer(device).printer_buffer.out_ptr :=
  671.               (io_buffer(device).printer_buffer.out_ptr + 1) mod buffer_length ;
  672.         END ;
  673.   OR
  674.     ACCEPT put_printer_char(device : IN port_number; ch : IN bit_count_8_type) 
  675.       DO
  676.         IF io_buffer(device).printer_buffer.out_ptr 
  677.               /= (io_buffer(device).printer_buffer.in_ptr + 1)
  678.                 mod buffer_length THEN
  679.         io_buffer(device).printer_buffer.buffer
  680.                (io_buffer(device).printer_buffer.in_ptr) := ch ;
  681.         io_buffer(device).printer_buffer.in_ptr :=
  682.              (io_buffer(device).printer_buffer.in_ptr + 1) mod buffer_length ;
  683.         END IF ;
  684.      END ;
  685.    OR
  686.     ACCEPT printer_char_rdy(device : IN port_number; rdy : OUT BOOLEAN ) 
  687.       DO
  688.         rdy := io_buffer(device).printer_buffer.in_ptr 
  689.               /= io_buffer(device).printer_buffer.out_ptr ;
  690.       END ;
  691.   END SELECT ;
  692.   END LOOP ;
  693. END ;
  694.  
  695.  
  696.     
  697.   FUNCTION there_are_characters_in_keyboard_buffer (I : port_number)
  698.            ---------------------------------------
  699.    RETURN BOOLEAN is
  700.  
  701.   flag : boolean ;
  702.   begin
  703.     inbuf.kbd_char_rdy(i, flag) ;
  704.     RETURN flag ;
  705.   END there_are_characters_in_keyboard_buffer ; -- body
  706.  
  707.  
  708.      
  709.      
  710.     
  711.   PROCEDURE get_next_character_from_keyboard_buffer 
  712.             ---------------------------------------
  713.    (I   : IN  port_number;
  714.    char : OUT bit_count_8_type) is
  715.   BEGIN
  716.     char := 0 ; -- default value
  717.     inbuf.get_kbd_char(i, char) ;
  718.   END get_next_character_from_keyboard_buffer ; -- body
  719.  
  720.  
  721.      
  722.  
  723.   FUNCTION there_is_room_in_the_printer_buffer (I : port_number) 
  724.            -----------------------------------
  725.    RETURN BOOLEAN IS
  726.  
  727.   -- ***********************  BODY SPECIFICATION  *************************
  728.   --
  729.   -- This function returns true if there is room for a character in the
  730.   -- NVT printer buffer.
  731.   -------------------------------------------------------------------------
  732.   BEGIN
  733.     RETURN TRUE ;
  734.   END there_is_room_in_the_printer_buffer ; -- body
  735.      
  736.  
  737.  
  738.   PROCEDURE output_character_to_NVT_printer  
  739.             -------------------------------
  740.    (I   : IN port_number;
  741.    char : IN bit_count_8_type ) is
  742.  
  743.   BEGIN
  744.   inbuf.put_printer_char(i,char) ;
  745.   END output_character_to_NVT_printer ; -- body
  746.     
  747.   
  748.   FUNCTION there_are_characters_in_printer_buffer (I : port_number) 
  749.            ---------------------------------------
  750.    RETURN BOOLEAN is
  751.     flag : boolean ;
  752.     begin
  753.     inbuf.printer_char_rdy(i, flag) ;
  754.     RETURN flag ;
  755.     END ;
  756.  
  757.  
  758.   PROCEDURE get_next_character_from_telnet 
  759.             ------------------------------
  760.    (I : port_number;
  761.    char : OUT bit_count_8_type) is
  762.     begin
  763.     char := 0 ;
  764.     inbuf.get_printer_char(i, char) ;
  765.     end ;
  766.  
  767.   PROCEDURE send_char_to_telnet 
  768.             -------------------
  769.    (I :   IN port_number;
  770.    char : IN bit_count_8_type ) is
  771.     begin
  772.       inbuf.put_kbd_char(i, char) ;
  773.     end ;
  774.  
  775.  
  776.   FUNCTION there_is_room_in_the_keyboard_buffer (I : port_number) 
  777.            -----------------------------------
  778.    RETURN BOOLEAN IS
  779.   BEGIN
  780.     RETURN TRUE ;
  781.   END there_is_room_in_the_keyboard_buffer ; -- body
  782.      
  783.  
  784.  
  785.   BEGIN
  786.     NULL ; 
  787.   END virtual_terminal ; -- package body
  788.   
  789. --::::::::::::::
  790. --dec_tn_tasks_.ada
  791. --::::::::::::::
  792. -----------------------------------------------------------------------
  793. --
  794. --         DoD Protocols    NA-00004-200       80-01055-100(-)
  795. --         E-Systems, Inc.  August 07, 1985
  796. --
  797. --         DEC_TN_TASKS_.ADA       Author : Mike Thomas
  798. --
  799. -----------------------------------------------------------------------
  800.      
  801. -- authors : Mike Thomas, Paul Higgins
  802. -- file : tn_tasks
  803.      
  804.      
  805. --  6/13/85   8:30 PM : tasks mod to allow telnet to while hang on vax
  806. --  6/25/85   3:06 PM : tcp_reader remove stop entry
  807.      
  808. WITH with_ulp_communicate ;
  809. PACKAGE dec_tn_tasks IS
  810.      
  811. ------------------------ tasks for Dec Ada Vax version -------------------------
  812.      
  813.   TASK tn IS
  814.     PRAGMA PRIORITY(10) ;
  815.     ENTRY go ;
  816.     ENTRY wait ;
  817.   END tn ; -- ok to put name here? --TBD
  818.      
  819.      
  820.   TASK telnet_buffer IS
  821.     PRAGMA PRIORITY(9) ;
  822.     ENTRY put_tcp_message(tcp_message : IN  with_ulp_communicate.user_message) ;
  823.     ENTRY get_tcp_message(tcp_message : OUT with_ulp_communicate.user_message) ;
  824.     ENTRY tcp_message_ready(buf_not_empty : OUT BOOLEAN) ;
  825.   END telnet_buffer ;
  826.      
  827.      
  828.   TASK tcp_reader IS
  829.     PRAGMA PRIORITY(8) ;
  830.     ENTRY start ;
  831.   END tcp_reader ;
  832.      
  833.      
  834. END dec_tn_tasks ;
  835.      
  836. --::::::::::::::
  837. --ttyio_.ada
  838. --::::::::::::::
  839. -----------------------------------------------------------------------
  840. --
  841. --         DoD Protocols    NA-00004-200       80-01069-100(-)
  842. --         E-Systems, Inc.  August 07, 1985
  843. --
  844. --         TTYIO_.ADA       Author : Mike Thomas 
  845. --
  846. -----------------------------------------------------------------------
  847.  
  848. -- File ttyio    AUTHOR : Paul Higgins
  849.  
  850. --   5/4/85  2:09 PM : MODIFY FOR DEC ADA 
  851. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  852.  
  853. package iotasks is
  854.   task getchar IS
  855.    PRAGMA PRIORITY(6) ; -- try to lower it to keep it from hanging 
  856.   end getchar;
  857.   task putchar IS
  858.    PRAGMA PRIORITY(8) ; -- whole telnet program
  859.   end putchar;
  860. end  iotasks ;
  861.  
  862. --::::::::::::::
  863. --ttyio.ada
  864. --::::::::::::::
  865. -----------------------------------------------------------------------
  866. --
  867. --         DoD Protocols    NA-00004-200       80-01070-100(-)
  868. --         E-Systems, Inc.  August 07, 1985
  869. --
  870. --         TTYIO.ADA       Author : Mike Thomas 
  871. --
  872. -----------------------------------------------------------------------
  873.  
  874. -- File : ttyio    Author : Paul Higgins   
  875.  
  876. --   5/4/85  2:09 PM : MODIFY FOR DEC ADA 
  877. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  878. --  6/11/85  4:00 PM : modified for DEC Ada by Paul Higgins
  879. --  6/14/85  3:28 PM : dec telnet tasking mod (MT)
  880.  
  881.  
  882. with text_io ; use text_io ;
  883. with virtual_terminal; use virtual_terminal;
  884. with system ;
  885. with dec_tn_tasks ;
  886.  
  887. package body iotasks is
  888.  
  889. --&MT SUBTYPE bit_count_16_type IS INTEGER ; 
  890.   SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  891.  
  892. --&MT SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  893.   SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  894.   
  895. task body getchar is
  896.   a_char : character ;
  897.   a_var  : bit_count_8_type ;
  898.   cr     : bit_count_8_type := 13 ; -- ASCII.CR
  899.   len    : integer ;
  900.   a_str  : string (1..255) ;
  901. begin
  902.   loop
  903.     IF TEXT_IO.END_OF_LINE THEN
  904.       send_char_to_telnet(1,cr) ; -- text_io will not read in a ascii.cr
  905.       TEXT_IO.SKIP_LINE ; -- hop past end of line
  906.     ELSE
  907.       --TEL text_io.get(a_char) ;
  908.       --TEL a_var := character'pos(a_char) ;
  909.       --TEL send_char_to_telnet(1,a_var) ;
  910.       --&MT vax version:
  911.       text_io.get_line(a_str,len) ;
  912.       for i in 1..len loop                 
  913.         a_var := character'pos(a_str(i)) ;
  914.         send_char_to_telnet(1,a_var) ;
  915.      end loop ; --&MT vax
  916.      send_char_to_telnet(1,cr) ; -- replace cr stripped out by text_io.
  917.     END IF ; 
  918.     dec_tn_tasks.tn.go ; -- signal telnet controller that there is input
  919.   end loop ;
  920. end getchar ;
  921.  
  922. task body putchar is
  923.   a_char : character ;
  924.   a_var  : bit_count_8_type ;
  925. begin
  926.   loop
  927.     get_next_character_from_telnet(1,a_var) ;
  928.     IF bit_count_16_type(a_var) = 13 THEN -- CR ==> new line
  929.       TEXT_IO.NEW_LINE ; -- text_io will send cr lf
  930.     ELSE
  931.       a_char := character'val(a_var) ;
  932.       text_io.put(a_char) ;
  933.     END IF ;
  934.   end loop ;
  935. end putchar ;
  936.  
  937. end iotasks ;
  938. --::::::::::::::
  939. --auserdpac_.ada
  940. --::::::::::::::
  941. -----------------------------------------------------------------------
  942. --
  943. --         DoD Protocols    NA-00004-200       80-01051-100(-)
  944. --         E-Systems, Inc.  August 07, 1985
  945. --
  946. --         AUSERDPAC_.ADA       Author : Mike Thomas 
  947. --
  948. -----------------------------------------------------------------------
  949.  
  950.  
  951. -- File : auserdpac   Author : Mike Thomas
  952.  
  953. --   5/6/85  3:40 PM : MODIFY FOR DEC ADA 
  954. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  955.  
  956. --   5/21/85 3:55 PM : MODIFY FOR TELESOFT
  957. --                     OLD CODE (DEC) MARKED AS --&MT
  958.  
  959. --   5/22/85 9:20 AM : MODIFY FOR DEC ADA
  960. --                     OLD CODE MARKED AS --&MT
  961. --   6/11/85 5:14 PM : lcn changed from lcn_type to lcn_ptr_type
  962. --   6/23/85 9:38 PM : init ga_state to no go_ahead_sent
  963.  
  964. --&MT PRAGMA SOURCE_INFO(ON) ; -- ask TeleSoft to provide run-time error reports
  965. WITH SYSTEM ;
  966. WITH virtual_terminal ;
  967. WITH with_ulp_communicate ; -- access lcn_type
  968. WITH buffer_data ; -- access sixteen_bits type
  969.  
  970. PACKAGE user_data -- specification 
  971.         ---------
  972.  IS 
  973.  
  974. -- **********************  USER SPECIFICATION  ********************************
  975. -- 
  976. -- This package contains the user buffers
  977. -- and state information.  The state information types and the maximum
  978. -- user command length are also exported.
  979. -- 
  980. -- ****************************************************************************
  981.  
  982.   -----------------------  data (object) declarations  -----------------------
  983.  
  984.   --&MT SUBTYPE bit_count_16_type IS INTEGER ; 
  985.   SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  986.  
  987.   --&MT SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  988.   SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  989.  
  990.   -- state information maintained for each user
  991.   TYPE nvt_io_state_type IS (io_done, no_io_done) ;
  992.   TYPE communication_state_type IS (connection_established, 
  993.                                     no_connection_established) ;
  994.   TYPE command_state_type IS (partial_command, no_partial_command) ;
  995.   TYPE go_ahead_sent_state_type IS (go_ahead_sent, no_go_ahead_sent) ;
  996.   
  997.   -- maximum user command string length (might use in partial cmd)
  998.   max_cmd_length : CONSTANT bit_count_16_type := 80 ; -- arbitrary, make defered constant when supported
  999.   TYPE string_type IS ARRAY (bit_count_16_type RANGE <>) OF bit_count_8_type ;
  1000.   max_out_string : CONSTANT bit_count_16_type := 256 ; -- largest ucb buffer size
  1001.   SUBTYPE out_string_type IS string_type(1..max_out_string) ;
  1002.  
  1003.   -- buffer space maintained for each user
  1004.        
  1005.   SUBTYPE partial_command_buf_length IS 
  1006.    bit_count_16_type RANGE 0..max_cmd_length ;
  1007.   TYPE partial_cmd_buffer_type IS 
  1008.    ARRAY (1..max_cmd_length) OF bit_count_8_type ;
  1009.   TYPE partial_command_buffer_type IS 
  1010.     RECORD
  1011.       buffer : partial_cmd_buffer_type ;
  1012.       length : partial_command_buf_length := 0 ;
  1013.     END RECORD ;
  1014.     
  1015.   data_buffer_length   : CONSTANT bit_count_16_type := 100 ; -- arbitrary
  1016.   SUBTYPE data_buf_ptr IS bit_count_16_type RANGE 0..data_buffer_length - 1 ;
  1017.   TYPE data_buf_type IS ARRAY (0..data_buffer_length - 1) OF bit_count_8_type ;
  1018.   TYPE data_buffer_type IS
  1019.     RECORD
  1020.       buffer : data_buf_type ;
  1021.       buf_head : data_buf_ptr := 0 ;
  1022.       buf_tail : data_buf_ptr := 1 ;
  1023.     END RECORD ;
  1024. -------------------------------  option tables  -------------------------------
  1025.   TYPE option_type IS (echo,suppress_ga) ; -- list of all options currently supported
  1026.   number_of_options_supported : CONSTANT bit_count_16_type := 2 ;  
  1027.   TYPE option_array_type IS ARRAY (1..number_of_options_supported)
  1028.    OF option_type ;
  1029.   SUBTYPE option_count_type IS bit_count_16_type
  1030.    RANGE 0..number_of_options_supported ; 
  1031.  
  1032.   TYPE option_table_type IS 
  1033.     RECORD
  1034.       option          : option_array_type ;
  1035.       number_of_items : option_count_type := 0 ;
  1036.     END RECORD ;
  1037.  
  1038.   TYPE option_tables_type IS
  1039.     RECORD
  1040.       local_options_desired    : option_table_type ;
  1041.       local_options_pending    : option_table_type ;
  1042.       local_options_in_effect  : option_table_type ;
  1043.       remote_options_desired   : option_table_type ;
  1044.       remote_options_pending   : option_table_type ;
  1045.       remote_options_in_effect : option_table_type ;
  1046.     END RECORD ;
  1047.  
  1048. -- These structures contain buffers which are used to communicate with the
  1049. -- transport level.  The trans_input_buffer and trans_output_buffer are
  1050. -- tightly coupled to the transport level and contain both messages and data.
  1051. -- (after link-up to TCP these debug buffers will not be used)
  1052. -- The other buffers are loosely coupled and have exclusivly data or messages.
  1053. -- 
  1054. -- ****************************************************************************
  1055.  
  1056.   -- transport level input buffer containing messages and data 
  1057.   -- direct channel to TCP (actual form will change) -- this for debug
  1058.  
  1059. --MT  trans_in_buffer_length : CONSTANT bit_count_16_type := 512 ; -- arbitrary
  1060. --MT  SUBTYPE trans_in_buf_ptr IS bit_count_16_type 
  1061. --MT   RANGE 0..trans_in_buffer_length - 1 ;
  1062. --MT  TYPE trans_input_buffer_type IS ARRAY (0..trans_in_buffer_length - 1)
  1063. --MT   OF bit_count_8_type ;
  1064. --MT  TYPE trans_input_buffer_record IS 
  1065. --MT    RECORD
  1066. --MT      buffer : trans_input_buffer_type ;
  1067. --MT      buf_head : trans_in_buf_ptr := 0 ;
  1068. --MT      buf_tail : trans_in_buf_ptr := 1 ;
  1069. --MT    END RECORD ;
  1070.     
  1071.  
  1072.   -- transport level output buffer containing messages and data 
  1073.   -- direct channel to TCP (actual form will change) -- this for debug
  1074.  
  1075. --MT  trans_out_buffer_length : CONSTANT bit_count_16_type := 512 ; -- arbitrary
  1076. --MT  SUBTYPE trans_out_buf_length IS bit_count_16_type RANGE 0..trans_out_buffer_length ;
  1077. --MT  TYPE trans_output_buffer_type IS ARRAY (1..trans_out_buffer_length) 
  1078. --MT   OF bit_count_8_type ;
  1079. --MT  TYPE trans_output_buffer_record IS 
  1080. --MT    RECORD
  1081. --MT      buffer : trans_output_buffer_type ;
  1082. --MT      length : trans_out_buf_length := 0 ;
  1083. --MT    END RECORD ;
  1084.  
  1085.  
  1086.   -- transport level to telnet messages
  1087.   -- these buffers not "directly" connected to the transport level
  1088.  
  1089.   trans_to_telnet_msg_buffer_length : CONSTANT bit_count_16_type := 512 ; -- arbitrary
  1090.   SUBTYPE trans_to_telnet_msg_buf_ptr_type IS 
  1091.    bit_count_16_type RANGE 0..trans_to_telnet_msg_buffer_length - 1 ;
  1092.   TYPE trans_to_telnet_msg_buffer_type IS
  1093.    ARRAY (0..trans_to_telnet_msg_buffer_length - 1) OF bit_count_8_type ;
  1094.   TYPE trans_to_telnet_messages_record IS 
  1095.     RECORD
  1096.       buffer   : trans_to_telnet_msg_buffer_type ;
  1097.       buf_head : trans_to_telnet_msg_buf_ptr_type := 0 ;
  1098.       buf_tail : trans_to_telnet_msg_buf_ptr_type := 1 ;
  1099.     END RECORD ;
  1100.     
  1101.  
  1102.   -- transport level to telnet data
  1103.   -- these buffers not "directly" connected to the transport level
  1104.  
  1105.   trans_to_telnet_data_buffer_length : CONSTANT bit_count_16_type := 512 ; -- arbitrary
  1106.   SUBTYPE trans_to_telnet_data_buf_ptr_type IS 
  1107.    bit_count_16_type RANGE 0..trans_to_telnet_data_buffer_length - 1 ;
  1108.   TYPE trans_to_telnet_data_buffer_type IS
  1109.    ARRAY (0..trans_to_telnet_data_buffer_length - 1) OF bit_count_8_type ;
  1110.   TYPE trans_to_telnet_data_record IS 
  1111.     RECORD
  1112.       buffer   : trans_to_telnet_data_buffer_type ;
  1113.       buf_head : trans_to_telnet_data_buf_ptr_type := 0 ;
  1114.       buf_tail : trans_to_telnet_data_buf_ptr_type := 1 ;
  1115.     END RECORD ;
  1116.   
  1117.  
  1118.   TYPE ppl_trans_buffers_type IS
  1119.     RECORD  
  1120. --MT      trans_input_buffer       : trans_input_buffer_record ; -- debug
  1121. --MT      trans_output_buffer      : trans_output_buffer_record ; -- debug
  1122.  
  1123.       trans_to_telnet_messages : trans_to_telnet_messages_record ;
  1124.       trans_to_telnet_data     : trans_to_telnet_data_record ;
  1125.     END RECORD ;
  1126.  
  1127.   TYPE control_block_type IS -- (contains state information etc. for a user)
  1128.     RECORD
  1129.       port                      : virtual_terminal.port_number ;
  1130.       tl_port_number            : buffer_data.sixteen_bits ; -- transport level local port #
  1131.       lcn                       : with_ulp_communicate.lcn_ptr_type ; -- TCP local_connection_number
  1132.       NVT_IO_state              : NVT_IO_state_type := IO_done ;
  1133.       communication_state       : communication_state_type :=
  1134.                                    no_connection_established ;
  1135.       command_state             : command_state_type := no_partial_command ;
  1136.       GA_state                  : go_ahead_sent_state_type := no_go_ahead_sent ;
  1137.       GA_received               : BOOLEAN := FALSE ;
  1138.       synch_is_in_progress      : BOOLEAN := FALSE ;
  1139.       last_keybd_char_was_cmd   : BOOLEAN := FALSE ; 
  1140.       rcv_data_is_urgent        : BOOLEAN := FALSE ;
  1141.       last_data_char_rcv_not_cr : BOOLEAN := TRUE ;
  1142.       partial_command_buffer    : partial_command_buffer_type ;
  1143.       data_buffer               : data_buffer_type ;
  1144.       option_tables             : option_tables_type ;
  1145.       trans_buffers             : ppl_trans_buffers_type ;
  1146.     END RECORD ;
  1147.  
  1148.   user_control_block : control_block_type ;
  1149.  
  1150.   -------------------  end data (object) declarations  -----------------------
  1151.  
  1152.   ---------------  function/procedure (verb) specifications  -----------------
  1153.  
  1154.   -- partial command data buffer manipulation functions/procedures
  1155.  
  1156.   FUNCTION there_is_data_in_command_buffer -- specification
  1157.            -------------------------------
  1158.    RETURN BOOLEAN ;
  1159.   -- ***********************  USER SPECIFICATION  *****************************
  1160.   --
  1161.   -- This function returns true if there is data in the APL command buffer.
  1162.   -----------------------------------------------------------------------------
  1163.  
  1164.  
  1165.   FUNCTION there_is_room_in_command_buffer -- specification
  1166.            -------------------------------
  1167.    RETURN BOOLEAN ; -- room for a character
  1168.   -- ***********************  USER SPECIFICATION  *****************************
  1169.   --
  1170.   -- This function returns true if there is room for a character in the 
  1171.   -- APL command buffer.
  1172.   -----------------------------------------------------------------------------
  1173.  
  1174.  
  1175.   PROCEDURE put_char_in_command_buffer -- specificaton
  1176.             --------------------------
  1177.    (char : IN bit_count_8_type) ;
  1178.   -- ***********************  USER SPECIFICATION  *****************************
  1179.   --
  1180.   -- This procedure will add a character to the APL command buffer.  The
  1181.   -- user should make sure there is room in the buffer before calling this 
  1182.   -- procedure.  If the NVT output buffer is full, the character will be lost.
  1183.   -----------------------------------------------------------------------------
  1184.  
  1185.  
  1186.   PROCEDURE put_string_in_command_buffer -- specificaton
  1187.             ----------------------------
  1188.    (str : IN string_type) ;
  1189.   -- ***********************  USER SPECIFICATION  *****************************
  1190.   --
  1191.   -- This procedure will add characters to the APL command buffer.  If there
  1192.   -- is not enough room in the buffer for all the characters, then the 
  1193.   -- extra characters will be lost.
  1194.   -----------------------------------------------------------------------------
  1195.  
  1196.  
  1197.   PROCEDURE get_char_from_command_buffer -- specificaton
  1198.             ----------------------------
  1199.    (char : OUT bit_count_8_type) ;
  1200.   -- ***********************  USER SPECIFICATION  *****************************
  1201.   --
  1202.   -- This procedure returns the next character from the APL command buffer.
  1203.   -- The user should determine that there are characters in the buffer before 
  1204.   -- calling this procedure.  If the buffer is empty, this procedure will 
  1205.   -- return null. 
  1206.   -----------------------------------------------------------------------------
  1207.  
  1208.  
  1209.   PROCEDURE get_command_buffer -- specificaton
  1210.             ------------------
  1211.    (buffer : OUT out_string_type ;
  1212.     length : OUT bit_count_16_type) ;
  1213.   -- ***********************  USER SPECIFICATION  *****************************
  1214.   --
  1215.   -- This procedure returns the entire contents of the APL command buffer.
  1216.   -- The user should determine that there are characters in the buffer before 
  1217.   -- calling this procedure.  If the buffer is empty, this procedure will 
  1218.   -- return null. 
  1219.   -----------------------------------------------------------------------------
  1220.  
  1221.   -- data buffer manipulation functions/procedures
  1222.  
  1223.   FUNCTION there_is_data_in_data_buffer -- specification
  1224.            ----------------------------
  1225.    RETURN BOOLEAN ;
  1226.   -- ***********************  USER SPECIFICATION  *****************************
  1227.   --
  1228.   -- This function returns true if there is data in the APL data buffer.
  1229.   -----------------------------------------------------------------------------
  1230.  
  1231.  
  1232.   FUNCTION there_is_room_in_data_buffer -- specification
  1233.            ----------------------------
  1234.    RETURN BOOLEAN ; -- room for a character
  1235.   -- ***********************  USER SPECIFICATION  *****************************
  1236.   --
  1237.   -- This function returns true if there is room for a character in the 
  1238.   -- APL data buffer.
  1239.   -----------------------------------------------------------------------------
  1240.  
  1241.  
  1242.   PROCEDURE put_char_in_data_buffer -- specificaton
  1243.             -----------------------
  1244.    (char : IN bit_count_8_type) ;
  1245.   -- ***********************  USER SPECIFICATION  *****************************
  1246.   --
  1247.   -- This procedure will add a character to the APL data buffer.  The
  1248.   -- user should make sure there is room in the buffer before calling this 
  1249.   -- procedure.  If the NVT output buffer is full, the character will be lost.
  1250.   -----------------------------------------------------------------------------
  1251.  
  1252.  
  1253.   PROCEDURE put_string_in_data_buffer -- specificaton
  1254.             -------------------------
  1255.    (str : IN string_type) ;
  1256.   -- ***********************  USER SPECIFICATION  *****************************
  1257.   --
  1258.   -- This procedure will add characters to the data buffer.  If there
  1259.   -- is not enough room in the buffer for all the characters, the 
  1260.   -- excess characters will be lost.
  1261.   -----------------------------------------------------------------------------
  1262.  
  1263.  
  1264.   PROCEDURE get_char_from_data_buffer -- specificaton
  1265.             -------------------------
  1266.    (char : OUT bit_count_8_type) ;
  1267.   -- ***********************  USER SPECIFICATION  *****************************
  1268.   --
  1269.   -- This procedure returns the next character from the APL data buffer.
  1270.   -- The user should determine that there are characters in the buffer before 
  1271.   -- calling this procedure.  If the buffer is empty, this procedure will 
  1272.   -- return null. 
  1273.   -----------------------------------------------------------------------------
  1274.  
  1275.  
  1276.   PROCEDURE get_data_buffer -- specificaton
  1277.             ---------------
  1278.    (buffer : OUT out_string_type ;
  1279.     length : OUT bit_count_16_type) ;
  1280.   -- ***********************  USER SPECIFICATION  *****************************
  1281.   --
  1282.   -- This procedure returns the entire contents of the APL data buffer.
  1283.   -- The user should determine that there are characters in the buffer before 
  1284.   -- calling this procedure.  If the buffer is empty, this procedure will 
  1285.   -- return null. 
  1286.   -----------------------------------------------------------------------------
  1287.  
  1288.  
  1289.   PROCEDURE get -- specification
  1290.             ---
  1291.    (user_control_block_out : OUT control_block_type) ;
  1292.     -- **********************  USER SPECIFICATION  ****************************
  1293.     -- 
  1294.     -- This procedure returns the contents of the entire user control block
  1295.     -- which contains state information and buffers for the TELNET user.
  1296.     -------------------------------------------------------------------------
  1297.  
  1298.  
  1299.   PROCEDURE put -- specification
  1300.             ---
  1301.    (user_control_block_in : IN control_block_type) ;
  1302.     -- **********************  USER SPECIFICATION  ****************************
  1303.     -- 
  1304.     -- This procedure assigns the contents of the entire user control block
  1305.     -- which contains state information and buffers for the TELNET user.
  1306.     -------------------------------------------------------------------------
  1307.  
  1308.  
  1309.  
  1310.     PROCEDURE reset_user_control_block ;
  1311.               ------------------------
  1312.     -- **********************  USER SPECIFICATION  ****************************
  1313.     -- 
  1314.     -- This procedure resets the user control block as a result of a connection
  1315.     -- closing due to abort or a normal close.
  1316.     ---------------------------------------------------------------------------
  1317.  
  1318.  
  1319.   -----------  end function/procedure (verb) specifications  -----------------
  1320.  
  1321. END user_data ; -- package specification 
  1322.  
  1323. --::::::::::::::
  1324. --auserdpac.ada
  1325. --::::::::::::::
  1326. -----------------------------------------------------------------------
  1327. --
  1328. --         DoD Protocols    NA-00004-200       80-01052-100(-)
  1329. --         E-Systems, Inc.  August 07, 1985
  1330. --
  1331. --         AUSERDPAC.ADA       Author : Mike Thomas 
  1332. --
  1333. -----------------------------------------------------------------------
  1334.  
  1335.  
  1336. -- File : auserdpac   Author : Mike Thomas
  1337.  
  1338. --    5/6/85   3:40 PM : MODIFY FOR DEC ADA 
  1339. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  1340.  
  1341. --   5/21/85   3:55 PM : MODIFY FOR TELESOFT
  1342. --                     OLD CODE (DEC) MARKED AS --&MT
  1343.  
  1344. --   5/22/85   9:20 AM : MODIFY FOR DEC ADA
  1345. --                     OLD CODE MARKED AS --&MT
  1346. --   6/26/85  10:17 AM : reset ga_state to no_go_ahead_sent
  1347. --   7/20/85   4:32 PM : don't reset desired options table in reset procedure
  1348.  
  1349.  
  1350. WITH debug_io ;
  1351.  
  1352. PACKAGE BODY user_data 
  1353.              ---------
  1354.  IS
  1355.  
  1356.   -- partial command data buffer manipulation functions/procedures
  1357.  
  1358.   FUNCTION there_is_data_in_command_buffer -- body
  1359.            -------------------------------
  1360.    RETURN BOOLEAN IS
  1361.   BEGIN
  1362.     RETURN user_control_block.partial_command_buffer.length /= 0 ;
  1363.   END there_is_data_in_command_buffer ; -- body
  1364.  
  1365.  
  1366.   FUNCTION there_is_room_in_command_buffer -- body -- room for a character
  1367.            -------------------------------
  1368.    RETURN BOOLEAN IS 
  1369.   BEGIN
  1370.     RETURN user_control_block.partial_command_buffer.length < max_cmd_length ;
  1371.   END there_is_room_in_command_buffer ; -- body
  1372.  
  1373.  
  1374.   PROCEDURE put_char_in_command_buffer -- body
  1375.             --------------------------
  1376.    (char : IN bit_count_8_type) IS
  1377.  
  1378.     length : partial_command_buf_length RENAMES
  1379.      user_control_block.partial_command_buffer.length ;
  1380.     buffer : partial_cmd_buffer_type RENAMES
  1381.      user_control_block.partial_command_buffer.buffer ;
  1382.  
  1383.   BEGIN
  1384.     IF there_is_room_in_command_buffer THEN
  1385.       length := length + 1 ;
  1386.       buffer(length) := char ;
  1387.     END IF ; 
  1388.   END put_char_in_command_buffer ; -- body
  1389.   
  1390.  
  1391.   PROCEDURE put_string_in_command_buffer -- body
  1392.             ----------------------------
  1393.    (str : IN string_type) IS
  1394.   BEGIN
  1395.     FOR index IN str'RANGE LOOP
  1396.       put_char_in_command_buffer(str(index)) ;
  1397.     END LOOP ;
  1398.   END put_string_in_command_buffer ; -- body
  1399.  
  1400.  
  1401.   PROCEDURE get_char_from_command_buffer -- body
  1402.             ----------------------------
  1403.    (char : OUT bit_count_8_type) IS
  1404.  
  1405.     length : partial_command_buf_length RENAMES
  1406.      user_control_block.partial_command_buffer.length ;
  1407.     buffer : partial_cmd_buffer_type RENAMES
  1408.      user_control_block.partial_command_buffer.buffer ;
  1409.  
  1410.   BEGIN
  1411.     char := 0 ;
  1412.     IF there_is_data_in_command_buffer THEN
  1413.       char := buffer(1) ;
  1414.       buffer(1..length - 1) := buffer(2..length) ;
  1415.       length := length - 1 ;
  1416.     END IF ;
  1417.   END get_char_from_command_buffer ; -- body
  1418.   
  1419.  
  1420.   PROCEDURE get_command_buffer -- body
  1421.             ------------------
  1422.    (buffer : OUT out_string_type ;
  1423.     length : OUT bit_count_16_type) IS
  1424.  
  1425.     cmd_length : partial_command_buf_length RENAMES
  1426.      user_control_block.partial_command_buffer.length ;
  1427.     cmd_buffer : partial_cmd_buffer_type RENAMES
  1428.      user_control_block.partial_command_buffer.buffer ;
  1429.     buffer_length : CONSTANT bit_count_16_type := cmd_length ;
  1430.  
  1431.   BEGIN
  1432.     length := cmd_length ;
  1433.     cmd_length := 0 ;
  1434.     FOR index IN 1..buffer_length LOOP
  1435.       buffer(index):= cmd_buffer(index) ;
  1436.     END LOOP ;
  1437.   END get_command_buffer ; -- body
  1438.  
  1439.   -- data buffer manipulation functions/procedures
  1440.  
  1441.   FUNCTION there_is_data_in_data_buffer -- body
  1442.            ----------------------------
  1443.    RETURN BOOLEAN IS
  1444.     data : data_buffer_type RENAMES user_control_block.data_buffer ;
  1445.   BEGIN
  1446.     RETURN (data.buf_head + 1) MOD data_buffer_length /= data.buf_tail ;
  1447.   END there_is_data_in_data_buffer ; -- body
  1448.  
  1449.  
  1450.   FUNCTION there_is_room_in_data_buffer -- body (room for a character)
  1451.            ----------------------------
  1452.    RETURN BOOLEAN IS
  1453.     data : data_buffer_type RENAMES user_control_block.data_buffer ;
  1454.   BEGIN
  1455.     RETURN data.buf_head /= data.buf_tail ;
  1456.   END there_is_room_in_data_buffer ; -- body
  1457.  
  1458.  
  1459.   PROCEDURE put_char_in_data_buffer -- body
  1460.             -----------------------
  1461.    (char : IN bit_count_8_type) IS
  1462.     data : data_buffer_type RENAMES user_control_block.data_buffer ;
  1463.   BEGIN
  1464.     IF there_is_room_in_data_buffer THEN
  1465.       data.buffer(data.buf_tail) := char ;
  1466.       data.buf_tail := (data.buf_tail + 1) MOD data_buffer_length ;
  1467.     END IF ; 
  1468.   END put_char_in_data_buffer ; -- body
  1469.  
  1470.  
  1471.   PROCEDURE put_string_in_data_buffer -- body
  1472.             -------------------------
  1473.    (str : IN string_type) IS
  1474.   BEGIN
  1475.     FOR index IN str'RANGE LOOP
  1476.       put_char_in_data_buffer(str(index)) ;
  1477.     END LOOP ;
  1478.   END put_string_in_data_buffer ; -- body
  1479.  
  1480.  
  1481.   PROCEDURE get_char_from_data_buffer -- body
  1482.             -------------------------
  1483.    (char : OUT bit_count_8_type) IS
  1484.     data : data_buffer_type RENAMES user_control_block.data_buffer ;
  1485.   BEGIN
  1486.     char := 0 ;
  1487.     IF there_is_data_in_data_buffer THEN
  1488.       data.buf_head := (data.buf_head + 1) MOD data_buffer_length ;
  1489.       char := data.buffer(data.buf_head) ;
  1490.     END IF ;
  1491.   END get_char_from_data_buffer ; -- body
  1492.  
  1493.  
  1494.   PROCEDURE get_data_buffer -- body
  1495.             ---------------
  1496.    (buffer : OUT out_string_type ;
  1497.     length : OUT bit_count_16_type) IS
  1498.     data : data_buffer_type RENAMES user_control_block.data_buffer ;
  1499.  
  1500.     buffer_length : bit_count_16_type := 0 ;
  1501.  
  1502.   BEGIN
  1503.     WHILE (data.buf_head + 1) MOD data_buffer_length /= data.buf_tail LOOP
  1504.       data.buf_head := (data.buf_head + 1) MOD data_buffer_length ; 
  1505.       buffer_length := buffer_length + 1 ;
  1506.       buffer(buffer_length) := data.buffer(data.buf_head) ;
  1507.     END LOOP ;
  1508.     length := buffer_length ;
  1509.   END get_data_buffer ; -- body
  1510.  
  1511.  
  1512.  
  1513.   PROCEDURE get -- body
  1514.             ---
  1515.    (user_control_block_out : OUT control_block_type) IS
  1516.   BEGIN
  1517.     user_control_block_out := user_control_block ;
  1518.   END get ; -- body
  1519.  
  1520.  
  1521.   PROCEDURE put -- body
  1522.             ---
  1523.    (user_control_block_in : IN control_block_type) IS
  1524.   BEGIN
  1525.     user_control_block := user_control_block_in ;
  1526.   END put ; -- body
  1527.  
  1528.  
  1529.   PROCEDURE reset_user_control_block IS
  1530.             ------------------------
  1531.     ucb : control_block_type RENAMES user_control_block ;
  1532.   BEGIN -- restore default values
  1533.     ucb.nvt_io_state                         := io_done ;
  1534.     ucb.communication_state                  := no_connection_established ;
  1535.     ucb.command_state                        := no_partial_command ;
  1536.     ucb.ga_state                             := no_go_ahead_sent ;
  1537.     ucb.ga_received                          := FALSE ;
  1538.     ucb.synch_is_in_progress                 := FALSE ;
  1539.     ucb.last_keybd_char_was_cmd              := FALSE ;
  1540.     ucb.rcv_data_is_urgent                   := FALSE ;
  1541.     ucb.last_data_char_rcv_not_cr            := TRUE ;
  1542.     ucb.partial_command_buffer.length        := 0 ;
  1543.     ucb.option_tables.local_options_pending.number_of_items    := 0 ;
  1544.     ucb.option_tables.local_options_in_effect.number_of_items  := 0 ;
  1545.     ucb.option_tables.remote_options_pending.number_of_items   := 0 ;
  1546.     ucb.option_tables.remote_options_in_effect.number_of_items := 0 ;
  1547.   END reset_user_control_block ;
  1548.  
  1549.  
  1550. BEGIN -- user_data
  1551.   NULL ;
  1552. EXCEPTION
  1553.   WHEN OTHERS =>
  1554.     debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN user_data instantiation") ;
  1555.     RAISE ;
  1556.  
  1557. END user_data ; -- package body
  1558. --::::::::::::::
  1559. --dec_tn_tasks.ada
  1560. --::::::::::::::
  1561. -----------------------------------------------------------------------
  1562. --
  1563. --         DoD Protocols    NA-00004-200       80-01056-100(-)
  1564. --         E-Systems, Inc.  August 07, 1985
  1565. --
  1566. --         DEC_TN_TASKS.ADA       Author : Mike Thomas
  1567. --
  1568. -----------------------------------------------------------------------
  1569. -- FILE : DEC_TN_TASKS         AUTHOR MIKE THOMAS AND PAUL HIGGINS
  1570. --  6/17/85  4:46 PM : ADD TN.GO TO PUT_TCP_MESSAGE
  1571. --  6/25/85  2:50 PM : have tcp_reader stop reading on Rx of close (#18)
  1572. --  6/27/85  1:56 PM : ...and abort_ok(#8) and connection_reset(#16)
  1573. --   7/1/85  9:52 AM : ...and time out(#24)
  1574.      
  1575. WITH user_data ;
  1576. USE  user_data ;
  1577. WITH DEBUG_IO ;
  1578. WITH TEXT_IO ;
  1579. WITH SYSTEM ;
  1580. USE SYSTEM ;
  1581. PACKAGE BODY dec_tn_tasks IS
  1582.      
  1583.   SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  1584.      
  1585.   TASK BODY tn IS --*********************** TN ********************************
  1586.     count : bit_count_8_type RANGE 0..255 := 0 ;
  1587.   BEGIN
  1588.     LOOP
  1589.       SELECT
  1590.         ACCEPT go DO
  1591.           count := count + 1 ;
  1592.         END go ;
  1593.       OR
  1594.         WHEN count > 0 =>
  1595.           ACCEPT wait DO
  1596.             count := count - 1 ;
  1597.           END wait ;
  1598.       END SELECT ;
  1599.     END LOOP ;
  1600.     EXCEPTION
  1601.       WHEN OTHERS =>
  1602.         TEXT_IO.PUT_LINE("EXCEPTION IN TASK TN.") ;
  1603.         DEBUG_IO.PUT_LINE("EXCEPTION IN TASK TN.") ;
  1604.         RAISE ;
  1605.   END tn ;
  1606.      
  1607.      
  1608.   TASK BODY telnet_buffer IS --************ telnet_buffer *********************
  1609.     message_buf : with_ulp_communicate.user_message ;
  1610.     room_in_buffer : BOOLEAN := TRUE ;
  1611.   BEGIN
  1612.     LOOP
  1613.       SELECT
  1614.         WHEN room_in_buffer =>
  1615.           ACCEPT put_tcp_message
  1616.                   (tcp_message : IN with_ulp_communicate.user_message) DO
  1617.             message_buf := tcp_message ;
  1618.             room_in_buffer := FALSE ;
  1619.             tn.go ;
  1620.           END put_tcp_message ;
  1621.       OR
  1622.         WHEN NOT(room_in_buffer) =>
  1623.           ACCEPT get_tcp_message
  1624.                   (tcp_message : OUT with_ulp_communicate.user_message) DO
  1625.             tcp_message := message_buf ;
  1626.             room_in_buffer := TRUE ;
  1627.           END get_tcp_message ;
  1628.       OR
  1629.         ACCEPT tcp_message_ready(buf_not_empty : OUT BOOLEAN) DO
  1630.           buf_not_empty := NOT(room_in_buffer) ;
  1631.         END tcp_message_ready ;
  1632.       END SELECT ;
  1633.     END LOOP ;
  1634.     EXCEPTION
  1635.       WHEN OTHERS =>
  1636.         TEXT_IO.PUT_LINE("EXCEPTION IN TASK TELNET_BUFFER") ;
  1637.         DEBUG_IO.PUT_LINE("EXCEPTION IN TASK TELNET_BUFFER") ;
  1638.         RAISE ;
  1639.   END telnet_buffer ;
  1640.      
  1641.      
  1642.   TASK BODY tcp_reader IS --****************** tcp_reader *********************
  1643.     message_from_tcp  : with_ulp_communicate.user_message ;
  1644.     done              : BOOLEAN ;
  1645.     ok_on_abort       : CONSTANT bit_count_16_type :=  8 ; -- tcp abort message
  1646.     connection_reset  : CONSTANT bit_count_16_type := 16 ; -- tcp reset message
  1647.     connection_closed : CONSTANT bit_count_16_type := 18 ; -- tcp closed message
  1648.     time_out          : CONSTANT bit_count_16_type := 24 ; -- tcp time_out messa
  1649.   BEGIN
  1650.     loop
  1651.       accept start ;
  1652.       done := false ;
  1653.       while not done LOOP
  1654.         message_from_tcp.local_connection_name :=
  1655.          user_data.user_control_block.lcn ;
  1656.         -- this will hang until a message is available...
  1657.         with_ulp_communicate.wait_for_tcp_message(message_from_tcp) ;
  1658.         telnet_buffer.put_tcp_message(message_from_tcp) ;
  1659.         IF (message_from_tcp.message_number = connection_closed) OR
  1660.            (message_from_tcp.message_number = time_out) OR
  1661.            (message_from_tcp.message_number = connection_reset) OR
  1662.            (message_from_tcp.message_number = ok_on_abort) THEN
  1663.           done := true ; -- don't read from non-existant mailbox
  1664.         END IF ;
  1665.       END LOOP ;
  1666.     end loop ;
  1667.     EXCEPTION
  1668.       WHEN OTHERS =>
  1669.         TEXT_IO.PUT_LINE("EXCEPTION IN TASK TCP_READER.") ;
  1670.         DEBUG_IO.PUT_LINE("EXCEPTION IN TASK TCP_READER.") ;
  1671.         RAISE ;
  1672.   END tcp_reader ;
  1673.      
  1674. BEGIN
  1675.   NULL ;
  1676.   EXCEPTION
  1677.     WHEN OTHERS =>
  1678.       TEXT_IO.PUT_LINE("EXCEPTION IN PACKAGE INSTANTIATION DEC_TN_TASKS") ;
  1679.       DEBUG_IO.PUT_LINE("EXCEPTION IN PACKAGE INSTANTIATION DEC_TN_TASKS") ;
  1680.       RAISE ;
  1681. END dec_tn_tasks ;
  1682.      
  1683. --::::::::::::::
  1684. --pvirtlpac_.ada
  1685. --::::::::::::::
  1686. -----------------------------------------------------------------------
  1687. --
  1688. --         DoD Protocols    NA-00004-200       80-01061-100(-)
  1689. --         E-Systems, Inc.  August 07, 1985
  1690. --
  1691. --         PVIRTLPAC_.ADA       Author : Mike Thomas 
  1692. --
  1693. -----------------------------------------------------------------------
  1694.  
  1695. -- File pvirtlpac
  1696.  
  1697. --   5/7/85  9:10 AM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS 
  1698. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  1699. --  5/28/85 11:18 AM : mods for new_ncommu interface : lcn : lcn_type/lcn_ptr_type
  1700. --           3:12 PM : mods for new tcp interface
  1701. --  5/29/85  2:06 PM : mod to use Tele-lie Ada
  1702.  
  1703. --&MT OMIT NEXT LINE FOR DEC
  1704. --&MT PRAGMA SOURCE_INFO (ON) ;
  1705. WITH SYSTEM ; -- to access byte TYPE (8 bits)
  1706. USE SYSTEM ;
  1707. WITH user_data ; 
  1708. WITH with_ulp_communicate ;
  1709. USE  with_ulp_communicate ;
  1710. WITH buffer_data ;
  1711. USE  buffer_data ;
  1712.  
  1713. PACKAGE virtual_transport_level -- specification
  1714.         -----------------------
  1715.  IS
  1716.  
  1717. -- ************************  USER SPECIFICATION  ****************************
  1718. --
  1719. -- A procedure will convert the desired transport level service call to the 
  1720. -- proper syntax for the actual transport level inplementation (TCP) and
  1721. -- have the transport level process that service call.  It will provide
  1722. -- functions to determine if there are messages and input available from the 
  1723. -- transport level.   It will get messages and input from the actual transport
  1724. -- level.  Messages are considered to be information from the local
  1725. -- transport level as apposed to input from the transport level which is
  1726. -- simply relayed data from the remote connection.
  1727. -- 
  1728. -- *************************************************************************
  1729.  
  1730. -------------------------  data specifications  ----------------------------
  1731.  
  1732.   --&MT SUBTYPE bit_count_32_type IS LONG_INTEGER ; 
  1733.   SUBTYPE bit_count_32_type IS INTEGER ;
  1734.  
  1735.   --&MT SUBTYPE bit_count_16_type IS INTEGER ; 
  1736.   SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  1737.  
  1738.   --&MT SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  1739.   SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  1740.  
  1741.   TYPE transport_level_service_call_type IS 
  1742.    (TL_open, TL_send, TL_receive, TL_close, TL_status, TL_abort) ;
  1743.  
  1744.   max_msg_length : CONSTANT bit_count_16_type := 256 ; -- arbitrary
  1745.   TYPE message_type IS ARRAY (1..max_msg_length) OF bit_count_8_type ;
  1746.   TYPE info_output_type IS ARRAY (bit_count_16_type RANGE <>) OF bit_count_8_type ;  
  1747.   SUBTYPE input_type IS bit_count_8_type ;
  1748.  
  1749.   TYPE service_call_parameters_type
  1750.    (service_call : transport_level_service_call_type) IS
  1751.     RECORD
  1752.       CASE service_call IS
  1753.         WHEN TL_send =>
  1754.           urgent_flag : BOOLEAN ;
  1755.           info_length : bit_count_16_type RANGE 1..max_msg_length ;
  1756.           info        : info_output_type(1..max_msg_length) ;
  1757.         WHEN TL_open =>
  1758.           network_number      : bit_count_16_type := 10 ; 
  1759.           host_number         : bit_count_16_type := 0 ; 
  1760.           logical_host_number : bit_count_16_type := 0 ; 
  1761.           imp_number          : bit_count_16_type := 0 ; 
  1762.           port_number         : bit_count_16_type := 23 ;
  1763.         WHEN OTHERS =>
  1764.           NULL ;
  1765.        END CASE ;
  1766.      END RECORD ;
  1767.  
  1768.   -------------------  subprogram specifications  ---------------------------
  1769.  
  1770.   FUNCTION there_is_a_message  -- specification
  1771.            ------------------
  1772.    RETURN BOOLEAN ;
  1773.   -- *************************  USER SPECIFICATION  ***************************
  1774.   --
  1775.   -- This function returns true if there is a message available from 
  1776.   -- the transport level.  A message is considered to be information 
  1777.   -- originating at the local transport level.
  1778.   -------------------------------------------------------------------------
  1779.  
  1780.  
  1781.   FUNCTION there_is_input  -- specification
  1782.            --------------
  1783.    RETURN BOOLEAN ;
  1784.   -- *************************  USER SPECIFICATION  ***************************
  1785.   --
  1786.   -- This function returns true if there is data available from the remote
  1787.   -- TELNET.
  1788.   -------------------------------------------------------------------------
  1789.     
  1790.     
  1791.   PROCEDURE get_message -- specification
  1792.             -----------
  1793.    (message : OUT message_type ;
  1794.     length  : OUT bit_count_16_type) ;
  1795.   -- *************************  USER SPECIFICATION  ***************************
  1796.   --
  1797.   -- This procedure returns the next message from the local transport level. 
  1798.   -- A message is considered to be information originating at the local 
  1799.   -- transport level.
  1800.   -----------------------------------------------------------------------------
  1801.     
  1802.     
  1803.   PROCEDURE get_input -- specification
  1804.             ---------
  1805.    (input           : OUT input_type ;
  1806.     tcp_urgent_flag : OUT BOOLEAN) ;
  1807.   -- *************************  USER SPECIFICATION  ***************************
  1808.   --
  1809.   -- This procedure returns the next data item relayed from the remote
  1810.   -- telnet and indicates if it is urgent.
  1811.   -----------------------------------------------------------------------------
  1812.  
  1813.  
  1814.   FUNCTION there_is_room_for_info_output -- specification
  1815.            -----------------------------
  1816.    RETURN BOOLEAN ;
  1817.   -- *************************  USER SPECIFICATION  ***************************
  1818.   --
  1819.   -- This procedure returns TRUE if there is buffer room for information
  1820.   -- to be sent to the local transport level.
  1821.   -----------------------------------------------------------------------------
  1822.  
  1823.  
  1824.   PROCEDURE send_data -- specification
  1825.             ---------
  1826.    (data : IN info_output_type ;
  1827.     urgent_flag : IN BOOLEAN) ;
  1828.   -- ***********************  USER SPECIFICATION  ***************************
  1829.   --
  1830.   -- This procedure sends data to the remote TELNET by presenting it to the
  1831.   -- local transport level as data and indicating if it is urgent. 
  1832.   ---------------------------------------------------------------------------
  1833.  
  1834.  
  1835.   PROCEDURE send_message -- specification
  1836.             ------------
  1837.    (message : IN info_output_type) ;
  1838.   -- *************************  USER SPECIFICATION  ***************************
  1839.   --
  1840.   -- This procedure sends a message to the local transport level.
  1841.   -----------------------------------------------------------------------------
  1842.  
  1843.  
  1844.   PROCEDURE convert_service_call_to_transport_level_syntax -- specification
  1845.             ----------------------------------------------
  1846.    (service_call : IN transport_level_service_call_type ;
  1847.     parameter   : IN service_call_parameters_type) ;
  1848.   -- *************************  USER SPECIFICATION  ***************************
  1849.   --
  1850.   -- The transport level service call is converted into the syntax
  1851.   -- for a call to the actual transport level and that service is
  1852.   -- requested.  The user's APL buffers and state information are used.
  1853.   -----------------------------------------------------------------------------
  1854.     
  1855. END virtual_transport_level ; -- package specification
  1856.  
  1857.  
  1858. --::::::::::::::
  1859. --pvirtlpac.ada
  1860. --::::::::::::::
  1861. -----------------------------------------------------------------------
  1862. --
  1863. --         DoD Protocols    NA-00004-200       80-01062-100(-)
  1864. --         E-Systems, Inc.  August 07, 1985
  1865. --
  1866. --         PVIRTLPAC.ADA       Author : Mike Thomas 
  1867. --
  1868. -----------------------------------------------------------------------
  1869.  
  1870. -- File pvirtlpac
  1871.  
  1872. --   5/7/85  9:10 AM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS 
  1873. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  1874. --  5/28/85 11:18 AM : mods for new_ncommu interface : lcn : lcn_type/lcn_ptr_type
  1875. --           3:12 PM : mods for new tcp interface
  1876. --  5/29/85  2:06 PM : mod to use Tele-lie Ada
  1877. --  6/11/85  5:29 PM : mods for new TCP interface (lcn)
  1878. --  6/12/85  9:57 AM : ditto
  1879. --  6/14/85  3:40 PM : mods for tasking
  1880. --  6/17/85 11:30 AM : use imp_number for local port on passive open for test
  1881. --  6/19/85  1:54 PM : save lcn after active open
  1882. --  6/20/85  1:54 PM : tcp_reader kick off upon opens 
  1883. --           3:56 PM : after opens, replace recieve with another (see 14)
  1884. --           6:20 PM : in 14, use lcn_ptr instead of record
  1885. --  6/21/85  3:21 PM : fixed bug in send data to tcp 
  1886. --  6/23/85  4:08 PM : alter send and receive tcp pointers
  1887. --  6/24/85  2:07 PM : only do passive open for server_telnet (tl_port#=0)
  1888. --  6/25/85  3:14 PM : omit tcp_reader.stop 
  1889. --           4:23 PM : put dummy params in passive open from -1 to 0
  1890. --  6/26/85 10:24 AM : put print stm in passive open, omit state set on close
  1891. --  6/27/85  1:43 PM : mods for reset
  1892. --   7/1/85  9:48 AM : treat time out as a close
  1893. --           3:56 PM : call buffree after processing tcp data (#10 | #19)
  1894.  
  1895. WITH debug_io ;
  1896. WITH dec_tn_tasks ;
  1897.  
  1898. PACKAGE BODY virtual_transport_level IS -- body
  1899.              -----------------------
  1900. -- ****************************************************************************
  1901. -- Note : Generics could be used to take advantage of the comonality of 
  1902. -- processing when supported by the compiler.
  1903. -------------------------------------------------------------------------------
  1904.  
  1905.   message_from_tcp : user_message ;
  1906.   lcn : with_ulp_communicate.lcn_ptr_type RENAMES
  1907.    user_data.user_control_block.lcn ;
  1908.   tl_data_is_urgent : BOOLEAN RENAMES
  1909.    user_data.user_control_block.rcv_data_is_urgent ; -- transport level data is urgent flag
  1910.   -- could be converted to urgent data byte count if convenient later...
  1911.   last_char_was_not_cr : BOOLEAN RENAMES
  1912.   user_data.user_control_block.last_data_char_rcv_not_cr ; -- flag for data characters
  1913.   request_ok : BOOLEAN ;
  1914.   lcn_record : with_ulp_communicate.lcn_ptr_type ;
  1915.  
  1916.   FUNCTION there_is_information_from_the_transport_level
  1917.            ---------------------------------------------
  1918.    RETURN BOOLEAN IS
  1919.     message_ready : BOOLEAN ;
  1920.   BEGIN
  1921.     message_from_tcp.local_connection_name := lcn ;
  1922.  
  1923. --&MT    wait_for_tcp_message(message_from_tcp) ; -- FOR TELESOFT ADA ON WICAT
  1924.     dec_tn_tasks.telnet_buffer.tcp_message_ready(message_ready) ;--&MT FOR DEC ADA
  1925.     IF message_ready THEN                                             --&MT 
  1926.       dec_tn_tasks.telnet_buffer.get_tcp_message(message_from_tcp) ;  --&MT
  1927.     ELSE                                                              --&MT
  1928.       RETURN FALSE ;                                                  --&MT
  1929.     END IF ;                                                          --&MT
  1930.  
  1931.     IF message_from_tcp.message_number = -1 THEN
  1932.       RETURN FALSE ;
  1933.     END IF ;
  1934.     RETURN TRUE ;
  1935.   END there_is_information_from_the_transport_level ;
  1936.  
  1937.  
  1938.   PROCEDURE store_message (message : IN STRING) IS -- (local procedure)
  1939.             -------------
  1940.     tl_msg : user_data.trans_to_telnet_messages_record RENAMES
  1941.      user_data.user_control_block.trans_buffers.trans_to_telnet_messages ;
  1942.     msg_buf_length : CONSTANT bit_count_16_type := 
  1943.      user_data.trans_to_telnet_msg_buffer_length ;
  1944.   BEGIN
  1945.     debug_io.put_line("  in pvirtlpac.store_message(s)") ;
  1946.     debug_io.put("message ==>") ;
  1947.     debug_io.put_line(message(1..message'LENGTH)) ;
  1948.     FOR index IN 1..message'LENGTH LOOP
  1949.       tl_msg.buffer(tl_msg.buf_tail) := 
  1950.        bit_count_8_type(CHARACTER'POS(message(index))) ;
  1951.       tl_msg.buf_tail := (tl_msg.buf_tail + 1) MOD msg_buf_length ;
  1952.     END LOOP ;
  1953.       tl_msg.buffer(tl_msg.buf_tail) := 13 ; -- ascii.cr
  1954.       tl_msg.buf_tail := (tl_msg.buf_tail + 1) MOD msg_buf_length ;
  1955.     debug_io.put_line("  end pvirtlpac.store_message(s)") ;
  1956.     EXCEPTION
  1957.       WHEN OTHERS =>
  1958.         DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.STORE_MESSAGE(s)") ;
  1959.         RAISE ;
  1960.   END store_message ;
  1961.  
  1962.  
  1963.   PROCEDURE get_and_process_information_from_the_transport_level IS
  1964.             ----------------------------------------------------
  1965.  
  1966.     PROCEDURE store_message (number : IN bit_count_32_type) IS
  1967.               -------------
  1968.       digit : bit_count_16_type RANGE 0..9 ;
  1969.       num   : bit_count_32_type := number ;
  1970.       number_string : STRING (1..20) ;
  1971.       num_digits : bit_count_32_type RANGE 0..19 := 0 ;
  1972.       --&MT num_digits : bit_count_16_type RANGE 0..19 := 0 ;
  1973.     BEGIN
  1974.       debug_io.put_line("  in pvirtlpac.store_message(i)") ;
  1975.       IF number > 0 THEN
  1976.         WHILE num > 0 LOOP
  1977.           debug_io.put("number=") ;
  1978.           debug_io.put_line(bit_count_16_type(number)) ;
  1979.           digit := bit_count_16_type(num - (num/bit_count_32_type(10)) * bit_count_32_type(10)) ; -- extract next digit
  1980.           debug_io.put("digit=") ;
  1981.           debug_io.put_line(digit) ;
  1982.           num := num / bit_count_32_type(10) ;
  1983.           number_string(20 - num_digits) := CHARACTER'VAL(digit+16#30#) ;
  1984.           debug_io.put("digit_char =") ;
  1985.           debug_io.put_line(number_string(20 - num_digits)) ;
  1986.           num_digits := num_digits + 1 ;
  1987.           debug_io.put("num_digits=") ;
  1988.           debug_io.put_line(bit_count_16_type(num_digits)) ;
  1989.         END LOOP ;
  1990.         number_string(1..num_digits) := number_string(21-num_digits..20) ;
  1991.       ELSE
  1992.         num_digits := 1 ;
  1993.         number_string(1) := '0' ;
  1994.       END IF ; -- number = 0 ?
  1995.       debug_io.put("number_string(1..num_digits)=") ;
  1996.       debug_io.put_line(number_string(1..num_digits)) ;
  1997.       store_message(number_string(1..num_digits)) ;
  1998.       debug_io.put_line("  end pvirtlpac.store_message(i)") ;
  1999.     EXCEPTION 
  2000.       WHEN OTHERS =>
  2001.         DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.STORE_MESSAGE(i)") ;
  2002.         RAISE ;
  2003.     END store_message ;
  2004.  
  2005.     PROCEDURE do_passive_open  IS
  2006.               ---------------
  2007.       tcp_options         : tcp_option_type ;
  2008.       open_parameters     : open_params ;
  2009.       the_message_for_tcp : message ;
  2010.     BEGIN
  2011.       debug_io.put_line("in passive open routine") ;
  2012.       IF user_data.user_control_block.tl_port_number = 0 THEN -- server_telnet
  2013.         debug_io.put_line("will attempt passive open") ;
  2014.         FOR index IN 1..50 LOOP
  2015.           tcp_options(index) := 0 ;
  2016.         END LOOP ;
  2017.         open_parameters := (2, --TBD hard wire for test
  2018.          0,0,with_ulp_communicate.passive,0,255,lcn_record,0,0,tcp_options) ;
  2019.         the_message_for_tcp := (with_ulp_communicate.open, open_parameters) ;
  2020.         message_for_tcp(the_message_for_tcp, request_ok) ;
  2021.         lcn := the_message_for_tcp.open_parameters.local_connection_name ;
  2022.         dec_tn_tasks.tcp_reader.start ;
  2023.       END IF ;
  2024.       debug_io.put_line("end passive open") ;
  2025.     END do_passive_open ;
  2026.  
  2027.  
  2028.   BEGIN
  2029.     debug_io.put_line("in vir_tl get_and_process_information...") ;
  2030.     debug_io.put("msg #=") ;
  2031.     debug_io.put_line(message_from_tcp.message_number) ;
  2032.     CASE message_from_tcp.message_number IS
  2033.       WHEN 2 => store_message("connection illegal") ;
  2034.       WHEN 3 => store_message("connection does not exist") ;
  2035.       WHEN 4 => store_message("foreign socket unpsecified") ;
  2036.       WHEN 5 => store_message("insufficient resources") ;
  2037.       WHEN 6 => store_message("connection closing") ; -- close sent from remote
  2038.         user_data.user_control_block.communication_state := 
  2039.          user_data.no_connection_established ;
  2040.         DECLARE
  2041.           parameter : service_call_parameters_type(tl_close) ;
  2042.         BEGIN
  2043.           convert_service_call_to_transport_level_syntax(tl_close, parameter) ;
  2044.         END ;
  2045.       WHEN 7 => store_message("performing urgent data processing") ;
  2046.         tl_data_is_urgent := TRUE ;
  2047.       WHEN 8 => store_message("connection aborted") ;
  2048.         user_data.reset_user_control_block ; -- reset to initial values
  2049.         do_passive_open ;
  2050.       WHEN 9 => store_message("precedence not allowed") ;
  2051.       WHEN 10 | 19 => -- data from remote
  2052.         DECLARE -- data
  2053.           tl_data : user_data.trans_to_telnet_data_record RENAMES
  2054.            user_data.user_control_block.trans_buffers.trans_to_telnet_data ;
  2055.           data_buf_length : CONSTANT bit_count_16_type := 
  2056.            user_data.trans_to_telnet_data_buffer_length ;
  2057.           char_count : bit_count_16_type := 
  2058.            message_from_tcp.data_buffer.telnet_ptr -
  2059.            message_from_tcp.data_buffer.tcp_ptr ;
  2060.           cr : CONSTANT bit_count_8_type := 13 ; -- ascii carraige return
  2061.         BEGIN
  2062.  
  2063.           debug_io.put_line("data msg detected") ;
  2064.           debug_io.put("  telnet_ptr=") ;
  2065.           debug_io.put(message_from_tcp.data_buffer.telnet_ptr) ;
  2066.           debug_io.put("  tcp_ptr :=") ;
  2067.           debug_io.put_line(message_from_tcp.data_buffer.tcp_ptr) ;
  2068.  
  2069.           FOR index IN 0..char_count LOOP
  2070.  
  2071.             debug_io.put("  position =") ;
  2072.             debug_io.put(message_from_tcp.data_buffer.telnet_ptr - index) ;
  2073.             debug_io.put("  char_code =") ;
  2074.             debug_io.put_line_byte(message_from_tcp.data_buffer.byte
  2075.              (message_from_tcp.data_buffer.telnet_ptr - index)) ;
  2076.  
  2077.             IF last_char_was_not_cr THEN
  2078.               tl_data.buffer(tl_data.buf_tail) := 
  2079.                message_from_tcp.data_buffer.byte
  2080.                (message_from_tcp.data_buffer.telnet_ptr - index) ;
  2081.               tl_data.buf_tail := (tl_data.buf_tail + 1) MOD data_buf_length ;
  2082.               debug_io.put_line("stored") ;
  2083.             END IF ; -- not cr?
  2084.             IF message_from_tcp.data_buffer.byte
  2085.              (message_from_tcp.data_buffer.telnet_ptr - index) = cr THEN
  2086.               last_char_was_not_cr := FALSE ;
  2087.             ELSE
  2088.               last_char_was_not_cr := TRUE ;
  2089.             END IF ;  
  2090.           END LOOP ;
  2091.           buffree(message_from_tcp.data_buffer, 0) ; 
  2092.           -- replace the satisfied receive with another receive
  2093.           DECLARE -- receive
  2094.             packed_buffer : packed_buffer_ptr ;
  2095.             receive_data  : receive_params ;
  2096.             task_message  : message ;
  2097.           BEGIN 
  2098.             buffget(packed_buffer,1) ;
  2099.             IF packed_buffer = NULL THEN
  2100.               debug_io.put_line("Unable to get buffer for a receive.") ;
  2101.               store_message("Unable to get buffer for a receive.") ;
  2102.             ELSE
  2103.              lcn_record := message_from_tcp.local_connection_name ;
  2104.              receive_data := (lcn_record, packed_buffer, 190) ;
  2105.              task_message := (receive, receive_data) ;
  2106.              message_for_tcp(task_message, request_ok) ;
  2107.             END IF ; -- null?
  2108.           END ; -- receive declare
  2109.         END ; -- data declare
  2110.       WHEN 11 => store_message("security/compartment illegal") ;
  2111.       WHEN 12 => store_message("connection exists") ;
  2112.       WHEN 14 => -- return lcn from open request
  2113.         debug_io.put_line("return lcn msg detected") ;
  2114.         lcn.lcn_ptr := message_from_tcp.local_connection_name.lcn_ptr ; 
  2115.         --&MT replace the satisfied receive with another receive
  2116.         DECLARE -- receive
  2117.           packed_buffer : packed_buffer_ptr ;
  2118.           receive_data  : receive_params ;
  2119.           task_message  : message ;
  2120.         BEGIN 
  2121.           buffget(packed_buffer,1) ;
  2122.           IF packed_buffer = NULL THEN
  2123.             debug_io.put_line("Unable to get buffer for a receive.") ;
  2124.             store_message("Unable to get buffer for a receive.") ;
  2125.           ELSE
  2126.             lcn_record.lcn_ptr := 
  2127.              message_from_tcp.local_connection_name.lcn_ptr ;
  2128.             receive_data := (lcn_record, packed_buffer, 190) ;
  2129.             task_message := (receive, receive_data) ;
  2130.             message_for_tcp(task_message, request_ok) ;
  2131.           END IF ; -- null?
  2132.         END ; -- receive declare
  2133.       WHEN 15 => -- status
  2134.         debug_io.put_line("status msg detected") ;
  2135.        DECLARE
  2136.        -- &MT  the : status_record RENAMES message_from_tcp.status_params ;
  2137.        -- &MT  variant record component status_params is not renamable in dec ada
  2138.        BEGIN
  2139.         store_message(" ") ;
  2140.         store_message("status information :") ;
  2141.         store_message(" ") ;
  2142.         store_message("source port=") ;
  2143.         store_message(bit_count_32_type(message_from_tcp.status_params.source_port)) ;
  2144.         store_message("source address=") ;
  2145.         store_message(bit_count_32_type(message_from_tcp.status_params.source_address)) ;
  2146.         store_message("destination address=") ; 
  2147.         store_message(bit_count_32_type(message_from_tcp.status_params.destination_address)) ;
  2148.         store_message("destination port=") ;
  2149.         store_message(bit_count_32_type(message_from_tcp.status_params.destination_port)) ;
  2150.         store_message("# of octets we can accept=") ;
  2151.         store_message(bit_count_32_type(message_from_tcp.status_params.local_rcv_window)) ;
  2152.         store_message("# of octets that can be sent=") ;
  2153.         store_message(bit_count_32_type(message_from_tcp.status_params.remote_rcv_window)) ;
  2154.         store_message("amount of data on retran q =") ;
  2155.         store_message(bit_count_32_type(message_from_tcp.status_params.octets_on_retransmit_queue)) ;
  2156.         store_message("amount of data waiting for us =") ;
  2157.         store_message(bit_count_32_type(message_from_tcp.status_params.data_waiting_for_ulp)) ;
  2158.         IF message_from_tcp.status_params.urgent_state THEN
  2159.           store_message("urgent state=true") ;
  2160.         ELSE
  2161.           store_message("urgent state=false") ;
  2162.         END IF ;
  2163.         store_message("precedence value=") ;
  2164.         store_message(bit_count_32_type(message_from_tcp.status_params.precedence)) ;
  2165.         store_message("user layer timeout=") ;
  2166.         store_message(bit_count_32_type(message_from_tcp.status_params.ulp_timeout)) ;
  2167.         store_message("security values=") ;
  2168.         FOR index IN 1..9 LOOP
  2169.           store_message(bit_count_32_type(message_from_tcp.status_params.security(index))) ;
  2170.         END LOOP ;
  2171.         IF message_from_tcp.status_params.status = with_ulp_communicate.connection_open THEN
  2172.           store_message("connection open") ;
  2173.         ELSE
  2174.           store_message("connection closed") ;
  2175.         END IF ;
  2176.         store_message("message_from_tcp.status_params TCB state is") ;
  2177.         CASE message_from_tcp.status_params.connection_state IS
  2178.           WHEN closed                         => store_message("closed") ;
  2179.           WHEN with_ulp_communicate.listen    => store_message("listen") ;
  2180.           WHEN syn_sent                       => store_message("syn_sent") ;
  2181.           WHEN syn_received                   => store_message("syn received") ;
  2182.           WHEN established                    => store_message("established") ;
  2183.           WHEN fin_wait_1                     => store_message("fin_wait_1") ;
  2184.           WHEN fin_wait_2                     => store_message("fin_wait_2") ;
  2185.           WHEN close_wait                     => store_message("close_wait") ;
  2186.           WHEN last_ack                       => store_message("last_ack") ;
  2187.           WHEN time_wait                      => store_message("time_wait") ;
  2188.           WHEN OTHERS                         => store_message("closing") ;
  2189.         END CASE ;
  2190.        END ; -- status declare
  2191.       WHEN 16 => store_message("connection reset by other host") ;
  2192.         user_data.reset_user_control_block ; -- reset to initial values
  2193.         do_passive_open ;
  2194.       WHEN 17 => store_message("connection refused") ;
  2195.       WHEN 18 => store_message("connection closed") ;
  2196.         user_data.reset_user_control_block ; -- reset to initial values
  2197.         do_passive_open ;
  2198.       WHEN 20 => store_message("out of buffers in a lower layer") ;
  2199.       WHEN 21 => store_message("unable to reset") ;
  2200.       WHEN 22 => store_message("the ip is currently overloaded") ;
  2201.       WHEN 23 => -- connection open
  2202.         debug_io.put_line("connection open msg detected") ;
  2203.         user_data.user_control_block.communication_state := 
  2204.          user_data.connection_established ;
  2205.         debug_io.put_line
  2206.          ("communication_state set to connection_established") ;
  2207.         store_message("connection open") ;
  2208.       WHEN 24 => store_message("error: connection aborted due to user time out") ;
  2209.         user_data.reset_user_control_block ; -- reset to initial values
  2210.         do_passive_open ;
  2211.       WHEN OTHERS => 
  2212.         debug_io.put("unknown msg # detected ==>") ;
  2213.         debug_io.put_line(message_from_tcp.message_number) ;
  2214.     END CASE ;
  2215.     debug_io.put_line("end vir_tl get_and_process_information...") ;
  2216.   EXCEPTION 
  2217.     WHEN OTHERS =>
  2218.       DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.GET_AND_PROC_INFO") ;
  2219.       RAISE ;
  2220.   END get_and_process_information_from_the_transport_level ;
  2221.  
  2222. ----------------------------- END LOCAL SUBPROGRAMS ---------------------------
  2223.  
  2224.   FUNCTION there_is_a_message  -- body
  2225.            ------------------
  2226.   RETURN BOOLEAN IS 
  2227.   -- (for test/debug use user_data.trans_input_buffer for the mock
  2228.   -- TCP interface buffer)
  2229.  
  2230.     message : user_data.trans_to_telnet_messages_record RENAMES
  2231.      user_data.user_control_block.trans_buffers.trans_to_telnet_messages ;
  2232.     buf_length : CONSTANT bit_count_16_type := 
  2233.      user_data.trans_to_telnet_msg_buffer_length ;
  2234.  
  2235.   BEGIN
  2236.     debug_io.put_line("in vir_tl there is a message") ;
  2237.     IF there_is_information_from_the_transport_level THEN
  2238.       debug_io.put_line("calling get&process because there is information") ;
  2239.       get_and_process_information_from_the_transport_level ;
  2240.     END IF ;
  2241.     debug_io.put_line("end vir_tl there is a message") ;
  2242.     RETURN (message.buf_head + 1) MOD buf_length /= message.buf_tail ;
  2243.   END there_is_a_message ; -- body
  2244.  
  2245.      
  2246.   FUNCTION there_is_input  -- body
  2247.            --------------
  2248.    RETURN BOOLEAN IS
  2249.   -- (for test/debug use user_data.trans_input_buffer for the mock
  2250.   -- TCP interface buffer)
  2251.  
  2252.     data : user_data.trans_to_telnet_data_record RENAMES
  2253.      user_data.user_control_block.trans_buffers.trans_to_telnet_data ;
  2254.     buf_length : CONSTANT bit_count_16_type := 
  2255.      user_data.trans_to_telnet_msg_buffer_length ;
  2256.  
  2257.   BEGIN
  2258.     debug_io.put_line("in vir_tl there is input") ;
  2259.     IF there_is_information_from_the_transport_level THEN
  2260.       debug_io.put_line("call get and process") ;
  2261.       get_and_process_information_from_the_transport_level ;
  2262.     END IF ;
  2263.     debug_io.put_line("end vir_tl there is input") ;
  2264.     RETURN (data.buf_head + 1) MOD buf_length /= data.buf_tail ;
  2265.   END there_is_input ; -- body
  2266.     
  2267.     
  2268.   PROCEDURE get_message -- body
  2269.             -----------
  2270.    (message : OUT message_type ;
  2271.     length  : OUT bit_count_16_type) IS
  2272.  
  2273.     mess : user_data.trans_to_telnet_messages_record RENAMES
  2274.      user_data.user_control_block.trans_buffers.trans_to_telnet_messages ;
  2275.     buf_length : CONSTANT bit_count_16_type := 
  2276.      user_data.trans_to_telnet_msg_buffer_length ;
  2277.     there_is_more : BOOLEAN := TRUE ;
  2278.     message_length : bit_count_16_type ;
  2279.       -- $MT  new local variable declared to resolve error of reading from 
  2280.       -- subprogram 'out'.'
  2281.   BEGIN
  2282.     debug_io.put_line("in get message") ;
  2283.     message_length := 0 ;
  2284.       -- &MT message_length replaced length
  2285.     IF there_is_a_message THEN
  2286.       WHILE there_is_more LOOP
  2287.         mess.buf_head := (mess.buf_head + 1) MOD buf_length ;
  2288.         IF mess.buffer(mess.buf_head) = 16#0D# THEN -- ascii.cr, end of message
  2289.           there_is_more := FALSE ;
  2290.         END IF ; -- eom?
  2291.         message_length := message_length + 1 ;
  2292.         message(message_length) := mess.buffer(mess.buf_head) ;
  2293.           -- &MT message_length replaced length
  2294.       END LOOP ; -- do all
  2295.     END IF ; -- message present?
  2296.     length := message_length ;
  2297.     debug_io.put(" at end of get message... ") ;
  2298.   EXCEPTION 
  2299.     WHEN OTHERS =>
  2300.       DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.GET_MESSAGE") ;
  2301.       RAISE ;
  2302.   END get_message ; -- body
  2303.  
  2304.     
  2305.   PROCEDURE get_input -- body
  2306.             ---------
  2307.    (input : OUT input_type ;
  2308.     tcp_urgent_flag : OUT BOOLEAN) IS 
  2309. -- this urgent handling will change when tcp passes back the flag with a get
  2310.  
  2311.     data : user_data.trans_to_telnet_data_record RENAMES
  2312.      user_data.user_control_block.trans_buffers.trans_to_telnet_data ;
  2313.     buf_length : CONSTANT bit_count_16_type := 
  2314.      user_data.trans_to_telnet_data_buffer_length ;
  2315.     there_is_more : BOOLEAN := TRUE ;
  2316.     temp_input : input_type ;
  2317.       -- $MT  new local variable declared to resolve error of reading from 
  2318.       -- subprogram 'out'.'
  2319.  
  2320.   BEGIN
  2321.     debug_io.put_line("pvirtlpac.get_input begin") ; 
  2322.     tcp_urgent_flag := tl_data_is_urgent ;
  2323.     IF there_is_input THEN
  2324.       data.buf_head := (data.buf_head + 1) MOD buf_length ;
  2325.       temp_input := data.buffer(data.buf_head);
  2326.         -- &MT  temp_input replaced input
  2327.       debug_io.put("input code =") ;
  2328.       debug_io.put_line_byte(temp_input) ;
  2329.         -- &MT  temp_input replaced input
  2330.     END IF ; -- data present?
  2331.     input := temp_input ;
  2332.     debug_io.put_line("pvirtlpac.get_input end") ;
  2333.     EXCEPTION 
  2334.       WHEN OTHERS =>
  2335.         DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.GET_INPUT") ;
  2336.         RAISE ;
  2337.   END get_input ; -- body
  2338.  
  2339.  
  2340.   FUNCTION there_is_room_for_info_output -- body
  2341.            -----------------------------
  2342.    RETURN BOOLEAN IS 
  2343. --MT    output : user_data.trans_output_buffer_record RENAMES
  2344. --MT     user_data.user_control_block.trans_buffers.trans_output_buffer ;
  2345. --MT    max_buf_length : CONSTANT bit_count_16_type := user_data.trans_out_buffer_length ;
  2346.   BEGIN 
  2347. --MT    RETURN output.length < max_buf_length ;
  2348.     RETURN TRUE ;
  2349.   END there_is_room_for_info_output ;
  2350.  
  2351.  
  2352.   PROCEDURE send_data -- body
  2353.             ---------
  2354.    (data : IN info_output_type ;
  2355.     urgent_flag : IN BOOLEAN) IS
  2356.  
  2357.     parameter : service_call_parameters_type(TL_send) ; -- can't do TeleSoft
  2358.                                                        -- aggregate assign here
  2359.   BEGIN -- send_data
  2360.     debug_io.put_line("begin vir_tl.send_data") ;
  2361.     parameter.urgent_flag := urgent_flag ;
  2362.     parameter.info_length := data'LENGTH ;
  2363.     FOR index IN data'RANGE LOOP -- copy rest of string
  2364.       parameter.info(index) := data(index) ;
  2365.     END LOOP ;
  2366.     convert_service_call_to_transport_level_syntax(TL_send, parameter) ;
  2367.     debug_io.put_line("end vir_tl.send_data") ;
  2368.   EXCEPTION 
  2369.     WHEN OTHERS =>
  2370.       DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.SEND_DATA") ;
  2371.       RAISE ;
  2372.   END send_data ;
  2373.  
  2374.  
  2375.   PROCEDURE send_message -- body 
  2376.             ------------
  2377.    (message : IN info_output_type) IS
  2378.     parameter : service_call_parameters_type(TL_send) ;-- can't do (TeleSoft)
  2379.                                                        -- aggregate assign here
  2380.   BEGIN
  2381.     debug_io.put_line("begin vir_tl.send_message") ;
  2382.     parameter.urgent_flag := false ;
  2383.     parameter.info_length := message'LENGTH ;
  2384.     parameter.info(1..message'LENGTH) := message(1..message'LENGTH) ;
  2385.     convert_service_call_to_transport_level_syntax(TL_send, parameter) ;
  2386.     debug_io.put_line("end vir_tl.send_message") ;
  2387.   EXCEPTION 
  2388.     WHEN OTHERS =>
  2389.       DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.SEND_MESSAGE") ;
  2390.       RAISE ;
  2391.   END send_message ;
  2392.  
  2393.  
  2394.   PROCEDURE convert_service_call_to_transport_level_syntax -- body
  2395.             ----------------------------------------------
  2396.    (service_call : IN transport_level_service_call_type ;
  2397.     parameter   : IN service_call_parameters_type) IS 
  2398.  
  2399.     the_message_for_tcp : message ;
  2400.  
  2401.   BEGIN -- convert_service_call_to_transport_level_syntax 
  2402.     debug_io.put_line("begin vir_tl.convert_service call...") ;
  2403.     IF (service_call = tl_open) THEN                       -- ****** OPEN ******
  2404.       debug_io.put_line("virt_tl processed open call to TCP") ;
  2405.       debug_io.put("network_number=") ;
  2406.       debug_io.put_line(parameter.network_number) ;
  2407.       debug_io.put("host_number=") ; 
  2408.       debug_io.put_line(parameter.host_number) ;
  2409.       debug_io.put("logical_host_number=") ; 
  2410.       debug_io.put_line(parameter.logical_host_number) ;
  2411.       debug_io.put("imp_number=") ; 
  2412.       debug_io.put_line(parameter.imp_number) ;
  2413.       debug_io.put("port_number=") ; 
  2414.       debug_io.put_line(parameter.port_number) ;
  2415.       DECLARE 
  2416.         foreign_net_host : bit_count_32_type ;
  2417.         options : tcp_option_type ;
  2418.         open_parameters : open_params ;
  2419.  
  2420.         FUNCTION calculate_class_a_address (net, imp, host : IN bit_count_16_type) 
  2421.          RETURN bit_count_32_type IS
  2422.         BEGIN
  2423.           RETURN bit_count_32_type(16#1000000#) * bit_count_32_type(net) -- high byte
  2424.                + bit_count_32_type(256) * bit_count_32_type(imp) -- middle 2 bytes
  2425.                + bit_count_32_type(host) ; -- low byte
  2426.         END calculate_class_a_address ;
  2427.  
  2428.       BEGIN -- (only class A networks currently supported)
  2429.         user_data.user_control_block.tl_port_number := parameter.port_number ;
  2430. --        foreign_net_host := calculate_class_a_address(parameter.network_number,
  2431. --         parameter.imp_number, parameter.host_number) ;
  2432.         FOR index IN 1..50 LOOP
  2433.           options(index) := 0 ; 
  2434.         END LOOP ;
  2435.         foreign_net_host := bit_count_32_type(parameter.logical_host_number) ; -- for testing
  2436.         lcn_record := lcn ;
  2437.         --use imp as local port number for testing (really 23)
  2438.         open_parameters := (parameter.imp_number, parameter.port_number, 
  2439.          foreign_net_host, active, 0, 15, lcn_record, 0, 0, options) ;
  2440.         the_message_for_tcp := (with_ulp_communicate.open, open_parameters) ;
  2441.         message_for_tcp(the_message_for_tcp, request_ok) ;
  2442.         lcn := the_message_for_tcp.open_parameters.local_connection_name ; 
  2443.         dec_tn_tasks.tcp_reader.start ;
  2444.       END ; -- open declare
  2445.     ELSIF service_call = tl_send THEN                     -- ****** SEND ******
  2446.       debug_io.put_line("virt_tl processing send call to TCP") ;
  2447.       DECLARE
  2448.         packed_buffer  : packed_buffer_ptr ;
  2449.         send_data      : send_params ;
  2450.         tl_byte_count  : bit_count_16_type := parameter.info_length - 1 ;
  2451.         tl_push_flag   : CONSTANT bit_count_16_type := 1 ; -- do push
  2452.         tl_urgent_flag : bit_count_16_type := 0 ; -- not urgent
  2453.         tl_time_out    : CONSTANT bit_count_16_type := 15 ; -- arbitrary
  2454.         buffer_index   : bit_count_16_type := 0 ;
  2455.         cr             : CONSTANT bit_count_8_type := 13 ;-- ascii carraige return
  2456.         lf             : CONSTANT bit_count_8_type := 10 ;-- ascii line feed
  2457.       
  2458.       BEGIN -- tl_send declare
  2459.         debug_io.put_line("in pvirtlpac.send_data to tcp (actual tcp call)") ;
  2460.         IF parameter.info_length > 0 THEN 
  2461.           buffget(packed_buffer,1) ;
  2462.           IF packed_buffer = NULL THEN
  2463.             store_message("out of buffers") ;
  2464.           ELSE
  2465.             IF parameter.urgent_flag THEN tl_urgent_flag := 1 ; END IF ;
  2466.             FOR index IN 1..parameter.info_length LOOP
  2467.               packed_buffer.byte(packed_buffer.telnet_ptr - buffer_index) :=
  2468.                parameter.info(index) ;
  2469.               buffer_index := buffer_index + 1 ;
  2470.               debug_io.put("data code=") ;
  2471.               debug_io.put_line_byte(parameter.info(index)) ;
  2472.               IF parameter.info(index) = cr THEN -- see RFC 854 page 11,12
  2473.                 packed_buffer.byte(packed_buffer.telnet_ptr - buffer_index) := lf ;
  2474.                 buffer_index := buffer_index + 1 ;
  2475.                 debug_io.put("data code=") ;
  2476.                 debug_io.put_byte(lf) ;
  2477.                 debug_io.put_line("  lf inserted") ;
  2478.               END IF ; -- cr?
  2479.             END LOOP ;
  2480.             lcn_record := lcn ;
  2481.             tl_byte_count := buffer_index - 1 ;
  2482.             packed_buffer.telnet_ptr := packed_buffer.telnet_ptr - tl_byte_count;
  2483.             packed_buffer.tcp_ptr := packed_buffer.telnet_ptr - 1 ;
  2484.  
  2485.             debug_io.put("tl_byte_count=") ;
  2486.             debug_io.put_line(tl_byte_count) ;
  2487.             debug_io.put("telnet_ptr=") ;
  2488.             debug_io.put_line(packed_buffer.telnet_ptr) ;
  2489.             debug_io.put("tcp_ptr=") ;
  2490.             debug_io.put_line(packed_buffer.tcp_ptr) ;
  2491.  
  2492.             send_data := (lcn_record, packed_buffer, tl_byte_count, 
  2493.              tl_push_flag, tl_urgent_flag, tl_time_out) ;
  2494.             the_message_for_tcp := (send, send_data) ;
  2495.             message_for_tcp(the_message_for_tcp, request_ok) ;
  2496.           END IF ; -- packed buffer = NULL ?
  2497.         END IF ; -- length > 0 ?
  2498.       END ; -- tl_send declare
  2499.       debug_io.put_line("end virt_tl processing send call to TCP") ;
  2500.     ELSIF service_call = tl_receive THEN               -- ****** RECEIVE ******
  2501.       debug_io.put_line("virt_tl processed receive call to TCP") ;
  2502.     ELSIF service_call = tl_close THEN                -- ******* CLOSE *******
  2503.       debug_io.put_line("virt_tl processing close call to TCP") ;
  2504.       DECLARE
  2505.         close_params : abort_close_params ;
  2506.       BEGIN
  2507.         lcn_record := lcn ;
  2508.         close_params := (local_connection_name => lcn_record) ;
  2509.         the_message_for_tcp := (with_ulp_communicate.close, close_params) ;
  2510.         message_for_tcp(the_message_for_tcp, request_ok) ;
  2511.       END ; 
  2512.       debug_io.put_line("communication_state is no_connection_established") ;
  2513.     ELSIF service_call = tl_status THEN                -- ****** STATUS ******
  2514.       debug_io.put_line("virt_tl processing status call to TCP") ;
  2515.       DECLARE
  2516.         status_data : status_params ;
  2517.       BEGIN
  2518.         lcn_record := lcn ;
  2519.         status_data := (local_connection_name => lcn_record) ;
  2520.         the_message_for_tcp := (with_ulp_communicate.status, status_data) ;
  2521.         message_for_tcp(the_message_for_tcp, request_ok) ;
  2522.       END ;
  2523.     ELSIF service_call = tl_abort THEN                  -- ****** ABORT ******
  2524.       debug_io.put_line("virt_tl processing abort call to TCP") ;
  2525.       DECLARE
  2526.         abort_params : abort_close_params ;
  2527.       BEGIN
  2528.         lcn_record := lcn ;
  2529.         abort_params := (local_connection_name => lcn_record) ;
  2530.         the_message_for_tcp := (with_ulp_communicate.abor_t, abort_params) ;
  2531.         message_for_tcp(the_message_for_tcp, request_ok) ;
  2532.       END ;
  2533.     ELSE 
  2534.       debug_io.put_line("unrecognized service call") ;
  2535.     END IF ; -- service type?
  2536.     debug_io.put_line("end of convt serv call to tl syntax") ;
  2537.   EXCEPTION 
  2538.     WHEN OTHERS =>
  2539.       DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.CONVERT...") ;
  2540.       RAISE ;
  2541.   END convert_service_call_to_transport_level_syntax ; -- body
  2542.    
  2543.  
  2544. BEGIN 
  2545.   NULL ;
  2546.   EXCEPTION 
  2547.     WHEN OTHERS =>
  2548.       DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.INSTAINTIATION") ;
  2549.       RAISE ;
  2550. END virtual_transport_level ; -- package body
  2551. --::::::::::::::
  2552. --poptngpac_.ada
  2553. --::::::::::::::
  2554. -----------------------------------------------------------------------
  2555. --
  2556. --         DoD Protocols    NA-00004-200       80-01059-100(-)
  2557. --         E-Systems, Inc.  August 07, 1985
  2558. --
  2559. --         POPTNGPAC_.ADA       Author : Mike Thomas 
  2560. --
  2561. -----------------------------------------------------------------------
  2562.  
  2563. -- File poptngpac
  2564.  
  2565. --   5/7/85  1:50 PM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS
  2566. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  2567. --   7/1/85  1:28 PM : remove status variable from request calls
  2568.  
  2569. WITH user_data ;
  2570. USE  user_data ; --&MT added this to help with handling of enumerated types
  2571. WITH SYSTEM ; -- access system.byte
  2572.  
  2573. PACKAGE option_negotiation -- specification
  2574.         ------------------
  2575.  IS
  2576.   --*********************  USER SPECIFICATION  ********************************
  2577.   --
  2578.   -- This package will have routines to negotiate the transfer syntax and 
  2579.   -- virtual resource characteristics.  A procedure will negotiate initial
  2580.   -- options.  Additionally, procedures can be called to explicitly request 
  2581.   -- option enable or demand option disable of a particular option at any time.
  2582.   -- **************************************************************************
  2583.  
  2584. -- NOTE : This compiles OK but does not work properly during runtime.
  2585. -- so get directly from user_data until on a real ADA compiler
  2586. --  SUBTYPE ppl_option_type IS user_data.option_type ;
  2587.  
  2588. --&MT SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  2589.   SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  2590.  
  2591.  
  2592.   PROCEDURE request_local_option_enable -- specification
  2593.             ---------------------------
  2594.    (option : IN user_data.option_type) ;
  2595.  
  2596.   -- ************************  USER SPECIFICATION  ****************************
  2597.   --
  2598.   -- If the connection is established and the option is not already in effect,
  2599.   -- this procedure will negotiate for that option.  If there is no connection
  2600.   -- established, the desirable option tables will be updated and TELNET
  2601.   -- PPL will try to negotiate these options at the establishment of a new 
  2602.   -- connection.  
  2603.   -----------------------------------------------------------------------------
  2604.  
  2605.      
  2606.   PROCEDURE demand_local_option_disable -- specification
  2607.             ---------------------------
  2608.    (option : IN user_data.option_type) ;
  2609.  
  2610.   -- ************************  USER SPECIFICATION  ****************************
  2611.   --
  2612.   -- If the connection is established and the option is already in effect,
  2613.   -- this procedure will negotiate the cessation of that option.  If there is
  2614.   -- no connection established, the desirable option tables will be updated 
  2615.   -- and TELNET PPL will not try to negotiate this option at the establishment 
  2616.   -- of a new connection.  
  2617.   -----------------------------------------------------------------------------
  2618.  
  2619.  
  2620.   PROCEDURE request_remote_option_enable -- specification
  2621.             ----------------------------
  2622.    (option : IN user_data.option_type) ;
  2623.  
  2624.   -- ************************  USER SPECIFICATION  ****************************
  2625.   --
  2626.   -- If the connection is established and the option is not already in effect,
  2627.   -- this procedure will negotiate for that option.  If there is no connection
  2628.   -- established, the desirable option tables will be updated and TELNET PPL
  2629.   -- will try to negotiate these options at the establishment of a new 
  2630.   -- connection.  
  2631.   -----------------------------------------------------------------------------
  2632.      
  2633.      
  2634.   PROCEDURE demand_remote_option_disable -- specification
  2635.             ----------------------------
  2636.    (option : IN user_data.option_type) ;
  2637.  
  2638.   -- ************************  USER SPECIFICATION  ****************************
  2639.   --
  2640.   -- If the connection is established and the option is already in effect,
  2641.   -- this procedure will negotiate the cessation of that option.  If there is
  2642.   -- no connection established, the desirable option tables will be updated 
  2643.   -- and TELNET PPL will not try to negotiate this option at the establishment 
  2644.   -- of a new connection.  
  2645.   -----------------------------------------------------------------------------
  2646.  
  2647.  
  2648.   PROCEDURE negotiate_initial_desired_options ; -- specification 
  2649.             ---------------------------------
  2650.  
  2651.   -- ************************  USER SPECIFICATION  ****************************
  2652.   --
  2653.   -- This procedure will use the information contained in the desirable 
  2654.   -- options tables to negotiate options with the remote TELNET.
  2655.   -----------------------------------------------------------------------------
  2656.  
  2657.  
  2658.   PROCEDURE remote_will_received  -- specification
  2659.             -------------------- 
  2660.    (option_code : IN bit_count_8_type) ;   
  2661.   -- *************************  USER SPECIFICATION  ***************************
  2662.   --
  2663.   -- This procedure will inform the option negotiation subprograms that a 
  2664.   -- WILL (option) was received from the remote TELNET.
  2665.   -------------------------------------------------------------------------
  2666.  
  2667.  
  2668.   PROCEDURE remote_wont_received  -- specification
  2669.             -------------------- 
  2670.    (option_code : IN bit_count_8_type) ;   
  2671.   -- *************************  USER SPECIFICATION  ***************************
  2672.   --
  2673.   -- This procedure will inform the option negotiation subprograms that a 
  2674.   -- WONT (option) was received from the remote TELNET.
  2675.   -------------------------------------------------------------------------
  2676.  
  2677.  
  2678.   PROCEDURE remote_do_received  -- specification
  2679.             ------------------ 
  2680.    (option_code : IN bit_count_8_type) ;   
  2681.   -- *************************  USER SPECIFICATION  ***************************
  2682.   --
  2683.   -- This procedure will inform the option negotiation subprograms that a 
  2684.   -- DO (option) was received from the remote TELNET.
  2685.   -------------------------------------------------------------------------
  2686.  
  2687.  
  2688.   PROCEDURE remote_dont_received  -- specification
  2689.             -------------------- 
  2690.    (option_code : IN bit_count_8_type) ;   
  2691.   -- *************************  USER SPECIFICATION  ***************************
  2692.   --
  2693.   -- This procedure will inform the option negotiation subprograms that a 
  2694.   -- DONT (option) was received from the remote TELNET.
  2695.   -------------------------------------------------------------------------
  2696.  
  2697. END option_negotiation ; -- package specification
  2698.  
  2699. --::::::::::::::
  2700. --poptngpac.ada
  2701. --::::::::::::::
  2702. -----------------------------------------------------------------------
  2703. --
  2704. --         DoD Protocols    NA-00004-200       80-01060-100(-)
  2705. --         E-Systems, Inc.  August 07, 1985
  2706. --
  2707. --         POPTNGPAC.ADA       Author : Mike Thomas 
  2708. --
  2709. -----------------------------------------------------------------------
  2710.  
  2711. -- File poptngpac
  2712. --   7-1-85  1:32 PM : remove status var from requests
  2713. --           5:46 PM : fix bug in option negotiation disable,dont,wont
  2714.  
  2715. WITH debug_io ;
  2716. WITH virtual_transport_level ;
  2717. WITH dec_tn_tasks ;
  2718.  
  2719. PACKAGE BODY option_negotiation IS
  2720.              ------------------
  2721.  
  2722. --&MT SUBTYPE bit_count_16_type IS INTEGER ; 
  2723.   SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  2724.  
  2725.   TYPE action_type IS (tn_will, tn_wont, tn_do, tn_dont) ;
  2726.   TYPE action_code_array_type IS ARRAY(action_type) OF bit_count_8_type ;
  2727.   TYPE option_code_array_type IS ARRAY(user_data.option_type) OF bit_count_8_type ;
  2728.   action_kind : action_type ;
  2729.   action_code : action_code_array_type ;-- aggregate asignment not implimented
  2730.   option_code : option_code_array_type ;-- during decl.(do assign in body part)
  2731.   echo : user_data.option_type ; -- TeleSoft-Ada can't do assign here
  2732.   suppress_ga : user_data.option_type ; -- ditto
  2733.   IAC : CONSTANT bit_count_8_type := 255 ; -- interprate as command code
  2734.  
  2735.   option_tables            : user_data.option_tables_type RENAMES 
  2736.    user_data.user_control_block.option_tables ;
  2737.   local_options_desired    : user_data.option_table_type RENAMES
  2738.    option_tables.local_options_desired ;
  2739.   local_options_in_effect  : user_data.option_table_type RENAMES
  2740.    option_tables.local_options_in_effect ;
  2741.   local_options_pending    : user_data.option_table_type RENAMES
  2742.    option_tables.local_options_pending ;
  2743.   remote_options_desired   : user_data.option_table_type RENAMES
  2744.    option_tables.remote_options_desired ;
  2745.   remote_options_in_effect : user_data.option_table_type RENAMES
  2746.    option_tables.remote_options_in_effect ;   
  2747.   remote_options_pending   : user_data.option_table_type RENAMES
  2748.    option_tables.remote_options_pending ;
  2749.  
  2750.  
  2751.   PROCEDURE store_message (message : IN STRING) IS -- (local procedure)
  2752.             -------------
  2753.     tl_msg : user_data.trans_to_telnet_messages_record RENAMES
  2754.      user_data.user_control_block.trans_buffers.trans_to_telnet_messages ;
  2755.     msg_buf_length : CONSTANT bit_count_16_type := 
  2756.      user_data.trans_to_telnet_msg_buffer_length ;
  2757.   BEGIN
  2758.     FOR index IN 1..message'LENGTH LOOP
  2759.       tl_msg.buffer(tl_msg.buf_tail) := 
  2760.        bit_count_8_type(CHARACTER'POS(message(index))) ;
  2761.       tl_msg.buf_tail := (tl_msg.buf_tail + 1) MOD msg_buf_length ;
  2762.     END LOOP ;
  2763.     tl_msg.buffer(tl_msg.buf_tail) := 10 ; -- ascii.lf
  2764.     tl_msg.buf_tail := (tl_msg.buf_tail + 1) MOD msg_buf_length ;
  2765.     tl_msg.buffer(tl_msg.buf_tail) := 13 ; -- ascii.cr
  2766.     tl_msg.buf_tail := (tl_msg.buf_tail + 1) MOD msg_buf_length ;
  2767.     dec_tn_tasks.tn.go ; -- make sure message gets out --&MT (dec only)
  2768.     EXCEPTION
  2769.       WHEN OTHERS =>
  2770.         DEBUG_IO.PUT_LINE("@@@ EXCEPTION IN POPTNGPAC.STORE_MESSAGE") ;
  2771.         RAISE ;
  2772.   END store_message ;
  2773.  
  2774.  
  2775.   PROCEDURE send_option 
  2776.             -----------
  2777.    (action : IN action_type ;
  2778.     option : IN user_data.option_type) IS
  2779.     data : virtual_transport_level.info_output_type(1..3) ;
  2780.   BEGIN
  2781.     data(1) := IAC ;
  2782.     data(2) := action_code(action) ;
  2783.     data(3) := option_code(option) ;
  2784.     virtual_transport_level.send_data(data, FALSE) ;
  2785.   EXCEPTION
  2786.     WHEN OTHERS =>
  2787.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.send_option(o)") ;
  2788.       RAISE ;
  2789.   END send_option ;
  2790.  
  2791.  
  2792.   PROCEDURE send_option 
  2793.             -----------
  2794.    (action      : IN action_type ;
  2795.     option_code : IN bit_count_8_type) IS
  2796.     data : virtual_transport_level.info_output_type(1..3) ;
  2797.   BEGIN
  2798.     data(1) := IAC ;
  2799.     data(2) := action_code(action) ;
  2800.     data(3) := option_code ;
  2801.     virtual_transport_level.send_data(data, FALSE) ;
  2802.   EXCEPTION
  2803.     WHEN OTHERS =>
  2804.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.send_option(c)") ;
  2805.       RAISE ;
  2806.   END send_option ;
  2807.  
  2808.  
  2809.   PROCEDURE send_message
  2810.             ------------
  2811.    (message : IN STRING) IS
  2812.     tl_message : virtual_transport_level.info_output_type(1..message'LENGTH) ;
  2813.   BEGIN
  2814.     FOR index IN message'RANGE LOOP -- convert to system.byte
  2815.       tl_message(bit_count_16_type(index)) :=
  2816.        bit_count_8_type(CHARACTER'POS(message(index))) ;
  2817.     END LOOP ;
  2818.     virtual_transport_level.send_message(tl_message) ;
  2819.   EXCEPTION
  2820.     WHEN OTHERS =>
  2821.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.send_message") ;
  2822.       RAISE ;
  2823.   END send_message ;
  2824.  
  2825.  
  2826.   FUNCTION option_in_table
  2827.            ---------------
  2828.    (table  : IN user_data.option_table_type ;
  2829.     option : IN user_data.option_type) RETURN BOOLEAN IS
  2830.   BEGIN
  2831.     FOR index IN 1..table.number_of_items LOOP
  2832.       IF table.option(bit_count_16_type(index)) = option THEN
  2833.         RETURN TRUE ;
  2834.       END IF ;
  2835.     END LOOP ;
  2836.     RETURN FALSE ;
  2837.   END option_in_table ;
  2838.  
  2839.  
  2840.   FUNCTION local_option_already_in_effect_or_being_negotiated
  2841.            --------------------------------------------------
  2842.    (option : IN user_data.option_type) RETURN BOOLEAN IS
  2843.   BEGIN
  2844.     IF option_in_table(local_options_in_effect, option)THEN RETURN TRUE ;END IF ;
  2845.     IF option_in_table(local_options_pending, option) THEN RETURN TRUE ; END IF ;
  2846.     RETURN FALSE ;
  2847.   END local_option_already_in_effect_or_being_negotiated ;
  2848.  
  2849.  
  2850.   FUNCTION remote_option_already_in_effect_or_being_negotiated
  2851.            ---------------------------------------------------
  2852.    (option : IN user_data.option_type) RETURN BOOLEAN IS
  2853.   BEGIN
  2854.     IF option_in_table(remote_options_in_effect,option) THEN RETURN TRUE ;END IF;
  2855.     IF option_in_table(remote_options_pending, option) THEN RETURN TRUE ;END IF ;
  2856.     RETURN FALSE ;
  2857.   END remote_option_already_in_effect_or_being_negotiated ;
  2858.  
  2859.  
  2860.   PROCEDURE add_option_to_table -- no check for overflow or duplication
  2861.             -------------------
  2862.    (table  : IN OUT user_data.option_table_type ;
  2863.     option : IN     user_data.option_type) IS
  2864.   BEGIN
  2865.     table.number_of_items := table.number_of_items + 1 ;
  2866.     table.option(table.number_of_items) := option ;
  2867.   EXCEPTION
  2868.     WHEN OTHERS =>
  2869.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.add_option_") ;
  2870.       RAISE ;
  2871.   END add_option_to_table ;
  2872.  
  2873.  
  2874.   PROCEDURE delete_option_from_table
  2875.             ------------------------
  2876.    (table  : IN OUT user_data.option_table_type ;
  2877.     option : IN     user_data.option_type) IS -- dedicated to Evanne
  2878.     save_index : bit_count_16_type RANGE 0..user_data.number_of_options_supported := 0 ;
  2879.   BEGIN
  2880.     FOR index IN 1..table.number_of_items LOOP
  2881.       IF table.option(bit_count_16_type(index)) /= option THEN
  2882.         save_index := save_index + 1 ;
  2883.         table.option(save_index) := table.option(index) ;
  2884.       END IF ;
  2885.     END LOOP ;
  2886.     table.number_of_items := save_index ;
  2887.   EXCEPTION
  2888.     WHEN OTHERS =>
  2889.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.delete_option_") ;
  2890.       RAISE ;
  2891.   END delete_option_from_table ;
  2892.  
  2893.  
  2894.   PROCEDURE request_local_option_enable -- body
  2895.             ---------------------------
  2896.    (option : IN  user_data.option_type) IS
  2897.  
  2898.   -- ************************  BODY SPECIFICATION  ****************************
  2899.   --
  2900.   -- If the connection is established and the option is not already in effect,
  2901.   -- this procedure will negotiate for that option.  Otherwise, the desirable
  2902.   -- option tables will be updated and TELNET PPL will try to negotiate these 
  2903.   -- options at the establishment of a new connection.
  2904.   -----------------------------------------------------------------------------
  2905.   BEGIN
  2906.     IF (user_data.user_control_block.communication_state =
  2907.      user_data.connection_established) AND 
  2908.      (NOT(local_option_already_in_effect_or_being_negotiated(option))) THEN
  2909.         action_kind := tn_will ;
  2910.         send_option(action_kind, option) ;
  2911.         add_option_to_table(local_options_pending, option) ;
  2912.     ELSE 
  2913.       add_option_to_table(local_options_desired, option) ;
  2914.     END IF ; 
  2915.   EXCEPTION
  2916.     WHEN OTHERS =>
  2917.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.rloe") ;
  2918.       RAISE ;
  2919.   END request_local_option_enable ; -- body
  2920.      
  2921.      
  2922.   PROCEDURE demand_local_option_disable -- body
  2923.             ---------------------------
  2924.    (option : IN user_data.option_type) IS 
  2925.  
  2926.   -- ************************  BODY SPECIFICATION  ****************************
  2927.   --
  2928.   -- If the connection is established and the option is already in effect,
  2929.   -- this procedure will negotiate the cessation of that 
  2930.   -- option.  If there is no connection established, the desirable option 
  2931.   -- tables will be updated and TELNET PPL will not try to negotiate this 
  2932.   -- option at the establishment of a new connection.  
  2933.   -----------------------------------------------------------------------------
  2934.   BEGIN
  2935.     IF (user_data.user_control_block.communication_state =
  2936.      user_data.connection_established) AND 
  2937.      option_in_table(local_options_in_effect, option) THEN
  2938.        action_kind := tn_wont ;
  2939.        send_option(action_kind, option) ;
  2940.        add_option_to_table(local_options_pending, option) ;
  2941.     ELSE 
  2942.       delete_option_from_table(local_options_desired, option) ;
  2943.     END IF ; 
  2944.   EXCEPTION
  2945.     WHEN OTHERS =>
  2946.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.dlod") ;
  2947.       RAISE ;
  2948.   END demand_local_option_disable ; -- body
  2949.  
  2950.  
  2951.   PROCEDURE request_remote_option_enable -- body
  2952.             ----------------------------
  2953.    (option : IN user_data.option_type) IS
  2954.  
  2955.   -- ************************  BODY SPECIFICATION  ****************************
  2956.   --
  2957.   -- If the connection is established and the option is not already in effect,
  2958.   -- this procedure will negotiate for that option.  Otherwise, the desirable 
  2959.   -- option tables will be updated and TELNET PPL will try to negotiate these 
  2960.   -- options at the establishment of a new connection.
  2961.   -----------------------------------------------------------------------------
  2962.   BEGIN 
  2963.     IF (user_data.user_control_block.communication_state =
  2964.      user_data.connection_established) AND 
  2965.      (NOT(remote_option_already_in_effect_or_being_negotiated(option))) THEN
  2966.         action_kind := tn_do ;
  2967.         send_option(action_kind, option) ;
  2968.         add_option_to_table(remote_options_pending, option) ;
  2969.     ELSE -- add to desired options table
  2970.       add_option_to_table(remote_options_desired, option) ;
  2971.     END IF ; -- not (in effect or in negotiation)
  2972.   EXCEPTION
  2973.     WHEN OTHERS =>
  2974.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.rroe") ;
  2975.       RAISE ;
  2976.   END request_remote_option_enable ; -- body
  2977.      
  2978.      
  2979.   PROCEDURE demand_remote_option_disable -- body
  2980.             ----------------------------
  2981.    (option : IN user_data.option_type) IS 
  2982.  
  2983.   -- ************************  BODY SPECIFICATION  ****************************
  2984.   --
  2985.   -- If the connection is established and the option is already in effect,
  2986.   -- this procedure will negotiate the cessation of that 
  2987.   -- option.  If there is no connection established, the desirable option 
  2988.   -- tables will be updated and TELNET PPL will not try to negotiate this 
  2989.   -- option at the establishment of a new connection.  
  2990.   -----------------------------------------------------------------------------
  2991.   BEGIN
  2992.     IF (user_data.user_control_block.communication_state =
  2993.      user_data.connection_established) AND 
  2994.      option_in_table(remote_options_in_effect, option) THEN
  2995.        action_kind := tn_dont ;
  2996.        send_option(action_kind, option) ;
  2997.        add_option_to_table(remote_options_pending, option) ;
  2998.     ELSE 
  2999.       delete_option_from_table(remote_options_desired, option) ;
  3000.     END IF ; 
  3001.   EXCEPTION
  3002.     WHEN OTHERS =>
  3003.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.drod") ;
  3004.       RAISE ;
  3005.   END demand_remote_option_disable ; -- body
  3006.  
  3007.  
  3008.   PROCEDURE negotiate_initial_desired_options -- body
  3009.             ---------------------------------
  3010.    IS
  3011.     -- ************************  BODY SPECIFICATION  **************************
  3012.     --
  3013.     -- This procedure will use the information contained in the desirable 
  3014.     -- options tables to negotiate initial options with the remote TELNET 
  3015.     -- connection.
  3016.     --
  3017.     -- Processing sequence... 
  3018.     -- Check the table of remote options that are desired for the other end 
  3019.     -- and send a DO OPTION --- through the connection for each.  Check the 
  3020.     -- table of local options desirable on this end and send a WILL OPTION --- 
  3021.     -- through the connection for each.
  3022.     ---------------------------------------------------------------------------
  3023.  
  3024.   BEGIN -- negotiate initial options procedure body
  3025.     action_kind := tn_do ;
  3026.     FOR index IN 1..remote_options_desired.number_of_items LOOP
  3027.       request_remote_option_enable
  3028.        (remote_options_desired.option(index)) ;
  3029.     END LOOP ;
  3030.     action_kind := tn_will ;
  3031.     FOR index IN 1..local_options_desired.number_of_items LOOP
  3032.       request_local_option_enable(local_options_desired.option(index)) ;
  3033.     END LOOP ;
  3034.   EXCEPTION
  3035.     WHEN OTHERS =>
  3036.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.nido") ;
  3037.       RAISE ;
  3038.   END negotiate_initial_desired_options ; -- procedure body
  3039.  
  3040.  
  3041.   PROCEDURE remote_will_received  -- body
  3042.             -------------------- 
  3043.    (option_code : IN bit_count_8_type) IS
  3044.  
  3045.   -- *************************  BODY SPECIFICATION  ***************************
  3046.   --
  3047.   -- If the option code is not supported, send a don't for the unknown code;
  3048.   -- otherwize process the option in the following manner.
  3049.   -- If we already asked for this option(in remote_options_pending table) then
  3050.   -- add it to the remote_options_in_effect table and remove it from the 
  3051.   -- remote pending options table.
  3052.   -- Otherwize, if the option is in the remote_options_desired table then "ack"
  3053.   -- it and add it to the remote_options_in_effect table.
  3054.   -- If the above conditions were not met, then refuse to allow the option 
  3055.   -- and "ack" it if required(option not in remote_option_pending table) or
  3056.   -- simply remove it from the remote_options_pending table if no "ack"
  3057.   -- is neccessary.   
  3058.   -----------------------------------------------------------------------------
  3059.   BEGIN
  3060.     CASE option_code IS
  3061.       WHEN 1 => -- echo : note both sides cannot echo at once(=> loop forever)
  3062.         -- see RFC 857 for information on the TELNET echo option
  3063.         IF option_in_table(remote_options_pending, echo) AND 
  3064.          (NOT(option_in_table(local_options_in_effect, echo))) THEN
  3065.           delete_option_from_table(remote_options_pending, echo) ;
  3066.           add_option_to_table(remote_options_in_effect, echo) ;
  3067.           store_message("$@$ remote echo option in effect $@$") ;
  3068.         ELSIF option_in_table(remote_options_desired, echo) AND 
  3069.          (NOT(option_in_table(local_options_in_effect, echo))) THEN
  3070.           add_option_to_table(remote_options_in_effect, echo) ;
  3071.           store_message("$@$ remote echo option in effect $@$") ;
  3072.           action_kind := tn_do ;
  3073.           send_option(action_kind, echo) ;
  3074.         ELSE -- check if negative ack required
  3075.           store_message("$@$ remote echo option denied by local Telnet $@$") ;
  3076.           IF option_in_table(remote_options_pending, echo) THEN -- no ack
  3077.              delete_option_from_table(remote_options_pending, echo) ;
  3078.           ELSE -- send negative ack
  3079.             action_kind := tn_dont ;
  3080.             send_option(action_kind, echo) ;
  3081.           END IF ;
  3082.         END IF ;
  3083.       WHEN 3 => -- suppress go ahead
  3084.         -- see RFC 858 for information on the TELNET suppress ga option
  3085.         IF option_in_table(remote_options_pending, suppress_ga) THEN
  3086.           delete_option_from_table(remote_options_pending, suppress_ga) ;
  3087.           add_option_to_table(remote_options_in_effect, suppress_ga) ;
  3088.           store_message("$@$ remote suppress_ga option in effect $@$") ;
  3089.         ELSIF option_in_table(remote_options_desired, suppress_ga) THEN 
  3090.           add_option_to_table(remote_options_in_effect, suppress_ga) ;
  3091.           store_message("$@$ remote suppress_ga option in effect $@$") ;
  3092.           action_kind := tn_do ;
  3093.           send_option(action_kind, suppress_ga) ;
  3094.         ELSE -- check if negative ack required
  3095.           store_message("$@$ remote suppress_ga option denied by local Telnet $@$") ;
  3096.           IF option_in_table(remote_options_pending, suppress_ga) THEN -- no ack
  3097.             delete_option_from_table(remote_options_pending, suppress_ga) ;
  3098.           ELSE -- send negative ack
  3099.             action_kind := tn_dont ;
  3100.             send_option(action_kind, suppress_ga) ;
  3101.           END IF ;
  3102.         END IF ;
  3103.       WHEN OTHERS => -- not supported, refuse offer
  3104.         action_kind := tn_dont ;
  3105.         send_option(action_kind, option_code) ;
  3106.     END CASE ;
  3107.   EXCEPTION
  3108.     WHEN OTHERS =>
  3109.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.rwillr") ;
  3110.       RAISE ;
  3111.   END remote_will_received ;
  3112.  
  3113.  
  3114.   PROCEDURE remote_wont_received  -- body
  3115.             -------------------- 
  3116.    (option_code : IN bit_count_8_type) IS
  3117.  
  3118.   -- *************************  BODY SPECIFICATION  ***************************
  3119.   --
  3120.   -- If the code is suported then process as follows...
  3121.   -- If the option was requested remotly(item in remote_options_in_effect table
  3122.   -- and item not in remote_options_pending) then ack the wont with a dont. 
  3123.   -- Remove the item from the romote_options_pending / in_effect tables
  3124.   -----------------------------------------------------------------------------
  3125.  
  3126.   BEGIN
  3127.     CASE option_code IS
  3128.       WHEN 1 => -- ECHO
  3129.         -- see RFC 857 for information on the TELNET echo option
  3130.         store_message("$@$ remote echo option denied by remote $@$") ;
  3131.         IF (option_in_table(remote_options_in_effect, echo)) AND 
  3132.          (NOT(option_in_table(remote_options_pending, echo))) THEN -- ack
  3133.           action_kind := tn_dont ; -- ack
  3134.           send_option(action_kind, echo) ;
  3135.         END IF ;
  3136.         delete_option_from_table(remote_options_in_effect, echo) ;
  3137.         delete_option_from_table(remote_options_pending, echo) ;
  3138.       WHEN 3 => -- SUPPRESS_GA
  3139.         -- see RFC 858 for information on the TELNET suppress_ga option
  3140.         store_message("$@$ remote suppress_ga option denied by remote $@$") ;
  3141.         IF option_in_table(remote_options_in_effect, suppress_ga) AND
  3142.          (NOT(option_in_table(remote_options_pending, suppress_ga))) THEN -- ack
  3143.           action_kind := tn_dont ; -- ack
  3144.           send_option(action_kind, suppress_ga) ;
  3145.         END IF ;
  3146.         delete_option_from_table(remote_options_in_effect, suppress_ga) ;
  3147.         delete_option_from_table(remote_options_pending, suppress_ga) ;
  3148.       WHEN OTHERS => -- not supported, refuse offer
  3149.         NULL ;
  3150.     END CASE ;
  3151.   EXCEPTION
  3152.     WHEN OTHERS =>
  3153.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.rwontr") ;
  3154.       RAISE ;
  3155.   END remote_wont_received ;
  3156.  
  3157.  
  3158.   PROCEDURE remote_do_received  -- body
  3159.             ------------------ 
  3160.    (option_code : IN bit_count_8_type) IS  
  3161.  
  3162.   -- *************************  BODY SPECIFICATION  ***************************
  3163.   --
  3164.   -- If the option code is not supported, send a don't for the unknown code;
  3165.   -- otherwize process the option in the following manner.
  3166.   -- If we already asked for this option(in remote_options_pending table) then
  3167.   -- add it to the remote_options_in_effect table and remove it from the 
  3168.   -- remote pending options table.
  3169.   -- Otherwize, if the option is in the remote_options_desired table then "ack"
  3170.   -- it and add it to the remote_options_in_effect table.
  3171.   -- If the above conditions were not met, then refuse to allow the option 
  3172.   -- and "ack" it if required(option not in remote_option_pending table) or
  3173.   -- simply remove it from the remote_options_pending table if no "ack"
  3174.   -- is neccessary.   
  3175.   -----------------------------------------------------------------------------
  3176.   BEGIN
  3177.     CASE option_code IS
  3178.       WHEN 1 => -- echo : note both sides cannot echo at once(=> loop forever)
  3179.         -- see RFC 857 for information on the TELNET echo option
  3180.         IF option_in_table(local_options_pending, echo) AND 
  3181.          (NOT(option_in_table(remote_options_in_effect, echo))) THEN
  3182.            delete_option_from_table(local_options_pending, echo) ;
  3183.           add_option_to_table(local_options_in_effect, echo) ;
  3184.           store_message("$@$ local echo option in effect $@$") ;
  3185.         ELSIF option_in_table(local_options_desired, echo) AND 
  3186.          (NOT(option_in_table(remote_options_in_effect, echo))) THEN
  3187.           add_option_to_table(local_options_in_effect, echo) ;
  3188.           action_kind := tn_will ;
  3189.           send_option(action_kind, echo) ;
  3190.           store_message("$@$ local echo option in effect $@$") ;
  3191.         ELSE -- check if negative ack required
  3192.           store_message("$@$ local echo option denied by local telnet $@$") ;
  3193.           IF option_in_table(remote_options_pending, echo) THEN
  3194.              delete_option_from_table(local_options_pending, echo) ;
  3195.           ELSE -- send negative ack
  3196.             action_kind := tn_wont ;
  3197.             send_option(action_kind, echo) ;
  3198.           END IF ;
  3199.         END IF ;
  3200.       WHEN 3 => -- suppress_ga
  3201.         -- see RFC 858 for information on the TELNET supress_ga option
  3202.         IF option_in_table(local_options_pending, suppress_ga) THEN
  3203.           delete_option_from_table(local_options_pending, suppress_ga) ;
  3204.           add_option_to_table(local_options_in_effect, suppress_ga) ;
  3205.           store_message("$@$ local suppress_ga option in effect $@$") ;
  3206.         ELSIF option_in_table(local_options_desired, suppress_ga) THEN
  3207.           store_message("$@$ local suppress_ga option in effect $@$") ;
  3208.           add_option_to_table(local_options_in_effect, suppress_ga) ;
  3209.           action_kind := tn_will ;
  3210.           send_option(action_kind, suppress_ga) ;
  3211.         ELSE -- check if negative ack required
  3212.           store_message("$@$ local suppress_ga option denied by local telnet $@$") ;
  3213.           IF option_in_table(remote_options_pending, suppress_ga) THEN
  3214.             delete_option_from_table(local_options_pending, suppress_ga) ;
  3215.           ELSE -- send negative ack
  3216.             action_kind := tn_wont ;
  3217.             send_option(action_kind, suppress_ga) ;
  3218.           END IF ;
  3219.         END IF ;
  3220.       WHEN OTHERS => -- not supported, refuse offer
  3221.         action_kind := tn_wont ;
  3222.         send_option(action_kind, option_code) ;
  3223.     END CASE ;
  3224.   EXCEPTION
  3225.     WHEN OTHERS =>
  3226.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.rdor") ;
  3227.       RAISE ;
  3228.   END remote_do_received  ;
  3229.  
  3230.  
  3231.   PROCEDURE remote_dont_received  -- body
  3232.             -------------------- 
  3233.    (option_code : IN bit_count_8_type) IS 
  3234.  
  3235.   -- *************************  BODY SPECIFICATION  ***************************
  3236.   --
  3237.   -- If the code is suported then process as follows...
  3238.   -- If the option was requested remotly(item in local_options_in_effect table
  3239.   -- and item not in local_options_pending) then ack the dont with a wont. 
  3240.   -- Remove the item from the local_options_pending / in_effect tables
  3241.   -----------------------------------------------------------------------------
  3242.  
  3243.   BEGIN
  3244.     CASE option_code IS
  3245.       WHEN 1 => -- echo
  3246.         -- see RFC 857 for information on the TELNET echo option
  3247.         store_message("$@$ local echo option denied by remote $@$") ;
  3248.         IF option_in_table(local_options_in_effect, echo) AND
  3249.          (NOT(option_in_table(local_options_pending, echo))) THEN -- ack
  3250.           action_kind := tn_wont ; -- ack
  3251.           send_option(action_kind, echo) ;
  3252.         END IF ;
  3253.         delete_option_from_table(local_options_in_effect, echo) ;
  3254.         delete_option_from_table(local_options_pending, echo) ;
  3255.       WHEN 3 => -- suppress_ga
  3256.         -- see RFC 858 for information on the TELNET suppress_ga
  3257.         store_message("$@$ local suppress_ga option denied by remote $@$") ;
  3258.         IF option_in_table(local_options_in_effect, suppress_ga) AND
  3259.          (NOT(option_in_table(local_options_pending, suppress_ga))) THEN -- ack
  3260.           action_kind := tn_wont ; -- ack
  3261.           send_option(action_kind, suppress_ga) ;
  3262.         END IF ;
  3263.         delete_option_from_table(local_options_in_effect, suppress_ga) ;
  3264.         delete_option_from_table(local_options_pending, suppress_ga) ;
  3265.       WHEN OTHERS => -- should not get this
  3266.         NULL ;
  3267.     END CASE ;
  3268.   EXCEPTION
  3269.     WHEN OTHERS =>
  3270.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.rdontr") ;
  3271.       RAISE ;
  3272.   END remote_dont_received  ;
  3273.      
  3274. BEGIN -- option_negotiation body
  3275.   echo := user_data.echo ; -- TeleSoft won't init this in declaration
  3276.   suppress_ga := user_data.suppress_ga ; -- ditto
  3277. -- packed agregates not impleminted yet
  3278. --  action_code := (251, 252, 253, 254) ; -- RFC 854 page 14
  3279. --  option_code := (1) ; -- RFC 857 page 1 (code for echo)
  3280.   action_code(tn_will) := 251 ;
  3281.   action_code(tn_wont) := 252 ;
  3282.   action_code(tn_do)   := 253 ;
  3283.   action_code(tn_dont) := 254 ;
  3284.   option_code(echo)        := 1 ;
  3285.   option_code(suppress_ga) := 3 ;
  3286.   EXCEPTION
  3287.     WHEN OTHERS =>
  3288.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac instantiation") ;
  3289.       RAISE ;
  3290. END option_negotiation ; -- package_body
  3291. --::::::::::::::
  3292. --amesspac_.ada
  3293. --::::::::::::::
  3294. -----------------------------------------------------------------------
  3295. --
  3296. --         DoD Protocols    NA-00004-200       80-01045-100(-)
  3297. --         E-Systems, Inc.  August 07, 1985
  3298. --
  3299. --         AMESSPAC_.ADA       Author : Mike Thomas 
  3300. --
  3301. -----------------------------------------------------------------------
  3302.  
  3303. -- File : amesspac
  3304.  
  3305. --   5/8/85  8:50 AM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS 
  3306. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  3307.  
  3308. WITH SYSTEM ; -- to gain access to system.byte
  3309. WITH virtual_transport_level ;
  3310. WITH virtual_terminal ;
  3311. WITH user_data ; -- access the port_number
  3312.  
  3313. PACKAGE message_processing -- specfication
  3314.         ------------------
  3315.  IS
  3316.  
  3317. -- **********************  USER SPECIFICATION  ********************************
  3318. --
  3319. -- This package provides data types and subprograms for processing (at
  3320. -- the APL level)  messages from the transport level to TELNET for a
  3321. -- particular user. A message being information which originated at the
  3322. -- local transport level, not simply data being relayed from the remote
  3323. -- TELNET.  This information is given higher priority than simple
  3324. -- data transfer.
  3325. --
  3326. -- ****************************************************************************
  3327.  
  3328. --&MT SUBTYPE bit_count_16_type IS INTEGER ; 
  3329.   SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  3330.  
  3331.   max_msg_length : CONSTANT bit_count_16_type := 
  3332.    virtual_transport_level.max_msg_length ;
  3333. -- make a deferred constant when supported
  3334.  
  3335.   SUBTYPE message_from_transport_level_type IS 
  3336.    virtual_transport_level.message_type ;
  3337. -- Telelie ADA does not support limited private subtpes ;
  3338.  
  3339.   FUNCTION there_is_a_message_available -- specification
  3340.            ----------------------------
  3341.    RETURN BOOLEAN ;
  3342.     -- ************************  USER SPECIFICATION  ****************************
  3343.   --
  3344.   -- This function returns true if there is a message available from the
  3345.   -- transport level. 
  3346.   -----------------------------------------------------------------------------
  3347.  
  3348.     
  3349.   PROCEDURE retrieve_message -- specification
  3350.             ----------------
  3351.    (message : OUT message_from_transport_level_type ;
  3352.     length  : OUT bit_count_16_type) ;
  3353.   -- ************************  USER SPECIFICATION  ****************************
  3354.   -- 
  3355.   -- This procedure gets an entire message from the transport level.
  3356.   -----------------------------------------------------------------------------
  3357.       
  3358.   
  3359.   PROCEDURE write_message_to_NVT_printer -- specification
  3360.             ----------------------------
  3361.    (transport_level_message : IN message_from_transport_level_type ; 
  3362.     length                  : IN bit_count_16_type) ;
  3363.   -- ************************  USER SPECIFICATION  ****************************
  3364.   -- 
  3365.   -- This procedure writes an entire message from the transport level
  3366.   -- to the NVT printer.
  3367.   -----------------------------------------------------------------------------
  3368.  
  3369. END message_processing ; -- package specification
  3370. --::::::::::::::
  3371. --amesspac.ada
  3372. --::::::::::::::
  3373. -----------------------------------------------------------------------
  3374. --
  3375. --         DoD Protocols    NA-00004-200       80-01046-100(-)
  3376. --         E-Systems, Inc.  August 07, 1985
  3377. --
  3378. --         AMESSPAC.ADA       Author : Mike Thomas 
  3379. --
  3380. -----------------------------------------------------------------------
  3381.  
  3382. -- File : amesspac
  3383.  
  3384. --   5/8/85  9:10 AM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS 
  3385. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  3386.  
  3387. WITH debug_io ;
  3388.  
  3389. PACKAGE BODY message_processing IS
  3390.              ------------------
  3391.  
  3392.   FUNCTION there_is_a_message_available -- body
  3393.            ----------------------------
  3394.    RETURN BOOLEAN IS 
  3395.   BEGIN
  3396.     RETURN virtual_transport_level.there_is_a_message ;
  3397.  
  3398.   EXCEPTION
  3399.     WHEN OTHERS =>
  3400.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN amesspac.there_is_msg") ;
  3401.       RAISE ;
  3402.  
  3403.   END there_is_a_message_available ; -- function body
  3404.  
  3405.     
  3406.   PROCEDURE retrieve_message -- body
  3407.             ----------------
  3408.    (message : OUT message_from_transport_level_type ;
  3409.     length  : OUT bit_count_16_type) IS 
  3410.   BEGIN
  3411.     IF virtual_transport_level.there_is_a_message THEN
  3412.       virtual_transport_level.get_message(message, length) ;
  3413.     ELSE -- error
  3414.       length := 0 ; -- no message available, erronious call
  3415.     END IF ;     
  3416.  
  3417.   EXCEPTION
  3418.     WHEN OTHERS =>
  3419.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN amesspac.retr_msg") ;
  3420.       RAISE ;
  3421.  
  3422.   END retrieve_message ; -- procedure body
  3423.       
  3424.       
  3425.   PROCEDURE write_message_to_NVT_printer -- body
  3426.             ----------------------------
  3427.    (transport_level_message : IN message_from_transport_level_type ;
  3428.     length  : IN bit_count_16_type) IS
  3429.   BEGIN
  3430.     FOR index IN 1..length LOOP 
  3431.       virtual_terminal.output_character_to_nvt_printer
  3432.        (user_data.user_control_block.port, transport_level_message(index)) ;
  3433.     END LOOP ;      
  3434.  
  3435.   EXCEPTION
  3436.     WHEN OTHERS =>
  3437.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN amesspac.write_msg_nvt") ;
  3438.       RAISE ;
  3439.  
  3440.   END write_message_to_NVT_printer ; -- procedure body
  3441.  
  3442. BEGIN
  3443.   NULL ;
  3444. EXCEPTION
  3445.   WHEN OTHERS =>
  3446.     debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN amesspac instantiation") ;
  3447.     RAISE ;
  3448.  
  3449. END message_processing ; -- package body
  3450. --::::::::::::::
  3451. --atrinpac_.ada
  3452. --::::::::::::::
  3453. -----------------------------------------------------------------------
  3454. --
  3455. --         DoD Protocols    NA-00004-200       80-01049-100(-)
  3456. --         E-Systems, Inc.  August 07, 1985
  3457. --
  3458. --         ATRINPAC_.ADA       Author : Mike Thomas 
  3459. --
  3460. -----------------------------------------------------------------------
  3461.  
  3462. -- File : atrinpac
  3463.  
  3464. --   5/8/85  9:25 AM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS 
  3465. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  3466.  
  3467. WITH SYSTEM ; -- to get access to system.byte
  3468.  
  3469. PACKAGE transport_level_input_processing -- specification
  3470.         --------------------------------
  3471.  IS 
  3472. -- **************************  USER SPECIFICATION  ****************************
  3473. --
  3474. -- This package provides subprograms to process (at the APL level) data 
  3475. -- input to TELNET relayed from the remote TELNET.
  3476. --
  3477. -- **************************************************************************
  3478.  
  3479. --&MT SUBTYPE bit_count_32_type IS LONG_INTEGER ; 
  3480.   SUBTYPE bit_count_32_type IS INTEGER ;
  3481.  
  3482. --&MT SUBTYPE bit_count_16_type IS INTEGER ; 
  3483.   SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  3484.  
  3485. --&MT SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  3486.   SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  3487.  
  3488.   
  3489.  
  3490.   SUBTYPE character_type IS bit_count_8_type ;
  3491.  
  3492.   FUNCTION there_is_input -- specification
  3493.            --------------
  3494.    RETURN BOOLEAN ;
  3495.   -- ************************  USER SPECIFICATION  ****************************
  3496.   -- 
  3497.   -- This function returns true if there is data input available from the
  3498.   -- remote TELNET.
  3499.   -----------------------------------------------------------------------------
  3500.  
  3501.  
  3502.   PROCEDURE input_character -- specification
  3503.             ---------------
  3504.    (char :             OUT character_type ;
  3505.     control_function : OUT BOOLEAN ;
  3506.     urgent_data      : OUT BOOLEAN) ;
  3507.   -- ************************  USER SPECIFICATION  ****************************
  3508.   -- 
  3509.   -- This procedure returns a character sent from the remote TELNET and 
  3510.   -- indicates whether it is to be interpreted as a control function.
  3511.   -----------------------------------------------------------------------------
  3512.     
  3513.     
  3514.   PROCEDURE process_standard_control_function -- specification
  3515.             ---------------------------------
  3516.    (char : IN character_type ;
  3517.     urgent_data : IN BOOLEAN) ;
  3518.   -- ************************  USER SPECIFICATION  ****************************
  3519.   -- 
  3520.   -- This procedure processes a control function which was received from
  3521.   -- the remote TELNET connection.
  3522.   -----------------------------------------------------------------------------
  3523.  
  3524.  
  3525.   PROCEDURE write_character_to_NVT_printer -- specification
  3526.             ------------------------------
  3527.    (char : IN character_type) ;
  3528.   -- ************************  USER SPECIFICATION  ****************************
  3529.   -- 
  3530.   -- This routine writes a character to the NVT printer.
  3531.   -----------------------------------------------------------------------------
  3532.  
  3533. END transport_level_input_processing ; -- package specification
  3534.  
  3535.  
  3536. --::::::::::::::
  3537. --atrinpac.ada
  3538. --::::::::::::::
  3539. -----------------------------------------------------------------------
  3540. --
  3541. --         DoD Protocols    NA-00004-200       80-01050-100(-)
  3542. --         E-Systems, Inc.  August 07, 1985
  3543. --
  3544. --         ATRINPAC.ADA       Author : Mike Thomas 
  3545. --
  3546. -----------------------------------------------------------------------
  3547.  
  3548. -- File : atrinpac
  3549.  
  3550. --   5/8/85  9:37 AM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS 
  3551. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  3552.  
  3553. WITH virtual_transport_level ;
  3554. WITH virtual_terminal ;
  3555. WITH option_negotiation ;
  3556. WITH user_data ;
  3557. WITH debug_io ;
  3558.  
  3559. PACKAGE BODY transport_level_input_processing 
  3560.              --------------------------------
  3561.  IS 
  3562. -- *********************  BODY SPECIFICATION  *********************************
  3563. --
  3564. -- This package provides subprograms to process (at the APL level) data 
  3565. -- input to TELNET from the transport level.  Make the appropriate calls
  3566. -- to the lower level APL packages which will in turn call routines from
  3567. -- the PPL.  Data input is data sent from the remote TELNET.
  3568. --
  3569. -- ****************************************************************************
  3570.  
  3571.   FUNCTION there_is_input -- body
  3572.            --------------
  3573.    RETURN BOOLEAN IS
  3574.   BEGIN
  3575.     RETURN virtual_transport_level.there_is_input ; 
  3576.  
  3577.   EXCEPTION
  3578.     WHEN OTHERS =>
  3579.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.there_is_input") ;
  3580.       RAISE ;
  3581.  
  3582.   END there_is_input ; -- function body
  3583.  
  3584.  
  3585.   PROCEDURE input_character -- body
  3586.             ---------------
  3587.    (char :             OUT character_type ;
  3588.     control_function : OUT BOOLEAN ;
  3589.     urgent_data      : OUT BOOLEAN) IS
  3590.   -- ************************  BODY SPECIFICATION  ****************************
  3591.   --
  3592.   -- This procedure returns a character sent from the remote TELNET 
  3593.   -- and indicates whether it is to be interpreted as a control function. 
  3594.   -- Characters which are part of a synch are flagged as a control function.
  3595.   -- The urgent data flag or the user_data.synch_in_progress = TRUE indicates
  3596.   -- that the current character is to be interpreted as a control function.
  3597.   -- If the character is an IAC(Interperate As Command), get another 
  3598.   -- character.  If the second character is not an IAC it is a command and to
  3599.   -- be interpreted as a control function.  (This will also have the effect of
  3600.   -- of screening out the doubling of the IAC code done by the remote TELNET 
  3601.   -- when it is not to be interpreted as an IAC, ie. the data byte 255.)
  3602.   -- A call to this procedure without checking for the presence of characters
  3603.   -- to input is erroneous but will result in char := 0 and control_function
  3604.   -- := FALSE.
  3605.   -----------------------------------------------------------------------------
  3606.   
  3607.     IAC : CONSTANT character_type := 255 ; -- interprate as command code
  3608.     temp_char : character_type;
  3609.     temp_control_function : BOOLEAN;
  3610.     temp_urgent_data : BOOLEAN;
  3611.  
  3612.   BEGIN
  3613.     temp_char := 0 ;
  3614.     temp_control_function := FALSE ;
  3615.     IF virtual_transport_level.there_is_input THEN
  3616.       virtual_transport_level.get_input(temp_char, temp_urgent_data) ;
  3617.       IF user_data.user_control_block.synch_is_in_progress
  3618.        OR temp_urgent_data THEN -- special handling required
  3619.         temp_control_function := TRUE ;
  3620.         debug_io.put("atrinpac.input_character: control func detected, code=") ;
  3621.         debug_io.put_line_byte(temp_char) ;
  3622.       END IF ;
  3623.       IF bit_count_16_type(temp_char) = bit_count_16_type(IAC) THEN
  3624.         WHILE NOT(virtual_transport_level.there_is_input) LOOP NULL ; END LOOP ;
  3625.         virtual_transport_level.get_input(temp_char, temp_urgent_data) ;
  3626.         IF bit_count_16_type(temp_char) /= bit_count_16_type(IAC) THEN -- command IAC
  3627.           temp_control_function := TRUE ;
  3628.         END IF ;
  3629.       END IF ;
  3630.     END IF ;
  3631.     
  3632.     char := temp_char;
  3633.     control_function := temp_control_function;
  3634.     urgent_data := temp_urgent_data;
  3635.  
  3636.   EXCEPTION
  3637.     WHEN OTHERS =>
  3638.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.input_chr") ;
  3639.       RAISE ;
  3640.  
  3641.   END input_character ; -- procedure body
  3642.  
  3643.     
  3644.   PROCEDURE process_standard_control_function -- body
  3645.             ---------------------------------
  3646.    (char : IN character_type ;
  3647.     urgent_data : IN BOOLEAN) 
  3648.    IS 
  3649.   -- ************************  BODY SPECIFICATION  ****************************
  3650.   -- 
  3651.   -- This procedure processes a control function which was received from
  3652.   -- the remote TELNET.  Handling of the TELNET synch mechanism is also done 
  3653.   -- here as follows.  The synch is sent via the transport level send 
  3654.   -- operation with the urgent flag set and the data mark (DM) as the last 
  3655.   -- (or only) data octet.  If the transport level urgent data flag is set, 
  3656.   -- the data stream is scanned for IP, AO, AYT, and DM signals.
  3657.   -- When in normal mode, the DM is a no-op; when in urgent mode, it signals
  3658.   -- the end of urgent processing.  If the transport level indicates the end 
  3659.   -- of urgent data before the DM is found, TELNET will continue special 
  3660.   -- handling of the data stream until the DM is found. If more urgent data is
  3661.   -- indicated after the DM is found, TELNET will continue special handling
  3662.   -- of the data stream until the DM is found.  NOTE: Site dependent code used
  3663.   -- for the IP and BREAK commands.
  3664.   -- See RFC 854, page 9 for details on the TELNET synch mechanism.
  3665.   -----------------------------------------------------------------------------
  3666.    
  3667.     option_code      : bit_count_8_type ;
  3668.     control_function : BOOLEAN ;
  3669.     urgent_flag      : BOOLEAN ;
  3670.     urgent           : CONSTANT BOOLEAN := TRUE ;
  3671.     not_urgent       : CONSTANT BOOLEAN := FALSE ;
  3672.     
  3673.   BEGIN -- process_standard_control_function  
  3674.  
  3675.     debug_io.put_line("begin atrinpac.process_standard_control_function") ;
  3676.     IF user_data.user_control_block.synch_is_in_progress THEN
  3677.       debug_io.put("synch is in progress,") ;
  3678.     ELSE
  3679.       debug_io.put("synch is NOT in progress,") ;
  3680.     END IF ;
  3681.     IF urgent_data THEN 
  3682.       debug_io.put("   urgent data,") ;
  3683.     ELSE
  3684.       debug_io.put("   NOT urgent data,") ;
  3685.     END IF ;
  3686.     debug_io.put("   char_code=") ; 
  3687.     debug_io.put_line_byte(char) ;
  3688.  
  3689.     IF user_data.user_control_block.synch_is_in_progress OR urgent_data THEN 
  3690.       user_data.user_control_block.synch_is_in_progress := TRUE ;
  3691.     END IF ;
  3692.       CASE char IS -- handle non synch char
  3693.         WHEN 240 | 241 | 250 => -- SE, NOP, SB (RFC 854, p. 14)
  3694.           NULL ; -- nop for now
  3695.         WHEN 242 => -- DM
  3696.           user_data.user_control_block.synch_is_in_progress := FALSE ;
  3697.         WHEN 243 => -- break ****** NOTE: SITE DEPENDENT CODE USED ******
  3698.           virtual_terminal.output_character_to_nvt_printer
  3699.            (user_data.user_control_block.port, 3) ; -- ctrl c for VAX
  3700.         WHEN 244 => -- IP  ****** NOTE: SITE DEPENDENT CODE USED ******
  3701.           virtual_terminal.output_character_to_nvt_printer
  3702.            (user_data.user_control_block.port, 25) ; -- ctrl y for VAX
  3703.         WHEN 245 => -- AO
  3704.           DECLARE -- (RFC 854, P. 7,8,&14)
  3705.             buffer : user_data.string_type(1..user_data.max_out_string) ;
  3706.             length : bit_count_16_type ;
  3707.             data_mark : virtual_transport_level.info_output_type(1..1) ;
  3708.           BEGIN -- declare
  3709.             data_mark(1) := 242 ;
  3710.             user_data.get_data_buffer(buffer, length) ; -- trash rest of buffer
  3711.             virtual_transport_level.send_data(data_mark, urgent) ; -- synch
  3712.           END ; -- declare
  3713.         WHEN 246 => -- AYT   (RFC 854, P. 13,14)
  3714.           DECLARE 
  3715.             ayt_responce     : STRING(1..12) := " I AM HERE. " ;
  3716.             ayt_responce_vtl : virtual_transport_level.info_output_type(1..12);
  3717.           BEGIN -- delcare
  3718.             ayt_responce(1) := ASCII.CR ;
  3719.             ayt_responce(12) := ASCII.CR ;
  3720.             FOR index IN ayt_responce'RANGE LOOP -- convert type
  3721.               ayt_responce_vtl(bit_count_16_type(index)) := 
  3722.                bit_count_8_type(CHARACTER'POS(ayt_responce(index))) ;
  3723.             END LOOP ;
  3724.             virtual_transport_level.send_data(ayt_responce_vtl, not_urgent) ;
  3725.           END ; -- declare
  3726.         WHEN 247 => -- EC  (RFC 854, P. 13,14)
  3727.           IF user_data.there_is_data_in_data_buffer AND 
  3728.             user_data.user_control_block.synch_is_in_progress = FALSE THEN
  3729.             DECLARE
  3730.               buffer : user_data.out_string_type ;
  3731.               length : bit_count_16_type RANGE 1..user_data.max_out_string ;
  3732.             BEGIN -- declare
  3733.               user_data.get_data_buffer(buffer, length) ;
  3734.               user_data.put_string_in_data_buffer(buffer(1..length - 1)) ; 
  3735.             END ; -- declare
  3736.           END IF ;
  3737.         WHEN 248 => -- EL
  3738.           IF user_data.there_is_data_in_data_buffer AND 
  3739.             user_data.user_control_block.synch_is_in_progress = FALSE THEN
  3740.             DECLARE
  3741.               buffer : user_data.out_string_type ;
  3742.               length : bit_count_16_type RANGE 1..user_data.max_out_string ;
  3743.             BEGIN -- declare
  3744.               user_data.get_data_buffer(buffer, length) ;
  3745.               FOR index IN REVERSE 1..length LOOP -- delete up to CRLF
  3746.                 IF bit_count_16_type(buffer(index)) = 10 THEN -- line feed
  3747.                   IF index > 1 AND THEN
  3748.                     bit_count_16_type(buffer(index - 1)) = 13 THEN -- cr
  3749.                     user_data.put_string_in_data_buffer(buffer(1..index)) ;
  3750.                     EXIT ; -- loop
  3751.                   END IF ; -- CR?
  3752.                 END IF ; -- LF?
  3753.               END LOOP ; -- delete up to CRLF
  3754.             END ; -- declare
  3755.           END IF ; -- data in buffer and no synch in progress?
  3756.         WHEN 249 => -- GA 
  3757.           user_data.user_control_block.ga_received := TRUE ;
  3758.         WHEN 251 => -- WILL (option code) 
  3759.           -- get option code
  3760.           WHILE NOT (virtual_transport_level.there_is_input) LOOP NULL ;
  3761.           END LOOP ; 
  3762.           virtual_transport_level.get_input(option_code, urgent_flag) ;
  3763.           option_negotiation.remote_will_received(option_code) ;
  3764.         WHEN 252 => -- WON'T (option code) 
  3765.           -- get option code
  3766.           WHILE NOT (virtual_transport_level.there_is_input) LOOP NULL ;
  3767.           END LOOP ;
  3768.           virtual_transport_level.get_input
  3769.            (option_code, urgent_flag) ;
  3770.           option_negotiation.remote_wont_received(option_code) ;
  3771.         WHEN 253 => -- DO (option code) 
  3772.           -- get option code
  3773.           WHILE NOT (virtual_transport_level.there_is_input) LOOP NULL ;
  3774.           END LOOP ;
  3775.           virtual_transport_level.get_input(option_code, urgent_flag) ;
  3776.           option_negotiation.remote_do_received(option_code) ;
  3777.         WHEN 254 => -- DON'T (option code) 
  3778.           -- get option code
  3779.           WHILE NOT (virtual_transport_level.there_is_input) LOOP NULL ;
  3780.           END LOOP ;
  3781.           virtual_transport_level.get_input(option_code, urgent_flag) ;
  3782.           option_negotiation.remote_dont_received(option_code) ;
  3783.         WHEN OTHERS => -- error 
  3784.           NULL ; 
  3785.       END CASE ; -- handle non synch char
  3786.     debug_io.put_line("begin atrinpac.process_standard_control_function") ;
  3787.  
  3788.   EXCEPTION
  3789.     WHEN OTHERS =>
  3790.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.proc_std_cf") ;
  3791.       debug_io.put("char=") ;
  3792.       debug_io.put_line_byte(char) ;
  3793.       RAISE ;
  3794.  
  3795.   END process_standard_control_function ; -- procedure body
  3796.  
  3797.  
  3798.   PROCEDURE write_character_to_NVT_printer -- body
  3799.             ------------------------------
  3800.    (char : IN character_type) IS
  3801.   BEGIN
  3802.     virtual_terminal.output_character_to_nvt_printer
  3803.     (user_data.user_control_block.port, char) ;
  3804.  
  3805.   EXCEPTION
  3806.     WHEN OTHERS =>
  3807.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.write_chr") ;
  3808.       RAISE ;
  3809.   END write_character_to_NVT_printer ; -- procedure body
  3810.  
  3811. BEGIN
  3812.   NULL ;
  3813.  
  3814.   EXCEPTION
  3815.     WHEN OTHERS =>
  3816.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac instantiation") ;
  3817.       RAISE ;
  3818.  
  3819. END transport_level_input_processing ; -- package body
  3820. --::::::::::::::
  3821. --akeybdpac_.ada
  3822. --::::::::::::::
  3823. -----------------------------------------------------------------------
  3824. --
  3825. --         DoD Protocols    NA-00004-200       80-01043-100(-)
  3826. --         E-Systems, Inc.  August 07, 1985
  3827. --
  3828. --         AKEYBDPAC_.ADA       Author : Mike Thomas 
  3829. --
  3830. -----------------------------------------------------------------------
  3831.  
  3832.  
  3833. -- File : akeybdpac
  3834.  
  3835. --   5/8/85  1:15 PM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS
  3836. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  3837.  
  3838. --   5/23/85 8:31 AM : MODIFY FOR TELESOFT        AUTHOR : MIKE THOMAS
  3839. --                     OLD CODE (DEC) MARKED AS --&MT 
  3840.  
  3841. --   5/23/85 10:09 AM : MODIFY FOR DEC ADA        AUTHOR : MIKE THOMAS
  3842. --                      OLD CODE (TELESOFT)  MARKED AS --&MT
  3843.  
  3844. WITH SYSTEM ; -- for access to system.byte
  3845. USE SYSTEM ;
  3846.  
  3847. PACKAGE nvt_keyboard_input_processing -- specification
  3848.         -----------------------------
  3849.  IS
  3850. -- ************************  USER SPECIFICATION  ******************************
  3851. --
  3852. -- This package provides subprograms to allow APL level processing of data 
  3853. -- entered into the Network Virtual Terminal (NVT) for a particular user of 
  3854. -- TELNET.
  3855. --
  3856. -- ****************************************************************************
  3857.  
  3858. --&MT   SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  3859.   SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  3860.  
  3861.   SUBTYPE character_type IS bit_count_8_type ;
  3862.  
  3863.   FUNCTION there_is_input_from_the_NVT_keyboard
  3864.            ------------------------------------
  3865.    RETURN BOOLEAN ;
  3866.   -- ************************  USER SPECIFICATION  ****************************
  3867.   --
  3868.   -- This function returns true if there is input from the NVT keyboard.
  3869.   -----------------------------------------------------------------------------
  3870.  
  3871.  
  3872.   PROCEDURE get_a_character
  3873.             ---------------
  3874.    (char : OUT character_type ;
  3875.     the_char_is_a_control_function : OUT BOOLEAN) ;
  3876.   -- ************************  USER SPECIFICATION  ****************************
  3877.   --
  3878.   -- This routine returns a logical character from the NVT keyboard and 
  3879.   -- indicates whether the character is to be interpreted as a control 
  3880.   -- function or data.
  3881.   -----------------------------------------------------------------------------
  3882.  
  3883.  
  3884.  
  3885.   PROCEDURE process_standard_control_function_from_keyboard
  3886.             -----------------------------------------------
  3887.    (char : IN character_type) ;
  3888.   -- ************************  USER SPECIFICATION  ****************************
  3889.   --
  3890.   -- This procedure will perform the appropriate action for the specified 
  3891.   -- control function.
  3892.   -----------------------------------------------------------------------------
  3893.  
  3894.  
  3895.   PROCEDURE process_partial_command
  3896.             -----------------------
  3897.    (char : IN character_type) ;
  3898.   -- ************************  USER SPECIFICATION  ****************************
  3899.   --
  3900.   -- This procedure will process the character as part of a parital command.
  3901.   -----------------------------------------------------------------------------
  3902.  
  3903.  
  3904.   PROCEDURE put_character_in_data_buffer
  3905.             ----------------------------
  3906.    (char : IN character_type) ;
  3907.   -- ************************  USER SPECIFICATION  ****************************
  3908.   --
  3909.   -- This procedure will put a character into the APL keyboard data buffer.
  3910.   -----------------------------------------------------------------------------
  3911.  
  3912.  
  3913.   PROCEDURE send_data_buffer_to_transport_level ;
  3914.             -----------------------------------
  3915.   -- ************************  USER SPECIFICATION  ****************************
  3916.   --
  3917.   -- This procedure will send the entire contents of the APL keyboard data
  3918.   -- buffer to the transport level for transmission to the remote TELNET.
  3919.   -----------------------------------------------------------------------------
  3920.  
  3921.  
  3922. END nvt_keyboard_input_processing ; -- specification
  3923.  
  3924. --::::::::::::::
  3925. --akeybdpac.ada
  3926. --::::::::::::::
  3927. -----------------------------------------------------------------------
  3928. --
  3929. --         DoD Protocols    NA-00004-200       80-01044-100(-)
  3930. --         E-Systems, Inc.  August 07, 1985
  3931. --
  3932. --         AKEYBDPAC.ADA       Author : Mike Thomas 
  3933. --
  3934. -----------------------------------------------------------------------
  3935.  
  3936.  
  3937. -- File : akeybdpac
  3938.  
  3939. --   5/8/85  1:35 PM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS
  3940. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  3941.  
  3942. --   5/23/85 8:31 AM : MODIFY FOR TELESOFT        AUTHOR : MIKE THOMAS
  3943. --                     OLD CODE (DEC) MARKED AS --&MT 
  3944.  
  3945. --   5/23/85  2:09 PM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS 
  3946. --                      OLD CODE (TELESOFT) MARKED AS --&MT 
  3947. --   6/23/85  9:08 PM : set ga_received = false in send_data_buffer
  3948. --    6/1/85  1:12 PM : add quit option commands, remove status var from opt reqs
  3949.  
  3950. WITH virtual_terminal ;
  3951. WITH virtual_transport_level ;
  3952. WITH option_negotiation ;
  3953. WITH user_data ;
  3954. USE user_data ;
  3955. WITH debug_io ; -- for test debug
  3956.  
  3957.  
  3958. PACKAGE BODY  nvt_keyboard_input_processing IS
  3959.               -----------------------------
  3960.  
  3961.   --&MT SUBTYPE bit_count_32_type IS LONG_INTEGER ; 
  3962.   SUBTYPE bit_count_32_type IS INTEGER ;
  3963.  
  3964.   --&MT SUBTYPE bit_count_16_type IS INTEGER ; 
  3965.   SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  3966.  
  3967.   FUNCTION there_is_input_from_the_NVT_keyboard
  3968.            ------------------------------------
  3969.    RETURN BOOLEAN IS
  3970.   BEGIN
  3971.     RETURN virtual_terminal.there_are_characters_in_keyboard_buffer
  3972.      (user_data.user_control_block.port) ;
  3973.   END there_is_input_from_the_NVT_keyboard ;
  3974.  
  3975.  
  3976.   PROCEDURE get_a_character
  3977.             ---------------
  3978.    (char : OUT character_type ;
  3979.     the_char_is_a_control_function : OUT BOOLEAN) IS
  3980.  
  3981.     temp_char : character_type ;
  3982.     temp_the_char_is_a_control_function : BOOLEAN ;
  3983.  
  3984.     PROCEDURE determine_if -- control function?
  3985.               ------------
  3986.      (the_char_is_a_control_function : OUT BOOLEAN ;
  3987.       char                           : IN  bit_count_8_type) IS --TBD
  3988.     BEGIN
  3989.       the_char_is_a_control_function := FALSE ; -- add real check later(TBD)
  3990.     END determine_if ;
  3991.  
  3992.   BEGIN
  3993.     virtual_terminal.get_next_character_from_keyboard_buffer 
  3994.      (user_data.user_control_block.port, temp_char) ;
  3995.     determine_if(temp_the_char_is_a_control_function, temp_char) ;
  3996.     char := temp_char ;
  3997.     the_char_is_a_control_function := temp_the_char_is_a_control_function ;
  3998.   EXCEPTION
  3999.     WHEN OTHERS =>
  4000.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.get_a_char") ;
  4001.       RAISE ;
  4002.   END get_a_character ;
  4003.  
  4004.  
  4005.   PROCEDURE process_standard_control_function_from_keyboard
  4006.             -----------------------------------------------
  4007.    (char : IN character_type) IS
  4008.  
  4009.   IAC : bit_count_8_type := 255 ; -- interprate as command
  4010.   no_partial_command : user_data.command_state_type ; 
  4011.   urgent : BOOLEAN := TRUE ; -- tcp urgent flag 
  4012.   command_bytes : virtual_transport_level.info_output_type(1..2) ; 
  4013.  
  4014.   BEGIN
  4015.     no_partial_command := user_data.no_partial_command ;
  4016.     CASE char IS -- page 14 of RFC 854
  4017.       WHEN 242..249 => -- Break, IP, AO, AYT, EC, EL, GA,
  4018.         -- put in data buffer or command buffer baised on command state 
  4019.         IF user_data.user_control_block.command_state = no_partial_command THEN
  4020.           put_character_in_data_buffer(IAC) ;
  4021.           put_character_in_data_buffer(char) ;
  4022.         ELSE -- partial command (EC, EL handled loacaly, rest==>"bad")
  4023.           process_partial_command(char) ;
  4024.         END IF ; -- not a partial command
  4025.       WHEN OTHERS =>
  4026.         NULL ; -- T B D  error condition
  4027.     END CASE ; 
  4028.   EXCEPTION
  4029.     WHEN OTHERS =>
  4030.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.proc_std_cont_f") ;
  4031.       RAISE ;
  4032.   END process_standard_control_function_from_keyboard ;
  4033.  
  4034.  
  4035.   PROCEDURE process_partial_command
  4036.             -----------------------
  4037.    (char : IN character_type) IS 
  4038.   -- ************************  BODY SPECIFICATION  ****************************
  4039.   --
  4040.   -- This procedure will process the character as part of a partial command.
  4041.   -- 
  4042.   -- Processing sequence...
  4043.   --
  4044.   -- If the character is not an end-of-line, add the character to the 
  4045.   -- partial command buffer.  If the character is an end-of-line, the 
  4046.   -- command will be parsed for semantics and the appropriate call will 
  4047.   -- be made to the presentation level which will convert the desired 
  4048.   -- action into the syntax of a call to the actual transport level.  Whether 
  4049.   -- or not the complete command was entered properly, the command state 
  4050.   -- will be set to no-partial-command.
  4051.  
  4052. -------------------------------------------------------------------------------
  4053. -- *** run-time compiler error: the initialization part of the declaration
  4054. --
  4055. --     does not happen at run time.  If the initialization is done explicitly
  4056. --     in the body part, the variable will be properly set.  Will just use
  4057. --     fully qualified name in body part.  TeleHosed again.
  4058. --     
  4059. --    no_partial_command : user_data.command_state_type := no_partial_command ;
  4060. -------------------------------------------------------------------------------
  4061.  
  4062.     ------------------------  subprogram declarations  ------------------------
  4063.  
  4064.     PROCEDURE add_the_character_to_the_partial_command_buffer
  4065.               -----------------------------------------------
  4066.      (char : IN character_type) IS
  4067.     -- ***************************  SPECIFICATION  ****************************
  4068.     --
  4069.     -- This procedure will place a character into the partial command buffer.
  4070.     -- If the character is an erase character or erase line then remove
  4071.     -- one or all of the characters.  If all the characters have been 
  4072.     -- erased, set the command_state to no_partial_command.
  4073.     ---------------------------------------------------------------------------
  4074.     
  4075.     command_buffer      : user_data.out_string_type ;
  4076. --&MT SUBTYPE length_type IS bit_count_16_type RANGE 1..user_data.max_out_string ;
  4077.      --&MT the above line caused a constraint error ; use the next line instead
  4078.     SUBTYPE length_type IS bit_count_16_type RANGE 0..user_data.max_out_string ;
  4079.     length              : length_type ;
  4080.     no_partial_command  : user_data.command_state_type ;
  4081.     slash               : CONSTANT bit_count_8_type := 16#2F# ; -- '/' 
  4082.     E                   : CONSTANT bit_count_8_type := 16#45# ; -- 'E' 
  4083.     L                   : CONSTANT bit_count_8_type := 16#4C# ; -- 'L' 
  4084.     B                   : CONSTANT bit_count_8_type := 16#42# ; -- 'B' 
  4085.     A                   : CONSTANT bit_count_8_type := 16#41# ; -- 'A' 
  4086.     D                   : CONSTANT bit_count_8_type := 16#44# ; -- 'D' 
  4087.     bell                : CONSTANT bit_count_8_type := 16#07# ; -- '^G' 
  4088.     cr                  : CONSTANT bit_count_8_type := 16#0D# ; -- 'carrage return' 
  4089.     lf                  : CONSTANT bit_count_8_type := 16#0A# ; -- 'line feed'
  4090.     not_control_char    : BOOLEAN := FALSE ;
  4091.     BEGIN -- add_the_character_to_the_partial_command_buffer
  4092.       no_partial_command := user_data.no_partial_command ;
  4093.       CASE char IS -- page 14 of RFC 854
  4094.         WHEN 247 | 248 => -- EC, EL
  4095.           IF user_data.there_is_data_in_command_buffer THEN
  4096.             user_data.get_command_buffer(command_buffer, length) ;
  4097.             IF char = 247 THEN -- EC
  4098.               -- put all but one back into the buffer
  4099.               FOR index IN 1..length-1 LOOP 
  4100.                 user_data.put_char_in_command_buffer(command_buffer(index)) ;
  4101.               END LOOP ;
  4102.               -- show character was deleted on nvt printer
  4103.               -- could be more eligant later on
  4104.               virtual_terminal.output_character_to_nvt_printer
  4105.                (user_data.user_control_block.port, slash) ; 
  4106.               virtual_terminal.output_character_to_nvt_printer
  4107.                (user_data.user_control_block.port, command_buffer(length)) ;
  4108.               virtual_terminal.output_character_to_nvt_printer
  4109.                (user_data.user_control_block.port, slash) ;
  4110.               length := length - 1 ;
  4111.             ELSE -- EL
  4112.               -- show line was deleted on nvt printer
  4113.               -- could be more eligant later on
  4114.               virtual_terminal.output_character_to_nvt_printer
  4115.                (user_data.user_control_block.port, slash) ;
  4116.               virtual_terminal.output_character_to_nvt_printer
  4117.                (user_data.user_control_block.port, E) ;
  4118.               virtual_terminal.output_character_to_nvt_printer
  4119.                (user_data.user_control_block.port, L) ;
  4120.               virtual_terminal.output_character_to_nvt_printer
  4121.                (user_data.user_control_block.port, slash) ;
  4122.               virtual_terminal.output_character_to_nvt_printer
  4123.                (user_data.user_control_block.port, cr) ;
  4124.               virtual_terminal.output_character_to_nvt_printer
  4125.                (user_data.user_control_block.port, lf) ;
  4126.               length := 0 ;  
  4127.             END IF ; -- EC or EL ?
  4128.             IF length = 0 THEN 
  4129.               user_data.user_control_block.command_state := 
  4130.                no_partial_command ;
  4131.             END IF ; -- length = 0?
  4132.           END IF ; -- data in command buffer?
  4133.         WHEN 242 | 243 | 244 | 245 | 246 | 249 => 
  4134.         -- not EC or EL control function ==> not allowed in command string
  4135.           user_data.user_control_block.command_state := no_partial_command ;
  4136.           virtual_terminal.output_character_to_nvt_printer
  4137.                (user_data.user_control_block.port, B) ;
  4138.           virtual_terminal.output_character_to_nvt_printer
  4139.                (user_data.user_control_block.port, A) ;
  4140.           virtual_terminal.output_character_to_nvt_printer
  4141.                (user_data.user_control_block.port, D) ;
  4142.           virtual_terminal.output_character_to_nvt_printer
  4143.                (user_data.user_control_block.port, bell) ;
  4144.           virtual_terminal.output_character_to_nvt_printer
  4145.                (user_data.user_control_block.port, cr) ;
  4146.           virtual_terminal.output_character_to_nvt_printer
  4147.                (user_data.user_control_block.port, lf) ;
  4148.         WHEN OTHERS => -- non-control function
  4149.           user_data.put_char_in_command_buffer(char) ;        
  4150.       END CASE ; 
  4151.   EXCEPTION
  4152.     WHEN OTHERS =>
  4153.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.add_char_to_pcb") ;
  4154.       RAISE ;
  4155.     END add_the_character_to_the_partial_command_buffer ;
  4156.  
  4157.  
  4158.     PROCEDURE
  4159.      parse_command_buffer_for_semantics_and_make_call_to_presentation_level
  4160.      ----------------------------------------------------------------------
  4161.      IS 
  4162.     -- **********************  USER SPECIFICATION  ****************************
  4163.     --
  4164.     -- This procedure will examine the command buffer and make the proper
  4165.     -- PPL procedure call to carry out that command action.
  4166.     ---------------------------------------------------------------------------
  4167.     
  4168.       command : user_data.out_string_type ;
  4169.       SUBTYPE length_type IS bit_count_16_type  RANGE 1..user_data.max_cmd_length ; 
  4170.       length : length_type ;
  4171.  
  4172.       command_string : STRING (1..bit_count_32_type(user_data.max_cmd_length)) ;
  4173.       --&MT command_string : STRING (1..user_data.max_cmd_length) ;
  4174.  
  4175.       successful : BOOLEAN ;
  4176.       TYPE command_type IS (open_command, close_command, status_command,
  4177.        reset_command, echo_local_command, echo_remote_command,
  4178.        suppress_ga_local_command, suppress_ga_remote_command, 
  4179.        send_abort_output_command, send_are_you_there_command,
  4180.        send_break_command, send_erase_character_command,
  4181.        send_erase_line_command, send_interrupt_process_command,
  4182.        send_sync_command, quit_echo_local_command, quit_echo_remote_command,
  4183.        quit_suppress_ga_local_command, quit_suppress_ga_remote_command,
  4184.        bad_command) ;
  4185.       type_of_command : command_type ;
  4186.       not_urgent : BOOLEAN := FALSE ; -- tcp urgent flag 
  4187.       urgent : BOOLEAN := TRUE ; -- tcp urgent flag 
  4188.       command_bytes : virtual_transport_level.info_output_type(1..2) ; 
  4189.       not_control_characters : BOOLEAN := FALSE ;
  4190.       TYPE bytes_type IS ARRAY (bit_count_16_type RANGE <>) OF bit_count_8_type ;
  4191.  
  4192.       address_length      : bit_count_32_type ; -- open address parameter string length
  4193.       --&MT address_length      : bit_count_16_type ;
  4194.  
  4195.       network_number      : bit_count_16_type ; -- open parameters
  4196.       host_number         : bit_count_16_type ;
  4197.       logical_host_number : bit_count_16_type ;
  4198.       imp_number          : bit_count_16_type ;
  4199.       port_number         : bit_count_16_type ;
  4200.  
  4201.       PROCEDURE determine_command_type
  4202.                 ----------------------
  4203.        (command_string_in  : IN STRING ;
  4204.  
  4205.         length             : IN bit_count_32_type ;
  4206.         --&MT   length             : IN bit_count_16_type ;
  4207.  
  4208.         type_of_command    : OUT command_type) IS 
  4209.       -- *************************  SPECIFICATION  ****************************
  4210.       --
  4211.       -- This procedure will examine the command string and determine type
  4212.       -- of command.  In the case of an 'open' command, the parameters
  4213.       -- will be set to the correct values.
  4214.       -------------------------------------------------------------------------
  4215.  
  4216.         command_string : STRING(1..length + 3) ; -- make room for future padding
  4217.         ok : BOOLEAN ;
  4218.  
  4219.         PROCEDURE strip_off_extra_characters 
  4220.                   --------------------------
  4221.          (item : IN OUT STRING ;
  4222.  
  4223.           string_length : IN OUT bit_count_32_type) IS
  4224.           --&MT     string_length : IN OUT bit_count_16_type) IS
  4225.  
  4226.         -- *************************  SPECIFICATION  **************************
  4227.         -- 
  4228.         -- This procedure returns a string in which the first four characters 
  4229.         -- are comprised of the first character of each word in the command.
  4230.         -- If less than three words are in the command the missing word's
  4231.         -- position(s) are padded with blanks.  If the command was an OPEN,
  4232.         -- the remainder of the string is the OPEN address.
  4233.         -----------------------------------------------------------------------
  4234.  
  4235.           kept_pos : bit_count_32_type RANGE 1..string_length + 3 := 1 ; -- see below
  4236. --&MT     kept_pos : bit_count_16_type RANGE 1..string_length + 3 := 1 ;
  4237.  
  4238.           kept_buffer : STRING (1..string_length + 3) ; -- allow for padding bl
  4239.           store_char : BOOLEAN := FALSE ;
  4240.           -- open address starting location
  4241.  
  4242.           adr_start_pos : bit_count_32_type RANGE 1..string_length ; 
  4243. --&MT     adr_start_pos : bit_count_16_type RANGE 1..string_length ;
  4244.           
  4245.         BEGIN -- strip off extra characters
  4246.           debug_io.put("in strip off extra characters, item=") ;
  4247.           debug_io.put(item(1..string_length)) ;
  4248.           debug_io.put("  string_length=") ;
  4249.           debug_io.put_line(bit_count_16_type(string_length)) ;
  4250.           IF item(2) = 'O' OR item(2) = 'o' THEN -- open (has parameters) (remove '@')
  4251.             debug_io.put_line("open detected") ;
  4252.             kept_buffer(1..4) :="O   " ; -- pad 
  4253.             kept_pos := 4 ;
  4254.             FOR index IN 3..string_length LOOP  -- skip any extra letters
  4255.               IF item(index) = ' ' THEN -- end of "open", start of address
  4256.                 adr_start_pos := index + 1 ;
  4257.                 EXIT ; -- skip any extra characters loop
  4258.               END IF ;
  4259.             END LOOP ; -- skip
  4260.             FOR index IN adr_start_pos..string_length LOOP -- copy address
  4261.               kept_pos := kept_pos + 1 ;
  4262.               kept_buffer(kept_pos) := item(index) ;
  4263.             END LOOP ;
  4264.             string_length := kept_pos ;
  4265.             debug_io.put_line("open processed") ;
  4266.           ELSE --(no parameters)
  4267.             debug_io.put_line("non-open detected") ;
  4268.             kept_buffer(1) := item(2) ; -- remove '@'
  4269.             FOR item_pos IN 3..string_length LOOP
  4270.               debug_io.put("item_pos=") ;
  4271.               debug_io.put(bit_count_16_type(item_pos)) ;
  4272.               debug_io.put(" item(item_pos)=") ;
  4273.               debug_io.put_line(item(item_pos)) ;
  4274.               IF item(item_pos) = ' ' THEN -- delimiter
  4275.                 store_char := TRUE ;
  4276.               ELSE -- non blank
  4277.                 IF store_char THEN 
  4278.                   kept_pos := kept_pos + 1 ;
  4279.                   kept_buffer(kept_pos) := item(item_pos) ;
  4280.                   store_char := FALSE ;
  4281.                 END IF ; -- store char?
  4282.               END IF ; -- blank character?
  4283.             END LOOP ; -- examine all positions
  4284.             FOR pad_pos IN kept_pos+1..4 LOOP -- pad with blanks
  4285.                kept_pos := kept_pos + 1 ;
  4286.                kept_buffer(pad_pos) := ' ' ;
  4287.             END LOOP ; -- pad
  4288.             string_length := 0 ; -- no params
  4289.           END IF ; -- item(1) = 'O'?
  4290.           item(1..kept_pos) := kept_buffer(1..kept_pos) ;
  4291.           debug_io.put("leaving strip off extra characters, item=") ;
  4292.           debug_io.put(item(1..kept_pos)) ;
  4293.           debug_io.put(" string_length=") ;
  4294.           debug_io.put_line(bit_count_16_type(string_length)) ;
  4295.         EXCEPTION
  4296.           WHEN OTHERS =>
  4297.             debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.strip_ex") ;
  4298.             RAISE ;
  4299.         END strip_off_extra_characters ;
  4300.  
  4301.         
  4302.         PROCEDURE process_open_command_parameters IS
  4303.                   -------------------------------
  4304.           good_number : BOOLEAN ; -- true if number-to-string convert ok
  4305.  
  4306.           PROCEDURE strip_command_to_address
  4307.                     ------------------------
  4308.            (command_string : IN OUT STRING ;
  4309.  
  4310.             address_length : IN OUT bit_count_32_type) IS
  4311. --&MT       address_length : IN OUT bit_count_16_type) IS
  4312.  
  4313.           -- this procedure strips the leading 'O' and blanks from the
  4314.           -- command string
  4315.  
  4316.             SUBTYPE string_position_type IS
  4317.  
  4318.         bit_count_32_type RANGE 0..bit_count_32_type(user_data.max_cmd_length) ;
  4319. --&MT   bit_count_16_type RANGE 0..bit_count_16_type(user_data.max_cmd_length) ;
  4320.  
  4321.             com_pos : string_position_type ;
  4322.             
  4323.             com_buf : STRING (1..bit_count_32_type(user_data.max_cmd_length)) ;
  4324. --&MT       com_buf : STRING (1..user_data.max_cmd_length) ;
  4325.  
  4326.             buf_pos : string_position_type := 0 ;
  4327.  
  4328.           BEGIN -- strip_command_to_address
  4329.             debug_io.put_line("in strip_command_to_address") ;
  4330.             debug_io.put(" address_length=") ;
  4331.             debug_io.put_line(bit_count_16_type(address_length)) ;
  4332.  
  4333.             FOR com_pos IN 2..address_length LOOP
  4334.               IF command_string(com_pos) /= ' ' THEN 
  4335.                 buf_pos := buf_pos + 1 ;
  4336.                 com_buf(buf_pos) := command_string(com_pos) ;
  4337.               END IF ;
  4338.             END LOOP ;
  4339.             command_string(1..buf_pos) := com_buf(1..buf_pos) ;
  4340.             debug_io.put("command string=") ;
  4341.             debug_io.put_line(command_string(1..buf_pos)) ;
  4342.             address_length := buf_pos ;
  4343.             debug_io.put("address_length=") ;
  4344.             debug_io.put_line(bit_count_16_type(address_length)) ;
  4345.             debug_io.put_line("end strip_command_to_adress") ;
  4346.           EXCEPTION
  4347.             WHEN OTHERS =>
  4348.               debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.strip_addr") ;
  4349.               RAISE ;
  4350.           END strip_command_to_address ;
  4351.  
  4352.  
  4353.           PROCEDURE convert_string_to_integer -- author : Mark Volpe
  4354.            (input_string  : IN  STRING ;
  4355.             integer_value : OUT bit_count_16_type ;
  4356.             status        : OUT BOOLEAN) IS 
  4357.  
  4358.             next_value       : bit_count_16_type  := 0 ;
  4359.             power_of_ten     : bit_count_16_type  := 1 ;
  4360.             character_offset : bit_count_16_type  := CHARACTER'POS('0') ;
  4361.  
  4362.             temp_integer_value : bit_count_16_type := 0 ;
  4363.             temp_status : BOOLEAN := TRUE ;
  4364.             
  4365.           BEGIN
  4366.             FOR index IN REVERSE INPUT_STRING'RANGE LOOP
  4367.               IF (input_string(index)<'0') OR (input_string(index)>'9') THEN
  4368.                 temp_status := FALSE ;
  4369.               EXIT ; -- loop
  4370.               END IF ;
  4371.               IF CHARACTER'POS(input_string(index))-character_offset = 0 THEN
  4372.                 NULL ;
  4373.               ELSIF power_of_ten >
  4374.                 ((bit_count_16_type'LAST - temp_integer_value) /
  4375.                  (CHARACTER'POS(input_string(index)) -
  4376.                  character_offset)) THEN
  4377.                 temp_status := FALSE ;
  4378.                 EXIT ; -- loop
  4379.               ELSE
  4380.                 temp_integer_value := temp_integer_value + 
  4381.                  (CHARACTER'POS(input_string(index)) - 
  4382.                  character_offset) * 
  4383.                  power_of_ten ;
  4384.               END IF ;
  4385.               power_of_ten := power_of_ten * 10 ;
  4386.             END LOOP ;
  4387.             integer_value := temp_integer_value ;
  4388.             status := temp_status ;
  4389.           EXCEPTION
  4390.             WHEN OTHERS =>
  4391.               debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.conv_s_i") ;
  4392.               RAISE ;
  4393.           END convert_string_to_integer ;
  4394.  
  4395.  
  4396.           PROCEDURE get_port_number 
  4397.                     ---------------
  4398.            (address    : IN     STRING ;
  4399.  
  4400.             length     : IN OUT bit_count_32_type ;
  4401. --&MT       length     : IN OUT bit_count_16_type ;
  4402.  
  4403.             status_ok  :    OUT BOOLEAN) IS
  4404.           BEGIN -- get port number
  4405.             debug_io.put_line("in get port number") ;
  4406.             port_number := 23 ; -- default port number:RFC 854,page 15
  4407.             status_ok := TRUE ;
  4408.             FOR index IN REVERSE 1..length LOOP
  4409.               IF address(index) = ';' THEN -- port number specified
  4410.                 convert_string_to_integer(address(index+1..length),
  4411.                  port_number, status_ok) ;
  4412.                 length := index - 1 ; -- length of remaining address string
  4413.                 EXIT ; -- LOOP
  4414.               END IF ; -- ';'?
  4415.             END LOOP ;
  4416.             debug_io.put("port #=") ;
  4417.             debug_io.put_line(port_number) ;
  4418.             debug_io.put("length=") ;
  4419.             debug_io.put_line(bit_count_16_type(length)) ;
  4420.             debug_io.put_line("end get port number") ;
  4421.           EXCEPTION
  4422.             WHEN OTHERS =>
  4423.               debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.get_port") ;
  4424.               RAISE ;
  4425.           END get_port_number ;
  4426.  
  4427.  
  4428.           PROCEDURE get_next_number -- get next # from address string
  4429.                     ---------------
  4430.            (address   : IN     STRING ;
  4431.  
  4432.             length    : IN OUT bit_count_32_type ;
  4433. --&MT       length    : IN OUT bit_count_16_type ;
  4434.  
  4435.             number    :    OUT bit_count_16_type ;
  4436.             ok        :    OUT BOOLEAN) IS
  4437.  
  4438.             temp_number : bit_count_16_type ;
  4439.             temp_ok : BOOLEAN ;
  4440.             SUBTYPE string_position_type IS
  4441.              bit_count_16_type RANGE 0..user_data.max_cmd_length ;
  4442.  
  4443.             buf_pos : bit_count_32_type := 0 ;
  4444. --&MT       buf_pos : bit_count_16_type := 0 ;
  4445.  
  4446.             num_buf : STRING (1..bit_count_32_type(user_data.max_cmd_length)) ;
  4447. --&MT       num_buf : STRING (1..user_data.max_cmd_length) ;
  4448.  
  4449.             delimiter : CHARACTER := '.' ;
  4450.  
  4451.             delimiter_found : bit_count_32_type RANGE 0..1 := 0 ;
  4452. --&MT       delimiter_found : bit_count_16_type RANGE 0..1 := 0 ;
  4453.  
  4454.             num_digits : bit_count_32_type RANGE 0..5 := 0 ;
  4455. --&MT       num_digits : bit_count_16_type RANGE 0..5 := 0 ;
  4456.  
  4457.           BEGIN -- get next number
  4458.             debug_io.put_line("in get next number") ;
  4459.             debug_io.put("address=") ;
  4460.             debug_io.put_line(address(1..length)) ;
  4461.             debug_io.put("length=") ;
  4462.             debug_io.put_line(bit_count_16_type(length)) ;
  4463.             temp_ok := TRUE ;
  4464.             FOR add_pos IN REVERSE 1..length LOOP -- find rightmost #
  4465.               IF address(add_pos) = delimiter THEN  
  4466.                 delimiter_found := 1 ; -- subtract 1 from final length of string
  4467.                 EXIT ; -- loop
  4468.               ELSE
  4469.                 num_digits := num_digits + 1 ;
  4470.               END IF ;
  4471.             END LOOP ;
  4472.             FOR add_pos IN length-num_digits+1..length LOOP -- get number
  4473.               buf_pos := buf_pos + 1 ;
  4474.               num_buf(buf_pos) := address(add_pos) ;
  4475.             END LOOP ;
  4476.             IF num_digits /= 0 THEN
  4477.               convert_string_to_integer(num_buf(1..num_digits), temp_number, temp_ok) ;
  4478.             ELSE -- set to a default of zero
  4479.               temp_number := 0 ;
  4480.             END IF ;   
  4481.             length := length - num_digits - delimiter_found ;
  4482.             debug_io.put_line("after processing...") ;
  4483.             debug_io.put("length=") ;
  4484.             debug_io.put_line(bit_count_16_type(length)) ;
  4485.             IF temp_ok THEN
  4486.               debug_io.put("number=") ;
  4487.               debug_io.put_line(temp_number) ;
  4488.             END IF ;
  4489.             number := temp_number ;
  4490.               ok := temp_ok ;
  4491.           EXCEPTION
  4492.             WHEN OTHERS =>
  4493.               debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.get_num") ;
  4494.               RAISE ;
  4495.           END get_next_number ;
  4496.  
  4497.  
  4498.           PROCEDURE get_imp_number
  4499.                     --------------
  4500.            (address    : IN     STRING ;
  4501.  
  4502.             length     : IN OUT bit_count_32_type ;
  4503. --&MT       length     : IN OUT bit_count_16_type ;
  4504.  
  4505.             status_ok  :    OUT BOOLEAN) IS 
  4506.           
  4507.             temp_status_ok : BOOLEAN ;
  4508.    
  4509.           BEGIN -- get imp number
  4510.             debug_io.put_line("in get imp #") ;
  4511.             get_next_number(address, length, imp_number, temp_status_ok) ;
  4512.             debug_io.put("imp_number=") ;
  4513.             debug_io.put_line(imp_number) ;
  4514.             IF imp_number = 0 THEN -- no imp number given, no default allowed
  4515.               temp_status_ok := FALSE ;
  4516.             END IF ;
  4517.             debug_io.put_line("end get imp #") ;
  4518.             status_ok := temp_status_ok ;
  4519.           EXCEPTION
  4520.             WHEN OTHERS =>
  4521.               debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.get_imp") ;
  4522.               RAISE ;
  4523.          END get_imp_number ;
  4524.  
  4525.  
  4526.           PROCEDURE get_logical_host_number
  4527.                     -----------------------
  4528.            (address    : IN OUT STRING ;
  4529.  
  4530.             length     : IN OUT bit_count_32_type ;
  4531. --&MT       length     : IN OUT bit_count_16_type ;
  4532.  
  4533.             status_ok  :    OUT BOOLEAN) IS 
  4534.  
  4535.              temp_status_ok : BOOLEAN ;
  4536.           BEGIN -- get logical host number
  4537.             debug_io.put_line("in get logical host #") ;
  4538.             get_next_number
  4539.              (address, length, logical_host_number, temp_status_ok) ;
  4540.             debug_io.put("logical_host_number=") ;
  4541.             debug_io.put_line(logical_host_number) ;
  4542.             debug_io.put_line("end get logical host #") ;
  4543.             status_ok := temp_status_ok ;
  4544.           EXCEPTION
  4545.             WHEN OTHERS =>
  4546.               debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.get_lhost") ;
  4547.               RAISE ;
  4548.           END get_logical_host_number ;
  4549.  
  4550.  
  4551.           PROCEDURE get_host_number
  4552.                     ---------------
  4553.            (address    : IN OUT STRING ;
  4554.  
  4555.             length     : IN OUT bit_count_32_type ;
  4556. --&MT       length     : IN OUT bit_count_16_type ;
  4557.  
  4558.             status_ok  :    OUT BOOLEAN) IS 
  4559.  
  4560.             temp_status_ok : BOOLEAN ;
  4561.  
  4562.           BEGIN -- get host number
  4563.             debug_io.put_line("in get_host_#") ;
  4564.             get_next_number(address, length, host_number, temp_status_ok) ;
  4565.             debug_io.put("host #=") ;
  4566.             debug_io.put_line(host_number) ;
  4567.             debug_io.put_line("end get_host_#") ;
  4568.             status_ok := temp_status_ok ;
  4569.           EXCEPTION
  4570.             WHEN OTHERS =>
  4571.               debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.get_host") ;
  4572.               RAISE ;
  4573.           END get_host_number ;
  4574.  
  4575.  
  4576.           PROCEDURE get_network_number
  4577.                     ------------------
  4578.            (address    : IN OUT STRING ;
  4579.  
  4580.             length     : IN OUT bit_count_32_type ;
  4581. --&MT       length     : IN OUT bit_count_16_type ;
  4582.  
  4583.             status_ok  :    OUT BOOLEAN) IS 
  4584.  
  4585.             temp_status_ok : BOOLEAN ;
  4586.  
  4587.           BEGIN -- get network number
  4588.             debug_io.put_line("in get_network_#") ;
  4589.             get_next_number(address, length, network_number, temp_status_ok) ;
  4590.             IF network_number = 0 THEN -- use default
  4591.               network_number := 10 ; -- arpanet
  4592.             END IF ;
  4593.             debug_io.put("network #=") ;
  4594.             debug_io.put_line(network_number) ;
  4595.             debug_io.put_line("in get_network_#") ;
  4596.             status_ok := temp_status_ok ;
  4597.           EXCEPTION
  4598.             WHEN OTHERS =>
  4599.               debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.get_net") ;
  4600.               RAISE ;
  4601.           END get_network_number ;
  4602.  
  4603.         BEGIN -- process_open_command_parameters 
  4604.           debug_io.put_line("in process_open_command_parameters") ;
  4605.           debug_io.put_line("pre strip") ;
  4606.           strip_command_to_address(command_string(1..address_length),
  4607.            address_length) ;
  4608.           debug_io.put_line("post strip, pre get_port_#") ;
  4609.           get_port_number(command_string, address_length, ok) ;
  4610.           debug_io.put_line("post get_port_#") ;
  4611.           IF ok THEN
  4612.             debug_io.put_line("pre get imp#") ;
  4613.             get_imp_number(command_string(1..address_length),
  4614.              address_length, ok) ;
  4615.             debug_io.put_line("post get imp #") ;
  4616.           IF ok THEN
  4617.             debug_io.put_line("pre get logical host #") ;
  4618.             get_logical_host_number(command_string(1..address_length),
  4619.              address_length, ok) ;
  4620.             debug_io.put_line("post get logical host#") ;
  4621.           IF ok THEN
  4622.             debug_io.put_line("pre get host #") ;
  4623.             get_host_number(command_string, address_length, ok) ;
  4624.             debug_io.put_line("post get host #") ;
  4625.           IF ok THEN
  4626.             debug_io.put_line("pre get network number") ;
  4627.             get_network_number(command_string, address_length, ok) ;
  4628.             debug_io.put_line("post get network number") ;
  4629.           END IF ; END IF ; END IF ; END IF ;
  4630.           IF NOT (ok) THEN 
  4631.             type_of_command := bad_command ;
  4632.           END IF ;
  4633.           debug_io.put("port #=") ;
  4634.           debug_io.put_line(port_number) ;
  4635.           debug_io.put("imp #=") ;
  4636.           debug_io.put_line(imp_number) ;
  4637.           debug_io.put("logical host #=") ;
  4638.           debug_io.put_line(logical_host_number) ;
  4639.           debug_io.put("host #=") ;
  4640.           debug_io.put_line(host_number) ;
  4641.           debug_io.put("network #=") ;
  4642.           debug_io.put_line(network_number) ;
  4643.           debug_io.put_line("end process_open_command_parameters") ;
  4644.         EXCEPTION
  4645.           WHEN OTHERS =>
  4646.             debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.pr_open_cmd_par") ;
  4647.             RAISE ;
  4648.        END process_open_command_parameters ;
  4649.       
  4650.  
  4651.       BEGIN -- determine command type
  4652.  
  4653.         -- *debug* try assign in body part
  4654.         debug_io.put_line("in determine command type, will try to do assign") ;
  4655.         command_string(1..length) := command_string_in(1..length) ;
  4656.         debug_io.put_line("in determine command type, body assign complete") ;
  4657.         debug_io.put("command_string=") ;
  4658.         debug_io.put_line(command_string(1..length)) ;
  4659.  
  4660.         address_length := length ; -- pass in length of entire string
  4661.         debug_io.put_line("pre call of strip ex char") ;
  4662.         strip_off_extra_characters(command_string(1..length+3),
  4663.          address_length) ; -- pass in room for blank padding padding too(+3)
  4664.         debug_io.put_line("post call of strip ex char") ;
  4665.         IF    command_string(1..4) = "O   " THEN
  4666.           type_of_command := open_command ;
  4667.           debug_io.put_line("pre process_open_command_parameters ") ;
  4668.           process_open_command_parameters ;
  4669.           debug_io.put_line("post process_open_command_parameters ") ;
  4670.         ELSIF command_string(1..4) = "C   " OR command_string(1..4)="c   " THEN
  4671.           type_of_command := close_command ;
  4672.         ELSIF command_string(1..4) = "S   " OR command_string(1..4)="s   " THEN
  4673.           type_of_command := status_command ;
  4674.         ELSIF command_string(1..4) = "R   " OR command_string(1..4)="r   " THEN
  4675.           type_of_command := reset_command ;
  4676.         ELSIF command_string(1..4) = "EL  " OR command_string(1..4)="el  " THEN
  4677.           type_of_command := echo_local_command ;
  4678.         ELSIF command_string(1..4) = "ER  " OR command_string(1..4)="er  " THEN
  4679.           type_of_command := echo_remote_command ;
  4680.         ELSIF command_string(1..4) = "QEL " OR command_string(1..4)="qel " THEN
  4681.           type_of_command := quit_echo_local_command ;
  4682.         ELSIF command_string(1..4) = "QER " OR command_string(1..4)="qer " THEN
  4683.           type_of_command := quit_echo_remote_command ;
  4684.         ELSIF command_string(1..4) = "SGL " OR command_string(1..4)="sgl " THEN
  4685.           type_of_command := suppress_ga_local_command ;
  4686.         ELSIF command_string(1..4) = "SGR " OR command_string(1..4)="sgr " THEN
  4687.           type_of_command := suppress_ga_remote_command ;
  4688.         ELSIF command_string(1..4) = "QSGL" OR command_string(1..4)="qsgl" THEN
  4689.           type_of_command := quit_suppress_ga_local_command ;
  4690.         ELSIF command_string(1..4) = "QSGR" OR command_string(1..4)="qsgr" THEN
  4691.           type_of_command := quit_suppress_ga_remote_command ;
  4692.         ELSIF command_string(1..4) = "SAO " OR command_string(1..4)="sao " THEN
  4693.           type_of_command := send_abort_output_command ;
  4694.         ELSIF command_string(1..4) = "SAYT" OR command_string(1..4)="sayt" THEN
  4695.           type_of_command := send_are_you_there_command ;
  4696.         ELSIF command_string(1..4) = "SB  " OR command_string(1..4)="sb  " THEN
  4697.           type_of_command := send_break_command ;
  4698.         ELSIF command_string(1..4) = "SEC " OR command_string(1..4)="sec " THEN
  4699.           type_of_command := send_erase_character_command ;
  4700.         ELSIF command_string(1..4) = "SEL " OR command_string(1..4)="sel " THEN
  4701.           type_of_command := send_erase_line_command ;
  4702.         ELSIF command_string(1..4) = "SIP " OR command_string(1..4)="sip " THEN
  4703.           type_of_command := send_interrupt_process_command ;
  4704.         ELSIF command_string(1..4) = "SS  " OR command_string(1..4)="ss  " THEN
  4705.           type_of_command := send_sync_command ;
  4706.         ELSE
  4707.           type_of_command := bad_command ;
  4708.         END IF ;
  4709.         debug_io.put_line("end determine command type") ;
  4710.       EXCEPTION
  4711.         WHEN OTHERS =>
  4712.           debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.deter_cmd_type") ;
  4713.           RAISE ;
  4714.       END determine_command_type ;
  4715.  
  4716.  
  4717.       PROCEDURE convert_string_to_byte
  4718.                 ----------------------
  4719.        (item  : IN  STRING ;
  4720.         bytes : OUT bytes_type) IS
  4721.       -- *********************  BODY SPECIFICATION  ***************************
  4722.       -- 
  4723.       -- This procedure converts a character string into an array of 
  4724.       -- SYSTEM.BYTE suitable for sending to the NVT I/O package.
  4725.       -------------------------------------------------------------------------
  4726.       BEGIN
  4727.         FOR index IN 1..item'length LOOP
  4728.           bytes(bit_count_16_type(index)) := bit_count_8_type(CHARACTER'POS(item(index))) ;
  4729.         END LOOP ;
  4730.       END convert_string_to_byte ;
  4731.  
  4732.  
  4733.       PROCEDURE convert_user_data_bytes_to_string
  4734.                 ---------------------------------
  4735.        (bytes  : IN     user_data.out_string_type ;
  4736.         str    :    OUT STRING ; 
  4737.         length : IN     bit_count_16_type ;
  4738.         ok     :    OUT BOOLEAN) IS
  4739.       BEGIN
  4740.         ok := TRUE ;
  4741.         FOR index IN 1..length LOOP
  4742.           IF bytes(index) > 16#7F# THEN -- error
  4743.             ok := FALSE ;
  4744.             EXIT ; -- loop
  4745.           END IF ;
  4746.  
  4747.           str(bit_count_32_type(index)) := CHARACTER'VAL(bytes(index)) ;
  4748. --&MT     str(index) := CHARACTER'VAL(bytes(index)) ;
  4749.  
  4750.         END LOOP ;
  4751.       END convert_user_data_bytes_to_string ;
  4752.  
  4753.  
  4754.     BEGIN -- parse_for_semantics_and_make_call_to_presentation_level
  4755. -- move any enumerated type initializations to 
  4756. -- body part(run time compiler bug)
  4757.       debug_io.put_line("begin parse for semantics and make call") ;
  4758.       user_data.get_command_buffer(command, length) ;
  4759.       convert_user_data_bytes_to_string
  4760.        (command, command_string, length, successful) ;
  4761.       IF successful THEN 
  4762.         debug_io.put_line("keybd.parse_for_semantics") ;
  4763.         debug_io.put("command string=") ;
  4764.  
  4765.         debug_io.put_line(command_string(1..bit_count_32_type(length))) ;
  4766. --&MT   debug_io.put_line(command_string(1..length)) ;
  4767.  
  4768.         debug_io.put("command string length=") ;
  4769.         debug_io.put_line(length) ;
  4770.  
  4771.         determine_command_type(command_string, bit_count_32_type(length), type_of_command) ;
  4772. --&MT   determine_command_type(command_string, length, type_of_command) ;
  4773.  
  4774.       ELSE
  4775.         type_of_command := bad_command ;
  4776.       END IF ; 
  4777.  
  4778.       CASE type_of_command IS
  4779.         -- transport level commands
  4780.         WHEN open_command =>
  4781.           debug_io.put_line("Making open command call to") ;
  4782.           debug_io.put_line
  4783.    ("virtual_transport_level.convert_service_call_to_transport_level_syntax") ;
  4784.           DECLARE
  4785.             parameter : virtual_transport_level.service_call_parameters_type
  4786.              (virtual_transport_level.TL_open) ;
  4787.           BEGIN
  4788.             parameter.network_number := network_number ;
  4789.             parameter.host_number := host_number ;
  4790.             parameter.logical_host_number := logical_host_number ;
  4791.             parameter.imp_number := imp_number ;
  4792.             parameter.port_number := port_number ;
  4793.             virtual_transport_level.convert_service_call_to_transport_level_syntax
  4794.              (virtual_transport_level.TL_open, parameter) ;
  4795.           END ; -- declare
  4796.         WHEN close_command =>
  4797.           debug_io.put_line("Making close command call to") ;
  4798.           debug_io.put_line
  4799.    ("virtual_transport_level.convert_service_call_to_transport_level_syntax") ;
  4800.           DECLARE
  4801.             parameter : virtual_transport_level.service_call_parameters_type
  4802.              (virtual_transport_level.TL_close) ;
  4803.           BEGIN
  4804.             virtual_transport_level.convert_service_call_to_transport_level_syntax 
  4805.              (virtual_transport_level.TL_close, parameter) ;
  4806.           END ; -- declare
  4807.         WHEN status_command =>
  4808.           debug_io.put_line("Making status command call to") ;
  4809.           debug_io.put_line
  4810.    ("virtual_transport_level.convert_service_call_to_transport_level_syntax") ;
  4811.           DECLARE
  4812.             parameter : virtual_transport_level.service_call_parameters_type
  4813.              (virtual_transport_level.TL_status) ;
  4814.           BEGIN
  4815.             virtual_transport_level.convert_service_call_to_transport_level_syntax 
  4816.              (virtual_transport_level.TL_status, parameter) ;
  4817.           END ; -- declare
  4818.         WHEN reset_command =>
  4819.           debug_io.put_line("Making reset command call to") ;
  4820.           debug_io.put_line
  4821.    ("virtual_transport_level.convert_service_call_to_transport_level_syntax") ;
  4822.           DECLARE
  4823.             parameter : virtual_transport_level.service_call_parameters_type
  4824.              (virtual_transport_level.TL_abort) ;
  4825.           BEGIN
  4826.             virtual_transport_level.convert_service_call_to_transport_level_syntax 
  4827.              (virtual_transport_level.TL_abort, parameter) ;
  4828.           END ; -- declare
  4829.  
  4830.         -- TELNET commands
  4831.         WHEN echo_local_command =>
  4832.             option_negotiation.request_local_option_enable(user_data.echo) ;
  4833.         WHEN echo_remote_command =>
  4834.             option_negotiation.request_remote_option_enable(user_data.echo) ;
  4835.         WHEN quit_echo_local_command =>
  4836.             option_negotiation.demand_local_option_disable(user_data.echo) ;
  4837.         WHEN quit_echo_remote_command =>
  4838.             option_negotiation.demand_remote_option_disable(user_data.echo) ;
  4839.         WHEN suppress_ga_local_command =>
  4840.             option_negotiation.request_local_option_enable(user_data.suppress_ga) ;
  4841.         WHEN suppress_ga_remote_command =>
  4842.             option_negotiation.request_remote_option_enable(user_data.suppress_ga) ;
  4843.         WHEN quit_suppress_ga_local_command =>
  4844.             option_negotiation.demand_local_option_disable(user_data.suppress_ga) ;
  4845.         WHEN quit_suppress_ga_remote_command =>
  4846.             option_negotiation.demand_remote_option_disable(user_data.suppress_ga) ;
  4847.         WHEN send_abort_output_command =>
  4848.           command_bytes(1) := 255 ; -- page 14 of RFC 854
  4849.           command_bytes(2) := 245 ;
  4850.           virtual_transport_level.send_data(command_bytes, not_urgent) ;
  4851.         WHEN send_are_you_there_command =>
  4852.           command_bytes(1) := 255 ; -- page 14 of RFC 854
  4853.           command_bytes(2) := 246 ;
  4854.           virtual_transport_level.send_data(command_bytes, not_urgent) ;
  4855.         WHEN send_break_command =>
  4856.           command_bytes(1) := 255 ; -- page 14 of RFC 854
  4857.           command_bytes(2) := 243 ;
  4858.           virtual_transport_level.send_data(command_bytes, not_urgent) ;
  4859.         WHEN send_erase_character_command =>
  4860.           command_bytes(1) := 255 ; -- page 14 of RFC 854
  4861.           command_bytes(2) := 247 ;
  4862.           virtual_transport_level.send_data(command_bytes, not_urgent) ;
  4863.         WHEN send_erase_line_command =>
  4864.           command_bytes(1) := 255 ; -- page 14 of RFC 854
  4865.           command_bytes(2) := 248 ;
  4866.           virtual_transport_level.send_data(command_bytes, not_urgent) ;
  4867.         WHEN send_interrupt_process_command =>
  4868.           command_bytes(1) := 255 ; -- page 14 of RFC 854
  4869.           command_bytes(2) := 244 ;
  4870.           virtual_transport_level.send_data(command_bytes, not_urgent) ;
  4871.         WHEN send_sync_command =>
  4872.           command_bytes(1) := 255 ; -- page 14 of RFC 854
  4873.           command_bytes(2) := 242 ; -- data mark, must be accompanied by a TCP 
  4874.                                     -- urgent notification
  4875.           virtual_transport_level.send_data(command_bytes, urgent) ;
  4876.         WHEN bad_command =>
  4877.           DECLARE -- aggregates would clean this up (not supported by Telelie)
  4878.             bad_message : STRING (1..6) ;
  4879.             bytes : bytes_type(1..6) ;
  4880.             not_control_characters : BOOLEAN := FALSE ;
  4881.           BEGIN
  4882.             bad_message(1..3) := "bad" ;
  4883.             bad_message(4) := ascii.bel ;
  4884.             bad_message(5) := ascii.cr ;
  4885.             bad_message(6) := ascii.lf ;
  4886.             convert_string_to_byte(bad_message, bytes) ;
  4887.             FOR index IN 1..6 LOOP
  4888.               virtual_terminal.output_character_to_nvt_printer
  4889.                (user_data.user_control_block.port, bytes(bit_count_16_type(index))) ;
  4890.             END LOOP ;
  4891.           END ; -- declare
  4892.       END CASE ;
  4893.       debug_io.put_line("end parse for semantics and make call") ;
  4894.     EXCEPTION
  4895.       WHEN OTHERS =>
  4896.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.parse_cmd") ;
  4897.         RAISE ;
  4898.     END parse_command_buffer_for_semantics_and_make_call_to_presentation_level ;
  4899.  
  4900.  
  4901.     FUNCTION char_not_end_of_line
  4902.              --------------------
  4903.      RETURN BOOLEAN IS 
  4904.       end_of_line : character_type := 16#0D# ; -- ASCII.CR (arbitrary)
  4905.     BEGIN
  4906.       RETURN char /= end_of_line ; 
  4907.     END char_not_end_of_line ;
  4908.  
  4909.     ------------------------  end subprogram declarations  -------------------
  4910.  
  4911.   BEGIN -- process partial command
  4912.     IF char_not_end_of_line THEN 
  4913.       add_the_character_to_the_partial_command_buffer(char);
  4914.     ELSE
  4915.       parse_command_buffer_for_semantics_and_make_call_to_presentation_level ;
  4916.  
  4917. ------------------------------------------------------------------------------
  4918. -- *** run-time compiler error: the initialization part of the declaration
  4919. --
  4920. --     does not happen at run time.  If the initialization is done explicitly
  4921. --     in the body part, the variable will be properly set.  Will just use
  4922. --     fully qualified name in body part.  TeleHosed again.
  4923. --
  4924. --      user_data.set_command_state_to(no_partial_command) ;
  4925. ------------------------------------------------------------------------------
  4926.  
  4927.       user_data.user_control_block.command_state := 
  4928.        user_data.no_partial_command ;
  4929.     END IF ; -- end of line?
  4930.   EXCEPTION
  4931.     WHEN OTHERS =>
  4932.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.proc_par_cmd") ;
  4933.       RAISE ;
  4934.   END process_partial_command ;
  4935.  
  4936.  
  4937.   PROCEDURE put_character_in_data_buffer
  4938.             ----------------------------
  4939.    (char : IN character_type) IS
  4940.   BEGIN
  4941.     IF user_data.there_is_room_in_data_buffer THEN
  4942.       user_data.put_char_in_data_buffer(char) ;
  4943.     ELSE -- error
  4944.       NULL ; -- T B D (just "lose" it for now)
  4945.     END IF ;
  4946.   EXCEPTION
  4947.     WHEN OTHERS =>
  4948.        debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.put_char_dat_buf") ;
  4949.        RAISE ;
  4950.   END put_character_in_data_buffer ;
  4951.  
  4952.  
  4953.   PROCEDURE send_data_buffer_to_transport_level IS
  4954.             -----------------------------------
  4955.  
  4956.     apl_buffer : user_data.out_string_type ;
  4957.     ppl_buffer : virtual_transport_level.info_output_type
  4958.      (1..user_data.max_out_string) ;
  4959.     length : bit_count_16_type RANGE 1..user_data.max_out_string ;
  4960.     not_urgent_data : BOOLEAN := FALSE ;
  4961.  
  4962.   BEGIN
  4963.     user_data.user_control_block.ga_received := FALSE ;
  4964.     user_data.get_data_buffer(apl_buffer, length) ;
  4965.     FOR index IN 1..length LOOP -- convert to ppl type
  4966.       ppl_buffer(index) := apl_buffer(index) ;
  4967.     END LOOP ;
  4968.     virtual_transport_level.send_data
  4969.      (ppl_buffer(1..length), not_urgent_data) ;
  4970.   EXCEPTION
  4971.     WHEN OTHERS =>
  4972.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.") ;
  4973.       RAISE ;
  4974.   END send_data_buffer_to_transport_level ;
  4975.  
  4976. BEGIN 
  4977.   NULL ;
  4978. EXCEPTION
  4979.   WHEN OTHERS =>
  4980.     debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac instantition") ;
  4981.     RAISE ;
  4982. END nvt_keyboard_input_processing ; -- package body part
  4983. --::::::::::::::
  4984. --aplpac_.ada
  4985. --::::::::::::::
  4986. -----------------------------------------------------------------------
  4987. --
  4988. --         DoD Protocols    NA-00004-200       80-01047-100(-)
  4989. --         E-Systems, Inc.  August 07, 1985
  4990. --
  4991. --         APLPAC_.ADA       Author : Mike Thomas 
  4992. --
  4993. -----------------------------------------------------------------------
  4994.  
  4995. -- File : aplpac       AUTHOR : MIKE THOMAS
  4996.  
  4997. --   5/9/85  1:20 PM : MODIFY FOR DEC ADA 
  4998. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  4999.  
  5000. PACKAGE telnet_apl -- specification
  5001.         ----------
  5002.  IS
  5003. --************************  USER SPECIFICATION  ******************************
  5004. --
  5005. --                     TELNET APPLICATION PROTOCOL LEVEL SPECIFICATION
  5006. --
  5007. -- The Application Protocol Level (APL)... [1]
  5008. --
  5009. --   * defines the semantics for information exchange; [2]
  5010. --   * provides network transparency; [3]
  5011. --   * and partitions the problem into high level functional areas : [4]
  5012. --     : read/write characters from/to the Network Virtual Terminal (NVT)
  5013. --       via the Presentation Protocol Level (PPL),
  5014. --     : handle standard control functions (ip, ao, ayt, ec, and el),
  5015. --     : perform command parsing,
  5016. --     : pass the commands to the Presentation Protocol Level (PPL) for
  5017. --       submission to the transport level protocol,
  5018. --     : receive responses/messages from the transport level protocol via the
  5019. --       Presentation Protocol Level (PPL).
  5020. --
  5021. -- SPECIFICATION REFERENCES:
  5022. --
  5023. --      DOD Protocol Reference Model (contract DCA 100-82-C-0036  2-Dec-83)
  5024. --
  5025. --        [1] section 4.1.1
  5026. --        [2] section 4.1.1.1
  5027. --        [3] section 4.1.1.2
  5028. --        [4] section 4.1.1.3
  5029. --
  5030. -----------------------------------------------------------------------------
  5031.  
  5032. -- **************************************************************************
  5033. --
  5034. -- This package performs the TELNET application protocol level(APL) processing
  5035. -- and imports procedures to access the TELNET presentation protocol 
  5036. -- level(PPL).  This package is responsible for the semantics of the user 
  5037. -- information exchange and uses the virtual resources provided for by the PPL
  5038. -- to access the network virtual terminal(NVT) and virtual transport level.
  5039. -- For example, this level could access the NVT to get user/process input
  5040. -- to TELNET; determine that it was a proper TELNET command to open a new
  5041. -- connection and call upon the virtual transport level to establish the
  5042. -- new connection.  If the real world terminal type were to change or the
  5043. -- transport level's actual implementation were changed, this would have no
  5044. -- effect on the APL.
  5045. --
  5046. -- ****************************************************************************
  5047.  
  5048.  
  5049.   PROCEDURE process_any_input_from_the_nvt_keyboard ; -- specification
  5050.   -- ************************  USER SPECIFICATION  ****************************
  5051.   -- 
  5052.   -- This procedure will input and process one character from the NVT 
  5053.   -- keyboard if one is available.
  5054.   -----------------------------------------------------------------------------
  5055.  
  5056.  
  5057.   PROCEDURE process_any_messages_from_the_transport_level ; -- specification
  5058.   -- ************************  USER SPECIFICATION  ****************************
  5059.   -- 
  5060.   -- This procedure will input and process one entire message from the 
  5061.   -- transport level if a message is available.  A message being information 
  5062.   -- for the local user/process which was generated by the local transport 
  5063.   -- level, not simply data being relayed from the remote TELNET.
  5064.   -----------------------------------------------------------------------------
  5065.  
  5066.  
  5067.   PROCEDURE process_any_input_from_the_transport_level ; -- specification
  5068.   -- ************************  USER SPECIFICATION  ****************************
  5069.   -- 
  5070.   -- This procedure will input and process one character from the 
  5071.   -- transport level which was relayed from the remote TELNET if it is
  5072.   -- available.
  5073.   -----------------------------------------------------------------------------
  5074.  
  5075.  
  5076.   PROCEDURE transmit_telnet_go_ahead ; -- specification
  5077.   -- ************************  USER SPECIFICATION  ****************************
  5078.   -- 
  5079.   -- This procedure will send the TELNET GA signal to the remote TELNET.
  5080.   -----------------------------------------------------------------------------
  5081.  
  5082. END telnet_apl ; -- package specification 
  5083.  
  5084. --::::::::::::::
  5085. --aplpac.ada
  5086. --::::::::::::::
  5087. -----------------------------------------------------------------------
  5088. --
  5089. --         DoD Protocols    NA-00004-200       80-01048-100(-)
  5090. --         E-Systems, Inc.  August 07, 1985
  5091. --
  5092. --         APLPAC.ADA       Author : Mike Thomas 
  5093. --
  5094. -----------------------------------------------------------------------
  5095.  
  5096. -- File : aplpac       AUTHOR : MIKE THOMAS
  5097.  
  5098. --    5/9/85  1:25 PM : MODIFY FOR DEC ADA            
  5099. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  5100. --   6/23/85  9:00 PM : set ga_state := no_ga_sent if there is input from tcp
  5101. --   6/24/85 10:19 AM : move set go_ahead to not control func part of if stm
  5102.  
  5103. WITH nvt_keyboard_input_processing ; -- procedures used in 
  5104. USE  nvt_keyboard_input_processing ; -- process_any_input_from_the_nvt_keyboard
  5105.  
  5106. WITH message_processing ; -- procedures/data/types used in
  5107. USE  message_processing ; -- process_any_messages_from_the_transport_level
  5108.  
  5109. WITH transport_level_input_processing ; -- procedures used in
  5110. USE  transport_level_input_processing ; -- process_any_input_from_the_transport_level
  5111.  
  5112. WITH user_data ; -- state information, user buffers, and data types
  5113. USE  user_data ;
  5114.  
  5115. WITH virtual_terminal ; -- for local character echoing
  5116. WITH virtual_transport_level ; -- to send telnet go ahead, echo data to remote
  5117. WITH SYSTEM ; -- for access to system.byte
  5118. WITH debug_io ;
  5119.  
  5120. PACKAGE BODY telnet_apl IS
  5121.              ----------
  5122.  
  5123. --&MT SUBTYPE bit_count_16_type IS INTEGER ; 
  5124.   SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  5125.  
  5126. --&MT SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  5127.   SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  5128.  
  5129.   PROCEDURE process_any_input_from_the_nvt_keyboard -- body
  5130.             ---------------------------------------
  5131.    IS
  5132.   -- *********************  BODY SPECIFICATION  *******************************
  5133.   --
  5134.   -- Processing sequence :
  5135.   --
  5136.   -- While there is input to process...
  5137.   -- If there is input from the NVT keyboard, get a character.   Set the
  5138.   -- NVT I/O state as I/O-done.  If the character was a standard control
  5139.   -- function, process the standard control function.  If the character was
  5140.   -- not a control function then process it as follows.  If the
  5141.   -- communication state is no-connection-established or the command state
  5142.   -- is partial-command or a new command was detected then set the NVT I/O
  5143.   -- state as partial-command and process a partial command.  Otherwise the
  5144.   -- input is data so put the character in the data buffer until an end of
  5145.   -- line is detected and then send it through to the transport level. 
  5146.   ----------------------------  data declarations  ---------------------------
  5147.  
  5148.     char : bit_count_8_type ;
  5149.     end_of_line : CONSTANT bit_count_8_type := 16#0D# ; -- ASCII.CR 
  5150.     TYPE control_function IS (ip, ao, ayt, ec, el) ;
  5151.     the_char_was_a_control_function : BOOLEAN ; 
  5152.     standard_control_function : control_function ;
  5153.     at_char : CONSTANT bit_count_8_type := 16#40# ; -- ascii '@' (command character)
  5154.     last_char_was_an_at : BOOLEAN RENAMES
  5155.      user_control_block.last_keybd_char_was_cmd ;
  5156.   -------------------------  local procedure declarations  --------------------
  5157.  
  5158.     PROCEDURE check_for_local_printing (char : IN bit_count_8_type) IS
  5159.               ------------------------
  5160.       remote_options_in_effect : user_data.option_table_type
  5161.        RENAMES user_control_block.option_tables.remote_options_in_effect ;
  5162.       echo_local : BOOLEAN := TRUE ;
  5163.     BEGIN
  5164.       FOR index IN 1..remote_options_in_effect.number_of_items LOOP
  5165.         IF remote_options_in_effect.option(index) = user_data.echo THEN
  5166.           echo_local := FALSE ;
  5167.           EXIT ;
  5168.         END IF ;
  5169.       END LOOP ;
  5170.       IF echo_local THEN
  5171.         virtual_terminal.output_character_to_nvt_printer
  5172.          (user_data.user_control_block.port, char) ;
  5173.       END IF ;
  5174.     EXCEPTION
  5175.       WHEN OTHERS =>
  5176.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN aplpac.check_loc_print") ;
  5177.         RAISE ;
  5178.     END check_for_local_printing ;
  5179.  
  5180.  
  5181.     FUNCTION time_to_transmit (char : IN bit_count_8_type) RETURN BOOLEAN IS 
  5182.              ----------------
  5183.     -- *************************  SPECIFICATION  ******************************
  5184.     -- This function returns true if it is time to transmit the characters
  5185.     -- which were typed into the keyboard and are to be sent to the remote
  5186.     -- TELNET connection.  In the default NVT options, this would be at the
  5187.     -- end of a line.[1]  Other options in effect (such as remote ECHO) may
  5188.     -- be criteria for character-at-a-time as appossed to line-at-a-time
  5189.     -- transmissions.[2]  
  5190.     -- 
  5191.     -- SPECIFICATION REFERENCES :
  5192.     --    [1] Network Working Group Request For Comments : 854, May 1983
  5193.     --        (page 5, default condition 1)
  5194.     --    [2] Network Working Group Request For Comments : 857, May 1983
  5195.     --        (page 3, paragraph 1)
  5196.     ---------------------------------------------------------------------------
  5197.  
  5198.       transmit_time : BOOLEAN := FALSE ;
  5199.       remote_options_in_effect : user_data.option_table_type 
  5200.        RENAMES user_control_block.option_tables.remote_options_in_effect ;
  5201.       local_options_in_effect : user_data.option_table_type 
  5202.        RENAMES user_control_block.option_tables.local_options_in_effect ;
  5203.       remote_options_pending : user_data.option_table_type
  5204.        RENAMES user_control_block.option_tables.remote_options_pending ;
  5205.       local_options_pending : user_data.option_table_type
  5206.        RENAMES user_control_block.option_tables.local_options_pending ;
  5207.  
  5208.       FUNCTION option_in_table
  5209.                ---------------
  5210.        (table  : IN user_data.option_table_type ;
  5211.         option : IN user_data.option_type) RETURN BOOLEAN IS
  5212.       BEGIN
  5213.         FOR index IN 1..table.number_of_items LOOP
  5214.           IF table.option(index) = option THEN
  5215.             RETURN TRUE ;
  5216.           END IF ;
  5217.         END LOOP ;
  5218.         RETURN FALSE ;
  5219.       END option_in_table ;
  5220.  
  5221.     BEGIN 
  5222.       IF user_data.user_control_block.ga_received OR
  5223.        option_in_table(remote_options_in_effect, suppress_ga) THEN
  5224.         IF bit_count_16_type(char) = bit_count_16_type(end_of_line) AND THEN
  5225.          (remote_options_pending.number_of_items = 0 AND
  5226.          local_options_pending.number_of_items = 0) THEN
  5227.           transmit_time := TRUE ; -- end of line, no option negotiation pending
  5228.         ELSE -- not end of line
  5229.           IF option_in_table(remote_options_in_effect, suppress_ga) AND
  5230.            option_in_table(local_options_in_effect, suppress_ga) THEN
  5231.             IF option_in_table(remote_options_in_effect, echo) OR
  5232.              option_in_table(local_options_in_effect, echo) THEN
  5233.               transmit_time := TRUE ; -- suppress_ga & echo ==> character at a time mode
  5234.             END IF ; -- echo?
  5235.           END IF ; -- suppress_ga?
  5236.         END IF ; -- end of line?
  5237.       END IF ; -- ga_received?
  5238.       RETURN transmit_time ;
  5239.     EXCEPTION
  5240.       WHEN OTHERS =>
  5241.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN aplpac.time_to_trans") ;
  5242.         RAISE ;
  5243.     END time_to_transmit ;
  5244.      
  5245.  
  5246.     PROCEDURE process_data_character(char : IN bit_count_8_type) IS
  5247.               ----------------------
  5248.     BEGIN
  5249.       debug_io.put_line("putting character in data buffer") ;
  5250.       put_character_in_data_buffer(char) ;
  5251.       IF bit_count_16_type(char) = bit_count_16_type(255) THEN -- double IAC on send to indecate a data byte 255
  5252.         put_character_in_data_buffer(char) ;
  5253.       END IF ;
  5254.       IF time_to_transmit(char) THEN 
  5255.         debug_io.put_line("sending data buffer to trans level") ;
  5256.         send_data_buffer_to_transport_level ;
  5257.       END IF ; -- transmit buffer?
  5258.     EXCEPTION
  5259.       WHEN OTHERS =>
  5260.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN aplpac.proc_data_char") ;
  5261.         RAISE ;
  5262.     END process_data_character ;
  5263.  
  5264.   BEGIN -- process keyboard input
  5265.     debug_io.put_line("begin process keyboard input") ;
  5266.     IF there_is_input_from_the_NVT_keyboard THEN
  5267.       WHILE there_is_input_from_the_NVT_keyboard LOOP
  5268.         debug_io.put_line("apl process keyboard input thinks there is input") ;
  5269.         get_a_character(char, the_char_was_a_control_function);
  5270.         check_for_local_printing(char) ;
  5271.         user_control_block.NVT_IO_state := IO_done ;
  5272.         IF the_char_was_a_control_function THEN 
  5273.           debug_io.put_line("will process control function...") ;
  5274.           process_standard_control_function_from_keyboard(char) ;
  5275.         ELSE -- not control function 
  5276.           debug_io.put_line("character not a control function") ;
  5277.           IF user_control_block.communication_state = 
  5278.            no_connection_established OR 
  5279.            user_control_block.command_state = partial_command THEN
  5280.             debug_io.put_line("current character is part of partial command") ;
  5281.             user_control_block.command_state := partial_command ;
  5282.             process_partial_command(char) ;
  5283.           ELSE -- data
  5284.             debug_io.put_line("current character is data") ;
  5285.             IF last_char_was_an_at THEN
  5286.               IF bit_count_16_type(char) = bit_count_16_type(at_char) THEN -- put at #2 in data buf
  5287.                 process_data_character(char) ;
  5288.                 last_char_was_an_at := FALSE ;
  5289.               ELSE -- new command detected
  5290.                 user_control_block.command_state := partial_command ;
  5291.                 process_partial_command(at_char) ;
  5292.                 process_partial_command(char) ;
  5293.                 last_char_was_an_at := FALSE ;
  5294.               END IF ; -- char=at?
  5295.             ELSE -- last char /= at
  5296.               IF bit_count_16_type(char) = bit_count_16_type(at_char) THEN 
  5297.                 last_char_was_an_at := TRUE ;
  5298.               ELSE -- niether last char nor this char = at
  5299.                 process_data_character(char) ;
  5300.               END IF ; -- transmit buffer?
  5301.             END IF ; -- last_char_was_an_at?
  5302.           END IF ; -- command?
  5303.         END IF ; -- control function?
  5304.       END LOOP ; -- input from keyboard?
  5305.     ELSE -- no input from keyboard, chack for send of buffered input
  5306.          -- due to pending option negotiation and/or go ahead processing
  5307.       IF user_data.there_is_data_in_data_buffer AND time_to_transmit(0) THEN
  5308.         send_data_buffer_to_transport_level ;
  5309.       END IF ; -- send buffered data?
  5310.     END IF ; -- keyboard input available?
  5311.     debug_io.put_line("end process keyboard input") ;
  5312.   EXCEPTION
  5313.     WHEN OTHERS =>
  5314.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN aplpac.proc_any_keybd_input") ;
  5315.       RAISE ;
  5316.   END process_any_input_from_the_NVT_keyboard ; -- procedure body
  5317.      
  5318.  
  5319.   PROCEDURE process_any_messages_from_the_transport_level -- body
  5320.             ---------------------------------------------
  5321.    IS
  5322.   --************************  BODY SPECIFICATION  *****************************
  5323.   --
  5324.   -- While there are messages to process...
  5325.   -- If there is a message from the transport level, retrieve the message and
  5326.   -- write the message to the NVT printer.  A message being information 
  5327.   -- for the local user/process which was generated by the local transport 
  5328.   -- level, not simply data being relayed from the remote TELNET.
  5329.   --------------------------  data declarations  ---------------------------
  5330.   
  5331.     message_from_transport_level : message_from_transport_level_type ;
  5332.     length                       : bit_count_16_type RANGE 1..max_msg_length ;
  5333.  
  5334.   BEGIN  -- process_any_messages_from_the_transport_level
  5335.     debug_io.put_line("begin telnet_apl.process_any_messages.") ;
  5336.     WHILE there_is_a_message_available LOOP
  5337.       retrieve_message(message_from_transport_level, length) ;
  5338.       debug_io.put("message length =") ;
  5339.       debug_io.put_line(length) ;
  5340.       write_message_to_NVT_printer(message_from_transport_level, length) ;
  5341.     END LOOP ; -- message to process?
  5342.     debug_io.put_line("end telnet_apl.process_any_messages.") ;
  5343.   EXCEPTION
  5344.     WHEN OTHERS =>
  5345.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN aplpac.proc_any_mess") ;
  5346.       RAISE ;
  5347.   END process_any_messages_from_the_transport_level ; -- body
  5348.  
  5349.  
  5350.   PROCEDURE process_any_input_from_the_transport_level -- body
  5351.             ------------------------------------------
  5352.    IS
  5353.   --**********************  BODY SPECIFICATION  ****************************
  5354.   --
  5355.   -- Processing sequence :
  5356.   --
  5357.   -- While there is input to process...
  5358.   -- If there is input from the transport level which is data simply
  5359.   -- relayed from the remote TELNET, input a character from the
  5360.   -- transport level and mark the NVT I/O state as having I/O-done.  If the
  5361.   -- character is not a standard control function, write it on the NVT
  5362.   -- printer.  If the character is a standard control function, process the
  5363.   -- standard control function. 
  5364.   --------------------------  data declarations  -------------------------
  5365.  
  5366.     char : bit_count_8_type ;
  5367.     the_char_was_a_control_function : BOOLEAN ;
  5368.     urgent_data : BOOLEAN := TRUE ;
  5369.     echo_chars : virtual_transport_level.info_output_type
  5370.      (1..virtual_transport_level.max_msg_length) ;
  5371.     char_count : bit_count_16_type RANGE 0..virtual_transport_level.max_msg_length := 0 ;
  5372.  
  5373.     FUNCTION echo_to_remote RETURN BOOLEAN IS
  5374.              --------------
  5375.       local_options_in_effect : user_data.option_table_type RENAMES
  5376.        user_data.user_control_block.option_tables.local_options_in_effect ;
  5377.     BEGIN
  5378.       FOR index IN 1..local_options_in_effect.number_of_items LOOP
  5379.         IF local_options_in_effect.option(index) = user_data.echo THEN
  5380.           RETURN TRUE ;
  5381.         END IF ;
  5382.       END LOOP ;
  5383.       RETURN FALSE ;
  5384.     EXCEPTION
  5385.       WHEN OTHERS =>
  5386.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN aplpac.ehco_to_remote") ;
  5387.         RAISE ;
  5388.     END echo_to_remote ;
  5389.  
  5390.   BEGIN -- process_any_input_from_transport_level
  5391.     debug_io.put_line
  5392.      ("begin telnet_apl.process_any_input_from_transport_level") ;
  5393.     WHILE there_is_input LOOP
  5394.       debug_io.put_line
  5395.       ("telnet_apl.process_any_input thinks there is input") ;
  5396.       input_character(char, the_char_was_a_control_function, urgent_data) ;
  5397.       debug_io.put("telnet_apl.proc_input.char=") ;
  5398.       debug_io.put_line_byte(char) ;
  5399.       
  5400.       IF the_char_was_a_control_function THEN
  5401.         debug_io.put_line("was a control function") ;
  5402.         process_standard_control_function(char, urgent_data) ;
  5403.       ELSE
  5404.         debug_io.put_line("was not a control function") ;
  5405.         user_data.user_control_block.ga_state := no_go_ahead_sent ;
  5406.         write_character_to_NVT_printer(char) ;
  5407.         user_control_block.NVT_IO_state := IO_done ;
  5408.         char_count := char_count + 1 ;
  5409.         echo_chars(char_count) := char ;
  5410.       END IF ; -- control function?
  5411.     END LOOP ; -- any input to process?
  5412.     IF echo_to_remote AND char_count > 0 THEN
  5413.       virtual_transport_level.send_data(echo_chars(1..char_count),urgent_data) ;
  5414.     END IF ;
  5415.     debug_io.put_line
  5416.      ("end telnet_apl.process_any_input_from_transport_level") ;
  5417.   EXCEPTION
  5418.     WHEN OTHERS =>
  5419.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN aplpac.proc_tl_input") ;
  5420.       RAISE ;
  5421.   END process_any_input_from_the_transport_level ; -- body
  5422.  
  5423.  
  5424.   PROCEDURE transmit_telnet_go_ahead -- body
  5425.             ------------------------
  5426.    IS
  5427.   --*************************  BODY SPECIFICATION  ***************************
  5428.   --
  5429.   -- Processing sequence ...
  5430.   --
  5431.   -- Send the TELNET GA (go ahead) signal through the presentation level
  5432.   -- to the transport level.
  5433.   --------------------------  data declarations  -----------------------------
  5434.   
  5435.     SUBTYPE telnet_go_ahead_type IS 
  5436.      virtual_transport_level.info_output_type(1..2) ;
  5437.     telnet_go_ahead : telnet_go_ahead_type ;
  5438.     not_urgent      : BOOLEAN := FALSE ;
  5439.   
  5440.   BEGIN -- transmit_telnet_go_ahead
  5441.     debug_io.put_line("telnet go ahead sent") ;
  5442.     telnet_go_ahead(1) := 16#FF# ; -- RFC 854 page 14
  5443.     telnet_go_ahead(2) := 16#F9# ;
  5444.     IF virtual_transport_level.there_is_room_for_info_output THEN
  5445.       virtual_transport_level.send_data (telnet_go_ahead, not_urgent) ;
  5446.     END IF ;
  5447.   END transmit_telnet_go_ahead ; -- body
  5448.     
  5449. BEGIN -- telnet APL package body
  5450.   NULL ;
  5451. EXCEPTION
  5452.   WHEN OTHERS =>
  5453.     debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN aplpac instantiation") ;
  5454.     RAISE ;
  5455. END telnet_apl ; -- package
  5456.  
  5457. --::::::::::::::
  5458. --telnetpac_.ada
  5459. --::::::::::::::
  5460. -----------------------------------------------------------------------
  5461. --
  5462. --         DoD Protocols    NA-00004-200       80-01067-100(-)
  5463. --         E-Systems, Inc.  August 07, 1985
  5464. --
  5465. --         TELNETPAC_.ADA       Author : Mike Thomas 
  5466. --
  5467. -----------------------------------------------------------------------
  5468.  
  5469. --   File : telnet         AUTHOR : MIKE THOMAS
  5470.  
  5471. --   5/9/85  2:20 PM : MODIFY FOR DEC ADA 
  5472. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  5473.  
  5474. --*****************************************************************************
  5475. --                E-SYSTEMS, ECI DIVISION, ST. PETERSBURG, FL.
  5476. --  
  5477. --
  5478. --  TITLE: Telnet 
  5479. --  
  5480. --  AUTHOR: Mike Thomas
  5481. --
  5482. --  LANGUAGE/COMPILER: TeleSoft ADA, version 1.5
  5483. --  
  5484. --  CUSTOMER: Naval Ocean Systems Center
  5485. --
  5486. --  DEPENDENCIES
  5487. --     HARDWARE: VAX / WICAT
  5488. --     SOFTWARE: VMS version 3.6 / ROS version 2.1e - Labtek RTK 2.2  
  5489. --
  5490. --  ABSTRACT: This is a source code listing of the Telnet communications 
  5491. --            protocol Computer Program Package
  5492. --
  5493. --
  5494. --*****************************************************************************
  5495. --
  5496. --  REVISION         :  Number         -  1.0
  5497. --                      Date           -  12-OCT-84
  5498. --                      Author         -  Mike Thomas
  5499. --                      Change Summary -  Original Version
  5500. --
  5501. --                   :  Number         -  1.1
  5502. --                      Date           -  10-DEC-84
  5503. --                      Author         -  Mike Thomas
  5504. --                      Change Summary -  Ready for Test/Debug
  5505. --
  5506. --                   :  Number         -  2.0
  5507. --                      Date           -  29-JAN-84
  5508. --                      Author         -  Mike Thomas, Paul Higgins
  5509. --                      Change Summary -  run-time optimized version
  5510. --
  5511. --*****************************************************************************
  5512.  
  5513.  
  5514.  
  5515.  
  5516. --*****************************************************************************
  5517. --
  5518. --                          PACKAGE DESCRIPTIONS
  5519. --
  5520. --*****************************************************************************
  5521. --
  5522. -- Package Name : TELNET_PACKAGE                        File : telnetpac.txt
  5523. --
  5524. -- Abstract : 
  5525. -- This package has the data types and data operations which are exported
  5526. -- to the TELNET controller program to allow the controller to set up the
  5527. -- data structure used by the TELNET procedure and the TELNET procedure
  5528. -- which services a TELNET user. 
  5529. --
  5530. --
  5531. -- 
  5532. -- Package Name : TELNET_APL                            File : aplpac.txt
  5533. -- 
  5534. -- Abstract : 
  5535. -- This package performs the high level processing associated with the 
  5536. -- Telnet Aplication Level protocol.
  5537. --
  5538. --
  5539. -- 
  5540. -- Package Name : NVT_KEYBOARD_INPUT_PROCESSING         File : akeybdpac.txt
  5541. -- 
  5542. -- Abstract : 
  5543. -- This package has subprograms to manage APL level processing of Network 
  5544. -- Virtual keyboard input.
  5545. -- 
  5546. --
  5547. -- 
  5548. -- Package Name : TRANSPORT_LEVEL_INPUT_PROCESSING      File : atrinpac.txt
  5549. -- 
  5550. -- Abstract : 
  5551. -- This package has APL subprograms used to process data input to the 
  5552. -- local Telnet from the remote Telnet.
  5553. -- 
  5554. --
  5555. -- 
  5556. -- Package Name : MESSAGE PROCESSING                    File : amesspac.txt
  5557. -- 
  5558. -- Abstract : 
  5559. -- This package has APL subprograms used to process message input to the 
  5560. -- local Telnet from the local transport level.
  5561. -- 
  5562. --
  5563. -- 
  5564. -- 
  5565. -- Package Name : VIRTUAL_TERMINAL                      File : pvirtmpac.txt
  5566. -- 
  5567. -- Abstract : 
  5568. -- This package provides low level Network Virtual Terminal services and 
  5569. -- interfaces with the actual I/O device or process. 
  5570. -- 
  5571. --
  5572. -- 
  5573. -- Package Name : VIRTUAL_TRANSPORT_LEVEL               File : pvirtlpac.txt
  5574. -- 
  5575. -- Abstract : 
  5576. -- This package provides low level virtual transport level services and 
  5577. -- interfaces with the actual transport level.
  5578. -- 
  5579. --
  5580. -- 
  5581. -- Package Name : USER_DATA                             File : auserdpac.txt
  5582. -- 
  5583. -- Abstract : 
  5584. -- This package contains operations to examine and manipulate user APL 
  5585. -- state information and APL buffers.
  5586. -- 
  5587. --
  5588. -- 
  5589. -- Package Name : OPTION_NEGOTIATION                    File : poptngpac.txt
  5590. -- 
  5591. -- Abstract : 
  5592. -- This package contains subprograms to handle Telnet option negotiation.
  5593. -- 
  5594. -------------------------------------------------------------------------------
  5595.  
  5596.  
  5597.  
  5598. WITH user_data ;
  5599. USE  user_data ;
  5600. WITH option_negotiation ;
  5601.  
  5602. PACKAGE telnet_package -- specification
  5603.         --------------
  5604.  IS
  5605. -- **********************  USER SPECIFICATION  *****************************
  5606. -- 
  5607. -- This package has the data types and data operations which are exported
  5608. -- to the TELNET controller program to allow the controller to set up the
  5609. -- data structure used by the TELNET procedure and the TELNET procedure
  5610. -- which services a TELNET user.  An array of user data structures could be 
  5611. -- used by the controller to serve multiple TELNET users.  The 
  5612. -- user_information_type contains all the necessary information maintained 
  5613. -- for a TELNET user.  The TELNET_options_supported_type lists the 
  5614. -- non-default options currently supported by this implementation.  User
  5615. -- information directly alterable by the controller are the non-standard
  5616. -- TELNET options and I/O_device_characteristics.  The controller
  5617. -- can request to begin a non-default TELNET option, demand not to support a
  5618. -- non-default option, (as well as the same request/demand for the other
  5619. -- side of the TELNET connection) and set information regarding the actual
  5620. -- I/O device characteristics for a particular user.  These characteristics 
  5621. -- should be initialized prior to running the TELNET procedure, but could
  5622. -- be dynamically changed if appropriate.
  5623. -- 
  5624. -- **************************************************************************
  5625.  
  5626. -- *debug*  make user_info_type public for test/debug *debug**********
  5627. --  TYPE user_info_type IS PRIVATE ; -- user specific information
  5628.  
  5629. --&MT SUBTYPE bit_count_16_type IS INTEGER ; 
  5630.   SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  5631.  
  5632.   SUBTYPE user_info_type IS user_data.control_block_type ;
  5633.  
  5634.   SUBTYPE telnet_options_supported_type IS -- non-default options supported
  5635.    user_data.option_type ;
  5636.   TYPE io_device_supported_type IS (process, VT100) ;
  5637.   SUBTYPE io_port_address_type IS bit_count_16_type ; -- arbitrary
  5638.  
  5639.   PROCEDURE telnet_request_to_do_option -- specification
  5640.             ---------------------------
  5641.    (option :        IN telnet_options_supported_type ;
  5642.     user_info : IN OUT user_info_type) ;
  5643.  
  5644.     -- *********************  USER SPECIFICATION  *****************************
  5645.     --
  5646.     -- This procedure allows the TELNET controller to request a non-default
  5647.     -- TELNET option to be done locally.  Used primarily to initialize
  5648.     -- this information prior to using the TELNET procedure, but it
  5649.     -- can be used to dynamically request a change in TELNET options if
  5650.     -- desired.  If this procedure is used for a closed connection, TELNET
  5651.     -- will automatically try to negotiate that option upon the establishment
  5652.     -- of a new connection.
  5653.     ---------------------------------------------------------------------------
  5654.  
  5655.  
  5656.   PROCEDURE telnet_demand_not_to_do_option -- specification
  5657.             ------------------------------
  5658.    (option :        IN telnet_options_supported_type ;
  5659.     user_info : IN OUT user_info_type) ;
  5660.  
  5661.     -- *********************  USER SPECIFICATION  *****************************
  5662.     --
  5663.     -- This procedure allows the TELNET controller to demand a non-default
  5664.     -- TELNET option not be done locally.  Used primarily to initialize
  5665.     -- this information prior to using the TELNET procedure, but it
  5666.     -- can be used to dynamically request a change in TELNET options if
  5667.     -- desired.
  5668.     ---------------------------------------------------------------------------
  5669.  
  5670.  
  5671.   PROCEDURE telnet_request_remote_to_do_option -- specification
  5672.             ----------------------------------
  5673.    (option :        IN telnet_options_supported_type ;
  5674.     user_info : IN OUT user_info_type) ;
  5675.  
  5676.     -- *********************  USER SPECIFICATION  *****************************
  5677.     --
  5678.     -- This procedure allows the TELNET controller to request a non-default
  5679.     -- TELNET option to be done remotely.  Used primarily to initialize
  5680.     -- this information prior to using the TELNET procedure, but it
  5681.     -- can be used to dynamically request a change in TELNET options if
  5682.     -- desired.  If this procedure is used for a closed connection, TELNET
  5683.     -- will automatically try to negotiate that option upon the establishment
  5684.     -- of a new connection.
  5685.     ---------------------------------------------------------------------------
  5686.  
  5687.  
  5688.   PROCEDURE telnet_demand_remote_not_to_do_option -- specification
  5689.             -------------------------------------
  5690.    (option :        IN telnet_options_supported_type ;
  5691.     user_info : IN OUT user_info_type) ;
  5692.  
  5693.     -- *********************  USER SPECIFICATION  *****************************
  5694.     --
  5695.     -- This procedure allows the TELNET controller to demand a non-default
  5696.     -- TELNET option not be done remotely.  Used primarily to initialize
  5697.     -- this information prior to using the TELNET procedure, but it
  5698.     -- can be used to dynamically request a change in TELNET options if
  5699.     -- desired.
  5700.     ---------------------------------------------------------------------------
  5701.  
  5702.  
  5703.   PROCEDURE set_device_type -- specification
  5704.             ---------------
  5705.    (device_type :     IN IO_device_supported_type ;
  5706.     user_info :   IN OUT user_info_type) ;
  5707.  
  5708.     -- *********************  USER SPECIFICATION  *****************************
  5709.     --
  5710.     -- This procedure sets the device type for use by the TELNET 
  5711.     -- presentation protocol level to allow actual communication 
  5712.     -- with that process or device.  Used primarily to initialize
  5713.     -- this information prior to using the TELNET procedure, but it
  5714.     -- can be used to dynamically request a change if desired.
  5715.     ---------------------------------------------------------------------------
  5716.  
  5717.  
  5718.   PROCEDURE set_IO_port_address -- specification
  5719.             -------------------
  5720.    (IO_port_address :     IN IO_port_address_type ;
  5721.     user_info :       IN OUT user_info_type) ;
  5722.  
  5723.     -- *********************  USER SPECIFICATION  *****************************
  5724.     --
  5725.     -- This procedure sets the I/O port address for use by the TELNET 
  5726.     -- presentation protocol level to allow actual communication 
  5727.     -- with that process or device.  Used primarily to initialize
  5728.     -- this information prior to using the TELNET procedure, but it
  5729.     -- can be used to dynamically request a change if desired.
  5730.     ---------------------------------------------------------------------------
  5731.   
  5732.   -- Note : Other device specific procedures may have to be added here
  5733.   --        as deemed appropriate baised on the characteristics of the 
  5734.   --        of the specific devices supported and the host system.
  5735.  
  5736.  
  5737.  
  5738.   PROCEDURE telnet -- specification
  5739.             ------ 
  5740.    (user_info : IN OUT user_info_type ;
  5741.     idle      :    OUT BOOLEAN) ;
  5742.  
  5743.     -- *****************  USER SPECIFICATION  *****************************
  5744.     --
  5745.     -- This procedure implements the TELNET [1] communication protocol
  5746.     -- for a single user.  One "pass" is made for all sources of I/O
  5747.     -- for a user for each call of this procedure.  The controlling
  5748.     -- program should initialize any non-default options desired and I/O 
  5749.     -- device characteristics prior to calling telnet.  An array of 
  5750.     -- user_info_type variables would allow the controller to process
  5751.     -- multiple users of TELNET.
  5752.     --
  5753.     -- SPECIFICATION REFERENCES:
  5754.     -- 
  5755.     --    [1] Network Working Group Request for Comments: 854, May 1983,
  5756.     --        TELNET PROTOCOL SPECIFICATION
  5757.     -----------------------------------------------------------------------
  5758.  
  5759. -- made public for test/debug
  5760. --  PRIVATE 
  5761. --    TYPE user_info_type IS -- user specific information
  5762. --      RECORD
  5763. --        user_control_block : user_data.control_block_type ;
  5764. --      END RECORD ;
  5765.  
  5766. END telnet_package ; -- specification
  5767.  
  5768. --::::::::::::::
  5769. --telnetpac.ada
  5770. --::::::::::::::
  5771. -----------------------------------------------------------------------
  5772. --
  5773. --         DoD Protocols    NA-00004-200       80-01068-100(-)
  5774. --         E-Systems, Inc.  August 07, 1985
  5775. --
  5776. --         TELNETPAC.ADA       Author : Mike Thomas 
  5777. --
  5778. -----------------------------------------------------------------------
  5779.  
  5780. -- File telnetpac      AUTHOR : MIKE THOMAS 
  5781.  
  5782. --   5/9/85  2:35 PM : MODIFY FOR DEC ADA 
  5783. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  5784. --  6/23/85  8:57 PM : don't set ga state at top of telnet proc
  5785. --   7/1/85  2:52 PM : remove status variable from option request
  5786.  
  5787. WITH telnet_apl ; -- TELNET application protocol level
  5788. USE telnet_apl ;
  5789. WITH debug_io ;
  5790.  
  5791. PACKAGE BODY telnet_package IS 
  5792.              --------------
  5793.  
  5794.   PROCEDURE telnet_request_to_do_option -- body
  5795.             ---------------------------
  5796.    (option :        IN telnet_options_supported_type ;
  5797.     user_info : IN OUT user_info_type) IS
  5798.  
  5799.   BEGIN
  5800. --    user_data.put(user_info.user_control_block) ; -- store_user_information ;
  5801.     user_data.put(user_info) ; -- made public
  5802.     option_negotiation.request_local_option_enable(option) ;
  5803. --    user_data.get(user_info.user_control_block) ; -- restore_user_information ;
  5804.     user_data.get(user_info) ; -- made public
  5805.   EXCEPTION
  5806.     WHEN OTHERS =>
  5807.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN telnetpac.req_l_do_opt") ;
  5808.       RAISE ;
  5809.   END telnet_request_to_do_option ; -- body
  5810.  
  5811.  
  5812.   PROCEDURE telnet_demand_not_to_do_option -- body
  5813.             ------------------------------
  5814.    (option : IN telnet_options_supported_type ;
  5815.     user_info : IN OUT user_info_type) IS
  5816.  
  5817.   BEGIN
  5818. --    user_data.put(user_info.user_control_block) ; -- store_user_information ;
  5819.     user_data.put(user_info) ; -- made public
  5820.     option_negotiation.demand_local_option_disable(option) ;
  5821. --    user_data.get(user_info.user_control_block) ; -- restore_user_information ;
  5822.     user_data.get(user_info) ; -- made public
  5823.   EXCEPTION
  5824.     WHEN OTHERS =>
  5825.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN telnetpac.dem_l_n_do_opt") ;
  5826.       RAISE ;
  5827.   END telnet_demand_not_to_do_option ; -- body
  5828.     
  5829.  
  5830.   PROCEDURE telnet_request_remote_to_do_option -- body
  5831.             ----------------------------------
  5832.    (option :        IN telnet_options_supported_type ;
  5833.     user_info : IN OUT user_info_type) IS
  5834.  
  5835.   BEGIN
  5836. --    user_data.put(user_info.user_control_block) ; -- store_user_information ;
  5837.     user_data.put(user_info) ; -- made public
  5838.     option_negotiation.request_remote_option_enable(option) ;
  5839. --    user_data.get(user_info.user_control_block) ; -- restore_user_information ;
  5840.     user_data.get(user_info) ; -- made public
  5841.   EXCEPTION
  5842.     WHEN OTHERS =>
  5843.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN telnetpac.req_r_do_opt") ;
  5844.       RAISE ;
  5845.   END telnet_request_remote_to_do_option ; -- body
  5846.  
  5847.  
  5848.   PROCEDURE telnet_demand_remote_not_to_do_option -- body
  5849.             -------------------------------------
  5850.    (option : IN telnet_options_supported_type ;
  5851.     user_info : IN OUT user_info_type) IS 
  5852.  
  5853.   BEGIN
  5854. --    user_data.put(user_info.user_control_block) ; -- store_user_information ;
  5855.     user_data.put(user_info) ; -- made public
  5856.     option_negotiation.demand_remote_option_disable(option) ;
  5857. --    user_data.get(user_info.user_control_block) ; -- restore_user_information ;
  5858.     user_data.get(user_info) ; -- made public
  5859.   EXCEPTION
  5860.     WHEN OTHERS =>
  5861.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN telnetpac.dem_r_n_d_opt") ;
  5862.       RAISE ;
  5863.   END telnet_demand_remote_not_to_do_option ;
  5864.  
  5865.  
  5866.  
  5867.   PROCEDURE set_device_type -- body
  5868.             ---------------
  5869.    (device_type : IN IO_device_supported_type ;
  5870.     user_info   : IN OUT user_info_type) IS --T B D
  5871.  
  5872.   BEGIN
  5873.     NULL ;
  5874.   END set_device_type ; -- body
  5875.  
  5876.  
  5877.  
  5878.   PROCEDURE set_IO_port_address -- body
  5879.             -------------------
  5880.    (IO_port_address : IN IO_port_address_type ;
  5881.     user_info : IN OUT user_info_type) IS -- T B D
  5882.  
  5883.   BEGIN
  5884.     user_info.port := io_port_address ;
  5885.   END set_IO_port_address ; -- body
  5886.  
  5887.  
  5888.   
  5889.   PROCEDURE telnet -- body
  5890.             ------ 
  5891.    (user_info : IN OUT user_info_type ;
  5892.     idle : OUT BOOLEAN) IS
  5893.  
  5894.     -- *****************  BODY SPECIFICATION  *****************************
  5895.     --
  5896.     -- Processing sequence...
  5897.     --
  5898.     -- Initialize the user information.  If the NVT I/O state is I/O done,
  5899.     -- then set the go ahead sent state to no_go_ahead_sent and the NVT I/O 
  5900.     -- state to no I/O done.  Process any input from the NVT keyboard.  Process
  5901.     -- any messages from the transport level.  Process any transport level 
  5902.     -- input.  If APL had completed sending data to the NVT printer  and  had
  5903.     -- no queued input from  the  NVT keyboard  for  further processing 
  5904.     -- (NVT I/O  state  is no-I/O-done) and the TELNET go ahead was not 
  5905.     -- already sent then the APL must transmit the TELNET GA (go ahead) to
  5906.     -- the transport level [2] and mark the go ahead sent state to 
  5907.     -- go_ahead_sent.  Restore the user information.
  5908.     --
  5909.     --
  5910.     -- SPECIFICATION REFERENCES:
  5911.     -- 
  5912.     --    [1] Network Working Group Request for Comments: 854, May 1983,
  5913.     --        TELNET PROTOCOL SPECIFICATION
  5914.     --
  5915.     --    [2] RFC 854 : TELNET rotocol Specification
  5916.     --         page 5, condition 2
  5917.     --
  5918.     --------------------------------------------------------------------------
  5919.  
  5920.     old_communication_state : user_data.communication_state_type ;
  5921.     communication_state : user_data.communication_state_type RENAMES
  5922.      user_data.user_control_block.communication_state ;
  5923.  
  5924.     FUNCTION time_to_send_telnet_go_ahead RETURN BOOLEAN IS 
  5925.              ----------------------------
  5926.       send_flag               : BOOLEAN := FALSE ;
  5927.       ga_not_suppressed       : BOOLEAN := TRUE ;
  5928.       local_options_in_effect : user_data.option_table_type RENAMES
  5929.        user_data.user_control_block.option_tables.local_options_in_effect ;
  5930.     BEGIN
  5931.       FOR index IN 1..local_options_in_effect.number_of_items LOOP
  5932.         IF local_options_in_effect.option(index) = suppress_ga THEN
  5933.           ga_not_suppressed := FALSE ;
  5934.           EXIT ;
  5935.         END IF ;
  5936.       END LOOP ;
  5937.       IF ga_not_suppressed AND THEN
  5938.        (user_control_block.NVT_IO_state = no_IO_done AND 
  5939.        user_control_block.ga_state = no_go_ahead_sent AND
  5940.        user_control_block.communication_state = 
  5941.        user_data.connection_established) THEN
  5942.          send_flag := TRUE ;
  5943.       END IF ;
  5944.       RETURN send_flag ;
  5945.     END time_to_send_telnet_go_ahead ;
  5946.  
  5947.  
  5948.   BEGIN 
  5949.  
  5950. --    user_data.put(user_info.user_control_block) ; --initialize_user_information
  5951.     user_data.put(user_info) ; -- made public
  5952.  
  5953.     -- make one "pass" for this user 
  5954.     old_communication_state := communication_state ;
  5955.     user_control_block.NVT_IO_state := no_IO_done ;
  5956.     process_any_input_from_the_nvt_keyboard ;
  5957.     process_any_messages_from_the_transport_level ;
  5958.     process_any_input_from_the_transport_level ;
  5959.     IF time_to_send_telnet_go_ahead THEN
  5960.       transmit_telnet_go_ahead ;
  5961.       user_control_block.ga_state := go_ahead_sent ;
  5962.     END IF ;
  5963.     IF (old_communication_state = user_data.no_connection_established) AND THEN
  5964.      (communication_state = user_data.connection_established) THEN
  5965.       option_negotiation.negotiate_initial_desired_options ;
  5966.     END IF ;
  5967.      
  5968. --    user_data.get(user_info.user_control_block) ; -- restore_user_information ;
  5969.     user_data.get(user_info) ; -- made public for ease of test/debug
  5970.  
  5971.   idle := user_control_block.nvt_io_state = no_io_done ;
  5972.  
  5973.   EXCEPTION
  5974.     WHEN OTHERS =>
  5975.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN telnetpac.telnet") ;
  5976.       RAISE ;
  5977.   END telnet ; -- body
  5978.  
  5979. BEGIN -- telnet_package body
  5980.   NULL ; 
  5981.   EXCEPTION
  5982.     WHEN OTHERS =>
  5983.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN telnetpac instantiation") ;
  5984.       RAISE ;
  5985. END telnet_package ; -- body
  5986. --::::::::::::::
  5987. --idebugso_.ada
  5988. --::::::::::::::
  5989. -----------------------------------------------------------------------
  5990. --
  5991. --         DoD Protocols    NA-00004-200       80-01057-100(-)
  5992. --         E-Systems, Inc.  August 07, 1985
  5993. --
  5994. --         IDEBUGSO_.ADA       Author : Mike Thomas 
  5995. --
  5996. -----------------------------------------------------------------------
  5997.  
  5998. -- File : idebugso     
  5999.  
  6000. --   5/9/85  2:53 PM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS
  6001. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  6002.  
  6003. --   5/23/85  11:14 AM : MODIFY FOR TELESOFT    AUTHOR : MIKE THOMAS
  6004. --                       OLD CODE (DEC) MARKED AS --&MT 
  6005.  
  6006. --   5/23/85  11:55 AM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS
  6007. --                       OLD CODE (TELESOFT) MARKED AS --&MT 
  6008.  
  6009. -- INTERACTIVE DEBUG STATE OUTPUT FOR TN TEST/DEBUG
  6010.  
  6011. WITH user_data ;
  6012. USE  user_data ;
  6013.  
  6014. PACKAGE I_debug_state_output IS
  6015.  
  6016.   PROCEDURE print_ppl_trans_buffers    (ucb : IN control_block_type) ;
  6017.  
  6018.   PROCEDURE print_telnet_option_tables (ucb : IN control_block_type) ;
  6019.  
  6020.   PROCEDURE print_user_control_block   (ucb : IN control_block_type) ; 
  6021.  
  6022.   PROCEDURE dump_all                   (ucb : IN control_block_type) ;
  6023.   --    print_ppl_trans_buffers ;
  6024.   --    print_telnet_option_tables ;
  6025.   --    print_user_control_block ;
  6026. END I_debug_state_output ; -- spec
  6027.  
  6028. --::::::::::::::
  6029. --idebugso.ada
  6030. --::::::::::::::
  6031. -----------------------------------------------------------------------
  6032. --
  6033. --         DoD Protocols    NA-00004-200       80-01058-100(-)
  6034. --         E-Systems, Inc.  August 07, 1985
  6035. --
  6036. --         IDEBUGSO.ADA       Author : Mike Thomas 
  6037. --
  6038. -----------------------------------------------------------------------
  6039.  
  6040. -- File : idebugso     
  6041.  
  6042. --   5/9/85  3:00 PM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS
  6043. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  6044.  
  6045. --   5/23/85  11:14 AM : MODIFY FOR TELESOFT    AUTHOR : MIKE THOMAS
  6046. --                       OLD CODE (DEC) MARKED AS --&MT 
  6047.  
  6048. --   5/23/85  11:59 AM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS 
  6049. --                       OLD CODE (TELESOFT) MARKED AS --&MT 
  6050.  
  6051. -- INTERACTIVE DEBUG STATE OUTPUT FOR TN TEST/DEBUG
  6052.  
  6053. WITH SYSTEM ; -- access ascii characters
  6054. WITH debug_io ; -- writes info to a debug file and/or the CRT.
  6055.  
  6056. PACKAGE BODY I_debug_state_output IS
  6057.  
  6058.   --&MT SUBTYPE bit_count_32_type IS LONG_INTEGER ; 
  6059.   SUBTYPE bit_count_32_type IS INTEGER ;
  6060.  
  6061.   --&MT SUBTYPE bit_count_16_type IS INTEGER ; 
  6062.   SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  6063.  
  6064.   --&MT SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  6065.   SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  6066.  
  6067.   PROCEDURE print_ppl_trans_buffers (ucb : IN control_block_type) IS 
  6068.   BEGIN
  6069.     debug_io.put_line(' ') ;
  6070.     debug_io.put_line("PPL TRANSPORT LEVEL BUFFERS.") ;
  6071.     debug_io.put_line("----------------------------") ;
  6072.   
  6073.   
  6074.     DECLARE
  6075.       in_buf     : trans_to_telnet_messages_record RENAMES 
  6076.                    ucb.trans_buffers.trans_to_telnet_messages ;
  6077.       head       : trans_to_telnet_msg_buf_ptr_type := in_buf.buf_head ;
  6078.       tail       : trans_to_telnet_msg_buf_ptr_type := in_buf.buf_tail ;
  6079.  
  6080.       buf_length : CONSTANT bit_count_32_type := 
  6081.        bit_count_32_type(trans_to_telnet_msg_buffer_length) ;
  6082. --&MT buf_length : CONSTANT bit_count_16_type := 
  6083. --&MT  bit_count_16_type(trans_to_telnet_msg_buffer_length) ;
  6084.  
  6085.       out_buf    : STRING(1..buf_length) ;
  6086.  
  6087.       out_ptr    : bit_count_32_type RANGE 0..buf_length := 0 ;
  6088. --&MT out_ptr    : bit_count_16_type RANGE 0..buf_length := 0 ;
  6089.  
  6090.       char_byte  : bit_count_8_type ;
  6091.     BEGIN
  6092.       debug_io.put_line(' ') ;
  6093.       debug_io.put_line("TRANS TO TELNET MESSAGE BUFFER") ;
  6094.       debug_io.put("head=") ;
  6095.       debug_io.put(head) ;
  6096.       debug_io.put("  tail=") ;
  6097.       debug_io.put_line(tail) ;
  6098.       WHILE (head + 1) MOD bit_count_16_type(buf_length) /= tail LOOP
  6099.         head := (head + 1) MOD bit_count_16_type(buf_length) ;
  6100.         char_byte := in_buf.buffer(head) ;
  6101.         IF bit_count_16_type(char_byte) >= bit_count_16_type(16#20#)
  6102.          AND bit_count_16_type(char_byte) < bit_count_16_type(16#7F#) THEN
  6103.           out_ptr := out_ptr + 1 ;
  6104.           out_buf(out_ptr) := CHARACTER'VAL(char_byte) ;
  6105.         ELSE
  6106.           debug_io.put(out_buf(1..out_ptr)) ;
  6107.           out_ptr := 0 ;
  6108.           debug_io.put('<') ;
  6109.           debug_io.put_byte(char_byte) ;
  6110.           debug_io.put('>') ;
  6111.         END IF ;
  6112.       END LOOP ;
  6113.       debug_io.put_line(out_buf(1..out_ptr)) ;
  6114.     EXCEPTION
  6115.       WHEN OTHERS =>
  6116.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN IDEBUGSO.TR TO TN MSG BUF") ;
  6117.         RAISE ;
  6118.     END ;    
  6119.   
  6120.     DECLARE
  6121.       in_buf     : trans_to_telnet_data_record RENAMES 
  6122.                    ucb.trans_buffers.trans_to_telnet_data ;
  6123.       head       : trans_to_telnet_data_buf_ptr_type := in_buf.buf_head ;
  6124.       tail       : trans_to_telnet_data_buf_ptr_type := in_buf.buf_tail ;
  6125.  
  6126.       buf_length : CONSTANT bit_count_32_type := 
  6127.        bit_count_32_type(trans_to_telnet_data_buffer_length) ;
  6128. --&MT buf_length : CONSTANT bit_count_16_type :=
  6129. --&MT  bit_count_16_type(trans_to_telnet_data_buffer_length)
  6130.  
  6131.       out_buf    : STRING(1..buf_length) ;
  6132.  
  6133.       out_ptr    : bit_count_32_type RANGE 0..buf_length := 0 ;
  6134. --&MT out_ptr    : bit_count_16_type RANGE 0..buf_length := 0 ;
  6135.  
  6136.       char_byte  : bit_count_8_type ;
  6137.     BEGIN
  6138.       debug_io.put_line(' ') ;
  6139.       debug_io.put_line("TRANS TO TELNET DATA BUFFER") ;
  6140.       debug_io.put("head=") ;
  6141.       debug_io.put(head) ;
  6142.       debug_io.put("  tail=") ;
  6143.       debug_io.put_line(tail) ;
  6144.       WHILE (head + 1) MOD bit_count_16_type(buf_length) /= tail LOOP
  6145.         head := (head + 1) MOD bit_count_16_type(buf_length) ;
  6146.         char_byte := in_buf.buffer(head) ;
  6147.         IF bit_count_16_type(char_byte) >= bit_count_16_type(16#20#)
  6148.          AND bit_count_16_type(char_byte) < bit_count_16_type(16#7F#) THEN -- printable
  6149.           out_ptr := out_ptr + 1 ;
  6150.           out_buf(out_ptr) := CHARACTER'VAL(char_byte) ;
  6151.         ELSE
  6152.           debug_io.put(out_buf(1..out_ptr)) ;
  6153.           out_ptr := 0 ;
  6154.           debug_io.put('<') ;
  6155.           debug_io.put_byte(char_byte) ;
  6156.           debug_io.put('>') ;
  6157.         END IF ;
  6158.       END LOOP ;
  6159.       debug_io.put_line(out_buf(1..out_ptr)) ;
  6160.     EXCEPTION
  6161.       WHEN OTHERS =>
  6162.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN IDEBUGSO.TR TO TN DATA BUF") ;
  6163.         RAISE ;
  6164.     END ;    
  6165.     
  6166.   END print_ppl_trans_buffers ;
  6167.  
  6168.   
  6169.  
  6170.   PROCEDURE print_telnet_option_tables (ucb : IN control_block_type) IS 
  6171.     ot : option_tables_type 
  6172.      RENAMES ucb.option_tables ;
  6173.  
  6174.     PROCEDURE print_items_in_table
  6175.               --------------------
  6176.      (table : IN user_data.option_table_type) IS
  6177.     BEGIN
  6178.       FOR index IN 1..table.number_of_items LOOP 
  6179.         CASE table.option(index) IS
  6180.           WHEN user_data.echo =>
  6181.             debug_io.put(" echo ") ;
  6182.           WHEN user_data.suppress_ga =>
  6183.             debug_io.put(" suppress_ga ") ;
  6184.           WHEN OTHERS =>
  6185.             debug_io.put("undefined item") ;
  6186.         END CASE ;  
  6187.       END LOOP ;
  6188.     END print_items_in_table ;
  6189.       
  6190.   BEGIN
  6191.     debug_io.put_line(' ') ;
  6192.     debug_io.put_line("TELNET OPTION TABLES") ;
  6193.     debug_io.put_line("--------------------") ;
  6194.   
  6195.     debug_io.put_line(' ') ;
  6196.     debug_io.put("local options desired : ") ;
  6197.     print_items_in_table(ot.local_options_desired) ;
  6198.     debug_io.put_line(' ') ;
  6199.   
  6200.     debug_io.put_line(' ') ;
  6201.     debug_io.put("remote options desired : ") ;
  6202.     print_items_in_table(ot.remote_options_desired) ;
  6203.     debug_io.put_line(' ') ;
  6204.          
  6205.     debug_io.put_line(' ') ;
  6206.     debug_io.put("local options pending : ") ;
  6207.     print_items_in_table(ot.local_options_pending) ;
  6208.     debug_io.put_line(' ') ;
  6209.   
  6210.     debug_io.put_line(' ') ;
  6211.     debug_io.put("remote options pending : ") ;
  6212.     print_items_in_table(ot.remote_options_pending) ; 
  6213.     debug_io.put_line(' ') ;
  6214.   
  6215.     debug_io.put_line(' ') ;
  6216.     debug_io.put("local options in effect : ") ;
  6217.     print_items_in_table(ot.local_options_in_effect) ;
  6218.     debug_io.put_line(' ') ;
  6219.   
  6220.     debug_io.put_line(' ') ;
  6221.     debug_io.put("remote options in effect : ") ;
  6222.     print_items_in_table(ot.remote_options_in_effect) ;
  6223.     debug_io.put_line(' ') ;
  6224.  
  6225.   EXCEPTION
  6226.     WHEN OTHERS =>
  6227.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN IDEBUGSO.PRNT OPT TABS") ;
  6228.       RAISE ;
  6229.  
  6230.   END print_telnet_option_tables ;
  6231.   
  6232.  
  6233.   
  6234.   PROCEDURE print_user_control_block (ucb : IN control_block_type) IS 
  6235.   BEGIN
  6236.     debug_io.put_line(' ') ;
  6237.     debug_io.put_line("USER CONTROL BLOCK.") ;
  6238.     debug_io.put_line("------------------") ;
  6239.     debug_io.put_line(' ') ;
  6240.   
  6241.     DECLARE -- partial command buffer
  6242.       length : CONSTANT partial_command_buf_length := 
  6243.        ucb.partial_command_buffer.length ;
  6244.  
  6245.       max_buf_length : CONSTANT bit_count_32_type := 
  6246.        bit_count_32_type(max_cmd_length) ;
  6247. --&MT max_buf_length : CONSTANT bit_count_16_type :=
  6248. --&MT  bit_count_16_type(max_cmd_length) ;
  6249.  
  6250.       out_buf : STRING(1..max_buf_length) ;
  6251.  
  6252.       out_ptr : bit_count_32_type RANGE 0..max_buf_length := 0 ;
  6253. --&MT out_ptr : bit_count_16_type RANGE 0..max_buf_length := 0 ;
  6254.  
  6255.       char_byte  : bit_count_8_type ;
  6256.     BEGIN
  6257.       debug_io.put_line("APL partial command buffer.") ;
  6258.       debug_io.put("length=") ;
  6259.       debug_io.put_line(length) ;
  6260.       FOR index IN 1..length LOOP
  6261.         char_byte := ucb.partial_command_buffer.buffer(index) ;
  6262.         IF bit_count_16_type(char_byte) >= bit_count_16_type(16#20#)
  6263.           AND bit_count_16_type(char_byte) < bit_count_16_type(16#7F#) THEN -- printable
  6264.           out_ptr := out_ptr + 1 ;
  6265.           out_buf(out_ptr) := CHARACTER'VAL(char_byte) ;
  6266.         ELSE -- print ascii code #
  6267.           debug_io.put(out_buf(1..out_ptr)) ;
  6268.           out_ptr := 0 ;
  6269.           debug_io.put('<') ;
  6270.           debug_io.put_byte(char_byte) ;
  6271.           debug_io.put('>') ;
  6272.         END IF ;
  6273.       END LOOP ; 
  6274.  
  6275. --&MT   debug_io.put_line(out_buf(1..bit_count_16_type(length))) ;
  6276.         debug_io.put_line(out_buf(1..bit_count_32_type(length))) ;
  6277.     
  6278.     EXCEPTION
  6279.       WHEN OTHERS =>
  6280.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN IDEBUGSO.PART_CMD_BUF") ;
  6281.         RAISE ;
  6282.     END ;
  6283.   
  6284.   
  6285.     DECLARE -- data buffer
  6286.       head : data_buf_ptr := ucb.data_buffer.buf_head ;
  6287.       tail : data_buf_ptr := ucb.data_buffer.buf_tail ;
  6288.  
  6289.       buf_length : CONSTANT bit_count_32_type := 
  6290.        bit_count_32_type(data_buffer_length) ;
  6291. --&MT buf_length : CONSTANT bit_count_16_type :=
  6292. --&MT  bit_count_16_type(data_buffer_length) ;
  6293.  
  6294.       out_buf    : STRING(1..buf_length) ;
  6295.  
  6296.       out_ptr    : bit_count_32_type RANGE 0..buf_length := 0 ;
  6297. --&MT out_ptr    : bit_count_16_type RANGE 0..buf_length := 0 ;
  6298.  
  6299.       char_byte  : bit_count_8_type ;
  6300.     BEGIN
  6301.       debug_io.put_line(' ') ;
  6302.       debug_io.put_line("APL data buffer.") ;
  6303.       debug_io.put("head=") ;
  6304.       debug_io.put(head) ;
  6305.       debug_io.put("  tail=") ;
  6306.       debug_io.put_line(tail) ;
  6307.       WHILE (head + 1) MOD bit_count_16_type(buf_length) /= tail LOOP
  6308.         head := (head + 1) MOD bit_count_16_type(buf_length) ;
  6309.         char_byte := ucb.data_buffer.buffer(head) ;
  6310.         IF bit_count_16_type(char_byte) >= bit_count_16_type(16#20#)
  6311.          AND bit_count_16_type(char_byte) < bit_count_16_type(16#7F#) THEN -- printable
  6312.           out_ptr := out_ptr + 1 ;
  6313.           out_buf(out_ptr) := CHARACTER'VAL(char_byte) ;
  6314.         ELSE
  6315.           debug_io.put(out_buf(1..out_ptr)) ;
  6316.           out_ptr := 0 ;
  6317.           debug_io.put('<') ;
  6318.           debug_io.put_byte(char_byte) ;
  6319.           debug_io.put('>') ;
  6320.         END IF ;
  6321.       END LOOP ;
  6322.       debug_io.put_line(out_buf(1..out_ptr)) ;
  6323.     EXCEPTION
  6324.       WHEN OTHERS =>
  6325.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN IDEBUGSO.DATA_BUF") ;
  6326.         RAISE ;
  6327.     END ;
  6328.   
  6329.  
  6330.     
  6331.   -- state information
  6332.     debug_io.put_line(' ') ;
  6333.     debug_io.put_line("STATE INFORMATION.") ;
  6334.     debug_io.put_line("------------------") ;
  6335.     debug_io.put_line(' ') ;
  6336.  
  6337.     debug_io.put("port=") ;
  6338.     debug_io.put_line(ucb.port) ;
  6339.  
  6340.     debug_io.put("tl_port_number=") ;
  6341.     debug_io.put_line(ucb.tl_port_number) ;
  6342.  
  6343.     debug_io.put("nvt_io_state = ") ;
  6344.     IF ucb.nvt_io_state = IO_done THEN
  6345.       debug_io.put_line("io_done") ;
  6346.     ELSIF ucb.nvt_io_state = no_IO_done THEN
  6347.       debug_io.put_line("no_io_done") ;
  6348.     ELSE
  6349.       debug_io.put_line("*UNDEFINED*") ;
  6350.     END IF ;
  6351.   
  6352.     debug_io.put("communication_state = ") ;
  6353.     IF ucb.communication_state = connection_established THEN
  6354.       debug_io.put_line("connection_established") ;
  6355.     ELSIF ucb.communication_state = no_connection_established THEN
  6356.       debug_io.put_line("no_connection_established") ;
  6357.     ELSE
  6358.       debug_io.put_line("*UNDEFINED*") ;
  6359.     END IF ;
  6360.   
  6361.   
  6362.     debug_io.put("command_state = ") ;
  6363.     IF ucb.command_state = partial_command THEN
  6364.       debug_io.put_line("partial_command") ;
  6365.     ELSIF ucb.command_state = no_partial_command THEN
  6366.       debug_io.put_line("no_partial_command") ;
  6367.     ELSE
  6368.       debug_io.put_line("*UNDEFINED*") ;
  6369.     END IF ;
  6370.   
  6371.   
  6372.     debug_io.put("ga_state = ") ;
  6373.     IF ucb.ga_state = go_ahead_sent THEN
  6374.       debug_io.put_line("go_ahead_sent") ;
  6375.     ELSIF ucb.ga_state = no_go_ahead_sent THEN
  6376.       debug_io.put_line("no_go_ahead_sent") ;
  6377.     ELSE
  6378.       debug_io.put_line("*UNDEFINED*") ;
  6379.     END IF ;
  6380.  
  6381.     debug_io.put("ga_received = ") ;
  6382.     IF ucb.ga_received = TRUE THEN
  6383.       debug_io.put_line("go_ahead_received") ;
  6384.     ELSIF ucb.ga_received = FALSE THEN
  6385.       debug_io.put_line("no_go_ahead_received") ;
  6386.     ELSE
  6387.       debug_io.put_line("*UNDEFINED*") ;
  6388.     END IF ;
  6389.  
  6390.     debug_io.put("synch_is_in_progress = ") ;
  6391.     IF ucb.synch_is_in_progress = TRUE THEN
  6392.       debug_io.put_line("synch_is_in_progress") ;
  6393.     ELSIF ucb.synch_is_in_progress = FALSE THEN
  6394.       debug_io.put_line("no_synch_is_in_progress") ;
  6395.     ELSE
  6396.       debug_io.put_line("*UNDEFINED*") ;
  6397.     END IF ;
  6398.  
  6399.     debug_io.put("last_keybd_char_was_cmd = ") ;
  6400.     IF ucb.last_keybd_char_was_cmd = TRUE THEN
  6401.       debug_io.put_line("TRUE") ;
  6402.     ELSIF ucb.synch_is_in_progress = FALSE THEN
  6403.       debug_io.put_line("FALSE") ;
  6404.     ELSE
  6405.       debug_io.put_line("*UNDEFINED*") ;
  6406.     END IF ;
  6407.  
  6408.     debug_io.put("rcv_data_is_urgent = ") ;
  6409.     IF ucb.rcv_data_is_urgent = TRUE THEN
  6410.       debug_io.put_line("TRUE") ;
  6411.     ELSIF ucb.rcv_data_is_urgent = FALSE THEN
  6412.       debug_io.put_line("FALSE") ;
  6413.     ELSE
  6414.       debug_io.put_line("*UNDEFINED*") ;
  6415.     END IF ;
  6416.  
  6417.  
  6418.     debug_io.put("last_data_char_rcv_not_cr = ") ;
  6419.     IF ucb.last_data_char_rcv_not_cr = TRUE THEN
  6420.       debug_io.put_line("TRUE") ;
  6421.     ELSIF ucb.last_data_char_rcv_not_cr = FALSE THEN
  6422.       debug_io.put_line("FALSE") ;
  6423.     ELSE
  6424.       debug_io.put_line("*UNDEFINED*") ;
  6425.     END IF ;
  6426.  
  6427.   
  6428.   EXCEPTION
  6429.     WHEN OTHERS =>
  6430.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN IDEBUGSO.PRINT UCB") ;
  6431.       RAISE ;
  6432.  
  6433.   END print_user_control_block ;
  6434.   
  6435.  
  6436.  
  6437.   PROCEDURE dump_all (ucb : IN control_block_type) IS
  6438.   BEGIN
  6439.     debug_io.put_line(' ') ;
  6440.     debug_io.put_line
  6441.      (".......................... dump all start ......................") ;
  6442.     debug_io.put_line(' ') ;
  6443.  
  6444.     print_ppl_trans_buffers(ucb) ;
  6445.     print_telnet_option_tables(ucb) ;
  6446.     print_user_control_block(ucb) ;
  6447.  
  6448.     debug_io.put_line(' ') ;
  6449.     debug_io.put_line
  6450.      ("eeeeeeeeeeeeeeeeeeeeeeeee  dump all end   eeeeeeeeeeeeeeeeeeeeee") ;
  6451.     debug_io.put_line(' ') ;
  6452.   EXCEPTION
  6453.     WHEN OTHERS =>
  6454.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN IDEBUGSO.DUMP ALL") ;
  6455.       RAISE ;
  6456.   END dump_all ;
  6457.  
  6458. BEGIN
  6459.   NULL ;
  6460. EXCEPTION
  6461.   WHEN OTHERS =>
  6462.     debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN IDEBUGSO.TR TO TN MSG BUF") ;
  6463. RAISE ;
  6464. END I_debug_state_output ;
  6465.  
  6466. --::::::::::::::
  6467. --server_telnet_package_.ada
  6468. --::::::::::::::
  6469. -----------------------------------------------------------------------
  6470. --
  6471. --         DoD Protocols    NA-00004-200       80-01157-100(-)
  6472. --         E-Systems, Inc.  August 07, 1985
  6473. --
  6474. --         SERVER_TELNET_PACKAGE_.ADA       Author : Mike Thomas
  6475. --
  6476. -----------------------------------------------------------------------
  6477.      
  6478. -- File : server_telnet.ada     Author : Mike Thomas
  6479. -- interactive telnet controller/debugger
  6480. --
  6481. -- 5/31/85    4:21 PM : modify for dec
  6482. -- 6/10/85   10:40 AM : mods to run with new tcp on vax
  6483. --            1:28 PM : route debug to disk file
  6484. -- 6/11/85    5:42 PM : mod due to new tcp interface
  6485. -- 6/12/85    2:44 PM : ditto
  6486. -- 6/14/85    3:00 PM : tasking mod
  6487. -- 6/16/85    1:55 PM : input local port number for initial passive open
  6488. -- 6/17/85   10:24 AM : can't do above task steals it so hard code lpn
  6489. -- 6/18/85   11:36 AM : put initialization stuff in task
  6490. -- 6/19/85   10:39 AM : init tcp buffers
  6491. -- 6/20/85   11:20 AM : make server telnet
  6492. --            1:48 AM : kick off tcp_reader task
  6493. -- 6/24/85    2:05 PM : Make Procedure into a PACKAGE exporting task type
  6494. -- 7/10/85    2:52 PM : modify name of package
  6495. -- 7/11/85    9:53 AM : don't do passive open for user_ftp (port num=-1)
  6496.      
  6497. WITH buffer_data ; -- access sixteen_bits type, init buffers procedure
  6498. PACKAGE  server_telnet_package  IS                                      --&KJW
  6499.   USE buffer_data;                                                      --&KJW
  6500.                                                                         --&KJW
  6501.   TASK TYPE  telnet_controller  IS                                      --&KJW
  6502.     PRAGMA PRIORITY(7) ;                                                --&KJW
  6503.     ENTRY  Connection_Assignments ( local,foreign : sixteen_bits;       --&KJW
  6504.                                     foreign_net   : thirtytwo_bits );   --&KJW
  6505.   END telnet_controller ;                                               --&KJW
  6506.                                                                         --&KJW
  6507. END server_telnet_package ;
  6508. --&KJW
  6509.                                                                         --&KJW
  6510. --::::::::::::::
  6511. --server_telnet_package.ada
  6512. --::::::::::::::
  6513. -----------------------------------------------------------------------
  6514. --
  6515. --         DoD Protocols    NA-00004-200       80-01066-100(-)
  6516. --         E-Systems, Inc.  August 07, 1985
  6517. --
  6518. --         SERVER_TELNET_PACKAGE.ADA       Author : Mike Thomas
  6519. --
  6520. -----------------------------------------------------------------------
  6521.      
  6522. -- File : server_telnet.ada     Author : Mike Thomas
  6523. --                                     : Kevin Weise (convt to package)
  6524. -- interactive telnet controller/debugger
  6525. --
  6526. -- 5/31/85    4:21 PM : modify for dec
  6527. -- 6/10/85   10:40 AM : mods to run with new tcp on vax
  6528. --            1:28 PM : route debug to disk file
  6529. -- 6/11/85    5:42 PM : mod due to new tcp interface
  6530. -- 6/12/85    2:44 PM : ditto
  6531. -- 6/14/85    3:00 PM : tasking mod
  6532. -- 6/16/85    1:55 PM : input local port number for initial passive open
  6533. -- 6/17/85   10:24 AM : can't do above task steals it so hard code lpn
  6534. -- 6/18/85   11:36 AM : put initialization stuff in task
  6535. -- 6/19/85   10:39 AM : init tcp buffers
  6536. -- 6/20/85   11:20 AM : make server telnet
  6537. --            1:48 AM : kick off tcp_reader task
  6538. -- 6/24/85    2:05 PM : Make Procedure into a PACKAGE exporting task type
  6539. -- 7/10/85    2:52 PM : modify name of package
  6540. -- 7/11/85    9:53 AM : don't do passive open for user_ftp (port num=-1)
  6541. -- 7/12/85    1:21 PM : remove  : "with iotasks"
  6542. -- 7/14/85    9:00 PM : put option negotiation defaults in
  6543. -- 7/24/85    3:35 AM : disable debug output
  6544.      
  6545. WITH SYSTEM ; -- access ascii characters
  6546. WITH TEXT_IO ;
  6547. USE  TEXT_IO ;
  6548. WITH with_ulp_communicate ;
  6549.      
  6550. -- give i_controller access to all low level data structures
  6551. WITH debug_io ; -- writes info to a debug file and/or the CRT.
  6552. WITH i_debug_state_output ; -- state information output procedures
  6553. USE  i_debug_state_output ;
  6554. WITH user_data ;
  6555. USE  user_data ;
  6556.      
  6557. WITH telnet_package ;
  6558. WITH dec_tn_tasks ;
  6559.      
  6560. PACKAGE BODY  server_telnet_package IS          --&KJW
  6561. --&KJW  PROCEDURE server_telnet IS
  6562.      
  6563.   SUBTYPE bit_count_16_type is SHORT_INTEGER ;
  6564.      
  6565.   PACKAGE telnet_integer_io IS NEW
  6566.    text_io.integer_io(buffer_data.sixteen_bits) ;
  6567.      
  6568. -- This task is a mock controller/debugger for TELNET which will
  6569. -- simulate a TELNET user and TCP and call the TELNET procedure itself.
  6570. -- It will insert data and messages from the mock TCP into the
  6571. -- appropriate buffers so that TELNET will process them.  Likewise, it
  6572. -- will pull out messages and data that TELNET has sent to TCP and print
  6573. -- them.  Similer low level buffer processing will be done for the TELNET
  6574. -- user.
  6575.      
  6576.   TASK BODY telnet_controller IS --********** telnet_controller ****************
  6577.     idle            : BOOLEAN ; -- true when telnet did not process any input
  6578.     index           : bit_count_16_type := 0 ;
  6579.     user_dat_info   : telnet_package.user_info_type ;           --&KJW
  6580.     --  status : telnet_package.tp_status_type ;                --&KJW
  6581.     open_parameters : with_ulp_communicate.open_params ;        --&KJW
  6582.     options         : with_ulp_communicate.tcp_option_type ;    --&KJW
  6583.     tcp_message     : with_ulp_communicate.message ;            --&KJW
  6584.     lcn_pointer     : with_ulp_communicate.lcn_ptr_type ;       --&KJW
  6585.     request_ok      : BOOLEAN := FALSE ;                        --&KJW
  6586.     locl_prt,                                                   --&KJW
  6587.     forn_prt        : sixteen_bits;                             --&KJW
  6588.     forn_net        : thirtytwo_bits;                           --&KJW
  6589.   BEGIN
  6590.     --MT debug_io.destination := debug_io.debug_disk_file_only ;
  6591.     --MT debug_io.open_debug_disk_file ;
  6592.     debug_io.destination := debug_io.none ;
  6593.      
  6594.     buffer_data.init ; -- init tcp buffers
  6595.      
  6596.     telnet_package.set_io_port_address(1, user_dat_info) ;
  6597.   telnet_package.telnet_request_remote_to_do_option(suppress_ga, user_dat_info);
  6598.     telnet_package.telnet_request_to_do_option(suppress_ga, user_dat_info) ;
  6599.     -- telnet_package.telnet_request_to_do_option(echo, user_dat_info) ;
  6600.      
  6601.      
  6602.     debug_io.put_line("<<<<<<<  INITIAL STATE OF SERVER_TN  >>>>>>>>>") ;
  6603.     dump_all(user_dat_info) ; -- debug debugso
  6604.      
  6605.     ACCEPT Connection_Assignments ( local,foreign : sixteen_bits;       --&KJW
  6606.                                     foreign_net   : thirtytwo_bits ) DO --&KJW
  6607.         locl_prt := local;                                              --&KJW
  6608.         forn_prt := foreign;                                            --&KJW
  6609.         forn_net := foreign_net;                                        --&KJW
  6610.     END Connection_Assignments;                                         --&KJW
  6611.      
  6612.     IF locl_prt /= -1 THEN -- do passive open, set default option negotiation
  6613.       text_io.put_line("attempting passive open to tcp from controller...") ;
  6614.       debug_io.put_line("attempting passive open to tcp from controller...") ;
  6615.       FOR i IN 1..50 LOOP
  6616.         options(i) := 0 ;
  6617.       END LOOP ;
  6618.       open_parameters := (locl_prt,                     --&KJW
  6619.                           forn_prt,                     --&KJW
  6620.                           forn_net,                     --&KJW
  6621.                           with_ulp_communicate.passive,
  6622.                           0,
  6623.                           255,
  6624.                           lcn_pointer,
  6625.                           0,
  6626.                           0,
  6627.                           options) ;
  6628.       tcp_message := (with_ulp_communicate.open, open_parameters);
  6629.       with_ulp_communicate.message_for_tcp(tcp_message, request_ok) ;
  6630.       user_dat_info.lcn := tcp_message.open_parameters.local_connection_name ;
  6631.       IF request_ok THEN
  6632.         TEXT_IO.PUT_LINE("passive open REQUEST_OK") ;
  6633.         debug_io.put_line("passive open REQUEST_OK") ;
  6634.         debug_io.put_line("beginning calls to telnet") ;
  6635.         TEXT_IO.PUT_LINE ("beginning calls to telnet") ;
  6636.         dec_tn_tasks.tcp_reader.start ;
  6637.       ELSE
  6638.         TEXT_IO.PUT_LINE("passive open REQUEST_OK = FALSE!") ;
  6639.         debug_io.put_line("passive open REQUEST_OK = FALSE!") ;
  6640.       END IF ; --  request ok?
  6641.     END IF ; -- local port /= -1?
  6642.     LOOP -- CYCLE TELNET
  6643.       dec_tn_tasks.tn.wait ; -- wait for keyboard entry or message/data from TCP
  6644.       idle := FALSE ;
  6645.       WHILE NOT(idle) LOOP
  6646.         -- run telnet [one telnet pass]
  6647.         index := index + 1 ;
  6648. --        TEXT_IO.PUT_LINE("server telnet is running...") ;
  6649. --        TEXT_IO.NEW_LINE ;
  6650.         debug_io.put_line(" ") ;
  6651.         debug_io.put("********  *** *** ***  call #") ;
  6652.         debug_io.put(index) ;
  6653.         debug_io.put_line(" to telnet  *** *** *** *******") ;
  6654.         debug_io.put_line(" ") ;
  6655.      
  6656.         telnet_package.telnet(user_dat_info, idle) ;
  6657.      
  6658.         debug_io.put_line(" ") ;
  6659.         debug_io.put("^^^^^^^^ ^^^ ^^^ ^^^ after call #") ;
  6660.         debug_io.put(index) ;
  6661.         debug_io.put_line(" to server telnet  ^^^ ^^^ ^^^ ^^^^^^^^^") ;
  6662.         debug_io.put_line(" ") ;
  6663.         dump_all(user_dat_info) ;
  6664.       END LOOP ;
  6665.     END LOOP ;
  6666.     EXCEPTION
  6667.       WHEN OTHERS =>
  6668.         TEXT_IO.PUT_LINE("EXCEPTION IN TASK TELNET_CONTROLLER") ;
  6669.         DEBUG_IO.PUT_LINE("EXCEPTION IN TASK TELNET_CONTROLLER") ;
  6670.         RAISE ;
  6671.   END telnet_controller ;
  6672.      
  6673.      
  6674. BEGIN
  6675.   NULL ;
  6676. EXCEPTION
  6677.   WHEN OTHERS =>
  6678.   TEXT_IO.PUT_LINE("EXCEPTION IN PROCEDURE SERVER_TELNET") ;
  6679.   DEBUG_IO.PUT_LINE("EXCEPTION IN PROCEDURE SERVER_TELNET") ;
  6680.   RAISE ;
  6681.      
  6682. END server_telnet_package ;
  6683. --::::::::::::::
  6684. --server_telnet.ada
  6685. --::::::::::::::
  6686. -----------------------------------------------------------------------
  6687. --
  6688. --         DoD Protocols    NA-00004-200       80-01065-100(-)
  6689. --         E-Systems, Inc.  August 07, 1985
  6690. --
  6691. --         SERVER_TELNET.ADA       Author : Mike Thomas
  6692. --
  6693. -----------------------------------------------------------------------
  6694. -- 7/11/85   9:51 AM :                File : server_telnet
  6695. --                                    AUTHOR : Mike Thomas
  6696. -- 7/12/85   1:23 PM : with iotasks
  6697.      
  6698. WITH iotasks ;
  6699. WITH server_telnet_package ;
  6700. USE  server_telnet_package ;
  6701. PROCEDURE server_telnet IS
  6702.   run_telnet_server_task : telnet_controller ;
  6703. BEGIN
  6704.   run_telnet_server_task.connection_assignments(2,0,0) ;
  6705. END server_telnet ;
  6706. --::::::::::::::
  6707. --user_telnet.ada
  6708. --::::::::::::::
  6709. -----------------------------------------------------------------------
  6710. --
  6711. --         DoD Protocols    NA-00004-200       80-01071-100(-)
  6712. --         E-Systems, Inc.  August 07, 1985
  6713. --
  6714. --         USER_TELNET.ADA       Author : Mike Thomas
  6715. --
  6716. -----------------------------------------------------------------------
  6717.      
  6718. -- File : user_telnet  Author : Mike Thomas
  6719. -- interactive telnet controler/debugger
  6720. --
  6721. -- 5/31/85    4:21 PM : modify for dec
  6722. -- 6/10/85   10:40 AM : mods to run with new tcp on vax
  6723. --            1:28 PM : route debug to disk file
  6724. -- 6/11/85    5:42 PM : mod due to new tcp interface
  6725. -- 6/12/85    2:44 PM : ditto
  6726. -- 6/14/85    3:00 PM : tasking mod
  6727. -- 6/16/85    1:55 PM : input local port number for initial passive open
  6728. -- 6/17/85   10:24 AM : can't do above task steals it so hard code lpn
  6729. -- 6/18/85   11:36 AM : put initialization stuff in task
  6730. -- 6/19/85   10:39 AM : init tcp buffers
  6731. --            8:41 PM : try turning debug off
  6732. -- 6/20/85   10:57 AM : make this a user telnet
  6733. --  7/2/85    1:06 PM : ask for remote echo, suppress ga's before run, debug off
  6734.      
  6735. WITH SYSTEM ; -- access ascii characters
  6736. WITH TEXT_IO ;
  6737. USE  TEXT_IO ;
  6738. WITH with_ulp_communicate ;
  6739. WITH buffer_data ; -- access sixteen_bits type, init buffers procedure
  6740.      
  6741. -- give i_controler access to all low level data structures
  6742. WITH debug_io ; -- writes info to a debug file and/or the CRT.
  6743. WITH i_debug_state_output ; -- state information output procedures
  6744. USE  i_debug_state_output ;
  6745. WITH user_data ;
  6746. USE  user_data ;
  6747.      
  6748. WITH telnet_package ;
  6749. WITH iotasks ;
  6750. WITH dec_tn_tasks ;
  6751.      
  6752. PROCEDURE user_telnet IS
  6753.      
  6754. -- This procedure is a mock controler/debugger for TELNET which will
  6755. -- simulate a TELNET user and TCP and call the TELNET procedure itself.
  6756. -- It will insert data and messages from the mock TCP into the
  6757. -- appropriate buffers so that TELNET will process them.  Likewise, it
  6758. -- will pull out messages and data that TELNET has sent to TCP and print
  6759. -- them.  Similer low level buffer processing will be done for the TELNET
  6760. -- user.
  6761.      
  6762.   idle : boolean ;
  6763.   user_dat_info : telnet_package.user_info_type ;
  6764.   SUBTYPE bit_count_16_type is SHORT_INTEGER ;
  6765.      
  6766.   PACKAGE telnet_integer_io IS NEW
  6767.    text_io.integer_io(buffer_data.sixteen_bits) ;
  6768.      
  6769.   open_parameters : with_ulp_communicate.open_params ;
  6770.   options : with_ulp_communicate.tcp_option_type ;
  6771.   tcp_message : with_ulp_communicate.message ;
  6772.   lcn_pointer : with_ulp_communicate.lcn_ptr_type ;
  6773.   request_ok : BOOLEAN := FALSE ;
  6774.      
  6775.   TASK telnet_controller IS
  6776.     PRAGMA PRIORITY(7) ;
  6777.   END telnet_controller ;
  6778.      
  6779.   TASK BODY telnet_controller IS --********** telnet_controler ****************
  6780.     idle : BOOLEAN ; -- true when telnet did not process any input
  6781.     index : bit_count_16_type := 0 ;
  6782.   BEGIN
  6783.     debug_io.destination := debug_io.debug_disk_file_only ;
  6784.     debug_io.open_debug_disk_file ;
  6785.     --MT debug_io.destination := debug_io.none ;
  6786.      
  6787.     buffer_data.init ; -- init tcp buffers
  6788.      
  6789.     telnet_package.set_io_port_address(1, user_dat_info) ;
  6790.      
  6791. --    telnet_package.telnet_request_remote_to_do_option(echo, user_dat_info) ;
  6792. --    telnet_package.telnet_request_remote_to_do_option(suppress_ga, user_dat_in
  6793. --    telnet_package.telnet_request_to_do_option(suppress_ga, user_dat_info) ;
  6794.      
  6795.     debug_io.put_line("<<<<<<<  INITIAL STATE OF USER_TN  >>>>>>>>>") ;
  6796.     dump_all(user_dat_info) ; -- debug debugso
  6797.      
  6798.     LOOP -- CYCLE TELNET
  6799.       dec_tn_tasks.tn.wait ; -- wait for keyboard entry or message/data from TCP
  6800.       idle := FALSE ;
  6801.       WHILE NOT(idle) LOOP
  6802.         -- run telnet [one telnet pass]
  6803.         index := index + 1 ;
  6804. --        TEXT_IO.PUT_LINE("user telnet is running...") ;
  6805. --        TEXT_IO.NEW_LINE ;
  6806.         debug_io.put_line(" ") ;
  6807.         debug_io.put("********  *** *** ***  call #") ;
  6808.         debug_io.put(index) ;
  6809.         debug_io.put_line(" to user telnet  *** *** *** *******") ;
  6810.         debug_io.put_line(" ") ;
  6811.      
  6812.         telnet_package.telnet(user_dat_info, idle) ;
  6813.      
  6814.         debug_io.put_line(" ") ;
  6815.         debug_io.put("^^^^^^^^ ^^^ ^^^ ^^^ after call #") ;
  6816.         debug_io.put(index) ;
  6817.         debug_io.put_line(" to user telnet  ^^^ ^^^ ^^^ ^^^^^^^^^") ;
  6818.         debug_io.put_line(" ") ;
  6819.         dump_all(user_dat_info) ;
  6820.       END LOOP ;
  6821.     END LOOP ;
  6822.     EXCEPTION
  6823.       WHEN OTHERS =>
  6824.         TEXT_IO.PUT_LINE("EXCEPTION IN TASK user TELNET_CONTROLLER") ;
  6825.         DEBUG_IO.PUT_LINE("EXCEPTION IN TASK user TELNET_CONTROLLER") ;
  6826.         RAISE ;
  6827.   END telnet_controller ;
  6828.      
  6829.      
  6830. BEGIN
  6831.      
  6832. ---  debug_io.close_debug_disk_file ;
  6833.   dec_tn_tasks.tn.go ;
  6834.   EXCEPTION
  6835.     WHEN OTHERS =>
  6836.       TEXT_IO.PUT_LINE("EXCEPTION IN PROCEDURE USER_TELNET") ;
  6837.       DEBUG_IO.PUT_LINE("EXCEPTION IN PROCEDURE USER_TELNET") ;
  6838.       RAISE ;
  6839.      
  6840. END user_telnet ;
  6841.