[comp.unix.ultrix] Duplicating Ultrix TK50s

JIW2@psuvm.psu.edu (06/06/91)

 Here is the code that we use at our site to duplicate TK50s.
It's a c-shell script, and fairly long, but it does the job, and
has a familiar Unix command-line interface and syntax.

This file contains both the dsdp source code, and the dsdp man
page.  Use your editor of choice to cut these into two separate
files.

This is a c-shell (csh) program.

                                          John Wagner

                                    Pennsylvania State University

-----------------------dsdp code starts here---------------------------

# @(#)dsdp
#
set tape_device='/dev/nrmt0h'
### Get the input parameters.
### Parm1 is the qualifier group, which must
### always begin with a dash.
### Parm2 is the name of the device driver for
### the tape drive.
### Parm3 is the directory to be used in the
### copying process.
set parm1 = $1
set parm2 = $2
set parm3 = $3
set initial_parm2 = $parm2
### Put a backslash in front of the first
### parameter string.  This is caused by the
### fact that, since a hyphen is a necessary
### part of parm1, we must force the cshell
### interpreter to recognize it as a literal
### hyphen, rather than trying to use it as
### a special command character.
set parm1 = "\"$parm1
### Parameter 2 is the device-driver file to be
### used.  If no parm2 is entered, use the
### default device.
if ($parm2 == "") then
   set parm2 = $tape_device
endif
### Parameter 3 is the disk directory to use in
### the copy process.  It defaults to the current
### directory.
set dir_name="pwd"
if ($parm3 == "") then
   set parm3=`$dir_name`
endif
#set parm2 = "\"$parm2
#set parm3 = "\"$parm3
#
### For each possible parameter that can
### be entered, we set up a variable with
### which to test for its presence.  Notice
### that we are testing for the presence of
### the "f" qualifier >only at the end of
### the string.<  This is because standard
### UNIX usage requires that "f" (file) qualifiers
### always be placed last in the qualifer list.
### Put backslashes at the beginning of the "-"
### and "f(end-of-line)" test strings, to make sure
### they will be correctly interpreted.
set dash_test=`echo $parm1|egrep '^\\-'`
set dash_test="\"$dash_test
set t_test=`echo $parm1|egrep '\t'`
set t_test="\"$t_test
set d_test=`echo $parm1|egrep '\d'`
set d_test="\"$d_test
set n_test=`echo $parm1|egrep '\n'`
set n_test="\"$n_test
set f_test=`echo $parm1|egrep '\f$'`
set f_test="\"$f_test
#
initial_syntax_checks:
### If no hyphen was used in the qualifier group,
### it is a syntax error.
 if($dash_test == "\")then
    goto syntax_error
 endif
### If neither a "d" nor "t" qualifier was entered, it
### it is a syntax error.
 if (($t_test == "\")&&($d_test == "\")) then
    goto syntax_error
 endif
### If both a "t" and "d" were passed as qualifiers,
### it is a syntax error.
 if (($t_test != "\")&&($d_test != "\")) then
    goto too_many_parameters
 endif
### If the "f" qualifer was used, but no device-name was
### entered, flag an error.
 if (($f_test != "\")&&($initial_parm2 == ""))then
    goto syntax_error
 endif
### If a device-name was given, but no "f" qualifier was
### entered, assume the string entered is the directory-
### name.
 if (($f_test == "\")&&($initial_parm2 != ""))then
    set parm3=$initial_parm2
    set parm2=$tape_device
 endif
### If the device specified does not exist, flag an error.
 if !(-e $parm2)then
    goto invalid_device
 endif
 if !(-d $parm3)then
    goto invalid_directory
 endif
### If the tape device specified is not a norewind ("/n")
### device, do not use it!  Flag an error.
 set norewind_test=`echo $parm2|egrep '/n'`
 if ($norewind_test == "") then
    goto norewind_error
 endif
goto tape_to_disk
#
tape_to_disk:
### Having passed the syntax tests, if the qualifier
### is "t", go to the copy-from-tape section.
 if ($t_test != "\") then
    goto copy_from_tape
 endif
### If the qualifer is not "t" (by this point, it can
### be only "t" or "d"), go to the disk-to-tape section.
 if ($t_test == "\") then
    goto disk_to_tape
 endif
#
disk_to_tape:
### Do a final test to be sure the qualifer was "d".
 if ($d_test == "\") then
    goto syntax_error
 endif
goto copy_from_disk
#
ex_it:
 exit
#
###################
###SUBPROCEDURES###
###################
#
rewind_tape:
# Rewind the tape.
 echo "Procedure ending.  Rewinding tape."
 mt -f $parm2 rewind
goto ex_it
#
syntax_error:
### Print the correct syntax.
 echo "Syntax is: dsdp -<d/t[n][f]> <tape-device> <directory>"
goto ex_it
#
##########################
###TAPE-TO-DISK SECTION###
##########################
copy_from_tape:
 echo "Copying from tape device "$parm2" to directory "$parm3
 echo " "
#
onintr control_c
#
# The first two header files of a DEC distribution tape have a
# block size of 512.  The third has a block size of 10k.  Note
# that this is true ONLY for either single-volume distribution
# tapes, or the first volume of multivolume distribution tape sets.
# If the distribution set spans more than one physical tape, the
# second tape does NOT have header files.  Therefore, we skip the
# header file transfer if we are duplicating the second (or higher)
# tape (signified by the "n" parameter).
if($n_test != "\")then
  echo "No header files being transferrred."
  echo " "
  goto subset_transfer_to_disk
  fi
endif
#
header_transfer_to_disk:
 echo "Transferring header files:"
 echo " "
 echo "TK50.1"
 dd conv=nomulti if=$parm2 of=$parm3/TK50.1 bs=512
 echo "TK50.2"
 dd conv=nomulti if=$parm2 of=$parm3/TK50.2 bs=512
 echo "ROOT"
 dd conv=nomulti if=$parm2 of=$parm3/ROOT bs=10k
#
# After the 3 header files come the subset files.  There may be
# any number of these, but we are using 100 as an arbitrary
# maximum, as a safety net to prevent any possible runaway looping.
# If DEC ever comes up with a distribution tape that has more than
# 100 subset files, this parameter will have to be increased.
#
subset_transfer_to_disk:
 echo " "
 echo "Transferring subset files:"
 echo " "
#
 set loop_index=1
#
 while($loop_index<101)
   echo "Subset file" $loop_index
   dd conv=nomulti if=$parm2 of=$parm3/file.$loop_index bs=10k
   set error_code=$status
# We will run into an I/O error when we run out of tape
# subset files, so use this error condition to trigger
# and end-of-loop.
   if ($error_code != 0) then
     goto no_more_input_subsets
   endif
# If we are not at the end of the subset files, increment
# the loop counter and start again.
   @ loop_index=($loop_index + 1)
 end
goto no_more_input_subsets
#
no_more_input_subsets:
  echo "File with 0 records is end-of-data marker."
# The last file is a dummy created by the final iteration of
# the read loop.  Delete it.
  rm $parm3/file.$loop_index
# Decrement the file counter, to give an accurate count
# of the number of files transferred from tape.
  @ loop_index=($loop_index - 1)
# Announce the number of files transferred.
  echo $loop_index "subset files on this tape."
goto rewind_tape
##############################
###END TAPE-TO-DISK SECTION###
##############################
#
##########################
###DISK-TO-TAPE SECTION###
##########################
copy_from_disk:
 echo "Copying from directory "$parm3" to device "$parm2
#
onintr control_c
#
# If this is a multi-tape distribution and this is not the
# first tape (as signified by using the "n" qualifier), do
# not try to copy any header files (there aren't any).
if($n_test != "\")then
  echo "No header files being transferrred."
  echo " "
  goto subset_transfer_to_tape
  fi
endif
#
header_transfer_to_tape:
# The first two header files of a DEC distribution tape have a
# block size of 512.  The third has a block size of 10k.
 echo "Transferring header files to tape:"
 echo " "
#
# Check to see if the header file exists before trying
# to copy it to tape.  If any one of them is missing,
# the header will be incomplete, so abort immediately.
# If the file is present, dd it to tape with the appropriate
# blocksize.
 if !(-e $parm3/TK50.1) then
    goto incomplete_header
 endif
 echo "TK50.1"
 dd conv=nomulti if=$parm3/TK50.1 of=$parm2 bs=512
#
 if !(-e $parm3/TK50.2) then
    goto incomplete_header
 endif
 echo "TK50.2"
 dd conv=nomulti if=$parm3/TK50.2 of=$parm2 bs=512
#
 if !(-e $parm3/ROOT) then
    goto incomplete_header
 endif
 echo "ROOT"
 dd conv=nomulti if=$parm3/ROOT of=$parm2 bs=10k
#
# After the 3 header files come the subset files.  There may be
# any number of these, but we are using 100 as an arbitrary
# maximum.  If DEC ever comes up with a distribution tape that
# has more than 100 subset files, this parameter will have to
# be increased.
subset_transfer_to_tape:
 echo " "
 echo "Transferring subset files to tape:"
 echo " "
#
 set loop_index=1
#
 while($loop_index<101)
# Check to see if the file exists before doing any disk-to-tape
# copying.  If it does not, assume that no more subset files
# exist (there should never be a break in the sequence) and quit.
 if !(-e $parm3/file.$loop_index) then
   goto no_more_output_subsets
 endif
   echo "Subset file" $loop_index
# Copy the file to tape, at a blocksize of 10k.
   dd conv=nomulti if=$parm3/file.$loop_index of=$parm2 bs=10k
   set error_code=$status
# If anything goes wrong during the dd, call an error procedure and
# quit.  Do not continue cycling until 100 iterations are reached!
   if ($error_code != 0) then
      goto dd_error
   endif
# If we are not at the end of the subset files, increment
# the loop counter and start again.
   @ loop_index=($loop_index + 1)
 end
goto no_more_output_subsets
#
dd_error:
 echo "Error during dd operation.  Aborting procedure."
goto ex_it
#
no_more_output_subsets:
# Decrement the file counter, to give an accurate count
# of the number of files transferred from tape.
  @ loop_index=($loop_index - 1)
# Announce the number of files transferred.
  echo $loop_index "subset files written to this tape."
goto rewind_tape
#
##############################
###END DISK-TO-TAPE SECTION###
##############################
#
incomplete_header:
 echo "Not all header files present.  Aborting transfer."
goto ex_it
#
invalid_option_1:
 echo "First option must be either t (tape to disk) or d (disk to tape)."
goto ex_it
#
too_many_parameters:
 echo "Use d (disk to tape) or t (tape to disk); not both."
goto ex_it
#
invalid_device:
 echo "Device file "$parm2" not found."
goto ex_it
#
invalid_directory:
 echo "Directory "$parm3" not found."
goto ex_it
#
norewind_error:
 echo "Tape device must be norewind (n) device."
goto ex_it
#
control_c:
 echo "CTRL/C interrupt."
 echo "Procedure aborting."
 echo "Copy process incomplete."
goto rewind_tape
#
#########################################################
###                   NOTICE!!!                       ###
### THIS PROGRAM IS NOT WARRANTED OR SUPPORTED BY     ###
### ITS AUTHOR, OR THE PENNSYLVANIA STATE UNIVERSITY  ###
### IN ANY WAY WHATSOEVER!!!                          ###
#                                                       #
#  PROGRAM: dsdp (distribution duplication)             #
#  AUTHOR: John Wagner (jiw2@psuvm.psu.edu)             #
#  SITE: Pennsylvania State University                  #
#  DATE: 08/31/90                                       #
#  DESCRIPTION:                                         #
#   This procedure automates the process of duplicating #
# DEC distribution tapes, and does so with a user inter-#
# face that mimics the standard UNIX command interface. #
# Syntax is:                                            #
#                                                       #
#  dsdp -<d/t>[n][f] [<device-file>] [<directory-file>] #
#                                                       #
# Where "d" indicates disk-to-tape duplication; "t"     #
# indicates tape-to-disk duplication (duplicating a     #
# distribution tape is a two-step process.  It is some- #
# times desired to copy a tape to disk without re-copy- #
# ing it to another tape, or vice-versa).  If the "f"   #
# qualifier is used, the next parameter must be the     #
# driver file for the tape device being used.  If this  #
# option is omitted, /dev/rmt0h is used.  If the "f"    #
# parameter is not used, the first parameter is taken   #
# to be the name of the disk directory to be used in    #
# the copy process.  If the "f" parameter is used, the  #
# first parameter is taken to be the device-name and    #
# the second parameter is taken as the directory-name.  #
# If no directory-specification is given, the current   #
# directory is used.                                    #
#                                                       #
# ADDED 11/29/90:  The "n" qualifier signifies          #
# "noheader".  DEC Ultrix distribution tapes all have   #
# three header files at the beginning of the tape,      #
# with one major exception:  If a distribution spans    #
# more than one tape, ONLY THE FIRST TAPE HAS HEADER    #
# FILES.  All following tapes in the distribution must  #
# be copied with the "n" qualifier, to ensure that the  #
# copy procedure does not treat the first three subset  #
# files on the second tape as headers.                  #
# ADDED 12/19/90:  Added the "conv=nomulti" qualifier   #
# to the dd command.  This qualifier was not implemented#
# under Ultrix 4.0, but is required when doing a dd     #
# operation under 4.1.  The default is now "conv=multi".#
# This now causes the value of $status to become non-   #
# zero when end-of-data is detected, and does not return#
# an I/O error message as dd did under 4.0.  The price  #
# to be paid for this is that dd now assumes, rather    #
# foolishly, that all tapes being copied with dd are    #
# multivolume tapes.  Trying to run this procedure with-#
# out the "conv=nomulti" qualifier will cause the value #
# of $status to remain zero at end-of-data, and result  #
# in an abnormal termination.                           #
#                                                       #
#########################################################


--------------end of dsdp source code--------------------

----------------start of dsdp man page-------------------

TH dsdp l
SH NAME
dsdp \- Distribution tape duplication
SH SYNTAX
B dsdp -[\fId\fR \fIt\fR][\fIn\fR][\fIf\fR \fItape\fR ] [\fIdirectory\fR]

SH DESCRIPTION
The
B dsdp
command is for the duplication of Digital Ultrix distribution
tapes.  These tapes have a consistent structure, consisting of
three header files (the first two with 512-byte blocksize,
the third of 10kb-blocksize), and a variable number of subset
files, each of 10kb-blocksize.  Note that this is true \fI only \fR
for distribution kits that occupy a single tape volume, or for
the first volume of a distribution kit which spans more than
one tape volume.  Subsequent volumes of multivolume distribution
kits have no header files (see "n" qualifier below).
B dsdp
automates the process of copying these files from tape to disk,
and back to a second tape, thus duplicating the original tape.
SH OPTIONS

   -d         Indicates that copying is to be
              disk-to-tape.

   -t         Indicates that copying is to be
              tape-to-disk.

              The d and t qualifiers are mutually exclusive,
              but one or the other must be specified.

    n         Specifies "noheader."  Does not treat the first
              three files on the current tape as header files.
              This qualifier is to be used when copying any of
              the volumes of a multi-volume distribution set
              other than the first (see above explanation).

    f         Indicates that the next parameter is a device
              driver file for the tape drive being used.  If
              this qualifier and parameter are omitted, the
              default is /dev/nrmt0h.  Only
I norewind
              (/dev/nrmt(n)h) devices may be specified.

SH PARAMETERS

\fI tape\fR          Device driver file for the tape drive to be
               used (see f qualifer).

\fI directory\fR     Disk directory to be used to receive tape
               files (if the t option is being used) or
               from which to copy disk files to tape (if the
               d option is being used).  If this parameter
               is not specified, the current directory is
               used.

SH USE

Duplicating a distribution tape is a two-stage process.  First the
files on the original tape must be copied to disk in their original
blocksize, then the disk files must be copied to a blank tape,
again preserving blocksize, and in the correct order.

SH EXAMPLES

         dsdp -t /user/tapecopy

In this example, the files from the default tape device /dev/nrmt0h
are copied to the disk directory /user/tapecopy.

         dsdp -df /dev/nrmt2h

In this example, the files from the current disk directory are copied
to tape device /dev/nrmt2h.

         dsdp -tf /dev/nrmt4h /opr/distribution

In this example, the files from tape device /dev/nrmt4h are copied to
disk directory /opr/distribution.

         dsdp -d

In this example, the files from the current directory are copied to
the default tape device /dev/nrmt0h.

         dsdp -tn

In this example, the files from tape device /dev/nrmt0h are copied
to the current directory.  None of the files on the tape are treated
as header files.

SH RESTRICTIONS

dsdp is \fIonly\fR for duplication of TK50 distribution tapes (tapes
which contain installable software).  Attempting to use it for
duplication of any other tape will produce unpredictable and
probably undesirable results.

SH SUMMARY

Once files have been copied to disk, they may be written to an
unlimited number of blank tapes.

To copy files from a distribution tape to a disk directory, use
the t (tape-to-disk) qualifier.

To copy files from a disk directory to a tape, use the
d (disk-to-tape) qualifier.

If you are copying a product distribution that spans more than
one tape, do \fInot\fR use the "n" qualifier when duplicating the
first tape.  \fIDo\fR use the "n" qualifier when duplicating the
following tapes in the distribution.

SH FILES

     /usr/new/dsdp
     /usr/man/manl/dsdp.l

SH SEE ALSO

dd(1), mt(1)

-----------------------end of dsdp man page----------------------