#!/bin/sh # $Id$ # /etc/rc.firmware # part of m0n0wall (http://neon1.net/m0n0wall) # # Copyright (C) 2003 Manuel Kasper . # All rights reserved. #CFDEVICE=`cat /var/etc/cfdevice` exec 3>&2 2>>/tmp/firmware_update.log export ACTION=$1 export IMG=$2 if [ $# -eq 3 ]; then export CUSTOMIMG=$3 fi if [ $ACTION != "upgrade" ]; then /sbin/umount -f /ftmp > /dev/null 2>&1 fi backup_chflags() { TOPROCESS="bin lib libexec sbin usr" for files in $TOPROCESS; do /usr/sbin/mtree -Pcp /${files} | bzip2 -9 > /tmp/chflags.dist.${files}.bz2 | logger -p daemon.info -i -t UpgradeFlags done } restore_chflags() { TOPROCESS="bin lib libexec sbin usr" for files in $TOPROCESS; do cd / && /usr/bin/bzcat /tmp/chflags.dist.${files}.bz2 | /usr/sbin/mtree -PU -p /${files} | logger -p daemon.info -i -t UpgradeFlags done } remove_chflags() { TOPROCESS="bin lib libexec sbin usr" for files in $TOPROCESS; do /bin/chflags -R noschg /${files} /bin/chmod -R u+rw /${files} done } binary_update() { TGZ=$1 ERR_F="/tmp/bdiff.log" rm ${ERR_F} 2>/dev/null /bin/mkdir /tmp/patched /tmp/patches 2>>${ERR_F} backup_chflags remove_chflags cd /tmp/patches for i in `/usr/bin/tar tvzf $TGZ | egrep -v "(^d|_md5)" | nawk '{print $9;}'`; do FILE=`basename ${i}` echo "Working on ${i}" # Untar patch file and md5 files /usr/bin/tar xzf ${TGZ} ${i} ${i}.old_file_md5 ${i}.new_patch_md5 ${i}.new_file_md5 2>>${ERR_F} # Apply patch - oldfile newfile patchfile /usr/local/bin/bspatch /${i} /tmp/patched/${FILE} /tmp/patches/${i} 2>>${ERR_F} OLD_FILE_MD5=`cat /tmp/patches/${i}.old_file_md5 2>/dev/null` NEW_PATCH_MD5=`cat /tmp/patches/${i}.new_patch_md5 2>/dev/null` NEW_FILE_MD5=`cat /tmp/patches/${i}.new_file_md5 2>/dev/null` PATCHED_MD5=`/sbin/md5 -q /tmp/patched/${FILE} 2>/dev/null` if [ "$PATCHED_MD5" = "$NEW_PATCH_MD5" ]; then /usr/bin/install -S /tmp/patched/${FILE} /${i} else #echo "${i} file does not match intended final md5." echo "${i} file does not match intended final md5." >> ${ERR_F} fi /bin/rm /tmp/patched/${FILE} >> ${ERR_F} /bin/rm /tmp/patches/${i} >> ${ERR_F} /bin/rm /tmp/patches/${i}.* >> ${ERR_F} done /bin/rm -rf /tmp/patched /tmp/patches >> ${ERR_F} restore_chflags } case $ACTION in enable) #/sbin/mount_mfs -s 15360 -T qp120at -b 8192 -f 1024 dummy /ftmp \ # > /dev/null 2>&1 ;; auto) touch /var/run/firmware.lock backup_chflags remove_chflags /etc/rc.firmware_auto restore_chflags ;; upgrade) touch /var/run/firmware.lock # wait 5 seconds before beginning sleep 5 backup_chflags remove_chflags exec /dev/console 2>/dev/console echo echo "Firmware upgrade in progress..." | logger -p daemon.info -i -t Upgrade echo "Firmware upgrade in progress..." | wall # backup config mkdir /tmp/configbak cp -p /conf/* /tmp/configbak # unmount /cf /sbin/umount -f /cf # dd image onto card if [ -r $IMG ]; then /usr/bin/gunzip -S "" -c $IMG | dd of=/dev/r$CFDEVICE bs=16k > /dev/null 2>&1 echo "Image installed." fi # mount /cf /sbin/mount -w -o noatime /cf # restore config cp -p /tmp/configbak/* /conf restore_chflags rm -f /var/run/firmware.lock /bin/sync sleep 5 echo "Done." # If /tmp/post_upgrade_command exists after update # then execute the command. if [ -f /tmp/post_upgrade_command ]; then sh /tmp/post_upgrade_command fi # If the archive has unpacked a file called # /tmp/no_upgrade_reboot_required then do # not reboot after upgrade. if [ -f /tmp/no_upgrade_reboot_required ]; then rm /tmp/no_upgrade_reboot_required else rm -f /var/run/config.lock sh /etc/rc.reboot fi ;; pfSenseupgrade) touch /var/run/firmware.lock # wait 1 seconds before beginning sleep 1 # Sanity check - bail early if there's no firmware file! if [ ! -r $IMG ]; then echo "2nd parameter has not been passed or file does not exist. Exiting." | logger -p daemon.info -i -t Upgrade exit fi backup_chflags remove_chflags # Do we have a pre-upgrade hook in the update file? if [ `tar tvzf $IMG | grep /tmp/pre_upgrade_command | wc -l` -gt 0 ]; then tar xzvf $IMG -C / ./tmp/pre_upgrade_command chmod a+rx /tmp/pre_upgrade_command sh /tmp/pre_upgrade_command fi #exec /dev/console 2>/dev/console echo "Firmware upgrade in progress..." | logger -p daemon.info -i -t Upgrade # backup config /bin/mkdir -p /tmp/configbak cp -p /conf/* /tmp/configbak 2>/dev/null # mount /cf /etc/rc.conf_mount_rw /sbin/mount -w -o noatime /cf 2>/dev/null /sbin/mount -w -o noatime / 2>/dev/null # tar explode image onto hd echo "Installing $IMG." | logger -p daemon.info -i -t Upgrade cd / && /usr/bin/tar xzUPf $IMG | logger -p daemon.info -i -t Upgrade /usr/bin/find / -name CVS -exec rm -fr {} \; echo "Image installed $IMG." | logger -p daemon.info -i -t Upgrade # process custom image if its passed if [ $# -eq 3 ]; then if [ -f $CUSTOMIMG ]; then echo "Custom image $CUSTOMIMG found." | logger -p daemon.info -i -t Upgrade echo "Custom image ($CUSTOMIMG) found." PWD_DIR=`pwd` cd / && /usr/bin/tar xzPUf $CUSTOMIMG | logger -p daemon.info -i -t Upgrade cd $PWD_DIR echo "Custom image $CUSTOMIMG installed." | logger -p daemon.info -i -t Upgrade fi fi # restore config cp -p /tmp/configbak/* /conf 2>/dev/null # restore /etc symlinks rm /etc/hosts ln -s /var/etc/hosts /etc/hosts restore_chflags # Remove upgrade file rm -f $IMG if [ -e /etc/init_bootloader.sh ]; then sh /etc/init_bootloader.sh fi # If /tmp/post_upgrade_command exists after update # then execute the command. if [ -f /tmp/post_upgrade_command ]; then sh /tmp/post_upgrade_command fi # remount /cf ro rm -rf /etc/rc.conf rm -rf /etc/motd find / -name CVS -type d -exec rm {} \; rm -rf /usr/savecore/* /etc/rc.conf_mount_ro /sbin/umount -f /cf 2>/dev/null /sbin/mount -r /cf 2>/dev/null /sbin/umount -f / 2>/dev/null /sbin/mount -r / 2>/dev/null sleep 3 rm -f /var/run/firmware.lock /bin/sync sleep 2 echo "Done." | logger -p daemon.info -i -t Upgrade # If the archive has unpacked a file called # /tmp/no_upgrade_reboot_required then do # not reboot after upgrade. if [ -f /tmp/no_upgrade_reboot_required ]; then rm /tmp/no_upgrade_reboot_required else rm -f /var/run/config.lock sh /etc/rc.reboot fi ;; delta_update) touch /var/run/firmware.lock backup_chflags remove_chflags binary_update $IMG restore_chflags rm -rf /etc/rc.conf rm -rf /etc/motd find / -name CVS -type d -exec rm {} \; rm -rf /usr/savecore/* /etc/rc.conf_mount_ro /sbin/umount -f /cf 2>/dev/null /sbin/mount -r /cf 2>/dev/null /sbin/umount -f / 2>/dev/null /sbin/mount -r / 2>/dev/null if [ -e /etc/init_bootloader.sh ]; then sh /etc/init_bootloader.sh fi ;; esac