Drop unnecessary header line from grml2usb script
[grml2usb.git] / grml2usb
index ae24edb..34ea78a 100755 (executable)
--- a/grml2usb
+++ b/grml2usb
@@ -16,9 +16,10 @@ This script installs a grml system (either a running system or ISO[s]) to a USB
 from optparse import OptionParser
 from inspect import isroutine, isclass
 import datetime, logging, os, re, subprocess, sys, tempfile, time, os.path
 from optparse import OptionParser
 from inspect import isroutine, isclass
 import datetime, logging, os, re, subprocess, sys, tempfile, time, os.path
+import fileinput
 
 # global variables
 
 # global variables
-PROG_VERSION = "0.9.10"
+PROG_VERSION = "0.9.14"
 MOUNTED = set()  # register mountpoints
 TMPFILES = set() # register tmpfiles
 DATESTAMP = time.mktime(datetime.datetime.now().timetuple()) # unique identifier for syslinux.cfg
 MOUNTED = set()  # register mountpoints
 TMPFILES = set() # register tmpfiles
 DATESTAMP = time.mktime(datetime.datetime.now().timetuple()) # unique identifier for syslinux.cfg
@@ -49,16 +50,18 @@ parser.add_option("--fat16", dest="fat16", action="store_true",
                   help="format specified partition with FAT16")
 parser.add_option("--force", dest="force", action="store_true",
                   help="force any actions requiring manual interaction")
                   help="format specified partition with FAT16")
 parser.add_option("--force", dest="force", action="store_true",
                   help="force any actions requiring manual interaction")
-#parser.add_option("--initrd", dest="initrd", action="store", type="string",
-#                  help="install specified initrd instead of the default [TODO - not implemented yet]")
-#parser.add_option("--kernel", dest="kernel", action="store", type="string",
-#                  help="install specified kernel instead of the default [TODO - not implemented yet]")
+parser.add_option("--grub", dest="grub", action="store_true",
+                  help="install grub bootloader instead of (default) syslinux")
+parser.add_option("--grub-mbr", dest="grubmbr", action="store_true",
+                  help="install grub into MBR instead of (default) PBR")
 parser.add_option("--lilo-binary", dest="lilobin",  action="store", type="string",
                   help="lilo executable to be used for installing MBR")
 parser.add_option("--mbr-menu", dest="mbrmenu", action="store_true",
                   help="enable interactive boot menu in MBR")
 parser.add_option("--quiet", dest="quiet", action="store_true",
                   help="do not output anything but just errors on console")
 parser.add_option("--lilo-binary", dest="lilobin",  action="store", type="string",
                   help="lilo executable to be used for installing MBR")
 parser.add_option("--mbr-menu", dest="mbrmenu", action="store_true",
                   help="enable interactive boot menu in MBR")
 parser.add_option("--quiet", dest="quiet", action="store_true",
                   help="do not output anything but just errors on console")
+parser.add_option("--remove-bootoption", dest="removeoption", action="append",
+                  help="regex for removing existing bootoptions")
 parser.add_option("--skip-addons", dest="skipaddons", action="store_true",
                   help="do not install /boot/addons/ files")
 parser.add_option("--skip-grub-config", dest="skipgrubconfig", action="store_true",
 parser.add_option("--skip-addons", dest="skipaddons", action="store_true",
                   help="do not install /boot/addons/ files")
 parser.add_option("--skip-grub-config", dest="skipgrubconfig", action="store_true",
@@ -68,19 +71,16 @@ parser.add_option("--skip-mbr", dest="skipmbr", action="store_true",
 parser.add_option("--skip-syslinux-config", dest="skipsyslinuxconfig", action="store_true",
                   help="skip generation of syslinux configuration files")
 parser.add_option("--syslinux", dest="syslinux", action="store_true",
 parser.add_option("--skip-syslinux-config", dest="skipsyslinuxconfig", action="store_true",
                   help="skip generation of syslinux configuration files")
 parser.add_option("--syslinux", dest="syslinux", action="store_true",
-                  help="install syslinux bootloader instead of grub")
+                  help="install syslinux bootloader (deprecated as it's the default)")
 parser.add_option("--syslinux-mbr", dest="syslinuxmbr", action="store_true",
                   help="install syslinux master boot record (MBR) instead of default")
 parser.add_option("--syslinux-mbr", dest="syslinuxmbr", action="store_true",
                   help="install syslinux master boot record (MBR) instead of default")
-#parser.add_option("--squashfs", dest="squashfs", action="store", type="string",
-#                  help="install specified squashfs file instead of the default [TODO - not implemented yet]")
-#parser.add_option("--uninstall", dest="uninstall", action="store_true",
-#                  help="remove grml ISO files from specified device [TODO - not implemented yet]")
 parser.add_option("--verbose", dest="verbose", action="store_true",
                   help="enable verbose mode")
 parser.add_option("-v", "--version", dest="version", action="store_true",
                   help="display version and exit")
 (options, args) = parser.parse_args()
 
 parser.add_option("--verbose", dest="verbose", action="store_true",
                   help="enable verbose mode")
 parser.add_option("-v", "--version", dest="version", action="store_true",
                   help="display version and exit")
 (options, args) = parser.parse_args()
 
+
 GRML2USB_BASE = '/usr/share/grml2usb'
 if not os.path.isdir(GRML2USB_BASE):
     GRML2USB_BASE = os.path.dirname(os.path.realpath(__file__))
 GRML2USB_BASE = '/usr/share/grml2usb'
 if not os.path.isdir(GRML2USB_BASE):
     GRML2USB_BASE = os.path.dirname(os.path.realpath(__file__))
@@ -93,6 +93,23 @@ class CriticalException(Exception):
     pass
 
 
     pass
 
 
+# The following two functions help to operate on strings as
+# array (list) of bytes (octets). In Python 3000, the bytes
+# datatype will need to be used. This is intended for using
+# with manipulation of files on the octet level, like shell
+# arrays, e.g. in MBR creation.
+
+
+def array2string(a):
+    """Convert a list of integers [0;255] to a string."""
+    return struct.pack("%sB" % len(a), *a)
+
+
+def string2array(s):
+    """Convert a (bytes) string into a list of integers."""
+    return struct.unpack("%sB" % len(s), s)
+
+
 def cleanup():
     """Cleanup function to make sure there aren't any mounted devices left behind.
     """
 def cleanup():
     """Cleanup function to make sure there aren't any mounted devices left behind.
     """
@@ -163,7 +180,7 @@ def execute(f, *exec_arguments):
     # TODO: doesn't work for proc = execute(subprocess.Popen...() -> any ideas?
     if options.dryrun:
         # pylint: disable-msg=W0141
     # TODO: doesn't work for proc = execute(subprocess.Popen...() -> any ideas?
     if options.dryrun:
         # pylint: disable-msg=W0141
-        logging.debug('dry-run only: %s(%s)' % (get_function_name(f), ', '.join(map(repr, exec_arguments))))
+        logging.debug('dry-run only: %s(%s)', get_function_name(f), ', '.join(map(repr, exec_arguments)))
     else:
         # pylint: disable-msg=W0142
         return f(*exec_arguments)
     else:
         # pylint: disable-msg=W0142
         return f(*exec_arguments)
@@ -225,13 +242,12 @@ def mkfs_fat16(device):
 
     @device: partition that should be formated"""
 
 
     @device: partition that should be formated"""
 
-    # syslinux -d boot/isolinux /dev/sdb1
     if options.dryrun:
         logging.info("Would execute mkfs.vfat -F 16 %s now.", device)
         return 0
 
     logging.info("Formating partition with fat16 filesystem")
     if options.dryrun:
         logging.info("Would execute mkfs.vfat -F 16 %s now.", device)
         return 0
 
     logging.info("Formating partition with fat16 filesystem")
-    logging.debug("mkfs.vfat -F 16 %s" % device)
+    logging.debug("mkfs.vfat -F 16 %s", device)
     proc = subprocess.Popen(["mkfs.vfat", "-F", "16", device])
     proc.wait()
     if proc.returncode != 0:
     proc = subprocess.Popen(["mkfs.vfat", "-F", "16", device])
     proc.wait()
     if proc.returncode != 0:
@@ -275,8 +291,8 @@ fi
 
 menuentry "%(grml_flavour)s (default)" {
     set gfxpayload=1024x768x16,1024x768
 
 menuentry "%(grml_flavour)s (default)" {
     set gfxpayload=1024x768x16,1024x768
-    linux   /boot/release/%(grml_flavour)s/linux26 apm=power-off quiet boot=live nomce live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
-    initrd  /boot/release/%(grml_flavour)s/initrd.gz
+    linux   /boot/release/%(flavour_filename)s/linux26 apm=power-off quiet boot=live nomce live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
+    initrd  /boot/release/%(flavour_filename)s/initrd.gz
 }
 
 menuentry "Memory test (memtest86+)" {
 }
 
 menuentry "Memory test (memtest86+)" {
@@ -311,6 +327,7 @@ menuentry "Boot OS of first partition on first disk" {
 }
 
 """ % {'grml_flavour': grml_flavour, 'local_datestamp': local_datestamp,
 }
 
 """ % {'grml_flavour': grml_flavour, 'local_datestamp': local_datestamp,
+        'flavour_filename': grml_flavour.replace('-', ''),
         'bootoptions': bootoptions } )
 
 
         'bootoptions': bootoptions } )
 
 
@@ -326,58 +343,59 @@ def generate_flavour_specific_grub2_config(grml_flavour, bootoptions):
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 menuentry "%(grml_flavour)s            - boot in default mode" {
     set gfxpayload=1024x768x16,1024x768
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 menuentry "%(grml_flavour)s            - boot in default mode" {
     set gfxpayload=1024x768x16,1024x768
-    linux  /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
-    initrd /boot/release/%(grml_flavour)s/initrd.gz
+    linux  /boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
+    initrd /boot/release/%(flavour_filename)s/initrd.gz
 }
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 menuentry "%(grml_flavour)s-persistent - enable persistency feature" {
     set gfxpayload=1024x768x16,1024x768
 }
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 menuentry "%(grml_flavour)s-persistent - enable persistency feature" {
     set gfxpayload=1024x768x16,1024x768
-    linux  /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet persistent live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
-    initrd /boot/release/%(grml_flavour)s/initrd.gz
+    linux  /boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet persistent live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
+    initrd /boot/release/%(flavour_filename)s/initrd.gz
 }
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 menuentry "%(grml_flavour)s2ram        - copy compressed grml file to RAM" {
     set gfxpayload=1024x768x16,1024x768
 }
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 menuentry "%(grml_flavour)s2ram        - copy compressed grml file to RAM" {
     set gfxpayload=1024x768x16,1024x768
-    linux  /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ toram=%(grml_flavour)s.squashfs %(bootoptions)s
-    initrd /boot/release/%(grml_flavour)s/initrd.gz
+    linux  /boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ toram=%(grml_flavour)s.squashfs %(bootoptions)s
+    initrd /boot/release/%(flavour_filename)s/initrd.gz
 }
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 menuentry "%(grml_flavour)s-debug      - enable debugging options" {
     set gfxpayload=1024x768x16,1024x768
 }
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 menuentry "%(grml_flavour)s-debug      - enable debugging options" {
     set gfxpayload=1024x768x16,1024x768
-    linux /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ debug boot=live initcall_debug%(bootoptions)s
-    initrd /boot/release/%(grml_flavour)s/initrd.gz
+    linux /boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ debug initcall_debug%(bootoptions)s
+    initrd /boot/release/%(flavour_filename)s/initrd.gz
 }
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 menuentry "%(grml_flavour)s-x          - start X Window System" {
     set gfxpayload=1024x768x16,1024x768
 }
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 menuentry "%(grml_flavour)s-x          - start X Window System" {
     set gfxpayload=1024x768x16,1024x768
-    linux  /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ startx=wm-ng %(bootoptions)s
-    initrd /boot/release/%(grml_flavour)s/initrd.gz
+    linux  /boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ startx=wm-ng %(bootoptions)s
+    initrd /boot/release/%(flavour_filename)s/initrd.gz
 }
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 menuentry "%(grml_flavour)s-nofb       - disable framebuffer" {
 }
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 menuentry "%(grml_flavour)s-nofb       - disable framebuffer" {
-    linux  /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=ofonly %(bootoptions)s
-    initrd /boot/release/%(grml_flavour)s/initrd.gz
+    linux  /boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=ofonly %(bootoptions)s
+    initrd /boot/release/%(flavour_filename)s/initrd.gz
 }
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 menuentry "%(grml_flavour)s-failsafe   - disable hardware detection" {
 }
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 menuentry "%(grml_flavour)s-failsafe   - disable hardware detection" {
-    linux /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal boot=live noautoconfig atapicd noapic noacpi acpi=off nomodules nofirewire noudev nousb nohotplug noapm nopcmcia nosmp maxcpus=0 noscsi noagp nodma ide=nodma noswap nofstab nosound nogpm nosyslog nodhcp nocpu nodisc nomodem xmodule=vesa noraid nolvm noresume selinux=0 edd=off pci=nomsi %(bootoptions)s
-    initrd /boot/release/%(grml_flavour)s/initrd.gz
+    linux /boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal noautoconfig atapicd noapic noacpi acpi=off nomodules nofirewire noudev nousb nohotplug noapm nopcmcia nosmp maxcpus=0 noscsi noagp nodma ide=nodma noswap nofstab nosound nogpm nosyslog nodhcp nocpu nodisc nomodem xmodule=vesa noraid nolvm noresume selinux=0 edd=off pci=nomsi %(bootoptions)s
+    initrd /boot/release/%(flavour_filename)s/initrd.gz
 }
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 menuentry "%(grml_flavour)s-forensic   - do not touch harddisks during hw recognition" {
     set gfxpayload=1024x768x16,1024x768
 }
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 menuentry "%(grml_flavour)s-forensic   - do not touch harddisks during hw recognition" {
     set gfxpayload=1024x768x16,1024x768
-    linux /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ nofstab noraid nolvm noautoconfig noswap raid=noautodetect forensic readonly %(bootoptions)s
-    initrd /boot/release/%(grml_flavour)s/initrd.gz
+    linux /boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ nofstab noraid nolvm noautoconfig noswap raid=noautodetect forensic readonly %(bootoptions)s
+    initrd /boot/release/%(flavour_filename)s/initrd.gz
 }
 
 """ % {'grml_flavour': grml_flavour, 'local_datestamp': local_datestamp,
 }
 
 """ % {'grml_flavour': grml_flavour, 'local_datestamp': local_datestamp,
+       'flavour_filename': grml_flavour.replace('-', ''),
        'bootoptions': bootoptions } )
 
 
        'bootoptions': bootoptions } )
 
 
@@ -393,50 +411,51 @@ def generate_flavour_specific_grub1_config(grml_flavour, install_partition, boot
     return("""\
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s
     return("""\
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s
-kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
-initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz
+kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
+initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s-persistent
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s-persistent
-kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce vga=791 quiet persistent live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
-initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz
+kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce vga=791 quiet persistent live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
+initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s2ram
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s2ram
-kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ toram=%(grml_flavour)s.squashfs %(bootoptions)s
-initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz
+kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ toram=%(grml_flavour)s.squashfs %(bootoptions)s
+initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s-debug
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s-debug
-kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ debug boot=live initcall_debug%(bootoptions)s
-initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz
+kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ debug initcall_debug%(bootoptions)s
+initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s-x
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s-x
-kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ startx=wm-ng %(bootoptions)s
-initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz
+kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ startx=wm-ng %(bootoptions)s
+initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s-nofb
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s-nofb
-kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=ofonly %(bootoptions)s
-initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz
+kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=ofonly %(bootoptions)s
+initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s-failsafe
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s-failsafe
-kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal boot=live noautoconfig atapicd noapic noacpi acpi=off nomodules nofirewire noudev nousb nohotplug noapm nopcmcia nosmp maxcpus=0 noscsi noagp nodma ide=nodma noswap nofstab nosound nogpm nosyslog nodhcp nocpu nodisc nomodem xmodule=vesa noraid nolvm noresume selinux=0 edd=off pci=nomsi %(bootoptions)s
-initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz
+kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal noautoconfig atapicd noapic noacpi acpi=off nomodules nofirewire noudev nousb nohotplug noapm nopcmcia nosmp maxcpus=0 noscsi noagp nodma ide=nodma noswap nofstab nosound nogpm nosyslog nodhcp nocpu nodisc nomodem xmodule=vesa noraid nolvm noresume selinux=0 edd=off pci=nomsi %(bootoptions)s
+initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s-forensic
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s-forensic
-kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ nofstab noraid nolvm noautoconfig noswap raid=noautodetect forensic readonly %(bootoptions)s
-initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz
+kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ nofstab noraid nolvm noautoconfig noswap raid=noautodetect forensic readonly %(bootoptions)s
+initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s-serial
 
 ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
 title %(grml_flavour)s-serial
-kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=vesafb:off console=tty1 console=ttyS0,9600n8 %(bootoptions)s
-initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz
+kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=vesafb:off console=tty1 console=ttyS0,9600n8 %(bootoptions)s
+initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz
 
 """ % {'grml_flavour': grml_flavour, 'local_datestamp': local_datestamp,
 
 """ % {'grml_flavour': grml_flavour, 'local_datestamp': local_datestamp,
+       'flavour_filename': grml_flavour.replace('-', ''),
        'bootoptions': bootoptions, 'install_partition': install_partition } )
 
 
        'bootoptions': bootoptions, 'install_partition': install_partition } )
 
 
@@ -458,8 +477,8 @@ background  = FFCC33
 
 # define entries:
 title %(grml_flavour)s  - Default boot (using 1024x768 framebuffer)
 
 # define entries:
 title %(grml_flavour)s  - Default boot (using 1024x768 framebuffer)
-kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off vga=791 quiet boot=live nomce live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
-initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz
+kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off vga=791 quiet boot=live nomce live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
+initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz
 
 title Memory test (memtest86+)
 kernel (hd0,%(install_partition)s)/boot/addons/memtest
 
 title Memory test (memtest86+)
 kernel (hd0,%(install_partition)s)/boot/addons/memtest
@@ -476,6 +495,7 @@ title MirOS BSD
 kernel (hd0,%(install_partition)s)/boot/addons/bsd4grml/ldbsd.com
 
 """ % {'grml_flavour': grml_flavour, 'local_datestamp': local_datestamp,
 kernel (hd0,%(install_partition)s)/boot/addons/bsd4grml/ldbsd.com
 
 """ % {'grml_flavour': grml_flavour, 'local_datestamp': local_datestamp,
+       'flavour_filename': grml_flavour.replace('-', ''),
        'bootoptions': bootoptions, 'install_partition': install_partition } )
 
 
        'bootoptions': bootoptions, 'install_partition': install_partition } )
 
 
@@ -496,125 +516,64 @@ Some information and boot options available via keys F2 - F10. http://grml.org/
 """ % {'grml_name': grml_name} )
 
 
 """ % {'grml_name': grml_name} )
 
 
-def generate_main_syslinux_config(grml_flavour, bootoptions):
+def generate_main_syslinux_config(*args):
     """Generate main configuration for use in syslinux.cfg
 
     """Generate main configuration for use in syslinux.cfg
 
-    @grml_flavour: name of grml flavour the configuration should be generated for
-    @bootoptions: additional bootoptions that should be used by default"""
+    @*args: just for backward compatibility"""
 
     local_datestamp = DATESTAMP
 
     return("""\
 
     local_datestamp = DATESTAMP
 
     return("""\
-## main syslinux configuration - generated by grml2usb [main config generated at: %(local_datestamp)s]
-# use this to control the bootup via a serial port
-# SERIAL 0 9600
-DEFAULT grml
-TIMEOUT 300
-PROMPT 1
-DISPLAY /boot/syslinux/boot.msg
-F1 /boot/syslinux/boot.msg
-F2 /boot/syslinux/f2
-F3 /boot/syslinux/f3
-F4 /boot/syslinux/f4
-F5 /boot/syslinux/f5
-F6 /boot/syslinux/f6
-F7 /boot/syslinux/f7
-F8 /boot/syslinux/f8
-F9 /boot/syslinux/f9
-F10 /boot/syslinux/f10
-## end of main configuration
-
-## global configuration
-# the default option (using %(grml_flavour)s)
-LABEL  grml
-KERNEL /boot/release/%(grml_flavour)s/linux26
-APPEND initrd=/boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
-
-# memtest
-LABEL  memtest
-KERNEL /boot/addons/memtest
-
-# grub
-LABEL grub
-MENU LABEL grub
-KERNEL /boot/addons/memdisk
-APPEND initrd=/boot/addons/allinone.img
-
-# dos
-LABEL dos
-MENU LABEL dos
-KERNEL /boot/addons/memdisk
-APPEND initrd=/boot/addons/balder10.imz
-
-# bsd
-LABEL bsd
-MENU LABEL bsd
-KERNEL /boot/addons/bsd4grml/ldbsd.com
-
-# hardware detection tool
-MENU LABEL hdt
-KERNEL /boot/addons/hdt.c32
-APPEND pciids=/boot/addons/pci.ids
-
-## end of global configuration
-""" % {'grml_flavour': grml_flavour, 'local_datestamp': local_datestamp, 'bootoptions': bootoptions} )
-
-
-def generate_flavour_specific_syslinux_config(grml_flavour, bootoptions):
+label -
+menu label Default boot modes:
+menu disable
+include defaults.cfg
+
+menu end
+menu separator
+
+# flavours:
+label -
+menu label Additional boot entries for:
+menu disable
+include additional.cfg
+
+menu separator
+include options.cfg
+include addons.cfg
+
+label help
+  include promptname.cfg
+  config prompt.cfg
+  text help
+                                        Jump to old style isolinux prompt
+                                        featuring further information
+                                        regarding available boot options.
+  endtext
+
+
+include hiddens.cfg
+""")
+
+
+def generate_flavour_specific_syslinux_config(grml_flavour):
     """Generate flavour specific configuration for use in syslinux.cfg
 
     """Generate flavour specific configuration for use in syslinux.cfg
 
-    @grml_flavour: name of grml flavour the configuration should be generated for
-    @bootoptions: bootoptions that should be used as a default"""
+    @grml_flavour: name of grml flavour the configuration should be generated for"""
 
 
-    local_datestamp = DATESTAMP
 
     return("""\
 
     return("""\
-
-# flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
-LABEL  %(grml_flavour)s
-KERNEL /boot/release/%(grml_flavour)s/linux26
-APPEND initrd=/boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
-
-# flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
-LABEL  %(grml_flavour)s-persistent
-KERNEL /boot/release/%(grml_flavour)s/linux26
-APPEND initrd=/boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce vga=791 quiet persistent live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
-
-# flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
-LABEL  %(grml_flavour)s2ram
-KERNEL /boot/release/%(grml_flavour)s/linux26
-APPEND initrd=/boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ toram=%(grml_flavour)s.squashfs %(bootoptions)s
-
-# flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
-LABEL  %(grml_flavour)s-debug
-KERNEL /boot/release/%(grml_flavour)s/linux26
-APPEND initrd=/boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ debug boot=live initcall_debug%(bootoptions)s
-
-# flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
-LABEL  %(grml_flavour)s-x
-KERNEL /boot/release/%(grml_flavour)s/linux26
-APPEND initrd=/boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ startx=wm-ng %(bootoptions)s
-
-# flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
-LABEL  %(grml_flavour)s-nofb
-KERNEL /boot/release/%(grml_flavour)s/linux26
-APPEND initrd=/boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=ofonly %(bootoptions)s
-
-# flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
-LABEL  %(grml_flavour)s-failsafe
-KERNEL /boot/release/%(grml_flavour)s/linux26
-APPEND initrd=/boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal boot=live noautoconfig atapicd noapic noacpi acpi=off nomodules nofirewire noudev nousb nohotplug noapm nopcmcia nosmp maxcpus=0 noscsi noagp nodma ide=nodma noswap nofstab nosound nogpm nosyslog nodhcp nocpu nodisc nomodem xmodule=vesa noraid nolvm noresume selinux=0 edd=off pci=nomsi %(bootoptions)s
-
-# flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
-LABEL  %(grml_flavour)s-forensic
-KERNEL /boot/release/%(grml_flavour)s/linux26
-APPEND initrd=/boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ nofstab noraid nolvm noautoconfig noswap raid=noautodetect forensic readonly %(bootoptions)s
-
-# flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
-LABEL  %(grml_flavour)s-serial
-KERNEL /boot/release/%(grml_flavour)s/linux26
-APPEND initrd=/boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=vesafb:off console=tty1 console=ttyS0,9600n8 %(bootoptions)s
-""" % {'grml_flavour': grml_flavour, 'local_datestamp': local_datestamp, 'bootoptions': bootoptions} )
+menu begin grml %(grml_flavour)s
+    menu title %(display_name)s
+    label mainmenu
+    menu label ^Back to main menu...
+    menu exit
+    menu separator
+    # include config for boot parameters from disk
+    include %(grml_flavour)s_grml.cfg
+    menu hide
+menu end
+""" % {'grml_flavour': grml_flavour, 'display_name' : grml_flavour.replace('_', '-') } )
 
 
 def install_grub(device):
 
 
 def install_grub(device):
@@ -631,17 +590,32 @@ def install_grub(device):
         try:
             try:
                 mount(device, device_mountpoint, "")
         try:
             try:
                 mount(device, device_mountpoint, "")
-                logging.debug("grub-install --recheck --no-floppy --root-directory=%s %s", device_mountpoint, device)
+
+                # If using --grub-mbr then make sure we install grub in MBR instead of PBR
+                # Thanks to grub2. NOT.
+                if options.grubmbr:
+                    logging.debug("Using option --grub-mbr ...")
+                    if device[-1:].isdigit():
+                        grub_device = re.match(r'(.*?)\d*$', device).group(1)
+                    else:
+                        grub_device = device
+                else:
+                    grub_device = device
+
+                logging.info("Installing grub as bootloader")
+                logging.debug("grub-install --recheck --no-floppy --root-directory=%s %s",
+                    device_mountpoint, grub_device)
                 proc = subprocess.Popen(["grub-install", "--recheck", "--no-floppy",
                 proc = subprocess.Popen(["grub-install", "--recheck", "--no-floppy",
-                    "--root-directory=%s" % device_mountpoint, device], stdout=file(os.devnull, "r+"))
+                    "--root-directory=%s" % device_mountpoint, grub_device], stdout=file(os.devnull, "r+"))
                 proc.wait()
                 if proc.returncode != 0:
                     # raise Exception("error executing grub-install")
                 proc.wait()
                 if proc.returncode != 0:
                     # raise Exception("error executing grub-install")
-                    logging.critical("Fatal: error executing grub-install (please check the grml2usb FAQ)")
+                    logging.critical("Fatal: error executing grub-install (please check the grml2usb FAQ or drop the --grub option)")
+                    logging.critical("Note:  if using grub2 consider using the --grub-mbr option because grub2's PBR feature is broken.")
                     cleanup()
                     sys.exit(1)
             except CriticalException, error:
                     cleanup()
                     sys.exit(1)
             except CriticalException, error:
-                logging.critical("Fatal: %s" % error)
+                logging.critical("Fatal: %s", error)
                 cleanup()
                 sys.exit(1)
 
                 cleanup()
                 sys.exit(1)
 
@@ -662,11 +636,11 @@ def install_syslinux(device):
 
     # syslinux -d boot/isolinux /dev/sdb1
     logging.info("Installing syslinux as bootloader")
 
     # syslinux -d boot/isolinux /dev/sdb1
     logging.info("Installing syslinux as bootloader")
-    logging.debug("syslinux -d boot/syslinux %s" % device)
+    logging.debug("syslinux -d boot/syslinux %s", device)
     proc = subprocess.Popen(["syslinux", "-d", "boot/syslinux", device])
     proc.wait()
     if proc.returncode != 0:
     proc = subprocess.Popen(["syslinux", "-d", "boot/syslinux", device])
     proc.wait()
     if proc.returncode != 0:
-        raise CriticalException("Error executing syslinux (either try --fat16 or --grub?)")
+        raise CriticalException("Error executing syslinux (either try --fat16 or use grub?)")
 
 
 def install_bootloader(device):
 
 
 def install_bootloader(device):
@@ -676,13 +650,9 @@ def install_bootloader(device):
 
     # by default we use grub, so install syslinux only on request
     if options.syslinux:
 
     # by default we use grub, so install syslinux only on request
     if options.syslinux:
-        try:
-            install_syslinux(device)
-        except CriticalException, error:
-            logging.critical("Fatal: %s" % error)
-            cleanup()
-            sys.exit(1)
-    else:
+        logging.info("Note: the --syslinux option is deprecated as syslinux is grml2usb's default. Continuing anyway.")
+
+    if options.grub:
         if not which("grub-install"):
             logging.critical("Fatal: grub-install not available (please install the grub package or use the --syslinux option)")
             cleanup()
         if not which("grub-install"):
             logging.critical("Fatal: grub-install not available (please install the grub package or use the --syslinux option)")
             cleanup()
@@ -691,9 +661,16 @@ def install_bootloader(device):
             try:
                 install_grub(device)
             except CriticalException, error:
             try:
                 install_grub(device)
             except CriticalException, error:
-                logging.critical("Fatal: %s" % error)
+                logging.critical("Fatal: %s", error)
                 cleanup()
                 sys.exit(1)
                 cleanup()
                 sys.exit(1)
+    else:
+        try:
+            install_syslinux(device)
+        except CriticalException, error:
+            logging.critical("Fatal: %s", error)
+            cleanup()
+            sys.exit(1)
 
 
 def execute_lilo(lilo, device):
 
 
 def execute_lilo(lilo, device):
@@ -704,14 +681,14 @@ def execute_lilo(lilo, device):
 
     # to support -A for extended partitions:
     logging.info("Activating partitions in MBR via lilo")
 
     # to support -A for extended partitions:
     logging.info("Activating partitions in MBR via lilo")
-    logging.debug("%s -S /dev/null -M %s ext" % (lilo, device))
+    logging.debug("%s -S /dev/null -M %s ext", lilo, device)
     proc = subprocess.Popen([lilo, "-S", "/dev/null", "-M", device, "ext"])
     proc.wait()
     if proc.returncode != 0:
         raise Exception("error executing lilo")
 
     # activate partition:
     proc = subprocess.Popen([lilo, "-S", "/dev/null", "-M", device, "ext"])
     proc.wait()
     if proc.returncode != 0:
         raise Exception("error executing lilo")
 
     # activate partition:
-    logging.debug("%s -S /dev/null -A %s 1" % (lilo, device))
+    logging.debug("%s -S /dev/null -A %s 1", lilo, device)
     proc = subprocess.Popen([lilo, "-S", "/dev/null", "-A", device, "1"])
     proc.wait()
     if proc.returncode != 0:
     proc = subprocess.Popen([lilo, "-S", "/dev/null", "-A", device, "1"])
     proc.wait()
     if proc.returncode != 0:
@@ -725,21 +702,21 @@ def install_syslinux_mbr(device):
 
     # make sure we have syslinux available
     if not which("syslinux") and not options.copyonly:
 
     # make sure we have syslinux available
     if not which("syslinux") and not options.copyonly:
-        raise Exception("syslinux not available (either install it or consider dropping the --syslinux option)")
+        raise Exception("syslinux not available (either install it or consider using the --grub option)")
 
     # lilo's mbr is broken, use the one from syslinux instead:
     if not os.path.isfile("/usr/lib/syslinux/mbr.bin"):
         raise Exception("/usr/lib/syslinux/mbr.bin can not be read")
 
     logging.info("Installing syslinux MBR")
 
     # lilo's mbr is broken, use the one from syslinux instead:
     if not os.path.isfile("/usr/lib/syslinux/mbr.bin"):
         raise Exception("/usr/lib/syslinux/mbr.bin can not be read")
 
     logging.info("Installing syslinux MBR")
-    logging.debug("cat /usr/lib/syslinux/mbr.bin > %s" % device)
+    logging.debug("cat /usr/lib/syslinux/mbr.bin > %s", device)
     try:
         # TODO -> use Popen instead?
         retcode = subprocess.call("cat /usr/lib/syslinux/mbr.bin > "+ device, shell=True)
         if retcode < 0:
     try:
         # TODO -> use Popen instead?
         retcode = subprocess.call("cat /usr/lib/syslinux/mbr.bin > "+ device, shell=True)
         if retcode < 0:
-            logging.critical("Error copying MBR to device (%s)" % retcode)
+            logging.critical("Error copying MBR to device (%s)", retcode)
     except OSError, error:
     except OSError, error:
-        logging.critical("Execution failed:", error)
+        logging.critical("Execution failed: %s", error)
 
 
 def install_mir_mbr(mbrtemplate, device, partition, ismirbsdmbr=True):
 
 
 def install_mir_mbr(mbrtemplate, device, partition, ismirbsdmbr=True):
@@ -769,7 +746,7 @@ def install_mir_mbr(mbrtemplate, device, partition, ismirbsdmbr=True):
     logging.info("Installing default MBR")
 
     if not os.path.isfile(mbrtemplate):
     logging.info("Installing default MBR")
 
     if not os.path.isfile(mbrtemplate):
-        logging.critical("Error: %s can not be read." % mbrtemplate)
+        logging.critical("Error: %s can not be read.", mbrtemplate)
         raise CriticalException("Error installing MBR (either try --syslinux-mbr or install missing file?)")
 
     if (partition < 0) or (partition > 3):
         raise CriticalException("Error installing MBR (either try --syslinux-mbr or install missing file?)")
 
     if (partition < 0) or (partition > 3):
@@ -782,14 +759,14 @@ def install_mir_mbr(mbrtemplate, device, partition, ismirbsdmbr=True):
 
     tmpf = tempfile.NamedTemporaryFile()
 
 
     tmpf = tempfile.NamedTemporaryFile()
 
-    logging.debug("executing: dd if='%s' of='%s' bs=512 count=1" % (device, tmpf.name))
+    logging.debug("executing: dd if='%s' of='%s' bs=512 count=1", device, tmpf.name)
     proc = subprocess.Popen(["dd", "if=%s" % device, "of=%s" % tmpf.name, "bs=512", "count=1"], stderr=file(os.devnull, "r+"))
     proc.wait()
     if proc.returncode != 0:
         raise Exception("error executing dd (first run)")
 
     proc = subprocess.Popen(["dd", "if=%s" % device, "of=%s" % tmpf.name, "bs=512", "count=1"], stderr=file(os.devnull, "r+"))
     proc.wait()
     if proc.returncode != 0:
         raise Exception("error executing dd (first run)")
 
-    logging.debug("executing: dd if=%s of=%s bs=%s count=1 conv=notrunc" % (mbrtemplate,
-        tmpf.name, nmbrbytes))
+    logging.debug("executing: dd if=%s of=%s bs=%s count=1 conv=notrunc"mbrtemplate,
+        tmpf.name, nmbrbytes)
     proc = subprocess.Popen(["dd", "if=%s" % mbrtemplate, "of=%s" % tmpf.name, "bs=%s" % nmbrbytes,
         "count=1", "conv=notrunc"], stderr=file(os.devnull, "r+"))
     proc.wait()
     proc = subprocess.Popen(["dd", "if=%s" % mbrtemplate, "of=%s" % tmpf.name, "bs=%s" % nmbrbytes,
         "count=1", "conv=notrunc"], stderr=file(os.devnull, "r+"))
     proc.wait()
@@ -817,7 +794,7 @@ def install_mir_mbr(mbrtemplate, device, partition, ismirbsdmbr=True):
     tmpf.file.write(mbrcode)
     tmpf.file.close()
 
     tmpf.file.write(mbrcode)
     tmpf.file.close()
 
-    logging.debug("executing: dd if='%s' of='%s' bs=512 count=1 conv=notrunc" % (tmpf.name, device))
+    logging.debug("executing: dd if='%s' of='%s' bs=512 count=1 conv=notrunc", tmpf.name, device)
     proc = subprocess.Popen(["dd", "if=%s" % tmpf.name, "of=%s" % device, "bs=512", "count=1",
                             "conv=notrunc"], stderr=file(os.devnull, "r+"))
     proc.wait()
     proc = subprocess.Popen(["dd", "if=%s" % tmpf.name, "of=%s" % device, "bs=512", "count=1",
                             "conv=notrunc"], stderr=file(os.devnull, "r+"))
     proc.wait()
@@ -889,16 +866,16 @@ def mount(source, target, mount_options):
             raise CriticalException("Error executing mount: %s already mounted - please unmount before invoking grml2usb" % source)
 
     if os.path.isdir(source):
             raise CriticalException("Error executing mount: %s already mounted - please unmount before invoking grml2usb" % source)
 
     if os.path.isdir(source):
-        logging.debug("Source %s is not a device, therefore not mounting." % source)
+        logging.debug("Source %s is not a device, therefore not mounting.", source)
         return 0
 
         return 0
 
-    logging.debug("mount %s %s %s" % (mount_options, source, target))
+    logging.debug("mount %s %s %s", mount_options, source, target)
     proc = subprocess.Popen(["mount"] + list(mount_options) + [source, target])
     proc.wait()
     if proc.returncode != 0:
         raise CriticalException("Error executing mount (no filesystem on the partition?)")
     else:
     proc = subprocess.Popen(["mount"] + list(mount_options) + [source, target])
     proc.wait()
     if proc.returncode != 0:
         raise CriticalException("Error executing mount (no filesystem on the partition?)")
     else:
-        logging.debug("register_mountpoint(%s)" % target)
+        logging.debug("register_mountpoint(%s)", target)
         register_mountpoint(target)
 
 
         register_mountpoint(target)
 
 
@@ -917,15 +894,15 @@ def unmount(target, unmount_options):
             target_unmount = True
 
     if not target_unmount:
             target_unmount = True
 
     if not target_unmount:
-        logging.debug("%s not mounted anymore" % target)
+        logging.debug("%s not mounted anymore", target)
     else:
     else:
-        logging.debug("umount %s %s" % (list(unmount_options), target))
+        logging.debug("umount %s %s", list(unmount_options), target)
         proc = subprocess.Popen(["umount"] + list(unmount_options) + [target])
         proc.wait()
         if proc.returncode != 0:
             raise Exception("Error executing umount")
         else:
         proc = subprocess.Popen(["umount"] + list(unmount_options) + [target])
         proc.wait()
         if proc.returncode != 0:
             raise Exception("Error executing umount")
         else:
-            logging.debug("unregister_mountpoint(%s)" % target)
+            logging.debug("unregister_mountpoint(%s)", target)
             unregister_mountpoint(target)
 
 
             unregister_mountpoint(target)
 
 
@@ -983,6 +960,25 @@ def mkdir(directory):
             pass
 
 
             pass
 
 
+def exec_rsync(source, target):
+    """Simple wrapper around rsync to install files
+
+    @source: source file/directory
+    @target: target file/directory"""
+    logging.debug("Source: %s / Target: %s", source, target)
+    proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", source, target])
+    proc.wait()
+    if proc.returncode == 12:
+        logging.critical("Fatal: No space left on device")
+        cleanup()
+        sys.exit(1)
+
+    if proc.returncode != 0:
+        logging.critical("Fatal: could not install %s", source)
+        cleanup()
+        sys.exit(1)
+
+
 def copy_system_files(grml_flavour, iso_mount, target):
     """copy grml's main files (like squashfs, kernel and initrd) to a given target
 
 def copy_system_files(grml_flavour, iso_mount, target):
     """copy grml's main files (like squashfs, kernel and initrd) to a given target
 
@@ -997,36 +993,31 @@ def copy_system_files(grml_flavour, iso_mount, target):
     else:
         squashfs_target = target + '/live/' + grml_flavour + '/'
         execute(mkdir, squashfs_target)
     else:
         squashfs_target = target + '/live/' + grml_flavour + '/'
         execute(mkdir, squashfs_target)
-        logging.debug("rsync -rlptDH --inplace %s %s" % (squashfs, squashfs_target + grml_flavour + '.squashfs'))
-        proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", squashfs, squashfs_target + grml_flavour + ".squashfs"])
-        proc.wait()
+    exec_rsync(squashfs, squashfs_target + grml_flavour + '.squashfs')
 
     filesystem_module = search_file('filesystem.module', iso_mount)
     if filesystem_module is None:
         logging.critical("Fatal: filesystem.module not found")
 
     filesystem_module = search_file('filesystem.module', iso_mount)
     if filesystem_module is None:
         logging.critical("Fatal: filesystem.module not found")
+        raise CriticalException("error locating filesystem.module file")
     else:
     else:
-        logging.debug("rsync -rlptDH --inplace %s %s" % (filesystem_module, squashfs_target + 'filesystem.module'))
-        proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", filesystem_module, squashfs_target + 'filesystem.module'])
-        proc.wait()
+        exec_rsync(filesystem_module, squashfs_target + 'filesystem.module')
 
 
-    release_target = target + '/boot/release/' + grml_flavour
+    release_target = target + '/boot/release/' + grml_flavour.replace('-', '')
     execute(mkdir, release_target)
 
     kernel = search_file('linux26', iso_mount)
     if kernel is None:
         logging.critical("Fatal kernel not found")
     execute(mkdir, release_target)
 
     kernel = search_file('linux26', iso_mount)
     if kernel is None:
         logging.critical("Fatal kernel not found")
+        raise CriticalException("error locating kernel file")
     else:
     else:
-        logging.debug("rsync -rlptDH --inplace %s %s" % (kernel, release_target + '/linux26'))
-        proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", kernel, release_target + '/linux26'])
-        proc.wait()
+        exec_rsync(kernel, release_target + '/linux26')
 
     initrd = search_file('initrd.gz', iso_mount)
     if initrd is None:
         logging.critical("Fatal: initrd not found")
 
     initrd = search_file('initrd.gz', iso_mount)
     if initrd is None:
         logging.critical("Fatal: initrd not found")
+        raise CriticalException("error locating initrd file")
     else:
     else:
-        logging.debug("rsync -rlptDH --inplace %s %s" % (initrd, release_target + '/initrd.gz'))
-        proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", initrd, release_target + '/initrd.gz'])
-        proc.wait()
+        exec_rsync(initrd, release_target + '/initrd.gz')
 
 
 def copy_grml_files(iso_mount, target):
 
 
 def copy_grml_files(iso_mount, target):
@@ -1043,9 +1034,7 @@ def copy_grml_files(iso_mount, target):
         if grml_file is None:
             logging.warn("Warning: myfile %s could not be found - can not install it", myfile)
         else:
         if grml_file is None:
             logging.warn("Warning: myfile %s could not be found - can not install it", myfile)
         else:
-            logging.debug("rsync -rlptDH --inplace %s %s" % (grml_file, grml_target + grml_file))
-            proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", grml_file, grml_target + myfile])
-            proc.wait()
+            exec_rsync(grml_file, grml_target + myfile)
 
     grml_web_target = grml_target + '/web/'
     execute(mkdir, grml_web_target)
 
     grml_web_target = grml_target + '/web/'
     execute(mkdir, grml_web_target)
@@ -1055,9 +1044,7 @@ def copy_grml_files(iso_mount, target):
         if grml_file is None:
             logging.warn("Warning: myfile %s could not be found - can not install it")
         else:
         if grml_file is None:
             logging.warn("Warning: myfile %s could not be found - can not install it")
         else:
-            logging.debug("rsync -rlptDH --inplace %s %s" % (grml_file, grml_web_target + grml_file))
-            proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", grml_file, grml_web_target + myfile])
-            proc.wait()
+            exec_rsync(grml_file, grml_web_target + myfile)
 
     grml_webimg_target = grml_web_target + '/images/'
     execute(mkdir, grml_webimg_target)
 
     grml_webimg_target = grml_web_target + '/images/'
     execute(mkdir, grml_webimg_target)
@@ -1067,9 +1054,7 @@ def copy_grml_files(iso_mount, target):
         if grml_file is None:
             logging.warn("Warning: myfile %s could not be found - can not install it")
         else:
         if grml_file is None:
             logging.warn("Warning: myfile %s could not be found - can not install it")
         else:
-            logging.debug("rsync -rlptDH --inplace %s %s" % (grml_file, grml_webimg_target + grml_file))
-            proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", grml_file, grml_webimg_target + myfile])
-            proc.wait()
+            exec_rsync(grml_file, grml_webimg_target + myfile)
 
 
 def copy_addons(iso_mount, target):
 
 
 def copy_addons(iso_mount, target):
@@ -1086,61 +1071,47 @@ def copy_addons(iso_mount, target):
     if allinoneimg is None:
         logging.warn("Warning: allinone.img not found (that's fine if you don't need it)")
     else:
     if allinoneimg is None:
         logging.warn("Warning: allinone.img not found (that's fine if you don't need it)")
     else:
-        logging.debug("rsync -rlptDH --inplace %s %s" % (allinoneimg, addons + '/allinone.img'))
-        proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", allinoneimg, addons + 'allinone.img'])
-        proc.wait()
+        exec_rsync(allinoneimg, addons + 'allinone.img')
 
     # bsd imag
     bsdimg = search_file('bsd4grml', iso_mount)
     if bsdimg is None:
         logging.warn("Warning: bsd4grml not found (that's fine if you don't need it)")
     else:
 
     # bsd imag
     bsdimg = search_file('bsd4grml', iso_mount)
     if bsdimg is None:
         logging.warn("Warning: bsd4grml not found (that's fine if you don't need it)")
     else:
-        logging.debug("rsync -rlptDH --inplace %s %s" % (bsdimg, addons + '/'))
-        proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", bsdimg, addons + '/'])
-        proc.wait()
+        exec_rsync(bsdimg, addons + '/')
 
     # freedos image
     balderimg = search_file('balder10.imz', iso_mount)
     if balderimg is None:
         logging.warn("Warning: balder10.imz not found (that's fine if you don't need it)")
     else:
 
     # freedos image
     balderimg = search_file('balder10.imz', iso_mount)
     if balderimg is None:
         logging.warn("Warning: balder10.imz not found (that's fine if you don't need it)")
     else:
-        logging.debug("rsync -rlptDH --inplace %s %s" % (balderimg, addons + '/balder10.imz'))
-        proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", balderimg, addons + 'balder10.imz'])
-        proc.wait()
+        exec_rsync(balderimg, addons + 'balder10.imz')
 
     # install hdt and pci.ids only when using syslinux (grub doesn't support it)
     if options.syslinux:
         # hdt (hardware detection tool) image
         hdtimg = search_file('hdt.c32', iso_mount)
         if hdtimg:
 
     # install hdt and pci.ids only when using syslinux (grub doesn't support it)
     if options.syslinux:
         # hdt (hardware detection tool) image
         hdtimg = search_file('hdt.c32', iso_mount)
         if hdtimg:
-            logging.debug("rsync -rlptDH --inplace %s %s" % (hdtimg, addons + '/hdt.c32'))
-            proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", hdtimg, addons + '/hdt.c32'])
-            proc.wait()
+            exec_rsync(hdtimg, addons + '/hdt.c32')
 
         # pci.ids file
         picids = search_file('pci.ids', iso_mount)
         if picids:
 
         # pci.ids file
         picids = search_file('pci.ids', iso_mount)
         if picids:
-            logging.debug("rsync -rlptDH --inplace %s %s" % (picids, addons + '/pci.ids'))
-            proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", picids, addons + '/pci.ids'])
-            proc.wait()
+            exec_rsync(picids, addons + '/pci.ids')
 
     # memdisk image
     memdiskimg = search_file('memdisk', iso_mount)
     if memdiskimg is None:
         logging.warn("Warning: memdisk not found (that's fine if you don't need it)")
     else:
 
     # memdisk image
     memdiskimg = search_file('memdisk', iso_mount)
     if memdiskimg is None:
         logging.warn("Warning: memdisk not found (that's fine if you don't need it)")
     else:
-        logging.debug("rsync -rlptDH --inplace %s %s" % (memdiskimg, addons + '/memdisk'))
-        proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", memdiskimg, addons + 'memdisk'])
-        proc.wait()
+        exec_rsync(memdiskimg, addons + 'memdisk')
 
     # memtest86+ image
     memtestimg = search_file('memtest', iso_mount)
     if memtestimg is None:
         logging.warn("Warning: memtest not found (that's fine if you don't need it)")
     else:
 
     # memtest86+ image
     memtestimg = search_file('memtest', iso_mount)
     if memtestimg is None:
         logging.warn("Warning: memtest not found (that's fine if you don't need it)")
     else:
-        logging.debug("rsync -rlptDH --inplace %s %s" % (memtestimg, addons + '/memtest'))
-        proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", memtestimg, addons + 'memtest'])
-        proc.wait()
+        exec_rsync(memtestimg, addons + 'memtest')
 
 
 def copy_bootloader_files(iso_mount, target):
 
 
 def copy_bootloader_files(iso_mount, target):
@@ -1153,42 +1124,55 @@ def copy_bootloader_files(iso_mount, target):
     execute(mkdir, syslinux_target)
 
     logo = search_file('logo.16', iso_mount)
     execute(mkdir, syslinux_target)
 
     logo = search_file('logo.16', iso_mount)
-    logging.debug("rsync -rlptDH --inplace %s %s" % (logo, syslinux_target + 'logo.16'))
-    proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", logo, syslinux_target + 'logo.16'])
-    proc.wait()
+    exec_rsync(logo, syslinux_target + 'logo.16')
 
 
-    for ffile in 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10':
+    for ffile in ['f%d' % number for number in range(1,11) ]:
         bootsplash = search_file(ffile, iso_mount)
         bootsplash = search_file(ffile, iso_mount)
-        logging.debug("rsync -rlptDH --inplace %s %s" % (bootsplash, syslinux_target + ffile))
-        proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", bootsplash, syslinux_target + ffile])
-        proc.wait()
+        exec_rsync(bootsplash, syslinux_target + ffile)
+
+    # avoid the "file is read only, overwrite anyway (y/n) ?" question
+    # of mtools by syslinux ("mmove -D o -D O s:/ldlinux.sys $target_file")
+    if os.path.isfile(syslinux_target + 'ldlinux.sys'):
+        os.unlink(syslinux_target + 'ldlinux.sys')
+
+    if not search_file('default.cfg', iso_mount + '/boot/isolinux/'):
+        logging.critical("Fatal: file default.cfg could not be found.")
+        logging.critical("Note:  this grml2usb version requires an ISO generated by grml-live >=0.9.24 ...")
+        logging.critical("       ... either use grml releases >=2009.10 or switch to an older grml2usb version.")
+        logging.critical("       Please visit http://grml.org/grml2usb/#grml2usb-compat for further information.")
+        raise
+
+    for filename in 'addons.cfg', 'default.cfg', 'distri.cfg', \
+                    'grml.cfg', 'grml.png', 'hd.cfg', 'isolinux.cfg', 'isolinux.bin', \
+                    'isoprompt.cfg', 'options.cfg', \
+                    'prompt.cfg', 'vesamenu.c32', 'vesamenu.cfg', 'grml.png':
+        path = search_file(filename, iso_mount + '/boot/isolinux/')
+        if not path:
+            print filename
+            continue
+        exec_rsync(path, syslinux_target + filename)
+
+    path = search_file('hidden.cfg', iso_mount + '/boot/isolinux/')
+    exec_rsync(path, syslinux_target + "new_" + 'hidden.cfg')
+
 
     grub_target = target + '/boot/grub/'
     execute(mkdir, grub_target)
 
     if not os.path.isfile(GRML2USB_BASE + "/grub/splash.xpm.gz"):
 
     grub_target = target + '/boot/grub/'
     execute(mkdir, grub_target)
 
     if not os.path.isfile(GRML2USB_BASE + "/grub/splash.xpm.gz"):
-        logging.critical("Error: %s/grub/splash.xpm.gz can not be read." % (GRML2USB_BASE, ))
-        logging.critical("Please make sure you've the grml2usb Debian package installed!")
+        logging.critical("Error: %s/grub/splash.xpm.gz can not be read.", GRML2USB_BASE)
+        logging.critical("Please make sure you've installed the grml2usb (Debian) package!")
         raise
     else:
         raise
     else:
-        logging.debug("rsync -rlptDH --inplace %s/grub/splash.xpm.gz %s%s" % (GRML2USB_BASE, grub_target, 'splash.xpm.gz'))
-        proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", GRML2USB_BASE + '/grub/splash.xpm.gz',
-                                grub_target + 'splash.xpm.gz'])
-        proc.wait()
+        exec_rsync(GRML2USB_BASE + '/grub/splash.xpm.gz', grub_target + 'splash.xpm.gz')
 
     # grml splash in grub
     if os.path.isfile(GRML2USB_BASE + "/grub/grml.png"):
 
     # grml splash in grub
     if os.path.isfile(GRML2USB_BASE + "/grub/grml.png"):
-        logging.debug("rsync -rlptDH --inplace %s/grub/grml.png to %s%s" % (GRML2USB_BASE, grub_target, 'grml.png'))
-        proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", GRML2USB_BASE + '/grub/grml.png',
-                                grub_target + 'grml.png'])
-        proc.wait()
+        exec_rsync(GRML2USB_BASE + '/grub/grml.png', grub_target + 'grml.png')
 
     # font file for graphical bootsplash in grub
     if os.path.isfile("/usr/share/grub/ascii.pf2"):
 
     # font file for graphical bootsplash in grub
     if os.path.isfile("/usr/share/grub/ascii.pf2"):
-        logging.debug("rsync -rlptDH --inplace /usr/share/grub/ascii.pf2 to %s" % grub_target + 'ascii.pf2')
-        proc = subprocess.Popen(["rsync", "-rlptDH", "--inplace", '/usr/share/grub/ascii.pf2',
-                                grub_target + 'ascii.pf2'])
-        proc.wait()
+        exec_rsync('/usr/share/grub/ascii.pf2', grub_target + 'ascii.pf2')
 
 
 def install_iso_files(grml_flavour, iso_mount, device, target):
 
 
 def install_iso_files(grml_flavour, iso_mount, device, target):
@@ -1238,7 +1222,7 @@ def uninstall_files(device):
     @device: partition where grml2usb files should be removed from"""
 
     # TODO - not implemented yet
     @device: partition where grml2usb files should be removed from"""
 
     # TODO - not implemented yet
-    logging.critical("TODO: uninstalling files from %s not yet implement, sorry." % device)
+    logging.critical("TODO: uninstalling files from %s not yet implement, sorry.", device)
 
 
 def identify_grml_flavour(mountpath):
 
 
 def identify_grml_flavour(mountpath):
@@ -1259,13 +1243,27 @@ def identify_grml_flavour(mountpath):
         grml_flavour = re.match(r'[\w-]*', grml_info).group()
     except TypeError:
         raise
         grml_flavour = re.match(r'[\w-]*', grml_info).group()
     except TypeError:
         raise
-    except:
-        logging.critical("Unexpected error:", sys.exc_info()[0])
+    except Exception, e:
+        logging.critical("Unexpected error: %s", e)
         raise
 
     return grml_flavour
 
 
         raise
 
     return grml_flavour
 
 
+def modify_grub_config(filename):
+    if options.removeoption:
+        regexe = []
+        for regex in options.removeoption:
+            regexe.append(re.compile(r'(.*/boot/release/.*linux26.*)(%s)(.*)' % regex))
+
+        for line in fileinput.input(filename, inplace=1):
+            for regex in regexe:
+                line = regex.sub( r'\1 \3', line)
+
+            sys.stdout.write(line)
+
+        fileinput.close()
+
 def handle_grub1_config(grml_flavour, install_partition, grub_target, bootopt):
     """Main handler for generating grub1 configuration
 
 def handle_grub1_config(grml_flavour, install_partition, grub_target, bootopt):
     """Main handler for generating grub1 configuration
 
@@ -1304,6 +1302,8 @@ def handle_grub1_config(grml_flavour, install_partition, grub_target, bootopt):
         grub1_config_file.write(generate_flavour_specific_grub1_config(grml_flavour, install_partition, bootopt))
         grub1_config_file.close()
 
         grub1_config_file.write(generate_flavour_specific_grub1_config(grml_flavour, install_partition, bootopt))
         grub1_config_file.close()
 
+    modify_grub_config(grub1_cfg)
+
     # make sure grub.conf isn't a symlink but a plain file instead,
     # otherwise it will break on FAT16 filesystems
     # this works around grub-install of (at least) Fedora 10
     # make sure grub.conf isn't a symlink but a plain file instead,
     # otherwise it will break on FAT16 filesystems
     # this works around grub-install of (at least) Fedora 10
@@ -1361,6 +1361,8 @@ def handle_grub2_config(grml_flavour, grub_target, bootopt):
         grub2_config_file.write(generate_flavour_specific_grub2_config(grml_flavour, bootopt))
         grub2_config_file.close()
 
         grub2_config_file.write(generate_flavour_specific_grub2_config(grml_flavour, bootopt))
         grub2_config_file.close()
 
+    modify_grub_config(grub2_cfg)
+
 
 def handle_grub_config(grml_flavour, device, target):
     """Main handler for generating grub (v1 and v2) configuration
 
 def handle_grub_config(grml_flavour, device, target):
     """Main handler for generating grub (v1 and v2) configuration
@@ -1394,6 +1396,100 @@ def handle_grub_config(grml_flavour, device, target):
     handle_grub2_config(grml_flavour, grub_target, bootopt)
 
 
     handle_grub2_config(grml_flavour, grub_target, bootopt)
 
 
+def initial_syslinux_config(target):
+    """Generates intial syslinux configuration
+
+    @target path of syslinux's configuration files"""
+
+    target = target + "/"
+    filename = target + "grmlmain.cfg"
+    if os.path.isfile(target + "grmlmain.cfg"):
+        return
+    data = open(filename, "w")
+    data.write(generate_main_syslinux_config())
+    data.close
+
+    filename = target + "hiddens.cfg"
+    data = open(filename, "w")
+    data.write("include hidden.cfg\n")
+    data.close()
+
+def add_entry_if_not_present(filename, entry):
+    data = open(filename, "a+")
+    for line in data:
+        if line == entry:
+            break
+    else:
+        data.write(entry)
+
+    data.close()
+
+
+
+def adjust_syslinux_bootoptions(src, flavour):
+    append_re = re.compile("^(\s*append.*)$", re.I)
+    boot_re = re.compile("/boot/([a-zA-Z0-9_]+/)+([a-zA-Z0-9._]+)")
+    # flavour_re = re.compile("(label.*)(grml\w+)")
+    default_re = re.compile("(default.cfg)")
+
+    # do NOT write "None" in kernel cmdline
+    if options.bootoptions is None:
+        bootopt = ""
+    else:
+        bootopt = options.bootoptions
+
+    regexe = []
+    if options.removeoption:
+        for regex in options.removeoption:
+            regexe.append(re.compile(r'(.*/boot/release/.*/initrd.gz.*)(%s)(.*)' % regex))
+
+    for line in fileinput.input(src, inplace=1):
+        line = boot_re.sub(r'/boot/release/%s/\2 ' % flavour.replace('-', ''), line)
+        # line = flavour_re.sub(r'\1 %s-\2' % flavour, line)
+        line = default_re.sub(r'%s-\1' % flavour, line)
+        line = append_re.sub(r'\1 live-media-path=/live/%s/ ' % flavour, line)
+        line = append_re.sub(r'\1 boot=live %s ' % bootopt, line)
+        for regex in regexe:
+            line = regex.sub( r'\1 \3', line)
+        sys.stdout.write(line)
+    fileinput.close()
+
+def adjust_labels(src, flavour):
+    label_re = re.compile("^(\s*label\s*) ([a-zA-Z0-9_-]+)", re.I)
+    for line in fileinput.input(src, inplace=1):
+        line = label_re.sub(r'\1 %s-\2' % flavour, line)
+        sys.stdout.write(line)
+    fileinput.close()
+
+
+def add_syslinux_entry(filename, grml_flavour):
+    entry_filename = "option_%s.cfg" % grml_flavour
+    entry = "include %s\n" % entry_filename
+
+    add_entry_if_not_present(filename, entry)
+    path = os.path.dirname(filename)
+
+    data = open(path + "/" + entry_filename, "w")
+    data.write(generate_flavour_specific_syslinux_config(grml_flavour))
+    data.close()
+
+def modify_filenames(grml_flavour, target, filenames):
+    grml_filename = grml_flavour.replace('-', '_')
+    for filename in filenames:
+        old_filename = "%s/%s" % (target, filename)
+        new_filename = "%s/%s_%s" % (target, grml_filename, filename)
+        os.rename(old_filename, new_filename)
+        adjust_syslinux_bootoptions(new_filename, grml_flavour)
+
+
+def remove_default_entry(filename):
+    default_re = re.compile("^(\s*menu\s*default\s*)$", re.I)
+    for line in fileinput.input(filename, inplace=1):
+        if default_re.match(line): continue
+        sys.stdout.write(line)
+    fileinput.close()
+
+
 def handle_syslinux_config(grml_flavour, target):
     """Main handler for generating syslinux configuration
 
 def handle_syslinux_config(grml_flavour, target):
     """Main handler for generating syslinux configuration
 
@@ -1416,43 +1512,48 @@ def handle_syslinux_config(grml_flavour, target):
 
     # install main configuration only *once*, no matter how many ISOs we have:
     syslinux_flavour_is_default = False
 
     # install main configuration only *once*, no matter how many ISOs we have:
     syslinux_flavour_is_default = False
-    if os.path.isfile(syslinux_cfg):
-        string = open(syslinux_cfg).readline()
-        main_identifier = re.compile(".*main config generated at: %s.*" % re.escape(str(DATESTAMP)))
-        if not re.match(main_identifier, string):
-            syslinux_config_file = open(syslinux_cfg, 'w')
-            GRML_DEFAULT = grml_flavour
-            syslinux_flavour_is_default = True
-            syslinux_config_file.write(generate_main_syslinux_config(grml_flavour, bootopt))
-            syslinux_config_file.close()
+    syslinux_config_file = open(syslinux_cfg, 'w')
+    syslinux_config_file.write("TIMEOUT 300\n")
+    syslinux_config_file.write("include vesamenu.cfg\n")
+    syslinux_config_file.close()
+
+    prompt_name = open(syslinux_target + 'promptname.cfg', 'w')
+    prompt_name.write('menu label S^yslinux prompt\n')
+    prompt_name.close()
+
+    initial_syslinux_config(syslinux_target)
+    modify_filenames(grml_flavour, syslinux_target, ['grml.cfg', 'default.cfg'])
+
+    filename = search_file("new_hidden.cfg", syslinux_target)
+
+
+    flavour_filename = grml_flavour.replace('-', '_')
+    # process hidden file
+    if not search_file("hidden.cfg", syslinux_target):
+        new_hidden = syslinux_target + "hidden.cfg"
+        os.rename(filename, new_hidden)
+        adjust_syslinux_bootoptions(new_hidden, grml_flavour)
     else:
     else:
-        syslinux_config_file = open(syslinux_cfg, 'w')
-        GRML_DEFAULT = grml_flavour
-        syslinux_flavour_is_default = True
-        syslinux_config_file.write(generate_main_syslinux_config(grml_flavour, bootopt))
-        syslinux_config_file.close()
+        new_hidden =  "%s_hidden.cfg" % (flavour_filename)
+        new_hidden_file =  "%s/%s" % (syslinux_target, new_hidden)
+        os.rename(filename, new_hidden_file)
+        adjust_labels(new_hidden_file, flavour_filename)
+        adjust_syslinux_bootoptions(new_hidden_file, flavour_filename)
+        entry = 'include %s\n' % new_hidden
+        add_entry_if_not_present("%s/hiddens.cfg" % syslinux_target, entry)
 
 
-    # install flavour specific configuration only *once* as well
-    syslinux_flavour_config = True
-    if os.path.isfile(syslinux_cfg):
-        string = open(syslinux_cfg).readlines()
-        flavour = re.compile("grml2usb for %s: %s" % (re.escape(grml_flavour), re.escape(str(DATESTAMP))))
-        for line in string:
-            if flavour.match(line):
-                syslinux_flavour_config = False
 
 
-    if syslinux_flavour_config:
-        syslinux_config_file = open(syslinux_cfg, 'a')
-        # display only if the grml flavour isn't the default
-        if not syslinux_flavour_is_default:
-            GRML_FLAVOURS.add(grml_flavour)
-        syslinux_config_file.write(generate_flavour_specific_syslinux_config(grml_flavour, bootopt))
-        syslinux_config_file.close()
 
 
-    logging.debug("Generating isolinux/syslinux splash %s" % syslinux_target + 'boot.msg')
-    isolinux_splash = open(syslinux_target + 'boot.msg', 'w')
-    isolinux_splash.write(generate_isolinux_splash(grml_flavour))
-    isolinux_splash.close()
+    new_default = "%s_default.cfg" % (flavour_filename)
+    entry = 'include %s\n' % new_default
+    defaults_file = '%s/defaults.cfg' % syslinux_target
+
+    if os.path.isfile(defaults_file):
+        remove_default_entry('%s/%s_default.cfg' % (syslinux_target, flavour_filename))
+
+    add_entry_if_not_present("%s/defaults.cfg" % syslinux_target, entry)
+
+    add_syslinux_entry("%s/additional.cfg" % syslinux_target, flavour_filename)
 
 
 def handle_bootloader_config(grml_flavour, device, target):
 
 
 def handle_bootloader_config(grml_flavour, device, target):
@@ -1468,7 +1569,7 @@ def handle_bootloader_config(grml_flavour, device, target):
         try:
             handle_syslinux_config(grml_flavour, target)
         except CriticalException, error:
         try:
             handle_syslinux_config(grml_flavour, target)
         except CriticalException, error:
-            logging.critical("Fatal: %s" % error)
+            logging.critical("Fatal: %s", error)
             sys.exit(1)
 
     if options.skipgrubconfig:
             sys.exit(1)
 
     if options.skipgrubconfig:
@@ -1477,16 +1578,17 @@ def handle_bootloader_config(grml_flavour, device, target):
         try:
             handle_grub_config(grml_flavour, device, target)
         except CriticalException, error:
         try:
             handle_grub_config(grml_flavour, device, target)
         except CriticalException, error:
-            logging.critical("Fatal: %s" % error)
+            logging.critical("Fatal: %s", error)
             sys.exit(1)
 
             sys.exit(1)
 
+
 def handle_dir(live_image, device):
     """Main logic for copying files of the currently running grml system.
 
     @live_image: directory where currently running live system resides (usually /live/image)
     @device: partition where the specified ISO should be installed to"""
 
 def handle_dir(live_image, device):
     """Main logic for copying files of the currently running grml system.
 
     @live_image: directory where currently running live system resides (usually /live/image)
     @device: partition where the specified ISO should be installed to"""
 
-    logging.info("Using %s as install base" % live_image)
+    logging.info("Using %s as install base", live_image)
 
     if os.path.isdir(device):
         logging.info("Specified target is a directory, therefore not mounting.")
 
     if os.path.isdir(device):
         logging.info("Specified target is a directory, therefore not mounting.")
@@ -1499,14 +1601,14 @@ def handle_dir(live_image, device):
         try:
             mount(device, device_mountpoint, "")
         except CriticalException, error:
         try:
             mount(device, device_mountpoint, "")
         except CriticalException, error:
-            logging.critical("Fatal: %s" % error)
+            logging.critical("Fatal: %s", error)
             cleanup()
             sys.exit(1)
 
     try:
         try:
             grml_flavour = identify_grml_flavour(live_image)
             cleanup()
             sys.exit(1)
 
     try:
         try:
             grml_flavour = identify_grml_flavour(live_image)
-            logging.info("Identified grml flavour \"%s\"." % grml_flavour)
+            logging.info("Identified grml flavour \"%s\".", grml_flavour)
             install_iso_files(grml_flavour, live_image, device, device_mountpoint)
         except TypeError:
             logging.critical("Fatal: a critical error happend during execution (not a grml ISO?), giving up")
             install_iso_files(grml_flavour, live_image, device, device_mountpoint)
         except TypeError:
             logging.critical("Fatal: a critical error happend during execution (not a grml ISO?), giving up")
@@ -1519,7 +1621,7 @@ def handle_dir(live_image, device):
                     os.rmdir(device_mountpoint)
                     unregister_tmpfile(device_mountpoint)
             except CriticalException, error:
                     os.rmdir(device_mountpoint)
                     unregister_tmpfile(device_mountpoint)
             except CriticalException, error:
-                logging.critical("Fatal: %s" % error)
+                logging.critical("Fatal: %s", error)
                 cleanup()
 
 
                 cleanup()
 
 
@@ -1529,21 +1631,21 @@ def handle_iso(iso, device):
     @iso: full path to the ISO that should be installed to the specified device
     @device: partition where the specified ISO should be installed to"""
 
     @iso: full path to the ISO that should be installed to the specified device
     @device: partition where the specified ISO should be installed to"""
 
-    logging.info("Using ISO %s" % iso)
+    logging.info("Using ISO %s", iso)
 
     iso_mountpoint = tempfile.mkdtemp(prefix="grml2usb")
     register_tmpfile(iso_mountpoint)
     remove_iso_mountpoint = True
 
     if not os.path.isfile(iso):
 
     iso_mountpoint = tempfile.mkdtemp(prefix="grml2usb")
     register_tmpfile(iso_mountpoint)
     remove_iso_mountpoint = True
 
     if not os.path.isfile(iso):
-        logging.critical("Fatal: specified ISO %s could not be read" % iso)
+        logging.critical("Fatal: specified ISO %s could not be read", iso)
         cleanup()
         sys.exit(1)
 
     try:
         mount(iso, iso_mountpoint, ["-o", "loop", "-t", "iso9660"])
     except CriticalException, error:
         cleanup()
         sys.exit(1)
 
     try:
         mount(iso, iso_mountpoint, ["-o", "loop", "-t", "iso9660"])
     except CriticalException, error:
-        logging.critical("Fatal: %s" % error)
+        logging.critical("Fatal: %s", error)
         sys.exit(1)
 
     if os.path.isdir(device):
         sys.exit(1)
 
     if os.path.isdir(device):
@@ -1558,14 +1660,14 @@ def handle_iso(iso, device):
         try:
             mount(device, device_mountpoint, "")
         except CriticalException, error:
         try:
             mount(device, device_mountpoint, "")
         except CriticalException, error:
-            logging.critical("Fatal: %s" % error)
+            logging.critical("Fatal: %s", error)
             cleanup()
             sys.exit(1)
 
     try:
         try:
             grml_flavour = identify_grml_flavour(iso_mountpoint)
             cleanup()
             sys.exit(1)
 
     try:
         try:
             grml_flavour = identify_grml_flavour(iso_mountpoint)
-            logging.info("Identified grml flavour \"%s\"." % grml_flavour)
+            logging.info("Identified grml flavour \"%s\".", grml_flavour)
             install_iso_files(grml_flavour, iso_mountpoint, device, device_mountpoint)
         except TypeError:
             logging.critical("Fatal: a critical error happend during execution (not a grml ISO?), giving up")
             install_iso_files(grml_flavour, iso_mountpoint, device, device_mountpoint)
         except TypeError:
             logging.critical("Fatal: a critical error happend during execution (not a grml ISO?), giving up")
@@ -1582,7 +1684,7 @@ def handle_iso(iso, device):
                     os.rmdir(device_mountpoint)
                     unregister_tmpfile(device_mountpoint)
             except CriticalException, error:
                     os.rmdir(device_mountpoint)
                     unregister_tmpfile(device_mountpoint)
             except CriticalException, error:
-                logging.critical("Fatal: %s" % error)
+                logging.critical("Fatal: %s", error)
                 cleanup()
 
 
                 cleanup()
 
 
@@ -1604,7 +1706,7 @@ def handle_mbr(device):
     # into /dev/loop of course, therefore use /dev/loop1 as mbr_device
     if mbr_device == "/dev/loop":
         mbr_device = device
     # into /dev/loop of course, therefore use /dev/loop1 as mbr_device
     if mbr_device == "/dev/loop":
         mbr_device = device
-        logging.info("Detected loop device - using %s as MBR device therefore" % mbr_device)
+        logging.info("Detected loop device - using %s as MBR device therefore", mbr_device)
         skip_install_mir_mbr = True
 
     try:
         skip_install_mir_mbr = True
 
     try:
@@ -1629,16 +1731,24 @@ def handle_vfat(device):
     @device: device that should checked / formated"""
 
     # make sure we have mkfs.vfat available
     @device: device that should checked / formated"""
 
     # make sure we have mkfs.vfat available
-    if options.fat16 and not options.force:
+    if options.fat16:
         if not which("mkfs.vfat") and not options.copyonly and not options.dryrun:
             logging.critical('Sorry, mkfs.vfat not available. Exiting.')
             logging.critical('Please make sure to install dosfstools.')
             sys.exit(1)
 
         if not which("mkfs.vfat") and not options.copyonly and not options.dryrun:
             logging.critical('Sorry, mkfs.vfat not available. Exiting.')
             logging.critical('Please make sure to install dosfstools.')
             sys.exit(1)
 
-        # make sure the user is aware of what he is doing
-        f = raw_input("Are you sure you want to format the specified partition with fat16? y/N ")
-        if f == "y" or f == "Y":
-            logging.info("Note: you can skip this question using the option --force")
+        exec_mkfs = False
+        if options.force:
+            print "Forcing mkfs.fat16 on %s as requested via option --force." % device
+            exec_mkfs = True
+        else:
+            # make sure the user is aware of what he is doing
+            f = raw_input("Are you sure you want to format the specified partition with fat16? y/N ")
+            if f == "y" or f == "Y":
+                logging.info("Note: you can skip this question using the option --force")
+                exec_mkfs = True
+
+        if exec_mkfs:
             try:
                 mkfs_fat16(device)
             except CriticalException, error:
             try:
                 mkfs_fat16(device)
             except CriticalException, error:
@@ -1708,7 +1818,7 @@ def handle_bootloader(device):
     if options.copyonly:
         logging.info("Not installing bootloader and its files as requested via option copyonly.")
     elif os.path.isdir(device):
     if options.copyonly:
         logging.info("Not installing bootloader and its files as requested via option copyonly.")
     elif os.path.isdir(device):
-        logging.info("Not installing bootloader as %s is a directory." % device)
+        logging.info("Not installing bootloader as %s is a directory.", device)
     else:
         install_bootloader(device)
 
     else:
         install_bootloader(device)
 
@@ -1772,13 +1882,13 @@ def main():
 
     handle_bootloader(device)
 
 
     handle_bootloader(device)
 
-    logging.info("Note: grml flavour %s was installed as the default booting system." % GRML_DEFAULT)
+    logging.info("Note: grml flavour %s was installed as the default booting system.", GRML_DEFAULT)
 
     for flavour in GRML_FLAVOURS:
 
     for flavour in GRML_FLAVOURS:
-        logging.info("Note: you can boot flavour %s using '%s' on the commandline." % (flavour, flavour))
+        logging.info("Note: you can boot flavour %s using '%s' on the commandline.", flavour, flavour)
 
     # finally be politely :)
 
     # finally be politely :)
-    logging.info("Finished execution of grml2usb (%s). Have fun with your grml system." % PROG_VERSION)
+    logging.info("Finished execution of grml2usb (%s). Have fun with your grml system.", PROG_VERSION)
 
 
 if __name__ == "__main__":
 
 
 if __name__ == "__main__":