summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Blin <oblin@mandriva.org>2005-05-27 11:36:31 +0000
committerOlivier Blin <oblin@mandriva.org>2005-05-27 11:36:31 +0000
commitf928e6d72824dc8ac2a794e4a0f44135c1f166a2 (patch)
treed8d262ea95a68e7867c7faca90285ef34984cce3
parentf1cb50794db65d31c56306effbcbe058c404b39b (diff)
downloaddrakx-f928e6d72824dc8ac2a794e4a0f44135c1f166a2.tar
drakx-f928e6d72824dc8ac2a794e4a0f44135c1f166a2.tar.gz
drakx-f928e6d72824dc8ac2a794e4a0f44135c1f166a2.tar.bz2
drakx-f928e6d72824dc8ac2a794e4a0f44135c1f166a2.tar.xz
drakx-f928e6d72824dc8ac2a794e4a0f44135c1f166a2.zip
initial import of network::thirdparty (this module factorizes the thirdparty software/drivers/firmwares detection and installation code, it points the user to the relevant packages/documentation/url if needed, and don't allow to configure a device if its requirements aren't satisfied)
-rw-r--r--perl-install/network/netconnect.pm79
-rw-r--r--perl-install/network/thirdparty.pm443
-rw-r--r--perl-install/network/tools.pm32
3 files changed, 449 insertions, 105 deletions
diff --git a/perl-install/network/netconnect.pm b/perl-install/network/netconnect.pm
index d50b51453..4b5554cd5 100644
--- a/perl-install/network/netconnect.pm
+++ b/perl-install/network/netconnect.pm
@@ -12,6 +12,7 @@ use fs;
use mouse;
use network::network;
use network::tools;
+use network::thirdparty;
use MDK::Common::Globals "network", qw($in);
sub detect {
@@ -85,7 +86,7 @@ sub real_main {
my (%connections, @connection_list);
my ($modem, $modem_name, $modem_conf_read, $modem_dyn_dns, $modem_dyn_ip);
my $cable_no_auth;
- my ($adsl_type, @adsl_devices, $adsl_failed, $adsl_answer, %adsl_cards, %adsl_data, $adsl_data, $adsl_provider, $adsl_old_provider, $adsl_vpi, $adsl_vci);
+ my ($adsl_type, @adsl_devices, %adsl_cards, %adsl_data, $adsl_data, $adsl_provider, $adsl_old_provider, $adsl_vpi, $adsl_vci);
my ($ntf_name, $gateway_ex, $up, $need_restart_network);
my ($isdn, $isdn_name, $isdn_type, %isdn_cards, @isdn_dial_methods);
my $my_isdn = join('', N("Manual choice"), " (", N("Internal ISDN card"), ")");
@@ -775,28 +776,14 @@ Take a look at http://www.linmodems.org"),
name => N("ADSL configuration") . "\n\n" . N("Select the network interface to configure:"),
data => [ { label => N("Net Device"), type => "list", val => \$ntf_name, allow_empty_list => 1,
list => \@adsl_devices, format => sub { $eth_intf{$_[0]} || $_[0] } } ],
+ complete => sub {
+ exists $adsl_cards{$ntf_name} && !network::thirdparty::setup_device($in, 'dsl', $adsl_cards{$ntf_name}[0]);
+ },
post => sub {
- my %packages = (
- 'eci' => [ 'eciadsl', 'missing' ],
- 'sagem' => [ 'eagle-usb', "/sbin/eaglectrl" ],
- 'speedtouch' => [ 'speedtouch', "/usr/sbin/modem_run" ],
- );
- return 'adsl_unsupported_eci' if $ntf_name eq 'eci';
if (exists $adsl_cards{$ntf_name}) {
my $modem;
($ntf_name, $modem) = @{$adsl_cards{$ntf_name}};
- # FIXME: check that the package installation succeeds, else retry or abort
- $in->do_pkgs->ensure_is_installed(@{$packages{$ntf_name}}) if $packages{$ntf_name};
- if ($ntf_name eq 'speedtouch') {
- $in->do_pkgs->ensure_is_installed_if_available('speedtouch_mgmt', "/usr/share/speedtouch/mgmt.o");
- return 'adsl_speedtouch_firmware' if ! -e "$::prefix/usr/share/speedtouch/mgmt.o";
- }
$netcnx->{bus} = $modem->{bus} if $ntf_name eq 'bewan';
- if ($ntf_name eq 'bewan' && !$::testing) {
- if (my $unicorn_packages = $in->do_pkgs->check_kernel_module_packages('unicorn-kernel', 'unicorn')) {
- $in->do_pkgs->install(@$unicorn_packages);
- }
- }
}
if (exists($isdn_cards{$ntf_name})) {
require network::isdn;
@@ -835,61 +822,6 @@ Take a look at http://www.linmodems.org"),
},
- adsl_speedtouch_firmware =>
- {
- name => N("You need the Alcatel microcode.
-You can provide it now via a floppy or your windows partition,
-or skip and do it later."),
- data => [ { label => "", val => \$adsl_answer, type => "list",
- list => [ N("Use a floppy"), N("Use my Windows partition"), N("Do it later") ], }
- ],
- post => sub {
- my $destination = "$::prefix/usr/share/speedtouch/";
- my ($file, $source, $mounted);
- if ($adsl_answer eq N("Use a floppy")) {
- $mounted = 1;
- $file = 'mgmt.o';
- ($source, $adsl_failed) = network::tools::use_floppy($in, $file);
- } elsif ($adsl_answer eq N("Use my Windows partition")) {
- ($source, $adsl_failed) = network::tools::use_windows($file = 'alcaudsl.sys');
- }
- return "adsl_no_firmawre" if $adsl_answer eq N("Do it later");
-
- my $_b = $mounted && before_leaving { fs::umount('/mnt') };
- if (!$adsl_failed) {
- if (-e "$source/$file") {
- cp_af("$source/$file", $destination) if !$::testing;
- } else {
- $adsl_failed = N("Firmware copy failed, file %s not found", $file);
- }
- }
- log::explanations($adsl_failed || "Firmware copy $file in $destination succeeded");
- -e "$destination/alcaudsl.sys" and rename "$destination/alcaudsl.sys", "$destination/mgmt.o";
-
- # kept translations b/c we may want to reuse it later:
- my $_msg = N("Firmware copy succeeded");
- return $adsl_failed ? 'adsl_copy_firmware_failled' : 'adsl_provider';
- },
- },
-
-
- adsl_copy_firmware_failled =>
- {
- name => sub { $adsl_failed },
- next => 'adsl_provider',
- },
-
-
- "adsl_no_firmawre" =>
- {
- name => N("You need the Alcatel microcode.
-Download it at:
-%s
-and copy the mgmt.o in /usr/share/speedtouch", 'http://www.speedtouch.com/supuser.htm'),
- next => "adsl_provider",
- },
-
-
adsl_protocol =>
{
pre => sub {
@@ -1276,6 +1208,7 @@ See iwpriv(8) man page for further information."),
$in->ask_warn(N("Error"), N("Could not install the %s package!", 'wpa_supplicant'));
return 1;
}
+ !network::thirdparty::setup_device($in, 'wireless', $module);
},
post => sub {
delete $ethntf->{WIRELESS_ENC_KEY};
diff --git a/perl-install/network/thirdparty.pm b/perl-install/network/thirdparty.pm
new file mode 100644
index 000000000..23471aab2
--- /dev/null
+++ b/perl-install/network/thirdparty.pm
@@ -0,0 +1,443 @@
+package network::thirdparty;
+
+use strict;
+use common;
+use detect_devices;
+use run_program;
+use services;
+use log;
+
+#- network_settings is an hash of categories (rtc, dsl, wireless, ...)
+#- each category is an hash of device settings
+
+#- a device settings element must have the following fields:
+#- o matching:
+#- specify if this settings element matches a driver
+#- can be a regexp, array ref or Perl code (parameters: driver)
+#- o description:
+#- full name of the device
+#- o name: name used by the packages
+
+#- the following fields are optional:
+#- o url:
+#- url where the user can find tools/drivers/firmwares for this device
+#- o device:
+#- device in /dev to be configured
+#- o post:
+#- command to be run after all packages are installed
+#- can be a shell command or Perl code
+#- o restart_service:
+#- if exists but not 1, name of the service to be restarted
+#- if 1, specify that the service named by the name field should be restarted
+#- o tools:
+#- if exists but not 1, hash of the tools settings
+#- if 1, tools are needed and package name is the name field
+#- o kernel_module:
+#- if exists but not 1, hash of the module settings
+#- if 1, kernel modules are needed and use the name field
+#- (name-kernel or dkms-name)
+#- o firmware:
+#- if exists but not 1, hash of the firmware settings
+#- if 1, firmware are needed and use the name field
+#- (name-firmware)
+
+#- hash of package settings structure (all fields are optional):
+#- o package:
+#- name of the package to be installed for these device
+#- o test_file:
+#- file used to test if the package is installed
+#- o prefix:
+#- path of the files that are tested
+#- o links:
+#- useful links for this device
+#- can be a single link or array ref
+#- o user_install:
+#- function to call if the package installation fails
+#- o explanations:
+#- additionnal text to display if the installation fails
+
+my $hotplug_firmware_prefix = "$::prefix/lib/hotplug/firmware";
+
+my %network_settings = (
+ rtc =>
+ [
+ {
+ matching => qr/^Hcf:/,
+ description => 'HCF 56k Modem',
+ url => 'http://www.linuxant.com/drivers/hcf/',
+ name => 'hcfpcimodem',
+ kernel_module => 1,
+ tools =>
+ {
+ test_file => '/usr/sbin/hcfpciconfig',
+ },
+ device => '/dev/ttySHSF0',
+ post => '/usr/sbin/hcfpciconfig --auto',
+ },
+
+ {
+ matching => qr/^Hsf:/,
+ description => 'HSF 56k Modem',
+ url => 'http://www.linuxant.com/drivers/hsf/',
+ name => 'hsflinmodem',
+ kernel_module => 1,
+ tools =>
+ {
+ test_file => '/usr/sbin/hsfconfig',
+ },
+ device => '/dev/ttySHSF0',
+ post => '/usr/sbin/hsfconfig --auto',
+ },
+
+ {
+ matching => qr/^LT:/,
+ description => 'LT WinModem',
+ url => 'http://www.heby.de/ltmodem/',
+ name => 'ltmodem',
+ kernel_module => 1,
+ tools =>
+ {
+ test_file => '/etc/devfs/conf.d/ltmodem.conf',
+ },
+ device => '/dev/ttyS14',
+ links =>
+ [
+ 'http://linmodems.technion.ac.il/Ltmodem.html',
+ 'http://linmodems.technion.ac.il/packages/ltmodem/',
+ ],
+ },
+
+ {
+ matching => [ list_modules::category2modules('network/slmodem') ],
+ description => 'Smartlink WinModem',
+ url => 'http://www.smlink.com/content.aspx?id=135/',
+ name => 'slmodem',
+ kernel_module => 1,
+ tools =>
+ {
+ test_file => '/usr/sbin/slmodemd',
+ },
+ device => '/dev/ttySL0',
+ restart_service => 1,
+ },
+ ],
+
+ wireless =>
+ [
+ {
+ matching => 'zd1201',
+ description => 'ZyDAS ZD1201',
+ url => 'http://linux-lc100020.sourceforge.net/',
+ firmware =>
+ {
+ test_file => 'zd1201*.fw',
+ },
+ },
+
+ (map { (
+ "ipw${_}" =>
+ {
+ matching => "ipw${_}",
+ description => "Intel® PRO/Wireless ${_}",
+ url => "http://ipw${_}.sourceforge.net/",
+ name => "ipw${_}",
+ firmware =>
+ {
+ test_file => ($_ == 2100 ? "ipw2100-*.fw" : "ipw-*.fw"),
+ },
+ },
+ );
+ } (2100, 2200)),
+
+ {
+ matching => 'prism54',
+ description => 'Prism GT / Prism Duette / Prism Indigo Chipsets',
+ url => 'http://prism54.org/',
+ name => 'prism54',
+ firmware =>
+ {
+ url => 'http://prism54.org/~mcgrof/firmware/',
+ test_file => "isl38*",
+ },
+ },
+
+ {
+ matching => qr/^at76c50/,
+ description => 'Atmel at76c50x cards',
+ url => 'http://thekelleys.org.uk/atmel/',
+ name => 'atmel',
+ firmware =>
+ {
+ test_file => 'atmel_at76c50*',
+ },
+ links => 'http://at76c503a.berlios.de/',
+ },
+ ],
+
+ dsl =>
+ [
+ {
+ matching => sub { detect_devices::getSpeedtouch() },
+ description => N_("Alcatel speedtouch USB modem"),
+ url => "http://www.speedtouch.com/supuser.htm",
+ name => 'speedtouch',
+ tools =>
+ {
+ test_file => '/usr/sbin/modem_run',
+ },
+ firmware =>
+ {
+ package => 'speedtouch_mgmt',
+ prefix => '/usr/share/speedtouch',
+ test_file => 'mgmt*.o',
+ explanations => N_("Copy the Alcatel microcode as mgmt.o in /usr/share/speedtouch/"),
+ user_install => \&install_speedtouch_microcode,
+ },
+ links => 'http://linux-usb.sourceforge.net/SpeedTouch/mandrake/index.html',
+ },
+
+ {
+ matching => 'eciadsl',
+ url => 'http://eciadsl.flashtux.org/',
+ name => 'eciadsl',
+ tools => 1,
+ },
+
+ {
+ matching => 'eagle-usb',
+ description => 'Eagle chipset (from Analog Devices), e.g. Sagem F@st 800/840/908',
+ url => 'http://www.eagle-usb.org/',
+ name => 'eagle-usb',
+ tools =>
+ {
+ test_file => '/sbin/eaglectrl',
+ },
+ },
+
+ {
+ matching => 'bewan',
+ description => 'Bewan Adsl (Unicorn)',
+ url => 'http://www.bewan.com/bewan/users/downloads/',
+ name => 'unicorn',
+ kernel_module => 1,
+ tools => 1,
+ },
+ ],
+);
+
+sub device_get_package {
+ my ($settings, $option, $o_default) = @_;
+ $settings->{$option} or return;
+ my $package;
+ if (ref $settings->{$option} eq 'HASH') {
+ $package = $settings->{$option}{package} || 1;
+ } else {
+ $package = $settings->{$option};
+ }
+ $package == 1 ? $o_default || $settings->{name} : $package;
+}
+
+sub device_get_option {
+ my ($settings, $option) = @_;
+ $settings->{$option} or return;
+ my $value = $settings->{$option};
+ $value == 1 ? $settings->{name} : $value;
+}
+
+sub find_settings {
+ my ($category, $driver) = @_;
+ find {
+ my $type = ref $_->{matching};
+ $type eq 'Regexp' && $driver =~ $_->{matching} ||
+ $type eq 'CODE' && $_->{matching}->($driver) ||
+ $type eq 'ARRAY' && member($driver, @{$_->{matching}}) ||
+ $driver eq $_->{matching};
+ } @{$network_settings{$category}};
+}
+
+sub warn_not_installed {
+ my ($in, @packages) = @_;
+ $in->ask_warn(N("Error"), N("Could not install the packages (%s)!", @packages));
+}
+
+sub warn_not_found {
+ my ($in, $settings, $option, @packages) = @_;
+ my ($url, $expl);
+ if (ref $settings->{$option}) {
+ $url = $settings->{$option}{url};
+ $expl = $settings->{$option}{explanations};
+ }
+ $url ||= $settings->{url};
+ $in->ask_warn(N("Error"),
+ N("Some packages (%s) are required but aren't available. They can be found in Mandriva Club or in Mandriva commercial releases.", @packages) .
+ if_($url, "\n\n" . N("The required files can also be installed from this URL:
+%s", $url)) .
+ if_($expl, "\n\n" . translate($expl)));
+}
+
+sub is_file_installed {
+ my ($settings, $option) = @_;
+ my $file = exists $settings->{$option} && $settings->{$option}{test_file};
+ $file && -e "$::prefix$file";
+}
+
+sub is_module_installed {
+ my ($driver) = @_;
+ find { m!/\Q$driver\E\.k?o! } cat_("$::prefix/lib/modules/" . c::kernel_version() . '/modules.dep');
+}
+
+sub is_firmware_installed {
+ my ($settings) = @_;
+ my $wildcard = exists $settings->{firmware} && $settings->{firmware}{test_file} or return;
+ my $path = $settings->{firmware}{prefix} || $hotplug_firmware_prefix;
+ scalar glob_("$::prefix$path/$wildcard");
+}
+
+sub find_file_on_windows_system {
+ my ($in, $file) = @_;
+ my $source;
+ require fsedit;
+ my $all_hds = fsedit::get_hds();
+ fs::get_info_from_fstab($all_hds);
+ if (my $part = find { $_->{device_windobe} eq 'C' } fs::get::fstab($all_hds)) {
+ foreach (qw(windows/system winnt/system windows/system32/drivers winnt/system32/drivers)) {
+ -d $_ and $source = first(glob_("$part->{mntpoint}/$_/$file")) and last;
+ }
+ $source or $in->ask_warn(N("Error"), N("Unable to find \"%s\" on your Windows system!", $file));
+ } else {
+ $in->ask_warn(N("Error"), N("No Windows system has been detected!"));
+ }
+ { file => $source };
+}
+
+sub find_file_on_floppy {
+ my ($in, $file) = @_;
+ my $floppy = detect_devices::floppy();
+ my $mountpoint = '/mnt/floppy';
+ my $h;
+ $in->ask_okcancel(N("Insert floppy"),
+ N("Insert a FAT formatted floppy in drive %s with %s in root directory and press %s", $floppy, $file, N("Next"))) or return;
+ if (eval { fs::mount(devices::make($floppy), $mountpoint, 'vfat', 'readonly'); 1 }) {
+ log::explanations("Mounting floppy device $floppy in $mountpoint");
+ $h = before_leaving { fs::umount($mountpoint) };
+ if ($h->{file} = first(glob("$mountpoint/$file"))) {
+ log::explanations("Found $h->{file} on floppy device");
+ } else {
+ log::explanations("Unabled to find $file on floppy device");
+ }
+ } else {
+ $in->ask_warn(N("Error"), N("Floppy access error, unable to mount device %s", $floppy));
+ log::explanations("Unable to mount floppy device $floppy");
+ }
+ $h;
+}
+
+sub install_speedtouch_microcode {
+ my ($in) = @_;
+ my $choice;
+ $in->ask_from('',
+ N("You need the Alcatel microcode.
+You can provide it now via a floppy or your windows partition,
+or skip and do it later."),
+ [ { type => "list", val => \$choice, format => \&translate,
+ list => [ N_("Use a floppy"), N_("Use my Windows partition") ] } ]) or return;
+ my ($h, $source);
+ if ($choice eq N_("Use a floppy")) {
+ $source = 'mgmt*.o';
+ $h = find_file_on_floppy($in, $source);
+ } else {
+ $source = 'alcaudsl.sys';
+ $h = find_file_on_windows_system($in, $source);
+ }
+ unless (-e $h->{file} && cp_f($h->{file}, "$::prefix/usr/share/speedtouch/mgmt.o")) {
+ $in->ask_warn(N("Error"), N("Firmware copy failed, file %s not found", $source));
+ log::explanations("Firmware copy of $source ($h->{file}) failed");
+ return;
+ }
+ log::explanations("Firmware copy of $h->{file} succeeded");
+ $in->ask_warn(N("Congratulations!"), N("Firmware copy succeeded"));
+ 1;
+}
+
+sub install_packages {
+ my ($in, $settings, $driver, @options) = @_;
+
+ foreach my $option (@options) {
+ my %methods =
+ (
+ default =>
+ {
+ find_package_name => sub { device_get_package($settings, $option) },
+ check_installed => sub { is_file_installed($settings, $option) },
+ get_packages => sub { my ($name) = @_; $in->do_pkgs->is_available($name) },
+ user_install => sub { my $f = $settings->{$option}{user_install}; $f && $f->($in) },
+ },
+ kernel_module =>
+ {
+ find_package_name => sub { device_get_package($settings, $option, "$settings->{name}-kernel") },
+ check_installed => sub { is_module_installed($driver) },
+ get_packages => sub { my ($name) = @_; my $l = $in->do_pkgs->check_kernel_module_packages($name); $l ? @$l : () }
+ },
+ firmware =>
+ {
+ find_package_name => sub { device_get_package($settings, $option, "$settings->{name}-firmware") },
+ check_installed => sub { is_firmware_installed($settings) },
+ },
+ );
+ my $get_method = sub { my ($method) = @_; exists $methods{$option} && $methods{$option}{$method} || $methods{default}{$method} };
+
+ my $name = $get_method->('find_package_name')->();
+ unless ($name) {
+ log::explanations(qq(No $option package for module "$driver" is required, skipping));
+ next;
+ }
+
+ if ($get_method->('check_installed')->()) {
+ log::explanations(qq(Required $option package for module "$driver" is already installed, skipping));
+ next;
+ }
+
+ if (my @packages = $get_method->('get_packages')->($name)) {
+ log::explanations("Installing thirdparty packages ($option) " . join(', ', @packages));
+ $in->do_pkgs->install(@packages) and next;
+ warn_not_installed($in, @packages);
+ }
+ log::explanations("Thirdparty package $name ($option) is required but not available");
+
+ unless ($get_method->('user_install')->($in)) {
+ warn_not_found($in, $settings, $option, $name);
+ return;
+ }
+ }
+
+ 1;
+}
+
+sub setup_device {
+ my ($in, $category, $driver) = @_;
+ if (my $settings = find_settings($category, $driver)) {
+ log::explanations(qq(Found settings for driver "$driver" in category "$category"));
+
+ my $_w = $in->wait_message('', N("Looking for required software and drivers..."));
+
+ install_packages($in, $settings, $driver, qw(kernel_module firmware tools)) or return;
+
+ if (my $service = device_get_option($settings, 'service')) {
+ log::explanations("Restarting service $service");
+ services::restart_or_start($service);
+ }
+
+ if (my $post = $settings->{post}) {
+ my $_w = $in->wait_message('', N("Please wait, running device configuration commands..."));
+ log::explanations("Running post-install command $post");
+ run_program::rooted($::prefix, $post);
+ }
+
+ log::explanations(qq(Settings for driver "$driver" applied));
+ } else {
+ log::explanations(qq(No settings found for driver "$driver" in category "$category"));
+ }
+ 1;
+}
+
+1;
diff --git a/perl-install/network/tools.pm b/perl-install/network/tools.pm
index 6ba1d9886..ba51572a7 100644
--- a/perl-install/network/tools.pm
+++ b/perl-install/network/tools.pm
@@ -3,7 +3,6 @@ package network::tools; # $Id$
use strict;
use common;
use run_program;
-use fsedit;
use c;
use vars qw(@ISA @EXPORT @EXPORT_OK);
use MDK::Common::System qw(getVarsFromSh);
@@ -169,37 +168,6 @@ sub remove_initscript() {
}
}
-sub use_windows {
- my ($file) = @_;
- my $all_hds = fsedit::get_hds();
- fs::get_info_from_fstab($all_hds);
- if (my $part = find { $_->{device_windobe} eq 'C' } fs::get::fstab($all_hds)) {
- my $source = find { -d $_ && -r "$_/$file" } map { "$part->{mntpoint}/$_" } qw(windows/system winnt/system windows/system32/drivers winnt/system32/drivers);
- log::explanations("Seek in $source to find firmware");
- $source;
- } else {
- my $failed = N("No partition available");
- log::explanations($failed);
- undef, $failed;
- }
-}
-
-sub use_floppy {
- my ($in, $file) = @_;
- my $floppy = detect_devices::floppy();
- $in->ask_okcancel(N("Insert floppy"),
- N("Insert a FAT formatted floppy in drive %s with %s in root directory and press %s", $floppy, $file, N("Next"))) or return;
- if (eval { fs::mount(devices::make($floppy), '/mnt', 'vfat', 'readonly'); 1 }) {
- log::explanations("Mounting floppy device $floppy in /mnt");
- '/mnt';
- } else {
- my $failed = N("Floppy access error, unable to mount device %s", $floppy);
- log::explanations($failed);
- undef, $failed;
- }
-}
-
-
sub is_dynamic_ip {
my ($intf) = @_;
any { $_->{BOOTPROTO} !~ /^(none|static|)$/ } values %$intf;