1147 lines
39 KiB
Bash
1147 lines
39 KiB
Bash
#!/bin/ksh
|
|
# @(#)05 1.33 src/bldenv/pkgtools/genfsimage.sh, pkgtools, bos41B, 9506B 1/25/95 15:38:21
|
|
#
|
|
# COMPONENT_NAME: PKGTOOLS
|
|
#
|
|
# FUNCTIONS: abort
|
|
# check_cmdline_parms
|
|
# getmemo
|
|
# quiet_abort
|
|
# resolv_ptf_paths_excluding_prereqs
|
|
# resolv_ptf_paths_including_prereqs
|
|
# syntax
|
|
#
|
|
# ORIGINS: 27
|
|
#
|
|
# IBM INTERNAL USE ONLY
|
|
#
|
|
# (C) COPYRIGHT International Business Machines Corp. 1991,1993
|
|
# All Rights Reserved
|
|
# US Government Users Restricted Rights - Use, duplication or
|
|
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
|
#
|
|
|
|
#===============================================================================
|
|
#
|
|
# Purpose:
|
|
# This shell creates a file system of stacked output from a list of
|
|
# PTF/ccss files. The order of search on the servers is: Build,
|
|
# production, then ship.
|
|
#
|
|
# Syntax:
|
|
# genfsimage <-l> <-d> [-A] [-b] [-o] [-p] [-e] [-t] [-s] [-x] [-c]
|
|
# [-B] [-w] [-m] [-N] [-M] [-V] [-T] [-h] [-?]
|
|
#
|
|
# Flags: Ref. usage message
|
|
#
|
|
#===============================================================================
|
|
|
|
trap '
|
|
rm -rf $WORK
|
|
exit 2
|
|
' 1 2 3 15
|
|
######################### Function ############################################
|
|
# The 'syntax' function simply echos command syntax, then exits the shell. #
|
|
################################################################################
|
|
syntax() {
|
|
echo "\n$cmd <-l> <-d> [-A] [-b] [-p] [-s] [-e] [-t] [-o] [-x] [-c] [-B]"
|
|
echo " [-m] [-N] [-M] [-V] [-T] [-h] [-?]"
|
|
echo "FLAGS: -l Stack list file contains PTF/ccss file names, or, "
|
|
echo " APAR numbers if the -A flag is specified."
|
|
echo " (default is that all prereqs are included)"
|
|
echo " -d Target directory where network .toc and bff images"
|
|
echo " are written."
|
|
echo " -A Include only PTFs for the APAR numbers listed in the stack"
|
|
echo " list file (specified by the -l flag). For version 4 PTFs"
|
|
echo " only. By default, any existing prereqs are also included."
|
|
echo " -b User build directory containing .ptf files (i.e. in CCSS"
|
|
echo " format) created with cum_ptf (for 3.2) or ptf_pkg (for 4.1)."
|
|
echo " -p The name of Product directory. "
|
|
echo " (default is in 32_pkg_environment) "
|
|
echo " -s The name of Ship directory."
|
|
echo " (default is in 32_pkg_environment) "
|
|
echo " -w Directory_name where the temporary files generated by this"
|
|
echo " by this program are written. The default is /tmp."
|
|
echo " -e Exclude PTF prereqs (overrides default)."
|
|
echo " PTF files will be installed in the order specified."
|
|
echo " -t There can be duplicate PTF's on BUILD_SVR and PROD or"
|
|
echo " SHIP server"
|
|
echo " -o Generate the toc image only without bff images"
|
|
echo " -x Exclude superseded images"
|
|
echo "HIT <ENTER> TO RECEIVE THE REST OF MESSAGE"
|
|
read
|
|
echo " -c Check filesystem size before generating backup images on"
|
|
echo " filesystem"
|
|
echo " -B Set both Ship directory and Product directory;"
|
|
echo " Default is setting Ship directory only."
|
|
echo " -m Do not generate the memo_to_users file under the"
|
|
echo " target directory."
|
|
echo " -N Do not include fixes from Problem Resolution file."
|
|
echo " (overrides default)"
|
|
echo " -M Current maintenance level on target system. All PTFs in "
|
|
echo " this and earlier maintenance levels are excluded from output."
|
|
echo " -V The target AIX version for the specified PTF/ccss files. "
|
|
echo " Default is '3' for AIX version 3."
|
|
echo " -T The mapping table for PTF to vrmf information per fileset. "
|
|
echo " (i.e. the ptfapardef file) This flag must be specified when "
|
|
echo " both the -b and -V options are used, IF the -V option specifies"
|
|
echo " AIX version 4."
|
|
echo " -h/-? Prints this help screen."
|
|
echo "\nNotes: File and Directory names can be absolute or relative.\n"
|
|
echo " -t requires Ship directory, Product directory and"
|
|
echo " build directory to be specified."
|
|
echo " Either use -b and -B options or -b, -p and -s options.\n"
|
|
echo " Default values for product directory and ship directory are"
|
|
echo " taken from 41_pkg_environment if AIX version 4 is specified."
|
|
|
|
rm -rf $WORK
|
|
if [ $error_code != 0 ]; then
|
|
echo "\ngenfsimage FAILED!\n"
|
|
else
|
|
echo ""
|
|
fi
|
|
exit $error_code
|
|
}
|
|
|
|
######################### Function ############################################
|
|
# The 'abort' function terminates the shell and removes work files. #
|
|
################################################################################
|
|
abort() {
|
|
rm -rf $WORK
|
|
echo "\ngenfsimage FAILED!\n"
|
|
exit 1
|
|
}
|
|
|
|
|
|
######################### Function ############################################
|
|
# The 'quiet_abort' function terminates the shell created by a while read loop.#
|
|
################################################################################
|
|
quiet_abort() {
|
|
exit 1
|
|
}
|
|
|
|
|
|
######################### Function ###########################################
|
|
# Function to verify required files, directories, and access privileges
|
|
###############################################################################
|
|
check_cmdline_parms() {
|
|
# Check to see if -l was used
|
|
if [ "x$stack_dir" = "x" ]; then
|
|
echo "\n$cmd: ERROR: -l option is required."
|
|
error_code=15
|
|
fi
|
|
|
|
# Check to see if -d was used
|
|
if [ "x$target_dir" = "x" ]; then
|
|
echo "\n$cmd: ERROR: -d option is required."
|
|
error_code=16
|
|
fi
|
|
|
|
# Check production directory
|
|
if [ "$ship_prod" = "yes" ]; then
|
|
if [ "x$prod_dir" = "x" ]; then
|
|
echo "\n$cmd: ERROR: Specify the production directory with the"
|
|
echo "\t-p option or the PROD_DIRNAME environment variable.\n"
|
|
error_code=17
|
|
syntax
|
|
else
|
|
if [ ! -d $prod_dir ]; then
|
|
echo "\n$cmd: ERROR: The production directory $prod_dir is invalid"
|
|
echo "\tUse the -p option or the PROD_DIRNAME environment variable\n"
|
|
echo "\tto specify the production directory."
|
|
error_code=18
|
|
else
|
|
if [ ! -r $prod_dir ]; then
|
|
echo "\n$cmd: ERROR: The production directory $prod_dir is not readable"
|
|
error_code=19
|
|
else
|
|
# Set prod_dir to absolute path
|
|
cd $prod_dir
|
|
prod_dir=`pwd`
|
|
cd $START_DIR
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Check ship directory
|
|
if [ "x$ship_dir" = "x" ]; then
|
|
echo "\n$cmd: ERROR: Specify the ship directory with the"
|
|
echo "\t-s option or the SHIP_DIRNAME environment variable.\n"
|
|
error_code=20
|
|
syntax
|
|
else
|
|
if [ ! -d $ship_dir ]; then
|
|
echo "\n$cmd: ERROR: The ship directory $ship_dir is invalid"
|
|
echo "\tUse the -s option or the SHIP_DIRNAME environment variable\n"
|
|
echo "\tto specify the ship directory."
|
|
error_code=21
|
|
else
|
|
if [ ! -r $ship_dir ]; then
|
|
echo "\n$cmd: ERROR: The ship directory $ship_dir is not readable"
|
|
error_code=22
|
|
else
|
|
# Set ship_dir to absolute path
|
|
cd $ship_dir
|
|
ship_dir=`pwd`
|
|
cd $START_DIR
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
#
|
|
# Check for unique directory names
|
|
#
|
|
if [ "x$build_dir" != "x" ]; then
|
|
if [ $build_dir = $ship_dir ]; then
|
|
echo "\n$cmd: ERROR: The build and ship directories are the same"
|
|
error_code=23
|
|
fi
|
|
if [ "x$prod_dir" != "x" ]; then
|
|
if [ $build_dir = $prod_dir ]; then
|
|
echo "\n$cmd: ERROR: The build and production directories are the same"
|
|
error_code=24
|
|
fi
|
|
fi
|
|
fi
|
|
if [ "x$prod_dir" != "x" ]; then
|
|
if [ $prod_dir = $ship_dir ]; then
|
|
echo "\n$cmd: ERROR: The production and ship directories are the same"
|
|
error_code=25
|
|
fi
|
|
fi
|
|
|
|
#
|
|
# Check that prod and ship index files are readable
|
|
#
|
|
if [ "x$prod_dir" != "x" -a "$ship_prod" = "yes" ];then
|
|
if [ ! -f $prod_dir/index -o ! -r $prod_dir/index ]; then
|
|
echo "\n$cmd: ERROR: Unable to read file '$prod_dir/index'"
|
|
error_code=26
|
|
fi
|
|
fi
|
|
if [ ! -f $ship_dir/index -o ! -r $ship_dir/index ]; then
|
|
echo "\n$cmd: ERROR: Unable to read file '$ship_dir/index'"
|
|
error_code=27
|
|
fi
|
|
|
|
# test to make sure flag -t and -b were used together
|
|
if [ "$duplicate_ptf" = "yes" ]; then
|
|
if [ "x$build_dir" = "x" -o "x$prod_dir" = "x" ]; then
|
|
echo "$cmd: ERROR: FLAG -t requires -b and -B or -p options"
|
|
error_code=28
|
|
fi
|
|
fi
|
|
|
|
# Check that maint_level file is readable
|
|
if [ "x$current_mlevel" != "x" ]; then
|
|
if [ ! -f $mlevel_file -o ! -r $mlevel_file ]; then
|
|
echo "$cmd: WARNING: $mlevel_file file not readable."
|
|
echo "$cmd continuing; will ignore -M flag value."
|
|
current_mlevel=""
|
|
else
|
|
# Check that maintenance level specified is valid
|
|
current_mlevel=`grep $current_mlevel $mlevel_file`
|
|
word_count=`echo $current_mlevel | wc -w`
|
|
if [ $word_count -gt 1 ]; then
|
|
echo "$cmd: ERROR: Too many maintenance levels specified"
|
|
echo "$cmd: Please specify one of the following on the command line:"
|
|
echo "$cmd: "$current_mlevel
|
|
echo "$cmd: or refer to the file $mlevel_file"
|
|
error_code=29
|
|
fi
|
|
if [ "x$current_mlevel" = "x" ]; then
|
|
echo "$cmd: WARNING: maintenance level $current_mlevel not found."
|
|
echo "$cmd continuing; will ignore -M flag value."
|
|
current_mlevel=""
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Check for the ptfapardef mapping table (option -T) if -V option
|
|
# specified AIX version 4 AND -b option was used.
|
|
if [ "$aix_version" = "41" -a "x$build_dir" != "x" -a "x$map_table" = "x" ];
|
|
then
|
|
echo "$cmd: ERROR: Please specify the ptfapardef mapping table (option -T)"
|
|
error_code=31
|
|
fi
|
|
|
|
if [ "$aix_version" != "41" -a "$apar_fix" = "yes" ]; then
|
|
echo "$cmd: ERROR: The -A flag can only be used for 41 PTFs. Use"
|
|
echo "$cmd the -V flag to specify the correct AIX version level."
|
|
error_code=32
|
|
fi
|
|
}
|
|
|
|
|
|
######################### Function ############################################
|
|
# The 'resolv_ptf_paths_excluding_prereqs' function strips any user provided
|
|
# information, then locates the ptf file in build, prod,
|
|
# or ship (in that order).
|
|
################################################################################
|
|
resolv_ptf_paths_excluding_prereqs() {
|
|
|
|
echo "$cmd: Resolving location of ptfs in the input list."
|
|
|
|
# empty the ordered stack list
|
|
> $ORD_STACK_LIST
|
|
|
|
# loop through input stacklist resolving the pathname
|
|
for PTF_file in `cat $STACK_LIST` ; do
|
|
|
|
# Convert PTF file names to just ptf# (no path, no .ptf)
|
|
PTF_file=`basename $PTF_file | sed -e "s/.ptf$//"`
|
|
|
|
# Add absolute path name to PTF file if in build
|
|
if [ "x$build_dir" != "x" -a -f ${build_dir}/$PTF_file.ptf ]; then
|
|
echo "${build_dir}/$PTF_file.ptf" >> $ORD_STACK_LIST
|
|
else
|
|
# Add absolute path name to PTF file if in prod
|
|
if [ "x$prod_dir" != "x" -a -f ${prod_dir}/$PTF_file.ptf ]; then
|
|
echo "${prod_dir}/$PTF_file.ptf" >> $ORD_STACK_LIST
|
|
else
|
|
# Add absolute path name to PTF file if in ship
|
|
if [ -f ${ship_dir}/$PTF_file.ptf ]; then
|
|
echo "${ship_dir}/$PTF_file.ptf" >> $ORD_STACK_LIST
|
|
else
|
|
#
|
|
# handle case where ptf not found
|
|
#
|
|
echo "$cmd: ERROR: PTF file $PTF_file not found on:"
|
|
# don't mention build directory if cmd was invoked without it
|
|
if [ "x$build_dir" != "x" ]; then
|
|
echo "$cmd: $build_dir"
|
|
fi
|
|
if [ "x$prod_dir" != "x" ]; then
|
|
echo "$cmd: $prod_dir"
|
|
fi
|
|
echo "$cmd: $ship_dir"
|
|
if [ "x$prod_dir" = "x" -a "x$build_dir" = "x" ]; then
|
|
echo "$cmd: ERROR: PTF(s) could be in PROD or BUILD SERVERS and in test phase"
|
|
echo "$cmd: Please use -p or -B option to set PROD SERVER"
|
|
echo "$cmd: and -b option to set BUILD SERVER"
|
|
else
|
|
if [ "x$prod_dir" = "x" ]; then
|
|
echo "$cmd: ERROR: PTF(s) could be in PROD SERVER and in test phase"
|
|
echo "$cmd: Please use -p or -B option to set PROD SERVER"
|
|
else
|
|
if [ "x$build_dir" = "x" ]; then
|
|
echo "$cmd: ERROR: PTF(s) could be in BUILD SERVER and in test phase"
|
|
echo "$cmd: Please use -b option to set BUILD SERVER"
|
|
fi
|
|
fi
|
|
fi
|
|
abort
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
|
|
|
|
######################### Function ############################################
|
|
# The 'resolv_ptf_paths_including_prereqs' function strips any user provided
|
|
# information, then locates the ptf file in build, prod,
|
|
# or ship (in that order).
|
|
################################################################################
|
|
resolv_ptf_paths_including_prereqs() {
|
|
|
|
echo "$cmd: Resolving location and requisites of ptfs in the input list."
|
|
|
|
if [ "x$current_mlevel" != "x" ]; then
|
|
# User specified their current maintenance level. Create an input file
|
|
# for media_list that includes all ptfs in this and earlier maintenance
|
|
# levels. media_list will exclude these ptfs from the toc it builds.
|
|
|
|
# Remove blank lines and comments from maint levels file
|
|
sed '/^$/d' $mlevel_file > $WORK/mlevel_file.$$
|
|
sed '/^#/d' $WORK/mlevel_file.$$ > $WORK/Mfile.$$
|
|
|
|
> $WORK/mlevels.$$
|
|
cat $WORK/Mfile.$$ | while read mfilename; do
|
|
cat $data_dir/$mfilename >> $WORK/mlevels.$$
|
|
if [ "$mfilename" = "$current_mlevel" ]; then
|
|
break
|
|
fi
|
|
done
|
|
# Remove blank lines and comments
|
|
sed '/^$/d' $WORK/mlevels.$$ > $WORK/mlevels.$$.sed
|
|
sed '/^#/d' $WORK/mlevels.$$.sed > $WORK/mlevels.$$
|
|
fi
|
|
|
|
cp $STACK_LIST $WORK/stacklist.in.$$
|
|
|
|
# For 41 PTFs, make sure a complete fix is generated: find additional
|
|
# PTFs associated with the APARS for the input PTFs.
|
|
# If the -A flag was used, the stack list is already a list of APARs.
|
|
|
|
if [ "$aix_version" = "41" ]; then
|
|
> $WORK/aparlist.$$
|
|
if [ "$apar_fix" = "yes" ]; then
|
|
cp $STACK_LIST $WORK/aparlist.$$
|
|
> $WORK/stacklist.in.$$
|
|
else
|
|
cat $STACK_LIST | while read ptfnumber; do
|
|
grep ^$ptfnumber $prod_maptable | \
|
|
awk -F"|" '{print $2}' >>$WORK/aparlist.$$
|
|
done
|
|
fi
|
|
sort -u $WORK/aparlist.$$ -o $WORK/aparlist.$$
|
|
|
|
cat $WORK/aparlist.$$ | while read apar; do
|
|
grep "|$apar|" $prod_maptable | \
|
|
awk -F"|" '{print $1}' >> $WORK/stacklist.in.$$
|
|
done
|
|
sort -u $WORK/stacklist.in.$$ -o $WORK/stacklist.in.$$
|
|
fi
|
|
|
|
# Check for various flags and build media_list command
|
|
|
|
if [ "x$build_dir" = "x" ]; then
|
|
# No build directory specified
|
|
CMD="media_list -l $WORK/stacklist.in.$$ -o $ORD_STACK_LIST -s $ship_dir"
|
|
|
|
if [ "x$prod_dir" = "x" ]; then
|
|
CMD="$CMD -n"
|
|
else
|
|
CMD="$CMD -p $prod_dir -n"
|
|
fi
|
|
if [ "$exclude_supersededs" = "yes" ]; then
|
|
CMD="$CMD -x"
|
|
fi
|
|
if [ "$include_peresl_file" = "yes" ]; then
|
|
CMD="$CMD -r $data_dir/ptfs.fixed.unfixed"
|
|
fi
|
|
if [ "x$current_mlevel" != "x" ]; then
|
|
CMD="$CMD -u $WORK/mlevels.$$"
|
|
fi
|
|
# Execute media_list command and check return code
|
|
$CMD
|
|
rc=$?
|
|
if [ $rc = 99 ]; then
|
|
if [ "x$prod_dir" = "x" ]; then
|
|
echo "$cmd: ERROR: PTF(s) could be in PROD or BUILD SERVERS and in test phase"
|
|
echo "$cmd: Please use -p or -B option to set PROD SERVER"
|
|
echo "$cmd: and -b option to set BUILD SERVER"
|
|
else
|
|
echo "$cmd: ERROR: PTF(s) could be in BUILD SERVER and in test phase"
|
|
echo "$cmd: Please use -b option to set BUILD SERVER"
|
|
fi
|
|
abort
|
|
else
|
|
if [ $rc != 0 ]; then
|
|
echo "\n$cmd: ERROR: Problem with media list"
|
|
echo $CMD
|
|
abort
|
|
fi
|
|
fi
|
|
else
|
|
# Build directory specified
|
|
# Create an 'index' file for the ptf library in temp_dir
|
|
if [ "$aix_version" = "32" ]; then
|
|
gen_ptf_index -o $WORK/index $build_dir
|
|
rc=$?
|
|
else
|
|
gen_ptf_index -o $WORK/index -T $map_table $build_dir
|
|
rc=$?
|
|
fi
|
|
if [ $rc != 0 ]; then
|
|
echo "\n$cmd: ERROR: Problem with gen_ptf_index"
|
|
abort
|
|
fi
|
|
|
|
CMD="media_list -l $WORK/stacklist.in.$$ -o $WORK_STACK_LIST -s $ship_dir"
|
|
|
|
if [ "x$prod_dir" = "x" ]; then
|
|
CMD="$CMD -b $WORK -n"
|
|
else
|
|
CMD="$CMD -b $WORK -p $prod_dir -n"
|
|
fi
|
|
if [ "$exclude_supersededs" = "yes" ]; then
|
|
CMD="$CMD -x"
|
|
fi
|
|
if [ "$duplicate_ptf" = "yes" ]; then
|
|
CMD="$CMD -t"
|
|
fi
|
|
if [ "$include_peresl_file" = "yes" ]; then
|
|
CMD="$CMD -r $data_dir/ptfs.fixed.unfixed"
|
|
fi
|
|
if [ "x$current_mlevel" != "x" ]; then
|
|
CMD="$CMD -u $WORK/mlevels.$$"
|
|
fi
|
|
# Execute media_list command and check return code
|
|
$CMD
|
|
rc=$?
|
|
if [ $rc = 99 ]; then
|
|
if [ "x$prod_dir" = "x" ]; then
|
|
echo "$cmd: ERROR: PTF(s) could be in PROD SERVER and in test phase"
|
|
echo "$cmd: Please use -p or -B option to set PROD SERVER"
|
|
else
|
|
echo "$cmd: ERROR: PTF(s) not found in BUILD, PROD, and SHIP SERVERS"
|
|
echo "$cmd: Please verify the $STACK_LIST file"
|
|
fi
|
|
abort
|
|
else
|
|
if [ $rc != 0 ]; then
|
|
echo "\n$cmd: ERROR: Problem with media list"
|
|
echo $CMD
|
|
abort
|
|
fi
|
|
fi
|
|
|
|
# change build ptf pathnames back to build directory (remember index
|
|
# was placed in the temp directory).
|
|
# Substitution will change '$WORK____' to
|
|
# '$build_dir____'
|
|
sed "s@$WORK\(.*\)@$build_dir\1@" $WORK_STACK_LIST \
|
|
> $ORD_STACK_LIST
|
|
fi
|
|
}
|
|
|
|
|
|
########################## Function ###########################################
|
|
# getmemo converts the info file to ascii format info file and get the memo #
|
|
# from info file if the memo is not "NONE" message. #
|
|
###############################################################################
|
|
getmemo() {
|
|
|
|
dd if=$WORK/info of=$WORK/cvinfo conv=ascii cbs=80 > /dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
echo "$cmd: ERROR: For PTF: $PTF_number, convert info file to ascii"
|
|
echo " format by using \"dd\" command failed!"
|
|
abort
|
|
fi
|
|
|
|
grep "^MEMO TO USERS = NONE$" $WORK/cvinfo > /dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
grep "CLASS" $WORK/info.head > /dev/null 2>&1
|
|
if [ $? -eq 0 ]; then
|
|
classValue=`grep "CLASS" $WORK/info.head |
|
|
awk -F"," '{print $5}' |
|
|
sed -e 's/CLASS//' |
|
|
sed -e 's/[ ]*//'`
|
|
echo "$classValue$PTF_number" >> $WORK/classPTF
|
|
else
|
|
echo "0 $PTF_number" >> $WORK/classPTF
|
|
fi
|
|
echo "*** PTF: $PTF_number ***" >> $WORK/allMEMO
|
|
genabst "MEMO TO USERS" "ENDSET" $WORK/cvinfo $WORK/allMEMO
|
|
rc=$?
|
|
if [ $rc -eq 0 ]; then
|
|
echo "ENDSET " >> $WORK/allMEMO
|
|
else
|
|
if [ $rc -eq 2 ]; then
|
|
echo "$cmd: ERROR: For PTF $PTF_number, there is no \"MEMO TO USERS\""
|
|
echo " information in the info file.\n"
|
|
echo " CONTINUE TO PROCESS NEXT PTF!"
|
|
else
|
|
if [ $rc -eq 3 ]; then
|
|
echo "$cmd: ERROR: For PTF $PTF_number, there is no separator\"ENDSET\""
|
|
echo " in the info file.\n"
|
|
echo " CONTINUE TO PROCESS NEXT PTF!"
|
|
else
|
|
if [ $rc -eq 4 ]; then
|
|
abort
|
|
else
|
|
echo "$cmd: Error occurred in genabst, Please check for above information!"
|
|
echo " CONTINUE TO PROCESS NEXT PTF!"
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
rm -f $WORK/cvinfo
|
|
}
|
|
|
|
|
|
################################################################################
|
|
# START OF SHELL LOGIC. First, check number of parameters on command line. #
|
|
################################################################################
|
|
|
|
set -u
|
|
|
|
########################
|
|
# Initialize variables #
|
|
########################
|
|
build_dir="" # Build directory set to null
|
|
prod_dir="" # Production directory set to null
|
|
ship_dir="" # Ship directory set to null
|
|
target_dir="" # Target directory where toc and images are written
|
|
stack_dir="" # Stack list directory
|
|
CONST_DATE=`date +"%m""%d""%H""%M""%S""%y"` # Constant date stamp
|
|
volume=0 # Preload toc uses a volume number of 0
|
|
START_DIR=`pwd` # Current directory
|
|
STACK_LIST="" # Stack list file name
|
|
toc_format="2" # Header format: same for AIX v3.2 and AIX v4.1
|
|
error_code=0 # Error flag indicates when an error has occurred
|
|
cmd=`basename $0` # Set the command name for error messages prior to
|
|
# checking for at least one argument
|
|
include_prereqs="yes" # Default includes all prerequisites
|
|
exclude_supersededs="no" # Default includes all supersededs
|
|
include_peresl_file="yes" # Default includes fixes from problem resolution file
|
|
# (This file is on production server: $PROD_DIRNAME)
|
|
duplicate_ptf="no" # duplicate PTF's are not allowed
|
|
toc_only="no" # generate toc and bff images
|
|
check_filesystem="no" # Not checking the filesystem size
|
|
ship_prod="no" # Set ship server only
|
|
apar_fix="no" # Read stack list file as PTFs, not APAR numbers
|
|
BLDTMP="/tmp" # Set temporary working directory
|
|
WORK=""
|
|
memo_file="yes" # Generate the memo_to_users file
|
|
current_mlevel="" # User can indicate current maintenance level to the
|
|
# minimize number of requisites included in output
|
|
map_table="" # Set ptfapardef map file to null
|
|
aix_version="32" # Default version is AIX v3
|
|
|
|
#
|
|
# check that 'media_list' program is in the path
|
|
#
|
|
type media_list | grep -s 'not found'
|
|
if [ $? -eq 0 ]; then
|
|
echo '$cmd: ERROR: "media_list" program not found in $PATH'
|
|
abort
|
|
fi
|
|
|
|
#################################################
|
|
# Check the command line for least one argument #
|
|
#################################################
|
|
if [ $# -lt 1 ]; then
|
|
error_code=1
|
|
clear # clear the screen before showing the syntax
|
|
syntax
|
|
fi
|
|
|
|
# Check the command line options
|
|
cmdline=$*
|
|
set -- `getopt "l:d:b:p:s:w:M:V:T:AtoexcBmNh?" $*`
|
|
if [ $? != 0 ]; then
|
|
error_code=2
|
|
clear # clear the screen before showing the syntax
|
|
syntax
|
|
fi
|
|
|
|
|
|
#####################
|
|
# Parse the options #
|
|
#####################
|
|
while [ $1 != "--" ]; do
|
|
case $1 in
|
|
"-l") # Stack list file
|
|
shift
|
|
# Dirname gives all except the last part of the path name
|
|
# that is all but the last /
|
|
# Set STACK_LIST to full path directory and filename using dirname cmd
|
|
stack_dir=`dirname $1`
|
|
if [ ! -d $stack_dir ]; then
|
|
echo "\n$cmd: ERROR: Cannot find stack file directory $stack_dir"
|
|
error_code=3
|
|
else
|
|
# Set the stack list name to the absolute path
|
|
cd $stack_dir
|
|
stack_dir=`pwd`
|
|
cd $START_DIR
|
|
stk_name=`basename $1`
|
|
STACK_LIST=$stack_dir/$stk_name
|
|
if [ ! -f $STACK_LIST ]; then
|
|
echo "\n$cmd: ERROR: Cannot find stack list $STACK_LIST"
|
|
error_code=4
|
|
else
|
|
if [ ! -r $STACK_LIST ]; then
|
|
echo "\n$cmd: ERROR: The stack list $STACK_LIST is not readable"
|
|
error_code=5
|
|
fi
|
|
fi
|
|
fi;;
|
|
|
|
"-d") # Target directory
|
|
shift
|
|
target_dir=$1
|
|
# Check target directory
|
|
if [ ! -d $target_dir ]; then
|
|
if [ -f $target_dir ]; then
|
|
echo "\n$cmd: ERROR: Target directory $target_dir is a file"
|
|
error_code=6
|
|
else
|
|
# Create and set target_dir to absolute path
|
|
mkdir $target_dir
|
|
chmod 777 $target_dir
|
|
cd $target_dir
|
|
target_dir=`pwd`
|
|
cd $START_DIR
|
|
echo "\n Creating target directory: $target_dir"
|
|
fi
|
|
else
|
|
if [ ! -w $target_dir ]; then
|
|
echo "\n$cmd: ERROR: Target directory $target_dir is not writeable"
|
|
error_code=7
|
|
else
|
|
# Set target_dir to absolute path
|
|
cd $target_dir
|
|
target_dir=`pwd`
|
|
cd $START_DIR
|
|
fi
|
|
fi;;
|
|
|
|
"-b") # Build directory
|
|
shift
|
|
build_dir=$1
|
|
# Check build directory
|
|
if [ ! -d $build_dir ]; then
|
|
echo "\n$cmd: ERROR: The build directory $build_dir is invalid"
|
|
error_code=8
|
|
else
|
|
if [ ! -r $build_dir ]; then
|
|
echo "\n$cmd: ERROR: The build directory $build_dir is not readable"
|
|
error_code=9
|
|
else
|
|
# Set build_dir to absolute path
|
|
cd $build_dir
|
|
build_dir=`pwd`
|
|
cd $START_DIR
|
|
fi
|
|
fi;;
|
|
|
|
"-p") # Prod directory
|
|
shift
|
|
ship_prod="yes"
|
|
prod_dir=$1;;
|
|
|
|
|
|
"-s") # Ship directory
|
|
shift
|
|
ship_dir=$1;;
|
|
|
|
"-w")
|
|
shift # Temporary working directory
|
|
BLDTMP=$1
|
|
if [ ! -d $BLDTMP ]; then
|
|
echo "\n$cmd: ERROR: The temporary directory $BLDTMP is invalid"
|
|
error_code=10
|
|
else
|
|
if [ ! -r $BLDTMP ]; then
|
|
echo "\n$cmd: ERROR: The temp directory $BLDTMP is not readable"
|
|
error_code=11
|
|
else
|
|
if [ ! -w $BLDTMP ]; then
|
|
echo "\n$cmd: ERROR: The temp directory $BLDTMP is not writable"
|
|
error_code=12
|
|
else
|
|
if [ ! -x $BLDTMP ]; then
|
|
echo "\n$cmd: ERROR: The temp directory $BLDTMP is not executable"
|
|
error_code=13
|
|
else
|
|
# Set BLDTMP to absolute path
|
|
cd $BLDTMP
|
|
BLDTMP=`pwd`
|
|
cd $START_DIR
|
|
fi
|
|
fi
|
|
fi
|
|
fi;;
|
|
|
|
"-M") # Set current maint_level
|
|
shift
|
|
current_mlevel=$1;;
|
|
|
|
"-V") # Get AIX release
|
|
shift
|
|
echo $1 | grep "^4" >/dev/null
|
|
if [ $? -eq 0 ]; then
|
|
aix_version="41"
|
|
fi;;
|
|
|
|
"-T") # PTF-to-vrmf mapping table
|
|
shift
|
|
map_table=$1
|
|
if [ ! -r $map_table ]; then
|
|
echo "\n$cmd: ERROR: The ptfapardef file $map_table is not readable"
|
|
error_code=30
|
|
fi;;
|
|
|
|
"-A") # Read stack list as APARs
|
|
apar_fix="yes";;
|
|
|
|
"-e") # Exclude prerequisites
|
|
include_prereqs="no";;
|
|
|
|
"-t")
|
|
duplicate_ptf="yes";; # Duplicate PTF's are allowed
|
|
# on BUILD and (PROD or SHIP)
|
|
|
|
"-o")
|
|
toc_only="yes";; # Generate toc file only
|
|
|
|
"-x")
|
|
exclude_supersededs="yes";; # Exclude supersededs
|
|
|
|
"-N")
|
|
include_peresl_file="no";; # Exclude fixes from peresl file
|
|
|
|
"-c")
|
|
check_filesystem="yes";; # Check the filesystem size
|
|
|
|
"-B")
|
|
ship_prod="yes";; # Set ship directory and
|
|
# product directory
|
|
|
|
"-m")
|
|
memo_file="no";; # Not generate memo_to_user
|
|
# file
|
|
|
|
"-h") # Help
|
|
clear
|
|
syntax;;
|
|
esac
|
|
shift
|
|
done
|
|
shift
|
|
|
|
#-------------------------------------------------------------------
|
|
# AIX bldenv uses <32 or 41>_pkg_environment to set up |
|
|
# SHIP_DIRNAME & PROD_DIRNAME; but OEM customers might not use it. |
|
|
#-------------------------------------------------------------------
|
|
type "$aix_version"_pkg_environment >/dev/null 2>&1
|
|
[ $? -eq 0 ] && . "$aix_version"_pkg_environment
|
|
|
|
#------------------------------------------------------------------------
|
|
# If ship_dir and prod_dir were not specified on the command line, |
|
|
# default to values set by <$aix_version>_pkg_environment. |
|
|
#------------------------------------------------------------------------
|
|
if [ "x$ship_dir" = "x" ]; then
|
|
ship_dir="$SHIP_DIRNAME"
|
|
fi
|
|
if [ "x$prod_dir" = "x" ]; then
|
|
prod_dir="$PROD_DIRNAME"
|
|
fi
|
|
|
|
data_dir="`dirname $prod_dir`/data"
|
|
mlevel_file="$data_dir/ML.list" # List of maintenance levels
|
|
|
|
prod_maptable="$prod_dir/ptfapardef.constant"
|
|
|
|
#
|
|
# check that 'genabst' program is in the path
|
|
#
|
|
if [ "$memo_file" = "yes" ]; then
|
|
type genabst | grep -s 'not found'
|
|
if [ $? -eq 0 ]; then
|
|
echo '$cmd: ERROR: "genabst" program not found in $PATH'
|
|
abort
|
|
fi
|
|
fi
|
|
|
|
#------------------------------------------------------------------------
|
|
# If ship_prod=no set prod_dir to null because we don't want media_list |
|
|
# to get a value from the environment. |
|
|
#------------------------------------------------------------------------
|
|
[ "$ship_prod" = "no" ] && prod_dir=""
|
|
|
|
##########################################
|
|
# Verify and standardize input variables #
|
|
##########################################
|
|
# Look for garbage left over on the command line
|
|
if [ $# -gt 0 ]; then
|
|
echo "\n$cmd: ERROR: Additional parameters on command line: $*"
|
|
error_code=14
|
|
fi
|
|
|
|
# check integrity of cmdline parms
|
|
check_cmdline_parms
|
|
|
|
######################
|
|
# Check for an error #
|
|
######################
|
|
if [ $error_code != 0 ]; then
|
|
syntax
|
|
fi
|
|
|
|
############################################
|
|
# Allocate temporary files and directories #
|
|
############################################
|
|
# export BLDTMP variable for subprocesses.
|
|
export BLDTMP
|
|
|
|
# Use a directory name variable for the /tmp work directory
|
|
WORK=$BLDTMP/genfsimage_work.$$
|
|
rm -f $WORK > /dev/null 2>&1
|
|
if [ -d $WORK ]; then
|
|
echo "\n$cmd: ERROR: The work directory $WORK could not be removed"
|
|
abort
|
|
fi
|
|
|
|
# Create the work directory
|
|
mkdir $WORK >/dev/null 2>&1
|
|
|
|
# chmod added to make sure that the directory can be overwritten in the future
|
|
chmod 777 $WORK
|
|
|
|
# Allocate temporary working variables
|
|
toc_name=$WORK/.toc
|
|
WORK_STACK_LIST="$WORK/stack_list"
|
|
ORD_STACK_LIST="$WORK/ordered_stack_list"
|
|
|
|
###############################################################
|
|
# Create ordered list of PTF files and all associated prereqs #
|
|
###############################################################
|
|
if [ $include_prereqs != "yes" ]; then
|
|
# Resolve the location of the ptfs specified without changing
|
|
# the order
|
|
resolv_ptf_paths_excluding_prereqs
|
|
else
|
|
# Resolve the location of the ptfs specified, include prereqs/etc.,
|
|
# and order them so a tape would stream.
|
|
resolv_ptf_paths_including_prereqs
|
|
fi
|
|
|
|
#########################################################################
|
|
# Check file system space #
|
|
#########################################################################
|
|
if [ "$check_filesystem" = "yes" ]; then
|
|
total=0
|
|
cat $ORD_STACK_LIST |
|
|
while read ptf
|
|
do
|
|
size=`ls -l $ptf | awk '{print $5}'`
|
|
total=`expr $total + $size`
|
|
done
|
|
|
|
os_version=`uname -v`
|
|
if [ "$os_version" = "4" ]; then
|
|
df -k > $WORK/outfile
|
|
else
|
|
df > $WORK/outfile
|
|
fi
|
|
cat $WORK/outfile | awk ' NR > 1 {print $3 " " $7}' > $WORK/outfile1
|
|
pdir=$target_dir
|
|
found=0
|
|
while [ $found = 0 ]
|
|
do
|
|
grep "$pdir$" $WORK/outfile1 > $WORK/outfile2
|
|
if [ $? = 0 ]; then
|
|
found=1
|
|
fssize=`cat $WORK/outfile2 | awk '{print $1}'`
|
|
else
|
|
pdir=`dirname $pdir`
|
|
fi
|
|
done
|
|
|
|
let "fssize = fssize * 1000"
|
|
if [ $fssize -lt $total ]; then
|
|
echo "\nThe size of file system is $fssize bytes"
|
|
echo "The total sizes you require to put images are $total bytes"
|
|
echo "INCREASE THE FILE SYSTEM and RUN genfsimage again !\n"
|
|
rm -rf $WORK
|
|
exit 99
|
|
fi
|
|
fi
|
|
|
|
#########################################################################
|
|
# Build the table of contents and unpack the files onto the file system #
|
|
#########################################################################
|
|
# Inform the user of the run parameters
|
|
echo "\n AIX VERSION: ............ $aix_version"
|
|
echo " TARGET DIRECTORY: ....... $target_dir"
|
|
echo " BUILD DIRECTORY: ........ $build_dir"
|
|
echo " PRODUCTION DIRECTORY: ... $prod_dir"
|
|
echo " SHIP DIRECTORY: ......... $ship_dir"
|
|
echo " STACK LIST FILE: ........ $STACK_LIST"
|
|
echo " INCLUDE PREREQUISITES: .. $include_prereqs"
|
|
echo " EXCLUDE SUPERSEDEDS: .... $exclude_supersededs"
|
|
|
|
echo "\nBuild a Table of Contents file and copy the ptf:"
|
|
|
|
##########################################################################
|
|
# Format of the toc specifies that first line should contain volume # in #
|
|
# first character, the date created and a # for version of toc header. #
|
|
# toc for all volumes is same but for 1st line. #
|
|
##########################################################################
|
|
# Put the header information into the new toc
|
|
echo "$volume $CONST_DATE $toc_format" > $toc_name
|
|
if [ $? != 0 ]; then
|
|
echo "\n$cmd: ERROR: Table of contents file $toc_name could not be created"
|
|
abort
|
|
fi
|
|
|
|
if [ "$memo_file" = "yes" -a "$toc_only" = "no" ]; then
|
|
# Create memo_to_user file under $target directory
|
|
> $target_dir/memo_to_user
|
|
fi
|
|
|
|
#
|
|
# For each PTF file from the ordered stacklist:
|
|
# - Copy the ptf to the target directory
|
|
# - append the new ptf information to the table of contents.
|
|
#
|
|
for PTF_file in `cat $ORD_STACK_LIST` ; do
|
|
|
|
# echo the full pathname of the file we are working on
|
|
echo " $PTF_file"
|
|
PTF_dir=`dirname $PTF_file`
|
|
if [ "$PTF_dir" != "$ship_dir" ]; then
|
|
echo "`basename $PTF_file` is in $PTF_dir" >> $WORK/notship
|
|
fi
|
|
|
|
# extract the ptf# from the filename
|
|
PTF_number=`basename $PTF_file | sed -e "s/.ptf$//"`
|
|
|
|
#
|
|
# Unpack each PTF file to the target file system
|
|
#
|
|
case "$PTF_file" in
|
|
*.ptf)
|
|
if [ "$toc_only" = "yes" ]; then
|
|
# unpack CCSS format files to get toc_entry
|
|
ccss_unpack -c $PTF_file -t $WORK/lpp_name
|
|
if [ $? != 0 ]; then
|
|
echo "\n$cmd: ERROR: Problem unpacking $PTF_file with ccss_unpack"
|
|
echo "$cmd: Ref. ccss_unpack -c $PTF_file -t $WORK/lpp_name"
|
|
abort
|
|
fi
|
|
else
|
|
# Unpack CCSS format files to get the bff file and toc_entry
|
|
if [ "$memo_file" = "yes" ]; then
|
|
ccss_unpack -c $PTF_file -p $target_dir/$PTF_number.bff -t $WORK/lpp_name -i $WORK/info -a
|
|
rc=$?
|
|
else
|
|
ccss_unpack -c $PTF_file -p $target_dir/$PTF_number.bff -t $WORK/lpp_name -i $WORK/info
|
|
rc=$?
|
|
fi
|
|
if [ $rc != 0 ]; then
|
|
echo "\n$cmd: ERROR: Problem unpacking $PTF_file with ccss_unpack"
|
|
echo "$cmd: Ref. ccss_unpack -c $PTF_file -p $target_dir/$PTF_number.bff"
|
|
echo "$cmd: -t $WORK/lpp_name"
|
|
if [ "$memo_file" = "yes" ]; then
|
|
echo "$cmd: -i $WORK/info -a"
|
|
fi
|
|
abort
|
|
fi
|
|
|
|
# patch for ccss_permissions bug affecting bai
|
|
chmod 644 $target_dir/$PTF_number.bff
|
|
|
|
if [ "$memo_file" = "yes" ]; then
|
|
getmemo
|
|
rm -f $WORK/info $WORK/info.head
|
|
fi
|
|
fi
|
|
;;
|
|
|
|
*)
|
|
# exit with error for any suffixs that we don't recognize
|
|
echo "\n$cmd: ERROR: Unrecognized file suffix for $PTF_file"
|
|
echo "\n$cmd: Currently only support .ptf"
|
|
abort
|
|
;;
|
|
esac
|
|
|
|
#
|
|
# Get the ./lpp_name file from the bff
|
|
#
|
|
cd $WORK
|
|
|
|
#
|
|
# Rename the bff to the verbose ptf name that bai likes
|
|
#
|
|
# Toc field number 1 (2nd line) is the fileset name
|
|
# (just use root name with no extensions for lpp_name)
|
|
fileset=`awk 'NR==2 { print $1 }' $WORK/lpp_name`
|
|
lpp_name=`echo $fileset | sed 's/\..*//'`
|
|
# Toc field number 2 (2nd line) is the vrlm
|
|
vrlm=`awk 'NR==2 { print $2 }' $WORK/lpp_name`
|
|
# Toc field number 5 (2nd line) is the content
|
|
content=`awk 'NR==2 { print $5 }' $WORK/lpp_name`
|
|
# Append them together to get a unique name
|
|
if [ "$aix_version" = "32" ]; then
|
|
verbose_name="${lpp_name}.${content}.${vrlm}"
|
|
else
|
|
verbose_name="${fileset}.${vrlm}"
|
|
fi
|
|
# Now actually rename the bff on the target machine
|
|
if [ "$toc_only" = "no" ]; then
|
|
mv ${target_dir}/${PTF_number}.bff ${target_dir}/${verbose_name}.bff
|
|
if [ $? != 0 ]; then
|
|
echo "genfsimage: ERROR: Rename ${target_dir}/${PTF_number}.bff file failed"
|
|
abort
|
|
fi
|
|
fi
|
|
|
|
#
|
|
# Add new entry to the toc
|
|
#
|
|
# Insert filename information.
|
|
echo "${verbose_name}.bff \c" >> $toc_name
|
|
# Append the contents of the current lpp_name file to the toc
|
|
cat ${WORK}/lpp_name >> $toc_name
|
|
|
|
done
|
|
|
|
# Check return code from while loop (when while loop was invoked, a
|
|
# new shell program was started)
|
|
if [ $? != 0 ]; then
|
|
quiet_abort
|
|
fi
|
|
|
|
mv $toc_name $target_dir
|
|
if [ $? != 0 ]; then
|
|
echo "\n$cmd: ERROR: Problem writing table of contents to file system"
|
|
abort
|
|
fi
|
|
|
|
if [ -s $WORK/notship ]; then
|
|
echo "\nFollowing PTF files are not from SHIP SERVER: "
|
|
cat $WORK/notship
|
|
fi
|
|
|
|
#
|
|
# check if memo_to_user contains the data
|
|
#
|
|
if [ "$memo_file" = "yes" -a "$toc_only" = "no" -a -s "$WORK"/classPTF ]; then
|
|
sort -r -n $WORK/classPTF > $WORK/classPTF.temp
|
|
mv $WORK/classPTF.temp $WORK/classPTF
|
|
cat $WORK/classPTF |
|
|
while read value ptf
|
|
do
|
|
genabst "*** PTF: $ptf ***" "ENDSET" $WORK/allMEMO $target_dir/memo_to_user
|
|
rc=$?
|
|
if [ $rc -eq 0 ]; then
|
|
echo " " >> $target_dir/memo_to_user
|
|
else
|
|
if [ $rc -eq 2 ]; then
|
|
echo "$cmd: ERROR: For PTF $ptf, there is no \"MEMO TO USERS\""
|
|
echo " information in the info file.\n"
|
|
echo " CONTINUE TO PROCESS NEXT PTF!"
|
|
else
|
|
if [ $rc -eq 3 ]; then
|
|
echo "$cmd: ERROR: For PTF $ptf, there is no separator\"ENDSET\""
|
|
echo " in the info file.\n"
|
|
echo " CONTINUE TO PROCESS NEXT PTF!"
|
|
else
|
|
if [ $rc -eq 4 ]; then
|
|
abort
|
|
else
|
|
echo "$cmd: Error occurred in genabst, Please check for above information!"
|
|
echo " CONTINUE TO PROCESS NEXT PTF!"
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
if [ ! -s $target_dir/memo_to_user ]; then
|
|
rm -f $target_dir/memo_to_user
|
|
else
|
|
echo "\nPlease read the memo_to_user file under $target_dir directory."
|
|
echo "This file contains the PTF memo information for you.\n"
|
|
fi
|
|
fi
|
|
|
|
# Tell the user that genfsimage was successful
|
|
echo "\ngenfsimage was SUCCESSFUL!\n"
|
|
|
|
cd $START_DIR
|
|
# Graceful exit
|
|
rm -rf $WORK
|
|
sync
|
|
exit 0
|
|
|
|
|