Script Source Code for "mkuue"

This document contains the source code for the Disaster Recovery script "mkuue".



#!/usr/bin/ksh93.att
################################################################
function usagemsg {
  print ""
  print "Program: mkuue"
  print ""
  print "This script retrieves a list of files from a remote"
  print "host, uuencodes them, and builds a self extracting and"
  print "configuring script around the uuencoded file."
  print ""
  print "Usage: ${1##*/} srcFile destFile fileAttributes"
  print ""
  print "   srcFile = The name of the source file to uuencode"
  print ""
  print "   destFile = The name of the destination file after"
  print "              it is uudecoded"
  print ""
  print "   fileAttributes = This is \"ls -l\" output for the"
  print "             destination file after it is uudecoded. "
  print "             This information is used to set attributes"
  print "             such as permissions, owner, group."
  print ""
  print "Author: Dana French (dfrench@mtxia.com)"
  print ""
  print "\"AutoContent\" enabled"
  print ""
}
################################################################
#### 
#### Description:
#### 
#### This utility creates a self extracting archive for a specified
#### file.  The self extracting archive contains a shell script that
#### that knows how to test and reconfigure various attributes of the
#### file, and the archive also contains a "uuencoded" copy of the 
#### file itself.  The attributes tested and reconfigured by the self
#### extracting archive include cksum, owner, group and permissions.
#### This utility generates the shell script necessary to perform these
#### tests and reconfigurations, uuencodes the specified file, and
#### saves all of this to a single archive.  This archive may be executed
#### which causes the file to be extracted, installed, tested, and 
#### configured as the original file in its original location.
#### 
#### Assumptions:
#### 
#### It is assumed the source file exists and is not the same name
#### as the destination file.
#### The "uuencode" command is accessible in the PATH variable.
#### The "cksum" command calculates a 32-bit Cyclic Redundancy Check (CRC)
#### which is POSIX 1003.2 compliant.
#### The execute permission bit for the archive files generated by this 
#### utility will be set.
#### 
#### Dependencies:
#### 
#### The self extracting archives generated by this utility will require
#### the directories containing the "uudecode" and "cksum" commands to be
#### in the PATH variable.
#### 
#### Documentation for this script is maintaned using the "AutoContent" 
#### utilities and requires the script be maintained according to 
#### those standards.
#### 
#### Products:
#### 
#### This utility generates a self extracting archive for any file.  The 
#### archive will contain all the information necessary to install and 
#### configure the file to its original location.  The file can be 
#### extracted, tested, installed and configured simply by executing the
#### archive file.
#### 
#### Configured Usage:
#### 
#### This utility requires three command line arguments.
#### 
#### srcFile = The file to be archived
#### 
#### destFile = The name of the file after it is extracted from the archive.
#### 
#### fileAttributes = The file attributes of the destination file after
#### it is extracted from the archive.  The attributes should be in the
#### form of "ls -l" output and should be enclosed in quotes on the
#### command line so that they all appear as the 3rd command line argument.
#### 
#### Details:
#### 
################################################################
TRUE="1"
FALSE="0"
VERBOSE="${VERBOSE:-${FALSE}}"

trap "usagemsg ${0}" EXIT
[[ "_${1}" = "_-?" ]] && exit 1
SRCFILE="${1:?ERROR: Full Path Source File Name not specified}"
DESTFILE="${2:?ERROR: Full Path Destination file name not specified}"
RLL="${3:?ERROR: ls -l output of Destination file not specified}"
trap "-" EXIT

shift 2
RLL="${*}"

  (( VERBOSE == TRUE )) && print -u2 "#     Processing ${SRCFILE}"

################################################################
#### 
#### When the "mkuue" script begins, the first thing it does is process
#### the 3rd command line argument and extract the various file attributes
#### for the destination file.  The file owner and group can be easily
#### extracted from the "ls -l" output, however the permissions require
#### some processing.
#### 
################################################################

# extract the owner for the file from the ls -l output
  FOWNER=$( print -- "${RLL}" | awk '{ print $3 }' )
# extract the group for the file from the ls -l output
  FGROUP=$( print -- "${RLL}" | awk '{ print $4 }' )
# extract the permission settings for the file from the ls -l output
  PERMS="${RLL:1:9}"

################################################################
#### 
#### The permission settings are contained within the first 10 characters
#### of the "ls -l" output and are processed in 3 steps. The first character
#### is the file type and is ignored, the next 3 characters are associated
#### with the "user" or file owner permissions.  The permissions are
#### checked to see if the tacky bit or SUID bit is set.  If so
#### the appropriate permission setting is added to the permission string
#### which will be used when the file is extracted.
#### 
################################################################

# extract the user permission settings for the file from the ls -l output
  UPERMS="${PERMS:0:3}"
# remove the dashes "-" from the user permissions
  UPERMS="${UPERMS//\-/}"
# Convert lowercase "s" to "xs" in the user permissions
  UPERMS="${UPERMS//s/xs}"
# Convert uppercase "S" to "s" in the user permissions
  UPERMS="${UPERMS//S/s}"
# Convert lowercase "t" to "xt" in the user permissions
  UPERMS="${UPERMS//t/xt}"
# Convert uppercase "T" to "t" in the user permissions
  UPERMS="${UPERMS//T/t}"

################################################################
#### 
#### The next set of 3 characters are associated with the "group" 
#### category of permissions.  The permissions are checked to see 
#### if the tacky bit or SUID bit is set.  If so the appropriate 
#### permission setting is added to the permission string which will 
#### be used when the file is extracted.
#### 
################################################################

# extract the group permission settings for the file from the ls -l output
  GPERMS="${PERMS:3:3}"
# remove the dashes "-" from the group permissions
  GPERMS="${GPERMS//\-/}"
# Convert lowercase "s" to "xs" in the group permissions
  GPERMS="${GPERMS//s/xs}"
# Convert uppercase "S" to "s" in the group permissions
  GPERMS="${GPERMS//S/s}"
# Convert lowercase "t" to "xt" in the group permissions
  GPERMS="${GPERMS//t/xt}"
# Convert uppercase "T" to "t" in the group permissions
  GPERMS="${GPERMS//T/t}"

################################################################
#### 
#### The last set of 3 characters are associated with the "other" 
#### category of permissions.  Again, the permissions are checked to see 
#### if the tacky bit or SUID bit is set.  If so the appropriate permission 
#### setting is added to the permission string which will be used when the 
#### file is extracted.
#### 
################################################################

# extract the other permission settings for the file from the ls -l output
  OPERMS="${PERMS:6:3}"
# remove the dashes "-" from the other permissions
  OPERMS="${OPERMS//\-/}"
# Convert lowercase "s" to "xs" in the other permissions
  OPERMS="${OPERMS//s/xs}"
# Convert uppercase "S" to "s" in the other permissions
  OPERMS="${OPERMS//S/s}"
# Convert lowercase "t" to "xt" in the other permissions
  OPERMS="${OPERMS//t/xt}"
# Convert uppercase "T" to "t" in the other permissions
  OPERMS="${OPERMS//T/t}"

################################################################
#### 
#### With the permission setting strings for each user category now known
#### and extracted from the "ls -l" output, a mnemonic "exact setting"
#### string is constructed for use with the "chmod" command during the
#### archive extraction.
#### 
################################################################

# Build the mnemonic mode exact permission setting command
  FMODE="u=${UPERMS},g=${GPERMS},o=${OPERMS}"

################################################################
#### 
#### The checksum of the source file is obtained and saved so that it may
#### be compared with the checksum of the destination file when the archive
#### is extracted.  The checksum is assumed to be a 
#### POSIX 1003.2 compliant 32-bit checksum Cyclic Redundancy Check (CRC).
#### 
################################################################

# get the cksum of the local file after the copy
  LCKSUM=$( cksum < "${SRCFILE}" )

  UUENAME="/tmp/${LCKSUM// /}.src"

################################################################
#### 
#### A korn shell script is now created by "mkuue" which will contain the
#### commands necessary to extract, test the cksum, and configure the file 
#### attributes of the destination file.  This script is what has been
#### referred to previously as the "self extracting archive".  Each 
#### archive always checks to see if it is being executed by "root" 
#### as this is necessary to perform the "chown" commmand.
#### 
################################################################

  print "#!/bin/ksh
####################################
WHOAMI=\$( whoami )
if [[ \"_\${WHOAMI}\" != \"_root\" ]]
then
    print -u2 \"ERROR: \${0} You must be \\\"root\\\" to execute this script\"
    exit 1
fi

################################################################
#### 
#### Within the script generated by mkuue, the script uudecodes itself,
#### which will extract the uuencoded portion of the
#### script to a temporary file location.  The temporary file is then
#### copied to the original source file name in preparation for the
#### checksum.
#### 
################################################################

uudecode \${0}

if ! cp \"${UUENAME}\" \"${SRCFILE}\"
then
    print -u2 \"ERROR: cp \\\"${UUENAME}\\\"  \\\"${SRCFILE}\\\"\"
    exit 2
fi

rm -rf \"${UUENAME}\"

################################################################
#### 
#### During the execution of the self extracting archive, the 
#### original checksum is compared with the checksum of the newly 
#### extracted file.  If they do not match, an error message is 
#### displayed and the script exits.
#### 
################################################################

OLDCKSUM=\"${LCKSUM}\"
NEWCKSUM=\$( cksum < \"${SRCFILE}\" )
if [[ \"_\${OLDCKSUM}\" != \"_\${NEWCKSUM}\" ]]
then
    print -u2 \"ERROR: ${SRCFILE} Checksums do not match\"
    exit 3
fi

################################################################
#### 
#### The script "mkuue" will now generate commands to cause the self 
#### extracting archive to copy the newly created and tested source 
#### file to the destination file name.  If during the execution of 
#### the self extracting archive, the environment variable 'ALT_ROOT'
#### is set, its value will be prepended to the destination file name. 
#### This allows self extracting archives to be extracted to alternate
#### locations such as an 'alt_rootvg'.  If the copy fails, an
#### error message is displayed and the script exits.
#### 
################################################################

mkdir -p \"\${ALT_ROOT}${DESTFILE%/*}\"
if ! cp \"${SRCFILE}\" \"\${ALT_ROOT}${DESTFILE}\"
then
    print -u2 \"ERROR: Unable to cp ${SRCFILE} \${ALT_ROOT}${DESTFILE}\"
    exit 4
fi
rm -f \"${SRCFILE}\"

################################################################
#### 
#### Commands are generated to cause the self extracting archive to 
#### change the owner of the file to match the owner specified in the 
#### file attributes when the archive was created.
#### 
################################################################

if ! chown ${FOWNER} \"\${ALT_ROOT}${DESTFILE}\"
then
    print -u2 \"ERROR: Unable to chown ${FOWNER} \${ALT_ROOT}${DESTFILE}\"
    exit 5
fi
################################################################
#### 
#### Similarly, commands are generated to cause the group setting 
#### of the file to be changed to match the group specified in the 
#### file attributes when the archive was created.
#### 
################################################################

if ! chgrp ${FGROUP} \"\${ALT_ROOT}${DESTFILE}\"
then
    print -u2 \"ERROR: Unable to chgrp ${FGROUP} \${ALT_ROOT}${DESTFILE}\"
    exit 6
fi
################################################################
#### 
#### Finally, commands will be generated to cause the the self extracting 
#### archive to reset the permissions of the destination file according to 
#### permissions specified on the command line when the archive was created.
#### 
#### The commands necessary to extract the destination file from the archive
#### are complete.
#### 
################################################################

if ! chmod ${FMODE} \"\${ALT_ROOT}${DESTFILE}\"
then
    print -u2 \"ERROR: Unable to chmod ${FMODE} \${ALT_ROOT}${DESTFILE}\"
    exit 7
fi
exit 0
####################################
" > "${SRCFILE}.uue"

################################################################
#### 
#### The source file will now be uuencoded and appended to the end of the
#### self extracting archive script.  The file name to which the archive
#### will be initially extracted is a temporary file name, rather than the
#### actual destination file name.  This is so the "cksum"s can be compared
#### and evaluated before replacing the existing file.  If the cksums do not
#### match, the existing file is NOT replaced, and an error message is
#### issued.
#### 
################################################################

#     if uuencode "${SRCFILE}" < "${SRCFILE}" >> "${SRCFILE}.uue"
    if uuencode "${UUENAME}" < "${SRCFILE}" >> "${SRCFILE}.uue"
    then
        chmod 755 "${SRCFILE}.uue"
    else
        print -u2 "ERROR: uuencode of \"${SRCFILE}\" failed"
    fi
    rm -f "${SRCFILE}"

    exit 0

################################################################
#### 
#### The creation of the self extracting archive is now complete.
#### The archive can be stored and saved for later use. It contains
#### all the information it needs to extract, test, install,
#### and configure the destination file it contains.
#### 
################################################################

This file last modified 02/04/09