File create_sane-backends-autoconfig.rules of Package sane-backends
#! /bin/bash
#
# Johannes Meixner <jsmeix@suse.de>, 2004, 2005, 2006
#set -x
export PATH="/sbin:/usr/sbin:/usr/bin:/bin"
export LC_ALL="POSIX"
export LANG="POSIX"
umask 022
MY_NAME=${0##*/}
# Input:
# Create a temporary file:
TMP_DATA=$(mktemp /tmp/$MY_NAME.XXXXXX) || { echo "Error: Failed to make a temporary file /tmp/$MY_NAME.XXXXXX" 1>&2 ; exit 1 ; }
# Extract only those USB scanners from the scanner database
# which are supported by the packages "sane-backends", "iscan-free", or "hplip"
# (i.e. not by the proprietary 32-bit-only i386-only "iscan" package)
# and which do not require firmware upload (i.e. FIRMWARE field is empty)
# (the INTERFACE field does not matter because it could be empty or stuff like "Parport USB" or "SCSI USB IEEE-1394")
# and where the USB-ID is known (i.e. '0x[0-9A-Fa-f][0-9A-Fa-f]*:0x[0-9A-Fa-f][0-9A-Fa-f]*')
# and where the support status is "complete" or "good" (i.e. skip "basic", "minimal", "untested", "unsupported")
# and keep only the fields of interest (i.e. BACKEND and USBID)
# and keep only unique lines (there are many duplicates among the fields of interest)
# and sort according to the USB-ID to have different driver lines for the same model contiguous
# which is needed to choose only one driver which is automatically activated
# because otherwise a scanner will show up multiple times in scanning frontends
# (once for each activated driver which works for this model)
# and finally set the usual input field separator ' ' (there are no blanks in BACKEND or USB-ID).
egrep '^sane-backends|^iscan-free|^hplip' scanner.database | grep '||[^|]*|0x[0-9A-Fa-f][0-9A-Fa-f]*:0x[0-9A-Fa-f][0-9A-Fa-f]*|' | cut -s -d '|' -f 2,7,8 | egrep 'complete$|good$' | cut -s -d '|' -f 1,2 | sort -u | sort -t '|' -k 2 | tr '|' ' ' >$TMP_DATA
# Output:
# Output header:
echo 'ACTION!="add", GOTO="sane_backends_autoconfig_rules_end"'
echo 'SUBSYSTEM!="usb", GOTO="sane_backends_autoconfig_rules_end"'
echo
# Output the scanner model entries:
USED_BACKENDS=""
PREVIOUS_VENDOR=""
PREVIOUS_MODEL=""
BACKENDS_FOR_SAME_MODEL=""
# Append a dummy entry to trigger the output for the last real model in the while loop:
echo 'dummy 0x0000:0x0000' >>$TMP_DATA
exec <$TMP_DATA
while read BACKEND USBID
do [ -z "$BACKEND" ] && { echo "Ignoring $USBID because there is no driver entry." 1>&2 ; continue ; }
VENDOR=$( echo $USBID | cut -s -d ':' -f 1 | sed -e 's/^0x//' )
[ -z "$VENDOR" ] && { echo "Ignoring $USBID because there is no vendor ID." 1>&2 ; continue ; }
MODEL=$( echo $USBID | cut -s -d ':' -f 2 | sed -e 's/^0x//' )
[ -z "$MODEL" ] && { echo "Ignoring $USBID because there is no model ID." 1>&2 ; continue ; }
# If the current model is the same as the previous model,
# add only the current backend to the list of backends for the same model:
if [ "$VENDOR" = "$PREVIOUS_VENDOR" -a "$MODEL" = "$PREVIOUS_MODEL" ]
then BACKENDS_FOR_SAME_MODEL=$( echo "$BACKENDS_FOR_SAME_MODEL $BACKEND" )
continue
fi
# When the model has changed,
# determine the "best" backend for the previous model
# and output only one single entry for it.
# Currently different driver lines for the same model happen only
# for Epson scanners (USB vendor ID 0x04b8):
# Many models are supported by epkowa, epson2, and epson (unmaintained driver).
# Two models are supported by plustek (and the non-free epkowa version in "iscan")
# One model is supported by epson2 and epson.
# The preferred driver is epkowa because
# it supports more models than the other drivers,
# it is made by the manufacturer (via Epson Avasys), and
# it is free software in the iscan-free package ("iscan" is suppressed, see above).
# On the one hand this means that when the iscan-free package is not installed,
# those scanners would not be autoconfigured even if many of those scanners are also
# supported by the epson2 driver (which is not activated because epkowa is preferred).
# On the other hand this avoids that different drivers are activated for the same model
# which lets the model show up several times in the scanning frontend (once for each driver).
# For example imagine there are two Epson USB scanners connected:
# One is supported only by epkowa, the other one is supported by epkowa and epson2.
# If both epkowa and epson2 would be activated, the other one would show up twice.
# Furthermore epson2 is preferred over the meanwhile unmaintained epson driver.
BEST_BACKEND=""
for B in plustek epson epson2 epkowa
do echo $BACKENDS_FOR_SAME_MODEL | grep -q "$B" && BEST_BACKEND="$B"
done
# Do not use 'cut -s' because BACKENDS_FOR_SAME_MODEL contains usually only one entry:
[ -z "$BEST_BACKEND" ] && BEST_BACKEND=$( echo $BACKENDS_FOR_SAME_MODEL | cut -d ' ' -f 1 )
if [ -n "$BEST_BACKEND" ]
then USED_BACKENDS=$( echo "$USED_BACKENDS $BEST_BACKEND" )
echo "ATTR{idVendor}==\"$PREVIOUS_VENDOR\", ATTR{idProduct}==\"$PREVIOUS_MODEL\", ENV{sane_backend_$BEST_BACKEND}=\"yes\""
fi
# Remember the current model:
BACKENDS_FOR_SAME_MODEL="$BACKEND"
PREVIOUS_VENDOR="$VENDOR"
PREVIOUS_MODEL="$MODEL"
done
echo
# Output the driver activation lines:
for B in $( echo $USED_BACKENDS | tr ' ' '\n' | sort -u )
do echo "ENV{sane_backend_$B}==\"yes\", RUN+=\"/bin/sed -i -e 's/^[[:space:]]*#[[:space:]]*$B[[:space:]]*\$\$/$B/' /etc/sane.d/dll.conf\""
done
echo
# Output footer:
echo 'LABEL="sane_backends_autoconfig_rules_end"'
echo
# Remove the temporary file
rm $TMP_DATA
exit 0