PROCEDURE restore_cataloged_files, rescf, restore, res (
  restore_catalogs, rc: boolean = $required
  vsn_prefix, vsnp, vp: any of
      name 1..5
      string 1..5
      integer 1..99999
    anyend = $optional
  vsn_count, vsnc, vc: integer 1..11881376 = 9
  vsn_suffix, vsns, vs: any of
      name 1..5
      string 1..5
      integer 1..99999
    anyend = $optional
  increment_scheme, is: key
      (alphabetic, a)
      (decimal, d)
    keyend = decimal
  vsn_list, vsnl: list of any of
      name 1..6
      string 1..6
    anyend = $optional
  file_label_type, flt: key
      (labeled, labelled, l)
      (unlabeled, unlabelled, u)
    keyend = labeled
  type, t: key
      mt9$800, mt9$1600, mt9$6250, mt18$38000
    keyend = mt9$6250
  backup_file, bf: file = $optional
  execution_mode, em: key
      (batch_job, bj)
      (asynchronous_task, at)
      (synchronous_task, st)
    keyend = batch_job
  output, o: file = $list
  status)


"  The purpose of this procedure is to restore files from a set
"  of backup tapes or from a permanent backup file.
"  The list of VSN's for the backup tapes are generated by the procedure
"  depending on the values for vsn_prefix, vsn_count, vsn_suffix and
"  increment_scheme.
"
"  PARAMETERS:
"    restore_catalogs, rc: This parameter specifies whether the catalog
"      information on this set of backup tapes should be restored.
"      When specified as false, only the cycle information is restored.
"      If restoring from several sets of backup tapes the initial restore
"      should restore the most recent catalog information available and
"      all successive restores should restore the cycle data only.
"
"    vsn_prefix, vsnp: Specify a one to five character name, string or integer
"      that will become the leftmost characters in the list of VSN's generated
"      by the procedure.
"
"    vsn_count, vsnc: The number of backup tapes in the set. This parameter
"      determines how many VSN's will be in the list generated by the
"      procedure.
"
"    vsn_suffix, vsns: This parameter specifies the rightmost characters of
"      the first vsn in the set you wish to restore. A name or string value
"      should be supplied for an alphabetic increment scheme and an integer
"      for a decimal increment scheme. This parameter should only be used when
"      problems are encountered during a restore that make it necessary to
"      restart the restore at a point other than the first reel.
"
"    increment_scheme, is: This parameter determines the format for the
"      rightmost characters of the VSN's generated by this procedure.
"      Decimal mode is the default. Alphabetic mode is for situations
"      where a decimal increment scheme does not allow enough tapes.
"
"    vsn_list, vsnl: A list of magnetic tape external VSNs generated by
"      an calling procedure such as SELECT_OPERATOR_MENU.  This parameter
"      value overrides the vsn_prefix, vsn_count, and increment_scheme VSN
"      generation parameters.
"
"    file_label_type, flt: This parameter specifies the type of label
"      on the backup tapes you are using. If this parameter is not specified,
"      then LABELED is used.
"
"    type, t: This parameter specifies the density of the backup tapes
"      you are using.
"
"    backup_file: This parameter is used to restore from a permanent backup
"      file, which can be either a permanent mass storage file or a permanent
"      tape file.  If this parameter is specified, the following parameters
"      will be ignored.
"
"          file_label_type
"          increment_scheme
"          type
"          vsn_count
"          vsn_list
"          vsn_prefix
"          vsn_suffix
"
" Note: If the execution mode is asynchronous_task or synchronous_task and
"       the backup file is attached prior to calling this procedure, the
"       backup file must be attached with a LOCAL_FILE_NAME of BACKUP_FILE.
"
"    execution_mode, em: This parameter specifies the mode of execution for
"      the task restoring the data.  When a file or catalog required for job
"      initiation is missing a batch job cannot be used to restore the data.
"      The default is to execute as a batch job.
"
"    output, o: This parameter specifies the file to which the output from
"      the restore session will be written.  When an EXECUTION_MODE of
"      asynchronous_task or synchronous_task is selected the output
"      parameter must be specified. The default is $LIST.
"
" VSN Generation Examples:
"   vsn_prefix=part vsn_count=12 increment_scheme=decimal ==>part01-part12
"   vsn_prefix=part vsn_count=12 increment_scheme=alphabetic ==>partaa-partal
"
"   vsn_prefix=A1 vsn_count=27 increment_scheme=decimal ==>A10001-A10027
"   vsn_prefix=A1 vsn_count=27 increment_scheme=alphabetic ==>A1AAAA-A1AABA
"
"   vsn_prefix=full vsn_count=4 vsn_suffix=7 is=decimal ==> FULL07-FULL10
"   vsn_prefix=full vsn_count=4 vsn_suffix=E is=alphabetic ==> FULLAE-FULLAH
"
" Restore Examples:
" Note:- In the examples below, the backup is refered to as a set of backup
" tapes from a full or partial backup, but the backup can also be on a
" permanent mass storage file or a permanent tape file.
"
" 1. There is only one set of backup tapes (from the last full backup).
"    restore restore_catalogs=true vsn_prefix=full vsn_count=17
"
" 2. There is a set of partial backup tapes (from partial_backup)
"    and a set of full backup tapes (from full_backup).
"
"    restore restore_catalogs=true vsn_prefix=part vsn_count=5
"      After the all partial tapes have been requested and
"      the job, restore, completes do:
"    restore restore_catalogs=false vsn_prefix=full vsn_count=17
"      The operator should assign_device all tapes specified.
"
"    If a site arranges their backups such that they do a partial
"    backup of files modified for each day, they must do a restore
"    for each set of partials (starting with the most recently generated
"    and working backwards through each partial set) and finally restore
"    for the set of full backups.
"
"    restore restore_catalogs=true vsn_prefix=part vsn_count=5
"
"    Wait for the initial restore job to complete and
"    for each set partial backup tapes remaining do:
"    restore restore_catalogs=false vsn_prefix=part vsn_count=5
"
"    When the final partial restore has completed start
"    a restore job for the full backup tapes.
"    restore restore_catalogs=false vsn_prefix=full vsn_count=17
"
" 3. If there are both a set of partial tapes and full tapes, and
"    for some reason an error occurs attempting to restore the fourth
"    tape in the set of partials, you can restart in the middle
"    of a set using the vsn_suffix parameter.
"
"      This job aborts on forth tape.
"      restore restore_catalogs=on vsn_prefix=part vsn_count=6
"
"      This command will start a restore job for tapes part05 & part06.
"      restore restore_catalogs=on vsn_prefix=part vsn_count=2 vsn_suffix=5
"
"      Then after all partial tapes are read restore the full backup.
"      restore restore_catalogs=off vsn_prefix=full vsn_count=17
"
" 4. If, for some reason, the set of partial tapes is completely
"     unreadable you must skip that days partials and begin the
"     restore with the previous days backup.
"
"     restore restore_catalogs=on vsn_prefix=part vsn_count=5
"     restore restore_catalogs=off vsn_prefix=full vsn_count=17
"
"    If, for some reason, the set of full backup tapes is lost or
"    is completely unreadable the following operations must be performed.
"     a) Restore the current weeks partials, most recent first.
"     b) Restore the previous weeks partials, most recent first.
"     c) restore the previous weeks full backups.
"
"    restore rc=on vsn_prefix=pafr vsn_count=4  - Most recent partial
"    restore rc=off vsn_prefix=path vsn_count=5  - Remainder of current
"                           .                      weeks partials
"                           .
"    restore rc=off vsn_prefix=pbfr vsn_count=6  - Previous week partials
"                           .
"                           .
"    restore rc=off vsn_prefix=fbsu vsn_count=20  - Previous weeks full backup

  VAR
    backup_file_already_attached: boolean = FALSE
    job_file: file = $unique(:$local)
    volume_list: list 1 .. $max_list of string 6
  VAREND

  IF $specified(backup_file) THEN
    IF $string($file_attributes(backup_file, lifetime)) <> 'UNLIMITED'  THEN
      EXIT procedure WITH $status(false, 'PU', 3330, 'The file specified '//..
'by the BACKUP_FILE parameter must be a permanent mass storage file or a permanent tape file.')
    ELSE
      IF NOT $string($file_attributes(backup_file, registered))='YES' THEN
        EXIT procedure WITH $status(false, 'PU', 3330, 'The file specified '//..
'by the BACKUP_FILE parameter must be an existing permanent mass storage file or a permanent tape file.')
      IFEND
    IFEND
  ELSE
    IF $specified(vsn_list) THEN
      delete_variable volume_list
      volume_list = $apply(vsn_list, $string(x))
    ELSE
      pup$construct_volume_list vsn_count=vsn_count vsn_prefix=vsn_prefix increment_scheme=increment_scheme ..
            vsn_suffix=vsn_suffix volume_list=volume_list
    IFEND
  IFEND

  IF $string(execution_mode)(1) = 'B' THEN
    execution_mode_command = 'JOB job_name=restore job_class=system magnetic_tape_limit=unlimited'
    terminate_execution_command = 'JOBEND'
  ELSEIF $string(execution_mode)(1) = 'S' THEN
    execution_mode_command = ''
    terminate_execution_command = ''
  ELSE
    execution_mode_command = 'TASK task_name=restore'
    terminate_execution_command = 'TASKEND'
  IFEND

  IF ($string(execution_mode)(1) <> 'B') AND NOT $specified(output) THEN
    EXIT procedure WITH $status(false, 'PU', 0, ..
'The OUTPUT parameter must be specified when an EXECUTION_MODE other than BATCH_JOB is selected.')
  IFEND

  IF $specified(backup_file) THEN
    IF $string($file_attributes(backup_file, attached)) = 'YES' AND ..
         $string(execution_mode)(1) <> 'B' THEN
      IF NOT $nil($select_string($string($file_attributes(backup_file, potential_job_access)),'READ')) THEN
        IF NOT $string($file_attributes($local.backup_file, registered))='YES' THEN
          EXIT procedure WITH $status(false, 'PU', 3330, 'If the file specified '//..
'by the BACKUP_FILE parameter is already attached, the LOCAL_FILE_NAME must be BACKUP_FILE.')
        IFEND
        attach_or_request_command = ''
        backup_file_already_attached = TRUE
      ELSE
        attach_or_request_command = 'attach_file am=read local_file_name=backup_file file= '//$string(backup_file)
      IFEND
    ELSE
      attach_or_request_command = 'attach_file am=read local_file_name=backup_file file= '//$string(backup_file)
    IFEND
  ELSE
    attach_or_request_command = 'request_magnetic_tape file=$local.backup_file ring=no type='//$string(type)// ..
          ' external_vsn='//$string(volume_list, source)// ..
          '; set_file_attributes file=$local.backup_file file_label_type='//$string(file_label_type)
  IFEND

"Create a file containing a batch job to do the actual restore.
COLLECT_TEXT output=job_file sm='?' until='**END_COLLECT**'
  ?execution_mode_command?
    IF NOT $variable(ignore_status, local) THEN
      VAR
        ignore_status: status
      VAREND
    IFEND
    create_command_list_entry entry=$system.osf$builtin_library status=ignore_status
    create_command_list_entry entry=$system.osf$sou_library status=ignore_status
    ?attach_or_request_command?

    WHEN any_fault DO
     IF NOT ?backup_file_already_attached? THEN
       detach_file file=$local.backup_file
     IFEND
     display_value osv$status
     send_operator_message ' RESTORE_CATALOGED_FILES aborted -check listing '
    WHENEND

    SYSTEM_OPERATOR_UTILITY CAPABILITY=SYSTEM_ADMINISTRATION
    TASK ring=3
      restore_permanent_files list=?output?
        set_restore_options update_cycle_statistics=FALSE restore_archive_information=TRUE
        IF "restore_catalogs =" ?restore_catalogs? THEN
          restore_all_files backup_file=$local.backup_file
        ELSE
          restore_excluded_file_cycles backup_file=$local.backup_file
        IFEND
      QUIT
      change_file_attributes file=?output? ring_attributes=(11 11 11) status=ignore_status
    TASKEND
    IF NOT ?backup_file_already_attached? THEN
      detach_file file=$local.backup_file
    IFEND
    QUIT
  ?terminate_execution_command?
**END_COLLECT**

  include_file file=job_file
  detach_file file=job_file

PROCEND restore_cataloged_files
