summaryrefslogtreecommitdiffstats
path: root/lib/network/thirdparty.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/network/thirdparty.pm')
-rw-r--r--lib/network/thirdparty.pm451
1 files changed, 145 insertions, 306 deletions
diff --git a/lib/network/thirdparty.pm b/lib/network/thirdparty.pm
index b7b8c1e..2c8acb0 100644
--- a/lib/network/thirdparty.pm
+++ b/lib/network/thirdparty.pm
@@ -9,6 +9,9 @@ use fs::get;
use fs;
use log;
+#- using bsd_glob() since glob("/DONT_EXIST") return "/DONT_EXIST" instead of () (and we don't want this)
+use File::Glob ':glob';
+
#- network_settings is an hash of categories (rtc, dsl, wireless, ...)
#- each category is an hash of device settings
@@ -61,220 +64,10 @@ use log;
#- o no_club:
#- 1 if the package isn't available on Mandriva club
-my $firmware_directory = "/lib/firmware";
-
-my %network_settings = (
- rtc =>
- [
- {
- matching => qr/^Hcf:/,
- description => 'HCF 56k Modem',
- url => 'http://www.linuxant.com/drivers/hcf/',
- name => 'hcfpcimodem',
- kernel_module => {
- test_file => 'hcfpciengine',
- },
- tools =>
- {
- test_file => '/usr/sbin/hcfpciconfig',
- },
- device => '/dev/ttySHCF0',
- post => '/usr/sbin/hcfpciconfig --auto',
- restart_service => 'hcfpci',
- },
-
- {
- matching => qr/^Hsf:/,
- description => 'HSF 56k Modem',
- url => 'http://www.linuxant.com/drivers/hsf/',
- name => 'hsfmodem',
- kernel_module => {
- test_file => 'hsfengine',
- },
- tools =>
- {
- test_file => '/usr/sbin/hsfconfig',
- },
- device => '/dev/ttySHSF0',
- post => '/usr/sbin/hsfconfig --auto',
- restart_service => 'hsf',
- },
-
- {
- 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',
- post => sub {
- my ($driver) = @_;
- addVarsInSh("$::prefix/etc/sysconfig/slmodemd", { SLMODEMD_MODULE => $driver });
- },
- restart_service => "slmodemd",
- },
-
- {
- matching => 'sm56',
- description => 'Motorola SM56 WinModem',
- url => 'http://www.motorola.com/softmodem/driver.htm#linux',
- name => 'sm56',
- kernel_module =>
- {
- package => 'sm56',
- },
- no_club => 1,
- device => '/dev/sm56',
- },
- ],
-
- wireless =>
- [
- {
- matching => 'zd1201',
- description => 'ZyDAS ZD1201',
- url => 'http://linux-lc100020.sourceforge.net/',
- firmware =>
- {
- test_file => 'zd1201*.fw',
- },
- },
-
- (map {
- {
- matching => "ipw${_}",
- description => "Intel(R) PRO/Wireless ${_}",
- url => "http://ipw${_}.sourceforge.net/",
- name => "ipw${_}",
- firmware =>
- {
- url => "http://ipw${_}.sourceforge.net/firmware.php",
- test_file => ($_ == 2100 ? "ipw2100-*.fw" : "ipw-2.3-*.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/',
- },
-
- {
- matching => 'ath_pci',
- description => 'Multiband Atheros Driver for WiFi',
- url => 'http://madwifi.sourceforge.net/',
- name => 'madwifi',
- kernel_module => 1,
- tools => {
- optionnal => 1,
- test_file => '/usr/bin/athstats',
- },
- },
- ],
-
- dsl =>
- [
- {
- matching => 'speedtouch',
- 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',
- name => 'eciadsl',
- explanations => N_("The ECI Hi-Focus modem cannot be supported due to binary driver distribution problem.
-
-You can find a driver on http://eciadsl.flashtux.org/"),
- no_club => 1,
- tools => {
- test_file => '/usr/sbin/pppoeci',
- },
- },
-
- {
- matching => 'sagem',
- 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 => {
- test_file => 'unicorn_.*_atm',
- },
- tools => {
- optionnal => 1,
- test_file => '/usr/bin/bewan_adsl_status',
- },
- },
- ],
-);
-
-sub device_get_package {
+our $firmware_directory = "/lib/firmware";
+our @thirdparty_types = qw(kernel_module tools firmware);
+
+sub device_get_packages {
my ($settings, $option, $o_default) = @_;
$settings->{$option} or return;
my $package;
@@ -283,25 +76,26 @@ sub device_get_package {
} else {
$package = $settings->{$option};
}
- $package == 1 ? $o_default || $settings->{name} : $package;
+ $package == 1 ? $o_default || $settings->{name} : ref $package eq 'ARRAY' ? @$package : $package;
}
sub device_get_option {
- my ($settings, $option) = @_;
+ my ($settings, $option, $o_default) = @_;
$settings->{$option} or return;
my $value = $settings->{$option};
- $value == 1 ? $settings->{name} : $value;
+ $value == 1 ? $o_default || $settings->{name} : $value;
}
sub find_settings {
- my ($category, $driver) = @_;
+ my ($settings_list, $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}};
+ my $match = $_->{matching} || $_->{name};
+ my $type = ref $match;
+ $type eq 'Regexp' && $driver =~ $match ||
+ $type eq 'CODE' && $match->($driver) ||
+ $type eq 'ARRAY' && member($driver, @$match) ||
+ $driver eq $match;
+ } @$settings_list;
}
sub device_run_command {
@@ -318,37 +112,53 @@ sub device_run_command {
sub warn_not_installed {
my ($in, @packages) = @_;
- $in->ask_warn(N("Error"), N("Could not install the packages (%s)!", @packages));
+ $in->ask_warn(N("Error"), N("Could not install the packages (%s)!", join(', ', @packages)));
+}
+
+sub get_checked_element {
+ my ($settings, $driver, $option) = @_;
+ $option eq 'firmware' ?
+ get_firmware_path($settings) :
+ $option eq 'kernel_module' ?
+ $driver :
+ ref $settings->{$option} eq 'HASH' && $settings->{$option}{test_file};
}
sub warn_not_found {
- my ($in, $settings, $option, @packages) = @_;
+ my ($in, $settings, $driver, $option, @packages) = @_;
my %opt;
- $opt{$_} = $settings->{$option}{$_} || $settings->{$_} foreach qw(url explanations no_club);
+ $opt{$_} = ref $settings->{$option} eq 'HASH' && $settings->{$option}{$_} || $settings->{$_} foreach qw(url explanations no_club no_package);
+ my $checked = get_checked_element($settings, $driver, $option);
$in->ask_warn(N("Error"),
- N("Some packages (%s) are required but aren't available.", @packages) .
- (!$opt{no_club} && "\n" . N("These packages can be found in Mandriva Club or in Mandriva commercial releases.")) .
- ($option eq 'firmware' && "\n\n" . N("Info: ") . "\n" . N("due to missing %s", get_firmware_path($settings))) .
- ($opt{url} && "\n\n" . N("The required files can also be installed from this URL:
-%s", $opt{url})) .
- ($opt{explanations} && "\n\n" . translate($opt{explanations})));
+ join('',
+ ($opt{no_package} ?
+ N("Some components (%s) are required but aren't available for %s hardware.", $option, $settings->{name}) :
+ N("Some packages (%s) are required but aren't available.", join(', ', @packages))),
+ join("\n\n",
+ if_(!$opt{no_club} && !$opt{no_package}, N("These packages can be found in Mandriva Club or in Mandriva commercial releases.")),
+ if_($checked, N("The following component is missing: %s", $checked)),
+ if_($opt{explanations}, translate($opt{explanations})),
+ if_($opt{url}, N("The required files can also be installed from this URL:
+%s", $opt{url})),
+ )));
}
sub is_file_installed {
my ($settings, $option) = @_;
- my $file = exists $settings->{$option} && $settings->{$option}{test_file};
+ my $file = ref $settings->{$option} eq 'HASH' && $settings->{$option}{test_file};
$file && -e "$::prefix$file";
}
sub is_module_installed {
my ($settings, $driver) = @_;
+ require modules;
my $module = ref $settings->{kernel_module} eq 'HASH' && $settings->{kernel_module}{test_file} || $driver;
- find { m!/$module\.k?o! } cat_("$::prefix/lib/modules/" . c::kernel_version() . '/modules.dep');
+ modules::module_is_available($module);
}
sub get_firmware_path {
my ($settings) = @_;
- my $wildcard = exists $settings->{firmware} && $settings->{firmware}{test_file} or return;
+ my $wildcard = ref $settings->{firmware} eq 'HASH' && $settings->{firmware}{test_file} or return;
my $path = $settings->{firmware}{prefix} || $firmware_directory;
"$::prefix$path/$wildcard";
}
@@ -356,7 +166,40 @@ sub get_firmware_path {
sub is_firmware_installed {
my ($settings) = @_;
my $pattern = get_firmware_path($settings) or return;
- scalar glob_($pattern);
+ scalar bsd_glob($pattern, undef);
+}
+
+sub extract_firmware {
+ my ($settings, $in) = @_;
+ my $choice;
+ $in->ask_from('', N("Firmware files are required for this device."),
+ [ { type => "list", val => \$choice, format => \&translate,
+ list => [
+ if_(exists $settings->{firmware}{extract}{floppy_source}, N_("Use a floppy")),
+ if_(exists $settings->{firmware}{extract}{windows_source}, N_("Use my Windows partition")),
+ N_("Select file")
+ ] } ]) or return;
+ my ($h, $source);
+ if ($choice eq N_("Use a floppy")) {
+ $source = $settings->{firmware}{extract}{floppy_source};
+ $h = find_file_on_floppy($in, $source);
+ } elsif ($choice eq N_("Use my Windows partition")) {
+ $source = $settings->{firmware}{extract}{windows_source};
+ $h = find_file_on_windows_system($in, $source);
+ } else {
+ $source = $settings->{firmware}{extract}{default_source};
+ $h = { file => $in->ask_file(N("Please select the firmware file (for example: %s)", basename($source)), dirname($source)) };
+ }
+ if (!-e $h->{file}) {
+ log::explanations("Unable to find firmware file (tried to find $source.");
+ return;
+ }
+
+ if ($settings->{firmware}{extract}{name}) {
+ $in->do_pkgs->ensure_is_installed($settings->{firmware}{extract}{name}, $settings->{firmware}{extract}{test_file}) or return;
+ }
+ $settings->{firmware}{extract}{run}->($h->{file});
+ 1;
}
sub find_file_on_windows_system {
@@ -367,7 +210,7 @@ sub find_file_on_windows_system {
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;
+ -d $_ and $source = first(bsd_glob("$part->{mntpoint}/$_/$file", undef)) and last;
}
$source or $in->ask_warn(N("Error"), N("Unable to find \"%s\" on your Windows system!", $file));
} else {
@@ -379,14 +222,14 @@ sub find_file_on_windows_system {
sub find_file_on_floppy {
my ($in, $file) = @_;
my $floppy = detect_devices::floppy();
- my $mountpoint = '/mnt/floppy';
+ my $mountpoint = '/media/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::mount(devices::make($floppy), $mountpoint, 'vfat', 'readonly'); 1 }) {
log::explanations("Mounting floppy device $floppy in $mountpoint");
$h = before_leaving { fs::mount::umount($mountpoint) };
- if ($h->{file} = first(glob("$mountpoint/$file"))) {
+ if ($h->{file} = first(bsd_glob("$mountpoint/$file", undef))) {
log::explanations("Found $h->{file} on floppy device");
} else {
log::explanations("Unabled to find $file on floppy device");
@@ -398,84 +241,75 @@ sub find_file_on_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);
+sub get_required_packages {
+ my ($type, $settings) = @_;
+ device_get_packages($settings, $type, if_($type eq 'firmware', "$settings->{name}-firmware"));
+}
+
+sub check_installed {
+ my ($type, $settings, $driver) = @_;
+ $type eq 'kernel_module' ?
+ is_module_installed($settings, $driver) :
+ $type eq 'firmware' ?
+ is_firmware_installed($settings) :
+ is_file_installed($settings, $type);
+}
+
+sub get_available_packages {
+ my ($type, $in, @names) = @_;
+ if ($type eq 'kernel_module') {
+ return map { my $l = $in->do_pkgs->check_kernel_module_packages($_); $l ? @$l : () } @names;
} else {
- $source = 'alcaudsl.sys';
- $h = find_file_on_windows_system($in, $source);
+ return $in->do_pkgs->is_available(@names);
}
- 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;
+}
+
+sub user_install {
+ my ($type, $settings, $in) = @_;
+ if ($type eq 'firmware') {
+ ref $settings->{$type} eq 'HASH' or return;
+ if ($settings->{$type}{extract}) {
+ extract_firmware($settings, $in);
+ } else {
+ my $f = $settings->{$type}{user_install};
+ $f && $f->($settings, $in);
+ }
+ } else {
+ my $f = ref $settings->{$type} eq 'HASH' && $settings->{$type}{user_install};
+ $f && $f->($settings, $in);
}
- 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($settings, $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) {
+ my @packages = get_required_packages($option, $settings);
+ unless (@packages) {
log::explanations(qq(No $option package for module "$driver" is required, skipping));
next;
}
- if ($get_method->('check_installed')->()) {
+ if (check_installed($option, $settings, $driver)) {
+ $settings->{old_status}{$option} = 1;
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));
- if (!$in->do_pkgs->install(@packages)) {
- next if ref $settings->{$option} eq 'HASH' && $settings->{$option}{optionnal};
- warn_not_installed($in, @packages);
- } elsif ($get_method->('check_installed')->()) {
- next;
+ my $optional = ref $settings->{$option} eq 'HASH' && $settings->{$option}{optional};
+ if (my @avalaible = get_available_packages($option, $in, @packages)) {
+ log::explanations("Installing thirdparty packages ($option) " . join(', ', @avalaible));
+ if ($in->do_pkgs->install(@avalaible) && check_installed($option, $settings, $in)) {
+ next;
+ } elsif (!$optional) {
+ warn_not_installed($in, @avalaible);
}
}
- log::explanations("Thirdparty package $name ($option) is required but not available");
+ next if $optional;
+ log::explanations("Thirdparty package @packages ($option) is required but not available");
- unless ($get_method->('user_install')->($in)) {
- warn_not_found($in, $settings, $option, $name);
+ unless (user_install($option, $settings, $in)) {
+ warn_not_found($in, $settings, $driver, $option, @packages);
return;
}
}
@@ -483,16 +317,22 @@ sub install_packages {
1;
}
-sub setup_device {
- my ($in, $category, $driver, $o_config, @o_fields) = @_;
+sub apply_settings {
+ my ($in, $category, $settings_list, $driver) = @_;
- my $settings = find_settings($category, $driver);
+ my $settings = find_settings($settings_list, $driver);
if ($settings) {
log::explanations(qq(Found settings for driver "$driver" in category "$category"));
my $wait = $in->wait_message('', N("Looking for required software and drivers..."));
- install_packages($in, $settings, $driver, qw(kernel_module firmware tools)) or return;
+ install_packages($in, $settings, $driver, @thirdparty_types) or return;
+
+ if (exists $settings->{firmware} && !$settings->{old_status}{firmware}) {
+ log::explanations("Reloading module $driver");
+ eval { modules::unload($driver) };
+ eval { modules::load($driver) };
+ }
undef $wait;
$wait = $in->wait_message('', N("Please wait, running device configuration commands..."));
@@ -503,15 +343,14 @@ sub setup_device {
services::restart_or_start($service);
}
+ $settings->{sleep} and sleep $settings->{sleep};
+
log::explanations(qq(Settings for driver "$driver" applied));
} else {
log::explanations(qq(No settings found for driver "$driver" in category "$category"));
}
- #- assign requested settings, erase with undef if no settings have been found
- $o_config->{$_} = $settings->{$_} foreach @o_fields;
-
- 1;
+ $settings || {};
}
1;