Skip to content

Instantly share code, notes, and snippets.

@erichschroeter
Last active Aug 29, 2015
Embed
What would you like to do?
#!/bin/sh
#
# This file handles auto mounting/unmounting devices.
usage()
{
cat << EOF
Usage:
`basename $0` add <device> <path>
`basename $0` remove <device>
EOF
}
#
# Unmounts the specified device.
#
# $1 the device file or mount point
#
auto_umount()
{
if grep -qs "^$1 " /proc/mounts ; then
umount "$1"
fi
}
#
# Mounts the specified device file to the specified directory If the directory
# does not exist it will be created.
#
# $1 the device file
# $2 the directory to mount to
#
auto_mount()
{
# Exit if the directory was not specified
if [ -z "$2" ]; then
echo "No directory specified" >&2
exit 1
fi
# Create the directory if it does not exist
[ -d "$2" ] || mkdir -p "$2"
if ! mount -t auto -o sync,flush "$1" "$2"; then
# failed to mount
exit $?
fi
}
case "$1" in
add)
shift
auto_mount $1 $2
;;
remove)
shift
auto_umount $1
;;
*) usage ; exit 1 ;;
esac
exit 0
#!/bin/sh
#
# Handles generating a manifest of files.
usage() {
cat << EOF
Usage:
`basename $0` [-h] [-o <file>]
Options:
h print this menu
o output file
EOF
}
generate_manifest()
{
# List all files on boot partition
if [ -e "/dev/mmcblk0p1" ] ; then
mkdir -p /mnt/boot
mount /dev/mmcblk0p1 /mnt/boot
find /mnt -type f | xargs md5sum
umount /mnt/boot
rmdir /mnt/boot
fi
# List all files on rootfs partition
find /bin /sbin /etc /lib /usr /home -type f | xargs md5sum
}
OUTPUT=
while getopts ":ho:" opt ;
do
case "$opt" in
h) usage ; exit 0 ;;
o) OUTPUT=$OPTARG ;;
\?) echo "Invalid option: $OPTARG" >&2 ; exit 1 ;;
esac
done
shift $((OPTIND-1))
case "$1" in
*)
if [ -n "$OUTPUT" ] ; then
generate_manifest > "$OUTPUT"
else
generate_manifest
fi
;;
esac
exit 0
#!/bin/sh
#
usage() {
cat << EOF
Usage:
`basename $0` [-hb] update <device>
`basename $0` [-h] backup <device>
Options:
h print this menu
b also backup logs
EOF
}
__log()
{
logger -t product_update "$1"
}
#
# Displays a message on the screen. Use this function so you don't have to
# mess with screwing up the title and separator.
#
# $1 the title
# $2 the message
#
__display()
{
display -x 35 -y 0 "$1" -y 1 " ------------------ " -y 2 "$2"
}
#
# Gracefully exits this script in the case of an error. This logs an error
# message and optionally displays a message to the user.
#
# $1 function which failed
# $2 exit code
# $3 message to be logged
# $4 message to be displayed on screen (optional)
#
__fail()
{
__log "$3"
case "$1" in
update)
[[ "x$4" != "x" ]] && __display "USB Update" "$4"
;;
backup)
[[ "x$4" != "x" ]] && __display "Backup Logs" "$4"
;;
manifest)
[[ "x$4" != "x" ]] && __display "Manifest" "$4"
;;
esac
gpio usb 0
# Pause for some time so user can see error message
sleep 2
exit $2
}
#
# Updates the PRODUCT firmware. Before installing the specified PRODUCT update it
# must pass a GPG signing verification. If the verification fails so does this
# command.
#
# Errors are logged via syslog.
#
# $1 the signed PRODUCT update file (a .tar.gz.gpg file)
#
product_update()
{
if [ -z "$1" ] ; then
__fail update 1 "update DNE" "not found"
fi
gpio usb 1
# Reset the screen in case there's something on it (e.g. failed update)
__display "USB Update" "verifying"
# Verify the update before actually installing it
gpg --verify "$1"
RES=$?
[[ $RES -eq 0 ]] || __fail update 2 "exit code [gpg --verify] $RES" "verify error"
# Clean prior updates and extract update file to tmp directory
TMPDIR=/tmp/usbupdate
FILENAME=$(basename $1)
cp "$1" /company/
RES=$?
[[ $RES -eq 0 ]] || __fail update 3 "exit code [cp "$1" /company] $RES" "copy error"
rm -rf $TMPDIR
RES=$?
[[ $RES -eq 0 ]] || __fail update 4 "exit code [rm -rf $TMPDIR] $RES" "cleanup error"
mkdir -p $TMPDIR
RES=$?
[[ $RES -eq 0 ]] || __fail update 5 "exit code [mkdir -p $TMPDIR] $RES" "init error"
gpg --decrypt "/company/$FILENAME" > /tmp/$FILENAME
RES=$?
[[ $RES -eq 0 ]] || __fail update 6 "exit code [gpg --decrypt] $RES " "decrypt error"
tar -xzf /tmp/$FILENAME -C $TMPDIR
RES=$?
[[ $RES -eq 0 ]] || __fail update 7 "exit code [tar -xzf /tmp/$FILENAME -C $TMPDIR] $RES" "extract error"
__display "USB Update" "installing"
sleep 1
# --force-downgrade otherwise we won't be able to install previous versions
opkg --force-downgrade install $(find $TMPDIR -type f -name '*.ipk')
RES=$?
# For some reason opkg returns exit code 255, but actually installs the
# packages. So, for now don't check the exit code until this is understood.
#[[ $RES -eq 0 ]] || __fail update 7 "exit code [opkg install $(find $TMPDIR -type f -name '*.ipk')] $RES" "install error"
__log "exit code [opkg install $(find $TMPDIR -type f -name '*.ipk')] $RES"
__display "USB Update" "complete"
gpio usb 0
}
#
# Backups the PRODUCT logs to the USB drive.
#
# $1 the directory to copy to (created if does not exist)
#
product_backup()
{
if [ -z "$1" ] ; then
__fail backup 1 "no backup backup location specified"
fi
gpio usb 1
__display "Backup Logs" "copying"
mkdir -p "$1"
RES=$?
[[ $RES -eq 0 ]] || __fail backup 1 "exit code [mkdir -p $1] $RES" "init error"
cp /var/log/persistent/bhacd/*.log* "$1"
RES=$?
[[ $RES -eq 0 ]] || __fail backup 2 "exit code [cp /var/log/persistent/bhacd/*.log* $1] $RES" "copy error"
__display "Backup Logs" "complete"
__display "Manifest" "generating"
product-manifest.sh > "$1/MANIFEST"
RES=$?
[[ $RES -eq 0 ]] || __fail manifest 3 "exit code [product-manifest > $1/MANIFEST] $RES" "generate error"
__display "Manifest" "complete"
gpio usb 0
}
BACKUP=0
while getopts ":hb" opt ;
do
case "$opt" in
h) usage ; exit 0 ;;
b) BACKUP=1 ;;
\?) echo "Invalid option: $OPTARG" >&2 ; exit 1 ;;
esac
done
shift $((OPTIND-1))
case "$1" in
update)
auto-mounter.sh add "$2" "/media/usb"
RES=$?
[[ $RES -eq 0 ]] || __fail update 0 "exit code [auto-mounter add \"$2\" \"/media/usb\"] $RES" "mount error"
if [[ -f "/media/usb/product/update.tar.gz.gpg" ]] ; then
product_update "/media/usb/product/update.tar.gz.gpg"
else
__display "USB Update" "skipping"
fi
# Some time to let user see progress
sleep 2
# Copy logs to a timestamped directory
[[ $BACKUP -eq 1 ]] && product_backup "/media/usb/product/logs/`date +'%Y-%m-%d_%H-%M-%S'`"
# THE SCRIPT SOMETIMES STOPS HERE
auto-mounter.sh remove "$2"
# THE SCRIPT SOMETIMES STOPS HERE
# Some time to let user see progress
sleep 2
display -y 2 " Unplug to continue"
;;
backup)
auto-mounter.sh add "$2" "/media/usb"
RES=$?
[[ $RES -eq 0 ]] || __fail backup 0 "exit code [auto-mounter add \"$2\" \"/media/usb\"] $RES" "mount error"
# Copy logs to a timestamped directory
product_backup "/media/usb/product/logs/`date +'%Y-%m-%d_%H-%M-%S'`"
auto-mounter.sh remove "$2"
;;
*) usage ; exit 1 ;;
esac
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment