Fix typo in option handling.
[grml2usb.git] / grml2usb
index bde7244..5aea516 100755 (executable)
--- a/grml2usb
+++ b/grml2usb
@@ -12,7 +12,6 @@ This script installs a grml system (either a running system or ISO[s]) to a USB
 
 """
 
 
 """
 
-# from __future__ import with_statement
 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
@@ -21,17 +20,17 @@ import glob
 import uuid
 
 # global variables
 import uuid
 
 # global variables
-PROG_VERSION = "0.9.20"
+PROG_VERSION = "0.9.25"
 MOUNTED = set()  # register mountpoints
 TMPFILES = set() # register tmpfiles
 DATESTAMP = time.mktime(datetime.datetime.now().timetuple()) # unique identifier for syslinux.cfg
 GRML_FLAVOURS = set() # which flavours are being installed?
 MOUNTED = set()  # register mountpoints
 TMPFILES = set() # register tmpfiles
 DATESTAMP = time.mktime(datetime.datetime.now().timetuple()) # unique identifier for syslinux.cfg
 GRML_FLAVOURS = set() # which flavours are being installed?
-global GRML_DEFAULT
-global UUID
+GRML_DEFAULT = None
+UUID = None
 
 def syslinux_warning(option, opt, value, parser):
     sys.stderr.write("Note: the --syslinux option is deprecated as syslinux " +
 
 def syslinux_warning(option, opt, value, parser):
     sys.stderr.write("Note: the --syslinux option is deprecated as syslinux " +
-            "is grml2usb's default. Continuing anyway.\n")
+                     "is grml2usb's default. Continuing anyway.\n")
     setattr(parser.values, option.dest, True)
 
 # if grub option is set, unset syslinux option
     setattr(parser.values, option.dest, True)
 
 # if grub option is set, unset syslinux option
@@ -226,6 +225,17 @@ def which(program):
     return None
 
 
     return None
 
 
+def get_defaults_file(iso_mount, flavour, name):
+    """get the default file for syslinux
+    """
+    bootloader_dirs = ['/boot/isolinux/', '/boot/syslinux/']
+    for dir in bootloader_dirs:
+        for name in name, \
+        "%s_%s" % (flavour_filename(flavour), name):
+            if os.path.isfile(iso_mount + dir + name):
+                return (dir, name)
+    return ('','')
+
 def search_file(filename, search_path='/bin' + os.pathsep + '/usr/bin'):
     """Given a search path, find file
 
 def search_file(filename, search_path='/bin' + os.pathsep + '/usr/bin'):
     """Given a search path, find file
 
@@ -234,10 +244,18 @@ def search_file(filename, search_path='/bin' + os.pathsep + '/usr/bin'):
     file_found = 0
     paths = search_path.split(os.pathsep)
     current_dir = '' # make pylint happy :)
     file_found = 0
     paths = search_path.split(os.pathsep)
     current_dir = '' # make pylint happy :)
+
+    def match_file(cwd):
+        return  os.path.exists(os.path.join(cwd, filename))
+
     for path in paths:
     for path in paths:
+        current_dir = path
+        if match_file(current_dir):
+            file_found = 1
+            break
         # pylint: disable-msg=W0612
         for current_dir, directories, files in os.walk(path):
         # pylint: disable-msg=W0612
         for current_dir, directories, files in os.walk(path):
-            if os.path.exists(os.path.join(current_dir, filename)):
+            if match_file(current_dir):
                 file_found = 1
                 break
     if file_found:
                 file_found = 1
                 break
     if file_found:
@@ -342,8 +360,8 @@ 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('-', ''),
-        'uid': UUID, 'bootoptions': bootoptions } )
+       'flavour_filename': grml_flavour.replace('-', ''),
+       'uid': UUID, 'bootoptions': bootoptions } )
 
 
 def generate_flavour_specific_grub2_config(grml_flavour, bootoptions):
 
 
 def generate_flavour_specific_grub2_config(grml_flavour, bootoptions):
@@ -607,7 +625,6 @@ def install_grub(device):
                 mount(device, device_mountpoint, "")
 
                 # If using --grub-mbr then make sure we install grub in MBR instead of PBR
                 mount(device, device_mountpoint, "")
 
                 # 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():
                 if options.grubmbr:
                     logging.debug("Using option --grub-mbr ...")
                     if device[-1:].isdigit():
@@ -619,14 +636,14 @@ def install_grub(device):
 
                 logging.info("Installing grub as bootloader")
                 logging.debug("grub-install --recheck --no-floppy --root-directory=%s %s",
 
                 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",
-                    "--root-directory=%s" % device_mountpoint, grub_device], stdout=file(os.devnull, "r+"))
+                              device_mountpoint, grub_device)
+                proc = subprocess.Popen(["grub-install", "--recheck", "--force", "--no-floppy",
+                                         "--root-directory=%s" % device_mountpoint, grub_device], stdout=file(os.devnull, "r+"))
                 proc.wait()
                 if proc.returncode != 0:
                     # raise Exception("error executing grub-install")
                     logging.critical("Fatal: error executing grub-install (please check the grml2usb FAQ or drop the --grub option)")
                 proc.wait()
                 if proc.returncode != 0:
                     # raise Exception("error executing grub-install")
                     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.")
+                    logging.critical("Note:  if using grub2 consider using the --grub-mbr option as grub considers PBR problematic.")
                     cleanup()
                     sys.exit(1)
             except CriticalException, error:
                     cleanup()
                     sys.exit(1)
             except CriticalException, error:
@@ -778,9 +795,9 @@ def install_mir_mbr(mbrtemplate, device, partition, ismirbsdmbr=True):
         raise Exception("error executing dd (first run)")
 
     logging.debug("executing: dd if=%s of=%s bs=%s count=1 conv=notrunc", mbrtemplate,
         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)
+                  tmpf.name, nmbrbytes)
     proc = subprocess.Popen(["dd", "if=%s" % mbrtemplate, "of=%s" % tmpf.name, "bs=%s" % nmbrbytes,
     proc = subprocess.Popen(["dd", "if=%s" % mbrtemplate, "of=%s" % tmpf.name, "bs=%s" % nmbrbytes,
-        "count=1", "conv=notrunc"], stderr=file(os.devnull, "r+"))
+                             "count=1", "conv=notrunc"], stderr=file(os.devnull, "r+"))
     proc.wait()
     if proc.returncode != 0:
         raise Exception("error executing dd (second run)")
     proc.wait()
     if proc.returncode != 0:
         raise Exception("error executing dd (second run)")
@@ -791,15 +808,15 @@ def install_mir_mbr(mbrtemplate, device, partition, ismirbsdmbr=True):
 
     if ismirbsdmbr:
         mbrcode = mbrcode[0:439] + chr(partition) + \
 
     if ismirbsdmbr:
         mbrcode = mbrcode[0:439] + chr(partition) + \
-          mbrcode[440:510] + "\x55\xAA"
+                mbrcode[440:510] + "\x55\xAA"
     else:
         actives = ["\x00", "\x00", "\x00", "\x00"]
         actives[partition] = "\x80"
         mbrcode = mbrcode[0:446] + actives[0] + \
     else:
         actives = ["\x00", "\x00", "\x00", "\x00"]
         actives[partition] = "\x80"
         mbrcode = mbrcode[0:446] + actives[0] + \
-          mbrcode[447:462] + actives[1] + \
-          mbrcode[463:478] + actives[2] + \
-          mbrcode[479:494] + actives[3] + \
-          mbrcode[495:510] + "\x55\xAA"
+                mbrcode[447:462] + actives[1] + \
+                mbrcode[463:478] + actives[2] + \
+                mbrcode[479:494] + actives[3] + \
+                mbrcode[495:510] + "\x55\xAA"
 
     tmpf.file.seek(0)
     tmpf.file.truncate()
 
     tmpf.file.seek(0)
     tmpf.file.truncate()
@@ -808,7 +825,7 @@ def install_mir_mbr(mbrtemplate, device, partition, ismirbsdmbr=True):
 
     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",
 
     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+"))
+                             "conv=notrunc"], stderr=file(os.devnull, "r+"))
     proc.wait()
     if proc.returncode != 0:
         raise Exception("error executing dd (third run)")
     proc.wait()
     if proc.returncode != 0:
         raise Exception("error executing dd (third run)")
@@ -946,7 +963,7 @@ def check_for_fat(partition):
 
     try:
         udev_info = subprocess.Popen(["/sbin/blkid", "-s", "TYPE", "-o", "value", partition],
 
     try:
         udev_info = subprocess.Popen(["/sbin/blkid", "-s", "TYPE", "-o", "value", partition],
-                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+                                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         filesystem = udev_info.communicate()[0].rstrip()
 
         if udev_info.returncode == 2:
         filesystem = udev_info.communicate()[0].rstrip()
 
         if udev_info.returncode == 2:
@@ -1004,12 +1021,12 @@ def get_uuid(target):
     uuid_file_name = conf_target + "/bootid.txt"
     if os.path.isdir(conf_target):
         if os.path.isfile(uuid_file_name):
     uuid_file_name = conf_target + "/bootid.txt"
     if os.path.isdir(conf_target):
         if os.path.isfile(uuid_file_name):
-           uuid_file = open(uuid_file_name, 'r')
-           uid = uuid_file.readline().strip()
-           uuid_file.close()
-           return uid
+            uuid_file = open(uuid_file_name, 'r')
+            uid = uuid_file.readline().strip()
+            uuid_file.close()
+            return uid
         else:
         else:
-           return write_uuid(uuid_file_name)
+            return write_uuid(uuid_file_name)
     else:
         execute(mkdir, conf_target)
         return write_uuid(uuid_file_name)
     else:
         execute(mkdir, conf_target)
         return write_uuid(uuid_file_name)
@@ -1031,7 +1048,9 @@ def copy_system_files(grml_flavour, iso_mount, target):
         execute(mkdir, squashfs_target)
     exec_rsync(squashfs, squashfs_target + grml_flavour + '.squashfs')
 
         execute(mkdir, squashfs_target)
     exec_rsync(squashfs, squashfs_target + grml_flavour + '.squashfs')
 
-    filesystem_module = search_file('filesystem.module', iso_mount)
+    for prefix in grml_flavour + "/", "":
+        filesystem_module = search_file(prefix + 'filesystem.module', iso_mount)
+        if filesystem_module: break
     if filesystem_module is None:
         logging.critical("Fatal: filesystem.module not found")
         raise CriticalException("error locating filesystem.module file")
     if filesystem_module is None:
         logging.critical("Fatal: filesystem.module not found")
         raise CriticalException("error locating filesystem.module file")
@@ -1039,17 +1058,22 @@ def copy_system_files(grml_flavour, iso_mount, target):
         exec_rsync(filesystem_module, squashfs_target + 'filesystem.module')
 
 
         exec_rsync(filesystem_module, squashfs_target + 'filesystem.module')
 
 
-    release_target = target + '/boot/release/' + grml_flavour.replace('-', '')
+    release_path = 'boot/release/' + grml_flavour.replace('-', '')
+    release_target = target + "/" + release_path
     execute(mkdir, release_target)
 
     execute(mkdir, release_target)
 
-    kernel = search_file('linux26', iso_mount)
+    prefix = ""
+    if os.path.isdir(iso_mount + '/boot/release'):
+        prefix = release_path + '/'
+
+    kernel = search_file(prefix + 'linux26', iso_mount)
     if kernel is None:
         logging.critical("Fatal kernel not found")
         raise CriticalException("error locating kernel file")
     else:
         exec_rsync(kernel, release_target + '/linux26')
 
     if kernel is None:
         logging.critical("Fatal kernel not found")
         raise CriticalException("error locating kernel file")
     else:
         exec_rsync(kernel, release_target + '/linux26')
 
-    initrd = search_file('initrd.gz', iso_mount)
+    initrd = search_file(prefix + 'initrd.gz', iso_mount)
     if initrd is None:
         logging.critical("Fatal: initrd not found")
         raise CriticalException("error locating initrd file")
     if initrd is None:
         logging.critical("Fatal: initrd not found")
         raise CriticalException("error locating initrd file")
@@ -1066,7 +1090,33 @@ def copy_grml_files(iso_mount, target):
     grml_target = target + '/grml/'
     execute(mkdir, grml_target)
 
     grml_target = target + '/grml/'
     execute(mkdir, grml_target)
 
-    for myfile in 'grml-cheatcodes.txt', 'grml-version', 'LICENSE.txt', 'md5sums', 'README.txt':
+    copy_files = [ 'grml-cheatcodes.txt', 'LICENSE.txt', 'md5sums', 'README.txt' ]
+    # handle grml-version
+    new_grml_version = search_file('grml-version', grml_target)
+    if new_grml_version:
+        orig_grml_version = search_file('grml-version', iso_mount)
+        if not orig_grml_version:
+            logging.warn("Warning: %s could not be found - can not install it", orig_grml_version)
+        else:
+            try:
+                new_file = open(new_grml_version, 'a+')
+                new_flavours = [ get_flavour(l) for l in new_file.readlines() ]
+
+                old_file = open(orig_grml_version, 'r')
+                old_lines = old_file.readlines()
+                for line in old_lines:
+                    if not get_flavour(line) in new_flavours:
+                        new_file.write(line)
+
+            except IOError, e:
+                logging.warn("Warning: Could not write file")
+            finally:
+                new_file.close()
+                old_file.close()
+    else:
+        copy_files.append('grml-version')
+
+    for myfile in copy_files:
         grml_file = search_file(myfile, iso_mount)
         if grml_file is None:
             logging.warn("Warning: myfile %s could not be found - can not install it", myfile)
         grml_file = search_file(myfile, iso_mount)
         if grml_file is None:
             logging.warn("Warning: myfile %s could not be found - can not install it", myfile)
@@ -1169,34 +1219,40 @@ def copy_bootloader_files(iso_mount, target):
     logo = search_file('logo.16', iso_mount)
     exec_rsync(logo, syslinux_target + 'logo.16')
 
     logo = search_file('logo.16', iso_mount)
     exec_rsync(logo, syslinux_target + 'logo.16')
 
+
     for ffile in ['f%d' % number for number in range(1,11) ]:
         bootsplash = search_file(ffile, iso_mount)
         if not bootsplash:
             continue
         exec_rsync(bootsplash, syslinux_target + ffile)
 
     for ffile in ['f%d' % number for number in range(1,11) ]:
         bootsplash = search_file(ffile, iso_mount)
         if not bootsplash:
             continue
         exec_rsync(bootsplash, syslinux_target + ffile)
 
+    loopback_cfg = search_file("loopback.cfg", iso_mount)
+    if loopback_cfg:
+        directory = os.path.dirname(loopback_cfg)
+        directory = directory.replace(iso_mount, "")
+        if not os.path.isdir(target + "/" + directory):
+            os.mkdir(target + os.path.sep + directory)
+        exec_rsync(loopback_cfg, target + os.path.sep + directory)
+
     # 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')
 
     # 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')
 
-    bootloader_dirs = ['/boot/isolinux/', '/boot/syslinux/']
-    source_dir = None
-    for dir in bootloader_dirs:
-        if glob.glob(iso_mount + dir + '*default.cfg'):
-            source_dir = dir
-            break
-    else:
+    source_dir, name = get_defaults_file(iso_mount, GRML_DEFAULT, "default.cfg")
+    (source_dir,options) = get_defaults_file(iso_mount, GRML_DEFAULT, "grml.cfg")
+
+    if not source_dir:
         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
 
         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 expr in '*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':
+    for expr in name, 'distri.cfg', \
+        options, 'grml.png', 'hd.cfg', 'isolinux.cfg', 'isolinux.bin', \
+        'isoprompt.cfg', 'options.cfg', \
+        'prompt.cfg', 'vesamenu.c32', 'vesamenu.cfg', 'grml.png', '*.c32':
         files = glob.glob(iso_mount + source_dir + expr)
         for path in files:
             filename = os.path.basename(path)
         files = glob.glob(iso_mount + source_dir + expr)
         for path in files:
             filename = os.path.basename(path)
@@ -1252,9 +1308,9 @@ def install_iso_files(grml_flavour, iso_mount, device, target):
     # * provide alternative search_file() if file information is stored in a config.ini file?
     # * catch "install: .. No space left on device" & CO
 
     # * provide alternative search_file() if file information is stored in a config.ini file?
     # * catch "install: .. No space left on device" & CO
 
+    global GRML_DEFAULT
+    GRML_DEFAULT = grml_flavour
     if options.dryrun:
     if options.dryrun:
-        global GRML_DEFAULT
-        GRML_DEFAULT = grml_flavour
         return 0
     elif not options.bootloaderonly:
         logging.info("Copying files. This might take a while....")
         return 0
     elif not options.bootloaderonly:
         logging.info("Copying files. This might take a while....")
@@ -1291,6 +1347,11 @@ def uninstall_files(device):
     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 get_flavour(str):
+    """Returns the flavour of a grml version string
+    """
+    return re.match(r'[\w-]*', str).group()
+
 def identify_grml_flavour(mountpath):
     """Get name of grml flavour
 
 def identify_grml_flavour(mountpath):
     """Get name of grml flavour
 
@@ -1303,17 +1364,21 @@ def identify_grml_flavour(mountpath):
         logging.critical("Error: could not find grml-version file.")
         raise
 
         logging.critical("Error: could not find grml-version file.")
         raise
 
+    flavours = []
+    tmpfile = None
     try:
         tmpfile = open(version_file, 'r')
     try:
         tmpfile = open(version_file, 'r')
-        grml_info = tmpfile.readline()
-        grml_flavour = re.match(r'[\w-]*', grml_info).group()
-    except TypeError:
+        for line in tmpfile.readlines():
+            flavours.append(get_flavour(line))
+    except TypeError, e:
         raise
     except Exception, e:
         logging.critical("Unexpected error: %s", e)
         raise
         raise
     except Exception, e:
         logging.critical("Unexpected error: %s", e)
         raise
+    finally:
+        if tmpfile: tmpfile.close()
 
 
-    return grml_flavour
+    return flavours
 
 
 def modify_grub_config(filename):
 
 
 def modify_grub_config(filename):
@@ -1493,14 +1558,16 @@ def add_entry_if_not_present(filename, entry):
 
     data.close()
 
 
     data.close()
 
-
+def flavour_filename(flavour):
+    return flavour.replace('-', '_')
 
 def adjust_syslinux_bootoptions(src, flavour):
 
 def adjust_syslinux_bootoptions(src, flavour):
-    append_re = re.compile("^(\s*append.*)$", re.I)
+    append_re = re.compile("^(\s*append.*/boot/release.*)$", 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)")
     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)")
-    bootid_re = re.compile("(bootid)=[\w_-]+")
+    bootid_re = re.compile("bootid=[\w_-]+")
+    live_media_path_re = re.compile("live-media-path=[\w_/-]+")
 
     # do NOT write "None" in kernel cmdline
     if options.bootoptions is None:
 
     # do NOT write "None" in kernel cmdline
     if options.bootoptions is None:
@@ -1521,7 +1588,8 @@ def adjust_syslinux_bootoptions(src, flavour):
         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 = 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 = bootid_re.sub(' ', line)
+        line = bootid_re.sub('', line)
+        line = live_media_path_re.sub('', 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)
         line = append_re.sub(r'\1 %s=%s ' % ("bootid", UUID), 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)
         line = append_re.sub(r'\1 %s=%s ' % ("bootid", UUID), line)
@@ -1556,7 +1624,6 @@ def modify_filenames(grml_flavour, target, filenames):
         old_filename = "%s/%s" % (target, filename)
         new_filename = "%s/%s_%s" % (target, grml_filename, filename)
         os.rename(old_filename, new_filename)
         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):
 
 
 def remove_default_entry(filename):
@@ -1599,13 +1666,14 @@ def handle_syslinux_config(grml_flavour, target):
     prompt_name.close()
 
     initial_syslinux_config(syslinux_target)
     prompt_name.close()
 
     initial_syslinux_config(syslinux_target)
+    flavour_filename = grml_flavour.replace('-', '_')
+
     if search_file('default.cfg', syslinux_target):
         modify_filenames(grml_flavour, syslinux_target, ['grml.cfg', 'default.cfg'])
 
     filename = search_file("new_hidden.cfg", syslinux_target)
 
 
     if search_file('default.cfg', 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"
     # process hidden file
     if not search_file("hidden.cfg", syslinux_target):
         new_hidden = syslinux_target + "hidden.cfg"
@@ -1625,10 +1693,10 @@ def handle_syslinux_config(grml_flavour, target):
     new_default = "%s_default.cfg" % (flavour_filename)
     entry = 'include %s\n' % new_default
     defaults_file = '%s/defaults.cfg' % syslinux_target
     new_default = "%s_default.cfg" % (flavour_filename)
     entry = 'include %s\n' % new_default
     defaults_file = '%s/defaults.cfg' % syslinux_target
+    new_default_with_path = "%s/%s" % (syslinux_target, new_default)
+    new_grml_cfg = "%s/%s_grml.cfg" % ( syslinux_target, flavour_filename)
 
     if os.path.isfile(defaults_file):
 
     if os.path.isfile(defaults_file):
-        new_default_with_path = "%s/%s" % (syslinux_target, new_default)
-        new_grml_cfg = "%s/%s_grml.cfg" % ( syslinux_target, flavour_filename)
 
         # remove default menu entry in menu
         remove_default_entry(new_default_with_path)
 
         # remove default menu entry in menu
         remove_default_entry(new_default_with_path)
@@ -1637,6 +1705,9 @@ def handle_syslinux_config(grml_flavour, target):
         adjust_labels(new_default_with_path, r'\1 %s' % grml_flavour)
         adjust_labels(new_grml_cfg, r'\1 %s-\2' % grml_flavour)
 
         adjust_labels(new_default_with_path, r'\1 %s' % grml_flavour)
         adjust_labels(new_grml_cfg, r'\1 %s-\2' % grml_flavour)
 
+    # always adjust bootoptions
+    adjust_syslinux_bootoptions(new_default_with_path, grml_flavour)
+    adjust_syslinux_bootoptions(new_grml_cfg, grml_flavour)
 
     add_entry_if_not_present("%s/defaults.cfg" % syslinux_target, entry)
 
 
     add_entry_if_not_present("%s/defaults.cfg" % syslinux_target, entry)
 
@@ -1696,9 +1767,15 @@ def handle_dir(live_image, device):
 
     try:
         try:
 
     try:
         try:
-            grml_flavour = identify_grml_flavour(live_image)
-            logging.info("Identified grml flavour \"%s\".", grml_flavour)
-            install_iso_files(grml_flavour, live_image, device, device_mountpoint)
+            grml_flavours = identify_grml_flavour(live_image)
+            worked_flavours = []
+            for flavour in grml_flavours:
+                if flavour in worked_flavours:
+                    continue
+                else:
+                    worked_flavours.append(flavour)
+                logging.info("Identified grml flavour \"%s\".", flavour)
+                install_iso_files(flavour, live_image, device, device_mountpoint)
         except TypeError:
             logging.critical("Fatal: a critical error happend during execution (not a grml ISO?), giving up")
             sys.exit(1)
         except TypeError:
             logging.critical("Fatal: a critical error happend during execution (not a grml ISO?), giving up")
             sys.exit(1)
@@ -1759,9 +1836,15 @@ def handle_iso(iso, device):
 
     try:
         try:
 
     try:
         try:
-            grml_flavour = identify_grml_flavour(iso_mountpoint)
-            logging.info("Identified grml flavour \"%s\".", grml_flavour)
-            install_iso_files(grml_flavour, iso_mountpoint, device, device_mountpoint)
+            grml_flavours = identify_grml_flavour(iso_mountpoint)
+            worked_flavours = []
+            for flavour in grml_flavours:
+                if flavour in worked_flavours:
+                    continue
+                else:
+                    worked_flavours.append(flavour)
+                logging.info("Identified grml flavour \"%s\".", flavour)
+                install_iso_files(flavour, iso_mountpoint, device, device_mountpoint)
         except TypeError:
             logging.critical("Fatal: a critical error happend during execution (not a grml ISO?), giving up")
             sys.exit(1)
         except TypeError:
             logging.critical("Fatal: a critical error happend during execution (not a grml ISO?), giving up")
             sys.exit(1)
@@ -1858,7 +1941,7 @@ def handle_vfat(device):
             logging.critical("Execution failed: %s", error)
             sys.exit(1)
 
             logging.critical("Execution failed: %s", error)
             sys.exit(1)
 
-    if not os.path.isdir(device) and not check_for_usbdevice(device):
+    if not os.path.isdir(device) and not check_for_usbdevice(device) and not options.force:
         print "Warning: the specified device %s does not look like a removable usb device." % device
         f = raw_input("Do you really want to continue? y/N ")
         if f == "y" or f == "Y":
         print "Warning: the specified device %s does not look like a removable usb device." % device
         f = raw_input("Do you really want to continue? y/N ")
         if f == "y" or f == "Y":