wok annotate tazndis/stuff/tazndis @ rev 11806

sdcc: fix cp -u
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sat Feb 25 16:25:09 2012 +0100 (2012-02-25)
parents 5117bf553562
children
rev   line source
erjo@1850 1 #!/usr/bin/perl
erjo@1850 2
erjo@1850 3 #/*
erjo@1850 4 #* tazndis, install, remove or list of NDIS drivers.
erjo@1850 5 #*
erjo@1850 6 #* This program is a replacement for ndiswrapper utility written by
erjo@1850 7 #* Pontus Fuchs and Giridhar Pemmasani.
erjo@1850 8 #* Most part of code come from the original ndiswrapper PERL script.
erjo@1850 9 #*
erjo@1850 10 #* If you need more complexe commands consider to use the original ndiswrapper
erjo@1850 11 #* instead.
erjo@1850 12 #*
erjo@1850 13 #* Copyright (C) 2008 Eric Joseph-Alexandre
erjo@1850 14 #* Copyright (C) 2005-2006 Pontus Fuchs, Giridhar Pemmasani
erjo@1850 15 #*
erjo@1850 16 #*
erjo@1850 17 #* This program is free software; you can redistribute it and/or modify
erjo@1850 18 #* it under the terms of the GNU General Public License as published by
erjo@1850 19 #* the Free Software Foundation; either version 2 of the License, or
erjo@1850 20 #* (at your option) any later version.
erjo@1850 21 #*
erjo@1850 22 #* This program is distributed in the hope that it will be useful,
erjo@1850 23 #* but WITHOUT ANY WARRANTY; without even the implied warranty of
erjo@1850 24 #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
erjo@1850 25 #* GNU General Public License for more details.
erjo@1850 26 #*
erjo@1850 27 #*/
erjo@1850 28
erjo@1941 29 $VERSION="1.53.1";
erjo@1893 30 $ENV{PATH} = "/sbin:/usr/sbin:/bin:/usr/bin";
erjo@1850 31
erjo@1850 32 my $WRAP_PCI_BUS = 5;
erjo@1850 33 my $WRAP_PCMCIA_BUS = 8;
erjo@1850 34 my $WRAP_USB_BUS = 15;
erjo@1850 35
erjo@1850 36 my %sections;
erjo@1850 37 my %parsed_sections;
erjo@1850 38 my $confdir = "/etc/ndiswrapper";
erjo@1850 39 my $src_dir;
erjo@1850 40 my $driver_name;
erjo@1850 41 my @source_disks_files;
erjo@1850 42
erjo@1850 43 my $re_dev_id = "([[:xdigit:]]{4})";
erjo@1850 44 my $re_sub_dev_conf = "$re_dev_id:$re_dev_id:$re_dev_id:$re_dev_id" .
erjo@1850 45 "\.([[:xdigit:]]+)\.conf";
erjo@1850 46 my $re_dev_conf = "$re_dev_id:$re_dev_id\.([[:xdigit:]]+)\.conf";
erjo@1850 47
erjo@1910 48 my $rcs_config = "/etc/rcS.conf";
erjo@1941 49 my $net_config = "/etc/network.conf";
erjo@1941 50 my $config_change = 1;
erjo@1950 51 #my $dbg = 1;
erjo@1941 52
erjo@1910 53
erjo@1850 54 # fixup list for parameters.
erjo@1850 55 my %param_fixlist = ("EnableRadio|0" => "1",
erjo@1850 56 "IBSSGMode|0" => "2",
erjo@1850 57 "PrivacyMode|0" => "2",
erjo@1850 58 "MapRegisters|256" => "64",
erjo@1850 59 "AdhocGMode|1" => "0");
erjo@1850 60
erjo@1850 61 if (@ARGV < 1) {
erjo@1850 62 usage();
erjo@1850 63 exit(1);
erjo@1850 64 }
erjo@1850 65
erjo@1850 66 my $res;
erjo@1850 67 my $dbg_file;
erjo@1850 68
erjo@1850 69 $dbg_file = "/dev/null";
erjo@1850 70
erjo@1850 71 # "-D" is for development/debugging only
erjo@1850 72 if ($ARGV[0] eq "-D") {
erjo@1942 73 my $dbg = 0;
erjo@1850 74 $dbg_file = "/tmp/ndiswrapper.dbg";
erjo@1850 75 $confdir = "/tmp/ndiswrapper";
erjo@1850 76 open(DBG, "> $dbg_file") or die "couldn't open $dbg_file: $!";
erjo@1850 77 shift;
erjo@1850 78 }
erjo@1850 79
erjo@1850 80 if ($ARGV[0] eq "-i" and @ARGV == 2) {
erjo@1850 81 $res = install($ARGV[1]);
erjo@1850 82 } elsif (($ARGV[0] eq "-r") and @ARGV == 2) {
erjo@1850 83 $res = remove_driver($ARGV[1]);
erjo@1850 84 } elsif ($ARGV[0] eq "-l" and @ARGV == 1) {
erjo@1850 85 $res = list_drivers();
erjo@1850 86 } elsif ($ARGV[0] eq "-v" and @ARGV == 1) {
erjo@1850 87 $res = check_version();
erjo@1850 88 } else {
erjo@1850 89 usage();
erjo@1850 90 }
erjo@1850 91 close(DBG);
erjo@1850 92 exit($res);
erjo@1850 93
erjo@1850 94 sub usage() {
erjo@1893 95 print "install/manage Windows drivers for ndiswrapper kernel module\n\n" .
erjo@1873 96 "usage: tazndis OPTION\n" .
erjo@1850 97 "-i inffile install driver described by 'inffile'\n" .
erjo@1850 98 "-r driver remove 'driver'\n" .
erjo@1850 99 "-l list installed drivers\n" .
erjo@1850 100 "-v report version information\n\n" .
erjo@1893 101 "If you need more complex operation, you may install full ndiswrapper package instead.\n" ;
erjo@1850 102 }
erjo@1850 103
erjo@1850 104 #/*
erjo@1850 105 #* Begin of PERL modules substition
erjo@1850 106 #*
erjo@1850 107 #* Replaced File.pm
erjo@1850 108
erjo@1850 109 sub basename(@_){
erjo@1910 110 ($a = shift) =~ s#.*/(.*)$#$1#;
erjo@1910 111 return $a;
erjo@1850 112 }
erjo@1850 113
erjo@1850 114
erjo@1850 115 # delete given single tree with no sub directories.
erjo@1850 116 sub rmtree {
erjo@1850 117 local $dir = $_[0];
erjo@1850 118 opendir(DIR, $dir) or die "couldn't delete $dir: $!\n";
erjo@1850 119 @dirs = grep(!/^.{1,2}$/, readdir(DIR));
erjo@1850 120 foreach $file (@dirs){
erjo@1850 121 unlink "$dir/$file" or die "couldn't delete file $file $!";
erjo@1850 122 }
erjo@1850 123 if(rmdir "$dir"){
erjo@1850 124 return 1;
erjo@1850 125 }else{
erjo@1850 126 return 0;
erjo@1850 127 }
erjo@1850 128 }
erjo@1850 129
erjo@1850 130 # return current path.
erjo@1850 131 sub cwd {
erjo@1850 132 local $var;
erjo@1850 133 chomp($var = `pwd`);
erjo@1850 134 return $var;
erjo@1850 135 }
erjo@1850 136
erjo@1850 137 #
erjo@1850 138 sub copy {
erjo@1850 139 local ($file1, $file2) = @_;
erjo@1850 140 open (F1, "$file1") or
erjo@1850 141 die "couldn't open file $file1 for reading $!\n";
erjo@1850 142 open (F2, ">$file2") or
erjo@1850 143 die "couldn't open file $file2 for writing $!\n";
erjo@1850 144 if ($file1 =~ /\.((bin)|(sys)|(cat))$/) {
erjo@1850 145 binmode F1;
erjo@1850 146 binmode F2;
erjo@1850 147 while (read(F1,$buffer,1)) {
erjo@1850 148 print(F2 $buffer);
erjo@1850 149 }
erjo@1850 150 } else {
erjo@1850 151 while (<F1>) {
erjo@1850 152 print F2 $_;
erjo@1850 153 }
erjo@1850 154 }
erjo@1850 155 close F1;
erjo@1850 156 close F2;
erjo@1850 157 }
erjo@1850 158
erjo@1850 159 ##
erjo@1850 160 ## End of PERL modules substition
erjo@1850 161 ##
erjo@1850 162
erjo@1850 163 sub remove_driver {
erjo@1850 164 my $driver = shift;
erjo@1850 165 if (!rmtree("$confdir/$driver", 0, 1)) {
erjo@1850 166 warn "couldn't delete $confdir/$driver: $!\n";
erjo@1850 167 }
erjo@1850 168 return 0;
erjo@1850 169 }
erjo@1850 170
erjo@1850 171 sub abort {
erjo@1850 172 remove_driver($driver_name);
erjo@1850 173 exit 1;
erjo@1850 174 }
erjo@1850 175
erjo@1850 176 sub check_version {
erjo@1850 177 my ($utils_version, $module_utils_version, $res);
erjo@1850 178 $res = 0;
erjo@1850 179 $utils_version = `loadndisdriver -v`;
erjo@1850 180 chomp($utils_version);
erjo@1850 181 $utils_version =~ s/^version: //;
erjo@1850 182 if (length($utils_version) eq 0) {
erjo@1850 183 printf "utils version is too old!\n";
erjo@1850 184 $res = -1;
erjo@1850 185 }
erjo@1850 186 $module_utils_version = 0;
erjo@1850 187 open(MODINFO, "modinfo ndiswrapper |");
erjo@1850 188 while (my $line = <MODINFO>) {
erjo@1850 189 if ($line =~ /utils_version:.*read only:\s([0-9\.]+)/) {
erjo@1850 190 $module_utils_version = $1;
erjo@1850 191 last;
erjo@1850 192 }
erjo@1850 193 }
erjo@1850 194 if ($module_utils_version eq 0) {
erjo@1850 195 printf "module version is too old!\n";
erjo@1850 196 $res = -1;
erjo@1850 197 } elsif ($utils_version ne $module_utils_version) {
erjo@1850 198 printf "utils version '%s' is incompatible with utils version needed" .
erjo@1850 199 " by driver ('%s')!\n", $utils_version, $module_utils_version;
erjo@1850 200 $res = -1;
erjo@1850 201 }
erjo@1941 202 printf "tazndis version: %s\n ", $VERSION;
erjo@1850 203 printf "utils version: '%s', utils version needed by module: '%s'\n",
erjo@1850 204 $utils_version, $module_utils_version;
erjo@1850 205 printf "module details:\n";
erjo@1850 206 system("modinfo ndiswrapper | grep -E '^(version|vermagic|filename)'");
erjo@1850 207
erjo@1850 208 if ($res) {
erjo@1850 209 printf "\nYou may need to upgrade driver and/or utils to latest " .
erjo@1850 210 "versions available at\n" .
erjo@1850 211 "http://ndiswrapper.sourceforge.net\n";
erjo@1850 212 }
erjo@1850 213 return $res;
erjo@1850 214 }
erjo@1850 215
erjo@1910 216 sub set_rcs_config {
erjo@1910 217 # Add ndiswrapper to LOAD_MODULES if needed.
erjo@1941 218 open (CONFIG, "< $rcs_config") or die "couldn't open $rcs_config:$!";
erjo@1941 219 open (CONFIG1, "> $rcs_config.tmp") or die "couldn't open $rcs_config.tmp for writting:$!";
erjo@1941 220 LINE: while(<CONFIG>){
erjo@1910 221 if(/^LOAD_MODULES/){
erjo@1910 222 if (!/^LOAD_MODULES=.*ndiswrapper/){
erjo@1910 223 print "Add ndiswrapper to module list...\n";
erjo@1910 224 $_ =~ s/(.*)\"$/$1 ndiswrapper\"/;
erjo@1941 225 $file_change = 0;
erjo@1910 226 }
erjo@1910 227 }
erjo@1910 228 chomp;
erjo@1941 229 print CONFIG1 "$_\n";
erjo@1910 230 }
erjo@1941 231 close CONFIG, CONFIG1;
erjo@1910 232
erjo@1941 233 if($file_change == 0){
erjo@1910 234 rename "$rcs_config.tmp","$rcs_config" or die "couldn't update $rcs_config: $!";
erjo@1941 235 $config_change=1;
erjo@1910 236 } else {
erjo@1910 237 unlink "$rcs_config.tmp";
erjo@1910 238 }
erjo@1941 239 }
erjo@1941 240
erjo@1941 241 sub set_net_config {
erjo@1941 242 #
erjo@1941 243 open (CONFIG, "< $net_config") or die "couldn't open $net_config:$!";
erjo@1941 244 open (CONFIG1, "> $net_config.tmp") or die "couldn't open $net_config.tmp for writting:$!";
erjo@1941 245 print "Set WiFi to start at boot time...\n";
erjo@1941 246 LINE: while(<CONFIG>){
erjo@1941 247 if(/^WIFI=/){
erjo@1941 248 if (/^WIFI="no"$/){
erjo@1941 249 $_ =~ s/^WIFI="no"$/WIFI="yes"/;
erjo@1941 250 $config_change = 0;
erjo@1941 251 }
erjo@1941 252 }
erjo@1941 253 chomp;
erjo@1941 254 print CONFIG1 "$_\n";
erjo@1941 255 }
erjo@1941 256 close CONFIG, CONFIG1;
erjo@1910 257
erjo@1941 258 if($rcs_config_change == 0){
erjo@1941 259 rename "$net_config.tmp","$net_config" or die "couldn't update $rcs_config: $!";
erjo@1941 260 $config_change=1;
erjo@1941 261 } else {
erjo@1941 262 unlink "$net_config.tmp";
erjo@1941 263 }
erjo@1910 264 }
erjo@1910 265
erjo@1910 266 sub load_ndiswrapper {
erjo@1910 267 open (LSMOD, " lsmod |") or die "couldn't get loaded module list: $!";
erjo@1950 268 while(<LSMOD>) {
erjo@1950 269 if(/^ndiswrapper/){$tmp = 1;}
erjo@1950 270 }
erjo@1950 271 if(!$tmp) {
erjo@1941 272 print "Loading ndiswrapper...\n";
erjo@1941 273 `modprobe ndiswrapper`;
erjo@1941 274 }
erjo@1950 275 }
erjo@1950 276
erjo@1850 277 sub install {
erjo@1850 278 my $inf = shift;
erjo@1850 279 chomp($inf);
erjo@1893 280 chop($src_dir = `dirname $inf`);
erjo@1850 281 $driver_name = lc(basename($inf));
erjo@1850 282
erjo@1850 283 unless ($driver_name =~ s/\.inf$//) {
erjo@1850 284 die "install argument must be .inf file\n";
erjo@1850 285 }
erjo@1850 286
erjo@1850 287 if (! -d $confdir) {
erjo@1850 288 mkdir($confdir) or die "couldn't create $confdir: $!";
erjo@1850 289 }
erjo@1850 290 (-d "$confdir/$driver_name") and
erjo@1850 291 die "driver $driver_name is already installed\n";
erjo@1850 292
erjo@1850 293 read_sections($inf);
erjo@1850 294 parse_section("Strings");
erjo@1850 295 parse_section("Version");
erjo@1850 296 parse_source_disks_files();
erjo@1850 297 mkdir("$confdir/$driver_name") or
erjo@1850 298 die "couldn't create $confdir/$driver_name: $!";
erjo@1850 299 print "installing $driver_name ...\n";
erjo@1850 300 parse_mfr();
erjo@1850 301 copy_file(basename($inf), basename($inf));
erjo@1850 302 create_fuzzy_conf($driver_name);
erjo@1910 303
erjo@1910 304 #Update LOAD_MODULES and load ndiswrapper.
erjo@1942 305 # Only if we are not in debug mode.
erjo@1942 306 if (!$dbg) {
erjo@1942 307 set_rcs_config();
erjo@1942 308 load_ndiswrapper();
erjo@1942 309
erjo@1942 310 # Ask for WiFi at boot time.
erjo@1942 311 print "Would you to start WiFi at boot time [y/N]? ";
erjo@1942 312 chomp(my $answer = <STDIN>);
erjo@1942 313 if (lc($answer) eq "y") {
erjo@1942 314 set_net_config();
erjo@1942 315 }
erjo@1941 316 }
erjo@1893 317
erjo@1850 318 return 0;
erjo@1850 319 }
erjo@1850 320
erjo@1850 321 # return lines in section
erjo@1850 322 sub get_section {
erjo@1850 323 my $name = shift;
erjo@1850 324 foreach my $key (keys %sections) {
erjo@1850 325 if (lc($key) eq lc($name)) {
erjo@1850 326 printf DBG "section: $key\n";
erjo@1850 327 return \@{$sections{$key}};
erjo@1850 328 }
erjo@1850 329 }
erjo@1850 330 printf DBG "couldn't find section \"$name\"\n";
erjo@1850 331 return 0;
erjo@1850 332 }
erjo@1850 333
erjo@1850 334 # load inf and split into different sections.
erjo@1850 335 sub read_sections {
erjo@1850 336 my $filename = shift;
erjo@1850 337 open(INF, $filename) or die "couldn't open $filename: $!";
erjo@1850 338
erjo@1850 339 my $name = "none";
erjo@1850 340 @{$sections{$name}} = ();
erjo@1850 341 while (my $line = <INF>) {
erjo@1850 342 # convert from unicode
erjo@1850 343 $line =~ s/\xff\xfe//;
erjo@1850 344 $line =~ s/\0//g;
erjo@1850 345
erjo@1850 346 chomp($line);
erjo@1850 347 $line = trim($line);
erjo@1850 348 next if ($line =~ /^$/);
erjo@1850 349 if ($line =~ /^\[(.+)\]/) {
erjo@1850 350 $name = $1;
erjo@1850 351 @{$sections{$name}} = ();
erjo@1850 352 } else {
erjo@1850 353 push(@{$sections{$name}}, $line);
erjo@1850 354 }
erjo@1850 355 }
erjo@1850 356 close(INF);
erjo@1850 357 foreach $name (keys %sections) {
erjo@1850 358 printf DBG "section: %s\n", $name;
erjo@1850 359 foreach my $line (@{$sections{$name}}) {
erjo@1850 360 printf DBG "%s: %s\n", $name, $line;
erjo@1850 361 }
erjo@1850 362 }
erjo@1850 363 }
erjo@1850 364
erjo@1850 365 sub parse_section {
erjo@1850 366 my $name = shift;
erjo@1850 367 my $lines = get_section($name);
erjo@1850 368 if (!$lines) {
erjo@1950 369 return;
erjo@1850 370 }
erjo@1850 371 $parsed_sections{$name} = ();
erjo@1850 372 foreach my $line (@{$lines}) {
erjo@1850 373 (my $key, my $val) = parse_key_value($line);
erjo@1850 374 if ($key) {
erjo@1850 375 $val = strip_quotes($val);
erjo@1850 376 $parsed_sections{$name}->{$key} = $val;
erjo@1850 377 printf DBG "$name: %s = %s\n", $key, $val;
erjo@1850 378 }
erjo@1850 379 }
erjo@1850 380 }
erjo@1850 381
erjo@1850 382 sub parse_mfr() {
erjo@1850 383 my $lines = get_section("Manufacturer");
erjo@1850 384 $lines or die "couldn't get manufacturer section - " .
erjo@1850 385 "installation may be incomplete\n";
erjo@1850 386 foreach my $line (@{$lines}) {
erjo@1850 387 my ($strkey, $val) = parse_key_value($line);
erjo@1850 388 if ($strkey) {
erjo@1850 389 my ($models, @targets) = split(",", $val);
erjo@1850 390 if ($models) {
erjo@1850 391 printf DBG "mfr: %s, %s\n", $line, $models;
erjo@1850 392 my $target = choose_target_os(@targets);
erjo@1850 393 printf DBG "target: '%s'\n", $target;
erjo@1850 394 parse_models($models, $target);
erjo@1850 395 }
erjo@1850 396 }
erjo@1850 397 }
erjo@1850 398 }
erjo@1850 399
erjo@1850 400 sub parse_models {
erjo@1850 401 my ($models, $target) = @_;
erjo@1850 402 printf DBG "models: target: '%s'.'%s'\n", $models, $target;
erjo@1850 403 my $lines = get_target_os_section($models, $target);
erjo@1850 404 if (!$lines) {
erjo@1850 405 warn "couldn't find models section \"$models\" -\n" .
erjo@1850 406 "installation may be incomplete\n";
erjo@1850 407 return -1;
erjo@1850 408 }
erjo@1850 409 foreach my $line (@{$lines}) {
erjo@1850 410 $line = del_comment($line);
erjo@1850 411 next if (length($line) eq 0);
erjo@1850 412 (my $dev_desc, my $val) = parse_key_value($line);
erjo@1850 413 my @fields = split(",", $val);
erjo@1850 414 if (@fields le 1) {
erjo@1850 415 printf "couldn't find install directive: %s\n", $line;
erjo@1850 416 next;
erjo@1850 417 }
erjo@1850 418 my $section = trim($fields[0]);
erjo@1850 419 my $hwid = trim($fields[1]);
erjo@1850 420 if ($hwid =~ /^%.+%$/) {
erjo@1850 421 $hwid = get_string_value($hwid);
erjo@1850 422 }
erjo@1850 423 # TODO: deal with compatible IDs as hwid?
erjo@1850 424 my ($bus_type, $vendor, $device, $subvendor, $subdevice) =
erjo@1850 425 parse_hwid($hwid);
erjo@1850 426 next if (!$vendor);
erjo@1850 427 printf DBG "models: %s, %s, %s\n", $section, $hwid, $vendor;
erjo@1850 428 parse_install($section, $target, $bus_type, $vendor, $device,
erjo@1850 429 $subvendor, $subdevice);
erjo@1850 430 }
erjo@1850 431 }
erjo@1850 432
erjo@1850 433 sub parse_install {
erjo@1850 434 my ($section, $target, $bus_type, $vendor, $device,
erjo@1850 435 $subvendor, $subdevice) = @_;
erjo@1850 436 my $lines = get_target_os_section($section, $target);
erjo@1850 437 if (!$lines) {
erjo@1850 438 warn "couldn't find install section \"$section\" -\n" .
erjo@1850 439 "installation may be incomplete\n";
erjo@1850 440 return -1;
erjo@1850 441 }
erjo@1850 442
erjo@1850 443 my $filename = "$vendor:$device";
erjo@1850 444 if ($subvendor) {
erjo@1850 445 $filename .= ":$subvendor:$subdevice"
erjo@1850 446 }
erjo@1850 447 $filename .= sprintf(".%X.conf", $bus_type);
erjo@1850 448
erjo@1850 449 my (@addregs, @copyfiles);
erjo@1850 450 foreach my $line (@{$lines}) {
erjo@1850 451 $line =~ s/^;\s*//;
erjo@1850 452 $line = trim(del_comment($line));
erjo@1850 453 my ($key, $val) = parse_key_value($line);
erjo@1850 454 my @array;
erjo@1850 455 if ($key) {
erjo@1850 456 if (lc($key) eq "addreg") {
erjo@1850 457 @array = split(",", $val);
erjo@1850 458 foreach my $reg (@array) {
erjo@1850 459 push @addregs, trim($reg);
erjo@1850 460 }
erjo@1850 461 } elsif (lc($key) eq "copyfiles") {
erjo@1850 462 printf DBG "copyfiles: %s\n", $val;
erjo@1850 463 @array = split(",", $val);
erjo@1850 464 foreach my $copy_file_dirs (@array) {
erjo@1850 465 my @copy_sec = split(",", $copy_file_dirs);
erjo@1850 466 foreach my $file (@copy_sec) {
erjo@1850 467 push @copyfiles, trim($file);
erjo@1850 468 }
erjo@1850 469 }
erjo@1850 470 } elsif (lc($key) eq "bustype") {
erjo@1850 471 printf DBG "bustype: %s\n", $val;
erjo@1850 472 $bus_type = $val;
erjo@1850 473 }
erjo@1850 474 }
erjo@1850 475 }
erjo@1850 476
erjo@1850 477 open(CONF, ">$confdir/$driver_name/$filename") or
erjo@1850 478 die "couldn't create file $confdir/$driver_name/$filename: $!";
erjo@1850 479
erjo@1850 480 printf CONF "sys_files|";
erjo@1850 481 foreach my $file (@copyfiles) {
erjo@1950 482 parse_copy_file($file);
erjo@1850 483 }
erjo@1850 484 printf CONF "\n";
erjo@1850 485
erjo@1850 486 my $version = get_section_value("Version", "DriverVer");
erjo@1850 487 my $provider = get_section_value("Version", "Provider");
erjo@1850 488 my $classguid = get_section_value("Version", "ClassGUID");
erjo@1850 489 my $providerstring = trim(strip_quotes(get_string_value(trim($provider))));
erjo@1850 490 $classguid =~ s/^\s*{//;
erjo@1850 491 $classguid =~ s/}\s*$//;
erjo@1850 492
erjo@1850 493 printf CONF "NdisVersion|0x50001\n";
erjo@1850 494 printf CONF "Environment|1\n";
erjo@1850 495 printf CONF "class_guid|%s\n", $classguid;
erjo@1850 496 printf CONF "driver_version|%s,%s\n", $providerstring, $version;
erjo@1850 497 printf CONF "BusType|%s\n", $bus_type;
erjo@1850 498 printf CONF "SlotNumber|01\n";
erjo@1850 499 printf CONF "NetCfgInstanceId|{28022A01-1234-5678-ABCDE-123813291A00}\n";
erjo@1850 500 printf CONF "\n";
erjo@1850 501 close(CONF);
erjo@1850 502
erjo@1850 503 open(CONF, "|sort|uniq >>$confdir/$driver_name/$filename") or
erjo@1850 504 die "couldn't create file $confdir/$driver_name/$filename: $!";
erjo@1850 505
erjo@1850 506 foreach my $reg (@addregs) {
erjo@1950 507 parse_registry($reg);
erjo@1850 508 }
erjo@1850 509 close(CONF);
erjo@1850 510 }
erjo@1850 511
erjo@1850 512 sub parse_registry {
erjo@1850 513 my ($reg, $conf) = @_;
erjo@1850 514 my $lines = get_section($reg);
erjo@1850 515 if (!$lines) {
erjo@1850 516 warn "couldn't find section \"$reg\" -\n" .
erjo@1850 517 "installation may be incomplete\n";
erjo@1850 518 return -1;
erjo@1850 519 }
erjo@1850 520
erjo@1850 521 my $driver_desc = 0;
erjo@1850 522 foreach my $line (@{$lines}) {
erjo@1850 523 $line = del_comment($line);
erjo@1850 524 my @fields = split(",", $line);
erjo@1850 525 next if (@fields lt 4);
erjo@1850 526 my $value;
erjo@1850 527 my $param = trim($fields[1]);
erjo@1850 528 if ($param =~ /^ndi\\/i) {
erjo@1850 529 if ($param =~ /^ndi\\params\\(.+)/i) {
erjo@1850 530 $param = strip_quotes(trim($1));
erjo@1850 531 $param =~ s/\\.*$//;
erjo@1850 532 next if (lc(trim($fields[2])) ne "default");
erjo@1850 533 $value = strip_quotes(trim($fields[4]));
erjo@1850 534 } else {
erjo@1850 535 printf DBG "ignoring parameter $line\n";
erjo@1850 536 next;
erjo@1850 537 }
erjo@1850 538 } else {
erjo@1850 539 $param = strip_quotes(trim($fields[2]));
erjo@1850 540 next if (length($param) eq 0);
erjo@1850 541 $value = strip_quotes(trim($fields[4]));
erjo@1850 542 }
erjo@1850 543 $value = get_string_value($value);
erjo@1850 544 if (length($param) gt 0) {
erjo@1850 545 if ($param_fixlist{"$param|$value"}) {
erjo@1850 546 my $orig_value = $value;
erjo@1850 547 $value = $param_fixlist{"$param|$value"};
erjo@1850 548 printf "forcing parameter $param from $orig_value to $value\n";
erjo@1850 549 }
erjo@1850 550 printf CONF "%s|%s\n", $param, $value;
erjo@1850 551 if ($param =~ /^DriverDesc$/) {
erjo@1850 552 $driver_desc = 1;
erjo@1850 553 }
erjo@1850 554 }
erjo@1850 555 }
erjo@1850 556 if ($driver_desc == 0) {
erjo@1850 557 printf CONF "DriverDesc|NDIS Network Adapter\n";
erjo@1850 558 }
erjo@1850 559 }
erjo@1850 560
erjo@1850 561 sub parse_copy_file {
erjo@1850 562 my $copy_name = shift;
erjo@1850 563
erjo@1850 564 if ($copy_name =~ /^\@/) {
erjo@1850 565 $copy_name =~ s/^\@//;
erjo@1850 566 $copy_name = trim($copy_name);
erjo@1850 567 if (valid_copy_file_name($copy_name)) {
erjo@1850 568 return copy_file($copy_name, $copy_name);
erjo@1850 569 }
erjo@1850 570 }
erjo@1850 571
erjo@1850 572 my $lines = get_section($copy_name);
erjo@1850 573 if (!$lines) {
erjo@1850 574 warn "couldn't find section \"$copy_name\" -\n" .
erjo@1850 575 "installation may be incomplete\n";
erjo@1850 576 return -1;
erjo@1850 577 }
erjo@1850 578 foreach my $line (@{$lines}) {
erjo@1850 579 $line = trim($line);
erjo@1850 580
erjo@1850 581 # some inf files have file names commented out; get file names from them
erjo@1850 582 $line =~ s/^\s*;//;
erjo@1850 583 my @files = split(",", $line);
erjo@1850 584 if (@files == 0) {
erjo@1850 585 printf DBG "copyfiles section $copy_name has no files\n";
erjo@1850 586 return -1;
erjo@1850 587 }
erjo@1850 588 my $src, my $dst;
erjo@1850 589 if (@files > 1 and length(trim($files[1])) > 0) {
erjo@1850 590 $src = $files[1];
erjo@1850 591 if (length(trim($files[0])) > 0) {
erjo@1850 592 $dst = $files[0];
erjo@1850 593 } else {
erjo@1850 594 $dst = $src;
erjo@1850 595 }
erjo@1850 596 } else {
erjo@1850 597 $src = $files[0];
erjo@1850 598 $dst = $src;
erjo@1850 599 }
erjo@1850 600 $src =~ s/^.*\\//;
erjo@1850 601 $dst =~ s/^.*\\//;
erjo@1850 602 printf DBG "src: '%s', dst: '%s'\n", $src, $dst;
erjo@1850 603 $src = trim(del_comment($src));
erjo@1850 604 next if (length($src) eq 0);
erjo@1850 605 if (valid_copy_file_name($src)) {
erjo@1850 606 $dst = trim(del_comment($dst));
erjo@1850 607 printf DBG "src: '%s', dst: '%s'\n", $src, $dst;
erjo@1850 608 copy_file($src, $dst);
erjo@1850 609 } else {
erjo@1850 610 printf DBG "invalid file '%s' ignored\n", $src;
erjo@1850 611 }
erjo@1850 612 }
erjo@1850 613 return 0;
erjo@1850 614 }
erjo@1850 615
erjo@1850 616 sub parse_hwid {
erjo@1850 617 my $hwid = uc(shift);
erjo@1850 618 if ($hwid =~ /(PCI\\)?VEN_(\w+)&DEV_(\w+)&SUBSYS_(\w{4})(\S{4})/) {
erjo@1850 619 return ($WRAP_PCI_BUS, $2, $3, $4, $5);
erjo@1850 620 } elsif ($hwid =~ /(PCI\\)?VEN_(\w+)&DEV_(\w+)/) {
erjo@1850 621 return ($WRAP_PCI_BUS, $2, $3, 0, 0);
erjo@1850 622 } elsif ($hwid =~ /(USB\\)?VID_(\w+)&PID_(\w+)/) {
erjo@1850 623 return ($WRAP_USB_BUS, $2, $3, 0, 0);
erjo@1850 624 } else {
erjo@1850 625 return 0;
erjo@1850 626 }
erjo@1850 627 }
erjo@1850 628
erjo@1850 629 sub parse_key_value {
erjo@1850 630 my $line = shift;
erjo@1850 631
erjo@1850 632 $line = del_comment($line);
erjo@1850 633 if ($line =~ /([^=]+)=(.+)/) {
erjo@1850 634 return (trim($1), trim($2));
erjo@1850 635 } else {
erjo@1850 636 return 0;
erjo@1850 637 }
erjo@1850 638 }
erjo@1850 639
erjo@1850 640 sub choose_target_os {
erjo@1850 641 my @targets = @_;
erjo@1850 642 my $arch = `uname -m`;
erjo@1850 643 chomp($arch);
erjo@1850 644 printf DBG "arch: %s\n", $arch;
erjo@1850 645 if ($arch =~ /64$/) {
erjo@1850 646 $arch = "amd64";
erjo@1850 647 } else {
erjo@1850 648 $arch = "x86";
erjo@1850 649 }
erjo@1850 650 printf DBG "arch: %s\n", $arch;
erjo@1850 651 my @prefs = ("NT($arch)\.5\.1", "NT($arch)\.5", "NT($arch)",
erjo@1850 652 "NT\.5\.1", "NT\.5", "NT");
erjo@1850 653 foreach my $pref (@prefs) {
erjo@1850 654 foreach my $target (@targets) {
erjo@1850 655 $target = trim($target);
erjo@1850 656 printf DBG "target: '%s', pref: '%s'\n", $target, $pref;
erjo@1850 657 if ($target =~ /NT((amd64)|(x86))/i) {
erjo@1850 658 printf DBG "target arch: '%s'\n", $1;
erjo@1850 659 next if ($1 !~ /$arch/i);
erjo@1850 660 }
erjo@1850 661 if ($target =~ /$pref/i) {
erjo@1850 662 return $target;
erjo@1850 663 }
erjo@1850 664 }
erjo@1850 665 }
erjo@1850 666 return "";
erjo@1850 667 }
erjo@1850 668
erjo@1850 669 sub get_target_os_section {
erjo@1850 670 my ($section, $target) = @_;
erjo@1850 671 my $lines;
erjo@1850 672
erjo@1850 673 chomp($section);
erjo@1850 674 $section =~ s/^\s*"\s*//;
erjo@1850 675 $section =~ s/\s*"\s*$//;
erjo@1850 676 printf DBG "section: \"%s\", target: \"%s\"\n", $section, $target;
erjo@1850 677
erjo@1850 678 if (length($target) gt 0) {
erjo@1850 679 $lines = get_section($section . "." . $target);
erjo@1850 680 return $lines if ($lines);
erjo@1850 681 }
erjo@1850 682
erjo@1850 683 my $arch = `uname -m`;
erjo@1850 684 chomp($arch);
erjo@1850 685 printf DBG "arch: %s\n", $arch;
erjo@1850 686 if ($arch =~ /64$/) {
erjo@1850 687 $arch = "AMD64";
erjo@1850 688 } else {
erjo@1850 689 $arch = "X86";
erjo@1850 690 }
erjo@1850 691 printf DBG "arch: %s\n", $arch;
erjo@1850 692
erjo@1850 693 my @prefs = ("NT$arch.5.1", "NT$arch.5", "NT$arch",
erjo@1850 694 "NT.5.1", "NT.5", "NT");
erjo@1850 695 foreach my $pref (@prefs) {
erjo@1850 696 $lines = get_section($section . "." . $pref);
erjo@1850 697 return $lines if ($lines);
erjo@1850 698 }
erjo@1850 699 $lines = get_section($section);
erjo@1850 700 return $lines if ($lines);
erjo@1850 701
erjo@1850 702 printf DBG "couldn't find section \"$section\" for \"$arch\"\n";
erjo@1850 703 return 0;
erjo@1850 704 }
erjo@1850 705
erjo@1850 706 sub get_section_value {
erjo@1850 707 (my $section, my $name) = @_;
erjo@1850 708 return $parsed_sections{$section}->{$name};
erjo@1850 709 }
erjo@1850 710
erjo@1850 711 sub get_string_value {
erjo@1850 712 my $key = shift;
erjo@1850 713 if ($key =~ /%(.+)%/) {
erjo@1850 714 $key = $1;
erjo@1850 715 return get_section_value("Strings", $key);
erjo@1850 716 } else {
erjo@1850 717 return $key;
erjo@1850 718 }
erjo@1850 719 }
erjo@1850 720
erjo@1850 721 sub copy_file {
erjo@1850 722 my ($src, $dst) = @_;
erjo@1850 723
erjo@1850 724 # ignore files not needed
erjo@1850 725 return 0 if (lc($src) =~ /\.((exe)|(dll)|(cpl)|(hlp))$/);
erjo@1850 726 my $real_file = get_file($src);
erjo@1850 727 if (length($real_file) gt 0) {
erjo@1850 728 $dst = lc($dst);
erjo@1850 729 printf DBG "copying \"$src_dir/$real_file\" to " .
erjo@1850 730 "\"$confdir/$driver_name/$dst\"\n";
erjo@1850 731 copy("$src_dir/$real_file", "$confdir/$driver_name/$dst") or
erjo@1850 732 warn "couldn't copy \"$src_dir/$real_file\" to " .
erjo@1850 733 "\"$confdir/$driver_name\": $! -\n" .
erjo@1850 734 "installation may be incomplete\n";
erjo@1850 735 printf DBG "chmod: $confdir/$driver_name/$dst\n";
erjo@1850 736 chmod(0644, "$confdir/$driver_name/$dst");
erjo@1850 737 if ($dst =~ /\.sys$/) {
erjo@1850 738 printf CONF "%s ", $dst;
erjo@1850 739 }
erjo@1850 740 } else {
erjo@1850 741 warn "couldn't find \"$src\" in \"$src_dir\"; make sure " .
erjo@1850 742 "all driver files, including .inf, .sys (and any firmware files) " .
erjo@1850 743 "are in \"$src_dir\" -\n" .
erjo@1850 744 "installation may be incomplete\n";
erjo@1850 745 }
erjo@1850 746 }
erjo@1850 747
erjo@1850 748
erjo@1850 749 # for conf files with subvendor and subdevice, create conf files with just
erjo@1850 750 # vendor and device
erjo@1850 751 sub create_fuzzy_conf {
erjo@1850 752 my $driver = shift;
erjo@1850 753 my $cwd = cwd();
erjo@1850 754 chdir("$confdir/$driver") or die "couldn't chdir to $confdir/$driver: $!";
erjo@1850 755 open(LS, "ls -1 . |") or die "couldn't open $confdir/$driver: $!";
erjo@1850 756 while (my $file = <LS>) {
erjo@1850 757 chomp($file);
erjo@1850 758 if ($file =~ /$re_sub_dev_conf/) {
erjo@1850 759 my $fuzzy_file = "$1:$2.$5.conf";
erjo@1850 760 printf DBG "file: $file, fuzzy file: $fuzzy_file\n";
erjo@1850 761 if (! -e "$confdir/$driver/$fuzzy_file") {
erjo@1850 762 symlink("$file", "$fuzzy_file") or
erjo@1850 763 warn "couldn't link $confdir/$driver/$file " .
erjo@1850 764 "to $confdir/$driver/$fuzzy_file: $!\n";
erjo@1850 765 }
erjo@1850 766 }
erjo@1850 767 }
erjo@1850 768 close(LS);
erjo@1850 769 chdir($cwd) or warn "couldn't chdir to $cwd: $!";
erjo@1850 770 return 0;
erjo@1850 771 }
erjo@1850 772
erjo@1850 773 # find a file in a case-insensitive way.
erjo@1850 774 sub get_file {
erjo@1850 775 my $file = lc(shift);
erjo@1850 776 if (opendir(DIR, "$src_dir")) {
erjo@1850 777 my @allfiles = readdir(DIR);
erjo@1850 778 foreach my $real_file (@allfiles) {
erjo@1850 779 if (lc($real_file) eq $file) {
erjo@1850 780 closedir(DIR);
erjo@1850 781 return $real_file;
erjo@1850 782 }
erjo@1850 783 }
erjo@1850 784 closedir(DIR);
erjo@1850 785 } else {
erjo@1850 786 warn "couldn't open \"$src_dir\": $! -\n" .
erjo@1850 787 "installation may be incomplete\n";
erjo@1850 788 }
erjo@1850 789 return "";
erjo@1850 790 }
erjo@1850 791
erjo@1850 792 sub strip_quotes {
erjo@1850 793 my $s = shift;
erjo@1850 794 $s =~ s/"(.*)"/$1/;
erjo@1850 795 return $s;
erjo@1850 796 }
erjo@1850 797
erjo@1850 798 sub del_comment {
erjo@1850 799 my $s = shift;
erjo@1850 800 $s =~ s/;.*//;
erjo@1850 801 return $s;
erjo@1850 802 }
erjo@1850 803
erjo@1850 804 # remove whitsepace at front and end.
erjo@1850 805 sub trim {
erjo@1850 806 my $s = shift;
erjo@1850 807 $s =~ s/^\s*//;
erjo@1850 808 $s =~ s/\s*$//;
erjo@1850 809 return $s;
erjo@1850 810 }
erjo@1850 811
erjo@1850 812 sub valid_copy_file_name {
erjo@1850 813 my $file = shift;
erjo@1850 814 $file = lc($file);
erjo@1850 815 printf DBG "file name: %s\n", $file;
erjo@1850 816 foreach my $disk_file (@source_disks_files) {
erjo@1850 817 return 1 if ($file eq $disk_file);
erjo@1850 818 }
erjo@1850 819 # some inf files may not have SourceDisksFiles section, so use
erjo@1850 820 # known file names
erjo@1850 821 return 1 if ($file =~ /\.((sys)|(bin)|(out))$/);
erjo@1850 822 return 0;
erjo@1850 823 }
erjo@1850 824
erjo@1850 825 sub parse_source_disks_files {
erjo@1850 826 my $lines = get_source_disks_files();
erjo@1850 827 if ($lines) {
erjo@1850 828 foreach my $line (@{$lines}) {
erjo@1850 829 $line = del_comment($line);
erjo@1850 830 next if (length($line) eq 0);
erjo@1850 831 my @file = split("=", $line);
erjo@1850 832 next if (@file eq 0 or length($file[0] eq 0));
erjo@1850 833 printf DBG "source disk file: \"%s\"\n", trim($file[0]);
erjo@1850 834 push (@source_disks_files, lc(trim($file[0])));
erjo@1850 835 }
erjo@1850 836 } else {
erjo@1850 837 warn "couldn't find SourceDisksFiles section - " .
erjo@1850 838 "continuing anyway...\n";
erjo@1850 839 }
erjo@1850 840 }
erjo@1850 841
erjo@1850 842 sub get_source_disks_files {
erjo@1850 843 my $arch = `uname -m`;
erjo@1850 844 chomp($arch);
erjo@1850 845 if ($arch =~ /64$/) {
erjo@1850 846 $arch = "AMD64";
erjo@1850 847 } else {
erjo@1850 848 $arch = "X86";
erjo@1850 849 }
erjo@1850 850
erjo@1850 851 my $lines = get_section("SourceDisksFiles." . $arch);
erjo@1850 852 return $lines if ($lines);
erjo@1850 853
erjo@1850 854 $lines = get_section("SourceDisksFiles");
erjo@1850 855 return $lines if ($lines);
erjo@1850 856
erjo@1850 857 return 0;
erjo@1850 858 }
erjo@1850 859
erjo@1850 860 sub device_driver_alias {
erjo@1850 861 my ($devid, $driver) = @_;
erjo@1850 862 my $done = 0;
erjo@1850 863
erjo@1850 864 $devid = uc($devid);
erjo@1850 865 if (!($devid =~ /^$re_dev_id:$re_dev_id$/)) {
erjo@1850 866 printf "'$devid' is not a valid device ID\n";
erjo@1850 867 return 1;
erjo@1850 868 }
erjo@1850 869 open(LS, "ls -1 $confdir/$driver/ |") or
erjo@1850 870 die "couldn't open $confdir/$driver: $!";
erjo@1850 871
erjo@1850 872 while (my $f = <LS>) {
erjo@1850 873 chomp($f);
erjo@1850 874 if ($f =~ /\.([[:xdigit:]]+)\.conf$/) {
erjo@1850 875 if (stat("$confdir/$driver/$devid.$1.conf")) {
erjo@1850 876 printf "Driver '$driver' is already used for '$devid'\n";
erjo@1850 877 $done = 1;
erjo@1850 878 last;
erjo@1850 879 }
erjo@1850 880 if (symlink("$f", "$confdir/$driver/$devid.$1.conf")) {
erjo@1850 881 printf "WARNING: Driver '$driver' will be used for '$devid'\n" .
erjo@1850 882 "This is safe _only_ if driver $driver is meant for " .
erjo@1850 883 "chip in device $devid\n";
erjo@1850 884 $done = 1;
erjo@1850 885 last;
erjo@1850 886 } else {
erjo@1850 887 warn "couldn't create symlink for \"$f\": $! -\n" .
erjo@1850 888 "installation may be incomplete\n";
erjo@1850 889 }
erjo@1850 890 }
erjo@1850 891 }
erjo@1850 892 close(LS);
erjo@1850 893 if ($done == 0) {
erjo@1850 894 printf "driver '$driver' is not installed (properly)!\n";
erjo@1850 895 return 1;
erjo@1850 896 }
erjo@1850 897 return 0;
erjo@1850 898 }
erjo@1850 899
erjo@1850 900 sub list_drivers {
erjo@1850 901 my $cards = get_cards();
erjo@1850 902 open(LS, "/bin/ls -1 $confdir|") or die "couldn't open $confdir: $!";
erjo@1850 903 while (my $driver = <LS>) {
erjo@1910 904 chomp($driver);
erjo@1910 905 if (-e "$confdir/$driver") {
erjo@1910 906 printf "%s : %s\n", $driver, install_status($cards, $driver);
erjo@1910 907 }
erjo@1850 908 }
erjo@1850 909 close(LS);
erjo@1850 910 return 0;
erjo@1850 911 }
erjo@1850 912
erjo@1850 913
erjo@1850 914 sub get_cards {
erjo@1850 915 #01:00.0 Class 0300: 1002:4c66 (rev 01)
erjo@1850 916 # Subsystem: 1043:1732
erjo@1850 917 my @cards = ();
erjo@1850 918 if (open(LSPCI, "/usr/bin/lspci -vn|")) {
erjo@1850 919 my $card;
erjo@1850 920 while (my $line = <LSPCI>) {
erjo@1850 921 if ($line =~ /^[0-9a-f]+.+\s$re_dev_id:$re_dev_id/) {
erjo@1850 922 $card = {vendor => uc($1), device => uc($2)};
erjo@1850 923 printf DBG "card: %s, %s\n", $1, $2;
erjo@1850 924 } elsif ($line =~ /.+Subsystem:\s$re_dev_id:$re_dev_id/) {
erjo@1850 925 $card->{subvendor} = uc($1);
erjo@1850 926 $card->{subdevice} = uc($2);
erjo@1850 927 printf DBG "sub: %s, %s\n", $1, $2;
erjo@1850 928 push(@cards, $card);
erjo@1850 929 }
erjo@1850 930 }
erjo@1850 931 close(LSPCI);
erjo@1850 932 }
erjo@1850 933
erjo@1850 934 if (open(LSUSB, "lsusb |")) {
erjo@1850 935 my $card;
erjo@1850 936 while (my $line = <LSUSB>) {
erjo@1850 937 if ($line =~ /.+: ID\s$re_dev_id:$re_dev_id/) {
erjo@1850 938 $card = {vendor => uc($1), device => uc($2)};
erjo@1850 939 push(@cards, $card);
erjo@1850 940 }
erjo@1850 941 }
erjo@1850 942 close(LSUSB);
erjo@1850 943 }
erjo@1850 944 return \@cards;
erjo@1850 945 }
erjo@1850 946
erjo@1850 947 sub install_status {
erjo@1850 948 my ($cards, $driver) = @_;
erjo@1850 949
erjo@1850 950 if (!$cards or !$driver) {
erjo@1850 951 return;
erjo@1850 952 }
erjo@1850 953
erjo@1850 954 my ($sys, $conf, $inf);
erjo@1850 955 my ($vendor, $device, $subvendor, $subdevice, $busid, $ret);
erjo@1850 956
erjo@1850 957 $sys = $conf = $inf = 0;
erjo@1850 958 open(LS2, "/bin/ls -1 $confdir/$driver|") or
erjo@1850 959 die "couldn't open $confdir/$driver: $!";
erjo@1850 960 while (my $file = <LS2>) {
erjo@1850 961 chomp($file);
erjo@1850 962 if ($file =~ /\.sys$/) {
erjo@1850 963 $sys = 1;
erjo@1850 964 } elsif ($file =~ /\.inf$/) {
erjo@1850 965 $inf = 1;
erjo@1850 966 } elsif ($file =~ /^$re_sub_dev_conf$/) {
erjo@1850 967 $busid = hex($5);
erjo@1850 968 $conf = 1 if ($busid eq $WRAP_PCI_BUS);
erjo@1850 969 } elsif ($file =~ /^$re_dev_conf$/) {
erjo@1850 970 $busid = hex($3);
erjo@1850 971 $conf = 1 if ($busid eq $WRAP_USB_BUS or $busid eq 0 or
erjo@1850 972 $busid eq $WRAP_PCI_BUS);
erjo@1850 973 }
erjo@1850 974 }
erjo@1850 975 close(LS2);
erjo@1850 976 printf DBG "status: $sys, $inf, $conf\n";
erjo@1850 977 if ($sys eq 0 or $inf eq 0 or $conf eq 0) {
erjo@1850 978 $ret = "invalid driver!";
erjo@1850 979 return $ret;
erjo@1850 980 }
erjo@1850 981 $ret = "driver installed";
erjo@1850 982 open(LS2, "/bin/ls -1 $confdir/$driver|") or
erjo@1850 983 die "couldn't open $confdir/$driver: $!";
erjo@1850 984
erjo@1850 985 while (my $file = <LS2>) {
erjo@1850 986 chomp($file);
erjo@1850 987 next if ($file !~ /\.conf$/);
erjo@1850 988 $conf = 0;
erjo@1850 989 if ($file =~ /^$re_sub_dev_conf$/) {
erjo@1850 990 ($vendor, $device, $subvendor, $subdevice, $busid) =
erjo@1850 991 (uc($1), uc($2), uc($3), uc($4), hex($5));
erjo@1850 992 $conf = 1;
erjo@1850 993 foreach my $card (@{$cards}) {
erjo@1850 994 if ($card->{vendor} eq $vendor and
erjo@1850 995 $card->{device} eq $device and
erjo@1850 996 $card->{subvendor} eq $subvendor and
erjo@1850 997 $card->{subdevice} eq $subdevice and
erjo@1850 998 $busid eq $WRAP_PCI_BUS) {
erjo@2293 999 $ret .= " : device ($vendor:$device" .
erjo@1850 1000 ":$subvendor:$subdevice) present";
erjo@1850 1001 $conf = 2;
erjo@1850 1002 last;
erjo@1850 1003 }
erjo@1850 1004 }
erjo@1850 1005 } elsif ($file =~ /^$re_dev_conf/) {
erjo@1850 1006 ($vendor, $device, $subvendor, $subdevice, $busid) =
erjo@1850 1007 (uc($1), uc($2), "\\*", "\\*", hex($3));
erjo@1850 1008 $conf = 1;
erjo@1850 1009 foreach my $card (@{$cards}) {
erjo@1850 1010 if ($card->{vendor} eq $vendor and
erjo@1850 1011 $card->{device} eq $device and
erjo@1850 1012 ($busid eq $WRAP_USB_BUS or $busid eq 0 or
erjo@1850 1013 $busid eq $WRAP_PCI_BUS)) {
erjo@2293 1014 $ret .= " : device ($vendor:$device) present";
erjo@1850 1015 $conf = 2;
erjo@1850 1016 last;
erjo@1850 1017 }
erjo@1850 1018 }
erjo@1850 1019 }
erjo@1850 1020 next if ($conf le 1);
erjo@1850 1021 # find if kernel knows of an alternate driver for this device
erjo@1850 1022 my $devstring;
erjo@1850 1023 if ($busid eq $WRAP_USB_BUS or $busid eq 0) {
erjo@1850 1024 $devstring = sprintf("usb:v%sp%sd", $vendor, $device);
erjo@1850 1025 } elsif ($busid eq $WRAP_PCI_BUS) {
erjo@1850 1026 $devstring = sprintf("pci:v0000%sd0000%ssv", $vendor, $device);
erjo@1850 1027 } else {
erjo@1850 1028 next;
erjo@1850 1029 }
erjo@1850 1030 open(MODPROBE, "modprobe -c|") or next;
erjo@1850 1031 while (my $line = <MODPROBE>) {
erjo@1850 1032 my $alt;
erjo@1850 1033 chomp($line);
erjo@1850 1034 next if $line !~ /$devstring/;
erjo@1850 1035 $alt = (split(' ', $line))[-1];
erjo@1850 1036 chomp($alt);
erjo@1850 1037 if (length($alt) gt 0 and $alt ne "ndiswrapper") {
erjo@1850 1038 $ret .= " (alternate driver: $alt)";
erjo@1850 1039 last;
erjo@1850 1040 }
erjo@1850 1041 }
erjo@1850 1042 close(MODPROBE);
erjo@1850 1043 }
erjo@1850 1044 close(LS2);
erjo@1850 1045 printf DBG "driver: $driver, $ret\n";
erjo@1850 1046 return $ret;
erjo@1850 1047 }
erjo@1850 1048
erjo@1850 1049 ## Local Variables: ##
erjo@1850 1050 ## cperl-indent-level: 4 ##
erjo@1850 1051 ## End: ##