Merge lp:~jfbcable/ubuntu/wily/sane-backends/fix-pixma into lp:ubuntu/wily/sane-backends

Proposed by Julian Cable on 2015-11-08
Status: Needs review
Proposed branch: lp:~jfbcable/ubuntu/wily/sane-backends/fix-pixma
Merge into: lp:ubuntu/wily/sane-backends
Diff against target: 1141205 lines (+1134985/-0) (has conflicts)
1201 files modified
.gitignore (+14/-0)
.pc/.quilt_patches (+1/-0)
.pc/.quilt_series (+1/-0)
.pc/.version (+1/-0)
.pc/0005-mk_reproducible_results.patch/tools/sane-desc.c (+4059/-0)
.pc/001-scanimage_manpage.patch/doc/scanimage.man (+482/-0)
.pc/0105-fuj-126a.patch/backend/fujitsu.c (+10102/-0)
.pc/0105-fuj-126a.patch/backend/fujitsu.h (+862/-0)
.pc/0500-systemd_configure.patch/configure.in (+875/-0)
.pc/0510-disable-html-tests.patch/testsuite/tools/Makefile.am (+43/-0)
.pc/0510-disable-html-tests.patch/testsuite/tools/Makefile.in (+518/-0)
.pc/applied-patches (+23/-0)
.pc/disable_v4l.patch/backend/v4l.conf.in (+10/-0)
.pc/dll_backend_conf.patch/backend/dll.conf.in (+88/-0)
.pc/fix_avahi_error_paths.patch/backend/net.c (+2378/-0)
.pc/frontend_libs.patch/frontend/Makefile.am (+34/-0)
.pc/frontend_libs.patch/frontend/Makefile.in (+772/-0)
.pc/hp3900.patch/backend/hp3900_sane.c (+2734/-0)
.pc/kfreebsd.patch/backend/umax_pp_low.c (+13195/-0)
.pc/libsane_deps.patch/backend/Makefile.am (+1139/-0)
.pc/libsane_deps.patch/backend/Makefile.in (+5514/-0)
.pc/license_typo.patch/po/fr.po (+5703/-0)
.pc/man_typo.patch/doc/sane-mustek_usb.man (+205/-0)
.pc/multiarch_dll_search_path.patch/backend/Makefile.am (+1139/-0)
.pc/multiarch_dll_search_path.patch/backend/Makefile.in (+5514/-0)
.pc/multiarch_dll_search_path.patch/backend/dll.c (+1305/-0)
.pc/multiarch_manpages_libdir.patch/doc/Makefile.in (+1009/-0)
.pc/nousbtest.patch/testsuite/sanei/Makefile.am (+43/-0)
.pc/nousbtest.patch/testsuite/sanei/Makefile.in (+1108/-0)
.pc/ppc64el.patch/configure (+21239/-0)
.pc/ppc64el.patch/m4/libtool.m4 (+7986/-0)
.pc/sane-desc.c_debian_mods.patch/testsuite/tools/data/html-backends-split.ref (+16502/-0)
.pc/sane-desc.c_debian_mods.patch/testsuite/tools/data/html-mfgs.ref (+23916/-0)
.pc/sane-desc.c_debian_mods.patch/tools/sane-desc.c (+4061/-0)
.pc/trim-libraries-in-sane-backends.pc.in.patch/tools/sane-backends.pc.in (+14/-0)
.pc/typo.patch/backend/genesys.conf.in (+134/-0)
.pc/unneeded_doc.patch/Makefile.in (+989/-0)
.pc/unneeded_doc.patch/doc/Makefile.am (+316/-0)
.pc/unneeded_doc.patch/doc/Makefile.in (+1009/-0)
.pc/usb3_timing_fix.patch/backend/genesys_low.c (+1996/-0)
AUTHORS (+253/-0)
COPYING (+340/-0)
ChangeLog (+387/-0)
ChangeLog-1.0.0 (+4309/-0)
ChangeLog-1.0.1 (+449/-0)
ChangeLog-1.0.10 (+890/-0)
ChangeLog-1.0.12 (+960/-0)
ChangeLog-1.0.13 (+1349/-0)
ChangeLog-1.0.14 (+899/-0)
ChangeLog-1.0.15 (+1027/-0)
ChangeLog-1.0.16 (+944/-0)
ChangeLog-1.0.17 (+1011/-0)
ChangeLog-1.0.18 (+973/-0)
ChangeLog-1.0.19 (+1161/-0)
ChangeLog-1.0.2 (+563/-0)
ChangeLog-1.0.20 (+2087/-0)
ChangeLog-1.0.21 (+887/-0)
ChangeLog-1.0.22 (+536/-0)
ChangeLog-1.0.23 (+694/-0)
ChangeLog-1.0.24 (+602/-0)
ChangeLog-1.0.3 (+791/-0)
ChangeLog-1.0.4 (+729/-0)
ChangeLog-1.0.5 (+1194/-0)
ChangeLog-1.0.6 (+667/-0)
ChangeLog-1.0.7 (+856/-0)
ChangeLog-1.0.8 (+1060/-0)
ChangeLog-1.0.9 (+1148/-0)
INSTALL (+370/-0)
LICENSE (+48/-0)
Makefile.am (+94/-0)
Makefile.in (+985/-0)
NEWS (+1104/-0)
PROBLEMS (+22/-0)
PROJECTS (+30/-0)
README (+199/-0)
README.aix (+13/-0)
README.beos (+29/-0)
README.darwin (+49/-0)
README.djpeg (+390/-0)
README.freebsd (+44/-0)
README.hp-ux (+101/-0)
README.linux (+287/-0)
README.netbsd (+59/-0)
README.openbsd (+56/-0)
README.os2 (+261/-0)
README.solaris (+190/-0)
README.unixware2 (+103/-0)
README.unixware7 (+79/-0)
README.windows (+65/-0)
README.zeta (+26/-0)
acinclude.m4 (+764/-0)
aclocal.m4 (+1312/-0)
backend/.gitignore (+5/-0)
backend/Makefile.am (+1139/-0)
backend/Makefile.in (+5513/-0)
backend/abaton.c (+1491/-0)
backend/abaton.conf.in (+2/-0)
backend/abaton.h (+133/-0)
backend/agfafocus.c (+2083/-0)
backend/agfafocus.conf.in (+2/-0)
backend/agfafocus.h (+132/-0)
backend/apple.c (+2690/-0)
backend/apple.conf.in (+2/-0)
backend/apple.h (+270/-0)
backend/artec.c (+3754/-0)
backend/artec.conf.in (+3/-0)
backend/artec.h (+272/-0)
backend/artec_eplus48u.c (+4568/-0)
backend/artec_eplus48u.conf.in (+119/-0)
backend/artec_eplus48u.h (+596/-0)
backend/as6e.c (+942/-0)
backend/as6e.h (+124/-0)
backend/avision.c (+8627/-0)
backend/avision.conf.in (+23/-0)
backend/avision.h (+799/-0)
backend/bh.c (+3883/-0)
backend/bh.conf.in (+2/-0)
backend/bh.h (+1036/-0)
backend/canon-sane.c (+2229/-0)
backend/canon-scsi.c (+733/-0)
backend/canon.c (+1881/-0)
backend/canon.conf.in (+2/-0)
backend/canon.h (+408/-0)
backend/canon630u-common.c (+1656/-0)
backend/canon630u.c (+1044/-0)
backend/canon630u.conf.in (+8/-0)
backend/canon_dr-cmd.h (+578/-0)
backend/canon_dr.c (+8624/-0)
backend/canon_dr.conf.in (+207/-0)
backend/canon_dr.h (+609/-0)
backend/canon_pp-dev.c (+1368/-0)
backend/canon_pp-dev.h (+185/-0)
backend/canon_pp-io.c (+618/-0)
backend/canon_pp-io.h (+65/-0)
backend/canon_pp.c (+2039/-0)
backend/canon_pp.conf.in (+36/-0)
backend/canon_pp.h (+125/-0)
backend/cardscan.c (+1686/-0)
backend/cardscan.conf.in (+17/-0)
backend/cardscan.h (+197/-0)
backend/coolscan-scsidef.h (+839/-0)
backend/coolscan.c (+4195/-0)
backend/coolscan.conf.in (+2/-0)
backend/coolscan.h (+324/-0)
backend/coolscan2.c (+3092/-0)
backend/coolscan2.conf.in (+20/-0)
backend/coolscan3.c (+3188/-0)
backend/coolscan3.conf.in (+20/-0)
backend/dc210.c (+1531/-0)
backend/dc210.conf.in (+29/-0)
backend/dc210.h (+279/-0)
backend/dc240.c (+2150/-0)
backend/dc240.conf.in (+29/-0)
backend/dc240.h (+278/-0)
backend/dc25.c (+2760/-0)
backend/dc25.conf.in (+23/-0)
backend/dc25.h (+276/-0)
backend/dell1600n_net.c (+2065/-0)
backend/dell1600n_net.conf.in (+14/-0)
backend/dll.aliases (+6/-0)
backend/dll.c (+1304/-0)
backend/dll.conf.in (+95/-0)
backend/dmc.c (+1404/-0)
backend/dmc.conf.in (+1/-0)
backend/dmc.h (+125/-0)
backend/epjitsu-cmd.h (+709/-0)
backend/epjitsu.c (+4921/-0)
backend/epjitsu.conf.in (+74/-0)
backend/epjitsu.h (+399/-0)
backend/epson.c (+6417/-0)
backend/epson.conf.in (+27/-0)
backend/epson.h (+262/-0)
backend/epson2-cct.c (+613/-0)
backend/epson2-commands.c (+1091/-0)
backend/epson2-commands.h (+63/-0)
backend/epson2-io.c (+393/-0)
backend/epson2-io.h (+50/-0)
backend/epson2-ops.c (+2222/-0)
backend/epson2-ops.h (+53/-0)
backend/epson2.c (+2375/-0)
backend/epson2.conf.in (+27/-0)
backend/epson2.h (+425/-0)
backend/epson2_net.c (+234/-0)
backend/epson2_net.h (+15/-0)
backend/epson2_scsi.c (+103/-0)
backend/epson2_scsi.h (+24/-0)
backend/epson_scsi.c (+114/-0)
backend/epson_scsi.h (+24/-0)
backend/epson_usb.c (+163/-0)
backend/epson_usb.h (+10/-0)
backend/epsonds-cmd.c (+901/-0)
backend/epsonds-cmd.h (+29/-0)
backend/epsonds-io.c (+177/-0)
backend/epsonds-io.h (+33/-0)
backend/epsonds-jpeg.c (+221/-0)
backend/epsonds-jpeg.h (+19/-0)
backend/epsonds-ops.c (+474/-0)
backend/epsonds-ops.h (+41/-0)
backend/epsonds-usb.c (+33/-0)
backend/epsonds-usb.h (+24/-0)
backend/epsonds.c (+1363/-0)
backend/epsonds.conf.in (+12/-0)
backend/epsonds.h (+199/-0)
backend/fujitsu-scsi.h (+1154/-0)
backend/fujitsu.c (+10110/-0)
backend/fujitsu.conf.in (+155/-0)
backend/fujitsu.h (+863/-0)
backend/genesys.c (+8041/-0)
backend/genesys.conf.in (+134/-0)
backend/genesys.h (+165/-0)
backend/genesys_conv.c (+478/-0)
backend/genesys_conv_hlp.c (+345/-0)
backend/genesys_devices.c (+3670/-0)
backend/genesys_gl124.c (+3823/-0)
backend/genesys_gl124.h (+728/-0)
backend/genesys_gl646.c (+5798/-0)
backend/genesys_gl646.h (+696/-0)
backend/genesys_gl841.c (+6377/-0)
backend/genesys_gl841.h (+456/-0)
backend/genesys_gl843.c (+4476/-0)
backend/genesys_gl843.h (+700/-0)
backend/genesys_gl846.c (+3710/-0)
backend/genesys_gl846.h (+705/-0)
backend/genesys_gl847.c (+3783/-0)
backend/genesys_gl847.h (+695/-0)
backend/genesys_low.c (+2005/-0)
backend/genesys_low.h (+1242/-0)
backend/gphoto2.c (+1995/-0)
backend/gphoto2.conf.in (+32/-0)
backend/gphoto2.h (+200/-0)
backend/gt68xx.c (+2389/-0)
backend/gt68xx.conf.in (+255/-0)
backend/gt68xx.h (+56/-0)
backend/gt68xx_devices.c (+1947/-0)
backend/gt68xx_generic.c (+679/-0)
backend/gt68xx_generic.h (+75/-0)
backend/gt68xx_gt6801.c (+278/-0)
backend/gt68xx_gt6801.h (+71/-0)
backend/gt68xx_gt6816.c (+263/-0)
backend/gt68xx_gt6816.h (+72/-0)
backend/gt68xx_high.c (+2744/-0)
backend/gt68xx_high.h (+374/-0)
backend/gt68xx_low.c (+1034/-0)
backend/gt68xx_low.h (+1099/-0)
backend/gt68xx_mid.c (+1185/-0)
backend/gt68xx_mid.h (+154/-0)
backend/gt68xx_shm_channel.c (+673/-0)
backend/gt68xx_shm_channel.h (+106/-0)
backend/hp-accessor.c (+902/-0)
backend/hp-accessor.h (+88/-0)
backend/hp-device.c (+476/-0)
backend/hp-device.h (+94/-0)
backend/hp-handle.c (+790/-0)
backend/hp-handle.h (+65/-0)
backend/hp-hpmem.c (+151/-0)
backend/hp-option.c (+4087/-0)
backend/hp-option.h (+294/-0)
backend/hp-scl.c (+2118/-0)
backend/hp-scl.h (+166/-0)
backend/hp-scsi.h (+78/-0)
backend/hp.README (+70/-0)
backend/hp.TODO (+52/-0)
backend/hp.c (+1013/-0)
backend/hp.conf.in (+21/-0)
backend/hp.h (+226/-0)
backend/hp3500.c (+3506/-0)
backend/hp3900.c (+61/-0)
backend/hp3900.conf.in (+31/-0)
backend/hp3900_config.c (+6055/-0)
backend/hp3900_debug.c (+1581/-0)
backend/hp3900_rts8822.c (+15123/-0)
backend/hp3900_sane.c (+2734/-0)
backend/hp3900_types.c (+783/-0)
backend/hp3900_usb.c (+509/-0)
backend/hp4200.c (+2979/-0)
backend/hp4200.conf.in (+6/-0)
backend/hp4200.h (+266/-0)
backend/hp4200_lm9830.c (+219/-0)
backend/hp4200_lm9830.h (+184/-0)
backend/hp5400.c (+82/-0)
backend/hp5400.conf.in (+14/-0)
backend/hp5400.h (+143/-0)
backend/hp5400_debug.c (+73/-0)
backend/hp5400_debug.h (+81/-0)
backend/hp5400_internal.c (+1455/-0)
backend/hp5400_internal.h (+276/-0)
backend/hp5400_sane.c (+1022/-0)
backend/hp5400_sanei.c (+387/-0)
backend/hp5400_sanei.h (+108/-0)
backend/hp5400_xfer.h (+77/-0)
backend/hp5590.c (+1389/-0)
backend/hp5590_cmds.c (+2274/-0)
backend/hp5590_cmds.h (+202/-0)
backend/hp5590_low.c (+965/-0)
backend/hp5590_low.h (+89/-0)
backend/hpljm1005.c (+1104/-0)
backend/hpsj5s.c (+1568/-0)
backend/hpsj5s.conf.in (+2/-0)
backend/hpsj5s.h (+102/-0)
backend/hs2p-saneopts.h (+365/-0)
backend/hs2p-scsi.c (+2198/-0)
backend/hs2p-scsi.h (+1290/-0)
backend/hs2p.c (+3332/-0)
backend/hs2p.conf.in (+2/-0)
backend/hs2p.h (+516/-0)
backend/ibm-scsi.c (+439/-0)
backend/ibm.c (+1183/-0)
backend/ibm.conf.in (+3/-0)
backend/ibm.h (+386/-0)
backend/kodak-cmd.h (+645/-0)
backend/kodak.c (+2913/-0)
backend/kodak.conf.in (+14/-0)
backend/kodak.h (+272/-0)
backend/kodakaio.c (+3542/-0)
backend/kodakaio.conf.in (+80/-0)
backend/kodakaio.h (+201/-0)
backend/kvs1025.c (+456/-0)
backend/kvs1025.conf.in (+2/-0)
backend/kvs1025.h (+127/-0)
backend/kvs1025_cmds.h (+74/-0)
backend/kvs1025_low.c (+1178/-0)
backend/kvs1025_low.h (+290/-0)
backend/kvs1025_opt.c (+1581/-0)
backend/kvs1025_usb.c (+370/-0)
backend/kvs1025_usb.h (+28/-0)
backend/kvs20xx.c (+535/-0)
backend/kvs20xx.h (+211/-0)
backend/kvs20xx_cmd.c (+379/-0)
backend/kvs20xx_cmd.h (+128/-0)
backend/kvs20xx_opt.c (+801/-0)
backend/kvs40xx.c (+748/-0)
backend/kvs40xx.h (+275/-0)
backend/kvs40xx_cmd.c (+601/-0)
backend/kvs40xx_opt.c (+1414/-0)
backend/leo.c (+2014/-0)
backend/leo.conf.in (+8/-0)
backend/leo.h (+554/-0)
backend/lexmark.c (+1348/-0)
backend/lexmark.conf.in (+8/-0)
backend/lexmark.h (+281/-0)
backend/lexmark_low.c (+6106/-0)
backend/lexmark_models.c (+116/-0)
backend/lexmark_sensors.c (+134/-0)
backend/lm9830.h (+58/-0)
backend/ma1509.c (+2020/-0)
backend/ma1509.conf.in (+10/-0)
backend/ma1509.h (+177/-0)
backend/magicolor.c (+3006/-0)
backend/magicolor.conf.in (+42/-0)
backend/magicolor.h (+233/-0)
backend/matsushita.c (+2512/-0)
backend/matsushita.conf.in (+23/-0)
backend/matsushita.h (+369/-0)
backend/microtek.c (+4187/-0)
backend/microtek.conf.in (+7/-0)
backend/microtek.h (+379/-0)
backend/microtek2.c (+8409/-0)
backend/microtek2.conf.in (+11/-0)
backend/microtek2.h (+1384/-0)
backend/mustek.c (+6776/-0)
backend/mustek.conf.in (+41/-0)
backend/mustek.h (+303/-0)
backend/mustek_pp.c (+1958/-0)
backend/mustek_pp.conf.in (+103/-0)
backend/mustek_pp.h (+286/-0)
backend/mustek_pp_ccd300.c (+2061/-0)
backend/mustek_pp_ccd300.h (+102/-0)
backend/mustek_pp_cis.c (+2854/-0)
backend/mustek_pp_cis.h (+273/-0)
backend/mustek_pp_decl.h (+83/-0)
backend/mustek_pp_drivers.h (+72/-0)
backend/mustek_pp_null.c (+153/-0)
backend/mustek_scsi_pp.c (+1086/-0)
backend/mustek_scsi_pp.h (+123/-0)
backend/mustek_usb.c (+1610/-0)
backend/mustek_usb.conf.in (+39/-0)
backend/mustek_usb.h (+62/-0)
backend/mustek_usb2.c (+2696/-0)
backend/mustek_usb2.h (+158/-0)
backend/mustek_usb2_asic.c (+5264/-0)
backend/mustek_usb2_asic.h (+1421/-0)
backend/mustek_usb2_high.c (+3240/-0)
backend/mustek_usb2_high.h (+263/-0)
backend/mustek_usb2_reflective.c (+1943/-0)
backend/mustek_usb2_transparent.c (+1745/-0)
backend/mustek_usb_high.c (+2751/-0)
backend/mustek_usb_high.h (+591/-0)
backend/mustek_usb_low.c (+2914/-0)
backend/mustek_usb_low.h (+450/-0)
backend/mustek_usb_mid.c (+2688/-0)
backend/mustek_usb_mid.h (+390/-0)
backend/nec.c (+3717/-0)
backend/nec.conf.in (+1/-0)
backend/nec.h (+447/-0)
backend/net.c (+2378/-0)
backend/net.conf.in (+14/-0)
backend/net.h (+88/-0)
backend/niash.c (+1486/-0)
backend/niash_core.c (+1362/-0)
backend/niash_core.h (+136/-0)
backend/niash_xfer.c (+330/-0)
backend/niash_xfer.h (+95/-0)
backend/p5.c (+2048/-0)
backend/p5.conf.in (+10/-0)
backend/p5.h (+205/-0)
backend/p5_device.c (+1611/-0)
backend/p5_device.h (+304/-0)
backend/pie-scsidef.h (+433/-0)
backend/pie.c (+3828/-0)
backend/pie.conf.in (+4/-0)
backend/pint.c (+987/-0)
backend/pint.h (+105/-0)
backend/pixma.c (+1825/-0)
backend/pixma.conf.in (+14/-0)
backend/pixma.h (+490/-0)
backend/pixma_bjnp.c (+2486/-0)
backend/pixma_bjnp.h (+202/-0)
backend/pixma_bjnp_private.h (+383/-0)
backend/pixma_common.c (+1177/-0)
backend/pixma_common.h (+231/-0)
backend/pixma_imageclass.c (+820/-0)
backend/pixma_io.h (+186/-0)
backend/pixma_io_sanei.c (+592/-0)
backend/pixma_mp150.c (+1830/-0)
backend/pixma_mp730.c (+828/-0)
backend/pixma_mp750.c (+970/-0)
backend/pixma_mp810.c (+2382/-0)
backend/pixma_rename.h (+105/-0)
backend/pixma_sane_options.c (+346/-0)
backend/pixma_sane_options.h (+51/-0)
backend/plustek-pp.h (+640/-0)
backend/plustek-pp_dac.c (+2658/-0)
backend/plustek-pp_dbg.h (+101/-0)
backend/plustek-pp_detect.c (+526/-0)
backend/plustek-pp_genericio.c (+1463/-0)
backend/plustek-pp_hwdefs.h (+1034/-0)
backend/plustek-pp_image.c (+1652/-0)
backend/plustek-pp_io.c (+999/-0)
backend/plustek-pp_map.c (+304/-0)
backend/plustek-pp_misc.c (+823/-0)
backend/plustek-pp_models.c (+614/-0)
backend/plustek-pp_motor.c (+3348/-0)
backend/plustek-pp_p12.c (+778/-0)
backend/plustek-pp_p12ccd.c (+1149/-0)
backend/plustek-pp_p48xx.c (+877/-0)
backend/plustek-pp_p9636.c (+1088/-0)
backend/plustek-pp_procfs.c (+474/-0)
backend/plustek-pp_procs.h (+255/-0)
backend/plustek-pp_ptdrv.c (+1987/-0)
backend/plustek-pp_scale.c (+149/-0)
backend/plustek-pp_scan.h (+202/-0)
backend/plustek-pp_scandata.h (+642/-0)
backend/plustek-pp_sysdep.h (+362/-0)
backend/plustek-pp_tpa.c (+1174/-0)
backend/plustek-pp_types.h (+191/-0)
backend/plustek-pp_wrapper.c (+361/-0)
backend/plustek-usb.c (+1526/-0)
backend/plustek-usb.h (+725/-0)
backend/plustek-usbcal.c (+1388/-0)
backend/plustek-usbcalfile.c (+845/-0)
backend/plustek-usbdevs.c (+3095/-0)
backend/plustek-usbhw.c (+1848/-0)
backend/plustek-usbimg.c (+1984/-0)
backend/plustek-usbio.c (+351/-0)
backend/plustek-usbmap.c (+210/-0)
backend/plustek-usbscan.c (+1666/-0)
backend/plustek-usbshading.c (+3215/-0)
backend/plustek.c (+2806/-0)
backend/plustek.conf.in (+184/-0)
backend/plustek.h (+431/-0)
backend/plustek_pp.c (+2180/-0)
backend/plustek_pp.conf.in (+40/-0)
backend/pnm.c (+1395/-0)
backend/qcam.c (+2264/-0)
backend/qcam.conf.in (+12/-0)
backend/qcam.h (+190/-0)
backend/ricoh-scsi.c (+413/-0)
backend/ricoh.c (+1025/-0)
backend/ricoh.conf.in (+2/-0)
backend/ricoh.h (+330/-0)
backend/rts8891.c (+7815/-0)
backend/rts8891.conf.in (+9/-0)
backend/rts8891.h (+155/-0)
backend/rts8891_devices.c (+248/-0)
backend/rts8891_low.c (+869/-0)
backend/rts8891_low.h (+301/-0)
backend/rts88xx_lib.c (+870/-0)
backend/rts88xx_lib.h (+213/-0)
backend/s9036.c (+1341/-0)
backend/s9036.conf.in (+1/-0)
backend/s9036.h (+83/-0)
backend/sane_strstatus.c (+109/-0)
backend/saned.conf.in (+31/-0)
backend/sceptre.c (+2094/-0)
backend/sceptre.conf.in (+2/-0)
backend/sceptre.h (+414/-0)
backend/scripts/pixma_gen_options.py (+390/-0)
backend/sharp.c (+4213/-0)
backend/sharp.conf.in (+42/-0)
backend/sharp.h (+462/-0)
backend/sm3600-color.c (+313/-0)
backend/sm3600-gray.c (+389/-0)
backend/sm3600-homerun.c (+499/-0)
backend/sm3600-scanmtek.c (+310/-0)
backend/sm3600-scantool.h (+134/-0)
backend/sm3600-scanusb.c (+443/-0)
backend/sm3600-scanutil.c (+440/-0)
backend/sm3600.c (+804/-0)
backend/sm3600.h (+315/-0)
backend/sm3840.c (+846/-0)
backend/sm3840.conf.in (+5/-0)
backend/sm3840.h (+125/-0)
backend/sm3840_lib.c (+1004/-0)
backend/sm3840_lib.h (+152/-0)
backend/sm3840_params.h (+74/-0)
backend/sm3840_scan.c (+946/-0)
backend/snapscan-data.c (+4150/-0)
backend/snapscan-mutex.c (+183/-0)
backend/snapscan-options.c (+1922/-0)
backend/snapscan-scsi.c (+1948/-0)
backend/snapscan-sources.c (+1385/-0)
backend/snapscan-sources.h (+109/-0)
backend/snapscan-usb.c (+656/-0)
backend/snapscan-usb.h (+128/-0)
backend/snapscan.c (+2646/-0)
backend/snapscan.conf.in (+115/-0)
backend/snapscan.h (+751/-0)
backend/sp15c-scsi.h (+566/-0)
backend/sp15c.c (+2232/-0)
backend/sp15c.conf.in (+1/-0)
backend/sp15c.h (+336/-0)
backend/st400.c (+1309/-0)
backend/st400.conf.in (+53/-0)
backend/st400.h (+79/-0)
backend/stubs.c (+85/-0)
backend/stv680.c (+2180/-0)
backend/stv680.conf.in (+10/-0)
backend/stv680.h (+302/-0)
backend/tamarack.c (+1474/-0)
backend/tamarack.conf.in (+3/-0)
backend/tamarack.h (+267/-0)
backend/teco1.c (+2263/-0)
backend/teco1.conf.in (+17/-0)
backend/teco1.h (+399/-0)
backend/teco2.c (+3455/-0)
backend/teco2.conf.in (+29/-0)
backend/teco2.h (+465/-0)
backend/teco3.c (+2255/-0)
backend/teco3.conf.in (+11/-0)
backend/teco3.h (+427/-0)
backend/test-picture.c (+849/-0)
backend/test.c (+2841/-0)
backend/test.conf.in (+87/-0)
backend/test.h (+146/-0)
backend/u12-ccd.c (+1121/-0)
backend/u12-hw.c (+978/-0)
backend/u12-hwdef.h (+473/-0)
backend/u12-if.c (+602/-0)
backend/u12-image.c (+908/-0)
backend/u12-io.c (+851/-0)
backend/u12-map.c (+192/-0)
backend/u12-motor.c (+519/-0)
backend/u12-scanner.h (+306/-0)
backend/u12-shading.c (+877/-0)
backend/u12-tpa.c (+441/-0)
backend/u12.c (+1869/-0)
backend/u12.conf.in (+67/-0)
backend/u12.h (+336/-0)
backend/umax-scanner.c (+136/-0)
backend/umax-scanner.h (+61/-0)
backend/umax-scsidef.h (+1091/-0)
backend/umax-uc1200s.c (+204/-0)
backend/umax-uc1200se.c (+204/-0)
backend/umax-uc1260.c (+204/-0)
backend/umax-uc630.c (+195/-0)
backend/umax-uc840.c (+195/-0)
backend/umax-ug630.c (+195/-0)
backend/umax-ug80.c (+198/-0)
backend/umax-usb.c (+324/-0)
backend/umax.c (+8131/-0)
backend/umax.conf.in (+117/-0)
backend/umax.h (+499/-0)
backend/umax1220u-common.c (+2386/-0)
backend/umax1220u.c (+960/-0)
backend/umax1220u.conf.in (+14/-0)
backend/umax_pp.c (+2404/-0)
backend/umax_pp.conf.in (+64/-0)
backend/umax_pp.h (+207/-0)
backend/umax_pp_low.c (+13197/-0)
backend/umax_pp_low.h (+123/-0)
backend/umax_pp_mid.c (+475/-0)
backend/umax_pp_mid.h (+191/-0)
backend/v4l-frequencies.h (+113/-0)
backend/v4l.c (+1137/-0)
backend/v4l.conf.in (+12/-0)
backend/v4l.h (+242/-0)
backend/xerox_mfp-tcp.c (+182/-0)
backend/xerox_mfp-usb.c (+112/-0)
backend/xerox_mfp.c (+1343/-0)
backend/xerox_mfp.conf.in (+212/-0)
backend/xerox_mfp.h (+216/-0)
compile (+347/-0)
config.guess (+1558/-0)
config.sub (+1793/-0)
configure (+21245/-0)
configure.in (+898/-0)
debian/TROUBLESHOOTING.Debian (+13/-0)
debian/changelog (+2632/-0)
debian/compat (+1/-0)
debian/control (+151/-0)
debian/copyright (+1399/-0)
debian/libsane-common.doc-base (+7/-0)
debian/libsane-common.examples (+2/-0)
debian/libsane-common.install.in (+6/-0)
debian/libsane-common.links (+1/-0)
debian/libsane-common.postrm (+11/-0)
debian/libsane-common.preinst (+12/-0)
debian/libsane-dev.doc-base (+16/-0)
debian/libsane-dev.install (+7/-0)
debian/libsane-dev.links (+3/-0)
debian/libsane.NEWS (+19/-0)
debian/libsane.README.Debian (+181/-0)
debian/libsane.docs (+1/-0)
debian/libsane.install (+4/-0)
debian/libsane.postinst (+36/-0)
debian/libsane.shlibs (+1/-0)
debian/libsane.symbols (+2065/-0)
debian/libsane1.docs (+1/-0)
debian/libsane1.install (+4/-0)
debian/libsane1.postinst (+36/-0)
debian/libsane1.shlibs (+1/-0)
debian/libsane1.symbols (+2065/-0)
debian/patches/0005-mk_reproducible_results.patch (+22/-0)
debian/patches/001-scanimage_manpage.patch (+21/-0)
debian/patches/0100-usb3-corrections.patch (+168/-0)
debian/patches/0105-fuj-126a.patch (+68/-0)
debian/patches/0500-systemd_configure.patch (+60/-0)
debian/patches/0510-disable-html-tests.patch (+35/-0)
debian/patches/99-fix-pixma.patch (+15/-0)
debian/patches/disable_v4l.patch (+25/-0)
debian/patches/dll_backend_conf.patch (+33/-0)
debian/patches/fix-FTBFS-format-not-a-string-literal-error.patch (+28/-0)
debian/patches/fix_avahi_error_paths.patch (+32/-0)
debian/patches/frontend_libs.patch (+46/-0)
debian/patches/hp3900.patch (+20/-0)
debian/patches/hp5370c.patch (+20/-0)
debian/patches/kfreebsd.patch (+15/-0)
debian/patches/kodakaio.patch (+63/-0)
debian/patches/libsane_deps.patch (+43/-0)
debian/patches/license_typo.patch (+21/-0)
debian/patches/man-page-spelling.patch (+218/-0)
debian/patches/man_typo.patch (+18/-0)
debian/patches/multiarch_dll_search_path.patch (+59/-0)
debian/patches/multiarch_manpages_libdir.patch (+18/-0)
debian/patches/nousbtest.patch (+36/-0)
debian/patches/out_of_bounds.patch (+85/-0)
debian/patches/ppc64el.patch (+74/-0)
debian/patches/sane-desc.c_debian_mods.patch (+15636/-0)
debian/patches/saned.man.patch (+15/-0)
debian/patches/series (+32/-0)
debian/patches/source-spelling.patch (+565/-0)
debian/patches/trim-libraries-in-sane-backends.pc.in.patch (+24/-0)
debian/patches/typo.patch (+20/-0)
debian/patches/unneeded_doc.patch (+58/-0)
debian/patches/usb3_timing_fix.patch (+40/-0)
debian/po/POTFILES.in (+1/-0)
debian/po/ca.po (+116/-0)
debian/po/cs.po (+110/-0)
debian/po/da.po (+111/-0)
debian/po/de.po (+114/-0)
debian/po/es.po (+140/-0)
debian/po/eu.po (+116/-0)
debian/po/fi.po (+115/-0)
debian/po/fr.po (+118/-0)
debian/po/gl.po (+125/-0)
debian/po/it.po (+112/-0)
debian/po/ja.po (+111/-0)
debian/po/nl.po (+115/-0)
debian/po/pl.po (+114/-0)
debian/po/pt.po (+112/-0)
debian/po/pt_BR.po (+114/-0)
debian/po/ru.po (+114/-0)
debian/po/sk.po (+112/-0)
debian/po/sv.po (+111/-0)
debian/po/templates.pot (+91/-0)
debian/po/vi.po (+113/-0)
debian/po/zh_CN.po (+105/-0)
debian/rules (+144/-0)
debian/sane-utils.README.Debian (+83/-0)
debian/sane-utils.config (+18/-0)
debian/sane-utils.install (+12/-0)
debian/sane-utils.links (+1/-0)
debian/sane-utils.lintian-overrides (+14/-0)
debian/sane-utils.postinst (+88/-0)
debian/sane-utils.postrm (+52/-0)
debian/sane-utils.saned.default (+8/-0)
debian/sane-utils.saned.init (+101/-0)
debian/sane-utils.templates (+35/-0)
debian/saned.socket (+10/-0)
debian/saned@.service (+16/-0)
debian/source.lintian-overrides (+4/-0)
debian/source/format (+1/-0)
debian/tests/control (+9/-0)
debian/tests/start-net (+29/-0)
debian/upstream/metadata (+6/-0)
debian/watch (+8/-0)
depcomp (+791/-0)
doc/.gitignore (+21/-0)
doc/Makefile.am (+316/-0)
doc/Makefile.in (+1009/-0)
doc/backend-writing.txt (+500/-0)
doc/canon/canon.changes (+42/-0)
doc/canon/canon.install2700F.txt (+135/-0)
doc/descriptions-external/brother-mfc4600.desc (+37/-0)
doc/descriptions-external/brother.desc (+409/-0)
doc/descriptions-external/brother2.desc (+235/-0)
doc/descriptions-external/canon_mfp.desc (+73/-0)
doc/descriptions-external/cs3200f.desc (+34/-0)
doc/descriptions-external/epkowa.desc (+3124/-0)
doc/descriptions-external/geniusvp2.desc (+26/-0)
doc/descriptions-external/hp3770.desc (+39/-0)
doc/descriptions-external/hp8200.desc (+40/-0)
doc/descriptions-external/hpaio.desc (+2241/-0)
doc/descriptions-external/hpoj.desc (+34/-0)
doc/descriptions-external/kodak-twain.desc (+87/-0)
doc/descriptions-external/lhii.desc (+46/-0)
doc/descriptions-external/mustek_a3p1.desc (+21/-0)
doc/descriptions-external/panamfs.desc (+57/-0)
doc/descriptions-external/primascan.desc (+33/-0)
doc/descriptions-external/primax.desc (+46/-0)
doc/descriptions-external/samsung.desc (+88/-0)
doc/descriptions-external/scanwit.desc (+27/-0)
doc/descriptions-external/template.desc. (+81/-0)
doc/descriptions-external/v4l2.desc (+21/-0)
doc/descriptions-external/viceo.desc (+75/-0)
doc/descriptions.txt (+130/-0)
doc/descriptions/abaton.desc (+20/-0)
doc/descriptions/agfafocus.desc (+40/-0)
doc/descriptions/apple.desc (+26/-0)
doc/descriptions/artec.desc (+72/-0)
doc/descriptions/artec_eplus48u.desc (+106/-0)
doc/descriptions/as6e.desc (+44/-0)
doc/descriptions/avision.desc (+857/-0)
doc/descriptions/bh.desc (+56/-0)
doc/descriptions/canon.desc (+65/-0)
doc/descriptions/canon630u.desc (+37/-0)
doc/descriptions/canon_dr.desc (+393/-0)
doc/descriptions/canon_pp.desc (+62/-0)
doc/descriptions/cardscan.desc (+35/-0)
doc/descriptions/coolscan.desc (+43/-0)
doc/descriptions/coolscan2.desc (+65/-0)
doc/descriptions/coolscan3.desc (+75/-0)
doc/descriptions/dc210.desc (+14/-0)
doc/descriptions/dc240.desc (+15/-0)
doc/descriptions/dc25.desc (+16/-0)
doc/descriptions/dell1600n_net.desc (+17/-0)
doc/descriptions/dll.desc (+7/-0)
doc/descriptions/dmc.desc (+29/-0)
doc/descriptions/epjitsu.desc (+65/-0)
doc/descriptions/epson.desc (+356/-0)
doc/descriptions/epson2.desc (+3095/-0)
doc/descriptions/epsonds.desc (+97/-0)
doc/descriptions/fujitsu.desc (+468/-0)
doc/descriptions/genesys.desc (+313/-0)
doc/descriptions/gphoto2.desc (+13/-0)
doc/descriptions/gt68xx.desc (+472/-0)
doc/descriptions/hp.desc (+120/-0)
doc/descriptions/hp3500.desc (+47/-0)
doc/descriptions/hp3900.desc (+82/-0)
doc/descriptions/hp4200.desc (+43/-0)
doc/descriptions/hp5400.desc (+47/-0)
doc/descriptions/hp5590.desc (+55/-0)
doc/descriptions/hpljm1005.desc (+36/-0)
doc/descriptions/hpsj5s.desc (+32/-0)
doc/descriptions/hs2p.desc (+41/-0)
doc/descriptions/ibm.desc (+42/-0)
doc/descriptions/kodak.desc (+190/-0)
doc/descriptions/kodakaio.desc (+186/-0)
doc/descriptions/kvs1025.desc (+34/-0)
doc/descriptions/kvs20xx.desc (+48/-0)
doc/descriptions/kvs40xx.desc (+36/-0)
doc/descriptions/leo.desc (+36/-0)
doc/descriptions/lexmark.desc (+89/-0)
doc/descriptions/ma1509.desc (+38/-0)
doc/descriptions/magicolor.desc (+36/-0)
doc/descriptions/matsushita.desc (+74/-0)
doc/descriptions/microtek.desc (+96/-0)
doc/descriptions/microtek2.desc (+167/-0)
doc/descriptions/mustek.desc (+174/-0)
doc/descriptions/mustek_pp.desc (+163/-0)
doc/descriptions/mustek_usb.desc (+41/-0)
doc/descriptions/mustek_usb2.desc (+16/-0)
doc/descriptions/nec.desc (+14/-0)
doc/descriptions/net.desc (+8/-0)
doc/descriptions/niash.desc (+63/-0)
doc/descriptions/p5.desc (+31/-0)
doc/descriptions/pie.desc (+98/-0)
doc/descriptions/pint.desc (+10/-0)
doc/descriptions/pixma.desc (+1056/-0)
doc/descriptions/plustek.desc (+284/-0)
doc/descriptions/plustek_pp.desc (+156/-0)
doc/descriptions/pnm.desc (+8/-0)
doc/descriptions/qcam.desc (+19/-0)
doc/descriptions/ricoh.desc (+29/-0)
doc/descriptions/rts8891.desc (+52/-0)
doc/descriptions/s9036.desc (+14/-0)
doc/descriptions/sceptre.desc (+30/-0)
doc/descriptions/sharp.desc (+40/-0)
doc/descriptions/sm3600.desc (+53/-0)
doc/descriptions/sm3840.desc (+56/-0)
doc/descriptions/snapscan.desc (+353/-0)
doc/descriptions/sp15c.desc (+31/-0)
doc/descriptions/st400.desc (+20/-0)
doc/descriptions/stv680.desc (+63/-0)
doc/descriptions/tamarack.desc (+35/-0)
doc/descriptions/teco1.desc (+127/-0)
doc/descriptions/teco2.desc (+83/-0)
doc/descriptions/teco3.desc (+62/-0)
doc/descriptions/template.desc. (+81/-0)
doc/descriptions/test.desc (+23/-0)
doc/descriptions/u12.desc (+61/-0)
doc/descriptions/umax.desc (+382/-0)
doc/descriptions/umax1220u.desc (+47/-0)
doc/descriptions/umax_pp.desc (+63/-0)
doc/descriptions/unsupported.desc (+2757/-0)
doc/descriptions/v4l.desc (+25/-0)
doc/descriptions/xerox_mfp.desc (+354/-0)
doc/doxygen-genesys.conf.in (+1793/-0)
doc/doxygen-sanei.conf.in (+1473/-0)
doc/figs/area.eps (+126/-0)
doc/figs/area.fig (+36/-0)
doc/figs/flow.eps (+161/-0)
doc/figs/flow.fig (+40/-0)
doc/figs/hierarchy.eps (+209/-0)
doc/figs/hierarchy.fig (+79/-0)
doc/figs/image-data.eps (+178/-0)
doc/figs/image-data.fig (+63/-0)
doc/figs/xfer.eps (+117/-0)
doc/figs/xfer.fig (+32/-0)
doc/gamma4scanimage.man (+66/-0)
doc/gt68xx/gt68xx.CHANGES (+720/-0)
doc/gt68xx/gt68xx.TODO (+105/-0)
doc/html.sty (+232/-0)
doc/leo/leo.txt (+141/-0)
doc/matsushita/matsushita.txt (+189/-0)
doc/mustek/mustek.CHANGES (+995/-0)
doc/mustek_usb/mustek_usb.CHANGES (+421/-0)
doc/mustek_usb/mustek_usb.TODO (+10/-0)
doc/mustek_usb2/mustek_usb2.CHANGES (+137/-0)
doc/mustek_usb2/mustek_usb2.TODO (+9/-0)
doc/net.tex (+479/-0)
doc/niash/niash.TODO (+64/-0)
doc/plustek/FAQ (+385/-0)
doc/plustek/MakeModule.sh (+116/-0)
doc/plustek/Makefile.kernel24 (+251/-0)
doc/plustek/Makefile.kernel26 (+124/-0)
doc/plustek/Plustek-PARPORT-TODO.txt (+38/-0)
doc/plustek/Plustek-PARPORT.changes (+180/-0)
doc/plustek/Plustek-PARPORT.txt (+49/-0)
doc/plustek/Plustek-USB-TODO.txt (+53/-0)
doc/plustek/Plustek-USB.changes (+307/-0)
doc/plustek/Plustek-USB.txt (+457/-0)
doc/releases.txt (+86/-0)
doc/sane-abaton.man (+126/-0)
doc/sane-agfafocus.man (+175/-0)
doc/sane-apple.man (+252/-0)
doc/sane-artec.man (+178/-0)
doc/sane-artec_eplus48u.man (+144/-0)
doc/sane-as6e.man (+45/-0)
doc/sane-avision.man (+165/-0)
doc/sane-bh.man (+547/-0)
doc/sane-canon.man (+101/-0)
doc/sane-canon630u.man (+106/-0)
doc/sane-canon_dr.man (+221/-0)
doc/sane-canon_pp.man (+232/-0)
doc/sane-cardscan.man (+114/-0)
doc/sane-config.man (+51/-0)
doc/sane-coolscan.man (+111/-0)
doc/sane-coolscan2.man (+182/-0)
doc/sane-coolscan3.man (+182/-0)
doc/sane-dc210.man (+107/-0)
doc/sane-dc240.man (+113/-0)
doc/sane-dc25.man (+99/-0)
doc/sane-dll.man (+178/-0)
doc/sane-dmc.man (+140/-0)
doc/sane-epjitsu.man (+106/-0)
doc/sane-epson.man (+306/-0)
doc/sane-epson2.man (+358/-0)
doc/sane-epsonds.man (+101/-0)
doc/sane-find-scanner.man (+134/-0)
doc/sane-fujitsu.man (+236/-0)
doc/sane-genesys.man (+321/-0)
doc/sane-gphoto2.man (+118/-0)
doc/sane-gt68xx.man (+218/-0)
doc/sane-hp.man (+273/-0)
doc/sane-hp3500.man (+53/-0)
doc/sane-hp3900.man (+110/-0)
doc/sane-hp4200.man (+105/-0)
doc/sane-hp5400.man (+102/-0)
doc/sane-hp5590.man (+69/-0)
doc/sane-hpljm1005.man (+37/-0)
doc/sane-hpsj5s.man (+103/-0)
doc/sane-hs2p.man (+120/-0)
doc/sane-ibm.man (+88/-0)
doc/sane-kodak.man (+142/-0)
doc/sane-kodakaio.man (+40/-0)
doc/sane-kvs1025.man (+31/-0)
doc/sane-kvs20xx.man (+29/-0)
doc/sane-kvs40xx.man (+31/-0)
doc/sane-leo.man (+157/-0)
doc/sane-lexmark.man (+151/-0)
doc/sane-ma1509.man (+134/-0)
doc/sane-magicolor.man (+72/-0)
doc/sane-matsushita.man (+169/-0)
doc/sane-microtek.man (+194/-0)
doc/sane-microtek2.man (+318/-0)
doc/sane-mustek.man (+407/-0)
doc/sane-mustek_pp.man (+490/-0)
doc/sane-mustek_usb.man (+206/-0)
doc/sane-mustek_usb2.man (+72/-0)
doc/sane-nec.man (+59/-0)
doc/sane-net.man (+155/-0)
doc/sane-niash.man (+81/-0)
doc/sane-p5.man (+160/-0)
doc/sane-pie.man (+58/-0)
doc/sane-pint.man (+123/-0)
doc/sane-pixma.man (+353/-0)
doc/sane-plustek.man (+521/-0)
doc/sane-plustek_pp.man (+518/-0)
doc/sane-pnm.man (+46/-0)
doc/sane-qcam.man (+92/-0)
doc/sane-ricoh.man (+79/-0)
doc/sane-rts8891.man (+159/-0)
doc/sane-s9036.man (+71/-0)
doc/sane-sceptre.man (+152/-0)
doc/sane-scsi.man (+328/-0)
doc/sane-sharp.man (+505/-0)
doc/sane-sm3600.man (+82/-0)
doc/sane-sm3840.man (+95/-0)
doc/sane-snapscan.man (+111/-0)
doc/sane-sp15c.man (+77/-0)
doc/sane-st400.man (+146/-0)
doc/sane-stv680.man (+176/-0)
doc/sane-tamarack.man (+80/-0)
doc/sane-teco1.man (+197/-0)
doc/sane-teco2.man (+229/-0)
doc/sane-teco3.man (+154/-0)
doc/sane-test.man (+324/-0)
doc/sane-u12.man (+184/-0)
doc/sane-umax.man (+276/-0)
doc/sane-umax1220u.man (+116/-0)
doc/sane-umax_pp.man (+302/-0)
doc/sane-usb.man (+149/-0)
doc/sane-v4l.man (+91/-0)
doc/sane-xerox_mfp.man (+85/-0)
doc/sane.man (+928/-0)
doc/sane.tex (+1894/-0)
doc/saned.man (+325/-0)
doc/scanimage.man (+485/-0)
doc/sceptre/s1200.txt (+109/-0)
doc/teco/teco1.txt (+193/-0)
doc/teco/teco2.txt (+267/-0)
doc/teco/teco3.txt (+166/-0)
doc/u12/U12.changes (+36/-0)
doc/u12/U12.todo (+12/-0)
doc/umax/negative-types.txt (+15/-0)
doc/umax/sane-umax-advanced-options-doc.html (+178/-0)
doc/umax/sane-umax-astra-doc.html (+580/-0)
doc/umax/sane-umax-config-doc.html (+431/-0)
doc/umax/sane-umax-doc.html (+85/-0)
doc/umax/sane-umax-mirage-doc.html (+281/-0)
doc/umax/sane-umax-not-listed-doc.html (+107/-0)
doc/umax/sane-umax-others-doc.html (+239/-0)
doc/umax/sane-umax-parport-doc.html (+95/-0)
doc/umax/sane-umax-powerlook-doc.html (+539/-0)
doc/umax/sane-umax-scanner-clones-doc.html (+1054/-0)
doc/umax/sane-umax-speed-doc.html (+509/-0)
doc/umax/sane-umax-standard-options-doc.html (+274/-0)
doc/umax/sane-umax-uc-doc.html (+741/-0)
doc/umax/sane-umax-vista-doc.html (+701/-0)
doc/umax/umax.BUGS (+12/-0)
doc/umax/umax.CHANGES (+1172/-0)
doc/umax/umax.FAQ (+147/-0)
doc/umax/umax.TODO (+22/-0)
frontend/.gitignore (+3/-0)
frontend/Makefile.am (+34/-0)
frontend/Makefile.in (+772/-0)
frontend/saned.c (+3355/-0)
frontend/scanimage.c (+2392/-0)
frontend/stiff.c (+610/-0)
frontend/stiff.h (+20/-0)
frontend/test.c (+182/-0)
frontend/tstbackend.c (+1871/-0)
include/.gitignore (+3/-0)
include/Makefile.am (+18/-0)
include/Makefile.in (+614/-0)
include/font_6x11.h (+3337/-0)
include/lalloca.h (+74/-0)
include/lassert.h (+62/-0)
include/lgetopt.h (+189/-0)
include/md5.h (+159/-0)
include/sane/.gitignore (+2/-0)
include/sane/config.h.in (+698/-0)
include/sane/sane.h (+248/-0)
include/sane/sanei.h (+160/-0)
include/sane/sanei_ab306.h (+58/-0)
include/sane/sanei_access.h (+97/-0)
include/sane/sanei_auth.h (+98/-0)
include/sane/sanei_backend.h (+179/-0)
include/sane/sanei_cderror.h (+132/-0)
include/sane/sanei_codec_ascii.h (+62/-0)
include/sane/sanei_codec_bin.h (+61/-0)
include/sane/sanei_config.h (+175/-0)
include/sane/sanei_debug.h (+153/-0)
include/sane/sanei_jinclude.h (+91/-0)
include/sane/sanei_jpeg.h (+55/-0)
include/sane/sanei_lm983x.h (+150/-0)
include/sane/sanei_magic.h (+222/-0)
include/sane/sanei_net.h (+144/-0)
include/sane/sanei_pa4s2.h (+220/-0)
include/sane/sanei_pio.h (+55/-0)
include/sane/sanei_pp.h (+172/-0)
include/sane/sanei_pv8630.h (+96/-0)
include/sane/sanei_scsi.h (+329/-0)
include/sane/sanei_tcp.h (+37/-0)
include/sane/sanei_thread.h (+164/-0)
include/sane/sanei_udp.h (+40/-0)
include/sane/sanei_usb.h (+525/-0)
include/sane/sanei_wire.h (+132/-0)
include/sane/saneopts.h (+461/-0)
install-sh (+527/-0)
japi/.gitignore (+1/-0)
japi/ImageCanvas.java (+110/-0)
japi/ImageCanvasClient.java (+54/-0)
japi/Jscanimage.java (+1166/-0)
japi/Makefile.am (+47/-0)
japi/Makefile.in (+738/-0)
japi/README.JAVA (+55/-0)
japi/Sane.c (+493/-0)
japi/Sane.java (+144/-0)
japi/SaneDevice.java (+55/-0)
japi/SaneOption.java (+145/-0)
japi/SaneParameters.java (+68/-0)
japi/SaneRange.java (+53/-0)
japi/ScanIt.java (+391/-0)
japi/Test.java (+175/-0)
lib/.gitignore (+1/-0)
lib/Makefile.am (+14/-0)
lib/Makefile.in (+659/-0)
lib/alloca.c (+495/-0)
lib/getenv.c (+18/-0)
lib/getopt.c (+1282/-0)
lib/getopt1.c (+199/-0)
lib/inet_ntop.c (+40/-0)
lib/inet_pton.c (+57/-0)
lib/isfdtype.c (+25/-0)
lib/md5.c (+457/-0)
lib/sigprocmask.c (+53/-0)
lib/sleep.c (+30/-0)
lib/snprintf.c (+1119/-0)
lib/strcasestr.c (+120/-0)
lib/strdup.c (+38/-0)
lib/strndup.c (+39/-0)
lib/strsep.c (+49/-0)
lib/syslog.c (+13/-0)
lib/usleep.c (+60/-0)
lib/vsyslog.c (+15/-0)
ltmain.sh (+9678/-0)
m4/byteorder.m4 (+401/-0)
m4/libtool.m4 (+7992/-0)
m4/ltoptions.m4 (+384/-0)
m4/ltsugar.m4 (+123/-0)
m4/ltversion.m4 (+23/-0)
m4/lt~obsolete.m4 (+98/-0)
m4/stdint.m4 (+695/-0)
missing (+215/-0)
mkinstalldirs (+162/-0)
po/.gitignore (+3/-0)
po/LINGUAS (+21/-0)
po/Makefile.am (+87/-0)
po/Makefile.in (+548/-0)
po/POTFILES (+111/-0)
po/README (+70/-0)
po/bg.po (+5584/-0)
po/cs.po (+5561/-0)
po/da.po (+5587/-0)
po/de.po (+5792/-0)
po/en_GB.po (+5587/-0)
po/eo.po (+5624/-0)
po/es.po (+5662/-0)
po/fi.po (+5554/-0)
po/fr.po (+5703/-0)
po/gl.po (+5657/-0)
po/it.po (+5656/-0)
po/ja.po (+5480/-0)
po/nb.po (+5425/-0)
po/nl.po (+5782/-0)
po/pl.po (+5628/-0)
po/pt.po (+5215/-0)
po/ru.po (+5593/-0)
po/sv.po (+5664/-0)
po/uk.po (+5809/-0)
sane-backends.lsm (+27/-0)
sanei/.gitignore (+1/-0)
sanei/Makefile.am (+21/-0)
sanei/Makefile.in (+675/-0)
sanei/linux_sg3_err.h (+135/-0)
sanei/os2_srb.h (+156/-0)
sanei/sanei_DomainOS.c (+528/-0)
sanei/sanei_DomainOS.h (+76/-0)
sanei/sanei_ab306.c (+583/-0)
sanei/sanei_access.c (+232/-0)
sanei/sanei_auth.c (+283/-0)
sanei/sanei_codec_ascii.c (+345/-0)
sanei/sanei_codec_bin.c (+139/-0)
sanei/sanei_config.c (+453/-0)
sanei/sanei_config2.c (+154/-0)
sanei/sanei_constrain_value.c (+309/-0)
sanei/sanei_init_debug.c (+150/-0)
sanei/sanei_jpeg.c (+235/-0)
sanei/sanei_lm983x.c (+265/-0)
sanei/sanei_magic.c (+1941/-0)
sanei/sanei_net.c (+186/-0)
sanei/sanei_pa4s2.c (+2103/-0)
sanei/sanei_pio.c (+604/-0)
sanei/sanei_pp.c (+1462/-0)
sanei/sanei_pv8630.c (+223/-0)
sanei/sanei_scsi.c (+6187/-0)
sanei/sanei_tcp.c (+136/-0)
sanei/sanei_thread.c (+562/-0)
sanei/sanei_udp.c (+232/-0)
sanei/sanei_usb.c (+3164/-0)
sanei/sanei_wire.c (+696/-0)
test-driver (+127/-0)
testsuite/Makefile.am (+45/-0)
testsuite/Makefile.in (+698/-0)
testsuite/README (+15/-0)
testsuite/sanei/Makefile.am (+40/-0)
testsuite/sanei/Makefile.in (+1108/-0)
testsuite/sanei/README (+40/-0)
testsuite/sanei/data/boolean.conf (+6/-0)
testsuite/sanei/data/empty.conf (+1/-0)
testsuite/sanei/data/fixed.conf (+6/-0)
testsuite/sanei/data/int.conf (+2/-0)
testsuite/sanei/data/snapscan.conf (+115/-0)
testsuite/sanei/data/string-list.conf (+3/-0)
testsuite/sanei/data/string.conf (+3/-0)
testsuite/sanei/data/umax_pp.conf (+64/-0)
testsuite/sanei/data/word-array.conf (+2/-0)
testsuite/sanei/data/wrong-boolean.conf (+4/-0)
testsuite/sanei/data/wrong-fixed.conf (+2/-0)
testsuite/sanei/data/wrong-range.conf (+2/-0)
testsuite/sanei/data/wrong-string-list.conf (+3/-0)
testsuite/sanei/sanei_check_test.c (+478/-0)
testsuite/sanei/sanei_config_test.c (+907/-0)
testsuite/sanei/sanei_constrain_test.c (+795/-0)
testsuite/sanei/sanei_usb_test.c (+949/-0)
testsuite/sanei/test_wire.c (+236/-0)
testsuite/tools/Makefile.am (+43/-0)
testsuite/tools/Makefile.in (+518/-0)
testsuite/tools/README (+10/-0)
testsuite/tools/data/ascii.ref (+15583/-0)
testsuite/tools/data/db.ref (+1362/-0)
testsuite/tools/data/hal-new.ref (+3543/-0)
testsuite/tools/data/hal.ref (+3543/-0)
testsuite/tools/data/html-backends-split.ref (+16501/-0)
testsuite/tools/data/html-mfgs.ref (+23915/-0)
testsuite/tools/data/hwdb.ref (+2736/-0)
testsuite/tools/data/plist.ref (+5358/-0)
testsuite/tools/data/statistics.ref (+20/-0)
testsuite/tools/data/testfile.desc (+13888/-0)
testsuite/tools/data/udev+acl.ref (+1470/-0)
testsuite/tools/data/udev+hwdb.ref (+79/-0)
testsuite/tools/data/udev.ref (+1470/-0)
testsuite/tools/data/usermap.ref (+1360/-0)
testsuite/tools/data/xml.ref (+18149/-0)
tools/.gitignore (+9/-0)
tools/Makefile.am (+79/-0)
tools/Makefile.in (+916/-0)
tools/README (+74/-0)
tools/RenSaneDlls.cmd (+33/-0)
tools/check-po.awk (+173/-0)
tools/check-usb-chip.c (+4338/-0)
tools/epson2usb.pl (+63/-0)
tools/gamma4scanimage.c (+140/-0)
tools/hotplug-ng/.gitignore (+2/-0)
tools/hotplug-ng/README (+46/-0)
tools/hotplug-ng/libsane.hotplug (+29/-0)
tools/hotplug/.gitignore (+2/-0)
tools/hotplug/README (+35/-0)
tools/hotplug/libusbscanner (+35/-0)
tools/libtool-get-dll-ext (+19/-0)
tools/mustek600iin-off.c (+199/-0)
tools/openbsd/attach (+20/-0)
tools/openbsd/detach (+22/-0)
tools/sane-backends.pc.in (+14/-0)
tools/sane-config.in (+91/-0)
tools/sane-desc.c (+4061/-0)
tools/sane-find-scanner.c (+2098/-0)
tools/umax_pp.c (+573/-0)
tools/xerox (+60/-0)
Conflict adding file .pc.  Moved existing file to .pc.moved.
Conflict adding file AUTHORS.  Moved existing file to AUTHORS.moved.
Conflict adding file COPYING.  Moved existing file to COPYING.moved.
Conflict adding file ChangeLog-1.0.0.  Moved existing file to ChangeLog-1.0.0.moved.
Conflict adding file ChangeLog-1.0.1.  Moved existing file to ChangeLog-1.0.1.moved.
Conflict adding file ChangeLog-1.0.10.  Moved existing file to ChangeLog-1.0.10.moved.
Conflict adding file ChangeLog-1.0.12.  Moved existing file to ChangeLog-1.0.12.moved.
Conflict adding file ChangeLog-1.0.13.  Moved existing file to ChangeLog-1.0.13.moved.
Conflict adding file ChangeLog-1.0.14.  Moved existing file to ChangeLog-1.0.14.moved.
Conflict adding file ChangeLog-1.0.15.  Moved existing file to ChangeLog-1.0.15.moved.
Conflict adding file ChangeLog-1.0.16.  Moved existing file to ChangeLog-1.0.16.moved.
Conflict adding file ChangeLog-1.0.17.  Moved existing file to ChangeLog-1.0.17.moved.
Conflict adding file ChangeLog-1.0.18.  Moved existing file to ChangeLog-1.0.18.moved.
Conflict adding file ChangeLog-1.0.19.  Moved existing file to ChangeLog-1.0.19.moved.
Conflict adding file ChangeLog-1.0.2.  Moved existing file to ChangeLog-1.0.2.moved.
Conflict adding file ChangeLog-1.0.20.  Moved existing file to ChangeLog-1.0.20.moved.
Conflict adding file ChangeLog-1.0.21.  Moved existing file to ChangeLog-1.0.21.moved.
Conflict adding file ChangeLog-1.0.22.  Moved existing file to ChangeLog-1.0.22.moved.
Conflict adding file ChangeLog-1.0.3.  Moved existing file to ChangeLog-1.0.3.moved.
Conflict adding file ChangeLog-1.0.4.  Moved existing file to ChangeLog-1.0.4.moved.
Conflict adding file ChangeLog-1.0.5.  Moved existing file to ChangeLog-1.0.5.moved.
Conflict adding file ChangeLog-1.0.6.  Moved existing file to ChangeLog-1.0.6.moved.
Conflict adding file ChangeLog-1.0.7.  Moved existing file to ChangeLog-1.0.7.moved.
Conflict adding file ChangeLog-1.0.8.  Moved existing file to ChangeLog-1.0.8.moved.
Conflict adding file ChangeLog-1.0.9.  Moved existing file to ChangeLog-1.0.9.moved.
Conflict adding file ChangeLog.  Moved existing file to ChangeLog.moved.
Conflict adding file INSTALL.  Moved existing file to INSTALL.moved.
Conflict adding file LICENSE.  Moved existing file to LICENSE.moved.
Conflict adding file Makefile.am.  Moved existing file to Makefile.am.moved.
Conflict adding file Makefile.in.  Moved existing file to Makefile.in.moved.
Conflict adding file NEWS.  Moved existing file to NEWS.moved.
Conflict adding file PROBLEMS.  Moved existing file to PROBLEMS.moved.
Conflict adding file PROJECTS.  Moved existing file to PROJECTS.moved.
Conflict adding file README.aix.  Moved existing file to README.aix.moved.
Conflict adding file README.beos.  Moved existing file to README.beos.moved.
Conflict adding file README.darwin.  Moved existing file to README.darwin.moved.
Conflict adding file README.djpeg.  Moved existing file to README.djpeg.moved.
Conflict adding file README.freebsd.  Moved existing file to README.freebsd.moved.
Conflict adding file README.hp-ux.  Moved existing file to README.hp-ux.moved.
Conflict adding file README.linux.  Moved existing file to README.linux.moved.
Conflict adding file README.  Moved existing file to README.moved.
Conflict adding file README.netbsd.  Moved existing file to README.netbsd.moved.
Conflict adding file README.openbsd.  Moved existing file to README.openbsd.moved.
Conflict adding file README.os2.  Moved existing file to README.os2.moved.
Conflict adding file README.solaris.  Moved existing file to README.solaris.moved.
Conflict adding file README.unixware2.  Moved existing file to README.unixware2.moved.
Conflict adding file README.unixware7.  Moved existing file to README.unixware7.moved.
Conflict adding file README.windows.  Moved existing file to README.windows.moved.
Conflict adding file README.zeta.  Moved existing file to README.zeta.moved.
Conflict adding file acinclude.m4.  Moved existing file to acinclude.m4.moved.
Conflict adding file aclocal.m4.  Moved existing file to aclocal.m4.moved.
Conflict adding file backend.  Moved existing file to backend.moved.
Conflict adding file compile.  Moved existing file to compile.moved.
Conflict adding file config.guess.  Moved existing file to config.guess.moved.
Conflict adding file config.sub.  Moved existing file to config.sub.moved.
Conflict adding file configure.in.  Moved existing file to configure.in.moved.
Conflict adding file configure.  Moved existing file to configure.moved.
Conflict adding file debian.  Moved existing file to debian.moved.
Conflict adding file depcomp.  Moved existing file to depcomp.moved.
Conflict adding file doc.  Moved existing file to doc.moved.
Conflict adding file frontend.  Moved existing file to frontend.moved.
Conflict adding file include.  Moved existing file to include.moved.
Conflict adding file install-sh.  Moved existing file to install-sh.moved.
Conflict adding file japi.  Moved existing file to japi.moved.
Conflict adding file lib.  Moved existing file to lib.moved.
Conflict adding file ltmain.sh.  Moved existing file to ltmain.sh.moved.
Conflict adding file m4.  Moved existing file to m4.moved.
Conflict adding file missing.  Moved existing file to missing.moved.
Conflict adding file mkinstalldirs.  Moved existing file to mkinstalldirs.moved.
Conflict adding file po.  Moved existing file to po.moved.
Conflict adding file sane-backends.lsm.  Moved existing file to sane-backends.lsm.moved.
Conflict adding file sanei.  Moved existing file to sanei.moved.
Conflict adding file testsuite.  Moved existing file to testsuite.moved.
Conflict adding file tools.  Moved existing file to tools.moved.
To merge this branch: bzr merge lp:~jfbcable/ubuntu/wily/sane-backends/fix-pixma
Reviewer Review Type Date Requested Status
Marc Deslauriers 2015-11-08 Needs Fixing on 2015-11-10
Review via email: mp+276937@code.launchpad.net
To post a comment you must log in.
Marc Deslauriers (mdeslaur) wrote :

Thanks for this merge request.

This is the upstream commit:
http://anonscm.debian.org/cgit/sane/sane-backends.git/commit/backend/pixma_bjnp.c?id=43bca22e0cc9ad7e2024a4f97be7250aa72c7992

Could you please update the patch with appropriate tags, including a reference to the upstream commit?
Also, could you please add an appropriate description to the debian/changelog on what the patch fixes?

Thanks!

review: Needs Fixing
Julian Cable (jfbcable) wrote :

Hi Marc. I can add the description and link the upstream commit. What other tags should I add?

Julian

> On 10 Nov 2015, at 15:57, Marc Deslauriers <email address hidden> wrote:
>
> Review: Needs Fixing
>
> Thanks for this merge request.
>
> This is the upstream commit:
> http://anonscm.debian.org/cgit/sane/sane-backends.git/commit/backend/pixma_bjnp.c?id=43bca22e0cc9ad7e2024a4f97be7250aa72c7992
>
> Could you please update the patch with appropriate tags, including a reference to the upstream commit?
> Also, could you please add an appropriate description to the debian/changelog on what the patch fixes?
>
> Thanks!
> --
> https://code.launchpad.net/~jfbcable/ubuntu/wily/sane-backends/fix-pixma/+merge/276937
> You are the owner of lp:~jfbcable/ubuntu/wily/sane-backends/fix-pixma.

Unmerged revisions

3. By Julian Cable on 2015-11-08

debian/patches/99-fix-pixma.patch: [apply upstream fix #315219]

2. By Michael Thayer on 2015-09-16

Fix timing issues on USB3 or fast recent hardware. Back-port from
upstream.

1. By Michael Thayer on 2015-09-16

Import upstream version 1.0.25+git20150528

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file '.gitignore'
2--- .gitignore 1970-01-01 00:00:00 +0000
3+++ .gitignore 2015-11-08 16:17:40 +0000
4@@ -0,0 +1,14 @@
5+*.o
6+*.lo
7+*.a
8+*.la
9+.libs/
10+*~
11+autom4te.cache/
12+Makefile
13+config.log
14+config.status
15+config.cache
16+libtool
17+.deps/
18+.*
19
20=== added directory '.pc'
21=== renamed directory '.pc' => '.pc.moved'
22=== added file '.pc/.quilt_patches'
23--- .pc/.quilt_patches 1970-01-01 00:00:00 +0000
24+++ .pc/.quilt_patches 2015-11-08 16:17:40 +0000
25@@ -0,0 +1,1 @@
26+debian/patches
27
28=== added file '.pc/.quilt_series'
29--- .pc/.quilt_series 1970-01-01 00:00:00 +0000
30+++ .pc/.quilt_series 2015-11-08 16:17:40 +0000
31@@ -0,0 +1,1 @@
32+series
33
34=== added file '.pc/.version'
35--- .pc/.version 1970-01-01 00:00:00 +0000
36+++ .pc/.version 2015-11-08 16:17:40 +0000
37@@ -0,0 +1,1 @@
38+2
39
40=== added directory '.pc/0005-mk_reproducible_results.patch'
41=== added directory '.pc/0005-mk_reproducible_results.patch/tools'
42=== added file '.pc/0005-mk_reproducible_results.patch/tools/sane-desc.c'
43--- .pc/0005-mk_reproducible_results.patch/tools/sane-desc.c 1970-01-01 00:00:00 +0000
44+++ .pc/0005-mk_reproducible_results.patch/tools/sane-desc.c 2015-11-08 16:17:40 +0000
45@@ -0,0 +1,4059 @@
46+/*
47+ sane-desc.c -- generate list of supported SANE devices
48+
49+ Copyright (C) 2002-2006 Henning Meier-Geinitz <henning@meier-geinitz.de>
50+ Copyright (C) 2004 Jose Gato <jgato@gsyc.escet.urjc.es> (XML output)
51+ Copyright (C) 2006 Mattias Ellert <mattias.ellert@tsl.uu.se> (plist output)
52+ Copyright (C) 2009 Dr. Ing. Dieter Jurzitza <dieter.jurzitza@t-online.de>
53+ Copyright (C) 2013 Tom Gundersen <teg@jklm.no> (hwdb output)
54+
55+ This file is part of the SANE package.
56+
57+ This program is free software; you can redistribute it and/or
58+ modify it under the terms of the GNU General Public License as
59+ published by the Free Software Foundation; either version 2 of the
60+ License, or (at your option) any later version.
61+
62+ This program is distributed in the hope that it will be useful, but
63+ WITHOUT ANY WARRANTY; without even the implied warranty of
64+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
65+ General Public License for more details.
66+
67+ You should have received a copy of the GNU General Public License
68+ along with this program; if not, write to the Free Software
69+ Foundation, Inc., 59 Temple Place - Suite 330, Boston,
70+ MA 02111-1307, USA.
71+*/
72+
73+#include <../include/sane/config.h>
74+
75+#include "lgetopt.h"
76+#include <stdio.h>
77+#include <stdlib.h>
78+#include <string.h>
79+#include <unistd.h>
80+#include <stdarg.h>
81+#include <errno.h>
82+#include <sys/types.h>
83+#include <sys/stat.h>
84+#include <dirent.h>
85+#include <limits.h>
86+#include <ctype.h>
87+#include <time.h>
88+
89+#include "../include/sane/sane.h"
90+#include "../include/sane/sanei.h"
91+#include "../include/sane/sanei_config.h"
92+
93+#define SANE_DESC_VERSION "3.5"
94+
95+#define MAN_PAGE_LINK "http://www.sane-project.org/man/%s.5.html"
96+#define COLOR_MINIMAL "\"#B00000\""
97+#define COLOR_BASIC "\"#FF9000\""
98+#define COLOR_GOOD "\"#90B000\""
99+#define COLOR_COMPLETE "\"#007000\""
100+#define COLOR_UNTESTED "\"#0000B0\""
101+#define COLOR_UNSUPPORTED "\"#F00000\""
102+#define COLOR_NEW "\"#F00000\""
103+#define COLOR_UNKNOWN "\"#000000\""
104+
105+#define DEVMODE "0664"
106+#define DEVOWNER "root"
107+#define DEVGROUP "scanner"
108+
109+#ifndef PATH_MAX
110+# define PATH_MAX 1024
111+#endif
112+
113+#define DBG_ERR current_debug_level = 0; debug_call
114+#define DBG_WARN current_debug_level = 1; debug_call
115+#define DBG_INFO current_debug_level = 2; debug_call
116+#define DBG_DBG current_debug_level = 3; debug_call
117+
118+typedef enum output_mode
119+{
120+ output_mode_ascii = 0,
121+ output_mode_xml,
122+ output_mode_html_backends,
123+ output_mode_html_backends_split,
124+ output_mode_html_mfgs,
125+ output_mode_statistics,
126+ output_mode_usermap,
127+ output_mode_db,
128+ output_mode_udev,
129+ output_mode_udevacl,
130+ output_mode_udevhwdb,
131+ output_mode_hwdb,
132+ output_mode_plist,
133+ output_mode_hal,
134+ output_mode_halnew
135+}
136+output_mode;
137+
138+typedef enum parameter_type
139+{
140+ param_none = 0,
141+ param_string,
142+ param_two_strings,
143+ param_three_strings
144+}
145+parameter_type;
146+
147+typedef enum status_entry
148+{
149+ status_unknown,
150+ status_unsupported,
151+ status_untested,
152+ status_minimal,
153+ status_basic,
154+ status_good,
155+ status_complete
156+}
157+status_entry;
158+
159+typedef enum device_type
160+{
161+ type_unknown,
162+ type_scanner,
163+ type_stillcam,
164+ type_vidcam,
165+ type_meta,
166+ type_api
167+}
168+device_type;
169+
170+typedef enum level
171+{
172+ level_backend,
173+ level_mfg,
174+ level_model,
175+ level_desc
176+}
177+level;
178+
179+typedef struct url_entry
180+{
181+ struct url_entry *next;
182+ char *name;
183+}
184+url_entry;
185+
186+typedef struct model_entry
187+{
188+ struct model_entry *next;
189+ char *name;
190+ char *interface;
191+ struct url_entry *url;
192+ char *comment;
193+ enum status_entry status;
194+ char *usb_vendor_id;
195+ char *usb_product_id;
196+ SANE_Bool ignore_usb_id;
197+ char *scsi_vendor_id;
198+ char *scsi_product_id;
199+ SANE_Bool scsi_is_processor;
200+}
201+model_entry;
202+
203+typedef struct desc_entry
204+{
205+ struct desc_entry *next;
206+ char *desc;
207+ struct url_entry *url;
208+ char *comment;
209+}
210+desc_entry;
211+
212+typedef struct mfg_entry
213+{
214+ struct mfg_entry *next;
215+ char *name;
216+ struct url_entry *url;
217+ char *comment;
218+ struct model_entry *model;
219+}
220+mfg_entry;
221+
222+typedef struct type_entry
223+{
224+ struct type_entry *next;
225+ enum device_type type;
226+ struct desc_entry *desc;
227+ struct mfg_entry *mfg;
228+}
229+type_entry;
230+
231+typedef struct backend_entry
232+{
233+ struct backend_entry *next;
234+ char *name;
235+ char *version;
236+ char *manpage;
237+ struct url_entry *url;
238+ char *comment;
239+ struct type_entry *type;
240+ SANE_Bool new;
241+}
242+backend_entry;
243+
244+typedef struct model_record_entry
245+{
246+ struct model_record_entry *next;
247+ char *name;
248+ char *interface;
249+ struct url_entry *url;
250+ char *comment;
251+ enum status_entry status;
252+ char *usb_vendor_id;
253+ char *usb_product_id;
254+ char *scsi_vendor_id;
255+ char *scsi_product_id;
256+ SANE_Bool scsi_is_processor;
257+ struct backend_entry *be;
258+}
259+model_record_entry;
260+
261+typedef struct mfg_record_entry
262+{
263+ struct mfg_record_entry *next;
264+ char *name;
265+ char *comment;
266+ struct url_entry *url;
267+ struct model_record_entry *model_record;
268+}
269+mfg_record_entry;
270+
271+typedef int statistics_type [status_complete + 1];
272+
273+
274+typedef struct manufacturer_model_type
275+{
276+ struct manufacturer_model_type * next;
277+ char *name;
278+}
279+manufacturer_model_type;
280+
281+typedef struct usbid_type
282+{
283+ struct usbid_type * next;
284+ char *usb_vendor_id;
285+ char *usb_product_id;
286+ struct manufacturer_model_type *name;
287+}
288+usbid_type;
289+
290+typedef struct scsiid_type
291+{
292+ struct scsiid_type * next;
293+ char *scsi_vendor_id;
294+ char *scsi_product_id;
295+ SANE_Bool is_processor;
296+ struct manufacturer_model_type *name;
297+}
298+scsiid_type;
299+
300+static char *program_name;
301+static int debug = 0;
302+static int current_debug_level = 0;
303+static char *search_dir_spec = 0;
304+static backend_entry *first_backend = 0;
305+static enum output_mode mode = output_mode_ascii;
306+static char *title = 0;
307+static char *intro = 0;
308+static SANE_String desc_name = 0;
309+static const char *status_name[] =
310+ {"Unknown", "Unsupported", "Untested", "Minimal", "Basic",
311+ "Good", "Complete"};
312+static const char *device_type_name[] =
313+ {"Unknown", "Scanners", "Still cameras", "Video Cameras", "Meta backends",
314+ "APIs"};
315+static const char *device_type_aname[] =
316+ {"UKNOWN", "SCANNERS", "STILL", "VIDEO", "META",
317+ "API"};
318+static const char *status_color[] =
319+ {COLOR_UNKNOWN, COLOR_UNSUPPORTED, COLOR_UNTESTED, COLOR_MINIMAL,
320+ COLOR_BASIC, COLOR_GOOD, COLOR_COMPLETE};
321+
322+
323+static void
324+debug_call (const char *fmt, ...)
325+{
326+ va_list ap;
327+ char *level_txt;
328+
329+ va_start (ap, fmt);
330+ if (debug >= current_debug_level)
331+ {
332+ /* print to stderr */
333+ switch (current_debug_level)
334+ {
335+ case 0:
336+ level_txt = "ERROR:";
337+ break;
338+ case 1:
339+ level_txt = "Warning:";
340+ break;
341+ case 2:
342+ level_txt = "Info:";
343+ break;
344+ default:
345+ level_txt = "";
346+ break;
347+ }
348+ if (desc_name)
349+ fprintf (stderr, "%s: %8s ", desc_name, level_txt);
350+ else
351+ fprintf (stderr, "[%s] %8s ", program_name, level_txt);
352+ vfprintf (stderr, fmt, ap);
353+ }
354+ va_end (ap);
355+}
356+
357+static void
358+print_usage (char *program_name)
359+{
360+ printf ("Usage: %s [-s dir] [-m mode] [-d level] [-h] [-V]\n",
361+ program_name);
362+ printf (" -s|--search-dir dir "
363+ "Specify the directory that contains .desc files \n"
364+ " "
365+ "(multiple directories can be concatenated by \":\")\n");
366+ printf (" -m|--mode mode "
367+ "Output mode (ascii, html-backends-split, html-mfgs,\n"
368+ " xml, statistics, usermap, db, udev, udev+acl, udev+hwdb, hwdb, plist, hal, hal-new)\n");
369+ printf (" -t|--title \"title\" The title used for HTML pages\n");
370+ printf (" -i|--intro \"intro\" A short description of the "
371+ "contents of the page\n");
372+ printf (" -d|--debug-level level Specify debug level (0-3)\n");
373+ printf (" -h|--help Print help message\n");
374+ printf (" -V|--version Print version information\n");
375+ printf ("Report bugs to <henning@meier-geinitz.de>\n");
376+}
377+
378+static void
379+print_version (void)
380+{
381+ printf ("sane-desc %s (%s)\n", SANE_DESC_VERSION, PACKAGE_STRING);
382+ printf ("Copyright (C) 2002-2006 Henning Meier-Geinitz "
383+ "<henning@meier-geinitz.de>\n"
384+ "sane-desc comes with NO WARRANTY, to the extent permitted by "
385+ "law.\n"
386+ "You may redistribute copies of sane-desc under the terms of the "
387+ "GNU General\n"
388+ "Public License.\n"
389+ "For more information about these matters, see the file named "
390+ "COPYING.\n");
391+}
392+
393+static SANE_Bool
394+get_options (int argc, char **argv)
395+{
396+ int longindex;
397+ int opt;
398+ static struct option desc_options[] = {
399+ {"search-dir", required_argument, NULL, 's'},
400+ {"mode", required_argument, NULL, 'm'},
401+ {"title", required_argument, NULL, 't'},
402+ {"intro", required_argument, NULL, 'i'},
403+ {"debug-level", required_argument, NULL, 'd'},
404+ {"help", 0, NULL, 'h'},
405+ {"version", 0, NULL, 'V'},
406+ {0, 0, 0, 0}
407+ };
408+
409+ while ((opt = getopt_long (argc, argv, "s:m:t:i:d:hV", desc_options,
410+ &longindex)) != -1)
411+ {
412+ switch (opt)
413+ {
414+ case 'h':
415+ print_usage (argv[0]);
416+ exit (0);
417+ case 'V':
418+ print_version ();
419+ exit (0);
420+ case 's':
421+ search_dir_spec = strdup (optarg);
422+ DBG_INFO ("setting search directory to `%s'\n", search_dir_spec);
423+ break;
424+ case 'm':
425+ if (strcmp (optarg, "ascii") == 0)
426+ {
427+ DBG_INFO ("Output mode: %s\n", optarg);
428+ mode = output_mode_ascii;
429+ }
430+ else if (strcmp (optarg, "xml") == 0)
431+ {
432+ DBG_INFO ("Output mode: %s\n", optarg);
433+ mode = output_mode_xml;
434+ }
435+ else if (strcmp (optarg, "html-backends-split") == 0)
436+ {
437+ DBG_INFO ("Output mode: %s\n", optarg);
438+ mode = output_mode_html_backends_split;
439+ }
440+ else if (strcmp (optarg, "html-mfgs") == 0)
441+ {
442+ DBG_INFO ("Output mode: %s\n", optarg);
443+ mode = output_mode_html_mfgs;
444+ }
445+ else if (strcmp (optarg, "statistics") == 0)
446+ {
447+ DBG_INFO ("Output mode: %s\n", optarg);
448+ mode = output_mode_statistics;
449+ }
450+ else if (strcmp (optarg, "usermap") == 0)
451+ {
452+ DBG_INFO ("Output mode: %s\n", optarg);
453+ mode = output_mode_usermap;
454+ }
455+ else if (strcmp (optarg, "db") == 0)
456+ {
457+ DBG_INFO ("Output mode: %s\n", optarg);
458+ mode = output_mode_db;
459+ }
460+ else if (strcmp (optarg, "udev") == 0)
461+ {
462+ DBG_INFO ("Output mode: %s\n", optarg);
463+ mode = output_mode_udev;
464+ }
465+ else if (strcmp (optarg, "udev+acl") == 0)
466+ {
467+ DBG_INFO ("Output mode: %s\n", optarg);
468+ mode = output_mode_udevacl;
469+ }
470+ else if (strcmp (optarg, "udev+hwdb") == 0)
471+ {
472+ DBG_INFO ("Output mode: %s\n", optarg);
473+ mode = output_mode_udevhwdb;
474+ }
475+ else if (strcmp (optarg, "hwdb") == 0)
476+ {
477+ DBG_INFO ("Output mode: %s\n", optarg);
478+ mode = output_mode_hwdb;
479+ }
480+ else if (strcmp (optarg, "plist") == 0)
481+ {
482+ DBG_INFO ("Output mode: %s\n", optarg);
483+ mode = output_mode_plist;
484+ }
485+ else if (strcmp (optarg, "hal") == 0)
486+ {
487+ DBG_INFO ("Output mode: %s\n", optarg);
488+ mode = output_mode_hal;
489+ }
490+ else if (strcmp (optarg, "hal-new") == 0)
491+ {
492+ DBG_INFO ("Output mode: %s\n", optarg);
493+ mode = output_mode_halnew;
494+ }
495+ else
496+ {
497+ DBG_ERR ("Unknown output mode: %s\n", optarg);
498+ exit (1);
499+ }
500+ break;
501+ case 't':
502+ title = optarg;
503+ DBG_INFO ("setting title to `%s'\n", optarg);
504+ break;
505+ case 'i':
506+ intro = optarg;
507+ DBG_INFO ("setting intro to `%s'\n", optarg);
508+ break;
509+ case 'd':
510+ debug = atoi (optarg);
511+ DBG_INFO ("setting debug level to %d\n", debug);
512+ break;
513+ case '?':
514+ DBG_ERR ("unknown option (use -h for help)\n");
515+ return SANE_FALSE;
516+ case ':':
517+ DBG_ERR ("missing parameter (use -h for help)\n");
518+ return SANE_FALSE;
519+ default:
520+ DBG_ERR ("missing option (use -h for help)\n");
521+ return SANE_FALSE;
522+ }
523+ }
524+ if (!search_dir_spec)
525+ search_dir_spec = ".";
526+ return SANE_TRUE;
527+}
528+
529+static int
530+char_compare (char char1, char char2)
531+{
532+ char1 = toupper (char1);
533+ char2 = toupper (char2);
534+
535+ if (char1 < char2)
536+ return -1;
537+ else if (char1 > char2)
538+ return 1;
539+ else
540+ return 0;
541+}
542+
543+static int
544+num_compare (char *num_string1, char *num_string2)
545+{
546+ int num1 = atoi (num_string1);
547+ int num2 = atoi (num_string2);
548+ if (num1 < num2)
549+ return -1;
550+ else if (num1 > num2)
551+ return 1;
552+ else
553+ return 0;
554+}
555+
556+/* Compare two strings, try to sort numbers correctly (600 < 1200) */
557+static int
558+string_compare (char *string1, char *string2)
559+{
560+ int count = 0;
561+ int compare = 0;
562+
563+ if (!string1)
564+ {
565+ if (!string2)
566+ return 0;
567+ else
568+ return 1;
569+ }
570+ else if (!string2)
571+ return -1;
572+
573+ while (string1[count] && string2[count])
574+ {
575+ if (isdigit (string1[count]) && isdigit (string2[count]))
576+ compare = num_compare (&string1[count], &string2[count]);
577+ else
578+ compare = char_compare (string1[count], string2[count]);
579+ if (compare != 0)
580+ return compare;
581+ count++;
582+ }
583+ return char_compare (string1[count], string2[count]);
584+}
585+
586+/* Add URLs to the end of the list if they are unique */
587+static url_entry *
588+update_url_list (url_entry * first_url, char *new_url)
589+{
590+ url_entry *url = first_url;
591+ SANE_Bool found = SANE_FALSE;
592+
593+ while (url && url->name)
594+ {
595+ if (string_compare (url->name, new_url) == 0)
596+ found = SANE_TRUE;
597+ url = url->next;
598+ }
599+ if (found)
600+ return first_url;
601+
602+ url = first_url;
603+ if (url)
604+ {
605+ while (url->next)
606+ url = url->next;
607+ url->next = calloc (1, sizeof (url_entry));
608+ url = url->next;
609+ }
610+ else
611+ {
612+ first_url = calloc (1, sizeof (url_entry));
613+ url = first_url;
614+ }
615+ if (!url)
616+ {
617+ DBG_ERR ("update_url_list: couldn't calloc url_entry\n");
618+ exit (1);
619+ }
620+ url->name = new_url;
621+ return first_url;
622+}
623+
624+/* Get the next token, ignoring escaped quotation marks */
625+static const char *
626+get_token (const char *str, char **string_const)
627+{
628+ const char *start;
629+ size_t len;
630+
631+ str = sanei_config_skip_whitespace (str);
632+
633+ if (*str == '"')
634+ {
635+ start = ++str;
636+ while (*str && (*str != '"' || *(str - 1) == '\\'))
637+ ++str;
638+ len = str - start;
639+ if (*str == '"')
640+ ++str;
641+ else
642+ start = 0; /* final double quote is missing */
643+ }
644+ else
645+ {
646+ start = str;
647+ while (*str && !isspace (*str))
648+ ++str;
649+ len = str - start;
650+ }
651+ if (start)
652+ *string_const = strndup (start, len);
653+ else
654+ *string_const = NULL;
655+ return str;
656+}
657+
658+/* Checks a line for a keyword token and determines keyword/string argument */
659+static SANE_Status
660+read_keyword (SANE_String line, SANE_String keyword_token,
661+ parameter_type p_type, void *argument)
662+{
663+ SANE_String_Const cp;
664+ SANE_Char *word;
665+
666+ word = 0;
667+
668+ cp = get_token (line, &word);
669+
670+ if (!word)
671+ {
672+ DBG_ERR ("read_keyword: missing quotation mark: %s\n", line);
673+ return SANE_STATUS_INVAL;
674+ }
675+
676+ if (strcmp (word, keyword_token) != 0)
677+ {
678+ free(word);
679+ return SANE_STATUS_INVAL;
680+ }
681+
682+ free (word);
683+ word = 0;
684+
685+ switch (p_type)
686+ {
687+ case param_none:
688+ return SANE_STATUS_GOOD;
689+ case param_string:
690+ {
691+ char *pos;
692+ cp = get_token (cp, &word);
693+ if (!word)
694+ {
695+ DBG_ERR ("read_keyword: missing quotation mark: %s\n", line);
696+ return SANE_STATUS_INVAL;
697+ }
698+ /* remove escaped quotations */
699+ while ((pos = strstr (word, "\\\"")) != 0)
700+ *pos = ' ';
701+
702+ DBG_DBG ("read_keyword: set entry `%s' to `%s'\n", keyword_token,
703+ word);
704+ *(SANE_String *) argument = strdup (word);
705+ break;
706+ }
707+ case param_two_strings:
708+ {
709+ char *pos;
710+ char **strings = malloc (2 * sizeof (SANE_String));
711+
712+ cp = get_token (cp, &word);
713+ if (!word)
714+ {
715+ free(strings);
716+ DBG_ERR ("read_keyword: missing quotation mark: %s\n", line);
717+ return SANE_STATUS_INVAL;
718+ }
719+ /* remove escaped quotations */
720+ while ((pos = strstr (word, "\\\"")) != 0)
721+ *pos = ' ';
722+ DBG_INFO ("read_keyword: set first entry of `%s' to `%s'\n", keyword_token,
723+ word);
724+ strings[0] = strdup (word);
725+ if (word)
726+ free (word);
727+
728+ cp = get_token (cp, &word);
729+ if (!word)
730+ {
731+ free(strings);
732+ DBG_ERR ("read_keyword: missing quotation mark: %s\n", line);
733+ return SANE_STATUS_INVAL;
734+ }
735+ /* remove escaped quotations */
736+ while ((pos = strstr (word, "\\\"")) != 0)
737+ *pos = ' ';
738+ DBG_INFO ("read_keyword: set second entry of `%s' to `%s'\n", keyword_token,
739+ word);
740+ strings[1] = strdup (word);
741+ * (SANE_String **) argument = strings;
742+ break;
743+ }
744+ case param_three_strings:
745+ {
746+ char *pos;
747+ char **strings = malloc (3 * sizeof (SANE_String));
748+
749+ cp = get_token (cp, &word);
750+ if (!word)
751+ {
752+ free(strings);
753+ DBG_ERR ("read_keyword: missing quotation mark: %s\n", line);
754+ return SANE_STATUS_INVAL;
755+ }
756+ /* remove escaped quotations */
757+ while ((pos = strstr (word, "\\\"")) != 0)
758+ *pos = ' ';
759+ DBG_INFO ("read_keyword: set first entry of `%s' to `%s'\n", keyword_token,
760+ word);
761+ strings[0] = strdup (word);
762+ if (word)
763+ free (word);
764+
765+ cp = get_token (cp, &word);
766+ if (!word)
767+ {
768+ free(strings);
769+ DBG_ERR ("read_keyword: missing quotation mark: %s\n", line);
770+ return SANE_STATUS_INVAL;
771+ }
772+ /* remove escaped quotations */
773+ while ((pos = strstr (word, "\\\"")) != 0)
774+ *pos = ' ';
775+ DBG_INFO ("read_keyword: set second entry of `%s' to `%s'\n", keyword_token,
776+ word);
777+ strings[1] = strdup (word);
778+ if (word)
779+ free (word);
780+
781+ cp = get_token (cp, &word);
782+ if (!word)
783+ {
784+ free(strings);
785+ DBG_ERR ("read_keyword: missing quotation mark: %s\n", line);
786+ return SANE_STATUS_INVAL;
787+ }
788+ /* remove escaped quotations */
789+ while ((pos = strstr (word, "\\\"")) != 0)
790+ *pos = ' ';
791+ DBG_INFO ("read_keyword: set third entry of `%s' to `%s'\n", keyword_token,
792+ word);
793+ strings[2] = strdup (word);
794+ * (SANE_String **) argument = strings;
795+ break;
796+ }
797+ default:
798+ DBG_ERR ("read_keyword: unknown param_type %d\n", p_type);
799+ return SANE_STATUS_INVAL;
800+ }
801+
802+ if (word)
803+ free (word);
804+ word = 0;
805+ return SANE_STATUS_GOOD;
806+}
807+
808+/* Check for a all-lowercase 4-digit hex number (e.g. 0x1234) */
809+static SANE_Bool
810+check_hex (SANE_String string)
811+{
812+ unsigned int i;
813+
814+ if (strlen (string) != 6)
815+ return SANE_FALSE;
816+ if (strncmp (string, "0x", 2) != 0)
817+ return SANE_FALSE;
818+ for (i = 0; i < strlen (string); i++)
819+ {
820+ if (isupper (string[i]))
821+ return SANE_FALSE;
822+ }
823+ for (i = 2; i < strlen (string); i++)
824+ {
825+ if (!isxdigit (string[i]))
826+ return SANE_FALSE;
827+ }
828+ return SANE_TRUE;
829+}
830+
831+/* Read and interprete the .desc files */
832+static SANE_Bool
833+read_files (void)
834+{
835+ struct stat stat_buf;
836+ DIR *dir;
837+ struct dirent *dir_entry;
838+ FILE *fp;
839+ char file_name[PATH_MAX];
840+ SANE_Char line[4096], *word;
841+ SANE_String_Const cp;
842+ backend_entry *current_backend = 0;
843+ type_entry *current_type = 0;
844+ mfg_entry *current_mfg = 0;
845+ model_entry *current_model = 0;
846+ enum level current_level = level_backend;
847+ char *search_dir = search_dir_spec, *end = 0;
848+
849+ DBG_INFO ("looking for .desc files in `%s'\n", search_dir_spec);
850+
851+ while (search_dir && search_dir[0])
852+ {
853+ end = strchr (search_dir, ':');
854+ if (end)
855+ end[0] = '\0';
856+ DBG_INFO ("reading directory `%s'\n", search_dir);
857+
858+ if (stat (search_dir, &stat_buf) < 0)
859+ {
860+ DBG_ERR ("cannot stat `%s' (%s)\n", search_dir, strerror (errno));
861+ return SANE_FALSE;
862+ }
863+ if (!S_ISDIR (stat_buf.st_mode))
864+ {
865+ DBG_ERR ("`%s' is not a directory\n", search_dir);
866+ return SANE_FALSE;
867+ }
868+ if ((dir = opendir (search_dir)) == 0)
869+ {
870+ DBG_ERR ("cannot read directory `%s' (%s)\n", search_dir,
871+ strerror (errno));
872+ return SANE_FALSE;
873+ }
874+
875+ while ((dir_entry = readdir (dir)) != NULL)
876+ {
877+ if (strlen (dir_entry->d_name) > 5 &&
878+ strcmp (dir_entry->d_name + strlen (dir_entry->d_name) - 5,
879+ ".desc") == 0)
880+ {
881+ if (strlen (search_dir)
882+ + strlen (dir_entry->d_name) + 1 + 1 > PATH_MAX)
883+ {
884+ DBG_ERR ("filename too long\n");
885+ return SANE_FALSE;
886+ }
887+ sprintf (file_name, "%s/%s", search_dir, dir_entry->d_name);
888+ DBG_INFO ("-> reading desc file: %s\n", file_name);
889+ fp = fopen (file_name, "r");
890+ if (!fp)
891+ {
892+ DBG_ERR ("can't open desc file: %s (%s)\n", file_name,
893+ strerror (errno));
894+ return SANE_FALSE;
895+ }
896+ /* now we check if everything is ok with the previous backend
897+ before we read the new one */
898+ if (current_backend)
899+ {
900+ type_entry *current_type = current_backend->type;
901+ int no_usbids = 0;
902+ int no_interface = 0;
903+ int no_status = 0;
904+
905+ while (current_type)
906+ {
907+ if (current_type->type == type_scanner ||
908+ current_type->type == type_stillcam ||
909+ current_type->type == type_vidcam)
910+ {
911+ mfg_entry *current_mfg = current_type->mfg;
912+
913+ while (current_mfg)
914+ {
915+ model_entry *current_model = current_mfg->model;
916+
917+ while (current_model)
918+ {
919+ if (current_model->status == status_unknown)
920+ {
921+ DBG_INFO
922+ ("Backend `%s': `%s' `%s' does not have a status\n",
923+ current_backend->name,
924+ current_mfg->name,
925+ current_model->name);
926+ no_status++;
927+ }
928+ if (!current_model->interface)
929+ {
930+ DBG_INFO
931+ ("Backend `%s': `%s' `%s' does not have an interface\n",
932+ current_backend->name,
933+ current_mfg->name,
934+ current_model->name);
935+ no_interface++;
936+ }
937+ else if (strstr (current_model->interface, "USB"))
938+ {
939+ if ((!current_model->usb_vendor_id || !current_model->usb_product_id)
940+ && !current_model->ignore_usb_id)
941+ {
942+ DBG_INFO ("`%s' seems to provide a USB device "
943+ "without :usbid (%s %s)\n",
944+ current_backend->name,
945+ current_mfg->name,
946+ current_model->name);
947+ no_usbids++;
948+ }
949+ }
950+ current_model = current_model->next;
951+ }
952+ current_mfg = current_mfg->next;
953+ }
954+ }
955+ current_type = current_type->next;
956+ }
957+ if (no_status)
958+ {
959+ DBG_WARN ("Backend `%s': %d devices without :status\n",
960+ current_backend->name, no_status);
961+ }
962+ if (no_interface)
963+ {
964+ DBG_WARN ("Backend `%s': %d devices without :interface\n",
965+ current_backend->name, no_interface);
966+ }
967+ if (no_usbids)
968+ {
969+ DBG_WARN ("Backend `%s': %d USB devices without :usbid\n",
970+ current_backend->name, no_usbids);
971+ }
972+ }
973+ desc_name = dir_entry->d_name;
974+ current_backend = 0;
975+ current_type = 0;
976+ current_mfg = 0;
977+ current_model = 0;
978+ while (sanei_config_read (line, sizeof (line), fp))
979+ {
980+ char *string_entry = 0;
981+ char **two_string_entry;
982+ char **three_string_entry;
983+ word = 0;
984+
985+ cp = get_token (line, &word);
986+ if (!word || cp == line)
987+ {
988+ DBG_DBG ("ignoring empty line\n");
989+ if (word)
990+ free (word);
991+ word = 0;
992+ continue;
993+ }
994+ if (word[0] == ';')
995+ {
996+ DBG_DBG ("ignoring comment line\n");
997+ free (word);
998+ word = 0;
999+ continue;
1000+ }
1001+ DBG_DBG ("line: %s\n", line);
1002+
1003+ if (read_keyword
1004+ (line, ":backend", param_string,
1005+ &string_entry) == SANE_STATUS_GOOD)
1006+ {
1007+ backend_entry *be = first_backend, *prev_be =
1008+ 0, *new_be = 0;
1009+ DBG_INFO ("creating backend entry `%s'\n",
1010+ string_entry);
1011+
1012+ new_be = calloc (1, sizeof (backend_entry));
1013+ if (!new_be)
1014+ {
1015+ DBG_ERR ("calloc failed (%s)\n", strerror (errno));
1016+ return SANE_FALSE;
1017+ }
1018+ new_be->name = string_entry;
1019+ new_be->new = SANE_FALSE;
1020+
1021+ if (!be)
1022+ {
1023+ first_backend = new_be;
1024+ be = new_be;
1025+ }
1026+ else
1027+ {
1028+ while (be)
1029+ {
1030+ int compare =
1031+ string_compare (new_be->name, be->name);
1032+ if (compare <= 0)
1033+ {
1034+ backend_entry *be_tmp = be;
1035+ be = new_be;
1036+ be->next = be_tmp;
1037+ if (!prev_be)
1038+ first_backend = be;
1039+ else
1040+ prev_be->next = be;
1041+ break;
1042+ }
1043+ prev_be = be;
1044+ be = be->next;
1045+ }
1046+ if (!be) /* last entry */
1047+ {
1048+ prev_be->next = new_be;
1049+ be = prev_be->next;
1050+ }
1051+ }
1052+ current_backend = be;
1053+ current_type = 0;
1054+ current_mfg = 0;
1055+ current_model = 0;
1056+ current_level = level_backend;
1057+ continue;
1058+ }
1059+ if (!current_backend)
1060+ {
1061+ DBG_ERR ("use `:backend' keyword first\n");
1062+ return SANE_FALSE;
1063+ }
1064+ if (read_keyword
1065+ (line, ":version", param_string,
1066+ &string_entry) == SANE_STATUS_GOOD)
1067+ {
1068+ if (current_backend->version)
1069+ {
1070+ DBG_WARN
1071+ ("overwriting version of backend `%s' to `%s'"
1072+ "(was: `%s')\n", current_backend->name,
1073+ string_entry, current_backend->version,
1074+ current_backend->version);
1075+ }
1076+
1077+ DBG_INFO ("setting version of backend `%s' to `%s'\n",
1078+ current_backend->name, string_entry);
1079+ current_backend->version = string_entry;
1080+ continue;
1081+ }
1082+ if (read_keyword
1083+ (line, ":status", param_string,
1084+ &string_entry) == SANE_STATUS_GOOD)
1085+ {
1086+ switch (current_level)
1087+ {
1088+ case level_model:
1089+ if (current_model->status != status_unknown)
1090+ {
1091+ DBG_WARN
1092+ ("overwriting status of model `%s' (backend `%s')\n",
1093+ current_model->name, current_backend->name);
1094+ }
1095+ if (strcmp (string_entry, ":minimal") == 0)
1096+ {
1097+ DBG_INFO
1098+ ("setting status of model `%s' to `minimal'\n",
1099+ current_model->name);
1100+ current_model->status = status_minimal;
1101+ }
1102+ else if (strcmp (string_entry, ":basic") == 0)
1103+ {
1104+ DBG_INFO
1105+ ("setting status of model `%s' to `basic'\n",
1106+ current_model->name);
1107+ current_model->status = status_basic;
1108+ }
1109+ else if (strcmp (string_entry, ":good") == 0)
1110+ {
1111+ DBG_INFO
1112+ ("setting status of model `%s' to `good'\n",
1113+ current_model->name);
1114+ current_model->status = status_good;
1115+ }
1116+ else if (strcmp (string_entry, ":complete") == 0)
1117+ {
1118+ DBG_INFO
1119+ ("setting status of model `%s' to `complete'\n",
1120+ current_model->name);
1121+ current_model->status = status_complete;
1122+ }
1123+ else if (strcmp (string_entry, ":untested") == 0)
1124+ {
1125+ DBG_INFO
1126+ ("setting status of model `%s' to `untested'\n",
1127+ current_model->name);
1128+ current_model->status = status_untested;
1129+ }
1130+ else if (strcmp (string_entry, ":unsupported") == 0)
1131+ {
1132+ DBG_INFO
1133+ ("setting status of model `%s' to `unsupported'\n",
1134+ current_model->name);
1135+ current_model->status = status_unsupported;
1136+ }
1137+ else
1138+ {
1139+ DBG_ERR
1140+ ("unknown status of model `%s': `%s' (backend `%s')\n",
1141+ current_model->name, string_entry,
1142+ current_backend->name);
1143+ current_model->status = status_untested;
1144+ return SANE_FALSE;
1145+ }
1146+ break;
1147+ default:
1148+ DBG_ERR
1149+ ("level %d not implemented for :status (backend `%s')\n",
1150+ current_level, current_backend->name);
1151+ return SANE_FALSE;
1152+ }
1153+
1154+
1155+ continue;
1156+ }
1157+ if (read_keyword (line, ":new", param_string, &string_entry)
1158+ == SANE_STATUS_GOOD)
1159+ {
1160+ if (strcmp (string_entry, ":yes") == 0)
1161+ {
1162+ DBG_INFO
1163+ ("backend %s is new in this SANE release\n",
1164+ current_backend->name);
1165+ current_backend->new = SANE_TRUE;
1166+ }
1167+ else if (strcmp (string_entry, ":no") == 0)
1168+ {
1169+ DBG_INFO
1170+ ("backend %s is NOT new in this SANE release\n",
1171+ current_backend->name);
1172+ current_backend->new = SANE_FALSE;
1173+ }
1174+ else
1175+ {
1176+ DBG_ERR ("unknown :new parameter of backend `%s': "
1177+ "`%s'\n", current_backend->name,
1178+ string_entry);
1179+ current_backend->new = SANE_FALSE;
1180+ return SANE_FALSE;
1181+ }
1182+ continue;
1183+ }
1184+ if (read_keyword
1185+ (line, ":manpage", param_string,
1186+ &string_entry) == SANE_STATUS_GOOD)
1187+ {
1188+ if (current_backend->manpage)
1189+ {
1190+ DBG_WARN
1191+ ("overwriting manpage of backend `%s' to `%s'"
1192+ "(was: `%s')\n", current_backend->name,
1193+ string_entry, current_backend->manpage);
1194+ }
1195+
1196+ DBG_INFO ("setting manpage of backend `%s' to `%s'\n",
1197+ current_backend->name, string_entry);
1198+ current_backend->manpage = string_entry;
1199+ continue;
1200+ }
1201+ if (read_keyword
1202+ (line, ":devicetype", param_string,
1203+ &string_entry) == SANE_STATUS_GOOD)
1204+ {
1205+ type_entry *type = 0;
1206+
1207+ type = current_backend->type;
1208+
1209+ DBG_INFO
1210+ ("adding `%s' to list of device types of backend "
1211+ "`%s'\n", string_entry, current_backend->name);
1212+
1213+ if (type)
1214+ {
1215+ while (type->next)
1216+ type = type->next;
1217+ type->next = calloc (1, sizeof (type_entry));
1218+ type = type->next;
1219+ }
1220+ else
1221+ {
1222+ current_backend->type =
1223+ calloc (1, sizeof (type_entry));
1224+ type = current_backend->type;
1225+ }
1226+
1227+ type->type = type_unknown;
1228+ if (strcmp (string_entry, ":scanner") == 0)
1229+ {
1230+ DBG_INFO ("setting device type of backend `%s' to "
1231+ "scanner\n", current_backend->name);
1232+ type->type = type_scanner;
1233+ }
1234+ else if (strcmp (string_entry, ":stillcam") == 0)
1235+ {
1236+ DBG_INFO ("setting device type of backend `%s' to "
1237+ "still camera\n", current_backend->name);
1238+ type->type = type_stillcam;
1239+ }
1240+ else if (strcmp (string_entry, ":vidcam") == 0)
1241+ {
1242+ DBG_INFO ("setting device type of backend `%s' to "
1243+ "video camera\n", current_backend->name);
1244+ type->type = type_vidcam;
1245+ }
1246+ else if (strcmp (string_entry, ":api") == 0)
1247+ {
1248+ DBG_INFO ("setting device type of backend `%s' to "
1249+ "API\n", current_backend->name);
1250+ type->type = type_api;
1251+ }
1252+ else if (strcmp (string_entry, ":meta") == 0)
1253+ {
1254+ DBG_INFO ("setting device type of backend `%s' to "
1255+ "meta\n", current_backend->name);
1256+ type->type = type_meta;
1257+ }
1258+ else
1259+ {
1260+ DBG_ERR
1261+ ("unknown device type of backend `%s': `%s'\n",
1262+ current_backend->name, string_entry);
1263+ type->type = type_unknown;
1264+ return SANE_FALSE;
1265+ }
1266+ current_type = type;
1267+ current_mfg = 0;
1268+ current_model = 0;
1269+ continue;
1270+ }
1271+ if (read_keyword
1272+ (line, ":desc", param_string,
1273+ &string_entry) == SANE_STATUS_GOOD)
1274+ {
1275+ if (!current_type)
1276+ {
1277+ DBG_ERR
1278+ ("use `:devicetype' keyword first (backend `%s')\n",
1279+ current_backend->name);
1280+ return SANE_FALSE;
1281+ }
1282+ if (current_type->type < type_meta)
1283+ {
1284+ DBG_ERR
1285+ ("use `:desc' for `:api' and `:meta' only (backend `%s')\n",
1286+ current_backend->name);
1287+ return SANE_FALSE;
1288+ }
1289+
1290+ if (current_type->desc)
1291+ {
1292+ DBG_WARN
1293+ ("overwriting description of device type of "
1294+ "backend `%s' to `%s' (was: `%s')\n",
1295+ current_backend->name, string_entry,
1296+ current_type->desc);
1297+ }
1298+
1299+ DBG_INFO
1300+ ("setting description of backend `%s' to `%s'\n",
1301+ current_backend->name, string_entry);
1302+ current_type->desc = calloc (1, sizeof (desc_entry));
1303+ if (!current_type->desc)
1304+ {
1305+ DBG_ERR ("calloc failed (%s)\n", strerror (errno));
1306+ return SANE_FALSE;
1307+ }
1308+ current_type->desc->desc = string_entry;
1309+ current_level = level_desc;
1310+ current_mfg = 0;
1311+ current_model = 0;
1312+ continue;
1313+ }
1314+ if (read_keyword (line, ":mfg", param_string, &string_entry)
1315+ == SANE_STATUS_GOOD)
1316+ {
1317+ mfg_entry *mfg = 0;
1318+
1319+ if (!current_type)
1320+ {
1321+ DBG_ERR
1322+ ("use `:devicetype' keyword first (backend `%s')\n",
1323+ current_backend->name);
1324+ return SANE_FALSE;
1325+ }
1326+ if (current_type->type >= type_meta)
1327+ {
1328+ DBG_ERR
1329+ ("use `:mfg' for hardware devices only (backend `%s')\n",
1330+ current_backend->name);
1331+ return SANE_FALSE;
1332+ }
1333+
1334+ mfg = current_type->mfg;
1335+ if (mfg)
1336+ {
1337+ while (mfg->next)
1338+ mfg = mfg->next;
1339+ mfg->next = calloc (1, sizeof (mfg_entry));
1340+ mfg = mfg->next;
1341+ }
1342+ else
1343+ {
1344+ current_type->mfg = calloc (1, sizeof (mfg_entry));
1345+ mfg = current_type->mfg;
1346+ }
1347+
1348+ if (!mfg)
1349+ {
1350+ DBG_ERR ("calloc failed (%s)\n", strerror (errno));
1351+ return SANE_FALSE;
1352+ }
1353+ mfg->name = string_entry;
1354+ DBG_INFO ("adding mfg entry %s to backend `%s'\n",
1355+ string_entry, current_backend->name);
1356+ current_mfg = mfg;
1357+ current_model = 0;
1358+ current_level = level_mfg;
1359+ continue;
1360+ }
1361+ if (read_keyword
1362+ (line, ":model", param_string,
1363+ &string_entry) == SANE_STATUS_GOOD)
1364+ {
1365+ model_entry *model = 0;
1366+
1367+ if (!current_type)
1368+ {
1369+ DBG_ERR
1370+ ("use `:devicetype' keyword first (backend `%s')\n",
1371+ current_backend->name);
1372+ return SANE_FALSE;
1373+ }
1374+ if (current_level != level_mfg
1375+ && current_level != level_model)
1376+ {
1377+ DBG_ERR
1378+ ("use `:mfg' keyword first (backend `%s')\n",
1379+ current_backend->name);
1380+ return SANE_FALSE;
1381+ }
1382+ model = current_mfg->model;
1383+ if (model)
1384+ {
1385+ while (model->next)
1386+ model = model->next;
1387+ model->next = calloc (1, sizeof (model_entry));
1388+ model = model->next;
1389+ }
1390+ else
1391+ {
1392+ current_mfg->model =
1393+ calloc (1, sizeof (model_entry));
1394+ model = current_mfg->model;
1395+ }
1396+
1397+ if (!model)
1398+ {
1399+ DBG_ERR ("calloc failed (%s)\n", strerror (errno));
1400+ return SANE_FALSE;
1401+ }
1402+ model->name = string_entry;
1403+ model->status = status_unknown;
1404+ DBG_INFO
1405+ ("adding model entry %s to manufacturer `%s'\n",
1406+ string_entry, current_mfg->name);
1407+ current_model = model;
1408+ current_level = level_model;
1409+ continue;
1410+ }
1411+ if (read_keyword
1412+ (line, ":interface", param_string,
1413+ &string_entry) == SANE_STATUS_GOOD)
1414+ {
1415+ if (!current_model)
1416+ {
1417+ DBG_WARN
1418+ ("ignored `%s' :interface, only allowed for "
1419+ "hardware devices\n", current_backend->name);
1420+ continue;
1421+ }
1422+
1423+ if (current_model->interface)
1424+ {
1425+ DBG_WARN ("overwriting `%s's interface of model "
1426+ "`%s' to `%s' (was: `%s')\n",
1427+ current_backend->name,
1428+ current_model->name, string_entry,
1429+ current_model->interface);
1430+ }
1431+
1432+ DBG_INFO ("setting interface of model `%s' to `%s'\n",
1433+ current_model->name, string_entry);
1434+ current_model->interface = string_entry;
1435+ continue;
1436+ }
1437+ if (read_keyword
1438+ (line, ":scsi", param_three_strings,
1439+ &three_string_entry) == SANE_STATUS_GOOD)
1440+ {
1441+ if (!current_model)
1442+ {
1443+ DBG_WARN
1444+ ("ignored `%s' :scsi, only allowed for "
1445+ "hardware devices\n", current_backend->name);
1446+ continue;
1447+ }
1448+
1449+ DBG_INFO ("setting scsi vendor and product ids of model `%s' to `%s/%s'\n",
1450+ current_model->name, three_string_entry[0], three_string_entry[1]);
1451+ if (strcasecmp (three_string_entry[0], "ignore") == 0)
1452+ {
1453+ DBG_INFO ("Ignoring `%s's scsi-entries of `%s'\n",
1454+ current_backend->name,
1455+ current_model->name);
1456+ continue;
1457+ }
1458+ if (strcasecmp (three_string_entry[2], "processor") == 0){
1459+ current_model->scsi_is_processor = SANE_TRUE;
1460+ current_model->scsi_vendor_id = three_string_entry[0];
1461+ current_model->scsi_product_id = three_string_entry[1];
1462+ }
1463+ else
1464+ {
1465+ DBG_INFO ("scsi-format info in %s is invalid -> break\n", current_backend->name);
1466+ continue;
1467+ }
1468+ continue;
1469+ }
1470+ if (read_keyword
1471+ (line, ":usbid", param_two_strings,
1472+ &two_string_entry) == SANE_STATUS_GOOD)
1473+ {
1474+ if (!current_model)
1475+ {
1476+ DBG_WARN
1477+ ("ignored `%s' :usbid, only allowed for "
1478+ "hardware devices\n", current_backend->name);
1479+ continue;
1480+ }
1481+ if (strcasecmp (two_string_entry[0], "ignore") == 0)
1482+ {
1483+ DBG_INFO ("Ignoring `%s's USB ids of `%s'\n",
1484+ current_backend->name,
1485+ current_model->name);
1486+ current_model->ignore_usb_id = SANE_TRUE;
1487+ continue;
1488+ }
1489+ if (!check_hex (two_string_entry[0]))
1490+ {
1491+ DBG_WARN ("`%s's USB vendor id of `%s' is "
1492+ "not a lowercase 4-digit hex number: "
1493+ "`%s'\n", current_backend->name,
1494+ current_model->name, two_string_entry[0]);
1495+ continue;
1496+ }
1497+ if (!check_hex (two_string_entry[1]))
1498+ {
1499+ DBG_WARN ("`%s's USB product id of `%s' is "
1500+ "not a lowercase 4-digit hex number: "
1501+ "`%s'\n", current_backend->name,
1502+ current_model->name, two_string_entry[1]);
1503+ continue;
1504+ }
1505+
1506+ if (current_model->usb_vendor_id || current_model->usb_product_id)
1507+ {
1508+ DBG_WARN ("overwriting `%s's USB ids of model "
1509+ "`%s' to `%s/%s' (was: `%s/%s')\n",
1510+ current_backend->name,
1511+ current_model->name, two_string_entry[0],
1512+ two_string_entry[1],
1513+ current_model->usb_vendor_id,
1514+ current_model->usb_product_id);
1515+ }
1516+
1517+ DBG_INFO ("setting USB vendor and product ids of model `%s' to `%s/%s'\n",
1518+ current_model->name, two_string_entry[0], two_string_entry[1]);
1519+ current_model->usb_vendor_id = two_string_entry[0];
1520+ current_model->usb_product_id = two_string_entry[1];
1521+ continue;
1522+ }
1523+ if (read_keyword (line, ":url", param_string, &string_entry)
1524+ == SANE_STATUS_GOOD)
1525+ {
1526+ switch (current_level)
1527+ {
1528+ case level_backend:
1529+ current_backend->url =
1530+ update_url_list (current_backend->url,
1531+ string_entry);
1532+ DBG_INFO ("adding `%s' to list of urls of backend "
1533+ "`%s'\n", string_entry,
1534+ current_backend->name);
1535+ break;
1536+ case level_mfg:
1537+ current_mfg->url =
1538+ update_url_list (current_mfg->url, string_entry);
1539+ DBG_INFO ("adding `%s' to list of urls of mfg "
1540+ "`%s'\n", string_entry,
1541+ current_mfg->name);
1542+ break;
1543+ case level_desc:
1544+ current_type->desc->url =
1545+ update_url_list (current_type->desc->url,
1546+ string_entry);
1547+ DBG_INFO
1548+ ("adding `%s' to list of urls of description "
1549+ "for backend `%s'\n", string_entry,
1550+ current_backend->name);
1551+ break;
1552+ case level_model:
1553+ current_model->url =
1554+ update_url_list (current_model->url,
1555+ string_entry);
1556+ DBG_INFO ("adding `%s' to list of urls of model "
1557+ "`%s'\n", string_entry,
1558+ current_model->name);
1559+ break;
1560+ default:
1561+ DBG_ERR
1562+ ("level %d not implemented for :url (backend `%s')\n",
1563+ current_level, current_backend->name);
1564+ return SANE_FALSE;
1565+ }
1566+ continue;
1567+ }
1568+ if (read_keyword
1569+ (line, ":comment", param_string,
1570+ &string_entry) == SANE_STATUS_GOOD)
1571+ {
1572+ switch (current_level)
1573+ {
1574+ case level_backend:
1575+ current_backend->comment = string_entry;
1576+ DBG_INFO ("setting comment of backend %s to `%s'\n",
1577+ current_backend->name, string_entry);
1578+ break;
1579+ case level_mfg:
1580+ current_mfg->comment = string_entry;
1581+ DBG_INFO
1582+ ("setting comment of manufacturer %s to `%s'\n",
1583+ current_mfg->name, string_entry);
1584+ break;
1585+ case level_desc:
1586+ current_type->desc->comment = string_entry;
1587+ DBG_INFO ("setting comment of description for "
1588+ "backend %s to `%s'\n",
1589+ current_backend->name, string_entry);
1590+ break;
1591+ case level_model:
1592+ current_model->comment = string_entry;
1593+ DBG_INFO ("setting comment of model %s to `%s'\n",
1594+ current_model->name, string_entry);
1595+ break;
1596+ default:
1597+ DBG_ERR
1598+ ("level %d not implemented for `:comment' (backend `%s')\n",
1599+ current_level, current_backend->name);
1600+ return SANE_FALSE;
1601+ }
1602+ continue;
1603+ }
1604+ DBG_ERR
1605+ ("unknown keyword token in line `%s' of file `%s'\n",
1606+ line, file_name);
1607+ return SANE_FALSE;
1608+ } /* while (sanei_config_readline) */
1609+ fclose (fp);
1610+ } /* if (strlen) */
1611+ } /* while (direntry) */
1612+ if (closedir(dir) != 0)
1613+ {
1614+ DBG_ERR ("cannot close directory `%s' (%s)\n", search_dir,
1615+ strerror (errno));
1616+ return SANE_FALSE;
1617+ }
1618+ if (end)
1619+ search_dir = end + 1;
1620+ else
1621+ search_dir = (search_dir + strlen (search_dir));
1622+ }
1623+
1624+ desc_name = 0;
1625+ if (!first_backend)
1626+ {
1627+ DBG_ERR ("Couldn't find any .desc file\n");
1628+ return SANE_FALSE;
1629+ }
1630+ return SANE_TRUE;
1631+}
1632+
1633+/* Create a model_record_entry based on a model_entry */
1634+static model_record_entry *
1635+create_model_record (model_entry * model)
1636+{
1637+ model_record_entry *model_record;
1638+
1639+ model_record = calloc (1, sizeof (model_record_entry));
1640+ if (!model_record)
1641+ {
1642+ DBG_ERR ("create_model_record: couldn't calloc model_record_entry\n");
1643+ exit (1);
1644+ }
1645+ model_record->name = model->name;
1646+ model_record->status = model->status;
1647+ model_record->interface = model->interface;
1648+ model_record->url = model->url;
1649+ model_record->comment = model->comment;
1650+ model_record->usb_vendor_id = model->usb_vendor_id;
1651+ model_record->usb_product_id = model->usb_product_id;
1652+ model_record->scsi_vendor_id = model->scsi_vendor_id;
1653+ model_record->scsi_product_id = model->scsi_product_id;
1654+ model_record->scsi_is_processor = model->scsi_is_processor;
1655+ return model_record;
1656+}
1657+
1658+/* Calculate the priority of statuses: */
1659+/* minimal, basic, good, complete -> 2, untested -> 1, unsupported -> 0 */
1660+static int
1661+calc_priority (status_entry status)
1662+{
1663+ switch (status)
1664+ {
1665+ case status_untested:
1666+ return 1;
1667+ case status_unsupported:
1668+ return 0;
1669+ default:
1670+ return 2;
1671+ }
1672+}
1673+
1674+/* Insert model into list at the alphabetically correct position */
1675+static model_record_entry *
1676+update_model_record_list (model_record_entry * first_model_record,
1677+ model_entry * model, backend_entry * be)
1678+{
1679+ model_record_entry *model_record = first_model_record;
1680+
1681+ if (!first_model_record)
1682+ {
1683+ /* First model for this manufacturer */
1684+ first_model_record = create_model_record (model);
1685+ model_record = first_model_record;
1686+ }
1687+ else
1688+ {
1689+ model_record_entry *prev_model_record = 0;
1690+
1691+ while (model_record)
1692+ {
1693+ int compare = string_compare (model->name, model_record->name);
1694+ if (compare <= 0)
1695+ {
1696+ model_record_entry *tmp_model_record = model_record;
1697+ if ((compare == 0) &&
1698+ (string_compare (model->interface, model_record->interface) == 0) &&
1699+ (string_compare (model->usb_vendor_id, model_record->usb_vendor_id) == 0) &&
1700+ (string_compare (model->usb_product_id, model_record->usb_product_id) == 0))
1701+ {
1702+ /* Two entries for the same model */
1703+ int new_priority = calc_priority (model->status);
1704+ int old_priority = calc_priority (model_record->status);
1705+ if (new_priority < old_priority)
1706+ {
1707+ DBG_DBG
1708+ ("update_model_record_list: model %s ignored, backend %s has "
1709+ "higher priority\n", model->name,
1710+ model_record->be->name);
1711+ return first_model_record;
1712+ }
1713+ if (new_priority > old_priority)
1714+ {
1715+ DBG_DBG
1716+ ("update_model_record_list: model %s overrides the one from backend %s\n",
1717+ model->name, model_record->be->name);
1718+ tmp_model_record = model_record->next;
1719+ }
1720+ }
1721+ /* correct position */
1722+ model_record = create_model_record (model);
1723+ model_record->next = tmp_model_record;
1724+ if (!prev_model_record)
1725+ first_model_record = model_record;
1726+ else
1727+ prev_model_record->next = model_record;
1728+ break;
1729+ }
1730+ prev_model_record = model_record;
1731+ model_record = model_record->next;
1732+ }
1733+ if (!model_record) /* last entry */
1734+ {
1735+ prev_model_record->next = create_model_record (model);
1736+ model_record = prev_model_record->next;
1737+ }
1738+ } /* if (first_model_record) */
1739+ model_record->be = be;
1740+ DBG_DBG ("update_model_record_list: added model %s\n", model->name);
1741+ return first_model_record;
1742+}
1743+
1744+
1745+/* Insert manufacturer into list at the alphabetically correct position, */
1746+/* create new record if neccessary */
1747+static mfg_record_entry *
1748+update_mfg_record_list (mfg_record_entry * first_mfg_record, mfg_entry * mfg,
1749+ backend_entry * be)
1750+{
1751+ model_entry *model = mfg->model;
1752+ mfg_record_entry *mfg_record = first_mfg_record;
1753+
1754+ while (mfg_record)
1755+ {
1756+ if (string_compare (mfg_record->name, mfg->name) == 0)
1757+ {
1758+ /* Manufacturer already exists */
1759+ url_entry *mfg_url = mfg->url;
1760+
1761+ /* Manufacturer comments and (additional) URLs? */
1762+ if (!mfg_record->comment)
1763+ mfg_record->comment = mfg->comment;
1764+ while (mfg_url && mfg_url->name)
1765+ {
1766+ mfg_record->url = update_url_list (mfg_record->url,
1767+ mfg_url->name);
1768+ mfg_url = mfg_url->next;
1769+ }
1770+ break;
1771+ }
1772+ mfg_record = mfg_record->next;
1773+ }
1774+
1775+ if (!mfg_record)
1776+ {
1777+ /* Manufacturer doesn't exist yet */
1778+ url_entry *url = mfg->url;
1779+
1780+ mfg_record = calloc (1, sizeof (mfg_record_entry));
1781+ if (!mfg_record)
1782+ {
1783+ DBG_ERR ("update_mfg_record_list: couldn't calloc "
1784+ "mfg_record_entry\n");
1785+ exit (1);
1786+ }
1787+ mfg_record->name = mfg->name;
1788+ mfg_record->comment = mfg->comment;
1789+ while (url)
1790+ {
1791+ mfg_record->url = update_url_list (mfg_record->url, url->name);
1792+ url = url->next;
1793+ }
1794+ if (first_mfg_record != 0)
1795+ {
1796+ /* We already have one manufacturer in the list */
1797+ mfg_record_entry *new_mfg_record = mfg_record;
1798+ mfg_record_entry *prev_mfg_record = 0;
1799+
1800+ mfg_record = first_mfg_record;
1801+
1802+ while (mfg_record)
1803+ {
1804+ int compare =
1805+ string_compare (new_mfg_record->name, mfg_record->name);
1806+ if (compare <= 0)
1807+ {
1808+ mfg_record_entry *tmp_mfg_record = mfg_record;
1809+ mfg_record = new_mfg_record;
1810+ mfg_record->next = tmp_mfg_record;
1811+ if (!prev_mfg_record)
1812+ first_mfg_record = mfg_record;
1813+ else
1814+ prev_mfg_record->next = mfg_record;
1815+ break;
1816+ }
1817+ prev_mfg_record = mfg_record;
1818+ mfg_record = mfg_record->next;
1819+ }
1820+ if (!mfg_record) /* last entry */
1821+ {
1822+ prev_mfg_record->next = new_mfg_record;
1823+ mfg_record = prev_mfg_record->next;
1824+ }
1825+ }
1826+ else
1827+ first_mfg_record = mfg_record;
1828+ DBG_DBG ("update_mfg_record_list: created mfg %s\n", mfg_record->name);
1829+ } /* if (!mfg_record) */
1830+
1831+ /* create model entries */
1832+ while (model)
1833+ {
1834+ mfg_record->model_record =
1835+ update_model_record_list (mfg_record->model_record, model, be);
1836+ model = model->next;
1837+ }
1838+ return first_mfg_record;
1839+}
1840+
1841+/* Create a sorted list of manufacturers based on the backends list */
1842+static mfg_record_entry *
1843+create_mfg_list (device_type dev_type)
1844+{
1845+ mfg_record_entry *first_mfg_record = 0;
1846+ backend_entry *be = first_backend;
1847+
1848+ DBG_DBG ("create_mfg_list: start\n");
1849+ while (be)
1850+ {
1851+ type_entry *type = be->type;
1852+ while (type)
1853+ {
1854+ if (type->type == dev_type)
1855+ {
1856+ mfg_entry *mfg = type->mfg;
1857+ while (mfg)
1858+ {
1859+ first_mfg_record =
1860+ update_mfg_record_list (first_mfg_record, mfg, be);
1861+ mfg = mfg->next;
1862+ }
1863+ }
1864+ type = type->next;
1865+ }
1866+ be = be->next;
1867+ }
1868+ DBG_DBG ("create_mfg_list: exit\n");
1869+ return first_mfg_record;
1870+}
1871+
1872+/* Print an ASCII list with all the information we have */
1873+static void
1874+ascii_print_backends (void)
1875+{
1876+ backend_entry *be;
1877+
1878+ be = first_backend;
1879+ while (be)
1880+ {
1881+ url_entry *url = be->url;
1882+ type_entry *type = be->type;
1883+
1884+ if (be->name)
1885+ printf ("backend `%s'\n", be->name);
1886+ else
1887+ printf ("backend *none*\n");
1888+
1889+ if (be->version)
1890+ printf (" version `%s'\n", be->version);
1891+ else
1892+ printf (" version *none*\n");
1893+
1894+ if (be->new)
1895+ printf (" NEW!\n");
1896+
1897+ if (be->manpage)
1898+ printf (" manpage `%s'\n", be->manpage);
1899+ else
1900+ printf (" manpage *none*\n");
1901+
1902+ if (url)
1903+ while (url)
1904+ {
1905+ printf (" url `%s'\n", url->name);
1906+ url = url->next;
1907+ }
1908+ else
1909+ printf (" url *none*\n");
1910+
1911+ if (be->comment)
1912+ printf (" comment `%s'\n", be->comment);
1913+ else
1914+ printf (" comment *none*\n");
1915+
1916+ if (type)
1917+ while (type)
1918+ {
1919+ switch (type->type)
1920+ {
1921+ case type_scanner:
1922+ printf (" type scanner\n");
1923+ break;
1924+ case type_stillcam:
1925+ printf (" type stillcam\n");
1926+ break;
1927+ case type_vidcam:
1928+ printf (" type vidcam\n");
1929+ break;
1930+ case type_meta:
1931+ printf (" type meta\n");
1932+ break;
1933+ case type_api:
1934+ printf (" type api\n");
1935+ break;
1936+ default:
1937+ printf (" type *unknown*\n");
1938+ break;
1939+ }
1940+ if (type->desc)
1941+ {
1942+ url_entry *url = type->desc->url;
1943+ printf (" desc `%s'\n", type->desc->desc);
1944+ if (url)
1945+ while (url)
1946+ {
1947+ printf (" url `%s'\n", url->name);
1948+ url = url->next;
1949+ }
1950+ else
1951+ printf (" url *none*\n");
1952+
1953+ if (type->desc->comment)
1954+ printf (" comment `%s'\n", type->desc->comment);
1955+ else
1956+ printf (" comment *none*\n");
1957+ }
1958+ else if (type->type >= type_meta)
1959+ printf (" desc *none*\n");
1960+
1961+ if (type->mfg)
1962+ {
1963+ mfg_entry *mfg = type->mfg;
1964+ while (mfg)
1965+ {
1966+ model_entry *model = mfg->model;
1967+ url_entry *url = mfg->url;
1968+
1969+ printf (" mfg `%s'\n", mfg->name);
1970+ if (url)
1971+ while (url)
1972+ {
1973+ printf (" url `%s'\n", url->name);
1974+ url = url->next;
1975+ }
1976+ else
1977+ printf (" url *none*\n");
1978+
1979+ if (mfg->comment)
1980+ printf (" comment `%s'\n", mfg->comment);
1981+ else
1982+ printf (" comment *none*\n");
1983+
1984+ if (model)
1985+ while (model)
1986+ {
1987+ url_entry *url = model->url;
1988+ printf (" model `%s'\n", model->name);
1989+ if (model->interface)
1990+ printf (" interface `%s'\n", model->interface);
1991+ else
1992+ printf (" interface *none*\n");
1993+
1994+ if (model->usb_vendor_id)
1995+ printf (" usb-vendor-id `%s'\n", model->usb_vendor_id);
1996+ else
1997+ printf (" usb-vendor-id *none*\n");
1998+
1999+ if (model->usb_product_id)
2000+ printf (" usb-product-id `%s'\n", model->usb_product_id);
2001+ else
2002+ printf (" usb-product-id *none*\n");
2003+
2004+ switch (model->status)
2005+ {
2006+ case status_minimal:
2007+ printf (" status minimal\n");
2008+ break;
2009+ case status_basic:
2010+ printf (" status basic\n");
2011+ break;
2012+ case status_good:
2013+ printf (" status good\n");
2014+ break;
2015+ case status_complete:
2016+ printf (" status complete\n");
2017+ break;
2018+ case status_untested:
2019+ printf (" status untested\n");
2020+ break;
2021+ case status_unsupported:
2022+ printf (" status unsupported\n");
2023+ break;
2024+ default:
2025+ printf (" status *unknown*\n");
2026+ break;
2027+ }
2028+
2029+ if (url)
2030+ while (url)
2031+ {
2032+ printf (" url `%s'\n", url->name);
2033+ url = url->next;
2034+ }
2035+ else
2036+ printf (" url *none*\n");
2037+
2038+ if (model->comment)
2039+ printf (" comment `%s'\n", model->comment);
2040+ else
2041+ printf (" comment *none*\n");
2042+
2043+ model = model->next;
2044+ }
2045+ else
2046+ printf (" model *none*\n");
2047+
2048+ mfg = mfg->next;
2049+ } /* while (mfg) */
2050+ }
2051+ else if (type->type < type_meta)
2052+ printf (" mfg *none*\n");
2053+ type = type->next;
2054+ } /* while (type) */
2055+ else
2056+ printf (" type *none*\n");
2057+ be = be->next;
2058+ } /* while (be) */
2059+}
2060+
2061+
2062+static char *
2063+clean_string (char *c)
2064+{
2065+ /* not avoided characters */
2066+
2067+ char *aux;
2068+
2069+ aux = malloc (strlen (c) * sizeof (char) * 6);
2070+
2071+ *aux = '\0';
2072+
2073+ while (*c != '\0')
2074+ {
2075+
2076+ /*limit to printable ASCII only*/
2077+ if(*c < 0x20 || *c > 0x7e){
2078+ c++;
2079+ continue;
2080+ }
2081+
2082+ switch (*c)
2083+ {
2084+ case '<':
2085+ aux = strcat (aux, "&lt;");
2086+ break;
2087+ case '>':
2088+ aux = strcat (aux, "&gt;");
2089+ break;
2090+ case '\'':
2091+ aux = strcat (aux, "&apos;");
2092+ break;
2093+ case '&':
2094+ aux = strcat (aux, "&amp;");
2095+ break;
2096+ default:
2097+ aux = strncat (aux, c, 1);
2098+ }
2099+ c = c + 1;
2100+ }
2101+ return aux;
2102+}
2103+
2104+/* Print an XML list with all the information we have */
2105+static void
2106+xml_print_backends (void)
2107+{
2108+ backend_entry *be;
2109+
2110+ be = first_backend;
2111+ printf ("<backends>\n");
2112+ while (be)
2113+ {
2114+ url_entry *url = be->url;
2115+ type_entry *type = be->type;
2116+
2117+ if (be->name)
2118+ printf ("<backend name=\"%s\">\n", clean_string (be->name));
2119+ else
2120+ printf ("<backend name=\"*none\">\n");
2121+
2122+ if (be->version)
2123+ printf ("<version>%s</version> \n", clean_string (be->version));
2124+ else
2125+ printf ("<version>*none*</version>\n");
2126+
2127+ if (be->new)
2128+ printf ("<new state=\"yes\"/>\n");
2129+ else
2130+ printf ("<new state=\"no\"/>\n");
2131+
2132+
2133+ if (be->manpage)
2134+ printf (" <manpage>%s</manpage>\n", clean_string (be->manpage));
2135+ else
2136+ printf (" <manpage>*none*</manpage>\n");
2137+
2138+ if (url)
2139+ while (url)
2140+ {
2141+ printf (" <url>%s</url>\n", clean_string (url->name));
2142+ url = url->next;
2143+ }
2144+ else
2145+ printf (" <url>*none*</url>\n");
2146+
2147+ if (be->comment)
2148+ printf (" <comment>%s</comment>\n", clean_string (be->comment));
2149+ else
2150+ printf (" <comment>*none*</comment>\n");
2151+
2152+ if (type)
2153+ while (type)
2154+ {
2155+
2156+ switch (type->type)
2157+ {
2158+ case type_scanner:
2159+ printf (" <type def=\"scanner\">\n");
2160+ break;
2161+ case type_stillcam:
2162+ printf (" <type def=\"stillcam\">\n");
2163+ break;
2164+ case type_vidcam:
2165+ printf (" <type def=\"vidcam\">\n");
2166+ break;
2167+ case type_meta:
2168+ printf (" <type def=\"meta\">\n");
2169+ break;
2170+ case type_api:
2171+ printf (" <type def=\"api\">\n");
2172+ break;
2173+ default:
2174+ printf (" <type def=\"*unknown*\">\n");
2175+ break;
2176+ }
2177+ if (type->desc)
2178+ {
2179+ url_entry *url = type->desc->url;
2180+ printf (" <desc>%s</desc>\n",
2181+ clean_string (type->desc->desc));
2182+ if (url)
2183+ while (url)
2184+ {
2185+ printf (" <url>%s</url>\n", clean_string (url->name));
2186+ url = url->next;
2187+ }
2188+ else
2189+ printf (" <url>*none*</url>\n");
2190+
2191+ if (type->desc->comment)
2192+ printf (" <comment>%s</comment>\n",
2193+ clean_string (type->desc->comment));
2194+ else
2195+ printf (" <comment>*none*</comment>\n");
2196+ }
2197+ else if (type->type >= type_meta)
2198+ printf (" <desc>*none*</desc>\n");
2199+
2200+ if (type->mfg)
2201+ {
2202+ mfg_entry *mfg = type->mfg;
2203+ while (mfg)
2204+ {
2205+ model_entry *model = mfg->model;
2206+ url_entry *url = mfg->url;
2207+
2208+ printf (" <mfg name=\"%s\">\n", clean_string (mfg->name));
2209+ if (url)
2210+ while (url)
2211+ {
2212+ printf (" <url>`%s'</url>\n",
2213+ clean_string (url->name));
2214+ url = url->next;
2215+ }
2216+ else
2217+ printf (" <url>*none*</url>\n");
2218+
2219+ if (mfg->comment)
2220+ printf (" <comment>%s</comment>\n",
2221+ clean_string (mfg->comment));
2222+ else
2223+ printf (" <comment>*none*</comment>\n");
2224+
2225+ if (model)
2226+ while (model)
2227+ {
2228+ url_entry *url = model->url;
2229+ printf (" <model name=\"%s\">\n",
2230+ clean_string (model->name));
2231+ if (model->interface)
2232+ printf (" <interface>%s</interface>\n",
2233+ clean_string (model->interface));
2234+ else
2235+ printf (" <interface>*none*</interface>\n");
2236+
2237+ if (model->usb_vendor_id)
2238+ printf (" <usbvendorid>%s</usbvendorid>\n",
2239+ clean_string (model->usb_vendor_id));
2240+ else
2241+ printf (" <usbvendorid>*none*</usbvendorid>\n");
2242+ if (model->usb_product_id)
2243+ printf (" <usbproductid>%s</usbproductid>\n",
2244+ clean_string (model->usb_product_id));
2245+ else
2246+ printf (" <usbproductid>*none*</usbproductid>\n");
2247+
2248+ switch (model->status)
2249+ {
2250+ case status_minimal:
2251+ printf (" <status>minimal</status>\n");
2252+ break;
2253+ case status_basic:
2254+ printf (" <status>basic</status>\n");
2255+ break;
2256+ case status_good:
2257+ printf (" <status>good</status>\n");
2258+ break;
2259+ case status_complete:
2260+ printf (" <status>complete</status>\n");
2261+ break;
2262+ case status_untested:
2263+ printf (" <status>untested</status>\n");
2264+ break;
2265+ case status_unsupported:
2266+ printf (" <status>unsupported</status>\n");
2267+ break;
2268+ default:
2269+ printf (" <status>*unknown*</status>\n");
2270+ break;
2271+ }
2272+
2273+ if (url)
2274+ while (url)
2275+ {
2276+ printf (" <url>%s</url>\n",
2277+ clean_string (url->name));
2278+ url = url->next;
2279+ }
2280+ else
2281+ printf (" <url>*none*</url>\n");
2282+
2283+ if (model->comment)
2284+ printf (" <comment>%s</comment>\n",
2285+ clean_string (model->comment));
2286+ else
2287+ printf (" <comment>*none*</comment>\n");
2288+
2289+ model = model->next;
2290+ printf (" </model>\n");
2291+ } /* while (model) */
2292+ else
2293+ printf (" <model name=\"*none*\" />\n");
2294+
2295+ printf (" </mfg>\n");
2296+ mfg = mfg->next;
2297+ } /* while (mfg) */
2298+ }
2299+ else if (type->type < type_meta)
2300+ printf (" <mfg>*none*</mfg>\n");
2301+ type = type->next;
2302+ printf (" </type>\n");
2303+ } /* while (type) */
2304+ else
2305+ printf (" <type>*none*</type>\n");
2306+ printf ("</backend>\n");
2307+ be = be->next;
2308+
2309+ } /* while (be) */
2310+ printf ("</backends>\n");
2311+}
2312+
2313+/* calculate statistics about supported devices per device type*/
2314+static void
2315+calculate_statistics_per_type (device_type dev_type, statistics_type num)
2316+{
2317+ backend_entry *be = first_backend;
2318+
2319+ while (be)
2320+ {
2321+ type_entry *type = be->type;
2322+
2323+ while (type)
2324+ {
2325+ if (type->type == dev_type)
2326+ {
2327+ mfg_entry *mfg = type->mfg;
2328+ model_entry *model;
2329+
2330+ if (type->desc)
2331+ {
2332+ num[status_complete]++;
2333+ type = type->next;
2334+ continue;
2335+ }
2336+
2337+ if (!mfg)
2338+ {
2339+ type = type->next;
2340+ continue;
2341+ }
2342+
2343+ mfg = type->mfg;
2344+ while (mfg)
2345+ {
2346+ model = mfg->model;
2347+ if (model)
2348+ {
2349+ while (model)
2350+ {
2351+ enum status_entry status = model->status;
2352+ num[status]++;
2353+ model = model->next;
2354+ } /* while (model) */
2355+ } /* if (num_models) */
2356+ mfg = mfg->next;
2357+ } /* while (mfg) */
2358+ } /* if (type->type) */
2359+ type = type->next;
2360+ } /* while (type) */
2361+ be = be->next;
2362+ } /* while (be) */
2363+}
2364+
2365+static void
2366+html_print_statistics_cell (const char * color, int number)
2367+{
2368+ printf ("<td align=center><font color=%s>%d</font></td>\n",
2369+ color, number);
2370+}
2371+
2372+static void
2373+html_print_statistics_per_type (device_type dev_type)
2374+{
2375+ statistics_type num = {0, 0, 0, 0, 0, 0, 0};
2376+ status_entry status;
2377+
2378+ calculate_statistics_per_type (dev_type, num);
2379+ printf ("<tr>\n");
2380+ printf("<td align=center><a href=\"#%s\">%s</a></td>\n",
2381+ device_type_aname [dev_type], device_type_name [dev_type]);
2382+
2383+ html_print_statistics_cell
2384+ (COLOR_UNKNOWN,
2385+ num[status_minimal] + num[status_basic] + num[status_good] +
2386+ num[status_complete] + num[status_untested] + num[status_unsupported]);
2387+ if (dev_type == type_scanner || dev_type == type_stillcam
2388+ || dev_type == type_vidcam)
2389+ {
2390+ html_print_statistics_cell
2391+ (COLOR_UNKNOWN,
2392+ num[status_minimal] + num[status_basic] + num[status_good] +
2393+ num[status_complete]);
2394+ for (status = status_complete; status >= status_unsupported; status--)
2395+ html_print_statistics_cell (status_color [status], num [status]);
2396+ }
2397+ else
2398+ {
2399+ printf ("<td align=center colspan=7>n/a</td>\n");
2400+ }
2401+ printf ("</tr>\n");
2402+}
2403+
2404+/* print html statistcis */
2405+static void
2406+html_print_summary (void)
2407+{
2408+ device_type dev_type;
2409+ status_entry status;
2410+
2411+ printf ("<h2>Summary</h2>\n");
2412+ printf ("<table border=1>\n");
2413+ printf ("<tr bgcolor=E0E0FF>\n");
2414+ printf ("<th align=center rowspan=3>Device type</th>\n");
2415+ printf ("<th align=center colspan=8>Number of devices</th>\n");
2416+ printf ("</tr>\n");
2417+ printf ("<tr bgcolor=E0E0FF>\n");
2418+ printf ("<th align=center rowspan=2>Total</th>\n");
2419+ printf ("<th align=center colspan=5>Supported</th>\n");
2420+ printf ("<th align=center rowspan=2><font color=" COLOR_UNTESTED
2421+ ">%s</font></th>\n", status_name[status_untested]);
2422+ printf ("<th align=center rowspan=2><font color=" COLOR_UNSUPPORTED
2423+ ">%s</font></th>\n", status_name[status_unsupported]);
2424+ printf ("</tr>\n");
2425+ printf ("<tr bgcolor=E0E0FF>\n");
2426+ printf ("<th align=center>Sum</th>\n");
2427+ for (status = status_complete; status >= status_minimal; status--)
2428+ printf ("<th align=center><font color=%s>%s</font></th>\n",
2429+ status_color[status], status_name[status]);
2430+ printf ("</tr>\n");
2431+ for (dev_type = type_scanner; dev_type <= type_api; dev_type++)
2432+ html_print_statistics_per_type (dev_type);
2433+ printf ("</table>\n");
2434+}
2435+
2436+
2437+/* Generate a name used for <a name=...> HTML tags */
2438+static char *
2439+html_generate_anchor_name (device_type dev_type, char *manufacturer_name)
2440+{
2441+ char *name = malloc (strlen (manufacturer_name) + 1 + 2);
2442+ char *pointer = name;
2443+ char type_char;
2444+
2445+ if (!name)
2446+ {
2447+ DBG_ERR ("html_generate_anchor_name: couldn't malloc\n");
2448+ return 0;
2449+ }
2450+
2451+ switch (dev_type)
2452+ {
2453+ case type_scanner:
2454+ type_char = 'S';
2455+ break;
2456+ case type_stillcam:
2457+ type_char = 'C';
2458+ break;
2459+ case type_vidcam:
2460+ type_char = 'V';
2461+ break;
2462+ case type_meta:
2463+ type_char = 'M';
2464+ break;
2465+ case type_api:
2466+ type_char = 'A';
2467+ break;
2468+ default:
2469+ type_char = 'Z';
2470+ break;
2471+ }
2472+
2473+ snprintf (name, strlen (manufacturer_name) + 1 + 2, "%c-%s",
2474+ type_char, manufacturer_name);
2475+
2476+ while (*pointer)
2477+ {
2478+ if (!isalnum (*pointer))
2479+ *pointer = '-';
2480+ else
2481+ *pointer = toupper (*pointer);
2482+ pointer++;
2483+ }
2484+ return name;
2485+}
2486+
2487+
2488+/* Generate one table per backend of all backends providing models */
2489+/* of type dev_type */
2490+static void
2491+html_backends_split_table (device_type dev_type)
2492+{
2493+ backend_entry *be = first_backend;
2494+ SANE_Bool first = SANE_TRUE;
2495+
2496+ printf ("<p><b>Backends</b>: \n");
2497+ while (be) /* print link list */
2498+ {
2499+ type_entry *type = be->type;
2500+ SANE_Bool found = SANE_FALSE;
2501+
2502+ while (type)
2503+ {
2504+ if (type->type == dev_type)
2505+ found = SANE_TRUE;
2506+ type = type->next;
2507+ }
2508+ if (found)
2509+ {
2510+ if (!first)
2511+ printf (", \n");
2512+ first = SANE_FALSE;
2513+ printf ("<a href=\"#%s\">%s</a>",
2514+ html_generate_anchor_name (dev_type, be->name), be->name);
2515+ }
2516+ be = be->next;
2517+ }
2518+ be = first_backend;
2519+ if (first)
2520+ printf ("(none)\n");
2521+
2522+ printf ("</p>\n");
2523+
2524+
2525+ while (be)
2526+ {
2527+ type_entry *type = be->type;
2528+
2529+ while (type)
2530+ {
2531+ if (type->type == dev_type)
2532+ {
2533+ mfg_entry *mfg = type->mfg;
2534+ model_entry *model;
2535+
2536+ printf ("<h3><a name=\"%s\">Backend: %s\n",
2537+ html_generate_anchor_name (type->type, be->name),
2538+ be->name);
2539+
2540+ if (be->version || be->new)
2541+ {
2542+ printf ("(");
2543+ if (be->version)
2544+ {
2545+ printf ("%s", be->version);
2546+ if (be->new)
2547+ printf (", <font color=" COLOR_NEW ">NEW!</font>");
2548+ }
2549+ else
2550+ printf ("<font color=" COLOR_NEW ">NEW!</font>");
2551+ printf (")\n");
2552+ }
2553+ printf ("</a></h3>\n");
2554+
2555+ printf ("<p>\n");
2556+
2557+ if (be->url && be->url->name)
2558+ {
2559+ url_entry *url = be->url;
2560+ printf ("<b>Link(s):</b> \n");
2561+ while (url)
2562+ {
2563+ if (url != be->url)
2564+ printf (", ");
2565+ printf ("<a href=\"%s\">%s</a>", url->name, url->name);
2566+ url = url->next;
2567+ }
2568+ printf ("<br>\n");
2569+ }
2570+ if (be->manpage)
2571+ printf ("<b>Manual page:</b> <a href=\"" MAN_PAGE_LINK
2572+ "\">%s</a><br>\n", be->manpage, be->manpage);
2573+
2574+ if (be->comment)
2575+ printf ("<b>Comment:</b> %s<br>\n", be->comment);
2576+
2577+
2578+ if (type->desc)
2579+ {
2580+ if (type->desc->desc)
2581+ {
2582+ if (type->desc->url && type->desc->url->name)
2583+ printf ("<b>Description:</b> "
2584+ "<a href=\"%s\">%s</a><br>\n",
2585+ type->desc->url->name, type->desc->desc);
2586+ else
2587+ printf ("<b>Description:</b> %s<br>\n",
2588+ type->desc->desc);
2589+ }
2590+
2591+ if (type->desc->comment)
2592+ printf ("<b>Comment:</b> %s<br>\n", type->desc->comment);
2593+ printf ("</p>\n");
2594+ type = type->next;
2595+ continue;
2596+ }
2597+ printf ("</p>\n");
2598+
2599+ if (!mfg)
2600+ {
2601+ type = type->next;
2602+ continue;
2603+ }
2604+
2605+ printf ("<table border=1>\n");
2606+
2607+ printf ("<tr bgcolor=E0E0FF>\n");
2608+ printf ("<th align=center>Manufacturer</th>\n");
2609+ printf ("<th align=center>Model</th>\n");
2610+ printf ("<th align=center>Interface</th>\n");
2611+ printf ("<th align=center>USB id</th>\n");
2612+ printf ("<th align=center>Status</th>\n");
2613+ printf ("<th align=center>Comment</th>\n");
2614+ printf ("</tr>\n");
2615+
2616+ mfg = type->mfg;
2617+ while (mfg)
2618+ {
2619+ model = mfg->model;
2620+ if (model)
2621+ {
2622+ int num_models = 0;
2623+
2624+ while (model) /* count models for rowspan */
2625+ {
2626+ model = model->next;
2627+ num_models++;
2628+ }
2629+ model = mfg->model;
2630+ printf ("<tr>\n");
2631+ printf ("<td align=center rowspan=%d>\n", num_models);
2632+ if (mfg->url && mfg->url->name)
2633+ printf ("<a href=\"%s\">%s</a>\n", mfg->url->name,
2634+ mfg->name);
2635+ else
2636+ printf ("%s\n", mfg->name);
2637+
2638+ while (model)
2639+ {
2640+ enum status_entry status = model->status;
2641+
2642+ if (model != mfg->model)
2643+ printf ("<tr>\n");
2644+
2645+ if (model->url && model->url->name)
2646+ printf
2647+ ("<td align=center><a href=\"%s\">%s</a></td>\n",
2648+ model->url->name, model->name);
2649+ else
2650+ printf ("<td align=center>%s</td>\n",
2651+ model->name);
2652+
2653+ if (model->interface)
2654+ printf ("<td align=center>%s</td>\n",
2655+ model->interface);
2656+ else
2657+ printf ("<td align=center>?</td>\n");
2658+
2659+ if (model->usb_vendor_id && model->usb_product_id)
2660+ printf ("<td align=center>%s/%s</td>\n",
2661+ model->usb_vendor_id, model->usb_product_id);
2662+ else
2663+ printf ("<td align=center>&nbsp;</td>\n");
2664+
2665+ printf ("<td align=center><font color=%s>%s</font></td>\n",
2666+ status_color[status], status_name[status]);
2667+
2668+ if (model->comment && model->comment[0] != 0)
2669+ printf ("<td>%s</td>\n", model->comment);
2670+ else
2671+ printf ("<td>&nbsp;</td>\n");
2672+
2673+ model = model->next;
2674+ printf ("</tr>\n");
2675+ } /* while (model) */
2676+ } /* if (num_models) */
2677+ mfg = mfg->next;
2678+ } /* while (mfg) */
2679+ printf ("</table>\n");
2680+ } /* if (type->type) */
2681+ type = type->next;
2682+ } /* while (type) */
2683+ be = be->next;
2684+ } /* while (be) */
2685+ /* printf ("</table>\n"); */
2686+}
2687+
2688+/* Generate one table per manufacturer constructed of all backends */
2689+/* providing models of type dev_type */
2690+static void
2691+html_mfgs_table (device_type dev_type)
2692+{
2693+ mfg_record_entry *mfg_record = 0, *first_mfg_record = 0;
2694+
2695+ first_mfg_record = create_mfg_list (dev_type);
2696+ mfg_record = first_mfg_record;
2697+
2698+ printf ("<p><b>Manufacturers</b>: \n");
2699+ while (mfg_record)
2700+ {
2701+ if (mfg_record != first_mfg_record)
2702+ printf (", \n");
2703+ printf ("<a href=\"#%s\">%s</a>",
2704+ html_generate_anchor_name (type_unknown, mfg_record->name),
2705+ mfg_record->name);
2706+ mfg_record = mfg_record->next;
2707+ }
2708+ mfg_record = first_mfg_record;
2709+ if (!mfg_record)
2710+ printf ("(none)\n");
2711+ printf ("</p>\n");
2712+ while (mfg_record)
2713+ {
2714+ model_record_entry *model_record = mfg_record->model_record;
2715+
2716+ printf ("<h3><a name=\"%s\">Manufacturer: %s</a></h3>\n",
2717+ html_generate_anchor_name (type_unknown, mfg_record->name),
2718+ mfg_record->name);
2719+ printf ("<p>\n");
2720+ if (mfg_record->url && mfg_record->url->name)
2721+ {
2722+ url_entry *url = mfg_record->url;
2723+ printf ("<b>Link(s):</b> \n");
2724+ while (url)
2725+ {
2726+ if (url != mfg_record->url)
2727+ printf (", ");
2728+ printf ("<a href=\"%s\">%s</a>", url->name, url->name);
2729+ url = url->next;
2730+ }
2731+ printf ("<br>\n");
2732+ }
2733+ if (mfg_record->comment)
2734+ printf ("<b>Comment:</b> %s<br>\n", mfg_record->comment);
2735+ printf ("</p>\n");
2736+ if (!model_record)
2737+ {
2738+ mfg_record = mfg_record->next;
2739+ continue;
2740+ }
2741+ printf ("<table border=1>\n");
2742+ printf ("<tr bgcolor=E0E0FF>\n");
2743+
2744+ printf ("<th align=center>Model</th>\n");
2745+ printf ("<th align=center>Interface</th>\n");
2746+ printf ("<th align=center>USB id</th>\n");
2747+ printf ("<th align=center>Status</th>\n");
2748+ printf ("<th align=center>Comment</th>\n");
2749+ printf ("<th align=center>Backend</th>\n");
2750+ printf ("<th align=center>Manpage</th>\n");
2751+ printf ("</tr>\n");
2752+
2753+ while (model_record)
2754+ {
2755+ enum status_entry status = model_record->status;
2756+
2757+ if (model_record->url && model_record->url->name)
2758+ printf ("<tr><td align=center><a "
2759+ "href=\"%s\">%s</a></td>\n",
2760+ model_record->url->name, model_record->name);
2761+ else
2762+ printf ("<tr><td align=center>%s</td>\n", model_record->name);
2763+
2764+ if (model_record->interface)
2765+ printf ("<td align=center>%s</td>\n", model_record->interface);
2766+ else
2767+ printf ("<td align=center>?</td>\n");
2768+
2769+ if (model_record->usb_vendor_id && model_record->usb_product_id)
2770+ printf ("<td align=center>%s/%s</td>\n",
2771+ model_record->usb_vendor_id, model_record->usb_product_id);
2772+ else
2773+ printf ("<td align=center>&nbsp;</td>\n");
2774+
2775+ printf ("<td align=center><font color=%s>%s</font></td>\n",
2776+ status_color[status], status_name[status]);
2777+
2778+ if (model_record->comment && model_record->comment[0] != 0)
2779+ printf ("<td>%s</td>\n", model_record->comment);
2780+ else
2781+ printf ("<td>&nbsp;</td>\n");
2782+
2783+ printf ("<td align=center>\n");
2784+ if (model_record->be->url && model_record->be->url->name)
2785+ printf ("<a href=\"%s\">%s</a>\n",
2786+ model_record->be->url->name, model_record->be->name);
2787+ else
2788+ printf ("%s", model_record->be->name);
2789+
2790+ if (model_record->be->version || model_record->be->new)
2791+ {
2792+ printf ("<br>(");
2793+ if (model_record->be->version)
2794+ {
2795+ printf ("%s", model_record->be->version);
2796+ if (model_record->be->new)
2797+ printf (", <font color=" COLOR_NEW ">NEW!</font>");
2798+ }
2799+ else
2800+ printf ("<font color=" COLOR_NEW ">NEW!</font>");
2801+ printf (")\n");
2802+ }
2803+
2804+ printf ("</td>\n");
2805+ if (model_record->be->manpage)
2806+ printf ("<td align=center><a href=\""
2807+ MAN_PAGE_LINK "\">%s</a></td>\n",
2808+ model_record->be->manpage, model_record->be->manpage);
2809+ else
2810+ printf ("<td align=center>?</td>\n");
2811+
2812+ printf ("</tr>\n");
2813+ model_record = model_record->next;
2814+ } /* while model_record */
2815+ printf ("</table>\n");
2816+ mfg_record = mfg_record->next;
2817+ } /* while mfg_record */
2818+}
2819+
2820+/* Print the HTML headers and an introduction */
2821+static void
2822+html_print_header (void)
2823+{
2824+ printf
2825+ ("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"
2826+ "<html> <head>\n"
2827+ "<meta http-equiv=\"Content-Type\" content=\"text/html; "
2828+ "charset=iso-8859-1\">\n");
2829+ printf ("<title>%s</title>\n", title);
2830+ printf
2831+ ("</head>\n"
2832+ "<body bgcolor=FFFFFF>\n"
2833+ "<div align=center>\n"
2834+ "<img src=\"http://www.sane-project.org/images/sane.png\" alt=\"SANE\">\n");
2835+ printf ("<h1>%s</h1>\n", title);
2836+ printf ("</div>\n" "<hr>\n");
2837+ printf ("%s\n", intro);
2838+ printf
2839+ ("<p>This is only a summary!\n"
2840+ "Please consult the manpages and the author-supplied webpages\n"
2841+ "for more detailed (and usually important) information\n"
2842+ "concerning each backend.</p>\n");
2843+ printf
2844+ ("<p>If you have new information or corrections, please file a\n"
2845+ "<a href=\"http://www.sane-project.org/bugs.html\">bug report</a>\n"
2846+ "with as many details as possible. Also please tell us if your scanner \n"
2847+ "isn't mentioned in this list at all.</p>\n"
2848+ "<p>For an explanation of the tables, see the\n"
2849+ "<a href=\"#legend\">legend</a>.\n");
2850+}
2851+
2852+/* Print the HTML footers and contact information */
2853+static void
2854+html_print_footer (void)
2855+{
2856+ time_t current_time = time (0);
2857+
2858+ printf
2859+ ("<hr>\n"
2860+ "<a href=\"http://www.sane-project.org/\">SANE homepage</a>\n"
2861+ "<address>\n"
2862+ "<a href=\"http://www.sane-project.org/imprint.html\"\n"
2863+ ">Contact</a>\n" "</address>\n" "<font size=-1>\n");
2864+ printf ("This page was last updated on %s by sane-desc %s from %s\n",
2865+ asctime (localtime (&current_time)), SANE_DESC_VERSION, PACKAGE_STRING);
2866+ printf ("</font>\n");
2867+ printf ("</body> </html>\n");
2868+}
2869+
2870+
2871+/* print parts of the legend */
2872+static void
2873+html_print_legend_backend (void)
2874+{
2875+ printf
2876+ (" <dt><b>Backend:</b></dt>\n"
2877+ " <dd>Name of the backend, in parentheses if available:\n"
2878+ " Version of backend/driver; newer versions may be\n"
2879+ " available from their home sites.<br>"
2880+ " <font color=" COLOR_NEW ">NEW!</font> means brand-new to the\n"
2881+ " current release of SANE.<br>\n"
2882+ " UNMAINTAINED means that nobody maintains that backend. Expect no \n"
2883+ " new features or newly supported devices. You are welcome to take over \n"
2884+ " maintainership.\n" " </dd>\n");
2885+}
2886+
2887+static void
2888+html_print_legend_link (void)
2889+{
2890+ printf
2891+ (" <dt><b>Link(s):</b></dt>\n"
2892+ " <dd>Link(s) to more extensive and\n"
2893+ " detailed information, if it exists, or the email address\n"
2894+ " of the author or maintainer.\n");
2895+}
2896+
2897+static void
2898+html_print_legend_manual (void)
2899+{
2900+ printf
2901+ (" <dt><b>Manual Page:</b></dt>\n"
2902+ " <dd>A link to the man-page online, if it exists.</dd>\n");
2903+}
2904+
2905+static void
2906+html_print_legend_comment (void)
2907+{
2908+ printf
2909+ (" <dt><b>Comment:</b></dt>\n"
2910+ " <dd>More information about the backend or model, e.g. the level of "
2911+ " support and possible problems.</dd>\n");
2912+}
2913+
2914+static void
2915+html_print_legend_manufacturer (void)
2916+{
2917+ printf
2918+ (" <dt><b>Manufacturer:</b></dt>\n"
2919+ " <dd>Manufacturer, vendor or brand name of the device.</dd>\n");
2920+}
2921+
2922+static void
2923+html_print_legend_model (void)
2924+{
2925+ printf
2926+ (" <dt><b>Model:</b></dt>\n" " <dd>Name of the the device.</dd>\n");
2927+}
2928+
2929+static void
2930+html_print_legend_interface (void)
2931+{
2932+ printf
2933+ (" <dt><b>Interface:</b></dt>\n"
2934+ " <dd>How the device is connected to the computer.</dd>\n");
2935+}
2936+
2937+static void
2938+html_print_legend_usbid (void)
2939+{
2940+ printf
2941+ (" <dt><b>USB id:</b></dt>\n"
2942+ " <dd>The USB vendor and product ids as printed by sane-find-scanner -q (only applicable for USB devices).</dd>\n");
2943+}
2944+
2945+static void
2946+html_print_legend_status (void)
2947+{
2948+ printf
2949+ (" <dt><b>Status</b>:</dt>\n"
2950+ " <dd>Indicates how many of the features the device provides \n"
2951+ " are supported by SANE.\n"
2952+ " <ul><li><font color=" COLOR_UNSUPPORTED ">unsupported</font>"
2953+ " means the device is not supported at least by this backend. "
2954+ " It may be supported by other backends, however.\n");
2955+ printf
2956+ (" <li><font color=" COLOR_UNTESTED ">untested</font> means the "
2957+ " device may be supported but couldn't be tested. Be very "
2958+ " careful and report success/failure.\n"
2959+ " <li><font color=" COLOR_MINIMAL ">minimal</font> means that the\n"
2960+ " device is detected and scans at least in one mode. But the quality \n"
2961+ " is bad or important features won't work.\n");
2962+ printf
2963+ (" <li><font color=" COLOR_BASIC ">basic</font> means it works at \n"
2964+ " least in the most important modes but quality is not perfect.\n"
2965+ " <li><font color=" COLOR_GOOD
2966+ ">good</font> means the device is usable \n"
2967+ " for day-to-day work. Some rather exotic features may be missing.\n"
2968+ " <li><font color=" COLOR_COMPLETE
2969+ ">complete</font> means the backends \n"
2970+ " supports everything the device can do.\n" " </ul></dd>\n");
2971+}
2972+
2973+static void
2974+html_print_legend_description (void)
2975+{
2976+ printf
2977+ (" <dt><b>Description</b>:</dt>\n"
2978+ " <dd>The scope of application of the backend.\n");
2979+}
2980+
2981+/* Print the HTML page with one table of models per backend */
2982+static void
2983+html_print_backends_split (void)
2984+{
2985+ if (!title)
2986+ title = "SANE: Backends (Drivers)";
2987+ if (!intro)
2988+ intro = "<p> The following table summarizes the backends/drivers "
2989+ "distributed with the latest version of sane-backends, and the hardware "
2990+ "or software they support. </p>";
2991+
2992+ html_print_header ();
2993+
2994+ html_print_summary ();
2995+
2996+ printf ("<h2><a name=\"SCANNERS\">Scanners</a></h2>\n");
2997+ html_backends_split_table (type_scanner);
2998+
2999+ printf ("<h2><a name=\"STILL\">Still Cameras</a></h2>\n");
3000+ html_backends_split_table (type_stillcam);
3001+
3002+ printf ("<h2><a name=\"VIDEO\">Video Cameras</a></h2>\n");
3003+ html_backends_split_table (type_vidcam);
3004+
3005+ printf ("<h2><a name=\"API\">APIs</a></h2>\n");
3006+ html_backends_split_table (type_api);
3007+
3008+ printf ("<h2><a name=\"META\">Meta Backends</a></h2>\n");
3009+ html_backends_split_table (type_meta);
3010+
3011+ printf ("<h3><a name=\"legend\">Legend:</a></h3>\n" "<blockquote><dl>\n");
3012+
3013+ html_print_legend_backend ();
3014+ html_print_legend_link ();
3015+ html_print_legend_manual ();
3016+ html_print_legend_comment ();
3017+ html_print_legend_manufacturer ();
3018+ html_print_legend_model ();
3019+ html_print_legend_interface ();
3020+ html_print_legend_usbid ();
3021+ html_print_legend_status ();
3022+ html_print_legend_description ();
3023+
3024+ printf ("</dl></blockquote>\n");
3025+
3026+ html_print_footer ();
3027+}
3028+
3029+/* Print the HTML page with one table of models per manufacturer */
3030+static void
3031+html_print_mfgs (void)
3032+{
3033+ if (!title)
3034+ title = "SANE: Supported Devices";
3035+
3036+ if (!intro)
3037+ intro = "<p> The following table summarizes the devices supported "
3038+ "by the latest version of sane-backends. </p>";
3039+
3040+ html_print_header ();
3041+
3042+ html_print_summary ();
3043+
3044+ printf ("<h2><a name=\"SCANNERS\">Scanners</a></h2>\n");
3045+ html_mfgs_table (type_scanner);
3046+
3047+ printf ("<h2><a name=\"STILL\">Still Cameras</a></h2>\n");
3048+ html_mfgs_table (type_stillcam);
3049+
3050+ printf ("<h2><a name=\"VIDEO\">Video Cameras</a></h2>\n");
3051+ html_mfgs_table (type_vidcam);
3052+
3053+ printf ("<h2><a name=\"API\">APIs</a></h2>\n");
3054+ html_backends_split_table (type_api);
3055+
3056+ printf ("<h2><a name=\"META\">Meta Backends</a></h2>\n");
3057+ html_backends_split_table (type_meta);
3058+
3059+ printf
3060+ ("<h3><a name=\"legend\">Legend:</a></h3>\n" "<blockquote>\n" "<dl>\n");
3061+
3062+ html_print_legend_model ();
3063+ html_print_legend_interface ();
3064+ html_print_legend_usbid ();
3065+ html_print_legend_status ();
3066+ html_print_legend_comment ();
3067+ html_print_legend_backend ();
3068+ html_print_legend_manual ();
3069+
3070+ html_print_legend_manufacturer ();
3071+ html_print_legend_description ();
3072+
3073+ printf ("</dl>\n" "</blockquote>\n");
3074+
3075+ html_print_footer ();
3076+}
3077+
3078+
3079+/* print statistics about supported devices */
3080+static void
3081+print_statistics_per_type (device_type dev_type)
3082+{
3083+ statistics_type num = {0, 0, 0, 0, 0, 0, 0};
3084+
3085+ calculate_statistics_per_type (dev_type, num);
3086+
3087+ printf (" Total: %4d\n",
3088+ num[status_minimal] + num[status_basic] + num[status_good] +
3089+ num[status_complete] + num[status_untested] + num[status_untested] +
3090+ num[status_unsupported]);
3091+ if (dev_type == type_scanner || dev_type == type_stillcam
3092+ || dev_type == type_vidcam)
3093+ {
3094+ printf (" Supported: %4d (complete: %d, good: %d, basic: %d, "
3095+ "minimal: %d)\n",
3096+ num[status_minimal] + num[status_basic] + num[status_good] +
3097+ num[status_complete], num[status_complete], num[status_good],
3098+ num[status_basic], num[status_minimal]);
3099+ printf (" Untested: %4d\n", num[status_untested]);
3100+ printf (" Unsupported: %4d\n", num[status_unsupported]);
3101+ }
3102+}
3103+
3104+static void
3105+print_statistics (void)
3106+{
3107+ printf ("Number of known devices:\n");
3108+ printf ("Scanners:\n");
3109+ print_statistics_per_type (type_scanner);
3110+ printf ("Still cameras:\n");
3111+ print_statistics_per_type (type_stillcam);
3112+ printf ("Video cameras:\n");
3113+ print_statistics_per_type (type_vidcam);
3114+ printf ("Meta backends:\n");
3115+ print_statistics_per_type (type_meta);
3116+ printf ("API backends:\n");
3117+ print_statistics_per_type (type_api);
3118+}
3119+
3120+static usbid_type *
3121+create_usbid (char *manufacturer, char *model,
3122+ char *usb_vendor_id, char *usb_product_id)
3123+{
3124+ usbid_type * usbid = calloc (1, sizeof (usbid_type));
3125+
3126+ usbid->usb_vendor_id = strdup (usb_vendor_id);
3127+ usbid->usb_product_id = strdup (usb_product_id);
3128+ usbid->name = calloc (1, sizeof (manufacturer_model_type));
3129+ usbid->name->name = calloc (1, strlen (manufacturer) + strlen (model) + 3);
3130+ sprintf (usbid->name->name, "%s %s", manufacturer, model);
3131+ usbid->name->next = 0;
3132+ usbid->next = 0;
3133+ DBG_DBG ("New USB ids: %s/%s (%s %s)\n", usb_vendor_id, usb_product_id,
3134+ manufacturer, model);
3135+ return usbid;
3136+}
3137+
3138+static scsiid_type *
3139+create_scsiid (char *manufacturer, char *model,
3140+ char *scsi_vendor_id, char *scsi_product_id, SANE_Bool is_processor)
3141+{
3142+ scsiid_type * scsiid = calloc (1, sizeof (scsiid_type));
3143+
3144+ scsiid->scsi_vendor_id = strdup (scsi_vendor_id);
3145+ scsiid->scsi_product_id = strdup (scsi_product_id);
3146+ scsiid->is_processor = is_processor;
3147+ scsiid->name = calloc (1, sizeof (manufacturer_model_type));
3148+ scsiid->name->name = calloc (1, strlen (manufacturer) + strlen (model) + 3);
3149+ sprintf (scsiid->name->name, "%s %s", manufacturer, model);
3150+ scsiid->name->next = 0;
3151+ scsiid->next = 0;
3152+ DBG_DBG ("New SCSI ids: %s/%s (%s %s)\n", scsi_vendor_id, scsi_product_id,
3153+ manufacturer, model);
3154+ return scsiid;
3155+}
3156+
3157+static usbid_type *
3158+add_usbid (usbid_type *first_usbid, char *manufacturer, char *model,
3159+ char *usb_vendor_id, char *usb_product_id)
3160+{
3161+ usbid_type *usbid = first_usbid;
3162+ usbid_type *prev_usbid = 0, *tmp_usbid = 0;
3163+
3164+ if (!first_usbid)
3165+ first_usbid = create_usbid (manufacturer, model, usb_vendor_id, usb_product_id);
3166+ else
3167+ {
3168+ while (usbid)
3169+ {
3170+ if (strcmp (usb_vendor_id, usbid->usb_vendor_id) == 0 &&
3171+ strcmp (usb_product_id, usbid->usb_product_id) == 0)
3172+ {
3173+ manufacturer_model_type *man_mod = usbid->name;
3174+
3175+ while (man_mod->next)
3176+ man_mod = man_mod->next;
3177+ man_mod->next = malloc (sizeof (manufacturer_model_type));
3178+ man_mod->next->name = malloc (strlen (manufacturer) + strlen (model) + 3);
3179+ sprintf (man_mod->next->name, "%s %s", manufacturer, model);
3180+ man_mod->next->next = 0;
3181+ DBG_DBG ("Added manufacturer/model %s %s to USB ids %s/%s\n", manufacturer, model,
3182+ usb_vendor_id, usb_product_id);
3183+ break;
3184+ }
3185+ if (strcmp (usb_vendor_id, usbid->usb_vendor_id) < 0 ||
3186+ (strcmp (usb_vendor_id, usbid->usb_vendor_id) == 0 &&
3187+ strcmp (usb_product_id, usbid->usb_product_id) < 0))
3188+ {
3189+
3190+ tmp_usbid = create_usbid (manufacturer, model, usb_vendor_id, usb_product_id);
3191+ tmp_usbid->next = usbid;
3192+ if (prev_usbid)
3193+ prev_usbid->next = tmp_usbid;
3194+ else
3195+ first_usbid = tmp_usbid;
3196+ break;
3197+ }
3198+ prev_usbid = usbid;
3199+ usbid = usbid->next;
3200+ }
3201+ if (!usbid)
3202+ {
3203+ prev_usbid->next = create_usbid (manufacturer, model, usb_vendor_id, usb_product_id);
3204+ usbid = prev_usbid->next;
3205+ }
3206+ }
3207+ return first_usbid;
3208+}
3209+
3210+static scsiid_type *
3211+add_scsiid (scsiid_type *first_scsiid, char *manufacturer, char *model,
3212+ char *scsi_vendor_id, char *scsi_product_id, SANE_Bool is_processor)
3213+{
3214+ scsiid_type *scsiid = first_scsiid;
3215+ scsiid_type *prev_scsiid = 0, *tmp_scsiid = 0;
3216+
3217+ if (!first_scsiid)
3218+ first_scsiid = create_scsiid (manufacturer, model, scsi_vendor_id, scsi_product_id, is_processor);
3219+ else
3220+ {
3221+ while (scsiid)
3222+ {
3223+ if (strcmp (scsi_vendor_id, scsiid->scsi_vendor_id) == 0 &&
3224+ strcmp (scsi_product_id, scsiid->scsi_product_id) == 0)
3225+ {
3226+ manufacturer_model_type *man_mod = scsiid->name;
3227+
3228+ while (man_mod->next)
3229+ man_mod = man_mod->next;
3230+ man_mod->next = malloc (sizeof (manufacturer_model_type));
3231+ man_mod->next->name = malloc (strlen (manufacturer) + strlen (model) + 3);
3232+ sprintf (man_mod->next->name, "%s %s", manufacturer, model);
3233+ man_mod->next->next = 0;
3234+ DBG_DBG ("Added manufacturer/model %s %s to SCSI ids %s/%s\n", manufacturer, model,
3235+ scsi_vendor_id, scsi_product_id);
3236+ break;
3237+ }
3238+ if (strcmp (scsi_vendor_id, scsiid->scsi_vendor_id) < 0 ||
3239+ (strcmp (scsi_vendor_id, scsiid->scsi_vendor_id) == 0 &&
3240+ strcmp (scsi_product_id, scsiid->scsi_product_id) < 0))
3241+ {
3242+
3243+ tmp_scsiid = create_scsiid (manufacturer, model, scsi_vendor_id, scsi_product_id, is_processor);
3244+ tmp_scsiid->next = scsiid;
3245+ if (prev_scsiid)
3246+ prev_scsiid->next = tmp_scsiid;
3247+ else
3248+ first_scsiid = tmp_scsiid;
3249+ break;
3250+ }
3251+ prev_scsiid = scsiid;
3252+ scsiid = scsiid->next;
3253+ }
3254+ if (!scsiid)
3255+ {
3256+ prev_scsiid->next = create_scsiid (manufacturer, model, scsi_vendor_id, scsi_product_id, is_processor);
3257+ scsiid = prev_scsiid->next;
3258+ }
3259+ }
3260+ return first_scsiid;
3261+}
3262+
3263+static usbid_type *
3264+create_usbids_table (void)
3265+{
3266+ backend_entry *be;
3267+ usbid_type *first_usbid = NULL;
3268+
3269+ if (!first_backend)
3270+ return NULL;
3271+
3272+ for (be = first_backend; be; be = be->next)
3273+ {
3274+ type_entry *type;
3275+
3276+ if (!be->type)
3277+ continue;
3278+
3279+ for (type = be->type; type; type = type->next)
3280+ {
3281+ mfg_entry *mfg;
3282+
3283+ if (!type->mfg)
3284+ continue;
3285+
3286+ for (mfg = type->mfg; mfg; mfg = mfg->next)
3287+ {
3288+ model_entry *model;
3289+
3290+ if (!mfg->model)
3291+ continue;
3292+
3293+ for (model = mfg->model; model; model = model->next)
3294+ {
3295+ if ((model->status == status_unsupported)
3296+ || (model->status == status_unknown))
3297+ continue;
3298+
3299+ if (model->usb_vendor_id && model->usb_product_id)
3300+ {
3301+ first_usbid = add_usbid (first_usbid, mfg->name,
3302+ model->name,
3303+ model->usb_vendor_id,
3304+ model->usb_product_id);
3305+ }
3306+ } /* for (model) */
3307+ } /* for (mfg) */
3308+ } /* for (type) */
3309+ } /* for (be) */
3310+
3311+ return first_usbid;
3312+}
3313+
3314+static scsiid_type *
3315+create_scsiids_table (void)
3316+{
3317+ backend_entry *be;
3318+ scsiid_type *first_scsiid = NULL;
3319+
3320+ if (!first_backend)
3321+ return NULL;
3322+
3323+ for (be = first_backend; be; be = be->next)
3324+ {
3325+ type_entry *type;
3326+
3327+ if (!be->type)
3328+ continue;
3329+
3330+ for (type = be->type; type; type = type->next)
3331+ {
3332+ mfg_entry *mfg;
3333+
3334+ if (!type->mfg)
3335+ continue;
3336+
3337+ for (mfg = type->mfg; mfg; mfg = mfg->next)
3338+ {
3339+ model_entry *model;
3340+
3341+ if (!mfg->model)
3342+ continue;
3343+
3344+ for (model = mfg->model; model; model = model->next)
3345+ {
3346+ if ((model->status == status_unsupported)
3347+ || (model->status == status_unknown))
3348+ continue;
3349+
3350+ if (model->scsi_vendor_id && model->scsi_product_id)
3351+ {
3352+ first_scsiid = add_scsiid (first_scsiid, mfg->name,
3353+ model->name,
3354+ model->scsi_vendor_id,
3355+ model->scsi_product_id,
3356+ model->scsi_is_processor);
3357+ }
3358+ } /* for (model) */
3359+ } /* for (mfg) */
3360+ } /* for (type) */
3361+ } /* for (be) */
3362+
3363+ return first_scsiid;
3364+}
3365+
3366+/* print USB usermap file to be used by the hotplug tools */
3367+static void
3368+print_usermap_header (void)
3369+{
3370+ time_t current_time = time (0);
3371+
3372+ printf
3373+ ("# This file was automatically created based on description files (*.desc)\n"
3374+ "# by sane-desc %s from %s on %s"
3375+ "#\n"
3376+ ,
3377+ SANE_DESC_VERSION, PACKAGE_STRING, asctime (localtime (&current_time)));
3378+
3379+ printf
3380+ ("# The entries below are used to detect a USB device and change owner\n"
3381+ "# and permissions on the \"device node\" used by libusb.\n"
3382+ "#\n"
3383+ "# The 0x0003 match flag means the device is matched by its vendor and\n"
3384+ "# product IDs.\n"
3385+ "#\n"
3386+ "# Sample entry (replace 0xVVVV and 0xPPPP with vendor ID and product ID\n"
3387+ "# respectively):\n"
3388+ "#\n"
3389+ );
3390+
3391+ printf
3392+ ("# libusbscanner 0x0003 0xVVVV 0xPPPP 0x0000 0x0000 0x00 0x00 0x00 0x00 "
3393+ "0x00 0x00 0x00000000\n"
3394+ "# usb module match_flags idVendor idProduct bcdDevice_lo bcdDevice_hi "
3395+ "bDeviceClass bDeviceSubClass bDeviceProtocol bInterfaceClass "
3396+ "bInterfaceSubClass bInterfaceProtocol driver_info\n"
3397+ "#\n"
3398+ );
3399+
3400+ printf
3401+ ("# If your scanner isn't listed below, you can add it as explained above.\n"
3402+ "#\n"
3403+ "# If your scanner is supported by some external backend (brother, epkowa,\n"
3404+ "# hpaio, etc) please ask the author of the backend to provide proper\n"
3405+ "# device detection support for your OS\n"
3406+ "#\n"
3407+ "# If the scanner is supported by sane-backends, please mail the entry to\n"
3408+ "# the sane-devel mailing list (sane-devel@lists.alioth.debian.org).\n"
3409+ "#\n"
3410+ );
3411+
3412+}
3413+
3414+static void
3415+print_usermap (void)
3416+{
3417+ usbid_type *usbid = create_usbids_table ();
3418+
3419+ print_usermap_header ();
3420+ while (usbid)
3421+ {
3422+ manufacturer_model_type * name = usbid->name;
3423+
3424+ printf ("# ");
3425+ while (name)
3426+ {
3427+ if (name != usbid->name)
3428+ printf (" | ");
3429+ printf ("%s", name->name);
3430+ name = name->next;
3431+ }
3432+ printf ("\n");
3433+ printf ("libusbscanner 0x0003 %s %s ", usbid->usb_vendor_id,
3434+ usbid->usb_product_id);
3435+ printf ("0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000\n");
3436+ usbid = usbid->next;
3437+ }
3438+}
3439+
3440+/* print libsane.db file for hotplug-ng */
3441+static void
3442+print_db_header (void)
3443+{
3444+ time_t current_time = time (0);
3445+ printf ("# This file was automatically created based on description files (*.desc)\n"
3446+ "# by sane-desc %s from %s on %s",
3447+ SANE_DESC_VERSION, PACKAGE_STRING, asctime (localtime (&current_time)));
3448+ printf
3449+ ("#\n"
3450+ "# The entries below are used to detect a USB device when it's plugged in\n"
3451+ "# and then run a script to change the ownership and\n"
3452+ "# permissions on the \"device node\" used by libusb.\n"
3453+ "# Sample entry (replace 0xVVVV and 0xPPPP with vendor ID and product ID\n"
3454+ "# respectively):\n");
3455+ printf
3456+ ("#\n"
3457+ "# 0xVVVV<tab>0xPPPP<tab>%s:%s<tab>%s<tab>[/usr/local/bin/foo.sh]\n"
3458+ "# Fields:\n"
3459+ "# vendor ID\n"
3460+ "# product ID\n"
3461+ "# ownership (user:group)\n"
3462+ "# permissions\n"
3463+ "# path of an optional script to run (it can be omitted)\n"
3464+ "#\n"
3465+ , DEVOWNER, DEVGROUP, DEVMODE);
3466+
3467+ printf
3468+ ("# If your scanner isn't listed below, you can add it as explained above.\n"
3469+ "#\n"
3470+ "# If your scanner is supported by some external backend (brother, epkowa,\n"
3471+ "# hpaio, etc) please ask the author of the backend to provide proper\n"
3472+ "# device detection support for your OS\n"
3473+ "#\n"
3474+ "# If the scanner is supported by sane-backends, please mail the entry to\n"
3475+ "# the sane-devel mailing list (sane-devel@lists.alioth.debian.org).\n"
3476+ "#\n"
3477+ );
3478+}
3479+
3480+static void
3481+print_db (void)
3482+{
3483+ usbid_type *usbid = create_usbids_table ();
3484+
3485+ print_db_header ();
3486+ while (usbid)
3487+ {
3488+ manufacturer_model_type * name = usbid->name;
3489+
3490+ printf ("# ");
3491+ while (name)
3492+ {
3493+ if (name != usbid->name)
3494+ printf (" | ");
3495+ printf ("%s", name->name);
3496+ name = name->next;
3497+ }
3498+ printf ("\n");
3499+ printf ("%s\t%s\t%s:%s\t%s\t\n", usbid->usb_vendor_id,
3500+ usbid->usb_product_id, DEVOWNER, DEVGROUP, DEVMODE);
3501+ usbid = usbid->next;
3502+ }
3503+}
3504+
3505+/* print libsane.rules for Linux udev */
3506+static void
3507+print_udev_header (void)
3508+{
3509+ time_t current_time = time (0);
3510+ printf ("# This file was automatically created based on description files (*.desc)\n"
3511+ "# by sane-desc %s from %s on %s",
3512+ SANE_DESC_VERSION, PACKAGE_STRING, asctime (localtime (&current_time)));
3513+
3514+ printf
3515+ ("#\n"
3516+ "# udev rules file for supported USB and SCSI devices\n"
3517+ "#\n"
3518+ "# The SCSI device support is very basic and includes only\n"
3519+ "# scanners that mark themselves as type \"scanner\" or\n"
3520+ "# SCSI-scanners from HP and other vendors that are entitled \"processor\"\n"
3521+ "# but are treated accordingly.\n"
3522+ "#\n");
3523+ printf
3524+ ("# To add a USB device, add a rule to the list below between the\n"
3525+ "# LABEL=\"libsane_usb_rules_begin\" and LABEL=\"libsane_usb_rules_end\" lines.\n"
3526+ "#\n"
3527+ "# To run a script when your device is plugged in, add RUN+=\"/path/to/script\"\n"
3528+ "# to the appropriate rule.\n"
3529+ "#\n"
3530+ );
3531+ printf
3532+ ("# If your scanner isn't listed below, you can add it as explained above.\n"
3533+ "#\n"
3534+ "# If your scanner is supported by some external backend (brother, epkowa,\n"
3535+ "# hpaio, etc) please ask the author of the backend to provide proper\n"
3536+ "# device detection support for your OS\n"
3537+ "#\n"
3538+ "# If the scanner is supported by sane-backends, please mail the entry to\n"
3539+ "# the sane-devel mailing list (sane-devel@lists.alioth.debian.org).\n"
3540+ "#\n"
3541+ );
3542+}
3543+
3544+static void
3545+print_udev (void)
3546+{
3547+ usbid_type *usbid = create_usbids_table ();
3548+ scsiid_type *scsiid = create_scsiids_table ();
3549+ int i;
3550+
3551+ print_udev_header ();
3552+ printf("ACTION!=\"add\", GOTO=\"libsane_rules_end\"\n"
3553+ "ENV{DEVTYPE}==\"usb_device\", GOTO=\"libsane_create_usb_dev\"\n"
3554+ "SUBSYSTEMS==\"scsi\", GOTO=\"libsane_scsi_rules_begin\"\n"
3555+ "SUBSYSTEM==\"usb_device\", GOTO=\"libsane_usb_rules_begin\"\n"
3556+ "SUBSYSTEM!=\"usb_device\", GOTO=\"libsane_usb_rules_end\"\n"
3557+ "\n");
3558+
3559+ printf("# Kernel >= 2.6.22 jumps here\n"
3560+ "LABEL=\"libsane_create_usb_dev\"\n"
3561+ "\n");
3562+
3563+ printf("# For Linux >= 2.6.22 without CONFIG_USB_DEVICE_CLASS=y\n"
3564+ "# If the following rule does not exist on your system yet, uncomment it\n"
3565+ "# ENV{DEVTYPE}==\"usb_device\", "
3566+ "MODE=\"0664\", OWNER=\"root\", GROUP=\"root\"\n"
3567+ "\n");
3568+
3569+ printf("# Kernel < 2.6.22 jumps here\n"
3570+ "LABEL=\"libsane_usb_rules_begin\"\n"
3571+ "\n");
3572+
3573+ while (usbid)
3574+ {
3575+ manufacturer_model_type * name = usbid->name;
3576+
3577+ i = 0;
3578+ printf ("# ");
3579+ while (name)
3580+ {
3581+ if ((name != usbid->name) && (i > 0))
3582+ printf (" | ");
3583+ printf ("%s", name->name);
3584+ name = name->next;
3585+
3586+ i++;
3587+
3588+ /*
3589+ * Limit the number of model names on the same line to 3,
3590+ * as udev cannot handle very long lines and prints a warning
3591+ * message while loading the rules files.
3592+ */
3593+ if ((i == 3) && (name != NULL))
3594+ {
3595+ printf("\n# ");
3596+ i = 0;
3597+ }
3598+ }
3599+ printf ("\n");
3600+
3601+ if (mode == output_mode_udevacl)
3602+ printf ("ATTRS{idVendor}==\"%s\", ATTRS{idProduct}==\"%s\", ENV{libsane_matched}=\"yes\"\n",
3603+ usbid->usb_vendor_id + 2, usbid->usb_product_id + 2);
3604+ else
3605+ printf ("ATTRS{idVendor}==\"%s\", ATTRS{idProduct}==\"%s\", MODE=\"%s\", GROUP=\"%s\", ENV{libsane_matched}=\"yes\"\n",
3606+ usbid->usb_vendor_id + 2, usbid->usb_product_id + 2, DEVMODE, DEVGROUP);
3607+
3608+ usbid = usbid->next;
3609+ }
3610+
3611+ printf("\n# The following rule will disable USB autosuspend for the device\n");
3612+ printf("ENV{libsane_matched}==\"yes\", RUN+=\"/bin/sh -c 'if test -e /sys/$env{DEVPATH}/power/control; then echo on > /sys/$env{DEVPATH}/power/control; elif test -e /sys/$env{DEVPATH}/power/level; then echo on > /sys/$env{DEVPATH}/power/level; fi'\"\n");
3613+
3614+ printf ("\nLABEL=\"libsane_usb_rules_end\"\n\n");
3615+
3616+ printf ("SUBSYSTEMS==\"scsi\", GOTO=\"libsane_scsi_rules_begin\"\n");
3617+ printf ("GOTO=\"libsane_scsi_rules_end\"\n\n");
3618+ printf ("LABEL=\"libsane_scsi_rules_begin\"\n");
3619+ printf ("# Generic: SCSI device type 6 indicates a scanner\n");
3620+
3621+ if (mode == output_mode_udevacl)
3622+ printf ("KERNEL==\"sg[0-9]*\", ATTRS{type}==\"6\", ENV{libsane_matched}=\"yes\"\n");
3623+ else
3624+ printf ("KERNEL==\"sg[0-9]*\", ATTRS{type}==\"6\", MODE=\"%s\", GROUP=\"%s\", ENV{libsane_matched}=\"yes\"\n", DEVMODE, DEVGROUP);
3625+
3626+
3627+ printf ("# Some scanners advertise themselves as SCSI device type 3\n");
3628+
3629+ printf ("# Wildcard: for some Epson SCSI scanners\n");
3630+ if (mode == output_mode_udevacl)
3631+ printf ("KERNEL==\"sg[0-9]*\", ATTRS{type}==\"3\", ATTRS{vendor}==\"EPSON\", ATTRS{model}==\"SCANNER*\", ENV{libsane_matched}=\"yes\"\n");
3632+ else
3633+ printf ("KERNEL==\"sg[0-9]*\", ATTRS{type}==\"3\", ATTRS{vendor}==\"EPSON\", ATTRS{model}==\"SCANNER*\", MODE=\"%s\", GROUP=\"%s\", ENV{libsane_matched}=\"yes\"\n",
3634+ DEVMODE, DEVGROUP);
3635+
3636+ while (scsiid)
3637+ {
3638+ manufacturer_model_type * name = scsiid->name;
3639+
3640+ if (!scsiid->is_processor)
3641+ {
3642+ scsiid = scsiid->next;
3643+ continue;
3644+ }
3645+
3646+ /* Wildcard for Epson scanners: vendor = EPSON, product = SCANNER* */
3647+ if ((strcmp(scsiid->scsi_vendor_id, "EPSON") == 0)
3648+ && (strncmp(scsiid->scsi_product_id, "SCANNER", 7) == 0))
3649+ {
3650+ scsiid = scsiid->next;
3651+ continue;
3652+ }
3653+
3654+ i = 0;
3655+ printf ("# ");
3656+ while (name)
3657+ {
3658+ if ((name != scsiid->name) && (i > 0))
3659+ printf (" | ");
3660+ printf ("%s", name->name);
3661+ name = name->next;
3662+
3663+ i++;
3664+
3665+ /*
3666+ * Limit the number of model names on the same line to 3,
3667+ * as udev cannot handle very long lines and prints a warning
3668+ * message while loading the rules files.
3669+ */
3670+ if ((i == 3) && (name != NULL))
3671+ {
3672+ printf("\n# ");
3673+ i = 0;
3674+ }
3675+ }
3676+ printf ("\n");
3677+
3678+ if (mode == output_mode_udevacl)
3679+ printf ("KERNEL==\"sg[0-9]*\", ATTRS{type}==\"3\", ATTRS{vendor}==\"%s\", ATTRS{model}==\"%s\", ENV{libsane_matched}=\"yes\"\n",
3680+ scsiid->scsi_vendor_id, scsiid->scsi_product_id);
3681+ else
3682+ printf ("KERNEL==\"sg[0-9]*\", ATTRS{type}==\"3\", ATTRS{vendor}==\"%s\", ATTRS{model}==\"%s\", MODE=\"%s\", GROUP=\"%s\", ENV{libsane_matched}=\"yes\"\n",
3683+ scsiid->scsi_vendor_id, scsiid->scsi_product_id, DEVMODE, DEVGROUP);
3684+
3685+ scsiid = scsiid->next;
3686+ }
3687+ printf ("LABEL=\"libsane_scsi_rules_end\"\n");
3688+
3689+ if (mode == output_mode_udevacl)
3690+ printf("\nENV{libsane_matched}==\"yes\", RUN+=\"/bin/setfacl -m g:%s:rw $env{DEVNAME}\"\n", DEVGROUP);
3691+ else
3692+ printf ("\nENV{libsane_matched}==\"yes\", MODE=\"664\", GROUP=\"scanner\"\n");
3693+
3694+ printf ("\nLABEL=\"libsane_rules_end\"\n");
3695+}
3696+
3697+
3698+/* print libsane.rules for Linux udev */
3699+static void
3700+print_udevhwdb_header (void)
3701+{
3702+ time_t current_time = time (0);
3703+ printf ("# This file was automatically created based on description files (*.desc)\n"
3704+ "# by sane-desc %s from %s on %s",
3705+ SANE_DESC_VERSION, PACKAGE_STRING, asctime (localtime (&current_time)));
3706+
3707+ printf
3708+ ("#\n"
3709+ "# udev rules file for supported USB and SCSI devices\n"
3710+ "#\n"
3711+ "# For the list of supported USB devices see /usr/lib/udev/hwdb.d/20-sane.hwdb\n"
3712+ "#\n"
3713+ "# The SCSI device support is very basic and includes only\n"
3714+ "# scanners that mark themselves as type \"scanner\" or\n"
3715+ "# SCSI-scanners from HP and other vendors that are entitled \"processor\"\n"
3716+ "# but are treated accordingly.\n"
3717+ "#\n");
3718+ printf
3719+ ("# If your SCSI scanner isn't listed below, you can add it to a new rules\n"
3720+ "# file under /etc/udev/rules.d/.\n"
3721+ "#\n"
3722+ "# If your scanner is supported by some external backend (brother, epkowa,\n"
3723+ "# hpaio, etc) please ask the author of the backend to provide proper\n"
3724+ "# device detection support for your OS\n"
3725+ "#\n"
3726+ "# If the scanner is supported by sane-backends, please mail the entry to\n"
3727+ "# the sane-devel mailing list (sane-devel@lists.alioth.debian.org).\n"
3728+ "#\n"
3729+ );
3730+}
3731+
3732+static void
3733+print_udevhwdb (void)
3734+{
3735+ scsiid_type *scsiid = create_scsiids_table ();
3736+ int i;
3737+
3738+ print_udevhwdb_header ();
3739+ printf("ACTION!=\"add\", GOTO=\"libsane_rules_end\"\n\n");
3740+
3741+ printf("# The following rule will disable USB autosuspend for the device\n");
3742+ printf("ENV{DEVTYPE}==\"usb_device\", ENV{libsane_matched}==\"yes\", TEST==\"power/control\", ATTR{power/control}=\"on\"\n\n");
3743+
3744+ printf ("SUBSYSTEMS==\"scsi\", GOTO=\"libsane_scsi_rules_begin\"\n");
3745+ printf ("GOTO=\"libsane_rules_end\"\n\n");
3746+ printf ("LABEL=\"libsane_scsi_rules_begin\"\n");
3747+ printf ("KERNEL!=\"sg[0-9]*\", GOTO=\"libsane_rules_end\"\n\n");
3748+
3749+ printf ("# Generic: SCSI device type 6 indicates a scanner\n");
3750+ printf ("ATTRS{type}==\"6\", ENV{libsane_matched}=\"yes\"\n\n");
3751+
3752+ printf ("# Some scanners advertise themselves as SCSI device type 3\n\n");
3753+
3754+ printf ("# Wildcard: for some Epson SCSI scanners\n");
3755+ printf ("ATTRS{type}==\"3\", ATTRS{vendor}==\"EPSON\", ATTRS{model}==\"SCANNER*\", ENV{libsane_matched}=\"yes\"\n\n");
3756+
3757+ while (scsiid)
3758+ {
3759+ manufacturer_model_type * name = scsiid->name;
3760+
3761+ if (!scsiid->is_processor)
3762+ {
3763+ scsiid = scsiid->next;
3764+ continue;
3765+ }
3766+
3767+ /* Wildcard for Epson scanners: vendor = EPSON, product = SCANNER* */
3768+ if ((strcmp(scsiid->scsi_vendor_id, "EPSON") == 0)
3769+ && (strncmp(scsiid->scsi_product_id, "SCANNER", 7) == 0))
3770+ {
3771+ scsiid = scsiid->next;
3772+ continue;
3773+ }
3774+
3775+ i = 0;
3776+ printf ("# ");
3777+ while (name)
3778+ {
3779+ if ((name != scsiid->name) && (i > 0))
3780+ printf (" | ");
3781+ printf ("%s", name->name);
3782+ name = name->next;
3783+
3784+ i++;
3785+
3786+ /*
3787+ * Limit the number of model names on the same line to 3,
3788+ * as udev cannot handle very long lines and prints a warning
3789+ * message while loading the rules files.
3790+ */
3791+ if ((i == 3) && (name != NULL))
3792+ {
3793+ printf("\n# ");
3794+ i = 0;
3795+ }
3796+ }
3797+ printf ("\n");
3798+
3799+ printf ("ATTRS{type}==\"3\", ATTRS{vendor}==\"%s\", ATTRS{model}==\"%s\", ENV{libsane_matched}=\"yes\"\n\n",
3800+ scsiid->scsi_vendor_id, scsiid->scsi_product_id);
3801+
3802+ scsiid = scsiid->next;
3803+ }
3804+
3805+ printf ("\nLABEL=\"libsane_rules_end\"\n");
3806+}
3807+
3808+/* print /usr/lib/udev/hwdb.d/20-sane.conf for Linux hwdb */
3809+static void
3810+print_hwdb_header (void)
3811+{
3812+ time_t current_time = time (0);
3813+ printf ("# This file was automatically created based on description files (*.desc)\n"
3814+ "# by sane-desc %s from %s on %s",
3815+ SANE_DESC_VERSION, PACKAGE_STRING, asctime (localtime (&current_time)));
3816+
3817+ printf
3818+ ("#\n"
3819+ "# hwdb file for supported USB devices\n"
3820+ "#\n");
3821+ printf
3822+ ("# If your scanner isn't listed below, you can add it to a new hwdb file\n"
3823+ "# under /etc/udev/hwdb.d/.\n"
3824+ "#\n"
3825+ "# If your scanner is supported by some external backend (brother, epkowa,\n"
3826+ "# hpaio, etc) please ask the author of the backend to provide proper\n"
3827+ "# device detection support for your OS\n"
3828+ "#\n"
3829+ "# If the scanner is supported by sane-backends, please mail the entry to\n"
3830+ "# the sane-devel mailing list (sane-devel@lists.alioth.debian.org).\n"
3831+ "#\n"
3832+ );
3833+}
3834+
3835+static void
3836+print_hwdb (void)
3837+{
3838+ usbid_type *usbid = create_usbids_table ();
3839+ char *vendor_id;
3840+ char *product_id;
3841+ int i,j;
3842+
3843+ print_hwdb_header ();
3844+
3845+ while (usbid)
3846+ {
3847+ manufacturer_model_type * name = usbid->name;
3848+
3849+ i = 0;
3850+ printf ("# ");
3851+ while (name)
3852+ {
3853+ if ((name != usbid->name) && (i > 0))
3854+ printf (" | ");
3855+ printf ("%s", name->name);
3856+ name = name->next;
3857+
3858+ i++;
3859+
3860+ /*
3861+ * Limit the number of model names on the same line to 3,
3862+ * as udev cannot handle very long lines and prints a warning
3863+ * message while loading the rules files.
3864+ */
3865+ if ((i == 3) && (name != NULL))
3866+ {
3867+ printf("\n# ");
3868+ i = 0;
3869+ }
3870+ }
3871+ printf ("\n");
3872+
3873+ vendor_id = strdup(usbid->usb_vendor_id + 2);
3874+ product_id = strdup(usbid->usb_product_id + 2);
3875+
3876+ for(j = 0; j < 4; j++) {
3877+ vendor_id[j] = toupper(vendor_id[j]);
3878+ product_id[j] = toupper(product_id[j]);
3879+ }
3880+
3881+ printf ("usb:v%sp%s*\n libsane_matched=yes\n\n",
3882+ vendor_id, product_id);
3883+
3884+ free(vendor_id);
3885+ free(product_id);
3886+
3887+ usbid = usbid->next;
3888+ }
3889+}
3890+
3891+static void
3892+print_plist (void)
3893+{
3894+ usbid_type *usbid = create_usbids_table ();
3895+
3896+ printf ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
3897+ printf ("<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n");
3898+ printf ("<plist version=\"1.0\">\n");
3899+ printf ("<dict>\n");
3900+ printf ("\t<key>device info version</key>\n");
3901+ printf ("\t<string>2.0</string>\n");
3902+ printf ("\t<key>usb</key>\n");
3903+ printf ("\t<dict>\n");
3904+ printf ("\t\t<key>IOUSBDevice</key>\n");
3905+ printf ("\t\t<array>\n");
3906+ while (usbid)
3907+ {
3908+ printf ("\t\t\t<dict>\n");
3909+ printf ("\t\t\t\t<key>device type</key>\n");
3910+ printf ("\t\t\t\t<string>scanner</string>\n");
3911+ printf ("\t\t\t\t<key>product</key>\n");
3912+ printf ("\t\t\t\t<string>%s</string>\n", usbid->usb_product_id);
3913+ printf ("\t\t\t\t<key>vendor</key>\n");
3914+ printf ("\t\t\t\t<string>%s</string>\n", usbid->usb_vendor_id);
3915+ printf ("\t\t\t</dict>\n");
3916+ usbid = usbid->next;
3917+ }
3918+ printf ("\t\t</array>\n");
3919+ printf ("\t</dict>\n");
3920+ printf ("</dict>\n");
3921+ printf ("</plist>\n");
3922+}
3923+
3924+
3925+static void
3926+print_hal (int new)
3927+{
3928+ int i;
3929+ SANE_Bool in_match;
3930+ char *last_vendor;
3931+ scsiid_type *scsiid = create_scsiids_table ();
3932+ usbid_type *usbid = create_usbids_table ();
3933+
3934+ printf ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
3935+ printf ("<deviceinfo version=\"0.2\">\n");
3936+ printf (" <device>\n");
3937+ printf (" <!-- SCSI-SUBSYSTEM -->\n");
3938+ printf (" <match key=\"info.category\" string=\"scsi_generic\">\n");
3939+ printf (" <!-- Some SCSI Scanners announce themselves \"processor\" -->\n");
3940+ printf (" <match key=\"@info.parent:scsi.type\" string=\"processor\">\n");
3941+
3942+ last_vendor = "";
3943+ in_match = SANE_FALSE;
3944+ while (scsiid)
3945+ {
3946+ manufacturer_model_type * name = scsiid->name;
3947+
3948+ if (!scsiid->is_processor)
3949+ {
3950+ scsiid = scsiid->next;
3951+ continue;
3952+ }
3953+
3954+ if (strcmp(last_vendor, scsiid->scsi_vendor_id) != 0)
3955+ {
3956+ if (in_match)
3957+ printf (" </match>\n");
3958+
3959+ printf (" <match key=\"@info.parent:scsi.vendor\" string=\"%s\">\n", scsiid->scsi_vendor_id);
3960+ last_vendor = scsiid->scsi_vendor_id;
3961+ in_match = SANE_TRUE;
3962+ }
3963+
3964+ printf (" <!-- SCSI Scanner ");
3965+ while (name)
3966+ {
3967+ if (name != scsiid->name)
3968+ printf (" | ");
3969+ printf ("\"%s\"", name->name);
3970+ name = name->next;
3971+ }
3972+ printf (" -->\n");
3973+ printf (" <match key=\"@info.parent:scsi.model\" string=\"%s\">\n", scsiid->scsi_product_id);
3974+ printf (" <append key=\"info.capabilities\" type=\"strlist\">scanner</append>\n");
3975+ printf (" </match>\n");
3976+
3977+ scsiid = scsiid->next;
3978+ }
3979+
3980+ if (in_match)
3981+ printf (" </match>\n");
3982+
3983+ printf (" </match>\n");
3984+ printf (" </match>\n");
3985+ printf (" <!-- USB-SUBSYSTEM -->\n");
3986+
3987+ if (new)
3988+ printf (" <match key=\"info.subsystem\" string=\"usb\">\n");
3989+ else
3990+ printf (" <match key=\"info.bus\" string=\"usb\">\n");
3991+
3992+ last_vendor = "";
3993+ in_match = SANE_FALSE;
3994+ while (usbid)
3995+ {
3996+ manufacturer_model_type * name = usbid->name;
3997+
3998+ if (strcmp(last_vendor, usbid->usb_vendor_id) != 0)
3999+ {
4000+ if (in_match)
4001+ printf (" </match>\n");
4002+
4003+ printf (" <match key=\"usb.vendor_id\" int=\"%s\">\n", usbid->usb_vendor_id);
4004+ last_vendor = usbid->usb_vendor_id;
4005+ in_match = SANE_TRUE;
4006+ }
4007+
4008+ i = 0;
4009+ printf (" <!-- ");
4010+ while (name)
4011+ {
4012+ if ((name != usbid->name) && (i > 0))
4013+ printf (" | ");
4014+
4015+ printf ("%s", name->name);
4016+ name = name->next;
4017+ i++;
4018+
4019+ if ((i == 3) && (name != NULL))
4020+ {
4021+ printf("\n ");
4022+ i = 0;
4023+ }
4024+ }
4025+ printf (" -->\n");
4026+ printf (" <match key=\"usb.product_id\" int=\"%s\">\n", usbid->usb_product_id);
4027+ printf (" <append key=\"info.capabilities\" type=\"strlist\">scanner</append>\n");
4028+ printf (" <merge key=\"scanner.access_method\" type=\"string\">proprietary</merge>\n");
4029+ printf (" </match>\n");
4030+
4031+ usbid = usbid->next;
4032+ }
4033+
4034+ if (in_match)
4035+ printf (" </match>\n");
4036+
4037+ printf (" </match>\n");
4038+
4039+ printf (" </device>\n");
4040+ printf ("</deviceinfo>\n");
4041+}
4042+
4043+int
4044+main (int argc, char **argv)
4045+{
4046+ program_name = strrchr (argv[0], '/');
4047+ if (program_name)
4048+ ++program_name;
4049+ else
4050+ program_name = argv[0];
4051+
4052+ if (!get_options (argc, argv))
4053+ return 1;
4054+ if (!read_files ())
4055+ return 1;
4056+ switch (mode)
4057+ {
4058+ case output_mode_ascii:
4059+ ascii_print_backends ();
4060+ break;
4061+ case output_mode_xml:
4062+ xml_print_backends ();
4063+ break;
4064+ case output_mode_html_backends_split:
4065+ html_print_backends_split ();
4066+ break;
4067+ case output_mode_html_mfgs:
4068+ html_print_mfgs ();
4069+ break;
4070+ case output_mode_statistics:
4071+ print_statistics ();
4072+ break;
4073+ case output_mode_usermap:
4074+ print_usermap ();
4075+ break;
4076+ case output_mode_db:
4077+ print_db ();
4078+ break;
4079+ case output_mode_udev:
4080+ case output_mode_udevacl:
4081+ print_udev ();
4082+ break;
4083+ case output_mode_udevhwdb:
4084+ print_udevhwdb ();
4085+ break;
4086+ case output_mode_hwdb:
4087+ print_hwdb ();
4088+ break;
4089+ case output_mode_plist:
4090+ print_plist ();
4091+ break;
4092+ case output_mode_hal:
4093+ print_hal (0);
4094+ break;
4095+ case output_mode_halnew:
4096+ print_hal (1);
4097+ break;
4098+ default:
4099+ DBG_ERR ("Unknown output mode\n");
4100+ return 1;
4101+ }
4102+
4103+ return 0;
4104+}
4105
4106=== added directory '.pc/001-scanimage_manpage.patch'
4107=== added directory '.pc/001-scanimage_manpage.patch/doc'
4108=== added file '.pc/001-scanimage_manpage.patch/doc/scanimage.man'
4109--- .pc/001-scanimage_manpage.patch/doc/scanimage.man 1970-01-01 00:00:00 +0000
4110+++ .pc/001-scanimage_manpage.patch/doc/scanimage.man 2015-11-08 16:17:40 +0000
4111@@ -0,0 +1,482 @@
4112+.TH scanimage 1 "10 Jul 2008" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
4113+.IX scanimage
4114+.SH NAME
4115+scanimage \- scan an image
4116+.SH SYNOPSIS
4117+.B scanimage
4118+.RB [ \-d | \-\-device\-name
4119+.IR dev ]
4120+.RB [ \-\-format
4121+.IR format ]
4122+.RB [ \-i | \-\-icc\-profile
4123+.IR profile ]
4124+.RB [ \-L | \-\-list\-devices ]
4125+.RB [ \-f | \-\-formatted\-device\-list
4126+.IR format ]
4127+.RB [ \-b | \-\-batch
4128+.RI [= format ]]
4129+.RB [ \-\-batch\-start
4130+.IR start ]
4131+.RB [ \-\-batch\-count
4132+.IR count ]
4133+.RB [ \-\-batch\-increment
4134+.IR increment ]
4135+.RB [ \-\-batch\-double ]
4136+.RB [ \-\-accept\-md5\-only ]
4137+.RB [ \-p | \-\-progress ]
4138+.RB [ \-n | \-\-dont\-scan ]
4139+.RB [ \-T | \-\-test ]
4140+.RB [ \-A | \-\-all-options ]
4141+.RB [ \-h | \-\-help ]
4142+.RB [ \-v | \-\-verbose ]
4143+.RB [ \-B | \-\-buffer-size
4144+.RI [= size ]]
4145+.RB [ \-V | \-\-version ]
4146+.RI [ device\-specific\-options ]
4147+.SH DESCRIPTION
4148+.B scanimage
4149+is a command-line interface to control image acquisition devices such
4150+as flatbed scanners or cameras. The device is controlled via
4151+command-line options. After command-line processing,
4152+.B scanimage
4153+normally proceeds to acquire an image. The image data is written to
4154+standard output in one of the PNM (portable aNyMaP) formats (PBM for
4155+black-and-white images, PGM for grayscale images, and PPM for color
4156+images) or in TIFF (black-and-white, grayscale or color).
4157+.B scanimage
4158+accesses image acquisition devices through the
4159+.B SANE
4160+(Scanner Access Now Easy) interface and can thus support any device for which
4161+there exists a
4162+.B SANE
4163+backend (try
4164+.B apropos
4165+.I sane\-
4166+to get a list of available backends).
4167+
4168+.SH EXAMPLES
4169+To get a list of devices:
4170+
4171+ scanimage \-L
4172+
4173+To scan with default settings to the file image.pnm:
4174+
4175+ scanimage >image.pnm
4176+
4177+To scan 100x100 mm to the file image.tiff (\-x and \-y may not be available with
4178+all devices):
4179+
4180+ scanimage \-x 100 \-y 100 \-\-format=tiff >image.tiff
4181+
4182+To print all available options:
4183+
4184+ scanimage \-h
4185+
4186+.SH OPTIONS
4187+Parameters are separated by a blank from single-character options (e.g.
4188+\-d epson) and by a "=" from multi-character options (e.g. \-\-device\-name=epson).
4189+
4190+.PP
4191+The
4192+.B \-d
4193+or
4194+.B \-\-device\-name
4195+options must be followed by a
4196+.B SANE
4197+device-name like
4198+.RI ` epson:/dev/sg0 '
4199+or
4200+.RI ` hp:/dev/usbscanner0 '.
4201+A (partial) list of available devices can be obtained with the
4202+.B \-\-list\-devices
4203+option (see below). If no device-name is specified explicitly,
4204+.B scanimage
4205+reads a device-name from the environment variable
4206+.BR SANE_DEFAULT_DEVICE .
4207+If this variable is not set,
4208+.B scanimage
4209+will attempt to open the first available device.
4210+.PP
4211+The
4212+.B \-\-format
4213+.I format
4214+option selects how image data is written to standard output.
4215+.I format
4216+can be
4217+.B pnm
4218+or
4219+.BR tiff.
4220+If
4221+.B \-\-format
4222+is not used, PNM is written.
4223+.PP
4224+The
4225+.B \-i
4226+or
4227+.B \-\-icc\-profile
4228+option is used to include an ICC profile into a TIFF file.
4229+.PP
4230+The
4231+.B \-L
4232+or
4233+.B \-\-list\-devices
4234+option requests a (partial) list of devices that are available. The
4235+list is not complete since some devices may be available, but are not
4236+listed in any of the configuration files (which are typically stored
4237+in directory
4238+.IR @CONFIGDIR@ ).
4239+This is particularly the case when accessing scanners through the network. If
4240+a device is not listed in a configuration file, the only way to access it is
4241+by its full device name. You may need to consult your system administrator to
4242+find out the names of such devices.
4243+.PP
4244+The
4245+.B \-f
4246+or
4247+.B \-\-formatted\-device\-list
4248+option works similar to
4249+.BR \-\-list\-devices ,
4250+but requires a format string.
4251+.B scanimage
4252+replaces the placeholders
4253+.B %d %v %m %t %i %n
4254+with the device name, vendor name, model name, scanner type, an index
4255+number and newline respectively. The command
4256+.PP
4257+.RS
4258+.B scanimage \-f
4259+.I \*(lq scanner number %i device %d is a %t, model %m, produced by %v \*(rq
4260+.PP
4261+.RE
4262+will produce something like:
4263+.PP
4264+.RS
4265+scanner number 0 device sharp:/dev/sg1 is a flatbed scanner, model JX250
4266+SCSI, produced by SHARP
4267+.RE
4268+.PP
4269+The
4270+.B \-\-batch*
4271+options provide the features for scanning documents using document
4272+feeders.
4273+.BR \-\-batch
4274+.RI [ format ]
4275+is used to specify the format of the filename that each page will be written
4276+to. Each page is written out to a single file. If
4277+.I format
4278+is not specified, the default of out%d.pnm (or out%d.tif for \-\-format tiff)
4279+will be used.
4280+.I format
4281+is given as a printf style string with one integer parameter.
4282+.B \-\-batch\-start
4283+.I start
4284+selects the page number to start naming files with. If this option is not
4285+given, the counter will start at 1.
4286+.B \-\-batch\-count
4287+.I count
4288+specifies the number of pages to attempt to scan. If not given,
4289+scanimage will continue scanning until the scanner returns a state
4290+other than OK. Not all scanners with document feeders signal when the
4291+ADF is empty, use this command to work around them.
4292+With
4293+.B \-\-batch\-increment
4294+.I increment
4295+you can change the amount that the number in the filename is incremented
4296+by. Generally this is used when you are scanning double-sided documents
4297+on a single-sided document feeder. A specific command is provided to
4298+aid this:
4299+.B \-\-batch\-double
4300+will automatically set the increment to 2.
4301+.B \-\-batch\-prompt
4302+will ask for pressing RETURN before scanning a page. This can be used for
4303+scanning multiple pages without an automatic document feeder.
4304+.PP
4305+The
4306+.B \-\-accept\-md5\-only
4307+option only accepts user authorization requests that support MD5 security. The
4308+.B SANE
4309+network daemon
4310+.RB ( saned )
4311+is capable of doing such requests. See
4312+.BR saned (8).
4313+.PP
4314+The
4315+.B \-p
4316+or
4317+.B \-\-progress
4318+option requests that
4319+.B scanimage
4320+prints a progress counter. It shows how much image data of the current image has
4321+already been received by
4322+.B scanimage
4323+(in percent).
4324+.PP
4325+The
4326+.B \-n
4327+or
4328+.B \-\-dont\-scan
4329+option requests that
4330+.B scanimage
4331+only sets the options provided by the user but doesn't actually perform a
4332+scan. This option can be used to e.g. turn off the scanner's lamp (if
4333+supported by the backend).
4334+.PP
4335+The
4336+.B \-T
4337+or
4338+.B \-\-test
4339+option requests that
4340+.B scanimage
4341+performs a few simple sanity tests to make sure the backend works as
4342+defined by the
4343+.B SANE
4344+API (in particular the
4345+.B sane_read
4346+function is exercised by this test).
4347+.PP
4348+The
4349+.B \-A
4350+or
4351+.B \-\-all-options
4352+option requests that
4353+.B scanimage
4354+lists all available options exposed the backend, including button options.
4355+The information is printed on standard output and no scan will be done.
4356+.PP
4357+The
4358+.B \-h
4359+or
4360+.B \-\-help
4361+options request help information. The information is printed on
4362+standard output and in this case, no attempt will be made to acquire
4363+an image.
4364+.PP
4365+The
4366+.B \-v
4367+or
4368+.B \-\-verbose
4369+options increase the verbosity of the operation of
4370+.B scanimage.
4371+The option may be specified repeatedly, each time increasing the verbosity
4372+level.
4373+.PP
4374+The
4375+.B \-B
4376+or
4377+.B \-\-buffer-size
4378+changes the input buffer size from 32KB to the number kB specified or 1M.
4379+.PP
4380+The
4381+.B \-V
4382+or
4383+.B \-\-version
4384+option requests that
4385+.B scanimage
4386+prints the program and package name, the version number of
4387+the
4388+.B SANE
4389+distribution that it came with and the version of the backend that it
4390+loads. Usually that's the dll backend. If more information about the version
4391+numbers of the backends are necessary, the
4392+.B DEBUG
4393+variable for the dll backend can be used. Example: SANE_DEBUG_DLL=3 scanimage
4394+\-L.
4395+.PP
4396+As you might imagine, much of the power of
4397+.B scanimage
4398+comes from the fact that it can control any
4399+.B SANE
4400+backend. Thus, the exact set of command-line options depends on the
4401+capabilities of the selected device. To see the options for a device named
4402+.IR dev ,
4403+invoke
4404+.B scanimage
4405+via a command-line of the form:
4406+.PP
4407+.RS
4408+.B scanimage \-\-help \-\-device\-name
4409+.I dev
4410+.RE
4411+.PP
4412+The documentation for the device-specific options printed by
4413+.B \-\-help
4414+is best explained with a few examples:
4415+
4416+ \-l 0..218mm [0]
4417+.br
4418+ Top-left x position of scan area.
4419+.PP
4420+.RS
4421+The description above shows that option
4422+.B \-l
4423+expects an option value in the range from 0 to 218 mm. The
4424+value in square brackets indicates that the current option value is 0
4425+mm. Most backends provide similar geometry options for top-left y position (\-t),
4426+width (\-x) and height of scan-area (\-y).
4427+.RE
4428+
4429+
4430+ \-\-brightness \-100..100% [0]
4431+.br
4432+ Controls the brightness of the acquired image.
4433+.PP
4434+.RS
4435+The description above shows that option
4436+.B \-\-brightness
4437+expects an option value in the range from \-100 to 100 percent. The
4438+value in square brackets indicates that the current option value is 0
4439+percent.
4440+.RE
4441+
4442+ \-\-default\-enhancements
4443+.br
4444+ Set default values for enhancement controls.
4445+.PP
4446+.RS
4447+The description above shows that option
4448+.B \-\-default\-enhancements
4449+has no option value. It should be thought of as having an immediate
4450+effect at the point of the command-line at which it appears. For
4451+example, since this option resets the
4452+.B \-\-brightness
4453+option, the option-pair
4454+.B \-\-brightness 50 \-\-default\-enhancements
4455+would effectively be a no-op.
4456+.RE
4457+
4458+ \-\-mode Lineart|Gray|Color [Gray]
4459+.br
4460+ Selects the scan mode (e.g., lineart or color).
4461+.PP
4462+.RS
4463+The description above shows that option
4464+.B \-\-mode
4465+accepts an argument that must be one of the strings
4466+.BR Lineart ,
4467+.BR Gray ,
4468+or
4469+.BR Color .
4470+The value in the square bracket indicates that the option is currently
4471+set to
4472+.BR Gray .
4473+For convenience, it is legal to abbreviate the string values as long as
4474+they remain unique. Also, the case of the spelling doesn't matter. For
4475+example, option setting
4476+.B \-\-mode col
4477+is identical to
4478+.BR "\-\-mode Color" .
4479+.RE
4480+
4481+ \-\-custom\-gamma[=(yes|no)] [inactive]
4482+.br
4483+ Determines whether a builtin or a custom gamma-table
4484+.br
4485+ should be used.
4486+.PP
4487+.RS
4488+The description above shows that option
4489+.B \-\-custom\-gamma
4490+expects either no option value, a "yes" string, or a "no" string.
4491+Specifying the option with no value is equivalent to specifying "yes".
4492+The value in square-brackets indicates that the option is not
4493+currently active. That is, attempting to set the option would result
4494+in an error message. The set of available options typically depends
4495+on the settings of other options. For example, the
4496+.B \-\-custom\-gamma
4497+table might be active only when a grayscale or color scan-mode has
4498+been requested.
4499+
4500+Note that the
4501+.B \-\-help
4502+option is processed only after all other options have been processed.
4503+This makes it possible to see the option settings for a particular
4504+mode by specifying the appropriate mode-options along
4505+with the
4506+.B \-\-help
4507+option. For example, the command-line:
4508+.PP
4509+.B scanimage \-\-help \-\-mode
4510+.I color
4511+.PP
4512+would print the option settings that are in effect when the color-mode
4513+is selected.
4514+.RE
4515+
4516+ \-\-gamma\-table 0..255,...
4517+.br
4518+ Gamma-correction table. In color mode this option
4519+.br
4520+ equally affects the red, green, and blue channels
4521+.br
4522+ simultaneously (i.e., it is an intensity gamma table).
4523+.PP
4524+.RS
4525+The description above shows that option
4526+.B \-\-gamma\-table
4527+expects zero or more values in the range 0 to 255. For example, a
4528+legal value for this option would be "3,4,5,6,7,8,9,10,11,12". Since
4529+it's cumbersome to specify long vectors in this form, the same can be
4530+expressed by the abbreviated form "[0]3-[9]12". What this means is
4531+that the first vector element is set to 3, the 9-th element is set to
4532+12 and the values in between are interpolated linearly. Of course, it
4533+is possible to specify multiple such linear segments. For example,
4534+"[0]3-[2]3-[6]7,[7]10-[9]6" is equivalent to "3,3,3,4,5,6,7,10,8,6".
4535+The program
4536+.B gamma4scanimage
4537+can be used to generate such gamma tables (see
4538+.BR gamma4scanimage (1)
4539+for details).
4540+.RE
4541+
4542+.br
4543+ \-\-filename <string> [/tmp/input.ppm]
4544+.br
4545+ The filename of the image to be loaded.
4546+.PP
4547+.RS
4548+The description above is an example of an option that takes an
4549+arbitrary string value (which happens to be a filename). Again,
4550+the value in brackets show that the option is current set to the
4551+filename
4552+.BR /tmp/input.ppm .
4553+.RE
4554+
4555+.SH ENVIRONMENT
4556+.TP
4557+.B SANE_DEFAULT_DEVICE
4558+The default device-name.
4559+.SH FILES
4560+.TP
4561+.I @CONFIGDIR@
4562+This directory holds various configuration files. For details, please
4563+refer to the manual pages listed below.
4564+.TP
4565+.I ~/.sane/pass
4566+This file contains lines of the form
4567+.PP
4568+.RS
4569+user:password:resource
4570+.PP
4571+scanimage uses this information to answer user authorization requests
4572+automatically. The file must have 0600 permissions or stricter. You should
4573+use this file in conjunction with the \-\-accept\-md5\-only option to avoid
4574+server-side attacks. The resource may contain any character but is limited
4575+to 127 characters.
4576+.SH "SEE ALSO"
4577+.BR sane (7),
4578+.BR gamma4scanimage (1),
4579+.BR xscanimage (1),
4580+.BR xcam(1) ,
4581+.BR xsane(1) ,
4582+.BR scanadf (1),
4583+.BR sane\-dll (5),
4584+.BR sane\-net (5),
4585+.BR sane\-"backendname" (5)
4586+.SH AUTHOR
4587+David Mosberger, Andreas Beck, Gordon Matzigkeit, Caskey Dickson, and many
4588+others. For questions and comments contact the sane\-devel mailinglist (see
4589+http://www.sane\-project.org/mailing\-lists.html).
4590+
4591+.SH BUGS
4592+For vector options, the help output currently has no indication as to
4593+how many elements a vector-value should have.
4594
4595=== added directory '.pc/0105-fuj-126a.patch'
4596=== added directory '.pc/0105-fuj-126a.patch/backend'
4597=== added file '.pc/0105-fuj-126a.patch/backend/fujitsu.c'
4598--- .pc/0105-fuj-126a.patch/backend/fujitsu.c 1970-01-01 00:00:00 +0000
4599+++ .pc/0105-fuj-126a.patch/backend/fujitsu.c 2015-11-08 16:17:40 +0000
4600@@ -0,0 +1,10102 @@
4601+/* sane - Scanner Access Now Easy.
4602+
4603+ This file is part of the SANE package, and implements a SANE backend
4604+ for various Fujitsu scanners.
4605+
4606+ Copyright (C) 2000 Randolph Bentson
4607+ Copyright (C) 2001 Frederik Ramm
4608+ Copyright (C) 2001-2004 Oliver Schirrmeister
4609+ Copyright (C) 2003-2014 m. allan noah
4610+
4611+ JPEG output and low memory usage support funded by:
4612+ Archivista GmbH, www.archivista.ch
4613+ Endorser support funded by:
4614+ O A S Oilfield Accounting Service Ltd, www.oas.ca
4615+ Automatic length detection support funded by:
4616+ Martin G. Miller, mgmiller at optonline.net
4617+ Software image enhancement routines and recent scanner support funded by:
4618+ Fujitsu Computer Products of America, Inc. www.fcpa.com
4619+
4620+ --------------------------------------------------------------------------
4621+
4622+ This program is free software; you can redistribute it and/or
4623+ modify it under the terms of the GNU General Public License as
4624+ published by the Free Software Foundation; either version 2 of the
4625+ License, or (at your option) any later version.
4626+
4627+ This program is distributed in the hope that it will be useful, but
4628+ WITHOUT ANY WARRANTY; without even the implied warranty of
4629+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4630+ General Public License for more details.
4631+
4632+ You should have received a copy of the GNU General Public License
4633+ along with this program; if not, write to the Free Software
4634+ Foundation, Inc., 59 Temple Place - Suite 330, Boston,
4635+ MA 02111-1307, USA.
4636+
4637+ As a special exception, the authors of SANE give permission for
4638+ additional uses of the libraries contained in this release of SANE.
4639+
4640+ The exception is that, if you link a SANE library with other files
4641+ to produce an executable, this does not by itself cause the
4642+ resulting executable to be covered by the GNU General Public
4643+ License. Your use of that executable is in no way restricted on
4644+ account of linking the SANE library code into it.
4645+
4646+ This exception does not, however, invalidate any other reasons why
4647+ the executable file might be covered by the GNU General Public
4648+ License.
4649+
4650+ If you submit changes to SANE to the maintainers to be included in
4651+ a subsequent release, you agree by submitting the changes that
4652+ those changes may be distributed with this exception intact.
4653+
4654+ If you write modifications of your own for SANE, it is your choice
4655+ whether to permit this exception to apply to your modifications.
4656+ If you do not wish that, delete this exception notice.
4657+
4658+ --------------------------------------------------------------------------
4659+
4660+ The source code is divided in sections which you can easily find by
4661+ searching for the tag "@@".
4662+
4663+ Section 1 - Boilerplate: Init & static stuff
4664+ Section 2 - Init: sane_init, _get_devices, _open ...
4665+ Section 3 - Options: sane_*_option functions
4666+ Section 4 - Scanning: sane_start, _get_param, _read ...
4667+ Section 5 - Cleanup: sane_cancel, ...
4668+ Section 6 - Misc: sense_handler, hexdump, ...
4669+ Section 7 - Image processing: deskew, crop, despeck
4670+
4671+ Changes:
4672+ v1, 2002-05-05, OS
4673+ - release memory allocated by sane_get_devices
4674+ - several bugfixes
4675+ - supports the M3097
4676+ - get threshold, contrast and brightness from vpd
4677+ - imprinter support
4678+ - get_hardware_status now works before calling sane_start
4679+ - avoid unnecessary reload of options when using source=fb
4680+ v2, 2002-08-08, OS
4681+ - bugfix. Imprinter didn't print the first time after
4682+ switching on the scanner
4683+ - bugfix. reader_generic_passthrough ignored the number of bytes
4684+ returned by the scanner
4685+ v3, 2002-09-13, OS
4686+ - 3092 support (mgoppold a t tbz-pariv.de)
4687+ - tested 4097 support
4688+ - changed some functions to receive compressed data
4689+ v4, 2003-02-13, OS
4690+ - fi-4220C support (ron a t roncemer.com)
4691+ - SCSI over USB support (ron a t roncemer.com)
4692+ v5, 2003-02-20, OS
4693+ - set availability of options THRESHOLD und VARIANCE
4694+ - option RIF is available for 3091 and 3092
4695+ v6, 2003-03-04, OS
4696+ - renamed some variables
4697+ - bugfix: duplex scanning now works when disconnect is enabled
4698+ v7, 2003-03-10, OS
4699+ - displays the offending byte in the window descriptor block
4700+ v8, 2003-03-28, OS
4701+ - fi-4120C support, MAN
4702+ - display information about gamma in vital_product_data
4703+ v9 2003-06-04, MAN
4704+ - separated the 4120 and 4220 into another model
4705+ - color support for the 4x20
4706+ v10 2003-06-04, MAN
4707+ - removed SP15 code
4708+ - sane_open actually opens the device you request
4709+ v11 2003-06-11, MAN
4710+ - fixed bug in that code when a scanner is disconnected
4711+ v12 2003-10-06, MAN
4712+ - added code to support color modes of more recent scanners
4713+ v13 2003-11-07, OS
4714+ - Bugfix. If a scanner returned a color image
4715+ in format rr...r gg...g bb...b the reader process crashed
4716+ - Bugfix. Disable option gamma was for the fi-4120
4717+ v14 2003-12-15, OS
4718+ - Bugfix: set default threshold range to 0..255 There is a problem
4719+ with the M3093 when you are not allows to set the threshold to 0
4720+ - Bugfix: set the allowable x- and y-DPI values from VPD. Scanning
4721+ with x=100 and y=100 dpi with an fi4120 resulted in an image
4722+ with 100,75 dpi
4723+ - Bugfix: Set the default value of gamma to 0x80 for all scanners
4724+ that don't have built in gamma patterns
4725+ - Bugfix: fi-4530 and fi-4210 don't support standard paper size
4726+ v15 2003-12-16, OS
4727+ - Bugfix: pagewidth and pageheight were disabled for the fi-4530C
4728+ v16 2004-02-20, OS
4729+ - merged the 3092-routines with the 3091-routines
4730+ - inverted the image in mode color and grayscale
4731+ - jpg hardware compression support (fi-4530C)
4732+ v17 2004-03-04, OS
4733+ - enabled option dropoutcolor for the fi-4530C, and fi-4x20C
4734+ v18 2004-06-02, OS
4735+ - bugfix: can read duplex color now
4736+ v19 2004-06-28, MAN
4737+ - 4220 use model code not strcmp (stan a t saticed.me.uk)
4738+ v20 2004-08-24, OS
4739+ - bugfix: 3091 did not work since 15.12.2003
4740+ - M4099 supported (bw only)
4741+ v21 2006-05-01, MAN
4742+ - Complete rewrite, half code size
4743+ - better (read: correct) usb command support
4744+ - basic support for most fi-series
4745+ - most scanner capabilities read from VPD
4746+ - reduced model-specific code
4747+ - improved scanner detection/initialization
4748+ - improved SANE_Option handling
4749+ - basic button support
4750+ - all IPC and Imprinter options removed temporarily
4751+ - duplex broken temporarily
4752+ v22 2006-05-04, MAN
4753+ - do_scsi_cmd gets basic looping capability
4754+ - reverse now divided by mode
4755+ - re-write sane_fix/unfix value handling
4756+ - fix several bugs in options code
4757+ - some options' ranges modified by other options vals
4758+ - added advanced read-only options for all
4759+ known hardware sensors and buttons
4760+ - rewrote hw status function
4761+ - initial testing with M3091dc- color mode broken
4762+ v23 2006-05-14, MAN
4763+ - initial attempt to recover duplex mode
4764+ - fix bad usb prodID when config file missing
4765+ v24 2006-05-17, MAN
4766+ - sane_read must set len=0 when return != good
4767+ - simplify do_cmd() calls by removing timeouts
4768+ - lengthen most timeouts, shorten those for wait_scanner()
4769+ v25 2006-05-19, MAN
4770+ - rename scsi-buffer-size to buffer-size, usb uses it too
4771+ - default buffer-size increased to 64k
4772+ - use sanei_scsi_open_extended() to set buffer size
4773+ - fix some compiler warns: 32&64 bit gcc
4774+ v26 2006-05-23, MAN
4775+ - dont send scanner control (F1) if unsupported
4776+ v27 2006-05-30, MAN
4777+ - speed up hexdump (adeuring A T gmx D O T net)
4778+ - duplex request same size block from both sides
4779+ - dont #include or call sanei_thread
4780+ - split usb/scsi command DBG into 25 and 30
4781+ v28 2006-06-01, MAN
4782+ - sane_read() usleep if scanner is busy
4783+ - do_*_cmd() no looping (only one caller used it),
4784+ remove unneeded casts, cleanup/add error messages
4785+ - scanner_control() look at correct has_cmd_* var,
4786+ handles own looping on busy
4787+ v29 2006-06-04, MAN
4788+ - M3091/2 Color mode support (duplex still broken)
4789+ - all sensors option names start with 'button-'
4790+ - rewrite sane_read and helpers to use buffers,
4791+ currently an extreme waste of ram, but should
4792+ work with saned and scanimage -T
4793+ - merge color conversion funcs into read_from_buf()
4794+ - compare bytes tx v/s rx instead of storing EOFs
4795+ - remove scanner cmd buf, use buf per func instead
4796+ - print color and duplex raster offsets (inquiry)
4797+ - print EOM, ILI, and info bytes (request sense)
4798+ v30 2006-06-06, MAN
4799+ - M3091/2 duplex support, color/gray/ht/lineart ok
4800+ - sane_read helpers share code, report more errors
4801+ - add error msg if VPD missing or non-extended
4802+ - remove references to color_lineart and ht units
4803+ - rework init_model to support more known models
4804+ - dont send paper size data if using flatbed
4805+ v31 2006-06-13, MAN
4806+ - add 5220C usb id
4807+ - dont show ink level buttons if no imprinter
4808+ - run ghs/rs every second instead of every other
4809+ v32 2006-06-14, MAN
4810+ - add 4220C2 usb id
4811+ v33 2006-06-14, MAN (SANE v1.0.18)
4812+ - add Fi-5900 usb id and init_model section
4813+ v34 2006-07-04, MAN
4814+ - add S500 usb id
4815+ - gather more data from inq and vpd
4816+ - allow background color setting
4817+ v35 2006-07-05, MAN
4818+ - allow double feed sensor settings
4819+ - more consistent naming of global strings
4820+ v36 2006-07-06, MAN
4821+ - deal with fi-5900 even bytes problem
4822+ - less verbose calculateDerivedValues()
4823+ v37 2006-07-14, MAN
4824+ - mode sense command support
4825+ - detect mode page codes instead of hardcoding
4826+ - send command support
4827+ - brightness/contrast support via LUT
4828+ - merge global mode page buffers
4829+ v38 2006-07-15, MAN
4830+ - add 'useless noise' debug level (35)
4831+ - move mode sense probe errors to DBG 35
4832+ v39 2006-07-17, MAN
4833+ - rewrite contrast slope math for readability
4834+ v40 2006-08-26, MAN
4835+ - rewrite brightness/contrast more like xsane
4836+ - initial gamma support
4837+ - add fi-5530 usb id
4838+ - rewrite do_*_cmd functions to handle short reads
4839+ and to use ptr to return read in length
4840+ - new init_user function split from init_model
4841+ - init_vpd allows short vpd block for older models
4842+ - support MS buffer (s.scipioni AT harvardgroup DOT it)
4843+ - support MS prepick
4844+ - read only 1 byte of mode sense output
4845+ v41 2006-08-28, MAN
4846+ - do_usb_cmd() returns io error on cmd/out/status/rs EOF
4847+ - fix bug in MS buffer/prepick scsi data block
4848+ v42 2006-08-31, MAN
4849+ - fix bug in get_hardware_status (#303798)
4850+ v43 2006-09-19, MAN
4851+ - add model-specific code to init_vpd for M3099
4852+ v44 2007-01-26, MAN
4853+ - set SANE_CAP_HARD_SELECT on all buttons/sensors
4854+ - disable sending gamma LUT, seems wrong on some units?
4855+ - support MS overscan
4856+ - clamp the scan area to the pagesize on ADF
4857+ v45 2007-01-28, MAN
4858+ - update overscan code to extend max scan area
4859+ v46 2007-03-08, MAN
4860+ - tweak fi-4x20c2 and M3093 settings
4861+ - add fi-5110EOXM usb id
4862+ - add M3093 non-alternating duplex code
4863+ v47 2007-04-13, MAN
4864+ - change window_gamma determination
4865+ - add fi-5650C usb id and color mode
4866+ v48 2007-04-16, MAN
4867+ - re-enable brightness/contrast for built-in models
4868+ v49 2007-06-28, MAN
4869+ - add fi-5750C usb id and color mode
4870+ v50 2007-07-10, MAN
4871+ - updated overscan and bgcolor option descriptions
4872+ - added jpeg output support
4873+ - restructured usb reading code to use RS len for short reads
4874+ - combined calcDerivedValues with sane_get_params
4875+ v51 2007-07-26, MAN
4876+ - fix bug in jpeg output support
4877+ v52 2007-07-27, MAN
4878+ - remove unused jpeg function
4879+ - reactivate look-up-table based brightness and contrast options
4880+ - change range of hardware brightness/contrast to match LUT versions
4881+ - call send_lut() from sane_control_option instead of sane_start
4882+ v53 2007-11-18, MAN
4883+ - add S510 usb id
4884+ - OPT_NUM_OPTS type is SANE_TYPE_INT (jblache)
4885+ v54 2007-12-29, MAN
4886+ - disable SANE_FRAME_JPEG support until SANE 1.1.0
4887+ v55 2007-12-29, MAN (SANE v1.0.19)
4888+ - add S500M usb id
4889+ v56 2008-02-14, MAN
4890+ - sanei_config_read has already cleaned string (#310597)
4891+ v57 2008-02-24, MAN
4892+ - fi-5900 does not (initially) interlace colors
4893+ - add mode sense for color interlacing? (page code 32)
4894+ - more debug output in init_ms()
4895+ v58 2008-04-19, MAN
4896+ - page code 32 is not color interlacing, rename to 'unknown'
4897+ - increase number of bytes in response buffer of init_ms()
4898+ - protect debug modification code in init_ms() if NDEBUG is set
4899+ - proper async sane_cancel support
4900+ - re-enable JPEG support
4901+ - replace s->img_count with s->side
4902+ - sane_get_parameters(): dont round up larger than current paper size
4903+ - sane_start() rewritten, shorter, more clear
4904+ - return values are SANE_Status, not int
4905+ - hide unused functions
4906+ v59 2008-04-22, MAN
4907+ - add fi-6140 usb ID, and fi-6x40 color mode
4908+ v60 2008-04-27, MAN
4909+ - move call to sanei_usb_init() from sane_init() to find_scanners
4910+ - free sane_devArray before calloc'ing a new one
4911+ v61 2008-05-11, MAN
4912+ - minor cleanups to init_ms()
4913+ - add fi-5530C2 usb id
4914+ - merge find_scanners into sane_get_devices
4915+ - inspect correct bool to enable prepick mode option
4916+ v62 2008-05-20, MAN
4917+ - check for all supported scsi commands
4918+ - use well-known option group strings from saneopts.h
4919+ - rename pagewidth to page-width, to meet sane 1.1.0, same for height
4920+ - add unused get_window()
4921+ v63 2008-05-21, MAN
4922+ - use sane 1.1.0 well-known option names for some buttons
4923+ - remove 'button-' from other buttons and sensors
4924+ v64 2008-05-28, MAN
4925+ - strcpy device_name[] instead of strdup/free *device_name
4926+ - add send/read diag commands to get scanner serial number
4927+ - use model and serial to build sane.name (idea from Ryan Duryea)
4928+ - allow both serial_name and device_name to sane_open scanner
4929+ - correct mode select/sense 6 vs 10 booleans
4930+ - rename product_name to model_name
4931+ - simulate missing VPD data for M3097G
4932+ - hide get_window
4933+ - improve handling of vendor unique section of set_window
4934+ - add init_interlace to detect proper color mode without hardcoding
4935+ - add ascii output to hexdump
4936+ v65 2008-06-24, MAN
4937+ - detect endorser type during init_inquiry()
4938+ - add endorser options
4939+ - add send_endorser() and call from sane_control_option()
4940+ - add endorser() and call from sane_start()
4941+ - convert set_window() to use local cmd and payload copies
4942+ - remove get_window()
4943+ - mode_select_buff() now clears the buffer, and called in sane_close()
4944+ - fi-4990 quirks added, including modified even_scan_line code
4945+ v66 2008-06-26, MAN
4946+ - restructure double feed detection options for finer-grained control
4947+ - add endorser side option
4948+ - prevent init_interlace() from overriding init_model()
4949+ - simplify sane_start() and fix interlaced duplex jpeg support
4950+ - simplify sane_read() and add non-interlaced duplex jpeg support
4951+ - removed unused code
4952+ v67 2008-07-01, MAN
4953+ - add IPC/DTC/SDTC options
4954+ - call check_for_cancel() in sane_cancel, unless s->reader flag is set
4955+ v68 2008-07-02, MAN
4956+ - add halftone type and pattern options
4957+ - support M3097G with IPC and CMP options via modified VPD response
4958+ v69 2008-07-03, MAN
4959+ - support hot-unplugging scanners
4960+ v70 2008-07-05, MAN
4961+ - fix bug in sane_get_parameters (failed to copy values)
4962+ - autodetect jpeg duplex interlacing mode by inspecting scan width
4963+ v71 2008-07-13, MAN
4964+ - disable overscan option if vpd does not tell overscan size
4965+ - fi-5110EOX crops scan area based on absolute maximum, not paper
4966+ - fi-5530C/2 and fi-5650C can't handle 10 bit LUT via USB
4967+ - fi-5900 has background color, though it reports otherwise
4968+ v72 2008-07-13, MAN
4969+ - use mode_sense to determine background color support
4970+ - remove fi-5900 background color override
4971+ v73 2008-07-14, MAN
4972+ - correct overscan dimension calculation
4973+ - provide correct overscan size overrides for fi-5110C and fi-4x20C2
4974+ - add fi-6130 usb ID
4975+ - fi-5750C can't handle 10 bit LUT via USB
4976+ v74 2008-08-02, MAN
4977+ - replace global scsi blocks with local ones in each function
4978+ v75 2008-08-07, ReneR
4979+ - added fi-6230 usb ID
4980+ v76 2008-08-13, MAN
4981+ - add independent maximum area values for flatbed
4982+ - override said values for fi-4220C, fi-4220C2 and fi-5220C
4983+ v77 2008-08-26, MAN
4984+ - override flatbed maximum area for fi-6230C and fi-6240C
4985+ - set PF bit in all mode_select(6) CDB's
4986+ - set SANE_CAP_INACTIVE on all disabled options
4987+ - fix bug in mode_select page for sleep timer
4988+ v78 2008-08-26, MAN
4989+ - recent model names (fi-6xxx) dont end in 'C'
4990+ - simplify flatbed area overrides
4991+ - call scanner_control to change source during sane_start
4992+ v79 2008-10-01, MAN
4993+ - add usb ids for several models
4994+ - print additional hardware capability bits
4995+ - detect front-side endorser
4996+ - disable endorser-side controls if only one side installed
4997+ - add quirks for fi-6x70
4998+ v80 2008-10-08, MAN
4999+ - front-side endorser uses data ID 0x80
5000+ v81 2008-10-20, MAN
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: