#!/bin/bash
#
# To unbundle, bash this file.
#
bundleFileDirectory=$( dirname "$( readlink -f $0 )" )
su --session-command="rm -f ${bundleFileDirectory}/newSugarStick " root
cat >newSugarStick  <<'End of newSugarStick' 
#!/bin/bash
#
#  'SugarClone' copies a live 'Sugar on a Stick' image onto a second device. 
#
#  Copyright 2010, Sugar Labs
#  Frederick Grose <fgrose@sugarlabs.org>
#
#  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}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'

shortusage() {
    brief='
    Short usage information for this program 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]

       Extended:  (not yet supported, except in modified_livecd-iso-to-disk)
       
           SugarClone [--format] [--reset-mbr] [--efi]
                      [--extra-kernel-args <args>] [--multi] [--livedir <dir>]
                      [--compress] [--skipcompress] [--swap-size-mb <size>]
                      [--xo] [--xo-no-home] [--noverify] [--skipcopy]
                      [--overlay-size-mb <size>] [--copy-overlay]
                      [--home-size-mb <size>] [--delete-home] [--copy-home]
                      [--force] [--crypted-home] [--unencrypted-home] [--help]
                      [--image <source>] [--partition <num>]  [--builder <name>]
                      [--skipcopy] [--keepuser] [quit]

    USAGE

    The script may be run in Simplest form with no command-line options.
    This will simply create a SugarClone 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 SugarClone.

    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.

    Extended mode allows one to override the default options.
    Enter any one of the available options before any from the Simple set.
    If --help is entered, this usage document will be displayed.

    REQUIRES

    modified_livecd-iso-to-disk - also available at
                                  http://people.sugarlabs.org/fgrose
                                    
    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'.  Following expansion, newSugarStick is called
    via the switch user, su, command with root priveledges, so that it 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, the newSugarStick script is deleted (Do not run this script in your
    development directory or your working copy will be lost).
    
    'modified_livecd-iso-to-disk' is left in the working directory for
    convenience of further use. All the extended installation options are
    implemented in this script.
    
    SugarClone installs a Live CD/DVD/USB/SD image (LiveOS) onto a USB/SD
    storage device.  The USB/SD storage device can then boot the installed
    operating system on systems that support booting via USB/SD.  SugarClone
    requires a LiveOS .iso image file, or a currently running LiveOS image or an
    installed image mount point, and a target USB/SD storage device.  If the
    operating system supports persistent overlays to save system changes, a
    fresh overlay, or a copy of the currently running overlay may be included in
    the installation.  This enables one to easily prepare customized LiveOS
    images for redistribution.

    Unless you request the --format or --reset-mbr options, 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
    USB/SD 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 or /LiveOS/ext3fs.img on the primary volume
    partition of the storage device.  In use, these are read-only filesystems.
    Optionally, one may specify a persistent home folder, which will exist in a
    /LiveOS/home.img filesystem image file.  Persistent LiveOS overlays hold
    image change snapshots in the /LiveOS/overlay-<device_id> file.

    Customized SugarClones 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.  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 SugarClone is booted, the learner will be asked to
    establish a new identification.  The original learner's Journal is copied
    into the new SugarClone and bears the original learner's color signature.
        (The original ownership keys may be maintained in the new SugarClone 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 SugarClone. Default: someone

    --keepuser
        Specifies that the Sugar learner's Journal identification keys should be
        preserved (copied into) the new SugarClone.  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/SD device.  (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.
        
    --format
        Formats the USB/SD stick 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 USB/SD storage device to the 
        mbr.bin file from the image'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.
        
    --compress   (default option)
        Installs image on a compressed SquashFS filesystem.
        
    --skipcompress   (default for when option --xo is specified)
        Installs the operation system into the /LiveOS/ext3fs.img filesystem
        image file.
        
    --xo
        Used to prepare an image for the OLPC XO 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, --compress
        
    --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   (default)
        Disables the image validation process which occurs before the image is 
        installed.  When this option is enabled, the image is not verified
        before loading onto the USB/SD storage device.
        
    --overlay-size-mb <size>
        This option specifies the creation of a persistent overlay and sets its 
        <size> in MB.  The overlay is additional storage available to the live
        operating system if the operating system supports it.  The USB/SD
        storage device must have enough free space for the image and the
        overlay.  The overlay holds image change snapshots in the
        /LiveOS/overlay-<device_id> file.  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   (default)
        This option allows one to copy a persistent overlay from a running 
        live image to the new SugarClone.  Changes already made in the running 
        image will be propagated to the new installation.  
        WARNING: User sensitive information such as password cookies and 
        activity histories will be copied to the new installation!  Scrub this 
        information before using this option.
        
    --delete-home   (default)
        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>
        Specifies creation of a persistent home directory and sets its size in 
        megabytes.  Note that --delete-home must also be selected to replace an 
        existing persistent home with a new, empty one.  The directory is saved
        in the /LiveOS/home.img file.  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   (default)
        This option allows one to copy a persistent home folder from a running 
        live image to the new SugarClone.  Changes already made in the running 
        image home directory will be propagated to the new installation.  
        WARNING: User sensitive information such as password cookies and 
        activity histories will be copied to the new installation! Scrub this 
        information before using this option.

    --force
        This option allows one to bypass the user confirmation for deletion of 
        an existing home directory on the target device, if one exists.
        
    --crypted-home   (default, if home-size-mb is specified)
        Encrypts a persistent home directory.
        
    --unencrypted-home
        Disables the encryption of the persistent home directory.

    CONTRIBUTORS

    SugarClone: Frederick Grose, Thomas Gilliard, and others.

    livecd-iso-to-disk: David Zeuthen, Jeremy Katz, Douglas McClendon,
                        Chris Curranm 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="$*"

scriptDirectory=$(dirname "$thisScriptPath")

scriptName=$(basename "$thisScriptPath")

releaseFile=/etc/fedora-release

cleanup() {
    echo -e "   Waiting for devices to settle...\n"
    /sbin/udevadm settle
    sleep 5
    [[ -d "$TARGETMNT" ]] && ( umount $TARGETMNT && rmdir $TARGETMNT )
}

exitclean() {
    echo -e "\n   Cleaning up to exit..."
    cleanup
    restorekeys
    [[ -d "$SOURCEMNT" ]] && \
    ( umount -d $SOURCEMNT &> /dev/null && rmdir $SOURCEMNT &> /dev/null )
    if [[ "$1" -eq 0 ]]; then
        echo -e "   Done... You may use your Sugar Clone now!\n"
    fi
    rm ${scriptDirectory}/newSugarStick
    exit "${1:-1}"
}

restorekeys() {
    [[ -f $scriptDirectory/owner.key ]] && \
      mv $scriptDirectory/owner.key $homemnt/liveuser/.sugar/default/owner.key
    [[ -f $scriptDirectory/owner.key.pub ]] && \
      mv $scriptDirectory/owner.key.pub \
      $homemnt/liveuser/.sugar/default/owner.key.pub
    chown liveuser:liveuser $homemnt/liveuser/.sugar/default/owner.key \
      $homemnt/liveuser/.sugar/default/owner.key.pub
    chmod 600 $homemnt/liveuser/.sugar/default/owner.key
    chmod 644 $homemnt/liveuser/.sugar/default/owner.key.pub
    
    [[ -f "${releaseFile}.bak" ]] && mv -fT "${releaseFile}.bak" $releaseFile

    [[ -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
            ;;
        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
    declare -i 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)
            label=$(hal-get-property --udi $parent_udi --key volume.label)
            media_size=$(hal-get-property --udi $udi --key \
                storage.removable.media_size)
            size=$((media_size/(1000*1000*1000)))
            if [[ "$mount" = /mnt/live ]]; then
                echo -e "\n   This Live USB/SD device was detected:\n
             \r       $bus..$vendor..$model..$device..$mount..$label..$size-GB "
            else
                USB_SDdevices[$i]="\
                    $bus..$vendor..$model..$device..$mount..$label..$size-GB "
                USB_SDdev[$i]=$device
                ((i++))
            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"
            exit ;;
        "")
            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[*]})
            echo -e "${USB_SDdevices[@]}"
            unset USB_SDdev[$REPLY-1]
            USB_SDdev=(${USB_SDdev[*]})
            echo -e "${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"
        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 SugarClone.\n
        \r       ${USB_SDdev}${partitionNum:-1} \n"
        [[ -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 SugarClone:\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 /media/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 -f --preserve=mode,timestamps $thisScriptPath $TARGETMNT/$scriptName

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

# protect Sugar Learner keys
[[ -f $homemnt/liveuser/.sugar/default/owner.key ]] && \
    chown root:root $homemnt/liveuser/.sugar/default/owner.key
[[ -f $homemnt/liveuser/.sugar/default/owner.key.pub ]] && \
    chown root:root $homemnt/liveuser/.sugar/default/owner.key.pub
[[ -f $homemnt/liveuser/.sugar/default/owner.key ]] && \
    mv $homemnt/liveuser/.sugar/default/owner.key /mnt/live/owner.key
[[ -f $homemnt/liveuser/.sugar/default/owner.key.pub ]] && \
    mv $homemnt/liveuser/.sugar/default/owner.key.pub /mnt/live/owner.key.pub

# 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

if [[ "$SOURCEMNT" != /mnt/live ]]; then
    SOURCEMNT=$(mktemp -d /media/source.XXXXXX)
    mount ${SOURCE} $SOURCEMNT || \
      (echo -e "
      PROBLEM: Unable to connect to the filesystem on the Source USB/SD device: 
              $SOURCE\n\    Exiting..." ; exitclean)
              
    cp -f --preserve=mode,timestamps $thisScriptPath $SOURCEMNT/$scriptName
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 [[ -z "$keepuser" ]]; 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
    [[ $? -gt 0 ]] && builder=someone
    echo -e "   Builder: $builder"
fi

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}')
#    pattern='\!'
#    existingTitle=${existingTitle:0:((${#existingTitle}-2))}
    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 SugarClone prepared by $builder on ${cloneDate}/" \
      $BOOTCONFIG $BOOTCONFIG_EFI
    releaseTitle="\
   remix of ${existingTitle} in a SugarClone prepared by $builder on $cloneDate"

    if [[ -f "$releaseFile" ]]; then
        cp -fTp $releaseFile ${releaseFile}.bak
        echo -e "$releaseTitle" >> $releaseFile
    fi
fi

sync

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

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

exitclean $exitCode
End of newSugarStick
su --session-command="mv -fT newSugarStick ${bundleFileDirectory}/newSugarStick\
        &> /dev/null " root
su --session-command="chmod +x ${bundleFileDirectory}/newSugarStick " \
        root
su --session-command="rm -f ${bundleFileDirectory}/modified_livecd-iso-to-disk " root
cat >modified_livecd-iso-to-disk  <<'End of modified_livecd-iso-to-disk' 
#!/bin/bash

# Convert a live CD iso so that it's bootable off of a USB 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}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'

shortusage() {
    echo "
    Short usage information for this program follows:
    
    NAME 

    modified_
    livecd-iso-to-disk  -  Convert a Live CD/DVD/USB image so that it's bootable
                           off of a USB stick
    
    SYNTAX

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

    Simplest:
    
    modified_
    livecd-iso-to-disk <source> <target_device>
                       
    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
                 mount point or device reference of another LiveOS filesystem
                 including a currently running one (such as a booted Live
                 CD/DVD/USB where /dev/live would reference the device).  If
                 your source image is on another connected device, you would
                 reference the bootable volume partition mount point, such as
                 /media/usbmnt or /media/<partition_label>, where the label is
                 often the device vendor's name.

             <target_device>
                 This should be the device partition name for the attached,
                 target device, such as /dev/sdb1 or /dev/sdc1.  Issue the df -h
                 command to get a listing of the mounted partitions, where you
                 can confirm the 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.

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

usage() {
    echo "
    "
    shortusage
    echo "
    DESCRIPTION

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

    Unless you request the --format or --reset-mbr options, 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 USB
    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 or /LiveOS/ext3fs.img on the primary volume
    partition of the storage device.  In use, these are read-only filesystems.
    Optionally, one may specify a persistent home folder, which will exist in a
    /LiveOS/home.img filesystem image file.  Persistent LiveOS overlays hold
    image change snapshots in the /LiveOS/overlay-<device_id> file.

    Customized images are made by copying the source image filesystems to the
    bootable primary volume partition of another USB 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 USB stick 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 USB storage device to the 
        mbr.bin file from the image'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.
        
    --compress   (default option)
        Installs image on a compressed SquashFS filesystem.
        
    --skipcompress   (default for when option --xo is specified)
        Installs the operation system into the /LiveOS/ext3fs.img filesystem
        image file.
        
    --xo
        Used to prepare an image for the OLPC XO 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, --compress
        
    --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 USB stick.  (Used to repair disk 
        configuration files or while testing the script in order to avoid
        repeated and lengthy copy commands.)
        
    --overlay-size-mb <size>
        This option specifies the creation of a persistent overlay and sets its 
        <size> in MB.  The overlay is additional storage available to the live
        operating system if the operating system supports it.  The USB storage
        device must have enough free space for the image and the overlay.  The
        overlay holds image change snapshots in the /LiveOS/overlay-<device_id>
        file.  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 
            activity histories will be copied to the new image!  Scrub this 
            information before using this option.
        
    --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>
        Specifies creation of a persistent home directory and sets its size in 
        megabytes.  Note that --delete-home must also be selected to replace an 
        existing persistent home with a new, empty one.  The directory is saved
        in the /LiveOS/home.img file.  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 a one live
        image to the new 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 
            activity histories 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 deletion of 
        an existing home directory on the target device, if one exists.
        
    --crypted-home   (default, if home-size-mb is specified)
        Encrypts a persistent home directory.
        
    --unencrypted-home
        Disables the encryption of the persistent home directory.

    CONTRIBUTORS

    livecd-iso-to-disk: David Zeuthen, Jeremy Katz, Douglas McClendon,
                        Chris Curranm 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
}

cleanup() {
    sleep 2
    [ -d "$CDMNT" ] && umount $CDMNT && rmdir $CDMNT
    [ -d "$USBMNT" ] && umount $USBMNT && rmdir $USBMNT
}

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 -o ! -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 "MBR appears to be blank."
        echo "Do you want to replace the MBR on this device?"
        echo "Press 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 "Partition isn't marked bootable!"
        echo "You can mark the partition as bootable with "
        echo "    # /sbin/parted $device"
        echo "    (parted) toggle N boot"
        echo "    (parted) quit"
        exitclean
    fi
}

createGPTLayout() {
    dev=$1
    getdisk $dev

    echo "WARNING: THIS WILL DESTROY ANY DATA ON $device!!!"
    echo "Press 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
    USBDEV=${device}1
    # Sometimes automount can be _really_ annoying.
    echo "Waiting for devices to settle..."
    /sbin/udevadm settle
    sleep 5
    umount $USBDEV &> /dev/null
    /sbin/mkdosfs -n LIVE $USBDEV
    USBLABEL="UUID=$(/sbin/blkid -s UUID -o value $USBDEV)"
}

createMSDOSLayout() {
    dev=$1
    getdisk $dev

    echo "WARNING: THIS WILL DESTROY ANY DATA ON $device!!!"
    echo "Press 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
    USBDEV=${device}1
    # Sometimes automount can be _really_ annoying.
    echo "Waiting for devices to settle..."
    /sbin/udevadm settle
    sleep 5
    umount $USBDEV &> /dev/null
    /sbin/mkdosfs -n LIVE $USBDEV
    USBLABEL="UUID=$(/sbin/blkid -s UUID -o value $USBDEV)"
}

checkGPT() {
    dev=$1
    getdisk $dev

    if [ "$(/sbin/fdisk -l $device 2>/dev/null |grep -c GPT)" -eq "0" ]; then
       echo "EFI boot requires a GPT partition table."
       echo "This 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 "Partition name must be 'EFI System Partition'"
        echo "This 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!"
        echo "You can mark the partition as bootable with "
        echo "    # /sbin/parted $device"
        echo "    (parted) toggle N boot"
        echo "    (parted) quit"
        exitclean
    fi
}

checkFilesystem() {
    dev=$1

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

    USBLABEL=$(/sbin/blkid -s UUID -o value $dev)
    if [ -n "$USBLABEL" ]; then 
        USBLABEL="UUID=$USBLABEL"; 
    else
        USBLABEL=$(/sbin/blkid -s LABEL -o value $dev)
        if [ -n "$USBLABEL" ]; then 
            USBLABEL="LABEL=$USBLABEL" 
        else
            echo "Need to have a filesystem label or UUID for your USB device"
            if [ "$USBFS" = "vfat" -o "$USBFS" = "msdos" ]; then
                echo "Label can be set with /sbin/dosfslabel"
            elif [ "$USBFS" = "ext2" -o "$USBFS" = "ext3" ]; then
                echo "Label can be set with /sbin/e2label"
            fi
            exitclean
        fi
    fi

    if [ "$USBFS" = "vfat" -o "$USBFS" = "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 ! test $1 -gt 0 2>/dev/null ; then
        echo "ERROR: You must specify a $1 <size> value."
        shortusage
    fi
}

detectisotype() {
    if [ -e $CDMNT/LiveOS/squashfs.img -o -e $CDMNT/LiveOS/ext3fs.img ]; then
        isotype=live
        return
    fi
    if [ -e $CDMNT/images/install.img ]; then
        isotype=installer
        return
    fi
    echo "ERROR: $ISO 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
isotype=
LIVEOS=LiveOS
HOMEFILE="home.img"

while [ $# -gt 2 ]; do
    case $1 in
    --help)
        usage
        ;;
    --format)
        format=1
        ;;
    --reset-mbr|--resetmbr)
        resetmbr=1
        ;;
    --efi|--mactel)
        efi=1
        ;;
    --extra-kernel-args)
        kernelargs=$2
        shift
        ;;
    --multi)
        multi=1
        ;;
    --livedir)
        LIVEOS=$2
        shift
        ;;
    --compress)
        skipcompress=""
        ;;
    --skipcompress)
        skipcompress=1
        ;;
    --swap-size-mb)
        checkint $2
        swapsizemb=$2
        shift
        ;;
    --xo)
        xo=1
        skipcompress=1
        ;;
    --xo-no-home)
        xonohome=1
        ;;
    --noverify)
        noverify=1
        ;;
    --skipcopy)
        skipcopy=1
        ;;
    --overlay-size-mb)
        checkint $2
        overlaysizemb=$2
        shift
        ;;
    --copy-overlay)
        copyoverlay=1
        ;;
    --delete-home)
        keephome=""
        ;;
    --home-size-mb)
        checkint $2
        homesizemb=$2
        shift
        ;;
    --copy-home)
        copyhome=1
        ;;
    --force)
        force=1
        ;;
    --crypted-home)
        cryptedhome=1
        ;;
    --unencrypted-home)
       	cryptedhome=""
        ;;
    *)
        echo "invalid arg -- $1"
        shortusage
        ;;
    esac
    shift
done

ISO=$(readlink -f "$1")
USBDEV=$(readlink -f "$2")

if [ -z "$ISO" ]; then
    echo "ERROR: You haven't specified a source image in <isopath>
    Please adjust this command requirement."
    shortusage
fi

if ! [ -b "$ISO" -o -s "$ISO" ]; then
    echo "$(ISO) is not a valid source image.
    Please adjust this command requirement."
    shortusage
fi

# FIXME: If --format is given, we shouldn't care and just use /dev/foo1
if [ -z "$USBDEV" -o ! -b "$USBDEV" ]; then
    shortusage
fi

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

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

if [ "$ISO" = "$USBDEV" ]; then
    echo "Source and destination images are on the same device partition."
    echo "Please check your inputs."
    exitclean
fi

if [ "$overlaysizemb" -gt 0 -a "$USBFS" = "vfat" ]; then
    if [ "$overlaysizemb" -gt 2047 ]; then
	echo "Can't have an overlay of 2048 MB or greater on VFAT"
	exitclean
    fi
fi

if [ "$homesizemb" -gt 0 -a "$USBFS" = "vfat" ]; then
    if [ "$homesizemb" -gt 2047 ]; then
	echo "Can't have a home overlay greater than 2048 MB on VFAT"
	exitclean
    fi
fi 

if [ "$swapsizemb" -gt 0 -a "$USBFS" = "vfat" ]; then
    if [ "$swapsizemb" -gt 2047 ]; then
        echo "Can't have a swap file greater than 2048 MB on VFAT"
        exitclean
    fi
fi 

# FIXME: would be better if we had better mountpoints
CDMNT=$(mktemp -d /media/cdtmp.XXXXXX)
mount -o loop,ro "$ISO" $CDMNT || exitclean
USBMNT=$(mktemp -d /media/usbdev.XXXXXX)
mount $mountopts $USBDEV $USBMNT || exitclean

trap exitclean SIGINT SIGTERM

detectisotype

if [ -f "$USBMNT/$LIVEOS/$HOMEFILE" -a -n "$keephome" -a "$homesizemb" -gt 0 ]; then
    echo "ERROR: Your target has an existing /home and you requested both keeping
    it and specified a size for a new /home.
    To remove an exiting /home, you must specify --delete-home explicitly.
    Please adjust your home options."
    cleanup
    shortusage
fi

if [ -f "$USBMNT/$LIVEOS/$HOMEFILE" -a -n "$keephome" -a -n "$copyhome" -a -s "$CDMNT/$LIVEOS/$HOMEFILE" ]; then
    echo "ERROR: Your target has an existing /home and you requested both keeping
    it and copying one from the source.
    To remove an exiting /home, you must specify --delete-home explicitly.
    Please adjust your home options."
    cleanup
    shortusage
fi

if [ -z "$noverify" ]; then
    # verify the image
    echo "Verifying image..."
    checkisomd5 --verbose "$ISO"
    if [ $? -ne 0 ]; then
        echo "Are you SURE you want to continue?
        Press Enter to continue or Ctrl-c to abort"
        read
    fi
fi

SOURCEOVERLAY="overlay-$( /sbin/blkid -s LABEL -o value $ISO )-$( /sbin/blkid -s UUID -o value $ISO )"

if [ -f "$CDMNT/$LIVEOS/$SOURCEOVERLAY" -a -n "$copyoverlay" -a "$overlaysizemb" -gt 0 ]; then
    echo "ERROR: You requested both a new overlay and copying one from the source.
    Please request only one of these options."
    cleanup
    shortusage
fi

if [ -s "$CDMNT/$LIVEOS/$HOMEFILE" -a -n "$copyhome" -a "$homesizemb" -gt 0 ]; then
    echo "ERROR: You requested both a new home and copying one from the source.
    Please request only one of these options."
    cleanup
    shortusage
fi

if [ -n "$efi" -a ! -d $CDMNT/EFI/boot ]; then
    echo "ERROR: This live image does not support EFI booting"
    exitclean
fi

# let's try to make sure there's enough room on the stick
if [ -d $CDMNT/LiveOS ]; then
    check=$CDMNT/LiveOS
else
    check=$CDMNT
fi
if [ -d $USBMNT/$LIVEOS ]; then
    tbd=$(du -s -B 1M $USBMNT/$LIVEOS | awk {'print $1;'})
    [ -f $USBMNT/$LIVEOS/$HOMEFILE ] && homesz=$(du -s -B 1M $USBMNT/$LIVEOS/$HOMEFILE | awk {'print $1;'})
    [ -n "$homesz" -a -n "$keephome" ] && tbd=$(($tbd - $homesz))
else
    tbd=0
fi
livesize=$(du -s -B 1M $check | awk {'print $1;'})
if [ -z "$copyoverlay" ]; then
    if [ -s $check/$SOURCEOVERLAY ]; then
        copyoverlaysize=$(du -s -B 1M $check/$SOURCEOVERLAY | awk {'print $1;'})
        livesize=$(($livesize - $copyoverlaysize))
    fi
elif [ ! -s $check/$SOURCEOVERLAY ]; then
    echo "There appears to be no persistent overlay file on this image."
    exitclean
fi
if [ -z "$copyhome" ]; then
    if [ -s $check/$HOMEFILE ]; then
        copyhomesize=$(du -s -B 1M $check/$HOMEFILE | awk {'print $1;'})
        livesize=$(($livesize - $copyhomesize))
    fi
elif [ ! -s $check/$HOMEFILE -a "$copyoverlaysize" -gt 0 ]; then
    echo "There appears to be no persistent /home file on this image.
    Are you SURE you want to continue with just the persistent overlay?
    Press Enter to continue or Ctrl-c to abort."
    read
    copyhome=""
fi
if [ -n "$skipcompress" ]; then
    if [ -e $CDMNT/LiveOS/squashfs.img ]; then
        if mount -o loop $CDMNT/LiveOS/squashfs.img $CDMNT; then
            livesize=$(du -s -B 1M $CDMNT/LiveOS/ext3fs.img | awk {'print $1;'})
            umount $CDMNT
        else
            echo "WARNING: --skipcompress or --xo was specified but the currently
            running kernel can not mount the squashfs from the ISO file to extract
            it. The compressed squashfs will be copied to the USB stick."
            skipcompress=""
        fi
    fi
fi
free=$(df  -B1M $USBDEV  |tail -n 1 |awk {'print $4;'})

if [ "$isotype" = "live" ]; then
    tba=$(($overlaysizemb + $copyoverlaysize + $homesizemb + $copyhomesize + $livesize + $swapsizemb))
    if [ $tba -gt $(($free + $tbd)) ]; then
        echo "Unable to fit live image + overlay on available space on USB stick
        + Size of live image:  $livesize"
        [ "$overlaysizemb" -gt 0 ] && echo "+ Overlay size:  $overlaysizemb"
        [ "$copyoverlaysize" -gt 0 ] && echo "+ Copy overlay size:  $copyoverlaysize"
        [ "$homesizemb" -gt 0 ] && echo "+ Home overlay size:  $homesizemb"
        [ "$copyhomesize" -gt 0 ] && echo "+ Copy home overlay size:  $copyhomesize"
        [ "$swapsizemb" -gt 0 ] && echo "+ Swap overlay size:  $swapsizemb"
        echo "---------------------------
        = Requested:  $tba
        - Available:  $(($free + $tbd))
        ---------------------------
        = To fit, free or decrease requested size total by:  $(($tba - $free - $tbd))"
        exitclean
    fi
fi

# Verify available space for DVD installer 
if [ "$isotype" = "installer" ]; then
    isosize=$(du -s -B 1M $ISO | awk {'print $1;'})
    installimgsize=$(du -s -B 1M $CDMNT/images/install.img | awk {'print $1;'})
    tbd=0
    if [ -e $USBMNT/images/install.img ]; then
        tbd=$(du -s -B 1M $USBMNT/images/install.img | awk {'print $1;'})
    fi
    if [ -e $USBMNT/$(basename $ISO) ]; then
        tbd=$(($tbd + $(du -s -B 1M $USBMNT/$(basename $ISO) | awk {'print $1;'})))
    fi
    echo "Size of DVD image: $isosize
    Size of install.img: $installimgsize
    Available space: $(($free + $tbd))"
    if [ $(($isosize + $installimgsize)) -gt $(($free + $tbd)) ]; then
        echo "ERROR: Unable to fit DVD image + install.img on available space on USB stick"
        exitclean
    fi
fi

if [ -z "$skipcopy" ] && [ "$isotype" = "live" ]; then
    if [ -d $USBMNT/$LIVEOS -a -z "$force" ]; then
        echo "Already set up as live image."  
        if [ -z "$keephome" -a -e $USBMNT/$LIVEOS/$HOMEFILE ]; then
            echo "WARNING: The old persistent /home will be deleted!!!
            Press Enter to continue or Ctrl-c to abort"
            # FIXME: read is not invoke in call through su --session-command=
            read
        else
            echo "Deleting old OS in fifteen seconds..."
            sleep 15
            [ -e "$USBMNT/$LIVEOS/$HOMEFILE" -a -n "$keephome" ] && mv $USBMNT/$LIVEOS/$HOMEFILE $USBMNT/$HOMEFILE
        fi

	rm -rf $USBMNT/$LIVEOS
    fi
fi

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

# copy this installer script to enable the new or refreshed installation to replicate the image
thisScriptPath=$(readlink -f $0)
cp -fTp $thisScriptPath $USBMNT/modified_livecd-iso-to-disk &> /dev/null

# Live image copy
if [ -z "$skipcopy" ] && [ "$isotype" = "live" ]; then
    echo "Copying live image to USB stick"
    [ ! -d $USBMNT/$LIVEOS ] && mkdir $USBMNT/$LIVEOS
    [ -n "$keephome" -a -f "$USBMNT/$HOMEFILE" ] && mv $USBMNT/$HOMEFILE $USBMNT/$LIVEOS/$HOMEFILE
    if [ -n "$skipcompress" -a -f $CDMNT/LiveOS/squashfs.img ]; then
        mount -o loop $CDMNT/LiveOS/squashfs.img $CDMNT || exitclean
        cp $CDMNT/LiveOS/ext3fs.img $USBMNT/$LIVEOS/ext3fs.img || (umount $CDMNT ; exitclean)
        umount $CDMNT
    elif [ -f $CDMNT/LiveOS/squashfs.img ]; then
        cp $CDMNT/LiveOS/squashfs.img $USBMNT/$LIVEOS/squashfs.img || exitclean
    elif [ -f $CDMNT/LiveOS/ext3fs.img ]; then
        cp $CDMNT/LiveOS/ext3fs.img $USBMNT/$LIVEOS/ext3fs.img || exitclean
    fi
    if [ -f $CDMNT/LiveOS/osmin.img ]; then
        cp $CDMNT/LiveOS/osmin.img $USBMNT/$LIVEOS/osmin.img || exitclean
    fi
    if [ -n "$copyoverlay" ]; then
        cp $CDMNT/$LIVEOS/$SOURCEOVERLAY $USBMNT/$LIVEOS/$SOURCEOVERLAY || exitclean
        echo "Copied overlay."
    fi
    if [ -s $CDMNT/$LIVEOS/$HOMEFILE -a -n "$copyhome" ]; then
        cp $CDMNT/$LIVEOS/$HOMEFILE $USBMNT/$LIVEOS/$HOMEFILE || exitclean
        echo "Copied home."
    fi
fi

# DVD installer copy
if [ -z "$skipcopy" ] && [ "$isotype" = "installer" ]; then
    echo "Copying DVD image to USB stick"
    mkdir -p $USBMNT/images/
    cp $CDMNT/images/install.img $USBMNT/images/install.img || exitclean
    cp $ISO $USBMNT/
fi

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

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

    # this is a little ugly, but it gets the "interesting" named config file
    BOOTCONFIG_EFI=$USBMNT/EFI/boot/boot?*.conf
    rm -f $USBMNT/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=[^ ]*/$USBLABEL/" -e "s/rootfstype=[^ ]*/rootfstype=$USBFS/" -e "s/LABEL=[^ ]*/$USBLABEL/" $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 [ "$isotype" = "installer" ]; then
    sed -i -e "s;initrd=initrd.img;initrd=initrd.img repo=hd:$USBLABEL:/;g" $BOOTCONFIG $BOOTCONFIG_EFI
    sed -i -e "s;stage2=\S*;;g" $BOOTCONFIG $BOOTCONFIG_EFI
fi

OVERFILE="overlay-$( /sbin/blkid -s LABEL -o value $USBDEV )-$( /sbin/blkid -s UUID -o value $USBDEV )"
if [ -z "$skipcopy" -a "$overlaysizemb" -gt 0 ]; then
    echo "Initializing persistent overlay file"
    if [ "$USBFS" = "vfat" ]; then
     	# vfat can't handle sparse files
        dd if=/dev/zero of=$USBMNT/$LIVEOS/$OVERFILE count=$overlaysizemb bs=1M
    else
        dd if=/dev/null of=$USBMNT/$LIVEOS/$OVERFILE count=1 bs=1M seek=$overlaysizemb
    fi
elif [ -z "$skipcopy" -a -n "$copyoverlay" ]; then
    if ! ([ -s $USBMNT/$LIVEOS/$SOURCEOVERLAY ] && mv $USBMNT/$LIVEOS/$SOURCEOVERLAY $USBMNT/$LIVEOS/$OVERFILE) ; then
        echo -e "\n   The persistent overlay was missing, had zero length, or failed to be renamed.\n\n
        \r   Please check your source.\n\a"
        exitclean
    fi  
fi

# include these with --skipcopy boot reconfiguration
if [ -s $USBMNT/$LIVEOS/$OVERFILE ]; then
    sed -i -e "s/liveimg/liveimg overlay=${USBLABEL}/" $BOOTCONFIG $BOOTCONFIG_EFI
    sed -i -e "s/\ ro\ /\ rw\ /" $BOOTCONFIG $BOOTCONFIG_EFI
fi

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

if [ -z "$skipcopy" -a "$homesizemb" -gt 0 ]; then
    echo "Initializing persistent /home"
    homesource=/dev/zero
    [ -n "$cryptedhome" ] && homesource=/dev/urandom
    if [ "$USBFS" = "vfat" ]; then
        # vfat can't handle sparse files
        dd if=${homesource} of=$USBMNT/$LIVEOS/$HOMEFILE count=$homesizemb bs=1M
    else
        dd if=/dev/null of=$USBMNT/$LIVEOS/$HOMEFILE count=1 bs=1M seek=$homesizemb
    fi
    if [ -n "$cryptedhome" ]; then
        loop=$(losetup -f)
        losetup $loop $USBMNT/$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 $USBMNT/$LIVEOS/$HOMEFILE
        tune2fs -c0 -i0 -ouser_xattr,acl $USBMNT/$LIVEOS/$HOMEFILE
    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" $USBMNT/$SYSLINUXPATH/isolinux.cfg |head -n1 |sed -e 's/.*initrd=[^ ]*//')
    if [ -z "$xonohome" -a ! -f $USBMNT/$LIVEOS/$HOMEFILE ]; then
        args="$args persistenthome=mtd0"
    fi
    args="$args reset_overlay"
    xosyspath=$(echo $SYSLINUXPATH | sed -e 's;/;\\;')
    if [ ! -d $USBMNT/boot ]; then
    	mkdir -p $USBMNT/boot
    fi
    cat > $USBMNT/boot/olpc.fth <<EOF
\ Boot script for USB 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 "$USBMNT/EFI/boot/boot.conf" ]; then
            cp -f $USBMNT/EFI/boot/bootia32.conf $USBMNT/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 $USBMNT/$SYSLINUXPATH/vesamenu.c32 -a -f /usr/share/syslinux/vesamenu.c32 ]; then
        cp /usr/share/syslinux/vesamenu.c32 $USBMNT/$SYSLINUXPATH/vesamenu.c32
    elif [ -f $USBMNT/$SYSLINUXPATH/vesamenu.c32 -a -f /usr/lib/syslinux/vesamenu.c32 ]; then
        cp /usr/lib/syslinux/vesamenu.c32 $USBMNT/$SYSLINUXPATH/vesamenu.c32
    elif [ -f $USBMNT/$SYSLINUXPATH/menu.c32 -a -f /usr/share/syslinux/menu.c32 ]; then
        cp /usr/share/syslinux/menu.c32 $USBMNT/$SYSLINUXPATH/menu.c32
    elif [ -f $USBMNT/$SYSLINUXPATH/menu.c32 -a -f /usr/lib/syslinux/menu.c32 ]; then
        cp /usr/lib/syslinux/menu.c32 $USBMNT/$SYSLINUXPATH/menu.c32
    fi

    if [ "$USBFS" = "vfat" -o "$USBFS" = "msdos" ]; then
        # syslinux expects the config to be named syslinux.cfg 
        # and has to run with the file system unmounted
        mv $USBMNT/$SYSLINUXPATH/isolinux.cfg $USBMNT/$SYSLINUXPATH/syslinux.cfg
        # deal with mtools complaining about ldlinux.sys
        if [ -f $USBMNT/$SYSLINUXPATH/ldlinux.sys ]; then
            rm -f $USBMNT/$SYSLINUXPATH/ldlinux.sys
        fi
        cleanup
        if [ -n "$SYSLINUXPATH" ]; then
            syslinux -d $SYSLINUXPATH $USBDEV
        else
            syslinux $USBDEV
        fi
    elif [ "$USBFS" = "ext2" -o "$USBFS" = "ext3" ]; then
        # extlinux expects the config to be named extlinux.conf
        # and has to be run with the file system mounted
        mv $USBMNT/$SYSLINUXPATH/isolinux.cfg $USBMNT/$SYSLINUXPATH/extlinux.conf
        extlinux -i $USBMNT/$SYSLINUXPATH
        chattr -i $USBMNT/$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;" $USBMNT/$SYSLINUXPATH/isolinux.cfg
    sed -i -e "s;initrd=i;initrd=/$LIVEOS/syslinux/i;" $USBMNT/$SYSLINUXPATH/isolinux.cfg
    mv $USBMNT/$SYSLINUXPATH/isolinux.cfg $USBMNT/$SYSLINUXPATH/syslinux.cfg
    cleanup
fi

echo "USB stick set up as live image!"
End of modified_livecd-iso-to-disk
su --session-command="mv -fT modified_livecd-iso-to-disk ${bundleFileDirectory}/modified_livecd-iso-to-disk\
        &> /dev/null " root
su --session-command="chmod +x ${bundleFileDirectory}/modified_livecd-iso-to-disk " \
        root
thisScriptPath=$( readlink -f $0 )
su --session-command="${bundleFileDirectory}/newSugarStick $thisScriptPath $@" root
