#!/bin/bash
# this script changes a kernel in woof-ce based puppy linux
# 4th revision. GPL v2,(c)Michael Amadio, 01micko@gmail.com, 2020
set -e
# error codes
# 65 - no /etc/DISTRO_SPECS file
# 66 - no /etc/rc.d/PUPSTATE file
# 7 - booted off optical media
# 255 - no 'Huge Kernel' or pup is too old
# 1 - error from external program
# 2 - full install to fast media
# 3 - full install to slow media
# 77 - save back to optical media install
# 21 - no valid kernel image (vmlinuz)
# 22 - no valid kernel modules sfs (zdrv_xxx_xxx.sfs)
# 100 - backup on same date found - technically not an error
# 23 - failed to backup vmlinuz
# 24 - failed to backup zdrv_xxx_xxx.sfs or fdrv
# 25 - failed to copy new vmlinuz
# 26 - failed to copy new zdrv_xxx_xxx.sfs or fdrv
# 123 - failed to restore vmlinuz backup
# 124 - failed to restore zdr_xxx_xx.sfs backup
# 69 - unknown
export TEXTDOMAIN=change_kernels
export OUTPUT_CHARSET=UTF-8
# current running kernel - throw away appendages
CURK=`uname -r`
CURK=${CURK%%-*}
uname -m | grep -qE 'arm|aarch' && exit 0 # doesn't work with arm
# Translations
# buttons
OKE=$(gettext "OK")
CAN=$(gettext "Cancel")
YEP=$(gettext "Yes")
NOPE=$(gettext "No")
HELP=$(gettext "Help")
ROLLBTN=$(gettext "Rollback")
KDATE=$(gettext "kernel from date")
BUTTONY=""
BUTTONN=""
BUTTONO=""
BUTTONC=""
# dialogs
OR=$(gettext "OR")
MSG1=$(gettext "Please choose an option below. Either download a kernel from the repository or find a kernel you already have and enter it in the entry on the first page or enter a vmlinuz and zdrv_XXX_XXX.sfs into the first and second entries on the second page (mandatory) and an fdrv_XXXXX.sfs into the third entry (optional). You can drag and drop files to the entry boxes. WARNING: Please read the help.")
BMSG=$(gettext "Your puppy is too old or broken")
CMSG=$(gettext "Unfortunately this doesn't work in CD/DVD installs")
FMSG=$(gettext "Unfortunately this doesn't work in full installs")
LMSG=$(gettext "Unfortunately this doesn't work with live CD installs")
OMSG=$(gettext "Unfortunately this doesn't work with older puppy installs")
KMSG=$(gettext "Not a valid kernel file")
MMSG=$(gettext "Not a valid module file")
FMMSG=$(gettext "Failed to move")
CERR=$(gettext "Something went wrong. Are the entries filled correctly?")
KTARBALL=$(gettext "Kernel Tarball")
DKERNELS=$(gettext "Download Kernels")
IF_DOWNLOAD=$(gettext "If you download or build a kernel you can enter it in the box below.")
KFILES=$(gettext "Kernel Files")
CHOOSE_LOC=$(gettext "Choose the location of kernel tarball named")
CHOOSE_LOC1=$(gettext "Choose the location of kernel file named")
CHOOSE_LOC2=$(gettext "or similar")
FIND_MOD=$(gettext "Find the module file named")
FIND_FIRM=$(gettext "Firmware for the kernel modules may be needed. This is optional. Find the firmware file named")
FND_KRN=$(gettext "We have found that your kernel is located at:")
VMSG=$(gettext "Failed to copy vmlinuz: restoring original")
FSMSG1=$(gettext "Failed to copy")
FSMSG2=$(gettext "restoring original")
RMSG=$(gettext "Now reboot to test your new kernel.")
ERR=$(gettext "Error")
SUCC=$(gettext "Success")
MSG=$(gettext "message")
CTITLE=$(gettext "Confirmation")
CONFMSG1=$(gettext "You have chosen the following kernel files to install")
CONFMSG2=$(gettext "Are you sure?")
KERNMSG=$(gettext "or 'kernel-modules.sfs-XXXXX' if built with kernel-kit. You can try other kernels built in other Puppies")
TT=$(gettext "Drag and drop is supported from Rox Filer")
ROLLTT=$(gettext "Roll back to a previous kernel.")
ROLL1=$(gettext "Choose an earlier kernel to roll back to...")
KRRERR=$(gettext "There are no kernels to roll back to.")
EXISTS=$(gettext "Overwrite")
OVERMSG=$(gettext "backup from today with kernel version")
OVERMSG1=$(gettext "already exists. Press 'Yes' to overwrite, 'No' to continue without overwriting or 'Cancel' to exit")
INF=$(gettext "Info")
FMNT=$(gettext "Failed to mount")
WAIT1=$(gettext "Please wait while the kernel package is extracted ...")
WAIT2=$(gettext "Please wait while the kernel files are rearranged ...")
# help
HHELP=HELP
HWARN=$(gettext "WARNING!")
HSYS=$(gettext "You may render your system unbootable!")
HTAR=$(gettext "Find a kernel tarball for the first page.")
HTARBALL=$(gettext 'It will be named something like huge-4.1.14-XXX.tar.bz2')
HOR=$(gettext "OR")
HVMLINUZ=$(gettext "Find a vmlinuz file for the second page.")
HMODULES1=$(gettext "Find a zdrive file (which may have an obscure name like")
HMODULES2=$(gettext "'kernel-modules.sfs-XXXXX'if it was built it in kernel-kit)")
HMODULES3=$(gettext "for the second entry box on the second page.")
HFIRM1=$(gettext "Optionally you can find a firmwware file named something like ")
HFIRM2=$(gettext "'fdrv_XXXXX.sfs' for the third entry box.")
HMATCH=$(gettext "These files MUST match!")
HROX=$(gettext "If you use Rox Filer you can drag and drop to the entry boxes.")
HOK=$(gettext "Hit OK.")
HID2=$(gettext "Hopefully you can reboot.")
HFAIL=$(gettext "IF IT FAILS")
HBACK1=$(gettext "There are backups of the old vmlinuz and zdrive in place appended")
HBACK2=$(gettext "with the today's date. Hit the Rollback button to restore a backup.")
HGOOD=$(gettext "GOOD LUCK")
HBUG=$(gettext "Bugs to 01micko @ github")
HGPL=GPL2
HCARE=$(gettext "While all care is taken, no responsibility accepted.")
export HHELP HWARN HSYS HTAR HTARBALL HOR HVMLINUZ HMODULES1 HMODULES2 HMODULES3 HFIRM1 HFIRM2 HMATCH HROX HOK HID2 HFAIL HBACK1 HBACK2 HGOOD HBUG HGPL HCARE
EXITVAL=""
# generic message tool
_msg() {
if [ "$4" = "cancel" ];then
CANCEL="$BUTTONC"
BUTTONZO="${BUTTONY}${BUTTONN}"
elif [ "$4" = "not" ];then
CANCEL=''
unset BUTTONZO
fi
export SPLMSG="${CANCEL}${BUTTONO}${BUTTONZO}"
eval $(gtkdialog -p SPLMSG -c)
[ "$3" != "100" ] && exit $3 || EXITVAL=$EXIT
}
[ -f /etc/DISTRO_SPECS ] && . /etc/DISTRO_SPECS || _msg $ERR "$BMSG" 65
[ -f /etc/rc.d/PUPSTATE ] && . /etc/rc.d/PUPSTATE || _msg $ERR "$BMSG" 66
# test we can do this
case $PUPMODE in
2|3)_msg $ERR "$FMSG" $PUPMODE;;
77)_msg $ERR "$CMSG" $PUPMODE;;
esac
[ "$PMEDIA" = "cd" ] && _msg $ERR "$LMSG" 7
[ "$DISTRO_KERNEL_PET" = "Huge_Kernel" ] || _msg $ERR "$OMSG" 255
# find where kernel and modules live
MODULES_HOME=/initrd${PUP_HOME}${PSUBDIR}
VHOME=$PDEV1
MHOME=${PUPSFS%%,*}
if [ "$VHOME" = "$MHOME" ];then
KERNEL_HOME=/initrd${PUP_HOME}${PSUBDIR}
else
KERNEL_HOME=/mnt/$VHOME
if mount | grep -q "${VHOME}" ;then
echo "${KERNEL_HOME} is mounted"
if ls ${KERNEL_HOME} | grep -q 'vmlinuz' ;then
echo "This is where the kernel lives: ${KERNEL_HOME}"
else
echo "This is NOT where the kernel lives: ${KERNEL_HOME}"
KERNEL_HOME=/initrd${PUP_HOME}${PSUBDIR}
echo "We'll try $KERNEL_HOME"
fi
else
UMT=1 # in case kernel lives elsewhere
[ -f "${KERNEL_HOME}" ] || mkdir -p ${KERNEL_HOME}
mount /dev/${VHOME} ${KERNEL_HOME}
ret=$?
[ $ret -ne 0 ] && $ERR "$FMNT" $ret
if ls ${KERNEL_HOME} | grep -q 'vmlinuz' ;then
echo "This is where the kernel lives: ${KERNEL_HOME}"
else
echo "This is NOT where the kernel lives: ${KERNEL_HOME} .. unmounting"
umount /dev/${VHOME}
KERNEL_HOME=/initrd${PUP_HOME}${PSUBDIR}
echo "We'll try $KERNEL_HOME"
fi
fi
fi
DATE=`date +%y%m%d`
cleanup() {
rm -f /tmp/kernelhelp.txt
ls /tmp | grep 'vmlinuz' && rm -f /tmp/vmlinuz* /tmp/kernel-modules* /tmp/fdrv*
}
trap cleanup EXIT
# the main operation
change() {
echo "$1" | grep -q 'vmlinuz' || _msg $ERR "$KMSG" 21
echo "$2" | grep 'sfs' | grep -qE 'zdrv|kernel\-modules' || _msg $ERR "$MMSG" 22
if [ "$3" ];then # fdrv exists
FDSFS=" "
FF=1
fi
export SURE="
$FDSFS
$BUTTONY
$BUTTONN
"
eval $(gtkdialog -p SURE -c)
case $EXIT in
No|abort)echo "abort"; exit 0;;
esac
# move it to backup
OV=yes
if [ -f "$KERNEL_HOME/vmlinuz.${DATE}-${CURK}" ];then
_msg "$EXISTS" "vmlinuz.${DATE}-${CURK} $OVERMSG $CURK $OVERMSG1" 100 cancel
case $EXITVAL in
Cancel|abort)echo "aborting"; exit 0;;
No)echo "no overwrite"; OV=no ;;
esac
fi
if [ "$OV" != "no" ];then
mv -f $KERNEL_HOME/vmlinuz $KERNEL_HOME/vmlinuz.${DATE}-${CURK}
[ $? -ne 0 ] && _msg $ERR "$FMMSG ${1##*/}" 23
mv -f $MODULES_HOME/$DISTRO_ZDRVSFS $MODULES_HOME/$DISTRO_ZDRVSFS.${DATE}-${CURK}
[ $? -ne 0 ] && _msg $ERR "$FMMSG ${2##*/}" 24
if [ -f "$MODULES_HOME/$DISTRO_FDRVSFS" ];then
mv -f $MODULES_HOME/$DISTRO_FDRVSFS $MODULES_HOME/$DISTRO_FDRVSFS.${DATE}-${CURK}
[ $? -ne 0 ] && _msg $ERR "$FMMSG ${3##*/}" 24
fi
fi
# copy the new kernel files
cp -a "$1" $KERNEL_HOME/vmlinuz
[ $? -ne 0 ] && mv -f $KERNEL_HOME/vmlinuz.${DATE}-${CURK} $KERNEL_HOME/vmlinuz \
&& _msg $ERR "$VMSG" 25
cp -a "$2" $MODULES_HOME/$DISTRO_ZDRVSFS
[ $? -ne 0 ] && mv -f $MODULES_HOME/${DISTRO_ZDRVSFS}.${DATE}-${CURK} $MODULES_HOME/$DISTRO_ZDRVSFS \
&& _msg $ERR "$FSMSG1 $DISTRO_ZDRVSFS: $FSMSG2" 26
if [ "$FF" = '1' ];then
cp -a "$3" $MODULES_HOME/$DISTRO_FDRVSFS
[ $? -ne 0 ] && mv -f $MODULES_HOME/${DISTRO_FDRVSFS}.${DATE}-${CURK} $MODULES_HOME/$DISTRO_FDRVSFS \
&& _msg $ERR "$FSMSG1 $DISTRO_FDRVSFS: $FSMSG2" 26
fi
echo $1 | grep -q 'tmp' && rm $1 $2 $3 # cleanup /tmp
# problem with deb based 64 not installing correctly with slacko64 kernels
change_lib64_to_lib $MODULES_HOME/$DISTRO_ZDRVSFS $MODULES_HOME
echo $?
[ "$UMT" = "1" ] && umount $KERNEL_HOME
_msg $SUCC "$RMSG" 0 not
}
# extract
extract_kernel() {
gtkdialog-splash -bg orange -close box -text "$WAIT1" &
epid=$!
tar -xf "$1" -C /tmp
kill -9 $epid
VML=$(ls /tmp | grep -m1 '^vmlinuz')
VMODS=$(ls /tmp | grep -m1 '^kernel\-modules')
VFD=$(ls /tmp | grep -m1 '^fdrv')
if [ -f "/tmp/$VFD" ];then
change /tmp/$VML /tmp/$VMODS /tmp/$VFD
else
change /tmp/$VML /tmp/$VMODS
fi
}
change_lib64_to_lib() {
uname -m | grep -q '64' || return 0 # 64 bit only
[ -h /usr/lib64 ] || return 0 # slackware
ZSFS="$1"
ZSFS=${ZSFS##*\/}
WDIR=$2
ZDIR=${ZSFS%\.*}
cd $WDIR
gtkdialog-splash -bg orange -close box -text "$WAIT2" &
cpid=$!
unsquashfs -d $ZDIR $ZSFS
rm $ZSFS
mv -f ${ZDIR}/usr/lib64 ${ZDIR}/usr/lib
mksquashfs ${ZDIR} $ZSFS
kill -9 $cpid
}
# rollback to a backup
rollback() {
VTRUE=`ls $KERNEL_HOME|grep 'vmlinuz'|cut -d '.' -f2,3,4,5|grep -E '^1|^2'`
[ -z "$VTRUE" ] && _msg $ERR $KRRERR 42
ls $MODULES_HOME|grep "$DISTRO_ZDRVSFS"|grep -q "$VTRUE" || _msg $ERR "$KRRERR" 43
for i in `echo $VTRUE`; do
BTNS="$BTNS"""
done
export RROLL="
$BTNS
$BUTTONC
"
eval $(gtkdialog -p RROLL -c)
case $EXIT in
Cancel|abort)echo "abort"; exit 0;;
2*) #any yymmdd date over 2000
KIMAGE=vmlinuz.${EXIT}
KMODULES=${DISTRO_ZDRVSFS}.${EXIT}
[ -f "${DISTRO_FDRVSFS}.${EXIT}" ] && KFIRM=${DISTRO_FDRVSFS}.${EXIT} && echo $KFIRM
echo $KIMAGE $KMODULES;;
*)echo bad; exit 99;;
esac
#copy - retain the backup
echo $KERNEL_HOME/${KIMAGE}
cp -af $KERNEL_HOME/${KIMAGE} $KERNEL_HOME/vmlinuz &&
[ $? -ne 0 ] && _msg $ERR "$FMMSG ${KIMAGE}" 123
cp -af $MODULES_HOME/${KMODULES} $MODULES_HOME/${DISTRO_ZDRVSFS} &&
[ $? -ne 0 ] && _msg $ERR "$FMMSG ${DISTRO_ZDRVSFS}" 124
[ -n "$KFIRM" ] && cp -af $MODULES_HOME/${KFIRM} $MODULES_HOME/${DISTRO_FDRVSFS}
[ "$UMT" = "1" ] && umount $KERNEL_HOME
_msg $SUCC "$RMSG" 0
}
help_me() {
cat > /tmp/kernelhelp.txt << _EOF
${HHELP}
=========================== $HWARN ==================================
${HSYS}
=========================== $HWARN ==================================
${HTAR}
${HTARBALL}
**************************** ${HOR} *************************************
${HVMLINUZ}
${HMODULES1}
${HMODULES2}
${HMODULES3}
${HFIRM1}
${HFIRM2}
${HMATCH}
${HROX}
${HOK}
${HID2}
${HFAIL}
${HBACK1}
${HBACK2}
${HGOOD}
${HBUG}
${HGPL}
${HCARE}
_EOF
defaulttextviewer /tmp/kernelhelp.txt
}
export -f help_me
[ "$GTKDIALOG_BUILD" = 'GTK3' ] && XOPT='--styles=/tmp/gtkrc_xml_info.css'
# main
export GUI="
`/usr/lib/gtkdialog/xml_info fixed /usr/share/pixmaps/tux.svg 60 "$MSG1"`
VTARBALLVMLINUZMODULESFIRM
$BUTTONO
$BUTTONC
"
. /usr/lib/gtkdialog/xml_info gtk
eval $(gtkdialog -p GUI -c $XOPT)
case $EXIT in
OK)
if [ -n "$VMLINUZ" -a -n "$MODULES" -a -z "$FIRM" ] ; then
change $VMLINUZ $MODULES
elif [ -n "$VMLINUZ" -a -n "$MODULES" -a -n "$FIRM" ] ; then
change $VMLINUZ $MODULES
elif [ -n "$VTARBALL" ] ;then
extract_kernel $VTARBALL
else
_msg $ERR "$CERR" 69
fi
;;
roll) rollback;;
*)exit 0;;
esac