diff options
author | Kenny Root <kroot@google.com> | 2010-09-21 10:13:19 -0700 |
---|---|---|
committer | Kenny Root <kroot@google.com> | 2010-09-21 10:13:19 -0700 |
commit | 30c1102fecda5e9ef071c58c0e54b721961ae4e3 (patch) | |
tree | d7b24893fb749d99db005a7cc10ae424c3e9de12 /tools/obbtool | |
parent | 181e5ea8087360742b3ed0a7f2e6f8f8baa0a760 (diff) | |
download | frameworks_base-30c1102fecda5e9ef071c58c0e54b721961ae4e3.zip frameworks_base-30c1102fecda5e9ef071c58c0e54b721961ae4e3.tar.gz frameworks_base-30c1102fecda5e9ef071c58c0e54b721961ae4e3.tar.bz2 |
Add image creator helper script for OBBs
Change-Id: Id3f2b158077e8d104582e0ac720c2428c3ba4d97
Diffstat (limited to 'tools/obbtool')
-rwxr-xr-x | tools/obbtool/mkobb.sh | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/tools/obbtool/mkobb.sh b/tools/obbtool/mkobb.sh new file mode 100755 index 0000000..f4cae9a --- /dev/null +++ b/tools/obbtool/mkobb.sh @@ -0,0 +1,260 @@ +#!/bin/bash +# +# Copyright (C) 2010 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# mkobb.sh - Creates OBB files on Linux machines + +# Directory where we should temporarily mount the OBB loopback to copy files +MOUNTDIR=/tmp + +# Presets. Changing these will probably break your OBB on the device +CRYPTO=blowfish +FS=vfat +MKFS=mkfs.vfat +LOSETUP=losetup +BLOCK_SIZE=512 +SLOP=512 # Amount of filesystem slop in ${BLOCK_SIZE} blocks + +find_binaries() { + MKFSBIN=`which ${MKFS}` + LOSETUPBIN=`which ${LOSETUP}` + MOUNTBIN=`which mount` + UMOUNTBIN=`which umount` + DDBIN=`which dd` + RSYNCBIN=`which rsync` +} + +check_prereqs() { + if [ "`uname -s`x" != "Linuxx" ]; then \ + echo "ERROR: This script only works on Linux!" + exit 1 + fi + + if ! egrep -q "^cryptoloop " /proc/modules; then \ + echo "ERROR: Could not find cryptoloop in the kernel." + echo "Perhaps you need to: modprobe cryptoloop" + exit 1 + fi + + if ! egrep -q "name\s*:\s*${CRYPTO}$" /proc/crypto; then \ + echo "ERROR: Could not find crypto \`${CRYPTO}' in the kernel." + echo "Perhaps you need to: modprobe ${CRYPTO}" + exit 1 + fi + + if ! egrep -q "^\s*${FS}$" /proc/filesystems; then \ + echo "ERROR: Could not find filesystem \`${FS}' in the kernel." + echo "Perhaps you need to: modprobe ${FS}" + exit 1 + fi + + if [ "${MKFSBIN}x" = "x" ]; then \ + echo "ERROR: Could not find ${MKFS} in your path!" + exit 1 + elif [ ! -x "${MKFSBIN}" ]; then \ + echo "ERROR: ${MKFSBIN} is not executable!" + exit 1 + fi + + if [ "${LOSETUPBIN}x" = "x" ]; then \ + echo "ERROR: Could not find ${LOSETUP} in your path!" + exit 1 + elif [ ! -x "${LOSETUPBIN}" ]; then \ + echo "ERROR: ${LOSETUPBIN} is not executable!" + exit 1 + fi +} + +cleanup() { + if [ "${loopdev}x" != "x" ]; then \ + ${LOSETUPBIN} -d ${loopdev} + fi +} + +hidden_prompt() { + unset output + prompt="$1" + outvar="$2" + while read -s -n 1 -p "$prompt" c; do \ + if [ "x$c" = "x" ]; then \ + break + fi + prompt='*' + output="${output}${c}" + done + echo + eval $outvar="$output" + unset output +} + +read_key() { + hidden_prompt " Encryption key: " key + + if [ "${key}x" = "x" ]; then \ + echo "ERROR: An empty key is not allowed!" + exit 1 + fi + + hidden_prompt "Encryption key (again): " key2 + + if [ "${key}x" != "${key2}x" ]; then \ + echo "ERROR: Encryption keys do not match!" + exit 1 + fi +} + +onexit() { + if [ "x${temp_mount}" != "x" ]; then \ + ${UMOUNTBIN} ${temp_mount} + rmdir ${temp_mount} + fi + if [ "x${loop_dev}" != "x" ]; then \ + ${LOSETUPBIN} -d ${loop_dev} + fi + if [ "x${tempfile}" != "x" -a -f "${tempfile}" ]; then \ + rm -f ${tempfile} + fi + if [ "x${keyfile}" != "x" -a -f "${keyfile}" ]; then \ + rm -f ${keyfile} + fi + echo "Fatal error." + exit 1 +} + +usage() { + echo "mkobb.sh -- Create OBB files for use on Android" + echo "" + echo " -c Use an encrypted OBB; must specify key" + echo " -d <directory> Use <directory> as input for OBB files" + echo " -k <key> Use <key> to encrypt OBB file" + echo " -K Prompt for key to encrypt OBB file" + echo " -o <filename> Write OBB file out to <filename>" + echo " -v Verbose mode" + echo " -h Help; this usage screen" +} + +find_binaries +check_prereqs + +use_crypto=0 + +args=`getopt -o cd:hk:Ko:v -- "$@"` +eval set -- "$args" + +while true; do \ + case "$1" in + -c) use_crypto=1; shift;; + -d) directory=$2; shift 2;; + -h) usage; exit 1;; + -k) key=$2; shift 2;; + -K) prompt_key=1; shift;; + -v) verbose=1; shift;; + -o) filename=$2; shift 2;; + --) shift; break;; + *) echo "ERROR: Invalid argument in option parsing! Cannot recover. Ever."; exit 1;; + esac +done + +if [ "${directory}x" = "x" -o ! -d "${directory}" ]; then \ + echo "ERROR: Must specify valid input directory" + echo "" + usage + exit 1; +fi + +if [ "${filename}x" = "x" ]; then \ + echo "ERROR: Must specify filename" + echo "" + usage + exit 1; +fi + +if [ ${use_crypto} -eq 1 -a "${key}x" = "x" -a 0${prompt_key} -eq 0 ]; then \ + echo "ERROR: Crypto desired, but no key supplied or requested to prompt for." + exit 1 +fi + +if [ 0${prompt_key} -eq 1 ]; then \ + read_key +fi + +outdir=`dirname ${filename}` +if [ ! -d "${outdir}" ]; then \ + echo "ERROR: Output directory does not exist: ${outdir}" + exit 1 +fi + +# Make sure we clean up any stuff we create from here on during error conditions +trap onexit ERR + +tempfile=$(tempfile -d ${outdir}) || ( echo "ERROR: couldn't create temporary file in ${outdir}"; exit 1 ) + +block_count=`du --apparent-size --block-size=512 ${directory} | awk '{ print $1; }'` +if [ $? -ne 0 ]; then \ + echo "ERROR: Couldn't read size of input directory ${directory}" + exit 1 +fi + +echo "Creating temporary file..." +${DDBIN} if=/dev/zero of=${tempfile} bs=${BLOCK_SIZE} count=$((${block_count} + ${SLOP})) > /dev/null 2>&1 +if [ $? -ne 0 ]; then \ + echo "ERROR: creating temporary file: $?" +fi + +loop_dev=$(${LOSETUPBIN} -f) || ( echo "ERROR: losetup wouldn't tell us the next unused device"; exit 1 ) + +if [ ${use_crypto} -eq 1 ]; then \ + keyfile=$(tempfile -d ${outdir}) || ( echo "ERROR: could not create temporary key file"; exit 1 ) + ${LOSETUPBIN} -p 5 -e ${CRYPTO} ${loop_dev} ${tempfile} 5< ${keyfile} || ( echo "ERROR: couldn't create loopback device"; exit 1 ) + rm -f ${keyfile} +else \ + ${LOSETUPBIN} ${loop_dev} ${tempfile} || ( echo "ERROR: couldn't create loopback device"; exit 1 ) +fi + +# +# Create the filesystem +# +echo "" +${MKFSBIN} -I ${loop_dev} +echo "" + +# +# Make the temporary mount point and mount it +# +temp_mount="${MOUNTDIR}/${RANDOM}" +mkdir ${temp_mount} +${MOUNTBIN} -t ${FS} -o loop ${loop_dev} ${temp_mount} + +# +# rsync the files! +# +echo "Copying files:" +${RSYNCBIN} -av --no-owner --no-group ${directory}/ ${temp_mount}/ +echo "" + +echo "Successfully created \`${filename}'" + +# +# Undo all the temporaries +# +umount ${temp_mount} +rmdir ${temp_mount} +${LOSETUPBIN} -d ${loop_dev} +mv ${tempfile} ${filename} + +trap - ERR + +exit 0 |