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

  1. --::::::::::::::
  2. --akeybdpac.txt
  3. --::::::::::::::
  4. -----------------------------------------------------------------------
  5. --
  6. --         DoD Protocols    NA-00009-200       80-01203-100(-)
  7. --         E-Systems, Inc.  August 07, 1985
  8. --
  9. --         akeybdpac.txt       Author : Mike Thomas
  10. --
  11. -----------------------------------------------------------------------
  12. WITH SYSTEM ;
  13. PACKAGE nvt_keyboard_input_processing IS
  14.   SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  15.   SUBTYPE character_type IS bit_count_8_type ;
  16.   FUNCTION there_is_input_from_the_NVT_keyboard
  17.    RETURN BOOLEAN ;
  18.   PROCEDURE get_a_character
  19.    (char : OUT character_type ;
  20.     the_char_is_a_control_function : OUT BOOLEAN) ;
  21.   PROCEDURE process_standard_control_function_from_keyboard
  22.    (char : IN character_type) ;
  23.   PROCEDURE process_partial_command
  24.    (char : IN character_type) ;
  25.   PROCEDURE put_character_in_data_buffer
  26.    (char : IN character_type) ;
  27.   PROCEDURE send_data_buffer_to_transport_level ;
  28. END nvt_keyboard_input_processing ;
  29.  
  30. WITH virtual_transport_level ;
  31. WITH virtual_terminal ;
  32. WITH option_negotiation ;
  33. WITH user_data ;
  34. USE user_data ;
  35. WITH debug_io ; 
  36. PACKAGE BODY  nvt_keyboard_input_processing IS
  37.   SUBTYPE bit_count_32_type IS LONG_INTEGER ; 
  38.   SUBTYPE bit_count_16_type IS INTEGER ; 
  39.   FUNCTION there_is_input_from_the_NVT_keyboard
  40.    RETURN BOOLEAN IS
  41.   BEGIN
  42.     RETURN virtual_terminal.there_are_characters_in_keyboard_buffer
  43.      (user_data.user_control_block.port) ;
  44.   END there_is_input_from_the_NVT_keyboard ;
  45.   PROCEDURE get_a_character
  46.    (char : OUT character_type ;
  47.     the_char_is_a_control_function : OUT BOOLEAN) IS
  48.     temp_char : character_type ;
  49.     temp_the_char_is_a_control_function : BOOLEAN ;
  50.     PROCEDURE determine_if 
  51.      (the_char_is_a_control_function : OUT BOOLEAN ;
  52.       char                           : IN  bit_count_8_type) IS 
  53.     BEGIN
  54.       the_char_is_a_control_function := FALSE ; 
  55.     END determine_if ;
  56.   BEGIN
  57.     virtual_terminal.get_next_character_from_keyboard_buffer 
  58.      (user_data.user_control_block.port, temp_char) ;
  59.     determine_if(temp_the_char_is_a_control_function, temp_char) ;
  60.     char := temp_char ;
  61.     the_char_is_a_control_function := temp_the_char_is_a_control_function ;
  62.   EXCEPTION
  63.     WHEN OTHERS =>
  64.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.get_a_char") ;
  65.       RAISE ;
  66.   END get_a_character ;
  67.   PROCEDURE process_standard_control_function_from_keyboard
  68.    (char : IN character_type) IS
  69.   IAC : bit_count_8_type := 255 ; 
  70.   no_partial_command : user_data.command_state_type ; 
  71.   urgent : BOOLEAN := TRUE ; 
  72.   command_bytes : virtual_transport_level.info_output_type(1..2) ; 
  73.   BEGIN
  74.     no_partial_command := user_data.no_partial_command ;
  75.     CASE char IS 
  76.       WHEN 242..249 => 
  77.         
  78.         IF user_data.user_control_block.command_state = no_partial_command THEN
  79.           put_character_in_data_buffer(IAC) ;
  80.           put_character_in_data_buffer(char) ;
  81.         ELSE 
  82.           process_partial_command(char) ;
  83.         END IF ; 
  84.       WHEN OTHERS =>
  85.         NULL ; 
  86.     END CASE ; 
  87.   EXCEPTION
  88.     WHEN OTHERS =>
  89.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.proc_std_cont_f") ;
  90.       RAISE ;
  91.   END process_standard_control_function_from_keyboard ;
  92.   PROCEDURE process_partial_command
  93.    (char : IN character_type) IS 
  94.     PROCEDURE add_the_character_to_the_partial_command_buffer
  95.      (char : IN character_type) IS
  96.     command_buffer      : user_data.out_string_type ;
  97.     SUBTYPE length_type IS bit_count_16_type RANGE 0..user_data.max_out_string ;
  98.     length              : length_type ;
  99.     no_partial_command  : user_data.command_state_type ;
  100.     slash               : CONSTANT bit_count_8_type := 16#2F# ; 
  101.     E                   : CONSTANT bit_count_8_type := 16#45# ; 
  102.     L                   : CONSTANT bit_count_8_type := 16#4C# ; 
  103.     B                   : CONSTANT bit_count_8_type := 16#42# ; 
  104.     A                   : CONSTANT bit_count_8_type := 16#41# ; 
  105.     D                   : CONSTANT bit_count_8_type := 16#44# ; 
  106.     bell                : CONSTANT bit_count_8_type := 16#07# ; 
  107.     cr                  : CONSTANT bit_count_8_type := 16#0D# ; 
  108.     lf                  : CONSTANT bit_count_8_type := 16#0A# ; 
  109.     not_control_char    : BOOLEAN := FALSE ;
  110.     BEGIN 
  111.       no_partial_command := user_data.no_partial_command ;
  112.       CASE char IS 
  113.         WHEN 247 | 248 => 
  114.           IF user_data.there_is_data_in_command_buffer THEN
  115.             user_data.get_command_buffer(command_buffer, length) ;
  116.             IF char = 247 THEN 
  117.               FOR index IN 1..length-1 LOOP 
  118.                 user_data.put_char_in_command_buffer(command_buffer(index)) ;
  119.               END LOOP ;
  120.               virtual_terminal.output_character_to_nvt_printer
  121.                (user_data.user_control_block.port, slash) ; 
  122.               virtual_terminal.output_character_to_nvt_printer
  123.                (user_data.user_control_block.port, command_buffer(length)) ;
  124.               virtual_terminal.output_character_to_nvt_printer
  125.                (user_data.user_control_block.port, slash) ;
  126.               length := length - 1 ;
  127.             ELSE 
  128.               virtual_terminal.output_character_to_nvt_printer
  129.                (user_data.user_control_block.port, slash) ;
  130.               virtual_terminal.output_character_to_nvt_printer
  131.                (user_data.user_control_block.port, E) ;
  132.               virtual_terminal.output_character_to_nvt_printer
  133.                (user_data.user_control_block.port, L) ;
  134.               virtual_terminal.output_character_to_nvt_printer
  135.                (user_data.user_control_block.port, slash) ;
  136.               virtual_terminal.output_character_to_nvt_printer
  137.                (user_data.user_control_block.port, cr) ;
  138.               virtual_terminal.output_character_to_nvt_printer
  139.                (user_data.user_control_block.port, lf) ;
  140.               length := 0 ;  
  141.             END IF ; 
  142.             IF length = 0 THEN 
  143.               user_data.user_control_block.command_state := 
  144.                no_partial_command ;
  145.             END IF ; 
  146.           END IF ; 
  147.         WHEN 242 | 243 | 244 | 245 | 246 | 249 => 
  148.           user_data.user_control_block.command_state := no_partial_command ;
  149.           virtual_terminal.output_character_to_nvt_printer
  150.                (user_data.user_control_block.port, B) ;
  151.           virtual_terminal.output_character_to_nvt_printer
  152.                (user_data.user_control_block.port, A) ;
  153.           virtual_terminal.output_character_to_nvt_printer
  154.                (user_data.user_control_block.port, D) ;
  155.           virtual_terminal.output_character_to_nvt_printer
  156.                (user_data.user_control_block.port, bell) ;
  157.           virtual_terminal.output_character_to_nvt_printer
  158.                (user_data.user_control_block.port, cr) ;
  159.           virtual_terminal.output_character_to_nvt_printer
  160.                (user_data.user_control_block.port, lf) ;
  161.         WHEN OTHERS => 
  162.           user_data.put_char_in_command_buffer(char) ;        
  163.       END CASE ; 
  164.   EXCEPTION
  165.     WHEN OTHERS =>
  166.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.add_char_to_pcb") ;
  167.       RAISE ;
  168.     END add_the_character_to_the_partial_command_buffer ;
  169.     PROCEDURE
  170.      parse_command_buffer_for_semantics_and_make_call_to_presentation_level
  171.      IS 
  172.     
  173.       command : user_data.out_string_type ;
  174.       SUBTYPE length_type IS bit_count_16_type  RANGE 1..user_data.max_cmd_length ; 
  175.       length : length_type ;
  176.       command_string : STRING (1..user_data.max_cmd_length) ;
  177.       successful : BOOLEAN ;
  178.       TYPE command_type IS (open_command, close_command, status_command,
  179.        reset_command, echo_local_command, echo_remote_command,
  180.        suppress_ga_local_command, suppress_ga_remote_command, 
  181.        send_abort_output_command, send_are_you_there_command,
  182.        send_break_command, send_erase_character_command,
  183.        send_erase_line_command, send_interrupt_process_command,
  184.        send_sync_command, quit_echo_local_command, quit_echo_remote_command,
  185.        quit_suppress_ga_local_command, quit_suppress_ga_remote_command,
  186.        bad_command) ;
  187.       type_of_command : command_type ;
  188.       not_urgent : BOOLEAN := FALSE ; 
  189.       urgent : BOOLEAN := TRUE ; 
  190.       command_bytes : virtual_transport_level.info_output_type(1..2) ; 
  191.       not_control_characters : BOOLEAN := FALSE ;
  192.       TYPE bytes_type IS ARRAY (bit_count_16_type RANGE <>) OF bit_count_8_type ;
  193.       address_length      : bit_count_16_type ;
  194.       network_number      : bit_count_16_type ; 
  195.       host_number         : bit_count_16_type ;
  196.       logical_host_number : bit_count_16_type ;
  197.       imp_number          : bit_count_16_type ;
  198.       port_number         : bit_count_16_type ;
  199.       PROCEDURE determine_command_type
  200.        (command_string_in  : IN STRING ;
  201.           length             : IN bit_count_16_type ;
  202.         type_of_command    : OUT command_type) IS 
  203.         command_string : STRING(1..length + 3) ; 
  204.         ok : BOOLEAN ;
  205.         PROCEDURE strip_off_extra_characters 
  206.          (item : IN OUT STRING ;
  207.               string_length : IN OUT bit_count_16_type) IS
  208.     kept_pos : bit_count_16_type RANGE 1..string_length + 3 := 1 ;
  209.           kept_buffer : STRING (1..string_length + 3) ; 
  210.           store_char : BOOLEAN := FALSE ;
  211.     adr_start_pos : bit_count_16_type RANGE 1..string_length ;
  212.           
  213.         BEGIN 
  214.           IF item(2) = 'O' OR item(2) = 'o' THEN 
  215.             kept_buffer(1..4) :="O   " ; 
  216.             kept_pos := 4 ;
  217.             FOR index IN 3..string_length LOOP  
  218.               IF item(index) = ' ' THEN 
  219.                 adr_start_pos := index + 1 ;
  220.                 EXIT ; 
  221.               END IF ;
  222.             END LOOP ; 
  223.             FOR index IN adr_start_pos..string_length LOOP 
  224.               kept_pos := kept_pos + 1 ;
  225.               kept_buffer(kept_pos) := item(index) ;
  226.             END LOOP ;
  227.             string_length := kept_pos ;
  228.           ELSE 
  229.             kept_buffer(1) := item(2) ; 
  230.             FOR item_pos IN 3..string_length LOOP
  231.               IF item(item_pos) = ' ' THEN 
  232.                 store_char := TRUE ;
  233.               ELSE 
  234.                 IF store_char THEN 
  235.                   kept_pos := kept_pos + 1 ;
  236.                   kept_buffer(kept_pos) := item(item_pos) ;
  237.                   store_char := FALSE ;
  238.                 END IF ; 
  239.               END IF ; 
  240.             END LOOP ; 
  241.             FOR pad_pos IN kept_pos+1..4 LOOP 
  242.                kept_pos := kept_pos + 1 ;
  243.                kept_buffer(pad_pos) := ' ' ;
  244.             END LOOP ; 
  245.             string_length := 0 ; 
  246.           END IF ; 
  247.           item(1..kept_pos) := kept_buffer(1..kept_pos) ;
  248.         EXCEPTION
  249.           WHEN OTHERS =>
  250.             debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.strip_ex") ;
  251.             RAISE ;
  252.         END strip_off_extra_characters ;
  253.         
  254.         PROCEDURE process_open_command_parameters IS
  255.           good_number : BOOLEAN ; 
  256.           PROCEDURE strip_command_to_address
  257.                     
  258.            (command_string : IN OUT STRING ;
  259.       address_length : IN OUT bit_count_16_type) IS
  260.             SUBTYPE string_position_type IS
  261.   bit_count_16_type RANGE 0..bit_count_16_type(user_data.max_cmd_length) ;
  262.             com_pos : string_position_type ;
  263.             
  264.       com_buf : STRING (1..user_data.max_cmd_length) ;
  265.             buf_pos : string_position_type := 0 ;
  266.           BEGIN 
  267.             FOR com_pos IN 2..address_length LOOP
  268.               IF command_string(com_pos) /= ' ' THEN 
  269.                 buf_pos := buf_pos + 1 ;
  270.                 com_buf(buf_pos) := command_string(com_pos) ;
  271.               END IF ;
  272.             END LOOP ;
  273.             command_string(1..buf_pos) := com_buf(1..buf_pos) ;
  274.             address_length := buf_pos ;
  275.           EXCEPTION
  276.             WHEN OTHERS =>
  277.               debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.strip_addr") ;
  278.               RAISE ;
  279.           END strip_command_to_address ;
  280.           PROCEDURE convert_string_to_integer 
  281.            (input_string  : IN  STRING ;
  282.             integer_value : OUT bit_count_16_type ;
  283.             status        : OUT BOOLEAN) IS 
  284.             next_value       : bit_count_16_type  := 0 ;
  285.             power_of_ten     : bit_count_16_type  := 1 ;
  286.             character_offset : bit_count_16_type  := CHARACTER'POS('0') ;
  287.             temp_integer_value : bit_count_16_type := 0 ;
  288.             temp_status : BOOLEAN := TRUE ;
  289.             
  290.           BEGIN
  291.             FOR index IN REVERSE INPUT_STRING'RANGE LOOP
  292.               IF (input_string(index)<'0') OR (input_string(index)>'9') THEN
  293.                 temp_status := FALSE ;
  294.               EXIT ; 
  295.               END IF ;
  296.               IF CHARACTER'POS(input_string(index))-character_offset = 0 THEN
  297.                 NULL ;
  298.               ELSIF power_of_ten >
  299.                 ((bit_count_16_type'LAST - temp_integer_value) /
  300.                  (CHARACTER'POS(input_string(index)) -
  301.                  character_offset)) THEN
  302.                 temp_status := FALSE ;
  303.                 EXIT ; 
  304.               ELSE
  305.                 temp_integer_value := temp_integer_value + 
  306.                  (CHARACTER'POS(input_string(index)) - 
  307.                  character_offset) * 
  308.                  power_of_ten ;
  309.               END IF ;
  310.               power_of_ten := power_of_ten * 10 ;
  311.             END LOOP ;
  312.             integer_value := temp_integer_value ;
  313.             status := temp_status ;
  314.           EXCEPTION
  315.             WHEN OTHERS =>
  316.               debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.conv_s_i") ;
  317.               RAISE ;
  318.           END convert_string_to_integer ;
  319.           PROCEDURE get_port_number 
  320.            (address    : IN     STRING ;
  321.       length     : IN OUT bit_count_16_type ;
  322.             status_ok  :    OUT BOOLEAN) IS
  323.           BEGIN 
  324.             port_number := 23 ; 
  325.             status_ok := TRUE ;
  326.             FOR index IN REVERSE 1..length LOOP
  327.               IF address(index) = ';' THEN 
  328.                 convert_string_to_integer(address(index+1..length),
  329.                  port_number, status_ok) ;
  330.                 length := index - 1 ; 
  331.                 EXIT ; 
  332.               END IF ; 
  333.             END LOOP ;
  334.           EXCEPTION
  335.             WHEN OTHERS =>
  336.               debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.get_port") ;
  337.               RAISE ;
  338.           END get_port_number ;
  339.  
  340.           PROCEDURE get_next_number 
  341.                     
  342.            (address   : IN     STRING ;
  343.       length    : IN OUT bit_count_16_type ;
  344.             number    :    OUT bit_count_16_type ;
  345.             ok        :    OUT BOOLEAN) IS
  346.             temp_number : bit_count_16_type ;
  347.             temp_ok : BOOLEAN ;
  348.             SUBTYPE string_position_type IS
  349.              bit_count_16_type RANGE 0..user_data.max_cmd_length ;
  350.       buf_pos : bit_count_16_type := 0 ;
  351.       num_buf : STRING (1..user_data.max_cmd_length) ;
  352.             delimiter : CHARACTER := '.' ;
  353.       delimiter_found : bit_count_16_type RANGE 0..1 := 0 ;
  354.       num_digits : bit_count_16_type RANGE 0..5 := 0 ;
  355.           BEGIN 
  356.             temp_ok := TRUE ;
  357.             FOR add_pos IN REVERSE 1..length LOOP 
  358.               IF address(add_pos) = delimiter THEN  
  359.                 delimiter_found := 1 ; 
  360.                 EXIT ; 
  361.               ELSE
  362.                 num_digits := num_digits + 1 ;
  363.               END IF ;
  364.             END LOOP ;
  365.             FOR add_pos IN length-num_digits+1..length LOOP 
  366.               buf_pos := buf_pos + 1 ;
  367.               num_buf(buf_pos) := address(add_pos) ;
  368.             END LOOP ;
  369.             IF num_digits /= 0 THEN
  370.               convert_string_to_integer(num_buf(1..num_digits), temp_number, temp_ok) ;
  371.             ELSE 
  372.               temp_number := 0 ;
  373.             END IF ;   
  374.             length := length - num_digits - delimiter_found ;
  375.             number := temp_number ;
  376.               ok := temp_ok ;
  377.           EXCEPTION
  378.             WHEN OTHERS =>
  379.               debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.get_num") ;
  380.               RAISE ;
  381.           END get_next_number ;
  382.           PROCEDURE get_imp_number
  383.            (address    : IN     STRING ;
  384.       length     : IN OUT bit_count_16_type ;
  385.             status_ok  :    OUT BOOLEAN) IS 
  386.           
  387.             temp_status_ok : BOOLEAN ;
  388.    
  389.           BEGIN 
  390.             get_next_number(address, length, imp_number, temp_status_ok) ;
  391.             IF imp_number = 0 THEN 
  392.               temp_status_ok := FALSE ;
  393.             END IF ;
  394.             status_ok := temp_status_ok ;
  395.           EXCEPTION
  396.             WHEN OTHERS =>
  397.               debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.get_imp") ;
  398.               RAISE ;
  399.          END get_imp_number ;
  400.  
  401.  
  402.           PROCEDURE get_logical_host_number
  403.            (address    : IN OUT STRING ;
  404.       length     : IN OUT bit_count_16_type ;
  405.             status_ok  :    OUT BOOLEAN) IS 
  406.              temp_status_ok : BOOLEAN ;
  407.           BEGIN 
  408.             get_next_number
  409.              (address, length, logical_host_number, temp_status_ok) ;
  410.             status_ok := temp_status_ok ;
  411.           EXCEPTION
  412.             WHEN OTHERS =>
  413.               debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.get_lhost") ;
  414.               RAISE ;
  415.           END get_logical_host_number ;
  416.  
  417.  
  418.           PROCEDURE get_host_number
  419.            (address    : IN OUT STRING ;
  420.       length     : IN OUT bit_count_16_type ;
  421.             status_ok  :    OUT BOOLEAN) IS 
  422.             temp_status_ok : BOOLEAN ;
  423.           BEGIN 
  424.             get_next_number(address, length, host_number, temp_status_ok) ;
  425.             status_ok := temp_status_ok ;
  426.           EXCEPTION
  427.             WHEN OTHERS =>
  428.               debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.get_host") ;
  429.               RAISE ;
  430.           END get_host_number ;
  431.  
  432.  
  433.           PROCEDURE get_network_number
  434.            (address    : IN OUT STRING ;
  435.       length     : IN OUT bit_count_16_type ;
  436.             status_ok  :    OUT BOOLEAN) IS 
  437.             temp_status_ok : BOOLEAN ;
  438.           BEGIN 
  439.             get_next_number(address, length, network_number, temp_status_ok) ;
  440.             IF network_number = 0 THEN 
  441.               network_number := 10 ; 
  442.             END IF ;
  443.             status_ok := temp_status_ok ;
  444.           EXCEPTION
  445.             WHEN OTHERS =>
  446.               debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.get_net") ;
  447.               RAISE ;
  448.           END get_network_number ;
  449.  
  450.         BEGIN 
  451.           strip_command_to_address(command_string(1..address_length),
  452.            address_length) ;
  453.           get_port_number(command_string, address_length, ok) ;
  454.           IF ok THEN
  455.             get_imp_number(command_string(1..address_length),
  456.              address_length, ok) ;
  457.           IF ok THEN
  458.             get_logical_host_number(command_string(1..address_length),
  459.              address_length, ok) ;
  460.           IF ok THEN
  461.             get_host_number(command_string, address_length, ok) ;
  462.           IF ok THEN
  463.             get_network_number(command_string, address_length, ok) ;
  464.           END IF ; END IF ; END IF ; END IF ;
  465.           IF NOT (ok) THEN 
  466.             type_of_command := bad_command ;
  467.           END IF ;
  468.         EXCEPTION
  469.           WHEN OTHERS =>
  470.             debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.pr_open_cmd_par") ;
  471.             RAISE ;
  472.        END process_open_command_parameters ;
  473.       
  474.       BEGIN 
  475.         command_string(1..length) := command_string_in(1..length) ;
  476.         address_length := length ; 
  477.         strip_off_extra_characters(command_string(1..length+3),
  478.          address_length) ; 
  479.         IF    command_string(1..4) = "O   " THEN
  480.           type_of_command := open_command ;
  481.           process_open_command_parameters ;
  482.         ELSIF command_string(1..4) = "C   " OR command_string(1..4)="c   " THEN
  483.           type_of_command := close_command ;
  484.         ELSIF command_string(1..4) = "S   " OR command_string(1..4)="s   " THEN
  485.           type_of_command := status_command ;
  486.         ELSIF command_string(1..4) = "R   " OR command_string(1..4)="r   " THEN
  487.           type_of_command := reset_command ;
  488.         ELSIF command_string(1..4) = "EL  " OR command_string(1..4)="el  " THEN
  489.           type_of_command := echo_local_command ;
  490.         ELSIF command_string(1..4) = "ER  " OR command_string(1..4)="er  " THEN
  491.           type_of_command := echo_remote_command ;
  492.         ELSIF command_string(1..4) = "QEL " OR command_string(1..4)="qel " THEN
  493.           type_of_command := quit_echo_local_command ;
  494.         ELSIF command_string(1..4) = "QER " OR command_string(1..4)="qer " THEN
  495.           type_of_command := quit_echo_remote_command ;
  496.         ELSIF command_string(1..4) = "SGL " OR command_string(1..4)="sgl " THEN
  497.           type_of_command := suppress_ga_local_command ;
  498.         ELSIF command_string(1..4) = "SGR " OR command_string(1..4)="sgr " THEN
  499.           type_of_command := suppress_ga_remote_command ;
  500.         ELSIF command_string(1..4) = "QSGL" OR command_string(1..4)="qsgl" THEN
  501.           type_of_command := quit_suppress_ga_local_command ;
  502.         ELSIF command_string(1..4) = "QSGR" OR command_string(1..4)="qsgr" THEN
  503.           type_of_command := quit_suppress_ga_remote_command ;
  504.         ELSIF command_string(1..4) = "SAO " OR command_string(1..4)="sao " THEN
  505.           type_of_command := send_abort_output_command ;
  506.         ELSIF command_string(1..4) = "SAYT" OR command_string(1..4)="sayt" THEN
  507.           type_of_command := send_are_you_there_command ;
  508.         ELSIF command_string(1..4) = "SB  " OR command_string(1..4)="sb  " THEN
  509.           type_of_command := send_break_command ;
  510.         ELSIF command_string(1..4) = "SEC " OR command_string(1..4)="sec " THEN
  511.           type_of_command := send_erase_character_command ;
  512.         ELSIF command_string(1..4) = "SEL " OR command_string(1..4)="sel " THEN
  513.           type_of_command := send_erase_line_command ;
  514.         ELSIF command_string(1..4) = "SIP " OR command_string(1..4)="sip " THEN
  515.           type_of_command := send_interrupt_process_command ;
  516.         ELSIF command_string(1..4) = "SS  " OR command_string(1..4)="ss  " THEN
  517.           type_of_command := send_sync_command ;
  518.         ELSE
  519.           type_of_command := bad_command ;
  520.         END IF ;
  521.       EXCEPTION
  522.         WHEN OTHERS =>
  523.           debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.deter_cmd_type") ;
  524.           RAISE ;
  525.       END determine_command_type ;
  526.       PROCEDURE convert_string_to_byte
  527.        (item  : IN  STRING ;
  528.         bytes : OUT bytes_type) IS
  529.       BEGIN
  530.         FOR index IN 1..item'length LOOP
  531.           bytes(bit_count_16_type(index)) := bit_count_8_type(CHARACTER'POS(item(index))) ;
  532.         END LOOP ;
  533.       END convert_string_to_byte ;
  534.       PROCEDURE convert_user_data_bytes_to_string
  535.        (bytes  : IN     user_data.out_string_type ;
  536.         str    :    OUT STRING ; 
  537.         length : IN     bit_count_16_type ;
  538.         ok     :    OUT BOOLEAN) IS
  539.       BEGIN
  540.         ok := TRUE ;
  541.         FOR index IN 1..length LOOP
  542.           IF bytes(index) > 16#7F# THEN 
  543.             ok := FALSE ;
  544.             EXIT ; 
  545.           END IF ;
  546.     str(index) := CHARACTER'VAL(bytes(index)) ;
  547.         END LOOP ;
  548.       END convert_user_data_bytes_to_string ;
  549.     BEGIN 
  550.       user_data.get_command_buffer(command, length) ;
  551.       convert_user_data_bytes_to_string
  552.        (command, command_string, length, successful) ;
  553.       IF successful THEN 
  554.   determine_command_type(command_string, length, type_of_command) ;
  555.       ELSE
  556.         type_of_command := bad_command ;
  557.       END IF ; 
  558.       CASE type_of_command IS
  559.         WHEN open_command =>
  560.           DECLARE
  561.             parameter : virtual_transport_level.service_call_parameters_type
  562.              (virtual_transport_level.TL_open) ;
  563.           BEGIN
  564.             parameter.network_number := network_number ;
  565.             parameter.host_number := host_number ;
  566.             parameter.logical_host_number := logical_host_number ;
  567.             parameter.imp_number := imp_number ;
  568.             parameter.port_number := port_number ;
  569.             virtual_transport_level.convert_service_call_to_transport_level_syntax
  570.              (virtual_transport_level.TL_open, parameter) ;
  571.           END ; 
  572.         WHEN close_command =>
  573.           DECLARE
  574.             parameter : virtual_transport_level.service_call_parameters_type
  575.              (virtual_transport_level.TL_close) ;
  576.           BEGIN
  577.             virtual_transport_level.convert_service_call_to_transport_level_syntax 
  578.              (virtual_transport_level.TL_close, parameter) ;
  579.           END ; 
  580.         WHEN status_command =>
  581.           DECLARE
  582.             parameter : virtual_transport_level.service_call_parameters_type
  583.              (virtual_transport_level.TL_status) ;
  584.           BEGIN
  585.             virtual_transport_level.convert_service_call_to_transport_level_syntax 
  586.              (virtual_transport_level.TL_status, parameter) ;
  587.           END ; 
  588.         WHEN reset_command =>
  589.           DECLARE
  590.             parameter : virtual_transport_level.service_call_parameters_type
  591.              (virtual_transport_level.TL_abort) ;
  592.           BEGIN
  593.             virtual_transport_level.convert_service_call_to_transport_level_syntax 
  594.              (virtual_transport_level.TL_abort, parameter) ;
  595.           END ; 
  596.         WHEN echo_local_command =>
  597.             option_negotiation.request_local_option_enable(user_data.echo) ;
  598.         WHEN echo_remote_command =>
  599.             option_negotiation.request_remote_option_enable(user_data.echo) ;
  600.         WHEN quit_echo_local_command =>
  601.             option_negotiation.demand_local_option_disable(user_data.echo) ;
  602.         WHEN quit_echo_remote_command =>
  603.             option_negotiation.demand_remote_option_disable(user_data.echo) ;
  604.         WHEN suppress_ga_local_command =>
  605.             option_negotiation.request_local_option_enable(user_data.suppress_ga) ;
  606.         WHEN suppress_ga_remote_command =>
  607.             option_negotiation.request_remote_option_enable(user_data.suppress_ga) ;
  608.         WHEN quit_suppress_ga_local_command =>
  609.             option_negotiation.demand_local_option_disable(user_data.suppress_ga) ;
  610.         WHEN quit_suppress_ga_remote_command =>
  611.             option_negotiation.demand_remote_option_disable(user_data.suppress_ga) ;
  612.         WHEN send_abort_output_command =>
  613.           command_bytes(1) := 255 ; 
  614.           command_bytes(2) := 245 ;
  615.           virtual_transport_level.send_data(command_bytes, not_urgent) ;
  616.         WHEN send_are_you_there_command =>
  617.           command_bytes(1) := 255 ; 
  618.           command_bytes(2) := 246 ;
  619.           virtual_transport_level.send_data(command_bytes, not_urgent) ;
  620.         WHEN send_break_command =>
  621.           command_bytes(1) := 255 ; 
  622.           command_bytes(2) := 243 ;
  623.           virtual_transport_level.send_data(command_bytes, not_urgent) ;
  624.         WHEN send_erase_character_command =>
  625.           command_bytes(1) := 255 ; 
  626.           command_bytes(2) := 247 ;
  627.           virtual_transport_level.send_data(command_bytes, not_urgent) ;
  628.         WHEN send_erase_line_command =>
  629.           command_bytes(1) := 255 ; 
  630.           command_bytes(2) := 248 ;
  631.           virtual_transport_level.send_data(command_bytes, not_urgent) ;
  632.         WHEN send_interrupt_process_command =>
  633.           command_bytes(1) := 255 ; 
  634.           command_bytes(2) := 244 ;
  635.           virtual_transport_level.send_data(command_bytes, not_urgent) ;
  636.         WHEN send_sync_command =>
  637.           command_bytes(1) := 255 ; 
  638.           command_bytes(2) := 242 ; 
  639.                                     
  640.           virtual_transport_level.send_data(command_bytes, urgent) ;
  641.         WHEN bad_command =>
  642.           DECLARE 
  643.             bad_message : STRING (1..6) ;
  644.             bytes : bytes_type(1..6) ;
  645.             not_control_characters : BOOLEAN := FALSE ;
  646.           BEGIN
  647.             bad_message(1..3) := "bad" ;
  648.             bad_message(4) := ascii.bel ;
  649.             bad_message(5) := ascii.cr ;
  650.             bad_message(6) := ascii.lf ;
  651.             convert_string_to_byte(bad_message, bytes) ;
  652.             FOR index IN 1..6 LOOP
  653.               virtual_terminal.output_character_to_nvt_printer
  654.                (user_data.user_control_block.port, bytes(bit_count_16_type(index))) ;
  655.             END LOOP ;
  656.           END ; 
  657.       END CASE ;
  658.     EXCEPTION
  659.       WHEN OTHERS =>
  660.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.parse_cmd") ;
  661.         RAISE ;
  662.     END parse_command_buffer_for_semantics_and_make_call_to_presentation_level ;
  663.     FUNCTION char_not_end_of_line
  664.      RETURN BOOLEAN IS 
  665.       end_of_line : character_type := 16#0D# ; 
  666.     BEGIN
  667.       RETURN char /= end_of_line ; 
  668.     END char_not_end_of_line ;
  669.   BEGIN 
  670.     IF char_not_end_of_line THEN 
  671.       add_the_character_to_the_partial_command_buffer(char);
  672.     ELSE
  673.       parse_command_buffer_for_semantics_and_make_call_to_presentation_level ;
  674.       user_data.user_control_block.command_state := 
  675.        user_data.no_partial_command ;
  676.     END IF ; 
  677.   EXCEPTION
  678.     WHEN OTHERS =>
  679.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.proc_par_cmd") ;
  680.       RAISE ;
  681.   END process_partial_command ;
  682.   PROCEDURE put_character_in_data_buffer
  683.    (char : IN character_type) IS
  684.   BEGIN
  685.     IF user_data.there_is_room_in_data_buffer THEN
  686.       user_data.put_char_in_data_buffer(char) ;
  687.     ELSE 
  688.       NULL ; 
  689.     END IF ;
  690.   EXCEPTION
  691.     WHEN OTHERS =>
  692.        debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.put_char_dat_buf") ;
  693.        RAISE ;
  694.   END put_character_in_data_buffer ;
  695.   PROCEDURE send_data_buffer_to_transport_level IS
  696.     apl_buffer : user_data.out_string_type ;
  697.     ppl_buffer : virtual_transport_level.info_output_type
  698.      (1..user_data.max_out_string) ;
  699.     length : bit_count_16_type RANGE 1..user_data.max_out_string ;
  700.     not_urgent_data : BOOLEAN := FALSE ;
  701.   BEGIN
  702.     user_data.user_control_block.ga_received := FALSE ;
  703.     user_data.get_data_buffer(apl_buffer, length) ;
  704.     FOR index IN 1..length LOOP 
  705.       ppl_buffer(index) := apl_buffer(index) ;
  706.     END LOOP ;
  707.     virtual_transport_level.send_data
  708.      (ppl_buffer(1..length), not_urgent_data) ;
  709.   EXCEPTION
  710.     WHEN OTHERS =>
  711.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.") ;
  712.       RAISE ;
  713.   END send_data_buffer_to_transport_level ;
  714. BEGIN 
  715.   NULL ;
  716. EXCEPTION
  717.   WHEN OTHERS =>
  718.     debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac instantition") ;
  719.     RAISE ;
  720. END nvt_keyboard_input_processing ; 
  721. --::::::::::::::
  722. --amesspac.txt
  723. --::::::::::::::
  724. -----------------------------------------------------------------------
  725. --
  726. --         DoD Protocols    NA-00009-200       80-01204-100(-)
  727. --         E-Systems, Inc.  August 07, 1985
  728. --
  729. --         amesspac.txt       Author : Mike Thomas
  730. --
  731. -----------------------------------------------------------------------
  732. -- File : amesspac
  733. --   5/8/85  8:50 AM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS 
  734. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  735. --  7/16/85 11:15 AM : convert to telesoft for wicat 
  736. WITH SYSTEM ; -- to gain access to system.byte
  737. WITH virtual_transport_level ;
  738. WITH virtual_terminal ;
  739. WITH user_data ; -- access the port_number
  740. PACKAGE message_processing -- specfication
  741.         ------------------
  742.  IS
  743. -- **********************  USER SPECIFICATION  ********************************
  744. --
  745. -- This package provides data types and subprograms for processing (at
  746. -- the APL level)  messages from the transport level to TELNET for a
  747. -- particular user. A message being information which originated at the
  748. -- local transport level, not simply data being relayed from the remote
  749. -- TELNET.  This information is given higher priority than simple
  750. -- data transfer.
  751. --
  752. -- ****************************************************************************
  753.       SUBTYPE bit_count_16_type IS INTEGER ; 
  754.   --&MT SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  755.   max_msg_length : CONSTANT bit_count_16_type := 
  756.    virtual_transport_level.max_msg_length ;
  757. -- make a deferred constant when supported
  758.   SUBTYPE message_from_transport_level_type IS 
  759.    virtual_transport_level.message_type ;
  760. -- Telelie ADA does not support limited private subtpes ;
  761.   FUNCTION there_is_a_message_available -- specification
  762.            ----------------------------
  763.    RETURN BOOLEAN ;
  764.     -- ************************  USER SPECIFICATION  ****************************
  765.   --
  766.   -- This function returns true if there is a message available from the
  767.   -- transport level. 
  768.   -----------------------------------------------------------------------------
  769.     
  770.   PROCEDURE retrieve_message -- specification
  771.             ----------------
  772.    (message : OUT message_from_transport_level_type ;
  773.     length  : OUT bit_count_16_type) ;
  774.   -- ************************  USER SPECIFICATION  ****************************
  775.   -- 
  776.   -- This procedure gets an entire message from the transport level.
  777.   -----------------------------------------------------------------------------
  778.       
  779.   
  780.   PROCEDURE write_message_to_NVT_printer -- specification
  781.             ----------------------------
  782.    (transport_level_message : IN message_from_transport_level_type ; 
  783.     length                  : IN bit_count_16_type) ;
  784.   -- ************************  USER SPECIFICATION  ****************************
  785.   -- 
  786.   -- This procedure writes an entire message from the transport level
  787.   -- to the NVT printer.
  788.   -----------------------------------------------------------------------------
  789. END message_processing ; -- package specification
  790. -- File : amesspac
  791. --   5/8/85  9:10 AM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS 
  792. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  793. WITH debug_io ;
  794. PACKAGE BODY message_processing IS
  795.              ------------------
  796.   FUNCTION there_is_a_message_available -- body
  797.            ----------------------------
  798.    RETURN BOOLEAN IS 
  799.   BEGIN
  800.     RETURN virtual_transport_level.there_is_a_message ;
  801.   EXCEPTION
  802.     WHEN OTHERS =>
  803.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN amesspac.there_is_msg") ;
  804.       RAISE ;
  805.   END there_is_a_message_available ; -- function body
  806.     
  807.   PROCEDURE retrieve_message -- body
  808.             ----------------
  809.    (message : OUT message_from_transport_level_type ;
  810.     length  : OUT bit_count_16_type) IS 
  811.   BEGIN
  812.     IF virtual_transport_level.there_is_a_message THEN
  813.       virtual_transport_level.get_message(message, length) ;
  814.     ELSE -- error
  815.       length := 0 ; -- no message available, erronious call
  816.     END IF ;     
  817.   EXCEPTION
  818.     WHEN OTHERS =>
  819.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN amesspac.retr_msg") ;
  820.       RAISE ;
  821.   END retrieve_message ; -- procedure body
  822.       
  823.       
  824.   PROCEDURE write_message_to_NVT_printer -- body
  825.             ----------------------------
  826.    (transport_level_message : IN message_from_transport_level_type ;
  827.     length  : IN bit_count_16_type) IS
  828.   BEGIN
  829.     FOR index IN 1..length LOOP 
  830.       virtual_terminal.output_character_to_nvt_printer
  831.        (user_data.user_control_block.port, transport_level_message(index)) ;
  832.     END LOOP ;      
  833.   EXCEPTION
  834.     WHEN OTHERS =>
  835.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN amesspac.write_msg_nvt") ;
  836.       RAISE ;
  837.   END write_message_to_NVT_printer ; -- procedure body
  838. BEGIN
  839.   NULL ;
  840. EXCEPTION
  841.   WHEN OTHERS =>
  842.     debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN amesspac instantiation") ;
  843.     RAISE ;
  844. END message_processing ; -- package body
  845. --::::::::::::::
  846. --aplpac.txt
  847. --::::::::::::::
  848. -----------------------------------------------------------------------
  849. --
  850. --         DoD Protocols    NA-00009-200       80-01205-100(-)
  851. --         E-Systems, Inc.  August 07, 1985
  852. --
  853. --         aplpac.txt       Author : Mike Thomas
  854. --
  855. -----------------------------------------------------------------------
  856. -- File : aplpac       AUTHOR : MIKE THOMAS
  857. --   5/9/85  1:20 PM : MODIFY FOR DEC ADA 
  858. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  859. --  7/16/85 11:29 AM : modify for telesoft to run on wicat
  860. PACKAGE telnet_apl -- specification
  861.         ----------
  862.  IS
  863. --************************  USER SPECIFICATION  ******************************
  864. --
  865. --                     TELNET APPLICATION PROTOCOL LEVEL SPECIFICATION
  866. --
  867. -- The Application Protocol Level (APL)... [1]
  868. --
  869. --   * defines the semantics for information exchange; [2]
  870. --   * provides network transparency; [3]
  871. --   * and partitions the problem into high level functional areas : [4]
  872. --     : read/write characters from/to the Network Virtual Terminal (NVT)
  873. --       via the Presentation Protocol Level (PPL),
  874. --     : handle standard control functions (ip, ao, ayt, ec, and el),
  875. --     : perform command parsing,
  876. --     : pass the commands to the Presentation Protocol Level (PPL) for
  877. --       submission to the transport level protocol,
  878. --     : receive responses/messages from the transport level protocol via the
  879. --       Presentation Protocol Level (PPL).
  880. --
  881. -- SPECIFICATION REFERENCES:
  882. --
  883. --      DOD Protocol Reference Model (contract DCA 100-82-C-0036  2-Dec-83)
  884. --
  885. --        [1] section 4.1.1
  886. --        [2] section 4.1.1.1
  887. --        [3] section 4.1.1.2
  888. --        [4] section 4.1.1.3
  889. --
  890. -----------------------------------------------------------------------------
  891. -- **************************************************************************
  892. --
  893. -- This package performs the TELNET application protocol level(APL) processing
  894. -- and imports procedures to access the TELNET presentation protocol 
  895. -- level(PPL).  This package is responsible for the semantics of the user 
  896. -- information exchange and uses the virtual resources provided for by the PPL
  897. -- to access the network virtual terminal(NVT) and virtual transport level.
  898. -- For example, this level could access the NVT to get user/process input
  899. -- to TELNET; determine that it was a proper TELNET command to open a new
  900. -- connection and call upon the virtual transport level to establish the
  901. -- new connection.  If the real world terminal type were to change or the
  902. -- transport level's actual implementation were changed, this would have no
  903. -- effect on the APL.
  904. --
  905. -- ****************************************************************************
  906.   PROCEDURE process_any_input_from_the_nvt_keyboard ; -- specification
  907.   -- ************************  USER SPECIFICATION  ****************************
  908.   -- 
  909.   -- This procedure will input and process one character from the NVT 
  910.   -- keyboard if one is available.
  911.   -----------------------------------------------------------------------------
  912.   PROCEDURE process_any_messages_from_the_transport_level ; -- specification
  913.   -- ************************  USER SPECIFICATION  ****************************
  914.   -- 
  915.   -- This procedure will input and process one entire message from the 
  916.   -- transport level if a message is available.  A message being information 
  917.   -- for the local user/process which was generated by the local transport 
  918.   -- level, not simply data being relayed from the remote TELNET.
  919.   -----------------------------------------------------------------------------
  920.   PROCEDURE process_any_input_from_the_transport_level ; -- specification
  921.   -- ************************  USER SPECIFICATION  ****************************
  922.   -- 
  923.   -- This procedure will input and process one character from the 
  924.   -- transport level which was relayed from the remote TELNET if it is
  925.   -- available.
  926.   -----------------------------------------------------------------------------
  927.   PROCEDURE transmit_telnet_go_ahead ; -- specification
  928.   -- ************************  USER SPECIFICATION  ****************************
  929.   -- 
  930.   -- This procedure will send the TELNET GA signal to the remote TELNET.
  931.   -----------------------------------------------------------------------------
  932.  
  933. END telnet_apl ; -- package specification 
  934. -- File : aplpac       AUTHOR : MIKE THOMAS
  935. --    5/9/85  1:25 PM : MODIFY FOR DEC ADA            
  936. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  937. --   6/23/85  9:00 PM : set ga_state := no_ga_sent if there is input from tcp
  938. --   6/24/85 10:19 AM : move set go_ahead to not control func part of if stm
  939. --  7/16/85 11:29 AM : modify for telesoft to run on wicat
  940. WITH nvt_keyboard_input_processing ; -- procedures used in 
  941. USE  nvt_keyboard_input_processing ; -- process_any_input_from_the_nvt_keyboard
  942. WITH message_processing ; -- procedures/data/types used in
  943. USE  message_processing ; -- process_any_messages_from_the_transport_level
  944. WITH transport_level_input_processing ; -- procedures used in
  945. USE  transport_level_input_processing ; -- process_any_input_from_the_transport_level
  946.  
  947. WITH user_data ; -- state information, user buffers, and data types
  948. USE  user_data ;
  949. WITH virtual_terminal ; -- for local character echoing
  950. WITH virtual_transport_level ; -- to send telnet go ahead, echo data to remote
  951. WITH SYSTEM ; -- for access to system.byte
  952. WITH debug_io ;
  953. PACKAGE BODY telnet_apl IS
  954.              ----------
  955. SUBTYPE bit_count_16_type IS INTEGER ; 
  956.   --&MT SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  957. SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  958.   --&MT SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  959.   PROCEDURE process_any_input_from_the_nvt_keyboard -- body
  960.             ---------------------------------------
  961.    IS
  962.   -- *********************  BODY SPECIFICATION  *******************************
  963.   --
  964.   -- Processing sequence :
  965.   --
  966.   -- While there is input to process...
  967.   -- If there is input from the NVT keyboard, get a character.   Set the
  968.   -- NVT I/O state as I/O-done.  If the character was a standard control
  969.   -- function, process the standard control function.  If the character was
  970.   -- not a control function then process it as follows.  If the
  971.   -- communication state is no-connection-established or the command state
  972.   -- is partial-command or a new command was detected then set the NVT I/O
  973.   -- state as partial-command and process a partial command.  Otherwise the
  974.   -- input is data so put the character in the data buffer until an end of
  975.   -- line is detected and then send it through to the transport level. 
  976.   ----------------------------  data declarations  ---------------------------
  977.     char : bit_count_8_type ;
  978.     end_of_line : CONSTANT bit_count_8_type := 16#0D# ; -- ASCII.CR 
  979.     TYPE control_function IS (ip, ao, ayt, ec, el) ;
  980.     the_char_was_a_control_function : BOOLEAN ; 
  981.     standard_control_function : control_function ;
  982.     at_char : CONSTANT bit_count_8_type := 16#40# ; -- ascii '@' (command character)
  983.     last_char_was_an_at : BOOLEAN RENAMES
  984.      user_control_block.last_keybd_char_was_cmd ;
  985.   -------------------------  local procedure declarations  --------------------
  986.     PROCEDURE check_for_local_printing (char : IN bit_count_8_type) IS
  987.               ------------------------
  988.       remote_options_in_effect : user_data.option_table_type
  989.        RENAMES user_control_block.option_tables.remote_options_in_effect ;
  990.       echo_local : BOOLEAN := TRUE ;
  991.     BEGIN
  992.       FOR index IN 1..remote_options_in_effect.number_of_items LOOP
  993.         IF remote_options_in_effect.option(index) = user_data.echo THEN
  994.           echo_local := FALSE ;
  995.           EXIT ;
  996.         END IF ;
  997.       END LOOP ;
  998.       IF echo_local THEN
  999.         virtual_terminal.output_character_to_nvt_printer
  1000.          (user_data.user_control_block.port, char) ;
  1001.       END IF ;
  1002.     EXCEPTION
  1003.       WHEN OTHERS =>
  1004.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN aplpac.check_loc_print") ;
  1005.         RAISE ;
  1006.     END check_for_local_printing ;
  1007.     FUNCTION time_to_transmit (char : IN bit_count_8_type) RETURN BOOLEAN IS 
  1008.              ----------------
  1009.     -- *************************  SPECIFICATION  ******************************
  1010.     -- This function returns true if it is time to transmit the characters
  1011.     -- which were typed into the keyboard and are to be sent to the remote
  1012.     -- TELNET connection.  In the default NVT options, this would be at the
  1013.     -- end of a line.[1]  Other options in effect (such as remote ECHO) may
  1014.     -- be criteria for character-at-a-time as appossed to line-at-a-time
  1015.     -- transmissions.[2]  
  1016.     -- 
  1017.     -- SPECIFICATION REFERENCES :
  1018.     --    [1] Network Working Group Request For Comments : 854, May 1983
  1019.     --        (page 5, default condition 1)
  1020.     --    [2] Network Working Group Request For Comments : 857, May 1983
  1021.     --        (page 3, paragraph 1)
  1022.     ---------------------------------------------------------------------------
  1023.  
  1024.       transmit_time : BOOLEAN := FALSE ;
  1025.       remote_options_in_effect : user_data.option_table_type 
  1026.        RENAMES user_control_block.option_tables.remote_options_in_effect ;
  1027.       local_options_in_effect : user_data.option_table_type 
  1028.        RENAMES user_control_block.option_tables.local_options_in_effect ;
  1029.       remote_options_pending : user_data.option_table_type
  1030.        RENAMES user_control_block.option_tables.remote_options_pending ;
  1031.       local_options_pending : user_data.option_table_type
  1032.        RENAMES user_control_block.option_tables.local_options_pending ;
  1033.       FUNCTION option_in_table
  1034.                ---------------
  1035.        (table  : IN user_data.option_table_type ;
  1036.         option : IN user_data.option_type) RETURN BOOLEAN IS
  1037.       BEGIN
  1038.         FOR index IN 1..table.number_of_items LOOP
  1039.           IF table.option(index) = option THEN
  1040.             RETURN TRUE ;
  1041.           END IF ;
  1042.         END LOOP ;
  1043.         RETURN FALSE ;
  1044.       END option_in_table ;
  1045.     BEGIN 
  1046.       IF user_data.user_control_block.ga_received OR
  1047.        option_in_table(remote_options_in_effect, suppress_ga) THEN
  1048.         IF bit_count_16_type(char) = bit_count_16_type(end_of_line) AND THEN
  1049.          (remote_options_pending.number_of_items = 0 AND
  1050.          local_options_pending.number_of_items = 0) THEN
  1051.           transmit_time := TRUE ; -- end of line, no option negotiation pending
  1052.         ELSE -- not end of line
  1053.           IF option_in_table(remote_options_in_effect, suppress_ga) AND
  1054.            option_in_table(local_options_in_effect, suppress_ga) THEN
  1055.             IF option_in_table(remote_options_in_effect, echo) OR
  1056.              option_in_table(local_options_in_effect, echo) THEN
  1057.               transmit_time := TRUE ; -- suppress_ga & echo ==> character at a time mode
  1058.             END IF ; -- echo?
  1059.           END IF ; -- suppress_ga?
  1060.         END IF ; -- end of line?
  1061.       END IF ; -- ga_received?
  1062.       RETURN transmit_time ;
  1063.     EXCEPTION
  1064.       WHEN OTHERS =>
  1065.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN aplpac.time_to_trans") ;
  1066.         RAISE ;
  1067.     END time_to_transmit ;
  1068.      
  1069.     PROCEDURE process_data_character(char : IN bit_count_8_type) IS
  1070.               ----------------------
  1071.     BEGIN
  1072.       debug_io.put_line("putting character in data buffer") ;
  1073.       put_character_in_data_buffer(char) ;
  1074.       IF bit_count_16_type(char) = bit_count_16_type(255) THEN -- double IAC on send to indecate a data byte 255
  1075.         put_character_in_data_buffer(char) ;
  1076.       END IF ;
  1077.       IF time_to_transmit(char) THEN 
  1078.         debug_io.put_line("sending data buffer to trans level") ;
  1079.         send_data_buffer_to_transport_level ;
  1080.       END IF ; -- transmit buffer?
  1081.     EXCEPTION
  1082.       WHEN OTHERS =>
  1083.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN aplpac.proc_data_char") ;
  1084.         RAISE ;
  1085.     END process_data_character ;
  1086.   BEGIN -- process keyboard input
  1087.     debug_io.put_line("begin process keyboard input") ;
  1088.     IF there_is_input_from_the_NVT_keyboard THEN
  1089.       WHILE there_is_input_from_the_NVT_keyboard LOOP
  1090.         debug_io.put_line("apl process keyboard input thinks there is input") ;
  1091.         get_a_character(char, the_char_was_a_control_function);
  1092.         check_for_local_printing(char) ;
  1093.         user_control_block.NVT_IO_state := IO_done ;
  1094.         IF the_char_was_a_control_function THEN 
  1095.           debug_io.put_line("will process control function...") ;
  1096.           process_standard_control_function_from_keyboard(char) ;
  1097.         ELSE -- not control function 
  1098.           debug_io.put_line("character not a control function") ;
  1099.           IF user_control_block.communication_state = 
  1100.            no_connection_established OR 
  1101.            user_control_block.command_state = partial_command THEN
  1102.             debug_io.put_line("current character is part of partial command") ;
  1103.             user_control_block.command_state := partial_command ;
  1104.             process_partial_command(char) ;
  1105.           ELSE -- data
  1106.             debug_io.put_line("current character is data") ;
  1107.             IF last_char_was_an_at THEN
  1108.               IF bit_count_16_type(char) = bit_count_16_type(at_char) THEN -- put at #2 in data buf
  1109.                 process_data_character(char) ;
  1110.                 last_char_was_an_at := FALSE ;
  1111.               ELSE -- new command detected
  1112.                 user_control_block.command_state := partial_command ;
  1113.                 process_partial_command(at_char) ;
  1114.                 process_partial_command(char) ;
  1115.                 last_char_was_an_at := FALSE ;
  1116.               END IF ; -- char=at?
  1117.             ELSE -- last char /= at
  1118.               IF bit_count_16_type(char) = bit_count_16_type(at_char) THEN 
  1119.                 last_char_was_an_at := TRUE ;
  1120.               ELSE -- niether last char nor this char = at
  1121.                 process_data_character(char) ;
  1122.               END IF ; -- transmit buffer?
  1123.             END IF ; -- last_char_was_an_at?
  1124.           END IF ; -- command?
  1125.         END IF ; -- control function?
  1126.       END LOOP ; -- input from keyboard?
  1127.     ELSE -- no input from keyboard, chack for send of buffered input
  1128.          -- due to pending option negotiation and/or go ahead processing
  1129.       IF user_data.there_is_data_in_data_buffer AND time_to_transmit(0) THEN
  1130.         send_data_buffer_to_transport_level ;
  1131.       END IF ; -- send buffered data?
  1132.     END IF ; -- keyboard input available?
  1133.     debug_io.put_line("end process keyboard input") ;
  1134.   EXCEPTION
  1135.     WHEN OTHERS =>
  1136.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN aplpac.proc_any_keybd_input") ;
  1137.       RAISE ;
  1138.   END process_any_input_from_the_NVT_keyboard ; -- procedure body
  1139.      
  1140.   PROCEDURE process_any_messages_from_the_transport_level -- body
  1141.             ---------------------------------------------
  1142.    IS
  1143.   --************************  BODY SPECIFICATION  *****************************
  1144.   --
  1145.   -- While there are messages to process...
  1146.   -- If there is a message from the transport level, retrieve the message and
  1147.   -- write the message to the NVT printer.  A message being information 
  1148.   -- for the local user/process which was generated by the local transport 
  1149.   -- level, not simply data being relayed from the remote TELNET.
  1150.   --------------------------  data declarations  ---------------------------
  1151.   
  1152.     message_from_transport_level : message_from_transport_level_type ;
  1153.     length                       : bit_count_16_type RANGE 1..max_msg_length ;
  1154.   BEGIN  -- process_any_messages_from_the_transport_level
  1155.     debug_io.put_line("begin telnet_apl.process_any_messages.") ;
  1156.     WHILE there_is_a_message_available LOOP
  1157.       retrieve_message(message_from_transport_level, length) ;
  1158.       debug_io.put("message length =") ;
  1159.       debug_io.put_line(length) ;
  1160.       write_message_to_NVT_printer(message_from_transport_level, length) ;
  1161.     END LOOP ; -- message to process?
  1162.     debug_io.put_line("end telnet_apl.process_any_messages.") ;
  1163.   EXCEPTION
  1164.     WHEN OTHERS =>
  1165.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN aplpac.proc_any_mess") ;
  1166.       RAISE ;
  1167.   END process_any_messages_from_the_transport_level ; -- body
  1168.   PROCEDURE process_any_input_from_the_transport_level -- body
  1169.             ------------------------------------------
  1170.    IS
  1171.   --**********************  BODY SPECIFICATION  ****************************
  1172.   --
  1173.   -- Processing sequence :
  1174.   --
  1175.   -- While there is input to process...
  1176.   -- If there is input from the transport level which is data simply
  1177.   -- relayed from the remote TELNET, input a character from the
  1178.   -- transport level and mark the NVT I/O state as having I/O-done.  If the
  1179.   -- character is not a standard control function, write it on the NVT
  1180.   -- printer.  If the character is a standard control function, process the
  1181.   -- standard control function. 
  1182.   --------------------------  data declarations  -------------------------
  1183.     char : bit_count_8_type ;
  1184.     the_char_was_a_control_function : BOOLEAN ;
  1185.     urgent_data : BOOLEAN := TRUE ;
  1186.     echo_chars : virtual_transport_level.info_output_type
  1187.      (1..virtual_transport_level.max_msg_length) ;
  1188.     char_count : bit_count_16_type RANGE 0..virtual_transport_level.max_msg_length := 0 ;
  1189.     FUNCTION echo_to_remote RETURN BOOLEAN IS
  1190.              --------------
  1191.       local_options_in_effect : user_data.option_table_type RENAMES
  1192.        user_data.user_control_block.option_tables.local_options_in_effect ;
  1193.     BEGIN
  1194.       FOR index IN 1..local_options_in_effect.number_of_items LOOP
  1195.         IF local_options_in_effect.option(index) = user_data.echo THEN
  1196.           RETURN TRUE ;
  1197.         END IF ;
  1198.       END LOOP ;
  1199.       RETURN FALSE ;
  1200.     EXCEPTION
  1201.       WHEN OTHERS =>
  1202.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN aplpac.ehco_to_remote") ;
  1203.         RAISE ;
  1204.     END echo_to_remote ;
  1205.   BEGIN -- process_any_input_from_transport_level
  1206.     debug_io.put_line
  1207.      ("begin telnet_apl.process_any_input_from_transport_level") ;
  1208.     WHILE there_is_input LOOP
  1209.       debug_io.put_line
  1210.       ("telnet_apl.process_any_input thinks there is input") ;
  1211.       input_character(char, the_char_was_a_control_function, urgent_data) ;
  1212.       debug_io.put("telnet_apl.proc_input.char=") ;
  1213.       debug_io.put_line_byte(char) ;
  1214.       
  1215.       IF the_char_was_a_control_function THEN
  1216.         debug_io.put_line("was a control function") ;
  1217.         process_standard_control_function(char, urgent_data) ;
  1218.       ELSE
  1219.         debug_io.put_line("was not a control function") ;
  1220.         user_data.user_control_block.ga_state := no_go_ahead_sent ;
  1221.         write_character_to_NVT_printer(char) ;
  1222.         user_control_block.NVT_IO_state := IO_done ;
  1223.         char_count := char_count + 1 ;
  1224.         echo_chars(char_count) := char ;
  1225.       END IF ; -- control function?
  1226.     END LOOP ; -- any input to process?
  1227.     IF echo_to_remote AND char_count > 0 THEN
  1228.       virtual_transport_level.send_data(echo_chars(1..char_count),urgent_data) ;
  1229.     END IF ;
  1230.     debug_io.put_line
  1231.      ("end telnet_apl.process_any_input_from_transport_level") ;
  1232.   EXCEPTION
  1233.     WHEN OTHERS =>
  1234.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN aplpac.proc_tl_input") ;
  1235.       RAISE ;
  1236.   END process_any_input_from_the_transport_level ; -- body
  1237.   PROCEDURE transmit_telnet_go_ahead -- body
  1238.             ------------------------
  1239.    IS
  1240.   --*************************  BODY SPECIFICATION  ***************************
  1241.   --
  1242.   -- Processing sequence ...
  1243.   --
  1244.   -- Send the TELNET GA (go ahead) signal through the presentation level
  1245.   -- to the transport level.
  1246.   --------------------------  data declarations  -----------------------------
  1247.   
  1248.     SUBTYPE telnet_go_ahead_type IS 
  1249.      virtual_transport_level.info_output_type(1..2) ;
  1250.     telnet_go_ahead : telnet_go_ahead_type ;
  1251.     not_urgent      : BOOLEAN := FALSE ;
  1252.   
  1253.   BEGIN -- transmit_telnet_go_ahead
  1254.     debug_io.put_line("telnet go ahead sent") ;
  1255.     telnet_go_ahead(1) := 16#FF# ; -- RFC 854 page 14
  1256.     telnet_go_ahead(2) := 16#F9# ;
  1257.     IF virtual_transport_level.there_is_room_for_info_output THEN
  1258.       virtual_transport_level.send_data (telnet_go_ahead, not_urgent) ;
  1259.     END IF ;
  1260.   END transmit_telnet_go_ahead ; -- body
  1261.     
  1262. BEGIN -- telnet APL package body
  1263.   NULL ;
  1264. EXCEPTION
  1265.   WHEN OTHERS =>
  1266.     debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN aplpac instantiation") ;
  1267.     RAISE ;
  1268. END telnet_apl ; -- package
  1269. --::::::::::::::
  1270. --atrinpac.txt
  1271. --::::::::::::::
  1272. -----------------------------------------------------------------------
  1273. --
  1274. --         DoD Protocols    NA-00009-200       80-01206-100(-)
  1275. --         E-Systems, Inc.  August 07, 1985
  1276. --
  1277. --         atrinpac.txt       Author : Mike Thomas
  1278. --
  1279. -----------------------------------------------------------------------
  1280. -- File : atrinpac
  1281. --   5/8/85  9:25 AM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS 
  1282. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  1283. --  7/16/85  1:52 PM : mod for telesoft for wicat
  1284. WITH SYSTEM ; -- to get access to system.byte
  1285. PACKAGE transport_level_input_processing -- specification
  1286.         --------------------------------
  1287.  IS 
  1288. -- **************************  USER SPECIFICATION  ****************************
  1289. --
  1290. -- This package provides subprograms to process (at the APL level) data 
  1291. -- input to TELNET relayed from the remote TELNET.
  1292. --
  1293. -- **************************************************************************
  1294. SUBTYPE bit_count_32_type IS LONG_INTEGER ; 
  1295.   --&MT SUBTYPE bit_count_32_type IS INTEGER ;
  1296. SUBTYPE bit_count_16_type IS INTEGER ; 
  1297.   --&MT SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  1298. SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  1299.   --&MT SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  1300.   
  1301.   SUBTYPE character_type IS bit_count_8_type ;
  1302.   FUNCTION there_is_input -- specification
  1303.            --------------
  1304.    RETURN BOOLEAN ;
  1305.   -- ************************  USER SPECIFICATION  ****************************
  1306.   -- 
  1307.   -- This function returns true if there is data input available from the
  1308.   -- remote TELNET.
  1309.   -----------------------------------------------------------------------------
  1310.   PROCEDURE input_character -- specification
  1311.             ---------------
  1312.    (char :             OUT character_type ;
  1313.     control_function : OUT BOOLEAN ;
  1314.     urgent_data      : OUT BOOLEAN) ;
  1315.   -- ************************  USER SPECIFICATION  ****************************
  1316.   -- 
  1317.   -- This procedure returns a character sent from the remote TELNET and 
  1318.   -- indicates whether it is to be interpreted as a control function.
  1319.   -----------------------------------------------------------------------------
  1320.     
  1321.     
  1322.   PROCEDURE process_standard_control_function -- specification
  1323.             ---------------------------------
  1324.    (char : IN character_type ;
  1325.     urgent_data : IN BOOLEAN) ;
  1326.   -- ************************  USER SPECIFICATION  ****************************
  1327.   -- 
  1328.   -- This procedure processes a control function which was received from
  1329.   -- the remote TELNET connection.
  1330.   -----------------------------------------------------------------------------
  1331.  
  1332.   PROCEDURE write_character_to_NVT_printer -- specification
  1333.             ------------------------------
  1334.    (char : IN character_type) ;
  1335.   -- ************************  USER SPECIFICATION  ****************************
  1336.   -- 
  1337.   -- This routine writes a character to the NVT printer.
  1338.   -----------------------------------------------------------------------------
  1339. END transport_level_input_processing ; -- package specification
  1340.  
  1341.  
  1342. -- File : atrinpac
  1343. --   5/8/85  9:37 AM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS 
  1344. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  1345. --  7/16/85  1:52 PM : mod for telesoft for wicat
  1346. WITH virtual_transport_level ;
  1347. WITH virtual_terminal ;
  1348. WITH option_negotiation ;
  1349. WITH user_data ;
  1350. WITH debug_io ;
  1351. PACKAGE BODY transport_level_input_processing 
  1352.              --------------------------------
  1353.  IS 
  1354. -- *********************  BODY SPECIFICATION  *********************************
  1355. --
  1356. -- This package provides subprograms to process (at the APL level) data 
  1357. -- input to TELNET from the transport level.  Make the appropriate calls
  1358. -- to the lower level APL packages which will in turn call routines from
  1359. -- the PPL.  Data input is data sent from the remote TELNET.
  1360. --
  1361. -- ****************************************************************************
  1362.   FUNCTION there_is_input -- body
  1363.            --------------
  1364.    RETURN BOOLEAN IS
  1365.   BEGIN
  1366.     RETURN virtual_transport_level.there_is_input ; 
  1367.   EXCEPTION
  1368.     WHEN OTHERS =>
  1369.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.there_is_input") ;
  1370.       RAISE ;
  1371.   END there_is_input ; -- function body
  1372.   PROCEDURE input_character -- body
  1373.             ---------------
  1374.    (char :             OUT character_type ;
  1375.     control_function : OUT BOOLEAN ;
  1376.     urgent_data      : OUT BOOLEAN) IS
  1377.   -- ************************  BODY SPECIFICATION  ****************************
  1378.   --
  1379.   -- This procedure returns a character sent from the remote TELNET 
  1380.   -- and indicates whether it is to be interpreted as a control function. 
  1381.   -- Characters which are part of a synch are flagged as a control function.
  1382.   -- The urgent data flag or the user_data.synch_in_progress = TRUE indicates
  1383.   -- that the current character is to be interpreted as a control function.
  1384.   -- If the character is an IAC(Interperate As Command), get another 
  1385.   -- character.  If the second character is not an IAC it is a command and to
  1386.   -- be interpreted as a control function.  (This will also have the effect of
  1387.   -- of screening out the doubling of the IAC code done by the remote TELNET 
  1388.   -- when it is not to be interpreted as an IAC, ie. the data byte 255.)
  1389.   -- A call to this procedure without checking for the presence of characters
  1390.   -- to input is erroneous but will result in char := 0 and control_function
  1391.   -- := FALSE.
  1392.   -----------------------------------------------------------------------------
  1393.   
  1394.     IAC : CONSTANT character_type := 255 ; -- interprate as command code
  1395.     temp_char : character_type;
  1396.     temp_control_function : BOOLEAN;
  1397.     temp_urgent_data : BOOLEAN;
  1398.   BEGIN
  1399.     temp_char := 0 ;
  1400.     temp_control_function := FALSE ;
  1401.     IF virtual_transport_level.there_is_input THEN
  1402.       virtual_transport_level.get_input(temp_char, temp_urgent_data) ;
  1403.       IF user_data.user_control_block.synch_is_in_progress
  1404.        OR temp_urgent_data THEN -- special handling required
  1405.         temp_control_function := TRUE ;
  1406.         debug_io.put("atrinpac.input_character: control func detected, code=") ;
  1407.         debug_io.put_line_byte(temp_char) ;
  1408.       END IF ;
  1409.       IF bit_count_16_type(temp_char) = bit_count_16_type(IAC) THEN
  1410.         WHILE NOT(virtual_transport_level.there_is_input) LOOP NULL ; END LOOP ;
  1411.         virtual_transport_level.get_input(temp_char, temp_urgent_data) ;
  1412.         IF bit_count_16_type(temp_char) /= bit_count_16_type(IAC) THEN -- command IAC
  1413.           temp_control_function := TRUE ;
  1414.         END IF ;
  1415.       END IF ;
  1416.     END IF ;
  1417.     
  1418.     char := temp_char;
  1419.     control_function := temp_control_function;
  1420.     urgent_data := temp_urgent_data;
  1421.   EXCEPTION
  1422.     WHEN OTHERS =>
  1423.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.input_chr") ;
  1424.       RAISE ;
  1425.   END input_character ; -- procedure body
  1426.     
  1427.   PROCEDURE process_standard_control_function -- body
  1428.             ---------------------------------
  1429.    (char : IN character_type ;
  1430.     urgent_data : IN BOOLEAN) 
  1431.    IS 
  1432.   -- ************************  BODY SPECIFICATION  ****************************
  1433.   -- 
  1434.   -- This procedure processes a control function which was received from
  1435.   -- the remote TELNET.  Handling of the TELNET synch mechanism is also done 
  1436.   -- here as follows.  The synch is sent via the transport level send 
  1437.   -- operation with the urgent flag set and the data mark (DM) as the last 
  1438.   -- (or only) data octet.  If the transport level urgent data flag is set, 
  1439.   -- the data stream is scanned for IP, AO, AYT, and DM signals.
  1440.   -- When in normal mode, the DM is a no-op; when in urgent mode, it signals
  1441.   -- the end of urgent processing.  If the transport level indicates the end 
  1442.   -- of urgent data before the DM is found, TELNET will continue special 
  1443.   -- handling of the data stream until the DM is found. If more urgent data is
  1444.   -- indicated after the DM is found, TELNET will continue special handling
  1445.   -- of the data stream until the DM is found.  NOTE: Site dependent code used
  1446.   -- for the IP and BREAK commands.
  1447.   -- See RFC 854, page 9 for details on the TELNET synch mechanism.
  1448.   -----------------------------------------------------------------------------
  1449.    
  1450.     option_code      : bit_count_8_type ;
  1451.     control_function : BOOLEAN ;
  1452.     urgent_flag      : BOOLEAN ;
  1453.     urgent           : CONSTANT BOOLEAN := TRUE ;
  1454.     not_urgent       : CONSTANT BOOLEAN := FALSE ;
  1455.     
  1456.   BEGIN -- process_standard_control_function  
  1457.     debug_io.put_line("begin atrinpac.process_standard_control_function") ;
  1458.     IF user_data.user_control_block.synch_is_in_progress THEN
  1459.       debug_io.put("synch is in progress,") ;
  1460.     ELSE
  1461.       debug_io.put("synch is NOT in progress,") ;
  1462.     END IF ;
  1463.     IF urgent_data THEN 
  1464.       debug_io.put("   urgent data,") ;
  1465.     ELSE
  1466.       debug_io.put("   NOT urgent data,") ;
  1467.     END IF ;
  1468.     debug_io.put("   char_code=") ; 
  1469.     debug_io.put_line_byte(char) ;
  1470.     IF user_data.user_control_block.synch_is_in_progress OR urgent_data THEN 
  1471.       user_data.user_control_block.synch_is_in_progress := TRUE ;
  1472.     END IF ;
  1473.       CASE char IS -- handle non synch char
  1474.         WHEN 240 | 241 | 250 => -- SE, NOP, SB (RFC 854, p. 14)
  1475.           NULL ; -- nop for now
  1476.         WHEN 242 => -- DM
  1477.           user_data.user_control_block.synch_is_in_progress := FALSE ;
  1478.         WHEN 243 => -- break ****** NOTE: SITE DEPENDENT CODE USED ******
  1479.           virtual_terminal.output_character_to_nvt_printer
  1480.            (user_data.user_control_block.port, 3) ; -- ctrl c for VAX
  1481.         WHEN 244 => -- IP  ****** NOTE: SITE DEPENDENT CODE USED ******
  1482.           virtual_terminal.output_character_to_nvt_printer
  1483.            (user_data.user_control_block.port, 25) ; -- ctrl y for VAX
  1484.         WHEN 245 => -- AO
  1485.           DECLARE -- (RFC 854, P. 7,8,&14)
  1486.             buffer : user_data.string_type(1..user_data.max_out_string) ;
  1487.             length : bit_count_16_type ;
  1488.             data_mark : virtual_transport_level.info_output_type(1..1) ;
  1489.           BEGIN -- declare
  1490.             data_mark(1) := 242 ;
  1491.             user_data.get_data_buffer(buffer, length) ; -- trash rest of buffer
  1492.             virtual_transport_level.send_data(data_mark, urgent) ; -- synch
  1493.           END ; -- declare
  1494.         WHEN 246 => -- AYT   (RFC 854, P. 13,14)
  1495.           DECLARE 
  1496.             ayt_responce     : STRING(1..12) := " I AM HERE. " ;
  1497.             ayt_responce_vtl : virtual_transport_level.info_output_type(1..12);
  1498.           BEGIN -- delcare
  1499.             ayt_responce(1) := ASCII.CR ;
  1500.             ayt_responce(12) := ASCII.CR ;
  1501.             FOR index IN ayt_responce'RANGE LOOP -- convert type
  1502.               ayt_responce_vtl(bit_count_16_type(index)) := 
  1503.                bit_count_8_type(CHARACTER'POS(ayt_responce(index))) ;
  1504.             END LOOP ;
  1505.             virtual_transport_level.send_data(ayt_responce_vtl, not_urgent) ;
  1506.           END ; -- declare
  1507.         WHEN 247 => -- EC  (RFC 854, P. 13,14)
  1508.           IF user_data.there_is_data_in_data_buffer AND 
  1509.             user_data.user_control_block.synch_is_in_progress = FALSE THEN
  1510.             DECLARE
  1511.               buffer : user_data.out_string_type ;
  1512.               length : bit_count_16_type RANGE 1..user_data.max_out_string ;
  1513.             BEGIN -- declare
  1514.               user_data.get_data_buffer(buffer, length) ;
  1515.               user_data.put_string_in_data_buffer(buffer(1..length - 1)) ; 
  1516.             END ; -- declare
  1517.           END IF ;
  1518.         WHEN 248 => -- EL
  1519.           IF user_data.there_is_data_in_data_buffer AND 
  1520.             user_data.user_control_block.synch_is_in_progress = FALSE THEN
  1521.             DECLARE
  1522.               buffer : user_data.out_string_type ;
  1523.               length : bit_count_16_type RANGE 1..user_data.max_out_string ;
  1524.             BEGIN -- declare
  1525.               user_data.get_data_buffer(buffer, length) ;
  1526.               FOR index IN REVERSE 1..length LOOP -- delete up to CRLF
  1527.                 IF bit_count_16_type(buffer(index)) = 10 THEN -- line feed
  1528.                   IF index > 1 AND THEN
  1529.                     bit_count_16_type(buffer(index - 1)) = 13 THEN -- cr
  1530.                     user_data.put_string_in_data_buffer(buffer(1..index)) ;
  1531.                     EXIT ; -- loop
  1532.                   END IF ; -- CR?
  1533.                 END IF ; -- LF?
  1534.               END LOOP ; -- delete up to CRLF
  1535.             END ; -- declare
  1536.           END IF ; -- data in buffer and no synch in progress?
  1537.         WHEN 249 => -- GA 
  1538.           user_data.user_control_block.ga_received := TRUE ;
  1539.         WHEN 251 => -- WILL (option code) 
  1540.           -- get option code
  1541.           WHILE NOT (virtual_transport_level.there_is_input) LOOP NULL ;
  1542.           END LOOP ; 
  1543.           virtual_transport_level.get_input(option_code, urgent_flag) ;
  1544.           option_negotiation.remote_will_received(option_code) ;
  1545.         WHEN 252 => -- WON'T (option code) 
  1546.           -- get option code
  1547.           WHILE NOT (virtual_transport_level.there_is_input) LOOP NULL ;
  1548.           END LOOP ;
  1549.           virtual_transport_level.get_input
  1550.            (option_code, urgent_flag) ;
  1551.           option_negotiation.remote_wont_received(option_code) ;
  1552.         WHEN 253 => -- DO (option code) 
  1553.           -- get option code
  1554.           WHILE NOT (virtual_transport_level.there_is_input) LOOP NULL ;
  1555.           END LOOP ;
  1556.           virtual_transport_level.get_input(option_code, urgent_flag) ;
  1557.           option_negotiation.remote_do_received(option_code) ;
  1558.         WHEN 254 => -- DON'T (option code) 
  1559.           -- get option code
  1560.           WHILE NOT (virtual_transport_level.there_is_input) LOOP NULL ;
  1561.           END LOOP ;
  1562.           virtual_transport_level.get_input(option_code, urgent_flag) ;
  1563.           option_negotiation.remote_dont_received(option_code) ;
  1564.         WHEN OTHERS => -- error 
  1565.           NULL ; 
  1566.       END CASE ; -- handle non synch char
  1567.     debug_io.put_line("begin atrinpac.process_standard_control_function") ;
  1568.   EXCEPTION
  1569.     WHEN OTHERS =>
  1570.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.proc_std_cf") ;
  1571.       debug_io.put("char=") ;
  1572.       debug_io.put_line_byte(char) ;
  1573.       RAISE ;
  1574.   END process_standard_control_function ; -- procedure body
  1575.   PROCEDURE write_character_to_NVT_printer -- body
  1576.             ------------------------------
  1577.    (char : IN character_type) IS
  1578.   BEGIN
  1579.     virtual_terminal.output_character_to_nvt_printer
  1580.     (user_data.user_control_block.port, char) ;
  1581.   EXCEPTION
  1582.     WHEN OTHERS =>
  1583.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac.write_chr") ;
  1584.       RAISE ;
  1585.   END write_character_to_NVT_printer ; -- procedure body
  1586. BEGIN
  1587.   NULL ;
  1588.   EXCEPTION
  1589.     WHEN OTHERS =>
  1590.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN akeybdpac instantiation") ;
  1591.       RAISE ;
  1592. END transport_level_input_processing ; -- package body
  1593. --::::::::::::::
  1594. --auserdpac.txt
  1595. --::::::::::::::
  1596. -----------------------------------------------------------------------
  1597. --
  1598. --         DoD Protocols    NA-00009-200       80-01207-100(-)
  1599. --         E-Systems, Inc.  August 07, 1985
  1600. --
  1601. --         auserdpac.txt       Author : Mike Thomas
  1602. --
  1603. -----------------------------------------------------------------------
  1604. -- File : auserdpac   Author : Mike Thomas
  1605. --   5/22/85 9:20 AM : MODIFY FOR DEC ADA
  1606. --                     OLD CODE MARKED AS --&MT
  1607. --   6/11/85 5:14 PM : lcn changed from lcn_type to lcn_ptr_type
  1608. --   6/23/85 9:38 PM : init ga_state to no go_ahead_sent
  1609. --   7/16/85 1:58 PM : mods for telesoft for wicat
  1610. --&MT PRAGMA SOURCE_INFO(ON) ; -- ask TeleSoft to provide run-time error reports
  1611. WITH SYSTEM ;
  1612. WITH virtual_terminal ;
  1613. WITH with_ulp_communicate ; -- access lcn_type
  1614. WITH buffer_data ; -- access sixteen_bits type
  1615. WITH t_tcp_globals_data_structures ;
  1616. USE  t_tcp_globals_data_structures ;
  1617. PACKAGE user_data -- specification 
  1618.         ---------
  1619.  IS 
  1620. -- **********************  USER SPECIFICATION  ********************************
  1621. -- 
  1622. -- This package contains the user buffers
  1623. -- and state information.  The state information types and the maximum
  1624. -- user command length are also exported.
  1625. -- 
  1626. -- ****************************************************************************
  1627.   -----------------------  data (object) declarations  -----------------------
  1628.   SUBTYPE bit_count_16_type IS INTEGER ; 
  1629.   --&MT SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  1630.   SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  1631.   --&MT SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  1632.   -- state information maintained for each user
  1633.   TYPE nvt_io_state_type IS (io_done, no_io_done) ;
  1634.   TYPE communication_state_type IS (connection_established, 
  1635.                                     no_connection_established) ;
  1636.   TYPE command_state_type IS (partial_command, no_partial_command) ;
  1637.   TYPE go_ahead_sent_state_type IS (go_ahead_sent, no_go_ahead_sent) ;
  1638.   
  1639.   -- maximum user command string length (might use in partial cmd)
  1640.   max_cmd_length : CONSTANT bit_count_16_type := 80 ; -- arbitrary, make defered constant when supported
  1641.   TYPE string_type IS ARRAY (bit_count_16_type RANGE <>) OF bit_count_8_type ;
  1642.   max_out_string : CONSTANT bit_count_16_type := 256 ; -- largest ucb buffer size
  1643.   SUBTYPE out_string_type IS string_type(1..max_out_string) ;
  1644.   -- buffer space maintained for each user
  1645.        
  1646.   SUBTYPE partial_command_buf_length IS 
  1647.    bit_count_16_type RANGE 0..max_cmd_length ;
  1648.   TYPE partial_cmd_buffer_type IS 
  1649.    ARRAY (1..max_cmd_length) OF bit_count_8_type ;
  1650.   TYPE partial_command_buffer_type IS 
  1651.     RECORD
  1652.       buffer : partial_cmd_buffer_type ;
  1653.       length : partial_command_buf_length := 0 ;
  1654.     END RECORD ;
  1655.     
  1656.   data_buffer_length   : CONSTANT bit_count_16_type := 100 ; -- arbitrary
  1657.   SUBTYPE data_buf_ptr IS bit_count_16_type RANGE 0..data_buffer_length - 1 ;
  1658.   TYPE data_buf_type IS ARRAY (0..data_buffer_length - 1) OF bit_count_8_type ;
  1659.   TYPE data_buffer_type IS
  1660.     RECORD
  1661.       buffer : data_buf_type ;
  1662.       buf_head : data_buf_ptr := 0 ;
  1663.       buf_tail : data_buf_ptr := 1 ;
  1664.     END RECORD ;
  1665. -------------------------------  option tables  -------------------------------
  1666.   TYPE option_type IS (echo,suppress_ga) ; -- list of all options currently supported
  1667.   number_of_options_supported : CONSTANT bit_count_16_type := 2 ;  
  1668.   TYPE option_array_type IS ARRAY (1..number_of_options_supported)
  1669.    OF option_type ;
  1670.   SUBTYPE option_count_type IS bit_count_16_type
  1671.    RANGE 0..number_of_options_supported ; 
  1672.   TYPE option_table_type IS 
  1673.     RECORD
  1674.       option          : option_array_type ;
  1675.       number_of_items : option_count_type := 0 ;
  1676.     END RECORD ;
  1677.   TYPE option_tables_type IS
  1678.     RECORD
  1679.       local_options_desired    : option_table_type ;
  1680.       local_options_pending    : option_table_type ;
  1681.       local_options_in_effect  : option_table_type ;
  1682.       remote_options_desired   : option_table_type ;
  1683.       remote_options_pending   : option_table_type ;
  1684.       remote_options_in_effect : option_table_type ;
  1685.     END RECORD ;
  1686. -- These structures contain buffers which are used to communicate with the
  1687. -- transport level.  The trans_input_buffer and trans_output_buffer are
  1688. -- tightly coupled to the transport level and contain both messages and data.
  1689. -- (after link-up to TCP these debug buffers will not be used)
  1690. -- The other buffers are loosely coupled and have exclusivly data or messages.
  1691. -- 
  1692. -- ****************************************************************************
  1693.   -- transport level input buffer containing messages and data 
  1694.   -- direct channel to TCP (actual form will change) -- this for debug
  1695. --MT  trans_in_buffer_length : CONSTANT bit_count_16_type := 512 ; -- arbitrary
  1696. --MT  SUBTYPE trans_in_buf_ptr IS bit_count_16_type 
  1697. --MT   RANGE 0..trans_in_buffer_length - 1 ;
  1698. --MT  TYPE trans_input_buffer_type IS ARRAY (0..trans_in_buffer_length - 1)
  1699. --MT   OF bit_count_8_type ;
  1700. --MT  TYPE trans_input_buffer_record IS 
  1701. --MT    RECORD
  1702. --MT      buffer : trans_input_buffer_type ;
  1703. --MT      buf_head : trans_in_buf_ptr := 0 ;
  1704. --MT      buf_tail : trans_in_buf_ptr := 1 ;
  1705. --MT    END RECORD ;
  1706.     
  1707.   -- transport level output buffer containing messages and data 
  1708.   -- direct channel to TCP (actual form will change) -- this for debug
  1709. --MT  trans_out_buffer_length : CONSTANT bit_count_16_type := 512 ; -- arbitrary
  1710. --MT  SUBTYPE trans_out_buf_length IS bit_count_16_type RANGE 0..trans_out_buffer_length ;
  1711. --MT  TYPE trans_output_buffer_type IS ARRAY (1..trans_out_buffer_length) 
  1712. --MT   OF bit_count_8_type ;
  1713. --MT  TYPE trans_output_buffer_record IS 
  1714. --MT    RECORD
  1715. --MT      buffer : trans_output_buffer_type ;
  1716. --MT      length : trans_out_buf_length := 0 ;
  1717. --MT    END RECORD ;
  1718.   -- transport level to telnet messages
  1719.   -- these buffers not "directly" connected to the transport level
  1720.   trans_to_telnet_msg_buffer_length : CONSTANT bit_count_16_type := 512 ; -- arbitrary
  1721.   SUBTYPE trans_to_telnet_msg_buf_ptr_type IS 
  1722.    bit_count_16_type RANGE 0..trans_to_telnet_msg_buffer_length - 1 ;
  1723.   TYPE trans_to_telnet_msg_buffer_type IS
  1724.    ARRAY (0..trans_to_telnet_msg_buffer_length - 1) OF bit_count_8_type ;
  1725.   TYPE trans_to_telnet_messages_record IS 
  1726.     RECORD
  1727.       buffer   : trans_to_telnet_msg_buffer_type ;
  1728.       buf_head : trans_to_telnet_msg_buf_ptr_type := 0 ;
  1729.       buf_tail : trans_to_telnet_msg_buf_ptr_type := 1 ;
  1730.     END RECORD ;
  1731.     
  1732.   -- transport level to telnet data
  1733.   -- these buffers not "directly" connected to the transport level
  1734.   trans_to_telnet_data_buffer_length : CONSTANT bit_count_16_type := 512 ; -- arbitrary
  1735.   SUBTYPE trans_to_telnet_data_buf_ptr_type IS 
  1736.    bit_count_16_type RANGE 0..trans_to_telnet_data_buffer_length - 1 ;
  1737.   TYPE trans_to_telnet_data_buffer_type IS
  1738.    ARRAY (0..trans_to_telnet_data_buffer_length - 1) OF bit_count_8_type ;
  1739.   TYPE trans_to_telnet_data_record IS 
  1740.     RECORD
  1741.       buffer   : trans_to_telnet_data_buffer_type ;
  1742.       buf_head : trans_to_telnet_data_buf_ptr_type := 0 ;
  1743.       buf_tail : trans_to_telnet_data_buf_ptr_type := 1 ;
  1744.     END RECORD ;
  1745.   
  1746.   TYPE ppl_trans_buffers_type IS
  1747.     RECORD  
  1748. --MT      trans_input_buffer       : trans_input_buffer_record ; -- debug
  1749. --MT      trans_output_buffer      : trans_output_buffer_record ; -- debug
  1750.       trans_to_telnet_messages : trans_to_telnet_messages_record ;
  1751.       trans_to_telnet_data     : trans_to_telnet_data_record ;
  1752.     END RECORD ;
  1753.   TYPE control_block_type IS -- (contains state information etc. for a user)
  1754.     RECORD
  1755.       port                      : virtual_terminal.port_number ;
  1756.       tl_port_number            : buffer_data.sixteen_bits ; -- transport level local port #
  1757.       lcn                       : tcb_ptr  ; -- TCP local_connection_number
  1758.       NVT_IO_state              : NVT_IO_state_type := IO_done ;
  1759.       communication_state       : communication_state_type :=
  1760.                                    no_connection_established ;
  1761.       command_state             : command_state_type := no_partial_command ;
  1762.       GA_state                  : go_ahead_sent_state_type := no_go_ahead_sent ;
  1763.       GA_received               : BOOLEAN := FALSE ;
  1764.       synch_is_in_progress      : BOOLEAN := FALSE ;
  1765.       last_keybd_char_was_cmd   : BOOLEAN := FALSE ; 
  1766.       rcv_data_is_urgent        : BOOLEAN := FALSE ;
  1767.       last_data_char_rcv_not_cr : BOOLEAN := TRUE ;
  1768.       partial_command_buffer    : partial_command_buffer_type ;
  1769.       data_buffer               : data_buffer_type ;
  1770.       option_tables             : option_tables_type ;
  1771.       trans_buffers             : ppl_trans_buffers_type ;
  1772.     END RECORD ;
  1773.   user_control_block : control_block_type ;
  1774.   -------------------  end data (object) declarations  -----------------------
  1775.  
  1776.   ---------------  function/procedure (verb) specifications  -----------------
  1777.  
  1778.   -- partial command data buffer manipulation functions/procedures
  1779.   FUNCTION there_is_data_in_command_buffer -- specification
  1780.            -------------------------------
  1781.    RETURN BOOLEAN ;
  1782.   -- ***********************  USER SPECIFICATION  *****************************
  1783.   --
  1784.   -- This function returns true if there is data in the APL command buffer.
  1785.   -----------------------------------------------------------------------------
  1786.   FUNCTION there_is_room_in_command_buffer -- specification
  1787.            -------------------------------
  1788.    RETURN BOOLEAN ; -- room for a character
  1789.   -- ***********************  USER SPECIFICATION  *****************************
  1790.   --
  1791.   -- This function returns true if there is room for a character in the 
  1792.   -- APL command buffer.
  1793.   -----------------------------------------------------------------------------
  1794.   PROCEDURE put_char_in_command_buffer -- specificaton
  1795.             --------------------------
  1796.    (char : IN bit_count_8_type) ;
  1797.   -- ***********************  USER SPECIFICATION  *****************************
  1798.   --
  1799.   -- This procedure will add a character to the APL command buffer.  The
  1800.   -- user should make sure there is room in the buffer before calling this 
  1801.   -- procedure.  If the NVT output buffer is full, the character will be lost.
  1802.   -----------------------------------------------------------------------------
  1803.   PROCEDURE put_string_in_command_buffer -- specificaton
  1804.             ----------------------------
  1805.    (str : IN string_type) ;
  1806.   -- ***********************  USER SPECIFICATION  *****************************
  1807.   --
  1808.   -- This procedure will add characters to the APL command buffer.  If there
  1809.   -- is not enough room in the buffer for all the characters, then the 
  1810.   -- extra characters will be lost.
  1811.   -----------------------------------------------------------------------------
  1812.   PROCEDURE get_char_from_command_buffer -- specificaton
  1813.             ----------------------------
  1814.    (char : OUT bit_count_8_type) ;
  1815.   -- ***********************  USER SPECIFICATION  *****************************
  1816.   --
  1817.   -- This procedure returns the next character from the APL command buffer.
  1818.   -- The user should determine that there are characters in the buffer before 
  1819.   -- calling this procedure.  If the buffer is empty, this procedure will 
  1820.   -- return null. 
  1821.   -----------------------------------------------------------------------------
  1822.   PROCEDURE get_command_buffer -- specificaton
  1823.             ------------------
  1824.    (buffer : OUT out_string_type ;
  1825.     length : OUT bit_count_16_type) ;
  1826.   -- ***********************  USER SPECIFICATION  *****************************
  1827.   --
  1828.   -- This procedure returns the entire contents of the APL command buffer.
  1829.   -- The user should determine that there are characters in the buffer before 
  1830.   -- calling this procedure.  If the buffer is empty, this procedure will 
  1831.   -- return null. 
  1832.   -----------------------------------------------------------------------------
  1833.   -- data buffer manipulation functions/procedures
  1834.   FUNCTION there_is_data_in_data_buffer -- specification
  1835.            ----------------------------
  1836.    RETURN BOOLEAN ;
  1837.   -- ***********************  USER SPECIFICATION  *****************************
  1838.   --
  1839.   -- This function returns true if there is data in the APL data buffer.
  1840.   -----------------------------------------------------------------------------
  1841.   FUNCTION there_is_room_in_data_buffer -- specification
  1842.            ----------------------------
  1843.    RETURN BOOLEAN ; -- room for a character
  1844.   -- ***********************  USER SPECIFICATION  *****************************
  1845.   --
  1846.   -- This function returns true if there is room for a character in the 
  1847.   -- APL data buffer.
  1848.   -----------------------------------------------------------------------------
  1849.   PROCEDURE put_char_in_data_buffer -- specificaton
  1850.             -----------------------
  1851.    (char : IN bit_count_8_type) ;
  1852.   -- ***********************  USER SPECIFICATION  *****************************
  1853.   --
  1854.   -- This procedure will add a character to the APL data buffer.  The
  1855.   -- user should make sure there is room in the buffer before calling this 
  1856.   -- procedure.  If the NVT output buffer is full, the character will be lost.
  1857.   -----------------------------------------------------------------------------
  1858.   PROCEDURE put_string_in_data_buffer -- specificaton
  1859.             -------------------------
  1860.    (str : IN string_type) ;
  1861.   -- ***********************  USER SPECIFICATION  *****************************
  1862.   --
  1863.   -- This procedure will add characters to the data buffer.  If there
  1864.   -- is not enough room in the buffer for all the characters, the 
  1865.   -- excess characters will be lost.
  1866.   -----------------------------------------------------------------------------
  1867.   PROCEDURE get_char_from_data_buffer -- specificaton
  1868.             -------------------------
  1869.    (char : OUT bit_count_8_type) ;
  1870.   -- ***********************  USER SPECIFICATION  *****************************
  1871.   --
  1872.   -- This procedure returns the next character from the APL data buffer.
  1873.   -- The user should determine that there are characters in the buffer before 
  1874.   -- calling this procedure.  If the buffer is empty, this procedure will 
  1875.   -- return null. 
  1876.   -----------------------------------------------------------------------------
  1877.   PROCEDURE get_data_buffer -- specificaton
  1878.             ---------------
  1879.    (buffer : OUT out_string_type ;
  1880.     length : OUT bit_count_16_type) ;
  1881.   -- ***********************  USER SPECIFICATION  *****************************
  1882.   --
  1883.   -- This procedure returns the entire contents of the APL data buffer.
  1884.   -- The user should determine that there are characters in the buffer before 
  1885.   -- calling this procedure.  If the buffer is empty, this procedure will 
  1886.   -- return null. 
  1887.   -----------------------------------------------------------------------------
  1888.   PROCEDURE get -- specification
  1889.             ---
  1890.    (user_control_block_out : OUT control_block_type) ;
  1891.     -- **********************  USER SPECIFICATION  ****************************
  1892.     -- 
  1893.     -- This procedure returns the contents of the entire user control block
  1894.     -- which contains state information and buffers for the TELNET user.
  1895.     -------------------------------------------------------------------------
  1896.   PROCEDURE put -- specification
  1897.             ---
  1898.    (user_control_block_in : IN control_block_type) ;
  1899.     -- **********************  USER SPECIFICATION  ****************************
  1900.     -- 
  1901.     -- This procedure assigns the contents of the entire user control block
  1902.     -- which contains state information and buffers for the TELNET user.
  1903.     -------------------------------------------------------------------------
  1904.     PROCEDURE reset_user_control_block ;
  1905.               ------------------------
  1906.     -- **********************  USER SPECIFICATION  ****************************
  1907.     -- 
  1908.     -- This procedure resets the user control block as a result of a connection
  1909.     -- closing due to abort or a normal close.
  1910.     ---------------------------------------------------------------------------
  1911.   -----------  end function/procedure (verb) specifications  -----------------
  1912. END user_data ; -- package specification 
  1913. -- File : auserdpac   Author : Mike Thomas
  1914. --   5/22/85   9:20 AM : MODIFY FOR DEC ADA
  1915. --                     OLD CODE MARKED AS --&MT
  1916. --   6/26/85  10:17 AM : reset ga_state to no_go_ahead_sent
  1917. --   7/16/85   1:58 PM : mods for telesoft for wicat
  1918. WITH debug_io ;
  1919. PACKAGE BODY user_data 
  1920.              ---------
  1921.  IS
  1922.  
  1923.   -- partial command data buffer manipulation functions/procedures
  1924.   FUNCTION there_is_data_in_command_buffer -- body
  1925.            -------------------------------
  1926.    RETURN BOOLEAN IS
  1927.   BEGIN
  1928.     RETURN user_control_block.partial_command_buffer.length /= 0 ;
  1929.   END there_is_data_in_command_buffer ; -- body
  1930.   FUNCTION there_is_room_in_command_buffer -- body -- room for a character
  1931.            -------------------------------
  1932.    RETURN BOOLEAN IS 
  1933.   BEGIN
  1934.     RETURN user_control_block.partial_command_buffer.length < max_cmd_length ;
  1935.   END there_is_room_in_command_buffer ; -- body
  1936.   PROCEDURE put_char_in_command_buffer -- body
  1937.             --------------------------
  1938.    (char : IN bit_count_8_type) IS
  1939.     length : partial_command_buf_length RENAMES
  1940.      user_control_block.partial_command_buffer.length ;
  1941.     buffer : partial_cmd_buffer_type RENAMES
  1942.      user_control_block.partial_command_buffer.buffer ;
  1943.   BEGIN
  1944.     IF there_is_room_in_command_buffer THEN
  1945.       length := length + 1 ;
  1946.       buffer(length) := char ;
  1947.     END IF ; 
  1948.   END put_char_in_command_buffer ; -- body
  1949.   
  1950.   PROCEDURE put_string_in_command_buffer -- body
  1951.             ----------------------------
  1952.    (str : IN string_type) IS
  1953.   BEGIN
  1954.     FOR index IN str'RANGE LOOP
  1955.       put_char_in_command_buffer(str(index)) ;
  1956.     END LOOP ;
  1957.   END put_string_in_command_buffer ; -- body
  1958.   PROCEDURE get_char_from_command_buffer -- body
  1959.             ----------------------------
  1960.    (char : OUT bit_count_8_type) IS
  1961.     length : partial_command_buf_length RENAMES
  1962.      user_control_block.partial_command_buffer.length ;
  1963.     buffer : partial_cmd_buffer_type RENAMES
  1964.      user_control_block.partial_command_buffer.buffer ;
  1965.   BEGIN
  1966.     char := 0 ;
  1967.     IF there_is_data_in_command_buffer THEN
  1968.       char := buffer(1) ;
  1969.       buffer(1..length - 1) := buffer(2..length) ;
  1970.       length := length - 1 ;
  1971.     END IF ;
  1972.   END get_char_from_command_buffer ; -- body
  1973.   
  1974.   PROCEDURE get_command_buffer -- body
  1975.             ------------------
  1976.    (buffer : OUT out_string_type ;
  1977.     length : OUT bit_count_16_type) IS
  1978.     cmd_length : partial_command_buf_length RENAMES
  1979.      user_control_block.partial_command_buffer.length ;
  1980.     cmd_buffer : partial_cmd_buffer_type RENAMES
  1981.      user_control_block.partial_command_buffer.buffer ;
  1982.     buffer_length : CONSTANT bit_count_16_type := cmd_length ;
  1983.   BEGIN
  1984.     length := cmd_length ;
  1985.     cmd_length := 0 ;
  1986.     FOR index IN 1..buffer_length LOOP
  1987.       buffer(index):= cmd_buffer(index) ;
  1988.     END LOOP ;
  1989.   END get_command_buffer ; -- body
  1990.   -- data buffer manipulation functions/procedures
  1991.   FUNCTION there_is_data_in_data_buffer -- body
  1992.            ----------------------------
  1993.    RETURN BOOLEAN IS
  1994.     data : data_buffer_type RENAMES user_control_block.data_buffer ;
  1995.   BEGIN
  1996.     RETURN (data.buf_head + 1) MOD data_buffer_length /= data.buf_tail ;
  1997.   END there_is_data_in_data_buffer ; -- body
  1998.   FUNCTION there_is_room_in_data_buffer -- body (room for a character)
  1999.            ----------------------------
  2000.    RETURN BOOLEAN IS
  2001.     data : data_buffer_type RENAMES user_control_block.data_buffer ;
  2002.   BEGIN
  2003.     RETURN data.buf_head /= data.buf_tail ;
  2004.   END there_is_room_in_data_buffer ; -- body
  2005.   PROCEDURE put_char_in_data_buffer -- body
  2006.             -----------------------
  2007.    (char : IN bit_count_8_type) IS
  2008.     data : data_buffer_type RENAMES user_control_block.data_buffer ;
  2009.   BEGIN
  2010.     IF there_is_room_in_data_buffer THEN
  2011.       data.buffer(data.buf_tail) := char ;
  2012.       data.buf_tail := (data.buf_tail + 1) MOD data_buffer_length ;
  2013.     END IF ; 
  2014.   END put_char_in_data_buffer ; -- body
  2015.   PROCEDURE put_string_in_data_buffer -- body
  2016.             -------------------------
  2017.    (str : IN string_type) IS
  2018.   BEGIN
  2019.     FOR index IN str'RANGE LOOP
  2020.       put_char_in_data_buffer(str(index)) ;
  2021.     END LOOP ;
  2022.   END put_string_in_data_buffer ; -- body
  2023.   PROCEDURE get_char_from_data_buffer -- body
  2024.             -------------------------
  2025.    (char : OUT bit_count_8_type) IS
  2026.     data : data_buffer_type RENAMES user_control_block.data_buffer ;
  2027.   BEGIN
  2028.     char := 0 ;
  2029.     IF there_is_data_in_data_buffer THEN
  2030.       data.buf_head := (data.buf_head + 1) MOD data_buffer_length ;
  2031.       char := data.buffer(data.buf_head) ;
  2032.     END IF ;
  2033.   END get_char_from_data_buffer ; -- body
  2034.   PROCEDURE get_data_buffer -- body
  2035.             ---------------
  2036.    (buffer : OUT out_string_type ;
  2037.     length : OUT bit_count_16_type) IS
  2038.     data : data_buffer_type RENAMES user_control_block.data_buffer ;
  2039.     buffer_length : bit_count_16_type := 0 ;
  2040.   BEGIN
  2041.     WHILE (data.buf_head + 1) MOD data_buffer_length /= data.buf_tail LOOP
  2042.       data.buf_head := (data.buf_head + 1) MOD data_buffer_length ; 
  2043.       buffer_length := buffer_length + 1 ;
  2044.       buffer(buffer_length) := data.buffer(data.buf_head) ;
  2045.     END LOOP ;
  2046.     length := buffer_length ;
  2047.   END get_data_buffer ; -- body
  2048.  
  2049.   PROCEDURE get -- body
  2050.             ---
  2051.    (user_control_block_out : OUT control_block_type) IS
  2052.   BEGIN
  2053.     user_control_block_out := user_control_block ;
  2054.   END get ; -- body
  2055.   PROCEDURE put -- body
  2056.             ---
  2057.    (user_control_block_in : IN control_block_type) IS
  2058.   BEGIN
  2059.     user_control_block := user_control_block_in ;
  2060.   END put ; -- body
  2061.   PROCEDURE reset_user_control_block IS
  2062.             ------------------------
  2063.     ucb : control_block_type RENAMES user_control_block ;
  2064.   BEGIN -- restore default values
  2065.     ucb.nvt_io_state                         := io_done ;
  2066.     ucb.communication_state                  := no_connection_established ;
  2067.     ucb.command_state                        := no_partial_command ;
  2068.     ucb.ga_state                             := no_go_ahead_sent ;
  2069.     ucb.ga_received                          := FALSE ;
  2070.     ucb.synch_is_in_progress                 := FALSE ;
  2071.     ucb.last_keybd_char_was_cmd              := FALSE ;
  2072.     ucb.rcv_data_is_urgent                   := FALSE ;
  2073.     ucb.last_data_char_rcv_not_cr            := TRUE ;
  2074.     ucb.partial_command_buffer.length        := 0 ;
  2075.     ucb.option_tables.local_options_pending.number_of_items    := 0 ;
  2076.     ucb.option_tables.local_options_in_effect.number_of_items  := 0 ;
  2077.     ucb.option_tables.remote_options_pending.number_of_items   := 0 ;
  2078.     ucb.option_tables.remote_options_in_effect.number_of_items := 0 ;
  2079.   END reset_user_control_block ;
  2080. BEGIN -- user_data
  2081.   NULL ;
  2082. EXCEPTION
  2083.   WHEN OTHERS =>
  2084.     debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN user_data instantiation") ;
  2085.     RAISE ;
  2086. END user_data ; -- package body
  2087. --::::::::::::::
  2088. --debugio.txt
  2089. --::::::::::::::
  2090. -----------------------------------------------------------------------
  2091. --
  2092. --         DoD Protocols    NA-00009-200       80-01208-100(-)
  2093. --         E-Systems, Inc.  August 07, 1985
  2094. --
  2095. --         debugio.txt       Author : Mike Thomas
  2096. --
  2097. -----------------------------------------------------------------------
  2098. -- File : debugio    Author : Mike Thomas
  2099. --  5/22/85  8:10 AM : MODIFY FOR DEC ADA 
  2100. --                     OLD CODE (TELESOFT) MARKED AS --&MT
  2101. --  7/16/85  2:15 PM : mods for telesoft wicat
  2102. WITH SYSTEM ;
  2103. USE  SYSTEM ;
  2104. PACKAGE debug_io IS
  2105. -- ****************************************************************************
  2106. -- 
  2107. -- This package has routines which do output to the CRT or a debug disk file
  2108. -- or both (or neither).  The interface is indended to look similer to 
  2109. -- text_io for string, character and integer output.  NOTE : The Wicat
  2110. -- must close a disk file for it to exist.
  2111. --
  2112. -- ****************************************************************************
  2113.    SUBTYPE bit_count_32_type IS LONG_INTEGER ; 
  2114.   --&MT SUBTYPE bit_count_32_type IS INTEGER ;
  2115.     SUBTYPE bit_count_16_type IS INTEGER ; 
  2116.   --&MT SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  2117.     SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  2118.   --&MT SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  2119.   
  2120.   PROCEDURE put (item : IN CHARACTER) ;
  2121.   PROCEDURE put (item : IN STRING) ;
  2122.   PROCEDURE put (item : IN bit_count_16_type) ;
  2123. --&MT--PROCEDURE put (item : IN SYSTEM.BYTE) ;      -- TeleLie-ADA flags this as an 
  2124. --&MT                                               -- illegel redeclaration!
  2125. --&MT  PROCEDURE put_byte (item : IN SYSTEM.BYTE) ; -- so... use this
  2126.   PROCEDURE put_byte (item : IN bit_count_8_type) ;
  2127.   PROCEDURE put_line (item : IN CHARACTER) ;
  2128.   PROCEDURE put_line (item : IN STRING) ;
  2129.   PROCEDURE put_line (item : IN bit_count_16_type) ;
  2130. --&MT--PROCEDURE put_line (item : IN SYSTEM.BYTE) ; -- as above...
  2131.   PROCEDURE put_line_byte (item : IN bit_count_8_type) ; 
  2132.   PROCEDURE open_debug_disk_file ;
  2133.   PROCEDURE close_debug_disk_file ;
  2134.   FUNCTION debug_disk_file_is_open RETURN BOOLEAN ;
  2135. -- user could store existing destination, set his own temporary one, and
  2136. -- restore the origional destination at any point to redirect debug info.
  2137. -- NOTE : ATTEMPTING TO WRITE TO THE DISK FILE WHEN IT IS NOT OPEN IS ERRONEOUS.
  2138.   TYPE debug_destination_type IS 
  2139.    (none, crt_only, debug_disk_file_only, crt_and_disk) ;
  2140.   destination : debug_destination_type := none ;
  2141.   
  2142. END debug_io ;
  2143. -- File : debugio    Author : Mike Thomas
  2144. --  5/22/85  8:10 AM : MODIFY FOR DEC ADA 
  2145. --                     OLD CODE (TELESOFT) MARKED AS --&MT
  2146. --  7/16/85  2:15 PM : mods for telesoft wicat
  2147. WITH TEXT_IO ;
  2148. USE  TEXT_IO ;
  2149. PACKAGE BODY debug_io IS
  2150. -- ****************************************************************************
  2151. -- 
  2152. -- It would be nice to revamp this package and use generics when they are 
  2153. -- supported by the compiler.  Also could add enumerated type I/O routines.  
  2154. -- If input routines are needed, they could be added.
  2155. -- ****************************************************************************
  2156.   debug_filename              : CONSTANT STRING(1..13) := "DEBUGFILE.TXT" ;
  2157.   debug_output_file           : TEXT_IO.FILE_TYPE ;
  2158.   output_file                 : TEXT_IO.FILE_MODE := TEXT_IO.OUT_FILE ;
  2159.   the_debug_disk_file_is_open : BOOLEAN := FALSE ;
  2160. --&MT  next line not used for TeleSoft
  2161. --&MT  PACKAGE integer_io IS NEW TEXT_IO.INTEGER_IO(bit_count_16_type) ;
  2162.   PROCEDURE screening_put (item : IN CHARACTER) IS
  2163.             -------------
  2164.   BEGIN
  2165.     IF item = ASCII.CR THEN 
  2166.       TEXT_IO.PUT("<CR>") ; -- display logical cr so won't mess up printer
  2167.     ELSE
  2168.       TEXT_IO.PUT(item) ;
  2169.     END IF ;
  2170.   EXCEPTION
  2171.     WHEN OTHERS =>
  2172.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.SCR_PUT(C)") ;
  2173.       RAISE ;
  2174.   END screening_put ;
  2175.   PROCEDURE screening_put 
  2176.             -------------
  2177.    (debug_file : IN TEXT_IO.FILE_TYPE ;
  2178.     item       : IN CHARACTER) IS
  2179.   BEGIN
  2180.     IF item = ASCII.CR THEN 
  2181.       TEXT_IO.PUT(debug_file, "<CR>") ; -- display logical cr so won't 
  2182.     ELSE
  2183.       TEXT_IO.PUT(debug_file, item) ;
  2184.     END IF ;
  2185.   EXCEPTION
  2186.     WHEN OTHERS =>
  2187.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.SCR_PUT(F,C)") ;
  2188.       RAISE ;
  2189.   END screening_put ;
  2190.   PROCEDURE put (item : IN CHARACTER) IS 
  2191.   BEGIN
  2192.     CASE destination IS
  2193.       WHEN crt_only =>
  2194.         screening_put(item) ;
  2195.       WHEN debug_disk_file_only =>
  2196.         screening_put(debug_output_file, item) ;
  2197.       WHEN crt_and_disk =>
  2198.         screening_put(item) ;
  2199.         screening_put(debug_output_file, item) ;
  2200.       WHEN none =>
  2201.         NULL ;
  2202.     END CASE ;       
  2203.   EXCEPTION
  2204.     WHEN OTHERS =>
  2205.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.PUT(C)") ;
  2206.       RAISE ;
  2207.   END put ;
  2208.   PROCEDURE put (item : IN STRING) IS
  2209.     buf : STRING (1..4*item'length) ;-- arbitrary length(allow for "expansion")
  2210.     --&MT buf_ptr : bit_count_32_type RANGE 0..4*item'length := 0 ;
  2211.     buf_ptr : bit_count_16_type RANGE 0..4*item'length := 0 ;
  2212.   BEGIN
  2213.   -- Calls to text_io are expensive, do processing here to reduce calls
  2214.   -- by printing strings and not individual characters.
  2215.     IF destination = none THEN RETURN ; END IF ;
  2216.     FOR index IN item'RANGE LOOP -- check for printer control char
  2217.       IF item(index) = ASCII.CR THEN -- replace ASCII.CR with "<CR>"
  2218.         buf((buf_ptr + 1)..(buf_ptr + 4)) := "<CR>" ;
  2219.         buf_ptr := buf_ptr + 4 ;
  2220.       ELSE
  2221.         buf_ptr := buf_ptr + 1 ;
  2222.         buf(buf_ptr) := item(index) ;
  2223.       END IF ;
  2224.     END LOOP ;
  2225.     IF buf_ptr > 0 THEN
  2226.       DECLARE -- handle strings > 132 so text_io does not get constraint error
  2227.         --&MT start : bit_count_32_type := 1 ;
  2228.         --&MT stop  : bit_count_32_type := 79 ;
  2229.         start : bit_count_16_type := 1 ;
  2230.         stop  : bit_count_16_type := 79 ;
  2231.       BEGIN
  2232.         LOOP
  2233.           IF stop > buf_ptr THEN
  2234.             CASE destination IS
  2235.               WHEN crt_only =>
  2236.                 TEXT_IO.PUT(buf(start..buf_ptr)) ;
  2237.               WHEN debug_disk_file_only =>
  2238.                 TEXT_IO.PUT(debug_output_file, buf(start..buf_ptr)) ;
  2239.               WHEN crt_and_disk =>
  2240.                 TEXT_IO.PUT(buf(start..buf_ptr)) ;
  2241.                 TEXT_IO.PUT(debug_output_file, buf(start..buf_ptr)) ;
  2242.               WHEN none =>
  2243.                 NULL ;
  2244.               END CASE ; 
  2245.               EXIT ;
  2246.           ELSE
  2247.             CASE destination IS
  2248.               WHEN crt_only =>
  2249.                 TEXT_IO.PUT_LINE(buf(start..stop)) ;
  2250.               WHEN debug_disk_file_only =>
  2251.                 TEXT_IO.PUT_LINE(debug_output_file, buf(start..stop)) ;
  2252.               WHEN crt_and_disk =>
  2253.                 TEXT_IO.PUT_LINE(buf(start..stop)) ;
  2254.                 TEXT_IO.PUT_LINE(debug_output_file, buf(start..stop)) ;
  2255.               WHEN none =>
  2256.                 NULL ;
  2257.               END CASE ; 
  2258.               start := start + 79;
  2259.               stop := stop + 79 ;
  2260.           END IF ; -- < 79 characters ?
  2261.         END LOOP ;
  2262.       END ; -- declare
  2263.     END IF ; -- buf_ptr > 0 
  2264.   EXCEPTION
  2265.     WHEN OTHERS =>
  2266.       TEXT_IO.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.PUT(S)") ;
  2267.       RAISE ;
  2268.   END put ;
  2269.   PROCEDURE put (item : IN bit_count_16_type) IS 
  2270.   BEGIN
  2271.     CASE destination IS
  2272.       WHEN crt_only =>
  2273.         INTEGER_IO.PUT(item) ;
  2274.       WHEN debug_disk_file_only =>
  2275.         INTEGER_IO.PUT(debug_output_file, item) ;
  2276.       WHEN crt_and_disk =>
  2277.         INTEGER_IO.PUT(item) ;
  2278.         INTEGER_IO.PUT(debug_output_file, item) ;
  2279.       WHEN none =>
  2280.         NULL ;
  2281.     END CASE ;       
  2282.   EXCEPTION
  2283.     WHEN OTHERS =>
  2284.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.PUT(I)") ;
  2285.       RAISE ;
  2286.   END put ;
  2287.   PROCEDURE put_byte (item : IN bit_count_8_type) IS
  2288.   BEGIN
  2289.     debug_io.put('<') ;
  2290.     debug_io.put(bit_count_16_type(item)) ;
  2291.     debug_io.put('>') ;
  2292.   EXCEPTION
  2293.     WHEN OTHERS =>
  2294.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.PUT(B)") ;
  2295.       RAISE ;
  2296.   END put_byte ;
  2297.   
  2298.   PROCEDURE put_line (item : IN CHARACTER) IS
  2299.   BEGIN
  2300.     debug_io.put(item) ;
  2301.     CASE destination IS
  2302.       WHEN crt_only =>
  2303.         TEXT_IO.NEW_LINE ;
  2304.       WHEN debug_disk_file_only =>
  2305.         TEXT_IO.NEW_LINE(debug_output_file) ;
  2306.       WHEN crt_and_disk =>
  2307.         TEXT_IO.NEW_LINE ;
  2308.         TEXT_IO.NEW_LINE(debug_output_file) ;
  2309.       WHEN none =>
  2310.         NULL ;
  2311.      END CASE ; 
  2312.   EXCEPTION
  2313.     WHEN OTHERS =>
  2314.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.PUT_LINE(C)") ;
  2315.       RAISE ;
  2316.   END put_line ;
  2317.   PROCEDURE put_line (item : IN STRING) IS
  2318.   BEGIN
  2319.     IF destination = none THEN RETURN ; END IF ;
  2320.     debug_io.put(item) ;
  2321.     CASE destination IS
  2322.       WHEN crt_only =>
  2323.         TEXT_IO.NEW_LINE ;
  2324.       WHEN debug_disk_file_only =>
  2325.         TEXT_IO.NEW_LINE(debug_output_file) ;
  2326.       WHEN crt_and_disk =>
  2327.         TEXT_IO.NEW_LINE ;
  2328.         TEXT_IO.NEW_LINE(debug_output_file) ;
  2329.       WHEN none =>
  2330.         NULL ;
  2331.      END CASE ; 
  2332.   EXCEPTION
  2333.     WHEN OTHERS =>
  2334.       TEXT_IO.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.PUT_LINE(S)") ;
  2335.       RAISE ;
  2336.   END put_line ;
  2337.   PROCEDURE put_line (item : IN bit_count_16_type) IS 
  2338.   BEGIN
  2339.     CASE destination IS
  2340.       WHEN crt_only =>
  2341.         INTEGER_IO.PUT(item) ;
  2342.         TEXT_IO.NEW_LINE ;
  2343.       WHEN debug_disk_file_only =>
  2344.         INTEGER_IO.PUT(debug_output_file, item) ;
  2345.         TEXT_IO.NEW_LINE(debug_output_file) ;
  2346.       WHEN crt_and_disk =>
  2347.         INTEGER_IO.PUT(item) ;
  2348.         INTEGER_IO.PUT(debug_output_file, item) ;
  2349.         TEXT_IO.NEW_LINE ;
  2350.         TEXT_IO.NEW_LINE(debug_output_file) ;
  2351.       WHEN none =>
  2352.         NULL ;
  2353.     END CASE ;
  2354.   EXCEPTION
  2355.     WHEN OTHERS =>
  2356.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.PUT_LINE(I)") ;
  2357.       RAISE ;
  2358.   END put_line ;
  2359.   PROCEDURE put_line_byte (item : IN bit_count_8_type) IS
  2360.   BEGIN
  2361.     debug_io.put('<') ;
  2362.     debug_io.put(bit_count_16_type(item)) ;
  2363.     debug_io.put_line('>') ;
  2364.   EXCEPTION
  2365.     WHEN OTHERS =>
  2366.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.PUT_LINE(B)") ;
  2367.       RAISE ;
  2368.   END put_line_byte ;
  2369.   PROCEDURE open_debug_disk_file IS
  2370.   BEGIN
  2371.     TEXT_IO.CREATE (debug_output_file, output_file, debug_filename) ;
  2372.     the_debug_disk_file_is_open := TRUE ;
  2373.   EXCEPTION
  2374.     WHEN OTHERS =>
  2375.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.OPEN_DDF") ;
  2376.       RAISE ;
  2377.   END open_debug_disk_file ;
  2378.   PROCEDURE close_debug_disk_file IS
  2379.   BEGIN
  2380.     TEXT_IO.CLOSE(debug_output_file) ;
  2381.     the_debug_disk_file_is_open := FALSE ;
  2382.   EXCEPTION
  2383.     WHEN OTHERS =>
  2384.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN DEBUG_IO.CLOSE_DDF") ;
  2385.       RAISE ;
  2386.   END close_debug_disk_file ;
  2387.   FUNCTION debug_disk_file_is_open RETURN BOOLEAN IS
  2388.   BEGIN
  2389.     RETURN the_debug_disk_file_is_open ;
  2390.   END debug_disk_file_is_open ;
  2391. BEGIN -- package body
  2392.   NULL ;
  2393. EXCEPTION
  2394.   WHEN OTHERS =>
  2395.     debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN debugio instantiation") ;
  2396.     RAISE ;
  2397. END debug_io ;
  2398. --::::::::::::::
  2399. --idebugso.txt
  2400. --::::::::::::::
  2401. -----------------------------------------------------------------------
  2402. --
  2403. --         DoD Protocols    NA-00009-200       80-01209-100(-)
  2404. --         E-Systems, Inc.  August 07, 1985
  2405. --
  2406. --         idebugso.txt       Author : Mike Thomas
  2407. --
  2408. -----------------------------------------------------------------------
  2409. -- File : idebugso     
  2410. --   5/23/85  11:55 AM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS
  2411. --                       OLD CODE (TELESOFT) MARKED AS --&MT 
  2412. --   7/16/85   2:21 PM : mods for telesoft for wicat
  2413. -- INTERACTIVE DEBUG STATE OUTPUT FOR TN TEST/DEBUG
  2414. WITH user_data ;
  2415. USE  user_data ;
  2416. PACKAGE I_debug_state_output IS
  2417.   PROCEDURE print_ppl_trans_buffers    (ucb : IN control_block_type) ;
  2418.   PROCEDURE print_telnet_option_tables (ucb : IN control_block_type) ;
  2419.   PROCEDURE print_user_control_block   (ucb : IN control_block_type) ; 
  2420.   PROCEDURE dump_all                   (ucb : IN control_block_type) ;
  2421.   --    print_ppl_trans_buffers ;
  2422.   --    print_telnet_option_tables ;
  2423.   --    print_user_control_block ;
  2424. END I_debug_state_output ; -- spec
  2425. --   5/23/85  11:59 AM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS 
  2426. --                       OLD CODE (TELESOFT) MARKED AS --&MT 
  2427. --   7/16/85   2:21 PM : mods for telesoft for wicat
  2428. -- INTERACTIVE DEBUG STATE OUTPUT FOR TN TEST/DEBUG
  2429. WITH SYSTEM ; -- access ascii characters
  2430. WITH debug_io ; -- writes info to a debug file and/or the CRT.
  2431. PACKAGE BODY I_debug_state_output IS
  2432.   SUBTYPE bit_count_32_type IS LONG_INTEGER ; 
  2433.   --&MT SUBTYPE bit_count_32_type IS INTEGER ;
  2434.   SUBTYPE bit_count_16_type IS INTEGER ; 
  2435.   --&MT SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  2436.   SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  2437.   --&MT SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  2438.   PROCEDURE print_ppl_trans_buffers (ucb : IN control_block_type) IS 
  2439.   BEGIN
  2440.     debug_io.put_line(' ') ;
  2441.     debug_io.put_line("PPL TRANSPORT LEVEL BUFFERS.") ;
  2442.     debug_io.put_line("----------------------------") ;
  2443.   
  2444.   
  2445.     DECLARE
  2446.       in_buf     : trans_to_telnet_messages_record RENAMES 
  2447.                    ucb.trans_buffers.trans_to_telnet_messages ;
  2448.       head       : trans_to_telnet_msg_buf_ptr_type := in_buf.buf_head ;
  2449.       tail       : trans_to_telnet_msg_buf_ptr_type := in_buf.buf_tail ;
  2450. --&MT       buf_length : CONSTANT bit_count_32_type := 
  2451. --&MT        bit_count_32_type(trans_to_telnet_msg_buffer_length) ;
  2452.       buf_length : CONSTANT bit_count_16_type := 
  2453.       bit_count_16_type(trans_to_telnet_msg_buffer_length) ;
  2454.       out_buf    : STRING(1..buf_length) ;
  2455.       --&MT out_ptr    : bit_count_32_type RANGE 0..buf_length := 0 ;
  2456.       out_ptr    : bit_count_16_type RANGE 0..buf_length := 0 ;
  2457.       char_byte  : bit_count_8_type ;
  2458.     BEGIN
  2459.       debug_io.put_line(' ') ;
  2460.       debug_io.put_line("TRANS TO TELNET MESSAGE BUFFER") ;
  2461.       debug_io.put("head=") ;
  2462.       debug_io.put(head) ;
  2463.       debug_io.put("  tail=") ;
  2464.       debug_io.put_line(tail) ;
  2465.       WHILE (head + 1) MOD bit_count_16_type(buf_length) /= tail LOOP
  2466.         head := (head + 1) MOD bit_count_16_type(buf_length) ;
  2467.         char_byte := in_buf.buffer(head) ;
  2468.         IF bit_count_16_type(char_byte) >= bit_count_16_type(16#20#)
  2469.          AND bit_count_16_type(char_byte) < bit_count_16_type(16#7F#) THEN
  2470.           out_ptr := out_ptr + 1 ;
  2471.           out_buf(out_ptr) := CHARACTER'VAL(char_byte) ;
  2472.         ELSE
  2473.           debug_io.put(out_buf(1..out_ptr)) ;
  2474.           out_ptr := 0 ;
  2475.           debug_io.put('<') ;
  2476.           debug_io.put_byte(char_byte) ;
  2477.           debug_io.put('>') ;
  2478.         END IF ;
  2479.       END LOOP ;
  2480.       debug_io.put_line(out_buf(1..out_ptr)) ;
  2481.     EXCEPTION
  2482.       WHEN OTHERS =>
  2483.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN IDEBUGSO.TR TO TN MSG BUF") ;
  2484.         RAISE ;
  2485.     END ;    
  2486.   
  2487.     DECLARE
  2488.       in_buf     : trans_to_telnet_data_record RENAMES 
  2489.                    ucb.trans_buffers.trans_to_telnet_data ;
  2490.       head       : trans_to_telnet_data_buf_ptr_type := in_buf.buf_head ;
  2491.       tail       : trans_to_telnet_data_buf_ptr_type := in_buf.buf_tail ;
  2492. --&MT       buf_length : CONSTANT bit_count_32_type := 
  2493. --&MT        bit_count_32_type(trans_to_telnet_data_buffer_length) ;
  2494.       buf_length : CONSTANT bit_count_16_type :=
  2495.        bit_count_16_type(trans_to_telnet_data_buffer_length) ;
  2496.       out_buf    : STRING(1..buf_length) ;
  2497.       --&MT out_ptr    : bit_count_32_type RANGE 0..buf_length := 0 ;
  2498.       out_ptr    : bit_count_16_type RANGE 0..buf_length := 0 ;
  2499.       char_byte  : bit_count_8_type ;
  2500.     BEGIN
  2501.       debug_io.put_line(' ') ;
  2502.       debug_io.put_line("TRANS TO TELNET DATA BUFFER") ;
  2503.       debug_io.put("head=") ;
  2504.       debug_io.put(head) ;
  2505.       debug_io.put("  tail=") ;
  2506.       debug_io.put_line(tail) ;
  2507.       WHILE (head + 1) MOD bit_count_16_type(buf_length) /= tail LOOP
  2508.         head := (head + 1) MOD bit_count_16_type(buf_length) ;
  2509.         char_byte := in_buf.buffer(head) ;
  2510.         IF bit_count_16_type(char_byte) >= bit_count_16_type(16#20#)
  2511.          AND bit_count_16_type(char_byte) < bit_count_16_type(16#7F#) THEN -- printable
  2512.           out_ptr := out_ptr + 1 ;
  2513.           out_buf(out_ptr) := CHARACTER'VAL(char_byte) ;
  2514.         ELSE
  2515.           debug_io.put(out_buf(1..out_ptr)) ;
  2516.           out_ptr := 0 ;
  2517.           debug_io.put('<') ;
  2518.           debug_io.put_byte(char_byte) ;
  2519.           debug_io.put('>') ;
  2520.         END IF ;
  2521.       END LOOP ;
  2522.       debug_io.put_line(out_buf(1..out_ptr)) ;
  2523.     EXCEPTION
  2524.       WHEN OTHERS =>
  2525.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN IDEBUGSO.TR TO TN DATA BUF") ;
  2526.         RAISE ;
  2527.     END ;    
  2528.     
  2529.   END print_ppl_trans_buffers ;
  2530.   
  2531.   PROCEDURE print_telnet_option_tables (ucb : IN control_block_type) IS 
  2532.     ot : option_tables_type 
  2533.      RENAMES ucb.option_tables ;
  2534.     PROCEDURE print_items_in_table
  2535.               --------------------
  2536.      (table : IN user_data.option_table_type) IS
  2537.     BEGIN
  2538.       FOR index IN 1..table.number_of_items LOOP 
  2539.         CASE table.option(index) IS
  2540.           WHEN user_data.echo =>
  2541.             debug_io.put(" echo ") ;
  2542.           WHEN user_data.suppress_ga =>
  2543.             debug_io.put(" suppress_ga ") ;
  2544.           WHEN OTHERS =>
  2545.             debug_io.put("undefined item") ;
  2546.         END CASE ;  
  2547.       END LOOP ;
  2548.     END print_items_in_table ;
  2549.       
  2550.   BEGIN
  2551.     debug_io.put_line(' ') ;
  2552.     debug_io.put_line("TELNET OPTION TABLES") ;
  2553.     debug_io.put_line("--------------------") ;
  2554.   
  2555.     debug_io.put_line(' ') ;
  2556.     debug_io.put("local options desired : ") ;
  2557.     print_items_in_table(ot.local_options_desired) ;
  2558.     debug_io.put_line(' ') ;
  2559.   
  2560.     debug_io.put_line(' ') ;
  2561.     debug_io.put("remote options desired : ") ;
  2562.     print_items_in_table(ot.remote_options_desired) ;
  2563.     debug_io.put_line(' ') ;
  2564.          
  2565.     debug_io.put_line(' ') ;
  2566.     debug_io.put("local options pending : ") ;
  2567.     print_items_in_table(ot.local_options_pending) ;
  2568.     debug_io.put_line(' ') ;
  2569.   
  2570.     debug_io.put_line(' ') ;
  2571.     debug_io.put("remote options pending : ") ;
  2572.     print_items_in_table(ot.remote_options_pending) ; 
  2573.     debug_io.put_line(' ') ;
  2574.   
  2575.     debug_io.put_line(' ') ;
  2576.     debug_io.put("local options in effect : ") ;
  2577.     print_items_in_table(ot.local_options_in_effect) ;
  2578.     debug_io.put_line(' ') ;
  2579.   
  2580.     debug_io.put_line(' ') ;
  2581.     debug_io.put("remote options in effect : ") ;
  2582.     print_items_in_table(ot.remote_options_in_effect) ;
  2583.     debug_io.put_line(' ') ;
  2584.   EXCEPTION
  2585.     WHEN OTHERS =>
  2586.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN IDEBUGSO.PRNT OPT TABS") ;
  2587.       RAISE ;
  2588.   END print_telnet_option_tables ;
  2589.   
  2590.   
  2591.   PROCEDURE print_user_control_block (ucb : IN control_block_type) IS 
  2592.   BEGIN
  2593.     debug_io.put_line(' ') ;
  2594.     debug_io.put_line("USER CONTROL BLOCK.") ;
  2595.     debug_io.put_line("------------------") ;
  2596.     debug_io.put_line(' ') ;
  2597.   
  2598.     DECLARE -- partial command buffer
  2599.       length : CONSTANT partial_command_buf_length := 
  2600.        ucb.partial_command_buffer.length ;
  2601.       --&MT max_buf_length : CONSTANT bit_count_32_type := 
  2602.       --&MT  bit_count_32_type(max_cmd_length) ;
  2603.       max_buf_length : CONSTANT bit_count_16_type :=
  2604.        bit_count_16_type(max_cmd_length) ;
  2605.       out_buf : STRING(1..max_buf_length) ;
  2606.       --&MT out_ptr : bit_count_32_type RANGE 0..max_buf_length := 0 ;
  2607.       out_ptr : bit_count_16_type RANGE 0..max_buf_length := 0 ;
  2608.       char_byte  : bit_count_8_type ;
  2609.     BEGIN
  2610.       debug_io.put_line("APL partial command buffer.") ;
  2611.       debug_io.put("length=") ;
  2612.       debug_io.put_line(length) ;
  2613.       FOR index IN 1..length LOOP
  2614.         char_byte := ucb.partial_command_buffer.buffer(index) ;
  2615.         IF bit_count_16_type(char_byte) >= bit_count_16_type(16#20#)
  2616.           AND bit_count_16_type(char_byte) < bit_count_16_type(16#7F#) THEN -- printable
  2617.           out_ptr := out_ptr + 1 ;
  2618.           out_buf(out_ptr) := CHARACTER'VAL(char_byte) ;
  2619.         ELSE -- print ascii code #
  2620.           debug_io.put(out_buf(1..out_ptr)) ;
  2621.           out_ptr := 0 ;
  2622.           debug_io.put('<') ;
  2623.           debug_io.put_byte(char_byte) ;
  2624.           debug_io.put('>') ;
  2625.         END IF ;
  2626.       END LOOP ; 
  2627.       debug_io.put_line(out_buf(1..bit_count_16_type(length))) ;
  2628.       --&MT debug_io.put_line(out_buf(1..bit_count_32_type(length))) ;
  2629.     
  2630.     EXCEPTION
  2631.       WHEN OTHERS =>
  2632.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN IDEBUGSO.PART_CMD_BUF") ;
  2633.         RAISE ;
  2634.     END ;
  2635.   
  2636.   
  2637.     DECLARE -- data buffer
  2638.       head : data_buf_ptr := ucb.data_buffer.buf_head ;
  2639.       tail : data_buf_ptr := ucb.data_buffer.buf_tail ;
  2640. --&MT       buf_length : CONSTANT bit_count_32_type := 
  2641. --&MT        bit_count_32_type(data_buffer_length) ;
  2642.       buf_length : CONSTANT bit_count_16_type :=
  2643.        bit_count_16_type(data_buffer_length) ;
  2644.       out_buf    : STRING(1..buf_length) ;
  2645.       --&MT out_ptr    : bit_count_32_type RANGE 0..buf_length := 0 ;
  2646.       out_ptr    : bit_count_16_type RANGE 0..buf_length := 0 ;
  2647.       char_byte  : bit_count_8_type ;
  2648.     BEGIN
  2649.       debug_io.put_line(' ') ;
  2650.       debug_io.put_line("APL data buffer.") ;
  2651.       debug_io.put("head=") ;
  2652.       debug_io.put(head) ;
  2653.       debug_io.put("  tail=") ;
  2654.       debug_io.put_line(tail) ;
  2655.       WHILE (head + 1) MOD bit_count_16_type(buf_length) /= tail LOOP
  2656.         head := (head + 1) MOD bit_count_16_type(buf_length) ;
  2657.         char_byte := ucb.data_buffer.buffer(head) ;
  2658.         IF bit_count_16_type(char_byte) >= bit_count_16_type(16#20#)
  2659.          AND bit_count_16_type(char_byte) < bit_count_16_type(16#7F#) THEN -- printable
  2660.           out_ptr := out_ptr + 1 ;
  2661.           out_buf(out_ptr) := CHARACTER'VAL(char_byte) ;
  2662.         ELSE
  2663.           debug_io.put(out_buf(1..out_ptr)) ;
  2664.           out_ptr := 0 ;
  2665.           debug_io.put('<') ;
  2666.           debug_io.put_byte(char_byte) ;
  2667.           debug_io.put('>') ;
  2668.         END IF ;
  2669.       END LOOP ;
  2670.       debug_io.put_line(out_buf(1..out_ptr)) ;
  2671.     EXCEPTION
  2672.       WHEN OTHERS =>
  2673.         debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN IDEBUGSO.DATA_BUF") ;
  2674.         RAISE ;
  2675.     END ;
  2676.   
  2677.     
  2678.   -- state information
  2679.     debug_io.put_line(' ') ;
  2680.     debug_io.put_line("STATE INFORMATION.") ;
  2681.     debug_io.put_line("------------------") ;
  2682.     debug_io.put_line(' ') ;
  2683.     debug_io.put("port=") ;
  2684.     debug_io.put_line(ucb.port) ;
  2685.     debug_io.put("tl_port_number=") ;
  2686.     debug_io.put_line(ucb.tl_port_number) ;
  2687.     debug_io.put("nvt_io_state = ") ;
  2688.     IF ucb.nvt_io_state = IO_done THEN
  2689.       debug_io.put_line("io_done") ;
  2690.     ELSIF ucb.nvt_io_state = no_IO_done THEN
  2691.       debug_io.put_line("no_io_done") ;
  2692.     ELSE
  2693.       debug_io.put_line("*UNDEFINED*") ;
  2694.     END IF ;
  2695.   
  2696.     debug_io.put("communication_state = ") ;
  2697.     IF ucb.communication_state = connection_established THEN
  2698.       debug_io.put_line("connection_established") ;
  2699.     ELSIF ucb.communication_state = no_connection_established THEN
  2700.       debug_io.put_line("no_connection_established") ;
  2701.     ELSE
  2702.       debug_io.put_line("*UNDEFINED*") ;
  2703.     END IF ;
  2704.   
  2705.   
  2706.     debug_io.put("command_state = ") ;
  2707.     IF ucb.command_state = partial_command THEN
  2708.       debug_io.put_line("partial_command") ;
  2709.     ELSIF ucb.command_state = no_partial_command THEN
  2710.       debug_io.put_line("no_partial_command") ;
  2711.     ELSE
  2712.       debug_io.put_line("*UNDEFINED*") ;
  2713.     END IF ;
  2714.   
  2715.   
  2716.     debug_io.put("ga_state = ") ;
  2717.     IF ucb.ga_state = go_ahead_sent THEN
  2718.       debug_io.put_line("go_ahead_sent") ;
  2719.     ELSIF ucb.ga_state = no_go_ahead_sent THEN
  2720.       debug_io.put_line("no_go_ahead_sent") ;
  2721.     ELSE
  2722.       debug_io.put_line("*UNDEFINED*") ;
  2723.     END IF ;
  2724.     debug_io.put("ga_received = ") ;
  2725.     IF ucb.ga_received = TRUE THEN
  2726.       debug_io.put_line("go_ahead_received") ;
  2727.     ELSIF ucb.ga_received = FALSE THEN
  2728.       debug_io.put_line("no_go_ahead_received") ;
  2729.     ELSE
  2730.       debug_io.put_line("*UNDEFINED*") ;
  2731.     END IF ;
  2732.     debug_io.put("synch_is_in_progress = ") ;
  2733.     IF ucb.synch_is_in_progress = TRUE THEN
  2734.       debug_io.put_line("synch_is_in_progress") ;
  2735.     ELSIF ucb.synch_is_in_progress = FALSE THEN
  2736.       debug_io.put_line("no_synch_is_in_progress") ;
  2737.     ELSE
  2738.       debug_io.put_line("*UNDEFINED*") ;
  2739.     END IF ;
  2740.     debug_io.put("last_keybd_char_was_cmd = ") ;
  2741.     IF ucb.last_keybd_char_was_cmd = TRUE THEN
  2742.       debug_io.put_line("TRUE") ;
  2743.     ELSIF ucb.synch_is_in_progress = FALSE THEN
  2744.       debug_io.put_line("FALSE") ;
  2745.     ELSE
  2746.       debug_io.put_line("*UNDEFINED*") ;
  2747.     END IF ;
  2748.     debug_io.put("rcv_data_is_urgent = ") ;
  2749.     IF ucb.rcv_data_is_urgent = TRUE THEN
  2750.       debug_io.put_line("TRUE") ;
  2751.     ELSIF ucb.rcv_data_is_urgent = FALSE THEN
  2752.       debug_io.put_line("FALSE") ;
  2753.     ELSE
  2754.       debug_io.put_line("*UNDEFINED*") ;
  2755.     END IF ;
  2756.     debug_io.put("last_data_char_rcv_not_cr = ") ;
  2757.     IF ucb.last_data_char_rcv_not_cr = TRUE THEN
  2758.       debug_io.put_line("TRUE") ;
  2759.     ELSIF ucb.last_data_char_rcv_not_cr = FALSE THEN
  2760.       debug_io.put_line("FALSE") ;
  2761.     ELSE
  2762.       debug_io.put_line("*UNDEFINED*") ;
  2763.     END IF ;
  2764.   
  2765.   EXCEPTION
  2766.     WHEN OTHERS =>
  2767.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN IDEBUGSO.PRINT UCB") ;
  2768.       RAISE ;
  2769.   END print_user_control_block ;
  2770.   
  2771.   PROCEDURE dump_all (ucb : IN control_block_type) IS
  2772.   BEGIN
  2773.     debug_io.put_line(' ') ;
  2774.     debug_io.put_line
  2775.      (".......................... dump all start ......................") ;
  2776.     debug_io.put_line(' ') ;
  2777.     print_ppl_trans_buffers(ucb) ;
  2778.     print_telnet_option_tables(ucb) ;
  2779.     print_user_control_block(ucb) ;
  2780.     debug_io.put_line(' ') ;
  2781.     debug_io.put_line
  2782.      ("eeeeeeeeeeeeeeeeeeeeeeeee  dump all end   eeeeeeeeeeeeeeeeeeeeee") ;
  2783.     debug_io.put_line(' ') ;
  2784.   EXCEPTION
  2785.     WHEN OTHERS =>
  2786.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN IDEBUGSO.DUMP ALL") ;
  2787.       RAISE ;
  2788.   END dump_all ;
  2789. BEGIN
  2790.   NULL ;
  2791. EXCEPTION
  2792.   WHEN OTHERS =>
  2793.     debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN IDEBUGSO.TR TO TN MSG BUF") ;
  2794. RAISE ;
  2795. END I_debug_state_output ;
  2796.  
  2797. --::::::::::::::
  2798. --poptngpac.txt
  2799. --::::::::::::::
  2800. -----------------------------------------------------------------------
  2801. --
  2802. --         DoD Protocols    NA-00009-200       80-01210-100(-)
  2803. --         E-Systems, Inc.  August 07, 1985
  2804. --
  2805. --         poptngpac.txt       Author : Mike Thomas
  2806. --
  2807. -----------------------------------------------------------------------
  2808. -- File poptngpac
  2809. --   5/7/85  1:50 PM : MODIFY FOR DEC ADA         AUTHOR : MIKE THOMAS
  2810. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  2811. --   7/1/85  1:28 PM : remove status variable from request calls
  2812. --  7/16/85  2:29 PM : mods for telesoft wicat 
  2813. WITH user_data ;
  2814. USE  user_data ; --&MT added this to help with handling of enumerated types
  2815. WITH SYSTEM ; -- access system.byte
  2816. PACKAGE option_negotiation -- specification
  2817.         ------------------
  2818.  IS
  2819.   --*********************  USER SPECIFICATION  ********************************
  2820.   --
  2821.   -- This package will have routines to negotiate the transfer syntax and 
  2822.   -- virtual resource characteristics.  A procedure will negotiate initial
  2823.   -- options.  Additionally, procedures can be called to explicitly request 
  2824.   -- option enable or demand option disable of a particular option at any time.
  2825.   -- **************************************************************************
  2826. -- NOTE : This compiles OK but does not work properly during runtime.
  2827. -- so get directly from user_data until on a real ADA compiler
  2828. --  SUBTYPE ppl_option_type IS user_data.option_type ;
  2829.   SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  2830.   --&MT SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  2831.   PROCEDURE request_local_option_enable -- specification
  2832.             ---------------------------
  2833.    (option : IN user_data.option_type) ;
  2834.   -- ************************  USER SPECIFICATION  ****************************
  2835.   --
  2836.   -- If the connection is established and the option is not already in effect,
  2837.   -- this procedure will negotiate for that option.  If there is no connection
  2838.   -- established, the desirable option tables will be updated and TELNET
  2839.   -- PPL will try to negotiate these options at the establishment of a new 
  2840.   -- connection.  
  2841.   -----------------------------------------------------------------------------
  2842.      
  2843.   PROCEDURE demand_local_option_disable -- specification
  2844.             ---------------------------
  2845.    (option : IN user_data.option_type) ;
  2846.   -- ************************  USER SPECIFICATION  ****************************
  2847.   --
  2848.   -- If the connection is established and the option is already in effect,
  2849.   -- this procedure will negotiate the cessation of that option.  If there is
  2850.   -- no connection established, the desirable option tables will be updated 
  2851.   -- and TELNET PPL will not try to negotiate this option at the establishment 
  2852.   -- of a new connection.  
  2853.   -----------------------------------------------------------------------------
  2854.   PROCEDURE request_remote_option_enable -- specification
  2855.             ----------------------------
  2856.    (option : IN user_data.option_type) ;
  2857.   -- ************************  USER SPECIFICATION  ****************************
  2858.   --
  2859.   -- If the connection is established and the option is not already in effect,
  2860.   -- this procedure will negotiate for that option.  If there is no connection
  2861.   -- established, the desirable option tables will be updated and TELNET PPL
  2862.   -- will try to negotiate these options at the establishment of a new 
  2863.   -- connection.  
  2864.   -----------------------------------------------------------------------------
  2865.      
  2866.      
  2867.   PROCEDURE demand_remote_option_disable -- specification
  2868.             ----------------------------
  2869.    (option : IN user_data.option_type) ;
  2870.   -- ************************  USER SPECIFICATION  ****************************
  2871.   --
  2872.   -- If the connection is established and the option is already in effect,
  2873.   -- this procedure will negotiate the cessation of that option.  If there is
  2874.   -- no connection established, the desirable option tables will be updated 
  2875.   -- and TELNET PPL will not try to negotiate this option at the establishment 
  2876.   -- of a new connection.  
  2877.   -----------------------------------------------------------------------------
  2878.   PROCEDURE negotiate_initial_desired_options ; -- specification 
  2879.             ---------------------------------
  2880.   -- ************************  USER SPECIFICATION  ****************************
  2881.   --
  2882.   -- This procedure will use the information contained in the desirable 
  2883.   -- options tables to negotiate options with the remote TELNET.
  2884.   -----------------------------------------------------------------------------
  2885.   PROCEDURE remote_will_received  -- specification
  2886.             -------------------- 
  2887.    (option_code : IN bit_count_8_type) ;   
  2888.   -- *************************  USER SPECIFICATION  ***************************
  2889.   --
  2890.   -- This procedure will inform the option negotiation subprograms that a 
  2891.   -- WILL (option) was received from the remote TELNET.
  2892.   -------------------------------------------------------------------------
  2893.   PROCEDURE remote_wont_received  -- specification
  2894.             -------------------- 
  2895.    (option_code : IN bit_count_8_type) ;   
  2896.   -- *************************  USER SPECIFICATION  ***************************
  2897.   --
  2898.   -- This procedure will inform the option negotiation subprograms that a 
  2899.   -- WONT (option) was received from the remote TELNET.
  2900.   -------------------------------------------------------------------------
  2901.   PROCEDURE remote_do_received  -- specification
  2902.             ------------------ 
  2903.    (option_code : IN bit_count_8_type) ;   
  2904.   -- *************************  USER SPECIFICATION  ***************************
  2905.   --
  2906.   -- This procedure will inform the option negotiation subprograms that a 
  2907.   -- DO (option) was received from the remote TELNET.
  2908.   -------------------------------------------------------------------------
  2909.   PROCEDURE remote_dont_received  -- specification
  2910.             -------------------- 
  2911.    (option_code : IN bit_count_8_type) ;   
  2912.   -- *************************  USER SPECIFICATION  ***************************
  2913.   --
  2914.   -- This procedure will inform the option negotiation subprograms that a 
  2915.   -- DONT (option) was received from the remote TELNET.
  2916.   -------------------------------------------------------------------------
  2917. END option_negotiation ; -- package specification
  2918.  
  2919.  
  2920. -- File poptngpac
  2921. --   7-1-85  1:32 PM : remove status var from requests
  2922. --           5:46 PM : fix bug in option negotiation disable,dont,wont
  2923. --  7/16/85  2:29 PM : mods for telesoft wicat 
  2924. WITH debug_io ;
  2925. WITH virtual_transport_level ;
  2926. --&MT WITH dec_tn_tasks ;--&MT not user in telesoft
  2927. PACKAGE BODY option_negotiation IS
  2928.              ------------------
  2929.   SUBTYPE bit_count_16_type IS INTEGER ; 
  2930.   --&MT SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  2931.   TYPE action_type IS (tn_will, tn_wont, tn_do, tn_dont) ;
  2932.   TYPE action_code_array_type IS ARRAY(action_type) OF bit_count_8_type ;
  2933.   TYPE option_code_array_type IS ARRAY(user_data.option_type) OF bit_count_8_type ;
  2934.   action_kind : action_type ;
  2935.   action_code : action_code_array_type ;-- aggregate asignment not implimented
  2936.   option_code : option_code_array_type ;-- during decl.(do assign in body part)
  2937.   echo : user_data.option_type ; -- TeleSoft-Ada can't do assign here
  2938.   suppress_ga : user_data.option_type ; -- ditto
  2939.   IAC : CONSTANT bit_count_8_type := 255 ; -- interprate as command code
  2940.   option_tables            : user_data.option_tables_type RENAMES 
  2941.    user_data.user_control_block.option_tables ;
  2942.   local_options_desired    : user_data.option_table_type RENAMES
  2943.    option_tables.local_options_desired ;
  2944.   local_options_in_effect  : user_data.option_table_type RENAMES
  2945.    option_tables.local_options_in_effect ;
  2946.   local_options_pending    : user_data.option_table_type RENAMES
  2947.    option_tables.local_options_pending ;
  2948.   remote_options_desired   : user_data.option_table_type RENAMES
  2949.    option_tables.remote_options_desired ;
  2950.   remote_options_in_effect : user_data.option_table_type RENAMES
  2951.    option_tables.remote_options_in_effect ;   
  2952.   remote_options_pending   : user_data.option_table_type RENAMES
  2953.    option_tables.remote_options_pending ;
  2954.   PROCEDURE store_message (message : IN STRING) IS -- (local procedure)
  2955.             -------------
  2956.     tl_msg : user_data.trans_to_telnet_messages_record RENAMES
  2957.      user_data.user_control_block.trans_buffers.trans_to_telnet_messages ;
  2958.     msg_buf_length : CONSTANT bit_count_16_type := 
  2959.      user_data.trans_to_telnet_msg_buffer_length ;
  2960.   BEGIN
  2961.     FOR index IN 1..message'LENGTH LOOP
  2962.       tl_msg.buffer(tl_msg.buf_tail) := 
  2963.        bit_count_8_type(CHARACTER'POS(message(index))) ;
  2964.       tl_msg.buf_tail := (tl_msg.buf_tail + 1) MOD msg_buf_length ;
  2965.     END LOOP ;
  2966.     tl_msg.buffer(tl_msg.buf_tail) := 10 ; -- ascii.lf
  2967.     tl_msg.buf_tail := (tl_msg.buf_tail + 1) MOD msg_buf_length ;
  2968.     tl_msg.buffer(tl_msg.buf_tail) := 13 ; -- ascii.cr
  2969.     tl_msg.buf_tail := (tl_msg.buf_tail + 1) MOD msg_buf_length ;
  2970. --&MT     dec_tn_tasks.tn.go ; -- make sure message gets out --&MT (dec only)
  2971.     EXCEPTION
  2972.       WHEN OTHERS =>
  2973.         DEBUG_IO.PUT_LINE("@@@ EXCEPTION IN POPTNGPAC.STORE_MESSAGE") ;
  2974.         RAISE ;
  2975.   END store_message ;
  2976.   PROCEDURE send_option 
  2977.             -----------
  2978.    (action : IN action_type ;
  2979.     option : IN user_data.option_type) IS
  2980.     data : virtual_transport_level.info_output_type(1..3) ;
  2981.   BEGIN
  2982.     data(1) := IAC ;
  2983.     data(2) := action_code(action) ;
  2984.     data(3) := option_code(option) ;
  2985.     virtual_transport_level.send_data(data, FALSE) ;
  2986.   EXCEPTION
  2987.     WHEN OTHERS =>
  2988.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.send_option(o)") ;
  2989.       RAISE ;
  2990.   END send_option ;
  2991.   PROCEDURE send_option 
  2992.             -----------
  2993.    (action      : IN action_type ;
  2994.     option_code : IN bit_count_8_type) IS
  2995.     data : virtual_transport_level.info_output_type(1..3) ;
  2996.   BEGIN
  2997.     data(1) := IAC ;
  2998.     data(2) := action_code(action) ;
  2999.     data(3) := option_code ;
  3000.     virtual_transport_level.send_data(data, FALSE) ;
  3001.   EXCEPTION
  3002.     WHEN OTHERS =>
  3003.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.send_option(c)") ;
  3004.       RAISE ;
  3005.   END send_option ;
  3006.   PROCEDURE send_message
  3007.             ------------
  3008.    (message : IN STRING) IS
  3009.     tl_message : virtual_transport_level.info_output_type(1..message'LENGTH) ;
  3010.   BEGIN
  3011.     FOR index IN message'RANGE LOOP -- convert to system.byte
  3012.       tl_message(bit_count_16_type(index)) :=
  3013.        bit_count_8_type(CHARACTER'POS(message(index))) ;
  3014.     END LOOP ;
  3015.     virtual_transport_level.send_message(tl_message) ;
  3016.   EXCEPTION
  3017.     WHEN OTHERS =>
  3018.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.send_message") ;
  3019.       RAISE ;
  3020.   END send_message ;
  3021.   FUNCTION option_in_table
  3022.            ---------------
  3023.    (table  : IN user_data.option_table_type ;
  3024.     option : IN user_data.option_type) RETURN BOOLEAN IS
  3025.   BEGIN
  3026.     FOR index IN 1..table.number_of_items LOOP
  3027.       IF table.option(bit_count_16_type(index)) = option THEN
  3028.         RETURN TRUE ;
  3029.       END IF ;
  3030.     END LOOP ;
  3031.     RETURN FALSE ;
  3032.   END option_in_table ;
  3033.   FUNCTION local_option_already_in_effect_or_being_negotiated
  3034.            --------------------------------------------------
  3035.    (option : IN user_data.option_type) RETURN BOOLEAN IS
  3036.   BEGIN
  3037.     IF option_in_table(local_options_in_effect, option)THEN RETURN TRUE ;END IF ;
  3038.     IF option_in_table(local_options_pending, option) THEN RETURN TRUE ; END IF ;
  3039.     RETURN FALSE ;
  3040.   END local_option_already_in_effect_or_being_negotiated ;
  3041.   FUNCTION remote_option_already_in_effect_or_being_negotiated
  3042.            ---------------------------------------------------
  3043.    (option : IN user_data.option_type) RETURN BOOLEAN IS
  3044.   BEGIN
  3045.     IF option_in_table(remote_options_in_effect,option) THEN RETURN TRUE ;END IF;
  3046.     IF option_in_table(remote_options_pending, option) THEN RETURN TRUE ;END IF ;
  3047.     RETURN FALSE ;
  3048.   END remote_option_already_in_effect_or_being_negotiated ;
  3049.   PROCEDURE add_option_to_table -- no check for overflow or duplication
  3050.             -------------------
  3051.    (table  : IN OUT user_data.option_table_type ;
  3052.     option : IN     user_data.option_type) IS
  3053.   BEGIN
  3054.     table.number_of_items := table.number_of_items + 1 ;
  3055.     table.option(table.number_of_items) := option ;
  3056.   EXCEPTION
  3057.     WHEN OTHERS =>
  3058.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.add_option_") ;
  3059.       RAISE ;
  3060.   END add_option_to_table ;
  3061.   PROCEDURE delete_option_from_table
  3062.             ------------------------
  3063.    (table  : IN OUT user_data.option_table_type ;
  3064.     option : IN     user_data.option_type) IS -- dedicated to Evanne
  3065.     save_index : bit_count_16_type RANGE 0..user_data.number_of_options_supported := 0 ;
  3066.   BEGIN
  3067.     FOR index IN 1..table.number_of_items LOOP
  3068.       IF table.option(bit_count_16_type(index)) /= option THEN
  3069.         save_index := save_index + 1 ;
  3070.         table.option(save_index) := table.option(index) ;
  3071.       END IF ;
  3072.     END LOOP ;
  3073.     table.number_of_items := save_index ;
  3074.   EXCEPTION
  3075.     WHEN OTHERS =>
  3076.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.delete_option_") ;
  3077.       RAISE ;
  3078.   END delete_option_from_table ;
  3079.   PROCEDURE request_local_option_enable -- body
  3080.             ---------------------------
  3081.    (option : IN  user_data.option_type) IS
  3082.   -- ************************  BODY SPECIFICATION  ****************************
  3083.   --
  3084.   -- If the connection is established and the option is not already in effect,
  3085.   -- this procedure will negotiate for that option.  Otherwise, the desirable
  3086.   -- option tables will be updated and TELNET PPL will try to negotiate these 
  3087.   -- options at the establishment of a new connection.
  3088.   -----------------------------------------------------------------------------
  3089.   BEGIN
  3090.     IF (user_data.user_control_block.communication_state =
  3091.      user_data.connection_established) AND 
  3092.      (NOT(local_option_already_in_effect_or_being_negotiated(option))) THEN
  3093.         action_kind := tn_will ;
  3094.         send_option(action_kind, option) ;
  3095.         add_option_to_table(local_options_pending, option) ;
  3096.     ELSE 
  3097.       add_option_to_table(local_options_desired, option) ;
  3098.     END IF ; 
  3099.   EXCEPTION
  3100.     WHEN OTHERS =>
  3101.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.rloe") ;
  3102.       RAISE ;
  3103.   END request_local_option_enable ; -- body
  3104.      
  3105.      
  3106.   PROCEDURE demand_local_option_disable -- body
  3107.             ---------------------------
  3108.    (option : IN user_data.option_type) IS 
  3109.   -- ************************  BODY SPECIFICATION  ****************************
  3110.   --
  3111.   -- If the connection is established and the option is already in effect,
  3112.   -- this procedure will negotiate the cessation of that 
  3113.   -- option.  If there is no connection established, the desirable option 
  3114.   -- tables will be updated and TELNET PPL will not try to negotiate this 
  3115.   -- option at the establishment of a new connection.  
  3116.   -----------------------------------------------------------------------------
  3117.   BEGIN
  3118.     IF (user_data.user_control_block.communication_state =
  3119.      user_data.connection_established) AND 
  3120.      option_in_table(local_options_in_effect, option) THEN
  3121.        action_kind := tn_wont ;
  3122.        send_option(action_kind, option) ;
  3123.        add_option_to_table(local_options_pending, option) ;
  3124.     ELSE 
  3125.       delete_option_from_table(local_options_desired, option) ;
  3126.     END IF ; 
  3127.   EXCEPTION
  3128.     WHEN OTHERS =>
  3129.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.dlod") ;
  3130.       RAISE ;
  3131.   END demand_local_option_disable ; -- body
  3132.   PROCEDURE request_remote_option_enable -- body
  3133.             ----------------------------
  3134.    (option : IN user_data.option_type) IS
  3135.   -- ************************  BODY SPECIFICATION  ****************************
  3136.   --
  3137.   -- If the connection is established and the option is not already in effect,
  3138.   -- this procedure will negotiate for that option.  Otherwise, the desirable 
  3139.   -- option tables will be updated and TELNET PPL will try to negotiate these 
  3140.   -- options at the establishment of a new connection.
  3141.   -----------------------------------------------------------------------------
  3142.   BEGIN 
  3143.     IF (user_data.user_control_block.communication_state =
  3144.      user_data.connection_established) AND 
  3145.      (NOT(remote_option_already_in_effect_or_being_negotiated(option))) THEN
  3146.         action_kind := tn_do ;
  3147.         send_option(action_kind, option) ;
  3148.         add_option_to_table(remote_options_pending, option) ;
  3149.     ELSE -- add to desired options table
  3150.       add_option_to_table(remote_options_desired, option) ;
  3151.     END IF ; -- not (in effect or in negotiation)
  3152.   EXCEPTION
  3153.     WHEN OTHERS =>
  3154.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.rroe") ;
  3155.       RAISE ;
  3156.   END request_remote_option_enable ; -- body
  3157.      
  3158.      
  3159.   PROCEDURE demand_remote_option_disable -- body
  3160.             ----------------------------
  3161.    (option : IN user_data.option_type) IS 
  3162.   -- ************************  BODY SPECIFICATION  ****************************
  3163.   --
  3164.   -- If the connection is established and the option is already in effect,
  3165.   -- this procedure will negotiate the cessation of that 
  3166.   -- option.  If there is no connection established, the desirable option 
  3167.   -- tables will be updated and TELNET PPL will not try to negotiate this 
  3168.   -- option at the establishment of a new connection.  
  3169.   -----------------------------------------------------------------------------
  3170.   BEGIN
  3171.     IF (user_data.user_control_block.communication_state =
  3172.      user_data.connection_established) AND 
  3173.      option_in_table(remote_options_in_effect, option) THEN
  3174.        action_kind := tn_dont ;
  3175.        send_option(action_kind, option) ;
  3176.        add_option_to_table(remote_options_pending, option) ;
  3177.     ELSE 
  3178.       delete_option_from_table(remote_options_desired, option) ;
  3179.     END IF ; 
  3180.   EXCEPTION
  3181.     WHEN OTHERS =>
  3182.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.drod") ;
  3183.       RAISE ;
  3184.   END demand_remote_option_disable ; -- body
  3185.   PROCEDURE negotiate_initial_desired_options -- body
  3186.             ---------------------------------
  3187.    IS
  3188.     -- ************************  BODY SPECIFICATION  **************************
  3189.     --
  3190.     -- This procedure will use the information contained in the desirable 
  3191.     -- options tables to negotiate initial options with the remote TELNET 
  3192.     -- connection.
  3193.     --
  3194.     -- Processing sequence... 
  3195.     -- Check the table of remote options that are desired for the other end 
  3196.     -- and send a DO OPTION --- through the connection for each.  Check the 
  3197.     -- table of local options desirable on this end and send a WILL OPTION --- 
  3198.     -- through the connection for each.
  3199.     ---------------------------------------------------------------------------
  3200.  
  3201.   BEGIN -- negotiate initial options procedure body
  3202.     action_kind := tn_do ;
  3203.     FOR index IN 1..remote_options_desired.number_of_items LOOP
  3204.       request_remote_option_enable
  3205.        (remote_options_desired.option(index)) ;
  3206.     END LOOP ;
  3207.     action_kind := tn_will ;
  3208.     FOR index IN 1..local_options_desired.number_of_items LOOP
  3209.       request_local_option_enable(local_options_desired.option(index)) ;
  3210.     END LOOP ;
  3211.   EXCEPTION
  3212.     WHEN OTHERS =>
  3213.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.nido") ;
  3214.       RAISE ;
  3215.   END negotiate_initial_desired_options ; -- procedure body
  3216.   PROCEDURE remote_will_received  -- body
  3217.             -------------------- 
  3218.    (option_code : IN bit_count_8_type) IS
  3219.   -- *************************  BODY SPECIFICATION  ***************************
  3220.   --
  3221.   -- If the option code is not supported, send a don't for the unknown code;
  3222.   -- otherwize process the option in the following manner.
  3223.   -- If we already asked for this option(in remote_options_pending table) then
  3224.   -- add it to the remote_options_in_effect table and remove it from the 
  3225.   -- remote pending options table.
  3226.   -- Otherwize, if the option is in the remote_options_desired table then "ack"
  3227.   -- it and add it to the remote_options_in_effect table.
  3228.   -- If the above conditions were not met, then refuse to allow the option 
  3229.   -- and "ack" it if required(option not in remote_option_pending table) or
  3230.   -- simply remove it from the remote_options_pending table if no "ack"
  3231.   -- is neccessary.   
  3232.   -----------------------------------------------------------------------------
  3233.   BEGIN
  3234.     CASE option_code IS
  3235.       WHEN 1 => -- echo : note both sides cannot echo at once(=> loop forever)
  3236.         -- see RFC 857 for information on the TELNET echo option
  3237.         IF option_in_table(remote_options_pending, echo) AND 
  3238.          (NOT(option_in_table(local_options_in_effect, echo))) THEN
  3239.           delete_option_from_table(remote_options_pending, echo) ;
  3240.           add_option_to_table(remote_options_in_effect, echo) ;
  3241.           store_message("$@$ remote echo option in effect $@$") ;
  3242.         ELSIF option_in_table(remote_options_desired, echo) AND 
  3243.          (NOT(option_in_table(local_options_in_effect, echo))) THEN
  3244.           add_option_to_table(remote_options_in_effect, echo) ;
  3245.           store_message("$@$ remote echo option in effect $@$") ;
  3246.           action_kind := tn_do ;
  3247.           send_option(action_kind, echo) ;
  3248.         ELSE -- check if negative ack required
  3249.           store_message("$@$ remote echo option denied by local Telnet $@$") ;
  3250.           IF option_in_table(remote_options_pending, echo) THEN -- no ack
  3251.              delete_option_from_table(remote_options_pending, echo) ;
  3252.           ELSE -- send negative ack
  3253.             action_kind := tn_dont ;
  3254.             send_option(action_kind, echo) ;
  3255.           END IF ;
  3256.         END IF ;
  3257.       WHEN 3 => -- suppress go ahead
  3258.         -- see RFC 858 for information on the TELNET suppress ga option
  3259.         IF option_in_table(remote_options_pending, suppress_ga) THEN
  3260.           delete_option_from_table(remote_options_pending, suppress_ga) ;
  3261.           add_option_to_table(remote_options_in_effect, suppress_ga) ;
  3262.           store_message("$@$ remote suppress_ga option in effect $@$") ;
  3263.         ELSIF option_in_table(remote_options_desired, suppress_ga) THEN 
  3264.           add_option_to_table(remote_options_in_effect, suppress_ga) ;
  3265.           store_message("$@$ remote suppress_ga option in effect $@$") ;
  3266.           action_kind := tn_do ;
  3267.           send_option(action_kind, suppress_ga) ;
  3268.         ELSE -- check if negative ack required
  3269.           store_message("$@$ remote suppress_ga option denied by local Telnet $@$") ;
  3270.           IF option_in_table(remote_options_pending, suppress_ga) THEN -- no ack
  3271.             delete_option_from_table(remote_options_pending, suppress_ga) ;
  3272.           ELSE -- send negative ack
  3273.             action_kind := tn_dont ;
  3274.             send_option(action_kind, suppress_ga) ;
  3275.           END IF ;
  3276.         END IF ;
  3277.       WHEN OTHERS => -- not supported, refuse offer
  3278.         action_kind := tn_dont ;
  3279.         send_option(action_kind, option_code) ;
  3280.     END CASE ;
  3281.   EXCEPTION
  3282.     WHEN OTHERS =>
  3283.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.rwillr") ;
  3284.       RAISE ;
  3285.   END remote_will_received ;
  3286.   PROCEDURE remote_wont_received  -- body
  3287.             -------------------- 
  3288.    (option_code : IN bit_count_8_type) IS
  3289.   -- *************************  BODY SPECIFICATION  ***************************
  3290.   --
  3291.   -- If the code is suported then process as follows...
  3292.   -- If the option was requested remotly(item in remote_options_in_effect table
  3293.   -- and item not in remote_options_pending) then ack the wont with a dont. 
  3294.   -- Remove the item from the romote_options_pending / in_effect tables
  3295.   -----------------------------------------------------------------------------
  3296.   BEGIN
  3297.     CASE option_code IS
  3298.       WHEN 1 => -- ECHO
  3299.         -- see RFC 857 for information on the TELNET echo option
  3300.         store_message("$@$ remote echo option denied by remote $@$") ;
  3301.         IF (option_in_table(remote_options_in_effect, echo)) AND 
  3302.          (NOT(option_in_table(remote_options_pending, echo))) THEN -- ack
  3303.           action_kind := tn_dont ; -- ack
  3304.           send_option(action_kind, echo) ;
  3305.         END IF ;
  3306.         delete_option_from_table(remote_options_in_effect, echo) ;
  3307.         delete_option_from_table(remote_options_pending, echo) ;
  3308.       WHEN 3 => -- SUPPRESS_GA
  3309.         -- see RFC 858 for information on the TELNET suppress_ga option
  3310.         store_message("$@$ remote suppress_ga option denied by remote $@$") ;
  3311.         IF option_in_table(remote_options_in_effect, suppress_ga) AND
  3312.          (NOT(option_in_table(remote_options_pending, suppress_ga))) THEN -- ack
  3313.           action_kind := tn_dont ; -- ack
  3314.           send_option(action_kind, suppress_ga) ;
  3315.         END IF ;
  3316.         delete_option_from_table(remote_options_in_effect, suppress_ga) ;
  3317.         delete_option_from_table(remote_options_pending, suppress_ga) ;
  3318.       WHEN OTHERS => -- not supported, refuse offer
  3319.         NULL ;
  3320.     END CASE ;
  3321.   EXCEPTION
  3322.     WHEN OTHERS =>
  3323.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.rwontr") ;
  3324.       RAISE ;
  3325.   END remote_wont_received ;
  3326.   PROCEDURE remote_do_received  -- body
  3327.             ------------------ 
  3328.    (option_code : IN bit_count_8_type) IS  
  3329.   -- *************************  BODY SPECIFICATION  ***************************
  3330.   --
  3331.   -- If the option code is not supported, send a don't for the unknown code;
  3332.   -- otherwize process the option in the following manner.
  3333.   -- If we already asked for this option(in remote_options_pending table) then
  3334.   -- add it to the remote_options_in_effect table and remove it from the 
  3335.   -- remote pending options table.
  3336.   -- Otherwize, if the option is in the remote_options_desired table then "ack"
  3337.   -- it and add it to the remote_options_in_effect table.
  3338.   -- If the above conditions were not met, then refuse to allow the option 
  3339.   -- and "ack" it if required(option not in remote_option_pending table) or
  3340.   -- simply remove it from the remote_options_pending table if no "ack"
  3341.   -- is neccessary.   
  3342.   -----------------------------------------------------------------------------
  3343.   BEGIN
  3344.     CASE option_code IS
  3345.       WHEN 1 => -- echo : note both sides cannot echo at once(=> loop forever)
  3346.         -- see RFC 857 for information on the TELNET echo option
  3347.         IF option_in_table(local_options_pending, echo) AND 
  3348.          (NOT(option_in_table(remote_options_in_effect, echo))) THEN
  3349.            delete_option_from_table(local_options_pending, echo) ;
  3350.           add_option_to_table(local_options_in_effect, echo) ;
  3351.           store_message("$@$ local echo option in effect $@$") ;
  3352.         ELSIF option_in_table(local_options_desired, echo) AND 
  3353.          (NOT(option_in_table(remote_options_in_effect, echo))) THEN
  3354.           add_option_to_table(local_options_in_effect, echo) ;
  3355.           action_kind := tn_will ;
  3356.           send_option(action_kind, echo) ;
  3357.           store_message("$@$ local echo option in effect $@$") ;
  3358.         ELSE -- check if negative ack required
  3359.           store_message("$@$ local echo option denied by local telnet $@$") ;
  3360.           IF option_in_table(remote_options_pending, echo) THEN
  3361.              delete_option_from_table(local_options_pending, echo) ;
  3362.           ELSE -- send negative ack
  3363.             action_kind := tn_wont ;
  3364.             send_option(action_kind, echo) ;
  3365.           END IF ;
  3366.         END IF ;
  3367.       WHEN 3 => -- suppress_ga
  3368.         -- see RFC 858 for information on the TELNET supress_ga option
  3369.         IF option_in_table(local_options_pending, suppress_ga) THEN
  3370.           delete_option_from_table(local_options_pending, suppress_ga) ;
  3371.           add_option_to_table(local_options_in_effect, suppress_ga) ;
  3372.           store_message("$@$ local suppress_ga option in effect $@$") ;
  3373.         ELSIF option_in_table(local_options_desired, suppress_ga) THEN
  3374.           store_message("$@$ local suppress_ga option in effect $@$") ;
  3375.           add_option_to_table(local_options_in_effect, suppress_ga) ;
  3376.           action_kind := tn_will ;
  3377.           send_option(action_kind, suppress_ga) ;
  3378.         ELSE -- check if negative ack required
  3379.           store_message("$@$ local suppress_ga option denied by local telnet $@$") ;
  3380.           IF option_in_table(remote_options_pending, suppress_ga) THEN
  3381.             delete_option_from_table(local_options_pending, suppress_ga) ;
  3382.           ELSE -- send negative ack
  3383.             action_kind := tn_wont ;
  3384.             send_option(action_kind, suppress_ga) ;
  3385.           END IF ;
  3386.         END IF ;
  3387.       WHEN OTHERS => -- not supported, refuse offer
  3388.         action_kind := tn_wont ;
  3389.         send_option(action_kind, option_code) ;
  3390.     END CASE ;
  3391.   EXCEPTION
  3392.     WHEN OTHERS =>
  3393.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.rdor") ;
  3394.       RAISE ;
  3395.   END remote_do_received  ;
  3396.   PROCEDURE remote_dont_received  -- body
  3397.             -------------------- 
  3398.    (option_code : IN bit_count_8_type) IS 
  3399.   -- *************************  BODY SPECIFICATION  ***************************
  3400.   --
  3401.   -- If the code is suported then process as follows...
  3402.   -- If the option was requested remotly(item in local_options_in_effect table
  3403.   -- and item not in local_options_pending) then ack the dont with a wont. 
  3404.   -- Remove the item from the local_options_pending / in_effect tables
  3405.   -----------------------------------------------------------------------------
  3406.   BEGIN
  3407.     CASE option_code IS
  3408.       WHEN 1 => -- echo
  3409.         -- see RFC 857 for information on the TELNET echo option
  3410.         store_message("$@$ local echo option denied by remote $@$") ;
  3411.         IF option_in_table(local_options_in_effect, echo) AND
  3412.          (NOT(option_in_table(local_options_pending, echo))) THEN -- ack
  3413.           action_kind := tn_wont ; -- ack
  3414.           send_option(action_kind, echo) ;
  3415.         END IF ;
  3416.         delete_option_from_table(local_options_in_effect, echo) ;
  3417.         delete_option_from_table(local_options_pending, echo) ;
  3418.       WHEN 3 => -- suppress_ga
  3419.         -- see RFC 858 for information on the TELNET suppress_ga
  3420.         store_message("$@$ local suppress_ga option denied by remote $@$") ;
  3421.         IF option_in_table(local_options_in_effect, suppress_ga) AND
  3422.          (NOT(option_in_table(local_options_pending, suppress_ga))) THEN -- ack
  3423.           action_kind := tn_wont ; -- ack
  3424.           send_option(action_kind, suppress_ga) ;
  3425.         END IF ;
  3426.         delete_option_from_table(local_options_in_effect, suppress_ga) ;
  3427.         delete_option_from_table(local_options_pending, suppress_ga) ;
  3428.       WHEN OTHERS => -- should not get this
  3429.         NULL ;
  3430.     END CASE ;
  3431.   EXCEPTION
  3432.     WHEN OTHERS =>
  3433.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac.rdontr") ;
  3434.       RAISE ;
  3435.   END remote_dont_received  ;
  3436.      
  3437. BEGIN -- option_negotiation body
  3438.   echo := user_data.echo ; -- TeleSoft won't init this in declaration
  3439.   suppress_ga := user_data.suppress_ga ; -- ditto
  3440. -- packed agregates not impleminted yet
  3441. --  action_code := (251, 252, 253, 254) ; -- RFC 854 page 14
  3442. --  option_code := (1) ; -- RFC 857 page 1 (code for echo)
  3443.   action_code(tn_will) := 251 ;
  3444.   action_code(tn_wont) := 252 ;
  3445.   action_code(tn_do)   := 253 ;
  3446.   action_code(tn_dont) := 254 ;
  3447.   option_code(echo)        := 1 ;
  3448.   option_code(suppress_ga) := 3 ;
  3449.   EXCEPTION
  3450.     WHEN OTHERS =>
  3451.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN poptngpac instantiation") ;
  3452.       RAISE ;
  3453. END option_negotiation ; -- package_body
  3454. --::::::::::::::
  3455. --pvirtlpac.txt
  3456. --::::::::::::::
  3457. -----------------------------------------------------------------------
  3458. --
  3459. --         DoD Protocols    NA-00009-200       80-01211-100(-)
  3460. --         E-Systems, Inc.  August 07, 1985
  3461. --
  3462. --         pvirtlpac.txt       Author : Mike Thomas
  3463. --
  3464. -----------------------------------------------------------------------
  3465.  
  3466. WITH with_ulp_communicate ;
  3467. USE  with_ulp_communicate ;
  3468. WITH with_tcp_communicate ;
  3469. USE  with_tcp_communicate ;
  3470. WITH t_tcp_globals_data_structures ;
  3471. USE  t_tcp_globals_data_structures ;
  3472. WITH buffer_data ;
  3473. USE  buffer_data ;
  3474. WITH  user_data ;
  3475. WITH SYSTEM ;
  3476. USE  SYSTEM ;
  3477. PACKAGE virtual_transport_level IS
  3478.   SUBTYPE bit_count_32_type IS LONG_INTEGER ; 
  3479.   
  3480.   SUBTYPE bit_count_16_type IS INTEGER ; 
  3481.   
  3482.   SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  3483.   
  3484.   TYPE transport_level_service_call_type IS 
  3485.    (TL_open, TL_send, TL_receive, TL_close, TL_status, TL_abort) ;
  3486.   max_msg_length : CONSTANT bit_count_16_type := 256 ; 
  3487.   TYPE message_type IS ARRAY (1..max_msg_length) OF bit_count_8_type ;
  3488.   TYPE info_output_type IS ARRAY (bit_count_16_type RANGE <>) OF bit_count_8_type ;  
  3489.   SUBTYPE input_type IS bit_count_8_type ;
  3490.   TYPE service_call_parameters_type
  3491.    (service_call : transport_level_service_call_type) IS
  3492.     RECORD
  3493.       CASE service_call IS
  3494.         WHEN TL_send =>
  3495.           urgent_flag : BOOLEAN ;
  3496.           info_length : bit_count_16_type RANGE 1..max_msg_length ;
  3497.           info        : info_output_type(1..max_msg_length) ;
  3498.         WHEN TL_open =>
  3499.           network_number      : bit_count_16_type := 10 ; 
  3500.           host_number         : bit_count_16_type := 0 ; 
  3501.           logical_host_number : bit_count_16_type := 0 ; 
  3502.           imp_number          : bit_count_16_type := 0 ; 
  3503.           port_number         : bit_count_16_type := 23 ;
  3504.         WHEN OTHERS =>
  3505.           NULL ;
  3506.        END CASE ;
  3507.      END RECORD ;
  3508.   
  3509.   FUNCTION there_is_a_message  
  3510.            
  3511.    RETURN BOOLEAN ;
  3512.  
  3513.   FUNCTION there_is_input  
  3514.            
  3515.    RETURN BOOLEAN ;
  3516.     
  3517.     
  3518.   PROCEDURE get_message 
  3519.             
  3520.    (message : OUT message_type ;
  3521.     length  : OUT bit_count_16_type) ;
  3522.     
  3523.   PROCEDURE get_input 
  3524.             
  3525.    (input           : OUT input_type ;
  3526.     tcp_urgent_flag : OUT BOOLEAN) ;
  3527.   
  3528.   
  3529.   FUNCTION there_is_room_for_info_output 
  3530.            
  3531.    RETURN BOOLEAN ;
  3532.   
  3533.   PROCEDURE send_data 
  3534.             
  3535.    (data : IN info_output_type ;
  3536.     urgent_flag : IN BOOLEAN) ;
  3537.   
  3538.   
  3539.   PROCEDURE send_message 
  3540.             
  3541.    (message : IN info_output_type) ;
  3542.   
  3543.   
  3544.   PROCEDURE convert_service_call_to_transport_level_syntax 
  3545.             
  3546.    (service_call : IN transport_level_service_call_type ;
  3547.     parameter   : IN service_call_parameters_type) ;
  3548.     
  3549. END virtual_transport_level ; 
  3550. WITH debug_io ;
  3551. PACKAGE BODY virtual_transport_level IS 
  3552.              
  3553.   message_from_tcp : user_message ;
  3554.   lcn : tcb_ptr RENAMES
  3555.    user_data.user_control_block.lcn ;
  3556.   tl_data_is_urgent : BOOLEAN RENAMES
  3557.    user_data.user_control_block.rcv_data_is_urgent ; 
  3558.   
  3559.   last_char_was_not_cr : BOOLEAN RENAMES
  3560.   user_data.user_control_block.last_data_char_rcv_not_cr ; 
  3561.   lcn_record : tcb_ptr ;
  3562.   FUNCTION there_is_information_from_the_transport_level
  3563.            
  3564.    RETURN BOOLEAN IS
  3565.     message_ready : BOOLEAN ;
  3566.   BEGIN
  3567.     message_from_tcp.lcn := lcn ;
  3568.     wait_for_tcp_message(message_from_tcp) ; 
  3569.     IF message_from_tcp.message_number = -1 THEN
  3570.       RETURN FALSE ;
  3571.     END IF ;
  3572.     RETURN TRUE ;
  3573.   END there_is_information_from_the_transport_level ;
  3574.   PROCEDURE store_message (message : IN STRING) IS 
  3575.             
  3576.     tl_msg : user_data.trans_to_telnet_messages_record RENAMES
  3577.      user_data.user_control_block.trans_buffers.trans_to_telnet_messages ;
  3578.     msg_buf_length : CONSTANT bit_count_16_type := 
  3579.      user_data.trans_to_telnet_msg_buffer_length ;
  3580.   BEGIN
  3581.     debug_io.put_line("  in pvirtlpac.store_message(s)") ;
  3582.     debug_io.put("message ==>") ;
  3583.     debug_io.put_line(message(1..message'LENGTH)) ;
  3584.     FOR index IN 1..message'LENGTH LOOP
  3585.       tl_msg.buffer(tl_msg.buf_tail) := 
  3586.        bit_count_8_type(CHARACTER'POS(message(index))) ;
  3587.       tl_msg.buf_tail := (tl_msg.buf_tail + 1) MOD msg_buf_length ;
  3588.     END LOOP ;
  3589.       tl_msg.buffer(tl_msg.buf_tail) := 13 ; 
  3590.       tl_msg.buf_tail := (tl_msg.buf_tail + 1) MOD msg_buf_length ;
  3591.     debug_io.put_line("  end pvirtlpac.store_message(s)") ;
  3592.     EXCEPTION
  3593.       WHEN OTHERS =>
  3594.         DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.STORE_MESSAGE(s)") ;
  3595.         RAISE ;
  3596.   END store_message ;
  3597.   PROCEDURE get_and_process_information_from_the_transport_level IS
  3598.             
  3599.     PROCEDURE store_message (number : IN bit_count_32_type) IS
  3600.               
  3601.       digit : bit_count_16_type RANGE 0..9 ;
  3602.       num   : bit_count_32_type := number ;
  3603.       number_string : STRING (1..20) ;
  3604.       
  3605.       num_digits : bit_count_16_type RANGE 0..19 := 0 ;
  3606.     BEGIN
  3607.       debug_io.put_line("  in pvirtlpac.store_message(i)") ;
  3608.       IF number > 0 THEN
  3609.         WHILE num > 0 LOOP
  3610.           debug_io.put("number=") ;
  3611.           debug_io.put_line(bit_count_16_type(number)) ;
  3612.           digit := bit_count_16_type(num - (num/bit_count_32_type(10)) * bit_count_32_type(10)) ; 
  3613.           debug_io.put("digit=") ;
  3614.           debug_io.put_line(digit) ;
  3615.           num := num / bit_count_32_type(10) ;
  3616.           number_string(20 - num_digits) := CHARACTER'VAL(digit+16#30#) ;
  3617.           debug_io.put("digit_char =") ;
  3618.           debug_io.put_line(number_string(20 - num_digits)) ;
  3619.           num_digits := num_digits + 1 ;
  3620.           debug_io.put("num_digits=") ;
  3621.           debug_io.put_line(bit_count_16_type(num_digits)) ;
  3622.         END LOOP ;
  3623.         number_string(1..num_digits) := number_string(21-num_digits..20) ;
  3624.       ELSE
  3625.         num_digits := 1 ;
  3626.         number_string(1) := '0' ;
  3627.       END IF ; 
  3628.       debug_io.put("number_string(1..num_digits)=") ;
  3629.       debug_io.put_line(number_string(1..num_digits)) ;
  3630.       store_message(number_string(1..num_digits)) ;
  3631.       debug_io.put_line("  end pvirtlpac.store_message(i)") ;
  3632.     EXCEPTION 
  3633.       WHEN OTHERS =>
  3634.         DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.STORE_MESSAGE(i)") ;
  3635.         RAISE ;
  3636.     END store_message ;
  3637.     PROCEDURE do_passive_open  IS
  3638.               
  3639.       tcp_options         : tcp_option_type ;
  3640.       open_parameters     : open_params ;
  3641.       the_message_for_tcp : message ;
  3642.     BEGIN
  3643.       debug_io.put_line("in passive open routine") ;
  3644.       IF user_data.user_control_block.tl_port_number = 0 THEN 
  3645.         debug_io.put_line("will attempt passive open") ;
  3646.         FOR index IN 1..50 LOOP
  3647.           tcp_options(index) := 0 ;
  3648.         END LOOP ;
  3649.         open_parameters := (2, 
  3650.          0,0,with_tcp_communicate.passive,0,255,lcn_record,0,0,tcp_options) ;
  3651.         the_message_for_tcp := (with_tcp_communicate.open, open_parameters) ;
  3652.         message_for_tcp(the_message_for_tcp) ;
  3653.         lcn := the_message_for_tcp.open_parameters.lcn ;
  3654.       END IF ;
  3655.       debug_io.put_line("end passive open") ;
  3656.     END do_passive_open ;
  3657.   BEGIN
  3658.     debug_io.put_line("in vir_tl get_and_process_information...") ;
  3659.     debug_io.put("msg #=") ;
  3660.     debug_io.put_line(message_from_tcp.message_number) ;
  3661.     CASE message_from_tcp.message_number IS
  3662.       WHEN 2 => store_message("connection illegal") ;
  3663.       WHEN 3 => store_message("connection does not exist") ;
  3664.       WHEN 4 => store_message("foreign socket unpsecified") ;
  3665.       WHEN 5 => store_message("insufficient resources") ;
  3666.       WHEN 6 => store_message("connection closing") ; 
  3667.         user_data.user_control_block.communication_state := 
  3668.          user_data.no_connection_established ;
  3669.         DECLARE
  3670.           parameter : service_call_parameters_type(tl_close) ;
  3671.         BEGIN
  3672.           convert_service_call_to_transport_level_syntax(tl_close, parameter) ;
  3673.         END ;
  3674.       WHEN 7 => store_message("performing urgent data processing") ;
  3675.         tl_data_is_urgent := TRUE ;
  3676.       WHEN 8 => store_message("connection aborted") ;
  3677.         user_data.reset_user_control_block ; 
  3678.         do_passive_open ;
  3679.       WHEN 9 => store_message("precedence not allowed") ;
  3680.       WHEN 10 | 19 => 
  3681.         DECLARE 
  3682.           tl_data : user_data.trans_to_telnet_data_record RENAMES
  3683.            user_data.user_control_block.trans_buffers.trans_to_telnet_data ;
  3684.           data_buf_length : CONSTANT bit_count_16_type := 
  3685.            user_data.trans_to_telnet_data_buffer_length ;
  3686.           char_count : bit_count_16_type := 
  3687.            message_from_tcp.data_buffer.telnet_ptr -
  3688.            message_from_tcp.data_buffer.tcp_ptr ;
  3689.           cr : CONSTANT bit_count_8_type := 13 ; 
  3690.         BEGIN
  3691.           debug_io.put_line("data msg detected") ;
  3692.           debug_io.put("  telnet_ptr=") ;
  3693.           debug_io.put(message_from_tcp.data_buffer.telnet_ptr) ;
  3694.           debug_io.put("  tcp_ptr :=") ;
  3695.           debug_io.put_line(message_from_tcp.data_buffer.tcp_ptr) ;
  3696.           FOR index IN 0..char_count LOOP
  3697.             debug_io.put("  position =") ;
  3698.             debug_io.put(message_from_tcp.data_buffer.telnet_ptr - index) ;
  3699.             debug_io.put("  char_code =") ;
  3700.             debug_io.put_line_byte(message_from_tcp.data_buffer.byte
  3701.              (message_from_tcp.data_buffer.telnet_ptr - index)) ;
  3702.             IF last_char_was_not_cr THEN
  3703.               tl_data.buffer(tl_data.buf_tail) := 
  3704.                message_from_tcp.data_buffer.byte
  3705.                (message_from_tcp.data_buffer.telnet_ptr - index) ;
  3706.               tl_data.buf_tail := (tl_data.buf_tail + 1) MOD data_buf_length ;
  3707.               debug_io.put_line("stored") ;
  3708.             END IF ; 
  3709.             IF message_from_tcp.data_buffer.byte
  3710.              (message_from_tcp.data_buffer.telnet_ptr - index) = cr THEN
  3711.               last_char_was_not_cr := FALSE ;
  3712.             ELSE
  3713.               last_char_was_not_cr := TRUE ;
  3714.             END IF ;  
  3715.           END LOOP ;
  3716.           message_from_tcp.data_buffer.in_use := FALSE ;
  3717.           message_from_tcp.data_buffer.status := none ;
  3718.           buffree(message_from_tcp.data_buffer, 0) ; 
  3719.           
  3720.           DECLARE 
  3721.             packed_buffer : packed_buffer_ptr ;
  3722.             receive_data  : receive_params ;
  3723.             task_message  : message ;
  3724.           BEGIN 
  3725.             buffget(packed_buffer,1) ;
  3726.             IF packed_buffer = NULL THEN
  3727.               debug_io.put_line("Unable to get buffer for a receive.") ;
  3728.               store_message("Unable to get buffer for a receive.") ;
  3729.             ELSE
  3730.               packed_buffer.in_use := TRUE ;
  3731.               packed_buffer.status := owner_tcp ;
  3732.               lcn_record := message_from_tcp.lcn ;
  3733.               receive_data := (lcn_record, packed_buffer, 190) ;
  3734.               task_message := (receive, receive_data) ;
  3735.               message_for_tcp(task_message) ;
  3736.             END IF ; 
  3737.           END ; 
  3738.         END ; 
  3739.       WHEN 11 => store_message("security/compartment illegal") ;
  3740.       WHEN 12 => store_message("connection exists") ;
  3741.       WHEN 14 => 
  3742.         debug_io.put_line("return lcn msg detected") ;
  3743.         lcn := message_from_tcp.lcn ;
  3744.         
  3745.         DECLARE 
  3746.           packed_buffer : packed_buffer_ptr ;
  3747.           receive_data  : receive_params ;
  3748.           task_message  : message ;
  3749.         BEGIN 
  3750.           buffget(packed_buffer,1) ;
  3751.           IF packed_buffer = NULL THEN
  3752.             debug_io.put_line("Unable to get buffer for a receive.") ;
  3753.             store_message("Unable to get buffer for a receive.") ;
  3754.           ELSE
  3755.             lcn_record := message_from_tcp.lcn ;
  3756.             receive_data := (lcn_record, packed_buffer, 190) ;
  3757.             task_message := (receive, receive_data) ;
  3758.             message_for_tcp(task_message) ;
  3759.           END IF ; 
  3760.         END ; 
  3761.       WHEN 15 =>
  3762.        DECLARE
  3763.          listen : CONSTANT with_ulp_communicate.state_type :=
  3764.           with_ulp_communicate.listen ;
  3765.        BEGIN
  3766.         debug_io.put_line("status msg detected") ;
  3767.         store_message(" ") ;
  3768.         store_message("status information :") ;
  3769.         store_message(" ") ;
  3770.         store_message("source port=") ;
  3771.         store_message(bit_count_32_type(message_from_tcp.status_params.source_port)) ;
  3772.         store_message("source address=") ;
  3773.         store_message(bit_count_32_type(message_from_tcp.status_params.source_address)) ;
  3774.         store_message("destination address=") ; 
  3775.         store_message(bit_count_32_type(message_from_tcp.status_params.destination_address)) ;
  3776.         store_message("destination port=") ;
  3777.         store_message(bit_count_32_type(message_from_tcp.status_params.destination_port)) ;
  3778.         store_message("# of octets we can accept=") ;
  3779.         store_message(bit_count_32_type(message_from_tcp.status_params.local_rcv_window)) ;
  3780.         store_message("# of octets that can be sent=") ;
  3781.         store_message(bit_count_32_type(message_from_tcp.status_params.remote_rcv_window)) ;
  3782.         store_message("amount of data on retran q =") ;
  3783.         store_message(bit_count_32_type(message_from_tcp.status_params.octets_on_retransmit_queue)) ;
  3784.         store_message("amount of data waiting for us =") ;
  3785.         store_message(bit_count_32_type(message_from_tcp.status_params.data_waiting_for_ulp)) ;
  3786.         IF message_from_tcp.status_params.urgent_state THEN
  3787.           store_message("urgent state=true") ;
  3788.         ELSE
  3789.           store_message("urgent state=false") ;
  3790.         END IF ;
  3791.         store_message("precedence value=") ;
  3792.         store_message(bit_count_32_type(message_from_tcp.status_params.precedence)) ;
  3793.         store_message("user layer timeout=") ;
  3794.         store_message(bit_count_32_type(message_from_tcp.status_params.ulp_timeout)) ;
  3795.         store_message("security values=") ;
  3796.         FOR index IN 1..9 LOOP
  3797.           store_message(bit_count_32_type(message_from_tcp.status_params.security(index))) ;
  3798.         END LOOP ;
  3799.         IF message_from_tcp.status_params.status = 
  3800.          with_ulp_communicate.connection_open THEN
  3801.           store_message("connection open") ;
  3802.         ELSE
  3803.           store_message("connection closed") ;
  3804.         END IF ;
  3805.         store_message("message_from_tcp.status_params TCB state is") ;
  3806.         CASE message_from_tcp.status_params.connection_state IS
  3807.           WHEN closed                         => store_message("closed") ;
  3808.           WHEN listen                         => store_message("listen") ;
  3809.           WHEN syn_sent                       => store_message("syn_sent") ;
  3810.           WHEN syn_received                   => store_message("syn received") ;
  3811.           WHEN established                    => store_message("established") ;
  3812.           WHEN fin_wait_1                     => store_message("fin_wait_1") ;
  3813.           WHEN fin_wait_2                     => store_message("fin_wait_2") ;
  3814.           WHEN close_wait                     => store_message("close_wait") ;
  3815.           WHEN last_ack                       => store_message("last_ack") ;
  3816.           WHEN time_wait                      => store_message("time_wait") ;
  3817.           WHEN OTHERS                         => store_message("closing") ;
  3818.         END CASE ;
  3819.        END ; -- DECLARE
  3820.       WHEN 16 => store_message("connection reset by other host") ;
  3821.         user_data.reset_user_control_block ; 
  3822.         do_passive_open ;
  3823.       WHEN 17 => store_message("connection refused") ;
  3824.       WHEN 18 => store_message("connection closed") ;
  3825.         user_data.reset_user_control_block ; 
  3826.         do_passive_open ;
  3827.       WHEN 20 => store_message("out of buffers in a lower layer") ;
  3828.       WHEN 21 => store_message("unable to reset") ;
  3829.       WHEN 22 => store_message("the ip is currently overloaded") ;
  3830.       WHEN 23 => 
  3831.         debug_io.put_line("connection open msg detected") ;
  3832.         user_data.user_control_block.communication_state := 
  3833.          user_data.connection_established ;
  3834.         debug_io.put_line
  3835.          ("communication_state set to connection_established") ;
  3836.         store_message("connection open") ;
  3837.       WHEN 24 => store_message("error: connection aborted due to user time out") ;
  3838.         user_data.reset_user_control_block ; 
  3839.         do_passive_open ;
  3840.       WHEN OTHERS => 
  3841.         debug_io.put("unknown msg # detected ==>") ;
  3842.         debug_io.put_line(message_from_tcp.message_number) ;
  3843.     END CASE ;
  3844.     debug_io.put_line("end vir_tl get_and_process_information...") ;
  3845.   EXCEPTION 
  3846.     WHEN OTHERS =>
  3847.       DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.GET_AND_PROC_INFO") ;
  3848.       RAISE ;
  3849.   END get_and_process_information_from_the_transport_level ;
  3850.   FUNCTION there_is_a_message  
  3851.            
  3852.   RETURN BOOLEAN IS 
  3853.   
  3854.   
  3855.     message : user_data.trans_to_telnet_messages_record RENAMES
  3856.      user_data.user_control_block.trans_buffers.trans_to_telnet_messages ;
  3857.     buf_length : CONSTANT bit_count_16_type := 
  3858.      user_data.trans_to_telnet_msg_buffer_length ;
  3859.   BEGIN
  3860.     debug_io.put_line("in vir_tl there is a message") ;
  3861.     IF there_is_information_from_the_transport_level THEN
  3862.       debug_io.put_line("calling get&process because there is information") ;
  3863.       get_and_process_information_from_the_transport_level ;
  3864.     END IF ;
  3865.     debug_io.put_line("end vir_tl there is a message") ;
  3866.     RETURN (message.buf_head + 1) MOD buf_length /= message.buf_tail ;
  3867.   END there_is_a_message ; 
  3868.      
  3869.   FUNCTION there_is_input  
  3870.            
  3871.    RETURN BOOLEAN IS
  3872.   
  3873.   
  3874.     data : user_data.trans_to_telnet_data_record RENAMES
  3875.      user_data.user_control_block.trans_buffers.trans_to_telnet_data ;
  3876.     buf_length : CONSTANT bit_count_16_type := 
  3877.      user_data.trans_to_telnet_msg_buffer_length ;
  3878.   BEGIN
  3879.     debug_io.put_line("in vir_tl there is input") ;
  3880.     IF there_is_information_from_the_transport_level THEN
  3881.       debug_io.put_line("call get and process") ;
  3882.       get_and_process_information_from_the_transport_level ;
  3883.     END IF ;
  3884.     debug_io.put_line("end vir_tl there is input") ;
  3885.     RETURN (data.buf_head + 1) MOD buf_length /= data.buf_tail ;
  3886.   END there_is_input ; 
  3887.     
  3888.     
  3889.   PROCEDURE get_message 
  3890.             
  3891.    (message : OUT message_type ;
  3892.     length  : OUT bit_count_16_type) IS
  3893.     mess : user_data.trans_to_telnet_messages_record RENAMES
  3894.      user_data.user_control_block.trans_buffers.trans_to_telnet_messages ;
  3895.     buf_length : CONSTANT bit_count_16_type := 
  3896.      user_data.trans_to_telnet_msg_buffer_length ;
  3897.     there_is_more : BOOLEAN := TRUE ;
  3898.     message_length : bit_count_16_type ;
  3899.       
  3900.       
  3901.   BEGIN
  3902.     debug_io.put_line("in get message") ;
  3903.     message_length := 0 ;
  3904.       
  3905.     IF there_is_a_message THEN
  3906.       WHILE there_is_more LOOP
  3907.         mess.buf_head := (mess.buf_head + 1) MOD buf_length ;
  3908.         IF mess.buffer(mess.buf_head) = 16#0D# THEN 
  3909.           there_is_more := FALSE ;
  3910.         END IF ; 
  3911.         message_length := message_length + 1 ;
  3912.         message(message_length) := mess.buffer(mess.buf_head) ;
  3913.           
  3914.       END LOOP ; 
  3915.     END IF ; 
  3916.     length := message_length ;
  3917.     debug_io.put(" at end of get message... ") ;
  3918.   EXCEPTION 
  3919.     WHEN OTHERS =>
  3920.       DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.GET_MESSAGE") ;
  3921.       RAISE ;
  3922.   END get_message ; 
  3923.  
  3924.     
  3925.   PROCEDURE get_input 
  3926.             
  3927.    (input : OUT input_type ;
  3928.     tcp_urgent_flag : OUT BOOLEAN) IS 
  3929.     data : user_data.trans_to_telnet_data_record RENAMES
  3930.      user_data.user_control_block.trans_buffers.trans_to_telnet_data ;
  3931.     buf_length : CONSTANT bit_count_16_type := 
  3932.      user_data.trans_to_telnet_data_buffer_length ;
  3933.     there_is_more : BOOLEAN := TRUE ;
  3934.     temp_input : input_type ;
  3935.       
  3936.       
  3937.   BEGIN
  3938.     debug_io.put_line("pvirtlpac.get_input begin") ; 
  3939.     tcp_urgent_flag := tl_data_is_urgent ;
  3940.     IF there_is_input THEN
  3941.       data.buf_head := (data.buf_head + 1) MOD buf_length ;
  3942.       temp_input := data.buffer(data.buf_head);
  3943.         
  3944.       debug_io.put("input code =") ;
  3945.       debug_io.put_line_byte(temp_input) ;
  3946.         
  3947.     END IF ; 
  3948.     input := temp_input ;
  3949.     debug_io.put_line("pvirtlpac.get_input end") ;
  3950.     EXCEPTION 
  3951.       WHEN OTHERS =>
  3952.         DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.GET_INPUT") ;
  3953.         RAISE ;
  3954.   END get_input ; 
  3955.   FUNCTION there_is_room_for_info_output 
  3956.            
  3957.    RETURN BOOLEAN IS 
  3958.   BEGIN 
  3959.     RETURN TRUE ;
  3960.   END there_is_room_for_info_output ;
  3961.   PROCEDURE send_data 
  3962.             
  3963.    (data : IN info_output_type ;
  3964.     urgent_flag : IN BOOLEAN) IS
  3965.     parameter : service_call_parameters_type(TL_send) ; 
  3966.                                                        
  3967.   BEGIN 
  3968.     debug_io.put_line("begin vir_tl.send_data") ;
  3969.     parameter.urgent_flag := urgent_flag ;
  3970.     parameter.info_length := data'LENGTH ;
  3971.     FOR index IN data'RANGE LOOP       
  3972.      parameter.info(index) := data(index) ;
  3973.     END LOOP ;
  3974.     convert_service_call_to_transport_level_syntax(TL_send, parameter) ;
  3975.     debug_io.put_line("end vir_tl.send_data") ;
  3976.   EXCEPTION 
  3977.     WHEN OTHERS =>
  3978.       DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.SEND_DATA") ;
  3979.       RAISE ;
  3980.   END send_data ;
  3981.   PROCEDURE send_message 
  3982.             
  3983.    (message : IN info_output_type) IS
  3984.     parameter : service_call_parameters_type(TL_send) ;
  3985.                                                        
  3986.   BEGIN
  3987.     debug_io.put_line("begin vir_tl.send_message") ;
  3988.     parameter.urgent_flag := false ;
  3989.     parameter.info_length := message'LENGTH ;
  3990.     parameter.info(1..message'LENGTH) := message(1..message'LENGTH) ;
  3991.     convert_service_call_to_transport_level_syntax(TL_send, parameter) ;
  3992.     debug_io.put_line("end vir_tl.send_message") ;
  3993.   EXCEPTION 
  3994.     WHEN OTHERS =>
  3995.       DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.SEND_MESSAGE") ;
  3996.       RAISE ;
  3997.   END send_message ;
  3998.   PROCEDURE convert_service_call_to_transport_level_syntax 
  3999.             
  4000.    (service_call : IN transport_level_service_call_type ;
  4001.     parameter   : IN service_call_parameters_type) IS 
  4002.     the_message_for_tcp : message ;
  4003.   BEGIN 
  4004.     debug_io.put_line("begin vir_tl.convert_service call...") ;
  4005.     IF (service_call = tl_open) THEN                       
  4006.       debug_io.put_line("virt_tl processed open call to TCP") ;
  4007.       debug_io.put("network_number=") ;
  4008.       debug_io.put_line(parameter.network_number) ;
  4009.       debug_io.put("host_number=") ; 
  4010.       debug_io.put_line(parameter.host_number) ;
  4011.       debug_io.put("logical_host_number=") ; 
  4012.       debug_io.put_line(parameter.logical_host_number) ;
  4013.       debug_io.put("imp_number=") ; 
  4014.       debug_io.put_line(parameter.imp_number) ;
  4015.       debug_io.put("port_number=") ; 
  4016.       debug_io.put_line(parameter.port_number) ;
  4017.       DECLARE 
  4018.         foreign_net_host : bit_count_32_type ;
  4019.         options : tcp_option_type ;
  4020.         open_parameters : open_params ;
  4021.         FUNCTION calculate_class_a_address (net, imp, host : IN bit_count_16_type) 
  4022.          RETURN bit_count_32_type IS
  4023.         BEGIN
  4024.           RETURN bit_count_32_type(16#1000000#) * bit_count_32_type(net) 
  4025.                + bit_count_32_type(256) * bit_count_32_type(imp) 
  4026.                + bit_count_32_type(host) ; 
  4027.         END calculate_class_a_address ;
  4028.       BEGIN 
  4029.         user_data.user_control_block.tl_port_number := parameter.port_number ;
  4030.         FOR index IN 1..50 LOOP
  4031.           options(index) := 0 ; 
  4032.         END LOOP ;
  4033.         foreign_net_host := bit_count_32_type(parameter.logical_host_number) ; 
  4034.         lcn_record := lcn ;
  4035.         
  4036.         open_parameters := (parameter.imp_number, parameter.port_number, 
  4037.          foreign_net_host, with_tcp_communicate.active, 0, 15, lcn_record,
  4038.           0, 0, options) ;
  4039.         the_message_for_tcp := (with_tcp_communicate.open, open_parameters) ;
  4040.         message_for_tcp(the_message_for_tcp) ;
  4041.         lcn := the_message_for_tcp.open_parameters.lcn ; 
  4042.       END ; 
  4043.     ELSIF service_call = tl_send THEN                     
  4044.       debug_io.put_line("virt_tl processing send call to TCP") ;
  4045.       DECLARE
  4046.         packed_buffer  : packed_buffer_ptr ;
  4047.         send_data      : send_params ;
  4048.         tl_byte_count  : bit_count_16_type := parameter.info_length - 1 ;
  4049.         tl_push_flag   : CONSTANT bit_count_16_type := 1 ; 
  4050.         tl_urgent_flag : bit_count_16_type := 0 ; 
  4051.         tl_time_out    : CONSTANT bit_count_16_type := 15 ; 
  4052.         buffer_index   : bit_count_16_type := 0 ;
  4053.         cr             : CONSTANT bit_count_8_type := 13 ;
  4054.         lf             : CONSTANT bit_count_8_type := 10 ;
  4055.       
  4056.       BEGIN 
  4057.         debug_io.put_line("in pvirtlpac.send_data to tcp (actual tcp call)") ;
  4058.         IF parameter.info_length > 0 THEN 
  4059.           buffget(packed_buffer,1) ;
  4060.           IF packed_buffer = NULL THEN
  4061.             store_message("out of buffers") ;
  4062.           ELSE
  4063.             IF parameter.urgent_flag THEN tl_urgent_flag := 1 ; END IF ;
  4064.             FOR index IN 1..parameter.info_length LOOP
  4065.               packed_buffer.byte(packed_buffer.telnet_ptr - buffer_index) :=
  4066.                parameter.info(index) ;
  4067.               buffer_index := buffer_index + 1 ;
  4068.               debug_io.put("data code=") ;
  4069.               debug_io.put_line_byte(parameter.info(index)) ;
  4070.               IF parameter.info(index) = cr THEN 
  4071.                 packed_buffer.byte(packed_buffer.telnet_ptr - buffer_index) := lf ;
  4072.                 buffer_index := buffer_index + 1 ;
  4073.                 debug_io.put("data code=") ;
  4074.                 debug_io.put_byte(lf) ;
  4075.                 debug_io.put_line("  lf inserted") ;
  4076.               END IF ; 
  4077.             END LOOP ;
  4078.             lcn_record := lcn ;
  4079.             tl_byte_count := buffer_index - 1 ;
  4080.             packed_buffer.telnet_ptr := packed_buffer.telnet_ptr - tl_byte_count;
  4081.             packed_buffer.tcp_ptr := packed_buffer.telnet_ptr - 1 ;
  4082.             debug_io.put("tl_byte_count=") ;
  4083.             debug_io.put_line(tl_byte_count) ;
  4084.             debug_io.put("telnet_ptr=") ;
  4085.             debug_io.put_line(packed_buffer.telnet_ptr) ;
  4086.             debug_io.put("tcp_ptr=") ;
  4087.             debug_io.put_line(packed_buffer.tcp_ptr) ;
  4088.             send_data := (lcn_record, packed_buffer, tl_byte_count, 
  4089.              tl_push_flag, tl_urgent_flag, tl_time_out) ;
  4090.             the_message_for_tcp := (send, send_data) ;
  4091.             message_for_tcp(the_message_for_tcp) ;
  4092.           END IF ; 
  4093.         END IF ; 
  4094.       END ; 
  4095.       debug_io.put_line("end virt_tl processing send call to TCP") ;
  4096.     ELSIF service_call = tl_receive THEN               
  4097.       debug_io.put_line("virt_tl processed receive call to TCP") ;
  4098.     ELSIF service_call = tl_close THEN                
  4099.       debug_io.put_line("virt_tl processing close call to TCP") ;
  4100.       DECLARE
  4101.         close_params : abort_close_params ;
  4102.       BEGIN
  4103.         lcn_record := lcn ;
  4104.         close_params := (lcn => lcn_record) ;
  4105.         the_message_for_tcp := (with_tcp_communicate.close, close_params) ;
  4106.         message_for_tcp(the_message_for_tcp) ;
  4107.       END ; 
  4108.       debug_io.put_line("communication_state is no_connection_established") ;
  4109.     ELSIF service_call = tl_status THEN                
  4110.       debug_io.put_line("virt_tl processing status call to TCP") ;
  4111.       DECLARE
  4112.         status_data : status_params ;
  4113.       BEGIN
  4114.         lcn_record := lcn ;
  4115.         status_data := (lcn => lcn_record) ;
  4116.         the_message_for_tcp := (with_tcp_communicate.status, status_data) ;
  4117.         message_for_tcp(the_message_for_tcp) ;
  4118.       END ;
  4119.     ELSIF service_call = tl_abort THEN                  
  4120.       debug_io.put_line("virt_tl processing abort call to TCP") ;
  4121.       DECLARE
  4122.         abort_params : abort_close_params ;
  4123.       BEGIN
  4124.         lcn_record := lcn ;
  4125.         abort_params := (lcn => lcn_record) ;
  4126.         the_message_for_tcp := (with_tcp_communicate.abor_t, abort_params) ;
  4127.         message_for_tcp(the_message_for_tcp) ;
  4128.       END ;
  4129.     ELSE 
  4130.       debug_io.put_line("unrecognized service call") ;
  4131.     END IF ; 
  4132.     debug_io.put_line("end of convt serv call to tl syntax") ;
  4133.   EXCEPTION 
  4134.     WHEN OTHERS =>
  4135.       DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.CONVERT...") ;
  4136.       RAISE ;
  4137.   END convert_service_call_to_transport_level_syntax ; 
  4138.    
  4139. BEGIN 
  4140.   NULL ;
  4141.   EXCEPTION 
  4142.     WHEN OTHERS =>
  4143.       DEBUG_IO.PUT_LINE("@@@EXCEPTION IN PVIRTLPAC.INSTAINTIATION") ;
  4144.       RAISE ;
  4145. END virtual_transport_level ; 
  4146. --::::::::::::::
  4147. --pvirtmpac.txt
  4148. --::::::::::::::
  4149. -----------------------------------------------------------------------
  4150. --
  4151. --         DoD Protocols    NA-00009-200       80-01212-100(-)
  4152. --         E-Systems, Inc.  August 07, 1985
  4153. --
  4154. --         pvirtmpac.txt       Author : Mike Thomas
  4155. --
  4156. -----------------------------------------------------------------------
  4157. -- File pvirtmpac     AUTHOR : Paul Higgins
  4158. --   5/4/85  2:09 PM : MODIFY FOR DEC ADA 
  4159. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  4160. --  7/16/85  2:45 PM : mods for telesoft for wicat
  4161. WITH SYSTEM ; -- to access system.byte
  4162. PACKAGE virtual_terminal -- specification
  4163.         ----------------
  4164.  IS
  4165. --**********************  USER SPECIFICATION  *******************************
  4166. --
  4167. -- This package implements the interface between telnet and the process
  4168. --  using telnet. The interface is on a character by character basis and
  4169. --  is buffered. The "user process" is referred to as the NVT (network
  4170. --  virtual terminal) and could be an applications process (FTP,SMTP,etc)
  4171. --  or a terminal-handler.
  4172. --
  4173. -------------------------  data specifications  -----------------------------
  4174.   
  4175.   SUBTYPE bit_count_32_type IS LONG_INTEGER ; 
  4176.   --&MT SUBTYPE bit_count_32_type IS INTEGER ;
  4177.   SUBTYPE bit_count_16_type IS INTEGER ; 
  4178.   --&MT SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  4179.   SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  4180.   --&MT SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  4181.   SUBTYPE port_number IS bit_count_16_type ;
  4182.   ---------------------  procedure specifications  ----------------------------
  4183. --- telnet's side of the interface:
  4184.   
  4185.   FUNCTION there_are_characters_in_keyboard_buffer (I : port_number)
  4186.            ---------------------------------------
  4187.    RETURN BOOLEAN ;
  4188.   -- ***********************  USER SPECIFICATION  *************************
  4189.   --
  4190.   -- This function returns true if there are unprocessed characters in the
  4191.   -- NVT keyboard buffer.
  4192.   -------------------------------------------------------------------------
  4193.     
  4194.   PROCEDURE get_next_character_from_keyboard_buffer 
  4195.             ---------------------------------------
  4196.    (I   : IN  port_number;
  4197.    char : OUT bit_count_8_type) ;
  4198.   -- ***********************  USER SPECIFICATION  *************************
  4199.   --
  4200.   -- This procedure will return the next unprocessed character from the
  4201.   -- NVT keyboard buffer.
  4202.   -------------------------------------------------------------------------
  4203.      
  4204.      
  4205.      
  4206.   FUNCTION there_is_room_in_the_printer_buffer (I : port_number) 
  4207.            -----------------------------------
  4208.    RETURN BOOLEAN ;
  4209.   -- ***********************  USER SPECIFICATION  *************************
  4210.   --
  4211.   -- This function returns true if there is room for a character in the
  4212.   -- NVT printer buffer.
  4213.   -------------------------------------------------------------------------
  4214.   PROCEDURE output_character_to_NVT_printer  
  4215.             -------------------------------
  4216.    (I   : IN port_number;
  4217.    char : IN bit_count_8_type);
  4218.   -- ***********************  USER SPECIFICATION  *************************
  4219.   --
  4220.   -- This procedure will output a character to the NVT printer buffer.
  4221.   -- If there is no room in the buffer the character will be lost.
  4222.   -- It is the caller's responsibility to make sure there is room in the 
  4223.   -- buffer.
  4224.   -------------------------------------------------------------------------
  4225.     
  4226.     
  4227.   --- nvt's side of the interface
  4228.   FUNCTION there_are_characters_in_printer_buffer (I : port_number) 
  4229.            ---------------------------------------
  4230.    RETURN BOOLEAN ;
  4231.   -- ***********************  USER SPECIFICATION  *************************
  4232.   --
  4233.   -- This function returns true if there are unprocessed characters in the
  4234.   -- NVT printer buffer.
  4235.   -------------------------------------------------------------------------
  4236.     
  4237.   PROCEDURE get_next_character_from_telnet 
  4238.             ------------------------------
  4239.    (I : port_number;
  4240.    char : OUT bit_count_8_type) ;
  4241.   -- ***********************  USER SPECIFICATION  *************************
  4242.   --
  4243.   -- This procedure will return the next unprocessed character from the
  4244.   -- NVT printer buffer.
  4245.   -------------------------------------------------------------------------
  4246.      
  4247.      
  4248.      
  4249.   FUNCTION there_is_room_in_the_keyboard_buffer (I : port_number)
  4250.            -----------------------------------
  4251.    RETURN BOOLEAN ;
  4252.   -- ***********************  USER SPECIFICATION  *************************
  4253.   --
  4254.   -- This function returns true if there is room for a character in the
  4255.   -- NVT keyboard buffer.
  4256.   -------------------------------------------------------------------------
  4257.   PROCEDURE send_char_to_telnet 
  4258.             -------------------
  4259.    (I :   IN port_number;
  4260.    char : IN bit_count_8_type);
  4261.   -- ***********************  USER SPECIFICATION  *************************
  4262.   --
  4263.   -- If there is no room in the buffer the character will be lost.
  4264.   -- It is the caller's responsibility to make sure there is room in the 
  4265.   -- buffer.
  4266.   -------------------------------------------------------------------------
  4267.     
  4268.     
  4269. END virtual_terminal ;
  4270.  
  4271. -- File pvirtmpac    AUTHOR : Paul Higgins
  4272. --   5/4/85  2:09 PM : MODIFY FOR DEC ADA 
  4273. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  4274. --  7/16/85  2:45 PM : mods for telesoft for wicat
  4275. with text_io; use text_io ;
  4276.   
  4277. PACKAGE BODY virtual_terminal IS 
  4278.              ----------------
  4279. -- *************************  BODY SPECIFICATION  *****************************
  4280. --
  4281. -- This package manages buffers which are tied to the process/user terminal
  4282. -- "I/O" device.  For example, keyboard input is stored in the keyboard_
  4283. -- input_buffer.  Then, the Presentation Protocol Layer can retrieve
  4284. -- characters from that buffer and pass them back to the Application Protocol 
  4285. -- Layer when that layer asks for the characters.  Similar processing
  4286. -- occurs for the printer_output_buffer.  The APL could ask the PPL to send
  4287. -- a character out to the NVT_printer; the PPL would put the character into
  4288. -- the printer_output_buffer and this character would eventually be 
  4289. -- "printed" on the nvt printer.  Also procedures exist to store and retrieve
  4290. -- these buffers in their entirety.  
  4291. -- 
  4292. -- ****************************************************************************
  4293.   -- the buffers 
  4294.   buffer_length : CONSTANT bit_count_16_type := 256 ; -- arbitrary
  4295.   SUBTYPE buf_ptr IS bit_count_16_type RANGE 0..buffer_length ;
  4296.   TYPE buffer_type IS ARRAY (0..buffer_length-1) OF bit_count_8_type ;
  4297.   -- keyboard input buffer
  4298.   TYPE keyboard_input_buffer_record IS 
  4299.     RECORD
  4300.       buffer  : buffer_type ;
  4301.       in_ptr  : buf_ptr := 0 ;
  4302.       out_ptr  : buf_ptr := 0 ;
  4303.     END RECORD ;
  4304.     
  4305.   -- printer output buffer
  4306.   TYPE printer_output_buffer_record IS 
  4307.     RECORD
  4308.       buffer   : buffer_type ;
  4309.       in_ptr   : buf_ptr := 0 ;
  4310.       out_ptr  : buf_ptr := 0 ;
  4311.     END RECORD ;
  4312.   TYPE nvt_ppl_buffers_type IS
  4313.     RECORD  
  4314.       keyboard_buffer : keyboard_input_buffer_record ;
  4315.       printer_buffer : printer_output_buffer_record ;
  4316.     END RECORD ;
  4317.  number_of_devices : CONSTANT port_number := 1 ;
  4318.  io_buffer : ARRAY (1..number_of_devices) OF nvt_ppl_buffers_type ;
  4319. -- Note that only one task is implemented. This should be a task type,
  4320. -- and an array of them should be defined (one for each device).
  4321. -- This could not be done by TS for now...
  4322. TASK inbuf IS
  4323.   ENTRY kbd_char_rdy     (device : IN port_number; rdy : OUT BOOLEAN ) ;
  4324.   ENTRY get_kbd_char     (device : IN port_number; ch  : OUT bit_count_8_type) ;
  4325.   ENTRY put_kbd_char     (device : IN port_number; ch  : IN  bit_count_8_type) ;
  4326.   ENTRY get_printer_char (device : IN port_number; ch  : OUT bit_count_8_type) ;
  4327.   ENTRY put_printer_char (device : IN port_number; ch  : IN  bit_count_8_type) ;
  4328.   ENTRY printer_char_rdy (device : IN port_number; rdy : OUT BOOLEAN ) ;
  4329. END ;
  4330. TASK BODY inbuf IS
  4331.   BEGIN
  4332.   LOOP
  4333.   SELECT
  4334.     ACCEPT kbd_char_rdy     (device : IN port_number; rdy : OUT BOOLEAN )
  4335.       DO
  4336.         rdy := io_buffer(device).keyboard_buffer.in_ptr 
  4337.               /= io_buffer(device).keyboard_buffer.out_ptr ;
  4338.       END ;
  4339.   OR
  4340.     WHEN io_buffer(1).keyboard_buffer.in_ptr 
  4341.               /= io_buffer(1).keyboard_buffer.out_ptr =>
  4342.       ACCEPT get_kbd_char (device : IN port_number; ch  : OUT bit_count_8_type) 
  4343.         DO
  4344.           ch := io_buffer(device).keyboard_buffer.buffer
  4345.                 (io_buffer(device).keyboard_buffer.out_ptr) ;
  4346.           io_buffer(device).keyboard_buffer.out_ptr :=
  4347.            (io_buffer(device).keyboard_buffer.out_ptr + 1) mod buffer_length ;
  4348.         END ;
  4349.   OR
  4350.     ACCEPT put_kbd_char (device : IN port_number; ch  : IN  bit_count_8_type) 
  4351.       DO
  4352.         IF io_buffer(device).keyboard_buffer.out_ptr 
  4353.               /= (io_buffer(device).keyboard_buffer.in_ptr + 1)
  4354.                 mod buffer_length THEN
  4355.         io_buffer(device).keyboard_buffer.buffer
  4356.                (io_buffer(device).keyboard_buffer.in_ptr) := ch ;
  4357.         io_buffer(device).keyboard_buffer.in_ptr :=
  4358.              (io_buffer(device).keyboard_buffer.in_ptr + 1) mod buffer_length ;
  4359.         END IF ;
  4360.      END ;
  4361.   OR
  4362.     WHEN io_buffer(1).printer_buffer.in_ptr 
  4363.               /= io_buffer(1).printer_buffer.out_ptr =>
  4364.       ACCEPT get_printer_char(device : IN port_number; ch : OUT bit_count_8_type)
  4365.         DO
  4366.           ch := io_buffer(device).printer_buffer.buffer
  4367.                 (io_buffer(device).printer_buffer.out_ptr) ;
  4368.           io_buffer(device).printer_buffer.out_ptr :=
  4369.               (io_buffer(device).printer_buffer.out_ptr + 1) mod buffer_length ;
  4370.         END ;
  4371.   OR
  4372.     ACCEPT put_printer_char(device : IN port_number; ch : IN bit_count_8_type) 
  4373.       DO
  4374.         IF io_buffer(device).printer_buffer.out_ptr 
  4375.               /= (io_buffer(device).printer_buffer.in_ptr + 1)
  4376.                 mod buffer_length THEN
  4377.         io_buffer(device).printer_buffer.buffer
  4378.                (io_buffer(device).printer_buffer.in_ptr) := ch ;
  4379.         io_buffer(device).printer_buffer.in_ptr :=
  4380.              (io_buffer(device).printer_buffer.in_ptr + 1) mod buffer_length ;
  4381.         END IF ;
  4382.      END ;
  4383.    OR
  4384.     ACCEPT printer_char_rdy(device : IN port_number; rdy : OUT BOOLEAN ) 
  4385.       DO
  4386.         rdy := io_buffer(device).printer_buffer.in_ptr 
  4387.               /= io_buffer(device).printer_buffer.out_ptr ;
  4388.       END ;
  4389.   END SELECT ;
  4390.   END LOOP ;
  4391. END ;
  4392.     
  4393.   FUNCTION there_are_characters_in_keyboard_buffer (I : port_number)
  4394.            ---------------------------------------
  4395.    RETURN BOOLEAN is
  4396.   flag : boolean ;
  4397.   begin
  4398.     inbuf.kbd_char_rdy(i, flag) ;
  4399.     RETURN flag ;
  4400.   END there_are_characters_in_keyboard_buffer ; -- body
  4401.      
  4402.      
  4403.     
  4404.   PROCEDURE get_next_character_from_keyboard_buffer 
  4405.             ---------------------------------------
  4406.    (I   : IN  port_number;
  4407.    char : OUT bit_count_8_type) is
  4408.   BEGIN
  4409.     char := 0 ; -- default value
  4410.     inbuf.get_kbd_char(i, char) ;
  4411.   END get_next_character_from_keyboard_buffer ; -- body
  4412.      
  4413.   FUNCTION there_is_room_in_the_printer_buffer (I : port_number) 
  4414.            -----------------------------------
  4415.    RETURN BOOLEAN IS
  4416.   -- ***********************  BODY SPECIFICATION  *************************
  4417.   --
  4418.   -- This function returns true if there is room for a character in the
  4419.   -- NVT printer buffer.
  4420.   -------------------------------------------------------------------------
  4421.   BEGIN
  4422.     RETURN TRUE ;
  4423.   END there_is_room_in_the_printer_buffer ; -- body
  4424.      
  4425.   PROCEDURE output_character_to_NVT_printer  
  4426.             -------------------------------
  4427.    (I   : IN port_number;
  4428.    char : IN bit_count_8_type ) is
  4429.   BEGIN
  4430.   inbuf.put_printer_char(i,char) ;
  4431.   END output_character_to_NVT_printer ; -- body
  4432.     
  4433.   
  4434.   FUNCTION there_are_characters_in_printer_buffer (I : port_number) 
  4435.            ---------------------------------------
  4436.    RETURN BOOLEAN is
  4437.     flag : boolean ;
  4438.     begin
  4439.     inbuf.printer_char_rdy(i, flag) ;
  4440.     RETURN flag ;
  4441.     END ;
  4442.   PROCEDURE get_next_character_from_telnet 
  4443.             ------------------------------
  4444.    (I : port_number;
  4445.    char : OUT bit_count_8_type) is
  4446.     begin
  4447.     char := 0 ;
  4448.     inbuf.get_printer_char(i, char) ;
  4449.     end ;
  4450.   PROCEDURE send_char_to_telnet 
  4451.             -------------------
  4452.    (I :   IN port_number;
  4453.    char : IN bit_count_8_type ) is
  4454.     begin
  4455.       inbuf.put_kbd_char(i, char) ;
  4456.     end ;
  4457.   FUNCTION there_is_room_in_the_keyboard_buffer (I : port_number) 
  4458.            -----------------------------------
  4459.    RETURN BOOLEAN IS
  4460.   BEGIN
  4461.     RETURN TRUE ;
  4462.   END there_is_room_in_the_keyboard_buffer ; -- body
  4463.      
  4464.   BEGIN
  4465.     NULL ; 
  4466.   END virtual_terminal ; -- package body
  4467.   
  4468. --::::::::::::::
  4469. --telnetpac.txt
  4470. --::::::::::::::
  4471. -----------------------------------------------------------------------
  4472. --
  4473. --         DoD Protocols    NA-00009-200       80-01213-100(-)
  4474. --         E-Systems, Inc.  August 07, 1985
  4475. --
  4476. --         telnetpac.txt       Author : Mike Thomas
  4477. --
  4478. -----------------------------------------------------------------------
  4479. --   File : telnet         AUTHOR : MIKE THOMAS
  4480. --   5/9/85  2:20 PM : MODIFY FOR DEC ADA 
  4481. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  4482. --   7/16/85 2:51 PM : mods for telesoft for wicat
  4483. WITH user_data ;
  4484. USE  user_data ;
  4485. WITH option_negotiation ;
  4486.  
  4487. PACKAGE telnet_package -- specification
  4488.         --------------
  4489.  IS
  4490. -- **********************  USER SPECIFICATION  *****************************
  4491. -- 
  4492. -- This package has the data types and data operations which are exported
  4493. -- to the TELNET controller program to allow the controller to set up the
  4494. -- data structure used by the TELNET procedure and the TELNET procedure
  4495. -- which services a TELNET user.  An array of user data structures could be 
  4496. -- used by the controller to serve multiple TELNET users.  The 
  4497. -- user_information_type contains all the necessary information maintained 
  4498. -- for a TELNET user.  The TELNET_options_supported_type lists the 
  4499. -- non-default options currently supported by this implementation.  User
  4500. -- information directly alterable by the controller are the non-standard
  4501. -- TELNET options and I/O_device_characteristics.  The controller
  4502. -- can request to begin a non-default TELNET option, demand not to support a
  4503. -- non-default option, (as well as the same request/demand for the other
  4504. -- side of the TELNET connection) and set information regarding the actual
  4505. -- I/O device characteristics for a particular user.  These characteristics 
  4506. -- should be initialized prior to running the TELNET procedure, but could
  4507. -- be dynamically changed if appropriate.
  4508. -- 
  4509. -- **************************************************************************
  4510. -- *debug*  make user_info_type public for test/debug *debug**********
  4511. --  TYPE user_info_type IS PRIVATE ; -- user specific information
  4512.   SUBTYPE bit_count_16_type IS INTEGER ; 
  4513.   --&MT SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  4514.   SUBTYPE user_info_type IS user_data.control_block_type ;
  4515.   SUBTYPE telnet_options_supported_type IS -- non-default options supported
  4516.    user_data.option_type ;
  4517.   TYPE io_device_supported_type IS (process, VT100) ;
  4518.   SUBTYPE io_port_address_type IS bit_count_16_type ; -- arbitrary
  4519.   PROCEDURE telnet_request_to_do_option -- specification
  4520.             ---------------------------
  4521.    (option :        IN telnet_options_supported_type ;
  4522.     user_info : IN OUT user_info_type) ;
  4523.     -- *********************  USER SPECIFICATION  *****************************
  4524.     --
  4525.     -- This procedure allows the TELNET controller to request a non-default
  4526.     -- TELNET option to be done locally.  Used primarily to initialize
  4527.     -- this information prior to using the TELNET procedure, but it
  4528.     -- can be used to dynamically request a change in TELNET options if
  4529.     -- desired.  If this procedure is used for a closed connection, TELNET
  4530.     -- will automatically try to negotiate that option upon the establishment
  4531.     -- of a new connection.
  4532.     ---------------------------------------------------------------------------
  4533.   PROCEDURE telnet_demand_not_to_do_option -- specification
  4534.             ------------------------------
  4535.    (option :        IN telnet_options_supported_type ;
  4536.     user_info : IN OUT user_info_type) ;
  4537.     -- *********************  USER SPECIFICATION  *****************************
  4538.     --
  4539.     -- This procedure allows the TELNET controller to demand a non-default
  4540.     -- TELNET option not be done locally.  Used primarily to initialize
  4541.     -- this information prior to using the TELNET procedure, but it
  4542.     -- can be used to dynamically request a change in TELNET options if
  4543.     -- desired.
  4544.     ---------------------------------------------------------------------------
  4545.   PROCEDURE telnet_request_remote_to_do_option -- specification
  4546.             ----------------------------------
  4547.    (option :        IN telnet_options_supported_type ;
  4548.     user_info : IN OUT user_info_type) ;
  4549.     -- *********************  USER SPECIFICATION  *****************************
  4550.     --
  4551.     -- This procedure allows the TELNET controller to request a non-default
  4552.     -- TELNET option to be done remotely.  Used primarily to initialize
  4553.     -- this information prior to using the TELNET procedure, but it
  4554.     -- can be used to dynamically request a change in TELNET options if
  4555.     -- desired.  If this procedure is used for a closed connection, TELNET
  4556.     -- will automatically try to negotiate that option upon the establishment
  4557.     -- of a new connection.
  4558.     ---------------------------------------------------------------------------
  4559.   PROCEDURE telnet_demand_remote_not_to_do_option -- specification
  4560.             -------------------------------------
  4561.    (option :        IN telnet_options_supported_type ;
  4562.     user_info : IN OUT user_info_type) ;
  4563.     -- *********************  USER SPECIFICATION  *****************************
  4564.     --
  4565.     -- This procedure allows the TELNET controller to demand a non-default
  4566.     -- TELNET option not be done remotely.  Used primarily to initialize
  4567.     -- this information prior to using the TELNET procedure, but it
  4568.     -- can be used to dynamically request a change in TELNET options if
  4569.     -- desired.
  4570.     ---------------------------------------------------------------------------
  4571.   PROCEDURE set_device_type -- specification
  4572.             ---------------
  4573.    (device_type :     IN IO_device_supported_type ;
  4574.     user_info :   IN OUT user_info_type) ;
  4575.     -- *********************  USER SPECIFICATION  *****************************
  4576.     --
  4577.     -- This procedure sets the device type for use by the TELNET 
  4578.     -- presentation protocol level to allow actual communication 
  4579.     -- with that process or device.  Used primarily to initialize
  4580.     -- this information prior to using the TELNET procedure, but it
  4581.     -- can be used to dynamically request a change if desired.
  4582.     ---------------------------------------------------------------------------
  4583.   PROCEDURE set_IO_port_address -- specification
  4584.             -------------------
  4585.    (IO_port_address :     IN IO_port_address_type ;
  4586.     user_info :       IN OUT user_info_type) ;
  4587.     -- *********************  USER SPECIFICATION  *****************************
  4588.     --
  4589.     -- This procedure sets the I/O port address for use by the TELNET 
  4590.     -- presentation protocol level to allow actual communication 
  4591.     -- with that process or device.  Used primarily to initialize
  4592.     -- this information prior to using the TELNET procedure, but it
  4593.     -- can be used to dynamically request a change if desired.
  4594.     ---------------------------------------------------------------------------
  4595.   
  4596.   -- Note : Other device specific procedures may have to be added here
  4597.   --        as deemed appropriate baised on the characteristics of the 
  4598.   --        of the specific devices supported and the host system.
  4599.   PROCEDURE telnet -- specification
  4600.             ------ 
  4601.    (user_info : IN OUT user_info_type ;
  4602.     idle      :    OUT BOOLEAN) ;
  4603.     -- *****************  USER SPECIFICATION  *****************************
  4604.     --
  4605.     -- This procedure implements the TELNET [1] communication protocol
  4606.     -- for a single user.  One "pass" is made for all sources of I/O
  4607.     -- for a user for each call of this procedure.  The controlling
  4608.     -- program should initialize any non-default options desired and I/O 
  4609.     -- device characteristics prior to calling telnet.  An array of 
  4610.     -- user_info_type variables would allow the controller to process
  4611.     -- multiple users of TELNET.
  4612.     --
  4613.     -- SPECIFICATION REFERENCES:
  4614.     -- 
  4615.     --    [1] Network Working Group Request for Comments: 854, May 1983,
  4616.     --        TELNET PROTOCOL SPECIFICATION
  4617.     -----------------------------------------------------------------------
  4618. -- made public for test/debug
  4619. --  PRIVATE 
  4620. --    TYPE user_info_type IS -- user specific information
  4621. --      RECORD
  4622. --        user_control_block : user_data.control_block_type ;
  4623. --      END RECORD ;
  4624. END telnet_package ; -- specification
  4625. -- File telnetpac      AUTHOR : MIKE THOMAS 
  4626. --   5/9/85  2:35 PM : MODIFY FOR DEC ADA 
  4627. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  4628. --  6/23/85  8:57 PM : don't set ga state at top of telnet proc
  4629. --   7/1/85  2:52 PM : remove status variable from option request
  4630. --  7/16/85  2:51 PM : mods for telesoft for wicat
  4631. WITH telnet_apl ; -- TELNET application protocol level
  4632. USE telnet_apl ;
  4633. WITH debug_io ;
  4634. PACKAGE BODY telnet_package IS 
  4635.              --------------
  4636.   PROCEDURE telnet_request_to_do_option -- body
  4637.             ---------------------------
  4638.    (option :        IN telnet_options_supported_type ;
  4639.     user_info : IN OUT user_info_type) IS
  4640.   BEGIN
  4641. --    user_data.put(user_info.user_control_block) ; -- store_user_information ;
  4642.     user_data.put(user_info) ; -- made public
  4643.     option_negotiation.request_local_option_enable(option) ;
  4644. --    user_data.get(user_info.user_control_block) ; -- restore_user_information ;
  4645.     user_data.get(user_info) ; -- made public
  4646.   EXCEPTION
  4647.     WHEN OTHERS =>
  4648.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN telnetpac.req_l_do_opt") ;
  4649.       RAISE ;
  4650.   END telnet_request_to_do_option ; -- body
  4651.   PROCEDURE telnet_demand_not_to_do_option -- body
  4652.             ------------------------------
  4653.    (option : IN telnet_options_supported_type ;
  4654.     user_info : IN OUT user_info_type) IS
  4655.   BEGIN
  4656. --    user_data.put(user_info.user_control_block) ; -- store_user_information ;
  4657.     user_data.put(user_info) ; -- made public
  4658.     option_negotiation.demand_local_option_disable(option) ;
  4659. --    user_data.get(user_info.user_control_block) ; -- restore_user_information ;
  4660.     user_data.get(user_info) ; -- made public
  4661.   EXCEPTION
  4662.     WHEN OTHERS =>
  4663.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN telnetpac.dem_l_n_do_opt") ;
  4664.       RAISE ;
  4665.   END telnet_demand_not_to_do_option ; -- body
  4666.     
  4667.   PROCEDURE telnet_request_remote_to_do_option -- body
  4668.             ----------------------------------
  4669.    (option :        IN telnet_options_supported_type ;
  4670.     user_info : IN OUT user_info_type) IS
  4671.   BEGIN
  4672. --    user_data.put(user_info.user_control_block) ; -- store_user_information ;
  4673.     user_data.put(user_info) ; -- made public
  4674.     option_negotiation.request_remote_option_enable(option) ;
  4675. --    user_data.get(user_info.user_control_block) ; -- restore_user_information ;
  4676.     user_data.get(user_info) ; -- made public
  4677.   EXCEPTION
  4678.     WHEN OTHERS =>
  4679.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN telnetpac.req_r_do_opt") ;
  4680.       RAISE ;
  4681.   END telnet_request_remote_to_do_option ; -- body
  4682.   PROCEDURE telnet_demand_remote_not_to_do_option -- body
  4683.             -------------------------------------
  4684.    (option : IN telnet_options_supported_type ;
  4685.     user_info : IN OUT user_info_type) IS 
  4686.   BEGIN
  4687. --    user_data.put(user_info.user_control_block) ; -- store_user_information ;
  4688.     user_data.put(user_info) ; -- made public
  4689.     option_negotiation.demand_remote_option_disable(option) ;
  4690. --    user_data.get(user_info.user_control_block) ; -- restore_user_information ;
  4691.     user_data.get(user_info) ; -- made public
  4692.   EXCEPTION
  4693.     WHEN OTHERS =>
  4694.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN telnetpac.dem_r_n_d_opt") ;
  4695.       RAISE ;
  4696.   END telnet_demand_remote_not_to_do_option ;
  4697.   PROCEDURE set_device_type -- body
  4698.             ---------------
  4699.    (device_type : IN IO_device_supported_type ;
  4700.     user_info   : IN OUT user_info_type) IS --T B D
  4701.   BEGIN
  4702.     NULL ;
  4703.   END set_device_type ; -- body
  4704.   PROCEDURE set_IO_port_address -- body
  4705.             -------------------
  4706.    (IO_port_address : IN IO_port_address_type ;
  4707.     user_info : IN OUT user_info_type) IS -- T B D
  4708.   BEGIN
  4709.     user_info.port := io_port_address ;
  4710.   END set_IO_port_address ; -- body
  4711.   
  4712.   PROCEDURE telnet -- body
  4713.             ------ 
  4714.    (user_info : IN OUT user_info_type ;
  4715.     idle : OUT BOOLEAN) IS
  4716.     -- *****************  BODY SPECIFICATION  *****************************
  4717.     --
  4718.     -- Processing sequence...
  4719.     --
  4720.     -- Initialize the user information.  If the NVT I/O state is I/O done,
  4721.     -- then set the go ahead sent state to no_go_ahead_sent and the NVT I/O 
  4722.     -- state to no I/O done.  Process any input from the NVT keyboard.  Process
  4723.     -- any messages from the transport level.  Process any transport level 
  4724.     -- input.  If APL had completed sending data to the NVT printer  and  had
  4725.     -- no queued input from  the  NVT keyboard  for  further processing 
  4726.     -- (NVT I/O  state  is no-I/O-done) and the TELNET go ahead was not 
  4727.     -- already sent then the APL must transmit the TELNET GA (go ahead) to
  4728.     -- the transport level [2] and mark the go ahead sent state to 
  4729.     -- go_ahead_sent.  Restore the user information.
  4730.     --
  4731.     --
  4732.     -- SPECIFICATION REFERENCES:
  4733.     -- 
  4734.     --    [1] Network Working Group Request for Comments: 854, May 1983,
  4735.     --        TELNET PROTOCOL SPECIFICATION
  4736.     --
  4737.     --    [2] RFC 854 : TELNET rotocol Specification
  4738.     --         page 5, condition 2
  4739.     --
  4740.     --------------------------------------------------------------------------
  4741.     old_communication_state : user_data.communication_state_type ;
  4742.     communication_state : user_data.communication_state_type RENAMES
  4743.      user_data.user_control_block.communication_state ;
  4744.     FUNCTION time_to_send_telnet_go_ahead RETURN BOOLEAN IS 
  4745.              ----------------------------
  4746.       send_flag               : BOOLEAN := FALSE ;
  4747.       ga_not_suppressed       : BOOLEAN := TRUE ;
  4748.       local_options_in_effect : user_data.option_table_type RENAMES
  4749.        user_data.user_control_block.option_tables.local_options_in_effect ;
  4750.     BEGIN
  4751.       FOR index IN 1..local_options_in_effect.number_of_items LOOP
  4752.         IF local_options_in_effect.option(index) = suppress_ga THEN
  4753.           ga_not_suppressed := FALSE ;
  4754.           EXIT ;
  4755.         END IF ;
  4756.       END LOOP ;
  4757.       IF ga_not_suppressed AND THEN
  4758.        (user_control_block.NVT_IO_state = no_IO_done AND 
  4759.        user_control_block.ga_state = no_go_ahead_sent AND
  4760.        user_control_block.communication_state = 
  4761.        user_data.connection_established) THEN
  4762.          send_flag := TRUE ;
  4763.       END IF ;
  4764.       RETURN send_flag ;
  4765.     END time_to_send_telnet_go_ahead ;
  4766.   BEGIN 
  4767. --    user_data.put(user_info.user_control_block) ; --initialize_user_information
  4768.     user_data.put(user_info) ; -- made public
  4769.  
  4770.     -- make one "pass" for this user 
  4771.     old_communication_state := communication_state ;
  4772.     user_control_block.NVT_IO_state := no_IO_done ;
  4773.     process_any_input_from_the_nvt_keyboard ;
  4774.     process_any_messages_from_the_transport_level ;
  4775.     process_any_input_from_the_transport_level ;
  4776.     IF time_to_send_telnet_go_ahead THEN
  4777.       transmit_telnet_go_ahead ;
  4778.       user_control_block.ga_state := go_ahead_sent ;
  4779.     END IF ;
  4780.     IF (old_communication_state = user_data.no_connection_established) AND THEN
  4781.      (communication_state = user_data.connection_established) THEN
  4782.       option_negotiation.negotiate_initial_desired_options ;
  4783.     END IF ;
  4784.      
  4785. --    user_data.get(user_info.user_control_block) ; -- restore_user_information ;
  4786.     user_data.get(user_info) ; -- made public for ease of test/debug
  4787.   idle := user_control_block.nvt_io_state = no_io_done ;
  4788.   EXCEPTION
  4789.     WHEN OTHERS =>
  4790.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN telnetpac.telnet") ;
  4791.       RAISE ;
  4792.   END telnet ; -- body
  4793. BEGIN -- telnet_package body
  4794.   NULL ; 
  4795.   EXCEPTION
  4796.     WHEN OTHERS =>
  4797.       debug_io.put_line("@#@#@#@ EXCEPTION RAISED IN telnetpac instantiation") ;
  4798.       RAISE ;
  4799. END telnet_package ; -- body
  4800. --::::::::::::::
  4801. --telserv.txt
  4802. --::::::::::::::
  4803. -----------------------------------------------------------------------
  4804. --
  4805. --         DoD Protocols    NA-00009-200       80-01214-100(-)
  4806. --         E-Systems, Inc.  August 07, 1985
  4807. --
  4808. --         telserv.txt       Author : Mike Thomas
  4809. --
  4810. -----------------------------------------------------------------------
  4811. with WITH_TCP_COMMUNICATE;
  4812. with SYSTEM;
  4813. with SUBNET_CONTROLLER_TASK;    use SUBNET_CONTROLLER_TASK;
  4814. with TEXT_IO;                   use TEXT_IO;
  4815. with BUFFER_DATA;               use BUFFER_DATA;
  4816. with USER_DATA;                 use USER_DATA;
  4817. with TELNET_PACKAGE;
  4818. with IOTASKS;
  4819. with DEBUG_IO;                  use DEBUG_IO;
  4820. with I_DEBUG_STATE_OUTPUT;        use I_DEBUG_STATE_OUTPUT;
  4821. with SUBNET_CALLS;              use SUBNET_CALLS;
  4822. with INTERNET_PROTOCOL_CONTROL_AND_SEND_PROCESSING;
  4823. use INTERNET_PROTOCOL_CONTROL_AND_SEND_PROCESSING;
  4824. with TCP_CONTROLLER_TASK;       use TCP_CONTROLLER_TASK;
  4825. with REAL_TIME_CLOCK_AND_DATE;  use REAL_TIME_CLOCK_AND_DATE;
  4826. procedure TELNET_TCP_IP is
  4827. IDLE : BOOLEAN;
  4828. USER_DAT_INFO : TELNET_PACKAGE.USER_INFO_TYPE;
  4829. subtype BIT_COUNT_16_TYPE is INTEGER;
  4830. open_parameters : with_TCP_communicate.open_params;
  4831. options : with_TCP_communicate.tcp_option_type;
  4832. lcn_pointer : with_TCP_communicate.LCN_TYPE;
  4833. TCP_MESSAGE : WITH_TCP_COMMUNICATE.MESSAGE;
  4834. begin
  4835.  BUFFER_DATA.INIT; --Initialize buffers
  4836.  START_LOCAL_CLOCK;
  4837.  DEBUG_IO.DESTINATION := DEBUG_IO.NONE;
  4838.  TELNET_PACKAGE.SET_IO_PORT_ADDRESS( 1, USER_DAT_INFO );
  4839.  telnet_package.telnet_request_remote_to_do_option
  4840.  (suppress_ga,user_dat_info);
  4841.  telnet_package.telnet_request_to_do_option
  4842.  (suppress_ga,user_dat_info);
  4843.  open_parameters := ( 2,
  4844.                       0,
  4845.                       0,
  4846.                       with_TCP_communicate.passive,
  4847.                       0,
  4848.                       255,
  4849.                       lcn_pointer,
  4850.                       0,
  4851.                       0,
  4852.                       options);
  4853.  TCP_MESSAGE := (WITH_TCP_COMMUNICATE.OPEN, OPEN_PARAMETERS);
  4854.  WITH_TCP_COMMUNICATE.MESSAGE_FOR_TCP( TCP_MESSAGE );
  4855.  TELNET_PACKAGE.TELNET( USER_DAT_INFO, IDLE ) ;
  4856.  TELNET_PACKAGE.TELNET( USER_DAT_INFO, IDLE ) ;
  4857.  TELNET_PACKAGE.TELNET( USER_DAT_INFO, IDLE ) ;
  4858.  loop
  4859.    --TEXT_IO.PUT_LINE("CALLING SUBNET_CONTROLLER");
  4860.    SUBNET_CONTROLLER;
  4861.    --TEXT_IO.PUT_LINE("JUST CAME BACK FROM SUBNET");
  4862.    IP_CONTROLLER;
  4863.    --TEXT_IO.PUT_LINE("JUST CAME BACK FROM IP");
  4864.    TCP_CONTROLLER;
  4865.    --TEXT_IO.PUT_LINE("JUST CAME BACK FROM TCP");
  4866.    TELNET_PACKAGE.TELNET( USER_DAT_INFO, IDLE ) ;
  4867.    --TEXT_IO.PUT_LINE("JUST CAME BACK FROM TELNET");
  4868.    TCP_CONTROLLER;
  4869.    IP_CONTROLLER;
  4870.    SUBNET_CONTROLLER;
  4871.  end loop;
  4872. exception
  4873.  when CONSTRAINT_ERROR =>
  4874.   TEXT_IO.PUT_LINE("CONSTRAINT ERROR MAIN CONTROLLER");
  4875.  when others =>
  4876.   TEXT_IO.PUT_LINE("UNKNONW ERROR MAIN CONTROLLER");
  4877. end TELNET_TCP_IP;
  4878. --::::::::::::::
  4879. --teluser.txt
  4880. --::::::::::::::
  4881. -----------------------------------------------------------------------
  4882. --
  4883. --         DoD Protocols    NA-00009-200       80-01215-100(-)
  4884. --         E-Systems, Inc.  August 07, 1985
  4885. --
  4886. --         teluser.txt       Author : Mike Thomas
  4887. --
  4888. -----------------------------------------------------------------------
  4889. with SYSTEM;
  4890. with SUBNET_CONTROLLER_TASK;    use SUBNET_CONTROLLER_TASK;
  4891. with TEXT_IO;                   use TEXT_IO;
  4892. with BUFFER_DATA;               use BUFFER_DATA;
  4893. with USER_DATA;                 use USER_DATA;
  4894. with TELNET_PACKAGE;
  4895. with IOTASKS;
  4896. with DEBUG_IO;                  use DEBUG_IO;
  4897. with I_DEBUG_STATE_OUTPUT;        use I_DEBUG_STATE_OUTPUT;
  4898. with SUBNET_CALLS;              use SUBNET_CALLS;
  4899. with INTERNET_PROTOCOL_CONTROL_AND_SEND_PROCESSING;
  4900. use INTERNET_PROTOCOL_CONTROL_AND_SEND_PROCESSING;
  4901. with TCP_CONTROLLER_TASK;       use TCP_CONTROLLER_TASK;
  4902. with REAL_TIME_CLOCK_AND_DATE;  use REAL_TIME_CLOCK_AND_DATE;
  4903. procedure TELNET_TCP_IP is
  4904. IDLE : BOOLEAN;
  4905. USER_DAT_INFO : TELNET_PACKAGE.USER_INFO_TYPE;
  4906. subtype BIT_COUNT_16_TYPE is INTEGER;
  4907. begin
  4908.  DEBUG_IO.DESTINATION := DEBUG_IO.NONE;
  4909.  TELNET_PACKAGE.SET_IO_PORT_ADDRESS( 1, USER_DAT_INFO );
  4910.  BUFFER_DATA.INIT; --Initialize buffers
  4911.  START_LOCAL_CLOCK;
  4912.  loop
  4913.    --TEXT_IO.PUT_LINE("CALLING SUBNET_CONTROLLER");
  4914.    SUBNET_CONTROLLER;
  4915.    --TEXT_IO.PUT_LINE("JUST CAME BACK FROM SUBNET");
  4916.    IP_CONTROLLER;
  4917.    --TEXT_IO.PUT_LINE("JUST CAME BACK FROM IP");
  4918.    TCP_CONTROLLER;
  4919.    --TEXT_IO.PUT_LINE("JUST CAME BACK FROM TCP");
  4920.    TELNET_PACKAGE.TELNET( USER_DAT_INFO, IDLE ) ;
  4921.    --TEXT_IO.PUT_LINE("JUST CAME BACK FROM TELNET");
  4922.    TCP_CONTROLLER;
  4923.    IP_CONTROLLER;
  4924.    SUBNET_CONTROLLER;
  4925.  end loop;
  4926. exception
  4927.  when CONSTRAINT_ERROR =>
  4928.   TEXT_IO.PUT_LINE("CONSTRAINT ERROR MAIN CONTROLLER");
  4929.  when others =>
  4930.   TEXT_IO.PUT_LINE("UNKNONW ERROR MAIN CONTROLLER");
  4931. end TELNET_TCP_IP;
  4932. --::::::::::::::
  4933. --ttyio.txt
  4934. --::::::::::::::
  4935. -----------------------------------------------------------------------
  4936. --
  4937. --         DoD Protocols    NA-00009-200       80-01216-100(-)
  4938. --         E-Systems, Inc.  August 07, 1985
  4939. --
  4940. --         ttyio.txt       Author : Mike Thomas
  4941. --
  4942. -----------------------------------------------------------------------
  4943. -- File ttyio    AUTHOR : Paul Higgins
  4944. --   5/4/85  2:09 PM : MODIFY FOR DEC ADA 
  4945. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  4946. --  7/16/85  2:56 PM : mods for telesoft for wicat
  4947. package iotasks is
  4948.   task getchar IS
  4949.    --&MT PRAGMA PRIORITY(6) ; -- try to lower it to keep it from hanging 
  4950.   end getchar;
  4951.   task putchar IS
  4952.    --&MT PRAGMA PRIORITY(8) ; -- whole telnet program
  4953.   end putchar;
  4954. end  iotasks ;
  4955. -- File : ttyio    Author : Paul Higgins   
  4956. --   5/4/85  2:09 PM : MODIFY FOR DEC ADA 
  4957. --                     OLD CODE (TELESOFT) MARKED AS --&MT 
  4958. --  6/11/85  4:00 PM : modified for DEC Ada by Paul Higgins
  4959. --  6/14/85  3:28 PM : dec telnet tasking mod (MT)
  4960. --  7/16/85  2:56 PM : mods for telesoft for wicat
  4961. with text_io ; use text_io ;
  4962. with virtual_terminal; use virtual_terminal;
  4963. with system ;
  4964. --&MT with dec_tn_tasks ;--&MT omit this for telesoft version 
  4965. package body iotasks is
  4966.   SUBTYPE bit_count_16_type IS INTEGER ; 
  4967.   --&MT SUBTYPE bit_count_16_type IS SHORT_INTEGER ;
  4968.   SUBTYPE bit_count_8_type IS SYSTEM.BYTE ;
  4969.   --&MT SUBTYPE bit_count_8_type IS SYSTEM.UNSIGNED_BYTE ;
  4970.   
  4971. task body getchar is
  4972.   a_char : character ;
  4973.   a_var  : bit_count_8_type ;
  4974.   cr     : bit_count_8_type := 13 ; -- ASCII.CR
  4975.   len    : integer ;
  4976.   a_str  : string (1..255) ;
  4977. begin
  4978.   loop
  4979.     IF TEXT_IO.END_OF_LINE THEN
  4980.       send_char_to_telnet(1,cr) ; -- text_io will not read in a ascii.cr
  4981.       TEXT_IO.SKIP_LINE ; -- hop past end of line
  4982.     ELSE
  4983.       text_io.get(a_char) ;--&MT telesoft version
  4984.       a_var := character'pos(a_char) ;--&MT telesoft version
  4985.       send_char_to_telnet(1,a_var) ;--&MT telesoft version
  4986.       --&MT vax version:
  4987.       --&MT text_io.get_line(a_str,len) ;
  4988.       --&MT for i in 1..len loop                 
  4989.         --&MT a_var := character'pos(a_str(i)) ;
  4990.         --&MT send_char_to_telnet(1,a_var) ;
  4991.       --&MT end loop ; --&MT vax
  4992.       --&MT send_char_to_telnet(1,cr) ; -- replace cr stripped out by text_io.
  4993.     END IF ; 
  4994.     --&MT dec_tn_tasks.tn.go ;--&MT  signal telnet controller that there is input
  4995.   end loop ;
  4996. end getchar ;
  4997. task body putchar is
  4998.   a_char : character ;
  4999.   a_var  : bit_count_8_type ;
  5000. begin
  5001.   loop
  5002.     get_next_character_from_telnet(1,a_var) ;
  5003.     IF bit_count_16_type(a_var) = 13 THEN -- CR ==> new line
  5004.       TEXT_IO.NEW_LINE ; -- text_io will send cr lf
  5005.     ELSE
  5006.       a_char := character'val(a_var) ;
  5007.       text_io.put(a_char) ;
  5008.     END IF ;
  5009.   end loop ;
  5010. end putchar ;
  5011. end iotasks ;
  5012.