From 9fb9fd85f26508108d06b82b024759764bb6593b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 14 Feb 2022 21:29:33 +0100 Subject: Remove test artefact (debian/1.sh) --- debian/1.sh | 12 ------------ debian/changelog | 6 ++++++ 2 files changed, 6 insertions(+), 12 deletions(-) delete mode 100755 debian/1.sh diff --git a/debian/1.sh b/debian/1.sh deleted file mode 100755 index 9d8e101..0000000 --- a/debian/1.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -set -e - - - if [ ! -d /var/lib/saned ] ; then - echo /var/lib/saned not found - fi - - if [ -d /var/lib/saned ] ; then - echo /var/lib/saned found - fi - diff --git a/debian/changelog b/debian/changelog index bae3faf..9d9b0dc 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +sane-backends (1.1.1-3) UNRELEASED; urgency=medium + + * Remove test artefact (debian/1.sh). + + -- Jörg Frings-Fürst Mon, 14 Feb 2022 21:28:17 +0100 + sane-backends (1.1.1-2) unstable; urgency=medium * debina/sane-utils.postinst: -- cgit v1.2.3 From f66f0495d579a693bdabca232fcccc8aecc54d9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 21 Feb 2022 07:11:04 +0100 Subject: d/changelog: Fix spelling error --- debian/changelog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 9d9b0dc..5c5b4f8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,12 +1,13 @@ sane-backends (1.1.1-3) UNRELEASED; urgency=medium * Remove test artefact (debian/1.sh). + * debian/changelog: Fix spelling error (Closes: #1006116). -- Jörg Frings-Fürst Mon, 14 Feb 2022 21:28:17 +0100 sane-backends (1.1.1-2) unstable; urgency=medium - * debina/sane-utils.postinst: + * debian/sane-utils.postinst: - Fix syntax error (Closes: #1005102). -- Jörg Frings-Fürst Mon, 07 Feb 2022 20:35:48 +0100 -- cgit v1.2.3 From 632c82ef43ac91f21304e3374b5231bd7da78410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 21 Feb 2022 07:20:55 +0100 Subject: d/sane-utils.postinst: Remove not longer requested home directory move --- debian/changelog | 1 + debian/sane-utils.postinst | 16 ---------------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/debian/changelog b/debian/changelog index 5c5b4f8..0c48c28 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,7 @@ sane-backends (1.1.1-3) UNRELEASED; urgency=medium * Remove test artefact (debian/1.sh). * debian/changelog: Fix spelling error (Closes: #1006116). + * debian/sane-utils.postinst: Remove not longer requested home directory move. -- Jörg Frings-Fürst Mon, 14 Feb 2022 21:28:17 +0100 diff --git a/debian/sane-utils.postinst b/debian/sane-utils.postinst index 4d8e9b1..b026a6e 100644 --- a/debian/sane-utils.postinst +++ b/debian/sane-utils.postinst @@ -46,22 +46,6 @@ if [ "$1" = "configure" ] || [ "$1" = "reconfigure" ]; then adduser --home /var/lib/saned --quiet --system --group saned || true fi - # Move home from /home/saned to /var/lib/saned (since 1.0.24-6) - if getent passwd | grep "^saned:" | grep -q "/home/saned"; then - echo "Test for running scanbd" - if ps -Af | grep "saned" | grep -q "scanbd"; then - echo "Stop scanbd" - invoke-rc.d --quiet scanbd stop - echo "Move homedir from /home/saned to /var/lib/saned" - usermod -d /var/lib/saned saned - echo "Start scanbd" - invoke-rc.d --quiet scanbd start - else - echo "Move homedir from /home/saned to /var/lib/saned" - usermod -d /var/lib/saned saned - fi - fi - if [ ! -d /var/lib/saned ] ; then usermod -d /var/lib/saned saned fi -- cgit v1.2.3 From f8a9c34a1b53a4f5b2696f4f52612c9340b2f370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 21 Feb 2022 07:31:30 +0100 Subject: d/sane-utils.postrm: Don't remove group scanner --- debian/changelog | 1 + debian/sane-utils.postrm | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 0c48c28..60d26b0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,7 @@ sane-backends (1.1.1-3) UNRELEASED; urgency=medium * Remove test artefact (debian/1.sh). * debian/changelog: Fix spelling error (Closes: #1006116). * debian/sane-utils.postinst: Remove not longer requested home directory move. + * debian/sane-utils.postrm: Don't remove group scanner (Closes: #1005737). -- Jörg Frings-Fürst Mon, 14 Feb 2022 21:28:17 +0100 diff --git a/debian/sane-utils.postrm b/debian/sane-utils.postrm index 4bb3253..f5a0394 100644 --- a/debian/sane-utils.postrm +++ b/debian/sane-utils.postrm @@ -55,7 +55,6 @@ if [ "$1" = purge ] ; then # if pathfind deluser ; then deluser -q --group --system saned || true - deluser -q --group --system scanner || true deluser -q --system --remove-home saned || true fi -- cgit v1.2.3 From c29081c8566cb5d4d2606e9b68b35b8f38583c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 21 Feb 2022 07:35:24 +0100 Subject: dcontrol: Add Recommends: sane-airscan to libsane1 --- debian/changelog | 11 ++++++++--- debian/control | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index 60d26b0..c0b6e1e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,14 @@ sane-backends (1.1.1-3) UNRELEASED; urgency=medium * Remove test artefact (debian/1.sh). - * debian/changelog: Fix spelling error (Closes: #1006116). - * debian/sane-utils.postinst: Remove not longer requested home directory move. - * debian/sane-utils.postrm: Don't remove group scanner (Closes: #1005737). + * debian/changelog: + - Fix spelling error (Closes: #1006116). + * debian/sane-utils.postinst: + - Remove not longer requested home directory move. + * debian/sane-utils.postrm: + - Don't remove group scanner (Closes: #1005737). + * debian/control: + - Add Recommends: sane-airscan to libsane1 (Closes: 1005817). -- Jörg Frings-Fürst Mon, 14 Feb 2022 21:28:17 +0100 diff --git a/debian/control b/debian/control index 8794851..f6277ff 100644 --- a/debian/control +++ b/debian/control @@ -97,6 +97,7 @@ Depends: ${misc:Depends}, ${shlibs:Depends} Recommends: + sane-airscan sane-utils (>= ${binary:Version}), ipp-usb Suggests: avahi-daemon, hplip -- cgit v1.2.3 From 0655911383ce74c5082cf35374adf06908e94bf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 21 Feb 2022 13:00:30 +0100 Subject: Move man page sane-umax_pp.5 back to libsane-common --- .pc/.quilt_patches | 1 + .pc/.quilt_series | 1 + debian/changelog | 8 + debian/control | 8 +- debian/rules | 1 - debian/sane-utils.links | 1 - debian/sane-utils.manpages | 1 - debian/sane-utils.preinst | 21 + tools/sane-find-scanner.c.orig | 2108 ++++++++++++++++++++++++++++++++++++++++ tools/sane-find-scanner.c.rej | 22 + 10 files changed, 2165 insertions(+), 7 deletions(-) create mode 100644 .pc/.quilt_patches create mode 100644 .pc/.quilt_series create mode 100644 debian/sane-utils.preinst create mode 100644 tools/sane-find-scanner.c.orig create mode 100644 tools/sane-find-scanner.c.rej diff --git a/.pc/.quilt_patches b/.pc/.quilt_patches new file mode 100644 index 0000000..6857a8d --- /dev/null +++ b/.pc/.quilt_patches @@ -0,0 +1 @@ +debian/patches diff --git a/.pc/.quilt_series b/.pc/.quilt_series new file mode 100644 index 0000000..c206706 --- /dev/null +++ b/.pc/.quilt_series @@ -0,0 +1 @@ +series diff --git a/debian/changelog b/debian/changelog index c0b6e1e..e977760 100644 --- a/debian/changelog +++ b/debian/changelog @@ -9,6 +9,14 @@ sane-backends (1.1.1-3) UNRELEASED; urgency=medium - Don't remove group scanner (Closes: #1005737). * debian/control: - Add Recommends: sane-airscan to libsane1 (Closes: 1005817). + * Move man page sane-umax_pp.5 back to libsane-common (Closes: #1005736): + - debian/rules: + - Remove delete manpage vom libsane-common. + - New debian/sane-utils.preinst to remove man page and sysmlink. + - debian/sane-utils.link: + - Remove create link from sane-umax_pp.5 + - debian/control: + - Add new Breaks and Replace. -- Jörg Frings-Fürst Mon, 14 Feb 2022 21:28:17 +0100 diff --git a/debian/control b/debian/control index f6277ff..a7b9e87 100644 --- a/debian/control +++ b/debian/control @@ -43,8 +43,7 @@ Depends: ${shlibs:Depends} Pre-Depends: ${misc:Pre-Depends} -Breaks: libsane-common (<<1.0.27-1~) -Replaces: libsane-common (<<1.0.27-1~) +Breaks: libsane-common (<<1.1.1-3~) Suggests: avahi-daemon, unpaper Description: API library for scanners -- utilities SANE stands for "Scanner Access Now Easy" and is an application @@ -67,7 +66,8 @@ Multi-Arch: foreign Pre-Depends: dpkg (>= 1.15.7.2) Depends: ${misc:Depends} -Breaks: sane-utils (<<1.0.27-1~) +Breaks: sane-utils (<<1.1.1-3~) +Replaces: sane-utils (<<1.1.1-3~) Description: API library for scanners -- documentation and support files SANE stands for "Scanner Access Now Easy" and is an application programming interface (API) that provides standardized access to any @@ -97,7 +97,7 @@ Depends: ${misc:Depends}, ${shlibs:Depends} Recommends: - sane-airscan + sane-airscan, sane-utils (>= ${binary:Version}), ipp-usb Suggests: avahi-daemon, hplip diff --git a/debian/rules b/debian/rules index d0e1664..ef8e976 100755 --- a/debian/rules +++ b/debian/rules @@ -106,7 +106,6 @@ override_dh_installman-indep: $(RM) $(CURDIR)/debian/libsane-common/usr/share/man/man1/sane-find-scanner.1 $(RM) $(CURDIR)/debian/libsane-common/usr/share/man/man1/scanimage.1 $(RM) $(CURDIR)/debian/libsane-common/usr/share/man/man1/sane-config.1 - $(RM) $(CURDIR)/debian/libsane-common/usr/share/man/man5/sane-umax_pp.5 $(RM) -r $(CURDIR)/debian/libsane-common/usr/share/man/man8/ $(RM) -r $(CURDIR)/debian/libsane-common/usr/share/man/man1/ # remove manpages for not build libs diff --git a/debian/sane-utils.links b/debian/sane-utils.links index dacfe5d..50ffd0e 100644 --- a/debian/sane-utils.links +++ b/debian/sane-utils.links @@ -1,2 +1 @@ /dev/null /lib/systemd/system/saned.service -/usr/share/man/man5/sane-umax_pp.5 /usr/share/man/man5/umax_pp.5 diff --git a/debian/sane-utils.manpages b/debian/sane-utils.manpages index 6a2c010..357020f 100644 --- a/debian/sane-utils.manpages +++ b/debian/sane-utils.manpages @@ -1,3 +1,2 @@ usr/share/man/man8/*.8 usr/share/man/man1/*.1 -/usr/share/man/man5/sane-umax_pp.5 diff --git a/debian/sane-utils.preinst b/debian/sane-utils.preinst new file mode 100644 index 0000000..1a7f24b --- /dev/null +++ b/debian/sane-utils.preinst @@ -0,0 +1,21 @@ +#!/bin/sh + +set -e + +MANPAGE=/usr/share/man/man5/sane-umax_pp.5.gz +MANLINK=/usr/share/man/man5/umax_pp.5.gz + + +if [ -f "$MANLINK" ] && [ -L "$MANLINK" ]; then + # Remove old directory and files that are now provided by xsane-common + rm -rf "$MANLINK" +fi + + +if [ -f "$MANPAGE" ]; then + # Remove old directory and files that are now provided by xsane-common + rm -rf "$MANPAGE" +fi + + +#DEBHELPER# diff --git a/tools/sane-find-scanner.c.orig b/tools/sane-find-scanner.c.orig new file mode 100644 index 0000000..25e5954 --- /dev/null +++ b/tools/sane-find-scanner.c.orig @@ -0,0 +1,2108 @@ +/* sane-find-scanner.c + + Copyright (C) 1997-2013 Oliver Rauch, Henning Meier-Geinitz, and others. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + */ + +#include "../include/sane/config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined (HAVE_DDK_NTDDSCSI_H) || defined (HAVE_NTDDSCSI_H) +# define WIN32_SCSI +# include +# if defined (HAVE_DDK_NTDDSCSI_H) +# include +# include +# elif defined (HAVE_NTDDSCSI_H) +# include +# endif +#endif + +#include "../include/sane/sanei.h" +#include "../include/sane/sanei_scsi.h" +#include "../include/sane/sanei_pa4s2.h" +#include "../include/sane/sanei_config.h" + +#ifdef HAVE_LIBUSB_LEGACY +#ifdef HAVE_LUSB0_USB_H +#include +#else +#include +#endif +extern char * check_usb_chip (struct usb_device *dev, int verbosity, SANE_Bool from_file); +#endif + +#ifdef HAVE_LIBUSB +#include +extern char * check_usb_chip (int verbosity, + struct libusb_device_descriptor desc, + libusb_device_handle *hdl, + struct libusb_config_descriptor *config0); +#endif + +#include "../include/sane/sanei_usb.h" + +#ifndef PATH_MAX +# define PATH_MAX 1024 +#endif + +static const char *prog_name; +static int verbose = 1; +static SANE_Bool force = SANE_FALSE; +static SANE_Bool device_found = SANE_FALSE; +static SANE_Bool libusb_device_found = SANE_FALSE; +static SANE_Bool unknown_found = SANE_FALSE; + +#ifdef HAVE_LIBUSB +libusb_context *sfs_usb_ctx; +#endif + +typedef struct +{ + unsigned char *cmd; + size_t size; +} +scsiblk; + +#define INQUIRY 0x12 +#define set_inquiry_return_size(icb,val) icb[0x04]=val +#define IN_periph_devtype_cpu 0x03 +#define IN_periph_devtype_scanner 0x06 +#define get_scsi_inquiry_vendor(in, buf) strncpy(buf, in + 0x08, 0x08) +#define get_scsi_inquiry_product(in, buf) strncpy(buf, in + 0x10, 0x010) +#define get_scsi_inquiry_version(in, buf) strncpy(buf, in + 0x20, 0x04) +#define get_scsi_inquiry_periph_devtype(in) (in[0] & 0x1f) +#define get_scsi_inquiry_additional_length(in) in[0x04] +#define set_scsi_inquiry_length(out,n) out[0x04]=n-5 + +static unsigned char inquiryC[] = { + INQUIRY, 0x00, 0x00, 0x00, 0xff, 0x00 +}; +static scsiblk inquiry = { + inquiryC, sizeof (inquiryC) +}; + +static void +usage (char *msg) +{ + fprintf (stderr, "Usage: %s [-hvqf] [devname ...]\n", prog_name); + fprintf (stderr, "\t-h: print this help message\n"); + fprintf (stderr, "\t-v: be more verbose (can be used multiple times)\n"); + fprintf (stderr, "\t-q: be quiet (print only devices, no comments)\n"); + fprintf (stderr, "\t-f: force opening devname as SCSI even if it looks " + "like USB\n"); + fprintf (stderr, "\t-p: enable scanning for parallel port devices\n"); +#ifdef HAVE_LIBUSB_LEGACY + fprintf (stderr, "\t-F file: try to detect chipset from given " + "/proc/bus/usb/devices file\n"); +#endif + if (msg) + fprintf (stderr, "\t%s\n", msg); +} + +/* if SCSI generic is optional on your OS, and there is a software test + which will determine if it is included, add it here. If you are sure + that SCSI generic was found, return 1. If SCSI generic is always + available in your OS, return 1 */ + +static int +check_sg (void) +{ +#if defined(__linux__) + /* Assumption: /proc/devices lines are shorter than 256 characters */ + char line[256], driver[256] = ""; + FILE *stream; + + stream = fopen ("/proc/devices", "r"); + /* Likely reason for failure, no /proc => probably no SG either */ + if (stream == NULL) + return 0; + + while (fgets (line, sizeof (line) - 1, stream)) + { + if (sscanf (line, " %*d %s\n", driver) > 0 && !strcmp (driver, "sg")) + break; + } + fclose (stream); + + if (strcmp (driver, "sg")) + { + return 0; + } + else + { + return 1; + } +#endif + return 1; /* Give up, and assume yes to avoid false negatives */ +} + +/* Display a buffer in the log. Display by lines of 16 bytes. */ +static void +hexdump (const char *comment, unsigned char *buf, const int length) +{ + int i; + char line[128]; + char *ptr; + char asc_buf[17]; + char *asc_ptr; + + printf (" %s\n", comment); + + i = 0; + goto start; + + do + { + if (i < length) + { + ptr += sprintf (ptr, " %2.2x", *buf); + + if (*buf >= 32 && *buf <= 127) + { + asc_ptr += sprintf (asc_ptr, "%c", *buf); + } + else + { + asc_ptr += sprintf (asc_ptr, "."); + } + } + else + { + /* After the length; do nothing. */ + ptr += sprintf (ptr, " "); + } + + i++; + buf++; + + if ((i % 16) == 0) + { + /* It's a new line */ + printf (" %s %s\n", line, asc_buf); + + start: + ptr = line; + *ptr = '\0'; + asc_ptr = asc_buf; + *asc_ptr = '\0'; + + ptr += sprintf (ptr, " %3.3d:", i); + } + + } + while (i < ((length + 15) & ~15)); +} + +static SANE_Status +scanner_do_scsi_inquiry (unsigned char *buffer, int sfd) +{ + size_t size; + SANE_Status status; + + memset (buffer, '\0', 256); /* clear buffer */ + + size = 5; /* first get only 5 bytes to get size of + inquiry_return_block */ + set_inquiry_return_size (inquiry.cmd, size); + status = sanei_scsi_cmd (sfd, inquiry.cmd, inquiry.size, buffer, &size); + + if (status != SANE_STATUS_GOOD) + return (status); + + size = get_scsi_inquiry_additional_length (buffer) + 5; + + /* then get inquiry with actual size */ + set_inquiry_return_size (inquiry.cmd, size); + status = sanei_scsi_cmd (sfd, inquiry.cmd, inquiry.size, buffer, &size); + + return (status); +} + +static void +scanner_identify_scsi_scanner (unsigned char *buffer, int sfd, + char *devicename) +{ + unsigned char vendor[9]; + unsigned char product[17]; + unsigned char version[5]; + unsigned char *pp; + unsigned int devtype; + SANE_Status status; + static char *devtypes[] = { + "disk", "tape", "printer", "processor", "CD-writer", + "CD-drive", "scanner", "optical-drive", "jukebox", + "communicator" + }; + status = scanner_do_scsi_inquiry (buffer, sfd); + if (status != SANE_STATUS_GOOD) + { + if (verbose > 1) + printf ("inquiry for device %s failed (%s)\n", + devicename, sane_strstatus (status)); + return; + } + + if (verbose > 2) + hexdump ("Inquiry for device:", buffer, + get_scsi_inquiry_additional_length (buffer) + 5); + + devtype = get_scsi_inquiry_periph_devtype (buffer); + if (verbose <= 1 && devtype != IN_periph_devtype_scanner + /* old HP scanners use the CPU id ... */ + && devtype != IN_periph_devtype_cpu) + return; /* no, continue searching */ + + get_scsi_inquiry_vendor ((char *) buffer, (char *) vendor); + get_scsi_inquiry_product ((char *) buffer, (char *) product); + get_scsi_inquiry_version ((char *) buffer, (char *) version); + + pp = &vendor[7]; + vendor[8] = '\0'; + while (pp >= vendor && (*pp == ' ' || *pp >= 127)) + *pp-- = '\0'; + + pp = &product[15]; + product[16] = '\0'; + while (pp >= product && (*pp == ' ' || *pp >= 127)) + *pp-- = '\0'; + + pp = &version[3]; + version[4] = '\0'; + while (pp >= version && (*pp == ' ' || *(pp - 1) >= 127)) + *pp-- = '\0'; + + device_found = SANE_TRUE; + printf ("found SCSI %s \"%s %s %s\" at %s\n", + devtype < NELEMS (devtypes) ? devtypes[devtype] : "unknown device", + vendor, product, version, devicename); + return; +} + +static void +check_scsi_file (char *file_name) +{ + int result; + int sfd; + unsigned char buffer[16384]; + + if (strstr (file_name, "usb") + || strstr (file_name, "uscanner") || strstr (file_name, "ugen")) + { + if (force) + { + if (verbose > 1) + printf ("checking %s even though it looks like a USB device...", + file_name); + } + else + { + if (verbose > 1) + printf ("ignored %s (not a SCSI device)\n", file_name); + return; + } + } + else if (verbose > 1) + printf ("checking %s...", file_name); + + result = sanei_scsi_open (file_name, &sfd, NULL, NULL); + + if (verbose > 1) + { + if (result != 0) + printf (" failed to open (%s)\n", sane_strstatus (result)); + else + printf (" open ok\n"); + } + + if (result == SANE_STATUS_GOOD) + { + scanner_identify_scsi_scanner (buffer, sfd, file_name); + sanei_scsi_close (sfd); + } + return; +} + +static void +check_usb_file (char *file_name) +{ + SANE_Status result; + SANE_Word vendor, product; + SANE_Int fd; + + if (!strstr (file_name, "usb") + && !strstr (file_name, "uscanner") && !strstr (file_name, "ugen")) + { + if (force) + { + if (verbose > 1) + printf ("checking %s even though doesn't look like a " + "USB device...", file_name); + } + else + { + if (verbose > 1) + printf ("ignored %s (not a USB device)\n", file_name); + return; + } + } + else if (verbose > 1) + printf ("checking %s...", file_name); + + result = sanei_usb_open (file_name, &fd); + + if (result != SANE_STATUS_GOOD) + { + if (verbose > 1) + printf (" failed to open (%s)\n", sane_strstatus (result)); + } + else + { + result = sanei_usb_get_vendor_product (fd, &vendor, &product); + if (result == SANE_STATUS_GOOD) + { + if (verbose > 1) + printf (" open ok, vendor and product ids were identified\n"); + printf ("found USB scanner (vendor=0x%04x, " + "product=0x%04x) at %s\n", vendor, product, file_name); + } + else + { + if (verbose > 1) + printf (" open ok, but vendor and product could NOT be " + "identified\n"); + printf ("found USB scanner (UNKNOWN vendor and product) " + "at device %s\n", file_name); + unknown_found = SANE_TRUE; + } + device_found = SANE_TRUE; + sanei_usb_close (fd); + } +} + +#ifdef HAVE_LIBUSB_LEGACY + +static char * +get_libusb_string_descriptor (struct usb_device *dev, int index) +{ + usb_dev_handle *handle; + char *buffer, short_buffer[2]; + struct usb_string_descriptor *sd; + int size = 2; + int i; + + if (!index) + return 0; + + handle = usb_open (dev); + if (!handle) + return 0; + + sd = (struct usb_string_descriptor *) short_buffer; + + if (usb_control_msg (handle, + USB_ENDPOINT_IN + USB_TYPE_STANDARD + USB_RECIP_DEVICE, + USB_REQ_GET_DESCRIPTOR, + (USB_DT_STRING << 8) + index, 0, short_buffer, + size, 1000) < 0) + { + usb_close (handle); + return 0; + } + + if (sd->bLength < 2 + || sd->bDescriptorType != USB_DT_STRING) + { + usb_close (handle); + return 0; + } + + size = sd->bLength; + + buffer = calloc (1, size + 1); + if (!buffer) + return 0; + + sd = (struct usb_string_descriptor *) buffer; + + if (usb_control_msg (handle, + USB_ENDPOINT_IN + USB_TYPE_STANDARD + USB_RECIP_DEVICE, + USB_REQ_GET_DESCRIPTOR, + (USB_DT_STRING << 8) + index, 0, buffer, + size, 1000) < 0) + { + usb_close (handle); + free (buffer); + return 0; + } + + if (sd->bLength < 2 || sd->bLength > size + || sd->bDescriptorType != USB_DT_STRING) + { + usb_close (handle); + free (buffer); + return 0; + } + size = sd->bLength - 2; + for (i = 0; i < (size / 2); i++) + buffer[i] = buffer[2 + 2 * i]; + buffer[i] = 0; + + usb_close (handle); + return buffer; +} + +static char * +get_libusb_vendor (struct usb_device *dev) +{ + return get_libusb_string_descriptor (dev, dev->descriptor.iManufacturer); +} + +static char * +get_libusb_product (struct usb_device *dev) +{ + return get_libusb_string_descriptor (dev, dev->descriptor.iProduct); +} + +static void +check_libusb_device (struct usb_device *dev, SANE_Bool from_file) +{ + int is_scanner = 0; + char *vendor; + char *product; + int interface_nr; + + if (!dev->config) + { + if (verbose > 1) + printf ("device 0x%04x/0x%04x is not configured\n", + dev->descriptor.idVendor, dev->descriptor.idProduct); + return; + } + + vendor = get_libusb_vendor (dev); + product = get_libusb_product (dev); + + if (verbose > 2) + { + /* print everything we know about the device */ + char *buf; + int config_nr; + struct usb_device_descriptor *d = &dev->descriptor; + + printf ("\n"); + printf ("idVendor, d->idProduct, dev->bus->dirname, dev->filename); + if (vendor || product) + { + printf (" (%s%s%s)", vendor ? vendor : "", + (vendor && product) ? " " : "", product ? product : ""); + } + printf (">\n"); + printf ("bLength %d\n", d->bLength); + printf ("bDescriptorType %d\n", d->bDescriptorType); + printf ("bcdUSB %d.%d%d\n", d->bcdUSB >> 8, + (d->bcdUSB >> 4) & 15, d->bcdUSB & 15); + printf ("bDeviceClass %d\n", d->bDeviceClass); + printf ("bDeviceSubClass %d\n", d->bDeviceSubClass); + printf ("bDeviceProtocol %d\n", d->bDeviceProtocol); + printf ("bMaxPacketSize0 %d\n", d->bMaxPacketSize0); + printf ("idVendor 0x%04X\n", d->idVendor); + printf ("idProduct 0x%04X\n", d->idProduct); + printf ("bcdDevice %d.%d%d\n", d->bcdDevice >> 8, + (d->bcdDevice >> 4) & 15, d->bcdDevice & 15); + printf ("iManufacturer %d (%s)\n", d->iManufacturer, + (vendor) ? vendor : ""); + printf ("iProduct %d (%s)\n", d->iProduct, + (product) ? product : ""); + + buf = get_libusb_string_descriptor (dev, d->iSerialNumber); + printf ("iSerialNumber %d (%s)\n", d->iSerialNumber, + (buf) ? buf : ""); + if (buf) + free (buf); + printf ("bNumConfigurations %d\n", d->bNumConfigurations); + + for (config_nr = 0; config_nr < d->bNumConfigurations; config_nr++) + { + struct usb_config_descriptor *c = &dev->config[config_nr]; + int interface_nr; + + printf (" \n", config_nr); + printf (" bLength %d\n", c->bLength); + printf (" bDescriptorType %d\n", c->bDescriptorType); + printf (" wTotalLength %d\n", c->wTotalLength); + printf (" bNumInterfaces %d\n", c->bNumInterfaces); + printf (" bConfigurationValue %d\n", c->bConfigurationValue); + buf = get_libusb_string_descriptor (dev, c->iConfiguration); + printf (" iConfiguration %d (%s)\n", c->iConfiguration, + (buf) ? buf : ""); + if (buf) + free (buf); + printf (" bmAttributes %d (%s%s)\n", c->bmAttributes, + c->bmAttributes & 64 ? "Self-powered" : "", + c->bmAttributes & 32 ? "Remote Wakeup" : ""); + printf (" MaxPower %d mA\n", c->MaxPower * 2); + + for (interface_nr = 0; interface_nr < c->bNumInterfaces; + interface_nr++) + { + struct usb_interface *interface = &c->interface[interface_nr]; + int alt_setting_nr; + + printf (" \n", interface_nr); + for (alt_setting_nr = 0; + alt_setting_nr < interface->num_altsetting; + alt_setting_nr++) + { + struct usb_interface_descriptor *i + = &interface->altsetting[alt_setting_nr]; + int ep_nr; + printf (" \n", alt_setting_nr); + printf (" bLength %d\n", i->bLength); + printf (" bDescriptorType %d\n", i->bDescriptorType); + printf (" bInterfaceNumber %d\n", i->bInterfaceNumber); + printf (" bAlternateSetting %d\n", i->bAlternateSetting); + printf (" bNumEndpoints %d\n", i->bNumEndpoints); + printf (" bInterfaceClass %d\n", i->bInterfaceClass); + printf (" bInterfaceSubClass %d\n", + i->bInterfaceSubClass); + printf (" bInterfaceProtocol %d\n", + i->bInterfaceProtocol); + buf = get_libusb_string_descriptor (dev, i->iInterface); + printf (" iInterface %d (%s)\n", i->iInterface, + (buf) ? buf : ""); + if (buf) + free (buf); + + for (ep_nr = 0; ep_nr < i->bNumEndpoints; ep_nr++) + { + struct usb_endpoint_descriptor *e = &i->endpoint[ep_nr]; + char *ep_type; + + switch (e->bmAttributes & USB_ENDPOINT_TYPE_MASK) + { + case USB_ENDPOINT_TYPE_CONTROL: + ep_type = "control"; + break; + case USB_ENDPOINT_TYPE_ISOCHRONOUS: + ep_type = "isochronous"; + break; + case USB_ENDPOINT_TYPE_BULK: + ep_type = "bulk"; + break; + case USB_ENDPOINT_TYPE_INTERRUPT: + ep_type = "interrupt"; + break; + default: + ep_type = "unknown"; + break; + } + printf (" \n", ep_nr); + printf (" bLength %d\n", e->bLength); + printf (" bDescriptorType %d\n", + e->bDescriptorType); + printf (" bEndpointAddress 0x%02X (%s 0x%02X)\n", + e->bEndpointAddress, + e->bEndpointAddress & USB_ENDPOINT_DIR_MASK ? + "in" : "out", + e-> + bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK); + printf (" bmAttributes %d (%s)\n", + e->bmAttributes, ep_type); + printf (" wMaxPacketSize %d\n", + e->wMaxPacketSize); + printf (" bInterval %d ms\n", e->bInterval); + printf (" bRefresh %d\n", e->bRefresh); + printf (" bSynchAddress %d\n", e->bSynchAddress); + } + } + } + } + + } + + /* Some heuristics, which device may be a scanner */ + if (dev->descriptor.idVendor == 0) /* hub */ + --is_scanner; + if (dev->descriptor.idProduct == 0) /* hub */ + --is_scanner; + + for (interface_nr = 0; interface_nr < dev->config[0].bNumInterfaces && is_scanner <= 0; interface_nr++) + { + switch (dev->descriptor.bDeviceClass) + { + case USB_CLASS_VENDOR_SPEC: + ++is_scanner; + break; + case USB_CLASS_PER_INTERFACE: + if (dev->config[0].interface[interface_nr].num_altsetting == 0 || + !dev->config[0].interface[interface_nr].altsetting) + break; + switch (dev->config[0].interface[interface_nr].altsetting[0].bInterfaceClass) + { + case USB_CLASS_VENDOR_SPEC: + case USB_CLASS_PER_INTERFACE: + case 16: /* data? */ + ++is_scanner; + break; + } + break; + } + } + + if (is_scanner > 0) + { + char * chipset = check_usb_chip (dev, verbose, from_file); + + printf ("found USB scanner (vendor=0x%04x", dev->descriptor.idVendor); + if (vendor) + printf (" [%s]", vendor); + printf (", product=0x%04x", dev->descriptor.idProduct); + if (product) + printf (" [%s]", product); + if (chipset) + printf (", chip=%s", chipset); + if (from_file) + printf (")\n"); + else + printf (") at libusb:%s:%s\n", dev->bus->dirname, dev->filename); + + libusb_device_found = SANE_TRUE; + device_found = SANE_TRUE; + } + + if (vendor) + free (vendor); + + if (product) + free (product); +} +#endif /* HAVE_LIBUSB_LEGACY */ + + +#ifdef HAVE_LIBUSB +static char * +sfs_libusb_strerror (int errcode) +{ + /* Error codes & descriptions from the libusb-1.0 documentation */ + + switch (errcode) + { + case LIBUSB_SUCCESS: + return "Success (no error)"; + + case LIBUSB_ERROR_IO: + return "Input/output error"; + + case LIBUSB_ERROR_INVALID_PARAM: + return "Invalid parameter"; + + case LIBUSB_ERROR_ACCESS: + return "Access denied (insufficient permissions)"; + + case LIBUSB_ERROR_NO_DEVICE: + return "No such device (it may have been disconnected)"; + + case LIBUSB_ERROR_NOT_FOUND: + return "Entity not found"; + + case LIBUSB_ERROR_BUSY: + return "Resource busy"; + + case LIBUSB_ERROR_TIMEOUT: + return "Operation timed out"; + + case LIBUSB_ERROR_OVERFLOW: + return "Overflow"; + + case LIBUSB_ERROR_PIPE: + return "Pipe error"; + + case LIBUSB_ERROR_INTERRUPTED: + return "System call interrupted (perhaps due to signal)"; + + case LIBUSB_ERROR_NO_MEM: + return "Insufficient memory"; + + case LIBUSB_ERROR_NOT_SUPPORTED: + return "Operation not supported or unimplemented on this platform"; + + case LIBUSB_ERROR_OTHER: + return "Other error"; + + default: + return "Unknown libusb-1.0 error code"; + } +} + +static char * +get_libusb_string_descriptor (libusb_device_handle *hdl, int index) +{ + unsigned char *buffer, short_buffer[2]; + int size; + int ret; + int i; + + if (!index) + return NULL; + + ret = libusb_get_descriptor (hdl, LIBUSB_DT_STRING, index, + short_buffer, sizeof (short_buffer)); + if (ret < 0) + { + printf ("could not fetch string descriptor: %s\n", + sfs_libusb_strerror (ret)); + return NULL; + } + + if ((short_buffer[0] < 2) /* descriptor length */ + || (short_buffer[1] != LIBUSB_DT_STRING)) /* descriptor type */ + return NULL; + + size = short_buffer[0]; + + buffer = calloc (1, size + 1); + if (!buffer) + return NULL; + + ret = libusb_get_descriptor (hdl, LIBUSB_DT_STRING, index, + buffer, size); + if (ret < 0) + { + printf ("could not fetch string descriptor (again): %s\n", + sfs_libusb_strerror (ret)); + free (buffer); + return NULL; + } + + if ((buffer[0] < 2) || (buffer[0] > size) /* descriptor length */ + || (buffer[1] != LIBUSB_DT_STRING)) /* descriptor type */ + { + free (buffer); + return NULL; + } + + size = buffer[0] - 2; + for (i = 0; i < (size / 2); i++) + buffer[i] = buffer[2 + 2 * i]; + buffer[i] = '\0'; + + return (char *) buffer; +} + +static void +check_libusb_device (libusb_device *dev, SANE_Bool from_file) +{ + libusb_device_handle *hdl; + struct libusb_device_descriptor desc; + struct libusb_config_descriptor *config0; + + int is_scanner = 0; + char *vendor; + char *product; + unsigned short vid, pid; + unsigned char busno, address; + int config; + int intf; + int ret; + + busno = libusb_get_bus_number (dev); + address = libusb_get_device_address (dev); + + ret = libusb_get_device_descriptor (dev, &desc); + if (ret < 0) + { + printf ("could not get device descriptor for device at %03d:%03d: %s\n", + busno, address, sfs_libusb_strerror (ret)); + return; + } + + vid = desc.idVendor; + pid = desc.idProduct; + + ret = libusb_open (dev, &hdl); + if (ret < 0) + { + printf ("could not open USB device 0x%04x/0x%04x at %03d:%03d: %s\n", + vid, pid, busno, address, sfs_libusb_strerror (ret)); + return; + } + + ret = libusb_get_configuration (hdl, &config); + if (ret < 0) + { + printf ("could not get configuration for device 0x%04x/0x%04x at %03d:%03d: %s\n", + vid, pid, busno, address, sfs_libusb_strerror (ret)); + libusb_close (hdl); + return; + } + + if (config == 0) + { + if (verbose > 1) + printf ("device 0x%04x/0x%04x at %03d:%03d is not configured\n", + vid, pid, busno, address); + libusb_close (hdl); + return; + } + + vendor = get_libusb_string_descriptor (hdl, desc.iManufacturer); + product = get_libusb_string_descriptor (hdl, desc.iProduct); + + if (verbose > 2) + { + /* print everything we know about the device */ + char *buf; + int config_nr; + + printf ("\n"); + printf ("\n"); + printf ("bLength %d\n", desc.bLength); + printf ("bDescriptorType %d\n", desc.bDescriptorType); + printf ("bcdUSB %d.%d%d\n", desc.bcdUSB >> 8, + (desc.bcdUSB >> 4) & 15, desc.bcdUSB & 15); + printf ("bDeviceClass %d\n", desc.bDeviceClass); + printf ("bDeviceSubClass %d\n", desc.bDeviceSubClass); + printf ("bDeviceProtocol %d\n", desc.bDeviceProtocol); + printf ("bMaxPacketSize0 %d\n", desc.bMaxPacketSize0); + printf ("idVendor 0x%04X\n", desc.idVendor); + printf ("idProduct 0x%04X\n", desc.idProduct); + printf ("bcdDevice %d.%d%d\n", desc.bcdDevice >> 8, + (desc.bcdDevice >> 4) & 15, desc.bcdDevice & 15); + printf ("iManufacturer %d (%s)\n", desc.iManufacturer, + (vendor) ? vendor : ""); + printf ("iProduct %d (%s)\n", desc.iProduct, + (product) ? product : ""); + buf = get_libusb_string_descriptor (hdl, desc.iSerialNumber); + printf ("iSerialNumber %d (%s)\n", desc.iSerialNumber, + (buf) ? buf : ""); + if (buf) + free (buf); + printf ("bNumConfigurations %d\n", desc.bNumConfigurations); + + for (config_nr = 0; config_nr < desc.bNumConfigurations; config_nr++) + { + struct libusb_config_descriptor *c; + + ret = libusb_get_config_descriptor (dev, config_nr, &c); + if (ret < 0) + { + printf ("could not get configuration descriptor %d: %s\n", + config_nr, sfs_libusb_strerror (ret)); + continue; + } + + printf (" \n", config_nr); + printf (" bLength %d\n", c->bLength); + printf (" bDescriptorType %d\n", c->bDescriptorType); + printf (" wTotalLength %d\n", c->wTotalLength); + printf (" bNumInterfaces %d\n", c->bNumInterfaces); + printf (" bConfigurationValue %d\n", c->bConfigurationValue); + + buf = get_libusb_string_descriptor (hdl, c->iConfiguration); + printf (" iConfiguration %d (%s)\n", c->iConfiguration, + (buf) ? buf : ""); + free (buf); + + printf (" bmAttributes %d (%s%s)\n", c->bmAttributes, + c->bmAttributes & 64 ? "Self-powered" : "", + c->bmAttributes & 32 ? "Remote Wakeup" : ""); + printf (" MaxPower %d mA\n", c->MaxPower * 2); + + for (intf = 0; intf < c->bNumInterfaces; intf++) + { + const struct libusb_interface *interface; + int alt_setting_nr; + + interface = &c->interface[intf]; + + printf (" \n", intf); + for (alt_setting_nr = 0; + alt_setting_nr < interface->num_altsetting; + alt_setting_nr++) + { + const struct libusb_interface_descriptor *i; + int ep_nr; + + i = &interface->altsetting[alt_setting_nr]; + + printf (" \n", alt_setting_nr); + printf (" bLength %d\n", i->bLength); + printf (" bDescriptorType %d\n", i->bDescriptorType); + printf (" bInterfaceNumber %d\n", i->bInterfaceNumber); + printf (" bAlternateSetting %d\n", i->bAlternateSetting); + printf (" bNumEndpoints %d\n", i->bNumEndpoints); + printf (" bInterfaceClass %d\n", i->bInterfaceClass); + printf (" bInterfaceSubClass %d\n", + i->bInterfaceSubClass); + printf (" bInterfaceProtocol %d\n", + i->bInterfaceProtocol); + + buf = NULL; + buf = get_libusb_string_descriptor (hdl, i->iInterface); + printf (" iInterface %d (%s)\n", i->iInterface, + (buf) ? buf : ""); + free (buf); + for (ep_nr = 0; ep_nr < i->bNumEndpoints; ep_nr++) + { + const struct libusb_endpoint_descriptor *e; + char *ep_type; + + e = &i->endpoint[ep_nr]; + + switch (e->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) + { + case LIBUSB_TRANSFER_TYPE_CONTROL: + ep_type = "control"; + break; + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + ep_type = "isochronous"; + break; + case LIBUSB_TRANSFER_TYPE_BULK: + ep_type = "bulk"; + break; + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + ep_type = "interrupt"; + break; + default: + ep_type = "unknown"; + break; + } + printf (" \n", ep_nr); + printf (" bLength %d\n", e->bLength); + printf (" bDescriptorType %d\n", + e->bDescriptorType); + printf (" bEndpointAddress 0x%02X (%s 0x%02X)\n", + e->bEndpointAddress, + e->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK ? + "in" : "out", + e-> + bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK); + printf (" bmAttributes %d (%s)\n", + e->bmAttributes, ep_type); + printf (" wMaxPacketSize %d\n", + e->wMaxPacketSize); + printf (" bInterval %d ms\n", e->bInterval); + printf (" bRefresh %d\n", e->bRefresh); + printf (" bSynchAddress %d\n", e->bSynchAddress); + } + } + } + } + } + + + /* Some heuristics, which device may be a scanner */ + if (desc.idVendor == 0) /* hub */ + --is_scanner; + if (desc.idProduct == 0) /* hub */ + --is_scanner; + + ret = libusb_get_config_descriptor (dev, 0, &config0); + if (ret < 0) + { + printf ("could not get config[0] descriptor: %s\n", + sfs_libusb_strerror (ret)); + + goto out_free; + } + + for (intf = 0; (intf < config0->bNumInterfaces) && (is_scanner <= 0); intf++) + { + switch (desc.bDeviceClass) + { + case USB_CLASS_VENDOR_SPEC: + ++is_scanner; + break; + case USB_CLASS_PER_INTERFACE: + if ((config0->interface[intf].num_altsetting == 0) + || !config0->interface[intf].altsetting) + break; + switch (config0->interface[intf].altsetting[0].bInterfaceClass) + { + case USB_CLASS_VENDOR_SPEC: + case USB_CLASS_PER_INTERFACE: + case 16: /* data? */ + ++is_scanner; + break; + } + break; + } + } + + if (is_scanner > 0) + { + char *chipset = NULL; + + if(!from_file) + chipset = check_usb_chip (verbose, desc, hdl, config0); + + printf ("found USB scanner (vendor=0x%04x", vid); + if (vendor) + printf (" [%s]", vendor); + printf (", product=0x%04x", pid); + if (product) + printf (" [%s]", product); + if (chipset) + printf (", chip=%s", chipset); + if (from_file) + printf (")\n"); + else + printf (") at libusb:%03d:%03d\n", busno, address); + + libusb_device_found = SANE_TRUE; + device_found = SANE_TRUE; + } + + libusb_free_config_descriptor (config0); + + out_free: + libusb_close (hdl); + if (vendor) + free (vendor); + + if (product) + free (product); +} +#endif /* HAVE_LIBUSB */ + + +static DIR * +scan_directory (char *dir_name) +{ + struct stat stat_buf; + DIR *dir; + + if (verbose > 2) + printf ("scanning directory %s\n", dir_name); + + if (stat (dir_name, &stat_buf) < 0) + { + if (verbose > 1) + printf ("cannot stat `%s' (%s)\n", dir_name, strerror (errno)); + return 0; + } + if (!S_ISDIR (stat_buf.st_mode)) + { + if (verbose > 1) + printf ("`%s' is not a directory\n", dir_name); + return 0; + } + if ((dir = opendir (dir_name)) == 0) + { + if (verbose > 1) + printf ("cannot read directory `%s' (%s)\n", dir_name, + strerror (errno)); + return 0; + } + return dir; +} + +static char * +get_next_file (char *dir_name, DIR * dir) +{ + struct dirent *dir_entry; + static char file_name[PATH_MAX]; + + do + { + dir_entry = readdir (dir); + if (!dir_entry) + return 0; + } + while (strcmp (dir_entry->d_name, ".") == 0 + || strcmp (dir_entry->d_name, "..") == 0); + + if (strlen (dir_name) + strlen (dir_entry->d_name) + 1 > PATH_MAX) + { + if (verbose > 1) + printf ("filename too long\n"); + return 0; + } + sprintf (file_name, "%s%s", dir_name, dir_entry->d_name); + return file_name; +} + +#if defined(WIN32_SCSI) +/* Return a list of potential scanners. There's a lot of hardcoded values here that might break on a system with lots of scsi devices. */ +static char **build_scsi_dev_list(void) +{ + char **dev_list; + int dev_list_index; + int hca; + HANDLE fd; + char scsi_hca_name[20]; + char buffer[4096]; + DWORD BytesReturned; + BOOL ret; + size_t dev_list_size; + PSCSI_ADAPTER_BUS_INFO adapter; + PSCSI_INQUIRY_DATA inquiry; + int i; + + /* Allocate room for about 100 scanners. That should be enough. */ + dev_list_size = 100; + dev_list_index = 0; + dev_list = calloc(1, dev_list_size * sizeof(char *)); + + hca = 0; + + for(hca = 0; ; hca++) { + + /* Open the adapter */ + snprintf(scsi_hca_name, 20, "\\\\.\\Scsi%d:", hca); + fd = CreateFile(scsi_hca_name, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, + FILE_FLAG_RANDOM_ACCESS, NULL ); + + if (fd == INVALID_HANDLE_VALUE) { + /* Assume there is no more adapter. This is wrong in the case + * of hot-plug stuff, but I have yet to see it on a user + * machine. */ + break; + } + + /* Get the inquiry info for the devices on that hca. */ + ret = DeviceIoControl(fd, + IOCTL_SCSI_GET_INQUIRY_DATA, + NULL, + 0, + buffer, + sizeof(buffer), + &BytesReturned, + FALSE); + + if(ret == 0) + { + CloseHandle(fd); + continue; + } + + adapter = (PSCSI_ADAPTER_BUS_INFO)buffer; + + for(i = 0; i < adapter->NumberOfBuses; i++) { + + if (adapter->BusData[i].InquiryDataOffset == 0) { + /* No device here */ + continue; + } + + inquiry = (PSCSI_INQUIRY_DATA) (buffer + + adapter->BusData[i].InquiryDataOffset); + while(1) { + /* Check if it is a scanner or a processor + * device. Ignore the other + * device types. */ + if (inquiry->InquiryDataLength >= 5 && + ((inquiry->InquiryData[0] & 0x1f) == 3 || + (inquiry->InquiryData[0] & 0x1f) == 6)) { + char device_name[20]; + sprintf(device_name, "h%db%dt%dl%d", hca, inquiry->PathId, inquiry->TargetId, inquiry->Lun); + dev_list[dev_list_index] = strdup(device_name); + dev_list_index++; + } + + if (inquiry->NextInquiryDataOffset == 0) { + /* No device here */ + break; + } else { + inquiry = (PSCSI_INQUIRY_DATA) (buffer + + inquiry->NextInquiryDataOffset); + } + } + } + + CloseHandle(fd); + + } + + return dev_list; + +} +#endif + +#if defined (HAVE_IOKIT_CDB_IOSCSILIB_H) || \ + defined (HAVE_IOKIT_SCSI_SCSICOMMANDOPERATIONCODES_H) || \ + defined (HAVE_IOKIT_SCSI_COMMANDS_SCSICOMMANDOPERATIONCODES_H) +char **scsi_dev_list; +int scsi_dev_list_index; + +static SANE_Status AddToSCSIDeviceList (const char *dev) { + if (scsi_dev_list_index < 99) { + scsi_dev_list [scsi_dev_list_index] = strdup (dev); + scsi_dev_list_index++; + return SANE_STATUS_GOOD; + } + else + return SANE_STATUS_NO_MEM; +} + +static char **build_scsi_dev_list(void) +{ + scsi_dev_list_index = 0; + scsi_dev_list = malloc (100 * sizeof(char *)); + sanei_scsi_find_devices (NULL, NULL, NULL, -1, -1, -1, -1, + AddToSCSIDeviceList); + scsi_dev_list [scsi_dev_list_index] = NULL; + return scsi_dev_list; +} +#endif + +static int +check_mustek_pp_device (void) +{ + const char **devices; + int ctr = 0, found = 0, scsi = 0; + + if (verbose > 1) + printf ("searching for Mustek parallel port scanners:\n"); + + devices = sanei_pa4s2_devices (); + + while (devices[ctr] != NULL) { + int fd; + SANE_Status result; + + /* ordinary parallel port scanner type */ + if (verbose > 1) + printf ("checking %s...", devices[ctr]); + + result = sanei_pa4s2_open (devices[ctr], &fd); + + if (verbose > 1) + { + if (result != 0) + printf (" failed to open (%s)\n", sane_strstatus (result)); + else + printf (" open ok\n"); + } + + if (result == 0) { + printf ("found possible Mustek parallel port scanner at \"%s\"\n", + devices[ctr]); + found++; + sanei_pa4s2_close(fd); + } + + /* trying scsi over pp devices */ + if (verbose > 1) + printf ("checking %s (SCSI emulation)...", devices[ctr]); + + result = sanei_pa4s2_scsi_pp_open (devices[ctr], &fd); + + if (verbose > 1) + { + if (result != 0) + printf (" failed to open (%s)\n", sane_strstatus (result)); + else + printf (" open ok\n"); + } + + if (result == 0) { + printf ("found possible Mustek SCSI over PP scanner at \"%s\"\n", + devices[ctr]); + scsi++; + sanei_pa4s2_close(fd); + } + + ctr++; + } + + free(devices); + + if (found > 0 && verbose > 0) + printf("\n # Your Mustek parallel port scanner was detected. It may or\n" + " # may not be supported by SANE. Please read the sane-mustek_pp\n" + " # man-page for setup instructions.\n"); + + if (scsi > 0 && verbose > 0) + printf("\n # Your Mustek parallel port scanner was detected. It may or\n" + " # may not be supported by SANE. Please read the sane-mustek_pp\n" + " # man-page for setup instructions.\n"); + + return (found > 0 || scsi > 0); +} + +#ifdef HAVE_LIBUSB_LEGACY +static SANE_Bool +parse_num (char* search, const char* line, int base, long int * number) +{ + char* start_number; + + start_number = strstr (line, search); + if (start_number == NULL) + return SANE_FALSE; + start_number += strlen (search); + + *number = strtol (start_number, NULL, base); + if (verbose > 2) + printf ("Found %s%ld\n", search, *number); + return SANE_TRUE; +} + +static SANE_Bool +parse_bcd (char* search, const char* line, long int * number) +{ + char* start_number; + char* end_number; + int first_part; + int second_part; + + start_number = strstr (line, search); + if (start_number == NULL) + return SANE_FALSE; + start_number += strlen (search); + + first_part = strtol (start_number, &end_number, 10); + start_number = end_number + 1; /* skip colon */ + second_part = strtol (start_number, NULL, 10); + *number = ((first_part / 10) << 12) + ((first_part % 10) << 8) + + ((second_part / 10) << 4) + (second_part % 10); + if (verbose > 2) + printf ("Found %s%ld\n", search, *number); + return SANE_TRUE; +} + +static void +parse_file (char *filename) +{ + FILE * parsefile; + char line [PATH_MAX], *token; + const char * p; + struct usb_device *dev = 0; + long int number = 0; + int current_config = 1; + int current_if = -1; + int current_as = -1; + int current_ep = -1; + + if (verbose > 1) + printf ("trying to open %s\n", filename); + parsefile = fopen (filename, "r"); + + if (parsefile == NULL) + { + if (verbose > 0) + printf ("opening %s failed: %s\n", filename, strerror (errno)); + return; + } + + while (sanei_config_read (line, PATH_MAX, parsefile)) + { + if (verbose > 2) + printf ("parsing line: `%s'\n", line); + p = sanei_config_get_string (line, &token); + if (!token || !p || token[0] == '\0') + continue; + if (token[1] != ':') + { + if (verbose > 2) + printf ("missing `:'?\n"); + continue; + } + switch (token[0]) + { + case 'T': + if (dev) + check_libusb_device (dev, SANE_TRUE); + dev = calloc (1, sizeof (struct usb_device)); + dev->bus = calloc (1, sizeof (struct usb_bus)); + current_config = 1; + current_if = -1; + current_as = -1; + current_ep = -1; + break; + case 'D': + if (parse_bcd ("Ver=", line, &number)) + dev->descriptor.bcdUSB = number; + if (parse_num ("Cls=", line, 16, &number)) + dev->descriptor.bDeviceClass = number; + if (parse_num ("Sub=", line, 16, &number)) + dev->descriptor.bDeviceSubClass = number; + if (parse_num ("Prot=", line, 16, &number)) + dev->descriptor.bDeviceProtocol = number; + if (parse_num ("MxPS=", line, 10, &number)) + dev->descriptor.bMaxPacketSize0 = number; + if (parse_num ("#Cfgs=", line, 10, &number)) + dev->descriptor.bNumConfigurations = number; + dev->config = calloc (number, sizeof (struct usb_config_descriptor)); + break; + case 'P': + if (parse_num ("Vendor=", line, 16, &number)) + dev->descriptor.idVendor = number; + if (parse_num ("ProdID=", line, 16, &number)) + dev->descriptor.idProduct = number; + if (parse_bcd ("Rev=", line, &number)) + dev->descriptor.bcdDevice = number; + break; + case 'C': + current_if = -1; + current_as = -1; + current_ep = -1; + if (parse_num ("Cfg#=", line, 10, &number)) + { + current_config = number - 1; + dev->config[current_config].bConfigurationValue = number; + } + if (parse_num ("Ifs=", line, 10, &number)) + dev->config[current_config].bNumInterfaces = number; + dev->config[current_config].interface + = calloc (number, sizeof (struct usb_interface)); + if (parse_num ("Atr=", line, 16, &number)) + dev->config[current_config].bmAttributes = number; + if (parse_num ("MxPwr=", line, 10, &number)) + dev->config[current_config].MaxPower = number / 2; + break; + case 'I': + current_ep = -1; + if (parse_num ("If#=", line, 10, &number)) + { + if (current_if != number) + { + current_if = number; + current_as = -1; + dev->config[current_config].interface[current_if].altsetting + = calloc (20, sizeof (struct usb_interface_descriptor)); + /* Can't read number of altsettings */ + dev->config[current_config].interface[current_if].num_altsetting = 1; + } + else + dev->config[current_config].interface[current_if].num_altsetting++; + } + if (parse_num ("Alt=", line, 10, &number)) + { + current_as = number; + dev->config[current_config].interface[current_if].altsetting[current_as].bInterfaceNumber + = current_if; + dev->config[current_config].interface[current_if].altsetting[current_as].bAlternateSetting + = current_as; + } + if (parse_num ("#EPs=", line, 10, &number)) + dev->config[current_config].interface[current_if].altsetting[current_as].bNumEndpoints + = number; + dev->config[current_config].interface[current_if].altsetting[current_as].endpoint + = calloc (number, sizeof (struct usb_endpoint_descriptor)); + if (parse_num ("Cls=", line, 16, &number)) + dev->config[current_config].interface[current_if].altsetting[current_as].bInterfaceClass + = number; + if (parse_num ("Sub=", line, 16, &number)) + dev->config[current_config].interface[current_if].altsetting[current_as].bInterfaceSubClass + = number; + if (parse_num ("Prot=", line, 16, &number)) + dev->config[current_config].interface[current_if].altsetting[current_as].bInterfaceProtocol + = number; + break; + case 'E': + current_ep++; + if (parse_num ("Ad=", line, 16, &number)) + dev->config[current_config].interface[current_if].altsetting[current_as] + .endpoint[current_ep].bEndpointAddress = number; + if (parse_num ("Atr=", line, 16, &number)) + dev->config[current_config].interface[current_if].altsetting[current_as] + .endpoint[current_ep].bmAttributes = number; + if (parse_num ("MxPS=", line, 10, &number)) + dev->config[current_config].interface[current_if].altsetting[current_as] + .endpoint[current_ep].wMaxPacketSize = number; + if (parse_num ("Ivl=", line, 10, &number)) + dev->config[current_config].interface[current_if].altsetting[current_as] + .endpoint[current_ep].bInterval = number; + break; + case 'S': + case 'B': + continue; + default: + if (verbose > 1) + printf ("ignoring unknown line identifier: %c\n", token[0]); + continue; + } + free (token); + } + if (dev) + check_libusb_device (dev, SANE_TRUE); + fclose (parsefile); + return; +} +#endif + +int +main (int argc, char **argv) +{ + char **dev_list, **usb_dev_list, *dev_name, **ap; + int enable_pp_checks = SANE_FALSE; + + prog_name = strrchr (argv[0], '/'); + if (prog_name) + ++prog_name; + else + prog_name = argv[0]; + + for (ap = argv + 1; ap < argv + argc; ++ap) + { + if ((*ap)[0] != '-') + break; + switch ((*ap)[1]) + { + case '?': + case 'h': + usage (0); + exit (0); + + case 'v': + ++verbose; + break; + + case 'q': + --verbose; + break; + + case 'f': + force = SANE_TRUE; + break; + + case 'p': + enable_pp_checks = SANE_TRUE; + break; + + case 'F': +#ifdef HAVE_LIBUSB_LEGACY + parse_file ((char *) (*(++ap))); +#elif defined(HAVE_LIBUSB) + printf ("option -F not implemented with libusb-1.0\n"); +#else + printf ("libusb not available: option -F can't be used\n"); +#endif + exit (0); + + case '-': + if (!strcmp((*ap), "--help")) + { + usage (0); + exit (0); + } + // fall through + default: + printf ("unknown option: -%c, try -h for help\n", (*ap)[1]); + exit (0); + } + } + if (ap < argv + argc) + { + dev_list = ap; + usb_dev_list = ap; + } + else + { + static char *default_dev_list[] = { +#if defined(__sgi) + "/dev/scsi/sc0d1l0", "/dev/scsi/sc0d2l0", + "/dev/scsi/sc0d3l0", "/dev/scsi/sc0d4l0", + "/dev/scsi/sc0d5l0", "/dev/scsi/sc0d6l0", + "/dev/scsi/sc0d7l0", "/dev/scsi/sc0d8l0", + "/dev/scsi/sc0d9l0", "/dev/scsi/sc0d10l0", + "/dev/scsi/sc0d11l0", "/dev/scsi/sc0d12l0", + "/dev/scsi/sc0d13l0", "/dev/scsi/sc0d14l0", + "/dev/scsi/sc0d15l0", + "/dev/scsi/sc1d1l0", "/dev/scsi/sc1d2l0", + "/dev/scsi/sc1d3l0", "/dev/scsi/sc1d4l0", + "/dev/scsi/sc1d5l0", "/dev/scsi/sc1d6l0", + "/dev/scsi/sc1d7l0", "/dev/scsi/sc1d8l0", + "/dev/scsi/sc1d9l0", "/dev/scsi/sc1d10l0", + "/dev/scsi/sc1d11l0", "/dev/scsi/sc1d12l0", + "/dev/scsi/sc1d13l0", "/dev/scsi/sc1d14l0", + "/dev/scsi/sc1d15l0", + "/dev/scsi/sc2d1l0", "/dev/scsi/sc2d2l0", + "/dev/scsi/sc2d3l0", "/dev/scsi/sc2d4l0", + "/dev/scsi/sc2d5l0", "/dev/scsi/sc2d6l0", + "/dev/scsi/sc2d7l0", "/dev/scsi/sc2d8l0", + "/dev/scsi/sc2d9l0", "/dev/scsi/sc2d10l0", + "/dev/scsi/sc2d11l0", "/dev/scsi/sc2d12l0", + "/dev/scsi/sc2d13l0", "/dev/scsi/sc2d14l0", + "/dev/scsi/sc2d15l0", + "/dev/scsi/sc3d1l0", "/dev/scsi/sc3d2l0", + "/dev/scsi/sc3d3l0", "/dev/scsi/sc3d4l0", + "/dev/scsi/sc3d5l0", "/dev/scsi/sc3d6l0", + "/dev/scsi/sc3d7l0", "/dev/scsi/sc3d8l0", + "/dev/scsi/sc3d9l0", "/dev/scsi/sc3d10l0", + "/dev/scsi/sc3d11l0", "/dev/scsi/sc3d12l0", + "/dev/scsi/sc3d13l0", "/dev/scsi/sc3d14l0", + "/dev/scsi/sc3d15l0", + "/dev/scsi/sc4d1l0", "/dev/scsi/sc4d2l0", + "/dev/scsi/sc4d3l0", "/dev/scsi/sc4d4l0", + "/dev/scsi/sc4d5l0", "/dev/scsi/sc4d6l0", + "/dev/scsi/sc4d7l0", "/dev/scsi/sc4d8l0", + "/dev/scsi/sc4d9l0", "/dev/scsi/sc4d10l0", + "/dev/scsi/sc4d11l0", "/dev/scsi/sc4d12l0", + "/dev/scsi/sc4d13l0", "/dev/scsi/sc4d14l0", + "/dev/scsi/sc4d15l0", + "/dev/scsi/sc5d1l0", "/dev/scsi/sc5d2l0", + "/dev/scsi/sc5d3l0", "/dev/scsi/sc5d4l0", + "/dev/scsi/sc5d5l0", "/dev/scsi/sc5d6l0", + "/dev/scsi/sc5d7l0", "/dev/scsi/sc5d8l0", + "/dev/scsi/sc5d9l0", "/dev/scsi/sc5d10l0", + "/dev/scsi/sc5d11l0", "/dev/scsi/sc5d12l0", + "/dev/scsi/sc5d13l0", "/dev/scsi/sc5d14l0", + "/dev/scsi/sc5d15l0", + "/dev/scsi/sc6d1l0", "/dev/scsi/sc6d2l0", + "/dev/scsi/sc6d3l0", "/dev/scsi/sc6d4l0", + "/dev/scsi/sc6d5l0", "/dev/scsi/sc6d6l0", + "/dev/scsi/sc6d7l0", "/dev/scsi/sc6d8l0", + "/dev/scsi/sc6d9l0", "/dev/scsi/sc6d10l0", + "/dev/scsi/sc6d11l0", "/dev/scsi/sc6d12l0", + "/dev/scsi/sc6d13l0", "/dev/scsi/sc6d14l0", + "/dev/scsi/sc6d15l0", + "/dev/scsi/sc7d1l0", "/dev/scsi/sc7d2l0", + "/dev/scsi/sc7d3l0", "/dev/scsi/sc7d4l0", + "/dev/scsi/sc7d5l0", "/dev/scsi/sc7d6l0", + "/dev/scsi/sc7d7l0", "/dev/scsi/sc7d8l0", + "/dev/scsi/sc7d9l0", "/dev/scsi/sc7d10l0", + "/dev/scsi/sc7d11l0", "/dev/scsi/sc7d12l0", + "/dev/scsi/sc7d13l0", "/dev/scsi/sc7d14l0", + "/dev/scsi/sc7d15l0", + "/dev/scsi/sc8d1l0", "/dev/scsi/sc8d2l0", + "/dev/scsi/sc8d3l0", "/dev/scsi/sc8d4l0", + "/dev/scsi/sc8d5l0", "/dev/scsi/sc8d6l0", + "/dev/scsi/sc8d7l0", "/dev/scsi/sc8d8l0", + "/dev/scsi/sc8d9l0", "/dev/scsi/sc8d10l0", + "/dev/scsi/sc8d11l0", "/dev/scsi/sc8d12l0", + "/dev/scsi/sc8d13l0", "/dev/scsi/sc8d14l0", + "/dev/scsi/sc8d15l0", + "/dev/scsi/sc9d1l0", "/dev/scsi/sc9d2l0", + "/dev/scsi/sc9d3l0", "/dev/scsi/sc9d4l0", + "/dev/scsi/sc9d5l0", "/dev/scsi/sc9d6l0", + "/dev/scsi/sc9d7l0", "/dev/scsi/sc9d8l0", + "/dev/scsi/sc9d9l0", "/dev/scsi/sc9d10l0", + "/dev/scsi/sc9d11l0", "/dev/scsi/sc9d12l0", + "/dev/scsi/sc9d13l0", "/dev/scsi/sc9d14l0", + "/dev/scsi/sc9d15l0", + "/dev/scsi/sc10d1l0", "/dev/scsi/sc10d2l0", + "/dev/scsi/sc10d3l0", "/dev/scsi/sc10d4l0", + "/dev/scsi/sc10d5l0", "/dev/scsi/sc10d6l0", + "/dev/scsi/sc10d7l0", "/dev/scsi/sc10d8l0", + "/dev/scsi/sc10d9l0", "/dev/scsi/sc10d10l0", + "/dev/scsi/sc10d11l0", "/dev/scsi/sc10d12l0", + "/dev/scsi/sc10d13l0", "/dev/scsi/sc10d14l0", + "/dev/scsi/sc10d15l0", + "/dev/scsi/sc11d1l0", "/dev/scsi/sc11d2l0", + "/dev/scsi/sc11d3l0", "/dev/scsi/sc11d4l0", + "/dev/scsi/sc11d5l0", "/dev/scsi/sc11d6l0", + "/dev/scsi/sc11d7l0", "/dev/scsi/sc11d8l0", + "/dev/scsi/sc11d9l0", "/dev/scsi/sc11d10l0", + "/dev/scsi/sc11d11l0", "/dev/scsi/sc11d12l0", + "/dev/scsi/sc11d13l0", "/dev/scsi/sc11d14l0", + "/dev/scsi/sc11d15l0", + "/dev/scsi/sc12d1l0", "/dev/scsi/sc12d2l0", + "/dev/scsi/sc12d3l0", "/dev/scsi/sc12d4l0", + "/dev/scsi/sc12d5l0", "/dev/scsi/sc12d6l0", + "/dev/scsi/sc12d7l0", "/dev/scsi/sc12d8l0", + "/dev/scsi/sc12d9l0", "/dev/scsi/sc12d10l0", + "/dev/scsi/sc12d11l0", "/dev/scsi/sc12d12l0", + "/dev/scsi/sc12d13l0", "/dev/scsi/sc12d14l0", + "/dev/scsi/sc12d15l0", + "/dev/scsi/sc13d1l0", "/dev/scsi/sc13d2l0", + "/dev/scsi/sc13d3l0", "/dev/scsi/sc13d4l0", + "/dev/scsi/sc13d5l0", "/dev/scsi/sc13d6l0", + "/dev/scsi/sc13d7l0", "/dev/scsi/sc13d8l0", + "/dev/scsi/sc13d9l0", "/dev/scsi/sc13d10l0", + "/dev/scsi/sc13d11l0", "/dev/scsi/sc13d12l0", + "/dev/scsi/sc13d13l0", "/dev/scsi/sc13d14l0", + "/dev/scsi/sc13d15l0", + "/dev/scsi/sc14d1l0", "/dev/scsi/sc14d2l0", + "/dev/scsi/sc14d3l0", "/dev/scsi/sc14d4l0", + "/dev/scsi/sc14d5l0", "/dev/scsi/sc14d6l0", + "/dev/scsi/sc14d7l0", "/dev/scsi/sc14d8l0", + "/dev/scsi/sc14d9l0", "/dev/scsi/sc14d10l0", + "/dev/scsi/sc14d11l0", "/dev/scsi/sc14d12l0", + "/dev/scsi/sc14d13l0", "/dev/scsi/sc14d14l0", + "/dev/scsi/sc14d15l0", + "/dev/scsi/sc15d1l0", "/dev/scsi/sc15d2l0", + "/dev/scsi/sc15d3l0", "/dev/scsi/sc15d4l0", + "/dev/scsi/sc15d5l0", "/dev/scsi/sc15d6l0", + "/dev/scsi/sc15d7l0", "/dev/scsi/sc15d8l0", + "/dev/scsi/sc15d9l0", "/dev/scsi/sc15d10l0", + "/dev/scsi/sc15d11l0", "/dev/scsi/sc15d12l0", + "/dev/scsi/sc15d13l0", "/dev/scsi/sc15d14l0", + "/dev/scsi/sc15d15l0", +#elif defined(__EMX__) + "b0t0l0", "b0t1l0", "b0t2l0", "b0t3l0", + "b0t4l0", "b0t5l0", "b0t6l0", "b0t7l0", + "b1t0l0", "b1t1l0", "b1t2l0", "b1t3l0", + "b1t4l0", "b1t5l0", "b1t6l0", "b1t7l0", + "b2t0l0", "b2t1l0", "b2t2l0", "b2t3l0", + "b2t4l0", "b2t5l0", "b2t6l0", "b2t7l0", + "b3t0l0", "b3t1l0", "b3t2l0", "b3t3l0", + "b3t4l0", "b3t5l0", "b3t6l0", "b3t7l0", +#elif defined(__linux__) + "/dev/scanner", + "/dev/sg0", "/dev/sg1", "/dev/sg2", "/dev/sg3", + "/dev/sg4", "/dev/sg5", "/dev/sg6", "/dev/sg7", + "/dev/sg8", "/dev/sg9", + "/dev/sga", "/dev/sgb", "/dev/sgc", "/dev/sgd", + "/dev/sge", "/dev/sgf", "/dev/sgg", "/dev/sgh", + "/dev/sgi", "/dev/sgj", "/dev/sgk", "/dev/sgl", + "/dev/sgm", "/dev/sgn", "/dev/sgo", "/dev/sgp", + "/dev/sgq", "/dev/sgr", "/dev/sgs", "/dev/sgt", + "/dev/sgu", "/dev/sgv", "/dev/sgw", "/dev/sgx", + "/dev/sgy", "/dev/sgz", +#elif defined(__NeXT__) + "/dev/sg0a", "/dev/sg0b", "/dev/sg0c", "/dev/sg0d", + "/dev/sg0e", "/dev/sg0f", "/dev/sg0g", "/dev/sg0h", + "/dev/sg1a", "/dev/sg1b", "/dev/sg1c", "/dev/sg1d", + "/dev/sg1e", "/dev/sg1f", "/dev/sg1g", "/dev/sg1h", + "/dev/sg2a", "/dev/sg2b", "/dev/sg2c", "/dev/sg2d", + "/dev/sg2e", "/dev/sg2f", "/dev/sg2g", "/dev/sg2h", + "/dev/sg3a", "/dev/sg3b", "/dev/sg3c", "/dev/sg3d", + "/dev/sg3e", "/dev/sg3f", "/dev/sg3g", "/dev/sg3h", +#elif defined(_AIX) + "/dev/scanner", + "/dev/gsc0", "/dev/gsc1", "/dev/gsc2", "/dev/gsc3", + "/dev/gsc4", "/dev/gsc5", "/dev/gsc6", "/dev/gsc7", + "/dev/gsc8", "/dev/gsc9", "/dev/gsc10", "/dev/gsc11", + "/dev/gsc12", "/dev/gsc13", "/dev/gsc14", "/dev/gsc15", +#elif defined(__sun) + "/dev/scg0a", "/dev/scg0b", "/dev/scg0c", "/dev/scg0d", + "/dev/scg0e", "/dev/scg0f", "/dev/scg0g", + "/dev/scg1a", "/dev/scg1b", "/dev/scg1c", "/dev/scg1d", + "/dev/scg1e", "/dev/scg1f", "/dev/scg1g", + "/dev/scg2a", "/dev/scg2b", "/dev/scg2c", "/dev/scg2d", + "/dev/scg2e", "/dev/scg2f", "/dev/scg2g", + "/dev/sg/0", "/dev/sg/1", "/dev/sg/2", "/dev/sg/3", + "/dev/sg/4", "/dev/sg/5", "/dev/sg/6", + "/dev/scsi/scanner/", "/dev/scsi/processor/", +#elif defined(HAVE_CAMLIB_H) + "/dev/scanner", "/dev/scanner0", "/dev/scanner1", + "/dev/pass0", "/dev/pass1", "/dev/pass2", "/dev/pass3", + "/dev/pass4", "/dev/pass5", "/dev/pass6", "/dev/pass7", +#elif defined(__FreeBSD__) || defined(__DragonFly__) + "/dev/uk0", "/dev/uk1", "/dev/uk2", "/dev/uk3", "/dev/uk4", + "/dev/uk5", "/dev/uk6", +#elif defined(__NetBSD__) + "/dev/uk0", "/dev/uk1", "/dev/uk2", "/dev/uk3", "/dev/uk4", + "/dev/uk5", "/dev/uk6", + "/dev/ss0", +#elif defined(__OpenBSD__) + "/dev/uk0", "/dev/uk1", "/dev/uk2", "/dev/uk3", "/dev/uk4", + "/dev/uk5", "/dev/uk6", +#elif defined(__hpux) + "/dev/rscsi/", +#endif + 0 + }; + static char *usb_default_dev_list[] = { +#if defined(__linux__) + "/dev/usb/scanner", + "/dev/usb/scanner0", "/dev/usb/scanner1", + "/dev/usb/scanner2", "/dev/usb/scanner3", + "/dev/usb/scanner4", "/dev/usb/scanner5", + "/dev/usb/scanner5", "/dev/usb/scanner7", + "/dev/usb/scanner8", "/dev/usb/scanner9", + "/dev/usb/scanner10", "/dev/usb/scanner11", + "/dev/usb/scanner12", "/dev/usb/scanner13", + "/dev/usb/scanner14", "/dev/usb/scanner15", + "/dev/usbscanner", + "/dev/usbscanner0", "/dev/usbscanner1", + "/dev/usbscanner2", "/dev/usbscanner3", + "/dev/usbscanner4", "/dev/usbscanner5", + "/dev/usbscanner6", "/dev/usbscanner7", + "/dev/usbscanner8", "/dev/usbscanner9", + "/dev/usbscanner10", "/dev/usbscanner11", + "/dev/usbscanner12", "/dev/usbscanner13", + "/dev/usbscanner14", "/dev/usbscanner15", +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) + "/dev/uscanner", + "/dev/uscanner0", "/dev/uscanner1", + "/dev/uscanner2", "/dev/uscanner3", + "/dev/uscanner4", "/dev/uscanner5", + "/dev/uscanner6", "/dev/uscanner7", + "/dev/uscanner8", "/dev/uscanner9", + "/dev/uscanner10", "/dev/uscanner11", + "/dev/uscanner12", "/dev/uscanner13", + "/dev/uscanner14", "/dev/uscanner15", +#endif + 0 + }; + +#if defined (WIN32_SCSI) || \ + defined (HAVE_IOKIT_CDB_IOSCSILIB_H) || \ + defined (HAVE_IOKIT_SCSI_SCSICOMMANDOPERATIONCODES_H) || \ + defined (HAVE_IOKIT_SCSI_COMMANDS_SCSICOMMANDOPERATIONCODES_H) + /* Build a list of valid of possible scanners found */ + dev_list = build_scsi_dev_list(); +#else + dev_list = default_dev_list; +#endif + + usb_dev_list = usb_default_dev_list; + } + if (verbose > 1) + printf ("This is sane-find-scanner from %s\n", PACKAGE_STRING); + + if (verbose > 0) + printf ("\n # sane-find-scanner will now attempt to detect your scanner. If the" + "\n # result is different from what you expected, first make sure your" + "\n # scanner is powered up and properly connected to your computer.\n\n"); + + if (verbose > 1) + printf ("searching for SCSI scanners:\n"); + + while ((dev_name = *dev_list++)) + { + if (strlen (dev_name) == 0) + continue; /* Empty device names ... */ + + if (dev_name[strlen (dev_name) - 1] == '/') + { + /* check whole directories */ + DIR *dir; + char *file_name; + + dir = scan_directory (dev_name); + if (!dir) + continue; + + while ((file_name = get_next_file (dev_name, dir))) + check_scsi_file (file_name); + } + else + { + /* check device files */ + check_scsi_file (dev_name); + } + } + if (device_found) + { + if (verbose > 0) + printf + (" # Your SCSI scanner was detected. It may or may not be " + "supported by SANE. Try\n # scanimage -L and read the backend's " + "manpage.\n"); + } + else + { + if (verbose > 0) + printf + (" # No SCSI scanners found. If you expected something different, " + "make sure that\n # you have loaded a kernel SCSI driver for your SCSI " + "adapter.\n"); + if (!check_sg ()) + { + if (verbose > 0) + printf + (" # Also you need support for SCSI Generic (sg) in your " + "operating system.\n # If using Linux, try \"modprobe " + "sg\".\n"); + } + } + if (verbose > 0) + printf ("\n"); + device_found = SANE_FALSE; + sanei_usb_init (); + if (verbose > 1) + printf ("searching for USB scanners:\n"); + + while ((dev_name = *usb_dev_list++)) + { + if (strlen (dev_name) == 0) + continue; /* Empty device names ... */ + + if (dev_name[strlen (dev_name) - 1] == '/') + { + /* check whole directories */ + DIR *dir; + char *file_name; + + dir = scan_directory (dev_name); + if (!dir) + continue; + + while ((file_name = get_next_file (dev_name, dir))) + check_usb_file (file_name); + } + else + { + /* check device files */ + check_usb_file (dev_name); + } + } +#ifdef HAVE_LIBUSB_LEGACY + /* Now the libusb devices */ + { + struct usb_bus *bus; + struct usb_device *dev; + + if (ap < argv + argc) + { + /* user-specified devices not useful for libusb */ + if (verbose > 1) + printf ("ignoring libusb devices\n"); + } + else + { + if (verbose > 2) + printf ("trying libusb:\n"); + for (bus = usb_get_busses (); bus; bus = bus->next) + { + for (dev = bus->devices; dev; dev = dev->next) + { + check_libusb_device (dev, SANE_FALSE); + } /* for (dev) */ + } /* for (bus) */ + } + } +#elif defined(HAVE_LIBUSB) + /* Now the libusb-1.0 devices */ + { + if (ap < argv + argc) + { + /* user-specified devices not useful for libusb */ + if (verbose > 1) + printf ("ignoring libusb devices\n"); + } + else + { + libusb_device **devlist; + ssize_t devcnt; + int i; + int ret; + + if (verbose > 2) + printf ("trying libusb:\n"); + + ret = libusb_init (&sfs_usb_ctx); + if (ret < 0) + { + printf ("# Could not initialize libusb-1.0, error %d\n", ret); + printf ("# Skipping libusb devices\n"); + + goto failed_libusb_1_0; + } + + if (verbose > 3) +#if LIBUSB_API_VERSION >= 0x01000106 + libusb_set_option (sfs_usb_ctx, LIBUSB_OPTION_LOG_LEVEL, + LIBUSB_LOG_LEVEL_INFO); +#else + libusb_set_debug (sfs_usb_ctx, 3); +#endif + + devcnt = libusb_get_device_list (sfs_usb_ctx, &devlist); + if (devcnt < 0) + { + printf ("# Could not get device list, error %d\n", ret); + + goto deinit_libusb_1_0; + } + + for (i = 0; i < devcnt; i++) + { + check_libusb_device (devlist[i], SANE_FALSE); + } + + libusb_free_device_list (devlist, 1); + + deinit_libusb_1_0: + libusb_exit (sfs_usb_ctx); + + failed_libusb_1_0: + ; /* init failed, jumping here */ + } + } +#else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */ + if (verbose > 1) + printf ("libusb not available\n"); +#endif /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */ + + if (device_found) + { + if (libusb_device_found) + { + if (verbose > 0) + printf + (" # Your USB scanner was (probably) detected. It " + "may or may not be supported by\n # SANE. Try scanimage " + "-L and read the backend's manpage.\n"); + } + else if (verbose > 0) + printf + (" # Your USB scanner was detected. It may or may not " + "be supported by\n # SANE. Try scanimage -L and read the " + "backend's manpage.\n"); + if (unknown_found && verbose > 0) + printf + (" # `UNKNOWN vendor and product' means that there seems to be a " + "scanner at this\n # device file but the vendor and product ids " + "couldn't be identified.\n # Currently identification only works " + "with Linux versions >= 2.4.8. You may\n # need to configure your " + "backend manually, see the backend's manpage.\n"); + } + else + { + if (verbose > 0) + printf + (" # No USB scanners found. If you expected something different, " + "make sure that\n # you have loaded a kernel driver for your USB host " + "controller and have setup\n # the USB system correctly. " + "See man sane-usb for details.\n"); +#if !defined(HAVE_LIBUSB_LEGACY) && !defined(HAVE_LIBUSB) + if (verbose > 0) + printf (" # SANE has been built without libusb support. This may be a " + "reason\n # for not detecting USB scanners. Read README for " + "more details.\n"); +#endif + } + if (enable_pp_checks == SANE_TRUE) + { + if (!check_mustek_pp_device() && verbose > 0) + printf ("\n # No Mustek parallel port scanners found. If you expected" + " something\n # different, make sure the scanner is correctly" + " connected to your computer\n # and you have appropriate" + " access rights.\n"); + } + else if (verbose > 0) + printf ("\n # Not checking for parallel port scanners.\n"); + if (verbose > 0) + printf ("\n # Most Scanners connected to the parallel port or other " + "proprietary ports\n # can't be detected by this program.\n"); +#ifdef HAVE_GETUID + if (getuid ()) + if (verbose > 0) + printf + ("\n # You may want to run this program as root to find all devices. " + "Once you\n # found the scanner devices, be sure to adjust access " + "permissions as\n # necessary.\n"); +#endif + + if (verbose > 1) + printf ("done\n"); + + return 0; +} diff --git a/tools/sane-find-scanner.c.rej b/tools/sane-find-scanner.c.rej new file mode 100644 index 0000000..719a906 --- /dev/null +++ b/tools/sane-find-scanner.c.rej @@ -0,0 +1,22 @@ +--- tools/sane-find-scanner.c ++++ tools/sane-find-scanner.c +@@ -384,7 +384,7 @@ check_usb_file (char *file_name) + { + if (verbose > 1) + printf (" open ok, vendor and product ids were identified\n"); +- printf ("found USB scanner (vendor=0x%04x, " ++ printf ("found possible USB scanner (vendor=0x%04x, " + "product=0x%04x) at %s\n", vendor, product, file_name); + } + else +@@ -392,8 +392,8 @@ check_usb_file (char *file_name) + if (verbose > 1) + printf (" open ok, but vendor and product could NOT be " + "identified\n"); +- printf ("found USB scanner (UNKNOWN vendor and product) " +- "at device %s\n", file_name); ++ printf ("found possible USB scanner (UNKNOWN vendor and " ++ "product) at %s\n", file_name); + unknown_found = SANE_TRUE; + } + device_found = SANE_TRUE; -- cgit v1.2.3 From f489006c92d580eb2e391ab3a5bdd49520b4941d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 21 Feb 2022 13:11:55 +0100 Subject: New debian/patches/0185-Change_output_from_sane-find-scanner.patch --- debian/changelog | 4 +- ...0185-Change_output_from_sane-find-scanner.patch | 51 ++++++++++++++++++++++ debian/patches/series | 1 + 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 debian/patches/0185-Change_output_from_sane-find-scanner.patch diff --git a/debian/changelog b/debian/changelog index e977760..cd0c51d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -10,13 +10,15 @@ sane-backends (1.1.1-3) UNRELEASED; urgency=medium * debian/control: - Add Recommends: sane-airscan to libsane1 (Closes: 1005817). * Move man page sane-umax_pp.5 back to libsane-common (Closes: #1005736): - - debian/rules: + - debian/rules: - Remove delete manpage vom libsane-common. - New debian/sane-utils.preinst to remove man page and sysmlink. - debian/sane-utils.link: - Remove create link from sane-umax_pp.5 - debian/control: - Add new Breaks and Replace. + * New debian/patches/0185-Change_output_from_sane-find-scanner.patch: + - Improve output for possible USB scanners (Closes: #983332). -- Jörg Frings-Fürst Mon, 14 Feb 2022 21:28:17 +0100 diff --git a/debian/patches/0185-Change_output_from_sane-find-scanner.patch b/debian/patches/0185-Change_output_from_sane-find-scanner.patch new file mode 100644 index 0000000..ee4bc1a --- /dev/null +++ b/debian/patches/0185-Change_output_from_sane-find-scanner.patch @@ -0,0 +1,51 @@ +Description: Improve output for possible USB scanners +Author: Ralph Little +Origin: upstream, https://gitlab.com/sane-project/backends/-/commit/b701c499c9ce56c6bbea14b2fac2feea37f2410f +Bug: https://gitlab.com/sane-project/backends/-/issues/575 +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=983332 +Forwarded: not-needed +Applied-Upstream: commit b701c499c9ce56c6bbea14b2fac2feea37f2410f +Last-Update: 2022-02-21 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: trunk/tools/sane-find-scanner.c +=================================================================== +--- trunk.orig/tools/sane-find-scanner.c ++++ trunk/tools/sane-find-scanner.c +@@ -384,7 +384,7 @@ check_usb_file (char *file_name) + { + if (verbose > 1) + printf (" open ok, vendor and product ids were identified\n"); +- printf ("found USB scanner (vendor=0x%04x, " ++ printf ("found possible USB scanner (vendor=0x%04x, " + "product=0x%04x) at %s\n", vendor, product, file_name); + } + else +@@ -392,7 +392,7 @@ check_usb_file (char *file_name) + if (verbose > 1) + printf (" open ok, but vendor and product could NOT be " + "identified\n"); +- printf ("found USB scanner (UNKNOWN vendor and product) " ++ printf ("found possible USB scanner (UNKNOWN vendor and product) " + "at device %s\n", file_name); + unknown_found = SANE_TRUE; + } +@@ -676,7 +676,8 @@ check_libusb_device (struct usb_device * + { + char * chipset = check_usb_chip (dev, verbose, from_file); + +- printf ("found USB scanner (vendor=0x%04x", dev->descriptor.idVendor); ++ printf ("found possible USB scanner (vendor=0x%04x", ++ dev->descriptor.idVendor); + if (vendor) + printf (" [%s]", vendor); + printf (", product=0x%04x", dev->descriptor.idProduct); +@@ -1066,7 +1067,7 @@ check_libusb_device (libusb_device *dev, + if(!from_file) + chipset = check_usb_chip (verbose, desc, hdl, config0); + +- printf ("found USB scanner (vendor=0x%04x", vid); ++ printf ("found possible USB scanner (vendor=0x%04x", vid); + if (vendor) + printf (" [%s]", vendor); + printf (", product=0x%04x", pid); diff --git a/debian/patches/series b/debian/patches/series index a1dd4c2..31378d7 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -18,3 +18,4 @@ #0170-return_empty_list_when_local_devices_requested.patch 0605-fix_groff-warnings.patch #0180-gt68xx_fix_use-after-free_two_memleaks.patch +0185-Change_output_from_sane-find-scanner.patch -- cgit v1.2.3 From 6934a0f18c5678fe570ec18ac700fef97610930b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 21 Feb 2022 13:20:49 +0100 Subject: Add some debian files / dirs into .gitignore --- .gitignore | 5 +++++ .pc/.quilt_patches | 1 - .pc/.quilt_series | 1 - 3 files changed, 5 insertions(+), 2 deletions(-) delete mode 100644 .pc/.quilt_patches delete mode 100644 .pc/.quilt_series diff --git a/.gitignore b/.gitignore index bd3b383..7daab1f 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,8 @@ test-suite.log # `make dist` artifacts /sane-backends-*.tar.gz + + +# debian +.pc +debian/files diff --git a/.pc/.quilt_patches b/.pc/.quilt_patches deleted file mode 100644 index 6857a8d..0000000 --- a/.pc/.quilt_patches +++ /dev/null @@ -1 +0,0 @@ -debian/patches diff --git a/.pc/.quilt_series b/.pc/.quilt_series deleted file mode 100644 index c206706..0000000 --- a/.pc/.quilt_series +++ /dev/null @@ -1 +0,0 @@ -series -- cgit v1.2.3 From 9f6168979f9f9cc7d6f394f2d888a18e2ebc916f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 21 Feb 2022 14:37:28 +0100 Subject: Refesh symbols file --- debian/changelog | 2 ++ debian/libsane1.symbols | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index cd0c51d..a862b6d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -19,6 +19,8 @@ sane-backends (1.1.1-3) UNRELEASED; urgency=medium - Add new Breaks and Replace. * New debian/patches/0185-Change_output_from_sane-find-scanner.patch: - Improve output for possible USB scanners (Closes: #983332). + * debian/libsane1.symbols: + - Add !kfreebsd-any to missing symbol. -- Jörg Frings-Fürst Mon, 14 Feb 2022 21:28:17 +0100 diff --git a/debian/libsane1.symbols b/debian/libsane1.symbols index 69ecbbb..b32e02e 100644 --- a/debian/libsane1.symbols +++ b/debian/libsane1.symbols @@ -1,6 +1,6 @@ libsane.so.1 libsane1 #MINVER# * Build-Depends-Package: libsane-dev - (arch=!hurd-i386)cmsg@Base 1.0.29 + (arch=!hurd-i386 !kfreebsd-any)cmsg@Base 1.0.29 fail_test@Base 1.0.29 md5_buffer@Base 1.0.27 md5_finish_ctx@Base 1.0.27 -- cgit v1.2.3 From 5f0fc1c52623b9a9f317567478bda73dd64741b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 21 Feb 2022 14:38:52 +0100 Subject: Remove unused .[orig|rej] files --- tools/sane-find-scanner.c.orig | 2108 ---------------------------------------- tools/sane-find-scanner.c.rej | 22 - 2 files changed, 2130 deletions(-) delete mode 100644 tools/sane-find-scanner.c.orig delete mode 100644 tools/sane-find-scanner.c.rej diff --git a/tools/sane-find-scanner.c.orig b/tools/sane-find-scanner.c.orig deleted file mode 100644 index 25e5954..0000000 --- a/tools/sane-find-scanner.c.orig +++ /dev/null @@ -1,2108 +0,0 @@ -/* sane-find-scanner.c - - Copyright (C) 1997-2013 Oliver Rauch, Henning Meier-Geinitz, and others. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - */ - -#include "../include/sane/config.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined (HAVE_DDK_NTDDSCSI_H) || defined (HAVE_NTDDSCSI_H) -# define WIN32_SCSI -# include -# if defined (HAVE_DDK_NTDDSCSI_H) -# include -# include -# elif defined (HAVE_NTDDSCSI_H) -# include -# endif -#endif - -#include "../include/sane/sanei.h" -#include "../include/sane/sanei_scsi.h" -#include "../include/sane/sanei_pa4s2.h" -#include "../include/sane/sanei_config.h" - -#ifdef HAVE_LIBUSB_LEGACY -#ifdef HAVE_LUSB0_USB_H -#include -#else -#include -#endif -extern char * check_usb_chip (struct usb_device *dev, int verbosity, SANE_Bool from_file); -#endif - -#ifdef HAVE_LIBUSB -#include -extern char * check_usb_chip (int verbosity, - struct libusb_device_descriptor desc, - libusb_device_handle *hdl, - struct libusb_config_descriptor *config0); -#endif - -#include "../include/sane/sanei_usb.h" - -#ifndef PATH_MAX -# define PATH_MAX 1024 -#endif - -static const char *prog_name; -static int verbose = 1; -static SANE_Bool force = SANE_FALSE; -static SANE_Bool device_found = SANE_FALSE; -static SANE_Bool libusb_device_found = SANE_FALSE; -static SANE_Bool unknown_found = SANE_FALSE; - -#ifdef HAVE_LIBUSB -libusb_context *sfs_usb_ctx; -#endif - -typedef struct -{ - unsigned char *cmd; - size_t size; -} -scsiblk; - -#define INQUIRY 0x12 -#define set_inquiry_return_size(icb,val) icb[0x04]=val -#define IN_periph_devtype_cpu 0x03 -#define IN_periph_devtype_scanner 0x06 -#define get_scsi_inquiry_vendor(in, buf) strncpy(buf, in + 0x08, 0x08) -#define get_scsi_inquiry_product(in, buf) strncpy(buf, in + 0x10, 0x010) -#define get_scsi_inquiry_version(in, buf) strncpy(buf, in + 0x20, 0x04) -#define get_scsi_inquiry_periph_devtype(in) (in[0] & 0x1f) -#define get_scsi_inquiry_additional_length(in) in[0x04] -#define set_scsi_inquiry_length(out,n) out[0x04]=n-5 - -static unsigned char inquiryC[] = { - INQUIRY, 0x00, 0x00, 0x00, 0xff, 0x00 -}; -static scsiblk inquiry = { - inquiryC, sizeof (inquiryC) -}; - -static void -usage (char *msg) -{ - fprintf (stderr, "Usage: %s [-hvqf] [devname ...]\n", prog_name); - fprintf (stderr, "\t-h: print this help message\n"); - fprintf (stderr, "\t-v: be more verbose (can be used multiple times)\n"); - fprintf (stderr, "\t-q: be quiet (print only devices, no comments)\n"); - fprintf (stderr, "\t-f: force opening devname as SCSI even if it looks " - "like USB\n"); - fprintf (stderr, "\t-p: enable scanning for parallel port devices\n"); -#ifdef HAVE_LIBUSB_LEGACY - fprintf (stderr, "\t-F file: try to detect chipset from given " - "/proc/bus/usb/devices file\n"); -#endif - if (msg) - fprintf (stderr, "\t%s\n", msg); -} - -/* if SCSI generic is optional on your OS, and there is a software test - which will determine if it is included, add it here. If you are sure - that SCSI generic was found, return 1. If SCSI generic is always - available in your OS, return 1 */ - -static int -check_sg (void) -{ -#if defined(__linux__) - /* Assumption: /proc/devices lines are shorter than 256 characters */ - char line[256], driver[256] = ""; - FILE *stream; - - stream = fopen ("/proc/devices", "r"); - /* Likely reason for failure, no /proc => probably no SG either */ - if (stream == NULL) - return 0; - - while (fgets (line, sizeof (line) - 1, stream)) - { - if (sscanf (line, " %*d %s\n", driver) > 0 && !strcmp (driver, "sg")) - break; - } - fclose (stream); - - if (strcmp (driver, "sg")) - { - return 0; - } - else - { - return 1; - } -#endif - return 1; /* Give up, and assume yes to avoid false negatives */ -} - -/* Display a buffer in the log. Display by lines of 16 bytes. */ -static void -hexdump (const char *comment, unsigned char *buf, const int length) -{ - int i; - char line[128]; - char *ptr; - char asc_buf[17]; - char *asc_ptr; - - printf (" %s\n", comment); - - i = 0; - goto start; - - do - { - if (i < length) - { - ptr += sprintf (ptr, " %2.2x", *buf); - - if (*buf >= 32 && *buf <= 127) - { - asc_ptr += sprintf (asc_ptr, "%c", *buf); - } - else - { - asc_ptr += sprintf (asc_ptr, "."); - } - } - else - { - /* After the length; do nothing. */ - ptr += sprintf (ptr, " "); - } - - i++; - buf++; - - if ((i % 16) == 0) - { - /* It's a new line */ - printf (" %s %s\n", line, asc_buf); - - start: - ptr = line; - *ptr = '\0'; - asc_ptr = asc_buf; - *asc_ptr = '\0'; - - ptr += sprintf (ptr, " %3.3d:", i); - } - - } - while (i < ((length + 15) & ~15)); -} - -static SANE_Status -scanner_do_scsi_inquiry (unsigned char *buffer, int sfd) -{ - size_t size; - SANE_Status status; - - memset (buffer, '\0', 256); /* clear buffer */ - - size = 5; /* first get only 5 bytes to get size of - inquiry_return_block */ - set_inquiry_return_size (inquiry.cmd, size); - status = sanei_scsi_cmd (sfd, inquiry.cmd, inquiry.size, buffer, &size); - - if (status != SANE_STATUS_GOOD) - return (status); - - size = get_scsi_inquiry_additional_length (buffer) + 5; - - /* then get inquiry with actual size */ - set_inquiry_return_size (inquiry.cmd, size); - status = sanei_scsi_cmd (sfd, inquiry.cmd, inquiry.size, buffer, &size); - - return (status); -} - -static void -scanner_identify_scsi_scanner (unsigned char *buffer, int sfd, - char *devicename) -{ - unsigned char vendor[9]; - unsigned char product[17]; - unsigned char version[5]; - unsigned char *pp; - unsigned int devtype; - SANE_Status status; - static char *devtypes[] = { - "disk", "tape", "printer", "processor", "CD-writer", - "CD-drive", "scanner", "optical-drive", "jukebox", - "communicator" - }; - status = scanner_do_scsi_inquiry (buffer, sfd); - if (status != SANE_STATUS_GOOD) - { - if (verbose > 1) - printf ("inquiry for device %s failed (%s)\n", - devicename, sane_strstatus (status)); - return; - } - - if (verbose > 2) - hexdump ("Inquiry for device:", buffer, - get_scsi_inquiry_additional_length (buffer) + 5); - - devtype = get_scsi_inquiry_periph_devtype (buffer); - if (verbose <= 1 && devtype != IN_periph_devtype_scanner - /* old HP scanners use the CPU id ... */ - && devtype != IN_periph_devtype_cpu) - return; /* no, continue searching */ - - get_scsi_inquiry_vendor ((char *) buffer, (char *) vendor); - get_scsi_inquiry_product ((char *) buffer, (char *) product); - get_scsi_inquiry_version ((char *) buffer, (char *) version); - - pp = &vendor[7]; - vendor[8] = '\0'; - while (pp >= vendor && (*pp == ' ' || *pp >= 127)) - *pp-- = '\0'; - - pp = &product[15]; - product[16] = '\0'; - while (pp >= product && (*pp == ' ' || *pp >= 127)) - *pp-- = '\0'; - - pp = &version[3]; - version[4] = '\0'; - while (pp >= version && (*pp == ' ' || *(pp - 1) >= 127)) - *pp-- = '\0'; - - device_found = SANE_TRUE; - printf ("found SCSI %s \"%s %s %s\" at %s\n", - devtype < NELEMS (devtypes) ? devtypes[devtype] : "unknown device", - vendor, product, version, devicename); - return; -} - -static void -check_scsi_file (char *file_name) -{ - int result; - int sfd; - unsigned char buffer[16384]; - - if (strstr (file_name, "usb") - || strstr (file_name, "uscanner") || strstr (file_name, "ugen")) - { - if (force) - { - if (verbose > 1) - printf ("checking %s even though it looks like a USB device...", - file_name); - } - else - { - if (verbose > 1) - printf ("ignored %s (not a SCSI device)\n", file_name); - return; - } - } - else if (verbose > 1) - printf ("checking %s...", file_name); - - result = sanei_scsi_open (file_name, &sfd, NULL, NULL); - - if (verbose > 1) - { - if (result != 0) - printf (" failed to open (%s)\n", sane_strstatus (result)); - else - printf (" open ok\n"); - } - - if (result == SANE_STATUS_GOOD) - { - scanner_identify_scsi_scanner (buffer, sfd, file_name); - sanei_scsi_close (sfd); - } - return; -} - -static void -check_usb_file (char *file_name) -{ - SANE_Status result; - SANE_Word vendor, product; - SANE_Int fd; - - if (!strstr (file_name, "usb") - && !strstr (file_name, "uscanner") && !strstr (file_name, "ugen")) - { - if (force) - { - if (verbose > 1) - printf ("checking %s even though doesn't look like a " - "USB device...", file_name); - } - else - { - if (verbose > 1) - printf ("ignored %s (not a USB device)\n", file_name); - return; - } - } - else if (verbose > 1) - printf ("checking %s...", file_name); - - result = sanei_usb_open (file_name, &fd); - - if (result != SANE_STATUS_GOOD) - { - if (verbose > 1) - printf (" failed to open (%s)\n", sane_strstatus (result)); - } - else - { - result = sanei_usb_get_vendor_product (fd, &vendor, &product); - if (result == SANE_STATUS_GOOD) - { - if (verbose > 1) - printf (" open ok, vendor and product ids were identified\n"); - printf ("found USB scanner (vendor=0x%04x, " - "product=0x%04x) at %s\n", vendor, product, file_name); - } - else - { - if (verbose > 1) - printf (" open ok, but vendor and product could NOT be " - "identified\n"); - printf ("found USB scanner (UNKNOWN vendor and product) " - "at device %s\n", file_name); - unknown_found = SANE_TRUE; - } - device_found = SANE_TRUE; - sanei_usb_close (fd); - } -} - -#ifdef HAVE_LIBUSB_LEGACY - -static char * -get_libusb_string_descriptor (struct usb_device *dev, int index) -{ - usb_dev_handle *handle; - char *buffer, short_buffer[2]; - struct usb_string_descriptor *sd; - int size = 2; - int i; - - if (!index) - return 0; - - handle = usb_open (dev); - if (!handle) - return 0; - - sd = (struct usb_string_descriptor *) short_buffer; - - if (usb_control_msg (handle, - USB_ENDPOINT_IN + USB_TYPE_STANDARD + USB_RECIP_DEVICE, - USB_REQ_GET_DESCRIPTOR, - (USB_DT_STRING << 8) + index, 0, short_buffer, - size, 1000) < 0) - { - usb_close (handle); - return 0; - } - - if (sd->bLength < 2 - || sd->bDescriptorType != USB_DT_STRING) - { - usb_close (handle); - return 0; - } - - size = sd->bLength; - - buffer = calloc (1, size + 1); - if (!buffer) - return 0; - - sd = (struct usb_string_descriptor *) buffer; - - if (usb_control_msg (handle, - USB_ENDPOINT_IN + USB_TYPE_STANDARD + USB_RECIP_DEVICE, - USB_REQ_GET_DESCRIPTOR, - (USB_DT_STRING << 8) + index, 0, buffer, - size, 1000) < 0) - { - usb_close (handle); - free (buffer); - return 0; - } - - if (sd->bLength < 2 || sd->bLength > size - || sd->bDescriptorType != USB_DT_STRING) - { - usb_close (handle); - free (buffer); - return 0; - } - size = sd->bLength - 2; - for (i = 0; i < (size / 2); i++) - buffer[i] = buffer[2 + 2 * i]; - buffer[i] = 0; - - usb_close (handle); - return buffer; -} - -static char * -get_libusb_vendor (struct usb_device *dev) -{ - return get_libusb_string_descriptor (dev, dev->descriptor.iManufacturer); -} - -static char * -get_libusb_product (struct usb_device *dev) -{ - return get_libusb_string_descriptor (dev, dev->descriptor.iProduct); -} - -static void -check_libusb_device (struct usb_device *dev, SANE_Bool from_file) -{ - int is_scanner = 0; - char *vendor; - char *product; - int interface_nr; - - if (!dev->config) - { - if (verbose > 1) - printf ("device 0x%04x/0x%04x is not configured\n", - dev->descriptor.idVendor, dev->descriptor.idProduct); - return; - } - - vendor = get_libusb_vendor (dev); - product = get_libusb_product (dev); - - if (verbose > 2) - { - /* print everything we know about the device */ - char *buf; - int config_nr; - struct usb_device_descriptor *d = &dev->descriptor; - - printf ("\n"); - printf ("idVendor, d->idProduct, dev->bus->dirname, dev->filename); - if (vendor || product) - { - printf (" (%s%s%s)", vendor ? vendor : "", - (vendor && product) ? " " : "", product ? product : ""); - } - printf (">\n"); - printf ("bLength %d\n", d->bLength); - printf ("bDescriptorType %d\n", d->bDescriptorType); - printf ("bcdUSB %d.%d%d\n", d->bcdUSB >> 8, - (d->bcdUSB >> 4) & 15, d->bcdUSB & 15); - printf ("bDeviceClass %d\n", d->bDeviceClass); - printf ("bDeviceSubClass %d\n", d->bDeviceSubClass); - printf ("bDeviceProtocol %d\n", d->bDeviceProtocol); - printf ("bMaxPacketSize0 %d\n", d->bMaxPacketSize0); - printf ("idVendor 0x%04X\n", d->idVendor); - printf ("idProduct 0x%04X\n", d->idProduct); - printf ("bcdDevice %d.%d%d\n", d->bcdDevice >> 8, - (d->bcdDevice >> 4) & 15, d->bcdDevice & 15); - printf ("iManufacturer %d (%s)\n", d->iManufacturer, - (vendor) ? vendor : ""); - printf ("iProduct %d (%s)\n", d->iProduct, - (product) ? product : ""); - - buf = get_libusb_string_descriptor (dev, d->iSerialNumber); - printf ("iSerialNumber %d (%s)\n", d->iSerialNumber, - (buf) ? buf : ""); - if (buf) - free (buf); - printf ("bNumConfigurations %d\n", d->bNumConfigurations); - - for (config_nr = 0; config_nr < d->bNumConfigurations; config_nr++) - { - struct usb_config_descriptor *c = &dev->config[config_nr]; - int interface_nr; - - printf (" \n", config_nr); - printf (" bLength %d\n", c->bLength); - printf (" bDescriptorType %d\n", c->bDescriptorType); - printf (" wTotalLength %d\n", c->wTotalLength); - printf (" bNumInterfaces %d\n", c->bNumInterfaces); - printf (" bConfigurationValue %d\n", c->bConfigurationValue); - buf = get_libusb_string_descriptor (dev, c->iConfiguration); - printf (" iConfiguration %d (%s)\n", c->iConfiguration, - (buf) ? buf : ""); - if (buf) - free (buf); - printf (" bmAttributes %d (%s%s)\n", c->bmAttributes, - c->bmAttributes & 64 ? "Self-powered" : "", - c->bmAttributes & 32 ? "Remote Wakeup" : ""); - printf (" MaxPower %d mA\n", c->MaxPower * 2); - - for (interface_nr = 0; interface_nr < c->bNumInterfaces; - interface_nr++) - { - struct usb_interface *interface = &c->interface[interface_nr]; - int alt_setting_nr; - - printf (" \n", interface_nr); - for (alt_setting_nr = 0; - alt_setting_nr < interface->num_altsetting; - alt_setting_nr++) - { - struct usb_interface_descriptor *i - = &interface->altsetting[alt_setting_nr]; - int ep_nr; - printf (" \n", alt_setting_nr); - printf (" bLength %d\n", i->bLength); - printf (" bDescriptorType %d\n", i->bDescriptorType); - printf (" bInterfaceNumber %d\n", i->bInterfaceNumber); - printf (" bAlternateSetting %d\n", i->bAlternateSetting); - printf (" bNumEndpoints %d\n", i->bNumEndpoints); - printf (" bInterfaceClass %d\n", i->bInterfaceClass); - printf (" bInterfaceSubClass %d\n", - i->bInterfaceSubClass); - printf (" bInterfaceProtocol %d\n", - i->bInterfaceProtocol); - buf = get_libusb_string_descriptor (dev, i->iInterface); - printf (" iInterface %d (%s)\n", i->iInterface, - (buf) ? buf : ""); - if (buf) - free (buf); - - for (ep_nr = 0; ep_nr < i->bNumEndpoints; ep_nr++) - { - struct usb_endpoint_descriptor *e = &i->endpoint[ep_nr]; - char *ep_type; - - switch (e->bmAttributes & USB_ENDPOINT_TYPE_MASK) - { - case USB_ENDPOINT_TYPE_CONTROL: - ep_type = "control"; - break; - case USB_ENDPOINT_TYPE_ISOCHRONOUS: - ep_type = "isochronous"; - break; - case USB_ENDPOINT_TYPE_BULK: - ep_type = "bulk"; - break; - case USB_ENDPOINT_TYPE_INTERRUPT: - ep_type = "interrupt"; - break; - default: - ep_type = "unknown"; - break; - } - printf (" \n", ep_nr); - printf (" bLength %d\n", e->bLength); - printf (" bDescriptorType %d\n", - e->bDescriptorType); - printf (" bEndpointAddress 0x%02X (%s 0x%02X)\n", - e->bEndpointAddress, - e->bEndpointAddress & USB_ENDPOINT_DIR_MASK ? - "in" : "out", - e-> - bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK); - printf (" bmAttributes %d (%s)\n", - e->bmAttributes, ep_type); - printf (" wMaxPacketSize %d\n", - e->wMaxPacketSize); - printf (" bInterval %d ms\n", e->bInterval); - printf (" bRefresh %d\n", e->bRefresh); - printf (" bSynchAddress %d\n", e->bSynchAddress); - } - } - } - } - - } - - /* Some heuristics, which device may be a scanner */ - if (dev->descriptor.idVendor == 0) /* hub */ - --is_scanner; - if (dev->descriptor.idProduct == 0) /* hub */ - --is_scanner; - - for (interface_nr = 0; interface_nr < dev->config[0].bNumInterfaces && is_scanner <= 0; interface_nr++) - { - switch (dev->descriptor.bDeviceClass) - { - case USB_CLASS_VENDOR_SPEC: - ++is_scanner; - break; - case USB_CLASS_PER_INTERFACE: - if (dev->config[0].interface[interface_nr].num_altsetting == 0 || - !dev->config[0].interface[interface_nr].altsetting) - break; - switch (dev->config[0].interface[interface_nr].altsetting[0].bInterfaceClass) - { - case USB_CLASS_VENDOR_SPEC: - case USB_CLASS_PER_INTERFACE: - case 16: /* data? */ - ++is_scanner; - break; - } - break; - } - } - - if (is_scanner > 0) - { - char * chipset = check_usb_chip (dev, verbose, from_file); - - printf ("found USB scanner (vendor=0x%04x", dev->descriptor.idVendor); - if (vendor) - printf (" [%s]", vendor); - printf (", product=0x%04x", dev->descriptor.idProduct); - if (product) - printf (" [%s]", product); - if (chipset) - printf (", chip=%s", chipset); - if (from_file) - printf (")\n"); - else - printf (") at libusb:%s:%s\n", dev->bus->dirname, dev->filename); - - libusb_device_found = SANE_TRUE; - device_found = SANE_TRUE; - } - - if (vendor) - free (vendor); - - if (product) - free (product); -} -#endif /* HAVE_LIBUSB_LEGACY */ - - -#ifdef HAVE_LIBUSB -static char * -sfs_libusb_strerror (int errcode) -{ - /* Error codes & descriptions from the libusb-1.0 documentation */ - - switch (errcode) - { - case LIBUSB_SUCCESS: - return "Success (no error)"; - - case LIBUSB_ERROR_IO: - return "Input/output error"; - - case LIBUSB_ERROR_INVALID_PARAM: - return "Invalid parameter"; - - case LIBUSB_ERROR_ACCESS: - return "Access denied (insufficient permissions)"; - - case LIBUSB_ERROR_NO_DEVICE: - return "No such device (it may have been disconnected)"; - - case LIBUSB_ERROR_NOT_FOUND: - return "Entity not found"; - - case LIBUSB_ERROR_BUSY: - return "Resource busy"; - - case LIBUSB_ERROR_TIMEOUT: - return "Operation timed out"; - - case LIBUSB_ERROR_OVERFLOW: - return "Overflow"; - - case LIBUSB_ERROR_PIPE: - return "Pipe error"; - - case LIBUSB_ERROR_INTERRUPTED: - return "System call interrupted (perhaps due to signal)"; - - case LIBUSB_ERROR_NO_MEM: - return "Insufficient memory"; - - case LIBUSB_ERROR_NOT_SUPPORTED: - return "Operation not supported or unimplemented on this platform"; - - case LIBUSB_ERROR_OTHER: - return "Other error"; - - default: - return "Unknown libusb-1.0 error code"; - } -} - -static char * -get_libusb_string_descriptor (libusb_device_handle *hdl, int index) -{ - unsigned char *buffer, short_buffer[2]; - int size; - int ret; - int i; - - if (!index) - return NULL; - - ret = libusb_get_descriptor (hdl, LIBUSB_DT_STRING, index, - short_buffer, sizeof (short_buffer)); - if (ret < 0) - { - printf ("could not fetch string descriptor: %s\n", - sfs_libusb_strerror (ret)); - return NULL; - } - - if ((short_buffer[0] < 2) /* descriptor length */ - || (short_buffer[1] != LIBUSB_DT_STRING)) /* descriptor type */ - return NULL; - - size = short_buffer[0]; - - buffer = calloc (1, size + 1); - if (!buffer) - return NULL; - - ret = libusb_get_descriptor (hdl, LIBUSB_DT_STRING, index, - buffer, size); - if (ret < 0) - { - printf ("could not fetch string descriptor (again): %s\n", - sfs_libusb_strerror (ret)); - free (buffer); - return NULL; - } - - if ((buffer[0] < 2) || (buffer[0] > size) /* descriptor length */ - || (buffer[1] != LIBUSB_DT_STRING)) /* descriptor type */ - { - free (buffer); - return NULL; - } - - size = buffer[0] - 2; - for (i = 0; i < (size / 2); i++) - buffer[i] = buffer[2 + 2 * i]; - buffer[i] = '\0'; - - return (char *) buffer; -} - -static void -check_libusb_device (libusb_device *dev, SANE_Bool from_file) -{ - libusb_device_handle *hdl; - struct libusb_device_descriptor desc; - struct libusb_config_descriptor *config0; - - int is_scanner = 0; - char *vendor; - char *product; - unsigned short vid, pid; - unsigned char busno, address; - int config; - int intf; - int ret; - - busno = libusb_get_bus_number (dev); - address = libusb_get_device_address (dev); - - ret = libusb_get_device_descriptor (dev, &desc); - if (ret < 0) - { - printf ("could not get device descriptor for device at %03d:%03d: %s\n", - busno, address, sfs_libusb_strerror (ret)); - return; - } - - vid = desc.idVendor; - pid = desc.idProduct; - - ret = libusb_open (dev, &hdl); - if (ret < 0) - { - printf ("could not open USB device 0x%04x/0x%04x at %03d:%03d: %s\n", - vid, pid, busno, address, sfs_libusb_strerror (ret)); - return; - } - - ret = libusb_get_configuration (hdl, &config); - if (ret < 0) - { - printf ("could not get configuration for device 0x%04x/0x%04x at %03d:%03d: %s\n", - vid, pid, busno, address, sfs_libusb_strerror (ret)); - libusb_close (hdl); - return; - } - - if (config == 0) - { - if (verbose > 1) - printf ("device 0x%04x/0x%04x at %03d:%03d is not configured\n", - vid, pid, busno, address); - libusb_close (hdl); - return; - } - - vendor = get_libusb_string_descriptor (hdl, desc.iManufacturer); - product = get_libusb_string_descriptor (hdl, desc.iProduct); - - if (verbose > 2) - { - /* print everything we know about the device */ - char *buf; - int config_nr; - - printf ("\n"); - printf ("\n"); - printf ("bLength %d\n", desc.bLength); - printf ("bDescriptorType %d\n", desc.bDescriptorType); - printf ("bcdUSB %d.%d%d\n", desc.bcdUSB >> 8, - (desc.bcdUSB >> 4) & 15, desc.bcdUSB & 15); - printf ("bDeviceClass %d\n", desc.bDeviceClass); - printf ("bDeviceSubClass %d\n", desc.bDeviceSubClass); - printf ("bDeviceProtocol %d\n", desc.bDeviceProtocol); - printf ("bMaxPacketSize0 %d\n", desc.bMaxPacketSize0); - printf ("idVendor 0x%04X\n", desc.idVendor); - printf ("idProduct 0x%04X\n", desc.idProduct); - printf ("bcdDevice %d.%d%d\n", desc.bcdDevice >> 8, - (desc.bcdDevice >> 4) & 15, desc.bcdDevice & 15); - printf ("iManufacturer %d (%s)\n", desc.iManufacturer, - (vendor) ? vendor : ""); - printf ("iProduct %d (%s)\n", desc.iProduct, - (product) ? product : ""); - buf = get_libusb_string_descriptor (hdl, desc.iSerialNumber); - printf ("iSerialNumber %d (%s)\n", desc.iSerialNumber, - (buf) ? buf : ""); - if (buf) - free (buf); - printf ("bNumConfigurations %d\n", desc.bNumConfigurations); - - for (config_nr = 0; config_nr < desc.bNumConfigurations; config_nr++) - { - struct libusb_config_descriptor *c; - - ret = libusb_get_config_descriptor (dev, config_nr, &c); - if (ret < 0) - { - printf ("could not get configuration descriptor %d: %s\n", - config_nr, sfs_libusb_strerror (ret)); - continue; - } - - printf (" \n", config_nr); - printf (" bLength %d\n", c->bLength); - printf (" bDescriptorType %d\n", c->bDescriptorType); - printf (" wTotalLength %d\n", c->wTotalLength); - printf (" bNumInterfaces %d\n", c->bNumInterfaces); - printf (" bConfigurationValue %d\n", c->bConfigurationValue); - - buf = get_libusb_string_descriptor (hdl, c->iConfiguration); - printf (" iConfiguration %d (%s)\n", c->iConfiguration, - (buf) ? buf : ""); - free (buf); - - printf (" bmAttributes %d (%s%s)\n", c->bmAttributes, - c->bmAttributes & 64 ? "Self-powered" : "", - c->bmAttributes & 32 ? "Remote Wakeup" : ""); - printf (" MaxPower %d mA\n", c->MaxPower * 2); - - for (intf = 0; intf < c->bNumInterfaces; intf++) - { - const struct libusb_interface *interface; - int alt_setting_nr; - - interface = &c->interface[intf]; - - printf (" \n", intf); - for (alt_setting_nr = 0; - alt_setting_nr < interface->num_altsetting; - alt_setting_nr++) - { - const struct libusb_interface_descriptor *i; - int ep_nr; - - i = &interface->altsetting[alt_setting_nr]; - - printf (" \n", alt_setting_nr); - printf (" bLength %d\n", i->bLength); - printf (" bDescriptorType %d\n", i->bDescriptorType); - printf (" bInterfaceNumber %d\n", i->bInterfaceNumber); - printf (" bAlternateSetting %d\n", i->bAlternateSetting); - printf (" bNumEndpoints %d\n", i->bNumEndpoints); - printf (" bInterfaceClass %d\n", i->bInterfaceClass); - printf (" bInterfaceSubClass %d\n", - i->bInterfaceSubClass); - printf (" bInterfaceProtocol %d\n", - i->bInterfaceProtocol); - - buf = NULL; - buf = get_libusb_string_descriptor (hdl, i->iInterface); - printf (" iInterface %d (%s)\n", i->iInterface, - (buf) ? buf : ""); - free (buf); - for (ep_nr = 0; ep_nr < i->bNumEndpoints; ep_nr++) - { - const struct libusb_endpoint_descriptor *e; - char *ep_type; - - e = &i->endpoint[ep_nr]; - - switch (e->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) - { - case LIBUSB_TRANSFER_TYPE_CONTROL: - ep_type = "control"; - break; - case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: - ep_type = "isochronous"; - break; - case LIBUSB_TRANSFER_TYPE_BULK: - ep_type = "bulk"; - break; - case LIBUSB_TRANSFER_TYPE_INTERRUPT: - ep_type = "interrupt"; - break; - default: - ep_type = "unknown"; - break; - } - printf (" \n", ep_nr); - printf (" bLength %d\n", e->bLength); - printf (" bDescriptorType %d\n", - e->bDescriptorType); - printf (" bEndpointAddress 0x%02X (%s 0x%02X)\n", - e->bEndpointAddress, - e->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK ? - "in" : "out", - e-> - bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK); - printf (" bmAttributes %d (%s)\n", - e->bmAttributes, ep_type); - printf (" wMaxPacketSize %d\n", - e->wMaxPacketSize); - printf (" bInterval %d ms\n", e->bInterval); - printf (" bRefresh %d\n", e->bRefresh); - printf (" bSynchAddress %d\n", e->bSynchAddress); - } - } - } - } - } - - - /* Some heuristics, which device may be a scanner */ - if (desc.idVendor == 0) /* hub */ - --is_scanner; - if (desc.idProduct == 0) /* hub */ - --is_scanner; - - ret = libusb_get_config_descriptor (dev, 0, &config0); - if (ret < 0) - { - printf ("could not get config[0] descriptor: %s\n", - sfs_libusb_strerror (ret)); - - goto out_free; - } - - for (intf = 0; (intf < config0->bNumInterfaces) && (is_scanner <= 0); intf++) - { - switch (desc.bDeviceClass) - { - case USB_CLASS_VENDOR_SPEC: - ++is_scanner; - break; - case USB_CLASS_PER_INTERFACE: - if ((config0->interface[intf].num_altsetting == 0) - || !config0->interface[intf].altsetting) - break; - switch (config0->interface[intf].altsetting[0].bInterfaceClass) - { - case USB_CLASS_VENDOR_SPEC: - case USB_CLASS_PER_INTERFACE: - case 16: /* data? */ - ++is_scanner; - break; - } - break; - } - } - - if (is_scanner > 0) - { - char *chipset = NULL; - - if(!from_file) - chipset = check_usb_chip (verbose, desc, hdl, config0); - - printf ("found USB scanner (vendor=0x%04x", vid); - if (vendor) - printf (" [%s]", vendor); - printf (", product=0x%04x", pid); - if (product) - printf (" [%s]", product); - if (chipset) - printf (", chip=%s", chipset); - if (from_file) - printf (")\n"); - else - printf (") at libusb:%03d:%03d\n", busno, address); - - libusb_device_found = SANE_TRUE; - device_found = SANE_TRUE; - } - - libusb_free_config_descriptor (config0); - - out_free: - libusb_close (hdl); - if (vendor) - free (vendor); - - if (product) - free (product); -} -#endif /* HAVE_LIBUSB */ - - -static DIR * -scan_directory (char *dir_name) -{ - struct stat stat_buf; - DIR *dir; - - if (verbose > 2) - printf ("scanning directory %s\n", dir_name); - - if (stat (dir_name, &stat_buf) < 0) - { - if (verbose > 1) - printf ("cannot stat `%s' (%s)\n", dir_name, strerror (errno)); - return 0; - } - if (!S_ISDIR (stat_buf.st_mode)) - { - if (verbose > 1) - printf ("`%s' is not a directory\n", dir_name); - return 0; - } - if ((dir = opendir (dir_name)) == 0) - { - if (verbose > 1) - printf ("cannot read directory `%s' (%s)\n", dir_name, - strerror (errno)); - return 0; - } - return dir; -} - -static char * -get_next_file (char *dir_name, DIR * dir) -{ - struct dirent *dir_entry; - static char file_name[PATH_MAX]; - - do - { - dir_entry = readdir (dir); - if (!dir_entry) - return 0; - } - while (strcmp (dir_entry->d_name, ".") == 0 - || strcmp (dir_entry->d_name, "..") == 0); - - if (strlen (dir_name) + strlen (dir_entry->d_name) + 1 > PATH_MAX) - { - if (verbose > 1) - printf ("filename too long\n"); - return 0; - } - sprintf (file_name, "%s%s", dir_name, dir_entry->d_name); - return file_name; -} - -#if defined(WIN32_SCSI) -/* Return a list of potential scanners. There's a lot of hardcoded values here that might break on a system with lots of scsi devices. */ -static char **build_scsi_dev_list(void) -{ - char **dev_list; - int dev_list_index; - int hca; - HANDLE fd; - char scsi_hca_name[20]; - char buffer[4096]; - DWORD BytesReturned; - BOOL ret; - size_t dev_list_size; - PSCSI_ADAPTER_BUS_INFO adapter; - PSCSI_INQUIRY_DATA inquiry; - int i; - - /* Allocate room for about 100 scanners. That should be enough. */ - dev_list_size = 100; - dev_list_index = 0; - dev_list = calloc(1, dev_list_size * sizeof(char *)); - - hca = 0; - - for(hca = 0; ; hca++) { - - /* Open the adapter */ - snprintf(scsi_hca_name, 20, "\\\\.\\Scsi%d:", hca); - fd = CreateFile(scsi_hca_name, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, - FILE_FLAG_RANDOM_ACCESS, NULL ); - - if (fd == INVALID_HANDLE_VALUE) { - /* Assume there is no more adapter. This is wrong in the case - * of hot-plug stuff, but I have yet to see it on a user - * machine. */ - break; - } - - /* Get the inquiry info for the devices on that hca. */ - ret = DeviceIoControl(fd, - IOCTL_SCSI_GET_INQUIRY_DATA, - NULL, - 0, - buffer, - sizeof(buffer), - &BytesReturned, - FALSE); - - if(ret == 0) - { - CloseHandle(fd); - continue; - } - - adapter = (PSCSI_ADAPTER_BUS_INFO)buffer; - - for(i = 0; i < adapter->NumberOfBuses; i++) { - - if (adapter->BusData[i].InquiryDataOffset == 0) { - /* No device here */ - continue; - } - - inquiry = (PSCSI_INQUIRY_DATA) (buffer + - adapter->BusData[i].InquiryDataOffset); - while(1) { - /* Check if it is a scanner or a processor - * device. Ignore the other - * device types. */ - if (inquiry->InquiryDataLength >= 5 && - ((inquiry->InquiryData[0] & 0x1f) == 3 || - (inquiry->InquiryData[0] & 0x1f) == 6)) { - char device_name[20]; - sprintf(device_name, "h%db%dt%dl%d", hca, inquiry->PathId, inquiry->TargetId, inquiry->Lun); - dev_list[dev_list_index] = strdup(device_name); - dev_list_index++; - } - - if (inquiry->NextInquiryDataOffset == 0) { - /* No device here */ - break; - } else { - inquiry = (PSCSI_INQUIRY_DATA) (buffer + - inquiry->NextInquiryDataOffset); - } - } - } - - CloseHandle(fd); - - } - - return dev_list; - -} -#endif - -#if defined (HAVE_IOKIT_CDB_IOSCSILIB_H) || \ - defined (HAVE_IOKIT_SCSI_SCSICOMMANDOPERATIONCODES_H) || \ - defined (HAVE_IOKIT_SCSI_COMMANDS_SCSICOMMANDOPERATIONCODES_H) -char **scsi_dev_list; -int scsi_dev_list_index; - -static SANE_Status AddToSCSIDeviceList (const char *dev) { - if (scsi_dev_list_index < 99) { - scsi_dev_list [scsi_dev_list_index] = strdup (dev); - scsi_dev_list_index++; - return SANE_STATUS_GOOD; - } - else - return SANE_STATUS_NO_MEM; -} - -static char **build_scsi_dev_list(void) -{ - scsi_dev_list_index = 0; - scsi_dev_list = malloc (100 * sizeof(char *)); - sanei_scsi_find_devices (NULL, NULL, NULL, -1, -1, -1, -1, - AddToSCSIDeviceList); - scsi_dev_list [scsi_dev_list_index] = NULL; - return scsi_dev_list; -} -#endif - -static int -check_mustek_pp_device (void) -{ - const char **devices; - int ctr = 0, found = 0, scsi = 0; - - if (verbose > 1) - printf ("searching for Mustek parallel port scanners:\n"); - - devices = sanei_pa4s2_devices (); - - while (devices[ctr] != NULL) { - int fd; - SANE_Status result; - - /* ordinary parallel port scanner type */ - if (verbose > 1) - printf ("checking %s...", devices[ctr]); - - result = sanei_pa4s2_open (devices[ctr], &fd); - - if (verbose > 1) - { - if (result != 0) - printf (" failed to open (%s)\n", sane_strstatus (result)); - else - printf (" open ok\n"); - } - - if (result == 0) { - printf ("found possible Mustek parallel port scanner at \"%s\"\n", - devices[ctr]); - found++; - sanei_pa4s2_close(fd); - } - - /* trying scsi over pp devices */ - if (verbose > 1) - printf ("checking %s (SCSI emulation)...", devices[ctr]); - - result = sanei_pa4s2_scsi_pp_open (devices[ctr], &fd); - - if (verbose > 1) - { - if (result != 0) - printf (" failed to open (%s)\n", sane_strstatus (result)); - else - printf (" open ok\n"); - } - - if (result == 0) { - printf ("found possible Mustek SCSI over PP scanner at \"%s\"\n", - devices[ctr]); - scsi++; - sanei_pa4s2_close(fd); - } - - ctr++; - } - - free(devices); - - if (found > 0 && verbose > 0) - printf("\n # Your Mustek parallel port scanner was detected. It may or\n" - " # may not be supported by SANE. Please read the sane-mustek_pp\n" - " # man-page for setup instructions.\n"); - - if (scsi > 0 && verbose > 0) - printf("\n # Your Mustek parallel port scanner was detected. It may or\n" - " # may not be supported by SANE. Please read the sane-mustek_pp\n" - " # man-page for setup instructions.\n"); - - return (found > 0 || scsi > 0); -} - -#ifdef HAVE_LIBUSB_LEGACY -static SANE_Bool -parse_num (char* search, const char* line, int base, long int * number) -{ - char* start_number; - - start_number = strstr (line, search); - if (start_number == NULL) - return SANE_FALSE; - start_number += strlen (search); - - *number = strtol (start_number, NULL, base); - if (verbose > 2) - printf ("Found %s%ld\n", search, *number); - return SANE_TRUE; -} - -static SANE_Bool -parse_bcd (char* search, const char* line, long int * number) -{ - char* start_number; - char* end_number; - int first_part; - int second_part; - - start_number = strstr (line, search); - if (start_number == NULL) - return SANE_FALSE; - start_number += strlen (search); - - first_part = strtol (start_number, &end_number, 10); - start_number = end_number + 1; /* skip colon */ - second_part = strtol (start_number, NULL, 10); - *number = ((first_part / 10) << 12) + ((first_part % 10) << 8) - + ((second_part / 10) << 4) + (second_part % 10); - if (verbose > 2) - printf ("Found %s%ld\n", search, *number); - return SANE_TRUE; -} - -static void -parse_file (char *filename) -{ - FILE * parsefile; - char line [PATH_MAX], *token; - const char * p; - struct usb_device *dev = 0; - long int number = 0; - int current_config = 1; - int current_if = -1; - int current_as = -1; - int current_ep = -1; - - if (verbose > 1) - printf ("trying to open %s\n", filename); - parsefile = fopen (filename, "r"); - - if (parsefile == NULL) - { - if (verbose > 0) - printf ("opening %s failed: %s\n", filename, strerror (errno)); - return; - } - - while (sanei_config_read (line, PATH_MAX, parsefile)) - { - if (verbose > 2) - printf ("parsing line: `%s'\n", line); - p = sanei_config_get_string (line, &token); - if (!token || !p || token[0] == '\0') - continue; - if (token[1] != ':') - { - if (verbose > 2) - printf ("missing `:'?\n"); - continue; - } - switch (token[0]) - { - case 'T': - if (dev) - check_libusb_device (dev, SANE_TRUE); - dev = calloc (1, sizeof (struct usb_device)); - dev->bus = calloc (1, sizeof (struct usb_bus)); - current_config = 1; - current_if = -1; - current_as = -1; - current_ep = -1; - break; - case 'D': - if (parse_bcd ("Ver=", line, &number)) - dev->descriptor.bcdUSB = number; - if (parse_num ("Cls=", line, 16, &number)) - dev->descriptor.bDeviceClass = number; - if (parse_num ("Sub=", line, 16, &number)) - dev->descriptor.bDeviceSubClass = number; - if (parse_num ("Prot=", line, 16, &number)) - dev->descriptor.bDeviceProtocol = number; - if (parse_num ("MxPS=", line, 10, &number)) - dev->descriptor.bMaxPacketSize0 = number; - if (parse_num ("#Cfgs=", line, 10, &number)) - dev->descriptor.bNumConfigurations = number; - dev->config = calloc (number, sizeof (struct usb_config_descriptor)); - break; - case 'P': - if (parse_num ("Vendor=", line, 16, &number)) - dev->descriptor.idVendor = number; - if (parse_num ("ProdID=", line, 16, &number)) - dev->descriptor.idProduct = number; - if (parse_bcd ("Rev=", line, &number)) - dev->descriptor.bcdDevice = number; - break; - case 'C': - current_if = -1; - current_as = -1; - current_ep = -1; - if (parse_num ("Cfg#=", line, 10, &number)) - { - current_config = number - 1; - dev->config[current_config].bConfigurationValue = number; - } - if (parse_num ("Ifs=", line, 10, &number)) - dev->config[current_config].bNumInterfaces = number; - dev->config[current_config].interface - = calloc (number, sizeof (struct usb_interface)); - if (parse_num ("Atr=", line, 16, &number)) - dev->config[current_config].bmAttributes = number; - if (parse_num ("MxPwr=", line, 10, &number)) - dev->config[current_config].MaxPower = number / 2; - break; - case 'I': - current_ep = -1; - if (parse_num ("If#=", line, 10, &number)) - { - if (current_if != number) - { - current_if = number; - current_as = -1; - dev->config[current_config].interface[current_if].altsetting - = calloc (20, sizeof (struct usb_interface_descriptor)); - /* Can't read number of altsettings */ - dev->config[current_config].interface[current_if].num_altsetting = 1; - } - else - dev->config[current_config].interface[current_if].num_altsetting++; - } - if (parse_num ("Alt=", line, 10, &number)) - { - current_as = number; - dev->config[current_config].interface[current_if].altsetting[current_as].bInterfaceNumber - = current_if; - dev->config[current_config].interface[current_if].altsetting[current_as].bAlternateSetting - = current_as; - } - if (parse_num ("#EPs=", line, 10, &number)) - dev->config[current_config].interface[current_if].altsetting[current_as].bNumEndpoints - = number; - dev->config[current_config].interface[current_if].altsetting[current_as].endpoint - = calloc (number, sizeof (struct usb_endpoint_descriptor)); - if (parse_num ("Cls=", line, 16, &number)) - dev->config[current_config].interface[current_if].altsetting[current_as].bInterfaceClass - = number; - if (parse_num ("Sub=", line, 16, &number)) - dev->config[current_config].interface[current_if].altsetting[current_as].bInterfaceSubClass - = number; - if (parse_num ("Prot=", line, 16, &number)) - dev->config[current_config].interface[current_if].altsetting[current_as].bInterfaceProtocol - = number; - break; - case 'E': - current_ep++; - if (parse_num ("Ad=", line, 16, &number)) - dev->config[current_config].interface[current_if].altsetting[current_as] - .endpoint[current_ep].bEndpointAddress = number; - if (parse_num ("Atr=", line, 16, &number)) - dev->config[current_config].interface[current_if].altsetting[current_as] - .endpoint[current_ep].bmAttributes = number; - if (parse_num ("MxPS=", line, 10, &number)) - dev->config[current_config].interface[current_if].altsetting[current_as] - .endpoint[current_ep].wMaxPacketSize = number; - if (parse_num ("Ivl=", line, 10, &number)) - dev->config[current_config].interface[current_if].altsetting[current_as] - .endpoint[current_ep].bInterval = number; - break; - case 'S': - case 'B': - continue; - default: - if (verbose > 1) - printf ("ignoring unknown line identifier: %c\n", token[0]); - continue; - } - free (token); - } - if (dev) - check_libusb_device (dev, SANE_TRUE); - fclose (parsefile); - return; -} -#endif - -int -main (int argc, char **argv) -{ - char **dev_list, **usb_dev_list, *dev_name, **ap; - int enable_pp_checks = SANE_FALSE; - - prog_name = strrchr (argv[0], '/'); - if (prog_name) - ++prog_name; - else - prog_name = argv[0]; - - for (ap = argv + 1; ap < argv + argc; ++ap) - { - if ((*ap)[0] != '-') - break; - switch ((*ap)[1]) - { - case '?': - case 'h': - usage (0); - exit (0); - - case 'v': - ++verbose; - break; - - case 'q': - --verbose; - break; - - case 'f': - force = SANE_TRUE; - break; - - case 'p': - enable_pp_checks = SANE_TRUE; - break; - - case 'F': -#ifdef HAVE_LIBUSB_LEGACY - parse_file ((char *) (*(++ap))); -#elif defined(HAVE_LIBUSB) - printf ("option -F not implemented with libusb-1.0\n"); -#else - printf ("libusb not available: option -F can't be used\n"); -#endif - exit (0); - - case '-': - if (!strcmp((*ap), "--help")) - { - usage (0); - exit (0); - } - // fall through - default: - printf ("unknown option: -%c, try -h for help\n", (*ap)[1]); - exit (0); - } - } - if (ap < argv + argc) - { - dev_list = ap; - usb_dev_list = ap; - } - else - { - static char *default_dev_list[] = { -#if defined(__sgi) - "/dev/scsi/sc0d1l0", "/dev/scsi/sc0d2l0", - "/dev/scsi/sc0d3l0", "/dev/scsi/sc0d4l0", - "/dev/scsi/sc0d5l0", "/dev/scsi/sc0d6l0", - "/dev/scsi/sc0d7l0", "/dev/scsi/sc0d8l0", - "/dev/scsi/sc0d9l0", "/dev/scsi/sc0d10l0", - "/dev/scsi/sc0d11l0", "/dev/scsi/sc0d12l0", - "/dev/scsi/sc0d13l0", "/dev/scsi/sc0d14l0", - "/dev/scsi/sc0d15l0", - "/dev/scsi/sc1d1l0", "/dev/scsi/sc1d2l0", - "/dev/scsi/sc1d3l0", "/dev/scsi/sc1d4l0", - "/dev/scsi/sc1d5l0", "/dev/scsi/sc1d6l0", - "/dev/scsi/sc1d7l0", "/dev/scsi/sc1d8l0", - "/dev/scsi/sc1d9l0", "/dev/scsi/sc1d10l0", - "/dev/scsi/sc1d11l0", "/dev/scsi/sc1d12l0", - "/dev/scsi/sc1d13l0", "/dev/scsi/sc1d14l0", - "/dev/scsi/sc1d15l0", - "/dev/scsi/sc2d1l0", "/dev/scsi/sc2d2l0", - "/dev/scsi/sc2d3l0", "/dev/scsi/sc2d4l0", - "/dev/scsi/sc2d5l0", "/dev/scsi/sc2d6l0", - "/dev/scsi/sc2d7l0", "/dev/scsi/sc2d8l0", - "/dev/scsi/sc2d9l0", "/dev/scsi/sc2d10l0", - "/dev/scsi/sc2d11l0", "/dev/scsi/sc2d12l0", - "/dev/scsi/sc2d13l0", "/dev/scsi/sc2d14l0", - "/dev/scsi/sc2d15l0", - "/dev/scsi/sc3d1l0", "/dev/scsi/sc3d2l0", - "/dev/scsi/sc3d3l0", "/dev/scsi/sc3d4l0", - "/dev/scsi/sc3d5l0", "/dev/scsi/sc3d6l0", - "/dev/scsi/sc3d7l0", "/dev/scsi/sc3d8l0", - "/dev/scsi/sc3d9l0", "/dev/scsi/sc3d10l0", - "/dev/scsi/sc3d11l0", "/dev/scsi/sc3d12l0", - "/dev/scsi/sc3d13l0", "/dev/scsi/sc3d14l0", - "/dev/scsi/sc3d15l0", - "/dev/scsi/sc4d1l0", "/dev/scsi/sc4d2l0", - "/dev/scsi/sc4d3l0", "/dev/scsi/sc4d4l0", - "/dev/scsi/sc4d5l0", "/dev/scsi/sc4d6l0", - "/dev/scsi/sc4d7l0", "/dev/scsi/sc4d8l0", - "/dev/scsi/sc4d9l0", "/dev/scsi/sc4d10l0", - "/dev/scsi/sc4d11l0", "/dev/scsi/sc4d12l0", - "/dev/scsi/sc4d13l0", "/dev/scsi/sc4d14l0", - "/dev/scsi/sc4d15l0", - "/dev/scsi/sc5d1l0", "/dev/scsi/sc5d2l0", - "/dev/scsi/sc5d3l0", "/dev/scsi/sc5d4l0", - "/dev/scsi/sc5d5l0", "/dev/scsi/sc5d6l0", - "/dev/scsi/sc5d7l0", "/dev/scsi/sc5d8l0", - "/dev/scsi/sc5d9l0", "/dev/scsi/sc5d10l0", - "/dev/scsi/sc5d11l0", "/dev/scsi/sc5d12l0", - "/dev/scsi/sc5d13l0", "/dev/scsi/sc5d14l0", - "/dev/scsi/sc5d15l0", - "/dev/scsi/sc6d1l0", "/dev/scsi/sc6d2l0", - "/dev/scsi/sc6d3l0", "/dev/scsi/sc6d4l0", - "/dev/scsi/sc6d5l0", "/dev/scsi/sc6d6l0", - "/dev/scsi/sc6d7l0", "/dev/scsi/sc6d8l0", - "/dev/scsi/sc6d9l0", "/dev/scsi/sc6d10l0", - "/dev/scsi/sc6d11l0", "/dev/scsi/sc6d12l0", - "/dev/scsi/sc6d13l0", "/dev/scsi/sc6d14l0", - "/dev/scsi/sc6d15l0", - "/dev/scsi/sc7d1l0", "/dev/scsi/sc7d2l0", - "/dev/scsi/sc7d3l0", "/dev/scsi/sc7d4l0", - "/dev/scsi/sc7d5l0", "/dev/scsi/sc7d6l0", - "/dev/scsi/sc7d7l0", "/dev/scsi/sc7d8l0", - "/dev/scsi/sc7d9l0", "/dev/scsi/sc7d10l0", - "/dev/scsi/sc7d11l0", "/dev/scsi/sc7d12l0", - "/dev/scsi/sc7d13l0", "/dev/scsi/sc7d14l0", - "/dev/scsi/sc7d15l0", - "/dev/scsi/sc8d1l0", "/dev/scsi/sc8d2l0", - "/dev/scsi/sc8d3l0", "/dev/scsi/sc8d4l0", - "/dev/scsi/sc8d5l0", "/dev/scsi/sc8d6l0", - "/dev/scsi/sc8d7l0", "/dev/scsi/sc8d8l0", - "/dev/scsi/sc8d9l0", "/dev/scsi/sc8d10l0", - "/dev/scsi/sc8d11l0", "/dev/scsi/sc8d12l0", - "/dev/scsi/sc8d13l0", "/dev/scsi/sc8d14l0", - "/dev/scsi/sc8d15l0", - "/dev/scsi/sc9d1l0", "/dev/scsi/sc9d2l0", - "/dev/scsi/sc9d3l0", "/dev/scsi/sc9d4l0", - "/dev/scsi/sc9d5l0", "/dev/scsi/sc9d6l0", - "/dev/scsi/sc9d7l0", "/dev/scsi/sc9d8l0", - "/dev/scsi/sc9d9l0", "/dev/scsi/sc9d10l0", - "/dev/scsi/sc9d11l0", "/dev/scsi/sc9d12l0", - "/dev/scsi/sc9d13l0", "/dev/scsi/sc9d14l0", - "/dev/scsi/sc9d15l0", - "/dev/scsi/sc10d1l0", "/dev/scsi/sc10d2l0", - "/dev/scsi/sc10d3l0", "/dev/scsi/sc10d4l0", - "/dev/scsi/sc10d5l0", "/dev/scsi/sc10d6l0", - "/dev/scsi/sc10d7l0", "/dev/scsi/sc10d8l0", - "/dev/scsi/sc10d9l0", "/dev/scsi/sc10d10l0", - "/dev/scsi/sc10d11l0", "/dev/scsi/sc10d12l0", - "/dev/scsi/sc10d13l0", "/dev/scsi/sc10d14l0", - "/dev/scsi/sc10d15l0", - "/dev/scsi/sc11d1l0", "/dev/scsi/sc11d2l0", - "/dev/scsi/sc11d3l0", "/dev/scsi/sc11d4l0", - "/dev/scsi/sc11d5l0", "/dev/scsi/sc11d6l0", - "/dev/scsi/sc11d7l0", "/dev/scsi/sc11d8l0", - "/dev/scsi/sc11d9l0", "/dev/scsi/sc11d10l0", - "/dev/scsi/sc11d11l0", "/dev/scsi/sc11d12l0", - "/dev/scsi/sc11d13l0", "/dev/scsi/sc11d14l0", - "/dev/scsi/sc11d15l0", - "/dev/scsi/sc12d1l0", "/dev/scsi/sc12d2l0", - "/dev/scsi/sc12d3l0", "/dev/scsi/sc12d4l0", - "/dev/scsi/sc12d5l0", "/dev/scsi/sc12d6l0", - "/dev/scsi/sc12d7l0", "/dev/scsi/sc12d8l0", - "/dev/scsi/sc12d9l0", "/dev/scsi/sc12d10l0", - "/dev/scsi/sc12d11l0", "/dev/scsi/sc12d12l0", - "/dev/scsi/sc12d13l0", "/dev/scsi/sc12d14l0", - "/dev/scsi/sc12d15l0", - "/dev/scsi/sc13d1l0", "/dev/scsi/sc13d2l0", - "/dev/scsi/sc13d3l0", "/dev/scsi/sc13d4l0", - "/dev/scsi/sc13d5l0", "/dev/scsi/sc13d6l0", - "/dev/scsi/sc13d7l0", "/dev/scsi/sc13d8l0", - "/dev/scsi/sc13d9l0", "/dev/scsi/sc13d10l0", - "/dev/scsi/sc13d11l0", "/dev/scsi/sc13d12l0", - "/dev/scsi/sc13d13l0", "/dev/scsi/sc13d14l0", - "/dev/scsi/sc13d15l0", - "/dev/scsi/sc14d1l0", "/dev/scsi/sc14d2l0", - "/dev/scsi/sc14d3l0", "/dev/scsi/sc14d4l0", - "/dev/scsi/sc14d5l0", "/dev/scsi/sc14d6l0", - "/dev/scsi/sc14d7l0", "/dev/scsi/sc14d8l0", - "/dev/scsi/sc14d9l0", "/dev/scsi/sc14d10l0", - "/dev/scsi/sc14d11l0", "/dev/scsi/sc14d12l0", - "/dev/scsi/sc14d13l0", "/dev/scsi/sc14d14l0", - "/dev/scsi/sc14d15l0", - "/dev/scsi/sc15d1l0", "/dev/scsi/sc15d2l0", - "/dev/scsi/sc15d3l0", "/dev/scsi/sc15d4l0", - "/dev/scsi/sc15d5l0", "/dev/scsi/sc15d6l0", - "/dev/scsi/sc15d7l0", "/dev/scsi/sc15d8l0", - "/dev/scsi/sc15d9l0", "/dev/scsi/sc15d10l0", - "/dev/scsi/sc15d11l0", "/dev/scsi/sc15d12l0", - "/dev/scsi/sc15d13l0", "/dev/scsi/sc15d14l0", - "/dev/scsi/sc15d15l0", -#elif defined(__EMX__) - "b0t0l0", "b0t1l0", "b0t2l0", "b0t3l0", - "b0t4l0", "b0t5l0", "b0t6l0", "b0t7l0", - "b1t0l0", "b1t1l0", "b1t2l0", "b1t3l0", - "b1t4l0", "b1t5l0", "b1t6l0", "b1t7l0", - "b2t0l0", "b2t1l0", "b2t2l0", "b2t3l0", - "b2t4l0", "b2t5l0", "b2t6l0", "b2t7l0", - "b3t0l0", "b3t1l0", "b3t2l0", "b3t3l0", - "b3t4l0", "b3t5l0", "b3t6l0", "b3t7l0", -#elif defined(__linux__) - "/dev/scanner", - "/dev/sg0", "/dev/sg1", "/dev/sg2", "/dev/sg3", - "/dev/sg4", "/dev/sg5", "/dev/sg6", "/dev/sg7", - "/dev/sg8", "/dev/sg9", - "/dev/sga", "/dev/sgb", "/dev/sgc", "/dev/sgd", - "/dev/sge", "/dev/sgf", "/dev/sgg", "/dev/sgh", - "/dev/sgi", "/dev/sgj", "/dev/sgk", "/dev/sgl", - "/dev/sgm", "/dev/sgn", "/dev/sgo", "/dev/sgp", - "/dev/sgq", "/dev/sgr", "/dev/sgs", "/dev/sgt", - "/dev/sgu", "/dev/sgv", "/dev/sgw", "/dev/sgx", - "/dev/sgy", "/dev/sgz", -#elif defined(__NeXT__) - "/dev/sg0a", "/dev/sg0b", "/dev/sg0c", "/dev/sg0d", - "/dev/sg0e", "/dev/sg0f", "/dev/sg0g", "/dev/sg0h", - "/dev/sg1a", "/dev/sg1b", "/dev/sg1c", "/dev/sg1d", - "/dev/sg1e", "/dev/sg1f", "/dev/sg1g", "/dev/sg1h", - "/dev/sg2a", "/dev/sg2b", "/dev/sg2c", "/dev/sg2d", - "/dev/sg2e", "/dev/sg2f", "/dev/sg2g", "/dev/sg2h", - "/dev/sg3a", "/dev/sg3b", "/dev/sg3c", "/dev/sg3d", - "/dev/sg3e", "/dev/sg3f", "/dev/sg3g", "/dev/sg3h", -#elif defined(_AIX) - "/dev/scanner", - "/dev/gsc0", "/dev/gsc1", "/dev/gsc2", "/dev/gsc3", - "/dev/gsc4", "/dev/gsc5", "/dev/gsc6", "/dev/gsc7", - "/dev/gsc8", "/dev/gsc9", "/dev/gsc10", "/dev/gsc11", - "/dev/gsc12", "/dev/gsc13", "/dev/gsc14", "/dev/gsc15", -#elif defined(__sun) - "/dev/scg0a", "/dev/scg0b", "/dev/scg0c", "/dev/scg0d", - "/dev/scg0e", "/dev/scg0f", "/dev/scg0g", - "/dev/scg1a", "/dev/scg1b", "/dev/scg1c", "/dev/scg1d", - "/dev/scg1e", "/dev/scg1f", "/dev/scg1g", - "/dev/scg2a", "/dev/scg2b", "/dev/scg2c", "/dev/scg2d", - "/dev/scg2e", "/dev/scg2f", "/dev/scg2g", - "/dev/sg/0", "/dev/sg/1", "/dev/sg/2", "/dev/sg/3", - "/dev/sg/4", "/dev/sg/5", "/dev/sg/6", - "/dev/scsi/scanner/", "/dev/scsi/processor/", -#elif defined(HAVE_CAMLIB_H) - "/dev/scanner", "/dev/scanner0", "/dev/scanner1", - "/dev/pass0", "/dev/pass1", "/dev/pass2", "/dev/pass3", - "/dev/pass4", "/dev/pass5", "/dev/pass6", "/dev/pass7", -#elif defined(__FreeBSD__) || defined(__DragonFly__) - "/dev/uk0", "/dev/uk1", "/dev/uk2", "/dev/uk3", "/dev/uk4", - "/dev/uk5", "/dev/uk6", -#elif defined(__NetBSD__) - "/dev/uk0", "/dev/uk1", "/dev/uk2", "/dev/uk3", "/dev/uk4", - "/dev/uk5", "/dev/uk6", - "/dev/ss0", -#elif defined(__OpenBSD__) - "/dev/uk0", "/dev/uk1", "/dev/uk2", "/dev/uk3", "/dev/uk4", - "/dev/uk5", "/dev/uk6", -#elif defined(__hpux) - "/dev/rscsi/", -#endif - 0 - }; - static char *usb_default_dev_list[] = { -#if defined(__linux__) - "/dev/usb/scanner", - "/dev/usb/scanner0", "/dev/usb/scanner1", - "/dev/usb/scanner2", "/dev/usb/scanner3", - "/dev/usb/scanner4", "/dev/usb/scanner5", - "/dev/usb/scanner5", "/dev/usb/scanner7", - "/dev/usb/scanner8", "/dev/usb/scanner9", - "/dev/usb/scanner10", "/dev/usb/scanner11", - "/dev/usb/scanner12", "/dev/usb/scanner13", - "/dev/usb/scanner14", "/dev/usb/scanner15", - "/dev/usbscanner", - "/dev/usbscanner0", "/dev/usbscanner1", - "/dev/usbscanner2", "/dev/usbscanner3", - "/dev/usbscanner4", "/dev/usbscanner5", - "/dev/usbscanner6", "/dev/usbscanner7", - "/dev/usbscanner8", "/dev/usbscanner9", - "/dev/usbscanner10", "/dev/usbscanner11", - "/dev/usbscanner12", "/dev/usbscanner13", - "/dev/usbscanner14", "/dev/usbscanner15", -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) - "/dev/uscanner", - "/dev/uscanner0", "/dev/uscanner1", - "/dev/uscanner2", "/dev/uscanner3", - "/dev/uscanner4", "/dev/uscanner5", - "/dev/uscanner6", "/dev/uscanner7", - "/dev/uscanner8", "/dev/uscanner9", - "/dev/uscanner10", "/dev/uscanner11", - "/dev/uscanner12", "/dev/uscanner13", - "/dev/uscanner14", "/dev/uscanner15", -#endif - 0 - }; - -#if defined (WIN32_SCSI) || \ - defined (HAVE_IOKIT_CDB_IOSCSILIB_H) || \ - defined (HAVE_IOKIT_SCSI_SCSICOMMANDOPERATIONCODES_H) || \ - defined (HAVE_IOKIT_SCSI_COMMANDS_SCSICOMMANDOPERATIONCODES_H) - /* Build a list of valid of possible scanners found */ - dev_list = build_scsi_dev_list(); -#else - dev_list = default_dev_list; -#endif - - usb_dev_list = usb_default_dev_list; - } - if (verbose > 1) - printf ("This is sane-find-scanner from %s\n", PACKAGE_STRING); - - if (verbose > 0) - printf ("\n # sane-find-scanner will now attempt to detect your scanner. If the" - "\n # result is different from what you expected, first make sure your" - "\n # scanner is powered up and properly connected to your computer.\n\n"); - - if (verbose > 1) - printf ("searching for SCSI scanners:\n"); - - while ((dev_name = *dev_list++)) - { - if (strlen (dev_name) == 0) - continue; /* Empty device names ... */ - - if (dev_name[strlen (dev_name) - 1] == '/') - { - /* check whole directories */ - DIR *dir; - char *file_name; - - dir = scan_directory (dev_name); - if (!dir) - continue; - - while ((file_name = get_next_file (dev_name, dir))) - check_scsi_file (file_name); - } - else - { - /* check device files */ - check_scsi_file (dev_name); - } - } - if (device_found) - { - if (verbose > 0) - printf - (" # Your SCSI scanner was detected. It may or may not be " - "supported by SANE. Try\n # scanimage -L and read the backend's " - "manpage.\n"); - } - else - { - if (verbose > 0) - printf - (" # No SCSI scanners found. If you expected something different, " - "make sure that\n # you have loaded a kernel SCSI driver for your SCSI " - "adapter.\n"); - if (!check_sg ()) - { - if (verbose > 0) - printf - (" # Also you need support for SCSI Generic (sg) in your " - "operating system.\n # If using Linux, try \"modprobe " - "sg\".\n"); - } - } - if (verbose > 0) - printf ("\n"); - device_found = SANE_FALSE; - sanei_usb_init (); - if (verbose > 1) - printf ("searching for USB scanners:\n"); - - while ((dev_name = *usb_dev_list++)) - { - if (strlen (dev_name) == 0) - continue; /* Empty device names ... */ - - if (dev_name[strlen (dev_name) - 1] == '/') - { - /* check whole directories */ - DIR *dir; - char *file_name; - - dir = scan_directory (dev_name); - if (!dir) - continue; - - while ((file_name = get_next_file (dev_name, dir))) - check_usb_file (file_name); - } - else - { - /* check device files */ - check_usb_file (dev_name); - } - } -#ifdef HAVE_LIBUSB_LEGACY - /* Now the libusb devices */ - { - struct usb_bus *bus; - struct usb_device *dev; - - if (ap < argv + argc) - { - /* user-specified devices not useful for libusb */ - if (verbose > 1) - printf ("ignoring libusb devices\n"); - } - else - { - if (verbose > 2) - printf ("trying libusb:\n"); - for (bus = usb_get_busses (); bus; bus = bus->next) - { - for (dev = bus->devices; dev; dev = dev->next) - { - check_libusb_device (dev, SANE_FALSE); - } /* for (dev) */ - } /* for (bus) */ - } - } -#elif defined(HAVE_LIBUSB) - /* Now the libusb-1.0 devices */ - { - if (ap < argv + argc) - { - /* user-specified devices not useful for libusb */ - if (verbose > 1) - printf ("ignoring libusb devices\n"); - } - else - { - libusb_device **devlist; - ssize_t devcnt; - int i; - int ret; - - if (verbose > 2) - printf ("trying libusb:\n"); - - ret = libusb_init (&sfs_usb_ctx); - if (ret < 0) - { - printf ("# Could not initialize libusb-1.0, error %d\n", ret); - printf ("# Skipping libusb devices\n"); - - goto failed_libusb_1_0; - } - - if (verbose > 3) -#if LIBUSB_API_VERSION >= 0x01000106 - libusb_set_option (sfs_usb_ctx, LIBUSB_OPTION_LOG_LEVEL, - LIBUSB_LOG_LEVEL_INFO); -#else - libusb_set_debug (sfs_usb_ctx, 3); -#endif - - devcnt = libusb_get_device_list (sfs_usb_ctx, &devlist); - if (devcnt < 0) - { - printf ("# Could not get device list, error %d\n", ret); - - goto deinit_libusb_1_0; - } - - for (i = 0; i < devcnt; i++) - { - check_libusb_device (devlist[i], SANE_FALSE); - } - - libusb_free_device_list (devlist, 1); - - deinit_libusb_1_0: - libusb_exit (sfs_usb_ctx); - - failed_libusb_1_0: - ; /* init failed, jumping here */ - } - } -#else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */ - if (verbose > 1) - printf ("libusb not available\n"); -#endif /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */ - - if (device_found) - { - if (libusb_device_found) - { - if (verbose > 0) - printf - (" # Your USB scanner was (probably) detected. It " - "may or may not be supported by\n # SANE. Try scanimage " - "-L and read the backend's manpage.\n"); - } - else if (verbose > 0) - printf - (" # Your USB scanner was detected. It may or may not " - "be supported by\n # SANE. Try scanimage -L and read the " - "backend's manpage.\n"); - if (unknown_found && verbose > 0) - printf - (" # `UNKNOWN vendor and product' means that there seems to be a " - "scanner at this\n # device file but the vendor and product ids " - "couldn't be identified.\n # Currently identification only works " - "with Linux versions >= 2.4.8. You may\n # need to configure your " - "backend manually, see the backend's manpage.\n"); - } - else - { - if (verbose > 0) - printf - (" # No USB scanners found. If you expected something different, " - "make sure that\n # you have loaded a kernel driver for your USB host " - "controller and have setup\n # the USB system correctly. " - "See man sane-usb for details.\n"); -#if !defined(HAVE_LIBUSB_LEGACY) && !defined(HAVE_LIBUSB) - if (verbose > 0) - printf (" # SANE has been built without libusb support. This may be a " - "reason\n # for not detecting USB scanners. Read README for " - "more details.\n"); -#endif - } - if (enable_pp_checks == SANE_TRUE) - { - if (!check_mustek_pp_device() && verbose > 0) - printf ("\n # No Mustek parallel port scanners found. If you expected" - " something\n # different, make sure the scanner is correctly" - " connected to your computer\n # and you have appropriate" - " access rights.\n"); - } - else if (verbose > 0) - printf ("\n # Not checking for parallel port scanners.\n"); - if (verbose > 0) - printf ("\n # Most Scanners connected to the parallel port or other " - "proprietary ports\n # can't be detected by this program.\n"); -#ifdef HAVE_GETUID - if (getuid ()) - if (verbose > 0) - printf - ("\n # You may want to run this program as root to find all devices. " - "Once you\n # found the scanner devices, be sure to adjust access " - "permissions as\n # necessary.\n"); -#endif - - if (verbose > 1) - printf ("done\n"); - - return 0; -} diff --git a/tools/sane-find-scanner.c.rej b/tools/sane-find-scanner.c.rej deleted file mode 100644 index 719a906..0000000 --- a/tools/sane-find-scanner.c.rej +++ /dev/null @@ -1,22 +0,0 @@ ---- tools/sane-find-scanner.c -+++ tools/sane-find-scanner.c -@@ -384,7 +384,7 @@ check_usb_file (char *file_name) - { - if (verbose > 1) - printf (" open ok, vendor and product ids were identified\n"); -- printf ("found USB scanner (vendor=0x%04x, " -+ printf ("found possible USB scanner (vendor=0x%04x, " - "product=0x%04x) at %s\n", vendor, product, file_name); - } - else -@@ -392,8 +392,8 @@ check_usb_file (char *file_name) - if (verbose > 1) - printf (" open ok, but vendor and product could NOT be " - "identified\n"); -- printf ("found USB scanner (UNKNOWN vendor and product) " -- "at device %s\n", file_name); -+ printf ("found possible USB scanner (UNKNOWN vendor and " -+ "product) at %s\n", file_name); - unknown_found = SANE_TRUE; - } - device_found = SANE_TRUE; -- cgit v1.2.3 From 4b201ef213beeb0c1a97ee427525fd59253e1419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 21 Feb 2022 19:26:09 +0100 Subject: d/copyright: Refresh Upstream Contact and Source --- debian/changelog | 2 ++ debian/copyright | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index a862b6d..d1cb9d7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -21,6 +21,8 @@ sane-backends (1.1.1-3) UNRELEASED; urgency=medium - Improve output for possible USB scanners (Closes: #983332). * debian/libsane1.symbols: - Add !kfreebsd-any to missing symbol. + * debian/copyright: + - Refresh Upstream Contact and Source. -- Jörg Frings-Fürst Mon, 14 Feb 2022 21:28:17 +0100 diff --git a/debian/copyright b/debian/copyright index 551790f..5fbfc74 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,7 +1,7 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: sane-backends -Upstream-Contact: -Source: ftp://ftp.sane-project.org/pub/sane/ +Upstream-Contact: +Source: https://gitlab.com/sane-project/backends/-/archive/master/ Files: * Copyright: 1997-2014 Andreas Beck -- cgit v1.2.3 From cfaf9fc8246b4826ff641aad1034cf5a4546219f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Tue, 22 Feb 2022 21:30:03 +0100 Subject: Fix debian/sane-utils.preinst --- debian/sane-utils.preinst | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/debian/sane-utils.preinst b/debian/sane-utils.preinst index 1a7f24b..2e49781 100644 --- a/debian/sane-utils.preinst +++ b/debian/sane-utils.preinst @@ -6,16 +6,25 @@ MANPAGE=/usr/share/man/man5/sane-umax_pp.5.gz MANLINK=/usr/share/man/man5/umax_pp.5.gz -if [ -f "$MANLINK" ] && [ -L "$MANLINK" ]; then - # Remove old directory and files that are now provided by xsane-common - rm -rf "$MANLINK" -fi + +if [ "$1" = install ] || [ "$1" = upgrade ]; then + + ## Remove obsolete manpages that are now provided by sane-common + if dpkg --compare-versions "$2" le "1.1.1-2"; then + + if [ -f "$MANLINK" ] && [ -L "$MANLINK" ]; then + rm -rf "$MANLINK" + fi -if [ -f "$MANPAGE" ]; then - # Remove old directory and files that are now provided by xsane-common - rm -rf "$MANPAGE" + if [ -f "$MANPAGE" ]; then + rm -rf "$MANPAGE" + fi + fi fi + + + #DEBHELPER# -- cgit v1.2.3 From b49afcfced33b314620d2888d06452271be51210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 23 Feb 2022 08:37:20 +0100 Subject: Fix typos --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index d1cb9d7..491aa6c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -11,8 +11,8 @@ sane-backends (1.1.1-3) UNRELEASED; urgency=medium - Add Recommends: sane-airscan to libsane1 (Closes: 1005817). * Move man page sane-umax_pp.5 back to libsane-common (Closes: #1005736): - debian/rules: - - Remove delete manpage vom libsane-common. - - New debian/sane-utils.preinst to remove man page and sysmlink. + - Remove delete manpage from libsane-common. + - New debian/sane-utils.preinst to remove man page and symlink. - debian/sane-utils.link: - Remove create link from sane-umax_pp.5 - debian/control: -- cgit v1.2.3 From b1b67fa7704fb30ea9070cd39cf4c2ce43c99052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 23 Feb 2022 08:43:40 +0100 Subject: d/changelog: Change distribution to unstable, Change date and time --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 491aa6c..c315e80 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -sane-backends (1.1.1-3) UNRELEASED; urgency=medium +sane-backends (1.1.1-3) unstable; urgency=medium * Remove test artefact (debian/1.sh). * debian/changelog: @@ -24,7 +24,7 @@ sane-backends (1.1.1-3) UNRELEASED; urgency=medium * debian/copyright: - Refresh Upstream Contact and Source. - -- Jörg Frings-Fürst Mon, 14 Feb 2022 21:28:17 +0100 + -- Jörg Frings-Fürst Wed, 23 Feb 2022 08:40:55 +0100 sane-backends (1.1.1-2) unstable; urgency=medium -- cgit v1.2.3 From 9c16214bb7884d23f0dc354d1ef88a1e6dc9744f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 23 Feb 2022 09:28:20 +0100 Subject: d/copyright: Fix upstream mail --- debian/copyright | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/copyright b/debian/copyright index 5fbfc74..6671360 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,6 +1,6 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: sane-backends -Upstream-Contact: +Upstream-Contact: Source: https://gitlab.com/sane-project/backends/-/archive/master/ Files: * -- cgit v1.2.3 From 425490576efeef5d57889a5a7f4accaee9afdcd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 23 Feb 2022 09:28:52 +0100 Subject: d/changelog: Change date and time --- debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index c315e80..ca09256 100644 --- a/debian/changelog +++ b/debian/changelog @@ -24,7 +24,7 @@ sane-backends (1.1.1-3) unstable; urgency=medium * debian/copyright: - Refresh Upstream Contact and Source. - -- Jörg Frings-Fürst Wed, 23 Feb 2022 08:40:55 +0100 + -- Jörg Frings-Fürst Wed, 23 Feb 2022 09:28:33 +0100 sane-backends (1.1.1-2) unstable; urgency=medium -- cgit v1.2.3