File modeswitch.conf2udevrules.pl of Package usb_modeswitch
#!/usr/bin/perl -w
#
# This script creates udev rules from a usb_modeswitch.conf file. call with
# ./modeswitch.conf2udevrules.pl usb_modeswitch.conf > udev.rules, then double
# check the generated udev rules!
#
# you can add the devices which should be ignored (probably because they are
# handled by a different program) to @ignore, devices that need special udev
# rules can be added to print_custom().
#
# (C) 2009 Novell, Inc. Author: Stefan Seyfried, seife@suse.de
#
# This program is released under the GPL v2 or, at your option, any later version.
@ignore = ( # [ vendor, product ], set product to 0 to blacklist a whole vendor.
[ 0x05c6, 0x1000 ], # lots of devices have this ID, all with different parameters :(
[ 0x0af0, 0x6711 ], # those are all option devices handled by "ozerocdoff"
[ 0x0af0, 0x6731 ], # maybe we should just blacklist all option devices?
[ 0x0af0, 0x6751 ],
[ 0x0af0, 0x6771 ],
[ 0x0af0, 0x6791 ],
[ 0x0af0, 0x6811 ],
[ 0x0af0, 0x6911 ],
[ 0x0af0, 0x6951 ],
[ 0x0af0, 0x6971 ],
[ 0x0af0, 0x7011 ],
[ 0x0af0, 0x7031 ],
[ 0x0af0, 0x7051 ],
[ 0x0af0, 0x7071 ],
[ 0x0af0, 0x7111 ],
[ 0x0af0, 0x7211 ],
[ 0x0af0, 0x7251 ],
[ 0x0af0, 0x7271 ],
[ 0x0af0, 0x7301 ],
[ 0x0af0, 0x7311 ],
[ 0x0af0, 0x7361 ],
[ 0x0af0, 0x7401 ],
[ 0x0af0, 0x7501 ],
[ 0x0af0, 0x7601 ],
[ 0x0af0, 0xc031 ],
[ 0x0af0, 0xd031 ],
[ 0x0af0, 0xd033 ],
[ 0x1199, 0x0000 ], # the sierra driver handles sierra devices by itself AFAIK
[ 0x1410, 0x5010 ], # novatel mc950d is handled in print_custom()
[ 0x19d2, 0x2000 ], # many different configs in the config file, cannot know which one to take
[ 0, 0 ] # terminate the array.
);
sub checkbl(@)
{
$v = hex("0x" . $_[0]);
$p = hex("0x" . $_[1]);
# printf(STDERR "checking 0x%04x:0x%04x\n", $v, $p);
for ($i = 0; $ignore[$i][0] != 0; $i++)
{
if ($ignore[$i][0] == $v) {
if (($ignore[$i][1] == 0) || # wildcard
($ignore[$i][1] == $p)) {
printf(STDERR "ignoring device %04x:%04x, bl entry %2d (%04x:%04x)\n",
$v, $p, $i, $ignore[$i][0], $ignore[$i][1]);
return 1;
}
}
}
return 0;
}
sub print_head()
{
print("ACTION!=\"add\", GOTO=\"usb_modeswitch_end\"\n");
print("\n");
print("# this udev rules file is autogenerated by modeswitch.conf2udevrules.pl\n");
print("# which can be found in the usb_modeswitch package\n");
print("\n");
}
sub print_foot()
{
print("\n");
print("LABEL=\"usb_modeswitch_end\"\n");
}
sub print_custom()
{
print("# devices that need custom rules\n");
# novatel mc950d, has two different entries in usb_modeswitch.conf, but works also with plain "eject"
print("SUBSYSTEM==\"block\", SYSFS{idProduct}==\"5010\", SYSFS{idVendor}==\"1410\", RUN=\"/bin/eject %k\"\n");
}
$count = 0;
$ignored = 0;
$failed = 0;
$flag = 0;
$dup = 0;
print_head;
while ($line = <>)
{
if ($line =~ m/^(#|$)/) {
next;
}
if ($line =~ m/^;*DefaultVendor=\s*0[Xx](.*?)[;\s]*$/) {
if ($flag) {
# a new record starts, but the old one is not finished.
print(STDERR "ignored entry (not all required fields): flag: $flag vendor: $vendor id: $product\n");
$failed++;
}
$flag = 1; # reset flag
$vendor = $1;
}
if (! $flag) {
next;
}
if ($line =~ m/^;*DefaultProduct=\s*0[Xx](.*?)[;\s]*$/) {
$product = $1;
$flag |= 2;
}
if ($line =~ m/^;*MessageEndpoint=\s*0[Xx](.*?)[;\s]*$/) {
$endpoint = $1;
$flag |= 4;
}
if ($line =~ m/^;*MessageContent=.*(".*")/) {
$message = $1;
$flag |= 8;
}
if ($flag == 0x0f) {
if (checkbl($vendor, $product)) {
$ignored++;
} elsif (defined($found{$vendor}{$product})) {
printf(STDERR "duplicate entry: %s:%s\n", $vendor, $product);
if (($found{$vendor}{$product}[0] ne $endpoint) ||
($found{$vendor}{$product}[1] ne $message)) {
printf(STDERR "input line: $.\n");
printf(STDERR "...with different endpoint or message. Aborting!\n");
printf(STDERR "old endpoint: '%s' old message: '%s'\n", $found{$vendor}{$product}[0], $found{$vendor}{$product}[1]);
printf(STDERR "new endpoint: '%s' new message: '%s'\n", $endpoint, $message);
exit 1;
}
$dup++;
} else {
printf("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%s\", ATTRS{idProduct}==\"%s\"," .
" RUN+=/usr/sbin/usb_modeswitch -v 0x%s -p 0x%s -m 0x%s -M %s\n",
$vendor, $product, $vendor, $product, $endpoint, $message);
$found{$vendor}{$product}[0] = $endpoint;
$found{$vendor}{$product}[1] = $message;
$count++;
}
$flag = 0;
}
}
print_custom;
print_foot;
printf(STDERR "Summary:\n");
printf(STDERR " total udev lines from config: %d\n" .
" ignored devices (blacklisted): %d\n" .
" ignored devices (malformed): %d\n" .
" ignored devices (duplicates): %d\n",
$count, $ignored, $failed, $dup);