?? RIGHT := 110 ??
?? NEWTITLE := ' NOS/VE File Server : Client : Request Remote Application Info', EJECT ??
MODULE dfm$request_remote_app_info;

{ PURPOSE:
{    The purpose of this module is to provide the procedures involved with
{    requesting and processing of remote application information from the server
{    mainframe. The main procedure is called as a result of the server/client
{    link reaching an active state.

?? NEWTITLE := ' Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc dfe$error_condition_codes
*copyc dft$cpu_queue
*copyc dft$procedure_address_ordinal
*copyc dft$application_support_limits
?? POP ??
*copyc clp$evaluate_parameters
*copyc dfi$display
*copyc dfi$log_display
*copyc dfp$find_mainframe_id
*copyc dfp$send_remote_procedure_call
*copyc dfp$verify_system_administrator
*copyc dfv$file_server_debug_enabled
*copyc dfv$recovery_task
*copyc dfv$server_wired_heap
*copyc i#current_sequence_position
*copyc osp$set_status_abnormal
*copyc osp$set_status_from_condition
*copyc osp$system_error
*copyc pmp$get_mainframe_id
?? OLDTITLE ??
?? TITLE := '[XDCL, #GATE] dfp$request_remote_app_info', EJECT ??

  PROCEDURE [XDCL, #GATE] dfp$request_remote_app_info
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{  procedure request_remote_pdt (
{   mainframe_id, mi: name pmc$mainframe_id_size = $required
{   status)

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 3] of clt$pdt_parameter_name,
      parameters: array [1 .. 2] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$name_type_qualifier,
      recend,
      type2: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [89, 5, 10, 8, 28, 15, 473],
    clc$command, 3, 2, 1, 0, 0, 0, 2, ''], [
    ['MAINFRAME_ID                   ',clc$nominal_entry, 1],
    ['MI                             ',clc$abbreviation_entry, 1],
    ['STATUS                         ',clc$nominal_entry, 2]],
    [
{ PARAMETER 1
    [1, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 5, clc$required_parameter, 0
  , 0],
{ PARAMETER 2
    [3, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$name_type], [pmc$mainframe_id_size, pmc$mainframe_id_size]],
{ PARAMETER 2
    [[1, 0, clc$status_type]]];

?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$mainframe_id = 1,
      p$status = 2;

    VAR
      pvt: array [1 .. 2] of clt$parameter_value;

    VAR
      mainframe_id: pmt$mainframe_id;

    status.normal := TRUE;
    dfp$verify_system_administrator (' DFP$REQUEST_REMOTE_APP_INFO', status);
    IF status.normal THEN

      clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
      IF status.normal THEN
        mainframe_id := pvt [p$mainframe_id].value^.name_value;
        dfv$recovery_task := TRUE;
        request_remote_app_info (mainframe_id, status);
        dfv$recovery_task := FALSE;
      IFEND;
    IFEND;

  PROCEND dfp$request_remote_app_info;

?? TITLE := ' request_remote_app_info ', EJECT ??

  PROCEDURE request_remote_app_info
    (    server_mainframe_id: pmt$mainframe_id;
     VAR status: ost$status);

?? NEWTITLE := 'dfp$remote_procedure_call_ch', EJECT ??

{ PURPOSE:
{   This procedure is a condition handler established to call a routine to clear the assignment of a task
{   services queue_entry if a task aborts with a queue_entry assigned to it.  The queue_entry must be clear
{   before the task can safely exit.

    PROCEDURE dfp$remote_procedure_call_ch
      (    condition: pmt$condition;
           cond_desc: ^pmt$condition_information;
           save: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      dfp$ch_cleanup;
      osp$set_status_from_condition (dfc$file_server_id, condition, save, status, handler_status);
      EXIT request_remote_app_info;

    PROCEND dfp$remote_procedure_call_ch;
*block
*copyc dfp$begin_ch_remote_proc_call
*copyc dfp$end_ch_remote_proc_call
*blockend
?? OLDTITLE, EJECT ??
    VAR
      allowed_when_server_deactivated: boolean,
      application_index: dft$number_of_applications,
      host_mainframe_id: pmt$mainframe_id,
      ignore_p_q_interf_dir_entry: ^dft$q_interface_directory_entry,
      ignore_p_queue_interf_table: ^dft$queue_interface_table,
      ignore_queue_index: dft$queue_index,
      last_p_remote_app_info: ^dft$remote_application_info,
      local_status: ost$status,
      log_message: string (100),
      log_message_size: integer,
      mainframe_found: boolean,
      p_cpu_queue: ^dft$cpu_queue,
      p_host_mainframe_id: ^pmt$mainframe_id,
      p_number_of_applications: ^dft$number_of_applications,
      p_proc_list: ^array [ * ] of dft$rpc_procedure_address_entry,
      p_rcv_remote_app_info: ^dft$remote_application_info,
      p_receive_buffer: dft$p_receive_parameters,
      p_receive_data: dft$p_receive_data,
      p_remote_app_info: ^dft$remote_application_info,
      p_send_buffer: dft$p_send_parameters,
      p_send_data: dft$p_send_data,
      p_total_proc_count: ^dft$total_number_of_app_procs,
      procedure_ordinal: dft$procedure_address_ordinal,
      queue_entry_location: dft$rpc_queue_entry_location,
      send_buffer_size: dft$send_parameter_size,
      send_data_size: dft$send_data_size,
      server_location: dft$server_location;

    status.normal := TRUE;
    local_status.normal := TRUE;

    dfp$find_mainframe_id (server_mainframe_id, {host_is_server_to_client=} FALSE, mainframe_found,
          ignore_p_queue_interf_table, p_cpu_queue, ignore_queue_index, ignore_p_q_interf_dir_entry);
    IF NOT mainframe_found THEN
      osp$set_status_abnormal (dfc$file_server_id, dfe$mainframe_not_server, server_mainframe_id, status);
      RETURN;
    IFEND;


    IF p_cpu_queue^.queue_header.p_application_rpc_list <> NIL THEN
      FREE p_cpu_queue^.queue_header.p_application_rpc_list IN dfv$server_wired_heap^;
    IFEND;

    IF p_cpu_queue^.queue_header.p_remote_application_info <> NIL THEN
      FREE p_cpu_queue^.queue_header.p_remote_application_info IN dfv$server_wired_heap^;
    IFEND;

    server_location.server_location_selector := dfc$mainframe_id;
    server_location.server_mainframe := server_mainframe_id;
    allowed_when_server_deactivated := FALSE;

    procedure_ordinal := dfc$send_remote_app_info;
    pmp$get_mainframe_id (host_mainframe_id, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    dfp$begin_ch_remote_proc_call (server_location, allowed_when_server_deactivated, queue_entry_location,
          p_send_buffer, p_send_data, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  /after_begin/
    BEGIN

      NEXT p_host_mainframe_id IN p_send_buffer;
      p_host_mainframe_id^ := host_mainframe_id;
      send_buffer_size := i#current_sequence_position (p_send_buffer);
      send_data_size := 0;
      dfp$send_remote_procedure_call (queue_entry_location, procedure_ordinal, send_buffer_size,
            send_data_size, p_receive_buffer, p_receive_data, status);
      IF NOT status.normal THEN
        IF ((status.condition <> dfe$server_request_terminated) AND
              (status.condition <> dfe$server_not_active) AND (status.condition <> dfe$server_has_terminated))
              THEN
          STRINGREP (log_message, log_message_size, ' ABNORMAL STATUS FROM dfp$request_remote_app_info');
          display (log_message (1, log_message_size));
          log_display ($pmt$ascii_logset [pmc$system_log], log_message (1, log_message_size));
          display_status (status);
          log_display_status ($pmt$ascii_logset [pmc$system_log], TRUE, status);
        IFEND;
        EXIT /after_begin/;
      IFEND;

{ Process receive data

      NEXT p_number_of_applications IN p_receive_data;
      NEXT p_total_proc_count IN p_receive_data;
      IF p_number_of_applications^ = 0 THEN
        EXIT /after_begin/;
      IFEND;

      last_p_remote_app_info := NIL;
      FOR application_index := 1 TO p_number_of_applications^ DO
        NEXT p_rcv_remote_app_info IN p_receive_data;
        ALLOCATE p_remote_app_info IN dfv$server_wired_heap^;
        IF p_remote_app_info = NIL THEN
          osp$system_error (' NIL p_remote_app_info', NIL);
        IFEND;
        p_remote_app_info^ := p_rcv_remote_app_info^;
        p_remote_app_info^.next_p_application_info := NIL;
        IF last_p_remote_app_info = NIL THEN
          p_cpu_queue^.queue_header.p_remote_application_info := p_remote_app_info;
        ELSE
          last_p_remote_app_info^.next_p_application_info := p_remote_app_info;
        IFEND;
        last_p_remote_app_info := p_remote_app_info;
      FOREND;

      ALLOCATE p_cpu_queue^.queue_header.p_application_rpc_list: [1 .. p_total_proc_count^] IN
            dfv$server_wired_heap^;
      IF p_cpu_queue^.queue_header.p_application_rpc_list = NIL THEN
        osp$system_error (' NIL p_application_rpc_list', NIL);
      IFEND;

      NEXT p_proc_list: [1 .. p_total_proc_count^] IN p_receive_data;

      p_cpu_queue^.queue_header.p_application_rpc_list^ := p_proc_list^;

      STRINGREP (log_message, log_message_size, ' Server ', server_mainframe_id,
            '    size of app info received = ', #SIZE (p_receive_data^));
      log_display ($pmt$ascii_logset [pmc$job_log, pmc$system_log], log_message (1, log_message_size));
      IF dfv$file_server_debug_enabled THEN
        display (log_message (1, log_message_size));
      IFEND;
    END /after_begin/;

    dfp$end_ch_remote_proc_call (queue_entry_location, local_status);
    IF status.normal AND NOT local_status.normal THEN
      status := local_status;
    IFEND;
  PROCEND request_remote_app_info;
MODEND dfm$request_remote_app_info;



