Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 30c1102f authored by Kenny Root's avatar Kenny Root
Browse files

Add image creator helper script for OBBs

Change-Id: Id3f2b158077e8d104582e0ac720c2428c3ba4d97
parent 181e5ea8
Loading
Loading
Loading
Loading

tools/obbtool/mkobb.sh

0 → 100755
+260 −0
Original line number Diff line number Diff line
#!/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