#!/bin/bash 
# mkbootdev - create a KNOPPIX bootable device

# this script is licensed under the GPL V2

# Martin Oehler <oehler@knopper.net>, Dec 2006
# based on a script from Klaus Knopper <knopper@knopper.net>, Oct 2006

PATH="/bin:/sbin:/usr/bin:/usr/sbin"
export PATH

XDIALOG_HIGH_DIALOG_COMPAT=1
export XDIALOG_HIGH_DIALOG_COMPAT

# Get root
[ "`id -u`" != "0" ] && exec sudo "$0" "$@"

TMP=`mktemp /tmp/mkbootdev.XXXXXX`

bailout(){
touch "$TMP.done" ; wait
rm -f "$TMP" "$TMP.done" "$TMP.err"
umount "$MOUNTPOINT" 2>/dev/null
exit 0
}

DIALOG="dialog"
[ -n "$DISPLAY" ] && [ -x /usr/bin/Xdialog ] && DIALOG="Xdialog --cr-wrap"

trap bailout 1 2 3 15

# LANGUAGE etc.
[ -f /etc/sysconfig/knoppix ] && . /etc/sysconfig/knoppix
[ -z "$LANG" ] && export LANG
[ -z "$LANGUAGE" ] && export LANGUAGE
[ -z "$CHARSET" ] && export CHARSET

let SPACE_NEEDED="$(LANG=C du -scm /cdrom/KNOPPIX | tail -1  | cut -f1)"
let SPACE_NEEDED=$SPACE_NEEDED+10

# Language-dependent Messages
case "$LANGUAGE" in
de*|at*|ch*)
# main menu
MAINMENU_TITLE="MKBOOTDEV"
MAINMENU_MSG="Auswahl der Formatierungsmethode:"
MAINMENU_NOPART="Unpartitionierten Stick erzeugen"
MAINMENU_PART="Partitionierten Stick erzeugen"
MAINMENU_KEEP="Partitionierung des Sticks beibehalten"

TITLE1="USB-Speicher formatieren und mit KNOPPIX bootbar machen"
TITLE2="Daten auf Stick kopieren"
MESSAGE1="Gerät auswählen (benötigter Platz: ${SPACE_NEEDED}MB):"
MESSAGE2A="
Das Gerät "
MESSAGE2B=' wird nun mit dem FAT32-Dateisystem formatiert.
ALLE DATEN DARAUF GEHEN VERLOREN!

Möchten Sie wirklich formatieren?'
MESSAGE3="Kopiere Daten und richte Bootsystem ein ..."
MESSAGE4="Auf dem Gerät scheint sich bereits ein /KNOPPIX Ordner zu befinden.

Sollen die Daten wirklich überschrieben werden?"
TOOSMALL=", zu klein"

# error messages
ERROR1="Keine USB-Storage-Geräte gefunden."
ERROR="Leider konnte das Gerät nicht Knoppifiziert werden:"
;;
fr)
MAINMENU_TITLE="MKBOOTDEV"
MAINMENU_MSG="Choisissez le mode:"
MAINMENU_NOPART="Système sur un périphérique USB de stockage sans partitions "
MAINMENU_PART="Système sur un périphérique USB de stockage utilisant une partition FAT32"
MAINMENU_KEEP="Ne pas modifier les partitions du périphérique USB de stockage"

TITLE1="Formatage du périphérique de stockage USB et permettre le démarrage de Knoppix"
TITLE2="Copie des données..."
MESSAGE1="Choisissez le périphérique (espace recquis: ${SPACE_NEEDED}MB):"
MESSAGE2A="
Le périphérique "
MESSAGE2B=' sera formaté en utilisant le système de fichier FAT32.
TOUTES LES DONNÉES SERONT ÉFFACÉES!

Voulez-vous vraiment continuer le formatage?'
MESSAGE3="Copie des données et activation du système de démarrage..."
MESSAGE4="Un répertoire /KNOPPIX semble déja exister sur ce périphérique.

Voulez-vous vraiment continuer et écraser les données?"
TOOSMALL=", trop petit"

# error messages
ERROR1="Aucun périphérique de stockage USB trouvé."
ERROR="Le périphérique ne peut être Knoppifié:"
;;
*)
MAINMENU_TITLE="MKBOOTDEV"
MAINMENU_MSG="Select mode:"
MAINMENU_NOPART="Create system on USB storage without partitions "
MAINMENU_PART="Create system on USB storage using a FAT32 partition"
MAINMENU_KEEP="Don't change partitions on USB storage"

TITLE1="Format USB storage device and make it boot Knoppix"
TITLE2="Copying data..."
MESSAGE1="Select device (space needed: ${SPACE_NEEDED}MB):"
MESSAGE2A="
The device "
MESSAGE2B=' will now be formatted using the FAT32 filesystem.
ALL EXISTING DATA WILL BE ERASED!

Do you really want to continue formatting?'
MESSAGE3="Copying data and initializing boot system..."
MESSAGE4="There seems to be already a /KNOPPIX directory on this device.

Really continue and overwrite the data?"
TOOSMALL=", too small"

# error messages
ERROR1="No USB-Storage devices found."
ERROR="The device could not be Knoppified:"
;;
esac

# main menu
$DIALOG --title "$MAINMENU_TITLE" --radiolist "$MAINMENU_MSG"  18 75 3 \
"A" "$MAINMENU_KEEP" "on" \
"B" "$MAINMENU_PART" "off" \
"C" "$MAINMENU_NOPART" "off" \
2> "$TMP" || bailout 
TYPE="$(<$TMP)"

case "$TYPE" in
  A*) TYPE="KEEP";; 
  B*) TYPE="PART";;
  C*) TYPE="NOPART";;
esac

# Directory selector
DISKS=()
count=0

while read major minor sizekb device relax; do 
 case "$device" in
  sd[a-z]|ub[a-z])
   # do we have an USB device?
   udevinfo -a -p /sys/block/"$device" | grep 'usb-storage' &> /dev/null
   RETURN="$?"
   if [ "$RETURN" = "0" ]; then
     DISKS[$((count++))]="/dev/$device"
     sizemb="$((sizekb / 1024))"
     SIZE="${sizemb}MB"
     if [ "$sizemb" -lt "$SPACE_NEEDED" ] 2>/dev/null; then
       SIZE="${SIZE}${TOOSMALL}"
     fi
     DISKS[$((count++))]="($SIZE)"
     DISKS[$((count++))]="off"
   fi
   ;;
 esac
done <<EOT
$(awk 'BEGIN{old="__start"}{if($0==old){exit}else{old=$0;if($4&&$4!="name"){print $0}}}' /proc/partitions)
EOT

# jump out when there are no usb devices
if [ $count -eq 0 ]; then
 $DIALOG --clear --title "$TITLE" --msgbox "$ERROR1" 12 75
 bailout
fi

rm -f "$TMP"
$DIALOG --clear --title "$TITLE1" --radiolist "$MESSAGE1" 18 75 9 \
"${DISKS[@]}" 2>"$TMP" || bailout
DISK="$(<$TMP)"
[ -z "$DISK" -o ! -e "$DISK" ] && bailout

if [ $TYPE != "KEEP" ]; then
  $DIALOG --clear --title "$TITLE1" --defaultno --yesno \
  "${MESSAGE2A}${DISK}${MESSAGE2B}" 12 75 || bailout
fi

# Make sure it is not mounted.
rm -f "$TMP.err"
mount | grep -q "$DISK" && umount -l "$DISK" 2>"$TMP.err" && \
[ "$?" != "0" ] && { $DIALOG --title "$TITLE1" --msgbox \
"$ERROR `cat $TMP.err`" 18 75; bailout; }

if [ "$TYPE" = "NOPART" ]; then
  MOUNTPOINT="/media/${DISK##/dev/}"
else
  MOUNTPOINT="/media/${DISK##/dev/}1"
fi
mkdir -p "$MOUNTPOINT"


# progress "Message" seconds_expected
progress(){
if [ -n "$1" ]; then
  # Show progressbar
  rm -f "$TMP.done"
  expected="$2"
  [ -n "$expected" ] && ratio="$((expected/10))+2" || ratio=4
  status=0
  ( while [ ! -e "$TMP.done" ]; do echo "$(((status=(10000-status)/ratio+status)/100))"; sleep 1; done | $DIALOG --gauge "$1" 8 75 0 ) &
else
  # Kill previous
  touch "$TMP.done" ; wait ; rm -f "$TMP.done"
fi
}


# Start progress bar
progress "$MESSAGE3" "$((SPACE_NEEDED * 2))"

DISK_WITHOUT_PARTITION="$DISK"

if [ $TYPE != "KEEP" ]; then
  # Wipe out old partition table
  rm -f "$TMP.err"
  dd if=/dev/zero of="$DISK" bs=512 count=1 >/dev/null 2>"$TMP.err" || { progress ""; $DIALOG --title "$TITLE1" --msgbox "$ERROR `cat $TMP.err`" 18 75; bailout; }
fi


if [ $TYPE = "NOPART" ]; then
sfdisk "$DISK" >/dev/null 2>&1 <<EOT
# partition table of $DISK
unit: sectors

${DISK}1 : start=        0, size=        0, Id= 0
${DISK}2 : start=        0, size=        0, Id= 0
${DISK}3 : start=        0, size=        0, Id= 0
${DISK}4 : start=        0, size=        0, Id= 0
EOT
fi

if [ $TYPE = "PART" ]; then
# build one partition of type fat32
sfdisk "$DISK" -uM >/dev/null 2>&1 <<EOT
,,b,*
EOT
# we use the first partition starting with the partitioning
DISK="$DISK"1
fi

if [ $TYPE = "KEEP" ]; then
# set bootable flag to first partition
sfdisk "$DISK" -A1

DISK="$DISK"1
fi

# Wait for device to settle down
sleep 6

if [ "$TYPE" != "KEEP" ]; then
# Format with FAT32
  rm -f "$TMP.err"
  mkdosfs -F32 -I "$DISK" >/dev/null 2>"$TMP.err" || { progress ""; $DIALOG --title "$TITLE1" --msgbox "$ERROR `cat $TMP.err`" 18 75; bailout; }
fi

# Make bootable using syslinux
rm -f "$TMP.err"
syslinux "$DISK" >/dev/null 2>"$TMP.err" || { progress ""; $DIALOG --title "$TITLE1" --msgbox "$ERROR `cat $TMP.err`" 18 75; bailout; }

# Mount
rm -f "$TMP.err"
mount -t vfat -o rw,umask=000,shortname=winnt "$DISK" "$MOUNTPOINT" 2>"$TMP.err" || { progress ""; $DIALOG --title "$TITLE1" --msgbox "$ERROR `cat $TMP.err`" 18 75; bailout; }

# Ask whether we shall overwrite an existing /KNOPPIX directory 
if [ -d "$MOUNTPOINT"/KNOPPIX ]; then
  $DIALOG --clear --title "$TITLE2" --defaultno --yesno \
  "${MESSAGE4}" 12 75 || bailout
  /bin/rm -f "$MOUNTPOINT"/KNOPPIX/KNOPPIX*
  sync
fi

# Copy boot files
rm -f "$TMP.err"
( rsync -Ha /cdrom/boot/isolinux/isolinux.cfg "$MOUNTPOINT"/syslinux.cfg 2>"$TMP.err" && \
  rsync --exclude /cdrom/boot/isolinux/\*.cat --exclude /cdrom/boot/isolinux/isolinux.\* -Ha /cdrom/boot/isolinux/ "$MOUNTPOINT"/ && \
  rsync -Ha /cdrom/KNOPPIX "$MOUNTPOINT"/) 2>"$TMP.err" || \
{ progress ""; $DIALOG --title "$TITLE1" --msgbox "$ERROR `cat $TMP.err`" 18 75; bailout; }

umount "$MOUNTPOINT"

if [ $TYPE != "NOPART" ]; then
ms-sys -s "$DISK_WITHOUT_PARTITION" &> /dev/null
fi

progress ""

# More language-dependent Messages
case "$LANGUAGE" in
de*|at*|ch*)
SUCCESS='
Fertig!

Die KNOPPIX-Dateien wurden erfolgreich gespeichert, und das Gerät wurde mit syslinux bootbar gemacht.'
;;
*)
SUCCESS='
SUCCESS!

The KNOPPIX files have been transferred successfully, and the device has been made bootable with syslinux.'
;;
esac

$DIALOG --title "$TITLE1" --msgbox "$SUCCESS" 12 65

bailout
