#!/usr/bin/perl

use lib qw(../../perl-install /usr/lib/libDrakX);
use common;
use interactive;

sub busy_pids_and_files() {
    my @pids = grep { $_ ne $$ && /^(\d+)$/ } all('/proc');

    map {

	my @l1 = grep {
	    $_ && !m!^(/proc/|/dev/|pipe:|socket:)!;
	} map { readlink($_) } "/proc/$_/exe", glob_("/proc/$_/fd/*");

	my @l2 = grep { $_ } map { (split)[5] } cat_("/proc/$_/maps");

	if (my @l = grep { m!^/(image(_boot)?|cdrom/live_tree)/! } @l1, @l2) {
	    my $cmdline = join(' ', split('\0', cat_("/proc/$_/cmdline")));
	    my $exe = readlink("/proc/$_/exe");
	    { pid => $_, cmdline => $cmdline, exe => $exe, files => [ sort(uniq(@l)) ] };
	} else {
	    ();
	}
    } @pids;
}

my @to_restart_progs = qw(kded kdesktop kicker);
my $restart_progs = join(";", @to_restart_progs);
my @simple_daemons = qw(kdesud kio_uiserver klaptopdaemon artsd portmap);
sub simple_daemon {
    my ($e) = @_;
    my $re = join('|', @to_restart_progs, @simple_daemons);
    $e->{cmdline} =~ m!\b($re)\b!
}

my $in = interactive->vnew;

my @busy = busy_pids_and_files();

my $needed_processes = join('|', map { quotemeta }
			'init',
			'xfs',
			'kdeinit: Running...', 
			'/etc/X11/X',
			'/sbin/devfsd',
			);

if (!$ENV{DEBUG} && find { $_->{cmdline} =~ /^($needed_processes)/ } @busy) {
    exec 'totem' if $in->ask_okcancel('', N("You can only run with no CDROM support"));
    $in->exit(1);
}

my ($simple_daemons, $bad_busy) = partition { simple_daemon($_) } @busy;
if (@$bad_busy) {
    warn '*' x 80, "\n";
    warn join("\n", "$_->{exe} ($_->{cmdline}) =>", map { "  $_" } @{$_->{files}}) . "\n" foreach @$bad_busy;
    warn '*' x 80, "\n";

    my @progs = map { 
	my $s = $_->{cmdline};
	$s =~ s!^/usr/bin/perl\s+([^-]\S*).*!$1!;
	$s =~ s!/.*/!!;
	$s =~ s!^kdeinit:\s+(\S+).*!$1!;
	$s =~ s!\s.*!!;
	$s;
    } @$bad_busy;

    my $choice = 'quit';
    my @l = my %l = (
		     kill => N("Kill those programs"), 
		     keep => N("No CDROM support"), 
		    );

    $in->ask_from_({ 
		     title => N("Read carefully!"),
		     messages => N("You can not use another CDROM when the following programs are running: 
%s", join(", ", uniq(sort @progs))) }, 
		  [ { type => 'list', val => \$choice, list => first(list2kv(@l)), format => sub { $l{$_[0]} } } ]) or $in->exit;

    if ($choice eq 'keep') {
	exec 'totem' or $in->exit;
    } else {
	system('sudo', 'kill', map { $_->{pid} } @$bad_busy);
	sleep 2;
	system('sudo', 'kill', '-9', map { $_->{pid} } @$bad_busy);
    }
}

kill 15, map { $_->{pid} } @$simple_daemons;
sleep 1;

@busy = busy_pids_and_files(); #- update list
if (@busy) {
    system($restart_progs);
    exec 'totem' if $in->ask_okcancel('', N("You can only run with no CDROM support"));
    $in->exit(1);
}

my %file2loop = do {
    my $_w = $in->wait_message('', N("Copying to memory to allow removing the CDROM"));
    `GIVE_LOOP=1 mdk_move_loop to_memory always always_i18n totem nvidia` =~ /(.*?)=(.*)/g;
};

ugtk2::gtkset_mousecursor_normal(); #- for restoring a normal in any case
ugtk2::flush();

my ($lang) = map { if_(/live_tree_i18n_(.*)\.clp/, $1) } keys %file2loop;
my $totem_pid = $$;

if (my $pid = fork()) {
    $ENV{MDKMOVE} = $pid;
    $ENV{G_BROKEN_FILENAMES} = 1;
    exec 'totem';
} else {
    exec 'sudo', 'mdk_behind_totem',
        '--lang', $lang,
	'--i18n-loop', $file2loop{"live_tree_i18n_$lang.clp"},
	'--boot-loop', $file2loop{'live_tree_boot.clp'},
	'--boot-loop', $file2loop{'live_tree_boot.clp'},
	'--main-loop', $file2loop{'live_tree.clp'},
	'--totem-pid', $totem_pid,
	'--user', $ENV{USER},
	'--restore-cmd', $restart_progs;
}