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