home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-2 / Inter.Net 55-2.iso / Mandrake / mdkinst / usr / bin / perl-install / detect_devices.pm < prev    next >
Encoding:
Perl POD Document  |  2000-01-12  |  5.2 KB  |  240 lines

  1. package detect_devices;
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9. use log;
  10. use common qw(:common :file);
  11. use devices;
  12. use c;
  13.  
  14.  
  15.  
  16.  
  17. my @netdevices = map { my $l = $_; map { "$l$_" } (0..3) } qw(eth tr plip fddi);
  18.  
  19.  
  20.  
  21.  
  22. sub get {
  23.     
  24.     
  25.     
  26.     
  27.     
  28.     
  29.  
  30.     map { &{$_->[0]}() ? &{$_->[1]}() : () }
  31.     [ \&hasIDE, \&getIDE ],
  32.     [ \&hasSCSI, \&getSCSI ],
  33.     [ \&hasDAC960, \&getDAC960 ],
  34.     [ \&hasCompaqSmartArray, \&getCompaqSmartArray ];
  35. }
  36. sub hds() { grep { $_->{type} eq 'hd' && ($::isStandalone || !isRemovableDrive($_)) } get(); }
  37. sub zips() { grep { $_->{type} eq 'hd' && isZipDrive($_) } get(); }
  38.  
  39. sub cdroms() { grep { $_->{type} eq 'cdrom' } get(); }
  40. sub floppies() {
  41.     (grep { tryOpen($_) } qw(fd0 fd1)),
  42.     (grep { $_->{type} eq 'fd' } get());
  43. }
  44.  
  45. sub isZipDrive() { $_[0]->{info} =~ /ZIP\s+\d+/ } 
  46.  
  47. sub isRemovableDrive() { &isZipDrive } 
  48.  
  49. sub hasSCSI() {
  50.     local *F;
  51.     open F, "/proc/scsi/scsi" or log::l("failed to open /proc/scsi/scsi: $!"), return 0;
  52.     foreach (<F>) {
  53.     /devices: none/ and log::l("no scsi devices are available"), return 0;
  54.     }
  55.     log::l("scsi devices are available");
  56.     1;
  57. }
  58. sub hasIDE() { -e "/proc/ide" }
  59. sub hasDAC960() { 1 }
  60. sub hasCompaqSmartArray() { -r "/proc/array/ida0" }
  61.  
  62. sub getSCSI() {
  63.     my @drives;
  64.     my ($driveNum, $cdromNum, $tapeNum) = qw(0 0 0);
  65.     my $err = sub { chop; die "unexpected line in /proc/scsi/scsi: $_"; };
  66.     local $_;
  67.  
  68.     local *F;
  69.     open F, "/proc/scsi/scsi" or die "failed to open /proc/scsi/scsi";
  70.     local $_ = <F>; /^Attached devices:/ or return &$err();
  71.     while ($_ = <F>) {
  72.     my ($id) = /^Host:.*?Id: (\d+)/ or return &$err();
  73.     $_ = <F>; my ($vendor, $model) = /^\s*Vendor:\s*(.*?)\s+Model:\s*(.*?)\s+Rev:/ or return &$err();
  74.     $_ = <F>; my ($type) = /^\s*Type:\s*(.*)/ or &$err();
  75.     my $device;
  76.     if ($type =~ /Direct-Access/) {
  77.         $type = 'hd';
  78.         $device = "sd" . chr($driveNum++ + ord('a'));
  79.     } elsif ($type =~ /Sequential-Access/) {
  80.         $type = 'tape';
  81.         $device = "st" . $tapeNum++;
  82.     } elsif ($type =~ /CD-ROM/) {
  83.         $type = 'cdrom';
  84.         $device = "scd" . $cdromNum++;
  85.     }
  86.     $device and push @drives, { device => $device, type => $type, info => "$vendor $model", id => $id, bus => 0 };
  87.     }
  88.     @drives;
  89. }
  90.  
  91. sub getIDE() {
  92.     my @idi;
  93.  
  94.     
  95.     foreach my $d (sort @{[glob_('/proc/ide/hd*')]}) {
  96.     my ($t) = chop_(cat_("$d/media"));
  97.     my $type = $ {{disk => 'hd', cdrom => 'cdrom', tape => 'tape', floppy => 'fd'}}{$t} or next;
  98.     my ($info) = chop_(cat_("$d/model")); $info ||= "(none)";
  99.  
  100.     my $num = ord (($d =~ /(.)$/)[0]) - ord 'a';
  101.     push @idi, { type => $type, device => basename($d), info => $info, bus => $num/2, id => $num%2 };
  102.     }
  103.     
  104.     @idi;
  105. }
  106.  
  107.  
  108. sub getIDEBurners() { uniq map { m!ATAPI.* CD(-R|/RW){1,2} ! ? /(\w+)/ : () } syslog() }
  109.  
  110. sub getCompaqSmartArray() {
  111.     my @idi;
  112.     my $f;
  113.  
  114.     for (my $i = 0; -r ($f = "/proc/array/ida$i"); $i++) {
  115.     foreach (cat_($f)) {
  116.         if (m|^(ida/.*?):|) {
  117.         push @idi, { device => $1, info => "Compaq RAID logical disk", type => 'hd' };
  118.         last;
  119.         }
  120.     }
  121.     }
  122.     @idi;
  123. }
  124.  
  125. sub getDAC960() {
  126.     my @idi;
  127.  
  128.     
  129.     
  130.     foreach (syslog()) {
  131.     my ($devicename, $info) = m|/dev/rd/(.*?): (.*?),| or next;
  132.     push @idi, { info => $info, type => 'hd', devicename => $devicename };
  133.     log::l("DAC960: $devicename: $info");
  134.     }
  135.     @idi;
  136. }
  137.  
  138. sub net2module() {
  139.     my @modules = map { quotemeta first(split) } cat_("/proc/modules");
  140.     my $modules = join '|', @modules;
  141.     my $net     = join '|', @netdevices;
  142.     my ($module, %l);
  143.     foreach (syslog()) {
  144.     if (/^($modules)\.c:/) {
  145.         $module = $1;
  146.     } elsif (/^($net):/) {
  147.         $l{$1} = $module if $module;
  148.     }
  149.     }
  150.     %l;
  151. }
  152.  
  153. sub getNet() {
  154.     grep { hasNetDevice($_) } @netdevices;
  155. }
  156. sub getPlip() {
  157.     foreach (0..2) {
  158.     hasNetDevice("plip$_") and log::l("plip$_ will be used for PLIP"), return "plip$_";
  159.     }
  160.     undef;
  161. }
  162.  
  163. sub hasNet() { goto &getNet }
  164. sub hasPlip() { goto &getPlip }
  165. sub hasEthernet() { hasNetDevice("eth0"); }
  166. sub hasTokenRing() { hasNetDevice("tr0"); }
  167. sub hasNetDevice($) { c::hasNetDevice($_[0]) }
  168.  
  169. sub tryOpen($) {
  170.     local *F;
  171.     sysopen F, devices::make($_[0]), c::O_NONBLOCK() and *F;
  172. }
  173.  
  174. sub tryWrite($) {
  175.     local *F;
  176.     sysopen F, devices::make($_[0]), 1 | c::O_NONBLOCK() and *F;
  177. }
  178.  
  179. sub syslog {
  180.     -r "/tmp/syslog" and return map { /<\d+>(.*)/ } cat_("/tmp/syslog");
  181.     `dmesg`;
  182. }
  183.  
  184. sub hasSMP { c::detectSMP() }
  185.  
  186. sub whatParport() {
  187.     my @res =();
  188.     foreach (0..3) {
  189.     local *F;
  190.     my $elem = {};
  191.     open F, "/proc/parport/$_/autoprobe" or next;
  192.     foreach (<F>) { $elem->{$1} = $2 if /(.*):(.*);/ }
  193.     push @res, { port => "/dev/lp$_", val => $elem};
  194.     }
  195.     @res;
  196. }
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203. sub whatPrinter() {
  204.     my @res = whatParport();
  205.     grep { $_->{val}{CLASS} eq "PRINTER"} @res;
  206. }
  207.  
  208. sub whatPrinterPort() {
  209.     grep { tryWrite($_)} qw(/dev/lp0 /dev/lp1 /dev/lp2);
  210. }
  211.  
  212. sub probe_device($) {
  213.     my $device = devices::make($_[0]);
  214.     my %probe;
  215.  
  216.     
  217.     local *F;
  218.     open F, "pnp_serial $device 2>/dev/null |" if $device =~ /ttyS/;
  219.  
  220.     foreach (<F>) { $probe{$1} = $2 if /^\s+(.*?)\s*:\s*\"(.*)\"\s*$/ }
  221.     log::l("probing $device find class: $probe{CLASS}");
  222.  
  223.     \%probe;
  224. }
  225.  
  226. sub hasModem($) {
  227.     my $probe = probe_device($_[0]);
  228.     $probe->{CLASS} =~ /MODEM/i && $probe->{DESCRIPTION};
  229. }
  230.  
  231. sub hasMousePS2() {
  232.     my $t; sysread(tryOpen("psaux") || return, $t, 256) != 1 || $t ne "\xFE";
  233. }
  234.  
  235.  
  236.  
  237.  
  238. 1; #
  239.  
  240.