1 |
#!/usr/bin/perl |
2 |
|
3 |
# Copyright (C) 2005 Mandriva |
4 |
# Olivier Blin |
5 |
# |
6 |
# This program is free software; you can redistribute it and/or modify |
7 |
# it under the terms of the GNU General Public License as published by |
8 |
# the Free Software Foundation; either version 2, or (at your option) |
9 |
# any later version. |
10 |
# |
11 |
# This program is distributed in the hope that it will be useful, |
12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 |
# GNU General Public License for more details. |
15 |
# |
16 |
# You should have received a copy of the GNU General Public License |
17 |
# along with this program; if not, write to the Free Software |
18 |
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
19 |
|
20 |
@ARGV > 1 or die "usage: $0 [--no-modprobe] [--no-driver-agent] subsystem /path/to/map1.usermap [/path/to/map2.usermap]"; |
21 |
|
22 |
my $agents_dir = '/etc/udev/agents.d'; |
23 |
|
24 |
my %flags = ( |
25 |
idVendor => 0x0001, |
26 |
idProduct => 0x0002, |
27 |
bcdDevice_lo => 0x0004, |
28 |
bcdDevice_hi => 0x0008, |
29 |
bDeviceClass => 0x0010, |
30 |
bDeviceSubClass => 0x0020, |
31 |
bDeviceProtocol => 0x0040, |
32 |
bInterfaceClass => 0x0080, |
33 |
bInterfaceSubClass => 0x0100, |
34 |
bInterfaceProtocol => 0x0200, |
35 |
); |
36 |
|
37 |
my ($no_modprobe, $no_driver_agent); |
38 |
|
39 |
@ARGV = grep { |
40 |
if ($_ eq "--no-modprobe") { |
41 |
$no_modprobe = 1; |
42 |
0; |
43 |
} elsif ($_ eq "--no-driver-agent") { |
44 |
$no_driver_agent = 1; |
45 |
0; |
46 |
} else { |
47 |
1; |
48 |
} |
49 |
} @ARGV; |
50 |
|
51 |
my $subsystem = shift @ARGV; |
52 |
|
53 |
sub parse_usermap_line { |
54 |
local $_ = shift; |
55 |
/^#/ and next; |
56 |
my %match; |
57 |
@match{module, match_flags, idVendor, idProduct, bcdDevice_lo, bcdDevice_hi, bDeviceClass, bDeviceSubClass, bDeviceProtocol, bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol, driver_info} = |
58 |
/^(\S+)\s+0x(\w{2,})\s+0x(\w{2,})\s+0x(\w{2,})\s+0x(\w{2,})\s+0x(\w{2,})\s+0x(\w{2})\s+0x(\w{2})\s+0x(\w{2})\s+0x(\w{2})\s+0x(\w{2})\s+0x(\w{2})(?:\s+0x(\w{2,}))?/ |
59 |
or die qq(unable to parse line "$_"); |
60 |
$match{driver_info} ||= 0; |
61 |
|
62 |
my @rule = qq(SUBSYSTEM=="$subsystem"); |
63 |
while (my ($key, $flag) = each(%flags)) { |
64 |
hex($match{match_flags}) & $flag and push @rule, qq(ATTR{$key}=="$match{$key}"); |
65 |
} |
66 |
push @rule, qq(RUN+="/sbin/modprobe $match{module}") unless $no_modprobe; |
67 |
push @rule, qq(RUN+="$agents_dir/$subsystem/$match{module}") unless $no_driver_agent; |
68 |
print join(', ', @rule) . "\n"; |
69 |
} |
70 |
|
71 |
foreach my $usermap (@ARGV) { |
72 |
open(my $IN, $usermap . (-x $usermap && "|")) or die "unable to open usermap $usermap"; |
73 |
parse_usermap_line($_) foreach <$IN>; |
74 |
} |