?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE : nfm$manage_store_forward_network' ??
MODULE nfm$manage_store_forward_netwrk;

{ PURPOSE:
{   This module will create and display the System Store/Forward
{   Network file.  This file contains the information for the Queue
{   File Facilities (QTF and NTF) for store and forward name changes
{   and application changes (ie. from QTF to NTF or from NTF to QTF).
{
{ DESIGN:
{   1.  Add this utility to the User's command list.
{   2.  Read the input file to determine what the User intends to do.
{   3.  If the User wants to display the Store/Forward Network file,
{       display the information that the User is requesting.
{   4.  If the User wants to verify an input file for the purpose of
{       creating the Store/Forward Network file, read the input file
{       and verify that all values are specified correctly.
{   5.  If the User wants to install a new Store/Forward Network file,
{       verify that the input file is valid and then create/replace
{       the System Store/Forward Network file.
{   6.  If the User wants to create a Store/Forward directive file
{       from the current System Store/Forward Network file, read the
{       System Store/Forward Network file and recreate the directives.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc amt$ring_attributes
*copyc cle$ecc_expression_result
*copyc nfc$manage_store_forward_file
*copyc nfc$sf_directive_command_names
*copyc nfe$manage_store_forward_netwrk
*copyc nft$sf_application_name_info
*copyc nft$sf_application_set
*copyc nft$sf_destination_names_array
*copyc nft$sf_dest_group_comparision
*copyc nft$sf_display_name_value
*copyc nft$sf_display_options_set
*copyc nft$sf_group_name_information
*copyc nft$sf_rel_ptr_appl_name_info
*copyc nft$sf_rel_ptr_group_name_info
*copyc nft$sf_rel_ptr_source_name_info
*copyc nft$sf_rel_ptr_target_name_info
*copyc nft$sf_source_name_information
*copyc nft$sf_target_name_information
*copyc oss$job_paged_literal
*copyc osv$lower_to_upper
?? POP ??
*copyc amp$get_segment_pointer
*copyc amp$put_next
*copyc amp$return
*copyc amp$set_segment_eoi
*copyc avp$get_capability
*copyc clp$begin_utility
*copyc clp$close_display
*copyc clp$convert_file_ref_to_string
*copyc clp$count_list_elements
*copyc clp$end_include
*copyc clp$end_utility
*copyc clp$evaluate_file_reference
*copyc clp$evaluate_parameters
*copyc clp$get_parameter_list_text
*copyc clp$include_file
*copyc clp$new_display_line
*copyc clp$open_display_reference
*copyc clp$reset_for_next_display_page
*copyc clp$put_display
*copyc clp$scan_command_file
*copyc clp$trimmed_string_size
*copyc fsp$close_file
*copyc fsp$copy_file
*copyc fsp$open_file
*copyc jmp$system_job
*copyc osp$append_status_file
*copyc osp$append_status_parameter
*copyc osp$format_message
*copyc osp$set_status_abnormal
*copyc nfp$close_store_forward_file
*copyc nfp$open_store_forward_file
*copyc nfv$manage_sfn_directives
*copyc nfv$manage_sf_network
*copyc nfv$sf_application_names
*copyc pfp$attach
*copyc pfp$define
*copyc pfp$purge
*copyc pmp$disestablish_cond_handler
*copyc pmp$establish_condition_handler
*copyc pmp$get_legible_date_time
*copyc pmp$get_os_version
*copyc pmp$get_unique_name
*copyc pmp$log
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

  VAR
    output_file_identifier: amt$file_identifier,
    output_file_open: boolean,
    ptr_application_name_list: ^nft$sf_application_name_info,
    ptr_group_name_list: ^nft$sf_group_name_information,
    ptr_source_name_list: ^nft$sf_source_name_information,
    ptr_target_name_list: ^nft$sf_target_name_information;

?? OLDTITLE ??
?? NEWTITLE := 'cmd_define_application_switch', EJECT ??

{ PURPOSE:
{   This is the Utility's command DEFINE_APPLICATION_NAME_SWITCH.  It will
{   add a unique application_name onto the application_names_list.

  PROCEDURE cmd_define_application_switch
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

*copyc nft$pdt_def_application_switch

    VAR
      application_information: nft$sf_application_name_info,
      application_qualifier_index: nft$sf_applications,
      ignore_status: ost$status,
      parameter_text: ^clt$parameter_list_text,
      ptr_application_qualifiers: ^clt$data_value,
      ptr_last_entry: ^nft$sf_application_name_info,
      ptr_new_application_info: ^nft$sf_application_name_info;

    status.normal := TRUE;

    clp$evaluate_parameters (parameter_list, #SEQ(pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      IF status.condition <> cle$parameters_displayed THEN

{ Get the parameter list and write the command and the parameter list to the output file

        clp$get_parameter_list_text (^parameter_list, parameter_text, ignore_status);
        write_command_to_output (nfc$cmd_def_appl_name_switch, parameter_text^, ignore_status);
        write_status_to_output (status);
      IFEND;
      RETURN;
    IFEND;

{ Get the parameter list and write the command and the parameter list to the output file

    clp$get_parameter_list_text (^parameter_list, parameter_text, status);
    IF NOT status.normal THEN
      write_status_to_output (status);
      RETURN;
    IFEND;

    write_command_to_output (nfc$cmd_def_appl_name_switch, parameter_text^, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Save the next_hop_application value

    application_information.next_hop_application := pvt [p$next_hop_application].value^ .name_value;

{ Initialize the application qualifier set to NULL and then add all unique application qualifiers into the set

    application_information.application_qualifier := $nft$sf_application_set [];
    ptr_application_qualifiers := pvt [p$application_qualifier].value;

    WHILE ptr_application_qualifiers <> NIL DO
    /add_application_qual_to_set/
      FOR application_qualifier_index := LOWERBOUND (nfv$sf_application_names)
            TO UPPERBOUND (nfv$sf_application_names) DO
        IF ptr_application_qualifiers^ .element_value^ .name_value = nfv$sf_application_names
              [application_qualifier_index] THEN
          application_information.application_qualifier := application_information.application_qualifier +
                $nft$sf_application_set [application_qualifier_index];
          EXIT /add_application_qual_to_set/;
        IFEND;
      FOREND /add_application_qual_to_set/;
      ptr_application_qualifiers := ptr_application_qualifiers^ .link;
    WHILEND;

    IF pvt [p$destination_group_qualifier].specified THEN
      application_information.destination_group_qualifier := pvt [p$destination_group_qualifier].value^ .
            name_value;
    ELSE

{ The destination_group_qualifier was not specified, which means that the application will be switch for all
{ destinations.

      application_information.destination_group_qualifier := osc$null_name;
    IFEND;

    application_information.link.relative_pointer := FALSE;
    application_information.link.ptr := NIL;

{ Allocate some space for the new application_name_switch information and add it to the end of the linked list

    ALLOCATE ptr_new_application_info;
    ptr_new_application_info^ := application_information;

    IF ptr_application_name_list = NIL THEN
      ptr_application_name_list := ptr_new_application_info;
    ELSE
      ptr_last_entry := ptr_application_name_list;
      IF ptr_last_entry^.link.relative_pointer THEN
        osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
              'CMD_DEFINE_APPLICATION_SWITCH 1', status);
        RETURN;
      IFEND;
      WHILE ptr_last_entry^.link.ptr <> NIL DO
        ptr_last_entry := ptr_last_entry^.link.ptr;
        IF ptr_last_entry^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                'CMD_DEFINE_APPLICATION_SWITCH 2', status);
          RETURN;
        IFEND;
      WHILEND;
      ptr_last_entry^.link.ptr := ptr_new_application_info;
    IFEND;
  PROCEND cmd_define_application_switch;
?? OLDTITLE ??
?? NEWTITLE := 'cmd_define_destination_group', EJECT ??

{ PURPOSE:
{   This is the Utility's command DEFINE_DESTINATION_GROUP.  It will
{   add a unique group_name onto the group_names_list.  If a duplicate
{   destination already exists the second occurrance will be ignored.

  PROCEDURE cmd_define_destination_group
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

*copyc nft$pdt_def_destination_group

    VAR
      destination_name: nft$parameter_24_definition,
      destination_name_array_index: ost$non_negative_integers,
      duplicate_name_found: boolean,
      group_name_information: nft$sf_group_name_information,
      ignore_status: ost$status,
      index: ost$non_negative_integers,
      number_of_destination_names: ost$non_negative_integers,
      parameter_text: ^clt$parameter_list_text,
      ptr_destination_names: ^clt$data_value,
      ptr_last_entry: ^nft$sf_group_name_information,
      ptr_new_group_name_info: ^nft$sf_group_name_information;

    status.normal := TRUE;

    clp$evaluate_parameters (parameter_list, #SEQ(pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      IF status.condition <> cle$parameters_displayed THEN

{ Get the parameter list and write the command and the parameter list to the output file

        clp$get_parameter_list_text (^parameter_list, parameter_text, ignore_status);
        write_command_to_output (nfc$cmd_def_destination_group, parameter_text^, ignore_status);
        write_status_to_output (status);
      IFEND;
      RETURN;
    IFEND;

{ Get the parameter list and write the command and the parameter list to the output file

    clp$get_parameter_list_text (^parameter_list, parameter_text, status);
    IF NOT status.normal THEN
      write_status_to_output (status);
      RETURN;
    IFEND;

    write_command_to_output (nfc$cmd_def_destination_group, parameter_text^, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    group_name_information.group_name := pvt [p$group_name].value^ .name_value;

{ Get the number of destination_names specified.

    number_of_destination_names := clp$count_list_elements (pvt [p$destination_name].value);

    destination_name_array_index := 0;

{ Allocate space for the list of destination_names.

    group_name_information.ptr_destination_names.relative_pointer := FALSE;
    ALLOCATE group_name_information.ptr_destination_names.ptr: [1 .. number_of_destination_names];
    ptr_destination_names := pvt [p$destination_name] .value;

    WHILE ptr_destination_names <> NIL DO
      convert_parameter_to_ost$name (ptr_destination_names^ .element_value^, destination_name.value,
            destination_name.size, status);
      IF NOT status.normal THEN
        IF (status.condition = nfe$sf_name_too_short) OR (status.condition = nfe$sf_name_too_long) OR
              (status.condition = nfe$sf_string_too_short) OR (status.condition = nfe$sf_string_too_long) THEN
          osp$append_status_parameter (osc$status_parameter_delimiter, 'destination_name', status);
        IFEND;
        write_status_to_output (status);
        RETURN;
      IFEND;

{ Check to see if the destination_name has been specified before.

      duplicate_name_found := FALSE;

      IF destination_name_array_index > 0 THEN

      /unique_destination_name/
        FOR index := 1 TO destination_name_array_index DO
          IF destination_name = group_name_information.ptr_destination_names.ptr^ [index] THEN
            duplicate_name_found := TRUE;
            EXIT /unique_destination_name/;
          IFEND;
        FOREND /unique_destination_name/;
      IFEND;

{ If the destination_name is unique add it into the destination name array

      IF NOT duplicate_name_found THEN
        destination_name_array_index := destination_name_array_index + 1;
        group_name_information.ptr_destination_names.ptr^ [destination_name_array_index] := destination_name;
      IFEND;
      ptr_destination_names := ptr_destination_names^ .link;
    WHILEND;

    group_name_information.destination_name_count := destination_name_array_index;
    group_name_information.link.relative_pointer := FALSE;
    group_name_information.link.ptr := NIL;

{ Allocate some space for the new destination_group information and add it to the end of the linked list.

    ALLOCATE ptr_new_group_name_info;
    ptr_new_group_name_info^ := group_name_information;

    IF ptr_group_name_list = NIL THEN
      ptr_group_name_list := ptr_new_group_name_info;
    ELSE
      ptr_last_entry := ptr_group_name_list;
      IF ptr_last_entry^.link.relative_pointer THEN
        osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
              'CMD_DEFINE_DESTINATION_GROUP 1', status);
        RETURN;
      IFEND;
      WHILE ptr_last_entry^.link.ptr <> NIL DO
        ptr_last_entry := ptr_last_entry^.link.ptr;
        IF ptr_last_entry^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                'CMD_DEFINE_DESTINATION_GROUP 2', status);
          RETURN;
        IFEND;
      WHILEND;
      ptr_last_entry^.link.ptr := ptr_new_group_name_info;
    IFEND;
  PROCEND cmd_define_destination_group;
?? OLDTITLE ??
?? NEWTITLE := 'cmd_define_dest_name_switch', EJECT ??

{ PURPOSE:
{   This is the Utility's command DEFINE_DESTINATION_NAME_SWITCH.  It will
{   add a unique target_name onto the target_names_list.

  PROCEDURE cmd_define_dest_name_switch
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

*copyc nft$pdt_def_dest_name_switch

    VAR
      application_qualifier_index: nft$sf_applications,
      application_qualifier_set: nft$sf_application_set,
      ignore_status: ost$status,
      parameter_text: ^clt$parameter_list_text,
      ptr_application_qualifiers: ^clt$data_value,
      ptr_last_entry: ^nft$sf_target_name_information,
      ptr_new_target_name_info: ^nft$sf_target_name_information,
      target_name_information: nft$sf_target_name_information;

    status.normal := TRUE;

    clp$evaluate_parameters (parameter_list, #SEQ(pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      IF status.condition <> cle$parameters_displayed THEN

{ Get the parameter list and write the command and the parameter list to the output file

        clp$get_parameter_list_text (^parameter_list, parameter_text, ignore_status);
        write_command_to_output (nfc$cmd_def_target_name_switch, parameter_text^, ignore_status);
        write_status_to_output (status);
      IFEND;
      RETURN;
    IFEND;

{ Get the parameter list and write the command and the parameter list to the output file

    clp$get_parameter_list_text (^parameter_list, parameter_text, status);
    IF NOT status.normal THEN
      write_status_to_output (status);
      RETURN;
    IFEND;

    write_command_to_output (nfc$cmd_def_target_name_switch, parameter_text^, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    convert_parameter_to_ost$name (pvt [p$name].value^, target_name_information.target_name.value,
          target_name_information.target_name.size, status);
    IF NOT status.normal THEN
      IF (status.condition = nfe$sf_name_too_short) OR (status.condition = nfe$sf_name_too_long) OR
            (status.condition = nfe$sf_string_too_short) OR (status.condition = nfe$sf_string_too_long) THEN
        osp$append_status_parameter (osc$status_parameter_delimiter, 'destination name', status);
      IFEND;
      write_status_to_output (status);
      RETURN;
    IFEND;

    convert_parameter_to_ost$name (pvt [p$next_hop_name].value^, target_name_information.next_hop_name.value,
          target_name_information.next_hop_name.size, status);
    IF NOT status.normal THEN
      IF (status.condition = nfe$sf_name_too_short) OR (status.condition = nfe$sf_name_too_long) OR
            (status.condition = nfe$sf_string_too_short) OR (status.condition = nfe$sf_string_too_long) THEN
        osp$append_status_parameter (osc$status_parameter_delimiter, 'next_hop_name', status);
      IFEND;
      write_status_to_output (status);
      RETURN;
    IFEND;

{ Initialize the application qualifier set to NULL and then add all unique application qualifiers into the set

    target_name_information.application_qualifier := $nft$sf_application_set [];
    ptr_application_qualifiers := pvt [p$application_qualifier] .value;

    WHILE ptr_application_qualifiers <> NIL DO
    /add_application_qual_to_set/
      FOR application_qualifier_index := LOWERBOUND (nfv$sf_application_names)
            TO UPPERBOUND (nfv$sf_application_names) DO
        IF ptr_application_qualifiers^ .element_value^ .name_value = nfv$sf_application_names
              [application_qualifier_index] THEN
          target_name_information.application_qualifier := target_name_information.application_qualifier +
                $nft$sf_application_set [application_qualifier_index];
          EXIT /add_application_qual_to_set/;
        IFEND;
      FOREND /add_application_qual_to_set/;
      ptr_application_qualifiers := ptr_application_qualifiers^ .link;
    WHILEND;
    target_name_information.link.relative_pointer := FALSE;
    target_name_information.link.ptr := NIL;

{ Allocate some space for the new target_name_switch information and add it to the end of the linked list.

    ALLOCATE ptr_new_target_name_info;
    ptr_new_target_name_info^ := target_name_information;

    IF ptr_target_name_list = NIL THEN
      ptr_target_name_list := ptr_new_target_name_info;
    ELSE
      ptr_last_entry := ptr_target_name_list;
      IF ptr_last_entry^.link.relative_pointer THEN
        osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
              'CMD_DEFINE_DEST_NAME_SWITCH 1', status);
        RETURN;
      IFEND;
      WHILE ptr_last_entry^.link.ptr <> NIL DO
        ptr_last_entry := ptr_last_entry^.link.ptr;
        IF ptr_last_entry^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                'CMD_DEFINE_DEST_NAME_SWITCH 2', status);
          RETURN;
        IFEND;
      WHILEND;
      ptr_last_entry^.link.ptr := ptr_new_target_name_info;
    IFEND;
  PROCEND cmd_define_dest_name_switch;
?? OLDTITLE ??
?? NEWTITLE := 'cmd_define_source_name_switch', EJECT ??

{ PURPOSE:
{   This is the Utility's command DEFINE_SOURCE_NAME_SWITCH.  It will
{   add a unique source_name onto the source_names_list.

  PROCEDURE cmd_define_source_name_switch
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

*copyc nft$pdt_def_source_name_switch

    VAR
      application_qualifier_index: nft$sf_applications,
      ignore_status: ost$status,
      source_name_information: nft$sf_source_name_information,
      parameter_text: ^clt$parameter_list_text,
      ptr_application_qualifiers: ^clt$data_value,
      ptr_last_entry: ^nft$sf_source_name_information,
      ptr_new_source_name_info: ^nft$sf_source_name_information;

    status.normal := TRUE;

    clp$evaluate_parameters (parameter_list, #SEQ(pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      IF status.condition <> cle$parameters_displayed THEN

{ Get the parameter list and write the command and the parameter list to the output file

        clp$get_parameter_list_text (^parameter_list, parameter_text, ignore_status);
        write_command_to_output (nfc$cmd_def_source_name_switch, parameter_text^, ignore_status);
        write_status_to_output (status);
      IFEND;
      RETURN;
    IFEND;

{ Get the parameter list and write the command and the parameter list to the output file

    clp$get_parameter_list_text (^parameter_list, parameter_text, status);
    IF NOT status.normal THEN
      write_status_to_output (status);
      RETURN;
    IFEND;

    write_command_to_output (nfc$cmd_def_source_name_switch, parameter_text^, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    convert_parameter_to_ost$name (pvt [p$name].value^, source_name_information.source_name.value,
          source_name_information.source_name.size, status);
    IF NOT status.normal THEN
      IF (status.condition = nfe$sf_name_too_short) OR (status.condition = nfe$sf_name_too_long) OR
            (status.condition = nfe$sf_string_too_short) OR (status.condition = nfe$sf_string_too_long) THEN
        osp$append_status_parameter (osc$status_parameter_delimiter, 'source name', status);
      IFEND;
      write_status_to_output (status);
      RETURN;
    IFEND;

    convert_parameter_to_ost$name (pvt [p$next_hop_name].value^, source_name_information.next_hop_name.value,
          source_name_information.next_hop_name.size, status);
    IF NOT status.normal THEN
      IF (status.condition = nfe$sf_name_too_short) OR (status.condition = nfe$sf_name_too_long) OR
            (status.condition = nfe$sf_string_too_short) OR (status.condition = nfe$sf_string_too_long) THEN
        osp$append_status_parameter (osc$status_parameter_delimiter, 'next_hop_name', status);
      IFEND;
      write_status_to_output (status);
      RETURN;
    IFEND;

{ Initialize the application qualifier set to NULL and then add all unique application qualifiers into the set

    source_name_information.application_qualifier := $nft$sf_application_set [];
    ptr_application_qualifiers := pvt [p$application_qualifier] .value;

    WHILE ptr_application_qualifiers <> NIL DO
    /add_application_qual_to_set/
      FOR application_qualifier_index := LOWERBOUND (nfv$sf_application_names)
            TO UPPERBOUND (nfv$sf_application_names) DO
        IF ptr_application_qualifiers^ .element_value^ .name_value = nfv$sf_application_names
              [application_qualifier_index] THEN
          source_name_information.application_qualifier := source_name_information.application_qualifier +
                $nft$sf_application_set [application_qualifier_index];
          EXIT /add_application_qual_to_set/;
        IFEND;
      FOREND /add_application_qual_to_set/;
      ptr_application_qualifiers := ptr_application_qualifiers^ .link;
    WHILEND;

    IF pvt [p$destination_group_qualifier].specified THEN
      source_name_information.destination_group_qualifier := pvt [p$destination_group_qualifier].value^ .
            name_value;
    ELSE

{ The destination_group_qualifier was not specified, which means that the source name will be switch for all
{ destinations.

      source_name_information.destination_group_qualifier := osc$null_name;
    IFEND;
    source_name_information.link.relative_pointer := FALSE;
    source_name_information.link.ptr := NIL;

{ Allocate some space for the new source_name_switch information and add it to the end of the linked list.

    ALLOCATE ptr_new_source_name_info;
    ptr_new_source_name_info^ := source_name_information;

    IF ptr_source_name_list = NIL THEN
      ptr_source_name_list := ptr_new_source_name_info;
    ELSE
      ptr_last_entry := ptr_source_name_list;
      IF ptr_last_entry^.link.relative_pointer THEN
        osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
              'CMD_DEFINE_SOURCE_NAME_SWITCH 1', status);
        RETURN;
      IFEND;
      WHILE ptr_last_entry^.link.ptr <> NIL DO
        ptr_last_entry := ptr_last_entry^.link.ptr;
        IF ptr_last_entry^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                'CMD_DEFINE_SOURCE_NAME_SWITCH 2', status);
          RETURN;
        IFEND;
      WHILEND;
      ptr_last_entry^.link.ptr := ptr_new_source_name_info;
    IFEND;
  PROCEND cmd_define_source_name_switch;
?? OLDTITLE ??
?? NEWTITLE := 'cmd_display_sf_network', EJECT ??

{ PURPOSE:
{   This is the Utility's command DISPLAY_STORE_FORWARD_NETWORK.  It will
{   display the SYSTEM'S existing STORE/FORWARD Network file.

  PROCEDURE cmd_display_sf_network
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

*copyc nft$pdt_display_sf_network

    CONST
      all_known_destinations = 'CHANGED FOR ALL DESTINATIONS',
      append_application_information = ' with the APPLICATION_QUALIFIER of ',
      append_application_length = 35,
      append_name_information = '  with the NAME or STRING of ',
      append_name_length = 29,
      application_ignored_message = ' the APPLICATION_QUALIFIER is being IGNORED.',
      application_name_w_space_length = 5,
      information_message = '  --  INFORMATION',
      line_skip_for_first_entry = 2,
      line_skip_for_next_entry = 1,
      max_display_line_length = 72,
      no_information_message = ' has no information defined',
      start_col_for_info = 40;

    VAR
      application_value: nft$sf_display_name_value,
      default_ring_attributes: amt$ring_attributes,
      display_control: clt$display_control,
      display_option_index: ost$non_negative_integers,
      display_option_set: nft$sf_display_options_set,
      name_value: nft$sf_display_name_value,
      ptr_display_options: ^clt$data_value,
      store_forward_file_info: nft$store_forward_file_info;

?? NEWTITLE := 'display_application_name_switch', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to display the APPLICATION_NAME_SWITCHes to
{   the MANAGE_STORE_FORWARD_NETWORK user.

    PROCEDURE display_application_name_switch
      (    store_forward_file_info: nft$store_forward_file_info;
           name_value: nft$sf_display_name_value;
           application_value: nft$sf_display_name_value;
       VAR display_control: clt$display_control;
       VAR status: ost$status);

      CONST
        application_qual_parameter = '    APPLICATION_QUALIFIER            :  ',
        destination_group_parameter = '    DESTINATION_GROUP_QUALIFIER      :  ',
        next_hop_appl_parameter = '    NEXT_HOP_APPLICATION             :  ';

      VAR
        application_found: boolean,
        application_name: nft$sf_applications,
        application_name_offset: ost$non_negative_integers,
        application_qualifier_index: nft$sf_applications,
        display_line: string (max_display_line_length),
        display_line_length: integer,
        first_entry_found: boolean,
        ignore_status: ost$status,
        name_found: boolean,
        ptr_current_application_info: ^nft$sf_application_name_info;

      status.normal := TRUE;

{ Determine the application name for the information to display

      IF application_value.value_specified THEN
        application_name := nfc$sf_unknown_application;

      /find_application_qualifier/
        FOR application_qualifier_index := LOWERBOUND (nfv$sf_application_names)
              TO UPPERBOUND (nfv$sf_application_names) DO
          IF application_value.value = nfv$sf_application_names [application_qualifier_index] THEN
            application_name := application_qualifier_index;
            EXIT /find_application_qualifier/;
          IFEND;
        FOREND /find_application_qualifier/;
      IFEND;

      first_entry_found := FALSE;
      ptr_current_application_info := #PTR (store_forward_file_info.pointers.ptr_application_name_list,
            store_forward_file_info.segment_pointer.sequence_pointer^);

      WHILE ptr_current_application_info <> NIL DO
        IF NOT ptr_current_application_info^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_rptr,
                'DISPLAY_APPLICATION_NAME_SWITCH', status);
          RETURN;
        IFEND;

{ Verify that the value specified on the name parameter is the same as the next_hop_application name or
{ destination_group_qualifier name.  If no name parameter was specified then all entries will be displayed.

        IF name_value.value_specified THEN
          IF (name_value.value = ptr_current_application_info^.next_hop_application) OR
                (name_value.value = ptr_current_application_info^.destination_group_qualifier) THEN
            name_found := TRUE;
          ELSE
            name_found := FALSE;
          IFEND;
        ELSE
          name_found := TRUE;
        IFEND;

{ Verify that the value specified on the application_qualifier parameter is in the set of
{ application_qualifiers for this entry.  If no application_qualifier was specified then all entries will be
{ displayed.

        IF application_value.value_specified THEN
          IF application_name IN ptr_current_application_info^.application_qualifier THEN
            application_found := TRUE;
          ELSE
            application_found := FALSE;
          IFEND;
        ELSE
          application_found := TRUE;
        IFEND;

{ Display the entry if both the name value was found (or not specified) and the application_qualifier value
{ was found (or not specified).

        IF name_found AND application_found THEN
          IF NOT first_entry_found THEN

{ Display the header on the first page of information for this directive, once an qualifing entry has been
{ found.

            display_first_header (nfc$cmd_def_appl_name_switch, display_control);
            first_entry_found := TRUE;
          IFEND;

{ Display all the information to the output file for this directive. Display the next_hop_application
{ information

          clp$new_display_line (display_control, line_skip_for_next_entry, ignore_status);
          display_line := next_hop_appl_parameter;
          display_line (start_col_for_info, * ) := ptr_current_application_info^.next_hop_application;
          clp$put_display (display_control, display_line, clc$trim, ignore_status);

{ Display the application_qualifier information

          application_name_offset := 0;
          display_line := application_qual_parameter;
          FOR application_qualifier_index := LOWERBOUND (nfv$sf_application_names)
                TO UPPERBOUND (nfv$sf_application_names) DO
            IF application_qualifier_index IN ptr_current_application_info^.application_qualifier THEN
              display_line ((start_col_for_info + application_name_offset), * ) :=
                    nfv$sf_application_names [application_qualifier_index];
              application_name_offset := application_name_offset + application_name_w_space_length;
            IFEND;
          FOREND;
          clp$put_display (display_control, display_line, clc$trim, ignore_status);

{ Display the destination_group_qualifier information

          display_line := destination_group_parameter;
          IF ptr_current_application_info^.destination_group_qualifier = osc$null_name THEN
            display_line (start_col_for_info, * ) := all_known_destinations;
          ELSE
            display_line (start_col_for_info, * ) := ptr_current_application_info^.
                  destination_group_qualifier;
          IFEND;
          clp$put_display (display_control, display_line, clc$trim, ignore_status);
        IFEND;

{ Process next entry in the linked list for this directive.

        ptr_current_application_info := #PTR (ptr_current_application_info^.link.relative_ptr,
              store_forward_file_info.segment_pointer.sequence_pointer^);
      WHILEND;

      IF NOT first_entry_found THEN

{ Tell the user no information was found for the requested information for this directive.

        display_no_entry_found (nfc$cmd_def_appl_name_switch, name_value, application_value, display_control);
      IFEND;
    PROCEND display_application_name_switch;
?? OLDTITLE ??
?? NEWTITLE := 'display_destination_name_switch', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to display the DESTINATION_NAME_SWITCHes to
{   the MANAGE_STORE_FORWARD_NETWORK user.

    PROCEDURE display_destination_name_switch
      (    store_forward_file_info: nft$store_forward_file_info;
           name_value: nft$sf_display_name_value;
           application_value: nft$sf_display_name_value;
       VAR display_control: clt$display_control;
       VAR status: ost$status);

      CONST
        application_qual_parameter = '      APPLICATION_QUALIFIER          :  ',
        next_hop_name_parameter = '      NEXT_HOP_NAME                  :  ',
        target_name_parameter = '    DESTINATION NAME                 :  ';

      VAR
        application_found: boolean,
        application_name: nft$sf_applications,
        application_name_offset: ost$non_negative_integers,
        application_qualifier_index: nft$sf_applications,
        display_line: string (max_display_line_length),
        display_line_length: integer,
        first_entry_found: boolean,
        ignore_status: ost$status,
        name_found: boolean,
        ptr_current_target_name_info: ^nft$sf_target_name_information;

      status.normal := TRUE;

{ Determine the application name for the information to display

      IF application_value.value_specified THEN
        application_name := nfc$sf_unknown_application;

      /find_application_qualifier/
        FOR application_qualifier_index := LOWERBOUND (nfv$sf_application_names)
              TO UPPERBOUND (nfv$sf_application_names) DO
          IF application_value.value = nfv$sf_application_names [application_qualifier_index] THEN
            application_name := application_qualifier_index;
            EXIT /find_application_qualifier/;
          IFEND;
        FOREND /find_application_qualifier/;
      IFEND;

      first_entry_found := FALSE;
      ptr_current_target_name_info := #PTR (store_forward_file_info.pointers.ptr_target_name_list,
            store_forward_file_info.segment_pointer.sequence_pointer^);

      WHILE ptr_current_target_name_info <> NIL DO
        IF NOT ptr_current_target_name_info^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_rptr,
                'DISPLAY_DESTINATION_NAME_SWITCH', status);
          RETURN;
        IFEND;

{ Verify that the value specified on the name parameter is the same as the target_name or next_hop_name.
{ If no name parameter was specified then all entries will be displayed.

        IF name_value.value_specified THEN
          IF (name_value.value = ptr_current_target_name_info^.target_name.value) OR
                (name_value.value = ptr_current_target_name_info^.next_hop_name.value) THEN
            name_found := TRUE;
          ELSE
            name_found := FALSE;
          IFEND;
        ELSE
          name_found := TRUE;
        IFEND;

{ Verify that the value specified on the application_qualifier parameter is in the set of
{ application_qualifiers for this entry.  If no application_qualifier was specified then all entries will be
{ displayed.

        IF application_value.value_specified THEN
          IF application_name IN ptr_current_target_name_info^.application_qualifier THEN
            application_found := TRUE;
          ELSE
            application_found := FALSE;
          IFEND;
        ELSE
          application_found := TRUE;
        IFEND;

{ Display the entry if both the name value was found (or not specified) and the application_qualifier value
{ was found (or not specified).

        IF name_found AND application_found THEN
          IF NOT first_entry_found THEN

{ Display the header on the first page of information for this directive, once an qualifing entry has been
{ found.

            display_first_header (nfc$cmd_def_target_name_switch, display_control);
            first_entry_found := TRUE;
          IFEND;

{ Display all the information to the output file for this directive.  Display the current destination name
{ information

          clp$new_display_line (display_control, line_skip_for_next_entry, ignore_status);
          display_line := target_name_parameter;
          display_line (start_col_for_info, * ) := ptr_current_target_name_info^.target_name.value;
          clp$put_display (display_control, display_line, clc$trim, ignore_status);

{ Display the next_hop_name information

          display_line := next_hop_name_parameter;
          display_line (start_col_for_info, * ) := ptr_current_target_name_info^.next_hop_name.value;
          clp$put_display (display_control, display_line, clc$trim, ignore_status);

{ Display the application_qualifier information

          application_name_offset := 0;
          display_line := application_qual_parameter;
          FOR application_qualifier_index := LOWERBOUND (nfv$sf_application_names)
                TO UPPERBOUND (nfv$sf_application_names) DO
            IF application_qualifier_index IN ptr_current_target_name_info^.application_qualifier THEN
              display_line ((start_col_for_info + application_name_offset), * ) :=
                    nfv$sf_application_names [application_qualifier_index];
              application_name_offset := application_name_offset + application_name_w_space_length;
            IFEND;
          FOREND;
          clp$put_display (display_control, display_line, clc$trim, ignore_status);
        IFEND;

{ Process next entry in the linked list for this directive.

        ptr_current_target_name_info := #PTR (ptr_current_target_name_info^.link.relative_ptr,
              store_forward_file_info.segment_pointer.sequence_pointer^);
      WHILEND;

      IF NOT first_entry_found THEN

{ Tell the user no information was found for the requested information for this directive.

        display_no_entry_found (nfc$cmd_def_target_name_switch, name_value, application_value,
              display_control);
      IFEND;
    PROCEND display_destination_name_switch;
?? OLDTITLE ??
?? NEWTITLE := 'display_first_header', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to display the first message
{   header on the output file before the first entry is displayed
{   for this directive.

    PROCEDURE display_first_header
      (    command_name: string ( * );
       VAR display_control: clt$display_control);

      VAR
        display_line: string (max_display_line_length),
        display_line_length: integer,
        ignore_status: ost$status;

      clp$new_display_line (display_control, line_skip_for_first_entry, ignore_status);
      display_line := ' ';
      display_line (3, * ) := command_name;
      display_line_length := clp$trimmed_string_size (display_line);
      display_line ((display_line_length + 1), * ) := information_message;
      clp$put_display (display_control, display_line, clc$trim, ignore_status);
    PROCEND display_first_header;
?? OLDTITLE ??
?? NEWTITLE := 'display_no_entry_found', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to display a message to the user
{   stating that no entries were found for the information requested
{   for this directive.

    PROCEDURE display_no_entry_found
      (    command_name: string ( * );
           name_value: nft$sf_display_name_value;
           application_value: nft$sf_display_name_value;
       VAR display_control: clt$display_control);

      CONST
        append_null_string = '''  ''',
        append_period_string = '.',
        append_string_delimiter = '''';

      VAR
        display_line: string (max_display_line_length),
        display_line_length: integer,
        ignore_status: ost$status;

{ Display the no_information was found for this directive.

      clp$new_display_line (display_control, line_skip_for_first_entry, ignore_status);
      display_line := ' ';
      display_line (3, * ) := command_name;
      display_line_length := clp$trimmed_string_size (display_line);
      display_line ((display_line_length + 1), * ) := no_information_message;
      IF NOT (name_value.value_specified OR application_value.value_specified) THEN
        display_line_length := clp$trimmed_string_size (display_line);
        display_line ((display_line_length + 1), * ) := append_period_string;
      IFEND;
      clp$put_display (display_control, display_line, clc$trim, ignore_status);

      IF name_value.value_specified THEN

{ Display the no information was found for the name qualifier for this directive.

        display_line := append_name_information;
        display_line_length := append_name_length;

        IF (name_value.value = osc$null_name) THEN
          display_line ((display_line_length + 1), * ) := append_null_string;
        ELSE
          IF first_character_is_integer (name_value.value) THEN
            display_line ((display_line_length + 1), * ) := append_string_delimiter;
            display_line_length := display_line_length + 1;
          IFEND;
          display_line ((display_line_length + 1), * ) := name_value.value;
          display_line_length := clp$trimmed_string_size (display_line);
          IF first_character_is_integer (name_value.value) THEN
            display_line ((display_line_length + 1), * ) := append_string_delimiter;
          IFEND;
        IFEND;
        IF NOT application_value.value_specified THEN
          display_line_length := clp$trimmed_string_size (display_line);
          display_line ((display_line_length + 1), * ) := append_period_string;
        IFEND;
        clp$put_display (display_control, display_line, clc$trim, ignore_status);
      IFEND;

      IF application_value.value_specified THEN

{ Display the no information was found for the application qualifier for this directive.

        IF name_value.value_specified THEN
          display_line := '  and';
          display_line_length := 6;
        ELSE
          display_line := ' ';
          display_line_length := 2;
        IFEND;

        IF command_name = nfc$cmd_def_destination_group THEN

{ Display application_qualifier ignored for the DEFINE_DESTINATION_GROUP directive since this is not a valid
{ parameter on this command.

          display_line (display_line_length, * ) := application_ignored_message;
        ELSE
          display_line (display_line_length, * ) := append_application_information;
          display_line ((display_line_length + append_application_length), * ) := application_value.value;
          display_line ((display_line_length + append_application_length + 4), * ) := append_period_string;
        IFEND;
        clp$put_display (display_control, display_line, clc$trim, ignore_status);
      IFEND;
    PROCEND display_no_entry_found;
?? OLDTITLE ??
?? NEWTITLE := 'display_group_names', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to display the GROUP_NAMEs to
{   the MANAGE_STORE_FORWARD_NETWORK user.

    PROCEDURE display_group_names
      (    store_forward_file_info: nft$store_forward_file_info;
           name_value: nft$sf_display_name_value;
           application_value: nft$sf_display_name_value;
       VAR display_control: clt$display_control;
       VAR status: ost$status);

      CONST
        destination_name_parameter = '      DESTINATION_NAME               :  ',
        group_name_parameter = '    GROUP_NAME                       :  ';

      VAR
        destination_name_index: ost$non_negative_integers,
        display_line: string (max_display_line_length),
        display_line_length: integer,
        first_entry_found: boolean,
        ignore_status: ost$status,
        name_found: boolean,
        ptr_current_dest_names_info: ^nft$sf_destination_names_array,
        ptr_current_group_name_info: ^nft$sf_group_name_information;

      status.normal := TRUE;
      first_entry_found := FALSE;
      ptr_current_group_name_info := #PTR (store_forward_file_info.pointers.ptr_group_name_list,
            store_forward_file_info.segment_pointer.sequence_pointer^);

      WHILE ptr_current_group_name_info <> NIL DO
        IF NOT ptr_current_group_name_info^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_rptr, 'DISPLAY_GROUP_NAMES 1',
                status);
          RETURN;
        IFEND;
        IF NOT ptr_current_group_name_info^.ptr_destination_names.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_rptr, 'DISPLAY_GROUP_NAMES 2',
                status);
          RETURN;
        IFEND;

{ Verify that the value specified on the name parameter is the same as the group_name.  If no name parameter
{ was specified then all entries will be displayed.

        IF name_value.value_specified THEN
          IF name_value.value = ptr_current_group_name_info^.group_name THEN
            name_found := TRUE;
          ELSE
            name_found := FALSE;

{ Verify that the value specified on the name parameter is in the list of destination names.

            ptr_current_dest_names_info := #PTR (ptr_current_group_name_info^.ptr_destination_names.
                  relative_ptr, store_forward_file_info.segment_pointer.sequence_pointer^);

          /find_specified_name/
            FOR destination_name_index := 1 TO ptr_current_group_name_info^.destination_name_count DO
              IF name_value.value = ptr_current_dest_names_info^ [destination_name_index].value THEN
                name_found := TRUE;
                EXIT /find_specified_name/;
              IFEND;
            FOREND /find_specified_name/;
          IFEND;
        ELSE
          name_found := TRUE;
        IFEND;

{ Display the entry if the name value was found (or not specified).

        IF name_found THEN
          IF NOT first_entry_found THEN

{ Display the header on the first page of information for this directive, once an qualifing entry has been
{ found.

            display_first_header (nfc$cmd_def_destination_group, display_control);
            IF application_value.value_specified THEN

{ Display an application_qualifier was ignored message, since the application_qualifier is not a valid
{ parameter on the DEFINE_DESTINATION_GROUP directive.

              clp$new_display_line (display_control, line_skip_for_next_entry, ignore_status);
              display_line := ' ';
              display_line (4, * ) := application_ignored_message;
              clp$put_display (display_control, display_line, clc$trim, ignore_status);
            IFEND;
            first_entry_found := TRUE;
          IFEND;

{ Display all the information to the output file for this directive.  Display the destination_group_name
{ information

          clp$new_display_line (display_control, line_skip_for_next_entry, ignore_status);
          display_line := group_name_parameter;
          display_line (start_col_for_info, * ) := ptr_current_group_name_info^.group_name;
          clp$put_display (display_control, display_line, clc$trim, ignore_status);

          display_line := destination_name_parameter;
          ptr_current_dest_names_info := #PTR (ptr_current_group_name_info^.ptr_destination_names.
                relative_ptr, store_forward_file_info.segment_pointer.sequence_pointer^);
          FOR destination_name_index := 1 TO ptr_current_group_name_info^.destination_name_count DO

{ Display the destination_names information

            display_line (start_col_for_info, * ) := ptr_current_dest_names_info^ [destination_name_index].
                  value;
            clp$put_display (display_control, display_line, clc$trim, ignore_status);
          FOREND;
        IFEND;

{ Process next entry in the linked list for this directive.

        ptr_current_group_name_info := #PTR (ptr_current_group_name_info^.link.relative_ptr,
              store_forward_file_info.segment_pointer.sequence_pointer^);
      WHILEND;

      IF NOT first_entry_found THEN

{ Tell the user no information was found for the requested information for this directive.

        display_no_entry_found (nfc$cmd_def_destination_group, name_value, application_value,
              display_control);
      IFEND;
    PROCEND display_group_names;
?? OLDTITLE ??
?? NEWTITLE := 'display_source_name_switch', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to display the SOURCE_NAME_SWITCHes to
{   the MANAGE_STORE_FORWARD_NETWORK user.

    PROCEDURE display_source_name_switch
      (    store_forward_file_info: nft$store_forward_file_info;
           name_value: nft$sf_display_name_value;
           application_value: nft$sf_display_name_value;
       VAR display_control: clt$display_control;
       VAR status: ost$status);

      CONST
        application_qual_parameter = '      APPLICATION_QUALIFIER          :  ',
        destination_group_parameter = '      DESTINATION_GROUP_QUALIFIER    :  ',
        next_hop_name_parameter = '      NEXT_HOP_NAME                  :  ',
        source_name_parameter = '    SOURCE NAME                      :  ';

      VAR
        application_found: boolean,
        application_name: nft$sf_applications,
        application_name_offset: ost$non_negative_integers,
        application_qualifier_index: nft$sf_applications,
        display_line: string (max_display_line_length),
        display_line_length: integer,
        first_entry_found: boolean,
        ignore_status: ost$status,
        name_found: boolean,
        ptr_current_source_name_info: ^nft$sf_source_name_information;

      status.normal := TRUE;

{ Determine the application name for the information to display

      IF application_value.value_specified THEN
        application_name := nfc$sf_unknown_application;

      /find_application_qualifier/
        FOR application_qualifier_index := LOWERBOUND (nfv$sf_application_names)
              TO UPPERBOUND (nfv$sf_application_names) DO
          IF application_value.value = nfv$sf_application_names [application_qualifier_index] THEN
            application_name := application_qualifier_index;
            EXIT /find_application_qualifier/;
          IFEND;
        FOREND /find_application_qualifier/;
      IFEND;

      first_entry_found := FALSE;
      ptr_current_source_name_info := #PTR (store_forward_file_info.pointers.ptr_source_name_list,
            store_forward_file_info.segment_pointer.sequence_pointer^);

      WHILE ptr_current_source_name_info <> NIL DO
        IF NOT ptr_current_source_name_info^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_rptr,
                'DISPLAY_SOURCE_NAME_SWITCH', status);
          RETURN;
        IFEND;

{ Verify that the value specified on the name parameter is the same as the source_name or next_hop_name or
{ destination_group_qualifier name.  If no name parameter was specified then all entries will be displayed.

        IF name_value.value_specified THEN
          IF (name_value.value = ptr_current_source_name_info^.source_name.value) OR
                (name_value.value = ptr_current_source_name_info^.next_hop_name.value) OR
                (name_value.value = ptr_current_source_name_info^.destination_group_qualifier) THEN
            name_found := TRUE;
          ELSE
            name_found := FALSE;
          IFEND;
        ELSE
          name_found := TRUE;
        IFEND;

{ Verify that the value specified on the application_qualifier parameter is in the set of
{ application_qualifiers for this entry.  If no application_qualifier was specified then all entries will be
{ displayed.

        IF application_value.value_specified THEN
          IF application_name IN ptr_current_source_name_info^.application_qualifier THEN
            application_found := TRUE;
          ELSE
            application_found := FALSE;
          IFEND;
        ELSE
          application_found := TRUE;
        IFEND;

{ Display the entry if both the name value was found (or not specified) and the application_qualifier value
{ was found (or not specified).

        IF name_found AND application_found THEN
          IF NOT first_entry_found THEN

{ Display the header on the first page of information for this directive, once an qualifing entry has been
{ found.

            display_first_header (nfc$cmd_def_source_name_switch, display_control);
            first_entry_found := TRUE;
          IFEND;

{ Display all the information to the output file for this directive.  Display the source_name information

          clp$new_display_line (display_control, line_skip_for_next_entry, ignore_status);
          display_line := source_name_parameter;
          display_line (start_col_for_info, * ) := ptr_current_source_name_info^.source_name.value;
          clp$put_display (display_control, display_line, clc$trim, ignore_status);

{ Display the next_hop_name information

          display_line := next_hop_name_parameter;
          display_line (start_col_for_info, * ) := ptr_current_source_name_info^.next_hop_name.value;
          clp$put_display (display_control, display_line, clc$trim, ignore_status);

{ Display the application_qualifier information

          application_name_offset := 0;
          display_line := application_qual_parameter;
          FOR application_qualifier_index := LOWERBOUND (nfv$sf_application_names)
                TO UPPERBOUND (nfv$sf_application_names) DO
            IF application_qualifier_index IN ptr_current_source_name_info^.application_qualifier THEN
              display_line ((start_col_for_info + application_name_offset), * ) :=
                    nfv$sf_application_names [application_qualifier_index];
              application_name_offset := application_name_offset + application_name_w_space_length;
            IFEND;
          FOREND;
          clp$put_display (display_control, display_line, clc$trim, ignore_status);

{ Display the destination_group_qualifier information

          display_line := destination_group_parameter;
          IF ptr_current_source_name_info^.destination_group_qualifier = osc$null_name THEN
            display_line (start_col_for_info, * ) := all_known_destinations;
          ELSE
            display_line (start_col_for_info, * ) := ptr_current_source_name_info^.
                  destination_group_qualifier;
          IFEND;
          clp$put_display (display_control, display_line, clc$trim, ignore_status);
        IFEND;

{ Process next entry in the linked list for this directive.

        ptr_current_source_name_info := #PTR (ptr_current_source_name_info^.link.relative_ptr,
              store_forward_file_info.segment_pointer.sequence_pointer^);
      WHILEND;

      IF NOT first_entry_found THEN

{ Tell the user no information was found for the requested information for this directive.

        display_no_entry_found (nfc$cmd_def_source_name_switch, name_value, application_value,
              display_control);
      IFEND;
    PROCEND display_source_name_switch;
?? OLDTITLE ??
?? NEWTITLE := 'write_display_header', EJECT ??

    PROCEDURE write_display_header
      (VAR display_control: clt$display_control;
           page_number: integer;
       VAR status: ost$status);

      CONST
        date_length = 18,
        display_header_length = 132,
        long_date_start = 75,
        long_os_version_start = 21,
        long_page_number_start = 126, {includes leading blank}
        long_page_title_start = 122,
        long_product_level_start = 54,
        long_product_name_start = 28,
        long_time_start = 94,
        nfc$manage_store_forward_level = '88092',
        os_version_length = 6,
        page_number_length = 5, {includes leading blank}
        page_title = 'PAGE',
        product_name = 'ADM STORE_FORWARD_NETWORK',
        product_name_length = 25,
        product_level_length = 5,
        short_date_start = 40,
        short_os_version_start = 1,
        short_page_number_start = 76, {includes leading blank}
        short_page_title_start = 72,
        short_product_level_start = 34,
        short_product_name_start = 8,
        short_time_start = 59,
        time_length = 12;

      VAR
        date: ost$date,
        display_header: string (display_header_length),
        os_version: pmt$os_name,
        page_length: integer,
        page_string: string (10),
        start_of_date: 0 .. display_header_length,
        start_of_time: 0 .. display_header_length,
        time: ost$time;

      status.normal := TRUE;
      display_header := ' ';
      STRINGREP (page_string, page_length, page_number);

      pmp$get_os_version (os_version, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      IF (display_control.page_width < display_header_length) THEN
        start_of_date := short_date_start;
        start_of_time := short_time_start;
        display_header (short_os_version_start, os_version_length) := os_version;
        display_header (short_product_name_start, product_name_length) := product_name;
        display_header (short_product_level_start, product_level_length) := nfc$manage_store_forward_level;
        display_header (short_page_title_start, * ) := page_title;
        display_header (short_page_number_start, page_length) := page_string (1, page_length);
      ELSE
        start_of_date := long_date_start;
        start_of_time := long_time_start;
        display_header (long_os_version_start, os_version_length) := os_version;
        display_header (long_product_name_start, product_name_length) := product_name;
        display_header (long_product_level_start, product_level_length) := nfc$manage_store_forward_level;
        display_header (long_page_title_start, * ) := page_title;
        display_header (long_page_number_start, page_length) := page_string (1, page_length);
      IFEND;

      pmp$get_legible_date_time (osc$default_date, date, osc$default_time, time, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      CASE date.date_format OF
      = osc$month_date =
        display_header (start_of_date, date_length) := date.month;
      = osc$mdy_date =
        display_header (start_of_date, date_length) := date.mdy;
      = osc$iso_date =
        display_header (start_of_date, date_length) := date.iso;
      = osc$dmy_date =
        display_header (start_of_date, date_length) := date.dmy;
      ELSE
        ;
      CASEND;

      CASE time.time_format OF
      = osc$ampm_time =
        display_header (start_of_time, time_length) := time.ampm;
      = osc$hms_time =
        display_header (start_of_time, time_length) := time.hms;
      = osc$millisecond_time =
        display_header (start_of_time, time_length) := time.millisecond;
      ELSE
        ;
      CASEND;

      clp$reset_for_next_display_page (display_control, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$put_display (display_control, display_header, clc$trim, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$new_display_line (display_control, line_skip_for_next_entry, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    PROCEND write_display_header;
?? OLDTITLE, EJECT ??
    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ(pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ get the name or string value for the information to be displayed

    IF pvt [p$name].specified THEN
      name_value.value_specified := TRUE;
      CASE pvt [p$name].value^ .kind OF
      = clc$name =
        name_value.value := pvt [p$name].value^ .name_value;
      = clc$string =
        #TRANSLATE (osv$lower_to_upper, pvt [p$name].value^ .string_value^, name_value.value);
      ELSE
        osp$set_status_abnormal ('CL', cle$wrong_kind_of_value, 'name or string', status);
        RETURN;
      CASEND;
    ELSE
      name_value.value_specified := FALSE;
    IFEND;

{ get the application qualifier for the information to be displayed

    IF pvt [p$application_qualifier].specified THEN
      application_value.value_specified := TRUE;
      application_value.value := pvt [p$application_qualifier] .value^ .name_value;
    ELSE
      application_value.value_specified := FALSE;
    IFEND;

    display_option_set := $nft$sf_display_options_set [];
    ptr_display_options := pvt [p$display_option] .value;

    WHILE ptr_display_options <> NIL DO

{ determine what information options will be displayed

      IF (ptr_display_options^ .element_value^ .name_value = 'APPLICATION_NAME_SWITCH') OR
            (ptr_display_options^ .name_value = 'ANS') THEN
        display_option_set := display_option_set + $nft$sf_display_options_set [nfc$sf_display_applications];
      ELSEIF (ptr_display_options^ .element_value^ .name_value = 'DESTINATION_GROUP') OR
            (ptr_display_options^ .element_value^ .name_value = 'DESTINATION_GROUPS') OR
            (ptr_display_options^ .element_value^ .name_value = 'DG') THEN
        display_option_set := display_option_set + $nft$sf_display_options_set [nfc$sf_display_group_names];
      ELSEIF (ptr_display_options^ .element_value^ .name_value = 'DESTINATION_NAME_SWITCH') OR
            (ptr_display_options^ .element_value^ .name_value = 'DNS') THEN
        display_option_set := display_option_set + $nft$sf_display_options_set [nfc$sf_display_target_names];
      ELSEIF (ptr_display_options^ .element_value^ .name_value = 'SOURCE_NAME_SWITCH') OR
            (ptr_display_options^ .element_value^ .name_value = 'SNS') THEN
        display_option_set := display_option_set + $nft$sf_display_options_set [nfc$sf_display_source_names];
      ELSEIF (ptr_display_options^ .element_value^ .name_value = 'ALL') THEN
        display_option_set := display_option_set + $nft$sf_display_options_set
              [nfc$sf_display_applications, nfc$sf_display_group_names, nfc$sf_display_source_names,
              nfc$sf_display_target_names];
      IFEND;
      ptr_display_options := ptr_display_options^ .link;
    WHILEND;

{ attach and open the latest version of the store_forward_network file

    nfp$open_store_forward_file (TRUE, store_forward_file_info, status);
    IF status.normal AND store_forward_file_info.file_open THEN

{ open the display file as specified by the output parameter

      default_ring_attributes.r1 := #RING (^default_ring_attributes);
      default_ring_attributes.r2 := #RING (^default_ring_attributes);
      default_ring_attributes.r3 := #RING (^default_ring_attributes);

      clp$open_display_reference (pvt [p$output] .value^ .file_value^, ^write_display_header, fsc$list,
            default_ring_attributes, display_control, status);
      IF status.normal THEN

{ display the various information requested

        IF (nfc$sf_display_group_names IN display_option_set) THEN
          display_group_names (store_forward_file_info, name_value, application_value, display_control,
                status);
        IFEND;

        IF (nfc$sf_display_applications IN display_option_set) THEN
          display_application_name_switch (store_forward_file_info, name_value, application_value,
                display_control, status);
        IFEND;

        IF (nfc$sf_display_source_names IN display_option_set) THEN
          display_source_name_switch (store_forward_file_info, name_value, application_value, display_control,
                status);
        IFEND;

        IF (nfc$sf_display_target_names IN display_option_set) THEN
          display_destination_name_switch (store_forward_file_info, name_value, application_value,
                display_control, status);
        IFEND;
      IFEND;

{ close the display file

      clp$close_display (display_control, status);

{ close the store_forward_network file

      nfp$close_store_forward_file (store_forward_file_info, status);
    IFEND;
  PROCEND cmd_display_sf_network;
?? OLDTITLE ??
?? NEWTITLE := 'cmd_generate_sf_network', EJECT ??

{ PURPOSE:
{   This is the Utility's command GENERATE_STORE_FORWARD_NETWORK.  It will
{   create the STORE/FORWARD Network directives from the active SYSTEM'S
{   STORE/FORWARD Network file.

  PROCEDURE cmd_generate_sf_network
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

*copyc nft$pdt_generate_sf_network

    CONST
      append_continuation_line_string = '..',
      append_string_delimiter = '''',
      application_name_w_space_length = 5,
      max_command_parameter_length = 79;

    VAR
      local_status: ost$status,
      store_forward_file_info: nft$store_forward_file_info;

?? NEWTITLE := 'create_application_directives', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to create the MANAGE_STORE_FORWARD_NETWORK
{   application name directives that are currently defined in the System's
{   Store/Forward Network file.

    PROCEDURE create_application_directives
      (    store_forward_file_info: nft$store_forward_file_info;
       VAR status: ost$status);

      CONST
        max_parameter_length_appl_qual = 15,
        max_parameter_length_dest_qual = 36,
        max_parameter_length_x_hop_appl = 36,
        parameter_application_qualifier = ' AQ=(',
        parameter_length_appl_qualifier = 5,
        parameter_destination_qualifier = ' DGQ=',
        parameter_length_dest_qualifier = 5,
        parameter_next_hop_application = 'NHA=',
        parameter_length_next_hop_appl = 4;

      VAR
        application_qualifier_index: nft$sf_applications,
        application_qualifier_length: integer,
        application_qualifier_parameter: string (max_parameter_length_appl_qual),
        destination_qualifier_length: integer,
        destination_qualifier_parameter: string (max_parameter_length_dest_qual),
        next_hop_appl_length: integer,
        next_hop_appl_parameter: string (max_parameter_length_x_hop_appl),
        parameter_list: string (max_command_parameter_length + 1),
        ptr_current_application_info: ^nft$sf_application_name_info;

      status.normal := TRUE;
      ptr_current_application_info := #PTR (store_forward_file_info.pointers.ptr_application_name_list,
            store_forward_file_info.segment_pointer.sequence_pointer^);

      WHILE ptr_current_application_info <> NIL DO
        IF NOT ptr_current_application_info^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_rptr,
                'CREATE_APPLICATION_DIRECTIVES', status);
          RETURN;
        IFEND;

{ Create the next_hop_application parameter

        next_hop_appl_parameter := parameter_next_hop_application;
        next_hop_appl_parameter ((parameter_length_next_hop_appl + 1), * ) :=
              ptr_current_application_info^.next_hop_application;
        next_hop_appl_length := clp$trimmed_string_size (next_hop_appl_parameter);

{ Create the destination_group_qualifier parameter

        IF ptr_current_application_info^.destination_group_qualifier <> osc$null_name THEN
          destination_qualifier_parameter := parameter_destination_qualifier;
          destination_qualifier_parameter ((parameter_length_dest_qualifier + 1), * ) :=
                ptr_current_application_info^.destination_group_qualifier;
        ELSE
          destination_qualifier_parameter := ' ';
        IFEND;
        destination_qualifier_length := clp$trimmed_string_size (destination_qualifier_parameter);

{ Create the application_qualifier parameter

        application_qualifier_parameter := parameter_application_qualifier;
        application_qualifier_length := parameter_length_appl_qualifier;
        FOR application_qualifier_index := LOWERBOUND (nfv$sf_application_names)
              TO UPPERBOUND (nfv$sf_application_names) DO
          IF application_qualifier_index IN ptr_current_application_info^.application_qualifier THEN
            application_qualifier_parameter ((application_qualifier_length + 1), * ) :=
                  nfv$sf_application_names [application_qualifier_index];
            application_qualifier_length := application_qualifier_length + application_name_w_space_length;
          IFEND;
        FOREND;
        application_qualifier_parameter (application_qualifier_length, * ) := ')';
        application_qualifier_length := clp$trimmed_string_size (application_qualifier_parameter);

{ When writting the directive to the output file, break the directive on a parameter boundry.  The maximum
{ output line is 80 characters.  The command name is written along with the parameters on the first call to
{ write this directive to the output file.

        parameter_list := next_hop_appl_parameter;
        IF (nfc$cmd_def_appl_name_length + next_hop_appl_length + application_qualifier_length +
              destination_qualifier_length) < max_command_parameter_length THEN
          parameter_list ((next_hop_appl_length + 1), * ) := application_qualifier_parameter;
          parameter_list ((next_hop_appl_length + application_qualifier_length + 1), * ) :=
                destination_qualifier_parameter;
          write_command_to_output (nfc$cmd_def_appl_name_switch, parameter_list, status);
        ELSEIF (nfc$cmd_def_appl_name_length + next_hop_appl_length + application_qualifier_length) <
              max_command_parameter_length THEN
          parameter_list ((next_hop_appl_length + 1), * ) := application_qualifier_parameter;
          parameter_list ((next_hop_appl_length + application_qualifier_length + 1), * ) :=
                append_continuation_line_string;
          write_command_to_output (nfc$cmd_def_appl_name_switch, parameter_list, status);
          IF status.normal THEN
            write_command_to_output ('', destination_qualifier_parameter, status);
          IFEND;
        ELSE
          parameter_list ((next_hop_appl_length + 1), * ) := append_continuation_line_string;
          write_command_to_output (nfc$cmd_def_appl_name_switch, parameter_list, status);
          IF status.normal THEN
            parameter_list := application_qualifier_parameter;
            parameter_list ((application_qualifier_length + 1), * ) := destination_qualifier_parameter;
            write_command_to_output ('', parameter_list, status);
          IFEND;
        IFEND;
        ptr_current_application_info := #PTR (ptr_current_application_info^.link.relative_ptr,
              store_forward_file_info.segment_pointer.sequence_pointer^);
      WHILEND;
    PROCEND create_application_directives;
?? OLDTITLE ??
?? NEWTITLE := 'create_dest_name_directives', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to create the MANAGE_STORE_FORWARD_NETWORK
{   destination name directives that are currently defined in the System's
{   Store/Forward Network file.

    PROCEDURE create_dest_name_directives
      (    store_forward_file_info: nft$store_forward_file_info;
       VAR status: ost$status);

      CONST
        max_parameter_length_appl_qual = 25,
        max_parameter_length_name = 36,
        max_parameter_length_x_hop_name = 38,
        parameter_application_qualifier = ' AQ=(',
        parameter_length_appl_qualifier = 5,
        parameter_name = 'N=',
        parameter_length_name = 2,
        parameter_next_hop_name = ' NHN=',
        parameter_length_next_hop_name = 5;

      VAR
        application_qualifier_index: nft$sf_applications,
        application_qualifier_length: integer,
        application_qualifier_parameter: string (max_parameter_length_appl_qual),
        name_length: integer,
        name_parameter: string (max_parameter_length_name),
        next_hop_name_length: integer,
        next_hop_name_parameter: string (max_parameter_length_x_hop_name),
        parameter_list: string (max_command_parameter_length + 1),
        ptr_current_target_name_info: ^nft$sf_target_name_information;

      status.normal := TRUE;
      ptr_current_target_name_info := #PTR (store_forward_file_info.pointers.ptr_target_name_list,
            store_forward_file_info.segment_pointer.sequence_pointer^);

      WHILE ptr_current_target_name_info <> NIL DO
        IF NOT ptr_current_target_name_info^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_rptr,
                'CREATE_DEST_NAME_DIRECTIVES', status);
          RETURN;
        IFEND;

{ Create the name parameter

        name_parameter := parameter_name;
        name_length := parameter_length_name;

{ If the value for this parameter begins with an integer, make this parameter a string value by placing quotes
{ before and after the value.

        IF first_character_is_integer (ptr_current_target_name_info^.target_name.value) THEN
          name_length := name_length + 1;
          name_parameter (name_length, 1) := append_string_delimiter;
        IFEND;
        name_parameter ((name_length + 1), * ) := ptr_current_target_name_info^.target_name.value;
        name_length := clp$trimmed_string_size (name_parameter);
        IF first_character_is_integer (ptr_current_target_name_info^.target_name.value) THEN
          name_length := name_length + 1;
          name_parameter (name_length, 1) := append_string_delimiter;
        IFEND;

{ Create the next_hop_name parameter

        next_hop_name_parameter := parameter_next_hop_name;
        next_hop_name_length := parameter_length_next_hop_name;

{ If the value for this parameter begins with an integer, make this parameter a string value by placing quotes
{ before and after the value.

        IF first_character_is_integer (ptr_current_target_name_info^.next_hop_name.value) THEN
          next_hop_name_length := next_hop_name_length + 1;
          next_hop_name_parameter (next_hop_name_length, 1) := append_string_delimiter;
        IFEND;
        next_hop_name_parameter ((next_hop_name_length + 1), * ) :=
              ptr_current_target_name_info^.next_hop_name.value;
        next_hop_name_length := clp$trimmed_string_size (next_hop_name_parameter);
        IF first_character_is_integer (ptr_current_target_name_info^.next_hop_name.value) THEN
          next_hop_name_length := next_hop_name_length + 1;
          next_hop_name_parameter (next_hop_name_length, 1) := append_string_delimiter;
        IFEND;

{ Create the application_qualifier parameter

        application_qualifier_parameter := parameter_application_qualifier;
        application_qualifier_length := parameter_length_appl_qualifier;
        FOR application_qualifier_index := LOWERBOUND (nfv$sf_application_names)
              TO UPPERBOUND (nfv$sf_application_names) DO
          IF application_qualifier_index IN ptr_current_target_name_info^.application_qualifier THEN
            application_qualifier_parameter ((application_qualifier_length + 1), * ) :=
                  nfv$sf_application_names [application_qualifier_index];
            application_qualifier_length := application_qualifier_length + application_name_w_space_length;
          IFEND;
        FOREND;
        application_qualifier_parameter ((application_qualifier_length), * ) := ')';
        application_qualifier_length := clp$trimmed_string_size (application_qualifier_parameter);

{ When writting the directive to the output file, break the directive on a parameter boundry.  The maximum
{ output line is 80 characters.  The command name is written along with the parameters on the first call to
{ write this directive to the output file.

        parameter_list := name_parameter;
        IF (nfc$cmd_def_target_name_length + name_length + next_hop_name_length +
              application_qualifier_length) < max_command_parameter_length THEN
          parameter_list ((name_length + 1), * ) := next_hop_name_parameter;
          parameter_list ((name_length + next_hop_name_length + 1), * ) := application_qualifier_parameter;
          write_command_to_output (nfc$cmd_def_target_name_switch, parameter_list, status);
        ELSEIF (nfc$cmd_def_target_name_length + name_length + next_hop_name_length) <
              max_command_parameter_length THEN
          parameter_list ((name_length + 1), * ) := next_hop_name_parameter;
          parameter_list ((name_length + next_hop_name_length + 1), * ) := append_continuation_line_string;
          write_command_to_output (nfc$cmd_def_target_name_switch, parameter_list, status);
          IF status.normal THEN
            write_command_to_output ('', application_qualifier_parameter, status);
          IFEND;
        ELSE
          parameter_list ((name_length + 1), * ) := append_continuation_line_string;
          write_command_to_output (nfc$cmd_def_target_name_switch, parameter_list, status);
          IF status.normal THEN
            parameter_list := next_hop_name_parameter;
            parameter_list ((next_hop_name_length + 1), * ) := application_qualifier_parameter;
            write_command_to_output ('', parameter_list, status);
          IFEND;
        IFEND;
        ptr_current_target_name_info := #PTR (ptr_current_target_name_info^.link.relative_ptr,
              store_forward_file_info.segment_pointer.sequence_pointer^);
      WHILEND;
    PROCEND create_dest_name_directives;
?? OLDTITLE ??
?? NEWTITLE := 'create_group_name_directives', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to create the MANAGE_STORE_FORWARD_NETWORK
{   group name directives that are currently defined in the System's
{   Store/Forward Network file.

    PROCEDURE create_group_name_directives
      (    store_forward_file_info: nft$store_forward_file_info;
       VAR status: ost$status);

      CONST
        parameter_destination_names = ' DN=(',
        parameter_group_name = 'GN=',
        parameter_length_group_name = 3;

      VAR
        command_name_parameter: string (nfc$cmd_def_dest_group_length),
        command_name_length: integer,
        command_parameter_length: integer,
        destination_name_index: ost$non_negative_integers,
        destination_name_length: integer,
        parameter_length: integer,
        parameter_list: string (max_command_parameter_length + 1),
        ptr_current_dest_names_info: ^nft$sf_destination_names_array,
        ptr_current_group_name_info: ^nft$sf_group_name_information;

      status.normal := TRUE;
      ptr_current_group_name_info := #PTR (store_forward_file_info.pointers.ptr_group_name_list,
            store_forward_file_info.segment_pointer.sequence_pointer^);

      WHILE ptr_current_group_name_info <> NIL DO
        IF NOT ptr_current_group_name_info^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_rptr,
                'CREATE_GROUP_NAME_DIRECTIVES 1', status);
          RETURN;
        IFEND;
        IF NOT ptr_current_group_name_info^.ptr_destination_names.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_rptr,
                'CREATE_GROUP_NAME_DIRECTIVES 2', status);
          RETURN;
        IFEND;

        command_name_parameter := nfc$cmd_def_destination_group;
        command_name_length := nfc$cmd_def_dest_group_length;

{ create the group_name parameter

        parameter_list := parameter_group_name;
        parameter_list ((parameter_length_group_name + 1), * ) := ptr_current_group_name_info^.group_name;
        parameter_length := clp$trimmed_string_size (parameter_list);

{ create the destination_names parameter

        parameter_list ((parameter_length + 1), * ) := parameter_destination_names;
        parameter_length := clp$trimmed_string_size (parameter_list);
        command_parameter_length := command_name_length + parameter_length;

        ptr_current_dest_names_info := #PTR (ptr_current_group_name_info^.ptr_destination_names.relative_ptr,
              store_forward_file_info.segment_pointer.sequence_pointer^);
        FOR destination_name_index := 1 TO ptr_current_group_name_info^.destination_name_count DO

          destination_name_length := clp$trimmed_string_size
                (ptr_current_dest_names_info^ [destination_name_index].value);

{ When writting the directive to the output file, break the directive on a parameter boundry.  The maximum
{ output line is 80 characters.  The command name is written along with the parameters on the first call to
{ write this directive to the output file.

          IF (command_parameter_length + destination_name_length) >= max_command_parameter_length THEN
            parameter_list ((parameter_length + 1), * ) := append_continuation_line_string;
            write_command_to_output (command_name_parameter, parameter_list, status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;

{ Reset the command name to a blank string so that when the continuation lines are written the command name is
{ not the first part of each line.

            command_name_parameter := ' ';
            command_name_length := 0;
            parameter_list := ' ';
            parameter_length := 1;
          IFEND;

{ If the value for this parameter begins with an integer, make this parameter a string value by placing quotes
{ before and after the value.

          IF first_character_is_integer (ptr_current_dest_names_info^ [destination_name_index].value) THEN
            parameter_length := parameter_length + 1;
            parameter_list (parameter_length, 1) := append_string_delimiter;
          IFEND;
          parameter_list ((parameter_length + 1), * ) := ptr_current_dest_names_info^
                [destination_name_index].value;
          parameter_length := clp$trimmed_string_size (parameter_list);
          IF first_character_is_integer (ptr_current_dest_names_info^ [destination_name_index].value) THEN
            parameter_length := parameter_length + 1;
            parameter_list (parameter_length, 1) := append_string_delimiter;
          IFEND;
          parameter_length := parameter_length + 1;
          command_parameter_length := command_name_length + parameter_length;
        FOREND;
        parameter_list ((parameter_length), * ) := ')';
        write_command_to_output (command_name_parameter, parameter_list, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        ptr_current_group_name_info := #PTR (ptr_current_group_name_info^.link.relative_ptr,
              store_forward_file_info.segment_pointer.sequence_pointer^);
      WHILEND;
    PROCEND create_group_name_directives;
?? OLDTITLE ??
?? NEWTITLE := 'create_source_name_directives', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to create the MANAGE_STORE_FORWARD_NETWORK
{   source name directives that are currently defined in the System's
{   Store/Forward Network file.

    PROCEDURE create_source_name_directives
      (    store_forward_file_info: nft$store_forward_file_info;
       VAR status: ost$status);

      CONST
        max_parameter_length_appl_qual = 25,
        max_parameter_length_dest_qual = 36,
        max_parameter_length_name = 36,
        max_parameter_length_x_hop_name = 38,
        parameter_application_qualifier = ' AQ=(',
        parameter_length_appl_qualifier = 5,
        parameter_destination_qualifier = ' DGQ=',
        parameter_length_dest_qualifier = 5,
        parameter_name = 'N=',
        parameter_length_name = 2,
        parameter_next_hop_name = ' NHN=',
        parameter_length_next_hop_name = 5;

      VAR
        application_qualifier_index: nft$sf_applications,
        application_qualifier_length: integer,
        application_qualifier_parameter: string (max_parameter_length_appl_qual),
        destination_qualifier_length: integer,
        destination_qualifier_parameter: string (max_parameter_length_dest_qual),
        name_length: integer,
        name_parameter: string (max_parameter_length_name),
        next_hop_name_length: integer,
        next_hop_name_parameter: string (max_parameter_length_x_hop_name),
        parameter_list: string (max_command_parameter_length + 1),
        ptr_current_source_name_info: ^nft$sf_source_name_information;

      status.normal := TRUE;
      ptr_current_source_name_info := #PTR (store_forward_file_info.pointers.ptr_source_name_list,
            store_forward_file_info.segment_pointer.sequence_pointer^);

      WHILE ptr_current_source_name_info <> NIL DO
        IF NOT ptr_current_source_name_info^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_rptr,
                'CREATE_SOURCE_NAME_DIRECTIVES', status);
          RETURN;
        IFEND;

{ Create the name parameter

        name_parameter := parameter_name;
        name_length := parameter_length_name;

{ If the value for this parameter begins with an integer, make this parameter a string value by placing quotes
{ before and after the value.

        IF first_character_is_integer (ptr_current_source_name_info^.source_name.value) THEN
          name_length := name_length + 1;
          name_parameter (name_length, 1) := append_string_delimiter;
        IFEND;
        name_parameter ((name_length + 1), * ) := ptr_current_source_name_info^.source_name.value;
        name_length := clp$trimmed_string_size (name_parameter);
        IF first_character_is_integer (ptr_current_source_name_info^.source_name.value) THEN
          name_length := name_length + 1;
          name_parameter (name_length, 1) := append_string_delimiter;
        IFEND;

{ Create the next_hop_name parameter

        next_hop_name_parameter := parameter_next_hop_name;
        next_hop_name_length := parameter_length_next_hop_name;

{ If the value for this parameter begins with an integer, make this parameter a string value by placing quotes
{ before and after the value.

        IF first_character_is_integer (ptr_current_source_name_info^.next_hop_name.value) THEN
          next_hop_name_length := next_hop_name_length + 1;
          next_hop_name_parameter (next_hop_name_length, 1) := append_string_delimiter;
        IFEND;
        next_hop_name_parameter ((next_hop_name_length + 1), * ) :=
              ptr_current_source_name_info^.next_hop_name.value;
        next_hop_name_length := clp$trimmed_string_size (next_hop_name_parameter);
        IF first_character_is_integer (ptr_current_source_name_info^.next_hop_name.value) THEN
          next_hop_name_length := next_hop_name_length + 1;
          next_hop_name_parameter (next_hop_name_length, 1) := append_string_delimiter;
        IFEND;

{ Create the destination_group_qualifier parameter

        IF ptr_current_source_name_info^.destination_group_qualifier <> osc$null_name THEN
          destination_qualifier_parameter := parameter_destination_qualifier;
          destination_qualifier_parameter ((parameter_length_dest_qualifier + 1), * ) :=
                ptr_current_source_name_info^.destination_group_qualifier;
        ELSE
          destination_qualifier_parameter := ' ';
        IFEND;
        destination_qualifier_length := clp$trimmed_string_size (destination_qualifier_parameter);

{ Create the application_qualifier parameter

        application_qualifier_parameter := parameter_application_qualifier;
        application_qualifier_length := parameter_length_appl_qualifier;
        FOR application_qualifier_index := LOWERBOUND (nfv$sf_application_names)
              TO UPPERBOUND (nfv$sf_application_names) DO
          IF application_qualifier_index IN ptr_current_source_name_info^.application_qualifier THEN
            application_qualifier_parameter ((application_qualifier_length + 1), * ) :=
                  nfv$sf_application_names [application_qualifier_index];
            application_qualifier_length := application_qualifier_length + application_name_w_space_length;
          IFEND;
        FOREND;
        application_qualifier_parameter ((application_qualifier_length), * ) := ')';
        application_qualifier_length := clp$trimmed_string_size (application_qualifier_parameter);

{ When writting the directive to the output file, break the directive on a parameter boundry.  The maximum
{ output line is 80 characters.  The command name is written along with the parameters on the first call to
{ write this directive to the output file.

        parameter_list := name_parameter;
        IF (nfc$cmd_def_source_name_length + name_length + next_hop_name_length +
              application_qualifier_length + destination_qualifier_length) < max_command_parameter_length THEN
          parameter_list ((name_length + 1), * ) := next_hop_name_parameter;
          parameter_list ((name_length + next_hop_name_length + 1), * ) := application_qualifier_parameter;
          parameter_list ((name_length + next_hop_name_length + application_qualifier_length + 1), * ) :=
                destination_qualifier_parameter;
          write_command_to_output (nfc$cmd_def_source_name_switch, parameter_list, status);
        ELSEIF (nfc$cmd_def_source_name_length + name_length + next_hop_name_length +
              application_qualifier_length) < max_command_parameter_length THEN
          parameter_list ((name_length + 1), * ) := next_hop_name_parameter;
          parameter_list ((name_length + next_hop_name_length + 1), * ) := application_qualifier_parameter;
          parameter_list ((name_length + next_hop_name_length + application_qualifier_length + 1), * ) :=
                append_continuation_line_string;
          write_command_to_output (nfc$cmd_def_source_name_switch, parameter_list, status);
          IF status.normal THEN
            parameter_list := destination_qualifier_parameter;
            write_command_to_output ('', parameter_list, status);
          IFEND;
        ELSEIF (nfc$cmd_def_source_name_length + name_length + next_hop_name_length) <
              max_command_parameter_length THEN
          parameter_list ((name_length + 1), * ) := next_hop_name_parameter;
          parameter_list ((name_length + next_hop_name_length + 1), * ) := append_continuation_line_string;
          write_command_to_output (nfc$cmd_def_source_name_switch, parameter_list, status);
          IF status.normal THEN
            parameter_list := application_qualifier_parameter;
            parameter_list ((application_qualifier_length + 1), * ) := destination_qualifier_parameter;
            write_command_to_output ('', parameter_list, status);
          IFEND;
        ELSE
          parameter_list ((name_length + 1), * ) := append_continuation_line_string;
          write_command_to_output (nfc$cmd_def_source_name_switch, parameter_list, status);
          IF status.normal THEN
            parameter_list := next_hop_name_parameter;
            parameter_list ((next_hop_name_length + 1), * ) := application_qualifier_parameter;
            IF (1 + next_hop_name_length + application_qualifier_length + destination_qualifier_length) <
                  max_command_parameter_length THEN
              parameter_list ((next_hop_name_length + application_qualifier_length + 1), * ) :=
                    destination_qualifier_parameter;
              write_command_to_output ('', parameter_list, status);
            ELSE
              parameter_list ((next_hop_name_length + application_qualifier_length + 1), * ) :=
                    append_continuation_line_string;
              write_command_to_output ('', parameter_list, status);
              IF status.normal THEN
                write_command_to_output ('', destination_qualifier_parameter, status);
              IFEND;
            IFEND;
          IFEND;
        IFEND;
        ptr_current_source_name_info := #PTR (ptr_current_source_name_info^.link.relative_ptr,
              store_forward_file_info.segment_pointer.sequence_pointer^);
      WHILEND;
    PROCEND create_source_name_directives;
?? OLDTITLE, EJECT ??
    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ(pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ attach and open the latest version of the store_forward_network file

    nfp$open_store_forward_file (TRUE, store_forward_file_info, status);
    IF status.normal AND store_forward_file_info.file_open THEN

{ open the output file as specified by the output parameter the directives will be written to this file.

      fsp$open_file (pvt [p$output] .value^ .file_value^, amc$record, NIL, NIL, NIL, NIL, NIL,
            output_file_identifier, status);
      output_file_open := status.normal;
      IF status.normal THEN

      /create_sfn_directives_block/
        BEGIN

{ create the store forward directives from the currently installed System's Store/Forward Network file.

          create_group_name_directives (store_forward_file_info, status);
          IF NOT status.normal THEN
            EXIT /create_sfn_directives_block/;
          IFEND;

          create_application_directives (store_forward_file_info, status);
          IF NOT status.normal THEN
            EXIT /create_sfn_directives_block/;
          IFEND;

          create_source_name_directives (store_forward_file_info, status);
          IF NOT status.normal THEN
            EXIT /create_sfn_directives_block/;
          IFEND;

          create_dest_name_directives (store_forward_file_info, status);
          IF NOT status.normal THEN
            EXIT /create_sfn_directives_block/;
          IFEND;

          write_command_to_output (nfc$cmd_quit, '', status);
        END /create_sfn_directives_block/;
      IFEND;

{ close the store_forward_network file

      nfp$close_store_forward_file (store_forward_file_info, local_status);
      IF status.normal AND (NOT local_status.normal) THEN
        status := local_status;
      IFEND;

{ close the output file (generated directive file)

      fsp$close_file (output_file_identifier, local_status);
      output_file_open := NOT local_status.normal;
      IF status.normal AND (NOT local_status.normal) THEN
        status := local_status;
      IFEND;
    IFEND;
  PROCEND cmd_generate_sf_network;
?? OLDTITLE ??
?? NEWTITLE := 'cmd_install_sf_network', EJECT ??

{ PURPOSE:
{   This is the Utility's command INSTALL_STORE_FORWARD_NETWORK.  It will
{   verify and install (create or replace) the SYSTEM'S STORE/FORWARD
{   Network file.

  PROCEDURE cmd_install_sf_network
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

*copyc nft$pdt_install_sf_network

    CONST
      max_retry_count = 5;

    VAR
      local_status: ost$status,
      ptr_file_attachment_options: ^fst$attachment_options,
      temporary_store_forward_file: amt$local_file_name;

?? NEWTITLE := 'install_sfn_directives', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to install the MANAGE_STORE_FORWARD_NETWORK
{   directives into the System's Store/Forward Network file.

    PROCEDURE install_sfn_directives
      (    temporary_store_forward_file: amt$local_file_name;
       VAR status: ost$status);

      VAR
        copy_error: boolean,
        error_retry_count: 0 .. max_retry_count,
        local_status: ost$status,
        permanent_store_forward_file: amt$local_file_name,
        pf_access_mode: pft$usage_selections,
        pf_cycle_selection: pft$cycle_selector,
        pf_logging: pft$log,
        pf_password: pft$password,
        pf_retention: pft$retention,
        pf_share_mode: pft$share_selections,
        pf_store_forward_file_path: ^pft$path;

      error_retry_count := 0;
      status.normal := TRUE;
      PUSH pf_store_forward_file_path: [1 .. 4];

{ set up the permanent file path for the System's Store/Forward Network file and have exclusive access so that
{ there is no contention when we write the file

      pf_store_forward_file_path^ [1] := nfc$sf_family_name;
      pf_store_forward_file_path^ [2] := nfc$sf_user_name;
      pf_store_forward_file_path^ [3] := nfc$sf_subcatalog_name;
      pf_store_forward_file_path^ [4] := nfc$sf_permanent_file_name;
      pf_access_mode := $pft$usage_selections [pfc$read, pfc$append, pfc$modify, pfc$shorten];
      pf_share_mode := $pft$usage_selections [];
      pf_logging := pfc$no_log;
      pf_password := osc$null_name;
      pf_retention := pfc$maximum_retention;

      REPEAT
        copy_error := FALSE;
        pmp$get_unique_name (permanent_store_forward_file, status);
        pf_cycle_selection.cycle_option := pfc$highest_cycle;

{ attach the highest cycle of the System's Store/Forward Network file

        pfp$attach (permanent_store_forward_file, pf_store_forward_file_path^, pf_cycle_selection,
              pf_password, pf_access_mode, pf_share_mode, pfc$no_wait, status);
        IF NOT status.normal THEN
          IF (status.condition = pfe$unknown_permanent_file) OR (status.condition = pfe$cycle_busy) THEN

{ if the file is unknown or is busy (attached by some other application) create the next cycle for us to write
{ the Store/Forward information

            pf_cycle_selection.cycle_option := pfc$highest_cycle;
            pfp$define (permanent_store_forward_file, pf_store_forward_file_path^, pf_cycle_selection,
                  pf_password, pf_retention, pf_logging, status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
          ELSE
            RETURN;
          IFEND;
        IFEND;

{ copy the directive information into the permanent file System's Store/Forward Network file

        fsp$copy_file (temporary_store_forward_file, permanent_store_forward_file, NIL, NIL, NIL, status);
        amp$return (permanent_store_forward_file, local_status);
        IF status.normal THEN
          IF NOT local_status.normal THEN
            status := local_status;
          IFEND;
        ELSE

{ if an error occurs when we wrote to the permanent file, we will delete the cycle of the permanent file that
{ we just wrote and then we will try again to write a valid Store/Forward Network file

          copy_error := TRUE;
          error_retry_count := error_retry_count + 1;
          pf_cycle_selection.cycle_option := pfc$highest_cycle;
          pfp$purge (pf_store_forward_file_path^, pf_cycle_selection, pf_password, status);
        IFEND;
      UNTIL (NOT copy_error) OR (error_retry_count >= max_retry_count);
    PROCEND install_sfn_directives;
?? OLDTITLE ??
?? NEWTITLE := 'write_sfn_directives', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to write the MANAGE_STORE_FORWARD_NETWORK
{   directives into a file that will be copied to the System's Store/Forward
{   Network file.
{
{ NOTE:
{   The format of the Store_Forward_Network file is as follows:
{     The first series of bytes consist of relative pointers to the first
{     entry of the various linked lists for application_name_switch,
{     destination_name_switch, destination_group names, and source_name_switch.
{     This set of relative pointers are in the order as specified in the type
{     nft$store_forward_file_pointers.  The rest of the file consists of all
{     the entries for the Store/Forward directives in the following order:
{       1. application_name_switch, 2. source_name_switch,
{       3. destination_name_switch, and 4. destination_group names.
{     The destination_group names are unique because the information defining
{     a particular group_name is placed in the file first and it is followed
{     immediately by its list of destination names.
{   All of the entries for a particular directive are linked together.  To find
{   the next entry, the LINK field should be used.

    PROCEDURE write_sfn_directives
      (VAR temporary_store_forward_file: amt$local_file_name;
       VAR status: ost$status);

      VAR
        error_retry_count: 0 .. max_retry_count,
        ignore_status: ost$status,
        segment_pointer: amt$segment_pointer,
        store_forward_file_pointers: ^nft$store_forward_file_pointers,
        temporary_file_identifier: amt$file_identifier,
        write_error: boolean;

?? NEWTITLE := 'write_application_directives', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to write the DEFINE_APPLICATION_NAME_SWITCH
{   directives into a file that will be copied to the System's Store/Forward
{   Network file.

      PROCEDURE write_application_directives
        (VAR segment_pointer: amt$segment_pointer;
         VAR ptr_first_application_directive: nft$sf_rel_ptr_appl_name_info;
         VAR write_error: boolean;
         VAR status: ost$status);

        VAR
          first_entry: boolean,
          ptr_current_appl_name_file: ^nft$sf_application_name_info,
          ptr_current_appl_name_list: ^nft$sf_application_name_info,
          ptr_previous_appl_name_file: ^nft$sf_application_name_info;

{ write the Store/Forward Network application directives to the temporary file

        status.normal := TRUE;
        write_error := FALSE;
        first_entry := TRUE;
        ptr_current_appl_name_list := ptr_application_name_list;
        ptr_previous_appl_name_file := NIL;
        WHILE ptr_current_appl_name_list <> NIL DO
          IF ptr_current_appl_name_list^.link.relative_pointer THEN
            osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                  'WRITE_APPLICATION_DIRECTIVES', status);
            RETURN;
          IFEND;

{ Allocate space in the temporary file for the next application directive

          NEXT ptr_current_appl_name_file IN segment_pointer.sequence_pointer;
          IF ptr_current_appl_name_file <> NIL THEN

{ write the application directive information into the temporary file

            ptr_current_appl_name_file^.link.relative_pointer := TRUE;
            ptr_current_appl_name_file^.link.relative_ptr := NIL;
            ptr_current_appl_name_file^.next_hop_application :=
                  ptr_current_appl_name_list^.next_hop_application;
            ptr_current_appl_name_file^.application_qualifier :=
                  ptr_current_appl_name_list^.application_qualifier;
            ptr_current_appl_name_file^.destination_group_qualifier :=
                  ptr_current_appl_name_list^.destination_group_qualifier;
            IF ptr_previous_appl_name_file <> NIL THEN

{ connect (link it) the current application directive with the last application directive

              ptr_previous_appl_name_file^.link.relative_ptr :=
                    #REL (ptr_current_appl_name_file, segment_pointer.sequence_pointer^);
            IFEND;
            IF first_entry THEN

{ save the pointer to the first application directive

              ptr_first_application_directive := #REL (ptr_current_appl_name_file,
                    segment_pointer.sequence_pointer^);
              first_entry := FALSE;
            IFEND;
            ptr_previous_appl_name_file := ptr_current_appl_name_file;
          ELSE
            write_error := TRUE;
          IFEND;
          ptr_current_appl_name_list := ptr_current_appl_name_list^.link.ptr;
        WHILEND;
      PROCEND write_application_directives;
?? OLDTITLE ??
?? NEWTITLE := 'write_dest_name_directives', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to write the DEFINE_DESTINATION_NAME_SWITCH
{   directives into a file that will be copied to the System's Store/Forward
{   Network file.

      PROCEDURE write_dest_name_directives
        (VAR segment_pointer: amt$segment_pointer;
         VAR ptr_first_target_name_directive: nft$sf_rel_ptr_target_name_info;
         VAR write_error: boolean;
         VAR status: ost$status);

        VAR
          first_entry: boolean,
          ptr_current_target_name_file: ^nft$sf_target_name_information,
          ptr_current_target_name_list: ^nft$sf_target_name_information,
          ptr_previous_target_name_file: ^nft$sf_target_name_information;

{ write the Store/Forward Network destination name directives to the temporary file

        status.normal := TRUE;
        write_error := FALSE;
        first_entry := TRUE;
        ptr_current_target_name_list := ptr_target_name_list;
        ptr_previous_target_name_file := NIL;
        WHILE ptr_current_target_name_list <> NIL DO
          IF ptr_current_target_name_list^.link.relative_pointer THEN
            osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                  'WRITE_DEST_NAME_DIRECTIVES', status);
            RETURN;
          IFEND;

{ Allocate space in the temporary file for the next destination name directive

          NEXT ptr_current_target_name_file IN segment_pointer.sequence_pointer;
          IF ptr_current_target_name_file <> NIL THEN

{ write the destination name directive information into the temporary file

            ptr_current_target_name_file^.link.relative_pointer := TRUE;
            ptr_current_target_name_file^.link.relative_ptr := NIL;
            ptr_current_target_name_file^.target_name := ptr_current_target_name_list^.target_name;
            ptr_current_target_name_file^.next_hop_name := ptr_current_target_name_list^.next_hop_name;
            ptr_current_target_name_file^.application_qualifier :=
                  ptr_current_target_name_list^.application_qualifier;
            IF ptr_previous_target_name_file <> NIL THEN

{ connect (link it) the current destination name directive with the last destination name directive

              ptr_previous_target_name_file^.link.relative_ptr :=
                    #REL (ptr_current_target_name_file, segment_pointer.sequence_pointer^);
            IFEND;
            IF first_entry THEN

{ save the pointer to the first destination name directive

              ptr_first_target_name_directive := #REL (ptr_current_target_name_file,
                    segment_pointer.sequence_pointer^);
              first_entry := FALSE;
            IFEND;
            ptr_previous_target_name_file := ptr_current_target_name_file;
          ELSE
            write_error := TRUE;
          IFEND;
          ptr_current_target_name_list := ptr_current_target_name_list^.link.ptr;
        WHILEND;
      PROCEND write_dest_name_directives;
?? OLDTITLE ??
?? NEWTITLE := 'write_group_name_directives', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to write the DEFINE_DESTINATION_GROUP
{   directives into a file that will be copied to the System's Store/Forward
{   Network file.

      PROCEDURE write_group_name_directives
        (VAR segment_pointer: amt$segment_pointer;
         VAR ptr_first_group_name_directive: nft$sf_rel_ptr_group_name_info;
         VAR write_error: boolean;
         VAR status: ost$status);

        VAR
          first_entry: boolean,
          ptr_current_group_name_file: ^nft$sf_group_name_information,
          ptr_current_group_name_list: ^nft$sf_group_name_information,
          ptr_destination_names: ^nft$sf_destination_names_array,
          ptr_previous_group_name_file: ^nft$sf_group_name_information;

{ write the Store/Forward Network destination group directives to the temporary file

        status.normal := TRUE;
        write_error := FALSE;
        first_entry := TRUE;
        ptr_current_group_name_list := ptr_group_name_list;
        ptr_previous_group_name_file := NIL;
        WHILE ptr_current_group_name_list <> NIL DO
          IF ptr_current_group_name_list^.link.relative_pointer THEN
            osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                  'WRITE_GROUP_NAME_DIRECTIVES 1', status);
            RETURN;
          IFEND;
          IF ptr_current_group_name_list^.ptr_destination_names.relative_pointer THEN
            osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                  'WRITE_GROUP_NAME_DIRECTIVES 2', status);
            RETURN;
          IFEND;

{ Allocate space in the temporary file for the next destination group directive

          NEXT ptr_current_group_name_file IN segment_pointer.sequence_pointer;
          IF ptr_current_group_name_file <> NIL THEN

{ Allocate space in the temporary file for the list of destination names

            NEXT ptr_destination_names: [1 .. ptr_current_group_name_list^.destination_name_count] IN
                  segment_pointer.sequence_pointer;
            IF ptr_destination_names <> NIL THEN

{ write the destination group directive information into the temporary file

              ptr_current_group_name_file^.link.relative_pointer := TRUE;
              ptr_current_group_name_file^.link.relative_ptr := NIL;
              ptr_current_group_name_file^.group_name := ptr_current_group_name_list^.group_name;
              ptr_current_group_name_file^.destination_name_count :=
                    ptr_current_group_name_list^.destination_name_count;
              ptr_destination_names^ := ptr_current_group_name_list^.ptr_destination_names.ptr^;
              ptr_current_group_name_file^.ptr_destination_names.relative_pointer := TRUE;
              ptr_current_group_name_file^.ptr_destination_names.relative_ptr :=
                    #REL (ptr_destination_names, segment_pointer.sequence_pointer^);
              IF ptr_previous_group_name_file <> NIL THEN

{ connect (link it) the current destination group directive with the last destination group directive

                ptr_previous_group_name_file^.link.relative_ptr :=
                      #REL (ptr_current_group_name_file, segment_pointer.sequence_pointer^);
              IFEND;
              IF first_entry THEN

{ save the pointer to the first destination group directive

                ptr_first_group_name_directive := #REL (ptr_current_group_name_file,
                      segment_pointer.sequence_pointer^);
                first_entry := FALSE;
              IFEND;
              ptr_previous_group_name_file := ptr_current_group_name_file;
            IFEND;
          ELSE
            write_error := TRUE;
          IFEND;
          ptr_current_group_name_list := ptr_current_group_name_list^.link.ptr;
        WHILEND;
      PROCEND write_group_name_directives;
?? OLDTITLE ??
?? NEWTITLE := 'write_source_name_directives', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to write the DEFINE_SOURCE_NAME_SWITCH
{   directives into a file that will be copied to the System's Store/Forward
{   Network file.

      PROCEDURE write_source_name_directives
        (VAR segment_pointer: amt$segment_pointer;
         VAR ptr_first_source_name_directive: nft$sf_rel_ptr_source_name_info;
         VAR write_error: boolean;
         VAR status: ost$status);

        VAR
          first_entry: boolean,
          ptr_current_source_name_file: ^nft$sf_source_name_information,
          ptr_current_source_name_list: ^nft$sf_source_name_information,
          ptr_previous_source_name_file: ^nft$sf_source_name_information;

{ write the Store/Forward Network source name directives to the temporary file

        status.normal := TRUE;
        write_error := FALSE;
        first_entry := TRUE;
        ptr_current_source_name_list := ptr_source_name_list;
        ptr_previous_source_name_file := NIL;
        WHILE ptr_current_source_name_list <> NIL DO
          IF ptr_current_source_name_list^.link.relative_pointer THEN
            osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                  'WRITE_SOURCE_NAME_DIRECTIVES', status);
            RETURN;
          IFEND;

{ Allocate space in the temporary file for the next source name directive

          NEXT ptr_current_source_name_file IN segment_pointer.sequence_pointer;
          IF ptr_current_source_name_file <> NIL THEN

{ write the source name directive information into the temporary file

            ptr_current_source_name_file^.link.relative_pointer := TRUE;
            ptr_current_source_name_file^.link.relative_ptr := NIL;
            ptr_current_source_name_file^.source_name := ptr_current_source_name_list^.source_name;
            ptr_current_source_name_file^.next_hop_name := ptr_current_source_name_list^.next_hop_name;
            ptr_current_source_name_file^.application_qualifier :=
                  ptr_current_source_name_list^.application_qualifier;
            ptr_current_source_name_file^.destination_group_qualifier :=
                  ptr_current_source_name_list^.destination_group_qualifier;
            IF ptr_previous_source_name_file <> NIL THEN

{ connect (link it) the current source name directive with the last source name directive

              ptr_previous_source_name_file^.link.relative_ptr :=
                    #REL (ptr_current_source_name_file, segment_pointer.sequence_pointer^);
            IFEND;
            IF first_entry THEN

{ save the pointer to the first source name directive

              ptr_first_source_name_directive := #REL (ptr_current_source_name_file,
                    segment_pointer.sequence_pointer^);
              first_entry := FALSE;
            IFEND;
            ptr_previous_source_name_file := ptr_current_source_name_file;
          ELSE
            write_error := TRUE;
          IFEND;
          ptr_current_source_name_list := ptr_current_source_name_list^.link.ptr;
        WHILEND;
      PROCEND write_source_name_directives;
?? OLDTITLE, EJECT ??
      status.normal := TRUE;
      error_retry_count := 0;

      REPEAT

        write_error := FALSE;

{ create a temporary file that will contain the information from the Store/Forward directives supplied by the
{ user

        pmp$get_unique_name (temporary_store_forward_file, status);
        fsp$open_file (temporary_store_forward_file, amc$segment, NIL, NIL, NIL, NIL, NIL,
              temporary_file_identifier, status);

        amp$get_segment_pointer (temporary_file_identifier, amc$sequence_pointer, segment_pointer, status);
        RESET segment_pointer.sequence_pointer;
        NEXT store_forward_file_pointers IN segment_pointer.sequence_pointer;

{ initialize the pointers to the first entry for each list

        store_forward_file_pointers^.ptr_application_name_list := NIL;
        store_forward_file_pointers^.ptr_group_name_list := NIL;
        store_forward_file_pointers^.ptr_source_name_list := NIL;
        store_forward_file_pointers^.ptr_target_name_list := NIL;

        write_application_directives (segment_pointer, store_forward_file_pointers^.ptr_application_name_list,
              write_error, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        IF NOT write_error THEN
          write_source_name_directives (segment_pointer, store_forward_file_pointers^.ptr_source_name_list,
                write_error, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;

          IF NOT write_error THEN
            write_dest_name_directives (segment_pointer, store_forward_file_pointers^.ptr_target_name_list,
                  write_error, status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;

            IF NOT write_error THEN
              write_group_name_directives (segment_pointer, store_forward_file_pointers^.ptr_group_name_list,
                    write_error, status);
              IF NOT status.normal THEN
                RETURN;
              IFEND;
            IFEND;
          IFEND;
        IFEND;

        IF write_error THEN

{ if an error occurred while writing the temporary Store/Forward Network file close and detach the temporary
{ file and try again

          error_retry_count := error_retry_count + 1;
          fsp$close_file (temporary_file_identifier, ignore_status);
          amp$return (temporary_store_forward_file, ignore_status);
        IFEND;
      UNTIL (NOT write_error) OR (error_retry_count >= max_retry_count);

      IF write_error THEN
        osp$set_status_abnormal (nfc$status_id, nfe$sf_write_network_file_error, ' ', status);
      ELSE

{ if Store/Forward Network file was successfully writen set the segment end_of_information

        amp$set_segment_eoi (temporary_file_identifier, segment_pointer, status);
        fsp$close_file (temporary_file_identifier, status);
      IFEND;
    PROCEND write_sfn_directives;
?? OLDTITLE, EJECT ??
    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ(pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ verify the Store/Forward Network directives for errors and overlapping definitions

    verify_sfn_directives (pvt [p$input] .value^ .file_value^, pvt [p$error] .value^ .file_value^, status);
    IF status.normal THEN

{ write the temporary Store/Forward Network file

      write_sfn_directives (temporary_store_forward_file, status);
      IF status.normal THEN

{ install the temporary Store/Forward Network file into the SYSTEM's Store/Forward Network file

        install_sfn_directives (temporary_store_forward_file, status);
      IFEND;
      amp$return (temporary_store_forward_file, local_status);
    IFEND;

{ FREE all the space allocated for the information associated with the Store/Forward Network directives

    free_store_forward_information (local_status);
    IF status.normal AND NOT local_status.normal THEN
      status := local_status;
    IFEND;
  PROCEND cmd_install_sf_network;
?? OLDTITLE ??
?? NEWTITLE := 'cmd_quit_sf_directive', EJECT ??

{ PURPOSE:
{   This is the Utility's command to QUIT the directive phase of
{   of VERIFY_STORE_FORWARD_NETWORK or INSTALL_STORE_FORWARD_NETWORK
{   of MANAGE_STORE_FORWARD_NETWORK.

  PROCEDURE cmd_quit_sf_directive
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

*copy nft$pdt_quit_store_forward

    VAR
      ignore_status: ost$status;

    status.normal := TRUE;

    clp$evaluate_parameters (parameter_list, #SEQ(pdt), NIL, NIL, status);
    IF NOT status.normal THEN
      IF status.condition <> cle$parameters_displayed THEN

{ write the command to the output file

        write_command_to_output (nfc$cmd_quit, '', ignore_status);
        write_status_to_output (status);
      IFEND;
      RETURN;
    IFEND;

{ write the command to the output file

    write_command_to_output (nfc$cmd_quit, '', status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ end the processing of the Store/Forward Network directives

    clp$end_include (nfv$manage_sfn_directives, status);
    If NOT status.normal THEN
      write_status_to_output (status);
      RETURN;
    IFEND;
  PROCEND cmd_quit_sf_directive;
?? OLDTITLE ??
?? NEWTITLE := 'cmd_quit_sf_network', EJECT ??

{ PURPOSE:
{   This is the Utility's command to QUIT the MANAGE_STORE_FORWARD_NETWORK.

  PROCEDURE cmd_quit_sf_network
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

*copy nft$pdt_quit_store_forward

    status.normal := TRUE;

    clp$evaluate_parameters (parameter_list, #SEQ(pdt), NIL, NIL, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ end the processing of the MANAGE_STORE_FORWARD_NETWORK utility

    clp$end_include (nfv$manage_sf_network, status);
    If NOT status.normal THEN
      RETURN;
    IFEND;
  PROCEND cmd_quit_sf_network;
?? OLDTITLE ??
?? NEWTITLE := 'cmd_verify_sf_network', EJECT ??

{ PURPOSE:
{   This is the Utility's command VERIFY_STORE_FORWARD_NETWORK.  It will
{   verify the SYSTEM'S STORE/FORWARD Network file.

  PROCEDURE cmd_verify_sf_network
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

*copyc nft$pdt_verify_sf_network

    VAR
      local_status: ost$status;

    status.normal := TRUE;

    clp$evaluate_parameters (parameter_list, #SEQ(pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ verify the Store/Forward Network directives for errors and overlapping definitions

    verify_sfn_directives (pvt [p$input] .value^ .file_value^, pvt [p$output] .value^ .file_value^, status);

{ FREE all the space allocated for the information associated with the Store/Forward Network directives

    free_store_forward_information (local_status);
    IF status.normal AND NOT local_status.normal THEN
      status := local_status;
    IFEND;
  PROCEND cmd_verify_sf_network;
?? OLDTITLE ??
?? NEWTITLE := 'convert_parameter_to_ost$name', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to convert a name or string parameter to
{   a value of ost$name.

  PROCEDURE convert_parameter_to_ost$name
    (    parameter: clt$data_value;
     VAR parameter_value: ost$name;
     VAR parameter_size: nfc$p24_min_param_size .. nfc$p24_max_param_size;
     VAR status: ost$status);

    VAR
      value_size: ost$non_negative_integers;

    status.normal := TRUE;

    CASE parameter.kind OF
    = clc$name =

{ verify that the name value meets the length restrictions for this parameter value

      value_size := clp$trimmed_string_size (parameter.name_value);

      IF value_size < LOWERVALUE (parameter_size) THEN
        osp$set_status_abnormal (nfc$status_id, nfe$sf_name_too_short, parameter.name_value
              (1, value_size), status);
        RETURN;
      ELSEIF value_size > UPPERVALUE (parameter_size) THEN
        osp$set_status_abnormal (nfc$status_id, nfe$sf_name_too_long, parameter.name_value
              (1, value_size), status);
        RETURN;
      IFEND;
      parameter_value := parameter.name_value;
      parameter_size := value_size;
    = clc$string =

{ verify that the string value meets the length restrictions for this parameter value

      value_size := clp$trimmed_string_size (parameter.string_value^);
      IF value_size < LOWERVALUE (parameter_size) THEN
        osp$set_status_abnormal (nfc$status_id, nfe$sf_string_too_short, parameter.string_value^
              (1, value_size), status);
        RETURN;
      ELSEIF value_size > UPPERVALUE (parameter_size) THEN
        osp$set_status_abnormal (nfc$status_id, nfe$sf_string_too_long, parameter.string_value^
              (1, value_size), status);
        RETURN;
      IFEND;
      #TRANSLATE (osv$lower_to_upper, parameter.string_value^, parameter_value);
      parameter_size := value_size;
    ELSE

{ the parameter should only be a name or string value

      osp$set_status_abnormal ('CL', cle$wrong_kind_of_value, 'name or string', status);
      RETURN;
    CASEND;

  PROCEND convert_parameter_to_ost$name;
?? OLDTITLE ??
?? NEWTITLE := 'first_character_is_integer', EJECT ??

{ PURPOSE:
{   The purpose of this function is to determine if the first character
{   is an integer value.

  FUNCTION first_character_is_integer
    (    string_value: string ( * )): boolean;

    TYPE
      set_of_integers = set of char;

    VAR
      compare_character: char,
      integer_set: [STATIC, READ] set_of_integers := ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];

    compare_character := string_value (1);
    IF compare_character IN integer_set THEN
      first_character_is_integer := TRUE;
    ELSE
      first_character_is_integer := FALSE;
    IFEND;
  FUNCEND first_character_is_integer;
?? OLDTITLE ??
?? NEWTITLE := 'free_store_forward_information', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to FREE the Store/Forward Information
{   allocated by the MANAGE_STORE_FORWARD_NETWORK directives.  This
{   information is pointed to by the global pointers: ptr_application_name_list,
{     ptr_group_name_list, ptr_source_name_list, and ptr_target_name_list.

  PROCEDURE free_store_forward_information
    (VAR status: ost$status);

    VAR
      free_application_name_ptr: ^nft$sf_application_name_info,
      free_group_name_ptr: ^nft$sf_group_name_information,
      free_source_name_ptr: ^nft$sf_source_name_information,
      free_target_name_ptr: ^nft$sf_target_name_information;

    status.normal := TRUE;

{ Free all the information on the application_name_list and set the ptr_application_name_list to NIL

    IF ptr_application_name_list <> NIL THEN
      free_application_name_ptr := ptr_application_name_list;
      WHILE free_application_name_ptr <> NIL DO
        IF free_application_name_ptr^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                'FREE_STORE_FORWARD_INFORMATION 1', status);
          RETURN;
        IFEND;
        ptr_application_name_list := free_application_name_ptr^.link.ptr;
        FREE free_application_name_ptr;
        free_application_name_ptr := ptr_application_name_list;
      WHILEND;
      ptr_application_name_list := NIL;
    IFEND;

{ Free all the information on the group_name_list and set the ptr_group_name_list to NIL

    IF ptr_group_name_list <> NIL THEN
      free_group_name_ptr := ptr_group_name_list;
      WHILE free_group_name_ptr <> NIL DO
        IF free_group_name_ptr^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                'FREE_STORE_FORWARD_INFORMATION 2', status);
          RETURN;
        IFEND;
        IF free_group_name_ptr^.ptr_destination_names.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                'FREE_STORE_FORWARD_INFORMATION 3', status);
          RETURN;
        IFEND;
        ptr_group_name_list := free_group_name_ptr^.link.ptr;
        IF free_group_name_ptr^.ptr_destination_names.ptr <> NIL THEN

{ Free the list of destination names associated with this particular group name

          FREE free_group_name_ptr^.ptr_destination_names.ptr;
        IFEND;
        FREE free_group_name_ptr;
        free_group_name_ptr := ptr_group_name_list;
      WHILEND;
      ptr_group_name_list := NIL;
    IFEND;

{ Free all the information on the source_name_list and set the ptr_source_name_list to NIL

    IF ptr_source_name_list <> NIL THEN
      free_source_name_ptr := ptr_source_name_list;
      WHILE free_source_name_ptr <> NIL DO
        IF free_source_name_ptr^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                'FREE_STORE_FORWARD_INFORMATION 4', status);
          RETURN;
        IFEND;
        ptr_source_name_list := free_source_name_ptr^.link.ptr;
        FREE free_source_name_ptr;
        free_source_name_ptr := ptr_source_name_list;
      WHILEND;
      ptr_source_name_list := NIL;
    IFEND;

{ Free all the information on the target_name_list and set the ptr_target_name_list to NIL

    IF ptr_target_name_list <> NIL THEN
      free_target_name_ptr := ptr_target_name_list;
      WHILE free_target_name_ptr <> NIL DO
        IF free_target_name_ptr^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                'FREE_STORE_FORWARD_INFORMATION 5', status);
          RETURN;
        IFEND;
        ptr_target_name_list := free_target_name_ptr^.link.ptr;
        FREE free_target_name_ptr;
        free_target_name_ptr := ptr_target_name_list;
      WHILEND;
      ptr_target_name_list := NIL;
    IFEND;
  PROCEND free_store_forward_information;
?? OLDTITLE ??
?? NEWTITLE := 'verify_sfn_directives', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to write the MANAGE_STORE_FORWARD_NETWORK
{   directive abnormal status to the specified output file.

  PROCEDURE verify_sfn_directives
    (    input_file: fst$file_reference;
         output_file: fst$file_reference;
     VAR status: ost$status);

*copyc nft$cdt_manage_sfn_directives

    VAR
      evaluated_file_ref: fst$evaluated_file_reference,
      file_reference_parsing_options: clt$file_ref_parsing_options,
      local_status: ost$status,
      output_file_size: fst$path_size,
      output_file_string: fst$path,
      utility_attributes: ^clt$utility_attributes;

?? NEWTITLE := 'compare_destination_groups', EJECT ??

{ PURPOSE:
{   The purpose of this function is to compare two destination_group_names
{   arrays of destination names to determine if the destination names are:
{     identical, a subset of each other, overlapping (but not a subset),
{     unique or cannot find either or both destination group names.

    FUNCTION compare_destination_groups
      (    destination_group_name_1: ost$name;
           destination_group_name_2: ost$name): nft$sf_dest_group_comparision;

      VAR
        group_name_1_found: boolean,
        group_name_2_found: boolean,
        index_dest_group_array_1: ost$non_negative_integers,
        index_dest_group_array_2: ost$non_negative_integers,
        number_of_group_1_names: ost$non_negative_integers,
        number_of_group_2_names: ost$non_negative_integers,
        number_of_matches_found: ost$non_negative_integers,
        ptr_dest_names_array_1: ^nft$sf_destination_names_array,
        ptr_dest_names_array_2: ^nft$sf_destination_names_array,
        ptr_dest_group_names: ^nft$sf_group_name_information;

      IF destination_group_name_1 = destination_group_name_2 THEN
        compare_destination_groups := nfc$sf_dest_groups_identical;
      ELSEIF (destination_group_name_1 = osc$null_name) OR (destination_group_name_2 = osc$null_name) THEN

{ a destination_group_name of osc$null_name means that for any destination the substition for this directive
{ will take place

        compare_destination_groups := nfc$sf_dest_groups_subset;
      ELSE
        group_name_1_found := FALSE;
        group_name_2_found := FALSE;

{ find pointers for destination group names 1 and 2

        ptr_dest_group_names := ptr_group_name_list;

      /find_ptrs_for_group_names/
        WHILE ptr_dest_group_names <> NIL DO
          IF (NOT group_name_1_found) AND (ptr_dest_group_names^.group_name = destination_group_name_1) THEN
            group_name_1_found := TRUE;
            number_of_group_1_names := ptr_dest_group_names^.destination_name_count;
            ptr_dest_names_array_1 := ptr_dest_group_names^.ptr_destination_names.ptr;
          IFEND;
          IF (NOT group_name_2_found) AND (ptr_dest_group_names^.group_name = destination_group_name_2) THEN
            group_name_2_found := TRUE;
            number_of_group_2_names := ptr_dest_group_names^.destination_name_count;
            ptr_dest_names_array_2 := ptr_dest_group_names^.ptr_destination_names.ptr;
          IFEND;
          IF group_name_1_found AND group_name_2_found THEN
            EXIT /find_ptrs_for_group_names/;
          IFEND;
          ptr_dest_group_names := ptr_dest_group_names^.link.ptr;
        WHILEND /find_ptrs_for_group_names/;

        IF group_name_1_found AND group_name_2_found THEN
          number_of_matches_found := 0;

{ determine the number of identical destination names in both group_name_1 and group_name_2

        /output_dest_group_array/
          FOR index_dest_group_array_1 := 1 TO number_of_group_1_names DO
            FOR index_dest_group_array_2 := 1 TO number_of_group_2_names DO
              IF ptr_dest_names_array_1^ [index_dest_group_array_1] =
                    ptr_dest_names_array_2^ [index_dest_group_array_2] THEN
                number_of_matches_found := number_of_matches_found + 1;
                CYCLE /output_dest_group_array/;
              IFEND;
            FOREND;
          FOREND /output_dest_group_array/;

          IF (number_of_group_1_names = number_of_matches_found) AND
                (number_of_group_2_names = number_of_matches_found) THEN

{ all the destination names from group_name_1 match all the destination names from group_name_2

            compare_destination_groups := nfc$sf_dest_groups_identical;
          ELSEIF (number_of_group_1_names = number_of_matches_found) OR
                (number_of_group_2_names = number_of_matches_found) THEN

{ all the destination names from group_name_1 match a subset of destination names from group_name_2 or
{ all the destination names from group_name_2 match a subset of destination names from group_name_1

            compare_destination_groups := nfc$sf_dest_groups_subset;
          ELSEIF (number_of_matches_found > 0) THEN

{ at least one destination name from group_name_1 matches at least one destination name from group_name_2

            compare_destination_groups := nfc$sf_dest_groups_overlap;
          ELSE { number_of_matches_found = 0 }

{ none of the destination names from group_name_1 matches any of the destination names from group_name_2

            compare_destination_groups := nfc$sf_dest_groups_unique;
          IFEND;
        ELSE

{ one or both of the group_names were not found

          compare_destination_groups := nfc$sf_dest_groups_not_found;
        IFEND;
      IFEND;
    FUNCEND compare_destination_groups;
?? OLDTITLE ??
?? NEWTITLE := 'verify_application_directives', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to verify the APPLICATION_NAME_SWITCHes from
{   the MANAGE_STORE_FORWARD_NETWORK directives for uniqueness and exclusiveness.

    PROCEDURE verify_application_directives
      (VAR status: ost$status);

      VAR
        compare_application_name_ptr: ^nft$sf_application_name_info,
        destination_group_comparision: nft$sf_dest_group_comparision,
        group_name_found: boolean,
        local_status: ost$status,
        verify_errors: boolean,
        verify_application_name_ptr: ^nft$sf_application_name_info,
        verify_group_name_ptr: ^nft$sf_group_name_information;

      status.normal := TRUE;
      verify_errors := FALSE;
      verify_application_name_ptr := ptr_application_name_list;

{ check for application_definition errors

      WHILE verify_application_name_ptr <> NIL DO
        IF verify_application_name_ptr^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                'VERIFY_APPLICATION_DIRECTIVES 1', status);
          RETURN;
        IFEND;
        compare_application_name_ptr := verify_application_name_ptr^.link.ptr;
        WHILE compare_application_name_ptr <> NIL DO
          IF compare_application_name_ptr^.link.relative_pointer THEN
            osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                  'VERIFY_APPLICATION_DIRECTIVES 2', status);
            RETURN;
          IFEND;

{ check to see if the application_qualifier is a subset of the other application_qualifier

          IF (verify_application_name_ptr^.application_qualifier <=
                compare_application_name_ptr^.application_qualifier) OR
                (verify_application_name_ptr^.application_qualifier >=
                compare_application_name_ptr^.application_qualifier) THEN

            destination_group_comparision := compare_destination_groups
                  (verify_application_name_ptr^.destination_group_qualifier,
                  compare_application_name_ptr^.destination_group_qualifier);

{ check to see if the destination_group_qualifier are identical or a subset of each other

            IF (destination_group_comparision = nfc$sf_dest_groups_identical) OR
                  (destination_group_comparision = nfc$sf_dest_groups_subset) THEN

{ check to see if the next_hop_appliction are the same

              IF verify_application_name_ptr^.next_hop_application =
                    compare_application_name_ptr^.next_hop_application THEN
                osp$set_status_abnormal (nfc$status_id, nfe$sf_combine_dup_appl_def,
                      verify_application_name_ptr^.destination_group_qualifier, local_status);
                osp$append_status_parameter (osc$status_parameter_delimiter,
                      verify_application_name_ptr^.next_hop_application, local_status);
              ELSE { next_hop_application are different}
                verify_errors := TRUE;
                osp$set_status_abnormal (nfc$status_id, nfe$sf_dif_nha_same_aq_and_dgq,
                      verify_application_name_ptr^.destination_group_qualifier, local_status);
              IFEND;
              write_status_to_output (local_status);
            ELSEIF destination_group_comparision = nfc$sf_dest_groups_overlap THEN

{ check to see if the next_hop_appliction are the same

              IF verify_application_name_ptr^.next_hop_application =
                    compare_application_name_ptr^.next_hop_application THEN
                osp$set_status_abnormal (nfc$status_id, nfe$sf_duplicate_appl_def,
                      verify_application_name_ptr^.destination_group_qualifier, local_status);
                osp$append_status_parameter (osc$status_parameter_delimiter,
                      verify_application_name_ptr^.next_hop_application, local_status);
              ELSE { next_hop_application are different}
                verify_errors := TRUE;
                osp$set_status_abnormal (nfc$status_id, nfe$sf_dif_nha_same_aq_and_dgq,
                      verify_application_name_ptr^.destination_group_qualifier, local_status);
              IFEND;
              write_status_to_output (local_status);
            IFEND;

{ check to see if the application_qualifiers overlap

          ELSEIF (verify_application_name_ptr^.application_qualifier *
                compare_application_name_ptr^.application_qualifier) <> $nft$sf_application_set [] THEN

            destination_group_comparision := compare_destination_groups
                  (verify_application_name_ptr^.destination_group_qualifier,
                  compare_application_name_ptr^.destination_group_qualifier);

{ check to see if the destination_group_qualifier are identical or a subset of each other

            IF (destination_group_comparision = nfc$sf_dest_groups_identical) OR
                  (destination_group_comparision = nfc$sf_dest_groups_subset) OR
                  (destination_group_comparision = nfc$sf_dest_groups_overlap) THEN

{ check to see if the next_hop_appliction are different

              IF verify_application_name_ptr^.next_hop_application <>
                    compare_application_name_ptr^.next_hop_application THEN
                verify_errors := TRUE;
                osp$set_status_abnormal (nfc$status_id, nfe$sf_dif_nha_same_aq_and_dgq,
                      verify_application_name_ptr^.destination_group_qualifier, local_status);
                write_status_to_output (local_status);
              IFEND;
            IFEND;
          IFEND;
          compare_application_name_ptr := compare_application_name_ptr^.link.ptr;
        WHILEND;

        IF verify_application_name_ptr^.destination_group_qualifier <> osc$null_name THEN
          group_name_found := FALSE;
          verify_group_name_ptr := ptr_group_name_list;

{ verify that the destination_group_qualifier has been defined

        /verify_group_name_loop/
          WHILE verify_group_name_ptr <> NIL DO
            IF verify_group_name_ptr^.link.relative_pointer THEN
              osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                    'VERIFY_APPLICATION_DIRECTIVES 3', status);
              RETURN;
            IFEND;
            IF verify_application_name_ptr^.destination_group_qualifier =
                  verify_group_name_ptr^.group_name THEN
              group_name_found := TRUE;
              EXIT /verify_group_name_loop/;
            IFEND;
            verify_group_name_ptr := verify_group_name_ptr^.link.ptr;
          WHILEND /verify_group_name_loop/;

          IF NOT group_name_found THEN
            verify_errors := TRUE;
            osp$set_status_abnormal (nfc$status_id, nfe$sf_dest_group_not_found,
                  verify_application_name_ptr^.destination_group_qualifier, local_status);
            write_status_to_output (local_status);
          IFEND;
        IFEND;
        verify_application_name_ptr := verify_application_name_ptr^.link.ptr;
      WHILEND;

      IF verify_errors THEN

{ report to the user that at least one fatal directive error has occurred

        osp$set_status_abnormal (nfc$status_id, nfe$sf_directive_errors, ' ', status);
      IFEND;
    PROCEND verify_application_directives;
?? OLDTITLE ??
?? NEWTITLE := 'verify_dest_name_directives', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to verify the DESTINATION_NAME_SWITCHes from
{   the MANAGE_STORE_FORWARD_NETWORK directives for uniqueness and exclusiveness.

    PROCEDURE verify_dest_name_directives
      (VAR status: ost$status);

      VAR
        compare_target_name_ptr: ^nft$sf_target_name_information,
        local_status: ost$status,
        verify_errors: boolean,
        verify_target_name_ptr: ^nft$sf_target_name_information;

      status.normal := TRUE;
      verify_errors := FALSE;
      verify_target_name_ptr := ptr_target_name_list;

{ check for target_definition errors

      WHILE verify_target_name_ptr <> NIL DO
        IF verify_target_name_ptr^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                'VERIFY_DEST_NAME_DIRECTIVES 1', status);
          RETURN;
        IFEND;
        compare_target_name_ptr := verify_target_name_ptr^.link.ptr;
        WHILE compare_target_name_ptr <> NIL DO
          IF compare_target_name_ptr^.link.relative_pointer THEN
            osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                  'VERIFY_DEST_NAME_DIRECTIVES 2', status);
            RETURN;
          IFEND;
          IF verify_target_name_ptr^.target_name = compare_target_name_ptr^.target_name THEN

{ check to see if the application_qualifier is a subset of the other application_qualifier

            IF (verify_target_name_ptr^.application_qualifier <=
                  compare_target_name_ptr^.application_qualifier) OR
                  (verify_target_name_ptr^.application_qualifier >=
                  compare_target_name_ptr^.application_qualifier) THEN

{ check to see if the next_hop_names are identical

              IF verify_target_name_ptr^.next_hop_name = compare_target_name_ptr^.next_hop_name THEN

                osp$set_status_abnormal (nfc$status_id, nfe$sf_combine_dup_target_def,
                      verify_target_name_ptr^.target_name.value, local_status);
                osp$append_status_parameter (osc$status_parameter_delimiter,
                      verify_target_name_ptr^.next_hop_name.value, local_status);
              ELSE
                verify_errors := TRUE;
                osp$set_status_abnormal (nfc$status_id, nfe$sf_dif_nhn_same_n_and_aq,
                      verify_target_name_ptr^.target_name.value, local_status);
              IFEND;
              write_status_to_output (local_status);

{ check to see if the application_qualifiers overlap each other

            ELSEIF (verify_target_name_ptr^.application_qualifier *
                  compare_target_name_ptr^.application_qualifier) <> $nft$sf_application_set [] THEN

              verify_errors := TRUE;

{ check to see if the next_hop_names are identical

              IF verify_target_name_ptr^.next_hop_name = compare_target_name_ptr^.next_hop_name THEN
                osp$set_status_abnormal (nfc$status_id, nfe$sf_duplicate_target_def,
                      verify_target_name_ptr^.target_name.value, local_status);
                osp$append_status_parameter (osc$status_parameter_delimiter,
                      verify_target_name_ptr^.next_hop_name.value, local_status);
              ELSE
                osp$set_status_abnormal (nfc$status_id, nfe$sf_dif_nhn_same_n_and_aq,
                      verify_target_name_ptr^.target_name.value, local_status);
              IFEND;

              write_status_to_output (local_status);
            IFEND;
          IFEND;
          compare_target_name_ptr := compare_target_name_ptr^.link.ptr;
        WHILEND;
        verify_target_name_ptr := verify_target_name_ptr^.link.ptr;
      WHILEND;

      IF verify_errors THEN

{ report to the user that at least one fatal directive error has occurred

        osp$set_status_abnormal (nfc$status_id, nfe$sf_directive_errors, ' ', status);
      IFEND;
    PROCEND verify_dest_name_directives;
?? OLDTITLE ??
?? NEWTITLE := 'verify_group_name_directives', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to verify the GROUP_NAMEes from
{   the MANAGE_STORE_FORWARD_NETWORK directives for uniqueness and exclusiveness.

    PROCEDURE verify_group_name_directives
      (VAR status: ost$status);

      VAR
        compare_group_name_ptr: ^nft$sf_group_name_information,
        compare_index: ost$non_negative_integers,
        identical_destination_names: boolean,
        group_name_used: boolean,
        local_status: ost$status,
        verify_errors: boolean,
        verify_application_name_ptr: ^nft$sf_application_name_info,
        verify_group_name_ptr: ^nft$sf_group_name_information,
        verify_source_name_ptr: ^nft$sf_source_name_information,
        verify_index: ost$non_negative_integers;

      status.normal := TRUE;
      verify_errors := FALSE;

{ check for duplicate group names

      verify_group_name_ptr := ptr_group_name_list;

      WHILE verify_group_name_ptr <> NIL DO
        IF verify_group_name_ptr^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                'VERIFY_GROUP_NAME_DIRECTIVES 1', status);
          RETURN;
        IFEND;
        compare_group_name_ptr := verify_group_name_ptr^.link.ptr;
        WHILE compare_group_name_ptr <> NIL DO
          IF compare_group_name_ptr^.link.relative_pointer THEN
            osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                  'VERIFY_GROUP_NAME_DIRECTIVES 2', status);
            RETURN;
          IFEND;
          IF verify_group_name_ptr^.group_name = compare_group_name_ptr^.group_name THEN
            verify_errors := TRUE;
            osp$set_status_abnormal (nfc$status_id, nfe$sf_duplicate_group_names,
                  verify_group_name_ptr^.group_name, local_status);
            write_status_to_output (local_status);
          IFEND;
          compare_group_name_ptr := compare_group_name_ptr^.link.ptr;
        WHILEND;
        verify_group_name_ptr := verify_group_name_ptr^.link.ptr;
      WHILEND;

{ check for identical destination group lists

      verify_group_name_ptr := ptr_group_name_list;

      WHILE verify_group_name_ptr <> NIL DO
        IF verify_group_name_ptr^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                'VERIFY_GROUP_NAME_DIRECTIVES 3', status);
          RETURN;
        IFEND;
        IF verify_group_name_ptr^.ptr_destination_names.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                'VERIFY_GROUP_NAME_DIRECTIVES 4', status);
          RETURN;
        IFEND;
        compare_group_name_ptr := verify_group_name_ptr^.link.ptr;
        WHILE compare_group_name_ptr <> NIL DO
          IF compare_group_name_ptr^.link.relative_pointer THEN
            osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                  'VERIFY_GROUP_NAME_DIRECTIVES 5', status);
            RETURN;
          IFEND;
          IF compare_group_name_ptr^.ptr_destination_names.relative_pointer THEN
            osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                  'VERIFY_GROUP_NAME_DIRECTIVES 6', status);
            RETURN;
          IFEND;
          IF verify_group_name_ptr^.destination_name_count =
                compare_group_name_ptr^.destination_name_count THEN
            identical_destination_names := TRUE;

          /verify_destination_names/
            FOR verify_index := 1 TO verify_group_name_ptr^.destination_name_count DO
              FOR compare_index := 1 TO compare_group_name_ptr^.destination_name_count DO
                IF verify_group_name_ptr^.ptr_destination_names.ptr^ [verify_index] =
                      compare_group_name_ptr^.ptr_destination_names.ptr^ [compare_index] THEN
                  CYCLE /verify_destination_names/;
                IFEND;
              FOREND;
              identical_destination_names := FALSE;
              EXIT /verify_destination_names/;
            FOREND /verify_destination_names/;
            IF identical_destination_names THEN
              osp$set_status_abnormal (nfc$status_id, nfe$sf_identical_dest_list,
                    verify_group_name_ptr^.group_name, local_status);
              osp$append_status_parameter (osc$status_parameter_delimiter, compare_group_name_ptr^.group_name,
                    local_status);
              write_status_to_output (local_status);
            IFEND;
          IFEND;
          compare_group_name_ptr := compare_group_name_ptr^.link.ptr;
        WHILEND;
        verify_group_name_ptr := verify_group_name_ptr^.link.ptr;
      WHILEND;

{ check for unused group names

      verify_group_name_ptr := ptr_group_name_list;

      WHILE verify_group_name_ptr <> NIL DO
        IF verify_group_name_ptr^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                'VERIFY_GROUP_NAME_DIRECTIVES 7', status);
          RETURN;
        IFEND;

{ check to see if the application directives use this destination_group_qualifier

        verify_application_name_ptr := ptr_application_name_list;
        group_name_used := FALSE;
        WHILE (NOT group_name_used) AND (verify_application_name_ptr <> NIL) DO
          IF verify_application_name_ptr^.link.relative_pointer THEN
            osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                  'VERIFY_GROUP_NAME_DIRECTIVES 8', status);
            RETURN;
          IFEND;
          IF verify_group_name_ptr^.group_name = verify_application_name_ptr^.destination_group_qualifier THEN
            group_name_used := TRUE;
          IFEND;
          verify_application_name_ptr := verify_application_name_ptr^.link.ptr;
        WHILEND;

{ check to see if the source name directives use this destination_group_qualifier

        verify_source_name_ptr := ptr_source_name_list;
        WHILE (NOT group_name_used) AND (verify_source_name_ptr <> NIL) DO
          IF verify_source_name_ptr^.link.relative_pointer THEN
            osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                  'VERIFY_GROUP_NAME_DIRECTIVES 8', status);
            RETURN;
          IFEND;
          IF verify_group_name_ptr^.group_name = verify_source_name_ptr^.destination_group_qualifier THEN
            group_name_used := TRUE;
          IFEND;
          verify_source_name_ptr := verify_source_name_ptr^.link.ptr;
        WHILEND;

        IF NOT group_name_used THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_group_name_not_used,
                verify_group_name_ptr^.group_name, local_status);
          write_status_to_output (local_status);
        IFEND;

        verify_group_name_ptr := verify_group_name_ptr^.link.ptr;
      WHILEND;

      IF verify_errors THEN

{ report to the user that at least one fatal directive error has occurred

        osp$set_status_abnormal (nfc$status_id, nfe$sf_directive_errors, ' ', status);
      IFEND;
    PROCEND verify_group_name_directives;
?? OLDTITLE ??
?? NEWTITLE := 'verify_source_name_directives', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to verify the SOURCE_NAME_SWITCHes from
{   the MANAGE_STORE_FORWARD_NETWORK directives for uniqueness and exclusiveness.

    PROCEDURE verify_source_name_directives
      (VAR status: ost$status);

      VAR
        compare_source_name_ptr: ^nft$sf_source_name_information,
        destination_group_comparision: nft$sf_dest_group_comparision,
        group_name_found: boolean,
        local_status: ost$status,
        verify_errors: boolean,
        verify_group_name_ptr: ^nft$sf_group_name_information,
        verify_source_name_ptr: ^nft$sf_source_name_information;

      status.normal := TRUE;
      verify_errors := FALSE;
      verify_source_name_ptr := ptr_source_name_list;

{ check for source_name_definition errors

      WHILE verify_source_name_ptr <> NIL DO
        IF verify_source_name_ptr^.link.relative_pointer THEN
          osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                'VERIFY_SOURCE_NAME_DIRECTIVES 1', status);
          RETURN;
        IFEND;
        compare_source_name_ptr := verify_source_name_ptr^.link.ptr;
        WHILE compare_source_name_ptr <> NIL DO
          IF compare_source_name_ptr^.link.relative_pointer THEN
            osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                  'VERIFY_SOURCE_NAME_DIRECTIVES 2', status);
            RETURN;
          IFEND;

{ check to see if the source_names are identical

          IF verify_source_name_ptr^.source_name = compare_source_name_ptr^.source_name THEN

{ check to see if the application_qualifier is a subset of the other application_qualifier

            IF (verify_source_name_ptr^.application_qualifier <=
                  compare_source_name_ptr^.application_qualifier) OR
                  (verify_source_name_ptr^.application_qualifier >=
                  compare_source_name_ptr^.application_qualifier) THEN

{ check to see if the destination_group_qualifier are identical or a subset of each other

              destination_group_comparision := compare_destination_groups
                    (verify_source_name_ptr^.destination_group_qualifier,
                    compare_source_name_ptr^.destination_group_qualifier);

              IF (destination_group_comparision = nfc$sf_dest_groups_identical) OR
                    (destination_group_comparision = nfc$sf_dest_groups_subset) THEN

{ check to see if the next_hop_name are the same

                IF verify_source_name_ptr^.next_hop_name = compare_source_name_ptr^.next_hop_name THEN
                  osp$set_status_abnormal (nfc$status_id, nfe$sf_combine_dup_source_def,
                        verify_source_name_ptr^.source_name.value, local_status);
                  osp$append_status_parameter (osc$status_parameter_delimiter,
                        verify_source_name_ptr^.next_hop_name.value, local_status);
                  osp$append_status_parameter (osc$status_parameter_delimiter,
                        verify_source_name_ptr^.destination_group_qualifier, local_status);
                ELSE { next_hop_name are different}
                  verify_errors := TRUE;
                  osp$set_status_abnormal (nfc$status_id, nfe$sf_dif_nhn_same_n_aq_dgq,
                        verify_source_name_ptr^.source_name.value, local_status);
                  osp$append_status_parameter (osc$status_parameter_delimiter,
                        verify_source_name_ptr^.destination_group_qualifier, local_status);
                IFEND;
                write_status_to_output (local_status);
              ELSEIF destination_group_comparision = nfc$sf_dest_groups_overlap THEN

{ check to see if the next_hop_name are the same

                IF verify_source_name_ptr^.next_hop_name = compare_source_name_ptr^.next_hop_name THEN
                  osp$set_status_abnormal (nfc$status_id, nfe$sf_duplicate_source_def,
                        verify_source_name_ptr^.source_name.value, local_status);
                  osp$append_status_parameter (osc$status_parameter_delimiter,
                        verify_source_name_ptr^.next_hop_name.value, local_status);
                  osp$append_status_parameter (osc$status_parameter_delimiter,
                        verify_source_name_ptr^.destination_group_qualifier, local_status);
                ELSE { next_hop_name are different}
                  verify_errors := TRUE;
                  osp$set_status_abnormal (nfc$status_id, nfe$sf_dif_nhn_same_n_aq_dgq,
                        verify_source_name_ptr^.source_name.value, local_status);
                  osp$append_status_parameter (osc$status_parameter_delimiter,
                        verify_source_name_ptr^.destination_group_qualifier, local_status);
                IFEND;
                write_status_to_output (local_status);
              IFEND;

{ check to see if the application_qualifiers overlap

            ELSEIF (verify_source_name_ptr^.application_qualifier *
                  compare_source_name_ptr^.application_qualifier) <> $nft$sf_application_set [] THEN

{ check to see if the destination_group_qualifier are identical or a subset of each other

              destination_group_comparision := compare_destination_groups
                    (verify_source_name_ptr^.destination_group_qualifier,
                    compare_source_name_ptr^.destination_group_qualifier);

              IF (destination_group_comparision = nfc$sf_dest_groups_identical) OR
                    (destination_group_comparision = nfc$sf_dest_groups_subset) OR
                    (destination_group_comparision = nfc$sf_dest_groups_overlap) THEN

{ check to see if the next_hop_name are the same

                IF verify_source_name_ptr^.next_hop_name <> compare_source_name_ptr^.next_hop_name THEN
                  verify_errors := TRUE;
                  osp$set_status_abnormal (nfc$status_id, nfe$sf_dif_nhn_same_n_aq_dgq,
                        verify_source_name_ptr^.source_name.value, local_status);
                  osp$append_status_parameter (osc$status_parameter_delimiter,
                        verify_source_name_ptr^.destination_group_qualifier, local_status);
                  write_status_to_output (local_status);
                IFEND;
              IFEND;
            IFEND;
          IFEND;
          compare_source_name_ptr := compare_source_name_ptr^.link.ptr;
        WHILEND;

        IF verify_source_name_ptr^.destination_group_qualifier <> osc$null_name THEN
          group_name_found := FALSE;
          verify_group_name_ptr := ptr_group_name_list;

{ verify that the destination_group_qualifier has been defined

        /verify_group_name_loop/
          WHILE verify_group_name_ptr <> NIL DO
            IF verify_group_name_ptr^.link.relative_pointer THEN
              osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                    'VERIFY_SOURCE_NAME_DIRECTIVES 3', status);
              RETURN;
            IFEND;
            IF verify_group_name_ptr^.ptr_destination_names.relative_pointer THEN
              osp$set_status_abnormal (nfc$status_id, nfe$sf_internal_error_bad_ptr,
                    'VERIFY_SOURCE_NAME_DIRECTIVES 4', status);
              RETURN;
            IFEND;
            IF verify_source_name_ptr^.destination_group_qualifier = verify_group_name_ptr^.group_name THEN
              group_name_found := TRUE;
              EXIT /verify_group_name_loop/;
            IFEND;
            verify_group_name_ptr := verify_group_name_ptr^.link.ptr;
          WHILEND /verify_group_name_loop/;

          IF NOT group_name_found THEN
            verify_errors := TRUE;
            osp$set_status_abnormal (nfc$status_id, nfe$sf_dest_group_not_found,
                  verify_source_name_ptr^.destination_group_qualifier, local_status);
            write_status_to_output (local_status);
          IFEND;
        IFEND;
        verify_source_name_ptr := verify_source_name_ptr^.link.ptr;
      WHILEND;

      IF verify_errors THEN

{ report to the user that at least one fatal directive error has occurred

        osp$set_status_abnormal (nfc$status_id, nfe$sf_directive_errors, ' ', status);
      IFEND;
    PROCEND verify_source_name_directives;
?? OLDTITLE, EJECT ??
    status.normal := TRUE;

{ open the specified output file that will receive the directives and any appropriate error messages

    fsp$open_file (output_file, amc$record, NIL, NIL, NIL, NIL, NIL, output_file_identifier, status);
    output_file_open := status.normal;
    IF status.normal THEN

      PUSH utility_attributes : [1 .. 5];
      utility_attributes^ [1].key := clc$utility_command_search_mode;
      utility_attributes^ [1].command_search_mode := clc$exclusive_command_search;
      utility_attributes^ [2].key := clc$utility_command_table;
      utility_attributes^ [2].command_table := mansfn_directive_list;
      utility_attributes^ [3].key := clc$utility_prompt;
      utility_attributes^ [3].prompt.size := 3;
      utility_attributes^ [3].prompt.value := 'vsf';
      utility_attributes^ [4].key := clc$utility_subcmnd_log_enabled;
      utility_attributes^ [4].subcommand_logging_enabled := TRUE;
      utility_attributes^ [5].key := clc$utility_termination_command;
      utility_attributes^ [5].termination_command := 'QUIT';

{ add the Store/Forward Network directives utility to the users command list

      clp$begin_utility (nfv$manage_sfn_directives, utility_attributes^, status);
      IF status.normal THEN

{ process the MANAGE_STORE_FORWARD_NETWORK utility directives from the user

        clp$include_file (input_file, '', nfv$manage_sfn_directives, status);

{ delete the Store/Forward Network directives utility to the users command list

        clp$end_utility (nfv$manage_sfn_directives, local_status);
        IF status.normal AND (NOT local_status.normal) THEN
          status := local_status;
        IFEND;

{ verify the various groups of Store/Forward Network directives

        verify_group_name_directives (local_status);
        IF status.normal AND (NOT local_status.normal) THEN
          status := local_status;
        IFEND;

        verify_application_directives (local_status);
        IF status.normal AND (NOT local_status.normal) THEN
          status := local_status;
        IFEND;

        verify_source_name_directives (local_status);
        IF status.normal AND (NOT local_status.normal) THEN
          status := local_status;
        IFEND;

        verify_dest_name_directives (local_status);
        IF status.normal AND (NOT local_status.normal) THEN
          status := local_status;
        IFEND;

        IF NOT status.normal AND NOT ((status.condition = nfe$sf_internal_error_bad_ptr) OR
              (status.condition = nfe$sf_internal_error_bad_rptr)) THEN
          file_reference_parsing_options := $clt$file_ref_parsing_options [];
          clp$evaluate_file_reference (output_file, file_reference_parsing_options, TRUE, evaluated_file_ref,
                local_status);
          clp$convert_file_ref_to_string (evaluated_file_ref, FALSE, output_file_string, output_file_size,
                local_status);
          osp$set_status_abnormal (nfc$status_id, nfe$sf_directive_errors,
                output_file_string (1, output_file_size), status);
        IFEND;

      ELSE

{ delete the Store/Forward Network directives utility to the users command list

        clp$end_utility (nfv$manage_sfn_directives, local_status);
        IF status.normal AND (NOT local_status.normal) THEN
          status := local_status;
        IFEND;
      IFEND;
    IFEND;

{ close the specified output file that received the directives and error messages

    fsp$close_file (output_file_identifier, local_status);
    output_file_open := NOT local_status.normal;
    IF status.normal AND (NOT local_status.normal) THEN
      status := local_status;
    IFEND;
  PROCEND verify_sfn_directives;
?? OLDTITLE ??
?? NEWTITLE := 'write_command_to_output', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to write the MANAGE_STORE_FORWARD_NETWORK
{   directive to the specified output file.

  PROCEDURE write_command_to_output
    (    command_name: string ( * );
         parameter_list: string ( * );
     VAR status: ost$status);

    VAR
      byte_address: amt$file_byte_address,
      command_name_length: integer,
      length: integer,
      output_line: ^string ( * ),
      parameter_list_length: integer;

    status.normal := TRUE;
    command_name_length := clp$trimmed_string_size (command_name);
    parameter_list_length := clp$trimmed_string_size (parameter_list);
    PUSH output_line: [1 + command_name_length + 1 + parameter_list_length];
    output_line^ := ' ';
    output_line^ (2, * ) := command_name;
    output_line^ ((command_name_length + 3), * ) := parameter_list;
    amp$put_next (output_file_identifier, output_line, (command_name_length + parameter_list_length + 2),
          byte_address, status);
  PROCEND write_command_to_output;
?? OLDTITLE ??
?? NEWTITLE := 'write_status_to_output', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to write the MANAGE_STORE_FORWARD_NETWORK
{   directive abnormal status to the specified output file and to the job log.

  PROCEDURE write_status_to_output
    (    status: ost$status);

    CONST
      max_output_message_length = 80;

    VAR
      byte_address: amt$file_byte_address,
      ignore_status: ost$status,
      line_index: 1 .. osc$max_status_message_lines,
      message: ost$status_message,
      message_line_count: ^ost$status_message_line_count,
      message_line_size: ^ost$status_message_line_size,
      message_line_text: ^string ( * ),
      ptr_message: ^ost$status_message;

    osp$format_message (status, osc$full_message_level, max_output_message_length, message, ignore_status);
    ptr_message := ^message;
    RESET ptr_message;
    NEXT message_line_count IN ptr_message;
    FOR line_index := 1 TO message_line_count^ DO
      NEXT message_line_size IN ptr_message;
      NEXT message_line_text: [message_line_size^] IN ptr_message;
      pmp$log (message_line_text^, ignore_status);
      amp$put_next (output_file_identifier, message_line_text, message_line_size^, byte_address,
            ignore_status);
    FOREND;
  PROCEND write_status_to_output;
?? OLDTITLE ??
?? NEWTITLE := 'nfp$manage_store_forward_netwrk', EJECT ??

  PROGRAM nfp$manage_store_forward_netwrk
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

*copy nfh$manage_store_forward_netwrk

*copyc nft$pdt_manage_sf_network

*copyc nft$cdt_manage_sf_network

    VAR
      establish_descriptor: pmt$established_handler,
      exit_condition: [STATIC, READ] pmt$condition := [pmc$block_exit_processing,
            [pmc$block_exit, pmc$program_termination, pmc$program_abort]],
      local_status: ost$status,
      user_capability_network_appl: boolean,
      user_capability_network_oper: boolean,
      utility_attributes: ^clt$utility_attributes;

?? NEWTITLE := 'sf_network_condition_handler', EJECT ??

{ PURPOSE:
{   This is the condition handler for the utility  MANAGE_STORE_FORWARD_NETWORK.

    PROCEDURE sf_network_condition_handler
      (    condition: pmt$condition;
           condition_descriptor: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR cond_handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      pmp$log (' MANAGE_STORE_FORWARD_NETWORK error processing', ignore_status);
      IF output_file_open THEN
        fsp$close_file (output_file_identifier, ignore_status);
        output_file_open := NOT ignore_status.normal;
      IFEND;
    PROCEND sf_network_condition_handler;
?? OLDTITLE, EJECT ??
    status.normal := TRUE;
    output_file_open := FALSE;

{ initialize the global pointers to the various lists

    ptr_application_name_list := NIL;
    ptr_group_name_list := NIL;
    ptr_source_name_list := NIL;
    ptr_target_name_list := NIL;

{ see if the user is validated to use this utility

    IF NOT jmp$system_job () THEN
      avp$get_capability (avc$network_applic_management, avc$user, user_capability_network_appl, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      avp$get_capability (avc$network_operation, avc$user, user_capability_network_oper, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      IF (NOT user_capability_network_appl) AND (NOT user_capability_network_oper) THEN
        osp$set_status_abnormal (nfc$status_id, nfe$sf_caller_not_privileged, nfv$manage_sf_network, status);
        RETURN;
      IFEND;
    IFEND;

    clp$evaluate_parameters (parameter_list, #SEQ(pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    pmp$establish_condition_handler (exit_condition, ^sf_network_condition_handler, ^establish_descriptor,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ add the Manage_Store_Forward_Network utility to the users command list

    PUSH utility_attributes : [1 .. 5];
    utility_attributes^ [1].key := clc$utility_command_search_mode;
    utility_attributes^ [1].command_search_mode := clc$global_command_search;
    utility_attributes^ [2].key := clc$utility_command_table;
    utility_attributes^ [2].command_table := mansfn_command_list;
    utility_attributes^ [3].key := clc$utility_prompt;
    utility_attributes^ [3].prompt.size := 3;
    utility_attributes^ [3].prompt.value := 'msf';
    utility_attributes^ [4].key := clc$utility_subcmnd_log_enabled;
    utility_attributes^ [4].subcommand_logging_enabled := TRUE;
    utility_attributes^ [5].key := clc$utility_termination_command;
    utility_attributes^ [5].termination_command := 'QUIT';

    clp$begin_utility (nfv$manage_sf_network, utility_attributes^, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ process the MANAGE_STORE_FORWARD_NETWORK utility commands from the user

    clp$include_file (clc$current_command_input, '', nfv$manage_sf_network, status);

{ delete the Manage_Store_Forward_Network utility to the users command list

    clp$end_utility (nfv$manage_sf_network, local_status);
    IF status.normal AND (NOT local_status.normal) THEN
      status := local_status;
    IFEND;

    pmp$disestablish_cond_handler (exit_condition, local_status);
    IF status.normal AND (NOT local_status.normal) THEN
      status := local_status;
    IFEND;
  PROCEND nfp$manage_store_forward_netwrk;
?? OLDTITLE ??
MODEND nfm$manage_store_forward_netwrk;
