?? RIGHT := 110 ??
MODULE fmm$get_info;
{ The routine fmp$get_files_volume_info returns information on the device
{ residency of a file.

?? PUSH (LISTEXT := ON) ??
*copyc clp$validate_local_file_name
*copyc dmp$get_server_fmd
*copyc dmp$get_stored_fmd
*copyc dmp$get_stored_fmd_header_info
*copyc dmp$get_stored_fmd_size
*copyc dmp$get_stored_fmd_volume_list
*copyc dmp$get_tape_volume_information
*copyc dmp$get_tape_volume_list
*copyc dmt$error_condition_codes
*copyc dmt$stored_fmd
*copyc dmt$stored_fmd_size
*copyc fme$file_management_errors
*copyc fmp$get_device_class_and_sfid
*copyc gft$system_file_identifier
*copyc osp$set_status_abnormal
*copyc rmd$volume_declarations
*copyc syp$pop_inhibit_job_recovery
*copyc syp$push_inhibit_job_recovery
?? POP ??
?? TITLE := '  Information Declarations', EJECT ??
*copyc fmd$volume_info

?? TITLE := '  fmp$get_files_volume_info', EJECT ??

  PROCEDURE [XDCL, #GATE] fmp$get_files_volume_info
    (    file: fst$file_reference;
     VAR volume_information: fmt$volume_information;
     VAR status: ost$status);

    VAR
      device_class: rmt$device_class,
      current_volume: amt$volume_number,
      current_vsns: rmt$volume_descriptor,
      density: rmt$density,
      i: integer,
      label_type: amt$label_type,
      num_of_volumes: amt$volume_number,
      number_of_volumes: integer,
      p_vsn_array: ^rmt$volume_list,
      requested_volume_attributes: iot$requested_volume_attributes,
      sfid: gft$system_file_identifier,
      volume_overflow_allowed: boolean,
      write_ring: rmt$write_ring;

    fmp$get_device_class_and_sfid (file, device_class, sfid, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    CASE device_class OF
    = rmc$mass_storage_device =
      syp$push_inhibit_job_recovery;
      PUSH p_vsn_array: [1 .. 4];
      get_ms_vsn_list (sfid, number_of_volumes, p_vsn_array, status);
      IF status.normal AND (number_of_volumes > UPPERBOUND (p_vsn_array^)) THEN
        PUSH p_vsn_array: [1 .. number_of_volumes];
        get_ms_vsn_list (sfid, number_of_volumes, p_vsn_array, status);
      IFEND;
      syp$pop_inhibit_job_recovery;
    = rmc$magnetic_tape_device =
      dmp$get_tape_volume_information (sfid, num_of_volumes, current_volume, current_vsns,
            density, write_ring, requested_volume_attributes, volume_overflow_allowed,
            label_type, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      number_of_volumes := num_of_volumes;
      PUSH p_vsn_array: [1 .. number_of_volumes];
      dmp$get_tape_volume_list (sfid, p_vsn_array, status);
    ELSE
      {null and terminal }
      number_of_volumes := 0;
    CASEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    FOR i := LOWERBOUND (volume_information) TO UPPERBOUND (volume_information) DO
      CASE volume_information [i].key OF
      = fmc$number_of_volumes, fmc$volume =
        IF number_of_volumes <= 0 THEN
          volume_information [i].item_returned := FALSE;
        ELSE
          CASE volume_information [i].key OF
          = fmc$number_of_volumes =
            volume_information [i].item_returned := TRUE;
            volume_information [i].number_of_volumes := number_of_volumes;
          = fmc$volume =
            IF (volume_information [i].requested_volume_number < 1) OR (volume_information [i].
                  requested_volume_number > number_of_volumes) THEN
              volume_information [i].item_returned := FALSE;
            ELSE
              volume_information [i].item_returned := TRUE;
              volume_information [i].volume := p_vsn_array^ [volume_information [i].
                    requested_volume_number];
            IFEND;
          ELSE
          CASEND;
        IFEND;

      = fmc$tape_density, fmc$tape_class, fmc$write_ring =
        IF device_class = rmc$magnetic_tape_device THEN
          volume_information [i].item_returned := TRUE;
          CASE volume_information [i].key OF
          = fmc$tape_density =
            volume_information [i].tape_density := density;
          = fmc$tape_class =
            IF density = rmc$38000 THEN
              volume_information [i].tape_class := rmc$mt18;
            ELSE
              volume_information [i].tape_class := rmc$mt9;
            IFEND;
          = fmc$write_ring =
            volume_information [i].write_ring := write_ring;
          ELSE
          CASEND;
        ELSE  { unexpected device class
          volume_information [i].item_returned := FALSE;
        IFEND;
      ELSE { unknown item
        volume_information [i].item_returned := FALSE;
      CASEND;
    FOREND;
  PROCEND fmp$get_files_volume_info;

?? TITLE := '  get_ms_vsn_list', EJECT ??

  PROCEDURE get_ms_vsn_list
    (    sfid: gft$system_file_identifier;
     VAR vsn_count: integer;
     VAR p_vsn_list: ^rmt$volume_list;
     VAR status: ost$status);

    VAR
      fmd_header: pft$fmd_header,
      p_local_volume_list: ^pft$volume_list,
      p_stored_fmd: ^dmt$stored_fmd,
      stored_fmd_size: dmt$stored_fmd_size,
      subfile_index: dmt$subfile_index;

    vsn_count := 0;

    dmp$get_stored_fmd_size (sfid, stored_fmd_size, status);
    IF status.normal THEN
      PUSH p_stored_fmd: [[REP stored_fmd_size OF cell]];
      dmp$get_stored_fmd (sfid, p_stored_fmd^, status);
    ELSEIF status.condition = dme$unexpected_server_file THEN
      PUSH p_stored_fmd: [[REP (#SIZE (dmt$stored_ms_fmd_header) + #SIZE (dmt$stored_ms_fmd_subfile) *
            UPPERBOUND (p_vsn_list^)) OF cell]];
      dmp$get_server_fmd (sfid, p_stored_fmd^, stored_fmd_size, status);
      IF NOT status.normal AND (status.condition = dme$fmd_too_small) THEN
        PUSH p_stored_fmd: [[REP stored_fmd_size OF cell]];
        dmp$get_server_fmd (sfid, p_stored_fmd^, stored_fmd_size, status);
      IFEND;
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    dmp$get_stored_fmd_header_info (p_stored_fmd, fmd_header, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    vsn_count := fmd_header.number_of_subfiles;

    IF vsn_count > UPPERBOUND (p_vsn_list^) THEN
      RETURN;
    IFEND;

    IF vsn_count > 0 THEN
      PUSH p_local_volume_list: [1 .. vsn_count];

      dmp$get_stored_fmd_volume_list (p_stored_fmd, p_local_volume_list, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      FOR subfile_index := 1 TO vsn_count DO
        p_vsn_list^ [subfile_index].external_vsn := p_local_volume_list^ [subfile_index];
        p_vsn_list^ [subfile_index].recorded_vsn := p_local_volume_list^ [subfile_index];
      FOREND;
    IFEND;
  PROCEND get_ms_vsn_list;

MODEND fmm$get_info;
