#!/usr/bin/perl use lib qw(/usr/lib/libDrakX); use strict; use diagnostics; use standalone; #- warning, standalone must be loaded very first, for 'explanations' use c; use common; use interactive; use detect_devices; use harddrake::data; use harddrake::sound; use modules; use Storable qw(store retrieve); my $invert_do_it = $ARGV[0] eq 'X11' ? 1 : 0; my ($hw_sysconfdir, $timeout) = ("/etc/sysconfig/harddrake2", $invert_do_it ? 600 : 25); my $last_boot_config = $hw_sysconfdir."/previous_hw"; $last_boot_config .= '_X11' if $invert_do_it; modules::mergein_conf('/etc/modules.conf'); # autoreconfigure the mouse on major kernel change: my $prev_kernel = { getVarsFromSh("$hw_sysconfdir/kernel") }->{KERNEL}; my $curr_kernel = c::kernel_version(); $curr_kernel =~ s/(^\d+\.\d+).*/\1/; setVarsInSh("$hw_sysconfdir/kernel", KERNEL => $curr_kernel); if ($curr_kernel ne $prev_kernel) { require class_discard; require mouse; mouse::write_conf(class_discard->new, mouse::detect(), 1); } if (find { $_->{driver} =~ /Card:NVIDIA/ } detect_devices::probeall()) { if (find { -e join('', "/lib/modules/", c::kernel_version(), "/kernel/drivers/$_") } map { ("video/$_", "char/$_") } qw(NVdriver nvidia.o nvidia.o.gz nvidia.ko nvidia.ko.gz)) { #log::explanations("switch XFree86 driver from nv to nvidia"); #substInFile { s!Driver "nv.*"!Driver "nvidia"!g; s!#*( Load.*glx)!\1!g } $_ foreach "/etc/X11/XF86Config-4", "/etc/X11/XF86Config"; } else { log::explanations("switch XFree86 driver from nvidia to nv"); substInFile { s!Driver "nv.*"!Driver "nv"!g; s!([^#]Load.*glx)!#\1!g } $_ foreach "/etc/X11/XF86Config-4", "/etc/X11/XF86Config"; } } my $is_globetrotter = -f '/usr/sbin/mdkmove'; # first run ? if not read old hw config my $previous_config = -f $last_boot_config && -s $last_boot_config ? Storable::retrieve($last_boot_config) : {}; $previous_config = $$previous_config if ref($previous_config) !~ /HASH/; my (%config, $wait); my $in; my $splash = -f '/proc/splash'; # For each hw, class, detect device, compare and offer to reconfigure if needed foreach my $hw_class (@harddrake::data::tree) { my ($Ident, $item, $configurator, $detector, $do_it) = @$hw_class{qw(class string configurator_auto detector checked_on_boot)}; $configurator ||= $hw_class->{configurator}; next unless $do_it ^ $invert_do_it; # No detector ? (should never happen but who know ?) ref($detector) eq 'CODE' or next; my %ID = map { my $i = $_; my $id = defined $i->{device} ? $i->{device} : join(':', map { $i->{$_} } qw(vendor id subvendor subid)); $id => $i; } eval { &$detector }; $config{$Ident} = \%ID; next if !$is_globetrotter && is_empty_hash_ref $previous_config; # don't fsck on first run my $oldconfig = $previous_config->{$Ident}; my $msg; my @was_removed = difference2([ keys %$oldconfig ], [ keys %ID ]); if (@was_removed) { $msg .= N("Some devices in the \"%s\" hardware class were removed:\n", $item) . join('', map { N("- %s was removed\n", harddrake::data::custom_id($oldconfig->{$_}, $item)) } @was_removed) . "\n"; } my @added = difference2([ keys %ID ], [ keys %$oldconfig ]); $msg .= N("Some devices were added: %s\n", $item) if @added; $msg .= N("- %s was added\n", harddrake::data::custom_id($ID{$_}, $item)) foreach @added; log::explanations("removed $Ident: " . harddrake::data::custom_id($oldconfig->{$_}, $item)) foreach @was_removed; log::explanations("added $Ident: " . harddrake::data::custom_id($oldconfig->{$_}, $item)) foreach @added; modules::load('ohci1394') if $Ident eq 'FIREWIRE_CONTROLLER' && any { $_->{driver} eq 'ohci1394' } @added; @added || @was_removed or next; my @configurator_pool; if (harddrake::data::is_removable($Ident)) { foreach my $device (@ID{@added}) { push @configurator_pool, harddrake::data::set_removable_configurator($Ident, $device); }; foreach my $device (@$oldconfig{@was_removed}) { push @configurator_pool, harddrake::data::set_removable_remover($Ident, $device); } } else { @configurator_pool = $configurator; } if ($Ident eq "AUDIO") { # automatic sound slots configuration rm_rf("/etc/asound.state"); harddrake::sound::configure_sound_slots(); next; } elsif ($Ident eq "ETHERNET") { modules::remove_alias_regexp('^(wlan|eth)[0-9]*$'); modules::load_category('network/main|gigabit|usb|wireless'); require network::ethernet; network::ethernet::configure_eth_aliases(); modules::write_conf(); } elsif ($Ident eq "AGP") { # add agpgart modules to modprobe.preload if needed: modules::write_conf(); } elsif ($Ident eq "VIDEO") { require harddrake::autoconf; harddrake::autoconf::xconf(); undef @configurator_pool; } next if $is_globetrotter && !$hw_class->{automatic}; next unless $configurator_pool[0]; if (!-x first(split /\s+/, $configurator_pool[0])) { log::explanations(qw(skip $Ident configuration sincecannot "$configurator" isn't executable)); next; } my ($pid, $no, $res); if (!$hw_class->{automatic}) { $SIG{ALRM} = sub { $no = 1; kill 15, $pid }; unless ($pid = fork()) { $splash and eval { output('/proc/splash', 'verbose') } and $splash = 0; exec("/usr/share/harddrake/confirm", $Ident, $timeout, $msg); } alarm($timeout); wait(); $res = $?; alarm(0); } else { $res = 1; } if (!$no && $res) { foreach my $configurator (@configurator_pool) { if (fork()) { wait(); } else { exec("$configurator 2>/dev/null") or do { log::explanations(qw(cannot run "$configurator")); require POSIX; POSIX::_exit(); }; } } } if (!$hw_class->{automatic}) { require interactive; undef $wait; $in ||= interactive->vnew; $wait = $in->wait_message(N("Please wait"), N("Hardware probing in progress")); } } # output new hw config log::explanations("created file $last_boot_config"); Storable::store(\%config, $last_boot_config); $in->exit(0) if $in;