#!/usr/bin/perl
#
# MyLiveCD iso build script
#
# Copyright (C) 2014 Bill Reynolds <texstar@gmail.com>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# Adapted from the Mklivecd
#

use strict;
use lib qw(/usr/lib/libDrakX);
require services;


### dependancies
use Getopt::Long;
use MDK::Common;
use run_program;
use Storable qw(store);
use threads::shared;
use POSIX qw(ceil);

### useful functions
sub get_exec { my $r = qx($_[0]); chomp($r); $r; };

### global "constants"
my $PROG_VERSION   = '0.9.10';
my $PROG_NAME      = 'mylivecd';
my $ESC            = "\x1B[";
my $URL            = "http://pclinuxos.com/";
my $COPYRIGHT      = "Copyright (C) 2016, Texstar <texstar at gmail.com>";

### global variables
my $starttime      = time;
my $workdir        = undef;
my $kernel26       = undef;
my $kernelver      = "3.14.6";
my $dietarch       = undef;
my $libdir         = "lib";
my $depmod         = "/sbin/depmod";
my $modfile        = "/etc/modules.conf";
my $modext         = undef;
my $modules        = undef;
my $modules_opt    = "";
my $modules_26     = "";
my $modules_opt_26 = "";
my $nodirs         = '^/[.].* ^/run$ ^/dev$ ^/initrd$ ^/lost+found$ ^/mnt$ ^/media$ ^/proc$ ^/sys$ ^/tmp$ ^/var/tmp$ ^/root/tmp$ ^/home/guest/tmp$ ^/proc/asound ^/root/.local/share/akonadi ^/home/guest/.local/share/akonadi ^/root/.synaptic/log ^/home/guest/.config/pulse ^/home/guest/.pulse ^/usr/share/doc';
my $nofiles        = '^/[.].* ^/fastboot$ /core[.][0-9][0-9]*$ .*~$ .*[.]rpmnew$ .*[.]rpmsave$ [.]bash_history$ [.]fonts[.]cache-[0-9]$ [.]xauth.* [.]wh[.]* [.]xsession-errors$ icon-theme.cache$ ^/var/run/ ^/var/lock/subsys/ ^/var/lib/dhcp/ ^/etc/modprobe.conf ^/etc/sysconfig/network-scripts/ifcfg-* ^/etc/sysconfig/network-scripts/wireless.d/* ^/etc/udev/rules.d/70-persistent* ^/var/lib/alsa/asound.state ^/etc/asound.state ^/etc/modprobe.preload.d/00-amdgpu ^/etc/sysconfig/harddrake2/previous_hw ^/var/lib/rpm/__db.* ^/etc/sysconfig/finish-install ^/var/lib/speedboot/* ^/etc/modprobe.d/sound ^/var/log/mysqld/mysqlmanager.log ^/var/cache/apt/*.bin ^/var/lib/apt/lists/* ^/var/log/* ^/home/guest/.config/kxkbrc ^/var/lib/NetworkManager/* ^/etc/NetworkManager/system-connections/*';
my $loopmod        = undef;
my $loopcmp        = undef;
my $o_stage2       = undef;
my $finaliso       = "livecd.iso";
my $loader         = "isolinux/isolinux.bin";
my $md5sum	   = undef;
my $genisoimage_opts   = "";	# Fix for concat of undef in iso looptype
my @services	   = ();

### command-line options
my $o_verbose;
my $o_workdir;
my $o_root         = "/";
my $o_tmp          = "/tmp";
my $o_looptype     = "sqfs";
my $o_keyboard     = 'us';
my $o_resolution   = '800x600';
my $o_theme        = 'PCLinuxOS';
my $o_vgamode      = '788';
my $o_splash       = "silent";
my $o_bootloader   = "iso";
my $o_ufs          = 'overlayfs';
my $o_kernel       = get_exec("uname -r");
my $o_mbkopt       = "";
my $o_mbkopt_label = "";
my $o_lz4;
my $o_gzip;
my $o_xz;
my $o_zstd;

my $o_timeout      = 90;
my %opts           = ( # these are all the options with defaults
	'root'         => \$o_root,
	'tmp'          => \$o_tmp,
	'keyboard'     => \$o_keyboard,
	'resolution'   => \$o_resolution,
	'splash'       => \$o_splash,
	'kernel'       => \$o_kernel,
	'timeout'      => \$o_timeout,
	'bootloader'   => \$o_bootloader,
	'mbkopt'       => \$o_mbkopt,
	'mbkopt_label' => \$o_mbkopt_label,
	'ufs'          => \$o_ufs
);

my $mod_ext        = "";
if ( -e "$o_root/lib/modules/$o_kernel/kernel/fs/squashfs/squashfs.ko.gz" ) {
$mod_ext        = "gz";
}
else {
$mod_ext        = "xz";
}

### startup banner
sub print_banner {
	print STDERR "$PROG_NAME, version $PROG_VERSION, $URL
$COPYRIGHT

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
";
}


### usage
sub print_usage {
	print STDERR "Usage:
   $0 [options] <livecd-image>

General Options:
   --help                          Display this message
   --version                       Display version information
   --verbose                       Be verbose in output
   --noclean                       Don't remove temporary files on exit.'
   --workdir			   Specify a working directory which will not be cleaned.
   --debug                         Display some extra debugging information
                                   while building the CD. (Usefull for bug
                                   reports to the developers.)

Image generation:
   --root <rootdir>                Root directory of the live filesystem to use
                                   as the for the image of the LiveCD.
                                   (default: $o_root)
   --tmp <tmpdir>                  Name of the directory to be used for
                                   temporary file storage.
                                   (default: $o_tmp)
   --img <image>                   Name of the saved compressed image. When an
                                   image by this name is found, it will not be
                                   re-created or overwritten, rather the
                                   existing image will be re-used, i.e. the
                                   compressed image is not re-built.
   --nofile <ex1>[,][...]          Excludes files from the final image. (Also
                                   see the --nodir option for a full
                                   description)
   --nodir <ex1>[,][...]           Excludes directories from the final image.
                                   Patterns passed to this option (as with the
                                   --nofile option) should be valid in a grep(1)
                                   search, e.g. --nodir=^/home/jaco,^/root/.mcop
                                   will exclude both the /home/jaco and
                                   /root/.mcop directories from the final
                                   LiveCD.
   --sort <file>                   Sort the files on the compressed iso image
                                   according to the genisoimage-style sort specifier
                                   as detailed in file.
   --kernel <kernel>               Kernel to use as default for the LiveCD
                                   image. (Output of uname -r)
                                   (default: $o_kernel)
   --lz4                           Use lz4 compression for the image
   --gzip                          Use gzip compression for the image
   --xz                            Use xz compression for the image
   --zstd                          Use zstd compression for the image
   
Boot options:
   --bootopt <option>              Specify an additional boot option to pass to
                                   the kernel command-line.
   --bootmsg <msg>                 Use 'msg' as the isolinux boot message.
   --bootkey <key=msg>             Display 'msg' on key 'key' from isolinux.
   --bootimg <img>                 Use 'img' (LSS format) as the isolinux.
                                   background display image.
   --bootloader <iso|grub|usb>     The bootloader to use on the livecd i.e. isolinux, 
                                   GRUB or syslinux for usb stick
   --bootmenu <file>               What boot menu definition file should be used
                                   in case that bootloader option is set to iso or grub.
                                   For iso this file must be named 'isolinux.cfg',
				   for grub the name must be 'grub.cfg'.
				   Boot menu will be generated if not specified.
   --boottheme <name>              Which gfxboot theme should be used.
                                   Defaults to 'pclinuxos'
   --bootlang <lang code>          Which language shound be used as default
                                   in the boot menu.
				   Defaults to 'en'.
   --mbkopt <kernel>               Create the ISO with multi boot kernel option.
   --mbkopt_label <Menu Label>     Customize the menu entry for the 2nd kernel

   --ufs <overlayfs|unionfs>       Specify the overlayfs file system.
   --timeout <sec>                 Specify the default ISO Linux prompt timeout
                                   in seconds.
                                   (default: $o_timeout)
   --noprompt                      Disable ISO Linux prompt (i.e. prompt 0).
   --keyboard <mapping>            Specify a different keyboard layout as
                                   default for the LiveCD.
                                   (default: $o_keyboard)
   --resolution <res>              Specify the resolution for the framebuffer
                                   output device. (Either resolution or normal)
                                   (default: $o_resolution)
   --splash <silent|verbose|no>    Create the LiveCD with bootsplash support if
                                   available on the root filesystem.
                                   (default: $o_splash)
   --fstab <options>               Override the default options for the fstab on
                                   the LiveCD. Options are one or more of 'auto'
                                   and 'rw', for example '--fstab=rw,auto' will
                                   automatically mount all detected partitions
                                   rw.

ISO Image options:
   --isoextrafiles <path>          Add the files in 'path' to the root of the
                                   LiveCD ISO image.
   --application <id>              Use the specified iso application ID, as '-A'
                                   option to genisoimage.
   --volumeid <id>                 Use the specified iso volume ID, as a '-V'
                                   option to genisoimage.
   --preparer <prep>               Use the specified preparer ID, as a '-p'
                                   option to genisoimage.
   --publisher <pub>               Use the specified publisher ID, as a '-P'
                                   option to genisoimage.
   --md5sum                        Compute and implant the md5sum to verify media.

   
Behaviour:
   --usbhome                       Use USB memory stick devices as a persistent
                                   home when available/connected on bootup.

Examples:
    $0 --nodir ^/usr/src/RPM,^/root/tmp livecd.iso
    $0 --splash=silent livecd.iso

";
	exit(1);
}
# --- Default settings ---
my $o_persistence = "no";   # default
my $o_unionfs     = "afs"; # default non-persistent FS

# --- Ask user ---
print "Persistence yes? If no press enter. (yes/no) [no]: ";
chomp(my $answer = <STDIN>);

if ($answer =~ /^y/i) {
    $o_persistence = "yes";
    $o_unionfs     = "unionfs";
    print "Persistence enabled (unionfs)\n";
} else {
    print "Persistence disabled\n";
}

my $rc_sysinit_path = "/usr/share/mylivecd/rc.sysinit";

# read the file
open my $in, '<', $rc_sysinit_path
  or die "Can't read $rc_sysinit_path: $!";
my @lines = <$in>;
close $in;

$o_unionfs = defined $o_unionfs ? $o_unionfs : 'overlay';

# process each line: comment/uncomment unionfs vs overlay
for my $i (0..$#lines) {
    if ( $lines[$i] =~ /(^\s*)(#?)(\s*)(unionfs\b.*)/ ) {
        my ($indent, $hash, $spc, $rest) = ($1,$2,$3,$4);
        if ($o_unionfs eq 'unionfs') {
            $lines[$i] = $indent . $rest . "\n";
        } else {
            # comment: keep indentation, add single '#' then a space then command
            $lines[$i] = $indent . '#' . ($spc || '') . $rest . "\n";
        }
        next;
    }

    # overlay line (match 'mount -t overlay')
    if ( $lines[$i] =~ /(^\s*)(#?)(\s*)(mount\s+-t\s+overlay\b.*)/i ) {
        my ($indent, $hash, $spc, $rest) = ($1,$2,$3,$4);
        if ($o_unionfs eq 'unionfs') {
            # comment overlay
            $lines[$i] = $indent . '#' . ($spc || '') . $rest . "\n";
        } else {
            # uncomment overlay
            $lines[$i] = $indent . $rest . "\n";
        }
        next;
    }
}

# write back (atomic-ish)
open my $out, '>', "$rc_sysinit_path.new" or die "Can't write $rc_sysinit_path.new: $!";
print $out @lines;
close $out;
rename "$rc_sysinit_path.new", $rc_sysinit_path
  or die "Can't replace $rc_sysinit_path: $!";


### format an elapsed time
sub fmt_elapsed {
	my ($t) = @_;
	my $h = int($t/3600);
	my $m = int(($t - $h*3600)/60);
	my $s = int($t - $h*3600 - $m*60);
	sprintf("%02d:%02d:%02d", $h, $m, $s);
}


### format a number
sub fmt_number {
	my ($n) = @_;
	$n = $n/1000;
	my $t = int($n/1000);
	my $h = $n - $t*1000;
	my $r = sprintf("%0.3f", $h);
	$r =~ s/[.]/,/;
	if ($t > 0) {
		$r = "0$r" while (length($r) < 7);
		$r = "$t,$r";
	}
	$r;
}

### progress bar globals
my $PROGRESS_MAX     = 76;
my $progress_max     : shared = 0;
my $progress_inc     : shared = 0;
my $progress_curr    : shared = 0;
my $progress_start   : shared = 0;
my $progress_tot     : shared = 0;
my $progress_text    : shared = undef;
my $progress_ttext   : shared = undef;
my $progress_timer   : shared = -1; # 0 to active, -1 to deactivate
my $progress_last    : shared = 0;

### to be called before we use the progress bar
sub start_progress {
	my ($title, $max) = @_;
	my $i = 0;
	$| = 1;
	print $title.":\n";
	print "[";
	print " " while ($i++ < $PROGRESS_MAX);
	print "]";
	$progress_max = $max;
	$progress_inc = $progress_max/$PROGRESS_MAX;
	$progress_start = time;
	$progress_curr = 0;
	$progress_tot = 0;
	$progress_text = undef;
	$progress_ttext = undef;
	$progress_last = 0;
	print $ESC."1A".$ESC."52G";
	print "[  0.00% ".fmt_elapsed(0)."/".fmt_elapsed(0)."]";
	start_thread();
}


### while we are progressing
sub set_progress {
	my ($curr, $text, $thr) = @_;
	$progress_last = $curr;
	$progress_last = $progress_max if ($progress_last > $progress_max);
	my $num = int($progress_last/$progress_inc) - $progress_curr;
	if (defined($opts{verbose}) && defined($text)) {
		$text =~ s/\[//g;
		$text =~ s/\]//g;
		$text =~ s/\+//g;
#		if (!defined($progress_text) || !($text =~ m/^$progress_text$/)) {
		if (!defined($progress_text) || ($text ne $progress_text)) {
			if (defined($thr) || ($progress_timer == -1)) {
				$progress_text = $text;
				$progress_ttext = $text;
				print "\n";
				$progress_curr += $num;
				print $ESC."1G";
				chomp($text);
				$text =~ s#\r?\n# #gs; # remove newlines in text
				if (length($text) > 72) {
					print "  ".pack("A72", $text)." ...";
				}
				else {
					print "  ".pack("A76",$text);
				}
				print $ESC."1A";
			}
			else {
				$progress_ttext = $text;
			}
		}
	}
	elsif ($num) {
		if (defined($thr) || ($progress_timer == -1)) {
			print "\n";
			my $col = 2+$progress_curr;
			$progress_curr += $num;
			print $ESC.$col."G";
			print "=" while ($num--);
			print $ESC."1A";
		}
	}

	if (defined($thr) || ($progress_timer == -1)) {
		my $elapsed = time - $progress_start;
		my $remain = 0;
		if ($progress_curr < $PROGRESS_MAX) {
			$remain = $progress_curr ? ($elapsed/$progress_curr)*($PROGRESS_MAX - $progress_curr) : 0;
		}
		print $ESC."52G";
		print sprintf("[%6.2f%% ", $curr*100/$progress_max);
		print fmt_elapsed($elapsed)."/".fmt_elapsed($remain+$elapsed)."]";
	}
}


### to close off the progress bar
sub end_progress {
	end_thread();
	set_progress($progress_max, $progress_text);
	print "\n";
	my $i = -2;
	print " " while ($i++ < $PROGRESS_MAX);
	print $ESC."1G";
}


### this is our timer thingy
sub timer_progress {
	while (($progress_timer > 0) && ($progress_timer < 2)) {
		set_progress($progress_last, $progress_ttext, 1);
		sleep(1);
	}
	$progress_timer = 0;
}


### start the progress thread
sub start_thread {
	if ($progress_timer > -1) {
		$progress_timer = 1;
		threads->new(\&timer_progress);
	}
}


### end the progress thread
sub end_thread {
	if ($progress_timer > -1) {
		$progress_timer = 2;
		sleep(2) if ($progress_timer > 0);
	}
}

### parse the command-line options
sub parse_options {
	GetOptions(\%opts,
		'help',
		'verbose+',
		'noclean',
		'workdir=s',
		'debug',
		'root=s',
		'tmp=s',
		'img=s',
		'nofile=s@',
		'nodir=s@',
		'sort=s',
		'kernel=s',
		'lowmem',
		'bootopt=s@',
		'bootmsg=s',
		'bootkey=s%',
		'bootimg=s',
		'timeout=i',
		'noprompt',
		'keyboard=s',
		'resolution=s',
		'splash=s',
		'fstab=s',
		'isoextrafiles=s',
		'application=s',
		'volumeid=s',
		'preparer=s',
		'publisher=s',
		'bootloader=s',
		'mbkopt=s',
		'mbkopt_label=s',
		'bootmenu=s',
		'boottheme=s',
		'bootlang=s',
		'ufs=s',
		'md5sum',
		'lz4',
		'gzip',
		'xz',
		'zstd',
		'usbhome',
		'union',
		'unionfs',
		'uefi'
	);

	# help and stuff
	print_usage if (defined($opts{help}));

	# mandatory stuff
	$o_root =~ s|/$||;
	$o_root .= "/";
	die_("\nFATAL: Root directory (--root) '$o_root' does not exist\n") unless (-d $o_root);
	$o_tmp =~ s|/$||;
	$o_tmp .= "/";
	$o_stage2 = get_exec("find $o_root/lib -name stage2_eltorito");
	die_("\nFATAL: Temporary directory (--tmp) '$o_tmp' does not exist\n") unless (-d $o_tmp);

	# optional stuff
	die_("\nFATAL: Specified sort file (--sort) '".$opts{sort}."' does not exist\n") if (defined($opts{sort}) && !(-f $opts{sort}));
	die_("\nFATAL: Kernel (--kernel) '".$o_kernel."' not installed on the root image. (Directory '".$o_root."/lib/modules/".$o_kernel."' does not exist.)\n") if (!(-d $o_root."/lib/modules/".$o_kernel));
	die_("\nFATAL: Extra ISO directory (--isoextrafiles) '".$opts{isoextrafiles}."' does not exist\n") if (defined($opts{isoextrafiles}) && !(-d $opts{isoextrafiles}));
	die_("\nFATAL: Unknown splash (--splash) option '$o_splash'\n") unless ($o_splash =~ /silent|verbose|no/);
	die_("\nFATAL: Work directory (--workdir) '".$opts{workdir}."' does not exist\n") if (defined($opts{workdir}) && !(-d $opts{workdir}));

	# final iso name
	if (scalar(@ARGV) > 0) {
		die_("\nFATAL: Too many command-line arguments\n") if (scalar(@ARGV) > 1);
		$finaliso = $ARGV[0];
	}
	else {
		#die_("\nFATAL: No final iso name specified\nUse --help for usage\n");
		$finaliso = "livecd.iso";
	}

	# set some options
	my $rhr = "$o_root/etc/redhat-release";
	my $distro  = (-f $rhr) ? get_exec("gawk -F' ' '{ print \$1 \" \" \$2 }' $rhr") : "$PROG_NAME";
	my $version = (-f $rhr) ? get_exec("gawk -F' ' '{ print \$4 \" \" \$5 }' $rhr") : "$PROG_VERSION";
	my $date    = get_exec("date +\%Y\%m\%d\%R");
	$opts{volumeid} = "livecd_$date" unless (defined($opts{volumeid}));
	$opts{application} = "$distro $version LiveCD" unless (defined($opts{application}));
	$opts{preparer} = "$PROG_NAME $PROG_VERSION" unless (defined($opts{preparer}));
	$opts{publisher} = "$URL" unless (defined($opts{publisher}));
	$opts{boottheme} = "PCLinuxOS" unless (defined($opts{boottheme}));
	$opts{bootlang} = "en" unless (defined($opts{bootlang}));

	# create our working dir if none given
	if ($opts{workdir}) {
		$workdir = $opts{workdir};
		$opts{noclean} = 1;
	} else {
		$workdir = $o_tmp."mylivecd.$$";
	}
	mkdir_p($workdir);
	die_("\nFATAL: Unable to create working directory, '$workdir'\n") unless (-e $workdir);
	print STDERR "\nWARNING: The temporary directory '$workdir' will not be removed at exit, please do so manually" if (defined($opts{noclean}));

	# massage where we might have options csv
	@{$opts{nofile}} = split(/,/, join(',', @{$opts{nofile}})) if (defined($opts{nofile}));
	push @{$opts{nofile}}, split(/ /, $nofiles);
	@{$opts{nodir}} = split(/,/, join(',', @{$opts{nodir}})) if (defined($opts{nodir}));
	push @{$opts{nodir}}, split(/ /, $nodirs);

	# setup executables

	$loopcmp = "/usr/bin/mksquashfs";
	$loopmod = "squashfs";

	# do other things before starting
	check_kernel();
	check_dietlibc();
	check_resolution();
	check_root();
	check_apps();
	check_services();
	# pretty up
	print "\n\n";
	}


	### check for the kernel version
	sub check_kernel {
	# this should really be perl regex's

	$kernel26 = 1;
	$modfile = "/etc/modprobe.conf";
	$depmod = "/sbin/depmod";

	# check for identical kernels
	if ($o_kernel eq $o_mbkopt) {
		print "\n";
		print "\nThe LiveCD kernel and multi boot kernel are identical.\n";
		print "Please choose another kernel or use the --kernel option.\n";
		print "\n";
		cleanup ();
			exit (1);
		}
	}


	### checks if this is a MDK dietlibc architecture and adjust lib directory name for 64 bit
	sub check_dietlibc {
	my $arch = get_exec("uname -m");
	$dietarch = 1 if ($arch =~ m/i.86|x86_64/);
	$libdir = "lib64" if ($arch =~ m/x86_64/);
	# always add UEFI boot rec on 64bit
	$opts{uefi} = 1 if ($arch =~ m/x86_64/);
	}


	### checks the resolution given
	sub check_resolution {
	if ($o_resolution =~ m/^normal/) {
		$o_vgamode = "normal";
		$o_splash = "no";
	}
	elsif ($o_resolution =~ m/^640x480/) {
		$o_vgamode = 785;
	}
	elsif ($o_resolution =~ m/^800x600/) {
	$o_vgamode = 788;
	}
	elsif ($o_resolution =~ m/^1024x768/) {
		$o_vgamode = 791;
	}
	elsif ($o_resolution =~ m/^1280x1024/) {
		$o_vgamode = 794;
	}
	elsif ($o_resolution =~ m/^1600x1200/) {
		$o_vgamode = 797;
	}
	else {
	die_("\nFATAL: Invalid resolution '$o_resolution' specified with '--resolution' option
       Valid resolutions are:
            normal
            640x480
            800x600
           1024x768
          1280x1024
          1600x1200\n");
	}
}


### see if we are indeed root
sub check_root {
	die_("\nFATAL: You have to be root to execute this program\n") if ($> > 0);
}


### see if we have everything we need
sub check_apps {
 die_("\nFATAL: The 'genisoimage' program is not available, please install the cdrkit-genisoimage package\n") unless (-f '/usr/bin/genisoimage');
 die_("\nFATAL: The 'md5sum' program is not available, please install the coreutils package\n") unless (-f '/usr/bin/md5sum');
 die_("\nFATAL: The 'mylive-install' program is not available, please install the mylive-install package\n") unless (-f '/usr/lib/live-installer/installer.py');
	if (($o_bootloader =~m/^grub/) && ($o_stage2 eq '')) {
	    die("\nFATAL: The Grub program is not available, please install the correct package\n")
	}
	die_("\nFATAL: The '$loopcmp' program is not available, please install the correct package\n") unless (!defined($loopcmp) || -f $loopcmp);

	if ($libdir eq "lib64") {
		die_("\nFATAL: The grub2-efi package is required for UEFI/grub2 option\n") unless (-d '/usr/lib/grub/x86_64-efi');
	}
}

sub check_services {
    my $eachserv='';
   # disable some services
print STDERR "\nDisabling Services not needed on the LiveCD\n\n";
    foreach $eachserv ('avahi-daemon','atd','cups','cups-browsed','crond','rsyslog','xinetd','vnstat','update-notifier'){
	(push(@services,$eachserv) and  services::do_not_start_service_on_boot($eachserv)) if (services::starts_on_boot($eachserv));
    }
}


### execute a command
sub do_cmd {
	my ($cmd, $prog) = @_;
	set_progress($prog-1, $cmd) if (defined($prog));
	system($cmd) and die_("\nFATAL: Execution of '$cmd' failed\n");
	set_progress($prog, $cmd) if (defined($prog));
}


### copy a file
sub do_copy {
	my ($src, $mode, $dest, $prog) = @_;
	my $cmd = ($mode > 0) ? "install -m $mode $src $dest" : "cp -aL $src $dest";
	set_progress($prog-1, $cmd) if (defined($prog));
	system($cmd);
	set_progress($prog, $cmd) if (defined($prog));
}   	


### create an initrd image
sub create_initrd {
	# I don't know why we have to do this now but it works
	#do_cmd("mount -o bind /dev /dev");
	#sleep 2;
	$modules = $modules_26;
	$modules_opt = $modules_opt_26;
	my @allmods = split(/ /, $modules);
	push @allmods, $loopmod if (defined($loopmod));
	push @allmods, $o_ufs;
	my @allmods_opt = split(/ /, $modules_opt);

	# start progress bar
	my $pos = 0;
	if ($o_mbkopt ne "") {
	    start_progress("Creating $o_kernel initrd", 130+scalar(@allmods));
	  } else {
	    start_progress("Creating initrd", 130+scalar(@allmods));
	}

	# create directories 
	my $dir = $workdir."/initrd.dir";
	mkdir_p("$dir/$_") foreach "lib/modules/$o_kernel/kernel/crypto", "lib/modules/$o_kernel/kernel/drivers", "lib/modules/$o_kernel/kernel/drivers/staging", "lib/modules/$o_kernel/kernel/drivers/media", "lib/modules/$o_kernel/kernel/drivers/char", "lib/modules/$o_kernel/kernel/net/ipv6", "lib/modules/$o_kernel/kernel/drivers/net/ethernet/broadcom", "lib/modules/$o_kernel/kernel/drivers/iommu", "lib/modules/$o_kernel/kernel/drivers/input", "lib/modules/$o_kernel/kernel/drivers/misc", "lib/modules/$o_kernel/kernel/drivers/media/rc", "lib/modules/$o_kernel/kernel/drivers/target", "lib/modules/$o_kernel/kernel/drivers/iio", "lib/modules/$o_kernel/kernel/sound/pci", "lib/modules/$o_kernel/kernel/drivers/leds/trigger", "lib/modules/$o_kernel/kernel/fs", "lib/modules/$o_kernel/kernel/lib", "$libdir", "usr/$libdir", "usr/$libdir/plymouth", "usr/$libdir/plymouth/renderers", qw(lib usr/lib bin sbin usr/bin usr/sbin dev etc/sysconfig etc/rc.d/ etc/profile.d proc sys ramfs usr/share/ldetect-lst lib/module-init-tools cdrom loopfs tmp ramfs usr/share/icons/large usr/share/plymouth/themes usr/share/plymouth/themes/details usr/share/plymouth/themes/text usr/share/plymouth/themes/PCLinuxOS etc/plymouth);
	set_progress(++$pos, "mkdir -p $dir/...");

	# copy files
	do_copy($o_root."usr/bin/busybox",               755, "$dir/bin/busybox",             ++$pos);
	do_copy($o_root."sbin/nash",                     755, "$dir/bin/nash",                ++$pos);
	do_copy($o_root."usr/share/mylivecd/linuxrc",    755, "$dir/linuxrc",                 ++$pos);
	do_copy($o_root."usr/share/mylivecd/rc.sysinit", 755, "$dir/etc/rc.d/rc.sysinit",     ++$pos);
	do_copy($o_root."bin/lsblk",                     755, "$dir/bin/lsblk",               ++$pos);
	do_copy($o_root."bin/sed",                       755, "$dir/bin/sed",                 ++$pos);
	do_copy($o_root."bin/grep",                      755, "$dir/bin/grep",                ++$pos);
	do_copy($o_root."bin/cat",                       755, "$dir/bin/cat",                 ++$pos);

	#unionfs-fuse
	do_copy($o_root."usr/bin/unionfs",               755, "$dir/bin/unionfs",             ++$pos);
	do_copy($o_root."usr/$libdir/libfuse3.so.3",       0, "$dir/$libdir",                 ++$pos);
	do_copy($o_root."usr/$libdir/libfuse3.so.4",       0, "$dir/$libdir",                 ++$pos);

	if ($o_ufs =~ m/^overlayfs/) {
	do_cmd("perl -pi -e 's/#mount -t overlay/mount -t overlay/' $dir/etc/rc.d/rc.sysinit");
	}
	if ($o_ufs =~ m/^unionfs/) {
	do_cmd("perl -pi -e 's/#unionfs -o/unionfs -o/' $dir/etc/rc.d/rc.sysinit");
	}

	# copy core library files
	do_copy($o_root."usr/share/mylivecd/halt.local",   755, "$dir/sbin/halt.local",         ++$pos);
	do_copy($o_root."etc/inittab",                     644, "$dir/etc/inittab",             ++$pos);
	do_copy($o_root."etc/pclinuxos-release",           644, "$dir/etc/pclinuxos-release",   ++$pos);
	do_copy($o_root."sbin/init",                       755, "$dir/sbin/init.dynamic",       ++$pos);
	do_copy($o_root."usr/$libdir/drakx-installer-binaries/probe-modules", 755, "$dir/bin/probe-modules",           ++$pos);

	do_copy($o_root."lib/ld-linux.so.2",                                 0, "$dir/lib",                            ++$pos);

	do_copy($o_root."lib/libpthread.so.0",                               0, "$dir/lib",                            ++$pos);
	do_copy($o_root."lib/libc.so.6",                                     0, "$dir/lib",                            ++$pos);
	do_copy($o_root."usr/$libdir/libz.so.1",                             0, "$dir/$libdir",                        ++$pos);
	do_copy($o_root."$libdir/libc.so.6",                                 0, "$dir/$libdir",                        ++$pos);
	if ($libdir eq "lib64") {
	do_copy($o_root."$libdir/ld-linux-x86-64.so.2",                      0, "$dir/$libdir",                        ++$pos);
	}

	do_copy($o_root."$libdir/libext2fs.so.2",                             644, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libncurses.so.5",                        644, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libncurses.so.6",                        644, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libtinfo.so.5",                          644, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libtinfo.so.6",                          644, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/libblkid.so.1",                              644, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/libuuid.so.1",                               644, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/libmount.so.1",                              644, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libreadline.so.8",                             0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/libdl.so.2",                                   0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/libpthread.so.0",                              0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/librt.so.1",                                   0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/libgcc_s.so.1",                                0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/libm.so.6",                                    0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/libresolv.so.2",                               0, "$dir/$libdir",                     ++$pos);
	if (-e "$o_root/$libdir/libudev.so.1") {
	do_copy($o_root."$libdir/libudev.so.1",                                 0, "$dir/$libdir",                     ++$pos);
	}
	if (-e "$o_root/$libdir/libudev.so.0") {
	do_copy($o_root."$libdir/libudev.so.0",                                 0, "$dir/$libdir",                     ++$pos);
	}
	do_copy($o_root."$libdir/libsmartcols.so.1",                            0, "$dir/$libdir",	               ++$pos);
	do_copy($o_root."$libdir/libfdisk.so.1",                                0, "$dir/$libdir",	               ++$pos);
	do_copy($o_root."usr/$libdir/libbdevid.so.6.0.93",                      0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libnash.so.6.0.93",                        0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libparted.so.2",                           0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libelf.so.1",                              0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libpng16.so.16",                           0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libpng12.so.0",                            0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libdevmapper.so.1.02",                     0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libpopt.so.0",                             0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libldetect.so.0.12",                             0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libkmod.so.2",                             0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libpci.so.3",                             0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libsysfs.so.2",                             0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libzstd.so.1",                             0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libpcre2-8.so.0",                             0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libcrypto.so.1.1",                             0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libcrypto.so.3",                             0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/liblzma.so.5",                                         0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libglib-2.0.so.0",                                         0, "$dir/usr/$libdir",                     ++$pos);

	#Plymouth support
	if ( -e "$o_root/sbin/plymouthd" ) {
	do_copy($o_root."bin/plymouth",                                     755, "$dir/bin/plymouth",                    ++$pos);
	do_copy($o_root."sbin/plymouthd",                                   755, "$dir/bin/plymouthd",                   ++$pos);
	do_copy($o_root."sbin/console_init",                                   755, "$dir/bin/console_init",                   ++$pos);
	do_copy($o_root."usr/share/plymouth/*",                               0, "$dir/usr/share/plymouth",              ++$pos);

	do_copy($o_root."$libdir/libply.so.2",                                0, "$dir/$libdir",                         ++$pos);
	do_copy($o_root."$libdir/libply-splash-core.so.2",                    0, "$dir/$libdir",                         ++$pos);
	do_copy($o_root."usr/$libdir/libply-boot-client.so.2",                0, "$dir/usr/$libdir",                     ++$pos);	
	do_copy($o_root."usr/$libdir/libply-splash-graphics.so.2",            0, "$dir/usr/$libdir",                     ++$pos);	

	do_copy($o_root."usr/$libdir/plymouth/text.so",                       0, "$dir/usr/$libdir/plymouth",            ++$pos);
	do_copy($o_root."usr/$libdir/plymouth/script.so",                     0, "$dir/usr/$libdir/plymouth",            ++$pos);
	do_copy($o_root."usr/$libdir/plymouth/details.so",                    0, "$dir/usr/$libdir/plymouth",            ++$pos);

     do_copy($o_root."usr/$libdir/plymouth/renderers/drm.so",              0, "$dir/usr/$libdir/plymouth/renderers",  ++$pos);
        do_copy($o_root."usr/$libdir/plymouth/renderers/frame-buffer.so",     0, "$dir/usr/$libdir/plymouth/renderers",  ++$pos);
        do_copy($o_root."usr/$libdir/plymouth/renderers/x11.so",              0, "$dir/usr/$libdir/plymouth/renderers",  ++$pos);

	do_copy($o_root."usr/share/icons/large/pclinuxos.png",                0, "$dir/usr/share/icons/large", ++$pos);
       	do_copy($o_root."etc/plymouth/plymouthd.conf",                        0, "$dir/etc/plymouth",          ++$pos);
       	}

	# Kernel stuff
	do_copy($o_root."lib/module-init-tools/ldetect-lst-modules.alias",   0, "$dir/lib/module-init-tools",   ++$pos);
	do_copy($o_root."lib/modules/$o_kernel/modules.description", 0, "$dir/lib/modules/$o_kernel",            ++$pos);
	do_copy($o_root."lib/modules/$o_kernel/modules.builtin", 0, "$dir/lib/modules/$o_kernel",            ++$pos);
	do_copy($o_root."lib/modules/$o_kernel/modules.order", 0, "$dir/lib/modules/$o_kernel",            ++$pos);
	do_copy($o_root."lib/modules/$o_kernel/modules.devname", 0, "$dir/lib/modules/$o_kernel",            ++$pos);
	do_copy($o_root."lib/modules/$o_kernel/modules.builtin.alias.bin", 0, "$dir/lib/modules/$o_kernel",            ++$pos);
	do_copy($o_root."lib/modules/$o_kernel/modules.builtin.modinfo", 0, "$dir/lib/modules/$o_kernel",            ++$pos);

	# Hardware detection stuff
	do_copy($o_root."usr/share/pci.ids",                                 0, "$dir/usr/share",               ++$pos);
	do_copy($o_root."usr/share/usb.ids",                                 0, "$dir/usr/share",               ++$pos);
	do_copy($o_root."usr/share/ldetect-lst/fallback-modules.alias",      0, "$dir/usr/share/ldetect-lst",   ++$pos);
	do_copy($o_root."usr/share/ldetect-lst/pcitable.gz",               644, "$dir/usr/share/ldetect-lst",   ++$pos);
	do_copy($o_root."usr/share/ldetect-lst/usbtable.gz",               644, "$dir/usr/share/ldetect-lst",   ++$pos);
	
	# Copy but hide the udev binaries
	do_cmd("mkdir -p $dir/sbin/tmp",			                         ++$pos);
	do_copy($o_root."/sbin/udev*",	          755, "$dir/sbin/tmp",			 ++$pos);
	do_copy($o_root."/lib/udev/console_init",	         755, "$dir/sbin/tmp",		 	 ++$pos);
	do_copy($o_root."/sbin/start_udev",	  755, "$dir/sbin/tmp",		 	 ++$pos);
	do_cmd("cp -a $o_root/etc/udev $dir/etc",	                                 ++$pos);
	if (-e "$o_root/etc/dev.d") {
	    do_cmd("cp -a $o_root/etc/dev.d $dir/etc",	++$pos);
	}
	do_cmd("cp -a $o_root/etc/hotplug $dir/etc",	++$pos);
	do_cmd("cp -a $o_root/etc/sysconfig $dir/etc",	++$pos);

	do_cmd("mknod $dir/dev/initrd b 1 250", ++$pos);
	do_cmd("mknod $dir/dev/console c 5 1",  ++$pos);
	do_cmd("mknod $dir/dev/fb c 29 0",      ++$pos);
	do_cmd("mknod $dir/dev/null c 1 3",     ++$pos);
	do_cmd("mknod $dir/dev/systty c 4 0",   ++$pos);
	do_cmd("mknod $dir/dev/ram b 1 1",      ++$pos);
	do_cmd("mknod $dir/dev/tty$_ c 4 $_",   ++$pos) foreach((0,1,2,3,4,5,6,7,8,9,10,11,12));
	do_cmd("mknod $dir/dev/ttyS0 c 4 64",   ++$pos);
	do_cmd("mknod $dir/dev/ttyS1 c 4 65",   ++$pos);
	do_cmd("mknod $dir/dev/ttyS2 c 4 66",   ++$pos);
	do_cmd("mknod $dir/dev/ttyS3 c 4 67",   ++$pos);
	do_cmd("mknod $dir/dev/lvm b 109 0",    ++$pos);

	# Copy specific kernel drivers for linuxrc
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/acpi     $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/ata      $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/block    $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/gpu      $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/i2c      $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	if (-e "$o_root/lib/modules/$o_kernel/kernel/drivers/ide") {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/ide      $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/message  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/parport  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	if (-e "$o_root/lib/modules/$o_kernel/kernel/drivers/pcmcia") {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/pcmcia   $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/platform/x86 $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/scsi     $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/usb      $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	if (-e "$o_root/lib/modules/$o_kernel/kernel/drivers/uwb") {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/uwb      $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if (-e "$o_root/lib/modules/$o_kernel/kernel/drivers/hid/usbhid") {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/hid/usbhid      $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if (-e "$o_root/lib/modules/$o_kernel/kernel/drivers/staging/uwb") {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/staging/uwb      $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}	
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/video    $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	if (-e "$o_root/lib/modules/$o_kernel/kernel/drivers/cdrom") {
	 do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/cdrom   $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if (-e "$o_root/lib/modules/$o_kernel/kernel/drivers/ieee1394") {
	 do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/ieee1394 $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if (-e "$o_root/lib/modules/$o_kernel/kernel/fs/ext4") {
	 do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/fs/ext4         $dir/lib/modules/$o_kernel/kernel/fs",      ++$pos);
	}
	if (-e "$o_root/lib/modules/$o_kernel/kernel/fs/f2fs") {
	 do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/fs/f2fs         $dir/lib/modules/$o_kernel/kernel/fs",      ++$pos);
	}
	if (-e "$o_root/lib/modules/$o_kernel/kernel/fs/fuse") {
	 do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/fs/fuse         $dir/lib/modules/$o_kernel/kernel/fs",      ++$pos);
	}
	if (-e "$o_root/lib/modules/$o_kernel/kernel/fs/btrfs") {
	 do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/fs/btrfs         $dir/lib/modules/$o_kernel/kernel/fs",      ++$pos);
	}
	if (-e "$o_root/lib/modules/$o_kernel/kernel/crypto/xor.ko.$mod_ext") {
	 do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/crypto/xor.ko.$mod_ext         $dir/lib/modules/$o_kernel/kernel/crypto",      ++$pos);
	}
	if (-e "$o_root/lib/modules/$o_kernel/kernel/fs/jbd2") {
         do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/fs/jbd2         $dir/lib/modules/$o_kernel/kernel/fs",      ++$pos);
    }
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/fs/fat           $dir/lib/modules/$o_kernel/kernel/fs",	++$pos);
	if (-e "$o_root/lib/modules/$o_kernel/kernel/fs/exfat") {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/fs/exfat           $dir/lib/modules/$o_kernel/kernel/fs",	++$pos);
	}
	if (-e "$o_root/lib/modules/$o_kernel/kernel/drivers/staging/exfat") {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/staging/exfat           $dir/lib/modules/$o_kernel/kernel/drivers/staging",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/fs/ntfs" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/fs/ntfs          $dir/lib/modules/$o_kernel/kernel/fs",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/fs/ntfs3" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/fs/ntfs3          $dir/lib/modules/$o_kernel/kernel/fs",	++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/fs/isofs         $dir/lib/modules/$o_kernel/kernel/fs",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/fs/nls           $dir/lib/modules/$o_kernel/kernel/fs",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/fs/squashfs      $dir/lib/modules/$o_kernel/kernel/fs",	++$pos);
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/fs/unionfs" ) {
	 do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/fs/unionfs      $dir/lib/modules/$o_kernel/kernel/fs",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/fs/overlayfs" ) {
	 do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/fs/overlayfs    $dir/lib/modules/$o_kernel/kernel/fs",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/fs/udf" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/fs/udf           $dir/lib/modules/$o_kernel/kernel/fs",	++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/lib              $dir/lib/modules/$o_kernel/kernel",	++$pos);
	
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/crypto/crct10dif_common.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/crypto/crct10dif_common.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	}
	
	# resolve missing dependencies
	
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/media/cec  $dir/lib/modules/$o_kernel/kernel/drivers/media",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/char/ipmi  $dir/lib/modules/$o_kernel/kernel/drivers/char",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/nvdimm  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/virtio  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/net/ceph  $dir/lib/modules/$o_kernel/kernel/net",	++$pos);
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/arch/x86/crypto/poly1305-x86_64.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/arch/x86/crypto/poly1305-x86_64.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/arch/x86/crypto/chacha-x86_64.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/arch/x86/crypto/chacha-x86_64.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/fs/configfs/configfs.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/fs/configfs $dir/lib/modules/$o_kernel/kernel/fs",	++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/iommu $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/arch/x86/crypto/blake2s-x86_64.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/arch/x86/crypto/blake2s-x86_64.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/arch/x86/crypto/libblake2s-generic.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/arch/x86/crypto/libblake2s-generic.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/net/ethernet/broadcom/cnic.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/net/ethernet/broadcom",	++$pos);
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/net/ipv6/ipv6.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/net/ipv6/ipv6.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/net/ipv6",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/net/ethernet/qlogic/qed/qed.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/net/ethernet/qlogic/qed/qed.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/net/ethernet",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/lib/crc-ccitt.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/lib/crc-ccitt.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/uio $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/target/target_core_mod.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/target/target_core_mod.ko.$mod_ext $dir/lib/modules/$o_kernel/kernel/drivers/target",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/input/sparse-keymap.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/input/sparse-keymap.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/input",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/input/input-polldev.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/input/input-polldev.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/input",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/net/ethernet/chelsio/libcxgb/libcxgb.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/net/ethernet/chelsio/libcxgb  $dir/lib/modules/$o_kernel/kernel/drivers/net/ethernet/chelsio",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/net/ethernet/chelsio/cxgb3  $dir/lib/modules/$o_kernel/kernel/drivers/net/ethernet/chelsio",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/net/ethernet/chelsio/cxgb4  $dir/lib/modules/$o_kernel/kernel/drivers/net/ethernet/chelsio",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/net/mdio.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/net",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/misc/enclosure.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/misc/enclosure.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/misc",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/misc/eeprom/eeprom_93cx6.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/misc/eeprom/eeprom_93cx6.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/misc",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/misc/lis3lv02d/lis3lv02d.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/misc/lis3lv02d  $dir/lib/modules/$o_kernel/kernel/drivers/misc",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/bcma/bcma.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/bcma  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/ssb/ssb.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/ssb  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/net/atm/atm.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/net/atm/atm.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/net/atm/atm.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/net/atm/atm.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/media/rc/rc-core.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/media/rc",	++$pos);
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/iio/industrialio.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/iio/industrialio.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/iio",	++$pos);
	}
	
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/sound/soundcore.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/sound",	++$pos);
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/sound/ac97_bus.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/sound/ac97_bus.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/sound",	++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/sound/core  $dir/lib/modules/$o_kernel/kernel/sound",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/sound/pci/hda  $dir/lib/modules/$o_kernel/kernel/sound/pci",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/sound/hda  $dir/lib/modules/$o_kernel/kernel/sound",	++$pos);
	
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/leds/trigger/ledtrig-audio.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/leds/trigger/ledtrig-audio.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/leds/trigger",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/security/keys/encrypted-keys/encrypted-keys.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/security/keys  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/char/tpm/tpm.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/char",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/nvme/target/nvmet.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/nvme/target/nvmet.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/nvme/target/nvmet-fc.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/nvme/target/nvmet-fc.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/ptp/ptp.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/ptp/ptp.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/pps/pps_core.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/pps/pps_core.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/mfd/kempld-core.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/mfd/kempld-core.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/mfd/retu-mfd.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/mfd/retu-mfd.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/soundwire/soundwire-generic-allocation.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/soundwire/soundwire-generic-allocation.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/soundwire/soundwire-cadence.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/soundwire/soundwire-cadence.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/sound/soc/snd-soc-core.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/sound/soc/snd-soc-core.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/sound",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/soundwire/soundwire-intel.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/soundwire/soundwire-intel.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/char/nvram.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/char/nvram.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/char",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/mfd/dln2.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/mfd/dln2.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/arch/x86/crypto/crc32-pclmul.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/arch/x86/crypto/crc32-pclmul.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	}
	# Still resolve missing deps
	# mknod require the following stuff when do the static nodes
	
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/md/dm-mod.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/md/dm-mod.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/vfio/vfio.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/vfio/vfio.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/vfio/vfio_iommu_type1.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/vfio/vfio_iommu_type1.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/net/tun.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/net/tun.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/net",	++$pos);
	}
	
	# fix missing deps for linux6 - lazy > put all stuff in drivers
	
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/platform/x86/intel/ishtp_eclite.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/platform/x86/intel/ishtp_eclite.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/hid/intel-ish-hid/intel-ishtp.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/hid/intel-ish-hid/intel-ishtp.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/gpu/drm/i915/kvmgt.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/gpu/drm/i915/kvmgt.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/arch/x86/kvm/kvm.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/arch/x86/kvm/kvm.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/virt/lib/irqbypass.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/virt/lib/irqbypass.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/vfio/vfio.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/vfio/vfio.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/vfio/mdev/mdev.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/vfio/mdev/mdev.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/net/tls/tls.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/net/tls/tls.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/firmware/cirrus/cs_dsp.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/firmware/cirrus/cs_dsp.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/sound/soc/codecs/snd-soc-cs35l41-lib.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/sound/soc/codecs/snd-soc-cs35l41-lib.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/drivers/tty/serdev/serdev.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/drivers/tty/serdev/serdev.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	
	# generate modules file
	do_cmd(":>$dir$modfile", ++$pos);
	my $cfg = defined($kernel26) ? "" : "--config $dir$modfile";
	do_cmd("(/sbin/depmod -ae -b $dir -F /boot/System.map-$o_kernel $o_kernel) 2>/dev/null", ++$pos);

	# get sizes$o_kernel
	my $size = get_exec("du -ks $dir | awk '{print \$1}'");
	$size = $size + 250;
	set_progress(++$pos, "du -ks $dir");

	# number of inodes
	my $inodes = 1250;
	my $num = get_exec("find $dir | wc -l");
	$inodes = $inodes + $num;
	$size = int($size + ($inodes / 10)) + 1; # 10 inodes needs 1K
	set_progress(++$pos, "find $dir | wc -l");

	# do magic
	my $initrd = "$workdir/livecd/isolinux/initrd";
	my $mnt = "$workdir/initrd.mnt";
	do_cmd("mkdir -p $workdir/livecd/isolinux",                         ++$pos);
	do_cmd("mkdir -p $workdir/livecd/boot/grub2",                        ++$pos);
	do_cmd("dd if=/dev/zero of=$initrd bs=1k count=$size 2> /dev/null", ++$pos);
	do_cmd("/sbin/mke2fs -q -m 0 -F -N $inodes $initrd",                ++$pos);
	do_cmd("mkdir -p $mnt ; mount -o loop -t ext2 $initrd $mnt",        ++$pos);
	do_cmd("rm -rf $mnt/lost+found",                                    ++$pos);
	do_cmd("(cd $dir ; tar cf - .) | (cd $mnt ; tar xf -)",             ++$pos);
	do_cmd("sleep 2",                                                   ++$pos);
	do_cmd("umount $mnt",                                               ++$pos);
	do_cmd("sleep 2",                                                   ++$pos);
	do_cmd("(cd $workdir/livecd/isolinux ; gzip -9 initrd)",            ++$pos);
	do_cmd("sleep 2",                                                   ++$pos);

	# make splash 
	if (($o_splash !~ m/no/) && ($o_root =~ m/union/)) {
	if (-e "/tmp/bootsplash/scripts/make-boot-splash") {
	    do_cmd("rm -rf /tmp/bootsplash");
        }
	do_cmd("mkdir -p /tmp/bootsplash");
	do_cmd("cp -r /usr/share/bootsplash/scripts /tmp/bootsplash");
	do_cmd("perl -pi -e 's#usr/share/bootsplash#tmp/bootsplash#' /tmp/bootsplash/scripts/make-boot-splash");
	do_cmd("perl -pi -e 's#usr/share/bootsplash#tmp/bootsplash#' /tmp/bootsplash/scripts/make-boot-splash-raw");
	do_cmd("perl -pi -e 's/^warn/#warn/' /tmp/bootsplash/scripts/remove-boot-splash");

	do_cmd("mv -f $initrd.gz /tmp ; \
		/tmp/bootsplash/scripts/make-boot-splash-raw /tmp/initrd.gz $o_theme; \
		mv -f /tmp/initrd.gz $workdir/livecd/isolinux", ++$pos);
	
	}
	
  	# we are done
	end_progress();


}

	
## check for legacy kernel and create initrd2
sub create_initrd2 {
    if  ($o_mbkopt ne "" && -d "/lib/modules/$o_mbkopt") {	
	# get our modules
	$modules = $modules_26;
	$modules_opt = $modules_opt_26;	
	my @allmods = split(/ /, $modules);
	push @allmods, $loopmod if (defined($loopmod));
	push @allmods, $o_ufs;
	my @allmods_opt = split(/ /, $modules_opt);

	# start progress bar
	my $pos = 0;
	start_progress("Creating $o_mbkopt initrd", 130+scalar(@allmods));

	# create directories
	my $dir = $workdir."/initrd2.dir";
	mkdir_p("$dir/$_") foreach "lib/modules/$o_kernel/kernel/crypto", "lib/modules/$o_kernel/kernel/drivers", "lib/modules/$o_kernel/kernel/drivers/staging", "lib/modules/$o_kernel/kernel/drivers/media", "lib/modules/$o_kernel/kernel/drivers/char", "lib/modules/$o_kernel/kernel/net/ipv6", "lib/modules/$o_kernel/kernel/drivers/net/ethernet/broadcom", "lib/modules/$o_kernel/kernel/drivers/iommu", "lib/modules/$o_kernel/kernel/drivers/input", "lib/modules/$o_kernel/kernel/drivers/misc", "lib/modules/$o_kernel/kernel/drivers/media/rc", "lib/modules/$o_kernel/kernel/drivers/target", "lib/modules/$o_kernel/kernel/drivers/iio", "lib/modules/$o_kernel/kernel/sound/pci", "lib/modules/$o_kernel/kernel/drivers/leds/trigger", "lib/modules/$o_kernel/kernel/fs", "lib/modules/$o_kernel/kernel/lib", "$libdir", "usr/$libdir", "usr/$libdir/plymouth", "usr/$libdir/plymouth/renderers", qw(lib usr/lib bin sbin usr/bin usr/sbin dev etc/sysconfig etc/rc.d/ etc/profile.d proc sys ramfs usr/share/ldetect-lst lib/module-init-tools cdrom loopfs tmp ramfs usr/share/icons/large usr/share/plymouth/themes usr/share/plymouth/themes/details usr/share/plymouth/themes/text usr/share/plymouth/themes/PCLinuxOS etc/plymouth);
	set_progress(++$pos, "mkdir -p $dir/...");

	# copy files
	do_copy($o_root."usr/bin/busybox",               755, "$dir/bin/busybox",             ++$pos);
	do_copy($o_root."sbin/nash",                     755, "$dir/bin/nash",                ++$pos);
	do_copy($o_root."usr/share/mylivecd/linuxrc",    755, "$dir/linuxrc",                 ++$pos);
	do_copy($o_root."usr/share/mylivecd/rc.sysinit", 755, "$dir/etc/rc.d/rc.sysinit",     ++$pos);
	# unionfs-fuse
	do_copy($o_root."usr/bin/unionfs",               755, "$dir/bin/unionfs",             ++$pos);
	do_copy($o_root."usr/$libdir/libfuse3.so.3",       0, "$dir/$libdir",                 ++$pos);

	if ($o_ufs =~ m/^overlayfs/) {
	do_cmd("perl -pi -e 's/#mount -t overlay/mount -t overlay/' $dir/etc/rc.d/rc.sysinit");
	}
	if ($o_ufs =~ m/^unionfs/) {
	do_cmd("perl -pi -e 's/#unionfs -o/unionfs -o/' $dir/etc/rc.d/rc.sysinit");
	}
	# copy core library files
	do_copy($o_root."usr/share/mylivecd/halt.local",   755, "$dir/sbin/halt.local",         ++$pos);
	do_copy($o_root."etc/inittab",                     644, "$dir/etc/inittab",             ++$pos);
	do_copy($o_root."etc/pclinuxos-release",           644, "$dir/etc/pclinuxos-release",   ++$pos);
	do_copy($o_root."sbin/init",                       755, "$dir/sbin/init.dynamic",       ++$pos);
	do_copy($o_root."usr/$libdir/drakx-installer-binaries/probe-modules", 755, "$dir/bin/probe-modules",         ++$pos);

	do_copy($o_root."lib/ld-linux.so.2",                                 0, "$dir/lib",                        ++$pos);
	do_copy($o_root."lib/libpthread.so.0",                               0, "$dir/lib",                        ++$pos);
	do_copy($o_root."lib/libc.so.6",                                     0, "$dir/lib",                        ++$pos);
	do_copy($o_root."usr/$libdir/libz.so.1",                             0, "$dir/$libdir",                    ++$pos);
	do_copy($o_root."$libdir/libc.so.6",                                 0, "$dir/$libdir",                    ++$pos);
	if ($libdir eq "lib64") {
	do_copy($o_root."$libdir/ld-linux-x86-64.so.2",                         0, "$dir/$libdir",                     ++$pos);
	}
	do_copy($o_root."$libdir/libext2fs.so.2",                             644, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libncurses.so.5",                            644, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libncurses.so.6",                            644, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libtinfo.so.5",                              644, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libtinfo.so.6",                              644, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/libblkid.so.1",                              644, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/libuuid.so.1",                               644, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/libmount.so.1",                              644, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libreadline.so.8",                             0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/libdl.so.2",                                   0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/libpthread.so.0",                              0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/librt.so.1",                                   0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/libgcc_s.so.1",                                0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/libm.so.6",                                    0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/libresolv.so.2",                               0, "$dir/$libdir",                     ++$pos);
	if (-e "$o_root/$libdir/libudev.so.1") {
	do_copy($o_root."$libdir/libudev.so.1",                                 0, "$dir/$libdir",                     ++$pos);
	}
	if (-e "$o_root/$libdir/libudev.so.0") {
	do_copy($o_root."$libdir/libudev.so.0",                                 0, "$dir/$libdir",                     ++$pos);
	}
	do_copy($o_root."$libdir/libsmartcols.so.1",                            0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."$libdir/libfdisk.so.1",                                0, "$dir/$libdir",                     ++$pos);

	do_copy($o_root."usr/$libdir/libbdevid.so.6.0.93",                      0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libnash.so.6.0.93",                        0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libparted.so.2",                           0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libelf.so.1",                              0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libpng16.so.16",                           0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libpng12.so.0",                            0, "$dir/$libdir",                     ++$pos);
	do_copy($o_root."usr/$libdir/libdevmapper.so.1.02",                     0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libpopt.so.0",                             0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libldetect.so.0.12",                             0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libkmod.so.2",                             0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libpci.so.3",                             0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libsysfs.so.2",                             0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libzstd.so.1",                             0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libpcre2-8.so.0",                             0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libcrypto.so.1.1",                             0, "$dir/$libdir",                     ++$pos);
     do_copy($o_root."usr/$libdir/libcrypto.so.3",                             0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/liblzma.so.5",                                   0, "$dir/$libdir",                     ++$pos);
    do_copy($o_root."usr/$libdir/libglib-2.0.so.0",                                         0, "$dir/usr/$libdir",                     ++$pos);

	#Plymouth support
	if ( -e "$o_root/sbin/plymouthd" ) {
	do_copy($o_root."bin/plymouth",                                     755, "$dir/bin/plymouth",                    ++$pos);
	do_copy($o_root."sbin/plymouthd",                                   755, "$dir/bin/plymouthd",                   ++$pos);
	do_copy($o_root."sbin/console_init",                                   755, "$dir/bin/console_init",                   ++$pos);
	do_copy($o_root."usr/share/plymouth/*",                               0, "$dir/usr/share/plymouth",              ++$pos);
	do_copy($o_root."$libdir/libply.so.2",                                0, "$dir/$libdir",                         ++$pos);
	do_copy($o_root."$libdir/libply-splash-core.so.2",                    0, "$dir/$libdir",                         ++$pos);
	do_copy($o_root."usr/$libdir/libply-boot-client.so.2",                0, "$dir/usr/$libdir",                     ++$pos);	
	do_copy($o_root."usr/$libdir/libply-splash-graphics.so.2",            0, "$dir/usr/$libdir",                     ++$pos);	
	do_copy($o_root."usr/$libdir/plymouth/text.so",                       0, "$dir/usr/$libdir/plymouth",            ++$pos);
	do_copy($o_root."usr/$libdir/plymouth/script.so",                     0, "$dir/usr/$libdir/plymouth",            ++$pos);
	do_copy($o_root."usr/$libdir/plymouth/details.so",                    0, "$dir/usr/$libdir/plymouth",            ++$pos);
	do_copy($o_root."usr/$libdir/plymouth/renderers/drm.so",              0, "$dir/usr/$libdir/plymouth/renderers",  ++$pos);
	do_copy($o_root."usr/$libdir/plymouth/renderers/frame-buffer.so",     0, "$dir/usr/$libdir/plymouth/renderers",  ++$pos);
	do_copy($o_root."usr/$libdir/plymouth/renderers/x11.so",              0, "$dir/usr/$libdir/plymouth/renderers",  ++$pos);
	do_copy($o_root."usr/share/icons/large/pclinuxos.png",                0, "$dir/usr/share/icons/large",           ++$pos);
	do_copy($o_root."etc/plymouth/plymouthd.conf",                        0, "$dir/etc/plymouth",                    ++$pos);
	}

	# Kernel stuff
	do_copy($o_root."lib/module-init-tools/ldetect-lst-modules.alias",   0, "$dir/lib/module-init-tools",   ++$pos);
	do_copy($o_root."lib/modules/$o_kernel/modules.description", 0, "$dir/lib/modules/$o_kernel",            ++$pos);
	do_copy($o_root."lib/modules/$o_kernel/modules.builtin", 0, "$dir/lib/modules/$o_kernel",            ++$pos);
	do_copy($o_root."lib/modules/$o_kernel/modules.order", 0, "$dir/lib/modules/$o_kernel",            ++$pos);
	do_copy($o_root."lib/modules/$o_kernel/modules.devname", 0, "$dir/lib/modules/$o_kernel",            ++$pos);
	do_copy($o_root."lib/modules/$o_kernel/modules.builtin.alias.bin", 0, "$dir/lib/modules/$o_kernel",            ++$pos);
	do_copy($o_root."lib/modules/$o_kernel/modules.builtin.modinfo", 0, "$dir/lib/modules/$o_kernel",            ++$pos);

	# Hardware detection stuff
	do_copy($o_root."usr/share/pci.ids",                                 0, "$dir/usr/share",               ++$pos);
	do_copy($o_root."usr/share/usb.ids",                                 0, "$dir/usr/share",               ++$pos);
	do_copy($o_root."usr/share/ldetect-lst/fallback-modules.alias",      0, "$dir/usr/share/ldetect-lst",   ++$pos);
	do_copy($o_root."usr/share/ldetect-lst/pcitable.gz",               644, "$dir/usr/share/ldetect-lst",   ++$pos);
	do_copy($o_root."usr/share/ldetect-lst/usbtable.gz",               644, "$dir/usr/share/ldetect-lst",   ++$pos);

	# Copy but hide the udev binaries
	do_cmd("mkdir -p $dir/sbin/tmp",			                ++$pos);
	do_copy($o_root."/sbin/udev*",	          755, "$dir/sbin/tmp",		++$pos);
	do_copy($o_root."/lib/udev/console_init",	         755, "$dir/sbin/tmp",		 	 ++$pos);
	do_copy($o_root."/sbin/start_udev",	  755, "$dir/sbin/tmp",		++$pos);
	do_cmd("cp -a $o_root/etc/udev $dir/etc",	                        ++$pos);
	if (-e "$o_root/etc/dev.d") {
	do_cmd("cp -a $o_root/etc/dev.d $dir/etc",	++$pos);
	}
	do_cmd("cp -a $o_root/etc/hotplug $dir/etc",	++$pos);
	do_cmd("cp -a $o_root/etc/sysconfig $dir/etc",	++$pos);
	do_cmd("mknod $dir/dev/initrd b 1 250", ++$pos);
	do_cmd("mknod $dir/dev/console c 5 1",  ++$pos);
	do_cmd("mknod $dir/dev/fb c 29 0",      ++$pos);
	do_cmd("mknod $dir/dev/null c 1 3",     ++$pos);
	do_cmd("mknod $dir/dev/systty c 4 0",   ++$pos);
	do_cmd("mknod $dir/dev/ram b 1 1",      ++$pos);
	do_cmd("mknod $dir/dev/tty$_ c 4 $_",   ++$pos) foreach((0,1,2,3,4,5,6,7,8,9,10,11,12));
	do_cmd("mknod $dir/dev/ttyS0 c 4 64",   ++$pos);
	do_cmd("mknod $dir/dev/ttyS1 c 4 65",   ++$pos);
	do_cmd("mknod $dir/dev/ttyS2 c 4 66",   ++$pos);
	do_cmd("mknod $dir/dev/ttyS3 c 4 67",   ++$pos);
	do_cmd("mknod $dir/dev/lvm b 109 0",    ++$pos);


	# Copy specific kernel drivers for linuxrc
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/ata      $dir/lib/modules/$o_mbkopt/kernel/drivers",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/block    $dir/lib/modules/$o_mbkopt/kernel/drivers",	++$pos);
	if (-e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/ide") {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/ide      $dir/lib/modules/$o_mbkopt/kernel/drivers",	++$pos);
	}	
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/message  $dir/lib/modules/$o_mbkopt/kernel/drivers",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/parport  $dir/lib/modules/$o_mbkopt/kernel/drivers",	++$pos);
	if (-e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/pcmcia") {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/pcmcia   $dir/lib/modules/$o_mbkopt/kernel/drivers",	++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/scsi     $dir/lib/modules/$o_mbkopt/kernel/drivers",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/usb      $dir/lib/modules/$o_mbkopt/kernel/drivers",	++$pos);
	if (-e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/uwb"){
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/uwb      $dir/lib/modules/$o_mbkopt/kernel/drivers",	++$pos);
	}
	if (-e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/hid/usbhid"){
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/hid/usbhid      $dir/lib/modules/$o_mbkopt/kernel/drivers",	++$pos);
	}
	if (-e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/staging/uwb") {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/staging/uwb      $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}		
	if (-e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/cdrom") {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/cdrom   $dir/lib/modules/$o_mbkopt/kernel/drivers",	++$pos);
	}
	if (-e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/ieee1394") {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/ieee1394 $dir/lib/modules/$o_mbkopt/kernel/drivers",	++$pos);
	}
	if (-e "$o_root/lib/modules/$o_mbkopt/kernel/fs/ext4") {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/fs/ext4         $dir/lib/modules/$o_mbkopt/kernel/fs",      ++$pos);
	}
	if (-e "$o_root/lib/modules/$o_mbkopt/kernel/fs/f2fs") {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/fs/f2fs         $dir/lib/modules/$o_mbkopt/kernel/fs",      ++$pos);
	}
	if (-e "$o_root/lib/modules/$o_mbkopt/kernel/fs/fuse") {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/fs/fuse         $dir/lib/modules/$o_mbkopt/kernel/fs",      ++$pos);
	}
	if (-e "$o_root/lib/modules/$o_mbkopt/kernel/fs/btrfs") {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/fs/btrfs         $dir/lib/modules/$o_mbkopt/kernel/fs",      ++$pos);
	}
	if (-e "$o_root/lib/modules/$o_mbkopt/kernel/crypto/xor.ko.$mod_ext") {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/crypto/xor.ko.$mod_ext         $dir/lib/modules/$o_mbkopt/kernel/crypto",      ++$pos);
	}
	if (-e "$o_root/lib/modules/$o_mbkopt/kernel/fs/jbd2") {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/fs/jbd2         $dir/lib/modules/$o_mbkopt/kernel/fs",      ++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/fs/fat           $dir/lib/modules/$o_mbkopt/kernel/fs",	++$pos);
	if (-e "$o_root/lib/modules/$o_mbkopt/kernel/fs/exfat") {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/fs/exfat           $dir/lib/modules/$o_mbkopt/kernel/fs",	++$pos);
	}
	if (-e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/staging/exfat") {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/staging/exfat           $dir/lib/modules/$o_mbkopt/kernel/drivers/staging",	++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/fs/ntfs          $dir/lib/modules/$o_kernel/kernel/fs",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/fs/isofs         $dir/lib/modules/$o_mbkopt/kernel/fs",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/fs/nls           $dir/lib/modules/$o_mbkopt/kernel/fs",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/fs/squashfs      $dir/lib/modules/$o_mbkopt/kernel/fs",	++$pos);
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/fs/unionfs" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/fs/unionfs      $dir/lib/modules/$o_mbkopt/kernel/fs",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/fs/overlayfs" ) {
	 do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/fs/overlayfs    $dir/lib/modules/$o_mbkopt/kernel/fs",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/fs/udf" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/fs/udf         $dir/lib/modules/$o_kernel/kernel/fs",	++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/lib              $dir/lib/modules/$o_mbkopt/kernel",	++$pos);

	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/crypto/crct10dif_common.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/crypto/crct10dif_common.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	}
	
	# resolve missing dependencies
	
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/media/cec  $dir/lib/modules/$o_kernel/kernel/drivers/media",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/char/ipmi  $dir/lib/modules/$o_kernel/kernel/drivers/char",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/nvdimm $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/virtio $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/net/ceph $dir/lib/modules/$o_kernel/kernel/net",	++$pos);
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/arch/x86/crypto/poly1305-x86_64.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/arch/x86/crypto/poly1305-x86_64.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/arch/x86/crypto/chacha-x86_64.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/arch/x86/crypto/chacha-x86_64.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/fs/configfs/configfs.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/fs/configfs $dir/lib/modules/$o_kernel/kernel/fs",	++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/iommu $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/arch/x86/crypto/blake2s-x86_64.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/arch/x86/crypto/blake2s-x86_64.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_kernel/kernel/arch/x86/crypto/libblake2s-generic.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_kernel/kernel/arch/x86/crypto/libblake2s-generic.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/net/ethernet/broadcom/cnic.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/net/ethernet/broadcom",	++$pos);
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/net/ipv6/ipv6.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/net/ipv6/ipv6.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/net/ipv6",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/net/ethernet/qlogic/qed/qed.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/net/ethernet/qlogic/qed/qed.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/net/ethernet",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/lib/crc-ccitt.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/lib/crc-ccitt.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/uio $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/target/target_core_mod.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/target/target_core_mod.ko.$mod_ext $dir/lib/modules/$o_kernel/kernel/drivers/target",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/input/sparse-keymap.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/input/sparse-keymap.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/input",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/input/input-polldev.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/input/input-polldev.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/input",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/net/ethernet/chelsio/libcxgb/libcxgb.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/net/ethernet/chelsio/libcxgb  $dir/lib/modules/$o_kernel/kernel/drivers/net/ethernet/chelsio",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/net/ethernet/chelsio/cxgb3  $dir/lib/modules/$o_kernel/kernel/drivers/net/ethernet/chelsio",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/net/ethernet/chelsio/cxgb4  $dir/lib/modules/$o_kernel/kernel/drivers/net/ethernet/chelsio",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/net/mdio.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/net",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/misc/enclosure.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/misc/enclosure.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/misc",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/misc/lis3lv02d/lis3lv02d.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/misc/lis3lv02d  $dir/lib/modules/$o_kernel/kernel/drivers/misc",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/misc/eeprom/eeprom_93cx6.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/misc/eeprom/eeprom_93cx6.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/misc",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/bcma/bcma.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/bcma  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/ssb/ssb.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/ssb  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/media/rc/rc-core.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/media/rc",	++$pos);
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/iio/industrialio.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/iio/industrialio.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/iio",	++$pos);
	}
	
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/sound/soundcore.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/sound",	++$pos);
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/sound/ac97_bus.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/sound/ac97_bus.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/sound",	++$pos);
	}
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/sound/core  $dir/lib/modules/$o_kernel/kernel/sound",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/sound/hda  $dir/lib/modules/$o_kernel/kernel/sound",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/sound/pci/hda  $dir/lib/modules/$o_kernel/kernel/sound/pci",	++$pos);
	
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/leds/trigger/ledtrig-audio.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/leds/trigger/ledtrig-audio.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/leds/trigger",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/security/keys/encrypted-keys/encrypted-keys.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/security/keys  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/char/tpm/tpm.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/char",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/nvme/target/nvmet.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/nvme/target/nvmet.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/nvme/target/nvmet-fc.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/nvme/target/nvmet-fc.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/ptp/ptp.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/ptp/ptp.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/pps/pps_core.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/pps/pps_core.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/mfd/kempld-core.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/mfd/kempld-core.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/mfd/retu-mfd.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/mfd/retu-mfd.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/soundwire/soundwire-generic-allocation.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/soundwire/soundwire-generic-allocation.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/soundwire/soundwire-cadence.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/soundwire/soundwire-cadence.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/sound/soc/snd-soc-core.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/sound/soc/snd-soc-core.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/sound",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/soundwire/soundwire-intel.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/soundwire/soundwire-intel.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/char/nvram.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/char/nvram.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/char",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/mfd/dln2.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/mfd/dln2.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/arch/x86/crypto/crc32-pclmul.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/arch/x86/crypto/crc32-pclmul.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/lib",	++$pos);
	}
	
	# Still resolve missing deps
	# mknod require the following stuff when do static nodes
	
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/md/dm-mod.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/md/dm-mod.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/vfio/vfio.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/vfio/vfio.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/vfio/vfio_iommu_type1.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/vfio/vfio_iommu_type1.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/net/tun.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/net/tun.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers/net",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/net/tls/tls.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/net/tls/tls.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	
	# fix missing deps for linux6 - lazy > put all stuff in drivers
	
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/platform/x86/intel/ishtp_eclite.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/platform/x86/intel/ishtp_eclite.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/hid/intel-ish-hid/intel-ishtp.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/hid/intel-ish-hid/intel-ishtp.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/gpu/drm/i915/kvmgt.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/gpu/drm/i915/kvmgt.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/arch/x86/kvm/kvm.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/arch/x86/kvm/kvm.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/virt/lib/irqbypass.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/virt/lib/irqbypass.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/vfio/vfio.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/vfio/vfio.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/vfio/mdev/mdev.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/vfio/mdev/mdev.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/firmware/cirrus/cs_dsp.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/firmware/cirrus/cs_dsp.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/sound/soc/codecs/snd-soc-cs35l41-lib.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/sound/soc/codecs/snd-soc-cs35l41-lib.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	if ( -e "$o_root/lib/modules/$o_mbkopt/kernel/drivers/tty/serdev/serdev.ko.$mod_ext" ) {
	do_cmd("cp -r $o_root/lib/modules/$o_mbkopt/kernel/drivers/tty/serdev/serdev.ko.$mod_ext  $dir/lib/modules/$o_kernel/kernel/drivers",	++$pos);
	}
	
	# generate modules file
	do_cmd(":>$dir$modfile", ++$pos);
	my $cfg = defined($kernel26) ? "" : "--config $dir$modfile";
	do_cmd("(/sbin/depmod -ae -b $dir -F /boot/System.map-$o_mbkopt $o_mbkopt) 2>/dev/null", ++$pos);

	# get sizes$o_kernel
	my $size = get_exec("du -ks $dir | awk '{print \$1}'");
	$size = $size + 250;
	set_progress(++$pos, "du -ks $dir");

	# number of inodes
	my $inodes = 1250;
	my $num = get_exec("find $dir | wc -l");
	$inodes = $inodes + $num;
	$size = int($size + ($inodes / 10)) + 1; # 10 inodes needs 1K
	set_progress(++$pos, "find $dir | wc -l");

	# do magic
	my $initrd2 = "$workdir/livecd/isolinux/initrd2";
	my $mntlg = "$workdir/initrd2.mnt";
	do_cmd("mkdir -p $workdir/livecd/isolinux",                         ++$pos);
	do_cmd("mkdir -p $workdir/livecd/boot/grub2",                        ++$pos);
	do_cmd("dd if=/dev/zero of=$initrd2 bs=1k count=$size 2> /dev/null", ++$pos);
	do_cmd("/sbin/mke2fs -q -m 0 -F -N $inodes $initrd2",                ++$pos);
	do_cmd("mkdir -p $mntlg ; mount -o loop -t ext2 $initrd2 $mntlg",    ++$pos);
	do_cmd("rm -rf $mntlg/lost+found",                                    ++$pos);
	do_cmd("(cd $dir ; tar cf - .) | (cd $mntlg ; tar xf -)",             ++$pos);
	do_cmd("umount $mntlg",                                               ++$pos);
	do_cmd("(cd $workdir/livecd/isolinux ; gzip -9 initrd2)",            ++$pos);


	# make splash 
	if (($o_splash !~ m/no/) && ($o_root =~ m/union/)) {
	if (-e "/tmp/bootsplash/scripts/make-boot-splash") {
	do_cmd("rm -rf /tmp/bootsplash");
	}
	do_cmd("mkdir -p /tmp/bootsplash");
	do_cmd("cp -r /usr/share/bootsplash/scripts /tmp/bootsplash");
	do_cmd("perl -pi -e 's#usr/share/bootsplash#tmp/bootsplash#' /tmp/bootsplash/scripts/make-boot-splash");
	do_cmd("perl -pi -e 's#usr/share/bootsplash#tmp/bootsplash#' /tmp/bootsplash/scripts/make-boot-splash-raw");
	do_cmd("perl -pi -e 's/^warn/#warn/' /tmp/bootsplash/scripts/remove-boot-splash");

	do_cmd("mv -f $initrd2.gz /tmp ; \
		/tmp/bootsplash/scripts/make-boot-splash-raw /tmp/initrd2.gz $o_theme; \
		mv -f /tmp/initrd.gz $workdir/livecd/isolinux", ++$pos);
	
	}
       	}
	else {
	    print "\n";
	    print "The option --mbkopt $o_mbkopt was used.\n";
	    print "Is kernel $o_mbkopt installed?\n";
	    print "\n";
	    cleanup ();
	    exit (1);
	} 
  	# we are done
	end_progress();
}


### create the compressed image
sub create_compressed {
	if (defined($opts{img}) && (-f $opts{img})) {
		do_cmd("ln $opts{img} $workdir/livecd/livecd.$o_looptype");
	}
	else {
		my $pos = 0;
		start_progress("Setting filesystem parameters", 5);

		# handle excludes
		do_cmd(":>$workdir/excludes.list", ++$pos);
		if (defined($opts{nodir})) {
			my $ex = join("\n", @{$opts{nodir}});
			do_cmd("(find $o_root -type d 2>/dev/null | sed -e 's,^$o_root,/,g' | grep '$ex' | sed 's,^/,$o_root,' >>$workdir/excludes.list)", ++$pos);
			do_cmd("echo $workdir >>$workdir/excludes.list");

		}
		if (defined($opts{nofile})) {
			my $ex = join("\n", @{$opts{nofile}});
			do_cmd("(find $o_root -type f 2>/dev/null | sed -e 's,^$o_root,/,g' | grep '$ex' | sed 's,^/,$o_root,' >>$workdir/excludes.list)", ++$pos);
			#work around to avoid excluding /etc/X11/xorg.conf.d
		        do_cmd("echo /etc/X11/xorg.conf >>$workdir/excludes.list");
			#work around to avoid excluding loopback iface
		        do_cmd("sed -i -e '/ifcfg-lo/d' $workdir/excludes.list");
			#optional to exclude Synaptic file lists 
		        do_cmd("echo /var/cache/apt/pkgcache.bin >>$workdir/excludes.list");
		        do_cmd("echo /var/cache/apt/srcpkgcache.bin >>$workdir/excludes.list");
		      }

		# handle sort
		do_cmd(":>$workdir/sort.list", ++$pos);
		do_cmd("cat ".$opts{sort}." >>$workdir/sort.list", ++$pos) if (defined($opts{sort}));
		end_progress();	
	
		my $withgzip;
		if (defined($opts{gzip})) {
		  $withgzip = ""
		  }
		elsif (defined($opts{lz4})) {
		  $withgzip = "-comp lz4"
		  }
		elsif (defined($opts{xz})) {
		  $withgzip = "-comp xz -Xbcj x86 -b 1048576"
		  }
		elsif (defined($opts{zstd})) {
		  $withgzip = "-comp zstd"
		  }		  
		else {
		  $withgzip = "-comp zstd"
		  }

		$pos = 0;
		if ($o_looptype =~ m/sqfs/) {
			my @files = qx(find $o_root -type f 2>/dev/null);
			my $total = scalar(@files);
			start_progress("Creating compressed image", $total+2);
			my $iso = "$loopcmp $o_root $workdir/livecd/livecd.$o_looptype $withgzip -info -ef $workdir/excludes.list";
			$iso = "$iso -sort $workdir/sort.list" if (defined($opts{sort}));
			$iso = "$iso 2>&1";
			print "DEBUG: $iso\n" if (defined($opts{debug}));
			open CMP, "$iso |" or die_("\nFATAL: Unable to execute '$iso'\n");
			my $line;
			my $linep = "";
			while ($line = <CMP>) {
				if ($line =~ m/file/) {
					$linep = $line;
					$pos++;
					set_progress($pos, $linep);
				}
				else {
					if (defined($opts{debug})) {
						print "$line\n" if ($line =~ m/Error/);
					}
				}
				set_progress($pos, $linep);
			}
			close CMP;
			do_cmd("chmod 644 $workdir/livecd/livecd.$o_looptype", $total+1); # Failure = out of space
			do_cmd("ln $workdir/livecd/livecd.$o_looptype $opts{img}", $total+2) if (defined($opts{img}));
			end_progress();
		}
		else {
			start_progress("Creating loop image", 10001);
			my $iso = "genisoimage $genisoimage_opts -R -exclude-list $workdir/excludes.list -hide-rr-moved -cache-inodes -no-bak -pad -v -v";
			$iso = "$iso -sort $workdir/sort.list" if (defined($opts{sort}));


			$iso = "$iso -o $workdir/livecd/livecd.$o_looptype $o_root";

			$iso = "($iso) 2>&1";
			print "DEBUG: $iso\n" if (defined($opts{debug}));
			open CMP, "$iso |" or die_("\nFATAL: Unable to execute '$iso'\n");
			my $line;
			while ($line = <CMP>) {
				if ($line =~ m/done, estimate/) {
					$line =~ s/^ //g while ($line =~ m/^ /);
					my ($per, @rest) = split(/ /, $line);
					$per =~ s/%//;
					$pos = int($per*100);
				}
				set_progress($pos, $line);
			}
			close CMP;
			do_cmd("ln $workdir/livecd/livecd.$o_looptype $opts{img}", 10001) if (defined($opts{img}));
			end_progress();
		}
	}
}


### create the isolinux stuff
sub create_isolinux {
	my $pos = 0;
	start_progress("Creating isolinux boot", 9);

	# copy boot images
	my $bin = "/usr/lib/syslinux/isolinux.bin";
	die_("\nFATAL: '$bin' does not exist on your machine. You need to install the syslinux package.\n") unless (-f $bin);
	do_copy($bin, 644, "$workdir/livecd/isolinux/isolinux.bin", ++$pos);
	die_("\nFATAL: The kernel '".$o_root."boot/vmlinuz-$o_kernel' does not exist on your machine.\n") unless (-f $o_root."boot/vmlinuz-$o_kernel");
	do_copy($o_root."boot/vmlinuz-$o_kernel", 644, "$workdir/livecd/isolinux/vmlinuz", ++$pos);
	do_copy($o_root."usr/lib/syslinux/gfxboot.c32",  755, "$workdir/livecd/isolinux/gfxboot.c32", ++$pos);
	do_copy($o_root."usr/lib/syslinux/ldlinux.c32",  755, "$workdir/livecd/isolinux/ldlinux.c32", ++$pos);
	do_copy($o_root."usr/lib/syslinux/libcom32.c32",  755, "$workdir/livecd/isolinux/libcom32.c32", ++$pos);
	if ($o_mbkopt ne "") {
	    do_copy($o_root."boot/vmlinuz-$o_mbkopt", 644, "$workdir/livecd/isolinux/vmlinuz2", ++$pos)
        }
	#do_copy("/usr/bin/mediacheck", 755, "$workdir/livecd/isolinux/mediacheck", ++$pos);
	#do_copy("/usr/bin/checkisomd5", 755, "$workdir/livecd/isolinux/checkisomd5", ++$pos);
	#do_copy($o_root."boot/memtest-4.20", 644, "$workdir/livecd/isolinux/memtest", ++$pos);
        if ($o_bootloader =~ m/^iso/) {
	    do_copy($o_root."usr/share/gfxboot/themes/$opts{boottheme}/install/*", 644, "$workdir/livecd/isolinux", ++$pos);
	    do_copy($o_root."usr/share/gfxboot/themes/$opts{boottheme}/install/bootlogo", 644, "$workdir/livecd/isolinux/bootlogo", ++$pos);
	  } else {
	    do_copy($o_stage2, 644, "$workdir/livecd/boot/grub2/stage2_eltorito", ++$pos);
	    do_copy($o_root."usr/share/gfxboot/themes/$opts{boottheme}/boot/*", 644, "$workdir/livecd/boot/grub2", ++$pos);
        }

	# copy messages
	do_copy($opts{bootmsg}, 644, "$workdir/livecd/isolinux/livecd.msg", ++$pos) if (defined($opts{bootmsg}));
	if (defined($opts{bootimg})) {
		do_cmd("echo -n '' >$workdir/livecd/isolinux/livecd.msg", ++$pos);
		do_cmd("echo -e '\\030livecd.lss' >>$workdir/livecd/isolinux/livecd.msg", ++$pos);
		do_copy($opts{bootimg}, 644, "$workdir/livecd/isolinux/livecd.lss", ++$pos);
	}

	# write config
	my $appopt;
	$appopt = "initrd=initrd.gz vga=$o_vgamode keyb=$o_keyboard quiet";
	#$appopt .= " splash=$o_splash" if ($o_splash !~ m/no/);
	$appopt = "$appopt fastboot=yes automatic=method:cdrom ramdisk_size=131072" if (!defined($kernel26));
	$appopt = "$appopt fstab=".$opts{fstab} if (defined($opts{fstab}));
	$appopt = "$appopt home=usb" if (defined($opts{usbhome}));
	$appopt = "$appopt $_" foreach (@{$opts{bootopt}});

	open LANG, '>', "$workdir/livecd/isolinux/lang";
	print LANG $opts{bootlang}."\n";
	close LANG;
	
	if (defined($opts{bootmenu}) && -f $opts{bootmenu} )
	{
	    do_copy($opts{bootmenu}, 644, "$workdir/livecd/isolinux", ++$pos);
	} else {
	open CFG, '>', "$workdir/livecd/isolinux/isolinux.cfg";
	print CFG "default LiveCD\n";
	print CFG "prompt  ".(defined($opts{noprompt}) ? "0" : "1")."\n";
	print CFG "timeout $o_timeout\n";
	print CFG "display livecd.msg\n" if (-f "$workdir/livecd/isolinux/livecd.msg");
	foreach my $k (keys %{$opts{bootkey}}) {
		do_copy(${$opts{bootkey}}{$k}, 644, "$workdir/livecd/isolinux/livecd_$k.msg");
		print CFG "$k livecd_$k.msg\n";
	}
	print CFG "ui gfxboot.c32 bootlogo\n";
	print CFG "label LiveCD\n";
	print CFG "    kernel vmlinuz\n";
	print CFG "    append livecd=livecd $appopt splash=$o_splash\n";
	print CFG "label LiveCD - No Boot Splash\n";
	print CFG "    kernel vmlinuz\n";
	print CFG "    append livecd=livecd $appopt splash=verbose\n";
	print CFG "label Video safe mode - modesetting\n";
	print CFG "    kernel vmlinuz\n";
	print CFG "    append livecd=livecd $appopt splash=verbose xdriver=modesetting\n";
	print CFG "label Safe boot\n";
	print CFG "    kernel vmlinuz\n";
	print CFG "    append livecd=livecd initrd=initrd.gz acpi=off vga=normal keyb=us noapic nolapic nopinit xdriver=modesetting\n";
	print CFG "label Console\n";
	print CFG "    kernel vmlinuz\n";
	print CFG "    append livecd=livecd 3 $appopt splash=verbose\n";
	print CFG "label Copy to RAM\n";
	print CFG "    kernel vmlinuz\n";
	print CFG "    append livecd=livecd copy2ram $appopt splash=verbose\n";
	close CFG;
	}

    if ($o_bootloader =~ m/^grub/) {
	if (defined($opts{bootmenu}) && -f $opts{bootmenu} )
	{
	    do_copy($opts{bootmenu}, 644, "$workdir/livecd/boot/grub2", ++$pos);
	} else {
	open CFG, '>', "$workdir/livecd/boot/grub2/grub.cfg";
	print CFG "default 0\n";
	print CFG "timeout 10\n";
	print CFG "gfxmenu (cd)/boot/grub2/message\n\n";
	print CFG "title LiveCD\n";
	print CFG "kernel (cd)/isolinux/vmlinuz livecd=livecd $appopt splash=$o_splash\n";
	print CFG "initrd (cd)/isolinux/initrd.gz\n\n";
	print CFG "title LiveCD - No Boot Splash\n";
	print CFG "kernel (cd)/isolinux/vmlinuz livecd=livecd $appopt splash=verbose\n";
	print CFG "initrd (cd)/isolinux/initrd.gz\n\n";
	print CFG "title Video safe mode - modesetting\n";
	print CFG "kernel (cd)/isolinux/vmlinuz livecd=livecd $appopt splash=verbose xdriver=modesetting\n";
	print CFG "initrd (cd)/isolinux/initrd.gz\n\n";
	print CFG "title Safe boot\n";
	print CFG "kernel (cd)/isolinux/vmlinuz livecd=livecd acpi=off vga=normal keyb=us noapic nolapic nopinit xdriver=modesetting\n";
	print CFG "initrd (cd)/isolinux/initrd.gz\n\n";
	print CFG "title Console\n";
	print CFG "kernel (cd)/isolinux/vmlinuz $appopt splash=verbose 3\n";
	print CFG "initrd (cd)/isolinux/initrd.gz\n\n";
	print CFG "title Copy to RAM\n";
	print CFG "kernel (cd)/isolinux/vmlinuz livecd=livecd copy2ram $appopt splash=verbose\n";
	print CFG "initrd (cd)/isolinux/initrd.gz\n\n";
	close CFG;
	}
    }

	set_progress(++$pos, "$workdir/livecd/isolinux/isolinux.cfg");

	if ($o_mbkopt ne "") {
	    if ($o_bootloader =~ m/^iso/) {
	        do_cmd("perl -pi -e 's/initrd2.gz initrd=initrd.gz/initrd2.gz/' $workdir/livecd/isolinux/isolinux.cfg");
	        do_cmd("perl -pi -e 's/#//' $workdir/livecd/isolinux/isolinux.cfg");
#    if ($o_mbkopt !~ m/lgc/) {	
	        do_cmd("perl -pi -e 's/LiveCD/LiveCD-".$o_kernel."/' $workdir/livecd/isolinux/isolinux.cfg");
                if ($o_mbkopt_label ne "") {	
	          do_cmd("perl -pi -e 's/LegacyKernel/".$o_mbkopt_label."/' $workdir/livecd/isolinux/isolinux.cfg");
		} else {
	          do_cmd("perl -pi -e 's/LegacyKernel/Kernel-".$o_mbkopt."/' $workdir/livecd/isolinux/isolinux.cfg");
	        }
#    }
    	    } else {
		do_cmd("perl -pi -e 's/initrd2.gz initrd=initrd.gz/initrd2.gz/' $workdir/livecd/boot/grub2/grub.cfg");
		do_cmd("perl -pi -e 's/#//' $workdir/livecd/boot/grub2/grub.cfg");
#     if ($o_mbkopt !~ m/lgc/) {
		do_cmd("perl -pi -e 's/LiveCD/LiveCD-".$o_kernel."/' $workdir/livecd/boot/grub2/grub.cfg");
                if ($o_mbkopt_label ne "") {	
		    do_cmd("perl -pi -e 's/LegacyKernel/".$o_mbkopt_label."/' $workdir/livecd/boot/grub2/grub.cfg");
		} else {
		    do_cmd("perl -pi -e 's/LegacyKernel/Kernel-".$o_mbkopt."/' $workdir/livecd/boot/grub2/grub.cfg");
	        }
#     }
	    }
        }		
	# create boot catalogue
	do_cmd("dd if=/dev/zero of=$workdir/livecd/isolinux/boot.cat bs=1k count=2 2> /dev/null", ++$pos);

	end_progress();
}

### create UEFI boot image
sub create_efiimage {
	my $pos = 0;
	start_progress("Creating UEFI boot image", 3);

	my $efiimage = "$workdir/livecd/isolinux/efiboot.img";
	my $efi_dir = "$workdir/livecd/EFI";
	my $mnt = "$workdir/efi_mnt";

	# Modules needed in EFI app
	my $core_mods = "configfile normal boot echo linux loadenv ls reboot search search_label part_msdos part_gpt part_apple fat iso9660 udf ext2";
	my $gfx_mods = "gfxmenu gfxterm efi_gop efi_uga video video_colors videoinfo video_fb font png";

	# make GRUB2 EFI bootloader app
	do_cmd("mkdir -p $efi_dir/BOOT");
	do_cmd("grub2-mkimage --prefix='/EFI/BOOT' -O x86_64-efi -o $efi_dir/BOOT/bootx64.efi $core_mods $gfx_mods", ++$pos);

	# add theme if present
	if ( -e "$o_root/boot/grub2/themes/pclinuxos/theme.txt" ) {
		do_cmd("cp -pr $o_root/boot/grub2/fonts $efi_dir/BOOT");
		do_cmd("cp -pr $o_root/boot/grub2/themes $efi_dir/BOOT");
	}

	# build the GRUB2 config for the LiveCD
	open CFG, '>', "$efi_dir/BOOT/grub.cfg";
	print CFG "insmod $_\n" foreach qw(part_gpt part_msdos fat efi_gop efi_uga video_colors videoinfo video_fb font);
	print CFG 'if loadfont "${prefix}/fonts/unicode.pf2" ; then',"\n";
	print CFG '   insmod gfxterm',"\n";
	print CFG '   set gfxmode=auto',"\n";
	print CFG '   set gfxpayload=keep',"\n";
	print CFG '   terminal_input console',"\n";
	print CFG '   terminal_output gfxterm',"\n";
	print CFG 'fi',"\n";
	if ( -e "$efi_dir/BOOT/themes/pclinuxos/theme.txt" ) {
		print CFG 'insmod png',"\n";
		print CFG 'set theme=($root)/EFI/BOOT/themes/pclinuxos/theme.txt',"\n";
		print CFG 'export theme',,"\n";
	}
	print CFG "search --no-floppy --set=root --label $opts{volumeid}\n";
	print CFG 'menuentry "Start PCLinuxOS Live (UEFI mode)" {',"\n";
	print CFG "   linux /isolinux/vmlinuz livecd=livecd root=/dev/rd/3 vga=$o_vgamode keyb=$o_keyboard quiet splash=$o_splash  \n";
	print CFG "   initrd /isolinux/initrd.gz\n";
	print CFG "}\n";
	print CFG 'menuentry "Start PCLinuxOS Live (UEFI mode)(No Boot Splash)" {',"\n";
	print CFG "   linux /isolinux/vmlinuz livecd=livecd root=/dev/rd/3 vga=$o_vgamode keyb=$o_keyboard quiet splash=verbose  \n";
	print CFG "   initrd /isolinux/initrd.gz\n";
	print CFG "}\n";
	print CFG 'menuentry "Start PCLinuxOS Live (UEFI mode)(Video - Modesetting)" {',"\n";
	print CFG "   linux /isolinux/vmlinuz livecd=livecd root=/dev/rd/3 vga=$o_vgamode keyb=$o_keyboard quiet splash=verbose  xdriver=modesetting\n";
	print CFG "   initrd /isolinux/initrd.gz\n";
	print CFG "}\n";	
	print CFG 'menuentry "Start PCLinuxOS Live (UEFI mode)(Safe Mode)" {',"\n";
	print CFG "   linux /isolinux/vmlinuz livecd=livecd root=/dev/rd/3 vga=$o_vgamode keyb=$o_keyboard acpi=off noapic nolapic nopinit xdriver=modesetting \n"; 
	print CFG "   initrd /isolinux/initrd.gz\n";
	print CFG "}\n";
	print CFG 'menuentry "Start PCLinuxOS Live (UEFI mode)(Copy to RAM)" {',"\n";
	print CFG "   linux /isolinux/vmlinuz livecd=livecd root=/dev/rd/3 vga=$o_vgamode keyb=$o_keyboard copy2ram quiet splash=verbose  \n";
	print CFG "   initrd /isolinux/initrd.gz\n";
	print CFG "}\n";	
	close CFG;

	# make the EFI image
	my $efisize = ceil(chomp_(`du -s -k $efi_dir`) / 1024) * 1024;
	do_cmd("dd if=/dev/zero of=$efiimage bs=1k count=$efisize 2> /dev/null",  ++$pos);
	do_cmd("mkdosfs -F 12 $efiimage >/dev/null");
	do_cmd("mkdir -p $mnt ; mount -o loop $efiimage $mnt");
	do_cmd("rm -rf $mnt/lost+found");
	do_cmd("mkdir -p $mnt/EFI/BOOT");
	do_cmd("cp -r $efi_dir/BOOT $mnt/EFI",                                    ++$pos);
	do_cmd("umount $mnt");

	end_progress();
}

### create the final iso
sub create_finaliso {
	# create a sort-file
	my $pos = 0;
	start_progress("Creating final iso", 10001);
	open SORT, '>', "$workdir/sort_iso.list";
	print SORT "$workdir/livecd/isolinux/isolinux.bin 500\n";
	print SORT "$workdir/livecd/isolinux/isolinux.cfg 499\n";
	print SORT "$workdir/livecd/isolinux/vmlinuz 498\n";
	print SORT "$workdir/livecd/isolinux/initrd.gz 497\n";
	print SORT "$workdir/livecd/isolinux/* 450\n";
	print SORT "$workdir/livecd/livecd.$o_looptype 400\n";
	close SORT;
	set_progress(++$pos, "$workdir/sort_iso.list");

	# create actual iso
	$opts{isoextrafiles} = "" unless (defined($opts{isoextrafiles}));
	if ($o_bootloader =~ m/^grub/) {
		$loader = "boot/grub2/stage2_eltorito";
	}
	elsif ($o_bootloader =~ m/^iso/) {
		$loader = "isolinux/isolinux.bin";
	}

	my $eltorito_opts = "-b $loader -c isolinux/boot.cat -hide-rr-moved -no-emul-boot -boot-load-size 4 -boot-info-table ";
	if (defined($opts{uefi})) {
		$eltorito_opts .= " -eltorito-alt-boot -e isolinux/efiboot.img -no-emul-boot";
	}

	# switch to UDF if larger than 4GB
	my $udf_opts = "";
	my $imagesize = -s "$workdir/livecd/livecd.$o_looptype";
	print "\nDEBUG: Loop image size is $imagesize\n" if (defined($opts{debug}));
	$udf_opts .= "" if $imagesize > ((2**32) - 25000000);

	my $cmd="xorriso -as mkisofs -d -l -r -no-emul-boot -iso-level 3 \\\
                  -V '".$opts{volumeid}."' \\\
                  -A '".$opts{application}."' \\\
                  -p '".$opts{preparer}."' \\\
                  -P '".$opts{publisher}."' \\\
                  $eltorito_opts -sort $workdir/sort_iso.list -o $finaliso $workdir/livecd/ ".$opts{isoextrafiles}." 2>&1";
	  print "DEBUG: $cmd\n" if (defined($opts{debug}));
          open ISO, "$cmd |" or die_("\nFATAL: Unable to execute '$cmd'\n");
          my $line;
          while ($line = <ISO>) {
		if ($line =~ m/done, estimate/) {
			$line =~ s/^ //g while ($line =~ m/^ /);
			my ($per, @rest) = split(/ /, $line);
			$per =~ s/%//;
			$pos = int($per*100)+1;
		}
		else {
			if (defined($opts{debug})) {
				print "$line\n" if ($line !~ m/^\s+[0-9]/);
			}
		}
		set_progress($pos, $line);
	}
	close ISO;
	if (defined($opts{uefi})) {
		do_cmd("isohybrid -u $finaliso");
	}
	else {
		do_cmd("isohybrid -o 1 $finaliso");
	}
	end_progress();
}


### create the embedded md5sum
sub create_md5 {
	my $isosize = get_exec("ls -al --block-size=1M $finaliso | awk '{print \$5 }'");
	start_progress("Embedding MD5 checksum", $isosize);
	open MD5, "implantisomd5 $finaliso |" or die_("\nFATAL: Unable to execute 'implantisomd5'\n");
	my $line;
	my $pos = 0;
	while ($line = <MD5>) {
		chomp($line);
		if ($line =~ /^Read/) {
			$pos = $line;
			$pos =~ s/Read//;
			$pos =~ s/MB//;
			$pos =~ s/\s// while ($pos =~ /\s/);
		}
		set_progress($pos, $line);
	}
	close MD5;
	end_progress();
}


### clean everything
sub cleanup {
	if (defined($workdir)) {
		system("umount $workdir/initrd.mnt 2>/dev/null");
		system("rm -rf $workdir") unless (defined($opts{noclean}));
		#unmount the (mount -o bind /dev /dev) command now
		#do_cmd("umount /dev");
	}
	if (-e "/tmp/bootsplash/scripts/make-boot-splash") {
		do_cmd("rm -rf /tmp/bootsplash");
	}

	# enable back some disabled services
	print STDERR "\nRestoring Services on the installed system\n\n";
	services::start_service_on_boot($_) foreach @services;
}



### signals
sub die_ {
	die('DIE', join(' ', @_));
}
sub do_signal {
	my ($signal, $text) = @_;
	end_thread();
	my $to = $text ? $text : "\nFATAL: Interrupted.\n";
	chomp($to);
	print pack("A80", $to)."\n";
	cleanup();
	exit(1);
}


### main program entry point
MAIN: {
	$SIG{INT} = \&do_signal;
	$SIG{KILL} = \&do_signal;
	$SIG{PIPE} = \&do_signal;

	print_banner();
	parse_options();

	create_initrd();
	create_initrd2() if ($o_mbkopt ne "");;
	create_compressed();
	create_isolinux();
	create_efiimage() if (defined($opts{uefi}));
	create_finaliso();
	create_md5() if (defined($opts{md5sum}));;
	cleanup();

	my $finalsize = get_exec("ls -al $finaliso | awk '{print \$5 }'");
	print "\nCreated '$finaliso' (".fmt_number($finalsize)." bytes) in ".fmt_elapsed(time-$starttime)."\n\n";
}
