#!/bin/bash
# build date: 2010-07-19 23:37:01 -0400
#
# To unbundle, bash this file.
#
export PS4='+(${LINENO}:${BASH_SOURCE}:${EUID}): 
        ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
TMPDIR=${TMPDIR:-/tmp}
cat >|${TMPDIR}/launcher <<'End of launcher'
#!/bin/bash
#  version date: 2010-06-15 22:44:57 -0400 
#
#  launcher:  launches code from a bundled script
#
#  Copyright 2010, Sugar Labs
#  Frederick Grose <fgrose@sugarlabs.org>
#
#  Usage:
#       ${TMPDIR}/launcher $*
#
#       Used with the 'bundle' package builder to control the launch environment
#       for a bundled script.  See 'bundle' documentation.
#        
#       $*  are options or arguments given to the bundleFile and passed on to
#       launcher.
#        
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; version 2 of the License.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU Library General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

TMPDIR=${TMPDIR:-/tmp}

su --session-command="pwd" 2>/dev/null 1>2&
case $? in
    0)
        su_option=--session-command
        ;;
    *)
        su_option=--command
        ;;
esac
su ${su_option}="${TMPDIR}/newSugarStick $* " root
exit 0
End of launcher
chmod 777 ${TMPDIR}/launcher
cat >|${TMPDIR}/newSugarStick <<'End of newSugarStick'
#!/bin/bash
#  version date: 2010-07-19 20:24:30 -0400
#
#  'SugarClone' copies a live 'Sugar on a Stick' image onto a second device. 
#
#  Copyright 2010, Sugar Labs
#  Frederick Grose <fgrose@sugarlabs.org>
#        
#  Usage:
#        Called from 'SugarClone'
#        
#   newSugarStick is bundled in SugarClone.  When SugarClone is called, 4
#   Bash scripts are unbundled. 'launcher' is called to launch
#   'newSugarStick', which later calls 'modified_livecd-iso-to-disk'. Finally,
#   'SugarCellar', a utility for reporting disc space availability, is saved on
#   the Sugar on a Stick image.        
#
#  Requires: 'modified_livecd-iso-to-disk'
#      from http://people.sugarlabs.org/modified_livecd-iso-to-disk
#  If accepted upstream, the previous requirement would become:
#  Requires: 'livecd-iso-to-disk'
#  from
#  http://git.fedorahosted.org/git/livecd/tools?p=livecd;a=tree;f=tools;hb=HEAD
#
#  to install a live media iso or running image so that
#  it's bootable off of a bootable, flash storage device.
# 
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; version 2 of the License.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU Library General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

export PATH=/sbin:/usr/sbin:$PATH
export \
   PS4='+(${LINENO}:${BASH_SOURCE}:${EUID}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
clear

shortusage() {
    brief='
    Short usage information for SugarClone follows:
    
    NAME 

       SugarClone  -  Installs a copy of a Sugar image onto a second device.
    
    SYNTAX
    
       Simplest:
       
           SugarClone

       Simple:
       
           SugarClone [--help] [--image <source>] [--partition <num>]
                      [--builder <name>] [--keepuser] [--skipcopy] [quit]

    USAGE

    The script may be run in Simplest form with no command-line options.
    This will simply create a Sugar Clone of the running image.
        (The --noverify --copy-overlay --delete-home --copy-home options have
        been hard-coded into this mode.)
        
    If there is more than one USB storage device connected to your system,
    you will be presented with a menu to select the device you would like to
    make the target for the Sugar Clone.

    In the Simple mode, any of the --help --image <source> --partition <num>
    --builder <name> --skipcopy & --keepuser options may be entered to augment
    the Simplest mode.

    Enter SugarClone --help on the command line to see more information.
'
}
shortusage

usage() {
    echo -e "
    ""$brief"
    echo "
    DESCRIPTION

    SugarClone is a bundle that expands on execution to a transient script,
    'newSugarStick', and a modified, Fedora, live image installer,
    'modified_livecd-iso-to-disk'.  The scripts are copied and run from /tmp/
    directory (which is a RAM disc on Sugar on a Stick) in order to preserve the
    write-once, ever-diminishing persistent operating system storage on the
    LiveOS image.  Following expansion, newSugarStick is set to run with the
    'su', switch user, command, so that the command may be called in the Sugar
    Terminal as the default user, liveuser, in Sugar on a Stick.  Following
    image replication, through the modified_livecd-iso-to-disk script, that
    shell script is copied to the root directory for the convenience of further
    self-replication of images.  (All the extended installation options are
    implemented by this script.)

    modified_livecd-iso-to-disk installs a Live CD/DVD/USB image (LiveOS) onto a
    USB/SD storage device (or any storage partition that will boot with a
    SYSLINUX bootloader).  The target storage device can then boot the installed
    operating system on systems that support booting via the USB or the SD
    interface.  The script requires a source, LiveOS image and a target, storage
    device.  The source image may be either a LiveOS .iso file, the
    currently-running LiveOS image, or the device node reference for the mount
    point of an installed LiveOS image.  If the operating system supports
    persistent overlays for saving system changes, a fresh overlay, or a copy of
    the source overlay may be included with the installation.  This enables one
    to easily prepare customized LiveOS images for redistribution.

    Unless you request the --format option, the installation does not destroy
    data outside of the LiveOS, syslinux, EFI, & boot folders on your target
    device.  This allows one to maintain other files on the target disk outside
    of the LiveOS filesystem.

    LiveOS images provide embedded filesystems through the Device-mapper
    component of the Linux kernel.  The embedded filesystems exist within files
    such as /LiveOS/squashfs.img (the default compressed storage) or
    /LiveOS/ext3fs.img (an uncompressed version) on the primary volume partition
    of the storage device.  In use, these are read-only filesystems. Optionally,
    one may specify a persistent LiveOS overlay to hold image-change snapshots
    (that use write-once difference tracking storage) in the
    /LiveOS/overlay-<device_id> file, which--one should note--always grow in
    size due to the storage mechanism.  (The fraction of allocated space that
    has been consumed by system activity and changes may be displayed by issuing
    the dmsetup status command in a terminal session of a running LiveOS image.)
    To conserve the unrecoverable, overlay file space, one may specify a
    persistent home folder, which will exist in a /LiveOS/home.img filesystem
    image file.  This file space is encrypted by default, but is not compressed
    (one may bypass encryption with the --unencrypted-home installation option).
    Files in this home folder may be erased to recover storage space.  The
    home.img file is also convenient for backing up or swapping user account
    files.

    Customized Sugar Clones are made by copying the source image filesystems to
    the bootable primary volume partition of the target device and adjusting the
    syslinux boot configuration and overlay files to reflect the new device
    identification.  The Sugar learner's Journal account identification keys,
    /home/liveuser/.sugar/default/owner.key & owner.key.pub are excluded from
    the copy so when the new Sugar Clone is booted, the learner will be asked to
    establish a new identification.  The original learner's Journal is copied
    into the new Sugar Clone and bears the original learner's color signature.
        (The original ownership keys may be maintained in the new Sugar Clone by
        submitting the --keepuser option on the command line.  This is a way to
        backup or archive the entire LiveOS image, including operating system
        changes.)

    OPTIONS

    --help
        Displays usage information and exits.
        
    --image <source>   (default: /dev/live)
        The running live image device, another partition
        holding a live image, or the path to an .iso file bearing a live image.

    --partition <num>   (default: 1)
        Used to designate a device volume partition other than the default, 1.
        Not to be used with --image <source> as <source> is assumed to contain
        the designated partition. Useful when a target device has multiple
        partitions.

    --builder <name>  
        The name of the builder of the customized Sugar Clone. Default: someone

    --keepuser
        Specifies that the Sugar learner's Journal identification keys should be
        preserved (copied into) the new Sugar Clone.  This feature can be used
        to backup or archive the full image in the new LiveOS storage device.

    --skipcopy
        Skips the copy of the live image to the USB stick, bypassing --format,
        --reset-mbr, --overlay-size-mb, --home-size-mb, --swap-size-mb,
        --copy-overlay, & --copy-home options, if present on the command line.
        (Used to repair disk configuration files or while testing the script,
        in order to avoid repeated and lengthy copy commands.)

    quit
        Interrupts interactive dialog and exits.

    The following options are available through the modified_livecd-iso-to-disk
    shell script provided in the Sugar Clone bundle.

    --format
        Formats the target device and creates an MS-DOS partition table (or GPT
        partition table if --efi is passed).

    --reset-mbr
        Sets the Master Boot Record (MBR) of the target storage device to the
        mbr.bin file from the installation system's syslinux directory.

    --efi
        Creates a GPT partition table when --format is passed, and install a
        hybrid EFI/MBR bootloader on the disk.  This is necessary for most Intel
        Macs.

    --extra-kernel-args <args>
        Specifies additional kernel arguments, <args>, that will be inserted
        into the syslinux and EFI boot configurations.  Multiple arguments
        should be specified in one string, i.e.,
            --extra-kernel-args \"arg1 arg2 ...\"

    --multi
        Used when enabling multi image copies (avoiding configuration of the
        boot files for an arbitrary image).

    --livedir <dir>
        Used with multi image copies to designate the directory <dir> for the
        particular image.

    --compressed   (default state for the operating system files)
        Allows the default compressed SquashFS filesystem image to be copied.
        Has no effect on an already-expanded filesystem copy.

    --skipcompress   (default for when option --xo is specified)
        Installs the operating system into the /LiveOS/ext3fs.img filesystem
        image file.

    --xo
        Used to prepare an image for the OLPC XO-1 laptop and its compressed,
        JFFS2 filesystem.  Do not use the following options with --xo:
            --overlay-size-mb <size>, home-size-mb <size>, --delete-home,
            --copy-home, --copy-overlay, --compressed

    --xo-no-home
        Used together with the --xo option to prepare an image for an OLPC XO
        laptop with the home folder on an SD card instead of the internal NAND
        flash storage.

    --noverify
        Disables the image validation process which occurs before the image is
        installed.  When this option is enabled, the image is not verified
        before loading on the USB storage device.

    --skipcopy
        Skips the copy of the live image to the target stick, bypassing the
        actions of the --format, --overlay-size-mb, --copy-overlay,
        --home-size-mb, --copy-home & --swap-size-mb options, if present on the
        command line. (The --skipcopy option is used while testing the script,
        in order to avoid repeated and lengthy copy commands, or to repair boot
        configuration files.)

    --swap-size-mb <size>
        Sets up a swap file of <size> megabytes (integer values only) on the
        target device.

    --overlay-size-mb <size>
        This option sets the overlay size in megabytes (integer values only).
        The overlay is additional storage available to the live operating system
        if the operating system supports it.  The persistent LiveOS overlay
        holds image-change snapshots (using write-once difference tracking
        storage) in the /LiveOS/overlay-<device_id> file, which, one should
        note, always grows in size due to the storage mechanism.  (The fraction
        of allocated space that has been consumed may be displayed by issueing
        the dmsetup status command in a terminal session of a running LiveOS
        image.)  To conserve this unrecoverable overlay file space, one may
        specify a persistent home folder with the --home-size-mb option (see
        below).  The target storage device must have enough free space for the
        image and the overlay.  There is a maximum <size> of 2047 MB for vfat-
        formatted devices.  If there is insufficient room on your device, you
        will be given information to adjust your settings.

    --copy-overlay
        This option allows one to copy the persistent overlay from one live
        image to the new image.  Changes already made in the source image will
        be propagated to the new installation.
            WARNING: User sensitive information such as password cookies and
            application or user data will be copied to the new image!  Scrub
            this information before using this option.

    --build-message <message>
        This option allows one to update release files to show the non pristine
        status of an image through the build-message, and copydate.  The default
        message is \"by someone, copied on\" which will be appended to the
        standard \"Welcome to <releasename>!\" (skipping the '!') and followed
        by the copy date in 'dd MMM yyyy' format as found in the
        /syslinux/syslinux.cfg or corresponding boot configuration file.

    --releasefile <filepath>
        This option allows one to update a particular release file to show the
        non-pristine status of an image through the build-message, and copydate.
        The default message is \"by someone, copied on\" which will prepended
        the designated file with the line,
        \"Remix of <releasename> <build-message> \" followed by the copy date
        in 'dd MMM yyyy' format.

    --delete-home
        Must be explicitly selected when options --home-size-mb <size> or
        --copy-home are selected and there is an existing persistent home
        directory on the image.

    --home-size-mb <size>
        Sets the home directory size in megabytes (integer values only).  A
        persistent home directory will be made in the /LiveOS/home.img
        filesystem image file.  This file space is encrypted by default, but not
        compressed  (one may bypass encryption with the --unencrypted-home
        installation option).  Files in this home folder may be erased to
        recover storage space.  The target storage device must have enough free
        space for the image, any overlay, and the home directory.  Note that
        --delete-home must also be selected to replace an existing persistent
        home with a new, empty one.  There is a maximum <size> of 2047 MB for
        vfat-formatted devices.  If there is insufficient room on your device,
        you will be given information to adjust your settings.

    --copy-home
        This option allows one to copy a persistent home folder from one LiveOS
        image to the target image.  Changes already made in the source image
        home directory will be propagated to the new image.
            WARNING: User sensitive information such as password cookies and
            user and application data will be copied to the new image! Scrub
            this information before using this option.

    --force
        This option allows one to bypass the user confirmation for the deletion
        of the LiveOS directory on the target device, if one exists.

    --encrypted-home   (default that only applies to new, home-size-mb requests)
        Allows the default option to encrypt a new, persistent home directory.
        Has no effect on a copied home directory.

    --unencrypted-home
        Prevents the default option to encrypt a new, persistent home directory.
        Has no effect on a copied home directory.


    CONTRIBUTORS

    SugarClone: Frederick Grose, Thomas Gilliard, and others.

    livecd-iso-to-disk: David Zeuthen, Jeremy Katz, Douglas McClendon,
                        Chris Curran and other contributors.
                        (See the AUTHORS file in the source distribution for
                        the complete list of credits.)

    BUGS

    Report bugs to the mailing list
    http://lists.sugarlabs.org/mailman/listinfo/soas or directly to
    http://bugs.sugarlabs.org against the soas component.

    COPYRIGHT

    Copyright (C) Sugar Labs 2010 and various contributors. This is free
    software. You may redistribute copies of it under the terms of the
    GNU General Public License, http://www.gnu.org/licenses/gpl.html.
    There is NO WARRANTY, to the extent permitted by law.

    SEE ALSO

    livecd-creator, project website http://fedoraproject.org/wiki/FedoraLiveCD
    "
    exit 1
}

declare -a inputArgs
declare -a USB_SDdevices
declare -a USB_SDdev
declare -a liveArgs
declare -a cloneArgs
declare -a see

thisScriptPath="$1"
shift

installOptions="$*"

TMPDIR=${TMPDIR:-/tmp}

scriptDirectory=$(dirname "$thisScriptPath")
scriptName=$(basename "$thisScriptPath")

releaseFile1=/etc/fedora-release
releaseFile2=/boot/olpc_build

cleanup() {
    restorekeys
    [[ -d $TARGETMNT ]] && ( umount -dl $TARGETMNT && rmdir $TARGETMNT )
    [[ -d $SOURCEMNT && $SOURCEMNT != /mnt/live ]] \
        && ( umount -dl $SOURCEMNT && rmdir $SOURCEMNT )
    [[ $homemnt != /home ]] && ( umount -dl $homemnt && rmdir $homemnt )
    [[ -f ${TMPDIR}/modified_livecd-iso-to-disk ]] && \
        rm ${TMPDIR}/modified_livecd-iso-to-disk
    [[ -f ${TMPDIR}/newSugarStick ]] && rm ${TMPDIR}/newSugarStick
    [[ -f ${TMPDIR}/SugarCellar ]] && rm ${TMPDIR}/SugarCellar
    [[ -f ${TMPDIR}/launcher ]] && rm ${TMPDIR}/launcher
    [[ -f ${TMPDIR}/prependedFile ]] && rm ${TMPDIR}/prependedFile
}

exitclean() {
    echo -e "\n   Cleaning up to exit..."
    cleanup
    echo -e "   Waiting for devices to settle...\n"
    /sbin/udevadm settle
    sleep 5
    if [[ $1 -eq 0 ]]; then
        echo -e "   Done... You may use your Sugar Clone now!\n"
    fi
    exit "${1:-1}"
}

restorekeys() {
    if [[ -z $keepuser ]]; then
        [[ -f $SOURCEMNT/owner.key ]] && \
            mv $SOURCEMNT/owner.key $homemnt/liveuser/.sugar/default/owner.key
        [[ -f $SOURCEMNT/owner.key.pub ]] && \
            mv $SOURCEMNT/owner.key.pub \
                $homemnt/liveuser/.sugar/default/owner.key.pub
        [[ -f $homemnt/liveuser/.sugar/default/owner.key ]] && \
          chown liveuser:liveuser\
            $homemnt/liveuser/.sugar/default/owner.key &> /dev/null
        [[ -f $homemnt/liveuser/.sugar/default/owner.key.pub ]] && \
          chown liveuser:liveuser\
            $homemnt/liveuser/.sugar/default/owner.key.pub &> /dev/null
        [[ -f $homemnt/liveuser/.sugar/default/owner.key ]] && \
          chmod 600 $homemnt/liveuser/.sugar/default/owner.key
        [[ -f $homemnt/liveuser/.sugar/default/owner.key.pub ]] && \
          chmod 644 $homemnt/liveuser/.sugar/default/owner.key.pub
    fi
    
    [[ -f ${releaseFile1}.bak ]] && mv -fT "${releaseFile1}.bak" $releaseFile1
    [[ -f ${releaseFile2}.bak ]] && mv -fT "${releaseFile2}.bak" $releaseFile2

    [[ -f ${BOOTCONFIG}.bak ]] && mv -fT ${BOOTCONFIG}.bak $BOOTCONFIG
    [[ -f ${BOOTCONFIG_EFI}.bak ]] && mv -fT ${BOOTCONFIG_EFI}.bak \
        $BOOTCONFIG_EFI
    sync
}

keepuser=
LIVEOS=LiveOS
homemnt=/home
builder=someone
SOURCEMNT=
SOURCE=/dev/live

baditem=

processArgs() {
    squigleline="≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈\
    \b\b\b\b≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈"
    
    until [[ $# -eq 0 ]]; do
        case $1 in
        --image)
            SOURCE=$(readlink -f "$2")
            if [[ ! -b $SOURCE ]]; then
                see[1]="--> $SOURCE is not a valid source image.
                Please adjust this command requirement.\n\n"
                baditem="$baditem $2"
                see[3]="$baditem"               
            else
                cloneArgs[0]="$1"
                cloneArgs[1]="$2"
                SOURCEMNT=
            fi
            shift
            ;;
        x--image)
            SOURCE=/dev/live
            if ! [[ -b $SOURCE ]]; then
                see[1]="\
 --> The default image source, $SOURCE, is invalid at this time.\n\n
     Please adjust this by providing new --image <source> options.\n\n"
                baditem="$baditem $SOURCE"
                see[3]="$baditem"
            else
                cloneArgs[0]=
                cloneArgs[1]=
            fi
            ;;
        --partition)
            partitionNum="$2"
            cloneArgs[2]="$1"
            cloneArgs[3]="$2"
            shift ;;
        x--partition)
            partitionNum=1
            cloneArgs[2]=
            cloneArgs[3]=
            ;;
        --builder)
            builder=$2
            cloneArgs[4]="$1"
            cloneArgs[5]="$2"
            shift ;;
        x--builder)
            builder=someone
            cloneArgs[4]=
            cloneArgs[5]=
            ;;
        --keepuser)
            keepuser="1" ;;
        x--keepuser)
            keepuser=
            ;;
        --skipcopy)
            skipcopy=1
            liveArgs[15]="$1" ;;
        x--skipcopy)
            skipcopy= ; liveArgs[15]=
            ;;
        --help)
            usage | less
            exit 1
            ;;
        quit)
            exit 1
            ;;  
                    *)
            see[2]="${see[2]}\r --> You entered INVALID option/argument(s):"
            baditem="$baditem $1"
            see[3]="$baditem"
            ;;
        esac
        if [[ -n $baditem ]]; then       
            echo -en "\a $baditem"
        fi
        shift
    done
    if [[ -n $baditem ]]; then
        see[0]="$brief$squigleline\n
           --> (Scroll up, if needed, to see usage information.) <--\n\n"
        see[4]="\n\n        Please try again.\n
     These options/arguments are acceptable: ${cloneArgs[*]}  ${liveArgs[*]}"
        see[5]="\n
 --> Please Enter replacements for just the baditem option/argument(s), OR\n
     just press 'Enter' to ignore those.\n
     (You may Enter additional option/arguments, OR override any by
     entering that option with an 'x' prefix, such as this: x--skipcopy.)
        To exit altogether, Enter: quit\n"
        echo -e "${see[*]}"
        read -p " --> Go ahead here: " -a inputArgs
        clear
        baditem=
        see[1]=
        [[ -n ${inputArgs[*]} ]] && processArgs "${inputArgs[@]}"
    fi
}

defaultArgs="--noverify --copy-overlay --delete-home --copy-home "
installOptions=$defaultArgs

if [[ $# -gt 0 ]]; then
    case "$1" in
    --skipcopy|--image|--partition|--builder|--keepuser|--help|quit)
        inputArgs=( "$*" )
        processArgs "$@"
        installOptions=${defaultArgs}${liveArgs[*]}
        ;;
    *)
        processArgs "$@"
        ;;
    esac
fi
echo -e "\n       clone options: ${cloneArgs[*]}
   installer options: ${liveArgs[*]}"
           
findStorageDevices() {
    declare -i i=0
    declare -i media_size

    for udi in $(/usr/bin/hal-find-by-capability --capability storage)
    do
        device=$(hal-get-property --udi $udi --key block.device)
        vendor=$(hal-get-property --udi $udi --key storage.vendor)
        model=$(hal-get-property --udi $udi --key storage.model)
        bus=$(hal-get-property --udi $udi --key storage.bus)
        if [[ $bus == usb || $bus == mmc ]]
        then
            parent_udi=$(hal-find-by-property --key block.storage_device \
                --string $udi)
            mount=$(hal-get-property --udi $parent_udi --key volume.mount_point\
                2>/dev/null)
            label=$(hal-get-property --udi $parent_udi --key volume.label \
                2>/dev/null)
            media_size=$(hal-get-property --udi $udi --key \
                storage.removable.media_size 2>/dev/null)
            if [[ $media_size -gt 0 ]] ; then
                size=$(dc <<< "8k 10 0.05 $media_size 1024 1024 1024 **/+*p")
                size=$(dc <<< "1k $size 10 /p")
                [[ ${size:0:1} == . ]] && size=0$size
                if [[ $mount = /mnt/live ]]; then
                    echo -e "\n   This Live USB/SD device was detected:\n
            \r       $bus..$vendor..$model..$device..$mount..$label..$size-GiB "
                else
                    d="$bus..$vendor..$model..$device..$mount..$label..$size"
                    USB_SDdevices[$i]="${d// /.}-GiB "
                    USB_SDdev[$i]=$device
                    ((i++))
                fi
            fi
        fi       
    done
    USB_SDdevices[$i]="EXIT"
}

selectAdevice() {
    select myChoice in ${USB_SDdevices[*]}
    do
        case $myChoice in
        "EXIT")
            echo -e "\n   OK, we will exit.\n"
            exitclean -1 ;;
        "")
            echo -e "   Invalid entry.\r\a"
            continue
            ;;
        *)
            ;;
        esac 
        echo -e "   You chose: $myChoice\n
           choice # $REPLY, ${USB_SDdev[$REPLY-1]}\n"
        # test if running in a live image
        if [[ -b /dev/live ]]; then
            TARGETDEV=${USB_SDdev[$REPLY-1]}
            SOURCEMNT=/mnt/live
            SOURCE=/dev/live
            break
        elif [[ -z $SOURCEMNT ]]; then
            TARGETDEV=${USB_SDdev[$REPLY-1]}
            unset USB_SDdevices[$REPLY-1]
            USB_SDdevices=(${USB_SDdevices[*]})
            unset USB_SDdev[$REPLY-1]
            USB_SDdev=(${USB_SDdev[*]})
            prompt="\n   Choose the Source USB/SD device that has the image \
            \b\b\b\b\b\b\b\b\b\b\b\bto propagate:\n\n   > "
            PS3=$(echo -en "$prompt")
            break
        else
            break
        fi
    done
    # query for image source, if needed
    if [[ -z $SOURCEMNT ]]; then
        SOURCEMNT=From-mktemp
        selectAdevice 
        SOURCE=${USB_SDdev[$REPLY-1]}${partitionNum:-1}
    fi
}

selectDevices() {
    findStorageDevices

    case ${#USB_SDdev[*]} in
    0)
        echo -e "\n   No USB/SD storage devices were detected on your system.\n
        \r   Please check that a device is inserted properly.\n
        \n   To exit, press Ctrl + C\n"
        read -p "   Pause.. You may insert a device now; then press 'Enter'."
        echo -e "\n   ...Waiting 10 seconds to register any new devices."
        sleep 10
        selectDevices
        ;;
    1)
        TARGETDEV=$USB_SDdev
        targetDevice="${USB_SDdevices%EXIT}"
        echo -e "\n   One USB/SD storage device is available:\n
        \r       ${targetDevice//\ /}
        \n\r   That's where we'll load the Sugar Clone.\n
        \r       ${USB_SDdev}${partitionNum:-1} \n"
        read -s -r -n 1 -t 10 -p "Press 'C' to Continue, any other key to Exit.
        (Automatic continue in 10 seconds...)
        : "
        case "$REPLY" in
        [^cC])
            echo -e "\n\n"
            exit 1
            ;;
        esac
        [[ -b /dev/live ]] &&  SOURCEMNT=/mnt/live
        ;;
    *)
        prompt="\n   Choose the Target USB/SD storage device to be loaded with \
        \b\b\b\b\b\b\b\bthe Sugar Clone:\n\n   > "
        PS3=$(echo -en "$prompt")
        echo -e "\n   The following USB/SD devices were detected:\n"
        selectAdevice
        ;;
    esac  
}

selectDevices

targetPartition=${TARGETDEV}${partitionNum:-1}

TARGETMNT=$(mktemp -d ${TMPDIR}/target.XXXXXX)
# FIXME: assumes partition 1 on TARGETDEV...
mount ${targetPartition} $TARGETMNT || \
    (echo -e "
    PROBLEM: Unable to connect to the filesystem on the Target USB/SD device:
            $targetPartition\n    Exiting..." ; exitclean)
            
trap exitclean SIGINT SIGTERM

cp -fT --preserve=mode,timestamps $thisScriptPath $TARGETMNT/$scriptName
cp -f --preserve=mode,timestamps ${TMPDIR}/SugarCellar $TARGETMNT/

umount $TARGETMNT && rmdir $TARGETMNT
umount $targetPartition &> /dev/null
/sbin/udevadm settle
sleep 2

# adjust syslinux config directory for replication of installed images between \
# filesystem types
checkSyslinuxVersion() {
# FIXME: Assuming no $multi, running on a live image
    multi=""
    LIVEOS=LiveOS
    
    if [[ ! -x /usr/bin/syslinux ]]; then
        echo "   You need to have syslinux installed to run this script"
        exit 1
    fi
    if ! syslinux 2>&1 | grep -qe -d; then
        SYSLINUXPATH=""
    elif [[ -n $multi ]]; then
        SYSLINUXPATH="$LIVEOS/syslinux"
    else
        SYSLINUXPATH="syslinux"
    fi
}

checkSyslinuxVersion

# exclude this when running from a live source image
if [[ ! -b /dev/live ]]; then
    SOURCEMNT=$(mktemp -d ${TMPDIR}/source.XXXXXX)
    homemnt=$(mktemp -d ${TMPDIR}/source.XXXXXX)
    mount ${SOURCE} $SOURCEMNT || \
      (echo -e "
      PROBLEM in connecting to the main filesystem on the Source USB/SD device: 
              $SOURCE\n\    Exiting..." ; exitclean)
    if [[ -s $SOURCEMNT/$LIVEOS/home.img ]]; then
        mount -o loop $SOURCEMNT/$LIVEOS/home.img $homemnt || \
            (echo -e "
      PROBLEM in connecting to the home filesystem on the Source USB/SD device: 
              $SOURCE\n\    Exiting..." ; exitclean)
    else
        : #FIXME connect to persistent overlay
    fi
fi

if ! [[ ${thisScriptPath} -ef $SOURCEMNT/$scriptName ]]; then
    cp -fT --preserve=mode,timestamps $thisScriptPath $SOURCEMNT/$scriptName
fi
cp -f --preserve=mode,timestamps ${TMPDIR}/modified_livecd-iso-to-disk\
    $SOURCEMNT/
cp -f --preserve=mode,timestamps ${TMPDIR}/SugarCellar $SOURCEMNT/

# protect Sugar Learner keys, if requested
if [[ -z $keepuser ]]; then
    [[ -f $homemnt/liveuser/.sugar/default/owner.key ]] && \
        ( cp -fT --preserve=mode,timestamps\
          $homemnt/liveuser/.sugar/default/owner.key $SOURCEMNT/owner.key\
            && rm $homemnt/liveuser/.sugar/default/owner.key )
    [[ -f $homemnt/liveuser/.sugar/default/owner.key.pub ]] && \
        ( cp -fT --preserve=mode,timestamps\
        $homemnt/liveuser/.sugar/default/owner.key.pub $SOURCEMNT/owner.key.pub\
            && rm $homemnt/liveuser/.sugar/default/owner.key.pub )
fi

if [[ -d $SOURCEMNT/isolinux/ ]]; then
    echo "   Source is an iso9660 image."
    BOOTCONFIG=
elif [ -d $SOURCEMNT/$SYSLINUXPATH/ ]; then
    if [[ -f $SOURCEMNT/$SYSLINUXPATH/extlinux.conf ]]; then
        echo "   Source is on a ext234fs partition."
        BOOTCONFIG=$SOURCEMNT/$SYSLINUXPATH/extlinux.conf
    elif [[ -f $SOURCEMNT/$SYSLINUXPATH/syslinux.cfg ]]; then
        echo "   Source is on a vfat partition."
        BOOTCONFIG=$SOURCEMNT/$SYSLINUXPATH/syslinux.cfg
    fi
fi

# Set this to nothing so sed doesn't care
BOOTCONFIG_EFI=
if [[ -n $efi ]];then
    # this is a little ugly, but it gets the "interesting" named config file
    BOOTCONFIG_EFI=$SOURCEMNT/EFI/boot/boot?*.conf
# FIXME: needed?    rm -f $USBMNT/EFI/boot/grub.conf
fi

# Set builder to the Sugar Learner's name if not directed otherwise
if [[ -d $homemnt/liveuser/.gconf/desktop/sugar/user ]]; then
    # check if the gconfdeamon is running 
    gconftool-2 --ping
    if [[ $? -eq 2 ]]; then
        builder=$(gconftool-2 --direct \
     --config-source=xml:readwrite:$homemnt/liveuser/.gconf/desktop/sugar/user \
        --get /nick)
    else
        builder=$(gconftool-2 --get /desktop/sugar/user/nick)
    fi
fi
[[ -z $builder ]] && builder=someone
echo -e "   Builder: $builder"

if [[ -f $BOOTCONFIG ]]; then
    echo "   Updating boot config file."
    # FIXME: adjust menu title / release title fragile to changes in Welcome
    # message and EFI format
    existingTitle=$(grep "menu title" $BOOTCONFIG | awk '{print $5}')
    existingTitle="${existingTitle%\!}"  
    cloneDate=$(date '+%d %b %Y')

    cp -fTp $BOOTCONFIG ${BOOTCONFIG}.bak
    [[ -f "$BOOTCONFIG_EFI" ]] && cp -fTp $BOOTCONFIG_EFI ${BOOTCONFIG_EFI}.bak

    sed -i -e "s/title Welcome to .*/title Welcome to\
 ${existingTitle} in a Sugar Clone by $builder from ${cloneDate}/" \
      $BOOTCONFIG $BOOTCONFIG_EFI
    releaseTitle="Remixed ${existingTitle} in a Sugar Clone prepared by\
 $builder on $cloneDate"

    if [[ -f $releaseFile1 ]]; then
        cp -fTp $releaseFile1 ${releaseFile1}.bak
        echo -e "  $releaseTitle" >> $releaseFile1
    fi
    if [[ -f $releaseFile2 ]]; then
        cp -fTp $releaseFile2 ${releaseFile2}.bak
        echo -e "$releaseTitle" | cat - $releaseFile2 > ${TMPDIR}/prependedFile
        mv -fT ${TMPDIR}/prependedFile $releaseFile2
    fi
fi

if [[ -b /dev/live ]]; then
    freePortion=$(dmsetup status live-rw | awk '{print $4}')

    numerator=$(dc <<< "8k ${freePortion/\/*/} 2048 /p")    
    denominator=$(dc <<< "8k ${freePortion/*\//} 2048 /p")
    freePortion=$(dc <<< "8k 10 0.05 100 1 ${numerator} ${denominator} /-*+*p")
    freePortion=$(dc <<< "1k $freePortion 10 /p")
    denominator=$(dc <<< "8k 10 0.5 ${denominator} +*p")
    denominator=$(dc <<< "0k $denominator 10 /p")
    echo -e "\n   $freePortion % of the $denominator MiBytes allocated in LiveOS
    \r   persistent storage is free on both the Source & Target devices.\n"
fi

if [[ -f $SOURCEMNT/$LIVEOS/home.img ]]; then
    denominator=$(df --block-size=1024 $homemnt/ | \
        awk "/${homemnt//\//\\/}"'/ {print $2;}')
    usedHome=$(df --block-size=1024 $homemnt/ | 
        awk "/${homemnt//\//\\/}"'/ {print $3;}')
    freePortion=$(dc <<< "8k 10 0.05 100 1 $usedHome $denominator /-*+*p" )
    freePortion=$(dc <<< "1k $freePortion 10 /p")
    capacity=$(dc <<< "8k 10 0.5 $denominator 1024 /+*p")
    capacity=$(dc <<< "0k $capacity 10 /p")
    echo -e "
    \r   $freePortion % of the $capacity MiBytes allocated in a persistent
    \r   home directory is free on both the Source & Target devices.\n"
fi    
sync

echo -e "   Calling:
   ${TMPDIR}/modified_livecd-iso-to-disk $installOptions\
 $SOURCE $targetPartition\n"
    
${TMPDIR}/modified_livecd-iso-to-disk $installOptions $SOURCE\
  $targetPartition

exitCode=$?
if [[ $exitCode -gt 0 ]]; then
    echo -e "\n   PROBLEM: Transfer of Sugar Clone failed.\n
    Exit code $exitCode was reported.  Exiting...\n"
fi

exitclean $exitCode
End of newSugarStick
chmod 777 ${TMPDIR}/newSugarStick
cat >|${TMPDIR}/modified_livecd-iso-to-disk <<'End of modified_livecd-iso-to-disk'
#!/bin/bash
# version date: 2010-07-19 23:35:09 -0400

# Convert a Live media image so that it's bootable off of a USB/SD stick
# Copyright 2007  Red Hat, Inc.
# Jeremy Katz <katzj@redhat.com>
#
# overlay/persistence enhancements by Douglas McClendon <dmc@viros.org>
# GPT+MBR hybrid enhancements by Stewart Adam <s.adam@diffingo.com>
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

export PATH=/sbin:/usr/sbin:$PATH
export \
   PS4='+(${LINENO}:${BASH_SOURCE}:${EUID}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'

shortusage() {
    echo "
    SYNTAX

    livecd-iso-to-disk [--help] [--format] [--reset-mbr] [--efi]
                       [--extra-kernel-args <args>] [--multi] [--livedir <dir>]
                       [--compressed] [--skipcompress] [--swap-size-mb <size>]
                       [--xo] [--xo-no-home] [--noverify] [--skipcopy]
                       [--overlay-size-mb <size>] [--copy-overlay]
                       [--builder-message <message>] [--releasefile <filepath>]
                       [--delete-home] [--force] [--home-size-mb <size>]
                       [--copy-home] [--encrypted-home] [--unencrypted-home]
                       <source> <target_device>

    (Enter livecd-iso-to-disk --help on the command line for more information.)"
}

usage() {
    echo "
    "
    shortusage
    echo "
    livecd-iso-to-disk  -  Convert a Live CD/DVD/USB image so that it's bootable
                           off of a USB/SD stick

    The script may be run in simplest form with just the two arguments:

             <source>
                 This may be the filesystem path to a LiveOS .iso image file,
                 such as from a CD-ROM, DVD, or download.  It could also be the
                 device node reference for the mount point of another LiveOS
                 filesystem, including the currently-running one (such as a
                 booted Live CD/DVD/USB, where /dev/live would reference the
                 device).

             <target_device>
                 This should be the device partition name for the attached,
                 target device, such as /dev/sdb1 or /dev/sdc1.  Issue the
                 df -Th command to get a listing of the mounted partitions,
                 where you can confirm the filesystem types, available space,
                 and device names.  Be careful to specify the correct device,
                 or you may lose important data!

    To execute the script to completion, you will need to run it with root user
    permissions.
    SYSLINUX must be installed on the computer running the installation script.

    DESCRIPTION

    livecd-iso-to-disk installs a Live CD/DVD/USB image (LiveOS) onto a USB/SD
    storage device (or any storage partition that will boot with a SYSLINUX
    bootloader).  The target storage device can then boot the installed
    operating system on systems that support booting via the USB or the SD
    interface.  The script requires a source, LiveOS image and a target, storage
    device.  The source image may be either a LiveOS .iso file, the
    currently-running LiveOS image, or the device node reference for the mount
    point of an installed LiveOS image.  If the operating system supports
    persistent overlays for saving system changes, a fresh overlay, or a copy of
    the source overlay may be included with the installation.  This enables one
    to easily prepare customized LiveOS images for redistribution.

    Unless you request the --format option, the installation does not destroy
    data outside of the LiveOS, syslinux, EFI, & boot folders on your target
    device.  This allows one to maintain other files on the target disk outside
    of the LiveOS filesystem.

    LiveOS images provide embedded filesystems through the Device-mapper
    component of the Linux kernel.  The embedded filesystems exist within files
    such as /LiveOS/squashfs.img (the default compressed storage) or
    /LiveOS/ext3fs.img (an uncompressed version) on the primary volume partition
    of the storage device.  In use, these are read-only filesystems. Optionally,
    one may specify a persistent LiveOS overlay to hold image-change snapshots
    (that use write-once difference tracking storage) in the
    /LiveOS/overlay-<device_id> file, which--one should note--always grow in
    size due to the storage mechanism.  (The fraction of allocated space that
    has been consumed by system activity and changes may be displayed by issuing
    the dmsetup status command in a terminal session of a running LiveOS image.)
    To conserve the unrecoverable, overlay file space, one may specify a
    persistent home folder, which will exist in a /LiveOS/home.img filesystem
    image file.  This file space is encrypted by default, but is not compressed
    (one may bypass encryption with the --unencrypted-home installation option).
    Files in this home folder may be erased to recover storage space.  The
    home.img file is also convenient for backing up or swapping user account
    files.

    Customized images are made by copying the source image filesystems to the
    bootable primary volume partition of another USB/SD device and adjusting the
    Syslinux boot configuration and overlay files to reflect the new device
    identification.

    OPTIONS

    --help
        Displays usage information and exits.

    --format
        Formats the target device and creates an MS-DOS partition table (or GPT
        partition table if --efi is passed).

    --reset-mbr
        Sets the Master Boot Record (MBR) of the target storage device to the
        mbr.bin file from the installation system's syslinux directory.

    --efi
        Creates a GPT partition table when --format is passed, and install a
        hybrid EFI/MBR bootloader on the disk.  This is necessary for most Intel
        Macs.

    --extra-kernel-args <args>
        Specifies additional kernel arguments, <args>, that will be inserted
        into the syslinux and EFI boot configurations.  Multiple arguments
        should be specified in one string, i.e.,
            --extra-kernel-args \"arg1 arg2 ...\"

    --multi
        Used when enabling multi image copies (avoiding configuration of the
        boot files for an arbitrary image).

    --livedir <dir>
        Used with multi image copies to designate the directory <dir> for the
        particular image.

    --compressed   (default state for the operating system files)
        Allows the default compressed SquashFS filesystem image to be copied.
        Has no effect on an already-expanded filesystem copy.

    --skipcompress   (default for when option --xo is specified)
        Installs the operating system into the /LiveOS/ext3fs.img filesystem
        image file.

    --xo
        Used to prepare an image for the OLPC XO-1 laptop and its compressed,
        JFFS2 filesystem.  Do not use the following options with --xo:
            --overlay-size-mb <size>, home-size-mb <size>, --delete-home,
            --copy-home, --copy-overlay, --compressed

    --xo-no-home
        Used together with the --xo option to prepare an image for an OLPC XO
        laptop with the home folder on an SD card instead of the internal NAND
        flash storage.

    --noverify
        Disables the image validation process which occurs before the image is
        installed.  When this option is enabled, the image is not verified
        before loading on the USB storage device.

    --skipcopy
        Skips the copy of the live image to the target stick, bypassing the
        actions of the --format, --overlay-size-mb, --copy-overlay,
        --home-size-mb, --copy-home & --swap-size-mb options, if present on the
        command line. (The --skipcopy option is used while testing the script,
        in order to avoid repeated and lengthy copy commands, or to repair boot
        configuration files.)

    --swap-size-mb <size>
        Sets up a swap file of <size> megabytes (integer values only) on the
        target device.

    --overlay-size-mb <size>
        This option sets the overlay size in megabytes (integer values only).
        The overlay is additional storage available to the live operating system
        if the operating system supports it.  The persistent LiveOS overlay
        holds image-change snapshots (using write-once difference tracking
        storage) in the /LiveOS/overlay-<device_id> file, which, one should
        note, always grows in size due to the storage mechanism.  (The fraction
        of allocated space that has been consumed may be displayed by issueing
        the dmsetup status command in a terminal session of a running LiveOS
        image.)  To conserve this unrecoverable overlay file space, one may
        specify a persistent home folder with the --home-size-mb option (see
        below).  The target storage device must have enough free space for the
        image and the overlay.  There is a maximum <size> of 2047 MB for vfat-
        formatted devices.  If there is insufficient room on your device, you
        will be given information to adjust your settings.

    --copy-overlay
        This option allows one to copy the persistent overlay from one live
        image to the new image.  Changes already made in the source image will
        be propagated to the new installation.
            WARNING: User sensitive information such as password cookies and
            application or user data will be copied to the new image!  Scrub
            this information before using this option.

    --build-message <message>
        This option allows one to update release files to show the non pristine
        status of an image through the build-message, and copydate.  The default
        message is \"by someone, copied on\" which will be appended to the
        standard \"Welcome to <releasename>!\" (skipping the '!') and followed
        by the copy date in 'dd MMM yyyy' format as found in the
        /syslinux/syslinux.cfg or corresponding boot configuration file.

    --releasefile <filepath>
        This option allows one to update a particular release file to show the
        non-pristine status of an image through the build-message, and copydate.
        The default message is \"by someone, copied on\" which will prepended
        the designated file with the line,
        \"Remix of <releasename> <build-message> \" followed by the copy date
        in 'dd MMM yyyy' format.

    --delete-home
        Must be explicitly selected when options --home-size-mb <size> or
        --copy-home are selected and there is an existing persistent home
        directory on the image.

    --home-size-mb <size>
        Sets the home directory size in megabytes (integer values only).  A
        persistent home directory will be made in the /LiveOS/home.img
        filesystem image file.  This file space is encrypted by default, but not
        compressed  (one may bypass encryption with the --unencrypted-home
        installation option).  Files in this home folder may be erased to
        recover storage space.  The target storage device must have enough free
        space for the image, any overlay, and the home directory.  Note that
        --delete-home must also be selected to replace an existing persistent
        home with a new, empty one.  There is a maximum <size> of 2047 MB for
        vfat-formatted devices.  If there is insufficient room on your device,
        you will be given information to adjust your settings.

    --copy-home
        This option allows one to copy a persistent home folder from one LiveOS
        image to the target image.  Changes already made in the source image
        home directory will be propagated to the new image.
            WARNING: User sensitive information such as password cookies and
            user and application data will be copied to the new image! Scrub
            this information before using this option.

    --force
        This option allows one to bypass the user confirmation for the deletion
        of the LiveOS directory on the target device, if one exists.

    --encrypted-home   (default that only applies to new, home-size-mb requests)
        Allows the default option to encrypt a new, persistent home directory.
        Has no effect on a copied home directory.

    --unencrypted-home
        Prevents the default option to encrypt a new, persistent home directory.
        Has no effect on a copied home directory.

    CONTRIBUTORS

    livecd-iso-to-disk: David Zeuthen, Jeremy Katz, Douglas McClendon,
                        Chris Curran and other contributors.
                        (See the AUTHORS file in the source distribution for
                        the complete list of credits.)

    BUGS

    Report bugs to the mailing list
    http://admin.fedoraproject.org/mailman/listinfo/livecd or directly to
    Bugzilla http://bugzilla.redhat.com/bugzilla/ against the Fedora product,
    and the livecd-tools component.

    COPYRIGHT

    Copyright (C) Fedora Project 2008, 2009, 2010 and various contributors.
    This is free software. You may redistribute copies of it under the terms of
    the GNU General Public License http://www.gnu.org/licenses/gpl.html.
    There is NO WARRANTY, to the extent permitted by law.

    SEE ALSO

    livecd-creator, project website http://fedoraproject.org/wiki/FedoraLiveCD
    "
    exit 1
}

TMPDIR=${TMPDIR:-/tmp}

cleanup() {
    sleep 2
    [[ -d $SRCMNT ]] && umount $SRCMNT && rmdir $SRCMNT
    [[ -d $TGTMNT ]] && umount $TGTMNT && rmdir $TGTMNT
}

exitclean() {
    echo "Cleaning up to exit..."
    cleanup
    exit 1
}

getdisk() {
    DEV=$1

    if [[ $DEV =~ /dev/loop* ]]; then
       device="$DEV"
       return
    fi

    p=$(udevadm info -q path -n $DEV)
    if [ -e /sys/$p/device ]; then
        device=$(basename /sys/$p)
    else
        device=$(basename $(readlink -f /sys/$p/../))
    fi
    if [[ ! -e /sys/block/$device ]] || [[ ! -e /dev/$device ]]; then
        echo "Error finding block device of $DEV.  Aborting!"
        exitclean
    fi

    device="/dev/$device"
    # FIXME: weird dev names could mess this up I guess
    p=/dev/$(basename $p)
    partnum=${p##$device}
}

resetMBR() {
    if [[ $DEV =~ /dev/loop* ]]; then
        return
    fi
    getdisk $1
    # if efi, we need to use the hybrid MBR
    if [[ -n $efi ]]; then
        if [[ -f /usr/lib/syslinux/gptmbr.bin ]]; then
            gptmbr='/usr/lib/syslinux/gptmbr.bin'
        elif [[ -f /usr/share/syslinux/gptmbr.bin ]]; then
            gptmbr='/usr/share/syslinux/gptmbr.bin'
        else
            echo "Could not find gptmbr.bin (syslinux)."
            exitclean
        fi
        # our magic number is LBA-2, offset 16 - (512+512+16)/$bs
        dd if=$device bs=16 skip=65 count=1 | cat $gptmbr - > $device
    else
        if [[ -f /usr/lib/syslinux/mbr.bin ]]; then
            cat /usr/lib/syslinux/mbr.bin > $device
        elif [[ -f /usr/share/syslinux/mbr.bin ]]; then
            cat /usr/share/syslinux/mbr.bin > $device
        else
            echo "Could not find mbr.bin (syslinux)."
            exitclean
        fi
    fi
}

checkMBR() {
    if [[ $DEV =~ /dev/loop* ]]; then
        return 0
    fi
    getdisk $1

    bs=$(mktemp /tmp/bs.XXXXXX)
    dd if=$device of=$bs bs=512 count=1 2>/dev/null || exit 2
    mbrword=$(hexdump -n 2 $bs | head -n 1 | awk {'print $2;'})
    rm -f $bs
    if [[ $mbrword = 0000 ]]; then
        echo -e "MBR appears to be blank.
        \rDo you want to replace the MBR on this device?\n
        \rPress Enter to continue, or Ctrl-c to abort."
        read
        resetMBR $1
    fi
    return 0
}

checkPartActive() {
    dev=$1
    getdisk $dev
    # if we're installing to whole-disk and not a partition, then we
    # don't need to worry about being active
    if [[ $dev = $device ]]; then
        return
    fi
    if [[ $dev =~ /dev/loop* ]]; then
        return
    fi
    if [[ $(/sbin/fdisk -l $device 2>/dev/null | \
            grep $dev | awk {'print $2;'}) != * ]]; then
        echo -e "Partition isn't marked bootable!
        \rYou can mark the partition as bootable with
        \r    # /sbin/parted $device
        \r    (parted) toggle N boot
        \r    (parted) quit"
        exitclean
    fi
}

checkLVM() {
    dev=$1

    if [[ -x /sbin/pvs ]] && \
       [[ $(/sbin/pvs -o vg_name --noheadings $dev* 2>/dev/null) ]]; then
        echo -e "Device, $dev, contains a volume group and cannot be formated!
        \rYou can remove the volume group using vgremove."
        exitclean
    fi
    return 0
}

createGPTLayout() {
    dev=$1
    getdisk $dev

    echo -e "WARNING: THIS WILL DESTROY ANY DATA ON $device!!!
    \rPress Enter to continue, or Ctrl-c to abort."
    read
    umount ${device}? &> /dev/null
    /sbin/parted --script $device mklabel gpt
    partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit b print" | \
               grep ^$device:)
    size=$(echo $partinfo | cut -d : -f 2 | sed -e 's/B$//')
    /sbin/parted --script $device unit b mkpart '"EFI System Partition"'\
                          fat32 17408 $(($size - 17408)) set 1 boot on
    TGTDEV=${device}1
    # Sometimes automount can be _really_ annoying.
    echo "Waiting for devices to settle..."
    /sbin/udevadm settle
    sleep 5
    umount $TGTDEV &> /dev/null
    /sbin/mkdosfs -n LIVE $TGTDEV
    TGTLABEL="UUID=$(/sbin/blkid -s UUID -o value $TGTDEV)"
}

createMSDOSLayout() {
    dev=$1
    getdisk $dev

    echo -e "WARNING: THIS WILL DESTROY ANY DATA ON $device!!!\n
    \rPress Enter to continue, or Ctrl-c to abort."
    read
    umount ${device}? &> /dev/null
    /sbin/parted --script $device mklabel msdos
    partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit b print" | \
               grep ^$device:)
    size=$(echo $partinfo | cut -d : -f 2 | sed -e 's/B$//')
    /sbin/parted --script $device unit b mkpart primary fat32 17408 \
                          $(($size - 17408)) set 1 boot on
    TGTDEV=${device}1
    # Sometimes automount can be _really_ annoying.
    echo "Waiting for devices to settle..."
    /sbin/udevadm settle
    sleep 5
    umount $TGTDEV &> /dev/null
    /sbin/mkdosfs -n LIVE $TGTDEV
    TGTLABEL="UUID=$(/sbin/blkid -s UUID -o value $TGTDEV)"
}

checkGPT() {
    dev=$1
    getdisk $dev

    if [[ $(/sbin/fdisk -l $device 2>/dev/null | grep -c GPT) -eq 0 ]]; then
        echo -e "EFI boot requires a GPT partition table.
        \rThis can be done manually, or you can run with --format"
       exitclean
    fi

    partinfo=$(LC_ALL=C /sbin/parted --script -m $device "print" | \
                   grep ^$partnum:)
    volname=$(echo $partinfo | cut -d : -f 6)
    flags=$(echo $partinfo | cut -d : -f 7)
    if [[ $volname != "EFI System Partition" ]]; then
        echo -e "Partition name must be 'EFI System Partition'
        \rThis can be set in parted, or you can run with --reset-mbr."
        exitclean
    fi
    if [[ $(echo $flags | grep -c boot) = 0 ]]; then
        echo "Partition isn't marked bootable!
        \rYou can mark the partition as bootable with
        \r    # /sbin/parted $device
        \r    (parted) toggle N boot
        \r    (parted) quit"
        exitclean
    fi
}

checkFilesystem() {
    dev=$1

    TGTFS=$(/sbin/blkid -s TYPE -o value $dev)
    if [[ $TGTFS != vfat && $TGTFS != msdos && \
          $TGTFS != ext2 && $TGTFS != ext3 ]]; then
        echo "Target filesystem must be vfat or ext[23]."
        exitclean
    fi

    TGTLABEL=$(/sbin/blkid -s UUID -o value $dev)
    if [[ -n $TGTLABEL ]]; then
        TGTLABEL="UUID=$TGTLABEL"
    else
        TGTLABEL=$(/sbin/blkid -s LABEL -o value $dev)
        if [[ -n $TGTLABEL ]]; then
            TGTLABEL="LABEL=$TGTLABEL"
        else
            echo "A filesystem label or UUID is needed for your target device."
            if [[ $TGTFS = vfat || $TGTFS = msdos ]]; then
                echo "Label can be set with /sbin/dosfslabel"
            elif [[ $TGTFS = ext2 || $TGTFS = ext3 ]]; then
                echo "Label can be set with /sbin/e2label"
            fi
            exitclean
        fi
    fi

    if [[ $TGTFS = vfat || $TGTFS = msdos ]]; then
        mountopts="-o shortname=winnt,umask=0077"
    fi
}

checkSyslinuxVersion() {
    if [[ ! -x /usr/bin/syslinux ]]; then
        echo "You need to have syslinux installed to run this script."
        exit 1
    fi
    if ! syslinux 2>&1 | grep -qe -d; then
        SYSLINUXPATH=""
    elif [[ -n $multi ]]; then
        SYSLINUXPATH="$LIVEOS/syslinux"
    else
        SYSLINUXPATH="syslinux"
    fi
}

checkMounted() {
    dev=$1
    if grep -q "^$dev " /proc/mounts ; then
        echo "$dev is mounted, please unmount for safety."
        exitclean
    fi
    if grep -q "^$dev " /proc/swaps; then
        echo "$dev is in use as a swap device, please disable swap."
        exitclean
    fi
}

checkint() {
    if [[ ! $1 -gt 0 ]] 2>/dev/null ; then
        shortusage
        echo "ERROR: $1 is not a valid <size> value."
        exit 1
    fi
}

if [[ $(id -u) != 0 ]]; then
    echo "You need to be root to run this script."
    exit 1
fi

detectsrctype() {
    if [[ -e $SRCMNT/LiveOS/squashfs.img || \
          -e $SRCMNT/LiveOS/ext3fs.img ]]; then
        srctype=live
        return
    fi
    if [[ -e $SRCMNT/images/install.img ]]; then
        srctype=installer
        return
    fi
    echo "ERROR: $SRC does not appear to be a Live image or DVD installer."
    exitclean
}

cryptedhome=1
keephome=1
homesizemb=0
copyhome=
copyhomesize=0
swapsizemb=0
overlaysizemb=0
copyoverlaysize=0
buildermessage=
buildmessage="by someone, copied on"
srctype=
LIVEOS=LiveOS

HOMEFILE="home.img"
while [[ $# -gt 2 ]]; do
    case $1 in
    --help)
        usage
        ;;
    --overlay-size-mb)
        checkint $2
        overlaysizemb=$2
        shift
        ;;
    --copy-overlay)
        copyoverlay=1
        ;;
    --home-size-mb)
        checkint $2
        homesizemb=$2
        shift
        ;;
    --copy-home)
        copyhome=1
        cryptedhome=""
        ;;
    --builder-message)
        buildermessage=1
        buildmessage=$2
        shift
        ;;
    --releasefile)
        buildermessage=1
        releasefile=$2
        shift
        ;;
    --swap-size-mb)
        checkint $2
        swapsizemb=$2
        shift
        ;;
    --encrypted-home|--crypted-home)
        cryptedhome=1
        ;;
    --unencrypted-home)
        cryptedhome=""
        ;;
    --delete-home)
        keephome=""
        ;;
    --noverify)
        noverify=1
        ;;
    --reset-mbr|--resetmbr)
        resetmbr=1
        ;;
    --efi|--mactel)
        efi=1
        ;;
    --format)
        format=1
        ;;
    --skipcopy)
        skipcopy=1
        ;;
    --xo)
        xo=1
        skipcompress=1
        ;;
    --xo-no-home)
        xonohome=1
        ;;
    --compressed|--compress)
        skipcompress=""
        ;;
    --skipcompress)
        skipcompress=1
        ;;
    --extra-kernel-args)
        kernelargs=$2
        shift
        ;;
    --force)
        force=1
        ;;
    --livedir)
        LIVEOS=$2
        shift
        ;;
    --multi)
        multi=1
        ;;
    *)
        shortusage
        echo -e "Invalid argument:  $1 \n"
        exit 1
        ;;
    esac
    shift
done

SRC=$(readlink -f "$1")
TGTDEV=$(readlink -f "$2")

if [[ -z $SRC ]]; then
    shortusage
    echo -e "ERROR: You haven't specified a source image in <source>.
       Please adjust this command requirement.\n"
    exit 1
fi

if [[ ! -b $SRC && ! -f $SRC ]]; then
    shortusage
    echo -e "ERROR: $SRC is not a valid source image.
       Please adjust this command requirement.\n"
    exit 1
fi

# FIXME: If --format is given, we shouldn't care and just use /dev/foo1
if [[ -z $TGTDEV || ! -b $TGTDEV ]]; then
    shortusage
    echo -e "ERROR: $TGTDEV is not a valid target.
       Please adjust this command requirement.\n"
    exit 1
fi

# do some basic sanity checks.  
checkMounted $TGTDEV
if [[ -n $format ]]; then
    checkLVM $TGTDEV
    # checks for a valid filesystem
    if [[ -n $efi ]]; then
        createGPTLayout $TGTDEV
    else
        createMSDOSLayout $TGTDEV
    fi
fi
checkFilesystem $TGTDEV
if [[ -n $efi ]]; then
    checkGPT $TGTDEV
fi
checkSyslinuxVersion
# Because we can't set boot flag for EFI Protective on msdos partition tables
[[ -z $efi ]] && checkPartActive $TGTDEV
[[ -n $resetmbr ]] && resetMBR $TGTDEV
checkMBR $TGTDEV

if [[ $SRC = $TGTDEV ]]; then
    echo -e "Source and destination images are on the same device partition.
    \rPlease check your inputs.\n"
    exitclean
fi

if [[ $overlaysizemb -gt 0 && $TGTFS = vfat ]]; then
    if [[ $overlaysizemb -gt 2047 ]]; then
        echo "A persistent overlays may not exceed 2047 MB on VFAT filesystems.
        "
        exitclean
    fi
fi

if [[ $homesizemb -gt 0 && $TGTFS = vfat ]]; then
    if [[ $homesizemb -gt 2047 ]]; then
        echo -e "A home.img file may not exceed 2047 MB on VFAT filesystems.\n"
        exitclean
    fi
fi

if [[ $swapsizemb -gt 0 && $TGTFS = vfat ]]; then
    if [[ $swapsizemb -gt 2047 ]]; then
        echo -e "A swap file may not exceed 2047 MB on VFAT filesystems.\n"
        exitclean
    fi
fi

# FIXME: would be better if we had better mountpoints
SRCMNT=$(mktemp -d /media/srctmp.XXXXXX)
mount -o loop,ro "$SRC" $SRCMNT || exitclean
TGTMNT=$(mktemp -d /media/tgtdev.XXXXXX)
mount $mountopts $TGTDEV $TGTMNT || exitclean

trap exitclean SIGINT SIGTERM

detectsrctype

SOURCEOVERLAY="overlay-$( /sbin/blkid -s LABEL -o value $SRC )\
-$( /sbin/blkid -s UUID -o value $SRC )"
TGTOVERFILE="overlay-$( /sbin/blkid -s LABEL -o value $TGTDEV )\
-$( /sbin/blkid -s UUID -o value $TGTDEV )"
if [[ -d $SRCMNT/LiveOS ]]; then
    check=$SRCMNT/LiveOS
else
    check=$SRCMNT
fi
if [[ ! -f $SRCMNT/$LIVEOS/$HOMEFILE && -n $copyhome ]]; then
    echo -e "ERROR: There appears to be no persistent /home.img on the source
       Please check your inputs.\n"
    exitclean
fi
if [[ -f $SRCMNT/$LIVEOS/$HOMEFILE && -n $copyhome && -n $cryptedhome ]]; then
    echo -e "WARNING: You asked for an --encrypted-home and to copy the source's
         /home.img to your target device.  The --encrypted-home option is only
         available for newly-created /home directories.  (If the /home.img on
         the source is encrypted, that feature will carry over.)\n
         Press Enter to continue, or Ctrl-c to abort.\n"
    read
fi
if [[ -f $TGTMNT/$LIVEOS/$HOMEFILE && -n $keephome && $homesizemb -gt 0 ]]; then
    echo -e "ERROR: The target has an existing /home and you requested that a
       new /home.img be created.
       To remove an existing /home on the target, you must explicitly specify
       --delete-home.
       Please adjust your home options.\n"
    exitclean
fi
if [[ -f $TGTMNT/$LIVEOS/$HOMEFILE && -n $keephome && -n $copyhome && \
      -s $SRCMNT/$LIVEOS/$HOMEFILE ]]; then
    echo -e "ERROR: The target has an existing /home and you requested that one
       from the source be copied to the target device.
       To remove an existing /home on the target, you must explicitly specify
       --delete-home.
       Please adjust your home options.\n"
    exitclean
fi
if [[ -f $SRCMNT/$LIVEOS/$SOURCEOVERLAY && -n $copyoverlay && \
         $overlaysizemb -gt 0 ]]; then
    echo "ERROR: You requested a new overlay AND a copy of one from the source.
       Please request only one of these options.
    "
    exitclean
fi
if [[ -s $SRCMNT/$LIVEOS/$HOMEFILE && -n $copyhome && $homesizemb -gt 0 ]]; then
    echo -e "ERROR: You requested a new home AND a copy of one from the source.
       Please request only one of these options.\n"
    exitclean
fi
if [[ ! -s $check/$SOURCEOVERLAY && -n $copyoverlay ]]; then
    echo "NOTICE: There appears to be no persistent overlay file on this image.
    Would you LIKE to continue with NO persistent overlay?

    Press Enter to continue, or Ctrl-c to abort.
    "
    read
    copyoverlay=""
fi
if [[ ! -s $check/$HOMEFILE && -n $copyhome && $overlaysizemb -gt 0 ]]; then
    echo -e "NOTICE: There appears to be no persistent /home.img on this image.
        Would you LIKE to continue with just the persistent overlay?\n
        Press Enter to continue, or Ctrl-c to abort.\n"
    read
    copyhome=""
fi
if [[ -n $efi && ! -d $SRCMNT/EFI/boot ]]; then
  echo -e "ERROR: This live image does not support EFI booting.\n"
  exitclean
fi

# let's try to make sure there's enough room on the stick

if [[ -d $TGTMNT/$LIVEOS ]]; then
    tbd=$(du -s -B 1M $TGTMNT/$LIVEOS | awk {'print $1;'})
    [[ -f $TGTMNT/$LIVEOS/$HOMEFILE ]] && \
        homesz=$(du -s -B 1M $TGTMNT/$LIVEOS/$HOMEFILE | awk {'print $1;'})
    [[ -n $homesz && -n $keephome ]] && tbd=$(($tbd - $homesz))
    [[ -f $TGTMNT/$LIVEOS/$TGTOVERFILE ]] && \
        oversz=$(du -s -B 1M $TGTMNT/$LIVEOS/$TGTOVERFILE | awk {'print $1;'})
    [[ -n $oversz && -n $keepoverlay ]] && tbd=$(($tbd - $oversz))
else
    tbd=0
fi
livesize=$(du -s -B 1M $check | awk {'print $1;'})
if [[ -n $skipcompress ]]; then
    if [[ -e $SRCMNT/LiveOS/squashfs.img ]]; then
        if mount -o loop $SRCMNT/LiveOS/squashfs.img $SRCMNT; then
            livesize=$(du -s -B 1M $SRCMNT/LiveOS/ext3fs.img | awk {'print $1;'})
            umount $SRCMNT
        else
            echo "WARNING: --skipcompress or --xo was specified but the
            currently-running kernel can not mount the SquashFS from the source
            file to extract it.  Instead, the compressed SquashFS will be copied
            to the target device."
            skipcompress=""
        fi
    fi
fi
if [[ -s $check/$SOURCEOVERLAY ]]; then
    copyoverlaysize=$(du -s -B 1M $check/$SOURCEOVERLAY | awk {'print $1;'})
fi
if [[ -s $check/$HOMEFILE ]]; then
    copyhomesize=$(du -s -B 1M $check/$HOMEFILE | awk {'print $1;'})
fi
if [[ -s $check/ext3fs.img ]]; then
    livesize=$(du -s -B 1M $check/ext3fs.img | awk {'print $1;'})
else
    livesize=$(($livesize - $copyoverlaysize - $copyhomesize))
    [[ -z $copyoverlay ]] && copyoverlaysize=0
    [[ -z $copyhome ]] && copyhomesize=0
fi
free=$(df  -B1M $TGTDEV  |tail -n 1 |awk {'print $4;'})

if [[ $srctype = live ]]; then
    tba=$(($overlaysizemb + $copyoverlaysize + $homesizemb + $copyhomesize\
    + $livesize + $swapsizemb))
    if [ $tba -gt $(($free + $tbd)) ]; then
        echo -e "  The live image + overlay, home, & swap space, if requested,
        \r  will NOT fit in the space available on the target device.\n
        \r+ Size of live image:  $livesize  MB"
        [[ $overlaysizemb -gt 0 ]] && \
            echo "+ Overlay size:  $overlaysizemb  MB"
        [[ $copyoverlaysize -gt 0 ]] && \
            echo "+ Copy overlay size:  $copyoverlaysize  MB"
        [[ $homesizemb -gt 0 ]] && \
            echo "+ Home directory size:  $homesizemb  MB"
        [[ $copyhomesize -gt 0 ]] && \
            echo "+ Copy home directory size:  $copyhomesize  MB"
        [[ $swapsizemb -gt 0 ]] && \
            echo "+ Swap overlay size:  $swapsizemb  MB"
        echo "---------------------------"
        echo "= Requested:  $tba  MB"
        echo "- Available:  $(($free + $tbd))  MB"
        echo "---------------------------"
        echo -e "  To fit on this device,
        \r= free or decrease the requested size total by:  $(($tba - $free -\
                                                              $tbd))  MB"
        exitclean
    fi
fi

# Verify available space for DVD installer 
if [[ $srctype = installer ]]; then
    srcsize=$(du -s -B 1M $SRC | awk {'print $1;'})
    installimgsize=$(du -s -B 1M $SRCMNT/images/install.img | awk {'print $1;'})
    tbd=0
    if [[ -e $TGTMNT/images/install.img ]]; then
        tbd=$(du -s -B 1M $TGTMNT/images/install.img | awk {'print $1;'})
    fi
    if [[ -e $TGTMNT/$(basename $SRC) ]]; then
        tbd=$(($tbd + $(du -s -B 1M $TGTMNT/$(basename $SRC) | \
                awk {'print $1;'})))
    fi
    echo -e "Size of DVD image: $srcsize  MB
    \rSize of install.img: $installimgsize  MB
    \rAvailable space: $(($free + $tbd))  MB"
    if [[ $(($srcsize + $installimgsize)) -gt $(($free + $tbd)) ]]; then
        echo -e "ERROR: Unable to fit the DVD image + install.img in the
        \r       available space on the target device.\n"
        exitclean
    fi
fi

# this is delayed until now so other goof-ups may be corrected before waiting
# through the md5 verification.
if [[ -z $noverify ]]; then
    # verify the image
    echo "Verifying image..."
    checkisomd5 --verbose "$SRC"
    if [[ $? -ne 0 ]]; then
        echo -e "Are you SURE you want to continue?\n
        \rPress Enter to continue, or Ctrl-c to abort.\n"
        read
    fi
fi

if [[ -z $skipcopy && $srctype = live ]]; then
    if [[ -d $TGTMNT/$LIVEOS && -z $force ]]; then
        echo "Already set up as live image."
        if [[ -z $keephome && -e $TGTMNT/$LIVEOS/$HOMEFILE ]]; then
            echo -e "WARNING: Persistent /home will be deleted!!!\n
            \rPress Enter to continue, or Ctrl-c to abort.\n"
            read
        else
            echo "Deleting old OS in fifteen seconds..."
            sleep 15

            [[ -e $TGTMNT/$LIVEOS/$HOMEFILE && -n $keephome ]] && \
                mv $TGTMNT/$LIVEOS/$HOMEFILE $TGTMNT/$HOMEFILE
        fi

        rm -rf $TGTMNT/$LIVEOS
    fi
fi

# Bootloader is always reconfigured, so keep these out of the if skipcopy stuff.
[[ ! -d $TGTMNT/$SYSLINUXPATH ]] && mkdir -p $TGTMNT/$SYSLINUXPATH
[[ -n $efi && ! -d $TGTMNT/EFI/boot ]] && mkdir -p $TGTMNT/EFI/boot

# Live image copy
if [[ -z $skipcopy && $srctype = live ]]; then
    echo "Copying live image to target device."
    [[ ! -d $TGTMNT/$LIVEOS ]] && mkdir $TGTMNT/$LIVEOS
    [[ -n $keephome && -f $TGTMNT/$HOMEFILE ]] && \
        mv $TGTMNT/$HOMEFILE $TGTMNT/$LIVEOS/$HOMEFILE
    if [[ -n $skipcompress && -f $SRCMNT/LiveOS/squashfs.img ]]; then
        mount -o loop $SRCMNT/LiveOS/squashfs.img $SRCMNT || exitclean
        cp $SRCMNT/LiveOS/ext3fs.img $TGTMNT/$LIVEOS/ext3fs.img || \
           { umount $SRCMNT ; exitclean ;}
        umount $SRCMNT
    elif [[ -f $SRCMNT/LiveOS/squashfs.img ]]; then
        cp $SRCMNT/LiveOS/squashfs.img $TGTMNT/$LIVEOS/squashfs.img || exitclean
    elif [[ -f $SRCMNT/LiveOS/ext3fs.img ]]; then
        cp $SRCMNT/LiveOS/ext3fs.img $TGTMNT/$LIVEOS/ext3fs.img || exitclean
    fi
    if [[ -f $SRCMNT/LiveOS/osmin.img ]]; then
        cp $SRCMNT/LiveOS/osmin.img $TGTMNT/$LIVEOS/osmin.img || exitclean
    fi
    if [[ -n $copyoverlay && -s $SRCMNT/$LIVEOS/$SOURCEOVERLAY ]]; then
        cp $SRCMNT/$LIVEOS/$SOURCEOVERLAY $TGTMNT/$LIVEOS/$TGTOVERFILE || \
            exitclean
      echo "Copied overlay."
    fi
    if [[ -n $copyhome && -s $SRCMNT/$LIVEOS/$HOMEFILE ]]; then
        cp $SRCMNT/$LIVEOS/$HOMEFILE $TGTMNT/$LIVEOS/$HOMEFILE || exitclean
        echo "Copied home."
    fi
fi
# Copy this installer script. Provide the means for the new or refreshed
#   installation to replicate itself.
thisScriptPath=$(readlink -f $0)
cp -fTp $thisScriptPath $TGTMNT/$LIVEOS/livecd-iso-to-disk &> /dev/null

# DVD installer copy
if [[ -z $skipcopy && $srctype = installer ]]; then
      echo "Copying DVD image to target device."
      mkdir -p $TGTMNT/images/
      cp $SRCMNT/images/install.img $TGTMNT/images/install.img || exitclean
      cp $SRC $TGTMNT/
fi

# adjust syslinux sources for replication of installed images between filesystem
#   types
if [[ -d $SRCMNT/isolinux/ ]]; then
    cp $SRCMNT/isolinux/* $TGTMNT/$SYSLINUXPATH
elif [[ -d $SRCMNT/syslinux/ ]]; then
    cp $SRCMNT/syslinux/* $TGTMNT/$SYSLINUXPATH
    if [[ -f $SRCMNT/syslinux/extlinux.conf ]]; then
        mv $TGTMNT/$SYSLINUXPATH/extlinux.conf \
           $TGTMNT/$SYSLINUXPATH/isolinux.cfg
    elif [[ -f $SRCMNT/syslinux/syslinux.cfg ]]; then
        mv $TGTMNT/$SYSLINUXPATH/syslinux.cfg $TGTMNT/$SYSLINUXPATH/isolinux.cfg
    fi
fi

BOOTCONFIG=$TGTMNT/$SYSLINUXPATH/isolinux.cfg
# Set this to nothing so sed doesn't care
BOOTCONFIG_EFI=
if [[ -n $efi ]]; then
    cp $SRCMNT/EFI/boot/* $TGTMNT/EFI/boot

    # this is a little ugly, but it gets the "interesting" named config file
    BOOTCONFIG_EFI=$TGTMNT/EFI/boot/boot?*.conf
    rm -f $TGTMNT/EFI/boot/grub.conf
fi

# restore boot config file to base state before updating
sed -i -e "s/root=[^ ]*/root=CDLABEL=name/"\
       -e "s/liveimg .* quiet/liveimg quiet/" $BOOTCONFIG $BOOTCONFIG_EFI

echo "Updating boot config file."
# adjust label and fstype
sed -i -e "s/CDLABEL=[^ ]*/$TGTLABEL/"\
       -e "s/rootfstype=[^ ]*/rootfstype=$TGTFS/"\
       -e "s/LABEL=[^ ]*/$TGTLABEL/"\
     $BOOTCONFIG $BOOTCONFIG_EFI
if [[ -n $kernelargs ]]; then
    sed -i -e "s/liveimg/liveimg ${kernelargs}/" $BOOTCONFIG $BOOTCONFIG_EFI
fi
if [[ $LIVEOS != LiveOS ]]; then
    sed -i -e "s;liveimg;liveimg live_dir=$LIVEOS;" $BOOTCONFIG $BOOTCONFIG_EFI
fi

# DVD Installer
if [[ $srctype = installer ]]; then
    sed -i -e "s;initrd=initrd.img;initrd=initrd.img repo=hd:$TGTLABEL:/;g"\
         $BOOTCONFIG $BOOTCONFIG_EFI
    sed -i -e "s;stage2=\S*;;g" $BOOTCONFIG $BOOTCONFIG_EFI
fi

if [[ -z $skipcopy && $overlaysizemb -gt 0 ]]; then
    echo "Initializing persistent overlay file."
    if [[ $TGTFS = vfat ]]; then
        # vfat can't handle sparse files
        dd if=/dev/zero of=$TGTMNT/$LIVEOS/$TGTOVERFILE\
           count=$overlaysizemb bs=1M
    else
        dd if=/dev/null of=$TGTMNT/$LIVEOS/$TGTOVERFILE\
           count=1 bs=1M seek=$overlaysizemb
    fi
fi

# include these with --skipcopy boot reconfiguration to support boot file repair
if [[ -s $TGTMNT/$LIVEOS/$TGTOVERFILE ]]; then
    sed -i -e "s/liveimg/liveimg overlay=${TGTLABEL}/"\
         $BOOTCONFIG $BOOTCONFIG_EFI
    sed -i -e "s/\ ro\ /\ rw\ /" $BOOTCONFIG  $BOOTCONFIG_EFI
fi

if [[ -z $skipcopy && $swapsizemb -gt 0 ]]; then
    echo "Initializing swap file."
    dd if=/dev/zero of=$TGTMNT/$LIVEOS/swap.img count=$swapsizemb bs=1M
    mkswap -f $TGTMNT/$LIVEOS/swap.img
fi

if [[ -z $skipcopy && $homesizemb -gt 0 ]]; then
    echo "Initializing persistent /home."
    homesource=/dev/zero
    [[ -n $cryptedhome ]] && homesource=/dev/urandom
    if [[ $TGTFS = vfat ]]; then
        # vfat can't handle sparse files
        dd if=${homesource} of=$TGTMNT/$LIVEOS/$HOMEFILE count=$homesizemb bs=1M
    else
        dd if=/dev/null of=$TGTMNT/$LIVEOS/$HOMEFILE\
           count=1 bs=1M seek=$homesizemb
    fi
    if [[ -n $cryptedhome ]]; then
        loop=$(losetup -f)
        losetup $loop $TGTMNT/$LIVEOS/$HOMEFILE
        setupworked=1
        until [[ ${setupworked} == 0 ]]; do
            echo "Encrypting persistent /home."
            cryptsetup luksFormat -y -q $loop
            setupworked=$?
        done
        setupworked=1
        until [[ ${setupworked} == 0 ]]; do
            echo "Please enter the password again to unlock the device."
            cryptsetup luksOpen $loop EncHomeFoo
            setupworked=$?
        done
        mke2fs -j /dev/mapper/EncHomeFoo
        tune2fs -c0 -i0 -ouser_xattr,acl /dev/mapper/EncHomeFoo
        sleep 2
        cryptsetup luksClose EncHomeFoo
        losetup -d $loop
    else
        echo "Formatting unencrypted /home."
        mke2fs -F -j $TGTMNT/$LIVEOS/$HOMEFILE
        tune2fs -c0 -i0 -ouser_xattr,acl $TGTMNT/$LIVEOS/$HOMEFILE
    fi
fi

# Update release files to show the non pristine status, build-message, and
#  copydate.
if [[ -n $buildermessage && -f $BOOTCONFIG ]]; then
    echo "   Updating boot config file."
    releasefile0=/etc/fedora-release
    # FIXME: adjust menu title / release title - fragile to changes in Welcome
    # message and EFI format
    existingTitle=$(grep "menu title" $BOOTCONFIG | awk '{print $5}')
    existingTitle="${existingTitle%\!}"
    cloneDate=$(date '+%d %b %Y')

    cp -fTp $BOOTCONFIG ${BOOTCONFIG}.bak
    [[ -f $BOOTCONFIG_EFI ]] && cp -fTp $BOOTCONFIG_EFI ${BOOTCONFIG_EFI}.bak

    sed -i -e "s/title Welcome to .*/\
 title Welcome to ${existingTitle} $buildmessage ${cloneDate}/" \
         $BOOTCONFIG $BOOTCONFIG_EFI
    releaseTitle="Remix of ${existingTitle} $buildmessage $cloneDate"

    if [[ -f $releasefile0 ]]; then
        cp -fTp $releasefile0 ${releasefile0}.bak
        echo -e "  $releaseTitle" >> $releasefile0
    fi
    if [[ -f $releasefile ]]; then
        cp -fTp $releasefile ${releasefile}.bak
        echo -e "$releaseTitle" | cat - $releasefile > ${TMPDIR}/prependedFile
        mv -fT ${TMPDIR}/prependedFile $releasefile
    fi
fi

# create the forth files for booting on the XO if requested
# we'd do this unconditionally, but you have to have a kernel that will
# boot on the XO anyway.
if [[ -n $xo ]]; then
    echo "Setting up /boot/olpc.fth file."
    args=$(egrep "^[ ]*append" $TGTMNT/$SYSLINUXPATH/isolinux.cfg | \
            head -n1 | sed -e 's/.*initrd=[^ ]*//')
    if [[ -z $xonohome && ! -f $TGTMNT/$LIVEOS/$HOMEFILE ]]; then
        args="$args persistenthome=mtd0"
    fi
    args="$args reset_overlay"
    xosyspath=$(echo $SYSLINUXPATH | sed -e 's;/;\\;')
    if [[ ! -d $TGTMNT/boot ]]; then
        mkdir -p $TGTMNT/boot
    fi
    cat > $TGTMNT/boot/olpc.fth <<EOF
\ Boot script for target boot
hex  rom-pa fffc7 + 4 \$number drop  h# 2e19 < [if]
  patch 2drop erase claim-params
  : high-ramdisk  ( -- )
     cv-load-ramdisk
     h# 22c +lp l@ 1+   memory-limit  umin  /ramdisk - ffff.f000 and ( new-ramdisk-adr )
     ramdisk-adr over  /ramdisk move                    ( new-ramdisk-adr )
     to ramdisk-adr
  ;
  ' high-ramdisk to load-ramdisk
[then]

: set-bootpath-dev  ( -- )
   " /chosen" find-package  if                       ( phandle )
      " bootpath" rot  get-package-property  0=  if  ( propval$ )
         get-encoded-string                          ( bootpath$ )
         [char] \ left-parse-string  2nip            ( dn$ )
         dn-buf place                                ( )
      then
   then

   " /sd"  dn-buf  count  sindex  0>=   if
          " sd:"
   else
          " u:"
   then
   " BOOTPATHDEV" \$set-macro
;

set-bootpath-dev
" $args" to boot-file
" \${BOOTPATHDEV}$xosyspath\initrd0.img" expand$ to ramdisk
" \${BOOTPATHDEV}$xosyspath\vmlinuz0" expand$ to boot-device
unfreeze
boot
EOF

fi

if [[ -z $multi ]]; then
    echo "Installing boot loader."
    if [[ -n $efi ]]; then
    # replace the ia32 hack
        if [[ -f $TGTMNT/EFI/boot/boot.conf ]]; then
            cp -f $TGTMNT/EFI/boot/bootia32.conf $TGTMNT/EFI/boot/boot.conf
        fi
    fi

  # this is a bit of a kludge, but syslinux doesn't guarantee the API for its
  #  com32 modules :/
    if [[ -f $TGTMNT/$SYSLINUXPATH/vesamenu.c32 && \
          -f /usr/share/syslinux/vesamenu.c32 ]]; then
        cp /usr/share/syslinux/vesamenu.c32 $TGTMNT/$SYSLINUXPATH/vesamenu.c32
    elif [[ -f $TGTMNT/$SYSLINUXPATH/vesamenu.c32 && \
            -f /usr/lib/syslinux/vesamenu.c32 ]]; then
        cp /usr/lib/syslinux/vesamenu.c32 $TGTMNT/$SYSLINUXPATH/vesamenu.c32
    elif [[ -f $TGTMNT/$SYSLINUXPATH/menu.c32 && \
            -f /usr/share/syslinux/menu.c32 ]]; then
        cp /usr/share/syslinux/menu.c32 $TGTMNT/$SYSLINUXPATH/menu.c32
    elif [[ -f $TGTMNT/$SYSLINUXPATH/menu.c32 && \
            -f /usr/lib/syslinux/menu.c32 ]]; then
        cp /usr/lib/syslinux/menu.c32 $TGTMNT/$SYSLINUXPATH/menu.c32
    fi

    if [[ $TGTFS = vfat || $TGTFS = msdos ]]; then
    # syslinux expects the config to be named syslinux.cfg 
    # and has to run with the file system unmounted
        mv $TGTMNT/$SYSLINUXPATH/isolinux.cfg $TGTMNT/$SYSLINUXPATH/syslinux.cfg
    # deal with mtools complaining about ldlinux.sys
        if [[ -f $TGTMNT/$SYSLINUXPATH/ldlinux.sys ]]; then
            rm -f $TGTMNT/$SYSLINUXPATH/ldlinux.sys
        fi
        cleanup
        if [[ -n $SYSLINUXPATH ]]; then
            syslinux -d $SYSLINUXPATH $TGTDEV
        else
            syslinux $TGTDEV
        fi
    elif [[ $TGTFS = ext2 || $TGTFS = ext3 ]]; then
    # extlinux expects the config to be named extlinux.conf
    # and has to be run with the file system mounted
        mv $TGTMNT/$SYSLINUXPATH/isolinux.cfg \
            $TGTMNT/$SYSLINUXPATH/extlinux.conf
        extlinux -i $TGTMNT/$SYSLINUXPATH
        chattr -i $TGTMNT/$SYSLINUXPATH/extlinux.sys
        cleanup
    fi
else
  # we need to do some more config file tweaks for multi-image mode
    sed -i -e "s;kernel vm;kernel /$LIVEOS/syslinux/vm;"\
         $TGTMNT/$SYSLINUXPATH/isolinux.cfg
    sed -i -e "s;initrd=i;initrd=/$LIVEOS/syslinux/i;"\
         $TGTMNT/$SYSLINUXPATH/isolinux.cfg
    mv $TGTMNT/$SYSLINUXPATH/isolinux.cfg $TGTMNT/$SYSLINUXPATH/syslinux.cfg
    cleanup
fi

echo -e "\nTarget device is now set up with a Live image!\n"
End of modified_livecd-iso-to-disk
chmod 777 ${TMPDIR}/modified_livecd-iso-to-disk
cat >|${TMPDIR}/SugarCellar <<'End of SugarCellar'
#!/bin/bash
#  version date: 2010-06-13 22:36:00 -0400  
#  
#  'SugarCellar' reports on the availability of storage on a live 'Sugar on a
#   Stick' image. 
#
#  Copyright 2010, Sugar Labs
#  Frederick Grose <fgrose@sugarlabs.org>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; version 2 of the License.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU Library General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

export PATH=/sbin:/usr/sbin:$PATH
export \
   PS4='+(${LINENO}:${BASH_SOURCE}:${EUID}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'

SOURCEMNT=/mnt/live
LIVEOS=LiveOS

if [[ -b /dev/live ]]; then
    freePortion=$(su --session-command="dmsetup status live-rw | \
        awk '{print \$4}' " root)
fi

echo -e "\n   Your Sugar Cellar storage space:\n"

if [[ -n "$freePortion" ]]; then
    numerator=$(dc <<< "8k ${freePortion/\/*/} 2048 /p")    
    denominator=$(dc <<< "8k ${freePortion/*\//} 2048 /p")
    freePortion=$(dc <<< "8k 10 0.05 100 1 ${numerator} ${denominator} /-*+*p")
    freePortion=$(dc <<< "1k $freePortion 10 /p")
    denominator=$(dc <<< "8k 10 0.5 ${denominator} +*p")
    denominator=$(dc <<< "0k $denominator 10 /p")
    echo -e "   $freePortion % of the $denominator MiBytes allocated in LiveOS
    \r   persistent storage is free on this device.\n"
fi

if [[ -f $SOURCEMNT/$LIVEOS/home.img ]]; then
    denominator=$(df --block-size=1024 /home/ | awk '/home/ {print $2;}')
    usedHome=$(df --block-size=1024 /home/ | awk '/home/ {print $3;}')
    freePortion=$(dc <<< "8k 10 0.05 100 1 $usedHome $denominator /-*+*p" )
    freePortion=$(dc <<< "1k $freePortion 10 /p")
    capacity=$(dc <<< "8k 10 0.5 $denominator 1024 /+*p")
    capacity=$(dc <<< "0k $capacity 10 /p")
    echo -e "   $freePortion % of the $capacity MiBytes allocated in a
    \r   persistent home directory is free on this device.\n"
fi

df -Th
echo 

exit 0
End of SugarCellar
chmod 777 ${TMPDIR}/SugarCellar
thisScriptPath=$( readlink -f $0 )
${TMPDIR}/launcher $thisScriptPath $*
exit 0
