PROCEDURE main_batch_output_filter (
  input, i: record
      system_file_name: name 19..19
      password: string 1..31
    recend = $required
  output, o: (VAR) file = $required
  statistics_file, sf: file = $required
  device_environment_variable, dev: name = $required
  file_attributes, fa: (VAR) record
      comment_banner: string 0..31 = $optional
      data_mode: key
        (coded, c)
        (transparent, t)
      keyend = $optional
      forms_code: string 0..6 = $optional
      page_length: integer 0..4398046511103 = $optional
      page_width: integer 10..255 = $optional
      routing_banner: string 0..31 = $optional
      vertical_print_density: key
        six, eight
      keyend = $optional
      vfu_load_procedure: any of
        key
          none
        keyend
        name
      anyend = $optional
    recend = $required
  file_disposition, fd: (VAR) key
      (hold, h)
      (print_and_hold, pah)
      (print_and_terminate, pat)
      (terminate, t)
    keyend = $required
  status)

" Filtering disabled.

  EXIT_PROC

" Site-defined CONSTANTS

"$FORMAT=OFF
  VAR
    debug_commands: file = $system.batch_device_support.main_debug
    postscript_dictionaries: any of
        key
          none
        keyend
        list of file
      anyend = none
    postscript_dictionary_catalog: file =
          $system.batch_device_support.postscript_dictionaries
    printer_validation_file: file =
          $system.batch_device_support.printer_validation
  VAREND

" VARIABLES

  VAR
    banner_count: integer 1..3
    data_mode: key
        (coded, c)
        (transparent, t)
      keyend
    ec4: string 6
    filter_input: record
        system_file_name: name 19..19
        password: string 1..31
        file: file = $optional
      recend = (input.system_file_name, input.password)
    ignore_status: status
    local_status: status
    user_info: string
  VAREND
"$FORMAT=ON

" Obtain access to utilities and sub-filters.

  PUSH command_list
  create_command_list_entry ..
        $system.batch_device_support.standard_filters.command_library ..
        status=ignore_status

" Issue debug information if protocol_trace is enabled.

  IF $variable(nfv$rhf_protocol_trace, defined) AND ..
        (nfv$rhf_protocol_trace = 'BTFC') THEN
    display_message m='-- MAIN BATCH OUTPUT FILTER CALLED' to=job ..
          status=ignore_status
    display_message m='INPUT:' to=job status=ignore_status
    display_value input o=$local.$job_log do=ds status=ignore_status
    display_message m='STATISTICS_FILE:' to=job status=ignore_status
    display_value statistics_file o=$local.$job_log do=ds status=ignore_status
    display_message m='DEVICE_ENVIRONMENT_VARIABLE:' to=job status=ignore_status
    display_value device_environment_variable o=$local.$job_log do=ds ..
          status=ignore_status
    include_command 'display_value '//..
$string(device_environment_variable)//' do=ds o=$local.$job_log' ..
          status=ignore_status
    display_message m='FILE_ATTRIBUTES:' to=job status=ignore_status
    display_value file_attributes o=$local.$job_log do=ds status=ignore_status
    display_message m='FILE_DISPOSITION:' to=job status=ignore_status
    display_value file_disposition o=$local.$job_log do=ds status=ignore_status
  IFEND

" Determine whether the version of SCFS controlling this I/O station supports
" Batch Output Filters.  Quit if it does not.

  include_command c='test_scfs=$device_attributes('//..
$string(dev)//', banner_page_count)' status=local_status
  IF NOT local_status.normal THEN
    display_message ..
          m='-- Version of SCFS does NOT support BATCH_OUTPUT_FILTERS.' ..
          to=job status=ignore_status
    display_message m='   MAIN_BATCH_OUTPUT_FILTER abandoned.' to=job ..
          status=ignore_status
    EXIT_PROC
  IFEND

" Enter the SYSTEM_OPERATOR_UTILITY with SYSTEM_OPERATION capability.  This
" is necessary in order to use the $JOB_OUTPUT function and the
" COPY_OUTPUT_FILE command for output queue files created by other users.

  SYSTEM_OPERATOR_UTILITY capability=system_operation

" Initialize some common variables.

    data_mode = file_attributes.data_mode
    ec4 = $translate(ltu, $device_attributes(dev, external_characteristics_4))
    filter_input.system_file_name = input.system_file_name
    filter_input.password = input.password
    user_info = $translate(ltu, $job_output(input.system_file_name, ui))

" Execute commands from DEBUG_COMMANDS file (if any).

    IF ($file(debug_commands, size) > 0) THEN
      include_file debug_commands status=local_status
      IF NOT local_status.normal THEN
        display_message m='** Main Output Filter DEBUG_COMMANDS failed.' ..
              to=job status=ignore_status
        EXIT_PROC WITH local_status
      IFEND
    IFEND

" Validate user access to printer.
"
"   Site-defined convention
"   -----------------------
"
"   File $SYSTEM.BATCH_DEVICE_SUPPORT.PRINTER_VALIDATION is used to specify
"   device access restrictions.  This file should be protected by setting its
"   ring attributes to (6,6,6).  See the CONTROL_ACCESS filter for the format
"   of this file.  Note that if the file does not exist or is empty, no
"   validation checking is performed.
"
"   Note that this filter does not really filter data (no OUTPUT is produced).

    control_access sfn=input.system_file_name dev=dev ..
          af=printer_validation_file sf=statistics_file fd=file_disposition ..
          status=local_status

    IF NOT local_status.normal THEN
      display_message m='** The CONTROL_ACCESS Output Filter failed.' to=job ..
            status=ignore_status
      EXIT_PROC WITH local_status
    IFEND

    EXIT_PROC WHEN (file_disposition = hold) " Access has been denied

" Process files for PostScript devices.
"
"   Site-defined convention
"   -----------------------
"
"   If the device TERMINAL_MODEL is POSTSCRIPT then:
"
"   - If the file DATA_MODE is TRANSPARENT or the OUTPUT_ATTRIBUTE
"     USER_INFORMATION (specified on the PRINT_FILE) is 'POSTSCRIPT' then
"     the file is a PostScript file and is filtered.  The output from this
"     filter is TRANSPARENT.
"
"   - If the file DATA_MODE is CODED (with USER_INFORMATION <> 'POSTSCRIPT')
"     then no PostScript filtering is done.

    IF ($device_attributes(dev, terminal_model) = postscript) AND ..
          ((data_mode = transparent) OR (user_info = 'POSTSCRIPT')) THEN

      output = $unique($local) " Define new filter output file

      preprocess_postscript_file i=filter_input o=output ..
            dc=postscript_dictionary_catalog dn=postscript_dictionaries ..
            dm=data_mode status=local_status

      IF $field(filter_input, file, initialized) THEN
        delete_file filter_input.file status=ignore_status
      IFEND

      IF NOT local_status.normal THEN
        display_message ..
              m='** The PREPROCESS_POSTSCRIPT_FILE Output Filter failed.' ..
              to=job status=ignore_status
        EXIT_PROC WITH local_status
      IFEND

      file_attributes.data_mode = data_mode
      filter_input.file = output " Prepare for possible chaining of filters

" Add PostScript Banner.  This is only done if the device BPC is 0 and EC4
" is 'BPBOF1' (see banner page convention, below).

      IF ($device_attributes(dev, banner_page_count) = 0) AND (ec4 = 'BPBOF1')..
             THEN

        output = $unique($local) " Define new filter output file

        generate_postscript_banner i=filter_input o=output dm=data_mode ..
              status=local_status

        IF $field(filter_input, file, initialized) THEN
          delete_file filter_input.file status=ignore_status
        IFEND

        IF NOT local_status.normal THEN
          display_message m=..
'** The GENERATE_POSTSCRIPT_BANNER_PAGE Output Filter failed.' to=job ..
                status=ignore_status
          EXIT_PROC WITH local_status
        IFEND

        file_attributes.data_mode = data_mode
        filter_input.file = output " Prepare for possible chaining of filters

      IFEND

      EXIT_PROC " Can do no more with transparent PostScript file

    IFEND

" Process files with embedded ASCII format effectors.
"
"   Site-defined convention
"   -----------------------
"
"   If the file USER_INFORMATION (specified on the PRINT_FILE) is 'ASCII'
"   then the file contains ASCII format effectors and is filtered.  The
"   output from this filter is always CODED.

    IF user_info = 'ASCII' THEN

      output = $unique($local) " Define new filter output file

      emulate_format_effectors i=filter_input o=output hts=standard vts=none ..
            pl=file_attributes.page_length pw=file_attributes.page_width ..
            dm=data_mode status=local_status

      IF $field(filter_input, file, initialized) THEN
        delete_file filter_input.file status=ignore_status
      IFEND

      IF NOT local_status.normal THEN
        display_message ..
              m='** The EMULATE_FORMAT_EFFECTORS Output Filter failed.' ..
              to=job status=ignore_status
        EXIT_PROC WITH local_status
      IFEND

      file_attributes.data_mode = data_mode
      filter_input.file = output " Prepare for possible chaining of filters

    IFEND

" Generate Banner Pages.
"
"   Site-defined convention
"   -----------------------
"
"   If the device attribute BANNER_PAGE_COUNT is 0 (no banners generated by
"   the CDCNET DI) then EXTERNAL_CHARACTERISTICS_4 attribute specifies banner
"   placement.
"
"   EXTERNAL_CHARACTERISTICS_4 is assumed to be of the form:  'BPpppn'
"
"     Where:  ppp = BAE for banner at Beginning And End of file
"             ppp = BOF for banner at Beginning Of File
"             ppp = EOF for banner at End Of File
"
"             n = Number of banner-pages (1..3)
"
"   If EXTERNAL_CHARACTERISTICS_4 is not in the recognized format, no
"   banners are generated.

    IF $device_attributes(dev, banner_page_count) = 0 THEN
      IF ((ec4(1, 5) = 'BPBAE') OR (ec4(1, 5) = 'BPBOF') OR ..
            (ec4(1, 5) = 'BPEOF')) THEN
        include_command 'banner_count = '//$integer(ec4(6, 1)) ..
              status=local_status
        IF local_status.normal THEN

          output = $unique($local) " Define new filter output file

          generate_banner_page i=filter_input o=output bp=$name(ec4(3, 3)) ..
                dev=dev bpc=banner_count cb=file_attributes.comment_banner ..
                dm=data_mode rb=file_attributes.routing_banner ..
                status=local_status

          IF $field(filter_input, file, initialized) THEN
            delete_file filter_input.file status=ignore_status
          IFEND
        IFEND

        IF NOT local_status.normal THEN
          display_message ..
                m='** The GENERATE_BANNER_PAGE Output Filter failed.' to=job ..
                status=ignore_status
          EXIT_PROC WITH local_status
        IFEND

        file_attributes.data_mode = data_mode
        filter_input.file = output " Prepare for possible chaining of filters

      IFEND
    IFEND

" Process files destined to the URI Printer.
"
"   Site-defined convention
"   -----------------------
"
"   If the file STATION (specified on the PRINT_FILE) is 'URIPRINT',
"   then the file is filtered.  The input to this filter must be CODED and
"   the output is always TRANSPARENT.

    IF ($device_attributes(dev, station) = URIPRINT) AND ..
       (file_attributes.data_mode = CODED) THEN

      output = $unique($local) " Define new filter output file

      preprocess_uri i=filter_input o=output ..
            fpd = file_attributes.vertical_print_density ..
            dpd = $device_attributes(dev, vertical_print_density) ..
            pl=file_attributes.page_length pw=file_attributes.page_width ..
            status=local_status

      IF $field(filter_input, file, initialized) THEN
        delete_file filter_input.file status=ignore_status
      IFEND

      IF NOT local_status.normal THEN
        display_message ..
              m='** The PREPROCESS_URI Output Filter failed.' ..
              to=job status=ignore_status
        EXIT_PROC WITH local_status
      IFEND

      file_attributes.data_mode = transparent
      filter_input.file = output " Prepare for possible chaining of filters

    IFEND

  QUIT

PROCEND main_batch_output_filter
