Listing 1 Makeinstall
#!/usr/dt/bin/dtksh
# Type "makeinstall help=y" for online man page.
function my_getopts {
#- version 3.141592, 2002-02-02, Michael Wang <xw73@columbia.edu>.
typeset PATH= SEP= i
typeset -u _I
for i; do
_I=$i
eval ${_I%%?(:)=*}= unset ${_I%%?(:)=*}
case $_I in
*[!:]=*) eval $(IFS=$SEP; print ${_I%%=*}=\"${_I#*=}\") ;;
*:=*) eval $(IFS=$SEP; print ${_I%%:=*}=\"${i#*:=}\") ;;
esac
done
}
function kshdoc {
# version 2.0, 2003-05-08, Michael Wang <xw73@columbia.edu>.
typeset path file base tdir;
typeset -u help
eval help=y "$@"
typeset -x PATH=${path:-$PATH}
whence perldoc >/dev/null || {
[[ -x /usr/perl5/bin/perldoc ]] && PATH=$PATH:/usr/perl5/bin
whence perldoc >/dev/null || {
print "You need to have perldoc in your PATH."
return 1
}
}
[[ $help = @(Y|PS|PDF) ]] && {
base=${file##*/}; base=${base%.@(ksh|sh|ss)}
tdir=/tmp/$base.$$.$RANDOM
mkdir $tdir && trap "rm -rf $tdir" EXIT
sed -n '/^## =/,${/^##/s/^## \{0,1\}//p;}' $file > $tdir/$base.pod
case $help in
Y) if (( $(id -u) == 0 )); then
su bin -c "perldoc $tdir/$base.pod"
else
perldoc $tdir/$base.pod
fi;;
PS) pod2man $tdir/$base.pod | groff -man > $base.ps;;
PDF) pod2man $tdir/$base.pod | groff -man | ps2pdf - $base.pdf;;
esac
}
return 0
}
[[ $1 == help=y ]] && { kshdoc file=$0 help=y; exit 0; }
function do_snapshot {
typeset fs=${1} sr=${2} bs=${3} mp dv ix
for ix in ${fs//:/ }; do
mp=${sr}${ix/%"/"/"/root"}
mkdir -p $mp
mount -F ufs -o ro $(fssnap -F ufs -o bs=${bs},unlink $ix) $mp
fssnap -i -o blockdevname $ix | awk "{print \$NF}" | read dv &&
df -Pk $mp | grep "^$dv" || return 1
done
}
# Reason for awk "{print \$NF}":
# fssnap -i -o blockdevname /fs
# Solaris 8: /dev/fssnap/0
# Solaris 9: Block Device : /dev/fssnap/0
function undo_snapshot {
typeset fs=${1} sr=${2} mp ix
for ix in ${fs//:/ }; do
mp=${sr}${ix/%"/"/"/root"}
umount $mp
fssnap -F ufs -d $ix
! fssnap -i -o blockdevname $ix | awk "{print \$NF}" | read &&
! df -Pk $mp | grep "^/dev/fssnap/[0-9]\{1,\}" || return 1
done
}
function find_diff {
typeset fs=${1} sr=${2} md=${3} mp ix iy
typeset -u an
for ix in ${fs//:/ }; do
mp=${sr}${ix/%"/"/"/root"}
print ${ix}:
if [[ $md == new2old ]]; then
rsync -vanx --delete ${ix}/ ${mp}/
else
rsync -vanx --delete ${mp}/ ${ix}/
print -n "commit? "
read an
[[ $an == Y* ]] && rsync -vax --delete ${mp}/ ${ix}/
fi
done
}
function find_fs {
typeset fs=$1
[[ -n "$fs" && $fs != [+-]* ]] && print $fs && return 0
typeset i j k
df -Pk -F ufs | while read i; do
set -- $i
j=${@:$#:1}
[[ $j == @(/|/usr|/var|/opt) ]] && {
[[ $fs == -?(*:)${j}?(:*) ]] || k="$k:$j"
}
done
if [[ $fs == +* ]]
then print ${k}:${fs#+}
else print ${k}
fi
}
set -e
PATH=$(/bin/getconf PATH)
PATH=$PATH:/usr/sbin
PATH=$PATH:/opt/csw/bin
my_getopts HELP=N "$@"
: ${SNAPROOT:=/snapshot}
: ${STEP:=0}
: ${BS:=$(< $SNAPROOT/.backing-store)}
# fs:=
FS=$(find_fs $FS)
[[ $STEP == *1* || $STEP == 9 ]] && do_snapshot $FS $SNAPROOT $BS
[[ $STEP == *2* || $STEP == 9 ]] && {
print "type make install or whatever in another window."
print -n "ready? "
read
}
[[ $STEP == *3* || $STEP == 9 ]] && find_diff $FS $SNAPROOT "new2old"
[[ $STEP == *4* || $STEP == 9 ]] && find_diff $FS $SNAPROOT "old2new"
[[ $STEP == *5* || $STEP == 9 ]] && {
if [[ $STEP == 5 ]]
then an=Y
else print -n "delete snapshots? "
read an
fi
[[ $an == [Yy]* ]] && undo_snapshot $FS $SNAPROOT
}
exit 0
## =head1 NAME
##
## B<makeinstall> - capture file system changes with snapshot and rsync
##
## =head1 SYNOPSIS
##
## ... |