#!/bin/bash
# Copyright (C) 2004 Networks Associates Technology Inc. All rights reserved.

shopt -s extglob	# extended globs rule
shopt -s dotglob	# no hiding place
shopt -s nullglob	# no match no token
umask 022		# reasonable umask

# cd to the directory where this script lives
me=${0##*/}
mydir=${0%$me}
[[ -n $mydir ]] && cd "$mydir" || exit

# hotfix name should be the name of this directory
hf=${PWD##*/}

. /var/NAIENV/.profile.vars
PATH=$wsPATH:$PATH
export LC_ALL=C

# constants
hf_logs=/logs/hotfixes
hf_dir=$NETAWSS/hotfixes
hf_about=$hf_dir/about

# output to log file
mkdir -p $hf_logs
exec >>$hf_logs/hotfixlog 2>&1 </dev/null
echo -e "\n------- Start $(date)"

# function for progress output
ReportMessage() { :; }	# no-op by default, but source from file if possible...
if [[ -f message_functions.bash ]] && . message_functions.bash; then :
else
    [[ -f $WS_MGMT/message_functions.bash ]] &&
	. $WS_MGMT/message_functions.bash
fi

###############################################################################
# Check for prerequisites
###############################################################################
missing=''
[[ -s prerequisites ]] && for f in $(<prerequisites); do
    x=( $hf_about/$f-+([^.-]).+([^.-]) )
    [[ ${#x[@]} -gt 0 ]] || missing="$missing $f"
done
if [[ -n $missing ]]; then
    echo $'\n---------------------------------------------------------'
    echo "Hotfix $hf $(date) missing prerequisites$missing"
    ReportMessage MSG_prerequisite "${missing# }"
    sleep 10
    exit 1
fi

###############################################################################
# Start for real
###############################################################################

echo $'\n---------------------------------------------------------'
echo "Installing Hotfix $hf $(date)"
ReportMessage MSG_install_hotfix "$hf"

# self check
if (
	cd .. && [[ -d validate ]] || exit 0
	echo "Self-check hotfix content"
	if [[ -f validate/filelist.txt ]]; then
	    m=$(find * -type f -print | sort | comm -3 validate/filelist.txt -)
	    [[ -n $m ]] && echo -e "File list mismatch:\n$m" && exit 1
	fi
	if [[ -f validate/md5sum.txt ]]; then
	    md5sum -c validate/md5sum.txt || exit 1
	fi
    ); then :
else
    echo "Self-check FAILED!"
    ReportMessage MSG_hotfix_failed "$hf"
    sleep 5
    exit 1
fi

# kernel install
endwith_reboot=''
install_kernel()
{
    local kver=$(<kernel/version)
    [[ -n $kver ]] || { echo no kernel version; return 1; }
    if (cd / && md5sum -c --status 2>/dev/null) < kernel/kernel.md5; then
	echo kernel already up to date
	return 0
    fi
    ReportMessage MSG_install_package "kernel $kver"
    echo "Installing kernel $kver"
    tar -zxf kernel/kernel.tgz -C / &&
	(cd / && md5sum -c --status) < kernel/kernel.md5 ||
	{ echo Failed unpacking new kernel; return 1; }
    /sbin/depmod -a -b /lib/$kver > /dev/null 2>&1
    /sbin/depmod -a > /dev/null 2>&1
    /sbin/mkinitrd /boot/initrd-$kver.img $kver &&
	cp kernel/grub.conf /boot/grub/. ||
	{ echo failed setting up boot for kernel $kver; return 1; }
    endwith_reboot=yes
    echo "s.product.kernel $kver" >>/.build
}
if [[ -d ./kernel ]]; then
    mount -o remount,rw /boot
    install_kernel || ReportMessage MSG_install_failed "kernel $kver"
    mount -o remount,ro /boot
fi

# stop necessary services
[[ -s services_stop ]] && for f in $(<services_stop); do
    [[ -f /etc/init.d/$f ]] && /etc/init.d/$f stop
done

# construct save rpms
rpmdir=/tmp/rpms.$hf.$$
for f in ./rpmspecs/*.spec; do
    mkdir -p $rpmdir &&
    rpmbuild -bb \
	--define "_initrddir /etc/rc.d/init.d/" \
	--define "_sourcedir $rpmdir" \
	--define "_builddir $rpmdir" \
	--define "_rpmdir $rpmdir" \
	--define "_srcrpmdir $rpmdir" \
	--define "__check_files %{nil}" \
	--define "serial $(date -u '+%s')" \
	--define "_rpmfilename %{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}.rpm" \
	$f
done

# save precious files (will be restored by copy in below)
[[ -s savefiles ]] && echo "Saving precious files" && mkdir -p root &&
    cpio -pdmv root <savefiles

# install RPMs - prefer this to "install" in the hf script as this gets logged
for f in ./rpms/*.rpm; do
    ReportMessage MSG_install_package "${f##*/}"
    rpm -Uv --nodeps $f &&
	rpm >>/.build -qp --queryformat \
	    's.product.component.%{NAME} %{VERSION}-%{RELEASE}\n' $f ||
	ReportMessage MSG_install_failed "${f##*/}"
done

# install save RPMs
for f in $rpmdir/*.rpm; do
    ReportMessage MSG_install_package "${f##*/}"
    rpm -Uv --nodeps $f &&
	rpm >>/.build -qp --queryformat \
	    's.product.component.%{NAME} %{VERSION}-%{RELEASE}\n' $f ||
	ReportMessage MSG_install_failed "${f##*/}"
done
rm -rf $rpmdir

# delete potentially munged precious files (saved above, will be restored below)
[[ -s savefiles ]] && echo "Resetting precious files" &&
    xargs -r rm -rvf <savefiles

# copy in files
[[ -d ./root ]] && (
	cd ./root && find . -mindepth 1 -print | while read f; do
	    [[ -d $f ]] && mkdir -p "/$f" && continue
	    ReportMessage MSG_install_file "${f##*/}"
	    cp -av "$f" "/${f%/*}" ||
		ReportMessage MSG_install_failed "${f##*/}"
	done
    )

# webshield-ui pre-uninstall script may have turned off httpd service
echo "Forcing service httpd on"
chkconfig --level 3 httpd on
# webshield-files pre-uninstall script may have removed necessary links
echo "Correcting script links"
ln -sfv /opt/NETAwss/mgmt/ifup-pre-local /sbin/
ln -sfv /opt/NETAwss/mgmt/ifdown-local /sbin/
ln -sfv /opt/NETAwss/mgmt/ws_rmail /usr/bin/rmail
# early version of first hotfix munged these settings
(cd /config/wsxmlconf/spamconfig/ || exit
    [[ -f wsui_spam_activation ]] && rm -f wsui_spam_can_evaluate
    if [[ -f antispam-eval.log && ! -f wsui_spam_activation ]]; then
	# evaluation appears to have been cut short - start a new one
	rm -f antispam-eval.log wsui_spam_evaluation
	touch wsui_spam_can_evaluate
	/opt/NETAwss/mgmt/spamkiller_eval_monitor.py start
    fi
)

# append any new build info
[[ -s add_info ]] && fgrep -xv -f /.build add_info >>/.build

# update about box
echo "Updating about box"
mkdir -p $hf_about && :> $hf_about/$hf
$WSMGMT/abouthotfixes

# all done
echo -e "\nCompleted Hotfix $hf $(date)"

# reboot if we need to...
if [[ -n $endwith_reboot ]]; then
    ReportMessage MSG_reboot 15
    ( cd /; sleep 15; /sbin/reboot) &
    sleep 5
    exit
fi
# ... otherwise ...

# start stopped services
[[ -s services_stop ]] && for f in $(<services_stop); do
    [[ -f /etc/init.d/$f ]] && /etc/init.d/$f start
done

# report completion and exit
if [[ -e reboot_ui && $(<reboot_ui) != *nohttpd* ]]; then
    # have to restart apache, so bg it with a sleep and exit before it happens
    ReportMessage MSG_ui_restart 15
    exec 3>&-
    ( cd /; sleep 15; until /etc/init.d/httpd restart; do sleep 5; done ) &
else
    ReportMessage MSG_hotfix_success "$hf"
fi
sleep 5
exit
