kopia lustrzana https://gitlab.com/sane-project/backends
Added usermap, db, and udev output modes for generating USB vendor/product lists
for hotplug (ng) and Linux udev. Added version information to html modes.merge-requests/1/head
rodzic
60a4f9e3ed
commit
14e5a82d9d
|
@ -3,7 +3,9 @@
|
||||||
* doc/descriptions/unsupported.desc: Added Xerox 4800.
|
* doc/descriptions/unsupported.desc: Added Xerox 4800.
|
||||||
* doc/descriptions.txt tools/sane-desc.c: Added support for
|
* doc/descriptions.txt tools/sane-desc.c: Added support for
|
||||||
keyword :usbid. All output modes now print the usb vendor and
|
keyword :usbid. All output modes now print the usb vendor and
|
||||||
product modes.
|
product modes. Added usermap, db, and udev output modes for
|
||||||
|
generating USB vendor/product lists for hotplug (ng) and Linux
|
||||||
|
udev. Added version information to html modes.
|
||||||
* doc/descriptions/gt68xx.desc: Added vendor and product ids for
|
* doc/descriptions/gt68xx.desc: Added vendor and product ids for
|
||||||
all scanners.
|
all scanners.
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
MA 02111-1307, USA.
|
MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SANE_DESC_VERSION "3.0"
|
#define SANE_DESC_VERSION "3.1"
|
||||||
|
|
||||||
#define MAN_PAGE_LINK "http://www.sane-project.org/man/%s.5.html"
|
#define MAN_PAGE_LINK "http://www.sane-project.org/man/%s.5.html"
|
||||||
#define COLOR_MINIMAL "\"#B00000\""
|
#define COLOR_MINIMAL "\"#B00000\""
|
||||||
|
@ -71,7 +71,10 @@ typedef enum output_mode
|
||||||
output_mode_html_backends,
|
output_mode_html_backends,
|
||||||
output_mode_html_backends_split,
|
output_mode_html_backends_split,
|
||||||
output_mode_html_mfgs,
|
output_mode_html_mfgs,
|
||||||
output_mode_statistics
|
output_mode_statistics,
|
||||||
|
output_mode_usermap,
|
||||||
|
output_mode_db,
|
||||||
|
output_mode_udev
|
||||||
}
|
}
|
||||||
output_mode;
|
output_mode;
|
||||||
|
|
||||||
|
@ -202,6 +205,23 @@ mfg_record_entry;
|
||||||
|
|
||||||
typedef int statistics_type [status_complete + 1];
|
typedef int statistics_type [status_complete + 1];
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct manufacturer_model_type
|
||||||
|
{
|
||||||
|
struct manufacturer_model_type * next;
|
||||||
|
char *name;
|
||||||
|
}
|
||||||
|
manufacturer_model_type;
|
||||||
|
|
||||||
|
typedef struct usbid_type
|
||||||
|
{
|
||||||
|
struct usbid_type * next;
|
||||||
|
char *usb_vendor_id;
|
||||||
|
char *usb_product_id;
|
||||||
|
struct manufacturer_model_type *name;
|
||||||
|
}
|
||||||
|
usbid_type;
|
||||||
|
|
||||||
static char *program_name;
|
static char *program_name;
|
||||||
static int debug = 0;
|
static int debug = 0;
|
||||||
static int current_debug_level = 0;
|
static int current_debug_level = 0;
|
||||||
|
@ -269,7 +289,7 @@ print_usage (char *program_name)
|
||||||
"(multiple directories can be concatenated by \":\")\n");
|
"(multiple directories can be concatenated by \":\")\n");
|
||||||
printf (" -m|--mode mode "
|
printf (" -m|--mode mode "
|
||||||
"Output mode (ascii, html-backends-split,\n"
|
"Output mode (ascii, html-backends-split,\n"
|
||||||
" html-mfgs, xml, statistics)\n");
|
" html-mfgs, xml, statistics, usermap, db, udev)\n");
|
||||||
printf (" -t|--title \"title\" The title used for HTML pages\n");
|
printf (" -t|--title \"title\" The title used for HTML pages\n");
|
||||||
printf (" -i|--intro \"intro\" A short description of the "
|
printf (" -i|--intro \"intro\" A short description of the "
|
||||||
"contents of the page\n");
|
"contents of the page\n");
|
||||||
|
@ -351,6 +371,21 @@ get_options (int argc, char **argv)
|
||||||
DBG_INFO ("Output mode: %s\n", optarg);
|
DBG_INFO ("Output mode: %s\n", optarg);
|
||||||
mode = output_mode_statistics;
|
mode = output_mode_statistics;
|
||||||
}
|
}
|
||||||
|
else if (strcmp (optarg, "usermap") == 0)
|
||||||
|
{
|
||||||
|
DBG_INFO ("Output mode: %s\n", optarg);
|
||||||
|
mode = output_mode_usermap;
|
||||||
|
}
|
||||||
|
else if (strcmp (optarg, "db") == 0)
|
||||||
|
{
|
||||||
|
DBG_INFO ("Output mode: %s\n", optarg);
|
||||||
|
mode = output_mode_db;
|
||||||
|
}
|
||||||
|
else if (strcmp (optarg, "udev") == 0)
|
||||||
|
{
|
||||||
|
DBG_INFO ("Output mode: %s\n", optarg);
|
||||||
|
mode = output_mode_udev;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBG_ERR ("Unknown output mode: %s\n", optarg);
|
DBG_ERR ("Unknown output mode: %s\n", optarg);
|
||||||
|
@ -2555,8 +2590,8 @@ html_print_footer (void)
|
||||||
"<address>\n"
|
"<address>\n"
|
||||||
"<a href=\"http://www.sane-project.org/imprint.html\"\n"
|
"<a href=\"http://www.sane-project.org/imprint.html\"\n"
|
||||||
">Contact</a>\n" "</address>\n" "<font size=-1>\n");
|
">Contact</a>\n" "</address>\n" "<font size=-1>\n");
|
||||||
printf ("This page was last updated on %s\n",
|
printf ("This page was last updated on %s by sane-desc %s from %s\n",
|
||||||
asctime (localtime (¤t_time)));
|
asctime (localtime (¤t_time)), SANE_DESC_VERSION, PACKAGE_STRING);
|
||||||
printf ("</font>\n");
|
printf ("</font>\n");
|
||||||
printf ("</body> </html>\n");
|
printf ("</body> </html>\n");
|
||||||
}
|
}
|
||||||
|
@ -2811,6 +2846,297 @@ print_statistics (void)
|
||||||
print_statistics_per_type (type_api);
|
print_statistics_per_type (type_api);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static usbid_type *
|
||||||
|
create_usbid (char *manufacturer, char *model,
|
||||||
|
char *usb_vendor_id, char *usb_product_id)
|
||||||
|
{
|
||||||
|
usbid_type * usbid = calloc (1, sizeof (usbid_type));
|
||||||
|
|
||||||
|
usbid->usb_vendor_id = strdup (usb_vendor_id);
|
||||||
|
usbid->usb_product_id = strdup (usb_product_id);
|
||||||
|
usbid->name = calloc (1, sizeof (manufacturer_model_type));
|
||||||
|
usbid->name->name = calloc (1, strlen (manufacturer) + strlen (model) + 3);
|
||||||
|
sprintf (usbid->name->name, "%s %s", manufacturer, model);
|
||||||
|
usbid->name->next = 0;
|
||||||
|
usbid->next = 0;
|
||||||
|
DBG_DBG ("New USB ids: %s/%s (%s %s)\n", usb_vendor_id, usb_product_id,
|
||||||
|
manufacturer, model);
|
||||||
|
return usbid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static usbid_type *
|
||||||
|
add_usbid (usbid_type *first_usbid, char *manufacturer, char *model,
|
||||||
|
char *usb_vendor_id, char *usb_product_id)
|
||||||
|
{
|
||||||
|
usbid_type *usbid = first_usbid;
|
||||||
|
usbid_type *prev_usbid = 0, *tmp_usbid = 0;
|
||||||
|
|
||||||
|
if (!first_usbid)
|
||||||
|
first_usbid = create_usbid (manufacturer, model, usb_vendor_id, usb_product_id);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (usbid)
|
||||||
|
{
|
||||||
|
if (strcmp (usb_vendor_id, usbid->usb_vendor_id) == 0 &&
|
||||||
|
strcmp (usb_product_id, usbid->usb_product_id) == 0)
|
||||||
|
{
|
||||||
|
manufacturer_model_type *man_mod = usbid->name;
|
||||||
|
|
||||||
|
while (man_mod->next)
|
||||||
|
man_mod = man_mod->next;
|
||||||
|
man_mod->next = malloc (sizeof (manufacturer_model_type));
|
||||||
|
man_mod->next->name = malloc (strlen (manufacturer) + strlen (model) + 3);
|
||||||
|
sprintf (man_mod->next->name, "%s %s", manufacturer, model);
|
||||||
|
man_mod->next->next = 0;
|
||||||
|
DBG_DBG ("Added manufacturer/model %s %s to USB ids %s/%s\n", manufacturer, model,
|
||||||
|
usb_vendor_id, usb_product_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strcmp (usb_vendor_id, usbid->usb_vendor_id) < 0 ||
|
||||||
|
(strcmp (usb_vendor_id, usbid->usb_vendor_id) == 0 &&
|
||||||
|
strcmp (usb_product_id, usbid->usb_product_id) < 0))
|
||||||
|
{
|
||||||
|
|
||||||
|
tmp_usbid = create_usbid (manufacturer, model, usb_vendor_id, usb_product_id);
|
||||||
|
tmp_usbid->next = usbid;
|
||||||
|
if (prev_usbid)
|
||||||
|
prev_usbid->next = tmp_usbid;
|
||||||
|
else
|
||||||
|
first_usbid = tmp_usbid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev_usbid = usbid;
|
||||||
|
usbid = usbid->next;
|
||||||
|
}
|
||||||
|
if (!usbid)
|
||||||
|
{
|
||||||
|
prev_usbid->next = create_usbid (manufacturer, model, usb_vendor_id, usb_product_id);
|
||||||
|
usbid = prev_usbid->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return first_usbid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static usbid_type *
|
||||||
|
create_usbids_table (void)
|
||||||
|
{
|
||||||
|
backend_entry *be = first_backend;
|
||||||
|
usbid_type *first_usbid = 0;
|
||||||
|
|
||||||
|
while (be)
|
||||||
|
{
|
||||||
|
type_entry *type = be->type;
|
||||||
|
|
||||||
|
while (type)
|
||||||
|
{
|
||||||
|
mfg_entry *mfg = type->mfg;
|
||||||
|
model_entry *model;
|
||||||
|
|
||||||
|
if (!mfg)
|
||||||
|
{
|
||||||
|
type = type->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mfg = type->mfg;
|
||||||
|
while (mfg)
|
||||||
|
{
|
||||||
|
model = mfg->model;
|
||||||
|
if (model)
|
||||||
|
{
|
||||||
|
while (model)
|
||||||
|
{
|
||||||
|
if (model->usb_vendor_id && model->usb_product_id)
|
||||||
|
{
|
||||||
|
first_usbid = add_usbid (first_usbid, mfg->name,
|
||||||
|
model->name,
|
||||||
|
model->usb_vendor_id,
|
||||||
|
model->usb_product_id);
|
||||||
|
}
|
||||||
|
model = model->next;
|
||||||
|
} /* while (model) */
|
||||||
|
} /* if (model) */
|
||||||
|
mfg = mfg->next;
|
||||||
|
} /* while (mfg) */
|
||||||
|
type = type->next;
|
||||||
|
} /* while (type) */
|
||||||
|
be = be->next;
|
||||||
|
} /* while (be) */
|
||||||
|
return first_usbid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* print USB usermap file to be used by the hotplug tools */
|
||||||
|
static void
|
||||||
|
print_usermap_header (void)
|
||||||
|
{
|
||||||
|
time_t current_time = time (0);
|
||||||
|
|
||||||
|
printf ("# This file was automatically created based on description files (*.desc)\n"
|
||||||
|
"# by sane-desc %s from %s on %s",
|
||||||
|
SANE_DESC_VERSION, PACKAGE_STRING, asctime (localtime (¤t_time)));
|
||||||
|
printf
|
||||||
|
("#\n"
|
||||||
|
"# The entries below are used to detect a USB device when it's plugged in\n"
|
||||||
|
"# and then run the libusbscanner script to change the ownership and\n"
|
||||||
|
"# permissions on the \"device node\" used by libusb.\n"
|
||||||
|
"#\n"
|
||||||
|
"# The 0x0003 match flag means the device is matched by its vendor and\n"
|
||||||
|
"# product IDs.\n"
|
||||||
|
"#\n"
|
||||||
|
"# Sample entry (replace 0xVVVV and 0xPPPP with vendor ID and product ID\n"
|
||||||
|
"# respectively):\n");
|
||||||
|
printf
|
||||||
|
("# libusbscanner 0x0003 0xVVVV 0xPPPP 0x0000 0x0000 0x00 0x00 0x00 0x00 "
|
||||||
|
"0x00 0x00 0x00000000\n"
|
||||||
|
"# usb module match_flags idVendor idProduct bcdDevice_lo bcdDevice_hi "
|
||||||
|
"bDeviceClass bDeviceSubClass bDeviceProtocol bInterfaceClass "
|
||||||
|
"bInterfaceSubClass bInterfaceProtocol driver_info\n"
|
||||||
|
"#\n"
|
||||||
|
"# The following list already contains a lot of scanners. If your scanner\n"
|
||||||
|
"# isn't mentioned there, add it as explained above and mail the entry to\n"
|
||||||
|
"# the sane-devel mailing list (sane-devel@lists.alioth.debian.org).\n"
|
||||||
|
"#\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_usermap (void)
|
||||||
|
{
|
||||||
|
usbid_type *usbid = create_usbids_table ();
|
||||||
|
|
||||||
|
print_usermap_header ();
|
||||||
|
while (usbid)
|
||||||
|
{
|
||||||
|
manufacturer_model_type * name = usbid->name;
|
||||||
|
|
||||||
|
printf ("# ");
|
||||||
|
while (name)
|
||||||
|
{
|
||||||
|
if (name != usbid->name)
|
||||||
|
printf (" | ");
|
||||||
|
printf ("%s", name->name);
|
||||||
|
name = name->next;
|
||||||
|
}
|
||||||
|
printf ("\n");
|
||||||
|
printf ("libusbscanner 0x0003 %s %s ", usbid->usb_vendor_id,
|
||||||
|
usbid->usb_product_id);
|
||||||
|
printf ("0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000\n");
|
||||||
|
usbid = usbid->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* print libsane.db file for hotplug-ng */
|
||||||
|
static void
|
||||||
|
print_db_header (void)
|
||||||
|
{
|
||||||
|
time_t current_time = time (0);
|
||||||
|
printf ("# This file was automatically created based on description files (*.desc)\n"
|
||||||
|
"# by sane-desc %s from %s on %s",
|
||||||
|
SANE_DESC_VERSION, PACKAGE_STRING, asctime (localtime (¤t_time)));
|
||||||
|
printf
|
||||||
|
("#\n"
|
||||||
|
"# The entries below are used to detect a USB device when it's plugged in\n"
|
||||||
|
"# and then run a script to change the ownership and\n"
|
||||||
|
"# permissions on the \"device node\" used by libusb.\n"
|
||||||
|
"# Sample entry (replace 0xVVVV and 0xPPPP with vendor ID and product ID\n"
|
||||||
|
"# respectively):\n");
|
||||||
|
printf
|
||||||
|
("#\n"
|
||||||
|
"# 0xVVVV<tab>0xPPPP<tab>root:scanner<tab>0660<tab>[/usr/local/bin/foo.sh]\n"
|
||||||
|
"# Fields:\n"
|
||||||
|
"# vendor ID\n"
|
||||||
|
"# product ID\n"
|
||||||
|
"# ownership (user:group)\n"
|
||||||
|
"# permissions\n"
|
||||||
|
"# path of an optional script to run (it can be omitted)\n");
|
||||||
|
printf
|
||||||
|
("#\n"
|
||||||
|
"# The following list already contains a lot of scanners. If your scanner\n"
|
||||||
|
"# isn't mentioned there, add it as explained above and mail the entry to\n"
|
||||||
|
"# the sane-devel mailing list (sane-devel@lists.alioth.debian.org).\n"
|
||||||
|
"#\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_db (void)
|
||||||
|
{
|
||||||
|
usbid_type *usbid = create_usbids_table ();
|
||||||
|
|
||||||
|
print_db_header ();
|
||||||
|
while (usbid)
|
||||||
|
{
|
||||||
|
manufacturer_model_type * name = usbid->name;
|
||||||
|
|
||||||
|
printf ("# ");
|
||||||
|
while (name)
|
||||||
|
{
|
||||||
|
if (name != usbid->name)
|
||||||
|
printf (" | ");
|
||||||
|
printf ("%s", name->name);
|
||||||
|
name = name->next;
|
||||||
|
}
|
||||||
|
printf ("\n");
|
||||||
|
printf ("%s\t%s\troot:scanner\t0660\t\n", usbid->usb_vendor_id,
|
||||||
|
usbid->usb_product_id);
|
||||||
|
usbid = usbid->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* print libsane.rules for Linux udev */
|
||||||
|
static void
|
||||||
|
print_udev_header (void)
|
||||||
|
{
|
||||||
|
time_t current_time = time (0);
|
||||||
|
printf ("# This file was automatically created based on description files (*.desc)\n"
|
||||||
|
"# by sane-desc %s from %s on %s",
|
||||||
|
SANE_DESC_VERSION, PACKAGE_STRING, asctime (localtime (¤t_time)));
|
||||||
|
|
||||||
|
printf
|
||||||
|
("#\n"
|
||||||
|
"# udev rules file for supported USB devices\n"
|
||||||
|
"#\n"
|
||||||
|
"# To add a USB device, add a rule to the list below between the SUBSYSTEM...\n"
|
||||||
|
"# and LABEL... lines.\n"
|
||||||
|
"#\n"
|
||||||
|
"# To run a script when your device is plugged in, add RUN=\"/path/to/script\"\n"
|
||||||
|
"# to the appropriate rule.\n");
|
||||||
|
printf
|
||||||
|
("#\n"
|
||||||
|
"# The following list already contains a lot of scanners. If your scanner\n"
|
||||||
|
"# isn't mentioned there, add it as explained above and mail the entry to\n"
|
||||||
|
"# the sane-devel mailing list (sane-devel@lists.alioth.debian.org).\n"
|
||||||
|
"#\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_udev (void)
|
||||||
|
{
|
||||||
|
usbid_type *usbid = create_usbids_table ();
|
||||||
|
|
||||||
|
print_udev_header ();
|
||||||
|
printf ("\nSUBSYSTEM!=\"usb_device\", ACTION!=\"add\", GOTO=\"libsane_rules_end\"\n\n");
|
||||||
|
while (usbid)
|
||||||
|
{
|
||||||
|
manufacturer_model_type * name = usbid->name;
|
||||||
|
|
||||||
|
printf ("# ");
|
||||||
|
while (name)
|
||||||
|
{
|
||||||
|
if (name != usbid->name)
|
||||||
|
printf (" | ");
|
||||||
|
printf ("%s", name->name);
|
||||||
|
name = name->next;
|
||||||
|
}
|
||||||
|
printf ("\n");
|
||||||
|
printf ("SYSFS{idVendor}==\"%s\", SYSFS{idProduct}==\"%s\", MODE=\"660\", GROUP=\"scanner\"\n",
|
||||||
|
usbid->usb_vendor_id + 2, usbid->usb_product_id + 2);
|
||||||
|
usbid = usbid->next;
|
||||||
|
}
|
||||||
|
printf ("LABEL=\"libsane_rules_end\"\n");
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -2841,6 +3167,15 @@ main (int argc, char **argv)
|
||||||
case output_mode_statistics:
|
case output_mode_statistics:
|
||||||
print_statistics ();
|
print_statistics ();
|
||||||
break;
|
break;
|
||||||
|
case output_mode_usermap:
|
||||||
|
print_usermap ();
|
||||||
|
break;
|
||||||
|
case output_mode_db:
|
||||||
|
print_db ();
|
||||||
|
break;
|
||||||
|
case output_mode_udev:
|
||||||
|
print_udev ();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
DBG_ERR ("Unknown output mode\n");
|
DBG_ERR ("Unknown output mode\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
|
Ładowanie…
Reference in New Issue