?? NEWTITLE := 'NOS/VE PTF Application: Remote Validation' ??

?? LEFT := 1, RIGHT := 110 ??
?? FMT (FORMAT := ON, INDENT := 2) ??
?? SET (LIST := ON, LISTCTS := OFF) ??

MODULE nfm$remote_validation;

{
{ PURPOSE:
{   This module contains procedures to save, delete, and read the
{   validation information to be used for permanent file access
{   on remote systems.
{

?? NEWTITLE := '  Global Declarations', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc clt$value
*copyc nfe$ptf_condition_codes
*copyc nft$remote_validation
*copyc oss$job_paged_literal
*copyc oss$task_shared
*copyc ost$caller_identifier
*copyc ost$name
*copyc ost$status
?? POP ??
*copyc osp$clear_job_signature_lock
*copyc clp$close_display
*copyc clp$open_display_reference
*copyc clp$put_display
*copyc osp$set_job_signature_lock
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc osp$set_status_abnormal
*copyc osv$task_shared_heap

?? TITLE := '  Global Variables', EJECT ??

  TYPE
    remote_validation_control = record
      lock: ost$signature_lock,
      ptr: ^nft$remote_validation,
    recend;

  VAR
    nfv$remote_validation: [STATIC, oss$task_shared] remote_validation_control := [[0], NIL];


?? TITLE := '  [XDCL, #GATE] nfp$find_remote_validation', EJECT ??
{
{     The purpose of this request is to search the remote validation table for
{ an entry for the specified remote location.  The remote validation table is
{ located in the task shared heap and each entry contains one or more lines of
{ directives to be sent to a remote server application.  The requestor is
{ informed whether an entry exists, and how many lines it contains.
{
{       NFP$FIND_REMOTE_VALIDATION (LOCATION, VALIDATION_LINE_COUNT, STATUS)
{
{ LOCATION: (input)  This parameter specifies the remote location for which the
{       validation entry is sought.  If the remote system is NOS/VE, the loca-
{       tion is a family name.
{
{ VALIDATION_LINE_COUNT: (output)  This parameter specifies the number of lines
{       of directives contained in the remote validation entry.  If no entry
{       exists for the specified location, a value of zero will be returned.
{
{ STATUS: (output)  This parameter specifies the request status.
{       CONDITIONS: none.
{

  PROCEDURE [XDCL, #GATE] nfp$find_remote_validation
    (    location: ost$name;
     VAR validation_line_count: 0 .. nfc$max_validation_lines;
     VAR status: ost$status);

    VAR
      entry_p: ^nft$remote_validation;


    status.normal := TRUE;

    osp$set_job_signature_lock (nfv$remote_validation.lock);
    get_validation_entry (location, entry_p);

    IF entry_p = NIL THEN
      validation_line_count := 0;
    ELSE
      validation_line_count := UPPERBOUND (entry_p^.text);
    IFEND;

    osp$clear_job_signature_lock (nfv$remote_validation.lock);

  PROCEND nfp$find_remote_validation;

?? TITLE := '  [XDCL, #GATE] nfp$get_remote_validation', EJECT ??
{
{     The purpose of this request is to return the remote validation table
{ entry for the specified remote location.  The remote validation table is
{ located in the task shared heap and each entry contains one or more lines of
{ directives to be sent to a remote server application.  The requestor must
{ know the size of this entry in order to provide sufficient space to accept
{ it.  This is done via a prior call to nfp$find remote_validation.
{
{       NFP$GET_REMOTE_VALIDATION (LOCATION, VALIDATION, STATUS)
{
{ LOCATION: (input)  This parameter specifies the remote location for which the
{       validation entry is requested.  If the remote system is NOS/VE, the
{       location is a family name.
{
{ VALIDATION: (output)  This parameter specifies the array of directive lines
{       obtained from the remote validation entry.
{
{ STATUS: (output)  This parameter specifies the request status.
{       CONDITIONS: nfe$remote_val_undefined.
{       IDENTIFIER: nfc$status_id.
{

  PROCEDURE [XDCL, #GATE] nfp$get_remote_validation
    (    location: ost$name;
     VAR validation: ^array [1 .. * ] of string (osc$max_string_size);
     VAR status: ost$status);

    VAR
      entry_p: ^nft$remote_validation,
      line_count: 0 .. nfc$max_validation_lines,
      output_count: 0 .. nfc$max_validation_lines,
      i: 1 .. nfc$max_validation_lines;


    status.normal := TRUE;

    osp$set_job_signature_lock (nfv$remote_validation.lock);
    get_validation_entry (location, entry_p);

  /get/
    BEGIN
      IF entry_p = NIL THEN
        osp$set_status_abnormal (nfc$status_id, nfe$remote_val_undefined, location, status);
        EXIT /get/;
      IFEND;

      line_count := UPPERBOUND (entry_p^.text);
      output_count := UPPERBOUND (validation^);
      IF output_count < line_count THEN
        line_count := output_count;
      IFEND;

      FOR i := 1 TO line_count DO
        validation^ [i] := entry_p^.text [i];
      FOREND;
    END /get/;

    osp$clear_job_signature_lock (nfv$remote_validation.lock);

  PROCEND nfp$get_remote_validation;

?? TITLE := '  [XDCL, #GATE] nfp$set_remote_validation', EJECT ??
{
{     The purpose of this request is to create a remote validation table
{ entry for the specified remote location.  The remote validation table is
{ located in the task shared heap and each entry contains one or more lines of
{ directives to be sent to a remote server application.
{
{       NFP$SET_REMOTE_VALIDATION (LOCATION, VALIDATION, STATUS)
{
{ LOCATION: (input)  This parameter specifies the remote location for which the
{       validation entry is to be created.  If the remote system is NOS/VE, the
{       location is a family name.
{
{ VALIDATION: (input)  This parameter specifies the array of directive lines
{       to be stored in the remote validation entry.
{
{ STATUS: (output)  This parameter specifies the request status.
{       CONDITIONS: nfe$remote_val_defined.
{       IDENTIFIER: nfc$status_id.
{

  PROCEDURE [XDCL, #GATE] nfp$set_remote_validation
    (    location: ost$name;
         validation: ^array [1 .. * ] of string (osc$max_string_size);
     VAR status: ost$status);

    VAR
      entry_p: ^nft$remote_validation,
      last_entry_p: ^nft$remote_validation,
      line_count: 0 .. nfc$max_validation_lines,
      i: 1 .. nfc$max_validation_lines;


    status.normal := TRUE;

    osp$set_job_signature_lock (nfv$remote_validation.lock);
    get_validation_entry (location, entry_p);

    IF entry_p = NIL THEN
      line_count := UPPERBOUND (validation^);
      ALLOCATE entry_p: [1 .. line_count] IN osv$task_shared_heap^;
      entry_p^.next_entry := NIL;
      entry_p^.location := location;
      FOR i := 1 TO line_count DO
        entry_p^.text [i] := validation^ [i];
      FOREND;
      IF nfv$remote_validation.ptr = NIL THEN
        nfv$remote_validation.ptr := entry_p;
      ELSE
        last_entry_p := nfv$remote_validation.ptr;
        WHILE last_entry_p^.next_entry <> NIL DO
          last_entry_p := last_entry_p^.next_entry;
        WHILEND;
        last_entry_p^.next_entry := entry_p;
      IFEND;
    ELSE
      osp$set_status_abnormal (nfc$status_id, nfe$remote_val_defined, location, status);
    IFEND;

    osp$clear_job_signature_lock (nfv$remote_validation.lock);

  PROCEND nfp$set_remote_validation;

?? TITLE := '  [XDCL, #GATE] nfp$clear_remote_validation', EJECT ??
{
{     The purpose of this request is to delete the remote validation table
{ entry for the specified remote location.  The remote validation table is
{ located in the task shared heap and each entry contains one or more lines of
{ directives to be sent to a remote server application.
{
{       NFP$CLEAR_REMOTE_VALIDATION (LOCATION, VALIDATION, STATUS)
{
{ LOCATION: (input)  This parameter specifies the remote location for which the
{       validation entry is to be deleted.  If the remote system is NOS/VE, the
{       location is a family name.
{
{ STATUS: (output)  This parameter specifies the request status.
{       CONDITIONS: none.
{

  PROCEDURE [XDCL, #GATE] nfp$clear_remote_validation
    (    location: ost$name;
     VAR status: ost$status);

    VAR
      entry_p: ^nft$remote_validation,
      next_entry_p: ^nft$remote_validation;

    status.normal := TRUE;

    osp$set_job_signature_lock (nfv$remote_validation.lock);

    entry_p := nfv$remote_validation.ptr;

    IF location = 'ALL' THEN
      WHILE entry_p <> NIL DO
        next_entry_p := entry_p^.next_entry;
        FREE entry_p IN osv$task_shared_heap^;
        entry_p := next_entry_p;
      WHILEND;
      nfv$remote_validation.ptr := NIL;

    ELSEIF entry_p^.location = location THEN
      nfv$remote_validation.ptr := entry_p^.next_entry;
      FREE entry_p IN osv$task_shared_heap^;

    ELSE

    /clear_one_entry/
      WHILE entry_p <> NIL DO
        next_entry_p := entry_p^.next_entry;
        IF next_entry_p^.location = location THEN
          entry_p^.next_entry := next_entry_p^.next_entry;
          FREE next_entry_p IN osv$task_shared_heap^;

          EXIT /clear_one_entry/;
        IFEND;
        entry_p := next_entry_p;
      WHILEND /clear_one_entry/;
    IFEND;

    osp$clear_job_signature_lock (nfv$remote_validation.lock);

  PROCEND nfp$clear_remote_validation;

?? TITLE := '  [XDCL, #GATE] nfp$remote_validation_display', EJECT ??
{
{     The purpose of this request is to display the remote validation entries
{ for the specified remote location(s).  The remote validation table is located
{ in the task shared heap and each entry contains one or more lines of
{ directives to be sent to a remote server application.
{
{       NFP$REMOTE_VALIDATION_DISPLAY (LOCATIONS, OUTPUT_FILE, STATUS)
{
{ LOCATIONS: (input)  This parameter specifies an array of one or more names
{       of remote locations for which the validation display is requested.
{       If 'ALL' is specified, all validation entries will be displayed.
{
{ OUTPUT_FILE: (input)  This parameter specifies the file to which the display
{       output is to be written.
{
{ STATUS: (output)  This parameter specifies the request status.
{       CONDITIONS: nfe$remote_val_empty, nfe$remote_val_undefined.
{       IDENTIFIER: nfc$status_id
{

  PROCEDURE [XDCL, #GATE] nfp$remote_validation_display
    (    locations: ^array [1 .. * ] of ost$name;
         output_file: fst$file_reference;
     VAR status: ost$status);

?? NEWTITLE := '    abort_handler', EJECT ??

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      IF output_open THEN
        clp$close_display (display_control, ignore_status);
        output_open := FALSE;
      IFEND;

    PROCEND abort_handler;

?? OLDTITLE, EJECT ??
    VAR
      caller_id: ost$caller_identifier,
      default_ring_attributes: amt$ring_attributes,
      display_control: clt$display_control,
      loc_index: integer,
      local_status: ost$status,
      location_count: integer,
      output_open: boolean;


    status.normal := TRUE;
    output_open := FALSE;
    osp$establish_block_exit_hndlr (^abort_handler);

    #CALLER_ID (caller_id);

    default_ring_attributes.r1 := caller_id.ring;
    default_ring_attributes.r2 := caller_id.ring;
    default_ring_attributes.r3 := caller_id.ring;

    clp$open_display_reference (output_file, NIL, fsc$list, default_ring_attributes, display_control, status);
    IF NOT status.normal THEN
      osp$disestablish_cond_handler;
      RETURN
    IFEND;
    output_open := TRUE;
    location_count := UPPERBOUND (locations^);

  /display/
    BEGIN
      FOR loc_index := 1 TO location_count DO
        IF locations^ [loc_index] = 'ALL' THEN
          display_all_validations (display_control, status);
          EXIT /display/;
        ELSE
          display_validation_entry (display_control, locations^ [loc_index], status);
          IF NOT status.normal THEN
            EXIT /display/;
          IFEND;
        IFEND;
      FOREND;
    END /display/;

    clp$close_display (display_control, local_status);
    IF NOT local_status.normal AND (status.normal) THEN
      status := local_status;
    IFEND;

    osp$disestablish_cond_handler;

  PROCEND nfp$remote_validation_display;
?? TITLE := '    display_all_validations', EJECT ??

{
{    Procedure to display all remote validation entries defined for job.
{

  PROCEDURE display_all_validations
    (VAR display_control: clt$display_control;
     VAR status: ost$status);

    VAR
      display_line: string (2 * osc$max_name_size),
      entry_p: ^nft$remote_validation,
      location: ost$name,
      location_count: integer,
      loc_index: integer,
      location_list: ^array [1 .. * ] of ost$name;

    status.normal := TRUE;

    osp$set_job_signature_lock (nfv$remote_validation.lock);

    entry_p := nfv$remote_validation.ptr;
    IF entry_p = NIL THEN
      osp$set_status_abnormal (nfc$status_id, nfe$remote_val_empty, '', status);
      osp$clear_job_signature_lock (nfv$remote_validation.lock);
      RETURN;
    IFEND;

    location_count := 0;
    WHILE entry_p <> NIL DO
      entry_p := entry_p^.next_entry;
      location_count := location_count + 1;
    WHILEND;

    PUSH location_list: [1 .. location_count];
    entry_p := nfv$remote_validation.ptr;
    FOR loc_index := 1 TO location_count DO
      location_list^ [loc_index] := entry_p^.location;
      entry_p := entry_p^.next_entry;
    FOREND;

    osp$clear_job_signature_lock (nfv$remote_validation.lock);

    FOR loc_index := 1 TO location_count DO
      display_validation_entry (display_control, location_list^ [loc_index], status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    FOREND;

  PROCEND display_all_validations;

?? TITLE := '    display_validation_entry', EJECT ??

{
{    Procedure to display validation text for a location.
{

  PROCEDURE display_validation_entry
    (VAR display_control: clt$display_control;
         location: ost$name;
     VAR status: ost$status);

    VAR
      entry_p: ^nft$remote_validation,
      display_line: string (2 * osc$max_name_size);


    status.normal := TRUE;

    osp$set_job_signature_lock (nfv$remote_validation.lock);

  /display_entry/
    BEGIN
      get_validation_entry (location, entry_p);
      IF entry_p = NIL THEN
        osp$set_status_abnormal (nfc$status_id, nfe$remote_val_undefined, location, status);
        EXIT /display_entry/;
      IFEND;

      display_line := 'LOCATION: ';
      display_line (11, osc$max_name_size) := location;
      clp$put_display (display_control, display_line, clc$trim, status);
      IF NOT status.normal THEN
        EXIT /display_entry/;
      IFEND;

    END /display_entry/;

    osp$clear_job_signature_lock (nfv$remote_validation.lock);

  PROCEND display_validation_entry;

?? TITLE := '  get_validation_entry', EJECT ??

  PROCEDURE get_validation_entry
    (    location: ost$name;
     VAR entry_p: ^nft$remote_validation);


    entry_p := nfv$remote_validation.ptr;
    IF location <> 'ALL' THEN
      WHILE entry_p <> NIL DO
        IF entry_p^.location = location THEN
          RETURN;
        IFEND;
        entry_p := entry_p^.next_entry;
      WHILEND;
    IFEND;

  PROCEND get_validation_entry;

MODEND nfm$remote_validation;
