PROCEDURE retrieve_qualified_files, retqf (
  retrieve_file_list, rfl: file = $required
  accessed_after, aa: date_time = $optional
  accessed_before, ab: date_time = $optional
  created_after, ca: date_time = $optional
  created_before, cb: date_time = $optional
  duplicated_after, da: date_time = $optional
  duplicated_before, db: date_time = $optional
  expired_after, ea: date_time = $optional
  expired_before, eb: date_time = $optional
  modified_after, ma: date_time = $optional
  modified_before, mb: date_time = $optional
  retrieved_after, ra: date_time = $optional
  retrieved_before, rb: date_time = $optional
  size_greater_than, sgt: integer = $optional
  size_less_than, slt: integer = $optional
  total_megabyte_limit, tml: integer = $optional
  pause_for_retrieval, pfr: boolean = TRUE
  pause_trigger_point, ptp: integer 1..4000 = 2000
  retrieval_trigger_point, rtp: integer 1..100 = 100
  status)

  VAR
    candidate: boolean
    chunk_size: integer = 1000
    date_parameter_specified: boolean
    file_name: file
    files: list 0 .. 100 of string (512)
    files_analyzed: integer = 0
    files_retrieved: integer = 0
    handler_entered: boolean = false
    ignore_status: status
    local_status: status
    min_allocation_unit: integer = 16384
    one_mb: integer = 1048576
    path_string: string (512)
    pause_counter: integer = 0
    permanent_file: boolean = ($file_attributes(retrieve_file_list lifetime)(1).lifetime = unlimited)
    retrieval_list: list of file = ()
    size_accumulator: integer = 0
    size_limit: integer = $max_integer
  VAREND

  WHEN any_fault exit terminate DO
    IF NOT handler_entered THEN
      handler_entered = true
      change_catalog_access flush_catalogs=true
      IF permanent_file THEN
        detach_file f=retrieve_file_list status=ignore_status
      IFEND
      IF ($size(retrieval_list) > 0) THEN
        retrieve_files file=retrieval_list wait_for_retrieval=false
        files_retrieved = files_retrieved + $size(retrieval_list)
      IFEND
      delete_variable attrib status=ignore_status
      delete_variable file_list status=ignore_status
      stop_time = $time
      display_value (' Files Processed: '//files_analyzed)
      display_value (' Files Processed: '//files_analyzed) o=$job_log
      display_value (' Files Retrieved: '//files_retrieved)
      display_value (' Files Retrieved: '//files_retrieved) o=$job_log
      display_value (' Retrieval Byte Limit: '//size_limit)
      display_value (' Retrieval Byte Limit: '//size_limit) o=$job_log
      display_value (' Bytes Retrieved: '//size_accumulator)
      display_value (' Bytes Retrieved: '//size_accumulator) o=$job_log
      display_value (' Started At: '//start_time)
      display_value (' Started At: '//start_time) o=$job_log
      display_value (' Stopped At: '//stop_time)
      display_value (' Stopped At: '//stop_time) o=$job_log
    IFEND
    EXIT retrieve_qualified_files WITH osv$status
  WHENEND

  start_time = $time
  date_parameter_specified = $specified(accessed_after) OR $specified(accessed_before)
  date_parameter_specified = date_parameter_specified OR $specified(created_after) OR $specified(created_before)
  date_parameter_specified = date_parameter_specified OR $specified(duplicated_after) OR $specified(duplicated_before)
  date_parameter_specified = date_parameter_specified OR $specified(expired_after) OR $specified(expired_before)
  date_parameter_specified = date_parameter_specified OR $specified(modified_after) OR $specified(modified_before)
  date_parameter_specified = date_parameter_specified OR $specified(retrieved_after) OR $specified(retrieved_before)
  IF $specified(total_megabyte_limit) THEN
    IF (total_megabyte_limit > 0) AND (total_megabyte_limit < ($max_integer/one_mb)) THEN
      size_limit = total_megabyte_limit * one_mb
    IFEND
  IFEND

  change_catalog_access flush_catalogs=false

  IF permanent_file THEN
    attach_file f=retrieve_file_list local_file_name=$name($unique()) private_read=false status=local_status
  IFEND

  IF local_status.normal THEN
    execute_task sp=pfp$get_file_list p='file=retrieve_file_list.$boi variable_name=file_list list_size=chunk_size' ..
          l=$system.osf$task_services_library status=local_status
  main_block: ..
    WHILE local_status.normal AND ($size(file_list) > 0) DO
      attrib = $file_attributes(file_list, (creation_date_time cycle_number device_class expiration_date last_access_date_time ..
            last_modification_date_time lifetime object_type path registered secondary_residence size))

      FOR EACH file_ref IN attrib DO
        files_analyzed = files_analyzed + 1
        IF file_ref.registered AND (file_ref.lifetime = 'UNLIMITED') AND (file_ref.device_class = 'MASS_STORAGE') AND ..
              (file_ref.object_type = 'CYCLE') THEN
          candidate = false
          IF date_parameter_specified THEN

            IF $specified(accessed_after) THEN
              candidate = candidate OR (file_ref.last_access_date_time > accessed_after)
            IFEND
            IF (NOT candidate) AND $specified(accessed_before) THEN
              candidate = candidate OR (file_ref.last_access_date_time < accessed_before)
            IFEND

            IF (NOT candidate) AND $specified(created_after) THEN
              candidate = candidate OR (file_ref.creation_date_time > created_after)
            IFEND
            IF (NOT candidate) AND $specified(created_before) THEN
              candidate = candidate OR (file_ref.creation_date_time < created_before)
            IFEND

            IF (NOT candidate) AND $specified(modified_after) THEN
              candidate = candidate OR (file_ref.last_modification_date_time > modified_after)
            IFEND
            IF (NOT candidate) AND $specified(modified_before) THEN
              candidate = candidate OR (file_ref.last_modification_date_time < modified_before)
            IFEND

            IF (NOT candidate) AND (NOT $nil(file_ref.secondary_residence)) THEN
              FOR i = 1 TO $size(file_ref.secondary_residence) DO
                IF $specified(duplicated_after) THEN
                  candidate = candidate OR (file_ref.secondary_residence(i).duplication_date_time > duplicated_after)
                IFEND
                IF (NOT candidate) AND $specified(duplicated_before) THEN
                  candidate = candidate OR (file_ref.secondary_residence(i).duplication_date_time < duplicated_before)
                IFEND

                IF (NOT candidate) AND ..
                      ($name($generic_type(file_ref.secondary_residence(i).last_data_retrieval_date_time)) <> 'KEY') THEN
                  IF $specified(retrieved_after) THEN
                    candidate = candidate OR (file_ref.secondary_residence(i).last_data_retrieval_date_time > retrieved_after)
                  IFEND
                  IF (NOT candidate) AND $specified(retrieved_before) THEN
                    candidate = candidate OR (file_ref.secondary_residence(i).last_data_retrieval_date_time < retrieved_before)
                  IFEND
                IFEND
              FOREND
            IFEND

            IF (NOT candidate) AND ($name($generic_type(file_ref.expiration_date)) <> 'KEY') THEN
              IF $specified(expired_after) THEN
                candidate = candidate OR (file_ref.expiration_date > expired_after)
              IFEND
              IF $specified(expired_before) THEN
                candidate = candidate OR (file_ref.expiration_date < expired_before)
              IFEND
            IFEND

            IF candidate AND $specified(size_greater_than) AND (NOT $specified(size_less_than)) THEN
              candidate = (file_ref.size > size_greater_than)
            ELSEIF candidate AND $specified(size_less_than) AND (NOT $specified(size_greater_than)) THEN
              candidate = (file_ref.size < size_less_than)
            ELSEIF candidate AND $specified(size_less_than) AND $specified(size_greater_than) THEN
              candidate = ((file_ref.size > size_greater_than) AND (file_ref.size < size_less_than))
            IFEND
          ELSE
            IF $specified(size_greater_than) AND (NOT $specified(size_less_than)) THEN
              candidate = (file_ref.size > size_greater_than)
            ELSEIF $specified(size_less_than) AND (NOT $specified(size_greater_than)) THEN
              candidate = (file_ref.size < size_less_than)
            ELSEIF $specified(size_less_than) AND $specified(size_greater_than) THEN
              candidate = ((file_ref.size > size_greater_than) AND (file_ref.size < size_less_than))
            ELSE
              candidate = true
            IFEND
          IFEND

          IF candidate THEN
            path_string = $string(file_ref.path)//'.'//$string(file_ref.cycle_number)
            IF ($size(retrieval_list) > 0) THEN
              IF $size(retrieval_list) = retrieval_trigger_point THEN
                files_retrieved = files_retrieved + retrieval_trigger_point
                retrieve_files file=retrieval_list wait_for_retrieval=false
                pause_counter = pause_counter + retrieval_trigger_point
                IF pause_for_retrieval AND (pause_counter >= pause_trigger_point) THEN
                  send_operator_message message=..
'RETRIEVE_QUALIFIED_FILES - waiting for retrievals.  Acknowledge this message to process more retrieval candidates.' ..
                        operator_class=removable_media_operator
                  pause_counter = 0
                IFEND
                retrieval_list = $list_of($fname(path_string))
              ELSE
                retrieval_list = $join(retrieval_list $fname(path_string))
              IFEND
            ELSE
              retrieval_list = $list_of($fname(path_string))
            IFEND
            size_accumulator = size_accumulator + ..
                  (((file_ref.size + min_allocation_unit - 1)/min_allocation_unit)* min_allocation_unit)
            IF size_accumulator >= size_limit THEN
              EXIT main_block
            IFEND
          IFEND
        IFEND
      FOREND
      delete_variable attrib status=ignore_status
      execute_task sp=pfp$get_file_list p='file=retrieve_file_list.$asis variable_name=file_list list_size=chunk_size' ..
            l=$system.osf$task_services_library status=local_status
    WHILEND main_block
  IFEND
  EXIT_PROC WHEN (NOT local_status.normal) AND (local_status.condition <> ame$input_after_eoi) with local_status

PROCEND retrieve_qualified_files
