1#! /bin/sh 2# make-udev-rules -- creates udev rules from hotplug match info 3# Copyright (C) 2006, 2007 SEIKO EPSON Corporation 4 5# This file is part of "Image Scan! for Linux". 6# You can redistribute it and/or modify it under the terms of the GNU 7# General Public License as published by the Free Software Foundation; 8# either version 2 of the License or at your option any later version. 9# 10# This program is distributed in the hope that it will be useful, but 11# WITHOUT ANY WARRANTY; without even the implied warranty of FITNESS 12# FOR A PARTICULAR PURPOSE or MERCHANTABILITY. 13# See the GNU General Public License for more details. 14# 15# You should have received a verbatim copy of the GNU General Public 16# License along with this program; if not, write to: 17# 18# Free Software Foundation, Inc. 19# 59 Temple Place, Suite 330 20# Boston, MA 02111-1307 USA 21 22 23USERMAP=${1} # location of iscan.usermap 24RULEDIR=${2:-/etc/udev/rules.d} 25 26TEMPLATE='SYSFS{idVendor}=="04b8", SYSFS{idProduct}=="HHHH", MODE="0666"' 27SUB_SYST='usb_device' 28 29# Convenience functions. 30 31usage () { 32 cat <<EOF 33Usage: make-udev-rules FILE [UDEV_RULES_DIR] 34Creates a udev rules file using the hotplug match information found 35in FILE. The UDEV_RULES_DIR is searched for SANE related files for 36use in rule template generation. It defaults to /etc/udev/rules.d. 37A rules file will be written to *iscan.rules in UDEV_RULES_DIR. 38 39Setting the DEBUG environment variable to a non-empty string can be 40used to divert the rules to standard output instead. 41EOF 42} 43 44debug () { 45 test x$DEBUG != x || return 0 46 echo DBG: $* >&2 47} 48 49get_usb_product_ids () { 50 sed 's/#.*//; /^[[:space:]]*$/d' $USERMAP \ 51 | awk '{print $4}' \ 52 | sed 's/0x//' \ 53 | tr '\n' ' ' 54} 55 56# Although this function takes line continuation into account, it 57# does assume that SYSFS{idVendor} is on the first line. 58# 59get_template_rule () { 60 sed -n 's/#.*//; /^[[:space:]]*$/d 61 /SYSFS{idVendor}=\{1,2\}"04[bB]8"/{ 62 /\\$/N 63 s/\\\n// 64 p 65 q 66 }' $* \ 67 | sed 's/\(SYSFS{idProduct}=\{1,2\}\)"[[:xdigit:]]\{4\}"/\1"HHHH"/' 68} 69 70# Heavily based on get_template_rule (), this tries to find the name 71# that is used by udev for the USB subsystem. Unfortunately not all 72# distributions (kernel/udev versions?) use the same name. 73# 74get_sub_syst_name () { 75 sed -n 's/#.*//; /^[[:space:]]*$/d 76 /SUBSYSTEM!\{,1\}=\{1,2\}"usb.*"/{ 77 p 78 q 79 }' $* \ 80 | sed 's/.*SUBSYSTEM!\{,1\}=\{1,2\}"\([^"]*\)".*/\1/' 81} 82 83# WARNING: this heavily relies on the fact that we only try existing 84# rules files that match lib*.rules. 85# 86get_out_file_name () { 87 ls $* | sed 's/lib[^.]*/iscan/' 88} 89 90# Sanity tests. 91 92if test -z "$USERMAP"; then 93 usage 94 exit 1 95fi 96 97LC_ALL=C # sanitise environment a bit 98RULEDIR=${RULEDIR%%/} 99 100prod_ids="`get_usb_product_ids`" 101test -n "$prod_ids" || exit 1 102 103template= 104out_file= 105for rules in \ 106 libsane.rules \ 107 libusbscanner.rules \ 108 ; do 109 template="`get_template_rule $RULEDIR/*$rules 2>/dev/null`" 110 sub_syst="`get_sub_syst_name $RULEDIR/*$rules 2>/dev/null`" 111 out_file="`get_out_file_name $RULEDIR/*$rules 2>/dev/null`" 112 test -n "$template" && break 113done 114debug "Using template from $RULEDIR/*$rules" 115 116if test -z "$template"; then 117 template="$TEMPLATE" 118 out_file=$RULEDIR/60_iscan.rules 119fi 120if test -z "$sub_syst"; then 121 sub_syst="$SUB_SYST" 122fi 123 124if test x$DEBUG != x; then 125 debug "Would have sent output to $out_file" 126else # better make sure 127 test -d $RULEDIR || mkdir -p $RULEDIR 128 exec 1> $out_file 129fi 130 131 132cat <<EOF 133# This file is part of the "Image Scan! for Linux" binary package (or 134# generated automatically as part of its installation). Any changes 135# will be overwritten with each upgrade of the package. 136 137ACTION!="add", GOTO="iscan_rules_end" 138SUBSYSTEM!="$sub_syst", GOTO="iscan_rules_end" 139 140EOF 141 142for id in $prod_ids; do 143 echo $template | sed "s,HHHH,$id," 144done 145 146cat <<EOF 147 148LABEL="iscan_rules_end" 149EOF 150 151exit 0 152